[Reproducible-commits] [doxygen] 01/04: unpacked doxygen_1.8.8.orig.tar.gz
Mattia Rizzolo
mattia at mapreri.org
Sat Apr 11 16:20:02 UTC 2015
This is an automated email from the git hooks/post-receive script.
mapreri-guest pushed a commit to branch master
in repository doxygen.
commit 146552f3081574b028e8c66a468bdf75210c7a36
Author: Holger Levsen <holger at layer-acht.org>
Date: Mon Mar 16 18:50:45 2015 +0000
unpacked doxygen_1.8.8.orig.tar.gz
---
Doxyfile | 315 +
INSTALL | 7 +
LANGUAGE.HOWTO | 50 +
LICENSE | 340 +
Makefile.in | 160 +
Makefile.win_make.in | 34 +
Makefile.win_nmake.in | 51 +
PLATFORMS | 32 +
README.md | 66 +
VERSION | 1 +
addon/doxmlparser/Doxyfile | 177 +
addon/doxmlparser/Doxyfile.impl | 179 +
addon/doxmlparser/examples/metrics/Makefile | 37 +
addon/doxmlparser/examples/metrics/Makefile.in | 15 +
.../doxmlparser/examples/metrics/Makefile.metrics | 77 +
addon/doxmlparser/examples/metrics/main.cpp | 254 +
addon/doxmlparser/examples/metrics/metrics.pro | 27 +
addon/doxmlparser/examples/metrics/metrics.pro.in | 20 +
addon/doxmlparser/include/doxmlintf.h | 1 +
addon/doxmlparser/src/Makefile | 37 +
addon/doxmlparser/src/Makefile.doxmlparser | 224 +
addon/doxmlparser/src/Makefile.in | 15 +
addon/doxmlparser/src/basehandler.cpp | 3 +
addon/doxmlparser/src/basehandler.h | 325 +
addon/doxmlparser/src/baseiterator.h | 50 +
addon/doxmlparser/src/compoundhandler.cpp | 654 +
addon/doxmlparser/src/compoundhandler.h | 237 +
addon/doxmlparser/src/debug.cpp | 24 +
addon/doxmlparser/src/debug.h | 7 +
addon/doxmlparser/src/dochandler.cpp | 2240 +++
addon/doxmlparser/src/dochandler.h | 1352 ++
addon/doxmlparser/src/doxmlintf.h | 1141 ++
addon/doxmlparser/src/doxmlparser.pro | 34 +
addon/doxmlparser/src/doxmlparser.pro.in | 27 +
addon/doxmlparser/src/graphhandler.cpp | 216 +
addon/doxmlparser/src/graphhandler.h | 154 +
addon/doxmlparser/src/linkedtexthandler.cpp | 133 +
addon/doxmlparser/src/linkedtexthandler.h | 54 +
addon/doxmlparser/src/loamhandler.cpp | 75 +
addon/doxmlparser/src/loamhandler.h | 52 +
addon/doxmlparser/src/mainhandler.cpp | 299 +
addon/doxmlparser/src/mainhandler.h | 82 +
addon/doxmlparser/src/memberhandler.cpp | 600 +
addon/doxmlparser/src/memberhandler.h | 252 +
addon/doxmlparser/src/paramhandler.cpp | 158 +
addon/doxmlparser/src/paramhandler.h | 103 +
addon/doxmlparser/src/sectionhandler.cpp | 168 +
addon/doxmlparser/src/sectionhandler.h | 102 +
addon/doxmlparser/src/stringimpl.h | 30 +
addon/doxmlparser/test/Makefile | 37 +
addon/doxmlparser/test/Makefile.in | 15 +
addon/doxmlparser/test/Makefile.xmlparse | 77 +
addon/doxmlparser/test/main.cpp | 759 +
addon/doxmlparser/test/xmlparse.pro | 27 +
addon/doxmlparser/test/xmlparse.pro.in | 20 +
addon/doxyapp/Makefile.in | 19 +
addon/doxyapp/README | 8 +
addon/doxyapp/doxyapp.cpp | 330 +
addon/doxyapp/doxyapp.pro.in | 12 +
addon/doxypysql/search.py | 364 +
addon/doxysearch/Makefile.in | 34 +
addon/doxysearch/doxyindexer.cpp | 377 +
addon/doxysearch/doxyindexer.pro.in | 12 +
addon/doxysearch/doxysearch.cpp | 434 +
addon/doxysearch/doxysearch.pro.in | 12 +
addon/doxywizard/Makefile | 62 +
addon/doxywizard/Makefile.doxywizard | 436 +
addon/doxywizard/Makefile.in | 40 +
addon/doxywizard/README | 3 +
addon/doxywizard/config.h | 27 +
addon/doxywizard/config.l | 555 +
addon/doxywizard/config_doxyw.l | 555 +
addon/doxywizard/configdoc.h | 8 +
addon/doxywizard/docintf.h | 12 +
addon/doxywizard/doxywizard.cpp | 665 +
addon/doxywizard/doxywizard.h | 87 +
addon/doxywizard/doxywizard.ico | Bin 0 -> 84071 bytes
addon/doxywizard/doxywizard.pro | 48 +
addon/doxywizard/doxywizard.pro.in | 41 +
addon/doxywizard/doxywizard.qrc | 11 +
addon/doxywizard/doxywizard.rc | 1 +
addon/doxywizard/expert.cpp | 945 ++
addon/doxywizard/expert.h | 74 +
addon/doxywizard/helplabel.h | 33 +
addon/doxywizard/images/add.png | Bin 0 -> 4321 bytes
addon/doxywizard/images/del.png | Bin 0 -> 4231 bytes
addon/doxywizard/images/file.png | Bin 0 -> 4380 bytes
addon/doxywizard/images/folder.png | Bin 0 -> 4308 bytes
addon/doxywizard/images/refresh.png | Bin 0 -> 4458 bytes
addon/doxywizard/images/tunecolor.png | Bin 0 -> 116333 bytes
addon/doxywizard/input.h | 36 +
addon/doxywizard/inputbool.cpp | 112 +
addon/doxywizard/inputbool.h | 72 +
addon/doxywizard/inputint.cpp | 113 +
addon/doxywizard/inputint.h | 74 +
addon/doxywizard/inputstring.cpp | 250 +
addon/doxywizard/inputstring.h | 96 +
addon/doxywizard/inputstrlist.cpp | 255 +
addon/doxywizard/inputstrlist.h | 93 +
addon/doxywizard/version.h | 23 +
addon/doxywizard/wizard.cpp | 1330 ++
addon/doxywizard/wizard.h | 256 +
configure | 988 ++
doc/.gitignore | 1 +
doc/Doxyfile | 55 +
doc/Makefile | 61 +
doc/Makefile.in | 39 +
doc/Makefile.latex | 25 +
doc/Makefile.win_make.in | 40 +
doc/Makefile.win_nmake.in | 41 +
doc/arch.doc | 259 +
doc/archoverview.eps | 380 +
doc/archoverview.gif | Bin 0 -> 7822 bytes
doc/autolink.doc | 140 +
doc/changelog.doc | 2442 +++
doc/commands.doc | 3201 ++++
doc/config.doc | 3859 +++++
doc/custcmd.doc | 132 +
doc/customize.doc | 401 +
doc/dbusxml.doc | 149 +
doc/diagrams.doc | 149 +
doc/docblocks.doc | 622 +
doc/doxygen.1 | 50 +
doc/doxygen.sty | 486 +
doc/doxygen_logo.eps | 6322 ++++++++
doc/doxygen_logo.gif | Bin 0 -> 29863 bytes
doc/doxygen_logo_low.gif | Bin 0 -> 3952 bytes
doc/doxygen_manual.css | 1108 ++
doc/doxygen_manual.tex | 116 +
doc/doxygen_usage.doc | 116 +
doc/doxyindexer.1 | 17 +
doc/doxysearch.1 | 11 +
doc/doxywizard.1 | 13 +
doc/doxywizard.gif | Bin 0 -> 18928 bytes
doc/doxywizard_expert.png | Bin 0 -> 30056 bytes
doc/doxywizard_main.png | Bin 0 -> 57204 bytes
doc/doxywizard_menu.png | Bin 0 -> 58661 bytes
doc/doxywizard_page1.png | Bin 0 -> 39646 bytes
doc/doxywizard_page2.png | Bin 0 -> 39048 bytes
doc/doxywizard_page3.png | Bin 0 -> 50904 bytes
doc/doxywizard_page4.png | Bin 0 -> 43718 bytes
doc/doxywizard_usage.doc | 153 +
doc/external.doc | 120 +
doc/extsearch.doc | 306 +
doc/extsearch_flow.dot | 18 +
doc/extsearch_flow.eps | 2100 +++
doc/extsearch_flow.png | Bin 0 -> 21062 bytes
doc/faq.doc | 290 +
doc/features.doc | 122 +
doc/formulas.doc | 112 +
doc/grouping.doc | 223 +
doc/htmlcmds.doc | 389 +
doc/index.doc | 193 +
doc/index.hhp.txt | 108 +
doc/infoflow.eps | 624 +
doc/infoflow.fig | 229 +
doc/infoflow.png | Bin 0 -> 100602 bytes
doc/install.doc | 569 +
doc/install_prefix | 2 +
doc/language.doc | 773 +
doc/language.tpl | 372 +
doc/lists.doc | 125 +
doc/maintainers.txt | 165 +
doc/markdown.doc | 654 +
doc/output.doc | 72 +
doc/perlmod.doc | 201 +
doc/perlmod_tree.doc | 383 +
doc/preprocessing.doc | 272 +
doc/searching.doc | 193 +
doc/starting.doc | 335 +
doc/translator.py | 2003 +++
doc/translator_report.txt | 1200 ++
doc/trouble.doc | 149 +
doc/xmlcmds.doc | 109 +
examples/Makefile | 151 +
examples/Makefile.in | 129 +
examples/Makefile.win.in | 122 +
examples/afterdoc.cfg | 10 +
examples/afterdoc.h | 18 +
examples/author.cfg | 10 +
examples/author.cpp | 13 +
examples/autolink.cfg | 10 +
examples/autolink.cpp | 99 +
examples/class.cfg | 10 +
examples/class.h | 11 +
examples/dbusxml.cfg | 12 +
examples/dbusxml.xml | 78 +
examples/define.cfg | 11 +
examples/define.h | 18 +
examples/diagrams.cfg | 14 +
examples/diagrams_a.h | 4 +
examples/diagrams_b.h | 5 +
examples/diagrams_c.h | 6 +
examples/diagrams_d.h | 7 +
examples/diagrams_e.h | 5 +
examples/docstring.cfg | 11 +
examples/docstring.py | 27 +
examples/enum.cfg | 10 +
examples/enum.h | 24 +
examples/example.cfg | 12 +
examples/example.cpp | 19 +
examples/example.tag | 14 +
examples/example_test.cpp | 5 +
examples/file.cfg | 10 +
examples/file.h | 10 +
examples/func.cfg | 10 +
examples/func.h | 21 +
examples/group.cfg | 10 +
examples/group.cpp | 88 +
examples/include.cfg | 11 +
examples/include.cpp | 22 +
examples/jdstyle.cfg | 10 +
examples/jdstyle.cpp | 66 +
examples/manual.c | 87 +
examples/manual.cfg | 16 +
examples/memgrp.cfg | 11 +
examples/memgrp.cpp | 41 +
examples/mux.cfg | 16 +
examples/mux.vhdl | 32 +
examples/overload.cfg | 11 +
examples/overload.cpp | 25 +
examples/page.cfg | 10 +
examples/page.doc | 15 +
examples/par.cfg | 10 +
examples/par.cpp | 20 +
examples/pyexample.cfg | 10 +
examples/pyexample.py | 30 +
examples/qtstyle.cfg | 10 +
examples/qtstyle.cpp | 65 +
examples/relates.cfg | 10 +
examples/relates.cpp | 23 +
examples/restypedef.cfg | 10 +
examples/restypedef.cpp | 25 +
examples/structcmd.cfg | 10 +
examples/structcmd.h | 57 +
examples/tag.cfg | 12 +
examples/tag.cpp | 9 +
examples/tclexample.cfg | 12 +
examples/tclexample.tcl | 82 +
examples/templ.cfg | 10 +
examples/templ.cpp | 35 +
jquery/Makefile | 48 +
jquery/README | 17 +
jquery/jquery-1.7.1.js | 9266 +++++++++++
jquery/jquery.ba-1.3-hashchange.js | 390 +
jquery/jquery.powertip-1.2.0.js | 1166 ++
jquery/jquery.scrollTo-1.4.2.js | 215 +
jquery/jquery.ui-1.8.18.core.js | 319 +
jquery/jquery.ui-1.8.18.mouse.js | 162 +
jquery/jquery.ui-1.8.18.resizable.js | 808 +
jquery/jquery.ui-1.8.18.widget.js | 272 +
jquery/split_jquery.pl | 25 +
libmd5/Makefile | 40 +
libmd5/Makefile.in | 18 +
libmd5/Makefile.libmd5 | 82 +
libmd5/libmd5.pro | 17 +
libmd5/libmd5.pro.in | 10 +
libmd5/md5.c | 313 +
libmd5/md5.h | 57 +
libmd5/md5_loc.h | 6 +
packages/rpm/doxygen.spec | 129 +
packages/rpm/doxygen.spec.in | 126 +
qtools/Doxyfile | 309 +
qtools/Doxyfile.bak | 308 +
qtools/LICENSE.GPL | 349 +
qtools/LICENSE.QPL | 103 +
qtools/Makefile | 52 +
qtools/Makefile.in | 30 +
qtools/README | 4 +
qtools/qarray.doc | 486 +
qtools/qarray.h | 110 +
qtools/qasciidict.h | 107 +
qtools/qbuffer.cpp | 465 +
qtools/qbuffer.h | 98 +
qtools/qcache.h | 152 +
qtools/qcollection.cpp | 182 +
qtools/qcollection.h | 74 +
qtools/qconfig.h | 1 +
qtools/qcstring.cpp | 799 +
qtools/qcstring.h | 480 +
qtools/qdatastream.cpp | 951 ++
qtools/qdatastream.h | 173 +
qtools/qdatetime.cpp | 1434 ++
qtools/qdatetime.h | 216 +
qtools/qdict.doc | 492 +
qtools/qdict.h | 130 +
qtools/qdir.cpp | 1200 ++
qtools/qdir.h | 235 +
qtools/qdir_unix.cpp | 290 +
qtools/qdir_win32.cpp | 485 +
qtools/qfeatures.h | 978 ++
qtools/qfile.cpp | 550 +
qtools/qfile.h | 128 +
qtools/qfile_unix.cpp | 668 +
qtools/qfile_win32.cpp | 678 +
qtools/qfiledefs_p.h | 268 +
qtools/qfileinfo.cpp | 458 +
qtools/qfileinfo.h | 138 +
qtools/qfileinfo_unix.cpp | 425 +
qtools/qfileinfo_win32.cpp | 357 +
qtools/qgarray.cpp | 747 +
qtools/qgarray.h | 120 +
qtools/qgcache.cpp | 878 ++
qtools/qgcache.h | 130 +
qtools/qgdict.cpp | 1218 ++
qtools/qgdict.h | 222 +
qtools/qgeneric.h | 43 +
qtools/qglist.cpp | 1223 ++
qtools/qglist.h | 257 +
qtools/qglobal.cpp | 685 +
qtools/qglobal.h | 650 +
qtools/qgstring.cpp | 258 +
qtools/qgstring.h | 139 +
qtools/qgvector.cpp | 638 +
qtools/qgvector.h | 120 +
qtools/qintdict.doc | 475 +
qtools/qintdict.h | 102 +
qtools/qinternallist.h | 139 +
qtools/qiodevice.cpp | 638 +
qtools/qiodevice.h | 155 +
qtools/qlist.doc | 1044 ++
qtools/qlist.h | 157 +
qtools/qmap.cpp | 254 +
qtools/qmap.h | 606 +
qtools/qmodules.h | 11 +
qtools/qmutex.cpp | 95 +
qtools/qmutex.h | 83 +
qtools/qmutex_p.h | 90 +
qtools/qmutex_unix.cpp | 117 +
qtools/qmutex_win32.cpp | 108 +
qtools/qptrdict.doc | 486 +
qtools/qptrdict.h | 103 +
qtools/qqueue.h | 70 +
qtools/qregexp.cpp | 1092 ++
qtools/qregexp.h | 92 +
qtools/qshared.h | 55 +
qtools/qsortedlist.doc | 94 +
qtools/qsortedlist.h | 59 +
qtools/qstack.doc | 135 +
qtools/qstack.h | 71 +
qtools/qstring.cpp | 15319 +++++++++++++++++++
qtools/qstring.h | 834 +
qtools/qstringlist.cpp | 307 +
qtools/qstringlist.h | 82 +
qtools/qstrlist.doc | 5 +
qtools/qstrlist.h | 109 +
qtools/qstrvec.h | 90 +
qtools/qtextcodec.cpp | 2071 +++
qtools/qtextcodec.h | 104 +
qtools/qtextstream.cpp | 2237 +++
qtools/qtextstream.h | 351 +
qtools/qthread.cpp | 85 +
qtools/qthread.h | 77 +
qtools/qthread_p.h | 85 +
qtools/qthread_unix.cpp | 232 +
qtools/qthread_win32.cpp | 158 +
qtools/qtl.doc | 249 +
qtools/qtl.h | 223 +
qtools/qtools.pro | 109 +
qtools/qtools.pro.in | 102 +
qtools/qutfcodec.cpp | 276 +
qtools/qutfcodec.h | 71 +
qtools/qvaluelist.doc | 772 +
qtools/qvaluelist.h | 449 +
qtools/qvaluestack.h | 64 +
qtools/qvector.doc | 344 +
qtools/qvector.h | 85 +
qtools/qwaitcondition.h | 68 +
qtools/qwaitcondition_unix.cpp | 134 +
qtools/qwaitcondition_win32.cpp | 186 +
qtools/qxml.cpp | 6061 ++++++++
qtools/qxml.h | 671 +
qtools/scstring.cpp | 798 +
qtools/scstring.h | 155 +
src/Makefile | 75 +
src/Makefile.in | 53 +
src/Makefile.libdoxycfg | 137 +
src/arguments.cpp | 96 +
src/arguments.h | 110 +
src/bib2xhtml.pl | 319 +
src/bufstr.h | 123 +
src/cite.cpp | 307 +
src/cite.h | 98 +
src/clangparser.cpp | 942 ++
src/clangparser.h | 67 +
src/classdef.cpp | 4623 ++++++
src/classdef.h | 560 +
src/classlist.cpp | 211 +
src/classlist.h | 87 +
src/cmdmapper.cpp | 246 +
src/cmdmapper.h | 219 +
src/code.h | 37 +
src/code.l | 3702 +++++
src/commentcnv.h | 27 +
src/commentcnv.l | 1039 ++
src/commentscan.h | 84 +
src/commentscan.l | 3194 ++++
src/compound.xsd | 844 +
src/condparser.cpp | 309 +
src/condparser.h | 75 +
src/config.h | 559 +
src/config.l | 1772 +++
src/config.xml | 3394 ++++
src/configgen.py | 649 +
src/configoptions.h | 23 +
src/constexp.h | 33 +
src/constexp.l | 124 +
src/constexp.y | 278 +
src/context.cpp | 8226 ++++++++++
src/context.h | 1135 ++
src/cppvalue.cpp | 95 +
src/cppvalue.h | 61 +
src/dbusxmlscanner.cpp | 881 ++
src/dbusxmlscanner.h | 65 +
src/debug.cpp | 134 +
src/debug.h | 54 +
src/declinfo.h | 33 +
src/declinfo.l | 361 +
src/defargs.h | 27 +
src/defargs.l | 562 +
src/defgen.cpp | 638 +
src/defgen.h | 20 +
src/define.cpp | 54 +
src/define.h | 99 +
src/definition.cpp | 1898 +++
src/definition.h | 398 +
src/dia.cpp | 88 +
src/dia.h | 30 +
src/diagram.cpp | 1386 ++
src/diagram.h | 44 +
src/dirdef.cpp | 938 ++
src/dirdef.h | 187 +
src/docbookgen.cpp | 1983 +++
src/docbookgen.h | 20 +
src/docbookvisitor.cpp | 1456 ++
src/docbookvisitor.h | 171 +
src/docparser.cpp | 7388 +++++++++
src/docparser.h | 1378 ++
src/docsets.cpp | 538 +
src/docsets.h | 86 +
src/doctokenizer.h | 165 +
src/doctokenizer.l | 1455 ++
src/docvisitor.h | 201 +
src/dot.cpp | 4851 ++++++
src/dot.h | 458 +
src/doxygen.bst | 1388 ++
src/doxygen.cpp | 11602 ++++++++++++++
src/doxygen.css | 1440 ++
src/doxygen.h | 195 +
src/doxygen.md | 227 +
src/doxygen.pro | 47 +
src/doxygen.pro.in | 40 +
src/doxygen.sty | 478 +
src/dynsections.js | 97 +
src/eclipsehelp.cpp | 237 +
src/eclipsehelp.h | 79 +
src/entry.cpp | 444 +
src/entry.h | 382 +
src/example.h | 48 +
src/extsearch.js | 129 +
src/filedef.cpp | 1821 +++
src/filedef.h | 323 +
src/filename.cpp | 146 +
src/filename.h | 74 +
src/fileparser.cpp | 51 +
src/fileparser.h | 50 +
src/filestorage.h | 135 +
src/footer.html | 20 +
src/formula.cpp | 328 +
src/formula.h | 62 +
src/fortrancode.h | 37 +
src/fortrancode.l | 1237 ++
src/fortranscanner.h | 74 +
src/fortranscanner.l | 2429 +++
src/ftextstream.cpp | 260 +
src/ftextstream.h | 82 +
src/ftvhelp.cpp | 1335 ++
src/ftvhelp.h | 77 +
src/groupdef.cpp | 1521 ++
src/groupdef.h | 199 +
src/growbuf.h | 47 +
src/header.html | 54 +
src/htags.cpp | 178 +
src/htags.h | 29 +
src/htmlattrib.h | 78 +
src/htmldocvisitor.cpp | 2098 +++
src/htmldocvisitor.h | 177 +
src/htmlentity.cpp | 500 +
src/htmlentity.h | 47 +
src/htmlgen.cpp | 3479 +++++
src/htmlgen.h | 362 +
src/htmlhelp.cpp | 714 +
src/htmlhelp.h | 105 +
src/image.cpp | 540 +
src/image.h | 71 +
src/increasebuffer.py | 7 +
src/index.cpp | 4272 ++++++
src/index.h | 288 +
src/index.xsd | 66 +
src/jquery_fx.js | 1 +
src/jquery_p1.js | 18 +
src/jquery_p2.js | 10 +
src/jquery_p3.js | 3 +
src/jquery_pt.js | 8 +
src/jquery_ui.js | 40 +
src/lang_cfg.py | 8 +
src/language.cpp | 422 +
src/language.h | 26 +
src/languages.py | 106 +
src/latexdocvisitor.cpp | 1865 +++
src/latexdocvisitor.h | 204 +
src/latexgen.cpp | 2231 +++
src/latexgen.h | 292 +
src/layout.cpp | 1464 ++
src/layout.h | 206 +
src/layout_default.h | 194 +
src/layout_default.xml | 194 +
src/libdoxycfg.pro | 34 +
src/libdoxycfg.pro.in | 27 +
src/libdoxycfg.t | 53 +
src/libdoxycfg.t.in | 53 +
src/libdoxygen.pro | 245 +
src/libdoxygen.pro.in | 238 +
src/libdoxygen.t | 208 +
src/libdoxygen.t.in | 208 +
src/lodepng.cpp | 4158 +++++
src/lodepng.h | 1575 ++
src/logos.cpp | 1985 +++
src/logos.h | 27 +
src/main.cpp | 41 +
src/mandocvisitor.cpp | 1031 ++
src/mandocvisitor.h | 166 +
src/mangen.cpp | 837 +
src/mangen.h | 276 +
src/markdown.cpp | 2455 +++
src/markdown.h | 62 +
src/marshal.cpp | 801 +
src/marshal.h | 97 +
src/memberdef.cpp | 5098 ++++++
src/memberdef.h | 440 +
src/membergroup.cpp | 407 +
src/membergroup.h | 148 +
src/memberlist.cpp | 963 ++
src/memberlist.h | 129 +
src/membername.cpp | 77 +
src/membername.h | 104 +
src/message.cpp | 243 +
src/message.h | 35 +
src/msc.cpp | 224 +
src/msc.h | 39 +
src/namespacedef.cpp | 1135 ++
src/namespacedef.h | 187 +
src/navtree.css | 143 +
src/navtree.js | 527 +
src/objcache.cpp | 329 +
src/objcache.h | 127 +
src/outputgen.cpp | 83 +
src/outputgen.h | 557 +
src/outputlist.cpp | 358 +
src/outputlist.h | 554 +
src/pagedef.cpp | 321 +
src/pagedef.h | 92 +
src/parserintf.h | 205 +
src/perlmodgen.cpp | 2987 ++++
src/perlmodgen.h | 23 +
src/plantuml.cpp | 97 +
src/plantuml.h | 40 +
src/portable.cpp | 442 +
src/portable.h | 47 +
src/portable_c.c | 30 +
src/pre.h | 29 +
src/pre.l | 3208 ++++
src/printdocvisitor.h | 728 +
src/pycode.h | 43 +
src/pycode.l | 1510 ++
src/pyscanner.h | 67 +
src/pyscanner.l | 1744 +++
src/qhp.cpp | 367 +
src/qhp.h | 72 +
src/qhpxmlwriter.cpp | 157 +
src/qhpxmlwriter.h | 64 +
src/qtbc.h | 21 +
src/reflist.cpp | 171 +
src/reflist.h | 92 +
src/resize.js | 97 +
src/resize_js.h | 93 +
src/rtfdocvisitor.cpp | 1738 +++
src/rtfdocvisitor.h | 174 +
src/rtfgen.cpp | 2949 ++++
src/rtfgen.h | 298 +
src/rtfstyle.cpp | 518 +
src/rtfstyle.h | 82 +
src/scanner.h | 62 +
src/scanner.l | 7021 +++++++++
src/search.css | 271 +
src/search.js | 776 +
src/search_functions.php | 366 +
src/search_opensearch.php | 127 +
src/searchindex.cpp | 1391 ++
src/searchindex.h | 115 +
src/section.h | 74 +
src/settings.py | 29 +
src/sortdict.h | 734 +
src/sqlite3gen.cpp | 1370 ++
src/sqlite3gen.h | 23 +
src/store.cpp | 484 +
src/store.h | 123 +
src/svgpan.js | 319 +
src/tagreader.cpp | 1512 ++
src/tagreader.h | 26 +
src/tclscanner.h | 59 +
src/tclscanner.l | 3095 ++++
src/template.cpp | 4799 ++++++
src/template.h | 539 +
src/textdocvisitor.cpp | 62 +
src/textdocvisitor.h | 145 +
src/to_c_cmd.py | 8 +
src/tooltip.cpp | 132 +
src/tooltip.h | 37 +
src/translator.h | 575 +
src/translator_adapter.h | 298 +
src/translator_am.h | 1804 +++
src/translator_ar.h | 1569 ++
src/translator_br.h | 1838 +++
src/translator_ca.h | 1843 +++
src/translator_cn.h | 1800 +++
src/translator_cz.h | 2042 +++
src/translator_de.h | 2045 +++
src/translator_dk.h | 1785 +++
src/translator_en.h | 1999 +++
src/translator_eo.h | 1948 +++
src/translator_es.h | 2063 +++
src/translator_fa.h | 1784 +++
src/translator_fi.h | 1859 +++
src/translator_fr.h | 2060 +++
src/translator_gr.h | 1922 +++
src/translator_hr.h | 1576 ++
src/translator_hu.h | 1498 ++
src/translator_id.h | 1817 +++
src/translator_it.h | 1860 +++
src/translator_je.h | 55 +
src/translator_jp.h | 1980 +++
src/translator_ke.h | 54 +
src/translator_kr.h | 2009 +++
src/translator_lt.h | 1515 ++
src/translator_lv.h | 1951 +++
src/translator_mk.h | 1723 +++
src/translator_nl.h | 1591 ++
src/translator_no.h | 1569 ++
src/translator_pl.h | 1867 +++
src/translator_pt.h | 1840 +++
src/translator_ro.h | 2020 +++
src/translator_ru.h | 1974 +++
src/translator_sc.h | 1765 +++
src/translator_si.h | 1212 ++
src/translator_sk.h | 1971 +++
src/translator_sr.h | 1774 +++
src/translator_sv.h | 1882 +++
src/translator_tr.h | 1822 +++
src/translator_tw.h | 1973 +++
src/translator_ua.h | 1917 +++
src/translator_vi.h | 1743 +++
src/translator_za.h | 1723 +++
src/types.h | 220 +
src/util.cpp | 8279 ++++++++++
src/util.h | 462 +
src/version.cpp | 1 +
src/version.h | 23 +
src/version.py | 58 +
src/vhdlcode.h | 16 +
src/vhdlcode.l | 1628 ++
src/vhdldocgen.cpp | 4483 ++++++
src/vhdldocgen.h | 345 +
src/vhdljjparser.cpp | 828 +
src/vhdljjparser.h | 102 +
src/xmldocvisitor.cpp | 1055 ++
src/xmldocvisitor.h | 169 +
src/xmlgen.cpp | 2052 +++
src/xmlgen.h | 20 +
testing/001/indexpage.xml | 10 +
testing/001_a.dox | 5 +
testing/002/indexpage.xml | 15 +
testing/002_addindex.dox | 5 +
testing/003/indexpage.xml | 10 +
testing/003_anchor.dox | 8 +
testing/004/indexpage.xml | 13 +
testing/004_arg.dox | 15 +
testing/005/indexpage.xml | 35 +
testing/005_attention.dox | 14 +
testing/006/indexpage.xml | 26 +
testing/006_author.dox | 9 +
testing/007/indexpage.xml | 10 +
testing/007_b.dox | 5 +
testing/008/008__brief_8c.xml | 13 +
testing/008_brief.c | 7 +
testing/009/bug.xml | 26 +
testing/009/class_bug.xml | 43 +
testing/009/class_deprecated.xml | 41 +
testing/009/class_reminder.xml | 48 +
testing/009/class_test.xml | 48 +
testing/009/class_todo.xml | 48 +
testing/009/deprecated.xml | 25 +
testing/009/reminders.xml | 25 +
testing/009/test.xml | 25 +
testing/009/todo.xml | 25 +
testing/009_bug.cpp | 62 +
testing/010/indexpage.xml | 11 +
testing/010_c.dox | 7 +
testing/011/category_integer_07_arithmetic_08.xml | 60 +
testing/011/interface_integer.xml | 99 +
testing/011_category.m | 30 +
testing/012/citelist.xml | 20 +
testing/012/indexpage.xml | 10 +
testing/012_cite.dox | 7 +
testing/013/class_t1.xml | 15 +
testing/013/class_t2.xml | 15 +
testing/013/class_t3.xml | 15 +
testing/013/class_t4.xml | 15 +
testing/013_class.h | 37 +
testing/014/indexpage.xml | 42 +
testing/014_code.dox | 14 +
testing/015/015__cond_8c.xml | 26 +
testing/015_cond.c | 30 +
testing/016/016__copydoc_8c.xml | 76 +
testing/016_copydoc.c | 23 +
testing/017/indexpage.xml | 17 +
testing/017_copyright.dox | 6 +
testing/018/018__def_8c.xml | 125 +
testing/018_def.c | 37 +
testing/019/group__g1.xml | 28 +
testing/019/group__g2.xml | 29 +
testing/019/group__g3.xml | 42 +
testing/019_defgroup.c | 48 +
testing/020/indexpage.xml | 24 +
testing/020_only.dox | 27 +
testing/021/indexpage.xml | 10 +
testing/021_dontinclude.cpp | 24 +
testing/022/indexpage.xml | 17 +
testing/022_dot.cpp | 22 +
testing/023/indexpage.xml | 10 +
testing/023_e.dox | 5 +
testing/024/indexpage.xml | 10 +
testing/024_if.dox | 21 +
testing/025/class_test.xml | 36 +
testing/025/example_test_8cpp-example.xml | 10 +
testing/025_example.cpp | 26 +
testing/026/class_test.xml | 52 +
testing/026_exception.cpp | 21 +
testing/027/struct_car.xml | 95 +
testing/027/struct_object.xml | 105 +
testing/027/struct_truck.xml | 95 +
testing/027/struct_vehicle.xml | 132 +
testing/027_extends.c | 93 +
testing/028/indexpage.xml | 11 +
testing/028_formula.c | 17 +
testing/029/029__hideinit_8c.xml | 42 +
testing/029_hideinit.c | 12 +
testing/030/indexpage.xml | 11 +
testing/030_htmlinclude.dox | 8 +
testing/031/indexpage.xml | 12 +
testing/031_image.dox | 9 +
testing/032/indexpage.xml | 10 +
testing/032_include.cpp | 11 +
testing/033/indexpage.xml | 11 +
testing/033_internal.dox | 12 +
testing/034/indexpage.xml | 29 +
testing/034_internal.dox | 21 +
testing/035/035__invariant_8c.xml | 45 +
testing/035_invariant.c | 15 +
testing/036/036__link_8c.xml | 33 +
testing/036_link.c | 16 +
testing/037/class_receiver.xml | 42 +
testing/037/class_sender.xml | 42 +
testing/037_msc.cpp | 33 +
testing/038/indexpage.xml | 12 +
testing/038_n.dox | 7 +
testing/039/class_test.xml | 74 +
testing/039_name.cpp | 25 +
testing/040/namespace_n_s.xml | 12 +
testing/040_namespace.cpp | 10 +
testing/041/class_test.xml | 100 +
testing/041_overload.cpp | 33 +
testing/042/namespaceorg_1_1doxygen_1_1_test.xml | 12 +
testing/042_package.java | 8 +
testing/043/another.xml | 10 +
testing/043/mypage.xml | 34 +
testing/043_page.dox | 22 +
testing/044/struct_s.xml | 129 +
testing/044_section.h | 28 +
testing/045/indexpage.xml | 21 +
testing/045_refitem.dox | 20 +
testing/046/046__related_8cpp.xml | 28 +
testing/046/class_test.xml | 80 +
testing/046_related.cpp | 28 +
testing/047/047__return_8cpp.xml | 58 +
testing/047_return.cpp | 20 +
testing/048/048__showinit_8c.xml | 42 +
testing/048_showinit.c | 13 +
testing/049/indexpage.xml | 10 +
testing/049_snippet.cpp | 13 +
testing/050/indexpage.xml | 18 +
testing/050_verbatim.dox | 14 +
testing/051/indexpage.xml | 10 +
testing/051_escape.dox | 18 +
testing/052/indexpage.xml | 10 +
testing/052_tilde.dox | 9 +
testing/053/indexpage.xml | 10 +
testing/053_tilde.dox | 10 +
testing/054/054__parblock_8cpp.xml | 103 +
testing/054_parblock.cpp | 32 +
testing/055/md_055_markdown.xml | 28 +
testing/055_markdown.md | 22 +
testing/056/indexpage.xml | 11 +
testing/056_latexinclude.dox | 8 +
testing/057/057__caller__graphs_8tcl.xml | 92 +
testing/057/__057__caller__graphs_8tcl.xml | 28 +
testing/057/namespace1.xml | 113 +
testing/057/namespace1_1_11.xml | 28 +
testing/057/namespace1_1_11_1_11.xml | 26 +
testing/057/namespace2.xml | 30 +
testing/057/namespace2_1_12.xml | 29 +
testing/057/namespace2_1_12_1_12.xml | 29 +
testing/057/namespace2_1_12_1_12_1_12.xml | 29 +
testing/057/namespace2_1_12_1_12_1_12_1_12.xml | 28 +
testing/057/namespacebar.xml | 57 +
testing/057/namespacefoo.xml | 27 +
testing/057_caller_graphs.tcl | 155 +
testing/058/058__bracket__recursion_8tcl.xml | 384 +
testing/058_bracket_recursion.tcl | 157 +
testing/059/059__command__catch_8tcl.xml | 191 +
testing/059_command_catch.tcl | 87 +
testing/060/060__command__switch_8tcl.xml | 326 +
testing/060_command_switch.tcl | 238 +
testing/061/class_test.xml | 70 +
testing/061_bug_705503.tcl | 19 +
testing/062/namespacen1.xml | 42 +
testing/062/namespacen2.xml | 42 +
testing/062/namespacen3.xml | 42 +
testing/062_namespace_resolution.tcl | 68 +
testing/063/namespaceoo.xml | 13 +
testing/063/namespaceoo_1_1_helpers.xml | 27 +
testing/063/namespaceoo_1_1define.xml | 27 +
testing/063_bug_729092.tcl | 43 +
testing/Doxyfile | 7 +
testing/Makefile | 3 +
testing/README | 48 +
testing/_057_caller_graphs.tcl | 4 +
testing/debug.txt | 30 +
testing/example_test.cpp | 6 +
testing/html/063__bug__729092_8tcl.html | 111 +
testing/html/bc_s.png | Bin 0 -> 676 bytes
testing/html/bdwn.png | Bin 0 -> 147 bytes
testing/html/closed.png | Bin 0 -> 132 bytes
testing/html/doxygen.css | 1440 ++
testing/html/doxygen.png | Bin 0 -> 3779 bytes
testing/html/dynsections.js | 97 +
testing/html/files.html | 98 +
testing/html/ftv2blank.png | Bin 0 -> 86 bytes
testing/html/ftv2doc.png | Bin 0 -> 746 bytes
testing/html/ftv2folderclosed.png | Bin 0 -> 616 bytes
testing/html/ftv2folderopen.png | Bin 0 -> 597 bytes
testing/html/ftv2lastnode.png | Bin 0 -> 86 bytes
testing/html/ftv2link.png | Bin 0 -> 746 bytes
testing/html/ftv2mlastnode.png | Bin 0 -> 246 bytes
testing/html/ftv2mnode.png | Bin 0 -> 246 bytes
testing/html/ftv2node.png | Bin 0 -> 86 bytes
testing/html/ftv2plastnode.png | Bin 0 -> 229 bytes
testing/html/ftv2pnode.png | Bin 0 -> 229 bytes
testing/html/ftv2splitbar.png | Bin 0 -> 314 bytes
testing/html/ftv2vertline.png | Bin 0 -> 86 bytes
testing/html/index.html | 88 +
testing/html/jquery.js | 31 +
testing/html/namespacemembers.html | 104 +
testing/html/namespacemembers_func.html | 104 +
testing/html/namespaceoo.html | 104 +
testing/html/namespaceoo_1_1_helpers.html | 128 +
testing/html/namespaceoo_1_1define.html | 128 +
testing/html/namespaces.html | 101 +
testing/html/nav_f.png | Bin 0 -> 153 bytes
testing/html/nav_g.png | Bin 0 -> 95 bytes
testing/html/nav_h.png | Bin 0 -> 98 bytes
testing/html/open.png | Bin 0 -> 123 bytes
testing/html/search/all_0.html | 26 +
testing/html/search/all_0.js | 4 +
testing/html/search/all_1.html | 26 +
testing/html/search/all_1.js | 5 +
testing/html/search/all_2.html | 26 +
testing/html/search/all_2.js | 6 +
testing/html/search/close.png | Bin 0 -> 273 bytes
testing/html/search/files_0.html | 26 +
testing/html/search/files_0.js | 4 +
testing/html/search/functions_0.html | 26 +
testing/html/search/functions_0.js | 5 +
testing/html/search/mag_sel.png | Bin 0 -> 563 bytes
testing/html/search/namespaces_0.html | 26 +
testing/html/search/namespaces_0.js | 6 +
testing/html/search/nomatches.html | 12 +
testing/html/search/search.css | 271 +
testing/html/search/search.js | 799 +
testing/html/search/search_l.png | Bin 0 -> 604 bytes
testing/html/search/search_m.png | Bin 0 -> 158 bytes
testing/html/search/search_r.png | Bin 0 -> 612 bytes
testing/html/sync_off.png | Bin 0 -> 853 bytes
testing/html/sync_on.png | Bin 0 -> 845 bytes
testing/html/tab_a.png | Bin 0 -> 142 bytes
testing/html/tab_b.png | Bin 0 -> 169 bytes
testing/html/tab_h.png | Bin 0 -> 177 bytes
testing/html/tab_s.png | Bin 0 -> 184 bytes
testing/html/tabs.css | 60 +
testing/runtests.pl | 252 +
testing/sample.bib | 7 +
testing/sample.html | 1 +
testing/sample.png | Bin 0 -> 3779 bytes
testing/sample.tex | 1 +
testing/snippet_test.cpp | 41 +
testing/testsqlite3.py | 146 +
tmake/CHANGES | 49 +
tmake/LICENSE | 9 +
tmake/README | 10 +
tmake/bin/progen | 249 +
tmake/bin/tmake | 1262 ++
tmake/doc/m-linux-gcc.html | 85 +
tmake/doc/m-win32-msvc.html | 89 +
tmake/doc/tmake.html | 727 +
tmake/doc/tmake_ref.html | 463 +
tmake/example/hello.cpp | 102 +
tmake/example/hello.h | 34 +
tmake/example/hello.pro | 3 +
tmake/example/main.cpp | 38 +
tmake/example/wc.t | 6 +
tmake/lib/aix-g++/app.t | 2 +
tmake/lib/aix-g++/lib.t | 2 +
tmake/lib/aix-g++/subdirs.t | 2 +
tmake/lib/aix-g++/tmake.conf | 58 +
tmake/lib/aix-xlc/app.t | 2 +
tmake/lib/aix-xlc/lib.t | 2 +
tmake/lib/aix-xlc/subdirs.t | 2 +
tmake/lib/aix-xlc/tmake.conf | 64 +
tmake/lib/beos-g++/app.t | 2 +
tmake/lib/beos-g++/lib.t | 2 +
tmake/lib/beos-g++/subdirs.t | 2 +
tmake/lib/beos-g++/tmake.conf | 51 +
tmake/lib/bsdi-g++/app.t | 2 +
tmake/lib/bsdi-g++/lib.t | 2 +
tmake/lib/bsdi-g++/subdirs.t | 2 +
tmake/lib/bsdi-g++/tmake.conf | 61 +
tmake/lib/dgux-g++/app.t | 2 +
tmake/lib/dgux-g++/lib.t | 2 +
tmake/lib/dgux-g++/subdirs.t | 2 +
tmake/lib/dgux-g++/tmake.conf | 59 +
tmake/lib/freebsd-g++/app.t | 2 +
tmake/lib/freebsd-g++/lib.t | 2 +
tmake/lib/freebsd-g++/subdirs.t | 2 +
tmake/lib/freebsd-g++/tmake.conf | 60 +
tmake/lib/gnu-g++/app.t | 2 +
tmake/lib/gnu-g++/lib.t | 2 +
tmake/lib/gnu-g++/subdirs.t | 2 +
tmake/lib/gnu-g++/tmake.conf | 58 +
tmake/lib/hpux-acc/app.t | 2 +
tmake/lib/hpux-acc/lib.t | 2 +
tmake/lib/hpux-acc/subdirs.t | 2 +
tmake/lib/hpux-acc/tmake.conf | 60 +
tmake/lib/hpux-cc/app.t | 2 +
tmake/lib/hpux-cc/lib.t | 2 +
tmake/lib/hpux-cc/subdirs.t | 2 +
tmake/lib/hpux-cc/tmake.conf | 59 +
tmake/lib/hpux-g++/app.t | 2 +
tmake/lib/hpux-g++/lib.t | 2 +
tmake/lib/hpux-g++/subdirs.t | 2 +
tmake/lib/hpux-g++/tmake.conf | 60 +
tmake/lib/irix-64/app.t | 2 +
tmake/lib/irix-64/lib.t | 2 +
tmake/lib/irix-64/subdirs.t | 2 +
tmake/lib/irix-64/tmake.conf | 60 +
tmake/lib/irix-dcc/app.t | 2 +
tmake/lib/irix-dcc/lib.t | 2 +
tmake/lib/irix-dcc/subdirs.t | 2 +
tmake/lib/irix-dcc/tmake.conf | 60 +
tmake/lib/irix-g++/app.t | 2 +
tmake/lib/irix-g++/lib.t | 2 +
tmake/lib/irix-g++/subdirs.t | 2 +
tmake/lib/irix-g++/tmake.conf | 60 +
tmake/lib/irix-n32/app.t | 2 +
tmake/lib/irix-n32/lib.t | 2 +
tmake/lib/irix-n32/subdirs.t | 2 +
tmake/lib/irix-n32/tmake.conf | 60 +
tmake/lib/irix-o32/app.t | 2 +
tmake/lib/irix-o32/lib.t | 2 +
tmake/lib/irix-o32/subdirs.t | 2 +
tmake/lib/irix-o32/tmake.conf | 60 +
tmake/lib/linux-64/app.t | 2 +
tmake/lib/linux-64/lib.t | 2 +
tmake/lib/linux-64/subdirs.t | 2 +
tmake/lib/linux-64/tmake.conf | 59 +
tmake/lib/linux-g++/app.t | 2 +
tmake/lib/linux-g++/lib.t | 2 +
tmake/lib/linux-g++/subdirs.t | 2 +
tmake/lib/linux-g++/tmake.conf | 59 +
tmake/lib/m68k-atari-mint-g++/app.t | 2 +
tmake/lib/m68k-atari-mint-g++/lib.t | 2 +
tmake/lib/m68k-atari-mint-g++/subdirs.t | 2 +
tmake/lib/m68k-atari-mint-g++/tmake.conf | 59 +
tmake/lib/macosx-c++/app.t | 2 +
tmake/lib/macosx-c++/lib.t | 2 +
tmake/lib/macosx-c++/subdirs.t | 2 +
tmake/lib/macosx-c++/tmake.conf | 59 +
tmake/lib/macosx-intel-c++/app.t | 2 +
tmake/lib/macosx-intel-c++/lib.t | 2 +
tmake/lib/macosx-intel-c++/subdirs.t | 2 +
tmake/lib/macosx-intel-c++/tmake.conf | 59 +
tmake/lib/macosx-uni-c++/app.t | 2 +
tmake/lib/macosx-uni-c++/lib.t | 2 +
tmake/lib/macosx-uni-c++/subdirs.t | 2 +
tmake/lib/macosx-uni-c++/tmake.conf | 59 +
tmake/lib/netbsd-g++/app.t | 2 +
tmake/lib/netbsd-g++/lib.t | 2 +
tmake/lib/netbsd-g++/subdirs.t | 2 +
tmake/lib/netbsd-g++/tmake.conf | 61 +
tmake/lib/openbsd-g++/app.t | 2 +
tmake/lib/openbsd-g++/lib.t | 2 +
tmake/lib/openbsd-g++/subdirs.t | 2 +
tmake/lib/openbsd-g++/tmake.conf | 61 +
tmake/lib/osf1-cxx/app.t | 2 +
tmake/lib/osf1-cxx/lib.t | 2 +
tmake/lib/osf1-cxx/subdirs.t | 2 +
tmake/lib/osf1-cxx/tmake.conf | 60 +
tmake/lib/osf1-g++/app.t | 2 +
tmake/lib/osf1-g++/lib.t | 2 +
tmake/lib/osf1-g++/subdirs.t | 2 +
tmake/lib/osf1-g++/tmake.conf | 58 +
tmake/lib/qnx-g++/app.t | 2 +
tmake/lib/qnx-g++/lib.t | 2 +
tmake/lib/qnx-g++/subdirs.t | 2 +
tmake/lib/qnx-g++/tmake.conf | 58 +
tmake/lib/sco-g++/app.t | 2 +
tmake/lib/sco-g++/lib.t | 2 +
tmake/lib/sco-g++/subdirs.t | 2 +
tmake/lib/sco-g++/tmake.conf | 58 +
tmake/lib/solaris-cc-64/app.t | 2 +
tmake/lib/solaris-cc-64/lib.t | 2 +
tmake/lib/solaris-cc-64/subdirs.t | 2 +
tmake/lib/solaris-cc-64/tmake.conf | 61 +
tmake/lib/solaris-cc-gcc/app.t | 2 +
tmake/lib/solaris-cc-gcc/lib.t | 2 +
tmake/lib/solaris-cc-gcc/subdirs.t | 2 +
tmake/lib/solaris-cc-gcc/tmake.conf | 62 +
tmake/lib/solaris-cc/app.t | 2 +
tmake/lib/solaris-cc/lib.t | 2 +
tmake/lib/solaris-cc/subdirs.t | 2 +
tmake/lib/solaris-cc/tmake.conf | 61 +
tmake/lib/solaris-g++/app.t | 2 +
tmake/lib/solaris-g++/lib.t | 2 +
tmake/lib/solaris-g++/subdirs.t | 2 +
tmake/lib/solaris-g++/tmake.conf | 59 +
tmake/lib/sunos-g++/app.t | 2 +
tmake/lib/sunos-g++/lib.t | 2 +
tmake/lib/sunos-g++/subdirs.t | 2 +
tmake/lib/sunos-g++/tmake.conf | 58 +
tmake/lib/ultrix-g++/app.t | 2 +
tmake/lib/ultrix-g++/lib.t | 2 +
tmake/lib/ultrix-g++/subdirs.t | 2 +
tmake/lib/ultrix-g++/tmake.conf | 58 +
tmake/lib/unix/app.t | 6 +
tmake/lib/unix/generic.t | 283 +
tmake/lib/unix/lib.t | 6 +
tmake/lib/unix/subdirs.t | 38 +
tmake/lib/unixware-g++/app.t | 2 +
tmake/lib/unixware-g++/lib.t | 2 +
tmake/lib/unixware-g++/subdirs.t | 2 +
tmake/lib/unixware-g++/tmake.conf | 60 +
tmake/lib/unixware7-cc/app.t | 2 +
tmake/lib/unixware7-cc/lib.t | 2 +
tmake/lib/unixware7-cc/subdirs.t | 2 +
tmake/lib/unixware7-cc/tmake.conf | 60 +
tmake/lib/unixware7-g++/app.t | 2 +
tmake/lib/unixware7-g++/lib.t | 2 +
tmake/lib/unixware7-g++/subdirs.t | 2 +
tmake/lib/unixware7-g++/tmake.conf | 60 +
tmake/lib/win32-borland/app.t | 6 +
tmake/lib/win32-borland/generic.t | 237 +
tmake/lib/win32-borland/lib.t | 6 +
tmake/lib/win32-borland/subdirs.t | 3 +
tmake/lib/win32-borland/tmake.conf | 56 +
tmake/lib/win32-g++/app.t | 6 +
tmake/lib/win32-g++/generic.t | 243 +
tmake/lib/win32-g++/lib.t | 6 +
tmake/lib/win32-g++/subdirs.t | 2 +
tmake/lib/win32-g++/tmake.conf | 56 +
tmake/lib/win32-mingw/app.t | 6 +
tmake/lib/win32-mingw/generic.t | 239 +
tmake/lib/win32-mingw/lib.t | 6 +
tmake/lib/win32-mingw/subdirs.t | 2 +
tmake/lib/win32-mingw/tmake.conf | 56 +
tmake/lib/win32-msvc/app.t | 6 +
tmake/lib/win32-msvc/generic.t | 229 +
tmake/lib/win32-msvc/lib.t | 6 +
tmake/lib/win32-msvc/subdirs.t | 2 +
tmake/lib/win32-msvc/tmake.conf | 65 +
tmake/lib/win32-msvc/vcapp.t | 244 +
tmake/lib/win32-msvc/vclib.t | 178 +
tmake/lib/win32-symantec/app.t | 6 +
tmake/lib/win32-symantec/generic.t | 211 +
tmake/lib/win32-symantec/lib.t | 6 +
tmake/lib/win32-symantec/subdirs.t | 2 +
tmake/lib/win32-symantec/tmake.conf | 56 +
tmake/lib/win32-visage/app.t | 6 +
tmake/lib/win32-visage/generic.t | 207 +
tmake/lib/win32-visage/lib.t | 6 +
tmake/lib/win32-visage/subdirs.t | 2 +
tmake/lib/win32-visage/tmake.conf | 56 +
tmake/lib/win32-watcom/app.t | 6 +
tmake/lib/win32-watcom/generic.t | 201 +
tmake/lib/win32-watcom/lib.t | 6 +
tmake/lib/win32-watcom/subdirs.t | 2 +
tmake/lib/win32-watcom/tmake.conf | 54 +
tmake/lib/win32/subdirs.t | 54 +
vhdlparser/CharStream.cc | 212 +
vhdlparser/CharStream.h | 257 +
vhdlparser/ErrorHandler.h | 78 +
vhdlparser/JavaCC.h | 52 +
vhdlparser/JavaCC.h.in | 52 +
vhdlparser/Makefile | 62 +
vhdlparser/Makefile.in | 40 +
vhdlparser/Makefile.vhdlparser | 165 +
vhdlparser/ParseException.cc | 186 +
vhdlparser/ParseException.h | 99 +
vhdlparser/Token.cc | 92 +
vhdlparser/Token.h | 116 +
vhdlparser/TokenManager.h | 33 +
vhdlparser/TokenMgrError.cc | 121 +
vhdlparser/TokenMgrError.h | 90 +
vhdlparser/VhdlParser.cc | 13071 ++++++++++++++++
vhdlparser/VhdlParser.h | 8984 +++++++++++
vhdlparser/VhdlParserConstants.h | 950 ++
vhdlparser/VhdlParserErrorHandler.hpp | 40 +
vhdlparser/VhdlParserIF.cpp | 55 +
vhdlparser/VhdlParserIF.h | 12 +
vhdlparser/VhdlParserTokenManager.cc | 3605 +++++
vhdlparser/VhdlParserTokenManager.h | 139 +
vhdlparser/vhdlparser.jj | 2816 ++++
vhdlparser/vhdlparser.patch | 10 +
vhdlparser/vhdlparser.pro | 40 +
vhdlparser/vhdlparser.pro.in | 33 +
vhdlparser/vhdlstring.h | 101 +
winbuild/.gitignore | 7 +
winbuild/Config.rules | 30 +
winbuild/Doxygen.sln | 71 +
winbuild/Doxygen.vcproj | 2989 ++++
winbuild/Doxywizard.vcproj | 718 +
winbuild/Gen_head.rules | 19 +
winbuild/Languages.rules | 862 ++
winbuild/Lex.rules | 34 +
winbuild/Settings.rules | 59 +
winbuild/Unistd.rules | 18 +
winbuild/Version.rules | 19 +
winbuild/doxyindexer.vcproj | 363 +
winbuild/doxysearch.vcproj | 359 +
winbuild/iconv.h | 141 +
winbuild/iconv.lib | Bin 0 -> 958612 bytes
winbuild/iconv.vcproj | 468 +
winbuild/iconv64.lib | Bin 0 -> 1206128 bytes
winbuild/moc.rules | 20 +
winbuild/pack_the_distribution_for_windows.py | 234 +
winbuild/qtools.vcproj | 1587 ++
winbuild/unistd.py | 16 +
1165 files changed, 460113 insertions(+)
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..325a875
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,315 @@
+# Doxyfile 1.8.7
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = Doxygen
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = doxygen_docs
+CREATE_SUBDIRS = YES
+ALLOW_UNICODE_NAMES = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+SHOW_GROUPED_MEMB_INC = NO
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text "
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = src \
+ vhdlparser
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.h \
+ *.cpp \
+ *.md
+RECURSIVE = NO
+EXCLUDE = src/logos.cpp \
+ src/lodepng.cpp
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = YES
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = YES
+DOCSET_FEEDNAME = "Doxygen docs"
+DOCSET_BUNDLE_ID = org.doxygen.Doxygen
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = YES
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT =
+MAN_EXTENSION = .3
+MAN_SUBDIR =
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+DOCBOOK_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH = qtools \
+ libmd5
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+TAGFILES = qtools_docs/qtools.tag=../../qtools_docs/html
+GENERATE_TAGFILE = doxygen.tag
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+MSCGEN_PATH =
+DIA_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = svg
+INTERACTIVE_SVG = YES
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DIAFILE_DIRS =
+PLANTUML_JAR_PATH =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..d94748f
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,7 @@
+DOXYGEN
+
+Please read the installation section of the manual
+(http://www.doxygen.org/install.html) for instructions.
+
+--------
+Dimitri van Heesch
diff --git a/LANGUAGE.HOWTO b/LANGUAGE.HOWTO
new file mode 100644
index 0000000..e535a05
--- /dev/null
+++ b/LANGUAGE.HOWTO
@@ -0,0 +1,50 @@
+This short howto explains how to add support for a new language to Doxygen:
+
+Just follow these steps:
+
+1) Tell me which language you want to add support for. If no one else
+ is already working on support for that language, you will be
+ assigned as the maintainer for the language. I'll create a
+ list on Doxygen's homepage, so everyone knows who is doing what.
+2) Create a copy of translator_en.h and name it
+ translator_<your_2_letter_country_code>.h
+ I'll use xx in the rest of this document.
+3) Edit language.cpp:
+ - Add a #include<translator_xx.h>
+ - In setTranslator() add
+
+ else if (L_EQUAL("your_language_name"))
+ {
+ theTranslator = new TranslatorYourLanguage;
+ }
+
+ after the if { ... }
+4) Edit libdoxygen.pro.in and add translator_xx.h to the HEADERS line.
+5) Edit translator_xx.h:
+ - Change TRANSLATOR_EN_H to TRANSLATOR_XX_H (in both the #include line and
+ the #define line).
+ - Change TranslatorEnglish to TranslatorYourLanguage
+ - In the member idLanguage() change "english" into the name of your
+ language (use lower case characters only). Depending on the language you
+ may also wish to change the member functions latexLanguageSupportCommand()
+ and idLanguageCharset().
+ - Edit all the strings that are returned by the members that start
+ with tr. Try to match punctuation and capitals!
+ To enter special characters (with accents) you can:
+ a) Enter them directly if your keyboard supports that and you are
+ using a Latin-1 font.
+ Doxygen will translate the characters to proper Latex and
+ leave the Html and man output for what it is (which is fine, if
+ idLanguageCharset() is set correctly).
+ b) Use html codes like ä for an a with an umlaut (i.e. �).
+ See the HTML specification for the codes.
+6) Run configure and make again from the root of the distribution,
+ in order to regenerate the Makefiles.
+7) Now you can use OUTPUT_LANGUAGE = your_language_name
+ in the config file to generate output in your language.
+8) Send translator_xx.h to me so I can add it to doxygen.
+ Send also your name and e-mail address to be included in the
+ maintainers.txt list.
+
+Good luck, and let me know if there are problems.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..219ec28
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) yyyy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) yyyy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..a83f08b
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,160 @@
+
+DESTDIR =
+
+doxywizard:
+ cd addon/doxywizard ; $(MAKE)
+
+doxysearch:
+ cd addon/doxysearch ; $(MAKE)
+
+doxmlparser:
+ cd addon/doxmlparser/src ; $(MAKE)
+ cd addon/doxmlparser/test ; $(MAKE)
+ cd addon/doxmlparser/examples/metrics ; $(MAKE)
+
+doxyapp:
+ cd addon/doxyapp ; $(MAKE) clean
+
+clean: FORCE
+ - cd examples ; $(MAKE) clean
+ - cd doc ; $(MAKE) clean
+ - cd qtools ; $(MAKE) clean
+ - cd src ; $(MAKE) clean
+ - cd libmd5 ; $(MAKE) clean
+ - cd vhdlparser ; $(MAKE) clean
+ -cd addon/doxywizard ; $(MAKE) clean
+ -cd addon/doxysearch ; $(MAKE) clean
+ -cd addon/doxyapp ; $(MAKE) clean
+ -cd addon/doxmlparser/src ; $(MAKE) clean
+ -cd addon/doxmlparser/test ; $(MAKE) clean
+ -cd addon/doxmlparser/examples/metrics ; $(MAKE) clean
+ -rm -f bin/doxy*
+ -rm -f objects/*/*.o
+
+distclean: clean
+ -cd src ; $(MAKE) distclean
+ -cd libmd5 ; $(MAKE) distclean
+ -cd vhdlparser ; $(MAKE) distclean
+ -cd addon/doxywizard ; $(MAKE) distclean
+ -cd addon/doxysearch ; $(MAKE) distclean
+ -cd addon/doxyapp ; $(MAKE) distclean
+ -cd addon/doxmlparser/src ; $(MAKE) distclean
+ -cd addon/doxmlparser/test ; $(MAKE) distclean
+ -cd addon/doxmlparser/examples/metrics ; $(MAKE) distclean
+ -rm -rf lib
+ -rm -rf bin
+ -rm -rf objects
+ -rm -rf html
+ -rm -rf latex
+ -rm -rf man
+ -rm -rf docbook
+ -rm -rf perlmod
+ -rm -rf rtf
+ -rm -rf xml
+ -rm -f src/Makefile.doxygen src/Makefile.libdoxygen
+ -rm -f src/Makefile.libdoxycfg src/libdoxycfg.t src/libdoxygen.t
+ -rm -f libmd5/Makefile.libmd5
+ -rm -f vhdlparser/Makefile.vhdlparser
+ -rm -f .makeconfig .tmakeconfig
+ -rm -f src/doxygen.pro src/libdoxygen.pro qtools/qtools.pro src/libdoxycfg.pro libmd5/libmd5.pro vhdlparser/vhdlparser.pro
+ -rm -rf generated_src
+ -rm -f addon/doxywizard/doxywizard.pro
+ -rm -f VERSION
+ -rm -f packages/rpm/doxygen.spec
+ -rm -r addon/doxywizard/Makefile
+ -rm -f addon/doxysearch/Makefile
+ -rm -f addon/doxyapp/Makefile
+ -rm -f addon/doxmlparser/src/Makefile
+ -rm -f addon/doxmlparser/test/Makefile
+ -rm -f addon/doxmlparser/examples/metrics/Makefile
+ -rm -f qtools/Makefile src/Makefile examples/Makefile doc/Makefile
+ -rm -f Makefile
+
+DATE=$(shell date "+%B %Y")
+
+MAN1DIR = man/man1
+
+install: doxywizard_install doxysearch_install
+ $(INSTTOOL) -d $(DESTDIR)$(INSTALL)/bin
+ $(INSTTOOL) -m 755 bin/doxygen $(DESTDIR)$(INSTALL)/bin
+ $(INSTTOOL) -d $(DESTDIR)$(INSTALL)/$(MAN1DIR)
+ cat doc/doxygen.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxygen.1
+ $(INSTTOOL) -m 644 doxygen.1 $(DESTDIR)$(INSTALL)/$(MAN1DIR)/doxygen.1
+ rm doxygen.1
+
+install_docs:
+ $(INSTTOOL) -d $(DESTDIR)$(DOCDIR)
+ $(MAKE) -C examples
+ $(MAKE) -C doc
+ $(MAKE) -C latex
+ $(INSTTOOL) -m 644 latex/doxygen_manual.pdf $(DESTDIR)$(DOCDIR)
+ cp -r examples $(DESTDIR)$(DOCDIR)
+ cp -r html $(DESTDIR)$(DOCDIR)
+
+docs: FORCE
+ cd examples ; $(MAKE)
+ cd doc ; $(MAKE)
+
+pdf: docs
+ cd latex ; $(MAKE)
+
+DISTFILES = Doxyfile vhdlparser libmd5 addon tmake doc examples bin lib objects testing \
+ qtools src configure configure.bin Makefile.in Makefile.win_nmake.in \
+ Makefile.win_make.in INSTALL LANGUAGE.HOWTO LICENSE PLATFORMS \
+ VERSION README.md packages winbuild jquery
+
+archive: clean
+ tar zcvf dx`date +%y%m%d`.tgz $(DISTFILES)
+
+DISTDIR = doxygen-`echo $(VERSION) | tr - _`
+
+dist: clean
+ rm -rf $(DISTDIR)
+ mkdir $(DISTDIR)
+ cp -a $(DISTFILES) README $(DISTDIR)
+ find $(DISTDIR) \( -name ".svn" \) -print0 | xargs -0 rm -rf
+ tar zcvf $(DISTDIR).src.tar.gz $(DISTDIR)
+ rm -rf $(DISTDIR)
+
+DISTDIR = doxygen-`echo $(VERSION) | tr - _`
+rpm: dist
+ gzip -df $(DISTDIR).src.tar.gz
+ mkdir $(DISTDIR)
+ mkdir $(DISTDIR)/packages
+ mkdir $(DISTDIR)/packages/rpm
+ cp packages/rpm/doxygen.spec $(DISTDIR)/packages/rpm
+ rm -rf $(DISTDIR)
+ gzip -9v $(DISTDIR).src.tar
+ rpmbuild -ta %%WITHDOXYWIZARD%% $(DISTDIR).src.tar.gz
+
+rpmsrc: dist
+ gzip -df $(DISTDIR).src.tar.gz
+ mkdir $(DISTDIR)
+ mkdir $(DISTDIR)/packages
+ mkdir $(DISTDIR)/packages/rpm
+ cp packages/rpm/doxygen.spec $(DISTDIR)/packages/rpm
+ tar -rvf $(DISTDIR).src.tar $(DISTDIR)/packages/rpm/doxygen.spec
+ rm -rf $(DISTDIR)
+ gzip -9v $(DISTDIR).src.tar
+ rpmbuild -ts %%WITHDOXYWIZARD%% $(DISTDIR).src.tar.gz
+
+rpmbinary: dist
+ gzip -df $(DISTDIR).src.tar.gz
+ mkdir $(DISTDIR)
+ mkdir $(DISTDIR)/packages
+ mkdir $(DISTDIR)/packages/rpm
+ cp packages/rpm/doxygen.spec $(DISTDIR)/packages/rpm
+ tar -rvf $(DISTDIR).src.tar $(DISTDIR)/packages/rpm/doxygen.spec
+ rm -rf $(DISTDIR)
+ gzip -9v $(DISTDIR).src.tar
+ rpmbuild -tb %%WITHDOXYWIZARD%% $(DISTDIR).src.tar.gz
+
+
+ctags:
+ ctags -R -f tags src addon/doxywizard qtools
+
+test: FORCE
+ make -C testing
+
+FORCE:
+
diff --git a/Makefile.win_make.in b/Makefile.win_make.in
new file mode 100644
index 0000000..1218979
--- /dev/null
+++ b/Makefile.win_make.in
@@ -0,0 +1,34 @@
+all: src\version.cpp
+ set TMAKEPATH=$(TMAKEPATH) & cd qtools & $(MAKE)
+ set TMAKEPATH=$(TMAKEPATH) & cd libmd5 & $(MAKE)
+ set TMAKEPATH=$(TMAKEPATH) & cd src & $(MAKE)
+
+clean:
+ cd examples & $(MAKE) clean
+ cd doc & $(MAKE) clean
+ cd src & $(MAKE) clean
+ -del bin\doxy*.*
+ -del objects\*.o
+
+distclean: clean
+ -del src\Makefile.libdoxygen \
+ src\Makefile.doxygen \
+ src\Makefile.libdoxycfg \
+ src\libdoxycfg.t src\libdoxygen.t
+ -del Makefile src\Makefile examples\Makefile doc\Makefile
+ -del src\libdoxygen.pro src\doxygen.pro src\libdoxycfg.pro
+ -del src\version.cpp
+
+realclean: distclean
+
+docs:
+ set TMAKEPATH=$(TMAKEPATH) & cd examples & $(MAKE)
+ set TMAKEPATH=$(TMAKEPATH) & cd doc & $(MAKE)
+
+ps: docs
+ cd latex & $(MAKE)
+
+src\version.cpp: Makefile
+ echo char versionString[]="""$(VERSION)"""; > src\version.cpp
+
+FORCE:
diff --git a/Makefile.win_nmake.in b/Makefile.win_nmake.in
new file mode 100644
index 0000000..069bb53
--- /dev/null
+++ b/Makefile.win_nmake.in
@@ -0,0 +1,51 @@
+all: src\version.cpp
+ set TMAKEPATH=$(TMAKEPATH)
+ cd qtools
+ $(MAKE)
+ cd ..
+ cd libmd5
+ $(MAKE)
+ cd ..
+ cd src
+ $(MAKE)
+
+clean: FORCE
+ cd examples
+ $(MAKE) clean
+ cd ..
+ cd doc
+ $(MAKE) clean
+ cd ..
+ cd src
+ $(MAKE) clean
+ cd ..
+ -del bin\doxy*.*
+ -del objects\*.o
+
+distclean: clean
+ -del src\Makefile.libdoxygen \
+ src\Makefile.doxygen \
+ src\Makefile.libdoxycfg \
+ src\libdoxycfg.t src\libdoxygen.t
+ -del Makefile src\Makefile examples\Makefile doc\Makefile
+ -del src\libdoxygen.pro src\doxygen.pro src\libdoxycfg.pro
+ -del src\version.cpp
+
+realclean: distclean
+
+docs: FORCE
+ cd examples
+ $(MAKE)
+ cd ..
+ cd doc
+ $(MAKE)
+ cd ..
+
+ps: docs
+ cd latex
+ $(MAKE)
+
+src\version.cpp: Makefile
+ echo char versionString[]="$(VERSION)"; > src\version.cpp
+
+FORCE:
diff --git a/PLATFORMS b/PLATFORMS
new file mode 100644
index 0000000..22a8d8c
--- /dev/null
+++ b/PLATFORMS
@@ -0,0 +1,32 @@
+aix-g++
+aix-xlc
+beos-g++
+dgux-g++
+freebsd-g++
+gnu-g++
+hpux-acc
+hpux-cc
+hpux-g++
+irix-64
+irix-dcc
+irix-g++
+irix-n32
+linux-g++
+linux-64
+macosx-c++
+macosx-uni-c++
+m68k-atari-mint-g++
+netbsd-g++
+openbsd-g++
+osf1-cxx
+osf1-g++
+qnx-g++
+sco-g++
+solaris-cc
+solaris-cc-64
+solaris-g++
+sunos-g++
+ultrix-g++
+unixware-g++
+win32-g++
+win32-mingw
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..eb0e103
--- /dev/null
+++ b/README.md
@@ -0,0 +1,66 @@
+Doxygen
+===============
+Doxygen is the de facto standard tool for generating documentation from
+annotated C++ sources, but it also supports other popular programming
+languages such as C, Objective-C, C#, PHP, Java, Python, IDL
+(Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL, Tcl,
+and to some extent D.
+
+Doxygen can help you in three ways:
+
+1. It can generate an on-line documentation browser (in HTML) and/or an
+ off-line reference manual (in LaTeX) from a set of documented source files.
+ There is also support for generating output in RTF (MS-Word), PostScript,
+ hyperlinked PDF, compressed HTML, DocBook and Unix man pages.
+ The documentation is extracted directly from the sources, which makes
+ it much easier to keep the documentation consistent with the source code.
+2. You can configure doxygen to extract the code structure from undocumented
+ source files. This is very useful to quickly find your way in large
+ source distributions. Doxygen can also visualize the relations between
+ the various elements by means of include dependency graphs, inheritance
+ diagrams, and collaboration diagrams, which are all generated automatically.
+3. You can also use doxygen for creating normal documentation (as I did for
+ the doxygen user manual and doxygen web-site).
+
+Download
+---------
+The latest binaries and source of Doxygen can be downloaded from:
+* http://www.doxygen.org/
+
+Developers
+---------
+* Build Status: <a href="https://travis-ci.org/doxygen/doxygen"><img src="https://secure.travis-ci.org/doxygen/doxygen.png?branch=master"/></a>
+
+* Install
+ * Quick install see (./INSTALL)
+ * else http://www.doxygen.org/manual/install.html
+
+Issues, bugs, requests, ideas
+----------------------------------
+Use the bug tracker to report bugs:
+* current list:
+ * [Bugzilla](https://bugzilla.gnome.org/buglist.cgi?product=doxygen&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED)
+* Submit a new bug or feature request
+ * [Enter bug](https://bugzilla.gnome.org/enter_bug.cgi?product=doxygen)
+
+Comms
+----------------------------------
+### Mailing Lists ###
+
+There are three mailing lists:
+
+* doxygen-announce at lists.sourceforge.net - Announcement of new releases only
+* doxygen-users at lists.sourceforge.net - for doxygen users
+* doxygen-develop at lists.sourceforge.net - for doxygen developers
+* To subscribe follow the link to
+ * http://sourceforge.net/projects/doxygen
+
+Source Code
+----------------------------------
+In May 2013, Doxygen moved from
+subversion to git hosted at github
+* https://github.com/doxygen/doxygen
+
+Enjoy,
+
+Dimitri van Heesch (dimitri at stack.nl)
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..1790d35
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.8.8
diff --git a/addon/doxmlparser/Doxyfile b/addon/doxmlparser/Doxyfile
new file mode 100644
index 0000000..faf4bee
--- /dev/null
+++ b/addon/doxmlparser/Doxyfile
@@ -0,0 +1,177 @@
+# Doxyfile 1.2.12-20011209
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = doxmlparser
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = doc
+OUTPUT_LANGUAGE = English
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+STRIP_CODE_COMMENTS = YES
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+VERBATIM_HEADERS = YES
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = NO
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = NO
+SHOW_USED_FILES = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_FORMAT =
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = include
+FILE_PATTERNS = *.h
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT =
+MAN_EXTENSION =
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+TAGFILES = ../../qtools_docs/qtools.tag=../../../../qtools_docs/html
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+PERL_PATH =
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+TEMPLATE_RELATIONS = YES
+HIDE_UNDOC_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1280
+MAX_DOT_GRAPH_HEIGHT = 1024
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+CGI_NAME =
+CGI_URL =
+DOC_URL =
+DOC_ABSPATH =
+BIN_ABSPATH =
+EXT_DOC_PATHS =
diff --git a/addon/doxmlparser/Doxyfile.impl b/addon/doxmlparser/Doxyfile.impl
new file mode 100644
index 0000000..a954db3
--- /dev/null
+++ b/addon/doxmlparser/Doxyfile.impl
@@ -0,0 +1,179 @@
+# Doxyfile 1.2.13.1
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = doxmlparser
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = doc_impl
+OUTPUT_LANGUAGE = English
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+STRIP_CODE_COMMENTS = YES
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+VERBATIM_HEADERS = YES
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = NO
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = NO
+SHOW_USED_FILES = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_FORMAT =
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = src
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT =
+MAN_EXTENSION =
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED = DEFINE_CLS_IMPL
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+TAGFILES = ../../qtools_docs/qtools.tag=../../../../qtools_docs/html
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH =
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+TEMPLATE_RELATIONS = YES
+HIDE_UNDOC_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1280
+MAX_DOT_GRAPH_HEIGHT = 1024
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+CGI_NAME =
+CGI_URL =
+DOC_URL =
+DOC_ABSPATH =
+BIN_ABSPATH =
+EXT_DOC_PATHS =
diff --git a/addon/doxmlparser/examples/metrics/Makefile b/addon/doxmlparser/examples/metrics/Makefile
new file mode 100644
index 0000000..5282f9b
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/Makefile
@@ -0,0 +1,37 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+all clean depend: Makefile.metrics
+ $(MAKE) -f Makefile.metrics $@
+
+distclean: clean
+ $(RM) -rf Makefile.metrics metrics.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) metrics.pro >Makefile.metrics
+
+Makefile.metrics: metrics.pro
+ $(ENV) $(PERL) $(TMAKE) metrics.pro >Makefile.metrics
+
+install:
diff --git a/addon/doxmlparser/examples/metrics/Makefile.in b/addon/doxmlparser/examples/metrics/Makefile.in
new file mode 100644
index 0000000..a3eb784
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/Makefile.in
@@ -0,0 +1,15 @@
+all clean depend: Makefile.metrics
+ $(MAKE) -f Makefile.metrics $@
+
+distclean: clean
+ $(RM) -rf Makefile.metrics metrics.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) metrics.pro >Makefile.metrics
+
+Makefile.metrics: metrics.pro
+ $(ENV) $(PERL) $(TMAKE) metrics.pro >Makefile.metrics
+
+install:
diff --git a/addon/doxmlparser/examples/metrics/Makefile.metrics b/addon/doxmlparser/examples/metrics/Makefile.metrics
new file mode 100644
index 0000000..90e4cb6
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/Makefile.metrics
@@ -0,0 +1,77 @@
+#############################################################################
+# Makefile for building ../../../../bin/metrics
+# Generated by tmake at 10:48, 2014/08/21
+# Project: metrics
+# Template: app.t
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I../../../../qtools -I../../include -I/opt/local/include
+LINK = c++
+LFLAGS = -Wl,-search_paths_first
+LIBS = -L../../../../lib -ldoxmlparser -lqtools -L/opt/local/lib -liconv -framework CoreServices
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS =
+SOURCES = main.cpp
+OBJECTS = ../../../../objects/doxmlparer/metrics/main.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../../../../bin/metrics
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) ../../../../lib/libdoxmlparser.a
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake metrics.pro
+
+dist:
+ $(TAR) metrics.tar metrics.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) metrics.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../../../../objects/doxmlparer/metrics/main.o: main.cpp \
+ ../../include/doxmlintf.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../../objects/doxmlparer/metrics/main.o main.cpp
+
diff --git a/addon/doxmlparser/examples/metrics/main.cpp b/addon/doxmlparser/examples/metrics/main.cpp
new file mode 100644
index 0000000..1328abe
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/main.cpp
@@ -0,0 +1,254 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2006 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+/*! \mainpage Metrics
+ * This is a small example that shows how to use doxygen's XML output and
+ * the doxmlparser library. The example shows some very basic code metrics.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <doxmlintf.h>
+
+bool isDocumented(IDocRoot *brief,IDocRoot *detailed)
+{
+ bool found=false;
+ if (brief)
+ {
+ IDocIterator *docIt = brief->contents();
+ if (docIt->current()) // method has brief description
+ {
+ found=true;
+ }
+ docIt->release();
+ }
+ if (detailed && !found)
+ {
+ IDocIterator *docIt = detailed->contents();
+ if (docIt->current())
+ {
+ found=true;
+ }
+ docIt->release();
+ }
+ return found;
+}
+
+int main(int argc,char **argv)
+{
+ if (argc!=2)
+ {
+ printf("Usage: %s xml_output_dir\n",argv[0]);
+ exit(1);
+ }
+
+ int numClasses=0;
+ int numDocClasses=0;
+ int numStructs=0;
+ int numUnions=0;
+ int numInterfaces=0;
+ int numExceptions=0;
+ int numNamespaces=0;
+ int numFiles=0;
+ int numGroups=0;
+ int numPages=0;
+ int numPackages=0;
+ int numPubMethods=0;
+ int numProMethods=0;
+ int numPriMethods=0;
+ int numDocPubMethods=0;
+ int numDocProMethods=0;
+ int numDocPriMethods=0;
+ int numFunctions=0;
+ int numAttributes=0;
+ int numVariables=0;
+ int numDocFunctions=0;
+ int numDocAttributes=0;
+ int numDocVariables=0;
+ int numParams=0;
+
+ IDoxygen *dox = createObjectModel();
+
+ dox->setDebugLevel(0);
+
+ if (!dox->readXMLDir(argv[1]))
+ {
+ printf("Error reading %s/index.xml\n",argv[1]);
+ exit(1);
+ }
+
+ ICompoundIterator *cli = dox->compounds();
+ ICompound *comp;
+ for (cli->toFirst();(comp=cli->current());cli->toNext())
+ {
+ printf("Processing %s...\n",comp->name()->latin1());
+ bool hasDocs = isDocumented(comp->briefDescription(),comp->detailedDescription());
+ switch (comp->kind())
+ {
+ case ICompound::Class:
+ numClasses++;
+ if (hasDocs) numDocClasses++;
+ break;
+ case ICompound::Struct: numStructs++; break;
+ case ICompound::Union: numUnions++; break;
+ case ICompound::Interface: numInterfaces++; break;
+ case ICompound::Exception: numExceptions++; break;
+ case ICompound::Namespace: numNamespaces++; break;
+ case ICompound::File: numFiles++; break;
+ case ICompound::Group: numGroups++; break;
+ case ICompound::Page: numPages++; break;
+ default: break;
+ }
+
+ ISectionIterator *sli = comp->sections();
+ ISection *sec;
+ for (sli->toFirst();(sec=sli->current());sli->toNext())
+ {
+ IMemberIterator *mli = sec->members();
+ IMember *mem;
+ for (mli->toFirst();(mem=mli->current());mli->toNext())
+ {
+ IParamIterator *pli = mem->parameters();
+ IParam *par;
+ if (comp->kind()==ICompound::Class ||
+ comp->kind()==ICompound::Struct ||
+ comp->kind()==ICompound::Interface
+ )
+ {
+ if (mem->kind()==IMember::Function ||
+ mem->kind()==IMember::Prototype ||
+ mem->kind()==IMember::Signal ||
+ mem->kind()==IMember::Slot ||
+ mem->kind()==IMember::DCOP
+ ) // is a "method"
+ {
+ if (mem->section()->isPublic())
+ {
+ numPubMethods++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocPubMethods++;
+ }
+ }
+ else if (mem->section()->isProtected())
+ {
+ numProMethods++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocProMethods++;
+ }
+ }
+ else if (mem->section()->isPrivate())
+ {
+ numPriMethods++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocPriMethods++;
+ }
+ }
+ }
+ else if (mem->kind()==IMember::Variable ||
+ mem->kind()==IMember::Property
+ ) // is an "attribute"
+ {
+ numAttributes++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocAttributes++;
+ }
+ }
+ }
+ else if (comp->kind()==ICompound::File ||
+ comp->kind()==ICompound::Namespace
+ )
+ {
+ if (mem->kind()==IMember::Function ||
+ mem->kind()==IMember::Prototype ||
+ mem->kind()==IMember::Signal ||
+ mem->kind()==IMember::Slot ||
+ mem->kind()==IMember::DCOP
+ ) // is a "method"
+ {
+ numFunctions++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocFunctions++;
+ }
+ }
+ else if (mem->kind()==IMember::Variable ||
+ mem->kind()==IMember::Property
+ ) // is an "attribute"
+ {
+ numVariables++;
+ if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
+ {
+ numDocVariables++;
+ }
+ }
+ }
+
+ for (pli->toFirst();(par=pli->current());pli->toNext())
+ {
+ numParams++;
+ }
+ const char *type = mem->typeString()->latin1();
+ if (type && strcmp(type, "void"))
+ {
+ numParams++; // count non-void return types as well
+ }
+ pli->release();
+ }
+ mli->release();
+ }
+ sli->release();
+
+ comp->release();
+ }
+ cli->release();
+
+ dox->release();
+
+ int numMethods = numPubMethods+numProMethods+numPriMethods;
+ int numDocMethods = numDocPubMethods+numDocProMethods+numDocPriMethods;
+
+ printf("Metrics:\n");
+ printf("-----------------------------------\n");
+ if (numClasses>0) printf("Classes: %10d (%d documented)\n",numClasses,numDocClasses);
+ if (numStructs>0) printf("Structs: %10d\n",numStructs);
+ if (numUnions>0) printf("Unions: %10d\n",numUnions);
+ if (numInterfaces>0) printf("Interfaces: %10d\n",numInterfaces);
+ if (numExceptions>0) printf("Exceptions: %10d\n",numExceptions);
+ if (numNamespaces>0) printf("Namespaces: %10d\n",numNamespaces);
+ if (numFiles>0) printf("Files: %10d\n",numFiles);
+ if (numGroups>0) printf("Groups: %10d\n",numGroups);
+ if (numPages>0) printf("Pages: %10d\n",numPages);
+ if (numPackages>0) printf("Packages: %10d\n",numPackages);
+ if (numMethods>0) printf("Methods: %10d (%d documented)\n",numMethods,numDocMethods);
+ if (numPubMethods>0) printf(" Public: %10d (%d documented)\n",numPubMethods,numDocPubMethods);
+ if (numProMethods>0) printf(" Protected: %10d (%d documented)\n",numProMethods,numDocProMethods);
+ if (numPriMethods>0) printf(" Private: %10d (%d documented)\n",numPriMethods,numDocPriMethods);
+ if (numFunctions>0) printf("Functions: %10d (%d documented)\n",numFunctions,numDocFunctions);
+ if (numAttributes>0) printf("Attributes: %10d (%d documented)\n",numAttributes,numDocAttributes);
+ if (numVariables>0) printf("Variables: %10d (%d documented)\n",numVariables,numDocVariables);
+ if (numParams>0) printf("Params: %10d\n",numParams);
+ printf("-----------------------------------\n");
+ if (numClasses>0) printf("Avg. #methods/compound: %10f\n",(double)numMethods/(double)numClasses);
+ if (numMethods>0) printf("Avg. #params/method: %10f\n",(double)numParams/(double)numMethods);
+ printf("-----------------------------------\n");
+
+ return 0;
+}
+
diff --git a/addon/doxmlparser/examples/metrics/metrics.pro b/addon/doxmlparser/examples/metrics/metrics.pro
new file mode 100644
index 0000000..5eeac94
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/metrics.pro
@@ -0,0 +1,27 @@
+#
+# This file was generated from metrics.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = app.t
+CONFIG = console warn_on debug
+HEADERS =
+SOURCES = main.cpp
+unix:LIBS += -L../../../../lib -ldoxmlparser -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../../lib -ldoxmlparser -lqtools
+win32-msvc:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\..\..\..\lib;
+win32-borland:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../../bin
+OBJECTS_DIR = ../../../../objects/doxmlparer/metrics
+TARGET = metrics
+DEPENDPATH = ../../include
+INCLUDEPATH += ../../../../qtools ../../include
+unix:TARGETDEPS = ../../../../lib/libdoxmlparser.a
+win32:TARGETDEPS = ..\..\..\..\lib\doxmlparser.lib
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/addon/doxmlparser/examples/metrics/metrics.pro.in b/addon/doxmlparser/examples/metrics/metrics.pro.in
new file mode 100644
index 0000000..3b2354d
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/metrics.pro.in
@@ -0,0 +1,20 @@
+TEMPLATE = app.t
+CONFIG = console warn_on $extraopts
+HEADERS =
+SOURCES = main.cpp
+unix:LIBS += -L../../../../lib -ldoxmlparser -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../../lib -ldoxmlparser -lqtools
+win32-msvc:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\..\..\..\lib;
+win32-borland:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../../bin
+OBJECTS_DIR = ../../../../objects/doxmlparer/metrics
+TARGET = metrics
+DEPENDPATH = ../../include
+INCLUDEPATH += ../../../../qtools ../../include
+unix:TARGETDEPS = ../../../../lib/libdoxmlparser.a
+win32:TARGETDEPS = ..\..\..\..\lib\doxmlparser.lib
+
diff --git a/addon/doxmlparser/include/doxmlintf.h b/addon/doxmlparser/include/doxmlintf.h
new file mode 120000
index 0000000..2d2b707
--- /dev/null
+++ b/addon/doxmlparser/include/doxmlintf.h
@@ -0,0 +1 @@
+../src/doxmlintf.h
\ No newline at end of file
diff --git a/addon/doxmlparser/src/Makefile b/addon/doxmlparser/src/Makefile
new file mode 100644
index 0000000..9cb684b
--- /dev/null
+++ b/addon/doxmlparser/src/Makefile
@@ -0,0 +1,37 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+all clean depend: Makefile.doxmlparser
+ $(MAKE) -f Makefile.doxmlparser $@
+
+distclean: clean
+ $(RM) -rf Makefile.doxmlparser doxmlparser.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) doxmlparser.pro >Makefile.doxmlparser
+
+Makefile.doxmlparser: doxmlparser.pro
+ $(ENV) $(PERL) $(TMAKE) doxmlparser.pro >Makefile.doxmlparser
+
+install:
diff --git a/addon/doxmlparser/src/Makefile.doxmlparser b/addon/doxmlparser/src/Makefile.doxmlparser
new file mode 100644
index 0000000..ce9f0d5
--- /dev/null
+++ b/addon/doxmlparser/src/Makefile.doxmlparser
@@ -0,0 +1,224 @@
+#############################################################################
+# Makefile for building ../../../lib/libdoxmlparser.a
+# Generated by tmake at 10:48, 2014/08/21
+# Project: doxmlparser
+# Template: lib.t
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I../../../qtools -I../include -I/opt/local/include
+AR = ar cq
+RANLIB = ranlib
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = basehandler.h \
+ mainhandler.h \
+ compoundhandler.h \
+ sectionhandler.h \
+ memberhandler.h \
+ paramhandler.h \
+ dochandler.h \
+ linkedtexthandler.h \
+ debug.h \
+ graphhandler.h \
+ stringimpl.h \
+ loamhandler.h
+SOURCES = mainhandler.cpp \
+ compoundhandler.cpp \
+ sectionhandler.cpp \
+ memberhandler.cpp \
+ paramhandler.cpp \
+ dochandler.cpp \
+ linkedtexthandler.cpp \
+ basehandler.cpp \
+ debug.cpp \
+ graphhandler.cpp \
+ loamhandler.cpp
+OBJECTS = ../../../objects/doxmlparser/mainhandler.o \
+ ../../../objects/doxmlparser/compoundhandler.o \
+ ../../../objects/doxmlparser/sectionhandler.o \
+ ../../../objects/doxmlparser/memberhandler.o \
+ ../../../objects/doxmlparser/paramhandler.o \
+ ../../../objects/doxmlparser/dochandler.o \
+ ../../../objects/doxmlparser/linkedtexthandler.o \
+ ../../../objects/doxmlparser/basehandler.o \
+ ../../../objects/doxmlparser/debug.o \
+ ../../../objects/doxmlparser/graphhandler.o \
+ ../../../objects/doxmlparser/loamhandler.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../../../lib/libdoxmlparser.a
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ ranlib $(TARGET)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake doxmlparser.pro
+
+dist:
+ $(TAR) doxmlparser.tar doxmlparser.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) doxmlparser.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../../../objects/doxmlparser/mainhandler.o: mainhandler.cpp \
+ mainhandler.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ compoundhandler.h \
+ stringimpl.h \
+ baseiterator.h \
+ sectionhandler.h \
+ graphhandler.h \
+ dochandler.h \
+ memberhandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/mainhandler.o mainhandler.cpp
+
+../../../objects/doxmlparser/compoundhandler.o: compoundhandler.cpp \
+ mainhandler.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ compoundhandler.h \
+ stringimpl.h \
+ baseiterator.h \
+ dochandler.h \
+ graphhandler.h \
+ sectionhandler.h \
+ paramhandler.h \
+ loamhandler.h \
+ memberhandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/compoundhandler.o compoundhandler.cpp
+
+../../../objects/doxmlparser/sectionhandler.o: sectionhandler.cpp \
+ mainhandler.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ compoundhandler.h \
+ stringimpl.h \
+ baseiterator.h \
+ sectionhandler.h \
+ memberhandler.h \
+ dochandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/sectionhandler.o sectionhandler.cpp
+
+../../../objects/doxmlparser/memberhandler.o: memberhandler.cpp \
+ memberhandler.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ baseiterator.h \
+ stringimpl.h \
+ sectionhandler.h \
+ dochandler.h \
+ mainhandler.h \
+ linkedtexthandler.h \
+ paramhandler.h \
+ compoundhandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/memberhandler.o memberhandler.cpp
+
+../../../objects/doxmlparser/paramhandler.o: paramhandler.cpp \
+ paramhandler.h \
+ doxmlintf.h \
+ stringimpl.h \
+ basehandler.h \
+ debug.h \
+ baseiterator.h \
+ memberhandler.h \
+ linkedtexthandler.h \
+ dochandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/paramhandler.o paramhandler.cpp
+
+../../../objects/doxmlparser/dochandler.o: dochandler.cpp \
+ dochandler.h \
+ doxmlintf.h \
+ stringimpl.h \
+ basehandler.h \
+ debug.h \
+ baseiterator.h \
+ linkedtexthandler.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/dochandler.o dochandler.cpp
+
+../../../objects/doxmlparser/linkedtexthandler.o: linkedtexthandler.cpp \
+ linkedtexthandler.h \
+ baseiterator.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ stringimpl.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/linkedtexthandler.o linkedtexthandler.cpp
+
+../../../objects/doxmlparser/basehandler.o: basehandler.cpp \
+ basehandler.h \
+ debug.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/basehandler.o basehandler.cpp
+
+../../../objects/doxmlparser/debug.o: debug.cpp \
+ debug.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/debug.o debug.cpp
+
+../../../objects/doxmlparser/graphhandler.o: graphhandler.cpp \
+ graphhandler.h \
+ stringimpl.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ baseiterator.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/graphhandler.o graphhandler.cpp
+
+../../../objects/doxmlparser/loamhandler.o: loamhandler.cpp \
+ loamhandler.h \
+ doxmlintf.h \
+ basehandler.h \
+ debug.h \
+ memberhandler.h \
+ baseiterator.h \
+ stringimpl.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/loamhandler.o loamhandler.cpp
+
diff --git a/addon/doxmlparser/src/Makefile.in b/addon/doxmlparser/src/Makefile.in
new file mode 100644
index 0000000..47d20c2
--- /dev/null
+++ b/addon/doxmlparser/src/Makefile.in
@@ -0,0 +1,15 @@
+all clean depend: Makefile.doxmlparser
+ $(MAKE) -f Makefile.doxmlparser $@
+
+distclean: clean
+ $(RM) -rf Makefile.doxmlparser doxmlparser.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) doxmlparser.pro >Makefile.doxmlparser
+
+Makefile.doxmlparser: doxmlparser.pro
+ $(ENV) $(PERL) $(TMAKE) doxmlparser.pro >Makefile.doxmlparser
+
+install:
diff --git a/addon/doxmlparser/src/basehandler.cpp b/addon/doxmlparser/src/basehandler.cpp
new file mode 100644
index 0000000..02d98c2
--- /dev/null
+++ b/addon/doxmlparser/src/basehandler.cpp
@@ -0,0 +1,3 @@
+#include "basehandler.h"
+
+QXmlLocator * LocatorContainer::s_theLocator=0;
diff --git a/addon/doxmlparser/src/basehandler.h b/addon/doxmlparser/src/basehandler.h
new file mode 100644
index 0000000..31fbf24
--- /dev/null
+++ b/addon/doxmlparser/src/basehandler.h
@@ -0,0 +1,325 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _BASEHANDLER_H
+#define _BASEHANDLER_H
+
+#include <qxml.h>
+#include <qdict.h>
+#include <qstring.h>
+
+#include "debug.h"
+
+//-----------------------------------------------------------------------------
+
+class IBaseHandler
+{
+ public:
+ virtual void setDelegate(QXmlDefaultHandler *delegate) = 0;
+ virtual QXmlDefaultHandler *delegate() const = 0;
+ virtual ~IBaseHandler() {}
+};
+
+//-----------------------------------------------------------------------------
+
+class IFallBackHandler
+{
+ public:
+ virtual bool handleStartElement(const QString & name,
+ const QXmlAttributes & attrib) = 0;
+ virtual bool handleEndElement(const QString &name) = 0;
+ virtual ~IFallBackHandler() {}
+};
+
+//-----------------------------------------------------------------------------
+
+template<class T> class ElementMapper
+{
+ class StartElementHandler
+ {
+ typedef void (T::*Handler)(const QXmlAttributes &attrib);
+ public:
+ StartElementHandler() : m_parent(0) {}
+ StartElementHandler(T *parent, Handler h)
+ : m_parent(parent), m_handler(h) {}
+ void operator()(const QXmlAttributes &attrib)
+ { if (m_parent) (m_parent->*m_handler)(attrib); }
+ private:
+ T *m_parent;
+ Handler m_handler;
+ };
+
+ class EndElementHandler
+ {
+ typedef void (T::*Handler)();
+ public:
+ EndElementHandler() : m_parent(0) {}
+ EndElementHandler(T *parent, Handler h)
+ : m_parent(parent), m_handler(h) {}
+ void operator()()
+ { if (m_parent) (m_parent->*m_handler)(); }
+ private:
+ T *m_parent;
+ Handler m_handler;
+ };
+
+ public:
+ typedef StartElementHandler StartElementHandlerT;
+ typedef EndElementHandler EndElementHandlerT;
+
+ ElementMapper() : m_startHandlers(67), m_endHandlers(67)
+ {
+ m_startHandlers.setAutoDelete(TRUE);
+ m_endHandlers.setAutoDelete(TRUE);
+ }
+ virtual ~ElementMapper()
+ {
+ }
+
+ void addStartHandler(const char *key)
+ {
+ m_startHandlers.insert(key,new StartElementHandlerT);
+ }
+
+ void addStartHandler(const char *key, T *obj, void (T::*handler)(const QXmlAttributes &))
+ {
+ m_startHandlers.insert(key,new StartElementHandlerT(obj,handler));
+ }
+
+ void addEndHandler(const char *key)
+ {
+ m_endHandlers.insert(key,new EndElementHandlerT);
+ }
+
+ void addEndHandler(const char *key, T *obj, void (T::*handler)())
+ {
+ m_endHandlers.insert(key,new EndElementHandlerT(obj,handler));
+ }
+
+
+ protected:
+ QDict<StartElementHandlerT> m_startHandlers;
+ QDict<EndElementHandlerT> m_endHandlers;
+};
+
+//-----------------------------------------------------------------------------
+
+struct LocatorContainer
+{
+ static QXmlLocator *s_theLocator;
+};
+
+//-----------------------------------------------------------------------------
+
+template<class T> class BaseHandler : public QXmlDefaultHandler,
+ public ElementMapper<T>,
+ public LocatorContainer,
+ public IBaseHandler
+{
+ public:
+ typedef typename ElementMapper<T>::StartElementHandlerT StartElementHandlerT;
+ typedef typename ElementMapper<T>::EndElementHandlerT EndElementHandlerT;
+
+ BaseHandler() : m_skipCount(0), m_delegateHandler(0), m_fallBackHandler(0)
+ {
+ }
+
+ virtual ~BaseHandler()
+ {
+ ASSERT(m_delegateHandler==0);
+ }
+
+ virtual bool startDocument()
+ {
+ return TRUE;
+ }
+
+ virtual bool startElement( const QString & namespaceURI,
+ const QString & localName,
+ const QString & name,
+ const QXmlAttributes & attrib
+ )
+ {
+ if (m_delegateHandler)
+ {
+ return m_delegateHandler->startElement(namespaceURI,localName,name,attrib);
+ }
+ if (!m_skipUntil.isEmpty()) // skip mode
+ {
+ if (m_skipUntil==name) m_skipCount++;
+ debug(1,"line %d, col %d: skipping start tag %s count=%d\n",
+ s_theLocator->lineNumber(),s_theLocator->columnNumber(),
+ name.data(),m_skipCount);
+ return TRUE;
+ }
+
+ StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)(attrib);
+ //printf("found start tag %s\n",name.data());
+ }
+ else if (!m_fallBackHandler ||
+ !m_fallBackHandler->handleStartElement(name,attrib)
+ )
+ {
+ debug(1,"line %d, col %d: found unexpected tag `%s', skipping until matching end tag\n",
+ s_theLocator->lineNumber(),s_theLocator->columnNumber(),
+ name.data());
+ m_skipUntil = name;
+ m_skipCount=1;
+ }
+ return TRUE;
+ }
+
+ virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& name )
+ {
+ if (m_delegateHandler)
+ {
+ return m_delegateHandler->endElement(namespaceURI,localName,name);
+ }
+
+ if (name==m_skipUntil)
+ {
+ m_skipCount--;
+ debug(1,"line %d, col %d: skipping end tag %s count=%d\n",
+ s_theLocator->lineNumber(),s_theLocator->columnNumber(),
+ name.data(),m_skipCount);
+ if (m_skipCount==0)
+ {
+ m_skipUntil="";
+ }
+ //printf("found end tag %s\n",name.data());
+ }
+ else if (m_skipUntil.isEmpty())
+ {
+ EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)();
+ //printf("found end tag %s\n",name.data());
+ }
+ else if (m_fallBackHandler)
+ {
+ m_fallBackHandler->handleEndElement(name);
+ }
+ }
+ m_curString="";
+ return TRUE;
+ }
+
+ bool skippedEntity ( const QString &s )
+ {
+ if (m_delegateHandler)
+ {
+ return m_delegateHandler->skippedEntity(s);
+ }
+
+ debug(1,"line %d, col %d: Skipped unhandled entity %s\n",
+ s_theLocator->lineNumber(),s_theLocator->columnNumber(),
+ s.data());
+ return TRUE;
+ }
+
+ /*! called when a number of characters are received by the parser.
+ * \param ch the characters.
+ */
+ virtual bool characters ( const QString & ch )
+ {
+ if (m_delegateHandler)
+ {
+ return m_delegateHandler->characters(ch);
+ }
+
+ //printf("Found characters \"%s\"\n",ch.data());
+ m_curString+=ch;
+ return TRUE;
+ }
+
+ void setDelegate(QXmlDefaultHandler *delegate)
+ {
+ m_delegateHandler = delegate;
+ }
+
+ QXmlDefaultHandler *delegate() const
+ {
+ return m_delegateHandler;
+ }
+
+ void setFallBackHandler(IFallBackHandler *h)
+ {
+ m_fallBackHandler = h;
+ }
+
+ IFallBackHandler *fallBackHandler() const
+ {
+ return m_fallBackHandler;
+ }
+
+ void setDocumentLocator( QXmlLocator * locator )
+ {
+ debug(2,"setDocumentLocator(%p)\n",locator);
+ s_theLocator = locator;
+ }
+
+ protected:
+ QString m_curString;
+ QString m_skipUntil;
+ int m_skipCount;
+ QXmlDefaultHandler *m_delegateHandler;
+ IFallBackHandler *m_fallBackHandler;
+};
+
+//-----------------------------------------------------------------------------
+
+template<class T> class BaseFallBackHandler : public ElementMapper<T>,
+ public IFallBackHandler
+{
+ public:
+ typedef typename ElementMapper<T>::StartElementHandlerT StartElementHandlerT;
+ typedef typename ElementMapper<T>::EndElementHandlerT EndElementHandlerT;
+
+ BaseFallBackHandler()
+ {
+ }
+ virtual ~BaseFallBackHandler()
+ {
+ }
+
+ bool handleStartElement(const QString & name,
+ const QXmlAttributes & attrib)
+ {
+ StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)(attrib);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ bool handleEndElement(const QString &name)
+ {
+ EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)();
+ return TRUE;
+ }
+ return FALSE;
+ }
+};
+
+
+#endif
diff --git a/addon/doxmlparser/src/baseiterator.h b/addon/doxmlparser/src/baseiterator.h
new file mode 100644
index 0000000..2ee9c2f
--- /dev/null
+++ b/addon/doxmlparser/src/baseiterator.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+#ifndef BASEITERATOR_H
+#define BASEITERATOR_H
+
+#include <qlist.h>
+#include <doxmlintf.h>
+
+template<class Intf,class ElemIntf,class ElemImpl> class BaseIterator :
+ public Intf, public QListIterator<ElemImpl>
+{
+ public:
+ BaseIterator(const QList<ElemImpl> &list) : QListIterator<ElemImpl>(list) {}
+ virtual ~BaseIterator() {}
+ virtual ElemIntf *toFirst() { return QListIterator<ElemImpl>::toFirst(); }
+ virtual ElemIntf *toLast() { return QListIterator<ElemImpl>::toLast(); }
+ virtual ElemIntf *toNext() { return QListIterator<ElemImpl>::operator++(); }
+ virtual ElemIntf *toPrev() { return QListIterator<ElemImpl>::operator--(); }
+ virtual ElemIntf *current() const { return QListIterator<ElemImpl>::current(); }
+ virtual void release() { delete this; }
+};
+
+template<class Intf,class ElemIntf,class ElemImpl,class Intermediate>
+ class BaseIteratorVia :
+ public Intf, public QListIterator<ElemImpl>
+{
+ public:
+ BaseIteratorVia(const QList<ElemImpl> &list) : QListIterator<ElemImpl>(list) {}
+ virtual ~BaseIteratorVia() {}
+ virtual ElemIntf *toFirst() { return static_cast<Intermediate *>(QListIterator<ElemImpl>::toFirst()); }
+ virtual ElemIntf *toLast() { return static_cast<Intermediate *>(QListIterator<ElemImpl>::toLast()); }
+ virtual ElemIntf *toNext() { return static_cast<Intermediate *>(QListIterator<ElemImpl>::operator++()); }
+ virtual ElemIntf *toPrev() { return static_cast<Intermediate *>(QListIterator<ElemImpl>::operator--()); }
+ virtual ElemIntf *current() const { return static_cast<Intermediate *>(QListIterator<ElemImpl>::current()); }
+ virtual void release() { delete this; }
+};
+
+#endif
diff --git a/addon/doxmlparser/src/compoundhandler.cpp b/addon/doxmlparser/src/compoundhandler.cpp
new file mode 100644
index 0000000..87b0440
--- /dev/null
+++ b/addon/doxmlparser/src/compoundhandler.cpp
@@ -0,0 +1,654 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "mainhandler.h"
+#include "compoundhandler.h"
+#include "dochandler.h"
+#include "debug.h"
+#include "graphhandler.h"
+#include "sectionhandler.h"
+#include "paramhandler.h"
+#include "loamhandler.h"
+#include "memberhandler.h"
+
+//----------------------------------------------------------------------------
+
+IncludeHandler::IncludeHandler(IBaseHandler *parent,const char *endtag) :
+ m_parent(parent)
+{
+ addEndHandler(endtag,this,&IncludeHandler::endInclude);
+}
+
+IncludeHandler::~IncludeHandler()
+{
+}
+
+void IncludeHandler::startInclude(const QXmlAttributes &attrib)
+{
+ m_curString = "";
+ m_refId = attrib.value("refid");
+ m_isLocal = attrib.value("local")=="yes";
+ m_parent->setDelegate(this);
+}
+
+void IncludeHandler::endInclude()
+{
+ m_name = m_curString;
+ m_parent->setDelegate(0);
+ debug(2,"Found include %s\n",m_name.data());
+}
+
+//----------------------------------------------------------------------------
+
+class CompoundIdIterator : public ICompoundIterator,
+ public QListIterator<QString>
+{
+ public:
+ CompoundIdIterator(const MainHandler *m,const QList<QString> &list) :
+ QListIterator<QString>(list), m_mainHandler(m) {}
+ virtual ~CompoundIdIterator() {}
+
+ virtual void toFirst()
+ {
+ QListIterator<QString>::toFirst();
+ }
+ virtual void toLast()
+ {
+ QListIterator<QString>::toLast();
+ }
+ virtual void toNext()
+ {
+ QListIterator<QString>::operator++();
+ }
+ virtual void toPrev()
+ {
+ QListIterator<QString>::operator--();
+ }
+ virtual ICompound *current() const
+ {
+ QString *id = QListIterator<QString>::current();
+ return id ? m_mainHandler->compoundById(id->utf8()) : 0;
+ }
+ virtual void release()
+ { delete this; }
+
+ private:
+ const MainHandler *m_mainHandler;
+};
+
+//----------------------------------------------------------------------------
+
+ICompound *RelatedCompound::compound() const
+{
+ return m_parent->m_mainHandler->compoundById(m_id.utf8());
+}
+
+//----------------------------------------------------------------------------
+
+class CompoundErrorHandler : public QXmlErrorHandler
+{
+ public:
+ virtual ~CompoundErrorHandler() {}
+ bool warning( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool error( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool fatalError( const QXmlParseException &exception )
+ {
+ debug(1,"Fatal error at line %d column %d: %s\n",
+ exception.lineNumber(),exception.columnNumber(),
+ exception.message().data());
+ return FALSE;
+ }
+ QString errorString() { return ""; }
+
+ private:
+ QString errorMsg;
+};
+
+//----------------------------------------------------------------------------
+
+class CompoundTypeMap
+{
+ public:
+ CompoundTypeMap()
+ {
+ m_map.setAutoDelete(TRUE);
+ m_map.insert("class", new int(ICompound::Class));
+ m_map.insert("struct", new int(ICompound::Struct));
+ m_map.insert("union", new int(ICompound::Union));
+ m_map.insert("interface",new int(ICompound::Interface));
+ m_map.insert("protocol", new int(ICompound::Protocol));
+ m_map.insert("category", new int(ICompound::Category));
+ m_map.insert("exception",new int(ICompound::Exception));
+ m_map.insert("file", new int(ICompound::File));
+ m_map.insert("namespace",new int(ICompound::Namespace));
+ m_map.insert("group", new int(ICompound::Group));
+ m_map.insert("page", new int(ICompound::Page));
+ m_map.insert("example", new int(ICompound::Example));
+ m_map.insert("dir", new int(ICompound::Dir));
+ }
+ virtual ~CompoundTypeMap()
+ {
+ }
+ ICompound::CompoundKind map(const QString &s)
+ {
+ int *val = m_map.find(s.utf8());
+ if (val==0)
+ {
+ debug(1,"Warning: `%s' is an invalid compound type\n",s.data());
+ return ICompound::Invalid;
+ }
+ else return (ICompound::CompoundKind)*val;
+ }
+ private:
+ QDict<int> m_map;
+};
+
+static CompoundTypeMap *s_typeMap;
+
+void compoundhandler_init()
+{
+ s_typeMap = new CompoundTypeMap;
+}
+
+void compoundhandler_exit()
+{
+ delete s_typeMap;
+}
+
+//----------------------------------------------------------------------------
+
+CompoundHandler::CompoundHandler(const QString &xmlDir)
+ : m_titleHandler(0),
+ m_includeDependencyGraph(0),
+ m_includedByDependencyGraph(0),
+ m_templateParamList(0),
+ m_brief(0),
+ m_detailed(0),
+ m_inheritanceGraph(0),
+ m_collaborationGraph(0),
+ m_programListing(0),
+ m_members(0),
+ m_xmlDir(xmlDir),
+ m_refCount(1),
+ m_memberDict(257),
+ m_memberNameDict(257),
+ m_mainHandler(0)
+{
+ m_superClasses.setAutoDelete(TRUE);
+ m_subClasses.setAutoDelete(TRUE);
+ m_sections.setAutoDelete(TRUE);
+ m_memberNameDict.setAutoDelete(TRUE);
+ m_innerCompounds.setAutoDelete(TRUE);
+ m_includes.setAutoDelete(TRUE);
+ m_includedBy.setAutoDelete(TRUE);
+
+ addStartHandler("doxygen");
+ addEndHandler("doxygen");
+
+ addStartHandler("compounddef",this,&CompoundHandler::startCompound);
+ addEndHandler("compounddef",this,&CompoundHandler::endCompound);
+
+ addStartHandler("compoundname");
+ addEndHandler("compoundname",this,&CompoundHandler::endCompoundName);
+
+ addStartHandler("title",this,&CompoundHandler::startTitle);
+
+ addStartHandler("basecompoundref",this,&CompoundHandler::startSuperClass);
+ addEndHandler("basecompoundref",this,&CompoundHandler::endSuperClass);
+
+ addStartHandler("derivedcompoundref",this,&CompoundHandler::startSubClass);
+ addEndHandler("derivedcompoundref",this,&CompoundHandler::endSubClass);
+
+ addStartHandler("includes",this,&CompoundHandler::startIncludes);
+ addStartHandler("includedby",this,&CompoundHandler::startIncludedBy);
+
+ addStartHandler("incdepgraph",this,&CompoundHandler::startIncludeDependencyGraph);
+
+ addStartHandler("invincdepgraph",this,&CompoundHandler::startIncludedByDependencyGraph);
+
+ addStartHandler("innerdir",this,&CompoundHandler::startInnerDir);
+ addEndHandler("innerdir");
+
+ addStartHandler("innerfile",this,&CompoundHandler::startInnerFile);
+ addEndHandler("innerfile");
+
+ addStartHandler("innerclass",this,&CompoundHandler::startInnerClass);
+ addEndHandler("innerclass");
+
+ addStartHandler("innernamespace",this,&CompoundHandler::startInnerNamespace);
+ addEndHandler("innernamespace");
+
+ addStartHandler("innerpage",this,&CompoundHandler::startInnerPage);
+ addEndHandler("innerpage");
+
+ addStartHandler("innergroup",this,&CompoundHandler::startInnerGroup);
+ addEndHandler("innergroup");
+
+ addStartHandler("templateparamlist",this,&CompoundHandler::startTemplateParamList);
+
+ addStartHandler("sectiondef",this,&CompoundHandler::startSection);
+
+ addStartHandler("briefdescription",this,&CompoundHandler::startBriefDesc);
+
+ addStartHandler("detaileddescription",this,&CompoundHandler::startDetailedDesc);
+
+ addStartHandler("inheritancegraph",this,&CompoundHandler::startInheritanceGraph);
+
+ addStartHandler("collaborationgraph",this,&CompoundHandler::startCollaborationGraph);
+
+ addStartHandler("programlisting",this,&CompoundHandler::startProgramListing);
+
+ addStartHandler("location",this,&CompoundHandler::startLocation);
+ addEndHandler("location");
+
+ addStartHandler("listofallmembers",this,&CompoundHandler::startListOfAllMembers);
+}
+
+CompoundHandler::~CompoundHandler()
+{
+ debug(2,"CompoundHandler::~CompoundHandler()\n");
+ delete m_titleHandler;
+ delete m_brief;
+ delete m_detailed;
+ delete m_programListing;
+ delete m_inheritanceGraph;
+ delete m_collaborationGraph;
+ delete m_includeDependencyGraph;
+ delete m_includedByDependencyGraph;
+ delete m_templateParamList;
+ delete m_members;
+}
+
+void CompoundHandler::startSection(const QXmlAttributes& attrib)
+{
+ SectionHandler *sectHandler = new SectionHandler(this);
+ sectHandler->startSection(attrib);
+ m_sections.append(sectHandler);
+}
+
+void CompoundHandler::startBriefDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_brief = docHandler;
+}
+
+void CompoundHandler::startDetailedDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_detailed = docHandler;
+}
+
+void CompoundHandler::startProgramListing(const QXmlAttributes& attrib)
+{
+ ProgramListingHandler *plHandler = new ProgramListingHandler(this);
+ plHandler->startProgramListing(attrib);
+ m_programListing = plHandler;
+}
+
+void CompoundHandler::startIncludes(const QXmlAttributes& attrib)
+{
+ IncludeHandler *inc = new IncludeHandler(this,"includes");
+ m_includes.append(inc);
+ inc->startInclude(attrib);
+}
+
+void CompoundHandler::startIncludedBy(const QXmlAttributes& attrib)
+{
+ IncludeHandler *inc = new IncludeHandler(this,"includedby");
+ m_includedBy.append(inc);
+ inc->startInclude(attrib);
+}
+
+void CompoundHandler::startCompound(const QXmlAttributes& attrib)
+{
+ m_id = attrib.value("id");
+ m_kindString = attrib.value("kind");
+ m_kind = s_typeMap->map(m_kindString);
+ m_protection = attrib.value("prot");
+ debug(2,"startCompound(id=`%s' type=`%s')\n",m_id.data(),m_kindString.data());
+}
+
+void CompoundHandler::endCompound()
+{
+ debug(2,"endCompound()\n");
+}
+
+void CompoundHandler::startLocation(const QXmlAttributes& attrib)
+{
+ m_defFile = attrib.value("file");
+ m_defLine = attrib.value("line").toInt();
+ m_defBodyFile = attrib.value("bodyfile");
+ m_defBodyStart = attrib.value("bodystart").toInt();
+ m_defBodyEnd = attrib.value("bodyend").toInt();
+}
+
+void CompoundHandler::endCompoundName()
+{
+ m_name = m_curString.stripWhiteSpace();
+ debug(2,"Compound name `%s'\n",m_name.data());
+}
+
+void CompoundHandler::startInnerClass(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startInnerNamespace(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startInnerFile(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startInnerGroup(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startInnerPage(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startInnerDir(const QXmlAttributes& attrib)
+{
+ m_innerCompounds.append(new QString(attrib.value("refid")));
+}
+
+void CompoundHandler::startTemplateParamList(const QXmlAttributes& attrib)
+{
+ m_templateParamList = new TemplateParamListHandler(this);
+ m_templateParamList->startTemplateParamList(attrib);
+}
+
+void CompoundHandler::startListOfAllMembers(const QXmlAttributes& attrib)
+{
+ m_members = new ListOfAllMembersHandler(this);
+ m_members->startListOfAllMembers(attrib);
+}
+
+void CompoundHandler::startSuperClass(const QXmlAttributes& attrib)
+{
+ IRelatedCompound::Protection prot = IRelatedCompound::Public;
+ QString protString = attrib.value("prot");
+ if (protString=="protected")
+ {
+ prot = IRelatedCompound::Protected;
+ }
+ else if (protString=="private")
+ {
+ prot = IRelatedCompound::Private;
+ }
+ IRelatedCompound::Kind kind = IRelatedCompound::Normal;
+ QString kindString = attrib.value("virt");
+ if (kindString=="virtual") kind = IRelatedCompound::Virtual;
+
+ RelatedCompound *sc=new RelatedCompound(
+ this,
+ attrib.value("refid"),
+ prot,
+ kind
+ );
+ debug(2,"super class id=`%s' prot=`%s' virt=`%s'\n",
+ attrib.value("refid").data(),
+ protString.data(),
+ kindString.data());
+ m_superClasses.append(sc);
+ m_curString = "";
+}
+
+void CompoundHandler::endSuperClass()
+{
+ m_superClasses.getLast()->setName(m_curString);
+}
+
+void CompoundHandler::startSubClass(const QXmlAttributes& attrib)
+{
+ IRelatedCompound::Protection prot = IRelatedCompound::Public;
+ QString protString = attrib.value("prot");
+ if (protString=="protected") prot = IRelatedCompound::Protected;
+ else if (protString=="private") prot = IRelatedCompound::Private;
+
+ IRelatedCompound::Kind kind = IRelatedCompound::Normal;
+ QString kindString = attrib.value("virt");
+ if (kindString=="virtual") kind = IRelatedCompound::Virtual;
+
+ RelatedCompound *sc = new RelatedCompound(
+ this,
+ attrib.value("refid"),
+ prot,
+ kind
+ );
+ debug(2,"sub class id=`%s' prot=`%s' virt=`%s'\n",
+ attrib.value("refid").data(),
+ protString.data(),
+ kindString.data());
+ m_subClasses.append(sc);
+ m_curString = "";
+}
+
+void CompoundHandler::endSubClass()
+{
+ m_subClasses.getLast()->setName(m_curString);
+}
+
+void CompoundHandler::startTitle(const QXmlAttributes& attrib)
+{
+ ASSERT(m_titleHandler==0);
+ m_titleHandler = new TitleHandler(this);
+ m_titleHandler->startTitle(attrib);
+}
+
+bool CompoundHandler::parseXML(const char *compId)
+{
+ QFile xmlFile(m_xmlDir+"/"+compId+".xml");
+ if (!xmlFile.exists()) return FALSE;
+ CompoundErrorHandler errorHandler;
+ QXmlInputSource source( xmlFile );
+ QXmlSimpleReader reader;
+ reader.setContentHandler( this );
+ reader.setErrorHandler( &errorHandler );
+ reader.parse( source );
+ return TRUE;
+}
+
+void CompoundHandler::initialize(MainHandler *mh)
+{
+ m_mainHandler = mh;
+ QListIterator<SectionHandler> msi(m_sections);
+ SectionHandler *sec;
+ for (;(sec=msi.current());++msi)
+ {
+ sec->initialize(this);
+ }
+ if (m_members)
+ {
+ m_members->initialize(mh);
+ }
+}
+
+void CompoundHandler::insertMember(MemberHandler *mh)
+{
+ m_memberDict.insert(mh->id()->latin1(),mh);
+ mh->initialize(m_mainHandler);
+ QList<MemberHandler> *mhl = m_memberNameDict.find(mh->id()->latin1());
+ if (mhl==0)
+ {
+ mhl = new QList<MemberHandler>;
+ m_memberNameDict.insert(mh->name()->latin1(),mhl);
+ }
+ mhl->append(mh);
+}
+
+ICompound *CompoundHandler::toICompound() const
+{
+ switch (m_kind)
+ {
+ case ICompound::Class: return (IClass *)this;
+ case ICompound::Struct: return (IStruct *)this;
+ case ICompound::Union: return (IUnion *)this;
+ case ICompound::Interface: return (IInterface *)this;
+ case ICompound::Protocol: return (IClass *)this;
+ case ICompound::Category: return (IClass *)this;
+ case ICompound::Exception: return (IException *)this;
+ case ICompound::File: return (IFile *)this;
+ case ICompound::Namespace: return (INamespace *)this;
+ case ICompound::Group: return (IGroup *)this;
+ case ICompound::Page: return (IPage *)this;
+ case ICompound::Example: return (IPage *)this;
+ case ICompound::Dir: return (IDir *)this;
+ default: return 0;
+ }
+ return 0;
+}
+
+void CompoundHandler::release()
+{
+ debug(2,"CompoundHandler::release() %d->%d\n",m_refCount,m_refCount-1);
+ if (--m_refCount<=0)
+ {
+ m_mainHandler->unloadCompound(this);
+ delete this;
+ }
+}
+
+ISectionIterator *CompoundHandler::sections() const
+{
+ return new SectionIterator(m_sections);
+}
+
+IMemberIterator *CompoundHandler::memberByName(const char *name) const
+{
+ QList<MemberHandler> *ml = m_memberNameDict[name];
+ if (ml==0) return 0;
+ return new MemberIterator(*ml);
+}
+
+void CompoundHandler::startInheritanceGraph(const QXmlAttributes &attrib)
+{
+ m_inheritanceGraph = new GraphHandler(this,"inheritancegraph");
+ m_inheritanceGraph->startGraph(attrib);
+}
+
+void CompoundHandler::startCollaborationGraph(const QXmlAttributes &attrib)
+{
+ m_collaborationGraph = new GraphHandler(this,"collaborationgraph");
+ m_collaborationGraph->startGraph(attrib);
+}
+
+void CompoundHandler::startIncludeDependencyGraph(const QXmlAttributes &attrib)
+{
+ m_includeDependencyGraph = new GraphHandler(this,"incdepgraph");
+ m_includeDependencyGraph->startGraph(attrib);
+}
+
+void CompoundHandler::startIncludedByDependencyGraph(const QXmlAttributes &attrib)
+{
+ m_includedByDependencyGraph = new GraphHandler(this,"invincdepgraph");
+ m_includedByDependencyGraph->startGraph(attrib);
+}
+
+IDocRoot *CompoundHandler::briefDescription() const
+{
+ return m_brief;
+}
+
+IDocRoot *CompoundHandler::detailedDescription() const
+{
+ return m_detailed;
+}
+
+IMember *CompoundHandler::memberById(const char *id) const
+{
+ return (IFunction*)m_memberDict[id];
+}
+
+IGraph *CompoundHandler::inheritanceGraph() const
+{
+ return m_inheritanceGraph;
+}
+
+IGraph *CompoundHandler::collaborationGraph() const
+{
+ return m_collaborationGraph;
+}
+
+IGraph *CompoundHandler::includeDependencyGraph() const
+{
+ return m_includeDependencyGraph;
+}
+
+IGraph *CompoundHandler::includedByDependencyGraph() const
+{
+ return m_includedByDependencyGraph;
+}
+
+IRelatedCompoundIterator *CompoundHandler::baseCompounds() const
+{
+ return new RelatedCompoundIterator(m_superClasses);
+}
+
+IRelatedCompoundIterator *CompoundHandler::derivedCompounds() const
+{
+ return new RelatedCompoundIterator(m_subClasses);
+}
+
+ICompoundIterator *CompoundHandler::nestedCompounds() const
+{
+ return new CompoundIdIterator(m_mainHandler,m_innerCompounds);
+}
+
+IDocProgramListing *CompoundHandler::source() const
+{
+ return m_programListing;
+}
+
+IIncludeIterator *CompoundHandler::includes() const
+{
+ return new IncludeIterator(m_includes);
+}
+
+IIncludeIterator *CompoundHandler::includedBy() const
+{
+ return new IncludeIterator(m_includedBy);
+}
+
+IParamIterator *CompoundHandler::templateParameters() const
+{
+ return m_templateParamList ? m_templateParamList->templateParams() : 0;
+}
+
+const IDocTitle *CompoundHandler::title() const
+{
+ return m_titleHandler;
+}
+
+IMemberReferenceIterator *CompoundHandler::members() const
+{
+ return m_members ? m_members->members() : 0;
+}
+
+
diff --git a/addon/doxmlparser/src/compoundhandler.h b/addon/doxmlparser/src/compoundhandler.h
new file mode 100644
index 0000000..c7e5ac0
--- /dev/null
+++ b/addon/doxmlparser/src/compoundhandler.h
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+#ifndef _COMPOUNDHANDLER_H
+#define _COMPOUNDHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+#include <doxmlintf.h>
+
+#include "stringimpl.h"
+#include "basehandler.h"
+#include "baseiterator.h"
+
+class MainHandler;
+class DocHandler;
+class ProgramListingHandler;
+class GraphHandler;
+class MemberHandler;
+class CompoundHandler;
+class SectionHandler;
+class ParamHandler;
+class TemplateParamListHandler;
+class TitleHandler;
+class ListOfAllMembersHandler;
+
+class IncludeHandler : public IInclude, public BaseHandler<IncludeHandler>
+{
+ public:
+ IncludeHandler(IBaseHandler *parent,const char *endtag);
+ virtual ~IncludeHandler();
+
+ void startInclude(const QXmlAttributes &attrib);
+ void endInclude();
+
+ // IInclude
+ virtual const IString * name() const
+ { return &m_name; }
+ virtual const IString * refId() const
+ { return &m_refId; }
+ virtual bool isLocal() const
+ { return &m_isLocal; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_name; // element's content
+ StringImpl m_refId; // refid
+ bool m_isLocal; // local
+};
+
+class IncludeIterator : public BaseIterator<IIncludeIterator,IInclude,IncludeHandler>
+{
+ public:
+ IncludeIterator(const QList<IncludeHandler> &list) :
+ BaseIterator<IIncludeIterator,IInclude,IncludeHandler>(list) {}
+};
+
+
+class RelatedCompound : public IRelatedCompound
+{
+ public:
+ RelatedCompound(CompoundHandler *parent,
+ const QString &id,
+ Protection prot,
+ Kind kind
+ ) :
+ m_parent(parent), m_id(id), m_protection(prot), m_kind(kind) {}
+ virtual ~RelatedCompound() {}
+ void setName(const QString &str) { m_name = str; }
+
+ virtual ICompound *compound() const;
+ virtual Protection protection() const { return m_protection; }
+ virtual Kind kind() const { return m_kind; }
+ virtual const IString *name() const { return &m_name; }
+
+ private:
+ CompoundHandler *m_parent;
+ QString m_id; // refid
+ Protection m_protection; // prot
+ Kind m_kind; // virt
+ StringImpl m_name; // element's content
+};
+
+class RelatedCompoundIterator : public BaseIterator<IRelatedCompoundIterator,IRelatedCompound,RelatedCompound>
+{
+ public:
+ RelatedCompoundIterator(const QList<RelatedCompound> &list) :
+ BaseIterator<IRelatedCompoundIterator,IRelatedCompound,RelatedCompound>(list) {}
+};
+
+
+class CompoundHandler : public IClass,
+ public IStruct,
+ public IUnion,
+ public IException,
+ public IInterface,
+ public INamespace,
+ public IFile,
+ public IGroup,
+ public IPage,
+ public IDir,
+ public BaseHandler<CompoundHandler>
+{
+ friend class RelatedCompound;
+
+ public:
+ virtual void startSection(const QXmlAttributes& attrib);
+ virtual void startCompound(const QXmlAttributes& attrib);
+ virtual void startSuperClass(const QXmlAttributes& attrib);
+ virtual void endSuperClass();
+ virtual void startSubClass(const QXmlAttributes& attrib);
+ virtual void endSubClass();
+ virtual void endCompound();
+ virtual void endCompoundName();
+ virtual void startBriefDesc(const QXmlAttributes& attrib);
+ virtual void startDetailedDesc(const QXmlAttributes& attrib);
+ virtual void startLocation(const QXmlAttributes& attrib);
+ virtual void startProgramListing(const QXmlAttributes& attrib);
+ virtual void startInheritanceGraph(const QXmlAttributes& attrib);
+ virtual void startCollaborationGraph(const QXmlAttributes& attrib);
+ virtual void startIncludeDependencyGraph(const QXmlAttributes& attrib);
+ virtual void startIncludedByDependencyGraph(const QXmlAttributes& attrib);
+ virtual void startIncludes(const QXmlAttributes& attrib);
+ virtual void startIncludedBy(const QXmlAttributes& attrib);
+ virtual void startInnerDir(const QXmlAttributes& attrib);
+ virtual void startInnerClass(const QXmlAttributes& attrib);
+ virtual void startInnerNamespace(const QXmlAttributes& attrib);
+ virtual void startInnerFile(const QXmlAttributes& attrib);
+ virtual void startInnerGroup(const QXmlAttributes& attrib);
+ virtual void startInnerPage(const QXmlAttributes& attrib);
+ virtual void startTitle(const QXmlAttributes& attrib);
+ virtual void startTemplateParamList(const QXmlAttributes& attrib);
+ virtual void startListOfAllMembers(const QXmlAttributes& attrib);
+ virtual void addref() { m_refCount++; }
+
+ CompoundHandler(const QString &dirName);
+ virtual ~CompoundHandler();
+ bool parseXML(const char *compId);
+ void initialize(MainHandler *mh);
+ void insertMember(MemberHandler *mh);
+ ICompound *toICompound() const;
+
+ // ICompound implementation
+ const IString *name() const { return &m_name; }
+ const IString *id() const { return &m_id; }
+ CompoundKind kind() const { return m_kind; }
+ const IString *kindString() const { return &m_kindString; }
+ ISectionIterator *sections() const;
+ IDocRoot *briefDescription() const;
+ IDocRoot *detailedDescription() const;
+ IMember *memberById(const char *id) const;
+ IMemberIterator *memberByName(const char *name) const;
+ IParamIterator *templateParameters() const;
+ void release();
+
+ // IClass implementation
+ IGraph *inheritanceGraph() const;
+ IGraph *collaborationGraph() const;
+ IRelatedCompoundIterator *baseCompounds() const;
+ IRelatedCompoundIterator *derivedCompounds() const;
+ ICompoundIterator *nestedCompounds() const;
+ ICompoundIterator *nestedGroup() const;
+ const IString *locationFile() const { return &m_defFile; }
+ int locationLine() const { return m_defLine; }
+ const IString *locationBodyFile() const { return &m_defBodyFile; }
+ int locationBodyStartLine() const { return m_defBodyStart; }
+ int locationBodyEndLine() const { return m_defBodyEnd; }
+ IMemberReferenceIterator *members() const;
+
+ // IFile implementation
+ IGraph *includeDependencyGraph() const;
+ IGraph *includedByDependencyGraph() const;
+ IDocProgramListing *source() const;
+ IIncludeIterator *includes() const;
+ IIncludeIterator *includedBy() const;
+
+ // IPage implementation
+ const IDocTitle *title() const;
+
+ private:
+ // XML elements:
+ // -------------
+ StringImpl m_name; // compoundname
+ TitleHandler* m_titleHandler; // title
+ QList<RelatedCompound> m_subClasses; // basecompoundref
+ QList<RelatedCompound> m_superClasses; // derivedcompoundref
+ QList<IncludeHandler> m_includes; // includes
+ QList<IncludeHandler> m_includedBy; // includedBy
+ GraphHandler* m_includeDependencyGraph; // incdepgraph
+ GraphHandler* m_includedByDependencyGraph; // invincdepgraph
+ QList<QString> m_innerCompounds; // innerdir/innerfile/innerclass/innernamespace/innergroup
+ TemplateParamListHandler* m_templateParamList; // templateparamlist
+ QList<SectionHandler> m_sections; // sectiondef
+ DocHandler* m_brief; // briefdescription
+ DocHandler* m_detailed; // detaileddescription
+ GraphHandler* m_inheritanceGraph; // inheritancegraph
+ GraphHandler* m_collaborationGraph; // collaborationgraph
+ ProgramListingHandler* m_programListing; // programlisting
+ // location
+ StringImpl m_defFile; // - file
+ int m_defLine; // - line
+ StringImpl m_defBodyFile; // - bodyfile
+ int m_defBodyStart; // - bodystart
+ int m_defBodyEnd; // - bodyend
+ ListOfAllMembersHandler* m_members; // listofallmember
+
+ // XML attributes:
+ // ---------------
+ StringImpl m_id; // id
+ CompoundKind m_kind; // kind
+ StringImpl m_kindString; // kind as a string
+ StringImpl m_protection; // prot
+
+ // local variables
+ QString m_xmlDir; // directory where the info is found
+ int m_refCount; // object reference counter
+ QDict<MemberHandler> m_memberDict; // id->member lookup
+ QDict<QList<MemberHandler> > m_memberNameDict; // name->memberlist lookup
+ MainHandler* m_mainHandler; // parent object
+};
+
+void compoundhandler_init();
+void compoundhandler_exit();
+
+#endif
diff --git a/addon/doxmlparser/src/debug.cpp b/addon/doxmlparser/src/debug.cpp
new file mode 100644
index 0000000..a8be32c
--- /dev/null
+++ b/addon/doxmlparser/src/debug.cpp
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "debug.h"
+
+static int s_debugLevel = 0;
+
+void debug(int level,const char *msg,...)
+{
+ if (level<=s_debugLevel)
+ {
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+ }
+}
+
+void setDebugLevel(int level)
+{
+ s_debugLevel = level;
+}
+
diff --git a/addon/doxmlparser/src/debug.h b/addon/doxmlparser/src/debug.h
new file mode 100644
index 0000000..c77f7fe
--- /dev/null
+++ b/addon/doxmlparser/src/debug.h
@@ -0,0 +1,7 @@
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+void debug(int level,const char *msg,...);
+void setDebugLevel(int level);
+
+#endif
diff --git a/addon/doxmlparser/src/dochandler.cpp b/addon/doxmlparser/src/dochandler.cpp
new file mode 100644
index 0000000..df71e6a
--- /dev/null
+++ b/addon/doxmlparser/src/dochandler.cpp
@@ -0,0 +1,2240 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include <qmap.h>
+
+#include "dochandler.h"
+#include "debug.h"
+#include "linkedtexthandler.h"
+
+
+//----------------------------------------------------------------------
+
+class TypeNameMapper
+{
+ public:
+ TypeNameMapper()
+ {
+ m_map.insert("see", SimpleSectHandler::See);
+ m_map.insert("return", SimpleSectHandler::Return);
+ m_map.insert("author", SimpleSectHandler::Author);
+ m_map.insert("version", SimpleSectHandler::Version);
+ m_map.insert("since", SimpleSectHandler::Since);
+ m_map.insert("date", SimpleSectHandler::Date);
+ m_map.insert("bug", SimpleSectHandler::Bug);
+ m_map.insert("note", SimpleSectHandler::Note);
+ m_map.insert("warning", SimpleSectHandler::Warning);
+ m_map.insert("par", SimpleSectHandler::Par);
+ m_map.insert("deprecated",SimpleSectHandler::Deprecated);
+ m_map.insert("pre", SimpleSectHandler::Pre);
+ m_map.insert("post", SimpleSectHandler::Post);
+ m_map.insert("invariant", SimpleSectHandler::Invar);
+ m_map.insert("remark", SimpleSectHandler::Remark);
+ m_map.insert("attention", SimpleSectHandler::Attention);
+ m_map.insert("todo", SimpleSectHandler::Todo);
+ m_map.insert("test", SimpleSectHandler::Test);
+ m_map.insert("rcs", SimpleSectHandler::RCS);
+ m_map.insert("enumvalues",SimpleSectHandler::EnumValues);
+ m_map.insert("examples", SimpleSectHandler::Examples);
+ }
+ SimpleSectHandler::Types stringToType(const QString &typeStr)
+ {
+ return m_map[typeStr];
+ }
+ private:
+ QMap<QString,SimpleSectHandler::Types> m_map;
+};
+
+class HighlightMapper
+{
+ public:
+ HighlightMapper()
+ {
+ m_map.insert("comment", HighlightHandler::Comment);
+ m_map.insert("keyword", HighlightHandler::Keyword);
+ m_map.insert("keywordtype", HighlightHandler::KeywordType);
+ m_map.insert("keywordflow", HighlightHandler::KeywordFlow);
+ m_map.insert("charliteral", HighlightHandler::CharLiteral);
+ m_map.insert("stringliteral", HighlightHandler::StringLiteral);
+ m_map.insert("preprocessor", HighlightHandler::Preprocessor);
+ }
+ HighlightHandler::HighlightKind stringToKind(const QString &kindStr)
+ {
+ return m_map[kindStr];
+ }
+ private:
+ QMap<QString,HighlightHandler::HighlightKind> m_map;
+};
+
+static TypeNameMapper *s_typeMapper;
+static HighlightMapper *s_highlightMapper;
+
+void dochandler_init()
+{
+ s_typeMapper = new TypeNameMapper;
+ s_highlightMapper = new HighlightMapper;
+}
+
+void dochandler_exit()
+{
+ delete s_typeMapper;
+ delete s_highlightMapper;
+}
+
+//----------------------------------------------------------------------
+// MarkupHandler
+//----------------------------------------------------------------------
+
+MarkupHandler::MarkupHandler(QList<DocImpl> &children,QString &curString)
+ : m_children(children), m_curString(curString),
+ m_curMarkup(IDocMarkup::Normal), m_headingLevel(0)
+{
+ addStartHandler("bold",this,&MarkupHandler::startBold);
+ addEndHandler("bold",this,&MarkupHandler::endBold);
+
+ addStartHandler("emphasis",this,&MarkupHandler::startEmphasis);
+ addEndHandler("emphasis",this,&MarkupHandler::endEmphasis);
+
+ addStartHandler("computeroutput",this,&MarkupHandler::startComputerOutput);
+ addEndHandler("computeroutput",this,&MarkupHandler::endComputerOutput);
+
+ addStartHandler("center",this,&MarkupHandler::startCenter);
+ addEndHandler("center",this,&MarkupHandler::endCenter);
+
+ addStartHandler("small",this,&MarkupHandler::startSmallFont);
+ addEndHandler("small",this,&MarkupHandler::endSmallFont);
+
+ addStartHandler("subscript",this,&MarkupHandler::startSubscript);
+ addEndHandler("subscript",this,&MarkupHandler::endSubscript);
+
+ addStartHandler("superscript",this,&MarkupHandler::startSuperscript);
+ addEndHandler("superscript",this,&MarkupHandler::endSuperscript);
+
+ addStartHandler("preformatted",this,&MarkupHandler::startPreformatted);
+ addEndHandler("preformatted",this,&MarkupHandler::endPreformatted);
+
+ addStartHandler("heading1",this,&MarkupHandler::startHeading1);
+ addEndHandler("heading1",this,&MarkupHandler::endHeading1);
+
+ addStartHandler("heading2",this,&MarkupHandler::startHeading2);
+ addEndHandler("heading2",this,&MarkupHandler::endHeading2);
+
+ addStartHandler("heading3",this,&MarkupHandler::startHeading3);
+ addEndHandler("heading3",this,&MarkupHandler::endHeading3);
+
+ addStartHandler("heading4",this,&MarkupHandler::startHeading4);
+ addEndHandler("heading4",this,&MarkupHandler::endHeading4);
+
+ addStartHandler("heading5",this,&MarkupHandler::startHeading5);
+ addEndHandler("heading5",this,&MarkupHandler::endHeading5);
+
+ addStartHandler("heading6",this,&MarkupHandler::startHeading6);
+ addEndHandler("heading6",this,&MarkupHandler::endHeading6);
+}
+
+MarkupHandler::~MarkupHandler()
+{
+}
+
+void MarkupHandler::addTextNode()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(new TextNode(m_curString,m_curMarkup,m_headingLevel));
+ debug(2,"addTextNode() text=%s markup=%x\n",m_curString.data(),m_curMarkup);
+ m_curString="";
+ }
+}
+
+void MarkupHandler::startBold(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Bold,TRUE));
+ m_curMarkup |= IDocMarkup::Bold;
+}
+
+void MarkupHandler::endBold()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Bold,FALSE));
+ m_curMarkup &= ~IDocMarkup::Bold;
+}
+
+void MarkupHandler::startEmphasis(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Emphasis,TRUE));
+ m_curMarkup |= IDocMarkup::Emphasis;
+}
+
+void MarkupHandler::endEmphasis()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Emphasis,FALSE));
+ m_curMarkup &= ~IDocMarkup::Emphasis;
+}
+
+void MarkupHandler::startComputerOutput(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::ComputerOutput,TRUE));
+ m_curMarkup |= IDocMarkup::ComputerOutput;
+}
+
+void MarkupHandler::endComputerOutput()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::ComputerOutput,FALSE));
+ m_curMarkup &= ~IDocMarkup::ComputerOutput;
+}
+
+void MarkupHandler::startCenter(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Center,TRUE));
+ m_curMarkup |= IDocMarkup::Center;
+}
+
+void MarkupHandler::endCenter()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Center,FALSE));
+ m_curMarkup &= ~IDocMarkup::Center;
+}
+
+void MarkupHandler::startSmallFont(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::SmallFont,TRUE));
+ m_curMarkup |= IDocMarkup::SmallFont;
+}
+
+void MarkupHandler::endSmallFont()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::SmallFont,FALSE));
+ m_curMarkup &= ~IDocMarkup::SmallFont;
+}
+
+void MarkupHandler::startSubscript(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Subscript,TRUE));
+ m_curMarkup |= IDocMarkup::Subscript;
+}
+
+void MarkupHandler::endSubscript()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Subscript,FALSE));
+ m_curMarkup &= ~IDocMarkup::Subscript;
+}
+
+void MarkupHandler::startSuperscript(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Superscript,TRUE));
+ m_curMarkup |= IDocMarkup::Superscript;
+}
+
+void MarkupHandler::endSuperscript()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Superscript,FALSE));
+ m_curMarkup &= ~IDocMarkup::Superscript;
+}
+
+void MarkupHandler::startPreformatted(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Preformatted,TRUE));
+ m_curMarkup |= IDocMarkup::Preformatted;
+}
+
+void MarkupHandler::endPreformatted()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Preformatted,FALSE));
+ m_curMarkup &= ~IDocMarkup::Preformatted;
+}
+
+void MarkupHandler::startHeading1(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,1));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=1;
+}
+
+void MarkupHandler::endHeading1()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,1));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+void MarkupHandler::startHeading2(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,2));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=2;
+}
+
+void MarkupHandler::endHeading2()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,2));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+void MarkupHandler::startHeading3(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,3));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=3;
+}
+
+void MarkupHandler::endHeading3()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,3));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+void MarkupHandler::startHeading4(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,4));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=4;
+}
+
+void MarkupHandler::endHeading4()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,4));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+void MarkupHandler::startHeading5(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,5));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=5;
+}
+
+void MarkupHandler::endHeading5()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,5));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+void MarkupHandler::startHeading6(const QXmlAttributes & /*attrib*/)
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,TRUE,6));
+ m_curMarkup |= IDocMarkup::Heading;
+ m_headingLevel=6;
+}
+
+void MarkupHandler::endHeading6()
+{
+ addTextNode();
+ m_children.append(new MarkupModifierNode(IDocMarkup::Heading,FALSE,6));
+ m_curMarkup &= ~IDocMarkup::Heading;
+ m_headingLevel=0;
+}
+
+
+//----------------------------------------------------------------------
+// ListItemHandler
+//----------------------------------------------------------------------
+
+ListItemHandler::ListItemHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+
+ addEndHandler("listitem",this,&ListItemHandler::endListItem);
+
+ addStartHandler("para",this,&ListItemHandler::startParagraph);
+}
+
+ListItemHandler::~ListItemHandler()
+{
+}
+
+void ListItemHandler::startListItem(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start list item handler\n");
+}
+
+void ListItemHandler::endListItem()
+{
+ debug(2,"end list item handler\n");
+ m_parent->setDelegate(0);
+}
+
+void ListItemHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *parHandler = new ParagraphHandler(this);
+ parHandler->startParagraph(attrib);
+ m_children.append(parHandler);
+}
+
+IDocIterator *ListItemHandler::contents() const
+{
+ return new ListItemIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// OrderedListHandler
+//----------------------------------------------------------------------
+
+OrderedListHandler::OrderedListHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("orderedlist",this,&OrderedListHandler::endOrderedList);
+ addStartHandler("listitem",this,&OrderedListHandler::startOrderedListItem);
+}
+
+OrderedListHandler::~OrderedListHandler()
+{
+}
+
+void OrderedListHandler::startOrderedList(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+}
+
+void OrderedListHandler::endOrderedList()
+{
+ m_parent->setDelegate(0);
+}
+
+void OrderedListHandler::startOrderedListItem(const QXmlAttributes& attrib)
+{
+ ListItemHandler *liHandler = new ListItemHandler(this);
+ liHandler->startListItem(attrib);
+ m_children.append(liHandler);
+}
+
+IDocIterator *OrderedListHandler::elements() const
+{
+ return new OrderedListIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// ItemizedListHandler
+//----------------------------------------------------------------------
+
+ItemizedListHandler::ItemizedListHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("itemizedlist",this,&ItemizedListHandler::endItemizedList);
+ addStartHandler("listitem",this,&ItemizedListHandler::startItemizedListItem);
+}
+
+ItemizedListHandler::~ItemizedListHandler()
+{
+}
+
+void ItemizedListHandler::startItemizedList(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+}
+
+void ItemizedListHandler::endItemizedList()
+{
+ m_parent->setDelegate(0);
+}
+
+void ItemizedListHandler::startItemizedListItem(const QXmlAttributes& attrib)
+{
+ ListItemHandler *liHandler = new ListItemHandler(this);
+ liHandler->startListItem(attrib);
+ m_children.append(liHandler);
+}
+
+IDocIterator *ItemizedListHandler::elements() const
+{
+ return new ItemizedListIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// TocListHandler
+//----------------------------------------------------------------------
+
+TocListHandler::TocListHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("toclist",this,&TocListHandler::endTocList);
+ addStartHandler("tocitem",this,&TocListHandler::startTocItem);
+}
+
+TocListHandler::~TocListHandler()
+{
+}
+
+void TocListHandler::startTocList(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+}
+
+void TocListHandler::endTocList()
+{
+ m_parent->setDelegate(0);
+}
+
+void TocListHandler::startTocItem(const QXmlAttributes& attrib)
+{
+ TocItemHandler *tiHandler = new TocItemHandler(this);
+ tiHandler->startTocItem(attrib);
+ m_children.append(tiHandler);
+}
+
+IDocIterator *TocListHandler::elements() const
+{
+ return new TocListIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// TocItemHandler
+//----------------------------------------------------------------------
+
+TocItemHandler::TocItemHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ addEndHandler("tocitem",this,&TocItemHandler::endTocItem);
+}
+
+TocItemHandler::~TocItemHandler()
+{
+}
+
+void TocItemHandler::startTocItem(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_id = attrib.value("id");
+ m_curString="";
+}
+
+void TocItemHandler::endTocItem()
+{
+ m_title = m_curString;
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// ParameterHandler
+//----------------------------------------------------------------------
+
+ParameterHandler::ParameterHandler(IBaseHandler *parent) :
+ m_parent(parent)
+{
+ addEndHandler("parametername",this,&ParameterHandler::endParameterName);
+}
+
+ParameterHandler::~ParameterHandler()
+{
+}
+
+void ParameterHandler::startParameterName(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+}
+
+void ParameterHandler::endParameterName()
+{
+ m_name = m_curString;
+ debug(2,"parameter %s\n",m_name.data());
+ m_curString="";
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// ParameterListHandler
+//----------------------------------------------------------------------
+
+ParameterItemHandler::ParameterItemHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("parameteritem",this,&ParameterItemHandler::endParameterItem);
+ addStartHandler("parameternamelist");
+ addEndHandler("parameternamelist");
+ addStartHandler("parametername",this,&ParameterItemHandler::startParameterName);
+ addStartHandler("parameterdescription");
+ addEndHandler("parameterdescription");
+ addStartHandler("para",this,&ParameterItemHandler::startParagraph);
+ m_parameters.setAutoDelete(TRUE);
+ m_description = 0;
+}
+
+ParameterItemHandler::~ParameterItemHandler()
+{
+ delete m_description;
+}
+
+void ParameterItemHandler::startParameterItem(const QXmlAttributes&)
+{
+ m_parent->setDelegate(this);
+}
+
+void ParameterItemHandler::endParameterItem()
+{
+ m_parent->setDelegate(0);
+}
+
+void ParameterItemHandler::startParameterName(const QXmlAttributes& attrib)
+{
+ ParameterHandler *param = new ParameterHandler(this);
+ m_parameters.append(param);
+ param->startParameterName(attrib);
+}
+
+void ParameterItemHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ m_description = new ParagraphHandler(this);
+ m_description->startParagraph(attrib);
+}
+
+IDocIterator *ParameterItemHandler::paramNames() const
+{
+ return new ParameterItemIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// ParameterListHandler
+//----------------------------------------------------------------------
+
+ParameterListHandler::ParameterListHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("parameterlist",this,&ParameterListHandler::endParameterList);
+ addStartHandler("parameteritem",this,&ParameterListHandler::startParameterItem);
+ m_paramItems.setAutoDelete(TRUE);
+}
+
+ParameterListHandler::~ParameterListHandler()
+{
+}
+
+void ParameterListHandler::startParameterList(const QXmlAttributes& attrib)
+{
+ QString kind = attrib.value("kind");
+ if (kind=="retval") m_type=RetVal;
+ else if (kind=="exception") m_type=Exception;
+ else if (kind=="param") m_type=Param;
+ else
+ {
+ debug(1,"Error: invalid parameterlist type: %s\n",kind.data());
+ }
+ debug(2,"parameterlist kind=%s\n",kind.data());
+ m_parent->setDelegate(this);
+}
+
+void ParameterListHandler::endParameterList()
+{
+ m_parent->setDelegate(0);
+}
+
+void ParameterListHandler::startParameterItem(const QXmlAttributes& attrib)
+{
+ ParameterItemHandler *paramItem = new ParameterItemHandler(this);
+ m_paramItems.append(paramItem);
+ paramItem->startParameterItem(attrib);
+}
+
+IDocIterator *ParameterListHandler::params() const
+{
+ return new ParameterListIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// LinkHandler
+//----------------------------------------------------------------------
+
+LinkHandler::LinkHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("link",this,&LinkHandler::endLink);
+}
+
+LinkHandler::~LinkHandler()
+{
+}
+
+void LinkHandler::startLink(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start link\n");
+ m_ref = attrib.value("linkend");
+ m_curString="";
+}
+
+void LinkHandler::endLink()
+{
+ m_text = m_curString;
+ m_curString="";
+ m_parent->setDelegate(0);
+ debug(2,"End link\n");
+}
+
+//----------------------------------------------------------------------
+// EMailHandler
+//----------------------------------------------------------------------
+
+EMailHandler::EMailHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("email",this,&EMailHandler::endEMail);
+}
+
+EMailHandler::~EMailHandler()
+{
+}
+
+void EMailHandler::startEMail(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start email\n");
+ m_curString="";
+}
+
+void EMailHandler::endEMail()
+{
+ m_address = m_curString;
+ m_curString="";
+ m_parent->setDelegate(0);
+ debug(2,"End email\n");
+}
+
+//----------------------------------------------------------------------
+// ULinkHandler
+//----------------------------------------------------------------------
+
+ULinkHandler::ULinkHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("ulink",this,&ULinkHandler::endULink);
+}
+
+ULinkHandler::~ULinkHandler()
+{
+}
+
+void ULinkHandler::startULink(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start ulink\n");
+ m_url = attrib.value("url");
+ m_curString="";
+}
+
+void ULinkHandler::endULink()
+{
+ m_text = m_curString;
+ m_curString="";
+ m_parent->setDelegate(0);
+ debug(2,"End ulink\n");
+}
+
+//----------------------------------------------------------------------
+// LineBreakHandler
+//----------------------------------------------------------------------
+
+LineBreakHandler::LineBreakHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("linebreak",this,&LineBreakHandler::endLineBreak);
+}
+
+LineBreakHandler::~LineBreakHandler()
+{
+}
+
+void LineBreakHandler::startLineBreak(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start linebreak\n");
+}
+
+void LineBreakHandler::endLineBreak()
+{
+ m_parent->setDelegate(0);
+ debug(2,"End linebreak\n");
+}
+
+//----------------------------------------------------------------------
+// HRulerHandler
+//----------------------------------------------------------------------
+
+HRulerHandler::HRulerHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("hruler",this,&HRulerHandler::endHRuler);
+}
+
+HRulerHandler::~HRulerHandler()
+{
+}
+
+void HRulerHandler::startHRuler(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start hruler\n");
+}
+
+void HRulerHandler::endHRuler()
+{
+ m_parent->setDelegate(0);
+ debug(2,"End hruler\n");
+}
+
+//----------------------------------------------------------------------
+// RefHandler
+//----------------------------------------------------------------------
+
+RefHandler::RefHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("ref",this,&RefHandler::endRef);
+}
+
+RefHandler::~RefHandler()
+{
+}
+
+void RefHandler::startRef(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_refId = attrib.value("refid");
+ m_extId = attrib.value("external");
+ ASSERT(attrib.value("kindref")=="compound" ||
+ attrib.value("kindref")=="member");
+ m_targetKind = attrib.value("kindref")=="compound" ? Compound : Member;
+ debug(2,"Start ref refId=%s\n",m_refId.data());
+ m_curString="";
+}
+
+void RefHandler::endRef()
+{
+ m_linkText = m_curString;
+ m_parent->setDelegate(0);
+ debug(2,"End ref: text=`%s'\n",m_linkText.data());
+}
+
+
+//----------------------------------------------------------------------
+// TitleHandler
+//----------------------------------------------------------------------
+
+TitleHandler::TitleHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ m_markupHandler = new MarkupHandler(m_children,m_curString);
+ setFallBackHandler(m_markupHandler);
+ addStartHandler("ref",this,&TitleHandler::startRef);
+ addEndHandler("title",this,&TitleHandler::endTitle);
+}
+
+TitleHandler::~TitleHandler()
+{
+ delete m_markupHandler;
+}
+
+void TitleHandler::startTitle(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start title\n");
+ m_curString="";
+}
+
+void TitleHandler::endTitle()
+{
+ addTextNode();
+ m_parent->setDelegate(0);
+ debug(2,"End title\n");
+}
+
+void TitleHandler::addTextNode()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(
+ new TextNode(
+ m_curString,
+ m_markupHandler->markup(),
+ m_markupHandler->headingLevel()
+ )
+ );
+ debug(2,"addTextNode() text=\"%s\" markup=%x headingLevel=%d\n",
+ m_curString.data(),m_markupHandler->markup(),m_markupHandler->headingLevel());
+ m_curString="";
+ }
+}
+
+void TitleHandler::startRef(const QXmlAttributes& attrib)
+{
+ RefHandler *ref = new RefHandler(this);
+ ref->startRef(attrib);
+ m_children.append(ref);
+}
+
+IDocIterator *TitleHandler::title() const
+{
+ return new TitleIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// SimpleSectHandler
+//----------------------------------------------------------------------
+
+SimpleSectHandler::SimpleSectHandler(IBaseHandler *parent)
+ : m_parent(parent), m_paragraph(0), m_title(0)
+{
+ addStartHandler("title",this,&SimpleSectHandler::startTitle);
+ addStartHandler("para",this,&SimpleSectHandler::startParagraph);
+ addEndHandler("simplesect",this,&SimpleSectHandler::endSimpleSect);
+}
+
+SimpleSectHandler::~SimpleSectHandler()
+{
+}
+
+void SimpleSectHandler::startSimpleSect(const QXmlAttributes& attrib)
+{
+ m_typeString = attrib.value("kind");
+ m_type = s_typeMapper->stringToType(m_typeString);
+ debug(2,"start simple section %s\n",m_typeString.data());
+ m_parent->setDelegate(this);
+}
+
+void SimpleSectHandler::endSimpleSect()
+{
+ debug(2,"end simple section\n");
+ m_parent->setDelegate(0);
+}
+
+void SimpleSectHandler::startTitle(const QXmlAttributes& attrib)
+{
+ ASSERT(m_title==0);
+ m_title = new TitleHandler(this);
+ m_title->startTitle(attrib);
+}
+
+void SimpleSectHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ASSERT(m_paragraph==0);
+ m_paragraph = new ParagraphHandler(this);
+ m_paragraph->startParagraph(attrib);
+}
+
+//----------------------------------------------------------------------
+// VariableListEntryHandler
+//----------------------------------------------------------------------
+
+VariableListEntryHandler::VariableListEntryHandler(IBaseHandler *parent)
+ : m_parent(parent), m_description(0), m_linkedTextHandler(0)
+{
+ addStartHandler("term",this,&VariableListEntryHandler::startTerm);
+ addEndHandler("term",this,&VariableListEntryHandler::endTerm);
+ addStartHandler("para",this,&VariableListEntryHandler::startParagraph);
+ addEndHandler("varlistentry",this,&VariableListEntryHandler::endVarListEntry);
+ addEndHandler("listitem",this,&VariableListEntryHandler::endListItem);
+}
+
+VariableListEntryHandler::~VariableListEntryHandler()
+{
+ delete m_description;
+}
+
+void VariableListEntryHandler::startVarListEntry(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start varlistentry\n");
+}
+
+void VariableListEntryHandler::endVarListEntry()
+{
+ m_parent->setDelegate(0);
+ debug(2,"end varlistentry\n");
+}
+
+void VariableListEntryHandler::startListItem(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start listitem\n");
+}
+
+void VariableListEntryHandler::endListItem()
+{
+ m_parent->setDelegate(0);
+ debug(2,"end listitem\n");
+}
+
+void VariableListEntryHandler::startTerm(const QXmlAttributes& /*attrib*/)
+{
+ m_curString="";
+ m_linkedTextHandler = new LinkedTextHandler(this,m_term);
+ m_linkedTextHandler->start("term");
+}
+
+void VariableListEntryHandler::endTerm()
+{
+ delete m_linkedTextHandler;
+}
+
+void VariableListEntryHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ASSERT(m_description==0);
+ m_description = new ParagraphHandler(this);
+ m_description->startParagraph(attrib);
+}
+
+ILinkedTextIterator *VariableListEntryHandler::term() const
+{
+ return new LinkedTextIterator(m_term);
+}
+
+
+//----------------------------------------------------------------------
+// VariableListHandler
+//----------------------------------------------------------------------
+
+VariableListHandler::VariableListHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_entries.setAutoDelete(TRUE);
+ addStartHandler("varlistentry",this,&VariableListHandler::startVarListEntry);
+ addStartHandler("listitem",this,&VariableListHandler::startListItem);
+ addEndHandler("variablelist",this,&VariableListHandler::endVariableList);
+}
+
+VariableListHandler::~VariableListHandler()
+{
+}
+
+void VariableListHandler::startVariableList(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start variablelist\n");
+}
+
+void VariableListHandler::endVariableList()
+{
+ debug(2,"end variablelist\n");
+ m_parent->setDelegate(0);
+}
+
+void VariableListHandler::startVarListEntry(const QXmlAttributes& attrib)
+{
+ VariableListEntryHandler *vle = new VariableListEntryHandler(this);
+ vle->startVarListEntry(attrib);
+ m_curEntry = vle;
+ m_entries.append(vle);
+}
+
+void VariableListHandler::startListItem(const QXmlAttributes& attrib)
+{
+ ASSERT(m_curEntry!=0);
+ m_curEntry->startListItem(attrib);
+}
+
+IDocIterator *VariableListHandler::entries() const
+{
+ return new VariableListIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// HighlightHandler
+//----------------------------------------------------------------------
+
+HighlightHandler::HighlightHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("highlight",this,&HighlightHandler::endHighlight);
+ addStartHandler("ref",this,&HighlightHandler::startRef);
+ addStartHandler("sp",this,&HighlightHandler::startSpace);
+ m_hl = IDocHighlight::Invalid;
+}
+
+HighlightHandler::~HighlightHandler()
+{
+}
+
+void HighlightHandler::startHighlight(const QXmlAttributes& attrib)
+{
+ m_hlString = attrib.value("class");
+ m_hl = s_highlightMapper->stringToKind(m_hlString);
+ m_curString="";
+ m_parent->setDelegate(this);
+ debug(2,"start highlight\n");
+}
+
+void HighlightHandler::endHighlight()
+{
+ addTextNode();
+ debug(2,"end highlight class=`%s'\n",m_hlString.data());
+ m_parent->setDelegate(0);
+}
+
+void HighlightHandler::startRef(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ RefHandler *rh = new RefHandler(this);
+ m_children.append(rh);
+ rh->startRef(attrib);
+}
+
+void HighlightHandler::startSpace(const QXmlAttributes&)
+{
+ m_curString=" ";
+ addTextNode();
+}
+
+void HighlightHandler::addTextNode()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(new TextNode(m_curString,IDocMarkup::Normal,0));
+ debug(2,"addTextNode() text=\"%s\"\n",
+ m_curString.data());
+ m_curString="";
+ }
+}
+
+IDocIterator *HighlightHandler::codeElements() const
+{
+ return new HighlightIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// CodeLineHandler
+//----------------------------------------------------------------------
+
+CodeLineHandler::CodeLineHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("codeline",this,&CodeLineHandler::endCodeLine);
+ addEndHandler("linenumber",this,&CodeLineHandler::endLineNumber);
+ addStartHandler("highlight",this,&CodeLineHandler::startHighlight);
+ addStartHandler("ref",this,&CodeLineHandler::startRef);
+ m_lineNumber = 0;
+}
+
+CodeLineHandler::~CodeLineHandler()
+{
+}
+
+void CodeLineHandler::startCodeLine(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start codeline\n");
+}
+
+void CodeLineHandler::endCodeLine()
+{
+ addTextNode();
+ debug(2,"end codeline\n");
+ m_parent->setDelegate(0);
+}
+
+void CodeLineHandler::startLineNumber(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start linenumber\n");
+ m_lineNumber = attrib.value("line").toInt();
+ m_refId = attrib.value("refid");
+}
+
+void CodeLineHandler::endLineNumber()
+{
+ m_parent->setDelegate(0);
+}
+
+void CodeLineHandler::startHighlight(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ HighlightHandler *hlh = new HighlightHandler(this);
+ m_children.append(hlh);
+ hlh->startHighlight(attrib);
+}
+
+void CodeLineHandler::startRef(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ RefHandler *rh = new RefHandler(this);
+ m_children.append(rh);
+ rh->startRef(attrib);
+}
+
+void CodeLineHandler::addTextNode()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(new TextNode(m_curString,IDocMarkup::Normal,0));
+ debug(2,"addTextNode() text=\"%s\"\n",
+ m_curString.data());
+ m_curString="";
+ }
+}
+
+IDocIterator *CodeLineHandler::codeElements() const
+{
+ return new CodeLineIterator(*this);
+}
+
+
+//----------------------------------------------------------------------
+// ProgramListingHandler
+//----------------------------------------------------------------------
+
+ProgramListingHandler::ProgramListingHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ m_hasLineNumber=FALSE;
+ addEndHandler("programlisting",this,&ProgramListingHandler::endProgramListing);
+
+ addStartHandler("linenumber",this,&ProgramListingHandler::startLineNumber);
+ addStartHandler("codeline",this,&ProgramListingHandler::startCodeLine);
+}
+
+ProgramListingHandler::~ProgramListingHandler()
+{
+}
+
+void ProgramListingHandler::startProgramListing(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start programlisting\n");
+}
+
+void ProgramListingHandler::endProgramListing()
+{
+ debug(2,"end programlisting\n");
+ m_parent->setDelegate(0);
+}
+
+void ProgramListingHandler::startLineNumber(const QXmlAttributes& attrib)
+{
+ CodeLineHandler *clh = new CodeLineHandler(this);
+ m_children.append(clh);
+ m_hasLineNumber=TRUE;
+ clh->startLineNumber(attrib);
+}
+
+void ProgramListingHandler::startCodeLine(const QXmlAttributes& attrib)
+{
+ CodeLineHandler *clh = 0;
+ if (!m_hasLineNumber)
+ {
+ clh = new CodeLineHandler(this);
+ m_children.append(clh);
+ }
+ else
+ {
+ clh = m_children.getLast();
+ }
+ ASSERT(clh!=0);
+ clh->startCodeLine(attrib);
+ m_hasLineNumber=FALSE;
+}
+
+IDocIterator *ProgramListingHandler::codeLines() const
+{
+ return new ProgramListingIterator(*this);
+}
+
+
+
+//----------------------------------------------------------------------
+// FormulaHandler
+//----------------------------------------------------------------------
+
+FormulaHandler::FormulaHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("formula",this,&FormulaHandler::endFormula);
+}
+
+FormulaHandler::~FormulaHandler()
+{
+}
+
+void FormulaHandler::startFormula(const QXmlAttributes& attrib)
+{
+ m_id = attrib.value("id");
+ m_curString="";
+ m_parent->setDelegate(this);
+}
+
+void FormulaHandler::endFormula()
+{
+ m_text = m_curString;
+ debug(2,"formula id=`%s' text=`%s'\n",m_id.data(),m_text.data());
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// AnchorHandler
+//----------------------------------------------------------------------
+
+AnchorHandler::AnchorHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("anchor",this,&AnchorHandler::endAnchor);
+}
+
+AnchorHandler::~AnchorHandler()
+{
+}
+
+void AnchorHandler::startAnchor(const QXmlAttributes& attrib)
+{
+ m_id = attrib.value("id");
+ m_parent->setDelegate(this);
+}
+
+void AnchorHandler::endAnchor()
+{
+ debug(2,"anchor id=`%s'\n",m_id.data());
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// ImageHandler
+//----------------------------------------------------------------------
+
+ImageHandler::ImageHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("image",this,&ImageHandler::endImage);
+}
+
+ImageHandler::~ImageHandler()
+{
+}
+
+void ImageHandler::startImage(const QXmlAttributes& attrib)
+{
+ m_name = attrib.value("name");
+ m_curString="";
+ m_parent->setDelegate(this);
+}
+
+void ImageHandler::endImage()
+{
+ m_caption = m_curString;
+ debug(2,"image name=`%s' caption=`%s'\n",m_name.data(),m_caption.data());
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// DotFileHandler
+//----------------------------------------------------------------------
+
+DotFileHandler::DotFileHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("dotfile",this,&DotFileHandler::endDotFile);
+}
+
+DotFileHandler::~DotFileHandler()
+{
+}
+
+void DotFileHandler::startDotFile(const QXmlAttributes& attrib)
+{
+ m_name = attrib.value("name");
+ m_curString="";
+ m_parent->setDelegate(this);
+}
+
+void DotFileHandler::endDotFile()
+{
+ m_caption = m_curString;
+ debug(2,"image name=`%s' caption=`%s'\n",m_name.data(),m_caption.data());
+ m_parent->setDelegate(0);
+}
+
+//----------------------------------------------------------------------
+// IndexEntryHandler
+//----------------------------------------------------------------------
+
+IndexEntryHandler::IndexEntryHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("indexentry",this,&IndexEntryHandler::endIndexEntry);
+ addStartHandler("primaryie",this,&IndexEntryHandler::startPrimaryIE);
+ addEndHandler("primaryie",this,&IndexEntryHandler::endPrimaryIE);
+ addStartHandler("secondaryie",this,&IndexEntryHandler::startSecondaryIE);
+ addEndHandler("secondaryie",this,&IndexEntryHandler::endSecondaryIE);
+}
+
+IndexEntryHandler::~IndexEntryHandler()
+{
+}
+
+void IndexEntryHandler::startIndexEntry(const QXmlAttributes& /*attrib*/)
+{
+ debug(2,"start index entry\n");
+ m_parent->setDelegate(this);
+}
+
+void IndexEntryHandler::endIndexEntry()
+{
+ debug(2,"index entry primary=`%s' secondary=`%s'\n",
+ m_primary.data(),m_secondary.data());
+ m_parent->setDelegate(0);
+}
+
+void IndexEntryHandler::startPrimaryIE(const QXmlAttributes& /*attrib*/)
+{
+ m_curString="";
+}
+
+void IndexEntryHandler::endPrimaryIE()
+{
+ m_primary = m_curString;
+}
+
+void IndexEntryHandler::startSecondaryIE(const QXmlAttributes& /*attrib*/)
+{
+ m_curString="";
+}
+
+void IndexEntryHandler::endSecondaryIE()
+{
+ m_secondary = m_curString;
+}
+
+//----------------------------------------------------------------------
+// EntryHandler
+//----------------------------------------------------------------------
+
+EntryHandler::EntryHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("entry",this,&EntryHandler::endEntry);
+ addStartHandler("para",this,&EntryHandler::startParagraph);
+}
+
+EntryHandler::~EntryHandler()
+{
+}
+
+void EntryHandler::startEntry(const QXmlAttributes&)
+{
+ m_parent->setDelegate(this);
+}
+
+void EntryHandler::endEntry()
+{
+ m_parent->setDelegate(0);
+}
+
+void EntryHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *ph = new ParagraphHandler(this);
+ ph->startParagraph(attrib);
+ m_children.append(ph);
+}
+
+IDocIterator *EntryHandler::contents() const
+{
+ return new EntryIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// RowHandler
+//----------------------------------------------------------------------
+
+RowHandler::RowHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("row",this,&RowHandler::endRow);
+ addStartHandler("entry",this,&RowHandler::startEntry);
+}
+
+RowHandler::~RowHandler()
+{
+}
+
+void RowHandler::startRow(const QXmlAttributes&)
+{
+ m_parent->setDelegate(this);
+}
+
+void RowHandler::endRow()
+{
+ m_parent->setDelegate(0);
+}
+
+void RowHandler::startEntry(const QXmlAttributes& attrib)
+{
+ EntryHandler *eh = new EntryHandler(this);
+ eh->startEntry(attrib);
+ m_children.append(eh);
+}
+
+IDocIterator *RowHandler::entries() const
+{
+ return new RowIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// TableHandler
+//----------------------------------------------------------------------
+
+TableHandler::TableHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+ addEndHandler("table",this,&TableHandler::endTable);
+ addStartHandler("row",this,&TableHandler::startRow);
+ addStartHandler("caption",this,&TableHandler::startCaption);
+ addEndHandler("caption",this,&TableHandler::endCaption);
+}
+
+TableHandler::~TableHandler()
+{
+}
+
+void TableHandler::startTable(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_numColumns = attrib.value("cols").toInt();
+ debug(2,"table cols=%d\n",m_numColumns);
+}
+
+void TableHandler::endTable()
+{
+ m_parent->setDelegate(0);
+}
+
+void TableHandler::startRow(const QXmlAttributes& attrib)
+{
+ RowHandler *rh = new RowHandler(this);
+ rh->startRow(attrib);
+ m_children.append(rh);
+}
+
+void TableHandler::startCaption(const QXmlAttributes& /*attrib*/)
+{
+ m_curString="";
+}
+
+void TableHandler::endCaption()
+{
+ m_caption = m_curString;
+}
+
+IDocIterator *TableHandler::rows() const
+{
+ return new TableIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// CopyHandler
+//----------------------------------------------------------------------
+
+CopyHandler::CopyHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+
+ addEndHandler("copydoc",this,&CopyHandler::endCopy);
+
+ addStartHandler("para",this,&CopyHandler::startParagraph);
+}
+
+CopyHandler::~CopyHandler()
+{
+}
+
+void CopyHandler::startCopy(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start copy handler\n");
+}
+
+void CopyHandler::endCopy()
+{
+ debug(2,"end copy handler\n");
+ m_parent->setDelegate(0);
+}
+
+void CopyHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *parHandler = new ParagraphHandler(this);
+ parHandler->startParagraph(attrib);
+ m_children.append(parHandler);
+}
+
+IDocIterator *CopyHandler::contents() const
+{
+ return new CopyIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// VerbatimHandler
+//----------------------------------------------------------------------
+
+VerbatimHandler::VerbatimHandler(IBaseHandler *parent)
+ : m_parent(parent), m_type(IDocVerbatim::Invalid)
+{
+ addEndHandler("verbatim",this,&VerbatimHandler::endVerbatim);
+ addEndHandler("latexonly",this,&VerbatimHandler::endVerbatim);
+ addEndHandler("htmlonly",this,&VerbatimHandler::endVerbatim);
+}
+
+VerbatimHandler::~VerbatimHandler()
+{
+}
+
+void VerbatimHandler::startVerbatim(const QXmlAttributes&,Types type)
+{
+ m_type = type;
+ m_parent->setDelegate(this);
+ m_curString="";
+}
+
+void VerbatimHandler::endVerbatim()
+{
+ m_text = m_curString;
+ m_parent->setDelegate(0);
+}
+
+
+//----------------------------------------------------------------------
+// SymbolHandler
+//----------------------------------------------------------------------
+
+SymbolHandler::SymbolHandler(IBaseHandler *parent,Types type)
+ : m_parent(parent), m_letter('\0'), m_type(type)
+{
+ addEndHandler("symbol");
+ switch (type)
+ {
+ case IDocSymbol::Invalid: m_typeString="invalid"; break;
+ case IDocSymbol::Umlaut: m_typeString="umlaut"; break;
+ case IDocSymbol::Acute: m_typeString="acute"; break;
+ case IDocSymbol::Grave: m_typeString="grave"; break;
+ case IDocSymbol::Circ: m_typeString="circ"; break;
+ case IDocSymbol::Tilde: m_typeString="tilde"; break;
+ case IDocSymbol::Szlig: m_typeString="szlig"; break;
+ case IDocSymbol::Cedil: m_typeString="cedil"; break;
+ case IDocSymbol::Ring: m_typeString="ring"; break;
+ case IDocSymbol::Nbsp: m_typeString="nbsp"; break;
+ case IDocSymbol::Copy: m_typeString="copy"; break;
+ }
+}
+
+SymbolHandler::~SymbolHandler()
+{
+}
+
+void SymbolHandler::startSymbol(const QXmlAttributes& attrib)
+{
+ QString ls = attrib.value("char");
+ if (!ls.isEmpty()) m_letter = ls.latin1()[0];
+}
+
+//----------------------------------------------------------------------
+// ParagraphHandler
+//----------------------------------------------------------------------
+
+ParagraphHandler::ParagraphHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+
+ m_markupHandler = new MarkupHandler(m_children,m_curString);
+
+ // preformatted
+ setFallBackHandler(m_markupHandler);
+
+ addEndHandler("para",this,&ParagraphHandler::endParagraph);
+
+ addStartHandler("linebreak",this,&ParagraphHandler::startLineBreak);
+ addStartHandler("hruler",this,&ParagraphHandler::startHRuler);
+ addStartHandler("programlisting",this,&ParagraphHandler::startProgramListing);
+ addStartHandler("verbatim",this,&ParagraphHandler::startVerbatim);
+ addStartHandler("indexentry",this,&ParagraphHandler::startIndexEntry);
+ addStartHandler("orderedlist",this,&ParagraphHandler::startOrderedList);
+ addStartHandler("itemizedlist",this,&ParagraphHandler::startItemizedList);
+ addStartHandler("simplesect",this,&ParagraphHandler::startSimpleSect);
+ // TODO: title
+ addStartHandler("variablelist",this,&ParagraphHandler::startVariableList);
+ addStartHandler("table",this,&ParagraphHandler::startTable);
+ // TODO: heading
+ addStartHandler("image",this,&ParagraphHandler::startImage);
+ addStartHandler("dotfile",this,&ParagraphHandler::startDotFile);
+ addStartHandler("toclist",this,&ParagraphHandler::startTocList);
+ // TODO: language???
+ addStartHandler("parameterlist",this,&ParagraphHandler::startParameterList);
+ // TODO: xrefsect
+ addStartHandler("copydoc",this,&ParagraphHandler::startCopyDoc);
+
+ addStartHandler("ref",this,&ParagraphHandler::startRef);
+ addStartHandler("ulink",this,&ParagraphHandler::startULink);
+ addStartHandler("email",this,&ParagraphHandler::startEMail);
+ addStartHandler("link",this,&ParagraphHandler::startLink);
+ addStartHandler("formula",this,&ParagraphHandler::startFormula);
+ addStartHandler("latexonly",this,&ParagraphHandler::startHtmlOnly);
+ addStartHandler("htmlonly",this,&ParagraphHandler::startLatexOnly);
+ addStartHandler("umlaut",this,&ParagraphHandler::startUmlaut);
+ addStartHandler("acute",this,&ParagraphHandler::startAcute);
+ addStartHandler("grave",this,&ParagraphHandler::startGrave);
+ addStartHandler("circ",this,&ParagraphHandler::startCirc);
+ addStartHandler("tilde",this,&ParagraphHandler::startTilde);
+ addStartHandler("szlig",this,&ParagraphHandler::startSzlig);
+ addStartHandler("cedil",this,&ParagraphHandler::startCedil);
+ addStartHandler("ring",this,&ParagraphHandler::startRing);
+ addStartHandler("nbsp",this,&ParagraphHandler::startNbsp);
+ addStartHandler("copy",this,&ParagraphHandler::startCopy);
+ addStartHandler("anchor",this,&ParagraphHandler::startAnchor);
+}
+
+ParagraphHandler::~ParagraphHandler()
+{
+ delete m_markupHandler;
+}
+
+void ParagraphHandler::startParagraph(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"para\n");
+}
+
+void ParagraphHandler::endParagraph()
+{
+ addTextNode();
+ debug(2,"end para\n");
+ m_parent->setDelegate(0);
+}
+
+void ParagraphHandler::startItemizedList(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ ItemizedListHandler *listHandler = new ItemizedListHandler(this);
+ listHandler->startItemizedList(attrib);
+ m_children.append(listHandler);
+}
+
+void ParagraphHandler::startOrderedList(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ OrderedListHandler *listHandler = new OrderedListHandler(this);
+ listHandler->startOrderedList(attrib);
+ m_children.append(listHandler);
+}
+
+void ParagraphHandler::startParameterList(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ ParameterListHandler *listHandler = new ParameterListHandler(this);
+ listHandler->startParameterList(attrib);
+ m_children.append(listHandler);
+}
+
+void ParagraphHandler::startSimpleSect(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SimpleSectHandler *sectHandler = new SimpleSectHandler(this);
+ sectHandler->startSimpleSect(attrib);
+ m_children.append(sectHandler);
+}
+
+void ParagraphHandler::startRef(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ RefHandler *ref = new RefHandler(this);
+ ref->startRef(attrib);
+ m_children.append(ref);
+}
+
+void ParagraphHandler::startVariableList(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ VariableListHandler *vl = new VariableListHandler(this);
+ vl->startVariableList(attrib);
+ m_children.append(vl);
+}
+
+void ParagraphHandler::startHRuler(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ HRulerHandler *hr = new HRulerHandler(this);
+ hr->startHRuler(attrib);
+ m_children.append(hr);
+}
+
+void ParagraphHandler::startLineBreak(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ LineBreakHandler *lb = new LineBreakHandler(this);
+ lb->startLineBreak(attrib);
+ m_children.append(lb);
+}
+
+void ParagraphHandler::startULink(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ ULinkHandler *uh = new ULinkHandler(this);
+ uh->startULink(attrib);
+ m_children.append(uh);
+}
+
+void ParagraphHandler::startEMail(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ EMailHandler *eh = new EMailHandler(this);
+ eh->startEMail(attrib);
+ m_children.append(eh);
+}
+
+void ParagraphHandler::startLink(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ LinkHandler *lh = new LinkHandler(this);
+ lh->startLink(attrib);
+ m_children.append(lh);
+}
+
+void ParagraphHandler::startProgramListing(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ ProgramListingHandler *pl = new ProgramListingHandler(this);
+ pl->startProgramListing(attrib);
+ m_children.append(pl);
+}
+
+void ParagraphHandler::startFormula(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ FormulaHandler *fh = new FormulaHandler(this);
+ fh->startFormula(attrib);
+ m_children.append(fh);
+}
+
+void ParagraphHandler::startImage(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ ImageHandler *ih = new ImageHandler(this);
+ ih->startImage(attrib);
+ m_children.append(ih);
+}
+
+void ParagraphHandler::startDotFile(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ DotFileHandler *df = new DotFileHandler(this);
+ df->startDotFile(attrib);
+ m_children.append(df);
+}
+
+void ParagraphHandler::startIndexEntry(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ IndexEntryHandler *df = new IndexEntryHandler(this);
+ df->startIndexEntry(attrib);
+ m_children.append(df);
+}
+
+void ParagraphHandler::startTable(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ TableHandler *th = new TableHandler(this);
+ th->startTable(attrib);
+ m_children.append(th);
+}
+
+void ParagraphHandler::startVerbatim(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ VerbatimHandler *vh = new VerbatimHandler(this);
+ vh->startVerbatim(attrib,IDocVerbatim::Verbatim);
+ m_children.append(vh);
+}
+
+void ParagraphHandler::startHtmlOnly(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ VerbatimHandler *vh = new VerbatimHandler(this);
+ vh->startVerbatim(attrib,IDocVerbatim::HtmlOnly);
+ m_children.append(vh);
+}
+
+void ParagraphHandler::startLatexOnly(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ VerbatimHandler *vh = new VerbatimHandler(this);
+ vh->startVerbatim(attrib,IDocVerbatim::LatexOnly);
+ m_children.append(vh);
+}
+
+void ParagraphHandler::startUmlaut(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Umlaut);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startAcute(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Acute);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startGrave(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Grave);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startCirc(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Circ);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startTilde(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Tilde);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startSzlig(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Szlig);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startCedil(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Cedil);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startRing(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Ring);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startNbsp(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Nbsp);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startCopy(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ SymbolHandler *sh = new SymbolHandler(this,IDocSymbol::Copy);
+ sh->startSymbol(attrib);
+ m_children.append(sh);
+}
+
+void ParagraphHandler::startAnchor(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ AnchorHandler *ah = new AnchorHandler(this);
+ ah->startAnchor(attrib);
+ m_children.append(ah);
+}
+
+void ParagraphHandler::startCopyDoc(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ CopyHandler *ch = new CopyHandler(this);
+ ch->startCopy(attrib);
+ m_children.append(ch);
+}
+
+void ParagraphHandler::startTocList(const QXmlAttributes& attrib)
+{
+ addTextNode();
+ TocListHandler *th = new TocListHandler(this);
+ th->startTocList(attrib);
+ m_children.append(th);
+}
+
+void ParagraphHandler::addTextNode()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(
+ new TextNode(
+ m_curString,
+ m_markupHandler->markup(),
+ m_markupHandler->headingLevel()
+ )
+ );
+ debug(2,"addTextNode() text=\"%s\" markup=%x headingLevel=%d\n",
+ m_curString.data(),m_markupHandler->markup(),m_markupHandler->headingLevel());
+ m_curString="";
+ }
+}
+
+IDocIterator *ParagraphHandler::contents() const
+{
+ return new ParagraphIterator(*this);
+}
+
+//----------------------------------------------------------------------
+// DocSectionHandler
+//----------------------------------------------------------------------
+
+DocSectionHandler::DocSectionHandler(IBaseHandler *parent,int level)
+ : m_parent(parent), m_internal(0), m_level(level), m_title(0)
+{
+ QString sectionKey;
+ m_paragraphs.setAutoDelete(TRUE);
+ m_subsections.setAutoDelete(TRUE);
+ addStartHandler("title",this,&DocSectionHandler::startTitle);
+ addStartHandler("para",this,&DocSectionHandler::startParagraph);
+ if (level<6)
+ {
+ sectionKey.sprintf("sect%d",level+1);
+ addStartHandler(sectionKey.utf8(),this,&DocSectionHandler::startSubSection);
+ }
+ addStartHandler("internal",this,&DocSectionHandler::startInternal);
+ sectionKey.sprintf("sect%d",level);
+ addEndHandler(sectionKey.utf8(),this,&DocSectionHandler::endDocSection);
+}
+
+DocSectionHandler::~DocSectionHandler()
+{
+}
+
+void DocSectionHandler::startDocSection(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start docsection\n");
+ m_id = attrib.value("id");
+}
+
+void DocSectionHandler::endDocSection()
+{
+ m_parent->setDelegate(0);
+ debug(2,"End docsection\n");
+}
+
+void DocSectionHandler::startSubSection(const QXmlAttributes& attrib)
+{
+ DocSectionHandler *secHandler = new DocSectionHandler(this,m_level+1);
+ secHandler->startDocSection(attrib);
+ m_subsections.append(secHandler);
+}
+
+void DocSectionHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *parHandler = new ParagraphHandler(this);
+ parHandler->startParagraph(attrib);
+ m_paragraphs.append(parHandler);
+}
+
+void DocSectionHandler::startInternal(const QXmlAttributes& attrib)
+{
+ m_internal = new DocInternalHandler(this,m_level);
+ m_internal->startInternal(attrib);
+}
+
+void DocSectionHandler::startTitle(const QXmlAttributes& attrib)
+{
+ m_title = new TitleHandler(this);
+ m_title->startTitle(attrib);
+}
+
+IDocIterator *DocSectionHandler::paragraphs() const
+{
+ return new DocSectionParaIterator(*this);
+}
+
+IDocIterator *DocSectionHandler::subSections() const
+{
+ return new DocSectionSubIterator(*this);
+}
+
+IDocInternal *DocSectionHandler::internal() const
+{
+ return m_internal;
+}
+
+//----------------------------------------------------------------------
+// DocInternal
+//----------------------------------------------------------------------
+
+DocInternalHandler::DocInternalHandler(IBaseHandler *parent,int level)
+ : m_parent(parent), m_level(level)
+{
+ m_paragraphs.setAutoDelete(TRUE);
+ m_subsections.setAutoDelete(TRUE);
+ addStartHandler("para",this,&DocInternalHandler::startParagraph);
+ QString sectionKey;
+ sectionKey.sprintf("sect%d",level+1);
+ addStartHandler(sectionKey.utf8(),this,&DocInternalHandler::startSubSection);
+ addEndHandler("internal",this,&DocInternalHandler::endInternal);
+}
+
+DocInternalHandler::~DocInternalHandler()
+{
+}
+
+void DocInternalHandler::startInternal(const QXmlAttributes&)
+{
+ m_parent->setDelegate(this);
+ debug(2,"Start internal\n");
+}
+
+void DocInternalHandler::endInternal()
+{
+ m_parent->setDelegate(0);
+ debug(2,"End internal\n");
+}
+
+void DocInternalHandler::startSubSection(const QXmlAttributes& attrib)
+{
+ DocSectionHandler *secHandler = new DocSectionHandler(this,m_level+1);
+ secHandler->startDocSection(attrib);
+ m_subsections.append(secHandler);
+}
+
+void DocInternalHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *parHandler = new ParagraphHandler(this);
+ parHandler->startParagraph(attrib);
+ m_paragraphs.append(parHandler);
+}
+
+IDocIterator *DocInternalHandler::paragraphs() const
+{
+ return new DocInternalParaIterator(*this);
+}
+
+IDocIterator *DocInternalHandler::subSections() const
+{
+ return new DocInternalSubIterator(*this);
+}
+
+
+//----------------------------------------------------------------------
+// DocHandler
+//----------------------------------------------------------------------
+
+DocHandler::DocHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ m_children.setAutoDelete(TRUE);
+
+ addEndHandler("briefdescription",this,&DocHandler::endDoc);
+ addEndHandler("detaileddescription",this,&DocHandler::endDoc);
+ addEndHandler("inbodydescription",this,&DocHandler::endDoc);
+ //addEndHandler("internal"); // TODO: implement this as a section
+ addStartHandler("internal",this,&DocHandler::startInternal);
+
+ addStartHandler("para",this,&DocHandler::startParagraph);
+ addStartHandler("sect1",this,&DocHandler::startSect1);
+ addStartHandler("title",this,&DocHandler::startTitle);
+ //addStartHandler("internal");
+}
+
+DocHandler::~DocHandler()
+{
+}
+
+void DocHandler::startDoc(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"start dochandler\n");
+}
+
+void DocHandler::endDoc()
+{
+ debug(2,"end dochandler\n");
+ m_parent->setDelegate(0);
+}
+
+void DocHandler::startParagraph(const QXmlAttributes& attrib)
+{
+ ParagraphHandler *parHandler = new ParagraphHandler(this);
+ parHandler->startParagraph(attrib);
+ m_children.append(parHandler);
+}
+
+void DocHandler::startSect1(const QXmlAttributes& attrib)
+{
+ DocSectionHandler *secHandler = new DocSectionHandler(this,1);
+ secHandler->startDocSection(attrib);
+ m_children.append(secHandler);
+}
+
+void DocHandler::startTitle(const QXmlAttributes& attrib)
+{
+ TitleHandler *titleHandler = new TitleHandler(this);
+ titleHandler->startTitle(attrib);
+ m_children.append(titleHandler);
+}
+
+void DocHandler::startInternal(const QXmlAttributes& attrib)
+{
+ m_internal = new DocInternalHandler(this,1);
+ m_internal->startInternal(attrib);
+}
+
+IDocIterator *DocHandler::contents() const
+{
+ return new DocIterator(*this);
+}
+
+IDocInternal *DocHandler::internal() const
+{
+ return m_internal;
+}
+
diff --git a/addon/doxmlparser/src/dochandler.h b/addon/doxmlparser/src/dochandler.h
new file mode 100644
index 0000000..6bc2bd9
--- /dev/null
+++ b/addon/doxmlparser/src/dochandler.h
@@ -0,0 +1,1352 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DOCHANDLER_H
+#define _DOCHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+
+#include <doxmlintf.h>
+#include "stringimpl.h"
+#include "basehandler.h"
+#include "baseiterator.h"
+
+class ParagraphHandler;
+class DocInternalHandler;
+class LinkedTextImpl;
+class LinkedTextHandler;
+
+//-----------------------------------------------------------------------------
+
+class DocImpl : public IDoc { public: virtual ~DocImpl() {} };
+
+#define DEFINE_CLS_IMPL(cls) \
+ class cls##Impl : public I##cls, public DocImpl { public: virtual ~cls##Impl() {} }
+
+DEFINE_CLS_IMPL(DocMarkup);
+DEFINE_CLS_IMPL(DocPara);
+DEFINE_CLS_IMPL(DocText);
+DEFINE_CLS_IMPL(DocMarkupModifier);
+DEFINE_CLS_IMPL(DocItemizedList);
+DEFINE_CLS_IMPL(DocOrderedList);
+DEFINE_CLS_IMPL(DocListItem);
+DEFINE_CLS_IMPL(DocParameterList);
+DEFINE_CLS_IMPL(DocParameterItem);
+DEFINE_CLS_IMPL(DocParameter);
+DEFINE_CLS_IMPL(DocTitle);
+DEFINE_CLS_IMPL(DocSimpleSect);
+DEFINE_CLS_IMPL(DocRef);
+DEFINE_CLS_IMPL(DocVariableList);
+DEFINE_CLS_IMPL(DocVariableListEntry);
+DEFINE_CLS_IMPL(DocHRuler);
+DEFINE_CLS_IMPL(DocLineBreak);
+DEFINE_CLS_IMPL(DocULink);
+DEFINE_CLS_IMPL(DocEMail);
+DEFINE_CLS_IMPL(DocLink);
+DEFINE_CLS_IMPL(DocProgramListing);
+DEFINE_CLS_IMPL(DocCodeLine);
+DEFINE_CLS_IMPL(DocHighlight);
+DEFINE_CLS_IMPL(DocFormula);
+DEFINE_CLS_IMPL(DocImage);
+DEFINE_CLS_IMPL(DocDotFile);
+DEFINE_CLS_IMPL(DocIndexEntry);
+DEFINE_CLS_IMPL(DocTable);
+DEFINE_CLS_IMPL(DocRow);
+DEFINE_CLS_IMPL(DocEntry);
+DEFINE_CLS_IMPL(DocSection);
+DEFINE_CLS_IMPL(DocVerbatim);
+DEFINE_CLS_IMPL(DocCopy);
+DEFINE_CLS_IMPL(DocTocList);
+DEFINE_CLS_IMPL(DocTocItem);
+DEFINE_CLS_IMPL(DocAnchor);
+DEFINE_CLS_IMPL(DocSymbol);
+DEFINE_CLS_IMPL(DocInternal);
+DEFINE_CLS_IMPL(DocRoot);
+
+//-----------------------------------------------------------------------------
+
+
+/*! \brief Node representing a piece of text.
+ *
+ */
+class TextNode : public DocTextImpl
+{
+ public:
+ TextNode(const QString &t,int markup,int level)
+ : m_text(t), m_markup(markup), m_headingLevel(level) {}
+ virtual ~TextNode() {}
+
+ // IDocText
+ virtual Kind kind() const { return DocImpl::Text; }
+ virtual const IString *text() const { return &m_text; }
+ virtual int markup() const { return m_markup; }
+ virtual int headingLevel() const { return m_headingLevel; }
+
+ private:
+ StringImpl m_text;
+ int m_markup;
+ int m_headingLevel;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a change in the markup style.
+ *
+ */
+class MarkupModifierNode : public DocMarkupModifierImpl
+{
+ public:
+ MarkupModifierNode(int markup,bool enabled,int level=0)
+ : m_markup(markup), m_enabled(enabled), m_headingLevel(level) {}
+ virtual ~MarkupModifierNode() {}
+
+ // IDocMarkupModifier
+ virtual Kind kind() const { return DocImpl::MarkupModifier; }
+ virtual bool enabled() const { return m_enabled; }
+ virtual int markup() const { return m_markup; }
+ virtual int headingLevel() const { return m_headingLevel; }
+
+ private:
+ int m_markup;
+ bool m_enabled;
+ int m_headingLevel;
+};
+
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Handles markup commands in the XML input.
+ *
+ */
+class MarkupHandler : public BaseFallBackHandler<MarkupHandler>
+{
+ public:
+ MarkupHandler(QList<DocImpl> &children,QString &curString);
+ virtual ~MarkupHandler();
+ int markup() const { return m_curMarkup; }
+ int headingLevel() const { return m_headingLevel; }
+
+ virtual void startBold(const QXmlAttributes &attrib);
+ virtual void endBold();
+ virtual void startEmphasis(const QXmlAttributes &attrib);
+ virtual void endEmphasis();
+ virtual void startComputerOutput(const QXmlAttributes &attrib);
+ virtual void endComputerOutput();
+ virtual void startCenter(const QXmlAttributes &attrib);
+ virtual void endCenter();
+ virtual void startSmallFont(const QXmlAttributes &attrib);
+ virtual void endSmallFont();
+ virtual void startSubscript(const QXmlAttributes &attrib);
+ virtual void endSubscript();
+ virtual void startSuperscript(const QXmlAttributes &attrib);
+ virtual void endSuperscript();
+ virtual void startPreformatted(const QXmlAttributes &attrib);
+ virtual void endPreformatted();
+ virtual void startHeading1(const QXmlAttributes &attrib);
+ virtual void endHeading1();
+ virtual void startHeading2(const QXmlAttributes &attrib);
+ virtual void endHeading2();
+ virtual void startHeading3(const QXmlAttributes &attrib);
+ virtual void endHeading3();
+ virtual void startHeading4(const QXmlAttributes &attrib);
+ virtual void endHeading4();
+ virtual void startHeading5(const QXmlAttributes &attrib);
+ virtual void endHeading5();
+ virtual void startHeading6(const QXmlAttributes &attrib);
+ virtual void endHeading6();
+
+
+ private:
+ void addTextNode();
+
+ QList<DocImpl> &m_children;
+ QString &m_curString;
+ int m_curMarkup;
+ int m_headingLevel;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a paragraph of text and commands.
+ *
+ */
+// children: itemizedlist, orderedlist, parameterlist, simplesect, ref,
+// variablelist, hruler, linebreak, ulink, email, link
+// programlisting, formula, image, dotfile, indexentry,
+// table
+//
+// children handled by MarkupHandler:
+// bold, computeroutput, emphasis, center,
+// small, subscript, superscript.
+//
+class ParagraphHandler : public DocParaImpl,
+ public BaseHandler<ParagraphHandler>
+{
+ friend class ParagraphIterator;
+
+ public:
+ virtual void startParagraph(const QXmlAttributes& attrib);
+ virtual void endParagraph();
+ virtual void startItemizedList(const QXmlAttributes& attrib);
+ virtual void startOrderedList(const QXmlAttributes& attrib);
+ virtual void startParameterList(const QXmlAttributes& attrib);
+ virtual void startSimpleSect(const QXmlAttributes& attrib);
+ virtual void startRef(const QXmlAttributes& attrib);
+ virtual void startVariableList(const QXmlAttributes& attrib);
+ virtual void startHRuler(const QXmlAttributes& attrib);
+ virtual void startLineBreak(const QXmlAttributes& attrib);
+ virtual void startULink(const QXmlAttributes& attrib);
+ virtual void startEMail(const QXmlAttributes& attrib);
+ virtual void startLink(const QXmlAttributes& attrib);
+ virtual void startProgramListing(const QXmlAttributes& attrib);
+ virtual void startFormula(const QXmlAttributes& attrib);
+ virtual void startImage(const QXmlAttributes& attrib);
+ virtual void startDotFile(const QXmlAttributes& attrib);
+ virtual void startIndexEntry(const QXmlAttributes& attrib);
+ virtual void startTable(const QXmlAttributes& attrib);
+ virtual void startVerbatim(const QXmlAttributes& attrib);
+ virtual void startHtmlOnly(const QXmlAttributes& attrib);
+ virtual void startLatexOnly(const QXmlAttributes& attrib);
+ virtual void startUmlaut(const QXmlAttributes& attrib);
+ virtual void startAcute(const QXmlAttributes& attrib);
+ virtual void startGrave(const QXmlAttributes& attrib);
+ virtual void startCirc(const QXmlAttributes& attrib);
+ virtual void startTilde(const QXmlAttributes& attrib);
+ virtual void startSzlig(const QXmlAttributes& attrib);
+ virtual void startCedil(const QXmlAttributes& attrib);
+ virtual void startRing(const QXmlAttributes& attrib);
+ virtual void startNbsp(const QXmlAttributes& attrib);
+ virtual void startCopy(const QXmlAttributes& attrib);
+ virtual void startAnchor(const QXmlAttributes& attrib);
+ virtual void startCopyDoc(const QXmlAttributes& attrib);
+ virtual void startTocList(const QXmlAttributes& attrib);
+
+ ParagraphHandler(IBaseHandler *parent);
+ virtual ~ParagraphHandler();
+
+ // IDocPara
+ virtual Kind kind() const { return DocImpl::Para; }
+ virtual IDocIterator *contents() const;
+
+ private:
+ void addTextNode();
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+ MarkupHandler *m_markupHandler;
+};
+
+class ParagraphIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ ParagraphIterator(const ParagraphHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a list item.
+ *
+ */
+class ListItemHandler : public DocListItemImpl, public BaseHandler<ListItemHandler>
+{
+ friend class ListItemIterator;
+ public:
+ ListItemHandler(IBaseHandler *parent);
+ virtual ~ListItemHandler();
+ virtual void startListItem(const QXmlAttributes& attrib);
+ virtual void endListItem();
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocItem
+ virtual Kind kind() const { return DocImpl::ListItem; }
+ virtual IDocIterator *contents() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class ListItemIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ ListItemIterator(const ListItemHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing list of items.
+ *
+ */
+class OrderedListHandler : public DocOrderedListImpl, public BaseHandler<OrderedListHandler>
+{
+ friend class OrderedListIterator;
+ public:
+ OrderedListHandler(IBaseHandler *parent);
+ virtual ~OrderedListHandler();
+ virtual void startOrderedList(const QXmlAttributes& attrib);
+ virtual void endOrderedList();
+ virtual void startOrderedListItem(const QXmlAttributes& attrib);
+
+ // IDocOrderedList
+ virtual Kind kind() const { return DocImpl::OrderedList; }
+ virtual IDocIterator *elements() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class OrderedListIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ OrderedListIterator(const OrderedListHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing table of contents list.
+ *
+ */
+class TocListHandler : public DocTocListImpl, public BaseHandler<TocListHandler>
+{
+ friend class TocListIterator;
+ public:
+ TocListHandler(IBaseHandler *parent);
+ virtual ~TocListHandler();
+ virtual void startTocList(const QXmlAttributes& attrib);
+ virtual void endTocList();
+ virtual void startTocItem(const QXmlAttributes& attrib);
+
+ // IDocTocList
+ virtual Kind kind() const { return DocImpl::TocList; }
+ virtual IDocIterator *elements() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class TocListIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ TocListIterator(const TocListHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a table of contents item.
+ *
+ */
+class TocItemHandler : public DocTocItemImpl, public BaseHandler<TocItemHandler>
+{
+ friend class TocItemIterator;
+ public:
+ TocItemHandler(IBaseHandler *parent);
+ virtual ~TocItemHandler();
+ virtual void startTocItem(const QXmlAttributes& attrib);
+ virtual void endTocItem();
+
+ // IDocItem
+ virtual Kind kind() const { return DocImpl::TocItem; }
+ virtual const IString *id() const { return &m_id; }
+ virtual const IString *title() const { return &m_title; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_id;
+ StringImpl m_title;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing list of items.
+ *
+ */
+class ItemizedListHandler : public DocItemizedListImpl, public BaseHandler<ItemizedListHandler>
+{
+ friend class ItemizedListIterator;
+ public:
+ ItemizedListHandler(IBaseHandler *parent);
+ virtual ~ItemizedListHandler();
+ virtual void startItemizedList(const QXmlAttributes& attrib);
+ virtual void endItemizedList();
+ virtual void startItemizedListItem(const QXmlAttributes& attrib);
+
+ // IDocItemizedList
+ virtual Kind kind() const { return DocImpl::ItemizedList; }
+ virtual IDocIterator *elements() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class ItemizedListIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ ItemizedListIterator(const ItemizedListHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+
+//-----------------------------------------------------------------------------
+/*! \brief Node representing a parameter.
+ *
+ */
+class ParameterHandler : public DocParameterImpl,
+ public BaseHandler<ParameterHandler>
+{
+ public:
+ ParameterHandler(IBaseHandler *parent);
+ virtual ~ParameterHandler();
+ virtual void startParameterName(const QXmlAttributes& attrib);
+ virtual void endParameterName();
+
+ // IDocParameter
+ virtual Kind kind() const { return DocImpl::Parameter; }
+ virtual const IString *name() const { return &m_name; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_name;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a list of param names with a single description.
+ *
+ */
+class ParameterItemHandler : public DocParameterItemImpl,
+ public BaseHandler<ParameterItemHandler>
+{
+ friend class ParameterItemIterator;
+ public:
+ ParameterItemHandler(IBaseHandler *parent);
+ virtual ~ParameterItemHandler();
+ virtual void startParameterItem(const QXmlAttributes& attrib);
+ virtual void endParameterItem();
+ virtual void startParameterName(const QXmlAttributes& attrib);
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocParameterItem
+ virtual Kind kind() const { return DocImpl::ParameterItem; }
+ virtual IDocIterator *paramNames() const;
+ virtual IDocPara *description() const { return m_description; }
+
+ private:
+ IBaseHandler *m_parent;
+ QList<ParameterHandler> m_parameters;
+ ParagraphHandler *m_description;
+};
+
+class ParameterItemIterator : public BaseIteratorVia<IDocIterator,IDoc,ParameterHandler,DocImpl>
+{
+ public:
+ ParameterItemIterator(const ParameterItemHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,ParameterHandler,DocImpl>(handler.m_parameters) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a parameter section.
+ *
+ */
+class ParameterListHandler : public DocParameterListImpl,
+ public BaseHandler<ParameterListHandler>
+{
+ friend class ParameterListIterator;
+ public:
+ ParameterListHandler(IBaseHandler *parent);
+ virtual ~ParameterListHandler();
+ virtual void startParameterList(const QXmlAttributes& attrib);
+ virtual void endParameterList();
+ virtual void startParameterItem(const QXmlAttributes& attrib);
+
+ // IDocParameterList
+ virtual Kind kind() const { return DocImpl::ParameterList; }
+ virtual Types sectType() const { return m_type; }
+ virtual IDocIterator *params() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<ParameterItemHandler> m_paramItems;
+ Types m_type;
+};
+
+class ParameterListIterator : public BaseIteratorVia<IDocIterator,IDoc,ParameterItemHandler,DocImpl>
+{
+ public:
+ ParameterListIterator(const ParameterListHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,ParameterItemHandler,DocImpl>(handler.m_paramItems) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a horizontal ruler
+ *
+ */
+class LineBreakHandler : public DocLineBreakImpl, public BaseHandler<LineBreakHandler>
+{
+ public:
+ LineBreakHandler(IBaseHandler *parent);
+ virtual ~LineBreakHandler();
+
+ void startLineBreak(const QXmlAttributes& attrib);
+ void endLineBreak();
+
+ // IDocLineBreak
+ virtual Kind kind() const { return DocImpl::LineBreak; }
+
+ private:
+ IBaseHandler *m_parent;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a link to section
+ *
+ */
+class LinkHandler : public DocLinkImpl, public BaseHandler<LinkHandler>
+{
+ public:
+ LinkHandler(IBaseHandler *parent);
+ virtual ~LinkHandler();
+
+ void startLink(const QXmlAttributes& attrib);
+ void endLink();
+
+ // IDocLink
+ virtual Kind kind() const { return DocImpl::Link; }
+ virtual const IString *refId() const { return &m_ref; }
+ virtual const IString *text() const { return &m_text; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_ref;
+ StringImpl m_text;
+};
+
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a link to an email address
+ *
+ */
+class EMailHandler : public DocEMailImpl, public BaseHandler<EMailHandler>
+{
+ public:
+ EMailHandler(IBaseHandler *parent);
+ virtual ~EMailHandler();
+
+ void startEMail(const QXmlAttributes& attrib);
+ void endEMail();
+
+ // IDocEMail
+ virtual Kind kind() const { return DocImpl::EMail; }
+ virtual const IString *address() const { return &m_address; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_address;
+};
+
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a link to an URL
+ *
+ */
+class ULinkHandler : public DocULinkImpl, public BaseHandler<ULinkHandler>
+{
+ public:
+ ULinkHandler(IBaseHandler *parent);
+ virtual ~ULinkHandler();
+
+ void startULink(const QXmlAttributes& attrib);
+ void endULink();
+
+ // IDocULink
+ virtual Kind kind() const { return DocImpl::ULink; }
+ virtual const IString * url() const { return &m_url; }
+ virtual const IString * text() const { return &m_text; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_url;
+ StringImpl m_text;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a horizontal ruler
+ *
+ */
+class HRulerHandler : public DocHRulerImpl, public BaseHandler<HRulerHandler>
+{
+ public:
+ HRulerHandler(IBaseHandler *parent);
+ virtual ~HRulerHandler();
+
+ void startHRuler(const QXmlAttributes& attrib);
+ void endHRuler();
+
+ // IDocHRuler
+ virtual Kind kind() const { return DocImpl::HRuler; }
+
+ private:
+ IBaseHandler *m_parent;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a reference to another item
+ *
+ */
+class RefHandler : public DocRefImpl, public BaseHandler<RefHandler>
+{
+ public:
+ RefHandler(IBaseHandler *parent);
+ virtual ~RefHandler();
+ void startRef(const QXmlAttributes& attrib);
+ void endRef();
+
+ // IDocRef
+ virtual Kind kind() const { return DocImpl::Ref; }
+ virtual const IString *refId() const { return &m_refId; }
+ virtual TargetKind targetKind() const { return m_targetKind; }
+ virtual const IString *external() const { return &m_extId; }
+ virtual const IString *text() const { return &m_linkText; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_refId;
+ StringImpl m_extId;
+ StringImpl m_linkText;
+ TargetKind m_targetKind;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing the title of a section
+ *
+ */
+// children: text, ref
+// children handled by MarkupHandler:
+// bold, computeroutput, emphasis, center,
+// small, subscript, superscript.
+class TitleHandler : public DocTitleImpl, public BaseHandler<TitleHandler>
+{
+ friend class TitleIterator;
+ public:
+ TitleHandler(IBaseHandler *parent);
+ virtual ~TitleHandler();
+ virtual void startTitle(const QXmlAttributes& attrib);
+ virtual void endTitle();
+ virtual void startRef(const QXmlAttributes& attrib);
+ void addTextNode();
+
+ // IDocTitle
+ virtual Kind kind() const { return DocImpl::Title; }
+ virtual IDocIterator *title() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+ MarkupHandler *m_markupHandler;
+};
+
+class TitleIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ TitleIterator(const TitleHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing a simple section with an unnumbered header.
+ *
+ */
+// children: title, para
+class SimpleSectHandler : public DocSimpleSectImpl,
+ public BaseHandler<SimpleSectHandler>
+{
+ public:
+ SimpleSectHandler(IBaseHandler *parent);
+ virtual ~SimpleSectHandler();
+ virtual void startSimpleSect(const QXmlAttributes& attrib);
+ virtual void endSimpleSect();
+ virtual void startTitle(const QXmlAttributes& attrib);
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocSimpleSect
+ virtual Kind kind() const { return DocImpl::SimpleSect; }
+ virtual Types type() const { return m_type; }
+ virtual const IString *typeString() const { return &m_typeString; }
+ virtual IDocTitle *title() const { return m_title; }
+ virtual IDocPara *description() const { return m_paragraph; }
+
+ private:
+ IBaseHandler *m_parent;
+ ParagraphHandler *m_paragraph;
+ Types m_type;
+ StringImpl m_typeString;
+ TitleHandler *m_title;
+};
+
+//-----------------------------------------------------------------------------
+
+/* \brief Node representing an named item of a VariableList.
+ *
+ */
+class VariableListEntryHandler : public DocVariableListEntryImpl,
+ public BaseHandler<VariableListEntryHandler>
+{
+ public:
+ virtual void startVarListEntry(const QXmlAttributes& attrib);
+ virtual void endVarListEntry();
+ virtual void startListItem(const QXmlAttributes& attrib);
+ virtual void endListItem();
+ virtual void startTerm(const QXmlAttributes& attrib);
+ virtual void endTerm();
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ VariableListEntryHandler(IBaseHandler *parent);
+ virtual ~VariableListEntryHandler();
+
+ // IDocVariableListEntry
+ virtual Kind kind() const { return DocImpl::VariableListEntry; }
+ virtual ILinkedTextIterator *term() const;
+ virtual IDocPara *description() const { return m_description; }
+
+ private:
+ IBaseHandler* m_parent;
+ QList<LinkedTextImpl> m_term;
+ ParagraphHandler* m_description;
+ LinkedTextHandler* m_linkedTextHandler;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a list of named items.
+ *
+ */
+// children: varlistentry, listitem
+class VariableListHandler : public DocVariableListImpl,
+ public BaseHandler<VariableListHandler>
+{
+ friend class VariableListIterator;
+
+ public:
+ virtual void startVariableList(const QXmlAttributes& attrib);
+ virtual void endVariableList();
+ virtual void startVarListEntry(const QXmlAttributes& attrib);
+ virtual void startListItem(const QXmlAttributes& attrib);
+
+ VariableListHandler(IBaseHandler *parent);
+ virtual ~VariableListHandler();
+
+ // IDocVariableList
+ virtual Kind kind() const { return DocImpl::VariableList; }
+ virtual IDocIterator *entries() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<VariableListEntryHandler> m_entries;
+ VariableListEntryHandler *m_curEntry;
+};
+
+class VariableListIterator : public BaseIteratorVia<IDocIterator,IDoc,VariableListEntryHandler,DocImpl>
+{
+ public:
+ VariableListIterator(const VariableListHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,VariableListEntryHandler,DocImpl>(handler.m_entries) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a highlighted text fragment.
+ *
+ */
+// children: ref
+class HighlightHandler : public DocHighlightImpl, public BaseHandler<HighlightHandler>
+{
+ friend class HighlightIterator;
+ public:
+ HighlightHandler(IBaseHandler *parent);
+ virtual ~HighlightHandler();
+ void startHighlight(const QXmlAttributes& attrib);
+ void endHighlight();
+ virtual void startRef(const QXmlAttributes&);
+ virtual void startSpace(const QXmlAttributes&);
+
+ // IDocHighlight
+ virtual Kind kind() const { return DocImpl::Highlight; }
+ virtual HighlightKind highlightKind() const { return m_hl; }
+ virtual IDocIterator *codeElements() const;
+
+ private:
+ void addTextNode();
+
+ IBaseHandler *m_parent;
+ HighlightKind m_hl;
+ QString m_hlString;
+ QList<DocImpl> m_children;
+};
+
+class HighlightIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ HighlightIterator(const HighlightHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a line of code.
+ *
+ */
+// children: linenumber, highlight, anchor, ref
+class CodeLineHandler : public DocCodeLineImpl, public BaseHandler<CodeLineHandler>
+{
+ friend class CodeLineIterator;
+ public:
+
+ virtual void startCodeLine(const QXmlAttributes&);
+ virtual void endCodeLine();
+ virtual void startLineNumber(const QXmlAttributes&);
+ virtual void endLineNumber();
+ virtual void startHighlight(const QXmlAttributes&);
+ virtual void startRef(const QXmlAttributes&);
+
+ CodeLineHandler(IBaseHandler *parent);
+ virtual ~CodeLineHandler();
+
+ // IDocCodeLine
+ virtual Kind kind() const { return DocImpl::CodeLine; }
+ virtual int lineNumber() const { return m_lineNumber; }
+ virtual const IString *refId() const { return &m_refId; }
+ virtual IDocIterator *codeElements() const;
+
+ private:
+ void addTextNode();
+
+ IBaseHandler *m_parent;
+ int m_lineNumber;
+ StringImpl m_refId;
+ QList<DocImpl> m_children;
+};
+
+class CodeLineIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ CodeLineIterator(const CodeLineHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a program listing
+ *
+ */
+// children: codeline, linenumber
+class ProgramListingHandler : public DocProgramListingImpl, public BaseHandler<ProgramListingHandler>
+{
+ friend class ProgramListingIterator;
+ public:
+ virtual void startProgramListing(const QXmlAttributes& attrib);
+ virtual void endProgramListing();
+ virtual void startCodeLine(const QXmlAttributes&);
+ virtual void startLineNumber(const QXmlAttributes&);
+
+ ProgramListingHandler(IBaseHandler *parent);
+ virtual ~ProgramListingHandler();
+
+ // IDocProgramListing
+ virtual Kind kind() const { return DocImpl::ProgramListing; }
+ virtual IDocIterator *codeLines() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<CodeLineHandler> m_children;
+ bool m_hasLineNumber;
+};
+
+//-----------------------------------------------------------------------------
+
+class ProgramListingIterator : public BaseIteratorVia<IDocIterator,IDoc,CodeLineHandler,DocImpl>
+{
+ public:
+ ProgramListingIterator(const ProgramListingHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,CodeLineHandler,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a formula.
+ *
+ */
+// children: -
+class FormulaHandler : public DocFormulaImpl, public BaseHandler<FormulaHandler>
+{
+ public:
+ FormulaHandler(IBaseHandler *parent);
+ virtual ~FormulaHandler();
+ void startFormula(const QXmlAttributes& attrib);
+ void endFormula();
+
+ // IDocFormula
+ virtual Kind kind() const { return DocImpl::Formula; }
+ virtual const IString *id() const { return &m_id; }
+ virtual const IString *text() const { return &m_text; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_id;
+ StringImpl m_text;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an image.
+ *
+ */
+// children: -
+class ImageHandler : public DocImageImpl, public BaseHandler<ImageHandler>
+{
+ public:
+ ImageHandler(IBaseHandler *parent);
+ virtual ~ImageHandler();
+ void startImage(const QXmlAttributes& attrib);
+ void endImage();
+
+ // IDocImage
+ virtual Kind kind() const { return DocImpl::Image; }
+ virtual const IString *name() const { return &m_name; }
+ virtual const IString *caption() const { return &m_caption; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_name;
+ StringImpl m_caption;
+};
+
+
+//-----------------------------------------------------------------------------
+/*! \brief Node representing an anchor.
+ *
+ */
+// children: -
+class AnchorHandler : public DocAnchorImpl, public BaseHandler<AnchorHandler>
+{
+ public:
+ AnchorHandler(IBaseHandler *parent);
+ virtual ~AnchorHandler();
+ void startAnchor(const QXmlAttributes& attrib);
+ void endAnchor();
+
+ // IDocAnchor
+ virtual Kind kind() const { return DocImpl::Anchor; }
+ virtual const IString *id() const { return &m_id; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_id;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a dot file.
+ *
+ */
+// children: -
+class DotFileHandler : public DocDotFileImpl, public BaseHandler<DotFileHandler>
+{
+ public:
+ DotFileHandler(IBaseHandler *parent);
+ virtual ~DotFileHandler();
+ void startDotFile(const QXmlAttributes& attrib);
+ void endDotFile();
+
+ // IDocDotFile
+ virtual Kind kind() const { return DocImpl::DotFile; }
+ virtual const IString *name() const { return &m_name; }
+ virtual const IString *caption() const { return &m_caption; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_name;
+ StringImpl m_caption;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an entry in the index.
+ *
+ */
+// children: -
+class IndexEntryHandler : public DocIndexEntryImpl, public BaseHandler<IndexEntryHandler>
+{
+ public:
+ IndexEntryHandler(IBaseHandler *parent);
+ virtual ~IndexEntryHandler();
+ void startIndexEntry(const QXmlAttributes& attrib);
+ void endIndexEntry();
+ void startPrimaryIE(const QXmlAttributes& attrib);
+ void endPrimaryIE();
+ void startSecondaryIE(const QXmlAttributes& attrib);
+ void endSecondaryIE();
+
+ // IDocIndexEntry
+ virtual Kind kind() const { return DocImpl::IndexEntry; }
+ virtual const IString *primary() const { return &m_primary; }
+ virtual const IString *secondary() const { return &m_secondary; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_primary;
+ StringImpl m_secondary;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an entry in the table entry.
+ *
+ */
+// children: para
+class EntryHandler : public DocEntryImpl, public BaseHandler<EntryHandler>
+{
+ friend class EntryIterator;
+ public:
+ EntryHandler(IBaseHandler *parent);
+ virtual ~EntryHandler();
+ void startEntry(const QXmlAttributes& attrib);
+ void endEntry();
+ void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocEntry
+ virtual Kind kind() const { return DocImpl::Entry; }
+ virtual IDocIterator *contents() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class EntryIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ EntryIterator(const EntryHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an entry in the table row.
+ *
+ */
+// children: entry
+class RowHandler : public DocRowImpl, public BaseHandler<RowHandler>
+{
+ friend class RowIterator;
+ public:
+ RowHandler(IBaseHandler *parent);
+ virtual ~RowHandler();
+ void startRow(const QXmlAttributes& attrib);
+ void endRow();
+ void startEntry(const QXmlAttributes& attrib);
+
+ // IDocRow
+ virtual Kind kind() const { return DocImpl::Row; }
+ virtual IDocIterator *entries() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<EntryHandler> m_children;
+};
+
+class RowIterator : public BaseIteratorVia<IDocIterator,IDoc,EntryHandler,DocImpl>
+{
+ public:
+ RowIterator(const RowHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,EntryHandler,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an entry in the table.
+ *
+ */
+// children: row, caption
+class TableHandler : public DocTableImpl, public BaseHandler<TableHandler>
+{
+ friend class TableIterator;
+ public:
+ TableHandler(IBaseHandler *parent);
+ virtual ~TableHandler();
+ void startTable(const QXmlAttributes& attrib);
+ void endTable();
+ void startRow(const QXmlAttributes& attrib);
+ void startCaption(const QXmlAttributes& attrib);
+ void endCaption();
+
+ // IDocTable
+ virtual Kind kind() const { return DocImpl::Table; }
+ virtual IDocIterator *rows() const;
+ virtual int numColumns() const { return m_numColumns; }
+ virtual const IString *caption() const { return &m_caption; }
+
+ private:
+ IBaseHandler *m_parent;
+ QList<RowHandler> m_children;
+ int m_numColumns;
+ StringImpl m_caption;
+};
+
+class TableIterator : public BaseIteratorVia<IDocIterator,IDoc,RowHandler,DocImpl>
+{
+ public:
+ TableIterator(const TableHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,RowHandler,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a copied piece of documentation.
+ *
+ */
+class CopyHandler : public DocCopyImpl, public BaseHandler<CopyHandler>
+{
+ friend class CopyIterator;
+ public:
+ CopyHandler(IBaseHandler *parent);
+ virtual ~CopyHandler();
+ virtual void startCopy(const QXmlAttributes& attrib);
+ virtual void endCopy();
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocCopy
+ virtual Kind kind() const { return DocImpl::Copy; }
+ virtual IDocIterator *contents() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+};
+
+class CopyIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ CopyIterator(const CopyHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an preformatted section
+ */
+class VerbatimHandler : public DocVerbatimImpl,
+ public BaseHandler<VerbatimHandler>
+{
+ public:
+ VerbatimHandler(IBaseHandler *parent);
+ virtual ~VerbatimHandler();
+ void startVerbatim(const QXmlAttributes& attrib,Types type);
+ void endVerbatim();
+
+ // IDocVerbatim
+ virtual Kind kind() const { return DocImpl::Verbatim; }
+ virtual const IString *text() const { return &m_text; }
+ virtual Types type() const { return m_type; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_text;
+ Types m_type;
+};
+
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing an special symbol.
+ *
+ */
+// children: -
+class SymbolHandler : public DocSymbolImpl, public BaseHandler<SymbolHandler>
+{
+ public:
+ SymbolHandler(IBaseHandler *parent,Types type);
+ virtual ~SymbolHandler();
+ void startSymbol(const QXmlAttributes& attrib);
+ void endSymbol();
+
+ // IDocSymbol
+ virtual Kind kind() const { return DocImpl::Symbol; }
+ virtual Types type() const { return m_type; }
+ virtual const IString *typeString() const { return &m_typeString; }
+ virtual char letter() const { return m_letter; }
+
+ private:
+ IBaseHandler *m_parent;
+ char m_letter;
+ Types m_type;
+ StringImpl m_typeString;
+};
+
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a section.
+ *
+ */
+// children: title, para, sect(n+1)
+class DocSectionHandler : public DocSectionImpl, public BaseHandler<DocSectionHandler>
+{
+ friend class DocSectionParaIterator;
+ friend class DocSectionSubIterator;
+ public:
+ DocSectionHandler(IBaseHandler *parent,int level);
+ virtual ~DocSectionHandler();
+ virtual void startDocSection(const QXmlAttributes& attrib);
+ virtual void endDocSection();
+ virtual void startTitle(const QXmlAttributes& attrib);
+ virtual void startSubSection(const QXmlAttributes& attrib);
+ virtual void startParagraph(const QXmlAttributes& attrib);
+ virtual void startInternal(const QXmlAttributes& attrib);
+
+ // IDocSection
+ virtual Kind kind() const { return DocImpl::Section; }
+ virtual const IString *id() const { return &m_id; }
+ virtual int level() const { return m_level; }
+ virtual IDocTitle *title() const { return m_title; }
+ virtual IDocIterator *paragraphs() const;
+ virtual IDocIterator *subSections() const;
+ virtual IDocInternal *internal() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_paragraphs;
+ QList<DocImpl> m_subsections;
+ DocInternalHandler *m_internal;
+ StringImpl m_id;
+ int m_level;
+ TitleHandler *m_title;
+};
+
+class DocSectionParaIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ DocSectionParaIterator(const DocSectionHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_paragraphs) {}
+};
+
+class DocSectionSubIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ DocSectionSubIterator(const DocSectionHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_subsections) {}
+};
+
+//-----------------------------------------------------------------------------
+
+class DocInternalHandler : public DocInternalImpl, public BaseHandler<DocInternalHandler>
+{
+ public:
+ friend class DocInternalParaIterator;
+ friend class DocInternalSubIterator;
+ DocInternalHandler(IBaseHandler *parent,int level);
+ virtual ~DocInternalHandler();
+ virtual void startInternal(const QXmlAttributes& attrib);
+ virtual void endInternal();
+ virtual void startSubSection(const QXmlAttributes& attrib);
+ virtual void startParagraph(const QXmlAttributes& attrib);
+
+ // IDocInternal
+ virtual Kind kind() const { return DocImpl::Internal; }
+ virtual IDocIterator *paragraphs() const;
+ virtual IDocIterator *subSections() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_paragraphs;
+ QList<DocImpl> m_subsections;
+ int m_level;
+};
+
+class DocInternalParaIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ DocInternalParaIterator(const DocInternalHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_paragraphs) {}
+};
+
+class DocInternalSubIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ DocInternalSubIterator(const DocInternalHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_subsections) {}
+};
+
+
+//-----------------------------------------------------------------------------
+
+/*! \brief Node representing a documentation block.
+ *
+ */
+// children: para, title, sect1, internal
+class DocHandler : public DocRootImpl, public BaseHandler<DocHandler>
+{
+ friend class DocIterator;
+ public:
+ virtual void startDoc(const QXmlAttributes& attrib);
+ virtual void endDoc();
+ virtual void startParagraph(const QXmlAttributes& attrib);
+ virtual void startSect1(const QXmlAttributes& attrib);
+ virtual void startTitle(const QXmlAttributes& attrib);
+ virtual void startInternal(const QXmlAttributes& attrib);
+
+ DocHandler(IBaseHandler *parent);
+ virtual ~DocHandler();
+
+ // IDocRoot
+ virtual Kind kind() const { return DocImpl::Root; }
+ virtual IDocIterator *contents() const;
+ virtual IDocInternal *internal() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<DocImpl> m_children;
+ DocInternalHandler *m_internal;
+};
+
+class DocIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>
+{
+ public:
+ DocIterator(const DocHandler &handler) :
+ BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {}
+};
+
+//-----------------------------------------------------------------------------
+
+void dochandler_init();
+void dochandler_exit();
+
+#endif
diff --git a/addon/doxmlparser/src/doxmlintf.h b/addon/doxmlparser/src/doxmlintf.h
new file mode 100644
index 0000000..ba863d4
--- /dev/null
+++ b/addon/doxmlparser/src/doxmlintf.h
@@ -0,0 +1,1141 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DOXMLINTF_H
+#define _DOXMLINTF_H
+
+/*! \file
+ * \brief The interface to the object model provided by the XML parser
+ * library.
+ *
+ * To start using this library one calls createObjectModel() and then
+ * uses the returned IDoxygen interface to read doxygen generated
+ * XML output and navigate through the information contained in it.
+ *
+ * @see createObjectModel()
+ */
+
+class IMember;
+class IDocIterator;
+class ICompound;
+class ISection;
+class INode;
+class IDocInternal;
+class IDocRoot;
+
+#define VIRTUAL_DESTRUCTOR(x) virtual ~x() {}
+
+/*! \brief Read only interface to a string.
+ */
+class IString
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IString)
+ /*! Returns a latin1 character representation of the string. */
+ virtual const char *latin1() const = 0;
+ /*! Returns a utf8 character representation of the string. */
+ virtual const char *utf8() const = 0;
+ /*! Returns a 16-bit unicode character representation of the character at
+ * position \a index in the string. The first character is at index 0.
+ */
+ virtual unsigned short unicodeCharAt(int index) const = 0;
+ /*! Returns true if this string is empty or false otherwise */
+ virtual bool isEmpty() const = 0;
+ /*! Returns the number of characters in the string. */
+ virtual int length() const = 0;
+};
+
+/*! \brief Base interface for hyperlinked text
+ *
+ * Depending on the result of kind() the interface is extended by
+ * ILT_Text or ILT_Ref.
+ */
+class ILinkedText
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ILinkedText)
+ enum Kind { Kind_Text, Kind_Ref };
+ virtual Kind kind() const = 0;
+};
+
+/*! \brief Plain text fragment.
+ */
+class ILT_Text : public ILinkedText
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ILT_Text)
+ virtual const IString *text() const = 0;
+};
+
+/*! \brief Reference to an object.
+ */
+class ILT_Ref : public ILinkedText
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ILT_Ref)
+ enum TargetKind { Member, Compound };
+ virtual const IString *id() const = 0;
+ virtual TargetKind targetKind() const = 0;
+ virtual const IString *external() const = 0;
+ virtual const IString *text() const = 0;
+};
+
+/*! \brief Iterates over a list of ILinkedText fragments.
+ */
+class ILinkedTextIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ILinkedTextIterator)
+ virtual ILinkedText *toFirst() = 0;
+ virtual ILinkedText *toLast() = 0;
+ virtual ILinkedText *toNext() = 0;
+ virtual ILinkedText *toPrev() = 0;
+ virtual ILinkedText *current() const = 0;
+ virtual void release() = 0;
+};
+
+/*! \brief Representation of a parameter of a function. */
+class IParam
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IParam)
+ virtual ILinkedTextIterator *type() const = 0;
+ virtual const IString * declarationName() const = 0;
+ virtual const IString * definitionName() const = 0;
+ virtual const IString * attrib() const = 0;
+ virtual const IString * arraySpecifier() const = 0;
+ virtual ILinkedTextIterator *defaultValue() const = 0;
+ virtual IDocRoot *briefDescription() const = 0;
+};
+
+class IParamIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IParamIterator)
+ virtual IParam *toFirst() = 0;
+ virtual IParam *toLast() = 0;
+ virtual IParam *toNext() = 0;
+ virtual IParam *toPrev() = 0;
+ virtual IParam *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IMemberReference
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IMemberReference)
+ virtual IMember *member() const = 0;
+ virtual const IString * name() const = 0;
+ virtual const IString * scope() const = 0;
+ virtual const IString * protection() const = 0;
+ virtual const IString * virtualness() const = 0;
+ virtual const IString * ambiguityScope() const = 0;
+};
+
+class IMemberReferenceIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IMemberReferenceIterator)
+ virtual IMemberReference *toFirst() = 0;
+ virtual IMemberReference *toLast() = 0;
+ virtual IMemberReference *toNext() = 0;
+ virtual IMemberReference *toPrev() = 0;
+ virtual IMemberReference *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IDoc
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IDoc)
+ enum Kind
+ {
+ Invalid = 0, // 0
+ Para, // 1 -> IDocPara
+ Text, // 2 -> IDocText
+ MarkupModifier, // 3 -> IDocMarkupModifier
+ ItemizedList, // 4 -> IDocItemizedList
+ OrderedList, // 5 -> IDocOrderedList
+ ListItem, // 6 -> IDocListItem
+ ParameterList, // 7 -> IDocParameterList
+ Parameter, // 8 -> IDocParameter
+ SimpleSect, // 9 -> IDocSimpleSect
+ Title, // 10 -> IDocTitle
+ Ref, // 11 -> IDocRef
+ VariableList, // 12 -> IDocVariableList
+ VariableListEntry, // 13 -> IDocVariableListEntry
+ HRuler, // 14 -> IDocHRuler
+ LineBreak, // 15 -> IDocLineBreak
+ ULink, // 16 -> IDocULink
+ EMail, // 17 -> IDocEMail
+ Link, // 18 -> IDocLink
+ ProgramListing, // 19 -> IDocProgramListing
+ CodeLine, // 20 -> IDocCodeLine
+ Highlight, // 21 -> IDocHighlight
+ Formula, // 22 -> IDocFormula
+ Image, // 23 -> IDocImage
+ DotFile, // 24 -> IDocDotFile
+ IndexEntry, // 25 -> IDocIndexEntry
+ Table, // 26 -> IDocTable
+ Row, // 27 -> IDocRow
+ Entry, // 28 -> IDocEntry
+ Section, // 29 -> IDocSection
+ Verbatim, // 30 -> IDocVerbatim
+ Copy, // 31 -> IDocCopy
+ TocList, // 32 -> IDocTocList
+ TocItem, // 33 -> IDocTocItem
+ Anchor, // 34 -> IDocAnchor
+ Symbol, // 35 -> IDocSymbol
+ Internal, // 36 -> IDocInternal
+ Root, // 37 -> IDocRoot
+ ParameterItem // 38 -> IDocParameterItem
+ };
+ virtual Kind kind() const = 0;
+};
+
+class IDocMarkup : public IDoc
+{
+ public:
+ enum Markup
+ {
+ Normal = 0x000,
+ Bold = 0x001,
+ Emphasis = 0x002,
+ ComputerOutput = 0x004,
+ Subscript = 0x008,
+ Superscript = 0x010,
+ SmallFont = 0x020,
+ Center = 0x040,
+ Preformatted = 0x080,
+ Heading = 0x100
+ };
+};
+
+class IDocPara : public IDoc
+{
+ public:
+ virtual IDocIterator *contents() const = 0;
+};
+
+class IDocText : public IDocMarkup
+{
+ public:
+ virtual const IString * text() const = 0;
+ virtual int markup() const = 0;
+ virtual int headingLevel() const = 0;
+};
+
+class IDocMarkupModifier : public IDoc
+{
+ public:
+ virtual bool enabled() const = 0;
+ virtual int markup() const = 0;
+ virtual int headingLevel() const = 0;
+};
+
+class IDocItemizedList : public IDoc
+{
+ public:
+ virtual IDocIterator *elements() const = 0;
+};
+
+class IDocOrderedList : public IDoc
+{
+ public:
+ virtual IDocIterator *elements() const = 0;
+};
+
+class IDocListItem : public IDoc
+{
+ public:
+ virtual IDocIterator *contents() const = 0;
+};
+
+class IDocParameterList : public IDoc
+{
+ public:
+ enum Types { Param, RetVal, Exception };
+ virtual Types sectType() const = 0;
+ virtual IDocIterator *params() const = 0;
+};
+
+class IDocParameterItem : public IDoc
+{
+ public:
+ virtual IDocIterator *paramNames() const = 0;
+ virtual IDocPara *description() const = 0;
+};
+
+class IDocParameter : public IDoc
+{
+ public:
+ virtual const IString * name() const = 0;
+};
+
+class IDocTitle : public IDoc
+{
+ public:
+ virtual IDocIterator *title() const = 0;
+};
+
+class IDocSimpleSect : public IDoc
+{
+ public:
+ enum Types { Invalid = 0,
+ See, Return, Author, Version,
+ Since, Date, Bug, Note,
+ Warning, Par, Deprecated, Pre,
+ Post, Invar, Remark, Attention,
+ Todo, Test, RCS, EnumValues,
+ Examples
+ };
+ virtual Types type() const = 0;
+ virtual const IString * typeString() const = 0;
+ virtual IDocTitle *title() const = 0;
+ virtual IDocPara *description() const = 0;
+};
+
+class IDocRef : public IDoc
+{
+ public:
+ enum TargetKind { Member, Compound };
+ virtual const IString * refId() const = 0;
+ virtual TargetKind targetKind() const = 0;
+ virtual const IString * external() const = 0;
+ virtual const IString * text() const = 0;
+};
+
+class IDocVariableList : public IDoc
+{
+ public:
+ virtual IDocIterator *entries() const = 0;
+};
+
+class IDocVariableListEntry : public IDoc
+{
+ public:
+ virtual ILinkedTextIterator * term() const = 0;
+ virtual IDocPara *description() const = 0;
+};
+
+class IDocHRuler : public IDoc
+{
+};
+
+class IDocLineBreak : public IDoc
+{
+};
+
+class IDocULink : public IDoc
+{
+ public:
+ virtual const IString * url() const = 0;
+ virtual const IString * text() const = 0;
+};
+
+class IDocEMail : public IDoc
+{
+ public:
+ virtual const IString * address() const = 0;
+};
+
+class IDocLink : public IDoc
+{
+ public:
+ virtual const IString * refId() const = 0;
+ virtual const IString * text() const = 0;
+};
+
+class IDocProgramListing : public IDoc
+{
+ public:
+ virtual IDocIterator *codeLines() const = 0;
+};
+
+class IDocCodeLine : public IDoc
+{
+ public:
+ virtual int lineNumber() const = 0;
+ virtual const IString * refId() const = 0;
+ virtual IDocIterator *codeElements() const = 0;
+};
+
+class IDocHighlight : public IDoc
+{
+ public:
+ enum HighlightKind
+ { Invalid=0,
+ Comment, Keyword,
+ KeywordType, KeywordFlow, CharLiteral,
+ StringLiteral, Preprocessor
+ };
+ virtual HighlightKind highlightKind() const = 0;
+ virtual IDocIterator *codeElements() const = 0;
+};
+
+class IDocFormula : public IDoc
+{
+ public:
+ virtual const IString * id() const = 0;
+ virtual const IString * text() const = 0;
+};
+
+class IDocImage : public IDoc
+{
+ public:
+ virtual const IString * name() const = 0;
+ virtual const IString * caption() const = 0;
+};
+
+class IDocDotFile : public IDoc
+{
+ public:
+ virtual const IString * name() const = 0;
+ virtual const IString * caption() const = 0;
+};
+
+class IDocIndexEntry : public IDoc
+{
+ public:
+ virtual const IString * primary() const = 0;
+ virtual const IString * secondary() const = 0;
+};
+
+class IDocTable : public IDoc
+{
+ public:
+ virtual IDocIterator *rows() const = 0;
+ virtual int numColumns() const = 0;
+ virtual const IString * caption() const = 0;
+};
+
+class IDocRow : public IDoc
+{
+ public:
+ virtual IDocIterator *entries() const = 0;
+};
+
+class IDocEntry : public IDoc
+{
+ public:
+ virtual IDocIterator *contents() const = 0;
+};
+
+class IDocSection : public IDoc
+{
+ public:
+ virtual const IString * id() const = 0;
+ virtual int level() const = 0;
+ virtual IDocTitle *title() const = 0;
+ virtual IDocIterator *paragraphs() const = 0;
+ virtual IDocIterator *subSections() const = 0;
+ virtual IDocInternal *internal() const = 0;
+};
+
+class IDocInternal : public IDoc
+{
+ public:
+ virtual IDocIterator *paragraphs() const = 0;
+ virtual IDocIterator *subSections() const = 0;
+};
+
+class IDocTocList : public IDoc
+{
+ public:
+ virtual IDocIterator *elements() const = 0;
+};
+
+class IDocTocItem : public IDoc
+{
+ public:
+ virtual const IString *id() const = 0;
+ virtual const IString *title() const = 0;
+};
+
+class IDocCopy : public IDoc
+{
+ public:
+ virtual IDocIterator *contents() const = 0;
+};
+
+class IDocVerbatim : public IDoc
+{
+ public:
+ enum Types { Invalid = 0, HtmlOnly, LatexOnly, Verbatim };
+ virtual const IString *text() const = 0;
+ virtual Types type() const = 0;
+};
+
+class IDocAnchor : public IDoc
+{
+ public:
+ virtual const IString *id() const = 0;
+};
+
+class IDocSymbol : public IDoc
+{
+ public:
+ enum Types
+ { Invalid = 0,
+ Umlaut, Acute, Grave, Circ, Tilde, Szlig, Cedil, Ring, Nbsp, Copy
+ };
+ virtual Types type() const = 0;
+ virtual const IString * typeString() const = 0;
+ virtual char letter() const = 0;
+};
+
+class IDocRoot : public IDoc
+{
+ public:
+ virtual IDocIterator *contents() const = 0;
+ virtual IDocInternal *internal() const = 0;
+};
+
+class IDocIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IDocIterator)
+ virtual IDoc *toFirst() = 0;
+ virtual IDoc *toLast() = 0;
+ virtual IDoc *toNext() = 0;
+ virtual IDoc *toPrev() = 0;
+ virtual IDoc *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IEdgeLabel
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IEdgeLabel)
+ virtual const IString * label() const = 0;
+};
+
+class IEdgeLabelIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IEdgeLabelIterator)
+ virtual IEdgeLabel *toFirst() = 0;
+ virtual IEdgeLabel *toLast() = 0;
+ virtual IEdgeLabel *toNext() = 0;
+ virtual IEdgeLabel *toPrev() = 0;
+ virtual IEdgeLabel *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IChildNode
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IChildNode)
+ enum NodeRelation { PublicInheritance, ProtectedInheritance,
+ PrivateInheritance, Usage, TemplateInstance
+ };
+ virtual INode * node() const = 0;
+ virtual NodeRelation relation() const = 0;
+ virtual const IString * relationString() const = 0;
+ virtual IEdgeLabelIterator *edgeLabels() const = 0;
+};
+
+class IChildNodeIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IChildNodeIterator)
+ virtual IChildNode *toFirst() = 0;
+ virtual IChildNode *toLast() = 0;
+ virtual IChildNode *toNext() = 0;
+ virtual IChildNode *toPrev() = 0;
+ virtual IChildNode *current() const = 0;
+ virtual void release() = 0;
+};
+
+class INode
+{
+ public:
+ VIRTUAL_DESTRUCTOR(INode)
+ virtual const IString * id() const = 0;
+ virtual const IString * label() const = 0;
+ virtual const IString * linkId() const = 0;
+ virtual IChildNodeIterator *children() const = 0;
+};
+
+class INodeIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(INodeIterator)
+ virtual INode *toFirst() = 0;
+ virtual INode *toLast() = 0;
+ virtual INode *toNext() = 0;
+ virtual INode *toPrev() = 0;
+ virtual INode *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IGraph
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IGraph)
+ virtual INodeIterator *nodes() const = 0;
+};
+
+class IMember
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IMember)
+ enum MemberKind { Invalid=0,
+ Define, Property, Variable, Typedef, Enum,
+ Function, Signal, Prototype, Friend, DCOP, Slot,
+ EnumValue
+ };
+ virtual ICompound *compound() const = 0;
+ virtual ISection *section() const = 0;
+ virtual MemberKind kind() const = 0;
+ virtual const IString * kindString() const = 0;
+ virtual const IString * id() const = 0;
+ virtual const IString * protection() const = 0;
+ virtual const IString * virtualness() const = 0;
+ virtual ILinkedTextIterator *type() const = 0;
+ virtual const IString * typeString() const = 0;
+ virtual const IString * name() const = 0;
+ virtual const IString * readAccessor() const = 0;
+ virtual const IString * writeAccessor() const = 0;
+ virtual const IString * definition() const = 0;
+ virtual const IString * argsstring() const = 0;
+ virtual bool isConst() const = 0;
+ virtual bool isVolatile() const = 0;
+ virtual bool isStatic() const = 0;
+ virtual bool isExplicit() const = 0;
+ virtual bool isInline() const = 0;
+ virtual bool isMutable() const = 0;
+ virtual bool isReadable() const = 0;
+ virtual bool isWritable() const = 0;
+ virtual IParamIterator *parameters() const = 0;
+ virtual IParamIterator *templateParameters() const = 0;
+ virtual ILinkedTextIterator *initializer() const = 0;
+ virtual ILinkedTextIterator *exceptions() const = 0;
+ virtual IMemberReferenceIterator *references() const = 0;
+ virtual IMemberReferenceIterator *referencedBy() const = 0;
+ virtual const IString *bodyFile() const = 0;
+ virtual int bodyStart() const = 0;
+ virtual int bodyEnd() const = 0;
+ virtual const IString * definitionFile() const = 0;
+ virtual int definitionLine() const = 0;
+ virtual IMemberReference *reimplements() const = 0;
+ virtual IMemberReferenceIterator *reimplementedBy() const = 0;
+ virtual IDocRoot *briefDescription() const = 0;
+ virtual IDocRoot *detailedDescription() const = 0;
+ virtual IDocRoot *inbodyDescription() const = 0;
+};
+
+class IDefine : public IMember
+{
+ public:
+};
+
+class IProperty : public IMember
+{
+ public:
+};
+
+class IVariable : public IMember
+{
+ public:
+};
+
+class ITypedef : public IMember
+{
+ public:
+};
+
+class IFunction : public IMember
+{
+ public:
+};
+
+class ISignal : public IMember
+{
+ public:
+};
+
+class IPrototype : public IMember
+{
+ public:
+};
+
+class IFriend : public IMember
+{
+ public:
+};
+
+class IDCOP : public IMember
+{
+ public:
+};
+
+class ISlot : public IMember
+{
+ public:
+};
+
+class IEnumValue : public IMember
+{
+ public:
+ virtual const IString * name() const = 0;
+};
+
+/*! \brief Include relation
+ */
+class IInclude
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IInclude)
+ virtual const IString * name() const = 0;
+ virtual const IString * refId() const = 0;
+ virtual bool isLocal() const = 0;
+};
+
+class IIncludeIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IIncludeIterator)
+ virtual IInclude *toFirst() = 0;
+ virtual IInclude *toLast() = 0;
+ virtual IInclude *toNext() = 0;
+ virtual IInclude *toPrev() = 0;
+ virtual IInclude *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IMemberIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IMemberIterator)
+ virtual IMember *toFirst() = 0;
+ virtual IMember *toLast() = 0;
+ virtual IMember *toNext() = 0;
+ virtual IMember *toPrev() = 0;
+ virtual IMember *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IEnum : public IMember
+{
+ public:
+ virtual IMemberIterator *enumValues() const = 0;
+};
+
+/*! \brief The interface to a section in the object model.
+ *
+ * A compound can have a number of sections, where each
+ * section contains a set of members with the properties implied by
+ * the section kind. The kind() method returns the kind of the section.
+ * The members of the section can be accessed via members(). Apart
+ * from using kind(), some of the individual properties of the section can
+ * also be inspected via isStatic(), isPublic(), isProtected() and
+ * isPrivate().
+ */
+class ISection
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ISection)
+ /*! Possible section types */
+ enum SectionKind
+ { Invalid=0,
+ UserDefined, //!< A user defined member group
+ PubTypes, //!< Public member typedefs
+ PubFuncs, //!< Public member functions
+ PubAttribs, //!< Public member attributes
+ PubSlots, //!< Public Qt Slots
+ Signals, //!< Qt Signals
+ DCOPFuncs, //!< KDE-DCOP interface functions
+ Properties, //!< IDL properties
+ Events, //!< C# events
+ PubStatFuncs, //!< Public static member functions
+ PubStatAttribs, //!< Public static attributes
+ ProTypes, //!< Protected member typedefs
+ ProFuncs, //!< Protected member functions
+ ProAttribs, //!< Protected member attributes
+ ProSlots, //!< Protected slots
+ ProStatFuncs, //!< Protected static member functions
+ ProStatAttribs, //!< Protected static member attributes
+ PacTypes, //!< Package member typedefs
+ PacFuncs, //!< Package member functions
+ PacAttribs, //!< Package member attributes
+ PacStatFuncs, //!< Package static member functions
+ PacStatAttribs, //!< Package static member attributes
+ PriTypes, //!< Private member typedefs
+ PriFuncs, //!< Private member functions
+ PriAttribs, //!< Private member attributes
+ PriSlots, //!< Private Qt slots
+ PriStatFuncs, //!< Private static member functions
+ PriStatAttribs, //!< Private static member attributes
+ Friend, //!< Friends
+ Related, //!< Function marked as related
+ Defines, //!< Preprocessor defines
+ Prototypes, //!< Global function prototypes
+ Typedefs, //!< Global typedefs
+ Enums, //!< Enumerations
+ Functions, //!< Global functions
+ Variables //!< Global variables
+ };
+
+ /*! Returns a string representation of the value returned by kind() */
+ virtual const IString * kindString() const = 0;
+
+ /*! Returns what kind of section this is */
+ virtual SectionKind kind() const = 0;
+
+ /*! Returns the description attached to this section (for user defined
+ * sections, also known as member groups).
+ */
+ virtual IDocRoot *description() const = 0;
+
+ /*! Returns an iterator for the members of this section */
+ virtual IMemberIterator *members() const = 0;
+
+ /*! Returns \c true if this section contains statics */
+ virtual bool isStatic() const = 0;
+
+ /*! Returns \c true if this section belongs to a
+ * public section of a class
+ */
+ virtual bool isPublic() const = 0;
+
+ /*! Returns \c true if this section belongs to a
+ * private section of a class
+ */
+ virtual bool isPrivate() const = 0;
+
+ /*! Returns \c true if this section belongs to a
+ * protected section of a class
+ * */
+ virtual bool isProtected() const = 0;
+};
+
+class IUserDefined : public ISection
+{
+ public:
+ virtual const IString * header() const = 0;
+};
+
+class ISectionIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ISectionIterator)
+ virtual ISection *toFirst() = 0;
+ virtual ISection *toLast() = 0;
+ virtual ISection *toNext() = 0;
+ virtual ISection *toPrev() = 0;
+ virtual ISection *current() const = 0;
+ virtual void release() = 0;
+};
+
+/*! \brief The interface to a compound in the object model.
+ *
+ * A compound has a name which can be obtained via the name() method
+ * and a unique id, which is return via the id() method.
+ * A compound consists zero or more members which are grouped into sections.
+ * The sections() method can be used to access the individual sections.
+ * Alternatively, members can be obtained by name or id. There are
+ * different types of compounds. The kind() method returns what kind of
+ * compound this is. Depending on the return value one can dynamically
+ * cast an interface pointer to an more specialised interface that provides
+ * additional methods.
+ * Example:
+ * \code
+ * ICompound *comp=...;
+ * if (comp->kind()==ICompound::Class)
+ * {
+ * IClass *cls = dynamic_cast<IClass*>(comp);
+ * // use methods of IClass
+ * }
+ * \endcode
+ * The documentation that is provided by a compound is available via
+ * the briefDescription() and detailedDescription() methods.
+ * To avoid excessive memory usage, release() should be called (once) on each
+ * compound interface pointer that is no longer needed.
+ */
+class ICompound
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ICompound)
+ /*! Represents the kind of compounds recognised by doxygen. */
+ enum CompoundKind { Invalid=0,
+ Class, Struct, Union, Interface, Protocol, Category,
+ Exception, File, Namespace, Group, Page, Example, Dir
+ };
+
+ /*! Returns the name of this compound */
+ virtual const IString * name() const = 0;
+
+ /*! Returns the id of this compound. The id is a
+ * unique string representing a specific compound object.
+ */
+ virtual const IString * id() const = 0;
+
+ /*! Returns the kind of compound. See #CompoundKind for possible
+ * values.
+ */
+ virtual CompoundKind kind() const = 0;
+
+ /*! Returns a string representation of the compound kind.
+ * @see kind()
+ */
+ virtual const IString * kindString() const = 0;
+
+ /*! Returns an iterator for the different member sections in this
+ * compound.
+ */
+ virtual ISectionIterator *sections() const = 0;
+
+ /*! Returns a tree-structured representation of the brief
+ * description that is attached to this compound.
+ */
+ virtual IDocRoot *briefDescription() const = 0;
+
+ /*! Returns a tree-structured representation of the detailed
+ * description that is attached to this compound.
+ */
+ virtual IDocRoot *detailedDescription() const = 0;
+
+ /*! Returns an interface to a member given its id.
+ * @param id The member id.
+ */
+ virtual IMember *memberById(const char * id) const = 0;
+
+ /*! Returns a list of all members within the compound having a certain
+ * name. Member overloading is the reason why there can be more than
+ * one member.
+ * @param name The name of the member.
+ */
+ virtual IMemberIterator *memberByName(const char * name) const = 0;
+
+ /*! Decreases the reference counter for this compound. If it reaches
+ * zero, the memory for the compound will be released.
+ */
+ virtual void release() = 0;
+};
+
+class ICompoundIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(ICompoundIterator)
+ virtual void toFirst() = 0;
+ virtual void toLast() = 0;
+ virtual void toNext() = 0;
+ virtual void toPrev() = 0;
+ virtual ICompound *current() const = 0;
+ virtual void release() = 0;
+};
+
+class IRelatedCompound
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IRelatedCompound)
+ enum Protection { Public, Protected, Private };
+ enum Kind { Normal, Virtual };
+ virtual ICompound *compound() const = 0;
+ virtual Protection protection() const = 0;
+ virtual Kind kind() const = 0;
+ virtual const IString *name() const = 0;
+
+};
+
+class IRelatedCompoundIterator
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IRelatedCompoundIterator)
+ virtual IRelatedCompound *toFirst() = 0;
+ virtual IRelatedCompound *toLast() = 0;
+ virtual IRelatedCompound *toNext() = 0;
+ virtual IRelatedCompound *toPrev() = 0;
+ virtual IRelatedCompound *current() const = 0;
+ virtual void release() = 0;
+};
+
+/*! \brief The interface to a class in the object model.
+ */
+class IClass : public ICompound
+{
+ public:
+ virtual IGraph *inheritanceGraph() const = 0;
+ virtual IGraph *collaborationGraph() const = 0;
+ virtual IRelatedCompoundIterator *baseCompounds() const = 0;
+ virtual IRelatedCompoundIterator *derivedCompounds() const = 0;
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+ virtual IParamIterator *templateParameters() const = 0;
+ virtual const IString *locationFile() const = 0;
+ virtual int locationLine() const = 0;
+ virtual const IString *locationBodyFile() const = 0;
+ virtual int locationBodyStartLine() const = 0;
+ virtual int locationBodyEndLine() const = 0;
+
+ // TODO:
+ // class:
+ // listOfAllMembers()
+ // protection()
+ // isAbstract()
+};
+
+/*! \brief The interface to a struct in the object model.
+ */
+class IStruct : public ICompound
+{
+ public:
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+ virtual IRelatedCompoundIterator *baseCompounds() const = 0;
+ virtual IRelatedCompoundIterator *derivedCompounds() const = 0;
+ virtual const IString *locationFile() const = 0;
+ virtual int locationLine() const = 0;
+ virtual int locationBodyStartLine() const = 0;
+ virtual int locationBodyEndLine() const = 0;
+};
+
+/*! \brief The interface to a union in the object model.
+ */
+class IUnion : public ICompound
+{
+ public:
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+};
+
+/*! \brief The interface to a Java/IDL interface in the object model.
+ */
+class IInterface : public ICompound
+{
+ public:
+ virtual IRelatedCompoundIterator *baseCompounds() const = 0;
+ virtual IRelatedCompoundIterator *derivedCompounds() const = 0;
+};
+
+
+/*! \brief The interface to a Java/IDL exception in the object model.
+ */
+class IException : public ICompound
+{
+};
+
+/*! \brief The interface to a namespace in the object model.
+ */
+class INamespace : public ICompound
+{
+ public:
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+};
+
+/*! \brief The interface to a file in the object model.
+ */
+class IFile : public ICompound
+{
+ public:
+ virtual IGraph *includeDependencyGraph() const = 0;
+ virtual IGraph *includedByDependencyGraph() const = 0;
+ virtual IDocProgramListing *source() const = 0;
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+
+ virtual IIncludeIterator *includes() const = 0;
+ virtual IIncludeIterator *includedBy() const = 0;
+
+ // ICompound *innerNamespaces()
+ // ICompoundIterator *innerClasses()
+};
+
+/*! \brief The interface to a group in the object model.
+ */
+class IGroup : public ICompound
+{
+ public:
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+ // group:
+ // Title()
+ // innerFile()
+ // innerPage()
+};
+
+/*! \brief The interface to a page in the object model.
+ */
+class IPage : public ICompound
+{
+ public:
+ virtual const IDocTitle *title() const = 0;
+};
+
+/** \brief Interface to a directory in the object model. */
+class IDir : public ICompound
+{
+ public:
+ virtual ICompoundIterator *nestedCompounds() const = 0;
+};
+
+/*! Root node of the object model. */
+class IDoxygen
+{
+ public:
+ VIRTUAL_DESTRUCTOR(IDoxygen)
+
+ /*! Returns an iterator that can be used to iterate over the list
+ * of compounds found in the project.
+ */
+ virtual ICompoundIterator *compounds() const = 0;
+
+ /*! Returns a compound given its unique \a id. If you have a
+ * compound id this function is much more efficient than iterating
+ * over the compound list. Returns 0 if the id is not valid.
+ */
+ virtual ICompound *compoundById(const char * id) const = 0;
+
+ /*! Returns a compound given its name (including the scope).
+ * Returns 0 if the name is not found in the project.
+ */
+ virtual ICompound *compoundByName(const char * name) const = 0;
+
+ /*! Returns an interface to a compound containing a member given it the
+ * member's id. Given the ICompound interface one can use the same id
+ * to obtain the IMember interface.
+ * @param id The member id.
+ */
+ virtual ICompound *memberById(const char * id) const = 0;
+
+ /*! Returns a list of all compounds containing at least one members
+ * with a certain name. Each compound can be asked to return the
+ * list of members with that name.
+ * @param name The name of the member.
+ */
+ virtual ICompoundIterator *memberByName(const char * name) const = 0;
+
+ /*! Releases the memory for the object hierarchy obtained by
+ * createdObjecModelFromXML(). First release all iterators before calling
+ * this function.
+ */
+ virtual void release() = 0;
+
+ /*! Sets the debug level.
+ * - 0 all debugging messages are disabled (the default).
+ * - 1 display important messages only
+ * - 2 display any messages.
+ */
+ virtual void setDebugLevel(int level) = 0;
+
+ /*! Reads an XML directory produced by doxygen and builds up a data
+ * structure representing the contents of the XML files in the directory.
+ */
+ virtual bool readXMLDir(const char *xmlDirName) = 0;
+};
+
+/*! Factory method that creates an empty object model for a doxygen generated XML file.
+ * Use the readXMLDir() method to build the model from an XML output
+ * directory containing doxygen output.
+ */
+IDoxygen *createObjectModel();
+
+#endif
diff --git a/addon/doxmlparser/src/doxmlparser.pro b/addon/doxmlparser/src/doxmlparser.pro
new file mode 100644
index 0000000..42230de
--- /dev/null
+++ b/addon/doxmlparser/src/doxmlparser.pro
@@ -0,0 +1,34 @@
+#
+# This file was generated from doxmlparser.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = lib.t
+CONFIG = console staticlib warn_on debug
+HEADERS = basehandler.h mainhandler.h \
+ compoundhandler.h sectionhandler.h \
+ memberhandler.h paramhandler.h \
+ dochandler.h linkedtexthandler.h \
+ debug.h graphhandler.h stringimpl.h \
+ loamhandler.h
+SOURCES = mainhandler.cpp \
+ compoundhandler.cpp sectionhandler.cpp \
+ memberhandler.cpp paramhandler.cpp \
+ dochandler.cpp linkedtexthandler.cpp \
+ basehandler.cpp debug.cpp graphhandler.cpp \
+ loamhandler.cpp
+unix:LIBS += -L../../../lib -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../lib -lqtools
+win32-msvc:LIBS += qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:....\\..\lib
+win32-borland:LIBS += qtools.lib doxycfg.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../lib
+OBJECTS_DIR = ../../../objects/doxmlparser
+TARGET = doxmlparser
+INCLUDEPATH += ../../../qtools ../include
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/addon/doxmlparser/src/doxmlparser.pro.in b/addon/doxmlparser/src/doxmlparser.pro.in
new file mode 100644
index 0000000..2bbf326
--- /dev/null
+++ b/addon/doxmlparser/src/doxmlparser.pro.in
@@ -0,0 +1,27 @@
+TEMPLATE = lib.t
+CONFIG = console staticlib warn_on $extraopts
+HEADERS = basehandler.h mainhandler.h \
+ compoundhandler.h sectionhandler.h \
+ memberhandler.h paramhandler.h \
+ dochandler.h linkedtexthandler.h \
+ debug.h graphhandler.h stringimpl.h \
+ loamhandler.h
+SOURCES = mainhandler.cpp \
+ compoundhandler.cpp sectionhandler.cpp \
+ memberhandler.cpp paramhandler.cpp \
+ dochandler.cpp linkedtexthandler.cpp \
+ basehandler.cpp debug.cpp graphhandler.cpp \
+ loamhandler.cpp
+unix:LIBS += -L../../../lib -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../lib -lqtools
+win32-msvc:LIBS += qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:....\\..\lib
+win32-borland:LIBS += qtools.lib doxycfg.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../lib
+OBJECTS_DIR = ../../../objects/doxmlparser
+TARGET = doxmlparser
+INCLUDEPATH += ../../../qtools ../include
+
diff --git a/addon/doxmlparser/src/graphhandler.cpp b/addon/doxmlparser/src/graphhandler.cpp
new file mode 100644
index 0000000..de30923
--- /dev/null
+++ b/addon/doxmlparser/src/graphhandler.cpp
@@ -0,0 +1,216 @@
+#include "graphhandler.h"
+
+class EdgeRelationMapper
+{
+ public:
+ EdgeRelationMapper()
+ {
+ m_map.insert("public-inheritance", IChildNode::PublicInheritance);
+ m_map.insert("protected-inheritance", IChildNode::ProtectedInheritance);
+ m_map.insert("private-inheritance", IChildNode::PrivateInheritance);
+ m_map.insert("usage", IChildNode::Usage);
+ m_map.insert("template-instance", IChildNode::TemplateInstance);
+ }
+ IChildNode::NodeRelation stringToNodeRelation(const QString &nrStr)
+ {
+ return m_map[nrStr];
+ }
+ private:
+ QMap<QString,IChildNode::NodeRelation> m_map;
+};
+
+static EdgeRelationMapper *s_edgeRelationMapper;
+
+void graphhandler_init()
+{
+ s_edgeRelationMapper = new EdgeRelationMapper;
+}
+
+void graphhandler_exit()
+{
+ delete s_edgeRelationMapper;
+}
+
+//------------------------------------------------------------------------
+
+GraphHandler::GraphHandler(IBaseHandler *parent,const char *endTag)
+ : m_parent(parent)
+{
+ addEndHandler(endTag,this,&GraphHandler::endGraph);
+ addStartHandler("node",this,&GraphHandler::startNode);
+ m_nodes.setAutoDelete(TRUE);
+ m_nodeDict = new QDict<NodeHandler>(1009);
+}
+
+GraphHandler::~GraphHandler()
+{
+ delete m_nodeDict;
+}
+
+void GraphHandler::startGraph(const QXmlAttributes &)
+{
+ debug(2,"startGraph\n");
+ m_parent->setDelegate(this);
+}
+
+void GraphHandler::endGraph()
+{
+ debug(2,"endGraph\n");
+ m_parent->setDelegate(0);
+}
+
+void GraphHandler::startNode(const QXmlAttributes &attrib)
+{
+ NodeHandler *n = new NodeHandler(this);
+ n->startNode(attrib);
+ m_nodes.append(n);
+ m_nodeDict->insert(attrib.value("id").utf8(),n);
+}
+
+INodeIterator *GraphHandler::nodes() const
+{
+ return new NodeIterator(*this);
+}
+
+NodeHandler *GraphHandler::getNodeById(const QString &id) const
+{
+ return m_nodeDict->find(id.utf8());
+}
+
+//------------------------------------------------------------------------
+
+NodeHandler::NodeHandler(GraphHandler *gh)
+ : m_parent(gh), m_graph(gh)
+{
+ addEndHandler("node",this,&NodeHandler::endNode);
+ addStartHandler("link",this,&NodeHandler::startLink);
+ addEndHandler("link",this,&NodeHandler::endLink);
+ addStartHandler("label",this,&NodeHandler::startLabel);
+ addEndHandler("label",this,&NodeHandler::endLabel);
+ addStartHandler("childnode",this,&NodeHandler::startChildNode);
+ m_children.setAutoDelete(TRUE);
+}
+
+NodeHandler::~NodeHandler()
+{
+}
+
+void NodeHandler::startNode(const QXmlAttributes &attrib)
+{
+ debug(2,"startNode\n");
+ m_parent->setDelegate(this);
+ m_id = attrib.value("id");
+}
+
+void NodeHandler::endNode()
+{
+ debug(2,"endNode\n");
+ m_parent->setDelegate(0);
+}
+
+void NodeHandler::startLink(const QXmlAttributes &attrib)
+{
+ m_link = attrib.value("refid");
+}
+
+void NodeHandler::endLink()
+{
+}
+
+void NodeHandler::startLabel(const QXmlAttributes &/*attrib*/)
+{
+ m_curString="";
+}
+
+void NodeHandler::endLabel()
+{
+ m_label = m_curString;
+}
+
+void NodeHandler::startChildNode(const QXmlAttributes &attrib)
+{
+ ChildNodeHandler *cnh = new ChildNodeHandler(this,m_graph);
+ cnh->startChildNode(attrib);
+ m_children.append(cnh);
+}
+
+IChildNodeIterator *NodeHandler::children() const
+{
+ return new ChildNodeIterator(*this);
+}
+
+//------------------------------------------------------------------------
+
+ChildNodeHandler::ChildNodeHandler(IBaseHandler *parent,GraphHandler *gh)
+ : m_parent(parent), m_graph(gh)
+{
+ addEndHandler("childnode",this,&ChildNodeHandler::endChildNode);
+ addStartHandler("edgelabel",this,&ChildNodeHandler::startEdgeLabel);
+ m_edgeLabels.setAutoDelete(TRUE);
+}
+
+ChildNodeHandler::~ChildNodeHandler()
+{
+}
+
+void ChildNodeHandler::startChildNode(const QXmlAttributes &attrib)
+{
+ debug(2,"startChildNode\n");
+ m_id = attrib.value("refid");
+ m_relationString = attrib.value("relation");
+ m_relation = s_edgeRelationMapper->stringToNodeRelation(m_relationString);
+ m_parent->setDelegate(this);
+}
+
+void ChildNodeHandler::endChildNode()
+{
+ debug(2,"endChildNode\n");
+ m_parent->setDelegate(0);
+}
+
+
+void ChildNodeHandler::startEdgeLabel(const QXmlAttributes &attrib)
+{
+ EdgeLabelHandler *elh = new EdgeLabelHandler(this);
+ elh->startEdgeLabel(attrib);
+ m_edgeLabels.append(elh);
+}
+
+IEdgeLabelIterator *ChildNodeHandler::edgeLabels() const
+{
+ return new EdgeLabelIterator(*this);
+}
+
+INode *ChildNodeHandler::node() const
+{
+ return m_graph->getNodeById(m_id);
+}
+
+//-----------------------------------------------------------------------
+
+EdgeLabelHandler::EdgeLabelHandler(IBaseHandler *parent)
+ : m_parent(parent)
+{
+ addEndHandler("edgelabel",this,&EdgeLabelHandler::endEdgeLabel);
+}
+
+EdgeLabelHandler::~EdgeLabelHandler()
+{
+}
+
+void EdgeLabelHandler::startEdgeLabel(const QXmlAttributes &)
+{
+ m_parent->setDelegate(this);
+ m_curString="";
+}
+
+void EdgeLabelHandler::endEdgeLabel()
+{
+ m_label=m_curString;
+ m_parent->setDelegate(0);
+}
+
+
+
+
+
diff --git a/addon/doxmlparser/src/graphhandler.h b/addon/doxmlparser/src/graphhandler.h
new file mode 100644
index 0000000..090c62a
--- /dev/null
+++ b/addon/doxmlparser/src/graphhandler.h
@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _GRAPHHANDLER_H
+#define _GRAPHHANDLER_H
+
+#include "stringimpl.h"
+#include "doxmlintf.h"
+#include "basehandler.h"
+#include "baseiterator.h"
+
+class NodeHandler;
+class ChildNodeHandler;
+class EdgeLabelHandler;
+
+class GraphHandler : public IGraph, public BaseHandler<GraphHandler>
+{
+ friend class NodeIterator;
+ public:
+ GraphHandler(IBaseHandler *parent,const char *endTag);
+ virtual ~GraphHandler();
+
+ void startGraph(const QXmlAttributes &attrib);
+ void endGraph();
+ void startNode(const QXmlAttributes &attrib);
+ NodeHandler *getNodeById(const QString &id) const;
+
+ // IGraph
+ virtual INodeIterator *nodes() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QList<NodeHandler> m_nodes;
+ QDict<NodeHandler> *m_nodeDict;
+};
+
+//----------------------------------------------------------------------
+
+class NodeHandler : public INode, public BaseHandler<NodeHandler>
+{
+ friend class ChildNodeIterator;
+ public:
+ NodeHandler(GraphHandler *gh);
+ virtual ~NodeHandler();
+
+ void startNode(const QXmlAttributes &attrib);
+ void endNode();
+ void startLabel(const QXmlAttributes &attrib);
+ void endLabel();
+ void startLink(const QXmlAttributes &attrib);
+ void endLink();
+ void startChildNode(const QXmlAttributes &attrib);
+
+ // INode
+ virtual const IString *id() const { return &m_id; }
+ virtual const IString *label() const { return &m_label; }
+ virtual const IString *linkId() const { return &m_link; }
+ virtual IChildNodeIterator *children() const;
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_id;
+ StringImpl m_label;
+ StringImpl m_link;
+ QList<ChildNodeHandler> m_children;
+ GraphHandler *m_graph;
+};
+
+class NodeIterator : public BaseIterator<INodeIterator,INode,NodeHandler>
+{
+ public:
+ NodeIterator(const GraphHandler &handler) :
+ BaseIterator<INodeIterator,INode,NodeHandler>(handler.m_nodes) {}
+};
+
+//----------------------------------------------------------------------
+
+class ChildNodeHandler : public IChildNode, public BaseHandler<ChildNodeHandler>
+{
+ friend class EdgeLabelIterator;
+ public:
+ ChildNodeHandler(IBaseHandler *parent,GraphHandler *gh);
+ virtual ~ChildNodeHandler();
+
+ void startChildNode(const QXmlAttributes &attrib);
+ void endChildNode();
+ void startEdgeLabel(const QXmlAttributes &attrib);
+
+ // IChildNode
+ virtual INode *node() const;
+ virtual NodeRelation relation() const { return m_relation; }
+ virtual const IString * relationString() const { return &m_relationString; }
+ virtual IEdgeLabelIterator *edgeLabels() const;
+
+ private:
+ IBaseHandler *m_parent;
+ QString m_id;
+ NodeRelation m_relation;
+ StringImpl m_relationString;
+ QList<EdgeLabelHandler> m_edgeLabels;
+ GraphHandler *m_graph;
+};
+
+class ChildNodeIterator : public BaseIterator<IChildNodeIterator,IChildNode,ChildNodeHandler>
+{
+ public:
+ ChildNodeIterator(const NodeHandler &handler) :
+ BaseIterator<IChildNodeIterator,IChildNode,ChildNodeHandler>(handler.m_children) {}
+};
+
+//----------------------------------------------------------------------
+
+class EdgeLabelHandler : public IEdgeLabel, public BaseHandler<EdgeLabelHandler>
+{
+ friend class EdgeLabelIterator;
+ public:
+ EdgeLabelHandler(IBaseHandler *parent);
+ virtual ~EdgeLabelHandler();
+
+ void startEdgeLabel(const QXmlAttributes &attrib);
+ void endEdgeLabel();
+
+ // IEdgeLabel
+ virtual const IString *label() const { return &m_label; }
+
+ private:
+ IBaseHandler *m_parent;
+ StringImpl m_label;
+};
+
+class EdgeLabelIterator : public BaseIterator<IEdgeLabelIterator,IEdgeLabel,EdgeLabelHandler>
+{
+ public:
+ EdgeLabelIterator(const ChildNodeHandler &handler) :
+ BaseIterator<IEdgeLabelIterator,IEdgeLabel,EdgeLabelHandler>(handler.m_edgeLabels) {}
+};
+
+void graphhandler_init();
+void graphhandler_exit();
+
+#endif
+
diff --git a/addon/doxmlparser/src/linkedtexthandler.cpp b/addon/doxmlparser/src/linkedtexthandler.cpp
new file mode 100644
index 0000000..fe45133
--- /dev/null
+++ b/addon/doxmlparser/src/linkedtexthandler.cpp
@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+#include "linkedtexthandler.h"
+#include "debug.h"
+#include <doxmlintf.h>
+#include "stringimpl.h"
+
+class LT_Text : public LinkedTextImpl, public ILT_Text
+{
+ public:
+ LT_Text(const QString &text) : m_text(text) {}
+ virtual ~LT_Text() {}
+
+ // ILT_Text
+ virtual const IString *text() const { return &m_text; }
+ virtual Kind kind() const { return LinkedTextImpl::Kind_Text; }
+ private:
+ StringImpl m_text;
+};
+
+class LT_Ref : public LinkedTextImpl, public ILT_Ref
+{
+ public:
+ LT_Ref() {}
+ virtual ~LT_Ref() {}
+ void setRefId(const QString &refId) { m_refId=refId; }
+ void setText(const QString &text) { m_text=text; }
+ void setExtId(const QString &extId) { m_extId=extId; }
+ void setTargetKind(TargetKind k) { m_targetKind=k; }
+
+ // ILT_Ref
+ virtual const IString *text() const { return &m_text; }
+ virtual const IString * id() const { return &m_refId; }
+ virtual TargetKind targetKind() const { return m_targetKind; }
+ virtual const IString *external() const { return &m_extId; }
+ virtual Kind kind() const { return LinkedTextImpl::Kind_Ref; }
+
+ private:
+ StringImpl m_refId;
+ StringImpl m_extId;
+ StringImpl m_text;
+ TargetKind m_targetKind;
+};
+
+LinkedTextHandler::LinkedTextHandler(IBaseHandler *parent,
+ QList<LinkedTextImpl> &children
+ )
+ : m_parent(parent), m_children(children)
+{
+ addStartHandler("ref",this,&LinkedTextHandler::startRef);
+ addEndHandler("ref",this,&LinkedTextHandler::endRef);
+ m_children.setAutoDelete(TRUE);
+ m_ref=0;
+}
+
+LinkedTextHandler::~LinkedTextHandler()
+{
+}
+
+void LinkedTextHandler::start(const char *endTag)
+{
+ addEndHandler(endTag,this,&LinkedTextHandler::end);
+ m_parent->setDelegate(this);
+ m_curString="";
+}
+
+void LinkedTextHandler::end()
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(new LT_Text(m_curString));
+ debug(2,"LinkedTextHandler: add text `%s'\n",m_curString.data());
+ m_curString="";
+ }
+ m_parent->setDelegate(0);
+}
+
+void LinkedTextHandler::startRef(const QXmlAttributes& attrib)
+{
+ if (!m_curString.isEmpty())
+ {
+ m_children.append(new LT_Text(m_curString));
+ debug(2,"LinkedTextHandler: add text `%s'\n",m_curString.data());
+ m_curString="";
+ }
+ ASSERT(m_ref==0);
+ m_ref = new LT_Ref;
+ m_ref->setRefId(attrib.value("refid"));
+ m_ref->setExtId(attrib.value("external"));
+ ASSERT(attrib.value("kindref")=="compound" || attrib.value("kindref")=="member");
+ m_ref->setTargetKind(attrib.value("kindref")=="compound" ? ILT_Ref::Compound : ILT_Ref::Member);
+}
+
+void LinkedTextHandler::endRef()
+{
+ m_ref->setText(m_curString);
+ m_children.append(m_ref);
+ debug(2,"LinkedTextHandler: add ref `%s'\n",m_ref->text()->latin1());
+ m_ref=0;
+}
+
+QString LinkedTextHandler::toString(const QList<LinkedTextImpl> &list)
+{
+ QListIterator<LinkedTextImpl> li(list);
+ QString result;
+ LinkedTextImpl *lt;
+ for (li.toFirst();(lt=li.current());++li)
+ {
+ switch(lt->kind())
+ {
+ case ILinkedText::Kind_Text:
+ result+=dynamic_cast<ILT_Text*>(lt)->text()->latin1();
+ break;
+ case ILinkedText::Kind_Ref:
+ result+=dynamic_cast<ILT_Ref *>(lt)->text()->latin1();
+ break;
+ }
+ }
+ return result;
+}
+
diff --git a/addon/doxmlparser/src/linkedtexthandler.h b/addon/doxmlparser/src/linkedtexthandler.h
new file mode 100644
index 0000000..cebdeb0
--- /dev/null
+++ b/addon/doxmlparser/src/linkedtexthandler.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+#ifndef LINKEDTEXTHANDLER_H
+#define LINKEDTEXTHANDLER_H
+
+#include "baseiterator.h"
+#include "basehandler.h"
+
+class LT_Ref;
+class LinkedTextImpl : public ILinkedText
+{
+ public:
+ virtual ~LinkedTextImpl() {}
+};
+
+class LinkedTextHandler : public BaseHandler<LinkedTextHandler>
+{
+ public:
+ LinkedTextHandler(IBaseHandler *parent,QList<LinkedTextImpl> &children);
+ virtual ~LinkedTextHandler();
+ virtual void start(const char *endTag);
+ virtual void end();
+ virtual void startRef(const QXmlAttributes& attrib);
+ virtual void endRef();
+ static QString toString(const QList<LinkedTextImpl> &list);
+
+ // ILinkedText
+
+ private:
+ IBaseHandler *m_parent;
+ QList<LinkedTextImpl> &m_children;
+ LT_Ref *m_ref;
+};
+
+class LinkedTextIterator : public BaseIterator<ILinkedTextIterator,ILinkedText,LinkedTextImpl>
+{
+ public:
+ LinkedTextIterator(const QList<LinkedTextImpl> &list) :
+ BaseIterator<ILinkedTextIterator,ILinkedText,LinkedTextImpl>(list) {}
+};
+
+#endif
diff --git a/addon/doxmlparser/src/loamhandler.cpp b/addon/doxmlparser/src/loamhandler.cpp
new file mode 100644
index 0000000..a939b7b
--- /dev/null
+++ b/addon/doxmlparser/src/loamhandler.cpp
@@ -0,0 +1,75 @@
+#include "loamhandler.h"
+#include "memberhandler.h"
+
+
+ListOfAllMembersHandler::ListOfAllMembersHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ m_members.setAutoDelete(TRUE);
+
+ addStartHandler("member",this,&ListOfAllMembersHandler::startMember);
+ addStartHandler("name",this,&ListOfAllMembersHandler::startName);
+ addEndHandler("name",this,&ListOfAllMembersHandler::endName);
+ addStartHandler("scope",this,&ListOfAllMembersHandler::startScope);
+ addEndHandler("scope",this,&ListOfAllMembersHandler::endScope);
+
+ addEndHandler("listofallmembers",this,&ListOfAllMembersHandler::endListOfAllMembers);
+}
+
+void ListOfAllMembersHandler::initialize(MainHandler *mh)
+{
+ QListIterator<MemberReference> mli(m_members);
+ MemberReference *mr;
+ for (;(mr=mli.current());++mli)
+ {
+ mr->initialize(mh);
+ }
+}
+
+void ListOfAllMembersHandler::startMember(const QXmlAttributes& attrib)
+{
+ MemberReference *mr = new MemberReference;
+ mr->m_memId = attrib.value("refid");
+ mr->m_virtualness = attrib.value("virt");
+ mr->m_protection = attrib.value("prot");
+ mr->m_ambiguityScope = attrib.value("ambiguityscope");
+ m_members.append(new MemberReference);
+}
+
+void ListOfAllMembersHandler::startName(const QXmlAttributes&)
+{
+ m_curString="";
+}
+
+void ListOfAllMembersHandler::endName()
+{
+ ASSERT(m_members.getLast());
+ m_members.getLast()->m_name = m_curString;
+}
+
+void ListOfAllMembersHandler::startScope(const QXmlAttributes&)
+{
+ m_curString="";
+}
+
+void ListOfAllMembersHandler::endScope()
+{
+ ASSERT(m_members.getLast());
+ m_members.getLast()->m_scope = m_curString;
+}
+
+void ListOfAllMembersHandler::startListOfAllMembers(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"listofallmembers start\n");
+}
+
+void ListOfAllMembersHandler::endListOfAllMembers()
+{
+ m_parent->setDelegate(0);
+ debug(2,"listofallmembers end\n");
+}
+
+IMemberReferenceIterator *ListOfAllMembersHandler::members() const
+{
+ return new MemberReferenceIterator(m_members);
+}
diff --git a/addon/doxmlparser/src/loamhandler.h b/addon/doxmlparser/src/loamhandler.h
new file mode 100644
index 0000000..a113aa9
--- /dev/null
+++ b/addon/doxmlparser/src/loamhandler.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LOAMHANDLER_H
+#define _LOAMHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <doxmlintf.h>
+
+#include "basehandler.h"
+
+class MainHandler;
+class MemberReference;
+
+class ListOfAllMembersHandler : public BaseHandler<ListOfAllMembersHandler>
+{
+ public:
+ virtual void startMember(const QXmlAttributes& attrib);
+ virtual void startName(const QXmlAttributes& attrib);
+ virtual void endName();
+ virtual void startScope(const QXmlAttributes& attrib);
+ virtual void endScope();
+ virtual void startListOfAllMembers(const QXmlAttributes& attrib);
+ virtual void endListOfAllMembers();
+
+ ListOfAllMembersHandler(IBaseHandler *parent);
+ virtual ~ListOfAllMembersHandler() {}
+
+ void initialize(MainHandler *mh);
+
+ virtual IMemberReferenceIterator *members() const;
+
+ protected:
+ IBaseHandler *m_parent;
+ QList<MemberReference> m_members;
+};
+
+#endif
+
diff --git a/addon/doxmlparser/src/mainhandler.cpp b/addon/doxmlparser/src/mainhandler.cpp
new file mode 100644
index 0000000..48c77fa
--- /dev/null
+++ b/addon/doxmlparser/src/mainhandler.cpp
@@ -0,0 +1,299 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include <qxml.h>
+#include "mainhandler.h"
+#include "compoundhandler.h"
+#include "sectionhandler.h"
+#include "graphhandler.h"
+#include "dochandler.h"
+#include "memberhandler.h"
+#include "debug.h"
+
+
+class ErrorHandler : public QXmlErrorHandler
+{
+ public:
+ virtual ~ErrorHandler() {}
+ bool warning( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool error( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool fatalError( const QXmlParseException &exception )
+ {
+ debug(1,"Fatal error at line %d column %d: %s\n",
+ exception.lineNumber(),exception.columnNumber(),
+ exception.message().data());
+ return FALSE;
+ }
+ QString errorString() { return ""; }
+
+ private:
+ QString errorMsg;
+};
+
+//--------------------------------------------------------------------------
+
+class CompoundEntryIterator : public ICompoundIterator,
+ public QListIterator<CompoundEntry>
+{
+ public:
+ CompoundEntryIterator(const MainHandler *m,const QList<CompoundEntry> &list) :
+ QListIterator<CompoundEntry>(list), m_mainHandler(m) {}
+ virtual ~CompoundEntryIterator() {}
+
+ virtual void toFirst()
+ {
+ QListIterator<CompoundEntry>::toFirst();
+ }
+ virtual void toLast()
+ {
+ QListIterator<CompoundEntry>::toLast();
+ }
+ virtual void toNext()
+ {
+ QListIterator<CompoundEntry>::operator++();
+ }
+ virtual void toPrev()
+ {
+ QListIterator<CompoundEntry>::operator--();
+ }
+ virtual ICompound *current() const
+ {
+ CompoundEntry *ch = QListIterator<CompoundEntry>::current();
+ return ch ? m_mainHandler->compoundById(ch->id.utf8()) : 0;
+ }
+ virtual void release()
+ { delete this; }
+
+ private:
+ const MainHandler *m_mainHandler;
+};
+
+//--------------------------------------------------------------------------
+
+MainHandler::MainHandler() : m_compoundDict(2999), m_compoundNameDict(2999),
+ m_memberDict(12251), m_memberNameDict(12251),
+ m_compoundsLoaded(1009)
+{
+ m_compounds.setAutoDelete(TRUE);
+ m_memberNameDict.setAutoDelete(TRUE);
+ addStartHandler("doxygenindex");
+ addEndHandler("doxygenindex");
+ addStartHandler("compound",this,&MainHandler::startCompound);
+ addEndHandler("compound");
+ addStartHandler("member",this,&MainHandler::startMember);
+ addEndHandler("member",this,&MainHandler::endMember);
+ addStartHandler("name",this,&MainHandler::startName);
+ addEndHandler("name",this,&MainHandler::endName);
+ m_curCompound = 0;
+ m_insideMember = FALSE;
+}
+
+MainHandler::~MainHandler()
+{
+ debug(2,"MainHandler::~MainHandler()\n");
+}
+
+void MainHandler::startCompound(const QXmlAttributes& attrib)
+{
+ m_curCompound = new CompoundEntry(257);
+ m_curCompound->id = attrib.value("refid");
+ m_compounds.append(m_curCompound);
+ m_compoundDict.insert(m_curCompound->id.utf8(),m_curCompound);
+}
+
+void MainHandler::startName(const QXmlAttributes& /*attrib*/)
+{
+ m_curString = "";
+}
+
+void MainHandler::endName()
+{
+ if (m_insideMember)
+ {
+ m_curMember->name = m_curString;
+ }
+ else
+ {
+ m_curCompound->name = m_curString;
+ m_compoundNameDict.insert(m_curString.utf8(),m_curCompound);
+ }
+}
+
+void MainHandler::startMember(const QXmlAttributes& attrib)
+{
+ m_insideMember = TRUE;
+ m_curMember = new MemberEntry;
+ m_curMember->id = attrib.value("refid");
+ m_curMember->compound = m_curCompound;
+ m_memberDict.insert(m_curMember->id.utf8(),m_curMember);
+}
+
+void MainHandler::endMember()
+{
+ m_curCompound->memberDict.insert(m_curMember->name.utf8(),m_curMember);
+ QList<CompoundEntry> *cel=0;
+ if ((cel=m_memberNameDict.find(m_curMember->name.utf8()))==0)
+ {
+ cel = new QList<CompoundEntry>;
+ m_memberNameDict.insert(m_curMember->name.utf8(),cel);
+ }
+ cel->append(m_curCompound);
+ m_insideMember = FALSE;
+}
+
+void MainHandler::setDebugLevel(int level)
+{
+ ::setDebugLevel(level);
+}
+
+void MainHandler::dump()
+{
+ QListIterator<CompoundEntry> cli(m_compounds);
+ CompoundEntry *ce;
+ for (cli.toFirst();(ce=cli.current());++cli)
+ {
+ debug(2,"compound id=`%s' name=`%s'\n",ce->id.data(),ce->name.data());
+ QDictIterator<MemberEntry> mdi(ce->memberDict);
+ MemberEntry *me;
+ for (mdi.toFirst();(me=mdi.current());++mdi)
+ {
+ debug(2," member id=`%s' name=`%s'\n",me->id.data(),me->name.data());
+ }
+ }
+}
+
+bool MainHandler::readXMLDir(const char * xmlDirName)
+{
+ m_xmlDirName = xmlDirName;
+ QString xmlFileName=m_xmlDirName+"/index.xml";
+ QFile xmlFile(xmlFileName);
+ //printf("Trying %s xmlFile.exists()=%d isReadable()=%d\n",
+ // xmlFileName.data(),xmlFile.exists(),xmlFile.isReadable());
+ if (xmlFile.exists())
+ {
+ ErrorHandler errorHandler;
+ QXmlInputSource source( xmlFile );
+ QXmlSimpleReader reader;
+ reader.setContentHandler( this );
+ reader.setErrorHandler( &errorHandler );
+ reader.parse( source );
+ dump();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+ICompoundIterator *MainHandler::compounds() const
+{
+ return new CompoundEntryIterator(this,m_compounds);
+}
+
+ICompound *MainHandler::compoundById(const char *id) const
+{
+ QString ids = id;
+ if (ids.isEmpty()) return 0;
+ CompoundHandler *ch = m_compoundsLoaded[ids.utf8()];
+ if (ch) // compound already in memory
+ {
+ ch->addref(); // returning alias -> increase reference counter
+ return ch->toICompound();
+ }
+ CompoundEntry *ce = m_compoundDict.find(ids.utf8());
+ if (ce==0) return 0; // id not found
+ // create and load a new compound
+ ch = new CompoundHandler(m_xmlDirName);
+ if (!ch->parseXML(id))
+ {
+ // compound could not be initialized.
+ delete ch;
+ return 0;
+ }
+
+ // we disregard the constness here, because the object stays conceptually
+ // unchanged.
+ MainHandler *that = (MainHandler *)this;
+ ch->initialize(that);
+ //printf("loading compound %s in memory\n",id);
+ that->m_compoundsLoaded.insert(id,ch);
+ return ch->toICompound();
+}
+
+void MainHandler::unloadCompound(CompoundHandler *ch)
+{
+ //printf("unloading compound %s from memory\n",ch->id()->latin1());
+ bool result = m_compoundsLoaded.remove(ch->id()->latin1());
+ if (!result) debug(1,"Failed to unload component!\n");
+}
+
+ICompound *MainHandler::compoundByName(const char *name) const
+{
+ QString nameStr = name;
+ if (nameStr.isEmpty()) return 0;
+ CompoundEntry *ce = m_compoundNameDict[name];
+ if (ce==0) return 0; // name not found
+ return compoundById(ce->id.utf8());
+}
+
+ICompound *MainHandler::memberById(const char *id) const
+{
+ QString ids = id;
+ if (ids.isEmpty()) return 0;
+ MemberEntry *me = m_memberDict[id];
+ if (me==0) return 0; // id not found
+ return compoundById(me->compound->id.utf8());
+}
+
+ICompoundIterator *MainHandler::memberByName(const char *name) const
+{
+ QString nameStr = name;
+ if (nameStr.isEmpty()) return 0;
+ QList<CompoundEntry> *cel = m_memberNameDict[name];
+ if (cel==0) return 0; // name not found
+ return new CompoundEntryIterator(this,*cel);
+}
+
+IDoxygen *createObjectModel()
+{
+ compoundhandler_init();
+ sectionhandler_init();
+ memberhandler_init();
+ dochandler_init();
+ graphhandler_init();
+ return new MainHandler;
+}
+
+void MainHandler::release()
+{
+ //printf("MainHandler::release()\n");
+ QDictIterator<CompoundHandler> chi(m_compoundsLoaded);
+ CompoundHandler *ch;
+ for (chi.toFirst();(ch=chi.current());++chi)
+ {
+ debug(1,"Compound %s not released\n",ch->name()->latin1());
+ }
+ graphhandler_exit();
+ dochandler_exit();
+ memberhandler_exit();
+ sectionhandler_exit();
+ compoundhandler_exit();
+ delete this;
+}
+
diff --git a/addon/doxmlparser/src/mainhandler.h b/addon/doxmlparser/src/mainhandler.h
new file mode 100644
index 0000000..270f417
--- /dev/null
+++ b/addon/doxmlparser/src/mainhandler.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MAINHANDLER_H
+#define _MAINHANDLER_H
+
+#include <qlist.h>
+
+#include <doxmlintf.h>
+#include "basehandler.h"
+
+class CompoundHandler;
+struct CompoundEntry;
+
+struct IndexEntry
+{
+ QString id;
+ QString name;
+};
+
+struct MemberEntry : public IndexEntry
+{
+ CompoundEntry *compound;
+};
+
+struct CompoundEntry : public IndexEntry
+{
+ CompoundEntry(int size) : memberDict(size)
+ { memberDict.setAutoDelete(TRUE); }
+ QDict<MemberEntry> memberDict;
+};
+
+class MainHandler : public IDoxygen, public BaseHandler<MainHandler>
+{
+ public:
+ virtual void startCompound(const QXmlAttributes& attrib);
+ virtual void startMember(const QXmlAttributes& attrib);
+ virtual void endMember();
+ virtual void startName(const QXmlAttributes& attrib);
+ virtual void endName();
+ MainHandler();
+ virtual ~MainHandler();
+
+ // IDoxygen
+ ICompoundIterator *compounds() const;
+ ICompound *compoundById(const char *id) const;
+ virtual ICompound *compoundByName(const char *name) const;
+ virtual ICompound *memberById(const char *id) const;
+ virtual ICompoundIterator *memberByName(const char *name) const;
+
+ virtual void release();
+ void setDebugLevel(int level);
+ bool readXMLDir(const char *dirName);
+ void dump();
+ void unloadCompound(CompoundHandler *ch);
+
+ private:
+ CompoundEntry *m_curCompound;
+ MemberEntry *m_curMember;
+ QList<CompoundEntry> m_compounds;
+ QDict<CompoundEntry> m_compoundDict;
+ QDict<CompoundEntry> m_compoundNameDict;
+ QDict<MemberEntry> m_memberDict;
+ QDict<QList<CompoundEntry> > m_memberNameDict;
+ QString m_xmlDirName;
+ QDict<CompoundHandler> m_compoundsLoaded;
+ bool m_insideMember;
+};
+
+#endif
diff --git a/addon/doxmlparser/src/memberhandler.cpp b/addon/doxmlparser/src/memberhandler.cpp
new file mode 100644
index 0000000..ea55333
--- /dev/null
+++ b/addon/doxmlparser/src/memberhandler.cpp
@@ -0,0 +1,600 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "memberhandler.h"
+#include "sectionhandler.h"
+#include "dochandler.h"
+#include "mainhandler.h"
+#include "linkedtexthandler.h"
+#include "paramhandler.h"
+#include "compoundhandler.h"
+#include "debug.h"
+
+//------------------------------------------------------------------------------
+
+class MemberTypeMap
+{
+ public:
+ MemberTypeMap()
+ {
+ m_map.setAutoDelete(TRUE);
+ m_map.insert("define",new int(IMember::Define));
+ m_map.insert("property",new int(IMember::Property));
+ m_map.insert("variable",new int(IMember::Variable));
+ m_map.insert("typedef",new int(IMember::Typedef));
+ m_map.insert("enum",new int(IMember::Enum));
+ m_map.insert("function",new int(IMember::Function));
+ m_map.insert("signal",new int(IMember::Signal));
+ m_map.insert("prototype",new int(IMember::Prototype));
+ m_map.insert("friend",new int(IMember::Friend));
+ m_map.insert("dcop",new int(IMember::DCOP));
+ m_map.insert("slot",new int(IMember::Slot));
+ m_map.insert("enumvalue",new int(IMember::EnumValue));
+ }
+ IMember::MemberKind map(const QString &s)
+ {
+ int *val = m_map.find(s.utf8());
+ if (val==0)
+ {
+ debug(1,"Warning: `%s' is an invalid member type\n",s.data());
+ return IMember::Invalid;
+ }
+ else return (IMember::MemberKind)*val;
+ }
+ private:
+ QDict<int> m_map;
+};
+
+static MemberTypeMap *s_typeMap;
+
+void memberhandler_init()
+{
+ s_typeMap = new MemberTypeMap;
+}
+
+void memberhandler_exit()
+{
+ delete s_typeMap;
+}
+
+//------------------------------------------------------------------------------
+
+void MemberReference::initialize(MainHandler *mh)
+{
+ m_mainHandler = mh;
+}
+
+IMember *MemberReference::member() const
+{
+ //return m_mainHandler->memberById(m_memId);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+
+#if 0
+EnumValueHandler::EnumValueHandler(IBaseHandler *parent) :
+ m_parent(parent), m_brief(0), m_detailed(0), m_linkedTextHandler(0)
+{
+ addEndHandler("enumvalue",this,&EnumValueHandler::endEnumValue);
+
+ addStartHandler("name",this,&EnumValueHandler::startName);
+ addEndHandler("name",this,&EnumValueHandler::endName);
+ addStartHandler("initializer",this,&EnumValueHandler::startInitializer);
+
+ addStartHandler("briefdescription",this,&EnumValueHandler::startBriefDesc);
+
+ addStartHandler("detaileddescription",this,&EnumValueHandler::startDetailedDesc);
+
+ m_initializer.setAutoDelete(TRUE);
+}
+
+EnumValueHandler::~EnumValueHandler()
+{
+ delete m_brief;
+ delete m_detailed;
+ delete m_linkedTextHandler;
+}
+
+void EnumValueHandler::startEnumValue(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+}
+
+void EnumValueHandler::endEnumValue()
+{
+ m_parent->setDelegate(0);
+}
+
+void EnumValueHandler::startName(const QXmlAttributes& /*attrib*/)
+{
+ m_curString="";
+}
+
+void EnumValueHandler::endName()
+{
+ m_name = m_curString;
+}
+
+void EnumValueHandler::startInitializer(const QXmlAttributes& /*attrib*/)
+{
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_initializer);
+ m_linkedTextHandler->start("initializer");
+}
+
+void EnumValueHandler::startBriefDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_brief = docHandler;
+}
+
+void EnumValueHandler::startDetailedDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_detailed = docHandler;
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+MemberHandler::MemberHandler(IBaseHandler *parent)
+ : m_brief(0), m_detailed(0), m_inbody(0),
+ m_compound(0), m_section(0), m_parent(parent)
+{
+ //printf("MemberHandler::MemberHandler() %p\n",this);
+ addEndHandler("memberdef",this,&MemberHandler::endMember);
+
+ addStartHandler("templateparamlist",this,&MemberHandler::startTemplateParamList);
+ addEndHandler("templateparamlist",this,&MemberHandler::endTemplateParamList);
+
+ addStartHandler("type",this,&MemberHandler::startType);
+
+ addStartHandler("definition",this,&MemberHandler::startDefinition);
+ addEndHandler("definition",this,&MemberHandler::endDefinition);
+
+ addStartHandler("argsstring",this,&MemberHandler::startArgsString);
+ addEndHandler("argsstring",this,&MemberHandler::endArgsString);
+
+ addStartHandler("name",this,&MemberHandler::startName);
+ addEndHandler("name",this,&MemberHandler::endName);
+
+ addStartHandler("read",this,&MemberHandler::startRead);
+ addEndHandler("read",this,&MemberHandler::endRead);
+
+ addStartHandler("write",this,&MemberHandler::startWrite);
+ addEndHandler("write",this,&MemberHandler::endWrite);
+
+ addStartHandler("reimplements",this,&MemberHandler::startReimplements);
+ addEndHandler("reimplements",this,&MemberHandler::endReimplements);
+
+ addStartHandler("reimplementedby",this,&MemberHandler::startReimplementedBy);
+ addEndHandler("reimplementedby",this,&MemberHandler::endReimplementedBy);
+
+ addStartHandler("param",this,&MemberHandler::startParam);
+
+ addStartHandler("enumvalue",this,&MemberHandler::startEnumValue2);
+ addEndHandler("enumvalue",this,&MemberHandler::endMember);
+
+ addStartHandler("initializer",this,&MemberHandler::startInitializer);
+ addStartHandler("exceptions",this,&MemberHandler::startException);
+
+ addStartHandler("briefdescription",this,&MemberHandler::startBriefDesc);
+
+ addStartHandler("detaileddescription",this,&MemberHandler::startDetailedDesc);
+
+ addStartHandler("inbodydescription",this,&MemberHandler::startInbodyDesc);
+
+ addStartHandler("location",this,&MemberHandler::startLocation);
+ addEndHandler("location");
+
+ addStartHandler("references",this,&MemberHandler::startReferences);
+ addEndHandler("references",this,&MemberHandler::endReferences);
+
+ addStartHandler("referencedby",this,&MemberHandler::startReferencedBy);
+ addEndHandler("referencedby",this,&MemberHandler::endReferencedBy);
+
+ m_type.setAutoDelete(TRUE);
+ m_initializer.setAutoDelete(TRUE);
+ m_exception.setAutoDelete(TRUE);
+ m_params.setAutoDelete(TRUE);
+ m_references.setAutoDelete(TRUE);
+ m_referencedBy.setAutoDelete(TRUE);
+ m_reimplements = 0;
+ m_reimplementedBy.setAutoDelete(TRUE);
+ m_enumValues.setAutoDelete(TRUE);
+ m_linkedTextHandler = 0;
+ m_defLine=0;
+ m_bodyStart=0;
+ m_bodyEnd=0;
+ m_insideTemplateParamList=FALSE;
+ m_hasTemplateParamList=FALSE;
+}
+
+MemberHandler::~MemberHandler()
+{
+ debug(2,"MemberHandler::~MemberHandler() %p\n",this);
+ delete m_brief;
+ delete m_detailed;
+ delete m_inbody;
+ delete m_linkedTextHandler;
+ delete m_reimplements;
+}
+
+void MemberHandler::startMember(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_kindString = attrib.value("kind");
+ //printf("startMember kindString=`%s'\n",m_kindString.data());
+ m_kind = s_typeMap->map(m_kindString);
+ m_id = attrib.value("id");
+ m_protection = attrib.value("prot");
+ m_isStatic = attrib.value("static")=="yes";
+ m_isConst = attrib.value("const")=="yes";
+ m_isExplicit = attrib.value("explicit")=="yes";
+ m_isInline = attrib.value("inline")=="yes";
+ m_virtualness = attrib.value("virt");
+ m_isVolatile = attrib.value("volatile")=="yes";
+ m_isMutable = attrib.value("mutable")=="yes";
+ m_isReadable = attrib.value("readable")=="yes";
+ m_isWritable = attrib.value("writable")=="yes";
+
+ debug(2,"member kind=`%s' id=`%s' prot=`%s' virt=`%s'\n",
+ m_kindString.data(),m_id.data(),m_protection.data(),m_virtualness.data());
+}
+
+void MemberHandler::startEnumValue(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_kindString = "enumvalue";
+ //printf("startEnumValue kindString=`%s'\n",m_kindString.data());
+ m_kind = s_typeMap->map(m_kindString);
+ m_id = attrib.value("id");
+ m_protection = attrib.value("prot");
+ m_isStatic = FALSE;
+ m_isConst = FALSE;
+ m_isExplicit = FALSE;
+ m_isInline = FALSE;
+ m_virtualness = "non-virtual";
+ m_isVolatile = FALSE;
+ m_isMutable = FALSE;
+ m_isReadable = FALSE;
+ m_isWritable = FALSE;
+ debug(2,"member kind=`%s' id=`%s' prot=`%s' virt=`%s'\n",
+ m_kindString.data(),m_id.data(),m_protection.data(),m_virtualness.data());
+}
+
+void MemberHandler::startEnumValue2(const QXmlAttributes& attrib)
+{
+ MemberHandler *mh = new MemberHandler(this);
+ mh->startEnumValue(attrib);
+ m_enumValues.append(mh);
+}
+
+
+void MemberHandler::startBriefDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_brief = docHandler;
+}
+
+void MemberHandler::startDetailedDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_detailed = docHandler;
+}
+
+void MemberHandler::startInbodyDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_inbody = docHandler;
+}
+
+void MemberHandler::startLocation(const QXmlAttributes& attrib)
+{
+ m_defFile = attrib.value("file");
+ m_bodyFile = attrib.value("bodyfile");
+ QString s;
+ s = attrib.value("line");
+ if (!s.isEmpty()) m_defLine=s.toInt();
+ s = attrib.value("bodystart");
+ if (!s.isEmpty()) m_bodyStart=s.toInt();
+ s = attrib.value("bodyend");
+ if (!s.isEmpty()) m_bodyEnd=s.toInt();
+}
+
+void MemberHandler::startReferences(const QXmlAttributes& attrib)
+{
+ MemberReference *mr = new MemberReference;
+ mr->m_memId = attrib.value("refid");
+ m_references.append(mr);
+ m_curString="";
+}
+
+void MemberHandler::endReferences()
+{
+ m_references.getLast()->m_name = m_curString;
+}
+
+void MemberHandler::startReferencedBy(const QXmlAttributes& attrib)
+{
+ MemberReference *mr = new MemberReference;
+ mr->m_memId = attrib.value("refid");
+ m_referencedBy.append(mr);
+ m_curString="";
+}
+
+void MemberHandler::endReferencedBy()
+{
+ m_referencedBy.getLast()->m_name = m_curString;
+}
+
+void MemberHandler::startReimplements(const QXmlAttributes& attrib)
+{
+ m_reimplements = new MemberReference;
+ m_reimplements->m_memId = attrib.value("refid");
+ m_curString="";
+}
+
+void MemberHandler::endReimplements()
+{
+ m_reimplements->m_name = m_curString;
+}
+
+void MemberHandler::startReimplementedBy(const QXmlAttributes& attrib)
+{
+ MemberReference *mr = new MemberReference;
+ mr->m_memId = attrib.value("refid");
+ m_reimplementedBy.append(mr);
+ m_curString="";
+}
+
+void MemberHandler::endReimplementedBy()
+{
+ m_reimplementedBy.getLast()->m_name = m_curString;
+}
+
+void MemberHandler::endMember()
+{
+ m_parent->setDelegate(0);
+}
+
+void MemberHandler::startType(const QXmlAttributes &)
+{
+ debug(2,"startType!\n");
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_type);
+ m_linkedTextHandler->start("type");
+}
+
+void MemberHandler::startInitializer(const QXmlAttributes &)
+{
+ debug(2,"startInitializer!\n");
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_initializer);
+ m_linkedTextHandler->start("initializer");
+}
+
+void MemberHandler::startException(const QXmlAttributes &)
+{
+ debug(2,"startException!\n");
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_exception);
+ m_linkedTextHandler->start("exceptions");
+}
+
+void MemberHandler::startName(const QXmlAttributes &)
+{
+ m_curString="";
+}
+
+void MemberHandler::endName()
+{
+ m_name = m_curString.stripWhiteSpace();
+ debug(2,"member name=`%s'\n",m_name.data());
+}
+
+void MemberHandler::startRead(const QXmlAttributes &)
+{
+ m_curString="";
+}
+
+void MemberHandler::endRead()
+{
+ m_read = m_curString.stripWhiteSpace();
+ debug(2,"member read=`%s'\n",m_read.data());
+}
+
+void MemberHandler::startWrite(const QXmlAttributes &)
+{
+ m_curString="";
+}
+
+void MemberHandler::endWrite()
+{
+ m_write = m_curString.stripWhiteSpace();
+ debug(2,"member write=`%s'\n",m_write.data());
+}
+
+void MemberHandler::startDefinition(const QXmlAttributes&)
+{
+ m_curString="";
+}
+
+void MemberHandler::endDefinition()
+{
+ m_definition = m_curString.stripWhiteSpace();
+ debug(2,"definition=%s\n",m_definition.data());
+}
+
+void MemberHandler::startArgsString(const QXmlAttributes&)
+{
+ m_curString="";
+}
+
+void MemberHandler::endArgsString()
+{
+ m_argsstring = m_curString.stripWhiteSpace();
+ debug(2,"arggstring=%s\n",m_argsstring.data());
+}
+
+void MemberHandler::startParam(const QXmlAttributes& attrib)
+{
+ ParamHandler *paramHandler = new ParamHandler(this);
+ paramHandler->startParam(attrib);
+ if (m_insideTemplateParamList)
+ {
+ m_templateParams.append(paramHandler);
+ }
+ else
+ {
+ m_params.append(paramHandler);
+ }
+}
+
+void MemberHandler::startTemplateParamList(const QXmlAttributes&)
+{
+ m_insideTemplateParamList = TRUE;
+ m_hasTemplateParamList = TRUE;
+}
+
+void MemberHandler::endTemplateParamList()
+{
+ m_insideTemplateParamList = FALSE;
+}
+
+void MemberHandler::initialize(MainHandler *mh)
+{
+ {
+ QListIterator<MemberReference> mli(m_references);
+ MemberReference *mr;
+ for (;(mr=mli.current());++mli)
+ {
+ mr->initialize(mh);
+ }
+ }
+ {
+ QListIterator<MemberReference> mli(m_referencedBy);
+ MemberReference *mr;
+ for (;(mr=mli.current());++mli)
+ {
+ mr->initialize(mh);
+ }
+ }
+ {
+ QListIterator<MemberReference> mli(m_reimplementedBy);
+ MemberReference *mr;
+ for (;(mr=mli.current());++mli)
+ {
+ mr->initialize(mh);
+ }
+ }
+ if (m_reimplements) m_reimplements->initialize(mh);
+}
+
+void MemberHandler::setCompoundHandler(CompoundHandler *c)
+{
+ m_compound = c;
+}
+
+ICompound *MemberHandler::compound() const
+{
+ m_compound->addref();
+ return m_compound->toICompound();
+}
+
+void MemberHandler::setSectionHandler(SectionHandler *c)
+{
+ m_section = c;
+}
+
+ISection *MemberHandler::section() const
+{
+ return m_section;
+}
+
+IMemberIterator *MemberHandler::enumValues() const
+{
+ return new MemberIterator(m_enumValues);
+}
+
+ILinkedTextIterator *MemberHandler::type() const
+{
+ return new LinkedTextIterator(m_type);
+}
+
+const IString *MemberHandler::typeString() const
+{
+ MemberHandler *that = (MemberHandler *)this;
+ that->m_typeString = LinkedTextHandler::toString(m_type);
+ return &m_typeString;
+}
+
+IParamIterator *MemberHandler::parameters() const
+{
+ return new ParamIterator(m_params);
+}
+
+IParamIterator *MemberHandler::templateParameters() const
+{
+ return m_hasTemplateParamList ? new ParamIterator(m_templateParams) : 0;
+}
+
+IMemberReferenceIterator *MemberHandler::references() const
+{
+ return new MemberReferenceIterator(m_references);
+}
+
+IMemberReferenceIterator *MemberHandler::referencedBy() const
+{
+ return new MemberReferenceIterator(m_referencedBy);
+}
+
+ILinkedTextIterator *MemberHandler::initializer() const
+{
+ return new LinkedTextIterator(m_initializer);
+}
+
+ILinkedTextIterator *MemberHandler::exceptions() const
+{
+ return new LinkedTextIterator(m_exception);
+}
+
+IMemberReferenceIterator *MemberHandler::reimplementedBy() const
+{
+ return new MemberReferenceIterator(m_reimplementedBy);
+}
+
+IDocRoot *MemberHandler::briefDescription() const
+{
+ return m_brief;
+}
+
+IDocRoot *MemberHandler::detailedDescription() const
+{
+ return m_detailed;
+}
+
+IDocRoot *MemberHandler::inbodyDescription() const
+{
+ return m_inbody;
+}
+
diff --git a/addon/doxmlparser/src/memberhandler.h b/addon/doxmlparser/src/memberhandler.h
new file mode 100644
index 0000000..a84cc79
--- /dev/null
+++ b/addon/doxmlparser/src/memberhandler.h
@@ -0,0 +1,252 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MEMBERHANDLER_H
+#define _MEMBERHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+#include <doxmlintf.h>
+
+#include "basehandler.h"
+#include "baseiterator.h"
+#include "stringimpl.h"
+
+class MainHandler;
+class CompoundHandler;
+class SectionHandler;
+class ParamHandler;
+class LinkedTextImpl;
+class LinkedTextHandler;
+class DocHandler;
+
+class MemberReference : public IMemberReference
+{
+ public:
+ virtual ~MemberReference() {}
+ virtual IMember *member() const;
+ virtual const IString *name() const { return &m_name; }
+ virtual const IString *scope() const { return &m_scope; }
+ virtual const IString *protection() const { return &m_protection; }
+ virtual const IString *virtualness() const { return &m_virtualness; }
+ virtual const IString *ambiguityScope() const { return &m_ambiguityScope; }
+ void initialize(MainHandler *m);
+
+ QString m_memId;
+ StringImpl m_name;
+ StringImpl m_scope;
+ StringImpl m_virtualness;
+ StringImpl m_protection;
+ StringImpl m_ambiguityScope;
+ MainHandler *m_mainHandler;
+};
+
+class MemberReferenceIterator : public BaseIterator<IMemberReferenceIterator,IMemberReference,MemberReference>
+{
+ public:
+ MemberReferenceIterator(const QList<MemberReference> &list) :
+ BaseIterator<IMemberReferenceIterator,IMemberReference,MemberReference>(list) {}
+};
+
+class MemberHandler : public IDefine,
+ public IProperty,
+ public IVariable,
+ public ITypedef,
+ public IFunction,
+ public ISignal,
+ public IPrototype,
+ public IFriend,
+ public IDCOP,
+ public ISlot,
+ public IEnum,
+ public IEnumValue,
+ public BaseHandler<MemberHandler>
+{
+ public:
+ virtual void startMember(const QXmlAttributes& attrib);
+ virtual void endMember();
+ virtual void startParam(const QXmlAttributes& attrib);
+ virtual void startType(const QXmlAttributes& attrib);
+ virtual void startName(const QXmlAttributes& attrib);
+ virtual void endName();
+ virtual void startRead(const QXmlAttributes& attrib);
+ virtual void endRead();
+ virtual void startWrite(const QXmlAttributes& attrib);
+ virtual void endWrite();
+ virtual void startDefinition(const QXmlAttributes& attrib);
+ virtual void endDefinition();
+ virtual void startArgsString(const QXmlAttributes& attrib);
+ virtual void endArgsString();
+ virtual void startBriefDesc(const QXmlAttributes& attrib);
+ virtual void startDetailedDesc(const QXmlAttributes& attrib);
+ virtual void startInbodyDesc(const QXmlAttributes& attrib);
+ virtual void startLocation(const QXmlAttributes& attrib);
+ virtual void startReferences(const QXmlAttributes& attrib);
+ virtual void endReferences();
+ virtual void startReferencedBy(const QXmlAttributes& attrib);
+ virtual void endReferencedBy();
+ virtual void startReimplements(const QXmlAttributes& attrib);
+ virtual void endReimplements();
+ virtual void startReimplementedBy(const QXmlAttributes& attrib);
+ virtual void endReimplementedBy();
+ virtual void startInitializer(const QXmlAttributes& attrib);
+ virtual void startException(const QXmlAttributes& attrib);
+ virtual void startEnumValue(const QXmlAttributes& attrib);
+ virtual void startEnumValue2(const QXmlAttributes& attrib);
+ virtual void startTemplateParamList(const QXmlAttributes &attrib);
+ virtual void endTemplateParamList();
+
+ MemberHandler(IBaseHandler *parent);
+ virtual ~MemberHandler();
+
+ // IMember implementation
+ virtual ICompound *compound() const;
+ virtual ISection *section() const;
+ virtual MemberKind kind() const
+ { return m_kind; }
+ virtual const IString *kindString() const
+ { return &m_kindString; }
+ virtual const IString *id() const
+ { return &m_id; }
+ virtual const IString *protection() const
+ { return &m_protection; }
+ virtual const IString *virtualness() const
+ { return &m_virtualness; }
+ virtual const IString *name() const
+ { return &m_name; }
+ virtual const IString *readAccessor() const
+ { return &m_read; }
+ virtual const IString *writeAccessor() const
+ { return &m_write; }
+ virtual const IString *definition() const
+ { return &m_definition; }
+ virtual const IString *argsstring() const
+ { return &m_argsstring; }
+ virtual bool isConst() const
+ { return m_isConst; }
+ virtual bool isVolatile() const
+ { return m_isVolatile; }
+ virtual bool isStatic() const
+ { return m_isStatic; }
+ virtual bool isExplicit() const
+ { return m_isExplicit; }
+ virtual bool isInline() const
+ { return m_isInline; }
+ virtual bool isMutable() const
+ { return m_isMutable; }
+ virtual bool isReadable() const
+ { return m_isReadable; }
+ virtual bool isWritable() const
+ { return m_isWritable; }
+ virtual ILinkedTextIterator *type() const;
+ virtual const IString *typeString() const;
+ virtual IParamIterator *parameters() const;
+ virtual IParamIterator *templateParameters() const;
+ virtual IMemberReferenceIterator *references() const;
+ virtual IMemberReferenceIterator *referencedBy() const;
+ virtual ILinkedTextIterator *initializer() const;
+ virtual ILinkedTextIterator *exceptions() const;
+ virtual const IString *bodyFile() const
+ { return &m_bodyFile; }
+ virtual int bodyStart() const
+ { return m_bodyStart; }
+ virtual int bodyEnd() const
+ { return m_bodyEnd; }
+ virtual const IString *definitionFile() const
+ { return &m_defFile; }
+ virtual int definitionLine() const
+ { return m_defLine; }
+ virtual IMemberReference *reimplements() const
+ { return m_reimplements; }
+ virtual IMemberReferenceIterator *reimplementedBy() const;
+ virtual IDocRoot *briefDescription() const;
+ virtual IDocRoot *detailedDescription() const;
+ virtual IDocRoot *inbodyDescription() const;
+
+ // IEnum
+ virtual IMemberIterator *enumValues() const;
+
+ void initialize(MainHandler *m);
+ void setCompoundHandler(CompoundHandler *c);
+ void setSectionHandler(SectionHandler *s);
+
+ private:
+ // XML elements:
+ // -----------------
+ QList<ParamHandler> m_templateParams; // templateparamlist
+ QList<LinkedTextImpl> m_type; // type
+ StringImpl m_definition; // definition
+ StringImpl m_argsstring; // argsstring
+ StringImpl m_name; // name
+ StringImpl m_read; // read
+ StringImpl m_write; // write
+ MemberReference *m_reimplements; // reimplements
+ QList<MemberReference> m_reimplementedBy; // reimplementedby
+ QList<ParamHandler> m_params; // param
+ QList<MemberHandler> m_enumValues; // enumvalue
+ QList<LinkedTextImpl> m_initializer; // initializer
+ QList<LinkedTextImpl> m_exception; // exceptions
+ DocHandler *m_brief; // briefdescription
+ DocHandler *m_detailed; // detaileddescription
+ DocHandler *m_inbody; // inbodydescription
+ // location
+ StringImpl m_defFile; // - file
+ int m_defLine; // - line
+ StringImpl m_bodyFile; // - bodyfile
+ int m_bodyStart; // - bodystart
+ int m_bodyEnd; // - bodyend
+ QList<MemberReference> m_references; // references
+ QList<MemberReference> m_referencedBy; // referencedby
+
+ // XML attributes:
+ // ---------------
+ MemberKind m_kind; // kind
+ StringImpl m_kindString; // kind as a string
+ StringImpl m_id; // id
+ StringImpl m_protection; // prot
+ bool m_isStatic; // static
+ bool m_isConst; // const
+ bool m_isExplicit; // explicit
+ bool m_isInline; // inline
+ StringImpl m_virtualness; // virt
+ bool m_isVolatile; // volatile
+ bool m_isMutable; // mutable
+ bool m_isReadable; // readable
+ bool m_isWritable; // writable
+
+ CompoundHandler *m_compound;
+ SectionHandler *m_section;
+ StringImpl m_typeString;
+ LinkedTextHandler *m_linkedTextHandler;
+ bool m_insideTemplateParamList;
+ bool m_hasTemplateParamList;
+ IBaseHandler *m_parent;
+};
+
+class MemberIterator : public BaseIteratorVia<IMemberIterator,
+ IMember,
+ MemberHandler,
+ IFunction>
+{
+ public:
+ MemberIterator(const QList<MemberHandler> &list) :
+ BaseIteratorVia<IMemberIterator,IMember,MemberHandler,IFunction>(list) {}
+};
+
+void memberhandler_init();
+void memberhandler_exit();
+
+#endif
diff --git a/addon/doxmlparser/src/paramhandler.cpp b/addon/doxmlparser/src/paramhandler.cpp
new file mode 100644
index 0000000..e6d3db1
--- /dev/null
+++ b/addon/doxmlparser/src/paramhandler.cpp
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "paramhandler.h"
+#include "memberhandler.h"
+#include "linkedtexthandler.h"
+#include "debug.h"
+#include "dochandler.h"
+
+TemplateParamListHandler::TemplateParamListHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ addStartHandler("param",this,&TemplateParamListHandler::startParam);
+
+ addEndHandler("templateparamlist",this,&TemplateParamListHandler::endTemplateParamList);
+}
+
+void TemplateParamListHandler::startParam(const QXmlAttributes& attrib)
+{
+ ParamHandler *ph = new ParamHandler(this);
+ ph->startParam(attrib);
+ m_templateParams.append(ph);
+}
+
+void TemplateParamListHandler::endParam()
+{
+}
+
+void TemplateParamListHandler::startTemplateParamList(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"templateparamlist\n");
+}
+
+void TemplateParamListHandler::endTemplateParamList()
+{
+ m_parent->setDelegate(0);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ParamHandler::ParamHandler(IBaseHandler *parent) : m_brief(0), m_parent(parent)
+{
+ addEndHandler("param",this,&ParamHandler::endParam);
+
+ addStartHandler("type",this,&ParamHandler::startType);
+
+ addStartHandler("declname");
+ addEndHandler("declname",this,&ParamHandler::endDeclName);
+
+ addStartHandler("defname");
+ addEndHandler("defname",this,&ParamHandler::endDefName);
+
+ addStartHandler("array");
+ addEndHandler("array",this,&ParamHandler::endArray);
+
+ addStartHandler("attribute");
+ addEndHandler("attribute",this,&ParamHandler::endAttrib);
+
+ addStartHandler("briefdescription",this,&ParamHandler::startBriefDesc);
+
+ addStartHandler("defval",this,&ParamHandler::startDefVal);
+
+ m_linkedTextHandler = 0;
+}
+
+ParamHandler::~ParamHandler()
+{
+ delete m_brief;
+ delete m_linkedTextHandler;
+}
+
+void ParamHandler::startParam(const QXmlAttributes& /*attrib*/)
+{
+ m_parent->setDelegate(this);
+ debug(2,"param\n");
+}
+
+void ParamHandler::endParam()
+{
+ m_parent->setDelegate(0);
+}
+
+void ParamHandler::startType(const QXmlAttributes& /*attrib*/)
+{
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_type);
+ m_linkedTextHandler->start("type");
+ debug(2,"param type\n");
+}
+
+void ParamHandler::endDeclName()
+{
+ m_declName = m_curString.stripWhiteSpace();
+ debug(2,"member declName=`%s'\n",m_declName.data());
+}
+
+void ParamHandler::endDefName()
+{
+ m_defName = m_curString.stripWhiteSpace();
+ debug(2,"member defName=`%s'\n",m_defName.data());
+}
+
+void ParamHandler::endAttrib()
+{
+ m_attrib = m_curString.stripWhiteSpace();
+ debug(2,"member attrib=`%s'\n",m_attrib.data());
+}
+
+void ParamHandler::endArray()
+{
+ m_array = m_curString.stripWhiteSpace();
+ debug(2,"member array=`%s'\n",m_array.data());
+}
+
+void ParamHandler::startDefVal(const QXmlAttributes& /*attrib*/)
+{
+ delete m_linkedTextHandler;
+ m_linkedTextHandler = new LinkedTextHandler(this,m_defVal);
+ m_linkedTextHandler->start("defval");
+ debug(2,"member defVal\n");
+}
+
+void ParamHandler::startBriefDesc(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_brief = docHandler;
+}
+
+ILinkedTextIterator *ParamHandler::type() const
+{
+ return new LinkedTextIterator(m_type);
+}
+
+ILinkedTextIterator *ParamHandler::defaultValue() const
+{
+ return new LinkedTextIterator(m_defVal);
+}
+
+IDocRoot *ParamHandler::briefDescription() const
+{
+ return m_brief;
+}
+
+
+
diff --git a/addon/doxmlparser/src/paramhandler.h b/addon/doxmlparser/src/paramhandler.h
new file mode 100644
index 0000000..7ecf711
--- /dev/null
+++ b/addon/doxmlparser/src/paramhandler.h
@@ -0,0 +1,103 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _PARAMHANDLER_H
+#define _PARAMHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+#include <doxmlintf.h>
+
+#include "stringimpl.h"
+#include "basehandler.h"
+#include "baseiterator.h"
+
+class LinkedTextImpl;
+class LinkedTextHandler;
+class DocHandler;
+
+
+class ParamHandler : public IParam, public BaseHandler<ParamHandler>
+{
+ public:
+ virtual void startParam(const QXmlAttributes& attrib);
+ virtual void endParam();
+ virtual void startType(const QXmlAttributes& attrib);
+ virtual void endDeclName();
+ virtual void endDefName();
+ virtual void endAttrib();
+ virtual void endArray();
+ virtual void startDefVal(const QXmlAttributes& attrib);
+ virtual void startBriefDesc(const QXmlAttributes& attrib);
+
+ ParamHandler(IBaseHandler *parent);
+ virtual ~ParamHandler();
+
+ // IParam
+ virtual ILinkedTextIterator *type() const;
+ virtual const IString * declarationName() const { return &m_declName; }
+ virtual const IString * definitionName() const { return &m_defName; }
+ virtual const IString * attrib() const { return &m_attrib; }
+ virtual const IString * arraySpecifier() const { return &m_array; }
+ virtual ILinkedTextIterator *defaultValue() const;
+ virtual IDocRoot *briefDescription() const;
+
+ private:
+
+ // XML elements:
+ // -------------
+ QList<LinkedTextImpl> m_type; // type
+ StringImpl m_declName; // declname
+ StringImpl m_defName; // defname
+ StringImpl m_array; // array
+ QList<LinkedTextImpl> m_defVal; // defval
+ DocHandler *m_brief; // briefdescription
+
+ StringImpl m_attrib; // TODO: not yet in XML output
+
+ IBaseHandler *m_parent;
+ LinkedTextHandler *m_linkedTextHandler;
+};
+
+class ParamIterator : public BaseIterator<IParamIterator,IParam,ParamHandler>
+{
+ public:
+ ParamIterator(const QList<ParamHandler> &list) :
+ BaseIterator<IParamIterator,IParam,ParamHandler>(list) {}
+};
+
+class TemplateParamListHandler : public BaseHandler<TemplateParamListHandler>
+{
+ public:
+
+ virtual void startParam(const QXmlAttributes& attrib);
+ virtual void endParam();
+
+ virtual void startTemplateParamList(const QXmlAttributes& attrib);
+ virtual void endTemplateParamList();
+
+ TemplateParamListHandler(IBaseHandler *parent);
+ virtual ~TemplateParamListHandler() {}
+
+ ParamIterator* templateParams() { return new ParamIterator(m_templateParams); }
+
+ protected:
+ IBaseHandler *m_parent;
+ QList<ParamHandler> m_templateParams;
+};
+
+
+#endif
diff --git a/addon/doxmlparser/src/sectionhandler.cpp b/addon/doxmlparser/src/sectionhandler.cpp
new file mode 100644
index 0000000..bb43925
--- /dev/null
+++ b/addon/doxmlparser/src/sectionhandler.cpp
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "mainhandler.h"
+#include "compoundhandler.h"
+#include "sectionhandler.h"
+#include "memberhandler.h"
+#include "dochandler.h"
+#include "debug.h"
+
+class SectionTypeMap
+{
+ public:
+ SectionTypeMap() : m_map(37)
+ {
+ m_map.setAutoDelete(TRUE);
+ m_map.insert("user-defined",new int(ISection::UserDefined));
+ m_map.insert("public-type",new int(ISection::PubTypes));
+ m_map.insert("public-func",new int(ISection::PubFuncs));
+ m_map.insert("public-attrib",new int(ISection::PubAttribs));
+ m_map.insert("public-slot",new int(ISection::PubSlots));
+ m_map.insert("signal",new int(ISection::Signals));
+ m_map.insert("dcop-func",new int(ISection::DCOPFuncs));
+ m_map.insert("property",new int(ISection::Properties));
+ m_map.insert("event",new int(ISection::Events));
+ m_map.insert("public-static-func",new int(ISection::PubStatFuncs));
+ m_map.insert("public-static-attrib",new int(ISection::PubStatAttribs));
+ m_map.insert("protected-type",new int(ISection::ProTypes));
+ m_map.insert("protected-func",new int(ISection::ProFuncs));
+ m_map.insert("protected-attrib",new int(ISection::ProAttribs));
+ m_map.insert("protected-slot",new int(ISection::ProSlots));
+ m_map.insert("protected-static-func",new int(ISection::ProStatFuncs));
+ m_map.insert("protected-static-attrib",new int(ISection::ProStatAttribs));
+ m_map.insert("package-type",new int(ISection::PacTypes));
+ m_map.insert("package-func",new int(ISection::PacFuncs));
+ m_map.insert("package-attrib",new int(ISection::PacAttribs));
+ m_map.insert("package-static-func",new int(ISection::PacStatFuncs));
+ m_map.insert("package-static-attrib",new int(ISection::PacStatAttribs));
+ m_map.insert("private-type",new int(ISection::PriTypes));
+ m_map.insert("private-func",new int(ISection::PriFuncs));
+ m_map.insert("private-attrib",new int(ISection::PriAttribs));
+ m_map.insert("private-slot",new int(ISection::PriSlots));
+ m_map.insert("private-static-func",new int(ISection::PriStatFuncs));
+ m_map.insert("private-static-attrib",new int(ISection::PriStatAttribs));
+ m_map.insert("friend",new int(ISection::Friend));
+ m_map.insert("related",new int(ISection::Related));
+ m_map.insert("define",new int(ISection::Defines));
+ m_map.insert("prototype",new int(ISection::Prototypes));
+ m_map.insert("typedef",new int(ISection::Typedefs));
+ m_map.insert("enum",new int(ISection::Enums));
+ m_map.insert("func",new int(ISection::Functions));
+ m_map.insert("var",new int(ISection::Variables));
+ }
+ ISection::SectionKind map(const QString &s)
+ {
+ int *val = m_map.find(s.utf8());
+ if (val==0)
+ {
+ debug(1,"Warning: `%s' is an invalid section type\n",s.data());
+ return ISection::Invalid;
+ }
+ else return (ISection::SectionKind)*val;
+ }
+ private:
+ QDict<int> m_map;
+};
+
+static SectionTypeMap *s_typeMap;
+
+void sectionhandler_init()
+{
+ s_typeMap = new SectionTypeMap;
+}
+
+void sectionhandler_exit()
+{
+ delete s_typeMap;
+}
+
+SectionHandler::SectionHandler(IBaseHandler *parent) : m_parent(parent)
+{
+ //printf("SectionHandler::SectionHandler()\n");
+ m_members.setAutoDelete(TRUE);
+ addEndHandler("sectiondef",this,&SectionHandler::endSection);
+ addStartHandler("memberdef",this,&SectionHandler::startMember);
+ addStartHandler("header",this,&SectionHandler::startHeader);
+ addEndHandler("header",this,&SectionHandler::endHeader);
+ addStartHandler("description",this,&SectionHandler::startDescription);
+}
+
+SectionHandler::~SectionHandler()
+{
+ debug(2,"SectionHandler::~SectionHandler()\n");
+}
+
+void SectionHandler::startSection(const QXmlAttributes& attrib)
+{
+ m_parent->setDelegate(this);
+ m_kindString = attrib.value("kind");
+ m_kind = s_typeMap->map(m_kindString);
+ debug(2,"section kind=`%s'\n",m_kindString.data());
+}
+
+void SectionHandler::startDescription(const QXmlAttributes& attrib)
+{
+ DocHandler *docHandler = new DocHandler(this);
+ docHandler->startDoc(attrib);
+ m_description = docHandler;
+}
+
+void SectionHandler::endSection()
+{
+ m_parent->setDelegate(0);
+}
+
+void SectionHandler::startMember(const QXmlAttributes& attrib)
+{
+ MemberHandler *memHandler = new MemberHandler(this);
+ memHandler->startMember(attrib);
+ m_members.append(memHandler);
+}
+
+void SectionHandler::startHeader(const QXmlAttributes&)
+{
+ m_header="";
+ m_curString="";
+}
+
+void SectionHandler::endHeader()
+{
+ m_header = m_curString.stripWhiteSpace();
+ debug(2,"member header=`%s'\n",m_header.data());
+}
+
+void SectionHandler::initialize(CompoundHandler *ch)
+{
+ QListIterator<MemberHandler> mli(m_members);
+ MemberHandler *mh;
+ for (;(mh=mli.current());++mli)
+ {
+ mh->setCompoundHandler(ch);
+ ch->insertMember(mh);
+ mh->setSectionHandler(this);
+ }
+}
+
+IDocRoot *SectionHandler::description() const
+{
+ return m_description;
+}
+
+IMemberIterator *SectionHandler::members() const
+{
+ return new MemberIterator(m_members);
+}
+
diff --git a/addon/doxmlparser/src/sectionhandler.h b/addon/doxmlparser/src/sectionhandler.h
new file mode 100644
index 0000000..2730307
--- /dev/null
+++ b/addon/doxmlparser/src/sectionhandler.h
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SECTIONHANDLER_H
+#define _SECTIONHANDLER_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+#include <doxmlintf.h>
+
+#include "basehandler.h"
+
+class SectionIterator :
+ public BaseIterator<ISectionIterator,ISection,SectionHandler>
+{
+ public:
+ SectionIterator(const QList<SectionHandler> &list) :
+ BaseIterator<ISectionIterator,ISection,SectionHandler>(list) {}
+};
+
+
+class SectionHandler : public IUserDefined, public BaseHandler<SectionHandler>
+{
+ public:
+ virtual void startMember(const QXmlAttributes& attrib);
+ virtual void startHeader(const QXmlAttributes& attrib);
+ virtual void startSection(const QXmlAttributes& attrib);
+ virtual void startDescription(const QXmlAttributes& attrib);
+ virtual void endSection();
+ virtual void endHeader();
+
+ SectionHandler(IBaseHandler *parent);
+ virtual ~SectionHandler();
+
+ // ISection
+ virtual const IString *kindString() const
+ { return &m_kindString; }
+ virtual SectionKind kind() const
+ { return m_kind; }
+ IDocRoot *description() const;
+ virtual IMemberIterator *members() const;
+ virtual bool isStatic() const
+ {
+ return m_kind==PubStatFuncs || m_kind==PubStatAttribs ||
+ m_kind==ProStatFuncs || m_kind==ProStatAttribs ||
+ m_kind==PriStatFuncs || m_kind==PriStatAttribs;
+ }
+ virtual bool isPublic() const
+ {
+ return !isProtected() && !isPrivate();
+ }
+ virtual bool isProtected() const
+ {
+ return m_kind==ProTypes || m_kind==ProFuncs || m_kind==ProAttribs ||
+ m_kind==ProSlots || m_kind==ProStatFuncs || m_kind==ProStatAttribs;
+ }
+ virtual bool isPrivate() const
+ {
+ return m_kind==PriTypes || m_kind==PriFuncs || m_kind==PriAttribs ||
+ m_kind==PriSlots || m_kind==PriStatFuncs || m_kind==PriStatAttribs;
+ }
+
+ void initialize(CompoundHandler *c);
+
+ // IUserDefined implementation
+ virtual const IString *header() const
+ {
+ return &m_header;
+ }
+
+ private:
+ IBaseHandler *m_parent;
+
+ // XML elements:
+ // -------------
+ StringImpl m_header; // header
+ DocHandler* m_description; // description
+ QList<MemberHandler> m_members; // memberdef
+
+ // XML attributes:
+ // ---------------
+ SectionKind m_kind; // kind
+ StringImpl m_kindString; // kind as a string
+};
+
+void sectionhandler_init();
+void sectionhandler_exit();
+
+#endif
diff --git a/addon/doxmlparser/src/stringimpl.h b/addon/doxmlparser/src/stringimpl.h
new file mode 100644
index 0000000..013858f
--- /dev/null
+++ b/addon/doxmlparser/src/stringimpl.h
@@ -0,0 +1,30 @@
+#ifndef STRINGIMPL_H
+#define STRINGIMPL_H
+
+#include <qstring.h>
+#include "doxmlintf.h"
+
+class StringImpl : public QString, public IString
+{
+ public:
+ StringImpl() {}
+ StringImpl(const QString &str) : QString(str) {}
+ StringImpl &operator=(const QString &str)
+ { QString::operator=(str); return *this; }
+ virtual ~StringImpl() {}
+
+ // IString
+ const char *latin1() const
+ { return QString::latin1(); }
+ const char *utf8() const
+ { return QString::utf8(); }
+ unsigned short unicodeCharAt(int index) const
+ { return QString::unicode()[index].unicode(); }
+ bool isEmpty() const
+ { return QString::isEmpty(); }
+ int length() const
+ { return QString::length(); }
+};
+
+#endif
+
diff --git a/addon/doxmlparser/test/Makefile b/addon/doxmlparser/test/Makefile
new file mode 100644
index 0000000..ec3c5ba
--- /dev/null
+++ b/addon/doxmlparser/test/Makefile
@@ -0,0 +1,37 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+all clean depend: Makefile.xmlparse
+ $(MAKE) -f Makefile.xmlparse $@
+
+distclean: clean
+ $(RM) -rf Makefile.xmlparse xmlparse.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) xmlparse.pro >Makefile.xmlparse
+
+Makefile.xmlparse: xmlparse.pro
+ $(ENV) $(PERL) $(TMAKE) xmlparse.pro >Makefile.xmlparse
+
+install:
diff --git a/addon/doxmlparser/test/Makefile.in b/addon/doxmlparser/test/Makefile.in
new file mode 100644
index 0000000..87b1829
--- /dev/null
+++ b/addon/doxmlparser/test/Makefile.in
@@ -0,0 +1,15 @@
+all clean depend: Makefile.xmlparse
+ $(MAKE) -f Makefile.xmlparse $@
+
+distclean: clean
+ $(RM) -rf Makefile.xmlparse xmlparse.pro Makefile obj
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) $(TMAKE) xmlparse.pro >Makefile.xmlparse
+
+Makefile.xmlparse: xmlparse.pro
+ $(ENV) $(PERL) $(TMAKE) xmlparse.pro >Makefile.xmlparse
+
+install:
diff --git a/addon/doxmlparser/test/Makefile.xmlparse b/addon/doxmlparser/test/Makefile.xmlparse
new file mode 100644
index 0000000..b219a97
--- /dev/null
+++ b/addon/doxmlparser/test/Makefile.xmlparse
@@ -0,0 +1,77 @@
+#############################################################################
+# Makefile for building ../../../bin/xmlparse
+# Generated by tmake at 10:48, 2014/08/21
+# Project: xmlparse
+# Template: app.t
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I../../../qtools -I../include -I/opt/local/include
+LINK = c++
+LFLAGS = -Wl,-search_paths_first
+LIBS = -L../../../lib -ldoxmlparser -lqtools -L/opt/local/lib -liconv -framework CoreServices
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS =
+SOURCES = main.cpp
+OBJECTS = ../../../objects/doxmlparser/test/main.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../../../bin/xmlparse
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) ../../../lib/libdoxmlparser.a
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake xmlparse.pro
+
+dist:
+ $(TAR) xmlparse.tar xmlparse.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) xmlparse.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../../../objects/doxmlparser/test/main.o: main.cpp \
+ ../include/doxmlintf.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../../objects/doxmlparser/test/main.o main.cpp
+
diff --git a/addon/doxmlparser/test/main.cpp b/addon/doxmlparser/test/main.cpp
new file mode 100644
index 0000000..5f37c81
--- /dev/null
+++ b/addon/doxmlparser/test/main.cpp
@@ -0,0 +1,759 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ *
+ * Copyright (C) 1997-2006 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <doxmlintf.h>
+#include <qstring.h>
+
+/*! Dumps the contents of a hyperlinked text fragment as plain text to the
+ * output.
+ */
+QString linkedTextToString(ILinkedTextIterator *ti)
+{
+ QString result;
+ ILinkedText *lt=0;
+ for (ti->toFirst();(lt=ti->current());ti->toNext())
+ {
+ switch (lt->kind())
+ {
+ case ILinkedText::Kind_Text: // plain text
+ result+=dynamic_cast<ILT_Text*>(lt)->text()->latin1(); break;
+ case ILinkedText::Kind_Ref: // a link
+ result+=dynamic_cast<ILT_Ref *>(lt)->text()->latin1(); break;
+ }
+ }
+ return result;
+}
+
+/*! Macro for printing an indented message. */
+#define InPrint(x) printf("%s",indent.latin1()), printf x;
+
+/*! Dumps the contents of a documentation block to stdout.
+ * @note This function will call itself recursively.
+ * @param doc The root of the documentation tree.
+ * @param level The indent level.
+ */
+void DumpDoc(IDoc *doc,int level)
+{
+ if (doc==0) return;
+ QString indent;
+ indent.fill(' ',level);
+ //printf(" doc node kind=`%d'\n",doc->kind());
+ switch (doc->kind())
+ {
+ case IDoc::Para:
+ {
+ InPrint(("<para>\n"));
+ IDocPara *par = dynamic_cast<IDocPara*>(doc);
+ ASSERT(par!=0);
+ IDocIterator *di = par->contents();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</para>\n"));
+ }
+ break;
+ case IDoc::Text:
+ {
+ IDocText *txt = dynamic_cast<IDocText*>(doc);
+ ASSERT(txt!=0);
+ InPrint(("<text value=`%s' markup=%d headingLevel=%d/>\n",
+ txt->text()->latin1(),txt->markup(),txt->headingLevel()));
+ }
+ break;
+ case IDoc::MarkupModifier:
+ {
+ IDocMarkupModifier *md = dynamic_cast<IDocMarkupModifier*>(doc);
+ ASSERT(md!=0);
+ InPrint(("<markup modifier enabled=%d markup=%d headingLevel=%d/>\n",
+ md->enabled(),md->markup(),md->headingLevel()));
+ }
+ break;
+ case IDoc::ItemizedList:
+ {
+ InPrint(("<itemized list>\n"));
+ IDocItemizedList *list = dynamic_cast<IDocItemizedList*>(doc);
+ ASSERT(list!=0);
+ IDocIterator *di = list->elements();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</itemized list>\n"));
+ }
+ break;
+ case IDoc::OrderedList:
+ {
+ InPrint(("<ordered list>\n"));
+ IDocOrderedList *list = dynamic_cast<IDocOrderedList*>(doc);
+ ASSERT(list!=0);
+ IDocIterator *di = list->elements();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</ordered list>\n"));
+ }
+ break;
+ case IDoc::ListItem:
+ {
+ InPrint(("<list item>\n"));
+ IDocListItem *li = dynamic_cast<IDocListItem*>(doc);
+ ASSERT(li!=0);
+ IDocIterator *di = li->contents();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</list item>\n"));
+ }
+ break;
+ case IDoc::ParameterItem:
+ {
+ IDocParameterItem *item = dynamic_cast<IDocParameterItem*>(doc);
+ InPrint(("<parameter item>\n"));
+ IDocIterator *di = item->paramNames();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ DumpDoc(item->description(),level+1);
+ InPrint(("</parameter item>\n"));
+ }
+ break;
+ case IDoc::ParameterList:
+ {
+ IDocParameterList *list = dynamic_cast<IDocParameterList*>(doc);
+ InPrint(("<parameter list type=%d>\n",list->sectType()));
+ IDocIterator *di = list->params();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</parameter list>\n"));
+ ASSERT(list!=0);
+ }
+ break;
+ case IDoc::Parameter:
+ {
+ IDocParameter *par = dynamic_cast<IDocParameter*>(doc);
+ ASSERT(par!=0);
+ InPrint(("<parameter name=%s/>\n",par->name()->latin1()));
+ }
+ break;
+ case IDoc::SimpleSect:
+ {
+ IDocSimpleSect *ss = dynamic_cast<IDocSimpleSect*>(doc);
+ ASSERT(ss!=0);
+ InPrint(("<simplesect type=%s>\n",ss->typeString()->latin1()));
+ DumpDoc(ss->title(),level+1);
+ DumpDoc(ss->description(),level+1);
+ InPrint(("<simplesect/>\n"));
+ }
+ break;
+ case IDoc::Title:
+ {
+ InPrint(("<title>\n"));
+ IDocTitle *t = dynamic_cast<IDocTitle*>(doc);
+ ASSERT(t!=0);
+ IDocIterator *di = t->title();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ InPrint(("<title/>\n"));
+ }
+ break;
+ case IDoc::Ref:
+ {
+ IDocRef *ref = dynamic_cast<IDocRef*>(doc);
+ ASSERT(ref!=0);
+ InPrint(("<ref id=%s text=%s/>\n",
+ ref->refId()->latin1(),ref->text()->latin1()));
+ }
+ break;
+ case IDoc::VariableList:
+ {
+ InPrint(("<variablelist>\n"));
+ IDocVariableList *vl = dynamic_cast<IDocVariableList*>(doc);
+ ASSERT(vl!=0);
+ IDocIterator *di = vl->entries();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("<variablelist/>\n"));
+ }
+ break;
+ case IDoc::VariableListEntry:
+ {
+ IDocVariableListEntry *vle = dynamic_cast<IDocVariableListEntry*>(doc);
+ ASSERT(vle!=0);
+ ILinkedTextIterator *lti = vle->term();
+ QString term = linkedTextToString(lti);
+ lti->release();
+ InPrint(("<variablelistentry term=%s>\n",term.latin1()));
+ DumpDoc(vle->description(),level+1);
+ InPrint(("<variablelistentry/>\n"));
+ }
+ break;
+ case IDoc::HRuler:
+ {
+ IDocHRuler *hr = dynamic_cast<IDocHRuler*>(doc);
+ ASSERT(hr!=0);
+ InPrint(("<hruler/>\n"));
+ }
+ break;
+ case IDoc::LineBreak:
+ {
+ IDocLineBreak *lb = dynamic_cast<IDocLineBreak*>(doc);
+ ASSERT(lb!=0);
+ InPrint(("<linebreak/>\n"));
+ }
+ break;
+ case IDoc::ULink:
+ {
+ IDocULink *ul = dynamic_cast<IDocULink*>(doc);
+ ASSERT(ul!=0);
+ InPrint(("<ulink url=`%s' text=`%s'/>\n",ul->url()->latin1(),ul->text()->latin1()));
+ }
+ break;
+ case IDoc::EMail:
+ {
+ IDocEMail *em = dynamic_cast<IDocEMail*>(doc);
+ ASSERT(em!=0);
+ InPrint(("<email address=`%s'/>\n",em->address()->latin1()));
+ }
+ break;
+ case IDoc::Link:
+ {
+ IDocLink *lk = dynamic_cast<IDocLink*>(doc);
+ ASSERT(lk!=0);
+ InPrint(("<link refid=`%s' text=`%s'/>\n",lk->refId()->latin1(),lk->text()->latin1()));
+ }
+ break;
+ case IDoc::ProgramListing:
+ {
+ IDocProgramListing *pl = dynamic_cast<IDocProgramListing*>(doc);
+ ASSERT(pl!=0);
+ InPrint(("<programlisting>\n"));
+ IDocIterator *cli = pl->codeLines();
+ IDoc *cl;
+ for (cli->toFirst();(cl=cli->current());cli->toNext())
+ {
+ DumpDoc(cl,level+1);
+ }
+ cli->release();
+ InPrint(("</programlisting>\n"));
+ }
+ break;
+ case IDoc::CodeLine:
+ {
+ IDocCodeLine *cl = dynamic_cast<IDocCodeLine*>(doc);
+ ASSERT(cl!=0);
+ InPrint(("<codeline lineNumber=%d refId=`%s'>\n",cl->lineNumber(),cl->refId()->latin1()));
+ IDocIterator *cei = cl->codeElements();
+ IDoc *ce;
+ for (cei->toFirst();(ce=cei->current());cei->toNext())
+ {
+ DumpDoc(ce,level+1);
+ }
+ cei->release();
+ InPrint(("</codeline>\n"));
+ }
+ break;
+ case IDoc::Highlight:
+ {
+ IDocHighlight *hl = dynamic_cast<IDocHighlight*>(doc);
+ ASSERT(hl!=0);
+ InPrint(("<highlight kind=%d>\n",hl->kind()));
+ IDocIterator *cei = hl->codeElements();
+ IDoc *ce;
+ for (cei->toFirst();(ce=cei->current());cei->toNext())
+ {
+ DumpDoc(ce,level+1);
+ }
+ cei->release();
+ InPrint(("</highlight>\n"));
+ }
+ break;
+ case IDoc::Formula:
+ {
+ IDocFormula *fm = dynamic_cast<IDocFormula*>(doc);
+ ASSERT(fm!=0);
+ InPrint(("<formula id=`%s' text=`%s'/>\n",fm->id()->latin1(),fm->text()->latin1()));
+ }
+ break;
+ case IDoc::Image:
+ {
+ IDocImage *img = dynamic_cast<IDocImage*>(doc);
+ ASSERT(img!=0);
+ InPrint(("<image name=`%s' caption=`%s'/>\n",img->name()->latin1(),img->caption()->latin1()));
+ }
+ break;
+ case IDoc::DotFile:
+ {
+ IDocDotFile *df = dynamic_cast<IDocDotFile*>(doc);
+ ASSERT(df!=0);
+ InPrint(("<dotfile name=`%s' caption=`%s'/>\n",df->name()->latin1(),df->caption()->latin1()));
+ }
+ break;
+ case IDoc::IndexEntry:
+ {
+ IDocIndexEntry *ie = dynamic_cast<IDocIndexEntry*>(doc);
+ ASSERT(ie!=0);
+ InPrint(("<indexentry primary=`%s' secondary=`%s'/>\n",ie->primary()->latin1(),ie->secondary()->latin1()));
+ }
+ break;
+ case IDoc::Table:
+ {
+ IDocTable *tbl = dynamic_cast<IDocTable*>(doc);
+ ASSERT(tbl!=0);
+ InPrint(("<table numcols=%d caption=`%s'>\n",tbl->numColumns(),tbl->caption()->latin1()));
+ IDocIterator *ri = tbl->rows();
+ IDoc *row;
+ for (ri->toFirst();(row=ri->current());ri->toNext())
+ {
+ DumpDoc(row,level+1);
+ }
+ ri->release();
+ InPrint(("</table>\n"));
+ }
+ break;
+ case IDoc::Row:
+ {
+ IDocRow *row = dynamic_cast<IDocRow*>(doc);
+ ASSERT(row!=0);
+ InPrint(("<row>\n"));
+ IDocIterator *ei = row->entries();
+ IDoc *e;
+ for (ei->toFirst();(e=ei->current());ei->toNext())
+ {
+ DumpDoc(e,level+1);
+ }
+ ei->release();
+ InPrint(("</row>\n"));
+ }
+ break;
+ case IDoc::Entry:
+ {
+ IDocEntry *ent = dynamic_cast<IDocEntry*>(doc);
+ ASSERT(ent!=0);
+ InPrint(("<entry>\n"));
+ IDocIterator *di = ent->contents();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</entry>\n"));
+ }
+ break;
+ case IDoc::Section:
+ {
+ IDocSection *sec = dynamic_cast<IDocSection*>(doc);
+ ASSERT(sec!=0);
+ InPrint(("<section id=`%s' level=%d>\n",
+ sec->id()->latin1(),sec->level()));
+ DumpDoc(sec->title(),level+1);
+ IDocIterator *di = sec->paragraphs();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di=sec->subSections();
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ IDocInternal *intern = sec->internal();
+ if (intern)
+ {
+ DumpDoc(intern,level+1);
+ }
+ InPrint(("</section>\n"));
+ }
+ break;
+ case IDoc::Internal:
+ {
+ IDocInternal *intern = dynamic_cast<IDocInternal*>(doc);
+ ASSERT(intern!=0);
+ InPrint(("<internal>\n"));
+ IDocIterator *di = intern->paragraphs();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di=intern->subSections();
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ InPrint(("</internal>\n"));
+ }
+ break;
+ case IDoc::Copy:
+ {
+ IDocCopy *cpy = dynamic_cast<IDocCopy*>(doc);
+ ASSERT(cpy!=0);
+ InPrint(("<copydoc>\n"));
+ IDocIterator *di = cpy->contents();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("<copydoc/>\n"));
+ }
+ break;
+ case IDoc::TocItem:
+ {
+ IDocTocItem *ti = dynamic_cast<IDocTocItem*>(doc);
+ ASSERT(ti!=0);
+ InPrint(("<tocitem id=\"%s\" title=\"%s\"/>\n",
+ ti->id()->latin1(),ti->title()->latin1()));
+ }
+ break;
+ case IDoc::TocList:
+ {
+ IDocTocList *tl = dynamic_cast<IDocTocList*>(doc);
+ ASSERT(tl!=0);
+ InPrint(("<toclist>\n"));
+ IDocIterator *di = tl->elements();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("<toclist/>\n"));
+ }
+ break;
+ case IDoc::Verbatim:
+ {
+ IDocVerbatim *vt = dynamic_cast<IDocVerbatim*>(doc);
+ ASSERT(vt!=0);
+ const char *s=0;
+ switch (vt->type())
+ {
+ case IDocVerbatim::Verbatim: s="verbatim"; break;
+ case IDocVerbatim::HtmlOnly: s="htmlonly"; break;
+ case IDocVerbatim::LatexOnly: s="latexonly"; break;
+ default:
+ printf("Invalid verbatim type!\n");
+ }
+ InPrint(("<verbatim %s>\n",s));
+ InPrint(("%s",vt->text()->latin1()));
+ InPrint(("</verbatim>\n"));
+ }
+ break;
+ case IDoc::Anchor:
+ {
+ IDocAnchor *anc = dynamic_cast<IDocAnchor*>(doc);
+ ASSERT(anc!=0);
+ InPrint(("<anchor id='%s'/>\n",anc->id()->latin1()));
+ }
+ break;
+ case IDoc::Symbol:
+ {
+ IDocSymbol *sym = dynamic_cast<IDocSymbol*>(doc);
+ ASSERT(sym!=0);
+ InPrint(("<symbol type=%s letter=%c/>\n",
+ sym->typeString()->latin1(),sym->letter()));
+ }
+ break;
+ case IDoc::Root:
+ {
+ InPrint(("<root>\n"));
+ IDocRoot *root = dynamic_cast<IDocRoot*>(doc);
+ ASSERT(root!=0);
+ IDocIterator *di = root->contents();
+ IDoc *pdoc;
+ for (di->toFirst();(pdoc=di->current());di->toNext())
+ {
+ DumpDoc(pdoc,level+1);
+ }
+ di->release();
+ InPrint(("</root>\n"));
+ }
+ break;
+
+ default:
+ printf("Found unsupported node type %d!\n",doc->kind());
+ break;
+ }
+}
+
+void DumpGraph(IGraph *graph)
+{
+ if (graph==0) { printf(" --- no graph ---\n"); return; }
+ printf(" --- graph ----\n");
+ INodeIterator *ni = graph->nodes();
+ INode *node;
+ for (ni->toFirst();(node=ni->current());ni->toNext())
+ {
+ printf(" --- node id=%s label=%s linkId=%s\n",
+ node->id()->latin1(),
+ node->label()->latin1(),
+ node->linkId()->latin1()
+ );
+ IChildNodeIterator *cni = node->children();
+ IChildNode *cn;
+ for (cni->toFirst();(cn=cni->current());cni->toNext())
+ {
+ printf(" + child id=%s label=%s relation=%s\n",
+ cn->node()->id()->latin1(),
+ cn->node()->label()->latin1(),
+ cn->relationString()->latin1()
+ );
+ IEdgeLabelIterator *eli = cn->edgeLabels();
+ IEdgeLabel *el;
+ for (eli->toFirst();(el=eli->current());eli->toNext())
+ {
+ printf(" edgeLabel=%s\n",el->label()->latin1());
+ }
+ eli->release();
+ }
+ cni->release();
+ }
+ ni->release();
+ printf(" --- end graph ----\n");
+
+}
+
+void DumpParamList(IParamIterator *pli,int indent)
+{
+ QString indentStr;
+ indentStr.fill(' ',indent);
+ IParam *par;
+ for (pli->toFirst();(par=pli->current());pli->toNext())
+ {
+ ILinkedTextIterator *lti = par->type();
+ QString parType = linkedTextToString(lti);
+ lti->release();
+ lti = par->defaultValue();
+ QString defVal = linkedTextToString(lti);
+ lti->release();
+ printf("%sParam type=%s decl_name=%s def_name=%s defvalue=%s\n",
+ indentStr.data(), parType.latin1(),
+ par->declarationName()->latin1(),
+ par->definitionName()->latin1(),
+ defVal.latin1());
+ }
+}
+
+int main(int argc,char **argv)
+{
+ if (argc!=2)
+ {
+ printf("Usage: %s xmldir\n",argv[0]);
+ exit(1);
+ }
+
+ IDoxygen *dox = createObjectModel();
+
+ dox->setDebugLevel(4);
+
+ if (!dox->readXMLDir(argv[1]))
+ {
+ printf("Error reading %s/index.xml\n",argv[1]);
+ exit(1);
+ }
+
+ ICompoundIterator *cli = dox->compounds();
+ ICompound *comp;
+ printf("--- compound list ---------\n");
+ for (cli->toFirst();(comp=cli->current());cli->toNext())
+ {
+ printf("Compound name=%s id=%s kind=%s\n",
+ comp->name()->latin1(),comp->id()->latin1(),comp->kindString()->latin1());
+
+ ISectionIterator *sli = comp->sections();
+ ISection *sec;
+ for (sli->toFirst();(sec=sli->current());sli->toNext())
+ {
+ printf(" Section kind=%s\n",sec->kindString()->latin1());
+ IMemberIterator *mli = sec->members();
+ IMember *mem;
+ if( sec->kind() == ISection::UserDefined )
+ {
+ IUserDefined *group = dynamic_cast<IUserDefined*>(sec);
+ printf(" Title=%s\n", group->header()->latin1() );
+ }
+ for (mli->toFirst();(mem=mli->current());mli->toNext())
+ {
+ ILinkedTextIterator *lti = mem->type();
+ printf(" Member type=%s name=%s\n",
+ linkedTextToString(lti).latin1(),mem->name()->latin1());
+ lti->release();
+
+ IParamIterator *pli = mem->parameters();
+ DumpParamList(pli,6);
+ pli->release();
+ IMemberReferenceIterator *mri = mem->references();
+ IMemberReference *mr;
+ for (mri->toFirst();(mr=mri->current());mri->toNext())
+ {
+ IMember *memr = mr->member();
+ printf(" References %s at line %d\n",
+ mr->name()->latin1(),memr->bodyStart());
+ }
+
+ mri->release();
+ mri = mem->referencedBy();
+ for (mri->toFirst();(mr=mri->current());mri->toNext())
+ {
+ IMember *memr = mr->member();
+ printf(" ReferencedBy %s at line %d\n",
+ mr->name()->latin1(),memr->bodyStart());
+ }
+ mri->release();
+
+ if (mem->kind()==IMember::Enum) // we have found an enum
+ {
+ IEnum *e = dynamic_cast<IEnum*>(mem);
+ IMemberIterator *evi = e->enumValues(); // get the enum values
+ IMember *mev;
+ for (evi->toFirst();(mev=evi->current());evi->toNext())
+ {
+ IEnumValue *ev = dynamic_cast<IEnumValue*>(mev);
+ ILinkedTextIterator *lti = ev->initializer();
+ QString init = linkedTextToString(lti);
+ lti->release();
+ printf(" Enum value `%s' init=`%s'\n",
+ ev->name()->latin1(),init.latin1());
+ }
+ evi->release();
+ }
+
+ pli = mem->templateParameters();
+ if (pli)
+ {
+ printf(" Template parameters\n");
+ DumpParamList(pli,8);
+ pli->release();
+ }
+
+ IDoc *doc = mem->briefDescription();
+ if (doc)
+ {
+ printf("===== brief description ==== \n");
+ DumpDoc(doc,0);
+ }
+
+ doc = mem->detailedDescription();
+ if (doc)
+ {
+ printf("===== detailed description ==== \n");
+ DumpDoc(doc,0);
+ }
+ }
+ mli->release();
+ }
+ sli->release();
+
+ IDoc *doc = comp->briefDescription();
+ if (doc)
+ {
+ printf("===== brief description ==== \n");
+ DumpDoc(doc,0);
+ }
+
+ doc = comp->detailedDescription();
+ if (doc)
+ {
+ printf("===== detailed description ==== \n");
+ DumpDoc(doc,0);
+ }
+
+ if (comp->kind()==ICompound::Class)
+ {
+ IClass *cls = dynamic_cast<IClass*>(comp);
+ ASSERT(cls!=0);
+
+ printf("==== inheritance graph ==== \n");
+ DumpGraph(cls->inheritanceGraph());
+
+ printf("==== collabration graph ==== \n");
+ DumpGraph(cls->collaborationGraph());
+
+ printf("==== base classes ==== \n");
+ IRelatedCompoundIterator *bcli = cls->baseCompounds();
+ IRelatedCompound *bClass;
+ for (bcli->toFirst();(bClass=bcli->current());bcli->toNext())
+ {
+ ICompound *bc = bClass->compound();
+ printf(" + class %s\n",bc->name()->latin1());
+ bc->release();
+ }
+ bcli->release();
+
+ printf("==== derived classes ==== \n");
+ IRelatedCompoundIterator *dcli = cls->derivedCompounds();
+ IRelatedCompound *dClass;
+ for (dcli->toFirst();(dClass=dcli->current());dcli->toNext())
+ {
+ ICompound *dc = dClass->compound();
+ printf(" + class %s\n",dc->name()->latin1());
+ dc->release();
+ }
+ dcli->release();
+ }
+ else if (comp->kind()==ICompound::File)
+ {
+ IFile *file = dynamic_cast<IFile*>(comp);
+ ASSERT(file!=0);
+
+ printf("==== include dependency graph ==== \n");
+ DumpGraph(file->includeDependencyGraph());
+
+ printf("==== included by dependency graph ==== \n");
+ DumpGraph(file->includedByDependencyGraph());
+
+ printf("==== source ====\n");
+ DumpDoc(file->source(),0);
+ }
+
+ comp->release();
+ }
+ cli->release();
+ printf("---------------------------\n");
+
+ dox->release();
+
+ return 0;
+}
+
diff --git a/addon/doxmlparser/test/xmlparse.pro b/addon/doxmlparser/test/xmlparse.pro
new file mode 100644
index 0000000..9849c9b
--- /dev/null
+++ b/addon/doxmlparser/test/xmlparse.pro
@@ -0,0 +1,27 @@
+#
+# This file was generated from xmlparse.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = app.t
+CONFIG = console warn_on debug
+HEADERS =
+SOURCES = main.cpp
+unix:LIBS += -L../../../lib -ldoxmlparser -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../lib -ldoxmlparser -lqtools
+win32-msvc:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\..\..\lib;..\lib
+win32-borland:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../bin
+OBJECTS_DIR = ../../../objects/doxmlparser/test
+TARGET = xmlparse
+INCLUDEPATH += ../../../qtools ../include
+DEPENDPATH += ../include
+unix:TARGETDEPS = ../../../lib/libdoxmlparser.a
+win32:TARGETDEPS = ..\..\..\lib\doxmlparser.lib
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/addon/doxmlparser/test/xmlparse.pro.in b/addon/doxmlparser/test/xmlparse.pro.in
new file mode 100644
index 0000000..368d499
--- /dev/null
+++ b/addon/doxmlparser/test/xmlparse.pro.in
@@ -0,0 +1,20 @@
+TEMPLATE = app.t
+CONFIG = console warn_on $extraopts
+HEADERS =
+SOURCES = main.cpp
+unix:LIBS += -L../../../lib -ldoxmlparser -lqtools
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../../../lib -ldoxmlparser -lqtools
+win32-msvc:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\..\..\lib;..\lib
+win32-borland:LIBS += doxmlparser.lib qtools.lib shell32.lib
+win32-borland:TMAKE_LFLAGS += -L..\..\..\lib
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+DESTDIR = ../../../bin
+OBJECTS_DIR = ../../../objects/doxmlparser/test
+TARGET = xmlparse
+INCLUDEPATH += ../../../qtools ../include
+DEPENDPATH += ../include
+unix:TARGETDEPS = ../../../lib/libdoxmlparser.a
+win32:TARGETDEPS = ..\..\..\lib\doxmlparser.lib
+
diff --git a/addon/doxyapp/Makefile.in b/addon/doxyapp/Makefile.in
new file mode 100644
index 0000000..d0629d9
--- /dev/null
+++ b/addon/doxyapp/Makefile.in
@@ -0,0 +1,19 @@
+
+all clean depend distclean: Makefile.doxyapp
+ $(MAKE) -f Makefile.doxyapp $@
+
+distclean: clean
+ $(RM) -rf Makefile doxyapp.pro Makefile.doxyapp
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" doxyapp.pro >Makefile.doxyapp
+
+strip:
+ strip doxyapp
+
+Makefile.doxyapp: doxyapp.pro
+ $(ENV) $(PERL) "$(TMAKE)" doxyapp.pro >Makefile.doxyapp
+
+install:
diff --git a/addon/doxyapp/README b/addon/doxyapp/README
new file mode 100644
index 0000000..f92e106
--- /dev/null
+++ b/addon/doxyapp/README
@@ -0,0 +1,8 @@
+This directory contains an example of how to use doxygen as
+an "source parsing engine" in an application. It shows how to configure doxygen
+from the application and shows how to run doxygen without generating output,
+and then uses the information about the symbols found in the source code.
+
+Note that if you use this approach your application should be licensed under the GPL.
+
+
diff --git a/addon/doxyapp/doxyapp.cpp b/addon/doxyapp/doxyapp.cpp
new file mode 100644
index 0000000..e73d12a
--- /dev/null
+++ b/addon/doxyapp/doxyapp.cpp
@@ -0,0 +1,330 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/** @file
+ * @brief Example of how to use doxygen as part of another GPL applications
+ *
+ * This example shows how to configure and run doxygen programmatically from
+ * within an application without generating the usual output.
+ * The example should work on any Unix like OS (including Linux and Mac OS X).
+ *
+ * This example shows how to use to code parser to get cross-references information
+ * and it also shows how to look up symbols in a program parsed by doxygen and
+ * show some information about them.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "doxygen.h"
+#include "outputgen.h"
+#include "parserintf.h"
+#include "classdef.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "util.h"
+#include "classlist.h"
+#include "config.h"
+#include "filename.h"
+
+class XRefDummyCodeGenerator : public CodeOutputInterface
+{
+ public:
+ XRefDummyCodeGenerator(FileDef *fd) : m_fd(fd) {}
+ ~XRefDummyCodeGenerator() {}
+
+ // these are just null functions, they can be used to produce a syntax highlighted
+ // and cross-linked version of the source code, but who needs that anyway ;-)
+ void codify(const char *) {}
+ void writeCodeLink(const char *,const char *,const char *,const char *,const char *) {}
+ void writeLineNumber(const char *,const char *,const char *,int) {}
+ virtual void writeTooltip(const char *,const DocLinkInfo &,
+ const char *,const char *,const SourceLinkInfo &,
+ const SourceLinkInfo &) {}
+ void startCodeLine(bool) {}
+ void endCodeLine() {}
+ void startCodeAnchor(const char *) {}
+ void endCodeAnchor() {}
+ void startFontClass(const char *) {}
+ void endFontClass() {}
+ void writeCodeAnchor(const char *) {}
+ void setCurrentDoc(Definition *,const char *,bool) {}
+ void addWord(const char *,bool) {}
+
+ // here we are presented with the symbols found by the code parser
+ void linkableSymbol(int l, const char *sym,Definition *symDef,Definition *context)
+ {
+ QCString ctx;
+ if (context) // the context of the symbol is known
+ {
+ if (context->definitionType()==Definition::TypeMember) // it is inside a member
+ {
+ Definition *parentContext = context->getOuterScope();
+ if (parentContext && parentContext->definitionType()==Definition::TypeClass)
+ // it is inside a member of a class
+ {
+ ctx.sprintf("inside %s %s of %s %s",
+ ((MemberDef *)context)->memberTypeName().data(),
+ context->name().data(),
+ ((ClassDef*)parentContext)->compoundTypeString().data(),
+ parentContext->name().data());
+ }
+ else if (parentContext==Doxygen::globalScope) // it is inside a global member
+ {
+ ctx.sprintf("inside %s %s",
+ ((MemberDef *)context)->memberTypeName().data(),
+ context->name().data());
+ }
+ }
+ if (ctx.isEmpty()) // it is something else (class, or namespace member, ...)
+ {
+ ctx.sprintf("in %s",context->name().data());
+ }
+ }
+ printf("Found symbol %s at line %d of %s %s\n",
+ sym,l,m_fd->getDefFileName().data(),ctx.data());
+ if (symDef && context) // in this case the definition of the symbol is
+ // known to doxygen.
+ {
+ printf("-> defined at line %d of %s\n",
+ symDef->getDefLine(),symDef->getDefFileName().data());
+ }
+ }
+ private:
+ FileDef *m_fd;
+};
+
+static void findXRefSymbols(FileDef *fd)
+{
+ // get the interface to a parser that matches the file extension
+ ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
+
+ // get the programming language from the file name
+ SrcLangExt lang = getLanguageFromFileName(fd->name());
+
+ // reset the parsers state
+ pIntf->resetCodeParserState();
+
+ // create a new backend object
+ XRefDummyCodeGenerator *xrefGen = new XRefDummyCodeGenerator(fd);
+
+ // parse the source code
+ pIntf->parseCode(*xrefGen,
+ 0,
+ fileToString(fd->absFilePath()),
+ lang,
+ FALSE,
+ 0,
+ fd);
+
+ // dismiss the object.
+ delete xrefGen;
+}
+
+static void listSymbol(Definition *d)
+{
+ if (d!=Doxygen::globalScope && // skip the global namespace symbol
+ d->name().at(0)!='@' // skip anonymous stuff
+ )
+ {
+ printf("%s\n",
+ d->name().data());
+ }
+}
+
+static void listSymbols()
+{
+ QDictIterator<DefinitionIntf> sli(*Doxygen::symbolMap);
+ DefinitionIntf *di;
+ for (sli.toFirst();(di=sli.current());++sli)
+ {
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
+ // with same name
+ {
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *d;
+ // for each symbol
+ for (dli.toFirst();(d=dli.current());++dli)
+ {
+ listSymbol(d);
+ }
+ }
+ else // single symbol
+ {
+ listSymbol((Definition*)di);
+ }
+ }
+}
+
+static void lookupSymbol(Definition *d)
+{
+ if (d!=Doxygen::globalScope && // skip the global namespace symbol
+ d->name().at(0)!='@' // skip anonymous stuff
+ )
+ {
+ printf("Symbol info\n");
+ printf("-----------\n");
+ printf("Name: %s\n",d->name().data());
+ printf("File: %s\n",d->getDefFileName().data());
+ printf("Line: %d\n",d->getDefLine());
+ // depending on the definition type we can case to the appropriate
+ // derived to get additional information
+ switch (d->definitionType())
+ {
+ case Definition::TypeClass:
+ {
+ ClassDef *cd = (ClassDef *)d;
+ printf("Kind: %s\n",cd->compoundTypeString().data());
+ }
+ break;
+ case Definition::TypeFile:
+ {
+ FileDef *fd = (FileDef *)d;
+ printf("Kind: File: #includes %d other files\n",
+ fd->includeFileList() ? fd->includeFileList()->count() : 0);
+ }
+ break;
+ case Definition::TypeNamespace:
+ {
+ NamespaceDef *nd = (NamespaceDef *)d;
+ printf("Kind: Namespace: contains %d classes and %d namespaces\n",
+ nd->getClassSDict() ? nd->getClassSDict()->count() : 0,
+ nd->getNamespaceSDict() ? nd->getNamespaceSDict()->count() : 0);
+ }
+ break;
+ case Definition::TypeMember:
+ {
+ MemberDef *md = (MemberDef *)d;
+ printf("Kind: %s\n",md->memberTypeName().data());
+ }
+ break;
+ default:
+ // ignore groups/pages/packages/dirs for now
+ break;
+ }
+ }
+}
+
+static void lookupSymbols(const QCString &sym)
+{
+ if (!sym.isEmpty())
+ {
+ DefinitionIntf *di = Doxygen::symbolMap->find(sym);
+ if (di)
+ {
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList)
+ {
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *d;
+ // for each symbol with the given name
+ for (dli.toFirst();(d=dli.current());++dli)
+ {
+ lookupSymbol(d);
+ }
+ }
+ else
+ {
+ lookupSymbol((Definition*)di);
+ }
+ }
+ else
+ {
+ printf("Unknown symbol\n");
+ }
+ }
+}
+
+int main(int argc,char **argv)
+{
+ char cmd[256];
+
+ if (argc<2)
+ {
+ printf("Usage: %s [source_file | source_dir]\n",argv[0]);
+ exit(1);
+ }
+
+ // initialize data structures
+ initDoxygen();
+
+ // setup the non-default configuration options
+
+ // we need a place to put intermediate files
+ Config_getString("OUTPUT_DIRECTORY")="/tmp/doxygen";
+ // disable html output
+ Config_getBool("GENERATE_HTML")=FALSE;
+ // disable latex output
+ Config_getBool("GENERATE_LATEX")=FALSE;
+ // be quiet
+ Config_getBool("QUIET")=TRUE;
+ // turn off warnings
+ Config_getBool("WARNINGS")=FALSE;
+ Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE;
+ Config_getBool("WARN_IF_DOC_ERROR")=FALSE;
+ // Extract as much as possible
+ Config_getBool("EXTRACT_ALL")=TRUE;
+ Config_getBool("EXTRACT_STATIC")=TRUE;
+ Config_getBool("EXTRACT_PRIVATE")=TRUE;
+ Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE;
+ // Extract source browse information, needed
+ // to make doxygen gather the cross reference info
+ Config_getBool("SOURCE_BROWSER")=TRUE;
+
+ // set the input
+ Config_getList("INPUT").append(argv[1]);
+
+ // check and finialize the configuration
+ checkConfiguration();
+ adjustConfiguration();
+
+ // parse the files
+ parseInput();
+
+ // iterate over the input files
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ // foreach file with a certain name
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ // for each file definition
+ for (;(fd=fni.current());++fni)
+ {
+ // get the references (linked and unlinked) found in this file
+ findXRefSymbols(fd);
+ }
+ }
+
+ // remove temporary files
+ if (!Doxygen::objDBFileName.isEmpty()) unlink(Doxygen::objDBFileName);
+ if (!Doxygen::entryDBFileName.isEmpty()) unlink(Doxygen::entryDBFileName);
+ // clean up after us
+ rmdir("/tmp/doxygen");
+
+ while (1)
+ {
+ printf("> Type a symbol name or\n> .list for a list of symbols or\n> .quit to exit\n> ");
+ fgets(cmd,256,stdin);
+ QCString s(cmd);
+ if (s.at(s.length()-1)=='\n') s=s.left(s.length()-1); // strip trailing \n
+ if (s==".list")
+ listSymbols();
+ else if (s==".quit")
+ exit(0);
+ else
+ lookupSymbols(s);
+ }
+}
+
diff --git a/addon/doxyapp/doxyapp.pro.in b/addon/doxyapp/doxyapp.pro.in
new file mode 100644
index 0000000..7a8c5ee
--- /dev/null
+++ b/addon/doxyapp/doxyapp.pro.in
@@ -0,0 +1,12 @@
+TEMPLATE = app.t
+CONFIG = console warn_on debug
+HEADERS =
+SOURCES = doxyapp.cpp
+LIBS += -L../../lib -ldoxygen -lqtools -lmd5 -ldoxycfg -lpthread -liconv
+DESTDIR =
+OBJECTS_DIR = ../../objects/doxyapp
+TARGET = ../../bin/doxyapp
+INCLUDEPATH += ../../qtools ../../src
+DEPENDPATH += ../../src
+TARGETDEPS = ../../lib/libdoxygen.a
+
diff --git a/addon/doxypysql/search.py b/addon/doxypysql/search.py
new file mode 100755
index 0000000..d0c88c0
--- /dev/null
+++ b/addon/doxypysql/search.py
@@ -0,0 +1,364 @@
+#!/usr/bin/python
+
+# python script to search through doxygen_sqlite3.db
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+
+import sqlite3
+import sys
+import os
+import getopt
+import json
+
+class MemberType:
+ Define="0"
+ Function="1"
+ Variable="2"
+ Typedef="3"
+ Enumeration="4"
+ EnumValue="5"
+ Signal="6"
+ Slot="7"
+ Friend="8"
+ DCOP="9"
+ Property="10"
+ Event="11"
+
+class RequestType:
+ References="9901"
+ Struct="9902"
+ Includers="9903"
+ Includees="9904"
+ Members="9905"
+ BaseClasses="9906"
+ SubClasses="9907"
+
+g_conn=None
+###############################################################################
+
+def escapeLike(val):
+ return 'LIKE "%' + val.replace("\\", "\\\\").replace("_", "\\_") \
+ .replace("%", "\\%") + '%" ESCAPE "\\"'
+
+def matchName(name):
+ if type(name) is str:
+ return "name "+escapeLike(name)
+ else:
+ return 'id=%d' %name
+
+def fileName(id_file):
+ if g_conn.execute("SELECT COUNT(*) FROM files WHERE id=?",[id_file]).fetchone()[0] > 1:
+ print "non-uniq fileid"
+
+ for r in g_conn.execute("SELECT * FROM files WHERE id=?",[id_file]).fetchall():
+ return r['name']
+
+ return ""
+
+def fileId(name):
+ if g_conn.execute("SELECT COUNT(*) FROM files WHERE name=?",[name]).fetchone()[0] > 1:
+ print "non-uniq file name"
+
+ for r in g_conn.execute("SELECT * FROM files WHERE name=?",[name]).fetchall():
+ return r['id']
+
+ return -1
+
+###############################################################################
+
+def findReferences(name):
+ o=[]
+
+ cur = g_conn.cursor()
+ cur.execute("SELECT refid FROM memberdef WHERE name=?",[name])
+ refids = cur.fetchall()
+
+ if len(refids) == 0:
+ return o
+
+ refid = refids[0]['refid']
+ cur = g_conn.cursor()
+ for info in cur.execute("SELECT * FROM xrefs WHERE dst LIKE '%"+refid+"%'"):
+ item={}
+ cur = g_conn.cursor()
+ for i2 in cur.execute("SELECT * FROM memberdef WHERE refid=?",[info['src']]):
+ item['name']=i2['name']
+ item['src']=info['src']
+ item['file']=fileName(info['id_file'])
+ item['line']=info['line']
+
+ o.append(item)
+ return o
+
+
+def findFunction(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Function]).fetchall():
+ item={}
+ item['name'] = r['name']
+ item['definition'] = r['definition']
+ item['argsstring'] = r['argsstring']
+ item['file'] = fileName(r['id_file'])
+ item['line'] = r['line']
+ item['detaileddescription'] = r['detaileddescription']
+ o.append(item)
+ return o
+
+
+def findMacro(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Define]).fetchall():
+ item={}
+ item['name'] = r['name']
+ if r['argsstring']:
+ item['argsstring'] = r['argsstring']
+ item['definition'] = r['initializer']
+ item['file'] = fileName(r['id_file'])
+ item['line'] = r['line']
+ o.append(item)
+ return o
+
+
+def findTypedef(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Typedef]).fetchall():
+ item={}
+ item['name'] = r['name']
+ item['definition'] = r['definition']
+ item['file'] = fileName(r['id_file'])
+ item['line'] = r['line']
+ o.append(item)
+ return o
+
+
+def findVariable(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Variable]).fetchall():
+ item={}
+ item['name'] = r['name']
+ item['definition'] = r['definition']
+ item['file'] = fileName(r['id_file'])
+ item['line'] = r['line']
+ o.append(item)
+ return o
+
+def findParams(name):
+ o=[]
+ for r in g_conn.execute('SELECT id FROM memberdef WHERE '+matchName(name)).fetchall():
+ #a=("SELECT * FROM params where id=(SELECT id_param FROM memberdef_params where id_memberdef=?",[id_memberdef])
+ item={}
+ item['id'] = r['id']
+ o.append(item)
+ return o
+
+
+def findStruct(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM compounddef WHERE '+matchName(name)).fetchall():
+ item={}
+ item['name'] = r['name']
+ o.append(item)
+ return o
+
+def findIncluders(name):
+ o=[]
+ fid = fileId(name)
+ for r in g_conn.execute('SELECT * FROM includes WHERE id_dst=?',[fid]).fetchall():
+ item={}
+ item['name'] = fileName(r['id_src'])
+ o.append(item)
+ return o
+
+def findIncludees(name):
+ o=[]
+ fid = fileId(name)
+ for r in g_conn.execute('SELECT * FROM includes WHERE id_src=?',[fid]).fetchall():
+ item={}
+ item['name'] = r['dst']
+ o.append(item)
+ return o
+
+
+def findMembers(name):
+ o=[]
+ for r in g_conn.execute('SELECT * FROM memberdef WHERE scope LIKE "%'+name+'%";').fetchall():
+ item={}
+ item['name'] = r['name']
+ item['definition'] = r['definition']
+ item['argsstring'] = r['argsstring']
+ item['file'] = fileName(r['id_file'])
+ item['line'] = r['line']
+ item['documentation'] = r['documentation']
+ o.append(item)
+ return o
+
+
+def findBaseClasses(name):
+ o=[]
+ for r in g_conn.execute('SELECT base FROM basecompoundref WHERE derived=?',[name]).fetchall():
+ item={}
+ item['name'] = r['base']
+ o.append(item)
+ return o
+
+
+def findSubClasses(name):
+ o=[]
+ for r in g_conn.execute('SELECT derived FROM basecompoundref WHERE base=?',[name]).fetchall():
+ item={}
+ item['name'] = r['derived']
+ o.append(item)
+ return o
+
+
+###############################################################################
+
+def usage():
+ print """Usage: search.py [Options]
+Options:
+ -h, --help
+ -d <D> Use database <D> for queries
+ -r <F> Search for references to <F>
+ -f <F> Search for definition of function <F>
+ -m <M> Search for definition of macro <M>
+ -t <T> Search for definition of type <T>
+ -v <V> Search for definition of variable <V>
+ -I <I> Get the includers of <I>
+ -i <I> Get the includees of <I>
+ -M <C> Get all members of class <C>
+ -B <C> Get the base classes of class <C>
+ -S <C> Get the sub classes of class <C>
+"""
+
+def openDb(dbname):
+ global g_conn
+
+ if dbname == None:
+ dbname = "doxygen_sqlite3.db"
+
+ if not os.path.isfile(dbname):
+ raise BaseException("No such file %s" % dbname )
+
+ g_conn = sqlite3.connect(dbname)
+ g_conn.execute('PRAGMA temp_store = MEMORY;')
+ g_conn.row_factory = sqlite3.Row
+
+###############################################################################
+def process(kind,o):
+ request_processors = {
+ MemberType.Function: findFunction,
+ MemberType.Define: findMacro,
+ MemberType.Variable: findVariable,
+ MemberType.Typedef: findTypedef,
+ RequestType.References: findReferences,
+ RequestType.Struct: findStruct,
+ RequestType.Includers: findIncluders,
+ RequestType.Includees: findIncludees,
+ RequestType.Members: findMembers,
+ RequestType.BaseClasses: findBaseClasses,
+ RequestType.SubClasses: findSubClasses
+ }
+ return request_processors[kind](o)
+
+
+def processHref(ref):
+ j={}
+
+ # is it in memberdef ?
+ table="memberdef"
+ if ( g_conn.execute("SELECT count(*) from %s WHERE refid='%s'" % (table,ref) ).fetchone()[0] > 0 ):
+ for r in g_conn.execute("SELECT kind,id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall():
+ j=process(str(r['kind']),int(r['id']))
+
+ # is it in compounddef ?
+ table="compounddef"
+ if ( g_conn.execute("SELECT count(*) from %s WHERE refid='%s'" % (table,ref)).fetchone()[0] > 0 ):
+ for r in g_conn.execute("SELECT id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall():
+ j=process(RequestType.Struct,int(r['id']))
+
+ return j
+
+
+def serveCgi():
+ import cgi
+
+ print 'Content-Type: application/json\n'
+
+ fieldStorage = cgi.FieldStorage()
+ form = dict((key, fieldStorage.getvalue(key)) for key in fieldStorage.keys())
+
+ if 'href' in form:
+ ref = form['href']
+ else:
+ print '{"result": null, "error": "no refid given"}'
+ sys.exit(0)
+
+ openDb('doxygen_sqlite3.db')
+
+ j = processHref(ref)
+
+ print json.dumps({"result":j,"error":None})
+
+
+def serveCli(argv):
+ try:
+ opts, args = getopt.getopt(argv, "hr:I:i:d:f:m:t:v:H:M:B:S:",["help"])
+ except getopt.GetoptError:
+ usage()
+ sys.exit(1)
+
+ ref=None
+ dbname=None
+ j={}
+
+ for a, o in opts:
+ if a in ('-h', '--help'):
+ usage()
+ sys.exit(0)
+ elif a in ('-d'):
+ dbname=o
+ continue
+ elif a in ('-r'):
+ kind=RequestType.References
+ elif a in ('-I'):
+ kind=RequestType.Includers
+ elif a in ('-i'):
+ kind=RequestType.Includees
+ elif a in ('-M'):
+ kind=RequestType.Members
+ elif a in ('-B'):
+ kind=RequestType.BaseClasses
+ elif a in ('-S'):
+ kind=RequestType.SubClasses
+ elif a in ('-f'):
+ kind=MemberType.Function
+ elif a in ('-m'):
+ kind=MemberType.Define
+ elif a in ('-t'):
+ kind=MemberType.Typedef
+ elif a in ('-v'):
+ kind=MemberType.Variable
+ elif a in ('-H'):
+ ref = o
+
+ openDb(dbname)
+ if ref != None:
+ j=processHref(ref)
+ else:
+ j=process(kind,o)
+ print json.dumps(j)
+
+
+def main(argv):
+ if 'REQUEST_METHOD' in os.environ:
+ serveCgi()
+ else:
+ serveCli(argv)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/addon/doxysearch/Makefile.in b/addon/doxysearch/Makefile.in
new file mode 100644
index 0000000..7daafee
--- /dev/null
+++ b/addon/doxysearch/Makefile.in
@@ -0,0 +1,34 @@
+
+all clean depend: Makefile.doxysearch Makefile.doxyindexer
+ $(MAKE) -f Makefile.doxysearch $@
+ $(MAKE) -f Makefile.doxyindexer $@
+
+distclean: clean
+ $(RM) -rf Makefile doxysearch.pro Makefile.doxysearch
+ $(RM) -rf Makefile doxyindexer.pro Makefile.doxyindexer
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" doxysearch.pro >Makefile.doxysearch
+ $(ENV) $(PERL) "$(TMAKE)" doxyindexer.pro >Makefile.doxyindexer
+
+strip:
+ strip doxysearch
+
+Makefile.doxysearch: doxysearch.pro
+ $(ENV) $(PERL) "$(TMAKE)" doxysearch.pro >Makefile.doxysearch
+
+Makefile.doxyindexer: doxyindexer.pro
+ $(ENV) $(PERL) "$(TMAKE)" doxyindexer.pro >Makefile.doxyindexer
+
+install:
+ $(INSTTOOL) -d $(INSTALL)/bin
+ $(INSTTOOL) -m 755 ../../bin/doxysearch.cgi $(INSTALL)/bin
+ $(INSTTOOL) -m 755 ../../bin/doxyindexer $(INSTALL)/bin
+ $(INSTTOOL) -d $(INSTALL)/$(MAN1DIR)
+ cat ../../doc/doxyindexer.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxyindexer.1
+ $(INSTTOOL) -m 644 doxyindexer.1 $(INSTALL)/$(MAN1DIR)/doxyindexer.1
+ rm doxyindexer.1
+ cat ../../doc/doxysearch.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxysearch.1
+ $(INSTTOOL) -m 644 doxysearch.1 $(INSTALL)/$(MAN1DIR)/doxysearch.1
+ rm doxysearch.1
+
diff --git a/addon/doxysearch/doxyindexer.cpp b/addon/doxysearch/doxyindexer.cpp
new file mode 100644
index 0000000..b44a940
--- /dev/null
+++ b/addon/doxysearch/doxyindexer.cpp
@@ -0,0 +1,377 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+// STL includes
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <sstream>
+
+// Qtools includes
+#include <qregexp.h>
+#include <qxml.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
+// Xapian include
+#include <xapian.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static char pathSep = '\\';
+#else
+static char pathSep = '/';
+#endif
+
+/** trims \a whitespace characters from the start and end of string \a str. */
+static std::string trim(const std::string& str,
+ const std::string& whitespace = " \t")
+{
+ size_t strBegin = str.find_first_not_of(whitespace);
+ if (strBegin == std::string::npos)
+ return ""; // no content
+
+ size_t strEnd = str.find_last_not_of(whitespace);
+ int strRange = strEnd - strBegin + 1;
+
+ return str.substr(strBegin, strRange);
+}
+
+/** trims \a whitespace from start and end and replace occurrences of
+ * \a whitespace with \a fill.
+ */
+static std::string reduce(const std::string& str,
+ const std::string& fill = " ",
+ const std::string& whitespace = " \t")
+{
+ // trim first
+ std::string result = trim(str, whitespace);
+
+ // replace sub ranges
+ size_t beginSpace = result.find_first_of(whitespace);
+ while (beginSpace != std::string::npos)
+ {
+ size_t endSpace = result.find_first_not_of(whitespace, beginSpace);
+ int range = endSpace - beginSpace;
+
+ result.replace(beginSpace, range, fill);
+
+ size_t newStart = beginSpace + fill.length();
+ beginSpace = result.find_first_of(whitespace, newStart);
+ }
+
+ return result;
+}
+
+/** Adds all words in \a s to document \a doc with weight \a wfd */
+static void addWords(const std::string &s,Xapian::Document &doc,int wfd)
+{
+ std::istringstream iss(s);
+ std::istream_iterator<std::string> begin(iss),end,it;
+ for (it=begin;it!=end;++it)
+ {
+ std::string word = *it;
+ std::string lword = word;
+ std::transform(lword.begin(), lword.end(), lword.begin(), ::tolower);
+ doc.add_term(word,wfd);
+ if (lword!=word)
+ {
+ doc.add_term(lword,wfd);
+ }
+ }
+}
+
+/** Adds all identifiers in \a s to document \a doc with weight \a wfd */
+static void addIdentifiers(const std::string &s,Xapian::Document &doc,int wfd)
+{
+ QRegExp re("[A-Z_a-z][A-Z_a-z0-9]*");
+ int i,l,p=0;
+ QCString qs = s.c_str();
+ while ((i=re.match(qs,p,&l))!=-1)
+ {
+ doc.add_term(qs.mid(p,i-p).data(),wfd);
+ p=i+l;
+ }
+}
+
+/** Replaces all occurrences of \a old with \a repl in string \a str */
+static void replace_all(std::string& str, const std::string& old, const std::string& repl)
+{
+ size_t pos = 0;
+ while ((pos = str.find(old, pos)) != std::string::npos)
+ {
+ str.replace(pos, old.length(), repl);
+ pos += repl.length();
+ }
+}
+
+/** Replaces all XML entities in \a s with their unescaped representation */
+static std::string unescapeXmlEntities(const std::string &s)
+{
+ std::string result=s;
+ replace_all(result,">",">");
+ replace_all(result,"<","<");
+ replace_all(result,"'","'");
+ replace_all(result,""","\"");
+ replace_all(result,"&","&");
+ return result;
+}
+
+/** This class is a wrapper around SAX style XML parser, which
+ * parses the file without first building a DOM tree in memory.
+ */
+class XMLContentHandler : public QXmlDefaultHandler
+{
+ public:
+ /** Handler for parsing XML data */
+ XMLContentHandler(const QString &path)
+ : m_db((path+"doxysearch.db").utf8().data(),Xapian::DB_CREATE_OR_OVERWRITE),
+ m_stemmer("english")
+ {
+ m_curFieldName = UnknownField;
+ m_indexer.set_stemmer(m_stemmer);
+ m_indexer.set_document(m_doc);
+ }
+
+ /** Free data handler */
+ ~XMLContentHandler()
+ {
+ m_db.commit();
+ }
+
+ private:
+ enum FieldNames
+ {
+ UnknownField = 0,
+ TypeField = 1,
+ NameField = 2,
+ ArgsField = 3,
+ TagField = 4,
+ UrlField = 5,
+ KeywordField = 6,
+ TextField = 7
+ };
+
+ /** Handler for a start tag. Called for <doc> and <field> tags */
+ bool startElement(const QString &, const QString &,
+ const QString &name, const QXmlAttributes &attrib)
+ {
+ m_data="";
+ if (name=="field")
+ {
+ QString fieldName = attrib.value("name");
+ if (fieldName=="type") m_curFieldName=TypeField;
+ else if (fieldName=="name") m_curFieldName=NameField;
+ else if (fieldName=="args") m_curFieldName=ArgsField;
+ else if (fieldName=="tag") m_curFieldName=TagField;
+ else if (fieldName=="url") m_curFieldName=UrlField;
+ else if (fieldName=="keywords") m_curFieldName=KeywordField;
+ else if (fieldName=="text") m_curFieldName=TextField;
+ else m_curFieldName=UnknownField;
+ }
+ return TRUE;
+ }
+
+ /** Handler for an end tag. Called for </doc> and </field> tags */
+ bool endElement(const QString &, const QString &, const QString &name)
+ {
+ if (name=="doc") // </doc>
+ {
+ std::string term = m_doc.get_value(NameField);
+ std::string partTerm;
+ size_t pos = term.rfind("::");
+ if (pos!=std::string::npos)
+ {
+ partTerm = term.substr(pos+2);
+ }
+ if (m_doc.get_value(TypeField)=="class" ||
+ m_doc.get_value(TypeField)=="file" ||
+ m_doc.get_value(TypeField)=="namespace") // containers get highest prio
+ {
+ m_doc.add_term(term,1000);
+ if (!partTerm.empty())
+ {
+ m_doc.add_term(partTerm,500);
+ }
+ }
+ else // members and others get lower prio
+ {
+ m_doc.add_term(m_doc.get_value(NameField),100);
+ if (!partTerm.empty())
+ {
+ m_doc.add_term(partTerm,50);
+ }
+ }
+ m_db.add_document(m_doc);
+ m_doc.clear_values();
+ m_doc.clear_terms();
+ }
+ else if (name=="field" && m_curFieldName!=UnknownField) // </field>
+ {
+ // strip whitespace from m_data
+ m_data = reduce(m_data);
+ // replace XML entities
+ m_data = unescapeXmlEntities(m_data);
+ // add data to the document
+ m_doc.add_value(m_curFieldName,m_data);
+ switch (m_curFieldName)
+ {
+ case TypeField:
+ case NameField:
+ case TagField:
+ case UrlField:
+ // meta data that is not searchable
+ break;
+ case KeywordField:
+ addWords(m_data,m_doc,50);
+ break;
+ case ArgsField:
+ addIdentifiers(m_data,m_doc,10);
+ break;
+ case TextField:
+ addWords(m_data,m_doc,2);
+ break;
+ default:
+ break;
+ }
+ m_data="";
+ m_curFieldName=UnknownField;
+ }
+ // reset m_data
+ return TRUE;
+ }
+
+ /** Handler for inline text */
+ bool characters(const QString& ch)
+ {
+ m_data += ch.utf8();
+ return TRUE;
+ }
+
+ // internal state
+ Xapian::WritableDatabase m_db;
+ Xapian::Document m_doc;
+ Xapian::TermGenerator m_indexer;
+ Xapian::Stem m_stemmer;
+ std::string m_data;
+ FieldNames m_curFieldName;
+};
+
+/** Class for handling error during XML parsing */
+class XMLErrorHandler : public QXmlErrorHandler
+{
+ public:
+ virtual ~XMLErrorHandler() {}
+ bool warning( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool error( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool fatalError( const QXmlParseException &exception )
+ {
+ std::cerr << "Fatal error at line " << exception.lineNumber()
+ << " column " << exception.columnNumber() << ": "
+ << exception.message().utf8() << std::endl;
+ return FALSE;
+ }
+ QString errorString() { return ""; }
+
+ private:
+ QString errorMsg;
+};
+
+static void usage(const char *name)
+{
+ std::cerr << "Usage: " << name << " [-o output_dir] searchdata.xml [searchdata2.xml ...]" << std::endl;
+ exit(1);
+}
+
+/** main function to index data */
+int main(int argc,const char **argv)
+{
+ if (argc<2)
+ {
+ usage(argv[0]);
+ }
+ QString outputDir;
+ for (int i=1;i<argc;i++)
+ {
+ if (std::string(argv[i])=="-o")
+ {
+ if (i>=argc-1)
+ {
+ std::cerr << "Error: missing parameter for -o option" << std::endl;
+ usage(argv[0]);
+ }
+ else
+ {
+ i++;
+ outputDir=argv[i];
+ QFileInfo fi(outputDir);
+ if (!fi.exists() || !fi.isDir())
+ {
+ std::cerr << "Error: specified output directory does not exist!" << std::endl;
+ usage(argv[0]);
+ }
+ }
+ }
+ else if (std::string(argv[i])=="-h" || std::string(argv[i])=="--help")
+ {
+ usage(argv[0]);
+ }
+ }
+
+ try
+ {
+ if (!outputDir.isEmpty() && outputDir.at(outputDir.length()-1)!=pathSep)
+ {
+ outputDir+=pathSep;
+ }
+ XMLContentHandler handler(outputDir);
+ XMLErrorHandler errorHandler;
+ for (int i=1;i<argc;i++)
+ {
+ if (std::string(argv[i])=="-o")
+ {
+ i++;
+ }
+ else
+ {
+ QString xmlFileName = argv[i];
+ std::cout << "Processing " << xmlFileName.utf8() << "..." << std::endl;
+ QFile xmlFile(xmlFileName);
+ QXmlInputSource source(xmlFile);
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&errorHandler);
+ reader.parse(source);
+ }
+ }
+ }
+ catch(const Xapian::Error &e)
+ {
+ std::cerr << "Caught exception: " << e.get_description() << std::endl;
+ }
+ catch(...)
+ {
+ std::cerr << "Caught an unknown exception" << std::endl;
+ }
+
+ return 0;
+}
diff --git a/addon/doxysearch/doxyindexer.pro.in b/addon/doxysearch/doxyindexer.pro.in
new file mode 100644
index 0000000..c84a2ac
--- /dev/null
+++ b/addon/doxysearch/doxyindexer.pro.in
@@ -0,0 +1,12 @@
+TEMPLATE = app.t
+CONFIG = console warn_on static release
+HEADERS =
+SOURCES = doxyindexer.cpp
+LIBS += -L../../lib -lxapian -lqtools
+DESTDIR =
+OBJECTS_DIR = ../../objects/doxyindexer
+TARGET = ../../bin/doxyindexer
+INCLUDEPATH += ../../qtools
+DEPENDPATH +=
+TARGETDEPS =
+
diff --git a/addon/doxysearch/doxysearch.cpp b/addon/doxysearch/doxysearch.cpp
new file mode 100644
index 0000000..11af8e3
--- /dev/null
+++ b/addon/doxysearch/doxysearch.cpp
@@ -0,0 +1,434 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+// STL includes
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <algorithm>
+
+// Xapian includes
+#include <xapian.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/stat.h>
+#endif
+
+#define FIELD_TYPE 1
+#define FIELD_NAME 2
+#define FIELD_ARGS 3
+#define FIELD_TAG 4
+#define FIELD_URL 5
+#define FIELD_KEYW 6
+#define FIELD_DOC 7
+
+#define HEX2DEC(x) (((x)>='0' && (x)<='9')?((x)-'0'):\
+ ((x)>='a' && (x)<='f')?((x)-'a'+10):\
+ ((x)>='A' && (x)<='F')?((x)-'A'+10):-1)
+
+
+bool dirExists(const std::string& dirName)
+{
+#ifdef _WIN32
+ DWORD ftyp = GetFileAttributesA(dirName.c_str());
+ if (ftyp == INVALID_FILE_ATTRIBUTES)
+ return false; //something is wrong with your path!
+
+ if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
+ return true; // this is a directory!
+#else
+ struct stat sb;
+
+ if (stat(dirName.c_str(), &sb)==0 && S_ISDIR(sb.st_mode))
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+
+/** decodes a URI encoded string into a normal string. */
+static std::string uriDecode(const std::string & sSrc)
+{
+ // Note from RFC1630: "Sequences which start with a percent
+ // sign but are not followed by two hexadecimal characters
+ // (0-9, A-F) are reserved for future extension"
+
+ const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
+ const int SRC_LEN = sSrc.length();
+ const unsigned char * const SRC_END = pSrc + SRC_LEN;
+ // last decodable '%'
+ const unsigned char * const SRC_LAST_DEC = SRC_END - 2;
+
+ char * const pStart = new char[SRC_LEN];
+ char * pEnd = pStart;
+
+ while (pSrc < SRC_LAST_DEC)
+ {
+ if (*pSrc == '%') // replace %2A with corresponding ASCII character
+ {
+ char dec1, dec2;
+ unsigned char c1=*(pSrc+1);
+ unsigned char c2=*(pSrc+2);
+ if (-1 != (dec1 = HEX2DEC(c1))
+ && -1 != (dec2 = HEX2DEC(c2)))
+ {
+ *pEnd++ = (dec1 << 4) + dec2;
+ pSrc += 3;
+ continue;
+ }
+ }
+ else if (*pSrc == '+') // replace '+' with space
+ {
+ *pEnd++ = ' '; pSrc++;
+ continue;
+ }
+ *pEnd++ = *pSrc++;
+ }
+
+ // the last 2- chars
+ while (pSrc < SRC_END) *pEnd++ = *pSrc++;
+
+ std::string sResult(pStart, pEnd);
+ delete [] pStart;
+ return sResult;
+}
+
+/** return list of strings that result when splitting \a s using
+ * delimeter \a delim
+ */
+static std::vector<std::string> split(const std::string &s, char delim)
+{
+ std::vector<std::string> elems;
+ std::stringstream ss(s);
+ std::string item;
+ while (getline(ss, item, delim)) elems.push_back(item);
+ return elems;
+}
+
+/** Read type T from string \a s */
+template<class T>
+T fromString(const std::string& s)
+{
+ std::istringstream stream (s);
+ T t;
+ stream >> t;
+ return t;
+}
+
+/** Class that holds the startin position of a word */
+struct WordPosition
+{
+ WordPosition(int s,int i) : start(s), index(i) {}
+ int start;
+ int index;
+};
+
+/** Class representing the '<' operator for WordPosition objects based on position. */
+struct WordPosition_less
+{
+ bool operator()(const WordPosition &p1,const WordPosition &p2)
+ {
+ return p1.start<p2.start;
+ }
+};
+
+/** Class that holds a text fragment */
+struct Fragment
+{
+ Fragment(const std::string &t,int occ) : text(t), occurrences(occ) {}
+ std::string text;
+ int occurrences;
+};
+
+/** Class representing the '>' operator for Fragment objects based on occurrence. */
+struct Fragment_greater
+{
+ bool operator()(const Fragment &p1,const Fragment &p2)
+ {
+ return p1.occurrences>p2.occurrences;
+ }
+};
+
+/** Class representing a range within a string */
+struct Range
+{
+ Range(int s,int e) : start(s), end(e) {}
+ int start;
+ int end;
+};
+
+/** Returns true if [start..start+len] is inside one of the \a ranges. */
+static bool insideRange(const std::vector<Range> &ranges,int start,int len)
+{
+ for (std::vector<Range>::const_iterator it = ranges.begin();
+ it!=ranges.end(); ++it
+ )
+ {
+ Range r = *it;
+ if (start>=r.start && start+len<r.end)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+/** Returns a list of text \a fragments from \a s containing one or
+ * more \a words. The list is sorted occording to the
+ * number of occurrences of words within the fragment.
+ */
+static void highlighter(const std::string &s,
+ const std::vector<std::string> &words,
+ std::vector<Fragment> &fragments)
+{
+ const std::string spanStart="<span class=\"hl\">";
+ const std::string spanEnd="</span>";
+ const std::string dots="...";
+ const int fragLen = 60;
+ int sl=s.length();
+
+ // find positions of words in s
+ size_t j=0;
+ std::vector<WordPosition> positions;
+ for (std::vector<std::string>::const_iterator it=words.begin();
+ it!=words.end();
+ ++it,++j
+ )
+ {
+ int pos=0;
+ size_t i;
+ std::string word = *it;
+ while ((i=s.find(word,pos))!=std::string::npos)
+ {
+ positions.push_back(WordPosition(i,j));
+ pos=i+word.length();
+ }
+ }
+ // sort on position
+ std::sort(positions.begin(),positions.end(),WordPosition_less());
+ // get fragments around words
+ std::vector<Range> ranges;
+ for (std::vector<WordPosition>::const_iterator it=positions.begin();
+ it!=positions.end();
+ ++it)
+ {
+ WordPosition wp = *it;
+ std::string w = words[wp.index];
+ int i=wp.start;
+ int wl=w.length();
+ if (!insideRange(ranges,i,wl))
+ {
+ if (wl>fragLen)
+ {
+ fragments.push_back(Fragment(spanStart+w+spanEnd,1));
+ ranges.push_back(Range(i,i+wl));
+ }
+ else
+ {
+ std::string startFragment,endFragment;
+ int bi=i-(fragLen-wl)/2;
+ int ei=i+wl+(fragLen-wl)/2;
+ int occ=0;
+ if (bi<0) { ei-=bi; bi=0; } else startFragment=dots;
+ if (ei>sl) { ei=sl; } else endFragment=dots;
+ while (bi>0 && !isspace(s[bi])) bi--; // round to start of the word
+ while (ei<sl && !isspace(s[ei])) ei++; // round to end of the word
+ // highlight any word in s between indexes bi and ei
+ std::string fragment=startFragment;
+ int pos=bi;
+ for (std::vector<WordPosition>::const_iterator it2=positions.begin();
+ it2!=positions.end();
+ ++it2)
+ {
+ WordPosition wp2 = *it2;
+ std::string w2 = words[wp2.index];
+ int wl2 = w2.length();
+ if (wp2.start>=bi && wp2.start+wl2<=ei) // word is inside the range!
+ {
+ fragment+=s.substr(pos,wp2.start-pos)+
+ spanStart+
+ s.substr(wp2.start,wl2)+
+ spanEnd;
+ pos=wp2.start+wl2;
+ occ++;
+ }
+ }
+ fragment+=s.substr(pos,ei-pos)+endFragment;
+ fragments.push_back(Fragment(fragment,occ));
+ ranges.push_back(Range(bi,ei));
+ }
+ }
+ }
+ std::sort(fragments.begin(),fragments.end(),Fragment_greater());
+}
+
+/** Escapes a string such that is can be included in a JSON structure */
+static std::string escapeString(const std::string &s)
+{
+ std::stringstream dst;
+ for (unsigned int i=0;i<s.length();i++)
+ {
+ char ch = s[i];
+ switch (ch)
+ {
+ case '\"': dst << "\\\""; break;
+ default: dst << ch; break;
+ }
+ }
+ return dst.str();
+}
+
+static void showError(const std::string &callback,const std::string &error)
+{
+ std::cout << callback << "({\"error\":\"" << error << "\"})";
+ exit(0);
+}
+
+/** Main routine */
+int main(int argc,char **argv)
+{
+ // process inputs that were passed to us via QUERY_STRING
+ std::cout << "Content-Type:application/javascript;charset=utf-8\r\n\n";
+ std::string callback;
+ try
+ {
+ // get input parameters
+ const char *queryEnv = getenv("QUERY_STRING");
+ std::string queryString;
+ if (queryEnv)
+ {
+ queryString = queryEnv;
+ }
+ else if (argc>=2)
+ {
+ queryString = argv[1];
+ }
+ else
+ {
+ std::cout << "No input!\n";
+ exit(1);
+ }
+
+ // parse query string
+ std::vector<std::string> parts = split(queryString,'&');
+ std::string searchFor,callback;
+ int num=1,page=0;
+ for (std::vector<std::string>::const_iterator it=parts.begin();it!=parts.end();++it)
+ {
+ std::vector<std::string> kv = split(*it,'=');
+ if (kv.size()==2)
+ {
+ std::string val = uriDecode(kv[1]);
+ if (kv[0]=="q") searchFor = val;
+ else if (kv[0]=="n") num = fromString<int>(val);
+ else if (kv[0]=="p") page = fromString<int>(val);
+ else if (kv[0]=="cb") callback = val;
+ }
+ }
+
+ std::string indexDir = "doxysearch.db";
+
+ if (queryString=="test") // user test
+ {
+ bool dbOk = dirExists(indexDir);
+ if (dbOk)
+ {
+ std::cout << "Test successful.";
+ }
+ else
+ {
+ std::cout << "Test failed: cannot find search index " << indexDir;
+ }
+ exit(0);
+ }
+
+ // create query
+ Xapian::Database db(indexDir);
+ Xapian::Enquire enquire(db);
+ Xapian::Query query;
+ std::vector<std::string> words = split(searchFor,' ');
+ for (std::vector<std::string>::const_iterator it=words.begin();it!=words.end();++it)
+ {
+ query = Xapian::Query(Xapian::Query::OP_OR,query,Xapian::Query(*it));
+ }
+ enquire.set_query(query);
+
+ // get results
+ Xapian::MSet matches = enquire.get_mset(page*num,num);
+ unsigned int hits = matches.get_matches_estimated();
+ unsigned int offset = page*num;
+ unsigned int pages = num>0 ? (hits+num-1)/num : 0;
+ if (offset>hits) offset=hits;
+ if (offset+num>hits) num=hits-offset;
+
+ // write results as JSONP
+ std::cout << callback.c_str() << "(";
+ std::cout << "{" << std::endl
+ << " \"hits\":" << hits << "," << std::endl
+ << " \"first\":" << offset << "," << std::endl
+ << " \"count\":" << num << "," << std::endl
+ << " \"page\":" << page << "," << std::endl
+ << " \"pages\":" << pages << "," << std::endl
+ << " \"query\": \"" << escapeString(searchFor) << "\"," << std::endl
+ << " \"items\":[" << std::endl;
+ // foreach search result
+ unsigned int o = offset;
+ for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i,++o)
+ {
+ std::vector<Fragment> hl;
+ Xapian::Document doc = i.get_document();
+ highlighter(doc.get_value(FIELD_DOC),words,hl);
+ std::cout << " {\"type\": \"" << doc.get_value(FIELD_TYPE) << "\"," << std::endl
+ << " \"name\": \"" << doc.get_value(FIELD_NAME) << doc.get_value(FIELD_ARGS) << "\"," << std::endl
+ << " \"tag\": \"" << doc.get_value(FIELD_TAG) << "\"," << std::endl
+ << " \"url\": \"" << doc.get_value(FIELD_URL) << "\"," << std::endl;
+ std::cout << " \"fragments\":[" << std::endl;
+ int c=0;
+ bool first=true;
+ for (std::vector<Fragment>::const_iterator it = hl.begin();it!=hl.end() && c<3;++it,++c)
+ {
+ if (!first) std::cout << "," << std::endl;
+ std::cout << " \"" << escapeString((*it).text) << "\"";
+ first=false;
+ }
+ if (!first) std::cout << std::endl;
+ std::cout << " ]" << std::endl;
+ std::cout << " }";
+ if (o<offset+num-1) std::cout << ",";
+ std::cout << std::endl;
+ }
+ std::cout << " ]" << std::endl << "})" << std::endl;
+ }
+ catch (const Xapian::Error &e) // Xapian exception
+ {
+ showError(callback,e.get_description());
+ }
+ catch (...) // Any other exception
+ {
+ showError(callback,"Unknown Exception!");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/addon/doxysearch/doxysearch.pro.in b/addon/doxysearch/doxysearch.pro.in
new file mode 100644
index 0000000..702f5a4
--- /dev/null
+++ b/addon/doxysearch/doxysearch.pro.in
@@ -0,0 +1,12 @@
+TEMPLATE = app.t
+CONFIG = console warn_on debug cgi
+HEADERS =
+SOURCES = doxysearch.cpp
+LIBS += -lxapian
+DESTDIR =
+OBJECTS_DIR = ../../objects/doxysearch
+TARGET = ../../bin/doxysearch.cgi
+INCLUDEPATH +=
+DEPENDPATH +=
+TARGETDEPS =
+
diff --git a/addon/doxywizard/Makefile b/addon/doxywizard/Makefile
new file mode 100644
index 0000000..8c9a218
--- /dev/null
+++ b/addon/doxywizard/Makefile
@@ -0,0 +1,62 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+
+QMAKE=$(QTDIR)/bin/qmake $(MKSPECS)
+INCBUFSIZE=$(PYTHON) ../../src/increasebuffer.py
+
+all: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard LEX=$(LEX) PYTHON=$(PYTHON) INCBUFSIZE="$(INCBUFSIZE)"
+
+Makefile.doxywizard: doxywizard.pro
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+qmake:
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+clean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard clean
+
+distclean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard distclean
+ $(RM) Makefile.doxywizard
+
+install:
+ $(INSTTOOL) -d $(INSTALL)/bin
+ $(INSTTOOL) -m 755 ../../bin/doxywizard $(INSTALL)/bin
+ $(INSTTOOL) -d $(INSTALL)/$(MAN1DIR)
+ cat ../../doc/doxywizard.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxywizard.1
+ $(INSTTOOL) -m 644 doxywizard.1 $(INSTALL)/$(MAN1DIR)/doxywizard.1
+ rm doxywizard.1
+
+FORCE:
diff --git a/addon/doxywizard/Makefile.doxywizard b/addon/doxywizard/Makefile.doxywizard
new file mode 100644
index 0000000..e5e1a23
--- /dev/null
+++ b/addon/doxywizard/Makefile.doxywizard
@@ -0,0 +1,436 @@
+#############################################################################
+# Makefile for building: ../../bin/doxywizard.app/Contents/MacOS/doxywizard
+# Generated by qmake (2.01a) (Qt 4.8.6) on: Thu Aug 21 10:48:38 2014
+# Project: doxywizard.pro
+# Template: app
+# Command: /usr/bin/qmake -spec /usr/mkspecs/macx-g++ -o Makefile.doxywizard doxywizard.pro
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES = -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
+CFLAGS = -pipe -g -arch x86_64 -mmacosx-version-min=10.5 -Xarch_x86_64 -mmacosx-version-min=10.5 -arch i386 -mmacosx-version-min=10.5 -Wall -W $(DEFINES)
+CXXFLAGS = -pipe -g -arch x86_64 -mmacosx-version-min=10.5 -Xarch_x86_64 -mmacosx-version-min=10.5 -arch i386 -mmacosx-version-min=10.5 -Wall -W $(DEFINES)
+INCPATH = -I/usr/mkspecs/macx-g++ -I. -I/usr/lib/QtCore.framework/Versions/4/Headers -I/usr/include/QtCore -I/usr/lib/QtGui.framework/Versions/4/Headers -I/usr/include/QtGui -I/usr/lib/QtXml.framework/Versions/4/Headers -I/usr/include/QtXml -I/usr/include -I. -I../../generated_src/doxywizard -I/opt/local/include -I../../moc/doxywizard -F/usr/lib
+LINK = g++
+LFLAGS = -headerpad_max_install_names -arch x86_64 -mmacosx-version-min=10.5 -arch i386 -mmacosx-version-min=10.5 -Xarch_x86_64 -mmacosx-version-min=10.5
+LIBS = $(SUBLIBS) -F/usr/lib -L/usr/lib -L/opt/local/lib -framework QtXml -L/usr/lib -F/usr/lib -framework QtCore -framework QtGui
+AR = ar cq
+RANLIB = ranlib -s
+QMAKE = /usr/bin/qmake
+TAR = tar -cf
+COMPRESS = gzip -9f
+COPY = cp -f
+SED = sed
+COPY_FILE = cp -f
+COPY_DIR = cp -f -R
+STRIP =
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+INSTALL_PROGRAM = $(COPY_FILE)
+DEL_FILE = rm -f
+SYMLINK = ln -f -s
+DEL_DIR = rmdir
+MOVE = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+export MACOSX_DEPLOYMENT_TARGET = 10.4
+
+####### Output directory
+
+OBJECTS_DIR = ../../objects/doxywizard/
+
+####### Files
+
+SOURCES = doxywizard.cpp \
+ expert.cpp \
+ wizard.cpp \
+ inputbool.cpp \
+ inputstring.cpp \
+ inputint.cpp \
+ inputstrlist.cpp ../../generated_src/doxywizard/configdoc.cpp \
+ ../../generated_src/doxywizard/config_doxyw.cpp \
+ ../../generated_src/doxywizard/version.cpp \
+ ../../moc/doxywizard/moc_doxywizard.cpp \
+ ../../moc/doxywizard/moc_expert.cpp \
+ ../../moc/doxywizard/moc_helplabel.cpp \
+ ../../moc/doxywizard/moc_inputbool.cpp \
+ ../../moc/doxywizard/moc_inputstring.cpp \
+ ../../moc/doxywizard/moc_inputint.cpp \
+ ../../moc/doxywizard/moc_inputstrlist.cpp \
+ ../../moc/doxywizard/moc_wizard.cpp \
+ ../../rcc/doxywizard/qrc_doxywizard.cpp
+OBJECTS = ../../objects/doxywizard/doxywizard.o \
+ ../../objects/doxywizard/expert.o \
+ ../../objects/doxywizard/wizard.o \
+ ../../objects/doxywizard/inputbool.o \
+ ../../objects/doxywizard/inputstring.o \
+ ../../objects/doxywizard/inputint.o \
+ ../../objects/doxywizard/inputstrlist.o \
+ ../../objects/doxywizard/configdoc.o \
+ ../../objects/doxywizard/config_doxyw.o \
+ ../../objects/doxywizard/version.o \
+ ../../objects/doxywizard/moc_doxywizard.o \
+ ../../objects/doxywizard/moc_expert.o \
+ ../../objects/doxywizard/moc_helplabel.o \
+ ../../objects/doxywizard/moc_inputbool.o \
+ ../../objects/doxywizard/moc_inputstring.o \
+ ../../objects/doxywizard/moc_inputint.o \
+ ../../objects/doxywizard/moc_inputstrlist.o \
+ ../../objects/doxywizard/moc_wizard.o \
+ ../../objects/doxywizard/qrc_doxywizard.o
+DIST = /usr/mkspecs/common/unix.conf \
+ /usr/mkspecs/common/mac.conf \
+ /usr/mkspecs/common/gcc-base.conf \
+ /usr/mkspecs/common/gcc-base-macx.conf \
+ /usr/mkspecs/common/g++-base.conf \
+ /usr/mkspecs/common/g++-macx.conf \
+ /usr/mkspecs/qconfig.pri \
+ /usr/mkspecs/modules/qt_webkit_version.pri \
+ /usr/mkspecs/features/qt_functions.prf \
+ /usr/mkspecs/features/qt_config.prf \
+ /usr/mkspecs/features/exclusive_builds.prf \
+ /usr/mkspecs/features/default_pre.prf \
+ /usr/mkspecs/features/mac/default_pre.prf \
+ /usr/mkspecs/features/debug.prf \
+ /usr/mkspecs/features/default_post.prf \
+ /usr/mkspecs/features/mac/default_post.prf \
+ /usr/mkspecs/features/mac/objective_c.prf \
+ /usr/mkspecs/features/mac/x86_64.prf \
+ /usr/mkspecs/features/mac/x86.prf \
+ /usr/mkspecs/features/shared.prf \
+ /usr/mkspecs/features/warn_on.prf \
+ /usr/mkspecs/features/qt.prf \
+ /usr/mkspecs/features/unix/thread.prf \
+ /usr/mkspecs/features/moc.prf \
+ /usr/mkspecs/features/mac/rez.prf \
+ /usr/mkspecs/features/mac/sdk.prf \
+ /usr/mkspecs/features/resources.prf \
+ /usr/mkspecs/features/uic.prf \
+ /usr/mkspecs/features/yacc.prf \
+ /usr/mkspecs/features/lex.prf \
+ /usr/mkspecs/features/include_source_dir.prf \
+ doxywizard.pro
+QMAKE_TARGET = doxywizard
+DESTDIR = ../../bin/
+TARGET = ../../bin/doxywizard.app/Contents/MacOS/doxywizard
+
+####### Custom Compiler Variables
+QMAKE_COMP_QMAKE_OBJECTIVE_CFLAGS = -pipe \
+ -g \
+ -arch \
+ x86_64 \
+ -mmacosx-version-min=10.5 \
+ -Xarch_x86_64 \
+ -mmacosx-version-min=10.5 \
+ -arch \
+ i386 \
+ -mmacosx-version-min=10.5 \
+ -Wall \
+ -W
+
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile.doxywizard ../../bin/doxywizard.app/Contents/PkgInfo ../../bin/doxywizard.app/Contents/Resources/empty.lproj ../../bin/doxywizard.app/Contents/Info.plist $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ @$(CHK_DIR_EXISTS) ../../bin/doxywizard.app/Contents/MacOS/ || $(MKDIR) ../../bin/doxywizard.app/Contents/MacOS/
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
+
+Makefile.doxywizard: doxywizard.pro /usr/mkspecs/macx-g++/qmake.conf /usr/mkspecs/common/unix.conf \
+ /usr/mkspecs/common/mac.conf \
+ /usr/mkspecs/common/gcc-base.conf \
+ /usr/mkspecs/common/gcc-base-macx.conf \
+ /usr/mkspecs/common/g++-base.conf \
+ /usr/mkspecs/common/g++-macx.conf \
+ /usr/mkspecs/qconfig.pri \
+ /usr/mkspecs/modules/qt_webkit_version.pri \
+ /usr/mkspecs/features/qt_functions.prf \
+ /usr/mkspecs/features/qt_config.prf \
+ /usr/mkspecs/features/exclusive_builds.prf \
+ /usr/mkspecs/features/default_pre.prf \
+ /usr/mkspecs/features/mac/default_pre.prf \
+ /usr/mkspecs/features/debug.prf \
+ /usr/mkspecs/features/default_post.prf \
+ /usr/mkspecs/features/mac/default_post.prf \
+ /usr/mkspecs/features/mac/objective_c.prf \
+ /usr/mkspecs/features/mac/x86_64.prf \
+ /usr/mkspecs/features/mac/x86.prf \
+ /usr/mkspecs/features/shared.prf \
+ /usr/mkspecs/features/warn_on.prf \
+ /usr/mkspecs/features/qt.prf \
+ /usr/mkspecs/features/unix/thread.prf \
+ /usr/mkspecs/features/moc.prf \
+ /usr/mkspecs/features/mac/rez.prf \
+ /usr/mkspecs/features/mac/sdk.prf \
+ /usr/mkspecs/features/resources.prf \
+ /usr/mkspecs/features/uic.prf \
+ /usr/mkspecs/features/yacc.prf \
+ /usr/mkspecs/features/lex.prf \
+ /usr/mkspecs/features/include_source_dir.prf \
+ /usr/lib/QtXml.framework/QtXml.prl \
+ /usr/lib/QtCore.framework/QtCore.prl \
+ /usr/lib/QtGui.framework/QtGui.prl
+ $(QMAKE) -spec /usr/mkspecs/macx-g++ -o Makefile.doxywizard doxywizard.pro
+/usr/mkspecs/common/unix.conf:
+/usr/mkspecs/common/mac.conf:
+/usr/mkspecs/common/gcc-base.conf:
+/usr/mkspecs/common/gcc-base-macx.conf:
+/usr/mkspecs/common/g++-base.conf:
+/usr/mkspecs/common/g++-macx.conf:
+/usr/mkspecs/qconfig.pri:
+/usr/mkspecs/modules/qt_webkit_version.pri:
+/usr/mkspecs/features/qt_functions.prf:
+/usr/mkspecs/features/qt_config.prf:
+/usr/mkspecs/features/exclusive_builds.prf:
+/usr/mkspecs/features/default_pre.prf:
+/usr/mkspecs/features/mac/default_pre.prf:
+/usr/mkspecs/features/debug.prf:
+/usr/mkspecs/features/default_post.prf:
+/usr/mkspecs/features/mac/default_post.prf:
+/usr/mkspecs/features/mac/objective_c.prf:
+/usr/mkspecs/features/mac/x86_64.prf:
+/usr/mkspecs/features/mac/x86.prf:
+/usr/mkspecs/features/shared.prf:
+/usr/mkspecs/features/warn_on.prf:
+/usr/mkspecs/features/qt.prf:
+/usr/mkspecs/features/unix/thread.prf:
+/usr/mkspecs/features/moc.prf:
+/usr/mkspecs/features/mac/rez.prf:
+/usr/mkspecs/features/mac/sdk.prf:
+/usr/mkspecs/features/resources.prf:
+/usr/mkspecs/features/uic.prf:
+/usr/mkspecs/features/yacc.prf:
+/usr/mkspecs/features/lex.prf:
+/usr/mkspecs/features/include_source_dir.prf:
+/usr/lib/QtXml.framework/QtXml.prl:
+/usr/lib/QtCore.framework/QtCore.prl:
+/usr/lib/QtGui.framework/QtGui.prl:
+qmake: FORCE
+ @$(QMAKE) -spec /usr/mkspecs/macx-g++ -o Makefile.doxywizard doxywizard.pro
+
+../../bin/doxywizard.app/Contents/PkgInfo:
+ @$(CHK_DIR_EXISTS) ../../bin/doxywizard.app/Contents || $(MKDIR) ../../bin/doxywizard.app/Contents
+ @$(DEL_FILE) ../../bin/doxywizard.app/Contents/PkgInfo
+ @echo "APPL????" >../../bin/doxywizard.app/Contents/PkgInfo
+../../bin/doxywizard.app/Contents/Resources/empty.lproj:
+ @$(CHK_DIR_EXISTS) ../../bin/doxywizard.app/Contents/Resources || $(MKDIR) ../../bin/doxywizard.app/Contents/Resources
+ @touch ../../bin/doxywizard.app/Contents/Resources/empty.lproj
+
+../../bin/doxywizard.app/Contents/Info.plist:
+ @$(CHK_DIR_EXISTS) ../../bin/doxywizard.app/Contents || $(MKDIR) ../../bin/doxywizard.app/Contents
+ @$(DEL_FILE) ../../bin/doxywizard.app/Contents/Info.plist
+ @sed -e "s, at SHORT_VERSION@,1.0,g" -e "s, at TYPEINFO@,????,g" -e "s, at ICON@,,g" -e "s, at EXECUTABLE@,doxywizard,g" -e "s, at TYPEINFO@,????,g" /usr/mkspecs/macx-g++/Info.plist.app >../../bin/doxywizard.app/Contents/Info.plist
+dist:
+ @$(CHK_DIR_EXISTS) ../../objects/doxywizard/doxywizard1.0.0 || $(MKDIR) ../../objects/doxywizard/doxywizard1.0.0
+ $(COPY_FILE) --parents $(SOURCES) $(DIST) ../../objects/doxywizard/doxywizard1.0.0/ && $(COPY_FILE) --parents doxywizard.h version.h expert.h config.h helplabel.h inputbool.h inputstring.h inputint.h inputstrlist.h wizard.h docintf.h ../../objects/doxywizard/doxywizard1.0.0/ && $(COPY_FILE) --parents doxywizard.qrc ../../objects/doxywizard/doxywizard1.0.0/ && $(COPY_FILE) --parents doxywizard.cpp expert.cpp wizard.cpp inputbool.cpp inputstring.cpp inputint.cpp inputstrlist.cpp ../../obj [...]
+
+
+clean:compiler_clean
+ -$(DEL_FILE) $(OBJECTS)
+ -$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+ -$(DEL_FILE) -r ../../bin/doxywizard.app
+ -$(DEL_FILE) Makefile.doxywizard
+
+
+../../generated_src/doxywizard/configdoc.cpp: ../../src/config.xml ../../src/configgen.py
+ $(PYTHON) ../../src/configgen.py -wiz ../../src/config.xml > ../../generated_src/doxywizard/configdoc.cpp
+
+../../generated_src/doxywizard/config_doxyw.cpp: ../../addon/doxywizard/config_doxyw.l ../../src/increasebuffer.py
+ $(LEX) -Pconfig_doxywYY -t ../../addon/doxywizard/config_doxyw.l | $(INCBUFSIZE) >../../generated_src/doxywizard/$*.cpp
+
+../../generated_src/doxywizard/version.cpp: ../../configure
+ cd ../../src;$(PYTHON) version.py
+
+check: first
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_objective_c_make_all:
+compiler_objective_c_clean:
+compiler_moc_header_make_all: ../../moc/doxywizard/moc_doxywizard.cpp ../../moc/doxywizard/moc_expert.cpp ../../moc/doxywizard/moc_helplabel.cpp ../../moc/doxywizard/moc_inputbool.cpp ../../moc/doxywizard/moc_inputstring.cpp ../../moc/doxywizard/moc_inputint.cpp ../../moc/doxywizard/moc_inputstrlist.cpp ../../moc/doxywizard/moc_wizard.cpp
+compiler_moc_header_clean:
+ -$(DEL_FILE) ../../moc/doxywizard/moc_doxywizard.cpp ../../moc/doxywizard/moc_expert.cpp ../../moc/doxywizard/moc_helplabel.cpp ../../moc/doxywizard/moc_inputbool.cpp ../../moc/doxywizard/moc_inputstring.cpp ../../moc/doxywizard/moc_inputint.cpp ../../moc/doxywizard/moc_inputstrlist.cpp ../../moc/doxywizard/moc_wizard.cpp
+../../moc/doxywizard/moc_doxywizard.cpp: doxywizard.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ doxywizard.h -o ../../moc/doxywizard/moc_doxywizard.cpp
+
+../../moc/doxywizard/moc_expert.cpp: docintf.h \
+ expert.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ expert.h -o ../../moc/doxywizard/moc_expert.cpp
+
+../../moc/doxywizard/moc_helplabel.cpp: helplabel.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ helplabel.h -o ../../moc/doxywizard/moc_helplabel.cpp
+
+../../moc/doxywizard/moc_inputbool.cpp: input.h \
+ inputbool.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ inputbool.h -o ../../moc/doxywizard/moc_inputbool.cpp
+
+../../moc/doxywizard/moc_inputstring.cpp: input.h \
+ inputstring.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ inputstring.h -o ../../moc/doxywizard/moc_inputstring.cpp
+
+../../moc/doxywizard/moc_inputint.cpp: input.h \
+ inputint.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ inputint.h -o ../../moc/doxywizard/moc_inputint.cpp
+
+../../moc/doxywizard/moc_inputstrlist.cpp: input.h \
+ inputstrlist.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ inputstrlist.h -o ../../moc/doxywizard/moc_inputstrlist.cpp
+
+../../moc/doxywizard/moc_wizard.cpp: wizard.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ wizard.h -o ../../moc/doxywizard/moc_wizard.cpp
+
+compiler_rcc_make_all: ../../rcc/doxywizard/qrc_doxywizard.cpp
+compiler_rcc_clean:
+ -$(DEL_FILE) ../../rcc/doxywizard/qrc_doxywizard.cpp
+../../rcc/doxywizard/qrc_doxywizard.cpp: doxywizard.qrc \
+ ../../src/config.xml \
+ images/file.png \
+ images/add.png \
+ images/folder.png \
+ images/refresh.png \
+ images/tunecolor.png \
+ images/del.png
+ /usr/bin/rcc -name doxywizard doxywizard.qrc -o ../../rcc/doxywizard/qrc_doxywizard.cpp
+
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+ -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_rez_source_make_all:
+compiler_rez_source_clean:
+compiler_uic_make_all:
+compiler_uic_clean:
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean compiler_rcc_clean
+
+####### Compile
+
+../../objects/doxywizard/doxywizard.o: doxywizard.cpp doxywizard.h \
+ version.h \
+ expert.h \
+ docintf.h \
+ wizard.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/doxywizard.o doxywizard.cpp
+
+../../objects/doxywizard/expert.o: expert.cpp expert.h \
+ docintf.h \
+ inputbool.h \
+ input.h \
+ inputstring.h \
+ inputint.h \
+ inputstrlist.h \
+ config.h \
+ version.h \
+ configdoc.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/expert.o expert.cpp
+
+../../objects/doxywizard/wizard.o: wizard.cpp wizard.h \
+ input.h \
+ doxywizard.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/wizard.o wizard.cpp
+
+../../objects/doxywizard/inputbool.o: inputbool.cpp inputbool.h \
+ input.h \
+ helplabel.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/inputbool.o inputbool.cpp
+
+../../objects/doxywizard/inputstring.o: inputstring.cpp inputstring.h \
+ input.h \
+ helplabel.h \
+ doxywizard.h \
+ config.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/inputstring.o inputstring.cpp
+
+../../objects/doxywizard/inputint.o: inputint.cpp inputint.h \
+ input.h \
+ helplabel.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/inputint.o inputint.cpp
+
+../../objects/doxywizard/inputstrlist.o: inputstrlist.cpp inputstrlist.h \
+ input.h \
+ helplabel.h \
+ doxywizard.h \
+ config.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/inputstrlist.o inputstrlist.cpp
+
+../../objects/doxywizard/configdoc.o: ../../generated_src/doxywizard/configdoc.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/configdoc.o ../../generated_src/doxywizard/configdoc.cpp
+
+../../objects/doxywizard/config_doxyw.o: ../../generated_src/doxywizard/config_doxyw.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/config_doxyw.o ../../generated_src/doxywizard/config_doxyw.cpp
+
+../../objects/doxywizard/version.o: ../../generated_src/doxywizard/version.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/version.o ../../generated_src/doxywizard/version.cpp
+
+../../objects/doxywizard/moc_doxywizard.o: ../../moc/doxywizard/moc_doxywizard.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_doxywizard.o ../../moc/doxywizard/moc_doxywizard.cpp
+
+../../objects/doxywizard/moc_expert.o: ../../moc/doxywizard/moc_expert.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_expert.o ../../moc/doxywizard/moc_expert.cpp
+
+../../objects/doxywizard/moc_helplabel.o: ../../moc/doxywizard/moc_helplabel.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_helplabel.o ../../moc/doxywizard/moc_helplabel.cpp
+
+../../objects/doxywizard/moc_inputbool.o: ../../moc/doxywizard/moc_inputbool.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_inputbool.o ../../moc/doxywizard/moc_inputbool.cpp
+
+../../objects/doxywizard/moc_inputstring.o: ../../moc/doxywizard/moc_inputstring.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_inputstring.o ../../moc/doxywizard/moc_inputstring.cpp
+
+../../objects/doxywizard/moc_inputint.o: ../../moc/doxywizard/moc_inputint.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_inputint.o ../../moc/doxywizard/moc_inputint.cpp
+
+../../objects/doxywizard/moc_inputstrlist.o: ../../moc/doxywizard/moc_inputstrlist.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_inputstrlist.o ../../moc/doxywizard/moc_inputstrlist.cpp
+
+../../objects/doxywizard/moc_wizard.o: ../../moc/doxywizard/moc_wizard.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/moc_wizard.o ../../moc/doxywizard/moc_wizard.cpp
+
+../../objects/doxywizard/qrc_doxywizard.o: ../../rcc/doxywizard/qrc_doxywizard.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/doxywizard/qrc_doxywizard.o ../../rcc/doxywizard/qrc_doxywizard.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
diff --git a/addon/doxywizard/Makefile.in b/addon/doxywizard/Makefile.in
new file mode 100644
index 0000000..9b14174
--- /dev/null
+++ b/addon/doxywizard/Makefile.in
@@ -0,0 +1,40 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+
+QMAKE=$(QTDIR)/bin/qmake $(MKSPECS)
+INCBUFSIZE=$(PYTHON) ../../src/increasebuffer.py
+
+all: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard LEX=$(LEX) PYTHON=$(PYTHON) INCBUFSIZE="$(INCBUFSIZE)"
+
+Makefile.doxywizard: doxywizard.pro
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+qmake:
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+clean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard clean
+
+distclean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard distclean
+ $(RM) Makefile.doxywizard
+
+install:
+ $(INSTTOOL) -d $(INSTALL)/bin
+ $(INSTTOOL) -m 755 ../../bin/doxywizard $(INSTALL)/bin
+ $(INSTTOOL) -d $(INSTALL)/$(MAN1DIR)
+ cat ../../doc/doxywizard.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxywizard.1
+ $(INSTTOOL) -m 644 doxywizard.1 $(INSTALL)/$(MAN1DIR)/doxywizard.1
+ rm doxywizard.1
+
+FORCE:
diff --git a/addon/doxywizard/README b/addon/doxywizard/README
new file mode 100644
index 0000000..57705f0
--- /dev/null
+++ b/addon/doxywizard/README
@@ -0,0 +1,3 @@
+Doxywizard is a graphical front-end to read/edit/write doxygen configuration
+files and to launch doxygen. It requires Qt version 4.3 or higher.
+
diff --git a/addon/doxywizard/config.h b/addon/doxywizard/config.h
new file mode 100644
index 0000000..147056a
--- /dev/null
+++ b/addon/doxywizard/config.h
@@ -0,0 +1,27 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <QHash>
+#include <QString>
+
+class Input;
+class QTextStream;
+class QTextCodec;
+
+bool parseConfig(
+ const QString &fileName,
+ const QHash<QString,Input *> &options
+ );
+
+void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s);
+
+// directly copied from ../../src/config.h to be consistent
+enum
+{
+ /*! Maximum length of an option in the config file. Used for
+ * alignment purposes.
+ */
+ MAX_OPTION_LENGTH = 23
+};
+
+#endif
diff --git a/addon/doxywizard/config.l b/addon/doxywizard/config.l
new file mode 100644
index 0000000..f11bc46
--- /dev/null
+++ b/addon/doxywizard/config.l
@@ -0,0 +1,555 @@
+/******************************************************************************
+ *
+ * $Id: config_templ.l,v 1.8 2001/01/01 10:15:16 root Exp $
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include "config.h"
+#include "input.h"
+#include <QtCore>
+
+#define MAX_INCLUDE_DEPTH 10
+
+
+/* -----------------------------------------------------------------
+ *
+ * static variables
+ */
+
+struct ConfigFileState
+{
+ int lineNr;
+ FILE *file;
+ YY_BUFFER_STATE oldState;
+ YY_BUFFER_STATE newState;
+ QString fileName;
+};
+
+static const QHash<QString,Input*> *g_options;
+static FILE *g_file;
+static QString g_yyFileName;
+static QString g_includeName;
+static QVariant g_includePathList;
+static QStack<ConfigFileState*> g_includeStack;
+static int g_includeDepth;
+static QVariant *g_arg;
+static Input *g_curOption=0;
+static QString g_elemStr;
+static QTextCodec *g_codec = QTextCodec::codecForName("UTF-8");
+static QString g_codecName = QString::fromAscii("UTF-8");
+static int g_lastState;
+static QByteArray g_tmpString;
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int maxSize)
+{
+ // no file included
+ if (g_includeStack.isEmpty())
+ {
+ return fread(buf,1,maxSize,g_file);
+ }
+ else
+ {
+ return fread(buf,1,maxSize,g_includeStack.top()->file);
+ }
+}
+
+void config_err(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+void config_warn(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+static void substEnvVarsInStrList(QStringList &sl);
+static void substEnvVarsInString(QString &s);
+
+static void checkEncoding()
+{
+ Input *option = g_options->value(QString::fromAscii("DOXYFILE_ENCODING"));
+ if (option && option->value().toString()!=g_codecName)
+ {
+ QTextCodec *newCodec = QTextCodec::codecForName(option->value().toString().toAscii());
+ if (newCodec)
+ {
+ g_codec = newCodec;
+ g_codecName = option->value().toString();
+ }
+ }
+}
+
+static FILE *tryPath(const QString &path,const QString &fileName)
+{
+ QString absName=!path.isEmpty() ? path+QString::fromAscii("/")+fileName : fileName;
+ QFileInfo fi(absName);
+ if (fi.exists() && fi.isFile())
+ {
+ FILE *f = fopen(absName.toLocal8Bit(),"r");
+ if (f==NULL)
+ config_err("Error: could not open file %s for reading\n",absName.toLatin1().data());
+ else
+ return f;
+ }
+ return NULL;
+}
+
+static FILE *findFile(const QString &fileName)
+{
+ if (QFileInfo(fileName).isAbsolute()) // absolute path
+ {
+ return tryPath(QString(), fileName);
+ }
+
+ // relative path, try with include paths in the list
+ QStringList sl = g_includePathList.toStringList();
+ substEnvVarsInStrList(sl);
+ foreach (QString s, sl)
+ {
+ FILE *f = tryPath(s,fileName);
+ if (f) return f;
+ }
+ // try cwd if g_includePathList fails
+ return tryPath(QString::fromAscii("."),fileName);
+}
+
+static void readIncludeFile(const QString &incName)
+{
+ if (g_includeDepth==MAX_INCLUDE_DEPTH)
+ {
+ config_err("Error: maximum include depth (%d) reached, %s is not included. Aborting...\n",
+ MAX_INCLUDE_DEPTH,qPrintable(incName));
+ exit(1);
+ }
+
+ QString inc = incName;
+ substEnvVarsInString(inc);
+ inc = inc.trimmed();
+ uint incLen = inc.length();
+ if (inc.at(0)==QChar::fromAscii('"') &&
+ inc.at(incLen-1)==QChar::fromAscii('"')) // strip quotes
+ {
+ inc=inc.mid(1,incLen-2);
+ }
+
+ FILE *f = findFile(inc);
+ if (f) // see if the include file can be found
+ {
+ // For debugging
+#if SHOW_INCLUDES
+ for (i=0;i<includeStack.count();i++) msg(" ");
+ msg("@INCLUDE = %s: parsing...\n",inc.toLatin1().data());
+#endif
+
+ // store the state of the old file
+ ConfigFileState *fs=new ConfigFileState;
+ fs->oldState=YY_CURRENT_BUFFER;
+ fs->fileName=g_yyFileName;
+ fs->file=f;
+ // push the state on the stack
+ g_includeStack.push(fs);
+ // set the scanner to the include file
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ fs->newState=YY_CURRENT_BUFFER;
+ g_yyFileName=inc;
+ g_includeDepth++;
+ }
+ else
+ {
+ config_err("Error: @INCLUDE = %s: not found!\n",inc.toLatin1().data());
+ exit(1);
+ }
+}
+
+
+%}
+
+%option nounput
+%option noyywrap
+%option yylineno
+
+%x Start
+%x SkipComment
+%x SkipInvalid
+%x GetString
+%x GetStrList
+%x GetQuotedString
+%x GetEnvVar
+%x Include
+
+%%
+
+<*>\0x0d
+<Start,GetString,GetStrList,SkipInvalid>"#" { BEGIN(SkipComment); }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QString cmd = g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-1).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ //option->setEncoding(encoding);
+ g_arg = &g_curOption->value();
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_elemStr = QString();
+ *g_arg = QStringList();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ BEGIN(GetString);
+ break;
+ case Input::Int:
+ BEGIN(GetString);
+ break;
+ case Input::Bool:
+ BEGIN(GetString);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n", qPrintable(cmd),
+ yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QString cmd=g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-2).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_arg = &g_curOption->value();
+ g_elemStr=QString();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ case Input::Int:
+ case Input::Bool:
+ config_err("Warning: operator += not supported for `%s'. Ignoring line at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_arg=&g_includePathList; *g_arg = QStringList(); g_elemStr=QString(); }
+ /* include a config file */
+<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
+<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
+ readIncludeFile(g_codec->toUnicode(yytext));
+ BEGIN(Start);
+ }
+<<EOF>> {
+ //printf("End of include file\n");
+ //printf("Include stack depth=%d\n",g_includeStack.count());
+ if (g_includeStack.isEmpty())
+ {
+ //printf("Terminating scanner!\n");
+ yyterminate();
+ }
+ else
+ {
+ ConfigFileState *fs = g_includeStack.pop();
+ fclose(fs->file);
+ YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer( fs->oldState );
+ yy_delete_buffer( oldBuf );
+ g_yyFileName=fs->fileName;
+ delete fs;
+ g_includeDepth--;
+ }
+ }
+
+<Start>[a-z_A-Z0-9]+ { config_err("Warning: ignoring unknown tag `%s' at line %d, file %s\n",yytext,yylineno,qPrintable(g_yyFileName)); }
+<GetString,SkipInvalid>\n { BEGIN(Start); }
+<GetStrList>\n {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr1=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ BEGIN(Start);
+ }
+<GetStrList>[ \t]+ {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr2=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ g_elemStr = QString();
+ }
+<GetString>[^ \"\t\r\n]+ {
+ *g_arg = QVariant(g_codec->toUnicode(yytext));
+ checkEncoding();
+ }
+<GetString,GetStrList,SkipInvalid>"\"" { g_lastState=YY_START;
+ BEGIN(GetQuotedString);
+ g_tmpString="";
+ }
+<GetQuotedString>"\""|"\n" {
+ // we add a bogus space to signal that the string was quoted. This space will be stripped later on.
+ g_tmpString+=" ";
+ //printf("Quoted String = `%s'\n",tmpString.toLatin1().data());
+ if (g_lastState==GetString)
+ {
+ *g_arg = g_codec->toUnicode(g_tmpString);
+ checkEncoding();
+ }
+ else
+ {
+ g_elemStr+=g_codec->toUnicode(g_tmpString);
+ }
+ if (*yytext=='\n')
+ {
+ config_err("Warning: Missing end quote (\") on line %d, file %s\n",yylineno,
+ qPrintable(g_yyFileName));
+ }
+ BEGIN(g_lastState);
+ }
+<GetQuotedString>"\\\"" {
+ g_tmpString+='"';
+ }
+<GetQuotedString>. { g_tmpString+=*yytext; }
+<GetStrList>[^ \#\"\t\r\n]+ {
+ g_elemStr+=g_codec->toUnicode(yytext);
+ }
+<SkipComment>\n { BEGIN(Start); }
+<SkipComment>\\[ \r\t]*\n { BEGIN(Start); }
+<*>\\[ \r\t]*\n { }
+<*>\n
+<*>.
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+static void substEnvVarsInString(QString &s)
+{
+ static QRegExp re(QString::fromAscii("\\$\\([a-z_A-Z0-9]+\\)"));
+ if (s.isEmpty()) return;
+ int p=0;
+ int i,l;
+ //printf("substEnvVarInString(%s) start\n",s.toLatin1().data());
+ while ((i=re.indexIn(s,p))!=-1)
+ {
+ l = re.matchedLength();
+ //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).toLatin1().data());
+ QString env=g_codec->toUnicode(getenv(s.mid(i+2,l-3).toLatin1()));
+ substEnvVarsInString(env); // recursively expand variables if needed.
+ s = s.left(i)+env+s.right(s.length()-i-l);
+ p=i+env.length(); // next time start at the end of the expanded string
+ }
+ s=s.trimmed(); // to strip the bogus space that was added when an argument
+ // has quotes
+ //printf("substEnvVarInString(%s) end\n",s.toLatin1().data());
+}
+
+static void substEnvVarsInStrList(QStringList &sl)
+{
+ QStringList out;
+
+ foreach (QString result, sl)
+ {
+ // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
+ bool wasQuoted = (result.indexOf(QChar::fromAscii(' '))!=-1) ||
+ (result.indexOf(QChar::fromAscii('\t'))!=-1);
+ // here we strip the quote again
+ substEnvVarsInString(result);
+
+ //printf("Result %s was quoted=%d\n",result.toLatin1().data(),wasQuoted);
+
+ if (!wasQuoted) /* as a result of the expansion, a single string
+ may have expanded into a list, which we'll
+ add to sl. If the original string already
+ contained multiple elements no further
+ splitting is done to allow quoted items with spaces! */
+ {
+ int l=result.length();
+ int i,p=0;
+ // skip spaces
+ // search for a "word"
+ for (i=0;i<l;i++)
+ {
+ QChar c=0;
+ // skip until start of new word
+ while (i<l && ((c=result.at(i))==QChar::fromAscii(' ') || c==QChar::fromAscii('\t'))) i++;
+ p=i; // p marks the start index of the word
+ // skip until end of a word
+ while (i<l && ((c=result.at(i))!=QChar::fromAscii(' ') &&
+ c!=QChar::fromAscii('\t') &&
+ c!=QChar::fromAscii('"'))) i++;
+ if (i<l) // not at the end of the string
+ {
+ if (c==QChar::fromAscii('"')) // word within quotes
+ {
+ p=i+1;
+ for (i++;i<l;i++)
+ {
+ c=result.at(i);
+ if (c==QChar::fromAscii('"')) // end quote
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ break;
+ }
+ else if (c==QChar::fromAscii('\\')) // skip escaped stuff
+ {
+ i++;
+ }
+ }
+ }
+ else if (c==QChar::fromAscii(' ') || c==QChar::fromAscii('\t')) // separator
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ }
+ }
+ }
+ if (p!=l) // add the leftover as a string
+ {
+ out += result.right(l-p);
+ }
+ }
+ else // just goto the next element in the list
+ {
+ out += result;
+ }
+ }
+ sl = out;
+}
+
+//--------------------------------------------------------------------------
+
+bool parseConfig(
+ const QString &fileName,
+ const QHash<QString,Input *> &options
+ )
+{
+ QHashIterator<QString, Input*> i(options);
+ g_file = fopen(fileName.toLocal8Bit(),"r");
+ if (g_file==NULL) return false;
+
+ // reset all values
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->reset();
+ }
+ }
+
+ // parse config file
+ g_options = &options;
+ g_yyFileName = fileName;
+ g_includeStack.clear();
+ g_includeDepth = 0;
+ configrestart( configin );
+ BEGIN( Start );
+ configlex();
+
+ // update the values in the UI
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ //printf("Updating: %s\n",qPrintable(i.key()));
+ i.value()->update();
+ }
+ else
+ {
+ printf("Invalid option: %s\n",qPrintable(i.key()));
+ }
+ }
+ fclose(g_file);
+ return true;
+}
+
+void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
+{
+ QChar c;
+ bool needsEscaping=FALSE;
+ // convert the string back to it original encoding
+ //QByteArray se = codec->fromUnicode(s);
+ t.setCodec(codec);
+ const QChar *p=s.data();
+ if (!s.isEmpty() && !p->isNull())
+ {
+ while (!(c=*p++).isNull() && !needsEscaping)
+ {
+ needsEscaping = (c==QChar::fromAscii(' ') ||
+ c==QChar::fromAscii('\n') ||
+ c==QChar::fromAscii('\t') ||
+ c==QChar::fromAscii('"'));
+ }
+ if (needsEscaping)
+ {
+ t << "\"";
+ p=s.data();
+ while (!p->isNull())
+ {
+ if (*p ==QChar::fromAscii(' ') &&
+ *(p+1)==QChar::fromAscii('\0')) break; // skip inserted space at the end
+ if (*p ==QChar::fromAscii('"')) t << "\\"; // escape quotes
+ t << *p++;
+ }
+ t << "\"";
+ }
+ else
+ {
+ t << s;
+ }
+ }
+}
+
diff --git a/addon/doxywizard/config_doxyw.l b/addon/doxywizard/config_doxyw.l
new file mode 100644
index 0000000..400330f
--- /dev/null
+++ b/addon/doxywizard/config_doxyw.l
@@ -0,0 +1,555 @@
+/******************************************************************************
+ *
+ * $Id: config_templ.l,v 1.8 2001/01/01 10:15:16 root Exp $
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include "config.h"
+#include "input.h"
+#include <QtCore>
+
+#define MAX_INCLUDE_DEPTH 10
+
+
+/* -----------------------------------------------------------------
+ *
+ * static variables
+ */
+
+struct ConfigFileState
+{
+ int lineNr;
+ FILE *file;
+ YY_BUFFER_STATE oldState;
+ YY_BUFFER_STATE newState;
+ QString fileName;
+};
+
+static const QHash<QString,Input*> *g_options;
+static FILE *g_file;
+static QString g_yyFileName;
+static QString g_includeName;
+static QVariant g_includePathList;
+static QStack<ConfigFileState*> g_includeStack;
+static int g_includeDepth;
+static QVariant *g_arg;
+static Input *g_curOption=0;
+static QString g_elemStr;
+static QTextCodec *g_codec = QTextCodec::codecForName("UTF-8");
+static QString g_codecName = QString::fromAscii("UTF-8");
+static int g_lastState;
+static QByteArray g_tmpString;
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int maxSize)
+{
+ // no file included
+ if (g_includeStack.isEmpty())
+ {
+ return fread(buf,1,maxSize,g_file);
+ }
+ else
+ {
+ return fread(buf,1,maxSize,g_includeStack.top()->file);
+ }
+}
+
+void config_err(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+void config_warn(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+static void substEnvVarsInStrList(QStringList &sl);
+static void substEnvVarsInString(QString &s);
+
+static void checkEncoding()
+{
+ Input *option = g_options->value(QString::fromAscii("DOXYFILE_ENCODING"));
+ if (option && option->value().toString()!=g_codecName)
+ {
+ QTextCodec *newCodec = QTextCodec::codecForName(option->value().toString().toAscii());
+ if (newCodec)
+ {
+ g_codec = newCodec;
+ g_codecName = option->value().toString();
+ }
+ }
+}
+
+static FILE *tryPath(const QString &path,const QString &fileName)
+{
+ QString absName=!path.isEmpty() ? path+QString::fromAscii("/")+fileName : fileName;
+ QFileInfo fi(absName);
+ if (fi.exists() && fi.isFile())
+ {
+ FILE *f = fopen(absName.toLocal8Bit(),"r");
+ if (f==NULL)
+ config_err("Error: could not open file %s for reading\n",absName.toLatin1().data());
+ else
+ return f;
+ }
+ return NULL;
+}
+
+static FILE *findFile(const QString &fileName)
+{
+ if (QFileInfo(fileName).isAbsolute()) // absolute path
+ {
+ return tryPath(QString(), fileName);
+ }
+
+ // relative path, try with include paths in the list
+ QStringList sl = g_includePathList.toStringList();
+ substEnvVarsInStrList(sl);
+ foreach (QString s, sl)
+ {
+ FILE *f = tryPath(s,fileName);
+ if (f) return f;
+ }
+ // try cwd if g_includePathList fails
+ return tryPath(QString::fromAscii("."),fileName);
+}
+
+static void readIncludeFile(const QString &incName)
+{
+ if (g_includeDepth==MAX_INCLUDE_DEPTH)
+ {
+ config_err("Error: maximum include depth (%d) reached, %s is not included. Aborting...\n",
+ MAX_INCLUDE_DEPTH,qPrintable(incName));
+ exit(1);
+ }
+
+ QString inc = incName;
+ substEnvVarsInString(inc);
+ inc = inc.trimmed();
+ uint incLen = inc.length();
+ if (inc.at(0)==QChar::fromAscii('"') &&
+ inc.at(incLen-1)==QChar::fromAscii('"')) // strip quotes
+ {
+ inc=inc.mid(1,incLen-2);
+ }
+
+ FILE *f = findFile(inc);
+ if (f) // see if the include file can be found
+ {
+ // For debugging
+#if SHOW_INCLUDES
+ for (i=0;i<includeStack.count();i++) msg(" ");
+ msg("@INCLUDE = %s: parsing...\n",inc.toLatin1().data());
+#endif
+
+ // store the state of the old file
+ ConfigFileState *fs=new ConfigFileState;
+ fs->oldState=YY_CURRENT_BUFFER;
+ fs->fileName=g_yyFileName;
+ fs->file=f;
+ // push the state on the stack
+ g_includeStack.push(fs);
+ // set the scanner to the include file
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ fs->newState=YY_CURRENT_BUFFER;
+ g_yyFileName=inc;
+ g_includeDepth++;
+ }
+ else
+ {
+ config_err("Error: @INCLUDE = %s: not found!\n",inc.toLatin1().data());
+ exit(1);
+ }
+}
+
+
+%}
+
+%option nounput
+%option noyywrap
+%option yylineno
+
+%x Start
+%x SkipComment
+%x SkipInvalid
+%x GetString
+%x GetStrList
+%x GetQuotedString
+%x GetEnvVar
+%x Include
+
+%%
+
+<*>\0x0d
+<Start,GetString,GetStrList,SkipInvalid>"#" { BEGIN(SkipComment); }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QString cmd = g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-1).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ //option->setEncoding(encoding);
+ g_arg = &g_curOption->value();
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_elemStr = QString();
+ *g_arg = QStringList();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ BEGIN(GetString);
+ break;
+ case Input::Int:
+ BEGIN(GetString);
+ break;
+ case Input::Bool:
+ BEGIN(GetString);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n", qPrintable(cmd),
+ yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QString cmd=g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-2).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_arg = &g_curOption->value();
+ g_elemStr=QString();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ case Input::Int:
+ case Input::Bool:
+ config_err("Warning: operator += not supported for `%s'. Ignoring line at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_arg=&g_includePathList; *g_arg = QStringList(); g_elemStr=QString(); }
+ /* include a config file */
+<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
+<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
+ readIncludeFile(g_codec->toUnicode(yytext));
+ BEGIN(Start);
+ }
+<<EOF>> {
+ //printf("End of include file\n");
+ //printf("Include stack depth=%d\n",g_includeStack.count());
+ if (g_includeStack.isEmpty())
+ {
+ //printf("Terminating scanner!\n");
+ yyterminate();
+ }
+ else
+ {
+ ConfigFileState *fs = g_includeStack.pop();
+ fclose(fs->file);
+ YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer( fs->oldState );
+ yy_delete_buffer( oldBuf );
+ g_yyFileName=fs->fileName;
+ delete fs;
+ g_includeDepth--;
+ }
+ }
+
+<Start>[a-z_A-Z0-9]+ { config_err("Warning: ignoring unknown tag `%s' at line %d, file %s\n",yytext,yylineno,qPrintable(g_yyFileName)); }
+<GetString,SkipInvalid>\n { BEGIN(Start); }
+<GetStrList>\n {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr1=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ BEGIN(Start);
+ }
+<GetStrList>[ \t]+ {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr2=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ g_elemStr = QString();
+ }
+<GetString>[^ \"\t\r\n]+ {
+ *g_arg = QVariant(g_codec->toUnicode(yytext));
+ checkEncoding();
+ }
+<GetString,GetStrList,SkipInvalid>"\"" { g_lastState=YY_START;
+ BEGIN(GetQuotedString);
+ g_tmpString="";
+ }
+<GetQuotedString>"\""|"\n" {
+ // we add a bogus space to signal that the string was quoted. This space will be stripped later on.
+ g_tmpString+=" ";
+ //printf("Quoted String = `%s'\n",tmpString.toLatin1().data());
+ if (g_lastState==GetString)
+ {
+ *g_arg = g_codec->toUnicode(g_tmpString);
+ checkEncoding();
+ }
+ else
+ {
+ g_elemStr+=g_codec->toUnicode(g_tmpString);
+ }
+ if (*yytext=='\n')
+ {
+ config_err("Warning: Missing end quote (\") on line %d, file %s\n",yylineno,
+ qPrintable(g_yyFileName));
+ }
+ BEGIN(g_lastState);
+ }
+<GetQuotedString>"\\\"" {
+ g_tmpString+='"';
+ }
+<GetQuotedString>. { g_tmpString+=*yytext; }
+<GetStrList>[^ \#\"\t\r\n]+ {
+ g_elemStr+=g_codec->toUnicode(yytext);
+ }
+<SkipComment>\n { BEGIN(Start); }
+<SkipComment>\\[ \r\t]*\n { BEGIN(Start); }
+<*>\\[ \r\t]*\n { }
+<*>\n
+<*>.
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+static void substEnvVarsInString(QString &s)
+{
+ static QRegExp re(QString::fromAscii("\\$\\([a-z_A-Z0-9]+\\)"));
+ if (s.isEmpty()) return;
+ int p=0;
+ int i,l;
+ //printf("substEnvVarInString(%s) start\n",s.toLatin1().data());
+ while ((i=re.indexIn(s,p))!=-1)
+ {
+ l = re.matchedLength();
+ //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).toLatin1().data());
+ QString env=g_codec->toUnicode(getenv(s.mid(i+2,l-3).toLatin1()));
+ substEnvVarsInString(env); // recursively expand variables if needed.
+ s = s.left(i)+env+s.right(s.length()-i-l);
+ p=i+env.length(); // next time start at the end of the expanded string
+ }
+ s=s.trimmed(); // to strip the bogus space that was added when an argument
+ // has quotes
+ //printf("substEnvVarInString(%s) end\n",s.toLatin1().data());
+}
+
+static void substEnvVarsInStrList(QStringList &sl)
+{
+ QStringList out;
+
+ foreach (QString result, sl)
+ {
+ // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
+ bool wasQuoted = (result.indexOf(QChar::fromAscii(' '))!=-1) ||
+ (result.indexOf(QChar::fromAscii('\t'))!=-1);
+ // here we strip the quote again
+ substEnvVarsInString(result);
+
+ //printf("Result %s was quoted=%d\n",result.toLatin1().data(),wasQuoted);
+
+ if (!wasQuoted) /* as a result of the expansion, a single string
+ may have expanded into a list, which we'll
+ add to sl. If the original string already
+ contained multiple elements no further
+ splitting is done to allow quoted items with spaces! */
+ {
+ int l=result.length();
+ int i,p=0;
+ // skip spaces
+ // search for a "word"
+ for (i=0;i<l;i++)
+ {
+ QChar c=0;
+ // skip until start of new word
+ while (i<l && ((c=result.at(i))==QChar::fromAscii(' ') || c==QChar::fromAscii('\t'))) i++;
+ p=i; // p marks the start index of the word
+ // skip until end of a word
+ while (i<l && ((c=result.at(i))!=QChar::fromAscii(' ') &&
+ c!=QChar::fromAscii('\t') &&
+ c!=QChar::fromAscii('"'))) i++;
+ if (i<l) // not at the end of the string
+ {
+ if (c==QChar::fromAscii('"')) // word within quotes
+ {
+ p=i+1;
+ for (i++;i<l;i++)
+ {
+ c=result.at(i);
+ if (c==QChar::fromAscii('"')) // end quote
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ break;
+ }
+ else if (c==QChar::fromAscii('\\')) // skip escaped stuff
+ {
+ i++;
+ }
+ }
+ }
+ else if (c==QChar::fromAscii(' ') || c==QChar::fromAscii('\t')) // separator
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ }
+ }
+ }
+ if (p!=l) // add the leftover as a string
+ {
+ out += result.right(l-p);
+ }
+ }
+ else // just goto the next element in the list
+ {
+ out += result;
+ }
+ }
+ sl = out;
+}
+
+//--------------------------------------------------------------------------
+
+bool parseConfig(
+ const QString &fileName,
+ const QHash<QString,Input *> &options
+ )
+{
+ QHashIterator<QString, Input*> i(options);
+ g_file = fopen(fileName.toLocal8Bit(),"r");
+ if (g_file==NULL) return false;
+
+ // reset all values
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->reset();
+ }
+ }
+
+ // parse config file
+ g_options = &options;
+ g_yyFileName = fileName;
+ g_includeStack.clear();
+ g_includeDepth = 0;
+ config_doxywYYrestart( config_doxywYYin );
+ BEGIN( Start );
+ config_doxywYYlex();
+
+ // update the values in the UI
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ //printf("Updating: %s\n",qPrintable(i.key()));
+ i.value()->update();
+ }
+ else
+ {
+ printf("Invalid option: %s\n",qPrintable(i.key()));
+ }
+ }
+ fclose(g_file);
+ return true;
+}
+
+void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
+{
+ QChar c;
+ bool needsEscaping=FALSE;
+ // convert the string back to it original encoding
+ //QByteArray se = codec->fromUnicode(s);
+ t.setCodec(codec);
+ const QChar *p=s.data();
+ if (!s.isEmpty() && !p->isNull())
+ {
+ while (!(c=*p++).isNull() && !needsEscaping)
+ {
+ needsEscaping = (c==QChar::fromAscii(' ') ||
+ c==QChar::fromAscii('\n') ||
+ c==QChar::fromAscii('\t') ||
+ c==QChar::fromAscii('"'));
+ }
+ if (needsEscaping)
+ {
+ t << "\"";
+ p=s.data();
+ while (!p->isNull())
+ {
+ if (*p ==QChar::fromAscii(' ') &&
+ *(p+1)==QChar::fromAscii('\0')) break; // skip inserted space at the end
+ if (*p ==QChar::fromAscii('"')) t << "\\"; // escape quotes
+ t << *p++;
+ }
+ t << "\"";
+ }
+ else
+ {
+ t << s;
+ }
+ }
+}
+
diff --git a/addon/doxywizard/configdoc.h b/addon/doxywizard/configdoc.h
new file mode 100644
index 0000000..97ed6c3
--- /dev/null
+++ b/addon/doxywizard/configdoc.h
@@ -0,0 +1,8 @@
+#ifndef CONFIGDOC_H
+#define CONFIGDOC_H
+
+class DocIntf;
+
+void addConfigDocs(DocIntf *doc);
+
+#endif
diff --git a/addon/doxywizard/docintf.h b/addon/doxywizard/docintf.h
new file mode 100644
index 0000000..6c0ff26
--- /dev/null
+++ b/addon/doxywizard/docintf.h
@@ -0,0 +1,12 @@
+#ifndef DOCINTF_H
+#define DOCINTF_H
+
+class DocIntf
+{
+ public:
+ virtual ~DocIntf() {}
+ virtual void setHeader(const char *header) = 0;
+ virtual void add(const char *name,const char *docs) = 0;
+};
+
+#endif
diff --git a/addon/doxywizard/doxywizard.cpp b/addon/doxywizard/doxywizard.cpp
new file mode 100644
index 0000000..26df065
--- /dev/null
+++ b/addon/doxywizard/doxywizard.cpp
@@ -0,0 +1,665 @@
+#include <QtGui>
+#include "doxywizard.h"
+#include "version.h"
+#include "expert.h"
+#include "wizard.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#define MAX_RECENT_FILES 10
+
+const int messageTimeout = 5000; //!< status bar message timeout in millisec.
+
+MainWindow &MainWindow::instance()
+{
+ static MainWindow *theInstance = new MainWindow;
+ return *theInstance;
+}
+
+MainWindow::MainWindow()
+ : m_settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"))
+{
+ QMenu *file = menuBar()->addMenu(tr("File"));
+ file->addAction(tr("Open..."),
+ this, SLOT(openConfig()), Qt::CTRL+Qt::Key_O);
+ m_recentMenu = file->addMenu(tr("Open recent"));
+ file->addAction(tr("Save"),
+ this, SLOT(saveConfig()), Qt::CTRL+Qt::Key_S);
+ file->addAction(tr("Save as..."),
+ this, SLOT(saveConfigAs()), Qt::SHIFT+Qt::CTRL+Qt::Key_S);
+ file->addAction(tr("Quit"),
+ this, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
+
+ QMenu *settings = menuBar()->addMenu(tr("Settings"));
+ settings->addAction(tr("Reset to factory defaults"),
+ this,SLOT(resetToDefaults()));
+ settings->addAction(tr("Use current settings at startup"),
+ this,SLOT(makeDefaults()));
+ settings->addAction(tr("Clear recent list"),
+ this,SLOT(clearRecent()));
+
+ QMenu *help = menuBar()->addMenu(tr("Help"));
+ help->addAction(tr("Online manual"),
+ this, SLOT(manual()), Qt::Key_F1);
+ help->addAction(tr("About"),
+ this, SLOT(about()) );
+
+ m_expert = new Expert;
+ m_wizard = new Wizard(m_expert->modelData());
+
+ // ----------- top part ------------------
+ QWidget *topPart = new QWidget;
+ QVBoxLayout *rowLayout = new QVBoxLayout(topPart);
+
+ // select working directory
+ QHBoxLayout *dirLayout = new QHBoxLayout;
+ m_workingDir = new QLineEdit;
+ m_selWorkingDir = new QPushButton(tr("Select..."));
+ dirLayout->addWidget(m_workingDir);
+ dirLayout->addWidget(m_selWorkingDir);
+
+ //------------- bottom part --------------
+ QWidget *runTab = new QWidget;
+ QVBoxLayout *runTabLayout = new QVBoxLayout(runTab);
+
+ // run doxygen
+ QHBoxLayout *runLayout = new QHBoxLayout;
+ m_run = new QPushButton(tr("Run doxygen"));
+ m_run->setEnabled(false);
+ m_runStatus = new QLabel(tr("Status: not running"));
+ m_saveLog = new QPushButton(tr("Save log..."));
+ m_saveLog->setEnabled(false);
+ QPushButton *showSettings = new QPushButton(tr("Show configuration"));
+ runLayout->addWidget(m_run);
+ runLayout->addWidget(m_runStatus);
+ runLayout->addStretch(1);
+ runLayout->addWidget(showSettings);
+ runLayout->addWidget(m_saveLog);
+
+ // output produced by doxygen
+ runTabLayout->addLayout(runLayout);
+ runTabLayout->addWidget(new QLabel(tr("Output produced by doxygen")));
+ QGridLayout *grid = new QGridLayout;
+ m_outputLog = new QTextEdit;
+ m_outputLog->setReadOnly(true);
+ m_outputLog->setFontFamily(QString::fromAscii("courier"));
+ m_outputLog->setMinimumWidth(600);
+ grid->addWidget(m_outputLog,0,0);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+ QHBoxLayout *launchLayout = new QHBoxLayout;
+ m_launchHtml = new QPushButton(tr("Show HTML output"));
+ launchLayout->addWidget(m_launchHtml);
+
+ launchLayout->addStretch(1);
+ grid->addLayout(launchLayout,1,0);
+ runTabLayout->addLayout(grid);
+
+ m_tabs = new QTabWidget;
+ m_tabs->addTab(m_wizard,tr("Wizard"));
+ m_tabs->addTab(m_expert,tr("Expert"));
+ m_tabs->addTab(runTab,tr("Run"));
+
+ rowLayout->addWidget(new QLabel(tr("Step 1: Specify the working directory from which doxygen will run")));
+ rowLayout->addLayout(dirLayout);
+ rowLayout->addWidget(new QLabel(tr("Step 2: Configure doxygen using the Wizard and/or Expert tab, then switch to the Run tab to generate the documentation")));
+ rowLayout->addWidget(m_tabs);
+
+ setCentralWidget(topPart);
+ statusBar()->showMessage(tr("Welcome to Doxygen"),messageTimeout);
+
+ m_runProcess = new QProcess;
+ m_running = false;
+ m_timer = new QTimer;
+
+ // connect signals and slots
+ connect(m_tabs,SIGNAL(currentChanged(int)),SLOT(selectTab(int)));
+ connect(m_selWorkingDir,SIGNAL(clicked()),SLOT(selectWorkingDir()));
+ connect(m_recentMenu,SIGNAL(triggered(QAction*)),SLOT(openRecent(QAction*)));
+ connect(m_workingDir,SIGNAL(returnPressed()),SLOT(updateWorkingDir()));
+ connect(m_runProcess,SIGNAL(readyReadStandardOutput()),SLOT(readStdout()));
+ connect(m_runProcess,SIGNAL(finished(int, QProcess::ExitStatus)),SLOT(runComplete()));
+ connect(m_timer,SIGNAL(timeout()),SLOT(readStdout()));
+ connect(m_run,SIGNAL(clicked()),SLOT(runDoxygen()));
+ connect(m_launchHtml,SIGNAL(clicked()),SLOT(showHtmlOutput()));
+ connect(m_saveLog,SIGNAL(clicked()),SLOT(saveLog()));
+ connect(showSettings,SIGNAL(clicked()),SLOT(showSettings()));
+ connect(m_expert,SIGNAL(changed()),SLOT(configChanged()));
+ connect(m_wizard,SIGNAL(done()),SLOT(selectRunTab()));
+ connect(m_expert,SIGNAL(done()),SLOT(selectRunTab()));
+
+ loadSettings();
+ updateLaunchButtonState();
+ m_modified = false;
+ updateTitle();
+ m_wizard->refresh();
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (discardUnsavedChanges())
+ {
+ saveSettings();
+ event->accept();
+ }
+ else
+ {
+ event->ignore();
+ }
+}
+
+void MainWindow::quit()
+{
+ if (discardUnsavedChanges())
+ {
+ saveSettings();
+ }
+ QApplication::exit(0);
+}
+
+void MainWindow::setWorkingDir(const QString &dirName)
+{
+ QDir::setCurrent(dirName);
+ m_workingDir->setText(dirName);
+ m_run->setEnabled(!dirName.isEmpty());
+}
+
+void MainWindow::selectWorkingDir()
+{
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select working directory"),m_workingDir->text());
+ if (!dirName.isEmpty())
+ {
+ setWorkingDir(dirName);
+ }
+}
+
+void MainWindow::updateWorkingDir()
+{
+ setWorkingDir(m_workingDir->text());
+}
+
+void MainWindow::manual()
+{
+ QDesktopServices::openUrl(QUrl(QString::fromAscii("http://www.doxygen.org/manual.html")));
+}
+
+void MainWindow::about()
+{
+ QString msg;
+ QTextStream t(&msg,QIODevice::WriteOnly);
+ t << QString::fromAscii("<qt><center>A tool to configure and run doxygen version ")+
+ QString::fromAscii(versionString)+
+ QString::fromAscii(" on your source files.</center><p><br>"
+ "<center>Written by<br> Dimitri van Heesch<br>© 2000-2014</center><p>"
+ "</qt>");
+ QMessageBox::about(this,tr("Doxygen GUI"),msg);
+}
+
+void MainWindow::openConfig()
+{
+ if (discardUnsavedChanges(false))
+ {
+ QString fn = QFileDialog::getOpenFileName(this,
+ tr("Open configuration file"),
+ m_workingDir->text());
+ if (!fn.isEmpty())
+ {
+ loadConfigFromFile(fn);
+ }
+ }
+}
+
+void MainWindow::updateConfigFileName(const QString &fileName)
+{
+ if (m_fileName!=fileName)
+ {
+ m_fileName = fileName;
+ QString curPath = QFileInfo(fileName).path();
+ setWorkingDir(curPath);
+ addRecentFile(fileName);
+ updateTitle();
+ }
+}
+
+void MainWindow::loadConfigFromFile(const QString & fileName)
+{
+ // save full path info of original file
+ QString absFileName = QFileInfo(fileName).absoluteFilePath();
+ // updates the current directory
+ updateConfigFileName(fileName);
+ // open the specified configuration file
+ m_expert->loadConfig(absFileName);
+ m_wizard->refresh();
+ updateLaunchButtonState();
+ m_modified = false;
+ updateTitle();
+}
+
+void MainWindow::saveConfig(const QString &fileName)
+{
+ if (fileName.isEmpty()) return;
+ QFile f(fileName);
+ if (!f.open(QIODevice::WriteOnly))
+ {
+ QMessageBox::warning(this,
+ tr("Error saving"),
+ tr("Error: cannot open the file ")+fileName+tr(" for writing!\n")+
+ tr("Reason given: ")+f.error());
+ return;
+ }
+ QTextStream t(&f);
+ m_expert->writeConfig(t,false);
+ updateConfigFileName(fileName);
+ m_modified = false;
+ updateTitle();
+}
+
+bool MainWindow::saveConfig()
+{
+ if (m_fileName.isEmpty())
+ {
+ return saveConfigAs();
+ }
+ else
+ {
+ saveConfig(m_fileName);
+ return true;
+ }
+}
+
+bool MainWindow::saveConfigAs()
+{
+ QString fileName = QFileDialog::getSaveFileName(this, QString(),
+ m_workingDir->text()+QString::fromAscii("/Doxyfile"));
+ if (fileName.isEmpty()) return false;
+ saveConfig(fileName);
+ return true;
+}
+
+void MainWindow::makeDefaults()
+{
+ if (QMessageBox::question(this,tr("Use current setting at startup?"),
+ tr("Do you want to save the current settings "
+ "and use them next time Doxywizard starts?"),
+ QMessageBox::Save|
+ QMessageBox::Cancel)==QMessageBox::Save)
+ {
+ //printf("MainWindow:makeDefaults()\n");
+ m_expert->saveSettings(&m_settings);
+ m_settings.setValue(QString::fromAscii("wizard/loadsettings"), true);
+ m_settings.sync();
+ }
+}
+
+void MainWindow::clearRecent()
+{
+ if (QMessageBox::question(this,tr("Clear the list of recent files?"),
+ tr("Do you want to clear the list of recently "
+ "loaded configuration files?"),
+ QMessageBox::Yes|
+ QMessageBox::Cancel)==QMessageBox::Yes)
+ {
+ m_recentMenu->clear();
+ m_recentFiles.clear();
+ for (int i=0;i<MAX_RECENT_FILES;i++)
+ {
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
+ }
+ m_settings.sync();
+ }
+
+}
+
+void MainWindow::resetToDefaults()
+{
+ if (QMessageBox::question(this,tr("Reset settings to their default values?"),
+ tr("Do you want to revert all settings back "
+ "to their original values?"),
+ QMessageBox::Reset|
+ QMessageBox::Cancel)==QMessageBox::Reset)
+ {
+ //printf("MainWindow:resetToDefaults()\n");
+ m_expert->resetToDefaults();
+ m_settings.setValue(QString::fromAscii("wizard/loadsettings"), false);
+ m_settings.sync();
+ m_wizard->refresh();
+ }
+}
+
+void MainWindow::loadSettings()
+{
+ QVariant geometry = m_settings.value(QString::fromAscii("main/geometry"), QVariant::Invalid);
+ QVariant state = m_settings.value(QString::fromAscii("main/state"), QVariant::Invalid);
+ QVariant wizState = m_settings.value(QString::fromAscii("wizard/state"), QVariant::Invalid);
+ QVariant loadSettings = m_settings.value(QString::fromAscii("wizard/loadsettings"), QVariant::Invalid);
+ QVariant workingDir = m_settings.value(QString::fromAscii("wizard/workingdir"), QVariant::Invalid);
+
+ if (geometry !=QVariant::Invalid) restoreGeometry(geometry.toByteArray());
+ if (state !=QVariant::Invalid) restoreState (state.toByteArray());
+ if (wizState !=QVariant::Invalid) m_wizard->restoreState(wizState.toByteArray());
+ if (loadSettings!=QVariant::Invalid && loadSettings.toBool())
+ {
+ m_expert->loadSettings(&m_settings);
+ if (workingDir!=QVariant::Invalid && QDir(workingDir.toString()).exists())
+ {
+ setWorkingDir(workingDir.toString());
+ }
+ }
+
+ for (int i=0;i<MAX_RECENT_FILES;i++)
+ {
+ QString entry = m_settings.value(QString().sprintf("recent/config%d",i)).toString();
+ if (!entry.isEmpty() && QFileInfo(entry).exists())
+ {
+ addRecentFile(entry);
+ }
+ }
+
+}
+
+void MainWindow::saveSettings()
+{
+ QSettings settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"));
+
+ m_settings.setValue(QString::fromAscii("main/geometry"), saveGeometry());
+ m_settings.setValue(QString::fromAscii("main/state"), saveState());
+ m_settings.setValue(QString::fromAscii("wizard/state"), m_wizard->saveState());
+ m_settings.setValue(QString::fromAscii("wizard/workingdir"), m_workingDir->text());
+}
+
+void MainWindow::selectTab(int id)
+{
+ if (id==0) m_wizard->refresh();
+ else if (id==1) m_expert->refresh();
+}
+
+void MainWindow::selectRunTab()
+{
+ m_tabs->setCurrentIndex(2);
+}
+
+void MainWindow::addRecentFile(const QString &fileName)
+{
+ int i=m_recentFiles.indexOf(fileName);
+ if (i!=-1) m_recentFiles.removeAt(i);
+
+ // not found
+ if (m_recentFiles.count() < MAX_RECENT_FILES) // append
+ {
+ m_recentFiles.prepend(fileName);
+ }
+ else // add + drop last item
+ {
+ m_recentFiles.removeLast();
+ m_recentFiles.prepend(fileName);
+ }
+ m_recentMenu->clear();
+ i=0;
+ foreach( QString str, m_recentFiles )
+ {
+ m_recentMenu->addAction(str);
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),str);
+ }
+ for (;i<MAX_RECENT_FILES;i++)
+ {
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
+ }
+}
+
+void MainWindow::openRecent(QAction *action)
+{
+ if (discardUnsavedChanges(false))
+ {
+ loadConfigFromFile(action->text());
+ }
+}
+
+void MainWindow::runDoxygen()
+{
+ if (!m_running)
+ {
+ QString doxygenPath;
+#if defined(Q_OS_MACX)
+ doxygenPath = qApp->applicationDirPath()+QString::fromAscii("/../Resources/");
+ qDebug() << tr("Doxygen path: ") << doxygenPath;
+ if ( !QFile(doxygenPath + QString::fromAscii("doxygen")).exists() )
+ {
+ // No doygen binary in the resources, if there is a system doxygen binary, use that instead
+ if ( QFile(QString::fromAscii("/usr/local/bin/doxygen")).exists() )
+ {
+ doxygenPath = QString::fromAscii("/usr/local/bin/");
+ }
+ else
+ {
+ qDebug() << tr("Can't find the doxygen command, make sure it's in your $$PATH");
+ doxygenPath = QString::fromAscii("");
+ }
+ }
+ qDebug() << tr("Getting doxygen from: ") << doxygenPath;
+#endif
+
+ m_runProcess->setReadChannel(QProcess::StandardOutput);
+ m_runProcess->setProcessChannelMode(QProcess::MergedChannels);
+ m_runProcess->setWorkingDirectory(m_workingDir->text());
+ QStringList env=QProcess::systemEnvironment();
+ // set PWD environment variable to m_workingDir
+ env.replaceInStrings(QRegExp(QString::fromAscii("^PWD=(.*)"),Qt::CaseInsensitive),
+ QString::fromAscii("PWD=")+m_workingDir->text());
+ m_runProcess->setEnvironment(env);
+
+ QStringList args;
+ args << QString::fromAscii("-b"); // make stdout unbuffered
+ args << QString::fromAscii("-"); // read config from stdin
+
+ m_outputLog->clear();
+ m_runProcess->start(doxygenPath + QString::fromAscii("doxygen"), args);
+
+ if (!m_runProcess->waitForStarted())
+ {
+ m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
+ return;
+ }
+ QTextStream t(m_runProcess);
+ m_expert->writeConfig(t,false);
+ m_runProcess->closeWriteChannel();
+
+ if (m_runProcess->state() == QProcess::NotRunning)
+ {
+ m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
+ }
+ else
+ {
+ m_saveLog->setEnabled(false);
+ m_running=true;
+ m_run->setText(tr("Stop doxygen"));
+ m_runStatus->setText(tr("Status: running"));
+ m_timer->start(1000);
+ }
+ }
+ else
+ {
+ m_running=false;
+ m_run->setText(tr("Run doxygen"));
+ m_runStatus->setText(tr("Status: not running"));
+ m_runProcess->kill();
+ m_timer->stop();
+ //updateRunnable(m_workingDir->text());
+ }
+}
+
+void MainWindow::readStdout()
+{
+ if (m_running)
+ {
+ QByteArray data = m_runProcess->readAllStandardOutput();
+ QString text = QString::fromUtf8(data);
+ if (!text.isEmpty())
+ {
+ m_outputLog->append(text.trimmed());
+ }
+ }
+}
+
+void MainWindow::runComplete()
+{
+ if (m_running)
+ {
+ m_outputLog->append(tr("*** Doxygen has finished\n"));
+ }
+ else
+ {
+ m_outputLog->append(tr("*** Cancelled by user\n"));
+ }
+ m_outputLog->ensureCursorVisible();
+ m_run->setText(tr("Run doxygen"));
+ m_runStatus->setText(tr("Status: not running"));
+ m_running=false;
+ updateLaunchButtonState();
+ //updateRunnable(m_workingDir->text());
+ m_saveLog->setEnabled(true);
+}
+
+void MainWindow::updateLaunchButtonState()
+{
+ m_launchHtml->setEnabled(m_expert->htmlOutputPresent(m_workingDir->text()));
+#if 0
+ m_launchPdf->setEnabled(m_expert->pdfOutputPresent(m_workingDir->text()));
+#endif
+}
+
+void MainWindow::showHtmlOutput()
+{
+ QString indexFile = m_expert->getHtmlOutputIndex(m_workingDir->text());
+ QFileInfo fi(indexFile);
+ // TODO: the following doesn't seem to work with IE
+#ifdef WIN32
+ //QString indexUrl(QString::fromAscii("file:///"));
+ ShellExecute(NULL, L"open", (LPCWSTR)fi.absoluteFilePath().utf16(), NULL, NULL, SW_SHOWNORMAL);
+#else
+ QString indexUrl(QString::fromAscii("file://"));
+ indexUrl+=fi.absoluteFilePath();
+ QDesktopServices::openUrl(QUrl(indexUrl));
+#endif
+}
+
+void MainWindow::saveLog()
+{
+ QString fn = QFileDialog::getSaveFileName(this, tr("Save log file"),
+ m_workingDir->text()+
+ QString::fromAscii("/doxygen_log.txt"));
+ if (!fn.isEmpty())
+ {
+ QFile f(fn);
+ if (f.open(QIODevice::WriteOnly))
+ {
+ QTextStream t(&f);
+ t << m_outputLog->toPlainText();
+ statusBar()->showMessage(tr("Output log saved"),messageTimeout);
+ }
+ else
+ {
+ QMessageBox::warning(0,tr("Warning"),
+ tr("Cannot open file ")+fn+tr(" for writing. Nothing saved!"),tr("ok"));
+ }
+ }
+}
+
+void MainWindow::showSettings()
+{
+ QString text;
+ QTextStream t(&text);
+ m_expert->writeConfig(t,true);
+ m_outputLog->clear();
+ m_outputLog->append(text);
+ m_outputLog->ensureCursorVisible();
+ m_saveLog->setEnabled(true);
+}
+
+void MainWindow::configChanged()
+{
+ m_modified = true;
+ updateTitle();
+}
+
+void MainWindow::updateTitle()
+{
+ QString title = tr("Doxygen GUI frontend");
+ if (m_modified)
+ {
+ title+=QString::fromAscii(" +");
+ }
+ if (!m_fileName.isEmpty())
+ {
+ title+=QString::fromAscii(" (")+m_fileName+QString::fromAscii(")");
+ }
+ setWindowTitle(title);
+}
+
+bool MainWindow::discardUnsavedChanges(bool saveOption)
+{
+ if (m_modified)
+ {
+ QMessageBox::StandardButton button;
+ if (saveOption)
+ {
+ button = QMessageBox::question(this,
+ tr("Unsaved changes"),
+ tr("Unsaved changes will be lost! Do you want to save the configuration file?"),
+ QMessageBox::Save |
+ QMessageBox::Discard |
+ QMessageBox::Cancel
+ );
+ if (button==QMessageBox::Save)
+ {
+ return saveConfig();
+ }
+ }
+ else
+ {
+ button = QMessageBox::question(this,
+ tr("Unsaved changes"),
+ tr("Unsaved changes will be lost! Do you want to continue?"),
+ QMessageBox::Discard |
+ QMessageBox::Cancel
+ );
+ }
+ return button==QMessageBox::Discard;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------
+int main(int argc,char **argv)
+{
+ QApplication a(argc,argv);
+ if (argc == 2)
+ {
+ if (!qstrcmp(argv[1],"--help"))
+ {
+ QMessageBox msgBox;
+ msgBox.setText(QString().sprintf("Usage: %s [config file]",argv[0]));
+ msgBox.exec();
+ exit(0);
+ }
+ }
+ if (argc > 2)
+ {
+ QMessageBox msgBox;
+ msgBox.setText(QString().sprintf("Too many arguments specified\n\nUsage: %s [config file]",argv[0]));
+ msgBox.exec();
+ exit(1);
+ }
+ else
+ {
+ MainWindow &main = MainWindow::instance();
+ if (argc==2 && argv[1][0]!='-') // name of config file as an argument
+ {
+ main.loadConfigFromFile(QString::fromLocal8Bit(argv[1]));
+ }
+ main.show();
+ return a.exec();
+ }
+}
diff --git a/addon/doxywizard/doxywizard.h b/addon/doxywizard/doxywizard.h
new file mode 100644
index 0000000..189972f
--- /dev/null
+++ b/addon/doxywizard/doxywizard.h
@@ -0,0 +1,87 @@
+#ifndef DOXYWIZARD_H
+#define DOXYWIZARD_H
+
+#include <QMainWindow>
+#include <QSettings>
+#include <QStringList>
+
+class Expert;
+class Wizard;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QTextEdit;
+class QMenu;
+class QProcess;
+class QTimer;
+class QTabWidget;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+ public:
+ static MainWindow &instance();
+ void loadConfigFromFile(const QString &fileName);
+ void loadSettings();
+ void saveSettings();
+ void closeEvent(QCloseEvent *event);
+ QString configFileName() const { return m_fileName; }
+ void updateTitle();
+
+ public slots:
+ void manual();
+ void about();
+ void openConfig();
+ bool saveConfig();
+ bool saveConfigAs();
+ void makeDefaults();
+ void resetToDefaults();
+ void selectTab(int);
+ void quit();
+
+ private slots:
+ void openRecent(QAction *action);
+ void selectWorkingDir();
+ void updateWorkingDir();
+ void runDoxygen();
+ void readStdout();
+ void runComplete();
+ void showHtmlOutput();
+ void saveLog();
+ void showSettings();
+ void configChanged();
+ void clearRecent();
+ void selectRunTab();
+
+ private:
+ MainWindow();
+ void saveConfig(const QString &fileName);
+ void addRecentFile(const QString &fileName);
+ void updateConfigFileName(const QString &fileName);
+ void setWorkingDir(const QString &dirName);
+ void updateLaunchButtonState();
+ bool discardUnsavedChanges(bool saveOption=true);
+
+ QLineEdit *m_workingDir;
+ QPushButton *m_selWorkingDir;
+ QPushButton *m_run;
+ QPushButton *m_saveLog;
+ QPushButton *m_launchHtml;
+ QPushButton *m_launchPdf;
+ QTextEdit *m_outputLog;
+ QLabel *m_runStatus;
+ Expert *m_expert;
+ Wizard *m_wizard;
+ QString m_fileName;
+ QSettings m_settings;
+ QMenu *m_recentMenu;
+ QStringList m_recentFiles;
+ QProcess *m_runProcess;
+ QTimer *m_timer;
+ QTabWidget *m_tabs;
+ bool m_running;
+ bool m_modified;
+};
+
+#endif
diff --git a/addon/doxywizard/doxywizard.ico b/addon/doxywizard/doxywizard.ico
new file mode 100644
index 0000000..10d1755
Binary files /dev/null and b/addon/doxywizard/doxywizard.ico differ
diff --git a/addon/doxywizard/doxywizard.pro b/addon/doxywizard/doxywizard.pro
new file mode 100644
index 0000000..0e071db
--- /dev/null
+++ b/addon/doxywizard/doxywizard.pro
@@ -0,0 +1,48 @@
+#
+# This file was generated from doxywizard.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+######################################################################
+# Automatically generated by qmake (2.01a) zo okt 19 12:50:02 2008
+######################################################################
+
+TEMPLATE = app
+DESTDIR = ../../bin
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += . ../../generated_src/doxywizard
+QT += xml
+CONFIG += debug
+OBJECTS_DIR = ../../objects/doxywizard
+MOC_DIR = ../../moc/doxywizard
+RCC_DIR = ../../rcc/doxywizard
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+
+macx-g++ {
+ CONFIG += x86 x86_64
+}
+
+# Input
+HEADERS += doxywizard.h version.h expert.h config.h helplabel.h \
+ inputbool.h inputstring.h inputint.h inputstrlist.h wizard.h docintf.h
+SOURCES += doxywizard.cpp expert.cpp wizard.cpp \
+ inputbool.cpp inputstring.cpp inputint.cpp inputstrlist.cpp
+RESOURCES += doxywizard.qrc
+INCBUFSIZE=$(PYTHON) ../../src/increasebuffer.py
+win32:RC_FILE += doxywizard.rc
+
+config.target = ../../generated_src/doxywizard/config_doxyw.cpp
+config.commands = $(LEX) -Pconfig_doxywYY -t ../../addon/doxywizard/config_doxyw.l | $(INCBUFSIZE) >../../generated_src/doxywizard/$*.cpp
+config.depends = ../../addon/doxywizard/config_doxyw.l ../../src/increasebuffer.py
+configdoc.target = ../../generated_src/doxywizard/configdoc.cpp
+configdoc.commands = $(PYTHON) ../../src/configgen.py -wiz ../../src/config.xml > ../../generated_src/doxywizard/configdoc.cpp
+configdoc.depends = ../../src/config.xml ../../src/configgen.py
+version.target = ../../generated_src/doxywizard/version.cpp
+version.commands = cd ../../src;$(PYTHON) version.py
+version.depends = ../../configure
+QMAKE_EXTRA_TARGETS += configdoc config version
+GENERATED_SOURCES += $$configdoc.target $$config.target $$version.target
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/addon/doxywizard/doxywizard.pro.in b/addon/doxywizard/doxywizard.pro.in
new file mode 100644
index 0000000..d5c0cab
--- /dev/null
+++ b/addon/doxywizard/doxywizard.pro.in
@@ -0,0 +1,41 @@
+######################################################################
+# Automatically generated by qmake (2.01a) zo okt 19 12:50:02 2008
+######################################################################
+
+TEMPLATE = app
+DESTDIR = ../../bin
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += . ../../generated_src/doxywizard
+QT += xml
+CONFIG += $extraopts
+OBJECTS_DIR = ../../objects/doxywizard
+MOC_DIR = ../../moc/doxywizard
+RCC_DIR = ../../rcc/doxywizard
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+
+macx-g++ {
+ CONFIG += x86 x86_64
+}
+
+# Input
+HEADERS += doxywizard.h version.h expert.h config.h helplabel.h \
+ inputbool.h inputstring.h inputint.h inputstrlist.h wizard.h docintf.h
+SOURCES += doxywizard.cpp expert.cpp wizard.cpp \
+ inputbool.cpp inputstring.cpp inputint.cpp inputstrlist.cpp
+RESOURCES += doxywizard.qrc
+INCBUFSIZE=$(PYTHON) ../../src/increasebuffer.py
+win32:RC_FILE += doxywizard.rc
+
+config.target = ../../generated_src/doxywizard/config_doxyw.cpp
+config.commands = $(LEX) -Pconfig_doxywYY -t ../../addon/doxywizard/config_doxyw.l | $(INCBUFSIZE) >../../generated_src/doxywizard/$*.cpp
+config.depends = ../../addon/doxywizard/config_doxyw.l ../../src/increasebuffer.py
+configdoc.target = ../../generated_src/doxywizard/configdoc.cpp
+configdoc.commands = $(PYTHON) ../../src/configgen.py -wiz ../../src/config.xml > ../../generated_src/doxywizard/configdoc.cpp
+configdoc.depends = ../../src/config.xml ../../src/configgen.py
+version.target = ../../generated_src/doxywizard/version.cpp
+version.commands = cd ../../src;$(PYTHON) version.py
+version.depends = ../../configure
+QMAKE_EXTRA_TARGETS += configdoc config version
+GENERATED_SOURCES += $$configdoc.target $$config.target $$version.target
+
diff --git a/addon/doxywizard/doxywizard.qrc b/addon/doxywizard/doxywizard.qrc
new file mode 100644
index 0000000..88316ed
--- /dev/null
+++ b/addon/doxywizard/doxywizard.qrc
@@ -0,0 +1,11 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file alias="config.xml">../../src/config.xml</file>
+ <file>images/add.png</file>
+ <file>images/del.png</file>
+ <file>images/file.png</file>
+ <file>images/folder.png</file>
+ <file>images/refresh.png</file>
+ <file>images/tunecolor.png</file>
+</qresource>
+</RCC>
diff --git a/addon/doxywizard/doxywizard.rc b/addon/doxywizard/doxywizard.rc
new file mode 100644
index 0000000..7f5327c
--- /dev/null
+++ b/addon/doxywizard/doxywizard.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "doxywizard.ico"
diff --git a/addon/doxywizard/expert.cpp b/addon/doxywizard/expert.cpp
new file mode 100644
index 0000000..1cc5d15
--- /dev/null
+++ b/addon/doxywizard/expert.cpp
@@ -0,0 +1,945 @@
+#include <QtGui>
+#include <QtXml>
+#include "expert.h"
+#include "inputbool.h"
+#include "inputstring.h"
+#include "inputint.h"
+#include "inputstring.h"
+#include "inputstrlist.h"
+#include "config.h"
+#include "version.h"
+#include "configdoc.h"
+#include "settings.h"
+
+#define SA(x) QString::fromAscii(x)
+
+static QString convertToComment(const QString &s)
+{
+ if (s.isEmpty())
+ {
+ return QString();
+ }
+ else
+ {
+ return SA("# ")+
+ s.trimmed().replace(SA("\n"),SA("\n# ")).replace(SA("# \n"), SA("#\n"))+
+ SA("\n");
+ }
+}
+
+void Expert::setHeader(const char *header)
+{
+ m_header = SA(header);
+}
+
+void Expert::add(const char *name,const char *docs)
+{
+ Input *opt = m_options[SA(name)];
+ if (opt)
+ {
+ opt->setTemplateDocs(SA(docs));
+ }
+}
+
+//------------------------------------------------------------------------------------
+
+Expert::Expert()
+{
+ m_treeWidget = new QTreeWidget;
+ m_treeWidget->setColumnCount(1);
+ m_topicStack = new QStackedWidget;
+ m_inShowHelp = FALSE;
+
+ QFile file(SA(":/config.xml"));
+ QString err;
+ int errLine,errCol;
+ QDomDocument configXml;
+ if (file.open(QIODevice::ReadOnly))
+ {
+ if (!configXml.setContent(&file,false,&err,&errLine,&errCol))
+ {
+ QString msg = tr("Error parsing internal config.xml at line %1 column %2.\n%3").
+ arg(errLine).arg(errCol).arg(err);
+ QMessageBox::warning(this, tr("Error"), msg);
+ exit(1);
+ }
+ }
+ m_rootElement = configXml.documentElement();
+
+ createTopics(m_rootElement);
+ m_helper = new QTextBrowser;
+ m_helper->setReadOnly(true);
+ m_helper->setOpenExternalLinks(TRUE);
+ m_splitter = new QSplitter(Qt::Vertical);
+ m_splitter->addWidget(m_treeWidget);
+ m_splitter->addWidget(m_helper);
+
+ QWidget *rightSide = new QWidget;
+ QGridLayout *grid = new QGridLayout(rightSide);
+ m_prev = new QPushButton(tr("Previous"));
+ m_prev->setEnabled(false);
+ m_next = new QPushButton(tr("Next"));
+ grid->addWidget(m_topicStack,0,0,1,2);
+ grid->addWidget(m_prev,1,0,Qt::AlignLeft);
+ grid->addWidget(m_next,1,1,Qt::AlignRight);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+
+ addWidget(m_splitter);
+ addWidget(rightSide);
+ connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
+
+ connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
+
+ addConfigDocs(this);
+}
+
+Expert::~Expert()
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ delete i.value();
+ }
+}
+
+void Expert::createTopics(const QDomElement &rootElem)
+{
+ QList<QTreeWidgetItem*> items;
+ QDomElement childElem = rootElem.firstChildElement();
+ while (!childElem.isNull())
+ {
+ if (childElem.tagName()==SA("group"))
+ {
+ // Remove _ from a group name like: Source_Browser
+ QString name = childElem.attribute(SA("name")).replace(SA("_"),SA(" "));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(name)));
+ QWidget *widget = createTopicWidget(childElem);
+ m_topics[name] = widget;
+ m_topicStack->addWidget(widget);
+ }
+ childElem = childElem.nextSiblingElement();
+ }
+ m_treeWidget->setHeaderLabels(QStringList() << SA("Topics"));
+ m_treeWidget->insertTopLevelItems(0,items);
+ connect(m_treeWidget,
+ SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
+ this,
+ SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
+}
+
+static QString getDocsForNode(const QDomElement &child)
+{
+ QString type = child.attribute(SA("type"));
+ QString docs = SA("");
+ // read documentation text
+ QDomElement docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("docs") &&
+ docsVal.attribute(SA("doxywizard")) != SA("0"))
+ {
+ for (QDomNode n = docsVal.firstChild(); !n.isNull(); n = n.nextSibling())
+ {
+ QDomText t = n.toText();
+ if (!t.isNull()) docs+=t.data();
+ }
+ docs += SA("<br/>");
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+
+ // for an enum we list the values
+ if (type==SA("enum"))
+ {
+ docs += SA("<br/>");
+ docs += SA("Possible values are: ");
+ int numValues=0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ numValues++;
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ int i=0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ i++;
+ docs += SA("<code>") + docsVal.attribute(SA("name")) + SA("</code>");
+ QString desc = docsVal.attribute(SA("desc"));
+ if (!desc.isEmpty())
+ {
+ docs+= SA(" ")+desc;
+ }
+ if (i==numValues-1)
+ {
+ docs+=SA(" and ");
+ }
+ else if (i==numValues)
+ {
+ docs+=SA(".");
+ }
+ else
+ {
+ docs+=SA(", ");
+ }
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ docs+=SA("<br/>");
+ docs+=SA("<br/>");
+ docs+=SA(" The default value is: <code>")+
+ child.attribute(SA("defval"))+
+ SA("</code>.");
+ docs+= SA("<br/>");
+ }
+ else if (type==SA("int"))
+ {
+ docs+=SA("<br/>");
+ docs+=SA("Minimum value: ")+child.attribute(SA("minval"))+SA(", ");
+ docs+=SA("maximum value: ")+child.attribute(SA("maxval"))+SA(", ");
+ docs+=SA("default value: ")+child.attribute(SA("defval"))+SA(".");
+ docs+= SA("<br/>");
+ }
+ else if (type==SA("bool"))
+ {
+ docs+=SA("<br/>");
+ if (child.hasAttribute(SA("altdefval")))
+ {
+ docs+=SA(" The default value is: system dependent.");
+ }
+ else
+ {
+ QString defval = child.attribute(SA("defval"));
+ docs+=SA(" The default value is: <code>")+
+ (defval==SA("1")?SA("YES"):SA("NO"))+
+ SA("</code>.");
+ }
+ docs+= SA("<br/>");
+ }
+ else if (type==SA("list"))
+ {
+ if (child.attribute(SA("format"))==SA("string"))
+ {
+ int numValues = 0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ QString showDocu = SA("");
+ if (docsVal.hasAttribute(SA("show_docu")))
+ {
+ showDocu = docsVal.attribute(SA("show_docu")).toLower();
+ }
+ if ((showDocu != SA("no")) && (docsVal.attribute(SA("name"))!=SA(""))) numValues++;
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ if (numValues>0)
+ {
+ int i = 0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ QString showDocu = SA("");
+ if (docsVal.hasAttribute(SA("show_docu")))
+ {
+ showDocu = docsVal.attribute(SA("show_docu")).toLower();
+ }
+ if ((showDocu != SA("no")) && (docsVal.attribute(SA("name"))!=SA("")))
+ {
+ i++;
+ docs += SA("<code>") + docsVal.attribute(SA("name")) + SA("</code>");
+ QString desc = docsVal.attribute(SA("desc"));
+ if (desc != SA(""))
+ {
+ docs += SA(" ") + desc;
+ }
+ if (i==numValues-1)
+ {
+ docs += SA(" and ");
+ }
+ else if (i==numValues)
+ {
+ docs += SA(".");
+ }
+ else
+ {
+ docs += SA(", ");
+ }
+ }
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ }
+ // docs+= SA("<br/>");
+ }
+ }
+ else if (type==SA("string"))
+ {
+ QString defval = child.attribute(SA("defval"));
+ if (child.attribute(SA("format")) == SA("dir"))
+ {
+ if (defval != SA(""))
+ {
+ docs+=SA("<br/>");
+ docs += SA(" The default directory is: <code>") + defval + SA("</code>.");
+ docs += SA("<br/>");
+ }
+ }
+ else if (child.attribute(SA("format")) == SA("file"))
+ {
+ QString abspath = child.attribute(SA("abspath"));
+ if (defval != SA(""))
+ {
+ docs+=SA("<br/>");
+ if (abspath != SA("1"))
+ {
+ docs += SA(" The default file is: <code>") + defval + SA("</code>.");
+ }
+ else
+ {
+ docs += SA(" The default file (with absolute path) is: <code>") + defval + SA("</code>.");
+ }
+ docs += SA("<br/>");
+ }
+ else
+ {
+ if (abspath == SA("1"))
+ {
+ docs+=SA("<br/>");
+ docs += SA(" The file has to be specified with full path.");
+ docs += SA("<br/>");
+ }
+ }
+ }
+ else if (child.attribute(SA("format")) == SA("image"))
+ {
+ QString abspath = child.attribute(SA("abspath"));
+ if (defval != SA(""))
+ {
+ docs+=SA("<br/>");
+ if (abspath != SA("1"))
+ {
+ docs += SA(" The default image is: <code>") + defval + SA("</code>.");
+ }
+ else
+ {
+ docs += SA(" The default image (with absolute path) is: <code>") + defval + SA("</code>.");
+ }
+ docs += SA("<br/>");
+ }
+ else
+ {
+ if (abspath == SA("1"))
+ {
+ docs+=SA("<br/>");
+ docs += SA(" The image has to be specified with full path.");
+ docs += SA("<br/>");
+ }
+ }
+ }
+ else // if (child.attribute(SA("format")) == SA("string"))
+ {
+ if (defval != SA(""))
+ {
+ docs+=SA("<br/>");
+ docs += SA(" The default value is: <code>") + defval + SA("</code>.");
+ docs += SA("<br/>");
+ }
+ }
+ }
+
+ if (child.hasAttribute(SA("depends")))
+ {
+ QString dependsOn = child.attribute(SA("depends"));
+ docs+=SA("<br/>");
+ docs+= SA(" This tag requires that the tag \\ref cfg_");
+ docs+= dependsOn.toLower();
+ docs+= SA(" \"");
+ docs+= dependsOn.toUpper();
+ docs+= SA("\" is set to <code>YES</code>.");
+ }
+
+ // Remove / replace doxygen markup strings
+ // the regular expressions are hard to read so the intention will be given
+ QRegExp regexp;
+ // remove \n at end and replace by a space
+ regexp.setPattern(SA("\\n$"));
+ docs.replace(regexp,SA(" "));
+ // remove <br> at end
+ regexp.setPattern(SA("<br> *$"));
+ docs.replace(regexp,SA(" "));
+ // \c word -> <code>word</code>; word ends with ')', ',', '.' or ' '
+ regexp.setPattern(SA("\\\\c[ ]+([^ \\)]+)\\)"));
+ docs.replace(regexp,SA("<code>\\1</code>)"));
+
+ regexp.setPattern(SA("\\\\c[ ]+([^ ,]+),"));
+ docs.replace(regexp,SA("<code>\\1</code>,"));
+
+ regexp.setPattern(SA("\\\\c[ ]+([^ \\.]+)\\."));
+ docs.replace(regexp,SA("<code>\\1</code>."));
+
+ regexp.setPattern(SA("\\\\c[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<code>\\1</code> "));
+ // `word` -> <code>word</code>
+ docs.replace(SA("``"),SA(""));
+ regexp.setPattern(SA("`([^`]+)`"));
+ docs.replace(regexp,SA("<code>\\1</code>"));
+ // \ref key "desc" -> <code>desc</code>
+ regexp.setPattern(SA("\\\\ref[ ]+[^ ]+[ ]+\"([^ ]+)\""));
+ docs.replace(regexp,SA("<code>\\1</code> "));
+ //\ref specials
+ // \ref <key> -> description
+ regexp.setPattern(SA("\\\\ref[ ]+doxygen_usage"));
+ docs.replace(regexp,SA("\"Doxygen usage\""));
+ regexp.setPattern(SA("\\\\ref[ ]+extsearch"));
+ docs.replace(regexp,SA("\"External Indexing and Searching\""));
+ regexp.setPattern(SA("\\\\ref[ ]+external"));
+ docs.replace(regexp,SA("\"Linking to external documentation\""));
+ // fallback for not handled
+ docs.replace(SA("\\\\ref"),SA(""));
+ // \b word -> <b>word<\b>
+ regexp.setPattern(SA("\\\\b[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<b>\\1</b> "));
+ // \e word -> <em>word<\em>
+ regexp.setPattern(SA("\\\\e[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<em>\\1</em> "));
+ // \note -> <br>Note:
+ // @note -> <br>Note:
+ docs.replace(SA("\\note"),SA("<br>Note:"));
+ docs.replace(SA("@note"),SA("<br>Note:"));
+ // \#include -> #include
+ // \#undef -> #undef
+ docs.replace(SA("\\#include"),SA("#include"));
+ docs.replace(SA("\\#undef"),SA("#undef"));
+ // -# -> <br>-
+ // " - " -> <br>-
+ docs.replace(SA("-#"),SA("<br>-"));
+ docs.replace(SA(" - "),SA("<br>-"));
+ // \verbatim -> <pre>
+ // \endverbatim -> </pre>
+ docs.replace(SA("\\verbatim"),SA("<pre>"));
+ docs.replace(SA("\\endverbatim"),SA("</pre>"));
+ // \sa -> <br>See also:
+ // \par -> <br>
+ docs.replace(SA("\\sa"),SA("<br>See also:"));
+ docs.replace(SA("\\par"),SA("<br>"));
+ // 2xbackslash -> backslash
+ // \@ -> @
+ docs.replace(SA("\\\\"),SA("\\"));
+ docs.replace(SA("\\@"),SA("@"));
+ // \& -> &
+ // \$ -> $
+ docs.replace(SA("\\&"),SA("&"));
+ docs.replace(SA("\\$"),SA("$"));
+ // \< -> <
+ // \> -> >
+ docs.replace(SA("\\<"),SA("<"));
+ docs.replace(SA("\\>"),SA(">"));
+ regexp.setPattern(SA(" (http:[^ \\)]*)([ \\)])"));
+ docs.replace(regexp,SA(" <a href=\"\\1\">\\1</a>\\2"));
+ // LaTeX name as formula -> LaTeX
+ regexp.setPattern(SA("\\\\f\\$\\\\mbox\\{\\\\LaTeX\\}\\\\f\\$"));
+ docs.replace(regexp,SA("LaTeX"));
+ // Other forula's (now just 2) so explicitely mentioned.
+ regexp.setPattern(SA("\\\\f\\$2\\^\\{\\(16\\+\\\\mbox\\{LOOKUP\\\\_CACHE\\\\_SIZE\\}\\)\\}\\\\f\\$"));
+ docs.replace(regexp,SA("2^(16+LOOKUP_CACHE_SIZE)"));
+ regexp.setPattern(SA("\\\\f\\$2\\^\\{16\\} = 65536\\\\f\\$"));
+ docs.replace(regexp,SA("2^16=65536"));
+
+ return docs.trimmed();
+}
+
+QWidget *Expert::createTopicWidget(QDomElement &elem)
+{
+ QScrollArea *area = new QScrollArea;
+ QWidget *topic = new QWidget;
+ QGridLayout *layout = new QGridLayout(topic);
+ QDomElement child = elem.firstChildElement();
+ int row=0;
+ while (!child.isNull())
+ {
+ QString setting = child.attribute(SA("setting"));
+ if (setting.isEmpty() || IS_SUPPORTED(setting.toAscii()))
+ {
+ QString type = child.attribute(SA("type"));
+ QString docs = getDocsForNode(child);
+ if (type==SA("bool"))
+ {
+ InputBool *boolOption =
+ new InputBool(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval"))==SA("1"),
+ docs
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ boolOption
+ );
+ connect(boolOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(boolOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("string"))
+ {
+ InputString::StringMode mode;
+ QString format = child.attribute(SA("format"));
+ if (format==SA("dir"))
+ {
+ mode = InputString::StringDir;
+ }
+ else if (format==SA("file"))
+ {
+ mode = InputString::StringFile;
+ }
+ else if (format==SA("image"))
+ {
+ mode = InputString::StringImage;
+ }
+ else // format=="string"
+ {
+ mode = InputString::StringFree;
+ }
+ InputString *stringOption =
+ new InputString(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")),
+ mode,
+ docs,
+ child.attribute(SA("abspath"))
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ stringOption
+ );
+ connect(stringOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(stringOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("enum"))
+ {
+ InputString *enumList = new InputString(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")),
+ InputString::StringFixed,
+ docs
+ );
+ QDomElement enumVal = child.firstChildElement();
+ while (!enumVal.isNull())
+ {
+ if (enumVal.tagName()==SA("value"))
+ {
+ enumList->addValue(enumVal.attribute(SA("name")));
+ }
+ enumVal = enumVal.nextSiblingElement();
+ }
+ enumList->setDefault();
+
+ m_options.insert(child.attribute(SA("id")),enumList);
+ connect(enumList,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(enumList,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("int"))
+ {
+ InputInt *intOption =
+ new InputInt(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")).toInt(),
+ child.attribute(SA("minval")).toInt(),
+ child.attribute(SA("maxval")).toInt(),
+ docs
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ intOption
+ );
+ connect(intOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(intOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("list"))
+ {
+ InputStrList::ListMode mode;
+ QString format = child.attribute(SA("format"));
+ if (format==SA("dir"))
+ {
+ mode = InputStrList::ListDir;
+ }
+ else if (format==SA("file"))
+ {
+ mode = InputStrList::ListFile;
+ }
+ else if (format==SA("filedir"))
+ {
+ mode = InputStrList::ListFileDir;
+ }
+ else // format=="string"
+ {
+ mode = InputStrList::ListString;
+ }
+ QStringList sl;
+ QDomElement listVal = child.firstChildElement();
+ while (!listVal.isNull())
+ {
+ if (listVal.tagName()==SA("value"))
+ {
+ sl.append(listVal.attribute(SA("name")));
+ }
+ listVal = listVal.nextSiblingElement();
+ }
+ InputStrList *listOption =
+ new InputStrList(
+ layout,row,
+ child.attribute(SA("id")),
+ sl,
+ mode,
+ docs
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ listOption
+ );
+ connect(listOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(listOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("obsolete"))
+ {
+ // ignore
+ }
+ else // should not happen
+ {
+ printf("Unsupported type %s\n",qPrintable(child.attribute(SA("type"))));
+ }
+ } // IS_SUPPORTED
+ child = child.nextSiblingElement();
+ }
+
+ // compute dependencies between options
+ child = elem.firstChildElement();
+ while (!child.isNull())
+ {
+ QString setting = child.attribute(SA("setting"));
+ QString dependsOn = child.attribute(SA("depends"));
+ QString id = child.attribute(SA("id"));
+ if (!dependsOn.isEmpty() &&
+ (setting.isEmpty() || IS_SUPPORTED(setting.toAscii())))
+ {
+ Input *parentOption = m_options[dependsOn];
+ if (parentOption==0)
+ {
+ printf("%s has depends=%s that is not valid\n",
+ qPrintable(id),qPrintable(dependsOn));
+ }
+ Input *thisOption = m_options[id];
+ Q_ASSERT(parentOption);
+ Q_ASSERT(thisOption);
+ if (parentOption && thisOption)
+ {
+ //printf("Adding dependency '%s' (%p)->'%s' (%p)\n",
+ // qPrintable(dependsOn),parentOption,
+ // qPrintable(id),thisOption);
+ parentOption->addDependency(thisOption);
+ }
+ }
+ child = child.nextSiblingElement();
+ }
+
+ // set initial dependencies
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->updateDependencies();
+ }
+ }
+
+ layout->setRowStretch(row,1);
+ layout->setColumnStretch(1,2);
+ layout->setSpacing(5);
+ topic->setLayout(layout);
+ area->setWidget(topic);
+ area->setWidgetResizable(true);
+ return area;
+}
+
+void Expert::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
+{
+ if (item)
+ {
+ QWidget *w = m_topics[item->text(0)];
+ m_topicStack->setCurrentWidget(w);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_next->setEnabled(true);
+ }
+}
+
+void Expert::loadSettings(QSettings *s)
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ QVariant var = s->value(SA("config/")+i.key());
+ if (i.value())
+ {
+ //printf("Loading key %s: type=%d value='%s'\n",qPrintable(i.key()),var.type(),qPrintable(var.toString()));
+ i.value()->value() = var;
+ i.value()->update();
+ }
+ }
+}
+
+void Expert::saveSettings(QSettings *s)
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ //printf("Saving key %s: type=%d value='%s'\n",qPrintable(i.key()),i.value()->value().type(),qPrintable(i.value()->value().toString()));
+ if (i.value())
+ {
+ s->setValue(SA("config/")+i.key(),i.value()->value());
+ }
+ }
+}
+
+void Expert::loadConfig(const QString &fileName)
+{
+ //printf("Expert::loadConfig(%s)\n",qPrintable(fileName));
+ parseConfig(fileName,m_options);
+}
+
+void Expert::saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,
+ bool brief)
+{
+ if (!brief)
+ {
+ t << endl;
+ }
+ t << "#---------------------------------------------------------------------------" << endl;
+ t << "# " << elem.attribute(SA("docs")) << endl;
+ t << "#---------------------------------------------------------------------------" << endl;
+ // write options...
+ QDomElement childElem = elem.firstChildElement();
+ while (!childElem.isNull())
+ {
+ QString setting = childElem.attribute(SA("setting"));
+ QString type = childElem.attribute(SA("type"));
+ QString name = childElem.attribute(SA("id"));
+ if (setting.isEmpty() || IS_SUPPORTED(setting.toAscii()))
+ {
+ QHash<QString,Input*>::const_iterator i = m_options.find(name);
+ if (i!=m_options.end())
+ {
+ Input *option = i.value();
+ if (option && !brief)
+ {
+ t << endl;
+ t << convertToComment(option->templateDocs());
+ t << endl;
+ }
+ t << name.leftJustified(MAX_OPTION_LENGTH) << "= ";
+ if (option)
+ {
+ option->writeValue(t,codec);
+ }
+ t << endl;
+ }
+ }
+ childElem = childElem.nextSiblingElement();
+ }
+}
+
+bool Expert::writeConfig(QTextStream &t,bool brief)
+{
+ // write global header
+ t << "# Doxyfile " << versionString << endl << endl;
+ if (!brief)
+ {
+ t << convertToComment(m_header);
+ }
+
+ QTextCodec *codec = 0;
+ Input *option = m_options[QString::fromAscii("DOXYFILE_ENCODING")];
+ if (option)
+ {
+ codec = QTextCodec::codecForName(option->value().toString().toAscii());
+ if (codec==0) // fallback: use UTF-8
+ {
+ codec = QTextCodec::codecForName("UTF-8");
+ }
+ }
+ QDomElement childElem = m_rootElement.firstChildElement();
+ while (!childElem.isNull())
+ {
+ if (childElem.tagName()==SA("group"))
+ {
+ saveTopic(t,childElem,codec,brief);
+ }
+ childElem = childElem.nextSiblingElement();
+ }
+ return true;
+}
+
+QByteArray Expert::saveInnerState () const
+{
+ return m_splitter->saveState();
+}
+
+bool Expert::restoreInnerState ( const QByteArray & state )
+{
+ return m_splitter->restoreState(state);
+}
+
+void Expert::showHelp(Input *option)
+{
+ if (!m_inShowHelp)
+ {
+ m_inShowHelp = TRUE;
+ m_helper->setText(
+ QString::fromAscii("<qt><b>")+option->id()+
+ QString::fromAscii("</b><br>")+
+ QString::fromAscii("<br/>")+
+ option->docs().
+ replace(QChar::fromAscii('\n'),QChar::fromAscii(' '))+
+ QString::fromAscii("</qt>")
+ );
+ m_inShowHelp = FALSE;
+ }
+}
+
+void Expert::nextTopic()
+{
+ if (m_topicStack->currentIndex()+1==m_topicStack->count()) // last topic
+ {
+ done();
+ }
+ else
+ {
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+ }
+}
+
+void Expert::prevTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Expert::resetToDefaults()
+{
+ //printf("Expert::makeDefaults()\n");
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->reset();
+ }
+ }
+}
+
+static bool stringVariantToBool(const QVariant &v)
+{
+ QString s = v.toString().toLower();
+ return s==QString::fromAscii("yes") || s==QString::fromAscii("true") || s==QString::fromAscii("1");
+}
+
+static bool getBoolOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return stringVariantToBool(option->value());
+}
+
+static QString getStringOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toString();
+}
+
+
+bool Expert::htmlOutputPresent(const QString &workingDir) const
+{
+ bool generateHtml = getBoolOption(m_options,QString::fromAscii("GENERATE_HTML"));
+ if (!generateHtml || workingDir.isEmpty()) return false;
+ QString indexFile = getHtmlOutputIndex(workingDir);
+ QFileInfo fi(indexFile);
+ return fi.exists() && fi.isFile();
+}
+
+QString Expert::getHtmlOutputIndex(const QString &workingDir) const
+{
+ QString outputDir = getStringOption(m_options,QString::fromAscii("OUTPUT_DIRECTORY"));
+ QString htmlOutputDir = getStringOption(m_options,QString::fromAscii("HTML_OUTPUT"));
+ //printf("outputDir=%s\n",qPrintable(outputDir));
+ //printf("htmlOutputDir=%s\n",qPrintable(htmlOutputDir));
+ QString indexFile = workingDir;
+ if (QFileInfo(outputDir).isAbsolute()) // override
+ {
+ indexFile = outputDir;
+ }
+ else // append
+ {
+ indexFile += QString::fromAscii("/")+outputDir;
+ }
+ if (QFileInfo(htmlOutputDir).isAbsolute()) // override
+ {
+ indexFile = htmlOutputDir;
+ }
+ else // append
+ {
+ indexFile += QString::fromAscii("/")+htmlOutputDir;
+ }
+ indexFile+=QString::fromAscii("/index.html");
+ return indexFile;
+}
+
+bool Expert::pdfOutputPresent(const QString &workingDir) const
+{
+ bool generateLatex = getBoolOption(m_options,QString::fromAscii("GENERATE_LATEX"));
+ bool pdfLatex = getBoolOption(m_options,QString::fromAscii("USE_PDFLATEX"));
+ if (!generateLatex || !pdfLatex) return false;
+ QString latexOutput = getStringOption(m_options,QString::fromAscii("LATEX_OUTPUT"));
+ QString indexFile;
+ if (QFileInfo(latexOutput).isAbsolute())
+ {
+ indexFile = latexOutput+QString::fromAscii("/refman.pdf");
+ }
+ else
+ {
+ indexFile = workingDir+QString::fromAscii("/")+
+ latexOutput+QString::fromAscii("/refman.pdf");
+ }
+ QFileInfo fi(indexFile);
+ return fi.exists() && fi.isFile();
+}
+
+void Expert::refresh()
+{
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(0));
+}
+
diff --git a/addon/doxywizard/expert.h b/addon/doxywizard/expert.h
new file mode 100644
index 0000000..ff571cb
--- /dev/null
+++ b/addon/doxywizard/expert.h
@@ -0,0 +1,74 @@
+#ifndef EXPERT_H
+#define EXPERT_H
+
+#include <QSplitter>
+#include <QDomElement>
+#include <QHash>
+
+#include "docintf.h"
+
+class QTreeWidget;
+class QTreeWidgetItem;
+class QStackedWidget;
+class QSettings;
+class QTextBrowser;
+class QTextCodec;
+class QPushButton;
+class Input;
+
+class Expert : public QSplitter, public DocIntf
+{
+ Q_OBJECT
+
+ public:
+ Expert();
+ ~Expert();
+ void loadSettings(QSettings *);
+ void saveSettings(QSettings *);
+ void loadConfig(const QString &fileName);
+ bool writeConfig(QTextStream &t,bool brief);
+ QByteArray saveInnerState () const;
+ bool restoreInnerState ( const QByteArray & state );
+ const QHash<QString,Input*> &modelData() const { return m_options; }
+ void resetToDefaults();
+ bool htmlOutputPresent(const QString &workingDir) const;
+ bool pdfOutputPresent(const QString &workingDir) const;
+ QString getHtmlOutputIndex(const QString &workingDir) const;
+
+ // DocIntf methods
+ void setHeader(const char *name);
+ void add(const char *name,const char *doc);
+
+ public slots:
+ void activateTopic(QTreeWidgetItem *,QTreeWidgetItem *);
+ QWidget *createTopicWidget(QDomElement &elem);
+ void refresh();
+
+ private slots:
+ void showHelp(Input *);
+ void nextTopic();
+ void prevTopic();
+
+ signals:
+ void changed();
+ void done();
+
+ private:
+ void createTopics(const QDomElement &);
+ void saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,bool brief);
+
+ QSplitter *m_splitter;
+ QTextBrowser *m_helper;
+ QTreeWidget *m_treeWidget;
+ QStackedWidget *m_topicStack;
+ QHash<QString,QWidget *> m_topics;
+ QHash<QString,QObject *> m_optionWidgets;
+ QHash<QString,Input *> m_options;
+ QPushButton *m_next;
+ QPushButton *m_prev;
+ QDomElement m_rootElement;
+ bool m_inShowHelp;
+ QString m_header;
+};
+
+#endif
diff --git a/addon/doxywizard/helplabel.h b/addon/doxywizard/helplabel.h
new file mode 100644
index 0000000..07e2932
--- /dev/null
+++ b/addon/doxywizard/helplabel.h
@@ -0,0 +1,33 @@
+#ifndef HELPLABEL_H
+#define HELPLABEL_H
+
+#include <QLabel>
+#include <QMenu>
+
+class HelpLabel : public QLabel
+{
+ Q_OBJECT
+ public:
+ HelpLabel(const QString &text) : QLabel(text)
+ { setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this,SIGNAL(customContextMenuRequested(const QPoint&)),
+ this,SLOT(showMenu(const QPoint&)));
+ }
+ signals:
+ void enter();
+ void reset();
+ private slots:
+ void showMenu(const QPoint &p)
+ {
+ QMenu menu(this);
+ QAction *a = menu.addAction(tr("Reset to default"));
+ if (menu.exec(mapToGlobal(p))==a)
+ {
+ reset();
+ }
+ }
+ protected:
+ void enterEvent( QEvent * event ) { enter(); QLabel::enterEvent(event); }
+};
+
+#endif
diff --git a/addon/doxywizard/images/add.png b/addon/doxywizard/images/add.png
new file mode 100644
index 0000000..30a7090
Binary files /dev/null and b/addon/doxywizard/images/add.png differ
diff --git a/addon/doxywizard/images/del.png b/addon/doxywizard/images/del.png
new file mode 100644
index 0000000..ceb6a60
Binary files /dev/null and b/addon/doxywizard/images/del.png differ
diff --git a/addon/doxywizard/images/file.png b/addon/doxywizard/images/file.png
new file mode 100644
index 0000000..e204f67
Binary files /dev/null and b/addon/doxywizard/images/file.png differ
diff --git a/addon/doxywizard/images/folder.png b/addon/doxywizard/images/folder.png
new file mode 100644
index 0000000..2e420e0
Binary files /dev/null and b/addon/doxywizard/images/folder.png differ
diff --git a/addon/doxywizard/images/refresh.png b/addon/doxywizard/images/refresh.png
new file mode 100644
index 0000000..fd6d565
Binary files /dev/null and b/addon/doxywizard/images/refresh.png differ
diff --git a/addon/doxywizard/images/tunecolor.png b/addon/doxywizard/images/tunecolor.png
new file mode 100644
index 0000000..bf7be83
Binary files /dev/null and b/addon/doxywizard/images/tunecolor.png differ
diff --git a/addon/doxywizard/input.h b/addon/doxywizard/input.h
new file mode 100644
index 0000000..9e0a1bf
--- /dev/null
+++ b/addon/doxywizard/input.h
@@ -0,0 +1,36 @@
+#ifndef INPUT_H
+#define INPUT_H
+
+#include <QVariant>
+
+class QTextStream;
+class QTextCodec;
+
+class Input
+{
+ public:
+ enum Kind
+ {
+ Bool,
+ Int,
+ String,
+ StrList,
+ Obsolete
+ };
+ virtual ~Input() {}
+ virtual QVariant &value() = 0;
+ virtual void update() = 0;
+ virtual Kind kind() const = 0;
+ virtual QString docs() const = 0;
+ virtual QString id() const = 0;
+ virtual QString templateDocs() const = 0;
+ virtual void addDependency(Input *option) = 0;
+ virtual void setEnabled(bool) = 0;
+ virtual void updateDependencies() = 0;
+ virtual void reset() = 0;
+ virtual void writeValue(QTextStream &t,QTextCodec *codec) = 0;
+ virtual void setTemplateDocs(const QString &docs) = 0;
+};
+
+
+#endif
diff --git a/addon/doxywizard/inputbool.cpp b/addon/doxywizard/inputbool.cpp
new file mode 100644
index 0000000..be99b0a
--- /dev/null
+++ b/addon/doxywizard/inputbool.cpp
@@ -0,0 +1,112 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "inputbool.h"
+#include "helplabel.h"
+#include <QtGui>
+
+InputBool::InputBool( QGridLayout *layout, int &row,
+ const QString &id, bool checked,
+ const QString &docs )
+ : m_default(checked), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel(id);
+ m_cb = new QCheckBox;
+ layout->addWidget(m_lab,row, 0);
+ layout->addWidget(m_cb,row, 1);
+ m_enabled = true;
+ m_state=!checked; // force update
+ setValue(checked);
+ connect( m_cb, SIGNAL(toggled(bool)), SLOT(setValue(bool)) );
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+ row++;
+}
+
+void InputBool::help()
+{
+ showHelp(this);
+}
+
+void InputBool::setEnabled(bool b)
+{
+ m_enabled = b;
+ m_cb->setEnabled(b);
+ m_lab->setEnabled(b);
+ updateDefault();
+ updateDependencies();
+}
+
+void InputBool::updateDependencies()
+{
+ for (int i=0;i<m_dependencies.count();i++)
+ {
+ m_dependencies[i]->setEnabled(m_enabled && m_state);
+ }
+}
+
+void InputBool::setValue( bool s )
+{
+ if (m_state!=s)
+ {
+ m_state=s;
+ updateDefault();
+ updateDependencies();
+ m_cb->setChecked( s );
+ m_value = m_state;
+ emit changed();
+ }
+}
+
+void InputBool::updateDefault()
+{
+ if (m_state==m_default || !m_lab->isEnabled())
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+}
+
+QVariant &InputBool::value()
+{
+ return m_value;
+}
+
+void InputBool::update()
+{
+ QString v = m_value.toString().toLower();
+ m_state = (v==QString::fromAscii("yes") ||
+ v==QString::fromAscii("true") ||
+ v==QString::fromAscii("1"));
+ m_cb->setChecked( m_state );
+ updateDefault();
+ updateDependencies();
+}
+
+void InputBool::reset()
+{
+ setValue(m_default);
+}
+
+void InputBool::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ if (m_state)
+ t << codec->fromUnicode(QString::fromAscii("YES"));
+ else
+ t << codec->fromUnicode(QString::fromAscii("NO"));
+}
+
diff --git a/addon/doxywizard/inputbool.h b/addon/doxywizard/inputbool.h
new file mode 100644
index 0000000..03bb76e
--- /dev/null
+++ b/addon/doxywizard/inputbool.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _INPUTBOOL_H
+#define _INPUTBOOL_H
+
+#include "input.h"
+#include <QObject>
+
+class QCheckBox;
+class QGridLayout;
+class QLabel;
+
+class InputBool : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ InputBool(QGridLayout *layout,int &row,const QString &id,
+ bool enabled, const QString &docs );
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return Bool; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ QString templateDocs() const { return m_tdocs; }
+ void addDependency(Input *option) { m_dependencies+=option; }
+ void setEnabled(bool);
+ void updateDependencies();
+ void writeValue(QTextStream &t,QTextCodec *codec);
+ void setTemplateDocs(const QString &docs) { m_tdocs = docs; }
+
+ public slots:
+ void reset();
+ void setValue(bool);
+
+ signals:
+ void changed();
+ void toggle(QString,bool);
+ void showHelp(Input *);
+
+ private slots:
+ void help();
+
+ private:
+ void updateDefault();
+ bool m_state;
+ bool m_default;
+ bool m_enabled;
+ QVariant m_value;
+ QCheckBox *m_cb;
+ QString m_docs;
+ QList<Input*> m_dependencies;
+ QString m_id;
+ QLabel *m_lab;
+ QString m_tdocs;
+};
+
+#endif
diff --git a/addon/doxywizard/inputint.cpp b/addon/doxywizard/inputint.cpp
new file mode 100644
index 0000000..e0c426c
--- /dev/null
+++ b/addon/doxywizard/inputint.cpp
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "inputint.h"
+#include "helplabel.h"
+
+#include <QtGui>
+
+class NoWheelSpinBox : public QSpinBox
+{
+ protected:
+ void wheelEvent(QWheelEvent *e)
+ {
+ e->ignore();
+ }
+};
+
+InputInt::InputInt( QGridLayout *layout,int &row,
+ const QString & id,
+ int defVal, int minVal,int maxVal,
+ const QString & docs )
+ : m_default(defVal), m_minVal(minVal), m_maxVal(maxVal), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel(id);
+ m_sp = new NoWheelSpinBox;
+ m_sp->setMinimum(minVal);
+ m_sp->setMaximum(maxVal);
+ m_sp->setSingleStep(1);
+ m_val=defVal-1; // force update
+ setValue(defVal);
+
+ layout->addWidget( m_lab, row, 0 );
+ layout->addWidget( m_sp, row, 1 );
+
+ connect(m_sp, SIGNAL(valueChanged(int)),
+ this, SLOT(setValue(int)) );
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+ row++;
+}
+
+void InputInt::help()
+{
+ showHelp(this);
+}
+
+
+void InputInt::setValue(int val)
+{
+ val = qMax(m_minVal,val);
+ val = qMin(m_maxVal,val);
+ if (val!=m_val)
+ {
+ m_val = val;
+ m_sp->setValue(val);
+ m_value = m_val;
+ updateDefault();
+ }
+}
+
+void InputInt::updateDefault()
+{
+ {
+ if (m_val==m_default || !m_lab->isEnabled())
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+ emit changed();
+ }
+}
+
+void InputInt::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ m_sp->setEnabled(state);
+ updateDefault();
+}
+
+QVariant &InputInt::value()
+{
+ return m_value;
+}
+
+void InputInt::update()
+{
+ setValue(m_value.toInt());
+}
+
+void InputInt::reset()
+{
+ setValue(m_default);
+}
+
+void InputInt::writeValue(QTextStream &t,QTextCodec *)
+{
+ t << m_val;
+}
+
diff --git a/addon/doxywizard/inputint.h b/addon/doxywizard/inputint.h
new file mode 100644
index 0000000..6662865
--- /dev/null
+++ b/addon/doxywizard/inputint.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _INPUTINT_H
+#define _INPUTINT_H
+
+#include "input.h"
+#include <QObject>
+
+class QGridLayout;
+class QLabel;
+class QSpinBox;
+
+class InputInt : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ InputInt( QGridLayout *layout,int &row,
+ const QString &id, int defVal,
+ int minVal, int maxVal,
+ const QString &docs );
+ ~InputInt(){};
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return Int; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ QString templateDocs() const { return m_tdocs; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+ void setTemplateDocs(const QString &docs) { m_tdocs = docs; }
+
+ public slots:
+ void reset();
+ void setValue(int val);
+
+ private slots:
+ void help();
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private:
+ void updateDefault();
+ QLabel *m_lab;
+ QSpinBox *m_sp;
+ int m_val;
+ int m_default;
+ int m_minVal;
+ int m_maxVal;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+ QString m_tdocs;
+};
+
+#endif
diff --git a/addon/doxywizard/inputstring.cpp b/addon/doxywizard/inputstring.cpp
new file mode 100644
index 0000000..48ede55
--- /dev/null
+++ b/addon/doxywizard/inputstring.cpp
@@ -0,0 +1,250 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "inputstring.h"
+#include "helplabel.h"
+#include "doxywizard.h"
+#include "config.h"
+
+#include <QtGui>
+
+class NoWheelComboBox : public QComboBox
+{
+ protected:
+ void wheelEvent(QWheelEvent *e)
+ {
+ e->ignore();
+ }
+};
+
+
+InputString::InputString( QGridLayout *layout,int &row,
+ const QString & id, const QString &s,
+ StringMode m, const QString &docs,
+ const QString &absPath )
+ : m_default(s), m_sm(m), m_index(0), m_docs(docs), m_id(id),
+ m_absPath(absPath==QString::fromAscii("1"))
+{
+ m_lab = new HelpLabel(id);
+ if (m==StringFixed)
+ {
+ layout->addWidget( m_lab, row, 0 );
+ m_com = new NoWheelComboBox;
+ layout->addWidget( m_com, row, 1, 1, 3, Qt::AlignLeft );
+ m_le=0;
+ m_br=0;
+ m_im=0;
+ row++;
+ }
+ else
+ {
+ layout->addWidget( m_lab, row, 0 );
+ m_le = new QLineEdit;
+ m_le->setText( s );
+ m_im = 0;
+ //layout->setColumnMinimumWidth(2,150);
+ if (m==StringFile || m==StringDir || m==StringImage)
+ {
+ layout->addWidget( m_le, row, 1 );
+ m_br = new QToolBar;
+ m_br->setIconSize(QSize(24,24));
+ if (m==StringFile || m==StringImage)
+ {
+ QAction *file = m_br->addAction(QIcon(QString::fromAscii(":/images/file.png")),QString(),this,SLOT(browse()));
+ file->setToolTip(tr("Browse to a file"));
+ layout->addWidget( m_br,row,2 );
+ if (m==StringImage)
+ {
+ m_im = new QLabel;
+ m_im->setMinimumSize(1,55);
+ m_im->setAlignment(Qt::AlignLeft|Qt::AlignTop);
+ row++;
+ layout->addWidget( m_im,row,1 );
+ }
+ }
+ else
+ {
+ QAction *dir = m_br->addAction(QIcon(QString::fromAscii(":/images/folder.png")),QString(),this,SLOT(browse()));
+ dir->setToolTip(tr("Browse to a folder"));
+ layout->addWidget( m_br,row,2 );
+ }
+ }
+ else
+ {
+ layout->addWidget( m_le, row, 1, 1, 2 );
+ m_br=0;
+ m_im=0;
+ }
+ m_com=0;
+ row++;
+ }
+
+ if (m_le) connect( m_le, SIGNAL(textChanged(const QString&)),
+ this, SLOT(setValue(const QString&)) );
+ if (m_com) connect( m_com, SIGNAL(activated(const QString &)),
+ this, SLOT(setValue(const QString &)) );
+ m_str = s+QChar::fromAscii('!'); // force update
+ setValue(s);
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+}
+
+void InputString::help()
+{
+ showHelp(this);
+}
+
+
+InputString::~InputString()
+{
+}
+
+
+void InputString::setValue(const QString &s)
+{
+ if (m_str!=s)
+ {
+ m_str = s;
+ m_value = m_str;
+ updateDefault();
+ }
+}
+void InputString::updateDefault()
+{
+ {
+ if (m_str==m_default || !m_lab->isEnabled())
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+ if (m_im)
+ {
+ if (m_str.isEmpty())
+ {
+ m_im->setText(tr("No Project logo selected."));
+ }
+ else
+ {
+ QFile Fout(m_str);
+ if(!Fout.exists())
+ {
+ m_im->setText(tr("Sorry, cannot find file(")+m_str+QString::fromAscii(");"));
+ }
+ else
+ {
+ QPixmap pm(m_str);
+ if (!pm.isNull())
+ {
+ m_im->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
+ }
+ else
+ {
+ m_im->setText(tr("Sorry, no preview available (")+m_str+QString::fromAscii(");"));
+ }
+ }
+ }
+ }
+ if (m_le && m_le->text()!=m_str) m_le->setText( m_str );
+ emit changed();
+ }
+}
+
+void InputString::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ if (m_le) m_le->setEnabled(state);
+ if (m_im) m_im->setEnabled(state);
+ if (m_br) m_br->setEnabled(state);
+ if (m_com) m_com->setEnabled(state);
+ updateDefault();
+}
+
+void InputString::browse()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ if (m_sm==StringFile || m_sm==StringImage)
+ {
+ QString fileName = QFileDialog::getOpenFileName(&MainWindow::instance(),
+ tr("Select file"),path);
+ if (!fileName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ fileName = m_absPath ? fileName : dir.relativeFilePath(fileName);
+ }
+ setValue(fileName);
+ }
+ }
+ else // sm==StringDir
+ {
+ QString dirName = QFileDialog::getExistingDirectory(&MainWindow::instance(),
+ tr("Select directory"),path);
+ if (!dirName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = m_absPath ? dirName : dir.relativeFilePath(dirName);
+ }
+ setValue(dirName);
+ }
+ }
+}
+
+void InputString::clear()
+{
+ setValue(QString());
+}
+
+void InputString::addValue(QString s)
+{
+ if (m_sm==StringFixed)
+ {
+ m_values.append(s);
+ m_com->addItem(s);
+ }
+}
+
+void InputString::setDefault()
+{
+ int index = m_values.indexOf(m_str);
+ if (index!=-1 && m_com) m_com->setCurrentIndex(index);
+}
+
+QVariant &InputString::value()
+{
+ return m_value;
+}
+
+void InputString::update()
+{
+ setValue(m_value.toString().trimmed());
+ setDefault();
+}
+
+void InputString::reset()
+{
+ setValue(m_default);
+ setDefault();
+}
+
+void InputString::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ writeStringValue(t,codec,m_str);
+}
+
diff --git a/addon/doxywizard/inputstring.h b/addon/doxywizard/inputstring.h
new file mode 100644
index 0000000..90ea87d
--- /dev/null
+++ b/addon/doxywizard/inputstring.h
@@ -0,0 +1,96 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _INPUTSTRING_H
+#define _INPUTSTRING_H
+
+#include "input.h"
+
+#include <QObject>
+#include <QMap>
+#include <QStringList>
+
+class QLabel;
+class QLineEdit;
+class QToolBar;
+class QComboBox;
+class QGridLayout;
+
+class InputString : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ enum StringMode { StringFree=0,
+ StringFile=1,
+ StringDir=2,
+ StringFixed=3,
+ StringImage=4
+ };
+
+ InputString( QGridLayout *layout,int &row,
+ const QString &id, const QString &s,
+ StringMode m,
+ const QString &docs,
+ const QString &absPath = QString() );
+ ~InputString();
+ void addValue(QString s);
+ void setDefault();
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return String; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ QString templateDocs() const { return m_tdocs; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+ void setTemplateDocs(const QString &docs) { m_tdocs = docs; }
+
+ public slots:
+ void reset();
+ void setValue(const QString&);
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private slots:
+ void browse();
+ void clear();
+ void help();
+
+ private:
+ void updateDefault();
+ QLabel *m_lab;
+ QLineEdit *m_le;
+ QLabel *m_im;
+ QToolBar *m_br;
+ QComboBox *m_com;
+ QString m_str;
+ QString m_default;
+ StringMode m_sm;
+ QStringList m_values;
+ int m_index;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+ bool m_absPath;
+ QString m_tdocs;
+};
+
+#endif
diff --git a/addon/doxywizard/inputstrlist.cpp b/addon/doxywizard/inputstrlist.cpp
new file mode 100644
index 0000000..0a0f01f
--- /dev/null
+++ b/addon/doxywizard/inputstrlist.cpp
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include "inputstrlist.h"
+#include "helplabel.h"
+#include "doxywizard.h"
+#include "config.h"
+
+#include <QtGui>
+
+InputStrList::InputStrList( QGridLayout *layout,int &row,
+ const QString & id,
+ const QStringList &sl, ListMode lm,
+ const QString & docs)
+ : m_default(sl), m_strList(sl), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel( id );
+
+ m_le = new QLineEdit;
+ m_le->clear();
+
+ QToolBar *toolBar = new QToolBar;
+ toolBar->setIconSize(QSize(24,24));
+ m_add = toolBar->addAction(QIcon(QString::fromAscii(":/images/add.png")),QString(),
+ this,SLOT(addString()));
+ m_add->setToolTip(tr("Add item"));
+ m_del = toolBar->addAction(QIcon(QString::fromAscii(":/images/del.png")),QString(),
+ this,SLOT(delString()));
+ m_del->setToolTip(tr("Delete selected item"));
+ m_upd = toolBar->addAction(QIcon(QString::fromAscii(":/images/refresh.png")),QString(),
+ this,SLOT(updateString()));
+ m_upd->setToolTip(tr("Update selected item"));
+
+ m_lb = new QListWidget;
+ //m_lb->setMinimumSize(400,100);
+ foreach (QString s, m_strList) m_lb->addItem(s);
+
+ m_brFile=0;
+ m_brDir=0;
+ if (lm!=ListString)
+ {
+ if (lm&ListFile)
+ {
+ m_brFile = toolBar->addAction(QIcon(QString::fromAscii(":/images/file.png")),QString(),
+ this,SLOT(browseFiles()));
+ m_brFile->setToolTip(tr("Browse to a file"));
+ }
+ if (lm&ListDir)
+ {
+ m_brDir = toolBar->addAction(QIcon(QString::fromAscii(":/images/folder.png")),QString(),
+ this,SLOT(browseDir()));
+ m_brDir->setToolTip(tr("Browse to a folder"));
+ }
+ }
+ QHBoxLayout *rowLayout = new QHBoxLayout;
+ rowLayout->addWidget( m_le );
+ rowLayout->addWidget( toolBar );
+ layout->addWidget( m_lab, row,0 );
+ layout->addLayout( rowLayout, row,1,1,2 );
+ layout->addWidget( m_lb, row+1,1,1,2 );
+ row+=2;
+
+ m_value = m_strList;
+
+ connect(m_le, SIGNAL(returnPressed()),
+ this, SLOT(addString()) );
+ connect(m_lb, SIGNAL(currentTextChanged(const QString &)),
+ this, SLOT(selectText(const QString &)));
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+}
+
+void InputStrList::help()
+{
+ showHelp(this);
+}
+
+
+void InputStrList::addString()
+{
+ if (!m_le->text().isEmpty())
+ {
+ m_lb->addItem(m_le->text());
+ m_strList.append(m_le->text());
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ m_le->clear();
+ }
+}
+
+void InputStrList::delString()
+{
+ if (m_lb->currentRow()!=-1)
+ {
+ int itemIndex = m_lb->currentRow();
+ delete m_lb->currentItem();
+ m_strList.removeAt(itemIndex);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+}
+
+void InputStrList::updateString()
+{
+ if (m_lb->currentRow()!=-1 && !m_le->text().isEmpty())
+ {
+ m_lb->currentItem()->setText(m_le->text());
+ m_strList.insert(m_lb->currentRow(),m_le->text());
+ m_strList.removeAt(m_lb->currentRow()+1);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+}
+
+void InputStrList::selectText(const QString &s)
+{
+ m_le->setText(s);
+}
+
+void InputStrList::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ m_le->setEnabled(state);
+ m_add->setEnabled(state);
+ m_del->setEnabled(state);
+ m_upd->setEnabled(state);
+ m_lb->setEnabled(state);
+ if (m_brFile) m_brFile->setEnabled(state);
+ if (m_brDir) m_brDir->setEnabled(state);
+ updateDefault();
+}
+
+void InputStrList::browseFiles()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QStringList fileNames = QFileDialog::getOpenFileNames();
+
+ if (!fileNames.isEmpty())
+ {
+ QStringList::Iterator it;
+ for ( it= fileNames.begin(); it != fileNames.end(); ++it )
+ {
+ QString fileName;
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ fileName = dir.relativeFilePath(*it);
+ }
+ if (fileName.isEmpty())
+ {
+ fileName = *it;
+ }
+ m_lb->addItem(fileName);
+ m_strList.append(fileName);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+ m_le->setText(m_strList[0]);
+ }
+}
+
+void InputStrList::browseDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory();
+
+ if (!dirName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_lb->addItem(dirName);
+ m_strList.append(dirName);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ m_le->setText(dirName);
+ }
+}
+
+void InputStrList::setValue(const QStringList &sl)
+{
+ m_le->clear();
+ m_lb->clear();
+ m_strList = sl;
+ for (int i=0;i<m_strList.size();i++)
+ {
+ m_lb->addItem(m_strList[i].trimmed());
+ }
+ updateDefault();
+}
+
+QVariant &InputStrList::value()
+{
+ return m_value;
+}
+
+void InputStrList::update()
+{
+ setValue(m_value.toStringList());
+}
+
+void InputStrList::updateDefault()
+{
+ if (m_strList==m_default || !m_lab->isEnabled())
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+}
+
+void InputStrList::reset()
+{
+ setValue(m_default);
+}
+
+void InputStrList::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ bool first=TRUE;
+ foreach (QString s, m_strList)
+ {
+ if (!first)
+ {
+ t << " \\" << endl;
+ t << " ";
+ }
+ first=FALSE;
+ writeStringValue(t,codec,s);
+ }
+}
+
diff --git a/addon/doxywizard/inputstrlist.h b/addon/doxywizard/inputstrlist.h
new file mode 100644
index 0000000..0d7efe7
--- /dev/null
+++ b/addon/doxywizard/inputstrlist.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _INPUTSTRLIST_H
+#define _INPUTSTRLIST_H
+
+#include "input.h"
+
+#include <QObject>
+#include <QStringList>
+
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QListWidget;
+class QStringList;
+class QGridLayout;
+class QAction;
+
+class InputStrList : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ enum ListMode { ListString = 0,
+ ListFile = 1,
+ ListDir = 2,
+ ListFileDir = ListFile | ListDir
+ };
+
+ InputStrList( QGridLayout *layout,int &row,
+ const QString &id, const QStringList &sl,
+ ListMode v, const QString &docs);
+ void setValue(const QStringList &sl);
+
+ QVariant &value();
+ void update();
+ Kind kind() const { return StrList; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ QString templateDocs() const { return m_tdocs; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+ void setTemplateDocs(const QString &docs) { m_tdocs = docs; }
+
+ public slots:
+ void reset();
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private slots:
+ void addString();
+ void delString();
+ void updateString();
+ void selectText(const QString &s);
+ void browseFiles();
+ void browseDir();
+ void help();
+
+ private:
+ void updateDefault();
+ QLabel *m_lab;
+ QLineEdit *m_le;
+ QAction *m_add;
+ QAction *m_del;
+ QAction *m_upd;
+ QAction *m_brFile;
+ QAction *m_brDir;
+ QListWidget *m_lb;
+ QStringList m_default;
+ QStringList m_strList;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+ QString m_tdocs;
+};
+
+#endif
diff --git a/addon/doxywizard/version.h b/addon/doxywizard/version.h
new file mode 100644
index 0000000..b31fe4f
--- /dev/null
+++ b/addon/doxywizard/version.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+extern char versionString[];
+
+#endif
diff --git a/addon/doxywizard/wizard.cpp b/addon/doxywizard/wizard.cpp
new file mode 100644
index 0000000..a8b7f94
--- /dev/null
+++ b/addon/doxywizard/wizard.cpp
@@ -0,0 +1,1330 @@
+#include "wizard.h"
+#include "input.h"
+#include "doxywizard.h"
+
+#include <math.h>
+#include <QtGui>
+
+// options configurable via the wizard
+#define STR_PROJECT_NAME QString::fromAscii("PROJECT_NAME")
+#define STR_PROJECT_LOGO QString::fromAscii("PROJECT_LOGO")
+#define STR_PROJECT_BRIEF QString::fromAscii("PROJECT_BRIEF")
+#define STR_INPUT QString::fromAscii("INPUT")
+#define STR_OUTPUT_DIRECTORY QString::fromAscii("OUTPUT_DIRECTORY")
+#define STR_PROJECT_NUMBER QString::fromAscii("PROJECT_NUMBER")
+#define STR_RECURSIVE QString::fromAscii("RECURSIVE")
+#define STR_OPTIMIZE_OUTPUT_FOR_C QString::fromAscii("OPTIMIZE_OUTPUT_FOR_C")
+#define STR_OPTIMIZE_OUTPUT_JAVA QString::fromAscii("OPTIMIZE_OUTPUT_JAVA")
+#define STR_OPTIMIZE_FOR_FORTRAN QString::fromAscii("OPTIMIZE_FOR_FORTRAN")
+#define STR_OPTIMIZE_OUTPUT_VHDL QString::fromAscii("OPTIMIZE_OUTPUT_VHDL")
+#define STR_CPP_CLI_SUPPORT QString::fromAscii("CPP_CLI_SUPPORT")
+#define STR_HIDE_SCOPE_NAMES QString::fromAscii("HIDE_SCOPE_NAMES")
+#define STR_EXTRACT_ALL QString::fromAscii("EXTRACT_ALL")
+#define STR_SOURCE_BROWSER QString::fromAscii("SOURCE_BROWSER")
+#define STR_GENERATE_HTML QString::fromAscii("GENERATE_HTML")
+#define STR_GENERATE_LATEX QString::fromAscii("GENERATE_LATEX")
+#define STR_GENERATE_MAN QString::fromAscii("GENERATE_MAN")
+#define STR_GENERATE_RTF QString::fromAscii("GENERATE_RTF")
+#define STR_GENERATE_XML QString::fromAscii("GENERATE_XML")
+#define STR_GENERATE_HTMLHELP QString::fromAscii("GENERATE_HTMLHELP")
+#define STR_GENERATE_TREEVIEW QString::fromAscii("GENERATE_TREEVIEW")
+#define STR_USE_PDFLATEX QString::fromAscii("USE_PDFLATEX")
+#define STR_PDF_HYPERLINKS QString::fromAscii("PDF_HYPERLINKS")
+#define STR_SEARCHENGINE QString::fromAscii("SEARCHENGINE")
+#define STR_HAVE_DOT QString::fromAscii("HAVE_DOT")
+#define STR_CLASS_DIAGRAMS QString::fromAscii("CLASS_DIAGRAMS")
+#define STR_CLASS_GRAPH QString::fromAscii("CLASS_GRAPH")
+#define STR_COLLABORATION_GRAPH QString::fromAscii("COLLABORATION_GRAPH")
+#define STR_GRAPHICAL_HIERARCHY QString::fromAscii("GRAPHICAL_HIERARCHY")
+#define STR_INCLUDE_GRAPH QString::fromAscii("INCLUDE_GRAPH")
+#define STR_INCLUDED_BY_GRAPH QString::fromAscii("INCLUDED_BY_GRAPH")
+#define STR_CALL_GRAPH QString::fromAscii("CALL_GRAPH")
+#define STR_CALLER_GRAPH QString::fromAscii("CALLER_GRAPH")
+#define STR_HTML_COLORSTYLE_HUE QString::fromAscii("HTML_COLORSTYLE_HUE")
+#define STR_HTML_COLORSTYLE_SAT QString::fromAscii("HTML_COLORSTYLE_SAT")
+#define STR_HTML_COLORSTYLE_GAMMA QString::fromAscii("HTML_COLORSTYLE_GAMMA")
+
+static bool g_optimizeMapping[6][6] =
+{
+ // A: OPTIMIZE_OUTPUT_FOR_C
+ // B: OPTIMIZE_OUTPUT_JAVA
+ // C: OPTIMIZE_FOR_FORTRAN
+ // D: OPTIMIZE_OUTPUT_VHDL
+ // E: CPP_CLI_SUPPORT
+ // F: HIDE_SCOPE_NAMES
+ // A B C D E F
+ { false,false,false,false,false,false }, // 0: C++
+ { false,false,false,false,true, false }, // 1: C++/CLI
+ { false,true, false,false,false,false }, // 2: C#/Java
+ { true, false,false,false,false,true }, // 3: C/PHP
+ { false,false,true, false,false,false }, // 4: Fortran
+ { false,false,false,true, false,false }, // 5: VHDL
+};
+
+static QString g_optimizeOptionNames[6] =
+{
+ STR_OPTIMIZE_OUTPUT_FOR_C,
+ STR_OPTIMIZE_OUTPUT_JAVA,
+ STR_OPTIMIZE_FOR_FORTRAN,
+ STR_OPTIMIZE_OUTPUT_VHDL,
+ STR_CPP_CLI_SUPPORT,
+ STR_HIDE_SCOPE_NAMES
+};
+
+//==========================================================================
+
+static bool stringVariantToBool(const QVariant &v)
+{
+ QString s = v.toString().toLower();
+ return s==QString::fromAscii("yes") || s==QString::fromAscii("true") || s==QString::fromAscii("1");
+}
+
+static bool getBoolOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return stringVariantToBool(option->value());
+}
+
+static int getIntOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toInt();
+}
+
+static QString getStringOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toString();
+}
+
+static void updateBoolOption(
+ const QHash<QString,Input*>&model,const QString &name,bool bNew)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ bool bOld = stringVariantToBool(option->value());
+ if (bOld!=bNew)
+ {
+ option->value()=QString::fromAscii(bNew ? "true" : "false");
+ option->update();
+ }
+}
+
+static void updateIntOption(
+ const QHash<QString,Input*>&model,const QString &name,int iNew)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ int iOld = option->value().toInt();
+ if (iOld!=iNew)
+ {
+ option->value()=QString::fromAscii("%1").arg(iNew);
+ option->update();
+ }
+}
+
+
+static void updateStringOption(
+ const QHash<QString,Input*>&model,const QString &name,const QString &s)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ if (option->value().toString()!=s)
+ {
+ option->value() = s;
+ option->update();
+ }
+}
+
+//==========================================================================
+
+TuneColorDialog::TuneColorDialog(int hue,int sat,int gamma,QWidget *parent) : QDialog(parent)
+{
+ setWindowTitle(tr("Tune the color of the HTML output"));
+ QGridLayout *layout = new QGridLayout(this);
+ m_image = new QImage(QString::fromAscii(":/images/tunecolor.png"));
+ m_imageLab = new QLabel;
+ updateImage(hue,sat,gamma);
+ layout->addWidget(new QLabel(tr("Example output: use the sliders on the right to adjust the color")),0,0);
+ layout->addWidget(m_imageLab,1,0);
+ QHBoxLayout *buttonsLayout = new QHBoxLayout;
+
+ QPushButton *okButton = new QPushButton(tr("Ok"));
+ connect(okButton,SIGNAL(clicked()),SLOT(accept()));
+ okButton->setDefault(true);
+ QPushButton *cancelButton = new QPushButton(tr("Cancel"));
+ connect(cancelButton,SIGNAL(clicked()),SLOT(reject()));
+
+ ColorPicker *huePicker = new ColorPicker(ColorPicker::Hue);
+ huePicker->setCol(hue,sat,gamma);
+ huePicker->setFixedWidth(20);
+ layout->addWidget(huePicker,1,1);
+ ColorPicker *satPicker = new ColorPicker(ColorPicker::Saturation);
+ satPicker->setCol(hue,sat,gamma);
+ satPicker->setFixedWidth(20);
+ layout->addWidget(satPicker,1,2);
+ ColorPicker *gamPicker = new ColorPicker(ColorPicker::Gamma);
+ gamPicker->setCol(hue,sat,gamma);
+ gamPicker->setFixedWidth(20);
+ layout->addWidget(gamPicker,1,3);
+
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+
+ buttonsLayout->addStretch();
+ buttonsLayout->addWidget(okButton);
+ buttonsLayout->addWidget(cancelButton);
+ layout->addLayout(buttonsLayout,5,0,1,4);
+}
+
+void hsl2rgb(double h,double s,double l,
+ double *pRed,double *pGreen,double *pBlue)
+{
+ double v;
+ double r,g,b;
+
+ r = l; // default to gray
+ g = l;
+ b = l;
+ v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
+ if (v > 0)
+ {
+ double m;
+ double sv;
+ int sextant;
+ double fract, vsf, mid1, mid2;
+
+ m = l + l - v;
+ sv = (v - m ) / v;
+ h *= 6.0;
+ sextant = (int)h;
+ fract = h - sextant;
+ vsf = v * sv * fract;
+ mid1 = m + vsf;
+ mid2 = v - vsf;
+ switch (sextant)
+ {
+ case 0:
+ r = v;
+ g = mid1;
+ b = m;
+ break;
+ case 1:
+ r = mid2;
+ g = v;
+ b = m;
+ break;
+ case 2:
+ r = m;
+ g = v;
+ b = mid1;
+ break;
+ case 3:
+ r = m;
+ g = mid2;
+ b = v;
+ break;
+ case 4:
+ r = mid1;
+ g = m;
+ b = v;
+ break;
+ case 5:
+ r = v;
+ g = m;
+ b = mid2;
+ break;
+ }
+ }
+ *pRed = r;
+ *pGreen = g;
+ *pBlue = b;
+}
+
+
+
+void TuneColorDialog::updateImage(int hue,int sat,int gam)
+{
+ QImage coloredImg(m_image->width(),m_image->height(),QImage::Format_RGB32);
+ uint *srcPixel = (uint *)m_image->scanLine(0);
+ uint *dstPixel = (uint *)coloredImg.scanLine(0);
+ uint nrPixels = coloredImg.width()*coloredImg.height();
+ for (uint i=0;i<nrPixels;i++,srcPixel++,dstPixel++)
+ {
+ QColor c = QColor::fromRgb(*srcPixel);
+ double r,g,b;
+ hsl2rgb(hue/359.0, sat/255.0, pow(c.green()/255.0,gam/100.0),&r,&g,&b);
+ *dstPixel = qRgb((int)(r*255.0),(int)(g*255.0),(int)(b*255.0));
+ }
+ m_imageLab->setPixmap(QPixmap::fromImage(coloredImg));
+ m_hue = hue;
+ m_sat = sat;
+ m_gam = gam;
+}
+
+int TuneColorDialog::getHue() const
+{
+ return m_hue;
+}
+
+int TuneColorDialog::getSaturation() const
+{
+ return m_sat;
+}
+
+int TuneColorDialog::getGamma() const
+{
+ return m_gam;
+}
+
+//==========================================================================
+
+ColorPicker::ColorPicker(Mode m)
+{
+ m_hue = 220;
+ m_gam = 100;
+ m_sat = 100;
+ m_mode = m;
+ m_pix = 0;
+}
+
+ColorPicker::~ColorPicker()
+{
+ delete m_pix;
+}
+
+void ColorPicker::paintEvent(QPaintEvent*)
+{
+ int w = width() - 5;
+
+ QRect r(0, foff, w, height() - 2*foff);
+ int wi = r.width() - 2;
+ int hi = r.height() - 2;
+ if (!m_pix || m_pix->height() != hi || m_pix->width() != wi)
+ {
+ delete m_pix;
+ QImage img(wi, hi, QImage::Format_RGB32);
+ int y;
+ uint *pixel = (uint *) img.scanLine(0);
+ for (y = 0; y < hi; y++)
+ {
+ const uint *end = pixel + wi;
+ int yh = y2hue(y+coff);
+ int ys = y2sat(y+coff);
+ int yg = y2gam(y+coff);
+ while (pixel < end)
+ {
+ QColor c;
+ c.setHsv(yh, ys, (int)(255*pow(0.7,yg/100.0)));
+ *pixel = c.rgb();
+ ++pixel;
+ }
+ }
+ m_pix = new QPixmap(QPixmap::fromImage(img));
+ }
+ QPainter p(this);
+ p.drawPixmap(1, coff, *m_pix);
+ const QPalette &g = palette();
+ qDrawShadePanel(&p, r, g, true);
+ p.setPen(g.foreground().color());
+ p.setBrush(g.foreground());
+ QPolygon a;
+ int y = m_mode==Hue ? hue2y(m_hue) :
+ m_mode==Saturation ? sat2y(m_sat) :
+ gam2y(m_gam);
+ a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
+ p.eraseRect(w, 0, 5, height());
+ p.drawPolygon(a);
+}
+
+void ColorPicker::mouseMoveEvent(QMouseEvent *m)
+{
+ if (m_mode==Hue) setHue(y2hue(m->y()));
+ else if (m_mode==Saturation) setSat(y2sat(m->y()));
+ else setGam(y2gam(m->y()));
+}
+
+void ColorPicker::mousePressEvent(QMouseEvent *m)
+{
+ if (m_mode==Hue) setHue(y2hue(m->y()));
+ else if (m_mode==Saturation) setSat(y2sat(m->y()));
+ else setGam(y2gam(m->y()));
+}
+
+void ColorPicker::setHue(int h)
+{
+ if (h==m_hue) return;
+ m_hue = qMax(0,qMin(h,359));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setSat(int s)
+{
+ if (s==m_sat) return;
+ m_sat = qMax(0,qMin(s,255));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setGam(int g)
+{
+ if (g==m_gam) return;
+ m_gam = qMax(40,qMin(g,240));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setCol(int h, int s, int g)
+{
+ if (m_hue!=h || m_sat!=s || m_gam!=g)
+ {
+ m_hue = h;
+ m_sat = s;
+ m_gam = g;
+ delete m_pix; m_pix=0;
+ repaint();
+ }
+}
+
+int ColorPicker::y2hue(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Hue ? (y - coff)*359/d : m_hue;
+}
+
+int ColorPicker::hue2y(int v)
+{
+ int d = height() - 2*coff - 1;
+ return coff + v*d/359;
+}
+
+int ColorPicker::y2sat(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Saturation ? 255 - (y - coff)*255/d : m_sat;
+}
+
+int ColorPicker::sat2y(int v)
+{
+ int d = height() - 2*coff - 1;
+ return coff + (255-v)*d/255;
+}
+
+int ColorPicker::y2gam(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Gamma ? 240 - (y - coff)*200/d : m_gam;
+}
+
+int ColorPicker::gam2y(int g)
+{
+ int d = height() - 2*coff - 1;
+ return coff + (240-g)*d/200;
+}
+
+//==========================================================================
+
+Step1::Step1(Wizard *wizard,const QHash<QString,Input*> &modelData) : m_wizard(wizard), m_modelData(modelData)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(4);
+ layout->setSpacing(8);
+ QLabel *l = new QLabel(this);
+ l->setText(tr("Provide some information "
+ "about the project you are documenting"));
+ layout->addWidget(l);
+ QWidget *w = new QWidget( this );
+ QGridLayout *grid = new QGridLayout(w);
+ grid->setSpacing(10);
+
+ // project name
+ QLabel *projName = new QLabel(this);
+ projName->setText(tr("Project name:"));
+ projName->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project brief
+ QLabel *projBrief = new QLabel(this);
+ projBrief->setText(tr("Project synopsis:"));
+ projBrief->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project version
+ QLabel *projVersion = new QLabel(this);
+ projVersion->setText(tr("Project version or id:"));
+ projVersion->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project icon
+ QLabel *projLogo = new QLabel(this);
+ projLogo->setMinimumSize(1,55);
+ projLogo->setText(tr("Project logo:"));
+ projLogo->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+
+ grid->addWidget(projName,0,0);
+ grid->addWidget(projBrief,1,0);
+ grid->addWidget(projVersion,2,0);
+ grid->addWidget(projLogo,3,0);
+
+ m_projName = new QLineEdit;
+ m_projBrief = new QLineEdit;
+ m_projNumber = new QLineEdit;
+ QPushButton *projIconSel = new QPushButton(this);
+ projIconSel->setText(tr("Select..."));
+ m_projIconLab = new QLabel;
+
+ grid->addWidget(m_projName,0,1,1,2);
+ grid->addWidget(m_projBrief,1,1,1,2);
+ grid->addWidget(m_projNumber,2,1,1,2);
+ grid->addWidget(projIconSel,3,1);
+ grid->addWidget(m_projIconLab,3,2);
+
+ grid->setColumnStretch(2,1);
+
+ w->setLayout(grid);
+
+ layout->addWidget(w);
+
+ //---------------------------------------------------
+ QFrame *f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ l = new QLabel(this);
+ l->setText(tr("Specify the directory to scan for source code"));
+ layout->addWidget(l);
+ QWidget *row = new QWidget;
+ QHBoxLayout *rowLayout = new QHBoxLayout(row);
+ rowLayout->setSpacing(10);
+ l = new QLabel(this);
+ l->setText(tr("Source code directory:"));
+ rowLayout->addWidget(l);
+ m_sourceDir = new QLineEdit;
+ m_srcSelectDir = new QPushButton(this);
+ m_srcSelectDir->setText(tr("Select..."));
+ rowLayout->addWidget(m_sourceDir);
+ rowLayout->addWidget(m_srcSelectDir);
+ layout->addWidget(row);
+
+ m_recursive = new QCheckBox(this);
+ m_recursive->setText(tr("Scan recursively"));
+ m_recursive->setChecked(TRUE);
+ layout->addWidget(m_recursive);
+
+ //---------------------------------------------------
+ f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ l = new QLabel(this);
+ l->setText(tr("Specify the directory where doxygen should "
+ "put the generated documentation"));
+ layout->addWidget(l);
+ row = new QWidget;
+ rowLayout = new QHBoxLayout(row);
+ rowLayout->setSpacing(10);
+ l = new QLabel(this);
+ l->setText(tr("Destination directory:"));
+ rowLayout->addWidget(l);
+ m_destDir = new QLineEdit;
+ m_dstSelectDir = new QPushButton(this);
+ m_dstSelectDir->setText(tr("Select..."));
+ rowLayout->addWidget(m_destDir);
+ rowLayout->addWidget(m_dstSelectDir);
+ layout->addWidget(row);
+ layout->addStretch(1);
+ setLayout(layout);
+
+ connect(projIconSel,SIGNAL(clicked()),
+ this,SLOT(selectProjectIcon()));
+ connect(m_srcSelectDir,SIGNAL(clicked()),
+ this,SLOT(selectSourceDir()));
+ connect(m_dstSelectDir,SIGNAL(clicked()),
+ this,SLOT(selectDestinationDir()));
+ connect(m_projName,SIGNAL(textChanged(const QString &)),SLOT(setProjectName(const QString &)));
+ connect(m_projBrief,SIGNAL(textChanged(const QString &)),SLOT(setProjectBrief(const QString &)));
+ connect(m_projNumber,SIGNAL(textChanged(const QString &)),SLOT(setProjectNumber(const QString &)));
+ connect(m_sourceDir,SIGNAL(textChanged(const QString &)),SLOT(setSourceDir(const QString &)));
+ connect(m_recursive,SIGNAL(stateChanged(int)),SLOT(setRecursiveScan(int)));
+ connect(m_destDir,SIGNAL(textChanged(const QString &)),SLOT(setDestinationDir(const QString &)));
+}
+
+void Step1::selectProjectIcon()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString iconName = QFileDialog::getOpenFileName(this,
+ tr("Select project icon/image"),path);
+ if (iconName.isEmpty())
+ {
+ m_projIconLab->setText(tr("No Project logo selected."));
+ }
+ else
+ {
+ QFile Fout(iconName);
+ if(!Fout.exists())
+ {
+ m_projIconLab->setText(tr("Sorry, cannot find file(")+iconName+QString::fromAscii(");"));
+ }
+ else
+ {
+ QPixmap pm(iconName);
+ if (!pm.isNull())
+ {
+ m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
+ }
+ else
+ {
+ m_projIconLab->setText(tr("Sorry, no preview available (")+iconName+QString::fromAscii(");"));
+ }
+ }
+ }
+ updateStringOption(m_modelData,STR_PROJECT_LOGO,iconName);
+}
+
+void Step1::selectSourceDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select source directory"),path);
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_sourceDir->setText(dirName);
+}
+
+void Step1::selectDestinationDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select destination directory"),path);
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_destDir->setText(dirName);
+}
+
+void Step1::setProjectName(const QString &name)
+{
+ updateStringOption(m_modelData,STR_PROJECT_NAME,name);
+}
+
+void Step1::setProjectBrief(const QString &desc)
+{
+ updateStringOption(m_modelData,STR_PROJECT_BRIEF,desc);
+}
+
+void Step1::setProjectNumber(const QString &num)
+{
+ updateStringOption(m_modelData,STR_PROJECT_NUMBER,num);
+}
+
+void Step1::setSourceDir(const QString &dir)
+{
+ Input *option = m_modelData[STR_INPUT];
+ if (option->value().toStringList().count()>0)
+ {
+ QStringList sl = option->value().toStringList();
+ if (sl[0]!=dir)
+ {
+ sl[0] = dir;
+ option->value() = sl;
+ option->update();
+ }
+ }
+ else
+ {
+ option->value() = QStringList() << dir;
+ option->update();
+ }
+}
+
+void Step1::setDestinationDir(const QString &dir)
+{
+ updateStringOption(m_modelData,STR_OUTPUT_DIRECTORY,dir);
+}
+
+void Step1::setRecursiveScan(int s)
+{
+ updateBoolOption(m_modelData,STR_RECURSIVE,s==Qt::Checked);
+}
+
+void Step1::init()
+{
+ Input *option;
+ m_projName->setText(getStringOption(m_modelData,STR_PROJECT_NAME));
+ m_projBrief->setText(getStringOption(m_modelData,STR_PROJECT_BRIEF));
+ m_projNumber->setText(getStringOption(m_modelData,STR_PROJECT_NUMBER));
+ QString iconName = getStringOption(m_modelData,STR_PROJECT_LOGO);
+ if (!iconName.isEmpty())
+ {
+ QFile Fout(iconName);
+ if(!Fout.exists())
+ {
+ m_projIconLab->setText(tr("Sorry, cannot find file(")+iconName+QString::fromAscii(");"));
+ }
+ else
+ {
+ QPixmap pm(iconName);
+ if (!pm.isNull())
+ {
+ m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
+ }
+ else
+ {
+ m_projIconLab->setText(tr("Sorry, no preview available (")+iconName+QString::fromAscii(");"));
+ }
+ }
+ }
+ else
+ {
+ m_projIconLab->setText(tr("No Project logo selected."));
+ }
+ option = m_modelData[STR_INPUT];
+ if (option->value().toStringList().count()>0)
+ {
+ m_sourceDir->setText(option->value().toStringList().first());
+ }
+ m_recursive->setChecked(
+ getBoolOption(m_modelData,STR_RECURSIVE) ? Qt::Checked : Qt::Unchecked);
+ m_destDir->setText(getStringOption(m_modelData,STR_OUTPUT_DIRECTORY));
+}
+
+
+//==========================================================================
+
+Step2::Step2(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ QRadioButton *r;
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ //---------------------------------------------------
+ m_extractModeGroup = new QButtonGroup(this);
+ m_extractMode = new QGroupBox(this);
+ m_extractMode->setTitle(tr("Select the desired extraction mode:"));
+ QGridLayout *gbox = new QGridLayout( m_extractMode );
+ r = new QRadioButton(tr("Documented entities only"));
+ r->setChecked(true);
+ m_extractModeGroup->addButton(r, 0);
+ gbox->addWidget(r,1,0);
+ // 1 -> EXTRACT_ALL = NO
+ r = new QRadioButton(tr("All Entities"));
+ m_extractModeGroup->addButton(r, 1);
+ gbox->addWidget(r,2,0);
+ // 2 -> EXTRACT_ALL = YES
+ m_crossRef = new QCheckBox(m_extractMode);
+ m_crossRef->setText(tr("Include cross-referenced source code in the output"));
+ // m_crossRef -> SOURCE_BROWSER = YES/NO
+ gbox->addWidget(m_crossRef,3,0);
+ layout->addWidget(m_extractMode);
+
+ //---------------------------------------------------
+ QFrame *f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ m_optimizeLangGroup = new QButtonGroup(this);
+ m_optimizeLang = new QGroupBox(this);
+ m_optimizeLang->setTitle(tr("Select programming language to optimize the results for"));
+ gbox = new QGridLayout( m_optimizeLang );
+
+ r = new QRadioButton(m_optimizeLang);
+ r->setText(tr("Optimize for C++ output"));
+ r->setChecked(true);
+ m_optimizeLangGroup->addButton(r, 0);
+ // 0 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,0,0);
+ r = new QRadioButton(tr("Optimize for C++/CLI output"));
+ gbox->addWidget(r,1,0);
+ m_optimizeLangGroup->addButton(r, 1);
+ // 1 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = YES
+ // HIDE_SCOPE_NAMES = NO
+ r = new QRadioButton(tr("Optimize for Java or C# output"));
+ m_optimizeLangGroup->addButton(r, 2);
+ // 2 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = YES
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,2,0);
+ r = new QRadioButton(tr("Optimize for C or PHP output"));
+ m_optimizeLangGroup->addButton(r, 3);
+ // 3 -> OPTIMIZE_OUTPUT_FOR_C = YES
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = YES
+ gbox->addWidget(r,3,0);
+ r = new QRadioButton(tr("Optimize for Fortran output"));
+ m_optimizeLangGroup->addButton(r, 4);
+ // 4 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = YES
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,4,0);
+ r = new QRadioButton(tr("Optimize for VHDL output"));
+ m_optimizeLangGroup->addButton(r, 5);
+ // 5 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = YES
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,5,0);
+
+ layout->addWidget(m_optimizeLang);
+ layout->addStretch(1);
+
+ connect(m_crossRef,SIGNAL(stateChanged(int)),
+ SLOT(changeCrossRefState(int)));
+ connect(m_optimizeLangGroup,SIGNAL(buttonClicked(int)),
+ SLOT(optimizeFor(int)));
+ connect(m_extractModeGroup,SIGNAL(buttonClicked(int)),
+ SLOT(extractMode(int)));
+}
+
+
+void Step2::optimizeFor(int choice)
+{
+ for (int i=0;i<6;i++)
+ {
+ updateBoolOption(m_modelData,
+ g_optimizeOptionNames[i],
+ g_optimizeMapping[choice][i]);
+ }
+}
+
+void Step2::extractMode(int choice)
+{
+ updateBoolOption(m_modelData,STR_EXTRACT_ALL,choice==1);
+}
+
+void Step2::changeCrossRefState(int choice)
+{
+ updateBoolOption(m_modelData,STR_SOURCE_BROWSER,choice==Qt::Checked);
+}
+
+void Step2::init()
+{
+ m_extractModeGroup->button(
+ getBoolOption(m_modelData,STR_EXTRACT_ALL) ? 1 : 0)->setChecked(true);
+ m_crossRef->setChecked(getBoolOption(m_modelData,STR_SOURCE_BROWSER));
+
+ int x=0;
+ if (getBoolOption(m_modelData,STR_CPP_CLI_SUPPORT)) x=1;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_JAVA)) x=2;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_FOR_C)) x=3;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_FOR_FORTRAN)) x=4;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_VHDL)) x=5;
+ m_optimizeLangGroup->button(x)->setChecked(true);
+}
+
+//==========================================================================
+
+Step3::Step3(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ QVBoxLayout *vbox = 0;
+ QRadioButton *r = 0;
+
+ QGridLayout *gbox = new QGridLayout( this );
+ gbox->addWidget(new QLabel(tr("Select the output format(s) to generate")),0,0);
+ {
+ m_htmlOptions = new QGroupBox(tr("HTML"));
+ m_htmlOptions->setCheckable(true);
+ // GENERATE_HTML
+ m_htmlOptionsGroup = new QButtonGroup(m_htmlOptions);
+ QRadioButton *r = new QRadioButton(tr("plain HTML"));
+ r->setChecked(true);
+ m_htmlOptionsGroup->addButton(r, 0);
+ vbox = new QVBoxLayout;
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("with navigation panel"));
+ m_htmlOptionsGroup->addButton(r, 1);
+ // GENERATE_TREEVIEW
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("prepare for compressed HTML (.chm)"));
+ m_htmlOptionsGroup->addButton(r, 2);
+ // GENERATE_HTMLHELP
+ vbox->addWidget(r);
+ m_searchEnabled=new QCheckBox(tr("With search function"));
+ vbox->addWidget(m_searchEnabled);
+ // SEARCH_ENGINE
+ QHBoxLayout *hbox = new QHBoxLayout;
+ m_tuneColor=new QPushButton(tr("Change color..."));
+ hbox->addWidget(m_tuneColor);
+ hbox->addStretch(1);
+ vbox->addLayout(hbox);
+ m_htmlOptions->setLayout(vbox);
+ m_htmlOptions->setChecked(true);
+ }
+ gbox->addWidget(m_htmlOptions,1,0);
+
+ {
+ m_texOptions = new QGroupBox(tr("LaTeX"));
+ m_texOptions->setCheckable(true);
+ // GENERATE_LATEX
+ m_texOptionsGroup = new QButtonGroup(m_texOptions);
+ vbox = new QVBoxLayout;
+ r = new QRadioButton(tr("as intermediate format for hyperlinked PDF"));
+ m_texOptionsGroup->addButton(r, 0);
+ // PDF_HYPERLINKS = YES
+ r->setChecked(true);
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("as intermediate format for PDF"));
+ m_texOptionsGroup->addButton(r, 1);
+ // PDF_HYPERLINKS = NO, USE_PDFLATEX = YES
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("as intermediate format for PostScript"));
+ m_texOptionsGroup->addButton(r, 2);
+ // USE_PDFLATEX = NO
+ vbox->addWidget(r);
+ vbox->addStretch(1);
+ m_texOptions->setLayout(vbox);
+ m_texOptions->setChecked(true);
+ }
+ gbox->addWidget(m_texOptions,2,0);
+
+ m_manEnabled=new QCheckBox(tr("Man pages"));
+ // GENERATE_MAN
+ m_rtfEnabled=new QCheckBox(tr("Rich Text Format (RTF)"));
+ // GENERATE_RTF
+ m_xmlEnabled=new QCheckBox(tr("XML"));
+ // GENERATE_XML
+ gbox->addWidget(m_manEnabled,3,0);
+ gbox->addWidget(m_rtfEnabled,4,0);
+ gbox->addWidget(m_xmlEnabled,5,0);
+
+ gbox->setRowStretch(6,1);
+ connect(m_htmlOptions,SIGNAL(toggled(bool)),SLOT(setHtmlEnabled(bool)));
+ connect(m_texOptions,SIGNAL(toggled(bool)),SLOT(setLatexEnabled(bool)));
+ connect(m_manEnabled,SIGNAL(stateChanged(int)),SLOT(setManEnabled(int)));
+ connect(m_rtfEnabled,SIGNAL(stateChanged(int)),SLOT(setRtfEnabled(int)));
+ connect(m_xmlEnabled,SIGNAL(stateChanged(int)),SLOT(setXmlEnabled(int)));
+ connect(m_searchEnabled,SIGNAL(stateChanged(int)),SLOT(setSearchEnabled(int)));
+ connect(m_htmlOptionsGroup,SIGNAL(buttonClicked(int)),
+ SLOT(setHtmlOptions(int)));
+ connect(m_texOptionsGroup,SIGNAL(buttonClicked(int)),
+ SLOT(setLatexOptions(int)));
+ connect(m_tuneColor,SIGNAL(clicked()),SLOT(tuneColorDialog()));
+}
+
+void Step3::tuneColorDialog()
+{
+ int hue = getIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE);
+ int sat = getIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT);
+ int gam = getIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA);
+ TuneColorDialog tuneColor(hue,sat,gam,this);
+ if (tuneColor.exec()==QDialog::Accepted)
+ {
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE,tuneColor.getHue());
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT,tuneColor.getSaturation());
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA,tuneColor.getGamma());
+ }
+}
+
+void Step3::setHtmlEnabled(bool b)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_HTML,b);
+}
+
+void Step3::setLatexEnabled(bool b)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_LATEX,b);
+}
+
+void Step3::setManEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_MAN,state==Qt::Checked);
+}
+
+void Step3::setRtfEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_RTF,state==Qt::Checked);
+}
+
+void Step3::setXmlEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_XML,state==Qt::Checked);
+}
+
+void Step3::setSearchEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_SEARCHENGINE,state==Qt::Checked);
+}
+
+void Step3::setHtmlOptions(int id)
+{
+ if (id==0) // plain HTML
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
+ }
+ else if (id==1) // with navigation tree
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,true);
+ }
+ else if (id==2) // with compiled help
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,true);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
+ }
+}
+
+void Step3::setLatexOptions(int id)
+{
+ if (id==0) // hyperlinked PDF
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,true);
+ }
+ else if (id==1) // PDF
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
+ }
+ else if (id==2) // PostScript
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,false);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
+ }
+}
+
+void Step3::init()
+{
+ m_htmlOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_HTML));
+ m_texOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_LATEX));
+ m_manEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_MAN));
+ m_rtfEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_RTF));
+ m_xmlEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_XML));
+ m_searchEnabled->setChecked(getBoolOption(m_modelData,STR_SEARCHENGINE));
+ if (getBoolOption(m_modelData,STR_GENERATE_HTMLHELP))
+ {
+ m_htmlOptionsGroup->button(2)->setChecked(true); // compiled help
+ }
+ else if (getBoolOption(m_modelData,STR_GENERATE_TREEVIEW))
+ {
+ m_htmlOptionsGroup->button(1)->setChecked(true); // navigation tree
+ }
+ else
+ {
+ m_htmlOptionsGroup->button(0)->setChecked(true); // plain HTML
+ }
+ if (!getBoolOption(m_modelData,STR_USE_PDFLATEX))
+ {
+ m_texOptionsGroup->button(2)->setChecked(true); // PostScript
+ }
+ else if (!getBoolOption(m_modelData,STR_PDF_HYPERLINKS))
+ {
+ m_texOptionsGroup->button(1)->setChecked(true); // Plain PDF
+ }
+ else
+ {
+ m_texOptionsGroup->button(0)->setChecked(true); // PDF with hyperlinks
+ }
+}
+
+//==========================================================================
+
+Step4::Step4(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ m_diagramModeGroup = new QButtonGroup(this);
+ QGridLayout *gbox = new QGridLayout( this );
+ gbox->addWidget(new QLabel(tr("Diagrams to generate")),0,0);
+
+ QRadioButton *rb = new QRadioButton(tr("No diagrams"));
+ m_diagramModeGroup->addButton(rb, 0);
+ gbox->addWidget(rb,1,0);
+ // CLASS_DIAGRAMS = NO, HAVE_DOT = NO
+ rb->setChecked(true);
+ rb = new QRadioButton(tr("Use built-in class diagram generator"));
+ m_diagramModeGroup->addButton(rb, 1);
+ // CLASS_DIAGRAMS = YES, HAVE_DOT = NO
+ gbox->addWidget(rb,2,0);
+ rb = new QRadioButton(tr("Use dot tool from the GraphViz package"));
+ m_diagramModeGroup->addButton(rb, 2);
+ gbox->addWidget(rb,3,0);
+ // CLASS_DIAGRAMS = NO, HAVE_DOT = YES
+
+ m_dotGroup = new QGroupBox(tr("Dot graphs to generate"));
+ QVBoxLayout *vbox = new QVBoxLayout;
+ m_dotClass=new QCheckBox(tr("Class diagrams"));
+ // CLASS_GRAPH
+ m_dotCollaboration=new QCheckBox(tr("Collaboration diagrams"));
+ // COLLABORATION_GRAPH
+ m_dotInheritance=new QCheckBox(tr("Overall Class hierarchy"));
+ // GRAPHICAL_HIERARCHY
+ m_dotInclude=new QCheckBox(tr("Include dependency graphs"));
+ // INCLUDE_GRAPH
+ m_dotIncludedBy=new QCheckBox(tr("Included by dependency graphs"));
+ // INCLUDED_BY_GRAPH
+ m_dotCall=new QCheckBox(tr("Call graphs"));
+ // CALL_GRAPH
+ m_dotCaller=new QCheckBox(tr("Called by graphs"));
+ // CALLER_GRAPH
+ vbox->addWidget(m_dotClass);
+ vbox->addWidget(m_dotCollaboration);
+ vbox->addWidget(m_dotInheritance);
+ vbox->addWidget(m_dotInclude);
+ vbox->addWidget(m_dotIncludedBy);
+ vbox->addWidget(m_dotCall);
+ vbox->addWidget(m_dotCaller);
+ vbox->addStretch(1);
+ m_dotGroup->setLayout(vbox);
+ m_dotClass->setChecked(true);
+ m_dotGroup->setEnabled(false);
+ gbox->addWidget(m_dotGroup,4,0);
+
+ m_dotInclude->setChecked(true);
+ m_dotCollaboration->setChecked(true);
+ gbox->setRowStretch(5,1);
+
+ connect(m_diagramModeGroup,SIGNAL(buttonClicked(int)),
+ this,SLOT(diagramModeChanged(int)));
+ connect(m_dotClass,SIGNAL(stateChanged(int)),
+ this,SLOT(setClassGraphEnabled(int)));
+ connect(m_dotCollaboration,SIGNAL(stateChanged(int)),
+ this,SLOT(setCollaborationGraphEnabled(int)));
+ connect(m_dotInheritance,SIGNAL(stateChanged(int)),
+ this,SLOT(setGraphicalHierarchyEnabled(int)));
+ connect(m_dotInclude,SIGNAL(stateChanged(int)),
+ this,SLOT(setIncludeGraphEnabled(int)));
+ connect(m_dotIncludedBy,SIGNAL(stateChanged(int)),
+ this,SLOT(setIncludedByGraphEnabled(int)));
+ connect(m_dotCall,SIGNAL(stateChanged(int)),
+ this,SLOT(setCallGraphEnabled(int)));
+ connect(m_dotCaller,SIGNAL(stateChanged(int)),
+ this,SLOT(setCallerGraphEnabled(int)));
+}
+
+void Step4::diagramModeChanged(int id)
+{
+ if (id==0) // no diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,false);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
+ }
+ else if (id==1) // builtin diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,false);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,true);
+ }
+ else if (id==2) // dot diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,true);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
+ }
+ m_dotGroup->setEnabled(id==2);
+}
+
+void Step4::setClassGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CLASS_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCollaborationGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_COLLABORATION_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setGraphicalHierarchyEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY,state==Qt::Checked);
+}
+
+void Step4::setIncludeGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_INCLUDE_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setIncludedByGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCallGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CALL_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCallerGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CALLER_GRAPH,state==Qt::Checked);
+}
+
+void Step4::init()
+{
+ if (getBoolOption(m_modelData,STR_HAVE_DOT))
+ {
+ m_diagramModeGroup->button(2)->setChecked(true); // Dot
+ }
+ else if (getBoolOption(m_modelData,STR_CLASS_DIAGRAMS))
+ {
+ m_diagramModeGroup->button(1)->setChecked(true); // Builtin diagrams
+ }
+ else
+ {
+ m_diagramModeGroup->button(0)->setChecked(true); // no diagrams
+ }
+ m_dotClass->setChecked(getBoolOption(m_modelData,STR_CLASS_GRAPH));
+ m_dotCollaboration->setChecked(getBoolOption(m_modelData,STR_COLLABORATION_GRAPH));
+ m_dotInheritance->setChecked(getBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY));
+ m_dotInclude->setChecked(getBoolOption(m_modelData,STR_INCLUDE_GRAPH));
+ m_dotIncludedBy->setChecked(getBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH));
+ m_dotCall->setChecked(getBoolOption(m_modelData,STR_CALL_GRAPH));
+ m_dotCaller->setChecked(getBoolOption(m_modelData,STR_CALLER_GRAPH));
+}
+
+//==========================================================================
+
+Wizard::Wizard(const QHash<QString,Input*> &modelData, QWidget *parent) :
+ QSplitter(parent), m_modelData(modelData)
+{
+ m_treeWidget = new QTreeWidget;
+ m_treeWidget->setColumnCount(1);
+ m_treeWidget->setHeaderLabels(QStringList() << QString::fromAscii("Topics"));
+ QList<QTreeWidgetItem*> items;
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Project"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Mode"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Output"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Diagrams"))));
+ m_treeWidget->insertTopLevelItems(0,items);
+
+ m_topicStack = new QStackedWidget;
+ m_step1 = new Step1(this,modelData);
+ m_step2 = new Step2(this,modelData);
+ m_step3 = new Step3(this,modelData);
+ m_step4 = new Step4(this,modelData);
+ m_topicStack->addWidget(m_step1);
+ m_topicStack->addWidget(m_step2);
+ m_topicStack->addWidget(m_step3);
+ m_topicStack->addWidget(m_step4);
+
+ QWidget *rightSide = new QWidget;
+ QGridLayout *grid = new QGridLayout(rightSide);
+ m_prev = new QPushButton(tr("Previous"));
+ m_prev->setEnabled(false);
+ m_next = new QPushButton(tr("Next"));
+ grid->addWidget(m_topicStack,0,0,1,2);
+ grid->addWidget(m_prev,1,0,Qt::AlignLeft);
+ grid->addWidget(m_next,1,1,Qt::AlignRight);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+ addWidget(m_treeWidget);
+ addWidget(rightSide);
+
+ connect(m_treeWidget,
+ SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
+ SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
+ connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
+ connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
+
+ refresh();
+}
+
+Wizard::~Wizard()
+{
+}
+
+void Wizard::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
+{
+ if (item)
+ {
+
+ QString label = item->text(0);
+ if (label==tr("Project"))
+ {
+ m_topicStack->setCurrentWidget(m_step1);
+ m_prev->setEnabled(false);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Mode"))
+ {
+ m_topicStack->setCurrentWidget(m_step2);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Output"))
+ {
+ m_topicStack->setCurrentWidget(m_step3);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Diagrams"))
+ {
+ m_topicStack->setCurrentWidget(m_step4);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(true);
+ }
+ }
+}
+
+void Wizard::nextTopic()
+{
+ if (m_topicStack->currentIndex()+1==m_topicStack->count()) // last topic
+ {
+ done();
+ }
+ else
+ {
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+ }
+}
+
+void Wizard::prevTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Wizard::refresh()
+{
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(0));
+ m_step1->init();
+ m_step2->init();
+ m_step3->init();
+ m_step4->init();
+}
diff --git a/addon/doxywizard/wizard.h b/addon/doxywizard/wizard.h
new file mode 100644
index 0000000..4d5eb9d
--- /dev/null
+++ b/addon/doxywizard/wizard.h
@@ -0,0 +1,256 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include <QSplitter>
+#include <QHash>
+#include <QDialog>
+
+class Input;
+class QTreeWidget;
+class QTreeWidgetItem;
+class QStackedWidget;
+class QCheckBox;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class QGroupBox;
+class QButtonGroup;
+class Wizard;
+class QImage;
+class QLabel;
+
+enum OptLang { Lang_Cpp, Lang_C, Lang_Java, Lang_CS };
+enum HtmlStyle { HS_Plain, HS_TreeView, HS_CHM };
+enum TexStyle { TS_PDFHyper, TS_PDF, TS_PS };
+enum DiagramMode { DM_None, DM_Builtin, DM_Dot };
+
+class TuneColorDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ TuneColorDialog(int hue,int sat,int gamma,QWidget *parent=0);
+ int getHue() const;
+ int getSaturation() const;
+ int getGamma() const;
+
+ private slots:
+ void updateImage(int hue,int sat,int val);
+
+ private:
+ QImage *m_image;
+ QLabel *m_imageLab;
+ int m_hue;
+ int m_sat;
+ int m_gam;
+};
+
+class ColorPicker : public QWidget
+{
+ Q_OBJECT
+public:
+ enum Mode { Hue, Saturation, Gamma };
+ ColorPicker(Mode m);
+ ~ColorPicker();
+
+public slots:
+ void setCol(int h, int s, int g);
+ //void setCol(int h, int s);
+
+signals:
+ void newHsv(int h, int s, int g);
+
+protected:
+ void paintEvent(QPaintEvent*);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+
+private:
+ enum { foff = 3, coff = 4 }; //frame and contents offset
+ int y2hue(int y);
+ int y2sat(int y);
+ int y2gam(int y);
+ int hue2y(int hue);
+ int sat2y(int sat);
+ int gam2y(int gamma);
+ void setHue(int v);
+ void setSat(int v);
+ void setGam(int v);
+
+ QPixmap *m_pix;
+ Mode m_mode;
+ int m_gam;
+ int m_hue;
+ int m_sat;
+
+};
+
+
+class Step1 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step1(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void selectSourceDir();
+ void selectDestinationDir();
+ void selectProjectIcon();
+ void setProjectName(const QString &name);
+ void setProjectBrief(const QString &desc);
+ void setProjectNumber(const QString &num);
+ void setSourceDir(const QString &dir);
+ void setDestinationDir(const QString &dir);
+ void setRecursiveScan(int);
+
+ private:
+ QLineEdit *m_projName;
+ QLineEdit *m_projBrief;
+ QLineEdit *m_projNumber;
+ QLineEdit *m_sourceDir;
+ QLineEdit *m_destDir;
+ QLabel *m_projIconLab;
+ QCheckBox *m_recursive;
+ QPushButton *m_srcSelectDir;
+ QPushButton *m_dstSelectDir;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step2 : public QWidget
+{
+ Q_OBJECT
+ public:
+ Step2(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void optimizeFor(int choice);
+ void extractMode(int choice);
+ void changeCrossRefState(int choice);
+
+ private:
+ QGroupBox *m_extractMode;
+ QGroupBox *m_optimizeLang;
+ QButtonGroup *m_extractModeGroup;
+ QButtonGroup *m_optimizeLangGroup;
+ QCheckBox *m_crossRef;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step3 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step3(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void setHtmlEnabled(bool);
+ void setLatexEnabled(bool);
+ void setManEnabled(int);
+ void setRtfEnabled(int);
+ void setXmlEnabled(int);
+ void setSearchEnabled(int);
+ void setHtmlOptions(int);
+ void setLatexOptions(int);
+ void tuneColorDialog();
+
+ private:
+ QGroupBox *m_texOptions;
+ QButtonGroup *m_texOptionsGroup;
+ QGroupBox *m_htmlOptions;
+ QButtonGroup *m_htmlOptionsGroup;
+ QCheckBox *m_htmlEnabled;
+ QCheckBox *m_latexEnabled;
+ QCheckBox *m_manEnabled;
+ QCheckBox *m_rtfEnabled;
+ QCheckBox *m_xmlEnabled;
+ QCheckBox *m_searchEnabled;
+ QPushButton *m_tuneColor;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step4 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step4(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void diagramModeChanged(int);
+ void setClassGraphEnabled(int state);
+ void setCollaborationGraphEnabled(int state);
+ void setGraphicalHierarchyEnabled(int state);
+ void setIncludeGraphEnabled(int state);
+ void setIncludedByGraphEnabled(int state);
+ void setCallGraphEnabled(int state);
+ void setCallerGraphEnabled(int state);
+
+ private:
+ QGroupBox *m_diagramMode;
+ QButtonGroup *m_diagramModeGroup;
+ QGroupBox *m_dotGroup;
+ QCheckBox *m_dotClass;
+ QCheckBox *m_dotCollaboration;
+ QCheckBox *m_dotInclude;
+ QCheckBox *m_dotIncludedBy;
+ QCheckBox *m_dotInheritance;
+ QCheckBox *m_dotCall;
+ QCheckBox *m_dotCaller;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Wizard : public QSplitter
+{
+ Q_OBJECT
+ public:
+ Wizard(const QHash<QString,Input*> &modelData, QWidget *parent=0);
+ ~Wizard();
+
+ public slots:
+ void refresh();
+
+ private slots:
+ void activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *);
+ void nextTopic();
+ void prevTopic();
+
+ signals:
+ void done();
+
+ private:
+ const QHash<QString,Input *> &m_modelData;
+ QTreeWidget *m_treeWidget;
+ QStackedWidget *m_topicStack;
+ Step1 *m_step1;
+ Step2 *m_step2;
+ Step3 *m_step3;
+ Step4 *m_step4;
+ QPushButton *m_next;
+ QPushButton *m_prev;
+};
+
+#endif
diff --git a/configure b/configure
new file mode 100755
index 0000000..5c01af0
--- /dev/null
+++ b/configure
@@ -0,0 +1,988 @@
+#!/bin/sh
+#
+# $Id$
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# shell script to configure doxygen
+
+doxygen_version_major=1
+doxygen_version_minor=8
+doxygen_version_revision=8
+
+#NOTE: Setting version_mmn to "NO" will omit mmn info from the package.
+doxygen_version_mmn=NO
+
+bin_dirs=`echo $PATH | sed -e "s/:/ /g"`
+
+f_debug=NO
+f_shared=YES
+f_make=NO
+f_dot=NO
+f_perl=NO
+f_python=NO
+f_plf_auto=NO
+f_prefix=/usr/local
+f_insttool=NO
+f_english=NO
+f_wizard=NO
+f_app=NO
+f_doxmlparser=NO
+f_thread=NO
+f_flex=NO
+f_bison=NO
+f_search=NO
+f_sqlite3=NO
+f_sqlite3static=NO
+f_sqlite3_path=NO
+f_libclang=NO
+f_libclangstatic=NO
+
+#
+# first setup the list with availabe languages, so we cannot forget any
+# list will be in case as specified (f_langs) and in uppercase (f_ulangs) as used in the internal perl script
+#
+f_langs=`ls -1 src/translator_??.h | sed -e 's%src/translator_%%g' | sed -e 's/\.h//' | tr '\012' ','`
+
+while test -n "$1"; do
+ case $1 in
+ --prefix=*)
+ f_prefix=`echo $1 | sed 's/^--prefix=//'`
+ ;;
+ --prefix | -prefix)
+ shift; f_prefix=$1
+ ;;
+ --docdir=*)
+ f_docdir=`echo $1 | sed 's/^--docdir=//'`
+ ;;
+ --docdir | -docdir)
+ shift; f_docdir=$1
+ ;;
+ --shared | -shared)
+ f_shared=YES
+ ;;
+ --static | -static)
+ f_shared=NO
+ ;;
+ --release | -release)
+ f_debug=NO
+ ;;
+ --debug | -debug)
+ f_debug=YES
+ ;;
+ --english-only | -english-only)
+ f_english=YES
+ ;;
+ --enable-langs=*)
+ f_langs=`echo $1 | sed 's/^--enable-langs=//'`
+ ;;
+ --enable-langs | -enable-langs)
+ shift; f_langs=$1
+ ;;
+ --platform=*)
+ f_platform=`echo $1 | sed 's/^--platform=//'`
+ ;;
+ --platform | -platform)
+ shift; f_platform=$1
+ ;;
+ --make=*)
+ f_make=`echo $1 | sed 's/^--make=//'`
+ ;;
+ --make | -make)
+ shift; f_make=$1
+ ;;
+ --dot=*)
+ f_dot=`echo $1 | sed 's/^--dot=//'`
+ ;;
+ --dot | -dot)
+ shift; f_dot=$1
+ ;;
+ --python=*)
+ f_python=`echo $1 | sed 's/^--python=//'`
+ ;;
+ --python | -python)
+ shift; f_python=$1
+ ;;
+ --perl=*)
+ f_perl=`echo $1 | sed 's/^--perl=//'`
+ ;;
+ --perl | -perl)
+ shift; f_perl=$1
+ ;;
+ --flex=*)
+ f_flex=`echo $1 | sed 's/^--flex=//'`
+ ;;
+ --flex | -flex)
+ shift; f_flex=$1
+ ;;
+ --bison=*)
+ f_bison=`echo $1 | sed 's/^--bison=//'`
+ ;;
+ --bison | -bison)
+ shift; f_bison=$1
+ ;;
+ --install=*)
+ f_insttool=`echo $1 | sed 's/^--install=//'`
+ ;;
+ --install | -install)
+ shift; f_insttool=$1
+ ;;
+ --with-doxywizard | -with-doxywizard)
+ f_wizard=YES
+ ;;
+ --with-doxyapp | -with-doxyapp)
+ f_app=YES
+ ;;
+ --with-doxmlparser | -with-doxmlparser)
+ f_doxmlparser=YES
+ ;;
+ --with-doxysearch | -with-doxysearch)
+ f_search=YES
+ ;;
+ --with-sqlite3 | -with-sqlite3)
+ f_sqlite3=YES
+ ;;
+ --with-sqlite3-static | -with-sqlite3-static)
+ f_sqlite3=YES
+ f_sqlite3static=YES
+ ;;
+ --sqlite3-path=*)
+ f_sqlite3_path=`echo $1 | sed 's/^--sqlite3-path=//'`
+ ;;
+ --sqlite3-path | -sqlite3-path)
+ shift; f_sqlite3_path=$1
+ ;;
+ --with-libclang | -with-libclang)
+ f_libclang=YES
+ ;;
+ --with-libclang-static | -with-libclang-static)
+ f_libclang=YES
+ f_libclangstatic=YES
+ ;;
+ -h | -help | --help)
+ f_help=y
+ ;;
+ *)
+ echo $1: unknown argument
+ f_help=y
+ f_error=y
+ ;;
+ esac
+ shift
+done
+
+if test "$f_help" = y; then
+ cat <<EOF
+Usage: $0 [--help] [--shared] [--static] [--release] [--debug] [--python name]
+ [--perl name] [--flex name] [--bison name] [--make name]
+ [--dot name] [--platform target] [--prefix dir] [--docdir dir]
+ [--install name] [--english-only] [--enable-langs list]
+ [--with-sqlite3] [--with-sqlite3-static] [--sqlite3-path]
+ [--with-libclang] [--with-libclang-static]
+ [--with-doxywizard] [--with-doxysearch] [--with-doxyapp]
+ [--with-doxxmlparser]
+
+Options:
+
+ --help Print this help
+ --shared | --static Build using shared or static linking
+ [default: shared]
+ --release | --debug Build for release or debug
+ [default: release]
+ --python name Use \`name' as the name of the python interpreter
+ [default: autodetect]
+ --perl name Use \`name' as the name of the perl interpreter
+ [default: autodetect]
+ --flex name Use \`name' as the name of the GNU lexical scanner
+ [default: autodetect]
+ --bison name Use \`name' as the name of the GNU compiler generator
+ [default: autodetect]
+ --make name Use \`name' as the name of the GNU make tool
+ [default: autodetect]
+ --dot name Use \`name' as the name of the dot tool that
+ is part of the Graphviz package.
+ [default: autodetect]
+ --platform target Do not detect platform but use \`target' instead.
+ See PLATFORMS for a list of possibilities
+ --prefix dir Installation prefix directory (doxygen will be
+ put in PREFIX/bin/doxygen)
+ [default: $f_prefix]
+ --docdir dir Documentation is installed in DOCDIR/
+ [default: PREFIX/share/doc/packages/doxygen]
+ --install name Use \`name' as the name of the GNU install tool
+ [default: autodetect]
+ --english-only Include support for English only.
+ --enable-langs list Include support for output languages listed in list.
+ [default: $f_langs]
+ --with-sqlite3 Add support for sqlite3 output [experimental]
+ --with-libclang Add support for libclang parsing
+ --with-doxywizard Build the GUI frontend for doxygen. This
+ requires Qt version 4.
+ --with-doxysearch Build external search tools (doxysearch and doxyindexer)
+ requires Xapian library version 1.2
+ --with-doxyapp Example showing how to embed doxygen in an application.
+ --with-doxmlparser Example showing how to parse doxygen's XML output.
+
+EOF
+ test "$f_error" = y && exit 1
+ exit 0;
+fi
+
+u_release=`(uname -r) 2>/dev/null` || u_release=unknown
+u_system=`(uname -s) 2>/dev/null` || u_system=unknown
+
+if test -z "$f_platform"; then
+ f_platforms="`cat PLATFORMS`"
+
+ case "$u_system:$u_release" in
+ AIX*)
+ f_platform=aix-xlc
+ ;;
+ BeOS*)
+ f_platform=beos-g++
+ ;;
+ dgux:*)
+ f_platform=dgux-g++
+ ;;
+ Darwin:*)
+ f_platform=macosx-c++
+ if test "$f_insttool" = NO; then
+ f_insttool=/usr/bin/install
+ fi
+ ;;
+ FreeBSD:*)
+ f_platform=freebsd-g++
+ if test "$f_insttool" = NO; then
+ f_insttool=/usr/bin/install
+ fi
+ ;;
+ NetBSD:*)
+ f_platform=netbsd-g++
+ if test "$f_insttool" = NO; then
+ f_insttool=/usr/bin/install
+ fi
+ ;;
+ HP-UX:*)
+ f_platform=hpux-g++
+ if test "$f_insttool" = NO; then
+ f_insttool=/usr/bin/install
+ fi
+ ;;
+ IRIX64:*)
+ f_platform=irix-64
+ ;;
+ IRIX:*)
+ f_platform=irix-n32
+ ;;
+ Linux:*|GNU:*|GNU/*:*)
+ f_platform=linux-g++
+ ;;
+ NetBSD:*)
+ f_platform=netbsd-g++
+ ;;
+ OpenBSD:*)
+ f_platform=openbsd-g++
+ ;;
+ OSF1:*)
+ f_platform=osf1-g++
+ ;;
+ QNX:*)
+ f_platform=qnx-g++
+ ;;
+ *:3.2)
+ f_platform=sco-g++
+ ;;
+ SunOS:4*)
+ f_platform=sunos-g++
+ ;;
+ SunOS:5*)
+ f_platform=solaris-g++
+ if test "$f_insttool" = NO; then
+ f_insttool=/usr/bin/install
+ fi
+ ;;
+ ULTRIX:*)
+ f_platform=ultrix-g++
+ ;;
+ UNIX_SV:4.2*)
+ f_platform=unixware-g++
+ ;;
+ Cygwin:*|CYGWIN*)
+ f_platform=win32-g++
+ ;;
+ MINGW32_NT*)
+ f_platform=win32-mingw
+ ;;
+ *MiNT:*)
+ f_platform=m68k-atari-mint-g++
+ ;;
+ *)
+ echo
+ echo "Your platform was not recognised by this configure script"
+ echo "Please use the -platform option to specify one of platforms"
+ echo "in this list:"
+ echo
+ for p in $f_platforms
+ do
+ echo " $0 $* -platform $p"
+ done
+ echo
+ exit 2
+ esac
+ echo " Autodetected platform $f_platform... "
+ f_plf_auto=YES
+fi
+
+if test -z "$f_docdir"; then
+ f_docdir='$(INSTALL)/share/doc/packages/doxygen'
+fi
+
+if test "$f_plf_auto" = NO; then
+ printf " Checking for platform $f_platform... "
+ if test '!' -d tmake/lib/$f_platform; then
+ echo "not supported!"
+ echo
+ exit 2
+ fi
+ echo "supported"
+fi
+
+#- check for qt --------------------------------------------------------------
+
+if test "$f_wizard" = YES; then
+ if test -z "$QTDIR"; then
+ echo " QTDIR environment variable not set!"
+ printf " Checking for Qt..."
+ for d in /usr/{lib,share,qt}/{qt-4,qt4,qt,qt*,4} /usr; do
+ if test -x "$d/bin/qmake"; then
+ QTDIR=$d
+ break 2
+ fi
+ done
+ else
+ if test -e "$QTDIR/bin/qmake"; then
+ printf " Detected Qt via the QTDIR environment variable..."
+ else
+ printf "ERROR Detected Qt via the QTDIR environment variable..."
+ echo ", but $QTDIR/bin/qmake does not exist."
+ echo " Set the QTDIR environment variable such that \$QTDIR/bin/qmake exists."
+ exit 2
+ fi
+ fi
+ if test -z "$QTDIR"; then
+ echo "QTDIR not set and Qt not found at standard locations!"
+ echo
+ echo "Set the QTDIR environment variable such that \$QTDIR/bin/qmake exists."
+ echo "check the Qt installation instructions!"
+ exit 2
+ fi
+ echo using $QTDIR
+fi
+
+#- check for xapian -----------------------------------------------------------
+
+if test "$f_search" = YES; then
+ if test -z "$XAPIAN"; then
+ printf " Checking for Xapian..."
+ for d in /usr /usr/local /opt/local; do
+ if test -e "$d/include/xapian.h"; then
+ XAPIAN=$d
+ break 2
+ fi
+ done
+ else
+ if test -e "$XAPIAN/include/xapian.h"; then
+ printf " Detected Xapian via the XAPIAN environment variable..."
+ else
+ printf "ERROR Detected Xapian via the XAPIAN environment variable..."
+ echo ", but $XAPIAN/include/xapian.h does not exist."
+ echo " Set the XAPIAN environment variable such that \$XAPIAN/include/xapian.h exists."
+ exit 2
+ fi
+ fi
+ if test -z "$XAPIAN"; then
+ echo "XAPIAN not set and xapian.h not found at standard locations!"
+ exit 2;
+ fi
+ echo using $XAPIAN
+fi
+
+# - check for make ------------------------------------------------------------
+
+printf " Checking for GNU make tool... "
+if test "$f_make" = NO; then
+ make_names="gmake make"
+ make_dirs="$bin_dirs /usr/bin /usr/local/bin /bin /sbin"
+ make_prog=NO
+ for i in $make_names; do
+ for j in $make_dirs; do
+ if test -x "$j/$i"; then
+ if test -n "`$j/$i --version 2>/dev/null | grep GNU`"; then
+ make_prog="$j/$i"
+ break 2
+ fi
+ fi
+ done
+ done
+ f_make="$make_prog"
+fi
+
+if test "$f_make" = NO; then
+ echo "not found!";
+ echo
+ exit 2
+fi
+echo "using $f_make"
+
+# - check for install ------------------------------------------------------------
+
+printf " Checking for GNU install tool... "
+if test "$f_insttool" = NO; then
+ install_names="ginstall install"
+ install_dirs="$bin_dirs /usr/bin /usr/local/bin /bin /sbin /usr/ucb"
+ install_prog=NO
+ install_found=NO
+ for i in $install_names; do
+ for j in $install_dirs; do
+ if test -x "$j/$i"; then
+ if test -n "`$j/$i --version 2>/dev/null | grep utils`"; then
+ install_found=YES
+ install_prog="$j/$i"
+ break 2
+ fi
+ fi
+ done
+ done
+ f_insttool="$install_prog"
+fi
+
+if test "$f_insttool" = NO; then
+ if test "$install_found" = YES; then
+ echo;
+ else
+ echo "not found!";
+ echo
+ fi
+ echo "GNU version of install is required: this is part of the fileutils/coreutils package: "
+ echo "see http://www.gnu.org/software/fileutils/fileutils.html"
+ echo
+ exit 2
+fi
+echo "using $f_insttool";
+
+
+# - check for dot ------------------------------------------------------------
+
+printf " Checking for dot (part of GraphViz)... "
+if test "$f_dot" = NO; then
+ dot_dirs="$bin_dirs /usr/bin /usr/local/bin /bin /sbin"
+ dot_prog=NO
+ for j in $dot_dirs; do
+ if test -x "$j/dot"; then
+ dot_prog="$j/dot"
+ break 2
+ fi
+ done
+ f_dot="$dot_prog"
+fi
+
+if test "$f_dot" = NO; then
+ echo "not found!";
+else
+ echo "using $f_dot"
+fi
+
+# - check for sqlite3 ---------------------------------------------------------
+
+if test "$f_sqlite3" = YES; then
+ printf " Checking for sqlite3 ... "
+ if test "$f_sqlite3_path" = NO; then
+ sqlite3_hdr_dir="/usr/include /usr/local/include /opt/local/include"
+ sqlite3_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu /usr/lib64"
+ else
+ sqlite3_hdr_dir="$f_sqlite3_path/include"
+ sqlite3_lib_dir="$f_sqlite3_path/lib"
+ fi
+ if test "$f_sqlite3static" = NO; then
+ sqlite3_lib_name="libsqlite3.so libsqlite3.dylib libsqlite3.a libsqlite3.dll.a"
+ else
+ sqlite3_lib_name="libsqlite3.a"
+ fi
+ sqlite3_hdr=NO
+ sqlite3_lib=NO
+ sqlite3_link=
+ for j in $sqlite3_hdr_dir; do
+ if test -f "$j/sqlite3.h"; then
+ sqlite3_hdr="$j/sqlite3.h"
+ break
+ fi
+ done
+ for i in $sqlite3_lib_dir; do
+ if test "$sqlite3_lib" = NO; then
+ for j in $sqlite3_lib_name; do
+ if test -e "$i/$j"; then
+ if test "$f_sqlite3static" = NO; then
+ sqlite3_lib="$i/$j"
+ sqlite3_link="-L$i -lsqlite3"
+ else
+ sqlite3_lib="$i/$j"
+ sqlite3_link="$i/$j -ldl"
+ fi
+ break
+ fi
+ done
+ fi
+ done
+ if test "$sqlite3_hdr" = NO -o "$sqlite3_lib" = NO; then
+ echo "not found!";
+ exit 1
+ else
+ echo "using header $sqlite3_hdr and library $sqlite3_lib...";
+ fi
+fi
+
+# - check for libclang ---------------------------------------------------------
+
+if test "$f_libclang" = YES; then
+ printf " Checking for libclang ... "
+ libclang_hdr_dir="/usr/include /usr/local/include /opt/local/include"
+ libclang_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib64/llvm /usr/lib/llvm"
+ if test "$f_libclangstatic" = NO; then
+ libclang_lib_name="libclang.so libclang.dylib libclang.a libclang.dll.a"
+ else
+ libclang_lib_name="libclang.a"
+ fi
+ libclang_hdr=NO
+ libclang_lib=NO
+ libclang_link=
+ for j in $libclang_hdr_dir; do
+ if test -f "$j/clang-c/Index.h"; then
+ libclang_hdr="$j/clang-c/Index.h"
+ break
+ fi
+ done
+ for i in $libclang_lib_dir; do
+ if test "$libclang_lib" = NO; then
+ for j in $libclang_lib_name; do
+ if test -f "$i/$j"; then
+ libclang_lib="$i/$j"
+ if test "$f_libclangstatic" = NO; then
+ libclang_link="-L $i -lclang"
+ else
+ libclang_link="$i/libclang.a $i/libclangFrontend.a $i/libclangSerialization.a $i/libclangParse.a $i/libclangSema.a $i/libclangAnalysis.a $i/libclangStaticAnalyzerCore.a $i/libclangAST.a $i/libclangBasic.a $i/libclangDriver.a $i/libclangEdit.a $i/libclangLex.a $i/libclangRewriteCore.a $i/libLLVMBitReader.a $i/libLLVMMC.a $i/libLLVMMCParser.a $i/libLLVMSupport.a -ldl -lpthread"
+ fi
+ break
+ fi
+ done
+ fi
+ done
+ if test "$libclang_hdr" = NO -o "$libclang_lib" = NO; then
+ echo "not found!";
+ else
+ echo "using header $libclang_hdr and library $libclang_lib...";
+ fi
+fi
+
+# - check for python ----------------------------------------------------------
+
+python_version=0
+printf " Checking for python... "
+if test "$f_python" = NO; then
+ python_names="python3 python2 python"
+ python_dirs="$bin_dirs /usr/bin /usr/local/bin /bin /sbin"
+ python_prog=NO
+ python_found=NO
+ for i in $python_names; do
+ for j in $python_dirs; do
+ if test -x "$j/$i"; then
+ python_found=YES
+ if test `$j/$i -c "import sys; print(sys.version_info[0])"` = 3; then
+ python_prog="$j/$i";
+ python_version=`$j/$i -c "import platform; print(platform.python_version())"`;
+ break 2
+ elif test `$j/$i -c "import sys; print(sys.version_info[0])"` = 2; then
+ if test `$j/$i -c "import sys; print(sys.version_info[1])"` -ge 6; then
+ python_prog="$j/$i";
+ python_version=`$j/$i -c "import platform; print(platform.python_version())"`;
+ break 2
+ fi
+ fi
+ fi
+ done
+ done
+ f_python="$python_prog"
+fi
+
+if test "$f_python" = NO; then
+ if test "$python_found" = YES; then
+ echo "version should be python 2.6 or higher."
+ else
+ echo "not found!";
+ fi
+ echo
+ exit 2
+fi
+echo "using $f_python (version $python_version)";
+
+# - check for perl ------------------------------------------------------------
+
+printf " Checking for perl... "
+if test "$f_perl" = NO; then
+ perl_names="perl perl5"
+ perl_dirs="$bin_dirs /usr/bin /usr/local/bin /bin /sbin"
+ perl_prog=NO
+ perl_found=NO
+ for i in $perl_names; do
+ for j in $perl_dirs; do
+ if test -x "$j/$i"; then
+ perl_found=YES
+ if $j/$i -e 'require 5.000;' 2>/dev/null ; then
+ perl_prog="$j/$i"
+ break 2
+ fi
+ fi
+ done
+ done
+ f_perl="$perl_prog"
+fi
+
+if test "$f_perl" = NO; then
+ if test "$perl_found" = YES; then
+ echo "version is too old (5.000 or higher is required)."
+ else
+ echo "not found!";
+ fi
+ echo
+ exit 2
+fi
+echo "using $f_perl";
+
+# - check for flex ------------------------------------------------------------
+
+printf " Checking for flex... "
+if test "$f_flex" = NO; then
+ flex_dirs="$bin_dirs /usr/bin /usr/local/bin /bin"
+ flex_prog=NO
+ flex_found=NO
+ for j in $flex_dirs; do
+ if test -x "$j/flex"; then
+ flex_found=YES
+ flex_prog="$j/flex"
+ break
+ fi
+ done
+ f_flex="$flex_prog"
+fi
+
+if test "$f_flex" = NO; then
+ echo "not found!";
+ exit 2
+else
+ echo "using $f_flex"
+fi
+
+# - check for bison ------------------------------------------------------------
+
+printf " Checking for bison... "
+if test "$f_bison" = NO; then
+ bison_dirs="$bin_dirs /usr/bin /usr/local/bin /bin"
+ bison_prog=NO
+ bison_found=NO
+ for j in $bison_dirs; do
+ if test -x "$j/bison"; then
+ bison_found=YES
+ bison_prog="$j/bison"
+ break
+ fi
+ done
+ f_bison="$bison_prog"
+fi
+
+if test "$f_bison" = NO; then
+ echo "not found!";
+ exit 2
+else
+ echo "using $f_bison"
+fi
+
+# -----------------------------------------------------------------------------
+
+if test '!' -d "generated_src/doxygen"; then
+ mkdir -p generated_src/doxygen
+fi
+if test "$f_wizard" = YES; then
+ if test '!' -d "generated_src/doxywizard"; then
+ mkdir -p generated_src/doxywizard
+ fi
+fi
+
+#
+# Make VERSION file
+#
+test -f "VERSION" && chmod u+w VERSION
+test -f "generated_src/doxygen/version.cpp" && chmod u+w generated_src/doxygen/version.cpp
+echo " Generating generated_src/doxygen/version.cpp and VERSION..."
+cd src
+$f_python version.py ../generated_src/doxygen
+cd ..
+if test "$f_wizard" = YES; then
+ test -f "VERSION" && chmod u+w VERSION
+ test -f "generated_src/doxywizard/version.cpp" && chmod u+w generated_src/doxywizard/version.cpp
+ echo " Generating generated_src/doxywizard/version.cpp and VERSION..."
+ cd src
+ $f_python version.py ../generated_src/doxywizard
+ cd ..
+
+fi
+
+test -f .makeconfig && rm .makeconfig
+test -f .tmakeconfig && rm .tmakeconfig
+
+configPWD=`pwd`
+
+cat > .makeconfig <<EOF
+DOXYGEN = $configPWD
+TMAKEPATH = $configPWD/tmake/lib/$f_platform
+ENV = env TMAKEPATH="\$(TMAKEPATH)"
+TMAKE = $configPWD/tmake/bin/tmake
+MAKE = $f_make
+PYTHON = $f_python
+PERL = $f_perl
+LEX = $f_flex
+RM = rm -f
+CP = cp
+VERSION = `cat VERSION`
+INSTALL = $f_prefix
+INSTTOOL = $f_insttool
+DOXYDOCS = ..
+DOCDIR = $f_docdir
+QTDIR = $QTDIR
+EOF
+
+if test "$f_dot" != NO; then
+ cat >> .makeconfig <<EOF
+HAVE_DOT = $f_dot
+EOF
+fi
+
+
+if test "$f_platform" = "m68k-atari-mint-g++"; then
+ cat >> .makeconfig <<EOF
+TMAKE += -unix
+EOF
+fi
+
+if test "$f_platform" = "macosx-c++"; then
+ cat >> .makeconfig <<EOF
+MKSPECS = -spec macx-g++
+EOF
+fi
+if test "$f_platform" = "macosx-uni-c++"; then
+ cat >> .makeconfig <<EOF
+MKSPECS = -spec macx-g++
+EOF
+fi
+
+# Make doxygen.spec...
+#
+echo " Created doxygen.spec file, for rpm generation."
+
+echo "%define version $doxygen_version_major.$doxygen_version_minor.$doxygen_version_revision" > spec.tmp
+if test "$doxygen_version_mmn" = NO; then
+ echo "%define revision 1" >> spec.tmp
+ echo "%define mmn 1" >> spec.tmp
+else
+ echo "%define revision $doxygen_version_mmn" >> spec.tmp
+ echo "%define mmn $doxygen_version_mmn" >> spec.tmp
+fi
+
+mkdir -p packages
+mkdir -p packages/rpm
+
+cat spec.tmp ./packages/rpm/doxygen.spec.in > ./packages/rpm/doxygen.spec
+
+rm -f spec.tmp
+
+
+# make .tmakeconfig
+#
+touch .tmakeconfig
+if test "$f_shared" = NO; then
+ if test "$f_platform" = "osf1-cxx" -o "$f_platform" = "irix-n32"; then
+ cat >> .tmakeconfig <<EOF
+ TMAKE_LFLAGS += -non_shared
+EOF
+ elif test "$f_platform" = "solaris-cc"; then
+ cat >> .tmakeconfig <<EOF
+ TMAKE_LFLAGS += -Bstatic
+EOF
+ elif test "$f_platform" = "hpux-cc"; then
+ cat >> .tmakeconfig <<EOF
+ TMAKE_LFLAGS += -noshared
+EOF
+ else
+ cat >> .tmakeconfig <<EOF
+ TMAKE_LFLAGS += -static
+EOF
+ fi
+fi
+if test "$f_platform" = "hpux-g++" -o "$f_platform" = "linux-g++"; then
+ cat >> .tmakeconfig <<EOF
+ TMAKE_CXXFLAGS += -D_LARGEFILE_SOURCE
+EOF
+fi
+if test "$f_platform" = "macosx-uni-c++"; then
+ if test -n "`ls /Developer/SDKs/MacOSX10.*.sdk 2>/dev/null`"; then
+ mac_sdk=MacOSX10.4u.sdk
+ fi
+ if test -n "`ls /Developer/SDKs/MacOSX10.5*.sdk 2>/dev/null`"; then
+ mac_sdk=MacOSX10.5.sdk
+ fi
+ if test -n $mac_sdk; then
+ cat >> .tmakeconfig <<EOF
+ TMAKE_CFLAGS += -isysroot /Developer/SDKs/$mac_sdk
+ TMAKE_CXXFLAGS += -isysroot /Developer/SDKs/$mac_sdk
+ TMAKE_LFLAGS += -Wl,-syslibroot,/Developer/SDKs/$mac_sdk
+EOF
+ fi
+fi
+if test "$f_wizard" = YES; then
+ cat >> .tmakeconfig <<EOF
+TMAKE_MOC = $QTDIR/bin/moc
+EOF
+fi
+
+if test "$f_search" = YES; then
+ cat >> .tmakeconfig <<EOF
+LIBS += -L$XAPIAN/lib
+INCLUDEPATH += $XAPIAN/include
+EOF
+fi
+
+f_inmakefiles="Makefile.in qtools/Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in addon/doxywizard/Makefile.in addon/doxmlparser/src/Makefile.in addon/doxmlparser/test/Makefile.in addon/doxmlparser/examples/metrics/Makefile.in libmd5/Makefile.in addon/doxyapp/Makefile.in addon/doxysearch/Makefile.in vhdlparser/Makefile.in"
+
+for i in $f_inmakefiles ; do
+ SRC=$i
+ DST=`echo $i|sed 's%\(.*\).in$%\1%'`
+ TIME=`date`
+ cat > $DST <<EOF
+#
+# This file was generated from `basename $i` on $TIME
+#
+
+EOF
+ cat .makeconfig >> $DST
+ if test $i = Makefile.in; then
+ echo "" >> $DST
+ EXTRADEPS=
+ if test $f_wizard = YES; then
+ EXTRADEPS=doxywizard
+ fi
+# if test $f_search = YES; then
+# EXTRADEPS="$EXTRADEPS doxysearch"
+# fi
+ echo "all: generated_src/doxygen/version.cpp $EXTRADEPS" >> $DST
+ echo " \$(MAKE) -C qtools" >> $DST
+ echo " \$(MAKE) -C libmd5" >> $DST
+ echo " \$(MAKE) -C vhdlparser" >> $DST
+ echo " \$(MAKE) -C src" >> $DST
+
+ if test $f_wizard = YES; then
+ echo " \$(MAKE) MAN1DIR=\$(MAN1DIR) -C addon/doxywizard" >> $DST
+ fi
+ if test $f_search = YES; then
+ echo " \$(MAKE) -C addon/doxysearch" >> $DST
+ fi
+ if test $f_app = YES; then
+ echo " \$(MAKE) -C addon/doxyapp" >> $DST
+ fi
+ if test $f_doxmlparser = YES; then
+ echo " \$(MAKE) -C addon/doxmlparser/src" >> $DST
+ echo " \$(MAKE) -C addon/doxmlparser/test" >> $DST
+ echo " \$(MAKE) -C addon/doxmlparser/examples/metrics" >> $DST
+ fi
+ echo "" >> $DST
+ echo "doxywizard_install:" >> $DST
+ if test $f_wizard = YES; then
+ echo " \$(MAKE) INSTALL=\$(DESTDIR)\$(INSTALL) MAN1DIR=\$(MAN1DIR) -C addon/doxywizard install" >> $DST
+ fi
+ echo "doxysearch_install:" >> $DST
+ if test $f_search = YES; then
+ echo " \$(MAKE) INSTALL=\$(DESTDIR)\$(INSTALL) MAN1DIR=\$(MAN1DIR) -C addon/doxysearch install" >> $DST
+ fi
+ echo "" >> $DST
+ fi
+ if test $f_wizard = YES; then
+ sed -e "s/%%WITHDOXYWIZARD%% /--with doxywizard /g" $SRC >> $DST
+ else
+ sed -e "s/%%WITHDOXYWIZARD%% //g" $SRC >> $DST
+ fi
+ echo " Created $DST from $SRC..."
+done
+
+cat src/libdoxycfg.t.in | sed -e "s|%%FLEX%%|$f_flex|g" -e "s|%%BISON%%|$f_bison|g" -e "s|%%PYTHON%%|$f_python|g" > src/libdoxycfg.t
+cat src/libdoxygen.t.in | sed -e "s|%%FLEX%%|$f_flex|g" -e "s|%%BISON%%|$f_bison|g" -e "s|%%PYTHON%%|$f_python|g" > src/libdoxygen.t
+
+f_inprofiles="qtools/qtools.pro.in src/libdoxygen.pro.in src/libdoxycfg.pro.in src/doxygen.pro.in addon/doxywizard/doxywizard.pro.in addon/doxmlparser/src/doxmlparser.pro.in addon/doxmlparser/test/xmlparse.pro.in addon/doxmlparser/examples/metrics/metrics.pro.in libmd5/libmd5.pro.in addon/doxyapp/doxyapp.pro.in addon/doxysearch/doxysearch.pro.in addon/doxysearch/doxyindexer.pro.in vhdlparser/vhdlparser.pro.in"
+
+for i in $f_inprofiles ; do
+ SRC=$i
+ DST=`echo $i|sed 's%\(.*\).in$%\1%'`
+ TIME=`date`
+ cat > $DST <<EOF
+#
+# This file was generated from `basename $i` on $TIME
+#
+
+EOF
+ if test "$f_debug" = NO; then
+ realopts="release"
+ else
+ realopts="debug"
+ fi
+ #if test "$f_thread" = YES; then
+ # realopts="$realopts thread"
+ #fi
+ cat $SRC .tmakeconfig | sed -e "s/\$extraopts/$realopts/g" -e "s;%%SQLITE3_INC%%;$sqlite3_hdr_dir;g" -e "s;%%SQLITE3_LIBS%%;$sqlite3_link;g" -e "s;%%LIBCLANG_LIBS%%;$libclang_link;g" >> $DST
+ echo " Created $DST from $SRC..."
+done
+
+# - generating generated_src/doxygen/doxygen/lang_cfg.h
+# use consistent method on Linux and Windows
+
+if test -f "generated_src/doxygen/lang_cfg.h"; then
+ chmod u+w generated_src/doxygen/lang_cfg.h # make sure file can be overwritten
+fi
+echo " Generating generated_src/doxygen/lang_cfg.h..."
+if test "$f_english" = YES; then
+ $f_python src/lang_cfg.py ENONLY > generated_src/doxygen/lang_cfg.h
+else
+ f_ulangs=`echo $f_langs | tr '[a-z]' '[A-Z]' | tr ',' ' '`
+ $f_python src/lang_cfg.py $f_ulangs > generated_src/doxygen/lang_cfg.h
+fi
+
+if test -f "generated_src/doxygen/settings.h"; then
+ chmod u+w generated_src/doxygen/settings.h
+fi
+echo " Generating generated_src/doxygen/settings.h..."
+$f_python src/settings.py $f_sqlite3 $f_libclang generated_src/doxygen
+
+if test "$f_wizard" = YES; then
+ if test -f "generated_src/doxywizard/settings.h"; then
+ chmod u+w generated_src/doxywizard/settings.h
+ fi
+ echo " Generating generated_src/doxywizard/settings.h..."
+ $f_python src/settings.py $f_sqlite3 $f_libclang generated_src/doxywizard
+fi
+
+cd ..
+echo " Finished"
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..a464770
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1 @@
+mailto.txt
\ No newline at end of file
diff --git a/doc/Doxyfile b/doc/Doxyfile
new file mode 100644
index 0000000..c57bbe9
--- /dev/null
+++ b/doc/Doxyfile
@@ -0,0 +1,55 @@
+#
+#
+#
+# Copyright (C) 1997-1999 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+PROJECT_NAME = "Doxygen"
+OUTPUT_DIRECTORY = ..
+HTML_HEADER =
+HTML_FOOTER =
+QUIET = NO
+WARNINGS = YES
+DISABLE_INDEX = YES
+GENERATE_TREEVIEW = YES
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+GENERATE_MAN = NO
+GENERATE_LATEX = YES
+GENERATE_HTML = YES
+GENERATE_HTMLHELP = NO
+GENERATE_RTF = NO
+GENERATE_XML = NO
+HTML_COLORSTYLE_SAT = 0
+ENABLED_SECTIONS = logo_on
+ENABLE_PREPROCESSING = NO
+CASE_SENSE_NAMES = NO
+IMAGE_PATH = .
+INPUT = index.doc install.doc starting.doc docblocks.doc markdown.doc \
+ lists.doc grouping.doc formulas.doc diagrams.doc preprocessing.doc \
+ autolink.doc output.doc searching.doc extsearch.doc customize.doc custcmd.doc \
+ external.doc faq.doc trouble.doc features.doc \
+ doxygen_usage.doc doxywizard_usage.doc \
+ config.doc commands.doc htmlcmds.doc xmlcmds.doc language.doc \
+ perlmod.doc perlmod_tree.doc arch.doc changelog.doc
+FILE_PATTERNS = *.cpp *.h *.doc
+EXAMPLE_PATH = ../examples
+RECURSIVE = NO
+TAGFILES =
+ALLEXTERNALS = NO
+PERL_PATH = /usr/bin/perl
+SEARCHENGINE = NO
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+STRIP_CODE_COMMENTS = NO
+HTML_STYLESHEET = doxygen_manual.css
+ALIASES = LaTeX="\f$\mbox{\LaTeX}\f$"
+ALIASES += TeX="\f$\mbox{\TeX}\f$"
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..febba65
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,61 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+all: language config.doc FORCE
+ DOXYGEN_DOCDIR=$(DOXYDOCS); \
+ export DOXYGEN_DOCDIR; \
+ VERSION=$(VERSION) ; \
+ export VERSION; \
+ "$(DOXYGEN)/bin/doxygen"
+ @rm -f ../latex/refman.tex
+ @cp doxygen_logo*.gif ../html
+ @cp Makefile.latex ../latex/Makefile
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >../latex/doxygen_manual.tex
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >../latex/doxygen.sty
+ @epstopdf doxygen_logo.eps --outfile=../latex/doxygen_logo.pdf
+
+clean:
+ rm -rf ../html ../latex *.bak
+
+language: language.doc
+
+language.doc: $(wildcard ../src/translator*.h) maintainers.txt language.tpl translator.py
+ $(PYTHON) translator.py
+
+config.doc: ../src/config.xml ../src/configgen.py
+ $(PYTHON) ../src/configgen.py -doc ../src/config.xml > config.doc
+
+FORCE:
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..f0c3a03
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,39 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+all: language config.doc FORCE
+ DOXYGEN_DOCDIR=$(DOXYDOCS); \
+ export DOXYGEN_DOCDIR; \
+ VERSION=$(VERSION) ; \
+ export VERSION; \
+ "$(DOXYGEN)/bin/doxygen"
+ @rm -f ../latex/refman.tex
+ @cp doxygen_logo*.gif ../html
+ @cp Makefile.latex ../latex/Makefile
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >../latex/doxygen_manual.tex
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >../latex/doxygen.sty
+ @epstopdf doxygen_logo.eps --outfile=../latex/doxygen_logo.pdf
+
+clean:
+ rm -rf ../html ../latex *.bak
+
+language: language.doc
+
+language.doc: $(wildcard ../src/translator*.h) maintainers.txt language.tpl translator.py
+ $(PYTHON) translator.py
+
+config.doc: ../src/config.xml ../src/configgen.py
+ $(PYTHON) ../src/configgen.py -doc ../src/config.xml > config.doc
+
+FORCE:
diff --git a/doc/Makefile.latex b/doc/Makefile.latex
new file mode 100644
index 0000000..803b75d
--- /dev/null
+++ b/doc/Makefile.latex
@@ -0,0 +1,25 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+all: doxygen_manual.pdf
+
+doxygen_manual.pdf: doxygen_manual.tex doxygen.sty
+ echo "Running latex..."
+ pdflatex doxygen_manual.tex
+ echo "Running makeindex..."
+ makeindex doxygen_manual.idx
+ echo "Rerunning latex...."
+ pdflatex doxygen_manual.tex
+clean:
+ rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log doxygen_manual.pdf
diff --git a/doc/Makefile.win_make.in b/doc/Makefile.win_make.in
new file mode 100644
index 0000000..1d22dbf
--- /dev/null
+++ b/doc/Makefile.win_make.in
@@ -0,0 +1,40 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+all: language config.doc FORCE
+ @xcopy /s /q /i ..\examples ..\html\examples
+ set DOXYGEN_DOCDIR=. & \
+ set VERSION=$(VERSION) & \
+ $(DOXYGEN)\bin\doxygen
+ @del ..\latex\refman.tex
+ @copy doxygen_logo*.gif ..\html
+ @copy Makefile.latex ..\latex\Makefile
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >..\latex\doxygen_manual.tex
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >..\latex\doxygen.sty
+ @epstopdf doxygen_logo.eps --outfile=..\latex\doxygen_logo.pdf
+
+clean:
+ del /s /q ..\html ..\latex
+ del translator_report.txt *.bak
+
+language: language.doc
+
+language.doc: maintainers.txt language.tpl translator.py
+ set DOXYGEN_DOCDIR=. & set VERSION=$(VERSION) & python translator.py
+
+config.doc: ..\src\config.xml ..\src\configgen.py
+ python ..\src\configgen.py -doc ..\src\config.xml > config.doc
+
+
+FORCE:
diff --git a/doc/Makefile.win_nmake.in b/doc/Makefile.win_nmake.in
new file mode 100644
index 0000000..99ac2f1
--- /dev/null
+++ b/doc/Makefile.win_nmake.in
@@ -0,0 +1,41 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+all: language config.doc FORCE
+ @xcopy /s /q /i ..\examples ..\html\examples
+ set DOXYGEN_DOCDIR=.
+ set VERSION=$(VERSION)
+ $(DOXYGEN)\bin\doxygen
+ @del ..\latex\refman.tex
+ @copy doxygen_logo*.gif ..\html
+ @copy Makefile.latex ..\latex\Makefile
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >..\latex\doxygen_manual.tex
+ @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >..\latex\doxygen.sty
+ @epstopdf doxygen_logo.eps --outfile=..\latex\doxygen_logo.pdf
+
+clean:
+ del /s /q ..\html ..\latex
+ del translator_report.txt *.bak
+
+language: language.doc
+
+language.doc: maintainers.txt language.tpl translator.py
+ set DOXYGEN_DOCDIR=.
+ set VERSION=$(VERSION)
+ python translator.py
+
+config.doc: ../src/config.xml ../src/configgen.py
+ python ../src/configgen.py -doc ../src/config.xml > config.doc
+
+FORCE:
diff --git a/doc/arch.doc b/doc/arch.doc
new file mode 100644
index 0000000..fc80659
--- /dev/null
+++ b/doc/arch.doc
@@ -0,0 +1,259 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page arch Doxygen's Internals
+
+<h3>Doxygen's internals</h3>
+
+<B>Note that this section is still under construction!</B>
+
+The following picture shows how source files are processed by doxygen.
+
+\image html archoverview.gif "Data flow overview"
+\image latex archoverview.eps "Data flow overview" width=14cm
+
+The following sections explain the steps above in more detail.
+
+<h3>Config parser</h3>
+
+The configuration file that controls the settings of a project is parsed
+and the settings are stored in the singleton class \c Config
+in <code>src/config.h</code>. The parser itself is written using \c flex
+and can be found in <code>src/config.l</code>. This parser is also used
+directly by \c doxywizard, so it is put in a separate library.
+
+Each configuration option has one of 5 possible types: \c String,
+\c List, \c Enum, \c Int, or \c Bool. The values of these options are
+available through the global functions \c Config_getXXX(), where \c XXX is the
+type of the option. The argument of these function is a string naming
+the option as it appears in the configuration file. For instance:
+\c Config_getBool("GENERATE_TESTLIST") returns a reference to a boolean
+value that is \c TRUE if the test list was enabled in the config file.
+
+The function \c readConfiguration() in \c src/doxygen.cpp
+reads the command line options and then calls the configuration parser.
+
+<h3>C Preprocessor</h3>
+
+The input files mentioned in the config file are (by default) fed to the
+C Preprocessor (after being piped through a user defined filter if available).
+
+The way the preprocessor works differs somewhat from a standard C Preprocessor.
+By default it does not do macro expansion, although it can be configured to
+expand all macros. Typical usage is to only expand a user specified set
+of macros. This is to allow macro names to appear in the type of
+function parameters for instance.
+
+Another difference is that the preprocessor parses, but not actually includes
+code when it encounters a \c \#include (with the exception of \c \#include
+found inside { ... } blocks). The reasons behind this deviation from
+the standard is to prevent feeding multiple definitions of the
+same functions/classes to doxygen's parser. If all source files would
+include a common header file for instance, the class and type
+definitions (and their documentation) would be present in each
+translation unit.
+
+The preprocessor is written using \c flex and can be found in
+\c src/pre.l. For condition blocks (\c \#if) evaluation of constant expressions
+is needed. For this a \c yacc based parser is used, which can be found
+in \c src/constexp.y and \c src/constexp.l.
+
+The preprocessor is invoked for each file using the \c preprocessFile()
+function declared in \c src/pre.h, and will append the preprocessed result
+to a character buffer. The format of the character buffer is
+
+\verbatim
+0x06 file name 1
+0x06 preprocessed contents of file 1
+...
+0x06 file name n
+0x06 preprocessed contents of file n
+\endverbatim
+
+<h3>Language parser</h3>
+
+The preprocessed input buffer is fed to the language parser, which is
+implemented as a big state machine using \c flex. It can be found
+in the file \c src/scanner.l. There is one parser for all
+languages (C/C++/Java/IDL). The state variables \c insideIDL
+and \c insideJava are uses at some places for language specific choices.
+
+The task of the parser is to convert the input buffer into a tree of entries
+(basically an abstract syntax tree). An entry is defined in \c src/entry.h
+and is a blob of loosely structured information. The most important field
+is \c section which specifies the kind of information contained in the entry.
+
+Possible improvements for future versions:
+ - Use one scanner/parser per language instead of one big scanner.
+ - Move the first pass parsing of documentation blocks to a separate module.
+ - Parse defines (these are currently gathered by the preprocessor, and
+ ignored by the language parser).
+
+<h3>Data organizer</h3>
+
+This step consists of many smaller steps, that build
+dictionaries of the extracted classes, files, namespaces,
+variables, functions, packages, pages, and groups. Besides building
+dictionaries, during this step relations (such as inheritance relations),
+between the extracted entities are computed.
+
+Each step has a function defined in \c src/doxygen.cpp, which operates
+on the tree of entries, built during language parsing. Look at the
+"Gathering information" part of \c parseInput() for details.
+
+The result of this step is a number of dictionaries, which can be
+found in the Doxygen "namespace" defined in \c src/doxygen.h. Most
+elements of these dictionaries are derived from the class \c Definition;
+The class \c MemberDef, for instance, holds all information for a member.
+An instance of such a class can be part of a file ( class \c FileDef ),
+a class ( class \c ClassDef ), a namespace ( class \c NamespaceDef ),
+a group ( class \c GroupDef ), or a Java package ( class \c PackageDef ).
+
+<h3>Tag file parser</h3>
+
+If tag files are specified in the configuration file, these are parsed
+by a SAX based XML parser, which can be found in \c src/tagreader.cpp.
+The result of parsing a tag file is the insertion of \c Entry objects in the
+entry tree. The field \c Entry::tagInfo is used to mark the entry as
+external, and holds information about the tag file.
+
+<h3>Documentation parser</h3>
+
+Special comment blocks are stored as strings in the entities that they
+document. There is a string for the brief description and a string
+for the detailed description. The documentation parser reads these
+strings and executes the commands it finds in it (this is the second pass
+in parsing the documentation). It writes the result directly to the output
+generators.
+
+The parser is written in C++ and can be found in src/docparser.cpp. The
+tokens that are eaten by the parser come from src/doctokenizer.l.
+Code fragments found in the comment blocks are passed on to the source parser.
+
+The main entry point for the documentation parser is \c validatingParseDoc()
+declared in \c src/docparser.h. For simple texts with special
+commands \c validatingParseText() is used.
+
+<h3>Source parser</h3>
+
+If source browsing is enabled or if code fragments are encountered in the
+documentation, the source parser is invoked.
+
+The code parser tries to cross-reference to source code it parses with
+documented entities. It also does syntax highlighting of the sources. The
+output is directly written to the output generators.
+
+The main entry point for the code parser is \c parseCode()
+declared in \c src/code.h.
+
+<h3>Output generators</h3>
+
+After data is gathered and cross-referenced, doxygen generates
+output in various formats. For this it uses the methods provided by
+the abstract class \c OutputGenerator. In order to generate output
+for multiple formats at once, the methods of \c OutputList are called
+instead. This class maintains a list of concrete output generators,
+where each method called is delegated to all generators in the list.
+
+To allow small deviations in what is written to the output for each
+concrete output generator, it is possible to temporarily disable certain
+generators. The OutputList class contains various \c disable() and \c enable()
+methods for this. The methods \c OutputList::pushGeneratorState() and
+\c OutputList::popGeneratorState() are used to temporarily save the
+set of enabled/disabled output generators on a stack.
+
+The XML is generated directly from the gathered data structures. In the
+future XML will be used as an intermediate language (IL). The output
+generators will then use this IL as a starting point to generate the
+specific output formats. The advantage of having an IL is that various
+independently developed tools written in various languages,
+could extract information from the XML output. Possible tools could be:
+- an interactive source browser
+- a class diagram generator
+- computing code metrics.
+
+<h3>Debugging</h3>
+
+Since doxygen uses a lot of \c flex code it is important to understand
+how \c flex works (for this one should read the man page)
+and to understand what it is doing when \c flex is parsing some input.
+Fortunately, when flex is used with the `-d` option it outputs what rules
+matched. This makes it quite easy to follow what is going on for a
+particular input fragment.
+
+To make it easier to toggle debug information for a given flex file I
+wrote the following perl script, which automatically adds or removes `-d`
+from the correct line in the \c Makefile:
+
+\verbatim
+#!/usr/bin/perl
+
+$file = shift @ARGV;
+print "Toggle debugging mode for $file\n";
+
+# add or remove the -d flex flag in the makefile
+unless (rename "Makefile.libdoxygen","Makefile.libdoxygen.old") {
+ print STDERR "Error: cannot rename Makefile.libdoxygen!\n";
+ exit 1;
+}
+if (open(F,"<Makefile.libdoxygen.old")) {
+ unless (open(G,">Makefile.libdoxygen")) {
+ print STDERR "Error: opening file Makefile.libdoxygen for writing\n";
+ exit 1;
+ }
+ print "Processing Makefile.libdoxygen...\n";
+ while (<F>) {
+ if ( s/\(LEX\) (-i )?-P([a-zA-Z]+)YY -t $file/(LEX) -d \1-P\2YY -t $file/g ) {
+ print "Enabling debug info for $file\n";
+ }
+ elsif ( s/\(LEX\) -d (-i )?-P([a-zA-Z]+)YY -t $file/(LEX) \1-P\2YY -t $file/g ) {
+ print "Disabling debug info for $file\n";
+ }
+ print G "$_";
+ }
+ close F;
+ unlink "Makefile.libdoxygen.old";
+}
+else {
+ print STDERR "Warning file Makefile.libdoxygen.old does not exist!\n";
+}
+
+# touch the file
+$now = time;
+utime $now, $now, $file
+
+\endverbatim
+Another way to get rules matching / debugging information from the flex code is in the following way:
+\verbatim
+touch src/<flex code file>.l
+make LEX="flex -d"
+\endverbatim
+to remove the rules / debug information again:
+\verbatim
+touch src/<flex codefile>.l
+make
+\endverbatim
+
+Note that by running doxygen with `-d lex` you get information about which flex
+codefile is used.
+
+\htmlonly
+Return to the <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
+
diff --git a/doc/archoverview.eps b/doc/archoverview.eps
new file mode 100644
index 0000000..b41d36c
--- /dev/null
+++ b/doc/archoverview.eps
@@ -0,0 +1,380 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: archoverview.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 1
+%%CreationDate: Sat Sep 8 19:41:40 2001
+%%For: root at blizzard (root)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 733 511
+%%Pages: 0
+%%BeginSetup
+%%EndSetup
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-31.0 537.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n -1000 9949 m -1000 -1000 l 13719 -1000 l 13719 9949 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 4425 1725 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 5100 4200 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 10500 4275 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 2402 4198 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 7863 8104 837 837 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 5113 6622 887 887 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 9375 6450 837 837 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 7800 4200 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Polyline
+gs clippath
+1380 4170 m 1500 4200 l 1380 4230 l 1515 4230 l 1515 4170 l cp
+clip
+n 600 4200 m 1500 4200 l gs col0 s gr gr
+
+% arrowhead
+n 1380 4170 m 1500 4200 l 1380 4230 l 1380 4200 l 1380 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4080 4170 m 4200 4200 l 4080 4230 l 4215 4230 l 4215 4170 l cp
+clip
+n 3300 4200 m 4200 4200 l gs col0 s gr gr
+
+% arrowhead
+n 4080 4170 m 4200 4200 l 4080 4230 l 4080 4200 l 4080 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+9480 4170 m 9600 4200 l 9480 4230 l 9615 4230 l 9615 4170 l cp
+clip
+n 8700 4200 m 9600 4200 l gs col0 s gr gr
+
+% arrowhead
+n 9480 4170 m 9600 4200 l 9480 4230 l 9480 4200 l 9480 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11881 3482 m 12000 3450 l 11910 3535 l 12028 3469 l 11999 3416 l cp
+clip
+n 11325 3825 m 12000 3450 l gs col0 s gr gr
+
+% arrowhead
+n 11881 3482 m 12000 3450 l 11910 3535 l 11895 3508 l 11881 3482 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11876 4050 m 12000 4050 l 11891 4108 l 12022 4075 l 12007 4017 l cp
+clip
+n 11400 4200 m 12000 4050 l gs col0 s gr gr
+
+% arrowhead
+n 11876 4050 m 12000 4050 l 11891 4108 l 11884 4079 l 11876 4050 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11900 5028 m 12000 5100 l 11877 5083 l 12003 5133 l 12025 5078 l cp
+clip
+n 11250 4800 m 12000 5100 l gs col0 s gr gr
+
+% arrowhead
+n 11900 5028 m 12000 5100 l 11877 5083 l 11889 5055 l 11900 5028 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11891 4517 m 12000 4575 l 11876 4575 l 12007 4608 l 12022 4550 l cp
+clip
+n 11400 4425 m 12000 4575 l gs col0 s gr gr
+
+% arrowhead
+n 11891 4517 m 12000 4575 l 11876 4575 l 11884 4546 l 11891 4517 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11880 2820 m 12000 2850 l 11880 2880 l 12015 2880 l 12015 2820 l cp
+clip
+n 7800 3300 m 7800 2850 l 12000 2850 l gs col0 s gr gr
+
+% arrowhead
+n 11880 2820 m 12000 2850 l 11880 2880 l 11880 2850 l 11880 2820 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10470 5295 m 10500 5175 l 10530 5295 l 10530 5160 l 10470 5160 l cp
+clip
+n 8700 8100 m 10500 8100 l 10500 5175 l gs col0 s gr gr
+
+% arrowhead
+n 10470 5295 m 10500 5175 l 10530 5295 l 10500 5295 l 10470 5295 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4455 705 m 4425 825 l 4395 705 l 4395 840 l 4455 840 l cp
+clip
+n 4425 450 m 4425 825 l gs col0 s gr gr
+
+% arrowhead
+n 4455 705 m 4425 825 l 4395 705 l 4425 705 l 4455 705 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+3405 1695 m 3525 1725 l 3405 1755 l 3540 1755 l 3540 1695 l cp
+clip
+n 3525 1725 m 2400 1725 l 2400 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 3405 1695 m 3525 1725 l 3405 1755 l 3405 1725 l 3405 1695 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+5445 1680 m 5325 1650 l 5445 1620 l 5310 1620 l 5310 1680 l cp
+clip
+n 5325 1650 m 7575 1650 l 7575 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5445 1680 m 5325 1650 l 5445 1620 l 5445 1650 l 5445 1680 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+4845 2670 m 4875 2550 l 4905 2670 l 4905 2535 l 4845 2535 l cp
+clip
+n 4875 2550 m 4875 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4845 2670 m 4875 2550 l 4905 2670 l 4875 2670 l 4845 2670 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 7575 1650 m 10500 1650 l 10500 3375 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+6930 8070 m 7050 8100 l 6930 8130 l 7065 8130 l 7065 8070 l cp
+clip
+n 2400 5100 m 2400 8100 l 7050 8100 l gs col0 s gr gr
+
+% arrowhead
+n 6930 8070 m 7050 8100 l 6930 8130 l 6930 8100 l 6930 8070 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6780 4170 m 6900 4200 l 6780 4230 l 6915 4230 l 6915 4170 l cp
+clip
+n 6000 4200 m 6900 4200 l gs col0 s gr gr
+
+% arrowhead
+n 6780 4170 m 6900 4200 l 6780 4230 l 6780 4200 l 6780 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7090 4932 m 7200 4875 l 7130 4977 l 7231 4887 l 7191 4843 l cp
+clip
+n 5850 6075 m 7200 4875 l gs col0 s gr gr
+
+% arrowhead
+n 7090 4932 m 7200 4875 l 7130 4977 l 7110 4955 l 7090 4932 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7830 7155 m 7800 7275 l 7770 7155 l 7770 7290 l 7830 7290 l cp
+clip
+n 7800 7275 m 7800 5100 l gs col0 s gr gr
+
+% arrowhead
+n 7830 7155 m 7800 7275 l 7770 7155 l 7800 7155 l 7830 7155 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8886 5583 m 8925 5700 l 8835 5615 l 8908 5729 l 8958 5697 l cp
+clip
+n 8400 4875 m 8925 5700 l gs col0 s gr gr
+
+% arrowhead
+n 8886 5583 m 8925 5700 l 8835 5615 l 8861 5599 l 8886 5583 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8575 7427 m 8475 7500 l 8529 7389 l 8442 7492 l 8488 7531 l cp
+clip
+n 8850 7050 m 8475 7500 l gs col0 s gr gr
+
+% arrowhead
+n 8575 7427 m 8475 7500 l 8529 7389 l 8552 7408 l 8575 7427 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10106 5255 m 10200 5175 l 10155 5290 l 10233 5180 l 10184 5145 l cp
+clip
+n 9825 5700 m 10200 5175 l gs col0 s gr gr
+
+% arrowhead
+n 10106 5255 m 10200 5175 l 10155 5290 l 10130 5273 l 10106 5255 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+3900 1725 m
+gs 1 -1 sc (Config parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4425 4275 m
+gs 1 -1 sc (Language parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1725 4275 m
+gs 1 -1 sc (C Preprocessor) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 3525 m
+gs 1 -1 sc (HTML) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 4125 m
+gs 1 -1 sc (LaTeX) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 4650 m
+gs 1 -1 sc (RTF) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 2925 m
+gs 1 -1 sc (XML) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3450 4500 m
+gs 1 -1 sc (input) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3450 4725 m
+gs 1 -1 sc (string) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6150 4500 m
+gs 1 -1 sc (entry) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6150 4725 m
+gs 1 -1 sc (tree) col0 sh gr
+/Helvetica ff 180.00 scf sf
+525 3975 m
+gs 1 -1 sc (input files) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 5175 m
+gs 1 -1 sc (Man) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4650 750 m
+gs 1 -1 sc (config file) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7950 5475 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8850 4050 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2475 3150 m
+gs 1 -1 sc (get settings) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6675 5550 m
+gs 1 -1 sc (entry) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6675 5775 m
+gs 1 -1 sc (tree) col0 sh gr
+/Helvetica ff 180.00 scf sf
+9525 5325 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8700 7500 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4575 6675 m
+gs 1 -1 sc (tag file parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8925 6525 m
+gs 1 -1 sc (Doc Parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7275 8175 m
+gs 1 -1 sc (Source Parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7200 4275 m
+gs 1 -1 sc (Data organiser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+9750 4275 m
+gs 1 -1 sc (Output generators) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8775 8325 m
+gs 1 -1 sc (drives) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/archoverview.gif b/doc/archoverview.gif
new file mode 100644
index 0000000..f404076
Binary files /dev/null and b/doc/archoverview.gif differ
diff --git a/doc/autolink.doc b/doc/autolink.doc
new file mode 100644
index 0000000..b872f7d
--- /dev/null
+++ b/doc/autolink.doc
@@ -0,0 +1,140 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page autolink Automatic link generation
+
+ \tableofcontents
+
+ Most documentation systems have special `see also' sections where links
+ to other pieces of documentation can be inserted.
+ Although doxygen also has a command to start such a section (See section
+ \ref cmdsa "\\sa"), it does allow you to put these kind of links anywhere in the
+ documentation.
+ For \LaTeX documentation a reference to the page number
+ is written instead of a link. Furthermore, the index at the end of the
+ document can be used to quickly find the documentation of a member, class,
+ namespace or file.
+ For man pages no reference information is generated.
+
+ The next sections show how to generate links to the various documented
+ entities in a source file.
+
+ \section linkurl Links to web pages and mail addresses
+
+ Doxygen will automatically replace any URLs and mail addresses found in the
+ documentation by links (in HTML). To manually specify link text, use the
+ HTML '<tt>a</tt>' tag:
+ \verbatim <a href="linkURL">link text</a> \endverbatim
+ which will be automatically translated to other output formats by Doxygen.
+
+ \section linkclass Links to classes
+
+ All words in the documentation that correspond to a documented class and
+ contain at least one non-lower case character will automatically be
+ replaced by a link to the page containing the
+ documentation of the class. If you want to prevent that a word
+ that corresponds to a documented class is replaced by a link you
+ should put a \% in front of the word.
+ To link to an all lower case symbol, use \ref cmdref "\\ref".
+
+ \section linkfile Links to files
+
+ All words that contain a dot (<tt>.</tt>) that is not the last character
+ in the word are considered to be file names.
+ If the word is indeed the name of a documented input file, a link will
+ automatically be created to the documentation of that file.
+
+ \section linkfunc Links to functions
+
+ Links to functions are created if one of the following patterns is
+ encountered:
+ <ol>
+ <li><tt>\<functionName\>"("\<argument-list\>")"</tt>
+ <li><tt>\<functionName\>"()"</tt>
+ <li><tt>"::"\<functionName\></tt>
+ <li><tt>(\<className\>"::")<sup>n</sup>\<functionName\>"("\<argument-list\>")"</tt>
+ <li><tt>(\<className\>"::")<sup>n</sup>\<functionName\>"("\<argument-list\>")"\<modifiers\></tt>
+ <li><tt>(\<className\>"::")<sup>n</sup>\<functionName\>"()"</tt>
+ <li><tt>(\<className\>"::")<sup>n</sup>\<functionName\></tt>
+ </ol>
+ where n\>0.
+
+ \par Note 1:
+ Function arguments should be specified with correct types, i.e.
+ 'fun(const std::string&,bool)' or '()' to match any prototype.
+ \par Note 2:
+ Member function modifiers (like 'const' and 'volatile')
+ are required to identify the target, i.e. 'func(int) const' and 'fun(int)'
+ target different member functions.
+ \par Note 3:
+ For JavaDoc compatibility a \# may be used instead of a :: in
+ the patterns above.
+ \par Note 4:
+ In the documentation of a class containing a member foo,
+ a reference to a global variable is made using "::foo", whereas \#foo
+ will link to the member.
+
+ For non overloaded members the argument list may be omitted.
+
+ If a function is overloaded and no matching argument list is specified
+ (i.e. pattern 2 or 6 is used), a link will be created to the
+ documentation of one of the overloaded members.
+
+ For member functions the class scope (as used in patterns 4 to 7) may
+ be omitted, if:
+ <ol>
+ <li>The pattern points to a documented member that belongs to the same class
+ as the documentation block that contains the pattern.
+ <li>The class that corresponds to the documentation blocks that contains
+ the pattern has a base class that contains a documented member
+ that matches the pattern.
+ </ol>
+
+ \section linkother Links to other members
+
+ All of these entities can be linked to in the same way as described in the
+ previous section. For sake of clarity it is advised to only use
+ patterns 3 and 7 in this case.
+
+ \par Example:
+ \verbinclude autolink.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/autolink/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by Doxygen.
+ \endhtmlonly
+
+ \section resolving typedefs
+
+ Typedefs that involve classes, structs and unions, like
+\verbatim
+typedef struct StructName TypeName
+\endverbatim
+ create an alias for StructName, so links will be generated to StructName,
+ when either StructName itself or TypeName is encountered.
+
+ \par Example:
+ \verbinclude restypedef.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/restypedef/html/restypedef_8cpp.html">here</a>
+ for the corresponding HTML documentation that is generated by Doxygen.
+ \endhtmlonly
+
+\htmlonly
+Go to the <a href="output.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/changelog.doc b/doc/changelog.doc
new file mode 100644
index 0000000..606f63f
--- /dev/null
+++ b/doc/changelog.doc
@@ -0,0 +1,2442 @@
+/** \page changelog Changelog
+\tableofcontents
+\section log_1_8 1.8 Series
+
+\subsection log_1_8_8 Release 1.8.8
+\htmlonly
+<b>(release date 21-08-2014)</b>
+<a name="1.8.8"></a>
+<h3>New features</h3>
+<ul>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=731947">731947</a> - Support for PlantUML [<a href="http://github.com/doxygen/doxygen/commit/7506404e646f1fcc5a26ca6fca91a7f65154f05a">view</a>]</li>
+<li>Add BREAD_CRUMB_TRAIL. [<a href="http://github.com/doxygen/doxygen/commit/4074da5b83d37dd1c72c5df015fb2b41e7725a7e">view</a>]</li>
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=172072">172072</a> $title doesn't work in LateX header [<a href="http://github.com/doxygen/doxygen/commit/790000b90944646702ddd3a183ec166669c18f51">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=583958">583958</a> Class diagrams and class hierarchy don't work for java generic classes [<a href="http://github.com/doxygen/doxygen/commit/c3ddf3331239fb3f41e502a8337eee786ceaad06">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=589707">589707</a> Flex .rule file for Visual Studio build can't cope with spaces in filenames [<a href="http://github.com/doxygen/doxygen/commit/eb3ab2452d8a1ef7a85af7a03e1622c12b40400b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623299">623299</a> Fortran: quotation after define causes error [<a href="http://github.com/doxygen/doxygen/commit/f083109de116ee2c6e2a31a15ebc17d2dff008e0">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625601">625601</a> FORTRAN: recognition free versus fixed formatted code [<a href="http://github.com/doxygen/doxygen/commit/476d79d31a0534c3d7d07001c47c1212a73d10a5">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700510">700510</a> Bibliography duplicate filenames fails [<a href="http://github.com/doxygen/doxygen/commit/7779bf6d6206bc0f78c22100034c44bfdb7f1bc1">view</a>] and
+ [<a href="http://github.com/doxygen/doxygen/commit/da029a3c893df22536cb3635e597fd3f5b2a4862">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702584">702584</a> \cite rejects valid BibTeX keys [<a href="http://github.com/doxygen/doxygen/commit/06170de4a166bfad9342f3b957dda82b7fb266b2">view</a>] and
+ [<a href="http://github.com/doxygen/doxygen/commit/69df2f9d1deb87b79c79f9ea1bf20380ff9b71ad">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705503">705503</a> TCL: Documentation of oo::define is not working [<a href="http://github.com/doxygen/doxygen/commit/5ec66c2286d7cedbdbb0930fe0e293b050c91d24">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=727732">727732</a> Nested C structures/unions does not work with groups [<a href="http://github.com/doxygen/doxygen/commit/f4388dc4a62e183b7ca4457eba7cb978a35804c2">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=728654">728654</a> configuration stops with settings.h missing [<a href="http://github.com/doxygen/doxygen/commit/fd4b42ec54cb8d6faf2b0f16e580f376e8cf6982">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=728740">728740</a> XML Output: Doxygen doesn't escape & characters (included in a hyperlink) in <detaileddescription> [<a href="http://github.com/doxygen/doxygen/commit/cfde6cdd600b21bba6a2eb0ca0e7e208e014ccaf">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=729017">729017</a> function object in member initializer causes documentation loss [<a href="http://github.com/doxygen/doxygen/commit/f4f3e381dba1bc5d46feea3c39e8f076e27463d1">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=729427">729427</a> [PATCH] Propagate configure's perl to makefiles [<a href="http://github.com/doxygen/doxygen/commit/f1a692b019a30f7aa07e0fb3e11402d262af8026">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=730418">730418</a> man page extension is incorrect [<a href="http://github.com/doxygen/doxygen/commit/f25d896d4da9b44c23f89bfdd0379fa97ab2c351">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=730520">730520</a> No documentation generated for method-less C++ struct [<a href="http://github.com/doxygen/doxygen/commit/21178ab40160abf011fa084a10892b5b7821e44c">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=730887">730887</a> [PATCH] Fix potential copy and paste error in inputstring.cpp [<a href="http://github.com/doxygen/doxygen/commit/6f5748e822b009cbe82cc1df8eea43e4769bc44b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=730888">730888</a> [PATCH] Fix missing '&' in Boolean operation in qstring.cpp [<a href="http://github.com/doxygen/doxygen/commit/27f1e1e9316addcfd0bbc3321b5614ed14f7a1a5">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=731238">731238</a> Dead links in html documentation when using tabs for indentation in c++ [<a href="http://github.com/doxygen/doxygen/commit/2cc3b18da39bde323c5739483e507a133e93ac22">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=731363">731363</a> Callgraphs for C# only generated for methods inside the same class [<a href="http://github.com/doxygen/doxygen/commit/7edbf2b2e705eccc0d99cce86149228473bc7f3e">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=731985">731985</a> Variadic macros failing to expand if trailing ... is empty [<a href="http://github.com/doxygen/doxygen/commit/070c35549da108695074239be3ab4268f3722261">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=732594">732594</a> Two entries for a single member in Doxygen XML [<a href="http://github.com/doxygen/doxygen/commit/ed8ce3cf405204916f9832e26797cb15d1490fd1">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=732768">732768</a> nested html tables cause pdflatex to hang (1.8.4 and 1.8.6) [<a href="http://github.com/doxygen/doxygen/commit/3cb963061343aa5b3b8a044cdfa62848723a02ee">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=733451">733451</a> volatile declaration on member functions is not handled as xml attribute [<a href="http://github.com/doxygen/doxygen/commit/97d12d058a7831adcc8c6f2cfe8c20ddd2ae5bc2">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=733605">733605</a> Incorrect LaTeX generation for private union member in C++ [<a href="http://github.com/doxygen/doxygen/commit/a36ddbe0ee97c5ee248b7b391b4c30fd4b3c884b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=733722">733722</a> XML Output invalid: XML_PROGRAMLISTING=YES copies Unicode form feed character (U+000C) to XML files [<a href="http://github.com/doxygen/doxygen/commit/b272b4b5077873457a0f6b517ac799f4a5f8c951">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=733856">733856</a> segfault in QGListIterator while parsing fortran code [<a href="http://github.com/doxygen/doxygen/commit/aac81f8bfe8298aa0839bb2d7c70ea75149cdffb">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=733938">733938</a> Explicit links using operator()() not generated. [<a href="http://github.com/doxygen/doxygen/commit/e913d55b2e5a8e37ebd1ffd8fec730886a45fbda">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734077">734077</a> no uniquely matching class member found for inline function definition where parameter argument names don't match [<a href="http://github.com/doxygen/doxygen/commit/6f0269ef3074bbc4bc16ad63a0e0a8f9b5f0ce31">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734099">734099</a> Add support for non-parsed language [<a href="http://github.com/doxygen/doxygen/commit/0dd59398b3f62288897c8c3405977a27a94fbfee">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734245">734245</a> Q_PROPERTY switches the member access from private to public [<a href="http://github.com/doxygen/doxygen/commit/392b48a25e4315528fbb11a5a1bfc9f2bca791c0">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734331">734331</a> Strong enum members listed in containing namespace [<a href="http://github.com/doxygen/doxygen/commit/4766fdba2ab196844a0bd5ec5e0b64d94df4a74f">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734704">734704</a> Sigsegv while generating XML output [<a href="http://github.com/doxygen/doxygen/commit/14f88af12bae98859eafe605ddb5f54029e44076">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734727">734727</a> GENERATE_TAGFILE no longer includes any @*section links [<a href="http://github.com/doxygen/doxygen/commit/7d9d4320f5d183c4e1ebc87a316589c36f0afeed">view</a>] and
+ [<a href="http://github.com/doxygen/doxygen/commit/8b279c9bc28c70405e61219a6c2b3c6dbc7426e6">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=734828">734828</a> Request: disable building documentation if Python 2.6 or newer not available [<a href="http://github.com/doxygen/doxygen/commit/264ecc9eee1f2b74f0110120574056f0de42a3f9">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=735001">735001</a> No output for markdown pages with duplicate label title (different anchor) [<a href="http://github.com/doxygen/doxygen/commit/ebb2fe6d73b4aefc6dadab8eec45adc4ee0c9fd5">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=735037">735037</a> QGDict::hashAsciiKey: Invalid null key [<a href="http://github.com/doxygen/doxygen/commit/def392bf8d0326733c20504dc36168093e087c95">view</a>]</li>
+<li>Add FORTRAN 2003 keywords and commands [<a href="http://github.com/doxygen/doxygen/commit/4cbfaa8372beff4bd7070dd840924af8d96b0772">view</a>]</li>
+<li>Add type option to FORTRAN select statements [<a href="http://github.com/doxygen/doxygen/commit/db289e2272bfc3b00452cbf7c2a30114fb8b7c58">view</a>]</li>
+<li>Added build support for Python3+ and Python2.6+ [<a href="http://github.com/doxygen/doxygen/commit/98a54c576eec4feda606156ae591854311d9cd0e">view</a>]</li>
+<li>Added class/procedure vardefs to FORTRAN code highlighting [<a href="http://github.com/doxygen/doxygen/commit/dbd1985de07ccd19caf57ffa36c88811048689a4">view</a>]</li>
+<li>Added documentation for some missing HTML commands [<a href="http://github.com/doxygen/doxygen/commit/04c89e604877fa9a4aea160d971c782006872710">view</a>]</li>
+<li>Added flatten, listsort and paginate filters [<a href="http://github.com/doxygen/doxygen/commit/edd056308d04d6f445a48e05105d4d9a0ece80a0">view</a>]</li>
+<li>Added get filter, unified index properties [<a href="http://github.com/doxygen/doxygen/commit/7e3e890fedfb20e7018fadfa87ed97eef7f2b720">view</a>]</li>
+<li>Added groupby filter and some more context info [<a href="http://github.com/doxygen/doxygen/commit/064992b0c901661b49de24ce1a1d9a06e9957a93">view</a>]</li>
+<li>Added import keyword to FORTRAN code highlighting [<a href="http://github.com/doxygen/doxygen/commit/558697792cd062b93e8d7b7904fb9897e5f70750">view</a>]</li>
+<li>Added lists for indices to template context [<a href="http://github.com/doxygen/doxygen/commit/2d35b9a7c0fe70fa894dc266dd0b5ddd54d4014e">view</a>]</li>
+<li>Added mainpage to context and improved page tree [<a href="http://github.com/doxygen/doxygen/commit/2e837e0be05636923ef593c29299ff76c4590a09">view</a>]</li>
+<li>Added member indexes to template context [<a href="http://github.com/doxygen/doxygen/commit/b850eb45e80b348cbe8629c354350b051f7ef2ec">view</a>]</li>
+<li>Added missing links in changelog when multiple bug ids were on one line [<a href="http://github.com/doxygen/doxygen/commit/b752d01fe2de1668c0a247bc3955d7be6987d046">view</a>]</li>
+<li>Added more missing links to the changelog [<a href="http://github.com/doxygen/doxygen/commit/0d50c30becc147918b091c02b41502829b8083a3">view</a>]</li>
+<li>Added namespace info to the context [<a href="http://github.com/doxygen/doxygen/commit/a7c14ac74c43e6b372d866deeed77fe69e2a68e0">view</a>]</li>
+<li>Addition of module data to context and alphaIndex filter [<a href="http://github.com/doxygen/doxygen/commit/e0c3517ff9369387e00dd596b094a4729cfe789c">view</a>]</li>
+<li>Coded coloring of flow statements corrected (regression) [<a href="http://github.com/doxygen/doxygen/commit/ee7194bd73ee3a8142aee6ea59d2e5dc717b18de">view</a>]</li>
+<li>Corrected copyright year [<a href="http://github.com/doxygen/doxygen/commit/7652fc8472ac83e26641fb737539e7c87725ed68">view</a>]</li>
+<li>Correction of typing error [<a href="http://github.com/doxygen/doxygen/commit/81c99d10dbc41feab4a1aca220b27634ca0ff8cd">view</a>]</li>
+<li>Disabled/fixed segments that produced doxygen warnings while running the test [<a href="http://github.com/doxygen/doxygen/commit/3a5e6ac7c6018a7a0da7acd830293da0fcb7a21c">view</a>]</li>
+<li>Docbook output improvements [<a href="http://github.com/doxygen/doxygen/commit/12f5ee8a8c3a287f6bcfe81f79ff4332b3987c7e">view</a>]</li>
+<li>Documentation generator: added support for C# property accessors visibility modifiers. [<a href="http://github.com/doxygen/doxygen/commit/54ac45bd9f535d13b2bf98e4d71b27b4590c3dc7">view</a>]</li>
+<li>Doxywizard: make the Next button on the last page of the expert tab switch to the run tab [<a href="http://github.com/doxygen/doxygen/commit/2277e6e695d785d319cb52a8a8ead2982eac2afa">view</a>]</li>
+<li>Doxywizard: make the Next button on the last page of the wizard switch to the run tab [<a href="http://github.com/doxygen/doxygen/commit/fbc60af2298c2668893e2f7045f66765f8e0c63f">view</a>]</li>
+<li>Error linking 32-bit windows [<a href="http://github.com/doxygen/doxygen/commit/cce307d96a93515d46068cfdcf5e55c1944ae9e5">view</a>]</li>
+<li>Fix FORTRAN code function scope test [<a href="http://github.com/doxygen/doxygen/commit/2030240bc18d32581479306e6fd86211e6f30c73">view</a>]</li>
+<li>Fix after rebase from master [<a href="http://github.com/doxygen/doxygen/commit/57eee1777c18caa6d3215ec162da1fd9b2d14eb2">view</a>]</li>
+<li>Fix description of USE_PDFLATEX [<a href="http://github.com/doxygen/doxygen/commit/c87cceafe203a11e4074b748469e993d13cd8fb3">view</a>]</li>
+<li>Fix highlighting issues [<a href="http://github.com/doxygen/doxygen/commit/be0986e9ab7c1788e3650f1df7e7af70b68f28d8">view</a>]</li>
+<li>Fix typo [<a href="http://github.com/doxygen/doxygen/commit/e32121ab1fb261464356ce2352c08930f942f805">view</a>]</li>
+<li>Fix unnecessary rules for FORTRAN types [<a href="http://github.com/doxygen/doxygen/commit/1e6323e5bb04f49df9d00e82e5db3e8f301dbfc4">view</a>]</li>
+<li>Fix warning about unused functions in qstring.cpp [<a href="http://github.com/doxygen/doxygen/commit/84064ac4db9e487ca4bff9b6c37eb72992050ee3">view</a>]</li>
+<li>Fixed keyword type [<a href="http://github.com/doxygen/doxygen/commit/d8221cb7a73efc8f20068636c3d2fec84ce8cb8b">view</a>]</li>
+<li>Fixed missing include for Linux [<a href="http://github.com/doxygen/doxygen/commit/88468313289c659088be9beece59a82206153ed8">view</a>]</li>
+<li>Fixed test 021 [<a href="http://github.com/doxygen/doxygen/commit/c5c763056535216ccce4bed4892358bf5c8d1fd5">view</a>]</li>
+<li>Fixed typo [<a href="http://github.com/doxygen/doxygen/commit/0bb9b762844a2f88043223a29182dd9e7e524cef">view</a>]</li>
+<li>Fixed typo and used QString for directory [<a href="http://github.com/doxygen/doxygen/commit/5d00fa5862a1724bbe417e33d6c1a260607281ef">view</a>]</li>
+<li>Fixed windows compile issue for is_neutral [<a href="http://github.com/doxygen/doxygen/commit/9278509cf82ed7b0ff37c39e4d6e97f5308f29de">view</a>]</li>
+<li>Fixes for ./configure script on Solaris [<a href="http://github.com/doxygen/doxygen/commit/d234115b6f387ff723cb97a4d47b2bcca7f0bc6d">view</a>]</li>
+<li>Fixes regression due to PR 169 [<a href="http://github.com/doxygen/doxygen/commit/56143a268898249a63bb0a443e09dc2c77ec9ce9">view</a>]</li>
+<li>Language parser: added support for C# property accessors visibility modifiers. [<a href="http://github.com/doxygen/doxygen/commit/f5ff1b8e55b4dad074d2a73f1d003ff2991cf894">view</a>]</li>
+<li>Made INSTALL file version and date independent [<a href="http://github.com/doxygen/doxygen/commit/1781094043eb5f8f7b0f0bbe5f720012346123a2">view</a>]</li>
+<li>Made bread crumb trails enabled unconditionally [<a href="http://github.com/doxygen/doxygen/commit/c7c7d73c184ee2eebf65e83044cf1e325751cffa">view</a>]</li>
+<li>Made setName() virtual so overloading works [<a href="http://github.com/doxygen/doxygen/commit/d1e39098f94487f544a068b7864aa8d1b1f345cd">view</a>]</li>
+<li>Make index for faq [<a href="http://github.com/doxygen/doxygen/commit/38dfdcaba3e9130833cd7b695d5e20fec26f5c3f">view</a>]</li>
+<li>Messages truncated in warnings file [<a href="http://github.com/doxygen/doxygen/commit/cc4f3b454cae7d3e9eaa44342bcbae1061f5e790">view</a>]</li>
+<li>Minor fixes [<a href="http://github.com/doxygen/doxygen/commit/c31a81a85e0396fb276beefd06bb71c2819571ed">view</a>]</li>
+<li>Minor fixes to the template context [<a href="http://github.com/doxygen/doxygen/commit/963e0adfd76e6a59ace5e7318f948632322b1e51">view</a>]</li>
+<li>Missing word after \n command in Doxygen rtf output, version 1.8.5 & up [<a href="http://github.com/doxygen/doxygen/commit/ea9f3b1d727b22973c0176b2564304fb160aa70b">view</a>]</li>
+<li>More robust extraction of scope information from tag files [<a href="http://github.com/doxygen/doxygen/commit/6a60477b418e21dbadd3e62dc557a038e319581b">view</a>]</li>
+<li>No warning in case cite definition is missing [<a href="http://github.com/doxygen/doxygen/commit/1f77638174f715f0f2bcf5b2e32ebb329d531f85">view</a>]</li>
+<li>Preparations for release 1.8.8 [<a href="http://github.com/doxygen/doxygen/commit/f16be0113f8d47d4f04e69d0c45ccc4b24e3c426">view</a>]</li>
+<li>Removed not implemented HTML commands from documentation [<a href="http://github.com/doxygen/doxygen/commit/8199b2d105313efd30367c7a03b57bf7a7d2180b">view</a>]</li>
+<li>Removed unsupported HTML commands from the docs [<a href="http://github.com/doxygen/doxygen/commit/16ba4bd5744c2e5fbfabe95b27736b8ca8030390">view</a>]</li>
+<li>Set deployment targets for MacOSX 10.5+ versions [<a href="http://github.com/doxygen/doxygen/commit/28f40b3aea1411488832205fae447f4652125cdc">view</a>]</li>
+<li>Support multiple extra HTML stylesheets. [<a href="http://github.com/doxygen/doxygen/commit/595943c96860425f9086028b00e1e155e8ec434f">view</a>]</li>
+<li>Tcl: add missing file that breaks test 057 [<a href="http://github.com/doxygen/doxygen/commit/73e7c340f555291d4264b2f83caacf59a5a3395f">view</a>]</li>
+<li>Tcl: add test code for Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=729092">729092</a> [<a href="http://github.com/doxygen/doxygen/commit/36ce0578065b95cf12b81e5a4edd95dea5707e22">view</a>]</li>
+<li>Tcl: collect XRefs also if INLINE_SOURCES = no [<a href="http://github.com/doxygen/doxygen/commit/6245ef410358f332330195f9f2bfa458cfb6a2b8">view</a>]</li>
+<li>Tcl: correct namespace resolution in case of INLINE_SOURCES = YES [<a href="http://github.com/doxygen/doxygen/commit/470143192d0c8cf90ad84a66226d48060cc713db">view</a>]</li>
+<li>Tcl: recurse for [] [<a href="http://github.com/doxygen/doxygen/commit/9d315a987d7d0ea2f38809aa74e36c92281910df">view</a>]</li>
+<li>Tcl: refactor similar code into tcl_codify_token function [<a href="http://github.com/doxygen/doxygen/commit/06bd53ac6acee5fb83d9f2b5ded1c55c8a069b29">view</a>]</li>
+<li>Tcl: support eval/catch commands [<a href="http://github.com/doxygen/doxygen/commit/9d24b488add8b4c7c689f58a095184a6ed85e9f1">view</a>]</li>
+<li>Tcl: support switch command [<a href="http://github.com/doxygen/doxygen/commit/2984dad86558b4a81e11ce07485057e3903a9304">view</a>]</li>
+<li>Tcl: test 057 additionally tests mutual Xrefs for two files [<a href="http://github.com/doxygen/doxygen/commit/c6aaf0a4c35db27f968a7a6d0b9fa25b5b311bc3">view</a>]</li>
+<li>Template context support for CREATE_SUBDIRS [<a href="http://github.com/doxygen/doxygen/commit/9282aab5ed2a0cca3858df6e62132f959e99edb5">view</a>]</li>
+<li>Update dot.cpp [<a href="http://github.com/doxygen/doxygen/commit/a15c5c89f0b4f97d57474d9ea0e3166709d35534">view</a>]</li>
+<li>Update latexgen.cpp [<a href="http://github.com/doxygen/doxygen/commit/1f877b09262f34e6bad6dbfaee4b04b4be03bd4c">view</a>]</li>
+<li>Update test 058 because commit 9d315a9 fixes also Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=729135">729135</a> [<a href="http://github.com/doxygen/doxygen/commit/3486bfc158008da1d69d420e57e7a10f1c0d69c3">view</a>]</li>
+<li>Replaced the VHDL parser with the VHDL scanner from 1.7.5 to avoid potential licensing issues [<a href="http://github.com/doxygen/doxygen/commit/99433b3d2319916f11608c2c818fe35360256d9e">view</a>]</li>
+<li>New VHDL parser implementation [<a href="http://github.com/doxygen/doxygen/commit/36122e49ed1d9e640b1ceca52536ec7c55e10474">view</a>]</li>
+<li>Vhdl fixes [<a href="http://github.com/doxygen/doxygen/commit/3b8fea2f1f7f2e6a83a35626e6dec9d114a78c9e">view</a>]</li>
+<li>\usepackage{fixltx2e} must come before use \usepackage{float} [<a href="http://github.com/doxygen/doxygen/commit/d8a36bbd404bc9c77689f42cc4bfde8ac393cd8c">view</a>]</li>
+<li>cache anonymous into ClassDefImpl::isAnonymous [<a href="http://github.com/doxygen/doxygen/commit/34a5a051a8b91215ae4f93e5541d43c33aa887c1">view</a>]</li>
+<li>changed append filter and added index and path attributes to node [<a href="http://github.com/doxygen/doxygen/commit/47bc520ac8c0dde310dcb1999c622c591b373ffc">view</a>]</li>
+<li>doc/translator.py -- unification for Python 2.6+ and 3.3+ (not finished) [<a href="http://github.com/doxygen/doxygen/commit/8cac977ddfdc1c77546f5d766387f4a57710c8c0">view</a>]</li>
+<li>doc/translator.py unified for Python 2.6+ and Python 3.0+ [<a href="http://github.com/doxygen/doxygen/commit/6212c2d2af12dd9d47459bdecdf79ad106060229">view</a>]</li>
+<li>make.bat: change current directory [<a href="http://github.com/doxygen/doxygen/commit/fc386eb107958b4f3214aa2c0c6caf2a91c83177">view</a>] and
+ [<a href="http://github.com/doxygen/doxygen/commit/feb24c82002ced816bc72eb8f2a6a35c71e25ed7">view</a>]</li>
+<li>removeRedundantWhiteSpace micro-optimization [<a href="http://github.com/doxygen/doxygen/commit/d4601735b582b903f1ccb144f59b2030a7797b05">view</a>]</li>
+<li>resolves the error of unbalanced tags opened/closed in docbook output: parser error : Opening and ending tag mismatch: para line 358 and tbody [<a href="http://github.com/doxygen/doxygen/commit/d7b0858e079419bb7ea862e16946218a9352d5b5">view</a>]</li>
+<li>winbuild/pack_the_distribution_for_windows.py minor updates [<a href="http://github.com/doxygen/doxygen/commit/6d969cab51f4c32784966a28b8b9d5fe2d5b2089">view</a>]</li>
+</ul>
+\endhtmlonly
+
+\subsection log_1_8_7 Release 1.8.7
+\htmlonly
+<b>(release date 21-04-2014)</b>
+<a name="1.8.7"></a>
+<ul>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=436885">436885</a> - c-source and h-source missing for latex [<a href="http://github.com/doxygen/doxygen/commit/d5d34325fb9bed776cf2b4facc0c341f701e780b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625601">625601</a> - FORTRAN: recognition free versus fixed formatted code [<a href="http://github.com/doxygen/doxygen/commit/2dec1060623165057628ee678eb3580351922408">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626172">626172</a> - Latex $projectname with "&" gets no escaped [<a href="http://github.com/doxygen/doxygen/commit/586b3b69238fb09d55a03c5d50fc1b7d3e65ed97">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643618">643618</a> - Fortran: variable with name "type" confuses Doxygen [<a href="http://github.com/doxygen/doxygen/commit/17c5b6160d013d118296663e133cf8884c74a939">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674851">674851</a> - Percent to prevent auto-linking in page title is not removed for navpath [<a href="http://github.com/doxygen/doxygen/commit/5d44acc0a49bd7b990bfe649efa312f5f0bb594b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678436">678436</a> - Nested \if messes up list items [<a href="http://github.com/doxygen/doxygen/commit/7f4414b92a1c2147b073dd3cf58e0db7c8a88be6">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678436">678436</a> - Nested \if messes up list items [<a href="http://github.com/doxygen/doxygen/commit/de502ca71fc1c20ed93209f6a223c488eee38297">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=683115">683115</a> - Command ignored when using umlauts in markdown and also C-comments in markdown didn't work properly [<a href="http://github.com/doxygen/doxygen/commit/b4b40f4c7ea57655d1264e8f72c754526e3a9209">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692985">692985</a> - Notes in xml output are not correctly separated [<a href="http://github.com/doxygen/doxygen/commit/bc61f00f142792dfbe97c361d9fecd3ea2850f5e">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705220">705220</a> - Enables using unicode (non ASCII) to name output files [<a href="http://github.com/doxygen/doxygen/commit/d5fb69739a1b2facf32a63ca94c12d097f8278cc">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705499">705499</a> - Nested namespace causes incorrect display when referenced via .tag file [<a href="http://github.com/doxygen/doxygen/commit/1bdbbc60982f2f61f4e0423c9fc8c4a24cfb2e94">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=712251">712251</a> - Documentation for enumeration not generated [<a href="http://github.com/doxygen/doxygen/commit/1bb36723a522b371810606c2f6504d0374a7b027">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=720691">720691</a> - Code coloring in case of file without extension [<a href="http://github.com/doxygen/doxygen/commit/45934e88fa961686c00be1ad272a088f4e7eac0b">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721032">721032</a> - Trouble with /cond /endcond [<a href="http://github.com/doxygen/doxygen/commit/2912829ca5bced897a2c063d1883b9cfd39d3bd9">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721169">721169</a> - Wrong call graph in simple situation [<a href="http://github.com/doxygen/doxygen/commit/e12d6b506862c8ad843b7853bc1c9ceb5d0ccb4d">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721302">721302</a> - [Latex/PDF] Merging brief and detailed description in file section [<a href="http://github.com/doxygen/doxygen/commit/a99c33838057acba20768ca32681e1f379f36ca0">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721462">721462</a> - Parsing problem with C++11 empty initializer lists [<a href="http://github.com/doxygen/doxygen/commit/1bfacc3b8e589907352eff923b7b3aa73cfc5138">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721618">721618</a> - Move contructors and move assignment operators of embedded classes of template classes cannot be matched. [<a href="http://github.com/doxygen/doxygen/commit/1d0c9b6fefb6c2e0a9a2b7a7ea3192ccace33710">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=721878">721878</a> - Dia diagrams not displayed by Firefox [<a href="http://github.com/doxygen/doxygen/commit/5ea2f2a123e473d5964435369fd925d7f103b456">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722457">722457</a> - regression referencing namespaced type [<a href="http://github.com/doxygen/doxygen/commit/9b76c1a9bb7039962933aeef398bb7aa2f59c3a5">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722603">722603</a> - doxygen nested \if \endif sample not working [<a href="http://github.com/doxygen/doxygen/commit/cc78b12b0019fbcb17692b231d38ba75d0952201">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722619">722619</a> - doxygen 1.8.6 sorts the contents of a namespace by group within the Class List [<a href="http://github.com/doxygen/doxygen/commit/f9b80aff6d20524dd0838aff12033fe3df66ba98">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722711">722711</a> - Link refs with no title swallow an extra newline [<a href="http://github.com/doxygen/doxygen/commit/60ea06a68f2e355e34b61bf45babc6405bfbfe84">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722759">722759</a> - Documentation for derived classes no longer has an "Additional Inherited Members" section after upgrading Doxygen from 1.8.3.1 to 1.8.6 [<a href="http://github.com/doxygen/doxygen/commit/0e9da9fb27147c5685088019afd428a0aaa901fa">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722786">722786</a> - configure --prefix=/opt/foo not accepted [<a href="http://github.com/doxygen/doxygen/commit/bc7e6301e2d1474592f6cd6cc07624852d1b5016">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=722788">722788</a> - Command \| not working when last character in markdown table line [<a href="http://github.com/doxygen/doxygen/commit/8309fbd9e639eaf9e763e83ca7a228c659450a57">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=723299">723299</a> - Last line of code block lost if it is only one character and there is no text afterward [<a href="http://github.com/doxygen/doxygen/commit/4d1951ebb648bbc92464904305cafc7fc0dba557">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=723314">723314</a> - Doxygen crashes on incorrect end group /**< @} */ [<a href="http://github.com/doxygen/doxygen/commit/b4d5ef176eced8315523baea464cfda733ecb9aa">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=723516">723516</a> - star is not printed in \code environment [<a href="http://github.com/doxygen/doxygen/commit/0eaf1cd5d2eac57666b5ffea9e0f948b7a3e6b3a">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=724241">724241</a> - Internal inconsistency: namespace in IDL [<a href="http://github.com/doxygen/doxygen/commit/b0456fbefa864b33611f289818deeaaf791c17c9">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=724949">724949</a> - Server side (PHP) search broke in 1.8.3 [<a href="http://github.com/doxygen/doxygen/commit/1d2bb19e394850ecb37bea06ef4e5d15fe06e7b0">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=726219">726219</a> - python3 import style causes doxygen to ignore some inheritances [<a href="http://github.com/doxygen/doxygen/commit/513ce9aafd05add9b5c1e67e843e540f8937cf63">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=726294">726294</a> - Markdown Extra - fenced code block: '>' before tab width parsed as block quote [<a href="http://github.com/doxygen/doxygen/commit/3598e8fdf7ee61a281480fec09f63669710ac35d">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=726469">726469</a> - Tilde sign in combination with <pre> and MARKDOWN_SUPPORT disabled [<a href="http://github.com/doxygen/doxygen/commit/721764a1b3c63c77ff0792beb6c37fbfee0f87bb">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=726722">726722</a> - Blockquote followed by text inserts an extra paragraph [<a href="http://github.com/doxygen/doxygen/commit/518fccbbadba3136a29c895f3606f40fa220fe47">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=726734">726734</a> - alignment of blockquotes in pdf [<a href="http://github.com/doxygen/doxygen/commit/9059295fd6e178804f2f2d95ffe3764645ecc026">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=728077">728077</a> - Build fails when --with-libclang on Fedora [<a href="http://github.com/doxygen/doxygen/commit/837d63319a7b014412cb3cb2b5d27d2474a932c2">view</a>]</li>
+<li>Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=728530">728530</a> - Crash on \addindex \term [<a href="http://github.com/doxygen/doxygen/commit/653a2a8b123b79835af9f684f8b92ef7f88712aa">view</a>]</li>
+<li>A new files have been added but is not incorporated in the windows build part [<a href="http://github.com/doxygen/doxygen/commit/d9dd873e25fba968ddcbcc79d6643f5df669b626">view</a>]</li>
+<li>Add docbook directory to be removed as well [<a href="http://github.com/doxygen/doxygen/commit/08ea10029e705a388ab14ee29544d496a203f23f">view</a>]</li>
+<li>Add extra (documenattion) directories to ignore pattern [<a href="http://github.com/doxygen/doxygen/commit/db358b1f219fecf0d7df96d8c70b47b245471c66">view</a>]</li>
+<li>Add index support to context [<a href="http://github.com/doxygen/doxygen/commit/12cd22f4c32ed8b92da7b5a03181aa6735018a5b">view</a>]</li>
+<li>Add line numbers in case comment is not closed properly. [<a href="http://github.com/doxygen/doxygen/commit/b1d513b2ac65fe26ceec2fa494867713efa01cd5">view</a>]</li>
+<li>Add template context for annotated class index [<a href="http://github.com/doxygen/doxygen/commit/9434ecb13e1f3e2901b78d3e41e7f1d7d9469434">view</a>]</li>
+<li>Add validation of internal consistency to html entity mapper [<a href="http://github.com/doxygen/doxygen/commit/d96458ce99b92590a8fec0aba46c67b6816fa632">view</a>]</li>
+<li>Add warning when encountering a nested comment start (/*) without matching end (*/). [<a href="http://github.com/doxygen/doxygen/commit/7f30d0afbeb9565bced1439f86ce9f862de5282e">view</a>]</li>
+<li>Added \latexinclude command (thanks to Juan Zaratiegui for the patch) [<a href="http://github.com/doxygen/doxygen/commit/1134237afe25f86fcf7c7e2a76a3542eee8acc79">view</a>]</li>
+<li>Added basic arithmetic operations to the template expressions, and made the expression lexer faster [<a href="http://github.com/doxygen/doxygen/commit/5af2b7c0aef5cd6a0dc6ceddcffba16f623d920a">view</a>]</li>
+<li>Added dir tree nodes to the context [<a href="http://github.com/doxygen/doxygen/commit/762ee821bb0bef125d5406572963ce32c748e227">view</a>]</li>
+<li>Added directory info to the context [<a href="http://github.com/doxygen/doxygen/commit/47adeb82d67208db88a4aaae5c3427291462611a">view</a>]</li>
+<li>Added doc/config.doc to .gitignore [<a href="http://github.com/doxygen/doxygen/commit/fa400a0252d12db3ffd30eb083e5185f11264112">view</a>]</li>
+<li>Added language update for Swedish (thanks to Björn Palmqvist) [<a href="http://github.com/doxygen/doxygen/commit/eec2140f577431915ed087727093c5bf381500ba">view</a>]</li>
+<li>Added last and first attributes to index tree node [<a href="http://github.com/doxygen/doxygen/commit/ff5ec803a39b225e03edcd1bf2df3198dafcc16e">view</a>]</li>
+<li>Added missing \+ command to build LaTeX manual [<a href="http://github.com/doxygen/doxygen/commit/c096119b0c0bfc567058538b6225ca26eb191a3a">view</a>]</li>
+<li>Added new language maintainer for Swedish, removed generated file language.doc [<a href="http://github.com/doxygen/doxygen/commit/f3172cf19514fc05588878d3fabfffe479495cca">view</a>]</li>
+<li>Added optional [block] option to \htmlonly [<a href="http://github.com/doxygen/doxygen/commit/842c816a31537e32cec376c85c0a4363f74d7a54">view</a>]</li>
+<li>Added reference counting for all context objects [<a href="http://github.com/doxygen/doxygen/commit/ff00706a18b6e57419796ffd6f1448cb2ccb9436">view</a>]</li>
+<li>Added stricter URL filtering to prevent DOM Based XSS when the tree view is enabled [<a href="http://github.com/doxygen/doxygen/commit/8ba739ad1ecde1036bfe2e364aee378e137f6dff">view</a>]</li>
+<li>Added support for \-- and \--- to prevent interpretation as ndash and mdash [<a href="http://github.com/doxygen/doxygen/commit/385b87e08c23b1392d0e6d6fbdb6ef463fa28477">view</a>]</li>
+<li>Added support for elif to the template language [<a href="http://github.com/doxygen/doxygen/commit/ae3a22ba276a2e446a460274e0bff8a9bdf4af7d">view</a>]</li>
+<li>Added support for range tag in the template language [<a href="http://github.com/doxygen/doxygen/commit/b98846d0b57b78cd45d34e0962a8bcdc2e643e18">view</a>]</li>
+<li>Alterative way to get rules information from flex [<a href="http://github.com/doxygen/doxygen/commit/224fa96dd9c9245bfdf68ee6f92160b7aa05f8d1">view</a>]</li>
+<li>Better message in case doxygen -u is used [<a href="http://github.com/doxygen/doxygen/commit/cfd8c2415e7d0744a00bf1990f26aab538940f20">view</a>]</li>
+<li>Changed "See Also" back to "See also" [<a href="http://github.com/doxygen/doxygen/commit/0754c968a4a06c8217c9301a5ca82c6212c228ec">view</a>]</li>
+<li>Chm don't add images multiple times [<a href="http://github.com/doxygen/doxygen/commit/3b339813794390bdce59fa1009cf71506e0cec2b">view</a>]</li>
+<li>Command \< and \> are not properly shown in section headers (and consequently in index) [<a href="http://github.com/doxygen/doxygen/commit/04a8ce9a8e2f022c21a5728ffdfb029258fa54e9">view</a>]</li>
+<li>Consistency of usage of the word LaTeX in the documentation [<a href="http://github.com/doxygen/doxygen/commit/d63a7d8812c7f748a48d76bfc39ce57f79f6f667">view</a>]</li>
+<li>Context enhancement [<a href="http://github.com/doxygen/doxygen/commit/92d53a473074a78735d25bbef02715b3caced569">view</a>]</li>
+<li>Corrected some definitions for some Fortran keywords [<a href="http://github.com/doxygen/doxygen/commit/d4aa05e171d27cc17b177078d3ff481441087da4">view</a>]</li>
+<li>Disabled config dependency check to avoid regression [<a href="http://github.com/doxygen/doxygen/commit/904ad3fbdc5e1615fdb052ba8562fc9b1329cd81">view</a>]</li>
+<li>Documentation corrections [<a href="http://github.com/doxygen/doxygen/commit/4b51e6113f1e9e20a5700840d83f1c3928d84825">view</a>]</li>
+<li>Enable Previous and Next buttons in chm output file [<a href="http://github.com/doxygen/doxygen/commit/e6a78b6b2573388353bdb5dcd7a13dcc11959d13">view</a>]</li>
+<li>Enabling possibility to have { and } in (latex) index items [<a href="http://github.com/doxygen/doxygen/commit/dd2c137847e16d0a7c6086053f55bce501d84a0c">view</a>]</li>
+<li>Error message is given for make distclean as generated_src is a directory [<a href="http://github.com/doxygen/doxygen/commit/76701e2bfb688ac22a751c4f03b28fa9d5f594f7">view</a>]</li>
+<li>Extension in config.xml if type=string with format=image [<a href="http://github.com/doxygen/doxygen/commit/025cc9def72002d4ab6da7bfee8a73c03ca7c331">view</a>]</li>
+<li>Extension specific filtering [<a href="http://github.com/doxygen/doxygen/commit/425e64e2ee52b92a2c0c8f6fb5457bf95b95e5bf">view</a>]</li>
+<li>Fix id parsing for atx markdown headers [<a href="http://github.com/doxygen/doxygen/commit/ee830bb8888535ac48c0c4fd90580542e7f70481">view</a>]</li>
+<li>Fix segfault on invalid bounding FIG when patching dot [<a href="http://github.com/doxygen/doxygen/commit/1bd2e38a2ce2d0823557381c48fe47cb53d6fba8">view</a>]</li>
+<li>Fix to VHDL scanner. [<a href="http://github.com/doxygen/doxygen/commit/5ca7d423a11337d5c31082f52a287a3dc0986642">view</a>]</li>
+<li>Fix typos in russian translation [<a href="http://github.com/doxygen/doxygen/commit/8ce2b0d7aec1d4398b5b4f365a7d3abbe75daf5f">view</a>]</li>
+<li>Fixed Tidy's 'empty span' warning in HTML output [<a href="http://github.com/doxygen/doxygen/commit/8cfac90d6c8632436db1a6b650a05a8dfcfab5d0">view</a>]</li>
+<li>Fixed compiler warnings in section.h [<a href="http://github.com/doxygen/doxygen/commit/683ef76f7bf1ba929f9c263064bb5f6c8e377275">view</a>]</li>
+<li>Fixed difference between generated XML schema and XML files for HTML entities [<a href="http://github.com/doxygen/doxygen/commit/836af2f9510d10f2dd7d832025f214983387b3c6">view</a>]</li>
+<li>Fixed issues with @parblock and added regression test case [<a href="http://github.com/doxygen/doxygen/commit/2ed3d33a92dbcdf0a0149c5f06909926e44cdebd">view</a>]</li>
+<li>Fixed issues with SEPARATE_MEMBER_PAGES and INLINE_SIMPLE_STRUCTS [<a href="http://github.com/doxygen/doxygen/commit/a9f93437b6b2b9686e1b4f2e691782c6ebe99c26">view</a>]</li>
+<li>Fixed memory leak in nested comment administration [<a href="http://github.com/doxygen/doxygen/commit/2514ba72e53473f8dd424efdbef34287c8a3fd56">view</a>]</li>
+<li>Fixed off-by one error for last character in compound.xsd [<a href="http://github.com/doxygen/doxygen/commit/61b00c0061eda805696fe6f90db15136811e1ed7">view</a>]</li>
+<li>Fixed potential crash caused by overloading the variadic warn function [<a href="http://github.com/doxygen/doxygen/commit/31505eb34565b2e39d113b7f5460645d02ad6d2e">view</a>]</li>
+<li>Fixed problem handling Obj-C protocol list when proceeded by a newline [<a href="http://github.com/doxygen/doxygen/commit/09a5fc198a98d697d3e50c1c76392b8373f1af12">view</a>]</li>
+<li>Fixed problem with ending a paragraph when htmlonly was at the end of a comment block [<a href="http://github.com/doxygen/doxygen/commit/8d03b3f35e404abfd0ed31022a687fc1eab07fd5">view</a>]</li>
+<li>Fixed typo in changelog [<a href="http://github.com/doxygen/doxygen/commit/8f58d6dd7c3d0f6004d127bf111f76e4a4478516">view</a>]</li>
+<li>Fixed typo in doxyindexer.vcproj [<a href="http://github.com/doxygen/doxygen/commit/2bc8a820b3e2fefaedb10a3129eed35581a1ea5b">view</a>]</li>
+<li>Fixes for missing build dependencies [<a href="http://github.com/doxygen/doxygen/commit/62379ff8fdb13d95c7651419d92db47150e15bcc">view</a>]</li>
+<li>Give message when PROJECT_LOGO cannot be found or cannot be converted [<a href="http://github.com/doxygen/doxygen/commit/164864d9bc8ea7e32a69fbc0e47cff54dc678a48">view</a>]</li>
+<li>Handlingh of -- by \c and <code> results in - adjusted documentation [<a href="http://github.com/doxygen/doxygen/commit/73d12cc5cf0656e94125baea62cdb19b67908b3d">view</a>]</li>
+<li>Improve rendering of sub and superscripts in LaTeX [<a href="http://github.com/doxygen/doxygen/commit/a7c7f36ea2a67969bf3916c7600fe487e34438c0">view</a>]</li>
+<li>Improved handling of percent symbol [<a href="http://github.com/doxygen/doxygen/commit/0e080f486f67008ef427c834f6ab6ebca7578124">view</a>]</li>
+<li>Improved performance of rendering large index pages, by replacing images in the tables by spans [<a href="http://github.com/doxygen/doxygen/commit/956a7fb004e72923f737e387d053812f99b7bda2">view</a>]</li>
+<li>In case of sections with the same name they are not reported. [<a href="http://github.com/doxygen/doxygen/commit/ac611be473c2d9bf65bcafb53b0577274c4ae706">view</a>]</li>
+<li>Inconsistency in usage of simplesecr versus simplesectsep corrected [<a href="http://github.com/doxygen/doxygen/commit/bc46b90c42470e238a6e038f49a7423796a8c2e3">view</a>]</li>
+<li>Inconsistency in usage of simplesecr versus simplesectsep corrected [<a href="http://github.com/doxygen/doxygen/commit/c5bedcdc2e3b6c519aae62ff1a08d4ec808cce6b">view</a>]</li>
+<li>Incorrect handling dependencies [<a href="http://github.com/doxygen/doxygen/commit/bfcfa6fc73942b80cb22e2900438dc99d844a78e">view</a>]</li>
+<li>Items XML_SCHEMA and XML_DTD declared obsolete [<a href="http://github.com/doxygen/doxygen/commit/ba31ee73aad3bdc6b3854add2db01c302c9cf19c">view</a>]</li>
+<li>List only the project pages in "Related Pages" [<a href="http://github.com/doxygen/doxygen/commit/a2c7f91d6320f72951f1e3ef092e077a89562670">view</a>]</li>
+<li>Made documentation more consistent [<a href="http://github.com/doxygen/doxygen/commit/b81fe14c7fe8b3eaafa4ce8ddcd0f1815c2c7ff0">view</a>]</li>
+<li>Make sure all ids in g_linkRefs are lower case [<a href="http://github.com/doxygen/doxygen/commit/3df31762585075033a04e40c3cdfb52781aa258f">view</a>]</li>
+<li>Make the MAN_SUBDIR setting overide the name of the directry the man pages are placed in. [<a href="http://github.com/doxygen/doxygen/commit/83b344db49b27bf68994eb8ec6be87d6d0f24e86">view</a>]</li>
+<li>Meta tag in the HTML search page was not closed properly [<a href="http://github.com/doxygen/doxygen/commit/4ccfb9efa8382de50dfc5b176cb147fd1b05870c">view</a>]</li>
+<li>Minor fixes for the new build locations [<a href="http://github.com/doxygen/doxygen/commit/d86520ef4920a9a47a4d6e33eadfc62b8b983748">view</a>]</li>
+<li>Missing & and chars after " in tree of chm documentation [<a href="http://github.com/doxygen/doxygen/commit/89638fbc9961bd9a1e9cb7bc25e5f739936e8a43">view</a>]</li>
+<li>More context changes [<a href="http://github.com/doxygen/doxygen/commit/196f39515ec5f9fdcbda68046f48a1d1a8250854">view</a>]</li>
+<li>More work on the template and context mechanisms [<a href="http://github.com/doxygen/doxygen/commit/744d1ca52e25dfa9e3d656056d87ed7cb6320585">view</a>]</li>
+<li>On windows citelist.doc remains [<a href="http://github.com/doxygen/doxygen/commit/3c941f24ee93687c197363fa2d4b787512878eab">view</a>]</li>
+<li>Place where dot executable is found [<a href="http://github.com/doxygen/doxygen/commit/90ecc2487146e0cdd392047342a30fd13453b233">view</a>]</li>
+<li>Properly escape the XCODE path. [<a href="http://github.com/doxygen/doxygen/commit/0cc8f6b2a14fdeb6d6769d34edb035b755d1299f">view</a>]</li>
+<li>Pull out property names in Objective-C. [<a href="http://github.com/doxygen/doxygen/commit/f4ff0ea8b11560ce718bb41b63bdf793cd333f27">view</a>]</li>
+<li>Recognize all HTML4 special character entities [<a href="http://github.com/doxygen/doxygen/commit/1bd64ac0e925ba2ff069ec64c026ea3c32f85600">view</a>]</li>
+<li>Reduced and improved functionality of QList [<a href="http://github.com/doxygen/doxygen/commit/6e51abf63021dc9fe32c05f003232fe68a08591d">view</a>]</li>
+<li>Removed config.doc as it is generated by configgen.py [<a href="http://github.com/doxygen/doxygen/commit/a642629761d43d53f3ade41c78530d0c7228a84d">view</a>]</li>
+<li>Removed generated file src/settings.h from source repository [<a href="http://github.com/doxygen/doxygen/commit/43461e44d49200fd1564c4e416db7384e7e5eab8">view</a>]</li>
+<li>Removed message, minor restructuring [<a href="http://github.com/doxygen/doxygen/commit/ea436bd659e022d6375dd37f651d4bb18a1c01db">view</a>]</li>
+<li>Removed remark about installdox from the FAQ [<a href="http://github.com/doxygen/doxygen/commit/68080883535bb146e2e4f65943c8b836da6b68e0">view</a>]</li>
+<li>Restructered html entity handling [<a href="http://github.com/doxygen/doxygen/commit/dfa20277697fe904a0846b60a01cc388fc13c933">view</a>]</li>
+<li>Reverted #132 after submitter reported that it did not work [<a href="http://github.com/doxygen/doxygen/commit/fdc81edcd47ce176648d7507d0597294098ae8aa">view</a>]</li>
+<li>Showing error message on windows in case on error on startup [<a href="http://github.com/doxygen/doxygen/commit/6a0651d9328262271ade2b733c125aae4415e3c3">view</a>]</li>
+<li>Simplified LaTeX header/footer escaping [<a href="http://github.com/doxygen/doxygen/commit/3337add3a6e05e26800c9e269b23fff272a9534c">view</a>]</li>
+<li>Some restructuring and some compiler warning fixes [<a href="http://github.com/doxygen/doxygen/commit/941eea998d6b9608b8fc586069ef90e805d771f5">view</a>]</li>
+<li>Spitting generated files better from source files [<a href="http://github.com/doxygen/doxygen/commit/8885016b2a3bbeb6045a3e71d508939e0a7bd773">view</a>]</li>
+<li>Superfluous < sign [<a href="http://github.com/doxygen/doxygen/commit/599700e6e72d687b6597cfbe2453474b231640ea">view</a>]</li>
+<li>Superfluous backslash in documentation [<a href="http://github.com/doxygen/doxygen/commit/be5f9c70bcf38f9bce58e4b8e293dab6aea754fd">view</a>]</li>
+<li>Superfluous include removed [<a href="http://github.com/doxygen/doxygen/commit/0e12f6bfa938b675f827074eb3693eff362e6b96">view</a>]</li>
+<li>Undo previous commit [<a href="http://github.com/doxygen/doxygen/commit/1b5d5e53a7fce8136f9ab0ce82c95a8f9d479574">view</a>]</li>
+<li>Unified DirFileContext and NestingContext [<a href="http://github.com/doxygen/doxygen/commit/df839603204979113b96678e2ab21b3eba64476c">view</a>]</li>
+<li>Update doctokenizer.l [<a href="http://github.com/doxygen/doxygen/commit/68cf977ee72f8914678e30e3a88f0e9d90703418">view</a>]</li>
+<li>Update doctokenizer.l [<a href="http://github.com/doxygen/doxygen/commit/ea1ee635fccbba4273a922dab3d092dd75b195e0">view</a>]</li>
+<li>Updated copyright [<a href="http://github.com/doxygen/doxygen/commit/a28ff2331d8e228d901cd6f0b038f76e1cee630a">view</a>]</li>
+<li>Use \newline i.s.o. \par for linebreaks in LaTeX [<a href="http://github.com/doxygen/doxygen/commit/7e719d1ad5da33ccb3f54a90ae11dee58828b6ab">view</a>]</li>
+<li>Use hook arrow for hyphens in symbol names in the LaTeX output. [<a href="http://github.com/doxygen/doxygen/commit/ac813134a85ba9bd999fb4cf8271c74e02cd4ebb">view</a>]</li>
+<li>Wrong UTF 8 codes [<a href="http://github.com/doxygen/doxygen/commit/fd4beb272e5f1a760a71ab8d85463b8356c6f786">view</a>]</li>
+<li>Fix broken links to subpages in LaTeX output [<a href="http://github.com/doxygen/doxygen/commit/10189681dcb46e543a287827e2096cef3dbc42ae">view</a>]</li>
+<li>\xmlonly aoppeared twice in see also section of \htmlonly and \docbookonly [<a href="http://github.com/doxygen/doxygen/commit/f1cdb27194dd180f1bff1fbdd87874bb0d15758d">view</a>]</li>
+<li>add css-escape to avoid jquery based xss [<a href="http://github.com/doxygen/doxygen/commit/7fea82094723ecfb4e9b3ea6819137b99d7dfa9c">view</a>]</li>
+<li>add parameter [<a href="http://github.com/doxygen/doxygen/commit/c5bc9fc8c407aac845d594b2685d0c92699727d8">view</a>]</li>
+<li>add search.py, a client for doxygen_sqlite3.db [<a href="http://github.com/doxygen/doxygen/commit/697ac97aad7fa045b6cc205050b69cf3f22408ad">view</a>]</li>
+<li>add space between br and / for better compatibility [<a href="http://github.com/doxygen/doxygen/commit/2a40448c3855da250561fa4bac01179311831307">view</a>]</li>
+<li>added option to have numbers in the bookmark pane (PDF output) [<a href="http://github.com/doxygen/doxygen/commit/62cf79095c4d02ff1c737e02f91f8dcea2175b9e">view</a>]</li>
+<li>config.l: dependency checks for booleans [<a href="http://github.com/doxygen/doxygen/commit/5d64c0e2f39730bb5decd86a483a5b0823a67958">view</a>]</li>
+<li>detect python2 as Python 2 binary [<a href="http://github.com/doxygen/doxygen/commit/3754cd80cae41b23dc1069245ad5acdc460b8809">view</a>]</li>
+<li>fixed compile issue on Linux [<a href="http://github.com/doxygen/doxygen/commit/e3c636337323ba6e3f21bf1e8cfe2a899a8890c1">view</a>]</li>
+<li>pass libclang header file location; add paths for Ubuntu's llvm-3.4 [<a href="http://github.com/doxygen/doxygen/commit/2613bf77ccbeee4721a17a8168dead071e41b45e">view</a>]</li>
+<li>sqlite3: SQLITE_TRANSIENTs [<a href="http://github.com/doxygen/doxygen/commit/6f38dd245d56aaa9b6c8e966a4ccebe2f66ceb7d">view</a>]</li>
+<li>sqlite3: add new searches to search.py [<a href="http://github.com/doxygen/doxygen/commit/c99422b0c7919e953811a3a06e18c7cacbacd7c6">view</a>]</li>
+<li>sqlite3: clear bindings on errors and more care with return [<a href="http://github.com/doxygen/doxygen/commit/1a708967ba0c4a5604c1ac7d8f3c8112ec3e7044">view</a>]</li>
+<li>sqlite3: extract more info [<a href="http://github.com/doxygen/doxygen/commit/cd4bdf6708194228434bed1f71d1cd698863aaaf">view</a>]</li>
+<li>sqlite3: fedora has libsqlite3.so in /usr/lib64 [<a href="http://github.com/doxygen/doxygen/commit/49f65d1ee1c9005e019ec95a933ec5fcf02556c9">view</a>]</li>
+<li>sqlite3: leave out insertMemberReference until xref location is valid [<a href="http://github.com/doxygen/doxygen/commit/2349f4b3ff931e334b3d3e09b3e03861a7630f86">view</a>]</li>
+<li>sqlite3: remove some debug messages [<a href="http://github.com/doxygen/doxygen/commit/f76ec80dc8d1d7910951b34582ac25ce6f0efe4d">view</a>]</li>
+<li>sqlite3: speedup the SELECTs [<a href="http://github.com/doxygen/doxygen/commit/d7f9bbedaa4b4fcc0253470d522149a2307d1020">view</a>]</li>
+<li>sqlite3: updates [<a href="http://github.com/doxygen/doxygen/commit/2b80c416671220315a11287b6e10d5b3b2f852cc">view</a>]</li>
+<li>sqlite3: use the new qtools API [<a href="http://github.com/doxygen/doxygen/commit/54fbd99c753e09b1c3850af6b8b4457d339b6e84">view</a>]</li>
+<li>testsqlite3: a test for sqlite3gen [<a href="http://github.com/doxygen/doxygen/commit/733aaaa073a92a316ba888b6992f1172550dd469">view</a>]</li>
+<li>util/patternMatch: break when pattern is found [<a href="http://github.com/doxygen/doxygen/commit/6d8c3184fadb1834223236b13471797089e4a004">view</a>]</li>
+<li>util/patternMatch: don't extract a QCString(QFileInfo) each time we QRegExp.match [<a href="http://github.com/doxygen/doxygen/commit/8991d11cc824f40c11a28ccc38c09e9b10f722c3">view</a>]</li>
+</ul>
+\endhtmlonly
+
+\subsection log_1_8_6 Release 1.8.6
+\htmlonly
+<b>(release date 24-12-2013)</b>
+<a name="1.8.6"></a>
+<h3>Bug fixes</h3>
+<ul>
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=154880">154880</a> - if "using namespace" used, call of a static member function in C++ is not recognized or recognized wrong
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=647517">647517</a> - make install prepends a slash to the installation path Removed superfluous /
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668424">668424</a> - HTML links in RTF output are broken
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=683897">683897</a> - class list not sorted?
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692004">692004</a> - show includes for free functions
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693537">693537</a> - Create possibility to keep user comments in Doxyfile
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701949">701949</a> - Latex: Hyperlinks for \secreflist / \refitem
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702265">702265</a> - Generated Doxyfile differs from result of doxygen -u (partial fix)
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705910">705910</a> - Indexing and searching cannot treat non ASCII identifiers
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706520">706520</a> - Fortran: in body documentation lands on wrong place In some cases, in propriety code, with in body Fortran documentation doxygen crashed. I REOPENED Bug_706520 for this
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706804">706804</a> - Fortran: Doxygen mixes up function-attributes with the return type test string should not be equal to "function" but should contain "function"
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706813">706813</a> - RPM build via spec file fails
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706874">706874</a> - Doxygen crash if missing new-line in a snippet
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706916">706916</a> - C++ exception specifications are no longer parsed correctly
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707102">707102</a> - update the Japanese translation
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707353">707353</a> - Accept IDs using unicode(non ASCII) characters in python codes
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707389">707389</a> - GENERATE_TREEVIEW=YES disables touch scrolling with Android 3.x
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707431">707431</a> - Cannot @ref or @link C++ operator overloads
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707483">707483</a> - Wrong page number and header in pdf output
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707554">707554</a> - When I use @INCLUDE DoxyWizard is closed Current directory was not changed at the right time so the include files could not be found in the "current" directory (i.e. the directory where the Doxyfile resides too, as this directory is shown as the current directory in the doxywizard). This is also important when the doxywizard is started from a shortcut.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707567">707567</a> - Asterisks in comment wrongly displayed for @code
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707641">707641</a> - `FILTER_SOURCE_FILES=YES` required to build CALL_GRAPHS https://bugzilla.gnome.org/show_bug.cgi?id=707641
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707685">707685</a> - Fortran: error message when missing last EOL In case the original buffer in either fixed or free format code does not contain an EOL as last character, add it.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707713">707713</a> - Add support for dia diagrams
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707825">707825</a> - Const treatment
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707925">707925</a> - False warning for Java "warning: missing ( in exception list on member"
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707985">707985</a> - Strange output when : appended to an parameter description
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=707995">707995</a> - @copydoc not working for const member overloads
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=708446">708446</a> - Deprecated list breaks HTML tree with xhtml extension
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=708455">708455</a> - Enabling INLINE_SIMPLE_STRUCTS messes up Data Structures in tree
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=708806">708806</a> - Wrong path to graph_legend figure in graph_legend.html when CREATE_SUBDIRS = YES
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709052">709052</a> - Templated and non-templated method mixup documentation
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709226">709226</a> - Struct member fields not documented with INLINE_SIMPLE_STRUCTS
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709526">709526</a> - C++ parsing problem with operators <<, <, >, >> inside templates
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709706">709706</a> - Terminating C comments within markdown files breaks aliases
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709780">709780</a> - Copying of files via \image tag can get confused by symlinks at the destination
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709803">709803</a> - Generated hhc file contains an error for a section of a mainpage
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709845">709845</a> - Fortran: problem with types with name starting with is
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709870">709870</a> - Broken links on members HTML page when using BUILTIN_STL_SUPPORT
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=709921">709921</a> - position of linebreak in template argument list affects inheritance relation
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=710917">710917</a> - Segfault while parsing a C file
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=710998">710998</a> - latex_count=5 is not enough
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711004">711004</a> - Vertical bars cannot be sent straight to makeindex
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711097">711097</a> - Compiler warnings because char is unsigned on ARM/PPC: "comparison is always false"
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711378">711378</a> - Nested Aliases fail when the nested alias has two or more arguments.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711639">711639</a> - [PATCH] #include does not work with absolute paths
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711723">711723</a> - Comment /**/ confuses doxygen
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=711787">711787</a> - Long initialization line in C stops doxygen An extra "breakpoint" in the input string has been created in the form of a , (comma), so for initialization lines the line will be shorter and the , (comma) will be copied later on.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=712795">712795</a> - segmentation fault in memberdef.cpp
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=712819">712819</a> - Some external namespaces appear in list despite having ALLEXTERNALS = NO
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=715172">715172</a> - Consistently document Fortran's equivalent function bodies
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719389">719389</a> - HTML escaping incorrectly applied in source tooltips
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719422">719422</a> - private java class is mentioned in inherited by list of super class
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719463">719463</a> - Invalid null key and segmentation fault
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719489">719489</a> - Label "abstract" instead of "pure virtual" for Java language
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719525">719525</a> - Can't build because the definitions of ***YY_flex_debug are missing.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719591">719591</a> - expand_as_defined macro does not properly work
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=719639">719639</a> - @xrefitem with empty heading string
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=720046">720046</a> - Document inline objective-C blocks
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=720092">720092</a> - USE_MDFILE_AS_MAINPAGE doesn't work if full path is specified.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=720580">720580</a> - inline source browser shows wrong code with muilti-line c++11's raw strings
+<li> Add support for honoring svg image format preference in msc
+<li> Added @parblock and @endparblock commands
+<li> Added compile support for Mavericks
+<li> Added fix to avoid errors with older compilers.
+<li> Added generated files to gitignore
+<li> Added missing docs tag
+<li> Added missing pthread lib to doxyapp
+<li> Added missing space after @parblock
+<li> Added rudimentary support for Django like template system for output creation.
+<li> Added the possibility to specify the -d option in the Visual studio GUI on windows for the lex rules
+<li> Adjust internationalization part to current situation
+<li> Alignment of @code and @verbatim section When having a code and a verbatim section the boxes are not alligned, this patch fixes this. Example code, aa.c; standard Doxyfile: /** \file
+<li> Allow @ref to unlabeled markdown page by name, i.e. @ref mypage.md
+<li> Allow links to other markdown pages of the form [link text](page.md)
+<li> Avoid accessing uninitialized memory in fileToString
+<li> Build problem with unistd.h and Cygwin The standard g++ compiler under windows (win32-g++) has unistd.gh file; Microsoft windows does not have it, therfore it is better to use the winbuild directory in case of windows adn no dependency otherwise
+<li> Consistency in language part of the documentation Made documentation more inline with other parts of the documentation (regarding the way e.g. filenames are presented) Corrected some spelling errors Corrected the warning in the language.doc by placing ta reference to the files from which language.doc is generated Corrected the color for the languages that are still v1.4.6 (language name now also red in stead of a pink background, was confusing with languages that were 1.5 / 1.6 com [...]
+<li> Corrected some inconsistencies in the comments
+<li> Debug output for lexical analyzer
+<li> Deleted generated files from source repository
+<li> Doxygen didn't allow @ref to parameters of type reference to an array.
+<li> Doxysearch under Cygwin should not have extension cgi.exe but just .cgi
+<li> Esperanto not supported by htmlhelp compiler reverting for esperanto to default language (US English)
+<li> Fixed a number of compiler warnings reported by newer clang compiler
+<li> Fixed compilation issues in doxyapp
+<li> Fixed compile warning
+<li> Fixed compiler warning related to implicit size_t to int conversion
+<li> Fixed constness warning
+<li> Fixed invalid if statement found by cppcheck
+<li> Fixed issue with Romanian translator preventing treeview from working
+<li> Fixed regression autolinking C# template such as MyGenericClass<T>.g()
+<li> Fixed regression in argument matching for the template example
+<li> Fortran added keyword IMPURE
+<li> French translator up-to-date.
+<li> Internal documentation for debug possibilities Documentation regarding usage of -d option with [f]lex Initial documentation regarding the -d options with doxygen
+<li> LaTeX: Fix ToC entries of index/bibliography
+<li> Made lexer rule explicit
+<li> Make Python detection in configure work with version older than 2.7
+<li> Minor layout tweaks and extra guard
+<li> More fixes for the Windows build
+<li> Patch regarding generating the rules file for the windows build regarding languages, some inconsistencies in the (windows) build system, corrections to some spelling.
+<li> Regenerated language.doc
+<li> Removed japanese characters in maintainers.txt as they break the build
+<li> Removed redundant backslashes in regexp pattern
+<li> Report details about fork() failure in logs.
+<li> Russian translator updated, new Russian maintainer added.
+<li> Small spelling correction to generate an rtf extensions file -> to generate a rtf extensions file
+<li> Some texts can be independent of \htmlonly / \latexonly
+<li> Space missing in error message. the word 'in' and the vale of filesOption were concatenated
+<li> This patch contains changes regarding the build system so that the *nix and Windows systems use the same information (consistency). Some use names routine names have been changed (from .l files with -P option) to reflect the file name that generated the routines, this makes it easier to create a general procedure. A number of include / header files are files are generated from different file types (html, xml, js), due some limitations of the windows build system the generated file n [...]
+<li> Updated Visual Studio project files to include new source files
+<li> Usage of the -d opion corrected Giving an error when a wrong -d option is given. Made some error mesages more consistent. Corrected usage of the exit call, in case of an error: exit(1) otherwise exit(0). A closer look should be made on exitDoxygen as it does not contain any exit statements and it is unclear (to me) when it is used.
+<li> VHDL-2008 and arrays on unconstrained elements
+<li> consider currentFile when searching for global symbols
+<li> doc/language.doc generated from the updated sources (bgcolored)
+<li> doc/language.tpl -- UTF-8 reflected in the langhowto template
+<li> doc/language.tpl -- trailing spaces removed
+<li> doc/translator.py -- coloured status in HTML
+<li> doxygen /** style creates spurious code blocks with markdown enabled
+<li> doxygen version 1.8.5 throws many "Internal Inconsistency" errors when parsing .idl files
+<li> doxygen.sty.h was not ignored and not included/generated properly
+<li> testing dir was missing from 'make archive'
+<li> usage: make -d print dev doxygen options
+</ul>
+\endhtmlonly
+
+\subsection log_1_8_5 Release 1.8.5
+\htmlonly
+<b>(release date 23-08-2013)</b>
+<a name="1.8.5"></a>
+<h3>Changes</h3>
+<ul>
+<li>Doxygen's source code is now managed using git and GitHub. Automatic builds
+ and regression tests are scheduled via Travis CI.
+<li>Configuration data for the config file, the documentation, and the wizard
+ are now produced from a single source (thanks to Albert)
+<li>All translation files have been migrated to UTF-8 (thanks to Petr Prikryl)
+<li>Added black box testing framework and a set of tests.
+</ul>
+<h3>New features</h3>
+<ul>
+<li>Added SOURCE_TOOLTIPS option for advanced tooltip support while source browsing.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668007">668007</a> - HTML commands - documentation of </dd> tag missing
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676879">676879</a> - parameter on doxywizard manual Added sentenc in respect to possible argument for doxywizard Added images to the LaTex / pdf version of the manual
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=684324">684324</a> - Strange behavior when placing cite within brief.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688858">688858</a> - SHORT_NAMES break references to \page in PDF output
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691315">691315</a> - Line breaks are not copied/displayed properly when using @copydoc.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691830">691830</a> - Logical confusion with DISABLE_INDEX and GENERATE_TREEVIEW
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694147">694147</a> - #undef is ignored by doxygen
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=698998">698998</a> - vhdldocgen fails to generate proper latex for VHDL record type
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700385">700385</a> - Incorrectly parsed Q_PROPERTY with 'unsigned int' type
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700646">700646</a> - XML output does not handle HTML entities in titles
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700693">700693</a> - Duplicate entry for class template member function with no parameter
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700696">700696</a> - Template static member functions duplicated as non-static public
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700709">700709</a> - typedef warning when "using" some operator functions
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700710">700710</a> - Docbook output produces invalid XML for <programlisting> elements
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700740">700740</a> - Doxygen does not create links on C++ 11 style enum classes
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700788">700788</a> - support @cite within brief description.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700908">700908</a> - code after \@cond is removed
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701295">701295</a> - Doxygen 1.8.4 goes into an endless loop
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701314">701314</a> - URLs are not created on C# classes in some cases
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701550">701550</a> - Error List window in Visual Studio no longer recognizes doxygen warnings
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701771">701771</a> - EXPAND_AS_DEFINED not working with some project structures
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=701919">701919</a> - VHDL cross-references fail when unpaired apostrophe present
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702066">702066</a> - VHDL: Bad HTML formatting when using inline sources
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702170">702170</a> - Missing space before optional option in method argument list
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702189">702189</a> - Markdown and @image
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702491">702491</a> - UTF-16LE BOM not handled by source browser and \snippet
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702590">702590</a> - Crash with TAB_SIZE=-1
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=702676">702676</a> - Closing ) of function in function documentation is in wrong color
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703574">703574</a> - Add configure options to enable static SQLite and non-standard SQLite
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703112">703112</a> - Backward documentation comments are not allowed in Fortran type-bound procedures
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703133">703133</a> - "operator--()" transformed to "operator–()" in @copydoc
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703170">703170</a> - Segmentation fault parsing a fortran file
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703213">703213</a> - Can't use @ref instead of \ref with msc
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703301">703301</a> - Misleading warning about DOT font
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=703791">703791</a> - Out-of-line docs for class template specialisations failing
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=704079">704079</a> - Generated XML is malformed
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=704172">704172</a> - Nested Aliases fail when the nested alias has two or more arguments.
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=704412">704412</a> - doxygen don't hide private Inherited Members
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=704971">704971</a> - Can't build with MinGW
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=704973">704973</a> - Doxywizard can't show file names using non-ASCII(Unicode)
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705190">705190</a> - Incorrectly parsed Q_PROPERTY with 'long long' or 'long int' type
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705217">705217</a> - Can't use unicode characters to execute external commands
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705218">705218</a> - QRegExp doesn't work with 80-FF
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705219">705219</a> - Accept IDs using unicode for C/C++ preprocessor
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705586">705586</a> - @code tag as the last line of a comment block causes the parser to hang
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=705702">705702</a> - Post-comment blocks on C++11 using definitions attach to following entity
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706236">706236</a> - Confusing use of GENERATE_TAGFILE
+<li> Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=706520">706520</a> - Fortran: in body documentation lands on wrong place
+<li> Small typo correceted in doxywizard_usage.doc Generated config.doc file in git is not identical to the generated one
+<li> Various improvements to the (still experimental) sqlite3 support (thanks to Adrian Negreanu)
+<li> jquery: use the env MINIFIER if specified
+<li> Some words now in code style __attribute__ was seen (markdown) as the bold word attribute Reformulation of a sentence due to a not nice split of word (__declspec was split directly after __ in pdf)
+<li> Extended list with supported options for automatic link generation
+<li> Added -v option (analogous to --version). In case option started with -- and is not a known valuue (help or version) and error is given instead of starting Doxygen
+<li> Fixed regression when nested class were processed before their parent
+<li> Minor changes to the way the code for config options is generated (thanks to Albert for the patch)
+<li> Brief description did not appear in the page index, when a page did not have any details.
+<li> Using & in the project name caused invalid HTML and LaTeX output
+<li> Fixed regression caused by the patch for bug 705219
+<li> Fixed issue running dot on files with non-ascii characters
+<li> Delayed expanding the HTML navigation tree until after the page has loaded
+<li> Made some fixed to the configure script for Cygwin (thanks to David Stacey)
+<li> config.xml is now used to generate configoptions.cpp and config.doc
+<li> Fixed whitespace issue when using \overload without arguments
+<li> Avoid space in the output after \n command following by a newline.
+<li> Fixed problem handling C comments inside a \code block.
+<li> Improved handling of \internal and \endinternal
+<li> Removed extra newline when reading in an input file
+<li> Make XML output adhere to MAX_INITIALIZER_LINES
+<li> Fixed issue handling \elseif after \ifnot
+<li> Fixed regression that could cause double nested classes
+<li> Fixed issue handling \docbookonly..\enddocbookonly section
+<li> The language specifier in e.g. \code{.py} was ignored for the XML output
+<li> Fix reference to scoped enum imported via a tag file.
+<li> Replaced utf8 character that broke latex compilation of the manual
+<li> Fixed unused parameter warnings
+<li> Add support for writing and importing C++11 style enums to and from tag files
+<li> Fixed regression introduced by fixed bug Bug <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700740">700740</a>
+<li> Fixed type in function name
+<li> Remove some unneeded and still enabled debug info
+<li> Included fix for "Constant Groups" regression on file pages (thanks to Michael Stahl)
+<li> Add scopes to Fortran prototype name parsing (thanks to Oleg Batrashev).
+<li> Prototype scan for function, does not yet catch parameter types (thanks to Oleg Batrashev).
+</ul>
+\endhtmlonly
+
+\subsection log_1_8_4 Release 1.8.4
+\htmlonly
+<b>(release date 19-05-2013)</b>
+<a name="1.8.4"></a>
+<h3>Changes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686384">686384</a>: When INLINE_SIMPLE_STRUCTS is enabled, also structs with
+ simple typedefs will be inlined.
+<li> Doxywizard: scrolling with mouse wheel no longer affects the values in
+ the expert view.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681733">681733</a>: More consistent warnings and errors.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added support for "clang assisted parsing", which allows
+ the code to also be parsed via libclang (C/C++ frontend of LLVM)
+ and can improve the quality of the syntax highting, cross-references,
+ and call graphs, especially for template heavy C++ code. To enable
+ this feature you have to configure doxygen with the --with-libclang
+ option. Then you get two new configuration options: CLANG_ASSISTED_PARSING
+ to enable or disable parsing via clang and CLANG_OPTIONS to pass additional
+ compiler options needed to compile the files. Note that enabling this feature
+ has a significant performance penality.
+<li> Included patch donated by Intel which adds Docbook support.
+ This can be enabled via GENERATE_DOCBOOK and the output location can
+ be controlled using DOCBOOK_OUTPUT. Docbook specific sections can be
+ added using \docbookonly ... \enddocbookonly
+<li> Added support for UNO IDL (interace language used in Open/Libre Office), thanks to
+ Michael Stahl for the patch.
+<li> Included patch by Adrian Negreanu which stores data gathered by
+ doxygen in a sqlite3 database. Currently still work in progress and
+ can only be enabled using --with-sqlite3 during ./configure.
+<li> For interactive SVG graphs, edges are now highlighted when hovered by
+ the mouse.
+<li> Include patch by Adrian Negreanu to show duration statistics after a run.
+ You can enable this by running doxygen with the "-d Time" option.
+<li> Included patch by Markus Geimer which adds a new option
+ LATEX_EXTRA_FILES which works similarily to HTML_EXTRA_FILES in that
+ it copied specified files to the LaTeX output directory.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=698223">698223</a>: Added support for C++11 keyword alignas
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693178">693178</a>: Added support for processing DocSets with Dash (thanks to
+ Bogdan Popescu for the patch
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=684782">684782</a>: Added option EXTERNAL_PAGES which can be used to determine
+ whether or not pages importated via tags will appear under related
+ pages (similar to EXTERNAL_GROUPS).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692227">692227</a>: Added new MathJax command MATHJAX_CODEFILE which supports
+ including a file with MathJax related scripting to be inserted before
+ the MathJax script is loaded. Thanks to Albert for the patch.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693537">693537</a>: Comments in the config file starting with ## will now be
+ kept when upgrading the file with doxygen -u (and doxygen -s -u).
+ Thanks to Albert for the patch.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693422">693422</a>: Adds support for Latvian (thanks to a patch by Lauris).
+<li> Included language updates for Ukrainian, Romanian, and Korean
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=145294">145294</a>: Fixed parse issue when using less than inside a template
+ argument.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=325266">325266</a> man page output was missing a linebreak before .SH when
+ definition a group with a section.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=338205">338205</a>: @anchor were wrong when CREATE_SUBDIRS was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=427012">427012</a>: Putting a @todo in front of an anonoymous namespace caused
+ bogus entry in the todo list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=564462">564462</a>: Fixed alignment issue with tabs and multibyte characters.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=567542">567542</a>: Character entities in titles were not rendered correctly
+ in the HTML navigation tree.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=571561">571561</a>: No space between * and tag (e.g. \endcode) made parser
+ misbehave
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=583233">583233</a>: Included patch to limit generated Doxyfile comments to 80
+ columns
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592626">592626</a>: Fixed off-by-one with MAX_DOT_GRAPH_DEPTH.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=619790">619790</a>: Improved linking to template specializations.
+ Thanks to David Haney for the patch.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=627712">627712</a>: Doxygen Header in C Files makes empty Lines in HTML Source
+ Code when starts in Line 1
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=639954">639954</a>: Fortran: array constructors with brackets were not correctly
+ recognized.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646428">646428</a>: The generated man pages had a .PP just before the subject
+ description
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646431">646431</a>: On generated manpages the return section is incorrectly
+ indented
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=650004">650004</a>: use \page now generates a man page were the . is not
+ replaced by _8.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=657704">657704</a>: Fixed issue with PROJECT_LOGO when using backslashes in
+ the path.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666008">666008</a>: Fortran: Using @var at module levele didn't work.
+ expect a file/path name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673218">673218</a>: Replaced "echo -n" with "printf" in the configure script.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674856">674856</a>: Removed warning when using \endinternal
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=675607">675607</a>: Added &, @, and # as allowed characters for commands that
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679626">679626</a>: Included patch by Abert to correctly link pages in the manual
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681874">681874</a>: Added support for single column Markdown tables.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682369">682369</a>: Incomplete documentation on doxygen -w latex
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=683516">683516</a>: Doxygen crashed when structural commands (like \var) appeared
+ in .md files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686259">686259</a>: Fixed character encoding problem when multibytes characters
+ were used in anchors.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691071">691071</a>: Documentation before an anonymous member did not appear.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692162">692162</a>: Fixed Markdown related indentation problem.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692320">692320</a>: Regression: Text after @copydoc was not visible anymore.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692537">692537</a>: Linked to external pages was done using the page label
+ rather than the file name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693331">693331</a>: build using ./configure ; make did not work if the path
+ contained a space.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=693406">693406</a>: Tag files are now identfied by the full path instead of
+ only the name of the tag file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694376">694376</a>: In some cases members were missing from the tag file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694027">694027</a>: Fortran: derive intent from documentation in case no
+ intent is specified
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694610">694610</a>: Warning was not reported at the correct line in two cases.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694631">694631</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694632">694632</a>: @cond.. at endcond did not work properly for removing
+ macro definitions.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694685">694685</a>: Fixed crash when adding two different functions with the
+ same name to the same group.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=694726">694726</a>: VHDL: fixed issue generating LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=695277">695277</a>: Fortran: improved handling of protected statement
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=695974">695974</a>: Fortran: Fixed issue resulting in
+ "Stack buffers nested too deeply" error.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=696708">696708</a>: @cond was not handled properly by the preprocessor.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=697233">697233</a>: @copyright command did not end a brief description.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=697249">697249</a>: Markdown tables caused errors reported at wrong line number.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=697494">697494</a>: Removed double entry from the messages produced by doxygen.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=698818">698818</a>: Fixed problem handling @cond for #define's
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=698007">698007</a>: Fixed potential crash when searching files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=696925">696925</a>: #include's inside namespace could result in duplicate entries.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=696954">696954</a>: Doxywizard: Labels of items are now also grayed out
+ when an item is disabled (thanks to Albert for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699195">699195</a>: Changed Markdown page label to support multiple .md files
+ with the same name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699218">699218</a>: Fixed issue with margin computation in resize.js.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699381">699381</a>: Lonely h4,h5,h6 end tag caused assert.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699437">699437</a>: Trailing comments were not always rendered properly if
+ MARKDOWN_SUPPORT was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699460">699460</a>: Updated doxygen man page (thanks to Manuel for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699464">699464</a>: Added reference to \xmlonly and \docbookonly in \htmlonly
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699731">699731</a>: LaTeX: switch to using the xtabular package instead of
+ longtable to prevent overfull vbox errors.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=699732">699732</a>: Template parameters and Exceptions were rendered differently
+ than Parameters and Return Values in the LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700153">700153</a>: Tcl: Fixed crash when parsing certain Tcl code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700345">700345</a>: Comment blocking ending with ///// made slashes appear in
+ the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=700456">700456</a>: Added support for separating auto list items with an
+ empty paragraph.
+<li> Included a couple of VHDL fixes (thanks to Martin Kreis for the patch)
+<li> \include and \includelineno both showed line numbers.
+<li> Putting '// @endverbatim' inside a C comment block was not handled
+ properly by the preprocessor.
+<li> Fixed various typo's in the manual and improved cross referencing
+ (thanks to Albert and Guillem Jover for their help)
+<li> Added a couple of missing configuration dependencies.
+</ul>
+\endhtmlonly
+
+\subsection log_1_8_3_1 Release 1.8.3.1
+\htmlonly
+<b>(release date 20-01-2013)</b>
+<a name="1.8.3.1"></a>
+<h3>Changes</h3>
+<ul>
+<li> Changed to way the search results for multiple projects can be linked
+ together. A project is now no longer identified by the tag files name but
+ via new option EXTERNAL_SEARCH_ID giving a bit more flexibility.
+<li> Disabled the disk cache for member data. Allows removing quite some complexity
+ in doxygen and is not really needed now that 64bit systems with >4GB RAM
+ are becoming more common. Let me know if you think you benefit from this caching.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691607">691607</a>: Using $relpath$ in a custom footer could lead to ambiguities
+ when followed by a name that could also be a marker, like 'search'.
+ Now $relpath^ should be used instead. $relpath$ is still supported for
+ backward compatibility.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> You can now use EXTENSION_MAPPING on files without any extension using
+ no_extension as placeholder (thanks to Jason Majors for the patch).
+<li> To make navindex section inside a layout file that links to
+ a specific URL you can use usergroup with the url attribute.
+<li> To make navindex section without any link inside a layout file you
+ can use usergroup with special title [none].
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=644350">644350</a>: Fortran: Included patch to improve parsing line continuation
+ characters.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=645423">645423</a>: Fortran: added support for protected attribute
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682550">682550</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691315">691315</a>: When using @copydoc, paragraphs breaks did not appear
+ in the copied documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686581">686581</a>: Fortran: handle single quotes in normal Fortran comment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686689">686689</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691335">691335</a>: Scope of forwardly declared template class was lost
+ in the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=689713">689713</a>: Tcl: Inline source code was not rendered correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690787">690787</a>: Fixed case were a cyclic inheritance relation could crash
+ doxygen.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690831">690831</a>: Using @subpage in a -# style list was not handled properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691000">691000</a>: For a mainpage without title the project name is now shown as
+ the title in the XML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691277">691277</a>: The generated list of citations is now no longer included in
+ the tag file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691073">691073</a>: Documenting strongly typed enum values outside of the enum
+ did not work.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691310">691310</a>: Python: = was missing in the output for variable assignment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691323">691323</a>: Doxygen could crash when creating inline msc graphs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691340">691340</a>: Members didn't have a More.. link to jump to detailed docs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691602">691602</a>: Doxygen did not probably distinguish between two template
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=691798">691798</a>: regression: C++ style comments that started with a line of
+ slashes did not get processed correctly anymore.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=692031">692031</a>: Fixed parse error when left shift operator occurred as a
+ default parameter.
+ members or functions that only differ in the return type.
+<li> Setting SEARCH_INCLUDES to NO resulted in no include graphs and no
+ include files being listed in the output.
+<li> Improved support for MinGW (thanks to a patch by Brecht Sanders).
+<li> Removed the Graphviz/dot dependency when building the doxygen
+ documentation.
+<li> Anchors to sub pages were wrong in the XML output.
+<li> Included VHDL patch by Martin Kreis that improves the flow chart
+ generation.
+<li> corrected several code pages and fontsets for proper RTF output for
+ a number of languages such as Greek.
+</ul>
+\endhtmlonly
+\subsection log_1_8_3 Release 1.8.3
+\htmlonly
+<a name="1.8.3"></a>
+<b>(release date 26-12-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> Expanding the tree in an index page of the HTML output, will now
+ expand only one level instead of the whole sub-tree (thanks to
+ Pez Cuckow for the patch).
+<li> A blockquote in Markdown does no longer require a whitespace
+ after the last '>' if the '>' is followed by a newline.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682718">682718</a>: Included patch to add version info to all generated
+ template files (headers, footers, stylesheets, layout files, etc).
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added support for using external tools to index and search through
+ the HTML documentation. An example index tool is provided (doxyindexer)
+ and an example search engine (doxysearch.cgi).
+ To configure the external search engine the following new options
+ are added to the configuration file: EXTERNAL_SEARCH (to enable the
+ feature), SEARCHENGINE_URL (to specify the URL of the search engine),
+ SEARCHDATA_FILE (to specify the name of the raw search data to index),
+ EXTRA_SEARCH_MAPPINGS (for search through multiple projects).
+ See the <a href="extsearch.html">manual</a> for details.
+<li> Added USE_MDFILE_AS_MAINPAGE config option to select a markdown page to
+ be used as the main page.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=630645">630645</a>: This patch (contributed by Albert) adds support for
+ simple logic expressions for \cond, \if, and friends, i.e. you can do
+ \if (SOME_SECTION_NAME && (!THIS_ALTERNATIVE || THAT_ALTERNATIVE))
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=684152">684152</a>: Patch (contributed by Albert) adds a new configuration
+ option MATHJAX_FORMAT to select the MathJax output format. Options are
+ HTML-CSS, NativeMML, or SVG.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670853">670853</a>: Fixed compile issues with 0 to QCString cast for
+ old compilers.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678139">678139</a>: A class A deriving from another class B inside a namespace
+ not known to doxygen, caused class B to appear in the global scope.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681209">681209</a>: Fixed problem processing .bib files when they were located
+ in a path containing spaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681830">681830</a>: Using \addindex in a page will now produce a link to the
+ word, instead of the start of the page.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681831">681831</a>: The TREEVIEW_WIDTH option did not have any effect.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681898">681898</a>: Jumping from a level 3 section to a level 1 section did
+ not appear correctly in the page TOC.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681976">681976</a>: C++11: Improved handling of noexcept expressions, e.g.:
+ <code>Test() noexcept ( noexcept(T::T()) ) = default;</code>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682048">682048</a>: Improved SIGINT handling when running multiple dot instances.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682602">682602</a>: Fixed problem processing .bib files when using a non default
+ output directory.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682713">682713</a>: Comment for IDL_PROPERTY_SUPPORT in the config file template
+ did not have line wrapping.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682728">682728</a>: Setting SHOW_FILES to NO prevented call graphs from being
+ generated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=682740">682740</a>: Fortran: In initialization statement the "=" was missing
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=683284">683284</a>: Fortran: ALIASes where not replaced in !! and !< comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=683976">683976</a>: Added meta tag "generator" to HTML output (thanks to
+ Albert for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=684781">684781</a>: Sections of the main page did not appear in the
+ navigation tree until the main page had sub pages.
+ Also fixed bug in treeview that caused mainpage with title and
+ sections to appear at the same level as the sections.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=685125">685125</a>: Doxygen could select the wrong overloaded method when
+ the only difference in parameter types was the template type of
+ a typedef.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=685181">685181</a>: Inheriting member documentation did not work in combination
+ with Java interfaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=685623">685623</a>: Enum values did not appear in the detailed documentation
+ when using C++11 style enums.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=685879">685879</a>: Even though HIDE_UNDOC_MEMBERS was enabled, the navigation
+ still showed undocumented members.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=685940">685940</a>: Fixed back button behaviour when using the navigation tree.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686284">686284</a>: Added anchors to refs in the index.qhp TOC.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686826">686826</a>: Added XML declaration to index.qhp TOC.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686956">686956</a>: When a class and its base class has the same nested class,
+ the collaboration diagram could point to the wrong class.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=686983">686983</a>: Comments inside a function macro parameter appeared before
+ the expanded macro, instead of being treated as part of the parameter.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=687301">687301</a>: Allow minus in the name of a HTML attribute.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=687572">687572</a>: Code fragments were wrapped too early in the latex output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688226">688226</a>: Fixed Qt version number in ./configure --help text.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688463">688463</a>: Included patch to prevent processing identifiers starting
+ with _ or __ as markdown.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688531">688531</a>: Horizontal ruler inside paragraph caused missing </p>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688542">688542</a>: Using "usergroup" in the layout.xml caused missing <div>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688739">688739</a>: Fixed problem with user defined entries in the eclipse help
+ index (thanks to Rene Papenhoven for the fix).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=688647">688647</a>: Fixed problem parsing initializer list with C++11 style
+ uniform types.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=689341">689341</a>: \if around list item preceded by whitespace caused wrong
+ list in the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=689461">689461</a>: Correct link in documentation of SIP_SUPPORT option.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=689720">689720</a>: Fixed bug that could prevent refman.tex from being generated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=689833">689833</a>: Fixed missing space in Chinese translation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690093">690093</a>: Files added via HTML_EXTRA_STYLESHEET did not correct refer
+ to files that where placed in a subdirectory.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690190">690190</a>: Searching for multibyte characters did not work with the
+ server based search engine.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690250">690250</a>: Fixed case where line numbers got out of sync with the code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690341">690341</a>: First member of an anonymous C++11 style enum was not shown
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690385">690385</a>: Fixed case where _'s where falsely converted to Markdown
+ emphasis.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690403">690403</a>: Title not used when \ref'ing to a \section imported via
+ a tag file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690418">690418</a>: Behavior of @cond was accidentally reversed by new expression
+ parser.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690602">690602</a>: Fixed problems handling @cond inside /// comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690629">690629</a>: Fixed case where doxygen would during preprocessing.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=690685">690685</a>: A file specified using HTML_EXTRA_STYLEHSHEET did not end
+ up in the Qt Help index.
+<li> Improved the way enum's are rendered in the HTML output.
+<li> When inlining structs (INLINE_SIMPLE_STRUCTS=YES) a <p> was missing
+ for members with a detailed description, causing invalid XHTML.
+<li> Fixed problem loading the navigation tree when using .xhtml as the
+ file extension.
+<li> The navigation tree was not always correctly positioned upon initial
+ load when using Chrome.
+<li> HTML Navigation tree showed static members even when EXTRACT_STATIC was
+ set to NO.
+<li> Same word could appear multiple times in the match list for an entry
+ in the search results when using server based search.
+</ul>
+\endhtmlonly
+\subsection log_1_8_2 Release 1.8.2
+\htmlonly
+<a name="1.8.2"></a>
+<b>(release date 11-08-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> Using a fenched block (~~~~) in Markdown without explicit extension will
+ now be interpreted as a @code.. at endcode block instead
+ of @verbatim.. at endverbatim.
+<li> Classes inheriting from an class that is outside the scope of doxygen
+ are still shown in diagrams. This does not hold for usage relations.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added support for C++11:
+ <ul>
+ <li> strongly typed enums, e.g.:
+ <pre>enum class E</pre>
+ <li> enums with explicit type, e.g.:
+ <pre>enum E : unsigned int { ... }</pre>
+ <li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678097">678097</a>: added support for final keyword on classes and methods.
+ <li> support for override keyword for methods.
+ <li> <code>nullptr</code> is new a type keyword in code fragments.
+ <li> support for variables with initializer lists,
+ e.g.: <pre>const int var {10};</pre>
+ <li> support for trailing return types,
+ e.g.: <pre>auto foo() -> Bar;</pre>
+ <li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672372">672372</a>: added support for template aliases,
+ e.g.: <pre>template<typename T> using A = B<T>;</pre>
+ <li> support for C++11 variadic templates,
+ e.g.: <pre>template<typename... Values> class C;</pre>
+ <li> support for documenting template class declarations.
+ <li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680098">680098</a>: <code>static_assert(...);</code> inside a class is now ignored.
+ <li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679740">679740</a>: Add support parameters with default lambda functions,
+ e.g.: <pre>int foo(int i, std::function<int(int)> f = [](int x) -> int { return x / 2; })</pre>
+ <li> default initializers for non-static data members,
+ e.g.: <pre>class C { public: int x = 4; int y {6}; int z = y*func(); };</pre>
+ <li> support for decltype as a way selecting a type for a variable,
+ e.g.: <pre>int x; decltype(x) y;</pre>
+ <li> support for new string literals,
+ e.g. <pre>u8"utf8", u"utf-16", U"utf-32", L"wchar"</pre>
+ <li> support for raw string literals (with and without user defined
+ delimiter),
+ e.g. <pre>R"(some"thing)", u8R"raw(some)"thing)raw"</pre>
+ <li> support for explictly deleted and defaulted special members
+ (<code>=default</code> and <code>=delete</code>).
+ </ul>
+<li> Made several improvements to the way Objective-C categories and protocols
+ are handled:
+ <ul>
+ <li> Class extensions are now treated as part of the class, whereas
+ categories are listed separately.
+ <li> Fixed parse problem where category had a { } section.
+ <li> Fixed parse problem for categories that implemented protocols.
+ <li> Fixed render bug for protocols in class diagrams.
+ <li> Attributes with the same name as a method are now no longer matched.
+ <li> Internal properties are now also marked with [implementation]
+ <li> Members of categories are shown in the class they extend as well, and
+ cross reference links are made between these members.
+ <li> Class extension implementing protocols are now shown as protocols
+ inherited by the class itself, including the "Implemented by" relation.
+ </ul>
+<li> Added option HTML_EXTRA_STYLESHEET which allows adding an additional
+ stylesheet without completely replacing doxygen.css.
+<li> Added option AUTOLINK_SUPPORT which can be used to enable/disable
+ autolinking globally.
+<li> Included language updates for Czech, Spanish, Greek, Slovak, and
+ Esparanto.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Fixed render glitch where template member of a base class was not
+ properly hidden in the derived class.
+<li> Privately nested classes no longer appear in the declaration section
+ of their parent if EXTRACT_PRIVATE is disabled.
+<li> In the declaration section the separator line was in between the
+ member and its brief description.
+<li> Fixed a couple of compiler warning with the new XCode 4.4 compiler.
+<li> Added compilation support for Mountain Lion (Mac OS X 10.8).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679631">679631</a>: Nested namespaces did not appear in the namespace list if the
+ parent namespace was undocumented.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680227">680227</a>: Fixed some spelling errors in the code comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680398">680398</a>: Fortran: comma at begin of argument list description in
+ case of implicit type
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680405">680405</a>: Fortran: Entities on line with USE, ONLY were not hyperlinked
+ in code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680408">680408</a>: Fortran: handle carriage return in non terminated strings.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680492">680492</a>: Using Markdown formatting in @todo/@bug/.. like descriptions
+ did not work.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680575">680575</a>: Fixed potential crash when <code> appeared inside <summary>
+ for C# code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680697">680697</a>: \xrefitems of the same type are not grouped together under
+ the same heading (just like \todo and friends).
+<li> Fixed case where full directory path was shown even though
+ FULL_PATH_NAMES was set to NO.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680709">680709</a>: HTML output of template-derived classes contained unescaped
+ characters.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679963">679963</a>: "Class Index" appeared twice in the PDF TOC, Index at the
+ end did not appear at all.
+<li> In a declaration no link was created when referring to a class inside
+ an undocumented namespace imported via a tag file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681281">681281</a>: Make default for TAB_SIZE 4 and added remark in Markdown
+ section of the manual about the effect of TAB_SIZE on code block
+ processing when using tabs in the comment block.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681023">681023</a>: Project logo was not included in the Qt help output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=680992">680992</a>: Fixed a couple of typos in the comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=681350">681350</a>: Fixed a problem with Markdown processing of a @code block
+ inside an indented /// style comment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679928">679928</a>: Disabled section level correction for Markdown pages as
+ is was confusing.
+</ul>
+\endhtmlonly
+\subsection log_1_8_1_2 Release 1.8.1.2
+\htmlonly
+<a name="1.8.1.2"></a>
+<b>(release date 12-07-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> doxygen now strips the leading indentation shared by the lines in a
+ @code.. at endcode block.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678218">678218</a>: Changed title of the SVG graphs from 'G' to the root node
+ of the graph.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added button in the navigation tree to allow enabling/disabling
+ syncing the navigation tree with the content.
+<li> Extended the number of HTML entities with Greek letters and other
+ symbols (thanks to Charles Karney for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=663645">663645</a>: Added support for C++11 strongly typed enums
+ (enum class E { ... }).
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=590518">590518</a>: Added missing class member initialization to a
+ class in doxmlparser and made the library compile again.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=667678">667678</a>: Added support for Obj-C property attribute "unsafe_retained".
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674842">674842</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676984">676984</a>: Unmatched quote in a comment prevented alias expansion.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676019">676019</a>: Fixed another case where local include path did not appear
+ correctly in the class documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676966">676966</a>: Fortran: Some keyword were not colored in the source view.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676981">676981</a>: Fortran: Argument type was wrong type of in case of out of
+ place !> comment
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677935">677935</a>: Included patch to fix problem compiling for x86 release on
+ Windows.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677992">677992</a>: Section without title could result in an invalid Qt Help
+ index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678022">678022</a>: Anonymous enum could result in an invalid Qt Help index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678102">678102</a>: Superfluous trailing comma in javascript
+ prevented navigation tree to load in IE7.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678177">678177</a>: a + at the start of a line inside a <pre> block,
+ triggered the start of a list. Also -- and --- where not kept untouched
+ inside a <pre> block.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678180">678180</a>: ndash (--) appearing in a brief description could lead
+ to invalid SVG images.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=678288">678288</a>: -- and --- inside a Markdown code block were not handled
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679331">679331</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=675766">675766</a>: In body documentation with a different indentation then the
+ main documentation was not rendered correctly (MARKDOWN=YES).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679436">679436</a>: Using an escaped pipe symbol in a Markdown table did not get
+ unescaped in the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679533">679533</a>: Code fragments did not appear properly in the doxygen manual.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679615">679615</a>: Added missing delete call in a piece of debugging code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=679626">679626</a>: Fixed some navigation issues in the manual
+<li> Not all inherited members appeared in the "Additional inherited members"
+ list.
+<li> Link to call after "Inherited members" was not correct when
+ CREATE_SUBDIRS was enabled.
+<li> New VHDL diagram was not generated if the path contained spaces.
+<li> Fixed a couple of problems handling Objective-C categories.
+</ul>
+\endhtmlonly
+\subsection log_1_8_1_1 Release 1.8.1.1
+\htmlonly
+<a name="1.8.1.1"></a>
+<b>(release date 10-06-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> Integrated the root navigation tree in navtree.js for faster loading.
+<li> When the navigation tree is enabled, clicking jump to a line in
+ the source code view will now highlight the line.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> VHDL code now has a new Design Overview page (thanks for Martin Kreis
+ for the patch). Requires HAVE_DOT=YES, and DOT_IMAGE_FORMAT=svg.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677678">677678</a>: Added support for strong and weak attributes in Objective-C
+ properties.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=618462">618462</a>: Fortran: Appearance of comments in the HTML output
+ are now customizable via CSS again.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673660">673660</a>: <code> inside a <summary> or <remarks> section is now treated
+ as @code (was already the code for C#).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673921">673921</a>: When a comment started at indent >= 4 after a /** and
+ continued at the same indent without leading * after a blank line,
+ the continued part appeared at as a code block when Markdown was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=675036">675036</a>: If a file was not indexed, the navigation tree became empty.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676019">676019</a>: Include path using quotes did not work as documented.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676877">676877</a>: @warning did not end at blank line when followed by
+ a numbered list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676902">676902</a>: An anonymous namespace could introduce an invalid entry in
+ the navigation list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676948">676948</a>: Breadcrumb navigation path had wrong links when
+ CREATE_SUBDIRS was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677315">677315</a>: Fixed case where function was incorrectly detected as a
+ variable.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677589">677589</a>: Fixed typo in the documentation of the LAYOUT_FILE option.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=677771">677771</a>: Fixed visual misalignment for first argument.
+<li> The "arrow out" button in interactive SVG did not work when
+ served from a web server, due to the use of an absolute path.
+<li> If a declation was too wide for a page, the content in HTML spilled
+ over the boundary of its box, which looked ugly.
+<li> Empty lines in a code fragment were collapsed.
+<li> Navigation tree entries of the hierarchy appeared under class index as
+ well.
+<li> Grouped globals and enum values were not added to the navigation index.
+<li> Inlined class were not properly shows in the navigation index.
+<li> Documented class in undocumented namespace did not show up in
+ class list and navigation tree.
+<li> ALLEXTERNALS=YES did not show all external classes in the class list.
+<li> External reference via URL did not work for new
+ "Additional Inherited Members" section + inherited from class link.
+<li> Objective-C protocols and C# generics were not index and listed
+ properly in the navigation tree and indices.
+<li> Undocumented files could produce a broken link in the navigation tree.
+<li> Additional Inherited Members could turn up empty of all members of
+ the inherited class were grouped and SUBGROUPING was set to NO.
+</ul>
+\endhtmlonly
+\subsection log_1_8_1 Release 1.8.1
+\htmlonly
+<a name="1.8.1"></a>
+<b>(release date 19-05-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> Changed the way indexes (Class,File,Namespace,Groups) are rendered:
+ <p>
+ There are now shown in a uniform way in the HTML output as a tree.
+ Trees can be expanded and collapsed interactively
+ (this makes USE_INLINE_TREES obsolete).
+ <p>
+ The class list now also shows namespaces and nested classes.
+ The file list now also shows directories (this makes SHOW_DIRECTORIES
+ obsolete).
+ <p>
+ Member sections are now each rendered in a separate table.
+ This makes the HTML_ALIGN_MEMBERS option obsolete.
+ <p>
+<b>Note:</b> If you use a custom header for the HTML output (HTML_HEADER)
+make sure you add the following:
+ <pre>
+<script type="text/javascript" src="$relpath$jquery.js"></script>
+<script type="text/javascript" src="$relpath$dynsections.js"></script></pre>
+ Otherwise the interactivity of the trees does not work.
+ <p>
+
+<li> Included a couple of performance improvements (thanks to Dirk Reiners)
+<li> Changed the way member attributes (like protected, virtual, and static)
+ are rendered in the HTML output.
+<li> Changed the look of the source code output.
+<li> Included language updates for Chinese, Czech, German, Esperanto,
+ Italian, Slovak, Spanish, Hungarian, and Polish.
+<li> Syntax highlighing in source code fragments is no longer dependent
+ on LATEX_SOURCE_CODE being set to YES.
+<li> Added natural scrolling for tablet devices (like the iPad)
+ when using the treeview.
+<li> For interactive SVGs the print button has been replaced by a
+ "arrow out" button that opens the original non-interactive SVG in a
+ new window for easy printing or saving.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=661499">661499</a>: Long names are now wrapped in the dot nodes to avoid
+ very wide graphs.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666527">666527</a>: Added support for <inheritdoc/> C# XML command
+ (thanks to John Werner for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670965">670965</a>, Added support for resolving environment variables of the
+ form $(PROGRAMFILES(X86)) inside the config file
+<li> Doxygen now shows Objective-C properties in collaboration diagrams
+ (thanks to Sven Weidauer for the patch).
+<li> Added ability to search for group or page titles.
+<li> Inherited class members are now shown as expandable sections in the
+ member overview (default is collapsed). Each section is rendered as
+ a table.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674349">674349</a>: Included build support for NetBSD.
+<li> A -- will now be rendered as an 'en dash', similarly, --- will produce an
+ mdash.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=523156">523156</a>: Fortran: Prefix of routines got stripped.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666088">666088</a>: Include VHDL patch (thanks to Martin Kreis).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670235">670235</a>: Fixed include guard detection problem when using
+ #pragma once
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670805">670805</a>: A numbered list (1. 2. 3.) where each list item ended with
+ an empty line is no longer treated as a set of separate lists (all
+ starting with 1.).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670889">670889</a>: Java: last enum value did not appear in the output unless it was
+ followed by a comma.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671023">671023</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671312">671312</a>: Regression: Autolist items starting on a new paragraph
+ at indent level larger than 0 were not processed correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671076">671076</a>: Sections could be missing from the navigation tree in
+ some situations.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671158">671158</a>: @tableofcontents did not work for the main page (@mainpage)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671159">671159</a>: Sections in a separate markdown page did not appear in the
+ table of contents.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671166">671166</a>: Fortran: Fixed problem causing call/caller graphs not to be
+ generated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671171">671171</a>: RPM spec file was updated to make it work with RHEL 6.2
+ (thanks to Peter Klotz for the patch)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671240">671240</a>: Corrected line number of error message reported for
+ pages.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671291">671291</a>: C# regression: enum values where not shown in the docs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671395">671395</a>: When #some_member appeared at the start of a line it was
+ seen as a level one header instead of a link to a member when
+ Markdown processing was enable. Now at least one space is required
+ after the # to make it a header.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671426">671426</a>: Fixed case where doxygen could crash when a section and
+ subsection had the same label.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671591">671591</a>: docset creating could fail due to invalid Nodes.xml
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671702">671702</a>: Using \internal in a group or member did not hide it
+ from the navigation tree if there was no documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=671709">671709</a>: Backticks in C# comments did not appear as inline
+ fragments, like was the case for other languages.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672119">672119</a>: PHP: defines are now shown as constants rather than enums.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672662">672662</a>: File with .md or .markdown extension were not included
+ with the default setting of FILE_PATTERNS.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672366">672366</a>: mailto style URLs did not work correctly in combination with
+ CREATE_SUBDIRS = YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672472">672472</a>: Removed bogus </b> when using @par.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672475">672475</a>: Added "warning:" prefix to "missing \endcode" message.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672479">672479</a>: Doxygen comments after a macro definition were not
+ removed in the source browser view.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672526">672526</a>: Removed black line in front of custom paragraphs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672536">672536</a>: PHP: use keyword was not handled correctly when importing
+ classes from another namespace.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672620">672620</a>: Switched to using "Macro" in the output instead of "Define".
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=672656">672656</a>: Using  did not work correctly for
+ local images pointed to with IMAGE_PATH.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673045">673045</a>: A block of ///'s inside a verbatim block inside a .md
+ file was replaced by /** .. */
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673066">673066</a>: Doxygen now skips scanning files in directories starting with
+ a dot (e.g. .svn).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673219">673219</a>: Included patch by Ryan Schmidt to make the Mac versions
+ in qglobal.h match that of Apple header files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673870">673870</a>: Added C++11 classes when BUILTIN_STL_SUPPORT is enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=673983">673983</a>: Using a backslash in a section cause 026E30F to appear in the
+ latex TOC.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674563">674563</a>: Fortran: case sensitiveness for routines and functions
+ did not work
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=674583">674583</a>: Fortran: continuation by ampersand not placed in code output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=675757">675757</a>: Fixed indenting issue after the end of a markdown code block
+ inside a list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676116">676116</a>: Use new index style for page index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=676294">676294</a>: Fixed LaTeX error when backslash appeared in a hyperlinked
+ code fragment.
+<li> Tag files had wrong character encoding set in the header.
+<li> C# in/out did not appear in generics using covariance or contravariance.
+<li> When marker of an alias appeared at the end of the alias text it was
+ not expanded.
+<li> Aliases did not work in Markdown files.
+<li> Fixed some problems with the navigation tree for IE9 and Opera.
+<li> Included patch by Jake Colman to make the configgen.py work with older
+ Python version such as 2.4.3.
+<li> Fixed problem parsing \code{.py}...\endcode
+<li> UML_LIMIT_NUM_FIELDS did not work correctly in all cases.
+<li> Setting SORT_GROUP_NAMES to YES, had no effect on child groups within
+ a group.
+</ul>
+\endhtmlonly
+\subsection log_1_8_0 Release 1.8.0
+\htmlonly
+<a name="1.8.0"></a>
+<b>(release date 25-02-2012)</b>
+<h3>Changes</h3>
+<ul>
+<li> Auto list items can now consist of multiple paragraphs.
+ The indentation of the (first line) of a new paragraph detemines
+ to which list item the paragraph belongs or if it marks the end of the
+ list.
+<li> When UML_LOOK is enabled, relations shown on the edge of a graph
+ are not shown as attributes (conform to the UML notation)
+<li> Updated the manual and improved the look.
+<li> Made the contents in the navigation tree more consistent for
+ groups, pages with subpages, and grouped subpages.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669079">669079</a>: Latex: made the margins of latex page layout smaller using
+ the geometry package.
+<li> The tool doxytag has been declared obsolete and is removed
+ (it wasn't working properly anyway). Same goes for the installdox
+ script.
+<li> Updated the copyright in source code and doxywizard "about" to 2012.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668008">668008</a>: HTML version of the manual now has the treeview enabled
+ for easier navigation.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added support for
+ <a href="http://daringfireball.net/projects/markdown/">Markdown</a>
+ formatting.
+ This is enabled by default, but can be disabled by
+ setting MARKDOWN_SUPPORT to NO. When enabled the following is
+ processed differently:
+ <ul>
+ <li> tabs are converted to spaces according to TAB_SIZE.
+ <li> blockquotes are created for lines that start with one or more >'s
+ (amount of >'s detemine the indentation level).
+ <li> emphasis using *emphasize this* or _emphasis this_ or
+ strong emphasis using **emphasis this**. Unlike classic
+ Markdown 'some_great_indentifier' is not touched.
+ <li> code spans can be created using back-ticks, i.e. `here's an example`
+ <li> Using three or more -'s or *'s alone on a line with only spaces
+ will produce a horizontal ruler.
+ <li> A header can be created by putting a ===== (for h1) or ----- (for h2)
+ on the next line or by using 1 to 6 #'s at the start of a line
+ for h1-h6.
+ <li> auto lists item can also start with + or * instead of only -
+ <li> ordered lists can be made using 1. 2. ... labels.
+ <li> verbatim blocks can be produced by indenting 4 additional spaces.
+ Note that doxygen uses a relative indent of 4 spaces, not an
+ absolute indent like Markdown does.
+ <li> Markdown style hyperlinks and hyperlink references.
+ <li> Simple tables can be created using the <a href="http://michelf.com/projects/php-markdown/extra/#table">Markdown Extra format</a>.
+ <li> <a href="http://freewisdom.org/projects/python-markdown/Fenced_Code_Blocks">Fenced code blocks</a> are also supported, include language selection.
+ <li> files with extension .md or .markdown are converted to related pages.
+ </ul>
+ See the section about Markdown support in the manual for details.
+<li> It is now possible to add user defined tabs or groups of tabs to
+ the navigation menu using the layout file (see the section of the manual
+ about customizing the output for details).
+<li> Added new command \tableofcontents (or [TOC] if you prefer Markdown)
+ which can be used in a related page with sections to produce a
+ table of contents at the top of the HTML page (for other formats the
+ command has no effect).
+<li> When using SVG images and INTERACTIVE_SVG is enabled, a print icon
+ will be visible along with the navigation controls to facilitate
+ printing of the part of the graph that is visible on screen.
+<li> Added obfuscation of email addresses for the HTML output to make
+ email harvesting more difficult.
+<li> Added build targets for 64 bit Windows (thanks to Vladimir Simonov).
+ The installer script is also updated to install a 64 bit version of
+ doxygen on 64 bit systems and the 32 bit version on 32 bit systems.
+<li> Added support for using the HTML tag <blockquote> in comments.
+<li> Included patch by Gauthier Haderer that fixes some issues with the
+ dbus XML parser.
+<li> Added support for Markdown style fenced code blocks.
+<li> Added option to @code command to force parsing and syntax highlighting
+ according to a particular language.
+<li> Section of pages are now added to the navigation index.
+<li> Added support for cell alignment and table header shading in
+ LaTeX and RTF output.
+<li> Added -d filteroutput option to show the output of an input filter
+ (thanks to Albert for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668010">668010</a>: Latex: for Windows doxygen new generates a makepdf.bat
+ file in the latex output dir to create the latex documentation.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=498703">498703</a>: Fixed encoding issue in CHM index file for group titles.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=510975">510975</a>: FORTRAN: Keywords like .GT. recognized as symbols for
+ cross ref.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=511906">511906</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=581303">581303</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622749">622749</a>: \copydoc did copy the brief description
+ into the detailed section, causing a difference between the original
+ and the copy.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=555327">555327</a>: Using @ref for an example file, caused it to appear as
+ file::ext.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=567494">567494</a>: Fortran: Included patch for blockdata sub-programs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=628417">628417</a>: Fortran: doxygen filter, preparsing fixed form of null
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=662286">662286</a>: TCL: Inlcuded patch to fixed UTF-8 support.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=662289">662289</a>: TCL: Included patch to prevent ##### from appearing in the
+ output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646319">646319</a>: Using a file name with path for HTML_STYLESHEET caused the
+ path to appear in the HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=664826">664826</a>: Fixed one more problem with include guard detection.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665629">665629</a>: Fixed parse problem when a #define appeared inside an enum.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665855">665855</a>: Fixed problem parsing C++ template specialization of the
+ form A<func(T*)> such as used in boost::signal2 types.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666047">666047</a>: A </p> followed by an htmlonly..endhtmlonly section
+ caused invalid XHTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666085">666085</a>: Fixed include handling in case the include guard was
+ documented.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666124">666124</a>: Fixed problem loading the navigation tree in IE8 when
+ serving pages via a web server.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666337">666337</a>: Included patch to avoid hypenation hints in front of the
+ first captial in a word.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666568">666568</a>: When SHOW_FILES was NO, a grouped function did not appear
+ in the javascript based search index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666909">666909</a>: \copybrief introduced extra spacing in the HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666986">666986</a>: Fixed case where search engine specific code appeared
+ twice in the HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=666993">666993</a>: Fixed bug in the generated makefile causing index not
+ to be generated when using pdflatex.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=667020">667020</a>: HTML output for example pages was not well-formed.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=667192">667192</a>: Include statements in latex output where placed all on
+ one line in the LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=667835">667835</a>: PHP: Fixed problem handling heredoc blocks
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=667844">667844</a>: For aliases with a single argument it is no longer required
+ to escape commas that appear inside the argument text.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668037">668037</a>: Latex: tables can now span multiple pages by using the xtab
+ package.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668218">668218</a>: Doxygen will ignore the common prefix shared by all
+ directories when computing a names for the directory's output files.
+ This will make the names of the output more stable.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=668519">668519</a>: Added missing newline in man page output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669071">669071</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669072">669072</a>: Fixed parse problem for Q_PROPERTY when a template
+ with a namespaced type was used.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669078">669078</a>: Included patch which changes MATHJAX_RELPATH to use the
+ content delivery network by default.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669138">669138</a>: Fortran: Fixed problem handling multiple definition
+ statements on one line.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669406">669406</a>: Using -d Preprocessor now also works when QUIET is YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669434">669434</a>: Latex: citations where only generated properly if the
+ bib files specified via CITE_BIB_FILES did not have a path.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=669758">669758</a>: Tcl: Same function in multiple Tcl namespaces not added.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670289">670289</a>: Fixed case where doxygen would not correctly detect
+ >> as a termination of a nested template.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=670571">670571</a>: subpages generate empty pages in latex/rtf output and
+ broken links when SHORT_NAME was set to YES.
+<li> Included VHDL fixes provided by Martin Kreis.
+<li> The word "dummy" wrongly appeared before the first parameter type in
+ the LaTeX output for an Objective-C method.
+<li> Fixed several small glitches in the tree view javascript code.
+<li> Included a patch by Vladimir Simonov to make it possible to compile
+ doxygen with Visual Studio 2005.
+<li> Fixed some typos in the manual (thanks Albert).
+</ul>
+\endhtmlonly
+\section log_1_7 1.7 Series
+\htmlonly
+<a name="1.7.6.1"></a>
+<h1>Doxygen Release 1.7.6.1</h1>
+<h2>(release date 10-12-2011)</h2>
+<h3>Changes</h3>
+<ul>
+<li> Doxygen now reports its cache usage (for the symbol and the
+ lookup cache) at the end of a run (if QUIET=NO), and recommends
+ settings for SYMBOL_CACHE_SIZE and LOOKUP_CACHE_SIZE for your
+ project if either cache is too small.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added new option LOOKUP_CACHE_SIZE to control the internal cache
+ doxygen uses to find symbols given their name and a context.
+<li> Python: added support for @staticmethod
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Python: scopes are now shown with . instead of ::
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665313">665313</a>: Space before @if was not preserved, causing problems
+ with inline @if .. @endif constructs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665583">665583</a>: Fixed XHTML validity problem when using mscgen graphs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665641">665641</a>: Fixed XHTML validity problem when GENERATE_TREEVIEW was
+ disabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665720">665720</a>: Included patch to fix hang issue when non-empty
+ INCLUDE_PATH was used.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665778">665778</a>: Fixed parse issue when a comma appeared as part of an
+ enum's value.
+</ul>
+<a name="1.7.6"></a>
+<h1>Doxygen Release 1.7.6</h1>
+<h2>(release date 03-12-2011)</h2>
+<h3>Changes</h3>
+<ul>
+<li> To improve the performance of loading the navigation tree,
+ the data is now split into multiple javascript files which
+ are loaded dynamically.
+<li> The selected member is now briefly highlighted in the HTML output
+ (when GENERATE_TREEVIEW is enabled).
+<li> The navigation tree (GENERATE_TREEVIEW) now shows the same information
+ as the index.
+<li> The navindex section of layout now also controls what is shown in
+ the navigation tree.
+<li> Improved HTML output support for IE9.
+<li> Included redesigned VHDL parser (thanks to Martin Kreis for the patch)
+<li> When a class/structs has many (>15) members of the same type, only
+ the first 10 are shown in the UML diagram.
+<li> Made the output of the javascript based search engine more compact.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Update of the French translation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607305">607305</a>: Added support for PHP heredoc and nowdoc constructs.
+<li> Added support for cross-referencing in case of operator-> overloading.
+ This includes support for std::auto_ptr,std::smart_ptr,std::unique_ptr
+ and std::weak_ptr when BUILTIN_STL_SUPPORT is enabled.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Regression: some information was no longer available for a class,
+ due to accidental deletion of a code block.
+<li> Regression: fixed matching problem in the code parser.
+<li> Included fixes for TCL to support commands with \ and command
+ definitions preceded by whitespace (thanks to Rene Zaumseil)
+<li> When using "static int a,b" variable "b" incorrectly appeared in the
+ output even though EXTRACT_STATIC was set to NO.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521717">521717</a>: .spec file was only updated after running ./configure
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656642">656642</a>: Fixed potential crash when using doxygen for large projects.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656878">656878</a>: Fixed problem running bibtex with \cite command on Windows.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=657152">657152</a>: Fixed constant expression evaluation error in the
+ preprocessor.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652277">652277</a>: Removed bogus ' from the man page output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=659244">659244</a>: Quotes in the brief description could appear unescaped in
+ the tooltip.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641336">641336</a>: #includes with ../ were not always processed correctly.
+<li> Fixed potential crash when INLINE_GROUPED_CLASSES and INLINE_SIMPLE_STRUCTS
+ are set to YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=658896">658896</a>: Fixed preprocessor problem handling #defines whose value was
+ a constant string containing ///.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=660332">660332</a>: Using a \ at the end of a comment line could cause
+ parsing problems for C# as the \ was treated as a line continuation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=658033">658033</a>: Fixed parser problem when using multiple member groups
+ inside a macro definition.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=503239">503239</a>: Fixed several issues related to \cite handling.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=658587">658587</a>: Improved the way macro definitions are collected.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=660501">660501</a>: Fixed LaTeX error when using \name with a description.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=661292">661292</a>: The documentation for \mainpage incorrectly mentioned that
+ one has to use \ref main in case GENERATE_TREEVIEW was set to YES, which
+ is no longer the case.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=659096">659096</a>: Nested aliases definitions where not always expanded properly
+ (regression w.r.t version 1.7.4)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=658038">658038</a>: Fixed preprocessor problem where the @ character inside a
+ macro definition could appear as @@.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=658646">658646</a>: Fixed problem running mscgen for LaTeX and RTF output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=661723">661723</a>: Using ClassName%'s did not work anymore, and also
+ ClassName's wasn't autolinked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=662044">662044</a>: Fixed potential printing of null pointer when using
+ a version filter that returned blanks.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625518">625518</a>: Fortran: first problem where subroutine using results
+ variable appeared as a function.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654153">654153</a>: If an URL appeared at the end of a sentence, the period
+ was included in the URL.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656560">656560</a>: Fortran: Added support for the Double Complex type.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=663640">663640</a>: Included workaround for Solaris CC issue in index.cpp
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=662190">662190</a>: Included patch to fix some TCL issues and add the TCL_SUBST
+ configuration option.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=661672">661672</a>: Fortran: Added support for ALIAS expansion in comment blocks.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=663101">663101</a>: Fixed case where a macro was not corrected found in the header
+ file when it could only be found via INCLUDE_PATH.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=664718">664718</a>: using multiple <para>'s inside a <summary> block caused
+ text to be joined without spacing.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656556">656556</a>: Java enums are now parsed as classes.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=664826">664826</a>: Fixed problem in the preprocessor regarding the handling
+ of include guards.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=664893">664893</a>: Fixed typo in the docs for EXCLUDE_SYMLINKS.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665466">665466</a>: Using a relative URL with <a href> did not work when
+ CREATE_SUBDIRS was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=665464">665464</a>: Using an absolute URL with <img> did not work when
+ CREATE_SUBDIRS was enabled.
+</ul>
+<a name="1.7.5.1"></a>
+<h1>Doxygen Release 1.7.5.1</h1>
+<h2>(release date 21-08-2011)</h2>
+<h3>New features</h3>
+<ul>
+<li>Update of the French translation.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521717">521717</a>: .spec file was only updated after running ./configure
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656642">656642</a>: Fixed potential crash when using doxygen for large projects.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656878">656878</a>: Fixed problem running bibtex with \cite command on Windows.
+<li>Regression: some information was no longer available for a class,
+ due to accidental deletion of a code block.
+<li>Regression: fixed matching problem in the code parser.
+</ul>
+<a name="1.7.5"></a>
+<h1>Doxygen Release 1.7.5</h1>
+<h2>(release date 14-08-2011)</h2>
+<h3>Changes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641904">641904</a>: Function in the call graphs are now shown based on first
+ appearance rather then alphabetical order.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616213">616213</a>: When customizing the HTML header $title now only generates
+ the title excluding the project name (which can still be added using
+ $projectname)
+<li> Improved the look of the class index: all items now have equal spacing.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> New option INTERACTIVE_SVG which when set to YES in combination
+ with DOT_IMAGE_FORMAT=svg will make doxygen
+ generate interactive SVG diagrams that support zooming and
+ panning via the mouse (only for large graphs).
+<li> Added support for the Tcl programming language
+ (thanks to Rene Zaumseil and Samuel Bentley for the patch).
+<li> Added @copyright command.
+<li> added option MATHJAX_EXTENSIONS to provide additional extensions for
+ MathJax (thanks to David Munger for the patch).
+<li> added option INLINE_SIMPLE_STRUCTS which when enabled shows the fields
+ of simple classes and structs (with only public data fields) as a table
+ and inline in context (file/group/namespace/class) provided this context
+ is documented.
+<li> When using the server based search engine (SEARCHENGINE=YES and
+ SERVER_BASED_SEARCH=YES) doxygen now advertises a opensearch provider
+ for your project, that allows integrating the search directly in
+ the search field of the browser (thanks to Phil Lello for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=503239">503239</a>: Added new option CITE_BIB_FILES and LATEX_BIB_STYLE and a new
+ command \cite, allowing you to make references to literature (as defined
+ in one or more .bib files). This also works for output formats other
+ than LaTeX. The tool bibtex is required for this to work though. Thanks
+ to David Munger for the initial patch upon which this feature is based.
+<li> PHP namespaces are now shown as A\B in the output.
+<li> Added new \snippet command that can be used to include marked
+ sections from a source file. See
+ http://www.doxygen.org/commands.html#cmdsnippet for more info.
+<li> Added translation support for Armenian, thank to Armen Tangamyan.
+ and included translation updates for a number of languages.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Fixed a couple of potential race conditions found by Helgrind while
+ running dot from multiple threads.
+<li> Graphs did not appear when enabling both INTERACTIVE_SVG and
+ HTML_DYNAMIC_SECTIONS.
+<li> PDFs generated by newer versions of dot (i.e. 2.28) did not appear
+ in the output, because doxygen failed to extract the bounding box.
+<li> Improved call graph and cross-reference support for Python.
+<li> INTERACTIVE_SVG now also works with IE9 if the html file extension is
+ set to xhtml.
+<li> Fixed several cases where the LaTeX output could produce too long
+ lines.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=318061">318061</a>: Putting two functions in the same group that only
+ different in the number of template arguments did not work.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=437346">437346</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=564614">564614</a>: Fixed proper encoding of multibyte output in RTF
+ depending on the code page (thanks to Hirao for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521717">521717</a>: The .spec file in the source distribution did not get
+ updated to the latest version.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521861">521861</a>: Fortran: Continuation character was not recognised in
+ fixed format code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=522496">522496</a>: Fortran: @param checking was not case insensitive.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=560105">560105</a>: Fixed problem combining @cond with preprocessor directives.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=577359">577359</a>: Using "struct A : C, D {};" showed a private inheritance
+ relation for D.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=584194">584194</a>: Some links to typedef where pointing to the typedef'ed
+ class instead.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=619560">619560</a>: Anonymous enums caused an invalid entry in the LaTeX TOC.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622935">622935</a>: Deriving from an unknown template class could cause the
+ class to appear with a -g postfix in C#
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625731">625731</a>: Fortran: Fixed issue handling private subroutines.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=632946">632946</a>: LaTeX now starts a new page when starting a new module.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634837">634837</a>: Fortran: Prefix of function was overwritten and the word
+ 'function' not specified.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=637099">637099</a>: Fortran: Included fix for using collaboration diagrams.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=642468">642468</a>: Added PHP support for namespace with curly braces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643219">643219</a>: Fortran: Improved handling of semicolons.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643617">643617</a>: Fortran: Added support for "type is".
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643944">643944</a>: A macro added to a group appeared twice in the group
+ documentation if was also made related to a class using \relates.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646321">646321</a>: Fixed problem were the search box was missing when using
+ a custom HTML header.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646447">646447</a>: Fixed unterminated img tab in the XHTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646463">646463</a>: Fixed problem handling MSCFILE_DIRS option with multiple
+ paths.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646533">646533</a>: Included patch to sort overloaded members by appearance in
+ the code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646747">646747</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646879">646879</a>: Putting an autolist inside a @todo, @bug or similar
+ section did not work anymore.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=646922">646922</a>: Referring to a logo with a relative path, caused
+ a broken image target when using a custom HTML header.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=647499">647499</a>: Fixed HTML rendering problem on older browsers when
+ GENERATE_TREEVIEW was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=647768">647768</a>: Linking to a section on the main page could result in a
+ broken link when GENERATE_TREEVIEW was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=647889">647889</a>: Fixed invalid warning when using @deparated method with
+ default values for parameters.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=648302">648302</a>: A function made related using @relates could end up in
+ the wrong class if there was already a method with a matching
+ argument list in that other class.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=649103">649103</a>: Return types containing multiple *'s ended up in the
+ output with only one * in some cases.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=650397">650397</a>: Fixed problem with alias substitution if the alias had
+ more then 9 parameters.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=650430">650430</a>: For nested anonymous structs @xx markers could appear in
+ the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=650463">650463</a>: Added compilation support for MacOSX 10.7 (aka Lion).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=650958">650958</a>: Fixed issue printing HTML pages when the
+ GENERATE_TREEVIEW option is set to YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=651611">651611</a>: Fixed broken link to an undocumented namespace.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652138">652138</a>: Fixed potential crash while parsing Fortran code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652188">652188</a>: Fixed problem parsing comment which included
+ an unterminated alias within quotes (i.e. "\word{")
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652277">652277</a>: Lines starting with . did not appear in the man page output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652389">652389</a>: Fortran: Fixed text is detailed function section.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652396">652396</a>: When enabling INTERACTIVE_SVG wide graphs are now also
+ fit to the screen width.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652695">652695</a>: Added missing space between parameter type and name in
+ the RTF output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=652741">652741</a>: Use background-color instead of background in doxygen.css.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=653344">653344</a>: Fixed potential segfault while creating man pages.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=653666">653666</a>: Fortran: add a space to "type" in argument list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=653801">653801</a>: Fixed problem handling include guard when multiple
+ blocks guarded by the same guard were used in a header file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=653963">653963</a>: Fortran: Unified handling of @params at various places.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654108">654108</a>: make clean failed on a system without qmake.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654244">654244</a>: Fixed compile issue for HP Itanium.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654779">654779</a>: Fortran: Interface was seen as a class with constructor /
+ destructor.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654869">654869</a>: Using the word "property" as a type in C caused wrong
+ results.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=654866">654866</a>: Fortran: fixed issue parsing function type that looked like
+ C function pointers.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=655178">655178</a>: Fortran: Fixed parse issue when using variable name
+ starting with the word interface.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=655591">655591</a>: Improved error handling for empty html style list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=655935">655935</a>: Fixed case where %s could end up in a warning messge.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=656005">656005</a>: Methods of Objective-C categories defined in an .m file are
+ now marked as private.
+</ul>
+<a name="1.7.4"></a>
+<h1>Doxygen Release 1.7.4</h1>
+<h2>(release date 28-03-2011)</h2>
+<h3>Changes</h3>
+<ul>
+<li> doxygen -w html now reads the default Doxyfile even if not specified
+ explicitly
+<li> doxygen -w html now produces a template header and footer that can
+ be used independent of the configuration options used.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> New option INLINE_GROUPED_CLASSES that when enabled shows grouped
+ classes inside the group documentation, instead of on a separate page.
+<li> Included updates for the Italian and Russian translation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640875">640875</a>: Added option HTML_EXTRA_FILES which makes it easier to copy
+ additional files to the HTML output and also add them to the index files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=642579">642579</a>: Included patch that adds new LATEX_FOOTER option to
+ customize the end of refman.tex in the LaTeX output.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=140259">140259</a>: Jumping to a @section did not work in the RTF output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521854">521854</a>: Fortran: included patch for supporting multiple argument
+ declarations on one line.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=521861">521861</a>: Fixed problem with line continuation in Fortran.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=566921">566921</a>: %A::B now prevents a link for A::B, instead of only for A
+ and generating a warning that ::B cannot be linked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=598481">598481</a>: Fortran: Added support for extends keyword.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=618374">618374</a>: Added support for inlining code in the VHDL output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625519">625519</a>: Fortran: argument name starting with a reserved word was
+ not handled properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634415">634415</a>: Fixed problem parsing an array of character literals.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=635537">635537</a>: Links to file members were not made when found in tag files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=638637">638637</a>: The Doxyfile documentation contained some very long lines.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=638655">638655</a>: Double quote in page or group title broke treeview.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=638733">638733</a>: Improved documentation for DOT_IMAGE_FORMAT option.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=638829">638829</a>: Added documentation to warn for consequences of using
+ HTML_HEADER.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=638856">638856</a>: Fixed problem autolinking to struct field using #S::a
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=639272">639272</a>: using @dot... at endot produced an image referenced with
+ absolute path.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=639521">639521</a>: \mscfile did not work properly for LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=639716">639716</a>: Fixed problem where #include's could cause phantom __pad__
+ members to appear in the output (appeared on Windows only).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640259">640259</a>: Options PROJECT_LOGO and PROJECT_BRIEF were missing
+ from the manual.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640463">640463</a>: Fixed problem parsing PHP "use" statement when the argument
+ did not have a namespace scope.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640588">640588</a>: Included fix for proper splitting of multiple arguments
+ given to the QHP_CUST_FILTER_ATTRS option.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640646">640646</a>: Long error messages could cause memory corruption.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640742">640742</a>: XML: switched indent option to no in the combine.xslt script.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640754">640754</a>: Comment with XML style list of type table was not rendered
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640822">640822</a>: Added support for overloading of C# indexer operators.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640828">640828</a>: Internal section marked with @internal was not shown as
+ such anymore in the XML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640847">640847</a>: PHP: Fixed parse problem referring to class in global
+ namespace.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640924">640924</a>: Included patch by Haffmans to make the custom header and
+ footer independent of the chosen config options.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=640927">640927</a>: Included fix to prevent a warning in the server side PHP
+ search script.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641026">641026</a>: Included patch to fix broken hyperlink to page entry
+ in xreflists.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641188">641188</a>: Header of \page was wrong in Man page output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641336">641336</a>: #include's to other directories were not always linked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641673">641673</a>: Using "use Foo\Foo;" in PHP could cause doxygen to hang.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=641814">641814</a>: In some cases the HTML output could contain an extra </p>.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=642030">642030</a>: Tooltips with HTML entities could be wrongly truncated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=642475">642475</a>: Include graphs could be incomplete.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643056">643056</a>: Fixed problem with macro expansion.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643279">643279</a>: Fixed potential crash when generating a warning for
+ void f(int %x) style parameter, which is valid in C++/CLI.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643280">643280</a>: Included patch to enabled LargeAddressAware for Windows
+ builds.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643276">643276</a>: Fixed cases where FILE_VERSION_FILTER was called for
+ dummy files with name "generated".
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=643655">643655</a>: Fixed argument matching issue when one of match candidates
+ was a typedef of a method pointer.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=645754">645754</a>: mscfile tag was closed with dotfile in the XML output.
+<li> doxygen -w html now ignores the values for HTML_HEADER and HTML_FOOTER
+ found in the config file.
+<li> Importing a group via a tag file could overrule a local group with
+ the same name even when EXTERNAL_GROUPS was disabled.
+</ul>
+<a name="1.7.3"></a>
+<h1>Doxygen Release 1.7.3</h1>
+<h2>(release date 03-01-2011)</h2>
+<h3>Changes</h3>
+<ul>
+<li> Added a header for each HTML page above the navigation menu,
+ showing the project name and logo and a short descriptin (all optional).
+ Disabling the index (with DISABLE_INDEX) still shows the new header
+ (you can still customize this using HTML_HEADER). This now works
+ nicely in combination with GENERATE_TREEVIEW = YES and/or
+ SEARCH_ENGINE = YES.
+<li> Redesigned the treeview feature. Instead of using frames, the
+ navigation tree is now loaded on each page dynamically. This allows
+ bookmarking a page and always keeps the top menu visible. Also the
+ current item is automatically highlighted in the tree.
+ Also updated the icons in the treeview to match the overall look'n'feel.
+ Note: if you now use a custom HTML header, please update it using
+ doxygen with the -w and the edit the default header.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=499544">499544</a>: Added SVG support to doxygen's dot output
+ (setting DOT_IMAGE_FORMAT to svg now works as expected)
+<li> Added control to the wizard to configure the color of the output
+ visually.
+<li> Added options to specify project synopsis and select a
+ project logo to the wizard.
+<li> Added option PROJECT_LOGO which can be used to specify an image
+ which will be shown in the header of each HTML page along with
+ the project name (PROJECT_NAME option).
+<li> Added option PROJECT_BRIEF which can be used to specify a brief
+ description which will be shown in the header of each HTML page
+ just below the project name.
+<li> Added new option FILTER_SOURCE_PATTERNS which can be used
+ in combination with FILTER_SOURCE_FILES to filter files used for
+ the source browser based on file extension, which can overwrite
+ the filter set by FILTER_PATTERNS and/or INPUT_FILTER.
+<li> Added new option STRICT_PROTO_MATCHING which is disabled by default,
+ and makes the parameter matching to be less strict, resulting in
+ fewer "No matching class member found" warnings.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=306076">306076</a>: code blocks with using directives did not get hyperlinked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=313527">313527</a>: enum values with bitfields did not get parsed correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=565715">565715</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=630582">630582</a>: Included a patch that fixes a couple of Fortran issues
+ (thanks to Albert).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615507">615507</a>: Fixed problem handling @cond.. at endcond in Fortran code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=619040">619040</a>: Scope was missing in Tokens.xml when using docsets.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625517">625517</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=523156">523156</a>: Applied patch tp avoid stripping prefixes for Fortran
+ subroutines.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626476">626476</a>: allow label before end statement in Fortran
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=630901">630901</a>: </see> was not handled properly in comment block.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=632311">632311</a>: Fixed potential crash for empty verbatim section.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=632426">632426</a>: closing brace of a function with one parameter has wrong
+ color in HTML.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=632543">632543</a>: Added support for Fortan TYPEs with languge bindings.
+ (thanks to a patch by Daniel Franke)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=632879">632879</a>: An explicit link request such as #blah did not longer produce
+ a warning if no symbol named blah was found.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=633891">633891</a>: warnings in "inbody" documentation were shown with "unknown"
+ file name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634116">634116</a>: Titles customized via the layout file did not appear in
+ the title page and navigation tree, only in the top menu.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634600">634600</a>: Fixed problem resolving typedef.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634775">634775</a>: Fixed a problem were // inside a code block got removed.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634857">634857</a>: Added support for escaping :: by using \:: (or @::)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634962">634962</a>: #include with relative path to parent dir did not get
+ hyperlinked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=634986">634986</a>: Removed double definition of docParamName in compound.xsd.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=635198">635198</a>: C++/CLI Finalizer methods were not parsed properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636475">636475</a>: Objective-C method names can now be used as the
+ the first argument of \ref.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636588">636588</a>: Fixed a couple of problems in the compound.xsd schema used
+ for XML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636598">636598</a>: DISTRIBUTE_GROUP_DOC now works again for enum values.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636947">636947</a>: Improved matching of typedef'ed array parameter and non
+ typedef'ed array parameter.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=637610">637610</a>: Added a number of fixed for Fortran interfaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=637712">637712</a>: Handle files with the .for extension as Fortran.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=637987">637987</a>: Fixed error in the grouping documentation.
+<li> Fixed line number sync problem when using Objective-C #import
+ statements.
+<li> Fixed problem handling /** @cond */ in the preprocessor.
+<li> Member groups could get reordered in the output.
+</ul>
+<a name="1.7.2"></a>
+<h1>Doxygen Release 1.7.2</h1>
+<h2>(release date 09-10-2010)</h2>
+
+<h3>Changes</h3>
+<ul>
+<li> Changed the default font of the LaTeX output to helvetica.
+<li> Changed the way parameters and return values are represented in the
+ LaTeX and RTF output. They are now listed using tables.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> added support for Apple's block object extension for C/Obj-C/C++.
+<li> added support for detecting Python constructors and destructors.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624575">624575</a>: Added \endinternal command that can be used to force
+ the end of a section started with \internal.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=552605">552605</a>: Added parsing support for PHP 5.3+ style namespaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=582532">582532</a>: added \mscfile command which can be used to insert a
+ message sequence chart given a .msc file.
+ Also added a new config option MSCFILE_DIRS to provide directories
+ were msc files are searched (Thanks to Adrien for the patch).
+<li> Added support for type specifiers for documenting PHP parameters,
+ format: "@param type $paramname docs"
+<li> Added support for rendering formulas in the HTML output
+ using MathJax instead of using prerendered bitmaps.
+ For this purpose the options USE_MATHJAX and MATHJAX_RELPATH were
+ added.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=306076">306076</a>: Fixed case where using of a namespace did not work inside
+ an example.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=336053">336053</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=487871">487871</a>: /// were not stripped from formulas and \dot..\enddot
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=563698">563698</a>: dropped support for a4wide paper format for LaTeX, since
+ it is on the LaTeX taboo list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=571014">571014</a>: Behaviour of CLASS_DIAGRAM=NO in combination with
+ HAVE_DOT=YES, was not propely documented.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=576291">576291</a>: Python comments for next class or method could end up in
+ code of a method/class when enabling INLINE_SOURCES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=611174">611174</a>: Fixed problem handling nestes classes in Python.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621733">621733</a>: removed unexpected warnings about undocumented return types
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622737">622737</a>: Undefined function macros could cause constant expression
+ errors.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622780">622780</a>: updated copyright statement in PDF docs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622935">622935</a>: C# generics appeared with -g extension in the output in
+ some situations.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623023">623023</a>: Fixed parsing problem for "int &foo1(),&foo2();"
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623052">623052</a>: Link to destructor was wrong in the member index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623424">623424</a>: Fixed problem where struct description gets added to variable
+ of struct type.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623673">623673</a>: Anchors were missing in the Qhp index for members.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623733">623733</a>: Fixed potential crash due to uninitialized line number.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=623765">623765</a>: closed.png was wrongly linked when GENERATE_SUBDIRS and
+ HTML_DYNAMIC_SECTIONS were enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624014">624014</a>: Function macro was not handled properly when there was
+ a line continuation directly after the name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624095">624095</a>: Linking to a class via a tag file did not work if the class
+ was in an undocumented namespace.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624104">624104</a>: Fixed a couple of typos in lodepng.h
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624323">624323</a>: Graph legend image was missing form the index files.
+<li> Fixed a number of typos in the config file documentation
+ (thanks to Jens Schweikhardt)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624514">624514</a>: Some enums were not cross-referenced.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=624829">624829</a>: Missing \endcond could cause preprocessor issues in
+ next file(s) to be parsed.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625070">625070</a>: a function definition in a namespace, documented in the
+ header did not always get cross-referenced.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625296">625296</a>: Removed superfluous <td></td> from parameter list in
+ HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625317">625317</a>: Unterminated comment could crash doxygen.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625531">625531</a>: Inherited documentation was only included for the
+ last derived class in case of multiple inheritance.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625578">625578</a>: In the HTML output </div> was missing for built-in
+ class diagrams.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625555">625555</a>: References in example files with underscores were wrong.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625982">625982</a>: When using japanese characters mixed with ascii characters
+ doxygen incorrected ended the brief description with a dot.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=625952">625952</a>: setting MULTILINE_CPP_IS_BRIEF to YES, cause /// to appear
+ in the output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626033">626033</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=567774">567774</a>: EXTENSION_MAPPING did not work if a the mapped
+ language was handled by the same parser as used for the original
+ extension.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626175">626175</a>: Fixed bracket bug in LaTeX fancy headers.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626508">626508</a>: Allow hyphen in key argument of \xrefitem.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=626647">626647</a>: \copydoc did not work for array type arguments (e.g. int[]).
+<li> Use \dotfile did not produce the correct map file, so URLs in dot
+ files did not work.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=627371">627371</a>: #define's in files only found via INCLUDE_PATH were not
+ correctly handled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=628065">628065</a>: auto brief description ending with .) cause the ) to
+ end up in the detailed part.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=628242">628242</a>: Fixed encoding issue for the Spanish translation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=628678">628678</a>: Fixed segmentation fault in case of very long errors.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=629040">629040</a>: Fixed type in search page of the documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=629182">629182</a>: Fixed problem detecting include guard.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=629270">629270</a>: Made file extension to parser mapping case insensitive.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=629485">629485</a>: Latex makefile clean target used rm command also for Windows.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=629942">629942</a>: the EXCLUDE_SYMBOLS option was missing form the online docs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=631094">631094</a>: \htmlinclude and \verbinclude ended the brief description.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=631380">631380</a>: Inconsistent behaviour when a brief description was given
+ following by a detailed comment block with JAVADOC_AUTOBRIEF enabled.
+<li> Fixed a number of typos in the documentation
+ (thanks to Albert van der Meer)
+<li> Fixed potential hangup when scanning directories defined as
+ symlinks to absolute paths.
+<li> HTML attributes other than src were not copied for the <img> tag.
+</ul>
+<a name="1.7.1"></a>
+<h1>Doxygen Release 1.7.1</h1>
+<h2>(release date 25-06-2010)</h2>
+<h3>Changes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621695">621695</a>: Made warning and error messages appear with lower case
+ "warning:" and "error:" prefix to make it easier to use the messages
+ from Visual Studio.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621908">621908</a>: Added new config option FORMULA_TRANSPARENT which allows
+ selecting between transparent (YES) or non-transparent (NO) PNGs for
+ formulas in the HTML output.
+<li> Update for Turkish translation.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=533821">533821</a>: Inheritance relation for a C# class deriving from
+ a generic class was not handled correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=554638">554638</a>: Changing DOT_IMAGE_FORMAT did not cause the graphs to be
+ regenerated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=576533">576533</a>: A field of the form "enum E *p" was ignore.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597016">597016</a>: Hide scope name was not working properly for todo items
+ inside class members, where the class was inside a namespace.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=617761">617761</a>: In dot graphs now also @ref worked (previously only \ref was
+ supported).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621653">621653</a>: Fixed error when compiling doxygen for Solaris 8.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621733">621733</a>: Removed bogus warning about undocument return type for
+ define when WARN_NO_PARAMDOC was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621780">621780</a>: Fixed parsing support for a function that returns a
+ struct definition.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621785">621785</a>: Doxygen could hang when using \copydoc in a function with
+ \param.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621805">621805</a>: Using //!< after a #define no longer worked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621854">621854</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622219">622219</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622593">622593</a>: html help compiler (and also the Qt
+ help compiler) was called before all dot images were generated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=621984">621984</a>: Using a auto-list in combination with \subpage cause the
+ items to be inlined.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622018">622018</a>: Fixed problem parsing a @param command where the
+ text part started with a formula.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622019">622019</a>: Added some instructions how to document Fortran code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622041">622041</a>: Using \var multiple times in a comment block did not
+ work properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622413">622413</a>: Tooltips could get wrongly truncated when multi-byte
+ UTF-8 characters were used.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=622471">622471</a>: Argument matching failed for typedef in another namespace.
+<li> Fixed crash situation while handling commands inside a @ref section.
+<li> Treeview icons were missing in the HTML output when setting
+ GENERATE_TREEVIEW to NO and USE_INLINE_TREES to YES.
+</ul>
+
+<a name="1.7.0"></a>
+<h1>Doxygen Release 1.7.0</h1>
+<h2>(release date 15-06-2010)</h2>
+<h3>Changes</h3>
+<ul>
+<li> Changed the look of the HTML output.
+<li> Made several internal changes that should have a positive effect on the
+ overall performance.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> The color of the HTML output can now easily be adjusted using three new
+ options: HTML_COLORSTYLE_HUE, HTML_COLORSTYLE_SAT,
+ and HTML_COLORSTYLE_GAMMA, which control respectively the hue,
+ saturation, and gamma of all elements in the HTML output.
+<li> Moved dot invocations to the end of a doxygen run. Doxygen will now
+ run multiple instances of dot in parallel (for better CPU utilisation
+ on multi-core systems). The new config option DOT_NUM_THREADS
+ determines the number of threads used (were 0 is auto-detect).
+<li> Added option EXT_LINKS_IN_WINDOW which controls whether or not
+ links to symbols imported via tag files will be opened in a new window.
+<li> Included various language updates (thanks to Petr for coordinating).
+<li> Included patch by Stefan Oberhumer that allows customizing the
+ way parameter lists are shown in the LaTeX output.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=306076">306076</a>: source browser could miss links for used namespaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=361476">361476</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=620924">620924</a>: \if and \endif did not work properly inside auto lists.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=557164">557164</a>: No warning for missing return type documentation even though
+ WARN_NO_PARAMDOC was set to YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=577005">577005</a>: Handling of nesting \defgroup's was not always working
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=578739">578739</a>: ø was not translated correctly in the LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=583526">583526</a>: Use relative paths for mscgen diagrams to avoid errors in the
+ LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592991">592991</a>: The "Use current settings at startup" feature of Doxywizard
+ was broken.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=593679">593679</a>: Links in the search results were broken if they pointed to
+ symbols imported via tag files using an absolute path or URL.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=593760">593760</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615682">615682</a>: Fixed man page output problem when using @par.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=594021">594021</a>: A C comment before a #endif caused the preprocessor
+ statement to be ignored.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597013">597013</a>: When HIDE_SCOPE_NAMES was enabled also the scope for
+ nested classes was stripped. Now only the namespace scope will be
+ stripped as before.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=600829">600829</a>: Autolinks to namespace members did not work if
+ an explicit # or :: was used.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=602732">602732</a>: Slashes inside strings in java annotations were not handled
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606335">606335</a>: Fixed the "show html output" button in doxywizard
+ for Windows when IE was set as the default browser.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608292">608292</a>: Formatting was lost for section copied with \copydoc.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608359">608359</a>: Fixed C++ parse issue for "class : public base {} var;"
+ construct.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=611056">611056</a>: Generated HTML footer file did not have UTF-8 encoding and
+ the relative path marker needed when using CREATE_SUBDIRS = YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=611193">611193</a>: Fixed parsing problem with try-functions having multiple
+ catch handlers.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=611642">611642</a>: Specialized private template member function appeared as
+ public.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=611888">611888</a>: Include dependency graphs were sometimes wrong.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612170">612170</a>: Some lines in the generated Doxyfile where too long.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612275">612275</a>: Fixed auto-link problem for certain URLs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612292">612292</a>: Improved handling of ellipsis inside brief description when
+ JAVADOC_AUTOBRIEF is enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612364">612364</a>: Accessibility of macros was not handled properly in all cases.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612310">612310</a>: Enabling REFERENCED_BY_RELATION without SOURCE_BROWSER could
+ result in broken links.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612458">612458</a>: Fixed problem handling @copydoc for function operators.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612609">612609</a>: A raw C# string constant could end up in the next string.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612969">612969</a>: subpages were not part of the XML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=613024">613024</a>: First list item in the paragraph after a @todo
+ item was not parsed properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=614204">614204</a>: Generated man page links were having a heading underscore.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=614443">614443</a>: Made include guard detect a bit more strict to avoid false
+ positives.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=614447">614447</a>: The labels of CVS tags were missing a colon.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=614438">614438</a>: Fixed problem parsing Q_PROPERTY with template type and
+ spaces.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615165">615165</a>: Made the date string in the HTML footer translatable,
+ along with some other sentences on the directory pages.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=612858">612858</a>: Inline attribute was shown also for non-inline template
+ members.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615583">615583</a>: Fixed problem handling @copy for operators with
+ const qualifier.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615755">615755</a>: Fixed problem handling '"' inside comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615957">615957</a>: Made the LaTeX output a bit less spatious using \input.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615695">615695</a>: Fixed preprocessor issue where a macro that was redefined
+ was not resolved.
+<li> Fixed character encoding issue on the search results page.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=615670">615670</a>: C# namespaces are now extracted also without comment block
+ (the language spec does not allow XML documentation).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616209">616209</a>: included patch that fixes some typos in the code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616344">616344</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=610604">610604</a>: Pages with an underscore in the label generated a
+ file name containing two underscores.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616387">616387</a>: text of the form something.symbol got autolinked when
+ symbol had a global scope.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616761">616761</a>: Call graph could be wrong when local variable has the same
+ name as a global function.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616947">616947</a>: Added documentation patch on how to create URL links with
+ custom text.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=616988">616988</a>: Doxywizard now removes non-existant files from the
+ recent list and has an option to clear the list completely.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=617051">617051</a>: A macro defined via PREDEFINED did not always overrule a
+ macro definition in the code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=617278">617278</a>: Enabling call graphs produced invalid XHTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=617871">617871</a>: Non ascii characters in file or directory names
+ caused problems on Windows.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=618079">618079</a>: An ALIAS with parameters spanning multiple lines
+ caused problems with /// style comments.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=618632">618632</a>: Included patch to prevent image overflowing the page in
+ the LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=619728">619728</a>: Fixed problem using EXTENSION_MAPPING for C# (thanks to
+ Vsevolod Kukol for the patch).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=619978">619978</a>: Links to external files could be wrong when CREATE_SUBDIR
+ was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=620229">620229</a>: /* characters in a print broke parsing within an conditional
+ section.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=620926">620926</a>: \if and \endif did not work properly inside HTML tables.
+<li> Using @include in combination with LATEX_SOURCE_CODE caused wrong
+ output.
+<li> Included a patch by Guido Tack which adds two new options
+ for docsets (DOCSET_PUBLISHER_ID and DOCSET_PUBLISHER_NAME) and
+ fixes an issue with linking to docset members.
+<li> Included patch by Stefan Oberhumer to support escaped {}'s in alias
+ definition and parameters.
+
+</ul>
+\endhtmlonly
+\section log_1_6 1.6 Series
+\htmlonly
+<a name="1.6.3"></a>
+<h1>Doxygen Release 1.6.3</h1>
+<h2>(release date 21-02-2010)</h2>
+<h3>New features</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608480">608480</a>: Using \dir without argument will create directory
+ documentation for the directory in which the \dir command
+ was found.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=590161">590161</a>: perlmod output was wrong when using paragraph commands.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=600525">600525</a>: Included patch for VHDL.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=605698">605698</a>: Replaced size attribute of hr tag by class attribute in the
+ HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606030">606030</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606192">606192</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607563">607563</a>:
+ Using \dot produced "Error opening map file" or
+ could even crash doxygen.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606084">606084</a>: Loading a new config file in doxywizard did not reset all
+ values of a previously loaded config file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606104">606104</a>: Grouped members with todo-like items were shown with
+ "GlobalScope" prefix.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606156">606156</a>: Fixed RTF rendering problem with group index.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606206">606206</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=610133">610133</a>: Added missing line break in LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606330">606330</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608056">608056</a>: The title of pages whose label had an underscore
+ was not shown
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606717">606717</a>: Include guard not starting with #ifndef SOME_GUARD_H were not
+ recognised as such.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606718">606718</a>: Setting SEARCHENGINE to YES and GENERATE_HTML to NO caused
+ error that search results directory could not be created.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=606772">606772</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608493">608493</a>: typedef'ed enums or struct with the same as the
+ typedef did no longer show up.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607088">607088</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607946">607946</a>: Related pages (manual and automatic like the todo page)
+ caused broken links when SHORT_NAMES was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607432">607432</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608002">608002</a>: Automatically generated related pages (like the
+ todo page) caused broken links when CREATE_SUBDIR was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607736">607736</a>: comments after #if could cause next function call not to be
+ cross-referenced.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=607743">607743</a>: \internal inside a conditional section caused warning.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608016">608016</a>: Using \internal inside a \section did not end at the
+ next \section as documented.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608018">608018</a>: \internal command produced message with .: in
+ the LaTeX output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608072">608072</a>: HTML Tables with custom attributes were not rendered
+ properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608227">608227</a>: Man pages with underscore got double underscore in the name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608590">608590</a>: Buffer overflow when using non-ascii characters as class
+ name.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=608921">608921</a>: Macro definition had effect even if the definition was not
+ actually included.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=609504">609504</a>: config.h and config.l where missing from the SVN repository.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=609624">609624</a>: Todo items were merged for overloaded functions.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=609709">609709</a>: C# enum values with @todo items were missing from the todo
+ list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=610437">610437</a>: Removed bogus warning when using <br/> tag.
+<li> Fixed parsing problem for function pointer type starting with
+ "typedef enum".
+<li> Preprocessor did not take EXCLUDE_PATTERNS into account, which
+ could cause parse issues when importing a .tlb file.
+</ul>
+
+
+<a name="1.6.2"></a>
+<h1>Doxygen Release 1.6.2</h1>
+<h2>(release date 30-12-2009)</h2>
+<h3>Changes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=594787">594787</a>: Autolinking to all-lower case words has been disabled,
+ in accordance with the documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=604543">604543</a>: Doxygen now allows any extension supported by dot via the
+ DOT_IMAGE_FORMAT option.
+<li> Switched back to using PNGs for built-in diagrams and formulas using
+ the Lode Vandevenne's PNG encoder.
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added new option SERVER_BASED_SEARCH to re-enable searching via a
+ PHP enabled web browser instead of only using javascript locally.
+ This method better scales to larger projects and allows full text
+ search.
+<li> Added new options GENERATE_ECLIPSEHELP and ECLIPSE_DOC_ID
+ to generate an index file that can be used to embed doxygen's HTML
+ output into Eclipse as a help plugin
+ (thanks to a patch by Ondrej Starek).
+<li> Wrote new <a href="http://www.doxygen.org/searching.html">documentation</a>
+ regarding the methods of searching in the HTML output.
+<li> Included patch by Ed Rosten to render formulas with
+ proper anti-aliasing on non-white backgrounds using transparency.
+<li> Add new option FORCE_LOCAL_INCLUDES to make the default #include
+ appearance in class documentation with "" i.s.o sharp brackets.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=558457">558457</a>: Make \addindex put keywords into the .qhp file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595214">595214</a>: #cmakedefine is now treated the same was as #define
+ (for users of the CMake build system).
+<li> Added compilation support for OSX 10.6 (aka Snow Leopard)
+<li> Included language update for Brazilian.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> Doxywizard did not warn when it failed to save its config file.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=557035">557035</a>: Empty class definitions were not included in Tokens file
+ for docsets.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=563233">563233</a>: GENERATE_QHP details was considered even though it is
+ not defined.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=567346">567346</a>: Comment parser could get stuck in certain cases.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=570369">570369</a>: GENERATE_QHP should generate keywords for classes in
+ generated *.qhc.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=571964">571964</a>: Fixed two issues in the compound.xsd schema definition.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592991">592991</a>: Fixed wrong default destination directory.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=593040">593040</a>: Fixed problem with distributing member group documentation
+ for anonymous member groups.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=593273">593273</a>: GENERATE_TODOLIST=NO and friends not longer worked.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=593928">593928</a>: Added support for UCS-2 encoded input files.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=594391">594391</a>: Fixed problem parsing fully-qualified java annotations.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=594592">594592</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596815">596815</a>: Fixed problem handling quotes.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595191">595191</a>: Not all configuration options appeared in the index of
+ the documentation and some were not sorted correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595253">595253</a>: formulas had the .png extension while they were gifs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595833">595833</a>: Fixed recursive lockup while resolving template relations.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595935">595935</a>: Doxygen's preprocessor got confused when /**/ appeared as
+ part of a macro definition.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596085">596085</a>: Removed obsolete option USE_WINDOWS_ENCODING from the docs.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596233">596233</a>: RTF output was missing a new paragraph for brief
+ member descriptions.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596807">596807</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596819">596819</a>: Code reformatting done for the LaTeX output could
+ break multibyte UTF-8 characters causing invalid output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596809">596809</a>: Using multibyte characters in a page label caused invalid
+ output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596816">596816</a>: Documented the interaction between LATEX_CMD_NAME and
+ USE_PDFLATEX.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597015">597015</a>: Todo items for two inner classes with the same name where
+ collapsed together in the todo list when HIDE_SCOPE_NAMES
+ was enabled.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597016">597016</a>: Scope was not hidden for members in the todo list even
+ though HIDE_SCOPE_NAMES was set to YES.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=598497">598497</a>: Struct variable with explicit struct keyword got labelled
+ with [read] attribute.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=596902">596902</a>: PHP was not parsed properly when it appeared in a
+ <script language="php"> section.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597415">597415</a>: Fixed problem matching base class member against the
+ member in the derived class.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597518">597518</a>: Makefile for Docsets now honors DESTDIR.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=598298">598298</a>: Made browsing for HHC_LOCATION via the wizard
+ yield an absolute path.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=599128">599128</a>: Changed default for CHM_INDEX_ENCODING to CP1250 to avoid
+ issues in a Solaris environment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=595931">595931</a>: Removed unnecessary paragraphs from HTML table cells.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=597541">597541</a>: referring to page labels of the form a-1 did not work.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=599224">599224</a>: Code generators could produce extra </span> tags.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=599974">599974</a>: Included the PHP search engine again (with new config
+ option SERVER_BASED_SEARCH to enable it)
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=600544">600544</a>: Doxygen produced invalid Latex output for RCS tags.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=600563">600563</a>: Fixed issue with include dependency tracking that could
+ cause macro expansion not to work properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=600940">600940</a>: Fixed issue with VHDL call graph (thank to Martin Kreis
+ for the fix).
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=601138">601138</a>: Fixed problem parsing C++ function-try-blocks.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=601222">601222</a>: #include inside a class could cause line numbers to be off.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=601223">601223</a>: Fixed parsing problem skipping over /**/ comment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=601694">601694</a>: Fixed problem handling Javadoc style {@code ... } blocks.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=601771">601771</a>: Special commands did not work in the title of
+ the @mainpage.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=602818">602818</a>: Fixed problem parsing files that start with UTF-8 BOM.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=603001">603001</a>: Fixed problem parsing friend function with explicit scope.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=603238">603238</a>: Fixed perlmod generation issue.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=604948">604948</a>: Project number was not centered anymore in the HTML output.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=604503">604503</a>: Using %word in a page title incorrectly did show the %.
+</ul>
+
+<a name="1.6.1"></a>
+<h1>Doxygen Release 1.6.1</h1>
+<h2>(release date 25-08-2009)</h2>
+<h3>Bug fixes</h3>
+<ul>
+<li> Fixed file handle leak when parsing include files. Also fixed
+ the logic that determines whether or not an include file need to be
+ parsed.
+<li> Search result pages were not using UTF-8 character encoding.
+<li> Search results pointing to external references were not linked correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=133418">133418</a>: Multiline second argument of \ref caused unexpected " warning.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592454">592454</a>: Feeding invalid XML could crash doxygen's DBus XML parser.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592485">592485</a>: Include patch to fix problem with building rpms.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592511">592511</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592625">592625</a>: Doxywizard problem with GENERATE_TREEVIEW.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592650">592650</a>: SHOW_USED_FILES now works again.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=592808">592808</a>: xrefitems (like @todo) did not appear in the list when
+ found in comments marked with @enum or @name.
+</ul>
+<h1>Doxygen Release 1.6.0</h1>
+<h2>(release date 20-08-2009)</h2>
+<h3>Changes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=580924">580924</a>, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=541234">541234</a>: Replaced the PHP based search engine by a
+ Javascript/DHTML based one.
+ As a result the search feature no longer requires a HTTP server
+ with PHP enabled to be usable. Searching is limited to symbols
+ though, but it is now possible to filter on symbol type.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=519886">519886</a>: Make the HTML output XHTML 1.0 compliant.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=579950">579950</a>: Objective-C categories are now merged with their base
+ class, unless there is no base class.
+<li> Member groups with the same header within the same scope are now
+ merged. This also works for Objective-C categories.
+<li> Changed the LaTeX style sheet such that more of the markup is
+ configurable. Please update your style sheet if you use a custom one.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=584844">584844</a>: Treat \details inside a brief description as a new paragraph
+ command.
+<li> Split GENERATE_TREEVIEW into two separate options:
+ GENERATE_TREEVIEW and USE_INLINE_TREES.
+<li> Removed the dependencies on libpng and libz, doxygen now generates
+ gifs again for internal class diagrams (like it did 7 years ago ;-)
+</ul>
+<h3>New features</h3>
+<ul>
+<li> Added option SORT_MEMBERS_CTORS_1ST, which when enabled places the
+ constructors and destructors first in an otherwise sorted list.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=581518">581518</a>: Applied patch by Tobias Hunger that adds support for
+ documenting DBus XML interface descriptions.
+<li> Included QtHelp patch by Karsten Heimrich which adds missing
+ reference and keyword for methods.
+<li> Included updates for the Korean and Polish translation.
+</ul>
+<h3>Bug fixes</h3>
+<ul>
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=131989">131989</a>: Fixed preprocessor handling for C# code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=133418">133418</a>: -- was not rendered correctly for LaTeX output
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=157485">157485</a>: Missing link in todo page.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=318061">318061</a>: Two template functions that only differed in the number
+ of template arguments were seen as the same function.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=443939">443939</a>: HIDE_UNDOC_CLASSES did not work properly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=509348">509348</a>: Fixed problem with syncing the information of
+ declaration and definition in the presence of an extra forward
+ declaration in the source code.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=522193">522193</a>: For C# enum values were merged together if the same enum
+ name was used in different scopes.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=523167">523167</a>: Included patch to handle PROGRAM statement in Fortran as
+ subroutines/functions.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=554636">554636</a>: Remove spacing around brackets for Obj-C protocols.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=557026">557026</a>: Included patch for fixing wrongly labeled items in docsets.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=560512">560512</a>: Improved parser to better disambiguate
+ nested templates ending with >> from the bitshift right operator.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=570238">570238</a>: Fixed matching problem for method in nested class, where
+ the outer class is a template.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=581746">581746</a>: Segfault/realloc error when a very long path was used.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=582469">582469</a>: documented #define with guard caused wrong documentation.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=582276">582276</a>: Doxywizard could crash on exit in some cases.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=582676">582676</a>: Regression: a struct ivar in ObjC class screws up method
+ identification.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=583213">583213</a>: Included patch that avoids trailing spaces in the
+ generated Doxyfile template.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=584192">584192</a>: Included VHDL patch by Martin Klein
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=585543">585543</a>: Fixed case where matching declaration and definition did
+ not work correctly.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=585260">585260</a>: The "more..." link for files was broken, since the anchor
+ was not generated.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=586925">586925</a>: Fixed parsing problem when an unpaired apostrophe
+ appeared in a Python comment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=588291">588291</a>: Included fix for doxywizard makefile.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=588587">588587</a>: Added missing virtual destructor to CompAccept base class.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=588968">588968</a>: Fixed segmentation fault for specific case in PHP code.
+<li> Fixed some issues building for Windows.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=589514">589514</a>: Fixed problem handling strings like a"\b" within a comment.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=589616">589616</a>: Fixed problem matching explicitly scoped parameter in a
+ template class.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=590712">590712</a>: A namespaced with name "internal" (C++/CLI keyword)
+ could confuse doxygen's C++ parser.
+<li> id <a href="https://bugzilla.gnome.org/show_bug.cgi?id=591749">591749</a>: @optional/@required attributes for Objective-C were missing
+ from the XML output.
+</ul>
+<h1><a href="http://www.doxygen.org/changelog_1.5.html">Doxygen Release 1.5 and earlier</a></h1>
+<p>
+<hr>
+<p>
+Go <a href="index.html">back</a> to the main page.
+
+\endhtmlonly
+*/
diff --git a/doc/commands.doc b/doc/commands.doc
new file mode 100644
index 0000000..73eb842
--- /dev/null
+++ b/doc/commands.doc
@@ -0,0 +1,3201 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page commands Special Commands
+
+\section cmd_intro Introduction
+
+All commands in the documentation start with a backslash (<b>\\</b>) or an
+at-sign (<b>\@</b>). If you prefer you can replace all commands starting with a
+backslash below by their counterparts that start with an at-sign.
+
+Some commands have one or more arguments.
+Each argument has a certain range:
+<ul>
+<li>If \<sharp\> braces are used the argument is a single word.
+<li>If (round) braces are used the argument extends until the end of the line
+ on which the command was found.
+<li>If {curly} braces are used the argument extends until the next paragraph.
+ Paragraphs are delimited by a blank line or by a section indicator.
+</ul>
+If in addition to the above argument specifiers [square] brackets are used the argument is optional.
+
+Here is an alphabetically sorted list of all commands with references to their
+documentation:
+\anchor showsecreflist
+\secreflist
+\refitem cmda \\a
+\refitem cmdaddindex \\addindex
+\refitem cmdaddtogroup \\addtogroup
+\refitem cmdanchor \\anchor
+\refitem cmdarg \\arg
+\refitem cmdattention \\attention
+\refitem cmdauthor \\author
+\refitem cmdauthors \\authors
+\refitem cmdb \\b
+\refitem cmdbrief \\brief
+\refitem cmdbug \\bug
+\refitem cmdc \\c
+\refitem cmdcallgraph \\callgraph
+\refitem cmdcallergraph \\callergraph
+\refitem cmdcategory \\category
+\refitem cmdcite \\cite
+\refitem cmdclass \\class
+\refitem cmdcode \\code
+\refitem cmdcond \\cond
+\refitem cmdcopybrief \\copybrief
+\refitem cmdcopydetails \\copydetails
+\refitem cmdcopydoc \\copydoc
+\refitem cmdcopyright \\copyright
+\refitem cmddate \\date
+\refitem cmddef \\def
+\refitem cmddefgroup \\defgroup
+\refitem cmddeprecated \\deprecated
+\refitem cmddetails \\details
+\refitem cmddiafile \\diafile
+\refitem cmddir \\dir
+\refitem cmddocbookonly \\docbookonly
+\refitem cmddontinclude \\dontinclude
+\refitem cmddot \\dot
+\refitem cmddotfile \\dotfile
+\refitem cmde \\e
+\refitem cmdelse \\else
+\refitem cmdelseif \\elseif
+\refitem cmdem \\em
+\refitem cmdendcode \\endcode
+\refitem cmdendcond \\endcond
+\refitem cmdenddocbookonly \\enddocbookonly
+\refitem cmdenddot \\enddot
+\refitem cmdendhtmlonly \\endhtmlonly
+\refitem cmdendif \\endif
+\refitem cmdendinternal \\endinternal
+\refitem cmdendlatexonly \\endlatexonly
+\refitem cmdendlink \\endlink
+\refitem cmdendmanonly \\endmanonly
+\refitem cmdendmsc \\endmsc
+\refitem cmdendparblock \\endparblock
+\refitem cmdendrtfonly \\endrtfonly
+\refitem cmdendsecreflist \\endsecreflist
+\refitem cmdendverbatim \\endverbatim
+\refitem cmdenduml \\enduml
+\refitem cmdendxmlonly \\endxmlonly
+\refitem cmdenum \\enum
+\refitem cmdexample \\example
+\refitem cmdexception \\exception
+\refitem cmdextends \\extends
+\refitem cmdfdollar \\f\$
+\refitem cmdfbropen \\f[
+\refitem cmdfbrclose \\f]
+\refitem cmdfcurlyopen \\f{
+\refitem cmdfcurlyclose \\f}
+\refitem cmdfile \\file
+\refitem cmdfn \\fn
+\refitem cmdheaderfile \\headerfile
+\refitem cmdhideinitializer \\hideinitializer
+\refitem cmdhtmlinclude \\htmlinclude
+\refitem cmdhtmlonly \\htmlonly
+\refitem cmdidlexcept \\idlexcept
+\refitem cmdif \\if
+\refitem cmdifnot \\ifnot
+\refitem cmdimage \\image
+\refitem cmdimplements \\implements
+\refitem cmdinclude \\include
+\refitem cmdincludelineno \\includelineno
+\refitem cmdingroup \\ingroup
+\refitem cmdinternal \\internal
+\refitem cmdinvariant \\invariant
+\refitem cmdinterface \\interface
+\refitem cmdlatexinclude \\latexinclude
+\refitem cmdlatexonly \\latexonly
+\refitem cmdli \\li
+\refitem cmdline \\line
+\refitem cmdlink \\link
+\refitem cmdmainpage \\mainpage
+\refitem cmdmanonly \\manonly
+\refitem cmdmemberof \\memberof
+\refitem cmdmsc \\msc
+\refitem cmdmscfile \\mscfile
+\refitem cmdn \\n
+\refitem cmdname \\name
+\refitem cmdnamespace \\namespace
+\refitem cmdnosubgrouping \\nosubgrouping
+\refitem cmdnote \\note
+\refitem cmdoverload \\overload
+\refitem cmdp \\p
+\refitem cmdpackage \\package
+\refitem cmdpage \\page
+\refitem cmdpar \\par
+\refitem cmdparagraph \\paragraph
+\refitem cmdparam \\param
+\refitem cmdparblock \\parblock
+\refitem cmdpost \\post
+\refitem cmdpre \\pre
+\refitem cmdprivate \\private
+\refitem cmdprivatesection \\privatesection
+\refitem cmdproperty \\property
+\refitem cmdprotected \\protected
+\refitem cmdprotectedsection \\protectedsection
+\refitem cmdprotocol \\protocol
+\refitem cmdpublic \\public
+\refitem cmdpublicsection \\publicsection
+\refitem cmdpure \\pure
+\refitem cmdref \\ref
+\refitem cmdrefitem \\refitem
+\refitem cmdrelated \\related
+\refitem cmdrelates \\relates
+\refitem cmdrelatedalso \\relatedalso
+\refitem cmdrelatesalso \\relatesalso
+\refitem cmdremark \\remark
+\refitem cmdremarks \\remarks
+\refitem cmdresult \\result
+\refitem cmdreturn \\return
+\refitem cmdreturns \\returns
+\refitem cmdretval \\retval
+\refitem cmdrtfonly \\rtfonly
+\refitem cmdsa \\sa
+\refitem cmdsecreflist \\secreflist
+\refitem cmdsection \\section
+\refitem cmdsee \\see
+\refitem cmdshort \\short
+\refitem cmdshowinitializer \\showinitializer
+\refitem cmdsince \\since
+\refitem cmdskip \\skip
+\refitem cmdskipline \\skipline
+\refitem cmdsnippet \\snippet
+\refitem cmdstartuml \\startuml
+\refitem cmdstruct \\struct
+\refitem cmdsubpage \\subpage
+\refitem cmdsubsection \\subsection
+\refitem cmdsubsubsection \\subsubsection
+\refitem cmdtableofcontents \\tableofcontents
+\refitem cmdtest \\test
+\refitem cmdthrow \\throw
+\refitem cmdthrows \\throws
+\refitem cmdtodo \\todo
+\refitem cmdtparam \\tparam
+\refitem cmdtypedef \\typedef
+\refitem cmdunion \\union
+\refitem cmduntil \\until
+\refitem cmdvar \\var
+\refitem cmdverbatim \\verbatim
+\refitem cmdverbinclude \\verbinclude
+\refitem cmdversion \\version
+\refitem cmdvhdlflow \\vhdlflow
+\refitem cmdwarning \\warning
+\refitem cmdweakgroup \\weakgroup
+\refitem cmdxmlonly \\xmlonly
+\refitem cmdxrefitem \\xrefitem
+\refitem cmddollar \\\$
+\refitem cmdat \\\@
+\refitem cmdbackslash \\\\
+\refitem cmdamp \\\&
+\refitem cmdtilde \\~
+\refitem cmdlt \\\<
+\refitem cmdgt \\\>
+\refitem cmdhash \\\#
+\refitem cmdperc \\\%
+\refitem cmdquot \\\"
+\refitem cmdchardot \\\.
+\refitem cmddcolon \::
+\refitem cmdpipe \\|
+\refitem cmdndash \\\--
+\refitem cmdmdash \\\---
+\endsecreflist
+
+The following subsections provide a list of all commands that are recognized by
+doxygen. Unrecognized commands are treated as normal text.
+
+
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Structural indicators
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center> \endhtmlonly
+
+\section cmdaddtogroup \\addtogroup <name> [(title)]
+ \addindex \\addtogroup
+ Defines a group just like \ref cmddefgroup "\\defgroup", but in contrast to
+ that command using the same \<name\> more than once will not result in a warning,
+ but rather one group with a merged documentation and the first title found in
+ any of the commands.
+
+ The title is optional, so this command can also be used to add a number of
+ entities to an existing group using \c \@{ and \c \@} like this:
+
+\verbatim
+ /*! \addtogroup mygrp
+ * Additional documentation for group 'mygrp'
+ * @{
+ */
+
+ /*!
+ * A function
+ */
+ void func1()
+ {
+ }
+
+ /*! Another function */
+ void func2()
+ {
+ }
+
+ /*! @} */
+\endverbatim
+
+ \sa page \ref grouping "Grouping", sections \ref cmddefgroup "\\defgroup", \ref cmdingroup "\\ingroup", and
+ \ref cmdweakgroup "\\weakgroup".
+
+<hr>
+\section cmdcallgraph \\callgraph
+
+ \addindex \\callgraph
+ When this command is put in a comment block of a function or method
+ and \ref cfg_have_dot "HAVE_DOT" is set to \c YES, then doxygen will
+ generate a call graph for that function (provided the implementation of the
+ function or method calls other documented functions). The call graph will be
+ generated regardless of the value of \ref cfg_call_graph "CALL_GRAPH".
+ \note The completeness (and correctness) of the call graph depends on the
+ doxygen code parser which is not perfect.
+
+ \sa section \ref cmdcallergraph "\\callergraph".
+
+<hr>
+\section cmdcallergraph \\callergraph
+
+ \addindex \\callergraph
+ When this command is put in a comment block of a function or method
+ and \ref cfg_have_dot "HAVE_DOT" is set to \c YES, then doxygen will
+ generate a caller graph for that function (provided the implementation of the
+ function or method calls other documented functions). The caller graph will be
+ generated regardless of the value of \ref cfg_caller_graph "CALLER_GRAPH".
+ \note The completeness (and correctness) of the caller graph depends on the
+ doxygen code parser which is not perfect.
+
+ \sa section \ref cmdcallgraph "\\callgraph".
+
+<hr>
+\section cmdcategory \\category <name> [<header-file>] [<header-name>]
+
+ \addindex \\category
+ For Objective-C only: Indicates that a comment block contains documentation
+ for a class category with name \<name\>. The arguments are
+ equal to the \ref cmdclass "\\class" command.
+
+ \sa section \ref cmdclass "\\class".
+
+<hr>
+\section cmdclass \\class <name> [<header-file>] [<header-name>]
+
+ \addindex \\class
+ Indicates that a comment block contains documentation for a
+ class with name \<name\>. Optionally a header file and a header name
+ can be specified. If the header-file is specified, a link to a verbatim copy
+ of the header will be included in the HTML documentation.
+ The \<header-name\> argument can be used to overwrite the
+ name of the link that is used in the class documentation to something other
+ than \<header-file\>. This can be useful if the include name is not located
+ on the default include path (like \<X11/X.h\>). With the \<header-name\>
+ argument you can also specify how the include statement should look like,
+ by adding either quotes or sharp brackets around the name.
+ Sharp brackets are used if just the name is given. Note that the
+ last two arguments can also be specified using
+ the \ref cmdheaderfile "\\headerfile" command.
+
+ \par Example:
+ \verbinclude class.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/class/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmddef \\def <name>
+
+ \addindex \\def
+ Indicates that a comment block contains documentation for a
+ \c \#define macro.
+
+ \par Example:
+ \verbinclude define.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/define/html/define_8h.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmddefgroup \\defgroup <name> (group title)
+
+ \addindex \\defgroup
+ Indicates that a comment block contains documentation for a
+ \ref modules "group" of classes, files or namespaces. This can be used to
+ categorize classes, files or namespaces, and document those
+ categories. You can also use groups as members of other groups,
+ thus building a hierarchy of groups.
+
+ The \<name\> argument should be a single-word identifier.
+
+ \sa page \ref grouping "Grouping", sections \ref cmdingroup "\\ingroup", \ref cmdaddtogroup "\\addtogroup", and
+ \ref cmdweakgroup "\\weakgroup".
+
+<hr>
+\section cmddir \\dir [<path fragment>]
+
+ \addindex \\dir
+ Indicates that a comment block contains documentation for a directory.
+ The "path fragment" argument should include the directory name and
+ enough of the path to be unique with respect to the other directories
+ in the project.
+ The \ref cfg_strip_from_path "STRIP_FROM_PATH" option determines what is
+ stripped from the full path before it appears in the output.
+
+<hr>
+\section cmdenum \\enum <name>
+
+ \addindex \\enum
+ Indicates that a comment block contains documentation for an
+ enumeration, with name \<name\>. If the enum is a member of a class and
+ the documentation block is located outside the class definition,
+ the scope of the class should be specified as well.
+ If a comment block is located directly in front of an enum declaration,
+ the \c \\enum comment may be omitted.
+
+ \par Note:
+ The type of an anonymous enum cannot be documented, but the values
+ of an anonymous enum can.
+
+ \par Example:
+ \verbinclude enum.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/enum/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmdexample \\example <file-name>
+
+ \addindex \\example
+ Indicates that a comment block contains documentation for a source code
+ example. The name of the source file is \<file-name\>. The text of
+ this file will be included in the documentation, just after the
+ documentation contained in the comment block. All examples are placed
+ in a list. The source code is scanned for documented members and classes.
+ If any are found, the names are cross-referenced with the documentation.
+ Source files or directories can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH"
+ tag of doxygen's configuration file.
+
+ If \<file-name\> itself is not unique for the set of example files specified
+ by the
+ \ref cfg_example_path "EXAMPLE_PATH" tag, you can include part of the absolute path
+ to disambiguate it.
+
+ If more than one source file is needed for the example,
+ the \ref cmdinclude "\\include" command can be used.
+
+ \par Example:
+ \verbinclude example.cpp
+ Where the example file \c example_test.cpp looks as follows:
+ \verbinclude example_test.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/example/html/examples.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \sa section \ref cmdinclude "\\include".
+
+<hr>
+\section cmdendinternal \\endinternal
+
+ \addindex \\endinternal
+ This command ends a documentation fragment that was started with a
+ \ref cmdinternal "\\internal" command. The text between \ref cmdinternal "\\internal" and
+ \c \\endinternal will only be visible
+ if \ref cfg_internal_docs "INTERNAL_DOCS" is set to \c YES.
+
+<hr>
+\section cmdextends \\extends <name>
+
+ \addindex \\extends
+ This command can be used to manually indicate an inheritance relation,
+ when the programming language does not support this concept natively
+ (e.g. C).
+
+ The file \c manual.c in the example directory shows how to use this command.
+
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/manual/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \sa section \ref cmdimplements "\\implements" and section
+ \ref cmdmemberof "\\memberof"
+
+<hr>
+\section cmdfile \\file [<name>]
+
+ \addindex \\file
+ Indicates that a comment block contains documentation for a source or
+ header file with name \<name\>. The file name may include (part of) the
+ path if the file-name alone is not unique. If the file name is omitted
+ (i.e. the line after \c \\file is left blank) then the documentation block that
+ contains the \c \\file command will belong to the file it is located in.
+
+ \par Important:
+ The documentation of global functions, variables, typedefs, and enums will
+ only be included in the output if the file they are in is documented as well.
+
+ \par Example:
+ \verbinclude file.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/file/html/file_8h.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \note In the above example \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF"
+ has been set to \c YES in the configuration file.
+
+<hr>
+\section cmdfn \\fn (function declaration)
+
+ \addindex \\fn
+ Indicates that a comment block contains documentation for a function
+ (either global or as a member of a class). This command is \em only
+ needed if a comment block is \e not placed in front (or behind)
+ the function declaration or definition.
+
+ If your comment block \e is in front of the function
+ declaration or definition this command can (and to avoid redundancy
+ should) be omitted.
+
+ A full function declaration including arguments should be specified after the
+ \c \\fn command on a \e single line, since the argument ends at the end
+ of the line!
+
+ This command is equivalent to \ref cmdvar "\\var", \ref cmdtypedef "\\typedef",
+ and \ref cmdproperty "\\property".
+
+ \warning Do not use this command
+ if it is not absolutely needed, since it will lead to duplication of
+ information and thus to errors.
+
+ \par Example:
+ \verbinclude func.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/func/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+
+ \sa sections \ref cmdvar "\\var", \ref cmdproperty "\\property", and
+ \ref cmdtypedef "\\typedef".
+
+<hr>
+\section cmdheaderfile \\headerfile <header-file> [<header-name>]
+
+ \addindex \\headerfile
+ Intended to be used for class, struct, or union documentation, where
+ the documentation is in front of the definition. The arguments of
+ this command are the same as the second and third argument of
+ \ref cmdclass "\\class".
+ The \<header-file\> name refers to the file that should be included by the
+ application to obtain the definition of the class, struct, or union.
+ The \<header-name\> argument can be used to overwrite the
+ name of the link that is used in the class documentation to something other
+ than \<header-file\>. This can be useful if the include name is not located
+ on the default include path (like \<X11/X.h\>).
+
+ With the \<header-name\>
+ argument you can also specify how the include statement should look like,
+ by adding either double quotes or sharp brackets around the name.
+ By default sharp brackets are used if just the name is given.
+
+ If a pair of double quotes is given for either the \<header-file\> or
+ \<header-name\> argument, the current file (in which the command was found)
+ will be used but with quotes. So for a comment block with a \c \\headerfile
+ command inside a file <code>test.h</code>, the following three commands are equivalent:
+ \verbatim
+ \headerfile test.h "test.h"
+ \headerfile test.h ""
+ \headerfile "" \endverbatim
+ To get sharp brackets you do not need to specify anything,
+ but if you want to be explicit you could use any of the following:
+ \verbatim
+ \headerfile test.h <test.h>
+ \headerfile test.h <>
+ \headerfile <> \endverbatim
+
+ To globally reverse the default include representation to
+ local includes you can set
+ \ref cfg_force_local_includes "FORCE_LOCAL_INCLUDES" to \c YES.
+
+ To disable the include information altogether set
+ \ref cfg_show_include_files "SHOW_INCLUDE_FILES" to \c NO.
+
+<hr>
+\section cmdhideinitializer \\hideinitializer
+
+ \addindex \\hideinitializer
+ By default the value of a define and the initializer of a variable
+ are displayed unless they are longer than 30 lines. By putting
+ this command in a comment block of a define or variable, the
+ initializer is always hidden. The maximum number of initialization lines
+ can be changed by means of the configuration parameter
+ \ref cfg_max_initializer_lines "MAX_INITIALIZER_LINES", the default
+ value is 30.
+
+ \sa section \ref cmdshowinitializer "\\showinitializer".
+
+<hr>
+\section cmdidlexcept \\idlexcept <name>
+ \addindex \\idlexcept
+
+ Indicates that a comment block contains documentation for a
+ IDL exception with name \<name\>.
+
+<hr>
+\section cmdimplements \\implements <name>
+
+ \addindex \\implements
+ This command can be used to manually indicate an inheritance relation,
+ when the programming language does not support this concept natively
+ (e.g. C).
+
+ The file \c manual.c in the example directory shows how to use this command.
+
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/manual/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \sa section \ref cmdextends "\\extends" and section
+ \ref cmdmemberof "\\memberof"
+
+<hr>
+\section cmdingroup \\ingroup (<groupname> [<groupname> <groupname>])
+
+ \addindex \\ingroup
+ If the \c \\ingroup command is placed in a comment block of a
+ class, file or namespace, then it will be added to the group or
+ groups identified by \<groupname\>.
+
+ \sa page \ref grouping "Grouping", sections \ref cmddefgroup "\\defgroup",
+ \ref cmdaddtogroup "\\addtogroup", and \ref cmdweakgroup "\\weakgroup"
+
+<hr>
+\section cmdinterface \\interface <name> [<header-file>] [<header-name>]
+
+ \addindex \\interface
+ Indicates that a comment block contains documentation for an
+ interface with name \<name\>. The arguments are equal to the arguments of the
+ \ref cmdclass "\\class" command.
+
+ \sa section \ref cmdclass "\\class".
+
+<hr>
+\section cmdinternal \\internal
+
+ \addindex \\internal
+ This command starts a documentation fragment that is meant for internal
+ use only. The fragment naturally ends at the end of the comment block.
+ You can also force the internal section to end earlier by using the
+ \ref cmdendinternal "\\endinternal" command.
+
+ If the \c \\internal command is put inside a section
+ (see for example \ref cmdsection "\\section") all subsections after the
+ command are considered to be internal as well. Only a new section at the
+ same level will end the fragment that is considered internal.
+
+ You can use \ref cfg_internal_docs "INTERNAL_DOCS" in the config file
+ to show (\c YES) or hide (\c NO) the internal documentation.
+
+ \sa section \ref cmdendinternal "\\endinternal".
+
+
+<hr>
+\section cmdmainpage \\mainpage [(title)]
+
+ \addindex \\mainpage
+
+ If the \c \\mainpage command is placed in a comment block the
+ block is used to customize the index page (in HTML) or
+ the first chapter (in \LaTeX).
+
+ The title argument is optional and replaces the default title that
+ doxygen normally generates. If you do not want any title you can
+ specify \c notitle as the argument of \c \\mainpage.
+
+ Here is an example:
+\verbatim
+/*! \mainpage My Personal Index Page
+ *
+ * \section intro_sec Introduction
+ *
+ * This is the introduction.
+ *
+ * \section install_sec Installation
+ *
+ * \subsection step1 Step 1: Opening the box
+ *
+ * etc...
+ */
+\endverbatim
+
+ You can refer to the main page using: <code>\ref cmdref "\\ref" index</code>.
+
+ \sa section \ref cmdsection "\\section",
+ section \ref cmdsubsection "\\subsection", and
+ section \ref cmdpage "\\page".
+
+<hr>
+\section cmdmemberof \\memberof <name>
+
+ \addindex \\memberof
+ This command makes a function a member of a class in a similar way
+ as \ref cmdrelates "\\relates" does, only with this command the function
+ is represented as a real member of the class.
+ This can be useful when the programming language does not support
+ the concept of member functions natively (e.g. C).
+
+ It is also possible to use this command together with
+ \ref cmdpublic "\\public", \ref cmdprotected "\\protected" or
+ \ref cmdprivate "\\private".
+
+ The file \c manual.c in the example directory shows how to use this command.
+
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/manual/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \sa sections \ref cmdextends "\\extends", \ref cmdimplements "\\implements",
+ \ref cmdpublic "\\public", \ref cmdprotected "\\protected" and
+ \ref cmdprivate "\\private".
+
+<hr>
+\section cmdname \\name [(header)]
+
+ \addindex \\name
+
+ This command turns a comment block into a header
+ definition of a member group. The
+ comment block should be followed by a
+ <code>//\@{ ... //\@}</code> block containing the
+ members of the group.
+
+ See section \ref memgroup for an example.
+
+<hr>
+\section cmdnamespace \\namespace <name>
+
+ \addindex \\namespace
+ Indicates that a comment block contains documentation for a
+ namespace with name \<name\>.
+
+<hr>
+\section cmdnosubgrouping \\nosubgrouping
+
+ \addindex \\nosubgrouping
+ This command can be put in the documentation
+ of a class. It can be used in combination with member grouping
+ to avoid that doxygen puts a member group as a subgroup of a
+ Public/Protected/Private/... section.
+
+ \sa sections \ref cmdpublicsection "\\publicsection",
+ \ref cmdprotectedsection "\\protectedsection" and
+ \ref cmdprivatesection "\\privatesection".
+
+<hr>
+\section cmdoverload \\overload [(function declaration)]
+
+ \addindex \\overload
+ This command can be used to generate the following
+ standard text for an overloaded member function:
+
+ > This is an overloaded member function, provided for convenience.
+ > It differs from the above function only in what argument(s) it accepts.
+
+ If the documentation for the overloaded member function is not located
+ in front of the function declaration or definition, the optional
+ argument should be used to specify the correct function.
+
+ Any other documentation that is inside the documentation block will
+ by appended after the generated message.
+
+ \par Note 1:
+ You are responsible that there is indeed an
+ earlier documented member that is overloaded by this one.
+ To prevent that document reorders the documentation you should set
+ \ref cfg_sort_member_docs "SORT_MEMBER_DOCS" to \c NO in this case.
+ \par Note 2:
+ The \c \\overload command does not work inside a one-line comment.
+ \par Example:
+ \verbinclude examples/overload.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/overload/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmdpackage \\package <name>
+
+ \addindex \\package
+ Indicates that a comment block contains documentation for a
+ Java package with name \<name\>.
+
+<hr>
+\section cmdpage \\page <name> (title)
+
+ \addindex \\page
+ Indicates that a comment block contains a piece of documentation that is
+ not directly related to one specific class, file or member.
+ The HTML generator creates a page containing the documentation. The
+ \LaTeX generator
+ starts a new section in the chapter 'Page documentation'.
+
+ \par Example:
+ \verbinclude page.doc
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/page/html/pages.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ \par Note:
+ The \<name\> argument consists of a combination of letters and number
+ digits. If you wish to use upper case letters (e.g. \c MYPAGE1), or
+ mixed case letters (e.g. \c MyPage1) in the \<name\> argument, you
+ should set \ref cfg_case_sense_names "CASE_SENSE_NAMES" to \c YES. However, this is advisable
+ only if your file system is case sensitive. Otherwise (and for better
+ portability) you should use all lower case letters (e.g. \c mypage1)
+ for \<name\> in all references to the page.
+
+ \sa section \ref cmdsection "\\section", section
+ \ref cmdsubsection "\\subsection", and section
+ \ref cmdref "\\ref".
+
+<hr>
+\section cmdprivate \\private
+
+ \addindex \\private
+ Indicates that the member documented by the comment block is private,
+ i.e., should only be accessed by other members in the same class.
+
+ Note that Doxygen automatically detects the protection level of members
+ in object-oriented languages. This command is intended for use only when
+ the language does not support the concept of protection level natively
+ (e.g. C, PHP 4).
+
+ For starting a section of private members, in a way similar to the
+ "private:" class marker in C++, use \ref cmdprivatesection "\\privatesection".
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdpublic "\\public",
+ \ref cmdprotected "\\protected" and \ref cmdprivatesection "\\privatesection".
+
+<hr>
+\section cmdprivatesection \\privatesection
+
+ \addindex \\privatesection
+ Starting a section of private members, in a way similar to the
+ "private:" class marker in C++.
+ Indicates that the member documented by the comment block is private,
+ i.e., should only be accessed by other members in the same class.
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdpublic "\\public",
+ \ref cmdprotected "\\protected" and \ref cmdprivate "\\private".
+
+<hr>
+\section cmdproperty \\property (qualified property name)
+
+ \addindex \\property
+ Indicates that a comment block contains documentation for a
+ property (either global or as a member of a class).
+ This command is equivalent to \ref cmdfn "\\fn",
+ \ref cmdtypedef "\\typedef", and \ref cmdvar "\\var".
+
+ \sa sections \ref cmdfn "\\fn", \ref cmdtypedef "\\typedef", and
+ \ref cmdvar "\\var".
+
+<hr>
+\section cmdprotected \\protected
+
+ \addindex \\protected
+ Indicates that the member documented by the comment block is protected,
+ i.e., should only be accessed by other members in the same or derived
+ classes.
+
+ Note that Doxygen automatically detects the protection level of members
+ in object-oriented languages. This command is intended for use only when
+ the language does not support the concept of protection level natively
+ (e.g. C, PHP 4).
+
+ For starting a section of protected members, in a way similar to the
+ "protected:" class marker in C++, use \ref cmdprotectedsection "\\protectedsection".
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdpublic "\\public",
+ \ref cmdprivate "\\private" and \ref cmdprotectedsection "\\protectedsection".
+
+<hr>
+\section cmdprotectedsection \\protectedsection
+
+ \addindex \\protectedsection
+ Starting a section of protected members, in a way similar to the
+ "protected:" class marker in C++.
+ Indicates that the member documented by the comment block is protected,
+ i.e., should only be accessed by other members in the same or derived
+ classes.
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdpublic "\\public",
+ \ref cmdprivate "\\private" and \ref cmdprotected "\\protected".
+
+<hr>
+\section cmdprotocol \\protocol <name> [<header-file>] [<header-name>]
+
+ \addindex \\protocol
+ Indicates that a comment block contains documentation for a
+ protocol in Objective-C with name \<name\>. The arguments are equal
+ to the \ref cmdclass "\\class" command.
+
+ \sa section \ref cmdclass "\\class".
+
+<hr>
+\section cmdpublic \\public
+
+ \addindex \\public
+ Indicates that the member documented by the comment block is public,
+ i.e., can be accessed by any other class or function.
+
+ Note that Doxygen automatically detects the protection level of members
+ in object-oriented languages. This command is intended for use only when
+ the language does not support the concept of protection level natively
+ (e.g. C, PHP 4).
+
+ For starting a section of public members, in a way similar to the
+ "public:" class marker in C++, use \ref cmdpublicsection "\\publicsection".
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdprotected "\\protected",
+ \ref cmdprivate "\\private" and \ref cmdpublicsection "\\publicsection".
+
+<hr>
+\section cmdpublicsection \\publicsection
+
+ \addindex \\publicsection
+ Starting a section of public members, in a way similar to the
+ "public:" class marker in C++.
+ Indicates that the member documented by the comment block is public,
+ i.e., can be accessed by any other class or function.
+
+ \sa sections \ref cmdmemberof "\\memberof", \ref cmdprotected "\\protected",
+ \ref cmdprivate "\\private" and \ref cmdpublic "\\public".
+
+<hr>
+\section cmdpure \\pure
+
+ \addindex \\pure
+ Indicates that the member documented by the comment block is pure virtual,
+ i.e., it is abstract and has no implementation associated with it.
+
+ This command is intended for use only when
+ the language does not support the concept of pure virtual methods natively
+ (e.g. C, PHP 4).
+
+<hr>
+\section cmdrelates \\relates <name>
+
+ \addindex \\relates
+ This command can be used in the documentation of a non-member function
+ \<name\>. It puts the function inside the 'related function' section
+ of the class documentation. This command is useful for documenting
+ non-friend functions that are nevertheless strongly coupled to a certain
+ class. It prevents the need of having to document a file, but
+ only works for functions.
+
+ \par Example:
+ \verbinclude relates.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/relates/html/class_string.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmdrelated \\related <name>
+
+ \addindex \\related
+ Equivalent to \ref cmdrelates "\\relates"
+
+<hr>
+\section cmdrelatesalso \\relatesalso <name>
+
+ \addindex \\relatesalso
+ This command can be used in the documentation of a non-member function
+ \<name\>. It puts the function both inside the 'related function' section
+ of the class documentation as well as leaving it at its normal file documentation
+ location. This command is useful for documenting
+ non-friend functions that are nevertheless strongly coupled to a certain
+ class. It only works for functions.
+
+<hr>
+\section cmdrelatedalso \\relatedalso <name>
+
+ \addindex \\relatedalso
+ Equivalent to \ref cmdrelatesalso "\\relatesalso"
+
+<hr>
+\section cmdshowinitializer \\showinitializer
+
+ \addindex \\showinitializer
+ By default the value of a define and the initializer of a variable
+ are only displayed if they are less than 30 lines long. By putting
+ this command in a comment block of a define or variable, the
+ initializer is shown unconditionally.
+ The maximum number of initialization lines
+ can be changed by means of the configuration parameter
+ \ref cfg_max_initializer_lines "MAX_INITIALIZER_LINES", the default value is
+ 30.
+
+ \sa section \ref cmdhideinitializer "\\hideinitializer".
+
+<hr>
+\section cmdstatic \\static
+
+ \addindex \\static
+ Indicates that the member documented by the comment block is static,
+ i.e., it works on a class, instead of on an instance of the class.
+
+ This command is intended for use only when
+ the language does not support the concept of static methods natively (e.g. C).
+
+<hr>
+\section cmdstruct \\struct <name> [<header-file>] [<header-name>]
+
+ \addindex \\struct
+ Indicates that a comment block contains documentation for a
+ struct with name \<name\>. The arguments are equal to the arguments of the
+ \ref cmdclass "\\class" command.
+
+ \sa section \ref cmdclass "\\class".
+
+<hr>
+\section cmdtypedef \\typedef (typedef declaration)
+
+ \addindex \\typedef
+ Indicates that a comment block contains documentation for a
+ typedef (either global or as a member of a class).
+ This command is equivalent to \ref cmdfn "\\fn",
+ \ref cmdproperty "\\property", and \ref cmdvar "\\var".
+
+ \sa section \ref cmdfn "\\fn", \ref cmdproperty "\\property", and
+ \ref cmdvar "\\var".
+
+<hr>
+\section cmdunion \\union <name> [<header-file>] [<header-name>]
+
+ \addindex \\union
+ Indicates that a comment block contains documentation for a
+ union with name \<name\>. The arguments are equal to the arguments of the
+ \ref cmdclass "\\class" command.
+
+ \sa section \ref cmdclass "\\class".
+
+<hr>
+\section cmdvar \\var (variable declaration)
+
+ \addindex \\var
+ Indicates that a comment block contains documentation for a variable or
+ enum value (either global or as a member of a class).
+ This command is equivalent to \ref cmdfn "\\fn",
+ \ref cmdproperty "\\property", and \ref cmdtypedef "\\typedef".
+
+ \sa section \ref cmdfn "\\fn", \ref cmdproperty "\\property", and \ref cmdtypedef "\\typedef".
+
+<hr>
+\section cmdvhdlflow \\vhdlflow [(title for the flow chart)]
+
+ \addindex \\vhdlflow
+ This is a VHDL specific command, which can be put in the documentation of a process to
+ produce a flow chart of the logic in the process.
+ Optionally a title for the flow chart can be given.
+ \note Currently the flow chart will only appear in the HTML output.
+
+<hr>
+\section cmdweakgroup \\weakgroup <name> [(title)]
+ \addindex \\addtogroup
+ Can be used exactly like \ref cmdaddtogroup "\\addtogroup", but has
+ a lower priority when it comes to resolving conflicting grouping
+ definitions.
+
+ \sa page \ref grouping "Grouping" and section \ref cmdaddtogroup "\\addtogroup".
+
+<hr>
+
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Section indicators
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center>\endhtmlonly
+
+<hr>
+\section cmdattention \\attention { attention text }
+
+ \addindex \\attention
+ Starts a paragraph where a message that needs attention may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\attention commands will be joined into a single paragraph.
+ The \c \\attention command ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdauthor \\author { list of authors }
+
+ \addindex \\author
+ Starts a paragraph where one or more author names may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\author commands will be joined into a single paragraph.
+ Each author description will start a new line. Alternatively, one \c \\author command
+ may mention several authors. The \c \\author command ends when a blank line or some other
+ sectioning command is encountered.
+
+ \par Example:
+ \verbinclude author.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/author/html/class_some_nice_class.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmdauthors \\authors { list of authors }
+
+ \addindex \\authors
+ Equivalent to \ref cmdauthor "\\author".
+
+<hr>
+\section cmdbrief \\brief { brief description }
+
+ \addindex \\brief
+ Starts a paragraph that serves as a brief description. For classes and files
+ the brief description will be used in lists and at the start of the
+ documentation page. For class and file members, the brief description
+ will be placed at the declaration of the member and prepended to the
+ detailed description. A brief description may span several lines (although
+ it is advised to keep it brief!). A brief description ends when a
+ blank line or another sectioning command is encountered. If multiple
+ \c \\brief commands are present they will be joined. See section
+ \ref cmdauthor "\\author" for an example.
+
+ Synonymous to \ref cmdshort "\\short".
+
+<hr>
+\section cmdbug \\bug { bug description }
+
+ \addindex \\bug
+ Starts a paragraph where one or more bugs may be reported.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\bug commands will be joined into a single paragraph.
+ Each bug description will start on a new line.
+ Alternatively, one \c \\bug command may mention
+ several bugs. The \c \\bug command ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdauthor "\\author"
+ for an example.
+
+<hr>
+\section cmdcond \\cond [(section-label)]
+
+ \addindex \\cond
+ Starts a conditional section that ends with a corresponding
+ \ref cmdendcond "\\endcond" command, which is typically found in
+ another comment block. The main purpose of this pair of
+ commands is to (conditionally) exclude part of a file from processing
+ (in older version of doxygen this could only be achieved using C preprocessor commands).
+
+ The section between \c \\cond and \ref cmdendcond "\\endcond" can be included by
+ adding its section label to the \ref cfg_enabled_sections "ENABLED_SECTIONS"
+ configuration option. If the section label is omitted, the section will
+ be excluded from processing unconditionally. The section label can be a
+ logical expression build of section labels, round brackets, && (AND), || (OR) and ! (NOT).
+ If you use an expression you need to wrap it in round brackets, i.e
+ <tt>\\cond (!LABEL1 && LABEL2)</tt>.
+
+ For conditional sections within a comment block one should
+ use a \ref cmdif "\\if" ... \ref cmdendif "\\endif" block.
+
+ Conditional sections can be nested. In this case a nested section will only
+ be shown if it and its containing section are included.
+
+ Here is an example showing the commands in action:
+
+\verbatim
+/** An interface */
+class Intf
+{
+ public:
+ /** A method */
+ virtual void func() = 0;
+
+ /// @cond TEST
+
+ /** A method used for testing */
+ virtual void test() = 0;
+
+ /// @endcond
+};
+
+/// @cond DEV
+/*
+ * The implementation of the interface
+ */
+class Implementation : public Intf
+{
+ public:
+ void func();
+
+ /// @cond TEST
+ void test();
+ /// @endcond
+
+ /// @cond
+ /** This method is obsolete and does
+ * not show up in the documentation.
+ */
+ void obsolete();
+ /// @endcond
+};
+
+/// @endcond
+\endverbatim
+
+The output will be different depending on whether or not \ref cfg_enabled_sections "ENABLED_SECTIONS"
+contains \c TEST, or \c DEV
+
+ \sa sections \ref cmdendcond "\\endcond" and \ref cfg_enabled_sections "ENABLED_SECTIONS".
+
+<hr>
+\section cmdcopyright \\copyright { copyright description }
+
+ \addindex \\copyright
+ Starts a paragraph where the copyright of an entity can be described.
+ This paragraph will be indented.
+ The text of the paragraph has no special internal structure.
+ See section \ref cmdauthor "\\author" for an example.
+
+<hr>
+\section cmddate \\date { date description }
+
+ \addindex \\date
+ Starts a paragraph where one or more dates may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\date commands will be joined into a single paragraph.
+ Each date description will start on a new line.
+ Alternatively, one \c \\date command may mention
+ several dates. The \c \\date command ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdauthor "\\author"
+ for an example.
+
+<hr>
+\section cmddeprecated \\deprecated { description }
+
+ \addindex \\deprecated
+ Starts a paragraph indicating that this documentation block belongs to
+ a deprecated entity. Can be used to describe alternatives,
+ expected life span, etc.
+
+<hr>
+\section cmddetails \\details { detailed description }
+
+ \addindex \\details
+ Just like \ref cmdbrief "\\brief" starts a brief description, \c \\details
+ starts the detailed description. You can also start a new paragraph (blank line)
+ then the \c \\details command is not needed.
+
+<hr>
+\section cmdelse \\else
+
+ \addindex \\else
+ Starts a conditional section if the previous conditional section
+ was not enabled. The previous section should have been started with
+ a \ref cmdif "\\if", \ref cmdifnot "\\ifnot", or \ref cmdelseif "\\elseif"
+ command.
+
+ \sa \ref cmdif "\\if", \ref cmdifnot "\\ifnot", \ref cmdelseif "\\elseif",
+ \ref cmdendif "\\endif."
+
+<hr>
+\section cmdelseif \\elseif (section-label)
+
+ \addindex \\elseif
+ Starts a conditional documentation section if the previous section
+ was not enabled. A conditional section is
+ disabled by default. To enable it you must put the
+ section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS"
+ tag in the configuration file. The section label can be a logical expression
+ build of section names, round brackets, && (AND), || (OR) and ! (NOT).
+ Conditional blocks can be nested. A nested section is
+ only enabled if all enclosing sections are enabled as well.
+
+ \sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot",
+ \ref cmdelse "\\else", and \ref cmdelseif "\\elseif".
+
+<hr>
+\section cmdendcond \\endcond
+
+ \addindex \\endcond
+ Ends a conditional section that was started by \ref cmdcond "\\cond".
+
+ \sa section \ref cmdcond "\\cond".
+
+<hr>
+\section cmdendif \\endif
+
+ \addindex \\endif
+ Ends a conditional section that was started by \ref cmdif "\\if" or \ref cmdifnot "\\ifnot"
+ For each \ref cmdif "\\if" or \ref cmdifnot "\\ifnot" one and only one matching
+ \ref cmdendif "\\endif" must follow.
+
+ \sa sections \ref cmdif "\\if" and \ref cmdifnot "\\ifnot".
+
+<hr>
+\section cmdexception \\exception <exception-object> { exception description }
+
+ \addindex \\exception
+ Starts an exception description for an exception object with name
+ \<exception-object\>. Followed by a description of the exception.
+ The existence of the exception object is not checked.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\exception commands will be joined into a single paragraph.
+ Each exception description will start on a new line.
+ The \c \\exception description ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdfn "\\fn" for an
+ example.
+
+<hr>
+\section cmdif \\if (section-label)
+
+ \addindex \\if
+ Starts a conditional documentation section. The section ends
+ with a matching \ref cmdendif "\\endif" command. A conditional section is
+ disabled by default. To enable it you must put the
+ section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS"
+ tag in the configuration file.
+
+ The section label can be a logical expression
+ build of section names, round brackets, && (AND), || (OR) and ! (NOT).
+ If you use an expression you need to wrap it in round brackets, i.e
+ <tt>\\cond (!LABEL1 && LABEL2)</tt>.
+
+ Conditional blocks can be nested. A nested section is
+ only enabled if all enclosing sections are enabled as well.
+
+ \par Example:
+\verbatim
+ /*! Unconditionally shown documentation.
+ * \if Cond1
+ * Only included if Cond1 is set.
+ * \endif
+ * \if Cond2
+ * Only included if Cond2 is set.
+ * \if Cond3
+ * Only included if Cond2 and Cond3 are set.
+ * \endif
+ * More text.
+ * \endif
+ * Unconditional text.
+ */
+\endverbatim
+
+ You can also use conditional commands inside aliases. To
+ document a class in two languages you could for instance use:
+
+\par Example 2:
+\verbatim
+/*! \english
+ * This is English.
+ * \endenglish
+ * \dutch
+ * Dit is Nederlands.
+ * \enddutch
+ */
+class Example
+{
+};
+\endverbatim
+
+ Where the following aliases are defined in the configuration file:
+
+\verbatim
+ALIASES = "english=\if english" \
+ "endenglish=\endif" \
+ "dutch=\if dutch" \
+ "enddutch=\endif"
+\endverbatim
+
+ and \ref cfg_enabled_sections "ENABLED_SECTIONS" can be used to enable either \c english or \c dutch.
+
+ \sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot",
+ \ref cmdelse "\\else", \ref cmdelseif "\\elseif", and
+ \ref cfg_enabled_sections "ENABLED_SECTIONS".
+
+<hr>
+\section cmdifnot \\ifnot (section-label)
+
+ \addindex \\ifnot
+ Starts a conditional documentation section. The section ends
+ with a matching \ref cmdendif "\\endif" command. This conditional section is
+ enabled by default. To disable it you must put the
+ section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS"
+ tag in the configuration file. The section label can be a logical expression
+ build of section names, round brackets, && (AND), || (OR) and ! (NOT).
+
+ \sa sections \ref cmdendif "\\endif", \ref cmdif "\\if",
+ \ref cmdelse "\\else", and \ref cmdelseif "\\elseif", and
+ \ref cfg_enabled_sections "ENABLED_SECTIONS".
+
+<hr>
+\section cmdinvariant \\invariant { description of invariant }
+
+ \addindex \\invariant
+ Starts a paragraph where the invariant of an entity can be described.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\invariant commands will be joined into a single paragraph.
+ Each invariant description will start on a new line.
+ Alternatively, one \c \\invariant command may mention
+ several invariants. The \c \\invariant command ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdnote \\note { text }
+
+ \addindex \\note
+ Starts a paragraph where a note can be entered. The paragraph will be
+ indented. The text of the paragraph has no special internal structure.
+ All visual enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\note commands will be joined into a single paragraph.
+ Each note description will start on a new line.
+ Alternatively, one \c \\note command may mention
+ several notes. The \c \\note command ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdpar "\\par"
+ for an example.
+
+<hr>
+\section cmdpar \\par [(paragraph title)] { paragraph }
+
+ \addindex \\par
+ If a paragraph title is given this command starts a paragraph with a
+ user defined heading. The heading extends until the end of the
+ line. The paragraph following the command will be indented.
+
+ If no paragraph title is given this command will start a new paragraph.
+ This will also work inside other paragraph commands
+ (like \ref cmdparam "\\param" or \ref cmdwarning "\\warning") without ending that command.
+
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ The \c \\par command ends when a blank line or some other
+ sectioning command is encountered.
+
+ \par Example:
+ \verbinclude par.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/par/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+<hr>
+\section cmdparam \\param [(dir)] <parameter-name> { parameter description }
+
+ \addindex \\param
+ Starts a parameter description for a function parameter with name
+ \<parameter-name\>, followed by a description of the parameter.
+ The existence of the parameter is checked and a warning is given if
+ the documentation of this (or any other) parameter is missing or not
+ present in the function declaration or definition.
+
+ The \c \\param command has an optional attribute, (dir), specifying the direction
+ of the parameter. Possible values are "[in]", "[in,out]", and "[out]",
+ note the [square] brackets in this description.
+ When a parameter is both input and output, [in,out] is used as attribute.
+ Here is an example for the function \c memcpy:
+ \code
+/*!
+ * Copies bytes from a source memory area to a destination memory area,
+ * where both areas may not overlap.
+ * @param[out] dest The memory area to copy to.
+ * @param[in] src The memory area to copy from.
+ * @param[in] n The number of bytes to copy
+ */
+void memcpy(void *dest, const void *src, size_t n);
+ \endcode
+
+ The parameter description is a paragraph with no special internal structure.
+ All visual enhancement commands may be used inside the paragraph.
+
+ Multiple adjacent \c \\param commands will be joined into a single paragraph.
+ Each parameter description will start on a new line.
+ The \c \\param description ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdfn "\\fn" for an
+ example.
+
+ Note that you can also document multiple parameters with a single
+ \c \\param command using a comma separated list. Here is an example:
+
+\code
+/** Sets the position.
+ * @param x,y,z Coordinates of the position in 3D space.
+ */
+void setPosition(double x,double y,double z,double t)
+{
+}
+\endcode
+
+ Note that for PHP one can also specify the type (or types if you
+ separate them with a pipe symbol) which are allowed for a parameter
+ (as this is not part of the definition).
+ The syntax is the same as for phpDocumentor, i.e.
+\verbatim
+ at param datatype1|datatype2 $paramname description
+\endverbatim
+
+<hr>
+\section cmdparblock \\parblock
+ \addindex \\parblock
+ For commands that expect a single paragraph as argument
+ (such as \ref cmdpar "\\par", \ref cmdparam "\\param" and \ref cmdwarning "\\warning"),
+ the \ref cmdparblock "\\parblock" command allows to start a
+ description that covers multiple paragraphs, which then ends with
+ \ref cmdendparblock "\\endparblock".
+
+ Example:
+\verbatim
+/** Example of a param command with a description consisting of two paragraphs
+ * \param p
+ * \parblock
+ * First paragraph of the param description.
+ *
+ * Second paragraph of the param description.
+ * \endparblock
+ * Rest of the comment block continues.
+ */
+\endverbatim
+ Note that the \c \\parblock command may also appear directly after
+ \ref cmdparam "\\param"'s first argument.
+
+<hr>
+\section cmdendparblock \\endparblock
+ \addindex \\endparblock
+ This ends a block of paragraphs started with \ref cmdparblock "\\parblock".
+
+<hr>
+\section cmdtparam \\tparam <template-parameter-name> { description }
+
+ \addindex \\tparam
+ Starts a template parameter for a class or function template parameter
+ with name \<template-parameter-name\>, followed by a description of the
+ template parameter.
+
+ Otherwise similar to \ref cmdparam "\\param".
+
+<hr>
+\section cmdpost \\post { description of the postcondition }
+
+ \addindex \\post
+ Starts a paragraph where the postcondition of an entity can be described.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\post commands will be joined into a single paragraph.
+ Each postcondition will start on a new line.
+ Alternatively, one \c \\post command may mention
+ several postconditions. The \c \\post command ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdpre \\pre { description of the precondition }
+
+ \addindex \\pre
+ Starts a paragraph where the precondition of an entity can be described.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\pre commands will be joined into a single paragraph.
+ Each precondition will start on a new line.
+ Alternatively, one \c \\pre command may mention
+ several preconditions. The \c \\pre command ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdremark \\remark { remark text }
+
+ \addindex \\remark
+ Starts a paragraph where one or more remarks may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\remark commands will be joined into a single paragraph.
+ Each remark will start on a new line.
+ Alternatively, one \c \\remark command may mention
+ several remarks. The \c \\remark command ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdremarks \\remarks { remark text }
+
+ \addindex \\remarks
+ Equivalent to \ref cmdremark "\\remark".
+
+<hr>
+\section cmdresult \\result { description of the result value }
+
+ \addindex \\result
+ Equivalent to \ref cmdreturn "\\return".
+
+<hr>
+\section cmdreturn \\return { description of the return value }
+
+ \addindex \\return
+ Starts a return value description for a function.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\return commands will be joined into a single paragraph.
+ The \c \\return description ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdfn "\\fn" for an
+ example.
+
+<hr>
+\section cmdreturns \\returns { description of the return value }
+
+ \addindex \\returns
+ Equivalent to \ref cmdreturn "\\return".
+
+<hr>
+\section cmdretval \\retval <return value> { description }
+
+ \addindex \\retval
+ Starts a description for a function's return value with name
+ \<return value\>, followed by a description of the return value.
+ The text of the paragraph that forms the description has no special
+ internal structure. All visual enhancement commands may be used inside the
+ paragraph.
+ Multiple adjacent \c \\retval commands will be joined into a single paragraph.
+ Each return value description will start on a new line.
+ The \c \\retval description ends when a blank line or some other
+ sectioning command is encountered.
+
+<hr>
+\section cmdsa \\sa { references }
+
+ \addindex \\sa
+ Starts a paragraph where one or more cross-references to classes,
+ functions, methods, variables, files or URL may be specified.
+ Two names joined by either <code>::</code> or <code>\#</code>
+ are understood as referring to a class and one of its members.
+ One of several overloaded methods or constructors
+ may be selected by including a parenthesized list of argument types after
+ the method name.
+
+ Synonymous to \ref cmdsee "\\see".
+
+ \sa section \ref autolink "autolink" for information on how to create links
+ to objects.
+
+<hr>
+\section cmdsee \\see { references }
+
+ \addindex \\see
+ Equivalent to \ref cmdsa "\\sa". Introduced for compatibility with Javadoc.
+
+<hr>
+\section cmdshort \\short { short description }
+
+ \addindex \\short
+ Equivalent to \ref cmdbrief "\\brief".
+
+<hr>
+\section cmdsince \\since { text }
+
+ \addindex \\since
+ This command can be used to specify since when (version or time) an
+ entity is available. The paragraph that follows \c \\since does not have any
+ special internal structure. All visual enhancement commands may be
+ used inside the paragraph. The \c \\since description ends when a blank
+ line or some other sectioning command is encountered.
+
+<hr>
+\section cmdtest \\test { paragraph describing a test case }
+
+ \addindex \\test
+ Starts a paragraph where a test case can be described.
+ The description will also add the test case to a separate test list.
+ The two instances of the description will be cross-referenced.
+ Each test case in the test list will be preceded by a header that
+ indicates the origin of the test case.
+
+<hr>
+\section cmdthrow \\throw <exception-object> { exception description }
+
+ \addindex \\throw
+ Synonymous \ref cmdexception "\\exception".
+
+ \par Note:
+ the command \ref cmdthrows "\\throws" is a synonym for this command.
+
+ \sa section \ref cmdexception "\\exception"
+
+<hr>
+\section cmdthrows \\throws <exception-object> { exception description }
+
+ \addindex \\throws
+ Equivalent to \ref cmdthrow "\\throw".
+
+<hr>
+\section cmdtodo \\todo { paragraph describing what is to be done }
+
+ \addindex \\todo
+ Starts a paragraph where a TODO item is described.
+ The description will also add an item to a separate TODO list.
+ The two instances of the description will be cross-referenced.
+ Each item in the TODO list will be preceded by a header that
+ indicates the origin of the item.
+
+<hr>
+\section cmdversion \\version { version number }
+
+ \addindex \\version
+ Starts a paragraph where one or more version strings may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\version commands will be joined into a single paragraph.
+ Each version description will start on a new line.
+ Alternatively, one \c \\version command may mention
+ several version strings.
+ The \\version command ends when a blank line or some other
+ sectioning command is encountered.
+ See section \ref cmdauthor "\\author" for an example.
+
+<hr>
+\section cmdwarning \\warning { warning message }
+
+ \addindex \\warning
+ Starts a paragraph where one or more warning messages may be entered.
+ The paragraph will be indented.
+ The text of the paragraph has no special internal structure. All visual
+ enhancement commands may be used inside the paragraph.
+ Multiple adjacent \c \\warning commands will be joined into a single paragraph.
+ Each warning description will start on a new line.
+ Alternatively, one \c \\warning command may mention
+ several warnings. The \c \\warning command ends when a blank line or some other
+ sectioning command is encountered. See section \ref cmdauthor "\\author"
+ for an example.
+
+<hr>
+\section cmdxrefitem \\xrefitem <key> "(heading)" "(list title)" { text }
+
+ \addindex \\xrefitem
+ This command is a generalization of commands such as \ref cmdtodo "\\todo"
+ and \ref cmdbug "\\bug".
+ It can be used to create user-defined text sections which are automatically
+ cross-referenced between the place of occurrence and a related page,
+ which will be generated. On the related page all sections of
+ the same type will be collected.
+
+ The first argument \<key\> is an
+ identifier uniquely representing the type of the section. The second argument
+ is a quoted string representing the heading of the section under which
+ text passed as the fourth argument is put. The third argument (list title)
+ is used as the title for the related page containing all items with the
+ same key. The keys \c "todo", \c "test", \c "bug" and \c "deprecated" are predefined.
+
+ To get an idea on how to use the \c \\xrefitem command and what its effect
+ is, consider the todo list, which (for English output) can be seen an
+ alias for the command
+ \verbatim \xrefitem todo "Todo" "Todo List" \endverbatim
+
+ Since it is very tedious and error-prone to repeat the first three
+ parameters of the command for each section, the command is meant to
+ be used in combination with the \ref cfg_aliases "ALIASES" option in the
+ configuration file.
+ To define a new command \c \\reminder, for instance, one should add the following
+ line to the configuration file:
+ \verbatim ALIASES += "reminder=\xrefitem reminders \"Reminder\" \"Reminders\"" \endverbatim
+ Note the use of escaped quotes for the second and third argument of the
+ \c \\xrefitem command.
+
+ In case parameter "(heading)" is the empty string no heading is generated. This can be useful
+ when used in combination with the \ref cmdpage "\\page" command e.g.
+\verbatim
+/** @page my_errors My Errors
+ * @brief Errors page
+ *
+ * Errors page contents.
+ */
+
+/** \error ERROR 101: in case a file can not be opened.
+ Check about file system read/write access. */
+#define MY_ERR_CANNOT_OPEN_FILE 101
+
+/** \error ERROR 102: in case a file can not be closed.
+ Check about file system read/write access. */
+#define MY_ERR_CANNOT_CLOSE_FILE 102
+\endverbatim
+ with \c \\error defined as
+ \verbatim ALIASES += "error=\xrefitem my_errors \"\" \"\"" \endverbatim
+
+<hr>
+
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Commands to create links
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center>\endhtmlonly
+
+<hr>
+\section cmdaddindex \\addindex (text)
+
+ \addindex \\addindex
+ This command adds (text) to the \LaTeX index.
+
+<hr>
+\section cmdanchor \\anchor <word>
+
+ \addindex \\anchor
+ This command places an invisible, named anchor into the documentation
+ to which you can refer with the \ref cmdref "\\ref" command.
+
+ \note Anchors can currently only be put into a comment block
+ that is marked as a page (using \ref cmdpage "\\page") or mainpage
+ (\ref cmdmainpage "\\mainpage").
+
+ \sa section \ref cmdref "\\ref".
+
+<hr>
+\section cmdcite \\cite <label>
+
+ \addindex \\cite
+ Adds a bibliographic reference in the text and in the list of bibliographic
+ references. The \<label\> must be a valid BibTeX label that can be found
+ in one of the .bib files listed in \ref cfg_cite_bib_files "CITE_BIB_FILES".
+ For the \LaTeX output the formatting of the reference in the text can be
+ configured with \ref cfg_latex_bib_style "LATEX_BIB_STYLE". For other
+ output formats a fixed representation is used. Note that using this
+ command requires the \c bibtex tool to be present in the search path.
+
+<hr>
+\section cmdendlink \\endlink
+
+ \addindex \\endlink
+ This command ends a link that is started with the \ref cmdlink "\\link" command.
+
+ \sa section \ref cmdlink "\\link".
+
+<hr>
+\section cmdlink \\link <link-object>
+
+ \addindex \\link
+ The links that are automatically generated by doxygen always have the
+ name of the object they point to as link-text.
+
+ The \c \\link command can be used to create a link to an object (a file,
+ class, or member) with a user specified link-text.
+ The link command should end with an \ref cmdendlink "\\endlink" command. All text between
+ the \c \\link and \ref cmdendlink "\\endlink" commands serves as text for a link to
+ the \<link-object\> specified as the first argument of \c \\link.
+
+ \sa Section \ref autolink "autolink" for more information on automatically
+ generated links and valid link-objects.
+
+<hr>
+\section cmdref \\ref <name> ["(text)"]
+
+ \addindex \\ref
+ Creates a reference to a named section, subsection, page or anchor.
+ For HTML documentation the reference command will generate a link to
+ the section. For a section or subsection the title of the section will be
+ used as the text of the link. For an anchor the optional text between quotes
+ will be used or \<name\> if no text is specified.
+ For \LaTeX documentation the reference command will
+ generate a section number for sections or the text followed by a
+ page number if \<name\> refers to an anchor.
+
+ \sa
+ Section \ref cmdpage "\\page" for an example of the \c \\ref command.
+
+<hr>
+\section cmdrefitem \\refitem <name>
+ \addindex \\refitem
+ Just like the \ref cmdref "\\ref" command, this command creates a reference
+ to a named section, but this reference appears in a list that is started by
+ \ref cmdsecreflist "\\secreflist"
+ and ends with \ref cmdendsecreflist "\\endsecreflist".
+ An example of such a list can be seen
+ \ref showsecreflist "at the top of the page".
+
+<hr>
+\section cmdsecreflist \\secreflist
+ \addindex \\secreflist
+ Starts an index list of item, created with \ref cmdrefitem "\\refitem"
+ that each link to a named section.
+
+<hr>
+\section cmdendsecreflist \\endsecreflist
+ \addindex \\endsecreflist
+ End an index list started with \ref cmdsecreflist "\\secreflist".
+
+<hr>
+\section cmdsubpage \\subpage <name> ["(text)"]
+
+ \addindex \\subpage
+ This command can be used to create a hierarchy of pages. The
+ same structure can be made using the \ref cmddefgroup "\\defgroup" and
+ \ref cmdingroup "\\ingroup" commands, but for pages the \c \\subpage command
+ is often more convenient. The main page (see \ref cmdmainpage "\\mainpage")
+ is typically the root of hierarchy.
+
+ This command behaves similar as \ref cmdref "\\ref" in the sense that
+ it creates a reference to a page labeled \<name\> with the optional
+ link text as specified in the second argument.
+
+ It differs from the \ref cmdref "\\ref" command in that it only works for pages,
+ and creates a parent-child relation between pages, where the
+ child page (or sub page) is identified by label \<name\>.
+
+ See the \ref cmdsection "\\section"
+ and \ref cmdsubsection "\\subsection" commands if you want to add structure
+ without creating multiple pages.
+
+ \note Each page can be the sub page of only one other page and
+ no cyclic relations are allowed, i.e. the page hierarchy must have a tree
+ structure.
+
+ Here is an example:
+\verbatim
+/*! \mainpage A simple manual
+
+Some general info.
+
+This manual is divided in the following sections:
+- \subpage intro
+- \subpage advanced "Advanced usage"
+*/
+
+//-----------------------------------------------------------
+
+/*! \page intro Introduction
+This page introduces the user to the topic.
+Now you can proceed to the \ref advanced "advanced section".
+*/
+
+//-----------------------------------------------------------
+
+/*! \page advanced Advanced Usage
+This page is for advanced users.
+Make sure you have first read \ref intro "the introduction".
+*/
+\endverbatim
+
+<hr>
+\section cmdtableofcontents \\tableofcontents
+
+ \addindex \\tableofcontents
+ Creates a table of contents at the top of a page, listing all
+ sections and subsections in the page.
+
+ \warning This command only works inside related page documentation and
+ \e not in other documentation blocks and only has effect in the
+ HTML output!
+
+<hr>
+\section cmdsection \\section <section-name> (section title)
+
+ \addindex \\section
+ Creates a section with name \<section-name\>. The title of the
+ section should be specified as the second argument of the \c \\section
+ command.
+
+ \warning This command only works inside related page documentation and
+ \e not in other documentation blocks!
+
+ \sa
+ Section \ref cmdpage "\\page" for an example of the
+ \c \\section command.
+
+<hr>
+\section cmdsubsection \\subsection <subsection-name> (subsection title)
+
+ \addindex \\subsection
+ Creates a subsection with name \<subsection-name\>. The title of the
+ subsection should be specified as the second argument of the \c \\subsection
+ command.
+
+ \warning This command only works inside a section of a related page
+ documentation block and
+ \e not in other documentation blocks!
+
+ \sa
+ Section \ref cmdpage "\\page" for an example of the
+ \c \\subsection command.
+
+<hr>
+\section cmdsubsubsection \\subsubsection <subsubsection-name> (subsubsection title)
+
+ \addindex \\subsubsection
+ Creates a subsubsection with name \<subsubsection-name\>. The title of the
+ subsubsection should be specified as the second argument of the
+ \c \\subsubsection command.
+
+ \warning This command only works inside a subsection of a
+ related page documentation block and
+ \e not in other documentation blocks!
+
+ \sa
+ Section \ref cmdpage "\\page" for an example of the
+ \ref cmdsection "\\section" command and
+ \ref cmdsubsection "\\subsection" command.
+
+<hr>
+\section cmdparagraph \\paragraph <paragraph-name> (paragraph title)
+
+ \addindex \\paragraph
+ Creates a named paragraph with name \<paragraph-name\>. The title of the
+ paragraph should be specified as the second argument of the
+ \c \\paragraph command.
+
+ \warning This command only works inside a subsubsection of a
+ related page documentation block and
+ \e not in other documentation blocks!
+
+<hr>
+
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Commands for displaying examples
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center>\endhtmlonly
+
+<hr>
+\section cmddontinclude \\dontinclude <file-name>
+
+ \addindex \\dontinclude
+ This command can be used to parse a source file without actually
+ verbatim including it in the documentation (as the \ref cmdinclude "\\include" command does).
+ This is useful if you want to divide the source file into smaller pieces and
+ add documentation between the pieces.
+ Source files or directories can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH"
+ tag of doxygen's configuration file.
+
+ The class and member declarations and definitions inside the code fragment
+ are 'remembered' during the parsing of the comment block that contained
+ the \c \\dontinclude command.
+
+ For line by line descriptions of source files, one or more lines
+ of the example can be displayed using the \ref cmdline "\\line",
+ \ref cmdskip "\\skip", \ref cmdskipline "\\skipline", and
+ \ref cmduntil "\\until" commands. An internal pointer is used for these commands. The
+ \c \\dontinclude command sets the pointer to the first line of the example.
+
+ \par Example:
+ \verbinclude include.cpp
+ Where the example file \c example_test.cpp looks as follows:
+ \verbinclude example_test.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/include/html/example.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ Alternatively, the \ref cmdsnippet "\\snippet" command can be used to
+ include only a fragment of a source file. For this to work the
+ fragment has to be marked.
+
+ \sa sections \ref cmdline "\\line", \ref cmdskip "\\skip",
+ \ref cmdskipline "\\skipline", \ref cmduntil "\\until", and
+ \ref cmdinclude "\\include".
+
+<hr>
+\section cmdinclude \\include <file-name>
+
+ \addindex \\include
+ This command can be used to include a source file as a block of code.
+ The command takes the name of an include file as an argument.
+ Source files or directories can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH"
+ tag of doxygen's configuration file.
+
+ If \<file-name\> itself is not unique for the set of example files specified
+ by the \ref cfg_example_path "EXAMPLE_PATH" tag, you can include part
+ of the absolute path to disambiguate it.
+
+ Using the \c \\include command is equivalent to inserting the file into
+ the documentation block and surrounding it
+ with \ref cmdcode "\\code" and \ref cmdendcode "\\endcode" commands.
+
+ The main purpose of the \c \\include command is to avoid code
+ duplication in case of example blocks that consist of multiple
+ source and header files.
+
+ For a line by line description of a source files use the
+ \ref cmddontinclude "\\dontinclude" command in combination with
+ the \ref cmdline "\\line", \ref cmdskip "\\skip",
+ \ref cmdskipline "\\skipline",
+ and \ref cmduntil "\\until" commands.
+
+ Alternatively, the \ref cmdsnippet "\\snippet" command can be used to
+ include only a fragment of a source file. For this to work the
+ fragment has to be marked.
+
+ \note Doxygen's special commands do not work inside blocks of code.
+ It is allowed to nest C-style comments inside a code block though.
+
+ \sa sections \ref cmdexample "\\example", \ref cmddontinclude "\\dontinclude", and
+ \ref cmdverbatim "\\verbatim".
+
+<hr>
+\section cmdincludelineno \\includelineno <file-name>
+
+ \addindex \\includelineno
+ This command works the same way as \ref cmdinclude "\\include", but will add line
+ numbers to the included file.
+
+ \sa section \ref cmdinclude "\\include".
+
+<hr>
+\section cmdline \\line ( pattern )
+
+ \addindex \\line
+ This command searches line by line through the example that was last
+ included using \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude" until it finds a non-blank
+ line. If that line contains the specified pattern, it is written
+ to the output.
+
+ The internal pointer that is used to keep track of the current line in
+ the example, is set to the start of the line following the non-blank
+ line that was found (or to the end of the example if no such line could
+ be found).
+
+ See section \ref cmddontinclude "\\dontinclude" for an example.
+
+<hr>
+\section cmdskip \\skip ( pattern )
+
+ \addindex \\skip
+ This command searches line by line through the example that was last
+ included using \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude" until it finds a line that contains
+ the specified pattern.
+
+ The internal pointer that is used to keep track of the current line in
+ the example, is set to the start of the line that contains the specified
+ pattern (or to the end of the example if the pattern could not be found).
+
+ See section \ref cmddontinclude "\\dontinclude" for an example.
+
+<hr>
+\section cmdskipline \\skipline ( pattern )
+
+ \addindex \\skipline
+ This command searches line by line through the example that was last
+ included using \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude" until it finds a line that contains
+ the specified pattern. It then writes the line to the output.
+
+ The internal pointer that is used to keep track of the current line in
+ the example, is set to the start of the line following the line that is
+ written (or to the end of the example if the pattern could not be found).
+
+ \par Note:
+ The command:
+ \verbatim\skipline pattern\endverbatim
+ is equivalent to:
+\verbatim
+\skip pattern
+\line pattern\endverbatim
+
+ See section \ref cmddontinclude "\\dontinclude" for an example.
+
+<hr>
+\section cmdsnippet \\snippet <file-name> ( block_id )
+
+ \addindex \\snippet
+ Where the \ref cmdinclude "\\include" command can be used to include
+ a complete file as source code, this command can be used to quote only
+ a fragment of a source file.
+
+ For example, the putting the following command in the documentation,
+ references a snippet in file \c example.cpp residing in a subdirectory
+ which should be pointed to by \ref cfg_example_path "EXAMPLE_PATH".
+
+\verbatim
+ \snippet snippets/example.cpp Adding a resource
+\endverbatim
+
+ The text following the file name is the unique identifier for the snippet.
+ This is used to delimit the quoted code in the relevant snippet file as
+ shown in the following example that corresponds to the above \c \\snippet
+ command:
+
+\code
+ QImage image(64, 64, QImage::Format_RGB32);
+ image.fill(qRgb(255, 160, 128));
+
+//! [Adding a resource]
+ document->addResource(QTextDocument::ImageResource,
+ QUrl("mydata://image.png"), QVariant(image));
+//! [Adding a resource]
+ ...
+\endcode
+
+ Note that the lines containing the block markers will not be included,
+ so the output will be:
+
+\code
+ document->addResource(QTextDocument::ImageResource,
+ QUrl("mydata://image.png"), QVariant(image));
+\endcode
+
+ Note also that the [block_id] markers should appear exactly twice in the
+ source file.
+
+ see section \ref cmddontinclude "\\dontinclude" for an alternative way
+ to include fragments of a source file that does not require markers.
+
+<hr>
+\section cmduntil \\until ( pattern )
+
+ \addindex \\until
+ This command writes all lines of the example that was last
+ included using \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude" to the output, until it finds
+ a line containing the specified pattern. The line containing the pattern
+ will be written as well.
+
+ The internal pointer that is used to keep track of the current line in
+ the example, is set to the start of the line following last written
+ line (or to the end of the example if the pattern could not be found).
+
+ See section \ref cmddontinclude "\\dontinclude" for an example.
+
+<hr>
+\section cmdverbinclude \\verbinclude <file-name>
+
+ \addindex \\verbinclude
+ This command includes the file \<file-name\> verbatim in the documentation.
+ The command is equivalent to pasting the file in the documentation and
+ placing \ref cmdverbatim "\\verbatim" and \ref cmdendverbatim "\\endverbatim"
+ commands around it.
+
+ Files or directories that doxygen should look for can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH" tag of doxygen's configuration file.
+
+<hr>
+\section cmdhtmlinclude \\htmlinclude <file-name>
+
+ \addindex \\htmlinclude
+ This command includes the file \<file-name\> as is in the HTML documentation.
+ The command is equivalent to pasting the file in the documentation and
+ placing \ref cmdhtmlonly "\\htmlonly" and \ref cmdendhtmlonly "\\endhtmlonly"
+ commands around it.
+
+ Files or directories that doxygen should look for can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH" tag of doxygen's configuration file.
+
+<hr>
+
+\section cmdlatexinclude \\latexinclude <file-name>
+
+ \addindex \\latexinclude
+ This command includes the file \<file-name\> as is in the \LaTeX documentation.
+ The command is equivalent to pasting the file in the documentation and
+ placing \ref cmdlatexonly "\\latexonly" and \ref cmdendlatexonly "\\endlatexonly"
+ commands around it.
+
+ Files or directories that doxygen should look for can be specified using the
+ \ref cfg_example_path "EXAMPLE_PATH" tag of doxygen's configuration file.
+
+<hr>
+
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Commands for visual enhancements
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center>\endhtmlonly
+
+\section cmda \\a <word>
+
+ \addindex \\a
+ Displays the argument \<word\> in italics.
+ Use this command to emphasize words.
+ Use this command to refer to member arguments in the running text.
+
+ \par Example:
+ \verbatim
+ ... the \a x and \a y coordinates are used to ...
+ \endverbatim
+ This will result in the following text:<br><br>
+ ... the \a x and \a y coordinates are used to ...
+
+ Equivalent to \ref cmde "\\e" and \ref cmdem "\\em".
+ To emphasize multiple words use \<em\>multiple words\</em\>.
+
+<hr>
+\section cmdarg \\arg { item-description }
+
+ \addindex \\arg
+ This command has one argument that continues until the first
+ blank line or until another \c \\arg is encountered.
+ The command can be used to generate a simple, not nested list of
+ arguments.
+ Each argument should start with a \c \\arg command.
+
+ \par Example:
+ Typing:
+ \verbatim
+ \arg \c AlignLeft left alignment.
+ \arg \c AlignCenter center alignment.
+ \arg \c AlignRight right alignment
+
+ No other types of alignment are supported.
+ \endverbatim
+ will result in the following text:<br><br>
+ <ul>
+ <li> \c AlignLeft left alignment.
+ <li> \c AlignCenter center alignment.
+ <li> \c AlignRight right alignment
+ </ul><br>
+ No other types of alignment are supported.
+
+ \par Note:
+ For nested lists, HTML commands should be used.
+
+ Equivalent to \ref cmdli "\\li"
+
+
+<hr>
+\section cmdb \\b <word>
+
+ \addindex \\b
+ Displays the argument \<word\> using a bold font.
+ Equivalent to \<b\>word\</b\>.
+ To put multiple words in bold use \<b\>multiple words\</b\>.
+
+<hr>
+\section cmdc \\c <word>
+
+ \addindex \\c
+ Displays the argument \<word\> using a typewriter font.
+ Use this to refer to a word of code.
+ Equivalent to \<tt\>word\</tt\>.
+
+ \par Example:
+ Typing:
+ \verbatim
+ ... This function returns \c void and not \c int ...
+ \endverbatim
+ will result in the following text:<br><br>
+ ... This function returns \c void and not \c int ...
+
+ Equivalent to \ref cmdp "\\p"
+ To have multiple words in typewriter font use \<tt\>multiple words\</tt\>.
+
+<hr>
+\section cmdcode \\code [ '{'<word>'}']
+
+ \addindex \\code
+ Starts a block of code. A code block is treated differently
+ from ordinary text. It is interpreted as source code. The names of
+ classes and members and other documented entities are automatically
+ replaced by links to the documentation.
+
+ By default the language that is assumed for syntax highlighting is based
+ on the location where the \c \\code block was found. If this part of
+ a Python file for instance, the syntax highlight will be done according
+ to the Python syntax.
+
+ If it unclear from the context which language is meant (for instance the
+ comment is in a <code>.txt</code> or <code>.markdown</code> file) then you can also explicitly
+ indicate the language, by putting the file extension typically
+ that doxygen associated with the language in curly brackets after the
+ code block. Here is an example:
+
+\verbatim
+ \code{.py}
+ class Python:
+ pass
+ \endcode
+
+ \code{.cpp}
+ class Cpp {};
+ \endcode
+\endverbatim
+
+ If the contents of the code block are in a language that doxygen cannot parse, doxygen
+ will just show the output as-is. You can make this explicit using .unparsed, or by
+ giving some other extension that doxygen doesn't support, e.g.
+
+\verbatim
+ \code{.unparsed}
+ Show this as-is please
+ \endcode
+
+ \code{.sh}
+ echo "This is a shell script"
+ \endcode
+\endverbatim
+
+ \sa section \ref cmdendcode "\\endcode" and section \ref cmdverbatim "\\verbatim".
+
+<hr>
+\section cmdcopydoc \\copydoc <link-object>
+
+ \addindex \\copydoc
+ Copies a documentation block from the object specified by \<link-object\>
+ and pastes it at the location of the command. This command can be useful
+ to avoid cases where a documentation block would otherwise have to be
+ duplicated or it can be used to extend the documentation of an inherited
+ member.
+
+ The link object can point to a member (of a class, file or group),
+ a class, a namespace, a group, a page, or a file (checked in that order).
+ Note that if the object pointed to is a member (function, variable,
+ typedef, etc), the compound (class, file, or group) containing it
+ should also be documented for the copying to work.
+
+ To copy the documentation for a member of a
+ class one can, for instance, put the following in the documentation:
+
+\verbatim
+ /*! @copydoc MyClass::myfunction()
+ * More documentation.
+ */
+\endverbatim
+
+ if the member is overloaded, you should specify the argument types
+ explicitly (without spaces!), like in the following:
+
+\verbatim
+ //! @copydoc MyClass::myfunction(type1,type2)
+\endverbatim
+
+ Qualified names are only needed if the context in which the documentation
+ block is found requires them.
+
+ The \c \\copydoc command can be used recursively, but cycles in the \c \\copydoc
+ relation will be broken and flagged as an error.
+
+ Note that <code>\\copydoc foo()</code> is roughly equivalent to doing:
+\verbatim
+ \brief \copybrief foo()
+ \details \copydetails foo()
+\endverbatim
+ See \ref cmdcopybrief "\\copybrief" and
+ \ref cmdcopydetails "\\copydetails" for copying only the brief or
+ detailed part of the comment block.
+
+<hr>
+\section cmdcopybrief \\copybrief <link-object>
+
+ \addindex \\copybrief
+Works in a similar way as \ref cmdcopydoc "\\copydoc" but will
+only copy the brief description, not the detailed documentation.
+
+<hr>
+\section cmdcopydetails \\copydetails <link-object>
+
+ \addindex \\copydetails
+Works in a similar way as \ref cmdcopydoc "\\copydoc" but will
+only copy the detailed documentation, not the brief description.
+
+<hr>
+\section cmddocbookonly \\docbookonly
+
+ \addindex \\docbookonly
+ Starts a block of text that will be verbatim included in the
+ generated docbook documentation only. The block ends with a
+ \ref cmdenddocbookonly "\\enddocbookonly" command.
+
+ \sa section \ref cmdmanonly "\\manonly",
+ \ref cmdlatexonly "\\latexonly",
+ \ref cmdrtfonly "\\rtfonly",
+ \ref cmdxmlonly "\\xmlonly", and
+ \ref cmdhtmlonly "\\htmlonly".
+
+<hr>
+\section cmddot \\dot
+
+ \addindex \\dot
+ Starts a text fragment which should contain a valid description of a
+ dot graph. The text fragment ends with \ref cmdenddot "\\enddot".
+ Doxygen will pass the text on to dot and include the resulting
+ image (and image map) into the output.
+ The nodes of a graph can be made clickable by using the URL attribute.
+ By using the command \ref cmdref "\\ref" inside the URL value you can conveniently
+ link to an item inside doxygen. Here is an example:
+\code
+/*! class B */
+class B {};
+
+/*! class C */
+class C {};
+
+/*! \mainpage
+ *
+ * Class relations expressed via an inline dot graph:
+ * \dot
+ * digraph example {
+ * node [shape=record, fontname=Helvetica, fontsize=10];
+ * b [ label="class B" URL="\ref B"];
+ * c [ label="class C" URL="\ref C"];
+ * b -> c [ arrowhead="open", style="dashed" ];
+ * }
+ * \enddot
+ * Note that the classes in the above graph are clickable
+ * (in the HTML output).
+ */
+\endcode
+
+<hr>
+\section cmdmsc \\msc
+
+ \addindex \\msc
+ Starts a text fragment which should contain a valid description of a
+ message sequence chart. See http://www.mcternan.me.uk/mscgen/ for examples.
+ The text fragment ends with \ref cmdendmsc "\\endmsc".
+ \note The text fragment should only include the part of the message
+ sequence chart that is
+ within the <code>msc {...}</code> block.
+ \note You need to install the <code>mscgen</code> tool, if you want to use this
+ command.
+
+Here is an example of the use of the \c \\msc command.
+\code
+/** Sender class. Can be used to send a command to the server.
+ * The receiver will acknowledge the command by calling Ack().
+ * \msc
+ * Sender,Receiver;
+ * Sender->Receiver [label="Command()", URL="\ref Receiver::Command()"];
+ * Sender<-Receiver [label="Ack()", URL="\ref Ack()", ID="1"];
+ * \endmsc
+ */
+class Sender
+{
+ public:
+ /** Acknowledgment from server */
+ void Ack(bool ok);
+};
+
+/** Receiver class. Can be used to receive and execute commands.
+ * After execution of a command, the receiver will send an acknowledgment
+ * \msc
+ * Receiver,Sender;
+ * Receiver<-Sender [label="Command()", URL="\ref Command()"];
+ * Receiver->Sender [label="Ack()", URL="\ref Sender::Ack()", ID="1"];
+ * \endmsc
+ */
+class Receiver
+{
+ public:
+ /** Executable a command on the server */
+ void Command(int commandId);
+};
+
+\endcode
+
+ \sa section \ref cmdmscfile "\\mscfile".
+
+<hr>
+\section cmdstartuml \\startuml
+
+ \addindex \\startuml
+ Starts a text fragment which should contain a valid description of a
+ PlantUML diagram. See http://plantuml.sourceforge.net/ for examples.
+ The text fragment ends with \ref cmdenduml "\\enduml".
+ \note You need to install Java and the PlantUML's jar file,
+ if you want to use this command. The location of the jar file should be specified
+ using \ref cfg_plantuml_jar_path "PLANTUML_JAR_PATH".
+
+Here is an example of the use of the \c \\startuml command.
+\code
+/** Sender class. Can be used to send a command to the server.
+ * The receiver will acknowledge the command by calling Ack().
+ * \startuml
+ * Sender->Receiver : Command()
+ * Sender<--Receiver : Ack()
+ * \enduml
+ */
+class Sender
+{
+ public:
+ /** Acknowledgment from server */
+ void Ack(bool ok);
+};
+
+/** Receiver class. Can be used to receive and execute commands.
+ * After execution of a command, the receiver will send an acknowledgment
+ * \startuml
+ * Receiver<-Sender : Command()
+ * Receiver-->Sender : Ack()
+ * \enduml
+ */
+class Receiver
+{
+ public:
+ /** Executable a command on the server */
+ void Command(int commandId);
+};
+\endcode
+
+\note For compatibility with running PlantUML as a preprocessing step before
+running doxygen, you can also add the name of the image file after \c \\startuml
+and inside curly brackets, i.e.
+\verbatim
+ at startuml{myimage.png}
+Alice -> Bob : Hello
+ at enduml
+\endverbatim
+When the name of the image is specified, doxygen will generate an image with that name.
+Without the name doxygen will choose a name automatically.
+
+<hr>
+\section cmddotfile \\dotfile <file> ["caption"]
+
+ \addindex \\dotfile
+ Inserts an image generated by dot from \<file\> into the documentation.
+
+ The first argument specifies the file name of the image.
+ doxygen will look for files in the paths (or files) that you specified
+ after the \ref cfg_dotfile_dirs "DOTFILE_DIRS" tag.
+ If the dot file is found it will be used as an input file to the dot tool.
+ The resulting image will be put into the correct output directory.
+ If the dot file name contains spaces you'll have to put quotes ("...") around it.
+
+ The second argument is optional and can be used to specify the caption
+ that is displayed below the image. This argument has to be specified
+ between quotes even if it does not contain any spaces. The quotes are
+ stripped before the caption is displayed.
+
+<hr>
+\section cmdmscfile \\mscfile <file> ["caption"]
+
+ \addindex \\mscfile
+ Inserts an image generated by mscgen from \<file\> into the documentation.
+ See http://www.mcternan.me.uk/mscgen/ for examples.
+
+ The first argument specifies the file name of the image.
+ doxygen will look for files in the paths (or files) that you specified
+ after the \ref cfg_mscfile_dirs "MSCFILE_DIRS" tag.
+ If the msc file is found it will be used as an input file to the mscgen tool.
+ The resulting image will be put into the correct output directory.
+ If the msc file name contains spaces you'll have to put quotes ("...") around it.
+
+ The second argument is optional and can be used to specify the caption
+ that is displayed below the image. This argument has to be specified
+ between quotes even if it does not contain any spaces. The quotes are
+ stripped before the caption is displayed.
+
+ \sa section \ref cmdmsc "\\msc".
+
+<hr>
+\section cmddiafile \\diafile <file> ["caption"]
+
+ \addindex \\diafile
+ Inserts an image made in dia from \<file\> into the documentation.
+
+ The first argument specifies the file name of the image.
+ doxygen will look for files in the paths (or files) that you specified
+ after the \ref cfg_diafile_dirs "DIAFILE_DIRS" tag.
+ If the dia file is found it will be used as an input file dia.
+ The resulting image will be put into the correct output directory.
+ If the dia file name contains spaces you'll have to put quotes ("...") around it.
+
+ The second argument is optional and can be used to specify the caption
+ that is displayed below the image. This argument has to be specified
+ between quotes even if it does not contain any spaces. The quotes are
+ stripped before the caption is displayed.
+
+<hr>
+\section cmde \\e <word>
+
+ \addindex \\e
+ Displays the argument \<word\> in italics.
+ Use this command to emphasize words.
+
+ \par Example:
+ Typing:
+ \verbatim
+ ... this is a \e really good example ...
+ \endverbatim
+ will result in the following text:<br><br>
+ ... this is a \e really good example ...
+
+ Equivalent to \ref cmda "\\a" and \ref cmdem "\\em".
+ To emphasize multiple words use \<em\>multiple words\</em\>.
+
+<hr>
+\section cmdem \\em <word>
+
+ \addindex \\em
+ Displays the argument \<word\> in italics.
+ Use this command to emphasize words.
+
+ \par Example:
+ Typing:
+ \verbatim
+ ... this is a \em really good example ...
+ \endverbatim
+ will result in the following text:<br><br>
+ ... this is a \em really good example ...
+
+ Equivalent to \ref cmda "\\a" and \ref cmde "\\e".
+ To emphasize multiple words use \<em\>multiple words\</em\>.
+
+<hr>
+\section cmdendcode \\endcode
+
+ \addindex \\endcode
+ Ends a block of code.
+ \sa section \ref cmdcode "\\code"
+
+<hr>
+\section cmdenddocbookonly \\enddocbookonly
+
+ \addindex \\enddocbookonly
+ Ends a block of text that was started with a \ref cmddocbookonly "\\docbookonly" command.
+
+ \sa section \ref cmddocbookonly "\\docbookonly".
+
+<hr>
+\section cmdenddot \\enddot
+
+ \addindex \\enddot
+ Ends a block that was started with \ref cmddot "\\dot".
+
+<hr>
+\section cmdendmsc \\endmsc
+
+ \addindex \\endmsc
+ Ends a block that was started with \ref cmdmsc "\\msc".
+
+<hr>
+\section cmdenduml \\enduml
+
+ \addindex \\enduml
+ Ends a block that was started with \ref cmdstartuml "\\startuml".
+
+<hr>
+\section cmdendhtmlonly \\endhtmlonly
+
+ \addindex \\endhtmlonly
+ Ends a block of text that was started with a \ref cmdhtmlonly "\\htmlonly" command.
+
+ \sa section \ref cmdhtmlonly "\\htmlonly".
+
+<hr>
+\section cmdendlatexonly \\endlatexonly
+
+ \addindex \\endlatexonly
+ Ends a block of text that was started with a \ref cmdlatexonly "\\latexonly" command.
+
+ \sa section \ref cmdlatexonly "\\latexonly".
+
+<hr>
+\section cmdendmanonly \\endmanonly
+
+ \addindex \\endmanonly
+ Ends a block of text that was started with a \ref cmdmanonly "\\manonly" command.
+
+ \sa section \ref cmdmanonly "\\manonly".
+
+<hr>
+\section cmdendrtfonly \\endrtfonly
+
+ \addindex \\endrtfonly
+ Ends a block of text that was started with a \ref cmdrtfonly "\\rtfonly" command.
+
+ \sa section \ref cmdrtfonly "\\rtfonly".
+
+
+<hr>
+\section cmdendverbatim \\endverbatim
+
+ \addindex \\endverbatim
+ Ends a block of text that was started with a \ref cmdverbatim "\\verbatim" command.
+
+ \sa section \ref cmdverbatim "\\verbatim".
+
+<hr>
+\section cmdendxmlonly \\endxmlonly
+
+ \addindex \\endxmlonly
+ Ends a block of text that was started with a \ref cmdxmlonly "\\xmlonly" command.
+
+ \sa section \ref cmdxmlonly "\\xmlonly".
+
+<hr>
+\section cmdfdollar \\f$
+
+ \addindex \\f\$
+
+ Marks the start and end of an in-text formula.
+ \sa section \ref formulas "formulas" for an example.
+
+<hr>
+\section cmdfbropen \\f[
+
+ \addindex \\f[
+
+ Marks the start of a long formula that is displayed
+ centered on a separate line.
+ \sa section \ref cmdfbrclose "\\f]" and section \ref formulas "formulas".
+
+<hr>
+\section cmdfbrclose \\f]
+
+ \addindex \\f]
+
+ Marks the end of a long formula that is displayed
+ centered on a separate line.
+ \sa section \ref cmdfbropen "\\f[" and section \ref formulas "formulas".
+
+<hr>
+\section cmdfcurlyopen \\f{environment}{
+
+ \addindex \\f{
+
+ Marks the start of a formula that is in a specific environment.
+ \note The second \c { is optional and is only to help editors (such as \c Vim) to
+ do proper syntax highlighting by making the number of opening and closing braces
+ the same.
+ \sa section \ref cmdfcurlyclose "\\f}" and section \ref formulas "formulas".
+
+<hr>
+\section cmdfcurlyclose \\f}
+
+ \addindex \\f}
+
+ Marks the end of a formula that is in a specific environment.
+ \sa section \ref cmdfcurlyopen "\\f{" and section \ref formulas "formulas".
+
+<hr>
+\section cmdhtmlonly \\htmlonly ["[block]"]
+
+ \addindex \\htmlonly
+ Starts a block of text that will be verbatim included in the
+ generated HTML documentation only. The block ends with a
+ \ref cmdendhtmlonly "\\endhtmlonly" command.
+
+ This command can be used to include HTML code that is too complex
+ for doxygen (i.e. applets, java-scripts, and HTML tags that
+ require specific attributes).
+
+ Normally the contents between \ref cmdhtmlonly "\\htmlonly" and
+ \ref cmdendhtmlonly "\\endhtmlonly" is inserted as-is. When you
+ want to insert a HTML fragment that has block scope like a table or list
+ which should appear outside \<p\>..\</p\>, this can lead to invalid HTML.
+ You can use \\htmlonly[block] to make doxygen
+ end the current paragraph and restart it after \\endhtmlonly.
+
+ \note environment variables (like \$(HOME) ) are resolved inside a
+ HTML-only block.
+
+ \sa section \ref cmdmanonly "\\manonly",
+ \ref cmdlatexonly "\\latexonly",
+ \ref cmdrtfonly "\\rtfonly",
+ \ref cmdxmlonly "\\xmlonly", and
+ \ref cmddocbookonly "\\docbookonly".
+
+<hr>
+\section cmdimage \\image <format> <file> ["caption"] [<sizeindication>=<size>]
+
+ \addindex \\image
+ Inserts an image into the documentation. This command is format
+ specific, so if you want to insert an image for more than one
+ format you'll have to repeat this command for each format.
+
+ The first argument specifies the output format. Currently, the
+ following values are supported: \c html, \c latex and \c rtf.
+
+ The second argument specifies the file name of the image.
+ doxygen will look for files in the paths (or files) that you specified
+ after the \ref cfg_image_path "IMAGE_PATH" tag.
+ If the image is found it will be copied to the correct output directory.
+ If the image name contains spaces you'll have to put quotes ("...") around it.
+ You can also specify an absolute URL instead of a file name, but then
+ doxygen does not copy the image nor check its existence.
+
+ The third argument is optional and can be used to specify the caption
+ that is displayed below the image. This argument has to be specified
+ on a single line and between quotes even if it does not contain any
+ spaces. The quotes are stripped before the caption is displayed.
+
+ The fourth argument is also optional and can be used to specify the
+ width or height of the image. This is only useful
+ for \LaTeX output
+ (i.e. format=<code>latex</code>). The \c sizeindication can be
+ either \c width or \c height. The size should be a valid
+ size specifier in \LaTeX (for example <code>10cm</code> or
+ <code>6in</code> or a symbolic width like <code>\\textwidth</code>).
+
+ Here is example of a comment block:
+
+\verbatim
+ /*! Here is a snapshot of my new application:
+ * \image html application.jpg
+ * \image latex application.eps "My application" width=10cm
+ */
+\endverbatim
+
+ And this is an example of how the relevant part of the configuration file
+ may look:
+
+\verbatim
+ IMAGE_PATH = my_image_dir
+\endverbatim
+
+ \warning The image format for HTML is limited to what your
+ browser supports. For \LaTeX, the image format
+ must be Encapsulated PostScript (eps).
+ <br><br>
+ Doxygen does not check if the image is in the correct format.
+ So \e you have to make sure this is the case!
+
+<hr>
+\section cmdlatexonly \\latexonly
+
+ \addindex \\latexonly
+ Starts a block of text that will be verbatim included in the
+ generated \LaTeX documentation only. The block ends with a
+ \ref cmdendlatexonly "\\endlatexonly" command.
+
+ This command can be used to include \LaTeX code that is too
+ complex for doxygen (i.e. images, formulas, special characters). You can
+ use the \ref cmdhtmlonly "\\htmlonly" and \ref cmdendhtmlonly "\\endhtmlonly"
+ pair to provide a proper HTML alternative.
+
+ \b Note:
+ environment variables (like \$(HOME) ) are resolved inside a
+ \LaTeX-only block.
+
+ \sa sections \ref cmdrtfonly "\\rtfonly",
+ \ref cmdxmlonly "\\xmlonly",
+ \ref cmdmanonly "\\manonly",
+ \ref cmdhtmlonly "\\htmlonly", and
+ \ref cmdhtmlonly "\\docbookonly".
+
+<hr>
+\section cmdmanonly \\manonly
+
+ \addindex \\manonly
+ Starts a block of text that will be verbatim included in the
+ generated MAN documentation only. The block ends with a
+ \ref cmdendmanonly "\\endmanonly" command.
+
+ This command can be used to include groff code directly into
+ MAN pages. You can use the \ref cmdhtmlonly "\\htmlonly" and
+ \ref cmdendhtmlonly "\\endhtmlonly" and
+ \ref cmdlatexonly "\\latexonly" and
+ \ref cmdendlatexonly "\\endlatexonly" pairs to provide proper
+ HTML and \LaTeX alternatives.
+
+ \sa sections \ref cmdhtmlonly "\\htmlonly",
+ \ref cmdxmlonly "\\xmlonly",
+ \ref cmdrtfonly "\\rtfonly",
+ \ref cmdlatexonly "\\latexonly", and
+ \ref cmddocbookonly "\\docbookonly".
+
+<hr>
+\section cmdli \\li { item-description }
+
+ \addindex \\li
+ This command has one argument that continues until the first
+ blank line or until another \c \\li is encountered.
+ The command can be used to generate a simple, not nested list of
+ arguments.
+ Each argument should start with a \c \\li command.
+
+ \par Example:
+ Typing:
+ \verbatim
+ \li \c AlignLeft left alignment.
+ \li \c AlignCenter center alignment.
+ \li \c AlignRight right alignment
+
+ No other types of alignment are supported.
+ \endverbatim
+ will result in the following text:<br><br>
+ <ul>
+ <li> \c AlignLeft left alignment.
+ <li> \c AlignCenter center alignment.
+ <li> \c AlignRight right alignment
+ </ul><br>
+ No other types of alignment are supported.
+
+ \par Note:
+ For nested lists, HTML commands should be used.
+
+ Equivalent to \ref cmdarg "\\arg"
+
+<hr>
+\section cmdn \\n
+
+ \addindex \\n
+ Forces a new line. Equivalent to \<br\> and inspired by
+ the \c printf function.
+
+<hr>
+\section cmdp \\p <word>
+
+ \addindex \\p
+ Displays the parameter \<word\> using a typewriter font.
+ You can use this command to refer to member function parameters in
+ the running text.
+
+ \par Example:
+ \verbatim
+ ... the \p x and \p y coordinates are used to ...
+ \endverbatim
+ This will result in the following text:<br><br>
+ ... the \p x and \p y coordinates are used to ...
+
+ Equivalent to \ref cmdc "\\c"
+ To have multiple words in typewriter font use \<tt\>multiple words\</tt\>.
+
+<hr>
+\section cmdrtfonly \\rtfonly
+
+ \addindex \\rtfonly
+ Starts a block of text that will be verbatim included in the
+ generated RTF documentation only. The block ends with a
+ \ref cmdendrtfonly "\\endrtfonly" command.
+
+ This command can be used to include RTF code that is too complex
+ for doxygen.
+
+ \b Note:
+ environment variables (like \$(HOME) ) are resolved inside a
+ RTF-only block.
+
+ \sa sections \ref cmdmanonly "\\manonly",
+ \ref cmdxmlonly "\\xmlonly",
+ \ref cmdlatexonly "\\latexonly",
+ \ref cmdhtmlonly "\\htmlonly", and
+ \ref cmddocbookonly "\\docbookonly".
+
+<hr>
+\section cmdverbatim \\verbatim
+
+ \addindex \\verbatim
+ Starts a block of text that will be verbatim included in
+ the documentation. The block should end with a
+ \ref cmdendverbatim "\\endverbatim" command.
+ All commands are disabled in a verbatim block.
+
+ \warning Make sure you include a \ref cmdendverbatim "\\endverbatim" command for each
+ \c \\verbatim command or the parser will get confused!
+
+ \sa sections \ref cmdcode "\\code",
+ \ref cmdendverbatim "\\endverbatim", and
+ \ref cmdverbinclude "\\verbinclude".
+
+<hr>
+\section cmdxmlonly \\xmlonly
+
+ \addindex \\xmlonly
+ Starts a block of text that will be verbatim included in the
+ generated XML output only. The block ends with a
+ \ref cmdendxmlonly "\\endxmlonly" command.
+
+ This command can be used to include custom XML tags.
+
+ \sa sections \ref cmdmanonly "\\manonly",
+ \ref cmdrtfonly "\\rtfonly",
+ \ref cmdlatexonly "\\latexonly",
+ \ref cmdhtmlonly "\\htmlonly", and
+ \ref cmddocbookonly "\\docbookonly".
+
+<hr>
+\section cmdbackslash \\\\
+
+ \addindex \\\\
+ This command writes a backslash character (\c \\) to the
+ output. The backslash has to be escaped in some
+ cases because doxygen uses it to detect commands.
+
+<hr>
+\section cmdat \\\@
+
+ \addindex \\\@
+ This command writes an at-sign (\c \@) to the output.
+ The at-sign has to be escaped in some cases
+ because doxygen uses it to detect JavaDoc commands.
+
+<hr>
+\section cmdtilde \\~[LanguageId]
+ \addindex \\~
+ This command enables/disables a language specific filter. This can be
+ used to put documentation for different language into one comment block
+ and use the \ref cfg_output_language "OUTPUT_LANGUAGE" tag to filter out only a specific language.
+ Use \c \\~language_id to enable output for a specific language only and
+ \c \\~ to enable output for all languages (this is also the default mode).
+
+ Example:
+\verbatim
+/*! \~english This is English \~dutch Dit is Nederlands \~german Dies ist
+ Deutsch. \~ output for all languages.
+ */
+\endverbatim
+
+
+<hr>
+\section cmdamp \\\&
+
+ \addindex \\\&
+ This command writes the \c \& character to the output.
+ This character has to be escaped because it has a special meaning in HTML.
+
+<hr>
+\section cmddollar \\\$
+
+ \addindex \\\$
+ This command writes the \c \$ character to the output.
+ This character has to be escaped in some cases, because it is used to expand
+ environment variables.
+
+<hr>
+\section cmdhash \\\#
+
+ \addindex \\\#
+ This command writes the \c \# character to the output. This
+ character has to be escaped in some cases, because it is used to refer
+ to documented entities.
+
+<hr>
+\section cmdlt \\\<
+
+ \addindex \\\<
+ This command writes the \c \< character to the output.
+ This character has to be escaped because it has a special meaning in HTML.
+
+<hr>
+\section cmdgt \\\>
+
+ \addindex \\\>
+ This command writes the \c \> character to the output. This
+ character has to be escaped because it has a special meaning in HTML.
+
+<hr>
+\section cmdperc \\\%
+
+ \addindex \\\%
+ This command writes the \c \% character to the output. This
+ character has to be escaped in some cases, because it is used to
+ prevent auto-linking to word that is also a documented class or struct.
+
+<hr>
+\section cmdquot \\"
+
+ \addindex \\\"
+ This command writes the \c \" character to the output. This
+ character has to be escaped in some cases, because it is used in pairs
+ to indicate an unformatted text fragment.
+
+<hr>
+\section cmdchardot \\.
+
+ \addindex \\\.
+ This command writes a dot (`.`) to the output. This can be useful to
+ prevent ending a brief description when JAVADOC_AUTOBRIEF is enabled
+ or to prevent starting a numbered list when the dot follows a number at
+ the start of a line.
+
+<hr>
+\section cmddcolon \\::
+
+ \addindex \\::
+ This command writes a double colon (\c \::) to the output. This
+ character sequence has to be escaped in some cases, because it is used
+ to reference to documented entities.
+
+<hr>
+\section cmdpipe \\|
+
+ \addindex \\|
+ This command writes a pipe symbol (\|) to the output. This
+ character has to be escaped in some cases, because it is used
+ for Markdown tables.
+
+<hr>
+\section cmdndash \\--
+
+ \addindex \\\--
+ This command writes two dashes (\--) to the output. This allows
+ writing two consecutive dashes to the output instead of one n-dash character (--).
+
+<hr>
+\section cmdmdash \\---
+
+ \addindex \\\---
+ This command writes three dashes (\---) to the output. This allows
+ writing three consecutuve dashes to the output instead of one m-dash character (---).
+
+<hr>
+\htmlonly <center> \endhtmlonly
+<h2>
+\htmlonly --- \endhtmlonly
+Commands included for Qt compatibility
+\htmlonly --- \endhtmlonly
+</h2>
+\htmlonly </center>\endhtmlonly
+
+The following commands are supported to remain compatible to the Qt class
+browser generator. Do \e not use these commands in your own documentation.
+<ul>
+<li>\\annotatedclasslist
+<li>\\classhierarchy
+<li>\\define
+<li>\\functionindex
+<li>\\header
+<li>\\headerfilelist
+<li>\\inherit
+<li>\\l
+<li>\\postheader
+</ul>
+<hr>
+
+
+\htmlonly
+Go to the <a href="htmlcmds.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/config.doc b/doc/config.doc
new file mode 100644
index 0000000..cef270d
--- /dev/null
+++ b/doc/config.doc
@@ -0,0 +1,3859 @@
+/* WARNING: This file is generated!
+ * Do not edit this file, but edit config.xml instead and run
+ * python configgen.py -doc config.xml to regenerate this file!
+ */
+/*
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page config Configuration
+
+\tableofcontents
+\section config_format Format
+
+A configuration file is a free-form ASCII text file with a structure
+that is similar to that of a \c Makefile, with the default name \c Doxyfile. It is
+parsed by \c doxygen. The file may contain tabs and newlines for
+formatting purposes. The statements in the file are case-sensitive.
+Comments may be placed anywhere within the file (except within quotes).
+Comments beginning with two hash characters (\c \#\#) are kept when updating
+the configuration file and are placed in front of the TAG are in front of.
+Comments beginning with two hash characters (\c \#\#) at the end of the
+configuration file are also kept and placed at the end of the file.
+Comments begin with the hash character (\c \#) and ends at the end of the line.
+
+The file essentially consists of a list of assignment statements.
+Each statement consists of a \c TAG_NAME written in capitals,
+followed by the equal sign (<code>=</code>) and one or more values. If the same tag
+is assigned more than once, the last assignment overwrites any earlier
+assignment. For tags that take a list as their argument,
+the <code>+=</code> operator can be used instead of <code>=</code> to append
+new values to the list. Values are sequences of non-blanks. If the value should
+contain one or more blanks it must be surrounded by quotes (<code>"..."</code>).
+Multiple lines can be concatenated by inserting a backslash (\c \\)
+as the last character of a line. Environment variables can be expanded
+using the pattern <code>\$(ENV_VARIABLE_NAME)</code>.
+
+You can also include part of a configuration file from another configuration
+file using a <code>\@INCLUDE</code> tag as follows:
+\verbatim
+ at INCLUDE = config_file_name
+\endverbatim
+The include file is searched in the current working directory. You can
+also specify a list of directories that should be searched before looking
+in the current working directory. Do this by putting a <code>\@INCLUDE_PATH</code> tag
+with these paths before the <code>\@INCLUDE</code> tag, e.g.:
+\verbatim
+ at INCLUDE_PATH = my_config_dir
+\endverbatim
+
+The configuration options can be divided into several categories.
+Below is an alphabetical index of the tags that are recognized
+followed by the descriptions of the tags grouped by category.
+\secreflist
+\refitem cfg_abbreviate_brief ABBREVIATE_BRIEF
+\refitem cfg_aliases ALIASES
+\refitem cfg_allexternals ALLEXTERNALS
+\refitem cfg_allow_unicode_names ALLOW_UNICODE_NAMES
+\refitem cfg_alphabetical_index ALPHABETICAL_INDEX
+\refitem cfg_always_detailed_sec ALWAYS_DETAILED_SEC
+\refitem cfg_autolink_support AUTOLINK_SUPPORT
+\refitem cfg_binary_toc BINARY_TOC
+\refitem cfg_brief_member_desc BRIEF_MEMBER_DESC
+\refitem cfg_builtin_stl_support BUILTIN_STL_SUPPORT
+\refitem cfg_caller_graph CALLER_GRAPH
+\refitem cfg_call_graph CALL_GRAPH
+\refitem cfg_case_sense_names CASE_SENSE_NAMES
+\refitem cfg_chm_file CHM_FILE
+\refitem cfg_chm_index_encoding CHM_INDEX_ENCODING
+\refitem cfg_cite_bib_files CITE_BIB_FILES
+\refitem cfg_clang_assisted_parsing CLANG_ASSISTED_PARSING
+\refitem cfg_clang_options CLANG_OPTIONS
+\refitem cfg_class_diagrams CLASS_DIAGRAMS
+\refitem cfg_class_graph CLASS_GRAPH
+\refitem cfg_collaboration_graph COLLABORATION_GRAPH
+\refitem cfg_cols_in_alpha_index COLS_IN_ALPHA_INDEX
+\refitem cfg_compact_latex COMPACT_LATEX
+\refitem cfg_compact_rtf COMPACT_RTF
+\refitem cfg_cpp_cli_support CPP_CLI_SUPPORT
+\refitem cfg_create_subdirs CREATE_SUBDIRS
+\refitem cfg_diafile_dirs DIAFILE_DIRS
+\refitem cfg_dia_path DIA_PATH
+\refitem cfg_directory_graph DIRECTORY_GRAPH
+\refitem cfg_disable_index DISABLE_INDEX
+\refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC
+\refitem cfg_docbook_output DOCBOOK_OUTPUT
+\refitem cfg_docbook_programlisting DOCBOOK_PROGRAMLISTING
+\refitem cfg_docset_bundle_id DOCSET_BUNDLE_ID
+\refitem cfg_docset_feedname DOCSET_FEEDNAME
+\refitem cfg_docset_publisher_id DOCSET_PUBLISHER_ID
+\refitem cfg_docset_publisher_name DOCSET_PUBLISHER_NAME
+\refitem cfg_dotfile_dirs DOTFILE_DIRS
+\refitem cfg_dot_cleanup DOT_CLEANUP
+\refitem cfg_dot_fontname DOT_FONTNAME
+\refitem cfg_dot_fontpath DOT_FONTPATH
+\refitem cfg_dot_fontsize DOT_FONTSIZE
+\refitem cfg_dot_graph_max_nodes DOT_GRAPH_MAX_NODES
+\refitem cfg_dot_image_format DOT_IMAGE_FORMAT
+\refitem cfg_dot_multi_targets DOT_MULTI_TARGETS
+\refitem cfg_dot_num_threads DOT_NUM_THREADS
+\refitem cfg_dot_path DOT_PATH
+\refitem cfg_dot_transparent DOT_TRANSPARENT
+\refitem cfg_doxyfile_encoding DOXYFILE_ENCODING
+\refitem cfg_eclipse_doc_id ECLIPSE_DOC_ID
+\refitem cfg_enabled_sections ENABLED_SECTIONS
+\refitem cfg_enable_preprocessing ENABLE_PREPROCESSING
+\refitem cfg_enum_values_per_line ENUM_VALUES_PER_LINE
+\refitem cfg_example_path EXAMPLE_PATH
+\refitem cfg_example_patterns EXAMPLE_PATTERNS
+\refitem cfg_example_recursive EXAMPLE_RECURSIVE
+\refitem cfg_exclude EXCLUDE
+\refitem cfg_exclude_patterns EXCLUDE_PATTERNS
+\refitem cfg_exclude_symbols EXCLUDE_SYMBOLS
+\refitem cfg_exclude_symlinks EXCLUDE_SYMLINKS
+\refitem cfg_expand_as_defined EXPAND_AS_DEFINED
+\refitem cfg_expand_only_predef EXPAND_ONLY_PREDEF
+\refitem cfg_extension_mapping EXTENSION_MAPPING
+\refitem cfg_external_groups EXTERNAL_GROUPS
+\refitem cfg_external_pages EXTERNAL_PAGES
+\refitem cfg_external_search EXTERNAL_SEARCH
+\refitem cfg_external_search_id EXTERNAL_SEARCH_ID
+\refitem cfg_extract_all EXTRACT_ALL
+\refitem cfg_extract_anon_nspaces EXTRACT_ANON_NSPACES
+\refitem cfg_extract_local_classes EXTRACT_LOCAL_CLASSES
+\refitem cfg_extract_local_methods EXTRACT_LOCAL_METHODS
+\refitem cfg_extract_package EXTRACT_PACKAGE
+\refitem cfg_extract_private EXTRACT_PRIVATE
+\refitem cfg_extract_static EXTRACT_STATIC
+\refitem cfg_extra_packages EXTRA_PACKAGES
+\refitem cfg_extra_search_mappings EXTRA_SEARCH_MAPPINGS
+\refitem cfg_ext_links_in_window EXT_LINKS_IN_WINDOW
+\refitem cfg_file_patterns FILE_PATTERNS
+\refitem cfg_file_version_filter FILE_VERSION_FILTER
+\refitem cfg_filter_patterns FILTER_PATTERNS
+\refitem cfg_filter_source_files FILTER_SOURCE_FILES
+\refitem cfg_filter_source_patterns FILTER_SOURCE_PATTERNS
+\refitem cfg_force_local_includes FORCE_LOCAL_INCLUDES
+\refitem cfg_formula_fontsize FORMULA_FONTSIZE
+\refitem cfg_formula_transparent FORMULA_TRANSPARENT
+\refitem cfg_full_path_names FULL_PATH_NAMES
+\refitem cfg_generate_autogen_def GENERATE_AUTOGEN_DEF
+\refitem cfg_generate_buglist GENERATE_BUGLIST
+\refitem cfg_generate_chi GENERATE_CHI
+\refitem cfg_generate_deprecatedlist GENERATE_DEPRECATEDLIST
+\refitem cfg_generate_docbook GENERATE_DOCBOOK
+\refitem cfg_generate_docset GENERATE_DOCSET
+\refitem cfg_generate_eclipsehelp GENERATE_ECLIPSEHELP
+\refitem cfg_generate_html GENERATE_HTML
+\refitem cfg_generate_htmlhelp GENERATE_HTMLHELP
+\refitem cfg_generate_latex GENERATE_LATEX
+\refitem cfg_generate_legend GENERATE_LEGEND
+\refitem cfg_generate_man GENERATE_MAN
+\refitem cfg_generate_perlmod GENERATE_PERLMOD
+\refitem cfg_generate_qhp GENERATE_QHP
+\refitem cfg_generate_rtf GENERATE_RTF
+\refitem cfg_generate_tagfile GENERATE_TAGFILE
+\refitem cfg_generate_testlist GENERATE_TESTLIST
+\refitem cfg_generate_todolist GENERATE_TODOLIST
+\refitem cfg_generate_treeview GENERATE_TREEVIEW
+\refitem cfg_generate_xml GENERATE_XML
+\refitem cfg_graphical_hierarchy GRAPHICAL_HIERARCHY
+\refitem cfg_group_graphs GROUP_GRAPHS
+\refitem cfg_have_dot HAVE_DOT
+\refitem cfg_hhc_location HHC_LOCATION
+\refitem cfg_hide_friend_compounds HIDE_FRIEND_COMPOUNDS
+\refitem cfg_hide_in_body_docs HIDE_IN_BODY_DOCS
+\refitem cfg_hide_scope_names HIDE_SCOPE_NAMES
+\refitem cfg_hide_undoc_classes HIDE_UNDOC_CLASSES
+\refitem cfg_hide_undoc_members HIDE_UNDOC_MEMBERS
+\refitem cfg_hide_undoc_relations HIDE_UNDOC_RELATIONS
+\refitem cfg_html_colorstyle_gamma HTML_COLORSTYLE_GAMMA
+\refitem cfg_html_colorstyle_hue HTML_COLORSTYLE_HUE
+\refitem cfg_html_colorstyle_sat HTML_COLORSTYLE_SAT
+\refitem cfg_html_dynamic_sections HTML_DYNAMIC_SECTIONS
+\refitem cfg_html_extra_files HTML_EXTRA_FILES
+\refitem cfg_html_extra_stylesheet HTML_EXTRA_STYLESHEET
+\refitem cfg_html_file_extension HTML_FILE_EXTENSION
+\refitem cfg_html_footer HTML_FOOTER
+\refitem cfg_html_header HTML_HEADER
+\refitem cfg_html_index_num_entries HTML_INDEX_NUM_ENTRIES
+\refitem cfg_html_output HTML_OUTPUT
+\refitem cfg_html_stylesheet HTML_STYLESHEET
+\refitem cfg_html_timestamp HTML_TIMESTAMP
+\refitem cfg_idl_property_support IDL_PROPERTY_SUPPORT
+\refitem cfg_ignore_prefix IGNORE_PREFIX
+\refitem cfg_image_path IMAGE_PATH
+\refitem cfg_included_by_graph INCLUDED_BY_GRAPH
+\refitem cfg_include_file_patterns INCLUDE_FILE_PATTERNS
+\refitem cfg_include_graph INCLUDE_GRAPH
+\refitem cfg_include_path INCLUDE_PATH
+\refitem cfg_inherit_docs INHERIT_DOCS
+\refitem cfg_inline_grouped_classes INLINE_GROUPED_CLASSES
+\refitem cfg_inline_info INLINE_INFO
+\refitem cfg_inline_inherited_memb INLINE_INHERITED_MEMB
+\refitem cfg_inline_simple_structs INLINE_SIMPLE_STRUCTS
+\refitem cfg_inline_sources INLINE_SOURCES
+\refitem cfg_input INPUT
+\refitem cfg_input_encoding INPUT_ENCODING
+\refitem cfg_input_filter INPUT_FILTER
+\refitem cfg_interactive_svg INTERACTIVE_SVG
+\refitem cfg_internal_docs INTERNAL_DOCS
+\refitem cfg_javadoc_autobrief JAVADOC_AUTOBRIEF
+\refitem cfg_latex_batchmode LATEX_BATCHMODE
+\refitem cfg_latex_bib_style LATEX_BIB_STYLE
+\refitem cfg_latex_cmd_name LATEX_CMD_NAME
+\refitem cfg_latex_extra_files LATEX_EXTRA_FILES
+\refitem cfg_latex_footer LATEX_FOOTER
+\refitem cfg_latex_header LATEX_HEADER
+\refitem cfg_latex_hide_indices LATEX_HIDE_INDICES
+\refitem cfg_latex_output LATEX_OUTPUT
+\refitem cfg_latex_source_code LATEX_SOURCE_CODE
+\refitem cfg_layout_file LAYOUT_FILE
+\refitem cfg_lookup_cache_size LOOKUP_CACHE_SIZE
+\refitem cfg_macro_expansion MACRO_EXPANSION
+\refitem cfg_makeindex_cmd_name MAKEINDEX_CMD_NAME
+\refitem cfg_man_extension MAN_EXTENSION
+\refitem cfg_man_links MAN_LINKS
+\refitem cfg_man_output MAN_OUTPUT
+\refitem cfg_man_subdir MAN_SUBDIR
+\refitem cfg_markdown_support MARKDOWN_SUPPORT
+\refitem cfg_mathjax_codefile MATHJAX_CODEFILE
+\refitem cfg_mathjax_extensions MATHJAX_EXTENSIONS
+\refitem cfg_mathjax_format MATHJAX_FORMAT
+\refitem cfg_mathjax_relpath MATHJAX_RELPATH
+\refitem cfg_max_dot_graph_depth MAX_DOT_GRAPH_DEPTH
+\refitem cfg_max_initializer_lines MAX_INITIALIZER_LINES
+\refitem cfg_mscfile_dirs MSCFILE_DIRS
+\refitem cfg_mscgen_path MSCGEN_PATH
+\refitem cfg_multiline_cpp_is_brief MULTILINE_CPP_IS_BRIEF
+\refitem cfg_optimize_for_fortran OPTIMIZE_FOR_FORTRAN
+\refitem cfg_optimize_output_for_c OPTIMIZE_OUTPUT_FOR_C
+\refitem cfg_optimize_output_java OPTIMIZE_OUTPUT_JAVA
+\refitem cfg_optimize_output_vhdl OPTIMIZE_OUTPUT_VHDL
+\refitem cfg_output_directory OUTPUT_DIRECTORY
+\refitem cfg_output_language OUTPUT_LANGUAGE
+\refitem cfg_paper_type PAPER_TYPE
+\refitem cfg_pdf_hyperlinks PDF_HYPERLINKS
+\refitem cfg_perlmod_latex PERLMOD_LATEX
+\refitem cfg_perlmod_makevar_prefix PERLMOD_MAKEVAR_PREFIX
+\refitem cfg_perlmod_pretty PERLMOD_PRETTY
+\refitem cfg_perl_path PERL_PATH
+\refitem cfg_plantuml_jar_path PLANTUML_JAR_PATH
+\refitem cfg_predefined PREDEFINED
+\refitem cfg_project_brief PROJECT_BRIEF
+\refitem cfg_project_logo PROJECT_LOGO
+\refitem cfg_project_name PROJECT_NAME
+\refitem cfg_project_number PROJECT_NUMBER
+\refitem cfg_qch_file QCH_FILE
+\refitem cfg_qhg_location QHG_LOCATION
+\refitem cfg_qhp_cust_filter_attrs QHP_CUST_FILTER_ATTRS
+\refitem cfg_qhp_cust_filter_name QHP_CUST_FILTER_NAME
+\refitem cfg_qhp_namespace QHP_NAMESPACE
+\refitem cfg_qhp_sect_filter_attrs QHP_SECT_FILTER_ATTRS
+\refitem cfg_qhp_virtual_folder QHP_VIRTUAL_FOLDER
+\refitem cfg_qt_autobrief QT_AUTOBRIEF
+\refitem cfg_quiet QUIET
+\refitem cfg_recursive RECURSIVE
+\refitem cfg_referenced_by_relation REFERENCED_BY_RELATION
+\refitem cfg_references_link_source REFERENCES_LINK_SOURCE
+\refitem cfg_references_relation REFERENCES_RELATION
+\refitem cfg_repeat_brief REPEAT_BRIEF
+\refitem cfg_rtf_extensions_file RTF_EXTENSIONS_FILE
+\refitem cfg_rtf_hyperlinks RTF_HYPERLINKS
+\refitem cfg_rtf_output RTF_OUTPUT
+\refitem cfg_rtf_stylesheet_file RTF_STYLESHEET_FILE
+\refitem cfg_searchdata_file SEARCHDATA_FILE
+\refitem cfg_searchengine SEARCHENGINE
+\refitem cfg_searchengine_url SEARCHENGINE_URL
+\refitem cfg_search_includes SEARCH_INCLUDES
+\refitem cfg_separate_member_pages SEPARATE_MEMBER_PAGES
+\refitem cfg_server_based_search SERVER_BASED_SEARCH
+\refitem cfg_short_names SHORT_NAMES
+\refitem cfg_show_files SHOW_FILES
+\refitem cfg_show_grouped_memb_inc SHOW_GROUPED_MEMB_INC
+\refitem cfg_show_include_files SHOW_INCLUDE_FILES
+\refitem cfg_show_namespaces SHOW_NAMESPACES
+\refitem cfg_show_used_files SHOW_USED_FILES
+\refitem cfg_sip_support SIP_SUPPORT
+\refitem cfg_skip_function_macros SKIP_FUNCTION_MACROS
+\refitem cfg_sort_brief_docs SORT_BRIEF_DOCS
+\refitem cfg_sort_by_scope_name SORT_BY_SCOPE_NAME
+\refitem cfg_sort_group_names SORT_GROUP_NAMES
+\refitem cfg_sort_members_ctors_1st SORT_MEMBERS_CTORS_1ST
+\refitem cfg_sort_member_docs SORT_MEMBER_DOCS
+\refitem cfg_source_browser SOURCE_BROWSER
+\refitem cfg_source_tooltips SOURCE_TOOLTIPS
+\refitem cfg_strict_proto_matching STRICT_PROTO_MATCHING
+\refitem cfg_strip_code_comments STRIP_CODE_COMMENTS
+\refitem cfg_strip_from_inc_path STRIP_FROM_INC_PATH
+\refitem cfg_strip_from_path STRIP_FROM_PATH
+\refitem cfg_subgrouping SUBGROUPING
+\refitem cfg_tab_size TAB_SIZE
+\refitem cfg_tagfiles TAGFILES
+\refitem cfg_tcl_subst TCL_SUBST
+\refitem cfg_template_relations TEMPLATE_RELATIONS
+\refitem cfg_toc_expand TOC_EXPAND
+\refitem cfg_treeview_width TREEVIEW_WIDTH
+\refitem cfg_typedef_hides_struct TYPEDEF_HIDES_STRUCT
+\refitem cfg_uml_limit_num_fields UML_LIMIT_NUM_FIELDS
+\refitem cfg_uml_look UML_LOOK
+\refitem cfg_use_htags USE_HTAGS
+\refitem cfg_use_mathjax USE_MATHJAX
+\refitem cfg_use_mdfile_as_mainpage USE_MDFILE_AS_MAINPAGE
+\refitem cfg_use_pdflatex USE_PDFLATEX
+\refitem cfg_verbatim_headers VERBATIM_HEADERS
+\refitem cfg_warnings WARNINGS
+\refitem cfg_warn_format WARN_FORMAT
+\refitem cfg_warn_if_doc_error WARN_IF_DOC_ERROR
+\refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
+\refitem cfg_warn_logfile WARN_LOGFILE
+\refitem cfg_warn_no_paramdoc WARN_NO_PARAMDOC
+\refitem cfg_xml_output XML_OUTPUT
+\refitem cfg_xml_programlisting XML_PROGRAMLISTING
+\endsecreflist
+\section config_project Project related configuration options
+ \anchor cfg_doxyfile_encoding
+<dl>
+
+<dt>\c DOXYFILE_ENCODING <dd>
+ \addindex DOXYFILE_ENCODING
+ This tag specifies the encoding used for all characters in the config file that
+ follow. The default is UTF-8 which is also the encoding used for all text before
+ the first occurrence of this tag. Doxygen uses \c libiconv (or the iconv built into
+ \c libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+ possible encodings.
+
+The default value is: <code>UTF-8</code>.
+
+ \anchor cfg_project_name
+<dt>\c PROJECT_NAME <dd>
+ \addindex PROJECT_NAME
+ The \c PROJECT_NAME tag is a single word (or a sequence of words
+ surrounded by double-quotes, unless you are using Doxywizard) that should identify the project for which the
+ documentation is generated. This name is used in the title of most
+ generated pages and in a few other places.
+
+The default value is: <code>My Project</code>.
+
+ \anchor cfg_project_number
+<dt>\c PROJECT_NUMBER <dd>
+ \addindex PROJECT_NUMBER
+ The \c PROJECT_NUMBER tag can be used to enter a project or revision number.
+ This could be handy for archiving the generated documentation or
+ if some version control system is used.
+
+ \anchor cfg_project_brief
+<dt>\c PROJECT_BRIEF <dd>
+ \addindex PROJECT_BRIEF
+ Using the \c PROJECT_BRIEF tag one can provide an optional one line description
+ for a project that appears at the top of each page and should give viewer
+ a quick idea about the purpose of the project. Keep the description short.
+
+ \anchor cfg_project_logo
+<dt>\c PROJECT_LOGO <dd>
+ \addindex PROJECT_LOGO
+ With the \c PROJECT_LOGO tag one can specify an logo or icon that is
+ included in the documentation. The maximum height of the logo should not
+ exceed 55 pixels and the maximum width should not exceed 200 pixels.
+ Doxygen will copy the logo to the output directory.
+
+ \anchor cfg_output_directory
+<dt>\c OUTPUT_DIRECTORY <dd>
+ \addindex OUTPUT_DIRECTORY
+ The \c OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+ path into which the generated documentation will be written.
+ If a relative path is entered, it will be relative to the location
+ where doxygen was started. If left blank the current directory will be used.
+
+ \anchor cfg_create_subdirs
+<dt>\c CREATE_SUBDIRS <dd>
+ \addindex CREATE_SUBDIRS
+ If the \c CREATE_SUBDIRS tag is set to \c YES, then doxygen will create
+ 4096 sub-directories (in 2 levels) under the output directory of each output
+ format and will distribute the generated files over these directories.
+ Enabling this option can be useful when feeding doxygen a huge amount of source
+ files, where putting all generated files in the same directory would otherwise
+ causes performance problems for the file system.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_allow_unicode_names
+<dt>\c ALLOW_UNICODE_NAMES <dd>
+ \addindex ALLOW_UNICODE_NAMES
+ If the \c ALLOW_UNICODE_NAMES tag is set to \c YES,
+ doxygen will allow non-ASCII characters to appear in the names of generated files.
+ If set to \c NO, non-ASCII characters will be escaped, for example _xE3_x81_x84
+ will be used for Unicode U+3044.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_output_language
+<dt>\c OUTPUT_LANGUAGE <dd>
+ \addindex OUTPUT_LANGUAGE
+ The \c OUTPUT_LANGUAGE tag is used to specify the language in which all
+ documentation generated by doxygen is written. Doxygen will use this
+ information to generate all constant output in the proper language.
+
+Possible values are:
+<code>Afrikaans</code>,
+<code>Arabic</code>,
+<code>Armenian</code>,
+<code>Brazilian</code>,
+<code>Catalan</code>,
+<code>Chinese</code>,
+<code>Chinese-Traditional</code>,
+<code>Croatian</code>,
+<code>Czech</code>,
+<code>Danish</code>,
+<code>Dutch</code>,
+<code>English</code> (United States),
+<code>Esperanto</code>,
+<code>Farsi</code> (Persian),
+<code>Finnish</code>,
+<code>French</code>,
+<code>German</code>,
+<code>Greek</code>,
+<code>Hungarian</code>,
+<code>Indonesian</code>,
+<code>Italian</code>,
+<code>Japanese</code>,
+<code>Japanese-en</code> (Japanese with English messages),
+<code>Korean</code>,
+<code>Korean-en</code> (Korean with English messages),
+<code>Latvian</code>,
+<code>Lithuanian</code>,
+<code>Macedonian</code>,
+<code>Norwegian</code>,
+<code>Persian</code> (Farsi),
+<code>Polish</code>,
+<code>Portuguese</code>,
+<code>Romanian</code>,
+<code>Russian</code>,
+<code>Serbian</code>,
+<code>Serbian-Cyrillic</code>,
+<code>Slovak</code>,
+<code>Slovene</code>,
+<code>Spanish</code>,
+<code>Swedish</code>,
+<code>Turkish</code>,
+<code>Ukrainian</code> and
+<code>Vietnamese</code>.
+
+
+The default value is: <code>English</code>.
+
+ \anchor cfg_brief_member_desc
+<dt>\c BRIEF_MEMBER_DESC <dd>
+ \addindex BRIEF_MEMBER_DESC
+ If the \c BRIEF_MEMBER_DESC tag is set to \c YES doxygen will
+ include brief member descriptions after the members that are listed in
+ the file and class documentation (similar to \c Javadoc).
+ Set to \c NO to disable this.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_repeat_brief
+<dt>\c REPEAT_BRIEF <dd>
+ \addindex REPEAT_BRIEF
+ If the \c REPEAT_BRIEF tag is set to \c YES doxygen will
+ prepend the brief description of a member or function before the detailed
+ description
+ <br>Note:
+ If both \ref cfg_hide_undoc_members "HIDE_UNDOC_MEMBERS" and
+ \ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" are set to \c NO, the
+ brief descriptions will be completely suppressed.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_abbreviate_brief
+<dt>\c ABBREVIATE_BRIEF <dd>
+ \addindex ABBREVIATE_BRIEF
+ This tag implements a quasi-intelligent brief description abbreviator
+ that is used to form the text in various listings. Each string
+ in this list, if found as the leading text of the brief description, will be
+ stripped from the text and the result, after processing the whole list, is used
+ as the annotated text. Otherwise, the brief description is used as-is. If left
+ blank, the following values are used (`$name` is automatically replaced with the
+ name of the entity):
+<code>The $name class</code>,
+<code>The $name widget</code>,
+<code>The $name file</code>,
+<code>is</code>,
+<code>provides</code>,
+<code>specifies</code>,
+<code>contains</code>,
+<code>represents</code>,
+<code>a</code>,
+<code>an</code> and
+<code>the</code>.
+
+ \anchor cfg_always_detailed_sec
+<dt>\c ALWAYS_DETAILED_SEC <dd>
+ \addindex ALWAYS_DETAILED_SEC
+ If the \c ALWAYS_DETAILED_SEC and \ref cfg_repeat_brief "REPEAT_BRIEF" tags
+ are both set to \c YES then
+ doxygen will generate a detailed section even if there is only a brief
+ description.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_inline_inherited_memb
+<dt>\c INLINE_INHERITED_MEMB <dd>
+ \addindex INLINE_INHERITED_MEMB
+ If the \c INLINE_INHERITED_MEMB tag is set to \c YES, doxygen will show all inherited
+ members of a class in the documentation of that class as if those members were
+ ordinary class members. Constructors, destructors and assignment operators of
+ the base classes will not be shown.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_full_path_names
+<dt>\c FULL_PATH_NAMES <dd>
+ \addindex FULL_PATH_NAMES
+ If the \c FULL_PATH_NAMES tag is set to \c YES doxygen will prepend the full
+ path before files name in the file list and in the header files. If set
+ to \c NO the shortest path that makes the file name unique will be used
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_strip_from_path
+<dt>\c STRIP_FROM_PATH <dd>
+ \addindex STRIP_FROM_PATH
+ The \c STRIP_FROM_PATH tag
+ can be used to strip a user-defined part of the path. Stripping is
+ only done if one of the specified strings matches the left-hand part of the
+ path. The tag can be used to show relative paths in the file list.
+ If left blank the directory from which doxygen is run is used as the
+ path to strip.
+ <br>Note that you can specify absolute paths here, but also
+ relative paths, which will be relative from the directory where doxygen is
+ started.
+
+
+This tag requires that the tag \ref cfg_full_path_names "FULL_PATH_NAMES" is set to \c YES.
+ \anchor cfg_strip_from_inc_path
+<dt>\c STRIP_FROM_INC_PATH <dd>
+ \addindex STRIP_FROM_INC_PATH
+ The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+ the path mentioned in the documentation of a class, which tells
+ the reader which header file to include in order to use a class.
+ If left blank only the name of the header file containing the class
+ definition is used. Otherwise one should specify the list of include paths that
+ are normally passed to the compiler using the `-I` flag.
+
+ \anchor cfg_short_names
+<dt>\c SHORT_NAMES <dd>
+ \addindex SHORT_NAMES
+ If the \c SHORT_NAMES tag is set to \c YES, doxygen will generate much shorter
+ (but less readable) file names. This can be useful is your file systems
+ doesn't support long names like on DOS, Mac, or CD-ROM.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_javadoc_autobrief
+<dt>\c JAVADOC_AUTOBRIEF <dd>
+ \addindex JAVADOC_AUTOBRIEF
+ If the \c JAVADOC_AUTOBRIEF tag is set to \c YES then doxygen
+ will interpret the first line (until the first dot) of a Javadoc-style
+ comment as the brief description. If set to \c NO, the
+ Javadoc-style will behave just like regular Qt-style comments
+ (thus requiring an explicit \ref cmdbrief "\@brief" command for a brief description.)
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_qt_autobrief
+<dt>\c QT_AUTOBRIEF <dd>
+ \addindex QT_AUTOBRIEF
+ If the \c QT_AUTOBRIEF tag is set to \c YES then doxygen
+ will interpret the first line (until the first dot) of a Qt-style
+ comment as the brief description. If set to \c NO, the
+ Qt-style will behave just like regular Qt-style comments (thus
+ requiring an explicit \ref cmdbrief "\\brief" command for a brief description.)
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_multiline_cpp_is_brief
+<dt>\c MULTILINE_CPP_IS_BRIEF <dd>
+ \addindex MULTILINE_CPP_IS_BRIEF
+ The \c MULTILINE_CPP_IS_BRIEF tag can be set to \c YES to make doxygen
+ treat a multi-line C++ special comment block (i.e. a block of \c //! or \c ///
+ comments) as a brief description. This used to be the default behavior.
+ The new default is to treat a multi-line C++ comment block as a detailed
+ description. Set this tag to \c YES if you prefer the old behavior instead.
+ <br>Note that setting this tag to \c YES also means that rational rose comments
+ are not recognized any more.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_inherit_docs
+<dt>\c INHERIT_DOCS <dd>
+ \addindex INHERIT_DOCS
+ If the \c INHERIT_DOCS tag is set to \c YES then an undocumented
+ member inherits the documentation from any documented member that it
+ re-implements.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_separate_member_pages
+<dt>\c SEPARATE_MEMBER_PAGES <dd>
+ \addindex SEPARATE_MEMBER_PAGES
+ If the \c SEPARATE_MEMBER_PAGES tag is set to \c YES, then doxygen will produce
+ a new page for each member. If set to \c NO, the documentation of a member will
+ be part of the file/class/namespace that contains it.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_tab_size
+<dt>\c TAB_SIZE <dd>
+ \addindex TAB_SIZE
+ The \c TAB_SIZE tag can be used to set the number of spaces in a tab.
+ Doxygen uses this value to replace tabs by spaces in code fragments.
+
+
+ Minimum value: <code>1</code>, maximum value: <code>16</code>, default value: <code>4</code>.
+
+ \anchor cfg_aliases
+<dt>\c ALIASES <dd>
+ \addindex ALIASES
+ This tag can be used to specify a number of aliases that act
+ as commands in the documentation. An alias has the form:
+\verbatim
+ name=value
+\endverbatim
+ For example adding
+\verbatim
+ "sideeffect=@par Side Effects:\n"
+\endverbatim
+ will allow you to
+ put the command \c \\sideeffect (or \c \@sideeffect) in the documentation, which
+ will result in a user-defined paragraph with heading "Side Effects:".
+ You can put \ref cmdn "\\n"'s in the value part of an alias to insert newlines.
+
+ \anchor cfg_tcl_subst
+<dt>\c TCL_SUBST <dd>
+ \addindex TCL_SUBST
+ This tag can be used to specify a number of word-keyword mappings (TCL only).
+ A mapping has the form <code>"name=value"</code>. For example adding
+ <code>"class=itcl::class"</code> will allow you to use the command class in the
+ <code>itcl::class</code> meaning.
+
+ \anchor cfg_optimize_output_for_c
+<dt>\c OPTIMIZE_OUTPUT_FOR_C <dd>
+ \addindex OPTIMIZE_OUTPUT_FOR_C
+ Set the \c OPTIMIZE_OUTPUT_FOR_C tag to \c YES if your project consists
+ of C sources only. Doxygen will then generate output that is more tailored
+ for C. For instance, some of the names that are used will be different.
+ The list of all members will be omitted, etc.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_optimize_output_java
+<dt>\c OPTIMIZE_OUTPUT_JAVA <dd>
+ \addindex OPTIMIZE_OUTPUT_JAVA
+ Set the \c OPTIMIZE_OUTPUT_JAVA tag to \c YES if your project consists of Java or
+ Python sources only. Doxygen will then generate output that is more tailored
+ for that language. For instance, namespaces will be presented as packages,
+ qualified scopes will look different, etc.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_optimize_for_fortran
+<dt>\c OPTIMIZE_FOR_FORTRAN <dd>
+ \addindex OPTIMIZE_FOR_FORTRAN
+ Set the \c OPTIMIZE_FOR_FORTRAN tag to \c YES if your project consists of Fortran
+ sources. Doxygen will then generate output that is tailored for Fortran.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_optimize_output_vhdl
+<dt>\c OPTIMIZE_OUTPUT_VHDL <dd>
+ \addindex OPTIMIZE_OUTPUT_VHDL
+ Set the \c OPTIMIZE_OUTPUT_VHDL tag to \c YES if your project consists of VHDL
+ sources. Doxygen will then generate output that is tailored for VHDL.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extension_mapping
+<dt>\c EXTENSION_MAPPING <dd>
+ \addindex EXTENSION_MAPPING
+ Doxygen selects the parser to use depending on the extension of the files it parses.
+ With this tag you can assign which parser to use for a given extension.
+ Doxygen has a built-in mapping, but you can override or extend it using this tag.
+ The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of
+ the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+ Objective-C, Python, Fortran (fixed format Fortran: FortranFixed,
+ free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In
+ the later case the parser tries to guess whether the code is fixed or free
+ formatted code, this is the default for Fortran type files), VHDL.
+
+ For instance to make doxygen treat
+ <code>.inc</code> files as Fortran files (default is PHP), and <code>.f</code> files as C (default is Fortran),
+ use: `inc=Fortran f=C`.
+
+ <br>Note For files without extension you can use `no_extension` as a placeholder.
+ <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the
+ files are not read by doxygen.
+
+ \anchor cfg_markdown_support
+<dt>\c MARKDOWN_SUPPORT <dd>
+ \addindex MARKDOWN_SUPPORT
+ If the \c MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all
+ comments according to the Markdown format, which allows for more readable
+ documentation. See http://daringfireball.net/projects/markdown/ for details.
+ The output of markdown processing is further processed by doxygen, so you
+ can mix doxygen, HTML, and XML commands with Markdown formatting.
+ Disable only in case of backward compatibilities issues.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_autolink_support
+<dt>\c AUTOLINK_SUPPORT <dd>
+ \addindex AUTOLINK_SUPPORT
+ When enabled doxygen tries to link words that correspond to documented classes,
+ or namespaces to their corresponding documentation. Such a link can be
+ prevented in individual cases by by putting a \c % sign in front of the word or
+ globally by setting \c AUTOLINK_SUPPORT to \c NO.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_builtin_stl_support
+<dt>\c BUILTIN_STL_SUPPORT <dd>
+ \addindex BUILTIN_STL_SUPPORT
+ If you use STL classes (i.e. `std::string`, `std::vector`, etc.) but do not want to
+ include (a tag file for) the STL sources as input, then you should
+ set this tag to \c YES in order to let doxygen match functions declarations and
+ definitions whose arguments contain STL classes (e.g. `func(std::string`); versus
+ `func(std::string) {}`). This also make the inheritance and collaboration
+ diagrams that involve STL classes more complete and accurate.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_cpp_cli_support
+<dt>\c CPP_CLI_SUPPORT <dd>
+ \addindex CPP_CLI_SUPPORT
+ If you use Microsoft's C++/CLI language, you should set this option to \c YES to
+ enable parsing support.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_sip_support
+<dt>\c SIP_SUPPORT <dd>
+ \addindex SIP_SUPPORT
+ Set the \c SIP_SUPPORT tag to \c YES if your project consists
+ of <a href="http://www.riverbankcomputing.co.uk/software/sip/intro">sip</a> sources only.
+ Doxygen will parse them like normal C++ but will assume all classes use public
+ instead of private inheritance when no explicit protection keyword is present.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_idl_property_support
+<dt>\c IDL_PROPERTY_SUPPORT <dd>
+ \addindex IDL_PROPERTY_SUPPORT
+ For Microsoft's IDL there are \c propget and \c propput attributes to indicate getter
+ and setter methods for a property. Setting this option to \c YES
+ will make doxygen to replace the get and set methods by a property in the
+ documentation. This will only work if the methods are indeed getting or
+ setting a simple type. If this is not the case, or you want to show the
+ methods anyway, you should set this option to \c NO.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_distribute_group_doc
+<dt>\c DISTRIBUTE_GROUP_DOC <dd>
+ \addindex DISTRIBUTE_GROUP_DOC
+ If member grouping is used in the documentation and the \c DISTRIBUTE_GROUP_DOC
+ tag is set to \c YES, then doxygen will reuse the documentation of the first
+ member in the group (if any) for the other members of the group. By default
+ all members of a group must be documented explicitly.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_subgrouping
+<dt>\c SUBGROUPING <dd>
+ \addindex SUBGROUPING
+ Set the \c SUBGROUPING tag to \c YES to allow class member groups of
+ the same type (for instance a group of public functions) to be put as a
+ subgroup of that type (e.g. under the Public Functions section). Set it to
+ \c NO to prevent subgrouping. Alternatively, this can be done per class using
+ the \ref cmdnosubgrouping "\\nosubgrouping" command.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_inline_grouped_classes
+<dt>\c INLINE_GROUPED_CLASSES <dd>
+ \addindex INLINE_GROUPED_CLASSES
+ When the \c INLINE_GROUPED_CLASSES tag is set to \c YES, classes, structs and
+ unions are shown inside the group in which they are included
+ (e.g. using \ref cmdingroup "\\ingroup") instead of on a separate page (for HTML and Man pages)
+ or section (for \f$\mbox{\LaTeX}\f$ and RTF).
+ <br>Note that this feature does not work in
+ combination with \ref cfg_separate_member_pages "SEPARATE_MEMBER_PAGES".
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_inline_simple_structs
+<dt>\c INLINE_SIMPLE_STRUCTS <dd>
+ \addindex INLINE_SIMPLE_STRUCTS
+ When the \c INLINE_SIMPLE_STRUCTS tag is set to \c YES, structs, classes, and
+ unions with only public data fields or simple typedef fields will be shown
+ inline in the documentation of the scope in which they are defined (i.e. file,
+ namespace, or group documentation), provided this scope is documented. If set
+ to \c NO, structs, classes, and unions are shown on a separate
+ page (for HTML and Man pages) or section (for \f$\mbox{\LaTeX}\f$ and RTF).
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_typedef_hides_struct
+<dt>\c TYPEDEF_HIDES_STRUCT <dd>
+ \addindex TYPEDEF_HIDES_STRUCT
+ When \c TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or enum
+ is documented as struct, union, or enum with the name of the typedef. So
+ <code>typedef struct TypeS {} TypeT</code>, will appear in the documentation as a struct
+ with name \c TypeT. When disabled the typedef will appear as a member of a file,
+ namespace, or class. And the struct will be named \c TypeS. This can typically
+ be useful for C code in case the coding convention dictates that all compound
+ types are typedef'ed and only the typedef is referenced, never the tag name.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_lookup_cache_size
+<dt>\c LOOKUP_CACHE_SIZE <dd>
+ \addindex LOOKUP_CACHE_SIZE
+ The size of the symbol lookup cache can be
+ set using \c LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+ their name and scope. Since this can be an expensive process and often the
+ same symbol appears multiple times in the code, doxygen keeps a cache of
+ pre-resolved symbols. If the cache is too small doxygen will become slower.
+ If the cache is too large, memory is wasted. The cache size is given by this
+ formula: \f$2^{(16+\mbox{LOOKUP\_CACHE\_SIZE})}\f$. The valid range is 0..9, the default is 0,
+ corresponding to a cache size of \f$2^{16} = 65536\f$ symbols.
+ At the end of a run doxygen will report the cache usage and suggest the
+ optimal cache size from a speed point of view.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>9</code>, default value: <code>0</code>.
+
+</dl>
+\section config_build Build related configuration options
+ \anchor cfg_extract_all
+<dl>
+
+<dt>\c EXTRACT_ALL <dd>
+ \addindex EXTRACT_ALL
+ If the \c EXTRACT_ALL tag is set to \c YES doxygen will assume all
+ entities in documentation are documented, even if no documentation was
+ available. Private class members and static file members will be hidden
+ unless the \ref cfg_extract_private "EXTRACT_PRIVATE" respectively
+ \ref cfg_extract_static "EXTRACT_STATIC" tags are set to \c YES.
+
+ \note This will also disable the warnings about undocumented members
+ that are normally produced when \ref cfg_warnings "WARNINGS" is
+ set to \c YES.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extract_private
+<dt>\c EXTRACT_PRIVATE <dd>
+ \addindex EXTRACT_PRIVATE
+ If the \c EXTRACT_PRIVATE tag is set to \c YES all private members of a
+ class will be included in the documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extract_package
+<dt>\c EXTRACT_PACKAGE <dd>
+ \addindex EXTRACT_PACKAGE
+ If the \c EXTRACT_PACKAGE tag is set to \c YES all members with package
+ or internal scope will be included in the documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extract_static
+<dt>\c EXTRACT_STATIC <dd>
+ \addindex EXTRACT_STATIC
+ If the \c EXTRACT_STATIC tag is set to \c YES all static members of a file
+ will be included in the documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extract_local_classes
+<dt>\c EXTRACT_LOCAL_CLASSES <dd>
+ \addindex EXTRACT_LOCAL_CLASSES
+ If the \c EXTRACT_LOCAL_CLASSES tag is set to \c YES classes (and structs)
+ defined locally in source files will be included in the documentation.
+ If set to \c NO only classes defined in header files are included. Does not
+ have any effect for Java sources.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_extract_local_methods
+<dt>\c EXTRACT_LOCAL_METHODS <dd>
+ \addindex EXTRACT_LOCAL_METHODS
+ This flag is only useful for Objective-C code. When set to \c YES local
+ methods, which are defined in the implementation section but not in
+ the interface are included in the documentation.
+ If set to \c NO only methods in the interface are included.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_extract_anon_nspaces
+<dt>\c EXTRACT_ANON_NSPACES <dd>
+ \addindex EXTRACT_ANON_NSPACES
+ If this flag is set to \c YES, the members of anonymous namespaces will be extracted
+ and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+ where file will be replaced with the base name of the file that contains the anonymous
+ namespace. By default anonymous namespace are hidden.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_hide_undoc_members
+<dt>\c HIDE_UNDOC_MEMBERS <dd>
+ \addindex HIDE_UNDOC_MEMBERS
+ If the \c HIDE_UNDOC_MEMBERS tag is set to \c YES, doxygen will hide all
+ undocumented members inside documented classes or files.
+ If set to \c NO these members will be included in the
+ various overviews, but no documentation section is generated.
+ This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_hide_undoc_classes
+<dt>\c HIDE_UNDOC_CLASSES <dd>
+ \addindex HIDE_UNDOC_CLASSES
+ If the \c HIDE_UNDOC_CLASSES tag is set to \c YES, doxygen will hide all
+ undocumented classes that are normally visible in the class hierarchy.
+ If set to \c NO these classes will be included in the
+ various overviews.
+ This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_hide_friend_compounds
+<dt>\c HIDE_FRIEND_COMPOUNDS <dd>
+ \addindex HIDE_FRIEND_COMPOUNDS
+ If the \c HIDE_FRIEND_COMPOUNDS tag is set to \c YES, doxygen will hide all
+ friend (class|struct|union) declarations.
+ If set to \c NO these declarations will be included in the
+ documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_hide_in_body_docs
+<dt>\c HIDE_IN_BODY_DOCS <dd>
+ \addindex HIDE_IN_BODY_DOCS
+ If the \c HIDE_IN_BODY_DOCS tag is set to \c YES, doxygen will hide any
+ documentation blocks found inside the body of a function.
+ If set to \c NO these blocks will be appended to the
+ function's detailed documentation block.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_internal_docs
+<dt>\c INTERNAL_DOCS <dd>
+ \addindex INTERNAL_DOCS
+ The \c INTERNAL_DOCS tag determines if documentation
+ that is typed after a \ref cmdinternal "\\internal" command is included. If the tag is set
+ to \c NO then the documentation will be excluded.
+ Set it to \c YES to include the internal documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_case_sense_names
+<dt>\c CASE_SENSE_NAMES <dd>
+ \addindex CASE_SENSE_NAMES
+ If the \c CASE_SENSE_NAMES tag is set to \c NO then doxygen
+ will only generate file names in lower-case letters. If set to
+ \c YES upper-case letters are also allowed. This is useful if you have
+ classes or files whose names only differ in case and if your file system
+ supports case sensitive file names. Windows and Mac users are advised to set this
+ option to \c NO.
+
+
+The default value is: system dependent.
+
+ \anchor cfg_hide_scope_names
+<dt>\c HIDE_SCOPE_NAMES <dd>
+ \addindex HIDE_SCOPE_NAMES
+ If the \c HIDE_SCOPE_NAMES tag is set to \c NO then doxygen
+ will show members with their full class and namespace scopes in the
+ documentation. If set to \c YES the scope will be hidden.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_show_include_files
+<dt>\c SHOW_INCLUDE_FILES <dd>
+ \addindex SHOW_INCLUDE_FILES
+ If the \c SHOW_INCLUDE_FILES tag is set to \c YES then doxygen
+ will put a list of the files that are included by a file in the documentation
+ of that file.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_show_grouped_memb_inc
+<dt>\c SHOW_GROUPED_MEMB_INC <dd>
+ \addindex SHOW_GROUPED_MEMB_INC
+ If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen
+ will add for each grouped member an include statement to the documentation,
+ telling the reader which file to include in order to use the member.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_force_local_includes
+<dt>\c FORCE_LOCAL_INCLUDES <dd>
+ \addindex FORCE_LOCAL_INCLUDES
+ If the \c FORCE_LOCAL_INCLUDES tag is set to \c YES then doxygen
+ will list include files with double quotes in the documentation
+ rather than with sharp brackets.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_inline_info
+<dt>\c INLINE_INFO <dd>
+ \addindex INLINE_INFO
+ If the \c INLINE_INFO tag is set to \c YES then a tag [inline]
+ is inserted in the documentation for inline members.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_sort_member_docs
+<dt>\c SORT_MEMBER_DOCS <dd>
+ \addindex SORT_MEMBER_DOCS
+ If the \c SORT_MEMBER_DOCS tag is set to \c YES then doxygen
+ will sort the (detailed) documentation of file and class members
+ alphabetically by member name. If set to \c NO the members will appear in
+ declaration order.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_sort_brief_docs
+<dt>\c SORT_BRIEF_DOCS <dd>
+ \addindex SORT_BRIEF_DOCS
+ If the \c SORT_BRIEF_DOCS tag is set to \c YES then doxygen will sort the
+ brief descriptions of file, namespace and class members alphabetically
+ by member name. If set to \c NO the members will appear in
+ declaration order. Note that this will also influence the order of the
+ classes in the class list.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_sort_members_ctors_1st
+<dt>\c SORT_MEMBERS_CTORS_1ST <dd>
+ \addindex SORT_MEMBERS_CTORS_1ST
+ If the \c SORT_MEMBERS_CTORS_1ST tag is set to \c YES then doxygen
+ will sort the (brief and detailed) documentation of class members so that
+ constructors and destructors are listed first. If set to \c NO
+ the constructors will appear in the respective orders defined by
+ \ref cfg_sort_brief_docs "SORT_BRIEF_DOCS" and \ref cfg_sort_member_docs "SORT_MEMBER_DOCS".
+ \note If \ref cfg_sort_brief_docs "SORT_BRIEF_DOCS" is set to \c NO this option is ignored for
+ sorting brief member documentation.
+ \note If \ref cfg_sort_member_docs "SORT_MEMBER_DOCS" is set to \c NO this option is ignored for
+ sorting detailed member documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_sort_group_names
+<dt>\c SORT_GROUP_NAMES <dd>
+ \addindex SORT_GROUP_NAMES
+ If the \c SORT_GROUP_NAMES tag is set to \c YES then doxygen will sort the
+ hierarchy of group names into alphabetical order. If set to \c NO
+ the group names will appear in their defined order.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_sort_by_scope_name
+<dt>\c SORT_BY_SCOPE_NAME <dd>
+ \addindex SORT_BY_SCOPE_NAME
+ If the \c SORT_BY_SCOPE_NAME tag is set to \c YES, the class list will be
+ sorted by fully-qualified names, including namespaces. If set to
+ \c NO, the class list will be sorted only by class name,
+ not including the namespace part.
+ \note This option is not very useful if \ref cfg_hide_scope_names "HIDE_SCOPE_NAMES" is set to \c YES.
+ \note This option applies only to the class list, not to the
+ alphabetical list.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_strict_proto_matching
+<dt>\c STRICT_PROTO_MATCHING <dd>
+ \addindex STRICT_PROTO_MATCHING
+ If the \c STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+ do proper type resolution of all parameters of a function it will reject a
+ match between the prototype and the implementation of a member function even
+ if there is only one candidate or it is obvious which candidate to choose
+ by doing a simple string match. By disabling \c STRICT_PROTO_MATCHING doxygen
+ will still accept a match between prototype and implementation in such cases.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_generate_todolist
+<dt>\c GENERATE_TODOLIST <dd>
+ \addindex GENERATE_TODOLIST
+ The \c GENERATE_TODOLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the todo list. This list is created by
+ putting \ref cmdtodo "\\todo" commands in the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_generate_testlist
+<dt>\c GENERATE_TESTLIST <dd>
+ \addindex GENERATE_TESTLIST
+ The \c GENERATE_TESTLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the test list. This list is created by
+ putting \ref cmdtest "\\test" commands in the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_generate_buglist
+<dt>\c GENERATE_BUGLIST <dd>
+ \addindex GENERATE_BUGLIST
+ The \c GENERATE_BUGLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the bug list. This list is created by
+ putting \ref cmdbug "\\bug" commands in the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_generate_deprecatedlist
+<dt>\c GENERATE_DEPRECATEDLIST <dd>
+ \addindex GENERATE_DEPRECATEDLIST
+ The \c GENERATE_DEPRECATEDLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the deprecated list. This list is created by
+ putting \ref cmddeprecated "\\deprecated"
+ commands in the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_enabled_sections
+<dt>\c ENABLED_SECTIONS <dd>
+ \addindex ENABLED_SECTIONS
+ The \c ENABLED_SECTIONS tag can be used to enable conditional
+ documentation sections, marked by \ref cmdif "\\if" \<section_label\> ...
+ \ref cmdendif "\\endif" and \ref cmdcond "\\cond" \<section_label\> ...
+ \ref cmdendcond "\\endcond" blocks.
+
+ \anchor cfg_max_initializer_lines
+<dt>\c MAX_INITIALIZER_LINES <dd>
+ \addindex MAX_INITIALIZER_LINES
+ The \c MAX_INITIALIZER_LINES tag determines the maximum number of lines
+ that the initial value of a variable or macro / define can have for it to appear in
+ the documentation. If the initializer
+ consists of more lines than specified here it will be hidden. Use a value
+ of 0 to hide initializers completely. The appearance of the value of
+ individual variables and macros / defines can be controlled using \ref cmdshowinitializer "\\showinitializer"
+ or \ref cmdhideinitializer "\\hideinitializer" command in the documentation regardless of this setting.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>10000</code>, default value: <code>30</code>.
+
+ \anchor cfg_show_used_files
+<dt>\c SHOW_USED_FILES <dd>
+ \addindex SHOW_USED_FILES
+ Set the \c SHOW_USED_FILES tag to \c NO to disable the list of files generated
+ at the bottom of the documentation of classes and structs. If set to \c YES the
+ list will mention the files that were used to generate the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_show_files
+<dt>\c SHOW_FILES <dd>
+ \addindex SHOW_FILES
+ Set the \c SHOW_FILES tag to \c NO to disable the generation of the Files page.
+ This will remove the Files entry from the Quick Index and from the
+ Folder Tree View (if specified).
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_show_namespaces
+<dt>\c SHOW_NAMESPACES <dd>
+ \addindex SHOW_NAMESPACES
+ Set the \c SHOW_NAMESPACES tag to \c NO to disable the generation of the
+ Namespaces page. This will remove the Namespaces entry from the Quick Index
+ and from the Folder Tree View (if specified).
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_file_version_filter
+<dt>\c FILE_VERSION_FILTER <dd>
+ \addindex FILE_VERSION_FILTER
+ The \c FILE_VERSION_FILTER tag can be used to specify a program or script that
+ doxygen should invoke to get the current version for each file (typically from the
+ version control system). Doxygen will invoke the program by executing (via
+ <code>popen()</code>) the command <code>command input-file</code>, where \c command is
+ the value of the \c FILE_VERSION_FILTER tag, and \c input-file is the name
+ of an input file provided by doxygen.
+ Whatever the program writes to standard output is used as the file version.Example of using a shell script as a filter for Unix:
+\verbatim
+ FILE_VERSION_FILTER = "/bin/sh versionfilter.sh"
+\endverbatim
+<br>
+Example shell script for CVS:
+\verbatim
+#!/bin/sh
+cvs status $1 | sed -n 's/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p'
+\endverbatim
+<br>
+Example shell script for Subversion:
+\verbatim
+#!/bin/sh
+svn stat -v $1 | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p'
+\endverbatim
+<br>
+Example filter for ClearCase:
+\verbatim
+FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
+\endverbatim
+
+ \anchor cfg_layout_file
+<dt>\c LAYOUT_FILE <dd>
+ \addindex LAYOUT_FILE
+ The \c LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+ doxygen. The layout file controls the global structure of the generated output files
+ in an output format independent way. To create the layout file that represents
+ doxygen's defaults, run doxygen with the `-l` option. You can optionally specify a
+ file name after the option, if omitted \c DoxygenLayout.xml will be used as the name
+ of the layout file.
+ <br>Note that if you run doxygen from a directory containing
+ a file called \c DoxygenLayout.xml, doxygen will parse it automatically even if
+ the \c LAYOUT_FILE tag is left empty.
+
+ \anchor cfg_cite_bib_files
+<dt>\c CITE_BIB_FILES <dd>
+ \addindex CITE_BIB_FILES
+ The \c CITE_BIB_FILES tag can be used to specify one or more \c bib files
+ containing the reference definitions. This must be a list of <code>.bib</code> files. The
+ <code>.bib</code> extension is automatically appended if omitted. This requires the
+ \c bibtex tool to be installed. See also http://en.wikipedia.org/wiki/BibTeX for
+ more info. For \f$\mbox{\LaTeX}\f$ the style of the bibliography can be controlled
+ using \ref cfg_latex_bib_style "LATEX_BIB_STYLE".
+ To use this feature you need \c bibtex and \c perl available in the search path.
+ See also \ref cmdcite "\\cite" for info how to create references.
+
+</dl>
+\section config_messages Configuration options related to warning and progress messages
+ \anchor cfg_quiet
+<dl>
+
+<dt>\c QUIET <dd>
+ \addindex QUIET
+ The \c QUIET tag can be used to turn on/off the messages that are generated
+ to standard output by doxygen. If \c QUIET is set to \c YES this implies that the messages are off.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_warnings
+<dt>\c WARNINGS <dd>
+ \addindex WARNINGS
+ The \c WARNINGS tag can be used to turn on/off the warning messages that are
+ generated to standard error (\c stderr) by doxygen. If \c WARNINGS is set to
+ \c YES this implies that the warnings are on.
+<br>
+ \b Tip: Turn warnings on while writing the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_warn_if_undocumented
+<dt>\c WARN_IF_UNDOCUMENTED <dd>
+ \addindex WARN_IF_UNDOCUMENTED
+ If the \c WARN_IF_UNDOCUMENTED tag is set to \c YES, then doxygen will generate warnings
+ for undocumented members. If \ref cfg_extract_all "EXTRACT_ALL" is set to \c YES then this flag will
+ automatically be disabled.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_warn_if_doc_error
+<dt>\c WARN_IF_DOC_ERROR <dd>
+ \addindex WARN_IF_DOC_ERROR
+ If the \c WARN_IF_DOC_ERROR tag is set to \c YES, doxygen will generate warnings for
+ potential errors in the documentation, such as not documenting some
+ parameters in a documented function, or documenting parameters that
+ don't exist or using markup commands wrongly.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_warn_no_paramdoc
+<dt>\c WARN_NO_PARAMDOC <dd>
+ \addindex WARN_NO_PARAMDOC
+ This \c WARN_NO_PARAMDOC option can be enabled to get warnings for
+ functions that are documented, but have no documentation for their parameters
+ or return value. If set to \c NO doxygen will only warn about
+ wrong or incomplete parameter documentation, but not about the absence of
+ documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_warn_format
+<dt>\c WARN_FORMAT <dd>
+ \addindex WARN_FORMAT
+ The \c WARN_FORMAT tag determines the format of the warning messages that
+ doxygen can produce. The string should contain the <code>\$file</code>,
+ <code>\$line</code>, and <code>\$text</code>
+ tags, which will be replaced by the file and line number from which the
+ warning originated and the warning text.
+ Optionally the format may contain
+ <code>$version</code>, which will be replaced by the version of the file (if it could
+ be obtained via \ref cfg_file_version_filter "FILE_VERSION_FILTER")
+
+The default value is: <code>$file:$line: $text</code>.
+
+ \anchor cfg_warn_logfile
+<dt>\c WARN_LOGFILE <dd>
+ \addindex WARN_LOGFILE
+ The \c WARN_LOGFILE tag can be used to specify a file to which warning
+ and error messages should be written. If left blank the output is written
+ to standard error (`stderr`).
+
+</dl>
+\section config_input Configuration options related to the input files
+ \anchor cfg_input
+<dl>
+
+<dt>\c INPUT <dd>
+ \addindex INPUT
+ The \c INPUT tag is used to specify the files and/or directories that contain
+ documented source files. You may enter file names like
+ \c myfile.cpp or directories like \c /usr/src/myproject.
+ Separate the files or directories with spaces.
+
+ \note If this tag is empty the current directory is searched.
+
+ \anchor cfg_input_encoding
+<dt>\c INPUT_ENCODING <dd>
+ \addindex INPUT_ENCODING
+ This tag can be used to specify the character encoding of the source files that
+ doxygen parses. Internally doxygen uses the UTF-8 encoding.
+ Doxygen uses `libiconv` (or the `iconv` built into `libc`) for the transcoding.
+ See <a href="http://www.gnu.org/software/libiconv">the libiconv documentation</a> for
+ the list of possible encodings.
+
+The default value is: <code>UTF-8</code>.
+
+ \anchor cfg_file_patterns
+<dt>\c FILE_PATTERNS <dd>
+ \addindex FILE_PATTERNS
+ If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the
+ \c FILE_PATTERNS tag to specify one or more wildcard patterns
+ (like `*.cpp` and `*.h`) to filter out the source-files
+ in the directories. If left blank the following patterns are tested:
+<code>*.c</code>,
+<code>*.cc</code>,
+<code>*.cxx</code>,
+<code>*.cpp</code>,
+<code>*.c++</code>,
+<code>*.java</code>,
+<code>*.ii</code>,
+<code>*.ixx</code>,
+<code>*.ipp</code>,
+<code>*.i++</code>,
+<code>*.inl</code>,
+<code>*.idl</code>,
+<code>*.ddl</code>,
+<code>*.odl</code>,
+<code>*.h</code>,
+<code>*.hh</code>,
+<code>*.hxx</code>,
+<code>*.hpp</code>,
+<code>*.h++</code>,
+<code>*.cs</code>,
+<code>*.d</code>,
+<code>*.php</code>,
+<code>*.php4</code>,
+<code>*.php5</code>,
+<code>*.phtml</code>,
+<code>*.inc</code>,
+<code>*.m</code>,
+<code>*.markdown</code>,
+<code>*.md</code>,
+<code>*.mm</code>,
+<code>*.dox</code>,
+<code>*.py</code>,
+<code>*.f90</code>,
+<code>*.f</code>,
+<code>*.for</code>,
+<code>*.tcl</code>,
+<code>*.vhd</code>,
+<code>*.vhdl</code>,
+<code>*.ucf</code>,
+<code>*.qsf</code>,
+<code>*.as</code> and
+<code>*.js</code>.
+
+ \anchor cfg_recursive
+<dt>\c RECURSIVE <dd>
+ \addindex RECURSIVE
+ The \c RECURSIVE tag can be used to specify whether or not subdirectories
+ should be searched for input files as well.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_exclude
+<dt>\c EXCLUDE <dd>
+ \addindex EXCLUDE
+ The \c EXCLUDE tag can be used to specify files and/or directories that should be
+ excluded from the \ref cfg_input "INPUT" source files. This way you can easily exclude a
+ subdirectory from a directory tree whose root is specified with the \ref cfg_input "INPUT" tag.
+ <br>Note that relative paths are relative to the directory from which doxygen is run.
+
+ \anchor cfg_exclude_symlinks
+<dt>\c EXCLUDE_SYMLINKS <dd>
+ \addindex EXCLUDE_SYMLINKS
+ The \c EXCLUDE_SYMLINKS tag can be used to select whether or not files or directories
+ that are symbolic links (a Unix file system feature) are excluded from the input.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_exclude_patterns
+<dt>\c EXCLUDE_PATTERNS <dd>
+ \addindex EXCLUDE_PATTERNS
+ If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the
+ \c EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+ certain files from those directories.
+ <br>Note that the wildcards are matched
+ against the file with absolute path, so to exclude all test directories
+ for example use the pattern `*``/test/``*`
+
+ \anchor cfg_exclude_symbols
+<dt>\c EXCLUDE_SYMBOLS <dd>
+ \addindex EXCLUDE_SYMBOLS
+ The \c EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+ (namespaces, classes, functions, etc.) that should be excluded from the
+ output. The symbol name can be a fully qualified name, a word, or if the
+ wildcard `*` is used, a substring. Examples: `ANamespace`, `AClass`,
+ `AClass::ANamespace`, `ANamespace::*Test`
+ <br>Note that the wildcards are matched against the file with absolute path,
+ so to exclude all test directories use the pattern
+ `*``/test/``*`
+
+ \anchor cfg_example_path
+<dt>\c EXAMPLE_PATH <dd>
+ \addindex EXAMPLE_PATH
+ The \c EXAMPLE_PATH tag can be used to specify one or more files or
+ directories that contain example code fragments that are included (see
+ the \ref cmdinclude "\\include" command).
+
+ \anchor cfg_example_patterns
+<dt>\c EXAMPLE_PATTERNS <dd>
+ \addindex EXAMPLE_PATTERNS
+ If the value of the \ref cfg_example_path "EXAMPLE_PATH" tag contains directories,
+ you can use the
+ \c EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like `*.cpp`
+ and `*.h`) to filter out the source-files in the directories. If left
+ blank all files are included.
+
+ \anchor cfg_example_recursive
+<dt>\c EXAMPLE_RECURSIVE <dd>
+ \addindex EXAMPLE_RECURSIVE
+ If the \c EXAMPLE_RECURSIVE tag is set to \c YES then subdirectories will be
+ searched for input files to be used with the \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude"
+ commands irrespective of the value of the \ref cfg_recursive "RECURSIVE" tag.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_image_path
+<dt>\c IMAGE_PATH <dd>
+ \addindex IMAGE_PATH
+ The \c IMAGE_PATH tag can be used to specify one or more files or
+ directories that contain images that are to be included in the
+ documentation (see the \ref cmdimage "\\image" command).
+
+ \anchor cfg_input_filter
+<dt>\c INPUT_FILTER <dd>
+ \addindex INPUT_FILTER
+ The \c INPUT_FILTER tag can be used to specify a program that doxygen should
+ invoke to filter for each input file. Doxygen will invoke the filter program
+ by executing (via <code>popen()</code>) the command:
+ <br>
+ <code>\<filter\> \<input-file\></code>
+ <br>
+ where <code>\<filter\></code>
+ is the value of the \c INPUT_FILTER tag, and <code>\<input-file\></code> is the name of an
+ input file. Doxygen will then use the output that the filter program writes
+ to standard output. If \ref cfg_filter_patterns "FILTER_PATTERNS" is specified, this tag will be ignored.
+ <br>Note that the filter must not add or remove lines; it is applied before the
+ code is scanned, but not when the output code is generated. If lines are added
+ or removed, the anchors will not be placed correctly.
+
+ \anchor cfg_filter_patterns
+<dt>\c FILTER_PATTERNS <dd>
+ \addindex FILTER_PATTERNS
+ The \c FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+ basis. Doxygen will compare the file name with each pattern and apply the
+ filter if there is a match. The filters are a list of the form:
+ pattern=filter (like `*.cpp=my_cpp_filter`). See \ref cfg_input_filter "INPUT_FILTER" for further
+ information on how filters are used. If the \c FILTER_PATTERNS tag is empty or if
+ none of the patterns match the file name, \ref cfg_input_filter "INPUT_FILTER" is
+ applied.
+
+ \anchor cfg_filter_source_files
+<dt>\c FILTER_SOURCE_FILES <dd>
+ \addindex FILTER_SOURCE_FILES
+ If the \c FILTER_SOURCE_FILES tag is set to \c YES, the input filter (if set using
+ \ref cfg_input_filter "INPUT_FILTER" ) will also be used to filter the input
+ files that are used for producing the source files to browse
+ (i.e. when \ref cfg_source_browser "SOURCE_BROWSER" is set to \c YES).
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_filter_source_patterns
+<dt>\c FILTER_SOURCE_PATTERNS <dd>
+ \addindex FILTER_SOURCE_PATTERNS
+ The \c FILTER_SOURCE_PATTERNS tag can be used to specify source filters per
+ file pattern. A pattern will override the setting
+ for \ref cfg_filter_patterns "FILTER_PATTERN" (if any)
+ and it is also possible to disable source filtering for a specific pattern
+ using `*.ext=` (so without naming a filter).
+
+
+This tag requires that the tag \ref cfg_filter_source_files "FILTER_SOURCE_FILES" is set to \c YES.
+ \anchor cfg_use_mdfile_as_mainpage
+<dt>\c USE_MDFILE_AS_MAINPAGE <dd>
+ \addindex USE_MDFILE_AS_MAINPAGE
+ If the \c USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+ is part of the input, its contents will be placed on the main page (`index.html`).
+ This can be useful if you have a project on for instance GitHub and want to reuse
+ the introduction page also for the doxygen output.
+
+</dl>
+\section config_source_browser Configuration options related to source browsing
+ \anchor cfg_source_browser
+<dl>
+
+<dt>\c SOURCE_BROWSER <dd>
+ \addindex SOURCE_BROWSER
+ If the \c SOURCE_BROWSER tag is set to \c YES then a list of source files will
+ be generated. Documented entities will be cross-referenced with these sources.
+ <br>Note: To get rid of all source code in the generated output, make sure that also
+ \ref cfg_verbatim_headers "VERBATIM_HEADERS" is set to \c NO.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_inline_sources
+<dt>\c INLINE_SOURCES <dd>
+ \addindex INLINE_SOURCES
+ Setting the \c INLINE_SOURCES tag to \c YES will include the body
+ of functions, classes and enums directly into the documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_strip_code_comments
+<dt>\c STRIP_CODE_COMMENTS <dd>
+ \addindex STRIP_CODE_COMMENTS
+ Setting the \c STRIP_CODE_COMMENTS tag to \c YES will instruct
+ doxygen to hide any special comment blocks from generated source code
+ fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_referenced_by_relation
+<dt>\c REFERENCED_BY_RELATION <dd>
+ \addindex REFERENCED_BY_RELATION
+ If the \c REFERENCED_BY_RELATION tag is set to \c YES
+ then for each documented function all documented
+ functions referencing it will be listed.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_references_relation
+<dt>\c REFERENCES_RELATION <dd>
+ \addindex REFERENCES_RELATION
+ If the \c REFERENCES_RELATION tag is set to \c YES
+ then for each documented function all documented entities
+ called/used by that function will be listed.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_references_link_source
+<dt>\c REFERENCES_LINK_SOURCE <dd>
+ \addindex REFERENCES_LINK_SOURCE
+ If the \c REFERENCES_LINK_SOURCE tag is set to \c YES
+ and \ref cfg_source_browser "SOURCE_BROWSER" tag is set to \c YES, then the hyperlinks from
+ functions in \ref cfg_references_relation "REFERENCES_RELATION" and
+ \ref cfg_referenced_by_relation "REFERENCED_BY_RELATION" lists will
+ link to the source code. Otherwise they will link to the documentation.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_source_tooltips
+<dt>\c SOURCE_TOOLTIPS <dd>
+ \addindex SOURCE_TOOLTIPS
+If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+source code will show a tooltip with additional information such as prototype,
+brief description and links to the definition and documentation. Since this will
+make the HTML file larger and loading of large files a bit slower, you can opt
+to disable this feature.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_source_browser "SOURCE_BROWSER" is set to \c YES.
+ \anchor cfg_use_htags
+<dt>\c USE_HTAGS <dd>
+ \addindex USE_HTAGS
+ If the \c USE_HTAGS tag is set to \c YES then the references to source code
+ will point to the HTML generated by the \c htags(1) tool instead of doxygen
+ built-in source browser. The \c htags tool is part of GNU's global source
+ tagging system (see http://www.gnu.org/software/global/global.html). You
+ will need version 4.8.6 or higher.
+<br>
+ To use it do the following:
+ -# Install the latest version of \c global
+ -# Enable \ref cfg_source_browser "SOURCE_BROWSER" and \c USE_HTAGS in the config file
+ -# Make sure the \ref cfg_input "INPUT" points to the root of the source tree
+ -# Run \c doxygen as normal
+<br>
+ Doxygen will invoke \c htags (and that will in turn invoke \c gtags), so these tools
+ must be available from the command line (i.e. in the search path).
+<br>
+ The result: instead of the source browser generated by doxygen, the links to
+ source code will now point to the output of \c htags.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_source_browser "SOURCE_BROWSER" is set to \c YES.
+ \anchor cfg_verbatim_headers
+<dt>\c VERBATIM_HEADERS <dd>
+ \addindex VERBATIM_HEADERS
+ If the \c VERBATIM_HEADERS tag is set the \c YES then doxygen
+ will generate a verbatim copy of the header file for each class for
+ which an include is specified. Set to \c NO to disable this.
+ \sa Section \ref cmdclass "\\class".
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_clang_assisted_parsing
+<dt>\c CLANG_ASSISTED_PARSING <dd>
+ \addindex CLANG_ASSISTED_PARSING
+ If the \c CLANG_ASSISTED_PARSING tag is set to \c YES, then doxygen will use the
+ <a href="http://clang.llvm.org/">clang parser</a> for more accurate parsing
+ at the cost of reduced performance. This can be particularly helpful with
+ template rich C++ code for which doxygen's built-in parser lacks the
+ necessary type information.
+
+ @note The availability of this option depends on whether or not doxygen
+ was compiled with the `--with-libclang` option.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_clang_options
+<dt>\c CLANG_OPTIONS <dd>
+ \addindex CLANG_OPTIONS
+ If clang assisted parsing is enabled you can provide the compiler with command
+ line options that you would normally use when invoking the compiler. Note that
+ the include paths will already be set by doxygen for the files and directories
+ specified with \ref cfg_input "INPUT" and \ref cfg_include_path "INCLUDE_PATH".
+
+
+This tag requires that the tag \ref cfg_clang_assisted_parsing "CLANG_ASSISTED_PARSING" is set to \c YES.
+</dl>
+\section config_index Configuration options related to the alphabetical class index
+ \anchor cfg_alphabetical_index
+<dl>
+
+<dt>\c ALPHABETICAL_INDEX <dd>
+ \addindex ALPHABETICAL_INDEX
+ If the \c ALPHABETICAL_INDEX tag is set to \c YES, an alphabetical index
+ of all compounds will be generated. Enable this if the project contains
+ a lot of classes, structs, unions or interfaces.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_cols_in_alpha_index
+<dt>\c COLS_IN_ALPHA_INDEX <dd>
+ \addindex COLS_IN_ALPHA_INDEX
+ The \c COLS_IN_ALPHA_INDEX tag can be
+ used to specify the number of columns in which the alphabetical index list will be split.
+
+
+ Minimum value: <code>1</code>, maximum value: <code>20</code>, default value: <code>5</code>.
+
+
+This tag requires that the tag \ref cfg_alphabetical_index "ALPHABETICAL_INDEX" is set to \c YES.
+ \anchor cfg_ignore_prefix
+<dt>\c IGNORE_PREFIX <dd>
+ \addindex IGNORE_PREFIX
+ In case all classes in a project start with a common prefix, all classes will
+ be put under the same header in the alphabetical index.
+ The \c IGNORE_PREFIX tag can be used to specify a prefix
+ (or a list of prefixes) that should be ignored while generating the index headers.
+
+
+This tag requires that the tag \ref cfg_alphabetical_index "ALPHABETICAL_INDEX" is set to \c YES.
+</dl>
+\section config_html Configuration options related to the HTML output
+ \anchor cfg_generate_html
+<dl>
+
+<dt>\c GENERATE_HTML <dd>
+ \addindex GENERATE_HTML
+ If the \c GENERATE_HTML tag is set to \c YES doxygen will
+ generate HTML output
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_html_output
+<dt>\c HTML_OUTPUT <dd>
+ \addindex HTML_OUTPUT
+ The \c HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+
+The default directory is: <code>html</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_file_extension
+<dt>\c HTML_FILE_EXTENSION <dd>
+ \addindex HTML_FILE_EXTENSION
+ The \c HTML_FILE_EXTENSION tag can be used to specify the file extension for
+ each generated HTML page (for example: <code>.htm, .php, .asp</code>).
+
+The default value is: <code>.html</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_header
+<dt>\c HTML_HEADER <dd>
+ \addindex HTML_HEADER
+ The \c HTML_HEADER tag can be used to specify a user-defined HTML
+ header file for each generated HTML page.
+ If the tag is left blank doxygen will generate a
+ standard header.
+<br>
+ To get valid HTML the header file that
+ includes any scripts and style sheets that doxygen
+ needs, which is dependent on the configuration options used (e.g. the
+ setting \ref cfg_generate_treeview "GENERATE_TREEVIEW").
+ It is highly recommended to start with a default header using
+\verbatim
+doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFile
+\endverbatim
+ and then modify the file \c new_header.html.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the default header that doxygen normally uses.
+
+ @note The header is subject to change so you typically
+ have to regenerate the default header when upgrading to a newer version of
+ doxygen. The following markers have a special meaning inside the header and footer:
+ <dl>
+ <dt><code>\$title</code><dd>will be replaced with the title of the page.
+ <dt><code>\$datetime</code><dd>will be replaced with current the date and time.
+ <dt><code>\$date</code><dd>will be replaced with the current date.
+ <dt><code>\$year</code><dd>will be replaces with the current year.
+ <dt><code>\$doxygenversion</code><dd>will be replaced with the version of doxygen
+ <dt><code>\$projectname</code><dd>will be replaced with the name of
+ the project (see \ref cfg_project_name "PROJECT_NAME")
+ <dt><code>\$projectnumber</code><dd>will be replaced with the project number
+ (see \ref cfg_project_number "PROJECT_NUMBER")
+ <dt><code>\$projectbrief</code><dd>will be replaced with the project brief
+ description (see \ref cfg_project_brief "PROJECT_BRIEF")
+ <dt><code>\$projectlogo</code><dd>will be replaced with the project logo
+ (see \ref cfg_project_logo "PROJECT_LOGO")
+ <dt><code>\$treeview</code><dd>will be replaced with links to
+ the javascript and style sheets needed for the navigation tree
+ (or an empty string when \ref cfg_generate_treeview "GENERATE_TREEVIEW"
+ is disabled).
+ <dt><code>\$search</code><dd>will be replaced with a links to
+ the javascript and style sheets needed for the search engine
+ (or an empty string when \ref cfg_searchengine "SEARCHENGINE"
+ is disabled).
+ <dt><code>\$mathjax</code><dd>will be replaced with a links to
+ the javascript and style sheets needed for the MathJax feature
+ (or an empty string when \ref cfg_use_mathjax "USE_MATHJAX" is disabled).
+ <dt><code>\$relpath^</code><dd>
+ If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command <code>\$relpath^</code> can be
+ used to produce a relative path to the root of the HTML output directory,
+ e.g. use <code>\$relpath^doxygen.css</code>, to refer to the standard style sheet.
+ </dl>
+
+ To cope with differences in the layout of the header and footer that depend on
+ configuration settings, the header can also contain special blocks that
+ will be copied to the output or skipped depending on the configuration.
+ Such blocks have the following form:
+\verbatim
+ <!--BEGIN BLOCKNAME-->
+ Some context copied when condition BLOCKNAME holds
+ <!--END BLOCKNAME-->
+ <!--BEGIN !BLOCKNAME-->
+ Some context copied when condition BLOCKNAME does not hold
+ <!--END !BLOCKNAME-->
+\endverbatim
+ The following block names are supported:
+ <dl>
+ <dt><code>DISABLE_INDEX</code><dd>Content within this block is copied to the output
+ when the \ref cfg_disable_index "DISABLE_INDEX" option is enabled (so when the index is disabled).
+ <dt><code>GENERATE_TREEVIEW</code><dd>Content within this block is copied to the output
+ when the \ref cfg_generate_treeview "GENERATE_TREEVIEW" option is enabled.
+ <dt><code>SEARCHENGINE</code><dd>Content within this block is copied to the output
+ when the \ref cfg_searchengine "SEARCHENGINE" option is enabled.
+ <dt><code>PROJECT_NAME</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_name "PROJECT_NAME" option is not empty.
+ <dt><code>PROJECT_NUMBER</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_number "PROJECT_NUMBER" option is not empty.
+ <dt><code>PROJECT_BRIEF</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_brief "PROJECT_BRIEF" option is not empty.
+ <dt><code>PROJECT_LOGO</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_logo "PROJECT_LOGO" option is not empty.
+ <dt><code>TITLEAREA</code><dd>Content within this block is copied to the output
+ when a title is visible at the top of each page. This is the case
+ if either \ref cfg_project_name "PROJECT_NAME",
+ \ref cfg_project_brief "PROJECT_BRIEF", \ref cfg_project_logo "PROJECT_LOGO"
+ is filled in or if both \ref cfg_disable_index "DISABLE_INDEX" and
+ \ref cfg_searchengine "SEARCHENGINE" are enabled.
+ </dl>
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_footer
+<dt>\c HTML_FOOTER <dd>
+ \addindex HTML_FOOTER
+ The \c HTML_FOOTER tag can be used to specify a user-defined HTML footer for
+ each generated HTML page.
+ If the tag is left blank doxygen will generate a standard footer.
+
+ See \ref cfg_html_header "HTML_HEADER" for more information on
+ how to generate a default footer and what special commands can be
+ used inside the footer.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the default footer that doxygen normally uses.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_stylesheet
+<dt>\c HTML_STYLESHEET <dd>
+ \addindex HTML_STYLESHEET
+ The \c HTML_STYLESHEET tag can be used to specify a user-defined cascading
+ style sheet that is used by each HTML page. It can be used to
+ fine-tune the look of the HTML output. If left blank doxygen
+ will generate a default style sheet.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the style sheet that doxygen normally uses.
+
+ \note It is recommended to use
+ \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" instead of this tag,
+ as it is more robust and
+ this tag (<code>HTML_STYLESHEET</code>) will in the future become obsolete.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_extra_stylesheet
+<dt>\c HTML_EXTRA_STYLESHEET <dd>
+ \addindex HTML_EXTRA_STYLESHEET
+ The \c HTML_EXTRA_STYLESHEET tag can be used to specify additional
+ user-defined cascading style sheets that are included after the standard
+ style sheets created by doxygen. Using this option one can overrule
+ certain style aspects. This is preferred over using \ref cfg_html_stylesheet "HTML_STYLESHEET"
+ since it does not replace the standard style sheet and is therefor more
+ robust against future updates. Doxygen will copy the style sheet files to
+ the output directory.
+ \note The order of the extra stylesheet files is of importance (e.g. the last
+ stylesheet in the list overrules the setting of the previous ones in the list). Here is an example stylesheet that gives the contents area a fixed width:
+\verbatim
+body {
+ background-color: #CCC;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-bottom: 10px;
+ padding: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 960px;
+ background-color: white;
+ border-radius: 8px;
+}
+
+#titlearea {
+ background-color: white;
+}
+
+hr.footer {
+ display: none;
+}
+
+.footer {
+ background-color: #AAA;
+}
+\endverbatim
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_extra_files
+<dt>\c HTML_EXTRA_FILES <dd>
+ \addindex HTML_EXTRA_FILES
+ The \c HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+ other source files which should be copied to the HTML output directory. Note
+ that these files will be copied to the base HTML output directory. Use the
+ <code>$relpath^</code> marker in the \ref cfg_html_header "HTML_HEADER" and/or
+ \ref cfg_html_footer "HTML_FOOTER" files to load these
+ files. In the \ref cfg_html_stylesheet "HTML_STYLESHEET" file, use the file name only. Also note that
+ the files will be copied as-is; there are no commands or markers available.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_colorstyle_hue
+<dt>\c HTML_COLORSTYLE_HUE <dd>
+ \addindex HTML_COLORSTYLE_HUE
+ The \c HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+ Doxygen will adjust the colors in the stylesheet and background images
+ according to this color. Hue is specified as an angle on a colorwheel,
+ see http://en.wikipedia.org/wiki/Hue for more information.
+ For instance the value 0 represents red, 60 is yellow, 120 is green,
+ 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>359</code>, default value: <code>220</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_colorstyle_sat
+<dt>\c HTML_COLORSTYLE_SAT <dd>
+ \addindex HTML_COLORSTYLE_SAT
+ The \c HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+ the colors in the HTML output. For a value of 0 the output will use
+ grayscales only. A value of 255 will produce the most vivid colors.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>255</code>, default value: <code>100</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_colorstyle_gamma
+<dt>\c HTML_COLORSTYLE_GAMMA <dd>
+ \addindex HTML_COLORSTYLE_GAMMA
+ The \c HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+ the luminance component of the colors in the HTML output. Values below
+ 100 gradually make the output lighter, whereas values above 100 make
+ the output darker. The value divided by 100 is the actual gamma applied,
+ so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+ and 100 does not change the gamma.
+
+
+ Minimum value: <code>40</code>, maximum value: <code>240</code>, default value: <code>80</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_timestamp
+<dt>\c HTML_TIMESTAMP <dd>
+ \addindex HTML_TIMESTAMP
+ If the \c HTML_TIMESTAMP tag is set to \c YES then the footer of
+ each generated HTML page will contain the date and time when the page
+ was generated. Setting this to \c NO can help when comparing the output of
+ multiple runs.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_dynamic_sections
+<dt>\c HTML_DYNAMIC_SECTIONS <dd>
+ \addindex HTML_DYNAMIC_SECTIONS
+ If the \c HTML_DYNAMIC_SECTIONS tag is set to \c YES then the generated HTML
+ documentation will contain sections that can be hidden and shown after the
+ page has loaded.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_html_index_num_entries
+<dt>\c HTML_INDEX_NUM_ENTRIES <dd>
+ \addindex HTML_INDEX_NUM_ENTRIES
+ With \c HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+ entries shown in the various tree structured indices initially; the user
+ can expand and collapse entries dynamically later on. Doxygen will expand
+ the tree to such a level that at most the specified number of entries are
+ visible (unless a fully collapsed tree already exceeds this amount).
+ So setting the number of entries 1 will produce a full collapsed tree by
+ default. 0 is a special value representing an infinite number of entries
+ and will result in a full expanded tree by default.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>9999</code>, default value: <code>100</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_generate_docset
+<dt>\c GENERATE_DOCSET <dd>
+ \addindex GENERATE_DOCSET
+ If the \c GENERATE_DOCSET tag is set to \c YES, additional index files
+ will be generated that can be used as input for
+ <a href="http://developer.apple.com/tools/xcode/">Apple's Xcode 3
+ integrated development environment</a>, introduced with OSX 10.5 (Leopard).
+ To create a documentation set, doxygen will generate a Makefile in the
+ HTML output directory. Running \c make will produce the docset in that
+ directory and running <code>make install</code> will install the docset in
+ <code>~/Library/Developer/Shared/Documentation/DocSets</code>
+ so that Xcode will find it at startup. See
+ http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for
+ more information.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_docset_feedname
+<dt>\c DOCSET_FEEDNAME <dd>
+ \addindex DOCSET_FEEDNAME
+ This tag determines the name of the docset
+ feed. A documentation feed provides an umbrella under which multiple
+ documentation sets from a single provider (such as a company or product suite)
+ can be grouped.
+
+The default value is: <code>Doxygen generated docs</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docset "GENERATE_DOCSET" is set to \c YES.
+ \anchor cfg_docset_bundle_id
+<dt>\c DOCSET_BUNDLE_ID <dd>
+ \addindex DOCSET_BUNDLE_ID
+ This tag specifies a string that
+ should uniquely identify the documentation set bundle. This should be a
+ reverse domain-name style string, e.g. <code>com.mycompany.MyDocSet</code>.
+ Doxygen will append <code>.docset</code> to the name.
+
+The default value is: <code>org.doxygen.Project</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docset "GENERATE_DOCSET" is set to \c YES.
+ \anchor cfg_docset_publisher_id
+<dt>\c DOCSET_PUBLISHER_ID <dd>
+ \addindex DOCSET_PUBLISHER_ID
+The \c DOCSET_PUBLISHER_ID
+tag specifies a string that should uniquely identify
+the documentation publisher. This should be a reverse domain-name style
+string, e.g. <code>com.mycompany.MyDocSet.documentation</code>.
+
+The default value is: <code>org.doxygen.Publisher</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docset "GENERATE_DOCSET" is set to \c YES.
+ \anchor cfg_docset_publisher_name
+<dt>\c DOCSET_PUBLISHER_NAME <dd>
+ \addindex DOCSET_PUBLISHER_NAME
+The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+
+The default value is: <code>Publisher</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docset "GENERATE_DOCSET" is set to \c YES.
+ \anchor cfg_generate_htmlhelp
+<dt>\c GENERATE_HTMLHELP <dd>
+ \addindex GENERATE_HTMLHELP
+ If the \c GENERATE_HTMLHELP tag is set to \c YES then
+ doxygen generates three additional HTML index files:
+ \c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a
+ project file that can be read by
+ <a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138">
+ Microsoft's HTML Help Workshop</a>
+ on Windows.
+<br>
+ The HTML Help Workshop contains a compiler that can convert all HTML output
+ generated by doxygen into a single compiled HTML file (`.chm`). Compiled
+ HTML files are now used as the Windows 98 help format, and will replace
+ the old Windows help format (`.hlp`) on all Windows platforms in the future.
+ Compressed HTML files also contain an index, a table of contents,
+ and you can search for words in the documentation.
+ The HTML workshop also contains a viewer for compressed HTML files.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_chm_file
+<dt>\c CHM_FILE <dd>
+ \addindex CHM_FILE
+ The \c CHM_FILE tag can
+ be used to specify the file name of the resulting `.chm` file. You
+ can add a path in front of the file if the result should not be
+ written to the html output directory.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_hhc_location
+<dt>\c HHC_LOCATION <dd>
+ \addindex HHC_LOCATION
+ The \c HHC_LOCATION tag can
+ be used to specify the location (absolute path including file name) of
+ the HTML help compiler (\c hhc.exe). If non-empty doxygen will try to run
+ the HTML help compiler on the generated \c index.hhp.
+
+The file has to be specified with full path.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_generate_chi
+<dt>\c GENERATE_CHI <dd>
+ \addindex GENERATE_CHI
+ The \c GENERATE_CHI flag
+ controls if a separate `.chi` index file is generated (\c YES) or that
+ it should be included in the master `.chm` file (\c NO).
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_chm_index_encoding
+<dt>\c CHM_INDEX_ENCODING <dd>
+ \addindex CHM_INDEX_ENCODING
+ The \c CHM_INDEX_ENCODING
+ is used to encode HtmlHelp index (\c hhk), content (\c hhc) and project file
+ content.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_binary_toc
+<dt>\c BINARY_TOC <dd>
+ \addindex BINARY_TOC
+ The \c BINARY_TOC flag
+ controls whether a binary table of contents is generated (\c YES) or a
+ normal table of contents (\c NO) in the `.chm` file. Furthermore it enables
+ the `Previous` and `Next` buttons.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_toc_expand
+<dt>\c TOC_EXPAND <dd>
+ \addindex TOC_EXPAND
+ The \c TOC_EXPAND flag can be set to \c YES to add extra items for
+ group members to the table of contents of the HTML help documentation
+ and to the tree view.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+ \anchor cfg_generate_qhp
+<dt>\c GENERATE_QHP <dd>
+ \addindex GENERATE_QHP
+ If the \c GENERATE_QHP tag is set to \c YES and both \ref cfg_qhp_namespace "QHP_NAMESPACE"
+ and \ref cfg_qhp_virtual_folder "QHP_VIRTUAL_FOLDER" are set, an additional index file will
+ be generated that can be used as input for Qt's qhelpgenerator
+ to generate a Qt Compressed Help (`.qch`) of the generated HTML
+ documentation.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_qch_file
+<dt>\c QCH_FILE <dd>
+ \addindex QCH_FILE
+ If the \ref cfg_qhg_location "QHG_LOCATION" tag is specified, the \c QCH_FILE tag can
+ be used to specify the file name of the resulting `.qch` file.
+ The path specified is relative to the HTML output folder.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhp_namespace
+<dt>\c QHP_NAMESPACE <dd>
+ \addindex QHP_NAMESPACE
+ The \c QHP_NAMESPACE tag specifies the namespace to use when generating
+ Qt Help Project output. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
+
+The default value is: <code>org.doxygen.Project</code>.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhp_virtual_folder
+<dt>\c QHP_VIRTUAL_FOLDER <dd>
+ \addindex QHP_VIRTUAL_FOLDER
+ The \c QHP_VIRTUAL_FOLDER tag specifies the namespace to use when
+ generating Qt Help Project output. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
+
+The default value is: <code>doc</code>.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhp_cust_filter_name
+<dt>\c QHP_CUST_FILTER_NAME <dd>
+ \addindex QHP_CUST_FILTER_NAME
+ If the \c QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom filter to add. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhp_cust_filter_attrs
+<dt>\c QHP_CUST_FILTER_ATTRS <dd>
+ \addindex QHP_CUST_FILTER_ATTRS
+ The \c QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the custom filter to add.
+ For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhp_sect_filter_attrs
+<dt>\c QHP_SECT_FILTER_ATTRS <dd>
+ \addindex QHP_SECT_FILTER_ATTRS
+ The \c QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's filter section matches.
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_qhg_location
+<dt>\c QHG_LOCATION <dd>
+ \addindex QHG_LOCATION
+ The \c QHG_LOCATION tag can be used to specify the location of Qt's qhelpgenerator.
+ If non-empty doxygen will try to run qhelpgenerator on the generated `.qhp` file.
+
+
+This tag requires that the tag \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+ \anchor cfg_generate_eclipsehelp
+<dt>\c GENERATE_ECLIPSEHELP <dd>
+ \addindex GENERATE_ECLIPSEHELP
+ If the \c GENERATE_ECLIPSEHELP tag is set to \c YES, additional index files
+ will be generated, together with the HTML files, they form an `Eclipse` help
+ plugin.
+
+ To install this plugin and make it available under the help contents
+ menu in `Eclipse`, the contents of the directory containing the HTML and XML
+ files needs to be copied into the plugins directory of eclipse. The name of
+ the directory within the plugins directory should be the same as
+ the \ref cfg_eclipse_doc_id "ECLIPSE_DOC_ID" value.
+
+ After copying `Eclipse` needs to be restarted before the help appears.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_eclipse_doc_id
+<dt>\c ECLIPSE_DOC_ID <dd>
+ \addindex ECLIPSE_DOC_ID
+ A unique identifier for the `Eclipse` help plugin. When installing the plugin
+ the directory name containing the HTML and XML files should also have
+ this name. Each documentation set should have its own identifier.
+
+The default value is: <code>org.doxygen.Project</code>.
+
+
+This tag requires that the tag \ref cfg_generate_eclipsehelp "GENERATE_ECLIPSEHELP" is set to \c YES.
+ \anchor cfg_disable_index
+<dt>\c DISABLE_INDEX <dd>
+ \addindex DISABLE_INDEX
+ If you want full control over the layout of the generated HTML pages it
+ might be necessary to disable the index and replace it with your own.
+ The \c DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at
+ top of each HTML page. A value of \c NO enables the index and the
+ value \c YES disables it. Since the tabs in the index contain the same
+ information as the navigation tree, you can set this option to \c YES if
+ you also set \ref cfg_generate_treeview "GENERATE_TREEVIEW" to \c YES.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_generate_treeview
+<dt>\c GENERATE_TREEVIEW <dd>
+ \addindex GENERATE_TREEVIEW
+ The \c GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+ structure should be generated to display hierarchical information.
+ If the tag value is set to \c YES, a side panel will be generated
+ containing a tree-like index structure (just like the one that
+ is generated for HTML Help). For this to work a browser that supports
+ JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+ Windows users are probably better off using the HTML help feature.
+
+ Via custom stylesheets (see \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET")
+ one can further \ref doxygen_finetune "fine-tune" the look of the index.
+ As an example, the default style sheet generated by doxygen has an
+ example that shows how to put an image at the root of the tree instead of
+ the \ref cfg_project_name "PROJECT_NAME".
+
+ Since the tree basically has the same information as the tab index, you could
+ consider setting \ref cfg_disable_index "DISABLE_INDEX" to \c YES when
+ enabling this option.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_enum_values_per_line
+<dt>\c ENUM_VALUES_PER_LINE <dd>
+ \addindex ENUM_VALUES_PER_LINE
+ The \c ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+ that doxygen will group on one line in the generated HTML documentation.
+ <br>Note that a value of 0 will completely suppress the enum values from
+ appearing in the overview section.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>20</code>, default value: <code>4</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_treeview_width
+<dt>\c TREEVIEW_WIDTH <dd>
+ \addindex TREEVIEW_WIDTH
+ If the treeview is enabled (see \ref cfg_generate_treeview "GENERATE_TREEVIEW") then this tag can be
+ used to set the initial width (in pixels) of the frame in which the tree
+ is shown.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>1500</code>, default value: <code>250</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_ext_links_in_window
+<dt>\c EXT_LINKS_IN_WINDOW <dd>
+ \addindex EXT_LINKS_IN_WINDOW
+ When the \c EXT_LINKS_IN_WINDOW option is set to \c YES doxygen will open
+ links to external symbols imported via tag files in a separate window.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_formula_fontsize
+<dt>\c FORMULA_FONTSIZE <dd>
+ \addindex FORMULA_FONTSIZE
+ Use this tag to change the font size of \f$\mbox{\LaTeX}\f$ formulas included
+ as images in the HTML documentation.
+ When you change the font size after a successful doxygen run you need
+ to manually remove any `form_*.png` images from the HTML
+ output directory to force them to be regenerated.
+
+
+ Minimum value: <code>8</code>, maximum value: <code>50</code>, default value: <code>10</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_formula_transparent
+<dt>\c FORMULA_TRANSPARENT <dd>
+ \addindex FORMULA_TRANSPARENT
+ Use the \c FORMULA_TRANPARENT tag to determine whether or not the images
+ generated for formulas are transparent PNGs. Transparent PNGs are
+ not supported properly for IE 6.0, but are supported on all modern browsers.
+ <br>Note that when changing this option you need to delete any `form_*.png` files
+ in the HTML output directory before the changes have effect.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_use_mathjax
+<dt>\c USE_MATHJAX <dd>
+ \addindex USE_MATHJAX
+ Enable the \c USE_MATHJAX option to render \f$\mbox{\LaTeX}\f$ formulas using MathJax
+ (see http://www.mathjax.org) which uses client side Javascript for the
+ rendering instead of using prerendered bitmaps. Use this if you do not
+ have \f$\mbox{\LaTeX}\f$ installed or if you want to formulas look prettier in the HTML
+ output. When enabled you may also need to install MathJax separately and
+ configure the path to it using the \ref cfg_mathjax_relpath "MATHJAX_RELPATH"
+ option.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_mathjax_format
+<dt>\c MATHJAX_FORMAT <dd>
+ \addindex MATHJAX_FORMAT
+ When MathJax is enabled you can set the default output format to be used for
+ the MathJax output.
+ See <a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a>
+ for more details.
+
+Possible values are:
+<code>HTML-CSS</code> (which is slower, but has the best compatibility),
+<code>NativeMML</code> (i.e. MathML) and
+<code>SVG</code>.
+
+
+The default value is: <code>HTML-CSS</code>.
+
+
+This tag requires that the tag \ref cfg_use_mathjax "USE_MATHJAX" is set to \c YES.
+ \anchor cfg_mathjax_relpath
+<dt>\c MATHJAX_RELPATH <dd>
+ \addindex MATHJAX_RELPATH
+ When MathJax is enabled you need to specify the location relative to the
+ HTML output directory using the \c MATHJAX_RELPATH option. The destination
+ directory should contain the `MathJax.js` script. For instance, if the \c mathjax
+ directory is located at the same level as the HTML output directory, then
+ \c MATHJAX_RELPATH should be <code>../mathjax</code>. The default value points to
+ the MathJax Content Delivery Network so you can quickly see the result without
+ installing MathJax. However, it is strongly recommended to install a local
+ copy of MathJax from http://www.mathjax.org before deployment.
+
+The default value is: <code>http://cdn.mathjax.org/mathjax/latest</code>.
+
+
+This tag requires that the tag \ref cfg_use_mathjax "USE_MATHJAX" is set to \c YES.
+ \anchor cfg_mathjax_extensions
+<dt>\c MATHJAX_EXTENSIONS <dd>
+ \addindex MATHJAX_EXTENSIONS
+ The \c MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax extension
+ names that should be enabled during MathJax rendering. For example
+\verbatim
+MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+\endverbatim
+
+
+This tag requires that the tag \ref cfg_use_mathjax "USE_MATHJAX" is set to \c YES.
+ \anchor cfg_mathjax_codefile
+<dt>\c MATHJAX_CODEFILE <dd>
+ \addindex MATHJAX_CODEFILE
+ The \c MATHJAX_CODEFILE tag can be used to specify a file with javascript
+ pieces of code that will be used on startup of the MathJax code.
+ See
+<a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a>
+ for more details. As an example to disable the "Math Renderer" menu item in the "Math
+ Settings" menu of MathJax:
+\verbatim
+MATHJAX_CODEFILE = disableRenderer.js
+\endverbatim
+ with in the file <code>disableRenderer.js</code>:
+\verbatim
+ MathJax.Hub.Config({
+ menuSettings: {
+ showRenderer: false,
+ }
+ });
+\endverbatim
+
+
+This tag requires that the tag \ref cfg_use_mathjax "USE_MATHJAX" is set to \c YES.
+ \anchor cfg_searchengine
+<dt>\c SEARCHENGINE <dd>
+ \addindex SEARCHENGINE
+ When the \c SEARCHENGINE tag is enabled doxygen will generate a search box
+ for the HTML output. The underlying search engine uses javascript
+ and DHTML and should work on any modern browser. Note that when using
+ HTML help (\ref cfg_generate_htmlhelp "GENERATE_HTMLHELP"),
+ Qt help (\ref cfg_generate_qhp "GENERATE_QHP"), or docsets
+ (\ref cfg_generate_docset "GENERATE_DOCSET") there is already a search
+ function so this one should typically be disabled. For large projects
+ the javascript based search engine can be slow, then enabling
+ \ref cfg_server_based_search "SERVER_BASED_SEARCH" may provide a
+ better solution.
+
+ It is possible to search using the keyboard;
+ to jump to the search box use <code>\<access key\> + S</code> (what the <code>\<access key\></code> is
+ depends on the OS and browser, but it is typically <code>\<CTRL\></code>, <code>\<ALT\></code>/<code>\<option\></code>, or both).
+ Inside the search box use the <code>\<cursor down key\></code> to jump into the search
+ results window, the results can be navigated using the <code>\<cursor keys\></code>.
+ Press <code>\<Enter\></code> to select an item or <code>\<escape\></code> to cancel the search. The
+ filter options can be selected when the cursor is inside the search box
+ by pressing <code>\<Shift\>+\<cursor down\></code>. Also here use the <code>\<cursor keys\></code> to
+ select a filter and <code>\<Enter\></code> or <code>\<escape\></code> to activate or cancel the filter option.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_html "GENERATE_HTML" is set to \c YES.
+ \anchor cfg_server_based_search
+<dt>\c SERVER_BASED_SEARCH <dd>
+ \addindex SERVER_BASED_SEARCH
+When the \c SERVER_BASED_SEARCH tag is enabled the search engine will be
+implemented using a web server instead of a web client using Javascript.
+
+There are two flavors of web server based searching depending on the
+\ref cfg_external_search "EXTERNAL_SEARCH" setting. When disabled,
+doxygen will generate a PHP script for searching and an index file used
+by the script. When \ref cfg_external_search "EXTERNAL_SEARCH" is
+enabled the indexing and searching needs to be provided by external tools.
+See the section \ref extsearch for details.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+ \anchor cfg_external_search
+<dt>\c EXTERNAL_SEARCH <dd>
+ \addindex EXTERNAL_SEARCH
+ When \c EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+ script for searching. Instead the search results are written to an XML file
+ which needs to be processed by an external indexer. Doxygen will invoke an
+ external search engine pointed to by the
+ \ref cfg_searchengine_url "SEARCHENGINE_URL" option to obtain
+ the search results.
+ <br>Doxygen ships with an example indexer (\c doxyindexer) and
+ search engine (<code>doxysearch.cgi</code>) which are based on the open source search
+ engine library <a href="http://xapian.org/">Xapian</a>.
+ <br>See the section \ref extsearch for details.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+ \anchor cfg_searchengine_url
+<dt>\c SEARCHENGINE_URL <dd>
+ \addindex SEARCHENGINE_URL
+ The \c SEARCHENGINE_URL should point to a search engine hosted by a web server
+ which will return the search results when \ref cfg_external_search "EXTERNAL_SEARCH"
+ is enabled.
+ <br>Doxygen ships with an example indexer (\c doxyindexer) and
+ search engine (<code>doxysearch.cgi</code>) which are based on the open source search
+ engine library <a href="http://xapian.org/">Xapian</a>.
+ See the section \ref extsearch for details.
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+ \anchor cfg_searchdata_file
+<dt>\c SEARCHDATA_FILE <dd>
+ \addindex SEARCHDATA_FILE
+When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and
+\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the unindexed
+search data is written to a file for indexing by an external tool. With the
+\c SEARCHDATA_FILE tag the name of this file can be specified.
+
+The default file is: <code>searchdata.xml</code>.
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+ \anchor cfg_external_search_id
+<dt>\c EXTERNAL_SEARCH_ID <dd>
+ \addindex EXTERNAL_SEARCH_ID
+When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and
+\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the
+\c EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+useful in combination with \ref cfg_extra_search_mappings "EXTRA_SEARCH_MAPPINGS"
+to search through multiple projects and redirect the results back to the right project.
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+ \anchor cfg_extra_search_mappings
+<dt>\c EXTRA_SEARCH_MAPPINGS <dd>
+ \addindex EXTRA_SEARCH_MAPPINGS
+ The \c EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+ projects other than the one defined by this configuration file, but that are
+ all added to the same external search index. Each project needs to have a
+ unique id set via \ref cfg_external_search_id "EXTERNAL_SEARCH_ID".
+ The search mapping then maps the id of to a relative location where the
+ documentation can be found.
+
+ The format is:
+\verbatim
+EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+\endverbatim
+
+
+This tag requires that the tag \ref cfg_searchengine "SEARCHENGINE" is set to \c YES.
+</dl>
+\section config_latex Configuration options related to the LaTeX output
+ \anchor cfg_generate_latex
+<dl>
+
+<dt>\c GENERATE_LATEX <dd>
+ \addindex GENERATE_LATEX
+ If the \c GENERATE_LATEX tag is set to \c YES doxygen will
+ generate \f$\mbox{\LaTeX}\f$ output.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_latex_output
+<dt>\c LATEX_OUTPUT <dd>
+ \addindex LATEX_OUTPUT
+ The \c LATEX_OUTPUT tag is used to specify where the \f$\mbox{\LaTeX}\f$
+ docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+
+The default directory is: <code>latex</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_cmd_name
+<dt>\c LATEX_CMD_NAME <dd>
+ \addindex LATEX_CMD_NAME
+ The \c LATEX_CMD_NAME tag can be used to specify the \f$\mbox{\LaTeX}\f$ command name to be invoked.
+ <br>Note that when enabling \ref cfg_use_pdflatex "USE_PDFLATEX" this option is only used for
+ generating bitmaps for formulas in the HTML output, but not in the
+ \c Makefile that is written to the output directory.
+
+The default file is: <code>latex</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_makeindex_cmd_name
+<dt>\c MAKEINDEX_CMD_NAME <dd>
+ \addindex MAKEINDEX_CMD_NAME
+ The \c MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+ generate index for \f$\mbox{\LaTeX}\f$.
+
+The default file is: <code>makeindex</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_compact_latex
+<dt>\c COMPACT_LATEX <dd>
+ \addindex COMPACT_LATEX
+ If the \c COMPACT_LATEX tag is set to \c YES doxygen generates more compact
+ \f$\mbox{\LaTeX}\f$ documents. This may be useful for small projects and may help to
+ save some trees in general.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_paper_type
+<dt>\c PAPER_TYPE <dd>
+ \addindex PAPER_TYPE
+ The \c PAPER_TYPE tag can be used to set the paper type that is used
+ by the printer.
+
+Possible values are:
+<code>a4</code> (210 x 297 mm),
+<code>letter</code> (8.5 x 11 inches),
+<code>legal</code> (8.5 x 14 inches) and
+<code>executive</code> (7.25 x 10.5 inches).
+
+
+The default value is: <code>a4</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_extra_packages
+<dt>\c EXTRA_PACKAGES <dd>
+ \addindex EXTRA_PACKAGES
+ The \c EXTRA_PACKAGES tag can be used to specify one or more \f$\mbox{\LaTeX}\f$
+ package names that should be included in the \f$\mbox{\LaTeX}\f$ output.
+ To get the times font for instance you can specify
+\verbatim
+EXTRA_PACKAGES=times
+\endverbatim
+ If left blank no extra packages will be included.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_header
+<dt>\c LATEX_HEADER <dd>
+ \addindex LATEX_HEADER
+ The \c LATEX_HEADER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$
+ header for the generated \f$\mbox{\LaTeX}\f$ document.
+ The header should contain everything until the first chapter.
+
+ If it is left blank doxygen will generate a
+ standard header. See section \ref doxygen_usage for information on how to
+ let doxygen write the default header to a separate file.
+
+ <br>Note: Only use a user-defined header if you know what you are doing!
+
+ The following commands have a special meaning inside the header:
+ <code>\$title</code>, <code>\$datetime</code>, <code>\$date</code>,
+ <code>\$doxygenversion</code>, <code>\$projectname</code>,
+ <code>\$projectnumber</code>, <code>\$projectbrief</code>,
+ <code>\$projectlogo</code>.
+ Doxygen will replace <code>\$title</code> with the empy string, for the replacement values of the
+ other commands the user is refered to \ref cfg_html_header "HTML_HEADER".
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_footer
+<dt>\c LATEX_FOOTER <dd>
+ \addindex LATEX_FOOTER
+ The \c LATEX_FOOTER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ footer for
+ the generated \f$\mbox{\LaTeX}\f$ document. The footer should contain everything after
+ the last chapter. If it is left blank doxygen will generate a
+ standard footer.
+ See \ref cfg_latex_header "LATEX_HEADER" for more information on
+ how to generate a default footer and what special commands can be
+ used inside the footer.
+
+ <br>Note: Only use a user-defined footer if you know what you are doing!
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_extra_files
+<dt>\c LATEX_EXTRA_FILES <dd>
+ \addindex LATEX_EXTRA_FILES
+ The \c LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+ or other source files which should be copied to the \ref cfg_latex_output "LATEX_OUTPUT"
+ output directory.
+ Note that the files will be copied as-is; there are no commands or markers
+ available.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_pdf_hyperlinks
+<dt>\c PDF_HYPERLINKS <dd>
+ \addindex PDF_HYPERLINKS
+ If the \c PDF_HYPERLINKS tag is set to \c YES, the \f$\mbox{\LaTeX}\f$ that
+ is generated is prepared for conversion to PDF (using \c ps2pdf or \c pdflatex).
+ The PDF file will
+ contain links (just like the HTML output) instead of page references.
+ This makes the output suitable for online browsing using a PDF viewer.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_use_pdflatex
+<dt>\c USE_PDFLATEX <dd>
+ \addindex USE_PDFLATEX
+ If the \c USE_PDFLATEX tag is set to \c YES, doxygen will use
+ \c pdflatex to generate the PDF file directly from the \f$\mbox{\LaTeX}\f$
+ files. Set this option to \c YES to get a higher quality PDF documentation.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_batchmode
+<dt>\c LATEX_BATCHMODE <dd>
+ \addindex LATEX_BATCHMODE
+ If the \c LATEX_BATCHMODE tag is set to \c YES, doxygen will add the \c \\batchmode
+ command to the generated \f$\mbox{\LaTeX}\f$ files. This will
+ instruct \f$\mbox{\LaTeX}\f$ to keep running if errors occur, instead of
+ asking the user for help. This option is also used when generating formulas
+ in HTML.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_hide_indices
+<dt>\c LATEX_HIDE_INDICES <dd>
+ \addindex LATEX_HIDE_INDICES
+ If the \c LATEX_HIDE_INDICES tag is set to \c YES then doxygen will not
+ include the index chapters (such as File Index, Compound Index, etc.)
+ in the output.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_source_code
+<dt>\c LATEX_SOURCE_CODE <dd>
+ \addindex LATEX_SOURCE_CODE
+ If the \c LATEX_SOURCE_CODE tag is set to \c YES then doxygen will include
+ source code with syntax highlighting in the \f$\mbox{\LaTeX}\f$ output.
+ <br>Note that which sources are shown also depends on other settings
+ such as \ref cfg_source_browser "SOURCE_BROWSER".
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+ \anchor cfg_latex_bib_style
+<dt>\c LATEX_BIB_STYLE <dd>
+ \addindex LATEX_BIB_STYLE
+ The \c LATEX_BIB_STYLE tag can be used to specify the style to use for the
+ bibliography, e.g. \c plainnat, or \c ieeetr.
+ See http://en.wikipedia.org/wiki/BibTeX and \ref cmdcite "\\cite"
+ for more info.
+
+The default value is: <code>plain</code>.
+
+
+This tag requires that the tag \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES.
+</dl>
+\section config_rtf Configuration options related to the RTF output
+ \anchor cfg_generate_rtf
+<dl>
+
+<dt>\c GENERATE_RTF <dd>
+ \addindex GENERATE_RTF
+ If the \c GENERATE_RTF tag is set to \c YES doxygen will generate RTF output.
+ The RTF output is optimized for Word 97 and may not look too pretty with
+ other RTF readers/editors.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_rtf_output
+<dt>\c RTF_OUTPUT <dd>
+ \addindex RTF_OUTPUT
+ The \c RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+
+The default directory is: <code>rtf</code>.
+
+
+This tag requires that the tag \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES.
+ \anchor cfg_compact_rtf
+<dt>\c COMPACT_RTF <dd>
+ \addindex COMPACT_RTF
+ If the \c COMPACT_RTF tag is set to \c YES doxygen generates more compact
+ RTF documents. This may be useful for small projects and may help to
+ save some trees in general.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES.
+ \anchor cfg_rtf_hyperlinks
+<dt>\c RTF_HYPERLINKS <dd>
+ \addindex RTF_HYPERLINKS
+ If the \c RTF_HYPERLINKS tag is set to \c YES, the RTF that is generated
+ will contain hyperlink fields. The RTF file will
+ contain links (just like the HTML output) instead of page references.
+ This makes the output suitable for online browsing using Word or some other
+ Word compatible readers that support those fields.
+
+ <br>Note: WordPad (write) and others do not support links.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES.
+ \anchor cfg_rtf_stylesheet_file
+<dt>\c RTF_STYLESHEET_FILE <dd>
+ \addindex RTF_STYLESHEET_FILE
+ Load stylesheet definitions from file. Syntax is similar to doxygen's
+ config file, i.e. a series of assignments. You only have to provide
+ replacements, missing definitions are set to their default value.
+<br>
+ See also section \ref doxygen_usage for information on how to generate
+ the default style sheet that doxygen normally uses.
+
+
+This tag requires that the tag \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES.
+ \anchor cfg_rtf_extensions_file
+<dt>\c RTF_EXTENSIONS_FILE <dd>
+ \addindex RTF_EXTENSIONS_FILE
+ Set optional variables used in the generation of an RTF document.
+ Syntax is similar to doxygen's config file.
+ A template extensions file can be generated using
+ <code>doxygen -e rtf extensionFile</code>.
+
+
+This tag requires that the tag \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES.
+</dl>
+\section config_man Configuration options related to the man page output
+ \anchor cfg_generate_man
+<dl>
+
+<dt>\c GENERATE_MAN <dd>
+ \addindex GENERATE_MAN
+ If the \c GENERATE_MAN tag is set to \c YES doxygen will
+ generate man pages for classes and files.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_man_output
+<dt>\c MAN_OUTPUT <dd>
+ \addindex MAN_OUTPUT
+ The \c MAN_OUTPUT tag is used to specify where the man pages will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+ A directory \c man3 will be created inside the directory specified by
+ \c MAN_OUTPUT.
+
+The default directory is: <code>man</code>.
+
+
+This tag requires that the tag \ref cfg_generate_man "GENERATE_MAN" is set to \c YES.
+ \anchor cfg_man_extension
+<dt>\c MAN_EXTENSION <dd>
+ \addindex MAN_EXTENSION
+ The \c MAN_EXTENSION tag determines the extension that is added to
+ the generated man pages. In case
+ the manual section does not start with a number, the number 3 is prepended.
+ The dot (.) at the beginning of the \c MAN_EXTENSION tag is optional.
+
+The default value is: <code>.3</code>.
+
+
+This tag requires that the tag \ref cfg_generate_man "GENERATE_MAN" is set to \c YES.
+ \anchor cfg_man_subdir
+<dt>\c MAN_SUBDIR <dd>
+ \addindex MAN_SUBDIR
+ The \c MAN_SUBDIR tag determines the name of the directory created within \c MAN_OUTPUT
+ in which the man pages are placed. If defaults to man followed by \c MAN_EXTENSION
+ with the initial . removed.
+
+
+This tag requires that the tag \ref cfg_generate_man "GENERATE_MAN" is set to \c YES.
+ \anchor cfg_man_links
+<dt>\c MAN_LINKS <dd>
+ \addindex MAN_LINKS
+ If the \c MAN_LINKS tag is set to \c YES and doxygen generates man output,
+ then it will generate one additional man file for each entity documented in
+ the real man page(s). These additional files only source the real man page,
+ but without them the \c man command would be unable to find the correct page.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_man "GENERATE_MAN" is set to \c YES.
+</dl>
+\section config_xml Configuration options related to the XML output
+ \anchor cfg_generate_xml
+<dl>
+
+<dt>\c GENERATE_XML <dd>
+ \addindex GENERATE_XML
+ If the \c GENERATE_XML tag is set to \c YES doxygen will
+ generate an XML file that captures the structure of
+ the code including all documentation.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_xml_output
+<dt>\c XML_OUTPUT <dd>
+ \addindex XML_OUTPUT
+ The \c XML_OUTPUT tag is used to specify where the XML pages will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+
+The default directory is: <code>xml</code>.
+
+
+This tag requires that the tag \ref cfg_generate_xml "GENERATE_XML" is set to \c YES.
+ \anchor cfg_xml_programlisting
+<dt>\c XML_PROGRAMLISTING <dd>
+ \addindex XML_PROGRAMLISTING
+ If the \c XML_PROGRAMLISTING tag is set to \c YES doxygen will
+ dump the program listings (including syntax highlighting
+ and cross-referencing information) to the XML output. Note that
+ enabling this will significantly increase the size of the XML output.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_xml "GENERATE_XML" is set to \c YES.
+</dl>
+\section config_docbook Configuration options related to the DOCBOOK output
+ \anchor cfg_generate_docbook
+<dl>
+
+<dt>\c GENERATE_DOCBOOK <dd>
+ \addindex GENERATE_DOCBOOK
+If the \c GENERATE_DOCBOOK tag is set to \c YES doxygen will generate Docbook files
+that can be used to generate PDF.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_docbook_output
+<dt>\c DOCBOOK_OUTPUT <dd>
+ \addindex DOCBOOK_OUTPUT
+The \c DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in
+front of it.
+
+The default directory is: <code>docbook</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docbook "GENERATE_DOCBOOK" is set to \c YES.
+ \anchor cfg_docbook_programlisting
+<dt>\c DOCBOOK_PROGRAMLISTING <dd>
+ \addindex DOCBOOK_PROGRAMLISTING
+ If the \c DOCBOOK_PROGRAMLISTING tag is set to \c YES doxygen will
+ include the program listings (including syntax highlighting
+ and cross-referencing information) to the DOCBOOK output. Note that
+ enabling this will significantly increase the size of the DOCBOOK output.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_docbook "GENERATE_DOCBOOK" is set to \c YES.
+</dl>
+\section config_autogen Configuration options for the AutoGen Definitions output
+ \anchor cfg_generate_autogen_def
+<dl>
+
+<dt>\c GENERATE_AUTOGEN_DEF <dd>
+ \addindex GENERATE_AUTOGEN_DEF
+ If the \c GENERATE_AUTOGEN_DEF tag is set to \c YES doxygen will
+ generate an AutoGen Definitions (see http://autogen.sf.net) file
+ that captures the structure of the code including all
+ documentation. Note that this feature is still experimental
+ and incomplete at the moment.
+
+
+The default value is: <code>NO</code>.
+
+</dl>
+\section config_perlmod Configuration options related to the Perl module output
+ \anchor cfg_generate_perlmod
+<dl>
+
+<dt>\c GENERATE_PERLMOD <dd>
+ \addindex GENERATE_PERLMOD
+ If the \c GENERATE_PERLMOD tag is set to \c YES doxygen will
+ generate a Perl module file that captures the structure of
+ the code including all documentation.
+ <br>Note that this
+ feature is still experimental and incomplete at the
+ moment.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_perlmod_latex
+<dt>\c PERLMOD_LATEX <dd>
+ \addindex PERLMOD_LATEX
+ If the \c PERLMOD_LATEX tag is set to \c YES doxygen will generate
+ the necessary \c Makefile rules, \c Perl scripts and \f$\mbox{\LaTeX}\f$ code to be able
+ to generate PDF and DVI output from the Perl module output.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_generate_perlmod "GENERATE_PERLMOD" is set to \c YES.
+ \anchor cfg_perlmod_pretty
+<dt>\c PERLMOD_PRETTY <dd>
+ \addindex PERLMOD_PRETTY
+ If the \c PERLMOD_PRETTY tag is set to \c YES the Perl module output will be
+ nicely formatted so it can be parsed by a human reader. This is useful
+ if you want to understand what is going on. On the other hand, if this
+ tag is set to \c NO the size of the Perl module output will be much smaller
+ and Perl will parse it just the same.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_generate_perlmod "GENERATE_PERLMOD" is set to \c YES.
+ \anchor cfg_perlmod_makevar_prefix
+<dt>\c PERLMOD_MAKEVAR_PREFIX <dd>
+ \addindex PERLMOD_MAKEVAR_PREFIX
+ The names of the make variables in the generated `doxyrules.make` file
+ are prefixed with the string contained in \c PERLMOD_MAKEVAR_PREFIX.
+ This is useful so different `doxyrules.make` files included by the same
+ `Makefile` don't overwrite each other's variables.
+
+
+This tag requires that the tag \ref cfg_generate_perlmod "GENERATE_PERLMOD" is set to \c YES.
+</dl>
+\section config_preprocessor Configuration options related to the preprocessor
+ \anchor cfg_enable_preprocessing
+<dl>
+
+<dt>\c ENABLE_PREPROCESSING <dd>
+ \addindex ENABLE_PREPROCESSING
+ If the \c ENABLE_PREPROCESSING tag is set to \c YES doxygen will
+ evaluate all C-preprocessor directives found in the sources and include
+ files.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_macro_expansion
+<dt>\c MACRO_EXPANSION <dd>
+ \addindex MACRO_EXPANSION
+ If the \c MACRO_EXPANSION tag is set to \c YES doxygen will expand all macro
+ names in the source code. If set to \c NO only conditional
+ compilation will be performed. Macro expansion can be done in a controlled
+ way by setting \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" to \c YES.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_expand_only_predef
+<dt>\c EXPAND_ONLY_PREDEF <dd>
+ \addindex EXPAND_ONLY_PREDEF
+ If the \c EXPAND_ONLY_PREDEF and \ref cfg_macro_expansion "MACRO_EXPANSION" tags are both set to \c YES
+ then the macro expansion is limited to the macros specified with the
+ \ref cfg_predefined "PREDEFINED" and \ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tags.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_search_includes
+<dt>\c SEARCH_INCLUDES <dd>
+ \addindex SEARCH_INCLUDES
+ If the \c SEARCH_INCLUDES tag is set to \c YES the includes files
+ in the \ref cfg_include_path "INCLUDE_PATH" will be searched if a \c \#include is found.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_include_path
+<dt>\c INCLUDE_PATH <dd>
+ \addindex INCLUDE_PATH
+ The \c INCLUDE_PATH tag can be used to specify one or more directories that
+ contain include files that are not input files but should be processed by
+ the preprocessor.
+
+
+This tag requires that the tag \ref cfg_search_includes "SEARCH_INCLUDES" is set to \c YES.
+ \anchor cfg_include_file_patterns
+<dt>\c INCLUDE_FILE_PATTERNS <dd>
+ \addindex INCLUDE_FILE_PATTERNS
+ You can use the \c INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+ patterns (like `*.h` and `*.hpp`) to filter out the header-files in the
+ directories. If left blank, the patterns specified with \ref cfg_file_patterns "FILE_PATTERNS" will
+ be used.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_predefined
+<dt>\c PREDEFINED <dd>
+ \addindex PREDEFINED
+ The \c PREDEFINED tag can be used to specify one or more macro names that
+ are defined before the preprocessor is started (similar to the `-D` option of
+ e.g. \c gcc). The argument of the tag is a list of macros of the form:
+ <code>name</code> or <code>name=definition</code> (no spaces).
+ If the definition and the \c "=" are omitted, \c "=1" is assumed. To prevent
+ a macro definition from being undefined via \c \#undef or recursively expanded
+ use the <code>:=</code> operator instead of the \c = operator.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_expand_as_defined
+<dt>\c EXPAND_AS_DEFINED <dd>
+ \addindex EXPAND_AS_DEFINED
+ If the \ref cfg_macro_expansion "MACRO_EXPANSION" and
+ \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" tags are set to \c YES then
+ this tag can be used to specify a list of macro names that should be expanded.
+ The macro definition that is found in the sources will be used.
+ Use the \ref cfg_predefined "PREDEFINED" tag if you want to use a different macro definition that
+ overrules the definition found in the source code.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+ \anchor cfg_skip_function_macros
+<dt>\c SKIP_FUNCTION_MACROS <dd>
+ \addindex SKIP_FUNCTION_MACROS
+ If the \c SKIP_FUNCTION_MACROS tag is set to \c YES then
+ doxygen's preprocessor will remove all references to function-like macros that are alone
+ on a line, have an all uppercase name, and do not end with a semicolon.
+ Such function macros are typically
+ used for boiler-plate code, and will confuse the parser if not removed.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to \c YES.
+</dl>
+\section config_external Configuration options related to external references
+ \anchor cfg_tagfiles
+<dl>
+
+<dt>\c TAGFILES <dd>
+ \addindex TAGFILES
+ The \c TAGFILES tag can be used to specify one or more tag files.
+
+For each
+tag file the location of the external documentation should be added. The
+format of a tag file without this location is as follows:
+\verbatim
+ TAGFILES = file1 file2 ...
+\endverbatim
+Adding location for the tag files is done as follows:
+\verbatim
+ TAGFILES = file1=loc1 "file2 = loc2" ...
+\endverbatim
+where `loc1` and `loc2` can be relative or absolute paths or URLs.
+ See the section \ref external for more information about the use of tag files.
+
+ \note
+ Each tag file must have a unique name
+ (where the name does \e NOT include the path).
+ If a tag file is not located in the directory in which doxygen
+ is run, you must also specify the path to the tagfile here.
+
+ \anchor cfg_generate_tagfile
+<dt>\c GENERATE_TAGFILE <dd>
+ \addindex GENERATE_TAGFILE
+ When a file name is specified after \c GENERATE_TAGFILE, doxygen will create
+ a tag file that is based on the input files it reads.
+ See section \ref external for more information about the usage of
+ tag files.
+
+ \anchor cfg_allexternals
+<dt>\c ALLEXTERNALS <dd>
+ \addindex ALLEXTERNALS
+ If the \c ALLEXTERNALS tag is set to \c YES all external class will be listed
+ in the class index. If set to \c NO only the inherited external classes
+ will be listed.
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_external_groups
+<dt>\c EXTERNAL_GROUPS <dd>
+ \addindex EXTERNAL_GROUPS
+ If the \c EXTERNAL_GROUPS tag is set to \c YES all external groups will be listed
+ in the modules index. If set to \c NO, only the current project's groups will
+ be listed.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_external_pages
+<dt>\c EXTERNAL_PAGES <dd>
+ \addindex EXTERNAL_PAGES
+ If the \c EXTERNAL_PAGES tag is set to \c YES all external pages will be listed
+ in the related pages index. If set to \c NO, only the current project's
+ pages will be listed.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_perl_path
+<dt>\c PERL_PATH <dd>
+ \addindex PERL_PATH
+ The \c PERL_PATH should be the absolute path and name of the perl script
+ interpreter (i.e. the result of `'which perl'`).
+
+The default file (with absolute path) is: <code>/usr/bin/perl</code>.
+
+</dl>
+\section config_dot Configuration options related to the dot tool
+ \anchor cfg_class_diagrams
+<dl>
+
+<dt>\c CLASS_DIAGRAMS <dd>
+ \addindex CLASS_DIAGRAMS
+ If the \c CLASS_DIAGRAMS tag is set to \c YES doxygen will
+ generate a class diagram (in HTML and \f$\mbox{\LaTeX}\f$) for classes with base or
+ super classes. Setting the tag to \c NO turns the diagrams off. Note that
+ this option also works with \ref cfg_have_dot "HAVE_DOT" disabled, but it is recommended to
+ install and use \c dot, since it yields more powerful graphs.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_mscgen_path
+<dt>\c MSCGEN_PATH <dd>
+ \addindex MSCGEN_PATH
+ You can define message sequence charts within doxygen comments using the \ref cmdmsc "\\msc"
+ command. Doxygen will then run the <a href="http://www.mcternan.me.uk/mscgen/">mscgen tool</a>) to
+ produce the chart and insert it in the documentation. The <code>MSCGEN_PATH</code> tag allows you to
+ specify the directory where the \c mscgen tool resides. If left empty the tool is assumed to
+ be found in the default search path.
+
+ \anchor cfg_dia_path
+<dt>\c DIA_PATH <dd>
+ \addindex DIA_PATH
+You can include diagrams made with dia in doxygen documentation. Doxygen will then run
+dia to produce the diagram and insert it in the documentation. The DIA_PATH tag allows
+you to specify the directory where the dia binary resides. If left empty dia is assumed
+to be found in the default search path.
+
+ \anchor cfg_hide_undoc_relations
+<dt>\c HIDE_UNDOC_RELATIONS <dd>
+ \addindex HIDE_UNDOC_RELATIONS
+ If set to \c YES, the inheritance and collaboration graphs will hide
+ inheritance and usage relations if the target is undocumented
+ or is not a class.
+
+
+The default value is: <code>YES</code>.
+
+ \anchor cfg_have_dot
+<dt>\c HAVE_DOT <dd>
+ \addindex HAVE_DOT
+ If you set the \c HAVE_DOT tag to \c YES then doxygen will assume the \c dot tool is
+ available from the \c path. This tool is part of
+ <a href="http://www.graphviz.org/">Graphviz</a>, a graph
+ visualization toolkit from AT\&T and Lucent Bell Labs. The other options in
+ this section have no effect if this option is set to \c NO
+
+
+The default value is: <code>NO</code>.
+
+ \anchor cfg_dot_num_threads
+<dt>\c DOT_NUM_THREADS <dd>
+ \addindex DOT_NUM_THREADS
+ The \c DOT_NUM_THREADS specifies the number of \c dot invocations doxygen is
+ allowed to run in parallel. When set to \c 0 doxygen will
+ base this on the number of processors available in the system. You can set it
+ explicitly to a value larger than 0 to get control over the balance
+ between CPU load and processing speed.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>32</code>, default value: <code>0</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_fontname
+<dt>\c DOT_FONTNAME <dd>
+ \addindex DOT_FONTNAME
+ When you want a differently looking font in the dot files that doxygen generates
+ you can specify the font name
+ using \c DOT_FONTNAME. You need to make sure dot is able to find the font,
+ which can be done by putting it in a standard location or by setting the
+ \c DOTFONTPATH environment variable or by setting \ref cfg_dot_fontpath "DOT_FONTPATH" to the
+ directory containing the font.
+
+The default value is: <code>Helvetica</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_fontsize
+<dt>\c DOT_FONTSIZE <dd>
+ \addindex DOT_FONTSIZE
+ The \c DOT_FONTSIZE tag can be used to set the size (in points) of the font of dot graphs.
+
+
+ Minimum value: <code>4</code>, maximum value: <code>24</code>, default value: <code>10</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_fontpath
+<dt>\c DOT_FONTPATH <dd>
+ \addindex DOT_FONTPATH
+ By default doxygen will tell \c dot to use the default font as specified with \ref cfg_dot_fontname "DOT_FONTNAME".
+ If you specify a
+ different font using \ref cfg_dot_fontname "DOT_FONTNAME" you can set the path where \c dot
+ can find it using this tag.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_class_graph
+<dt>\c CLASS_GRAPH <dd>
+ \addindex CLASS_GRAPH
+ If the \c CLASS_GRAPH tag is set to \c YES then doxygen
+ will generate a graph for each documented class showing the direct and
+ indirect inheritance relations. Setting this tag to \c YES will force
+ the \ref cfg_class_diagrams "CLASS_DIAGRAMS" tag to \c NO.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_collaboration_graph
+<dt>\c COLLABORATION_GRAPH <dd>
+ \addindex COLLABORATION_GRAPH
+ If the \c COLLABORATION_GRAPH tag is set to \c YES then doxygen
+ will generate a graph for each documented class showing the direct and
+ indirect implementation dependencies (inheritance, containment, and
+ class references variables) of the class with other documented classes.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_group_graphs
+<dt>\c GROUP_GRAPHS <dd>
+ \addindex GROUP_GRAPHS
+ If the \c GROUP_GRAPHS tag is set to \c YES then doxygen
+ will generate a graph for groups, showing the direct groups dependencies.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_uml_look
+<dt>\c UML_LOOK <dd>
+ \addindex UML_LOOK
+ If the \c UML_LOOK tag is set to \c YES doxygen will generate inheritance and
+ collaboration diagrams in a style similar to the OMG's Unified Modeling
+ Language.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_uml_limit_num_fields
+<dt>\c UML_LIMIT_NUM_FIELDS <dd>
+ \addindex UML_LIMIT_NUM_FIELDS
+ If the \ref cfg_uml_look "UML_LOOK" tag is enabled, the fields and methods are shown inside
+ the class node. If there are many fields or methods and many nodes the
+ graph may become too big to be useful. The \c UML_LIMIT_NUM_FIELDS
+ threshold limits the number of items for each type to make the size more
+ manageable. Set this to 0 for no limit. Note that the threshold may be
+ exceeded by 50% before the limit is enforced. So when you set the threshold
+ to 10, up to 15 fields may appear, but if the number exceeds 15, the
+ total amount of fields shown is limited to 10.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>100</code>, default value: <code>10</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_template_relations
+<dt>\c TEMPLATE_RELATIONS <dd>
+ \addindex TEMPLATE_RELATIONS
+ If the \c TEMPLATE_RELATIONS tag is set to \c YES then
+ the inheritance and collaboration graphs will show the relations between templates and their instances.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_include_graph
+<dt>\c INCLUDE_GRAPH <dd>
+ \addindex INCLUDE_GRAPH
+ If the \c INCLUDE_GRAPH, \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" and
+ \ref cfg_search_includes "SEARCH_INCLUDES"
+ tags are set to \c YES then doxygen will generate a graph for each documented file
+ showing the direct and indirect include dependencies of the file with other
+ documented files.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_included_by_graph
+<dt>\c INCLUDED_BY_GRAPH <dd>
+ \addindex INCLUDED_BY_GRAPH
+ If the \c INCLUDED_BY_GRAPH, \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" and
+ \ref cfg_search_includes "SEARCH_INCLUDES"
+ tags are set to \c YES then doxygen will generate a graph for each documented file
+ showing the direct and indirect include dependencies of the file with other
+ documented files.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_call_graph
+<dt>\c CALL_GRAPH <dd>
+ \addindex CALL_GRAPH
+ If the \c CALL_GRAPH tag is set to \c YES then doxygen will
+ generate a call dependency graph for every global function or class method.
+ <br>Note that enabling this option will significantly increase the time of a run.
+ So in most cases it will be better to enable call graphs for selected
+ functions only using the \ref cmdcallgraph "\\callgraph" command.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_caller_graph
+<dt>\c CALLER_GRAPH <dd>
+ \addindex CALLER_GRAPH
+ If the \c CALLER_GRAPH tag is set to \c YES then doxygen will
+ generate a caller dependency graph for every global function or class method.
+ <br>Note that enabling this option will significantly increase the time of a run.
+ So in most cases it will be better to enable caller graphs for selected
+ functions only using the \ref cmdcallergraph "\\callergraph" command.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_graphical_hierarchy
+<dt>\c GRAPHICAL_HIERARCHY <dd>
+ \addindex GRAPHICAL_HIERARCHY
+ If the \c GRAPHICAL_HIERARCHY tag is set to \c YES then
+ doxygen will graphical hierarchy of all classes instead of a textual one.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_directory_graph
+<dt>\c DIRECTORY_GRAPH <dd>
+ \addindex DIRECTORY_GRAPH
+ If the \c DIRECTORY_GRAPH tag is set
+ to \c YES then doxygen will show the dependencies a directory has on other directories
+ in a graphical way. The dependency relations are determined by the \c \#include
+ relations between the files in the directories.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_image_format
+<dt>\c DOT_IMAGE_FORMAT <dd>
+ \addindex DOT_IMAGE_FORMAT
+ The \c DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+ generated by \c dot.
+ \note If you choose \c svg you need to set
+ \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order to make the SVG files
+ visible in IE 9+ (other browsers do not have this requirement).
+
+Possible values are:
+<code>png</code>,
+<code>jpg</code>,
+<code>gif</code> and
+<code>svg</code>.
+
+
+The default value is: <code>png</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_interactive_svg
+<dt>\c INTERACTIVE_SVG <dd>
+ \addindex INTERACTIVE_SVG
+ If \ref cfg_dot_image_format "DOT_IMAGE_FORMAT" is set to \c svg, then this option can be set to \c YES to
+ enable generation of interactive SVG images that allow zooming and panning.
+ <br>Note that this requires a modern browser other than Internet Explorer.
+ Tested and working are Firefox, Chrome, Safari, and Opera.
+ \note For IE 9+ you need to set \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order
+ to make the SVG files visible. Older versions of IE do not have SVG support.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_path
+<dt>\c DOT_PATH <dd>
+ \addindex DOT_PATH
+ The \c DOT_PATH tag can be used to specify the path where the \c dot tool can be found.
+ If left blank, it is assumed the \c dot tool can be found in the \c path.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dotfile_dirs
+<dt>\c DOTFILE_DIRS <dd>
+ \addindex DOTFILE_DIRS
+ The \c DOTFILE_DIRS tag can be used to specify one or more directories that
+ contain dot files that are included in the documentation (see the
+ \ref cmddotfile "\\dotfile" command).
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_mscfile_dirs
+<dt>\c MSCFILE_DIRS <dd>
+ \addindex MSCFILE_DIRS
+ The \c MSCFILE_DIRS tag can be used to specify one or more directories that
+ contain msc files that are included in the documentation (see the
+ \ref cmdmscfile "\\mscfile" command).
+
+ \anchor cfg_diafile_dirs
+<dt>\c DIAFILE_DIRS <dd>
+ \addindex DIAFILE_DIRS
+ The \c DIAFILE_DIRS tag can be used to specify one or more directories that
+ contain dia files that are included in the documentation (see the
+ \ref cmdmscfile "\\diafile" command).
+
+ \anchor cfg_plantuml_jar_path
+<dt>\c PLANTUML_JAR_PATH <dd>
+ \addindex PLANTUML_JAR_PATH
+ When using plantuml, the \c PLANTUML_JAR_PATH tag should be used to specify the path where
+ java can find the \c plantuml.jar file. If left blank, it is assumed PlantUML is not used or
+ called during a preprocessing step. Doxygen will generate a warning when it encounters a
+ \ref cmdstartuml "\\startuml" command in this case and will not generate output for the diagram.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_graph_max_nodes
+<dt>\c DOT_GRAPH_MAX_NODES <dd>
+ \addindex DOT_GRAPH_MAX_NODES
+ The \c DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+ nodes that will be shown in the graph. If the number of nodes in a graph
+ becomes larger than this value, doxygen will truncate the graph, which is
+ visualized by representing a node as a red box. Note that doxygen if the number
+ of direct children of the root node in a graph is already larger than
+ \c DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+ that the size of a graph can be further restricted by \ref cfg_max_dot_graph_depth "MAX_DOT_GRAPH_DEPTH".
+
+
+ Minimum value: <code>0</code>, maximum value: <code>10000</code>, default value: <code>50</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_max_dot_graph_depth
+<dt>\c MAX_DOT_GRAPH_DEPTH <dd>
+ \addindex MAX_DOT_GRAPH_DEPTH
+ The \c MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+ graphs generated by \c dot. A depth value of 3 means that only nodes reachable
+ from the root by following a path via at most 3 edges will be shown. Nodes
+ that lay further from the root node will be omitted. Note that setting this
+ option to 1 or 2 may greatly reduce the computation time needed for large
+ code bases. Also note that the size of a graph can be further restricted by
+ \ref cfg_dot_graph_max_nodes "DOT_GRAPH_MAX_NODES". Using a depth of 0 means no depth restriction.
+
+
+ Minimum value: <code>0</code>, maximum value: <code>1000</code>, default value: <code>0</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_transparent
+<dt>\c DOT_TRANSPARENT <dd>
+ \addindex DOT_TRANSPARENT
+ Set the \c DOT_TRANSPARENT tag to \c YES to generate images with a transparent
+ background. This is disabled by default, because dot on Windows does not
+ seem to support this out of the box.
+ <br>
+ Warning: Depending on the platform used,
+ enabling this option may lead to badly anti-aliased labels on the edges of
+ a graph (i.e. they become hard to read).
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_multi_targets
+<dt>\c DOT_MULTI_TARGETS <dd>
+ \addindex DOT_MULTI_TARGETS
+ Set the \c DOT_MULTI_TARGETS tag to \c YES allow dot to generate multiple output
+ files in one run (i.e. multiple -o and -T options on the command line). This
+ makes \c dot run faster, but since only newer versions of \c dot (>1.8.10)
+ support this, this feature is disabled by default.
+
+
+The default value is: <code>NO</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_generate_legend
+<dt>\c GENERATE_LEGEND <dd>
+ \addindex GENERATE_LEGEND
+ If the \c GENERATE_LEGEND tag is set to \c YES doxygen will
+ generate a legend page explaining the meaning of the various boxes and
+ arrows in the dot generated graphs.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+ \anchor cfg_dot_cleanup
+<dt>\c DOT_CLEANUP <dd>
+ \addindex DOT_CLEANUP
+If the \c DOT_CLEANUP tag is set to \c YES doxygen will
+remove the intermediate dot files that are used to generate the various graphs.
+
+
+The default value is: <code>YES</code>.
+
+
+This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
+</dl>
+\section config_examples Examples
+
+Suppose you have a simple project consisting of two files: a source file
+\c example.cc and a header file \c example.h.
+Then a minimal configuration file is as simple as:
+\verbatim
+INPUT = example.cc example.h
+\endverbatim
+
+Assuming the example makes use of Qt classes and \c perl is located
+in <code>/usr/bin</code>, a more realistic configuration file would be:
+\verbatim
+PROJECT_NAME = Example
+INPUT = example.cc example.h
+WARNINGS = YES
+TAGFILES = qt.tag
+PERL_PATH = /usr/local/bin/perl
+SEARCHENGINE = NO
+\endverbatim
+
+To generate the documentation for the
+<a href="http://www.stack.nl/~dimitri/qdbttabular/index.html">QdbtTabular</a> package
+I have used the following configuration file:
+\verbatim
+PROJECT_NAME = QdbtTabular
+OUTPUT_DIRECTORY = html
+WARNINGS = YES
+INPUT = examples/examples.doc src
+FILE_PATTERNS = *.cc *.h
+INCLUDE_PATH = examples
+TAGFILES = qt.tag
+PERL_PATH = /usr/bin/perl
+SEARCHENGINE = YES
+\endverbatim
+
+To regenerate the Qt-1.44 documentation from the sources, you could use the
+following config file:
+\verbatim
+PROJECT_NAME = Qt
+OUTPUT_DIRECTORY = qt_docs
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = $(QTDIR)/
+PREDEFINED = USE_TEMPLATECLASS Q_EXPORT= \
+ QArrayT:=QArray \
+ QListT:=QList \
+ QDictT:=QDict \
+ QQueueT:=QQueue \
+ QVectorT:=QVector \
+ QPtrDictT:=QPtrDict \
+ QIntDictT:=QIntDict \
+ QStackT:=QStack \
+ QDictIteratorT:=QDictIterator \
+ QListIteratorT:=QListIterator \
+ QCacheT:=QCache \
+ QCacheIteratorT:=QCacheIterator \
+ QIntCacheT:=QIntCache \
+ QIntCacheIteratorT:=QIntCacheIterator \
+ QIntDictIteratorT:=QIntDictIterator \
+ QPtrDictIteratorT:=QPtrDictIterator
+INPUT = $(QTDIR)/doc \
+ $(QTDIR)/src/widgets \
+ $(QTDIR)/src/kernel \
+ $(QTDIR)/src/dialogs \
+ $(QTDIR)/src/tools
+FILE_PATTERNS = *.cpp *.h q*.doc
+INCLUDE_PATH = $(QTDIR)/include
+RECURSIVE = YES
+\endverbatim
+
+For the Qt-2.1 sources I recommend to use the following settings:
+\verbatim
+PROJECT_NAME = Qt
+PROJECT_NUMBER = 2.1
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+SOURCE_BROWSER = YES
+INPUT = $(QTDIR)/src
+FILE_PATTERNS = *.cpp *.h q*.doc
+RECURSIVE = YES
+EXCLUDE_PATTERNS = *codec.cpp moc_* */compat/* */3rdparty/*
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 3
+IGNORE_PREFIX = Q
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+INCLUDE_PATH = $(QTDIR)/include
+PREDEFINED = Q_PROPERTY(x)= \
+ Q_OVERRIDE(x)= \
+ Q_EXPORT= \
+ Q_ENUMS(x)= \
+ "QT_STATIC_CONST=static const " \
+ _WS_X11_ \
+ INCLUDE_MENUITEM_DEF
+EXPAND_ONLY_PREDEF = YES
+EXPAND_AS_DEFINED = Q_OBJECT_FAKE Q_OBJECT ACTIVATE_SIGNAL_WITH_PARAM \
+ Q_VARIANT_AS
+\endverbatim
+
+Here doxygen's preprocessor is used to substitute some
+macro names that are normally substituted by the C preprocessor,
+but without doing full macro expansion.
+
+
+\htmlonly
+Go to the <a href="commands.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/custcmd.doc b/doc/custcmd.doc
new file mode 100644
index 0000000..db41f95
--- /dev/null
+++ b/doc/custcmd.doc
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page custcmd Custom Commands
+
+\tableofcontents
+
+Doxygen provides a large number of \ref commands "special commands",
+\ref xmlcmds "XML commands", and \ref htmlcmds "HTML commands".
+that can be used to enhance or structure the documentation inside a comment block.
+If you for some reason have a need to define new commands you can do
+so by means of an \e alias definition.
+
+The definition of an alias should be specified in the configuration file using
+the \ref cfg_aliases "ALIASES" configuration tag.
+
+\section custcmd_simple Simple aliases
+The simplest form of an alias is a simple substitution of the form
+\verbatim
+ name=value
+\endverbatim
+ For example defining the following alias:
+\verbatim
+ ALIASES += sideeffect="\par Side Effects:\n"
+\endverbatim
+ will allow you to
+ put the command `\sideeffect` (or `@sideeffect`) in the documentation, which
+ will result in a user-defined paragraph with heading <b>Side Effects:</b>.
+
+Note that you can put `\n`'s in the value part of an alias to insert newlines.
+
+Also note that you can redefine existing special commands if you wish.
+
+Some commands, such as \ref cmdxrefitem "\\xrefitem" are designed to be used in
+combination with aliases.
+
+\section custcmd_complex Aliases with arguments
+Aliases can also have one or more arguments. In the alias definition you then need
+to specify the number of arguments between curly braces. In the value part of the
+definition you can place `\x` markers, where '`x`' represents the argument number starting
+with 1.
+
+Here is an example of an alias definition with a single argument:
+\verbatim
+ALIASES += l{1}="\ref \1"
+\endverbatim
+
+Inside a comment block you can use it as follows
+\verbatim
+/** See \l{SomeClass} for more information. */
+\endverbatim
+which would be the same as writing
+\verbatim
+/** See \ref SomeClass for more information. */
+\endverbatim
+
+Note that you can overload an alias by a version with multiple arguments, for instance:
+\verbatim
+ALIASES += l{1}="\ref \1"
+ALIASES += l{2}="\ref \1 \"\2\""
+\endverbatim
+Note that the quotes inside the alias definition have to be escaped with a backslash.
+
+With these alias definitions, we can write
+\verbatim
+/** See \l{SomeClass,Some Text} for more information. */
+\endverbatim
+inside the comment block and it will expand to
+\verbatim
+/** See \ref SomeClass "Some Text" for more information. */
+\endverbatim
+where the command with a single argument would still work as shown before.
+
+Aliases can also be expressed in terms of other aliases, e.g. a new command
+`\reminder` can be expressed as a \ref cmdxrefitem "\\xrefitem" via an intermediate `\xreflist` command
+as follows:
+\verbatim
+ALIASES += xreflist{3}="\xrefitem \1 \"\2\" \"\3\" "
+ALIASES += reminder="\xreflist{reminders,Reminder,Reminders}"
+\endverbatim
+
+Note that if for aliases with more than one argument a comma is used as a separator,
+if you want to put a comma inside the command, you will need to escape it with a backslash,
+i.e.
+\verbatim
+\l{SomeClass,Some text\, with an escaped comma}
+\endverbatim
+given the alias definition of `\l` in the example above.
+
+\section custcmd_nesting Nesting custom command
+
+You can use commands as arguments of aliases, including commands
+defined using aliases.
+
+As an example consider the following alias definitions
+
+\verbatim
+ALIASES += Bold{1}="<b>\1</b>"
+ALIASES += Emph{1}="<em>\1</em>"
+\endverbatim
+
+Inside a comment block you can now use:
+\verbatim
+/** This is a \Bold{bold \Emph{and} Emphasized} text fragment. */
+\endverbatim
+which will expand to
+\verbatim
+/** This is a <b>bold <em>and</em> Emphasized</b> text fragment. */
+\endverbatim
+
+
+\htmlonly
+<br/>
+Go to the <a href="external.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+
+*/
diff --git a/doc/customize.doc b/doc/customize.doc
new file mode 100644
index 0000000..46b1d8b
--- /dev/null
+++ b/doc/customize.doc
@@ -0,0 +1,401 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page customize Customizing the output
+
+\tableofcontents
+
+Doxygen provides various levels of customization.
+The section \ref minor_tweaks "Minor Tweaks" discusses what to
+do if you want to do minor tweaking to the look and feel of the output.
+The section \ref layout "Layout" show how to reorder and hide certain
+information on a page.
+The section \ref xmlgenerator "XML output" show how to generate
+whatever output you want based on the XML output produced by doxygen.
+
+\section minor_tweaks Minor Tweaks
+
+The next subsections describe some aspects that can be tweaked with
+little effort.
+
+\subsection minor_tweaks_colors Overall Color
+
+To change the overall color of the HTML output doxygen provides three options
+- \ref cfg_html_colorstyle_hue "HTML_COLORSTYLE_HUE"
+- \ref cfg_html_colorstyle_sat "HTML_COLORSTYLE_SAT"
+- \ref cfg_html_colorstyle_gamma "HTML_COLORSTYLE_GAMMA"
+
+to change the hue, saturation, and gamma correction of the colors respectively.
+
+For your convenience the GUI frontend \ref doxywizard_usage "Doxywizard"
+has a control that allows you to see the effect of changing the values of these options
+on the output in real time.
+
+\subsection minor_tweaks_treeview Navigation
+
+By default doxygen shows navigation tabs on top of every HTML page,
+corresponding with the following settings:
+
+- \ref cfg_disable_index "DISABLE_INDEX" = \c NO
+- \ref cfg_generate_treeview "GENERATE_TREEVIEW" = \c NO
+
+you can switch to an interactive navigation tree as sidebar using
+
+- \ref cfg_disable_index "DISABLE_INDEX" = \c YES
+- \ref cfg_generate_treeview "GENERATE_TREEVIEW" = \c YES
+
+or even have both forms of navigation:
+
+- \ref cfg_disable_index "DISABLE_INDEX" = \c NO
+- \ref cfg_generate_treeview "GENERATE_TREEVIEW" = \c YES
+
+if you already use an external index (i.e. have one of the following
+options enabled
+\ref cfg_generate_htmlhelp "GENERATE_HTMLHELP",
+\ref cfg_generate_eclipsehelp "GENERATE_ECLIPSEHELP",
+\ref cfg_generate_qhp "GENERATE_QHP", or
+\ref cfg_generate_docset "GENERATE_DOCSET")
+then you can also disable all indices, like so:
+
+- \ref cfg_disable_index "DISABLE_INDEX" = \c YES
+- \ref cfg_generate_treeview "GENERATE_TREEVIEW" = \c NO
+
+\subsection minor_tweaks_dynsection Dynamic Content
+
+To make the HTML output more interactive, doxygen provides a number of options
+that are disabled by default:
+- enabling \ref cfg_html_dynamic_sections "HTML_DYNAMIC_SECTIONS" will make
+ doxygen hide certain content (like graphs) in the HTML by default,
+ and let the reader expand these sections on request.
+- enabling \ref cfg_have_dot "HAVE_DOT" along
+ with \ref cfg_interactive_svg "INTERACTIVE_SVG" while setting
+ \ref cfg_dot_image_format "DOT_IMAGE_FORMAT" to \c svg, will make doxygen
+ produce SVG images that will allow the user to zoom and pan (this only
+ happens when the size of the images exceeds a certain size).
+
+\subsection minor_tweaks_header_css Header, Footer, and Stylesheet changes
+
+To tweak things like fonts or colors, margins, or other look \& feel
+aspects of the HTML output in detail, you can create a different
+<a href="http://www.w3schools.com/css/default.asp">cascading style sheet</a>.
+You can also let doxygen use a custom header and footer for each HTML
+page it generates, for instance to make the output conform to the style
+used on the rest of your web site.
+
+To do this first run doxygen as follows:
+\verbatim
+doxygen -w html header.html footer.html customdoxygen.css
+\endverbatim
+
+This will create 3 files:
+- header.html is a HTML fragment which doxygen normally uses to start
+ a HTML page. Note that the fragment ends with a body tag and that is
+ contains a couple of commands of the form \$word. These will be replaced
+ by doxygen on the fly.
+- footer.html is a HTML fragment which doxygen normally uses to end
+ a HTML page. Also here special commands can be used. This file contain the
+ link to www.doxygen.org and the body and html end tags.
+- customdoxygen.css is the default cascading style sheet
+ used by doxygen. It is recommended only to look into this file and overrule
+ some settings you like by putting them in a separate stylesheets and
+ referencing those extra files
+ via \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET".
+
+You should edit these files and then reference them from the config file.
+- \ref cfg_html_header "HTML_HEADER" = \c header.html
+- \ref cfg_html_footer "HTML_FOOTER" = \c footer.html
+- \ref cfg_html_stylesheet "HTML_STYLESHEET" = \c customdoxygen.css <b>←obsolete</b>
+
+\note it is not longer recommended to use HTML_STYLESHEET this way,
+as it make it difficult to upgrade to a newer version of doxygen. Use
+\ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" instead.
+
+See the documentation of the \ref cfg_html_header "HTML_HEADER" tag
+for more information about the possible meta commands you can use inside
+your custom header.
+
+\note You should not put the style sheet in the HTML output directory. Treat
+it as a source file. Doxygen will copy it for you.
+
+\note If you use images or other external content in a custom header you
+need to make sure these end up in the HTML output directory yourself,
+for instance by writing a script that runs doxygen can then copies the
+images to the output.
+
+\warning The structure of headers and footers may change after upgrading to
+a newer version of doxygen, so if you are using a custom header or footer,
+it might not produce valid output anymore after upgrading.
+
+\section layout Changing the layout of pages
+
+In some cases you may want to change the way the output is structured.
+A different style sheet or custom headers and footers do not help in such
+case.
+
+The solution doxygen provides is a layout file, which you can
+modify and doxygen will use to control what information is presented,
+in which order, and to some extent also how information is presented.
+The layout file is an XML file.
+
+The default layout can be generated
+by doxygen using the following command:
+\verbatim
+doxygen -l
+\endverbatim
+optionally the name of the layout file can be specified, if omitted
+\c DoxygenLayout.xml will be used.
+
+The next step is to mention the layout file in the config file
+\verbatim
+LAYOUT_FILE = DoxygenLayout.xml
+\endverbatim
+To change the layout all you need to do is edit the layout file.
+
+The toplevel structure of the file looks as follows:
+\verbatim
+<doxygenlayout version="1.0">
+ <navindex>
+ ...
+ </navindex>
+ <class>
+ ...
+ </class>
+ <namespace>
+ ...
+ </namespace>
+ <file>
+ ...
+ </file>
+ <group>
+ ...
+ </group>
+ <directory>
+ ...
+ </directory>
+</doxygenlayout>
+\endverbatim
+
+The root element of the XML file is \c doxygenlayout, it has an attribute named
+\c version, which will be used in the future to cope with changes that are
+not backward compatible.
+
+The first section, identified by the \c navindex element, represents the
+layout of the navigation tabs displayed at the top of each HTML page. At the
+same time it also controls the items in the navigation tree in case
+\ref cfg_generate_treeview "GENERATE_TREEVIEW" is enabled.
+Each tab is represented by a \c tab element in the XML file.
+
+You can hide tabs by setting the \c visible attribute to \c no.
+You can also override the default title of a tab by specifying it as
+the value of the \c title attribute. If the title field is the empty string
+(the default) then doxygen will fill in an appropriate language specific title.
+
+You can reorder the tabs by moving the tab elements in the XML file
+within the \c navindex element and even change the tree structure.
+Do not change the value of the \c type attribute however.
+Only a fixed set of types are supported, each representing a link to a
+specific index.
+
+You can also add custom tabs using a type with name "user". Here is an
+example that shows how to add a tab with title "Google" pointing to
+www.google.com:
+
+\verbatim
+ <navindex>
+ ...
+ <tab type="user" url="http://www.google.com" title="Google"/>
+ ...
+ </navindex>
+\endverbatim
+
+The url field can also be a relative URL. If the URL starts with \@ref
+the link will point to a documented entities, such as a class, a function,
+a group, or a related page. Suppose we have defined a page using \@page with
+label mypage, then a tab with label "My Page" to this page would look
+as follows:
+
+\verbatim
+ <navindex>
+ ...
+ <tab type="user" url="@ref mypage" title="My Page"/>
+ ...
+ </navindex>
+\endverbatim
+
+You can also group tabs together in a custom group using a tab with
+type "usergroup". The following example puts the above tabs in a user
+defined group with title "My Group":
+
+\verbatim
+ <navindex>
+ ...
+ <tab type="usergroup" title="My Group">
+ <tab type="user" url="http://www.google.com" title="Google"/>
+ <tab type="user" url="@ref mypage" title="My Page"/>
+ </tab>
+ ...
+ </navindex>
+\endverbatim
+
+Groups can be nested to form a hierarchy.
+
+By default a usergroup entry in the navigation tree is a link to
+a landing page with the contents of the group. You can link to a
+different page using the `url` attribute just like you can for the
+`<tab>` element and prevent any link using `url="[none]"`, i.e.
+
+\verbatim
+ <tab type="usergroup" title="Group without link" url="[none]">
+ ...
+ </tab>
+\endverbatim
+
+The elements after \c navindex represent the layout of the different
+pages generated by doxygen:
+- The \c class element represents the layout of all pages generated for
+ documented classes, structs, unions, and interfaces.
+- The \c namespace element represents the layout of all pages generated for
+ documented namespaces (and also Java packages).
+- The \c file element represents the layout of all pages generated for
+ documented files.
+- The \c group element represents the layout of all pages generated for
+ documented groups (or modules).
+- The \c directory element represents the layout of all pages generated for
+ documented directories.
+
+Each XML element within one of the above page elements represents a certain
+piece of information. Some pieces can appear in each type of page,
+others are specific for a certain type of page.
+Doxygen will list the pieces in the order in which they appear
+in the XML file.
+
+The following generic elements are possible for each page:
+<dl>
+<dt>\c briefdescription
+ <dd>Represents the brief description on a page.
+<dt>\c detaileddescription
+ <dd>Represents the detailed description on a page.
+<dt>\c authorsection
+ <dd>Represents the author section of a page (only used for man pages).
+<dt>\c memberdecl
+ <dd>Represents the quick overview of members on a page (member declarations).
+ This elements has child elements per type of member list.
+ The possible child elements are not listed in detail in the document,
+ but the name of the element should be a good indication of the type
+ of members that the element represents.
+<dt>\c memberdef
+ <dd>Represents the detailed member list on a page (member definition).
+ Like the \c memberdecl element, also this element has a number of
+ possible child elements.
+</dl>
+
+The class page has the following specific elements:
+<dl>
+<dt>\c includes
+ <dd>Represents the include file needed to obtain the definition for
+ this class.
+<dt>\c inheritancegraph
+ <dd>Represents the inheritance relations for a class.
+ Note that the CLASS_DIAGRAM option determines
+ if the inheritance relation is a list of base and derived classes or
+ a graph.
+<dt>\c collaborationgraph
+ <dd>Represents the collaboration graph for a class.
+<dt>\c allmemberslink
+ <dd>Represents the link to the list of all members for a class.
+<dt>\c usedfiles
+ <dd>Represents the list of files from which documentation for the class was
+ extracted.
+</dl>
+
+The file page has the following specific elements:
+<dl>
+<dt>\c includes
+ <dd>Represents the list of \#include statements contained in this file.
+<dt>\c includegraph
+ <dd>Represents the include dependency graph for the file.
+<dt>\c includedbygraph
+ <dd>Represents the included by dependency graph for the file.
+<dt>\c sourcelink
+ <dd>Represents the link to the source code of this file.
+</dl>
+
+The group page has a specific \c groupgraph element which represents the
+graph showing the dependencies between groups.
+
+Similarly, the directory page has a specific \c directorygraph element
+which represents the graph showing the dependencies between the directories
+based on the \#include relations of the files inside the directories.
+
+Some elements have a \c visible attribute which can be
+used to hide the fragment from the generated output, by setting the attribute's
+value to "no". You can also use the value of a configuration option to
+determine the visibility, by using
+its name prefixed with a dollar sign, e.g.
+\verbatim
+ ...
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ ...
+\endverbatim
+This was mainly added for backward compatibility.
+Note that the \c visible attribute is just a hint for doxygen.
+If no relevant information is available for a certain piece it is
+omitted even if it is set to \c yes (i.e. no empty sections are generated).
+
+Some elements have a \c title attribute. This attribute can be used
+to customize the title doxygen will use as a header for the piece.
+
+ at warning at the moment you should not remove elements from the layout file
+as a way to hide information. Doing so can cause broken links in the
+generated output!
+
+
+\section xmlgenerator Using the XML output
+
+If the above two methods still do not provide enough flexibility, you
+can also use the XML output produced by doxygen as a basis to
+generate the output you like. To do this set GENERATE_XML to YES.
+
+The XML output consists of an index file named \c index.xml which
+lists all items extracted by doxygen with references to the other XML files
+for details. The structure of the index is described by a schema file
+\c index.xsd. All other XML files are described by the schema file
+named \c compound.xsd. If you prefer one big XML file
+you can combine the index and the other files using the
+XSLT file \c combine.xslt.
+
+You can use any XML parser to parse the file or use the one that can be found
+in the \c addon/doxmlparser directory of doxygen source distribution.
+Look at \c addon/doxmlparser/include/doxmlintf.h for the interface of the
+parser and in \c addon/doxmlparser/example for examples.
+
+The advantage of using the doxmlparser is that it
+will only read the index file into memory and then only those XML
+files that you implicitly load via navigating through the index. As a
+result this works even for very large projects where reading all XML
+files as one big DOM tree would not fit into memory.
+
+See <a href="https://github.com/michaeljones/breathe">the Breathe project</a> for
+an example that uses doxygen XML output from Python to bridge it with the
+<a href="http://sphinx.pocoo.org/">Sphinx</a> document generator.
+
+
+\htmlonly
+Go to the <a href="custcmd.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+ */
diff --git a/doc/dbusxml.doc b/doc/dbusxml.doc
new file mode 100644
index 0000000..e487126
--- /dev/null
+++ b/doc/dbusxml.doc
@@ -0,0 +1,149 @@
+/*! \page dbusxml DBus XML output format
+
+\addindex dbusxml
+
+<p>Doxygen can generate documentation for DBus XML files. This way
+DBus interfaces can be annotated with doxygen style comments, and
+without writing custom XML parsers. Doxygen extracts its text from
+all XML comments starting with '*' or '!'. An additional '<' can be
+used to assign the documentation string to the previous entity instead
+of the one following the comment.
+
+Note that before the parsing of DBus XML file works one has to
+assign the .xml extension to the DBus XML parser using the
+following configuration option:
+
+\verbatim
+EXTENSION_MAPPING = xml=dbusxml
+\endverbatim
+
+\section dbusxml_supported Supported XML elements and attributes
+
+<p>The following DBus XML elemets can be annotated:
+
+<ul>
+<li><b>interface</b>
+
+<li><b>method</b> or <b>signal</b>
+
+<li><b>arg</b>
+
+<li><b>property</b>
+
+</ul>
+
+Additional elements are supported. These are available once
+the xmlns "http://psiamp.org/dtd/doxygen_dbusxml.dtd" is
+available.
+
+<ul>
+<li><b>namespace</b>: This can be used to group other more of the
+additional elemets. This element requires a <b>name</b> attribute.
+
+<li><b>enum</b> is used to define enums. <b>value</b> element is
+ then used to define the individual values in the enum. This element
+ requires the <b>name</b> and <b>type</b> attributes. A
+ optional <b>named-type</b> attribute is allowed, referrencing typed
+ previously defined by one of the additional elements. A enum name
+ can be used anywhere a type is required using the <b>named-type</b>
+ attribute.
+
+<li><b>flagset</b> is used to define sets of flags. Required and
+ optional attributes are identical to the ones used by <b>enum</b>.
+ While <b>enum</b>s assume the values to be consecutive, while
+ a <b>flagset</b> is values suitable for flags. A flagset name
+ can be used anywhere a type is required using the <b>named-type</b>
+ attribute.
+
+<li><b>struct</b> is used to define structures. A <b>name</b>
+ attribute is required.
+
+<li><b>member</b> is used to define members of <b>structs</b>. It
+ is valid inside <b>struct</b> elements. This
+ element requires <b>name</b> and <b>type</b> attributes. In
+ addition to (or even instead of) the <b>type</b> attribute a
+ <b>named-type</b> attribute may be used to reference types defined
+ by <b>enum</b>, <b>flagset</b> or <b>struct</b>.
+
+\section dbusxml_example Example
+
+<pre>
+<?xml version="1.0" ?>
+<!-- Comment -->
+<!--*< File comment -->
+<node name="/SomeNode" xmlns:dx="http://psiamp.org/dtd/doxygen_dbusxml.dtd">
+ <!--* test struct outside a namespace and interface -->
+ <dx:struct name="StructOutsideNamespace">
+ <!--* member 1 -->
+ <dx:member name="member1" type="s"/>
+ <!--* complex member 1 -->
+ <dx:member name="complexMember1" type="(ssu)"/>
+ </dx:struct>
+
+ <!--* Test flag set -->
+ <dx:flagset name="flagset">
+ <!--* Flag 1 of flagset. -->
+ <dx:value name="FLAG1"/>
+ </dx:flagset>
+
+ <!--* namespace comment -->
+ <dx:namespace name="SomeNamespace">
+ <!--* struct inside a namespace -->
+ <dx:struct name="StructInNamespace">
+ <!--* member 2 -->
+ <dx:member name="member2" type="s"/>
+ </dx:struct>
+ </dx:namespace>
+ <!--* Documentation on the interface -->
+ <interface name="nl.stack.doxygen.test.interface">
+ <!--* Test Enum documentation -->
+ <dx:enum name="TestEnum">
+ <!--* key 1 with value 13 -->
+ <dx:value name="KEY1" value="13"/>
+ <!--* key 2 without a value -->
+ <dx:value name="KEY2"/>
+ </dx:enum>
+
+ <!--* struct inside a interface -->
+ <dx:struct name="StructInInterface">
+ <!--* member 3 -->
+ <dx:member name="member3" type="s"/>
+ <!--* Struct in a struct -->
+ <dx:struct name="StructInAStruct">
+ <!--* member4 -->
+ <dx:member name="member4" type="s"/>
+ </dx:struct>
+ <!--* struct member -->
+ <dx:member name="structMembor" type="(s)" named-type="StructInAStruct"/>
+ </dx:struct>
+ <!--* Document method
+
+ Some extended documentation for the method.
+
+ @param[in] input blah.
+ @param[out] output blub
+ -->
+ <method name="method">
+ <arg direction="in" name="input" type="(s(s))" named-type="::nl::stack::doxygen::test::interface::StructInInterface"/>
+ <arg direction="out" type="v" name="output"/>
+ </method>
+
+ <signal name="signal">
+ <!--*< Documentation for signal.
+
+ @param parameter some parameter.
+ -->
+ <arg name="parameter" type="s"/>
+ </signal>
+
+ <!--* property documentation -->
+ <property name="property" type="s" access="readwrite"/>
+
+ <!--* property documentation read-only -->
+ <property name="propertyRead" type="s" access="read"/>
+ <!--* property documentation write-only -->
+ <property name="propertyWrite" type="s" access="write"/>
+ </interface>
+</node>
+</pre>
+*/
diff --git a/doc/diagrams.doc b/doc/diagrams.doc
new file mode 100644
index 0000000..bafb21d
--- /dev/null
+++ b/doc/diagrams.doc
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page diagrams Graphs and diagrams
+
+ Doxygen has built-in support to generate inheritance diagrams for C++
+ classes.
+
+ Doxygen can use the "dot" tool from graphviz to generate
+ more advanced diagrams and graphs. Graphviz is an open-source,
+ cross-platform graph drawing toolkit and can be found
+ at http://www.graphviz.org/
+
+ If you have the "dot" tool in the path, you can set
+ \ref cfg_have_dot "HAVE_DOT" to \c YES in the configuration file to
+ let doxygen use it.
+
+ Doxygen uses the "dot" tool to generate the following graphs:
+ <ul>
+ <li>A graphical representation of the class hierarchy will be drawn, along
+ with the textual one. Currently this feature is supported for HTML only.\n
+ <b>Warning:</b> When you have a very large class hierarchy where many
+ classes derive from a common base class, the resulting image may become
+ too big to handle for some browsers.
+ <li>An inheritance graph will be generated for each documented class showing the
+ direct and indirect inheritance relations. This disables the
+ generation of the built-in class inheritance diagrams.
+ <li>An include dependency graph is generated for each documented file that
+ includes at least one other file. This feature is currently supported
+ for HTML and RTF only.
+ <li>An inverse include dependency graph is also generated showing for
+ a (header) file, which other files include it.
+ <li>A graph is drawn for each documented class and struct that shows:
+ <ul>
+ <li> the inheritance relations with base classes.
+ <li> the usage relations with other structs and classes (e.g.
+ class \c A has a member variable \c m_a of type class \c B, then
+ \c A has an arrow to \c B with \c m_a as label).
+ </ul>
+ <li>if \ref cfg_call_graph "CALL_GRAPH" is set to YES, a
+ graphical call graph is drawn for each function showing the
+ functions that the function directly or indirectly calls.
+ <li>if \ref cfg_caller_graph "CALLER_GRAPH" is set to YES, a
+ graphical caller graph is drawn for each function showing the
+ functions that the function is directly or indirectly called by.
+ </ul>
+
+ Using a \ref customize "layout file" you can determine which of the
+ graphs are actually shown.
+
+ The options \ref cfg_dot_graph_max_nodes "DOT_GRAPH_MAX_NODES" and
+ \ref cfg_max_dot_graph_depth "MAX_DOT_GRAPH_DEPTH" can be used to
+ limit the size of the various graphs.
+
+ The elements in the class diagrams in HTML and RTF
+ have the following meaning:
+ <ul>
+ <li> A \b yellow box indicates a class. A box can have a
+ little marker in the lower right corner to indicate that the class
+ contains base classes that are hidden.
+ For the class diagrams the maximum tree width is currently 8 elements.
+ If a tree is wider some nodes will be hidden.
+ If the box is filled with a
+ dashed pattern the inheritance relation is virtual.
+ <li> A \b white box indicates that the documentation of the class
+ is currently shown.
+ <li> A \b gray box indicates an undocumented class.
+ <li> A <b>solid dark blue</b> arrow indicates public inheritance.
+ <li> A <b>dashed dark green</b> arrow indicates protected inheritance.
+ <li> A <b>dotted dark green</b> arrow indicates private inheritance.
+ </ul>
+
+ The elements in the class diagram in \LaTeX have the
+ following meaning:
+ <ul>
+ <li> A \b white box indicates a class.
+ A \b marker in the lower right corner of the box indicates that the
+ class has base classes that are hidden.
+ If the box has a \b dashed border this indicates virtual inheritance.
+ <li> A \b solid arrow indicates public inheritance.
+ <li> A \b dashed arrow indicates protected inheritance.
+ <li> A \b dotted arrow indicates private inheritance.
+ </ul>
+
+ The elements in the graphs generated by the dot tool have the following
+ meaning:
+ <ul>
+ <li> A \b white box indicates a class or struct or file.
+ <li> A box with a \b red border indicates a node that has
+ \e more arrows than are shown!
+ In other words: the graph is \e truncated with respect to this node.
+ The reason why a graph is sometimes truncated is to prevent images
+ from becoming too large.
+ For the graphs generated with dot doxygen tries
+ to limit the width of the resulting image to 1024 pixels.
+ <li> A \b black box indicates that the class' documentation is currently shown.
+ <li> A <b>dark blue</b> arrow indicates an include relation (for the
+ include dependency graph) or public inheritance (for the other graphs).
+ <li> A <b>dark green</b> arrow indicates protected inheritance.
+ <li> A <b>dark red</b> arrow indicates private inheritance.
+ <li> A <b>purple dashed</b> arrow indicated a "usage" relation, the
+ edge of the arrow is labeled with the variable(s) responsible for the
+ relation.
+ Class \c A uses class \c B, if class \c A has a member variable \c m
+ of type C, where B is a subtype of C (e.g. `C` could be `B`, `B*`, `T<B>*`).
+ </ul>
+
+
+Here are a couple of header files that together show the various diagrams
+that doxygen can generate:
+
+<code>diagrams_a.h</code>
+\verbinclude diagrams_a.h
+<code>diagrams_b.h</code>
+\verbinclude diagrams_b.h
+<code>diagrams_c.h</code>
+\verbinclude diagrams_c.h
+<code>diagrams_d.h</code>
+\verbinclude diagrams_d.h
+<code>diagrams_e.h</code>
+\verbinclude diagrams_e.h
+
+\htmlonly
+Click <a href="$(DOXYGEN_DOCDIR)/examples/diagrams/html/index.html">here</a>
+for the corresponding HTML documentation that is generated by doxygen<br/>
+(<code>EXTRACT_ALL</code> = <code>YES</code> is used here).
+\endhtmlonly
+
+\htmlonly
+<br><br>
+Go to the <a href="preprocessing.html">next</a> section or return to the
+<a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/docblocks.doc b/doc/docblocks.doc
new file mode 100644
index 0000000..333e5d2
--- /dev/null
+++ b/doc/docblocks.doc
@@ -0,0 +1,622 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page docblocks Documenting the code
+\tableofcontents
+
+This chapter covers two topics:
+1. How to put comments in your code such that doxygen incorporates them in
+ the documentation it generates.
+ This is further detailed in the \ref specialblock "next section".
+2. Ways to structure the contents of a comment block such that the output
+ looks good, as explained in section \ref docstructure.
+
+\section specialblock Special comment blocks
+
+A special comment block is a C or C++ style comment block with some
+additional markings, so doxygen knows it is a piece of structured text that
+needs to end up in the generated documentation. The \ref cppblock "next" section
+presents the various styles supported by doxygen.
+
+For Python, VHDL, Fortran, and Tcl code there are different commenting
+conventions, which can be found in sections \ref pythonblocks, \ref vhdlblocks,
+\ref fortranblocks, and \ref tclblocks respectively.
+
+\subsection cppblock Comment blocks for C-like languages (C/C++/C#/Objective-C/PHP/Java)
+
+For each entity in the code there are two (or in some cases three) types of descriptions,
+which together form the documentation for that entity; a *brief* description and *detailed*
+description, both are optional. For methods and functions there is also a third
+type of description, the so called *in body* description, which consists of
+the concatenation of all comment blocks found within the body of the method or function.
+
+Having more than one brief or detailed description is allowed (but not recommended,
+as the order in which the descriptions will appear is not specified).
+
+As the name suggest, a brief description is
+a short one-liner, whereas the detailed description provides longer,
+more detailed documentation. An "in body" description can also act as a detailed
+description or can describe a collection of implementation details.
+For the HTML output brief descriptions are also
+used to provide tooltips at places where an item is referenced.
+
+There are several ways to mark a comment block as a detailed description:
+<ol>
+<li> You can use the JavaDoc style, which consist of a C-style comment
+block starting with two *'s, like this:
+
+\verbatim
+/**
+ * ... text ...
+ */
+\endverbatim
+
+<li> or you can use the Qt style and add an exclamation mark (!)
+after the opening of a C-style comment block, as shown in this example:
+
+\verbatim
+/*!
+ * ... text ...
+ */
+\endverbatim
+
+In both cases the intermediate *'s are optional, so
+
+\verbatim
+/*!
+ ... text ...
+*/
+\endverbatim
+
+is also valid.
+
+<li> A third alternative is to use a block of <i>at least two</i> C++ comment
+lines, where each line starts with an additional slash or an
+exclamation mark. Here are examples of the two cases:
+
+\verbatim
+///
+/// ... text ...
+///
+\endverbatim
+
+or
+
+\verbatim
+//!
+//!... text ...
+//!
+\endverbatim
+
+Note that a blank line ends a documentation block in this case.
+
+<li>
+
+Some people like to make their comment blocks more visible in the
+documentation. For this purpose you can use the following:
+
+\verbatim
+/********************************************//**
+ * ... text
+ ***********************************************/
+\endverbatim
+(note the 2 slashes to end the normal comment block and start a special comment block).
+
+or
+
+\verbatim
+/////////////////////////////////////////////////
+/// ... text ...
+/////////////////////////////////////////////////
+\endverbatim
+
+</ol>
+
+For the brief description there are also several possibilities:
+<ol>
+<li>One could use the \ref cmdbrief "\\brief" command with one of the
+above comment blocks. This command ends at the end of a paragraph,
+so the detailed description follows after an empty line.
+
+Here is an example:
+
+\verbatim
+/*! \brief Brief description.
+ * Brief description continued.
+ *
+ * Detailed description starts here.
+ */
+\endverbatim
+
+<li>If \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" is set to \c YES
+ in the configuration file,
+ then using JavaDoc style comment
+ blocks will automatically start a brief description which ends at the
+ first dot followed by a space or new line. Here is an example:
+
+\verbatim
+/** Brief description which ends at this dot. Details follow
+ * here.
+ */
+\endverbatim
+The option has the same effect for multi-line special C++ comments:
+\verbatim
+/// Brief description which ends at this dot. Details follow
+/// here.
+\endverbatim
+
+<li>A third option is to use a special C++ style comment which does not
+ span more than one line. Here are two examples:
+\verbatim
+/// Brief description.
+/** Detailed description. */
+\endverbatim
+
+or
+
+\verbatim
+//! Brief description.
+
+//! Detailed description
+//! starts here.
+\endverbatim
+
+Note the blank line in the last example, which is required to separate the
+brief description from the block containing the detailed description. The
+\ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" should also be set to \c NO
+for this case.
+
+</ol>
+
+As you can see doxygen is quite flexible. If you have multiple
+detailed descriptions, like in the following example:
+
+\verbatim
+//! Brief description, which is
+//! really a detailed description since it spans multiple lines.
+/*! Another detailed description!
+ */
+\endverbatim
+
+They will be joined. Note that this is also the case if the descriptions
+are at different places in the code! In this case the order will depend
+on the order in which doxygen parses the code.
+
+
+Unlike most other documentation systems, doxygen also allows you to put
+the documentation of members (including global functions) in front of
+the \e definition. This way the documentation can be placed in the source
+file instead of the header file. This keeps the header file compact, and allows the
+implementer of the members more direct access to the documentation.
+As a compromise the brief description could be placed before the
+declaration and the detailed description before the member definition.
+
+\subsubsection memberdoc Putting documentation after members
+
+If you want to document the members of a file, struct, union, class, or enum,
+it is sometimes desired to place the documentation block after the member
+instead of before. For this purpose you have to put an additional \< marker
+in the comment block. Note that this also works for the parameters
+of a function.
+
+Here are some examples:
+\verbatim
+int var; /*!< Detailed description after the member */
+\endverbatim
+This block can be used to put a Qt style detailed
+documentation block \e after a member. Other ways to do the
+same are:
+\verbatim
+int var; /**< Detailed description after the member */
+\endverbatim
+or
+\verbatim
+int var; //!< Detailed description after the member
+ //!<
+\endverbatim
+or
+\verbatim
+int var; ///< Detailed description after the member
+ ///<
+\endverbatim
+
+Most often one only wants to put a brief description after a member.
+This is done as follows:
+\verbatim
+int var; //!< Brief description after the member
+\endverbatim
+or
+\verbatim
+int var; ///< Brief description after the member
+\endverbatim
+
+For functions one can use the \ref cmdparam "\@param" command to document the parameters
+and then use <code>[in]</code>, <code>[out]</code>, <code>[in,out]</code>
+to document the direction. For inline documentation this is also possible
+by starting with the direction attribute, e.g.
+\verbatim
+void foo(int v /**< [in] docs for input parameter v. */);
+\endverbatim
+
+Note that these blocks have the same structure and meaning as the
+special comment blocks in the previous section
+only the \< indicates that the member is
+located in front of the block instead of after the block.
+
+Here is an example of the use of these comment blocks:
+\include afterdoc.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/afterdoc/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+\warning These blocks can only be used to document \e members and \e parameters.
+ They cannot be used to document files, classes, unions, structs,
+ groups, namespaces and enums themselves. Furthermore, the structural
+ commands mentioned in the next section
+ (like <code>\\class</code>) are not allowed
+ inside these comment blocks.
+
+\subsubsection docexamples Examples
+
+Here is an example of a documented piece of C++ code using the Qt style:
+\include qtstyle.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/qtstyle/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+The brief descriptions are included in the member overview of a
+class, namespace or file and are printed using a small italic font
+(this description can be hidden by setting
+\ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" to \c NO in
+the config file). By default the brief descriptions become the first
+sentence of the detailed descriptions
+(but this can be changed by setting the \ref cfg_repeat_brief "REPEAT_BRIEF"
+tag to \c NO). Both the brief and the detailed descriptions are optional
+for the Qt style.
+
+By default a JavaDoc style documentation block behaves the same way as a
+Qt style documentation block. This is not according the JavaDoc specification
+however, where the first sentence of the documentation block is automatically
+treated as a brief description. To enable this behavior you should set
+\ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" to YES in the configuration
+file. If you enable this option and want to put a dot in the middle of a
+sentence without ending it, you should put a backslash and a space after it.
+Here is an example:
+\verbatim
+ /** Brief description (e.g.\ using only a few words). Details follow. */
+\endverbatim
+
+Here is the same piece of code as shown above, this time documented using the
+JavaDoc style and \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" set to YES:
+\include jdstyle.cpp
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/jdstyle/html/class_test.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+Similarly, if one wishes the first sentence of a Qt style documentation
+block to automatically be treated as a brief description, one may set
+\ref cfg_qt_autobrief "QT_AUTOBRIEF" to YES in the configuration file.
+
+\subsubsection structuralcommands Documentation at other places
+
+In the examples in the previous section the comment blocks were always located *in
+front* of the declaration or definition of a file, class or namespace or *in
+front* or *after* one of its members.
+Although this is often comfortable, there may sometimes be reasons to put the
+documentation somewhere else. For documenting a file this is even
+required since there is no such thing as "in front of a file".
+
+Doxygen allows you to put your documentation blocks practically
+anywhere (the exception is inside the body of a function or inside a
+normal C style comment block).
+
+The price you pay for not putting the
+documentation block directly before (or after) an item is the need to put a
+structural command inside the documentation block, which leads to some
+duplication of information. So in practice you should \e avoid the use of
+structural commands \e unless other requirements force you to do so.
+
+Structural commands (like \ref cmd_intro "all other commands") start with a backslash
+(<tt>\\</tt>), or an at-sign (<tt>\@</tt>) if you prefer JavaDoc style,
+followed by a command name and one or more parameters.
+For instance, if you want to document the class \c Test in the example
+above, you could have also put the following documentation block somewhere
+in the input that is read by doxygen:
+\verbatim
+/*! \class Test
+ \brief A test class.
+
+ A more detailed class description.
+*/
+\endverbatim
+
+Here the special command \c \\class is used to indicate that the
+comment block contains documentation for the class \c Test.
+Other structural commands are:
+<ul>
+<li>\c \\struct to document a C-struct.
+<li>\c \\union to document a union.
+<li>\c \\enum to document an enumeration type.
+<li>\c \\fn to document a function.
+<li>\c \\var to document a variable or typedef or enum value.
+<li>\c \\def to document a \#define.
+<li>\c \\typedef to document a type definition.
+<li>\c \\file to document a file.
+<li>\c \\namespace to document a namespace.
+<li>\c \\package to document a Java package.
+<li>\c \\interface to document an IDL interface.
+</ul>
+See section \ref commands for detailed information about these and many other
+commands.
+
+To document a member of a C++ class, you must also document the class
+itself. The same holds for namespaces. To document a global C function,
+typedef, enum or preprocessor definition you must first document the file
+that contains it (usually this will be a header file, because that file
+contains the information that is exported to other source files).
+
+ at attention Let's repeat that, because it is often overlooked:
+to document global objects (functions, typedefs, enum, macros, etc), you
+<em>must</em> document the file in which they are defined. In other words,
+there <em>must</em> at least be a \verbatim /*! \file */ \endverbatim
+or a \verbatim /** @file */ \endverbatim line in this file.
+
+Here is an example of a C header named \c structcmd.h that is documented
+using structural commands:
+\include structcmd.h
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd_8h.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+ Because each comment block in the example above contains a structural command, all
+ the comment blocks could be moved to another location or input file
+ (the source file for instance), without affecting the generated
+ documentation. The disadvantage of this approach is that prototypes are
+ duplicated, so all changes have to be made twice! Because of this you
+ should first consider if this is really needed, and avoid structural
+ commands if possible. I often receive examples that contain \\fn command
+ in comment blocks which are place in front of a function. This is clearly
+ a case where the \\fn command is redundant and will only lead to problems.
+
+ When you place a comment block in a file with one of the following extensions
+ `.dox`, `.txt`, or `.doc` then doxygen will hide this file from the file list.
+
+ If you have a file that doxygen cannot parse but still would like to document it,
+ you can show it as-is using \ref cmdverbinclude "\\verbinclude", e.g.
+
+\verbatim
+/*! \file myscript.sh
+ * Look at this nice script:
+ * \verbinclude myscript.sh
+ */
+\endverbatim
+
+Make sure that the script is explicitly listed in the \ref cfg_input "INPUT" or
+that \ref cfg_file_patterns "FILE_PATTERNS" includes the `.sh` extention and the
+the script can be found in the path set via \ref cfg_example_path "EXAMPLE_PATH".
+
+\subsection pythonblocks Comment blocks in Python
+
+For Python there is a standard way of documenting the code using
+so called documentation strings. Such strings are stored in \c __doc__
+and can be retrieved at runtime. Doxygen will extract such comments
+and assume they have to be represented in a preformatted way.
+
+\include docstring.py
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/docstring/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+Note that in this case none of doxygen's \ref cmd_intro "special commands"
+are supported.
+
+There is also another way to document Python code using comments that
+start with "##". These type of comment blocks are more in line with the
+way documentation blocks work for the other languages supported by doxygen
+and this also allows the use of special commands.
+
+Here is the same example again but now using doxygen style comments:
+
+\include pyexample.py
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/pyexample/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+Since python looks more like Java than like C or C++, you should set
+\ref cfg_optimize_output_java "OPTIMIZE_OUTPUT_JAVA" to \c YES in the
+config file.
+
+
+\subsection vhdlblocks Comment blocks in VHDL
+
+For VHDL a comment normally start with "--". Doxygen will extract comments
+starting with "--!". There are only two types of comment blocks in VHDL;
+a one line "--!" comment representing a brief description, and a multi-line
+"--!" comment (where the "--!" prefix is repeated for each line) representing
+a detailed description.
+
+Comments are always located in front of the item that is being documented
+with one exception: for ports the comment can also be after the item
+and is then treated as a brief description for the port.
+
+Here is an example VHDL file with doxygen comments:
+
+\include mux.vhdl
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/mux/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+To get proper looking output you need to set
+\ref cfg_optimize_output_vhdl "OPTIMIZE_OUTPUT_VHDL" to \c YES in the
+config file. This will also affect a number of other settings. When they
+were not already set correctly doxygen will produce a warning telling which
+settings where overruled.
+
+\subsection fortranblocks Comment blocks in Fortran
+
+When using doxygen for Fortran code you should
+set \ref cfg_optimize_for_fortran "OPTIMIZE_FOR_FORTRAN" to \c YES.
+
+The parser tries to guess if the source code is fixed format Fortran or
+free format Fortran code. This may not always be correct. If not
+one should use \ref cfg_extension_mapping "EXTENSION_MAPPING" to correct this.
+By setting `EXTENSION_MAPPING = f=FortranFixed f90=FortranFree` files with
+extension \c f are interpreted as fixed format Fortran code and files with
+extension \c f90 are interpreted as free format Fortran code.
+
+For Fortran "!>" or "!<" starts a comment and "!!" or "!>" can be used to
+continue an one line comment into a multi-line comment.
+
+Here is an example of a documented Fortran subroutine:
+\code{.f}
+ !> Build the restriction matrix for the aggregation
+ !! method.
+ !! @param aggr information about the aggregates
+ !! @todo Handle special case
+ subroutine IntRestBuild(A,aggr,Restrict,A_ghost)
+ implicit none
+ Type(SpMtx), intent(in) :: A !< our fine level matrix
+ Type(Aggrs), intent(in) :: aggr
+ Type(SpMtx), intent(out) :: Restrict !< Our restriction matrix
+ !...
+ end subroutine
+\endcode
+
+As an alternative you can also use comments in fixed format code:
+
+\code{.f}
+C> Function comment
+C> another line of comment
+ function A(i)
+C> input parameter
+ integer i
+ end function A
+\endcode
+
+\subsection tclblocks Comment blocks in Tcl
+
+Doxygen documentation can be included in normal Tcl comments.
+
+To start a new documentation block start a line with \c ## (two hashes).
+All following comment lines and continuation lines will be added to this
+block. The block ends with a line not starting with a \c # (hash sign).
+
+A brief documentation can be added with \c ;#< (semicolon, hash and
+lower then sign). The brief documentation also ends at a line not starting
+with a \c # (hash sign).
+
+Inside doxygen comment blocks all normal doxygen markings are supported.
+The only exceptions are described in the following two paragraphs.
+
+If a doxygen comment block ends with a line containing only
+\c #\\code or \c #\@code all code until a line only containing \c #\\endcode
+or \c #\@endcode is added to the generated documentation as code block.
+
+If a doxygen comment block ends with a line containing only
+\c #\\verbatim or \c #\@verbatim all code until a line only containing
+\c #\\endverbatim or \c #\@endverbatim is added verbatim to the generated
+documentation.
+
+To detect namespaces, classes, functions and variables the following
+Tcl commands are recognized. Documentation blocks can be put on the lines
+before the command.
+
+<ul>
+<li><tt>namespace eval ..</tt> Namespace
+<li><tt>proc ..</tt> Function
+<li><tt>variable ..</tt> Variable
+<li><tt>common ..</tt> Common variable
+<li><tt>itcl::class ..</tt> Class
+<li><tt>itcl::body ..</tt> Class method body definition
+<li><tt>oo::class create ..</tt> Class
+<li><tt>oo::define ..</tt> OO Class definition
+<li><tt>method ..</tt> Class method definitions
+<li><tt>constructor ..</tt> Class constructor
+<li><tt>destructor ..</tt> Class destructor
+<li><tt>public ..</tt> Set protection level
+<li><tt>protected ..</tt> Set protection level
+<li><tt>private ..</tt> Set protection level
+</ul>
+
+<!--
+To use your own keywords you an map these keyword to the recognized commands
+using the \ref cfg_tcl_subs "TCL_SUBST" entry in the config file.
+The entry contain a list of word-keyword mappings. To use the itcl::*
+commands without the leading namespace use p.e.:
+
+\verbatim TCL_SUBST = class itcl:class body itcl:body \endverbatim
+-->
+
+Following is an example using doxygen style comments:
+
+\include tclexample.tcl
+ \htmlonly
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/tclexample/html/index.html">here</a>
+ for the corresponding HTML documentation that is generated by doxygen.
+ \endhtmlonly
+
+
+\section docstructure Anatomy of a comment block
+
+The previous section focused on how to make the comments in your code known
+to doxygen, it explained the difference between a brief and a detailed description, and
+the use of structural commands.
+
+In this section we look at the contents of the comment block itself.
+
+Doxygen supports various styles of formatting your comments.
+
+The simplest form is to use plain text. This will appear as-is in the output
+and is ideal for a short description.
+
+For longer descriptions you often will find the
+need for some more structure, like a block of verbatim text, a list, or a
+simple table. For this doxygen supports the
+<a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>
+syntax, including parts of the
+<a href="http://michelf.com/projects/php-markdown/extra/">Markdown Extra</a>
+extension.
+
+Markdown is designed to be very easy to read and write.
+It's formatting is inspired by plain text mail.
+Markdown works great for simple, generic formatting, like an introduction
+page for your project. Doxygen also supports reading of markdown files
+directly. See \ref markdown "here" for more details regards Markdown support.
+
+For programming language specific formatting doxygen has two
+forms of additional markup on top of Markdown formatting.
+
+1. <a href="http://en.wikipedia.org/wiki/Javadoc">Javadoc</a> like markup.
+ See \ref cmd_intro "here" for a complete overview of all commands supported by doxygen.
+2. <a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)#XML_documentation_system">XML</a> markup
+ as specified in the C# standard. See \ref xmlcmds "here" for the XML commands supported by doxygen.
+
+If this is still not enough doxygen also supports a \ref htmlcmds "subset" of
+the <a href="http://en.wikipedia.org/wiki/HTML">HTML</a> markup language.
+
+\htmlonly
+Go to the <a href="markdown.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/doxygen.1 b/doc/doxygen.1
new file mode 100644
index 0000000..f3a7abc
--- /dev/null
+++ b/doc/doxygen.1
@@ -0,0 +1,50 @@
+.TH DOXYGEN "1" "DATE" "doxygen VERSION" "User Commands"
+.SH NAME
+doxygen \- documentation system for various programming languages
+.SH DESCRIPTION
+Doxygen is a documentation system for C++, C, Java, Objective-C, IDL
+(Corba and Microsoft flavors) and to some extent PHP, C#, and D.
+.PP
+You can use doxygen in a number of ways:
+.TP
+1) Use doxygen to generate a template configuration file:
+.IP
+doxygen [-s] \fB\-g\fR [configName]
+.IP
+If - is used for configName doxygen will write to standard output.
+.TP
+2) Use doxygen to update an old configuration file:
+.IP
+doxygen [-s] \fB\-u\fR [configName]
+.TP
+3) Use doxygen to generate documentation using an existing configuration file:
+.IP
+doxygen [configName]
+.IP
+If - is used for configName doxygen will read from standard input.
+.TP
+4) Use doxygen to generate a template file controlling the layout of the generated documentation:
+.IP
+doxygen -l layoutFileName.xml
+.TP
+5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.
+.TP
+RTF:
+doxygen \fB\-w\fR rtf styleSheetFile
+.TP
+HTML:
+doxygen \fB\-w\fR html headerFile footerFile styleSheetFile [configFile]
+.TP
+LaTeX: doxygen \fB\-w\fR latex headerFile footerFile styleSheetFile [configFile]
+.TP
+6) Use doxygen to generate an rtf extensions file
+.TP
+RTF:
+doxygen \fB\-e\fR rtf extensionsFile
+.PP
+If \fB\-s\fR is specified the comments in the config file will be omitted.
+If configName is omitted `Doxyfile' will be used as a default.
+.SH AUTHOR
+Doxygen version VERSION, Copyright Dimitri van Heesch 1997-2014
+.SH SEE ALSO
+doxywizard(1).
diff --git a/doc/doxygen.sty b/doc/doxygen.sty
new file mode 100644
index 0000000..8013dad
--- /dev/null
+++ b/doc/doxygen.sty
@@ -0,0 +1,486 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{doxygen}
+
+% Packages used by this style file
+\RequirePackage{alltt}
+\RequirePackage{array}
+\RequirePackage{calc}
+\RequirePackage{color}
+\RequirePackage{fancyhdr}
+\RequirePackage{longtable}
+\RequirePackage{verbatim}
+\RequirePackage{ifthen}
+\RequirePackage{xtab}
+\RequirePackage{multirow}
+\RequirePackage[table]{xcolor}
+
+% Use helvetica font instead of times roman
+\RequirePackage{helvet}
+\RequirePackage{sectsty}
+\RequirePackage{tocloft}
+\providecommand{\rmdefault}{phv}
+\providecommand{\bfdefault}{bc}
+
+
+% Setup fancy headings
+\pagestyle{fancyplain}
+\newcommand{\clearemptydoublepage}{%
+ \newpage{\pagestyle{empty}\cleardoublepage}%
+}
+\renewcommand{\chaptermark}[1]{%
+ \markboth{#1}{}%
+}
+\renewcommand{\sectionmark}[1]{%
+ \markright{\thesection\ #1}%
+}
+\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
+\fancyhead[CE]{\fancyplain{}{}}
+\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
+\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
+\fancyhead[CO]{\fancyplain{}{}}
+\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
+\fancyfoot[LE]{\fancyplain{}{}}
+\fancyfoot[CE]{\fancyplain{}{}}
+\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
+\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
+\fancyfoot[CO]{\fancyplain{}{}}
+\fancyfoot[RO]{\fancyplain{}{}}
+%---------- Internal commands used in this style file ----------------
+
+\newcommand\tabfill[1]{%
+ \dimen@\linewidth%
+ \advance\dimen@\@totalleftmargin%
+ \advance\dimen at -\dimen\@curtab%
+ \parbox[t]\dimen@{\raggedright #1\ifhmode\strut\fi}%
+}
+
+\newcommand{\ensurespace}[1]{%
+ \begingroup
+ \setlength{\dimen@}{#1}%
+ \vskip\z@\@plus\dimen@
+ \penalty -100\vskip\z@\@plus -\dimen@
+ \vskip\dimen@
+ \penalty 9999%
+ \vskip -\dimen@
+ \vskip\z at skip % hide the previous |\vskip| from |\addvspace|
+ \endgroup
+}
+
+% Generic environment used by all paragraph-based environments defined
+% below. Note that the command \title{...} needs to be defined inside
+% those environments!
+\newenvironment{DoxyDesc}[1]{%
+ \ensurespace{4\baselineskip}%
+ \begin{list}{}%
+ {%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\itemsep}{-4pt}%
+ \renewcommand{\makelabel}{\entrylabel}%
+ }%
+ \item[#1]%
+}{%
+ \end{list}%
+}
+
+%---------- Commands used by doxygen LaTeX output generator ----------
+
+% Used by <pre> ... </pre>
+\newenvironment{DoxyPre}{%
+ \small%
+ \begin{alltt}%
+}{%
+ \end{alltt}%
+ \normalsize%
+}
+
+% Used by @code ... @endcode
+\newenvironment{DoxyCode}{%
+
+
+\begin{scriptsize}\begin{alltt}%
+}{%
+\end{alltt}\end{scriptsize}%
+}
+
+% Used by @example, @include, @includelineno and @dontinclude
+\newenvironment{DoxyCodeInclude}{%
+ \DoxyCode%
+}{%
+ \endDoxyCode%
+}
+
+% Used by @verbatim ... @endverbatim
+\newenvironment{DoxyVerb}{%
+ \footnotesize%
+ \verbatim%
+}{%
+ \endverbatim%
+ \normalsize%
+}
+
+% Used by @verbinclude
+\newenvironment{DoxyVerbInclude}{%
+ \DoxyVerb%
+}{%
+ \endDoxyVerb%
+}
+
+% Used by numbered lists (using '-#' or <ol> ... </ol>)
+\newenvironment{DoxyEnumerate}{%
+ \enumerate%
+}{%
+ \endenumerate%
+}
+
+% Used by bullet lists (using '-', @li, @arg, or <ul> ... </ul>)
+\newenvironment{DoxyItemize}{%
+ \itemize%
+}{%
+ \enditemize%
+}
+
+% Used by description lists (using <dl> ... </dl>)
+\newenvironment{DoxyDescription}{%
+ \description%
+}{%
+ \enddescription%
+}
+
+% Used by @image, @dotfile, and @dot ... @enddot
+% (only if caption is specified)
+\newenvironment{DoxyImage}{%
+ \begin{figure}[H]%
+ \begin{center}%
+}{%
+ \end{center}%
+ \end{figure}%
+}
+
+% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
+% (only if no caption is specified)
+\newenvironment{DoxyImageNoCaption}{%
+}{%
+}
+
+% Used by @attention
+\newenvironment{DoxyAttention}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @author and @authors
+\newenvironment{DoxyAuthor}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @date
+\newenvironment{DoxyDate}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @invariant
+\newenvironment{DoxyInvariant}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @note
+\newenvironment{DoxyNote}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @post
+\newenvironment{DoxyPostcond}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @pre
+\newenvironment{DoxyPrecond}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @copyright
+\newenvironment{DoxyCopyright}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @remark
+\newenvironment{DoxyRemark}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @return
+\newenvironment{DoxyReturn}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @since
+\newenvironment{DoxySince}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @see
+\newenvironment{DoxySeeAlso}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @version
+\newenvironment{DoxyVersion}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @warning
+\newenvironment{DoxyWarning}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @internal
+\newenvironment{DoxyInternal}[1]{%
+ \paragraph*{#1}%
+}{%
+}
+
+% Used by @par and @paragraph
+\newenvironment{DoxyParagraph}[1]{%
+ \begin{list}{}%
+ {%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\itemsep}{-4pt}%
+ \renewcommand{\makelabel}{\entrylabel}%
+ }%
+ \item[#1]%
+}{%
+ \end{list}%
+}
+
+% Used by parameter lists
+\newenvironment{DoxyParams}[2][]{%
+ \begin{DoxyDesc}{#2}%
+ \item[] \hspace{\fill} \vspace{-40pt}%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\LTleft}{0pt}%
+ \setlength{\tabcolsep}{0.01\textwidth}%
+ \ifthenelse{\equal{#1}{}}%
+ {\begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.815\textwidth}|}}%
+ {\ifthenelse{\equal{#1}{1}}%
+ {\begin{longtable}{|>{\centering}p{0.10\textwidth}|%
+ >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.685\textwidth}|}}%
+ {\begin{longtable}{|>{\centering}p{0.10\textwidth}|%
+ >{\centering\hspace{0pt}}p{0.15\textwidth}|%
+ >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.515\textwidth}|}}%
+ }\hline%
+}{%
+ \end{longtable}%
+ \end{DoxyDesc}%
+}
+
+% Used for fields of simple structs
+\newenvironment{DoxyFields}[1]{%
+ \begin{DoxyDesc}{#1}%
+ \item[] \hspace{\fill} \vspace{-40pt}%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\LTleft}{0pt}%
+ \setlength{\tabcolsep}{0.01\textwidth}%
+ \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.15\textwidth}|%
+ p{0.635\textwidth}|}%
+ \hline%
+}{%
+ \end{longtable}%
+ \end{DoxyDesc}%
+}
+
+% is used for parameters within a detailed function description
+\newenvironment{DoxyParamCaption}{%
+ \renewcommand{\item}[2][]{##1 {\em ##2}}%
+ }{%
+}
+
+% Used by return value lists
+\newenvironment{DoxyRetVals}[1]{%
+ \begin{DoxyDesc}{#1}%
+ \begin{description}%
+ \item[] \hspace{\fill} \vspace{-25pt}%
+ \setlength{\tabcolsep}{0.01\textwidth}%
+ \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.77\textwidth}|}%
+ \hline%
+}{%
+ \end{longtable}%
+ \end{description}%
+ \end{DoxyDesc}%
+}
+
+% Used by exception lists
+\newenvironment{DoxyExceptions}[1]{%
+ \begin{DoxyDesc}{#1}%
+ \begin{description}%
+ \item[] \hspace{\fill} \vspace{-25pt}%
+ \definecolor{tableShade}{HTML}{F8F8F8}%
+ \rowcolors{1}{white}{tableShade}%
+ \arrayrulecolor{gray}%
+ \setlength{\tabcolsep}{0.01\textwidth}%
+ \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.77\textwidth}|}%
+ \hline%
+}{%
+ \end{longtable}%
+ \end{description}%
+ \end{DoxyDesc}%
+}
+
+% Used by template parameter lists
+\newenvironment{DoxyTemplParams}[1]{%
+ \begin{DoxyDesc}{#1}%
+ \begin{description}%
+ \item[] \hspace{\fill} \vspace{-25pt}%
+ \definecolor{tableShade}{HTML}{F8F8F8}%
+ \rowcolors{1}{white}{tableShade}%
+ \arrayrulecolor{gray}%
+ \setlength{\tabcolsep}{0.01\textwidth}%
+ \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.77\textwidth}|}%
+ \hline%
+}{%
+ \end{longtable}%
+ \end{description}%
+ \end{DoxyDesc}%
+}
+
+\newcommand{\doxyref}[3]{\textbf{#1} (\textnormal{#2}\,\pageref{#3})}
+\newcommand{\lcurly}{\{}
+\newcommand{\rcurly}{\}}
+\newenvironment{DoxyCompactList}
+{\begin{list}{}{
+ \setlength{\leftmargin}{0.5cm}
+ \setlength{\itemsep}{0pt}
+ \setlength{\parsep}{0pt}
+ \setlength{\topsep}{0pt}
+ \renewcommand{\makelabel}{\hfill}}}
+{\end{list}}
+\newenvironment{DoxyCompactItemize}
+{
+ \begin{itemize}
+ \setlength{\itemsep}{-3pt}
+ \setlength{\parsep}{0pt}
+ \setlength{\topsep}{0pt}
+ \setlength{\partopsep}{0pt}
+}
+{\end{itemize}}
+\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}
+\newlength{\tmplength}
+\newenvironment{TabularC}[1]
+{
+\setlength{\tmplength}
+ {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)}
+ \par\begin{xtabular*}{\linewidth}
+ {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|}
+}
+{\end{xtabular*}\par}
+\newcommand{\entrylabel}[1]{
+ {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{%
+ \usefont{OT1}{phv}{bc}{n}\color{darkgray}#1}\vspace{1.5\baselineskip}}}}
+\newenvironment{Desc}
+{\begin{list}{}
+ {
+ \settowidth{\labelwidth}{40pt}
+ \setlength{\leftmargin}{\labelwidth}
+ \setlength{\parsep}{0pt}
+ \setlength{\itemsep}{-4pt}
+ \renewcommand{\makelabel}{\entrylabel}
+ }
+}
+{\end{list}}
+\newsavebox{\xrefbox}
+\newlength{\xreflength}
+\newcommand{\xreflabel}[1]{%
+ \sbox{\xrefbox}{#1}%
+ \setlength{\xreflength}{\wd\xrefbox}%
+ \ifthenelse{\xreflength>\labelwidth}{%
+ \begin{minipage}{\textwidth}%
+ \setlength{\parindent}{0pt}%
+ \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}%
+ \end{minipage}%
+ }{%
+ \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}%
+ }}%
+\newenvironment{DoxyRefList}{%
+ \begin{list}{}{%
+ \setlength{\labelwidth}{10pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \addtolength{\leftmargin}{\labelsep}%
+ \renewcommand{\makelabel}{\xreflabel}%
+ }%
+ }%
+{\end{list}}
+\newenvironment{DoxyRefDesc}[1]
+{\begin{list}{}{%
+ \renewcommand\makelabel[1]{\textbf{##1}}
+ \settowidth\labelwidth{\makelabel{#1}}
+ \setlength\leftmargin{\labelwidth+\labelsep}}}
+{\end{list}}
+\newenvironment{Indent}
+ {\begin{list}{}{\setlength{\leftmargin}{0.5cm}}
+ \item[]\ignorespaces}
+ {\unskip\end{list}}
+\setlength{\parindent}{0cm}
+\setlength{\parskip}{0.2cm}
+\addtocounter{secnumdepth}{2}
+\usepackage[T1]{fontenc}
+\makeatletter
+\renewcommand{\paragraph}{\@startsection{paragraph}{4}{0ex}%
+ {-1.0ex}%
+ {1.0ex}%
+ {\usefont{OT1}{phv}{bc}{n}\color{darkgray}}}
+\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{0ex}%
+ {-1.0ex}%
+ {1.0ex}%
+ {\usefont{OT1}{phv}{bc}{n}\color{darkgray}}}
+\makeatother
+\allsectionsfont{\usefont{OT1}{phv}{bc}{n}\selectfont\color{darkgray}}
+\stepcounter{secnumdepth}
+\stepcounter{tocdepth}
+\definecolor{comment}{rgb}{0.5,0.0,0.0}
+\definecolor{keyword}{rgb}{0.0,0.5,0.0}
+\definecolor{keywordtype}{rgb}{0.38,0.25,0.125}
+\definecolor{keywordflow}{rgb}{0.88,0.5,0.0}
+\definecolor{preprocessor}{rgb}{0.5,0.38,0.125}
+\definecolor{stringliteral}{rgb}{0.0,0.125,0.25}
+\definecolor{charliteral}{rgb}{0.0,0.5,0.5}
+\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0}
+\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43}
+\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0}
+\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0}
diff --git a/doc/doxygen_logo.eps b/doc/doxygen_logo.eps
new file mode 100644
index 0000000..6539c3a
--- /dev/null
+++ b/doc/doxygen_logo.eps
@@ -0,0 +1,6322 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 634 197
+%%HiResBoundingBox: 0.000000 0.000000 634.000000 197.000000
+%.........................................
+%%Creator: GNU Ghostscript 705 (epswrite)
+%%CreationDate: 2002/09/28 21:44:36
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%EndComments
+%%BeginProlog
+% This copyright applies to everything between here and the %%EndProlog:
+% Copyright (C) 2002 artofcode LLC, Benicia, CA. All rights reserved.
+%%BeginResource: procset GS_epswrite_2_0_1001
+/GS_epswrite_2_0_1001 80 dict dup begin
+/PageSize 2 array def/setpagesize{ PageSize aload pop 3 index eq exch
+4 index eq and{ pop pop pop}{ PageSize dup 1
+5 -1 roll put 0 4 -1 roll put dup null eq {false} {dup where} ifelse{ exch get exec}
+{ pop/setpagedevice where
+{ pop 1 dict dup /PageSize PageSize put setpagedevice}
+{ /setpage where{ pop PageSize aload pop pageparams 3 {exch pop} repeat
+setpage}if}ifelse}ifelse}ifelse} bind def
+/!{bind def}bind def/#{load def}!/N/counttomark #
+/rG{3{3 -1 roll 255 div}repeat setrgbcolor}!/G{255 div setgray}!/K{0 G}!
+/r6{dup 3 -1 roll rG}!/r5{dup 3 1 roll rG}!/r3{dup rG}!
+/w/setlinewidth #/J/setlinecap #
+/j/setlinejoin #/M/setmiterlimit #/d/setdash #/i/setflat #
+/m/moveto #/l/lineto #/c/rcurveto #
+/p{N 2 idiv{N -2 roll rlineto}repeat}!
+/P{N 0 gt{N -2 roll moveto p}if}!
+/h{p closepath}!/H{P closepath}!
+/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}!
+/re{4 -2 roll m exch dup lx exch ly neg lx h}!
+/^{3 index neg 3 index neg}!
+/f{P fill}!/f*{P eofill}!/s{H stroke}!/S{P stroke}!
+/q/gsave #/Q/grestore #/rf{re fill}!
+/Y{P clip newpath}!/Y*{P eoclip newpath}!/rY{re Y}!
+/|={pop exch 4 1 roll 3 array astore cvx exch 1 index def exec}!
+/|{exch string readstring |=}!
+/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}!
+/@/currentfile #/${+ @ |}!
+/B{{2 copy string{readstring pop}aload pop 4 array astore cvx
+3 1 roll}repeat pop pop true}!
+/Ix{[1 0 0 1 11 -2 roll exch neg exch neg]exch}!
+/,{true exch Ix imagemask}!/If{false exch Ix imagemask}!/I{exch Ix image}!
+/Ic{exch Ix false 3 colorimage}!
+/F{/Columns counttomark 3 add -2 roll/Rows exch/K -1/BlackIs1 true>>
+/CCITTFaxDecode filter}!/FX{<</EndOfBlock false F}!
+/X{/ASCII85Decode filter}!/@X{@ X}!/&2{2 index 2 index}!
+/@F{@ &2<<F}!/@C{@X &2 FX}!
+/$X{+ @X |}!/&4{4 index 4 index}!/$F{+ @ &4<<F |}!/$C{+ @X &4 FX |}!
+/IC{3 1 roll 10 dict begin 1{/ImageType/Interpolate/Decode/DataSource
+/ImageMatrix/BitsPerComponent/Height/Width}{exch def}forall
+currentdict end image}!
+/~{@ read {pop} if}!
+end readonly def
+%%EndResource
+/pagesave null def
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+GS_epswrite_2_0_1001 begin
+/pagesave save store 100 dict begin
+0.1 0.1 scale
+%%EndPageSetup
+gsave mark
+K
+0 0 0 0 rf
+Q q
+0 0 250000 0 0 250000 ^ Y
+q[6340 0 0 1970 0 0]concat
+634 197 8[634 0 0 -197 0 197]@X false 3
+colorimage
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,rk/1.]_qcA
+r;N/?b*;hr`rH)=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r;OA/s8W#r]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.Rf*/Rr;N/_gkY.I\c;^0
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,rk/1.]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.]_qcA
+r;OA,rk/1.]_qbtr;OA,rgNcaRf*/tr;N/_rgNcaRf*/8r;M6EgkY+:X8MV0s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W#r]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.]_qcAr;OA,rk/1.Rf*/t
+r;OA,rgNcaRf*/Rr;N/_rdaq=Qi-i5r;N/_rk/1$Qi-3gs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,rk/1.]_qcA
+r;OA,rk/1.]_qcAr;N/_rk/1.]_qcAr;OA,rk/1.Rf*/tr;OA,rgNca]_qbtr;N/_rgNcaJGfD8
+r;M6ErgNcaRf*/tr;OA,rgNcWEW?(=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#rRf*/tr;N/_rk/1.]_qcAr;N/_rk/1.]_qcA
+r;OA,rgNca]_qbtr;OA,rk/1.Rf*/tr;N/_rk/1.Rf*/8r;N/_rdaqGJGfD8r;N/_rk/1.Rf*/R
+r;M6Hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r;OA,rk/1.]_qcAr;N/_rk/1.]_qcAr;N/_rk/1.]_qcAr;OA,rgNca]_qbt
+r;OA,rgNcaRf*/Rr;N/_rgNcaJGfD8r;M6ErdaqG]_qcAr;N/_rgNcaJGfDZs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#rRf*/t
+r;N/_rk/1.]_qcAr;OA,rgNca]_qcAr;N/_rk/1.Rf*/tr;OA,rgNcaRf*/tr;N/_rk/1.Rf*/8
+r;N/_rdaqGJGfCsr;N/_rk/1.]_qbZr;M6Hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,rk/1.Rf*/tr;OA,rk/1.Rf*/t
+r;OA,rgNca]_qcAr;N/_rk/1.Rf*/tr;N/_rgNcaRf*/Rr;N/_rdaqGJGfD8r;M6ErgNcaRf*/t
+r;N/_rdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W#r]_qbtr;OA,rk/1.Rf*/tr;OA,rk/1.]_qcAr;OA,rk/1.Rf*/t
+r;N/_rgNca]_qbtr;OA,rgNcaRf*/8r;M6ErgNcaJGfCsr;N/_rgNcaRf*/8r;M6Hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r;N/_rk/1.Rf*/tr;OA,rgNca]_qbtr;OA,rgNca]_qbtr;OA,rgNca]_qbtr;N/_rgNcaRf*/R
+r;N/_rdaqGRf*/8r;N/_rdaqG]_qcAr;N/_rdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#rRf*/tr;OA,rk/1.Rf*/t
+r;OA,rk/1.Rf*/tr;OA,rk/1.Rf*/tr;N/_rgNcaRf*/tr;N/_rgNcaRf*/8r;M6ErgNcaJGfCs
+r;N/_rgNcaRf*/8r;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq>^Kpr;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/tr;OA,rgNcaRf*/t
+r;N/_rk/1.Rf*/tr;N/_rgNcaRf*/Rr;N/_rdaqGJGfD8r;M6ErgNcaRf*/tr;N/_rdaqGJH,ZL
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Yrk/1.]_qcAr;OA,rgNca]_qcAr;N/_rk/1.Rf*/tr;OA,rgNca]_qbtr;OA,rgNcaRf*/R
+r;N/_rgNcaRf*/8r;M6ErdaqGRf*/8r;N/_rgNcaRf*/8r;M6Erk/:2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_JAp&G'lr;N/_rgNca]_qcA
+r;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/Rr;OA,rgNcaRf*/Rr;M6ErdaqGJGfD8
+r;M6ErdaqG]_qbtr;N/_rdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d9oZ$h.Rf*/tr;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/t
+r;N/_rk/1.]_qbtr;OA,rgNcaRf*/Rr;N/_rgNcaRf*/8r;M6ErgNcaJGfCsr;N/_rgNcaJGfCs
+r;N/_rk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkPXtlr;OA,rgNca]_qbtr;OA,rgNca]_qbtr;OA,rgNca]_qbtr;OA,rgNca]_qbt
+r;N/_rgNcaRf*/Rr;M6ErdaqGJGfD8r;M6ErdaqGRf*/Rr;M6ErdaqGJGfDZs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d9oZ$h.Rf*/t
+r;N/_rk/1.Rf*/tr;N/_rgNca]_qbtr;OA,rgNca]_qcAr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/8
+r;M6ErgNcaJGfCsr;N/_rdaqGRf*/8r;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkPXtlr;OA,rgNca]_qbtr;OA,rgNca]_qbt
+r;N/_rk/1.Rf*/tr;N/_rgNca]_qbtr;N/_rgNcaRf*/Rr;M6ErdaqGJGfD8r;M6ErdaqGRf*/R
+r;M6ErdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726kj7d9oZ$h.Rf*/Rr;N/_rgNca]_qbtr;N/_rgNca]_qbtr;OA,rgNca]_qcA
+r;N/_rgNca]_qbtr;N/_rgNcaRf*/8r;N/_rdaqGJGfCsr;N/_rdaqGJGfCsr;M6Erk/:2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n,2gt
+r;OA,rgNca]_qbtr;N/_rk/1.Rf*/tr;N/_rgNca]_qbtr;OA,rgNca]_qbtr;N/_rgNcaRf*/R
+r;N/_rdaqGRf*/8r;M6ErdaqGJGfCsr;N/_rdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVi8j)!oZ$h.Rf*/tr;N/_rk/1.Rf*/R
+r;N/_rgNca]_qbtr;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/tr;N/_rk/1.Rf*/8r;M6ErgNcaJGfCs
+r;N/_rdaqGJGfCsr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kOeKDr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/t
+r;N/_rk/1.Rf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/8r;M6ErdaqGJGfCsr;M6ErdaqGJGfDZ
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+kj7d9oZ$h.Rf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/Rr;OA,rgNca]_qbt
+r;OA,rgNca]_qbZr;N/_rgNcaJGfCsr;M6ErdaqGJGfCsr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n,2gtr;N/_rgNcaRf*/R
+r;N/_rgNcaRf*/Rr;N/_rgNcaRf*/Rr;OA,rgNca]_qbtr;OA,rgNcaRf*/tr;N/_rdaqGRf*/8
+r;N/_rdaqGJGfCsr;M6Erdaq=EW#gKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<kj7d9oZ$h.Rf*/Rr;N/_rgNcaRf*/8r;N/_rgNcaJGfD8
+r;N/_rgNcaRf*/Rr;OA,rgNcaRf*/tr;N/_rgNcaRf*/Rr;N/_rgNcaJGfCsr;M6EoPsg.JGfCs
+r;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n,2Ojr;N/_rdaqGRf*/8r;N/_rgNcaJGfD8r;M6ErgNcaJGfD8r;N/_rgNcaRf*/R
+r;OA,rgNcaRf*/tr;N/_rdaqGJGfCsr;M6ErdaqGJGfCsr;M6Erdaq=EW#gKs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<kj7d9oZ$h.JGfD8
+r;M6ErgNcaJGfCsr;N/_rdaqGRf*/8r;N/_rdaqGRf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/8
+r;N/_rdaqGJGfD8r;M6EoPsg.JGfCsr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*q=n+Z23r;M6ErgNcaJGfD8r;M6ErgNcaJGfCs
+r;M6ErgNcaJGfD8r;N/_rgNcaRf*/Rr;N/_rgNca]_qbtr;N/_rgNcaJGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726kj7d9oZ$h.JGfCsr;N/_rdaqGJGfCsr;M6ErgNcaJGfCsr;N/_rdaqGRf*/R
+r;N/_rgNcaRf*/Rr;N/_rgNcaRf*/8r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6Erk/:2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kPXtl
+r;N/_rdaqGJGfD8r;M6ErgNcaJGfCsr;M6ErgNcaJGfD8r;M6ErgNcaRf*/Rr;N/_rgNcaRf*/R
+r;N/_rdaqGJGfCsr;N/_rdaqGJGfCsr;M6ErdaqGJGfDZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d9oZ$h.Rf*/8r;N/_rdaqGJGfCs
+r;M6ErdaqGRf*/8r;M6ErdaqGRf*/Rr;N/_rgNcaRf*/Rr;N/_rgNcaRf*/8r;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n,2Ojr;M6ErgNcaJGfCsr;N/_rdaqGRf*/8r;M6ErgNcaRf*/8
+r;N/_rdaqGRf*/Rr;N/_rgNcaRf*/Rr;N/_rdaqGJGfCsr;M6Erdaq=EW#HKr;M6ErdaqGJGfDZ
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<
+kj7d9oZ$h.JGfCsr;M6ErgNcaJGfCsr;M6ErdaqGRf*/8r;M6ErgNcaRf*/Rr;M6ErgNcaRf*/R
+r;N/_rgNcaRf*/8r;M6ErdaqGJGf%Zr:G",oPsg.JGfCsr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kPXtlr;N/_rdaqGJGfCs
+r;M6ErgNcaJGfD8r;M6ErgNcaJGfD8r;M6ErgNcaRf*/Rr;M6ErgNcaRf*/Rr;M6ErdaqGJGf%Z
+r;M6EoPsg$EW#fdr;M6Erdaq=EW#gKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d9oZ$h.JGfCsr;M6ErdaqGJGfCsr;N/_rdaqGJGfD8
+r;M6ErgNcaJGfD8r;M6ErgNcaRf*/Rr;M6ErgNcaJGfCsr;M6Erdaq=EW#HKr:G",oPsg.JGfCs
+r;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA*q=n,2Ojr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;N/_rdaqGJGfD8r;N/_rgNcaRf*/R
+r;M6ErgNcaRf*/Rr;M6Erdaq=EW#HKr:G",oPsg$EW#HKr;M6Erdaq=EW#gKs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<kj7d9m)8i$JGfCs
+r;M6ErdaqGJGfCsr;N/_rdaqGJGfCsr;N/_rdaqGJGfD8r;M6ErgNcaJGfD8r;M6ErdaqGJGf%Z
+r;M6EoPsg$EW#HKr:G",rdaq=EW#HKr;M6Erk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n,2Ojr;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;N/_rdaqGRf*/8r;N/_rdaqGRf*/8r;N/_rdaqGRf*/Rr;M6Erdaq=EW#HKr8qbloPsg$EW#HK
+r;M6EoPsg$EW#gKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726kj7d9m)8i$JGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfD8r;M6ErgNcaJGfD8
+r;M6ErgNcaJGfCsr;M6ErdaqGJGf%Zr:G",oPsfkCAd^Dr:G",rdaq=EW#HKr:G",rk/:2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*q=n,2Oj
+r;M6ErdaqGJGfCsr;M6ErdaqGRf*/8r;N/_rdaqGRf*/8r;N/_rdaqGJGfCsr;N/_rdaqGRf*/8
+r;M6EoPsg$EW#HKr8qblk%ahdEW#HKr;M6EoPsfqG5V?Ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d9m)8i$JGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGRf*/8r;N/_rdaqGJGfCsr;N/_rdaqGJGfCsr;M6ErdaqGJGf%Zr:G",k%ahVCAd4/
+r:G",oPsg$EW#HKr8qblrk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n,2Ojr;M6ErdaqGJGfCsr;M6ErdaqGRf*/Rr;M6ErgNcaJGfCs
+r;M6ErdaqGJGfCsr;N/_rdaqGRf*/8r;M6EoPsg$EW"s6r8qblk%ahdEW#HKr:G",oPsg$EW#gK
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<
+kj7d9m)8i$JGfCsr;M6ErdaqGJGfD8r;M6ErdaqGRf*/8r;M6ErgNcaJGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGJGebWr:G",k%ahVCAd4/r8qbloPsg$EW#HKr8qblrk/:2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n,2Ojr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfD8r;M6ErgNcaJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfD8r;M6EoPsfkCAd4/
+r8qblk%ahdEW#HKr:G",oPsfqG5V?Ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d9m)8i$JGfCsr;M6ErdaqGJGfD8r;M6ErgNcaJGfCs
+r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGf%Zr8qblk%ahVCAd4/r8qbloPsg$EW#HK
+r9SV)rk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n,2Ojr;M6ErdaqGJGfCsr;M6ErdaqGRf*/8r;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6EoPsfkCAd4/r8qblk%ahVCAd^Dr9SV)lur=!EW#IKs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d9m)8i$JGfCs
+r;M6ErdaqGJGfD8r;M6ErdaqGJGfD8r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;N/_rdaqGJGf%Z
+r8qblk%ahLB)Le+r8qbloPsg$EW#HKr9SV)rk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kPX\br;M6ErdaqGJGfCsr;M6ErdaqGRf*/8
+r;N/_rdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6Elur<hCAd4/r8qblk%ahVCAd^D
+r9SV)oPsg$EW#IKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gkj7d9m)8i$JGfCsr;M6ErdaqGJGfD8r;M6ErgNcaJGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6ErdaqGJGf%Zr8qblk%ahVCAd4/r8qbloPsfqG5UuPr9SV)rk/:2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kPX\b
+r;M6ErdaqGJGfCsr;M6ErdaqGJGfD8r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;M6Ek%ahVCAd4/r7ko^k%ahVCAdFAr9SV)oPsg$EW#IKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d9m)8i$JGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGRf*/8r;N/_rdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGebWr8qblk%ahVCAd4/
+r8qbloPsfqG5UuPr8qblrk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kPX\br;M6ErdaqGJGfCsr;M6ErdaqGRf*/8r;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6Ek%ah\G5UK;r8qblk%ah\G5U]Mr9SV)oPsfkCAe(D
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+kj7d9m)8i$JGfCsr;M6ErdaqGJGfCsr;M6ErdaqGRf*/8r;N/_rdaqGRf*/8r;M6ErdaqGJGfCs
+r;M6ErdaqGJGePEr8qblgh-KHCAdFAr8qbllur<nG5U]Mr8qbloZ$q2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kPX\br;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6ErdaqGRf*/8r;M6ErdaqGRf*/8r;M6ErgNcaJGfCsr;M6Ek%ah\G5UK;
+r8qblk%ah\G5UK;r9SV)oPsfkCAd^js8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d9m)8i$JGfCsr;M6ErdaqGJGfCsr;M6ErdaqGRf*/8
+r;M6ErgNcaJGfD8r;M6ErdaqGJGfCsr;M6ErdaqGJGePEr8qblgh-KHCAdFAr9SV)k%ah\G5UK;
+r7ko^oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_&&kPX\br;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErgNcaJGfCsr;N/_rdaqGJGfD8
+r;M6ErgNcaJGfCsr;M6Ek%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahLB)M:fs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVi8j)!m)8i$JGfCs
+r;M6ErdaqGJGfCsr;M6ErgNcaJGfCsr;N/_rdaqGJGfD8r;M6ErgNcaJGfCsr;M6Erdaq=EW"s6
+r7ko^gh-KHCAd4/r8qblk%ahVCAd4/r7ko^oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kPX\br;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;M6ErgNcaJGfCsr;N/_rdaqGJGfCsr;N/_rdaqGJGfCsr;M6Egh-K>B)LFrr8qblk%ahVCAck!
+r8qblk%ahLB)M:fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp%7tRi8j)!m)8i$JGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;N/_rdaqGJGfCs
+r;N/_rdaqGJGfCsr;M6ErdaqGJGe27r7ko^gh-K>B)LFrr8qblgh-K>B)Le+r7ko^oZ$q2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kPX\b
+r:G",rdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;N/_rdaqGJGfCsr;M6ErdaqGJGfCs
+r:G",k%ahD at JnV`r7ko^gh-K>B)LFrr7ko^k%ahLB)M:fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d8jMCcnJGf%Zr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;N/_rdaqGJGfCsr;M6ErdaqGJGfCsr;M6Erdaq=EW"<pr7#0Qe7&:)@Jnnm
+r7ko^e7&:1B)LFrr7ko^oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kPO>Vr:G",rdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr:G",e7&:)@Jn>Tr7#0Qe7&:)@JnV`r7#0Qgh-K6 at Joc;
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+kj7d9m)8hoEW#HKr:G",oPsg.JGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr;M6ErdaqGJGfCs
+r;M6Erdaq=EW"<pr6/IEb[(.j?2VoPr7#0Qb[(.r at JnV`r7ko^oZ$q2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n,)1^r:G",oPsg$EW#HK
+r:G",oPsg.JGf%Zr;M6ErdaqGJGfCsr;M6ErdaqGJGfCsr:G",rdaq=EW#HKr9SV)e7&:!?2VoP
+r6/IEb[(.j?2VoPr6/IEe7&:)@JoGZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j)!m)8haCAd4/r:G",oPsg$EW#HKr:G",oPsg$EW#HK
+r:G",oPsg.JGfCsr;M6EoPsg$EW#HKr:G",oPsfkCAc:]r5;b9b[(.b=o?3 at r6/IE`**#^?2VoP
+r7#0QoZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n,)1^r8qblk%ahdEW#0Hr:G",oPsg$EW#HKr:G",oPsg$EW#HKr:G",oPsg$EW#HK
+r:G",oPsfqG5UuPr8qbl`**#V=o>p3r5;b9]N"gI=o?3 at r5;b9`**#^?2X?7s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVi8j(ujMCcVCAd4/
+r8qblk%ah\G5U]Mr9SV)lur<nG5U]Mr9SV)lur=!EW#HKr9SV)oPsfqG5UuPr8qbllur<^B)K;@
+r5;b9`**#V=o>p3r5;b9]N"gA<;a[;r6/IEm)8r(s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n,)1^r8qblk%ahVCAd4/r8qblk%ahVCAd4/
+r8qbllur<hCAdFAr9SV)lur<nG5U]Mr9SV)k%ah\G5UK;r7ko^]N"gI=o>p3r4H#,]N"gI=o>p3
+r4H#,]N"gQ?2X#Vs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+(Hp#tc2i8j(tgopY2B)LFrr8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAdFA
+r8qblk%ahVCAd4/r8qblk%ahD at Jmc;r5;b9]N"gA<;a+"r4H#,]N"gA<;aC.r5;b9m)8r(s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W#r]`8$3s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;l/r:J#,oU#LARJcDpr9KdKl^@\:RJc]D
+r:J#,oZ$h$`r,JKs8W,soZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o.jQGI^kPEu;
+r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^k%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahLB)Le+
+r7#0Q]N"gA<;aC.r4H#,Zr$\5<;a+"r3T;uZr$\5<;c'Ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#rRf)fEr8qblk%ahVCAd4/
+r8qblk%ahVCAd4/r9SV)lur<mRJc]Dr:J#,oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA/s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8;l/r;OA/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,soZ$gaL]#Y1r7#0Qe7&:)@Jnnmr7ko^e7&:)@Jnnmr7#0Qgh-K>B)LFrr8qblgh-K6 at Jn>T
+r5;b9]N"gA<;a[;r4HkDc%GrDM#,o1qrGTfm-!U!n)39ig"bH\gopY2B)LFrr7ko^gh-K6 at Jnnm
+r7#0Qgh-K>B)LFrr7ko^gh-K>B)LFrr8qblgh-K>B)LFrr7ko^gh-K.?2V'+r3T;u]N"g9;#ICg
+r4H#,Zr$\%9`1tcr3T;um)8r(s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r;OA,lur<hCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/
+r8qblk%ahLB)LFrr7#0Q`**#N<;a[;qV8:PoZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r:H?Rk%ahD at JmK/r4H#,e;4%p`rH)=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;kbr:G",lur=!QiI*cs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,srk/1.Rf)et
+r9SV)lur<nG5V!Ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,soZ$gQ?2Wi"r9SV)rgNles8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,rk/1.]_qcAr;OA/s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;N/r9VAugopS0YPdFS
+r9KdKlur<nG5UK;r9SV)lur<hCAd4/r8qblk%ah\G5V!!r;N/bs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o:oC_JAp$D;C
+m.9oBpA+(Hp%7tRs8W,kpA+ at Sq=j7=r9VB"m)8e^_>;rjqV8:Pj.ZD2U&=5Er9KdKlur<nG5UK;
+r9SV)lur<nG5V!!r;OA/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r9KdKe7&9n=o?KLr6/IEb[(.j?2W2\
+r7#0Qe7&:)@JnV`r7ko^e7&:)@Jnnmr7ko^gh-K>B)LFrr8qblgh-K>B)LFrr6/IE]N"g9;#ICg
+r2`TiUe(Eb9`1\Wr3T;u]PQfTX8:&;r7#0Qe7&:)@JnV`r7#0Qe7&:1B)L.er7ko^e7&:1B)LFr
+r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr6/IEZr$\-;#I[sr3T;uXA&Q!;#I[sr2`TiXA&Q!;#K at I
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;l/r8qblk%ahVCAck!
+r8qblgh-K>B)LFrr8qblk%ahLB)Le+r7ko^gh-KHCAck!r7ko^k%ahLB)LFrr7ko^gh-K>B)LFr
+r7ko^b[(.Z<;`gkr2`Ti`*)rlYQ+Y&s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r:G",k%ahVCAd4/
+r8qbl`**#>9`1tcr4H#/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,slur<nG5U]M
+r:G",k%ahSU&Y/ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;N/_lur<hCAd4/r8qblk%ahVCAd4/r8qblgh-Tds8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s89f<r7#0Qgh-K>B)LFrr7ko^k%ahdEW#gKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r;OA,rk/1$EW#0Hr9SV)lur<nG5U]Mr9SV)lur<nG5UuPr:G",lur=!EW#HKr:H?RrgNca]_qcA
+r;OA/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVqrGTigopRnM>Y"cr2`TiZr$\==o@&er9SV)lur<hCAdFAr9SV)k%ahVCAdFA
+r8qblk%ahVCAd4/r8qbllur<nG5UuPr:G",oPsg.]_qcAs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r9VB"m)8hg`;AW3r9KdKl^@\2U&=5Er9KdKlur<nG5U^Fkj7crjQGd\\bag[qSe<h]PRMQ;#ICg
+r3T;uXA&Pn9`27or5;b9e7&:;CAd4/r9SV)k%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/
+r8qbloU#LT]`8$3s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;6%r6/IE`**#V=o?3 at r5;b9]N"gI=o?KLr5;b9b[(.j?2VoPr7#0Qe7&:)@JnV`
+r7ko^e7&:1B)LFrr7ko^e7&:1B)LFrr7#0Qgh-K6 at JnV`r5;b9Zr$\%9`1\Wr1lm]Ue(ER6N!WM
+r1lm]Zr$\E?2W2\r6/IEe7&:)@JnV`r7#0Qe7&:1B)L.er7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r7#0Qe7&9n=o>?pr3T;uZr$\%9`1tcr2`TiUe(EZ8Go8Sr2`ThjMClrs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W#r]_po,r7ko^gh-K>B)L.er7ko^gh-K>B)LFrr7ko^gh-K>B)LFr
+r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7#0Qe7&:)@Jnnmr7#0Qe7&9n=o>?p
+r1lm]XA&Q)<;PCRs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r9SV)k%ahVCAd4/r8qblk%ahVCAd4/r3T;uXA&Pn9`2h3
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#`G5UK;r9SV)k%ahVCAdFAr9SV)k%ah[RK*<e
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#r]_qDg
+r8qblk%ahVCAd4/r7ko^k%ahLB)Le+r7ko^k%ahVCAck!r:J#/s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qrGTk`**#nB)LFr
+r7ko^gh-K>B)LFrr7ko^k%ahVCAdFAr;N/bs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sm)8h^U&=5Er9SV)oPsg$EW#HKr9SV)lur<nG5U]M
+r8qblk%ah\G5U]Mr9SV)lur<hCAdFAr9SV)lur<nG5U]Mr9SV)lur<nG5U]Mr:G",lur<nG5U]M
+r:G",oU#LJQi-iOr;OA,rk/1.]_qcAr;OA/s8W#r]`8$3s8W,srk/:2s8;l/s8W,srk/1.]_qcA
+r;OA,rgNles8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n+thCqSe<hZr$\%9`1tc
+r3T;u`**#nB)Le+r9SV)k%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/
+r9SV)lur<nG5U]Mr9SV)lur<nG5V!!r;OA/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+\s8V`bq=OCVm.9o:oC_JAp$D;C
+m.9oBpA+ at Sq=j7=r9VB!jMC`S_>N>er8XLKgkYg_L]#Y1r7#0Qgh-KHCAd4/r9SV)lur<hCAdFA
+r9SV)lur<hCAd4/r9SV)e;4"/Er<:@r2`TiXA&Q!;#ICgr3T;uXA&Pn9`2h3r7#0Qk%ahVCAd4/
+r8qblk%ahVCAd4/r8qblgh-K>B)LFrr7ko^gh-K>B)Le+r7ko^k%ahLB)Le+r7ko^lur=!`rH)=
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8:oNr5;b9]N"gI=o>p3
+r4H#,]N"gA<;a[;r4H#,`**#V=o?KLr6/IEb[(.r at JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:1B)L.e
+r7#0Qe7&:)@JnV`r7#0Qe7&:!?2VoPr4H#,Ue(EZ8Go8Sr1lm]S3m.D6N!oYr6/IEb[(.j?2VoP
+r6/IEb[(.r at JnV`r6/IEe7&:)@Jn>Tr7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r5;b9XA&Pn9`1tc
+r2`TiXA&Pn9`1\Wr1lm]S3m.L8GqMAs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#hQi,WN
+r7ko^e7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:1B)LFrr7ko^gh-K>B)LFrr7ko^e7&:)@Jnnm
+r7#0Qgh-K>B)L.er7#0Qe7&:)@JnV`r7#0Qb[(.r at JnV`r6/IEe7&9n=o>?pr1$+OUe(Eb9`2P>
+r:J#/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;l/
+r9SV)gh-K>B)LFrr7ko^k%ahLB)Le+r7ko^k%ah<?2Uctr1lm]Zr$\\U&Y/ms8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;5,r8qblk%ahVCAd4/r8qblk%ah\G5UK;r8qblgh-KMRK*<es8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;OA,oU#LBG5UK;r8qblk%ahVCAd4/r7ko^gh-K>B)LFr
+r7ko^gh-K>B)L.er7ko^gh-K6 at K6B-s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#0D#DL_r7ko^e7&:1B)LFrr7#0Qgh-K>B)LFr
+r7ko^k%ahLB)Le+r8qbllur=+]`8$3s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+qV8:Pe;4%P at JoJ8r9SV)lur<nG5U]Mr9SV)lur<nG5UK;r8qblk%ahVCAd4/r8qblk%ahVCAd4/
+r9SV)k%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r9SV)k%ah\G5U]M
+r9SV)lur<nG5U]Mr9SV)k%ahVCAdFAr9SV)lur<hCAdFAr9SV)lur<hCAd^js8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVm.9o6m-j2l\ba:%r3T;uUe(Eb9`1tcr4H#,e7&:;CAdFAr9SV)k%ahVCAd4/
+r8qblk%ahVCAd4/r8qblgh-KHCAck!r7ko^gh-K>B)LFrr8qblk%ahVCAdFAr9SV)lur<hCAd4/
+r8qblk%ahLL]$L^r:H?Us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVm.9o:oC_JAp#tc2l.NWCgsP?/X89elqSe<h]SQHlEr<:@r2`TiUe(Er<;bln
+r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblgkYgoG5UK;r8qblk%ahVCAd4/r8qblk%ahVCAb_D
+r2`TiXA&Pn9`1tcr2`TiXA&Pn9`27or7ko^k%ahVCAd4/r7ko^gh-K>B)LFrr7ko^e7&:1B)LFr
+r7ko^gh-K6 at Jnnmr7ko^e7&:1B)LFrr7ko^gh-K>B)LFrr7ko^k%ah\`;fl;s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8:Z-r4H#,]N"gA<;aC.r4H#,]N"gA<;a[;r4H#,]N"gA<;a[;
+r5;b9`**#^?2VWDr6/IEb[(.r at JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@Jn>Tr6/IEb[(.j?2VoP
+r5;b9b[(.b=o?3 at r2`TiS3m.D6N!WMr1$+OUe(F%=o?3 at r6/IEb[(.j?2VoPr6/IEb[(.j?2VoP
+r5;b9b[(.j?2VoPr6/IEb[(.j?2VoPr6/IEb[(.b=o>?pr2`TiXA&Pn9`1DIr2`TiS3m.D6N!??
+r1$+NjMClrs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#_RJbQCr7#0Qb[(.r at Jn>Tr6/IEe7&:!?2VoP
+r6/IEe7&:!?2W2\r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IEe7&9f<;`gkr1$+OUe(EZ8GohkqV8:Ss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;l/r7m)*gh-K6 at Jnnmr7ko^gh-K>B)LFr
+r7ko^gh-KHCAck!r7ko^]N"g)8Go8Sr3T<#s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r9KdKgh-K>B)LFr
+r8qblgh-KHCAd4/r8qbllur<hCAdFAr7m)*e7&:8U&Y/ms8W-!s8W-!s8W-!s8W-!s8W-!s8;MU
+r8qblk%ahVCAd4/r8qblk%ahVCAd4/r7ko^gh-K6 at Jnnmr7#0Qe7&:)@Jn>Tr7#0Qe7&:)@JnV`
+r7#0QoZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCV
+o_/+QpA+ at Sq>/mMr4H#,e7&:1B)L.er7#0Qe7&:)@Jnnmr7ko^gh-K>B)LFrr7ko^gh-K>B)LFr
+r7ko^k%ah\G5V?.s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8(NSqSe<h`**#nB)Le+r9SV)k%ahVCAdFA
+r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAck!r7ko^k%ahLB)LFr
+r8qblgh-KHCAck!r8qblgh-KHCAck!r8qblgh-K>B)Le+r8qblk%ahVCAdFAr8qblk%ahVCAd4/
+r8qblk%ahVCAd4/r8qblk%ah\G5UK;r9SV)rk/:2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp$D;Cm.9o.jQHB`VYd`@
+r1lm]XA&Pf8GoP_r4H#,gh-KHCAd4/r8qblk%ahVCAd4/r8qblk%ahVCAd4/r8qblk%ahLB)LFr
+r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr8qbllur<hCAd4/r8qblk%ahLB)Le+r8qblgh-KHCAd4/
+r9SV,s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o6m-j0)n)39i
+i8j(t`JOMo9`1\Wr1$+OUe(EZ8Go8Sr2`TiUe(EZ8Go8Sr4H#,gh-K>B)LFrr8qblgh-KHCAck!
+r8qblgh-KHCAd4/r8qblk%ahLL]$:Lr7m)*k%ahLB)Le+r8qbl]N"g19`1\Wr2`TiXA&Pn9`1\W
+r6/IEgh-KHCAck!r7ko^gh-K>B)LFrr7#0Qgh-K6 at Jnnmr7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r7ko^gh-K>B)L.er7#0Qgh-K6 at JnV`r7ko^gh-KV`rH)=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8:Z-
+r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,]N"gA<;a[;r5;b9`**#V=o?KL
+r6/IEb[(.j?2W2\r6/IEb[(.j?2VoPr6/IEb[(.b=o?3 at r5;b9`**#V=o?3 at r4H#,`**#N<;a+"
+r1$+OS3m.D6N!WMr5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#^?2VWD
+r6/IEb[(.b=o?KLr4H#,Ue(EZ8Go8Sr1$+OS3m.L8GnuEr1$+OS3m.D6N#l;s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W#_RJbQCr6/IEb[(.j?2VoPr6/IEb[(.j?2VWDr6/IE`**#^?2VWDr6/IEb[(.j?2VoP
+r7#0Qe7&:!?2W2\r7#0Qe7&:!?2W2\r7#0Qe7&:!?2VoPr6/IEb[(.j?2VoPr5;b9b[(.j?2VoP
+r6/IE`**#^?2VWDr5;b9`**#F;#HhMr1$+OPX55C8GoP_qV8:Ss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;N/r7#0Qb[(.r at JnV`r7#0Qe7&:)@JnV`r7ko^gh-K>B)LFrr7ko^gh-K>B)L.e
+r2`TiS3m.L8Gp,:s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Ym)8hO at JnV`r7#0Qgh-K6 at Jnnmr7ko^gh-K>B)Le+
+r7ko^k%ahVCAd4/r7ko^e7&78_>jQ8s8W-!s8W-!s8W-!s8W,sgh-K>B)LFrr7m)*gh-K>B)L.e
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r6/IEe7&:!?2VoPr6/IEb[(.j?2W2\s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o6m-j0)n*'-,kj7d9]PRMa=o?cX
+r7#0Qe7&:)@JnV`r7#0Qe7&:1B)LFrr7ko^gh-K6 at Jnnmr7ko^gh-K>B)LFrr7ko^gh-KHCAd4/
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8Vi[kPE]4r3T;u`**#nB)Le+r8qblk%ahVCAd4/r8qblk%ahVCAd4/r7ko^k%ahLB)Le+
+r8qblgh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFr
+r7ko^gh-K6 at Jnnmr7ko^gh-K>B)LFrr8qblgh-KHCAd4/r7ko^k%ahLB)Le+r8qblk%ahVCAd4/
+r8qblk%ahVCB+>6s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp$D;Ckj7crjQHBYM>X/?r1lm]Ue(ER6N!WMr4H#,e7&:;CAck!
+r8qblgh-K>B)Le+r7ko^k%ahLB)LFrr7ko^gh-K>B)LFrr8qblgh-KHCAck!r7ko^gh-K>B)LFr
+r7ko^gh-KHCAd4/r7m)*k%ahVCAck!r7ko^gh-K>B)Le+r7ko^gh-KHCAck!r9KdNs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mm.9o6m-ilnkLnYIg"bH;gtp`>hXA+;r1lm]S3m.D6N!??
+r1$+OUe(EZ8GnuEr1$+OS3m.d<;bN`r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFr
+r8qblk%ahVCAck!r7m)*k%ahLB)K;@r1lm]Ue(Eb9`1DIr3T;ue7&:;CAd4/r7ko^gh-K6 at JnV`
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qb[(.j?2W2\r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r7#0Qe7&:!?2W2\r7#0Qj.ZMQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8:oNr5;b9]N"gA<;aC.r4H#,]N"g9;#I[s
+r3T;uZr$\-;#I[sr3T;u]N"gA<;aC.r5;b9]N"gA<;a[;r5;b9`**#V=o?3 at r6/IE`**#^?2VoP
+r5;b9`**#V=o?3 at r5;b9`**#V=o>p3r4H#,]N"gA<;a+"r4H#,]N"g9;#HhMr00MFS3m.d<;aC.
+r4H#,`**#N<;a[;r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,`**#V=o?3 at r5;b9`**#F;#I+[
+r1$+OUe(ER6N!??r1$+OPX4o!2Z/e*r1$+MgopbXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#h`r+)6r6/IEb[(.j?2VWD
+r5;b9`**#V=o?3 at r5;b9`**#V=o>p3r5;b9]N"gI=o?3 at r5;b9b[(.b=o?3 at r6/IE`**#^?2VoP
+r6/IEb[(.j?2VoPr6/IEb[(.b=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9`**#>9`1DIr00MFPX55;6N!WMqrGTns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;6%r7#0Q`**#^?2VoP
+r6/IEb[(.j?2VoPr7#0Qe7&:)@JnV`r7m)*e7&:1B)L.er7ko^gh-K&=o=dVr1$+OUe(CD_>jQ8
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-j]8kPWSWr7#0Qb[(.r at JnV`r7#0Qe7&:)@Jnnmr7ko^gh-K>B)L.er7ko^e7&:1B)LFr
+r7#0Q`*)rlYQ+Y&s8W-!s8W-!s8:Z-r7#0Qgh-K6 at JnV`r7#0Qe7&:)@JnV`r6/IEe7&:!?2VoP
+r6/IEb[(.j?2VWDr6/IEb[(.j?2VoPr6/IE]N"q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7d%m-ilnkMYFai8j(ZjQG[Lao&56r6/IEb[(.r at Jn>Tr7#0Qe7&:)@Jnnm
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qgh-K6 at Jnnmr7ko^oZ$q2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vi[kPE/Sr2`Ti]N"gaB)Le+
+r7ko^gh-K>B)LFrr7ko^gh-K6 at Jnnmr7#0Qgh-K6 at Jnnmr7ko^e7&:1B)L.er7ko^e7&:1B)LFr
+r7ko^e7&:1B)L.er7ko^e7&:)@JnV`r7#0Qe7&:1B)L.er7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r7#0Qgh-K>B)LFrr7ko^gkYg_B)Le+r7m)*k%ahLB)LG>r7ko^gh-KHCAckBr9SV,s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp$D;C
+kj7d#gt_h?M#=&>r1$+OS3m.D6N!??r2`Tie7&:1B)LFrr7ko^k%ahLB)LFrr7ko^gh-K>B)LFr
+r7ko^gh-KHCAck!r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7#0Qgh-K>B)LFrr7ko^gh-KHCAck!
+r7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr7ko^gh-K>B)LFrr:J#/s8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o:oC_&&kMYFag"bH;gtpK/f$`(!daZk:]T2o[6N!??r1$+OS3m.D6N!??r1$+OS3m.D6N!??
+r2`Tib[(.r at JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qgh-K6 at Jnnmr7ko^k%ahLB)LFr
+r8qblZr$[r8Go8Sr1$+O]N"gaB)LFrr7ko^e7&:1B)L.er7#0Qe7&:)@JnV`r6/IEe7&:!?2W2\
+r6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr7#0Qe7&:)@Jn>Tr6/IEb[(.j?2VoPr6/IEb[(.j?2VoP
+r7#0Ts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;N/r4HkD]N"gA<;aC.r4H#,]N"g9;#I[sr4H#,Zr$\-;#I[sr3T;uZr$\-;#I[s
+r4H#,Zr$\5<;aC.r4H#,]N"gA<;aC.r5;b9]N"gA<;a[;r4H#,`**#N<;a[;r4H#,]N"gA<;aC.
+r4H#,Zr$\-;#I[sr3T;uZr$\-;#I[sr3T;uXA&P^6N!??r4H#,]N"gA<;a+"r4H#,Zr$\5<;a+"
+r3T;uZr$\-;#It*r4H#,]N"gA<;aC.r4H#,]N"gA<;a[;r3T;uS3m.D6N!WMr1$+OS3m.D6M$*n
+o8>NuM`1L'6Mf39s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8:ATr5;b9`**#V=o?3 at r5;b9`**#N<;a[;r4H#,]N"gA<;aC.
+r4H#,]N"gA<;a[;r4H#,`**#N<;a[;r4H#,`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9`**#N<;aC.r4H#,]N"gA<;aC.r4H#,`**#N<;aC.r4H#,]N"gA<;aC.r4H#,Zr$[j6M$*n
+o8>O)PX55;6Mn-1s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8;6%r7#0Q`**#V=o?3 at r5;b9`**#V=o?3 at r6/IEb[(.j?2VoP
+r69llb[(.r at JnV`r69lle7&:)@JnV`r7#0QXA&P^6N!??r2`Tls8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n*'-,r69ll`**#^?2VoP
+r6/IEb[(.j?2W2\r7#0Qe7&:)@JnV`r7#0Qgh-K6 at Jnnmr7$Q#e7&:)@JnV`r6/IE]PRH"YQ+Y&
+s8W,sm)8hO at JnV`r7#0Qe7&:!?2VoPr6/IEb[(.j?2VoPr6/IEb[(.b=o?3 at r5;b9`**#V=o?3@
+r5;b9`**#V=o?3 at r69los8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYI
+g"bH;gtpK/f%Jj8m&ka6]N"gQ?2VoPr6/IEb[(.j?2VoPr6/IEe7&:)@JnV`r7#0Qe7&:!?2W2\
+r7#0Qe7&:)@JnV`r7$Q#e7&:)@K6B-s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq>/'er1lm]Zr$\M at Jnnmr7ko^gh-K>B)LFrr7ko^gh-K6 at JnV`
+r7#0Qe7&:)@JnV`r7#0Qb[(.j?2W2\r6/IEe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r6/IEe7&:)@Jn>Tr7#0Qe7&:)@JnV`r7#0Qgh-K>B)LFr
+r7ko^gkYg_B)LFrr7ko^k%ahLB)LFrr7ko^gh-KV`rH)=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<[_Gkj7ckgtqM4Nr5D6r00MFPX55362Zs5
+r1$+O]N"gY at JnV`r7#0Qgh-K>B)L.er7$Q#gh-K6 at Jnnmr7#0Qe7&:1B)LFrr7#0Qgh-K>B)LFr
+r7ko^gh-K6 at Jnnmr7#0Qe7&:)@JnV`r7ko^gh-K>L]#q>r7m)*gh-K>B)L.er7ko^e7&:)@JnV`
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JoJ8s8W-!s8W-!s8W-!s8W,coC_JAp#+ooi8j(SgtpK/f#u:^
+bKS5Sbg")F`T41Lr00MFPX55362Zs5r00MFS3m.D6N!'6r00MFPX55K9`3+?r6/IEb[(.j?2VoP
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:1B)L.er7ko^gh-K>B)K#4r1$+OS3m.l=o@&e
+r7ko^gh-K6 at Jnnmr7#0Qe7&:!?2VoPr6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IE`**#^?2VWD
+r6/IEb[(.j?2VoPr5;b9b[(.j?2VoPr6/IEb[(.b=o?KLr5;b9b[(.b=o?d*s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r69llZr$\-;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr2`TiZr$\%9`27or3T;uZr$\%9`27or3T;uZr$\-;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\-;#It*r4H#,]N"gA<;aC.r3T;uZr$\-;#ICgr3T;uXA&Pn9`1tc
+r2`TiXA&Pn9`1tcr3T;uS3m.\;#I[sr3T;uZr$\-;#ICgr3T;uZr$\-;#I[sr3T;uZr$\-;#It*
+r3T;u]N"gA<;aC.r4H#,]N"g9;#HhMr1$+OS3m.D6N!'6r1$+FM`10b2Y2hbr/<f8gopbXs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8:oN
+r4H#,]N"gI=o?3 at r4H#,]N"gA<;aC.r4H#,]N"gA<;a+"r4H#,Zr$\-;#I[sr4H#,Zr$\-;#I[s
+r3T;u]N"g9;#It*r4H#,]N"gA<;aC.r5;b9]N"gA<;a[;r5;b9`**#V=o>p3r4H#,]N"gA<;aC.
+r4H#,]N"gA<;aC.r4H#,Zr$\5<;a+"r3T;uZr$\-;#It*r4H#,XA&PV61^!mqh.$.PX55362\u[
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;6%
+r5;b9`**#V=o?3 at r5;b9`**#N<;a[;r4H#,`**#V=o?3 at r5;b9`**#V=o?KLr5;b9`**#^?2VWD
+r5;b9b[(.j?2VWDr1$+OPX55362\BOs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,i8j)!e;4%@=o?3 at r5;b9`**#^?2VWDr6/IEb[(.j?2VoP
+r7#0Qe7&:)@JnW2r7#0Qe7&:)@JnV`r7#0Qb[(.r at Jn>Tr5;b9XCh=QVYBH?r7$Q#e7&:"KD`r!
+r6/IEb[(.b=o?KLr5;b9`**#V=o?3 at r5;b9]N"gI=o?3 at r4H#,]N"gI=o>p3r4H#,]N"g9;#gRq
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH4eCN'tf#u:^bKS5_`4c)E8GpD/
+r5;b9b[(.j?2VoPr6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IEb[(.j?2W2\
+r9KdNs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=rI]
+r1lm]SP8t"=o?cXr7#0Qgh-K6 at JnW2r7ko^e7&:)@JnV`r7#0Qe7&:)@JnV`r6/IEb[(.j?2VoP
+r6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IEe7&:!?2W2\r6/IEe7&:!?2VoPr6/IEb[(.j?2VoP
+r6/IEb[(.j?2VoPr6/IEb[(.j?2W2\r6/IEe7&:)@JnV`r7#0Qe7&:)@Jnnmr7ko^gkYgW at JnV`
+r7#0Qe7&:)@Jnnmr;OA/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2kj7crjQGaMX7;cdo8>O)PX55362Zs5o8>O)XA&Q1=o?cXr6/IEe7&:)@JnB&
+r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r7#0Qe7&:)@JnW2r7#0Qgh-K6M#>b2r7#0Qe7&:)@JnV`
+r7#0Qe7&:)@JnV`r7#0Qe7&:1B)L.er7#0Qe7&:)@JnV`r7#0Qe7&:)@JnV`r6/IEe7&:)@JnV`
+r6/IEb[(.r at K6B-s8W-!s8V`bq<[_Gkj7ckgtp`>hU9p)`5T^6`PoI%]u7n/]=bi0Uj2g%62Zs5
+o8>O)PX4o!2Z/e*r00MFPX4o!2Y2hbr1$+O`**#V=o?3 at r5;b9b[(.b=o?3 at r6/IE`**#^?2VoP
+r6/IEc%GrD at JnV`r7#0Qe7&:)@JnV`r7#0QXA&P^6N#&5r7#0Qe7&:)@JnV`r7#0Qb[(.j?2VoP
+r6/IEb[(.b=o?KLr5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#nL]@DSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r:J#,]PRMI9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tc
+r1lm]XA&Pn9`1\Wr2`TiXA&Pf8GoP_r2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tc
+r3T;uXA&Q!;#ICgr3T;uZr$\%9`27or2`TiXA&Pn9`1\Wr2`TiUe(EZ8Go8Sr2`TiUe(Eb9`1tc
+r2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr3T;uZr$\-;#I[sr4HkD]N"gA<;aC.
+r2`TiPX55362Zs5r00MFPX55361^!mo8>NuM`1Kt62]5gs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r69llZr$\-;#I[sr4H#,]N"g9;#It*
+r3T;uZr$\-;#I[sr3T;uZr$\-;#ICgr3T;uXA&Pn9`1tcr3T;uXA&Pn9`27or3T;uZr$\-;#I[s
+r4H#,Zr$\5<;aC.r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r3T;uZr$\-;#I[sr3T;uZr$\-;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\-;#It*r3T;uPX4o!2Z&.go8>O)PX55CD?'Y9s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,rjMCc,<;aC.r4H#,]N"gA<;aC.
+r4H#,]N"gA<;aC.r4H#,]PRMa=o?3 at r5;b9`**#V=o?3 at r5;b9`**#ND#D4Sr5;b9`**#F;#H88
+o8>O)PX53-_>jQ8s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+i8j(ZjQGdXfDN9\r4H#,]N"gI=o?3 at r5;b9`**#V=o?3 at r6/IEb[(.j?2VoPr6/IEe7&:!?2Vs"
+r7#0Qb[(.kKD`r!r6/IEb[(.Z<;_\<r1$+9gt_hWM#>J&r6/IEb[(.j?2VWDr5;b9`**#V=o?3@
+r5;b9`**#N<;a[;r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r3T;ue;4/)s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(SgtpK/f%A3i`5T^=bg")F`T41Lr2`Tib[(.b=o?3 at r6/IE`**#V=o?3@
+r6/IE`**#V=o?KLr5;b9`**#^?2VWDr6/IEb[(.kKD`r!r6/IEc%H&rs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726n%=\YPX55C8GpD/r6/IEb[(.r at Jn>T
+r6/IEe7&:!?2W2\r69lle7&:"KD`r!r7#0Qb[(.j?2VoPr5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r6/IE`**#^?2VWDr6/IE`**#V=o?KLr5;b9b[(.b=o?KLr5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r6/IE`**#^?2VoPr6/IEc%GrD at JnV`r7#0Qc%GrD at Jn>Tr7#0Qb[(.r at JnB&r7#0Qe7&CWs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp$D;Ckj7crjQG4OhW1he
+r00MFPX55;6M$*no8>O)PX55S;#JOCr6/IEb[(.j?2VoPr6/IEb[(.j?2VoPr6/IEc%Gr<?2Vs"
+r6/IEb[(.kKD`r!r6/IEe7&:)@JnV`r7#0Qe7&:)@JnB&r6/IEb[(.j?2VoPr7#0Qe7&:)@JnW2
+r7#0Qe7&:"KD`r!r6/IEb[(.j?2VoPr6/IEb[(.j?2VWDr5;b9b[(.b=o?KLr5;b9c%Grd`rH)=
+m.9o6m-iW_hV$]@bKS5L`PoI%]t:qj]=bha['[3I[+M1!o8>NuM`10b2Y2hbo8>NuM`10b2Z/Ls
+o8>O(KKB%$6N"c)r4H#,`**#N<;aC.r5;b9]PRMa=o?3 at r4HkD`**#^?2VWDr5;b9b[(.kKD`r!
+r7#0Qc%GrD at Jm3#r5;b9b[(.j?2VoPr6/IE`**#^?2VWDr5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9`**#N<;a[;r4H#,]N"gA<;aC.r4H#,]N"gA<;a[;r4H#,`**#N<;a[;r4H#,]N"gI=o>p3
+r4H#,]N"gA<;aC.r4H#,oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,rjMCbq9`1tcr1lm]Ue(Eb9`1tcr1lm]XA&Pf8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8GnuE
+r1lm]Ue(EZ8GnuEr1lm]S3m.D6N!??r1lm]S3m.L8Go8Sr1lm]XA&Pf8GoP_r2`TiXA&Pf8GoP_
+r1lm]XA&Pf8Go8Sr1lm]S3m.D6N!WMr1$+OS3m.L8Go8Sr1lm]Ue(Eb9`1\Wr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8GoP_r2`TiXA&Pn9`1tcr2aN.Zr$\-;#I[sr3T;uZr$[r8Gn]<r/<f:N'7*'61^!m
+qh.$-KKB!`3r=Rkqh.$,e?JuQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,s]PRMI9`27or3T;uZr$\-;#I[sr3T;uXA&Pn9`27or2`TiXA&Pn9`1tc
+r2`TiUe(Eb9`1\Wr2`TiXA&Pf8GoP_r2`TiUe(Eb9`1tcr2`TiXA&Pn9`1tcr2`TiZr$\-;#I[s
+r3T;u]N"g9;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uXA&Pn9`1tcr2`TiXA&Q!;#I[s
+r3T;uZr$\-;#It*r1$+NKKB!`3r=Rkr/<f:S3m/?`;fl;s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r69llZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#It*
+r4H#,]N"gA<;aCFr4H#,`**#ND#CqFr5;b9]PRMa=o?3 at r4H#,Ue(*82Y2hbr1$+Rs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!kj7d%m-iW_hW`SBr4HkDZr$\5<;aC.
+r4H#,]N"gA<;aC.r4H#,]N"gA<;a[;r5;b9`**#^?2DNsr6/IEb[(.j?2VWDr6/IE`**#^?2V?7
+r00MFPX4NVX4c:bk1nbg`JON2=o?3 at r5;b9`**#V=o?3 at r4H#,`**#N<;aC.r4H#,]N"gA<;aC.
+r3T;u]N"g9;#I[sr3T;uZr$\-;#ICgs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!kj7d%m-iW_hU9p)
+bKS5L`Pod7`Pfa7`k8n\S3m.d<;a[;r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b9`**#^?2VWD
+r6/IE`**#V=o?KLr5;b9`**#V=o@'1s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gq;gN)Sm;2P4oCO1r4H#,`**#V=o>pKr5;b9`**#V=o?KLr5;b9b[(.j?2VoP
+r6/IEb[(.j?2VWDr5;b9`**#V=o?3 at r5;b9`**#N<;a[;r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r4H#,`**#N<;a[;r4H#,`**#N<;a[;r5;b9]N"gI=o>p3r5;b9]N"gI=o?3 at r5;b9`**#^?2VoP
+r6/IEc%Gr<?2VoPr6/IEb[(.j?2VoPr5;b9b[(.j?2WK5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7crjQGI^kLe#%r1-OZPX4o!2Z/Lso8>NuM`1L'6N"Jq
+r5;b9b[(.b=o?3 at r6/IE`**#^?2VWDr6/IE`**#V=o?3 at r5;b9`**#V=o?3 at r6/IE`**#^?2VoP
+r6/IEc%Gr<?2Vs"r6/IEb[(.j?2VoPr6/IEb[(.kKD`r!r69llb[(.j?2VoPr6/IEb[(.b=o?3@
+r6/IE]PRMa=o>p3r5;b9`**#V=o?3 at r5;b9`**#V=o?3 at r5;b4m-!U!n)39ig"bH4eCMgec+CX%
+['[3I['Zm8XfJP*X/rGIO_"'A2Y2hbqh.$-KKB!`3qJ7fqh.$%M`1Hc3r=Rkr1$+OZr$\5<;a+"
+r3T;u]N"g9;#It*r4H#,]N"gA<;a[;r4H#,`**#V=o>p3r4H#,`**#V=o?3 at r5;b9`**#V=o>p3
+r5;b9]N"gI=o?3 at r5;b9]N"gI=o>p3r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,]N"gA<;a+"
+r4H#,Zr$\5<;aC.r4H#,Zr$\5<;a+"r4H#,]N"gA<;aC.r3T;u]N"gA<;aC.r4H#,Zr$\5<;b!n
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VrNYPb1er1-OZUe(EZ8Go8S
+r1$+OUe(EZ8GnuEr1lm]Ue(ER6N!WMr1$+OS3m.D6N!??r1$+OS3m.D6N!??r1$+OS3m.D6N!??
+r1$+OS3m.D6N!??r1$+OS3m.D6N!??r1lm]S3m.L8Go8Sr1lm]S3m.L8GnuEr1$+OS3m.D6N!??
+r1$+OS3m.D6N!??r1$+OS3m.D6N!WMr1$+OS3m.L8GnuEr1$+OS3m.D6N!WMr1lm]Ue(EZ8GoP_
+r2`TiXA&Pn9`1tcr2`TiXChC39`1tcr1lm]N'6cj2Y2hbo8>NuM`1Hc3r=Rkqh.#sF=Qm?2Z2'\
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+Wn;#ICg
+r2`TiXA&Pn9`1u(r2`TiXA&PfD>^J/r1lm]Ue(Eb9`1\Wr1lm]Ue(EZ8Go8Sr1lm]S3m.L8GnuE
+r1lm]Ue(ER6N!WMr1lm]Ue(EZ8Go8Sr1lm]XA&Pf8GoP_r2`TiXA&Pn9`1u(r3T;uZr$\%9`1tc
+r3T;uXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`27or3T;uZr$\-;#HhM
+qh.$-KKB!`3qJ7fr/<f9jMClrs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+ILkPVtlr2`TiZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#It*r3T;u]N"g9;#I[s
+r4H#,]N"g9;#It*r4H#,]N"gA<;a+"r/<f1M`1Hc3r?:)s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n)iE\g"bH\`JON";#I[sr3T;uZr$\5<;a+"r4H#,Zr$\5<;aC.
+r4H#,]N"gAD#D4Sr4HkD`**#V=o>pKr5;b7`JON2=o>pKr4HkDS3m.44m]>!g"bH4eCN'tf)!@B
+r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,]N"g9;#I[sr3T;uZr$\-;#I[sr3T;uXA&Pn9`27o
+r2`TiZr$VSYQ+Y&s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)39idaZjreCMgec, at T?`5T^6`Ppo at I/Kd2
+r5;b9]N"gI=o>p3r5;b9`**#N<;a[;r5;b9`**#V=o?3 at r5;b9`**#ND#D4SqSe<h`**#V=o-*o
+r5;b<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d#gt_Fk>k<k3
+r/<f:Zr$\5<;aC.r4H#,]N"gI=o>pKr5;b9]PRMa=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9]N"gA<;aC.r4H#,]N"gA<;aCFr4H#,]N"gA<;aC.r4H#,]N"gA<;aC.r4H#,]N"gA<;aC.
+r4H#,Zr$\5<;a+"r3T;u]N"g9;#It*r4H#,]N"gI=o?3 at r5;b9`**#V=o?3 at r5;b9`**#V=o?3@
+r5;b9]PRMa=o?3 at r5;b9oZ$q2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o6m-ilnkLnYIf>PB#PX4o!2Y2hbo8>NuM`1Hc3rG4.r5;b9`**#V=o?3 at r5;b9`**#V=o>pK
+r5;b9]PRMa=o>pKr5;b9]PRMa=o>pKr4H#,]PRMa=o>pKr5;b7`JON2=o?KLr5;b9b[(.b=o?KL
+r5;b9c%Gr4=o?KLr6/IEb[(.j?2VoPr5;b9`**#ND#D4Sr4HkD`**#V=o>pKr5;b9]N"gA<;aC.
+r4H#,]N"gA<;aCFr4H#,`**#N<;a[;q:sBUjQFt at f#u:^]=bhh]Y1AIXfJP*Unsl_V50o`Us+s3
+r/<f9HoV"V3r=Rkqh.$-KKB!`3r=Rkqg:BiF=R3Q62\)dr3T;uXA&Q!;#ICgr3T;uZr$\-;#I[s
+r4H#,Zr$\-;#I[sr3T;u]N"gA<;a+"r4H#,]N"gA<;a+"r4H#,]N"g9;#It*r4H#,]N"g9;#It*
+r3T;uZr$\5<;aC.r3T;u]N"g9;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\m`rH)=s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8(6Lr1$+OPX55;6N!'6r00MFPX55;6N!??r00MFS3m.<62[6>
+r00MFS3m.<62[6>r00MFS3m.<62[6>r00MFPX55362Zs5r00MFPX55;6N!'6r00MFPX55362Zs5
+r00MFS3m.<62[6>r00MFS3m.<62[6>r00MFS3m.<62Zs5r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFS3m.<62[6>r1$+OPX55;6N!??r1$+OS3m.D6N!WMr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(ER6M$*nqg:C#KKA^_2Z&.gqh.#sF=R0 at 3r=:aqh.$,bbkF?s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s88rlr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8GnuEr1lm]S3m.L8GnuEr1lm]S3m.D6N!WMr1$+OS3m.L8GnuEr1lm]S3m.D6N!??
+r1$+OS3m.L8Go8Sr1lm]Ue(EZ8GoP_r2`TiXA&Pn9`1u(r2`TiXChC39`1tcr2`TiXA&Pf8GoP_
+r1lm]XA&Pf8Go8Sr1lm]XA&Pf8GoP_r2`TiXA&Pn9`1tcr2`TiXA&PV60r\Cqg:BiF=Qm?2Z&.g
+qrGTns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7d6gsQ%q8Go8S
+r2`TiUe(Eb9`1tcr2`TiXA&Q!;#I[sr2`TiZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[s
+r3T;uZr$[r8Ge'$qh.$-KKB"k_>jQ8s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(Sgtq8<X8K%mr2`TiXA&Pn9`27or2`TiZr$\%9`27or3T;uZr$\-;#I[sr3T;u]N"gA<;aC.
+r4HkD`**#ND#CqFr5;b9]N"g!6MlEsnXa"6eCMgec-+>UbKS5nbfTdi;#I[sr3T;uZr$\-;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\%9`27or2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`Tls8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gi8j(SgtpK/f#u:^`5T^6`Pod7`Q#R%r0:.WZr$\5<;aC.r4H#,]N"gA<;aC.
+r4H#,]N"gA<;aC.r4H#,`**#ND#D4Sr5;b9`**#ND#D4Sr5;b9]N"gRKE(uOs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d%m-iW_hXR1Bqh.$-KKB%49`27or3T;uZr$\-;#@V?
+r3T;uZr$\5<;aC.r4H#,]PRMa=o>pKr5;b9`**#ND#D4Sr4HkD]N"gA<;aC.r4H#,]N"g9;#It*
+r3T;uZr$\-;#I[sr3T;uZr$\-;#ICgr3T;uZr$\%9`27or2`TiZr$\-;#I[sr2`TiZr$\-;#I[s
+r3T;uZr$\-;#It*r4H#,]PRMa=o>pKr5;b9`**#V=o?3 at r4H#,]PRMa=o>p3r5;b9]N"gA<<*!u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIg"bH:]XIEi2Y2hb
+o8>NuM`1Hc3qJ7fr00MF]N"gA<;aC.r4H#,]N"gA<;aCFr4H#,]N"gAD#CqFr4H#,]N"g9;#It*
+r4H#,Zr$\5<;aC.r4H#,]PRMa=o?3 at r4HkD`**#V=o>pKr5;b9]PRMa=o>p3r5;b9]PRMa=o>pK
+r5;b9]PRMa=o>pKr5;b9]PRMa=o>pKr4H#,]N"gA<;aC.r4HkDZr$\5<;aC.r4H#,]N"gA<;aC.
+r4H#,]N"gA<9`)HdaZjkbg!c4]sP/RX/rFnSt)UQUnji_Unsm2O_"?:3;\@iluX`SHoUJ7.dV7,
+o8>NnF=Qm?2Z%k]r/<f:XA&Pn9`1tcr2`TiXA&Pn9`1tcr3T;uXA&Q!;#ICgr3T;uZr$\%9`1tc
+r2`TiZr$\%B)J`(r3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#ICgr3T;uXA&Q!;#ICg
+r3T;uXA&Q!;#I[sr3T;uXA&Q!;#ICgr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr3T;uXA&Pn9`1tc
+r3T;uXA&Pn9`1tcr2`TiXA&Pn9`1tcqTPi:s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r9VB"Pu7ID62Zs5r00MFPX55362Zs5r00MFPX55+4oCO1r00MFN'7*'62Z[)r00M=M`1Kl4oC7%
+r/<f:N'7)t4oCO1o8>O)N'7)t4oCO1r/<f:PX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFPX55362Zs5r00MFPX55+4oCO1r/<f:PX55362Zs5r00MFS3m.<62Zs5r1$+OPX55362Zs5
+r1$+OPX55;6N!??r1-OZSP8sP9`1GTr1-OZUe(ES9`1\Wr1lm]Ue(EZ8Go8Sr1$+NHoV"N3;\@i
+qh.$-KKAIA.f4l[luX`SHoV"N3;Ujrs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qm:DAS3m.D6N!??r1lm]SP8sW8Go#Pr1lm]SP8sO6N!??r1$+OS3m.D6N!??
+r00MFS3m.<62[6>r00MFS3m.D6N!'6r1$+OS3m.<62[6>r1$+OS3m.D6N!??r1$+OS3m.L8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8GoP_
+r1lm]XA&Pf8GoP_r2`TiUe(Eb9`1\Wr1lmTM`0pD.f4TQluX`SHoU_U2Y?_=s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7crjQGI^kLnYIqSe<hUe(EZ8Go8Sr1lm]Ue(Eb9`1\W
+r2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2`TiXA&Pn9`1tcr2aN.XA&Pn9`27or2`TiN'7&c3;\(_
+r00MIs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhW`SBr3T;uUe(Eb9`1\W
+r2`TiXA&Pf8GoP_r2`TiXA&Pn9`1tcr3T;uZr$\-;#I[sqm:DAZr$\5<;a+"r4H#,]PRMQ;#ICg
+qg:BpM`/Mm`QQKMbKS5Sbg">Tc, at T?r4Ij`XA&Q!;#ICgr2`TiXA&Q!;#I[sr2`TiZr$\%9`27o
+r2`TiXA&Pn9`1tcr1lm]XA&Pf8Go8Sr2`TiUe(EZ8GhJas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYI
+fZ_O^bg")F`Pfa7`5T^JXIo*B2Z0pYr3T;uZr$\-;#I[sr3T;uZr$Y,Er<RLr3T;u]PRMQ;#ItB
+r4H#,]PRMYD#CqFr4H#,]PRMQ;#It*r:J#/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+m.9o6m-ilnkLnYIkbX@;HoUJ7.f>f'r3T;uXA&PnB)K#4r2`TiXA&Q!;#I[sr3T;tZuZ)O;#It*
+r3T;u]N"g9;#ItBr3T;uZr$\5<;a+"r3T;uZr$\-;#I[sr3T;uXA&Q!;#ICgr3T;uXA&PnB)J`(
+r2`TiXA&Pf8GoP_r1lm]XA&Pf8GoP_r1lm]XA&Pn9`1\Wr2`TiUe(Eb9`1tcr3T;uZr$\-;#It*
+r4H#,]N"gA<;X%Cr4H#,Zr$\5<;a+"r3T;uZr$\-;#I[sr4HkGs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n)39ig"bH4eCMXP](:h<o8>NuM`1Hc3p^r<qg:BpM`1L79`2P&
+r4H#,Zr$\-;#I[sr3T;uZr$\5<;a+"r3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uXChC;;#I[s
+r3T;u]N"gA<;aCFr4HkD]N"gAD#CqFr4H#+ZuZ)W<;aC.r4HkD]N"gA<;a+"r3T;u]N"g9;#I[s
+r3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;uZr$\-;#I[sr3T;tZuZ)O;#I[sr3T;tZuYBRX2Mur
+]=bha['Zm8Xe_ehUnsl_V50o`Us+s3o8>NnF=QX!.dV7,qh.#sF=R083:(`:luX`DF=R3Q62[fX
+r2`TiXA&Pf8GoP_r1lm]Ue(Eb9`1\Wr2`TiXA&Pf8Go8Sr2`TiUe(EZ8Go8Sr1lm]XA&Pf8Go8S
+r1lm]XA&Pf8Go8Sr2`TiXA&Pn9`1tcr2`TiXA&Pf8GoP_r1lm]XA&Pf8GoP_r1lm]Ue(Eb9`1\W
+r2`TiUe(Eb9`1\Wr2`TiUe(EZ8GoP_r1lm]Ue(Eb9`1\Wr2`TiXA&Pf8GoP_r1lm]Ue(EZ8GnuE
+r1lm]S3m.TB)ho2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W"f9`0i4r/<f:N'7)t4oC7%
+r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%o8>NuM`1Hc3qJ7fo8>NuM`10b2Y2hbqh.$%M`1Hc3qJ7f
+o8>NuM`1Kl4oC7%r/<f:N'7)t4oCO1r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%
+r/<f:PX55+4oCO1r00MFPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5r00MFS3m.<62Zs5
+r1$+OPX55<9`1GTr0:.WSP8sP9`1GTr1-OZSP8sG60r\CluX`DF=QX!.f4TQluX`DF=QX!.dV7,
+luX`RbbkF?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,q`JOMW62Zs5
+r1$+OPX55;6N!'6r1-OZPX55<9`1DIr00MFSP8sG62Zs5r00MFPX55362Zs5r00MFN'7*'62Z[)
+r/<f:PX55+4oCO1r00MFPX55362Zs5r1$+OPX55;6N!??r1$+OS3m.E9`1GTr1lm]SP8sWD>^2#
+r1lm]Ue(EZ8Go8Sr1-OZUe(ES9`1DIr1lm]S3m.L8Go8Sr1lm]Ue(EZ8GnuEr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8GnuEqh.#sF=QX!.dV7,qg:C$N'74 at s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkN:RTg"bH4eCN=.hYX[#r1$+OS3m.L8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]XA&Pf8Go8Sqg:BiF=QX!.f6Sns8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+QpA*Y-kMYFag"bH^[>t0\8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8GoP_r1n3-XA&Pn9`1tcr2aN.Zr$\%B)K#4r2`ThHoU_U2V>[NfZ_O^bg")F`QQKM
+`5T^=bg#@gYl(Rrr2aN.XA&Pn9`1tcr2`TiXA&Pn9`1\Wr2`TiUe(Eb9`1\Wr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]XChM4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2g"bH4eCN'tf#5PH`5T^6`Pod7`TE.\
+r1lm]XA&Pn9`1tcr2aN.XA&PnB)J`(r3T;uXChC;;#ID,r3T;uZr$\-;#I[sr3T;tZuZ)O;#I[s
+r3T;u]PRWJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-ilnkLnYIdaZk"`4bMZ.f4TQ
+r/<f:XA&Pf8GoP_r2`TiUe(Eb9`1tcr1lm]XChC39`1tcr2`TiZr$Y,Er<:@r3T;uXA&Q!;#I[s
+r2`TiZr$\%9`1tcr2`TiXA&Pn9`1tcr1lm]XA&Pf8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1$+OUe(EZ8Go8Sr1lm]Ue(EZ8GoP_r2`TiZr$\%B)K#4r3T;uXA&Q!;#I[s
+r3T;uZr$\%9`27or3T;uXChC[M#[MTs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oo
+g"bH;gtpK/f#5PHk)EF.F=R0 at 3p^r<luX`SHoUJ7.f?)5r2`TiZr$\-;#ICgr3T;uXA&Q!;#ID,
+r3T;uZr$\%B)K#4r2aN.XA&PnB)J`(r1n3-Ue(Eb9`1tcr2`TiXA&Pn9`1tcr2aN.Zr$\-;#I[s
+r3T;uZr$\%9`27or2aN.XA&Q!;#I[sr3T;uXChC;;#ICgr2aN.Zr$\-;#I[sr3T;uXChC39`1u(
+r2`TiXChC39`1u(r1lm]Ui$%29`1tcr2`TiXChC39`1tcqm:C^`PoI%]sP/RUnsl_V50o`Unji_
+Unsm2O_!g#.dV7,qg:BiF=QX!.eAQVluX`KM`1Hc3p^r<o8>O)XA&Pf8GoP_r1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(ES9`1GTr1-OZSP8sW8Go#Pr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1$+OUe(ER6N!WMr1$+OUe(ER6N!WMr1lm]Ue(ER6N!WM
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8GnuEr1lm]S3m.D6N!??r1$+OS3m.D6N!??r1$+Om)8r(s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s800Dqh.$.N'7)t4oC7%r/<f9KKB$i4o9mnqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$%M`1Hc3qJ7fo8>NuM`1Kl4oCO1
+r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r00MFN'7*'62Z[)r00MFN'7)t4oCO1
+r00MFN'7*'62Z[)r00MFN'7*'62Zs5r00MFPX55362[!Fr1$+OPX55362Zs5r1$+OPX55;6N!'6
+r00MFPu7IL6N!'6r/<f*F=QX!.dV7,qg:BiF=QX!.dV7,luX`DF=QX!.f.Ads8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VoMdJT4pr00MFPX55362Zs5r00MFPX55;6N!'6
+r00MFPX55362Zs5r00MFPX55362Zs5r00MFN'7)t4oC7%r/<f1M`10b2Z/Lsr/<f:N'7*'62Z[)
+r00MFPX55362Zs5r00MFPX55362Zs5r00MFSP8sP9`1DIr1$+OSP8sP9`1GTr1-OZSP8sP9`1DI
+r1$+OS3m.<62[6>r1$+OS3m.<62[6>r1$+OS3m.D6N!??r1$+OSP8sO6N!WMr1-OZS3m.44m[8?
+luX`DF=QX!.dV7,qm:DDs8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(SgtpK/f$`(!
+fZ_Okbffp[D>]njr1$+OS3m.D6N!??r1$+OS3m.D6N!BJr1$+OSP8sO6N!BJr1-OZSP8sP9`1GT
+r1-OZSP8sP9`1GTr1-OZUe(EB4m[8?r+n1UF=R+AdJs7Hs8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+k1nbFgtqnGXSeSTr1$+OS3m.D6N!??r1$+OS3m.D6N!WMr1$+OUe(ER6N!WMr1-OZUe(EZ8Go8S
+r1lm]XA&Pn9`1\Wr2`TiUe(B13;\(_fVEc8bg">Tc-+>UbKS5L`Pp$Ec, at T?bKS6/XChC+8GoP_
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]S3m.L8GnuEr1$+OUe(ER6N!WMr1$+OUe(EZ8GnuE
+r9VB%s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQG4OhU9p)`5T^=bg")F`Pfa7aK268HoV&"8GoP_r1lm]Ue(EZ8GoQ$
+r2`TiXA&Pn9`1tcr2`TiXA&PnB)J`Br2aN.XA&PnB)J`(r2`TiUi$%*8Gqhms8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIg"bH4eCN9rbN=dbluX`DF=R3a8Go8Sr1lm]Ue(EZ8Go8S
+r1n3-Ue(EZ8Go8Sr2`TiXA&PnB)J`(r2`TiXA&PnB)J`(r1lm]XA&Pf8GoP_r1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go#Pr1lm]SP8sO6N!BJr1$+OS3m.D6N!??r1$+OS3m.D6N!??r1$+OS3m.D6N!??
+r1$+OS3m.D6N!WMr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8GoP_r1lm]XA&Pf8GoP_
+r:J#/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp$D;Ci8j(SgtpK/f$`(!`5T^HPC`(B.dV7,
+luX`DF=QX!.dV7,r/<f:XA&Pf8Go8Sr2`TiUe(EbB)JGqr2`TiXA&Pf8GoQ$r2`TiXA&Pf8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZD>^2#r2`TiUe(Eb9`1\Wr2aN.Ue(EbB)JGqr2aN.Ue(Eb9`1tc
+r2aN.XA&PnB)JGqr2`TiUe(Eb9`1]'r2`TiUi$%29`1tcr1lm]XA&Pf8Go8Sr2`TiUe(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr2`TiUe(Eb9`1u(`k8mi['ZX*Unji_Unsl_V50o`Us+s3luX`DF=QX!.dV7,
+luX`DF=QX!.dV7,luX`DF=R0 at 3rGdEr1lm]Ue(EZ8Go8Sr1$+OUe(ER6N!??r1-OZS3m.E9`1GT
+r1$+OS3m.D6N!'6r1$+OSP8sP9`1GTr1lm]SP8sW8GnuEr1lm]S3m.D6N!??r1$+OS3m.D6N!??
+r1$+OS3m.D6N!??r1$+OPX55;6N!??r1$+OS3m.D6N!??r1$+OS3m.D6N!??r1$+OS3m.D6N!??
+r1$+OS3m.D6N!??r00MFS3m.D6N!'6r1$+OS3m.<62JO$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+qUDbHKKB!`3r=Rkqh.$-KKB!X3;\@iqh.$-HoV"V3r=Rkqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$%M`1Hc3qJ7fo8>O)N'7)t4oC7%r/<f:N'6cj2Y2hb
+o8>NuM`1Kl4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%
+r/<f:PX55+4oCO1r00MFPX55362[!Fr00MFPX55362Zs5r00MFPX55362Zs5r00MFN'7)t4m[8?
+lte*:F=QX!.dV7,lte*:F=QWn.-taulte*H`2s"=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r1-OZN'7*'62Z[)r/<f:N'7*'62Zs5r00MFPX55362Zs5r00MFN'7*'62Z[)
+r00MFN'7)t4oC7%r/<f:N'7&k3r=Rkqh.$-KKA^_2Z&.go8>O)N'6cj2Z/Lsr/<f:N'7)t4oC7%
+r/<f:N'7*'62Z[)r00MFN'7*'62Z[)r00MFPu7I<4oCO1r00MFPX55362[6>r00MFPX55362Zs5
+r00MFPX55362Zs5r00MFPX55362[!Fr00MFSP8sO6N!??r1$+NHoV%F3UCi;luX`DF=QX!.f%lI
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG[\gsX^'daZjreCMgec.L7`f>PB#PX55362Zs5
+r00MFPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFF#iT'.-tauqg:C's8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhWE&(r1lm]PX55;6N!'6
+r00MFPX55362Zs5r1$+OPX55;6N!'6r00MFS3m.<62[6>r1$+OSP8sP9`1GTr1-OZSP8sP9`'K(
+lte*4NE4]UbL4nkbKS5L`Pp$Ec.L7``5T^=bg">Tc02gEr1-OZSP8sP9`1\Wr1-OZUe(ER6N!??
+r1$+OS3m.D6N!??r1$+OUe(ER6N!??r1$+OS3m.D6N!??r1$+OS3m.TB)ho2s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQ
+daZjkbg")F`Pfa7`5T^6`Ppu!<rA1Jr1lm]Ue(Eb9`1]'r1lm]Ue(EZD>^2#r1lm]Ui$%*8Go9#
+r1lm]XA&Pf8Go8Sr1lm]Ue(EZ8Go8Sr2aN1s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39i
+i8j(LeCN'tf#u:^f:7<VCaeXl.f>5gr1lm]SP8sW8Go#Pr1-OZSP8sO6N!BJr1lm]SP8sW8Go#P
+r1lm]Ue(EZ8GoP_r1lm]Ue(EZ8Go8Sr1-OZUe(EZ8Go#Pr1-OZSP8sP9`1GTr1-OZPu7IL6N!*G
+r1$+OS3m.<62[6>r00MFPX55362[9Ir00MFS3m.<62[6>r00MFS3m.<62[6>r1$+OS3m.D6N!??
+r1-OZSP8sP9`1GTr1-OZSP8sP9`1GTqTPi2m-"<=`qSi_r:J#$pA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5L`Pop"V<i"HluX`DCaeXl.dLUjlte*JF#j/g6N!??
+r1-OZUe(EZ8Go#Pr1lm]SP8sW8Go#Pr1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go#Pr1-OZUe(ES9`1GT
+r1$+OSP8sP9`1GTr1-OZSP8sP9`1GTr00MFPX55+4oCO1r0:.WSP8sW8Go8Sr1lm]Ue(EZ8Go8S
+r1lm]Ue(EZ8Go8Sr1lm]Ue(EZ8Go#Pr1lm]Ue(ES9`1GTr1-OZUe(ES9`1\Wr1-OZUe(EZ8Go8S
+r1-OZUe(EZD7$[WUnsl_V50o`Unji_Unsm.Kk'Ic.-u%*lte*:CaeXd.-taulte*:F=QWn.-tau
+qg:C$Ue(ER6N!WMr1$+OS3m.D6N!??r00MFS3m.<62Zs5r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFS3m.E9`1, at r1$+OS3m.D6N!'6r1$+OPX55;6N!'6r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFPX55362Zs5r00MFS3m.<62[6>r00MFS3m.<62Zs5r1$+OPX55362Zs5r00MFPX55362Zs5
+r00MFS3m.<62Zs5r1$+OUi$/3s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VtU<Vq/'qg:C#HoV"N3;\(_
+qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"V3r=:aqg:C#HoV"N3;\@i
+qg:C#KKB!`3r=Rkqh.$-KKB!`3r=Rko8>NuM`10b2Y2hbo8>O(KKB$i4o9mno8>NuM`1Kl4o9mn
+r/<f9KKB$i4oC7%qh.$.N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%
+r00MFN'7*'62Z[)r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%qh.#rA0gMX.-taulte*:CaeXd.-tau
+lte*:CaeXd./Ll`s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,s]SQH<3rFq"
+qh.$.N'7)t4oC7%r/<f:N'7&k3rFq"r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%qh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=:aqh.$-KKB!`3r=Rkqh.$-KKB!`3r=:aqg:C#KKB!`3rFq"qh.$.N'7)t4oC7%
+qi+VRN'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7*'62Z[)r00MFN'7*'62Z[)r/<f:N'7)t4oC7%
+r00MFPX55362Zs5r00MFPX55362Z[)lte*:CaeXd.-taulte*IKKB/5s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n)39ig"bH;gtpK/f%A3ibKS5Sbg">Tc0r<*r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%
+r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4o:4=r/<f:PX55362Z[)lte*9A0gJO,lFHT
+s8W-!s8W-!s8W-!o_/+Em-ilnkN:RTg"bH^Ui$$o62Zs5r/<f:PX55362Zs5r00MFPX55362Zs5
+r/<f:PX55362Z[)r00MFPX55+4oCRBr00MFPu7IE;>c\Vqh.$.AMN at k7+0T9daZjreCMgec-+>U
+bKS5L`Pp$Ec-+>U`5T^I`4c)ED>]Var1-OZPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5
+r00MFPX55362Zs5r00MFPX55;6N!'6r00MIs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^bKS5L`Poj0]#V4`
+qg:C$Ue(EZ8Go8Sr1lm]Ue(ES9`1GTr1$+OSP8sP9`1\Wr1-OZUe(ES9`1GTr1-OZSP8sP9`1GT
+r0:.WSP8n0YlFb's8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^bKS5O[B](?.dUt"
+r,XmrS3m.E9`1GTr1-OZSP8sP9`1GTr1-OZSP8sP9`1GTr1-OZSP8sP9`1GTr1lm]SP8sW8Go#P
+r1-OZSP8sP9`1/Qr0:.WSP8sG62Zs5r00MFN'7*'62Zs5r/<f:PX55+4oCO1r/<f:Pu7I<4oCO1
+r00MFPX55362[!Fr/<f:PX55+4oCO1r00MFN'7*'62[!Fr00MFPu7ID62Zs5r00MFPX55362[!F
+r1$+OPX52RErZ1>s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYI
+daZjkbg")F`OidrkB98ZA0gMX.-kChlXV:,A0gJO,l<6Ur1$+OS3m.=;>ctYr1-OZSP8sP9`1GT
+r1-OZSP8sP9`1GTr1-OZSP8sP9`1GTr1-OZPu7IL6N!*Gr00MFSP8sG62Zs5r00MFPu7IM9_kNC
+f:7<DKOX:i.dLUjlXV:-CaeXd.-taulte*IHoV"V3rG4.r1-OZSP8sW8Go#Pr1-OZSP8sP9`1GT
+r1-OZSP8sP9`1GTr1-OZS3m.E9`1, at r1-OZPu7IM9`1GTr0:.WS3m.E9`1DIr1$+OUi!06Xe_eh
+S=Z7HV50o`Ur\7"lte*9A0gJO,jStdlXV:-CaeXd.-taulte*:Caf1.3;f:5r1$+OPX55;6N!'6
+r00MFPX55362Z[)r00MFPX55+4oCO1r/<f:PX55+4oCO1r/<f:PX55362Zs5r00MFPX554;>cYE
+r00MFPX55362Z[)r00MFN'7*'62Z[)r/<f:N'7)t4oC7%r/<f:PX55+4oCO1r00MFPX55362Z[)
+r00MFPX55362Zs5r00MFPX55362Zs5r00MFPX55362Zs5r00MFN'7*'62Z[)r00MFPX55+4oCO1
+r:J#/s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s800Dr,XmrF#j,F3;dhXqg:C$F#j,F3;dhXr,XmqHoV%F3W*qY
+qg:C$F#j/>3W"1`r,XmqHoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\@i
+qg:C#HoV%F3W*qYr,XmrF#j,F3;\@iqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB$i4oC7%qh.$-KKB$i4o9mnr/<f:N'7)t4o9mnr/<f9KKB$i4o9mn
+qh.$-KKB!`3r=Rkqh.$-KKB!X39t*#lXV:,A0gMX.-kChlXV:,A0gJO,jStdlXV:;`2s"=s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VoUiVS9hqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rk
+r/<f9KKB$i4o9mnr/<f9KKB$i4o9mnqh.$-KKB!`3r=Rkqg:C#HoV"N3;\(_qg:C#HoV"N3;\(_
+qg:C$Cbu!#1$`?qlXV:&<$1F:,j/D^lXV:,Jn4)AO8Pejqi+VQKKB!`3r=Rkqh.$-KKB!`3r=n:
+qh.$.N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%
+r/<f:N'7&c3:(H0lte*:CaeXd.-taur3_Rbs8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-j)lgtCK>
+daZjreCMgec-k+mbKS5ZeCOGlMu8Msr/<f9KKB!`3r=Rkqh.$-KKB!X3;\@iqg:C#KKB!`3r=Rk
+qh.$-KKB!`3r=Rkr/<f:N'7)t4o:4=r/<f:N'7)[3TjWslXV:,A0grn_#OH7s8W,kpA+(Hp#tc2
+i8j(Sgtqt:Nr4i!r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4o:4=
+r/<f:N'7)t4oC7%r/<f9KKAF0,j]=qkeaRWgtp`>hU9p)daZjkbg">Tc-+>U`5T^=bg">Tc-+>U
+m^/#PN'7)t4o:4=r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r00MFN'7)t4oC7%r00MFN'7*'62Zs5
+r00MFPX55362S$0s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIfZ_O^bg")F`Pfa7`5T^HPC`Ua3rGL7r1-OZSP8sP9`1GT
+r1-OZSP8sP9`1GTr1-OZPu7IM9`1GTr1-OZSP8sP9`1GTr0:.WPX554;>ctYs8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5Sbg">Tc.S&#lte*9A0h)34oCjEr1-OZSP8sP9`1/Q
+r00MFSP8sG62Zs5r00MFPu7ID62[!Fr00MFPu7IE;>ctYr0:.WSP8sH;>cqNr0:.WPX55362Zs5
+r0:.WN'7)t4o:4=r/<f:N'7)t4oC7%r/<f9KKB$i4o9mnr/<f9KKB$i4oC7%r/<f9KKB$i4o:4=
+r/<f:N'7)t4o:4=r/<f:N'7)t4oC7%r/<f:PX55+4oCRBr/<f:N'7*'62Z[)r00MEjMClrs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH-bg")F`Pfa7]=bi$O_!W[.dLUj
+k?KM">Uni7+6QlYr+n1eN'7)t4oC7%r00MFPX55362[!Fr00MFPu7ID62[!Fr0:.WPX52+<W&(I
+r00MENE,n84oCO1r/<f:PX52+<W%e=r/<f:Pu6Y5LWH9^X/rG(XKAP)Xe_ehX/rG5PDdn1;sRs>
+lXV:,A0gJO,jStdlte*9A0h(o3W+h!r0:.WSP8sP9`1DIr0:.WPX554;>cYEr0:.WPX554;>cYE
+r00MFPX55362Zs5r00MFPX554;>cYEr00MFPu7IM9`1, at gS9t.V50o`Unji_Unsm.Kk'FZ,jStd
+lXV:(>Uo&M,jStdlXV:,A0gJO,jStdr,XmrPX55362Zs5r00MFN'7)t4oC7%qh.$.N'7)t4o9mn
+r/<f:N'7)t4oC7%r/<f:N'7)t4o9mnr/<f:N'7)t4oC7%r/<f:N'7)t4o9mnqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkr/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f9KKB$i4oC7%
+qh.$.N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7$eYlFb's8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+p[%)@F#j/71]2;Sr+n1eCbu!*1]2&Fr+n1eCbu!13W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*qY
+r,XmrF#j/>3W*qYr,XmrF#j,F3;dhXr,XmqHoV%F3W*qYr+n1TA0gJO,j/D^lXV:(>Uo&M,j/D^
+lXV:,A0gJO,lD^Dqh.$-HoV"N3;\(_qg:C#HoV"N3;\@iqg:C#KKB!`3r=Rkqg:C#KKB!`3r=:a
+qh.$-HoV"V3r=Rkqg:C#KKB!X3;\@iqh.$-KKB!`3r=Rkqg:C#KKB!`3r=:aqh.$-HoV"V3r=:a
+r,XmaA0g>C.dLUjlXV:,A0gJO,jStdk?KM&A0gJO,k&C+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r1n3,HoV"N3;\(_qg:C#HoV"N3;\(_qh.$-KKB!X3;\@iqh.$-KKB!`3r=Rk
+qh.$-HoV"V3r=:aqh.$-HoV"N3;\(_qg:C#HoV%F3W"1`r+n1eAMN:G+6?HDj]!>`<$14$+6QlY
+lte*%S:9).^!bE]fZ_O^bg"eabNQ:2qODj.KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$.N'7&k3rFq"
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$.N'7&k3rFq"qh.$.N'7)t4o9mnqh.#rA0gJO,jStd
+lXV:,A0gMX.0'>Is8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f$`(!daZk#bfe2Rc-+>U
+fZ_P:SP8p.3;\@iqg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$.AMN at Q.d(%dlte*Em-"$7q<[_Gkj7crjQG4OhWVh\qh.$-KKB!`3r=Rk
+r/<f9KKB$i4o9mnr/<f9KKB$i4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4o:4=r/<f9KKB!`3rEeM
+k?KM!Xde80kMYFag"bH;gtpK/f%A3ibKS5Sbg")F`QQKM`5T^=bg"bX^&*dhqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkr/<f9KKB$i4oC7%qh.$.N'7&k3rFq"r/<f9KKB/5s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oo
+g"bH4eCMRW`Pfa7`5T^6`Pom*Z0ZQ^r00MFPX55362[!Fr00MFPu7ID62Zs5qi+VRPX554;>cYE
+r0:.WPu7IE;>c\Vr0:.WPX554;>cYEr00MDbbkF?s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYI
+daZjkbg">Tc, at T?a0i2=CaeXd./[m;r00MFPX554;>cA9r0:.WPX55+4oCO1r0:.WN'7*'62Z[)
+r00MFPX55362[!Fr00MFPX554;>cYEr/<f9NE,n84oC7%r/<f9KKB$i4o:4=qODj%U2o at cLY-`S
+r+.VG>UoVU0)TNAr,XmqHoV"N3;\@iqg:C#KKAsW=Smb4qg:C#KKB!X3;\@iqh.$-KKB!`3r=Rk
+qh.$-NE,n84o9mnr/<f9KKB$i4oC7%qh.$-NE,n84oCRBs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gi8j(Sgtp5uc-+>U`5T^-]Y1hWWp=1 at j]!>`<$14$+6?HDk?KLu<$2!j3rFq"
+r/<f:N'7&t<W%e=r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f:N'7)t4oC7%r/<f9KKB$i4oC7%
+r/<f:Pu6bAO0l:$['[3 at XKAP)XfJP*X/rG(XKAP)XfJP*X/rG5PDe444Qfs!lXV:,A0g>C.dLUj
+lXV:,A0gMX./SZYr/<f:PX55+4oCO1r/<f:N'7)t4oC7%r/<f:N'7&t<W%e=r/<f9NE,n84oC7%
+r/<f:PX55362Z[)r00MFPX554;9,)aX/rFnSt)UQUr\7"k?KM">Uni7+6?HDlXV9o<%[HQ.,&/h
+k?KM">UoYf1]31pr/<f:N'7)t4o9mnqh.$-KKB!`3r=Rkqg:C#KKB!X3;\@iqg:C#KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=:aqg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\@i
+qg:C#KKB!X3;\@iqh.$-KKB!`3r=Rkqg:C#KKB!`3r=Rkqg:C#KKB!`3r=Rkqg:C#KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkr3_Rbs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VqcH2M5.r+n1eAMO+!1]2&F
+r+n1eAMO+!1]2&Fr+n1eCbu!*1]2&Fr+n1eCbu!*1]2;Sr+n1eF#j/71]2;Sr,XmrF#j/71]2;S
+r+n1eF#j/71]1f=lXV:(>Uni7+6?HDj]!>b>Uni7+6?HDj]!>`<$14$+513_k)EEo[&hlt^$MnL
+qh.$-HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;dhXqg:C#HoV"N3;\(_qg:C#HoV"N3;\(_
+qg:C#HoV%F3W"1`r,XmqHoV"N3;\(_r,XmqHoV%F3W*qYr,XmqHoV%F3TjWsk?KM">UnoA.d(%d
+j]!>b>UnoA.cjVOk?KM5`2s"=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qe?Jjl3W"1`
+r,XmrF#j/>3W"1`r,XmqHoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qg:C#HoV"N3;\(_
+qg:C#HoV"N3;\(_r+n1TA0g89+6?HDj]!>b>UnoA.cjVOkB98GXImqjf%Jj8daZjreCN'tf$`(!
+daZk#bfe2Rc03$KqODj.KKB!X3;\@iqh.$-KKB!X3;\@iqh.$-HoV"V3r=Rkqg:C#KKB!X3;\@i
+qg:C#KKB!`3r=:aqh.$-HoV"V3r=Rkqg:C#KKB!X3;dhXk?KM&A0gJO,jStdlXV:;S9b/7s8W-!
+s8W-!s8W-!s8W-!o_/+QpA*Y-kMYFag"bH;gtpK/f$`(!bKS5ZeCMgec.BnIqh.$-HoV"N3;\(_
+qg:C#HoV"N3;\(_r,XmqHoV%F3W"1`qg:C#HoV"N3;\(_qg:C#HoV"N3;\@iqg:C#KKB!`3rF%Z
+j]!>`<$14$+6f#<kj7d%m-ilnkLnYIl.+D_NE,k'3;\(_qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$.N'7&k3r=Rkqh.$-KKB!`3r=Rkr+n1P>Unlq<p8o=kj7d%m-ilnkN:RT
+daZjreCMgec.L7``5T^=bg")F`Pfa7bKS6,V2P4u3;\@iqg:C#KKB!`3r=Rkqh.$-KKB!`3r=Rk
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkr4Ijcs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQFt at f$`(!bKS5Sbg")F`Pfa7
+ert[^HoV%_4oCO1qi+VRN'7)t4oC7%qi+VRN'7)t4o9mnr/<f:N'7&t<W%e=r00MFN'7&t<W%e=
+r/<f:N'7*(;?-[rs8W-!s8W-!s8W-!s8W-!s8V`bq;C>si8j(LeCMgec, at T?`5T^6`Pp&`AER2I
+lXV:<HoV%g62Z[)r0:.WN'7)t4oC7%qi+VRN'7&k3rFq"qi+VQKKB!i<VqG1r/<f:N'7)t4oC7%
+r/<f:N'7)t4o9mnqh.$-KKB!`3r,"_kbX?\[B[?V]t:qj['[3P]Y1hWWlU*Hl"!'@<$13r*W'(o
+qeSRqHoV"N3;\(_qg:C#HoV"N3;\(_qKuEBKKB!X3;\@iqKuEBKKB!X3;\@iqg:C#KKB!`3r=Rk
+qKuEBKKB!`3r=Rkqh.$-KKAtJXT/>#s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG4OhTO-f
+bKS5L`PoI%]sP/RaG"-c<$14$+6?HDj]!>`<$14$+8f\)qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rk
+qi+VQKKB!`3r=Rkqh.$-KKB!`3r=Rkqg:C#KKB!X3;\@iqh.$-NE,,CS&W+P]=bhh]Y1qi]sP/R
+X/rG1['Zm8XfJP*X/rG(XKAP)XfJP*Unsm.Kk'4D+6?HDj]!>`<$14$+6?HDk?KLu<$2$S1])hd
+qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$.N'7&k3rFq"qh.$.N'7)t4o:4=r/<f:N'7&t<W%e=
+r/<f:Pu4?RUnji_UnslrHtqhL.cjVOfi0Qb<$0dm/a$@gk?KLu<$1:..cjVOr+n1eN'7&k3r=Rk
+qh.$-KKB!`3r=:aqg:C#HoV"N3;[emqg:C#HoV"N3;\(_qg:C#HoV"N3;\(_qKuEBHoV"N3;\(_
+r,XmqHoV"N3;dhXqg:C$F#j,F3;dSKr+.VKA0h%P-fn;Lqc,$AAMO+!1]2;Sqg:C#HoV%F3W"1`
+qg:C$F#j,F3;\(_r,XmqHoV"N3;\(_r,XmqHoUtM=SmJ*qg:C#KKB!X3;\@iqg:C#HoV"N3;\(_
+qg:C#KKB$r;?-[rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7ta7r+n1eAMO*o1&G3.qckcN>V>qc1&PT;r+.V\AMO*o1&PT;
+r+.V\Cbu!#1&PiDr+.V\Cbu!*1]2&Fr+n1eCbu!*1]2&Fr+n1eCbu!*1](E0j]!>`<$14$+6?HD
+j]!>`<$14$+6?HDj]!>T<%[32+6QlYb`QGf`4aUKf$`(!bKS5Sbg"eabN,gRqh.$.F#j/>3W*qY
+r,XmrF#j/>3W*qYqg:C$F#j/>3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*qYr+n1eF#j/71]2&F
+r+n1eCbu!13W*\Lr,XmrF#j/>3W*qYr+.VE<$14$+6?HDj]!>`<$1:..cjVOj]!>b>Uni7+8<=C
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq>$7tr+n1eCbu!*1]2;Sr,XmrF#j/>3W*qY
+r,XmrF#j/>3W"1`qg:C#FAD^\3;\(_qg:C$F#j,F3;\(_r,XmqHoV"N3;dhXr+n1TA0g89+6?HD
+j]!>`<$1:..cjVOlXV:'Xde80kMYFai8j(ZjQG[\gtCK>g"bH4eCN'tf$`(!daZjkbg"eabLa\G
+q36%"F#j,F3;\(_qg:C#HoV"N3;\(_qg:C$F#j,F3;\(_r,XmqHoV"N3;dhXqg:C#HoV%F3W"1`
+qg:C$F#j,F3;\(_qg:C$F#iPs,iquIk?KM">UnoA.dLUjp[%)Cs8W-!s8W-!s8W-!s8W-!s7H$\
+kj7d%m-j)lgtCK>daZjreCMgec-+>UdaZjkbg#@aYkrf-qg:C$F#j/>3W*qYr,XmrF#j/>3W*qY
+r,XmrF#j/>3W*qYr,XmrF#j,F3;[emqg:C#FAD^\3;dhXqg:C#HoV%81$)+Mj\6cW<$1>:Yi+U*
+i8j(SgtqmtH2DtKr,XmqHoV%F3W"1`qg:C#HoV"N3;\(_qh.$-HoV"V3r=Rkqh.$-KKB!`3r45+
+qh.$-HoV"N3;\(_qh.$.F#iDg.d(tCp[%)0oC_JAp#tc2i8j(`gt^T<hU9p)bKS5Sbg">Tc-+>U
+`5T^=bg")F`Rqi3qh.$-HoV"N3;\(_qfGU1HoV%F3W"1`r,XmqHoV"N3;\(_qg:C#HoV"N3;\(_
+qg:C#HoV"N3;\(_qKuEBKKAsW=TAF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIdaZjkbg")F`Pfa7`5T^8]XmHG./SZYqh.$.N'7&k3rFq"
+qh.$-KKB!`3r=Rkqh.$-KKAm\@f(g>qh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkr3_Rbs8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7crjQFt@f$`(!bKS5L`Pod7`Q,Bkk?KM">Uo&M,l<6Uqh.$-NE,k/3rFq"
+qh.$-KKB$i4o9mnqh.$-KKB!`3r=Rkqh.$-KKB!`3r=Rkqh.$-KKB!`3r45+qh.$-KKAsW=Sn(X
+k,k,m]Xl+q]">Vg]=bhh]Y1qi]t:qj['[3P]Y1hWWlU*Hk?KLi9-E:b)#I;\r+.V\F#j,F3;[em
+qg:C#HoV%F3W"1`qg:C#FAD^\3;\(_qg:C#HoV"N3;S#)qg:C#HoV"N3;\(_qg:C#HoV"V3r=Rk
+qh.$1s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_&&kLnYIdaZjkbg")F`Oidr]=bheXfC&R/`]A<
+fh3IL9c_n[+QZQEj\6cnF#j,F3;\(_qg:C"Hs$8n3;\(_qKuEBHoV"N3;\(_qKuEBHoUtM=SmJ*
+qKuECF#j,F3;S#)r,XmpHs$<BD:m(UbKS5Sbg")F`Oidr]=bhh]Y1\Z[&^:1X/rG(XKAP)XfJP*
+X/rG(XKAP)Xf.\Rgh]+7<$14$+6?HDj]!>`<$14$+6?HDj]!?"AMO(83r45+qg:C#KKAsW=SmJ*
+qg:C"Hs$8n3;\@iqKuEBKKB!X3;\@iqh.$-KKB!`3r=Rkr/<f:N'7)t4o9mnq36#tV50o`Ur[Xa
+j]!>T<%[32+6?HDj]!>T<%[32+5'UFj]!>`<$2$L1&H>Xqg:C#HoV"N3;[emr,XmrF#j/>3W*qY
+r,XmrF#j/>3W!VYr+n1dCdIu81]2;Sr,XmrF#j/>3W*qYr,XmrF#j/>3W*qYr+n1eF#j/71](E0
+qc,$)7Mt2U)!".'j at 1!>9-Dn\+QQ!/j at 1!J<$2!;-i at d:r,XmrF#j/71]2;Sr+n1eCbu!13W*qY
+r+n1eF#j/>3W*qYr,XmrF#j/>3W!nnr,XmrF#j/>3W"1`qg:C$F#j,F3;dhXqg:BqpA+ags8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,qS9b$D1&FruqckcN>V>nY0)Jm+qc,$@<@@ZD-i7.$qckcN>V>qc1&G3.r+.V\AMO'e0)T98
+r+.V\AMO*o1&PT;r+.V\AMO*o1&Fruj\6cW<$0dd+QZ<<fh3I at 9-Dn\+PBC1fh3IL<$0dd+QZQE
+g4Wqe`4ajZhV$]@g"bH;gtpK/f$`(!daZk#bfe2Rc17TLr,XmrF#j/>3W*\Lr,XmrCbu!*1]2;S
+r+n1eF#j/71]2&Fr+n1eCbu!*1]2&Fr+.V\Cbu!#1&PT;r+n1eAMO*o1&PT;r+.V\AMO*o1&PiD
+r+.V\Cbu!#1$)@Vj]!>`<$14$+5'UFj]!>`<$0dd+QZQEj]!>r\YfE,s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\prgJNCbu!#1&PiDr+.V\AMO+!1]1f=r+n1eAMO+!1]2&Fr+n1eCbu!*1]2&F
+r,XmrCbu!13W*qYr+n1eF#j/>3W*\Lr+n1d>V>,;+6?3;j\6cW9c`=p+6?HDj]!>fJn4-!\a8q\
+m.9oEm-!U!n*'-,kj7crjQG4OhV$]@g"bH4eCN'tf$`(!daZjkbg"eabPA9)qg:C#CdIu?3W*qY
+r,XmrF#j/>3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*qY
+r+.VE<$14$+6?HDj]!>`<$1t,H2mpEs8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp`>hU9p)
+daZjreCMgec.L7`bKS6%U2p0Q3W*qYr,XmrCbu!13W*\Lr,XmrCbu!13W*\Lr+n1eCbu!*1]2&F
+r+n1eCbu!*1]2&Fr+n1eF#j/71]2;Sr+n1N<$10j)!".'k?KM$e^rL0hY4RXr,XmrF#j/>3W*qY
+r,XmrF#j/>3W*qYqg:C$F#j/>3W"1`r,XmqHoV%F3W!nnqg:C#HoV"N3;\(_qg:C#HoV%F3TX3^
+k?KM4gsQ0%s8W-!o_/+QpA*q=n*'-,g"bH;gtpK/f#u:^bKS5L`Pp$Ec-+>UbKS5L`Pq\DH2M_D
+r,XmrF#j/>3W*qYr,XmrCbu!13W*qYr,XmrF#j/>3W*qYqg:C$F#j/>3W"1`qfGU1HoV%F3W"1`
+r,Xmp`2s"=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(SgtpK/f%A3i`5T^6`Pod7`RgW/r+n1dHoV"V3r=:aqh.$-HoV"N3;S#)qh.$-HoUtM=Smb4
+qh.$-HoV"N3;\(_qKuEBHoV"N3;S#)qg:C#HoUclq>^Kps8W-!s8W-!s8W-!o_/+Em-ilnkLnYI
+daZjkbg")F`Q#R%`5T^:Mga\d+6?3;r+.V[HoV"N3;\(_qg:C"Hs$9!3r=RkqKuEBKKB!`3r=Rk
+qh.$-HoV"V3r=:aqKuEBHoUtM=Smb4qKuEBHoV"N3;\@iq5on)bg">Tc, at T?]=bhq`PoI%]uI^r
+['[3P]Y1qi]sP/R]=bhh]Y1hWWmbuefh3IK7MsfG)>dD]r+n1eF#j/>3W*qYr,XmrF#j/>3W*qY
+r,XmqCdIu?3W!VYr,XmrF#j/>3W"1`r,XmrF#j,F3;[emr,XmpHs$8n3;g1Es8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2i8j(LeCMgec, at T?]=bhh]Y1\Z[)m].j at 1!>6Q+rS)!".'j at 1!I7Mu#&-i at d:
+r,XmqCdIu?3W*qYr,XmrF#j/>3W*qYqeSRrF#j/>3W*qYr,XmrF#j/>3W*qYr+n1eF#j,F3;URp
+g"bH;gtpK/f#u:^bKS5L`PoI%]t:qj['[3I['[?FWiN5'X/rG(XKAP)Xe_eh\Vbdr<$0dd+QQ!/
+fh3I at 9-E=q+5':0j]!>`<$2$S1])PZqg:C#HoV"N3;dhXqg:C#FAD^\3;\(_qg:C$F#j,F3;\(_
+qg:C"Hs$8n3;\(_qKuEBKKB!X3;\@iqg:C#KKB!`3ldYJUnsm.FC*Wn+PBC1fh3I at 9-E=q+5':0
+j]!>T9-E=q+5':0qckcNHoV%F3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W*\Lr+n1eCbu!*1]2&F
+r+n1eCbu!*1]2&Fr+n1eCbu!*1]2&Fr+n1eCbu!*1[BX'[uH*_D,f1U);. at pfg?Y16Q+QE);. at p
+j at 1!>6Q+QE)<=7(j at 1!I7Mu#&-i at O1r+n1eCbu!*1]2&Fr+n1eCbu!*1]2&Fr+n1eCbu!*1]2&F
+r+n1eF#j/71]2;Sr+n1eCbu!*1]2;Sr+n1eF#j/>3VhIXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vi[kPSmGqc,$@>V>nR-i6mk
+qc,$@<@@ZK0)JWrqc,$@<@@ZK0)Jm+qc,$@>V>nY0)Jm+qckcN>V>nR-i7.$qckcOAMO*o1&G3.
+j]!>_7Mt5]*TT[,fh3IL9c`:a)!+I4j\6cK9-E:b)!".'fi0QUXInG3kMYFakj7ckgtpuMkLnYI
+g"bH;gtpK/f$`(!bKS5ZeCN9b[ek_=r+n1eAMO*o1&PiDr+.V\AMO*o1&PT;r+.V\AMO'e0)Jm+
+qckcN>V>nY0)Jm+qckcOAMO'e0)T98r+.V[>V>nY0)T98qckcOAMO*o1&PT;qckc89c`:a(thP)
+fh3I at 9-E=j*SF(.j\6cV7MsfO+RZUss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+TF<W$D_
+qckcN>V>qc1&G3.qckcOAMO'e0)T98r+.V\AMO*o1&PT;r+.V\Cbu!#1&PT;r+.V\Cbu!#1&PT;
+r+.V\AMN:@*TT[,j at 1!I7MsfO+QQ!/fg?Y19-EJ`II-Ruo_/+QpA+ at Sq=OCVo_/+IoC_>6n*'-,
+i8j(ZjQG[\gtCK>daZjreCN'tf%A3ibKS5Sbg"eQ[ebARr+n1eCbu!#1&PiDr+n1eAMO+!1]2&F
+r+n1eCbu!*1]1f=r+n1eAMO+!1]2&Fr+n1eCbu!*1]2&Fr+n1eCbu!#1$)@Vj\6cK9-E=j*SF(.
+j]!?%s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ik1nb?eCN'tf$`(!bKS5ZeCMgec-+>U
+q36%"Cbu!*1]2&Fr+n1eCbu!#1&PT;r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V\Cbu!#1&PiD
+r+n1eCbu!*1]1f=j at 1!>9-DnT);9aQfZ_P9HoV%?1]2&Fr+n1eF#j/>3W*qYr+n1eF#j/71]2;S
+r,XmrF#j/>3W*\Lr,XmrF#j/>3W*\Lr,XmrF#j/>3W!VYqc,#s9-F)LXT/>#s8W-!s8W-!s7H$\
+o_/+Em-iW_hV$]@daZk#bfe2Rc, at T?bKS5L`Pod7`QQKMfY"ZjCbu!*1]2&Fr+n1eCbu!*1]2&F
+r+n1eCbu!*1]2&Fr,XmrCbu!*1]2;Sr,XmrCbu!13W*qYr,XmrF#j/>3W*qYs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o.jQG4OhU9p)bKS5L`Pod7`Pfa7
+`k8n<CcqW31])PZqg:C#FADaT3W"1`qfGU1HoV%F3W"1`r,XmrF#j/>3W*qYr,XmqCdIu81](uS
+r+n1eCbu!*1]!Ves8W-!s8W-!s8W-!s8W-!s8V`bq<726g"bH4eCMgec-+>U`5T^-]Y1qi^"QsS
+fg?Y<7Mu&>1]2;Sr,XmrF#j/>3W"1`r,XmqHoV%F3W"1`qfGU1FAD^\3;\(_qfGU1HoV"N3;\(_
+qg:C#HoV"N3;\(_on[GHbfSPnhU9p)bKS5Sbg">Tc, at T?]=bhh]Y1qi]t:qj]=bhh]Y1\Z[(Eua
+]=bhh]Y2CEIG$t*j at 1!A4r!'I)#IPjr+n1eF#j/71](uSr+n1eCbu!*1]2&Fr+n1eCbu!*1](uS
+r+n1eF#j,662YdaqeSRrF#j/>3W*\Lr,XmqFADl9s8W-!s8W-!s8W-!s7H$\m.9o.jQG4OhTO-f
+`5T^-]Y1qi]sP/R\?2da9-E"R']__#gccG-4qud9']__#qckcOCbu!*1]2&Fr+n1eCbu!*1]2&F
+r+n1eCbu!*1]2&Fr+n1eCbu!*1]2&Fr+n1eCbts)62YdaprgJ:m-ilnkLnYIg"bH4eCMgec, at T?
+`5T^-]Y1\Z[&^:1X/rG(XKAP)XfJP*\XJc'@nPfO)!".'j at 1!I7MsfO+QZ<<j at 1!I7Mu#&-i at d:
+r,XmrF#j/>3W*qYqg:C$F#j/>3W*qYr,XmrF#j/>3W*qYr,XmrF#j/>3W"1`r,XmqHoV"N3;dhX
+qg:C#FAD^\3;\(_qg:C#KK>p*Ur[CPj at 1!I7Mt2U(th7ofg?Y<7MsfG)<=7(j at 1!I7Mu#&-iA$G
+r+n1eF#j/71]2&Fr,XmrCbu!*1]2&Fr+n1eF#j/71]2&Fr+n1eCbu!#1&PT;r+n1eAMO*o1&PiD
+r+.V\Cbu!*1](uSb`QG+St)=BS=H1@[rc*?7Mt2U(th7oj at 1!I7MsoE']__#fg?Y<7MsoE']__#
+j at 1!`<@@]U1&PiDr+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V\Cbu!#1&PT;r+.V\Cbu!#1&PiD
+r+.V\Cbu!*1]2&Fr+n1c`2s"=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!q5onY<@@ZD-i6mkqc,$@<@@ZD-i6mkqc,$@<@@ZD-i6mk
+qc,$@<@@ZD-i6mkqc,$@<@@ZD-i6mkqc,$@<@@ZD-i6mkqc,$)7Mt2U(th7ofg?Y44r!'I(th7o
+fg?Y44r!'I(th7ofg?Y2 at lDu`bNS<]kj7d%m-j0)n*'-,kj7d%m-ilnkLnYIg"bH;gtpK/f$`(!
+bKS5Sbg#sJFo5f*r+.V[>V>nY0)Jm+r+.V[<@@ZD-i6mkqc,$@<@@ZD-i6mkqckcN<@@ZD-i6mk
+qc,$@<@@ZD-i6mkqckcN<@@ZK0)Jm+qckcN>V>nR-eUj)fg?Y<7MsfG)<=7(gccG57MsfG);. at p
+gccGH\YfE,s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=rI]r+.V[<@@]U1&G3.qckcN>V>nY0)Jm+
+qckcN>V>nR-i7.$qc,$@>V>nY0)Jm+qckcOAMO'e0)Jm+r+.V\AMO'^-fd`6j at 1!I7MsfG)<=7(
+fg?Y44r!'I)!IfWo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+ILkNM:$i8j(ZjQG[\gtCK>
+daZjreCN'tf$`(!bKS5_`4c"p=Su_br+.V\AMO*o1&PT;r+.V[>V>nY0)T98qckcOAMO*o1&G3.
+r+.V[>V>qc1&PT;r+.V\AMO'e0)T98r+.V[<@?Qc']__#gccG57MsfG)>]kKs8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\p[%),m-ilnkLnYIg"bH4eCN'tf#u:^bKS5ZeCN6i^&*1:r+n1eCbu!#1&PT;
+r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V[>V>qc1&PT;r+.V\AMO'^-epm"
+j at 1!I7Mu#E:AeZXr+.V\Cbu!#1&PiDr+.V\AMO*o1&PT;r+n1eAMO*o1&PT;r+n1eAMO+!1]1f=
+r+n1eCbu!*1](uSr+n1d<@?He)>]kKs8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7ckgtpK/f#u:^
+bKS5Sbg">Tc-+>UfZ_OW`Pp$Ec1lp#r+.V\AMO*o1&PT;r+.VYANfs&1&PT;r+n1eAMO*o1&PiD
+r+.V\AMO*o1&PT;r+.V\Cbu!#1&PiDr+n1eCbtk0_#OH7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH4eCMgec-+>U`5T^6`PoooSblD7r,XmrF#j/71]2;S
+r,XmrCbu!*1]2&Fr+n1dCdIu81](uSr+.V[CdIu11&PiDr+.V\Cbu!#1&PiDr+.VYjPg.=s8W-!
+s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5L`PoI%]u7n/aK25k6Q+ZC'`1lXr+n1eCbu!*1]2&F
+r+n1eCbu!*1](uSr+n1dCdIu?3W*qYr,XmrF#j/>3W*qYr,XmqCdIu?3W!VYr,XmpHs$0nal)7C
+i8j(Sgtp`>hU9p)bKS5Sbg")F`Pfa7]=bhs]XkJW[(Eua]=bhh]Y1\Z['[3I['[3^HtV4u'\Phk
+gccG57Mu#-0)T98r+.V\Cbu!*1]2&Fr+.V\Cbu!#1&PiDr+.V\Cbu!*1]2&Fr+n1eCbu!*1]2&F
+r+n1eCbu!*1]2&Fq5on]s8W-!s8W-!s8W,coC_>6n(HLQdaZjkbg")F`Oidr]=bha['[o-EnNet
+gccG-4r!'I(u.:hj at 1!J9ca.J1]2&Fr+n1eCbu!*1]2&Fr+.V\Cbu!*1]1f=r+.V\AMO+!1]1f=
+qeSRrCbu!*1]2&Fr+.VZ`2rV)q<726kj7crjQG4OhU9p)bKS5Sbg!c4]t:qj['[3P]Y1AIXfJP*
+X/rG6Km;9M/_iN(fg?Y44qu[;);. at pfg?Y44r!'I)#IPjr+n1eCbu!*1]2&Fr+n1eCbts)62YOT
+r,XmrCbu!*1](uSr+n1dCdIu81]2&Fr+n1eCbts)62YOTqeSRrF#j/>3W*qYr,XmrF#j,>:?ROT
+Unsm.D,f1U);ICigccG*6Q+ZC'\kkdfg?Y44qud9'\Phkqc,$AAMO+!1]2&Fr+n1eCbu!#1&PiD
+r+n1eAMO+!1]1f=r+.V\Cbu!#1&PT;r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;qeSR=R>m`.S=H1@
+S=Z7HV50WQS at W9-gccG57MsoE'\kkdgccG-4qud9'\kkdgccG-4qud9'\kkdqc,$AAMO*o1&PT;
+r+.V\AMO+!1\kTFr+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V[>V>qc1&7Z(
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+Vt1&Fruqc,$@<@@ZD-i6mkqc,$@>V>nR-i7.$qc,$@>V>nR-i6mkqckcN<@@ZD-i7.$
+qc,$@<@@ZK0)JWrqc,$@<@?Qc'\kkdgccG*6Q+QE);. at pfg?Y16Q+QE);. at pgccG-4qu^\2WifM
+kj7d%m-j<4p$D;Cp[%)0oC_JAp#tc2kj7d%m-ilnkLnYIg"bH;gtpK/f$`(!bKS5qP^WF/-i6mk
+qc,$@<@@ZD-i7.$qckcN>V>nY0)T98qckcN>V>nY0)Jm+qckcN>V>nY0)JWrqckcN>V>nR-i6mk
+qckcN<@@ZD-i7.$qc,$)7MsoE'\kkdj at 1!A4qud9'\kkdj at 1!A4r!'I)#::us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9oHS9b!:0)Jm+qc,$@>V>nY0)Jm+qc,$@>V>nY0)Jm+qckcOAMO'e0)Jm+
+qckcN>V>nR-i7.$qc,$@>V>nR-i6mkj at 1!I7MsoE'\kkdgccG-4qud9'\kkdk_<pRs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n*'-,i8j(Sgtp`>hV$]@daZjreCN9rbKJ,S
+f>PB#Cbtrn0)Jm+qckcN>V>nY0)T98qckcN>V>qc1&G3.r+.V\AMO*o1&G3.r+.V[>V>qc1&Fru
+r+.V[>V>nY0)JWrgccG-4qu[;);ICifg?Y?>UodRs8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+kj7d#gt^T<hU9p)daZjreCN9rbKJ,SbKS5`]XI`S1]1f=qckcOAMO'e0)T98qckcOAMO*o1&PT;
+r+.VYANfs&1&5BDr+.V\AMO*o1&PT;r+.V[>V>qc1&PT;qckc77MsoE'`1lXr+.V\AMO*o1&PT;
+qckcOAMO*o1&PT;r+.V\AMO*o1&PT;r+.V\AMO*o1&G3.r+.V\AMO*o1&PT;r+.V\AMO'^-epm"
+k\Nrms8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)iE\g"bH4eCMgec-+>U`5T^=bg")F`QQKM
+`5T^ZZ`*b;62YOTqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIar+n1dCdIu11&PT;
+r+.V\AMO*o1&PT;qKuEFs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+kj7ckgtpK/f%A3i`5T^6`Pod7`Pfa7g1*&<>V>qj1]1f=r+.V\AMO*o1&GcQr+.V\Cbu!#1&GcQ
+r+.V\Cbts)62YOTq.2_dCdIu81](uSqeSRqCdI`MD#aP8s8W-!s8W-!s8W-!s8W,coC_>6n(HLQ
+daZjkbg")F`Pfa7`k8mp]Y2C>EnihmgccGL<@@]U1&PT;q.2_eAMO*o1&5BDr+n1eAMO+!1]2&F
+r+.V\Cbu!*1]1f=r+n1eCbu!*1]2&Fr+n1eCbu!*1\\GWo_/+IoC_>6n)39ig"bH;gtpK/f$`(!
+bKS5L`Pod7`Oidr]=bhh]Y1\Z[(Eua['[3P]Y1qi]st2Ee6YPr6Q+QE);. at pj@1!aAMO'u62YOT
+qeSRqCdIr762PIaqeSRqCdIr762YOTr+.V\AMO*o1&PiDr+n1eCbu!*1]2&Fr+n1eAMO+(3WK-Z
+s8W-!s8V`bq<[_Gi8j(Sgtp5uc, at T?]=bhh]Y1\Z['[3Ia]U^\4qud9'\kkdgccG-4qud9'`1lX
+r+n1eCbu!#1&PT;r+n1bANfs-1]1f=q.2_eCbts)62PIar+n1dCdIu11&PT;q.2_eCbtpXH2mpE
+o_/+QpA+(Hp#+ooi8j(LeCN'tf#5PH`5T^-]Y1\Z[&^:1['[39V52.A9&)TEgccG-4qud9'\kkd
+fg?Y44qud9']i%0r+.V\AMO+!1]1f=r+n1eAMO+!1]1f=r+.V\AMO*o1&PiDr+n1eAMO+!1]1f=
+r+n1eAMO+!1]1f=r+n1eAMO*o1&PT;r+n1eCbts)62Gt2\XJbYV50o`UpkGTgccG-4qu[;);. at p
+gccG*6Q+ZC'\kkdfg?Y44r!*Q*W0J'r+.V\AMO*o1&PT;r+.V\AMO*o1&PT;r+.V\AMO'u62Y:K
+qeSRrCbts)62YOTq.2_eCbu!#1&GcQr+.V\Cbt:0Cn.)eUnslWSt)=BS=H1 at S=Z7LN/$"Y+PB+"
+fg?Y16Q+QE);. at pfg?Y16Q+QE);. at pfg?Y44qu[;)>n&#r+n1dCdIr762>(TqeSRrCbts)62Y:K
+q.2_eCbu!#1&GcQr+n1bANfs&1&5BDr+.VYANfs&1&GcQr+.VYP]d$+s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8'[8qc,$@<@@ZD-i6mk
+qc,$@<@@ZK0)JWrqckcN>V>nY0)Jm+qckcN>V>nY0)Jm+qckcN>V>nY0)Jm+qckcN>V>2E.bR0,
+fg?Y16Q+!7,2#=$fh3I at 6Q+QM+PB+"fh3I at 6Q+!7,2#pIk01s2m-j<4p%7tRo_/+QpA+ags8W-!
+o_/+QpA+ at Sq=j7=kj7crjQGI^kLnYIg"bH4eCN'tf#u:^pk*&Q>V>qc1&G3.r+.V[>V>nY0)Jm+
+qckcN>V>nY0)T98qckcN>V>nY0)Jm+qckcN>V>nY0)Jm+qckcOAMO'e0)Jm+qckcN<@@ZD-epm"
+gccG*6Q+ZC'\kkdfg?Y44qu[;);. at pgccG9Z`*p(s8W-!s8W-!s8W-!s8W-!s8W,kpA+OFiVRFW
+qckcN>V>qc1&G3.qckcOAMO'e0)T98qckcOAMO'e0)Jm+r+.V[>V>nY0)T98qckcN>V>qc1&G3.
+r+.V[<@?Qc'\Phkfg?Y44qu[;);. at pfg?Y1>s%]Pq>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\o_/+Em-j0)n*'-,k1nbFgtp`>hU9p)bKS5ZeCMgec02L4qckcOAMO'e0)T98
+r+.V[>V>qc1&PT;r+.V\AMO*o1&PT;q.2_eAMO+!1]2&Fr+.V\AMO*o1&PT;r+n1eAMN:G+5'"!
+fh3I at 6Q+QE);. at pprgJQs8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,k1nbFgtp`>hTO-f
+daZjkbg"eabKJ,SkbX@<AMO*o1&PT;r+.V\AMO*o1&PT;r+.VYANfs&1&5BDq.2_eAMO!l4o&YP
+q.2_bANfj#4oAkGr+.V\AMO*o1&G3.j at 1!aAMO*o1&PT;r+.VYANfs&1&PT;r+.V\AMO*o1&PT;
+r+.V\AMO*o1&PT;r+.VYANfs&1&PT;r+.V\AMO*o1&G3.fg?Y=<$1c+q>^Kps8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7d%m-iW_hU9p)fZ_O^bg"eabJ_B=bKS5L`Pp$Ec-+>Upk*&QCdIr762PIa
+qeSRqFADaT3W!nnr,XmqFAD^L62YdaqeSRrF#j,662PIaqeSRqCdIr762PIaqeSRoANfs&1&9nh
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjkbg">Tc, at T?
+`5T^:XJP#Q*W0J'r+n1dCdIr762PIaqeSRqCdIr762YdaqeSRqCdIr762PIaqeSRqCdIr762PIa
+qeSRqCdIr762PIaq:sBts8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp5uc-+>U`5T^6`Pod7`Q#R%
+e6YPr6Q+QE)>n&#qeSRrCbts)62PIaqeSRrCbts)62PIar+n1bANfs-1]1f=q.2_eAMO!l4oB+P
+q.2_eAMO+!1\kTFqi+VUs8W-!s7H$\o_/+Em-j0)n)39ig"bH4eCN'tf#u:^`5T^6`Poj0]">Vg
+`k8mi['[HX]sP/R]=bhh]Y1kEPhA\Pfg?Y16Q+QE)>dD]qeSRqCdIr762PIaqeSRqCdIr762PIa
+qeSRqCdIr762PIaqeSRrAMO'u62Y:Kq.2_eCbtlu4oB+PqeSRnbJ=/Xs8W-!m.9o.jQG4OhU9p)
+bKS5L`PoI%]sP/R['[3MPDe3['\Phkfg?Y16Q+QE);ICij at 1!aCbu!#1&PT;qeSRrAMO!l4oB+P
+qeSRqCdIu81](uSr+n1dCdIu81](uSqeSRrCbts)62Pb!o_/+\s8W-!s8W-!m.9o6m-ilnkLnYI
+bKS5Sbg!c4]t:qj]=bha['[B$I+_INfg?Y16Q+QE);. at pfg?Y16Q+QE);. at pqckcOCbu!*1]2&F
+r+n1dCdIu81](uSq.2_dCdIu81](uSr+n1bANfs-1\kTFr+n1dCdIr762PIar+n1dCdIl.4oB+P
+qeSRrAMO*o1&GcQfo10OV50o`Unji_UnslqCg#FY)9G;kfg?Y16Q+QE);. at pfg?Y16Q+QE);. at p
+qc,$ACbts)62PIaqeSRqCdIr762YOTqeSRqCdIr762PIar+n1dCdIr762PIar+n1bANfs-1](uS
+qeSRrCbts)62Pb!Unsl_V50WQS=H1 at W1'!ASt)=BS=H1@\n+[j6Q+!7,2#=$fg?Y16Q+QE);. at p
+fh3I at 6Q+QE);. at pfg?YS<@@Z[62YOTqeSRqCdIr762>(TqeSRrCbts)62PIaqeSRoANfs-1](uS
+qeSRqCdIr762YOTqeSRrAMO*o1&?9"s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,lLhurg-i7.$qckcN>V>nY0)Jm+qckcN>V>nY0)Jm+
+qckcN>V>nY0)Jm+qckcN>V>nY0)Jm+qckcN>V>nY0)Jm+fh3I073]iB,0<7tfh3I073]iB,0<7t
+a[IDq73]iB,0<7ta[IE.UQap.n+?>Lo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2
+kj7crjQG[\gtCK>daZjreCN9rbPQ*AqckcN>V>nY0)Jm+qckcN>V>qc1&G3.qckcN>V>nY0)T98
+qckcN>V>qc1&G3.r+.V[>V>nY0)Jm+qckcOAMO'e0)Jm+qc,#s6Q+QE)9G;kfg?Y!73^DP);. at p
+a[IE,6Q+!7,3H"ss8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mke+.s>V>nY0)Jm+qckcOAMO'e0)T98
+r+.V[>V>qc1&PT;r+.V\AMO*o1&PT;r+.V[>V>qc1&PT;qckcOAMO'^-eUj)fg?Y!73^DP);. at p
+fg?Y!73^DP)<e`;s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7d%m-ilnkLnYIg"bH;gtpK/f$`(!fZ_O^bg#g:D#@j!r+.V\AMO*o1&PT;q.2_eAMO!l4o&YP
+qeSRoANfp,62PIaqeSRoANfp,62PIaqeSRqCdIr762PIaqckbo9.JUf+NI,)fh3I.9.K4S?N:'*
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIg"bH4eCN'tf#u:^daZjkbg">Tc2!TH
+r+.V\AMO*o1&5BDr+.V[CdIl.4o&YPqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762>(T
+r+n1dCdIl.4o9%]qeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIaqfGU1CdIr762PIa
+qeSRqCdIr762>(Tq.2_N9c_n[+SaI.s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+g"bH;gtp5uc-+>UbKS5L`Pp$Ec-+>U`5T^=bg#:PS,7;&r,XmqFAD^T:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.r,XmqFAD^L62YdaqfGU/P]d$+s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726g"bH4eCN'tf#u:^`5T^6`Pod7`Q3.-qckcNCdIr762PIa
+r,XmqCdIr?:Af/nqfGU2F#j,>:Af/nqfGU2F#j,>:Af/nqfGU2F#j,>:Af/nqfGU1NE-#Ys8W-!
+s8W-!s8W-!s8W-!o_/+Em-ilnkL.l2bKS5L`Pod7`Oidr]=bheXfC&I+N[%rj]!?!CdIr762PIa
+r,XmqCdIu?3W!VYqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdImPdJs7H
+s8W-!s8W-!s7H$\m.9o6m-ilnkLnYIdaZjreCMRW`Pfa7`5T^-]Y1qi]t:qj]=bha['[HX]sP/R
+]=bhuD,eVG,0<7ta%Io(73_VF62Ydar,XmrF#j/>3W*qYr,XmqCdIu?3W*qYqeSRqCdIr762PIa
+r+n1dCdIr762PIaqeSRqCdIr762[Nqs8W,kpA+(Hp#+oog"bH-bg")F`Oidr['[3I['[3I['tEt
+fg?Y16Q+QE);. at pfg?Y16Q,c$-i at d:qeSRrCbu!#1&GcQqeSRqCdIr762YOTqeSRqCdIr762PIa
+qeSRqCdIu?3W!VYqeSRp`2s"=s8W-!s8W-!s8V`bq<726i8j(LeCN'tf#5PH`5T^-]Y1AIXiPTj
+a%Io86Q+!7,0<7tfh3I073^DX+N[%rj]!?"Cbts)62PIaqeSRqCdIr762PIar,XmqCdIu?3W!VY
+qeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIar+n1dCdIu81\kTFpk*%sUn+<XUnji_
+Unsl_V50o`Ur[Xaa[IDq73]iB,0<7ta[IDq73]iB,0<7ta[IDq73^hf*W'Y=qeSRqCdIr762PIa
+qeSRqCdIr762PIaqeSRqCdIr762PIar+n1bANfp,62PIar+.VYANfp,62>(TqeSR]MfGf!Xe_eh
+UnslWSt)=BS=H1 at S=Z7 at St)^3I*"f$fg?Y!73]iB,0<7ta[IDq73]iB,0<7ta[IE,6Q+!7,2#=$
+qeSRqCdIr762PIaqeSRqCdIr762PIaq.2_dCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIa
+qeSRrF#j:#s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VoUiVQk4k?KM6<@?s7.f33nk?KM6<@?s7.d(%dk?KM">UnoA.cjVOl"!'B>UnoA.d(%d
+k?KM$A3f<_.d:J/k?KLi<%Z3\,0*>+a[IDo9.ItT.`k+'a%Io&9.J%P,0*>+a%Io(73]fi<9W];
+o_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,i8j(`gt^T<hU9p)
+daZk#XIoAp0)9'Al"!'V>V>h`4o8J:qckcN>V>h`4o8J:q.2_d>V>h`4o8J:r+.V[>V>h`4o8J:
+r+.V\AMO'e0)Jm+r+.V[>V>2E.`k+'a[IDq73]iB,2#U3a[IDq73]iB,0<7tfg?Y at Z`*p(s8W-!
+s8W-!s8W-!s8W-!o_/+Em-jb7FnoT3q.2_bANfj#4o&YPr+.VYANfj#4o&YPq.2_bANfj#4o&YP
+q.2_bANfj#4o&YPq.2_bANfs&1&5BDj]!>D73]iB,2#U3a[IDq73]iB,0<7tg20[ds8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d%m-j)lgtCK>
+daZjreCMgec-k+mf>PB"CdIl.4o&YPq.2_dCdIl.4o9%]qeSRqCdIr762PIaqeSRqCdIr762PIa
+qeSRqCdIr762PIaqeSRqCdIr76.nmRa%Io&9.ItT.`k+'a]U_*s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7d#gt^T<hV$]@daZjreCMgec-+>UdaZk"`4bi"D#8$7qeSRqCdIr762PIa
+qeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr762PIa
+qeSRrF#j,>:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.r,XmqFAD^L62PIaqeSRqCdI/^+3?qq
+kbX@?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjreCMgec-+>U
+`5T^=bg")F`RrDX`5T^jK4=_":A]-.qfGU1FAD[[=Sm28qKuEAHs$5m=SdDIqKuEAHs$5m=Sm28
+qKuEBFAD^T:A]-.qfGU1FAD^T:A\ino_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o.jQG4OhU9p)bKS5L`Pod7`Pfa7a0i2*<%[u`62PIar,XmqCdIr?:Af/nqfGU1CdIr?:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:AT??qfGU0Hs$8f:AN\ms8W-!s8W-!s8W-!s8W,kpA+(Hp#+oo
+g"bH4eCMgec, at T?`k8n$`PoI%]uQP#a%Io&9.KgD0)K`cqfGU1FAD^T:A]-.qfGU2F#j,>:Af/n
+r,XmrF#j/>3W!nnr,XmrF#j/>3W*qYqeSRrF#j/>3Ven^s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+kj7crjQG4OhU9p)daZjd`Pod7`Oidr]=bhh]Y1\Z[(Eua['[3P]Y1\Z[(2Wia[IE,9-D>F,2#U3
+k?KM6CdIr?:A]-.qfGU1CdIr?:Af/nqfGU1CdIr?:Af/nr,XmrF#j,662PIaqeSRqCdIr762Yda
+qeSRpHs$FKs6T at Mkj7ckgtpK/f#u:^`5T^-]Y1qi]sP/R\?2dQ=Za_o,0<7tfg?Y!73]iB,0<7t
+q.2_dCdIr762PIaqfGU2F#j/>3W*qYqeSRqFADaT3W!nnr,XmrF#j,>:Af/nqfGU2F#j#J at fQK.
+s8W-!s8W-!s7H$\m.9o6m-ilnkLnYIdaZjd`Pod7`ODY9a]U^G9.ItT.`Y13a%Io&9.J%P,0*>+
+a%IoXANfp4:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:Af/nqfGU2F#j,>:Af/n
+r,XmqCdIu?3W!VYqeSRqCdIr762PIaqfGTsV2r7$]rS6:Unsl_V50o`Unji_UnslrFCN?\,0<7t
+a[IDq73]iB,0<7ta[IDq73]iB,0<7tj]!?"F#j,662YdaqeSRrF#j,662PIaqeSRqCdIr762PIa
+qeSRqCdIr762PIaqeSRqCdIr762PIaqeSRqCdIr76-,jm\?2d,V50o`Un"$HW1'!ASt)=BS=H1@
+W1'!n73]iB,0<7ta[IDq73]iB,0<7ta[IDq73]iB,0<7ta[IDq73_V60)9'AqeSRqCdIr762PIa
+qeSRqCdIr762YdaqeSRqFAD^L62PIaqfGU2F#j,662PIaqeSRqCdIr762PIao_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!pUR0a>UnoA.d(%d
+k?KM">UnoA.d(%dk?KM6>V>2E.d:J/k?KM$A3f<_.d(%dl"!'B>UnuK5j)B%k?KM$A3f<_.`Y13
+\OIsg73]cF.`Y13\OIsg73]93-cne$a%Inm7OQ;H,0*>+fY"ZbpA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n*'-,g"bH;gtpK/f$`(!l[i[1>UoP\4m?KB
+k?KM$A3fBi5l4e=l"!'DA3g#s0'Qn3qckc<A3fs%4m?KBq.2_bANfoq0'Qn3q.2_bANfoq0)9'A
+j]!>D73]iB,0<7ta[IDo9.J%P,0<7ta[IDq73]cF.d!k&s8W-!s8W-!s8W-!s8W-!s8V`bq<$Jf
+q.2_bANfj#4o&YPq.2_bANfj#4o9%]qeSRoANfp,62PIaqeSRqCdIr762>(TqeSRoANfj#4o&YP
+q.2_d>V=,e,0<7ta[IDq73]iB,0<7ta[IDq73_THXT/>#s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ILkNM:$i8j(Sgtp`>hV$]@daZjkbg">Tc/kIN
+q.2_dCdIr762PIaq.2_bANfj#4o&YPqeSRoANfp,62PIaqeSRqFAD^L62PIaqeSRqCdIr762PIa
+qeSR]>Umia,0*>+a%Io&9.J%P,58XFs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726
+k1nbFgtpK/f$`(!daZjkbg">Tc-+>Uf>PB!Hs$8^62PIaqeSRqCdIr762PIaqeSRqCdIr762Pb!
+qeSRqFADaT3W!nnqfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:?c:Sa%Io7KPphis8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7ckgtp`>hUp&qbKS5Sbg")F`QQKM`5T^=bg")F`TX.Z
+qfGU1FAD[[=Sm28qfGU0Hs$5m=Sm28qKuEBFAD^T:AT??qfGU0Hs$8f:AT??qKuEAHs$5m=SdDI
+qfGU0Hs$3 at MuWhWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39idaZjreCMgec, at T?
+`5T^6`PooOEr0)oqfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU0Hs$8f:AT??
+qfGU0Hs$5m=Sm28on[Gas8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQFt at f#u:^bKS5L`PoI%]t:qj
+`5T^;HtUJm.`Y13qeSRpHs$8f:AT??qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qeSRqFAD^T:A]-.
+qeSRqFAD^T:A]-.qfGU/gsQ0%s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2i8j(SgtpK/f$`(!
+`5T^-]Y28&`O*"Z]=bha['[HX]sP/R]=bhh]Y2?q9$'LGa%Io(73]cF.f4$JqfGU1FADaT3W!nn
+qeSRqFAD^L62Pb!r,XmqFAD^T:A]-.r,XmqFADaT3W*qYqeSRqFAD^T:Af/nq;gMum-ilnkLnYI
+bKS5L`PoI%]sP/R['[3I['[?,MoeC3a[IDq73]iB,0<7ta[IE,9-F+J62YdaqfGU1FADaT3W!nn
+qeSRqFAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qS]K8s8W-!s8W-!s8W,kpA+(Hp#+oo
+g"bH4eCMgec, at T?[sVr29.ItT.`Y13a%Io&9.ItT.`Y13a%Io8>s%t*3Vn,*qfGU0Hs$8n3;S#)
+qfGU1HoV"F:AT??qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU2F#j,>:Af/n
+qfGU/P]bTr]u7n/['[3I['ZX*Unji_Unsl_V50o`Upb)Ba[IDq73]iB,0<7ta[IDq73]iB,0<7t
+a[IDq73^hm+8^.TqeSRqCdIr?:A]-.r,XmqFADaT3W!nnr,XmqFAD^L62YdaqeSRqCdIr762PIa
+qeSRrF#j,662Pb!pk*%f]Y1\Z[&^:1Unsl_V50WQS=H1 at S=Z7 at St)=BS at Vupa[IDq73]iB,0<7t
+a[IDq73]iB,0<7ta[IDq73]iB,0<7tj]!?!CdIr762PIaqeSRrF#j,662Pb!qeSRqFAD^L62Pb!
+qfGU1FAD^L62Pb!qfGU1FAD^T:A]-.qeSRqCdImXiW&rXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+!$?KYQCfj-]&>UnoA.d(%dfi0QfA3f<_.bS)h
+fj-]&>UnoA.d(%dfj-](A3fBi5hTF)k?KM$A3egR46^9 at a%Inm7OQ;H,.U/j\OIsW7OQ;H,.U/j
+a%Inm7OP`9-b2\o\OIsfD,g0$q>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7d%m-ilnkMYFag"bH4eCN9ZXQa7\k?KM6>V>8O5l4e=l"!'DA3fBi5l4e=
+l"!'TANf9g5j;fEqckc<A3g#s0'Qn3q.2_RA3g#s0'Qn3q.2_RA3f<_.`Y13a%Io&9.J%P,.U/j
+a[IDo9.ItT.`Y13a[IE;Z`*p(s8W-!s8W-!s8W-!s7H$\kj7d%Z`*\24o&YPq.2_bANfj#4o9%]
+q.2_bANfp,62>(TqeSRoANfp,62>(TqeSRoANfp,62>(Tq.2_bANfj#4kWINa[IDo9.J%P,0*>+
+a%Io&9.J%P,04V#s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n)39ik1nb?eCN'tf$`(!fZ_Oj`4c%a62>(TqeSRoANfp,62PIa
+qeSRqCdIr762PIaqeSRqCdIr762PIaqfGU1CdIr?:A\inqeSRqFADXC4m?KBa%Io&9.J%P,0*>+
+a%Io6Ht*-Us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n)iE\g"bH4eCN'tf#u:^
+daZjkbg"eabLj2'qfGU1FAD^T:A\inqfGU1CdIr762Pb!qeSRqFAD^T:A\inqfGU1CdIr?:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU0Hs$8f:A]-.
+qfGU1FAD^T:A]-.qeSR=9.Itl9)nqks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+(Hp#b&bg"bH4eCMgec-+>UbKS5Sbg">Tc, at T?bKS5_`4bqu at etISqfGU0Hs$8f:AT??
+qfGU0Hs$8f:AT??qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=Sm28qfGU5s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7ckgtpK/f%A3ibKS5L`Pod7`Q#R%a]U_&FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:AT??qfGU0Hs$8f:A]-.qfGU0Hs$8f:AT??qfGU0Hs$6pYlFb'
+s8W-!s8W-!s8W-!s8W,coC_>6n(HLQdaZjkbg")F`Pfa7`5T^-]Y2=t]!cEX[o5?.9.Kg\:AT??
+qKuEBFAD[[=SdDIqfGU0Hs$8f:A]-.qfGU1FAD^T:A]-.qfGU1FAD[[=Sm28qfGU1FADU`@fQK.
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)39ig"bH4eCMgec, at T?]=bhs]XkJW[(Eua
+['[3P]Y1\Z['[3I\V5:<9JFL[.`Y13a[IE<A3g$6:A]-.qfGU1FAD^T:Af/nqfGU1CdIr?:A\in
+qfGU1CdIr?:A\inqfGU1FAD^T:A]-.qeSRqFAD\NXQ]$>i8j(LeCMgec, at T?]=bha['[3I['[3I
+[rc)i7OQ;H,.U/ja[IDq73]iB,3N2\qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.
+qeSRqFAD^T:A]-.qfGU0Hs$FKs8W-!s8W-!s8V`bq<[_Gi8j(ZjQG4OhTO-faK25LAP]d63k.j;
+[o5>t9JEqS3k&$Ka%Ink;`a/R5l,k1qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEBFAD[[=SdDI
+qKuEAHs$5m=SdDIqKuEAHs$8f:AT??qfGU1FAD^T:A]-.qfGU+Lhu:fYh at ggbKS5L`PoI%]rS6:
+Unsl_V50o`Unji_UnslrFCMdM-b2\oa[IDa7OP`9-cne$\OIsg73]93-cne$fi0R#FAD^T:A]-.
+qfGU1CdIr?:A]-.qeSRqFAD^T:A\inqfGU1FAD^L62Pb!qfGU1FAD^T:A]-.qfGU1FAD(bICm/*
+['[3 at XKA:pUnji_S=Z7 at St)aJQ(4G9S=Z7MFCi!P-b2\o\OIsW7OP`9-b2\o\OIsg73]93-b2\o
+a[IDa7OQkg/c0?MqeSRqCdIr762Pb!qeSRqFAD^L62Pb!qfGU1FAD^L62Pb!qfGU1FAD^T:A\in
+qfGU1CdIr?:A]-.q:sBts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7ta7fk!\,>s$_F45!n$fj-\m>s%4S.bS)hfi0Qd>UnE445!Rbfj-\m>s%4S.bS)h
+fj-](A3egR45!n$fj-\m>s#Sd-b2\o\OIsW7OP`9-b2\o\OIsW7OP`9-b2\o\OIsW7OP`9-ePf-
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+kj7crjQG4OhV$]@daZk3L2?*b5j;fEl"!'DA3f<_.d:J/l"!'DA3f<_.d:J/l"!'DA3fBi5j;fE
+l"!'DA3fBi5j;fEl"!'DA3fBi5j;fEfi0QD9.IJA-cne$\OIse9.IJA-b2\o\OIsW7OP`9-ePf-
+s8W-!s8W-!s8W-!s8W,kpA*q=n)oUKq.2_RA3fBi5j3#Xl"!'CCeX)(5j3#Xk\NrVCeX)(5j3#X
+k\NrVCeX&/9^$:dl"!'VCdI;r5l5@`l"!&h9JFRW,.L<#\OIse9.IJA-b2\oa%Io7XIoOms8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o6m-iW_hV$]@g"bH4eCMgec-+>Ul'-VnCdIl.4o9%]qeSRoANfp,62>(TqeSRqCdI9$9`&Wl
+qeSR^CeX_B62PIak\NriCdIr?:A\ink\NriCdH*7._&/+a%Inl9JEtM0ZdHZs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7d%m-iW_hV$]@daZjreCMgec-+>UbKS5Sbg#@JO8F#o
+qfGU1FAD^T:A]-.qfGU1FAD^T:A\inqfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qKuEBFAD[[=SdDI
+qKuEAHs$8f:AT??qfGU0Hs$5m=Sm28qKuEAHs$5m=Sm28qKuEBFAD[[=Sm28qKuEBFAB;D3ltMd
+q;gN7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hU9p)
+daZjkbg">Tc, at T?`5T^6`Pp$Ec, at T?kbX@;FAD[[=SdDIqKuEBFAD[[=SdDIqKuEAHs$5m=SdDI
+qKuEAHs$5m=SdDIpk*&PHs$5m=SdDIqKuEAHs$5m=SKA's8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkLnYIdaZjkbg")F`Pfa7`5T^:Mgabn.f4<_qKuEBFAD[[=Sm28qKuEAHs$5m=SdDI
+qKuEBFAD[[=Sm28qKuEAHs$8n3;[emqKuEAHs$8f:ABHNs8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+i8j(SgtpK/f#5PH`5T^-]Y1qi]u7n/]=bht>YV\+3ltMdpk*&PHs$5m=SdDIqKuEAHs$5m=SdDI
+qfGU0Hs$5m=SdDIqKuEBFAD[[=Sm28qKuEAHs$5m=SdDIr3_Rbs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o.jQG4OhU9p)daZjd`Pod7`Oidr]=bha['[HX]sP/R]=bha['[oMS[h3;
+a%Inl9JFL[.`Y13qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.q5on>jQG4OhU9p)`5T^-]Y1qi]sP/R['[3 at XKB'>7EItB\4eTe7OP]>0Y'Y#
+\4eURCdIr?:A]-.qfGU1FAD^T:AT??qKuEAHs$8f:A]-.qKuEBFAD^T:A]-.qfGU1FAD^T:AM#V
+s8W-!s8W-!s6T at Mm.9o.jQGI^kL.l2bKS5?NJ4i?3k.j;\4eTs9.IGF0Xse1a%Inl9JFRk48X+p
+qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuEAHs$5m=SdDIqKuEAHs$3HPi1Wck1nbFgtp5uc, at T?['[3 at XKA:pUnji_Unsl_V50o`UpkGT
+\OIsW7OP`9-b2\o\OIsW7OP`9-b2\o\OIsW7OQkg/c0WbqfGU1FAD^T:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1CdIr?:A\inqfGU1FAD^T:A]-.fW:^``PoI%]sP/RX/rG!V50WQS=H1@
+S=Z7 at St)=BS>V$f\OIsW7OP`9-b2\o\OIsb2E86:-b2\o\OIsW7OP`9-b2\o\OItDCdIr?:A]-.
+qfGU1CdIr?:A\inqfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qeSRqFADV\aoDD@
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,_Z`)A[7+kj-
+e6YPm?:<IP46^9 at bZ%]t>s$_F45!n$fj-\m>s$_F45!n$fj-\m>s$_F45!n$fj-\m>s$_F43'uD
+\OIsW7OP`9-b2\o\OIsD6n>f;-`09^\OIsD6n>f;-`09^\m7bgm-juSs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ILkMYFai8j(SgtpK/f%@'r
+l"!'4AOkuq5h'+.l"!'DA3fBi5j;fEk\NrWA3fBi5j;fEl"!'DA3fBi5j;fEl"!'DA3fBi5j;fE
+l"!'DA3egR41Is<\OIsV9JEtM0Y'Y#\4eTe7OP]>0Xse1\4eU/XIo.Yq>^Kps8W-!s8V`bq<[_G
+k1nbUFB7UA9^-(Qk\NrWA3g$.60VoFk\NrVCeX)(5j3#Xk\NrVCeX&/9^$:dl"!'CCeX&/9^$:d
+k\NrWA3egR41Is<\4eTd9JF"H-b)i(\4eTd9JEqS3qr"(s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vi[kNM:$kj7d#gt^T<hU9p)
+daZk#bfeYGXQXIoqeSRqCdIr760N,Yq.2_dFAD^L60N,YqeSR^CeX_J:A\ink\NriFAD%99`&p,
+qeSR^CeX_J:A]-.e6YPQ9JEtM0ZdHZ\4eTd9JH7b_#OH7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2k1nbFgtp`>hU9p)daZjkbg"Scf%A3ibKS5qP^WFN:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qKuEAHs$8f:AT??qfGU0Hs$8f:AT??qKuEBFAD[[=SdDI
+qfGU0Hs$5m=Sm28qKuEBFAD[[=SdDIqKuEAHs$8f:<-U6\4eU?Z`*p(s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726k1nbFgtpK/f%A3i`5T^=bg">Tc-+>U
+`5T^=bg"eQ[ebARqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuE?K4=\)=SdDIqKuE1HsZjQs8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2g"bH4eCMgec-+>U
+`5T^6`Pod7`Q)I\qfGU0Hs$8f:AT??qKuEAHs$5m=Sm28qKuEAHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuEAHs$5m=SdDIqKuE?bJ=/Xs8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkL.l2daZjd`Pod7`Q#R%
+`5T^-]Y2 at nZ+!Xm[o5?;?:=R@@etISqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEBFAD[[=SdDI
+qKuEAHs$5m=Sm28qKuEAHs$4*iW&rXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+i8j(SgtpK/f#u:^`5T^-]Y1qi]t:qj['[3P]Y1\Z[(Eua]=bht>YV_%0ZQg9\4eTs9.Kg\:AT??
+qfGU0Hs$5m=Sm28qKuEAHs$8f:AT??qKuEAHs$5m=SdDIqKuEAHs$8f:AT??qKuEBFADY.Mr<[Z
+g"bH-bg")F`Oidr['[3I['[3I[(2Wi\4eTd9JEtM0Xse1\OIsV9JFL[.f4<_qKuEBFAD[[=SdDI
+qKuEBFAD[[=Sm28qKuEAHs$8f:AT??qKuEAHs$8f:AT??qfGU/gsQ0%s7H$\m.9o.jQGI^kLnYI
+daZjg[BZZA<4GUU\4eTd9JEtM0Xse1\4eTd9JEtM0\U"pqKuEAHs$5m=SdDIqKuEAHs$/r at etIS
+pk*&PHs$/r at etISpk*&PHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$3/Fnsh?
+o_/+Em-ilnkL.l2bKS5L`PoI%]rS6:Unsl_V50o`Unji_UnsldFChsU0Xse1\4eTd9JF"H-b)i(
+\OIsW7OP]>0Y'Y#e6YQ?FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.qfGU1FAD^T:A]-.
+qfGU1FAD^T:A]-.qfGU1FACH+]u7n/]=bha['Zm8Xe_ehUnslWSt)=BS=H1 at S=Z7LN/"2t/#G]b
+`&9TP6n>f;-`09^VF2rQ2E7R%/%J+sVF2rF7OP`9-g>/,k\NriCdI9$9`&p,k\NriFAD%99`&p,
+k\NriFAD%A<p4?nqfGTsFB7UA9^$:dqfGTsFB7UA9`&p,q:sBts8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s43Bbe6YPm?:<:L7+>O2e6YPm?:<:L7+kj-
+e6YPr>s$_F44IS)fj-\`<*7gZ44IS)bZ%]t<%ZU+7*JV4fj-\M7OP'$/#G]bVF2r36n>-&/%J+s
+VF2r36n>f;-`09^VF2r36n?KDAG#Tks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o:oC_>6n(HLQg"bH:bfeIU;qY_Pl"!'4AOkEb8(hHD
+fk!\,AOkEb8(qfVfk!\;CeWMn8(qfVk\NrGAOks#9\EuIk\NrGAOkuq5hT^=fj-\L9JEtM0Xse1
+\4eTd9JEtM0Xse1\4eTd9JEtM0\EJ!s8W,kpA+ at Sq=OCVo_/+IoC_4`_WYf0k\NrVCeX&/9\O>[
+k\NrHD,BG49^-(Qk\NrVCeX&/9^$:dk\NrVCeX&/9^$:dk\NrHD,BG49\O>[\4eTd9JEtM0Xse1
+W(f.Z9JEqS3k.j;aa at b$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQg"bH4eCN'tf#u:^bKS5rHsZ#Q9^$:d
+k\NrVCeX&/9^$:dk\NriFAD^T:?ZLfqfGTsFB7UA9`&p,k\NriFAD%A<r6u6k]BkhFB7(+8%2DX
+[o5>t9JEqS3k&$KgS9u4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n)iE\
+g"bH4eCN'tf$`(!bKS5Sbg">Tc.L7`kDO?VHs$5m=SdDIqKuEAHs$5m=SdDIqKuEBFAD[[=Sm28
+qKuEAHs$8f:AT??qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuE/FB86c=R(9?fk![_;``!XIK0?Is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n(HLQdaZjreCMgec-+>U`5T^JbfdrD`QQKM`5T^WS;6rg=SdDI
+qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuE?K4=\)=SdDIpk*&PHs$5m=SdDIqKuE?K4=\)=SdDI
+prgJQs8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)fZ_OW`Pod7`Pfa7a-hq->YY'B=SdDI
+qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuE?K4=\)=SdDIpk*&PHs$/r at etISpk*&PHs$/r at fQK.
+s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2g"bH;gtp5uc, at T?`5T^-]Y1qi]t:qj\?2d?;`_Bd3ne(%
+pk*&NK4=V. at ebRbqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$/r at etIS
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)39idaZjkbg")F`Oidr
+]=bha['[HX]sP/R]=bha['[3I['t-d\4eTd9JEtM0XjtAk\NrhHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=SdDIq36$TgtpK/f#u:^`5T^-]Y1qi]sP/R
+['[3=N/"i90W7]'\4eTd9JEtM0Xse1a]U_%Hs$5m=SdDIqKuEAHs$5m=SdDIqKuEAHs$5m=Sm28
+qKuEBFAD[[=Sm28qKuEAHs$&tD"RGso_/+Em-ilnkMYFadaZjkbg!VVKr7m7\4eTT9f9FS0W7]'
+\4eTd9JEtM0XjtAk]Bl%Hs$5m=SdDIqKuEAHs$5m=SRMXqKuE?K4=V. at d8>Ipk*&NK4=\)=SRMX
+pk*&NK4=\)=SRMXqKuE?K4=\)=SRMXqKuEAHs$&tD#2)Os8W-!s8V`bq<726i8j(LeCMgec, at T?
+['[3I['ZX*Unji_Unsl_V50o`UoA3<W(f.Z9JED>27Z1(W(f.Z9JEtM0W7]'\4eTd9JFRk48O>,
+qKuEAHs$5m=SdDIqKuEAHs$5m=SdDIqKuEBFAD%A<r.2Gk]Bl%Hs#TS<p4X+k]BkhFB7UI<p59S
+daZjkbg")F`O*"ZX/rG!V50WQS=H1 at S=Z7 at St)=BS=,S)W(f.H6n>-&/#G]bVF2r36n>-&/#G]b
+VF2r36n>f;-`09^VF2rf>s%q*:?ZLfk\NrVCeX_J:?ZLfk\NrVCeX&7<p4?nk]BkhFB7UI<p4X+
+k]BkhFB7UI<p4X+k]BkhFB84mdJs7Hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+0E`:"`9ugL5a';?g?:;h=:!$O"a]U^T?:;n<43(T#a]U^L<*7XV7*/Rn
+e6YPb=Zb;B43:Vefj-\[>YW73.],TaVF2r36n>-&/#G]bVF2r36n>-&/#G]bVF2r36n>-&/#G]b
+daZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVkj7crjQG4OhU9p)ert[<AOkEb8(hHDfk!\,AOkHk:tfb_g20[?D,Ar':tfb_
+k\NrGAOkHk:tfb_g20[?D,BG49\O>[g20[MCeVlZ9"7PK\4eTT9f9CY3iGb1[o5>s;`^jO27HLF
+Vc5n5XInkNp%7tRo_/+QpA+(Hp#tc2kbX?oD,Ar':tfb_g20[?D,Ar':tfb_g20[?D,Ar':tfb_
+g20[>AOkHk:tfb_g20[?D,Ar';!;^hg20[>AOj7(0W.l7W(f.J9f9CY3iGb1W(f.J9f:S9[f?C-
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7d%m-iW_hV$]@daZjreCMgec.f"Wk]BkhFB7UI<p4X+k]BkhFB7UI<p4?n
+k]BkhFB7UA9^$S!k]BkhFB7UI<p4X+k]BkhFB7UI<p4X+k\Nqj<'Rij3k&$KVc5mi;`_@'=o\O%
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hWEVKdaZjreCN'tf#u:^
+bKS5Sbg"eQ[d&6HqKuE/FB86c=Qjj-qKuE/FB89\:AT??qKuEAHs$5m=SdDIqKuEAHs$5m=SdDI
+qKuE1HsZYs=SdDIl?lq7Hs$5m=R(9?qKuE1HsZ)c?M]%Ol?lq'HsZYs=R1QLpk*&2E`BMH3k'3?
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7crjQG4OhTO-ffZ_O^bg">Tc, at T?bKS5L`Pp$Ec,RE-pk*&NK4=\)=SRMXpk*&NK4=\)=SRMX
+pk*&NK4=V. at ebRbpk*&NK4=\)=SRMXpk*&NK4=V. at ebRbpk*&PHs#TeD#aP8s8W-!s8W-!s8W-!
+s8W,coC_>6n(HLQdaZjreCMRW`Pfa7`5T^6`Po<. at d%o7pk*&NK4=V. at ebRbpk*&NK4=V. at ebRb
+pk*&NK4=V. at ebRbpk*&NK4=V. at ebRbpk*&NK4=V. at ebRbqS]K8s8W-!s8W-!s8W-!s8W-!s8W-!
+kj7d%m-iW_hU9p)bKS5N]Xl&#`Oidr`5T^-]Y2 at nZ+!Xm[o5?AD,C"[@ebRbpk*&PHs$/r at ebRb
+pk*&NK4=V. at etISpk*&NK4=\)=SRMXpk*&NK4=V. at ebRbpk*&KLi!+ks8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG4OhU9p)`5T^6`Poj0]">Vg['[3P]Y1\Z[(Eua
+['[3LHtp/b0XjtA[o5>t9JG.28, at U8qKuEAHs$5m=SdDIqKuEAHs$5m=SRMXqKuE?K4=V. at ebRb
+pk*&NK4=V. at ebRbpk*&PHs$&tCt[V#daZjd`PoI%]sP/R['[3I['[3I['t-dW(f.Z9JED>27Q=6
+W(f.J9f:U88,.^GqKuEAHs$5m=SdDIl?lq7Hs$5m=SdDIpk*&PHs$5m=SdDIqKuEAHs$5m=SdDI
+q5'#9oC_>6n)39ig"bH4eCM[JZ*nIOW(f.J9f9FS0W%5gW(f.Z9JED>27Q=6a(%a<Hs#Z]?M]%O
+l?lq'HsZYs=R(9?l?lq'HsZ)c?KuoEl?lq7Hs#]dAEnPKl[i[4HsZT#@d8>Il?lq5K4=+n?MK.^
+l[i[5Jn4Y/@eljYo_/+\s8W-!s8W-!o_/+Em-ilnkLnYIdaZj[]Y1qi]rS6:Unsl_V50o`Unji_
+UnsldFChsU0W7]'W(f.J9f9FS0W7]'W(f.Z9JED>25j5,a';@&FB7UI<pG'=k]BkhFB86c=Qjj-
+k]BkhFB7UI<pG'=qKuE/FB7[S?KuoEk]BkjHsZ#Y<pG'=k]BkVRZQ4XhU9p)`5T^-]Y1\Z[%sOo
+UnslWSt)aJQ(4G9S=Z7 at St)`R25WblVF2r36n>-&/#G]bVF2r36n>-&/#G]bVF2r36n>-&/&tmh
+k\NrVCeX&7<p4?nk\NrVFB7UA9^$S!k\NrVFB7UA9^$S!k\NrVFB7UI<p4X+k]BkhFB7UA9^$S!
+q:sBts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V?6f?%/W
+a]U^I=Za`.43(T#a]U^G>YW7D:!$O"a';?\=ZaZ/:!$O"a]U^I=Za`.43:Vea]U^G>YW=C43:Ve
+\4eTR6n>-&/#G]bVF2r36n>-&/#G]bVF2r36n>-&/#G]bVF2rGAP_slq>^Kps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2
+k1nbFgtp\r[b54^g20[?D,Ar':tfb_g20[?D,Ar':tfb_g20[?D,Ar':t'G`g20[?D,Ar':tfb_
+drJC at D,Ar':t'G`aDFnc;`^gU5IXQPVc5mi;`^gU5GqIF[o5>c<'Rij3nUg at m.9oBpA+(Hp$D;C
+m.9o6m-iVdGhR"2g20[?D,Ar':tfb_g20[?D,Ar':tfb_g20[AE`Cb0:tfb_g20[?D,Ar':tfb_
+g20[?D,Ar':qBq$W(f.J9f9FS0W7]'W(f.J9f8kD25j5,q;gN7s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726
+k1nbFgtpK/f$`(!bKS5`]XHU9<7l=uk]BkXF^4-P<p4X+fQCH_FB71;<9SF)k]BkhFB7UI<p4X+
+k]BkhFB7UI<p4X+k]BkWHt);]<ju!gVc5mY<'Rij3i>qAVc5n\s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7ckgtp`>hU9p)daZjreCN9rbKJ,SbKS5`XIng1AEnPK
+qKuE1HsZYs=R(9?l?lq'HsZ)c?KuoEl?lq'HsZ)c?KuoEl?lq'HsZ)c?KuoEl?lq'HsZ)c?KuoE
+l[i[5Jn42!AGCddl?lq(Jn4Y/@dAVVl[i[4HsZ#Y<k;R*\m7c#jPg.=s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH;gtp5uc-+>U
+bKS5L`Pp$Ec, at T?bKS5L`Ppr/L\QL2k_<pKK4=V. at dAVVon[GMJn4Y/@dAVVpk*&NK4=V. at ebRb
+pk*&NK4=V. at ebRbpk*&PHs#]dAGCddl?lq5bJ=/Xs8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^
+bKS5L`Pod7`Q4jGa(%a:K4=V. at eGOnpk*&NK4=M0D"rWlpk*&NK4=M0D"rWlpk*&NK4=V. at ebRb
+pk*&NK4=V. at ebRbpk*&KLi!+ks8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH4eCMRW`Oidr
+]=bhq`PoI%]u7n/\?2d?;`_Bd3ll/;qKuE?K4=V. at ebRbpk*&PHs$/r at ebRbqKuE?K4=V. at ebRb
+pk*&NK4=V. at ebRbpk*&NK4=V. at eGOns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2g"bH4eCMgec, at T?]=bha['[HX]sP/R]=bha['[HX]r-6sW(f.I<'R<U27HLF
+a(%a:K4=V. at ebRbpk*&NK4=V. at ebRbpk*&NK4=.uAG(appk*&AJn4Y/@dAVVpk*&AJn4Y/@dAVV
+l[iZqeCMgec, at T?]=bha['[3I['[3IX/rG%AQ5U&25j5,W(f.J9f8kD27Q=6k]BkjHsZ)c?MK.^
+l?lq'HsZT#@d8>Il[i[DHs#Z]?M]%OqKuEAHs$5m=SdDIqKuEAHs#UFYi+U*i8j(SgtpK/f!pp%
+Vc5mZ9f8kD25j5,W(f.J9f8kD25j5,[o5?AD,C(V=R(9?qKuE1HsZ)c?MK.^l?lq(Jn4.o?MK.^
+l[i[5Jn42!AF"hXl[i[5Jn42!AEnPKl[i[5Jn42!AF"hXl[i[5Jn42!AG(appsdFcs8W-!s8W-!
+s8W-!s8VHWp#tc2i8j(LeCMgec, at T?['[3I['ZX*Unji_Unsl_V50o`UoAHIW(f.J9f8kD25j5,
+W(f.J9f8kD25j5,W(f.Z9JFRk46h3"pk*&@HsZ)c?KuoEl?lq'HsZYs=R(9?k]BkhFB7UI<pG'=
+k]BkhFB7UI<pG'=k]BkhFB7UI<p6B at g"bH4eCMRW`Oidr['[3 at XKA:pUn"$HS=Z7 at St)=BS=H1@
+VHZKd6n>-&/#G]bVF2r36n>-&/#G]bVF2r36n>-&/#G]bVF2rE9JG[H9\O>[k\NrVFB7+4;!;^h
+k]BkhCeWW)<9SF)gi?BXFB71;<8;Lngi?BJD,B#.<8;Lng20[MFB7YVfDkmNs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!fY"Z(>t)e=:!$O"\m7bH=ZaZ69"J:s
+a]U^I=ZaZ69$(3ta]U^I=ZaZ/:!$O"a';?\=ZaZ/:!$O"a]U^:>t(VY/#G]bVF2r36n>-&/#G]b
+VF2r36n>-&/#G]bVF2r36n>-&/'*p-o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjiHtV,D8(2KW
+a(%`qD,A;j<8)1caDFo1D,A;j<7>kdaDFo1D,A]%;qc(bdrJC at D,A]%;quCmfQCHSE`C+s<2W\[
+VHZKu;`^gU5GqIFVHZKu;`^gU5GhXRVHZL1XJP:Tp$D;Cm.9oBpA*q=n)39ifQCHSE`CM.;quCm
+drJCBE`Ch7<7>kdgi?BCE`:G-;qQ4tdrJC>F^3RA>hF1(g20[=F^3^B<7>kdgi?B*>t(\d25aD<
+Vc5mZ9f8kD25aD<W(f.XCg$f<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n)iE\daZjreCN9rbKJ,S
+fS".pF^3OG at b>g.fQCHOF^3RA>j-91fQCHOF^4-P<nMP"k]BkXF^4-P<nMP"l?lpjF^3OG at d8>I
+f6h&=>t(Yj5GqIFVc5mY<'R9[5PaC!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n)39ik1nbFgtpK/f#u:^daZjkbg">Tc-+>Ujd_+kHsZ)c?KuoEl?lq'HsZ)c?KuoE
+qKuE1HsZ)c?KuoEqKuE1HsZ)c?KuoEl?lq'HsZT#@dAVVpk*&AJn42!AF"hXl?lq(Jn42!AF"hX
+l[i[5Jn42!AF"hXa(%`=>=IbgYlFb's8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j)lgtCK>daZjkbg">Tc-+>U`5T^=bg")F`QQKM
+fX.aDL2?X;@d&P_k_<p;L2?(.D"WU#k_<p;L2?(.D!6Uil[i[5Jn42!AF"hXl[i[5Jn42!AF"hX
+l[i[5Jn42!AD)ods8W-!s8W-!s8W-!o_/+Em-j)lgsX^'fZ_O^bg")F`Pfa7`5T^)Htq;V>jHuP
+on[GWLhuj=@d&P_pk*&KLhuj=@eGOnpk*&KLhua?D"rWlon[GWLhua?D"WU#on[GWLhua?D"kK;
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhTO-f`5T^6`Pod7`Oidr`5T^-]Y2=t\u91>
+[o5?/D,g1aD"rWlon[GZK4=V. at eGOnpk*&NK4=V. at eGOnpk*&KLhuj=@eGOnpk*&KLhua?D"WU#
+on[G[P]d$+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYI
+bKS5L`PoI%]t:qj['[3P]Y1\Z[(Eua['[3LFCM.I5GqIFVc5mY<'SE59'_(>l[i[5Jn42!AF"hX
+l[i[5Jn42!AF"hXpk*&AJn42!AF"hXl[i[5Jn42!AF"hXl[i[4HsZK%CsphabKS5L`PoI%]sP/R
+['[3I['[?FWi&f\W(f.J9f8hJ5H%:6W(f.I<'TYq?L*2Rl[i[5Jn42!AF"hXl[i[5Jn4Y/@dAVV
+pk*&AJn42!AF"hXl[i[4HsZ)c?L*2Rk01s#gtpK/f#P2'WGQ"@9f8kD25j5,W(f.J9f8kD25j5,
+W(f.i at nQ$6?KuoEl?lq'HsZ)c?L*2Rl[i[4HsZ,jAF"hXl[i[5Jn4.o?L*2Rl[i[5Jn4)"D!Q[`
+k_<p>Jn42!AF"hXl[i[5Jn42!AF"hXq5'#Ls8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkL.l2
+bKS5L`PoI%]rS6:Unsl_V50o`Unji_UnsldFChCF25j5,W(f.J9f8kD25j5,W(f.J9f8kD25j5,
+a(%a,HsZ)c?KuoEl?lq'HsZ)c?KcK3k]BkhFB7[S?KcK3k]BkhFB7UI<nMP"k]BkXF^3RA>hF1(
+fQCHO[&hs9hU9p)bKS5L`Po3k[&^:1UnslWSt)=BS=H1 at S=Z7 at St)0N8Z"m+VF2r36n>-&/#G]b
+VF2r36n>-&/#G]bVF2r36n>-&/%8G<g20[MFB71;<8)1ck\NrJE`Cb0:u$(jgi?BLE`Ch7<8)1c
+gi?BLE`Ch7<8;Lngi?BLE`Ch7<8)1cq:sBts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*:.ON1j'\m7b9>t)k<41\]d\m7bH=Za3#7Clbna]U^:>t)eD9$(3t
+\n+[X at nOjG43(i'a(%`^@nOdO9"._[VF2r36n>-&/#G]bVF2r36n=[$4JkLsVF2r36n=[$4JkLs
+R85rt]XIk?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7ckgtp`>hU[mAaDFntD,eu);oifTg20[-D,eSn<7>kd
+g20[*DI1e4;q#bcdrJC9E`:V5>hF1(aE1b at F^3RA>hF1(`GT"[<'R6a7Aj*LVHZKd>=GGh5GhXR
+VHZKe<'R9[5KKq&p[%)0oC_>6n*'-,kj7d&e^rGr>hF1(fQCHOF^3RA>hF1(fQCHOF^3RA>hF1(
+fQCHOF^3RA>hF1(fQCHOF^3RA>hF1(fQCHOF^3C9;l<SZVc5mY<'R9[5GqIFVc5mY<'R9[5KK%A
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7ckgtp`>hU9p)bKS5Sbg"_-OP"\\fQCHOF^43Z?J'C*
+fQCHOF^3RA>j-91fQCHOF^4-P<nMP"fQCHaHsYHJ>h=@4k]BkWHt(`N>fU>HVc5mY<'R9[5GqIF
+Vc5nE]WhG9s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-j)lgtCK>
+g"bH4eCN'tf#u:^fZ_O^bg">Tc0:I at l?lq(Jn4.o?L*2Rl[i[5Jn42!AF"hXl?lq(Jn42!AF"hX
+l[i[5Jn42!AF"hXk_<p=HsZ#kD!6Uik_<p;L2?(.D!6Uik_<p>Jn42!AF"hXl[iZk at V)E at 7EC[G
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gi8j(SgtpK/f%A3ibKS5L`Pp$Ec, at T?`5T^=bg")F`T<VFk_<p;L2?(.D!-^r
+k_<p:MfIp<ET`7"k_<p;L2?%2ETi-non[GJL2?1-AE\bal[i[2L2?1-AF"hXon[GLHsZ'ffDkmN
+s8W,kpA+(Hp#+oog"bH4eCMgec-+>U`5T^6`Pom*Z+=LBk_<pHLhuC/AE\bak_<p:MfIs8D!-^r
+k_<p:MfIs8D!6UikDO?DL2?%2ETi-nk_<p;L2?(.D!-^rkDO?[s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n)39ig"bH:bfdrD`Oidr`k8mp]Y1qi]u7n/]=bhcCg!W>7E8n1on[GWLhua?D"WU#
+k_<pHLhua?D"WU#on[GWLhua?D!6Uion[GJL2?O=D!-^ron[GWLhu74EV5-(s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<i8j(SgtpK/f#5PH]=bhh]Y1\Z[(Eua
+['[3P]Y1\Z[&.%rVc5mY<'R9[5GqIFdrJCNL2?1-AE\baon[GMJn42!AE\bal[i[2L2?(.D!Q[`
+l[i[2L2?1-AE\bal[i[5Jn42!AF"hXk_<osbg")F`Oidr['[3I['[3I[&^:1W1'!L<'R9[5GqIF
+Vc5mY<'R9[5It,hl[i[4HsZ,jAE\bal[i[5Jn4)"D!Q[`k_<p>Jn42!AF"hXl[i[5Jn42!AF"hX
+l[i[5Jn3NXbL4nk\XJb[>=GJb2476&W(f.I<'R<U25j5,W(f.Y;``BJ;sJa:l[i[5Jn4Y/@dAVV
+l[i[5Jn42!AF"hXl[i[2L2?1-AE\bak_<p;L2?(.D!6Uik_<p;L2?(.D!6Uil[i[2L2?1-AE\ba
+kDO?UgsQ0%s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp5uc, at T?['[3 at XKA:pUnji_
+Unsl_V50o`UoAHIR85rD9f8>74K(t3W(f.J9f8kD25j5,W(f.J9f9Ln:[3=6l?lq%FB7UI<pG'=
+k]BkWHt)Ag?IsR6k]BkWHt);]<nMP"fQCH_FB7%:>hF1(fQCHOF^3RA>iio at i8j(LeCMgec, at T?
+['[3I['ZX*Un"$HS=Z7LR['D7S=H1 at Qs!"K:HYLB/#G]bR85rB6n>-&.ssB?VF2r36n>-&/#G]b
+VF2rG>t*Oh<7l=uk]Bk\E`C\6>hj@!gi?BLE`Ch7<8;LnfQCHSE`C\6>gm^lgi?BLE`Ch7<7l=u
+gi?BHF^41]fDkmNs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+aFnTF>t)>17Clbn\m7b9AP^EN41\]d\n+[Z=Za3+:WHs;\n+[K>t)eD9"JS0a(%`QAP^?V9"JS0
+a(%`><'R<U2476&R85r5:HY%@4IJu-VF2r&:HY%@4IJu-VF2r&:HYOS5N(Vcs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA*q=n)39ig"bH*XJNmR?H?t_`GT#$DI1D+?H$egaE1b-DI1D+?H at 4paE1b0FC)q(?H at 4p
+`GT#'FC*%1?H at 4paE1b0FC*%*<2W\[VHZKe<'R6a7Aj*LVHZKe<'QaQ8Z,NPVHZL1XJP.In*'-,
+m.9o6m-j0)n(>:]aE1b0FC*%1?J'C*aE1b?Ht(3FB at q?3f6h&KFC*RH at b>g.f6h&LHtUQKB at hN?
+aa at aQHt(0=?IsR6`GT"[<'R9[5GqIFVc5mY<'R6a7Aj*LVHZLAXIoOms8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n*'-,g"bH4eCN'tf#u:^fW:^tF^3OG at b>g.f6h&[F^3OG at b>g.fQCHOF^3OG at b>g.
+f6h&ZHt(`N>h=@4f6h&[F^3OG at b6!:f6h&HDI05?5GqIFVc5mY<'QdH4P6a-s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d#gt^T<hU9p)daZjreCN'tf#u:^
+bKS5N]Xm9aES,q^k_<p>Jn3MeDX)UUfS"/.Jn4)"CtF&Dk_<p*Ht)DnACuQQl?lq%L2>Ih at d&P_
+fS"/.Jn3MeDWlgkfS"/+L2?(.CtODYk_<p;L2=qQ?D^pq[sVrjs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)iE\
+daZjreCMgec-+>UbKS5Sbg")F`QQKM`5T^9[B\nQETi-nkDO?CMfIs8D!-^rkDO?DL2?%2ET`7"
+k_<p:MfIs8D!6Uik_<p;L2?(.D!6Uik_<p>Jn4)"D!6Uies_^#s8W-!s7H$\kj7crjQFt at f$`(!
+bKS5L`Pod7`Pfa7VhBHHE`;1VD!6UikDO?CMfIp<ETi-nkDO?DL2?%2ET`7"kDO?CMfIp<ET`7"
+kDO?CMfIp<ET`7"kDO?CMfJQpPlLd`s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQFt at f$`(!
+`5T^-]Y28&`Oidr`5T^-]Y28&`M\*&Vc5ml>t*q7ETi-nk_<p:MfJEGD!-^rkDO?CMfIs8D!-^r
+k_<p:MfIp<ET`7"on[GJL2?%2ET`7"kDO?QLhu_Wq>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIdaZjd`Poj0]">Vg]=bha['[HX]sP/R\XJb[>=FrU4Jl=O
+Vc5mY<'Su^@d&P_k_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<p;L2?(.D!6Ui
+k_<p;L2?+=IF?WrbKS5C]Y1\Z['[3I['[3I['ZcrOI00BVc5mJ=\5Mj5GqIFVc5mlAP_NED!6Ui
+k_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<p*Ht);oD!6Uik_<p;L2?(.D!-^r`k8m^D-s2?5FG;0
+Vc5mY<'R9[5FG;0Vc5mY<'Rs*:[3=6k_<p>Jn4)"D!Q[`k_<p>Jn4P1D!6Uik_<p;L2?(.D!6Ui
+k_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<pJ\YfE,s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkL.l2bKS5L`PoI%]sP/RUnsl_V50o`Unji_UnslbHuPKL4K(t3
+R85rD9f8>74IJu-W(f.;:HY%@4IJu-\m7bVHt(]T at dAVVf6h&ZHt(`N>j?]CfQCHOF^3RA>hF1(
+fQCHOF^3RA>hF1(fQCHOF^3RA>hF1(fQCHN`4ajZhV$]@bKS5L`Po3k['[3IUnslWSt)=BS=H1@
+S=Z7 at St)0N8Z"m+MGZ^;6n=-l6Dd.$R85rB6n=[$4JkLsHoaBX:HY%@4M"fefQCH_FB7%:>hF1(
+fQCHOF^3RA>hF1(fQCHOF^3RA>hF1(fQCHOF^3RA>fCSefQCHOF^3"0?J'C*q:sBts8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC]S?C:[\>\m7b9>t)>17Clbn
+\n+[KAP^?V9"JS0\n+[KAP^?V9"JS0aDFnfAP]mK:V(+5a(%`QAP]mK:T%/VR85r5:HYLB/"'0q
+R85r5:HY%@4IJu-R85r5:HY%@4IJu-Qs!#QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7d%m-j)lgt0KX
+`GT#'FC*%1?H at 4paE1b0FC*%1?H at 4paE1b0FC*%1?H at 4paE1b1HtUNB?H at 4paE1b1HtUNB?HIS-
+[VT*6=\4u`8XNXPR85r4=\4u`8XW@:Qs!"J=\4u`8]\!0kj7d%m-j0)n*'-,kj7cj[&h>j?H at 4p
+fQCH at HtUNB?IsR6aE1b?Ht(3FB at hN?aa at aCHtV&Y@`WXtf6h&LHtV&Y@`a"1f6h&LHtTm(=f54`
+VHZKd>=GDn7Aj*LVHZKd>=GGh5M*ies8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG[\gsX^'
+daZjkbg"eIXOhi/f6h&ZHt(`N>h=@4fQCHNHt(]T at b6!:fQCHNHt(]T at b6!:f6h&[F^3OG at b6!:
+f6h&ZHt(]T@`WXtR85rC<'QaQ8Z,NPQs!#$R>q7Hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2g"bH;gtpK/f$`(!bKS5Sbg"eabKJ,SfX.a4KPp".CtODY
+k_<p+KPp".CtODYfS"/.Jn3MeDV0V[fS"/-HsYHYDV0V[fS".oHt);oCtF&DfS".pKPp".CtF&D
+fS"/+L2>LqDV'8FVHZKfAQ8EjkPtS^s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG4OhU9p)daZjd`Pod7`Pfa7
+bKS5L`Pod7`Pfa7l'-VLN-O!.DWcptfo11=MfIp<ET`7"kDO?CMfIF/Git!)fo11>L2>P%Gj'lu
+k_<p;L2?(.D!6Uik_<p;L2>Ih at d2Fpm.9o6m-ilnkLnYIdaZjkbg">Tc, at T?`5T^8]Xk[c:YLJ2
+k_<p;L2?(.D!6UikDO?CMfIp<ET`7"kDO?CMfJ!GIHQN.kDO?CMfIp<ET`7"l'-V\P^V_QETr^9
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH-bg")F`Oidr`5T^-]Y28&`Oidr
+]=bhdNJ3a&8Z#]\k_<p:MfIp<ETi-nkDO?DL2?(.D!-^rk_<p:MfIs8D!6Uik_<p:MfIp<ET`7"
+kDO?CMfIp<ET`7"prgJQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+kj7ckgtpK/f#5PH]=bhh]Y1\Z[(Eua['[3P]Y14rI$e&.VHZKV=\5Mj5GhXRfo11=MfIs8CtODY
+k_<p+KPp".CtODYk_<p+KPoFqDWcptfS"/*MfIC&DWcptfS"/+L2>LqDWlgkes_]Dbg")F`Oidr
+['[3I['[3I['[3IW/QJ/<'QaQ8Z,NPQs!"J=\5Mj5IPB2kDO?5N-OQ at D!-^rfo11>L2>LqDWlgk
+fS".pKPp".CtODYk_<p+KPoFqDV0V[fS".oHt'$c<1-NER85rC<'QdH4IJu-R85rC<'R9[5KIqQ
+k_<p;L2?(.D!6Uik_<p;L2?(.D!6Uik_<p;L2?(.D!-^rkDO?CMfIp<ET`7"kDO?CMfIp<ET`7"
+kDO?4KPot2ES,q^fS"/,P^WAgiUlj>s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+i8j(Sgtp5uc, at T?['[3 at XKA:pUnji_Unsl_V50o`UmH1=R85r5:HY%@4IJu-R85r5:HY%@4IJu-
+Vc5mK:HZ4":[3=6fS".oHt(]T at d8>If6h&[F^3OG at d8>If6h&[F^3OG at d8>If6h&[F^3OG at d8>I
+fQCHNHt(`N>iio at i8j(Sgtp5uc, at T?]=bhXXKAP)XdkuQS=Z7 at St)=BS=H1 at Q=Ep_:HYLB.uI1j
+VF2ql;*q-J/"'0qR85r5:HYLB/#G]bR85rS;``NX at b6!:f6h&mHsYEP at b6!:f6h&ZHt(`N>h=@4
+fQCH at HtV)S>hF1(aE1b at F^3RA>f_"nfQCH?FC+4^fDkmNs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq=OCV[VT*XAP]mK:V(+5\n+[KAP]mK:V(+5\n+[KAP]mK:V(+5
+[VT*XAP]mK:V(+5\n+[KAP]mK:UY(B\n+[*:HY%@4IJu-R85r5:HY%@4IJu-R85r5:HY%@4IJu-
+R85r5:HYP&E:il"s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+ooi8j(LeCM]_?FP#c[VT*UFCM_$@^gGg
+[rc)gFCM_$@^gGg[rc)tH[WAF@`WXt[rc)tH[WtW?FP;saE1atHtp*+=dW>`Qs!"J=\4u`8XNXP
+Qs!"J=\4u`8XNXPQs!#%Un-`9n*'-,kj7d%m-ilnkLcl.aE1b1HtUNB?HIS-aa at aBFC*(:B?>O6
+aE1b1HtV)S>fhA+aa at aCHtUQKB?>O6aE1b1HtUNB?IsR6\n+[)=\5Mj5F>SFVc5mJ=\4u`8XNXP
+Qs!#CbfTnbs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vi[kNM:$g"bH;gtpK/f%A3i`5T^IHt(]T@`a"1
+f6h&ZHt(]T at b6!:f6h&ZHt(]T at b6!:f6h&ZHt(]T at b6!:aa at aRF^3%9B at hN?aa at aBFC(hK7 at 74L
+Vc5mJ=\4u`8][*Ks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+p[%),m-ilnkN:RTg"bH4eCN9rbL4nkbKS5Sbg">Tc.K+ifS".pKPoFqDV0V[fS".pKPoFqDV'8F
+fS".oHt(`]DV0V[fS".oHt(`]DV0V[fS".pKPoFqDV0V[fo11.KPoFqDV0V[fS". at AQ5O27G#Jk
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2g"bH4eCN'tf#u:^fZ_OW`Pp$Ec, at T?bKS5L`PpK:XOr2D
+fo11/N-O!.DV9tnfo11.KPoJ%Gh@[efo11.KPoJ%Gh@[ekDO?4KPoJ%Gh@[efo11.KPoFqDV0V[
+k_<ooR>pFsn*'-,i8j(SgtpK/f#u:^`5T^6`Pod7`OM+i[VT+1L2?%2ES6:qkDO?5N-ONDES,q^
+fo11=MfIF/GhJ%#fo11/N-O$7GhJ%#fo11/N-O$7Gh@[efo11>V2tZVs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQFt at f$`(!`5T^-]Y28&`Oidr`k8mp]Y28&`ODY9Qs!"X>=HY]BBY(d
+fo11=MfIF/Git!)fo11>L2>P%Gh@[efo11=MfIC&DV9tnk_<p,N-ONDETi-nkDO?CMfIjKL]@DS
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIdaZjkbg!c4]t:qj
+]=bha['[HX]sP/RW+Ar*>=Fo^8Z#]\Qs!"iFCNp^Git!)fo11/N-OQ at CtXblkDO?4KPoJ%Gj'lu
+fo11=MfIC&DV9tnkDO?5N-ONDES6:qfo11/N-O!^XNSi4`5T^&['[3I['[3I['[3I['ZcjL6u+8
+Qs!"J=\5Mj5F>SFQs!#%FC+-gES6:qfo11/N-O!.DV9tnfo11/N-O!.DV9tnfS".pKPoFqDV0V[
+fS"/+L2>LqDV0V[Qs!"K:HY"I8XW@:Qs!"Y<'QaQ8\/J/fS".rKOX,&ES,q^kDO?4KPp".D!-^r
+fS"/+L2>P%Git!)fo11=MfIp<ES6:qkDO?5N-ONDES6:qkDO?5N-O$7GhJ%#k_<p,N-P*-VZ6\r
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkL.l2bKS5L`PoI%]sP/R
+Unsl_V50o`Unji_UnslRFDI:?4IB8CR85r5:HY%@4IJu-R85r5:HY%@4IJu-\n+[iKPoFqDV0V[
+fS".oHt(`]DV'8Ff6h&ZHt(]T at dAVVf6h&ZHt(]T at b6!:fS".oHt(]T at b6!:f6h&[bfer*kLnYI
+daZjd`PoI%]sP/RUnsl_V50WQS=H1 at S=Z7LR['7C8XW@:MGZ^;6n=-l6Dd.$R85r&;*q-J/"'0q
+R85r5:HY%@4M"fefQCHNHt(`N>h=@4f6h&ZHt(]T at b6!:f6h&[KPoCh at b>g.aa at aQHt(`N>fhA+
+fQCH at HtV&Y@`WXtq:sBts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-hMs:V(+5\n+[KAP]mK:V(+5\n+[KAP]aN=h80?[VT*XAP]aN=gi-L[VT*TCg"2_=gi-L
+[VT*TCg"2_=d`&JR85r5:HXM36CCV3R85r5:HXM36C:nIMGZ^-=\4KJ6C:nIVgNI`s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkLnYI[sVr"FCM_$@`WXt[rc)gFCM_$@`WXt[rc)gFCM_$@^gGg
+aa at a1FCM_,C:A:o[sVr"FCM_,C<1L'WGQ"0=\5#W4IB8CQs!"J=\4KJ6C:nIMGZ]t;*p.;6Fa.t
+kj7d%m-ilnkNM:$i8j(UUQ`07C<1L'aa at aCHtUQKB?>O6`-ZpSHtUQKB?>O6`-ZpSHtUQKB?>O6
+aa at aQHt(3FB?>O6aa at aCHtTBh<2W\[Qs!"J=\4u`8XNXPVc5mJ=\4u`8`n7=s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIdaZjkbg")F`RfKHf6h&ZHt(3FB at hN?aa at aQHt(]T at b??O
+f6h&[KPoCh@`3VAfS".\H[XP"DV0V[`-ZpbKPoFqDTR9=Qs!"J=\4u`8Z#]\Qs!"jPDfJ at s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7crjQG4OhV$]@
+daZjreCMgec-+>UbKS5Sbg"_-OP#5(fS".pKPoFqDV0V[fS".\H[XP"DV0V[aFnTdKPn_TIFs3j
+fS".pKPnkaEnH%_fS".qN-O!.DV9tnfo11/N-MdI=dW>`Q=EqepA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkLnYIdaZk#bfe2Rc-+>U`5T^6`Pp$Ec, at T?`5T^HPC_DGGhJ%#fo11/N-O!.DV9tn
+fo11/N-O!.DV9tnfS".qN-O!.DV9tnfo11>L2>P%GhJ%#k_<p,N-O!.DTR9=daZk+jQG4OhU9p)
+fZ_OW`Pp$Ec, at T?`k8m^D-tqKDV9tnkDO?5N-ONDES6:ql'-VLN-O$7GhJ%#fo11.KPot2ES6:q
+fo11/N-O$7GhJ%#fo11/N-O$7Gk^Rfs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39i
+g"bH-bg")F`Pfa7]=bhq`PoI%]t:qj`5T^&['Z]77 at 74L[rc*4N-ONDES6:qfo11.KPoJ%Gh@[e
+fo11/N-O!.DV9tnfo11/N-O$7Gh@[efo11/N-O$7Git!)kDO?[s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7ckgtpK/f#5PH]=bhh]Y1\Z[(Eua['[3=P`V888XNXP
+Qs!"X>=Fo^8_A]6fo11=MfIF/Git!)fo11/N-ONDES6:qfo11/N-O$7GhJ%#kDO?5N-O$7GhJ%#
+kDO?5N-ONDES6:qfY"Z2`PoI%]t:qj['[3I['[3I[&^:1W/QIu=\4u`8XNXPQs!"J=\4u`8[ieN
+fo11/N-O!.DV9tnfo11.KPoFqDV9tnfS".qN-O$7Gh@[efo11/N-O!.DV0V[fS".pKPm/[8XNXP
+Qs!"J=\5#W4IB8CaE1bAN-O!.DV9tnfS"/*MfIF/GhJ%#kDO?4KPoJ%Git!)fS".qN-ONDES6:q
+fo11/N-O$7GhJ%#fo11/N-O$7GhJ%#fS".qN-OHSL\^#is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp5uc, at T?]=bhXXKA:pUnji_Unsl_V50o`UmQOP
+MGZ^.:HXM36CCV3Qs!"K:HY%@4IJu-R85r5:HYRe<7cM,f6h&[KPoCh at b??Of6h&ZHt(`]DV'8F
+f6h&ZHt(`]DV0V[fS".pKPoCh at b??O`-ZpbKPoCh at bAoJi8j(SgtpK/f#5PH]=bha['Zm8XdkuQ
+S=Z7 at St)=BS=H1 at Q=Ep_:HY%@4IJu-MGZ^.:HY%@4IJu-MGZ^.:HY%@4Gm!&R85rB>=I.k at b6!:
+f6h&[KPoFb>f:u;f6h&LHtV&Y@`a"1aa at aRKPn_TIFijUaa@aQHt($@IFijUaa at aCHtVTsh#IES
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s5;u$W+Ar>AP]79<4ZX:
+W+Ar:Cg"2_=gi-L[VT*TCg"2_=gi-L[VT*TCg"2_=gi-L\n+[HFCM[p=gi-L[VT*6=\4KJ6CCV3
+Qs!"<;*pXQ8W$A3Qs!"K:HXM36C:nIR85r5:HYP.I.[..s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726
+i8j(SgtoSqGd_Ek[rc)fCg"5h@^gGg[rc)gFCM_$@^gGg[rc)gFCM_$@^g`"[rc)gFCM_$@^g`"
+[rc)gHtoWt?]%]IQs!"<;*p.;6AeW,Lg!Q2;*p(B:7,0ULg!QpUn-H)kNM:$k1nbUm-ilnkK'Hi
+aa at aBFC*(:B=E8'aa at a1HtpcNB?>O6aa at aBKQ>1^B?5aHf6h&KKQ>.eEl<<Qaa at a>H[X"`B?>O6
+W+Aqq=\4u`8Z#]\Qs!"J=\4u`8XNXPQs!#4`4c3Ns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(SgtpK/f#u:^f>PAEHtUQKB at hN?`-ZpaHt($@IFijU`-ZpSHtUQKB>f.Ff6h&KKQ>^uDV0V[
+aa at aRKPnkaEn>\JaFnTTKQ<G_8Z#]\Qs!"H at o\n!8]R6Ys8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,g"bH;gtpK/f$`(!bKS5`bfe2Rc-k+m
+`k8n(KQ>^uDTIKOaFnTPH[WtgEnH%_aFnTdKPn_TIFs3jaFnTdKPnkaEl`oSfS".`KQ>b)GfYPY
+fo10sMga62DT$mMW+Aqo at o\n!8\'P"s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d#gt^?-f#u:^
+bKS5Sbg")F`RrDX`5T^6`Pp$Ec,cu_fo11/N-O$7GfYekfo10sMga9;GfYekfo10sMga9;GhJ%#
+fo11/N-O$7GhJ%#fo11/N-O$7GhJ%#fo11/N-NF>S`\__g"bH4eCMgec, at T?`5T^6`PoBVPdYC2
+fo11=MfIF/GhJ%#kDO?5N-O$7GhJ%#fo11.KPoJ%GhJ%#fo11/N-O$7Gh@[efo11/N-O$7GhJ%#
+kbX@?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQFt at f$`(!`5T^-]Y28&`Oidr
+`5T^-]Y2=t]">VgVgNHN=\6&<=kSaYfo11/N-O$7GhJ%#fo11/N-O$7GhJ%#fo11.KPoJ%Gh@[e
+fo11/N-O$7GhJ%#fS".nPC_DGGj)K4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_&&kLnYIdaZjd`Pod7`Oidr['[3P]Y1\Z[&J.YQs!"H at o\n!8XNXPW+Ar]N-Np;J_?!,
+fo11,PC_DGGhJ%#fo11/N-ONDES6:qkDO?5N-O$7GhJ%#kDO?5N-O$7GhJ%#fo11/N-NOic-+>U
+]=bha['[3I['[3I['[3I['Z`aI$e&.Qs!"J=\4u`8XNXPQs!"iHtq>nGhJ%#fo10sMga62DTI`a
+fS".`Mg`["EnQCraFnTeN-NF%IFs3jaGYK"N-NF%IFs3jQ=EpP;*pXQ8XW@:WGQ"`KQ>b)GhJ%#
+fo11/N-O$7GhJ%#fS".qN-O$7GhJ%#fo11/N-O$7GhJ%#fo11/N-OTOIFaU5fo11?P^V5DGhJ%#
+fo11/N-Np;Jbm<ds8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o6m-ilnkLnYIbKS5L`Po3k['[3IUnsl_V50o`Unji_UnslRFDHb26AeW,MGZ]t;*p.;6AeW,
+MGZ]t;*p.;6AeW,W+ArLKQ>^uDT$mMf6h&GH[XP"DV'8F`-ZpbKPnkaEn>\J`-ZpaHt(]T@`3VA
+fS".`KQ>^uDTIKOfS".pbff5:n(HLQdaZjkbg!c4]sP/RUnsl_V50WQS>_mAS=Z7 at St)*V<JjX?
+R85r&;*p[H4IJu-MGZ^.:HY%@4Gm!&R85r5:HY%@4K)gjfS".oHt($@IFijU`-ZpaHt(]T@`3VA
+f6h&GH[XLn@`a"1fS".\H[XP"DTR9=aFnTUHtUQKB?>O6q:sBts8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+=jQEsf=fH7F[VT*FAQ6-\@]3j;[VT*GD-s8Z?`@mL
+[VT*GFChFg?aacRWGQ"NCg"5h@^^)U[rc)fCg!`S?^OtfQs!"<;*pXQ8W$A3Qs!"<;*pXQ8W$A3
+Qs!"<;*p.;6C:nIQu-=4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n)iE\\V5::Cg"5h@]=H\
+[rc)YD-sbo@]=H\[rc)YFChq'@]+Tm[rc)WHuQQ:@^g`"[sVr"FCM_,C:A:oWGQ!u>#'lW:7,0U
+Qs!":>#(Gf8VgPFQs!":>#(Gf8[kLgi8j(ZjQGI^kMYFai8j(BUn,VTB=E8'[rc*$HtUQKB?>O6
+[sVr/H[WtgEli]AaFnTPH[WtgEl`oSaa at aBKQ>.eEl`oSaFnTUHtTEq?^OtfQs!"J=\4u`8XNXP
+Q=Ep^=\4u`8]\!0s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kN:RTdaZjreCMXP]#f>4
+aFnTTKQ>.eEli]AaFnTTKQ>1^B?5aHaFnTdKPnkaEl`oSaFnTTKQ>.eEl`oSfS".`KQ>.eEl`oS
+Qs!"H at o\h)<L?o\Q=Eq9XJPsss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjreCMgec-+>UbKS5Sbg"1rNQ?cn`-ZpRKQ>.eEl`oS
+aFnTUHtUNREli]AaFnTTKQ>.eEl`oSaFnTTMg`["Ela/eaGYJfKQ>.lIFs3jaGYJfKQ>1^B:)gn
+Qs!"H at o^UGScA`is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n(HLQg"bH4eCMgec-+>U`5T^=bg")F`QQKM
+`5T^6`PpDlJ]NataGYJfMg`[)IG'R(aGYJfMga9;GfYekfo10sMg`[)IG'R(aGYK"N-NF%IG'R(
+aGYJfMga9;GfYek[sVrCbfeGaf#u:^bKS5L`Pod7`Pfa7Qu-<RKQ>b)GhJ%#fo11/N-O$7GhJ%#
+fo11/N-O$7GhJ%#fo11/N-O$7GfYekfo10sMga9;GfYekfo10sMgbE^iW&rXs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH4eCMRW`Pfa7]=bhs]Xk_f]u7n/]=bhh]Y18.OI00B
+Q=EqJN-Np;J_?!,fo11/N-O$7GhJ%#aGYK!KPoJ%GfYekaGYK"N-NEsEnQCraGYK!KPnkhIG'R(
+fo11/N-PC&s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(Sgtp5uc, at T?
+]=bhh]Y1qi]sP/RW0EC2=\4u`8XNXPQs!"H at o^WuB@`8tfo11,PC_;KJ_$$9ert[9PC_DGGh/(0
+fo11,PC_DGGh/(0l'-VLN-O$7GhJ%#fo11/N-O$7Gh/=FdaZjd`PoI%]sP/R['[3I['[3I['[3I
+R?Nhl;*p.;6AeW,Lg!Q@=\4KJ6FV&Gert[+Mga9;GfYPYaFnTeN-NEsEl`oSfS".`Mg`["Ela/e
+fS".`Mg`[)IE7(^fo10sMg_O8</=^QQs!"iHtp`UEnQCraGYK"N-NF%IG'R(fo11/N-Np;J_?!,
+ert[9PC_DGGh/(0ert[<N-Np;J_$$9ert[9PC_;KJ_$$9ert[<N-O$7Gh]!Wo_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp5uc, at T?
+]=bhXXKAP)Xe_ehUnsl_V50o`UmH1=MGZ]t;*p.;6AeW,MGZ]t;*p.;6AeW,MGZ]t;*q-a7EC.&
+`-ZpRKQ>.eEl`oSaa at aBKQ>.eEli]A`-ZpRKQ>.eEl`oSaa at aBKQ>1^B?5aHaFnTTKQ>.eEotTf
+i8j(SgtpK/f#5PH]=bhh]Y1AIXdkuQS=Z7 at St)=BS=H1 at Q=Ep_:HXM36CCV3MGZ]t;*p[H4Gm!&
+MGZ^.:HXM36AeW,R85rDAQ6a(EnH%_aFnTcHt(0MEnH%_aFnTTKQ>.eEl`oSaFnTTKQ>.eEl`oS
+aFnTTKQ>1^B?5aH`-ZpSHtVTsh#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726[rc)YD-s8Z?`A-YWGQ"OFCM4kAZ9NR[rc)YD-s8aA[ZDXWGQ"NCg!`ZA[ZDX
+WGQ"OFCM4d?ak,d[VT*(;*pXQ8W$A3Qs!"<;*pXQ8W$A3MGZ]t;*p.;6C:nILg!Q2;*pXQ8a,O0
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(SgtoMfC8l;dWGQ"OFCM_$@]=H\[rc)gFCM4kA[cbj
+[rc)YFChFnA[cbjWH;^LHuQQ:@]+Tm[sVr"HtoWt?\hl\Qs!":>#'lW:5E(KLg!Q@=\4EQ:5E(K
+Lg!QpXJOk9kMYFakj7crjQGI^kLcl.[sVr"FCN@>B=E8'[sVr4HtU!DGfb>G\V5:LKQ>.eEl`oS
+aFnTTKQ>.eEl`oSaa at aBKQ=PLC<2'KWH;^;@o\n!8W%"[Qs!"H at o\n!8W%"[Qs!"iNJ7E4s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7ckgtpK/f%A3i`k8n)HtUNREl<<Qaa at aBKQ>1^B?5aH
+aFnTTKQ>.eEl`oSaFnTTKQ>.eEl`oSaGYJfMg`[)IE7=paFnTEKm8tf8X<jdQs!"H at o\h)<S,1&
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(`gt^?-f$`(!daZk#bfe2Rc,c]OaFnTPH[WtgEl`oS`-ZpSHtUQKB>f.FaFnTPH[WtgEli]A
+aFnTdKPnkhIE7(^fS".`Mg`["EnQCraGYJfMg`[)IG'R(aGYJUFCLPG<L?o\Qs!#CbfTnbs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\m.9o6m-iW_hU9p)bKS5`bfe2Rc, at T?bKS5L`Pod7`QQKMaJ>BJMg`[)IE7=p
+aGYJfKQ>.lIE7=paFnTTMg`[)IE7(^fo10sKQ>.lIE7(^aGYJfMga62DTI`aaFnTeN-NEsEjqj;
+daZjkbg">Tc, at T?`5T^)UnFYt<8!4TfS".pKPoFqDV9tnfo10sKQ>b)GfYPYfo10sKQ>b)GfYek
+aFnTdKPnkhIE7(^aFnTTKQ>.lIFaU5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o.jQG4OhU9p)`5T^6`Pod7`Oidr]=bhq`PoI%]u7n/\?2cg at p#+$8]ZR*aGYJtPC^f5IFaU5
+aGYK"N-NF%IFaU5aGYJfMga62DTI`aaGYJfKQ>.lIE7=paFnTTMg`["Ela/eke+/"s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkL.l2daZjd`PoI%]sP/R]=bheXf at b*@Ye2_
+Qs!":>#(Gf8Z63"aHM;1N-NpBOOfVHert[9PC_;KJ_$$9es_]OPC_;KJ_$$9ert[9PC_DGGh/(0
+ert[9PC_DGGhJ%#ert[;[&hHpc-+>U]=bha['[3I[&^:1['[3I['Zd#Q&&U=Qs!":>#'rP6C:nI
+Lg!Q_FCN=LIG'R(aFnTeN-NF%IE7(^aFnTTKQ>.lIE7(^fo10sMg`[)IE7(^fo10sMg`[)IE7=p
+WGQ"@AQ6a(Ela/efo10sMga9;GfYekfo10sMga0?J]NataGYJtPC^f5IG'R(ert[<N-Np;J_$$9
+ert[9PC_;KJ_$$9ert[9PC_;KJ_$9OpsdFcs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIbKS5L`Po3k['[3IUnsl_V50WQS><!W
+UnslSI!(<D6AeW,MGZ]t;*p.;6AeW,MGZ]t;*p.;6AeW,Q=Eq9KQ>.eEl`oSaFnTPH[WtgEl`oS
+aa at aBKQ>.eEli]AaFnTPH[WtgEl`oSaFnTTKQ>.eEl`oSaFnTdbff5:n(HLQdaZjkbg!c4]sP/R
+X/rG!V50WQS>_mAS=Z7 at St([J=GU-UMGZ]t;*p.;6AeW,MGZ^-=\4KJ6AeW,R85r&;*p[H4K)gj
+aFnTTKQ>^uDTIKOaFnTTKQ>.eEl`oSaFnTdKPnkaEl`oSaFnTTKQ>1^B?5aHaFnTTKQ>.eEl`oS
+k1nbls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o:oC]YJGc>Oe
+WH;^ND-s8aAZ9NRWGQ"AFChFg?`A-YWGQ"AFChFnAZ9c_WGQ"OFCM4kA[ZDXWH;^[Cg!`ZAXHUl
+MGZ]r>#'rP6ASf?MGZ]r>#'lW:7,0UMGZ]r>#'rP6ASf?Lg!R+bfg%ds8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n(>k-WH;^\FCM4kA[cbjWH;^NFChq'@]+Tm[rc)WHuQ',AZ9c_WH;^NFChFnA[cbj
+VgNHmHtoX&A[d&%WH;^->#(Gf8VgPFQs!":>#(Gf8VgPFLg!Q@=\4EQ::RF+i8j(ZjQGI^kMYFa
+i8j(A[B[2_@`a"1[sVr"HtpTHICFT=aa at a3Km:^eB=W_ at aFnTEKm:[lEk-mKaFnTEKm:.^GfYPY
+\V5:;Htp-<C7&-qMITbU=\4K\=GU-UQ=EpN>#(An<L at W4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n(HLQdaZjreCM^:S]HJ)aFnTTKQ=VWGfYPYaFnTTKQ>.eEl`oSaGYJWML<L'IE7=p
+aGYJfMg`[)IE7(^aGYJfMg`[)ICFT=Q=Ep\@o\h)<L.,pQ=EqWgt_r0s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*q=n(HLQg"bH4eCMgec-+>U
+a0i1nKQ=PLC<2'K[sVr"Htp`UEk-mK[sVr3KQ=VWGfYPYaa at aBKQ>.eEl`oSaFnTTKQ>.lIE7(^
+aGYJfKQ>.lIE7(^aGYJfKQ>.lIE7(^W+Aqq=\4u`8X<jds8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+k1nbFgtpK/f#u:^bKS5L`Pod7`RrDX`5T^6`Poj0]#]eXaFnTTMg`["Ela/eaFnTTMg`[)IE7=p
+aFnTTMg`["El`oSaGYJfMg`["Ela/eaFnTTKQ>.eEl`oSaFnTCHtpjKc-+>U`5T^6`Pod7`Kt[^
+[rc*#KQ>.eEla/eaFnTTKQ>.eEnH%_aFnTTMg`["Ela/eaFnTTMg`[)IE7=paFnTTMg`[)IE7(^
+aGYKAeB.ajs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2g"bH4eCMgec, at T?
+]=bhq`PoI%]u7n/]=bhs]Xk_f]pNYGQs!"[FCj-aGfYekert[+Mga0?J]NataGYJfKQ>.lIE7=p
+aGYJfMg`["Ela/eaFnTTMg`[)IE7(^aGYJfMg`["EqK)$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#+oog"bH4eCMRW`Pfa7]=bhh]Y1\Z[$Z5`Lg!Q>@o\Cr=GU-UQ=Eq*Km;14J]O%.
+ert[+PD%MUOOfVHes_]OPC_;KJ_$$9es_]OPC_;KJ_$$9aHM;.PC_;KJ]O%.ert[+PD%VJGhC6`
+daZjd`PoI%]sP/R['[3I['[3I['[3IUnslC>#'lW:5E(KLg!Q2;*p(B:8r);aGYJfMg`[)IE7=p
+aFnTTMg`[)IE7(^aFnTTKQ>.lIE7(^aGYJfMg`[)IE7=paGYJfMg`["Ela/eaGYJfMg`[1KZK("
+ert[+Mga0?J]Natfo10sMga0?J_$$9aGYJtPC^f=K[u?<ert[9PC_;KJ_$$9ert[9RZQ*aJ_$$9
+kd.5fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(Sgtp5uc, at T?]=bhXXKAP)Xe_ehUnsl_V50o`UmQOPG#Cqg>#'6=8r?J4
+G#Cqi;*oG(8r?J4MGZ]t;*pRY<QKi6\V5:LKQ>.eEl`oS\V5:LKQ>.eEk-mKaFnTEKm:[lEk-mK
+`-ZpCKm:[lEl<<QaFnTTKQ=VWGhC6`i8j(SgtpK/f#u:^]=bhh]Y1,;Unji_S=Z7 at St)=BS=H1@
+Q=EpN>#'rP6ASf?Lg!Q2;*p(B:5Vn8MGZ]t;*p.;6AeW,MGZ^>D-tA;El`oSaFnTTKQ>.eEl`oS
+aFnTTKQ>.eEl`oSaFnTTKQ>.eEl`oSaFnTTKQ>.eEl`oSaFnTTKQ?51h#IESs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726\<DiMD-s8aAZ9NRWH;^NFChFg?`A-Y
+WGQ"AFChFg?`@mLWGQ"AFChFnAZ9NRWH;^NFChFnAZ9c_WH;^;@o\=g:5E(KMGZ]r>#'lW:5Vn8
+Lg!Q2;*p(B:5E(KLg!Q0>#'lW:<9N5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7bmCkj7cV`Po<.@]=H\
+WH;^NFChFnA[cbjVgNH_FCh at tE49puVgNHmFCM.qE4:40VgNH]HuQQ:@]+Tm[sVr"HtoX&AXHUl
+Lg!Q2 at p#+$8VgPFMITbG at p#+$8W%"[Lg!QpXJOk9kMYFai8j(ZjQGI^kL[Yc[sVr"Htp-<C:AS*
+[sVr3KQ=VWGfYPY\V5:LKQ=VWGfYPY\V5:=Km:.^GfYPY\V5:=Km:.^Ge&NQ\V59o at o\h)<JXgR
+Q=Ep\@o\h)<L.,pQ=EpP at p&QfiW&rXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<kj7d#gt^?-f$`(!
+a-hptKm:.^Ge&NQ\V5:LMg`-nI(>,^\VbdUMg`'oKuf1#\VbdUMg`-nI)q4oaGYJUNJ5H3ICG2i
+aGYJGFCg>>=I*GsMITbS at o\Cr=TAF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVi8j(ZjQFt at f$`(!fZ_OY]XkY-Ge&NQ[sVr$Km:(SC:AS*
+[sVr"Htp-<C:AS*aFnTCHtp3GGe&NQ`-ZpCKm:[lEl`oSaFnTTMg`[)IE7=paGYJfMga0?J]Nat
+fo10sMg`["EgC38Q=Ep^=\5N=E<#t<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n(HLQdaZjkbg">Tc-+>U
+`5T^=bg")F`QQKM`5T^9R>nb2Ge&NQ\V5:LMg`-iGe&NQaFnTEKm:[sIE7(^\V5:LKQ>.eEl`oS
+aGYJfKQ=VWGfYekaFnTTMg`[)ICFT=\"o\8`Pod7`Pfa7\?2cu=\6\fEl`oSaFnTTKQ>.eEla/e
+aFnTTMg`["El`oSaFnTTMg`[)IE7(^aGYJfKQ>.lIE7=paFnTTMg`[1K`D)Ps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkL.l2bKS5L`Pod7`Oidr`k8mp]Y28&`Oidr
+]=bhUP`V2@<L.,paHM:uMg`[)IFaU5aGYJfMg`[)IE7=paGYJfMg`[)IE7=paGYJWKm:[lEk-mK
+\V5:LMg`-iGe&]ZaGYJtRZRRLs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7crjQG4OhU9p)
+`5T^6`PoI%]sP/RR!a%B at o\Cr=GU-UQ=EpN>#(uCE7U5(aHM:uPD%MUON3cKert[*R>o7TNRjP[
+a-hq<RZPRXNRjP[a-hq<RZQ*hON<W=es_]OPC^f=K[u?<aJ>B[gtp5uc, at T?]=bha['[3I['[3I
+X/rG1['[?FWet:gQs!":>#'lW:7,0ULg!QQD-tABIE7V*aGYJfMg`[)IE7(^aGYJfMg`[)IE7=p
+aGYJfMg`[)IE7=p\VbdUMg`[)IE7=paGYJfMg`[1KZK at 1ert[+PD%#@KZK at 1aHM;.PC^cBNRj;E
+a-hq<PC^f=K[u?<aHM;.PC^f=K[u?<a-hq<PC_;ROOfVHes_]qeB.ajs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYI
+bKS5L`Po3k['[3IUnsl_V50o`Unji_UnslSI!'^=</OO>Lg!Q2;*p(B:5Vn8Lg!Q0>#'6=8r-YG
+Qu-<CML<L'IE7(^\VbdFKm:[sICY&V\V5:LKQ=VWGe&NQ[sVr$Km:.^Gdi'8\V5:=Km:.^Gf4rW
+\V5:\bff5:n)39idaZjkbg!c4]sP/RX/rG!V50WQS=H1 at S=Z7 at St([J=GU-ULg!Q0>#'lW:5Vn8
+Lg!Q2;*p(B:5E(KLg!Q0>#'rP6C;V!aFnTTMg`[)IE7(^aGYJfKQ>.eEl`oSaFnTEKm:[lEk-mK
+aFnTTKQ=VWGfYPY\V5:LKQ=VWGfYPYk1nbls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o:oC]SgTW)d8Qu-<3FCghV@]=3OWH;^ND-s8Z?`@mLWH;^ND-s8Z?`A-Y
+WH;^NFChFg?`A-YWH;^NFChFnAX6h+MGZ]r>#'lW:5E(KMGZ]r>#'lW:5E(KLg!Q0>#'lW:5E(K
+Lg!QPN/%B4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n&V;qWH;^NFChq/C8ZGuWH;^LHuQ',AZ'op
+VgNH]HuQ!2E2S)&WH;^LHuQQ:@]+TmVgNHmHtoR,E4:40QZR#!>#'rb=GU-UMITbE>#'lW:5E(K
+MITbE>#'rb=LbK5q;gMmjQGI^kMYFai8j(RbfdPNGdi'8\V5:=Km:.^Gdi'8\V5:=Km:.^Ge&NQ
+\V5:=Km:.^Ge&NQ\V5:=Km:.^Ge&NQaFnTEKm:.^Ga;i>Q=EpP at p#%,<Jk9gMITbG at p"Uu=GgTj
+`k8n_s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIdaZjkbg!\UI)pt]\V5:=Km:[lEk.'T
+\VbdUMg`-nI(>,^aGYJUNJ5H3ICG2i[uH*_Mg`+!Mo^g)[uH*_Mg`'oKrK0*MITbG at p"Uu=GgTj
+VgNI`s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,_m-j0)n)iE\daZjreCMRW`Q3sc\V5:;Htp-<C:T%C[sVr$Km:(SC:AS*\V5:;Htp3GGfYPY
+[sVr3KQ=VWGfYPYaGYJWKm:[lEla/eaGYJfMga9;GfYekaGYJfMg`[)IE7=paGYJfKQ;lP:6oBi
+Lg!Q`PDfJ at s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mi8j(Sgtp`>hU9p)bKS5Sbg")F`Pfa7`5T^6`Pp$Ec,[5s
+\V5:=Km:.^Ge&NQ\VbdUMg`-iGe&NQ\V5:=Km:[sICY&V\V5:LMg`-iGfYPYaGYJWKm:.^GfYPY
+aFnTTKQ<uDI)O"C`5T^6`Pna.I&Usi\V5:LKQ=VWGfYPYaFnTTKQ>.lIE7(^aGYJfMg`[)IE7=p
+aFnTTMg`-nI)q4o[uH*_Mg`-iGfYekk01sIs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2i8j(Sgtp5uc, at T?`5T^-]Y1qi]u7n/]=bhq`PoI%]sP/RQ=Ep\@o^U'ElXT-
+aHM:uPD%#8IE7V*aGYJfMg`[)ICG2iaGYJWKm:.cI(>,^\VbdFML<L'ICY&V\VbdUMg`'oKt3(g
+aJ>C,s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYIdaZjkbg")F`OidrUnslSD.8B4=GgTj
+MITbG at p"Uu=JpOca-hq=S:8MHNQ7HHa-hq-R>o7TNQ7HHes_]@R>o:OKZBL?es_]APD%MUON<W=
+a-hq<PC^cBNRjP[aHM;.RZQ17[aN[VdaZjd`PoI%]sP/R['[3I['[3I['[3I['[3,FDH\9:5E(K
+Lg!Q0>#'lW:6oBiaHM:uMg`[1KZK("aGYJfPD%#8IE7=paGYJfMg`[)ICG2iaGYJfMg`[1KXZqp
+aGYJUNJ5H;KZK at 1aHM:uPD%#@KZBL?aHM;.RZPUSKZBL?es_]@R>oddON<W=es_]@R>od]J]O%.
+ert[*R>oddON<W=aHM;@]WhG9s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(LeCMgec, at T?]=bhXXKA:pUnji_
+Unsl_V50o`UmQOPG#Cqg>#'6=8r-YGH!=7(>#'6=8r-YGLg!Q2;*pXe@`XIU\VbdFML;slI(>,^
+\V5:=Km:.^Ge&NQ\V5:=Km:.^Ge&NQ[sVr$Km:(SC8Z`4[sVqgKRC=aGhC6`i8j(SgtpK/f#u:^
+]=bhh]Y1AIXdkuQS=Z7 at St)=BS=H1 at LM^[[>#'lW:5E(KLg!Q0>#'lW:5E(KG#Cqg>#'lW:5Vn8
+Lg!Q at D.:SEICY5_\V5:=ML;sgGfYek\V5:=Km:.^GfYPY\V5:=Km:.^GfYek\V5:=Km:.^Ge&NQ
+\V5:=Km;b8h#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+a0i1>D.9J]?^P\>Qu-<3FCghV@]=H\Qu-<"D.9JdAXI=DWH;^ND-s8aAZ9c_WH;^NFChFnAZ9c_
+WH;^NFCghB8VgPFLg!Q0>#'lW:5E(KLg!Q0>#'lW:5E(KLg!Q0>#'lW:6oBikj7d<s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6/h<kj7cJPDc>dE2dqjVgNH_FCh at tE2S)&VgNH]HuQ!2E2dqjVgNH]HuQ!2E2S)&
+VgNHmHtoR,E2SA:[sVqgKRBb at AVsu"Lg!Q2 at p"Oj:5WO`MITbG at p"Uu=GgTjLg!Q`XfC=?kNM:$
+i8j(ZjQGI^kLnYI\<Di]Km:(SC:T%C[sVr$Km:(SC:T%C\V5:=Km:.^Ge&]Z\V5:=Km:.^Ge&NQ
+\V5:=ML;sgGe&]Z\V5:-FCg>>=I*GsMITbE>#(An<Jk9gQ=EpN>#(uKI/j6Hs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726kj7d#gt^T<hT!4>\V5:=Km:.cI(=rU[uH*PML;sgGe&]Z\VbdDNJ4j$Kt!%q
+\<DilMg`'oKt*>)aGYJUNJ4j$Kuf1#[uH*/D.8B4=GgTjQ=EpP at p$49T`>&ls8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726kj7ckgtp`>hUp&q
+a-hptKm:(SC:T%C\V5:;Htp3GGdi'8\V5:;Htp3GGe&NQ[sVr$Km:.^Ge&NQ\V5:LMg`-iGfYek
+\VbdUMg`[)IE7=paGYJfPD%#8IE7=paGYJfMg`[)IE7=p[sVqH>#'lW:5E(KfY"Zms8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+ILkMYFag"bH4eCN9rbKJ,S`5T^JbfdrD`QQKM`5T^6`PoBVPduKm\V5:=Km:.^Ge&NQ
+\V5:LMg`-nI(>,^\V5:LMg`-iGe&NQ\V5:=Km:.^Ge&NQaFnTEML;slI(=rU[sVr"UnGZF`Oidr
+Lg!Q_Htp-<C:T%C\V5:=Km:[sICG2i\V5:=ML;slI)q4o\V5:;NJ5H3ICG2iaGYJUNJ5H;KZK("
+[uH*^R>q7Hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYI
+daZjd`Pod7`Pfa7`5T^-]Y28&`Oidr`k8n$`Pn1&MMbnGWH;^mPD%#@KZK at 1a-hq.PD$uENQ@$+
+\<DilMg`'oKt!%qaGYJUNJ5H3ICG2i\VbdDNJ4j$Kt!%q[uH*_Mg`'oKug'\p[%)Cs8W-!s8W-!
+s8W,kpA+(Hp#tc2g"bH;gtpK/f#u:^['[3-I!(<V=GgTjMITbG at p"Uu=GgTj\V5:LPD$uENQ7HH
+a-hq-R>o7TNRjP[a-hq-R>o7TNQ7HHes_]@R>o7TNQ7HHa-hq<RZPRXNRjP[a-hq-R>o7TNQ7HH
+g"bH;gtpK/f#5PH]=bha['[3I['[3I['[3I['[3I[$QGsLg!Q0>#'lW:5E(KLg!Q0>#*.sIE7V*
+aGYJfPD%#@KZK("aHM:dNJ5H;KXZqpaHM:uPD%#@KXZqpaGYJfPD%#@KZK at 1aGYJUNJ5H;KZK at 1
+aHM:uPD$uENQ@<:a-hq-R>o:OKZBL?a-hq-R>o:OKZBL?a-hq-R>o7TNRj;Ea-hq<RZR at +iW&rX
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIdaZjd`PoI%]sP/RUnsl_V50o`Unji_UnslSI!'U18r?J4
+G#CqU;G)gD6?Z7!Lg!Ps;G)aK:3KN-Qu-<CML;slI(>,^aGYJWML;sgGdiZd\V5:=Km:.^Ge&NQ
+\V5:;Htp3GGc,q.\V5:=Km9MCE4L[I[sVr6bg#),kMYFadaZjkbg!c4]sP/RX/rG!V50WQS=H1@
+S=Z7 at St(RQB8B_dLg!Q!>?$D^:5E(KH!=7(>#'lW:5E(KLg!Q0>#'lW:7,m-aGYJUNJ5H3ICY5_
+aGYJWML;slI(=rU\V5:=Km:.^GfYPY\V5:=Km:.^Ge&NQ\V5:HH[WGYGe&NQk1nbls8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o:oC^b[bF!-UQu-<"D.9JdAXI=D
+Qu-<3FCge\CT2DeQu-<3FCghV@]=H\WH;^NFChFnAZ'opVgNH_FCh at tE2dqjMITbE>#'lW:5E(K
+Q=EpN>#'lW:5E(KLg!Q0>#'lW:5E(KLg!Q0>#*)M])Vg1s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC^elhPkU.
+WH;^LHuQ',AZ'opVgNH]HuQ!2E2S)&VgNH]HuQ!2E4:40VgNH]HuQ!:I&D at 2[sVqgKRB\FE4L[I
+QZR##@p"Uu=GgTjLg!Q2 at p"Oj:5E(KLg!Q!>?$Ji=LbK5i8j(ZjQGann)39ii8j(LeCM^:SYq-g
+\V5:;HtoR4I(+K<VhBH.Km9MCE4L[I\V5:=Km:.^Ge&NQ\VbdFKm:.^Ge&NQVhBH.Km:.^Gc-4B
+MITbG at p"Uu=GgTjLg!Q2 at p"Oj:5WO`Lg!R;m-juSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLnYI
+daZjhUn,&RI(>,^\VbdFML;sgGdiZd\VbdDNJ4p#I(,)h[uH*NNJ4j$Kt!%q\<Di]ML;ptMn+^m
+\<Di[NJ4osG`$!5MITbG at p"Uu=GgTjfZ_P=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjhXJNI]Ge&NQ\V5:=Km:.^Ge&NQ
+\V5:=Km:.^Ge&NQ\V5:=Km:.^Ge&]Z\V5:LKQ=V\I)q4o\VbdUMg`[)IE7V*[uH*_PD%#@KZK at 1
+aGYJfPD%#8ICPK!aGYJVPDdM?I@#%kMITbE>#'rb=Q\Dos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-iW_hU9p)
+daZjkbg">Tc, at T?bKS5L`Pp$Ec, at T?a0i1_Km:.^GdiZd\VbdDNJ4p#I(>,^\VbdFML;slI(>,^
+[uH*_Mg`'oKuf1#\VbdFML;slI(=rU\VbdUMg`-nI&DXF`5T]oN/!^:@_%2;\V5:=Km:.^Ge&]Z
+\VbdFML<L'ICG2iaGYJUNJ5H;KXZqpaHM:dNJ5H;KXZqpaHM:dNJ5H;K\+/Us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7ckgtpK/f#u:^`5T^-]Y2=t]">Vg
+]=bhq`PoI%]t:qj['[3-D.8B4=NH\Za-hq-R>o7TNQ7HH\<DilPD$H0Mo_*8\<DilMg`+!Mmn\"
+[uH*NNJ5H;KXZqp[uH*_PD$E)Kt*>)\<DilMg`+!Mq>n\o_/+\s8V`bq<[_Gkj7ckgtp`>hTO-f
+UnslSI!(6K:5WO`Lg!Q2 at p"Oj:5WO`QZR#RML<I4NQ7HHa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HH
+a-hq-R>o7TNQ7HHa-hq-R>o7TNQ@<:a-hq-R>o:OKZBL?es_]Q]XHbZkLnYIbKS5L`PoI%]sP/R
+['[3 at XKAk:['[3IX/rG%R[&\4:3U5VLg!Q2 at p"Oj:5E(KVhBH=PD$E)KufI2[uH*_PD$E)KufI2
+aHM:uPD$E)KufI2aHM:uPD$E)KufI2[uH*_PD%#@KZBL?aHM:ePDdJLNQ@<:a-hq-R>o7TNQ7HH
+a-hq-R>o7TNQ7HHa-hq.PD$uENQ@<:a-hq-R>ok+XT/>#s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(Sgtp5uc, at T?]=bhXXKAP)XdkuQUnsl_V50o`UkX8DG#CqU;G)4=</OO>G#CqU;G)gD6?Z7!
+G#Cqi;*pXe at _%2;\VbdFKm:.cI(=rU\V5:=Km:.cI(>,^VhBH.Km9MKI(=rUVhBGqHuQ!:I&D at 2
+\V5:+HuQ!:I+ZZdi8j(SgtpK/f#u:^]=bhh]Y1AIXe_ehS=Z7 at St)44PGG%NLM^[L>?$D^:3g&C
+Lg!Q!>?$D^:5WO`H!=7(>#'9P@#.u]MITbUD.:#=Mo^g)[uH*_Mg`'oKt3(gaGYJWKm:.^Ge&NQ
+\V5:=Km:.^Ge&NQ\V5:=Km:.^Ge&NQVgNHoKm;b8h#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gk1naYFDI7\@[M"AQu-<"D.8lL@[D1PWGQ"/FDI7\@]=H\
+QZR#BFCge\CSuQ!VgNH_FCh at tE2S)&WH;^LHuPHi at Ye2_Lg!Q0>#'lW:5E(KLg!Q0>#'lW:5E(K
+Lg!Q!>?$D^:3g&CVhBHts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726a0i1=FDI4bCR9-YR!a%CFDI4bCSuQ!
+QZR#@HuQ!2E2S)&VgNH]KRB\FE2S)&VgNH]KRB\FE2SA:VgNH]KRB,.CPZ.hLg!Q!>?$Ji=F"+M
+Lg!PtA71:)=F"+MLg!Q_UnHr<n*'-,i8j(bm-ilnkLnYIa0i1_Km9MCE2SA:VhBH,HtoR4I&D at 2
+\V5:+KRB\NI&DXFVhBGqKRB\NI&DXFVhBGqKRC=aGe&]ZVhBH.Km8nn<JXgRLg!Q0>#'rb=F"+M
+Lg!PtA713s::RF+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f!pp%\VbdFKm:(dKt2n^
+W/QJAKm:(dKt!%q[uH*NNJ4j$Kt!%q\<Di[NJ4j$Kt!%q[uH*OPDcu/I(5AuVgNH@@p"Uu=GgTj
+MITbDD.inKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+ at Sq<726i8j(Sgtp)ZZ)EV9\V5:+KRC=aGe&NQ\V5:=Km9MKI(=rU\V5:=Km:(dKt2n^
+\VbdFML<L'ICG2i[uH*PML<L/KXZqpaHM:dNJ5H3ICG2iaHM:dNJ4m+Mmn\"[uH*OPDdM?ICG2i
+aGYJWML:e. at Z"YtMITbTFDLpVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^bKS5Sbg")F`QQKM
+`5T^6`Pod7`Mf#_\Vbd4KRC=fI(,)hVhBH.ML;mmKt3(g\VbdDNJ4j$Kt!%q[uH*NNJ4p#I(,)h
+\VbdFKm:(dKt2n^\Vbd4HuQQjTSQcHVhBH.Km:.cI(>,^\VbdDNJ4osGdiZd[uH*NNJ4j$Kt!%q
+[uH*NNJ4j$Kt!%q[uH*NNJ4j$Kt!%q[uH+As8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH-bg")F`Pfa7`5T^-]Y28&`Oidr`k8n$`PoI%]r7Bb
+MITbTFDJpbNQ7HHa-hq-R>o7TNQ7HHa-hpsPDdJLNOY11\<Di\PDdMGKXd5([uH*OPDcr7Mmn\"
+\<Di\PDco0Kt*>)\<Di[NJ5E at NQ8H3`k8mi['[?FWi2AOR!a%6 at p"Oj:3g&CH!=6n>?#lP</=^Q
+QZR#RML<I4NQ7HHaHM:tR>o7TNQ7HHa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HH
+a-hq-R>o7TNQ7HHa-hq-R>o:`S`&Slkj7ckgtpK/f#u:^]=bha['[3I['[3I['[3I['[3I[%sOo
+MITb6>?$Ji=GU-UH!=7*@p#^PA]U'g\<DilPD$H0Mo_*8\<DilPD$H0Mo_*8aHM:uPD$H0Mo_*8
+aHM:tR>o:OKZBL?\<DilPD$H0Mo_*8a-hq.PD$H0Mo_*8a-hq-R>o7TNQ7HHaHM:tR>o:OKZK at 1
+a-hq-R>o:`Sb_@*s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIbKS5L`Po3k['[3I
+Unsl_V50o`Unji_UnslSI!'U18p4*)G#CqU;G)+18pOW?G#CqU;G)+18p4*)MITbtNJ4osGdiZd
+\V5:;NJ49`I(=rUVhBH.Km9MKI(>,^\V5:+HuQWMGc,q.VgNHoKm9MCE2SA:VgNI9bfer*kMYFa
+daZjkbg!c4]sP/RX/rG!V50NCPGG%NS=Z7 at St(RQB6d]\Lg!Q!>?#lP</=^QH!=6n>?$D^:3g&C
+Lg!Q!>?$D^:7$'<[uH*OPDcr7Mn"t/[uH*NNJ4j$Kt3(g[uH*PKm:.^Ge&NQ\V5:=Km:.^Ge&NQ
+\V5:+KRC=aGc,q.k1nbls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n#22"Qu-<"D.8lL@[D1PQu-<"D.8iRCRAsJQZR#1D.8iRCSuQ!VgNH_FCgheFf0V+
+WH;^LHuQ',AZ'opQu-;g>#'?I</=^QH!=6n>?$D^:3g&CH!=6n>?#lP</=^QH!=6k;G)gV=P;Kd
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-gm;OI(')WH;^<FDIe%E0kZ^VgNHMFDI7kFf0V+R!a%DI!)?7E2S)&
+VgNH]KRB\FE2S)&VhBGqHuQ!:I&D at 2QZR##@p!qc@#.u]H!=7*@p""\<-_\IH!=6n>?#lP<4K'1
+kj7crjQGann)39ii8j(`gt^)sc)65BVgNH]HuQ!2E2S)&VgNH]KRB\FE2S)&VgNH]KRB\FE2S)&
+\V5:+HuQWMGc-4BVhBGqKRB\NI&DXFQZR#!>#'9P@#.u]H!=7*@p""\</=^QG at Y*KD.<PFs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-j)lgtCK>a0i1MKRC=aGc6RUVhBH.ML;sgGc6RU[uH*NNJ4j$Kt!%q
+\<Di[NJ4j$Kt!%q\<Di[NJ4m+Mmn\"[uH*NNJ3^@CPlV(MITb4A71:)=K%15s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQGI^kLe#%
+[uH*PKm9MKI(>,^W/QJ?NJ49`I(,)h\V5:;NJ4<iL:<.r[uH*PML;mmKt*>)[uH*OPDdMGKXZqp
+aHM:dNJ4j$KufI2[uH*_PD$E)KufI2[uH*_PD$E)Kuf1#\<Di[NJ4m+Mo^g)\Vbcl at p"Uu=GU-U
+VhBHts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n(HLQdaZjreCMgec-+>U`5T^6`PpKRbJ_B=bKS5PXJMhJI(>,^
+VhBH.ML;@]L:N1hW/QJ?NJ4p#I(,)h[uH*NNJ4j$KufI2[uH*PML;mmKt3(g[uH*PKm:(dKt2n^
+LM^[ZD.gD5Ge&NQVhBH,NJ4osGdiZd\VbdFML;slI(,)h[uH*PML;mmKt!%q[uH*OPDco0Kt!%q
+[uH*NNJ6#t[f?C-s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o.jQG4OhU9p)bKS5L`PoI%]u7n/]=bhh]Y1qi]u7n/]=bhq`Pn0sJVmr>[uH*^R>n_?MoV6F
+\XJbmPDdJLNObLBa-hpsPDdJLNOY11\XJbmPDcr7Mn"t/[uH*OPDcr7Mn"t/\<Di]ML;ptMmn\"
+[uH*OPDdM?ICG2iQZR#1D.7cp<-_\IH!=6n>?$Ji=I<r7R!a%eML;ptMn"t/\<Di\PDcr7Mn"t/
+aHM:fRZtj\NQ7HHa-hq-R>nbGPfK2Oa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HH
+k1nbapA*Y-kLnYIdaZjd`PoI%]sP/R['[3I['[3I['[3I['[3I['YU1E-YYeH!=7(>#'9P@#.u]
+LM^\ER>n_?Mn"t/aHM:ePDdMGKXd5(aHM:fRZtj\NObLBa-hq-R>o7TNQ7HHa-hq-R>o7TNQ7HH
+a-hq-R>n_?MoV6Fa-hptRZtmWKXd5(aHM:ePDdMGKXd5(\<Di\PDcr7MqG\Ns8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(LeCN'tf#5PH]=bhXXKAP)Xe_ehUnsl_V50WQS;23*
+G#CqU;G)+18p4*)G#CqU;G)+18p4*)G#CqU;G*<n@]+m,\V5:+KRB\NI&DXF\V5:+KRB\NI&DXF
+\V5:+KRB\NI&D at 2VgNH]KRB\FE2S)&VgNH]HuQ!:I+ZZdi8j(SgtpK/f#u:^]=bhh]Y1,;Unji_
+S=Z7 at St)=BS=H1 at LM^[I;G)4=<-_\IH!=6n>?#lP<-_\IH!=6n>?$D^:3g&CH!=77FDJFEI(5Au
+\VbdEPDco0Kuf1#[uH*PKm9MKI(=rUVhBGqKRB\NI&DXFVgNH]KRB\FE2SA:VgNH]HuS6'h#IES
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7cJXf at b*@Y\f5
+Qu-;fD.f5Q@[M"AQu-<"D.8lL@[D1PQZR#0FDI4bCSuQ!QZR#BFCgheFdI2cVgNHMFDI4bCPlV(
+Lg!Q!>?$D^:3KN-H!=6n>?#lP</=^QG#CqX>?#cD8pOW?G#Cr2R[*pQs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq:XQ[
+QZR#0FDI4bCR9-YQZR#1I!(ctCSuQ!QZR#1I!(ctCSuQ!R!a%DI!)?7E0u#qVgNHNI!)?7E2SA:
+VgNH]HuPEoCPZ.hH!=6n>?#lP<-_\IH!=6n>?$Ji=F"+MH!=7XXfCUOn*'-,kj7d4m-!<fkMYFa
+daZjHN/"6XE0u#qVgNHNI!)?7E0u#qVhBGqHuQ!2E2S)&VgNH]HuQ!2E2S)&VhBGqHuQ!:I(+K<
+VhBGqKRB\FE/J.-G at Y*;>#'9P@#.u]G at Y*;>#'9P@#.u]`5T^qs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,
+g"bH;gtoT1Pc0Oq\Vbd4KRC=fI&DXFW/QJ?NJ4j$KrBrb[uH*NNJ4j$Kt!%q[uH*NNJ4j$Kt!%q
+W/QJ at PDco0Kt!%qLM^[]@p!qc@#AGrMITc,`PqlWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*q=n)39ifZ_OKPDc>lI&N!Y\Vbd5N/"g$Kr9TO
+[uH*>KRC7gKrBrb\VbdDNJ4j$Kt!%q[uH*OPDcr7Mmn\"\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/
+\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/[uH*OPDco0Kr9TOMITbG at p""\<4AZrs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7d#gt^T<hU9p)bKS5Sbg">Tc, at T?`5T^6`Pod7`Pfa7\<DiKKRB_WL:N1hW/QJ?NJ4j$Kt!%q
+[uH*NNJ4j$Kt*>)[uH*NNJ4j$Kt!%q[uH*NNJ4j$Kt!%q[uH*>KRB\FE2S)&W/QJAKm9PTL:N"_
+W/QJ/KRB\NI&N!YVhBH,NJ4<iL:<.r[uH*NNJ4j$Kt!%q[uH*NNJ4<iL:<.rs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(LeCMgec, at T?
+`5T^6`PoI%]u7n/`5T^-]Y1qi]t:qj]=bhDFDHYKB=O.`a-hptRZtj\NObLBa-hpsPDcu?PfK2O
+\XJbmPDcu?Pdlp8\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/
+\Vbd5N/"lsGc6RU\VbdEPDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/a-hpsPDcu?Pe!6I
+a-hptRZt at OPfK2O\XJbnRZt at OPe!6Ia-hptRZtj\NQ7HHa-hqLbfTnbs6T at Mkj7ckgtpK/f#u:^
+`5T^&['[3I['[3I['[3 at XKAk:['[3IQ\9pI at p""\<-_\IH!=6n>?$Ji=LX9DaHM:ePDdMGKXd5(
+\<DilPD$H0MoV6F\<DikR>o7TNQ7HH\XJc'R>nbGPfT&A\XJc'R>nbGPfK2Oa-hptRZtj\NQ7HH
+\<DikR>nbGPfT&A\XJbmPDdMGKZKs[p[%)Cs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o6m-ilnkLnYIbKS5L`PoI%]sP/RUnsl_V50o`Unji_UnslAI!^$78p4*)BMV3C;G)+18p4*)
+G#CqU;G)+18p4*)MITbdKRB\NI&DXF\V5:+KRB\FE2SA:VhBGqKRB\FE2SA:VgNH]KRB\FE2S)&
+VhBGqHuQ!:I&DXFVgNI,bg#A<n(HLQdaZjkbg!c4]sP/RX/rFnSt)=BS=H1 at R?Ni)St("8@!PsU
+G#CqX>?#cD8pOW?G#CqX>?#lP<-_\IH!=6n>?#lP<1%N3[uH*NNJ4m+Mmn\"\<DiLN/"g$Kt!%q
+VhBH,NJ49`I(=rUVhBH.Km9MKI&DXFVgNH]KRB\NI&DXFk1nbls8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n&32aQu-;fD.f5Q at Z"YtQZR"uD.f2WCRAsJ
+QZR#0FDI4bCR9-YQZR#0FDI4bCR9-YQZR#0FDI4bCR9-YQZR#1D.7Zd8pOW?H!=6n>?#cD8pOW?
+G#CqX>?#lP<-D/3H!=6n>?#cD8p=fRkj7d<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9nZUnF)l@[D1PQZR#0FDI4bCR9-Y
+QZR#1I!(g(Ff0V+R!a%DI!)?7E0u#qR!a%SHuPI#Ff0V+R!a%DI!(g(Ff0V+LNIK\>?#lP<-_\I
+H!=6n>?#lP<-_\IH!=6n>?#lP<4K'1kj7d%m-j0)n*'-,kj7ckgtp`>hRB;RR!a%SHuPI#Ff0V+
+R!a%SHuPEoCRBKlR!a%DI!)?7E0u#qR!a%SHuQ!:I&D at 2VhBGqKRB\NI&DXFVhBGQD.eZ.:3U5V
+H!=6n>?#fW@#.u]G at Y*,>?$r2C]FG7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG[\grmpdW/QJAML;@]L8^&c
+W/QJAML;@]L:<.rW/QJ?NJ4j$KrC5t[uH*?N/"j+Ml;Sh[uH*?N/"g$KrBrb\<Di;KRo"j=Ee:`
+MITb4A71:)=TAF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq;C>si8j(SgtoN9TXTo7W/QJAML;@]L:N"_W/QJAML;@]L:N1hW/QJ/KRC7gKrBrb
+[uH*OPDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mmn\"
+\<Di[NJ4m+Mn+^m[uH*NNJ3aIFa71jH!=6n>?'4m^&S-4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2g"bH4eCN9rbKJ,S
+`5T^=bg")F`QQKM`5T^=bg!Z"WjdtA[uH*?N/"g$KrBrb[uH*?N/"j+Mmn\"\<Di\PDco0Kt*>)
+\<Di\PDco0Kt!%q[uH*NNJ4j$Kt!%q[uH*NNJ4j$KrBrb[uH*?N/"g$Kt!%qW/QJ?NJ4j$KrBrb
+[uH*OPDcAuL:<.rW/QJ?NJ4<iL8^&c\V5:LXJPsss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjkbg")F`Pfa7]=bhs]Xk_f]t:qj
+`5T^-]Y1qi]st2ELM^[jFDJFUPe!6I\XJc'R>nbGPe!6I\XJbnRZt at OPdlp8\<Di\PDcr7Mn"t/
+\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/[uH*OPDcr7Ml;Sh
+\<Di\PDcAuL:EG*\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/a-hptRZt at OPfK2O\XJbnRZtj\NQ7HH
+\XJc'R>nbGPfK2O\XJbnRZuFB^&S-4s8W,coC_>6n)39idaZjkbg")F`O*"Z['[3I['[3I['[3I
+['[3 at XKA:pUj60DH!=6lA713s:3g&CH!=7GKRC:nMn,:@\<Di]RZt at OPe!6I\XJc'R>nbGPfK2O
+\XJbnRZtj\NObLBa-hptRZtj\NObLBa-hptRZt=GMoV6F\XJc'R>n_?Mo_*8\<Di\PDcr7Mo_*8
+f>PB&s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(Sgtp5uc, at T?
+]=bhXXKAP)XdkuQUnsl_V50o`Uka&2BMV35:J#_-8n_!lG#CqG:J#_-8p4*)G#CqU;G)gV=Lj<:
+VhBGqKRB\NI&DXFVhBGqKRB\FE2S)&R!a%SHuPF*JZ!m7VhBGqKRB\NI&DXFVhBGqKRB\NI*9aY
+i8j(SgtpK/f#5PH]=bha['Zm8Xe_ehS=Z7 at St)=BS>_mAG at Y*);G(Uu8U4N>BMV3C;G)+18p4*)
+G#CqU;G)4=<-D/3G#CqfD.ff+L8^&cW/QJ?NJ4<iL:<.rW/QJ0N/"g$Kr9TOW/QJ/KRB\NI&DXF
+VhBGqHuQ!:I&DXFVgNH]KRDq;h#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVkj7crjQDnXFbagHLM^[ZD.f5Q at Y\f5Qu-;fFE!RgCR9-YQZR#0FDI4bCR9-Y
+QZR#0FDI4bCR9-YQZR#0FDI4bCR9-YH!=6n>?#cD8p4*)H!=6k;G)4=<-D/3BMV3F>?#938Tn!(
+BMV3C;G*mPOT5@\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*k+gmEJ3LM^[jFDHYRE0kZ^QZR#0FDI4bCR9-YQZR#1I!(g(Ff0V+
+R!a%DI!)?7E0u#qR!a%DI!)?7E0u#qVgNHNI!(ctCO',`H!=6n>?#lP<-_\IH!=6n>?#lP<-_\I
+H!=7XXfD-^kNM:$kj7d%m-j0)n)iE\g"bH(]XjJXFdI2cQZR#1I!(ctCRBKlQZR#0FDI4bCR9-Y
+QZR#0FDI4bCRBKlR!a%DI!)?7E0u#qVhBGqKRB\NI$f;(H!=6lA70[e</P0fH!=6lA70[e<-Mk\
+G at Y+$]Xn.Cs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bGnUnFZFL8^&cVhBGqKRB_WL8^&c[uH*?N/"g$KrBrb
+[uH*?N/"g$KrBrb[uH*?N/"g$KrBrb\<DiLN/"g$KpQmsG at Y*=@p!qc@#.u]Q]-h%s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhT2dp
+VhBGqKRB_WL8T]PW/QJ0N/"9iL8^&cVhBGrN/"m#I&N!YW/QJ?NJ4<iL8^&c\<DiLN/"j+Ml;l%
+\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/\<Di\PDcr7Mn"t/[uH*OPDcAuL:<.r[uH*?N/"g$KrBrb
+\V59`D.e,u<-_\IG at Y+Um-"EKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+=jQGI^kLnYIdaZk#bfe2Rc, at T?`5T^6`Pod7`QQKM
+`k8m]P`Vi&L8^&c[uH*?P`WA6KrC5t[uH*?P`WD=Mmn\"W0ECQNJ4m+Mmn\"\<Di[NJ4j$Kt!%q
+W/QJ?NJ4<iL8^&c[uH*OPDco0Kt!%qW/QJ0N/"g$KrBrbW/QJ?NJ4<iL8^&c[uH*?N/"g$KrBrb
+VhBGrN/"6`I.[..s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQFt at f#u:^bKS5L`Pod7`Pfa7]=bhq`PoI%]uI^r]=bhh]Y1hWWcr;q
+VgNHoRZt at OPe!6I\XJbnRZt at OPe!6I\<Di]RZt=GMn"t/\<Di\PDcB(OLUL4\<Di\PDcr7Mn"t/
+\<Di\PDcr7Mmn\"[uH*?N/"g$Kt*>)W/QJ at PDcAuL:EG*W/QJ at PDcr7Ml;l%\<Di\PDcr7Mn"t/
+\<Di\PDcr7Mn"t/\<Di\PDcr7Mn,:@\<Di]RZt at OPe!6I\XJbnRZt at OPe!6Ia-hptRZt at OPi]j#
+s8W-!s8W-!s7H$\kj7crjQG4OhTO-f`5T^-]Y1\Z['[3I['[3I['[3I['[3I['[2qD.e,u<-_\I
+H!=6n>?#fW@$btN\<Di\PDcr7Mn,:@\<Di]RZt=GMn,:@a-hptRZt at OPfK2O\XJbnRZt at OPfK2O
+\<Di]RZt=GMoV6F\XJc'R>n_?MoV6F\<Di]RZt=GMn,:@aJ>C!pA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!kj7bnD.eTNH`3Bu
+a0i2#eCO9cq>^Kps8W-!s8W-!s8W-!m.9o6m-ilnkL.l2daZjd`PoI%]sP/RUnsl_V50o`Unji_
+UnslBFDuD$8n_!lBMV35:J#4q8Tn!(BMV35:J#4q8SCmkMITbdKRB\NI&DXFVhBGqKRB\NI$f;(
+VgNHNI!)?7E2S)&R!a%SKRB\NI$f;(VhBGqKRB\NI&DXFVhBH at bg#),kLnYIdaZjkbg!c4]sP/R
+X/rFnSt)=BS=H1 at S=Z7 at St("8?t`>-BMV35:J#h9<+o'!BMV3F>?#938SCmkG#CqF>Zu;K8r at +\
+W/QJ0N/"6`I&N!YW/QJ/KRC7gKr9TOW/QJ/KRC7gKr9TOVhBGqKRB\NI&DXFVhBGqKRB\NI&DXF
+k1nbls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2
+\XJbMD.89;B:*OFLM^[ZD.f2WCPQb>QZR"uD.f2WCPQb>QZR"uFE!RgCPR"NQu-;fFE!Ua at Y]&E
+QZR"uFE!+I=D1K%H!=6]:J#4q8SCmkBMV35:J#h9<+o'!BMV3F>?#938SCmkH!=8$gtr)2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+\?2cdD.eW at B8:>:QZR"uFE!"WE//OSQZR#1I!(g(FdRQ!R!a%DI!(g(Ff0n?R!a%CFDI7kFdRQ!
+R!a%DI!(g(FdRQ!QZR"g>?#lP<-_\IH!=6k;G)4=<-_\IH!=6]:J#h9<4K'1m.9o:oC_kEkNqg5
+kj7crjQG4OhU9p)VhBGaFDI4bCR9-YQZR#0FDI4bCR9-YQZR"uD.f2WCR9-YQZR#1I!(ctCRBKl
+R!a%DI!)??I$]M;VhBGqKRAPlB8U2$G at Y*,>?#fW@!PsUG at Y*;>#'?I<-N1po_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+kj7d#gt^)sc)?SUW/QJ/KRB_WL8^&cW/QJ0N/"9iL8^>uW/QJ0P`Vi&L8^&cW/QJ0N/"9iL:EG*
+W/QJ0N/"9iL:<.rW/QIg at p""\<-Mk\H!=6lA74'6bQ%VBs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkMYFa`k8m\KRB\NI&DXFW/QJ/KRB_WL8T]P
+VhBGrN/"6`I&N!YVhBGrN/"6`I&N!YW/QJ?NJ4<iL8^>u[uH*?P`WD=Ml;l%W0ECBP`Vi.OLUL4
+W0ECBN/"9qOLL4'W0ECBN/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cMITb6>?#lP</5R7
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gi8j(SgtpK/f#u:^bKS5Sbg")F`QQKM`5T^6`Pp$Ec*sLA\<DiLN/"9qOJn+m
+W/QJ?NJ4<iL8^&cW/QJ0N/"g$KrBrbW/QJ0N/"9iL8^&cW/QJ?NJ4<iL:<.rW/QJ at PDcr7Ml;l%
+\<DiLP`WA6KrBrb\<DiLN/"9iL8^&cW/QJ?NJ4<iL8^&cW/QJ0N/"9iL8T]PaJ>C,s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oo
+k1nb?eCMgec, at T?`5T^6`PoI%]uI^r]=bhh]Y28&`Oidr]=bhQV5/l`B;^E1\XJbnRZt at OPe!6I
+\XJbmPDcB.Q+3$9W0ECBP`Vi.OLUL4W0ECRPDcB(OJn+mW0ECQNJ4<qOJn+mW0ECBN/"9iL:<.r
+W/QJ0N/"9iL:<.rW0ECRPDcB(OLUL4W0ECRPDcB(OLUL4W1'!]PDcB.Q+3$9\<DiLP`WD=Ml;l%
+\<DiLP`WD=Mn"t/\XJbnRZt at OPe!6I\XJbnRZt=GMn,:@f>PB&s8W-!s8W-!s8W,kpA+(Hp#+oo
+daZjreCMRW`Oidr['[3I['[3I['[3IX/rG1['[3I[$Q`/H!=6lA70[e<-Mk\H!=7*@p#[oOL^gE
+\XJbnRZt=GMn,:@\XJbnRZt at OPe!6I\XJbnRZt=GMoV6F\XJbnRZtj\NObLBa-hptRZt at OPe!6I
+\XJbmPDcu?Pdlp8a-hqOe^sj$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,]gt[*a@!PsUBMV3F>?#6?>'<e9H!=6n>?$u;Ff:ao
+['[4(m-jT?q<[_Gi8j(Sgtp5uc, at T?]=bhXXKAP)Xe_ehUnsl_V50o`Uka&2BMV35:J#4q8SCmk
+BMV35:J#4q8SCmkG#CqG:J$FR=Jph"VhBGbI!)?7E0u#qVgNHNI!)?7E0u#qVhBGbI!)?7E0u#q
+VhBGqKRB\NI$f;(VhBGqKRB\NI*9aYi8j(SgtpK/f#5PH]=bha['Zm8XdkuQS=Z7 at St)=BS=H1@
+G at Y)p:J#_-8n_!lBMV35:J#4q8SCmkBMV3F>?#938Tn!(BMV3TD.ff+L8T]PVhBGqKRB_WL8T]P
+W/QJ/KRB\NI&DXFW/QJ/KRB\NI&DXFR!a%SKRB\NI&DXFVhBGbI!+,thZ*WUs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-hm3`J8PSLM^[ZD.eW at B8:>:
+QZR"uFE!"WE0tKOLM^[ZD.eWGE//:CQu-;fD.eW at B8:>:LM^[kD.89;B8:>:LM^[L>?#938SCmk
+H!=6]:J#h9<+o'!BMV3F>?#938SCmkB3\VR:J#4q8V_D,o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+=jQDkOCPQb>Qu-;fD.eW at B8:>:
+QZR#0FDHYRE0u#qR!a%DI!(g(FdRQ!R!a%DI!(g(FdRQ!R!a%DI!(ctCRBKlR!a%DI!(3dE->,O
+H!=6n>?#cD8nVC4H!=6]:J#2(>'X=OBMV4,[']2kp$D;Cm.9oBpA*q=n)39ig"bH4eCM+)TSIAs
+LNIL%FDHYKB:!^ULM^[jFDHYKB8:SJLNIL%FDHYRE0kZ^R!a%DI!(g(FdRQ!R!a%CKRp%SI&DXF
+R!a%#A70Ul@!PsUH!=6lA70[e<-Mk\G at Y*,>?$rBJcGcMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYI\XJb]N/"6`I&DXF
+W/QJ/KRB_WL8^&cW/QJ?NJ4<iL8^&cW/QJ?NJ4<iL:EG*W/QJ0N/"9iL:N1hW/QJ0N/!^IFa%A(
+MITb4A71:)=GM!;s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n*'-,i8j(>`Pnd7L8T]PQ\9pfKRB\NI&N!YVhBGqKRB\NI&DXFVhBGaKRp%SI&N!Y
+VhBGrN/"9iL8^&cW/QJ0N/"9iL8^>uW0ECBP`WD=Ml;l%\<DiLP`WD=Ml;l%[uH*?P`Vi&L8^&c
+W/QJ0N/"6`I&DXFVhBGqKRB_WL8^&cW/QJ0N/![PJU(I!H!=6lA71a_MZ<_Vs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n(HLQ
+g"bH4eCMgec-+>U`5T^6`Pod7`QQKM`5T^8]Xk&+OJnD*W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW0ECBP`WD=Ml;l%W0ECRPDcB(OLUL4W0ECRPDcB(OJn+m
+W/QJ at PDcAuL8^&cW/QJ0N/"9iL8^&cVhBGrN/%)nkPtS^s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjkbg")F`Pfa7
+`5T^-]Y28&`Oidr]=bhq`PoI%]uI^rW1&uqD/6)/L:Nb;\XJb]P`WGEPc0h.\<DiLP`Vi.OLUL4
+W/QJ0N/"9iL8^&cW0ECQNJ4<iL8^&cW0ECQNJ4<iL:<.rW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+\<DiLN/"9qOLUL4W0ECBP`Vi.OLUL4W0ECRPDcB(OLUL4W0ECBN/"9iL:EG*W0ECRPDcB(OLUL4
+\XJbmPDcu?Pe!6I\<Dj8e^sj$s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hTO-fbKS5C]Y1qi]sP/R
+X/rG1['[3I['[3I['[39V5/B@<-_\IH!=6n>?#lP<-_\IW/QJ at PDcu?Pe!6I\XJbnRZt at OPe!6I
+\XJbnRZtj\NObLB\XJbnRZt at OPdlp8\XJbmPDcu?Pe!6I\<DikR>nbGPdlp8\XJc(XJPsss8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8U$V`FiFZBMV35:J#4q8SCmkBMV3F>?#938S;:3B3\V`;G)^dE5oQ%m.9o6m-ilnkLnYI
+daZjd`PoI%]sP/RUnsl_V50o`Unji_UnslBFDtnh8QA2FBMV3I3]q(O8SCmkBMV35:J#4q8SCmk
+G at Y*JKRp%SI$f;(VhBGqKRB/7Ff0n?R!a%CKRp%KE0u#qR!a%SKRB/7Ff0n?Q\9pfKRB\NI$]M;
+VhBH at bg#),kLnYIdaZjd`PoI%]sP/RX/rFnSt)=BS=H1 at S=Z7 at St("8?t`>-BMV35:J#4q8SCmk
+BMV35:J#4q8SCmkBMV35:J#4q8W%"[VhBGaKRp%SI&DXFVhBGqKRB\NI&DXFW/QJ/KRB\NI&DXF
+Q\9pfKRB,>JZ"0KQ\9pfKRB,>JZ"0Kk1nbls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726i8j'gI!(3]B8:>:LM^[ZD.eW at B8:>:LM^[ZD.eWGE0tKO
+LM^[ZD.eW at B8U2$LM^[ZD.eW at B8:>:LNIL%FDHYKB8:>:BMV34>Ztf:8SCmkB3\VR:J#4q8SCmk
+BMV35:J#4q8SCmkBMV35:J$t<PQ1[_s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8VHWor+=ELNIKjD.eW at B8:>:LM^[jFDHYRE//OSQZR"uFE!RgCPR"N
+QZR"uFE!RgCPR"NQZR#0FDHYRE0u#qQZR#1I!(ctCRBKlLM^[I;G(S,>%g]'B3\V`;G(Uu8S;:3
+BMV35:J#4q8[Pk3o_/+QpA+ at Sq<[_Gm.9o6m-ilnkLnYI`5T]^FDHYKB8:>:LM^[ZFE!RgCPQb>
+LNIL&D.89BE//OSQZR#1I!(ctCRBKlR!a%DI!(d/JX;%@VhBGaN/FNdI$f;(H!=6lA70Ul@!PsU
+G at Y*,>?#fW@!?-hG at Y*[R[*pQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726i8j(A[BZ'WMPl,TQ]-g"KRB_WL8^&cW/QJ0N/"9iL8^&c
+W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cQZR"eA70[e<-Mk\G at Y*kXfDF$s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7d#gt^?-eu4gp
+VhBGaKRoJCJZ"0KQ\9pVKRoJCJZ"0KQ]-fgKRp%SI$]M;Q\9pVKRoJCJZ"0KQ]-g"KRB_WL8^&c
+W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"6`I$]eLW/QItKRp(\L8^&c
+W/QJ0N/"9qOJn+mW0EC2I!'XD@!PsUH!=7XXfDF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)fZ_O^bg")F`RrDX
+`5T^6`Pp$Ec, at T?\"o[qP`Vi&L8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+W/QJ at PDcAuL:<.rW0ECBN/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8T]P
+W/QJ/KRB_WL:Nb;s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7ckgtp`>hU9p)bKS5L`Pod7`Oidr`5T^-]Y28&`Oidr
+]=bhh]Y1qi]qhL#G at Y*[N/"9qOJnD*W0ECBP`Vi.OJn+mW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^>uW/QJ0P`Vi.OJnD*\<DiLN/"9qOLUL4
+W0ECBP`WGEPc0h.\<DiLP`WD=Ml<)0\<DiLP`WD=Ml<)0\XJbnRZsb8OL^gE\XJbnRZuakkPtS^
+s8W-!s8W-!s8W-!s8W-!s8VHWp#+ooi8j(LeCMgec, at T?]=bha['[3I['[3IX/rG1['[3I[(*6<
+LNIKZA70[e<-_\IG at Y*,>?$B"E4D*i\<Di]RZt at OPe!6I\XJbmPDcu?Pdlp8\XJbnRZt=GMn,:@
+\XJbnRZt at OPe!6I\XJbnRZt at OPdlp8\XJbnRZusih#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+IoC_JAp%7tRo_/+\s8V`bq4+%HBMV35:J#4q8SCmk
+BMV35:J#4q8SCmkBMV35:J#4q8V_D,W/QJ0P`XhakNqg5i8j(Sgtp5uc, at T?]=bhXXKAP)Xe_eh
+Unsl_V50o`Uj$p&BMV3"76tT_8Q\YWBMV3"76tT_8SCmkBMV35:J$@G:7$WbVgNHMKRoJCJXCh-
+VhBGaKRp%KE0l6/VhBGaKRp%SI$]M;VhBGaKRp%SI&DXFQ]-g"KRB_WL<Ifci8j(SgtpK/f#5PH
+]=bha['ZX*Unji_S=Z7 at St)aJQ(4G9G at Y)p:J#4q8SCmkBMV35:J#4q8SCmkBMV35:J#4q8SCmk
+BMV3DA72<gI$f;(Q\9pVKRoJCJX;%@VhBGaKRp%SI$]M;VhBGaKRp%SI$]M;Q\9pVKRp%SI$]M;
+VhBGaN/HcQh#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-j0)n$f*cLM^[ZD.e`9=GLa+LM^[ZD.eW at B8:>:LM^[ZD.eW at B8:>:LM^[JD/5#==GLa+
+LM^[ZD.eW at B8:>:LM^[ZD.e''?t`>-BMV35:J#4q8SCmkBMV35:J#4q8SCmkBMV35:J"Y^88(dj
+BMV3uR[*pQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+fZ_NoD.eW at B8:>:LM^[ZD.eW at B8:>:LM^[ZFE!RgCPR"NLNIL&I!(3dE0kZ^L4"?7FDHVYH^Ahi
+L4"?7FDHVYH\Z]^LNIL%FDHYKB4kIQBMV35:J#4q8S;:3BMV35:J#4q8SCmkBMV40XfD$eq=OCV
+o_/+QpA+ at Sq<726i8j(SgtpK/esV_cQu-;fD.eW at B8:>:LM^[ZD.eW at B8:>:LM^[jFDHYRE//OS
+R!a%2I!_6.FdIc4R!a%CKRoJCJZ"0KQ\9pVKRnnqB6d]\G at Y**A70Ul@!?-hG at Y)o>ZuDW<-Mk\
+Q]-h%s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7crjQF_1c'OBHVhBGaKRoJCJZ+N^Q]-g"KRB,FMPuJgW/QJ0P`Vi&L8^&cW0ECBN/"9iL8^&c
+W/QJ0N/"9iL8^&cW/QJ/KR at uS@!?-hG at Y**A70Ul@/p9,s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!kj7d%m-ilnkLnYIW1'!<KRoJCJX;%@Q\9pVKRoJCJZ"0K
+Q\9pVKRoJCJX;%@Q\9pVKRoJCJZ"0KQ\9pVKRp%SI$]M;Q]-g#N/![XMO8d6G at Y*[N/"9iL8^>u
+W/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ/KRB,>JZ+N^Q\9pgN/"9iL8^&cW/QJ0N/"9iL8^>u
+LNIKZA70%T>'X=Og"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726i8j(LeCN'tf#u:^bKS5L`Pp$Ec, at T?`5T^6`Poj0\u:jT
+W/QJ0N/"9iL8^&cVhBGaN/FNdI&N!YW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cW/QJ0P`Vi&L8^&c
+W0ECBP`Vi&L8^>uW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&cQ]-g#N/![PJZ+N^Q\9qRm-juSs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+ at Sq;C>sg"bH4eCMgec-+>U`5T^6`Pod7`Oidr]=bhs]Xk_f]u7n/]=bhs]Xjo8Uk`f"
+Q]-g3PDcAuL8^>uW/QJ0N/"9qOJn+mW/QJ0N/"9iL6mjVW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+W/QJ0N/"9iL8^>uW/QJ0N/"9iL8^&cW/QJ0P`Vi.OJnD*W0ECBP`Vi4Q+3$9W0ECBP`Vi4Q+<?J
+W1'!]PDcB.Q+<?JW1'!^RZt at OPc1%9\XJbnRZt:WT`>&ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_&&kLnYIbKS5L`PoI%]sP/R['[3I['[3I['[3I['[3 at XK@nSPBgA3G at Y)o>ZuDW<-_\I
+G at Y*[P`WGEPdlp8\XJbmPDcu?Pe!6I\XJbnRZt=GMn,:@\XJbnRZt at OPdlp8\<Di]RZt=GMn"t/
+\XJbmPDdJhZ2ak(s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o:oC_>6n*'-,kj7d%m-j<4p#+ooL4">J76spB5ug?><CK2U9Lr8Z86APVBMV3%9Lrhm8SCmk
+QZR#AN/![PJZ"0K]=bi at m-ilnkL.l2daZjd`Po3k['[3IUnsl_V50o`Unji_UnslBFDt5K6"j%c
+<CK2e:J"Y^8:3H\BMV3"76spB6"j%cH!=7GHuPF*JXCh-VhBGbI!(d/JZ"0KQ\9pWI!(d/JXCh-
+Q\9pfKRB,>JX;%@VhBGaKRp(\L8^&cQ]-gFbg#),kLnYIdaZjd`PoI%]sP/RX/rFnSt)44PFS57
+S=Z7 at St'Fu>#e!W<CK2R76spB5ug?>BMV35:J#4q8SCmkBMV35:J#4q8W%"[Q\9pWI!(g(FdRQ!
+VgNHMKRp%SI$]eLVhBGaKRoJCJX;%@Q\9pWI!)??I$]M;Q\9pVKRoJCJZ"0Kg"bHas8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7c]bfto[B8:>:
+GAV,Q at p"M'B8:>:LM^[ZD.eW at B8:>:G at Y*=@p!qlCNj;sGAV,Q at p!qlCPQb>LM^[ZD.eWGE//:C
+LM^[;:J#4q8SCmkBMV35:J"Y^88(dj=A28!:J"Y^88(djBMV3%9Lr8Z88(djL4"@3m-juSs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,Pgtmg.E//:CLM^[ZD.eW at B6S3.
+LM^[ZD.eW at B8:>:LNIKjFE!"WE//OSLNIL%FDHYRE/&aeLNIKjFE!RgCPR"NLNIKjFE!RgCPI4`
+LM^[;:J#4q8SCmkBMV35:J#4q8SCmkBMV3%9Lrhm8[Pk3o_/+\s8V`bq=OCVo_/+Em-ilnkN:RT
+daZjT['YU*B8:SJLM^[ZD.eW at B8:>:LM^[ZD.eW at B8:SJLNIL%FDHVYH^AhiL4"?8I!(d/JX;%@
+VhBGaKRoJCJZ+N^Q\9p6D/4?+@!PsUB3\Vc>?#fW@!PsUB3\VaA70[e</5R7daZkJs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kLe#%W/QItKRoJCJX;%@
+Q\9pVKRoJCJX;%@W/QItN/FQmL8^&cW/QJ0P`Vi&L8^&cW0ECBN/"9iL8^&cW0ECBN/"9iL5()&
+G at Y*,>?#fW@!PsUUnsmes8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n)39ik1nb%Xf at _@JXCh-Q\9pWI!(d/JX;%@Q\9pVKRoJCJXCh-Q\9pWI!(d/JX;%@
+R!a%CKRoJCJX;%@Q]-g"KRB,>JZ+N^Q\9p6A70%T>*k2*W/QItN/FQmL6mjVQ]-g#N/![XMO09Z
+W/QItN/Es\MPuJgQ]-g"KRB,FMPuJgQ]-g#N/"9iL8^>uW0ECBN/"9iL3IKMH!=6\>Zu>^@/p9,
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkLnYIdaZjkbg")F`QQKM`5T^6`Pp$Ec, at T?`5T]oR['h1L6mjVVhBGaN/EsTJZ+N^
+Q\9pgN/![XMPl,TQ]-fgKRp(\L6mjVW/QItN/FQmL8^&cW/QJ0N/"9iL8^&cW/QJ0N/"9iL8^&c
+Q]-g#N/![PJX;=QVhBGaN/FNdI$]M;Q]-fgKRp(dOT5@\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n(HLQ
+daZjreCMgec, at T?`5T^-]Y28&`Oidr]=bhs]Xk_f]t:qj]=bhQV5/lgE0l6/W0ECBN/"9iL8^&c
+W/QItN/Es\MPuJgQ\9pfKRB,FMO0!IQ]-g#N/![XMPuJgQ]-g#N/![XMPuJgQ]-g#N/"9iL8^&c
+W0ECBN/"9qOLUL4W0ECRPDcB(OJnD*\<DiLP`Vi4Q+<?JW0ECBP`Vi4Q+<?JW1'!^RZsb>Q+<?J
+W1'!^RZsb>Q,LY\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(SgtpK/f#5PH
+]=bhh]Y1\Z['[3I['[3 at XKAk:['[3IX/rFIA70%T>'X=OB3\VaA70[e<2bb1W1'!^RZsb>Q+<?J
+\XJb]P`WGEPe!6IW0ECSRZt=GMn,:@W0ECSRZt at OPc1%9\XJb]R[(FPPe!6IfZ_P=s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kMYFai8j(SgtpuMkMYFa
+['[2Q>Zt,r5ug?><CK2R76spB5ug?><CK2R76spB5ug?>BMV3SI!_35JX;%@Q\9pVKRp(dOPo3_
+i8j(Sgtp5uc, at T?]=bha['ZX*Unji_Unsl_V50o`Uka&2BMV3%9Lr/P6"j%c<CK2U9Lrhm8QA2F
+BMV3"76u3'<0r8hR!a%CKRoM<FdIc4R!a%CKRoJCJX;%@Q\9pVKRoJCJX;%@VhBGaN/EsTJZ+N^
+Q\9pgN/![PJ^W'!i8j(LeCN'tf#5PH]=bha['ZX*Unji_S=Z7 at St)=BS=H1 at B3\V?76spB5ug?>
+BMV3"76spB5ug?><CK2R76spB6"j%c<CK2tA71dPFdRQ!R!a%CKRoM<FdRQ!Q\9pVKRoJCJX;%@
+Q\9pWI!(d/JXCh-Q\9pWI!(d/JZ"0KQ\9pVKRr:@h#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n)39iQ]-fGA7110B6RloGAV,>A70Ul@!?I'
+G at Y**D/4?+@!?I'MITb4A70Ul@!?I'G at Y**A70Ul@!?I'LM^[JA70Ul@#&T3B3\VB9Lrhm8Q\YW
+BMV3%9Lrhm8Q\YWBMV3%9Lr8Z86APVBMV3%9Lr8Z89\TP]=biWs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8Ud-hM-E)LM^[ZD.e'0CPQb>GAV,ND.eW at B6S3.LM^[ZFE!"PB8:SJ
+LNIKjFE!"WE//OSLNIL%FDHYRE//OSLNIKjFE!"PB8:>:LNIKjFDuG7?t`>-BMV35:J"Y^88(dj
+=A27f9Lr8Z86APV=A28m[']l5s8W-!s8W-!s8V`bq=OCVi8j(ZjQG4OhUp&qQ\9pFD.eW at B8:>:
+LM^[ZD.eW at B8:>:LM^[ZFE!"WE//OSLNIKjFDut^H^K2'R!a%DI!(g(FdIc4Q\9pVKRoJCJX;%@
+LM^[:>ZuDW<-Mk\B3\VaA70%T>'FLbB3\VQ>ZuDW<1/r6o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726`5T]^KRoJCJXCh-Q\9pWI!(d/JX;%@Q\9pfKRB,>JX;%@
+W/QItN/FQmL6mjVW/QItN/FQmL8^&cR?Ni5N/"9iL7+6hW/QITA70Ul@!?-hG at Y**A75''q>^Kp
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp&`\sJ)$
+Q\9pVKRoJCJX;%@Q\9pVKRoJCJX;%@L4"?8I!(0kH^K2'L4"?8I!(d/JXCh-Q\9pVKRp%SI$]eL
+Q]-g#N.uOnCN`TJL4"?d`PndEQ'[/TQ]-fgKRp(\L6mjVW/QItN/FQmL6mjVW/QItN/FQmL6mjV
+W/QItKRoJKMO09ZW/QJ!PEVr(L8^>uW/QItN/Dgi?t`>-B3\VpI!bnns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<kj7ckgtpK/f$`(!
+fZ_OW`Pp$Ec, at T?`5T^6`Pod7`OidrQ\9pgN/![PJX;%@W/QItKRp(\L6mjVW/QItKRp(\L6mRE
+VhBGaKRoJKMPl,TQ]-fgKRoJKMO09ZQ]-fgN/FQmL6mjVW/QItKRoJKMO0!IQ\9pfKRB,FMO0!I
+Q]-fgN/FNdI$]eLl.+Dcs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5Sbg")F`Pfa7
+`5T^-]Y28&`Oidr]=bhq`PoI%]uI^r\?2cTD/5JkJZ+fpW0ECBN/![XMPuJgQ]-g"KRB,>JX;%@
+Q\9pfKRB,>JX;%@Q\9pgN/![XMPuJgQ]-g#N/"9iL6mjVW/QItN/FQmL8^>uW/QJ0P`Vi.OJnV5
+\XJb]R['h?Q+<?JW1'!MP`Vi.OJnV5\<DiLR[(FPPc0h.\XJb]R[(FPPc1%9f>PB&s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQdaZjd`Pod7`Oidr['[3I['[3I['[3I
+['[3 at XKAk:["sBgH!=6\>Zu>^@!PsUB3\VqD.ff3OJnD*\XJb]R['h9OL^gEW0ECBR[(FPPe!6I
+W1'!MP`WGEPc1%9\XJb]P`WGEPe!6IW0ECBR[(FPPigcVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,coC_JAp#+ooi8j(SgtpK/f$`(!bKS4iMi:Y)5ug?><CK2R76spB5ug?>
+<CK2R76spB5ug?><CK2e:J$=`E0u#qR!a%DI!(d/JXCh-LkLH"`PpcrkLnYIdaZjd`PoI%]sP/R
+Unsl_V50o`Unji_UnslBFDt5K6"j%c<CK2e:J"Y^88(dj<CK2e:J"PT6!-fOH!=78I!(d/JX;%@
+R!a%CKRoM<FdIc4R!a%DI!(d/JX;%@Q\9pVKRoJCJZ+N^Q\9pVN/Es\MPuJgQ]-gFbg#),kLnYI
+daZjd`PoI%]rS6:X/rFnSt)=BS=H1 at S=Z7 at St't%8l\;G<CK2R76spB5ug?><CK2R76spB5ug?>
+<CK2R76spB6$Z[6L4"?8I!(0kH^K2'R!a%CKRoM<FdRQ!R!a%CKRoM<FdIc4R!a%DI!(d/JX;%@
+R!a%CKRoJCJX;%@g"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7d%m-hs,\p&",G at Y**A70Ul@#AGrGAV,Q at p!qc@!?-hG at Y**A70Ul@!?-h
+G at Y*,>?#fW@!?-hG at Y**A70Ul@!?I'G at Y**A70Ul@!PsU=A28!:J"Y^88(dj=A27f9Lrhm8Q\YW
+BMV3"76t$L86&)E=A27c76spB6&0Q$bKS62s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s2;mq
+LNIKjD.e''@#&T3GAV,>A7110B6S3.LM^[ZD.e'7FGF^GLNIKjD.eWGE//OSLNIKjFDut^H\Z]^
+LNIKjFE!"WE//:CGB at q^D.eW at B8:SJG at Y)`9Lr8Z86APV=A27f9Lrhm8Q\YW=A28!:J"Y^8 at 5b2
+s8W-!s8W-!s8W-!o_/+IoC_>6n)39ig"bH4eCM.3Wcqu]LM^[JD/4oDB6S3.LM^[ZD.e'0CPQb>
+LNIKjFE!"WE//OSR!a%3FDut^H\d?.R!a%4KS5_?FdRQ!Q\9pVKRoJKMO8d6G at Y)o>ZuDW<+fH>
+H!=6\>Zu>^@!?-hB3\VaA70%T>+D1Sp[%)Cs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCV
+i8j(1UnF'-JX;%@L4"?7KRoJCJX;%@Q\9pWI!(d7MO0!IQ]-g#N/![XMPuJgQ]-g#N/"9qOI(o`
+W/QItN/FQmL7+6hQ]-g#N/!+0E-Gi#G at Y)o>Zu>^@&TNZs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7d%m-ilnkKD)oQ]-fgKRoJCJX;%@Q\9pVKRoJCJX;%@
+Q\9pWI!(0kH^K2'L4"?8I!(0kH^BD:Q\9pGKS5_?FdIc4Q\9pVKRp%SI"uf_BMV34>[#(b`RrDX
+`k8m]N/![XMO0!IQ]-fgKRp(\L6mjVQ]-g#N/![XMPuJgQ]-fgN/FQmL6mjVW/QJ0N/![XMPuJg
+W0EC3PEVr(L6mjVQ\9p&>Ztf:8SCmkR?Nj7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH4eCMgec-+>U`5T^=bg")F`Pfa7
+f>PA@`Pnd?OI(WOQ\9pVKRoJCJX;%@Q]-g"KRB,FMO09ZQ\9pVKRoJKMPl,TQ\9pVN/EsTJX;%@
+Q\9pVKRp%SI$]eLQ]-g#N/![XMO0!IQ\9pVKRoJCJX;%@Q\9pVKRp%SI$]M;Q\9pgP`YqFs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp`>hTO-fbKS5L`Pod7`Oidr]=bhq`PoI%]t:qj
+]=bhh]Y1\ZZtN6,BMV3TFE!S*MO09ZVhBGaN/EsTJX;%@Q]-fgKRoJCJX;%@Q\9pfKRB,FMO09Z
+W/QItN/FQmL6mjVW/QItN/FQmL8^>uW0EC3PEVr0OJnD*W0ECBP`Vi4Q)Kq/W1'!MP`Vi4Q+<?J
+W1'!MR['h?Q)L.:W1'!^RZsb>Q)L.:W1'!MR['h9OQP?Rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7crjQG4OhTO-f`5T^-]Y1\Z['[3IX/rG1['[3I['[3I['[39V5.a/>%_)D
+BMV34>ZuDW<+fH>W/QJ0P`Vi.OJnD*W0ECBP`WGEPc0h.W1'!MP`WGEPc1%9W0ECBR['h9OJnV5
+\XJb]R['h9OL^gEW0ECBR[)glkPtS^s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_JAp#tc2
+i8j(SgtpK/f$`(!bKS53XK>uCAQ;/b<CK2R76spB5ug?><CK2R76spB5ug?><CK2R76u-.@$l=a
+L4"?&I!_6.FbY9jR!a%DI!(d/JXM^ci8j(Sgtp5uc, at T?]=bha['ZX*Unji_Unsl_V50o`Uj$p&
+=A27c76tT_8QA2FBMV3"76tT_8QA2FBMV35:J#2(>*jnnR!a%DI!(d/JVJQ!Q\9pWI!(6uKU7 at C
+R!a%CKRoJCJX;%@Q\9pVKRoJCJX;%@Q]-fgKRoJKMTa5gi8j(Sgtp5uc, at T?]=bha['ZX*Un"$H
+S=Z7 at St)=BS=,S)B3\V?76spB5ug?><CK2R76spB5ug?><CK2R76spB5ug?><CK2s;G)^dE0u#q
+LNIL&I!(0kH\Z]^L4"?8I!(0kH^K2'R!a%2I!^TqH\QopR!a%4KS5_?FdIc4R!a%CN/HcQh#IES
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2
+k1naHI!^'J@!?-hG at Y**A70Ul?tW_JG at Y*,>?#fW@!?-hG at Y*,>?#fW@!?-hG at Y**A70Ul@!?-h
+G at Y**A70Ul@!?-hG at Y**A70Ul?t`>-=A27f9Lr8Z86APV=A27c76spB6!-fO<CK2R76spB6!-fO
+<CK2R76spB6$IEm]=biWs8W-!s8W-!s8W-!s8W-!s5;u$W1&uqA7110B6S3.GAV,>A7110B6S3.
+G at Y**D/4?4CPQb>GAV,ND.e'0CPR"NLM^[ZFE!"WE//OSLNIKjFE!"WE//OSLNIKjFE!"WE-HDG
+LNIKZD/4?+?t`>-=A27f9Lrhm8Q\YW=A27f9Lr8Z86APV=A28m[']l5s8W-!s8W-!s8W-!s7H$\
+kj7crjQGI^kL.l2bKS4cI!^WcB6RloLM^[ZD.e'0CPQb>LM^[JD/4oKE//:CLNIKjD.eWGE/&ae
+LNIKiI!_6.FbY9jL4"?(KS5\FJX;%@Q\9pGKS5_?Fbb'XB3\VaA70%T>'FLbB3\VQ>ZtcF>%_)D
+H!=6\>ZtcF>*k2*`5T^qs8W-!s8W-!s8W-!s8W-!s7H$\m.9ni]XjGgMMQq=R!a%4KS5\FJVJQ!
+Q\9pEI!_35JX;%@Q\9pVKRoJCJX;=QQ]-fgN/FQmL6mjVQ]-g#N/![XMOBZlW/QItN/FQmL6mjV
+G at Y)o>Zu>^?tW_JG at Y+RpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,_m-j0)n)iE\daZjHP`V5jMO0!IQ\9pVKRoJCJX;=QQ\9pVKRoJKMO0!ILkLGKI!(6uKSFl$
+R!a%2I!_6.FdIc4Q\9pGKS5_?FdIc4L4">]:J"Mb<Of02bKS5Sbg")F`ON%MQ\9pgN/![PJZ+N^
+Q]-fgN/FQmL6mjVW/QJ!PEVr(L6mjVW/QItN/FQmL6mjVW/QJ!PEV>lMPuJgQ]-fgN/Es\MMH:m
+BMV3!<)mU-8\;XKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\o_/+=jQG4OhU9p)bKS5Sbg"eabJ_B=`5T^=bg")F`Pfa7\?2ctKRoJCJX;=Q
+Q\9pVKRoJCJX;=QQ\9pVKRp(\L6mREQ\9pVKRoJCJXCh-Q\9pVKRoM<FdIc4Q\9pVKRoJCJV\u4
+R!a%CKRoJCJXCh-LkLGKI!(d/JX;%@Q\9pVKRoJCJ_82is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA*q=n)iE\g"bH4eCMgec, at T?`5T^6`Pod7`Oidr`k8mp]Y28&`OidrS=Z6Q9Lrhm8Q\YW
+LNIL5KRB,FMO0!IW/QItN/FNdI$]M;R!a%CKRoJCJX;=QQ]-g#N/"9iL7+6hW/QJ!PEVr(L7+6h
+W/QJ!PEVr0OJnD*W1'!MR['h?Q)L.:W1'!MR['h?Q+<?JW1'!MR['h9OL^gEW1'!^RZsb>Q)L.:
+W1'!MR['h9OL^gEW1'!MR[*$jh#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#+oo
+g"bH-bg">Tc+CX%]=bha['[3I['[3I['[3 at XKAk:['[3IL4">]:J#2(>%_)DB3\VQ>Zuo)E2]"_
+W0ECBP`Vi.OJnV5W1'!MP`Vi4Q)Kq/W0ECBP`Vi.OJnD*\XJb]P`Vi4Q)Kq/W1'!MP`Vi.OJnD*
+W0ECleCO["s8W-!s8W-!s8W-!s8W-!s8W,coC_JAp$D;Ci8j(ZjQG4OhU9p)bKS53XK?5RDHKS'
+<CK2R76spB5ug?><CK2R76sC+4B4g9<CK2R76tT_8V_.qR!a%2I!_6.FbY9jL4"?&I!^TqH\Qop
+L4"?&I!`fN`S'&'daZjd`PoI%]sP/RUnsl_V50o`Unji_UnslBFDt5K6!-fO<CK2R76spB5ug?>
+<CK2e:J"PT6!-fOB3\W,KRoJCJVJQ!R!a%2I!_35JVJQ!R!a%2I!_6.Fbk^(R!a%4KS5\FJX;%@
+Q\9pVN/EsTJX;=QQ]-gFbg#),kLnYIdaZjd`PoI%]sP/RX/rFnSt)=BS=H1 at S=Z7LR[%Mj>#e!W
+<CK2R76spB5ug?>HoaAi76spB5ug?><CK2R76spB6"aG+L4"?'FE!"WE//OSL4"?'FE!"WE/&ae
+LNIKiI!^WjE/&aeR!a%2I!_6.FbY9jQ\9pVKRoJCJX;=Qg"bHas8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkI at XoG@Y**A70%T>'X=O
+B3\VaA70[e<+BHMG at Y)o>Zu>^?t3_YG at Y**A70Ul@!?-hG at Y**A70Ul@!?-hG at Y**A70Ul@!?-h
+G at Y**A70%T>$+Hh<CK2R76spB5ug?><CK2R76t$L86&)E<CK2R76spB6!-fO779RE76spB6"j%c
+R?NiXbg#MGp#tc2['[2qFDuG7@!?I'G at Y**D/4?+@!?I'G at Y**A70UuCNjW2LM^[JD/4oDB6SH>
+LNIKjFDuGGFGFsWGB at q^FE!"WE/&aeLNIKZFEE:[E-HDGLNIKjD.e'7FGFsWG at Y)`9Lr8Z86APV
+=A28!:J"Y^88(dj=A28!:J"Y^8 at uOJs8W-!s8W-!s8W-!s8W,kpA+ at Sq<726k1nbFgtpK/f!qi^
+LM^[JD/4oDB6S3.LM^[JD/4oDB6S3.LM^[JD/4oKE-HDGLM^[ZFE!"WE/&aeLNIKiI!_6.FdRQ!
+LkLGKI!(d/JX;%@Q\9pVKRnr4KSODWB3\Vc>?#6?>'X=OB3\VaA70%T>'X=OB3\VQ>ZtcF>'FLb
+LkLGkXfB=Y`S'&'daZjd`Pnd7L5:M9L4"?8I!(0kH^BD:L4"?7KRoJCJX;%@LkLGKI!(6uKU7 at C
+Q]-fgN/FQmL6mjVQ]-g#P`V5jMO09ZW/QItN/Es\MO09ZW/QIcI!^'J?tW_JG at Y)o>["MA[/^1+
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2i8j(Sgtnj'Uo96,
+Q]-fgN/EsTJX;=QQ\9pVKRoJKMO0!IQ\9pVKRoJCJV\u4R!a%2I!^TqH^BD:LkLGJKRoJCJX;%@
+LkLG9I!]L2>%g]'Q\9q<eCMgec-+>UbKS5Sbg!)TQ'[/TQ]-fgKRoJKMPuJgQ]-fgN/FQmL6mjV
+W0EC3PEV>lMPuc$R?Ni5N/!aaPF%5cW/QItN/Es\MO09ZQ\9pVKRn>aCM6L8=A27b<)r)9h#IES
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+i8j(SgtpK/f#u:^`5T^=bg")F`Pfa7bKS5L`Pod7`Ku7/Q\9pWI!(d/JX;=QQ\9pVKRoJCJX;%@
+Q\9pVKRoJCJV\u4L4"?8I!(0kH\QopL4"?8I!(6uKU at .0LkLGKI!(0kH\QopL4"?&I!_6.FbY9j
+L4"?&I!_35JV\u4Q\9qis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hV$]@
+daZjkbg")F`Pfa7]=bhh]Y1qi]t:qj`k8mp]Y0&IHWWs4=A27f9Lsq\E0lN at Q\9pgN/![XMO0!I
+Q\9pVKRoJCJX;%@Q]-g#N/![XMPuJgR?Ni5N/!aaPGjFpR?Ni5P`V;sPGj_-W0EC3PEVr0OJnV5
+W0ECBR['h?Q)L.:W1'!MR['h9OJnV5W1'!MR['h?Q)Kq/W1'!MP`Vi4Q)L.:W1'!MR['h?Q)Kq/
+W1'"0jQHRCs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkL.l2bKS5L`PoI%]sP/R
+['[3I['[3I['[3I['[3I['ZX*Uh<q9B3\VR:J#2(>%g]'B3\W=P`Vi.OJnD*W0ECBP`Vi4Q)L.:
+W1'!MP`Vi4Q)Kq/W0ECBR['h9OJnD*W0ECBR['h9OJnD*W0ECBP`Vi.OJnD*`k8nTpA+ags8W-!
+o_/+IoC_JAp#tc2i8j(ZjQG4OhU9p)['[3!Mi;:R>"(hJ=A27c76spB5ug?><CK2R76spB5ug?>
+<CK2R76spB6$Z[6L4"?&I!^TqH\QopLNIKiI!_6.FbY9jR!a%2I!_6.FbY9jUnsm?gtp5uc, at T?
+]=bha['ZX*Unji_Unsl_V50o`Uj$p&=A27f9Lr8Z86APV=A28!:J"PT5ug?><CK2e:J#2(>*s\[
+L4"?&I!_6.FbY9jL4"?8I!(0kH\d?.R!a%2I!^TqH^BD:LkLGJKRoJCJX;%@Q\9pVKRoJCJ]l9^
+i8j(LeCN'tf#5PH]=bha['ZX*Un"$HS=Z7 at St)=BS=H1 at B3\V04Zl_55t4""<CK2C4Zl_55ug?>
+<CK2R76spB5ug?><CK2s;G)[kH^K2'LNIKiI!^WjE//OSL4"?'FE!"WE/&aeLNIKjFDut^H\Qop
+Q\9pEI!_35JX;%@Q]-fgN/HcQh#IESs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7ckgtm6sFE_8'B3\VaA70%T>'FLbB3\VQ>Zu>^?tW_J
+G at Y**A70Ul@!?-hB3\VaA70%T>'X=O at q9.pA70Ul@!?-hGAV,>A70UuCNjW2G at Y**A70%T>$+Hh
+=A27c76t$L86&)E<CK2R76spB5t+11<CK2B6q(*E5ug?>779RE76s at 179E5SGAV,MI!^WjE-Gi#
+GAV,>A70UuCNj;sLM^[JD/4?4CNjW2G at Y*:D.e'0CNjW2GAV,>D/4oDB6SH>LNIKjFE!"WE-HDG
+LNIKjFDut^H\QopLNIKiI!^WjE-HDGLNIKjFDuG7?s$)n=A27f9Lrhm8Q\YW<)ck2:J"Y^85rPg
+BMV4,[']l5s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkMYFadaZjkbftliH\Z]^LNIKjD.e'7FGF^G
+GAV,NFDuG at CPR"NGB at q^FE!"WE//OSLNIKiI!^TqH^K2'LkLG;KS5_?Fbk^(N/NX]KRo)?N0f3K
+Q\9pVKRo)?N/)LoG at Y)kA7]CY>%_)DB3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%_)D at q9/+D.eTNH^BD:
+L4"?(KS5_?Fbk^(L4"?(KS5_?Fbk^(Q\9pGKS5\FJV\u4Q\9pVKRoJCJX;=QQ]-g#N/![XMO09Z
+Q]-fgN/Es\MPuJgQ]-fiPEV>dJTkX4G at Y)o>ZtcF>).3=s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhRK\fQ\9pVN/FNdI$]eLQ]-fgKRoJKMO0!I
+Q]-fgKRoJKMO0!IQ\9pGKS5\FJVJQ!Q\9pGKS5\FJX;%@Q\9pGKS5_?Fa%A(=A280D/7>=c-+>U
+bKS5Sbg">Tc-+>U`5T]^KRoJCJX;=QQ\9pVN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/Es\MO09Z
+Q]-fgN/Es\MO09ZQ]-fgKRoJCJX;%@L4">\>Zt6'86APVB3\X?s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kLnYIdaZk#bfe2Rc, at T?
+bKS5L`Pod7`Pfa7`5T]kV5/inH^BD:LkLGJKRoJCJX;%@Q]-fgKRoJKMO0!IQ\9pEI!_35JVJQ!
+L4"?8I!(0kH\QopR!a%2I!^TqH\QopL4"?&I!^TqH\QopL4"?&I!^TqH\QopL4"?&I!`lG])Vg1
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^`5T^6`PoI%]t:qj
+`5T^-]Y1qi]t:qjB3\VB9Lr8Z88(djL4"?7KRoJKMO09ZQ]-g#N/![XMO09ZQ]-fgN/EsTJX;=Q
+W/QItN/FQuOI(o`W0EC3PEVr0OI;;rW0ECBP`V;sPGj_-W1'!MP`Vi4Q)Kq/W1'!MP`Vi4Q)Kq/
+W1'!MR['h?Q)L.:W0ECBR['h?Q)L.:W1'!MR['h?Q)L.:W1'!MR['h?Q)L.:o_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(Sgtp5uc, at T?]=bhh]Y1\Z['[3IX/rG1['[3I[&^:1
+['[2pI!]L2>%_)DBMV34>ZtcF>).3=R?Ni&PEVr0OJnD*W1'!MR['h9OJnV5W0ECBR['h9OJnV5
+W0ECBR['h9OJnD*W1'!MP`Vi4Q'mi"W0EC1N/F$ePIR`pi8j(foC_JAp#tc2i8j(LeCM7E]pt[a
+H[C0C>[CE!5t+11<CK2U9Lr/P6!-fO<CK2U9Lr/P6!-fO<CK2R76t$L89nE=LNIKiI!^TqH\Qop
+L4"?'FDut^H\QopLNIKiI!^WjE/&aeLNIKiI!^[&KZhTadaZjd`PoI%]rS6:X/rG!V50o`Unji_
+UnslBFDt>U86&)E<CK2U9Lr/P6!-fO=A27f9Lr8Z86APVB3\W,KRnr4KU7 at CL4"?7KRnl*H\d?.
+R!a%2I!^TqH^K2'LkLGJKRoJCJX;%@Q]-fgN/ERPN0f3KQ]-g?`PpcrkLnYIdaZjd`PoI%]sP/R
+Unsl_V50WQS=H1 at S=Z7 at St'Ii8Obj*7Qik676sC+4B4g9<CK2C4Zl1s4B4g9<CK2R76spB6"j%c
+L4"?&I!^TqH^AhiL4"?&I!^WjE//OSLNIKjFE!"WE/&aeLNIKiI!_6.Fbk^(Q\9pVKRoJCJX;=Q
+g"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+IoC_>6n)39i\?2cD>Zu>^?t3_YG at Y)o>Zu>^?t3_YG at Y)o>Zu>^?t3_YG at Y)kA7]sq?t3_Y
+G at Y)kA7]sq@!?-h at q9.pA7/nXATqZmC2 at d3A7/nXATqZmG at Y**A70%T>$+Hh=A27S6q(*E5t+11
+<CK2R76spB5ug?><CK2R76t$L87u12G at Y*:FDuGGFGFsWGAV,>FEE:TB6S3.GAV,>D/4?+@!?I'
+LM^[JD/4?4CNjW2LM^[JD/4oKE-H/7GB at q^FDuGGFGFsWGB at q^FDuGGFGFsWH[C0rFDut^H\Z]^
+L4"?&I!^WjE-lq[GAV+t9Lrhm8Q8Yh=A28!:J"Mb<EMpcB3\VB9Lr,^<Q;\_s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gkj7ckgtp`>hU9p)['[2aD/4oKE-HDGLNIKjFDuGGFGF^GGB at q^FE!"WE//OS
+H[C0qI!^TqH\Z]^L4"?&I!^TqH^K2'LkLG;KS5_?FdIc4Q\9pVN/EsTJX;%@Q\9pVN/EsTJV\u4
+LNIKZD/4?+?tW_JG at Y)o>Zu>^@!?I'LNIKiI!_35JV\u4Q\9pEI!_35JV\u4L4"?&I!_6.FbY9j
+LkLG9I!^[&KU at .0LkLGJKRo)?N/3.?Q]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/Es\MO09Z
+LNIKJ>ZtcF>%_)DB3\WgeCO["s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkN:RT`k8mLN/Es\MO09ZQ\9pVN/EsTJX;=QQ\9pVN/EsTJX;%@LkLGJKRnr4KSY;7
+R!a%4KS5_?Fbk^(Q\9pGKS5\FJX;%@GAV+t9Lrhm8\;XKdaZjreCN'tf#u:^bKS5Sbg">Tc+'mU
+LkLGJKRoJCJX;%@Q]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/EsTJX;=Q
+LkLGJKRnr4KSOYg=A27c76t$L89]/ts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7crjQG4OhU9p)bKS5Sbg")F`Pfa7bKS5L`Pp$Ec,RE-
+Q]-fXKS5\FJX;%@Q]-fgN/EsTJW,MGQ]-fgKRnr4KU7 at CLkLG9I!^[&KSFl$L4"?(KS5)-H\d?.
+R!a%2I!^TqH\Z]^LNIKjFE!"WE/&aeLNIKiI!^TqH^K2's8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,coC_>6n(HLQg"bH-bg">Tc, at T?`k8mp]Y1qi]t:qj]=bhQV5.*[5ug?>
+=A28!:J$n3MO0!IQ]-fgKRoJKMO09ZQ]-fgN/EsTJX;=QQ]-fgN/Es\MOBZlQ]-g#P`V5jMPuc$
+Q]-g#P`V;sPF7VuW0EC3PEVr0OIVo4W0EC6St)aDOJnV5W0ECBR['h?Q)Kq/W1'!MR['h?Q)L.:
+W1'!MR['h?Q)Kq/W1'!MR['h?Q)L.:W1'!MP`V];V#UJps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,coC_&&kLnYIdaZjkbg")F`Oidr['[3I['[3I['[3IX/rG1['[3I[%sOoB3\VB9Lrf$>#\I$
+B3\VQ>[!JQMPuc$R?Ni5R['h9OJnV5W0ECBR[';)PGj_-R?Ni5R[';)PGjq8R?Ni5R['D7S>_[6
+R?Ni5P`V;sPGj_-Q]-fgN/FR&Q(4G9LkLG*FED86DHKS'=A27f9Lr8Z86&)E=A27c76spB5t+11
+<CK2R76s at 179)cB<CK2U9Lrf$>'FLbL4"?&I!^[&KU at .0L4"?'FE!"WE/&aeLNIKjFDut^H\Z]^
+LNIKiI!^WjE/&aeQ\9pjXKBq#f#5PH]=bha['ZX*Unji_Unsl_V50o`Uj$p&=A27f9Lr8Z86&)E
+=A27c76spB5ug?>=A27c76tQk>*jnnL4"?7KRnr4KSFl$Q\9pEI!^[&KU7 at CL4"?(KS5\FJW,MG
+Q\9pKMi=!]MO0!IQ\9pKMi=!UJ]l9^i8j(Sgtp5uc, at T?]=bha['ZX*Un"$HS=Z7 at St)44PFS57
+<)cje4Zl1s4 at VIr7Qik'4Zl1s4B4g97Qik676sC+4B4g9<CK2e:J$:gH\QopLNIKiI!^TqH\Z]^
+L4"?&I!^TqH\QopLNIKiI!^TqH\QopLkLG9I!_35JX;%@Q]-fgKRr(BkPtS^s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQG4OhKsTt
+G at Y**A7/nXATqZmB3\VaA70%T>'FLb at q9.r>?#*CAS57OG at Y)o>ZtcF>'FLbB3\VaA7/nXATqZm
+ at q9.pA7/nXATqZmG at Y**A7/nXATr!,B3\VaA70%T>%_)DB3\VR:J"Mb<G50"<)ck">[D&J>'FLb
+GAV,>FED_KFG>0iLNIKZFEE:[E//:CGAV,>D/4?4CNjW2GAV,NFDuG at CNjlBLM^[JD/4?4CNjW2
+GAV,>D/4?4CNjW2LNIKZFED_KFGFsWH[C0rFDuGGFG>0iL4"?&I!^TqH\QopL4"?&I!^'SCM6L8
+<)ck2:J"Mb<G50"<)ck2:J"Mb<G50"<)cl0]Y4 at Fs8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,
+g"bH4eCN9rbEn0FGAV,NFDuGGFGFsWGB at q^FDuGGFGFsWGB at q]I!^TqH\QopL4"?(KS5)-H\d?.
+R!a%4KS5/7KU at .0LkLG?Mi=!UJW,MGQ\9pKMi<IFKT(hJQ\9pVKRnr4KU7 at CLkLGJKRnr4KSY;7
+Q\9pEI!^TqH\d?.R!a%4KS5)-H^BD:LkLG;KS5\FJV\u4L4"?&I!^TqH\QopL4"?(KS5/7KSY;7
+LkLGJKRnr4KU7 at CQ]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgKRmWDAS57OB3\VQ>["(pQ2gma
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n*'-,g"bH-bfuQ>PF%5c
+Q\9pVN/Es\MO0!IQ]-fgN/EsTJX;%@Q]-fgKRoJKMO0!IQ\9pGKS5\FJV\u4Q\9pGKS5\FJVJQ!
+LkLG9I!]O&8Q\YWS=Z8(gtp`>hU9p)daZk#bfe2Rc-+>UbKS5L`PndEQ&(*HLkLG;KS5\FJX;=Q
+Q\9pVN/Es\MO09ZQ]-fgN/Es\MO0!IQ]-fgKRoJKMMQq=Q]-fgKRnr4KU7 at CLkLG9I!^'SCKO8$
+<CK2R77!H8SH&Whs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V<Ln)39ig"bH4eCN9rbJ_B=fZ_OW`Pod7`Pfa7`5T^6`PnXLUmHacQ]-fgN/Es\MO09Z
+Q]-fgN/Es\MO09ZQ]-fgKRnl*H^BD:L4"?7KRnl*H\QopL4"?&I!^TqH\QopL4">pH[UZkE-lq[
+GB at q^FDuGGFGFsWLNILFXfDF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+kj7crjQFt at f$`(!bKS5L`PoI%]t:qj`5T^-]Y2=t\ql#m<CK2B6q(*E6"=G:L4"?(KS5\FJX;%@
+Q]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/FQuOI;;rR?Ni&PEVDuPF%5cW0EC3PEVr0OI;;r
+Q]-fiPEVN.S>_[6W0EC6St)aDOIVo4W1'!>PEVr6Q'mi"W1'!>PEVr6Q'mi"W1'!MR[';)PGjq8
+W1'!>PEVr6Q)L.:W0ECRXfDF$s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7crjQG4OhTO-f
+`5T^-]Y1\Z['[3IX/rG1['[3I['[3I['[3 at XK@G>N+c!Y<)ck2:J"Y^87u12LNIL%N/Es\MOBZl
+R?Ni&PEVDuPF7VuR?Ni&PEVDuPF7VuW0EC3PEVr6Q'mi"W0EC6St)aJQ)Kq/R?Ni&PEVDuPF%5c
+R?Ni$N/Es\MM?M*G at Y)o>Zt6'86APV=A27f9Lr8Z86APV=A27f9Lr8Z86&)EB3\VQ>Zu>gCPR"N
+L4"?&I!^[&KSFl$L4"?&I!^TqH\QopL4"?'FDut^H\Z]^L4"?'FDut^H\Z]^L4"?&I!^[&KT(hJ
+bKS5L`PoI%]sP/RX/rG!V50o`Unji_Unsl2FECVY86&)E=A27f9Lr8Z86APV=A27c76t$L86APV
+B3\W,KRnr4KSFl$Q\9pVKRnr4KU7 at CQ\9pGKS5\FJV\u4N/NX]KRoJKMO09ZQ]-fgN/EsTJW,MG
+LkLH"`PpcrkLnYIdaZjd`PoI%]sP/RX/rFnSt)=BS=H1 at S=Z7LR[%Mj>"1Y;7Qik'4Zl1s4 at VIr
+7Qik'4Zl1s4 at VIr7Qik'4Zl1s4B,9[LNIKZFEE:[E-HDGLNIKjFDut^H\Z]^LNIKjFDut^H\Qop
+L4"?(KS5_?FbY9jLkLG;KS5/7KU7XTg"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(.['X=RATqZm at q9.pA7/nXAS57O
+B3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%;)SG at Y)o>Zu>^?tW_JG at Y)kA7]CY>%;)S
+G at Y)o>Zu>gCM-mUGAV,.>Zu>^?tsLqG at Y)rCi4H-@!?I'GAV,>D/4?;FGFsWGB at q^FDuSRI>3,r
+GB at qNFED_KFGF^GGB at qND/4oKE-HDGGB at q^FDuG at CNjW2GAV,>D/4?4CPR"NGAV,>FED_DCPR"N
+GB at qNFED_KFGFsWL4"?&I!^'ZFG>0iL4"?&I!^WjE/&aeGAV+p<)mU-8Q]5(BMV3!<)mU-8Q]5(
+BMV3!<)mU-8\;XKs8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o.jQGI^kLnYIdaZj[]Y0)BE-HDG
+LNIKZFEE:[E-HDGLNIKZFEE7bH\Z]^H[C0qI!^TqH\QopR!a%4KS5/7KSY;7R!a%4KS5/7KU7 at C
+LkLGJKRo)?N0f3KLkLGJKRnr4KSY;7LkLGJKRnr4KSY;7LkLG;KS5)-H\d?.L4"?(KS5)-H\d?.
+Q\9pGKS5)-H\d?.L4"?&I!^TqH\QopL4"?&I!^TqH^BD:LkLGJKRnr4KSY;7Q\9pVN/Es\MO09Z
+Q]-fgN/Es\MO09ZQ]-fgN/Es\MK`oQB3\VQ>ZtcF>'kUEs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(ZjQFt at eu4gpQ]-fgKRoJCJX;=QQ]-fgN/Es\MO09Z
+Q\9pKMi=!UJW,MGQ\9pGKS5\FJV\u4Q\9pGKS5\FJV\u4LkLG9I!^TqHY6Se=A284H[Xi5kMYFa
+g"bH;gtpK/f$`(!bKS5Sbg">Tc-+>U`5T]^N/EFEKSY;7Q\9pKMi=!]MO09ZQ]-fgN/Es\MO09Z
+Q]-fgN/EFEKU7 at CN/NX]KRoJKMMQq=LkLG;KS5/7KSFl$L4">\>Zt6'84>p8<CK3l`PqlWs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-iW_hV$]@
+daZjkbg")F`Pfa7fZ_OW`Pp$Ec, at T?`k8mLN/EFEKU7XTQ]-f\Mi=!]MO09ZQ]-fgN/ERPN/3.?
+LkLG9I!^TqH\QopL4"?&I!^TqH\Z]^H[C0qI!^WjE/&aeGB at q^FDuGGFGFsWGB at q^FDuGGFT;C@
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH4eCMRW`Pfa7
+`5T^-]Y1qi]u7n/]=bgeA7\4n4B4g9<CK2tD/4r\KSFl$Q\9pGKS5\FJX;%@Q]-fgN/Es\MPuJg
+Q]-fgN/Es\MPuJgR?Ni$N/FQmL7+6hW0EC3PEVr0OI;;rR?Ni&PEVr0OI;;rW0EC3PEVN.S>_[6
+R?Ni5P`V;sPGjq8S=Z7LR['h?Q'mi"W1'!MR[';)PGjq8W1'!>PEVr6Q'mi"W1'!>PEVr6Q(4G9
+`5T^qs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#+oog"bH4eCMgec, at T?]=bha['[3I['[3I
+X/rG1['[3I['[3IX/rF<Ci3o^8Q]5(BMV3!<)mR9>)7ibR?Ni$N/Es\MOBZlW0EC3PEVDuPGj_-
+R?Ni&PEVDuPF7VuR?Ni5R[';)PGjq8R?Ni&PEVDuPGj_-Q]-fiPEV>lMOBZlQ]-fgN/Es\MO09Z
+LkLG9I!^'SCMI['@q9.pA70.gDKfr5GB at q]I!^TqH\QopL4"?&I!^TqH\QopL4"?&I!^TqH\Qop
+L4"?'FDut^H\Z]^GB at q^FDuGGFG>0iGB at q]I!^TqH\d?.L4"?7KRpM;[)Br&]=bha['ZX*Unji_
+Unsl_V50o`Uj$p&=A27f9Lr8Z86APV8k_r]9Lr8Z86APV=A27c76tQk>)7ibL4"?7KRnr4KU7 at C
+Q]-f\Mi<IFKU7 at CLkLGJKRoJCJW,MGQ]-fgN/Es\MN!IPN/NXNKS5/7KZ(jKi8j(SgtpK/f#5PH
+]=bha['ZX*Un"$HS=Z7 at St)=BS=H1@<)cje4Zl1s4B4g97Qik'4Zl1s4 at VIr7Qik'4Zl1s4 at VIr
+7QikI:J#bPFGFsWGB at q^FDuGGFE_hKLNIKZFEE7bH\QopH[C0qI!^TqH\QopLkLG9I!_35JV\u4
+LkLGJKRqh3hZ*WUs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+Em-j0)n)39iN/NX=A7/nXAS57OB3\VQ>ZtWJAS57OB3\VQ>ZtcF>%;)S
+B3\VQ>ZtcF>%;)SG at Y)kA7]CY>%_)D at q9.\A7]CY>%_)DB3\VQ>ZtcF>%;)SB3\VMA7]7]ATqZm
+ at q9.pA7/nXATqZmC2 at d3A70UuCNjW2GAV,>FED_KFF/@_LNIK^H[UZkE-HDGLNIKZFED_KFE_hK
+GB at qND/4?4CNjlBGAV,>D/4?4CNjlBGAV,>D/4?;FE_hKGAV,>FED_DCNjW2LNIKZFED_KFGFsW
+L4"?&I!^TqH\QopL4">pH[U*TCM6L8<)cjs<)mU-8Q8Yh<)ck2:J"Yn?>*,+<)cl0]Y4 at Fs8W-!
+s8W-!s8W-!s8W-!s8W-!s8VHWp%Rh9i8j(Sgtp`>hU9p)Unsl2D/4?;FE_hKLNIKZD/4?;FG>0i
+LNIK^H[UWrH\Z]^L4"?&I!^TqH\QopL4"?&I!^[&KSY;7LkLG;KS5\FJV\u4LkLG;KS5/7KSY;7
+LkLG;KS5/7KSY;7LkLG;KS5\FJVJQ!LkLG;KS5\FJVJQ!LkLG;KS5)-H\d?.L4"?(KS5)-H\Qop
+L4"?&I!^TqH\QopL4"?&I!^TqH\d?.R!a%4KS5/7KT(hJLkLGJN/ERPN0f3KQ]-fgN/EsTJX;=Q
+LNIKJ>ZtcF>%_)D at q907m-juSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+kj7d%m-j0)n']_:UnslRN/Es\MN!IPQ\9pVN/Es\MO0!IQ]-fgKRo)?N0fK\Q\9pGKS5\NMMQq=
+Q\9pGKS5\FJV\u4LkLGJKRnl*H\QopGAV+t9Lrf$>1q]fkj7d%m-ilnkN:RTg"bH4eCMgec.L7`
+bKS5Sbg">Tc*XjbQ\9pGKS5/7KU7XTQ]-fgN/Es\MO09ZQ]-fgN/Es\MO0!IN/NX]N/EFEKT(hJ
+Q\9pGKS5/7KU at .0LkLG9I!^TqHZsRRB3\VB9Lr/P5u^f`kj7d<s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^bKS5Sbg")F`Pfa7
+`5T^6`Pod7`MB?+Q\9pKMi=!]MO09ZN/NX]N/ERPN/W[RQ\9pGKS5)-H\QopL4"?&I!^TqHZsRR
+L4">pH[UZkE/&aeGB at q^FDuGGFE_hKGB at qNFEE:[E-HDGS=Z8Ns8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!kj7d%m-iW_hU9p)bKS5L`Poj0]#;S,`5T^6`Po3kZrKO\
+7Qik'4Zl_56&'c6L4"?(KS5/7KU7 at CN/NX]KRoJKMO09ZQ]-fgN/Es\MOBZlQ]-fiPEV>lMOBZl
+R?Ni5R[';)PGjq8R?Ni&PEVr0OI;;rR?Ni&PEVDuPGjq8R?Ni5R[';)PFS57W1'!>PEVr6Q'mi"
+R?Ni5R[';)PGj_-R?Ni&PEVDuPGjq8R?Ni5R[';)PGjq8R?Ni&PEVr0OQc'"s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o:oC_&&kL.l2bKS5L`PoI%]sP/R['[3I['[3I['[3I['[3 at XKB"7WgoZN
+B3\V><)lms<G50"<)ckAD/5JsMPuc$Q]-fiPEVDuPF7VuR?Ni&PEVDuPF7VuR?Ni&PEVDuPF7Vu
+R?Ni&PEVr0OI;;rR?Ni$N/F$ePF%5cQ]-fgN/Es\MO09ZN/NXRMi=!]MN!IPQ\9pGKS5\FJV\u4
+LkLGJKRnr4KSY;7L4"?(KS5)-H\QopL4"?&I!^TqH\QopL4"?&I!^TqH\QopL4"?&I!^TqHZsRR
+GB at q]I!^TqH\QopL4"?&I!^[&KT(hJS=Z7h`PoI%]sP/RUnsl_V50o`Unji_Unsl2FECVY86APV
+8k_r]9Lr8Z86APV=A27S6q(3O86APVB3\W,KRnr4KU7 at CLkLG;KS5/7KSY;7Q\9pGKS5/7KSY;7
+N/NX]N/Es\MN!IPQ]-fgN/Es\MMQq=LkLH"`PpcrkLnYIdaZjd`PoI%]sP/RUnsl_V50WQS=H1@
+S=Z7 at St'Ii8Obj*7Qik'4Zl1s4 at VIr7Qik'4Zl1s4 at VIr7Qik'4Zl_55u^f`LNIKZFED_DCNjlB
+GB at q^FDuGGFE_hKGB at qRH[UZkE/&aeL4"?&I!^TqH\d?.L4"?(KS5/7KSY;7g"bHas8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7crjQF_1c!t9qB3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%_)DB3\VQ>ZtWJAS57OB3\VQ>ZtcF>%_)D
+B3\VMA7]sq?tW_JB3\VMA7]sq?tW_J at q9.pA70%T>'FLbB3\VTCi3`nATr!,G at Y)rCi4H6CMI['
+GAV,>D/4?;FE_hKLNIKZFED_KFGFsWGB at qNFED_KFE_hKLNIKZD/4?;FE_S;GB at qND/4?4CNjW2
+GB at qND/4?4CNjlBGAV,NFDuGGFE_S;GAV,>FED_DCNjlBGB at qNFEE7bHZsRRL4"?&I!^TqH\Qop
+GAV+p<)mU-8S;:3<)ck1>Ztf:8Q]5(=A27f>[D)>8\;XKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,coC_>6n)39ig"bH4eCN9rbD:h)GB at qND/4?;FE_hKLNIKZFED_KFG>0iGB at q]I!^3eI>;o`
+L4"?&I!^TqH\QopL4"?(KS5)-H\d?.LkLG;KS5/7KSY;7L4"?(KS5)-H^BD:L4"?(KS5)-H\d?.
+LkLG;KS5)-H\d?.L4"?&I!^TqH\QopL4"?&I!^[&KSFl$L4"?(KS5/7KSFl$L4"?&I!^[&KSFl$
+LkLG;KS5)-H\d?.LkLGJKRoJKMMQq=Q]-f\Mi<UQN0fK\N/NXLI!]L2>%_)DB3\VQ>[#S*f)PdM
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bGoXf at _HMO09Z
+Q]-fgN/Es\MO09ZQ]-fgN/ERPN0fK\Q\9pKMi<UQN0f3KN/NX]N/ERPN0f3KN/NX]KRnr4KSFl$
+LkLG:FDt>U85rPg]=biLpA*q=n*'-,kj7crjQG4OhV$]@daZjreCMgec-+>UbKS5Sbfur[Ukj\W
+LkLG;KS5\NMN!IPQ]-fgN/Es\MO09ZN/NX]N/ERPN0f3KN/NXNKS5/7KSY;7LkLG;KS5)-H\d?.
+L4"?&I!^'ZFBD4-=A27c76tEoAcMf1s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,coC_>6n(HLQdaZjreCMgec, at T?`5T^=bg")F`Pfa7`5T^-]Y0,SKT(hJ
+Q]-f\Mi=!]MN!IPQ]-fXKS5/7KSY;7LkLG9I!^TqH[C*fL4"?&I!^TqHZsRRH[C0bFEE:[E-HDG
+GB at q^FDuG at CNjlBGB@q^FE$I1n,NFfs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2g"bH;gtp5uc, at T?`5T^6`Pp$Ec-+>US=Z6?4Zl1s4 at VIrBMV3HH[UZkE/&ae
+LkLG;KS5/7KU7 at CN/NX]N/Es\MO09ZR?Ni5P`V];UoUT!\?2d<['[3I[(Eua]=bhh]Y1\Z['[3I
+X/rG!V51&SOJnV5R?Ni)St)44PFS57R?Ni5R[';)PF7VuR?Ni5R[';)PF7VuR?Ni&PEVDuPGj_-
+R?Ni&PEVDuPF7VuR?Ni&PEVDuPF7VuR?Ni5R[*pQs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+i8j(SgtpK/f#u:^`5T^-]Y1\Z['[3I['[3 at XKAk:['[3IX/rG1['YXBKNLo==A27b<)mU-8Q]5(
+LkLGJN/F$ePF7VuR?Ni$N/F$ePF%5cR?Ni$N/F$ePF7VuR?Ni&PEVDuPF7VuQ]-fiPEVDuPF%5c
+Q]-fgN/ERPN0fK\N/NXRMi=!]MMQq=Q]-fXKS5;BN/3.?LkLG;KS5)-H\d?.L4"?&I!^[&KSY;7
+L4"?&I!^TqH\QopL4"?&I!^TqH\QopL4"?&I!^3eI>;o`H[C0rFDut^HZsRRL4"?&I!^TqH\d?.
+LkLGJKRo)?N3ot!]=bha['Zm8Xe_ehUnsl_V50o`Uj$p&=A27X9MJV_86&)E=A27f9Lr8Z86APV
+=A27f9Lrf$>)7ibLkLG9I!^[&KSY;7Q\9pGKS5\FJW,MGQ\9pKMi=!UJW,MGQ]-fgN/Es\MN!IP
+Q\9pKMi<IFKZ(jKi8j(Sgtp5uc, at T?]=bha['ZX*Un"$HS=Z7 at St)aJQ(4G9<)cje4Zl1s4 at VIr
+7Qik'4Zl1s4 at VIr7Qik'4Zl_55t4""7QikI:J#bPFE_hKGB at qND/4?;FE_S;GB at qNFED_KFGFsW
+GB at qRH[UZkE/&aeL4"?&I!^TqH\QopLkLG;KS8%6hZ*WUs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq;C>si8j'sV5.a/>%_)D
+B3\VB>[D&J>$,$9B3\VB>[D&J>%_)D at q9.`>ZtcF>%_)DB3\VQ>ZtcF>%_)DB3\VQ>ZtWJAS57O
+ at q9.`>ZtcF>%_)DB3\VMA7]7]AS57OG at Y)kA7]t%CL^mdGAV,>A70.gDKfr5GAV,>FED_KFGFsW
+GB at qRH[UWrHZsRRLNIKZFED_KFGFsWGB at qNFED_DCNjW2C2@d3D/4?4CNjlBGB at qND/4?;FE_hK
+GAV,>FED_KFE_S;GAV,>FED_KFGFsWGB at q]I!^TqH\QopL4"?&I!^'SCK+85B3\V><)m$o85rPg
+<)ck2:J"Mb<EMpc<)cl0]Y4 at Fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG[\gtCK>
+daZjd`PmUSE-H/7GAV,>FEE:[E-HDGL4"?&I!^TqH\Z]^H[C0qI!^3eI>3,rH[C0qI!^TqH\d?.
+L4"?(KS5)-H\d?.L4"?&I!^[&KSY;7LkLG;KS5/7KSY;7Q\9pGKS5)-H\d?.L4"?(KS5)-H\Qop
+L4"?&I!^3eI>3,rL4"?&I!^TqH\QopL4"?(KS5/7KSFl$L4"?&I!^TqH\QopL4"?&I!^[&KSY;7
+LkLG?Mi=!UJV\u4Q]-fXKS5;BN-Af?=Bo0F>ZtcF>11pOs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp&`\sJA5Q]-fgN/Es\MO09ZN/NX]N/ERPN0fK\
+N/NXNKS5\NMMQq=Q]-fXKS5/7KT(hJQ\9pGKS5/7KSY;7LkLG;KS5)-HY6Se<)ckaN/IZ8s8W-!
+s8W,kpA*q=n*'-,i8j(SgtpK/f$`(!bKS5Sbg">Tc-+>U`5T]^N/EFEKU7 at CLkLG?Mi=!]MOBZl
+N/NX]N/EFEKU7XTLkLG?Mi=!]MO0!ILkLGJKRnr4KSFl$LkLG9I!^TqH\QopL4">lD/36I86&)E
+779S!I!bnns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7crjQG4OhU9p)bKS5Sbg")F`Pfa7bKS5L`Pod7`Pfa7S=Z7,KS5;BN1#lnQ]-fgN/EFEKU7XT
+LkLG;KS5)-H\QopL4"?(KS5/7KSFl$H[C0qI!^TqHZsRRGB at qNFED_KFE_S;GB at qND/4?;FIA>V
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYI
+daZjreCN'tf#u:^daZjreCKA%HU^.\7Qik'4Zm4bATr6<L4"?&I!^TqH\d?.LkLG;KS5\NMOBZl
+X/rG8]Y28&`QQKM`5T^6`Pod7`Oidr`5T^-]Y1\Z[(Eua['[3P]Y1\Z[(Eua['[3 at XK@nSPF7Vu
+W0EC3PEVr6Q'mi"R?Ni&PEVDuPF7VuQ]-fgN/Es\MO09ZQ]-fgN/Es\MO09ZQ]-fgN/Es\MOBZl
+R?Ni&PEVDuPF7Vu`5T^qs8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_JAp#+oodaZjkbg")F`Oidr
+]=bha['[3I[&^:1['[3I['Zm8XgGIBX/rFIFECVY86APV<)ck"9Lrf$>*k2*Q]-fgN/F$ePF7Vu
+R?Ni&PEVDuPF7VuR?Ni&PEV>lMOBZlQ]-fgN/F$ePF7VuQ]-f\Mi=!]MN!IPN/NXRMi=!]MN!IP
+N/NX]N/ERPN0fK\N/NX]KRnr4KSY;7LkLG;KS5)-H\QopL4"?(KS5)-H[C*fL4">pH[UWrH\Qop
+L4"?&I!^TqH\QopL4"?&I!^'ZFE_hKH[C0qI!^3eI>3,rL4"?&I!^[&KSY;7N/NXjV51`9]sP/R
+Unsl_V50o`Unji_Unsl2FECVY86APV=A27X9MJV_84lQM=A27X9MJV_86APVB3\VrKS5)-H\d?.
+Q\9pEI!^[&KT(hJN/NXRMi=!UJW,MGN/NX]N/Es\MN!IPQ]-f\Mi<UQN/3.?LkLH"`PpcrkLnYI
+daZjd`PoI%]sP/RX/rFnSt)=BS=H1 at S=Z7 at St&nV84Ga)7Qijk1c.Zb4 at VIr7Qik'4Zl1s4 at VIr
+2)I-Z4Zl1s4B,9[GB at qND/4?;FE_S;GAV,>FED_DCNjW2GAV,>FED_DCNjlBGAV,>FED_KFE_hK
+L4"?&I!^TqH\d?.g"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-j0)n(HLQLkLF\<)mR9>#\I$B3\VQ>Zt*+<G,Q?
+B3\VQ>ZtcF>$,$9=Bo0F>Zt*+<G,Q?=Bo0F>ZtcF>%_)DB3\VQ>ZtWJATqZm at q9.`>ZtWJATqZm
+ at q9.pA70.gDI[3gG at Y)kA7]t%CL^mdGAV,1Ci4H6CNjW2GB at qNFED_KFG>0iGB at qNFEE7bHZsRR
+GB at qNFED_KFE_hKGAV,>FED_DCNjW2C2 at d3D/4?;FE_hKLNIKZFEE:[E-HDGGAV,>FED_DCPR"N
+GB at q]I!^TqH[C*fL4"?&I!^3eI>3,rGAV+p<)m$o88(dj=Bo079Lr,^<E)pt<)ck"9Lr,^<P,oW
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(Sgtp`>hU9p)['[2aD/4?4CNjlB
+GB at q]I!^'ZFF/@_H[C0qI!^3eI>;o`H[C0bFEE7bHZsRRL4"?&I!^TqH\QopL4"?&I!^[&KSFl$
+L4"?&I!^[&KSFl$LkLG;KS5)-H\d?.L4"?&I!^3eI<TdTL4">pH[U*[FF/@_GB at q]I!^3eI=$<h
+L4">pH[UWrH\QopLkLG.H[U^'KR8&oLkLG;KS5/7KSFl$LkLG;KS5/7KSY;7N/NXRMi<IFKU7XT
+GAV+t>[D&J>&%kkdaZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7d%m-j)lgrmpdR?NhnMi<UQN/W[RN/NX]N/ERPN0fK\N/NX]N/ERPN0fK\N/NXNKS5\NMMQq=
+Q\9pKMi<IFKSY;7LkLG;KS5)-H\d?.GAV+t9Lro7DY3Yus8W-!s8W-!s8W-!o_/+Em-j0)n)iE\
+g"bH4eCN'tf%A3ibKS5Sbg">Tc+CX%LkLG;KS5\NMN!IPQ]-f\Mi=!]MN!IPN/NXNKS5\FJV\u4
+LkLG;KS5/7KSFl$L4"?(KS5)-H\QopL4">lFEE7bHZsRRC2 at cV6q'O477KF&S=Z8Ns8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq;C>sk1nb?eCN9rbKJ,S
+`5T^6`Pod7`Pfa7f>PA@`Po3k[$Q`/N/NXRMi<UQN/W[RQ]-f\Mi<IFKSY;7LkLG;KS5/7KSFl$
+LkLG;KS5)-H[C*fLNIKZFEE:[E-HDGGB at qNFED_KFE_S;GB at r[gtr)2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2i8j(Sgtp`>hU9p)daZjreCN=.hV$]@
+<)cje4Zl1s4B4g9GAV,MI!^TqH\QopLkLG;KS5/7KW(?)]=bi1gtp`>hV$]@daZjreCMgec-+>U
+`5T^6`Pod7`Oidr]=bhh]Y1qi]t:qj['[3I['[HX]sP/R['[2pI!^[&KUJ$fR?Ni&PEVr6Q'mi"
+R?Ni&PEVDuPF%5cR?Ni$N/ERPN/W[RQ]-fiPEV>lMO09ZQ]-fgN/Es\MOBZlR?Ni&PEVDuPP"SE
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o.jQG4OhU9p)bKS5L`PoI%]sP/R['[3I['[3I['[3I
+X/rG1['[3I[&^:1C2 at c[9MJV_84lQM=A27qA7^^XN0fK\Q]-fgN/Es\MOBZlR?Ni$N/F$ePF%5c
+Q]-fgN/F$ePF%5cN/NX]N/Es\MO09ZN/NXRMi=!UJW,MGLkLGJN/ERPN/W[RQ\9pKMi<IFKSY;7
+LkLG9I!^TqH[C*fL4"?&I!^3eI>3,rH[C0qI!^3eI>3,rL4">pH[UWrH[C*fL4">pH[UWrH\Qop
+L4"?&I!^[&KSY;7LkLG;KS5/7KSY;7LkLGJN/ERPN0fK\['[3I['ZX*Unji_Unsl_V50o`Uj$p&
+<)ck"9Lr8Z86APV8k_r]9Lr8Z86APV8k_r]9LrZ(AVc"mLkLG;KS5/7KSY;7Q\9pKMi=!UJW,MG
+N/NX]KRo)?N0fK\N/NX]N/ERPN/3.?Q\9pGKS5)-HcsXXi8j(SgtpK/f#5PH]=bha['ZX*Un"$H
+S=Z7 at St)=BS=H1@<)cje4Zl1s4 at VIr2)I-Z4Zl1s4>erP7Qik'4Zl1s4 at VIr7Qik99LsALFE_hK
+GAV,>FED_KFE_S;GAV,>FED_DCNjlBGB at qND/4?;FE_hKGB at qNFEDkVI=$<hL4"?&I!aQ%hZ*WU
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVkj7crjQFt at eou4XB3\VQ>ZtcF>$,$9B3\VQ>ZtWJAS57O=Bo0F>ZtcF>#\I$
+B3\V><)mR9>#\I$B3\VMA7]CY>%;)S at q9.`>ZtWJARf7^B3\VQ>ZtWJARf7^G at Y)kA7]7]ATqZm
+ at q9.\A7]7]ARf7^GAV,>FED_DCNjlBGB at qNFEDkVI>3,rH[C0bFED_KFGFsWGB at qNFED_KFE_S;
+GB at qNFED_KFE_S;GAV,>FED_KFE_hKGB at qND/4?;FE_hKGB at qNFEE7bHZsRRH[C0bFEE7bH[C*f
+L4">pH[U*TCK+85<)cjs<)m$o85rPg<)ck2:J"Mb<E)pt=A28t]Y4 at Fs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+QpA*q=n)39ig"bH4eCN'tetf.<C2 at d3D/4?;FE_hKGB at q^FDuGGFF/@_
+GB at qRH[U6fI>;o`H[C0qI!^3eI>3,rH[C0sKS4]!I>3,rL4"?&I!^TqH\QopL4"?&I!^[&KSFl$
+L4"?&I!^3eI=$<hGB at q^FDuGGFE_hKGB at qNFED_KFE_hKL4">lFEDkVI>3,rH[C0fH[UWrH[C*f
+L4">pH[UWrH\QopL4"?(KS5/7KSY;7LkLG;KS5/7KU7XTLkLG*D/36Y?>!MHLkLHFm-juSs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kMYFadaZj9PEUfUKU7XT
+Q]-fXKS5\NMN!IPQ\9pKMi=!]MMQq=N/NX]N/EFEKT(hJLkLG?Mi<IFKSY;7LkLG;KS5)-H\Qop
+LkLG*D/36I86APVg"bHas8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhV$]@daZjkbg">Tc-+>U
+`5T^=bg!Z"Wec=]N/NXNKS5;BN0fK\LkLG?Mi=!UJW,MGLkLG;KS5/7KSY;7L4"?(KS5)-H\Qop
+L4"?&I!^'ZFF/@_GB at q^FDuGGFD"i^7Qik'4ZkSY1t'n)s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZk#bfdrD`RrDX`5T^6`Pp$Ec, at T?
+`5T]`PEV>lMO09ZN/NX]N/ERPN/W[RLkLG;KS5/7KR8&oLkLG.H[UWrH\d?.LkLG9I!^3eI>3,r
+H[C0bFED_KFGFsWGB at qNFEEk.MZ<_Vs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n)39ig"bH;gtp`>hVdJXi8j(5]Y.<65t+11<CK2U9LsMWI=$<h
+H[C0qI!^[&KW(?)bKS5pm-j<4p#tc2kj7crjQGI^kLnYIdaZjreCN'tf#5PH`5T^6`PoI%]uI^r
+['[3P]Y1qi]t:qj['[3P]Y1\Z[&^:1B3\VTCi52iN1#lnR?Ni&PEVDuPF7VuR?Ni&PEUr`N0fK\
+Q]-fgN/ERPN0fK\N/NX_PEV>lMN!IPR?Ni&PEVDuPF7VuR?NiH]Y4 at Fs8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gi8j(SgtpK/f#5PH]=bhh]Y1\Z['[3I['[3I['[3I['[3IX/rG1['Zm8X`nl/
+<CK2B6q'^A9it([GAV,SMi<UQN/W[RQ]-fgN/Es\MN!IPQ]-f\Mi='fPDkEYQ]-f\Mi<UQN0fK\
+N/NXRMi<UQN/W[RN/NX]N/EFEKT(hJLkLG;KS5;BN/3.?LkLG;KS5)-H\QopH[C0bFEDkVI=$<h
+L4">pH[UWrH[C*fL4"?&I!^3eI>3,rH[C0qI!^3eI>3,rLkLG.H[U^'KSFl$L4"?(KS5/7KT(hJ
+Q]-fXKS5;BN/W[RN/NXNKS6D-XgGIBUnsl_V50o`Unji_Unsl2FECVY86APV8k_r]9Lr,^<EMpc
+8k_r]9Lr8Z86APVB3\VrKS5/7KSY;7LkLG;KS5/7KT(hJN/NX]KRo)?N/W[RQ]-f\Mi=!]MN!IP
+N/NXRMi<IFKSY;7H[C1Z`PpcrkLnYIdaZjd`PoI%]sP/RX/rFnSt)aJQ(4G9S=Z7LR[$iO<CT,6
+7Qik'4Zl1s4 at VIr7Qik'4Zl1s4>erP7Qik'4Zl1s4BP9JGB at qNFED_KFE_hKGAV,>D/4?;FE_hK
+GB at qNFED_KFE_hKGB@qNFED_KFE_hKGB at qRH[UWrH[C*fg"bHas8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oo
+i8j(Ebft?RFD"i^@q9.`>ZtWJARf7^B3\VMA7]CY>%_)D<)ck1>Zt*+<G,Q?<)ck1>ZtcF>$,$9
+B3\VMA7]CY>%;)S at q9.pA7/nXARf7^B3\VMA7]7]ARf7^@q9.\A7]CY>%;)SG at Y)kA7]t%CMI['
+GAV,>FED_KFG>0iL4">pH[U*[FG>0iH[C0fH[U*[FGFsWGB at qNFED_KFE_hKGB@qNFED_KFE_hK
+LNIKZFED_KFE_hKGAV,NFDuGGFE_hKGB at qNFED_KFE_hKGB@qNFEDkVI<TdTGAV+t9Lr,^<G50"
+<)cjs<)m$o85rPg=A27f9Lr,^<P,oWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o6m-ilnkLnYIg"bH4eCLFlUj$ZkC2 at d3D/4?;FE_hKGB at qNFED_KFG>0iGB at qRH[U*[FE_hK
+H[C0fH[UWrH[C*fL4">pH[U6fI>EQ0H[C0qI!^3eI>3,rL4">pH[U6fI<TODGB at qND/4?;FE_hK
+H[C0bFEE:[E-HDGL4">lFEDkVI<TdTLNIK^H[UWrH[C*fL4">pH[U6fI>3,rH[C0fH[U6fI>3,r
+L4"?&I!^[&KSY;7N/NXNKS4PdCK+85B3\W9V54.ks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(LeCLFlUl:4jQ]-fXKS5;BN/W[RN/NXNKS5;BN/W[R
+N/NXRMi<IFKU7XTN/NX]N/ERPN0fK\LkLG;KS5)-H\QopL4"?&I!^3eI99`\<CK3SXKDO&s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f$`(!fZ_O^bg">Tc-+>U`5T]`PEV>lMO09Z
+N/NX]N/ERPN/3.?LkLG;KS5/7KSY;7L4">pH[UWrH[C*fH[C0qI!^3eI<TdTL4">lFED_KFE_hK
+GB at qND/2R.75ZnY7Qik&6q..Us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(SgtpK/f#u:^bKS5Sbg")F`Pfa7`5T^6`Pod7`ON%MN/NXRMi<UQN0fK\
+N/NXRMi<IFKSY;7LkLG9I!^[&KSY;7LkLG;KS5/7KSY;7LkLG;KS5)-H\QopL4">pH[UWrH[C*f
+daZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+m.9o6m-ilnkNM:$i8j(bm-j<4ophVD7Qik676sC+4C_o5L4"?&I!^TqH^U(]bKS6'pA+ags7H$\
+o_/+IoC_JAp#tc2kj7crjQG4OhV$]@daZjkbg">Tc, at T?`5T^-]Y1qi]t:qj]=bhh]Y1qi]sP/R
+]=bhh]Y0_sP>kL]B3\VeH[V<GPF7VuR?Ni&PEVDuPF7VuQ]-fiPEUr`N/W[RN/NX_PEUr`N1#ln
+R?Ni&PEUr`N1#lnR?Ni&PEVDuPF7Vus8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQ
+daZjkbg")F`Oidr]=bha['[3I[&^:1['[3I['Zm8XgGIBX/rG5Xf at 21KM"p4<CK2B6q(3O89]/t
+LkLG;KS5;BN/W[RN/NX]N/ERPN/W[RN/NXRMi<UQN/W[RN/NXRMi<UQN/3.?LkLG;KS5;BN/W[R
+N/NXNKS5/7KSY;7LkLG;KS5)-H[C*fH[C0bFED_KFE_hKL4">lFEDkVI>3,rH[C0fH[UWrH[C*f
+L4">pH[UWrH[C*fLkLG;KS5/7KSY;7LkLG;KS5/7KSY;7N/NXNKS5;BN/W[RQ]-f\Mi<UQN1#ln
+['[3I['Zm8Xe_ehUnsl_V50o`Uj$p&8k_r]9LqcL9it([8k_r]9Lr8Z84lQM=A27f9LrZ(AXA at 5
+LkLG?Mi<IFKU7XTLkLG?Mi=!]MN!IPN/NX]N/ERPN1#lnN/NXRMi=!UJW,MGL4"?(KS4]!IDj+D
+i8j(SgtpK/f#5PH]=bha['ZX*Unji_S=Z7 at St)=BS=H1@=Bo0$6q'O477KF&7Qik'4Zl1s4 at VIr
+7Qik'4Zl1s4 at VIr7Qik99LsALFF/@_GB at qRH[U6fI<TdTGB at qNFED_KFE_hKGB@qNFED_KFE_hK
+L4">pH[UWrH\QopL4"?(KS8%6hZ*WUs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kMYFabKS4cI!]@6ARf7^
+B3\VMA7]7]ARf7^B3\VQ>ZtcF>$,$9B3\VB>[D&J>$,$9B3\VQ>ZtWJAS57O at q9.`>ZtcF>%;)S
+B3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%_)DB3\VQ>ZtcF>%;)S at q9.cCi4H6CNjW2GB@qRH[UWrHZsRR
+L4">lFED_KFE_hKGB at qNFED_DCNjlBGAV,>FED_KFE_S;GB at qNFED_KFE_hKGAV,>FED_KFE_hK
+GB at q^FDuGGFE_hKGB at qND/4?4CNjlBGB at qNFED_DCK+85=A27b<)m$o86APV=A27b<)m$o85rPg
+=A28m[']l5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=j7=kj7crjQG4OhV$]@
+daZjT['Y%!FD>W0GAV,>FED_DCNjlBGAV,>FED_KFF/@_GB at qNFED_KFE_hKH[C0bFEDkVI=$<h
+H[C0fH[U6fI=$<hH[C0fH[U6fI<TdTGB at qNFED_KFE_S;GB at qNFED_DCNjlBGB@qNFED_KFE_hK
+GB at qRH[U*[FE_hKGB at qRH[U6fI=$<hH[C0fH[U6fI>3,rL4">pH[U6fI>EQ0LkLG;KS5/7KO\P(
+<)ckPI!af4kPtS^s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7crjQG4OhRK\fLkLG?Mi<IFKT(hJQ]-fXKS5\NMMQq=N/NXRMi<IFKU7XTN/NXNKS5;BN/W[R
+LkLG?Mi<IFKSY;7H[C0fH[U6fI=$<hB3\V04Zmq1FT;C at s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-j0)n)iE\g"bH4eCN'tf#u:^bKS5Sbg">Tc+CX%R?NhnMi=!]MN!IPN/NXNKS5;BN.u_,
+LkLG9I!^[&KR8&oGB at qNFEDkVI=$<hL4">pH[U*[FE_hKGB at qNFED86DKfr5B3\V04ZkSY1c7*H
+ at q90Ns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39i
+g"bH4eCMgec, at T?`5T^=bg")F`Pfa7`5T^6`Pn7/PDkEYN/NXRMi<UQN/W[RN/NXLI!^[&KSY;7
+H[C0sKS5/7KT(hJLkLG;KS5/7KSY;7LkLG;KS4]!I=$<hL4"?(KS9C*s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVkj7d%m-j<4p%7tR
+o_/*NSt&5;77BU5779RgD/4KFI>EQ0]=biWs8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2
+i8j(Sgtp`>hV$]@bKS5Sbg")F`Pfa7]=bhs]XkJW[(Eua['[3P]Y1\Z[(Eua['[2aFECJ]<E)pt
+H[C1/PEUr`N1#lnR?NhnMi='fPDkEYN/NXRMi<UQN/W[RN/NX_PEUr`N1#lnR?Ni&PEVDuPDkEY
+R?Ni&PEXGEf)PdMs8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hU9p)daZjd`PoI%]t:qj
+['[3I['[3I[&^:1['[3 at XKAk:[&^:1X/rFkPESsF<D#qZ779R:9MK_QFGPU'N/NXRMi<UQN/3.?
+N/NXRMi=!]MN!IPN/NXRMi<UQN/W[RLkLG?Mi<IFKSY;7LkLG;KS5/7KSY;7LkLG;KS5/7KR8&o
+L4">pH[U6fI<TdTGB at qNFED_KFF/@_H[C0fH[UWrH\QopH[C0fH[U6fI>3,rH[C0qI!^[&KSY;7
+LkLG;KS5;BN/3.?N/NXNKS5;BN/W[RN/NXRMi<UQN/3.?S=Z7h`PoI%]sP/RUnsl_V50o`Unji_
+Unsl2FEC,K9it([8k_rO9MJV_84lQM8k_r]9LqcL9it([@q9/,KS5;BN/3.?LkLG;KS5;BN/3.?
+N/NXRMi<UQN/W[RQ]-f\Mi=!]MN!IPLkLG;KS5)-H[C*fH[C1Z`PpcrkLnYIdaZjd`PoI%]sP/R
+X/rFnSt)=BS=H1 at S=Z7 at St'Fu>"(hJ=A27T4Zl>19gqH=<CK2C4Zl_55t4""7Qik'4Zl/$79!5d
+GB at qRH[UZkE-lq[GB at qRH[U6fI=$<hH[C0bFED_KFE_hKGB at qNFEE7bHZsRRH[C0fH[U^'KR8&o
+g"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7d%m-ilnkL.l2Q]-f3A7]7]ATqZm at q9.\A7]7]ARf7^
+ at q9.`>ZtcF>%_)DB3\VB>[CoNAS57O at q9.`>ZtWJAS57O at q9.`>Zt67?>!MH=Bo07>[D&J>#\I$
+=Bo03<)m%*?<CH=B3\VQ>ZtWJATqZmC2 at d&Ci4H6CNjlBGB at qNFED_KFE_hKGB@qND/4?4CNjlB
+GAV,>FED_DCL^mdGAV,>FED_DCNjlBGB at qNFED_KFE_hKGB@qNFED_KFE_hKGB at qND/4?4CNjW2
+GB at qND/4KFI<TdTC2 at ci9Lr,^<EMpc=A27b<)m$o84lQM=A27X9MJ,Q9tS'Os8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(`gt^T<hU9p)`5T]OKS3iGATr!,
+GAV,>D/4?4CNjlBGAV,>FED_DCNjlBGB at qNFED_KFE_hKGB@qNFED_KFGFsWGB at qND/4?;FE_S;
+GB at qNFED_KFE_S;GB at qND/4?;FE_S;GB at qND/4?4CNjlBGB at qNFED_DCNjlBGB@qRH[U*[FG>0i
+GB at qNFEE7bH\QopLkLG.H[U^'KR8&oLkLG.H[U^'KQhN[B3\VMA7`]u`W,u<s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkN:RT]=bh9Mi<IFKT(hJ
+LkLG?Mi<IFKT(hJLkLG?Mi<IFKSY;7N/NXNKS5;BN/W[RLkLG?Mi<UQN/3.?LkLG.H[U6fI<TOD
+GB at q:A7\4n4B,9[o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7d%m-iW_hV$]@
+daZk#bfe2Rc-+>UbKS5Sbg!N%[#Bp%N/NXRMi<UQN/3.?LkLG;KS4]!I=$<hH[C0fH[U*[FE_hK
+H[C0bFEDkVI<TdTGB at qND/4?4CNjW2C2 at d&Ci4!(DJ*3X2)I-I1c1PXMZ<_Vs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5Sbg")F`Pfa7
+`5T^=bg")F`Pfa7X/rFZKS5/7KSY;7N/NXNKS5;BN/3.?LkLG;KS5/7KSY;7LkLG;KS5;BN/W[R
+N/NXRMi<IFKSY;7LkLG.H[UWrHd^Eps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+ at Sq=OCVs8W-!s8W-!s8W-!UnskZ9MJ,Q9m_58
+UnsmZpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(SgtpK/f$`(!
+bKS5L`Pod7`Oidr]=bhh]Y1qi]sP/R['[3P]Y1\Z[&BFY<)ck2:J"Yn?AO8fN/NX_PEVDuPF7Vu
+N/NX_PEUr`N0fK\N/NXRMi='fPDkEYR?Ni&PEVDuPF7VuR?Ni&PEUr`N1#lnX/rH's8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(SgtpK/f#u:^`5T^-]Y1qi]sP/R['[3I['[3I[(*6<
+X/rG1['[3I['[3IUnsl2FECVY84>p8=A28#Ci5&^KSY;7LkLG;KS5/7KSY;7LkLG;KS5/7KSY;7
+LkLG;KS5/7KSY;7LkLG;KS5/7KSY;7L4"?&I!^TqH[C*fL4">pH[U6fI<TdTGB at qNFED_DCNjW2
+GB at qNFEE7bH[C*fL4">pH[UWrH[C*fL4">pH[U^'KSY;7LkLG;KS5;BN/3.?N/NXRMi<UQN/W[R
+LkLG;KS5;BN/3.?Q]-g&XKB[ic, at T?]=bha['ZX*Unji_Unsl_V50o`Uj$Zk779R:9MIrD79E5S
+8k_r]9LqcL9it([8k_rO9MK/)>)7ibLkLG;KS5/7KSY;7LkLG;KS5/7KSY;7LkLG;KS5;BN/W[R
+LkLG;KS5/7KR8&oH[C0fH[U*[FMu/;i8j(SgtpK/f#5PH]=bha['ZX*Unji_S=Z7 at St)44PGG%N
+<)cjd6q'O477BU5<CK2R76s at 177BU5779R:9MJMU5t4""779RH>[E/4H[C*fH[C0fH[U6fI=$<h
+GB at q]I!^TqH\QopLkLG.H[UWrH[C*fH[C0fH[UWrH[C*fH[C0qI!aQ%hZ*WUs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(Sgtp`>hQ*`[GAV,*A7]sq?tsLqG at Y)rCi3lj>%;)S=Bo0BA7]CY>%;)S
+B3\VQ>Zt67?>!MHB3\VQ>Zt67?>!MH=Bo0F>Zt*+<E)pt<)cjs<)mR9>#\I$<)cjs<)m%*?=RMW
+ at q9.\A7]7]ARf7^C2 at d&Ci4H=FE_S;GAV,>FED_DCNjW2C2 at d3D/3m&DKfr5=Bo03<)n-ZCNjlB
+GAV,>FEDkVI<TdTL4">lFED_KFE_hKC2 at d3D/3m&DJF!*C2 at d&Ci4H6CNjlBGB at qNFED86DHKS'
+=A27f9LqcL9hJ)R8k_rO9MJ,Q9hJ)R779SO[']l5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+Em-j0)n)39ii8j(SgtpK/f$`(!Unsl2D/3m&DJF!*C2 at d3D/4?4CNjlB
+GB at qNFED_KFE_S;GB at qND/4?;FE_S;H[C0bFED_DCO:DVGB at qNFED_KFE_S;GB at qND/4?;FE_hK
+GB at qND/3m&DKg2EC2 at d3D/4?4CNjlBGB at qNFED_KFE_hKGB@qNFEDkVI=$<hH[C0fH[U6fI>EQ0
+H[C0qI!^3eI<TdT at q9.cCi6Ve[/^1+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39ii8j(>`PmdoN/3.?LkLG;KS5/7KSY;7LkLG;KS5;BN/3.?
+LkLG;KS5/7KT(hJLkLG?Mi<IFKSY;7LkLG;KS4]!I=$<hGB at qNFED_DCJ%8p779S_`PqlWs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726k1nbFgtpK/f$`(!bKS5Sbg">Tc-+>U
+`5T]cSt(atN/W[RN/NXNKS5)-H\d?.H[C0qI!^TqHZsRRH[C0bFED_KFE_hKGB at qNFED_KFE_hK
+GAV,1Ci4H6CL^md at q9.\A7\_><EMpcs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2g"bH4eCN9rbKJ,SbKS5L`Pod7`Pfa7`5T^6`PmRZH[C*f
+LkLG;KS5/7KSY;7N/NXNKS5/7KSY;7N/NXNKS5/7KSY;7LkLG?Mi<UQN/W[RN/NXRMi<IFKR8&o
+N/NYps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s2;mqGAV-Kgtr)2s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_&&kMYFag"bH4eCN'tf#5PH`5T^-]Y2=t]!SiO
+]=bha['[HX]sP/R]=bha['XRaDH'S8<)ck-A7^^XN1#lnN/NX_PEVDuPF7VuN/NX_PEUr`N1#ln
+N/NX_PEVDuPDkEYN/NXRMi='fPDkEYN/NXRMi<UQN;rqXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+(Hp#+oog"bH4eCMgec, at T?`5T^-]Y1qi]sP/R['[3 at XKAk:[&^:1['[3 at XKAk:[&^:1
+S=Z6`>ZsQa77BU5 at q9.tH[U6fI>EQ0H[C0sKS5/7KSY;7LkLG;KS4]!I>EQ0LkLG;KS5/7KSY;7
+LkLG.H[U^'KR8&oH[C0fH[U6fI=$<hGB at qRH[U*[FE_hKGAV,>D/4?;FF/@_H[C0qI!^3eI>3,r
+H[C0qI!^3eI>EQ0LkLG;KS5/7KSY;7N/NXRMi<UQN/W[RN/NXNKS5;BN/W[RN/NX_PEWr(`S'&'
+bKS5L`PoI%]rS6:X/rG!V50o`Unji_Unsl2FEBr>77BU5779RE76s at 177BU5779R:9MJV_84lQM
+ at q9/,KS5)-H\d?.LkLG;KS5/7KR8&oLkLG;KS5/7KSY;7LkLG;KS5/7KSY;7H[C0fH[U6fI<TdT
+GB at rF`PpcrkLnYIdaZjkbg!c4]sP/RX/rFnSt)=BS=H1 at S=Z7 at St'Fu>"(hJ<CK2B6q'R.4 at MY,
+779R56q(*E5t+11779R:9MIrD7;#k/H[C0fH[UWrH[C*fH[C0fH[UWrH[C*fLkLG.H[UWrH[C*f
+L4">pH[U6fI=$<hH[C0qI!^3eI=$<hdaZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+(Hp#tc2
+i8j(Sgtoug`JB2#@q9.\A7]7]ARf7^C2 at d#>ZtWJARf7^=Bo0F>Zt67?<CH==Bo07>[CB/<ENL4
+=Bo03<)lms<E)pt<)cjs<)lms<E)pt<)cjs<)lms<E)ptB3\VB>[D&J>%;)SGAV,*A7]sq?tsLq
+C2 at d&Ci3`nASQ%!GAV,1Ci4!(DJF!*C2 at ce<)l at T79!5dGAV,1Ci4!(DKg2EGB at qNFED_DCNjW2
+GAV,1Ci4!(DI[3gC2 at d#>ZtlYDJF!*C2 at d3D/4?4CNjW2 at q9.C9MJ,Q9hJ)R8k_rZ76sO>9iXVJ
+<CK2R76sO>9sh:7s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+Em-ilnkMYFag"bH;gtpK/f#5PHN/NX0Ci4!(DJF!*GAV,1Ci4H6CNjW2GB at qNFED_DCNjW2
+GAV,>FED_KFE_hKGB at qNFED_DCNjW2GB@qND/4?;FD>W0GB at qND/4?;FD>W0GB at qND/3m&DKg2E
+C2 at d3FED_DCNjlBGAV,>FED_KFF/@_GB at qRH[U6fI=$<hLkLG.H[U6fI=$<hC2 at d3FEFms[/^1+
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o.jQFt at esV_cLkLG.H[U^'KSY;7LkLG;KS5/7KSY;7H[C0sKS4]!I>EQ0H[C0sKS5/7KSY;7
+LkLG;KS5/7KR8&oLkLG*FED_KFD>W0<)cjt76uljN;rqXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC_>6n(HLQg"bH4eCN'tf%A3ibKS5Sbg">Tc, at T?Q]-fXKS5/7KR8&o
+H[C0fH[U6fI=$<hH[C0fH[U*[FE_hKH[C0bFEE7bH[C*fGB at qNFED86DKg2EC2@d&Ci3`nATqZm
+N/NYYm-juSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o6m-j)lgtCK>bKS5Sbg")F`Pfa7bKS5L`Pod7`O*"Z=Bo0eI!^[&KSY;7LkLG;KS5;BN/3.?
+LkLG;KS5/7KSY;7LkLG;KS5;BN/W[RN/NXRMi<UQN/W[RLkLG;KS7:_`W,u<s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\o_/+Em-ilnkLnYIdaZjkbg">Tc, at T?]=bhh]Y1qi]sP/R]=bha['[3I[(Eua
+Q]-f(9Lr,^<E)ptGB at qcMi='fPDkEYN/NX_PEUr`N/W[RN/NXRMi<UQN/W[RN/NXRMi<UQN/W[R
+N/NXRMi<UQN/W[RN/NYQjQHRCs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkLnYI
+daZjkbg")F`Oidr]=bhh]Y1\Z['[3I['[3 at XKAk:[&^:1['[3 at XKAP)XfJP*N/NWo<)l at T79!5d
+H[C0fH[U^'KSY;7LkLG;KS4]!I=$<hLkLG.H[U^'KR8&oLkLG.H[U6fI>EQ0H[C0fH[U6fI=$<h
+GB at qRH[U*[FE_hKGB at qND/4?;FD>W0GB at qRH[U6fI=$<hH[C0sKS4]!I>EQ0LkLG;KS5/7KT(hJ
+LkLG;KS5;BN0fK\N/NXRMi<UQN/W[RN/NXNKS6.tUtOP[i8j(LeCN'tf#5PH]=bha['ZX*Unji_
+Unsl_V50o`Uj$Zk4$5Yq4Zkeg4[qRs779RE76spB5t4""779R56q(`n>'kUELkLG.H[U6fI=$<h
+H[C0sKS4]!I>EQ0LkLG.H[U6fI=$<hH[C0fH[U6fI=$<hH[C0bFED_KFM#3!i8j(SgtpK/f#5PH
+]=bha['Zm8XdkuQS=Z7 at St)=BS=H1@=Bo0$6q'^A9gqH=<CK2B6q'O477BU5779R64Zl/$79)cB
+779RH>[Dc(I=$<hH[C0fH[UWrH[C*fH[C0sKS4]!I=$<hH[C0fH[U6fI=$<hH[C0bFEDkVI=$<h
+H[C0fH[XT&hZ*WUs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+Em-j0)n)39ig"bH;gto*5X`nl/
+ at q9.\A7]CY>%;)S at q9.Q>[D&J>$,$9<)cjs<)lms<E)pt<)cjs<)lms<EMpc<)ck"9Lr,^<EMpc
+<)ck"9Lr,^<E)pt=A27b<)lms<G,Q?@q9.\A7]7]ARf7^@q9.\A7]7]ARf7^@q9.cCi4!(DKfr5
+C2 at d#>ZsQa77BU5779RH9Lro7DJF!*C2 at d&Ci4H6CMI['C2 at d&Ci4!(DJF!*B3\VMA7]CY>%;)S
+ at q9.`>ZtWJASQ%!C2 at d&Ci3`nAP,Wj8k_rO9MJMU5tXgF779R64Zl/$76<Up7QilG]Y4 at Fs8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVp[%),m-ilnkMYFa
+g"bH;gtpK/f!MfkL4">_Ci4!(DJF!*C2 at d&Ci4H=FD>W0GB at qNFED_KFE_hKGB@qNFED_KFE_hK
+GB at qNFED86DKg2EC2@d3FED86DKg2EGB at qNFED86DKg2EGB@qACi4H=FE_hKC2 at d3FED_KFE_hK
+GB at qND/4?;FE_hKGB at qRH[U6fI=$<hGB at qpPEX26c2[hDs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39idaZjKXK at G>N/3.?
+H[C0fH[U^'KR8&oLkLG.H[U^'KR8&oH[C0fH[U6fI<TdTH[C0fH[U6fI=$<hH[C0fH[U6fI=$<h
+GB at q:A7\1t7:Tk>s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+kj7d%m-iW_hV$]@daZjkbg">Tc, at T?bKS5Sbg!2iXc/0sH[C0sKS4]!I>EQ0H[C0fH[U6fI<TdT
+GB at qNFED_KFE_hKGB@qNFED_KFE_hKC2 at d3D/3m&DKfr5UnsmNm-juSs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726g"bH;gtp5uc-+>U
+`5T^6`Pod7`Pfa7`5T]BH[TXFDL6_YLkLG.H[U^'KSY;7LkLG;KS5/7KSY;7N/NXAH[U^'KSY;7
+N/NXRMi<UQN/W[RN/NXRMi<IFKT(hJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6/h<
+kj7crjQG4OhU9p)bKS5L`Poj0]">Vg]=bhh]Y1\Z[(Eua]=bha['Zm8X]Sh7=A27f9Lr8j?Asf$
+N/NXRMi<UQN/W[RN/NXNKS5;BN/W[RLkLG?Mi<UQN/W[RN/NXRMi<UQN/W[RN/NXRMi<UQN4Za9
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9o.jQG4OhU9p)bKS5Sbg")F`Oidr
+]=bhh]Y1\Z['[3IX/rG5XfAG'XgGIBX/rG1['[?FWiN5'LkLF\<)lOa9k.^FH[C0sKS4]!I>EQ0
+LkLG;KS4]!I>EQ0H[C0sKS4]!I>EQ0H[C0fH[U*[FF/@_GB at qRH[U*[FE_hKGB at qNFED_KFD>W0
+C2 at d&Ci4H6CNjlBGB at qRH[U6fI=$<hH[C0fH[U^'KSY;7LkLG;KS5;BN/W[RN/NX_PEUr`N/W[R
+N/NXNKS5bWPJkGZm.9o6m-ilnkLnYIbKS5L`PoI%]rS6:Unsl_V50o`Unji_Unsl2D/2!c1c7*H
+4$5Yq4Zkeg4Zbbh4$5Yp6q(*E5t+11=Bo0ZH[U6fI=$<hLkLG.H[U6fI=$<hLkLG.H[U6fI=$<h
+H[C0fH[U6fI<TdTH[C0fH[U6fI<TdTC2 at e+`PpcrkLnYIdaZjd`PoI%]sP/RX/rFnSt)=BS>_mA
+S=Z7 at St'Fu>"(hJ<CK2G9MIrD77BU5<CK2G9MJ,Q9gqH=779R56q(*E5u^f`H[C0fH[U6fI=$<h
+H[C0fH[U6fI=$<hH[C0fH[U6fI=$<hH[C0fH[U6fI>3,rGB at qRH[U6fI=$<hdaZkJs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-ilnkMYFag"bH4eCL.]S9K's at q9.\A7]CY>#\I$
+=Bo03<)lms<E)pt<)ck"9Lr8Z86APV=A27b<)lms<EMpc<)cjs<)lms<EMpc<)cjs<)lms<E)pt
+<)cjs<)m%*?>!MHB3\VB>[CoNARf7^@q9.`>ZtWJARf7^@q9.\A7\_><CK;E7Qik'4Zkeg4[hb-
+ at q9.\A7]7]ASQ%!C2 at ctA7]7]ARf7^@q9.\A7]CY>%;)S at q9.Q>[D&J>$,$9 at q9.\A7]7]ATr!,
+B3\V?76s at 177KF&779R64Zl1s4 at MY,4$5Yq4Zm4bA^])Zs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d%m-ilnkN:RTg"bH;gtpK/f!qi^
+H[C0UCi4H6CMI['GAV,>FED_KFD>W0GB at qACi4H=FD>W0C2 at d3D/3m&DJF!*GB at qACi4H=FE_S;
+GB at qNFEDkVI<TdTGB at qNFED86DKfr5C2@d&Ci4H=FD>W0GB at qACi4!(DKg2EGB at qNFED_KFE_hK
+LkLG^XKCFAkPtS^s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-iW_hV$]@daZj[]Y0i,S;`AbH[C0sKS5/7KR8&o
+H[C0fH[U6fI<TdTGB at qNFED_KFE_hKH[C0fH[U6fI=$<hH[C0bFED86DG!Ss8k_t-eCO["s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2k1nbFgtpK/f$`(!
+daZk#bfe2Rc-+>UbKS5$St(UiKR8&oH[C0bFEDkVI=$<hGB at qNFED_KFD>W0GB at qNFED_KFE_hK
+GB at qACi4!(DMWt!]=biWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIbKS5Sbg")F`RrDX`5T^6`Po3kZrC")
+LkLG;KS5/7KSY;7H[C0sKS4]!I>EQ0LkLG;KS4]!I>EQ0LkLG;KS5;BN/W[RN/NXRMi<UQN/W[R
+LkLGn]Y4 at Fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH4eCN'tf#5PH
+`5T^-]Y1qi]sP/R]=bha['[3I[(Eua['[2aD/3*M<E)pt<)ckAFEEJ"N/3.?LkLG;KS5/7KSY;7
+H[C0sKS4]!I>EQ0LkLG?Mi<UQN/W[RN/NXRMi<UQN/W[RN/NXbSt,i\s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gi8j(ZjQG4OhU9p)bKS5L`Pod7`Oidr]=bhh]Y1\Z['[3I
+['[3 at XKAk:[&^:1X/rG(XKB"7WiN5'N/NX)A7\_><GH>fH[C0fH[U^'KSY;7LkLG.H[U^'KR8&o
+LkLG.H[U6fI=$<hGB at qNFED_KFE_hKGB@qNFED86DKg2EC2 at d3FED86DJF!*C2 at d3D/4?;FE_hK
+H[C0fH[U^'KT(hJH[C1"Mi<IFKT(hJN/NXRMi<UQN/W[RN/NX_PEUr`N2s%^m.9oMs8VHWp#tc2
+i8j(LeCN'tf"8T.]=bha['ZX*Unji_Unsl_V50o`UgmqH2)I-I1c.'H1c7*H4$5Yq4Zkeg4Zbbh
+4$5Yq4Zl\C<I9(@H[C0fH[U6fI=$<hH[C0fH[U6fI=$<hH[C0fH[U6fI<TdTGB at qNFED_KFE_hK
+GB at qNFED86DS*Qpkj7ckgtpK/f#5PH]=bha['Zm8Xe_ehS=Z7 at St)=BS=H1@<)cjd6q'O477KF&
+779R:9MIrD77BU5<CK2B6q'^A9gqH=779RH>[E/4H[C*fH[C0fH[U^'KR8&oLkLG.H[U6fI=$<h
+H[C0fH[U6fI=$<hH[C0fH[U6fI=$<hH[C0bFEGs\f)PdMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVkj7d%m-ilnkMYFag"bH-bfuZLS8)kX=Bo0F>Zt*+<E)pt<)cjs<)m$o85rPg
+8k_rY<)lOa9iP(l8k_rO9MJJc<EMpc8k_rY<)lOa9it([=A27b<)lms<E)pt<)cjs<)lms<ENL4
+B3\V><)m%*?<CH=@q9.`>Zt67?:@7N7Qijk1c.'H1cmf_<)ckAD/36Y?>!MHB3\VQ>ZtcF>%;)S
+ at q9.`>ZtWJAS57O at q9.Q>[D&J>#\I$=Bo03<)lms<G,Q?@q9.\A7\_><CK;E7Qik&6q'R.4?GYg
+<)ckEH[VrrXm#-?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq=j7=kj7d%m-ilnkMYFag"bH;gtpK/f!MfkN/NX0Ci4H=FD>W0
+GB at qACi4H=FE_S;C2 at d&Ci4H=FD>W0C2 at d3D/3m&DKg2EC2 at d3FED_KFF/@_GB at qRH[U*[FE_hK
+GB at qNFED_KFD>W0GB at qACi4!(DJF!*GB at qNFED_KFF/@_R?NiXbg$1fs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(ZjQG4OhV$]@g"bH-bg!N%[$d,ALkLG;KS4]!I=$<hGB at qNFED_KFD>W0
+C2 at d&Ci4!(DKg2EGB at qNFED_KFE_hK<)cje4ZoO:V#UJps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)iE\g"bH4eCN'tf#u:^bKS5Sbg"Scf#u:^
+N/NXAH[U6fI<TdTH[C0bFED_KFE_hKC2 at d3FED_KFD>W0GB at qNFEDkVI@Qn!g"bHas8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<726i8j(Sgtp]-bKJ,S`5T^6`Pp$Ec, at T?L4">XA7^+7I=$<hH[C0fH[U6fI=$<h
+H[C0sKS4]!I>EQ0LkLG?Mi<"0I>j)CH[C1"Mi<UQN/W[RN/NXRMi<UQN;rqXs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n(HLQdaZjkbg")F`Oidr]=bhh]Y1\Z['[3I
+]=bha['[HX]nh>p<)ck"9Lr,^<F]QNN/NXAH[Uj2N-fo"N/NXAH[U6fI=$<hH[C0sKS4]!I=$<h
+N/NXAH[U^'KSY;7N/NXRMi<UQN/W[Rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA+(Hp#tc2g"bH;gtpK/f$`(!bKS5L`PoI%]t:qj]=bhh]Y1\Z['[3I['[3 at XKAk:['[3I
+X/rG(XKAP)XfJP*S=Z6pFED#'AUAcPH[C0fH[U6fI>EQ0H[C0sKS4]!I=$<hH[C0fH[U6fI=$<h
+GB at qACi4THI;3S9GB at qACi4!(DI[3gC2 at ctA7]LlDJF!*C2 at d&Ci4H=FF/@_H[C0fH[U^'KR8&o
+LkLG?Mi<UQN/W[RN/NX_PEUr`N1?K0i8j)$s8W-!s8W-!m.9o6m-ilnkLnYIbKS5L`PoI%]rS6:
+Unsl_V50o`Unji_Unsl%Ci2*e1c7*H2)I-B/1i_91bL=22)I-O4?YPY1cmf_8k_s'FED86DKg2E
+C2 at d3FED_KFF/@_GB at qNFED_KFD>W0GB at qACi4H=FD>W0GB at qACi4!(DJF!*C2 at e"]Y37akLnYI
+daZjd`PoI%]sP/RX/rFnSt)=BS=H1 at S=Z7 at St'Fu>"(hJ8k_rJ6q'^A9gqH=8k_rJ6q'O477BU5
+8k_rJ6q(*E6"=G:H[C0fH[U6fI=$<hH[C0fH[U^'KR8&oH[C0bFEDkVI<TdTH[C0bFEDkVI=$<h
+H[C0bFED_KFF/@_daZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<[_G
+kj7crjQGI^kMYFag"bH:bfcNJS8)kX<)cjs<)m$o84lQM8k_rO9MJV_84lQM8k_rO9MJV_85rPg
+8k_rO9MJJc<EMpc<)cji9MJJc<E)pt<)cjs<)m%*?;sm(=Bo03<)lms<E)pt<)cjs<)lms<CK;E
+2)I-O4?ZYC<JGmJUnsm*`Pp9Tf!qi^=Bo07>[CN;?<CH==Bo0F>Zt67?<CH==Bo0F>Zt67?>!MH
+=Bo03<)lms<E)pt<)cjs<)m%*?>!MH<)cjZ4?Z;19k.^FR?NiQ`PqKCq>^Kps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+(Hp%7tRkj7d%m-ilnkMYFag"bH;gtp`>hSdCPS=Z6tH[TXFDKg2EGB at qACi4H=FD>W0
+C2 at d3FED_DCNjlBGB@qNFED_KFE_hKGB at qRH[U6fI<TdTH[C0bFED_KFE_hKC2 at d&Ci4!(DJF!*
+GB at qACi4H=FF/@_X/rG]jQHRCs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*q=n)39i
+i8j(Sgtp`>hV$]@daZjreCMRW`MB?+N/NXAH[U*[FE_hKC2 at d&Ci3`nARf7^C2 at d&Ci4H=FE_hK
+GB at q/>[Bl_4C_o5s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\m.9o6m-iW_hV$]@daZk$gtpK/f$`(!daZk$gtoug`Hur[H[C0fH[U6fI<TdT
+H[C0bFED_KFD>W0C2 at d3FEE=lKXA+nm.9oMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-iW_hV$]@
+bKS5Sbg")F`Pfa7`5T^&['WG!9m:]$H[C0fH[U6fI=$<hH[C0fH[U6fI=$<hH[C0sKS4]!I>EQ0
+LkLG;KS5/7KSY;7H[C1"Mi<UQN/3.?['[4?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7crjQG4OhTO-f`5T^6`PoI%]sP/R]=bhh]Y1\Z[(Eua['[31St&DH9iP(l
+8k_rY<)na-KT(hJN/NXNKS5;BN-fo"H[C0fH[U6fI=$<hH[C1"Mi<"0I>j)CLkLG.H[Uj2N-fo"
+N/NXRMi@#op&G'ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_JAp#+oo
+g"bH;gtpK/f$`(!bKS5L`PoI%]t:qj]=bha['[3I['[3I['[3 at XKAk:[&^:1['[3 at XKAP)XfJP*
+X/rF^Mi<"0I=$<hN/NXAH[U6fI=$<hH[C0fH[U6fI=$<hH[C0bFED_KFE_hKH[C0UCi4H=FD>W0
+ at q9.\A7]7]ASQ%!@q9.cCi4H=FD>W0GB at qRH[U6fI=$<hLkLG.H[Uj2N-fo"N/NXRMi<UQN1?K0
+`5T^qs8W-!s8W-!s8W-!s8V`bq<726i8j(LeCMgec, at T?['[3I['ZX*Unji_Unsl_V50o`Uj$Zk
+2)I-I1c.'H1c7*H2)I-B/1iJ*/N#@A2)I-I1c.fu9knK^C2 at d&Ci4!(DKg2EC2 at d&Ci4!(DJF!*
+C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DS*Qpkj7ckgtpK/f#5PH]=bha['Zm8XdkuQ
+S=Z7 at St)=BS=H1 at B3\V/6q'^A9iXVJ779RE76s at 177BU5779R:9MIu>4 at MY,779RH>[Dc(I>EQ0
+H[C0sKS5/7KSY;7LkLG.H[U6fI=$<hH[C0fH[U*[FF/@_GB at qNFED_KFE_hKGB@qNFEGs\f)PdM
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVkj7d%m-ilnkMYFa
+g"bH;gto*5XbM4M<)cjs<)lOa9hJ)R8k_r]9LqcL9hJ)R8k_rO9MJ,Q9iP(l8k_rY<)lms<E)pt
+=A27b<)lms<E)pt<)cjs<)m$o85rPg=A27b<)lms<E)pt at q9/,KS6k;Wm]DJi8j(ZjQG4OhVdJX
+g"bGk['We3<E)pt<)cjs<)lms<E)pt<)cjs<)m$o85rPg<)cjs<)lms<E)pt<)ck"9Lr8j??^7%
+H[C1"Mi<UQN2s%^g"bHNoC`.`s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=j7=
+kj7d%m-j0)n)39ii8j(Sgtp`>hU9p)['[3!Mi;k%FE_hKC2 at d3FED86DKg2EGB@qNFED_KFD>W0
+GB at qNFED_KFF/@_H[C0fH[U6fI<TdTGB at qACi4!(DJF!*C2 at d&Ci4THI at Qn!bKS62s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+Em-j0)n*'-,i8j(ZjQG4OhV$]@
+g"bH;gtpK/f"8T.R?NhYFED86DI[3g=Bo07>[CN;?>=:o at q9.cCi3`nAO\gF=Bo2!oC`.`s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+kj7crjQG4OhWEVKg"bH;gtq2KgtCK>i8j(.['YXBKR8&oGB at qRH[U*[FD>W0C2 at d&Ci52iN6BGi
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726g"bH;gtp5uc-+>U`5T^6`Pp$Ec%^Um
+=Bo0VFED_KFE_hKGB at qNFED_KFE_hKGB@qRH[U6fI=$<hH[C0sKS5/7KT(hJN/NXRMi<UQN/W[R
+H[C1"Mi@]9s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#+oo
+g"bH4eCMRW`Pfa7]=bhh]Y1\Z['[3I['[3P]Y1\Z[%sOo8k_rY<)lOa9iP(lH[C0sKS5/7KSY;7
+LkLG;KS5/7KSY;7H[C0fH[U6fI=$<hH[C0sKS4]!I>EQ0LkLG?Mi<IFKT(hJdaZkJs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o:oC_>6n)39ig"bH;gtpK/f$`(!
+bKS5L`Pod7`Oidr]=bhh]Y1\Z['[3I['[3I['Zm8XgGIBX/rG(XKAP)XfJP*X/rG!V50'.N/W[R
+N/NXRMi<"0I=$<hH[C0fH[U6fI<TdTC2 at d3FED_KFD>W0GB at qACi4!(DI[3g at q9.\A7]7]ASQ%!
+C2 at d3FED_KFE_hKH[C0fH[U6fI>EQ0H[C0sKS5;BN1#ln`5T^qs8W-!s8W-!s8W-!s8W-!s8W-!
+m.9o6m-iW_hU9p)bKS5L`PoI%]rS6:X/rG!V51/nXe_ehUnsl6H[S=N77KF&2)I-Z4ZkSY1c7*H
+2)I-I1c.'H1bL=2779RZCi4!(DJF!*C2 at d&Ci3`nASQ%!@q9.\A7]7]ASQ%!@q9.\A7]7]ARf7^
+ at q9.\A7]7]ASQ%!C2 at e"]Y37akLnYIdaZjkbg!c4]sP/RX/rFnSt)UQUn"$HUnslWSt'P3DFHr^
+779R56q'O477BU5779R:9MJ,Q9gqH=8k_rO9MIrD79Ef$H[C0sKS5/7KR8&oLkLG.H[U^'KT(hJ
+H[C0sKS4]!I=$<hGB at qNFED86DJF!*C2 at d3FED_KFE_hKdaZkJs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+(Hp#tc2kj7d%m-ilnkMYFag"bHBjQFJ#`LNNi
+GAV+p<)lOa9hJ)R8k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9iP(l<)cjs<)lms<E)pt<)cjs<)lms<E)pt
+8k_rY<)n-aFIA>V]=bi1gtq8]n*'-,kj7d%m-j0)n*'-,kj7crjQGI^kI\C?=Bo07>[CB/<E)pt
+<)ck-A7]LlDKg2EH[C1"Mi=0tS><!W['[3[]Xl;1c.Un/i8j(bm-j<4p$D;Co_/+QpA+ at Sq>^Kp
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVkj7d%m-j0)n*'-,
+i8j(ZjQGI^kLnYIdaZjT['Z6bPC%Y)GB at qACi4H=FD>W0H[C0bFEDkVI<TdTH[C0fH[U6fI=$<h
+H[C0bFED86DKg2EC2 at d7H[V<GPJkGZm.9oMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq>^Kpo_/+Em-j0)n*'-,i8j(ZjQGI^kLnYIi8j(ZjQGI^kL.l2
+['[2rKS3H4?<CH=@q9.\A7]7]ASQ%!779S'Mi@]9s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2kj7crjQGann)39i
+kj7d%m-j<4p#tc2R?Nh]H[U6fI<TdTGB at qRH[V]dV!.16s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\m.9o.jQG[\gsX^'bKS5Sbg")F`Pfa7['[249MK8<DJF!*GB at qNFED_KFE_hK
+GB at qACi4THI;3S9H[C0fH[U6fI>j)CLkLG;KS5;BN/3.?N/NXNKS5/7KWD2Vs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-ilnkLnYIbKS5L`PoI%]t:qj
+['[3[]Xk_f]sP/R]=bhQV5-^W9it([8k_r]9LrZ(AVc"mLkLG;KS4]!I>j)CH[C0fH[U6fI=$<h
+H[C0fH[U6fI=$<hH[C0fH[U6fI>j)CH[C0fH[WN=^&S-4s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-ilnkMYFag"bH;gtpK/f$`(!bKS5Sbg")F`Pfa7
+]=bhh]Y1qi]sP/R]=bha['[3I['[3I['[3I['[3I['[3I['[3I['Zm8XdkuQLkLG.H[U6fI=$<h
+H[C0UCi4H=FD>W0C2 at d3FED86DJF!*@q9.\A7]7]ARf7^@q9.\A7]LlDJF!*C2 at d7H[U6fI=$<h
+H[C0fH[Uj2N3ot!g"bHVpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#u:^
+]=bhh]Y1AIXgGIB['[3I['[3I['[3IUnslGMi;jsCJ%8p7Qik'4Zkeg4Z,&Q2)I-I1c.Wh7;?XV
+C2 at d&Ci4!(DJF!*@q9.cCi3`nASQ%!@q9.\A7]LlDI[3g at q9.\A7]7]ARf7^@q9.\A7]LlDS*Qp
+kj7ckgtp`>hTO-f`5T^-]Y1\Z[&^:1UnslfXKAP)XfJP*X/rG!V50'.N-BAc=Bo0)9MJ,Q9gqH=
+<CK2B6q'^A9gqH=8k_r]>[Dc(I>EQ0LkLG;KS5/7KR8&oLkLG.H[U^'KR8&oH[C0fH[U6fI;3S9
+GB at qNFED_KFD>W0GB at qACi7\Nf)PdMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726kj7d%m-j0)n)39ii8j(ZjQG4OhTO-fUnsl6H[TC7AP,Wj
+8k_rO9MJ,Q9iP(l8k_rY<)lms<E)pt<)cjs<)m%*?>=:oLkLGOSt*F*^#7u7kj7d%m-j<4p%7tR
+o_/+QpA+ at Sq=OCVm.9o:oC_kEkNM:$kj7ckgto*5Xh26Z`5T^=bg"hrhVdJXi8j(bm-j0)n*'-,
+kj7d%m-j0)n*'-,m.9o:oC_bLq=OCVo_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVp[%)0oC_>6n*'-,kj7d%m-ilnkMYFa
+i8j(Sgtoug`MB?+S=Z7,KS4]!I<TdTGB at qNFEDkVI<TdTGB at qACi4THI>j)CS=Z7X['\92f(A\3
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\o_/+IoC_JAp#tc2kj7d%m-j0)n*'-,i8j(foC_>6n*KZ=g"bG[V5/<WFD>W0
+ at q9.cCi7G?c2[hDs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+ILkNqg5kj7d)oC_JAp%7tRo_/+QpA*Y-kBhQ(
+H[C1"Mi>Tn`Urm"s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA*q=n)39i
+g"bH4eCMgec-+>U`5T^6`PmXdKN(oNGB at qNFEDkVI=$<hGB at qRH[U6fI=$<hH[C0bFED86DL6_Y
+H[C0fH[U6fI=$<hLkLG;KS5/7KT(hJLkLHJoC`.`s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<726i8j(SgtpK/f#5PH`k8mp]Y1qi]sP/R]=bha['[3I[%*_X
+8k_rO9MJ,Q9hJ)R=Bo0gKS5;BN-fo"N/NXAH[U6fI=$<hH[C0fH[TXFDKg2EH[C0fH[U6fI=$<h
+H[C0fH[U^'KR8&oX/rH's8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq=OCVm.9o:oC_&&kMYFag"bH;gtpK/f$`(!bKS5Sbg">Tc, at T?`5T^6`PoI%]t:qj
+]=bhh]Y1qi]t:qj]=bhh]Y1qi]u7n/]=bhq`PoI%]sP/RS=Z7,KS4]!I=$<hC2 at d&Ci4!(DJF!*
+C2 at ctA7]7]ARf7^=Bo0BA7]7]ARf7^C2 at d&Ci4!(DJF!*LkLGOSt*a<`TZ[Ws8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n)39ig"bH4eCMRW`Pfa7]=bha['[HX]t:qj
+]=bhh]Y1qi]t:qj`5T^-]Y1,;Ul:4j at q9.>6q'R.4 at VIr8k_s'FED_KFD>W0C2 at d3FED86DJF!*
+C2 at d&Ci4THI=$<hN/NXbSt)UQUpRM9]=bi#bg"Scf&5WPkj7d%m-j0)n)39ig"bH4eCN'tf#5PH
+]=bha['[3I['[3I['[3I['[3I[(Eua['[3I['[HX]sP/RS=Z70Mi;CeDH'S87Qik&6q(*E6!.Au
+H[C0sKS5/7KSY;7N/NXAH[U^'KR8&oH[C1"Mi<UQN1?K0UnslfXKB+I]t:qjbKS5agtq8]n*KZ=
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+\s8V`bq<726kj7d%m-j0)n)39ii8j(ZjQGI^kMYFag"bH-bg!N%[%*_XQ]-fXKS5/7KT(hJ
+N/NXbSt*0p[)Br&daZk+jQGann*'-,kj7d)oC_JAp%7tRo_/+QpA+ags8W-!o_/+\s8V`bq=OCV
+o_/+QpA+ at Sq=OCVkj7d%m-j0)n*'-,kj7d%m-j<4p#tc2o_/+Em-jT?q=OCVm.9oBpA+ at Sq=OCV
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+IoC_JAp#tc2kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,
+g"bH4eCMRW`Oidr`5T^-]Y2M4c.Un/kj7d)oC`.`s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+o_/+QpA+(Hp$D;Cm.9o:oC_JAp$D;Co_/+QpA+ags8W-!s8W,PgtoEF[/^1+s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVs8W-!s8W-!s8W-!s8W,Pgtp`>hXpO;s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7ckgtpK/f$`(!bKS5L`Pod7`Q#R%
+8k_roCi4!(DKg2EH[C0UCi4THI=$<hGB at qNFED86DJF!*C2 at d7H[TXFDL6_YH[C1"Mi<"0I>j)C
+H[C1"Mi=0tSH&Whs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,+['WG!:"e=Y
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,coC_&&kLnYIdaZjd`Pod7`Oidr['[3I['[3I[(Eua]=bhDN/C5$9gqH=8k_rO9MJJc<JZ<]
+H[C1"Mi<"0I>j)CH[C0fH[U6fI=$<hH[C0UCi4THI;3S9H[C0fH[U6fI=$<hH[C0fH[VEUSH&Wh
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCV
+m.9o6m-ilnkMYFag"bH;gtp`>hU9p)daZjkbg">Tc-+>UbKS5Sbg")F`QQKM`5T^6`Pod7`Pfa7
+`5T^6`Pp$Ec, at T?daZjkbg"Scf#u:^]=bhXXKA"aS9oU2GB at qACi4!(DI[3g at q9.\A7]7]ARf7^
+ at q9.pFEEJ"N2s%^bKS5toC_bLq>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq<[_Gkj7crjQG4OhV$]@bKS5Sbg")F`Pfa7`5T^6`Pod7`QQKMbKS5Sbg")F`QQKM
+bKS5ZeCN'tf$`(!X/rF^Mi;CeDN'L4S=Z7OXKB+I]u7n/daZk+jQGann+?>Ls8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8VHWp$D;Cm.9o6m-ilnkLnYIdaZjd`Pod7`Oidr]=bhh]Y1qi]t:qj
+`5T^-]Y28&`Oidr`5T^6`Pp$Ec-k+mdaZk$gtoug`MB?+LkLG.H[VEUS?&`n['[3Y`Pp$Ec.Un/
+i8j(bm-j<4p%7tRs8W-!s8W-!s8W-!o_/+\s8W-!s7H$\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCV
+m.9o:oC_>6n*'-,kj7d%m-ilnkNM:$i8j(ZjQGI^kMYFai8j(ZjQGann*'-,kj7d%m-j0)n*'-,
+m.9o:oC_bLq=OCVo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVs8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+IoC`.`s6T at Mm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp%7tR
+o_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+Em-ilnkLnYIdaZjkbg">Tc-+>U`5T]SMi:8%9m:]$C2 at d3FED_KFE_hK
+C2 at d&Ci4THI;3S9H[C0UCi4!(DJF!*H[C0UCi4THI=$<hH[C0fH[U6fI=$<hi8j)$s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8UNsejVtq779R:9MNsbf)PdMs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7crjQFt at f#u:^
+]=bhh]Y1qi]t:qj['[3P]Y1\Z[!-V6779R:9MJ,Q9hJ)R8k_s<Mi<"0I>j)CH[C0fH[U6fI=$<h
+H[C0fH[U6fI<TdTH[C0fH[TXFDL6_YC2 at d7H[U6fI=$<hR?Nj7s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9o:oC_>6n)39i
+i8j(Sgtp`>hV$]@g"bH4eCN'tf#u:^daZjkbg">Tc-k+mbKS5ZeCN'tf$`(!daZjreCN'tf$`(!
+g"bH;gtpuMkMYFai8j(bm-iW_hTO-f`5T^-]Y28&`OidrdaZk+jQGn$p&G'ls8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_JAp$D;C
+i8j(Sgtp`>hU9p)bKS5Sbg">Tc-k+mdaZjkbg">Tc-+>UdaZjreCN'tf%Jj8i8j(ZjQGann*KZ=
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,coC_JAp#tc2i8j(Sgtp`>hU9p)daZjd`Pod7`Pfa7`5T^=bg")F`Pfa7bKS5Sbg">Tc-+>U
+daZk$gtpuMkMYFai8j(foC_JAp$D;Co_/+QpA+ at Sq=OCVo_/+QpA+ at Sq>^Kps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9oBpA*q=n*KZ=
+kj7d%m-j0)n*'-,kj7d)oC_>6n*KZ=kj7d)oC_>6n+?>Lo_/+QpA+ at Sq=OCVs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags8W-!s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+g"bH;gtpK/f#u:^`5T^6`PoI%]h1sm at q9.cCi4!(DKg2EC2 at d&Ci4!(DKg2EC2 at d7H[TXFDJF!*
+C2 at d&Ci4!(DJF!*C2 at d7H[U6fI=$<hH[C1"Mi@]9s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s5;u$779R+4?Z.s4 at MY,8k_t-eCO["s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQdaZjkbg")F`Oidr['[3I['[HX]sP/R
+['[2><)l at T77p6J779R:9MJ,Q9m_58H[C1"Mi<"0I=$<hH[C0fH[U6fI=$<hH[C0fH[TXFDL6_Y
+C2 at d7H[U*[FE_hKC2 at d7H[Uj2N;rqXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9o:oC_JAp#+ooi8j(ZjQG4OhV$]@
+g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@i8j(ZjQGI^kMYFai8j(bm-j0)n*KZ=
+m.9o:oC_bLq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o:oC_>6n*'-,g"bH;gtpK/f%Jj8
+g"bH;gtpK/f%Jj8g"bH;gtp`>hV$]@i8j(ZjQGI^kNqg5m.9oBpA+ at Sq=OCVs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o:oC_JAp#+oo
+i8j(SgtpK/f$`(!daZjkbg"Scf$`(!daZjreCN'tf$`(!daZjreCN=.hV$]@i8j(bm-j<4p$D;C
+m.9oBpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+m.9oBpA+ at Sq=OCVo_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)bKS5Sbg")F`QQKM
+N/NWe9MK8<DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DKg2EC2 at d&Ci4!(DJF!*
+C2 at d7H[TXFDUR%cs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+ at Sq>^Kpkj7b;<)l"B4Zbbh
+4$5Yf4?Z;19o+IUs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7crjQFt@f#u:^`5T^-]Y1qi]sP/R]=bha['Z6bP=7l.779R56q'^A9gqH=
+=Bo0kMi<"0I=$<hH[C0fH[U6fI=$<hH[C0fH[TXFDL6_YH[C0UCi4THI;3S9C2 at d7H[TXFDKg2E
+N/NYps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<[_Gm.9o:oC_>6n*'-,i8j(ZjQGI^kLnYIi8j(Sgtp`>hV$]@
+g"bHBjQG4OhVdJXi8j(ZjQGI^kMYFakj7d%m-j<4p$D;Cm.9o:oC_bLq>^Kps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+(Hp$D;Cm.9o6m-ilnkMYFag"bH;gtp`>hV$]@g"bHBjQG4OhVdJX
+i8j(ZjQGI^kMYFakj7d)oC_JAp$D;Co_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp$D;Ckj7d%m-ilnkMYFag"bH4eCN'tf$`(!
+daZjreCN'tf$`(!daZk$gtp`>hV$]@i8j(ZjQGann*KZ=m.9o:oC_bLq=OCVs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags7H$\o_/+QpA+ at Sq=OCVm.9oBpA+ags7H$\o_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39idaZk#bfe2Rc, at T?bKS5N]Xg^/9knK^C2 at d&Ci4!(DJF!*
+C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*H[C0UCi4!(DJF!*C2 at d&Ci4!(DJF!*H[C2 at s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o:oC_>6n*KZ=m.9o6m-eFpAMl;$2)I-O4?Ybg4[hb- at q9.tH[WiO`W,u<
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQ
+g"bH-bg")F`O*"Z]=bha['[HX]sP/R at q9.>6q'O479)cB779R56q(TrAUAcPH[C0fH[U6fI=$<h
+H[C0fH[U6fI;3S9H[C0UCi4!(DL6_YC2 at d7H[TXFDL6_YC2 at d&Ci6&FV#UJps8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+o_/+IoC_JAp#tc2i8j(bm-ilnkMYFai8j(SgtpuMkLnYIi8j(Sgtp`>hV$]@i8j(ZjQGI^kMYFa
+i8j(bm-j0)n*'-,kj7d)oC_JAp$D;Co_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCV
+m.9o:oC_>6n*'-,i8j(ZjQG4OhV$]@g"bHBjQG4OhV$]@i8j(ZjQG4OhVdJXi8j(ZjQGann*'-,
+m.9o:oC_bLq=OCVo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp$D;Cm.9o6m-j0)n)39ii8j(Sgtp`>hU9p)daZk$gtpK/f%Jj8daZk$gtp`>hU9p)
+g"bH;gtpuMkMYFam.9o6m-j<4p$D;Co_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ags7H$\
+o_/+\s8V`bq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(SgtpK/f#u:^bKS5Sbg")F`Jf_68k_rhA7]LlDJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*
+C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci721`W,u<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n*'-,
+i8j(ZjQGI^kBhQ(/hAS31c.'H1cmf_4$5Z.>[Dc(I=$<hH[C2 at s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at Mkj7ckgtpK/f#u:^]=bhh]Y1\Z[(Eua
+['[31St&5;77KF&779R56q'O477BU5C2 at d7H[U6fI=$<hH[C0fH[TXFDL6_YC2 at d&Ci4!(DJF!*
+C2 at d&Ci4!(DJF!*H[C0UCi4!(DJF!*['[4?s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVm.9o6m-j0)n)39i
+i8j(ZjQG4OhVdJXg"bH;gtp`>hVdJXg"bHBjQG4OhVdJXi8j(ZjQGann)39ikj7d%m-j0)n*KZ=
+m.9oBpA+ at Sq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9o:oC_JAp#tc2kj7crjQGI^kLnYI
+g"bH;gtpuMkLnYIi8j(ZjQG4OhVdJXi8j(ZjQGI^kMYFakj7d%m-j0)n*KZ=m.9o:oC_JAp$D;C
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+(Hp$D;Cm.9o6m-j0)n*'-,
+i8j(ZjQG4OhV$]@g"bH4eCN'tf$`(!g"bH4eCN=.hU9p)daZk$gtp`>hVdJXi8j(ZjQGI^kNqg5
+m.9o:oC_bLq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq>^Kpo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-ilnkL.l2daZjkbg")F`Pfa7
+`5T\p<)mF=ARf7^@q9.\A7]LlDJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*
+C2 at d&Ci4!(DJF!*o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2i8j(Sgtp`>hV$]@R?Ngl1c-g9/N#@A
+/hAS31c.fu9m:]$GB at qRH[U6fI at Qn!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,coC_>6n(HLQdaZjkbg")F`Oidr['[3I['[3IZrgR>4$5Yf4?Z,$77BU5
+779R:9MKk\I=$<hH[C0fH[U6fI=$<hC2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DL6_Y
+C2 at d&Ci7\Nf)PdMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVm.9o:oC_JAp#tc2kj7crjQGI^kMYFai8j(SgtpuMkLnYI
+g"bH;gtpuMkLnYIi8j(ZjQGI^kMYFai8j(bm-j0)n*'-,m.9o:oC_JAp$D;Cm.9oBpA+(Hp%7tR
+o_/+\s8V`bq>^Kpo_/+\s8V`bq=OCVs8W,kpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+IoC_bLq<[_G
+o_/+IoC_bLq<[_Gm.9o:oC_>6n*'-,i8j(bm-ilnkMYFai8j(SgtpuMkLnYIg"bH;gtp`>hVdJX
+g"bHBjQG4OhVdJXi8j(ZjQGann)39ikj7d%m-j0)n*KZ=m.9o6m-j<4p$D;Cm.9o6m-j<4p#tc2
+kj7d%m-j0)n*'-,kj7d%m-j<4p#tc2kj7d%m-j0)n)39ii8j(ZjQG4OhV$]@g"bH;gtpK/f$`(!
+daZjreCN'tf%Jj8g"bH;gtpK/f%Jj8daZk$gtpuMkMYFakj7d)oC_JAp$D;Co_/+QpA+ags8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA*q=n)39ig"bH4eCMgec-+>UbKS5L`Pn7/P<1li at q9.\A7]7]ARf7^
+ at q9.\A7]LlDI[3gC2 at d&Ci4!(DJF!*@q9.\A7]7]ASQ%!C2 at d&Ci4!(DJF!*@q9/OXKDO&s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7ckgtp`>hU9p)daZjDV5-184Z,&Q/hAS,/1i_91cmf_C2 at d&Ci4!(DKg2E
+H[C0fH[WiO`W,u<s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<726
+i8j(SgtpK/f#5PH]=bhh]Y1qi]sP/RLkLFC4?Ybg4Zbbh4$5Yf4?Z,$7:Tk>H[C0fH[U6fI=$<h
+H[C0UCi4THI;3S9C2 at d&Ci3`nARf7^@q9.\A7]7]ARf7^C2 at d&Ci4!(DJF!*i8j)$s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\s8W,kpA+ags7H$\s8W,kpA+ at Sq>^Kpo_/+QpA+(Hp#tc2
+kj7d%m-j0)n)39ii8j(ZjQGI^kLnYIg"bH;gtpK/f$`(!bKS5ZeCN'tf$`(!bKS5ZeCN'tf$`(!
+daZjreCN'tf$`(!daZjreCN=.hV$]@g"bH;gtpuMkLnYIg"bH;gtp`>hV$]@g"bH;gtp`>hU9p)
+g"bH4eCN'tf$`(!daZjreCN'tf$`(!daZjreCMgec-k+mbKS5Sbg">Tc-+>UbKS5Sbg">Tc, at T?
+`5T^6`Pod7`Pfa7]=bhh]Y1qi]t:qj]=bhh]Y1qi]t:qj]=bhh]Y1qi]t:qj['[3P]Y1qi]t:qj
+]=bhh]Y1qi]t:qj]=bhh]Y1qi]sP/R]=bha['[3I[(Eua['[3I['[3I[(Eua['[3 at XKAk:[&^:1
+['[3 at XKAk:[&^:1X/rG(XKA:pUoUT!Unsl_V50WQS><!WS=Z7 at St)=BS><!WS=Z7 at St)=BS=H1@
+S=Z7 at St)=BS=H1 at Unsl_V50o`UoUT!X/rG(XKAk:['[3I['[3P]Y1qi^!"XEs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!kj7cF['Z?pS=H1 at S=Z7 at St)=BS=,S)S=Z7 at St)44PFS57S=Z7=PEVN.S=H1@
+S=Z70Mi=0tS=H1 at N/NXbSt)44PF7VuS=Z7=PEVDuPF7VuR?Ni&PEVDuPF7VuN/NX_PEVDuPF7Vu
+R?Ni&PEUr`N/W[RN/NX_PEUr`N/W[RR?NhnMi<UQN1#lnN/NXRMi<UQN/W[RN/NXRMi<UQN/W[R
+N/NXRMi<UQN/W[RLkLG;KS5/7KSY;7LkLG?Mi<IFKSY;7N/NXNKS5;BN/3.?LkLG;KS5/7KSY;7
+H[C1"Mi<IFKSY;7H[C0sKS4]!I>3,rH[C0fH[U^'KR8&oH[C0qI!^3eI=$<hH[C0fH[U6fI=$<h
+H[C0fH[U6fI=$<hH[C0bFEDkVI<TdTGB at qNFED_KFE_hKGB@qNFED_KFE_hKGB at qNFED86DKg2E
+C2 at d3FED86DKg2EC2@d3FED86DKg2EC2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*
+C2 at ctA7]LlDI[3gC2 at ctA7]LlDI[3gC2 at ctA7]LlDJ*3X at q9.\A7]7]AS57O at q9.\A7]7]ARf7^
+ at q9.\A7\kJ?>!MH=Bo0F>Zt67?=RMW=Bo0F>Zt67?>!MH=Bo07>[CB/<ENL4<)ck">[CB/<ENL4
+<)ck">[CB/<ENL4<)cjs<)lms<E)pt<)cjs<)lms<E)pt<)cjs<)lOa9it([8k_r]9LqcL9it([
+8k_rO9MJV_84lQM=A27X9MIrD77p6J779R:9MJ,Q9gqH==A27X9MIrD77p6J779R56q'O477BU5
+779R56q'O477BU5779R56q'O477KF&4$5Yp6q'1"4[qRs4$5Yq4Zkeg4[qRs4$5Yq4Zkeg4Z,&Q
+4$5Y`1c.9V4Z,&Q4$5Y`1c.9V4Z,&Q4$5Y`1c.'H1c7*H2)I-I1c.'H1c7*H2)I-I1c.'H1c7*H
+/hAS31c-g9/M8S+/hAS,/1i_91bL=22)I-I1c.'H1bL=22)I-B/1iJ*/M8S+/hASe>[%1-s6T at M
+kj7crjQG4OhU9p)bKS5L`Pod7`Pfa7<)cjs<)mF=ARf7^=Bo0BA7]7]AQW2D at q9.Q>[CoNAQW2D
+ at q9.\A7]7]AQW2D at q9.cCi3`nARf7^@q9.\A7]7]AaK$]s8W-!s8W-!s8W-!s8W-!s8W-!s+YoJ
+'b1Zk)]BG$%2B?^)B0S0%Lj-_%2B?^'b1Zf%Lj-_%2B?^'b1Zf%Lj-_%2B?^$k!IP$OdFO$l'6]
+$k!IY%Lj-_%2B?^'b1Zf%Lj-_%H-=1s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-iW_hV$]@
+daZjkbg!N%ZpdAO2)I-I1c.'H1bL=24$5Z9A7]7]ASQ%!C2 at d3FEDkVI<TdTH[C1ogtr)2s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!m.9o6m-iW_hV$]@bKS5L`Pod7`Oidr
+['[3!Mi9_[4Z,&Q4$5Yf4?Ybg4[hb-779RZCi4THI=$<hH[C0UCi4THI;3S9C2 at d&Ci4!(DJF!*
+ at q9.\A7]7]AQW2D=Bo07>[CoNARf7^C2 at d7H[Xi5k7nI9"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-">25WH[C1abg$1fs8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V<Ln$KI/C2 at c+)]Ah\"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"B\o8o_/+Em-ilnkLnYIdaZjkbg">Tc, at T?
+`5T]cSt%Yp1h1'- at q9.Q>[CoNARf7^@q9.\A7\kJ?=RMW=Bo07>[CoNAQW2D at q9.\A7]7]ARf7^
+ at q9.\A7]7]AQW2DS=Z8Ns8W-!s8W-!s8W-!s8W-!s7H$\i8j&(!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]O,:*<hs8W-!s8W-!s8W-!s8W-!s8W,coC_>6n(HLQg"bH4eCMgec+CX%<)cjZ4?YPY1c7*H
+2)I-O4?ZeO?>=:o at q9.cCi4!(DJF!*C2 at d3FEDkVI>j)CdaZkJs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,coC_>6n)39ig"bH4eCN'tf#5PH]=bha['Y1,I5Ni<2)I-I1c.9V4Z,&Q
+4$5Yf4?ZeO?@.$IC2 at d7H[TXFDL6_YC2 at d7H[TXFDJF!*C2 at ctA7]7]ARf7^=Bo0BA7\kJ?<CH=
+ at q9.\A7]LlDOd;gS=Z5R!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]`1c0Q+IF?Wrs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/*m]Y/&rDBpGP"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J_<]Y3\'p#tc2i8j(Sgtp]-bKJ,SbKS5L`Pod7`E6AO8k_rhA7\kJ?>=:o
+ at q9.\A7]7]ARf7^@q9.Q>[CoNARf7^@q9.\A7]7]ASQ%!@q9.Q>[CoNAQW2D at q9.Q>[H+=hZ*WU
+s8W-!s8V`bq=OCVm.9o:oC[<LF9DXJ"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/Unsmes8W-!s8W-!
+s8W-!s8V`bq<726i8j(SgtpK/f#u:^`5T]1Ci2<s4Zbbh2)I-I1c.'H1fRFSC2 at d&Ci4!(DJF!*
+C2 at d7H[U6fI=$<hGB at qRH[TXFDN'L4daZkJs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2
+i8j(ZjQFt at f#u:^`5T^6`Pn@=S4ZIL/hAS,/1iJ*/M8S+2)I-I1c.9V4[hb-C2 at d&Ci4H=FD>W0
+H[C0UCi4!(DJF!*C2 at ctA7]7]AQW2D at q9.\A7]7]ARf7^=Bo0BA7]7]ASQ%!C2 at dp['VG:/Hc+X
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/
+"9J]/!X&W-"9\c/"9J]/!X&W-"9\c/(BO^B!X&W-"9\c/(BO^B!X&W-"9\c/(BO^B!X';@"9\c/
+(BO^B!X';@"9\c/(BO^B!X';@"9\c/(BO^U!X&W-";_+B(BO^U!X&W-";_+B(BO^U!X&W-";_+B
+(BO^U!X';@";_+B(BO^U!X';@";_+B(BO^U!X';@";_+B(BO^U!X';@";_+B(BO^U!X';@";_+B
+(BO^U!X';@";_+B(BO^U!X';@";_+B(BO^U!X';@";_+B(BO^e!X';@"=F6R(BO^e!X';@"=F6R
+(BO^U!X'kP";_+B-NXDe!X'kP";_+B-NXDe!X'kP";_+B-NXDe!X'kP"=F6R-NXDu!X'kP"=F6R
+-NXDu!X'kP"=F6R-NXDu!X'kP"=F6R-NXDu!X'kP"=F6R-NXDu!X'kP"=F6R-NXDu!X'kP"=F6R
+-NXDu!X'kP"=F6R-NXDu!X)U,"K"R;ke+/"s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W+r>=DWq"?HSe
+3W]FF!X(Oc"?HSe3W]FF!X)$q"?HSe3W]FF!X(Oc"@rRs3W]FF!X)$q"?HSe3W]FT!X)$q"?HSe
+8-/ob!X(Oc"@rRs8-/oT!X)$q"@rRs8-/ob!X)$q"@rRs8-/ob!X)$q"@rRs8-/ob!X)$q"@rRs
+8-/ob!X)$q"@rRs8-/ob!X)$q"@rRs8-/or!X)$q"BY^.8-/ob!X)U,"@rRs=98Ur!X)U,"@rRs
+=98V-!X)$q"BY^.=98V-!X)U,"BY^.=98V-!X)U,"BY^.=98V-!X)U,"BY^.=98V-!X)U,"BY^.
+=98V-!X)U,"BY^.=98V=!X)U,"BY^.=98V-!X*0<"BY^.=98V=!X)U,"D at i>=98V=!X)U,"D at i>
+=98V=!X)U,"D at i>BEA<M!X*0<"D at i>BEA<M!X*0<"D at i>BEA<M!X*0<"D at i>BEA<M!X*0<"D at i>
+BEA<M!X*0<"D at i>BEA<M!X*0<"F1%OBEA<M!X*cM"D at i>BEA<M!X*cM"D at i>Gle+^!X*cM"D at i>
+Gle+o!X*0<"F1%OGle+^!X*cM"F1%OGle+o!X*cM"F1%OGle+o!X*cM"F1%OGle+o!X*cM"F1%O
+Gle+o!X*cM"F1%OGle+o!X*cM"F1%OGle,)!X*cM"Gd*^Gle,)!X*cM"Gd*^Gle,)!X*cM"Gd*^
+L]R^8!X+;\"F1%OL]R^8!X+;\"Gd*^L]R^8!X+;\"Gd*^L]R^8!X+;\"Gd*^L]R^8!X+;\"Gd*^
+L]R^8!X+;\"Gd*^L]R^8!X+;\"Gd*^L]R^8!X+;\"Gd*^L]R^D!X+_h"Gd*^PQCuP!X+;\"I&rj
+PQCuD!X+_h"I&rjPQCuP!X+_h"I&rjPQCuP!X+_h"I&rjPQCuP!X+_h"J>f!PQCu\!X+_h"J>f!
+PQCu\!X+_h"J>f!PQCu\!X,.t"J>f!PQCu\!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X-G"3:-80
+p[%)$jQG4OhU9p)bKS5Sbg")F`Pfa7UnskK4?ZeO?<CH==Bo0ICi4!(DI[3gC2 at ctA7]7]ARf7^
+=Bo0BA7]7]ARf7^@q9.cCi4!(DI[3g at q9.Q>[CN;?Asf$s8W-!s8W-!s7H$\m.9o6m-j0)n(HLQ
+"9J]/!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X-7T)#sX9s8W-!s8W-!s6T at Mkj7crjQFt@f$`(!
+bKS5SbftK]I76Om779R+4?Ybg4Z,&Q<)ck4Ci3`nASQ%!C2 at d&Ci4!(DJF!*C2 at d&Ci4THI;3S9
+H[C0NA7[hb4_['[4,oC`.`s8W-!s8W-!s8W-!s6T at Mm.9o.jQGI^kL.l2daZjd`PmdoN(Qc<
+/hAS",:"lm/M8S+/hAS,/1iJ*/N#@A4$5Z.>[D/]DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci3`nARf7^
+ at q9.\A7\kJ?=RMW=Bo0ICi4!(DJF!*C2 at d&Ci4THIB0HO"9J]/!X&W-"9\c/"9J]/!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:99!X,.t"LA.4
+ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,.t"LA.4TE57h!X,h2"J>f!TE58&!X,.t"J>f!
+ZN:9&!X,.t"J>f!ZN:9&!X,.t"J>f!ZN:9&!X,.t"J>f!ZN:9&!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X+_h"J>f!PQCu\!X+_h"J>f!PQCu\!X+_h"J>f!
+PQCu\!X,.t"J>f!PQCu\!X,.t"I&rjTE57h!X+_h"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"O(=ds8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7ta7`&9TJ!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!
+ZN:9&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,.t"LA.4ZN:99!X,.t"LA.4
+ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"M>*PZN:9B$P'fW%^Q3>
+]F,4^$P'KE"M>*P]F,4U!X-.D%^Q3>ZN:99!X,h2"LA.4]F,4U!X,h2"LA.4ZN:99!X-.D%^Q3>
+ZN:99!X,h2"LA.4]F,4U!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:9B$P'fW%^Q3>ZN:9B$P'KE"M>*PZN:99!X,h2"LA.4kbX@(m-j0)n)39ig"bH4eCMgec-+>U
+`5T^6`Pkqa?:mmc at q9.\A7]7]ARf7^C2 at ci>[CoNARf7^=Bo07>[CN;?=RMW=Bo0BA7]7]ASQ%!
+ at q9.Q>[CoNARf7^=Bo1\eCO9cq=OCVm.9o6m-ilnkMYFag"bG.FE at We"?HSeZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:9pHsZjQs8W-!o_/+IoC_&&kLnYIdaZjkbg">Tc'acZ4$5Yf4?Z,$77BU5
+4$5Yu9MK8<DJF!*C2 at d&Ci4!(DJF!*C2 at d&Ci4!(DL6_YC2 at d&Ci4H=FD>W0C2 at cL4?YPY1cmf_
+ at q9/=PEWr(`S'&'m.9o6m-ilnkLnYI]=bh9Mi;.VAM,Mc,U4Q[,:"NZ,VCW"/hAS,/1iJ*/M8S+
+/hAS31c/02<GH>fC2 at d&Ci4!(DJF!*C2 at d&Ci4!(DJF!*@q9.Q>[CoNAQW2D=Bo07>[D/]DJF!*
+C2 at d&Ci4THI;3S9N/NWe9MGWk"9\c/"9J]/!X&W-"BY^.TE58&!X,h2"J>f!ZN:99!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,.t"J>f!ZN:9&!X,.t"LA.4TE57h!X,h2"J>f!
+TE57h!X,h2"J>f!TE57h!X,.t"LA.4TE57h!X,h2"J>f!TE58&!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+PQCu\!X,.t"I&rjTE57h!X,.t"I&rjTE57h!X+_h"J>f!TE57\!X,.t"I&rjTE57\!X,.t"I&rj
+TE57\!X,.t"I&rjTE57\!X+_h"J>f!PQCu\!X+_h"I&rjPQCuP!X+_h"I&rjTE57\!X,eG)X5f(
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq:L@<ZN:9&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE58&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,h2"J>f!ZN:99!X,.t"LA.4ZN:99!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"M>*PZN:99!X,h2"LA.4ZN:99!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P
+]F,4U!X-.D%_N/Z]F,4U!X-.D%_N/Z]F,4^$P'fW%^Q3>]F,4^$P'fW%_N/Z]F,4^$P'KE"M>*P
+]F,4^$P'fW%_N/Z]F,4^$P'fW%^Q3>]F,4^$P'KE"M>*P]F,4^$P'KE"M>*P]F,4^$P'KE"M>*P
+ZN:99!X,h2"M>*P]F,4^$P'fW%_N/Z]F,4^$P'KE"M>*P]F,4^$P'KE"M>*PZN:9B$P'KE"M>*P
+ZN:9B$P'KE"M>*P]F,4f,:)L>n*'-,i8j(SgtpK/f%A3ibKS5L`Pod7`MB?+4$5Z.>[CoNAQW2D
+ at q9.\A7]7]ARf7^@q9.Q>[CN;?<CH==Bo07>[CoNAQW2D=Bo0BA7]LlDI[3g at q9.\A7^RMK^A='
+o_/+IoC_&&kMYFag"bH;gtp]-b6.kL"9J_!!X,h2"LA.4ZN:9B$P'KE"LA.4]F,4U!X-.D%^Q3>
+ZN:9B$P'KE"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ji#%.pA*q=n)39ig"bH;gtp5uc-+>UUnskK4?YPY1cmf_779R+4?Z;19m_58C2 at d7H[TXFDJF!*
+C2 at d&Ci3`nARf7^C2 at d&Ci4!(DL6_YC2 at d&Ci4!(DI[3g8k_r:1c.'H1aF:k/hAS",:#?54Zbbh
+779Qs/1hbZ)B'P5)B0S5)]BtH,U=T[,U4Q[,:"NZ,VCW"/hAS",:#-'1fRFS at q9.\A7]7]ARf7^
+ at q9.cCi3`nASQ%!@q9.\A7]7]AQW2D=Bo0BA7]7]ARf7^C2 at d&Ci4!(DJF!*C2 at d&Ci5c7S-/lr
+"9J]/!X&W-"9\c/"9J_!!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE57h!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,.t"LA.4
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE57h!X,h2"J>f!TE58&!X,.t"J>f!ZN:9&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57\!X,.t"J>f!TE57h!X+_h"J>f!PQCu\!X+_h"J>f!PQCu\!X,.t"I&rjTE57h!X+_h"J>f!
+PQCu\!X,.t"I&rjTE57h!X+_h"J>f!TE57h!X+_h"J>f!TE57\!X,.t"J>f!PQCu\!X+_h"J>f!
+PQCu\!X+_h"I&rjTE57\!X,.t"J>f!PQCu\!X+_h"I&rjTE57h!X.28GlRgDs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8U]h]tYC$TE57h!X,h2"J>f!TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:99!X,.t"LA.4ZN:9&!X,h2"LA.4TE58&!X,h2"J>f!ZN:99!X,h2"J>f!ZN:99!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:99!X,h2"LA.4TE58&!X,h2"LA.4
+ZN:99!X,.t"LA.4TE58&!X,.t"LA.4ZN:9&!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:9B$P'KE"M>*PZN:9B$P'KE"LA.4
+ZN:99!X,h2"M>*PZN:99!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'fW%_N/Z]F,4^$P'fW%_N/Z
+ZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P
+ZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*P]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%^Q3>
+]F,4^$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*P]F,4U!X-.D%_N/Z]F,4U!X-.D%^Q3>
+]F,4U!X,h2"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%_N/Z]F,4U!X-.D%^Q3>]F,4U!X,h2"Qc//
+kj7d%m-ilnkLnYIdaZjkbg">Tc, at T?bKS4 at A7\A,9k.^F at q9.\A7]7]AQW2D=Bo07>[CN;?<CH=
+=Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo0BA7]7]ARf7^`5T^^oC_JAp#+oog"bH;gtpK/f#u:^
+H[C/D!X'kP"LA.4ZN:9B$P'KE"M>*PZN:9B$P'KE"LA.4ZN:9B$P'KE"LA.4]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,_S.,!D4kj7ckgtp`>hTO-f
+bKS5L`Pl=tAM,Mc/hAS31c.9V4[hb-GB at qRH[U6fI<TdTC2 at d&Ci4!(DI[3g at q9.Q>[D/]DJF!*
+C2 at d&Ci4!(DJF!*C2 at d&Ci3`nAQW2D779R%1c-I&,VCW")B0S5)]BV6)B'P5)B0S?,:"0H)B'P5
+,U4QQ)]BV6)C-OQ,U4Q[,:#-'1eLG9=Bo07>[CN;?<CH==Bo0BA7]7]ARf7^=Bo0BA7]7]ARf7^
+=Bo0BA7\kJ?=RMW at q9.\A7]LlDI[3gC2 at d&Ci4THI=$<h8k_q^!X&W-"9\c/"9J]/!X'kP"LA.4
+TE58&!X,h2"LA.4TE58&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4
+TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4TE58&!X,.t"LA.4
+TE57h!X,h2"J>f!TE58&!X,.t"J>f!TE57h!X,h2"J>f!ZN:9&!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"LA.4TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X+_h"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"I&rjTE57h!X,.t"I&rjTE57h!X,.t"I&rjTE57h!X+_h"J>f!
+PQCu\!X+_h"J>f!TE57\!X,.t"I&rjTE57\!X,.t"J>f!PQCu\!X,.t"I&rjTE57\!X,.t"I&rj
+PQCuP!X,.t"I&rjTE57\!X,.t"I&rjTE58#-7J]NiW&rXs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+=jQFQg9sXm(
+TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4
+ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,h2"J>f!ZN:99!X,h2"LA.4ZN:9&!X,h2"J>f!
+ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4
+ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"J>f!ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:9B$P'KE"LA.4]F,4U!X,h2"LA.4
+]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>ZN:99!X,h2"LA.4]F,4^$P'KE"M>*PZN:9B$P'KE"M>*P
+ZN:9B$P'KE"LA.4]F,4U!X-.D%^Q3>ZN:99!X,h2"LA.4ZN:99!X-.D%^Q3>]F,4U!X-.D%_N/Z
+ZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%^Q3>ZN:9B$P'KE"M>*P
+ZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'fW%_N/ZZN:9B$P'KE"M>*P
+]F,4U!X-.D%^Q3>]F,4^$P'fW%^Q3>]F,4U!X-.D%_N/Z]F,4^$P'KE"LA.4]F,4U!X-.D%_N/Z
+ZN:9B$P'fW%^Q3>]F,4U!X-.D%_N/Z]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'fW%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*P]F,4U!X-.D%_N/Z^DIgGjQGann)39ig"bH4eCMgec-+>U
+bKS5L`PnXLUcU\%=Bo0BA7]7]ARf7^@q9.\A7\kJ?=RMW=Bo07>[CN;?<CH=<)ck">[CN;?<CH=
+=Bo0BA7\kJ?=RMW at q9.tH[Y8Pp$D;Ci8j(ZjQFt at f#u:^bKS5Sbfpq*"9\c/PQD!#$P'KE"LA.4
+]F,4U!X,h2"LA.4ZN:9B$P'KE"LA.4]F,4U!X,h2"M>*PZN:99!X-.D%^Q3>ZN:99!X,h2"M>*P
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:9.AQ7@<hV$]@daZjkbg")F`Pfa7UnskE1c-g9/M8S+
+4$5Z9A7]t,FD>W0C2 at d3FED86DJF!*@q9.\A7]7]AQW2D at q9.cCi4!(DJF!*C2 at d&Ci4!(DHL.M
+ at q9.\A7]7]AQW2D8k_r:1c-g9/L2Pd)B0S5)]BV6)B'P5)B0S5)]BV6)C-OQ)B0S?,:"lm/P8]2
+<)ck">[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CoNARf7^
+ at q9.cCi4!(DJF!*C2 at dHMi7c?"9\c/"9J]/!X&W-"9\c/L]R^c!X,h2"J>f!ZN:9&!X,h2"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,h2"LA.4TE57h!X,h2"J>f!
+TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE58&!X,.t"LA.4TE57h!X,.t"J>f!ZN:9&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,h2"J>f!
+TE58&!X,.t"J>f!TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"I&rjTE57h!X+_h"J>f!TE57h!X+_h"J>f!TE57\!X,.t"I&rj
+TE57h!X,.t"I&rjTE57h!X,.t"I&rjTE57h!X,.t"I&rjTE57h!X+_h"J>f!TE57\!X,.t"I&rj
+TE57\!X,.t"J>f!PQCu\!X+_h"J>f!PQCu\!X+_h"J>f!PQCu\!X,.t"I&rjTE57\!X,.t"I&rj
+TE57\!X+_h"J>f!TE58NUQb`Xs8W-!s8W-!s8W-!s7H$\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7cZUn+gn"J>f!ZN:9&!X,.t"LA.4
+TE57h!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,h2"LA.4TE58&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,.t"LA.4ZN:99!X,h2"J>f!ZN:99!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,.t"LA.4
+ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4]F,4U!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"M>*PZN:99!X-.D%^Q3>
+ZN:9B$P'KE"M>*PZN:9B$P'KE"LA.4]F,4U!X,h2"LA.4]F,4U!X,h2"M>*PZN:9B$P'KE"LA.4
+]F,4U!X-.D%_N/Z]F,4^$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*P]F,4U!X-.D%^Q3>]F,4U!X-.D%_N/ZZN:9B$P'fW%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'KE"M>*P]F,4^$P'KE"M>*P
+ZN:9B$P'fW%_N/ZZN:99!X-.D%_N/Z]F,4^$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%_N/Z]F,4U!X-.D%^Q3>]F,4^$P'fW%^Q3>]F,4U!X-.D%_N/Z
+]F,4U!X-.D%^Q3>]F,4U!X.\EETlcXi8j(`gt^T<hU9p)bKS5Sbg")F`Pfa7 at q9.C9MJVo?<CH=
+=Bo07>[CoNAQW2D=Bo07>[CoNAQW2D=Bo07>[CN;?<CH==Bo07>[CN;?<CH=@q9.Q>[CoNA[JhO
+m.9o6m-iW_hU9p)daZjkbg")F`JB2#"9J]B!X,h2"LA.4]F,4U!X,h2"M>*PZN:9B$P'KE"M>*P
+ZN:9B$P'KE"LA.4]F,4U!X,h2"M>*PZN:99!X-.D%^Q3>ZN:99!X,h2"M>*PZN:99!X-.D%^Q3>
+ZN:99!X,h2"J>f!\"o\FeCMgec, at T?`5T^6`PoI%]o7l./hAS31c/02<GH>fC2 at d&Ci4!(DJF!*
+ at q9.\A7]7]ARf7^@q9.\A7]7]ARf7^@q9.\A7]7]ARf7^=Bo0BA7\kJ?=RMW at q9.\A7]7]AQW2D
+=Bo0)9MIT24YA9;)B0S5)]BtH,U=T[,U4Qe/1iqG4\ACB<)cji9MJ,Q9iP(l8k_rO9MJ,Q9iP(l
+8k_rO9MJ,Q9hJ)R=Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo0BA7]7]ASQ%!C2 at d7H[U6fI76Om
+"9J]/!X&W-"9\c/"9J]B!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,.t"LA.4ZN:9&!X,h2"J>f!
+ZN:99!X,.t"LA.4TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:9&!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,.t"LA.4
+TE57h!X,.t"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!TE57h!X,.t"J>f!TE58&!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!ZN:9&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X+_h"J>f!TE57\!X,.t"I&rjTE57h!X+_h"J>f!
+PQCu\!X,.t"I&rjTE57h!X+_h"J>f!PQCu\!X+_h"J>f!PQCu\!X,.t"I&rjTE57\!X,.t"I&rj
+TE57h!X+_h"J>f!PQCu\!X+_h"I&rjTE57\!X+_h"J>f!PQCuP!X+_h"J>f!PQCu\!X+_h"J>f!
+cV74!m-juSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!o_/+QpA*q=n)39ifZ_OL7OOi1"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,h2"J>f!ZN:9&!X,h2"LA.4TE58&!X,.t"LA.4
+TE58&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,h2"J>f!ZN:99!X,h2"LA.4TE58&!X,h2"LA.4
+ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4ZN:99!X,.t"LA.4
+ZN:99!X,h2"LA.4TE58&!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:9B$P'KE"M>*PZN:99!X,h2"LA.4ZN:9B$P'KE"LA.4ZN:9B$P'KE"LA.4
+]F,4U!X,h2"LA.4]F,4^$P'KE"LA.4]F,4U!X,h2"M>*PZN:9B$P'KE"LA.4]F,4U!X,h2"LA.4
+ZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P
+]F,4U!X-.D%^Q3>]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%_N/Z
+ZN:9B$P'KE"M>*P]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*PZN:9B$P'fW%_N/ZZN:9B$P'fW%_N/Z
+ZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'fW%^Q3>
+]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4U!X,h2"M>*PZN:9B$P'KE"MYcj
+k1nbUm-ilnkLnYIdaZk#bfe2Rc, at T?`5T]rXK=*+/Qc7a=Bo07>[CN;?<CH=@q9.\A7]7]AQW2D
+=Bo07>[D/]DHL.M=Bo0BA7]LlDI[3g=Bo0BA7]7]ARf7^C2 at eOm-j0)n)39ig"bH;gtp5uc, at T?
+`5T\6)]Ah\"Gd*^ZN:99!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X,h2"LA.4ZN:9B$P'KE"LA.4
+]F,4U!X,h2"LA.4ZN:99!X,h2"M>*PZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X+;\"N89u
+`5T^6`Pod7`Oidr]=bhh]Y.EP?:@7N=Bo0BA7]7]ARf7^@q9.\A7\kJ?=RMW=Bo07>[CoNARf7^
+ at q9.\A7]7]ARf7^@q9.Q>[CN;?<CH=@q9.Q>[CoNAQW2D=Bo07>[CN;?<CH==Bo03<)lms<D#qZ
+8k_rY<)lms<E)pt<)cji9MJ,Q9hJ)R8k_rO9MJ,Q9hJ)R8k_rJ6q'O477BU58k_rO9MJ,Q9hJ)R
+8k_rY<)lms<E)pt8k_rO9MJVo?<CH==Bo0BA7]7]ASQ%!H[C/D!X&W-"9\c/"9J]/!X&W-"F1%O
+ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4TE57h!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,.t"LA.4TE57h!X,.t"LA.4TE57h!X,.t"LA.4TE58&!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"LA.4TE58&!X,.t"J>f!TE57h!X,h2"J>f!TE57h!X,h2"J>f!
+TE57h!X,.t"J>f!TE57h!X,h2"J>f!TE57h!X,.t"J>f!TE57h!X,.t"LA.4TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"I&rjTE57h!X,.t"J>f!PQCu\!X,.t"J>f!
+TE57\!X,.t"J>f!TE57\!X,.t"J>f!TE57h!X,.t"I&rjTE57h!X,.t"J>f!PQCu\!X+_h"J>f!
+PQCu\!X,.t"I&rjTE57h!X,.t"J>f!PQCu\!X,.t"I&rjTE57\!X,.t"I&rjTE57\!X,.t"I&rj
+TE57\!X,.t"I&rjTE57\!X,.t"I&rjTE57\!X,.t"I&rjTE57\!X,.t"J>f!ke+/"s8W-!s8W-!
+s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+m.9o6m-j0)n)39iaGYJQ!X,.t"J>f!TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:99!X,.t"LA.4TE58&!X,h2"LA.4TE58&!X,h2"J>f!ZN:99!X,h2"J>f!ZN:99!X,.t"LA.4
+ZN:99!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,h2"LA.4TE58&!X,.t"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"J>f!ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"M>*PZN:99!X-.D%^Q3>
+ZN:99!X,h2"LA.4]F,4U!X,h2"LA.4]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*PZN:9B$P'KE"LA.4
+]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*PZN:9B$P'fW%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4^$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%_N/Z
+ZN:9B$P'fW%_N/ZZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>
+]F,4^$P'KE"M>*PZN:9B$P'KE"M>*P]F,4U!X-.D%_N/ZZN:9^KPp#?n)39ii8j(SgtpK/f#u:^
+`5T^6`Pp$Ec!t9q4$5Z.>[CN;?<CH==Bo07>[CN;?=RMW at q9.\A7]7]ARf7^C2 at ctA7]LlDI[3g
+ at q9.\A7]7]AQW2D=Bo07>[FeE[-[DWm.9o6m-iW_hV$]@daZjreCM"6ZigF5(BO`G!X,h2"M>*P
+ZN:99!X-.D%^Q3>ZN:99!X,h2"M>*PZN:9B$P'KE"LA.4]F,4U!X,h2"M>*PZN:9B$P'KE"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:8W3]t@"`Pfa7]=bhh]Y1qi]t:qj
+X/rF<Ci3`nAQW2D at q9.Q>[CN;?<CH==Bo07>[CN;?<CH==Bo0BA7\kJ?=RMW=Bo0BA7\kJ?<CH=
+=Bo07>[CN;?=RMW at q9.\A7]7]AQW2D=Bo07>[CB/<E)pt<)cjs<)lms<D#qZ8k_rO9MJ,Q9hJ)R
+8k_rO9MIrD77BU5779R56q'O477BU5779R:9MIrD77BU58k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9itY,
+=Bo07>[CN;?=RMW at q9.tH[Uj2N!'1b"9J]/!X&W-"9\c/(BO`G!X,.t"LA.4ZN:9&!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,.t"LA.4TE58&!X,.t"LA.4TE57h!X,.t"LA.4TE58&!X,.t"LA.4
+TE57h!X,.t"LA.4TE57h!X,h2"J>f!TE57h!X,.t"J>f!TE58&!X,.t"LA.4TE57h!X,h2"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,h2"J>f!TE57h!X,h2"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!PQCu\!X,.t"J>f!TE57\!X,.t"J>f!
+TE57\!X,.t"I&rjTE57h!X+_h"J>f!PQCu\!X,.t"I&rjTE57h!X+_h"J>f!PQCu\!X+_h"I&rj
+TE57\!X,.t"I&rjTE57h!X+_h"J>f!PQCu\!X+_h"I&rjTE57\!X+_h"J>f!PQCu\!X+_h"I&rj
+TE57\!X+_h"I&rjTE57\!X+_h"I&rjPQCu\!X+_h"O(=ds8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVkj7d%m-ilnkLdGU
+`%3U8!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,h2"J>f!TE58&!X,.t"LA.4TE57h!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,h2"J>f!ZN:9&!X,h2"LA.4
+TE58&!X,.t"LA.4TE58&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4
+ZN:9&!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,h2"LA.4TE58&!X,h2"J>f!ZN:99!X,.t"LA.4
+ZN:99!X,h2"LA.4TE58&!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"M>*PZN:99!X,h2"M>*P
+ZN:9B$P'KE"LA.4ZN:99!X,h2"M>*PZN:99!X-.D%^Q3>]F,4U!X,h2"M>*PZN:9B$P'KE"LA.4
+]F,4U!X-.D%^Q3>]F,4U!X,h2"M>*PZN:9B$P'KE"M>*PZN:9B$P'KE"LA.4]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4U!X-.D%_N/Z
+ZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4^$P'KE"M>*P
+ZN:9B$P'fW%^Q3>]F,4U!X-.D%_N/Z]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*PZN:9B$P'fW%^Q3>
+]F,4^$P'KE"M>*P]F,4^$P'KE"M>*PZN:9B$P'fW%^Q3>ZN:9B$P'fW%^Q3>]F,4U!X-.D%^Q3>
+]F,4^$P'KE"M>*PZN:9B$P'fW%d)R%kj7d%m-iW_hU9p)bKS5Sbg">Tc, at T?['[1m/1jIf9iP(l
+<)cji9MJJc<ENL4=Bo07>[CN;?<CH=@q9.\A7]LlDJF!*@q9.cCi4!(DI[3g at q9.Q>[CN;?>=:o
+m.9oBpA+ at Sq<[_Gkj7ckgtp`>hV$]@`5T[u!X*cM"LA.4ZN:99!X-.D%^Q3>ZN:9B$P'KE"M>*P
+ZN:99!X-.D%^Q3>]F,4U!X,h2"M>*PZN:99!X,h2"LA.4]F,4U!X,h2"M>*PZN:99!X-.D%^Q3>
+ZN:99!X,h2"LA.4ZN:99!X,h2"J>f!Q]-g?`PoI%]u7n/]=bhh]Y1qi]qhL#@q9.Q>[CN;?<CH=
+=Bo07>[CN;?;sm(<)ck">[CN;?<CH==Bo07>[CoNAQW2D at q9.\A7\kJ?=RMW=Bo0BA7]7]ARf7^
+ at q9.\A7\kJ?<CH==Bo07>[CN;?;sm(<)cji9MJ,Q9hJ)R779R56q'1"4[hb-779R56q'O477BU5
+779R56q'O477BU5779R56q'O476<Up779R:9MJ,Q9hJ)R8k_rO9MJ,Q9itY, at q9.\A7]7]AXo?^
+bKS5<['V(s(^'mC"9J]/!X*cM"J>f!ZN:99!X,.t"LA.4TE58&!X,h2"J>f!ZN:99!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!TE58&!X,.t"LA.4
+TE58&!X,.t"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,.t"J>f!TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!
+TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE57h!X,.t"J>f!TE57h!X,.t"LA.4TE57h!X,.t"LA.4
+TE58&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!ZN:9&!X,.t"J>f!TE57h!X,h2"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57\!X,.t"J>f!TE57h!X,.t"J>f!TE57\!X,.t"J>f!TE57h!X+_h"J>f!TE57h!X+_h"J>f!
+TE57\!X,.t"J>f!PQCu\!X,.t"I&rjTE57h!X+_h"J>f!TE57h!X+_h"J>f!PQCu\!X+_h"I&rj
+TE57\!X,.t"I&rjPQCu\!X+_h"J>f!PQCu\!X+_h"I&rjTE57\!X+_h"J>f!PQCu\!X+_h"I&rj
+PQCu\!X+_h"J>f!PQCuP!X,eG)Ud-ds8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8VHWp$D;Ckj7d%m-iW_hT0eFZN:9&!X,h2"J>f!
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,h2"J>f!ZN:9&!X,h2"LA.4TE58&!X,.t"LA.4ZN:9&!X,h2"J>f!
+ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4ZN:9&!X,h2"LA.4ZN:9&!X,h2"LA.4ZN:9&!X,h2"LA.4
+TE58&!X,.t"LA.4TE58&!X,h2"LA.4TE58&!X,h2"LA.4ZN:99!X,.t"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+]F,4U!X,h2"LA.4]F,4U!X,h2"M>*PZN:99!X,h2"M>*PZN:99!X-.D%^Q3>ZN:9B$P'KE"M>*P
+ZN:99!X-.D%^Q3>ZN:99!X,h2"M>*PZN:99!X,h2"LA.4]F,4U!X-.D%^Q3>ZN:9B$P'KE"M>*P
+ZN:9B$P'KE"LA.4]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>ZN:9B$P'KE"M>*P
+ZN:9B$P'KE"M>*P]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%_N/Z]F,4U!X-.D%_N/ZZN:9B$P'KE"M>*P]F,4^$P'fW%^Q3>]F,4U!X-.D%^Q3>
+]F,4U!X-.D%^Q3>]F,4^$P'KE"M>*PZN:9B$P'fW%^Q3>]F,4^$P'KE"M>*PZN:9B$P'KE"M>*P
+fQCHnm-!<fkN:RTg"bH4eCMgec-+>U`5T^6`PlS.DD!Il<)cji9MJJc<E)pt=Bo0)9MJVo?<CH=
+=Bo0BA7\kJ?=RMWC2 at ctA7]7]ASQ%!C2 at ctA7\kJ?<CH==Bo1.V53bWq>^Kpo_/+IoC_>6n*'-,
+i8j(SgtpuMk;iYIZN:99!X,h2"M>*PZN:99!X-.D%^Q3>ZN:9B$P'KE"M>*PZN:99!X,h2"M>*P
+ZN:99!X-.D%^Q3>ZN:9B$P'KE"LA.4]F,4U!X,h2"M>*PZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,#/'ZRes]=bhh]Y1qi]t:qj]=bhh]Y0_sP?;'r<)cjs<)lms<D#qZ8k_rY<)lms<E)pt
+=Bo07>[CN;?<CH==Bo0BA7\kJ?=RMW=Bo07>[CN;?=RMW at q9.cCi3`nAQW2D=Bo07>[CN;?<CH=
+=Bo07>[CB/<D#qZ<)cji9MIrD77BU5779R56q'O477BU5779R56q'O477BU5779R56q'O477BU5
+779R56q'^A9gqH=8k_rO9MJ,Q9hJ)R<)ck">[CN;?=RMWH[C1abg"Scf$`(!g"bG2H[Q"u";_+B
+ZN:99!X,.t"LA.4ZN:9&!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:99!X,.t"LA.4TE58&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE58&!X,.t"J>f!ZN:9&!X,.t"LA.4
+TE58&!X,.t"LA.4TE58&!X,.t"J>f!TE58&!X,.t"J>f!TE58&!X,.t"LA.4TE57h!X,.t"J>f!
+TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!TE57h!X,.t"LA.4TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE58&!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!
+TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X,.t"J>f!TE57h!X+_h"J>f!
+TE57h!X+_h"J>f!TE57\!X,.t"J>f!TE57\!X,.t"I&rjTE57h!X+_h"J>f!TE57\!X,.t"I&rj
+TE57h!X+_h"J>f!TE57\!X,.t"I&rjTE57h!X+_h"J>f!PQCu\!X+_h"J>f!PQCu\!X+_h"J>f!
+PQCu\!X+_h"I&rjTE57\!X+_h"J>f!PQCuP!X,.t"I&rjTE57\!X,.t"I&rjPQCuP!X,.t"I&rj
+TE57h!X-GgIK0?Is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ at Sq<726kj7crjQG1&XKiZ]TE57h!X,h2"J>f!TE57h!X,h2"J>f!
+TE58&!X,.t"LA.4TE58&!X,.t"LA.4TE57h!X,h2"J>f!ZN:9&!X,h2"J>f!ZN:9&!X,h2"LA.4
+TE58&!X,.t"LA.4ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:9&!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4ZN:99!X,h2"LA.4
+ZN:99!X,h2"LA.4ZN:99!X-.D%^Q3>ZN:99!X,h2"LA.4ZN:9B$P'KE"LA.4ZN:9B$P'KE"LA.4
+]F,4U!X-.D%_N/Z]F,4^$P'fW%_N/Z]F,4^$P'fW%_N/Z]F,4^$P'fW%_iht]F,4^$P'fW%_N/Z
+]F,4^$P'fW%_iht]F,4a(`9mn%_iht]F,4a(`:")(q^4d^DIg#$P'og(r$n)^DIg&(`:")(r$n)
+^DIg&(`:")(r$n)^DIg&(`:")(r$n)^DIg+,:(#@(r$n)`$6PB(`:")(r$n)^DIg+,:(2P,fCoQ
+^DIg+,:(2P,fCoQ^DIg+,:(2P,fCoQ`$6PG/25!e,fD5f`$6PG,:(2Y0Z51]`%3U\,:(2Y0Z5Lr
+`%3U\/25!n0Z5Lr`%3U\/25!n0Z5Lr`%3U\2E8W535d@%`&9Tn/25"#35d@%`&9Tn/25"#35d@%
+`&9Tn2E8W535d^7`&9Tn2E8W535d^7`&9Tn2E8W536XKL`&9U!4?pbB36XKL`&9Tn2E8W536XKL
+`&9Tn2E8oC5Kl5SbWJ,64?q%P5Kl5SbWJ,64?q%P5Kl5SbWJ,66q#6]5KlM`bWJ,66q#6]5KlM`
+bWJ,66q#6]5KlM`bX=kF9i&u$7*eS'cV73]9i')0:X;a2cV73]9i($(fBDSii8j(SgtpK/f%A3i
+bKS5L`Pod7`O*"Z/hASC6q'^A9hJ)R<)ck">[CB/<ENL4<)ck">[CN;?<CH==Bo0BA7\kJ?=RMW
+=Bo0BA7\kJ?=RMW at q9.Q>[CoNAaK$]s8W-!s8W-!s7H$\m.9o6m-j0)n*'-,kj7cVH[Wq>:!?R=
+bZ%]g<*7 at D=Nj`HbZ%]g<*7 at D=Nj`HbZ%]g<*7XV7*K+ObZ%]g<*7 at RA^"+Ue6YPe<*7 at RA^"+U
+b[P/- at V*bmA^"Upb[P/- at V+5(8'GFRb[P/- at V*b_=Nk5cb[P/-<*6_;7Ee_5[o5>sUnG?4]u7n/
+]=bhh]Y1qi]t:qj]=bh(H[Sjm<ENL4<)cjs<)m%*?:mmc<)cjs<)lms<ENL4=Bo07>[CN;?<CH=
+=Bo07>[CN;?<CH=@q9.\A7]7]ASQ%!C2 at ctA7]7]AQW2D=Bo07>[CN;?<CH==Bo07>[CB/<D#qZ
+8k_rJ6q'O476<Up779R+4?Z,$77BU5779R+4?Z,$76<Up779R56q'1"4[hb-779R:9MJ,Q9hJ)R
+8k_rY<)lms<ENL4 at q9.\A7`-T[+X6ki8j(Sgtp`>hV$]@]=bhdHtpTHIE6M:`-ZpRFC)n4IDgJ\
+aa at a>H[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\
+`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\
+`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\`-ZpNH[WhZIDgJ\aFnTPH[WtgEl<<Q\V5:HH[WGYGf4rW
+\V5:HH[WtgEl<<QaGYJbH[WGYGfYek`-ZpRMg`NjIE7=p`-ZpRMg`'oKuf1#\VbdUMg`[)IE7=p
+\VbdUMg`-nI)q4o\VbdUMg`'oKuf1#[uH*_Mg`[)ICG2iaGYJUNJ5H3ICY5_aHM:dNJ5H;KXZqp
+aHM:dNJ5H;KXZqp[uH*NNJ4j$Kt!%q\<Di\PDcr7Mn"t/aHM:dNJ4m+Mn"t/aHM:dNJ4m+Mn"t/
+\<Di\PDcr7Mn"t/[uH*OPDco0Kt*>)[uH*OPDcu?Pdlp8\<Di\PDcu?Pdlp8\<Di\PDcr7Mn,:@
+\XJbnRZt at OPe!6I\XJbnRZt at OPe!6I\XJbnRZtmhS[YDfaK25ZXJO">V:`/VfY"ZF]XHG1^#d2L
+k01s3e^s'9fD*k;l.+DMe^s'9fBLi;l.+DMe^s'9fBLi;l.+DJgt_/EfD44Ll.+DXpA+ags8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA+ at Sq<[_Gm.9o6m-j)\al^ghf>PATbff.mak4h\fZ_P$bfSM]bLk%^fZ_OkbfeY_bLk%^
+fZ_Okbff8$f@\<jdaZk4e^rHtbL4nkl.+D6eCNm7f@&1"l.+D=gtq;GfB1lDl.+D=gtq;Gf at es9
+k1nbFgtq;Gf at es9k1nbSgt_&IgtCK>i8j(`gt_&IgudDIg"bHHgt^iKkMYFai8j(ZjQG[\h!"+n
+k1nbMjQGI^kN:RTi8j(bm-ilnkNM:$i8j(bm-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,
+m.9o6m-j<4p#tc2m.9o6m-j<4p#tc2o_/+Em-jT?q<726o_/+Em-jT?q<726o_/+Em-j<4p#tc2
+m.9oEm-!a,p$D;Ckj7d1pA*q=n*'-,o_/+Tm-"$7q<726o_/+Tm-"$7q=j7=o_/+Tm-"$7q=j7=
+o_/+Tm-"$7q=OCVo_/+Tm-"$7q=OCVp[%)8pA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=j7=
+o_/+QpA+ at Sq=j7=o_/+QpA+ILkOeKDp[%)8pA+ at Sq=OCVo_/+QpA+ILkOeKDo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+\s8W-!s7H$\o_/+QpA+ at Sq=OCVo_/+QpA+ags7H$\
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+\s8V`bq=OCVo_/+\s8V`bq=OCVo_/+QpA+ags7H$\
+o_/+\s8V`bq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+\s8V`bq=OCVo_/+QpA+ags7H$\s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq=OCVkj7d%m-ilnkLnYIdaZjkbg">Tc, at T?`5T]>FEB,d/P8]2
+8k_rO9MJJc<ENL4<)ck">[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH=
+S=Z8CpA+ags8W-!s8W-!s8W-!s7H$\m.9o:oC_JAp$D;Ckj7d1pA+ at Sq=OCVm.9oBpA+(Hp%7tR
+m.9oBpA+(Hp%7tRkj7d1pA+ at Sq=OCVp[%)0oC_JAp%7tRp[%)0oC_bLq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ILkNM:$kj7crjQG4OhV$]@daZjkbg")F`Pfa7`k8mp]Y1qi]t:qj]=bhh]Y1qi]t:qj
+H[C059MJJc<E)pt<)cjs<)lms<E)pt<)ck">[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH=
+C2 at d&Ci3`nAQW2D=Bo07>[CN;?<CH=<)cji9MJJc<E)pt8k_rY<)lOa9hJ)R8k_rO9MIrD77p6J
+8k_rO9MJ,Q9hJ)R779R56q'O477p6J8k_rO9MJ,Q9hJ)R8k_rO9MJVo?:mmc=Bo07>[CN;?Asf$
+kj7d%m-ilnkNM:$kj7crjQGann)39ii8j(ZjQGI^kMYFai8j(ZjQGI^kN:RTi8j(SgtpuMkLnYI
+i8j(SgtpuMkLnYIi8j(ZjQGI^kLnYIi8j(ZjQG4OhVdJXg"bHBjQGI^kLnYIi8j(SgtpuMkLnYI
+i8j(SgtpuMkLnYIi8j(ZjQGI^kMYFai8j(SgtpuMkLnYIi8j(SgtpuMkLnYIi8j(Sgtp`>hV$]@
+g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hVdJX
+g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@daZk$gtpK/f%Jj8daZjreCN'tf$`(!
+daZjreCN'tf$`(!daZjreCN'tf$`(!daZjreCN'tf$`(!daZjreCN'tf$`(!daZjreCN'tf%Jj8
+daZk$gtpK/f%Jj8daZjreCN'tf$`(!daZjreCN'tf$`(!daZjreCN'tf#u:^daZjreCN'tf#u:^
+daZjkbg"Scf#u:^daZjkbg"Scf#u:^bKS5ZeCMgec-k+mbKS5Sbg">Tc-+>UdaZjkbg">Tc-+>U
+bKS5ZeCMgec-k+mbKS5ZeCN'tf&5WPi8j(bm-j0)n*KZ=m.9oMs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCV
+kj7d)oC_>6n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,
+m.9oEm-!U!n*'-,kj7d1pA*q=n*KZ=kj7d)oC_JAp#tc2m.9oBpA*q=n*KZ=m.9o:oC_JAp$D;C
+m.9oBpA+ at Sq=OCVm.9o:oC_bLq=OCVm.9oBpA+ at Sq=OCVo_/+IoC_JAp%Rh9m.9oBpA+(Hp%7tR
+o_/+QpA+ at Sq=OCVp[%)8pA+(Hp%Rh9o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+s8W,kpA+ at Sq=OCVo_/+QpA+ at Sq>^Kpo_/+QpA+ at Sq>^Kpo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+\s8V`bq>^Kpo_/+\s8V`bq>^Kp
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\
+s8W-!s8V`bq>^Kps8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA*q=n)39ig"bH4eCMgec-+>U`5T^6`PoI%]eqW'779R:9MJ,Q9hJ)R8k_rO9MJVo?:mmc
+=Bo0)9MJJc<E)pt<)ck">[C#r9hJ)R8k_rO9MJ,Q9iP(l<)ck">[Hdgp&G'ls8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags8W-!o_/+QpA+ags7H$\o_/+QpA+ at Sq=OCVo_/+QpA+ags7H$\
+o_/+\s8V`bq>^Kps8W,kpA+ags8W-!o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA+(Hp#tc2
+i8j(SgtpK/f$`(!bKS5L`Pod7`Pfa7]=bhq`PoI%]t:qj`5T^-]Y1\Z[!-V6=Bo03<)m%*?;sm(
+<)cji9MJJc<E)pt<)ck">[C#r9iP(l<)cjs<)lms<E)pt=Bo07>[CN;?=RMW at q9.\A7\kJ?<CH=
+=Bo07>[CN;?<CH=<)cjs<)m%*?;sm(<)cji9MJ,Q9hJ)R8k_rO9MJJc<D#qZ8k_rO9MJ,Q9hJ)R
+8k_rO9MJ,Q9iP(l8k_r]>[CB/<E)pt<)ck">[CN;?<CH=C2 at eGjQGn$p$D;Cm.9o:oC_JAp$D;C
+m.9o:oC_JAp$D;Cm.9o:oC_JAp#tc2kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,
+kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,
+kj7d%m-j0)n*'-,kj7crjQGann)39ikj7crjQGI^kMYFakj7crjQGI^kMYFakj7crjQGI^kMYFa
+i8j(bm-j0)n)39ikj7crjQGI^kNM:$i8j(bm-ilnkNM:$kj7crjQGI^kNM:$i8j(ZjQGann)39i
+kj7crjQGI^kMYFai8j(ZjQGI^kMYFai8j(SgtpuMkMYFag"bHBjQGI^kMYFag"bHBjQGI^kLnYI
+i8j(ZjQG4OhVdJXi8j(SgtpuMkLnYIi8j(SgtpuMkMYFai8j(Sgtp`>hVdJXg"bH;gtp`>hV$]@
+i8j(SgtpuMkLnYIg"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@daZk$gtp`>hV$]@
+g"bH;gtp`>hV$]@g"bH;gtp`>hV$]@g"bH;gtpK/f%Jj8g"bH;gtp`>hU9p)g"bH;gtp`>hV$]@
+i8j(ZjQGI^kNM:$m.9oBpA+ at Sq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq<[_Go_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVs8W,kpA+ at Sq>^Kpo_/+\s8W-!s7H$\s8W-!s8W-!s8W-!
+o_/+\s8V`bq=OCVo_/+QpA+ags7H$\s8W-!s8V`bq=OCVs8W,kpA+ at Sq=OCVs8W,kpA+ags8W-!
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7crjQG4OhU9p)
+fZ_O^bg")F`Pfa7H[C/n/1jIf9hJ)R8k_rO9MJ,Q9hJ)R<)cji9MJVo?<CH=8k_rO9MJ,Q9hJ)R
+8k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9oP!hs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+IoC_>6n)39ig"bH4eCN'tf#u:^
+`5T^6`PoI%]t:qj]=bhh]Y1qi]t:qj]=bha['Y1,I99`\<)cjs<)lms<E)pt<)ck">[C#r9iP(l
+8k_rY<)lOa9itY,8k_r]>[CN;?<CH==Bo0BA7\kJ?<CH=@q9.Q>[CN;?<CH=<)cji9MJJc<ENL4
+<)ck">[CB/<E)pt<)cjs<)lms<E)pt<)cjs<)lms<E)pt<)cji9MJJc<D#qZ=Bo03<)m%*?<CH=
+=Bo03<)m%*?<CH==Bo0BA7a3=f'N#$m.9oBpA+ at Sq=OCVs8W-!s8W-!s7H$\o_/+QpA+ at Sq=OCV
+o_/+QpA+ags7H$\o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+(Hp%7tRo_/+IoC_bLq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVm.9o:oC_bLq<[_G
+m.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp#tc2m.9o:oC_>6n*KZ=
+m.9o6m-j<4p$D;Ckj7d)oC_>6n*KZ=kj7d)oC_JAp#tc2m.9o6m-j<4p$D;Ckj7d%m-j<4p#tc2
+kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,i8j(bm-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-ilnkNM:$
+kj7d%m-j0)n*'-,kj7crjQGann*'-,kj7crjQGann*'-,kj7d%m-ilnkNM:$kj7d%m-j0)n*'-,
+i8j(bm-ilnkMYFai8j(ZjQGI^kLnYIi8j(ZjQGI^kMYFai8j(SgtpuMkMYFai8j(SgtpuMkMYFa
+i8j(ZjQGI^kMYFai8j(ZjQGI^kMYFai8j(ZjQGI^kMYFai8j(ZjQGann*'-,kj7d%m-j<4p$D;C
+o_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ags8W-!o_/+\s8V`bq>^Kp
+o_/+\s8W-!s7H$\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+QpA*Y-kN:RTdaZjreCMgec-+>U`5T^-]Y-0Z1eLG9
+<)cji9MJ,Q9hJ)R8k_rO9MIrD77p6J779R:9MJ,Q9gqH=8k_r at 4?Ybg4Zbbh4$5Yf4?Ybg4Zbbh
+779T.m-juSs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n(HLQdaZjreCMgec, at T?`5T^6`Pod7`Oidr
+]=bhh]Y1qi]t:qj['[2eH[SL[9itY,<)ck">[CB/<ENL4<)cjs<)lOa9hJ)R8k_rY<)lOa9hJ)R
+=Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo03<)lms<E)pt<)cjs<)lOa9iP(l<)cjs<)m%*?<CH=
+<)ck">[CB/<E)pt=Bo07>[CN;?;sm(<)cjs<)m%*?<CH==Bo07>[CN;?<CH==Bo07>[CoNA\5Ug
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8V`bq>^Kps8W-!s8W-!s8W-!o_/+\s8V`bq>^Kpo_/+\s8V`bq>^Kpo_/+\s8V`bq=OCV
+o_/+QpA+ at Sq<[_Go_/+QpA+ at Sq=OCVo_/+QpA+(Hp%7tRo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq<[_G
+o_/+QpA+(Hp%7tRo_/+IoC_bLq=OCVm.9oBpA+ at Sq=OCVo_/+IoC_bLq<[_Gm.9o:oC_JAp$D;C
+m.9o:oC_JAp$D;Cm.9o:oC_JAp#tc2m.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;C
+m.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_>6n*'-,kj7d%m-j0)n*KZ=kj7d%m-j0)n*'-,
+kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n*'-,kj7d%m-j0)n)39ikj7d%m-ilnkNM:$
+kj7d%m-j0)n*'-,kj7crjQGann*'-,kj7d)oC_JAp$D;Co_/+QpA+ at Sq=OCVs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8VHWp#tc2i8j(SgtpK/f#u:^bKS5L`Pod7`Hur[/hASH9MJ,Q9hJ)R8k_rJ6q'O476<Up
+8k_rJ6q'O477BU5779R+4?Ybg4Zbbh4$5Yf4?Ybg4Zbbh4$5Yf4?\%<IJ!7/s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s7H$\kj7crjQGI^kL.l2daZjkbg")F`Pfa7]=bhh]Y28&`Oidr]=bhh]Y1qi]sP/R
+H[C0C>[CN;?;sm(<)cjs<)lms<D#qZ<)cji9MJ,Q9hJ)R8k_r]>[CB/<ENL4=Bo07>[CN;?<CH=
+=Bo03<)lOa9iP(l8k_rO9MJ,Q9iP(l<)cjs<)lms<ENL4<)ck">[CB/<ENL4<)ck">[CB/<ENL4
+=Bo07>[CB/<ENL4=Bo07>[CN;?=RMW=Bo07>[CN;?=RMW]=biLpA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags8W-!o_/+\s8W-!s8W-!o_/+\s8V`bq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ags7H$\
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+IoC_bLq=OCVm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;C
+m.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;C
+m.9o:oC_JAp$D;Co_/+QpA+ at Sq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\m.9o6m-ilnkL.l2
+daZjkbg">Tc, at T?]=bg71c.9V4\ACB8k_rJ6q'^A9gqH=779R56q'O476<Up8k_rJ6q'^A9fkI#
+4$5Yf4?Ybg4Zbbh4$5Yf4?Ybg4Zbbhg"bHas8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+i8j(Sgtp`>hU9p)bKS5Sbg")F`Pfa7`5T^-]Y1qi]t:qj]=bhh]Y1qi]o7l.<)ck">[CB/<ENL4
+<)cjs<)lOa9iP(l8k_rO9MJJc<D#qZ<)cjs<)lms<ENL4=Bo07>[CN;?<CH==Bo03<)lms<E)pt
+8k_rY<)lOa9iP(l<)ck">[CB/<E)pt=Bo0)9MJJc<E)pt<)ck">[CN;?<CH==Bo07>[CN;?<CH=
+ at q9.Q>[CN;?<CH=C2 at e@gtr)2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags8W-!s8W,kpA+ at Sq>^Kpo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCV
+o_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVo_/+QpA+ at Sq=OCVs8W,kpA+ags8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq>^Kp
+o_/+\s8V`bq>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#+oog"bH4eCMgec-+>U`5T^6`Pm1NI3^$_
+8k_r at 4?Ybg4Zbbh4$5Yf4?Ybg4Zbbh779R56q'O477BU5779R56q'O477BU5779R56q'^A9gqH=
+779RZCi8n=q>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+(Hp#tc2g"bH;gtpK/f#u:^
+`5T^6`Pod7`Oidr`5T^-]Y1qi]t:qj]=bhh]Y0i,S60$&<)ck">[CB/<E)pt<)cjs<)m%*?<CH=
+<)ck">[CB/<E)pt<)cjs<)lms<ENL4=Bo07>[CB/<E)pt8k_rY<)lms<E)pt=Bo07>[CB/<E)pt
+<)cji9MJ,Q9iP(l<)ck">[CN;?<CH==Bo07>[CoNARf7^=Bo0BA7\kJ?=RMW=Bo0kMi@#op&G'l
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s6T at Mkj7d#gt^?-f$`(!bKS5L`Pod7`Pfa78k_r at 4?Ybg4Zbbh4$5Yf4?Z,$76<Up
+4$5Yf4?Ybg4Zbbh779R56q'^A9fkI#779R56q'O477BU5779R56q'O47G6JQs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+Em-j0)n)39ig"bH;gtpK/f#u:^bKS5L`Pod7`Oidr
+`5T^-]Y1qi]t:qj]=bhQV5.jBDH'S8=Bo03<)lms<ENL4=Bo07>[CN;?<CH==Bo03<)lms<D#qZ
+=Bo07>[CN;?<CH=<)ck">[CB/<E)pt<)cjs<)lms<ENL4=Bo03<)m%*?;sm(8k_rO9MJJc<ENL4
+=Bo07>[CoNARf7^@q9.\A7]7]ARf7^@q9.tH[X>lf)PdMs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,kpA+ags8W-!s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,coC_>6n)39i
+g"bH4eCMgec-+>UbKS5C]Y,pK/NZ'X4$5YY/1i_91c7*H4$5Yf4?Z,$77p6J8k_rJ6q'^A9gqH=
+4$5Yu9MIrD77p6J8k_rO9MJ,Q9hJ)RC2 at e[pA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!m.9o6m-ilnkMYFag"bH4eCN'tf#u:^bKS5L`Pod7`Pfa7]=bhq`PoI%]t:qj
+['[2rKS3H4?<CH=@q9.Q>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH=
+<)cjs<)lms<E)pt<)ck">[CB/<ENL4=Bo03<)m%*?<CH==Bo07>[CN;?<CH=@q9.\A7]LlDJF!*
+C2 at d&Ci6kt^%D$oo_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq>^Kp
+s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\kj7crjQG4OhU9p)daZjreCMgec(q23
+/hAS31c.'H1bL=22)I-B/1iqG4Zbbh779R56q'1"4[hb-779R+4?Z;19gqH=779R:9MJ,Q9gqH=
+8k_rO9MN^Sc2[hDs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s6T at M
+m.9o.jQGI^kLnYIg"bH4eCN'tf#u:^bKS5Sbg")F`Pfa7`5T^6`PoI%]t:qjUnsl6H[TC7ARf7^
+=Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CN;?<CH==Bo07>[CB/<E)pt=Bo03<)lms<ENL4
+8k_r]>[CB/<E)pt<)ck">[CN;?<CH=@q9.\A7]LlDI[3gC2 at d7H[W9.[/^1+s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+\s8V`bq>^Kp
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8VHWp#tc2i8j(ZjQG4OhU9p)daZj(KS23>1bL=2/hAS31c-g9/N#@A
+2)I-O4?Z,$77p6J8k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9knK^o_/+\s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o.jQGI^kLnYI
+g"bH;gtpK/f$`(!bKS5Sbg">Tc, at T?bKS5L`Pod7`OidrS=Z6tH[TC7AQW2D=Bo07>[CN;?<CH=
+ at q9.Q>[CN;?<CH=8k_r]>[C#r9iP(l<)ck">[C#r9itY,<)cjs<)m%*?:mmc<)ck">[CB/<ENL4
+=Bo07>[CoNARf7^@q9/0Mi>j'c1L`*o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+QpA*q=n)39ii8j(ZjQGI^kG4rMC2 at ci>[BKS4YA9;2)I-B/1iqG4Zbbh4$5Yp6q'^A9gqH=
+8k_rO9MJ,Q9iP(l<)cjs<)lms<D#qZ8k_sk]Y4 at Fs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gkj7d)oC_&&kMYFag"bH;gtp`>hU9p)
+daZjreCN'tf#u:^daZjkbg">Tc-+>U['[3!Mi;CeDHL.M=Bo07>[CN;?<CH==Bo0)9MJVo?;sm(
+=Bo07>[C#r9iP(l<)cjs<)lms<E)pt<)ck">[C#r9iP(l8k_rO9MJVo?<CH=@q9/HV53>An+?>L
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+\s8W-!s7H$\s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+Em-j0)n*'-,
+kj7crjQGI^kMYFai8j(>`Po3k[%*_XN/NXAH[TC7AP,Wj4$5Yu9MJ,Q9iP(l<)cjs<)lms<E)pt
+8k_rY<)m%*?N:'*s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8V`bq<[_Gm.9o6m-j0)n)39ii8j(ZjQG4OhV$]@g"bH;gtpK/f$`(!
+g"bH4eCN=.hU9p)daZj[]Y0i,S9K's=Bo0)9MJ,Q9itY,=Bo0)9MJVo?:mmc8k_rO9MJ,Q9hJ)R
+8k_rO9MJ,Q9hJ)R8k_rO9MJ,Q9itY,S=Z8!eCO9cq=OCVs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+\s8W-!s8W-!
+o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+IoC_JAp$D;Cm.9o:oC_>6n*KZ=
+kj7d)oC_>6n*KZ=m.9o:oC_&&kKD)o]=bhXXK at G>N-fo"=Bo03<)lms<E)pt['[4?s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,kpA+ at Sq<[_Gm.9o:oC_>6n*'-,i8j(ZjQGI^kLnYIi8j(ZjQG4OhVdJXg"bH;gtpuMkLnYI
+g"bHBjQG4OhSdCPUnslGMi<"0I99`\<)cjs<)lOa9hJ)R8k_rO9MJ,Q9hJ)R8k_r]>[EAIN3ot!
+i8j)$s8V`bq>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ags8W-!o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ at Sq=OCVm.9o:oC_JAp$D;Cm.9oBpA+ at Sq=OCV
+o_/+\s8V`bq=OCVo_/+\s8V`bq>^Kpm.9o.jQH1/q>^Kps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8V`bq<[_G
+o_/+IoC_JAp$D;Ckj7d%m-j0)n)39ikj7crjQGann*'-,i8j(bm-j0)n*'-,kj7d)oC_JAp$D;C
+m.9o:oC_&&kL.l2daZjd`Pp$Ec-k+mg"bHBjQGn$p&G'lo_/+QpA+ags8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o_/+\s8W-!s8W-!s8W,kpA+ags8W-!o_/+\s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\o_/+IoC_bLq<[_G
+m.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Cm.9o:oC_JAp$D;Co_/+QpA+ags7H$\s8W,kpA+ags7H$\
+s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!o_/+\s8V`bq>^Kp
+s8W,kpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,kpA+ags7H$\o_/+QpA+(Hp%7tR
+o_/+QpA+ags8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s7H$\s8W-!s8W-!s8W-!s8W,kpA+ags8W-!o_/+\s8N~>
+Q
+cleartomark end end pagesave restore showpage
+%%PageTrailer
+%%Trailer
+%%Pages: 1
diff --git a/doc/doxygen_logo.gif b/doc/doxygen_logo.gif
new file mode 100644
index 0000000..6b45597
Binary files /dev/null and b/doc/doxygen_logo.gif differ
diff --git a/doc/doxygen_logo_low.gif b/doc/doxygen_logo_low.gif
new file mode 100644
index 0000000..02e3c9a
Binary files /dev/null and b/doc/doxygen_logo_low.gif differ
diff --git a/doc/doxygen_manual.css b/doc/doxygen_manual.css
new file mode 100644
index 0000000..3286004
--- /dev/null
+++ b/doc/doxygen_manual.css
@@ -0,0 +1,1108 @@
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+ font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 1.3;
+}
+
+/* @group Heading Levels */
+
+h1 {
+ font-size: 150%;
+}
+
+.title {
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2 {
+ font-size: 120%;
+}
+
+h3 {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+ margin-top: 2px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #F1F1F1;
+ border: 1px solid #BDBDBD;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #646494;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #7474A4;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #B8B8B8;
+ color: #ffffff;
+ border: 1px double #A8A8A8;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited {
+ color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 4px;
+ margin: 4px;
+ background-color: #FCFCFC;
+ border: 1px solid #D5D5D5;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+}
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: #CCCCCC;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-bottom: 10px;
+ padding: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 800px;
+ background-color: white;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 5px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15);
+}
+
+td.indexkey {
+ background-color: #F1F1F1;
+ font-weight: bold;
+ border: 1px solid #D5D5D5;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #F1F1F1;
+ border: 1px solid #D5D5D5;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #F2F2F2;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+ background-color: #8080A0;
+ color: white;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: #F9F9F9;
+ border-left: 2px solid #B8B8B8;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #BDBDBD;
+}
+
+th.dirtab {
+ background: #F1F1F1;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #7A7A7A;
+}
+
+hr.footer {
+ display: none;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #FAFAFA;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #D5D5D5;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #747474;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #747474;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #F1F1F1;
+ border: 1px solid #BDBDBD;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #C0C0C0;
+ border-left: 1px solid #C0C0C0;
+ border-right: 1px solid #C0C0C0;
+ padding: 6px 0px 6px 0px;
+ color: #3D3D3D;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-topleft: 8px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-top-left-radius: 8px;
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #EAEAEA;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #C0C0C0;
+ border-left: 1px solid #C0C0C0;
+ border-right: 1px solid #C0C0C0;
+ padding: 2px 5px;
+ background-color: #FCFCFC;
+ border-top-width: 0;
+ /* opera specific markup */
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F9F9F9 95%, #F2F2F2);
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F9F9F9), to(#F2F2F2));
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+ border-spacing: 6px 2px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+
+
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+ font-family: sans-serif;
+ margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+ margin: 5px;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+}
+
+address {
+ font-style: normal;
+ color: #464646;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #4A4A4A;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #5B5B5B;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+}
+
+table.fieldtable {
+ width: 100%;
+ margin-bottom: 10px;
+ border: 1px solid #C0C0C0;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #C0C0C0;
+ border-bottom: 1px solid #C0C0C0;
+ vertical-align: top;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #C0C0C0;
+ width: 100%;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #EAEAEA;
+ font-size: 90%;
+ color: #3D3D3D;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #C0C0C0;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ height:30px;
+ line-height:30px;
+ color:#ABABAB;
+ border:solid 1px #D3D3D3;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#595959;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#929292;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#595959;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.ingroups
+{
+ margin-left: 5px;
+ font-size: 8pt;
+ padding-left: 5px;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #FAFAFA;
+ border-bottom: 1px solid #D5D5D5;
+ margin-left: auto;
+ margin-right: auto;
+ width: 800px;
+ padding-left: 12px;
+ padding-right: 12px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 5px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15);
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 0px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+dl.section
+{
+ padding: 0 0 0 6px;
+}
+
+dl.note
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #505050;
+}
+
+dl.todo
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 1em;
+}
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #848484;
+ visibility: hidden;
+ height: 0px;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #AFAFAF;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#545454;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: #F6F6F6;
+ border: 1px solid #DDDDDD;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 20px 10px 10px;
+ width: 200px;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ border-bottom: 0 none;
+ color: #606060;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+ at media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+ pre.fragment
+ {
+ overflow: visible;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ }
+}
+
diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex
new file mode 100644
index 0000000..4bac9a9
--- /dev/null
+++ b/doc/doxygen_manual.tex
@@ -0,0 +1,116 @@
+%
+%
+%
+% Copyright (C) 1997-2014 by Dimitri van Heesch.
+%
+% Permission to use, copy, modify, and distribute this software and its
+% documentation under the terms of the GNU General Public License is hereby
+% granted. No representations are made about the suitability of this software
+% for any purpose. It is provided "as is" without express or implied warranty.
+% See the GNU General Public License for more details.
+%
+% Documents produced by Doxygen are derivative works derived from the
+% input used in their production; they are not affected by this license.
+
+\documentclass{book}
+\usepackage[a4paper,left=2.5cm,right=2.5cm,top=2.5cm,bottom=2.5cm]{geometry}
+\usepackage{makeidx}
+\usepackage{natbib}
+\usepackage{graphicx}
+\usepackage{multicol}
+\usepackage{float}
+\usepackage{geometry}
+\usepackage{listings}
+\usepackage{color}
+\usepackage{ifthen}
+\usepackage[table]{xcolor}
+\PassOptionsToPackage{warn}{textcomp}
+\usepackage{textcomp}
+\usepackage[nointegrals]{wasysym}
+\usepackage{alltt}
+\usepackage{ifpdf}
+\ifpdf
+\usepackage[pdftex,
+ pagebackref=true,
+ colorlinks=true,
+ linkcolor=blue,
+ unicode
+ ]{hyperref}
+\else
+\usepackage[ps2pdf,
+ pagebackref=true,
+ colorlinks=true,
+ linkcolor=blue,
+ unicode
+ ]{hyperref}
+\usepackage{pspicture}
+\fi
+\usepackage[utf8]{inputenc}
+\usepackage{mathptmx}
+\usepackage[scaled=.90]{helvet}
+\usepackage{courier}
+\usepackage{sectsty}
+\usepackage[titles]{tocloft}
+\usepackage{amssymb}
+\usepackage{doxygen}
+\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
+\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=8,numbers=left }
+\makeindex
+\setcounter{tocdepth}{3}
+\renewcommand{\footrulewidth}{0.4pt}
+\renewcommand{\familydefault}{\sfdefault}
+\renewcommand{\cftsecindent}{0 em}
+\renewcommand{\cftsecnumwidth}{3.2 em}
+\renewcommand{\cftsubsecindent}{3.2 em}
+\newcommand{\thisyear}{\the\year}
+\hfuzz=15pt
+\setlength{\emergencystretch}{15pt}
+\hbadness=750
+\tolerance=750
+\begin{document}
+\begin{titlepage}
+\includegraphics[width=\textwidth]{doxygen_logo}
+\begin{center}
+Manual for version $VERSION\\[2ex]
+Written by Dimitri van Heesch\\[2ex]
+\copyright 1997-\thisyear
+\end{center}
+\end{titlepage}
+\pagenumbering{Roman}
+\clearemptydoublepage
+\tableofcontents
+\clearemptydoublepage
+\pagenumbering{arabic}
+\part{User Manual}
+\chapter{Introduction}\label{intro}\hypertarget{intro}{}\input{index}
+\chapter{Installation}\label{install}\hypertarget{install}{}\input{install}
+\chapter{Getting Started}\label{starting}\hypertarget{starting}{}\input{starting}
+\chapter{Documenting the code}\label{docblocks}\hypertarget{docblocks}{}\input{docblocks}
+\chapter{Markdown}\label{markdown}\hypertarget{markdown}{}\input{markdown}
+\chapter{Lists}\label{lists}\hypertarget{lists}{}\input{lists}
+\chapter{Grouping}\label{grouping}\hypertarget{grouping}{}\input{grouping}
+\chapter{Including Formulas}\label{formulas}\hypertarget{formulas}{}\input{formulas}
+\chapter{Graphs and diagrams}\label{diagrams}\hypertarget{diagrams}{}\input{diagrams}
+\chapter{Preprocessing}\label{preprocessing}\hypertarget{preprocessing}{}\input{preprocessing}
+\chapter{Automatic link generation}\label{autolink}\hypertarget{autolink}{}\input{autolink}
+\chapter{Output Formats}\label{output}\hypertarget{output}{}\input{output}
+\chapter{Searching}\label{searching}\hypertarget{searching}{}\input{searching}
+\chapter{Customizing the Output}\label{customize}\hypertarget{customize}{}\input{customize}
+\chapter{Custom Commands}\label{custcmd}\hypertarget{custcmd}{}\input{custcmd}
+\chapter{Link to external documentation}\label{external}\hypertarget{external}{}\input{external}
+\chapter{Frequently Asked Questions}\label{faq}\hypertarget{faq}{}\input{faq}
+\chapter{Troubleshooting}\label{trouble}\hypertarget{trouble}{}\input{trouble}
+\part{Reference Manual}
+\chapter{Features}\label{features}\hypertarget{features}{}\input{features}
+\chapter{Doxygen usage}\label{doxygen_usage}\hypertarget{doxygen_usage}{}\input{doxygen_usage}
+\chapter{Doxywizard usage}\label{doxywizard_usage}\hypertarget{doxywizard_usage}{}\input{doxywizard_usage}
+\chapter{Configuration}\label{config}\hypertarget{config}{}\input{config}
+\chapter{Special Commands}\label{commands}\hypertarget{commands}{}\input{commands}
+\chapter{HTML commands}\label{htmlcmds}\hypertarget{htmlcmds}{}\input{htmlcmds}
+\chapter{XML commands}\label{xmlcmds}\hypertarget{xmlcmds}{}\input{xmlcmds}
+\part{Developers Manual}
+\chapter{Doxygen's internals}\label{arch}\hypertarget{arch}{}\input{arch}
+\chapter{Perl Module Output format}\label{perlmod}\hypertarget{perlmod}{}\input{perlmod}
+\chapter{Internationalization}\label{langhowto}\hypertarget{langhowto}{}\input{langhowto}
+\printindex
+\end{document}
diff --git a/doc/doxygen_usage.doc b/doc/doxygen_usage.doc
new file mode 100644
index 0000000..d84432e
--- /dev/null
+++ b/doc/doxygen_usage.doc
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page doxygen_usage Doxygen usage
+
+Doxygen is a command line based utility. Calling \c doxygen with the
+`--help` option at the command line will give you a brief description of the
+usage of the program.
+
+All options consist of a leading character <tt>-</tt>,
+followed by one character and one or more arguments depending on the option.
+
+To generate a manual for your project you typically
+need to follow these steps:
+<ol>
+<li> You document your source code with
+ special documentation blocks (see section \ref specialblock).
+<li> You generate a configuration file (see section \ref config) by
+ calling doxygen with the \c -g option:
+\verbatim
+doxygen -g <config_file>
+\endverbatim
+<li> You edit the configuration file so it matches your project.
+ In the configuration file you can specify the input files and
+ a lot of optional information.
+<li> You let doxygen generate the documentation, based on the settings in the
+ configuration file:
+\verbatim
+doxygen <config_file>
+\endverbatim
+</ol>
+
+If you have a configuration file generated with an older version of
+doxygen, you can upgrade it to the current version by running doxygen
+with the -u option.
+\verbatim
+doxygen -u <config_file>
+\endverbatim
+All configuration settings in the original configuration file will be copied
+to the new configuration file. Any new options will have their default value.
+Note that comments that you may have added in the original configuration file
+will be lost.
+
+\section doxygen_finetune Fine-tuning the output
+If you want to fine-tune the way the output looks, doxygen allows you
+generate default style sheet, header, and footer files that you can edit
+afterwards:
+<ul>
+<li>For HTML output, you can generate the default header file
+ (see \ref cfg_html_header "HTML_HEADER"), the default footer
+ (see \ref cfg_html_footer "HTML_FOOTER"), and the default style
+ sheet (see \ref cfg_html_stylesheet "HTML_STYLESHEET"), using the
+ following command:
+\verbatim
+doxygen -w html header.html footer.html stylesheet.css <config_file>
+\endverbatim
+ The `config_file` is optional. When omitted doxygen will search for
+ a file named `Doxyfile` and process that. When this is also not found it
+ will used the default settings.
+
+<li>For \LaTeX output, you can generate the first and last part of \c refman.tex
+ (see \ref cfg_latex_header "LATEX_HEADER" and
+ \ref cfg_latex_footer "LATEX_FOOTER") and the style sheet included
+ by that header (normally <code>doxygen.sty</code>), using the following
+ command:
+\verbatim
+doxygen -w latex header.tex footer.tex doxygen.sty <config_file>
+\endverbatim
+If you need non-default options (for instance to use extra \LaTeX packages)
+you need to make a config file with those options set correctly and then specify
+that config file after the generated files (make a backup of the configuration
+file first so you don't loose it in case you forget to specify one of the
+output files).
+<li>For RTF output, you can generate the default style sheet file (see
+ \ref cfg_rtf_stylesheet_file "RTF_STYLESHEET_FILE") using:
+\verbatim
+doxygen -w rtf rtfstyle.cfg
+\endverbatim
+</ul>
+\warning When using a custom header you are responsible
+ for the proper inclusion of any scripts and style sheets that doxygen
+ needs, which is dependent on the configuration options and may changes
+ when upgrading to a new doxygen release.
+
+\note
+<ul>
+<li> If you do not want documentation for each item inside the configuration
+ file then you can use the optional \c -s option. This can use be
+ used in combination with the \c -u option, to add or strip the
+ documentation from an existing configuration file.
+ Please use the \c -s option if you send me a configuration file
+ as part of a bug report!
+<li> To make doxygen read/write to standard input/output instead of from/to
+ a file, use \c - for the file name.
+</ul>
+
+
+\htmlonly
+Go to the <a href="doxywizard_usage.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/doxyindexer.1 b/doc/doxyindexer.1
new file mode 100644
index 0000000..7b7a298
--- /dev/null
+++ b/doc/doxyindexer.1
@@ -0,0 +1,17 @@
+.TH DOXYINDEXER "1" "DATE" "doxyindexer VERSION" "User Commands"
+.SH NAME
+doxyindexer \- creates a search index from raw search data
+.SH SYNOPSIS
+.B doxyindexer
+[\fI-o output_dir\fR] \fIsearchdata.xml \fR[\fIsearchdata2.xml\fR...] ]
+.SH DESCRIPTION
+Generates a search index called \fBdoxysearch.db\fR from one or more
+search data files produced by doxygen. Use
+doxysearch.cgi as a CGI program to search the data indexed by doxyindexer.
+.SH OPTIONS
+.TP
+\fB\-o\fR <output_dir>
+The directory where to write the doxysearch.db to.
+If omitted the current directory is used.
+.SH SEE ALSO
+doxygen(1), doxysearch(1), doxywizard(1).
diff --git a/doc/doxysearch.1 b/doc/doxysearch.1
new file mode 100644
index 0000000..da9ae05
--- /dev/null
+++ b/doc/doxysearch.1
@@ -0,0 +1,11 @@
+.TH DOXYSEARCH "1" "DATE" "doxysearch.cgi VERSION" "User Commands"
+.SH NAME
+doxysearch.cgi \- search engine used for searching in doxygen documentation.
+.SH SYNOPSIS
+.B doxyindexer.cgi
+.SH DESCRIPTION
+CGI binary that is used by doxygen generated HTML output to search for words.
+The tool uses the search index called \fBdoxysearch.db\fR produced by
+doxyindexer.
+.SH SEE ALSO
+doxygen(1), doxysearch(1), doxywizard(1).
diff --git a/doc/doxywizard.1 b/doc/doxywizard.1
new file mode 100644
index 0000000..e3f23c0
--- /dev/null
+++ b/doc/doxywizard.1
@@ -0,0 +1,13 @@
+.TH DOXYWIZARD "1" "DATE" "doxywizard VERSION" "User Commands"
+.SH NAME
+doxywizard \- a tool to configure and run doxygen on your source files
+.SH SYNOPSIS
+.B doxywizard
+.SH DESCRIPTION
+Doxywizard is an interactive frontend to the doxygen tool to configure
+and run doxygen on your source files.
+.PP
+You can optionally pass the name of a configuration file as the first argument
+to load it at startup.
+.SH SEE ALSO
+doxygen(1)
diff --git a/doc/doxywizard.gif b/doc/doxywizard.gif
new file mode 100644
index 0000000..80bb636
Binary files /dev/null and b/doc/doxywizard.gif differ
diff --git a/doc/doxywizard_expert.png b/doc/doxywizard_expert.png
new file mode 100644
index 0000000..93fd4ee
Binary files /dev/null and b/doc/doxywizard_expert.png differ
diff --git a/doc/doxywizard_main.png b/doc/doxywizard_main.png
new file mode 100644
index 0000000..e57c144
Binary files /dev/null and b/doc/doxywizard_main.png differ
diff --git a/doc/doxywizard_menu.png b/doc/doxywizard_menu.png
new file mode 100644
index 0000000..37adc46
Binary files /dev/null and b/doc/doxywizard_menu.png differ
diff --git a/doc/doxywizard_page1.png b/doc/doxywizard_page1.png
new file mode 100644
index 0000000..ee3181d
Binary files /dev/null and b/doc/doxywizard_page1.png differ
diff --git a/doc/doxywizard_page2.png b/doc/doxywizard_page2.png
new file mode 100644
index 0000000..dc9b5a8
Binary files /dev/null and b/doc/doxywizard_page2.png differ
diff --git a/doc/doxywizard_page3.png b/doc/doxywizard_page3.png
new file mode 100644
index 0000000..f75e63f
Binary files /dev/null and b/doc/doxywizard_page3.png differ
diff --git a/doc/doxywizard_page4.png b/doc/doxywizard_page4.png
new file mode 100644
index 0000000..e4f4361
Binary files /dev/null and b/doc/doxywizard_page4.png differ
diff --git a/doc/doxywizard_usage.doc b/doc/doxywizard_usage.doc
new file mode 100644
index 0000000..bec143c
--- /dev/null
+++ b/doc/doxywizard_usage.doc
@@ -0,0 +1,153 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page doxywizard_usage Doxywizard usage
+
+Doxywizard is a GUI front-end for configuring and running doxygen.
+
+Note it is possible to start the doxywizard with as argument the configuration file to be used.
+
+When you start doxywizard it will display the main window
+(the actual look depends on the OS used).
+
+\image html doxywizard_main.png "Main window"
+\image latex doxywizard_main.png "Main window" width=15cm
+
+The windows shows the steps to take to configure and run doxygen.
+The first step is to choose one of the ways to configure doxygen.
+<dl>
+<dt>Wizard<dd>Click this button to quickly configure the most important
+ settings and leave the rest of the options to their defaults.
+<dt>Expert<dd>Click this button to gain access to the
+ \ref config "full range of configuration options".
+<dt>Load<dd>Click this button to load an existing configuration file
+ from disk.
+</dl>
+Note that you can select multiple buttons in a row, for instance to first
+configure doxygen using the Wizard and then fine tune the settings via
+the Expert.
+
+After doxygen is configured you need to save the configuration as a file
+to disk. This second step allows doxygen to use the configuration
+and has the additional advantage that the configuration can be reused
+to run doxygen with the same settings at a later point in time.
+
+Since some configuration options may use relative paths, the next step is
+to select a directory from which to run doxygen. This is typically the root
+of the source tree and will most of the time already be filled in correctly.
+
+Once the configuration file is saved and the working directory is set, you
+can run doxygen based on the selected settings. Do this by pressing the
+"Start" button. Once doxygen runs you can cancel it by clicking the same
+button again. The output produced by doxygen is captured and shown in a log
+window. Once doxygen finishes, the log can be saved as a text file.
+
+<h3>The Wizard Dialog</h3>
+
+If you select the Wizard button in step 1, then a dialog with
+a number of tabs will appear.
+
+\image html doxywizard_page1.png "Wizard dialog: Project settings"
+\image latex doxywizard_page1.png "Wizard dialog: Project settings" width=13cm
+
+The fields in the project tab speak for themselves. Once doxygen has finished
+the Destination directory is where to look for the results. Doxygen will
+put each output format in a separate sub-directory.
+
+\image html doxywizard_page2.png "Wizard dialog: Mode of operating"
+\image latex doxywizard_page2.png "Wizard dialog: Mode of operating" width=13cm
+
+The mode tab allows you to select how doxygen will look at your sources.
+The default is to only look for things that have been documented.
+
+You can also select how doxygen should present the results.
+The latter does not affect the way doxygen parses your source code.
+
+\image html doxywizard_page3.png "Wizard dialog: Output to produce"
+\image latex doxywizard_page3.png "Wizard dialog: Output to produce" width=13cm
+
+You can select one or more of the output formats that doxygen should
+produce. For HTML and \LaTeX there are additional options.
+
+\image html doxywizard_page4.png "Wizard dialog: Diagrams to generate"
+\image latex doxywizard_page4.png "Wizard dialog: Diagrams to generate" width=13cm
+
+Doxygen can produce a number of diagrams. Using the diagrams tab you
+can select which ones to generate. For most diagrams the
+dot tool of the <a href="http://www.graphviz.org">GraphViz</a> package
+is needed (if you use the binary packages for MacOSX this
+tool is already included).
+
+<h3>Expert dialog</h3>
+
+The Expert dialog has a number of tab fields, one
+for each section in the configuration file. Each tab-field
+contains a number of lines, one for each configuration option in
+that section.
+
+The kind of input widget depends on the type of the configuration option.
+<ul>
+<li>For each boolean option (those options that are answered with YES or
+ NO in the configuration file) there is a check-box.
+<li>For items taking one of a fixed set of values (like
+ \ref cfg_output_language "OUTPUT_LANGUAGE") a combo box is used.
+<li>For items taking an integer value from a range, a spinbox is used.
+<li>For free form string-type options there is a one line edit field
+<li>For options taking a lists of strings, a one line edit field is
+ available, with a `+' button to add this string to the list and
+ a `-' button to remove the selected string from the list. There
+ is also a `*' button that, when pressed,
+ replaces the selected item in the list with the string entered in the
+ edit field.
+<li>For file and folder entries, there are special buttons
+ that start a file selection dialog.
+</ul>
+
+\image html doxywizard_expert.png "Some options from the Expert dialog"
+\image latex doxywizard_expert.png "Some options from the Expert dialog" width=15cm
+
+The get additional information about the meaning of an option, click
+on the "Help" button at the bottom right of the dialog and then on the
+item. A tooltip with additional information will appear.
+
+<h3>Menu options</h3>
+
+The GUI front-end has a menu with a couple of useful items
+
+\image html doxywizard_menu.png "File menu"
+\image latex doxywizard_menu.png "File menu" width=15cm
+
+<dl>
+<dt>Open...<dd>This is the same as the "Load" button in the main window
+ and allows to open a configuration file from disk.
+<dt>Save as..<dd>This is the same as the "Save" button in the main window
+ and can be used to save the current configuration settings to disk.
+<dt>Recent configurations<dd>Allow to quickly load a recently saved
+ configuration.
+<dt>Set as default...<dd>Stores the current configuration settings as the
+ default to use next time the GUI is started. You will be asked to
+ confirm the action.
+<dt>Reset...<dd>Restores the factory defaults as the default settings to use.
+ You will be asked to confirm the action.
+</dl>
+
+
+\htmlonly
+Go to the <a href="config.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/external.doc b/doc/external.doc
new file mode 100644
index 0000000..be7d764
--- /dev/null
+++ b/doc/external.doc
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page external Linking to external documentation
+
+If your project depends on external libraries or tools, there are several
+reasons to not include all sources for these with every run of doxygen:
+
+<dl>
+<dt>Disk space:<dd> Some documentation may be available outside of the output
+ directory of doxygen already, for instance somewhere on the web.
+ You may want to link to these pages instead of generating the documentation
+ in your local output directory.
+<dt>Compilation speed:<dd> External projects typically have a different update
+ frequency from your own project. It does not make much sense to let doxygen
+ parse the sources for these external project over and over again, even if
+ nothing has changed.
+<dt>Memory:<dd> For very large source trees, letting doxygen parse all sources
+ may simply take too much of your system's memory. By dividing the sources
+ into several "packages", the sources of one package can be parsed by
+ doxygen, while all other packages that this package depends on, are
+ linked in externally. This saves a lot of memory.
+<dt>Availability:<dd> For some projects that are documented with doxygen,
+ the sources may just not be available.
+<dt>Copyright issues:<dd>If the external
+ package and its documentation are copyright someone else, it may be
+ better - or even necessary - to reference it rather than include a
+ copy of it with your project's documentation. When the author forbids
+ redistribution, this is necessary. If the author requires compliance
+ with some license condition as a precondition of redistribution, and
+ you do not want to be bound by those conditions, referring to their
+ copy of their documentation is preferable to including a copy.
+
+</dl>
+
+If any of the above apply, you can use doxygen's tag file mechanism.
+A tag file is basically a compact representation of the entities found in the
+external sources. Doxygen can both generate and read tag files.
+
+To generate a tag file for your project, simply put the name of the
+tag file after the \ref cfg_generate_tagfile "GENERATE_TAGFILE" option in
+the configuration file.
+
+To combine the output of one or more external projects with your own project
+you should specify the name of the tag files after
+the \ref cfg_tagfiles "TAGFILES" option in the configuration file.
+
+A tag file typically only contains a relative location of the documentation from the
+point where doxygen was run. So when you include a tag file in other project
+you have to specify where the external documentation is located in relation this project.
+You can do this in the configuration file by assigning the (relative) location to the
+tag files specified after the \ref cfg_tagfiles "TAGFILES" configuration
+option. If you use a relative path it should be relative with respect to
+the directory where the HTML output of your project is generated; so a relative path
+from the HTML output directory of a project to the HTML output of the other project that
+is linked to.
+
+\par Example:
+Suppose you have a project \c proj that uses two external
+projects called \c ext1 and \c ext2.
+The directory structure looks as follows:
+
+\par
+\verbatim
+<root>
+ +- proj
+ | +- html HTML output directory for proj
+ | +- src sources for proj
+ | |- proj.cpp
+ +- ext1
+ | +- html HTML output directory for ext1
+ | |- ext1.tag tag file for ext1
+ +- ext2
+ | +- html HTML output directory for ext2
+ | |- ext2.tag tag file for ext2
+ |- proj.cfg doxygen configuration file for proj
+ |- ext1.cfg doxygen configuration file for ext1
+ |- ext2.cfg doxygen configuration file for ext2
+\endverbatim
+
+\par
+Then the relevant parts of the configuration files look as follows:
+\par
+proj.cfg:
+\verbatim
+OUTPUT_DIRECTORY = proj
+INPUT = proj/src
+TAGFILES = ext1/ext1.tag=../../ext1/html \
+ ext2/ext2.tag=../../ext2/html
+\endverbatim
+ext1.cfg:
+\verbatim
+OUTPUT_DIRECTORY = ext1
+GENERATE_TAGFILE = ext1/ext1.tag
+\endverbatim
+ext2.cfg:
+\verbatim
+OUTPUT_DIRECTORY = ext2
+GENERATE_TAGFILE = ext2/ext2.tag
+\endverbatim
+
+\htmlonly
+Go to the <a href="faq.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/extsearch.doc b/doc/extsearch.doc
new file mode 100644
index 0000000..e07edd7
--- /dev/null
+++ b/doc/extsearch.doc
@@ -0,0 +1,306 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page extsearch External Indexing and Searching
+
+[TOC]
+
+\section extsearch_intro Introduction
+
+With release 1.8.3, doxygen provides the ability to search through HTML using
+an external indexing tool and search engine.
+This has several advantages:
+- For large projects it can have significant performance advantages over
+ doxygen's built-in search engine, as doxygen uses a rather simple indexing
+ algorithm.
+- It allows combining the search data of multiple projects into one index,
+ allowing a global search across multiple doxygen projects.
+- It allows adding additional data to the search index, i.e. other web pages
+ not produced by doxygen.
+- The search engine needs to run on a web server, but clients can still browse
+ the web pages locally.
+
+To avoid that everyone has to start writing their own indexer and search
+engine, doxygen provides an example tool for each action: `doxyindexer`
+for indexing the data and `doxysearch.cgi` for searching through the index.
+
+The data flow is shown in the following diagram:
+
+\image html extsearch_flow.png "External Search Data Flow"
+\image latex extsearch_flow.eps "External Search Data Flow" height=10cm
+
+- `doxygen` produces the raw search data
+- `doxyindexer` indexes the data into a search database `doxysearch.db`
+- when a user performs a search from a doxygen generated HTML page,
+ the CGI binary `doxysearch.cgi` will be invoked.
+- the `doxysearch.cgi` tool will perform a query on the database and return
+ the results.
+- The browser will show the search results.
+
+\section extsearch_config Configuring
+
+The first step is to make the search engine available via a web server.
+If you use `doxysearch.cgi` this means making the
+<a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a> binary
+available from the web server (i.e. be able to run it from a
+browser via an URL starting with http:)
+
+How to setup a web server is outside the scope of this document,
+but if you for instance have Apache installed, you could simply copy the
+`doxysearch.cgi` file from doxygen's `bin` dir to the `cgi-bin` of the
+Apache web server. Read the <a href="http://httpd.apache.org/docs/2.2/howto/cgi.html">apache documentation</a> for details.
+
+To test if `doxysearch.cgi` is accessible start your web browser and
+point to URL to the binary and add `?test` at the end
+
+ http://yoursite.com/path/to/cgi/doxysearch.cgi?test
+
+You should get the following message:
+
+ Test failed: cannot find search index doxysearch.db
+
+If you use Internet Explorer you may be prompted to download a file,
+which will then contain this message.
+
+Since we didn't create or install a doxysearch.db it is ok for the test to
+fail for this reason. How to correct this is discussed in the next section.
+
+Before continuing with the next section add the above
+URL (without the `?test` part) to the `SEARCHENGINE_URL` tag in
+doxygen's configuration file:
+
+ SEARCHENGINE_URL = http://yoursite.com/path/to/cgi/doxysearch.cgi
+
+\subsection extsearch_single Single project index
+
+To use the external search option, make sure the following options are enabled
+in doxygen's configuration file:
+
+ SEARCHENGINE = YES
+ SERVER_BASED_SEARCH = YES
+ EXTERNAL_SEARCH = YES
+
+This will make doxygen generate a file called `searchdata.xml` in the output
+directory (configured with \ref cfg_output_directory "OUTPUT_DIRECTORY").
+You can change the file name (and location) with the
+\ref cfg_searchdata_file "SEARCHDATA_FILE" option.
+
+The next step is to put the raw search data into an index for efficient
+searching. You can use `doxyindexer` for this. Simply run it from the command
+line:
+
+ doxyindexer searchdata.xml
+
+This will create a directory called `doxysearch.db` with some files in it.
+By default the directory will be created at the location from which doxyindexer
+was started, but you can change the directory using the `-o` option.
+
+Copy the `doxysearch.db` directory to the same directory as where
+the `doxysearch.cgi` is located and rerun the browser test by pointing
+the browser to
+
+ http://yoursite.com/path/to/cgi/doxysearch.cgi?test
+
+You should now get the following message:
+
+ Test successful.
+
+Now you should be enable to search for words and symbols from the HTML output.
+
+\subsection extsearch_multi Multi project index
+
+In case you have more than one doxygen project and these projects are related,
+it may be desirable to allow searching for words in all projects from within
+the documentation of any of the projects.
+
+To make this possible all that is needed is to combine the search data
+for all projects into a single index, e.g. for two projects A and B for which the
+searchdata.xml is generated in directories project_A and project_B run:
+
+ doxyindexer project_A/searchdata.xml project_B/searchdata.xml
+
+and then copy the resulting `doxysearch.db` to the directory where also
+`doxysearch.cgi` is located.
+
+The `searchdata.xml` file doesn't contain any absolute paths or links,
+so how can the search results from multiple projects be linked back to the right documentation set?
+This is where the `EXTERNAL_SEARCH_ID` and `EXTRA_SEARCH_MAPPINGS` options come into play.
+
+To be able to identify the different projects, one needs to
+set a unique ID using \ref cfg_external_search_id "EXTERNAL_SEARCH_ID"
+for each project.
+
+To link the search results to the right project, you need to define a
+mapping per project using the \ref cfg_extra_search_mappings "EXTRA_SEARCH_MAPPINGS" tag.
+With this option to can define the mapping from IDs of other projects to the
+(relative) location of documentation of those projects.
+
+So for projects A and B the relevant part of the configuration file
+could look as follows:
+
+ project_A/Doxyfile
+ ------------------
+ EXTERNAL_SEARCH_ID = A
+ EXTRA_SEARCH_MAPPINGS = B=../../project_B/html
+
+for project A and for project B
+
+ project_B/Doxyfile
+ ------------------
+ EXTERNAL_SEARCH_ID = B
+ EXTRA_SEARCH_MAPPINGS = A=../../project_A/html
+
+with these settings, projects A and B can share the same search database,
+and the search results will link to the right documentation set.
+
+\section extsearch_update Updating the index
+
+When you modify the source code, you should re-run doxygen to get up to date
+documentation again. When using external searching you also need to update the
+search index by re-running `doxyindexer`. You could wrap the call to doxygen
+and doxyindexer together in a script to make this process easier.
+
+\section extsearch_api Programming interface
+
+Previous sections have assumed you use the tools `doxyindexer`
+and `doxysearch.cgi` to do the indexing and searching, but you could also
+write your own index and search tools if you like.
+
+For this 3 interfaces are important
+- The format of the input for the index tool.
+- The format of the input for the search engine.
+- The format of the output of search engine.
+
+The next subsections describe these interfaces in more detail.
+
+\subsection extsearch_api_index Indexer input format
+
+The search data produced by doxygen follows the
+<a href="http://wiki.apache.org/solr/UpdateXmlMessages">Solr XML index message</a>
+format.
+
+The input for the indexer is an XML file, which consists of one `<add>` tag containing
+multiple `<doc>` tags, which in turn contain multiple `<field>` tags.
+
+Here is an example of one doc node, which contains the search data and meta data for
+one method:
+
+ <add>
+ ...
+ <doc>
+ <field name="type">function</field>
+ <field name="name">QXmlReader::setDTDHandler</field>
+ <field name="args">(QXmlDTDHandler *handler)=0</field>
+ <field name="tag">qtools.tag</field>
+ <field name="url">de/df6/class_q_xml_reader.html#a0b24b1fe26a4c32a8032d68ee14d5dba</field>
+ <field name="keywords">setDTDHandler QXmlReader::setDTDHandler QXmlReader</field>
+ <field name="text">Sets the DTD handler to handler DTDHandler()</field>
+ </doc>
+ ...
+ </add>
+
+Each field has a name. The following field names are supported:
+- *type*: the type of the search entry; can be one of: source, function, slot,
+ signal, variable, typedef, enum, enumvalue, property, event, related,
+ friend, define, file, namespace, group, package, page, dir
+- *name*: the name of the search entry; for a method this is the qualified name of the method,
+ for a class it is the name of the class, etc.
+- *args*: the parameter list (in case of functions or methods)
+- *tag*: the name of the tag file used for this project.
+- *url*: the (relative) URL to the HTML documentation for this entry.
+- *keywords*: important words that are representative for the entry. When searching for such
+ keyword, this entry should get a higher rank in the search results.
+- *text*: the documentation associated with the item. Note that only words are present, no markup.
+
+ at note Due to the potentially large size of the XML file, it is recommended to use a
+<a href="http://en.wikipedia.org/wiki/Simple_API_for_XML">SAX based parser</a> to process it.
+
+\subsection extsearch_api_search_in Search URL format
+
+When the search engine is invoked from a doxygen generated HTML page, a number of parameters are
+passed to via the <a href="http://en.wikipedia.org/wiki/Query_string">query string</a>.
+
+The following fields are passed:
+- *q*: the query text as entered by the user
+- *n*: the number of search results requested.
+- *p*: the number of search page for which to return the results. Each page has *n* values.
+- *cb*: the name of the callback function, used for JSON with padding, see the next section.
+
+From the complete list of search results, the range `[n*p - n*(p+1)-1]` should be returned.
+
+Here is an example of how a query looks like.
+
+ http://yoursite.com/path/to/cgi/doxysearch.cgi?q=list&n=20&p=1&cb=dummy
+
+It represents a query for the word 'list' (`q=list`) requesting 20 search results (`n=20`),
+starting with the result number 20 (`p=1`) and using callback 'dummy' (`cb=dummy`):
+
+
+ at note The values are <a href="http://en.wikipedia.org/wiki/Percent-encoding">URL encoded</a> so they
+have to be decoded before they can be used.
+
+\subsection extsearch_api_search_out Search results format
+
+When invoking the search engine as shown in the previous subsection, it should reply with
+the results. The format of the reply is
+<a href="http://en.wikipedia.org/wiki/JSONP">JSON with padding</a>, which is basically
+a javascript struct wrapped in a function call. The name of function should be the name of
+the callback (as passed with the *cb* field in the query).
+
+With the example query as shown the previous subsection the main structure of the reply should
+look as follows:
+
+ dummy({
+ "hits":179,
+ "first":20,
+ "count":20,
+ "page":1,
+ "pages":9,
+ "query": "list",
+ "items":[
+ ...
+ ]})
+
+The fields have the following meaning:
+- *hits*: the total number of search results (could be more than was requested).
+- *first*: the index of first result returned: \f$\min(n*p,\mbox{\em hits})\f$.
+- *count*: the actual number of results returned: \f$\min(n,\mbox{\em hits}-\mbox{\em first})\f$
+- *page*: the page number of the result: \f$p\f$
+- *pages*: the total number of pages: \f$\lceil\frac{\mbox{\em hits}}{n}\rceil\f$.
+- *items*: an array containing the search data per result.
+
+Here is an example of how the element of the *items* array should look like:
+
+ {"type": "function",
+ "name": "QDir::entryInfoList(const QString &nameFilter, int filterSpec=DefaultFilter, int sortSpec=DefaultSort) const",
+ "tag": "qtools.tag",
+ "url": "d5/d8d/class_q_dir.html#a9439ea6b331957f38dbad981c4d050ef",
+ "fragments":[
+ "Returns a <span class=\"hl\">list</span> of QFileInfo objects for all files and directories...",
+ "... pointer to a QFileInfoList The <span class=\"hl\">list</span> is owned by the QDir object...",
+ "... to keep the entries of the <span class=\"hl\">list</span> after a subsequent call to this..."
+ ]
+ },
+
+The fields for such an item have the following meaning:
+- *type*: the type of the item, as found in the field with name "type" in the raw search data.
+- *name*: the name of the item, including the parameter list, as found in the fields with
+ name "name" and "args" in the raw search data.
+- *tag*: the name of the tag file, as found in the field with name "tag" in the raw search data.
+- *url*: the name of the (relative) URL to the documentation, as found in the field with name "url"
+ in the raw search data.
+- "fragments": an array with 0 or more fragments of text containing words that have been search for.
+ These words should be wrapped in `<span class="hl">` and `</span>` tags to highlight them
+ in the output.
+*/
diff --git a/doc/extsearch_flow.dot b/doc/extsearch_flow.dot
new file mode 100644
index 0000000..6352fba
--- /dev/null
+++ b/doc/extsearch_flow.dot
@@ -0,0 +1,18 @@
+digraph Flow {
+ edge [fontname="helvetica",fontsize="10pt"];
+ node [shape=ellipse,fontname="helvetica",fontsize="10pt"];
+ doxygen;
+ doxyindexer;
+ doxysearch [label="doxysearch.cgi"];
+ browser [label="HTML page\nin browser"];
+ node [shape=note];
+ searchdata [label="searchdata.xml"];
+ searchindex [label="doxysearch.db"];
+
+ doxygen -> searchdata [label=" writes"];
+ searchdata -> doxyindexer [label=" reads"];
+ doxyindexer -> searchindex [label=" writes"];
+ searchindex -> doxysearch [label=" reads"];
+ doxysearch -> browser [label=" get results "];
+ browser -> doxysearch [label=" query "];
+}
diff --git a/doc/extsearch_flow.eps b/doc/extsearch_flow.eps
new file mode 100644
index 0000000..ed140cb
--- /dev/null
+++ b/doc/extsearch_flow.eps
@@ -0,0 +1,2100 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%Produced by poppler pdftops version: 0.18.4 (http://poppler.freedesktop.org)
+%%Creator: cairo 1.10.2 (http://cairographics.org)
+%%LanguageLevel: 2
+%%DocumentSuppliedResources: (atend)
+%%BoundingBox: 0 0 176 542
+%%DocumentSuppliedResources: (atend)
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset xpdf 3.00 0
+%%Copyright: Copyright 1996-2004 Glyph & Cog, LLC
+/xpdf 75 dict def xpdf begin
+% PDF special state
+/pdfDictSize 15 def
+/pdfSetup {
+ 3 1 roll 2 array astore
+ /setpagedevice where {
+ pop 3 dict begin
+ /PageSize exch def
+ /ImagingBBox null def
+ /Policies 1 dict dup begin /PageSize 3 def end def
+ { /Duplex true def } if
+ currentdict end setpagedevice
+ } {
+ pop pop
+ } ifelse
+} def
+/pdfStartPage {
+ pdfDictSize dict begin
+ /pdfFillCS [] def
+ /pdfFillXform {} def
+ /pdfStrokeCS [] def
+ /pdfStrokeXform {} def
+ /pdfFill [0] def
+ /pdfStroke [0] def
+ /pdfFillOP false def
+ /pdfStrokeOP false def
+ /pdfLastFill false def
+ /pdfLastStroke false def
+ /pdfTextMat [1 0 0 1 0 0] def
+ /pdfFontSize 0 def
+ /pdfCharSpacing 0 def
+ /pdfTextRender 0 def
+ /pdfPatternCS false def
+ /pdfTextRise 0 def
+ /pdfWordSpacing 0 def
+ /pdfHorizScaling 1 def
+ /pdfTextClipPath [] def
+} def
+/pdfEndPage { end } def
+% PDF color state
+/cs { /pdfFillXform exch def dup /pdfFillCS exch def
+ setcolorspace } def
+/CS { /pdfStrokeXform exch def dup /pdfStrokeCS exch def
+ setcolorspace } def
+/sc { pdfLastFill not { pdfFillCS setcolorspace } if
+ dup /pdfFill exch def aload pop pdfFillXform setcolor
+ /pdfLastFill true def /pdfLastStroke false def } def
+/SC { pdfLastStroke not { pdfStrokeCS setcolorspace } if
+ dup /pdfStroke exch def aload pop pdfStrokeXform setcolor
+ /pdfLastStroke true def /pdfLastFill false def } def
+/op { /pdfFillOP exch def
+ pdfLastFill { pdfFillOP setoverprint } if } def
+/OP { /pdfStrokeOP exch def
+ pdfLastStroke { pdfStrokeOP setoverprint } if } def
+/fCol {
+ pdfLastFill not {
+ pdfFillCS setcolorspace
+ pdfFill aload pop pdfFillXform setcolor
+ pdfFillOP setoverprint
+ /pdfLastFill true def /pdfLastStroke false def
+ } if
+} def
+/sCol {
+ pdfLastStroke not {
+ pdfStrokeCS setcolorspace
+ pdfStroke aload pop pdfStrokeXform setcolor
+ pdfStrokeOP setoverprint
+ /pdfLastStroke true def /pdfLastFill false def
+ } if
+} def
+% build a font
+/pdfMakeFont {
+ 4 3 roll findfont
+ 4 2 roll matrix scale makefont
+ dup length dict begin
+ { 1 index /FID ne { def } { pop pop } ifelse } forall
+ /Encoding exch def
+ currentdict
+ end
+ definefont pop
+} def
+/pdfMakeFont16 {
+ exch findfont
+ dup length dict begin
+ { 1 index /FID ne { def } { pop pop } ifelse } forall
+ /WMode exch def
+ currentdict
+ end
+ definefont pop
+} def
+% graphics state operators
+/q { gsave pdfDictSize dict begin } def
+/Q {
+ end grestore
+ /pdfLastFill where {
+ pop
+ pdfLastFill {
+ pdfFillOP setoverprint
+ } {
+ pdfStrokeOP setoverprint
+ } ifelse
+ } if
+} def
+/cm { concat } def
+/d { setdash } def
+/i { setflat } def
+/j { setlinejoin } def
+/J { setlinecap } def
+/M { setmiterlimit } def
+/w { setlinewidth } def
+% path segment operators
+/m { moveto } def
+/l { lineto } def
+/c { curveto } def
+/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+ neg 0 rlineto closepath } def
+/h { closepath } def
+% path painting operators
+/S { sCol stroke } def
+/Sf { fCol stroke } def
+/f { fCol fill } def
+/f* { fCol eofill } def
+% clipping operators
+/W { clip newpath } def
+/W* { eoclip newpath } def
+/Ws { strokepath clip newpath } def
+% text state operators
+/Tc { /pdfCharSpacing exch def } def
+/Tf { dup /pdfFontSize exch def
+ dup pdfHorizScaling mul exch matrix scale
+ pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put
+ exch findfont exch makefont setfont } def
+/Tr { /pdfTextRender exch def } def
+/Tp { /pdfPatternCS exch def } def
+/Ts { /pdfTextRise exch def } def
+/Tw { /pdfWordSpacing exch def } def
+/Tz { /pdfHorizScaling exch def } def
+% text positioning operators
+/Td { pdfTextMat transform moveto } def
+/Tm { /pdfTextMat exch def } def
+% text string operators
+/cshow where {
+ pop
+ /cshow2 {
+ dup {
+ pop pop
+ 1 string dup 0 3 index put 3 index exec
+ } exch cshow
+ pop pop
+ } def
+}{
+ /cshow2 {
+ currentfont /FontType get 0 eq {
+ 0 2 2 index length 1 sub {
+ 2 copy get exch 1 add 2 index exch get
+ 2 copy exch 256 mul add
+ 2 string dup 0 6 5 roll put dup 1 5 4 roll put
+ 3 index exec
+ } for
+ } {
+ dup {
+ 1 string dup 0 3 index put 3 index exec
+ } forall
+ } ifelse
+ pop pop
+ } def
+} ifelse
+/awcp {
+ exch {
+ false charpath
+ 5 index 5 index rmoveto
+ 6 index eq { 7 index 7 index rmoveto } if
+ } exch cshow2
+ 6 {pop} repeat
+} def
+/Tj {
+ fCol
+ 1 index stringwidth pdfTextMat idtransform pop
+ sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse
+ pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj16 {
+ fCol
+ 2 index stringwidth pdfTextMat idtransform pop
+ sub exch div
+ pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj16V {
+ fCol
+ 2 index stringwidth pdfTextMat idtransform exch pop
+ sub exch div
+ 0 pdfWordSpacing pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing add 0 exch
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj1 {
+ 0 pdfTextRise pdfTextMat dtransform rmoveto
+ currentpoint 8 2 roll
+ pdfTextRender 1 and 0 eq pdfPatternCS not and {
+ 6 copy awidthshow
+ } if
+ pdfTextRender 3 and dup 1 eq exch 2 eq or {
+ 7 index 7 index moveto
+ 6 copy
+ currentfont /FontType get 3 eq { fCol } { sCol } ifelse
+ false awcp currentpoint stroke moveto
+ } if
+ pdfTextRender 4 and 0 ne pdfPatternCS or {
+ 8 6 roll moveto
+ false awcp
+ /pdfTextClipPath [ pdfTextClipPath aload pop
+ {/moveto cvx}
+ {/lineto cvx}
+ {/curveto cvx}
+ {/closepath cvx}
+ pathforall ] def
+ currentpoint newpath moveto
+ } {
+ 8 {pop} repeat
+ } ifelse
+ 0 pdfTextRise neg pdfTextMat dtransform rmoveto
+} def
+/TJm { pdfFontSize 0.001 mul mul neg 0
+ pdfTextMat dtransform rmoveto } def
+/TJmV { pdfFontSize 0.001 mul mul neg 0 exch
+ pdfTextMat dtransform rmoveto } def
+/Tclip { pdfTextClipPath cvx exec clip newpath
+ /pdfTextClipPath [] def } def
+/Tclip* { pdfTextClipPath cvx exec eoclip newpath
+ /pdfTextClipPath [] def } def
+% Level 2 image operators
+/pdfImBuf 100 string def
+/pdfIm {
+ image
+ { currentfile pdfImBuf readline
+ not { pop exit } if
+ (%-EOD-) eq { exit } if } loop
+} def
+/pdfImM {
+ fCol imagemask
+ { currentfile pdfImBuf readline
+ not { pop exit } if
+ (%-EOD-) eq { exit } if } loop
+} def
+/pr { 2 index 2 index 3 2 roll putinterval 4 add } def
+/pdfImClip {
+ gsave
+ 0 2 4 index length 1 sub {
+ dup 4 index exch 2 copy
+ get 5 index div put
+ 1 add 3 index exch 2 copy
+ get 3 index div put
+ } for
+ pop pop rectclip
+} def
+/pdfImClipEnd { grestore } def
+% shading operators
+/colordelta {
+ false 0 1 3 index length 1 sub {
+ dup 4 index exch get 3 index 3 2 roll get sub abs 0.004 gt {
+ pop true
+ } if
+ } for
+ exch pop exch pop
+} def
+/funcCol { func n array astore } def
+/funcSH {
+ dup 0 eq {
+ true
+ } {
+ dup 6 eq {
+ false
+ } {
+ 4 index 4 index funcCol dup
+ 6 index 4 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ 5 index 5 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ 6 index 8 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ colordelta or or or
+ } ifelse
+ } ifelse
+ {
+ 1 add
+ 4 index 3 index add 0.5 mul exch 4 index 3 index add 0.5 mul exch
+ 6 index 6 index 4 index 4 index 4 index funcSH
+ 2 index 6 index 6 index 4 index 4 index funcSH
+ 6 index 2 index 4 index 6 index 4 index funcSH
+ 5 3 roll 3 2 roll funcSH pop pop
+ } {
+ pop 3 index 2 index add 0.5 mul 3 index 2 index add 0.5 mul
+ funcCol sc
+ dup 4 index exch mat transform m
+ 3 index 3 index mat transform l
+ 1 index 3 index mat transform l
+ mat transform l pop pop h f*
+ } ifelse
+} def
+/axialCol {
+ dup 0 lt {
+ pop t0
+ } {
+ dup 1 gt {
+ pop t1
+ } {
+ dt mul t0 add
+ } ifelse
+ } ifelse
+ func n array astore
+} def
+/axialSH {
+ dup 0 eq {
+ true
+ } {
+ dup 8 eq {
+ false
+ } {
+ 2 index axialCol 2 index axialCol colordelta
+ } ifelse
+ } ifelse
+ {
+ 1 add 3 1 roll 2 copy add 0.5 mul
+ dup 4 3 roll exch 4 index axialSH
+ exch 3 2 roll axialSH
+ } {
+ pop 2 copy add 0.5 mul
+ axialCol sc
+ exch dup dx mul x0 add exch dy mul y0 add
+ 3 2 roll dup dx mul x0 add exch dy mul y0 add
+ dx abs dy abs ge {
+ 2 copy yMin sub dy mul dx div add yMin m
+ yMax sub dy mul dx div add yMax l
+ 2 copy yMax sub dy mul dx div add yMax l
+ yMin sub dy mul dx div add yMin l
+ h f*
+ } {
+ exch 2 copy xMin sub dx mul dy div add xMin exch m
+ xMax sub dx mul dy div add xMax exch l
+ exch 2 copy xMax sub dx mul dy div add xMax exch l
+ xMin sub dx mul dy div add xMin exch l
+ h f*
+ } ifelse
+ } ifelse
+} def
+/radialCol {
+ dup t0 lt {
+ pop t0
+ } {
+ dup t1 gt {
+ pop t1
+ } if
+ } ifelse
+ func n array astore
+} def
+/radialSH {
+ dup 0 eq {
+ true
+ } {
+ dup 8 eq {
+ false
+ } {
+ 2 index dt mul t0 add radialCol
+ 2 index dt mul t0 add radialCol colordelta
+ } ifelse
+ } ifelse
+ {
+ 1 add 3 1 roll 2 copy add 0.5 mul
+ dup 4 3 roll exch 4 index radialSH
+ exch 3 2 roll radialSH
+ } {
+ pop 2 copy add 0.5 mul dt mul t0 add
+ radialCol sc
+ encl {
+ exch dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ 0 360 arc h
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ 360 0 arcn h f
+ } {
+ 2 copy
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ a1 a2 arcn
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ a2 a1 arcn h
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ a1 a2 arc
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ a2 a1 arc h f
+ } ifelse
+ } ifelse
+} def
+end
+%%EndResource
+%%EndProlog
+%%BeginSetup
+xpdf begin
+%%BeginResource: font CairoFont-0-0
+%!PS-AdobeFont-1.0: NimbusSanL-Regu 1.06
+%%Title: NimbusSanL-Regu
+%Version: 1.06
+%%CreationDate: Thu Aug 2 14:35:58 2007
+%%Creator: frob
+%Copyright: Copyright (URW)++,Copyright 1999 by (URW)++ Design &
+%Copyright: Development; Cyrillic glyphs added by Valek Filippov (C)
+%Copyright: 2001-2005
+% Generated by FontForge 20070723 (http://fontforge.sf.net/)
+%%EndComments
+
+FontDirectory/NimbusSanL-Regu known{/NimbusSanL-Regu findfont dup/UniqueID known pop false {dup
+/UniqueID get 5020902 eq exch/FontType get 1 eq and}{pop false}ifelse
+{save true}{false}ifelse}{false}ifelse
+11 dict begin
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def
+/FontName /CairoFont-0-0 def
+/FontBBox {-174 -285 1022 953 }readonly def
+
+/PaintType 0 def
+/FontInfo 9 dict dup begin
+ /version (1.06) readonly def
+ /Notice (Copyright \050URW\051++,Copyright 1999 by \050URW\051++ Design & Development; Cyrillic glyphs added by Valek Filippov \050C\051 2001-2005) readonly def
+ /FullName (Nimbus Sans L Regular) readonly def
+ /FamilyName (Nimbus Sans L) readonly def
+ /Weight (Regular) readonly def
+ /ItalicAngle 0 def
+ /isFixedPitch false def
+ /UnderlinePosition -151 def
+ /UnderlineThickness 50 def
+end readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 17 /space put
+dup 14 /period put
+dup 21 /H put
+dup 24 /L put
+dup 23 /M put
+dup 22 /T put
+dup 9 /a put
+dup 20 /b put
+dup 11 /c put
+dup 1 /d put
+dup 6 /e put
+dup 5 /g put
+dup 12 /h put
+dup 19 /i put
+dup 16 /l put
+dup 15 /m put
+dup 7 /n put
+dup 2 /o put
+dup 25 /p put
+dup 27 /q put
+dup 10 /r put
+dup 8 /s put
+dup 13 /t put
+dup 26 /u put
+dup 18 /w put
+dup 3 /x put
+dup 4 /y put
+readonly def
+currentdict end
+currentfile eexec
+f983ef0097ece61cf3a79690d73bfb4b0027b850f3158905fdac1bc024d7276e
+0a12b7ddcede59e3601ab4509dfe0977ed5bf624ebc1f818c45f1350d41b052a
+72743accb053eb06ed043568d3196a30bed220227e2a15bacef508449221cf33
+8a8666e92410a9aa91d5a31900a93c01ec21742cd14dc46bffa111ce10b78ae0
+1abaeba7f36cdf79a4733245c63f6d36234d6b0961f1ac295d6177931b9ed554
+bb5fc6741a63c493daabf03d753c7d2b8e8c01e3e280898f810da5985212c8c0
+bbdee4e8ab9b22bea83671c0460443ede9be044168f8ab50be5874d46660f1f8
+241cb261280a68ae2cd60e1648cff45c0ba9b15cb42f86217172a5b855265c21
+4d4b954937d11b94b7b98738393ce09ce40802e512bea7714fe6f163d1b27c8e
+c87419fa91767418abc44c94a3a22f97f856b0a4729be6973455a7f7ae72c671
+542e9e74258c2b8b2ad440a1b69bc7de2e54ed6a96d0bfde08b35f6fbf739ae1
+8676c03800ff3e63c6fc20927b3158e8d2cb6644eaf7831c6bf0e9b39aa14145
+e721dc46e792da9be78696808fadf24136f9da0c8003cb34ecb8af2b7de9e033
+545fbca53d881eaea40c638396c8d3b08b6e2b8f7d6188d055d6924bafb0cf7e
+f8bf2719495988b0efe373dd1aea97b0f486d0555e3a62cc1b36024ec3ada21b
+fe1629acf431928facb4ead9c41e3d4cb50ed2f651d2cb6ca8d0b1ef49d9e214
+e06cb029bc1a40b2052938f6bcd05f013d9ed1edc90bdea459c4483ed0d1470e
+30ee0a77ecfb585268a94a8bc6be7d28e5746525107c0a3f05fb5e34e0a21572
+14be2d95a46fdec2e36afd180688fc710c92b27d69b2ff8b1fc7f73cd5526270
+e5bb585d7674a351d9bda5dcbc17b40d465923103f1d02e7446d949002657763
+c82c8fe0372afe94104d148679b4e5be01def615b295d7c25e24660b2a10dfb0
+b5b96fc02bdfdadc10afddd821fff6caf17f11d6a7cf157d3d7f1aa25a00cea4
+1207c8e160663d23b16d2934ffe6a6c178d456facef20fd46c4b33f6d1ebf103
+b7cde86d7aff74174d2d3f5820186c696b9245f97554b7f62411429f1dabebf1
+ce4abebcdd2a4ccc1c06d6ff8dd9d7f935ba5218765a81eb3c727a40dae317df
+89cb3234b1a4f1a0b16f88ed1684d3106c2a6cc18aedd3b052df1a2ea7ccb8c6
+c6111abed60277aaa2b91f1da4a83c0b2d4fae8cfbe2873b7f9ec2e9ad05045a
+bd1133b95f70185dea97f1081565ac65139ff102004b00e1e77023782a68a752
+088f8d8cd2393eb3f649553f0be59b83687f4425290ff1e334794e59ab4dc73b
+26f1beac4c5d6d4d507dd7d13b8721144d28b82eba624965e3d8cf9334083a6a
+461277026b05583f96e489be17dcfaad73cc5b9c6021527879f2c194a5bb1869
+9cbef3ea4e14950e1aa56abbd38bf509629e8a4f0edf0946a47aea100a088151
+a9e296d1b5d7688aa0b3b121fb93bd52789d22fc32d645230419d1df1d106a9a
+90948fd443eb64a212b3595a133a4a30434b5074ff14f69368de4e0452515257
+aad6332ed29556152c71240df8a6746486d28c6a1315bc5c5ed08a5192c2fd7b
+a4ddcd7496139ae2e6e47ac4971edc88a81e2056ff81081b72cec34df2e6bf17
+20bc5c6753ae32e31ce0db86b3aba65f26335a57f2f12827f7495183427d3e86
+1b6ba27f7157003a92a9405c8755f71dca78e6cf0730fe59504cbe903beec227
+65da1f35eabc756bf32e9980eed40c0d1a201e12a71b63171df7ca971e36c03e
+8137e0213fe675b392ad8b3232752dd3864c82f9ff85f814becb6fc7510a1e99
+17bcf12a90c4ee29e036db54278f2413731df21833d1f8149344b46e4c3fc2fa
+9647e76b3cfd81b4fe88643e427e7f6d9b01f99659e531df0c43b4f44ed236f1
+17bb00830dc10a5b1896cbee06fde9b4fd9b0b138405a0bb83d78ca5546a2b41
+490f5322405f0ea6276d9a13a63b98c59cc9a0428472759009cda518c4dfce24
+49e27df9caac365a6ee3a8ac451167c806889760c404164f941d035b6a1df55c
+44ebdda9484f4da9b07c059ae59617c0e86ffa71b9a70322acb3b60071128799
+46f950e04e6b634439b06e05a9781a9ca6b9cbfaf508a835e2daaec957d95fa0
+031f9ae42c17cfd5adfb81766af25ac5237818909e284ae4a439b8b2a5050dde
+be0dbde491d135155e98ab579904d045797ea516dbaa4529675a381372fd437e
+53f9372dae38f0eeece282771fe7c3d1e68061cc242e4640131ebfcf340b453e
+4868ce4825067dfcc88c7d84aee3f06eb202a89979aa520e501288e93f742fc8
+6b6f43e3bba4430be40b099cb0535504f966cf50fd9ba9fd358fa184a39eccfd
+4d8e5c4ec35b448bad9cf5bdf15b729a4137a9618a5a44db7d9740a15e0da9c8
+02b428d40ed5401ed76095c73512cb626630608c74143afaa7be85562aac8d81
+48a5e603e3b69b89706b0c1cf5c85bdeb32611221c13325835238fee492e4a08
+bce9741094c4cdc3edd691e82d224c7866590510e2c7cccc07e11484f62d7930
+3fd559e4e511eb67bab756f30acecc560f5def3902bfb52abfb7aa48e72f2732
+b7eb73c0123f6dfe97cb69897c1db3d57ff05466c3cce4730e04e921a5e56e8a
+dd31933536393bc00b3ab3435ab950965a752b913bfdff22a8e7df7bc441e5bb
+3a3192bea8a17829faa529e56ac69e5a25a6797615d5455e4b430627f9c219a3
+64bf0c55669cb872e403ed1cdffc63cf9223ab581bb9d7967892dfef80da723f
+18e199e0b57f12ef0210326aae328882d982392dfcd40e029ad3f53dcd820b4a
+61b580bc3f1b492453f5c752e05c705bf8bc05485c5499f804a6ed2a28bb63bc
+7e80759003cc7ef0a1d9d51dab1f785d14eb86bd9a4f4221951da58fe7263e23
+e58a2414dcedb6ce1943f62a65699080bf568cc0c67134d8728963466de67133
+27129138d203ab8db0079f63349ac8ea689ac7615d866b7f600b2e91333b61d7
+3c98401b1cb0432e90fa7bd87d9f4fdfecbc2dd5e5eee5daa7d7bd959e41817e
+17525a472ac035c391b918d549c38bf2b2426798fc27af235a725ddff5dc79af
+b59198c94528a36b8c7cd5683f8af50107b45e02fda4c787b4f14ea4e663bbd6
+15be5b30d6979456f6191b5051f458bf19c91ac99a9a8505a03abedc243ba287
+2c3305b81288a79f5ed8452e2a2caf3fa51208946c72b97e6d59ef74bd8b96ce
+d9de45d7cf76a6891c7c0691298855a366737da9be57d98c25c7415122c898a1
+564a052036a3aa550c2bc83478c4e15933de6e4aad64b2e97c640a2e8a14933a
+baf85907f09588cb05432f716f05efe4a669d16c881dadc0faf5a704dc91f500
+6e512a61372579eeea5f6076cb8048d71a1e4a3097bc27433bc3613ebd8291e4
+27bd9cf83c0969562d5363662f74f2ecd57071c4d331a26559bf3e307d0e2d1c
+9a90a3fc92254d2656555dbc0c8c3502985a00e705213e4522d5eecccc5f94af
+0f196501250a4200b04b491f64388f7c3aa37970a8a5bf78a072bcbac61cdbf0
+f95dbd13b8defacae1a53277fea4f19f829fced3b4cc6e209bc2616b9bd7312c
+87d78cda5c9f6bca02595086adb6dac9b7bc6c9fca577169940fb58c818a3757
+5de491222128989965657ea8b5dbd96a697ef71778109a1781bd7ddb9b2132da
+71b3bac95f6f69fc615b7733d709402bc7fa0812d18aa22fab627f91baf4a346
+d8f103362c0161a3b57d83856c63cc7150fa2ec1ba537a4c608bc28c85d388bc
+f4105158f0c9d40a573bab28148104e2db167ff009d34134008cd1ab4cea4091
+c04dd6eb2353686278cb190506778602b0a642d3997caa982a2b3c84f8bc97e8
+3a177fbe6c69512014cbf7ab75d5a35a0521a2d1204d7877f75a8b0816da0bc0
+58c0ccf411b939931bcbbcd1d3d92b0fee9e58012677b1db645c14ae63b7c4c3
+e4b18b890802aaa72c0d8cb771ee4e46ddb6d714894aed7816d7164799b70d7b
+64e0a50b979c3616590b871cbae60b9449d02fab57655abd48843da96359d608
+7ce297a26e192491d1cb8420d7cbf1dc66b68ab4299ed1c500ebb26de35f9563
+48d497c3c0858e812fd3d43cd76a41e24f19752bbc8a4a69510c9381cdb8a230
+31f8c0a914db40a659a5b51e19fc9024471cce4e65cbab05a3562a2929398879
+67cbe49331cb58e936a2b6873d3dedfbb378414914a2b78db4daa180a4b40a97
+2fec68f931b75f2109fcf824cc7439ea693c8c080abed27376461dd5f86617d1
+a931cf1caf206e872adf0d8b6e35499fe3df6d3833dca2daee3805fd76f7cc5e
+f2ac6f05134e8da55b15204896002803ad497e67c2ea83b2646bc13a72f73d64
+2ebe4b1d5b00a444744160f3341a84335643e58ee6c64acdfcec21bf506a6a30
+b70b1fce06b97b23c767e7e429892085fbff2996aa68e4776b76de0f66edfd89
+b015cc3a3e4d70cdf3bcad9d48b4e17b97f568b0f3b1557d003cd6f087aab912
+a15e88e51f6e33c8c8b2ab69fa8e81f09a75e0059723f1de598a20c567e681b6
+0e954bd6d80c7515870bd6158eb93e8af8ae71542d681895e2b32489694f090e
+bc5b560515048626f803b996baa342815b5adfc437dace01d549a6319eff5709
+6c537c9aea7c3f8dd978d42624304a68ef2427dbc0acd85a26960f10e348a30c
+dc46e46dc16700f62108fe6c35059759fe69c729edd6c91e83cd49535e16746b
+6dff037927de39b77eeb86fadd9ac5c89268c3c529fa1747650cf9e16c7626ae
+c25817ea46c1ab2b0a7a9c7ba33087db199adf7594c297a938ddd7ad595c6942
+552ae76711f444b5b833a92cdfea0462b6766685359cd4c2afe4114d884b230f
+dc86d680a9b10a4333d68db6ebc595f86806392857b55452e44288a42f924754
+c22778c6d7bfc3d4337bb3a8f68055d0d6f5053700b784c480509caf63336c68
+7c5bd339757008be54c289a10e62d5c83eee133f32168a68aa259e8247d6afcb
+25243df6ca8c238ea64082265560188e73a47db7603a1802e7ed3693a9b7e5ed
+7b0332171196792cd5272b640c8a5363978a87f58b9d1022d5e7af38d1e45dba
+bd89b095eb9e581ce8e9c314a8152465a4663fd4a7ad1996c08afe96d3975d67
+fde3aef4fdbad38c739d0f1bb4584f919b4b5b8a06aa94bc3a4162aaaf01cf60
+7fd24e90dd4889795aa0fd42e4cce9b0c4323963e288dab83c1d1187c1251d77
+da1c6602311cf8a73e16699d6646bf62cf68b3da3855648508edb97cf3614ed1
+141d158ce8f86e055e9034fcc9c77fe4f592251dca7e61952859567c6ff4fa83
+15b554ff50b48bec4d99ad1221b7caa1d47a8f430a07d49f561296a74277adb9
+c21c8b4ca1d3bf3b671506f71d8f88d37ec1b03432c2bcaa337659c35747b0eb
+1721073e4e60e93646c719bc4e27c5b5fed52f456f43158ad6ba09e9db6d0c17
+fa75bd7a80746258f7725116c37770e261c9bcf7f578f3f12ec7037c125fd86e
+4d38ef23886e18f4e206397006c8c4ba0105e10fcc254a718e3c8ba6dd71218c
+4768fe0d8efe2e01454dd52ef33080a1313911ce3e0afa57f5b74d7caef2440f
+f148f3c8bbe0cb2418a0367dddb217ffb47fd5766ab6db331bd9d2779ceac6e8
+e3e6562b79d947e687ce271f8f024c5cfe61e3453cc7ca45efc6b682d2da8ace
+dda708fc65b668e285e6f542b9fdc071082076c4ec2312de40214f8616ac615a
+2669bd490e89d5c125d6c0d6378113f4d37f1d6a06c225c7b0e879746f13607c
+0a4b98b7d77ca29572495f4edd58f292ca28417808c8e60c3dd8b1a9d185cc80
+5784e9a1ec1f290197637cb2f1ef65d1b114bc0e99a9d3070be7199f3d30db85
+cb3b65eb8cdd60b44567730017f4f851d4b15a15bf4312f79c05d5ea03b1da80
+1149fef5ad43eded70f470e62281fda1df9ef72f180630b3b1509eb5fd9c73e7
+f02fe23f554e5b74007d6384f6255ea4bdd2a6eba0310eda07327884d26c59d5
+3d38f02b11815e8adde0804c621d6cbda143ff30856063abcd0059183828625b
+c486f27c475059855c9dcdb5831ce58532e3e6984b63b690a27373d7d5e613be
+666ed52d9f743fd3c373984fbfb8ac8040dcc222ddff4a2e1f6d93f64aabad9a
+286e3e07679adc853885c8658e37b0efdb68fe51c09ec2b6b69735b84d2aa481
+793f0e5982e006d985c0c2b8d394b7093a210168e58688ab1c07b99b857e9052
+3f90ea3f4f4202f7751dc55dd7cc187f4afacced589cce0189545f2a26c9d283
+b14ab2aae2e5393d416e014ad99e27f8814c0b1bccd6f798865e243bdc9408df
+f7e6fca3b515e5edd3af9ac11e4bf0a7b7a736959a4f48d4e519d069263b0af1
+43dbf431cedf2ab7d4df2cacb62627ea46e77e20233ede4166f291a3a19f6227
+1ea68be133a61b6342782ab58310c4e2b08782800f48d311a7c15d1a6d3f7c6b
+5bf2d91cf23b931793adab17d9f085a9aecb9d4df2c4c50c5329503c4a8ad83f
+df446b306c56a2ca97bd50f359280415f8cd4bf01817da0f01a0e48bfa4c7a1e
+85f052a03369b0ad7eb0122585bd4445dd53912b2d1ee8cbd9b7e2716166790c
+32f4e068134102aeedc6ade4d5db39ac29f424b0d5e327d081990adcfad18f6a
+b64c7f199cddebf0490b10847d158b2151a8e79b707af40ba4a38c8c02fc49dc
+ffa7e2813ad7741ab7bb29c93e146d81be2a2494791582618f49aa9f904f8faa
+1ec63adb809cd473ea6743509617fdbf260d4024b4101d962f66f361d7257804
+e354e050004155cf050ffc6adfc28c4f742a3231c5fa37c7c826985c5099698e
+da86f0a2baefff000a4e74597e5bda20f8c36f22ddd94ff45e16ac91fd250eb9
+d8d0971bc4bfda5b6c0c14d850822031fcc8f231023a579c09493ff2ac9f72e8
+1b4c0eaa64fc3401b7e128b2642aa708ef990878091956a777d908fa0c4e1f2d
+a3363e098a28b6f141ef68258e2f6ae3ac089b3b89de4379a0da96cfaa81a7fd
+fae2fe9dbdaa3b21435793e464baaa346a722c385e71398949d32b76c6cdef0b
+05c752130d43ebc45a1738f06281097150423f885470928cc1153cb01b2295df
+e17cb19d3b4d576209425a806b98d83e80158b67120d6ea0a65d94582e248d3d
+d8ad826bbbc00b9b9dd0f4d606a65b1a0ba8eea83cff745e222e6f4645055a9c
+bdf1d99160e0e4854d989f07cc3f393f72af97c3575d6f1d8d4312848bc72bef
+988cc436c23f4c6a2a5569a79d04a0667611a3b0f2e2b8ca0a6ce0536b0e459e
+21dd3d74d8a94be16cdb3d65a6534be608688944c0d68c62e39899104ad6e587
+ec0f3fc097ce54d3e25c9f081dec3be6c71b714b9f92c15517dfd763b9bf0496
+d601fe4690a9a815e803221e007a7ca74743f679daf6a626af5a6525b394731f
+ebbe7cadb5de910c2163e640acb041736fe4e508dcb5c7d87d38e12ff80fc903
+c26c480b567f057b193f5d4ba352697b9481d780d94b815a7d96ba6dcc34e39f
+43caf780d101bd73488a88d213063432f8e6bea7e7248d85ab48b576ee702af9
+364c81f7d5c74ddad8315ed4345444e0cd92ea23b4394073178807892d2925a6
+a43a75c68881385a78d9d5582d3f3f8bae87ae177ea46dcba9af17217906204f
+751a358cd8a4d8c95ca76651271963b6d2ffdf282b653c85ede30f9c8bb5f113
+528e221aa1a6507364f74ecae922bc09e6c3f42166b2118a819638a85560c6e1
+eb7bf2893357a81571201a2bc31a91ab89489fa2050d353039a7085aacb83609
+825ae7392a84b6325bbf17af46a9a3eb63ad14bb387987f6d756ffc59a2a0893
+7538a0efa89ca08f9785952d2e8bbba0e6023ebb8fceb5abcc3c0c3c1b980255
+861d991fbf27e70686fa238e92ca9bffbad61bfd48c5b8e8aa8fde96fd9acb2d
+946b69a51137c905955ceafeafea0acb8a0c561808ec2e0d4fbacdb7ef9f9abf
+afee72f759e8208559c232ffe5bf6cd3e7cbe88ea579e795455f7c25f4343455
+06d98be333bffa7f7cf1f83bc00e38d2503ceb483519e3b1e5cb7751c00bd2a1
+3c385e2f88ee5df92086b57fadc621a1a539ff102d4fc4c075ab1d800eb1efc6
+fabdc04f81065f0ef3aa5b947d904410962f6533c1aa49b86178ad45e35d44b8
+66c938876f2bdf1dfb28d793bb5d049df0cc3e21b8ae8f9b75ac06f00759d48b
+f39c61125641612bc6032f5b6046d85ae9c7102b99b93f7674e80f96a1d74c13
+68d2fdfca6e8535a9d80fbaae20d681e1918b4af227270f40ee97fbaad4a4216
+908272cd9767fce64130744d0ac38825384bd51bfe19a150b55dd390020ae359
+29d4026d4d8798cf2fcabc5ffeb88f20129ff22baa1bf3fc412b404234554507
+5fc332a91a87c3ccaaba8c201ac784fab723c1371991d5a4c5d865727dc7170d
+876a83dd01b10c294e651e39a2d3a7c7de70817b0508f612856ddff87bf404f4
+c750437a96608c130bbdb8dc14051061957ec0976ac3b58e117b85cc17f7be4d
+d59a34a81ecfea08529704d8cb73176ea03c1d873f0a7acb41d533c8d68dbb3d
+9b879448ed2e52a98957c41682fc30a002015af634229c4d5d6b900586a0a0b0
+6b1fedaf188610cc3bfd97eb4261460ce68154b3a5a19a218bbf3035fbc64778
+89c2be397cad1e44c4fbbf3260bf85eaea01ca97d02b4c366a44fd08be6f197d
+f8243ca699c2b75b54756ab361115fcc5828dec91dff364db969960569e59a1c
+3fd2b76b4f88fd9309f8c9962d02ac778dca69f07609b0b9961ffac6d942943c
+bc2e3682879841df4f1d05350302cefc029100f934704dcec7e3f15387153325
+8ad2b5b5ad89d153f53be6390ca66461b84fb405b4722d3e3a205ce3bf339018
+b339f240c4956edd92e16ed988b46813e5e39533804efbc6e426304523b82073
+d9f296b3f8283f12dbb66157440222a888acde1eef4dc861f9e8d0e20c5876f7
+4e99c1dbb0b5fe81eae326545e84285864f90353f9c1c21c166deafc24ffcbe1
+a19522ac8cbabf3bb73c36bda0238a19da380a6ba263cb28f99d3643ca4f4b21
+ebdb9e19f1d53947c8f43a22320f8eb83f152580d83dd6cf230e30b74d2f0bf2
+6d6b621865797b989714ddc45136974dccdc37baa1a52d021544aab74521e9e2
+ef0607d951b1e4cbe230a9a1095df65774af0c2a0c0f1770dad9e054dc06c81d
+30801a927e525afce8cb8d753bfb1fc2b5d967b9e25c7cfa39bf6fb86dd482da
+0d871d5c8725cac7b44dcd5c3059f39a4cb216177100c0f99572ddadf8d7d537
+33db55286717ce9ee2a12357b901b675c566909a0b4c71bcbc7bbb7d36aa72a7
+018895b617ed93853602a5fd52daa01da6d6e3b713b7fd9d6f75e05f21857211
+d6ed29349ff0e628c26df07d1c079e556ffc60585ec8e91f38c9b4ef0a708559
+b4cc4155ff42c48c18731bd231b2dcb32399943e3fd64fb66d3011cc85e9fa20
+e28c741303d5b1f3b7178753cf97364716e6bea337a89ee47eaf9b93f938d9d1
+0d82d4c0e3927af3c34927fdd5fab439d303d997637e2d21725bca942bad146e
+4df93b37e5a38e4da57cb1d6e6e278b17a82644c800e6104eb2518c03ea9b8e3
+f9b7611066ef9afc58b893e3fadc53835440a47d93c7052ca4b617c1d958c693
+ceb60f9a2814cfc1b4a24b32783b389678bdd14fc3ea2124f124afc5ed977097
+af7a1d3a4d825c55f0842b2ac566e43458495b6f51c011d7e78818f6d934203a
+74a961618625a380923926544b7c13c14b2180f3576cdcd4f2140bc90b2ec84f
+1aca97f147781866d711448c1dc8df1fcc1a1769ece2ed5cea053795c0cbfb72
+04dc61065c87be00d9c0527d5df881708fdbfb7fbe01a933775548eefb736d01
+4a560cdb4313678581a3b1aa73d546869301f309f189c2df29f3d4bebb3b5a72
+046354c2edd273c9794c3659bc72fe7fb7442e75b04fc197a49efc2ea39ae0b5
+d1dce9bb509b5085445a66b6a59979c26412f1d6f5ebae84175ff08a90c9be44
+06797389c439693e2fd2f2c26d2e9dea41c505c32477ca50fc01dcd53d388e27
+cdfd4d73c2ac2fa03b9eb934479f0419ef50036b682c9ad8bfdaa3adf80a03de
+9f29b7021cf0441deec0f002fab57da0f5be89f5da4597a2523a2e7886589002
+e5cbbde0356b391148b5502eaa3b3689871a1cebe9b8214992f5349ede7d799a
+57b85d1e2ae706f8567efcf24081165f53810a2dc9568a263f69c40eb55cf317
+82da10dd970dc79f6593f1cdd9ce552de6c7c9fd3ab21169a2e487d5fa959d65
+9afddd071a0d756b5c7debd602cf9ad3e6b3dc3f29d954cad22ff28cf333ac67
+b8793f01c6f13c4ae2b6732d60633b59c2d9296ec77b6ee630906adf73ef8603
+3317cf59b6ffcf42fd7a68133f0673a5c91b8e0ec7b88872e9ac8d0aa904af60
+00799d57e1dccb74496e345dfea868ad7498f3ec7b85558a1fefb6f03c7d5365
+cef02b044b220c162c530b8cc899887f8846084c7b4fa1dcc631ba3a3773fa22
+443097b47852b119b42df9d58ef3d55ca10f38b04f378562b3bf03140e25544a
+77e66cb9589e6f9dc0a11b6c2a35fac32ce9bac552dc54270bfc025baf639b8a
+a5e3dfda4908b869969bd633a9b171ed6a04a2ee6e3744d7a348cdf09dacda62
+5269181d8d0fb84b468d2eea50fdf69324bf64ab1db3ad0fb2fb9583937f0be8
+b41f14a751d7115adf2d329db753cd14534cc282f2b4a4bf497a4c7b69cd25a1
+fb33c5e91796b885176284c77a119b50b077001b566328fd23170e4ae611e342
+6fc26443587e3982cea97c79fd63a4dfa95efee48dd81f90d67e40f283c27947
+d0f0823d2d2d26210e5243d2029b2ff059336b57b9b1334b0b615bf357c6a732
+c8d5165f2c9a6f310e48a2e4d7dc965887b45c14c9b744bd98de8f33071f0dea
+693ad64a55d03b2891660d09775030eb5c0e6e868ab1b90028c373d3448851e2
+25dc9eb442aebb5912ab0f3b1107a7d96f9d23983d8a6cfedd589e59fd355ea0
+aec2a448fd9d254d39331cd80dbfd653fffdb2702cb848144c33c28d207adc51
+097c28f754521e715be8b7b14c4f86aff04fddb0bd52247d814192a884e5af3a
+8f675cdf0c9dcdee0668773c3a3673af8f51a71bdfea19d0bde8a2a23453164e
+dbf01c932db93128b686cc6fd9a1dbd506b6c52664c5aaa01901c5ac0a8275e0
+ff4ec66ae3326dbc1b3b60c4488b6af86fbf30ddc1e3e3a8d63d7682c222e746
+05c95af3327e694f3b3c1600083f9cc241f97c5013c9a0588c715eb4dd00944e
+824e43a7a1c1fd144d1098628139034731eb1cbf633184cb857a17855f277bbc
+18751799ae28f48130cbc1ed559ab1a5abfa2576d59fa35772557a6fb3d15b4a
+de8bd38b763be0f8d8166613cc37dbcec1d65aa06c7b9f171028fddf8b55093a
+2fa509ce882054682fcfe32d510012ef5ddcf39f0ae5ade25af279829f8d47b6
+5b89a40a71ab70c2cd961aefb7004d3910c190bf32137e4d9733b971db4616ba
+789c741efc39c26540d3228884b4bb490bea1ab957682d250cf95e1d41c11662
+3925e7778755c11c654d42dfff1db2a49c5b57c3df98d942373519cb02f36759
+8997028e11c513a99b4abf115c61e2daedebb709068ce06692303cd0be482289
+18a12dc126af0e4f81766acf9a84526add4d2fa145cb5452c09547de307b352e
+141233cd8aea9f965070a2e6321a795f896c0cebc01ce3a15a81f14c14d74aac
+a4ab090125fecc310410da79bab5dbe07e9eeb2189788f491c457a82abf7f79f
+427932c8ad38466431e28659056c3d5a4be02c8d0d054bcd4f9170aa7b7b0d2e
+9a4564af66eb7372fe981bf441b68cf8247d11fcf0bfeb6453f9d2210dc880b9
+b9af2bca1dad558c1be18eab687f453d4aac976fb9466a6602ffca1dc852a56c
+50556d777258a7bc26489789fb4fbe2f70034eef6174244ebdcf514c5ff72391
+d097750ac8a9fcfe6c94af17b3a5f2667ca2a02e7f32424ad5a7d902751f7c41
+c9a7fa5fae2d8d7396f8e586be8ba8f960ff3fbcbe783e5ece80def85cdf792e
+33459d996a28775979b335a8448523c0a187dd8f3c0831231231f2a158a7b764
+2593932c9e0dce8892ae708b9458993d580656e1614f2d076f256a680ccd3d37
+0e37cde46dbaf38f096b032170759ec0619cfa0389b17568017f8d2811727965
+c75eacb1bf1b179b69567b0ed8bdce2ce95e98ec7a9a573a79ccd5b4990e46d5
+17324a06ba418b34110feeabfb71c1e43cfc1650179fc1e5f65fef017498b83a
+1eb5fb5e340a1b19ef7f10fd0422f6e7f640db9a46762fbbaf33e2eed637ee9d
+93cad018e33c4fc821212bb0f38f2251827a46f38c38c128dfa891f0b8ed1405
+4c651b735837a0f862967c3d39912e288dc3939816e015e8be9ba798f68c5e89
+a4184aa18392352bdb53119115b1a100e0941b80fb8017dd198c7d0629e72f27
+da2d8ebb59de72ee46daa03e57b12513988f2023484d9f0480126a378ac134a7
+5c2bfdc4df5b8d8fa77ba3fe2da9a01ec9427a00487b3a81b50a118c528b77c2
+2b57265e5f915a063fa3e8bac0ff7cbea9ddb19ab8390775df6049cb85921457
+cfae8a868bc6584a60223fa19a363f98876ea3d1e8a69337a58ffd75c9b296ea
+5485e343c04c72a53945e21fb479495d4686302f39188c01b036253ba0a18fc8
+7aae335fa522a435094c3608cf6e2e37fdf5fa3f59048fdbdbe6c58dabafe941
+a7af5aa4ee7b44d64df374780e9e2d691b4639e2aaef8c52de72b51f2bb6506e
+5e98f8ae236d183c9cf250dee46d102d964aefb7b82ef32d19a03aa88ef2ab97
+5f04a6cb5208f570af43f73d804843404eb835e5efe3e34887a37816ed3cb02b
+13e91be5bda75a112d1d27e92e462ec516100ab117b2882993af81dfbb58ebb2
+f5bc5d5eb98e48f73e88144889677b31d3c660839854a5c611a52bb493b64455
+3e6948d71f94f04eea57f7d458d7d78bb278d83065bdd9097f252d39a9ecfb40
+8f2229ad5edaf4afd518c804214dd2458b085d7bd382c7a1e697b5e0c1a47c25
+e2cf084d63bf186635783b56e6b36e7da64e3f9e3e7135d74381d957c0c62a6d
+2c4dda1c21a8e49979dc4946c3bb84680e4386750d4b19c4011759d84f90cf31
+b268f0af056d8566e84939388ff4cda569118ed71a2cd82d28b44e17c8438979
+5a4357f70f976891292e15448c74ce895be53e4212079fba23793f3c247827b4
+4f0e39066964e756719c628e6bf4a5f080de8402d5d1c154785564e019f13ca5
+b45b525b325e29f193557770f88ef82f8d7704631969d4ad624206665ee1d38d
+7ef7a7979aa05d39528beb6b7764d88da381eb63f0cca2f797dcac11011445da
+21da35e051c1db3da576e698451a0675944f5749e465faadfa4bfb09eba5177c
+e8cecbe67fa06b74d75278d7f28c236a596a17fea5467785f345197a43ec5f2e
+1b7e7e2151f287ad9181ac39c9771a1713f45b5ddbb402bf674e3eef369647bb
+c37b3afb327576831021a1a38fc4840cc4716da8026d16fae600d543a3c4dc4d
+7cd5baf19f1db2a24a0757ef6c3bd8047288c1436eda2bd3f9289e6f8b003dea
+d7b0cf49f3aa8a56adcc26ae300976e1c84bfa04d9a1887682d19ef68f52b76f
+dd0e03f64cc92dbb3ebeafbcc56f8a2a99af870bf7f0153dde4202ca45c530a0
+562dfae59234f4e3287b93bf427fcaa8d236606aa43aff3862063c0bd73dde6b
+dd3ab4a8c4d6ad9c24da288dacffd02aca90dfdc72444c9bcbd331755876f649
+e4b665d69921097c364eb8b0562090e10f4d719b2b5afc9312ed39c77e91ece7
+61c6c940133f940a74e5ce3c05d9703556d28a5839727c54800ad0e496885aa4
+052f65813ae552e8dce8d6f73949d0fcf5059e85ca8a1c137d751c6b8a87a52b
+198254d01258074227501dbe50de2b82bd2510e5788c46ac997c65bf44dd6928
+ca9f7a902bb957e277e7380123cdd93cf75dd6c7e5a56f93f114b6e46e0407d3
+ed544d781ef6fbfc704a035b7b737eb332457977f223d87ba6e3dbe827b4fae9
+e687f6975731d42a8977cfa67f94e90df98ca790e89713dcbc07cf27ea8c4584
+cc933fc342e5c5e740ee920ac3403d4deee426d35e1062a2cc7d5e23f568b494
+95c8b4556a8bbb0480ade618566f537b440ce52ff7d2cd89fc806fc388e9d7fc
+8bf15882a38ae0e11915ab03c272c8a312094938b9b4282ef3a321e3bd82701a
+50f8a4380fb32533cf4a100b0f96475a0f12fe9ce7e6a41784fe7c83f05869d4
+2b70febe4f60bf749429bfc4721acc4e17a961bd7da411471edb7a32f4479f2f
+079239c9bedcceaf35119982d686545cbb1eb0e9f429e9dbac1b743d28d12c6f
+faf8f98a3bbd60518803d997a56bb515602dd3a75f7ace8adf16a6ee79233fee
+1d21bf40914f29521638aef27eb796b06b5fe274444e0833ab9a79bddcb33443
+5b815d0af72964e8cc297d246c6bd6d78e0e8394d8359084963b01416db54a3e
+3a6d9784320814c4fa99aab6c4934b76a26c5e014d3fd202935f2f9399dda83b
+4d652ab89936578ac2c70daec483f69422b25472458417b87f2861ff90aa37e4
+5c07ac19fe09a4c2d37c917941f01682e650fce1785d114abd5949ae733bdaaa
+d98a802437f465bb7d2d1e0d4118d6ddc9aee8e08e606d9703c319001725da09
+5dc1e3a421f0c5315e28765e9571982039d5313efe20de55e7b614184c4a1e4e
+af4a89c62331c6f2511d706c2c4248c626e6474c450db1838f1d8b264e406d6f
+85dc63e78936a3f7d84baaf49bbd3ba15c58fc4734fdeb13d1f1557f29ee53fd
+bcca5d008c60f868ab756608ce889de583309a303cebdeed91e7c4922526f125
+58d2e751ec11b3c0bea88065ab0241f9d1e4c6144150f92f917b629295da2e84
+33a66b4a6e6c8571b684a675af7e77cfa6723f82dc6ac13a8a568ed06a519ea0
+a2725cdc99096ac0ce941b93207ed3f5991241f709ef7f9e8b2acb77100cf293
+452a1917d32c2f2a798af506a827be2d3f3ce87e3d920a0d8cf8e98a4bd3bd99
+e12f4374e0f6ad25af32793c5f85b77e213c7805156d53eba08d9a84ba43abbb
+a8202d43091436113d930a138dfdd15774397f496aea9172ff0302555658d3b4
+f6926fc115bf3de066f2d3bdac9738ecb824713de70361c91374fbac965ed71e
+e2aaf3a27a9cc5564dd26a4bf30dad76ec5f955915b1363ddc6bfb706b559fbe
+e46f6b6338dd6a07ccdb23b33b0237c8f0a428fcbf6db62fe6906e4a593b4dfa
+ff151b2cd167951a70f535394d84b7ad727bca8403cfd661abf9a72ca0634822
+f0ebf66ed148fd7b29513eb151c8d76ea7b74902d76ef7a88d5c571873bd219a
+9f7e60b5d6b77bbc1afe19165f88bbcf45cffa773fa9379259c61a930395ce89
+109c5e3a14066dcf9dc8387209c84273ecac6a6cb033d54cbe4451036b0b5335
+bc4b3a2c6f6a4395fdecf9c1b88d3b8840e0a94b0516c5821cdb3b15aa06ef3f
+e3a2c4729e258156fb7ade7c1b8f673dc87a8c87d6229df03d88fdb8d7e122cb
+db3c8e9eed4ddd03ef86bf2b6fb140187441e7d3ad4bff4bb61e57dacbb792e9
+f4263770c169933f99eaa94f686169ac46803bf6324b8498c154ca78482224ad
+28253607ce99680a755c573b8cc5bd9840b2c8a2518cfeec51a396ec8e3b6c3f
+980a3896feedde1a0605ab8d7891736e2c9502b5e2b3de8d76da62afee99a77e
+1b079bf6f92363e8a5b6e605245952f9cb351206b65eddff62ab5730b81d8531
+1489f9b4f4eb4690844b47a8a2cc0881180d3b5bb8f6bd73afcef9300002c168
+0503cab52a1c6c10b038c312a0c5e59c60072d4405937a8776bffb1c07d0a876
+1bb4aab03dedb634ce0192bb51b07dfc815073beb441be59d2a5b29a64e559a0
+d0f33022188ca9e9ee43530036e15604ac28bb7349b1f6b57ffea79982da0f9f
+ef3b0447ce31ab3bbfc0c03b7a421a836b8bf793fccbe963059de30c4ec0ea18
+bd7f3d00ceadc9e611bf4c1376a64087008b5941734d404646b9f698dcae3c90
+6f2208158f670d807d7ac8509a38a95d16679d11cc23115fd80301e84f4b200e
+e160fe96e54346be77e24998e679a0e1c0579135afc37c68c5163028b2c026f5
+d22035539795135e468f192814b49c4967e4873799ae4fccd31cdf23f754ec82
+068c2448ee44a452a0b4bf877a7c420006ce3e9e032d830e2bcb814e447b0147
+3cf5933f6d82cb74e6d1d5d6211484ff1ab6add9a46397b42fe3c7b7cf6357cc
+abffeda61f6aeab2ef6a84ba261f837fc8bffdbfb3ca6901c2b4b29834e08d4d
+45a2dd4e8a51c229d30915ec1bcb1c5486a57eb7490c70c0dbfa01fd1c53c998
+32c7e26e50265f54b8197a0316d30a5646f6e4a71d475e03460d81e8b658327d
+b8a1b1437334d3a907947b2c899e4a53ffe9e8227b2d5420ad4109b2b136ad02
+92b5ccaa83556e85b2018e629113c3e0d4d484bff995a484643f661975737cb0
+eb80f2b1ab319b1ec6251c49ebe855e2d6ea533398f9b3148316210b46ed555e
+f68a949b73f31a4457f45588654bf21d554b39eb23850e3a10c2ae0e7369c685
+641f6d8f43936c9250768af2829cc655bc027fa640aa14b18a70aa3a75524911
+45e6a7df0d81e0b7e1f3587ff086712368c48351d661add7e96a25b33f9f1f77
+7cbd3ad42b6786c8b0ae23f5e61421a0b660b7381809f13664aea3067bad45ad
+8451c40e07f38f9b6185867caa2a9ddc8c37647c6b6a77d281185db7a56c39cd
+ab0ace10890f5c0d7807fc420a2d0948c3880dd22e0b6aada2580f9a635d12a3
+05a89415a24ee12b834a6d01e9f1a756b492f4aab442368cc18c700e1016014b
+12e2ca27f141ac3084ce37b42a4c41d41a3ae37aa2e40028aa8f3dd3f0b80df1
+24f33e60d97ee975dc98338c7d2290544d8da601fdef3da00db855237a174cd3
+dda0a9a404c749c849f5592390320053c4de8004c650117289b8f0c44cbef09e
+2fdae18a593f2c7ae524cee7e3560e3116bba293c02937b0e95fe22687ee328f
+eb89d6738ebd1604031d248ceb6a11f9ffa7b2625d3ad21050df6f25d1bb4f3d
+5d269bbaf8d56d25ac40905ba0adab22ccfc7733dcdf3680fa85a94f65445951
+e960e817427a9126a9c767f263f324dfd34841554bedd86841dfba7e43986958
+d688da35786f0497a6d04fcbb6eef0d1e8d9575af1fdbeece6cfe66c574e6158
+346774b185fb5c4e3bc71b45b5202f79210579b4bc35b21f60843b811df3515c
+c0d81d665e7eb018619a243e72c29636b8d9366166797292ac7023cccacc9401
+999bedc5920fe7f51458d13eb772d6500f471416f079bee7c9bfc25a0858b10d
+c043cc9a219ab9a71ad62d68ba22432e1dfa7d7930f873a9af0ceca0cc4a4667
+d1102a8a685adfdbc5a1b4cea2e9a94d1766ccc8f9e74213876f3d7bfbe09500
+06b11f656a37641f9cfbd0b23c19dcac6d9c2b5cf0e38d8a58ed42c7d37d88bb
+9a96ad2864fcbc6033bd464ca519c9e8b24e1033ae844ce27b866f2fe38b09d4
+a262867f4782f15a5a0e762f76e1dae8062ba108e759c6d8f00ec4da4b4bff0e
+3b22b22fdc733b708e0c8ed1acc316d8677e488adff3fd5d912fbee47a55e583
+d814d6a77044767539c2a1b964f5a2522b482186ec9f957684f090862afac470
+7e5b48722a97df0d272c713ba3b611aacdbaa0ed665ce873979c55cd6a9dac4f
+b8aeca0b0cb0f6fe85e7c97088ac6f4ed2bce9a0d16527d001507702138709bc
+abdb694a61da95692e67999aa628b73837f53ca6892788ac702cd6eb52f8c79b
+92c866213a6126049797a48454b53318cfdebcbe1c50fd139abe01c30feec51f
+0cb7e9d9a863250021dfe7c27786e88b6baedd48d949dc481684e3faf67ca81e
+e76cfbd63b547d7a43f3ec9ad09b1bc9e31462a43245f40ee9f0cbe070805a1a
+bf940f2ed8300be39fecb86120ec4b0e680d890903458cb93153fd2ed736b873
+07aec4beb473ec4935bfb0b8c01ad84dac20d13b997a884930e3c6abdaabb083
+f6f66c5b936ec4624fd1d1ca39011688ef21faff4f69b93f7fe73a7ae036c3d1
+5f6f5da6838536f3fe0f7543f3f9460b197a7892d6424ba822cdcb26e2b3dd7c
+a75ad2710b9ab49c6d5810f68d1a0426987f1e462034ddb4aea10e8e04be42ea
+10cd8552670f9251994dd8e844245e97a5902b65d08fd41013de3f3cf0cd6dfe
+c75852ec385747f789cb0d846d0d8f4f0c823fe8a6202101f2cdb1811cac9e71
+9f54bffb04d646ebf824a17db7d78137f4e962f3fe6a19fec02697503d1f5c1a
+467799d2c347e8f85395eb9bd63f4e6a52fa05d4a3e25700b4de22c41d97c719
+cd5a7576a3dc797c96bf68c5ce7922a8fc928d6aa344fb67d4115cafa38e82f7
+5f621c9153f7f2f9e5ab5817e000d5eba9a789eae7831e1a75a382c6181a130b
+0ae6aac0e5cec25c567f1c3eb72caeba74fcd4ab5da3b73412e76399a56533ca
+6044f2c2df96153ea47213cdc057e3cdfc8923b80543e5c5b226628dc0bece91
+e30fafeb8d4a860c90021c1a996d178c6c85e9be45f28edd3fba26d6ef2e486c
+477670a17494c453ff09074c083aa8b74de9493f207b555c56e72fdb8867ccac
+10f060675e0393d1e5c6b2f44f08458dfa45cd4bdddc3ce3aeb5c7afaa73086c
+c7399ec8874f529e4af63bcb4df147edda137e552ca22f45ff9fa03ac41f724b
+870d8656fd9bb93690eeb0e7df81e6957e602a0159ebf6692fadbc46c9ded8ec
+229d9bb5cb617518127e557671723dd8768b1ee594ec29c4a096ec4fe6192ec5
+038eea033d0894c70de3920d1deac65b4fb001ed0c851779ed7154ef5a848257
+c973c7f02aa72c1067dd09b13575a33d3137969d683ebd38e8b61cf62fd3f4e3
+ce98c266e088aef330d9acb450ebbf96bf63600e83f13152eb0353801d2fca3e
+18eef4f1fd438afe54026028dfd703cfce0bca12b0d2fdba236918d27517393d
+c2ebd744f78e3dec0ce74805418f1a93252abef1ad71acc1809460a8dc423800
+86a593b8167212ad7ee18288d203244dd3a2025b8449c47021ff7620fb89d3ed
+41f8547bd5328e7ac7cf5f0ebfc314bd4afa8323d0cba57e98058af91ff4002e
+db452461e95eb2bff94e464bed868dc3014915a910704c5740a1ffe4eb3caffe
+27c199f573a2b8310ef7dca5dd1baaee4eb5add21887d9b65246d93e36a72766
+e664b83245aea45114ca3c11b50d51d218eddd1fdade2aeabd385ce371734446
+745552c5322e029c892e227dcb3fd626cccdbb1731d4cd23057686833fc20906
+fb3640b2481fdadf09ee20e487556f5dafb429d648d74f57c8f6aa04f2ef121d
+f2fd850667df1668f97d721647207084840861f2627f31e8858bfe5851c35fdb
+b4a81e41645ceac4873fd2447ff94ebe8b83636578eaed2be03bd8f283fb6832
+c10a917d9ad056ac7ce149186b5664cc52cab3939ef44f35b43bf33cf06416fd
+ff848179580a7c39732e7eeffce44f7b24cfb288534f47163a273f2a5d9f30ae
+802af8ca1dd90bb7149e3c3a3082fa471257bff78019380b1ac8238b735666c2
+df052ea0b436789bee7ad5dd407e9c20774d5ff3e0af9187e24065dc9a119cb8
+842c5f37421d005f27d787a611a8f52ce76aa34ee0ac7236905c28d6d9841415
+387be7eca5c533ef618397c89f3df4cb86ea2e38ec497e380efd12743f6bc297
+629e86fd88cc269eaadd0dd63984e253caa270ac816df54077f7981cf1f1d5a7
+7aa46b7538794d9d414db7f7eda8831fd123f843b4b6a963648b2f3169693292
+6626e040cda63af93f25d4a6e304d3b05c171c7186f5ba239f9e2156a0e9d30f
+d016aafff969eecff0111120c07706f09505359f63199c3e19e8142bc84b7efc
+caa61b1f13828755bf18cab9eb638f17c3f20342f60c1e1850332c16c8d21c26
+40dbb93652c7cc6469486584f2e036160ed2334c5cbf3b343c9c20fb460fe049
+2ac14315bbe89139796ad76f219f2f78aa252aba529db54863fba815857b4369
+dbf510ecf4db2255912af8fb0a1d7c1a2d176fbfbbff0182b969c8b02780868d
+2267b49d78b449702c46d1267319d79a101cabf6afef50a912b2fcb8482539e4
+9e919f3b1270599e8ccd1becd4fc4b973bf1d412764dcc3013c707039fc5db85
+b8c4759f7fb9be1fd2fc5d972e117af55ef2586b4441a440f350840210186a5e
+d1e4019761f7b460cebf431c6d564322cc22362d93433f843166133fdcd079db
+0f03591ae83885345c227b918e762e71db2b5e86653898d20f80c18c7f811797
+cd7f4a0b3c6c5d3289c5fe808a7068f3d19e8c4ae145fb822d59d2344bd47dd5
+6fc4f2c7237119a44710846bae73c9d13db5f08114ae8fbf644831e81dec6206
+d933c007f15c0c0ca65091a451a3f4268529df3d047f8c04bfbd7d7bc02b76fd
+3aaf76991f6f0b2b4b6a4fb87dfb7281a260920f79aa6c0cd16bd15de94e8681
+fc684280948d6279ca994a078a261860c868d0a029c70f80903265db27ed9791
+2c5a80e648aa078a321e5cb431c0bb2a9d21e9929a4ff4b1f9dbe980bf7ae713
+f76ba86fd6dfc798d7488b115e7c30d1068322010037fc6c9bcc6182df29c66b
+2477dc0197f1ec7f48a7473b80a284d917378e89b79c9aef1e975fc3edc7c60b
+a3afdace73264dd561ad9478a3cbbf9858978620c79c09d660b1048d3ff8044d
+c2bf02d1282e396f5c6298c30f3116285c16d3262630330c4fea515f629d480b
+cbaaaeba211aabcb932c2c8c9cbb2d48092f69f11c221d9ca068c529213b4303
+e7db0af9ea0ecefa45fdcfa5478312aeee4e7ab6d393b8b578cc181bde18d138
+6eee5ecb8aa46d9c62eb8dac91fc3375f93917170a43c2fb48ec5bf00d15c5fc
+f1d55710b6801ba04b406ad183dff76e19ee9526e6c38d5c2b084e8f36b7a9b1
+68ff8d2027c20b0d79d120a0785a35f93ac1f2a7319c65e68a4abbfd0ee8a3e9
+b14b3c5f230482032323b501a82424aa3256af1f7b5de145b16848b9bdb70bcc
+c4f83c231aae58de03afd4b7d0c7cadadff17b2dbe285300606de214cef1c624
+1d2f2969f0b9741dc34d8dfdd30331d8fb2b12d3bffc004ad1e9bccaf126e96a
+5e340a89e8a91a9eb19ea03d4886f768ce063c702f25f5ccc8f473f3a4b85fad
+95d7a92d2e3318f635bbd79a8a4eee3f1208e9e69a7d63de373262d38eb8ac61
+21f3df1bba843a961b5d3e7f8735ff641ea99fefd347df900b678758080fe745
+538c9d5ad428839bb6840d084a49b2cc475319a99b33a178a4b4f24e56a9c251
+9e8c010f81de925cb895a446c87b63ecea312c8b230151adf735c6b7b158a1d6
+55e44e2f5c77c2b461b97e494dd098fdea07d1940427d2a3f2585abf264bc4ed
+efada3790a85e0889e90e45c38482909b802b8c4c678e1129af4382e479e49a9
+e406e7120b85955936ffd8a40f41e91238e4d11c7e660b902897e9746f9948ec
+29ed59c91597ab7d2137149edc67bc432e470a404bb9e6b1f98bcfdf1d49389f
+828e3f35c203a3aededd8d4d3e6617c959d5c401fae6756223f2ff5b52134cc2
+804d20bb08498b8d00b0660fd27b4511a9a099a8487b7622184d781b47453611
+484da293aaa6b7e8124785991f755bbf689c4cd86e573f40e4f9cce9ffb6c5a8
+4a419e32002acd3392e677cdc2883bddc975bf0550a41e7d5623d745f389fab0
+5918c7cdfc9f49327eb8c4a59fad6ba52b0f075fe0a2851fde85910cf5cc9590
+b7d7bea3a1a8a251e37f6a20205b946b01da9adba76d14506850b6e634ddfdb3
+c853739461d428ac3349438634bc2c4577fa2a337990eb7bec05a6d9b90cfe70
+856680d5e822480f77f580c3a1e82b87dc2c2c554235da6133e79ad708786a8f
+bfc34d813f4e4330afbd5e03f7ef0875a7a07aa201c7e71ab6a818afb9399ebf
+d88e1d438e5d4634172f2f7000c10112692c4e9f0273a8db1c559b2e8d66fe93
+521514d2896b7321372d441e1e7c63edc272b30b6735ae53ac1b08c352aced8e
+8e569d3d3dc4e7b79c9a58310d03ac8d2760522cce13bb95bddbb22a13b13cfb
+78bbbf43cbee6adfb333ea66621a5616442fb9eb4d5855eafb1573075650d05b
+9b36e80e8ee6e5a4115aa1234ef0898c52ba94d85072c4da759dc246ae56ea52
+6be02430ffa280c4052cf73d6eb4b62c3282d82929177263931d89f27b1e1dc8
+de5ecabd3e348ae919c983913e6ea48b21bc0827807fba233c132aaf170f20b3
+3ba72160f184a3df9b130e3bd09301e12d0b22dbf56ce6fc87ce156de4377498
+cad735a6f5e57840ebd7706ee44c6b44a9bc0120cd4f50720ba4b4f4002e11db
+98d7db9a31a5c300d81546ef990481b7f9c278f0853c05b0fe5ef2586b4441a4
+218a64a07ed2bd6c547de31987297af9e99f16ecc361ec2650cbfc0ca9b55cb8
+f5b11408d58fe29e46eb31a0537fe757800abd0f34398cef4e77362a140d3ef6
+b00e83e143656b00cd218db158d44f5df1c5976fe708f15e32642e629645f1dc
+1a3d22742637a809f2197ff9a60d1f58e74d0937f8d8cbf0b0de616809d91cfe
+77675bc90ebd5cd44fc09ca0625e8cd6144b620bea2183744d33c42e535b4879
+ee3fc032610eab99688a6e800815164ce529eab33e85cb2a84ca3cea8074039a
+5b0b9e2065fd72389d02c6608660adcdd7ddeb2c4feb5a32e3276025f5c3ff65
+bf4b01473897164745b05a4c1e1dbaeeb2506bd306e266e613b16b93ac0f869a
+ecf140786a639f9856d2f47dfd448564cd6067590cd7c75bbe8b58eef67d2ea3
+8c965e69c090c242e29f12dee8b4335b8ecf7ef341de3a30892c09ef87913cf5
+147ae0cc255e05eb602420ae22e8c2754976dc6ce94fc477f330dba72728449d
+459b2ecfecec62d0be91a9397b312a7d46b0cb7cfa2fc664397dbf9a50bcfbc6
+3ed6fd6a7941d36a37a815cc9290c79fe24f19d1a5c1cf0671a73c6c22abb952
+5618c9a3a9909f1850a9f470d2fde679c254bf516641ef96f46574633a94bd7e
+c9890023100e55c6a51f1124b3dec6a7fd42f63499a1066d8d27a25819a7ca1a
+979e04a8f1fa55d4aaa3eb05d8205cf93fe5d372778e809ba05dfb1e0a1e60ab
+6d1140d4c0bd8e2db88e7d68eca8e3f3e2248cb6fcd2919c12d60bf4549cad35
+6000877d0241f7f19487e8c2b17a522bac5a91f864630e2ea4d2f5b7bef4d091
+064ed22d2f597d18c9f04e2e2e1be2ed884cafd31231da6133e79ad708400c02
+fa56a3f3f5eb56a713fe068d4cf564e7e20dec5cd4696759cc35d34fc0efce5b
+dda7c02eaad828006036386ca3432c6c005aee97bc884afccd3b642c0a17f418
+e3f2e436dd02237531cf86ae391102b2023ae0913471b6797a8e71031412ac87
+b96a7173d5a56332ddc5811f8672b377955fb5e39f90d787ed2b0cdb81866f79
+165c8353c9cc1f0924b5f4ab6bd5197ea6273aed03c838f6a78bd9c40eb8b71b
+436c0803bd569c3ae55ffac24dac9de63cf6f851c5e2199c11d9da77009e5531
+09e47298f63c44644470d768725db00743efd4b012665664b3f663da65c6329d
+a22e64b466f56bb45e7afa47e1d2e8680a49fb4948a8c424c175ebb3f221a458
+d75f3f84929ba4716c503c81e9baf81999337a0e74d9c386e2b46aa7ecaa0689
+e5b00465cc49f96f7003d7d0bd1463372602a5a18bdf3e924493566ee07b37df
+97814292f85845f2cdae528cf8e6d40b1b4c7ab83c276f3d9712e7cd00e96f81
+39dee7bc8d17b48a57a39210ae727a8563319091fb1944279c1e670a24093b0d
+03ac8d4a479d2eead32e98af57251eaef7a6a110493471c97c04cb50fed0461d
+b5d0f89df4f461b67bf479fac30463af0eb0a5c40b3ada200bda798ca929d04c
+aca634d46b3fcfc12980c2ece9439363ee588b4cfbfe1adf3520a28209e59572
+148f5dd6e4891d9bdfb2525b5d4e16fb79c13a65e1d6872b1e2ef1c761d1ba66
+ea1ca508c2a3bb27a32515269ed4377d1ee7ddc8c94c4078bc4b352211cea134
+95326faf27554edfc3a8854cdd4ed995df19dedd2beaa478a9409a77f75fc1f4
+d57ac4352afaface9ad01b0b621cd8572b3c65878ea89e3f43269e8a0c3854c1
+454418f7b0b385044a15ccc1823961ceac3f500a09579e605f92f0bbc9f2d816
+8c50cd9e61b84e0fc17ad73c36227e22447b9ef1296f2fe302f23663deef0fc1
+eb759acc9dd1909f369fca5564adb3f0b2ed33428c75fcea4caac27e7e2ebcb3
+f50fe19f3a3904eb94baf40c40bfdf8a787e622563a2cbf6c32de0eb309ebbc4
+402e31bcdce135d63f42f314928df9816b69e19f732539bd00b5950b5aa8fc6c
+b3bec0f14e60c3b97423680fd8158fae9b076f3d25aa3fd81bb5132f9b1f150a
+caf2cbc0744e0d4f42b186af0591f16f51eca0ab48aa2525dbbf629b4754f235
+49f1f9a88d2ec444c26f28ad54c9c388ed9c00c9b2f5a19a32fb8880c47ebb80
+16ceb36d0cc17489b3e4e552984ff17ec5388f14541759ec95282eaeb4a2d6e3
+192cebedc3526f99363024cdebb040b3da29dc93b58f6090f2f5bac6c67c8ea4
+88b3f0eff0d6228e20a5b865bb2d1870e9e76c9663fb32e899c3f1f03507e174
+af0e77433fb35748aba9dc78f419fab7c9e508f73824460a7fe6ee23fca964a2
+839043a19ecb24b15b6406769b703a3b831bd6c4c82ee4af7aad7e5295f85353
+c7d3476119fc664568089a3350ca986913f16002e2889a7f091e02e3a400cf8b
+83ece85176f96fc41efa93d5d658f45ac91e6e566184cc0376ebc6c8491f09c5
+e6b12eeea7e4e445a8821e03a381c468bdef4f7074b631a3146675b53f7539b2
+11e0b3b1885eb173883c4cacf1223ef4f6dcaed8054c8738fc3dd1abf1566be3
+b4d8e99bc538504742ab18cb9e5cf97c9e5284aba6f591e2d87f00952d0388ba
+ee7c3ba1182073481edc7b9c0e761a85a1643941fc9a0bb39252d59c5b0abad3
+85ca9296546fdb9faf2bd384db91bd96c59da8250df2b5d125d0b2546bc7e2c5
+0ed4dc568d8f1b65b6f327842bed0e7e910e44ddfa302f5b30ec127aef3f02f1
+1dc0ce8a94bd9a77c33c8e366ad06f6675806d7f4e77282f88376fcc8e1772e4
+1ee7f1e9cde177b826f9069ed5c3d3d0b4bd54bd60e01d4c768cb47b27624853
+fd9e3760387debdb46d9dfb6da0f7afc1e1ca352f141b9039c6d2f3ee7ba88db
+d5f1a0db0753962fad600b9245a3a6bdb0bc0dae1e65c3b27bf95a52353bff9d
+34d860a5d9de8ea0547b9100c160b7b631ef5d8e2bdae77d7a915788bef9eb91
+11d4d7f60f0329462d2ea14a7da9289922a575fd88a52c1aa98cf1f4f34b7054
+64336e3ab7cb09d81e427e3bf24e87bf7147dfc0c52e6c67205181ad234ca1ff
+0dedd467d4a13bf9afdc6167bb6f33a47f1ab1477ab32752c256286b25438259
+a143a6d95b2c6e5dd38dca03fd6c803782dd7dab0c7c0647f48a84a163cfec2c
+e098a2ee99d2b0d46e0afc85091c8402b36b41cc096e733d3e7252c2a4b58f54
+369f049d0924a6903f8ad3e1bbea39e25bfa05815f79eef03e1748b2d581fe11
+7ab2e3c7a8f520c194b3c5e98fdea58f19b4e79d677ad54a7fa485a7a9712896
+618b0c33694a3c3467a245c52cd39fe9730e7c2634d298c1638a0c7109692cf2
+58f8a6d0bdf578cd28f72e48176a959993014e050a7d060918fde0a223eab193
+96cca9c895a0d5bb26eeeb9190df3f07e2d6243d7a845404be35983125b133d3
+7bf15f8c7cffc8ecf514969e23fabd262facea11fee56fa69682307719c216b7
+881b733d24403eb703c288cbf898749f3e81fe24451e063b3c02cb2ef8dcfc36
+179a525662d47e0e6325b93d885973935c91cc6c52749a939d32fa1f5a74b689
+d06d161914dffba8335c544ad8c4e83522f403157b7aa2ab15593a7583c684e4
+72df545d24a4894038195781caa9f0f49a66fc62fbd0a5155743b7c17c9e6ffa
+e86076684c20a77b1e74abf75aab577b93dcde8c3ff60aed1a87ec006d276725
+215681e444c21acbb6318f41d175894c303738994c15099f4021950a8b389dc2
+ab91b74ed57317f7faf10f00bda6be25467f05676ac4192c369ce03bb374617a
+d5bebcc56ffc07cb5d8e7da3e17b7ab3d9d5dba4b8354c03a64f02be62ef5df1
+4b9b9376e79a803423bc55c5cee3972f75faf61dc41d1e8415ca55d3cf703612
+1cfe771be80b697389c047c601dbb8548f0d58ed841d25531a41d8664730f34e
+2b187bbeb8d9c16ae7591ca61fb2ab36ff3b6782c7e97833827a1ff86644ae56
+f463956635883b55891a08fa707e90c392ae4721fdb0b2311f8cf00a4703faad
+8114b615eef9737684a3c53ca307abd11558ce0810db4d94a444fc6babbbe40f
+3fca201d7f66ed5f834d33eeb1189648d68efefb7af5a080f1b6297b75e7815b
+4680e3c4b2676f3c763fd9d28fd00374c2ff2697bb8b96ea13cebdf68eb17001
+c041d24e19c97d33d448f4d6aa3d50d8720b0377135f30b479d973ebebb93031
+aa1faee6c275b21cd88852d903f08e2629066e18bfcdfe736b208429a99f7420
+7fe3f156e82b16cbe3d401aaf8ea2a417a7ded77fc22d8f047685fb642b7e25a
+50c5141c1f1f38a14ce3c0b8b3447d8f48de07c687e4c4cf69204e85c6489a3c
+adf29ca7f2363308621dfd1f48efe47d7fcb3f67441ce965f04f42b78d23500d
+25890201f30d13dc767cebd955da0ce6f6411001fac35b8ff9762eeafda44864
+cf1fd2f8c5c006ae8afaea913ae1c75765e4d6d77b7e21a6d16daac81366f237
+78d2c5b9a64872015bbad846c77d4a9b93353935d2b6e57b39ebbb02993c18f5
+228d99a76250b85311629162556dd299f7eb2479c705c6e477167faec90ace94
+4145a22a5cdca376cd2f809ee685329d8ae45f3d29b2187bd4077b1e7c5889aa
+d999a67759f2b649e82031f198bc592bff385a196f4b9943300e1c9557ccad85
+497b9f2c5ac963b85527302a1d7c42d5d5c8c58328318a6410df0437225eb017
+494c3aa09f129275a02d0f0d2d5e24fa35a6b0112435d63cc0706491cdb6e75d
+d957789831d30481e3b8e52d678d0990202a4310255adefea4a4b48abf4b835d
+35c66f7f279e1d7cd4887798ef065d2218056e2374c03c99fc2e17a24a9e70b4
+9440f5e20c8806dc23e1b1b545716dcea57adc5e40d7df2a7a259b559cd37c2d
+8fb1eeb6731601ccb46af23de0ba8c1628f4b88a9b2d468c96730bff946e66a5
+d200ae32702e6fa6c907ca03518731f60b1252a5cc2dd1f9bd90428c2e0f0a7c
+54d92afc89333da6a83c324af0629a26996457d6374437d9cef97bb99eff0e98
+a22c6b0deba1062f3c48226dbc9a5899cc864b975bd1f082d7e511a5b4cf9c0d
+7f30d371f689da42f11df7c18389941337b9c07e1cf5f5cbf33e400feb6f4aae
+e60a026da25d51a3bc14d427d37fbc1e64e938a4de50f52578768bc70ce53327
+2db34369f898761aec2c8dda5931f895d28872ec6f209d78be4f4ab8da35f656
+97c57405ce7ae5541c9ff509d5762aa6297e7a0194059eef3a2ae5d59dfad4e9
+807cba47217ba163742c83f8205052cd729ed6f8c452af9712dee557d4bf8a30
+3209d36bdddb790812c4e532165f955c981339226c4ccdb89f78666953c02eb2
+f38c4cacff62da858e16feb7bd379b92d9420a26fe2a0aa0c71e064000164413
+7c538d2da78a5403cae324705be07519a4c6124f4e299c41497f23ab3c479ac8
+e309dc694cb84b693a40ef5fa7d4eaeb84e97643474253f982e38060a81ef3de
+b08144992e048e8fe2e9719ee6c840e5be01142f4a62ff3f2f1b1d70997f1fcd
+183c5cdc04d67e5f46f946eefd6abbcf0170141516c7bffc2a07efb440dce1ce
+888a5acbe4c407c8fa46e28d20e7774d2e374e224b991242df5a20cf3be574c4
+10a1a88badb054b812e7f3ea575682e6a86792ff4ea12bb43245bfdf588df7ce
+ae590954e88607c4201efb34b2a9cffaaa392ab52f72ec08de1424d2420bf7b8
+2f2a0dc2aa083310b4a6f2a68ab5ee8384bbbf4ed9f932308c2836d6de8da231
+dee2b4f08790d1653490b71ad5d0bed41b06f659f8c3a771b82c8e58ec4e0a0c
+5a9f7f9874bc6a1479b918050f06e4d1b49232d8b44f312a5f6666b49e54389c
+18e7d89a399fac13ea6ea584dd48ac68c0ee40d26e4f2ac32951a3aef14c503c
+7ca2d05701b756990b9809e25384b0815fe2bf5084ed21d8cdab1fe3cbe15c41
+e8a94336359df9ed3a43c529529a9e7f63d8de36720e108d1a9feb0b9ec91379
+b57d2ac8a6799176ca5d5956ab877d87050d86ab917689c93652b729d4746f6f
+34de32680d8ab5c5a4565512d6ec950a60f5b0b141f348d1934b4f3689640592
+f22d1c1cbcdd5116b204061afc1b8f15afcb06f4c44905d17b8e44ec96ca2888
+b34eb85465ed2b2620756ed963fbb9312883c8aaf4870c52eb032bb5cb7458b2
+fbd796b670e972f576dd3941c76cbed5c40b669f0dcb34b31d29501097553698
+9bd2a479acfcf324fd549b3e41bdefd06f42492c36d8c0201d2526e53ad34e55
+2b2384e39836743766e384e5858f33ac842cfedc28022ee8dbefb2a2c3a408a6
+be84826023124f7eec8295a2e1079480f30eb64479f2673da8f051267142dc54
+e88dc8dc4ef41036f1de1b9a198e5006f8336b29720288c9f2e545ec8663171a
+280273b1626f882c6894be2fa2532c2f20e4e24f1406c0627f9cc4021cac67c8
+3a60b39f1849b483757f18ca956ec3bbaea96cb0e2a10477e69a6040dc3b5321
+391af5478fdded8730e825818d960c6f4a305d653a732f1c51c2ca3e3adc4a37
+22958d50a78359cabcffaae1d75ce79e72e09a354c5e805967e30ae708c109ee
+75ef233df66782bebc4c5dd9ed6ef0a50eb2693787576a19b42e70e3d0c073fd
+fe1b3562083bc01d9b38868e64b8ae90b9f3164e2a29fbb1f1bdfd8ffc2a842a
+c2f9801d4839c97f4bdaf1466038eb4b6975e777acbdd875beb59268f0eae6d3
+a03c2bb60bda0ffaaf77c4f33d4671ee85f301521557a6f323f1b0d060326fd8
+7c60f65e4220b7fdf85de8f0ed64661fddba2efd3374fc45a507437a1ad2ab49
+38e4ccbe2411ffb70718397e156d24ab018436fecd39af252f3f9527397cdab6
+75b261045194cb3d3b5aca47c98f1177ca1322775aa8c29216fb7f8ce0fbe698
+479abd173b9541fdebbc3cde6ad12be816108a049d5462572544912ecac19e6e
+9fc6dc06160904e7bb14796e5becff4df3a8f645825c9f59fb419bfb5ced8e5b
+449a2e57adc9693e9d34e6bb5a600d16189bf146f3dbaf4f75d16b303a322048
+ddc0de4a91156aa427f1b137a714f7ec2a4aaf612de4819dede79b78c90a86c9
+01278125bf2999c9acfd90a866830d00a0f1c83a87cec69cb2f382c935bc571e
+a3b53fb22664be95d8e95d229b9985d992dbc6439f0ca52762b3cd7a4a50973c
+17de473f987151687da95caf1457c524a4406c98bd025f353124da7e6389a921
+e56de4d1ca7901cb37f051b9d3b78709640530cd549c9907ee6def35aeb2eecd
+1c9a1a4ae7686da61b848371dcacd9f02cc320f29ef144a10803df5dc4621887
+09a85504074b8439c1a3a7c253581597d6f94289e7113c678fae406b6586ec40
+fe51769903be72259817704579212bbe802679ef21f7578fae78d1f8c29a5438
+b656f13d14ac4b10d1b48d83dd1ec6e569358f9dce2093f319f9d3663e331744
+bca142ec6b901acb9b5594ea7423072d96a61e523336059c1091823b03dc6756
+71cfc688bd2062830e0edf7a5d400c680784691ff46bf4d8853a42c57320414a
+0c7b838bf2bc33726d8a61d11dc42005b909b241b553c37462ba057c30e7bdee
+b3ec5513ddca5046dbf783c780ffccdc188b5890daf03c94c8bbeadd2e33e95a
+8bad7cf8c890753d607e1e74dda3963d32cd37ad2d0eb722498718df3827236d
+7f073eed7fc3c0ce0fb5629f08d4a71d1825c4d158ef364c8d69e8767acbaa92
+e1751a266718d67fb61b4a07c485cb887f04bd30468bd6ff5163e5e35c7b4bf6
+ead5db27d8690d7c54b2be107d8180396ba6046e8b1ec7f51a624a52ad2f9e25
+96df52d886aa0f5f0316fb0a6ff881ef3cf2a11debba86921f94b6ab18088a61
+ccb125c7732c3681373e4151094543ad56ba6b5b915ca303a753a65aa189f6d7
+1bcd8ab565ab5696b9b0a2fb5b7feef3dcd6ef83f859fa4be52c24c31ec71153
+4577aba733b4f0ec2ca742f8bd658d7646e6af057d09b504f072b85e8ce75c51
+cdb3b17d34c06c1ca57b88e7ae944d289bcbc1f7ad27898a703c0b2b9e0dfc9f
+87a6b2c1d9ea2cc05fef8bffb8cffd8d8246ddc86e135a8361d36748680881d2
+5daeefbe63d60e449d50acc1718f1b6df6297849d31eecb6c990304d5e37d6bc
+d83c17c4ebded22db52466af31cdd0b576d69ed50ef359cb44507a79462b2825
+04a48a4b8bbe2ef617837ae266e3ab90e5f45647ed6b99c6d8b6121f1f7771f7
+5b76362f01bbe8a8b4268d4755c7b613b2faed3f108c29bda855012eea6c2221
+0f618b416e25534efec4c0f6d0feaa4ce7517802f2ccf54c96c4b5b9227bb59f
+8c8a49fb435d4134dce397f41f3b6d295f6453b9483c3c1d2ffd47a3199b370f
+2f31b3772afd59d0135ee2970b66acc4a1a0d3a18be2b3cc0a8a261e9dfe32b1
+a63ebc7fd99af94cabd34eeafca393ab83b5ced9b4e60f868e0b7aad2c2f21b0
+d84919f1c1598e6143440481e3c4a97750300f7e0660eb65416215d13d8f546f
+74c4700693327ae762ef61db4463f3644d534a3b4127c06741f0f3394f395ed3
+84c4139b7ffc5b02185dd9e9fc4a9a790d91eda97f8262e6327779701f7440a2
+7120c75242cb2e3c5570399c648b21da288d2a9d610dd11d5f9cfae9aa1caf9f
+05437bc137d8cf0e83272ecdec1c574ee6880505f03fb673c5ef5e31a674d1fa
+390de77900b9dc1fe4d73311032af31f6985bf38005fd3498d569de012062aa9
+c4e5baee3ee651230cf8f06f9562482e56aef639b4e9b14fe104d7a4e59d9f59
+ed573a530fead02933ab576a225e00d4681821a6bd294b96c9f73ead9eba509a
+e5d9008007ece9e52dbe377e161c5b5e1fe556db12e167595ca9024a24c72e65
+527e3f4b94353bc5fd302dcd2343dfc038950bbc4c1249776e2561a90c9a5ca9
+c045f6812d9491a77d5f775ccaf51b81f299e1f9122c50712fcd660bf649f628
+2aee3c072d41bfb68cc3aec648f2201fd414d50e1375dc1fa058a80f54ef4852
+2715a66f46b0da8861864fdf8e22f6e47cb32837b34ffdc5b578717a1119c6e7
+ef7566c58b373d111eb6c2bf1e9853d13c6223fac9ad3123765163c06dfc0637
+c692af835e89ebecf5b37620104cb8f17851abfa357e02703a059d960d9df6f7
+fdbb168337708e7f919c04c802ea2e2b3a3babf74eb86e63de9b8644627d8985
+a1ad3b8adcca509f7a7debdd4634cbf42715063265b57d40eb7475423c383835
+9cb5a1fccfcc7874c782cd859ba71d5f114991e6fe5e557fd360943786fa1610
+75b6783140ef30382f184be07a3b0bb616442a4a4007af227492a994854b4029
+8b9e9b4e4483dd252b2230f1f615a122918f32c3ea0a68805fcc73bca40be7f3
+fd94e698d0a65005a64dcbb7d97f60cab183acc86762873f18b673dc194cfce1
+03f07cad09c8fd6b1f532d72cc86ea99ea24a21a41a2e09837093d5e1f1e3d74
+342cc4466d9ed9c1722d8665b00a9f254950c286426737b8690914d856ac20f1
+bf27180e6f9b00981bc8b3b165c5cc7e02a689dccfd58c1b5939186c590a97d0
+4d5710fb5506bcfff05f8c6241c125e300235afcd2311d997a1369783a83ee1f
+040b8fe44804dd62ff7e5e77dbfd66177a934eaee33737d643092a0cf65e51b1
+31a7ce8e502102aba1a8a68b8d95c5b0651c83214017ea2bd5e5a52d7e9d8afb
+ba7cd22bbcaae087ead54739401b0d8acda7766d94d640feecca18f1829ae75d
+a4aba8485bc9dfc9c67409c7d465f54d740ccc8ed6452872082bea2773fd5d64
+6a809f5d382b69955db3a56e61849017f103bec6de80850132002216dfd30111
+0250985d8241933cab0ceac16e90d929dda1d3169a8de16ca98aeec1bf59b9b4
+e0ec460a2631f6d3ad4f84fde5b5dcd29d53afbc6c8a3adf15d234b13de3fce5
+2689a74f49cdf2d9affd89a098d6fa7c0f93724a08324ed1ce7db85034bf4a67
+e7d0573db8e2fbd09e123156b2d066bccd9db05b87cf61545a6e219009452b75
+41aba3802cade07019910ced99eccd026725d0853f9f159703f449d1e1d33902
+148421d34f132378dd12d9e79168bcd8dec5bfe47c862adbf7883e46dcf0c241
+e068ca77b72ce9a73a3ac40f568481f62d9f36ede5f0264c4d8f9b2ce03e19e7
+0a94d0e467a9832efbacffcff9efbcbd405432914bc36fcbd16c4c2aba631f82
+13239b69f183482bd2922470427fbab78cc598a57819dae5e3321efef1fdb44e
+084a4402b8cee480242e42dc09bbf208042dea7968a643851cac21aebc1ba274
+0ac999d965b43feaedc8c76a32ff8d4fa30e2c8444b01716af4878ecf291309c
+bdb70c5bfbd4134ad5d044a04a057405a91e1a1ef15980383cd4aadd4190904d
+5528e55138635714ec3f9d8e0fe1bd1e8ed4b742ea90572f1ac8d01e711c074a
+4125ea595fbce0746121a5d022d16b2125a1577850f6d1010279a5dbbf135eb8
+edcdcfc459b7b554192149c29327f86e477dd3d13fa5ae3a78cfb714c9a75006
+7ba154407ef22158670059820c8041941f7ff5c27c016b20b867f83a9c8955dc
+d282dbb6f72bd2067dfc1e91373a3021be2be6aec5f90c8001878077eabc9263
+9f5beb892bfded1d04136bb3140dafaeeeb31c21d8baf03715fc56ecc16e7dd1
+1c12df0bb68240772f2c59829482cf97f6a922c8c7deccd1a395e7ba2a1a8552
+06c27630ae1f236606a3a9dba1404326b8b484d5d2564b480ee7422365234cef
+2609605ad9e24294ce5f5bdd61a479c33fe53ee8bf857e2d2a25dbbc9a1cfad3
+a5d7b2f1155d29367e318c8a82e1e0aa236b8442838e3deeb9f7455923cd769d
+28c1f780c0d3bffc275e0242ec975d2beb7f6bb5222b2cdd196e4ec94452050a
+76a4aa6352633cd58f461fd646f23758e343b5a386927b66ac6ef1acc84839f8
+bcca9f9f93f18cb4c6bbc663a951dd5211acd684ef945c10f156b5b6e1c182a7
+a580b3966716c334ddd9f78a404873a738ab6ccf8a335f1f6dc830d7d74e021b
+bca95d260b34d1933177e5ead9c2793d264c94e8bb274b9712afb7862bbd8f74
+b4cce27cac9f29c086bb30162820a229e6d5c83410a8b876fad5b8a028abc067
+885b5cec60995550d35f60afd1da93e3dc14c42decd2b0800706a222e9e4b7d7
+bba9646f6a3ef9489dfb011045a6444cb599c62dcae4b11de7d8d98f8e58a9a4
+feba0e5f7301b795f4085baa4a7085c5a438d0b784b21186787abf88b455f1e2
+ef19fbbb4501d5c69c22b219737aa5ceca0d0475bb6916685534448816d2791a
+31544769ff1152c2f2cf4c7cd3f64c6830522219349254d11e6ff2056a341648
+e9caf2fc5c6f48a8713448b4a0a7bf4f250df1f9ab9db798e0c5d2cad0116608
+a0a6190d8fa4f8e67f705d8dfc7cd8be652b13ec24beb159f97d22997094e38e
+90fe6e9f3d2a07ac92f1648c78e6ca7452481fb78dfefdb4399c62986b652e08
+ca4a9a4966cbbb572c4b2c8bedb9285372904836abcea90e91ee6fe8dbe8fcf7
+18f4e0ce97b29be634db1f19b541e003409442a59e320cd38789b76eb79e35ac
+b1e09f5ac2eee068664a0f505c61c07da5bbf439acd52feb4caac79ff0575647
+2aada68f6aad5a1b760468859d9297e3ac4ceaf7830c09d3562c012d48cf7da5
+f93d7942a15fd76be4e90cb1a966503d32dd2fc39c1cd01c629b600ba6463288
+466ebf44a4df63fe204067d6a39719ab32b5073d4bdd022933b5bb5652510919
+af2f90863be9f08dc507609487ebd7b796a3f0b029e13492cd0a1dc002d85b8d
+a0d2ddf319f7e732ed40a87c984340976292119ab947b5f5b9e5e31e6023e22e
+6ef0d04bb9d9cbb7de56a1626c5925847300a6dbeed495b18deeb81580701052
+e4b37d9e0b346aa8a55621bf5dfe3bd1cbf2051e62ab1e1da21387b5f38c1199
+34ffab0e8158107bc33f36a537996faf01870b85d5da02977ba62fb8e5d4878e
+1be660a6414c9084a3a5f05a4a2c3c1f311a589ba7afc5418e3b480c92f91033
+ea61d0a6a1f9e209226f2cab2d9c10e2b54f22e9a730ab8d48548cd28c3dab41
+5b03a59345bdfa9656cbdf48363eb233dead8ed309268a629bbc3c6e2d85eab1
+5f3b769afef377e4602fee3efe33401eba124aa4d4593c5356214c59db31702f
+44d33f89196e09e6e2215687c448c9615c69d7163b2867252de9771c9ee8a395
+87bb374d1b705d61c42da4a8a7ed8ebd24d1062d377fb37fd84d5ec3eac25d5d
+39bdc91f7c820b9fe806984bcfd3c3753a607650a6ee4460a24906f75b38f2c4
+42a65909bb70e7383f9e90a06f13fa2acf0a37e59a31185b6f9437e741571dbe
+fb518dd564140aab4c91d37e6435ab9b2b376bf6522f90b5660ccd1d7e8b82dc
+3a41d34e2c39cdfa05f1e4a7ebdd3586e69c6ccc4847e086052dc7d6cd4d8302
+c34f4f0402daf9549bdd83c24c44a68cc2e0c2635686c6e49ed8bd5675749650
+a79e40588f4315fdb9c187fa7b4956151b7123f36937b06fd147eb8d51a8eeac
+5461441d24afbadc7922cfc237823efff1a3e742b336e84702189c648ab7078d
+6097d8fd5f3baec947d63912156478662aeda72a501c747a325d1227cd4093ff
+e9a931367dde46d65857290ade9dc3d8eb73e7149dacc34c08faa51f9fa39e0c
+13d14be58999496dfde61566e68f83135a0e43cab3cc6395217a0845423210cb
+032c63d56bae68773991e91f186b198105f165723e08f6db39e889ef3f944d33
+9886c0c6ed8e41c20c0743864a50d37c281abf47fba6d08728aa21a833f22aea
+d0bc38d211caf58d44d01e10c2da4065a3082e562e82e3f1def28b5fbab1e93c
+c3716256b98ce87e4dde9e93622e5ddce60981e89ad0d70d0fa8b1638f4c12ee
+82a601073f84ccd47b631781ef34da22b5cd35023f23c6fff02973f993d7457e
+fe579da64d7110867d6fabe6b41b97e9e711369232f98cac9975d56d69cfc985
+30e76ecfa380311854170f98cc43596a3d4019d08c25e59dbc3eb850e026cd48
+4644353c125e38f199b22ccf0a502d675d5e0be2a4df28ea88c3ca6b939b4b19
+e81ab728d3e44648830f0ccaac81f705d098c127f07f56ca8550ceb827722d04
+6ce419a2504d8d6740cf9ccb5d079f1086dff76bcef4bd20e854eed00bce0858
+522818c8ebae755857d51961a9c61ab5367445b621562c645664f6df9f63a212
+46ca26d21aeb97ab2b271003d5734719358b16d2af5cbc1799c88b899e3c964c
+453e53de23d02bd3137cc0c1f07470d8ffea99d6a27e835ac56c977c149dfd13
+de3c0c328f8edd67c1f95953b9892e0147a245ee0d4e5912c7eba0b810c0667b
+17b545543b0662d53be35c26192356522fd7db85df65e5db4d6573b6c0c0f5da
+3747e6fd6c4a041525f7e48b56ae420995938a2229c967e98c8256c28f3a99b0
+739f75f0f1d250db34ecd7abcf25b86e6b94de40d033d99710fa654fafc2adf0
+118f750a07aea2c94f205cbd091eb2a3bbbff77253122f179395e088c6b7a9f0
+6ad421055622a1cc0538e8b3f03c4dec14746a49b2a19bb161ef7d5da64a4562
+e3a0ad91e4ad5a052d74c1473febc4f186cd6b73d48a895e8bbba44657d00663
+d5e76686f65a7ddc45ab8194be9fcd289e170994d8f17d4847080ec3f0fc36f8
+11035bde3970e330f1b654034faf87b01b9981330b3513c2f32e13a280b52c92
+449525bd879f684edc107a40c02da468ede54c9bf7ae72d4c314563e55d9d194
+96d0f80472b2f3c8398700bee642314f87fcee7e0fb9e4500fc980e0a9f755c7
+1cd9afe4b3946aa06d2ae458ea77080c3308f65bfa253674be7182dea45a8d2c
+029a570cb3914f7c7cd0cf31f9b537b4f2f7cf918c5e82c6ab36f65ac444ce93
+5e1d14f413c2c005ce388ef8175d7c8e7bfd68640c650385b646fd00dbdfbb9e
+0ec83d93f7ddd486a358a8493a4327d11568d3145b52cfbd0bd5b4d7def67990
+6fe1297a16908e16b9de0a13986d5ebf4f829c4de8eeab729480c1372c0b85c4
+62d02d8e6bb0c45fb26e4d82f0152eea9b745e1c20e478ea50110efdc5bf0164
+a678ecf71278fb2bf0c8a53a99ec0f46029eaff9229108234fa1624b5e33f927
+2a232f64acd955839b942f8f8cd3f3e3871a443f685149bc5ad0083f6baf20c1
+4025309173788aab5568160b31e7f7ab6f10f4033345656fe958613d626e8ab7
+091aae62e2150d7f854d5740f601c0756b4d04a2f4ced1f833042b4ea609a051
+defe8aed847795cacc657c5dde3331323d5f21b24154b3b2c991e3da5de77d00
+a4577ccc862f035c10f2c073f85b97fb489a5d5a17d84d9ca133a018a22788ef
+86afd7c1c8952eadc6cf5139605b19df95546e90a839440d56ea29625d57eba8
+0472486cae74bd099198ab8619cbb6fcd652774b0a97806f5f83f6e8a109eeca
+85cc7bfd19ae0cf27336e00d98d130f932be9752cbb97a14a44fc6407b286744
+ff893a26ede2d28c6d5a2c2369388cd6a23bf8e102d7014b3944afea96cbe037
+35db0e6e4922d4c5b2b6add56d317f3532fc50a410cf19be859075abe70ed195
+996f9b9afc7b1f3b1a5d1602fc6d55d5171ccc345e28040625e4fabb28699011
+6ff9dfdbbbd193d503d5ff027b0f4a3b124f2e0a1e428379ac6fecfa313fd135
+a6f38da32b37b3d6b877e5148b55aa40567b78d69bfc59681acf8c871507eb03
+518650eeac7270883e7003ab9ca8a2e531516c309c31f67a059349b0f603f584
+c6d91770ded8a825c6f759cb3128bb928cb1e671c1684cfa153a41e6e775ebdf
+54f25d11865ad5972e8bf3193fa4044fa618bfb88b621420c86a5a30b4716fea
+a63197c6081bb1f324605d018e8c63753fab6f972670cbaa9a4946b9c20fa42c
+6e52c9751654a3cd885fd9efe11600771861ae0d026fe0dbe642b073c91036ae
+eecfaa08a7d85983eb13828c3903c532c0829802ff8b45e64e39079f65a5b84f
+f91b65688eb31e6d5fc58cadc44319885bda8d78db2aab9fc4a268e3397d12d5
+1ca0ffc79929344f97a6201c01a183d2c0c2702049048205649b91a784c7095b
+8630b00c1ee0af742945873049981540863fe38a4e57cfc8647c85c069296284
+599f169506c9df019471e0ca8fbc9abf7d1af1dcec4802e72bfb1d16138585e4
+51918e0c421966a52ac29c21aa3822870959543691460c52ee43517b8588c365
+888921e4560d3e28f72358325197f09baea07fccf9d10b238659be645e0bcdd5
+e76534b21b52941a1e48267faae6abd43149987eb5385b44a422c0d6eb37c818
+542c3553452c97e016c26d38a4c0b53ae8b156167a5e11b861b44bc488bb2bb0
+cc652e3a1d12e616a502d1fcf31bfdcead55e2fdffc121ce85f525ba491feb54
+7a3d16d85f65ad30e430dca5c603685abe8484d4c4144f91c5595a3fda9351e1
+7f00eeccfcdb2e0465566192b23a9a78c14d62fdb3b1963c780f6855dd733820
+89094e921ce09784e1f5408c620f6481d300d9fa6f8c23876a49281b0d425090
+497b767614696424dcecad04f0767bb7601b99dd3bc5cc14d2dd77c09101fbd3
+b6e725e5c68ba66a5a371fd6f3ca6351ef075645a3c03492f7fbfa225a5f3e01
+b962177026d94e845953d5781064633edc41fcfed874e011304723a52fe8ebe5
+d6efc5e69b9edf735067ba2d3ef221ee6244034df2469afb6056dba877ca9850
+d4e20ce756a79a38e74b356019de03ca6651e54d1523e12ba9d9dd8e44dae7a9
+20eba8784607fd0eaeb0b456bad6e739e264aa0a3f4d5cc5584e072cfc8e0a2b
+949b4102d14fe3bbcd7ded2405718b0a7cd41deff91bd415340d6de94797c53c
+d734d14a11be9fd9de57cc35175f24913e96f95315ad3c66ee102176e59a3b66
+9c0b992d1b6c3cc131b33119eca4fae72f7553cb977dcffbd5ea29728ac5a645
+eaab33042a0ad86e8b28fbdf79325e28c3801cd0f9d8a2b563aaebcebfc6540a
+3ea351caa601ba8e5c5bfed770d61d7366f96d6bcde2db981b51e38ba35237ea
+d55fa9c1cc2b3381131c1dbb39ddd7229d06e4b9d203d066666c8ad6aaa1a6df
+0d346f843205c41a95f72df3027c9e6486a0088f8f8e7c9ef820e2e80766fc70
+6c4df71ba5801863b29a917a16abcd824d9a94c9081208685f8a4398004d8afa
+25087ba3fc81dceed46b7d6fc92d3b9557514899c5c97114ed722616b477ccfe
+4f4e1faba32e6a24a091a7a1067628ecc8c421f8a967c6e0136a9c23ef642100
+eb91c300975d6dc2c09da077e24fed0aeaf2876b91d0db63c4e347afd558f613
+44eafd38df995bd98fcb720ce19023c26e0b1157e299e18d13fc7715bc1141d4
+49f05fc6bf234ab5af157696a354495e45a818f41a007e601b49500e7554695a
+4c21c8f6fb67d7b81379f6d3abff7b059f277e48c0291852c6af3e9d412526e6
+b23653e0283af4ff8f06503ef135f552270f04d735cc21fbaa059025e7e32cc7
+f03bdc406a167be87ce1442f285aba9aab9f4ff91daed0f04eadcc8e98a6ef67
+0263a76e5b77baf65f979e202658c06d0deaa83aeb577e4872a916a87b8aad9e
+9c9b22630d3b3b95b790f11f83bc6a52497a7c03264d70f55b6ee2ecf4f5af13
+d45df4bcefc85437ad3d9b78e565e3dadc353e972fc21ba6f8ce701cb9c1aae6
+5b2ffd89d65075bd6a5ae8f195d13165969e08c20a6143efa43a31963e81805b
+584f93e1957713065d371abeef4ade6c3c024f37bcb2cc00895252332325359e
+6f7425665f46bf49ed14cbdd14a659876670d962d36aab38e75c47db93978cc7
+c30e5e33185c437cfc260caa8c3af8a0fe39d955fe41a89344db01f0f33632b5
+71832eff64ed70de8b5dcf90e73e908b274441d7e34e14381c6a88bf71db2703
+8b3037bcd5eb5a4a1c9b6067d2874b898c95dee5b114c10528dd3cd04d412719
+0405f89ad7461b66eac5bb976c6eb433a43db8847ab105a9d6e004c1d08e17ec
+c402862aeba56fa63297c5dab64a0f3dba016a5af5c761de36c9bdf0b375c0bd
+6fd3c0fa3787e362103c3f96d6d1bca0fe0b3fa33c034f472204cef2949742fa
+5b973d21b8af8e7c1ede70cb40860f7a58ac12a7709be24ba724166770215440
+b0dd64dbe6af369ec9fc0d82e3c7a597884e4330109ab7631b8f8a62f0ce7dc1
+7c9919d55bd997497b66e4089b640ada46e454b4cd90a45a5805eda36ec5db69
+ca53cd3380d2f59c9cc4c6d52139cc33324161adabcf2eb44cfce47ba893bd4a
+53d4480118c1ba64436d3771ded3182b2de8306237012aea5d5a2995abcbc097
+e7535e259053c58c8de2a6c7c8d21ad6feec5907c2f6783541c68d00be43776a
+8e766d72a8fa8123d819d38f1f53f36bd48adcc6f7a1455cc87453f96e550903
+df9b819196a27061facc772b773dbd1444c37d3136a0d3158d79e98a70e8e030
+dbaa42c202db2c0f8b03687f3d48b0f1783124024a5ebc0433990b1591459766
+cbeaadebafa313226d839697f97e14cad664856368583b3e2e79609cac4c81af
+e602dd4200cfa43fda4f1e48d68b13f27533ab9f3fd05a0143378b81d7e5bc77
+eb8829d3d4e896af1c31ae42d39bc60f687306a10107727c8fc2fb98ad61af9b
+7808b6afccd125519cc4f98828e53ac23388ffa188e885c64a97439cabfeeaca
+48453cf4c6ac118ff667c21300d1c1ed5fef10e03f22e69e36248e476519a677
+fd224e37ac95fa3d9aeea5b2482da91aec2f5e7a2b57a84ec7ec8699fc658175
+7cfc8ed6bab56242725f615304b3cc39c20e8dd67136f864ad32605b0ea9ab0d
+3662bb1ec7e317684a5a6afd8c3e83358db1392bdfb53dcb2d1624ba8772f701
+a3626967c0a543a4b01d70aadea4d1c2c86383c6eb9a722a6c833c0c5f7e92ef
+d67ff6bb9fc72a9933a446ac965c26c72ab279c5755890d21a9dd9f3862582bd
+b1d9ccd1963a21bacd4be17d03819ab523f4473b20a87f120dcef914c72144e3
+50ac33a94859de19fc1c45816ba504646b8b53410dedf6f2b1dd9b2f0b274901
+3aeba319bc7d2e1adc99cbcff5d5ca41baf982ab06c3741fdde91b5ae8601be0
+a690a8848d30eb1727351734daa8ec8fc416bb425309b1232d290ad42ab8d970
+62812696531e1a5f6f87844f9ad9fe0cc660a7c4bb1f7c2d37ac95214fe2cb45
+37f763691698dfc6cb42aee39ca3e37910a5caa4bbc93b20d7565936223f79d7
+77d14971397338d791989bdd842a25eb4747a45fb3d0d853000205301a799d0f
+1a597a34fad9c47ba0c27a82251b4d460f1de01fd0066bef08e4e6139412f5f7
+b46ca9c6fc7b5e1bff8f5a24498699cc168b419278a41f5eb1845b41a298cda7
+e237d3b149ebc1ebb02c33433c0cc8043bee875475cc389dfdb141fa31a67c9b
+97f2bd9afcdcbd16b0682b3da7c3fe91ce83fa0eee07e155dbbafa26ff706798
+c07bc149d963c31bd8b3d9736a21d45d5d7761f6d93111a10b978b32a00b6593
+4ad2e4df3c2979ce6179aaa50a28348d3fd1743d482c16a2538eaaa17f6894fe
+a19a21411ac73ff779f355ae9fca182a55d43f1080a60721ec087738c87987c4
+699e24c19172afdf0461ef5d75820f2957bf75b1b396bf2a5462c7be537e67d2
+8ddeb130863434670c75b36878888a430846e1f6565c9f0f529ad4e5d2386dc6
+1f9fb0f4782a802c853cf5830763f5b9df5d77c5c3fef77c14fa64b966573237
+b911aa353738e3ce2683d5a4612ddce6c8f50cd2c0b11912b7b09cb60590ea9b
+25dad41363a82751aff5a9da8e1fb9643a84f3701b518b059e935a3199685c4b
+f2afa07980ad93fcc6e7733a7c1cdb6d9ea9756eb985041297452d74381a609b
+b8c3f9cc4c7b9ad09e57753602e856b5511cda7b0c9a5e0fbab6c9ef7d7e8d67
+51760312ba04d771974ce5b6c18d9de0d4bf76d5e5b6cd7c3706f94693215165
+881bf682231eb90cb99794177468d89877475bd1510e117d5f845f26fa303762
+c92c2ced4c73a82afeedb275f48fb2cbbee350511004a58efd38e7002e91260e
+40f0792b73dbc2158d542146aac2b860479bf6046c7e0e4edc26090205846fc8
+e333cc60a4aa3990290508b400fb02f09560be4f200d272c713ba3b615e2b40b
+9552cd70a67a098edf6f1bc4ea86732f1fcc762f513a1a004d39c1dd6d8d0650
+24ad72b147c850945b7bfb29e830d4ef2e84d694422f1c89bc34ee502aca300d
+f3c5a3e0ff8359668b11ea33ce14ef62cca8e2dfb8e5ab68d96a9a2552bf53af
+81e78c84d96f3b1eda14e19ac07e75e3d3e5454200592a259bc950ccb398dc20
+862141083a5190c1b2cb0aa0d8d3e8a5a3b21004fd002040c4b3ea35de14ccc1
+ccd679d99308409a138c1ec129a71a1bb1443d1754f4763765b6409e8280e25b
+5965f444cbb2a6b78bf8541250b992e39d0a4c14ed92c7b9ca642ec4002946f5
+93ae24cc194f41357a86b418c8451b342860441b9d2e33c7f8a81ecfc0e5630d
+23ee1fe752b2536ca59253c97aa18712f73f2b0335eeb0c2a26cbd98eedc669e
+938831427718070324999284196cdbae8f16946b2bbf2b9f2a8e0a5928447383
+1de3315a2dc0ae872b1036a8040d9c2a0c77a6c0c473c293ab7e19837fd227b3
+52e8bf1bc817c76412f1d6abd47d809e989b3b2f89285d2693824df3191a6d1b
+c8c9853f2bf81b8c96607a02b31d23d7495a590cf3f96d7328c4fd74452dc16c
+2818512abf981c423d146e9d7a46bf2ef32a98dda4f6695f42532fabb8abba65
+de15bf69090b724a247fcdfefd6f1a83cc35a049d3324bd39816f4ee13a5a38d
+a73a3c3fb031daf9bf78fde0f8f6bdd0e897a3b24e090b54a955b232b2258e5f
+2bfbfbe13db81f6abd243d73e3ff7d5d21527541ce6258732e85baddc7e56dc1
+ae4b2bdead6d8de14b406a7234ab0c0fb1b6f129a7877adb864cfe9abef498ea
+89232ee6639c0cea4dbd515a7a09aafbe65d04ec923e1200fcce3a2f684c07f2
+02273eb6a93f7ae0771e7115385296132be25b258f67273c5a0f28f98627abf7
+7751b7860e123e4a4e70422114eafe03c2606f854588ef418312650f11393ea1
+5bfa6337b955355a183573948398e4438b3e13fc83a36f2d86cca04e6787f6a0
+b29bfbb9aba924f37f5174e3ee892d16102d37b14d7743d9725ac7367217425c
+f6263f30097ef995d81458db1357305c6044d6e490d9631e9ee456db83af1d45
+4176174c786a03a7771b02c10daa800cfa6819f878c871f0b3230e5aeb87d8e9
+b5d0e701fc2dd78a2ef5f9e3f0e060eeafc7ebeb813d13d4d77f1130256ceda9
+4dd73b6e7b423d7f4c0c55f3491bbf6153b106b1316b9eb2ce72b263f05fda15
+0b748d74b05f238982702f9564fb43259e9fd1f77d753f7a9bee8d81b2ea2d5b
+abfa686d76582857a1a2338a5f8c2733728fdd4adffcc90331d2670c260111b7
+6369299e8f79a9570d277107c81fbd22faf23d821471f8359f13980f282516b7
+800ba8ecbac26e646e401a4d7a644fc3851749c5d19a915fb046bc40de6256a2
+4184d666de6f54e6855060071896eea3338fbea7771f129a449e5bbb498f5edf
+7dfb723d4838d670b76ae2842b726e757d534c24ebc471588ea38760f07b59c9
+af9649132871a23ce328acfee7f583f7ff0486e07187a3d4942aaa9e6a38c615
+43299873ae9c902dc5777ef58d396b5feb718509da30302ca268a9fe75e8343e
+a5f4da3a39445369280cfca5442939a61f82f24b15bfc71d2e1b2880df011732
+32527227875329ab6069618cde196f153e7ec3b1dc5fa627ed4f49a43550d02c
+dd80cfc131d86dfd6ef64530f16be3c08b2fe804ba2c8b8ef512bac05420f780
+9507cdc6aedbfa690c85a1bee6f424799dd0407f40e90051ce3d6b1020719e05
+9187a78047533060ed3426bb7c314b179b608fdb19f181e4cf616e0eb850c408
+85f2e1d9c5afa60dd6480166d7b227b731c8491237112df20561ef85e4a3d207
+4bf8ba61da1e50699e9f9aba612c8a9a536cfaf7c9137b08aeee41148f96118a
+43a901722f64a6457937eb18f9733fc353987b8e1fb9da5ec6c7229dad8d0456
+54bcf4426f7148ef1942cd42954a8e5e5767ddd899f178f6f2443b93be25d5d6
+1b9c06e68d653ba56f1506a88f9439a896b3f604880099548ab0dbc39b26237d
+d1bbf9c1858716d858b94377708b44d800b95f77ba4f63577d1758719e208c1d
+4757e53eec9ad4e1919e197b4507d1d43355c142e91c3d4d80064fa7fd5a85d7
+c08f43cdb63e507726b4378853d6ad68ecc29592eef5a8b72869a2164552ae62
+2f3f02dfa6cc2b5452898943fb90521daee4b1679df0d385b9ff15c9ac6c120b
+30626415ed3415d06608b8b182f3efd579a539771a2af421119c43a5444f187b
+55fb3b8668eafbcb63b919a2e2152aaa0d62613c37ca5002c6daea891411cb46
+d58d815d7f231678185a0ea2b59ceb1030a8a9959f3426a666352ce86ddb3422
+0f43b9f0695747f65b5c7d0c0bdaf97f76a67c396f24f5c3d277a375744310a9
+f09dbe9f4501739523f301d94e6519029352ff5c1cced0d6dd89af38c49d8fdf
+adbfc0baf374d259404ce7bfd2bf94a09a02e3463ab9c6d975190944acde8589
+4ca4537a35ae86e26af1bd5e5bb7c7d24e671bd182153a5022047bd8c138016a
+a85f3b7b62bfdbc06ae4dbe5e37528d6c6432b3db333a1347a09838c17b5de1b
+2f9570c33e7580978d48effc18fa8e0fec834076990e0d4b8abaa2c336408011
+53c5ffc858524015d49008574cf40c060b751c67395e8d39952b5514463241e8
+aca46f92701b889780db90362ca74b5d13c5f9d3362a0b53d2dbaac2c54836e4
+e42422aa713a20a5124ee36b353631a3933a5bbe368b0c4fd93aac08fdbdd557
+59778a0b7ff59a185e2f9162c0ab4ce98bd37fdc7a85dddcddc3d5eba6020166
+8eda23e041e6920b10912d251171fd3fa5bdbeae378e996d039c7b07bc4aca72
+e81625f6f816a2bb469d2458518988aaddceb796926d796673c030554e7046b0
+0cd49f488394682075dcd5dd193fbfd068636c9daf09f6eda12a326c0bef9abc
+11578c932adf74009a4fb22ff201377253262e144366c9f9c140db1fc3074434
+87b103b07a68a869b23a613b0c69f687632f9a89bd1e3c9bb4bcb6b0b4bebb49
+8518f577692d8292730c3e761eb113bfd398b6f4f6e9aadee2f1baabd2cfef83
+de4e0924b35836bd53198fee5eeeed8aa2c15c5117f242ca04ddaf1ffc9ae2fb
+41a343b215b005e7267fd653e365a6842bad6be7d97a1df27404ab67126d88bc
+79139d47b3a0ad8f8eb78d4a28a503754513393ce036f6671c1ccc0eab2befee
+6f9d3b5afb869303af5580ea0b3568f8187087aca49310d17dc2e4b626f11ac2
+bca641f79e15101aa92b013dbdea8c4f28357d0fc8bd2cba2678f0058adc282a
+aa1cfcb544f6bef2b2b65488173e6fddb915382a02fd74806fe62fcaad8ca435
+7bd0073647d2809fc510d91b38dd7a964668f72d76d45d3dace0d6383135880d
+1082faf3595d0efb5b3026c0de0b4fe19d4713a8c1b31cbf82b9f4b458c75d74
+3e7731d662b5b78afc79c962a6d73e92bd63dfeccdbfcee8c33cf0f1058dd6ee
+ff9146cf33f535b4fe245110aea3ce3359accd39926187dc760dec775c0db374
+a77f9712be3312264042527b98267aa3cad2c49d0e33aba1d87712bc4ff630f7
+205019eaa70eee3cc1bd3e4c9f91aecdc8d8e1913ac869250c696a060b673c40
+b2d0fc55673c8c262dfdb0a730228c96e5f95a8d01e4559af8ca5bb847d07581
+5bed1aa246387bd73144b416fbe6652933956354c17a975209af6e2aceed8f07
+8e2ab2dd70221bf9b174cbda7cfae19c1313f4d6e0530e40df9c2f752ef81118
+e9cb012af24fe686924a3f5d145cb01942b72be7548f0d3a3ae8455ec4e422e4
+459e5e231be8510628c22295e5ab6226afeffa45b24ecdfeeefb7ef8717869b7
+758296e3249d4610ce84939d8f5a2b3dab176ec4b4e8902b1591099782f306ff
+396a10ba8caaf297123c8c46b8d17cb7f4390c61d4f5ae73e04fe0ea12b2d9ca
+2030cf4ba8d41484a101c9345f9849694ffdcdc3977382c54c4289c58960048a
+45ac803c9a91a2846d4675917b01393c4d8c130c2110a0e3bcf46d79f3ed369d
+19d5cd3be63489816cab5cb1c1eb46cf2550a4fb5ee579152bbd064e38616f6a
+de92f96bc7517596f71b35ee3f176bb07861881c6cb050bef617d19b071fba4c
+909a8a065aa936406c75e4936e9e138348f7321abf5ca3f4df3be8d0486dac3d
+51c41b750a1e41f4004dab3de9ac98b33baab15feedb88c291d71c302adca759
+2e1add8db5a26bde1fadb524588fb8b2971b86c8f31dc72eb3f2e1f3c673bccc
+65c64b2c129b862bcfdad7f3672b4c6b99fc413728a83aa750b15708540a38a0
+598ac513ddbbacae4b22fe4d2ea91b3eccf11bd5209032b3c744275c5dc194d8
+952c4f91dc97ab263685a2c2af2ca0b0043307445ffaba4fc039abd736499882
+51021b0ebf29492634dbc38a677e5bfbdd6716ac11d96de5459de1bdcabd7fc3
+528baf83527ffc7e9257800590cf22d7fbf66e48597e33a39f056c80e8713d73
+94a3eb7b3c65db7e7ca620db7ea44c67cab637c1c5d3606802ee0288ffc575e8
+29e05b312a50f0fee6180d8ac0cf7d0ac87d5c6933f88ab16884e412fb545c48
+c45e60e7e3322e9d1640abecf328ca705ef7f2eff6560f2b39b19354afb51515
+07fe5c904481b7f5201b7bda802357b01755da1d3bfd21d941df316198e652af
+5be4efc5e8d8e14d5ec9e3665881c74f660518b45aced85bf5b313c62e8ccd4a
+9d2d7f32a741dc00fd5f34ac215ac596cbe8b143fa8cc948e52387797268555d
+9a6d454ce1aa5cf8eba620a10483d8099c33520d88fbcaf0e1fb570b037b2bf0
+44acf21d9daee9dbf1b0b311fbbc3505f78ebd7ddbc027a5eca10507216e1963
+2b813b258e61fee6aef63c1570616eaa9f9dae95c212e758ab1e51da1fffdeb2
+79260de737a48f3e1fe5d20475ce1223d006a31b1ddf3182ffa611db5ecd812a
+4dd8a26a
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+{restore}if
+
+%%EndResource
+/F5_0 /CairoFont-0-0 1 1
+[ /.notdef/d/o/x/y/g/e/n
+ /s/a/r/c/h/t/period/m
+ /l/space/w/i/b/H/T/M
+ /L/p/u/q/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
+pdfMakeFont
+%%EndSetup
+pdfStartPage
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+{} settransfer
+q
+q
+36 35 105 471 re
+W
+/DeviceRGB {} cs
+[1 1 1] sc
+/DeviceRGB {} CS
+[1 1 1] SC
+1 w
+0 J
+1 j
+[] 0 d
+10 M
+36 35 105 471 re
+f
+36 35 105 471 re
+S
+/DeviceRGB {} CS
+[0 0 0] SC
+119.301 484 m
+119.301 474.059 105.285 466 88 466 c
+70.715 466 56.699 474.059 56.699 484 c
+56.699 493.941 70.715 502 88 502 c
+105.285 502 119.301 493.941 119.301 484 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 69.5 481.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\001) 0.556 Tj
+31 TJm
+(\002) 0.556 Tj
+31 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\004) 0.5 Tj
+-25 TJm
+(\005) 0.556 Tj
+31 TJm
+(\006) 0.556 Tj
+31 TJm
+(\007) 0.556 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+123.25 418 m
+46.75 418 l
+46.75 382 l
+129.25 382 l
+129.25 412 l
+123.25 418 l
+h
+S
+123.25 418 m
+123.25 412 l
+S
+129.25 412 m
+123.25 412 l
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 54.5 397.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\010) 0.5 Tj
+-25 TJm
+(\006) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+33 TJm
+(\013) 0.5 Tj
+-25 TJm
+(\014) 0.556 Tj
+31 TJm
+(\001) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\015) 0.278 Tj
+-22 TJm
+(\011) 0.556 Tj
+31 TJm
+(\016) 0.278 Tj
+-23 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\017) 0.832 Tj
+8 TJm
+(\020) 0.222 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+88 465.609 m
+88 454.773 88 440.602 88 428.293 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+91.5 428.082 m
+88 418.082 l
+84.5 428.082 l
+91.5 428.082 l
+h
+f
+91.5 428.082 m
+88 418.082 l
+84.5 428.082 l
+91.5 428.082 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 88 439.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\022) 0.721 Tj
+-28 TJm
+(\012) 0.333 Tj
+33 TJm
+(\023) 0.222 Tj
+-3 TJm
+(\015) 0.278 Tj
+-22 TJm
+(\006) 0.556 Tj
+31 TJm
+(\010) 0.5 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+128.426 316 m
+128.426 306.059 110.328 298 88 298 c
+65.672 298 47.574 306.059 47.574 316 c
+47.574 325.941 65.672 334 88 334 c
+110.328 334 128.426 325.941 128.426 316 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 61.5 313.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\001) 0.556 Tj
+31 TJm
+(\002) 0.556 Tj
+31 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\004) 0.5 Tj
+-25 TJm
+(\023) 0.222 Tj
+-3 TJm
+(\007) 0.556 Tj
+31 TJm
+(\001) 0.556 Tj
+31 TJm
+(\006) 0.556 Tj
+31 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\006) 0.556 Tj
+30 TJm
+(\012) 0.333 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+122 250 m
+48 250 l
+48 214 l
+128 214 l
+128 244 l
+122 250 l
+h
+S
+122 250 m
+122 244 l
+S
+128 244 m
+122 244 l
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 56 229.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\001) 0.556 Tj
+31 TJm
+(\002) 0.556 Tj
+31 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\004) 0.5 Tj
+-25 TJm
+(\010) 0.5 Tj
+-25 TJm
+(\006) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+33 TJm
+(\013) 0.5 Tj
+-25 TJm
+(\014) 0.556 Tj
+31 TJm
+(\016) 0.278 Tj
+-23 TJm
+(\001) 0.556 Tj
+31 TJm
+(\024) 0.556 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+88 297.609 m
+88 286.773 88 272.602 88 260.293 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+91.5 260.082 m
+88 250.082 l
+84.5 260.082 l
+91.5 260.082 l
+h
+f
+91.5 260.082 m
+88 250.082 l
+84.5 260.082 l
+91.5 260.082 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 88 271.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\022) 0.721 Tj
+-28 TJm
+(\012) 0.333 Tj
+33 TJm
+(\023) 0.222 Tj
+-3 TJm
+(\015) 0.278 Tj
+-22 TJm
+(\006) 0.556 Tj
+31 TJm
+(\010) 0.5 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+136.289 148 m
+136.289 138.059 114.672 130 88 130 c
+61.328 130 39.711 138.059 39.711 148 c
+39.711 157.941 61.328 166 88 166 c
+114.672 166 136.289 157.941 136.289 148 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 54.5 145.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\001) 0.556 Tj
+31 TJm
+(\002) 0.556 Tj
+31 TJm
+(\003) 0.5 Tj
+-25 TJm
+(\004) 0.5 Tj
+-25 TJm
+(\010) 0.5 Tj
+-25 TJm
+(\006) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+33 TJm
+(\013) 0.5 Tj
+-25 TJm
+(\014) 0.556 Tj
+31 TJm
+(\016) 0.278 Tj
+-23 TJm
+(\013) 0.5 Tj
+-25 TJm
+(\005) 0.556 Tj
+31 TJm
+(\023) 0.222 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+136.125 61 m
+136.125 49.164 114.578 39.57 88 39.57 c
+61.422 39.57 39.875 49.164 39.875 61 c
+39.875 72.836 61.422 82.43 88 82.43 c
+114.578 82.43 136.125 72.836 136.125 61 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 62 64] Tm
+0 0 Td
+/F5_0 1 Tf
+(\025) 0.721 Tj
+-28 TJm
+(\026) 0.61 Tj
+11 TJm
+(\027) 0.832 Tj
+8 TJm
+(\030) 0.556 Tj
+31 TJm
+(\021) 0.278 Tj
+-22 TJm
+(\031) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\005) 0.556 Tj
+31 TJm
+(\006) 0.556 Tj
+0.300007 -1.100027 Td
+(\023) 0.222 Tj
+-3 TJm
+(\007) 0.556 Tj
+31 TJm
+(\021) 0.278 Tj
+-22 TJm
+(\024) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+33 TJm
+(\002) 0.556 Tj
+31 TJm
+(\022) 0.721 Tj
+-28 TJm
+(\010) 0.5 Tj
+-25 TJm
+(\006) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+65.395 131.844 m
+55.582 123.238 47.281 111.84 52 100 c
+53.711 95.703 56.164 91.617 58.996 87.82 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+61.828 89.895 m
+65.66 80.02 l
+56.504 85.348 l
+61.828 89.895 l
+h
+f
+61.828 89.895 m
+65.66 80.02 l
+56.504 85.348 l
+61.828 89.895 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 52 103.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\005) 0.556 Tj
+31 TJm
+(\006) 0.556 Tj
+31 TJm
+(\015) 0.278 Tj
+-22 TJm
+(\021) 0.278 Tj
+-22 TJm
+(\012) 0.333 Tj
+33 TJm
+(\006) 0.556 Tj
+31 TJm
+(\010) 0.5 Tj
+-25 TJm
+(\032) 0.556 Tj
+31 TJm
+(\020) 0.222 Tj
+-3 TJm
+(\015) 0.278 Tj
+-22 TJm
+(\010) 0.5 Tj
+-25 TJm
+(\021) 0.278 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+99.348 81.715 m
+103.281 90.82 106.211 101.848 104 112 c
+103.375 114.875 102.488 117.801 101.453 120.668 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+98.152 119.488 m
+97.508 130.062 l
+104.605 122.199 l
+98.152 119.488 l
+h
+f
+98.152 119.488 m
+97.508 130.062 l
+104.605 122.199 l
+98.152 119.488 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 104 103.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\033) 0.556 Tj
+31 TJm
+(\032) 0.556 Tj
+31 TJm
+(\006) 0.556 Tj
+31 TJm
+(\012) 0.333 Tj
+33 TJm
+(\004) 0.5 Tj
+-25 TJm
+(\021) 0.278 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+88 381.609 m
+88 370.773 88 356.602 88 344.293 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+91.5 344.082 m
+88 334.082 l
+84.5 344.082 l
+91.5 344.082 l
+h
+f
+91.5 344.082 m
+88 334.082 l
+84.5 344.082 l
+91.5 344.082 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 88 355.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\012) 0.333 Tj
+33 TJm
+(\006) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\001) 0.556 Tj
+31 TJm
+(\010) 0.5 Tj
+/DeviceRGB {} CS
+[0 0 0] SC
+88 213.609 m
+88 202.773 88 188.602 88 176.293 c
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+91.5 176.082 m
+88 166.082 l
+84.5 176.082 l
+91.5 176.082 l
+h
+f
+91.5 176.082 m
+88 166.082 l
+84.5 176.082 l
+91.5 176.082 l
+h
+S
+/DeviceRGB {} cs
+[0 0 0] sc
+[1 0 0 1 0 0] Tm
+0 0 Td
+[9.999756 0 0 9.999756 88 187.5] Tm
+0 0 Td
+/F5_0 1 Tf
+(\021) 0.278 Tj
+-22 TJm
+(\012) 0.333 Tj
+33 TJm
+(\006) 0.556 Tj
+31 TJm
+(\011) 0.556 Tj
+31 TJm
+(\001) 0.556 Tj
+31 TJm
+(\010) 0.5 Tj
+Q
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Trailer
+end
+%%DocumentSuppliedResources:
+%%+ font CairoFont-0-0
+%%EOF
diff --git a/doc/extsearch_flow.png b/doc/extsearch_flow.png
new file mode 100644
index 0000000..e99450c
Binary files /dev/null and b/doc/extsearch_flow.png differ
diff --git a/doc/faq.doc b/doc/faq.doc
new file mode 100644
index 0000000..356c42b
--- /dev/null
+++ b/doc/faq.doc
@@ -0,0 +1,290 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page faq Frequently Asked Questions
+
+\tableofcontents
+
+
+\section faq_index How to get information on the index page in HTML?
+<p>
+You should use the \ref cmdmainpage "\\mainpage" command inside a comment block like this:
+\verbatim
+/*! \mainpage My Personal Index Page
+ *
+ * \section intro_sec Introduction
+ *
+ * This is the introduction.
+ *
+ * \section install_sec Installation
+ *
+ * \subsection step1 Step 1: Opening the box
+ *
+ * etc...
+ */
+\endverbatim
+
+\section fac_al Help, some/all of the members of my class / file / namespace are not documented?
+
+ Check the following:
+ <ol>
+ <li>Is your class / file / namespace documented? If not, it will not
+ be extracted from the sources unless \ref cfg_extract_all "EXTRACT_ALL" is set to \c YES
+ in the config file.
+ <li>Are the members private? If so, you must set \ref cfg_extract_private "EXTRACT_PRIVATE" to \c YES
+ to make them appear in the documentation.
+ <li>Is there a function macro in your class that does not end with a
+ semicolon (e.g. MY_MACRO())? If so then you have to instruct
+ doxygen's preprocessor to remove it.
+
+ This typically boils down to the following settings in the config file:
+
+ \verbatim
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = MY_MACRO()=
+ \endverbatim
+
+ Please read the \ref preprocessing "preprocessing" section of the
+ manual for more information.
+ </ol>
+
+\section faq_extract_allWhen I set EXTRACT_ALL to NO none of my functions are shown in the documentation.
+
+In order for global functions, variables, enums, typedefs, and defines
+to be documented you should document the file in which these commands are
+located using a comment block containing a \ref cmdfile "\\file" (or \ref cmdfile "\@file")
+command.
+
+Alternatively, you can put all members in a group (or module)
+using the \ref cmdingroup "\\ingroup" command and then document the group using a comment
+block containing the \ref cmddefgroup "\\defgroup" command.
+
+For member functions or functions that are part of a namespace you should
+document either the class or namespace.
+
+\section faq_code How can I make doxygen ignore some code fragment?
+
+The new and easiest way is to add one comment block
+with a \ref cmdcond "\\cond" command at the start and one comment block
+with a \ref cmdendcond "\\endcond" command at the end of the piece of
+code that should be ignored. This should be within the same file of course.
+
+But you can also use Doxygen's preprocessor for this:
+If you put
+\verbatim
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ /* code that must be skipped by Doxygen */
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+\endverbatim
+around the blocks that should be hidden and put:
+\verbatim
+ PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
+\endverbatim
+in the config file then all blocks should be skipped by Doxygen as long
+as \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" is set to `YES`.
+
+\section faq_code_inc How can I change what is after the <code>\#include</code> in the class documentation?
+
+In most cases you can use \ref cfg_strip_from_inc_path "STRIP_FROM_INC_PATH"
+to strip a user defined part of a path.
+
+You can also document your class as follows
+
+\verbatim
+/*! \class MyClassName include.h path/include.h
+ *
+ * Docs for MyClassName
+ */
+\endverbatim
+
+To make doxygen put <br><br>
+<code>
+\#include \<path/include.h\>
+</code>
+
+in the documentation of the class MyClassName regardless of the name of the actual
+header file in which the definition of MyClassName is contained.
+
+If you want doxygen to show that the include file should be included using
+quotes instead of angle brackets you should type:
+\verbatim
+/*! \class MyClassName myhdr.h "path/myhdr.h"
+ *
+ * Docs for MyClassName
+ */
+\endverbatim
+
+\section faq_chm How can I use tag files in combination with compressed HTML?
+
+If you want to refer from one compressed HTML file
+\c a.chm to another compressed HTML file
+called \c b.chm, the
+link in \c a.chm must have the following format:
+\verbatim
+<a href="b.chm::/file.html">
+\endverbatim
+Unfortunately this only works if both compressed HTML files are in the same
+directory.
+
+As a result you must rename the generated \c index.chm files for all projects
+into something unique and put all <code>.chm</code> files in one directory.
+
+Suppose you have a project \e a referring to a project \e b using tag file
+\c b.tag, then you could rename the \c index.chm for project \e a into
+\c a.chm and the \c index.chm for project \e b into \c b.chm. In the
+configuration file for project \e a you write:
+\verbatim
+TAGFILES = b.tag=b.chm::
+\endverbatim
+
+\section faq_html I don't like the quick index that is put above each HTML page, what do I do?
+
+You can disable the index by setting \ref cfg_disable_index "DISABLE_INDEX" to `YES`. Then you can
+put in your own header file by writing your own header and feed that to
+\ref cfg_html_header "HTML_HEADER".
+
+\section faq_html_header The overall HTML output looks different, while I only wanted to use my own html header file
+
+You probably forgot to include the stylesheet <code>doxygen.css</code> that
+doxygen generates. You can include this by putting
+\verbatim
+<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
+\endverbatim
+in the HEAD section of the HTML page.
+
+\section faq_use_qt Why does doxygen use Qt?
+
+The most important reason is to have a platform abstraction for most
+Unices and Windows by means of the QFile, QFileInfo, QDir, QDate,
+QTime and QIODevice classes.
+Another reason is for the nice and bug free utility classes, like QList,
+QDict, QString, QArray, QTextStream, QRegExp, QXML etc.
+
+The GUI front-end doxywizard uses Qt for... well... the GUI!
+
+\section faq_excl_dir How can I exclude all test directories from my directory tree?
+
+Simply put an exclude pattern like this in the configuration file:
+
+\verbatim
+EXCLUDE_PATTERNS = */test/*
+\endverbatim
+
+\section faq_class Doxygen automatically generates a link to the class MyClass somewhere in the running text. How do I prevent that at a certain place?
+
+Put a \% in front of the class name. Like this: \%MyClass. Doxygen will then
+remove the % and keep the word unlinked.
+
+\section faq_pgm_X My favorite programming language is X. Can I still use doxygen?
+
+No, not as such; doxygen needs to understand the structure of what it reads.
+If you don't mind spending some time on it, there are several options:
+- If the grammar of X is close to C or C++, then it is probably not too hard to
+ tweak src/scanner.l a bit so the language is supported. This is done
+ for all other languages directly supported by doxygen
+ (i.e. Java, IDL, C#, PHP).
+- If the grammar of X is somewhat different than you can write an input
+ filter that translates X into something similar enough to C/C++ for
+ doxygen to understand (this approach is taken for VB, Object Pascal, and
+ Javascript, see http://www.stack.nl/~dimitri/doxygen/download.html#helpers).
+- If the grammar is completely different one could write a parser for X and
+ write a backend that produces a similar syntax tree as is done by
+ src/scanner.l (and also by src/tagreader.cpp while reading tag files).
+
+\section faq_lex Help! I get the cryptic message "input buffer overflow, can't enlarge buffer because scanner uses REJECT"
+
+This error happens when doxygen's lexical scanner has a rule that matches
+more than 256K of input characters in one go. I've seen this happening
+on a very large generated file (\>256K lines), where the built-in preprocessor
+converted it into an empty file (with \>256K of newlines). Another case
+where this might happen is if you have lines in your code with more than
+256K characters.
+
+If you have run into such a case and want me to fix it, you
+should send me a code fragment that triggers the message. To work around
+the problem, put some line-breaks into your file, split it up into smaller
+parts, or exclude it from the input using EXCLUDE.
+
+\section faq_latex When running make in the latex dir I get "TeX capacity exceeded". Now what?
+
+You can edit the texmf.cfg file to increase the default values of the
+various buffers and then run "texconfig init".
+
+\section faq_stl Why are dependencies via STL classes not shown in the dot graphs?
+
+Doxygen is unaware of the STL classes, unless the
+option \ref cfg_builtin_stl_support "BUILTIN_STL_SUPPORT" is turned on.
+
+\section faq_search I have problems getting the search engine to work with PHP5 and/or windows
+
+Please read <a href="searchengine.html">this</a> for hints on where to look.
+
+\section faq_cmdline Can I configure doxygen from the command line?
+
+Not via command line options, but doxygen can read from <code>stdin</code>,
+so you can pipe things through it. Here's an example how to override an option
+in a configuration file from the command line (assuming a UNIX like environment):
+
+\verbatim
+( cat Doxyfile ; echo "PROJECT_NUMBER=1.0" ) | doxygen -
+\endverbatim
+
+For Windows the following would do the same:
+
+\verbatim
+( type Doxyfile & echo PROJECT_NUMBER=1.0 ) | doxygen.exe -
+\endverbatim
+
+If multiple options with the same name are specified then doxygen will use
+the last one. To append to an existing option you can use the += operator.
+
+\section faq_name How did doxygen get its name?
+
+Doxygen got its name from playing with the words
+documentation and generator.
+
+\verbatim
+documentation -> docs -> dox
+generator -> gen
+\endverbatim
+
+At the time I was looking into \c lex and \c yacc, where a lot of things start with
+"yy", so the "y" slipped in and made things pronounceable
+(the proper pronouncement is Docs-ee-gen, so with a long "e").
+
+\section faq_why What was the reason to develop doxygen?
+
+I once wrote a GUI widget based on the Qt library (it is still available at
+http://sourceforge.net/projects/qdbttabular/ but hasn't been updated since 2002).
+Qt had nicely generated documentation (using an internal tool which
+<a href="http://rant.gulbrandsen.priv.no/udoc/history">they didn't want to release</a>)
+and I wrote similar docs by hand.
+This was a nightmare to maintain, so I wanted a similar tool. I looked at
+Doc++ but that just wasn't good enough (it didn't support signals and
+slots and did not have the Qt look and feel I had grown to like),
+so I started to write my own tool...
+
+\htmlonly
+Go to the <a href="trouble.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/features.doc b/doc/features.doc
new file mode 100644
index 0000000..bd548c2
--- /dev/null
+++ b/doc/features.doc
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page features Features
+
+\addindex features
+<UL>
+<li>Requires very little overhead from the writer of the documentation.
+ Plain text will do, Markdown is support, and for more fancy or
+ structured output HTML tags and/or some of doxygen's special commands
+ can be used.
+<li>Cross platform: works on Windows and many Unix flavors (including Linux and
+ MacOSX).
+<li>Indexes, organizes and generates browsable and cross-referenced
+ output even from undocumented code.
+<li>Generates structured XML output for parsed sources, which can be
+ used by external tools.
+<li>Supports C/C++, Java, (Corba and Microsoft) Java, Python, VHDL, PHP
+ IDL, C#, Fortran, TCL, Objective-C 2.0, and to some extent D sources.
+<li>Supports documentation of files, namespaces, packages, classes,
+ structs, unions, templates, variables, functions, typedefs, enums and
+ defines.
+<li>JavaDoc (1.1), qdoc3 (partially), and ECMA-334 (C# spec.) compatible.
+<li>Comes with a GUI frontend (Doxywizard) to ease editing the options and
+ run doxygen. The GUI is available on Windows, Linux, and MacOSX.
+<li>Automatically generates class and collaboration diagrams in HTML (as clickable
+ image maps) and \LaTeX (as Encapsulated PostScript images).
+<li>Uses the `dot` tool of the Graphviz tool kit to generate
+ include dependency graphs, collaboration diagrams, call graphs, directory structure
+ graphs, and graphical class hierarchy graphs.
+<li>Allows grouping of entities in modules and creating a hierarchy of modules.
+<li>Flexible comment placement: Allows you to put documentation in the
+ header file (before the
+ declaration of an entity), source file (before the definition of an entity)
+ or in a separate file.
+<li>Generates a list of all members of a class (including any inherited
+ members) along with their protection level.
+<li>Outputs documentation in on-line format (XHTML and UNIX man page) and
+ off-line format (\LaTeX and RTF) simultaneously
+ (any of these can be disabled if desired). All formats are optimized for
+ ease of reading. <br>
+ Furthermore, compressed HTML can be generated from HTML output using
+ Microsoft's HTML Help Workshop (Windows only) and PDF can be generated
+ from the \LaTeX output.
+<li>Support for various third party help formats including HTML Help,
+ docsets, Qt-Help, and eclipse help.
+<li>Includes a full C preprocessor to allow proper parsing of conditional
+ code fragments and to allow expansion of all or part of macros definitions.
+<li>Automatically detects public, protected and private sections, as well as
+ the Qt specific signal and slots sections. Extraction of private class
+ members is optional.
+<li>Automatically generates references to documented classes, files, namespaces
+ and members. Documentation of global functions, global variables,
+ typedefs, defines and enumerations is also supported.
+<li>References to base/super classes and inherited/overridden members are
+ generated automatically.
+<li>Includes a fast, rank based search engine to search for strings or words
+ in the class and member documentation (PHP based).
+<li>Includes an Javascript based live search feature to search for symbols
+ as you type (for small to medium sized projects).
+<li>You can type normal HTML tags in your documentation. Doxygen will convert
+ them to their equivalent \LaTeX, RTF, and man-page
+ counterparts automatically.
+<li>Allows references to documentation generated for other (doxygen documented)
+ projects (or another part of the same project) in a location independent way.
+<li>Allows inclusion of source code examples that are automatically
+ cross-referenced with the documentation.
+<li>Inclusion of undocumented classes is also supported, allowing to quickly
+ learn the structure and interfaces of a (large) piece of code without
+ looking into the implementation details.
+<li>Allows automatic cross-referencing of (documented) entities with their
+ definition in the source code.
+<li>All source code fragments are syntax highlighted for ease of reading.
+<li>Allows inclusion of function/member/class definitions in the documentation.
+<li>All options are read from an easy to edit and (optionally) annotated
+ configuration file.
+<li>Documentation and search engine can be transferred to another
+ location or machine without regenerating the documentation.
+<li>Supports many different character encodings and uses UTF-8 internally and
+ for the generated output.
+<li>Doxygen can generate a layout which you can use and edit to change the
+ layout of each page.
+<li>There more than a 100 configurable options to fine-tune the output.
+<li>Can cope with large projects easily.
+</UL>
+
+Although doxygen can now be used in any project written in a language that is
+supported by doxygen, initially it was specifically designed to be used for projects
+that make use of Qt Software's
+<A HREF="http://qt-project.org/">Qt toolkit</A>. I have tried to
+make doxygen `Qt-compatible'. That is: Doxygen can read the documentation contained in
+the Qt source code and create a class browser that looks quite similar to the
+one that is generated by Qt Software. Doxygen understands the C++ extensions
+used by Qt such as signals and slots and many of the markup commands used in the Qt sources.
+
+Doxygen can also automatically generate links to existing documentation
+that was generated with Doxygen or with Qt's non-public class browser
+generator. For a Qt based project this means that whenever you refer to
+members or classes belonging to the Qt toolkit, a link will be generated to
+the Qt documentation. This is done independent of where this documentation
+is located!
+
+
+\htmlonly
+Go to the <a href="doxygen_usage.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/formulas.doc b/doc/formulas.doc
new file mode 100644
index 0000000..1a6208e
--- /dev/null
+++ b/doc/formulas.doc
@@ -0,0 +1,112 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page formulas Including formulas
+
+Doxygen allows you to put \LaTeX formulas in the
+output (this works only for the HTML and \LaTeX output,
+not for the RTF nor for the man page output). To be able to include
+formulas (as images) in the HTML documentation, you will also need to
+have the following tools installed
+<ul>
+<li>\c latex: the \LaTeX compiler, needed to parse the formulas.
+ To test I have used the teTeX 1.0 distribution.
+<li>\c dvips: a tool to convert DVI files to PostScript files
+ I have used version 5.92b from Radical Eye software for testing.
+<li>\c gs: the GhostScript interpreter for converting PostScript files
+ to bitmaps. I have used Aladdin GhostScript 8.0 for testing.
+</ul>
+For the HTML output there is also an alternative solution using
+<a href="http://www.mathjax.org">MathJax</a> which does not
+require the above tools. If you enable \ref cfg_use_mathjax "USE_MATHJAX" in
+the config then the latex formulas will be copied to the HTML "as is" and a
+client side javascript will parse them and turn them into (interactive) images.
+
+There are three ways to include formulas in the documentation.
+<ol>
+<li>Using in-text formulas that appear in the running text.
+ These formulas should be put between a pair of \\f\$
+ commands, so
+\verbatim
+ The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is
+ \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$.
+\endverbatim results in:
+
+ The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is
+ \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$.
+<br>
+<li>Unnumbered displayed formulas that are centered on a separate line.
+ These formulas should be put between \\f[ and \\f] commands.
+ An example:
+\verbatim
+ \f[
+ |I_2|=\left| \int_{0}^T \psi(t)
+ \left\{
+ u(a,t)-
+ \int_{\gamma(t)}^a
+ \frac{d\theta}{k(\theta,t)}
+ \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi
+ \right\} dt
+ \right|
+ \f]
+\endverbatim
+ results in:
+ \f[
+ |I_2|=\left| \int_{0}^T \psi(t)
+ \left\{
+ u(a,t)-
+ \int_{\gamma(t)}^a
+ \frac{d\theta}{k(\theta,t)}
+ \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi
+ \right\} dt
+ \right|
+ \f]
+<li>Formulas or other latex elements that are not in a math
+ environment can be specified using \\f{environment}, where
+ \c environment is the name of the \LaTeX environment,
+ the corresponding end command is \\f}. Here is an example for an
+ equation array
+\verbatim
+ \f{eqnarray*}{
+ g &=& \frac{Gm_2}{r^2} \\
+ &=& \frac{(6.673 \times 10^{-11}\,\mbox{m}^3\,\mbox{kg}^{-1}\,
+ \mbox{s}^{-2})(5.9736 \times 10^{24}\,\mbox{kg})}{(6371.01\,\mbox{km})^2} \\
+ &=& 9.82066032\,\mbox{m/s}^2
+ \f}
+\endverbatim
+ which results in:
+ \f{eqnarray*}
+ g &=& \frac{Gm_2}{r^2} \\
+ &=& \frac{(6.673 \times 10^{-11}\,\mbox{m}^3\,\mbox{kg}^{-1}\,
+ \mbox{s}^{-2})(5.9736 \times 10^{24}\,\mbox{kg})}{(6371.01\,\mbox{km})^2} \\
+ &=& 9.82066032\,\mbox{m/s}^2
+ \f}
+</ol>
+For the first two commands one should make sure formulas contain
+valid commands in \LaTeX's math-mode. For the third command
+the section should contain valid command for the specific environment.
+
+\warning Currently, doxygen is not very fault tolerant in recovering
+from typos in formulas. It may be necessary to remove the
+file <code>formula.repository</code> that is written to the html directory to
+get rid of an incorrect formula.
+
+\htmlonly
+Go to the <a href="diagrams.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/grouping.doc b/doc/grouping.doc
new file mode 100644
index 0000000..4397b76
--- /dev/null
+++ b/doc/grouping.doc
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page grouping Grouping
+
+Doxygen has three mechanisms to group things together.
+One mechanism works at a global level, creating a new page
+for each group. These groups are called \ref modules "'modules'" in the documentation.
+The second mechanism works within a member list of some compound entity,
+and is referred to as a \ref memgroup "'member groups'".
+For \ref cmdpage "pages" there is a third grouping mechanism referred to
+as \ref subpaging "subpaging".
+
+\section modules Modules
+
+Modules are a way to group things together on a separate page. You
+can document a group as a whole, as well as all individual members.
+Members of a group can be files, namespaces, classes, functions,
+variables, enums, typedefs, and defines, but also other groups.
+
+To define a group, you should put the \ref cmddefgroup "\\defgroup"
+command in a special comment block. The first argument of the command
+is a label that should uniquely identify the group.
+The second argument is the name or title of the group as it should appear
+in the documentation.
+
+You can make an entity a member of a specific group by putting
+a \ref cmdingroup "\\ingroup" command inside its documentation block.
+
+To avoid putting \ref cmdingroup "\\ingroup" commands in the documentation
+for each member you can also group members together by the
+open marker <code>\@{</code> before the group and the
+closing marker <code>\@}</code> after the group. The markers can
+be put in the documentation of the group definition or in a separate
+documentation block.
+
+Groups themselves can also be nested using these grouping markers.
+
+You will get an error message when you use the same group label more than once.
+If you don't want doxygen to enforce unique labels, then you can
+use \ref cmdaddtogroup "\\addtogroup" instead of
+\ref cmddefgroup "\\defgroup".
+It can be used exactly like \ref cmddefgroup "\\defgroup",
+but when the group has been defined already, then it silently merges the
+existing documentation with the new one.
+The title of the group is optional for this command, so you can use
+\verbatim
+/** \addtogroup <label>
+ * @{
+ */
+...
+
+/** @}*/
+\endverbatim
+to add additional members to a group that is defined in more detail elsewhere.
+
+Note that compound entities (like classes, files and namespaces) can
+be put into multiple groups, but members (like variable, functions, typedefs
+and enums) can only be a member of one group
+(this restriction is in place to avoid ambiguous linking targets in case
+a member is not documented in the context of its class, namespace
+or file, but only visible as part of a group).
+
+Doxygen will put members into the group whose definition has
+the highest "priority": e.g. An explicit \ref cmdingroup "\\ingroup" overrides
+an implicit grouping definition via <code>\@{</code> <code>\@}</code>.
+Conflicting grouping definitions with the same priority trigger a warning,
+unless one definition was for a member without any explicit documentation.
+
+The following example puts VarInA into group A and silently resolves
+the conflict for IntegerVariable by putting it into group IntVariables,
+because the second instance of IntegerVariable
+is undocumented:
+
+\verbatim
+
+/**
+ * \ingroup A
+ */
+extern int VarInA;
+
+/**
+ * \defgroup IntVariables Global integer variables
+ * @{
+ */
+
+/** an integer variable */
+extern int IntegerVariable;
+
+/**@}*/
+
+....
+
+/**
+ * \defgroup Variables Global variables
+ */
+/**@{*/
+
+/** a variable in group A */
+int VarInA;
+
+int IntegerVariable;
+
+/**@}*/
+\endverbatim
+
+The \ref cmdref "\\ref" command can be used to refer to a group.
+The first argument of the \\ref command should be group's label.
+To use a custom link name, you can put the name of the links in
+double quotes after the label, as shown by the following example
+\verbatim
+This is the \ref group_label "link" to this group.
+\endverbatim
+
+The priorities of grouping definitions are (from highest to lowest):
+\ref cmdingroup "\\ingroup", \ref cmddefgroup "\\defgroup",
+\ref cmdaddtogroup "\\addtogroup", \ref cmdweakgroup "\\weakgroup".
+The last command is exactly like \ref cmdaddtogroup "\\addtogroup"
+with a lower priority. It was added to allow "lazy" grouping
+definitions: you can use commands with a higher priority in your .h
+files to define the hierarchy and \ref cmdweakgroup "\\weakgroup"
+in .c files without having to duplicate the hierarchy exactly.
+
+\par Example:
+\verbinclude group.cpp
+
+\htmlonly
+Click <a href="$(DOXYGEN_DOCDIR)/examples/group/html/modules.html">here</a>
+for the corresponding HTML documentation that is generated by Doxygen.
+\endhtmlonly
+
+\section memgroup Member Groups
+
+If a compound (e.g. a class or file) has many members, it is often
+desired to group them together. Doxygen already automatically groups
+things together on type and protection level, but maybe you feel that
+this is not enough or that that default grouping is wrong.
+For instance, because you feel that members of different (syntactic)
+types belong to the same (semantic) group.
+
+A member group is defined by
+a
+\verbatim
+///@{
+ ...
+///@}
+\endverbatim
+block or a
+\verbatim
+/**@{*/
+ ...
+/**@}*/
+\endverbatim
+block if you prefer C style
+comments. Note that the members of the group should be
+physically inside the member group's body.
+
+Before the opening marker of a block a separate comment block may be
+placed. This block should contain the \ref cmdname "@@name"
+(or \ref cmdname "\\name") command and is used to specify the header
+of the group. Optionally, the comment block may also contain more
+detailed information about the group.
+
+Nesting of member groups is not allowed.
+
+If all members of a member group inside a class have the same type
+and protection level (for instance all are static public members),
+then the whole member group is displayed as a subgroup of
+the type/protection level group (the group is displayed as a
+subsection of the "Static Public Members" section for instance).
+If two or more members have different types, then the group is put
+at the same level as the automatically generated groups.
+If you want to force all member-groups of a class to be at the top level,
+you should put a \ref cmdnosubgrouping "\\nosubgrouping" command inside the
+documentation of the class.
+
+\par Example:
+\verbinclude memgrp.cpp
+
+\htmlonly
+Click <a href="$(DOXYGEN_DOCDIR)/examples/memgrp/html/class_test.html">here</a>
+for the corresponding HTML documentation that is generated by Doxygen.
+\endhtmlonly
+
+Here Group1 is displayed as a subsection of the "Public Members". And
+Group2 is a separate section because it contains members with
+different protection levels (i.e. public and protected).
+
+\section subpaging Subpaging
+
+Information can be grouped into pages using the \ref cmdpage "\\page" and
+\ref cmdsubpage "\\mainpage" commands. Normally, this results in a
+flat list of pages, where the "main" page is the first in the list.
+
+Instead of adding structure using the approach described in section
+\ref modules "modules" it is often more natural and convenient to add
+additional structure to the pages using the \ref cmdsubpage "\\subpage"
+command.
+
+For a page A the \\subpage command adds a link to another page B and at
+the same time makes page B a subpage of A. This has the effect of making
+two groups GA and GB, where GB is part of GA, page A is put in group GA,
+and page B is put in group GB.
+
+\htmlonly
+Go to the <a href="formulas.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/htmlcmds.doc b/doc/htmlcmds.doc
new file mode 100644
index 0000000..d041f1e
--- /dev/null
+++ b/doc/htmlcmds.doc
@@ -0,0 +1,389 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page htmlcmds HTML Commands
+
+Here is a list of all HTML commands that may be used inside the
+documentation. Note that although these HTML tags are translated to the
+proper commands for output formats other than HTML, all attributes
+of a HTML tag are passed on to the HTML output only
+(the \c HREF and \c NAME attributes for the \c A tag are the only exception).
+
+<ul>
+<li><tt>\<A HREF="..."\></tt> Starts a hyperlink
+ (if supported by the output format).
+<li><tt>\<A NAME="..."\></tt> Starts a named anchor
+ (if supported by the output format).
+<li><tt>\</A\></tt> Ends a link or anchor
+<li><tt>\<B\></tt> Starts a piece of text displayed in a bold font.
+<li><tt>\</B\></tt> Ends a <tt>\<B\></tt> section.
+<li><tt>\<BLOCKQUOTE\></tt> Starts a quotation block.
+<li><tt>\</BLOCKQUOTE\></tt> Ends the quotation block.
+<li><tt>\<BR\></tt> Forces a line break.
+<li><tt>\<CENTER\></tt> starts a section of centered text.
+<li><tt>\</CENTER\></tt> ends a section of centered text.
+<li><tt>\<CAPTION\></tt> Starts a caption. Use within a table only.
+<li><tt>\</CAPTION\></tt> Ends a caption. Use within a table only.
+<li><tt>\<CODE\></tt> Starts a piece of text displayed in a typewriter font.
+ Note that only for C# code, this command is equivalent to
+ \ref cmdcode "\\code".
+<li><tt>\</CODE\></tt> Ends a <tt>\<CODE\></tt> section.
+ Note that only for C# code, this command is equivalent to
+ \ref cmdendcode "\\endcode".
+<li><tt>\<DD\></tt> Starts an item description.
+<li><tt>\</DD\></tt> Ends an item description.
+<li><tt>\<DFN\></tt> Starts a piece of text displayed in a typewriter font.
+<li><tt>\</DFN\></tt> Ends a <tt>\<DFN\></tt> section.
+<li><tt>\<DIV></tt> Starts a section with a specific style (HTML only)
+<li><tt>\</DIV></tt> Ends a section with a specific style (HTML only)
+<li><tt>\<DL\></tt> Starts a description list.
+<li><tt>\</DL\></tt> Ends a description list.
+<li><tt>\<DT\></tt> Starts an item title.
+<li><tt>\</DT\></tt> Ends an item title.
+<li><tt>\<EM\></tt> Starts a piece of text displayed in an italic font.
+<li><tt>\</EM\></tt> Ends a <tt>\<EM\></tt> section.
+<li><tt>\<HR\></tt> Writes a horizontal ruler.
+<li><tt>\<H1\></tt> Starts an unnumbered section.
+<li><tt>\</H1\></tt> Ends an unnumbered section.
+<li><tt>\<H2\></tt> Starts an unnumbered subsection.
+<li><tt>\</H2\></tt> Ends an unnumbered subsection.
+<li><tt>\<H3\></tt> Starts an unnumbered subsubsection.
+<li><tt>\</H3\></tt> Ends an unnumbered subsubsection.
+<li><tt>\<H4\></tt> Starts an unnumbered subsubsection.
+<li><tt>\</H4\></tt> Ends an unnumbered subsubsection.
+<li><tt>\<H5\></tt> Starts an unnumbered subsubsection.
+<li><tt>\</H5\></tt> Ends an unnumbered subsubsection.
+<li><tt>\<H6\></tt> Starts an unnumbered subsubsection.
+<li><tt>\</H6\></tt> Ends an unnumbered subsubsection.
+<li><tt>\<I\></tt> Starts a piece of text displayed in an italic font.
+<li><tt>\</I\></tt> Ends a <tt>\<I\></tt> section.
+<li><tt>\<IMG SRC="..." ...\></tt> This command is written with its attributes to the HTML output only. The SRC attribute is mandatory.
+<li><tt>\<LI\></tt> Starts a new list item.
+<li><tt>\</LI\></tt> Ends a list item.
+<li><tt>\<OL\></tt> Starts a numbered item list.
+<li><tt>\</OL\></tt> Ends a numbered item list.
+<li><tt>\<P\></tt> Starts a new paragraph.
+<li><tt>\</P\></tt> Ends a paragraph.
+<li><tt>\<PRE\></tt> Starts a preformatted fragment.
+<li><tt>\</PRE\></tt> Ends a preformatted fragment.
+<li><tt>\<SMALL\></tt> Starts a section of text displayed in a smaller font.
+<li><tt>\</SMALL\></tt> Ends a <tt>\<SMALL\></tt> section.
+<li><tt>\<SPAN></tt> Starts an inline text fragment with a specific style (HTML only)
+<li><tt>\</SPAN></tt> Ends an inline text fragment with a specific style (HTML only)
+<li><tt>\<STRONG\></tt> Starts a section of bold text.
+<li><tt>\</STRONG\></tt> Ends a section of bold text.
+<li><tt>\<SUB\></tt> Starts a piece of text displayed in subscript.
+<li><tt>\</SUB\></tt> Ends a <tt>\<SUB\></tt> section.
+<li><tt>\<SUP\></tt> Starts a piece of text displayed in superscript.
+<li><tt>\</SUP\></tt> Ends a <tt>\<SUP\></tt> section.
+<li><tt>\<TABLE\></tt> starts a table.
+<li><tt>\</TABLE\></tt> ends a table.
+<li><tt>\<TD\></tt> Starts a new table data element.
+<li><tt>\</TD\></tt> Ends a table data element.
+<li><tt>\<TH\></tt> Starts a new table header.
+<li><tt>\</TH\></tt> Ends a table header.
+<li><tt>\<TR\></tt> Starts a new table row.
+<li><tt>\</TR\></tt> Ends a table row.
+<li><tt>\<TT\></tt> Starts a piece of text displayed in a typewriter font.
+<li><tt>\</TT\></tt> Ends a <tt>\<TT\></tt> section.
+<li><tt>\<KBD\></tt> Starts a piece of text displayed in a typewriter font.
+<li><tt>\</KBD\></tt> Ends a <tt>\<KBD\></tt> section.
+<li><tt>\<UL\></tt> Starts an unnumbered item list.
+<li><tt>\</UL\></tt> Ends an unnumbered item list.
+<li><tt>\<VAR\></tt> Starts a piece of text displayed in an italic font.
+<li><tt>\</VAR\></tt> Ends a <tt>\<VAR\></tt> section.
+</ul>
+
+The special HTML4 character entities.<br>
+The list of entities with their descriptions has been taken from <a href="http://www.w3.org/TR/html4/sgml/entities.html">Character entity references in HTML 4</a>.
+( Portions © International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.)
+<ul>
+<li><tt>\ </tt>` ` no-break space = non-breaking space:
+<li><tt>\¡</tt>` ` inverted exclamation mark: ¡
+<li><tt>\¢</tt>` ` cent sign: ¢
+<li><tt>\£</tt>` ` pound sign: £
+<li><tt>\¤</tt>` ` currency sign: ¤
+<li><tt>\¥</tt>` ` yen sign = yuan sign: ¥
+<li><tt>\¦</tt>` ` broken bar = broken vertical bar: ¦
+<li><tt>\§</tt>` ` section sign: §
+<li><tt>\¨</tt>` ` diaeresis = spacing diaeresis: ¨
+<li><tt>\©</tt>` ` copyright sign: ©
+<li><tt>\ª</tt>` ` feminine ordinal indicator: ª
+<li><tt>\«</tt>` ` left-pointing double angle quotation mark = left pointing guillemet: «
+<li><tt>\¬</tt>` ` not sign: ¬
+<li><tt>\</tt>` ` soft hyphen = discretionary hyphen:
+<li><tt>\®</tt>` ` registered sign = registered trade mark sign: ®
+<li><tt>\¯</tt>` ` macron = spacing macron = overline = APL overbar: ¯
+<li><tt>\°</tt>` ` degree sign: °
+<li><tt>\±</tt>` ` plus-minus sign = plus-or-minus sign: ±
+<li><tt>\²</tt>` ` superscript two = superscript digit two = squared: ²
+<li><tt>\³</tt>` ` superscript three = superscript digit three = cubed: ³
+<li><tt>\´</tt>` ` acute accent = spacing acute: ´
+<li><tt>\µ</tt>` ` micro sign: µ
+<li><tt>\¶</tt>` ` pilcrow sign = paragraph sign: ¶
+<li><tt>\·</tt>` ` middle dot = Georgian comma = Greek middle dot: ·
+<li><tt>\¸</tt>` ` cedilla = spacing cedilla: ¸
+<li><tt>\¹</tt>` ` superscript one = superscript digit one: ¹
+<li><tt>\º</tt>` ` masculine ordinal indicator: º
+<li><tt>\»</tt>` ` right-pointing double angle quotation mark = right pointing guillemet: »
+<li><tt>\¼</tt>` ` vulgar fraction one quarter = fraction one quarter: ¼
+<li><tt>\½</tt>` ` vulgar fraction one half = fraction one half: ½
+<li><tt>\¾</tt>` ` vulgar fraction three quarters = fraction three quarters: ¾
+<li><tt>\¿</tt>` ` inverted question mark = turned question mark: ¿
+<li><tt>\À</tt>` ` latin capital letter A with grave = latin capital letter A grave: À
+<li><tt>\Á</tt>` ` latin capital letter A with acute: Á
+<li><tt>\Â</tt>` ` latin capital letter A with circumflex: Â
+<li><tt>\Ã</tt>` ` latin capital letter A with tilde: Ã
+<li><tt>\Ä</tt>` ` latin capital letter A with diaeresis: Ä
+<li><tt>\Å</tt>` ` latin capital letter A with ring above = latin capital letter A ring: Å
+<li><tt>\Æ</tt>` ` latin capital letter AE = latin capital ligature AE: Æ
+<li><tt>\Ç</tt>` ` latin capital letter C with cedilla: Ç
+<li><tt>\È</tt>` ` latin capital letter E with grave: È
+<li><tt>\É</tt>` ` latin capital letter E with acute: É
+<li><tt>\Ê</tt>` ` latin capital letter E with circumflex: Ê
+<li><tt>\Ë</tt>` ` latin capital letter E with diaeresis: Ë
+<li><tt>\Ì</tt>` ` latin capital letter I with grave: Ì
+<li><tt>\Í</tt>` ` latin capital letter I with acute: Í
+<li><tt>\Î</tt>` ` latin capital letter I with circumflex: Î
+<li><tt>\Ï</tt>` ` latin capital letter I with diaeresis: Ï
+<li><tt>\Ð</tt>` ` latin capital letter ETH: Ð
+<li><tt>\Ñ</tt>` ` latin capital letter N with tilde: Ñ
+<li><tt>\Ò</tt>` ` latin capital letter O with grave: Ò
+<li><tt>\Ó</tt>` ` latin capital letter O with acute: Ó
+<li><tt>\Ô</tt>` ` latin capital letter O with circumflex: Ô
+<li><tt>\Õ</tt>` ` latin capital letter O with tilde: Õ
+<li><tt>\Ö</tt>` ` latin capital letter O with diaeresis: Ö
+<li><tt>\×</tt>` ` multiplication sign: ×
+<li><tt>\Ø</tt>` ` latin capital letter O with stroke = latin capital letter O slash: Ø
+<li><tt>\Ù</tt>` ` latin capital letter U with grave: Ù
+<li><tt>\Ú</tt>` ` latin capital letter U with acute: Ú
+<li><tt>\Û</tt>` ` latin capital letter U with circumflex: Û
+<li><tt>\Ü</tt>` ` latin capital letter U with diaeresis: Ü
+<li><tt>\Ý</tt>` ` latin capital letter Y with acute: Ý
+<li><tt>\Þ</tt>` ` latin capital letter THORN: Þ
+<li><tt>\ß</tt>` ` latin small letter sharp s = ess-zed: ß
+<li><tt>\à</tt>` ` latin small letter a with grave = latin small letter a grave: à
+<li><tt>\á</tt>` ` latin small letter a with acute: á
+<li><tt>\â</tt>` ` latin small letter a with circumflex: â
+<li><tt>\ã</tt>` ` latin small letter a with tilde: ã
+<li><tt>\ä</tt>` ` latin small letter a with diaeresis: ä
+<li><tt>\å</tt>` ` latin small letter a with ring above = latin small letter a ring: å
+<li><tt>\æ</tt>` ` latin small letter ae = latin small ligature ae: æ
+<li><tt>\ç</tt>` ` latin small letter c with cedilla: ç
+<li><tt>\è</tt>` ` latin small letter e with grave: è
+<li><tt>\é</tt>` ` latin small letter e with acute: é
+<li><tt>\ê</tt>` ` latin small letter e with circumflex: ê
+<li><tt>\ë</tt>` ` latin small letter e with diaeresis: ë
+<li><tt>\ì</tt>` ` latin small letter i with grave: ì
+<li><tt>\í</tt>` ` latin small letter i with acute: í
+<li><tt>\î</tt>` ` latin small letter i with circumflex: î
+<li><tt>\ï</tt>` ` latin small letter i with diaeresis: ï
+<li><tt>\ð</tt>` ` latin small letter eth: ð
+<li><tt>\ñ</tt>` ` latin small letter n with tilde: ñ
+<li><tt>\ò</tt>` ` latin small letter o with grave: ò
+<li><tt>\ó</tt>` ` latin small letter o with acute: ó
+<li><tt>\ô</tt>` ` latin small letter o with circumflex: ô
+<li><tt>\õ</tt>` ` latin small letter o with tilde: õ
+<li><tt>\ö</tt>` ` latin small letter o with diaeresis: ö
+<li><tt>\÷</tt>` ` division sign: ÷
+<li><tt>\ø</tt>` ` latin small letter o with stroke, = latin small letter o slash: ø
+<li><tt>\ù</tt>` ` latin small letter u with grave: ù
+<li><tt>\ú</tt>` ` latin small letter u with acute: ú
+<li><tt>\û</tt>` ` latin small letter u with circumflex: û
+<li><tt>\ü</tt>` ` latin small letter u with diaeresis: ü
+<li><tt>\ý</tt>` ` latin small letter y with acute: ý
+<li><tt>\þ</tt>` ` latin small letter thorn: þ
+<li><tt>\ÿ</tt>` ` latin small letter y with diaeresis: ÿ
+<li><tt>\ƒ</tt>` ` latin small f with hook = function = florin: ƒ
+<li><tt>\Α</tt>` ` greek capital letter alpha: Α
+<li><tt>\Β</tt>` ` greek capital letter beta: Β
+<li><tt>\Γ</tt>` ` greek capital letter gamma: Γ
+<li><tt>\Δ</tt>` ` greek capital letter delta: Δ
+<li><tt>\Ε</tt>` ` greek capital letter epsilon: Ε
+<li><tt>\Ζ</tt>` ` greek capital letter zeta: Ζ
+<li><tt>\Η</tt>` ` greek capital letter eta: Η
+<li><tt>\Θ</tt>` ` greek capital letter theta: Θ
+<li><tt>\Ι</tt>` ` greek capital letter iota: Ι
+<li><tt>\Κ</tt>` ` greek capital letter kappa: Κ
+<li><tt>\Λ</tt>` ` greek capital letter lambda: Λ
+<li><tt>\Μ</tt>` ` greek capital letter mu: Μ
+<li><tt>\Ν</tt>` ` greek capital letter nu: Ν
+<li><tt>\Ξ</tt>` ` greek capital letter xi: Ξ
+<li><tt>\Ο</tt>` ` greek capital letter omicron: Ο
+<li><tt>\Π</tt>` ` greek capital letter pi: Π
+<li><tt>\Ρ</tt>` ` greek capital letter rho: Ρ
+<li><tt>\Σ</tt>` ` greek capital letter sigma: Σ
+<li><tt>\Τ</tt>` ` greek capital letter tau: Τ
+<li><tt>\Υ</tt>` ` greek capital letter upsilon: Υ
+<li><tt>\Φ</tt>` ` greek capital letter phi: Φ
+<li><tt>\Χ</tt>` ` greek capital letter chi: Χ
+<li><tt>\Ψ</tt>` ` greek capital letter psi: Ψ
+<li><tt>\Ω</tt>` ` greek capital letter omega: Ω
+<li><tt>\α</tt>` ` greek small letter alpha: α
+<li><tt>\β</tt>` ` greek small letter beta: β
+<li><tt>\γ</tt>` ` greek small letter gamma: γ
+<li><tt>\δ</tt>` ` greek small letter delta: δ
+<li><tt>\ε</tt>` ` greek small letter epsilon: ε
+<li><tt>\ζ</tt>` ` greek small letter zeta: ζ
+<li><tt>\η</tt>` ` greek small letter eta: η
+<li><tt>\θ</tt>` ` greek small letter theta: θ
+<li><tt>\ι</tt>` ` greek small letter iota: ι
+<li><tt>\κ</tt>` ` greek small letter kappa: κ
+<li><tt>\λ</tt>` ` greek small letter lambda: λ
+<li><tt>\μ</tt>` ` greek small letter mu: μ
+<li><tt>\ν</tt>` ` greek small letter nu: ν
+<li><tt>\ξ</tt>` ` greek small letter xi: ξ
+<li><tt>\ο</tt>` ` greek small letter omicron: ο
+<li><tt>\π</tt>` ` greek small letter pi: π
+<li><tt>\ρ</tt>` ` greek small letter rho: ρ
+<li><tt>\ς</tt>` ` greek small letter final sigma: ς
+<li><tt>\σ</tt>` ` greek small letter sigma: σ
+<li><tt>\τ</tt>` ` greek small letter tau: τ
+<li><tt>\υ</tt>` ` greek small letter upsilon: υ
+<li><tt>\φ</tt>` ` greek small letter phi: φ
+<li><tt>\χ</tt>` ` greek small letter chi: χ
+<li><tt>\ψ</tt>` ` greek small letter psi: ψ
+<li><tt>\ω</tt>` ` greek small letter omega: ω
+<li><tt>\ϑ</tt> greek small letter theta symbol: ϑ
+<li><tt>\ϒ</tt>` ` greek upsilon with hook symbol: ϒ
+<li><tt>\ϖ</tt>` ` greek pi symbol: ϖ
+<li><tt>\•</tt>` ` bullet = black small circle: •
+<li><tt>\…</tt>` ` horizontal ellipsis = three dot leader: …
+<li><tt>\′</tt>` ` prime = minutes = feet: ′
+<li><tt>\″</tt>` ` double prime = seconds = inches: ″
+<li><tt>\‾</tt>` ` overline = spacing overscore: ‾
+<li><tt>\⁄</tt>` ` fraction slash: ⁄
+<li><tt>\℘</tt>` ` script capital P = power set = Weierstrass p: ℘
+<li><tt>\ℑ</tt>` ` blackletter capital I = imaginary part: ℑ
+<li><tt>\ℜ</tt>` ` blackletter capital R = real part symbol: ℜ
+<li><tt>\™</tt>` ` trade mark sign: ™
+<li><tt>\ℵ</tt>` ` alef symbol = first transfinite cardinal: ℵ
+<li><tt>\←</tt>` ` leftwards arrow: ←
+<li><tt>\↑</tt>` ` upwards arrow: ↑
+<li><tt>\→</tt>` ` rightwards arrow: →
+<li><tt>\↓</tt>` ` downwards arrow: ↓
+<li><tt>\↔</tt>` ` left right arrow: ↔
+<li><tt>\↵</tt>` ` downwards arrow with corner leftwards = carriage return: ↵
+<li><tt>\⇐</tt>` ` leftwards double arrow: ⇐
+<li><tt>\⇑</tt>` ` upwards double arrow: ⇑
+<li><tt>\⇒</tt>` ` rightwards double arrow: ⇒
+<li><tt>\⇓</tt>` ` downwards double arrow: ⇓
+<li><tt>\⇔</tt>` ` left right double arrow: ⇔
+<li><tt>\∀</tt>` ` for all: ∀
+<li><tt>\∂</tt>` ` partial differential: ∂
+<li><tt>\∃</tt>` ` there exists: ∃
+<li><tt>\∅</tt>` ` empty set = null set = diameter: ∅
+<li><tt>\∇</tt>` ` nabla = backward difference: ∇
+<li><tt>\∈</tt>` ` element of: ∈
+<li><tt>\∉</tt>` ` not an element of: ∉
+<li><tt>\∋</tt>` ` contains as member: ∋
+<li><tt>\∏</tt>` ` n-ary product = product sign: ∏
+<li><tt>\∑</tt>` ` n-ary sumation: ∑
+<li><tt>\−</tt>` ` minus sign: −
+<li><tt>\∗</tt>` ` asterisk operator: ∗
+<li><tt>\√</tt>` ` square root = radical sign: √
+<li><tt>\∝</tt>` ` proportional to: ∝
+<li><tt>\∞</tt>` ` infinity: ∞
+<li><tt>\∠</tt>` ` angle: ∠
+<li><tt>\∧</tt>` ` logical and = wedge: ∧
+<li><tt>\∨</tt>` ` logical or = vee: ∨
+<li><tt>\∩</tt>` ` intersection = cap: ∩
+<li><tt>\∪</tt>` ` union = cup: ∪
+<li><tt>\∫</tt>` ` integral: ∫
+<li><tt>\∴</tt>` ` therefore: ∴
+<li><tt>\∼</tt>` ` tilde operator = varies with = similar to: ∼
+<li><tt>\≅</tt>` ` approximately equal to: ≅
+<li><tt>\≈</tt>` ` almost equal to = asymptotic to: ≈
+<li><tt>\≠</tt>` ` not equal to: ≠
+<li><tt>\≡</tt>` ` identical to: ≡
+<li><tt>\≤</tt>` ` less-than or equal to: ≤
+<li><tt>\≥</tt>` ` greater-than or equal to: ≥
+<li><tt>\⊂</tt>` ` subset of: ⊂
+<li><tt>\⊃</tt>` ` superset of: ⊃
+<li><tt>\⊄</tt>` ` not a subset of: ⊄
+<li><tt>\⊆</tt>` ` subset of or equal to: ⊆
+<li><tt>\⊇</tt>` ` superset of or equal to: ⊇
+<li><tt>\⊕</tt>` ` circled plus = direct sum: ⊕
+<li><tt>\⊗</tt>` ` circled times = vector product: ⊗
+<li><tt>\⊥</tt>` ` up tack = orthogonal to = perpendicular: ⊥
+<li><tt>\⋅</tt>` ` dot operator: ⋅
+<li><tt>\⌈</tt>` ` left ceiling = apl upstile: ⌈
+<li><tt>\⌉</tt>` ` right ceiling: ⌉
+<li><tt>\⌊</tt>` ` left floor = apl downstile: ⌊
+<li><tt>\⌋</tt>` ` right floor: ⌋
+<li><tt>\〈</tt>` ` left-pointing angle bracket = bra: 〈
+<li><tt>\〉</tt>` ` right-pointing angle bracket = ket: 〉
+<li><tt>\◊</tt>` ` lozenge: ◊
+<li><tt>\♠</tt>` ` black spade suit: ♠
+<li><tt>\♣</tt>` ` black club suit = shamrock: ♣
+<li><tt>\♥</tt>` ` black heart suit = valentine: ♥
+<li><tt>\♦</tt>` ` black diamond suit: ♦
+<li><tt>\"</tt>` ` quotation mark = APL quote: "
+<li><tt>\&</tt>` ` ampersand: &
+<li><tt>\<</tt>` ` less-than sign: <
+<li><tt>\></tt>` ` greater-than sign: >
+<li><tt>\Œ</tt>` ` latin capital ligature OE: Œ
+<li><tt>\œ</tt>` ` latin small ligature oe: œ
+<li><tt>\Š</tt>` ` latin capital letter S with caron: Š
+<li><tt>\š</tt>` ` latin small letter s with caron: š
+<li><tt>\Ÿ</tt>` ` latin capital letter Y with diaeresis: Ÿ
+<li><tt>\ˆ</tt>` ` modifier letter circumflex accent: ˆ
+<li><tt>\˜</tt>` ` small tilde: ˜
+<li><tt>\ </tt>` ` en space:
+<li><tt>\ </tt>` ` em space:
+<li><tt>\ </tt>` ` thin space:
+<li><tt>\</tt>` ` zero width non-joiner:
+<li><tt>\</tt>` ` zero width joiner:
+<li><tt>\</tt>` ` left-to-right mark:
+<li><tt>\</tt>` ` right-to-left mark:
+<li><tt>\–</tt>` ` en dash: –
+<li><tt>\—</tt>` ` em dash: —
+<li><tt>\‘</tt>` ` left single quotation mark: ‘
+<li><tt>\’</tt>` ` right single quotation mark: ’
+<li><tt>\‚</tt>` ` single low-9 quotation mark: ‚
+<li><tt>\“</tt>` ` left double quotation mark: “
+<li><tt>\”</tt>` ` right double quotation mark: ”
+<li><tt>\„</tt>` ` double low-9 quotation mark: „
+<li><tt>\†</tt>` ` dagger: †
+<li><tt>\‡</tt>` ` double dagger: ‡
+<li><tt>\‰</tt>` ` per mille sign: ‰
+<li><tt>\‹</tt>` ` single left-pointing angle quotation mark: ‹
+<li><tt>\›</tt>` ` single right-pointing angle quotation mark: ›
+<li><tt>\€</tt>` ` euro sign: €
+</ul>
+Doxygen extensions:
+<ul>
+<li><tt>\&tm;</tt>` ` trade mark sign: &tm;
+<li><tt>\'</tt>` ` apostrophe: '
+</ul>
+
+Finally, to put invisible comments inside comment blocks, HTML style
+comments can be used:
+\verbatim
+/*! <!-- This is a comment with a comment block --> Visible text */
+\endverbatim
+
+
+\htmlonly
+<br/>
+Go to the <a href="xmlcmds.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/index.doc b/doc/index.doc
new file mode 100644
index 0000000..0cb1e59
--- /dev/null
+++ b/doc/index.doc
@@ -0,0 +1,193 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*!
+\mainpage
+<!--Doxygen Manual-->
+\if logo_on
+<center>
+\htmlonly
+<img src="doxygen_logo.gif" width="634" height="197" alt="doxygen"/><br/>
+Version: $(VERSION)
+\endhtmlonly
+</center>
+\endif
+
+<h2>Introduction</h2>
+Doxygen is the de facto standard tool for generating documentation from
+annotated C++ sources, but it also supports other popular programming
+languages such as C, Objective-C, C#, PHP, Java, Python, IDL
+(Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL, Tcl, and to some extent D.
+
+Doxygen can help you in three ways:
+<ol>
+<li> It can generate an on-line documentation browser (in HTML) and/or an
+ off-line reference manual (in \LaTeX) from a set
+ of documented source files.
+ There is also support for generating output in RTF (MS-Word),
+ PostScript, hyperlinked PDF, compressed HTML, and Unix man pages.
+ The documentation is extracted directly from the sources, which
+ makes it much easier to keep the documentation consistent with the
+ source code.
+<li> You can \ref extract_all "configure" doxygen to extract the code structure
+ from undocumented source files. This is very useful to quickly
+ find your way in large source distributions.
+ Doxygen can also visualize the relations between the various elements
+ by means of include dependency graphs, inheritance diagrams,
+ and collaboration diagrams, which are all generated automatically.
+<li> You can also use doxygen for creating normal documentation (as I did
+ for the doxygen user manual and web-site).
+</ol>
+
+Doxygen is developed under Mac OS X and Linux, but is set-up to be highly
+portable. As a result, it runs on most other Unix flavors as well.
+Furthermore, executables for Windows are available.
+
+\n
+This manual is divided into three parts, each of which is divided into several sections.
+
+The first part forms a user manual:
+<ul>
+<li>Section \ref install discusses how to
+ <a href="http://www.doxygen.org/download.html">download</a>, compile and install
+ doxygen for your platform.
+<li>Section \ref starting tells you how to generate your first piece of
+ documentation quickly.
+<li>Section \ref docblocks demonstrates the various ways that code can
+ be documented.
+<li>Section \ref markdown show the Markdown formatting supported by doxygen.
+<li>Section \ref lists shows how to create lists.
+<li>Section \ref grouping shows how to group things together.
+<li>Section \ref formulas shows how to insert formulas in the documentation.
+<li>Section \ref diagrams describes the diagrams and graphs that doxygen can generate.
+<li>Section \ref preprocessing explains how doxygen deals with macro definitions.
+<li>Section \ref autolink shows how to put links to files, classes,
+ and members in the documentation.
+<li>Section \ref output shows how to generate the various output formats
+ supported by doxygen.
+<li>Section \ref searching shows various ways to search in the HTML documentation.
+<li>Section \ref extsearch shows how use the external search and index tools
+<li>Section \ref customize explains how you can customize the output generated
+ by doxygen.
+<li>Section \ref custcmd show how to define and use custom commands in your comments.
+<li>Section \ref external explains how to let doxygen create links to externally generated documentation.
+<li>Section \ref faq gives answers to frequently asked questions.
+<li>Section \ref trouble tells you what to do when you have problems.
+</ul>
+
+The second part forms a reference manual:
+
+<ul>
+<li>Section \ref features presents an overview of what doxygen can do.
+<li>Section \ref doxygen_usage shows how to use the \c doxygen program.
+<li>Section \ref doxywizard_usage shows how to use the \c doxywizard program.
+<li>Section \ref config shows how to fine-tune doxygen, so it
+ generates the documentation you want.
+<li>Section \ref commands shows an overview of the special commands that can be
+ used within the documentation.
+<li>Section \ref htmlcmds shows an overview of the HTML commands that
+ can be used within the documentation.
+<li>Section \ref xmlcmds shows an overview of the C# style XML commands that
+ can be used within the documentation.
+</ul>
+
+The third part provides information for developers:
+
+<ul>
+<li>Section \ref arch gives a global overview of how doxygen is internally
+ structured.
+<li>Section \ref perlmod shows how to use the PerlMod output.
+<li>Section \ref langhowto explains how to add support for new
+ output languages.
+</ul>
+
+\n<h2>Doxygen license</h2>
+\addindex license
+\addindex GPL
+
+Copyright © 1997-2014 by
+<a href="mailto:dimitri at stack.nl">Dimitri van Heesch</a>.<p>
+
+Permission to use, copy, modify, and distribute this software and its
+documentation under the terms of the GNU General Public License is hereby
+granted. No representations are made about the suitability of this software
+for any purpose. It is provided "as is" without express or implied warranty.
+See the
+<a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">
+GNU General Public License</a>
+for more details.
+<p>
+Documents produced by doxygen are derivative works derived from the
+input used in their production; they are not affected by this license.
+
+<h2>User examples</h2>
+
+Doxygen supports a number of \ref output "output formats" where HTML is the
+most popular one. I've gathered
+<a href="http://www.doxygen.org/results.html">some nice examples</a>
+of real-life projects using doxygen.
+
+These are part of a larger
+<a href="http://www.doxygen.org/projects.html">list of projects</a>
+that use doxygen.
+If you know other projects, let <a href="mailto:dimitri at stack.nl?subject=New%20project%20using%20Doxygen">me</a>
+know and I'll add them.
+
+<h2>Future work</h2>
+Although doxygen is successfully used by large number of companies and
+open source projects already, there is always room for improvement.
+<p>
+You can submit enhancement requests in
+<a href="https://bugzilla.gnome.org/buglist.cgi?product=doxygen&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=enhancement">the bug tracker</a>.
+Make sure the severity of the bug report is set to "enhancement".
+
+<h2>Acknowledgments</h2>
+\addindex acknowledgments
+Thanks go to:
+<ul>
+<li>\addindex Doc++
+ Malte Zöckler and Roland Wunderling, authors of DOC++.
+ The first version of doxygen borrowed some code of an old version of DOC++.
+ Although I have rewritten practically all code since then, DOC++ has still
+ given me a good start in writing doxygen.
+<li>All people at Qt Software, for creating a beautiful GUI Toolkit
+ (which is very useful as a Windows/Unix platform abstraction layer :-)
+<li>My brother Frank
+ for rendering the logos.
+<li>Harm van der Heijden for adding HTML help support.
+<li>Wouter Slegers of
+ <a href="http://www.yourcreativesolutions.nl">Your Creative Solutions</a>
+ for registering the www.doxygen.org domain.
+<li>Parker Waechter for adding the RTF output generator.
+<li>Joerg Baumann, for adding conditional documentation blocks,
+ PDF links, and the configuration generator.
+<li>Tim Mensch for adding the todo command.
+<li>Christian Hammond for redesigning the web-site.
+<li>Ken Wong for providing the HTML tree view code.
+<li>Talin for adding support for C# style comments with XML markup.
+<li>Petr Prikryl for coordinating the internationalization support.
+ All language maintainers for providing translations into many languages.
+<li>The band <a href="http://www.porcupinetree.com">Porcupine Tree</a> for
+ providing hours of great music to listen to while coding.
+<li>many, many others for suggestions, patches and bug reports.
+</ul>
+
+\htmlonly
+Go to the <a href="install.html">next</a> section.
+\endhtmlonly
+
+*/
+
diff --git a/doc/index.hhp.txt b/doc/index.hhp.txt
new file mode 100644
index 0000000..b676d83
--- /dev/null
+++ b/doc/index.hhp.txt
@@ -0,0 +1,108 @@
+examples/afterdoc/html/tab_a.png
+examples/afterdoc/html/tab_b.png
+examples/afterdoc/html/tab_h.png
+examples/afterdoc/html/tab_s.png
+examples/author/html/tab_a.png
+examples/author/html/tab_b.png
+examples/author/html/tab_h.png
+examples/author/html/tab_s.png
+examples/autolink/html/tab_a.png
+examples/autolink/html/tab_b.png
+examples/autolink/html/tab_h.png
+examples/autolink/html/tab_s.png
+examples/class/html/tab_a.png
+examples/class/html/tab_b.png
+examples/class/html/tab_h.png
+examples/class/html/tab_s.png
+examples/define/html/tab_a.png
+examples/define/html/tab_b.png
+examples/define/html/tab_h.png
+examples/define/html/tab_s.png
+examples/diagrams/html/tab_a.png
+examples/diagrams/html/tab_b.png
+examples/diagrams/html/tab_h.png
+examples/diagrams/html/tab_s.png
+examples/docstring/html/tab_a.png
+examples/docstring/html/tab_b.png
+examples/docstring/html/tab_h.png
+examples/docstring/html/tab_s.png
+examples/enum/html/tab_a.png
+examples/enum/html/tab_b.png
+examples/enum/html/tab_h.png
+examples/enum/html/tab_s.png
+examples/example/html/tab_a.png
+examples/example/html/tab_b.png
+examples/example/html/tab_h.png
+examples/example/html/tab_s.png
+examples/file/html/tab_a.png
+examples/file/html/tab_b.png
+examples/file/html/tab_h.png
+examples/file/html/tab_s.png
+examples/func/html/tab_a.png
+examples/func/html/tab_b.png
+examples/func/html/tab_h.png
+examples/func/html/tab_s.png
+examples/group/html/tab_a.png
+examples/group/html/tab_b.png
+examples/group/html/tab_h.png
+examples/group/html/tab_s.png
+examples/include/html/tab_a.png
+examples/include/html/tab_b.png
+examples/include/html/tab_h.png
+examples/include/html/tab_s.png
+examples/jdstyle/html/tab_a.png
+examples/jdstyle/html/tab_b.png
+examples/jdstyle/html/tab_h.png
+examples/jdstyle/html/tab_s.png
+examples/manual/html/tab_a.png
+examples/manual/html/tab_b.png
+examples/manual/html/tab_h.png
+examples/manual/html/tab_s.png
+examples/memgrp/html/tab_a.png
+examples/memgrp/html/tab_b.png
+examples/memgrp/html/tab_h.png
+examples/memgrp/html/tab_s.png
+examples/mux/html/tab_a.png
+examples/mux/html/tab_b.png
+examples/mux/html/tab_h.png
+examples/mux/html/tab_s.png
+examples/overload/html/tab_a.png
+examples/overload/html/tab_b.png
+examples/overload/html/tab_h.png
+examples/overload/html/tab_s.png
+examples/page/html/tab_a.png
+examples/page/html/tab_b.png
+examples/page/html/tab_h.png
+examples/page/html/tab_s.png
+examples/par/html/tab_a.png
+examples/par/html/tab_b.png
+examples/par/html/tab_h.png
+examples/par/html/tab_s.png
+examples/pyexample/html/tab_a.png
+examples/pyexample/html/tab_b.png
+examples/pyexample/html/tab_h.png
+examples/pyexample/html/tab_s.png
+examples/qtstyle/html/tab_a.png
+examples/qtstyle/html/tab_b.png
+examples/qtstyle/html/tab_h.png
+examples/qtstyle/html/tab_s.png
+examples/relates/html/tab_a.png
+examples/relates/html/tab_b.png
+examples/relates/html/tab_h.png
+examples/relates/html/tab_s.png
+examples/restypedef/html/tab_a.png
+examples/restypedef/html/tab_b.png
+examples/restypedef/html/tab_h.png
+examples/restypedef/html/tab_s.png
+examples/structcmd/html/tab_a.png
+examples/structcmd/html/tab_b.png
+examples/structcmd/html/tab_h.png
+examples/structcmd/html/tab_s.png
+examples/tag/html/tab_a.png
+examples/tag/html/tab_b.png
+examples/tag/html/tab_h.png
+examples/tag/html/tab_s.png
+examples/template/html/tab_a.png
+examples/template/html/tab_b.png
+examples/template/html/tab_h.png
+examples/template/html/tab_s.png
diff --git a/doc/infoflow.eps b/doc/infoflow.eps
new file mode 100644
index 0000000..f11b1fc
--- /dev/null
+++ b/doc/infoflow.eps
@@ -0,0 +1,624 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: infoflow.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Thu Dec 29 10:46:41 2011
+%%For: dimitri at macbookpro (Dimitri van Heesch)
+%%BoundingBox: 0 0 661 582
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+/col32 {0.878 0.878 0.878 srgb} bind def
+/col33 {0.000 0.000 0.000 srgb} bind def
+
+end
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Times-Roman /Times-Roman-iso isovec ReEncode
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 582 moveto 0 0 lineto 661 0 lineto 661 582 lineto closepath clip newpath
+-53.3 599.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06000 0.06000 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+/Times-Roman-iso ff 200.00 scf sf
+8100 7200 m
+gs 1 -1 sc (import) col0 sh gr
+% Polyline
+0 slj
+0 slc
+7.500 slw
+n 975 3600 m 975 3300 l 2175 3300 l 2175 4800 l
+ 2100 4800 l gs col0 s gr
+% Polyline
+n 1050 3300 m 1050 3225 l 2250 3225 l 2250 4725 l
+ 2175 4725 l gs col0 s gr
+% Polyline
+n 1125 3225 m 1125 3150 l 2325 3150 l 2325 4650 l
+ 2250 4650 l gs col0 s gr
+% Polyline
+n 900 5700 m 1200 5400 l 2100 5400 l 2100 6900 l 900 6900 l 900 5700 l
+ 1200 5700 l
+ 1200 5400 l gs col0 s gr
+% Polyline
+n 975 5625 m 975 5325 l 2175 5325 l 2175 6825 l
+ 2100 6825 l gs col0 s gr
+% Polyline
+n 1050 5325 m 1050 5250 l 2250 5250 l 2250 6750 l
+ 2175 6750 l gs col0 s gr
+% Polyline
+n 1125 5250 m 1125 5175 l 2325 5175 l 2325 6675 l
+ 2250 6675 l gs col0 s gr
+/Times-Roman-iso ff 200.00 scf sf
+1275 6075 m
+gs 1 -1 sc (- headers) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+1275 6675 m
+gs 1 -1 sc (- images) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+1275 6375 m
+gs 1 -1 sc (- footers) col0 sh gr
+% Polyline
+n 6675 8775 m 6975 8475 l 7875 8475 l 7875 9975 l 6675 9975 l 6675 8775 l
+ 6975 8775 l
+ 6975 8475 l gs col0 s gr
+% Polyline
+n 6750 8700 m 6750 8400 l 7950 8400 l 7950 9900 l
+ 7875 9900 l gs col0 s gr
+% Polyline
+n 6825 8400 m 6825 8325 l 8025 8325 l 8025 9825 l
+ 7950 9825 l gs col0 s gr
+% Polyline
+n 6900 8325 m 6900 8250 l 8100 8250 l 8100 9750 l
+ 8025 9750 l gs col0 s gr
+% Polyline
+n 6600 4950 m 6900 4650 l 7800 4650 l 7800 6150 l 6600 6150 l 6600 4950 l
+ 6900 4950 l
+ 6900 4650 l gs col0 s gr
+% Polyline
+n 6675 4875 m 6675 4575 l 7875 4575 l 7875 6075 l
+ 7800 6075 l gs col0 s gr
+% Polyline
+n 6750 4575 m 6750 4500 l 7950 4500 l 7950 6000 l
+ 7875 6000 l gs col0 s gr
+% Polyline
+n 6825 4500 m 6825 4425 l 8025 4425 l 8025 5925 l
+ 7950 5925 l gs col0 s gr
+% Polyline
+n 6600 2925 m 6900 2625 l 7800 2625 l 7800 4125 l 6600 4125 l 6600 2925 l
+ 6900 2925 l
+ 6900 2625 l gs col0 s gr
+% Polyline
+n 6675 2850 m 6675 2550 l 7875 2550 l 7875 4050 l
+ 7800 4050 l gs col0 s gr
+% Polyline
+n 6750 2550 m 6750 2475 l 7950 2475 l 7950 3975 l
+ 7875 3975 l gs col0 s gr
+% Polyline
+n 6825 2475 m 6825 2400 l 8025 2400 l 8025 3900 l
+ 7950 3900 l gs col0 s gr
+% Polyline
+n 6600 900 m 6900 600 l 7800 600 l 7800 2100 l 6600 2100 l 6600 900 l
+ 6900 900 l
+ 6900 600 l gs col0 s gr
+% Polyline
+n 6675 825 m 6675 525 l 7875 525 l 7875 2025 l
+ 7800 2025 l gs col0 s gr
+% Polyline
+n 6750 525 m 6750 450 l 7950 450 l 7950 1950 l
+ 7875 1950 l gs col0 s gr
+% Polyline
+n 6825 450 m 6825 375 l 8025 375 l 8025 1875 l
+ 7950 1875 l gs col0 s gr
+% Polyline
+n 4350 1950 m 4650 1650 l 5550 1650 l 5550 3150 l 4350 3150 l 4350 1950 l
+ 4650 1950 l
+ 4650 1650 l gs col0 s gr
+/Times-Roman-iso ff 200.00 scf sf
+4575 2250 m
+gs 1 -1 sc (Config file) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+4575 2550 m
+gs 1 -1 sc (Doxyfile) col0 sh gr
+% Polyline
+n 2850 1950 m 3150 1650 l 4050 1650 l 4050 3150 l 2850 3150 l 2850 1950 l
+ 3150 1950 l
+ 3150 1650 l gs col0 s gr
+/Times-Roman-iso ff 200.00 scf sf
+3000 2475 m
+gs 1 -1 sc (Layout file) col0 sh gr
+% Polyline
+gs clippath
+3164 4155 m 3315 4155 l 3315 4095 l 3164 4095 l 3164 4095 l 3284 4125 l 3164 4155 l cp
+eoclip
+n 2100 4125 m
+ 3300 4125 l gs col0 s gr gr
+
+% arrowhead
+n 3164 4155 m 3284 4125 l 3164 4095 l 3164 4155 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+3164 4380 m 3315 4380 l 3315 4320 l 3164 4320 l 3164 4320 l 3284 4350 l 3164 4380 l cp
+eoclip
+n 2100 6225 m 2700 6225 l 2700 4350 l
+ 3300 4350 l gs col0 s gr gr
+
+% arrowhead
+n 3164 4380 m 3284 4350 l 3164 4320 l 3164 4380 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 3675 5925 m 3975 5625 l 4875 5625 l 4875 7125 l 3675 7125 l 3675 5925 l
+ 3975 5925 l
+ 3975 5625 l gs col0 s gr
+% Polyline
+gs clippath
+4155 4786 m 4155 4635 l 4095 4635 l 4095 4786 l 4095 4786 l 4125 4666 l 4155 4786 l cp
+eoclip
+n 4125 5625 m
+ 4125 4650 l gs col0 s gr gr
+
+% arrowhead
+n 4155 4786 m 4125 4666 l 4095 4786 l 4155 4786 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4320 5489 m 4320 5640 l 4380 5640 l 4380 5489 l 4380 5489 l 4350 5609 l 4320 5489 l cp
+eoclip
+n 4350 5625 m
+ 4350 4650 l gs col0 s gr gr
+
+% arrowhead
+n 4320 5489 m 4350 5609 l 4380 5489 l 4320 5489 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6464 1455 m 6615 1455 l 6615 1395 l 6464 1395 l 6464 1395 l 6584 1425 l 6464 1455 l cp
+eoclip
+n 5100 3900 m 6000 3900 l 6000 1425 l
+ 6600 1425 l gs col0 s gr gr
+
+% arrowhead
+n 6464 1455 m 6584 1425 l 6464 1395 l 6464 1455 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6464 3480 m 6615 3480 l 6615 3420 l 6464 3420 l 6464 3420 l 6584 3450 l 6464 3480 l cp
+eoclip
+n 5100 4050 m 6300 4050 l 6300 3450 l
+ 6600 3450 l gs col0 s gr gr
+
+% arrowhead
+n 6464 3480 m 6584 3450 l 6464 3420 l 6464 3480 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6464 5580 m 6615 5580 l 6615 5520 l 6464 5520 l 6464 5520 l 6584 5550 l 6464 5580 l cp
+eoclip
+n 5100 4200 m 6300 4200 l 6300 5550 l
+ 6600 5550 l gs col0 s gr gr
+
+% arrowhead
+n 6464 5580 m 6584 5550 l 6464 5520 l 6464 5580 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6539 7380 m 6690 7380 l 6690 7320 l 6539 7320 l 6539 7320 l 6659 7350 l 6539 7380 l cp
+eoclip
+n 5100 4350 m 6000 4350 l 6000 7350 l
+ 6675 7350 l gs col0 s gr gr
+
+% arrowhead
+n 6539 7380 m 6659 7350 l 6539 7320 l 6539 7380 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6539 9180 m 6690 9180 l 6690 9120 l 6539 9120 l 6539 9120 l 6659 9150 l 6539 9180 l cp
+eoclip
+n 5100 4500 m 5700 4500 l 5700 9150 l
+ 6675 9150 l gs col0 s gr gr
+
+% arrowhead
+n 6539 9180 m 6659 9150 l 6539 9120 l 6539 9180 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 6675 6675 m 6975 6375 l 7875 6375 l 7875 7875 l 6675 7875 l 6675 6675 l
+ 6975 6675 l
+ 6975 6375 l gs col0 s gr
+% Polyline
+n 3300 3750 m 5100 3750 l 5100 4650 l 3300 4650 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 8775 450 m 10800 450 l 10800 1575 l 8775 1575 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 9075 900 m 10650 900 l 10650 1425 l 9075 1425 l
+ cp gs col0 s gr
+% Polyline
+gs clippath
+8639 1380 m 8790 1380 l 8790 1320 l 8639 1320 l 8639 1320 l 8759 1350 l 8639 1380 l cp
+eoclip
+n 7800 1350 m
+ 8775 1350 l gs col0 s gr gr
+
+% arrowhead
+n 8639 1380 m 8759 1350 l 8639 1320 l 8639 1380 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11339 1380 m 11490 1380 l 11490 1320 l 11339 1320 l 11339 1320 l 11459 1350 l 11339 1380 l cp
+eoclip
+n 10800 1350 m
+ 11475 1350 l gs col0 s gr gr
+
+% arrowhead
+n 11339 1380 m 11459 1350 l 11339 1320 l 11339 1380 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8864 3180 m 9015 3180 l 9015 3120 l 8864 3120 l 8864 3120 l 8984 3150 l 8864 3180 l cp
+eoclip
+n 7800 3150 m
+ 9000 3150 l gs col0 s gr gr
+
+% arrowhead
+n 8864 3180 m 8984 3150 l 8864 3120 l 8864 3180 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8864 3555 m 9015 3555 l 9015 3495 l 8864 3495 l 8864 3495 l 8984 3525 l 8864 3555 l cp
+eoclip
+n 7800 3525 m
+ 9000 3525 l gs col0 s gr gr
+
+% arrowhead
+n 8864 3555 m 8984 3525 l 8864 3495 l 8864 3555 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 9000 2925 m 10800 2925 l 10800 3675 l 9000 3675 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+11339 3180 m 11490 3180 l 11490 3120 l 11339 3120 l 11339 3120 l 11459 3150 l 11339 3180 l cp
+eoclip
+n 10800 3150 m
+ 11475 3150 l gs col0 s gr gr
+
+% arrowhead
+n 11339 3180 m 11459 3150 l 11339 3120 l 11339 3180 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11339 3555 m 11490 3555 l 11490 3495 l 11339 3495 l 11339 3495 l 11459 3525 l 11339 3555 l cp
+eoclip
+n 10800 3525 m
+ 11475 3525 l gs col0 s gr gr
+
+% arrowhead
+n 11339 3555 m 11459 3525 l 11339 3495 l 11339 3555 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8864 7305 m 9015 7305 l 9015 7245 l 8864 7245 l 8864 7245 l 8984 7275 l 8864 7305 l cp
+eoclip
+n 7875 7275 m
+ 9000 7275 l gs col0 s gr gr
+
+% arrowhead
+n 8864 7305 m 8984 7275 l 8864 7245 l 8864 7305 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8864 9180 m 9015 9180 l 9015 9120 l 8864 9120 l 8864 9120 l 8984 9150 l 8864 9180 l cp
+eoclip
+n 7875 9150 m
+ 9000 9150 l gs col0 s gr gr
+
+% arrowhead
+n 8864 9180 m 8984 9150 l 8864 9120 l 8864 9180 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 8700 6450 m 11850 6450 l 11850 9975 l 8700 9975 l
+ cp gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+4845 1514 m 4845 1665 l 4905 1665 l 4905 1514 l 4905 1514 l 4875 1634 l 4845 1514 l cp
+4905 1186 m 4905 1035 l 4845 1035 l 4845 1186 l 4845 1186 l 4875 1066 l 4905 1186 l cp
+eoclip
+n 4875 1050 m
+ 4875 1650 l gs col0 s gr gr
+
+% arrowhead
+n 4905 1186 m 4875 1066 l 4845 1186 l 4905 1186 l cp gs 0.00 setgray ef gr col0 s
+% arrowhead
+n 4845 1514 m 4875 1634 l 4905 1514 l 4845 1514 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 4125 300 m 5925 300 l 5925 1050 l 4125 1050 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+4905 3286 m 4905 3135 l 4845 3135 l 4845 3286 l 4845 3286 l 4875 3166 l 4905 3286 l cp
+eoclip
+n 4875 3150 m
+ 4875 3750 l gs col0 s gr gr
+
+% arrowhead
+n 4905 3286 m 4875 3166 l 4845 3286 l 4905 3286 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4620 3614 m 4620 3765 l 4680 3765 l 4680 3614 l 4680 3614 l 4650 3734 l 4620 3614 l cp
+eoclip
+n 4650 3150 m
+ 4650 3750 l gs col0 s gr gr
+
+% arrowhead
+n 4620 3614 m 4650 3734 l 4680 3614 l 4620 3614 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+3720 3614 m 3720 3765 l 3780 3765 l 3780 3614 l 3780 3614 l 3750 3734 l 3720 3614 l cp
+eoclip
+n 3750 3150 m
+ 3750 3750 l gs col0 s gr gr
+
+% arrowhead
+n 3720 3614 m 3750 3734 l 3780 3614 l 3720 3614 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+3555 3286 m 3555 3135 l 3495 3135 l 3495 3286 l 3495 3286 l 3525 3166 l 3555 3286 l cp
+eoclip
+n 3525 3150 m
+ 3525 3750 l gs col0 s gr gr
+
+% arrowhead
+n 3555 3286 m 3525 3166 l 3495 3286 l 3555 3286 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 9000 8775 m 11175 8775 l 11175 9525 l 9000 9525 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+11639 7305 m 11790 7305 l 11790 7245 l 11639 7245 l 11639 7245 l 11759 7275 l 11639 7305 l cp
+eoclip
+n 11250 7275 m
+ 11775 7275 l gs col0 s gr gr
+
+% arrowhead
+n 11639 7305 m 11759 7275 l 11639 7245 l 11639 7305 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 9000 6900 m 11250 6900 l 11250 7650 l 9000 7650 l
+ cp gs col32 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+11564 9180 m 11715 9180 l 11715 9120 l 11564 9120 l 11564 9120 l 11684 9150 l 11564 9180 l cp
+eoclip
+n 11175 9150 m
+ 11700 9150 l gs col0 s gr gr
+
+% arrowhead
+n 11564 9180 m 11684 9150 l 11564 9120 l 11564 9180 l cp gs 0.00 setgray ef gr col0 s
+/Times-Roman-iso ff 200.00 scf sf
+2850 3975 m
+gs 1 -1 sc (read) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+2850 4650 m
+gs 1 -1 sc (read) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+4425 5175 m
+gs 1 -1 sc (generate) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+3675 5175 m
+gs 1 -1 sc (read) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+3900 4275 m
+gs 1 -1 sc (Doxygen) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+8175 3000 m
+gs 1 -1 sc (make ps) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+9675 3375 m
+gs 1 -1 sc (latex) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11025 825 m
+gs 1 -1 sc (custom) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11025 1050 m
+gs 1 -1 sc (output) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11025 3000 m
+gs 1 -1 sc (postscript) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11025 3825 m
+gs 1 -1 sc (PDF) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6975 9075 m
+gs 1 -1 sc (HTML) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6975 9300 m
+gs 1 -1 sc (pages) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+8775 6675 m
+gs 1 -1 sc (Windows only) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+8250 1200 m
+gs 1 -1 sc (read) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+1200 4200 m
+gs 1 -1 sc (Sources) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+1275 5775 m
+gs 1 -1 sc (Custom) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+3675 1350 m
+gs 1 -1 sc (generate/edit) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+4425 750 m
+gs 1 -1 sc (Doxywizard) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+4050 3525 m
+gs 1 -1 sc (read) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+5025 3375 m
+gs 1 -1 sc (generate) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+5025 3600 m
+gs 1 -1 sc (update) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+2625 3375 m
+gs 1 -1 sc (generate) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6825 1350 m
+gs 1 -1 sc (XML files) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6750 3300 m
+gs 1 -1 sc (Latex files) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6750 3750 m
+gs 1 -1 sc (Makefile) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+7125 3525 m
+gs 1 -1 sc (+) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6750 5625 m
+gs 1 -1 sc (Man pages) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+6900 7350 m
+gs 1 -1 sc (refman.rtf) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+9075 9225 m
+gs 1 -1 sc (HTML Help Workshop) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+8100 3750 m
+gs 1 -1 sc (make pdf) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+9225 1275 m
+gs 1 -1 sc (doxmlparser lib) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+9150 750 m
+gs 1 -1 sc (Your application) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+3900 6450 m
+gs 1 -1 sc (Tag file\(s\)) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11325 7125 m
+gs 1 -1 sc (doc) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+9750 7350 m
+gs 1 -1 sc (MS-Word) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+11325 9000 m
+gs 1 -1 sc (chm) col0 sh gr
+/Times-Roman-iso ff 200.00 scf sf
+8250 9075 m
+gs 1 -1 sc (read) col0 sh gr
+% Polyline
+n 900 3675 m 1200 3375 l 2100 3375 l 2100 4875 l 900 4875 l 900 3675 l
+ 1200 3675 l
+ 1200 3375 l gs col0 s gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+%EOF
diff --git a/doc/infoflow.fig b/doc/infoflow.fig
new file mode 100644
index 0000000..9db91af
--- /dev/null
+++ b/doc/infoflow.fig
@@ -0,0 +1,229 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+0 32 #e0e0e0
+0 33 #000000
+6 900 3150 2325 4875
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 900 3675 1200 3375 2100 3375 2100 4875 900 4875 900 3675
+ 1200 3675 1200 3375
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 975 3600 975 3300 2175 3300 2175 4800 2100 4800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1050 3300 1050 3225 2250 3225 2250 4725 2175 4725
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1125 3225 1125 3150 2325 3150 2325 4650 2250 4650
+-6
+6 900 5175 2325 6900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 900 5700 1200 5400 2100 5400 2100 6900 900 6900 900 5700
+ 1200 5700 1200 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 975 5625 975 5325 2175 5325 2175 6825 2100 6825
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1050 5325 1050 5250 2250 5250 2250 6750 2175 6750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1125 5250 1125 5175 2325 5175 2325 6675 2250 6675
+-6
+6 1275 5925 2025 6750
+4 0 0 50 0 0 12 0.0000 4 150 795 1275 6075 - headers\001
+4 0 0 50 0 0 12 0.0000 4 195 720 1275 6675 - images\001
+4 0 0 50 0 0 12 0.0000 4 150 705 1275 6375 - footers\001
+-6
+6 6675 8250 8100 9975
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 6675 8775 6975 8475 7875 8475 7875 9975 6675 9975 6675 8775
+ 6975 8775 6975 8475
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6750 8700 6750 8400 7950 8400 7950 9900 7875 9900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6825 8400 6825 8325 8025 8325 8025 9825 7950 9825
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6900 8325 6900 8250 8100 8250 8100 9750 8025 9750
+-6
+6 6600 4425 8025 6150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 6600 4950 6900 4650 7800 4650 7800 6150 6600 6150 6600 4950
+ 6900 4950 6900 4650
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6675 4875 6675 4575 7875 4575 7875 6075 7800 6075
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6750 4575 6750 4500 7950 4500 7950 6000 7875 6000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6825 4500 6825 4425 8025 4425 8025 5925 7950 5925
+-6
+6 6600 2400 8025 4125
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 6600 2925 6900 2625 7800 2625 7800 4125 6600 4125 6600 2925
+ 6900 2925 6900 2625
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6675 2850 6675 2550 7875 2550 7875 4050 7800 4050
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6750 2550 6750 2475 7950 2475 7950 3975 7875 3975
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6825 2475 6825 2400 8025 2400 8025 3900 7950 3900
+-6
+6 6600 375 8025 2100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 6600 900 6900 600 7800 600 7800 2100 6600 2100 6600 900
+ 6900 900 6900 600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6675 825 6675 525 7875 525 7875 2025 7800 2025
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6750 525 6750 450 7950 450 7950 1950 7875 1950
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6825 450 6825 375 8025 375 8025 1875 7950 1875
+-6
+6 4350 1650 5550 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 4350 1950 4650 1650 5550 1650 5550 3150 4350 3150 4350 1950
+ 4650 1950 4650 1650
+4 0 0 50 0 0 12 0.0000 4 195 870 4575 2250 Config file\001
+4 0 0 50 0 0 12 0.0000 4 195 720 4575 2550 Doxyfile\001
+-6
+6 2850 1650 4050 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 2850 1950 3150 1650 4050 1650 4050 3150 2850 3150 2850 1950
+ 3150 1950 3150 1650
+4 0 0 50 -1 0 12 0.0000 4 195 915 3000 2475 Layout file\001
+-6
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2100 4125 3300 4125
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 2100 6225 2700 6225 2700 4350 3300 4350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 3675 5925 3975 5625 4875 5625 4875 7125 3675 7125 3675 5925
+ 3975 5925 3975 5625
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4125 5625 4125 4650
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2
+ 1 1 1.00 60.00 120.00
+ 4350 5625 4350 4650
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 5100 3900 6000 3900 6000 1425 6600 1425
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 5100 4050 6300 4050 6300 3450 6600 3450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 5100 4200 6300 4200 6300 5550 6600 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 5100 4350 6000 4350 6000 7350 6675 7350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 5100 4500 5700 4500 5700 9150 6675 9150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 8
+ 6675 6675 6975 6375 7875 6375 7875 7875 6675 7875 6675 6675
+ 6975 6675 6975 6375
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 3300 3750 5100 3750 5100 4650 3300 4650 3300 3750
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 8775 450 10800 450 10800 1575 8775 1575 8775 450
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 9075 900 10650 900 10650 1425 9075 1425 9075 900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7800 1350 8775 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10800 1350 11475 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7800 3150 9000 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7800 3525 9000 3525
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 9000 2925 10800 2925 10800 3675 9000 3675 9000 2925
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10800 3150 11475 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10800 3525 11475 3525
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7875 7275 9000 7275
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7875 9150 9000 9150
+2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
+ 8700 6450 11850 6450 11850 9975 8700 9975 8700 6450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 4875 1050 4875 1650
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 4125 300 5925 300 5925 1050 4125 1050 4125 300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2
+ 1 1 1.00 60.00 120.00
+ 4875 3150 4875 3750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4650 3150 4650 3750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3750 3150 3750 3750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2
+ 1 1 1.00 60.00 120.00
+ 3525 3150 3525 3750
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 9000 8775 11175 8775 11175 9525 9000 9525 9000 8775
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11250 7275 11775 7275
+2 2 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
+ 9000 6900 11250 6900 11250 7650 9000 7650 9000 6900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11175 9150 11700 9150
+4 0 0 50 0 0 12 0.0000 4 150 390 2850 3975 read\001
+4 0 0 50 0 0 12 0.0000 4 150 390 2850 4650 read\001
+4 0 0 50 0 0 12 0.0000 4 165 765 4425 5175 generate\001
+4 0 0 50 0 0 12 0.0000 4 150 390 3675 5175 read\001
+4 0 0 50 0 0 12 0.0000 4 195 780 3900 4275 Doxygen\001
+4 0 0 50 0 0 12 0.0000 4 195 720 8175 3000 make ps\001
+4 0 0 50 0 0 12 0.0000 4 150 420 9675 3375 latex\001
+4 0 0 50 0 0 12 0.0000 4 120 630 11025 825 custom\001
+4 0 0 50 0 0 12 0.0000 4 165 540 11025 1050 output\001
+4 0 0 50 0 0 12 0.0000 4 195 840 11025 3000 postscript\001
+4 0 0 50 0 0 12 0.0000 4 150 390 11025 3825 PDF\001
+4 0 0 50 0 0 12 0.0000 4 150 615 6975 9075 HTML\001
+4 0 0 50 0 0 12 0.0000 4 150 510 6975 9300 pages\001
+4 0 0 50 0 0 12 0.0000 4 195 1215 8775 6675 Windows only\001
+4 0 0 50 0 0 12 0.0000 4 150 390 8250 1200 read\001
+4 0 0 50 0 0 12 0.0000 4 150 705 1200 4200 Sources\001
+4 0 0 50 0 0 12 0.0000 4 150 675 1275 5775 Custom\001
+4 0 0 50 0 0 12 0.0000 4 195 1140 3675 1350 generate/edit\001
+4 0 0 50 0 0 12 0.0000 4 195 1050 4425 750 Doxywizard\001
+4 0 0 50 0 0 12 0.0000 4 150 390 4050 3525 read\001
+4 0 0 50 0 0 12 0.0000 4 165 765 5025 3375 generate\001
+4 0 0 50 -1 0 12 0.0000 4 195 585 5025 3600 update\001
+4 0 0 50 0 0 12 0.0000 4 165 765 2625 3375 generate\001
+4 0 0 50 0 0 12 0.0000 4 150 870 6825 1350 XML files\001
+4 0 0 50 0 0 12 0.0000 4 150 900 6750 3300 Latex files\001
+4 0 0 50 0 0 12 0.0000 4 150 765 6750 3750 Makefile\001
+4 0 0 50 0 0 12 0.0000 4 105 120 7125 3525 +\001
+4 0 0 50 0 0 12 0.0000 4 195 960 6750 5625 Man pages\001
+4 0 0 50 0 0 12 0.0000 4 150 870 6900 7350 refman.rtf\001
+4 0 0 50 0 0 12 0.0000 4 195 1995 9075 9225 HTML Help Workshop\001
+4 0 0 50 0 0 12 0.0000 4 195 795 8100 3750 make pdf\001
+4 0 0 50 0 0 12 0.0000 4 195 1320 9225 1275 doxmlparser lib\001
+4 0 0 50 0 0 12 0.0000 4 195 1395 9150 750 Your application\001
+4 0 0 50 0 0 12 0.0000 4 195 885 3900 6450 Tag file(s)\001
+4 0 0 50 0 0 12 0.0000 4 150 315 11325 7125 doc\001
+4 0 0 50 0 0 12 0.0000 4 150 855 9750 7350 MS-Word\001
+4 0 0 50 0 0 12 0.0000 4 150 375 11325 9000 chm\001
+4 0 0 50 0 0 12 0.0000 4 150 390 8250 9075 read\001
+4 0 0 50 0 0 12 0.0000 4 195 555 8100 7200 import\001
diff --git a/doc/infoflow.png b/doc/infoflow.png
new file mode 100644
index 0000000..d975be1
Binary files /dev/null and b/doc/infoflow.png differ
diff --git a/doc/install.doc b/doc/install.doc
new file mode 100644
index 0000000..9648ade
--- /dev/null
+++ b/doc/install.doc
@@ -0,0 +1,569 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page install Installation
+
+\addindex installation
+\tableofcontents
+
+First go to the
+<a href="http://www.doxygen.org/download.html">download</a> page
+to get the latest distribution, if you have not downloaded doxygen already.
+
+\section install_src_unix Compiling from source on UNIX
+
+If you downloaded the source distribution, you need at least the
+following to build the executable:
+<ul>
+<li>The <a href="ftp://prep.ai.mit.edu/pub/gnu/">GNU</a> tools
+ \c flex, \c bison, \c libiconv and <code>GNU make</code>, and \c strip
+ \addindex flex
+ \addindex bison
+ \addindex libiconv
+ \addindex make
+ \addindex strip
+<li>In order to generate a \c Makefile for your platform, you need
+ <a href="http://www.perl.com/">perl</a>
+ \addindex perl
+<li>The configure script assume the availability of standard UNIX tools such
+ as <code>sed, date, find, uname, mv, cp, cat, echo, tr, cd</code> and \c rm.
+</ul>
+
+To take full advantage of doxygen's features the following additional
+tools should be installed.
+
+<ul>
+<li>Qt Software's GUI toolkit
+ <a href="http://qt-project.org/">Qt</A>
+ \addindex Qt
+ version 4.3 or higher (but currently, Qt 5.x is not supported).
+ This is needed to build the GUI front-end doxywizard.
+<li>A \LaTeX distribution: for instance
+ <a href="http://www.tug.org/interest.html#free">TeX Live</a>
+ This is needed for generating \LaTeX, Postscript, and PDF output.
+<li><a href="http://www.graphviz.org/">
+ the Graph visualization toolkit version 1.8.10 or higher</a>
+ Needed for the include dependency graphs,
+ the graphical inheritance graphs, and the collaboration graphs.
+ If you compile graphviz yourself, make sure you do include
+ freetype support (which requires the freetype library and header files),
+ otherwise the graphs will not render proper text labels.
+<li>For formulas or if you do not wish to use `pdflatex, the ghostscript interpreter
+ is needed. You can find it at
+ <a href="http://www.ghostscript.com/">www.ghostscript.com</a>.
+<li>In order to generate doxygen's own documentation, Python is needed, you
+ can find it at <a href="http://www.python.org">www.python.org</a>.
+</ul>
+
+Compilation is now done by performing the following steps:
+
+<ol>
+<li>Unpack the archive, unless you already have done that:
+
+ gunzip doxygen-$VERSION.src.tar.gz # uncompress the archive
+ tar xf doxygen-$VERSION.src.tar # unpack it
+
+<li>Run the configure script:
+
+ sh ./configure
+
+ The script tries to determine the platform you use, the make tool
+ (which \e must be GNU make) and the perl
+ interpreter. It will report what it finds.
+
+ To override the auto detected platform and compiler you can run
+ configure as follows:
+
+ configure --platform platform-type
+
+ See the <code>PLATFORMS</code> file for a list of possible platform
+ options.
+
+ If you have Qt-4.3 or higher installed and want to build the GUI
+ front-end, you should run the configure script with
+ the `--with-doxywizard` option:
+
+ configure --with-doxywizard
+
+ For an overview of other configuration options use
+
+ configure --help
+
+<li>Compile the program by running make:
+
+ make
+
+ The program should compile without problems and the binaries
+ (<code>doxygen</code> and optionally <code>doxywizard</code>)
+ should be available in the bin directory of the distribution.
+
+<li>Optional: Generate the user manual.
+
+ make docs
+
+ To let doxygen generate the HTML documentation.
+
+ The HTML directory of the distribution will now contain the html
+ documentation (just point a HTML browser to the file
+ <code>index.html</code> in the
+ html directory). You will need the <code>python</code> interpreter
+ for this.
+
+<li>Optional: Generate a PDF version of the manual
+ (you will need <code>pdflatex</code>, <code>makeindex</code>, and
+ <code>egrep</code> for this).
+
+ make pdf
+
+ The PDF manual <code>doxygen_manual.pdf</code> will be located
+ in the latex directory of the distribution. Just
+ view and print it via the acrobat reader.
+
+</ol>
+
+\section install_bin_unix Installing the binaries on UNIX
+
+After the compilation of the source code do a <code>make install</code>
+to install doxygen. If you downloaded the binary distribution for UNIX,
+type:
+
+ ./configure
+ make install
+
+Binaries are installed into the directory <code>\<prefix\>/bin</code>.
+Use <code>make install_docs</code> to install the
+documentation and examples into <code>\<docdir\>/doxygen</code>.
+
+<code>\<prefix\></code> defaults to <code>/usr/local</code> but can be changed with
+the `--prefix` option of the configure script.
+The default <code>\<docdir\></code> directory is
+<code>\<prefix\>/share/doc/packages</code> and can be changed with
+the `--docdir` option of the configure script.
+
+Alternatively, you can also copy the binaries from the <code>bin</code>
+directory manually to some <code>bin</code> directory in your search path.
+This is sufficient to use doxygen.
+
+\note You need the GNU install tool for this to work (it is part of
+the coreutils package). Other install tools may put the binaries in
+the wrong directory!
+
+If you have a RPM or DEP package, then please follow the
+standard installation procedure that is required for these packages.
+
+\section unix_problems Known compilation problems for UNIX
+
+<b>Qt problems</b>
+
+The Qt include files and libraries are not a subdirectory of the
+directory pointed to by <code>QTDIR</code> on some systems
+(for instance on Red Hat 6.0 includes are in <code>/usr/include/qt</code> and
+libs are in <code>/usr/lib</code>).
+
+The solution: go to the root of the doxygen distribution and do:
+
+ mkdir qt
+ cd qt
+ ln -s your-qt-include-dir-here include
+ ln -s your-qt-lib-dir-here lib
+ ln -s your-qt-bin-dir-here bin
+ export QTDIR=$PWD
+
+If you have a <code>csh</code>-like shell you should use <code>setenv QTDIR \$PWD</code>
+instead of the <code>export</code> command above.
+
+Now install doxygen as described above.
+
+<b>Bison problems</b>
+
+Versions 1.31 to 1.34 of \c bison contain a "bug" that results in a
+compiler errors like this:
+
+<code>ce_parse.cpp:348: member `class CPPValue yyalloc::yyvs' with </code>
+constructor not allowed in union
+
+This problem has been solved in version 1.35 (versions before 1.31
+will also work).
+
+<b>Sun compiler problems</b>
+
+It appears that doxygen doesn't work properly if it is compiled
+with Sun's C++ WorkShop Compiler. I cannot verify this myself as I do
+not have access to a Solaris machine with this compiler. With GNU compiler
+it does work and installing Sun patch 111679-13 has also been reported
+as a way to fix the problem.
+
+when configuring with `--static` I got:
+
+\verbatim
+Undefined first referenced
+ symbol in file
+dlclose /usr/lib/libc.a(nss_deffinder.o)
+dlsym /usr/lib/libc.a(nss_deffinder.o)
+dlopen /usr/lib/libc.a(nss_deffinder.o)
+\endverbatim
+
+Manually adding `-Bdynamic` after the target rule in
+`Makefile.doxygen` will fix this:
+
+ $(TARGET): $(OBJECTS) $(OBJMOC)
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) -Bdynamic
+
+<b>GCC compiler problems</b>
+
+Older versions of the GNU compiler have problems with constant strings
+containing characters with character codes larger than 127. Therefore
+the compiler will fail to compile some of the `translator_xx.h` files.
+A workaround, if you are planning to use the English translation only,
+is to configure doxygen with the `--english-only` option.
+
+On some platforms (such as OpenBSD) using some versions of gcc with
+-O2 can lead to eating all memory during the compilation of files
+such as config.cpp. As a workaround use `--debug` as a configure option
+or omit the `-O2` for the particular files in the Makefile.
+
+Gcc versions before 2.95 may produce broken binaries due to bugs in
+these compilers.
+
+<b>Dot problems</b>
+
+Due to a change in the way image maps are generated, older versions
+of doxygen (\<=1.2.17) will not work correctly with newer versions of
+graphviz (\>=1.8.8). The effect of this incompatibility is that
+generated graphs in HTML are not properly clickable. For doxygen 1.3
+it is recommended to use at least graphviz 1.8.10 or higher.
+For doxygen 1.4.7 or higher it is recommended to
+use GraphViz 2.8 or higher to avoid font issues.
+
+<b>Red Hat 9.0 problems</b>
+
+If you get the following error after running make
+\verbatim
+tmake error: qtools.pro:70: Syntax error
+\endverbatim
+then first type
+\verbatim
+export LANG=
+\endverbatim
+before running make.
+
+\section install_src_windows Compiling from source on Windows
+
+From version 1.7.0 onwards, build files are provided for Visual Studio 2008.
+Also the free (as in beer) "Express" version of Developer Studio can be used to
+compile doxygen. Alternatively, you can compile doxygen
+\ref install_src_unix "the UNIX way" using
+<a href="http://en.wikipedia.org/wiki/Cygwin">Cygwin</a>
+or <a href="http://www.mingw.org/">MinGW</a>.
+
+The next step is to install modern versions of \c bison and \c flex
+(see http://sourceforge.net/projects/winflexbison. After installation and adding them to
+your `path` rename `win_flex.exe` to `flex.exe` and `win_bison.exe` to `bison.exe`)
+Furthermore you have to install \c python (version 2.6 or higher, see http://www.python.org).
+These packages are needed during the
+compilation process if you use a GitHub snapshot of doxygen (the official source releases
+come with pre-generated sources).
+
+Download doxygen's source tarball and put it somewhere (e.g. use <code>c:\\tools</code>)
+
+Now start a new command shell and type
+\verbatim
+cd c:\tools
+tar zxvf doxygen-x.y.z.src.tar.gz
+\endverbatim
+to unpack the sources (you can obtain \c tar from e.g. http://gnuwin32.sourceforge.net/packages.html).
+Alternatively you can use an unpack program, like 7-Zip (see http://www.7-zip.org)
+or use the build in unpack feature of modern Windows systems).
+
+Now your environment is setup to build \c doxygen.
+
+Inside the \c doxygen-x.y.z directory you will find a \c winbuild directory
+containing a \c Doxygen.sln file. Open this file in Visual Studio.
+You can now build the Release or Debug flavor of Doxygen by right-clicking
+the project in the solutions explorer, and selecting Build.
+
+Note that compiling Doxywizard currently requires Qt version 4
+(see http://qt-project.org/).
+
+Also read the next section for additional tools you may need to install to run
+doxygen with certain features enabled.
+
+<!--
+
+Currently, I have only compiled doxygen for Windows using Microsoft's
+Visual C++ (). For other compilers you may need to edit the
+perl script in <code>wintools/make.pl</code> a bit.
+Let me know what you had to change if you got Doxygen working with another
+compiler. If you have Visual Studio you can also use the .dsw file found in
+the <code>wintools</code> directory. Note that this file is not maintained
+by me, so it might be outdated a little.
+
+If you have Visual C++ 6.0, and the source distribution, you can easily
+build doxygen using the project files in the \c wintools directory. If
+you want to build the CVS sources, or want to build from the command line,
+or with another compiler, you have to follow the steps below.
+
+Thomas Baust reported that if you have Visual Studio.NET (2003) then
+you should be aware that there is a problem with the _popen() and _pclose()
+implementation, which currently leaks handles, so if you build doxygen with
+it and use the INPUT_FILTER, you will run to risk of crashing Windows!
+The problem is reported to and confirmed by Microsoft so maybe it will
+fixed in the next service pack.
+
+Since Windows comes without all the nice tools that UNIX users are
+used to, you'll need to install a number of these tools before you can compile
+doxygen for Windows from the command-line.
+
+Here is what is required:
+<ul>
+<li>An unzip/untar tool like WinZip to unpack the tar source distribution.
+ This can be found at http://www.winzip.com/
+
+ The good, tested, and free alternative is the <code>tar</code> utility
+ supplied with <a href="http://sourceware.cygnus.com/cygwin/">cygwin
+ tools</a>. Anyway, the Cygwin's \c flex, \c bison, and \c sed are also
+ recommended below.
+
+<li>Microsoft Visual C++ (I only tested with version 6.0).
+ Use the <code>vcvars32.bat</code> batch file to set the environment
+ variables (if you did not select to do this automatically during
+ installation).
+
+ Borland C++ or MINGW (see http://www.mingw.org/) are also supported.
+
+<li>Perl 5.0 or higher for Windows. This can be downloaded from:
+ http://www.ActiveState.com/Products/ActivePerl/
+
+<li>The GNU tools \c flex, \c bison, and \c sed.
+ To get these working on Windows you should install the
+ <a href="http://sources.redhat.com/cygwin/">cygwin tools</a>
+
+ Alternatively, you can also choose to
+ download only a <a href="http://www.doxygen.org/dl/cygwin_tools.zip">small subset</a>
+ of the cygwin tools that I put together just to compile doxygen.
+
+ As a third alternative one could use the GNUWin32 tools that can be
+ found at http://gnuwin32.sourceforge.net/
+
+ Make sure the <code>BISON_SIMPLE</code> environment variable points to the
+ location where the files <code>bison.simple</code> and
+ is located. For instance if these file is in
+ <code>c:\\tools\\cygwin\\usr\\share</code> then BISON_SIMPLE should
+ be set to <code>c:/tools/cygwin/usr/share/bison.simple</code>
+
+ Also make sure the tools are available from a dos box, by adding
+ the directory they are in to the search path.
+
+ For those of you who are very new to cygwin (if you are going to
+ install it from scratch), you should notice that there is an
+ archive file <code>bootstrap.zip</code> which also contains the
+ <code>tar</code> utility (<code>tar.exe</code>), <code>gzip</code>
+ utilities, and the <code>cygwin1.dll</code> core. This also means
+ that you have the <code>tar</code> in hands from the start. It
+ can be used to unpack the tar source distribution instead of
+ using WinZip -- as mentioned at the beginning of this list of
+ steps.
+
+<li>From Doxygen-1.2.2-20001015 onwards, the distribution includes the part
+ of Qt that is needed for to compile doxygen.
+ The Windows specific part were also created.
+ As a result doxygen (without the wizard) can be compiled on systems
+ without X11 or (the commercial version of) Qt.
+
+<li>If you used WinZip to extract the tar archive it will (apparently) not
+ create empty folders, so you have to add the folders
+ <code>objects</code> and <code>bin</code> manually in the root of the
+ distribution before compiling.
+
+</ul>
+
+
+Compilation is now done by performing the following steps:
+
+<ol>
+<li>Open a dos box.
+ Make sure all tools (i.e. <code>nmake</code>, <code>latex</code>,
+ <code>gswin32</code>, <code>dvips</code>, <code>sed</code>,
+ <code>flex</code>, <code>bison</code>, <code>cl</code>,
+ <code>rm</code>, and <code>perl</code>), are accessible from
+ the command-line (add them to the PATH environment variable if
+ needed).
+
+ Notice: The use of \LaTeX is optional and only needed for compilation
+ of the documentation into PostScript or PDF.
+ It is \e not needed for compiling the doxygen's binaries.
+
+<li>Go to the doxygen root dir and type:
+
+\verbatim
+ make.bat msvc
+\endverbatim
+
+ This should build the executable
+ <code>doxygen.exe</code> using Microsoft's Visual C++ compiler
+ (The compiler should not produce any serious warnings or errors).
+
+ You can use also the <code>bcc</code> argument to build
+ executables using the Borland C++ compiler, or
+ <code>mingw</code> argument to compile using GNU gcc.
+
+<li>To build the examples, go to the <code>examples</code> subdirectory
+ and type:
+
+\verbatim
+ nmake
+\endverbatim
+
+<li>To generate the doxygen documentation, go to the <code>doc</code>
+ subdirectory and type:
+
+\verbatim
+ nmake
+\endverbatim
+
+ The generated HTML docs are located in the <code>..\\html</code>
+ subdirectory.
+
+ The sources for \LaTeX documentation are located in the <code>..\\latex</code>
+ subdirectory. From those sources, the DVI, PostScript, and PDF
+ documentation can be generated.
+</ol>
+
+-->
+
+\section install_bin_windows Installing the binaries on Windows
+
+Doxygen comes as a self-installing archive, so installation is extremely simple.
+Just follow the dialogs.
+
+After installation it is recommended to also download and install GraphViz
+(version 2.20 or better is highly recommended). Doxygen can use the \c dot tool
+of the GraphViz package to render nicer diagrams, see the
+\ref cfg_have_dot "HAVE_DOT" option in the configuration file.
+
+If you want to produce compressed HTML files (see \ref
+cfg_generate_htmlhelp "GENERATE_HTMLHELP") in the config file, then
+you need the Microsoft HTML help workshop.
+You can download it from
+<a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138">Microsoft</a>.
+
+If you want to produce Qt Compressed Help files (see \ref
+cfg_qhg_location "QHG_LOCATION") in the config file, then
+you need qhelpgenerator which is part of Qt.
+You can download Qt from <a href="http://qt-project.org/downloads">Qt Software Downloads</a>.
+
+In order to generate PDF output or use scientific formulas you will also need to
+install <a href="http://en.wikipedia.org/wiki/LaTeX">LaTeX</a> and
+<a href="http://en.wikipedia.org/wiki/Ghostscript">Ghostscript</a>.
+
+For \LaTeX a number of distributions exists. Popular ones that should work with
+doxygen are <a href="http://www.miktex.org">MikTex</a>
+and <a href="http://www.tug.org/protext/">proTeXt</a>.
+
+Ghostscript can be <a href="http://sourceforge.net/projects/ghostscript/">downloaded</a>
+from Sourceforge.
+
+After installing \LaTeX and Ghostscript you'll need to make sure the tools
+latex.exe, pdflatex.exe, and gswin32c.exe are present in the search path of a
+command box. Follow <a href="http://www.computerhope.com/issues/ch000549.htm">these</a>
+instructions if you are unsure and run the commands from a command box to verify it works.
+
+<!--
+There is no fancy installation procedure at the moment (if anyone can
+add it in a location independent way please let me know).
+
+To install doxygen, just copy the binaries from the <code>bin</code> directory
+to a location somewhere in the path. Alternatively, you can include
+the <code>bin</code> directory of the distribution to the path.
+
+There are a couple of tools you may want to install to use all of doxygen's
+features:
+
+<ul>
+<li>To generate \LaTeX documentation or formulas in HTML you need the tools:
+ <code>latex</code>, <code>dvips</code> and <code>gswin32</code>.
+ To get these working under Windows
+ install the fpTeX distribution. You can find more info at:
+ http://www.fptex.org/ and download it from CTAN or one of its mirrors.
+ In the Netherlands for example this would be:
+ ftp://ftp.easynet.nl/mirror/CTAN/systems/win32/fptex/
+
+ Make sure the tools are available from a dos box, by adding the
+ directory they are in to the search path.
+
+ For your information, \LaTeX is a freely available set of so
+ called macros and styles on the top of the famous \TeX program
+ (by famous Donald Knuth) and the accompanied utilities (all
+ available for free). It is used for high quality
+ typesetting. The result -- in the form of so called
+ <code>DVI</code> (DeVice Independent) file -- can be printed or
+ displayed on various devices preserving exactly the same look up
+ to the capability of the device. The <code>dvips</code> allows you
+ to convert the <code>dvi</code> to the high quality PostScript
+ (i.e. PostScript that can be processed by utilities like
+ <code>psnup</code>, <code>psbook</code>, <code>psselect</code>,
+ and others). The derived version of \TeX (the pdfTeX) can be used
+ to produce PDF output instead of DVI, or the PDF can be produced
+ from PostScript using the utility <code>ps2pdf</code>.
+
+ If you want to use MikTeX then you need to select at least the
+ medium size installation. For really old versions of MikTex or minimal
+ installations, you may need to download the fancyhdr package separately.
+ You can find it in the
+ <a href="ftp://ftp.tex.ac.uk/tex-archive/macros/latex/contrib/supported/fancyhdr/">
+ contrib/supported</a> directory of the tex archives.
+
+<li>If you want to generate compressed HTML help
+ (see \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP") in the
+ config file, then you need the Microsoft HTML help workshop.
+ You can download it from
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/vsconHH1Start.asp">Microsoft</a>.
+
+<li>If you want to produce Qt Compressed Help files (see \ref
+ cfg_qhelgenerator_loc "QHG_LOCATION") in the config file,
+ then you need qhelpgenerator which is part of Qt.
+ You can download Qt from
+ <a href="http://qt-project.org/downloads">Qt Software Downloads</a>.
+
+<li><a href="http://www.graphviz.org/">
+ the Graph visualization toolkit version 1.8.10</a><br>
+ Needed for the include dependency graphs, the graphical inheritance graphs,
+ and the collaboration graphs.
+</ul>
+
+-->
+
+\section build_tools Tools used to develop doxygen
+
+Doxygen was developed and tested under Linux & MacOSX using the following
+open-source tools:
+<ul>
+<li>GCC version 4.6.3 (Linux) and 4.2.1 (MacOSX)
+<li>GNU flex version 2.5.35
+<li>GNU bison version 2.5 (Linux) and 2.3 (MacOSX)
+<li>GNU make version 3.81
+<li>Perl version 5.12
+<li>Python version 2.7 and 3.4
+<li>TeX Live 2009 (or later)
+</ul>
+
+\htmlonly
+Go to the <a href="starting.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/install_prefix b/doc/install_prefix
new file mode 100644
index 0000000..681eca9
--- /dev/null
+++ b/doc/install_prefix
@@ -0,0 +1,2 @@
+VERSION = $(VERSION)
+
diff --git a/doc/language.doc b/doc/language.doc
new file mode 100644
index 0000000..bc94f23
--- /dev/null
+++ b/doc/language.doc
@@ -0,0 +1,773 @@
+/******************************************************************************
+ * Do not edit this file. It was generated by the translator.py script. * Instead edit language.tpl and maintainers.txt
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page langhowto Internationalization
+
+<h3>Support for multiple languages</h3>
+
+Doxygen has built-in support for multiple languages. This means that the
+text fragments, generated by doxygen, can be produced in languages other
+than English (the default). The output language is chosen through the
+configuration option \ref cfg_output_language "OUTPUT_LANGUAGE" in the
+configuration file (with default name and known as Doxyfile).
+
+Currently (version 1.8.7), 40 languages
+are supported (sorted alphabetically):
+Afrikaans, Arabic, Armenian, Brazilian Portuguese, Catalan, Chinese,
+Chinese Traditional, Croatian, Czech, Danish, Dutch, English,
+Esperanto, Finnish, French, German, Greek, Hungarian, Indonesian,
+Italian, Japanese (+En), Korean (+En), Latvian, Lithuanian,
+Macedonian, Norwegian, Persian, Polish, Portuguese, Romanian, Russian,
+Serbian, SerbianCyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+Ukrainian, and Vietnamese..
+
+The table of information related to the supported languages follows.
+It is sorted by language alphabetically. The <b>Status</b> column
+was generated from sources and shows approximately the last version
+when the translator was updated.
+
+\htmlonly
+<table align="center" cellspacing="0" cellpadding="0" border="0">
+<tr bgcolor="#000000">
+<td>
+ <table cellspacing="1" cellpadding="2" border="0">
+ <tr bgcolor="#4040c0">
+ <td ><b><font size="+1" color="#ffffff"> Language </font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Maintainer </font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Contact address </font>
+ <font size="-2" color="#ffffff">(replace the at and dot)</font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Status </font></b></td>
+ </tr>
+ <!-- table content begin -->
+
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Afrikaans</td>
+ <td>Johan Prinsloo</td>
+ <td>johan at zippysnoek dot com</td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ff5555">Arabic</td>
+ <td>Moaz Reyad<br/>Muhammad Bashir Al-Noimi</td>
+ <td><span style="color: brown">[resigned]</span><br/>mbnoimi at gmail dot com</td>
+ <td bgcolor="#ff5555">1.4.6</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Armenian</td>
+ <td>Armen Tangamyan</td>
+ <td>armen dot tangamyan at anu dot edu dot au</td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Brazilian Portuguese</td>
+ <td>Fabio "FJTC" Jun Takada Chino</td>
+ <td>jun-chino at uol dot com dot br</td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Catalan</td>
+ <td>Maximiliano Pin<br/>Albert Mora</td>
+ <td>max dot pin at bitroit dot com<br/><span style="color: brown">[unreachable]</span></td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Chinese</td>
+ <td>Lian Yang<br/>Li Daobing<br/>Wei Liu</td>
+ <td>lian dot yang dot cn at gmail dot com<br/>lidaobing at gmail dot com<br/>liuwei at asiainfo dot com</td>
+ <td bgcolor="#ffffcc">1.8.2</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Chinese Traditional</td>
+ <td>Daniel YC Lin<br/>Gary Lee</td>
+ <td>dlin dot tw at gmail dot com<br/>garywlee at gmail dot com</td>
+ <td bgcolor="#ffffff">almost up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Croatian</td>
+ <td>Boris Bralo</td>
+ <td>boris dot bralo at gmail dot com</td>
+ <td bgcolor="#ffffcc">1.8.2</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Czech</td>
+ <td>Petr Přikryl</td>
+ <td>prikryl at atlas dot cz</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Danish</td>
+ <td>Poul-Erik Hansen<br/>Erik Søe Sørensen</td>
+ <td>pouhan at gnotometrics dot dk<br/>eriksoe+doxygen at daimi dot au dot dk</td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Dutch</td>
+ <td>Dimitri van Heesch</td>
+ <td>dimitri at stack dot nl</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">English</td>
+ <td>Dimitri van Heesch</td>
+ <td>dimitri at stack dot nl</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Esperanto</td>
+ <td>Ander Martínez</td>
+ <td>ander dot basaundi at gmail dot com</td>
+ <td bgcolor="#ffffcc">1.8.4</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Finnish</td>
+ <td>Antti Laine</td>
+ <td>antti dot a dot laine at tut dot fi</td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">French</td>
+ <td>David Martinet<br/>Xavier Outhier<br/>Benoît BROSSE</td>
+ <td>contact at e-concept-applications dot fr<br/>xouthier at yahoo dot fr<br/>Benoit dot BROSSE at ingenico dot com</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">German</td>
+ <td>Peter Grotrian<br/>Jens Seidel</td>
+ <td>Peter dot Grotrian at pdv-FS dot de<br/>jensseidel at users dot sf dot net</td>
+ <td bgcolor="#ffffcc">1.8.4</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Greek</td>
+ <td>Paul Gessos</td>
+ <td>gessos dot paul at yahoo dot gr</td>
+ <td bgcolor="#ffffcc">1.8.4</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ff5555">Hungarian</td>
+ <td>Ákos Kiss<br/>Földvári György</td>
+ <td>akiss at users dot sourceforge dot net<br/><span style="color: brown">[unreachable]</span></td>
+ <td bgcolor="#ff5555">1.4.6</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Indonesian</td>
+ <td>Hendy Irawan</td>
+ <td>ceefour at gauldong dot net</td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Italian</td>
+ <td>Alessandro Falappa<br/>Ahmed Aldo Faisal</td>
+ <td>alessandro at falappa dot net<br/>aaf23 at cam dot ac dot uk</td>
+ <td bgcolor="#ffffcc">1.8.2</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Japanese</td>
+ <td>Suzumizaki-Kimikata<br/>Hiroki Iseri<br/>Ryunosuke Satoh<br/>Kenji Nagamatsu<br/>Iwasa Kazmi</td>
+ <td>szmml at h12u.com<br/>goyoki at gmail dot com<br/>sun594 at hotmail dot com<br/><span style="color: brown">[unreachable]</span><br/><span style="color: brown">[unreachable]</span></td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">JapaneseEn</td>
+ <td>see the Japanese language</td>
+ <td> </td>
+ <td bgcolor="#ccffcc">English based</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Korean</td>
+ <td>Kim Taedong<br/>SooYoung Jung<br/>Richard Kim</td>
+ <td>fly1004 at gmail dot com<br/>jung5000 at gmail dot com<br/><span style="color: brown">[unreachable]</span></td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">KoreanEn</td>
+ <td>see the Korean language</td>
+ <td> </td>
+ <td bgcolor="#ccffcc">English based</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Latvian</td>
+ <td>Lauris</td>
+ <td>lauris at nix.lv</td>
+ <td bgcolor="#ffffcc">1.8.4</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ff5555">Lithuanian</td>
+ <td>Tomas Simonaitis<br/>Mindaugas Radzius<br/>Aidas Berukstis<br/><span style="color: red; background-color: yellow">-- searching for the maintainer --</span></td>
+ <td><span style="color: brown">[unreachable]</span><br/><span style="color: brown">[unreachable]</span><br/><span style="color: brown">[unreachable]</span><br/><span style="color: brown">[Please, try to help to find someone.]</span></td>
+ <td bgcolor="#ff5555">1.4.6</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Macedonian</td>
+ <td>Slave Jovanovski</td>
+ <td>slavejovanovski at yahoo dot com</td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ff5555">Norwegian</td>
+ <td>Lars Erik Jordet</td>
+ <td>lejordet at gmail dot com</td>
+ <td bgcolor="#ff5555">1.4.6</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Persian</td>
+ <td>Ali Nadalizadeh</td>
+ <td>nadalizadeh at gmail dot com</td>
+ <td bgcolor="#ffcccc">1.7.5</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Polish</td>
+ <td>Piotr Kaminski<br/>Grzegorz Kowal<br/>Krzysztof Kral</td>
+ <td><span style="color: brown">[unreachable]</span><br/><span style="color: brown">[unreachable]</span><br/>krzysztof dot kral at gmail dot com</td>
+ <td bgcolor="#ffffcc">1.8.2</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Portuguese</td>
+ <td>Rui Godinho Lopes<br/>Fabio "FJTC" Jun Takada Chino</td>
+ <td><span style="color: brown">[resigned]</span><br/>jun-chino at uol dot com dot br</td>
+ <td bgcolor="#ffffcc">1.8.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Romanian</td>
+ <td>Ionut Dumitrascu<br/>Alexandru Iosup</td>
+ <td>reddumy at yahoo dot com<br/>aiosup at yahoo dot com</td>
+ <td bgcolor="#ffffff">almost up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Russian</td>
+ <td>Brilliantov Kirill Vladimirovich<br/>Alexandr Chelpanov</td>
+ <td>brilliantov at byterg dot ru<br/>cav at cryptopro dot ru</td>
+ <td bgcolor="#ffffff">almost up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Serbian</td>
+ <td>Dejan Milosavljevic</td>
+ <td><span style="color: brown">[unreachable]</span></td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">SerbianCyrillic</td>
+ <td>Nedeljko Stefanovic</td>
+ <td>stenedjo at yahoo dot com</td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Slovak</td>
+ <td>Kali+Laco Švec<br/>Petr Přikryl</td>
+ <td><span style="color: brown">[the Slovak language advisors]</span><br/>prikryl at atlas dot cz</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ff5555">Slovene</td>
+ <td>Matjaž Ostroveršnik</td>
+ <td>matjaz dot ostroversnik at ostri dot org</td>
+ <td bgcolor="#ff5555">1.4.6</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Spanish</td>
+ <td>Bartomeu<br/>Francisco Oltra Thennet<br/>David Vaquero</td>
+ <td>bartomeu at loteria3cornella dot com<br/><span style="color: brown">[unreachable]</span><br/>david at grupoikusnet dot com</td>
+ <td bgcolor="#ccffcc">up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Swedish</td>
+ <td>Björn Palmqvist</td>
+ <td>bjorn.palmqvist at aidium.se</td>
+ <td bgcolor="#ffffff">almost up-to-date</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Turkish</td>
+ <td>Emin Ilker Cetinbas</td>
+ <td>niw3 at yahoo dot com</td>
+ <td bgcolor="#ffcccc">1.7.5</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Ukrainian</td>
+ <td>Olexij Tkatchenko<br/>Petro Yermolenko</td>
+ <td><span style="color: brown">[resigned]</span><br/>python at i dot ua</td>
+ <td bgcolor="#ffffcc">1.8.4</td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td bgcolor="#ffffff">Vietnamese</td>
+ <td>Dang Minh Tuan</td>
+ <td>tuanvietkey at gmail dot com</td>
+ <td bgcolor="#ffcccc">1.6.0</td>
+ </tr>
+ <!-- table content end -->
+ </table>
+</td>
+</tr>
+</table>
+\endhtmlonly
+
+
+\latexonly
+\footnotesize
+\begin{longtable}{|l|l|l|l|}
+ \hline
+ {\bf Language} & {\bf Maintainer} & {\bf Contact address} & {\bf Status} \\
+ \hline
+
+ \hline
+ Afrikaans & Johan Prinsloo & {\tt\tiny johan at zippysnoek dot com} & 1.6.0 \\
+ \hline
+ Arabic & Moaz Reyad & {\tt\tiny [resigned] moazreyad at yahoo dot com} & 1.4.6 \\
+ ~ & Muhammad Bashir Al-Noimi & {\tt\tiny mbnoimi at gmail dot com} & ~ \\
+ \hline
+ Armenian & Armen Tangamyan & {\tt\tiny armen dot tangamyan at anu dot edu dot au} & 1.8.0 \\
+ \hline
+ Brazilian Portuguese & Fabio "FJTC" Jun Takada Chino & {\tt\tiny jun-chino at uol dot com dot br} & 1.8.0 \\
+ \hline
+ Catalan & Maximiliano Pin & {\tt\tiny max dot pin at bitroit dot com} & 1.8.0 \\
+ ~ & Albert Mora & {\tt\tiny [unreachable] amora at iua dot upf dot es} & ~ \\
+ \hline
+ Chinese & Lian Yang & {\tt\tiny lian dot yang dot cn at gmail dot com} & 1.8.2 \\
+ ~ & Li Daobing & {\tt\tiny lidaobing at gmail dot com} & ~ \\
+ ~ & Wei Liu & {\tt\tiny liuwei at asiainfo dot com} & ~ \\
+ \hline
+ Chinese Traditional & Daniel YC Lin & {\tt\tiny dlin dot tw at gmail dot com} & almost up-to-date \\
+ ~ & Gary Lee & {\tt\tiny garywlee at gmail dot com} & ~ \\
+ \hline
+ Croatian & Boris Bralo & {\tt\tiny boris dot bralo at gmail dot com} & 1.8.2 \\
+ \hline
+ Czech & Petr Přikryl & {\tt\tiny prikryl at atlas dot cz} & up-to-date \\
+ \hline
+ Danish & Poul-Erik Hansen & {\tt\tiny pouhan at gnotometrics dot dk} & 1.8.0 \\
+ ~ & Erik Søe Sørensen & {\tt\tiny eriksoe+doxygen at daimi dot au dot dk} & ~ \\
+ \hline
+ Dutch & Dimitri van Heesch & {\tt\tiny dimitri at stack dot nl} & up-to-date \\
+ \hline
+ English & Dimitri van Heesch & {\tt\tiny dimitri at stack dot nl} & up-to-date \\
+ \hline
+ Esperanto & Ander Martínez & {\tt\tiny ander dot basaundi at gmail dot com} & 1.8.4 \\
+ \hline
+ Finnish & Antti Laine & {\tt\tiny antti dot a dot laine at tut dot fi} & 1.6.0 \\
+ \hline
+ French & David Martinet & {\tt\tiny contact at e-concept-applications dot fr} & up-to-date \\
+ ~ & Xavier Outhier & {\tt\tiny xouthier at yahoo dot fr} & ~ \\
+ ~ & Benoît BROSSE & {\tt\tiny Benoit dot BROSSE at ingenico dot com} & ~ \\
+ \hline
+ German & Peter Grotrian & {\tt\tiny Peter dot Grotrian at pdv-FS dot de} & 1.8.4 \\
+ ~ & Jens Seidel & {\tt\tiny jensseidel at users dot sf dot net} & ~ \\
+ \hline
+ Greek & Paul Gessos & {\tt\tiny gessos dot paul at yahoo dot gr} & 1.8.4 \\
+ \hline
+ Hungarian & Ákos Kiss & {\tt\tiny akiss at users dot sourceforge dot net} & 1.4.6 \\
+ ~ & Földvári György & {\tt\tiny [unreachable] foldvari lost at cyberspace} & ~ \\
+ \hline
+ Indonesian & Hendy Irawan & {\tt\tiny ceefour at gauldong dot net} & 1.8.0 \\
+ \hline
+ Italian & Alessandro Falappa & {\tt\tiny alessandro at falappa dot net} & 1.8.2 \\
+ ~ & Ahmed Aldo Faisal & {\tt\tiny aaf23 at cam dot ac dot uk} & ~ \\
+ \hline
+ Japanese & Suzumizaki-Kimikata & {\tt\tiny szmml at h12u.com} & up-to-date \\
+ ~ & Hiroki Iseri & {\tt\tiny goyoki at gmail dot com} & ~ \\
+ ~ & Ryunosuke Satoh & {\tt\tiny sun594 at hotmail dot com} & ~ \\
+ ~ & Kenji Nagamatsu & {\tt\tiny [unreachable] naga at joyful dot club dot ne dot jp} & ~ \\
+ ~ & Iwasa Kazmi & {\tt\tiny [unreachable] iwasa at cosmo-system dot jp} & ~ \\
+ \hline
+ JapaneseEn & see the Japanese language & {\tt\tiny ~} & English based \\
+ \hline
+ Korean & Kim Taedong & {\tt\tiny fly1004 at gmail dot com} & up-to-date \\
+ ~ & SooYoung Jung & {\tt\tiny jung5000 at gmail dot com} & ~ \\
+ ~ & Richard Kim & {\tt\tiny [unreachable] ryk at dspwiz dot com} & ~ \\
+ \hline
+ KoreanEn & see the Korean language & {\tt\tiny ~} & English based \\
+ \hline
+ Latvian & Lauris & {\tt\tiny lauris at nix.lv} & 1.8.4 \\
+ \hline
+ Lithuanian & Tomas Simonaitis & {\tt\tiny [unreachable] haden at homelan dot lt} & 1.4.6 \\
+ ~ & Mindaugas Radzius & {\tt\tiny [unreachable] mindaugasradzius at takas dot lt} & ~ \\
+ ~ & Aidas Berukstis & {\tt\tiny [unreachable] aidasber at takas dot lt} & ~ \\
+ ~ & -- searching for the maintainer -- & {\tt\tiny [Please, try to help to find someone.]} & ~ \\
+ \hline
+ Macedonian & Slave Jovanovski & {\tt\tiny slavejovanovski at yahoo dot com} & 1.6.0 \\
+ \hline
+ Norwegian & Lars Erik Jordet & {\tt\tiny lejordet at gmail dot com} & 1.4.6 \\
+ \hline
+ Persian & Ali Nadalizadeh & {\tt\tiny nadalizadeh at gmail dot com} & 1.7.5 \\
+ \hline
+ Polish & Piotr Kaminski & {\tt\tiny [unreachable] Piotr dot Kaminski at ctm dot gdynia dot pl} & 1.8.2 \\
+ ~ & Grzegorz Kowal & {\tt\tiny [unreachable] g\_kowal at poczta dot onet dot pl} & ~ \\
+ ~ & Krzysztof Kral & {\tt\tiny krzysztof dot kral at gmail dot com} & ~ \\
+ \hline
+ Portuguese & Rui Godinho Lopes & {\tt\tiny [resigned] rgl at ruilopes dot com} & 1.8.0 \\
+ ~ & Fabio "FJTC" Jun Takada Chino & {\tt\tiny jun-chino at uol dot com dot br} & ~ \\
+ \hline
+ Romanian & Ionut Dumitrascu & {\tt\tiny reddumy at yahoo dot com} & almost up-to-date \\
+ ~ & Alexandru Iosup & {\tt\tiny aiosup at yahoo dot com} & ~ \\
+ \hline
+ Russian & Brilliantov Kirill Vladimirovich & {\tt\tiny brilliantov at byterg dot ru} & almost up-to-date \\
+ ~ & Alexandr Chelpanov & {\tt\tiny cav at cryptopro dot ru} & ~ \\
+ \hline
+ Serbian & Dejan Milosavljevic & {\tt\tiny [unreachable] dmilos at email dot com} & 1.6.0 \\
+ \hline
+ SerbianCyrillic & Nedeljko Stefanovic & {\tt\tiny stenedjo at yahoo dot com} & 1.6.0 \\
+ \hline
+ Slovak & Kali+Laco Švec & {\tt\tiny [the Slovak language advisors]} & up-to-date \\
+ ~ & Petr Přikryl & {\tt\tiny prikryl at atlas dot cz} & ~ \\
+ \hline
+ Slovene & Matjaž Ostroveršnik & {\tt\tiny matjaz dot ostroversnik at ostri dot org} & 1.4.6 \\
+ \hline
+ Spanish & Bartomeu & {\tt\tiny bartomeu at loteria3cornella dot com} & up-to-date \\
+ ~ & Francisco Oltra Thennet & {\tt\tiny [unreachable] foltra at puc dot cl} & ~ \\
+ ~ & David Vaquero & {\tt\tiny david at grupoikusnet dot com} & ~ \\
+ \hline
+ Swedish & Björn Palmqvist & {\tt\tiny bjorn.palmqvist at aidium.se} & almost up-to-date \\
+ \hline
+ Turkish & Emin Ilker Cetinbas & {\tt\tiny niw3 at yahoo dot com} & 1.7.5 \\
+ \hline
+ Ukrainian & Olexij Tkatchenko & {\tt\tiny [resigned] olexij at tkatchenko dot com} & 1.8.4 \\
+ ~ & Petro Yermolenko & {\tt\tiny python at i dot ua} & ~ \\
+ \hline
+ Vietnamese & Dang Minh Tuan & {\tt\tiny tuanvietkey at gmail dot com} & 1.6.0 \\
+ \hline
+\end{longtable}
+\normalsize
+\endlatexonly
+
+
+Most people on the list have indicated that they were also busy
+doing other things, so if you want to help to speed things up please
+let them (or me) know.
+
+If you want to add support for a language that is not yet listed
+please read the next section.
+
+
+<h3>Adding a new language to doxygen</h3>
+
+This short HOWTO explains how to add support for the new language to doxygen:
+
+Just follow the following steps:
+<ol>
+<li>Tell me for which language you want to add support. If no one else
+ is already working on support for that language, you will be
+ assigned as the maintainer for the language.
+<li>Create a copy of `doxygen/src/translator_en.h` and name it
+ `doxygen/src/translator_<your_2_letter_country_code>.h`
+ I'll use `xx` in the rest of this document (and `XX` for the uppercase version).
+<li>Edit `doxygen/src/language.cpp`:
+ Add the following code:
+\verbatim
+#ifdef LANG_XX
+#include<translator_xx.h>
+#endif
+\endverbatim
+ Remember to use the same symbol `LANG_XX` that was added to `doxygen/src/lang_cfg.h`.
+ <p>Now, in <code>setTranslator()</code> add
+\verbatim
+#ifdef LANG_XX
+ else if (L_EQUAL("your_language_name"))
+ {
+ theTranslator = new TranslatorYourLanguage;
+ }
+#endif
+\endverbatim
+ after the <code>if { ... }</code>. I.e., it must be placed after the code
+ for creating the English translator at the beginning, and before the
+ <code>else { ... }</code> part that creates the translator for the
+ default language (English again).
+<li>Edit <code>doxygen/src/translator_xx.h</code>:
+ <ul>
+ <li>Use the UTF-8 capable editor and open the file using the UTF-8 mode.
+ <li>Rename <code>TRANSLATOR_EN_H</code> to <code>TRANSLATOR_XX_H</code>
+ twice (i.e. in the \c \#ifndef and \c \#define preprocessor commands at
+ the beginning of the file).
+ <li>Rename \c TranslatorEnglish to \c TranslatorYourLanguage
+ <li>In the member <code>idLanguage()</code> change "english" into the
+ name of your language (use lower case characters only). Depending
+ on the language you may also wish to change the member functions
+ `latexLanguageSupportCommand()` and other (you will recognize them when
+ you start the work).
+ <li>Edit all the strings that are returned by the member functions that
+ start with \c tr.
+ Try to match punctuation and capitals!
+ To enter special characters (with accents) you can:
+ <ul>
+ <li> Enter them directly if your keyboard supports that. Recall that
+ the text is expected to be saved using the UTF-8 encoding. Doxygen
+ will translate the characters to proper \LaTeX and
+ leaves the HTML and man output in UTF-8.
+ <li> Use HTML codes like \c \ä for an \c a with an \c umlaut (i.e. \c ä).
+ See the HTML specification for the codes.
+ </ul>
+ </ul>
+<li>
+ <ul>
+ <li>On *nix systems:<br>
+ <ul>
+ <li>Rerun the `configure` script from the root (i.e. in the \c doxygen directory) so
+ that it generates `doxygen/src/lang_cfg.h`.
+ This file should now contain a \c \#define for your language code.<br>
+ <li>Run \c make again from the root (i.e. in the \c doxygen
+ directory) of the distribution, in order to regenerate the `Makefile`s.
+ </ul>
+ <li> On Windows:<br>
+ <ul>
+ <li>stop Visual Stdio<br>
+ <li>open a command window<br>
+ <li>goto the directory `doxygen\src`<br>
+ <li>give the command `python languages.py > ..\winbuild\Languages.rules`<br>
+ <li>close the command window<br>
+ <li>start Visual Studio again<br>
+ <li>Your language should now be selectable in the `General` part of the `Settings` of the `Properties`
+ window of `lang_cfg.py`, by default Your language will be `on`. Rebuild `doxygen` (and `doxywizard`) now.
+ </ul>
+ </ul>
+<li>Now you can use <code>OUTPUT_LANGUAGE = your_language_name</code>
+ in the config file to generate output in your language.
+<li>Send <code>translator_xx.h</code> to me so I can add it to doxygen.
+ Send also your name and e-mail address to be included in the
+ \c maintainers.txt list. You can also clone the doxygen repository
+ at GitHub and make a Pull Request later.
+</ol>
+
+
+<h3>Maintaining a language</h3>
+
+New versions of doxygen may use new translated sentences. In such
+situation, the \c Translator class requires implementation of new
+methods -- its interface changes. Of course, the English
+sentences need to be translated to the other languages. At least,
+new methods have to be implemented by the language-related
+translator class; otherwise, doxygen wouldn't even compile. Waiting
+until all language maintainers have translated the new sentences and
+sent the results would not be very practical. The following text
+describes the usage of translator adapters to solve the problem.
+
+<b>The role of Translator Adapters.</b>
+Whenever the \c Translator class interface changes in the new
+release, the new class \c TranslatorAdapter_x_y_z is added to the \c
+translator_adapter.h file (here x, y, and z are numbers that
+correspond to the current official version of doxygen). All
+translators that previously derived from the \c Translator class now
+derive from this adapter class.
+
+The \c TranslatorAdapter_x_y_z class implements the new, required
+methods. If the new method replaces some similar but obsolete
+method(s) (e.g. if the number of arguments changed and/or the
+functionality of the older method was changed or enriched), the \c
+TranslatorAdapter_x_y_z class may use the obsolete method to get the
+result which is as close as possible to the older result in the
+target language. If it is not possible, the result (the default
+translation) is obtained using the English translator, which is (by
+definition) always up-to-date.
+
+<b>For example,</b> when the new \c trFile() method with
+parameters (to determine the capitalization of the first letter and
+the singular/plural form) was introduced to replace the older method
+\c trFiles() without arguments, the following code appeared in one
+of the translator adapter classes:
+
+\verbatim
+ /*! This is the default implementation of the obsolete method
+ * used in the documentation of a group before the list of
+ * links to documented files. This is possibly localized.
+ */
+ virtual QCString trFiles()
+ { return "Files"; }
+
+ /*! This is the localized implementation of newer equivalent
+ * using the obsolete method trFiles().
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ if (first_capital && !singular)
+ return trFiles(); // possibly localized, obsolete method
+ else
+ return english.trFile(first_capital, singular);
+ }
+\endverbatim
+
+The \c trFiles() is not present in the \c TranslatorEnglish class,
+because it was removed as obsolete. However, it was used until now
+and its call was replaced by
+
+\verbatim
+ trFile(true, false)
+\endverbatim
+
+in the doxygen source files. Probably, many language translators
+implemented the obsolete method, so it perfectly makes sense to use
+the same language dependent result in those cases. The \c
+TranslatorEnglish does not implement the old method. It derives
+from the abstract \c Translator class. On the other hand, the old
+translator for a different language does not implement the new \c
+trFile() method. Because of that it is derived from another base
+class -- \c TranslatorAdapter_x_y_z. The \c TranslatorAdapter_x_y_z
+class has to implement the new, required \c trFile() method.
+However, the translator adapter would not be compiled if the \c
+trFiles() method was not implemented. This is the reason for
+implementing the old method in the translator adapter class (using
+the same code, that was removed from the TranslatorEnglish).
+
+The simplest way would be to pass the arguments to the English
+translator and to return its result. Instead, the adapter uses the
+old \c trFiles() in one special case -- when the new
+<code>trFile(true, false)</code> is called. This is the
+mostly used case at the time of introducing the new method -- see
+above. While this may look too complicated, the technique allows
+the developers of the core sources to change the Translator
+interface, while the users may not even notice the change. Of
+course, when the new \c trFile() is used with different arguments,
+the English result is returned and it will be noticed by non English
+users. Here the maintainer of the language translator should
+implement at least that one particular method.
+
+<b>What says the base class of a language translator?</b>
+If the language translator class inherits from any adapter class then
+maintenance is needed. In such case, the language translator is
+considered not up-to-date. On the other hand, if the language
+translator derives directly from the abstract class \c Translator, the
+language translator is up-to-date.
+
+The translator adapter classes are chained so that the older
+translator adapter class uses the one-step-newer translator adapter
+as the base class. The newer adapter does less \e adapting work
+than the older one. The oldest adapter class derives (indirectly)
+from all of the adapter classes. The name of the adapter class is
+chosen so that its suffix is derived from the previous official
+version of doxygen that did not need the adapter. This way, one can
+say approximately, when the language translator class was last
+updated -- see details below.
+
+The newest translator adapter derives from the abstract \c
+TranslatorAdapterBase class that derives directly from the abstract
+\c Translator class. It adds only the private English-translator
+member for easy implementation of the default translation inside the
+adapter classes, and it also enforces implementation of one method
+for notifying the user that the language translation is not up-to-date
+(because of that some sentences in the generated files may appear in
+English).
+
+Once the oldest adapter class is not used by any of the language
+translators, it can be removed from the doxygen project. The
+maintainers should try to reach the state with the minimal number of
+translator adapter classes.
+
+<b>To simplify the maintenance of the language translator classes</b>
+for the supported languages, the \c translator.py Python
+script was developed (located in \c doxygen/doc directory).
+It extracts the important information about obsolete and
+new methods from the source files for each of the languages.
+The information is stored in the translator report ASCII file
+(\c translator_report.txt).
+
+\htmlonly If you compiled this documentation
+from sources and if you have also doxygen sources available the
+link <a href="../doc/translator_report.txt"
+><code>doxygen/doc/translator_report.txt</code></a> should be valid.\endhtmlonly
+
+Looking at the base class of the language translator, the script
+guesses also the status of the translator -- see the last column of
+the table with languages above. The \c translator.py is called
+automatically when the doxygen documentation is generated. You can
+also run the script manually whenever you feel that it can help you.
+Of course, you are not forced to use the results of the script. You
+can find the same information by looking at the adapter class and
+its base classes.
+
+<b>How should I update my language translator?</b> First, you
+should be the language maintainer, or you should let him/her know
+about the changes. The following text was written for the language
+maintainers as the primary audience.
+
+There are several approaches to be taken when updating your
+language. If you are not extremely busy, you should always chose
+the most radical one. When the update takes much more time than you
+expected, you can always decide use some suitable translator adapter to
+finish the changes later and still make your translator working.
+
+<b>The most radical way of updating the language translator</b> is
+to make your translator class derive directly
+from the abstract class \c Translator and provide translations for the
+methods that are required to be implemented -- the compiler will
+tell you if you forgot to implement some of them. If you are in
+doubt, have a look at the \c TranslatorEnglish class to recognize the
+purpose of the implemented method. Looking at the previously used
+adapter class may help you sometimes, but it can also be misleading
+because the adapter classes do implement also the obsolete methods
+(see the previous \c trFiles() example).
+
+In other words, the up-to-date language translators do not need the
+\c TranslatorAdapter_x_y_z classes at all, and you do not need to
+implement anything else than the methods required by the Translator
+class (i.e. the pure virtual methods of the \c Translator -- they
+end with <code>=0;</code>).
+
+If everything compiles fine, try to run \c translator.py, and have a
+look at the translator report (ASCII file) at the \c doxygen/doc
+directory. Your translator is marked as up-to-date only if the script
+does not detect anything special. If the translator uses the \c Translator
+base class, there still may be some remarks related to your source code.
+In the case, the translator is marked as <em>almost up-to-date</em>.
+Namely, the obsolete methods--that are not used at all--may be listed in the
+section for your language. Simply, remove their code (and run the \c
+translator.py again). Also, you will be informed when you forgot to
+change the base class of your translator class to some newer adapter
+class or directly to the Translator class.
+
+<b>If you do not have time to finish all the updates</b> you should
+still start with <em>the most radical approach</em> as described
+above. You can always change the base class to the translator
+adapter class that implements all of the not-yet-implemented methods.
+
+<b>If you prefer to update your translator gradually</b>, have a look
+at \c TranslatorEnglish (the \c translator_en.h file). Inside, you
+will find the comments like <code>new since 1.2.4</code> that separate
+always a number of methods that were implemented in the stated
+version. Do implement the group of methods that are placed below the
+comment that uses the same version numbers as your translator adapter
+class. (For example, your translator class have to use the \c
+TranslatorAdapter_1_2_4, if it does not implement the methods below
+the comment <code>new since 1.2.4</code>. When you implement them,
+your class should use a newer translator adapter.
+
+Run the \c translator.py script occasionally and give it your \c xx
+identification (from \c translator_xx.h) to create the translator
+report shorter (also produced faster) -- it will contain only the
+information related to your translator. Once you reach the state when
+the base class should be changed to some newer adapter, you will see
+the note in the translator report.
+
+Warning: Don't forget to compile doxygen to discover, whether it is
+compilable. The \c translator.py does not check if everything is
+correct with respect to the compiler. Because of that, it may lie
+sometimes about the necessary base class.
+
+<b>The most obsolete language translators</b> would lead to
+implementation of too complicated adapters. Because of that, doxygen
+developers may decide to derive such translators from the \c
+TranslatorEnglish class, which is by definition always up-to-date.
+
+When doing so, all the missing methods will be replaced by the
+English translation. This means that not-implemented methods will
+always return the English result. Such translators are marked using
+the word \c obsolete. You should read it <b>really obsolete</b>. No
+guess about the last update can be done.
+
+Often, it is possible to construct better result from the obsolete
+methods. Because of that, the translator adapter classes should be
+used if possible. On the other hand, implementation of adapters for
+really obsolete translators brings too much maintenance and
+run-time overhead.
+
+\htmlonly
+Go to the <a href="perlmod.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/language.tpl b/doc/language.tpl
new file mode 100644
index 0000000..78e3e97
--- /dev/null
+++ b/doc/language.tpl
@@ -0,0 +1,372 @@
+
+ATTENTION! This is the template for generating language.doc. If you want to
+change the language.doc, make the changes here and inside maintainers.txt.
+
+/******************************************************************************
+ * %(editnote)s
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page langhowto Internationalization
+
+<h3>Support for multiple languages</h3>
+
+Doxygen has built-in support for multiple languages. This means that the
+text fragments, generated by doxygen, can be produced in languages other
+than English (the default). The output language is chosen through the
+configuration option \ref cfg_output_language "OUTPUT_LANGUAGE" in the
+configuration file (with default name and known as Doxyfile).
+
+Currently (version %(doxVersion)s), %(numLangStr)s languages
+are supported (sorted alphabetically):
+%(supportedLangReadableStr)s.
+
+The table of information related to the supported languages follows.
+It is sorted by language alphabetically. The <b>Status</b> column
+was generated from sources and shows approximately the last version
+when the translator was updated.
+
+%(informationTable)s
+
+Most people on the list have indicated that they were also busy
+doing other things, so if you want to help to speed things up please
+let them (or me) know.
+
+If you want to add support for a language that is not yet listed
+please read the next section.
+
+
+<h3>Adding a new language to doxygen</h3>
+
+This short HOWTO explains how to add support for the new language to doxygen:
+
+Just follow the following steps:
+<ol>
+<li>Tell me for which language you want to add support. If no one else
+ is already working on support for that language, you will be
+ assigned as the maintainer for the language.
+<li>Create a copy of `doxygen/src/translator_en.h` and name it
+ `doxygen/src/translator_<your_2_letter_country_code>.h`
+ I'll use `xx` in the rest of this document (and `XX` for the uppercase version).
+<li>Edit `doxygen/src/language.cpp`:
+ Add the following code:
+\verbatim
+#ifdef LANG_XX
+#include<translator_xx.h>
+#endif
+\endverbatim
+ Remember to use the same symbol `LANG_XX` that was added to `doxygen/src/lang_cfg.h`.
+ <p>Now, in <code>setTranslator()</code> add
+\verbatim
+#ifdef LANG_XX
+ else if (L_EQUAL("your_language_name"))
+ {
+ theTranslator = new TranslatorYourLanguage;
+ }
+#endif
+\endverbatim
+ after the <code>if { ... }</code>. I.e., it must be placed after the code
+ for creating the English translator at the beginning, and before the
+ <code>else { ... }</code> part that creates the translator for the
+ default language (English again).
+<li>Edit <code>doxygen/src/translator_xx.h</code>:
+ <ul>
+ <li>Use the UTF-8 capable editor and open the file using the UTF-8 mode.
+ <li>Rename <code>TRANSLATOR_EN_H</code> to <code>TRANSLATOR_XX_H</code>
+ twice (i.e. in the \c \#ifndef and \c \#define preprocessor commands at
+ the beginning of the file).
+ <li>Rename \c TranslatorEnglish to \c TranslatorYourLanguage
+ <li>In the member <code>idLanguage()</code> change "english" into the
+ name of your language (use lower case characters only). Depending
+ on the language you may also wish to change the member functions
+ `latexLanguageSupportCommand()` and other (you will recognize them when
+ you start the work).
+ <li>Edit all the strings that are returned by the member functions that
+ start with \c tr.
+ Try to match punctuation and capitals!
+ To enter special characters (with accents) you can:
+ <ul>
+ <li> Enter them directly if your keyboard supports that. Recall that
+ the text is expected to be saved using the UTF-8 encoding. Doxygen
+ will translate the characters to proper \LaTeX and
+ leaves the HTML and man output in UTF-8.
+ <li> Use HTML codes like \c \ä for an \c a with an \c umlaut (i.e. \c ä).
+ See the HTML specification for the codes.
+ </ul>
+ </ul>
+<li>
+ <ul>
+ <li>On *nix systems:<br>
+ <ul>
+ <li>Rerun the `configure` script from the root (i.e. in the \c doxygen directory) so
+ that it generates `doxygen/src/lang_cfg.h`.
+ This file should now contain a \c \#define for your language code.<br>
+ <li>Run \c make again from the root (i.e. in the \c doxygen
+ directory) of the distribution, in order to regenerate the `Makefile`s.
+ </ul>
+ <li> On Windows:<br>
+ <ul>
+ <li>stop Visual Stdio<br>
+ <li>open a command window<br>
+ <li>goto the directory `doxygen\src`<br>
+ <li>give the command `python languages.py > ..\winbuild\Languages.rules`<br>
+ <li>close the command window<br>
+ <li>start Visual Studio again<br>
+ <li>Your language should now be selectable in the `General` part of the `Settings` of the `Properties`
+ window of `lang_cfg.py`, by default Your language will be `on`. Rebuild `doxygen` (and `doxywizard`) now.
+ </ul>
+ </ul>
+<li>Now you can use <code>OUTPUT_LANGUAGE = your_language_name</code>
+ in the config file to generate output in your language.
+<li>Send <code>translator_xx.h</code> to me so I can add it to doxygen.
+ Send also your name and e-mail address to be included in the
+ \c maintainers.txt list. You can also clone the doxygen repository
+ at GitHub and make a Pull Request later.
+</ol>
+
+
+<h3>Maintaining a language</h3>
+
+New versions of doxygen may use new translated sentences. In such
+situation, the \c Translator class requires implementation of new
+methods -- its interface changes. Of course, the English
+sentences need to be translated to the other languages. At least,
+new methods have to be implemented by the language-related
+translator class; otherwise, doxygen wouldn't even compile. Waiting
+until all language maintainers have translated the new sentences and
+sent the results would not be very practical. The following text
+describes the usage of translator adapters to solve the problem.
+
+<b>The role of Translator Adapters.</b>
+Whenever the \c Translator class interface changes in the new
+release, the new class \c TranslatorAdapter_x_y_z is added to the \c
+translator_adapter.h file (here x, y, and z are numbers that
+correspond to the current official version of doxygen). All
+translators that previously derived from the \c Translator class now
+derive from this adapter class.
+
+The \c TranslatorAdapter_x_y_z class implements the new, required
+methods. If the new method replaces some similar but obsolete
+method(s) (e.g. if the number of arguments changed and/or the
+functionality of the older method was changed or enriched), the \c
+TranslatorAdapter_x_y_z class may use the obsolete method to get the
+result which is as close as possible to the older result in the
+target language. If it is not possible, the result (the default
+translation) is obtained using the English translator, which is (by
+definition) always up-to-date.
+
+<b>For example,</b> when the new \c trFile() method with
+parameters (to determine the capitalization of the first letter and
+the singular/plural form) was introduced to replace the older method
+\c trFiles() without arguments, the following code appeared in one
+of the translator adapter classes:
+
+\verbatim
+ /*! This is the default implementation of the obsolete method
+ * used in the documentation of a group before the list of
+ * links to documented files. This is possibly localized.
+ */
+ virtual QCString trFiles()
+ { return "Files"; }
+
+ /*! This is the localized implementation of newer equivalent
+ * using the obsolete method trFiles().
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ if (first_capital && !singular)
+ return trFiles(); // possibly localized, obsolete method
+ else
+ return english.trFile(first_capital, singular);
+ }
+\endverbatim
+
+The \c trFiles() is not present in the \c TranslatorEnglish class,
+because it was removed as obsolete. However, it was used until now
+and its call was replaced by
+
+\verbatim
+ trFile(true, false)
+\endverbatim
+
+in the doxygen source files. Probably, many language translators
+implemented the obsolete method, so it perfectly makes sense to use
+the same language dependent result in those cases. The \c
+TranslatorEnglish does not implement the old method. It derives
+from the abstract \c Translator class. On the other hand, the old
+translator for a different language does not implement the new \c
+trFile() method. Because of that it is derived from another base
+class -- \c TranslatorAdapter_x_y_z. The \c TranslatorAdapter_x_y_z
+class has to implement the new, required \c trFile() method.
+However, the translator adapter would not be compiled if the \c
+trFiles() method was not implemented. This is the reason for
+implementing the old method in the translator adapter class (using
+the same code, that was removed from the TranslatorEnglish).
+
+The simplest way would be to pass the arguments to the English
+translator and to return its result. Instead, the adapter uses the
+old \c trFiles() in one special case -- when the new
+<code>trFile(true, false)</code> is called. This is the
+mostly used case at the time of introducing the new method -- see
+above. While this may look too complicated, the technique allows
+the developers of the core sources to change the Translator
+interface, while the users may not even notice the change. Of
+course, when the new \c trFile() is used with different arguments,
+the English result is returned and it will be noticed by non English
+users. Here the maintainer of the language translator should
+implement at least that one particular method.
+
+<b>What says the base class of a language translator?</b>
+If the language translator class inherits from any adapter class then
+maintenance is needed. In such case, the language translator is
+considered not up-to-date. On the other hand, if the language
+translator derives directly from the abstract class \c Translator, the
+language translator is up-to-date.
+
+The translator adapter classes are chained so that the older
+translator adapter class uses the one-step-newer translator adapter
+as the base class. The newer adapter does less \e adapting work
+than the older one. The oldest adapter class derives (indirectly)
+from all of the adapter classes. The name of the adapter class is
+chosen so that its suffix is derived from the previous official
+version of doxygen that did not need the adapter. This way, one can
+say approximately, when the language translator class was last
+updated -- see details below.
+
+The newest translator adapter derives from the abstract \c
+TranslatorAdapterBase class that derives directly from the abstract
+\c Translator class. It adds only the private English-translator
+member for easy implementation of the default translation inside the
+adapter classes, and it also enforces implementation of one method
+for notifying the user that the language translation is not up-to-date
+(because of that some sentences in the generated files may appear in
+English).
+
+Once the oldest adapter class is not used by any of the language
+translators, it can be removed from the doxygen project. The
+maintainers should try to reach the state with the minimal number of
+translator adapter classes.
+
+<b>To simplify the maintenance of the language translator classes</b>
+for the supported languages, the \c translator.py Python
+script was developed (located in \c doxygen/doc directory).
+It extracts the important information about obsolete and
+new methods from the source files for each of the languages.
+The information is stored in the translator report ASCII file
+(\c %(translatorReportFileName)s).
+
+\htmlonly If you compiled this documentation
+from sources and if you have also doxygen sources available the
+link %(translatorReportLink)s should be valid.\endhtmlonly
+
+Looking at the base class of the language translator, the script
+guesses also the status of the translator -- see the last column of
+the table with languages above. The \c translator.py is called
+automatically when the doxygen documentation is generated. You can
+also run the script manually whenever you feel that it can help you.
+Of course, you are not forced to use the results of the script. You
+can find the same information by looking at the adapter class and
+its base classes.
+
+<b>How should I update my language translator?</b> First, you
+should be the language maintainer, or you should let him/her know
+about the changes. The following text was written for the language
+maintainers as the primary audience.
+
+There are several approaches to be taken when updating your
+language. If you are not extremely busy, you should always chose
+the most radical one. When the update takes much more time than you
+expected, you can always decide use some suitable translator adapter to
+finish the changes later and still make your translator working.
+
+<b>The most radical way of updating the language translator</b> is
+to make your translator class derive directly
+from the abstract class \c Translator and provide translations for the
+methods that are required to be implemented -- the compiler will
+tell you if you forgot to implement some of them. If you are in
+doubt, have a look at the \c TranslatorEnglish class to recognize the
+purpose of the implemented method. Looking at the previously used
+adapter class may help you sometimes, but it can also be misleading
+because the adapter classes do implement also the obsolete methods
+(see the previous \c trFiles() example).
+
+In other words, the up-to-date language translators do not need the
+\c TranslatorAdapter_x_y_z classes at all, and you do not need to
+implement anything else than the methods required by the Translator
+class (i.e. the pure virtual methods of the \c Translator -- they
+end with <code>=0;</code>).
+
+If everything compiles fine, try to run \c translator.py, and have a
+look at the translator report (ASCII file) at the \c doxygen/doc
+directory. Your translator is marked as up-to-date only if the script
+does not detect anything special. If the translator uses the \c Translator
+base class, there still may be some remarks related to your source code.
+In the case, the translator is marked as <em>almost up-to-date</em>.
+Namely, the obsolete methods--that are not used at all--may be listed in the
+section for your language. Simply, remove their code (and run the \c
+translator.py again). Also, you will be informed when you forgot to
+change the base class of your translator class to some newer adapter
+class or directly to the Translator class.
+
+<b>If you do not have time to finish all the updates</b> you should
+still start with <em>the most radical approach</em> as described
+above. You can always change the base class to the translator
+adapter class that implements all of the not-yet-implemented methods.
+
+<b>If you prefer to update your translator gradually</b>, have a look
+at \c TranslatorEnglish (the \c translator_en.h file). Inside, you
+will find the comments like <code>new since 1.2.4</code> that separate
+always a number of methods that were implemented in the stated
+version. Do implement the group of methods that are placed below the
+comment that uses the same version numbers as your translator adapter
+class. (For example, your translator class have to use the \c
+TranslatorAdapter_1_2_4, if it does not implement the methods below
+the comment <code>new since 1.2.4</code>. When you implement them,
+your class should use a newer translator adapter.
+
+Run the \c translator.py script occasionally and give it your \c xx
+identification (from \c translator_xx.h) to create the translator
+report shorter (also produced faster) -- it will contain only the
+information related to your translator. Once you reach the state when
+the base class should be changed to some newer adapter, you will see
+the note in the translator report.
+
+Warning: Don't forget to compile doxygen to discover, whether it is
+compilable. The \c translator.py does not check if everything is
+correct with respect to the compiler. Because of that, it may lie
+sometimes about the necessary base class.
+
+<b>The most obsolete language translators</b> would lead to
+implementation of too complicated adapters. Because of that, doxygen
+developers may decide to derive such translators from the \c
+TranslatorEnglish class, which is by definition always up-to-date.
+
+When doing so, all the missing methods will be replaced by the
+English translation. This means that not-implemented methods will
+always return the English result. Such translators are marked using
+the word \c obsolete. You should read it <b>really obsolete</b>. No
+guess about the last update can be done.
+
+Often, it is possible to construct better result from the obsolete
+methods. Because of that, the translator adapter classes should be
+used if possible. On the other hand, implementation of adapters for
+really obsolete translators brings too much maintenance and
+run-time overhead.
+
+\htmlonly
+Go to the <a href="perlmod.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/lists.doc b/doc/lists.doc
new file mode 100644
index 0000000..b79b2cd
--- /dev/null
+++ b/doc/lists.doc
@@ -0,0 +1,125 @@
+/*! \page lists Lists
+
+Doxygen provides a number of ways to create lists of items.
+
+<b>Using dashes</b>
+
+By putting a number of column-aligned minus (-) signs at the start of a
+line, a bullet list will automatically be generated. Instead of the minus
+sign also plus (+) or asterisk (\*) can be used.
+
+Numbered lists can also be generated by using a minus followed by a hash
+or by using a number followed by a dot.
+
+Nesting of lists is allowed and is based on indentation of the items.<p>
+Here is an example:
+
+\verbatim
+ /*!
+ * A list of events:
+ * - mouse events
+ * -# mouse move event
+ * -# mouse click event\n
+ * More info about the click event.
+ * -# mouse double click event
+ * - keyboard events
+ * 1. key down event
+ * 2. key up event
+ *
+ * More text here.
+ */
+\endverbatim
+ The result will be:
+
+ A list of events:
+ - mouse events
+ -# mouse move event
+ -# mouse click event\n
+ More info about the click event.
+ -# mouse double click event
+ - keyboard events
+ 1. key down event
+ 2. key up event
+
+ More text here.
+
+If you use tabs for indentation within lists, please make sure
+that \ref cfg_tab_size "TAB_SIZE" in the configuration file is set to
+the correct tab size.
+
+You can end a list by starting a new paragraph or
+by putting a dot (.) on an empty line at the same indentation level as the
+list you would like to end.
+
+Here is an example that speaks for itself:
+
+\verbatim
+/**
+ * Text before the list
+ * - list item 1
+ * - sub item 1
+ * - sub sub item 1
+ * - sub sub item 2
+ * .
+ * The dot above ends the sub sub item list.
+ *
+ * More text for the first sub item
+ * .
+ * The dot above ends the first sub item.
+ *
+ * More text for the first list item
+ * - sub item 2
+ * - sub item 3
+ * - list item 2
+ * .
+ * More text in the same paragraph.
+ *
+ * More text in a new paragraph.
+ */
+\endverbatim
+
+<b>Using HTML commands</b>
+
+If you like you can also use HTML commands inside the documentation
+blocks.
+
+Here is the above example with HTML commands:
+\verbatim
+ /*!
+ * A list of events:
+ * <ul>
+ * <li> mouse events
+ * <ol>
+ * <li>mouse move event
+ * <li>mouse click event<br>
+ * More info about the click event.
+ * <li>mouse double click event
+ * </ol>
+ * <li> keyboard events
+ * <ol>
+ * <li>key down event
+ * <li>key up event
+ * </ol>
+ * </ul>
+ * More text here.
+ */
+\endverbatim
+
+\note In this case the indentation is not important.
+
+<b>Using \\arg or \\li</b>
+
+For compatibility with the Qt Software's internal documentation tool qdoc and
+with KDoc, doxygen has two commands that can be used to create simple
+unnested lists.
+
+See \ref cmdarg "\\arg" and \ref cmdli "\\li" for more info.
+
+\htmlonly
+Go to the <a href="grouping.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
+
diff --git a/doc/maintainers.txt b/doc/maintainers.txt
new file mode 100644
index 0000000..30afcd5
--- /dev/null
+++ b/doc/maintainers.txt
@@ -0,0 +1,165 @@
+% The text is in UTF-8. Comments start with % sign at the beginning.
+% There is one record for each language. The records are separated
+% by the empty line and they do not contain empty lines.
+% First line of the record identifies the translator class for the language.
+% The following one or more lines contain information about
+% the maintainer(s) for the language (one line, one maintainer)
+% in the form: <readable name><colon><e-mail>
+% If the readable name name starts with '--' it will be displayed in HTML
+% output as a highlighted text notice related to the langluage (usually
+% '-- searching for the maintainer --').
+% If the <e-mail> is prefixed [some_text] it is not displayed in the table
+% of maintainers in the Doxygen documentation, nor it is used when building
+% the mailto.txt by translator.py. The mark is displayed in the documentation
+% instead.
+
+TranslatorAfrikaans
+Johan Prinsloo: johan at zippysnoek dot com
+
+TranslatorArabic
+Moaz Reyad: [resigned] moazreyad at yahoo dot com
+Muhammad Bashir Al-Noimi: mbnoimi at gmail dot com
+
+TranslatorArmenian
+Armen Tangamyan: armen dot tangamyan at anu dot edu dot au
+
+TranslatorBrazilian
+Fabio "FJTC" Jun Takada Chino: jun-chino at uol dot com dot br
+
+TranslatorCatalan
+Maximiliano Pin: max dot pin at bitroit dot com
+Albert Mora: [unreachable] amora at iua dot upf dot es
+
+TranslatorChinese
+Lian Yang: lian dot yang dot cn at gmail dot com
+Li Daobing: lidaobing at gmail dot com
+Wei Liu: liuwei at asiainfo dot com
+
+TranslatorChinesetraditional
+Daniel YC Lin: dlin dot tw at gmail dot com
+Gary Lee: garywlee at gmail dot com
+
+TranslatorCroatian
+Boris Bralo: boris dot bralo at gmail dot com
+
+TranslatorCzech
+Petr Přikryl: prikryl at atlas dot cz
+
+TranslatorDanish
+Poul-Erik Hansen: pouhan at gnotometrics dot dk
+Erik Søe Sørensen: eriksoe+doxygen at daimi dot au dot dk
+
+TranslatorDutch
+Dimitri van Heesch: dimitri at stack dot nl
+
+TranslatorEnglish
+Dimitri van Heesch: dimitri at stack dot nl
+
+TranslatorEsperanto
+Ander Martínez: ander dot basaundi at gmail dot com
+
+TranslatorFinnish
+Antti Laine: antti dot a dot laine at tut dot fi
+
+TranslatorFrench
+David Martinet: contact at e-concept-applications dot fr
+Xavier Outhier: xouthier at yahoo dot fr
+Benoît BROSSE: Benoit dot BROSSE at ingenico dot com
+
+TranslatorGerman
+Peter Grotrian: Peter dot Grotrian at pdv-FS dot de
+Jens Seidel: jensseidel at users dot sf dot net
+
+TranslatorGreek
+Paul Gessos: gessos dot paul at yahoo dot gr
+
+TranslatorHungarian
+Ákos Kiss: akiss at users dot sourceforge dot net
+Földvári György: [unreachable] foldvari lost at cyberspace
+
+TranslatorIndonesian
+Hendy Irawan: ceefour at gauldong dot net
+
+TranslatorItalian
+Alessandro Falappa: alessandro at falappa dot net
+Ahmed Aldo Faisal: aaf23 at cam dot ac dot uk
+
+TranslatorJapanese
+Suzumizaki-Kimikata: szmml at h12u.com
+Hiroki Iseri: goyoki at gmail dot com
+Ryunosuke Satoh: sun594 at hotmail dot com
+Kenji Nagamatsu: [unreachable] naga at joyful dot club dot ne dot jp
+Iwasa Kazmi: [unreachable] iwasa at cosmo-system dot jp
+
+TranslatorKorean
+Kim Taedong: fly1004 at gmail dot com
+SooYoung Jung: jung5000 at gmail dot com
+Richard Kim: [unreachable] ryk at dspwiz dot com
+
+TranslatorLatvian
+Lauris: lauris at nix.lv
+
+TranslatorLithuanian
+Tomas Simonaitis: [unreachable] haden at homelan dot lt
+Mindaugas Radzius: [unreachable] mindaugasradzius at takas dot lt
+Aidas Berukstis: [unreachable] aidasber at takas dot lt
+-- searching for the maintainer --: [Please, try to help to find someone.]
+
+TranslatorNorwegian
+Lars Erik Jordet: lejordet at gmail dot com
+
+TranslatorMacedonian
+Slave Jovanovski: slavejovanovski at yahoo dot com
+
+TranslatorPersian
+Ali Nadalizadeh: nadalizadeh at gmail dot com
+
+TranslatorPolish
+Piotr Kaminski: [unreachable] Piotr dot Kaminski at ctm dot gdynia dot pl
+Grzegorz Kowal: [unreachable] g_kowal at poczta dot onet dot pl
+Krzysztof Kral: krzysztof dot kral at gmail dot com
+
+TranslatorPortuguese
+Rui Godinho Lopes: [resigned] rgl at ruilopes dot com
+Fabio "FJTC" Jun Takada Chino: jun-chino at uol dot com dot br
+
+TranslatorRomanian
+Ionut Dumitrascu: reddumy at yahoo dot com
+Alexandru Iosup: aiosup at yahoo dot com
+
+TranslatorRussian
+Brilliantov Kirill Vladimirovich: brilliantov at byterg dot ru
+Alexandr Chelpanov: cav at cryptopro dot ru
+
+TranslatorSerbian
+Dejan Milosavljevic: [unreachable] dmilos at email dot com
+
+TranslatorSerbianCyrillic
+Nedeljko Stefanovic: stenedjo at yahoo dot com
+
+TranslatorSlovak
+% Stanislav Kudláč: [resigned] skudlac at pobox dot sk
+Kali+Laco Švec: [the Slovak language advisors]
+Petr Přikryl: prikryl at atlas dot cz
+
+TranslatorSlovene
+Matjaž Ostroveršnik: matjaz dot ostroversnik at ostri dot org
+
+TranslatorSpanish
+Bartomeu: bartomeu at loteria3cornella dot com
+Francisco Oltra Thennet: [unreachable] foltra at puc dot cl
+David Vaquero: david at grupoikusnet dot com
+
+TranslatorSwedish
+Björn Palmqvist: bjorn.palmqvist at aidium.se
+
+TranslatorTurkish
+Emin Ilker Cetinbas: niw3 at yahoo dot com
+
+TranslatorUkrainian
+Olexij Tkatchenko: [resigned] olexij at tkatchenko dot com
+Petro Yermolenko: python at i dot ua
+
+TranslatorVietnamese
+Dang Minh Tuan: tuanvietkey at gmail dot com
+
diff --git a/doc/markdown.doc b/doc/markdown.doc
new file mode 100644
index 0000000..e97b29e
--- /dev/null
+++ b/doc/markdown.doc
@@ -0,0 +1,654 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page markdown Markdown support
+
+[TOC]
+
+[Markdown] support
+was introduced in doxygen version 1.8.0. It is a plain text formatting
+syntax written by John Gruber, with the following underlying design goal:
+
+> The design goal for Markdown's formatting syntax is to
+> make it as readable as possible. The idea is that a Markdown-formatted
+> document should be publishable as-is, as plain text, without
+> looking like it's been marked up with tags or formatting instructions.
+> While Markdown's syntax has been influenced by several existing
+> text-to-HTML filters, the single biggest source of inspiration
+> for Markdown's syntax is the format of plain text email.
+
+In the \ref markdown_std "next section" the standard Markdown features
+are briefly discussed. The reader is referred to the [Markdown site][markdown]
+for more details.
+
+Some enhancements were made, for instance [PHP Markdown Extra][mdextra], and
+[GitHub flavored Markdown][github]. The section \ref markdown_extra discusses
+the extensions that doxygen supports.
+
+Finally section \ref markdown_dox discusses some specifics for doxygen's
+implementation of the Markdown standard.
+
+[markdown]: http://daringfireball.net/projects/markdown
+[mdextra]: http://michelf.com/projects/php-markdown/extra/
+[github]: http://github.github.com/github-flavored-markdown/
+
+\section markdown_std Standard Markdown
+
+\subsection md_para Paragraphs
+
+Even before doxygen had Markdown support it supported the same way
+of paragraph handling as Markdown: to make a paragraph you just separate
+consecutive lines of text by one or more blank lines.
+
+An example:
+
+ Here is text for one paragraph.
+
+ We continue with more text in another paragraph.
+
+\subsection md_headers Headers
+
+Just like Markdown, doxygen supports two types of headers
+
+Level 1 or 2 headers can be made as the follows
+
+ This is a level 1 header
+ ========================
+
+ This is a level 2 header
+ ------------------------
+
+A header is followed by a line containing only ='s or -'s.
+Note that the exact amount of ='s or -'s is not important as long as
+there are at least two.
+
+Alternatively, you can use #'s at the start of a line to make a header.
+The number of #'s at the start of the line determines the level (up to 6 levels are supported).
+You can end a header by any number of #'s.
+
+Here is an example:
+
+ # This is a level 1 header
+
+ ### This is level 3 header #######
+
+\subsection md_blockquotes Block quotes
+
+Block quotes can be created by starting each line with one or more >'s,
+similar to what is used in text-only emails.
+
+ > This is a block quote
+ > spanning multiple lines
+
+Lists and code blocks (see below) can appear inside a quote block.
+Quote blocks can also be nested.
+
+Note that doxygen requires that you put a space after the (last) > character
+to avoid false positives, i.e. when writing
+
+ 0 if OK\n
+ >1 if NOK
+
+the second line will not be seen as a block quote.
+
+\subsection md_lists Lists
+
+Simple bullet lists can be made by starting a line with -, +, or *.
+
+ - Item 1
+
+ More text for this item.
+
+ - Item 2
+ + nested list item.
+ + another nested item.
+ - Item 3
+
+List items can span multiple paragraphs (if each paragraph starts with
+the proper indentation) and lists can be nested.
+You can also make a numbered list like so
+
+ 1. First item.
+ 2. Second item.
+
+Make sure to also read \ref mddox_lists for doxygen specifics.
+
+\subsection md_codeblock Code Blocks
+
+Preformatted verbatim blocks can be created by indenting
+each line in a block of text by at least 4 extra spaces
+
+ This a normal paragraph
+
+ This is a code block
+
+ We continue with a normal paragraph again.
+
+Doxygen will remove the mandatory indentation from the code block.
+Note that you cannot start a code block in the middle of a paragraph
+(i.e. the line preceding the code block must be empty).
+
+See section \ref mddox_code_blocks for more info how doxygen handles
+indentation as this is slightly different than standard Markdown.
+
+\subsection md_rulers Horizontal Rulers
+
+A horizontal ruler will be produced for lines containing at least three or more
+hyphens, asterisks, or underscores. The line may also include any amount of whitespace.
+
+Examples:
+
+ - - -
+ ______
+
+Note that using asterisks in comment blocks does not work. See
+\ref mddox_stars for details.
+
+\subsection md_emphasis Emphasis
+
+To emphasize a text fragment you start and end the fragment with an underscore or star.
+Using two stars or underscores will produce strong emphasis.
+
+Examples:
+
+ *single asterisks*
+
+ _single underscores_
+
+ **double asterisks**
+
+ __double underscores__
+
+See section \ref mddox_emph_spans for more info how doxygen handles
+emphasis spans slightly different than standard Markdown.
+
+\subsection md_codespan code spans
+
+To indicate a span of code, you should wrap it in backticks (`). Unlike code blocks,
+code spans appear inline in a paragraph. An example:
+
+ Use the `printf()` function.
+
+To show a literal backtick inside a code span use double backticks, i.e.
+
+ To assign the output of command `ls` to `var` use ``var=`ls```.
+
+See section \ref mddox_code_spans for more info how doxygen handles
+code spans slightly different than standard Markdown.
+
+\subsection md_links Links
+
+Doxygen supports both styles of make links defined by Markdown: *inline* and *reference*.
+
+For both styles the link definition starts with the link text delimited by [square
+brackets].
+
+\subsubsection md_inlinelinks Inline Links
+
+For an inline link the link text is followed by a URL and an optional link title which
+together are enclosed in a set of regular parenthesis.
+The link title itself is surrounded by quotes.
+
+Examples:
+
+ [The link text](http://example.net/)
+ [The link text](http://example.net/ "Link title")
+ [The link text](/relative/path/to/index.html "Link title")
+ [The link text](somefile.html)
+
+In addition doxygen provides a similar way to link a documented entity:
+
+ [The link text](@ref MyClass)
+
+\subsubsection md_reflinks Reference Links
+
+Instead of putting the URL inline, you can also define the link separately
+and then refer to it from within the text.
+
+The link definition looks as follows:
+
+ [link name]: http://www.example.com "Optional title"
+
+Instead of double quotes also single quotes or parenthesis can
+be used for the title part.
+
+Once defined, the link looks as follows
+
+ [link text][link name]
+
+If the link text and name are the same, also
+
+ [link name][]
+
+or even
+
+ [link name]
+
+can be used to refer to the link.
+Note that the link name matching is not case sensitive
+as is shown in the following example:
+
+ I get 10 times more traffic from [Google] than from
+ [Yahoo] or [MSN].
+
+ [google]: http://google.com/ "Google"
+ [yahoo]: http://search.yahoo.com/ "Yahoo Search"
+ [msn]: http://search.msn.com/ "MSN Search"
+
+Link definitions will not be visible in the output.
+
+Like for inline links doxygen also supports \@ref inside a link definition:
+
+ [myclass]: @ref MyClass "My class"
+
+\subsection md_images Images
+
+Markdown syntax for images is similar to that for links.
+The only difference is an additional ! before the link text.
+
+Examples:
+
+ 
+ 
+ ![Caption text][img def]
+ ![img def]
+
+ [img def]: /path/to/img.jpg "Optional Title"
+
+Also here you can use \@ref to link to an image:
+
+ 
+ ![img def]
+
+ [img def]: @ref image.png "Caption text"
+
+The caption text is optional.
+
+\subsection md_autolink Automatic Linking
+
+To create a link to an URL or e-mail address Markdown supports the following
+syntax:
+
+ <http://www.example.com>
+ <https://www.example.com>
+ <ftp://www.example.com>
+ <mailto:address at example.com>
+ <address at example.com>
+
+Note that doxygen will also produce the links without the angle brackets.
+
+\section markdown_extra Markdown Extensions
+
+\subsection md_toc Table of Contents
+
+Doxygen supports a special link marker `[TOC]` which can be placed in a page
+to produce a table of contents at the start of the page, listing all sections.
+
+Note that using `[TOC]` is the same as using a
+\ref cmdtableofcontents "\\tableofcontents" command.
+
+\subsection md_tables Tables
+
+Of the features defined by "Markdown Extra" is support for
+<a href="http://michelf.com/projects/php-markdown/extra/#table">simple tables</a>:
+
+A table consists of a header line, a separator line, and at least one
+row line. Table columns are separated by the pipe (|) character.
+
+Here is an example:
+
+ First Header | Second Header
+ ------------- | -------------
+ Content Cell | Content Cell
+ Content Cell | Content Cell
+
+which will produce the following table:
+
+First Header | Second Header
+------------- | -------------
+Content Cell | Content Cell
+Content Cell | Content Cell
+
+Column alignment can be controlled via one or two colons
+at the header separator line:
+
+ | Right | Center | Left |
+ | ----: | :----: | :---- |
+ | 10 | 10 | 10 |
+ | 1000 | 1000 | 1000 |
+
+which will look as follows:
+
+| Right | Center | Left |
+| ----: | :----: | :---- |
+| 10 | 10 | 10 |
+| 1000 | 1000 | 1000 |
+
+\subsection md_fenced Fenced Code Blocks
+
+Another feature defined by "Markdown Extra" is support for
+<a href="http://michelf.com/projects/php-markdown/extra/#fenced-code-blocks">
+fenced code blocks</a>:
+
+A fenced code block does not require indentation, and is
+defined by a pair of "fence lines". Such a line consists of 3 or
+more tilde (~) characters on a line. The end of the block should have the
+same number of tildes. Here is an example:
+
+
+ This is a paragraph introducing:
+
+ ~~~~~~~~~~~~~~~~~~~~~
+ a one-line code block
+ ~~~~~~~~~~~~~~~~~~~~~
+
+By default the output is the same as for a normal code block.
+
+For languages supported by doxygen you can also make the code block
+appear with syntax highlighting. To do so you need to
+indicate the typical file extension that corresponds to the
+programming language after the opening fence. For highlighting according
+to the Python language for instance, you would need to write the following:
+
+ ~~~~~~~~~~~~~{.py}
+ # A class
+ class Dummy:
+ pass
+ ~~~~~~~~~~~~~
+
+which will produce:
+~~~~~~~~~~~~~{.py}
+# A class
+class Dummy:
+ pass
+~~~~~~~~~~~~~
+
+and for C you would write:
+
+ ~~~~~~~~~~~~~~~{.c}
+ int func(int a,int b) { return a*b; }
+ ~~~~~~~~~~~~~~~
+
+which will produce:
+
+~~~~~~~~~~~~~~~{.c}
+int func(int a,int b) { return a*b; }
+~~~~~~~~~~~~~~~
+
+The curly braces and dot are optional by the way.
+
+\subsection md_header_id Header Id Attributes
+
+Standard Markdown has no support for labeling headers, which
+is a problem if you want to link to a section.
+
+PHP Markdown Extra allows you to label a header by adding
+the following to the header
+
+ Header 1 {#labelid}
+ ========
+
+ ## Header 2 ## {#labelid2}
+
+To link to a section in the same comment block you can use
+
+ [Link text](#labelid)
+
+to link to a section in general, doxygen allows you to use \@ref
+
+ [Link text](@ref labelid)
+
+Note this only works for the headers of level 1 to 4.
+
+\section markdown_dox Doxygen specifics
+
+Even though doxygen tries to following the Markdown standard as closely as
+possible, there are couple of deviation and doxygen specifics additions.
+
+\subsection md_page_header Including Markdown files as pages
+
+Doxygen can process files with Markdown formatting.
+For this to work the extension for such a file should
+be `.md` or `.markdown` (see
+\ref cfg_extension_mapping "EXTENSION_MAPPING" if your Markdown files have
+a different extension, and use `md` as the name of the parser).
+Each file is converted to a page (see the \ref cmdpage "page" command for
+details).
+
+By default the name and title of the page are derived from the file name.
+If the file starts with a level 1 header however, it is used as the title
+of the page. If you specify a label for the
+header (as shown \ref md_header_id "here") doxygen will use that as the
+page name.
+
+If the label is called `index` or `mainpage` doxygen will put the
+documentation on the front page (`index.html`).
+
+Here is an example of a file `README.md` that will appear as the main page
+when processed by doxygen:
+
+ My Main Page {#mainpage}
+ ============
+
+ Documentation that will appear on the main page
+
+If a page has a label you can link to it using \ref cmdref "\@ref" as
+is shown above. To refer to a markdown page without
+such label you can simple use the file name of the page, e.g.
+
+ See [the other page](other.md) for more info.
+
+\subsection md_html_blocks Treatment of HTML blocks
+
+Markdown is quite strict in the way it processes block-level HTML:
+
+> block-level HTML elements — e.g.
+> `<div>`, `<table>`, `<pre>`, `<p>`, etc. —
+> must be separated from surrounding content by blank lines,
+> and the start and end tags of the block should not be indented
+> with tabs or spaces.
+
+Doxygen does not have this requirement, and will also process
+Markdown formatting inside such HTML blocks. The only exception is
+`<pre>` blocks, which are passed untouched (handy for ASCII art).
+
+Doxygen will not process Markdown formatting inside verbatim or code blocks,
+and in other sections that need to be processed without changes
+(for instance formulas or inline dot graphs).
+
+\subsection mddox_code_blocks Code Block Indentation
+
+Markdown allows both a single tab or 4 spaces to start a code block.
+Since doxygen already replaces tabs by spaces before doing Markdown
+processing, the effect will only be same if TAB_SIZE in the config file
+has been set to 4. When it is set to a higher value spaces will be
+present in the code block. A lower value will prevent a single tab to be
+interpreted as the start of a code block.
+
+With Markdown any block that is indented by 4 spaces (and 8 spaces
+inside lists) is treated as a code block. This indentation amount
+is absolute, i.e. counting from the start of the line.
+
+Since doxygen comments can appear at any indentation level
+that is required by the programming language, it
+uses a relative indentation instead. The amount of
+indentation is counted relative to the preceding paragraph.
+In case there is no preceding paragraph (i.e. you want to start with a
+code block), the minimal amount of indentation of the whole comment block
+is used as a reference.
+
+In most cases this difference does not result in different output.
+Only if you play with the indentation of paragraphs the difference
+is noticeable:
+
+ text
+
+ text
+
+ text
+
+ code
+
+In this case Markdown will put the word code in a code block,
+whereas Doxygen will treat it as normal text, since although the absolute
+indentation is 4, the indentation with respect to the previous paragraph
+is only 1.
+
+Note that list markers are not counted when determining the
+relative indent:
+
+ 1. Item1
+
+ More text for item1
+
+ 2. Item2
+
+ Code block for item2
+
+For Item1 the indentation is 4 (when treating the list marker as whitespace),
+so the next paragraph "More text..." starts at the same indentation level
+and is therefore not seen as a code block.
+
+\subsection mddox_emph_spans Emphasis limits
+
+Unlike standard Markdown, doxygen will not touch internal underscores or
+stars, so the following will appear as-is:
+
+ a_nice_identifier
+
+Furthermore, a `*` or `_` only starts an emphasis if
+- it is followed by an alphanumerical character, and
+- it is preceded by a space, newline, or one the following characters `<{([,:;`
+
+An emphasis ends if
+- it is not followed by an alphanumerical character, and
+- it is not preceded by a space, newline, or one the following characters `({[<=+-\@`
+
+Lastly, the span of the emphasis is limited to a single paragraph.
+
+
+\subsection mddox_code_spans Code Spans Limits
+
+Note that unlike standard Markdown, doxygen leaves the following untouched.
+
+ A `cool' word in a `nice' sentence.
+
+In other words; a single quote cancels the special treatment of a code span
+wrapped in a pair of backtick characters. This extra restriction was
+added for backward compatibility reasons.
+
+\subsection mddox_lists Lists Extensions
+
+With Markdown two lists separated by an empty line are joined together into
+a single list which can be rather unexpected and many people consider it to
+be a bug. Doxygen, however, will make two separate lists as you would expect.
+
+Example:
+
+ - Item1 of list 1
+ - Item2 of list 1
+
+ 1. Item1 of list 2
+ 2. Item2 of list 2
+
+With Markdown the actual numbers you use to mark the list have no
+effect on the HTML output Markdown produces. I.e. standard Markdown treats the
+following as one list with 3 numbered items:
+
+ 1. Item1
+ 1. Item2
+ 1. Item3
+
+Doxygen however requires that the numbers used as marks are in
+strictly ascending order, so the above example would produce 3 lists
+with one item. An item with an equal or lower number than
+the preceding item, will start a new list. For example:
+
+ 1. Item1 of list 1
+ 3. Item2 of list 1
+ 2. Item1 of list 2
+ 4. Item2 of list 2
+
+will produce:
+
+1. Item1 of list 1
+3. Item2 of list 1
+2. Item1 of list 2
+4. Item2 of list 2
+
+Historically doxygen has an additional way to create numbered
+lists by using `-#` markers:
+
+ -# item1
+ -# item2
+
+\subsection mddox_stars Use of asterisks
+
+Special care has to be taken when using *'s in a comment block
+to start a list or make a ruler.
+
+Doxygen will strip off any leading *'s from the comment before doing
+Markdown processing. So although the following works fine
+
+ at verbatim
+ /** A list:
+ * * item1
+ * * item2
+ */
+ at endverbatim
+
+When you remove the leading *'s doxygen will strip the other stars
+as well, making the list disappear!
+
+Rulers created with *'s will not be visible at all. They only work
+in Markdown files.
+
+\subsection mddox_limits Limits on markup scope
+
+To avoid that a stray * or _ matches something many paragraphs later,
+and shows everything in between with emphasis, doxygen limits the scope
+of a * and _ to a single paragraph.
+
+For a code span, between the starting and ending backtick only two
+new lines are allowed.
+
+Also for links there are limits; the link text, and link title each can
+contain only one new line, the URL may not contain any newlines.
+
+\section markdown_debug Debugging of problems
+
+When doxygen parses the source code it first extracts the comments blocks,
+then passes these through the Markdown preprocessor. The output of the
+Markdown preprocessing consists of text with \ref cmd_intro "special commands"
+and \ref htmlcmds "HTML commands".
+A second pass takes the output of the Markdown preprocessor and
+converts it into the various output formats.
+
+During Markdown preprocessing no errors are produced. Anything that
+does not fit the Markdown syntax is simply passed on as-is. In the subsequent
+parsing phase this could lead to errors, which may not always be obvious
+as they are based on the intermediate format.
+
+To see the result after Markdown processing you can run doxygen with the
+`-d Markdown` option. It will then print each comment block before and
+after Markdown processing.
+
+\htmlonly
+Go to the <a href="lists.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/output.doc b/doc/output.doc
new file mode 100644
index 0000000..2cb81bd
--- /dev/null
+++ b/doc/output.doc
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page output Output Formats
+
+\addindex output formats
+
+The following output formats are \e directly supported by doxygen:
+<dl>
+<dt><b>HTML</b>
+<dd>Generated if \ref cfg_generate_html "GENERATE_HTML" is set to \c YES in the configuration file.
+<dt>\LaTeX
+<dd>Generated if \ref cfg_generate_latex "GENERATE_LATEX" is set to \c YES in the configuration file.
+<dt><b>Man pages</b>
+<dd>Generated if \ref cfg_generate_man "GENERATE_MAN" is set to \c YES in the configuration file.
+<dt><b>RTF</b>
+<dd>Generated if \ref cfg_generate_rtf "GENERATE_RTF" is set to \c YES in the configuration file.<p>
+ Note that the RTF output probably only looks nice with Microsoft's
+ Word. If you have success with other programs, please let me know.
+<dt><b>XML</b>
+<dd>Generated if \ref cfg_generate_xml "GENERATE_XML" is set to \c YES in the configuration file.<p>
+<dt><b>Docbook</b>
+<dd>Generated if \ref cfg_generate_docbook "GENERATE_DOCBOOOK" is set to \c YES in the configuration file.<p>
+</dl>
+
+The following output formats are \e indirectly supported by doxygen:
+<dl>
+<dt><b>Compiled HTML Help</b> (a.k.a. Windows 98 help)
+<dd>Generated by Microsoft's HTML Help workshop from the HTML output if
+ \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" is set to \c YES.
+<dt><b>Qt Compressed Help (.qch)</b>
+<dd>Generated by Qt's qhelpgenerator tool from the HTML output if
+ \ref cfg_generate_qhp "GENERATE_QHP" is set to \c YES.
+<dt><b>Eclipse Help</b>
+<dd>Generated from HTML with a special index file that is generated when
+ \ref cfg_generate_eclipsehelp "GENERATE_ECLIPSEHELP" is set to \c YES.
+<dt><b>XCode DocSets</b>
+<dd>Compiled from HTML with a special index file that is generated when
+ \ref cfg_generate_docset "GENERATE_DOCSET" is set to \c YES.
+<dt><b>PostScript</b>
+<dd>Generated from the \LaTeX output by
+ running <code>make ps</code> in the output directory.
+ For the best results \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS" should be set to \c NO.
+<dt><b>PDF</b>\htmlonly \endhtmlonly
+<dd>Generated from the \LaTeX output by
+ running <code>make pdf</code> in the output directory.
+ To improve the PDF output, you typically would want to enable the use
+ of \c pdflatex by setting \ref cfg_use_pdflatex "USE_PDFLATEX" to \c YES in the
+ configuration file. In order to get hyperlinks in the PDF file you also need to enable
+ \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS".
+</dl>
+
+
+\htmlonly
+Go to the <a href="searching.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/perlmod.doc b/doc/perlmod.doc
new file mode 100644
index 0000000..8616dc6
--- /dev/null
+++ b/doc/perlmod.doc
@@ -0,0 +1,201 @@
+/*! \page perlmod Perl Module Output
+
+\addindex perlmod
+
+<p>Since version 1.2.18, Doxygen can generate a new output format we
+have called the "Perl Module output format". It has been
+designed as an intermediate format that can be used to generate new
+and customized output without having to modify the Doxygen source.
+Therefore, its purpose is similar to the XML output format that can be
+also generated by Doxygen. The XML output format is more standard,
+but the Perl Module output format is possibly simpler and easier to
+use.
+
+<p>The Perl Module output format is still experimental at the moment
+and could be changed in incompatible ways in future versions, although
+this should not be very probable. It is also lacking some features of
+other Doxygen backends. However, it can be already used to generate
+useful output, as shown by the Perl Module-based \LaTeX generator.
+
+<p>Please report any bugs or problems you find in the Perl Module
+backend or the Perl Module-based \LaTeX generator to the
+doxygen-develop mailing list. Suggestions are welcome as well.
+
+\section using_perlmod_fmt Usage
+
+<p>When the \ref cfg_generate_perlmod "GENERATE_PERLMOD" tag is enabled in the Doxyfile,
+running Doxygen generates a number of files in the `perlmod/`
+subdirectory of your output directory. These files are the following:
+
+<ul>
+
+<li>`DoxyDocs.pm`: This is the Perl module that actually
+contains the documentation, in the Perl Module format described
+\ref doxydocs_format "below".
+
+<li>`DoxyModel.pm`: This Perl module describes the structure of
+`DoxyDocs.pm`, independently of the actual documentation. See
+\ref doxymodel_format "below" for details.
+
+<li>`doxyrules.make`: This file contains the make rules to build
+and clean the files that are generated from the Doxyfile. Also
+contains the paths to those files and other relevant information. This
+file is intended to be included by your own Makefile.
+
+<li>`Makefile`: This is a simple Makefile including
+`doxyrules.make`.
+
+</ul>
+
+<p>To make use of the documentation stored in DoxyDocs.pm you can use
+one of the default Perl Module-based generators provided by Doxygen
+(at the moment this includes the Perl Module-based \LaTeX generator,
+see \ref perlmod_latex "below") or write your own customized
+generator. This should not be too hard if you have some knowledge of
+Perl and it's the main purpose of including the Perl Module backend in
+Doxygen. See \ref doxydocs_format "below" for details on how
+to do this.
+
+<-- want to use \LaTeX but not possible in headings -->
+\section perlmod_latex Using the LaTeX generator.
+
+<p>The Perl Module-based \LaTeX generator is pretty experimental and
+incomplete at the moment, but you could find it useful nevertheless.
+It can generate documentation for functions, typedefs and variables
+within files and classes and can be customized quite a lot by
+redefining \TeX macros. However, there is still no documentation on
+how to do this.
+
+<p>Setting the \ref cfg_perlmod_latex "PERLMOD_LATEX" tag to \c YES in the
+\c Doxyfile enables the creation of some additional files in the `perlmod/`
+subdirectory of your output directory. These files contain the Perl
+scripts and \LaTeX code necessary to generate PDF and DVI output from
+the Perl Module output, using `pdflatex` and `latex` respectively. Rules
+to automate the use of these files are also added to
+`doxyrules.make` and the `Makefile`.
+
+<p>The additional generated files are the following:
+
+<ul>
+
+<li>`doxylatex.pl`: This Perl script uses `DoxyDocs.pm` and
+DoxyModel.pm to generate `doxydocs.tex`, a \TeX file containing
+the documentation in a format that can be accessed by \LaTeX code. This
+file is not directly LaTeXable.
+
+<li>`doxyformat.tex`: This file contains the \LaTeX code that
+transforms the documentation from doxydocs.tex into \LaTeX text
+suitable to be \LaTeX'ed and presented to the user.
+
+<li>`doxylatex-template.pl`: This Perl script uses `DoxyModel.pm`
+to generate `doxytemplate.tex`, a \TeX file defining default
+values for some macros. doxytemplate.tex is included by
+doxyformat.tex to avoid the need of explicitly defining some macros.
+
+<li>`doxylatex.tex`: This is a very simple \LaTeX document that
+loads some packages and includes doxyformat.tex and doxydocs.tex. This
+document is \LaTeX'ed to produce the PDF and DVI documentation by the
+rules added to `doxyrules.make`.
+
+</ul>
+
+\subsection pm_pdf_gen Creation of PDF and DVI output
+
+<p>To try this you need to have installed `latex`, `pdflatex` and the
+packages used by `doxylatex.tex`.
+
+<ol>
+
+<li>Update your `Doxyfile` to the latest version using:
+
+<pre>doxygen -u Doxyfile</pre>
+
+<li>Set both \ref cfg_generate_perlmod "GENERATE_PERLMOD" and
+\ref cfg_perlmod_latex "PERLMOD_LATEX" tags to
+\c YES in your Doxyfile.
+
+<li>Run Doxygen on your Doxyfile:
+
+<pre>doxygen Doxyfile</pre>
+
+<li>A `perlmod/` subdirectory should have appeared in your output
+directory. Enter the `perlmod/` subdirectory and run:
+
+<pre>make pdf</pre>
+
+<p>This should generate a `doxylatex.pdf` with the documentation
+in PDF format.
+
+<li>Run:
+
+<pre>make dvi</pre>
+
+<p>This should generate a `doxylatex.dvi` with the documentation
+in DVI format.
+
+</ol>
+
+\section doxydocs_format Documentation format.
+
+<p>The Perl Module documentation generated by Doxygen is stored in
+`DoxyDocs.pm`. This is a very simple Perl module that contains
+only two statements: an assignment to the variable `$doxydocs` and
+the customary `1;` statement which usually ends Perl modules.
+The documentation is stored in the variable `$doxydocs`, which
+can then be accessed by a Perl script using `DoxyDocs.pm`.
+
+<p>`$doxydocs` contains a tree-like structure composed of three
+types of nodes: strings, hashes and lists.
+
+<ul>
+
+<li>`Strings`: These are normal Perl strings. They can be of
+any length can contain any character. Their semantics depends on
+their location within the tree. This type of node has no children.
+
+<li>`Hashes`: These are references to anonymous Perl hashes. A
+hash can have multiple fields, each with a different key. The value
+of a hash field can be a string, a hash or a list, and its semantics
+depends on the key of the hash field and the location of the hash
+within the tree. The values of the hash fields are the children of
+the node.
+
+<li>`Lists`: These are references to anonymous Perl lists. A
+list has an undefined number of elements, which are the children of
+the node. Each element has the same type (string, hash or list) and
+the same semantics, depending on the location of the list within the
+tree.
+
+</ul>
+
+<p>As you can see, the documentation contained in `$doxydocs`
+does not present any special impediment to be processed by a simple
+Perl script.
+<!--
+To be able to generate meaningful output using the
+documentation contained in `$doxydocs` you'll probably need to
+know the semantics of the nodes of the documentation tree, which we
+present in \ref perlmod_tree "this page".
+-->
+
+\section doxymodel_format Data structure
+
+<p>You might be interested in processing the documentation contained
+in `DoxyDocs.pm` without needing to take into account the
+semantics of each node of the documentation tree. For this purpose,
+Doxygen generates a `DoxyModel.pm` file which contains a data
+structure describing the type and children of each node in the
+documentation tree.
+
+<p>The rest of this section is to be written yet, but in the meantime
+you can look at the Perl scripts generated by Doxygen (such as
+`doxylatex.pl` or `doxytemplate-latex.pl`) to get an idea on
+how to use `DoxyModel.pm`.
+
+
+\htmlonly
+Go to the <a href="perlmod_tree.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/perlmod_tree.doc b/doc/perlmod_tree.doc
new file mode 100644
index 0000000..a936320
--- /dev/null
+++ b/doc/perlmod_tree.doc
@@ -0,0 +1,383 @@
+/*! \page perlmod_tree Perl Module Tree Nodes
+
+<h2>Nodes in the documentation tree of the Perl Module output
+format.</h2>
+
+This is a description of the structure of the documentation tree in
+<b>DoxyDocs.pm</b>. Each item in the list below describes a node in
+the tree, and the format of the description is as follows:
+
+<ul>
+<li>[ key => ] <b>Name</b> <i>(type)</i>. Explanation of the content.
+</ul>
+
+Where
+
+<ul>
+
+<li>The "key =>" part only appears if the parent node is a hash.
+"key" is the key for this node.
+
+<li><b>"Name"</b> is a unique name for the node, defined in
+DoxyModel.pm.
+
+<li><i>"(type)"</i> is the type of the node: "string" for string
+nodes, "hash" for hash nodes, "list" for list nodes, and "doc" for
+documentation subtrees. The structure of documentation subtrees is
+not described anywhere yet, but you can look for example at
+<b>doxylatex.pl</b> to see how to process it.
+
+</ul>
+
+The meaning of each node in the documentation tree is as follows:
+<ul>
+<li> <b>Root</b> <i>(hash)</i>. Root node.
+<ul>
+<li>classes => <b>Classes</b> <i>(list)</i>. Documented classes.
+<ul>
+<li> <b>Class</b> <i>(hash)</i>. A documented class.
+<ul>
+<li>protected_members => <b>ClassProtectedMembers</b> <i>(hash)</i>. Information about the protected members in the class.
+<ul>
+<li>members => <b>ClassProtectedMemberList</b> <i>(list)</i>. protected member list.
+<ul>
+<li> <b>ClassProtectedMember</b> <i>(hash)</i>. A protected member.
+<ul>
+<li>protection => <b>ClassProtectedMemberProtection</b> <i>(string)</i>. Protection of the protected member.
+<li>detailed => <b>ClassProtectedMemberDetailed</b> <i>(hash)</i>. Detailed information about the protected member.
+<ul>
+<li>doc => <b>ClassProtectedMemberDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the protected member.
+<li>see => <b>ClassProtectedMemberSee</b> <i>(doc)</i>. "See also" documentation for the protected member.
+</ul>
+<li>kind => <b>ClassProtectedMemberKind</b> <i>(string)</i>. Kind of protected member (usually "variable").
+<li>name => <b>ClassProtectedMemberName</b> <i>(string)</i>. Name of the protected member.
+<li>type => <b>ClassProtectedMemberType</b> <i>(string)</i>. Data type of the protected member.
+</ul>
+</ul>
+</ul>
+<li>detailed => <b>ClassDetailed</b> <i>(hash)</i>. Detailed information about the class.
+<ul>
+<li>doc => <b>ClassDetailedDoc</b> <i>(doc)</i>. Detailed documentation block for the class.
+</ul>
+<li>protected_typedefs => <b>ClassProtectedTypedefs</b> <i>(hash)</i>. Information about the protected typedefs in the class.
+<ul>
+<li>members => <b>ClassProtectedTypedefList</b> <i>(list)</i>. protected typedef list.
+<ul>
+<li> <b>ClassProtectedTypedef</b> <i>(hash)</i>. A protected typedef.
+<ul>
+<li>protection => <b>ClassProtectedTypedefProtection</b> <i>(string)</i>. Protection of the protected typedef.
+<li>detailed => <b>ClassProtectedTypedefDetailed</b> <i>(hash)</i>. Detailed information about the protected typedef.
+<ul>
+<li>doc => <b>ClassProtectedTypedefDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the protected typedef.
+<li>see => <b>ClassProtectedTypedefSee</b> <i>(doc)</i>. "See also" documentation for the protected typedef.
+</ul>
+<li>kind => <b>ClassProtectedTypedefKind</b> <i>(string)</i>. Kind of protected typedef (usually "typedef").
+<li>name => <b>ClassProtectedTypedefName</b> <i>(string)</i>. Name of the protected typedef.
+<li>type => <b>ClassProtectedTypedefType</b> <i>(string)</i>. Data type of the protected typedef.
+</ul>
+</ul>
+</ul>
+<li>name => <b>ClassName</b> <i>(string)</i>. Name of the class.
+<li>private_members => <b>ClassPrivateMembers</b> <i>(hash)</i>. Information about the private members in the class.
+<ul>
+<li>members => <b>ClassPrivateMemberList</b> <i>(list)</i>. private member list.
+<ul>
+<li> <b>ClassPrivateMember</b> <i>(hash)</i>. A private member.
+<ul>
+<li>protection => <b>ClassPrivateMemberProtection</b> <i>(string)</i>. Protection of the private member.
+<li>detailed => <b>ClassPrivateMemberDetailed</b> <i>(hash)</i>. Detailed information about the private member.
+<ul>
+<li>doc => <b>ClassPrivateMemberDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the private member.
+<li>see => <b>ClassPrivateMemberSee</b> <i>(doc)</i>. "See also" documentation for the private member.
+</ul>
+<li>kind => <b>ClassPrivateMemberKind</b> <i>(string)</i>. Kind of private member (usually "variable").
+<li>name => <b>ClassPrivateMemberName</b> <i>(string)</i>. Name of the private member.
+<li>type => <b>ClassPrivateMemberType</b> <i>(string)</i>. Data type of the private member.
+</ul>
+</ul>
+</ul>
+<li>private_typedefs => <b>ClassPrivateTypedefs</b> <i>(hash)</i>. Information about the private typedefs in the class.
+<ul>
+<li>members => <b>ClassPrivateTypedefList</b> <i>(list)</i>. private typedef list.
+<ul>
+<li> <b>ClassPrivateTypedef</b> <i>(hash)</i>. A private typedef.
+<ul>
+<li>protection => <b>ClassPrivateTypedefProtection</b> <i>(string)</i>. Protection of the private typedef.
+<li>detailed => <b>ClassPrivateTypedefDetailed</b> <i>(hash)</i>. Detailed information about the private typedef.
+<ul>
+<li>doc => <b>ClassPrivateTypedefDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the private typedef.
+<li>see => <b>ClassPrivateTypedefSee</b> <i>(doc)</i>. "See also" documentation for the private typedef.
+</ul>
+<li>kind => <b>ClassPrivateTypedefKind</b> <i>(string)</i>. Kind of private typedef (usually "typedef").
+<li>name => <b>ClassPrivateTypedefName</b> <i>(string)</i>. Name of the private typedef.
+<li>type => <b>ClassPrivateTypedefType</b> <i>(string)</i>. Data type of the private typedef.
+</ul>
+</ul>
+</ul>
+<li>protected_methods => <b>ClassProtectedMethods</b> <i>(hash)</i>. Information about the protected methods in the class.
+<ul>
+<li>members => <b>ClassProtectedMethodList</b> <i>(list)</i>. protected method list.
+<ul>
+<li> <b>ClassProtectedMethod</b> <i>(hash)</i>. A protected method.
+<ul>
+<li>parameters => <b>ClassProtectedMethodParams</b> <i>(list)</i>. List of the parameters of the protected method.
+<ul>
+<li> <b>ClassProtectedMethodParam</b> <i>(hash)</i>. A parameter of the protected method.
+<ul>
+<li>declaration_name => <b>ClassProtectedMethodParamName</b> <i>(string)</i>. The name of the parameter.
+<li>type => <b>ClassProtectedMethodParamType</b> <i>(string)</i>. The data type of the parameter.
+</ul>
+</ul>
+<li>protection => <b>ClassProtectedMethodProtection</b> <i>(string)</i>. Protection of the protected method.
+<li>virtualness => <b>ClassProtectedMethodVirtualness</b> <i>(string)</i>. Virtualness of the protected method.
+<li>detailed => <b>ClassProtectedMethodDetailed</b> <i>(hash)</i>. Detailed information about the protected method.
+<ul>
+<li>params => <b>ClassProtectedMethodPDBlocks</b> <i>(list)</i>. List of parameter documentation blocks for the protected method.
+<ul>
+<li> <b>ClassProtectedMethodPDBlock</b> <i>(hash)</i>. A parameter documentation block for the protected method.
+<ul>
+<li>parameters => <b>ClassProtectedMethodPDParams</b> <i>(list)</i>. Parameter list for this parameter documentation block.
+<ul>
+<li> <b>ClassProtectedMethodPDParam</b> <i>(hash)</i>. A parameter documented by this documentation block.
+<ul>
+<li>name => <b>ClassProtectedMethodPDParamName</b> <i>(string)</i>. Name of the parameter.
+</ul>
+</ul>
+<li>doc => <b>ClassProtectedMethodPDDoc</b> <i>(doc)</i>. Documentation for this parameter documentation block.
+</ul>
+</ul>
+<li>doc => <b>ClassProtectedMethodDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the protected method.
+<li>see => <b>ClassProtectedMethodSee</b> <i>(doc)</i>. "See also" documentation for the protected method.
+<li>return => <b>ClassProtectedMethodReturn</b> <i>(doc)</i>. Documentation about the return value of the protected method.
+</ul>
+<li>kind => <b>ClassProtectedMethodKind</b> <i>(string)</i>. Kind of protected method (usually "function").
+<li>name => <b>ClassProtectedMethodName</b> <i>(string)</i>. Name of the protected method.
+<li>type => <b>ClassProtectedMethodType</b> <i>(string)</i>. Data type returned by the protected method.
+<li>static => <b>ClassProtectedMethodStatic</b> <i>(string)</i>. Whether the protected method is static.
+</ul>
+</ul>
+</ul>
+<li>public_typedefs => <b>ClassPublicTypedefs</b> <i>(hash)</i>. Information about the public typedefs in the class.
+<ul>
+<li>members => <b>ClassPublicTypedefList</b> <i>(list)</i>. public typedef list.
+<ul>
+<li> <b>ClassPublicTypedef</b> <i>(hash)</i>. A public typedef.
+<ul>
+<li>protection => <b>ClassPublicTypedefProtection</b> <i>(string)</i>. Protection of the public typedef.
+<li>detailed => <b>ClassPublicTypedefDetailed</b> <i>(hash)</i>. Detailed information about the public typedef.
+<ul>
+<li>doc => <b>ClassPublicTypedefDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the public typedef.
+<li>see => <b>ClassPublicTypedefSee</b> <i>(doc)</i>. "See also" documentation for the public typedef.
+</ul>
+<li>kind => <b>ClassPublicTypedefKind</b> <i>(string)</i>. Kind of public typedef (usually "typedef").
+<li>name => <b>ClassPublicTypedefName</b> <i>(string)</i>. Name of the public typedef.
+<li>type => <b>ClassPublicTypedefType</b> <i>(string)</i>. Data type of the public typedef.
+</ul>
+</ul>
+</ul>
+<li>public_members => <b>ClassPublicMembers</b> <i>(hash)</i>. Information about the public members in the class.
+<ul>
+<li>members => <b>ClassPublicMemberList</b> <i>(list)</i>. public member list.
+<ul>
+<li> <b>ClassPublicMember</b> <i>(hash)</i>. A public member.
+<ul>
+<li>protection => <b>ClassPublicMemberProtection</b> <i>(string)</i>. Protection of the public member.
+<li>detailed => <b>ClassPublicMemberDetailed</b> <i>(hash)</i>. Detailed information about the public member.
+<ul>
+<li>doc => <b>ClassPublicMemberDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the public member.
+<li>see => <b>ClassPublicMemberSee</b> <i>(doc)</i>. "See also" documentation for the public member.
+</ul>
+<li>kind => <b>ClassPublicMemberKind</b> <i>(string)</i>. Kind of public member (usually "variable").
+<li>name => <b>ClassPublicMemberName</b> <i>(string)</i>. Name of the public member.
+<li>type => <b>ClassPublicMemberType</b> <i>(string)</i>. Data type of the public member.
+</ul>
+</ul>
+</ul>
+<li>private_methods => <b>ClassPrivateMethods</b> <i>(hash)</i>. Information about the private methods in the class.
+<ul>
+<li>members => <b>ClassPrivateMethodList</b> <i>(list)</i>. private method list.
+<ul>
+<li> <b>ClassPrivateMethod</b> <i>(hash)</i>. A private method.
+<ul>
+<li>parameters => <b>ClassPrivateMethodParams</b> <i>(list)</i>. List of the parameters of the private method.
+<ul>
+<li> <b>ClassPrivateMethodParam</b> <i>(hash)</i>. A parameter of the private method.
+<ul>
+<li>declaration_name => <b>ClassPrivateMethodParamName</b> <i>(string)</i>. The name of the parameter.
+<li>type => <b>ClassPrivateMethodParamType</b> <i>(string)</i>. The data type of the parameter.
+</ul>
+</ul>
+<li>protection => <b>ClassPrivateMethodProtection</b> <i>(string)</i>. Protection of the private method.
+<li>virtualness => <b>ClassPrivateMethodVirtualness</b> <i>(string)</i>. Virtualness of the private method.
+<li>detailed => <b>ClassPrivateMethodDetailed</b> <i>(hash)</i>. Detailed information about the private method.
+<ul>
+<li>params => <b>ClassPrivateMethodPDBlocks</b> <i>(list)</i>. List of parameter documentation blocks for the private method.
+<ul>
+<li> <b>ClassPrivateMethodPDBlock</b> <i>(hash)</i>. A parameter documentation block for the private method.
+<ul>
+<li>parameters => <b>ClassPrivateMethodPDParams</b> <i>(list)</i>. Parameter list for this parameter documentation block.
+<ul>
+<li> <b>ClassPrivateMethodPDParam</b> <i>(hash)</i>. A parameter documented by this documentation block.
+<ul>
+<li>name => <b>ClassPrivateMethodPDParamName</b> <i>(string)</i>. Name of the parameter.
+</ul>
+</ul>
+<li>doc => <b>ClassPrivateMethodPDDoc</b> <i>(doc)</i>. Documentation for this parameter documentation block.
+</ul>
+</ul>
+<li>doc => <b>ClassPrivateMethodDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the private method.
+<li>see => <b>ClassPrivateMethodSee</b> <i>(doc)</i>. "See also" documentation for the private method.
+<li>return => <b>ClassPrivateMethodReturn</b> <i>(doc)</i>. Documentation about the return value of the private method.
+</ul>
+<li>kind => <b>ClassPrivateMethodKind</b> <i>(string)</i>. Kind of private method (usually "function").
+<li>name => <b>ClassPrivateMethodName</b> <i>(string)</i>. Name of the private method.
+<li>type => <b>ClassPrivateMethodType</b> <i>(string)</i>. Data type returned by the private method.
+<li>static => <b>ClassPrivateMethodStatic</b> <i>(string)</i>. Whether the private method is static.
+</ul>
+</ul>
+</ul>
+<li>public_methods => <b>ClassPublicMethods</b> <i>(hash)</i>. Information about the public methods in the class.
+<ul>
+<li>members => <b>ClassPublicMethodList</b> <i>(list)</i>. public method list.
+<ul>
+<li> <b>ClassPublicMethod</b> <i>(hash)</i>. A public method.
+<ul>
+<li>parameters => <b>ClassPublicMethodParams</b> <i>(list)</i>. List of the parameters of the public method.
+<ul>
+<li> <b>ClassPublicMethodParam</b> <i>(hash)</i>. A parameter of the public method.
+<ul>
+<li>declaration_name => <b>ClassPublicMethodParamName</b> <i>(string)</i>. The name of the parameter.
+<li>type => <b>ClassPublicMethodParamType</b> <i>(string)</i>. The data type of the parameter.
+</ul>
+</ul>
+<li>protection => <b>ClassPublicMethodProtection</b> <i>(string)</i>. Protection of the public method.
+<li>virtualness => <b>ClassPublicMethodVirtualness</b> <i>(string)</i>. Virtualness of the public method.
+<li>detailed => <b>ClassPublicMethodDetailed</b> <i>(hash)</i>. Detailed information about the public method.
+<ul>
+<li>params => <b>ClassPublicMethodPDBlocks</b> <i>(list)</i>. List of parameter documentation blocks for the public method.
+<ul>
+<li> <b>ClassPublicMethodPDBlock</b> <i>(hash)</i>. A parameter documentation block for the public method.
+<ul>
+<li>parameters => <b>ClassPublicMethodPDParams</b> <i>(list)</i>. Parameter list for this parameter documentation block.
+<ul>
+<li> <b>ClassPublicMethodPDParam</b> <i>(hash)</i>. A parameter documented by this documentation block.
+<ul>
+<li>name => <b>ClassPublicMethodPDParamName</b> <i>(string)</i>. Name of the parameter.
+</ul>
+</ul>
+<li>doc => <b>ClassPublicMethodPDDoc</b> <i>(doc)</i>. Documentation for this parameter documentation block.
+</ul>
+</ul>
+<li>doc => <b>ClassPublicMethodDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the public method.
+<li>see => <b>ClassPublicMethodSee</b> <i>(doc)</i>. "See also" documentation for the public method.
+<li>return => <b>ClassPublicMethodReturn</b> <i>(doc)</i>. Documentation about the return value of the public method.
+</ul>
+<li>kind => <b>ClassPublicMethodKind</b> <i>(string)</i>. Kind of public method (usually "function").
+<li>name => <b>ClassPublicMethodName</b> <i>(string)</i>. Name of the public method.
+<li>type => <b>ClassPublicMethodType</b> <i>(string)</i>. Data type returned by the public method.
+<li>static => <b>ClassPublicMethodStatic</b> <i>(string)</i>. Whether the public method is static.
+</ul>
+</ul>
+</ul>
+</ul>
+</ul>
+<li>files => <b>Files</b> <i>(list)</i>. Documented files.
+<ul>
+<li> <b>File</b> <i>(hash)</i>. A documented file.
+<ul>
+<li>detailed => <b>FileDetailed</b> <i>(hash)</i>. Detailed information about the file.
+<ul>
+<li>doc => <b>FileDetailedDoc</b> <i>(doc)</i>. Detailed documentation block for the file.
+</ul>
+<li>functions => <b>FileFunctions</b> <i>(hash)</i>. Information about the functions in the file.
+<ul>
+<li>members => <b>FileFunctionList</b> <i>(list)</i>. function list.
+<ul>
+<li> <b>FileFunction</b> <i>(hash)</i>. A function.
+<ul>
+<li>parameters => <b>FileFunctionParams</b> <i>(list)</i>. List of the parameters of the function.
+<ul>
+<li> <b>FileFunctionParam</b> <i>(hash)</i>. A parameter of the function.
+<ul>
+<li>declaration_name => <b>FileFunctionParamName</b> <i>(string)</i>. The name of the parameter.
+<li>type => <b>FileFunctionParamType</b> <i>(string)</i>. The data type of the parameter.
+</ul>
+</ul>
+<li>protection => <b>FileFunctionProtection</b> <i>(string)</i>. Protection of the function.
+<li>virtualness => <b>FileFunctionVirtualness</b> <i>(string)</i>. Virtualness of the function.
+<li>detailed => <b>FileFunctionDetailed</b> <i>(hash)</i>. Detailed information about the function.
+<ul>
+<li>params => <b>FileFunctionPDBlocks</b> <i>(list)</i>. List of parameter documentation blocks for the function.
+<ul>
+<li> <b>FileFunctionPDBlock</b> <i>(hash)</i>. A parameter documentation block for the function.
+<ul>
+<li>parameters => <b>FileFunctionPDParams</b> <i>(list)</i>. Parameter list for this parameter documentation block.
+<ul>
+<li> <b>FileFunctionPDParam</b> <i>(hash)</i>. A parameter documented by this documentation block.
+<ul>
+<li>name => <b>FileFunctionPDParamName</b> <i>(string)</i>. Name of the parameter.
+</ul>
+</ul>
+<li>doc => <b>FileFunctionPDDoc</b> <i>(doc)</i>. Documentation for this parameter documentation block.
+</ul>
+</ul>
+<li>doc => <b>FileFunctionDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the function.
+<li>see => <b>FileFunctionSee</b> <i>(doc)</i>. "See also" documentation for the function.
+<li>return => <b>FileFunctionReturn</b> <i>(doc)</i>. Documentation about the return value of the function.
+</ul>
+<li>kind => <b>FileFunctionKind</b> <i>(string)</i>. Kind of function (usually "function").
+<li>name => <b>FileFunctionName</b> <i>(string)</i>. Name of the function.
+<li>type => <b>FileFunctionType</b> <i>(string)</i>. Data type returned by the function.
+<li>static => <b>FileFunctionStatic</b> <i>(string)</i>. Whether the function is static.
+</ul>
+</ul>
+</ul>
+<li>name => <b>FileName</b> <i>(string)</i>. Name of the file.
+<li>variables => <b>FileVariables</b> <i>(hash)</i>. Information about the variables in the file.
+<ul>
+<li>members => <b>FileVariableList</b> <i>(list)</i>. variable list.
+<ul>
+<li> <b>FileVariable</b> <i>(hash)</i>. A variable.
+<ul>
+<li>protection => <b>FileVariableProtection</b> <i>(string)</i>. Protection of the variable.
+<li>detailed => <b>FileVariableDetailed</b> <i>(hash)</i>. Detailed information about the variable.
+<ul>
+<li>doc => <b>FileVariableDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the variable.
+<li>see => <b>FileVariableSee</b> <i>(doc)</i>. "See also" documentation for the variable.
+</ul>
+<li>kind => <b>FileVariableKind</b> <i>(string)</i>. Kind of variable (usually "variable").
+<li>name => <b>FileVariableName</b> <i>(string)</i>. Name of the variable.
+<li>type => <b>FileVariableType</b> <i>(string)</i>. Data type of the variable.
+</ul>
+</ul>
+</ul>
+<li>typedefs => <b>FileTypedefs</b> <i>(hash)</i>. Information about the typedefs in the file.
+<ul>
+<li>members => <b>FileTypedefList</b> <i>(list)</i>. typedef list.
+<ul>
+<li> <b>FileTypedef</b> <i>(hash)</i>. A typedef.
+<ul>
+<li>protection => <b>FileTypedefProtection</b> <i>(string)</i>. Protection of the typedef.
+<li>detailed => <b>FileTypedefDetailed</b> <i>(hash)</i>. Detailed information about the typedef.
+<ul>
+<li>doc => <b>FileTypedefDetailedDoc</b> <i>(doc)</i>. Detailed documentation for the typedef.
+<li>see => <b>FileTypedefSee</b> <i>(doc)</i>. "See also" documentation for the typedef.
+</ul>
+<li>kind => <b>FileTypedefKind</b> <i>(string)</i>. Kind of typedef (usually "typedef").
+<li>name => <b>FileTypedefName</b> <i>(string)</i>. Name of the typedef.
+<li>type => <b>FileTypedefType</b> <i>(string)</i>. Data type of the typedef.
+</ul>
+</ul>
+</ul>
+</ul>
+</ul>
+</ul>
+</ul>
+
+
+\htmlonly
+Go to the <a href="arch.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/preprocessing.doc b/doc/preprocessing.doc
new file mode 100644
index 0000000..0ba9b12
--- /dev/null
+++ b/doc/preprocessing.doc
@@ -0,0 +1,272 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page preprocessing Preprocessing
+
+Source files that are used as input to doxygen can be parsed by doxygen's
+built-in C-preprocessor.
+
+By default doxygen does only partial preprocessing. That is, it
+evaluates conditional compilation statements (like \c \#if) and
+evaluates macro definitions, but it does not perform macro expansion.
+
+So if you have the following code fragment
+\verbatim
+#define VERSION 200
+#define CONST_STRING const char *
+
+#if VERSION >= 200
+ static CONST_STRING version = "2.xx";
+#else
+ static CONST_STRING version = "1.xx";
+#endif
+\endverbatim
+
+Then by default doxygen will feed the following to its parser:
+
+\verbatim
+#define VERSION
+#define CONST_STRING
+
+ static CONST_STRING version = "2.xx";
+\endverbatim
+
+You can disable all preprocessing by setting
+\ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" to \c
+NO in the configuration file. In the case above doxygen will then read
+both statements, i.e.:
+
+\verbatim
+ static CONST_STRING version = "2.xx";
+ static CONST_STRING version = "1.xx";
+\endverbatim
+
+In case you want to expand the \c CONST_STRING macro, you should set the
+\ref cfg_macro_expansion "MACRO_EXPANSION" tag in the config file
+to \c YES. Then the result after preprocessing becomes:
+
+\verbatim
+#define VERSION
+#define CONST_STRING
+
+ static const char * version = "1.xx";
+\endverbatim
+
+Note that doxygen will now expand \e all macro definitions
+(recursively if needed). This is often too much. Therefore, doxygen also
+allows you to expand only those defines that you explicitly
+specify. For this you have to set the
+\ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" tag to \c YES
+and specify the macro definitions after
+the \ref cfg_predefined "PREDEFINED" or
+\ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tag.
+
+A typically example where some help from the preprocessor is needed is
+when dealing with the language extension from Microsoft: \c __declspec. The same goes
+for GNU's \c \__attribute__ extension. Here is an example function.
+
+\verbatim
+extern "C" void __declspec(dllexport) ErrorMsg( String aMessage,...);
+\endverbatim
+
+When nothing is done, doxygen will be confused and see \c __declspec as
+some sort of function. To help doxygen one typically uses the following
+preprocessor settings:
+
+\verbatim
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = __declspec(x)=
+\endverbatim
+
+This will make sure the \c __declspec(dllexport) is removed before doxygen
+parses the source code.
+
+Similar settings can be used for removing \c \__attribute__ expressions from the input:
+
+\verbatim
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = __attribute__(x)=
+\endverbatim
+
+For a more complex example, suppose you have the following obfuscated
+code fragment of an abstract base class called \c IUnknown:
+
+\verbatim
+/*! A reference to an IID */
+#ifdef __cplusplus
+#define REFIID const IID &
+#else
+#define REFIID const IID *
+#endif
+
+
+/*! The IUnknown interface */
+DECLARE_INTERFACE(IUnknown)
+{
+ STDMETHOD(HRESULT,QueryInterface) (THIS_ REFIID iid, void **ppv) PURE;
+ STDMETHOD(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD(ULONG,Release) (THIS) PURE;
+};
+\endverbatim
+
+without macro expansion doxygen will get confused, but we may not want to
+expand the \c REFIID macro, because it is documented and the user that reads
+the documentation should use it when implementing the interface.
+
+By setting the following in the config file:
+
+\verbatim
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = "DECLARE_INTERFACE(name)=class name" \
+ "STDMETHOD(result,name)=virtual result name" \
+ "PURE= = 0" \
+ THIS_= \
+ THIS= \
+ __cplusplus
+\endverbatim
+
+we can make sure that the proper result is fed to doxygen's parser:
+\verbatim
+/*! A reference to an IID */
+#define REFIID
+
+/*! The IUnknown interface */
+class IUnknown
+{
+ virtual HRESULT QueryInterface ( REFIID iid, void **ppv) = 0;
+ virtual ULONG AddRef () = 0;
+ virtual ULONG Release () = 0;
+};
+\endverbatim
+
+Note that the \ref cfg_predefined "PREDEFINED" tag accepts function
+like macro definitions
+(like \c DECLARE_INTERFACE ), normal macro
+substitutions (like \c PURE and \c THIS) and plain
+defines (like \c __cplusplus).
+
+Note also that preprocessor definitions that are normally defined
+automatically by the preprocessor (like \c __cplusplus), have to be defined
+by hand with doxygen's parser (this is done because these defines
+are often platform/compiler specific).
+
+In some cases you may want to substitute a macro name or function by
+something else without exposing the result to further macro substitution.
+You can do this but using the <code>:=</code> operator instead of
+<code>=</code>
+
+As an example suppose we have the following piece of code:
+\verbatim
+#define QList QListT
+class QListT
+{
+};
+\endverbatim
+
+Then the only way to get doxygen interpret this as a class definition
+for class \c QList is to define:
+\verbatim
+PREDEFINED = QListT:=QList
+\endverbatim
+
+Here is an example provided by Valter Minute and Reyes Ponce that helps
+doxygen to wade through the boilerplate code in Microsoft's ATL \& MFC
+libraries:
+
+\verbatim
+PREDEFINED = "DECLARE_INTERFACE(name)=class name" \
+ "STDMETHOD(result,name)=virtual result name" \
+ "PURE= = 0" \
+ THIS_= \
+ THIS= \
+ DECLARE_REGISTRY_RESOURCEID=// \
+ DECLARE_PROTECT_FINAL_CONSTRUCT=// \
+ "DECLARE_AGGREGATABLE(Class)= " \
+ "DECLARE_REGISTRY_RESOURCEID(Id)= " \
+ DECLARE_MESSAGE_MAP= \
+ BEGIN_MESSAGE_MAP=/* \
+ END_MESSAGE_MAP=*/// \
+ BEGIN_COM_MAP=/* \
+ END_COM_MAP=*/// \
+ BEGIN_PROP_MAP=/* \
+ END_PROP_MAP=*/// \
+ BEGIN_MSG_MAP=/* \
+ END_MSG_MAP=*/// \
+ BEGIN_PROPERTY_MAP=/* \
+ END_PROPERTY_MAP=*/// \
+ BEGIN_OBJECT_MAP=/* \
+ END_OBJECT_MAP()=*/// \
+ DECLARE_VIEW_STATUS=// \
+ "STDMETHOD(a)=HRESULT a" \
+ "ATL_NO_VTABLE= " \
+ "__declspec(a)= " \
+ BEGIN_CONNECTION_POINT_MAP=/* \
+ END_CONNECTION_POINT_MAP=*/// \
+ "DECLARE_DYNAMIC(class)= " \
+ "IMPLEMENT_DYNAMIC(class1, class2)= " \
+ "DECLARE_DYNCREATE(class)= " \
+ "IMPLEMENT_DYNCREATE(class1, class2)= " \
+ "IMPLEMENT_SERIAL(class1, class2, class3)= " \
+ "DECLARE_MESSAGE_MAP()= " \
+ TRY=try \
+ "CATCH_ALL(e)= catch(...)" \
+ END_CATCH_ALL= \
+ "THROW_LAST()= throw"\
+ "RUNTIME_CLASS(class)=class" \
+ "MAKEINTRESOURCE(nId)=nId" \
+ "IMPLEMENT_REGISTER(v, w, x, y, z)= " \
+ "ASSERT(x)=assert(x)" \
+ "ASSERT_VALID(x)=assert(x)" \
+ "TRACE0(x)=printf(x)" \
+ "OS_ERR(A,B)={ #A, B }" \
+ __cplusplus \
+ "DECLARE_OLECREATE(class)= " \
+ "BEGIN_DISPATCH_MAP(class1, class2)= " \
+ "BEGIN_INTERFACE_MAP(class1, class2)= " \
+ "INTERFACE_PART(class, id, name)= " \
+ "END_INTERFACE_MAP()=" \
+ "DISP_FUNCTION(class, name, function, result, id)=" \
+ "END_DISPATCH_MAP()=" \
+ "IMPLEMENT_OLECREATE2(class, name, id1, id2, id3, id4,\
+ id5, id6, id7, id8, id9, id10, id11)="
+\endverbatim
+
+As you can see doxygen's preprocessor is quite powerful, but if you want
+even more flexibility you can always write an input filter and specify it
+after the \ref cfg_input_filter "INPUT_FILTER" tag.
+
+If you are unsure what the effect of doxygen's preprocessing will be
+you can run doxygen as follows:
+\verbatim
+ doxygen -d Preprocessor
+\endverbatim
+This will instruct doxygen to dump the input sources to standard output after
+preprocessing has been done (Hint: set <code>QUIET = YES</code> and
+<code>WARNINGS = NO</code> in the configuration file to disable any other
+output).
+
+\htmlonly
+Go to the <a href="autolink.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/searching.doc b/doc/searching.doc
new file mode 100644
index 0000000..25dcc3a
--- /dev/null
+++ b/doc/searching.doc
@@ -0,0 +1,193 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page searching Searching
+
+Doxygen indexes your source code in various ways to make it easier
+to navigate and find what you are looking for.
+There are also situations however where you want to
+search for something by keyword rather than browse for it.
+
+HTML browsers by default have no search capabilities that work across multiple
+pages, so either doxygen or external tools need to help to facilitate
+this feature.
+
+Doxygen has 7 different ways to add searching to the HTML output, each of which
+has its own advantages and disadvantages:
+
+<h2>1. Client side searching</h2>
+ The easiest way to enable searching is to enable the built-in client
+ side search engine. This engine is implemented using Javascript and DHTML
+ only and runs entirely on the clients browser. So no additional tooling is
+ required to make it work.
+
+ To enable it set
+ \ref cfg_searchengine "SEARCHENGINE" to \c YES in the config file
+ and make sure \ref cfg_server_based_search "SERVER_BASED_SEARCH" is set
+ to \c NO.
+
+ An additional advantage of this method is that it provides live
+ searching, i.e. the search results are presented and adapted as you type.
+
+ This method also has its drawbacks: it is limited to searching for symbols
+ only. It does not provide full text search capabilities, and it does not
+ scale well to very large projects (then searching becomes very slow).
+
+<h2>2. Server side searching</h2>
+ If you plan to put the HTML documentation on a web server, and that
+ web server has the capability to process PHP code, then you can also use
+ doxygen's built-in server side search engine.
+
+ To enable this set both
+ \ref cfg_searchengine "SEARCHENGINE" and
+ \ref cfg_server_based_search "SERVER_BASED_SEARCH" to \c YES in the config
+ file and set \ref cfg_external_search "EXTERNAL_SEARCH" to \c NO.
+
+ Advantages over the client side search engine are that it provides full
+ text search and it scales well to medium side projects.
+
+ Disadvantages are that it does not work locally (i.e. using a "file://" URL)
+ and that it does not provide live search capabilities.
+
+ @note In the future this option will probably be replaced by the next
+ search option.
+
+<h2>3. Server side searching with external indexing</h2>
+ With release 1.8.3 of doxygen, another server based search option has
+ been added. With this option doxygen generates the raw data that can be
+ searched and leaves it up to external tools to do the indexing and
+ searching, meaning that you could use your own indexer and search engine
+ of choice. To make life easier doxygen ships with an example indexer
+ (doxyindexer) and search engine (doxysearch.cgi) based on
+ the <a href="http://xapian.org/">Xapian</a> open source search engine
+ library.
+
+ To enable this search method set
+ \ref cfg_searchengine "SEARCHENGINE",
+ \ref cfg_server_based_search "SERVER_BASED_SEARCH" and
+ \ref cfg_external_search "EXTERNAL_SEARCH" all to \c YES.
+
+ See \subpage extsearch for configuration details.
+
+ Advantages over option 2 are that this method (potentially) scales to
+ very large projects. It is also possible to combine multiple doxygen
+ projects and external data into one search index.
+ The way the interaction with the search engine is done, makes it
+ possible to search from local HTML pages. Also the search results have
+ better ranking and show context information (if available).
+
+ Disadvantages are that is requires a web server that can execute a CGI
+ binary, and an additional indexing step after running doxygen.
+
+<h2>4. Windows Compiled HTML Help</h2>
+ If you are running doxygen on Windows, then you can make a
+ compiled HTML Help file (.chm) out of the HTML files produced by doxygen.
+ This is a single file containing all HTML files and it also includes a
+ search index. There are viewers for this format on many platforms,
+ and Windows even supports it natively.
+
+ To enable this set \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP" to \c YES
+ in the config file. To let doxygen compile the HTML Help file for you,
+ you also need to specify the path to the HTML compiler (hhc.exe) using the
+ \ref cfg_hhc_location "HHC_LOCATION" config option and the name of the
+ resulting CHM file using \ref cfg_chm_file "CHM_FILE".
+
+ An advantage of this method is that the result is a single file that can
+ easily be distributed. It also provides full text search.
+
+ Disadvantages are that compiling the CHM file only works on Windows
+ and requires Microsoft's HTML compiler, which is not very actively supported
+ by Microsoft. Although the tool works fine for most people, it can
+ sometimes crash for no apparent reason (how typical).
+
+<h2>5. Mac OS X Doc Sets</h2>
+ If you are running doxygen on Mac OS X 10.5 or higher,
+ then you can make a "doc set" out of the HTML files produced by doxygen.
+ A doc set consists of a single directory with a special structure
+ containing the HTML files along with a precompiled search index.
+ A doc set can be embedded in Xcode (the integrated development environment
+ provided by Apple).
+
+ To enable the creation of doc sets set \ref cfg_generate_docset "GENERATE_DOCSET"
+ to \c YES in the config file. There are a couple of other doc set related
+ options you may want to set. After doxygen has finished you will find
+ a Makefile in the HTML output directory. Running "make install" on this
+ Makefile will compile and install the doc set.
+ See <a href="https://developer.apple.com/library/mac/#featuredarticles/DoxygenXcode/_index.html">this
+ article</a> for more info.
+
+ Advantage of this method is that it nicely integrates with the Xcode
+ development environment, allowing for instance to click on an identifier
+ in the editor and jump to the corresponding section in the doxygen
+ documentation.
+
+ Disadvantage is that it only works in combination with Xcode on MacOSX.
+
+<h2>6. Qt Compressed Help</h2>
+ If you develop for or want to install the Qt application framework,
+ you will get an application
+ called <a href="http://qt-project.org/doc/qt-4.8/assistant-manual.html">Qt assistant</a>.
+ This is a help viewer for Qt Compressed Help files (<code>.qch</code>).
+
+ To enable this feature set \ref cfg_generate_qhp "GENERATE_QHP" to \c YES.
+ You also need to fill in the other Qt help related options, such as
+ \ref cfg_qhp_namespace "QHP_NAMESPACE",
+ \ref cfg_qhg_location "QHG_LOCATION",
+ \ref cfg_qhp_virtual_folder "QHP_VIRTUAL_FOLDER".
+ See <a href="http://doc.qt.digia.com/qq/qq28-qthelp.html#htmlfilesandhelpprojects">this article</a>
+ for more info.
+
+ Feature wise the Qt compressed help feature is comparable with the CHM
+ output, with the additional advantage that compiling the QCH file is
+ not limited to Windows.
+
+ Disadvantage is that it requires setting up a Qt 4.5 (or better) for
+ each user, or distributing the Qt help assistant along with
+ the documentation, which is complicated by the fact that it is not
+ available as a separate package at this moment.
+
+<h2>7. Eclipse Help Plugin</h2>
+ If you use eclipse, you can embed the documentation generated by
+ doxygen as a help plugin. It will then appear as a topic in the help
+ browser that can be started from "Help contents" in the Help menu.
+ Eclipse will generate a search index for the documentation when you
+ first search for a keyword.
+
+ To enable the help plugin set
+ \ref cfg_generate_eclipsehelp "GENERATE_ECLIPSEHELP" to \c YES,
+ and define a unique identifier for your project via
+ \ref cfg_eclipse_doc_id "ECLIPSE_DOC_ID", i.e.:
+\verbatim
+ GENERATE_ECLIPSEHELP = YES
+ ECLIPSE_DOC_ID = com.yourcompany.yourproject
+\endverbatim
+ then create the \c com.yourcompany.yourproject directory (so with
+ the same name as the value of \c ECLIPSE_DOC_ID) in the
+ \c plugin directory of eclipse and after doxygen completes copy
+ to contents of the help output directory to
+ the \c com.yourcompany.yourproject directory.
+ Then restart eclipse to make let it find the new plugin.
+
+ The eclipse help plugin provides similar functionality as the
+ Qt compressed help or CHM output, but it does require that Eclipse is
+ installed and running.
+
+\htmlonly
+Go to the <a href="customize.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
diff --git a/doc/starting.doc b/doc/starting.doc
new file mode 100644
index 0000000..a465d3f
--- /dev/null
+++ b/doc/starting.doc
@@ -0,0 +1,335 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page starting Getting started
+\tableofcontents
+
+The executable \c doxygen is the main program that parses the sources and
+generates the documentation. See section \ref doxygen_usage for more
+detailed usage information.
+
+Optionally, the executable \c doxywizard can be used, which is a
+\ref doxywizard_usage "graphical front-end" for editing the configuration file
+that is used by doxygen and for running doxygen in a graphical environment.
+For Mac OS X doxywizard will be started by clicking on the Doxygen application
+icon.
+
+The following figure shows the relation between the tools and the flow
+of information between them (it looks complex but that's only because it
+tries to be complete):
+
+\image html infoflow.png "Doxygen information flow"
+\image latex infoflow.eps "Doxygen information flow" width=14cm
+
+\section step0 Step 0: Check if doxygen supports your programming language
+
+First, assure that your programming language has a reasonable chance of being
+recognized by Doxygen. These languages are supported by default: C, C++, C#,
+Objective-C, IDL, Java, VHDL, PHP, Python, Tcl, Fortran, and D. It
+is possible to configure certain file type extensions to use certain parsers:
+see the \ref cfg_extension_mapping "Configuration/ExtensionMappings" for details.
+Also, completely different languages can be supported by using preprocessor
+programs: see the <a href="http://www.doxygen.org/helpers.html">Helpers page</a>
+for details.
+
+\section step1 Step 1: Creating a configuration file
+
+Doxygen uses a configuration file to determine all of its settings.
+Each project should get its own configuration file. A project can consist
+of a single source file, but can also be an entire source tree that is
+recursively scanned.
+
+To simplify the creation of a configuration file, doxygen can create a
+template configuration file for you. To do this call \c doxygen
+from the command line with the \c -g option:
+\verbatim
+doxygen -g <config-file>
+\endverbatim
+
+where \<config-file\> is the name of the configuration file. If you omit
+the file name, a file named \c Doxyfile will be created. If a file with the
+name \<config-file\> already exists, doxygen will rename it to
+\<config-file\>.bak before generating the configuration template.
+If you use <code>-</code> (i.e. the minus sign) as the file name then
+doxygen will try to read the configuration file from standard
+input (<code>stdin</code>), which can be useful for scripting.
+
+The configuration file has a format that is similar to that of a (simple)
+Makefile. It consists of a number of assignments (tags) of the form:
+
+<tt>TAGNAME = VALUE</tt> or <br>
+<tt>TAGNAME = VALUE1 VALUE2 ... </tt><br>
+
+You can probably leave the values of most tags in a generated template
+configuration file to their default value. See section \ref config for
+more details about the configuration file.
+
+If you do not wish to edit the config file with a text editor, you should
+have a look at \ref doxywizard_usage "doxywizard", which is a GUI
+front-end that can create, read and write doxygen configuration files,
+and allows setting configuration options by entering them via dialogs.
+
+For a small project consisting of a few C and/or C++ source
+and header files, you can leave
+\ref cfg_input "INPUT" tag empty and doxygen will search for sources in
+the current directory.
+
+If you have a larger project consisting of a source directory or tree
+you should assign the root directory or
+directories to the \ref cfg_input "INPUT" tag, and add one or more file
+patterns to the \ref cfg_file_patterns "FILE_PATTERNS" tag
+(for instance `*.cpp *.h`). Only files that match one of the
+patterns will be parsed (if the patterns are omitted a list of
+typical patterns is used for the types of files doxygen supports).
+For recursive parsing of a source tree you must set
+the \ref cfg_recursive "RECURSIVE" tag to \c YES. To further fine-tune the
+list of files that is parsed the \ref cfg_exclude "EXCLUDE" and
+\ref cfg_exclude_patterns "EXCLUDE_PATTERNS" tags can be used.
+To omit all \c test directories from a source tree for instance, one could use:
+
+\verbatim EXCLUDE_PATTERNS = */test/*
+\endverbatim
+
+Doxygen looks at the file's extension to determine how to parse a file,
+using the following table:
+
+Extension | Language
+---------:|---------
+.idl |IDL
+.ddl |IDL
+.odl |IDL
+.java |Java
+.cs |C#
+.d |D
+.php |PHP
+.php4 |PHP
+.php5 |PHP
+.inc |PHP
+.phtml |PHP
+.m |Objective-C
+.M |Objective-C
+.mm |Objective-C
+.py |Python
+.f |Fortran
+.for |Fortran
+.f90 |Fortran
+.vhd |VHDL
+.vhdl |VHDL
+.tcl |TCL
+.ucf |VHDL
+.qsf |VHDL
+.md |Markdown
+.markdown |Markdown
+
+Any other extension is parsed as if it is a C/C++ file.
+
+\anchor extract_all
+If you start using doxygen for an existing project (thus without any
+documentation that doxygen is aware of), you can still get an idea of
+what the structure is and how the documented result would look like.
+To do so, you must set
+the \ref cfg_extract_all "EXTRACT_ALL" tag in the configuration file
+to \c YES. Then, doxygen will pretend everything in your sources is documented.
+Please note that as a consequence warnings about undocumented members
+will not be generated as long as \ref cfg_extract_all "EXTRACT_ALL" is
+set to \c YES.
+
+To analyze an existing piece of software it is useful to cross-reference
+a (documented) entity with its definition in the source files. Doxygen will
+generate such cross-references if you set
+the \ref cfg_source_browser "SOURCE_BROWSER" tag to \c YES.
+It can also include the sources directly into the documentation by setting
+\ref cfg_inline_sources "INLINE_SOURCES" to \c YES (this can be handy for
+code reviews for instance).
+
+\section step2 Step 2: Running doxygen
+
+To generate the documentation you can now enter:
+\verbatim
+doxygen <config-file>
+\endverbatim
+
+Depending on your settings doxygen will create \c html, \c rtf,
+\c latex, \c xml, \c man, and/or docbook directories inside the output directory.
+As the names suggest these directories contain the
+generated documentation in HTML, RTF, \LaTeX, XML,
+Unix-Man page, and DocBook format.
+
+The default output directory is the directory in which \c doxygen
+is started. The root directory to which the output is written can be changed
+using the \ref cfg_output_directory "OUTPUT_DIRECTORY". The format specific
+directory within the output directory can be selected using the
+\ref cfg_html_output "HTML_OUTPUT", \ref cfg_rtf_output "RTF_OUTPUT",
+\ref cfg_latex_output "LATEX_OUTPUT", \ref cfg_xml_output "XML_OUTPUT",
+\ref cfg_man_output "MAN_OUTPUT", and \ref cfg_docbook_output "DOCBOOK_OUTPUT".
+tags of the configuration file. If the output directory does not exist,
+\c doxygen will try to create it for you (but it will \e not try to create
+a whole path recursively, like <code>mkdir -p</code> does).
+
+\subsection html_out HTML output
+\addindex browser
+The generated HTML documentation can be viewed by pointing a HTML browser
+to the \c index.html file in the \c html directory. For the best results
+a browser that supports cascading style sheets (CSS) should be used
+(I'm using Mozilla Firefox, Google Chrome, Safari, and sometimes
+IE8, IE9, and Opera to test the generated output).
+
+Some of the features the HTML section (such as
+\ref cfg_generate_treeview "GENERATE_TREEVIEW" or the search engine)
+require a browser that supports Dynamic HTML and Javascript enabled.
+
+\subsection latex_out LaTeX output
+\addindex LaTeX
+The generated \LaTeX documentation must first be compiled by
+a \LaTeX compiler (I use a recent teTeX distribution for Linux
+and MacOSX and MikTex for Windows).
+To simplify the process of compiling the generated
+documentation, \c doxygen writes a \c Makefile into the \c latex directory
+(on the Windows platform also a \c make.bat batch file is generated).
+
+The contents and targets in the \c Makefile depend on the setting of
+\ref cfg_use_pdflatex "USE_PDFLATEX". If it is disabled (set to \c NO), then
+typing \c make in the \c latex directory a \c dvi file called \c refman.dvi
+will be generated. This file can then be viewed using \c xdvi or
+converted into a PostScript file \c refman.ps by
+typing `make ps` (this requires `dvips`).
+
+To put 2 pages on one physical page use `make ps_2on1` instead.
+The resulting PostScript file can be send to a PostScript
+printer. If you do not have a PostScript printer, you can try to use
+ghostscript to convert PostScript into something your printer understands.
+
+Conversion to PDF is also possible if you have installed the ghostscript
+interpreter; just type `make pdf` (or `make pdf_2on1`).
+
+To get the best results for PDF output you should set
+the \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS"
+and \ref cfg_use_pdflatex "USE_PDFLATEX" tags to \c YES.
+In this case the \c Makefile will only contain a target to build
+\c refman.pdf directly.
+
+\subsection rtf_out RTF output
+\addindex RTF
+Doxygen combines the RTF output to a single file called refman.rtf. This
+file is optimized for importing into the Microsoft Word. Certain information
+is encoded using so called fields. To show the actual value you need to
+select all (Edit - select all) and then toggle fields (right click and select
+the option from the drop down menu).
+
+\subsection xml_out XML output
+\addindex XML
+The XML output consists of a structured "dump" of the information gathered
+by doxygen. Each compound (class/namespace/file/...) has its own XML file
+and there is also an index file called `index.xml`.
+
+A file called `combine.xslt`
+XSLT script is also generated and can be used to combine all XML files
+into a single file.
+
+Doxygen also generates two XML schema files `index.xsd`
+(for the index file) and `compound.xsd` (for the compound files).
+This schema file describes the possible elements, their attributes and
+how they are structured, i.e. it the describes the grammar of the XML
+files and can be used for validation or to steer XSLT scripts.
+
+In the `addon/doxmlparser` directory you can find a parser library for reading
+the XML output produced by doxygen in an incremental way
+(see `addon/doxmlparser/include/doxmlintf.h` for the interface of the library)
+
+\subsection man_out Man page output
+\addindex man
+The generated man pages can be viewed using the \c man program. You do need
+to make sure the man directory is in the man path (see the \c MANPATH
+environment variable). Note that there are some limitations to the
+capabilities of the man page format, so some information
+(like class diagrams, cross references and formulas) will be lost.
+
+\subsection docbook_out DocBook output
+\addindex docbook
+Doxygen can also generate output in the
+<a href="http://www.docbook.org/">DocBook</a> format. How to process the
+DocBook output is beyond the scope of this manual.
+
+\section step3 Step 3: Documenting the sources
+
+Although documenting the sources is presented as step 3, in a new project
+this should of course be step 1. Here I assume
+you already have some code and you want doxygen to generate a nice document
+describing the API and maybe the internals and some related design
+documentation as well.
+
+If the \ref cfg_extract_all "EXTRACT_ALL" option is set to \c NO in the
+configuration file (the default), then doxygen will only generate
+documentation for \e documented entities. So
+how do you document these? For members, classes and namespaces there are
+basically two options:
+1. Place a \e special documentation block in front of the declaration or
+ definition of the member, class or namespace. For file, class and namespace
+ members it is also allowed to place the documentation directly after the
+ member.
+
+ See section \ref specialblock to learn more about special
+ documentation blocks.
+2. Place a special documentation block somewhere else (another file or
+ another location) \e and put a <em>structural command</em> in the
+ documentation block. A structural command links a documentation block
+ to a certain entity that can be documented (e.g. a member, class,
+ namespace or file).
+
+ See section \ref structuralcommands to learn more
+ about structural commands.
+
+The advantage of the first option is that you do not have to repeat the
+name of the entity.
+
+Files can only be documented using the second option, since there is
+no way to put a documentation block before a file. Of course, file members
+(functions, variables, typedefs, defines) do not need an explicit
+structural command; just putting a special documentation block in front or
+behind them will work fine.
+
+The text inside a special documentation block is parsed
+before it is written to the HTML and/or \LaTeX output files.
+
+\addindex parsing
+During parsing the following steps take place:
+- Markdown formatting is replaced by corresponding HTML or special
+ commands.
+- The special commands inside the documentation are executed. See
+ section \ref commands for an overview of all commands.
+- If a line starts with some whitespace followed by one or more asterisks
+ (`*`) and then optionally more whitespace,
+ then all whitespace and asterisks are removed.
+- All resulting blank lines are treated as a paragraph separators.
+ This saves you from placing new-paragraph commands yourself
+ in order to make the generated documentation readable.
+- Links are created for words corresponding to documented classes
+ (unless the word is preceded by a \%; then the word will not be linked and
+ the \% sign is removed).
+- Links to members are created when certain patterns are found in the
+ text. See section \ref autolink
+ for more information on how the automatic link generation works.
+- HTML tags that are in the documentation are interpreted and converted
+ to \LaTeX equivalents for the \LaTeX output.
+ See section \ref htmlcmds for an overview of all supported HTML tags.
+
+\htmlonly
+Go to the <a href="docblocks.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/doc/translator.py b/doc/translator.py
new file mode 100644
index 0000000..19277be
--- /dev/null
+++ b/doc/translator.py
@@ -0,0 +1,2003 @@
+"""Script to generate reports on translator classes from Doxygen sources.
+
+ The main purpose of the script is to extract the information from sources
+ related to internationalization (the translator classes). It uses the
+ information to generate documentation (language.doc,
+ translator_report.txt) from templates (language.tpl, maintainers.txt).
+
+ Simply run the script without parameters to get the reports and
+ documentation for all supported languages. If you want to generate the
+ translator report only for some languages, pass their codes as arguments
+ to the script. In that case, the language.doc will not be generated.
+ Example:
+
+ python translator.py en nl cz
+
+ Originally, the script was written in Perl and was known as translator.pl.
+ The last Perl version was dated 2002/05/21 (plus some later corrections)
+
+ Petr Prikryl (prikryl at atlas dot cz)
+
+ History:
+ --------
+ 2002/05/21 - This was the last Perl version.
+ 2003/05/16 - List of language marks can be passed as arguments.
+ 2004/01/24 - Total reimplementation started: classes TrManager, and Transl.
+ 2004/02/05 - First version that produces translator report. No language.doc yet.
+ 2004/02/10 - First fully functional version that generates both the translator
+ report and the documentation. It is a bit slower than the
+ Perl version, but is much less tricky and much more flexible.
+ It also solves some problems that were not solved by the Perl
+ version. The translator report content should be more useful
+ for developers.
+ 2004/02/11 - Some tuning-up to provide more useful information.
+ 2004/04/16 - Added new tokens to the tokenizer (to remove some warnings).
+ 2004/05/25 - Added from __future__ import generators not to force Python 2.3.
+ 2004/06/03 - Removed dependency on textwrap module.
+ 2004/07/07 - Fixed the bug in the fill() function.
+ 2004/07/21 - Better e-mail mangling for HTML part of language.doc.
+ - Plural not used for reporting a single missing method.
+ - Removal of not used translator adapters is suggested only
+ when the report is not restricted to selected languages
+ explicitly via script arguments.
+ 2004/07/26 - Better reporting of not-needed adapters.
+ 2004/10/04 - Reporting of not called translator methods added.
+ 2004/10/05 - Modified to check only doxygen/src sources for the previous report.
+ 2005/02/28 - Slight modification to generate "mailto.txt" auxiliary file.
+ 2005/08/15 - Doxygen's root directory determined primarily from DOXYGEN
+ environment variable. When not found, then relatively to the script.
+ 2007/03/20 - The "translate me!" searched in comments and reported if found.
+ 2008/06/09 - Warning when the MAX_DOT_GRAPH_HEIGHT is still part of trLegendDocs().
+ 2009/05/09 - Changed HTML output to fit it with XHTML DTD
+ 2009/09/02 - Added percentage info to the report (implemented / to be implemented).
+ 2010/02/09 - Added checking/suggestion 'Reimplementation using UTF-8 suggested.
+ 2010/03/03 - Added [unreachable] prefix used in maintainers.txt.
+ 2010/05/28 - BOM skipped; minor code cleaning.
+ 2010/05/31 - e-mail mangled already in maintainers.txt
+ 2010/08/20 - maintainers.txt to UTF-8, related processin of unicode strings
+ - [any mark] introduced instead of [unreachable] only
+ - marks hihglighted in HTML
+ 2010/08/30 - Highlighting in what will be the table in langhowto.html modified.
+ 2010/09/27 - The underscore in \latexonly part of the generated language.doc
+ was prefixed by backslash (was LaTeX related error).
+ 2013/02/19 - Better diagnostics when translator_xx.h is too crippled.
+ 2013/06/25 - TranslatorDecoder checks removed after removing the class.
+ 2013/09/04 - Coloured status in langhowto. *ALMOST up-to-date* category
+ of translators introduced.
+ 2014/06/16 - unified for Python 2.6+ and 3.0+
+ """
+
+from __future__ import print_function
+
+import os
+import platform
+import re
+import sys
+import textwrap
+
+
+def xopen(fname, mode='r', encoding='utf-8-sig'):
+ '''Unified file opening for Python 2 an Python 3.
+
+ Python 2 does not have the encoding argument. Python 3 has one, and
+ the default 'utf-8-sig' is used (skips the BOM automatically).
+ '''
+
+ major, minor, patch = (int(e) for e in platform.python_version_tuple())
+ if major == 2:
+ return open(fname, mode=mode) # Python 2 without encoding
+ else:
+ return open(fname, mode=mode, encoding=encoding) # Python 3 with encoding
+
+
+def fill(s):
+ """Returns string formated to the wrapped paragraph multiline string.
+
+ Replaces whitespaces by one space and then uses he textwrap.fill()."""
+
+ # Replace all whitespace by spaces, remove whitespaces that are not
+ # necessary, strip the left and right whitespaces, and break the string
+ # to list of words.
+ rexWS = re.compile(r'\s+')
+ lst = rexWS.sub(' ', s).strip().split()
+
+ # If the list is not empty, put the words together and form the lines
+ # of maximum 70 characters. Build the list of lines.
+ lines = []
+ if lst:
+ line = lst.pop(0) # no separation space in front of the first word
+ for word in lst:
+ if len(line) + len(word) < 70:
+ line += ' ' + word
+ else:
+ lines.append(line) # another full line formed
+ line = word # next line started
+ lines.append(line) # the last line
+ return '\n'.join(lines)
+
+
+class Transl:
+ """One instance is build for each translator.
+
+ The abbreviation of the source file--part after 'translator_'--is used as
+ the identification of the object. The empty string is used for the
+ abstract Translator class from translator.h. The other information is
+ extracted from inside the source file."""
+
+ def __init__(self, fname, manager):
+ """Bind to the manager and initialize."""
+
+ # Store the filename and the reference to the manager object.
+ self.fname = fname
+ self.manager = manager
+
+ # The instance is responsible for loading the source file, so it checks
+ # for its existence and quits if something goes wrong.
+ if not os.path.isfile(fname):
+ sys.stderr.write("\a\nFile '%s' not found!\n" % fname)
+ sys.exit(1)
+
+ # Initialize the other collected information.
+ self.classId = None
+ self.baseClassId = None
+ self.readableStatus = None # 'up-to-date', '1.2.3', '1.3', etc.
+ self.status = None # '', '1.2.03', '1.3.00', etc.
+ self.lang = None # like 'Brasilian'
+ self.langReadable = None # like 'Brasilian Portuguese'
+ self.note = None # like 'should be cleaned up'
+ self.prototypeDic = {} # uniPrototype -> prototype
+ self.translateMeText = 'translate me!'
+ self.translateMeFlag = False # comments with "translate me!" found
+ self.txtMAX_DOT_GRAPH_HEIGHT_flag = False # found in string in trLegendDocs()
+ self.obsoleteMethods = None # list of prototypes to be removed
+ self.missingMethods = None # list of prototypes to be implemented
+ self.implementedMethods = None # list of implemented required methods
+ self.adaptMinClass = None # The newest adapter class that can be used
+
+ def __tokenGenerator(self):
+ """Generator that reads the file and yields tokens as 4-tuples.
+
+ The tokens have the form (tokenId, tokenString, lineNo). The
+ last returned token has the form ('eof', None, None). When trying
+ to access next token afer that, the exception would be raised."""
+
+ # Set the dictionary for recognizing tokenId for keywords, separators
+ # and the similar categories. The key is the string to be recognized,
+ # the value says its token identification.
+ tokenDic = { 'class': 'class',
+ 'const': 'const',
+ 'public': 'public',
+ 'protected': 'protected',
+ 'private': 'private',
+ 'static': 'static',
+ 'virtual': 'virtual',
+ ':': 'colon',
+ ';': 'semic',
+ ',': 'comma',
+ '[': 'lsqbra',
+ ']': 'rsqbra',
+ '(': 'lpar',
+ ')': 'rpar',
+ '{': 'lcurly',
+ '}': 'rcurly',
+ '=': 'assign',
+ '*': 'star',
+ '&': 'amp',
+ '+': 'plus',
+ '-': 'minus',
+ '!': 'excl',
+ '?': 'qmark',
+ '<': 'lt',
+ '>': 'gt',
+ "'": 'quot',
+ '"': 'dquot',
+ '.': 'dot',
+ '%': 'perc',
+ '~': 'tilde',
+ '^': 'caret',
+ }
+
+ # Regular expression for recognizing identifiers.
+ rexId = re.compile(r'^[a-zA-Z]\w*$')
+
+ # Open the file for reading and extracting tokens until the eof.
+ # Initialize the finite automaton.
+ f = xopen(self.fname)
+ lineNo = 0
+ line = '' # init -- see the pos initialization below
+ linelen = 0 # init
+ pos = 100 # init -- pos after the end of line
+ status = 0
+
+ tokenId = None # init
+ tokenStr = '' # init -- the characters will be appended.
+ tokenLineNo = 0
+
+ while status != 777:
+
+ # Get the next character. Read next line first, if necessary.
+ if pos < linelen:
+ c = line[pos]
+ else:
+ lineNo += 1
+ line = f.readline()
+ linelen = len(line)
+ pos = 0
+ if line == '': # eof
+ status = 777
+ else:
+ c = line[pos]
+
+ # Consume the character based on the status
+
+ if status == 0: # basic status
+
+ # This is the initial status. If tokenId is set, yield the
+ # token here and only here (except when eof is found).
+ # Initialize the token variables after the yield.
+ if tokenId:
+ # If it is an unknown item, it can still be recognized
+ # here. Keywords and separators are the example.
+ if tokenId == 'unknown':
+ if tokenStr in tokenDic:
+ tokenId = tokenDic[tokenStr]
+ elif tokenStr.isdigit():
+ tokenId = 'num'
+ elif rexId.match(tokenStr):
+ tokenId = 'id'
+ else:
+ msg = '\aWarning: unknown token "' + tokenStr + '"'
+ msg += '\tfound on line %d' % tokenLineNo
+ msg += ' in "' + self.fname + '".\n'
+ sys.stderr.write(msg)
+
+ yield (tokenId, tokenStr, tokenLineNo)
+
+ # If it is a comment that contains the self.translateMeText
+ # string, set the flag -- the situation will be reported.
+ if tokenId == 'comment' and tokenStr.find(self.translateMeText) >= 0:
+ self.translateMeFlag = True
+
+ tokenId = None
+ tokenStr = ''
+ tokenLineNo = 0
+
+ # Now process the character. When we just skip it (spaces),
+ # stay in this status. All characters that will be part of
+ # some token cause moving to the specific status. And only
+ # when moving to the status == 0 (or the final state 777),
+ # the token is yielded. With respect to that the automaton
+ # behaves as Moore's one (output bound to status). When
+ # collecting tokens, the automaton is the Mealy's one
+ # (actions bound to transitions).
+ if c.isspace():
+ pass # just skip whitespace characters
+ elif c == '/': # Possibly comment starts here, but
+ tokenId = 'unknown' # it could be only a slash in code.
+ tokenStr = c
+ tokenLineNo = lineNo
+ status = 1
+ elif c == '#':
+ tokenId = 'preproc' # preprocessor directive
+ tokenStr = c
+ tokenLineNo = lineNo
+ status = 5
+ elif c == '"': # string starts here
+ tokenId = 'string'
+ tokenStr = c
+ tokenLineNo = lineNo
+ status = 6
+ elif c == "'": # char literal starts here
+ tokenId = 'charlit'
+ tokenStr = c
+ tokenLineNo = lineNo
+ status = 8
+ elif c in tokenDic: # known one-char token
+ tokenId = tokenDic[c]
+ tokenStr = c
+ tokenLineNo = lineNo
+ # stay in this state to yield token immediately
+ else:
+ tokenId = 'unknown' # totally unknown
+ tokenStr = c
+ tokenLineNo = lineNo
+ status = 333
+
+ pos += 1 # move position in any case
+
+ elif status == 1: # possibly a comment
+ if c == '/': # ... definitely the C++ comment
+ tokenId = 'comment'
+ tokenStr += c
+ pos += 1
+ status = 2
+ elif c == '*': # ... definitely the C comment
+ tokenId = 'comment'
+ tokenStr += c
+ pos += 1
+ status = 3
+ else:
+ status = 0 # unrecognized, don't move pos
+
+ elif status == 2: # inside the C++ comment
+ if c == '\n': # the end of C++ comment
+ status = 0 # yield the token
+ else:
+ tokenStr += c # collect the C++ comment
+ pos += 1
+
+ elif status == 3: # inside the C comment
+ if c == '*': # possibly the end of the C comment
+ tokenStr += c
+ status = 4
+ else:
+ tokenStr += c # collect the C comment
+ pos += 1
+
+ elif status == 4: # possibly the end of the C comment
+ if c == '/': # definitely the end of the C comment
+ tokenStr += c
+ status = 0 # yield the token
+ elif c == '*': # more stars inside the comment
+ tokenStr += c
+ else:
+ tokenStr += c # this cannot be the end of comment
+ status = 3
+ pos += 1
+
+ elif status == 5: # inside the preprocessor directive
+ if c == '\n': # the end of the preproc. command
+ status = 0 # yield the token
+ else:
+ tokenStr += c # collect the preproc
+ pos += 1
+
+ elif status == 6: # inside the string
+ if c == '\\': # escaped char inside the string
+ tokenStr += c
+ status = 7
+ elif c == '"': # end of the string
+ tokenStr += c
+ status = 0
+ else:
+ tokenStr += c # collect the chars of the string
+ pos += 1
+
+ elif status == 7: # escaped char inside the string
+ tokenStr += c # collect the char of the string
+ status = 6
+ pos += 1
+
+ elif status == 8: # inside the char literal
+ tokenStr += c # collect the char of the literal
+ status = 9
+ pos += 1
+
+ elif status == 9: # end of char literal expected
+ if c == "'": # ... and found
+ tokenStr += c
+ status = 0
+ pos += 1
+ else:
+ tokenId = 'error' # end of literal was expected
+ tokenStr += c
+ status = 0
+
+ elif status == 333: # start of the unknown token
+ if c.isspace():
+ pos += 1
+ status = 0 # tokenId may be determined later
+ elif c in tokenDic: # separator, don't move pos
+ status = 0
+ else:
+ tokenStr += c # collect
+ pos += 1
+
+ # We should have finished in the final status. If some token
+ # have been extracted, yield it first.
+ assert(status == 777)
+ if tokenId:
+ yield (tokenId, tokenStr, tokenLineNo)
+ tokenId = None
+ tokenStr = ''
+ tokenLineNo = 0
+
+ # The file content is processed. Close the file. Then always yield
+ # the eof token.
+ f.close()
+ yield ('eof', None, None)
+
+
+ def __collectClassInfo(self, tokenIterator):
+ """Collect the information about the class and base class.
+
+ The tokens including the opening left curly brace of the class are
+ consumed."""
+
+ status = 0 # initial state
+
+ while status != 777: # final state
+
+ # Always assume that the previous tokens were processed. Get
+ # the next one.
+ tokenId, tokenStr, tokenLineNo = next(tokenIterator)
+
+ # Process the token and never return back.
+ if status == 0: # waiting for the 'class' keyword.
+ if tokenId == 'class':
+ status = 1
+
+ elif status == 1: # expecting the class identification
+ if tokenId == 'id':
+ self.classId = tokenStr
+ status = 2
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 2: # expecting the curly brace or base class info
+ if tokenId == 'lcurly':
+ status = 777 # correctly finished
+ elif tokenId == 'colon':
+ status = 3
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 3: # expecting the 'public' in front of base class id
+ if tokenId == 'public':
+ status = 4
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 4: # expecting the base class id
+ if tokenId == 'id':
+ self.baseClassId = tokenStr
+ status = 5
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 5: # expecting the curly brace and quitting
+ if tokenId == 'lcurly':
+ status = 777 # correctly finished
+ elif tokenId == 'comment':
+ pass
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ # Extract the status of the TranslatorXxxx class. The readable form
+ # will be used in reports the status form is a string that can be
+ # compared lexically (unified length, padding with zeros, etc.).
+ if self.baseClassId:
+ lst = self.baseClassId.split('_')
+ if lst[0] == 'Translator':
+ self.readableStatus = 'up-to-date'
+ self.status = ''
+ elif lst[0] == 'TranslatorAdapter':
+ self.status = lst[1] + '.' + lst[2]
+ self.readableStatus = self.status
+ if len(lst) > 3: # add the last part of the number
+ self.status += '.' + ('%02d' % int(lst[3]))
+ self.readableStatus += '.' + lst[3]
+ else:
+ self.status += '.00'
+ elif lst[0] == 'TranslatorEnglish':
+ # Obsolete or Based on English.
+ if self.classId[-2:] == 'En':
+ self.readableStatus = 'English based'
+ self.status = 'En'
+ else:
+ self.readableStatus = 'obsolete'
+ self.status = '0.0.00'
+
+ # Check whether status was set, or set 'strange'.
+ if self.status == None:
+ self.status = 'strange'
+ if not self.readableStatus:
+ self.readableStatus = 'strange'
+
+ # Extract the name of the language and the readable form.
+ self.lang = self.classId[10:] # without 'Translator'
+ if self.lang == 'Brazilian':
+ self.langReadable = 'Brazilian Portuguese'
+ elif self.lang == 'Chinesetraditional':
+ self.langReadable = 'Chinese Traditional'
+ else:
+ self.langReadable = self.lang
+
+
+ def __unexpectedToken(self, status, tokenId, tokenLineNo):
+ """Reports unexpected token and quits with exit code 1."""
+
+ import inspect
+ calledFrom = inspect.stack()[1][3]
+ msg = "\a\nUnexpected token '%s' on the line %d in '%s'.\n"
+ msg = msg % (tokenId, tokenLineNo, self.fname)
+ msg += 'status = %d in %s()\n' % (status, calledFrom)
+ sys.stderr.write(msg)
+ sys.exit(1)
+
+
+ def collectPureVirtualPrototypes(self):
+ """Returns dictionary 'unified prototype' -> 'full prototype'.
+
+ The method is expected to be called only for the translator.h. It
+ extracts only the pure virtual method and build the dictionary where
+ key is the unified prototype without argument identifiers."""
+
+ # Prepare empty dictionary that will be returned.
+ resultDic = {}
+
+ # Start the token generator which parses the class source file.
+ tokenIterator = self.__tokenGenerator()
+
+ # Collect the class and the base class identifiers.
+ self.__collectClassInfo(tokenIterator)
+ assert(self.classId == 'Translator')
+
+ # Let's collect readable form of the public virtual pure method
+ # prototypes in the readable form -- as defined in translator.h.
+ # Let's collect also unified form of the same prototype that omits
+ # everything that can be omitted, namely 'virtual' and argument
+ # identifiers.
+ prototype = '' # readable prototype (with everything)
+ uniPrototype = '' # unified prototype (without arg. identifiers)
+
+ # Collect the pure virtual method prototypes. Stop on the closing
+ # curly brace followed by the semicolon (end of class).
+ status = 0
+ curlyCnt = 0 # counter for the level of curly braces
+
+ # Loop until the final state 777 is reached. The errors are processed
+ # immediately. In this implementation, it always quits the application.
+ while status != 777:
+
+ # Get the next token.
+ tokenId, tokenStr, tokenLineNo = next(tokenIterator)
+
+ if status == 0: # waiting for 'public:'
+ if tokenId == 'public':
+ status = 1
+
+ elif status == 1: # colon after the 'public'
+ if tokenId == 'colon':
+ status = 2
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 2: # waiting for 'virtual'
+ if tokenId == 'virtual':
+ prototype = tokenStr # but not to unified prototype
+ status = 3
+ elif tokenId == 'comment':
+ pass
+ elif tokenId == 'rcurly':
+ status = 11 # expected end of class
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 3: # return type of the method expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype = tokenStr # start collecting the unified prototype
+ status = 4
+ elif tokenId == 'tilde':
+ status = 4
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 4: # method identifier expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ status = 5
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 5: # left bracket of the argument list expected
+ if tokenId == 'lpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 6
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 6: # collecting arguments of the method
+ if tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ elif tokenId == 'const':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 12
+ elif tokenId == 'id': # type identifier
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 7: # assignment expected or left curly brace
+ if tokenId == 'assign':
+ status = 8
+ elif tokenId == 'lcurly':
+ curlyCnt = 1 # method body entered
+ status = 10
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 8: # zero expected
+ if tokenId == 'num' and tokenStr == '0':
+ status = 9
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 9: # after semicolon, produce the dic item
+ if tokenId == 'semic':
+ assert(uniPrototype not in resultDic)
+ resultDic[uniPrototype] = prototype
+ status = 2
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 10: # consuming the body of the method
+ if tokenId == 'rcurly':
+ curlyCnt -= 1
+ if curlyCnt == 0:
+ status = 2 # body consumed
+ elif tokenId == 'lcurly':
+ curlyCnt += 1
+
+ elif status == 11: # probably the end of class
+ if tokenId == 'semic':
+ status = 777
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 12: # type id for argument expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 13: # namespace qualification or * or & expected
+ if tokenId == 'colon': # was namespace id
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 14
+ elif tokenId == 'star' or tokenId == 'amp': # pointer or reference
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ status = 16
+ elif tokenId == 'id': # argument identifier
+ prototype += ' ' + tokenStr
+ # don't put this into unified prototype
+ status = 17
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 14: # second colon for namespace:: expected
+ if tokenId == 'colon':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 15
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 15: # type after namespace:: expected
+ if tokenId == 'id':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 16: # argument identifier expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ # don't put this into unified prototype
+ status = 17
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 17: # comma or ')' after argument identifier expected
+ if tokenId == 'comma':
+ prototype += ', '
+ uniPrototype += ', '
+ status = 6
+ elif tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ # Eat the rest of the source to cause closing the file.
+ while tokenId != 'eof':
+ tokenId, tokenStr, tokenLineNo = next(tokenIterator)
+
+ # Return the resulting dictionary with 'uniPrototype -> prototype'.
+ return resultDic
+
+
+ def __collectPublicMethodPrototypes(self, tokenIterator):
+ """Collects prototypes of public methods and fills self.prototypeDic.
+
+ The dictionary is filled by items: uniPrototype -> prototype.
+ The method is expected to be called only for TranslatorXxxx classes,
+ i.e. for the classes that implement translation to some language.
+ It assumes that the openning curly brace of the class was already
+ consumed. The source is consumed until the end of the class.
+ The caller should consume the source until the eof to cause closing
+ the source file."""
+
+ assert(self.classId != 'Translator')
+ assert(self.baseClassId != None)
+
+ # The following finite automaton slightly differs from the one
+ # inside self.collectPureVirtualPrototypes(). It produces the
+ # dictionary item just after consuming the body of the method
+ # (transition from from state 10 to state 2). It also does not allow
+ # definitions of public pure virtual methods, except for
+ # TranslatorAdapterBase (states 8 and 9). Argument identifier inside
+ # method argument lists can be omitted or commented.
+ #
+ # Let's collect readable form of all public method prototypes in
+ # the readable form -- as defined in the source file.
+ # Let's collect also unified form of the same prototype that omits
+ # everything that can be omitted, namely 'virtual' and argument
+ # identifiers.
+ prototype = '' # readable prototype (with everything)
+ uniPrototype = '' # unified prototype (without arg. identifiers)
+ warning = '' # warning message -- if something special detected
+ methodId = None # processed method id
+
+ # Collect the method prototypes. Stop on the closing
+ # curly brace followed by the semicolon (end of class).
+ status = 0
+ curlyCnt = 0 # counter for the level of curly braces
+
+ # Loop until the final state 777 is reached. The errors are processed
+ # immediately. In this implementation, it always quits the application.
+ while status != 777:
+
+ # Get the next token.
+ tokenId, tokenStr, tokenLineNo = next(tokenIterator)
+
+ if status == 0: # waiting for 'public:'
+ if tokenId == 'public':
+ status = 1
+ elif tokenId == 'eof': # non-public things until the eof
+ status = 777
+
+ elif status == 1: # colon after the 'public'
+ if tokenId == 'colon':
+ status = 2
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 2: # waiting for 'virtual' (can be omitted)
+ if tokenId == 'virtual':
+ prototype = tokenStr # but not to unified prototype
+ status = 3
+ elif tokenId == 'id': # 'virtual' was omitted
+ prototype = tokenStr
+ uniPrototype = tokenStr # start collecting the unified prototype
+ status = 4
+ elif tokenId == 'comment':
+ pass
+ elif tokenId == 'protected' or tokenId == 'private':
+ status = 0
+ elif tokenId == 'rcurly':
+ status = 11 # expected end of class
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 3: # return type of the method expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype = tokenStr # start collecting the unified prototype
+ status = 4
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 4: # method identifier expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ methodId = tokenStr # for reporting
+ status = 5
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 5: # left bracket of the argument list expected
+ if tokenId == 'lpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 6
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 6: # collecting arguments of the method
+ if tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ elif tokenId == 'const':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 12
+ elif tokenId == 'id': # type identifier
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 7: # left curly brace expected
+ if tokenId == 'lcurly':
+ curlyCnt = 1 # method body entered
+ status = 10
+ elif tokenId == 'comment':
+ pass
+ elif tokenId == 'assign': # allowed only for TranslatorAdapterBase
+ assert(self.classId == 'TranslatorAdapterBase')
+ status = 8
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 8: # zero expected (TranslatorAdapterBase)
+ assert(self.classId == 'TranslatorAdapterBase')
+ if tokenId == 'num' and tokenStr == '0':
+ status = 9
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 9: # after semicolon (TranslatorAdapterBase)
+ assert(self.classId == 'TranslatorAdapterBase')
+ if tokenId == 'semic':
+ status = 2
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 10: # consuming the body of the method, then dic item
+ if tokenId == 'rcurly':
+ curlyCnt -= 1
+ if curlyCnt == 0:
+ # Check for possible copy/paste error when name
+ # of the method was not corrected (i.e. the same
+ # name already exists).
+ if uniPrototype in self.prototypeDic:
+ msg = "'%s' prototype found again (duplicity)\n"
+ msg += "in '%s'.\n" % self.fname
+ msg = msg % uniPrototype
+ sys.stderr.write(msg)
+ assert False
+
+ assert(uniPrototype not in self.prototypeDic)
+ # Insert new dictionary item.
+ self.prototypeDic[uniPrototype] = prototype
+ status = 2 # body consumed
+ methodId = None # outside of any method
+ elif tokenId == 'lcurly':
+ curlyCnt += 1
+
+ # Warn in special case.
+ elif methodId == 'trLegendDocs' and tokenId == 'string' \
+ and tokenStr.find('MAX_DOT_GRAPH_HEIGHT') >= 0:
+ self.txtMAX_DOT_GRAPH_HEIGHT_flag = True
+
+
+ elif status == 11: # probably the end of class
+ if tokenId == 'semic':
+ status = 777
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 12: # type id for argument expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 13: # :: or * or & or id or ) expected
+ if tokenId == 'colon': # was namespace id
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 14
+ elif tokenId == 'star' or tokenId == 'amp': # pointer or reference
+ prototype += ' ' + tokenStr
+ uniPrototype += ' ' + tokenStr
+ status = 16
+ elif tokenId == 'id': # argument identifier
+ prototype += ' ' + tokenStr
+ # don't put this into unified prototype
+ status = 17
+ elif tokenId == 'comment': # probably commented-out identifier
+ prototype += tokenStr
+ elif tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ elif tokenId == 'comma':
+ prototype += ', '
+ uniPrototype += ', '
+ status = 6
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 14: # second colon for namespace:: expected
+ if tokenId == 'colon':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 15
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 15: # type after namespace:: expected
+ if tokenId == 'id':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 13
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 16: # argument identifier or ) expected
+ if tokenId == 'id':
+ prototype += ' ' + tokenStr
+ # don't put this into unified prototype
+ status = 17
+ elif tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ elif tokenId == 'comment':
+ prototype += tokenStr
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+ elif status == 17: # comma or ')' after argument identifier expected
+ if tokenId == 'comma':
+ prototype += ', '
+ uniPrototype += ', '
+ status = 6
+ elif tokenId == 'rpar':
+ prototype += tokenStr
+ uniPrototype += tokenStr
+ status = 7
+ else:
+ self.__unexpectedToken(status, tokenId, tokenLineNo)
+
+
+
+ def collectAdapterPrototypes(self):
+ """Returns the dictionary of prototypes implemented by adapters.
+
+ It is created to process the translator_adapter.h. The returned
+ dictionary has the form: unifiedPrototype -> (version, classId)
+ thus by looking for the prototype, we get the information what is
+ the newest (least adapting) adapter that is sufficient for
+ implementing the method."""
+
+ # Start the token generator which parses the class source file.
+ assert(os.path.split(self.fname)[1] == 'translator_adapter.h')
+ tokenIterator = self.__tokenGenerator()
+
+ # Get the references to the involved dictionaries.
+ reqDic = self.manager.requiredMethodsDic
+
+ # Create the empty dictionary that will be returned.
+ adaptDic = {}
+
+
+ # Loop through the source of the adapter file until no other adapter
+ # class is found.
+ while True:
+ try:
+ # Collect the class and the base class identifiers.
+ self.__collectClassInfo(tokenIterator)
+
+ # Extract the comparable version of the adapter class.
+ # Note: The self.status as set by self.__collectClassInfo()
+ # contains similar version, but is related to the base class,
+ # not to the class itself.
+ lst = self.classId.split('_')
+ version = ''
+ if lst[0] == 'TranslatorAdapter': # TranslatorAdapterBase otherwise
+ version = lst[1] + '.' + lst[2]
+ if len(lst) > 3: # add the last part of the number
+ version += '.' + ('%02d' % int(lst[3]))
+ else:
+ version += '.00'
+
+ # Collect the prototypes of implemented public methods.
+ self.__collectPublicMethodPrototypes(tokenIterator)
+
+ # For the required methods, update the dictionary of methods
+ # implemented by the adapter.
+ for protoUni in self.prototypeDic:
+ if protoUni in reqDic:
+ # This required method will be marked as implemented
+ # by this adapter class. This implementation assumes
+ # that newer adapters do not reimplement any required
+ # methods already implemented by older adapters.
+ assert(protoUni not in adaptDic)
+ adaptDic[protoUni] = (version, self.classId)
+
+ # Clear the dictionary object and the information related
+ # to the class as the next adapter class is to be processed.
+ self.prototypeDic.clear()
+ self.classId = None
+ self.baseClassId = None
+
+ except StopIteration:
+ break
+
+ # Return the result dictionary.
+ return adaptDic
+
+
+ def processing(self):
+ """Processing of the source file -- only for TranslatorXxxx classes."""
+
+ # Start the token generator which parses the class source file.
+ tokenIterator = self.__tokenGenerator()
+
+ # Collect the class and the base class identifiers.
+ self.__collectClassInfo(tokenIterator)
+ assert(self.classId != 'Translator')
+ assert(self.classId[:17] != 'TranslatorAdapter')
+
+ # Collect the prototypes of implemented public methods.
+ self.__collectPublicMethodPrototypes(tokenIterator)
+
+ # Eat the rest of the source to cause closing the file.
+ while True:
+ try:
+ t = next(tokenIterator)
+ except StopIteration:
+ break
+
+ # Shorthands for the used dictionaries.
+ reqDic = self.manager.requiredMethodsDic
+ adaptDic = self.manager.adaptMethodsDic
+ myDic = self.prototypeDic
+
+ # Build the list of obsolete methods.
+ self.obsoleteMethods = []
+ for p in myDic:
+ if p not in reqDic:
+ self.obsoleteMethods.append(p)
+ self.obsoleteMethods.sort()
+
+ # Build the list of missing methods and the list of implemented
+ # required methods.
+ self.missingMethods = []
+ self.implementedMethods = []
+ for p in reqDic:
+ if p in myDic:
+ self.implementedMethods.append(p)
+ else:
+ self.missingMethods.append(p)
+ self.missingMethods.sort()
+ self.implementedMethods.sort()
+
+ # Check whether adapter must be used or suggest the newest one.
+ # Change the status and set the note accordingly.
+ if self.baseClassId != 'Translator':
+ if not self.missingMethods:
+ self.note = 'Change the base class to Translator.'
+ self.status = ''
+ self.readableStatus = 'almost up-to-date'
+ elif self.baseClassId != 'TranslatorEnglish':
+ # The translator uses some of the adapters.
+ # Look at the missing methods and check what adapter
+ # implements them. Remember the one with the lowest version.
+ adaptMinVersion = '9.9.99'
+ adaptMinClass = 'TranslatorAdapter_9_9_99'
+ for uniProto in self.missingMethods:
+ if uniProto in adaptDic:
+ version, cls = adaptDic[uniProto]
+ if version < adaptMinVersion:
+ adaptMinVersion = version
+ adaptMinClass = cls
+
+ # Test against the current status -- preserve the self.status.
+ # Possibly, the translator implements enough methods to
+ # use some newer adapter.
+ status = self.status
+
+ # If the version of the used adapter is smaller than
+ # the required, set the note and update the status as if
+ # the newer adapter was used.
+ if adaptMinVersion > status:
+ self.note = 'Change the base class to %s.' % adaptMinClass
+ self.status = adaptMinVersion
+ self.adaptMinClass = adaptMinClass
+ self.readableStatus = adaptMinVersion # simplified
+
+ # If everything seems OK, some explicit warning flags still could
+ # be set.
+ if not self.note and self.status == '' and \
+ (self.translateMeFlag or self.txtMAX_DOT_GRAPH_HEIGHT_flag):
+ self.note = ''
+ if self.translateMeFlag:
+ self.note += 'The "%s" found in a comment.' % self.translateMeText
+ if self.note != '':
+ self.note += '\n\t\t'
+ if self.txtMAX_DOT_GRAPH_HEIGHT_flag:
+ self.note += 'The MAX_DOT_GRAPH_HEIGHT found in trLegendDocs()'
+
+ # If everything seems OK, but there are obsolete methods, set
+ # the note to clean-up source. This note will be used only when
+ # the previous code did not set another note (priority).
+ if not self.note and self.status == '' and self.obsoleteMethods:
+ self.note = 'Remove the obsolete methods (never used).'
+
+ # If there is at least some note but the status suggests it is
+ # otherwise up-to-date, mark is as ALMOST up-to-date.
+ if self.note and self.status == '':
+ self.readableStatus = 'almost up-to-date'
+
+
+ def report(self, fout):
+ """Returns the report part for the source as a multiline string.
+
+ No output for up-to-date translators without problem."""
+
+ # If there is nothing to report, return immediately.
+ if self.status == '' and not self.note:
+ return
+
+ # Report the number of not implemented methods.
+ fout.write('\n\n\n')
+ fout.write(self.classId + ' (' + self.baseClassId + ')')
+ percentImplemented = 100 # init
+ allNum = len(self.manager.requiredMethodsDic)
+ if self.missingMethods:
+ num = len(self.missingMethods)
+ percentImplemented = 100 * (allNum - num) / allNum
+ fout.write(' %d' % num)
+ fout.write(' method')
+ if num > 1:
+ fout.write('s')
+ fout.write(' to implement (%d %%)' % (100 * num / allNum))
+ fout.write('\n' + '-' * len(self.classId))
+
+ # Write the info about the implemented required methods.
+ fout.write('\n\n Implements %d' % len(self.implementedMethods))
+ fout.write(' of the required methods (%d %%).' % percentImplemented)
+
+ # Report the missing method, but only when it is not English-based
+ # translator.
+ if self.missingMethods and self.status != 'En':
+ fout.write('\n\n Missing methods (should be implemented):\n')
+ reqDic = self.manager.requiredMethodsDic
+ for p in self.missingMethods:
+ fout.write('\n ' + reqDic[p])
+
+ # Always report obsolete methods.
+ if self.obsoleteMethods:
+ fout.write('\n\n Obsolete methods (should be removed, never used):\n')
+ myDic = self.prototypeDic
+ for p in self.obsoleteMethods:
+ fout.write('\n ' + myDic[p])
+
+ # For English-based translator, report the implemented methods.
+ if self.status == 'En' and self.implementedMethods:
+ fout.write('\n\n This English-based translator implements ')
+ fout.write('the following methods:\n')
+ reqDic = self.manager.requiredMethodsDic
+ for p in self.implementedMethods:
+ fout.write('\n ' + reqDic[p])
+
+
+ def getmtime(self):
+ """Returns the last modification time of the source file."""
+ assert(os.path.isfile(self.fname))
+ return os.path.getmtime(self.fname)
+
+
+class TrManager:
+ """Collects basic info and builds subordinate Transl objects."""
+
+ def __init__(self):
+ """Determines paths, creates and initializes structures.
+
+ The arguments of the script may explicitly say what languages should
+ be processed. Write the two letter identifications that are used
+ for composing the source filenames, so...
+
+ python translator.py cz
+
+ this will process only translator_cz.h source.
+ """
+
+ # Determine the path to the script and its name.
+ self.script = os.path.abspath(sys.argv[0])
+ self.script_path, self.script_name = os.path.split(self.script)
+ self.script_path = os.path.abspath(self.script_path)
+
+ # Determine the absolute path to the Doxygen's root subdirectory.
+ # If DOXYGEN environment variable is not found, the directory is
+ # determined from the path of the script.
+ doxy_default = os.path.join(self.script_path, '..')
+ self.doxy_path = os.path.abspath(os.getenv('DOXYGEN', doxy_default))
+
+ # Get the explicit arguments of the script.
+ self.script_argLst = sys.argv[1:]
+
+ # Build the path names based on the Doxygen's root knowledge.
+ self.doc_path = os.path.join(self.doxy_path, 'doc')
+ self.src_path = os.path.join(self.doxy_path, 'src')
+
+ # Create the empty dictionary for Transl object identitied by the
+ # class identifier of the translator.
+ self.__translDic = {}
+
+ # Create the None dictionary of required methods. The key is the
+ # unified prototype, the value is the full prototype. Set inside
+ # the self.__build().
+ self.requiredMethodsDic = None
+
+ # Create the empty dictionary that says what method is implemented
+ # by what adapter.
+ self.adaptMethodsDic = {}
+
+ # The last modification time will capture the modification of this
+ # script, of the translator.h, of the translator_adapter.h (see the
+ # self.__build() for the last two) of all the translator_xx.h files
+ # and of the template for generating the documentation. So, this
+ # time can be compared with modification time of the generated
+ # documentation to decide, whether the doc should be re-generated.
+ self.lastModificationTime = os.path.getmtime(self.script)
+
+ # Set the names of the translator report text file, of the template
+ # for generating "Internationalization" document, for the generated
+ # file itself, and for the maintainers list.
+ self.translatorReportFileName = 'translator_report.txt'
+ self.maintainersFileName = 'maintainers.txt'
+ self.languageTplFileName = 'language.tpl'
+ self.languageDocFileName = 'language.doc'
+
+ # The information about the maintainers will be stored
+ # in the dictionary with the following name.
+ self.__maintainersDic = None
+
+ # Define the other used structures and variables for information.
+ self.langLst = None # including English based
+ self.supportedLangReadableStr = None # coupled En-based as a note
+ self.numLang = None # excluding coupled En-based
+ self.doxVersion = None # Doxygen version
+
+ # Build objects where each one is responsible for one translator.
+ self.__build()
+
+
+ def __build(self):
+ """Find the translator files and build the objects for translators."""
+
+ # The translator.h must exist (the Transl object will check it),
+ # create the object for it and let it build the dictionary of
+ # required methods.
+ tr = Transl(os.path.join(self.src_path, 'translator.h'), self)
+ self.requiredMethodsDic = tr.collectPureVirtualPrototypes()
+ tim = tr.getmtime()
+ if tim > self.lastModificationTime:
+ self.lastModificationTime = tim
+
+ # The translator_adapter.h must exist (the Transl object will check it),
+ # create the object for it and store the reference in the dictionary.
+ tr = Transl(os.path.join(self.src_path, 'translator_adapter.h'), self)
+ self.adaptMethodsDic = tr.collectAdapterPrototypes()
+ tim = tr.getmtime()
+ if tim > self.lastModificationTime:
+ self.lastModificationTime = tim
+
+ # Create the list of the filenames with language translator sources.
+ # If the explicit arguments of the script were typed, process only
+ # those files.
+ if self.script_argLst:
+ lst = ['translator_' + x + '.h' for x in self.script_argLst]
+ for fname in lst:
+ if not os.path.isfile(os.path.join(self.src_path, fname)):
+ sys.stderr.write("\a\nFile '%s' not found!\n" % fname)
+ sys.exit(1)
+ else:
+ lst = os.listdir(self.src_path)
+ lst = [x for x in lst if x[:11] == 'translator_'
+ and x[-2:] == '.h'
+ and x != 'translator_adapter.h']
+
+ # Build the object for the translator_xx.h files, and process the
+ # content of the file. Then insert the object to the dictionary
+ # accessed via classId.
+ for fname in lst:
+ fullname = os.path.join(self.src_path, fname)
+ tr = Transl(fullname, self)
+ tr.processing()
+ assert(tr.classId != 'Translator')
+ self.__translDic[tr.classId] = tr
+
+ # Extract the global information of the processed info.
+ self.__extractProcessedInfo()
+
+
+ def __extractProcessedInfo(self):
+ """Build lists and strings of the processed info."""
+
+ # Build the auxiliary list with strings compound of the status,
+ # readable form of the language, and classId.
+ statLst = []
+ for obj in list(self.__translDic.values()):
+ assert(obj.classId != 'Translator')
+ s = obj.status + '|' + obj.langReadable + '|' + obj.classId
+ statLst.append(s)
+
+ # Sort the list and extract the object identifiers (classId's) for
+ # the up-to-date translators and English-based translators.
+ statLst.sort()
+ self.upToDateIdLst = [x.split('|')[2] for x in statLst if x[0] == '|']
+ self.EnBasedIdLst = [x.split('|')[2] for x in statLst if x[:2] == 'En']
+
+ # Reverse the list and extract the TranslatorAdapter based translators.
+ statLst.reverse()
+ self.adaptIdLst = [x.split('|')[2] for x in statLst if x[0].isdigit()]
+
+ # Build the list of tuples that contain (langReadable, obj).
+ # Sort it by readable name.
+ self.langLst = []
+ for obj in list(self.__translDic.values()):
+ self.langLst.append((obj.langReadable, obj))
+
+ self.langLst.sort(key=lambda x: x[0])
+
+ # Create the list with readable language names. If the language has
+ # also the English-based version, modify the item by appending
+ # the note. Number of the supported languages is equal to the length
+ # of the list.
+ langReadableLst = []
+ for name, obj in self.langLst:
+ if obj.status == 'En': continue
+
+ # Append the 'En' to the classId to possibly obtain the classId
+ # of the English-based object. If the object exists, modify the
+ # name for the readable list of supported languages.
+ classIdEn = obj.classId + 'En'
+ if classIdEn in self.__translDic:
+ name += ' (+En)'
+
+ # Append the result name of the language, possibly with note.
+ langReadableLst.append(name)
+
+ # Create the multiline string of readable language names,
+ # with punctuation, wrapped to paragraph.
+ if len(langReadableLst) == 1:
+ s = langReadableLst[0]
+ elif len(langReadableLst) == 2:
+ s = ' and '.join(langReadableLst)
+ else:
+ s = ', '.join(langReadableLst[:-1]) + ', and '
+ s += langReadableLst[-1]
+
+ self.supportedLangReadableStr = fill(s + '.')
+
+ # Find the number of the supported languages. The English based
+ # languages are not counted if the non-English based also exists.
+ self.numLang = len(self.langLst)
+ for name, obj in self.langLst:
+ if obj.status == 'En':
+ classId = obj.classId[:-2]
+ if classId in self.__translDic:
+ self.numLang -= 1 # the couple will be counted as one
+
+ # Extract the version of Doxygen.
+ f = xopen(os.path.join(self.doxy_path, 'VERSION'))
+ self.doxVersion = f.readline().strip()
+ f.close()
+
+ # Update the last modification time.
+ for tr in list(self.__translDic.values()):
+ tim = tr.getmtime()
+ if tim > self.lastModificationTime:
+ self.lastModificationTime = tim
+
+
+ def __getNoTrSourceFilesLst(self):
+ """Returns the list of sources to be checked.
+
+ All .cpp files and also .h files that do not declare or define
+ the translator methods are included in the list. The file names
+ are searched in doxygen/src directory.
+ """
+ files = []
+ for item in os.listdir(self.src_path):
+ # Split the bare name to get the extension.
+ name, ext = os.path.splitext(item)
+ ext = ext.lower()
+
+ # Include only .cpp and .h files (case independent) and exclude
+ # the files where the checked identifiers are defined.
+ if ext == '.cpp' or (ext == '.h' and name.find('translator') == -1):
+ fname = os.path.join(self.src_path, item)
+ assert os.path.isfile(fname) # assumes no directory with the ext
+ files.append(fname) # full name
+ return files
+
+
+ def __removeUsedInFiles(self, fname, dic):
+ """Removes items for method identifiers that are found in fname.
+
+ The method reads the content of the file as one string and searches
+ for all identifiers from dic. The identifiers that were found in
+ the file are removed from the dictionary.
+
+ Note: If more files is to be checked, the files where most items are
+ probably used should be checked first and the resulting reduced
+ dictionary should be used for checking the next files (speed up).
+ """
+ lst_in = list(dic.keys()) # identifiers to be searched for
+
+ # Read content of the file as one string.
+ assert os.path.isfile(fname)
+ f = xopen(fname)
+ cont = f.read()
+ f.close()
+
+ # Remove the items for identifiers that were found in the file.
+ while lst_in:
+ item = lst_in.pop(0)
+ if cont.find(item) != -1:
+ del dic[item]
+
+
+ def __checkForNotUsedTrMethods(self):
+ """Returns the dictionary of not used translator methods.
+
+ The method can be called only after self.requiredMethodsDic has been
+ built. The stripped prototypes are the values, the method identifiers
+ are the keys.
+ """
+ # Build the dictionary of the required method prototypes with
+ # method identifiers used as keys.
+ trdic = {}
+ for prototype in list(self.requiredMethodsDic.keys()):
+ ri = prototype.split('(')[0]
+ identifier = ri.split()[1].strip()
+ trdic[identifier] = prototype
+
+ # Build the list of source files where translator method identifiers
+ # can be used.
+ files = self.__getNoTrSourceFilesLst()
+
+ # Loop through the files and reduce the dictionary of id -> proto.
+ for fname in files:
+ self.__removeUsedInFiles(fname, trdic)
+
+ # Return the dictionary of not used translator methods.
+ return trdic
+
+
+ def __emails(self, classId):
+ """Returns the list of maintainer emails.
+
+ The method returns the list of e-mail adresses for the translator
+ class, but only the addresses that were not marked as [xxx]."""
+ lst = []
+ for m in self.__maintainersDic[classId]:
+ if not m[1].startswith('['):
+ email = m[1]
+ email = email.replace(' at ', '@') # Unmangle the mangled e-mail
+ email = email.replace(' dot ', '.')
+ lst.append(email)
+ return lst
+
+
+ def getBgcolorByReadableStatus(self, readableStatus):
+ if readableStatus == 'up-to-date':
+ color = '#ccffcc' # green
+ elif readableStatus.startswith('almost'):
+ color = '#ffffff' # white
+ elif readableStatus.startswith('English'):
+ color = '#ccffcc' # green
+ elif readableStatus.startswith('1.8'):
+ color = '#ffffcc' # yellow
+ elif readableStatus.startswith('1.7'):
+ color = '#ffcccc' # pink
+ elif readableStatus.startswith('1.6'):
+ color = '#ffcccc' # pink
+ else:
+ color = '#ff5555' # red
+ return color
+
+
+ def generateTranslatorReport(self):
+ """Generates the translator report."""
+
+ output = os.path.join(self.doc_path, self.translatorReportFileName)
+
+ # Open the textual report file for the output.
+ f = xopen(output, 'w')
+
+ # Output the information about the version.
+ f.write('(' + self.doxVersion + ')\n\n')
+
+ # Output the information about the number of the supported languages
+ # and the list of the languages, or only the note about the explicitly
+ # given languages to process.
+ if self.script_argLst:
+ f.write('The report was generated for the following, explicitly')
+ f.write(' identified languages:\n\n')
+ f.write(self.supportedLangReadableStr + '\n\n')
+ else:
+ f.write('Doxygen supports the following ')
+ f.write(str(self.numLang))
+ f.write(' languages (sorted alphabetically):\n\n')
+ f.write(self.supportedLangReadableStr + '\n\n')
+
+ # Write the summary about the status of language translators (how
+ # many translators) are up-to-date, etc.
+ s = 'Of them, %d translators are up-to-date, ' % len(self.upToDateIdLst)
+ s += '%d translators are based on some adapter class, ' % len(self.adaptIdLst)
+ s += 'and %d are English based.' % len(self.EnBasedIdLst)
+ f.write(fill(s) + '\n\n')
+
+ # The e-mail addresses of the maintainers will be collected to
+ # the auxiliary file in the order of translator classes listed
+ # in the translator report.
+ fmail = xopen('mailto.txt', 'w')
+
+ # Write the list of "up-to-date" translator classes.
+ if self.upToDateIdLst:
+ s = '''The following translator classes are up-to-date (sorted
+ alphabetically). This means that they derive from the
+ Translator class, they implement all %d of the required
+ methods, and even minor problems were not spotted by the script:'''
+ s = s % len(self.requiredMethodsDic)
+ f.write('-' * 70 + '\n')
+ f.write(fill(s) + '\n\n')
+
+ mailtoLst = []
+ for x in self.upToDateIdLst:
+ obj = self.__translDic[x]
+ if obj.note is None:
+ f.write(' ' + obj.classId + '\n')
+ mailtoLst.extend(self.__emails(obj.classId))
+
+ fmail.write('up-to-date\n')
+ fmail.write('; '.join(mailtoLst))
+
+
+ # Write separately the list of "ALMOST up-to-date" translator classes.
+ s = '''The following translator classes are ALMOST up-to-date (sorted
+ alphabetically). This means that they derive from the
+ Translator class, but there still may be some minor problems
+ listed for them:'''
+ f.write('\n' + ('-' * 70) + '\n')
+ f.write(fill(s) + '\n\n')
+ mailtoLst = []
+ for x in self.upToDateIdLst:
+ obj = self.__translDic[x]
+ if obj.note is not None:
+ f.write(' ' + obj.classId + '\t-- ' + obj.note + '\n')
+ mailtoLst.extend(self.__emails(obj.classId))
+
+ fmail.write('\n\nalmost up-to-date\n')
+ fmail.write('; '.join(mailtoLst))
+
+ # Write the list of the adapter based classes. The very obsolete
+ # translators that derive from TranslatorEnglish are included.
+ if self.adaptIdLst:
+ s = '''The following translator classes need maintenance
+ (the most obsolete at the end). The other info shows the
+ estimation of Doxygen version when the class was last
+ updated and number of methods that must be implemented to
+ become up-to-date:'''
+ f.write('\n' + '-' * 70 + '\n')
+ f.write(fill(s) + '\n\n')
+
+ # Find also whether some adapter classes may be removed.
+ adaptMinVersion = '9.9.99'
+
+ mailtoLst = []
+ numRequired = len(self.requiredMethodsDic)
+ for x in self.adaptIdLst:
+ obj = self.__translDic[x]
+ f.write(' %-30s' % obj.classId)
+ f.write(' %-6s' % obj.readableStatus)
+ numimpl = len(obj.missingMethods)
+ pluralS = ''
+ if numimpl > 1: pluralS = 's'
+ percent = 100 * numimpl / numRequired
+ f.write('\t%2d method%s to implement (%d %%)' % (
+ numimpl, pluralS, percent))
+ if obj.note:
+ f.write('\n\tNote: ' + obj.note + '\n')
+ f.write('\n')
+ mailtoLst.extend(self.__emails(obj.classId)) # to maintainer
+
+ # Check the level of required adapter classes.
+ if obj.status != '0.0.00' and obj.status < adaptMinVersion:
+ adaptMinVersion = obj.status
+
+ fmail.write('\n\ntranslator based\n')
+ fmail.write('; '.join(mailtoLst))
+
+ # Set the note if some old translator adapters are not needed
+ # any more. Do it only when the script is called without arguments,
+ # i.e. all languages were checked against the needed translator
+ # adapters.
+ if not self.script_argLst:
+ to_remove = {}
+ for version, adaptClassId in list(self.adaptMethodsDic.values()):
+ if version < adaptMinVersion:
+ to_remove[adaptClassId] = True
+
+ if to_remove:
+ lst = list(to_remove.keys())
+ lst.sort()
+ plural = len(lst) > 1
+ note = 'Note: The adapter class'
+ if plural: note += 'es'
+ note += ' ' + ', '.join(lst)
+ if not plural:
+ note += ' is'
+ else:
+ note += ' are'
+ note += ' not used and can be removed.'
+ f.write('\n' + fill(note) + '\n')
+
+ # Write the list of the English-based classes.
+ if self.EnBasedIdLst:
+ s = '''The following translator classes derive directly from the
+ TranslatorEnglish. The class identifier has the suffix 'En'
+ that says that this is intentional. Usually, there is also
+ a non-English based version of the translator for
+ the language:'''
+ f.write('\n' + '-' * 70 + '\n')
+ f.write(fill(s) + '\n\n')
+
+ for x in self.EnBasedIdLst:
+ obj = self.__translDic[x]
+ f.write(' ' + obj.classId)
+ f.write('\timplements %d methods' % len(obj.implementedMethods))
+ if obj.note:
+ f.write(' -- ' + obj.note)
+ f.write('\n')
+
+ # Check for not used translator methods and generate warning if found.
+ # The check is rather time consuming, so it is not done when report
+ # is restricted to explicitly given language identifiers.
+ if not self.script_argLst:
+ dic = self.__checkForNotUsedTrMethods()
+ if dic:
+ s = '''WARNING: The following translator methods are declared
+ in the Translator class but their identifiers do not appear
+ in source files. The situation should be checked. The .cpp
+ files and .h files excluding the '*translator*' files
+ in doxygen/src directory were simply searched for occurrence
+ of the method identifiers:'''
+ f.write('\n' + '=' * 70 + '\n')
+ f.write(fill(s) + '\n\n')
+
+ keys = list(dic.keys())
+ keys.sort()
+ for key in keys:
+ f.write(' ' + dic[key] + '\n')
+ f.write('\n')
+
+ # Write the details for the translators.
+ f.write('\n' + '=' * 70)
+ f.write('\nDetails for translators (classes sorted alphabetically):\n')
+
+ cls = list(self.__translDic.keys())
+ cls.sort()
+
+ for c in cls:
+ obj = self.__translDic[c]
+ assert(obj.classId != 'Translator')
+ obj.report(f)
+
+ # Close the report file and the auxiliary file with e-mails.
+ f.close()
+ fmail.close()
+
+
+ def __loadMaintainers(self):
+ """Load and process the file with the maintainers.
+
+ Fills the dictionary classId -> [(name, e-mail), ...]."""
+
+ fname = os.path.join(self.doc_path, self.maintainersFileName)
+
+ # Include the maintainers file to the group of files checked with
+ # respect to the modification time.
+ tim = os.path.getmtime(fname)
+ if tim > self.lastModificationTime:
+ self.lastModificationTime = tim
+
+ # Process the content of the maintainers file.
+ f = xopen(fname)
+ inside = False # inside the record for the language
+ lineReady = True
+ classId = None
+ maintainersLst = None
+ self.__maintainersDic = {}
+ while lineReady:
+ line = f.readline() # next line
+ lineReady = line != '' # when eof, then line == ''
+
+ line = line.strip() # eof should also behave as separator
+ if line != '' and line[0] == '%': # skip the comment line
+ continue
+
+ if not inside: # if outside of the record
+ if line != '': # should be language identifier
+ classId = line
+ maintainersLst = []
+ inside = True
+ # Otherwise skip empty line that do not act as separator.
+
+ else: # if inside the record
+ if line == '': # separator found
+ inside = False
+ else:
+ # If it is the first maintainer, create the empty list.
+ if classId not in self.__maintainersDic:
+ self.__maintainersDic[classId] = []
+
+ # Split the information about the maintainer and append
+ # the tuple. The address may be prefixed '[unreachable]'
+ # or whatever '[xxx]'. This will be processed later.
+ lst = line.split(':', 1)
+ assert(len(lst) == 2)
+ t = (lst[0].strip(), lst[1].strip())
+ self.__maintainersDic[classId].append(t)
+ f.close()
+
+
+ def generateLanguageDoc(self):
+ """Checks the modtime of files and generates language.doc."""
+ self.__loadMaintainers()
+
+ # Check the last modification time of the template file. It is the
+ # last file from the group that decide whether the documentation
+ # should or should not be generated.
+ fTplName = os.path.join(self.doc_path, self.languageTplFileName)
+ tim = os.path.getmtime(fTplName)
+ if tim > self.lastModificationTime:
+ self.lastModificationTime = tim
+
+ # If the generated documentation exists and is newer than any of
+ # the source files from the group, do not generate it and quit
+ # quietly.
+ fDocName = os.path.join(self.doc_path, self.languageDocFileName)
+ if os.path.isfile(fDocName):
+ if os.path.getmtime(fDocName) > self.lastModificationTime:
+ return
+
+ # The document or does not exist or is older than some of the
+ # sources. It must be generated again.
+ #
+ # Read the template of the documentation, and remove the first
+ # attention lines.
+ f = xopen(fTplName)
+ doctpl = f.read()
+ f.close()
+
+ pos = doctpl.find('/***')
+ assert pos != -1
+ doctpl = doctpl[pos:]
+
+ # Fill the tplDic by symbols that will be inserted into the
+ # document template.
+ tplDic = {}
+
+ s = 'Do not edit this file. It was generated by the %s script. * Instead edit %s and %s' % (self.script_name, self.languageTplFileName, self.maintainersFileName)
+ tplDic['editnote'] = s
+
+ tplDic['doxVersion'] = self.doxVersion
+ tplDic['supportedLangReadableStr'] = self.supportedLangReadableStr
+ tplDic['translatorReportFileName'] = self.translatorReportFileName
+
+ ahref = '<a href="../doc/' + self.translatorReportFileName
+ ahref += '"\n><code>doxygen/doc/' + self.translatorReportFileName
+ ahref += '</code></a>'
+ tplDic['translatorReportLink'] = ahref
+ tplDic['numLangStr'] = str(self.numLang)
+
+ # Define templates for HTML table parts of the documentation.
+ htmlTableTpl = '''\
+ \\htmlonly
+ <table align="center" cellspacing="0" cellpadding="0" border="0">
+ <tr bgcolor="#000000">
+ <td>
+ <table cellspacing="1" cellpadding="2" border="0">
+ <tr bgcolor="#4040c0">
+ <td ><b><font size="+1" color="#ffffff"> Language </font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Maintainer </font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Contact address </font>
+ <font size="-2" color="#ffffff">(replace the at and dot)</font></b></td>
+ <td ><b><font size="+1" color="#ffffff"> Status </font></b></td>
+ </tr>
+ <!-- table content begin -->
+ %s
+ <!-- table content end -->
+ </table>
+ </td>
+ </tr>
+ </table>
+ \\endhtmlonly
+ '''
+ htmlTableTpl = textwrap.dedent(htmlTableTpl)
+ htmlTrTpl = '\n <tr bgcolor="#ffffff">%s\n </tr>'
+ htmlTdTpl = '\n <td>%s</td>'
+ htmlTdStatusColorTpl = '\n <td bgcolor="%s">%s</td>'
+
+ # Loop through transl objects in the order of sorted readable names
+ # and add generate the content of the HTML table.
+ trlst = []
+ for name, obj in self.langLst:
+ # Fill the table data elements for one row. The first element
+ # contains the readable name of the language. Only the oldest
+ # translator are colour marked in the language columnt. Less
+ # "heavy" color is used (when compared with the Status column).
+ if obj.readableStatus.startswith('1.4'):
+ bkcolor = self.getBgcolorByReadableStatus('1.4')
+ else:
+ bkcolor = '#ffffff'
+
+ lst = [ htmlTdStatusColorTpl % (bkcolor, obj.langReadable) ]
+
+ # The next two elements contain the list of maintainers
+ # and the list of their mangled e-mails. For English-based
+ # translators that are coupled with the non-English based,
+ # insert the 'see' note.
+ mm = None # init -- maintainer
+ ee = None # init -- e-mail address
+ if obj.status == 'En':
+ # Check whether there is the coupled non-English.
+ classId = obj.classId[:-2]
+ if classId in self.__translDic:
+ lang = self.__translDic[classId].langReadable
+ mm = 'see the %s language' % lang
+ ee = ' '
+
+ if not mm and obj.classId in self.__maintainersDic:
+ # Build a string of names separated by the HTML break element.
+ # Special notes used instead of names are highlighted.
+ lm = []
+ for maintainer in self.__maintainersDic[obj.classId]:
+ name = maintainer[0]
+ if name.startswith('--'):
+ name = '<span style="color: red; background-color: yellow">'\
+ + name + '</span>'
+ lm.append(name)
+ mm = '<br/>'.join(lm)
+
+ # The marked adresses (they start with the mark '[unreachable]',
+ # '[resigned]', whatever '[xxx]') will not be displayed at all.
+ # Only the mark will be used instead.
+ rexMark = re.compile('(?P<mark>\\[.*?\\])')
+ le = []
+ for maintainer in self.__maintainersDic[obj.classId]:
+ address = maintainer[1]
+ m = rexMark.search(address)
+ if m is not None:
+ address = '<span style="color: brown">'\
+ + m.group('mark') + '</span>'
+ le.append(address)
+ ee = '<br/>'.join(le)
+
+ # Append the maintainer and e-mail elements.
+ lst.append(htmlTdTpl % mm)
+ lst.append(htmlTdTpl % ee)
+
+ # The last element contains the readable form of the status.
+ bgcolor = self.getBgcolorByReadableStatus(obj.readableStatus)
+ lst.append(htmlTdStatusColorTpl % (bgcolor, obj.readableStatus))
+
+ # Join the table data to one table row.
+ trlst.append(htmlTrTpl % (''.join(lst)))
+
+ # Join the table rows and insert into the template.
+ htmlTable = htmlTableTpl % (''.join(trlst))
+
+ # Define templates for LaTeX table parts of the documentation.
+ latexTableTpl = r'''
+ \latexonly
+ \footnotesize
+ \begin{longtable}{|l|l|l|l|}
+ \hline
+ {\bf Language} & {\bf Maintainer} & {\bf Contact address} & {\bf Status} \\
+ \hline
+ %s
+ \hline
+ \end{longtable}
+ \normalsize
+ \endlatexonly
+ '''
+ latexTableTpl = textwrap.dedent(latexTableTpl)
+ latexLineTpl = '\n' + r' %s & %s & {\tt\tiny %s} & %s \\'
+
+ # Loop through transl objects in the order of sorted readable names
+ # and add generate the content of the LaTeX table.
+ trlst = []
+ for name, obj in self.langLst:
+ # For LaTeX, more maintainers for the same language are
+ # placed on separate rows in the table. The line separator
+ # in the table is placed explicitly above the first
+ # maintainer. Prepare the arguments for the LaTeX row template.
+ maintainers = []
+ if obj.classId in self.__maintainersDic:
+ maintainers = self.__maintainersDic[obj.classId]
+
+ lang = obj.langReadable
+ maintainer = None # init
+ email = None # init
+ if obj.status == 'En':
+ # Check whether there is the coupled non-English.
+ classId = obj.classId[:-2]
+ if classId in self.__translDic:
+ langNE = self.__translDic[classId].langReadable
+ maintainer = 'see the %s language' % langNE
+ email = '~'
+
+ if not maintainer and (obj.classId in self.__maintainersDic):
+ lm = [ m[0] for m in self.__maintainersDic[obj.classId] ]
+ maintainer = maintainers[0][0]
+ email = maintainers[0][1]
+
+ status = obj.readableStatus
+
+ # Use the template to produce the line of the table and insert
+ # the hline plus the constructed line into the table content.
+ # The underscore character must be escaped.
+ trlst.append('\n \\hline')
+ s = latexLineTpl % (lang, maintainer, email, status)
+ s = s.replace('_', '\\_')
+ trlst.append(s)
+
+ # List the other maintainers for the language. Do not set
+ # lang and status for them.
+ lang = '~'
+ status = '~'
+ for m in maintainers[1:]:
+ maintainer = m[0]
+ email = m[1]
+ s = latexLineTpl % (lang, maintainer, email, status)
+ s = s.replace('_', '\\_')
+ trlst.append(s)
+
+ # Join the table lines and insert into the template.
+ latexTable = latexTableTpl % (''.join(trlst))
+
+ # Put the HTML and LaTeX parts together and define the dic item.
+ tplDic['informationTable'] = htmlTable + '\n' + latexTable
+
+ # Insert the symbols into the document template and write it down.
+ f = xopen(fDocName, 'w')
+ f.write(doctpl % tplDic)
+ f.close()
+
+if __name__ == '__main__':
+
+ # The Python 2.6+ or 3.3+ is required.
+ major, minor, patch = (int(e) for e in platform.python_version_tuple())
+ print(major, minor, patch)
+ if (major == 2 and minor < 6) or (major == 3 and minor < 0):
+ print('Python 2.6+ or Python 3.0+ are required for the script')
+ sys.exit(1)
+
+ # The translator manager builds the transl objects, parses the related
+ # sources, and keeps them in memory.
+ trMan = TrManager()
+
+ # Generate the language.doc.
+ trMan.generateLanguageDoc()
+
+ # Generate the translator report.
+ trMan.generateTranslatorReport()
diff --git a/doc/translator_report.txt b/doc/translator_report.txt
new file mode 100644
index 0000000..2997ec6
--- /dev/null
+++ b/doc/translator_report.txt
@@ -0,0 +1,1200 @@
+(1.8.7)
+
+Doxygen supports the following 40 languages (sorted alphabetically):
+
+Afrikaans, Arabic, Armenian, Brazilian Portuguese, Catalan, Chinese,
+Chinese Traditional, Croatian, Czech, Danish, Dutch, English,
+Esperanto, Finnish, French, German, Greek, Hungarian, Indonesian,
+Italian, Japanese (+En), Korean (+En), Latvian, Lithuanian,
+Macedonian, Norwegian, Persian, Polish, Portuguese, Romanian, Russian,
+Serbian, SerbianCyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+Ukrainian, and Vietnamese.
+
+Of them, 12 translators are up-to-date, 28 translators are based on
+some adapter class, and 2 are English based.
+
+----------------------------------------------------------------------
+The following translator classes are up-to-date (sorted
+alphabetically). This means that they derive from the Translator
+class, they implement all 242 of the required methods, and even minor
+problems were not spotted by the script:
+
+ TranslatorCzech
+ TranslatorDutch
+ TranslatorEnglish
+ TranslatorFrench
+ TranslatorJapanese
+ TranslatorKorean
+ TranslatorSlovak
+ TranslatorSpanish
+
+----------------------------------------------------------------------
+The following translator classes are ALMOST up-to-date (sorted
+alphabetically). This means that they derive from the Translator
+class, but there still may be some minor problems listed for them:
+
+ TranslatorChinesetraditional -- The MAX_DOT_GRAPH_HEIGHT found in trLegendDocs()
+ TranslatorRomanian -- The MAX_DOT_GRAPH_HEIGHT found in trLegendDocs()
+ TranslatorRussian -- The MAX_DOT_GRAPH_HEIGHT found in trLegendDocs()
+ TranslatorSwedish -- The "translate me!" found in a comment.
+ The MAX_DOT_GRAPH_HEIGHT found in trLegendDocs()
+
+----------------------------------------------------------------------
+The following translator classes need maintenance (the most obsolete
+at the end). The other info shows the estimation of Doxygen version
+when the class was last updated and number of methods that must be
+implemented to become up-to-date:
+
+ TranslatorUkrainian 1.8.4 8 methods to implement (3 %)
+ TranslatorLatvian 1.8.4 8 methods to implement (3 %)
+ TranslatorGreek 1.8.4 8 methods to implement (3 %)
+ TranslatorGerman 1.8.4 8 methods to implement (3 %)
+ TranslatorEsperanto 1.8.4 8 methods to implement (3 %)
+ TranslatorPolish 1.8.2 14 methods to implement (5 %)
+ TranslatorItalian 1.8.2 15 methods to implement (6 %)
+ TranslatorCroatian 1.8.2 15 methods to implement (6 %)
+ TranslatorChinese 1.8.2 15 methods to implement (6 %)
+ TranslatorPortuguese 1.8.0 22 methods to implement (9 %)
+ TranslatorIndonesian 1.8.0 22 methods to implement (9 %)
+ TranslatorDanish 1.8.0 22 methods to implement (9 %)
+ TranslatorCatalan 1.8.0 22 methods to implement (9 %)
+ TranslatorBrazilian 1.8.0 22 methods to implement (9 %)
+ TranslatorArmenian 1.8.0 22 methods to implement (9 %)
+ TranslatorTurkish 1.7.5 25 methods to implement (10 %)
+ TranslatorPersian 1.7.5 25 methods to implement (10 %)
+ TranslatorVietnamese 1.6.0 33 methods to implement (13 %)
+ TranslatorSerbian 1.6.0 33 methods to implement (13 %)
+ TranslatorSerbianCyrillic 1.6.0 33 methods to implement (13 %)
+ TranslatorMacedonian 1.6.0 33 methods to implement (13 %)
+ TranslatorFinnish 1.6.0 33 methods to implement (13 %)
+ TranslatorAfrikaans 1.6.0 33 methods to implement (13 %)
+ TranslatorSlovene 1.4.6 57 methods to implement (23 %)
+ TranslatorNorwegian 1.4.6 55 methods to implement (22 %)
+ TranslatorLithuanian 1.4.6 57 methods to implement (23 %)
+ TranslatorHungarian 1.4.6 57 methods to implement (23 %)
+ TranslatorArabic 1.4.6 55 methods to implement (22 %)
+
+----------------------------------------------------------------------
+The following translator classes derive directly from the
+TranslatorEnglish. The class identifier has the suffix 'En' that says
+that this is intentional. Usually, there is also a non-English based
+version of the translator for the language:
+
+ TranslatorJapaneseEn implements 4 methods
+ TranslatorKoreanEn implements 4 methods
+
+======================================================================
+WARNING: The following translator methods are declared in the
+Translator class but their identifiers do not appear in source files.
+The situation should be checked. The .cpp files and .h files excluding
+the '*translator*' files in doxygen/src directory were simply searched
+for occurrence of the method identifiers:
+
+ QCString trBug()
+ QCString trBugList()
+ QCString trDeprecated()
+ QCString trDeprecatedList()
+ QCString trTest()
+ QCString trTestList()
+ QCString trTodo()
+ QCString trTodoList()
+
+
+======================================================================
+Details for translators (classes sorted alphabetically):
+
+
+
+TranslatorAfrikaans (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+-------------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorArabic (TranslatorAdapter_1_4_6) 55 methods to implement (22 %)
+----------------
+
+ Implements 187 of the required methods (77 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCallerGraph()
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trCompoundIndexFortran()
+ virtual QCString trCompoundListDescriptionFortran()
+ virtual QCString trCompoundListFortran()
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ virtual QCString trCompoundMembersFortran()
+ virtual QCString trCompoundReferenceFortran(const char * clName, ClassDef::CompoundType compType, bool isTemplate)
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDataTypes()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trLoading()
+ virtual QCString trMemberFunctionDocumentationFortran()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trModule(bool first_capital, bool singular)
+ virtual QCString trModuleReference(const char * namespaceName)
+ virtual QCString trModulesIndex()
+ virtual QCString trModulesList()
+ virtual QCString trModulesListDescription(bool extractAll)
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ virtual QCString trModulesMembers()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ virtual QCString trSubprogramDocumentation()
+ virtual QCString trSubprograms()
+ virtual QCString trTemplateParameters()
+ virtual QCString trType(bool first_capital, bool singular)
+ virtual QCString trTypeConstraints()
+ virtual QCString trTypeDocumentation()
+
+ Obsolete methods (should be removed, never used):
+
+ virtual QCString trBugsAndLimitations()
+ virtual QCString trField(bool/*first_capital*/, bool singular)
+ virtual QCString trHeaderFiles()
+ virtual QCString trHeaderFilesDescription()
+ virtual QCString trNoDescriptionAvailable()
+ virtual QCString trPackageDocumentation()
+ virtual QCString trReimplementedForInternalReasons()
+ virtual QCString trSources()
+
+
+TranslatorArmenian (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+------------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorBrazilian (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+-------------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorCatalan (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+-----------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorChinese (TranslatorAdapter_1_8_2) 15 methods to implement (6 %)
+-----------------
+
+ Implements 227 of the required methods (93 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trExtendsClass()
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorChinesetraditional (Translator)
+----------------------------
+
+ Implements 242 of the required methods (100 %).
+
+
+TranslatorCroatian (TranslatorAdapter_1_8_2) 15 methods to implement (6 %)
+------------------
+
+ Implements 227 of the required methods (93 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trExtendsClass()
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorDanish (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+----------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorEsperanto (TranslatorAdapter_1_8_4) 8 methods to implement (3 %)
+-------------------
+
+ Implements 234 of the required methods (96 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trInterfaces()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorFinnish (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+-----------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorGerman (TranslatorAdapter_1_8_4) 8 methods to implement (3 %)
+----------------
+
+ Implements 234 of the required methods (96 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trInterfaces()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorGreek (TranslatorAdapter_1_8_4) 8 methods to implement (3 %)
+---------------
+
+ Implements 234 of the required methods (96 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trInterfaces()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorHungarian (TranslatorAdapter_1_4_6) 57 methods to implement (23 %)
+-------------------
+
+ Implements 185 of the required methods (76 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCallerGraph()
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trCompoundIndexFortran()
+ virtual QCString trCompoundListDescriptionFortran()
+ virtual QCString trCompoundListFortran()
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ virtual QCString trCompoundMembersFortran()
+ virtual QCString trCompoundReferenceFortran(const char * clName, ClassDef::CompoundType compType, bool isTemplate)
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDataTypes()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trEnumerationValueDocumentation()
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMemberFunctionDocumentationFortran()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trModule(bool first_capital, bool singular)
+ virtual QCString trModuleReference(const char * namespaceName)
+ virtual QCString trModulesIndex()
+ virtual QCString trModulesList()
+ virtual QCString trModulesListDescription(bool extractAll)
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ virtual QCString trModulesMembers()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ virtual QCString trSubprogramDocumentation()
+ virtual QCString trSubprograms()
+ virtual QCString trTemplateParameters()
+ virtual QCString trType(bool first_capital, bool singular)
+ virtual QCString trTypeConstraints()
+ virtual QCString trTypeDocumentation()
+
+
+TranslatorIndonesian (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+--------------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorItalian (TranslatorAdapter_1_8_2) 15 methods to implement (6 %)
+-----------------
+
+ Implements 227 of the required methods (93 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trExtendsClass()
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorJapaneseEn (TranslatorEnglish) 238 methods to implement (98 %)
+--------------------
+
+ Implements 4 of the required methods (1 %).
+
+ This English-based translator implements the following methods:
+
+ virtual QCString idLanguage()
+ virtual QCString latexLanguageSupportCommand()
+ virtual QCString trRTFCharSet()
+ virtual QCString trRTFansicp()
+
+
+TranslatorKoreanEn (TranslatorEnglish) 238 methods to implement (98 %)
+------------------
+
+ Implements 4 of the required methods (1 %).
+
+ This English-based translator implements the following methods:
+
+ virtual QCString idLanguage()
+ virtual QCString latexLanguageSupportCommand()
+ virtual QCString trRTFCharSet()
+ virtual QCString trRTFansicp()
+
+
+TranslatorLatvian (TranslatorAdapter_1_8_4) 8 methods to implement (3 %)
+-----------------
+
+ Implements 234 of the required methods (96 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trInterfaces()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorLithuanian (TranslatorAdapter_1_4_6) 57 methods to implement (23 %)
+--------------------
+
+ Implements 185 of the required methods (76 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCallerGraph()
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trCompoundIndexFortran()
+ virtual QCString trCompoundListDescriptionFortran()
+ virtual QCString trCompoundListFortran()
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ virtual QCString trCompoundMembersFortran()
+ virtual QCString trCompoundReferenceFortran(const char * clName, ClassDef::CompoundType compType, bool isTemplate)
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDataTypes()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trEnumerationValueDocumentation()
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMemberFunctionDocumentationFortran()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trModule(bool first_capital, bool singular)
+ virtual QCString trModuleReference(const char * namespaceName)
+ virtual QCString trModulesIndex()
+ virtual QCString trModulesList()
+ virtual QCString trModulesListDescription(bool extractAll)
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ virtual QCString trModulesMembers()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ virtual QCString trSubprogramDocumentation()
+ virtual QCString trSubprograms()
+ virtual QCString trTemplateParameters()
+ virtual QCString trType(bool first_capital, bool singular)
+ virtual QCString trTypeConstraints()
+ virtual QCString trTypeDocumentation()
+
+
+TranslatorMacedonian (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+--------------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorNorwegian (TranslatorAdapter_1_4_6) 55 methods to implement (22 %)
+-------------------
+
+ Implements 187 of the required methods (77 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCallerGraph()
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trCompoundIndexFortran()
+ virtual QCString trCompoundListDescriptionFortran()
+ virtual QCString trCompoundListFortran()
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ virtual QCString trCompoundMembersFortran()
+ virtual QCString trCompoundReferenceFortran(const char * clName, ClassDef::CompoundType compType, bool isTemplate)
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDataTypes()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trLoading()
+ virtual QCString trMemberFunctionDocumentationFortran()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trModule(bool first_capital, bool singular)
+ virtual QCString trModuleReference(const char * namespaceName)
+ virtual QCString trModulesIndex()
+ virtual QCString trModulesList()
+ virtual QCString trModulesListDescription(bool extractAll)
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ virtual QCString trModulesMembers()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ virtual QCString trSubprogramDocumentation()
+ virtual QCString trSubprograms()
+ virtual QCString trTemplateParameters()
+ virtual QCString trType(bool first_capital, bool singular)
+ virtual QCString trTypeConstraints()
+ virtual QCString trTypeDocumentation()
+
+ Obsolete methods (should be removed, never used):
+
+ virtual QCString trBugsAndLimitations()
+ virtual QCString trField(bool first_capital, bool singular)
+ virtual QCString trHeaderFiles()
+ virtual QCString trHeaderFilesDescription()
+ virtual QCString trNoDescriptionAvailable()
+ virtual QCString trPackageDocumentation()
+ virtual QCString trReimplementedForInternalReasons()
+ virtual QCString trSources()
+
+
+TranslatorPersian (TranslatorAdapter_1_7_5) 25 methods to implement (10 %)
+-----------------
+
+ Implements 217 of the required methods (89 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorPolish (TranslatorAdapter_1_8_2) 14 methods to implement (5 %)
+----------------
+
+ Implements 228 of the required methods (94 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trExtendsClass()
+ virtual QCString trInstanceMethods()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+ Obsolete methods (should be removed, never used):
+
+ QCString trBugsAndLimitations()
+ virtual QCString trField(bool first_capital, bool singular)
+ QCString trHeaderFiles()
+ QCString trHeaderFilesDescription()
+ QCString trNoDescriptionAvailable()
+ virtual QCString trPackageDocumentation()
+ QCString trReimplementedForInternalReasons()
+ QCString trSources()
+
+
+TranslatorPortuguese (TranslatorAdapter_1_8_0) 22 methods to implement (9 %)
+--------------------
+
+ Implements 220 of the required methods (90 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorRomanian (Translator)
+------------------
+
+ Implements 242 of the required methods (100 %).
+
+
+TranslatorRussian (Translator)
+-----------------
+
+ Implements 242 of the required methods (100 %).
+
+
+TranslatorSerbian (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+-----------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorSerbianCyrillic (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+-------------------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorSlovene (TranslatorAdapter_1_4_6) 57 methods to implement (23 %)
+-----------------
+
+ Implements 185 of the required methods (76 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCallerGraph()
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trCompoundIndexFortran()
+ virtual QCString trCompoundListDescriptionFortran()
+ virtual QCString trCompoundListFortran()
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ virtual QCString trCompoundMembersFortran()
+ virtual QCString trCompoundReferenceFortran(const char * clName, ClassDef::CompoundType compType, bool isTemplate)
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDataTypes()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trEnumerationValueDocumentation()
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMemberFunctionDocumentationFortran()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trModule(bool first_capital, bool singular)
+ virtual QCString trModuleReference(const char * namespaceName)
+ virtual QCString trModulesIndex()
+ virtual QCString trModulesList()
+ virtual QCString trModulesListDescription(bool extractAll)
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ virtual QCString trModulesMembers()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ virtual QCString trSubprogramDocumentation()
+ virtual QCString trSubprograms()
+ virtual QCString trTemplateParameters()
+ virtual QCString trType(bool first_capital, bool singular)
+ virtual QCString trTypeConstraints()
+ virtual QCString trTypeDocumentation()
+
+
+TranslatorSwedish (Translator)
+-----------------
+
+ Implements 242 of the required methods (100 %).
+
+
+TranslatorTurkish (TranslatorAdapter_1_7_5) 25 methods to implement (10 %)
+-----------------
+
+ Implements 217 of the required methods (89 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
+
+
+TranslatorUkrainian (TranslatorAdapter_1_8_4) 8 methods to implement (3 %)
+-------------------
+
+ Implements 234 of the required methods (96 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trInterfaces()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+
+
+TranslatorVietnamese (TranslatorAdapter_1_6_0) 33 methods to implement (13 %)
+--------------------
+
+ Implements 209 of the required methods (86 %).
+
+ Missing methods (should be implemented):
+
+ virtual QCString trAdditionalInheritedMembers()
+ virtual QCString trAndMore(const QCString & number)
+ virtual QCString trCiteReferences()
+ virtual QCString trClassMethods()
+ virtual QCString trConstantGroupReference(const char * namespaceName)
+ virtual QCString trConstantGroups()
+ virtual QCString trCopyright()
+ virtual QCString trDateTime(int year, int month, int day, int dayOfWeek, int hour, int minutes, int seconds, bool includeTime)
+ virtual QCString trDesignOverview()
+ virtual QCString trDetailLevel()
+ virtual QCString trDirDepGraph(const char * name)
+ virtual QCString trDirRelation(const char * name)
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ virtual QCString trEnumReference(const char * name)
+ virtual QCString trExtendsClass()
+ virtual QCString trFileIn(const char * name)
+ virtual QCString trGlobalNamespace()
+ virtual QCString trIncludesFileIn(const char * name)
+ virtual QCString trInheritedFrom(const char * members, const char * what)
+ virtual QCString trInstanceMethods()
+ virtual QCString trInterfaces()
+ virtual QCString trLoading()
+ virtual QCString trMethodDocumentation()
+ virtual QCString trNoMatches()
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ virtual QCString trProvidedByCategory()
+ virtual QCString trSearching()
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ virtual QCString trServiceReference(const char * sName)
+ virtual QCString trServices()
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ virtual QCString trSingletonReference(const char * sName)
+ virtual QCString trTemplateParameters()
\ No newline at end of file
diff --git a/doc/trouble.doc b/doc/trouble.doc
new file mode 100644
index 0000000..d36e330
--- /dev/null
+++ b/doc/trouble.doc
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page trouble Troubleshooting
+
+\section knowproblems Known Problems
+<ul>
+<li>If you have problems building doxygen from sources, please
+ read \ref unix_problems "this section" first.
+<li>Doxygen is <em>not</em> a real compiler, it is only a lexical scanner.
+ This means that it can and will not detect errors in your source code.
+<li>Doxygen has a build in preprocessor, but this works slightly different than
+ the C preprocessor. Doxygen assumes a header file is properly guarded against
+ multiple inclusion, and that each include file is standalone (i.e. it could be placed
+ at the top of a source file without causing compiler errors). As long as this is
+ true (and this is a good design practice) you should not encounter problems.
+<li>Since it is impossible to test all possible code fragments, it is
+ very well possible, that some valid piece of C/C++ code is not handled
+ properly. If you find such a piece, please send it to me, so I can
+ improve doxygen's parsing capabilities. Try to make the piece of code
+ you send as small as possible, to help me narrow down the search.
+<li>Doxygen does not work properly if there are multiple classes, structs
+ or unions with the same name in your code. It should not crash however,
+ rather it should ignore all of the classes with the same name except one.
+<li>Some commands do not work inside the arguments of other commands.
+ Inside a HTML link (i.e. \<a href="..."\>...\<a\>) for instance
+ other commands (including other HTML commands) do not work!
+ The sectioning commands are an important exception.
+<li>Redundant braces can confuse doxygen in some cases.
+ For example:
+\verbatim
+ void f (int);
+\endverbatim
+ is properly parsed as a function declaration, but
+\verbatim
+ const int (a);
+\endverbatim
+ is also seen as a function declaration with name
+ <code>int</code>, because only the syntax is analyzed,
+ not the semantics. If the redundant braces can be detected, as in
+\verbatim
+ int *(a[20]);
+\endverbatim
+ then doxygen will remove the braces and correctly parse the result.
+<li>Not all names in code fragments that are included in the documentation
+ are replaced by links (for instance when using \ref cfg_source_browser "SOURCE_BROWSER" = `YES`)
+ and links to overloaded members may point to the wrong member.
+ This also holds for the "Referenced by" list that is generated for
+ each function.
+
+ For a part this is because the code parser isn't smart enough at the
+ moment. I'll try to improve this in the future. But even with these
+ improvements not everything can be properly linked to the corresponding
+ documentation, because of possible ambiguities or lack of
+ information about the context in which the code fragment is found.
+<li>It is not possible to insert a non-member function f in a class A
+ using the \ref cmdrelates "\\relates" or \ref cmdrelatesalso "\\relatesalso"
+ command, if class A already
+ has a member with name f and the same argument list.
+<li>There is only very limited support for member specialization at the
+ moment. It only works if there is a specialized template class as
+ well.
+<li>Not all special commands are properly translated to RTF.
+<li>Version 1.8.6 of dot (and maybe earlier versions too) do not
+ generate proper map files, causing the graphs that doxygen generates
+ not to be properly clickable.
+<li>PHP only: Doxygen requires that all PHP statements (i.e. code) is
+ wrapped in a functions/methods, otherwise you may run into parse problems.
+</ul>
+
+
+\section howtohelp How to Help
+The development of Doxygen highly depends on your input!
+
+If you are trying Doxygen let me know what you think of it (do you
+miss certain features?). Even if you decide not to use it, please let me
+know why.
+
+\section bug_reports How to report a bug
+
+Bugs are tracked in GNOME's <a href="http://bugzilla.gnome.org">bugzilla</a> database.
+Before submitting a
+<a href="http://bugzilla.gnome.org/enter_bug.cgi?product=doxygen">new bug</a>,
+first <a href="http://bugzilla.gnome.org/query.cgi?format=advanced&product=doxygen">search</a>
+through the database if the same bug has already been submitted by others (the doxygen
+product will be preselected).
+If you believe you have found a new bug,
+please <a href="http://bugzilla.gnome.org/enter_bug.cgi?product=doxygen">report it</a>.
+
+If you are unsure whether or not something is a bug, please ask help
+on the <a href="http://sourceforge.net/mail/?group_id=5971">users mailing list</a>
+first (subscription is required).
+
+If you send only a (vague) description of a bug, you are usually not very
+helpful and it will cost me much more time to figure out what you mean.
+In the worst-case your bug report may even be completely ignored by me, so
+always try to include the following information in your bug report:
+- The version of doxygen you are using (for instance 1.5.3, use
+ `doxygen --version` if you are not sure).
+- The name and version number of your operating system (for instance
+ SuSE Linux 6.4)
+- It is usually a good idea to send along the configuration file as well,
+ but please use doxygen with the <code>-s</code> flag while generating it
+ to keep it small (use <code>doxygen -s -u [configName]</code> to strip
+ the comments from an existing config file).
+- The easiest (and often the only) way for me to fix bugs is if you can
+ attach a small example demonstrating the problem you have to the bug report, so I can
+ reproduce it on my machine. Please make sure the example is valid
+ source code (could potentially compile) and that the problem is really
+ captured by the example (I often get examples that do not trigger the
+ actual bug!). If you intend to send more than one file please zip or tar
+ the files together into a single file for easier processing.
+ Note that when reporting a new bug you'll get a chance to attach a file to it
+ only \e after submitting the initial bug description.
+
+You can (and are encouraged to) add a patch for a bug. If you do so
+please use PATCH as a keyword in the bug entry form.
+
+If you have ideas how to fix existing bugs and limitations please discuss them on
+the <a href="http://sourceforge.net/mail/?group_id=5971">developers mailing list</a>
+(subscription required). Patches can also be sent directly to dimitri at stack.nl if
+you prefer not to send them via the bug tracker or mailing list.
+
+For patches please use
+"diff -uN" or include the files you modified. If you send more than
+one file please tar or zip everything, so I only have to save and download
+one file.
+
+\htmlonly
+Go to the <a href="features.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+
+*/
+
diff --git a/doc/xmlcmds.doc b/doc/xmlcmds.doc
new file mode 100644
index 0000000..0e8aa64
--- /dev/null
+++ b/doc/xmlcmds.doc
@@ -0,0 +1,109 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page xmlcmds XML Commands
+
+Doxygen supports most of the XML commands that are typically used in C#
+code comments. The XML tags are defined in Appendix E of the
+<a href="http://www.ecma-international.org/publications/standards/Ecma-334.htm">ECMA-334</a>
+standard, which defines the C# language. Unfortunately, the specification is
+not very precise and a number of the examples given are of poor quality.
+
+Here is the list of tags supported by doxygen:
+
+<ul>
+<li><tt>\<c\></tt> Identifies inline text that should be rendered as a
+ piece of code. Similar to using <tt>\<tt\></tt>text<tt>\</tt\></tt>.
+<li><tt>\<code\></tt> Set one or more lines of source code or program output.
+ Note that this command behaves like \ref cmdcode "\\code" ... \ref cmdendcode "\\endcode"
+ for C# code, but it behaves like the HTML equivalent
+ <tt>\<code\>...\</code\></tt> for other languages.
+<li><tt>\<description\></tt> Part of a <tt>\<list\></tt> command, describes an item.
+<li><tt>\<example\></tt> Marks a block of text as an example, ignored by doxygen.
+<li><tt>\<exception cref="member"\></tt> Identifies the exception a
+ method can throw.
+<li><tt>\<include\></tt> Can be used to import a piece of XML from an external
+ file. Ignored by doxygen at the moment.
+<li><tt>\<inheritdoc\></tt> Can be used to insert the documentation of a
+ member of a base class into the documentation of a
+ member of a derived class that reimplements it.
+<li><tt>\<item\></tt> List item. Can only be used inside a <tt>\<list\></tt> context.
+<li><tt>\<list type="type"\></tt> Starts a list, supported types are <tt>bullet</tt>
+ or <tt>number</tt> and <tt>table</tt>.
+ A list consists of a number of <tt>\<item\></tt> tags.
+ A list of type table, is a two column table which can have
+ a header.
+<li><tt>\<listheader\></tt> Starts the header of a list of type "table".
+<li><tt>\<para\></tt> Identifies a paragraph of text.
+<li><tt>\<param name="paramName"\></tt> Marks a piece of text as the documentation
+ for parameter "paramName". Similar to
+ using \ref cmdparam "\\param".
+<li><tt>\<paramref name="paramName"\></tt> Refers to a parameter with name
+ "paramName". Similar to using \ref cmda "\\a".
+<li><tt>\<permission\></tt> Identifies the security accessibility of a member.
+ Ignored by doxygen.
+<li><tt>\<remarks\></tt> Identifies the detailed description.
+<li><tt>\<returns\></tt> Marks a piece of text as the return value of a
+ function or method. Similar to using \ref cmdreturn "\\return".
+<li><tt>\<see cref="member"\></tt> Refers to a member. Similar to \ref cmdref "\\ref".
+<li><tt>\<seealso cref="member"\></tt> Starts a "See also" section referring
+ to "member". Similar to using \ref cmdsa "\\sa" member.
+<li><tt>\<summary\></tt> Identifies the brief description.
+ Similar to using \ref cmdbrief "\\brief".
+<li><tt>\<term\></tt> Part of a <tt>\<list\></tt> command.
+<li><tt>\<typeparam name="paramName"\></tt> Marks a piece of text as the documentation
+ for type parameter "paramName". Similar to
+ using \ref cmdparam "\\param".
+<li><tt>\<typeparamref name="paramName"\></tt> Refers to a parameter with name
+ "paramName". Similar to using \ref cmda "\\a".
+<li><tt>\<value\></tt> Identifies a property. Ignored by doxygen.
+</ul>
+
+Here is an example of a typical piece of code using some of the above commands:
+
+\code
+/// <summary>
+/// A search engine.
+/// </summary>
+class Engine
+{
+ /// <summary>
+ /// The Search method takes a series of parameters to specify the search criterion
+ /// and returns a dataset containing the result set.
+ /// </summary>
+ /// <param name="connectionString">the connection string to connect to the
+ /// database holding the content to search</param>
+ /// <param name="maxRows">The maximum number of rows to
+ /// return in the result set</param>
+ /// <param name="searchString">The text that we are searching for</param>
+ /// <returns>A DataSet instance containing the matching rows. It contains a maximum
+ /// number of rows specified by the maxRows parameter</returns>
+ public DataSet Search(string connectionString, int maxRows, int searchString)
+ {
+ DataSet ds = new DataSet();
+ return ds;
+ }
+}
+\endcode
+
+
+\htmlonly
+Go to the <a href="langhowto.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..a5e08a2
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,151 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+DOXYGEN_BIN="$(DOXYGEN)/bin/doxygen"
+
+all: class/html/index.html \
+ define/html/index.html \
+ enum/html/index.html \
+ file/html/index.html \
+ func/html/index.html \
+ page/html/index.html \
+ relates/html/index.html \
+ author/html/index.html \
+ par/html/index.html \
+ overload/html/index.html \
+ example/html/index.html \
+ include/html/index.html \
+ qtstyle/html/index.html \
+ jdstyle/html/index.html \
+ structcmd/html/index.html \
+ autolink/html/index.html \
+ restypedef/html/index.html \
+ afterdoc/html/index.html \
+ template/html/index.html \
+ tag/html/index.html \
+ group/html/index.html \
+ diagrams/html/index.html \
+ memgrp/html/index.html \
+ docstring/html/index.html \
+ pyexample/html/index.html \
+ tclexample/html/index.html \
+ mux/html/index.html \
+ manual/html/index.html
+
+# Disabled since it is broken :-(
+# dbusxml/html/index.html
+
+clean:
+ rm -rf class define enum file func page relates author \
+ par overload example include qtstyle jdstyle structcmd \
+ autolink tag restypedef afterdoc template tag group diagrams \
+ memgrp docstring pyexample mux manual dbusxml tclexample
+
+class/html/index.html: class.h class.cfg
+ $(DOXYGEN_BIN) class.cfg
+
+define/html/index.html: define.h define.cfg
+ $(DOXYGEN_BIN) define.cfg
+
+enum/html/index.html: enum.h enum.cfg
+ $(DOXYGEN_BIN) enum.cfg
+
+file/html/index.html: file.h file.cfg
+ $(DOXYGEN_BIN) file.cfg
+
+func/html/index.html: func.h func.cfg
+ $(DOXYGEN_BIN) func.cfg
+
+page/html/index.html: page.doc page.cfg
+ $(DOXYGEN_BIN) page.cfg
+
+relates/html/index.html: relates.cpp relates.cfg
+ $(DOXYGEN_BIN) relates.cfg
+
+author/html/index.html: author.cpp author.cfg
+ $(DOXYGEN_BIN) author.cfg
+
+par/html/index.html: par.cpp par.cfg
+ $(DOXYGEN_BIN) par.cfg
+
+overload/html/index.html: overload.cpp overload.cfg
+ $(DOXYGEN_BIN) overload.cfg
+
+example/html/index.html: example.cpp example_test.cpp example.cfg
+ $(DOXYGEN_BIN) example.cfg
+
+include/html/index.html: include.cpp example_test.cpp include.cfg
+ $(DOXYGEN_BIN) include.cfg
+
+qtstyle/html/index.html: qtstyle.cpp qtstyle.cfg
+ $(DOXYGEN_BIN) qtstyle.cfg
+
+jdstyle/html/index.html: jdstyle.cpp jdstyle.cfg
+ $(DOXYGEN_BIN) jdstyle.cfg
+
+structcmd/html/index.html: structcmd.h structcmd.cfg
+ $(DOXYGEN_BIN) structcmd.cfg
+
+autolink/html/index.html: autolink.cpp autolink.cfg
+ $(DOXYGEN_BIN) autolink.cfg
+
+tag/html/index.html: tag.cpp tag.cfg example/html/index.html
+ $(DOXYGEN_BIN) tag.cfg
+
+restypedef/html/index.html: restypedef.cpp restypedef.cfg
+ $(DOXYGEN_BIN) restypedef.cfg
+
+afterdoc/html/index.html: afterdoc.h afterdoc.cfg
+ $(DOXYGEN_BIN) afterdoc.cfg
+
+template/html/index.html: templ.cpp templ.cfg
+ $(DOXYGEN_BIN) templ.cfg
+
+group/html/index.html: group.cpp group.cfg
+ $(DOXYGEN_BIN) group.cfg
+
+memgrp/html/index.html: memgrp.cpp memgrp.cfg
+ $(DOXYGEN_BIN) memgrp.cfg
+
+pyexample/html/index.html: pyexample.py pyexample.cfg
+ $(DOXYGEN_BIN) pyexample.cfg
+
+tclexample/html/index.html: tclexample.tcl tclexample.cfg
+ $(DOXYGEN_BIN) tclexample.cfg
+
+mux/html/index.html: mux.vhdl mux.cfg
+ $(DOXYGEN_BIN) mux.cfg
+
+manual/html/index.html: manual.c manual.cfg
+ $(DOXYGEN_BIN) manual.cfg
+
+docstring/html/index.html: docstring.py docstring.cfg
+ $(DOXYGEN_BIN) docstring.cfg
+
+#dbusxml/html/index.html: dbusxml.xml dbusxml.cfg
+# $(DOXYGEN_BIN) dbusxml.cfg
+
+diagrams/html/index.html: diagrams_a.h diagrams_b.h diagrams_c.h diagrams_d.h diagrams_e.h diagrams.cfg
+ifneq ($(HAVE_DOT),)
+ $(DOXYGEN_BIN) diagrams.cfg
+endif
+
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..b9c9f20
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,129 @@
+DOXYGEN_BIN="$(DOXYGEN)/bin/doxygen"
+
+all: class/html/index.html \
+ define/html/index.html \
+ enum/html/index.html \
+ file/html/index.html \
+ func/html/index.html \
+ page/html/index.html \
+ relates/html/index.html \
+ author/html/index.html \
+ par/html/index.html \
+ overload/html/index.html \
+ example/html/index.html \
+ include/html/index.html \
+ qtstyle/html/index.html \
+ jdstyle/html/index.html \
+ structcmd/html/index.html \
+ autolink/html/index.html \
+ restypedef/html/index.html \
+ afterdoc/html/index.html \
+ template/html/index.html \
+ tag/html/index.html \
+ group/html/index.html \
+ diagrams/html/index.html \
+ memgrp/html/index.html \
+ docstring/html/index.html \
+ pyexample/html/index.html \
+ tclexample/html/index.html \
+ mux/html/index.html \
+ manual/html/index.html
+
+# Disabled since it is broken :-(
+# dbusxml/html/index.html
+
+clean:
+ rm -rf class define enum file func page relates author \
+ par overload example include qtstyle jdstyle structcmd \
+ autolink tag restypedef afterdoc template tag group diagrams \
+ memgrp docstring pyexample mux manual dbusxml tclexample
+
+class/html/index.html: class.h class.cfg
+ $(DOXYGEN_BIN) class.cfg
+
+define/html/index.html: define.h define.cfg
+ $(DOXYGEN_BIN) define.cfg
+
+enum/html/index.html: enum.h enum.cfg
+ $(DOXYGEN_BIN) enum.cfg
+
+file/html/index.html: file.h file.cfg
+ $(DOXYGEN_BIN) file.cfg
+
+func/html/index.html: func.h func.cfg
+ $(DOXYGEN_BIN) func.cfg
+
+page/html/index.html: page.doc page.cfg
+ $(DOXYGEN_BIN) page.cfg
+
+relates/html/index.html: relates.cpp relates.cfg
+ $(DOXYGEN_BIN) relates.cfg
+
+author/html/index.html: author.cpp author.cfg
+ $(DOXYGEN_BIN) author.cfg
+
+par/html/index.html: par.cpp par.cfg
+ $(DOXYGEN_BIN) par.cfg
+
+overload/html/index.html: overload.cpp overload.cfg
+ $(DOXYGEN_BIN) overload.cfg
+
+example/html/index.html: example.cpp example_test.cpp example.cfg
+ $(DOXYGEN_BIN) example.cfg
+
+include/html/index.html: include.cpp example_test.cpp include.cfg
+ $(DOXYGEN_BIN) include.cfg
+
+qtstyle/html/index.html: qtstyle.cpp qtstyle.cfg
+ $(DOXYGEN_BIN) qtstyle.cfg
+
+jdstyle/html/index.html: jdstyle.cpp jdstyle.cfg
+ $(DOXYGEN_BIN) jdstyle.cfg
+
+structcmd/html/index.html: structcmd.h structcmd.cfg
+ $(DOXYGEN_BIN) structcmd.cfg
+
+autolink/html/index.html: autolink.cpp autolink.cfg
+ $(DOXYGEN_BIN) autolink.cfg
+
+tag/html/index.html: tag.cpp tag.cfg example/html/index.html
+ $(DOXYGEN_BIN) tag.cfg
+
+restypedef/html/index.html: restypedef.cpp restypedef.cfg
+ $(DOXYGEN_BIN) restypedef.cfg
+
+afterdoc/html/index.html: afterdoc.h afterdoc.cfg
+ $(DOXYGEN_BIN) afterdoc.cfg
+
+template/html/index.html: templ.cpp templ.cfg
+ $(DOXYGEN_BIN) templ.cfg
+
+group/html/index.html: group.cpp group.cfg
+ $(DOXYGEN_BIN) group.cfg
+
+memgrp/html/index.html: memgrp.cpp memgrp.cfg
+ $(DOXYGEN_BIN) memgrp.cfg
+
+pyexample/html/index.html: pyexample.py pyexample.cfg
+ $(DOXYGEN_BIN) pyexample.cfg
+
+tclexample/html/index.html: tclexample.tcl tclexample.cfg
+ $(DOXYGEN_BIN) tclexample.cfg
+
+mux/html/index.html: mux.vhdl mux.cfg
+ $(DOXYGEN_BIN) mux.cfg
+
+manual/html/index.html: manual.c manual.cfg
+ $(DOXYGEN_BIN) manual.cfg
+
+docstring/html/index.html: docstring.py docstring.cfg
+ $(DOXYGEN_BIN) docstring.cfg
+
+#dbusxml/html/index.html: dbusxml.xml dbusxml.cfg
+# $(DOXYGEN_BIN) dbusxml.cfg
+
+diagrams/html/index.html: diagrams_a.h diagrams_b.h diagrams_c.h diagrams_d.h diagrams_e.h diagrams.cfg
+ifneq ($(HAVE_DOT),)
+ $(DOXYGEN_BIN) diagrams.cfg
+endif
+
diff --git a/examples/Makefile.win.in b/examples/Makefile.win.in
new file mode 100644
index 0000000..914c5ed
--- /dev/null
+++ b/examples/Makefile.win.in
@@ -0,0 +1,122 @@
+DOXYDIR = ..\bin
+
+all: class/html/index.html \
+ define/html/index.html \
+ enum/html/index.html \
+ file/html/index.html \
+ func/html/index.html \
+ page/html/index.html \
+ relates/html/index.html \
+ author/html/index.html \
+ par/html/index.html \
+ overload/html/index.html \
+ example/html/index.html \
+ include/html/index.html \
+ qtstyle/html/index.html \
+ jdstyle/html/index.html \
+ structcmd/html/index.html \
+ autolink/html/index.html \
+ restypedef/html/index.html \
+ afterdoc/html/index.html \
+ template/html/index.html \
+ tag/html/index.html \
+ group/html/index.html \
+ diagrams/html/index.html \
+ memgrp/html/index.html \
+ docstring/html/index.html \
+ pyexample/html/index.html \
+ tclexample/html/index.html \
+ mux/html/index.html \
+ manual/html/index.html
+
+clean:
+ del /s/y class define enum file pyexample tclexample docstring
+ del /s/y func page relates author
+ del /s/y par overload example include qtstyle
+ del /s/y jdstyle structcmd autolink resdefine mux manual
+ del /s/y restypedef afterdoc template tag group diagrams memgrp
+
+class/html/index.html: class.h class.cfg
+ $(DOXYDIR)\doxygen class.cfg
+
+define/html/index.html: define.h define.cfg
+ $(DOXYDIR)\doxygen define.cfg
+
+enum/html/index.html: enum.h enum.cfg
+ $(DOXYDIR)\doxygen enum.cfg
+
+file/html/index.html: file.h file.cfg
+ $(DOXYDIR)\doxygen file.cfg
+
+func/html/index.html: func.h func.cfg
+ $(DOXYDIR)\doxygen func.cfg
+
+page/html/index.html: page.doc page.cfg
+ $(DOXYDIR)\doxygen page.cfg
+
+relates/html/index.html: relates.cpp relates.cfg
+ $(DOXYDIR)\doxygen relates.cfg
+
+author/html/index.html: author.cpp author.cfg
+ $(DOXYDIR)\doxygen author.cfg
+
+par/html/index.html: par.cpp par.cfg
+ $(DOXYDIR)\doxygen par.cfg
+
+overload/html/index.html: overload.cpp overload.cfg
+ $(DOXYDIR)\doxygen overload.cfg
+
+example/html/index.html: example.cpp example_test.cpp example.cfg
+ $(DOXYDIR)\doxygen example.cfg
+
+include/html/index.html: include.cpp example_test.cpp include.cfg
+ $(DOXYDIR)\doxygen include.cfg
+
+qtstyle/html/index.html: qtstyle.cpp qtstyle.cfg
+ $(DOXYDIR)\doxygen qtstyle.cfg
+
+jdstyle/html/index.html: jdstyle.cpp jdstyle.cfg
+ $(DOXYDIR)\doxygen jdstyle.cfg
+
+structcmd/html/index.html: structcmd.h structcmd.cfg
+ $(DOXYDIR)\doxygen structcmd.cfg
+
+autolink/html/index.html: autolink.cpp autolink.cfg
+ $(DOXYDIR)\doxygen autolink.cfg
+
+tag/html/index.html: tag.cpp tag.cfg
+ $(DOXYDIR)\doxygen tag.cfg
+
+restypedef/html/index.html: restypedef.cpp restypedef.cfg
+ $(DOXYDIR)\doxygen restypedef.cfg
+
+afterdoc/html/index.html: afterdoc.h afterdoc.cfg
+ $(DOXYDIR)\doxygen afterdoc.cfg
+
+template/html/index.html: templ.cpp templ.cfg
+ $(DOXYDIR)\doxygen templ.cfg
+
+group/html/index.html: group.cpp group.cfg
+ $(DOXYDIR)\doxygen group.cfg
+
+memgrp/html/index.html: memgrp.cpp memgrp.cfg
+ $(DOXYDIR)\doxygen memgrp.cfg
+
+pyexample/html/index.html: pyexample.py pyexample.cfg
+ $(DOXYDIR)\doxygen pyexample.cfg
+
+tclexample/html/index.html: tclexample.tcl tclexample.cfg
+ $(DOXYDIR)\doxygen tclexample.cfg
+
+mux/html/index.html: mux.vhdl mux.cfg
+ $(DOXYDIR)\doxygen mux.cfg
+
+manual/html/index.html: manual.c manual.cfg
+ $(DOXYDIR)\doxygen manual.cfg
+
+docstring/html/index.html: docstring.py docstring.cfg
+ $(DOXYDIR)\doxygen docstring.cfg
+
+diagrams/html/index.html: diagrams_a.h diagrams_b.h diagrams_c.h diagrams_d.h diagrams_e.h diagrams.cfg
+ $(DOXYDIR)\doxygen diagrams.cfg
+
diff --git a/examples/afterdoc.cfg b/examples/afterdoc.cfg
new file mode 100644
index 0000000..fcdbcae
--- /dev/null
+++ b/examples/afterdoc.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "AfterDocs"
+OUTPUT_DIRECTORY = afterdoc
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = afterdoc.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/afterdoc.h b/examples/afterdoc.h
new file mode 100644
index 0000000..907dabe
--- /dev/null
+++ b/examples/afterdoc.h
@@ -0,0 +1,18 @@
+/*! A test class */
+
+class Test
+{
+ public:
+ /** An enum type.
+ * The documentation block cannot be put after the enum!
+ */
+ enum EnumType
+ {
+ int EVal1, /**< enum value 1 */
+ int EVal2 /**< enum value 2 */
+ };
+ void member(); //!< a member function.
+
+ protected:
+ int value; /*!< an integer value */
+};
diff --git a/examples/author.cfg b/examples/author.cfg
new file mode 100644
index 0000000..8bb04f7
--- /dev/null
+++ b/examples/author.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Author Command"
+OUTPUT_DIRECTORY = author
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = author.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/author.cpp b/examples/author.cpp
new file mode 100644
index 0000000..709354f
--- /dev/null
+++ b/examples/author.cpp
@@ -0,0 +1,13 @@
+/*!
+ * \brief Pretty nice class.
+ * \details This class is used to demonstrate a number of section commands.
+ * \author John Doe
+ * \author Jan Doe
+ * \version 4.1a
+ * \date 1990-2011
+ * \pre First initialize the system.
+ * \bug Not all memory is freed when deleting an object of this class.
+ * \warning Improper use can crash your application
+ * \copyright GNU Public License.
+ */
+class SomeNiceClass {};
diff --git a/examples/autolink.cfg b/examples/autolink.cfg
new file mode 100644
index 0000000..406d52c
--- /dev/null
+++ b/examples/autolink.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Automatic link generation"
+OUTPUT_DIRECTORY = autolink
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = autolink.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/autolink.cpp b/examples/autolink.cpp
new file mode 100644
index 0000000..e028f22
--- /dev/null
+++ b/examples/autolink.cpp
@@ -0,0 +1,99 @@
+/*! \file autolink.cpp
+ Testing automatic link generation.
+
+ A link to a member of the Test class: Test::member,
+
+ More specific links to the each of the overloaded members:
+ Test::member(int) and Test#member(int,int)
+
+ A link to a protected member variable of Test: Test#var,
+
+ A link to the global enumeration type #GlobEnum.
+
+ A link to the define #ABS(x).
+
+ A link to the destructor of the Test class: Test::~Test,
+
+ A link to the typedef ::B.
+
+ A link to the enumeration type Test::EType
+
+ A link to some enumeration values Test::Val1 and ::GVal2
+*/
+
+/*!
+ Since this documentation block belongs to the class Test no link to
+ Test is generated.
+
+ Two ways to link to a constructor are: #Test and Test().
+
+ Links to the destructor are: #~Test and ~Test().
+
+ A link to a member in this class: member().
+
+ More specific links to the each of the overloaded members:
+ member(int) and member(int,int).
+
+ A link to the variable #var.
+
+ A link to the global typedef ::B.
+
+ A link to the global enumeration type #GlobEnum.
+
+ A link to the define ABS(x).
+
+ A link to a variable \link #var using another text\endlink as a link.
+
+ A link to the enumeration type #EType.
+
+ A link to some enumeration values: \link Test::Val1 Val1 \endlink and ::GVal1.
+
+ And last but not least a link to a file: autolink.cpp.
+
+ \sa Inside a see also section any word is checked, so EType,
+ Val1, GVal1, ~Test and member will be replaced by links in HTML.
+*/
+
+class Test
+{
+ public:
+ Test(); //!< constructor
+ ~Test(); //!< destructor
+ void member(int); /**< A member function. Details. */
+ void member(int,int); /**< An overloaded member function. Details */
+
+ /** An enum type. More details */
+ enum EType {
+ Val1, /**< enum value 1 */
+ Val2 /**< enum value 2 */
+ };
+
+ protected:
+ int var; /**< A member variable */
+};
+
+/*! details. */
+Test::Test() { }
+
+/*! details. */
+Test::~Test() { }
+
+/*! A global variable. */
+int globVar;
+
+/*! A global enum. */
+enum GlobEnum {
+ GVal1, /*!< global enum value 1 */
+ GVal2 /*!< global enum value 2 */
+ };
+
+/*!
+ * A macro definition.
+ */
+#define ABS(x) (((x)>0)?(x):-(x))
+
+typedef Test B;
+
+/*! \fn typedef Test B
+ * A type definition.
+ */
diff --git a/examples/class.cfg b/examples/class.cfg
new file mode 100644
index 0000000..f2c4796
--- /dev/null
+++ b/examples/class.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Class Command"
+OUTPUT_DIRECTORY = class
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = class.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/class.h b/examples/class.h
new file mode 100644
index 0000000..e5a9121
--- /dev/null
+++ b/examples/class.h
@@ -0,0 +1,11 @@
+/* A dummy class */
+
+class Test
+{
+};
+
+/*! \class Test class.h "inc/class.h"
+ * \brief This is a test class.
+ *
+ * Some details about the Test class
+ */
diff --git a/examples/dbusxml.cfg b/examples/dbusxml.cfg
new file mode 100644
index 0000000..23b9dea
--- /dev/null
+++ b/examples/dbusxml.cfg
@@ -0,0 +1,12 @@
+PROJECT_NAME = "DBusXMLDocs"
+OUTPUT_DIRECTORY = dbusxml
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = dbusxml.xml
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+EXTRACT_ALL = YES
+SEARCHENGINE = NO
+EXTENSION_MAPPING = xml=dbusxml
diff --git a/examples/dbusxml.xml b/examples/dbusxml.xml
new file mode 100644
index 0000000..4ab7f78
--- /dev/null
+++ b/examples/dbusxml.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" ?>
+<!-- Comment -->
+<!--*< File comment -->
+<node name="/SomeNode" xmlns:dx="http://psiamp.org/dtd/doxygen_dbusxml.dtd">
+ <!--* test struct outside a namespace and interface -->
+ <dx:struct name="StructOutsideNamespace">
+ <!--* member 1 -->
+ <dx:member name="member1" type="s"/>
+ <!--* complex member 1 -->
+ <dx:member name="complexMember1" type="(ssu)"/>
+ </dx:struct>
+
+ <!--* Test flag set -->
+ <dx:flagset name="flagset">
+ <!--* Flag 1 of flagset. -->
+ <dx:value name="FLAG1"/>
+ </dx:flagset>
+
+ <!--* namespace comment -->
+ <dx:namespace name="SomeNamespace">
+ <!--* struct inside a namespace -->
+ <dx:struct name="StructInNamespace">
+ <!--* member 2 -->
+ <dx:member name="member2" type="s"/>
+ </dx:struct>
+ </dx:namespace>
+ <!--* Documentation on the interface -->
+ <interface name="nl.stack.doxygen.test.interface">
+ <!--* Test Enum documentation -->
+ <dx:enum name="TestEnum">
+ <!--* key 1 with value 13 -->
+ <dx:value name="KEY1" value="13"/>
+ <!--* key 2 without a value -->
+ <dx:value name="KEY2"/>
+ </dx:enum>
+
+ <!--* struct inside a interface -->
+ <dx:struct name="StructInInterface">
+ <!--* member 3 -->
+ <dx:member name="member3" type="s"/>
+ <!--* Struct in a struct -->
+ <dx:struct name="StructInAStruct">
+ <!--* member4 -->
+ <dx:member name="member4" type="s"/>
+ </dx:struct>
+ <!--* struct member -->
+ <dx:member name="structMembor" type="(s)" named-type="StructInAStruct"/>
+ </dx:struct>
+ <!--* Document method
+
+ Some extended documentation for the method.
+
+ @param[in] input blah.
+ @param[out] output blub
+ -->
+ <method name="method">
+ <arg direction="in" name="input" type="(s(s))" named-type="::nl::stack::doxygen::test::interface::StructInInterface"/>
+ <arg direction="out" type="v" name="output"/>
+ </method>
+
+ <signal name="signal">
+ <!--*< Documentation for signal.
+
+ @param parameter some parameter.
+ -->
+ <arg name="parameter" type="s"/>
+ </signal>
+
+ <!--* property documentation -->
+ <property name="property" type="s" access="readwrite"/>
+
+ <!--* property documentation read-only -->
+ <property name="propertyRead" type="s" access="read"/>
+ <!--* property documentation write-only -->
+ <property name="propertyWrite" type="s" access="write"/>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/examples/define.cfg b/examples/define.cfg
new file mode 100644
index 0000000..547591e
--- /dev/null
+++ b/examples/define.cfg
@@ -0,0 +1,11 @@
+PROJECT_NAME = "Define Command"
+OUTPUT_DIRECTORY = define
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = define.h
+ENABLE_PREPROCESSING = YES
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/define.h b/examples/define.h
new file mode 100644
index 0000000..c330447
--- /dev/null
+++ b/examples/define.h
@@ -0,0 +1,18 @@
+/*! \file define.h
+ \brief testing defines
+
+ This is to test the documentation of defines.
+*/
+
+/*!
+ \def MAX(x,y)
+ Computes the maximum of \a x and \a y.
+*/
+
+/*!
+ Computes the absolute value of its argument \a x.
+*/
+#define ABS(x) (((x)>0)?(x):-(x))
+#define MAX(x,y) ((x)>(y)?(x):(y))
+#define MIN(x,y) ((x)>(y)?(y):(x))
+ /*!< Computes the minimum of \a x and \a y. */
diff --git a/examples/diagrams.cfg b/examples/diagrams.cfg
new file mode 100644
index 0000000..9bc5551
--- /dev/null
+++ b/examples/diagrams.cfg
@@ -0,0 +1,14 @@
+PROJECT_NAME = "Diagrams"
+OUTPUT_DIRECTORY = diagrams
+HAVE_DOT = YES
+EXTRACT_ALL = YES
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+ENABLE_PREPROCESSING = YES
+INPUT = .
+FILE_PATTERNS = diagrams_*.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/diagrams_a.h b/examples/diagrams_a.h
new file mode 100644
index 0000000..047a8ab
--- /dev/null
+++ b/examples/diagrams_a.h
@@ -0,0 +1,4 @@
+#ifndef _DIAGRAMS_A_H
+#define _DIAGRAMS_A_H
+class A { public: A *m_self; };
+#endif
diff --git a/examples/diagrams_b.h b/examples/diagrams_b.h
new file mode 100644
index 0000000..5fcd247
--- /dev/null
+++ b/examples/diagrams_b.h
@@ -0,0 +1,5 @@
+#ifndef _DIAGRAMS_B_H
+#define _DIAGRAMS_B_H
+class A;
+class B { public: A *m_a; };
+#endif
diff --git a/examples/diagrams_c.h b/examples/diagrams_c.h
new file mode 100644
index 0000000..e4ec11d
--- /dev/null
+++ b/examples/diagrams_c.h
@@ -0,0 +1,6 @@
+#ifndef _DIAGRAMS_C_H
+#define _DIAGRAMS_C_H
+#include "diagrams_c.h"
+class D;
+class C : public A { public: D *m_d; };
+#endif
diff --git a/examples/diagrams_d.h b/examples/diagrams_d.h
new file mode 100644
index 0000000..3e635ce
--- /dev/null
+++ b/examples/diagrams_d.h
@@ -0,0 +1,7 @@
+#ifndef _DIAGRAM_D_H
+#define _DIAGRAM_D_H
+#include "diagrams_a.h"
+#include "diagrams_b.h"
+class C;
+class D : virtual protected A, private B { public: C m_c; };
+#endif
diff --git a/examples/diagrams_e.h b/examples/diagrams_e.h
new file mode 100644
index 0000000..5282388
--- /dev/null
+++ b/examples/diagrams_e.h
@@ -0,0 +1,5 @@
+#ifndef _DIAGRAM_E_H
+#define _DIAGRAM_E_H
+#include "diagrams_d.h"
+class E : public D {};
+#endif
diff --git a/examples/docstring.cfg b/examples/docstring.cfg
new file mode 100644
index 0000000..2a5cd9a
--- /dev/null
+++ b/examples/docstring.cfg
@@ -0,0 +1,11 @@
+PROJECT_NAME = "Python"
+OUTPUT_DIRECTORY = docstring
+EXTRACT_ALL = YES
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+OPTIMIZE_OUTPUT_JAVA = YES
+INPUT = docstring.py
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/docstring.py b/examples/docstring.py
new file mode 100644
index 0000000..07b13e0
--- /dev/null
+++ b/examples/docstring.py
@@ -0,0 +1,27 @@
+"""@package docstring
+Documentation for this module.
+
+More details.
+"""
+
+def func():
+ """Documentation for a function.
+
+ More details.
+ """
+ pass
+
+class PyClass:
+ """Documentation for a class.
+
+ More details.
+ """
+
+ def __init__(self):
+ """The constructor."""
+ self._memVar = 0;
+
+ def PyMethod(self):
+ """Documentation for a method."""
+ pass
+
diff --git a/examples/enum.cfg b/examples/enum.cfg
new file mode 100644
index 0000000..ed83670
--- /dev/null
+++ b/examples/enum.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Enum Command"
+OUTPUT_DIRECTORY = enum
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = enum.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/enum.h b/examples/enum.h
new file mode 100644
index 0000000..4c54fab
--- /dev/null
+++ b/examples/enum.h
@@ -0,0 +1,24 @@
+class Test
+{
+ public:
+ enum TEnum { Val1, Val2 };
+
+ /*! Another enum, with inline docs */
+ enum AnotherEnum
+ {
+ V1, /*!< value 1 */
+ V2 /*!< value 2 */
+ };
+};
+
+/*! \class Test
+ * The class description.
+ */
+
+/*! \enum Test::TEnum
+ * A description of the enum type.
+ */
+
+/*! \var Test::TEnum Test::Val1
+ * The description of the first enum value.
+ */
diff --git a/examples/example.cfg b/examples/example.cfg
new file mode 100644
index 0000000..4c5c869
--- /dev/null
+++ b/examples/example.cfg
@@ -0,0 +1,12 @@
+PROJECT_NAME = "Example Command"
+OUTPUT_DIRECTORY = example
+GENERATE_TAGFILE = example.tag
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = example.cpp
+EXAMPLE_PATH = example_test.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/example.cpp b/examples/example.cpp
new file mode 100644
index 0000000..230d6ec
--- /dev/null
+++ b/examples/example.cpp
@@ -0,0 +1,19 @@
+/** A Test class.
+ * More details about this class.
+ */
+
+class Test
+{
+ public:
+ /** An example member function.
+ * More details about this function.
+ */
+ void example();
+};
+
+void Test::example() {}
+
+/** \example example_test.cpp
+ * This is an example of how to use the Test class.
+ * More details about this example.
+ */
diff --git a/examples/example.tag b/examples/example.tag
new file mode 100644
index 0000000..98b2efd
--- /dev/null
+++ b/examples/example.tag
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<tagfile>
+ <compound kind="class">
+ <name>Test</name>
+ <filename>class_test.html</filename>
+ <member kind="function">
+ <type>void</type>
+ <name>example</name>
+ <anchorfile>class_test.html</anchorfile>
+ <anchor>a47b775f65718978f1ffcd96376f8ecfa</anchor>
+ <arglist>()</arglist>
+ </member>
+ </compound>
+</tagfile>
diff --git a/examples/example_test.cpp b/examples/example_test.cpp
new file mode 100644
index 0000000..a7e1643
--- /dev/null
+++ b/examples/example_test.cpp
@@ -0,0 +1,5 @@
+void main()
+{
+ Test t;
+ t.example();
+}
diff --git a/examples/file.cfg b/examples/file.cfg
new file mode 100644
index 0000000..e54b1c7
--- /dev/null
+++ b/examples/file.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "File Command"
+OUTPUT_DIRECTORY = file
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = file.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/file.h b/examples/file.h
new file mode 100644
index 0000000..8dff6cb
--- /dev/null
+++ b/examples/file.h
@@ -0,0 +1,10 @@
+/** \file file.h
+ * A brief file description.
+ * A more elaborated file description.
+ */
+
+/**
+ * A global integer value.
+ * More details about this value.
+ */
+extern int globalValue;
diff --git a/examples/func.cfg b/examples/func.cfg
new file mode 100644
index 0000000..32c3190
--- /dev/null
+++ b/examples/func.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Fn Command"
+OUTPUT_DIRECTORY = func
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = func.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/func.h b/examples/func.h
new file mode 100644
index 0000000..b335448
--- /dev/null
+++ b/examples/func.h
@@ -0,0 +1,21 @@
+class Test
+{
+ public:
+ const char *member(char,int) throw(std::out_of_range);
+};
+
+const char *Test::member(char c,int n) throw(std::out_of_range) {}
+
+/*! \class Test
+ * \brief Test class.
+ *
+ * Details about Test.
+ */
+
+/*! \fn const char *Test::member(char c,int n)
+ * \brief A member function.
+ * \param c a character.
+ * \param n an integer.
+ * \exception std::out_of_range parameter is out of range.
+ * \return a character pointer.
+ */
diff --git a/examples/group.cfg b/examples/group.cfg
new file mode 100644
index 0000000..98cc27e
--- /dev/null
+++ b/examples/group.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Grouping"
+OUTPUT_DIRECTORY = group
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = group.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/group.cpp b/examples/group.cpp
new file mode 100644
index 0000000..b120b90
--- /dev/null
+++ b/examples/group.cpp
@@ -0,0 +1,88 @@
+/** @defgroup group1 The First Group
+ * This is the first group
+ * @{
+ */
+
+/** @brief class C1 in group 1 */
+class C1 {};
+
+/** @brief class C2 in group 1 */
+class C2 {};
+
+/** function in group 1 */
+void func() {}
+
+/** @} */ // end of group1
+
+/**
+ * @defgroup group2 The Second Group
+ * This is the second group
+ */
+
+/** @defgroup group3 The Third Group
+ * This is the third group
+ */
+
+/** @defgroup group4 The Fourth Group
+ * @ingroup group3
+ * Group 4 is a subgroup of group 3
+ */
+
+/**
+ * @ingroup group2
+ * @brief class C3 in group 2
+ */
+class C3 {};
+
+/** @ingroup group2
+ * @brief class C4 in group 2
+ */
+class C4 {};
+
+/** @ingroup group3
+ * @brief class C5 in @link group3 the third group at endlink.
+ */
+class C5 {};
+
+/** @ingroup group1 group2 group3 group4
+ * namespace N1 is in four groups
+ * @sa @link group1 The first group at endlink, group2, group3, group4
+ *
+ * Also see @ref mypage2
+ */
+namespace N1 {};
+
+/** @file
+ * @ingroup group3
+ * @brief this file in group 3
+ */
+
+/** @defgroup group5 The Fifth Group
+ * This is the fifth group
+ * @{
+ */
+
+/** @page mypage1 This is a section in group 5
+ * Text of the first section
+ */
+
+/** @page mypage2 This is another section in group 5
+ * Text of the second section
+ */
+
+/** @} */ // end of group5
+
+/** @addtogroup group1
+ *
+ * More documentation for the first group.
+ * @{
+ */
+
+/** another function in group 1 */
+void func2() {}
+
+/** yet another function in group 1 */
+void func3() {}
+
+/** @} */ // end of group1
+
diff --git a/examples/include.cfg b/examples/include.cfg
new file mode 100644
index 0000000..8516b32
--- /dev/null
+++ b/examples/include.cfg
@@ -0,0 +1,11 @@
+PROJECT_NAME = "Include Command"
+OUTPUT_DIRECTORY = include
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = include.cpp
+EXAMPLE_PATH = example_test.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/include.cpp b/examples/include.cpp
new file mode 100644
index 0000000..674ad13
--- /dev/null
+++ b/examples/include.cpp
@@ -0,0 +1,22 @@
+
+/*! A test class. */
+
+class Test
+{
+ public:
+ /// a member function
+ void example();
+};
+
+/*! \page example
+ * \dontinclude example_test.cpp
+ * Our main function starts like this:
+ * \skip main
+ * \until {
+ * First we create an object \c t of the Test class.
+ * \skipline Test
+ * Then we call the example member function
+ * \line example
+ * After that our little test routine ends.
+ * \line }
+ */
diff --git a/examples/jdstyle.cfg b/examples/jdstyle.cfg
new file mode 100644
index 0000000..02bf18c
--- /dev/null
+++ b/examples/jdstyle.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "JavaDoc Style"
+OUTPUT_DIRECTORY = jdstyle
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = jdstyle.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/jdstyle.cpp b/examples/jdstyle.cpp
new file mode 100644
index 0000000..bd8b9a7
--- /dev/null
+++ b/examples/jdstyle.cpp
@@ -0,0 +1,66 @@
+/**
+ * A test class. A more elaborate class description.
+ */
+
+class Test
+{
+ public:
+
+ /**
+ * An enum.
+ * More detailed enum description.
+ */
+
+ enum TEnum {
+ TVal1, /**< enum value TVal1. */
+ TVal2, /**< enum value TVal2. */
+ TVal3 /**< enum value TVal3. */
+ }
+ *enumPtr, /**< enum pointer. Details. */
+ enumVar; /**< enum variable. Details. */
+
+ /**
+ * A constructor.
+ * A more elaborate description of the constructor.
+ */
+ Test();
+
+ /**
+ * A destructor.
+ * A more elaborate description of the destructor.
+ */
+ ~Test();
+
+ /**
+ * a normal member taking two arguments and returning an integer value.
+ * @param a an integer argument.
+ * @param s a constant character pointer.
+ * @see Test()
+ * @see ~Test()
+ * @see testMeToo()
+ * @see publicVar()
+ * @return The test results
+ */
+ int testMe(int a,const char *s);
+
+ /**
+ * A pure virtual member.
+ * @see testMe()
+ * @param c1 the first argument.
+ * @param c2 the second argument.
+ */
+ virtual void testMeToo(char c1,char c2) = 0;
+
+ /**
+ * a public variable.
+ * Details.
+ */
+ int publicVar;
+
+ /**
+ * a function variable.
+ * Details.
+ */
+ int (*handler)(int a,int b);
+};
+
diff --git a/examples/manual.c b/examples/manual.c
new file mode 100644
index 0000000..fac6832
--- /dev/null
+++ b/examples/manual.c
@@ -0,0 +1,87 @@
+/**
+ * \file manual.c
+ */
+
+typedef struct Object Object; //!< Object type
+typedef struct Vehicle Vehicle; //!< Vehicle type
+typedef struct Car Car; //!< Car type
+typedef struct Truck Truck; //!< Truck type
+
+/*!
+ * Base object class.
+ */
+struct Object
+{
+ int ref; //!< \private Reference count.
+};
+
+
+/*!
+ * Increments object reference count by one.
+ * \public \memberof Object
+ */
+static Object * objRef(Object *obj);
+
+
+/*!
+ * Decrements object reference count by one.
+ * \public \memberof Object
+ */
+static Object * objUnref(Object *obj);
+
+
+/*!
+ * Vehicle class.
+ * \extends Object
+ */
+struct Vehicle
+{
+ Object base; //!< \protected Base class.
+};
+
+
+/*!
+ * Starts the vehicle.
+ * \public \memberof Vehicle
+ */
+void vehicleStart(Vehicle *obj);
+
+
+/*!
+ * Stops the vehicle.
+ * \public \memberof Vehicle
+ */
+void vehicleStop(Vehicle *obj);
+
+
+/*!
+ * Car class.
+ * \extends Vehicle
+ */
+struct Car
+{
+ Vehicle base; //!< \protected Base class.
+};
+
+
+/*!
+ * Truck class.
+ * \extends Vehicle
+ */
+struct Truck
+{
+ Vehicle base; //!< \protected Base class.
+};
+
+
+/*!
+ * Main function.
+ *
+ * Ref vehicleStart(), objRef(), objUnref().
+ */
+int main(void)
+{
+ Car c;
+ vehicleStart((Vehicle*) &c);
+}
+
diff --git a/examples/manual.cfg b/examples/manual.cfg
new file mode 100644
index 0000000..9359842
--- /dev/null
+++ b/examples/manual.cfg
@@ -0,0 +1,16 @@
+PROJECT_NAME = "Manual inheritance and membership"
+OUTPUT_DIRECTORY = manual
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = manual.c
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+TYPEDEF_HIDES_STRUCT = YES
+INLINE_SOURCES = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+SEARCHENGINE = NO
diff --git a/examples/memgrp.cfg b/examples/memgrp.cfg
new file mode 100644
index 0000000..a69c33c
--- /dev/null
+++ b/examples/memgrp.cfg
@@ -0,0 +1,11 @@
+PROJECT_NAME = "Member Grouping"
+OUTPUT_DIRECTORY = memgrp
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = memgrp.cpp
+QUIET = YES
+DISTRIBUTE_GROUP_DOC = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/memgrp.cpp b/examples/memgrp.cpp
new file mode 100644
index 0000000..77f03a4
--- /dev/null
+++ b/examples/memgrp.cpp
@@ -0,0 +1,41 @@
+/** A class. Details */
+class Test
+{
+ public:
+ //@{
+ /** Same documentation for both members. Details */
+ void func1InGroup1();
+ void func2InGroup1();
+ //@}
+
+ /** Function without group. Details. */
+ void ungroupedFunction();
+ void func1InGroup2();
+ protected:
+ void func2InGroup2();
+};
+
+void Test::func1InGroup1() {}
+void Test::func2InGroup1() {}
+
+/** @name Group2
+ * Description of group 2.
+ */
+///@{
+/** Function 2 in group 2. Details. */
+void Test::func2InGroup2() {}
+/** Function 1 in group 2. Details. */
+void Test::func1InGroup2() {}
+///@}
+
+/*! \file
+ * docs for this file
+ */
+
+//!@{
+//! one description for all members of this group
+//! (because DISTRIBUTE_GROUP_DOC is YES in the config file)
+#define A 1
+#define B 2
+void glob_func();
+//!@}
diff --git a/examples/mux.cfg b/examples/mux.cfg
new file mode 100644
index 0000000..ccb0f05
--- /dev/null
+++ b/examples/mux.cfg
@@ -0,0 +1,16 @@
+PROJECT_NAME = Mux
+OUTPUT_DIRECTORY = mux
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = mux.vhdl
+OPTIMIZE_OUTPUT_VHDL = YES
+QUIET = YES
+INHERIT_DOCS = YES
+EXTRACT_PRIVATE = YES
+HIDE_SCOPE_NAMES = YES
+INHERIT_DOCS = NO
+SEARCHENGINE = NO
+ENABLE_PREPROCESSING = NO
+EXTRACT_PACKAGE = YES
diff --git a/examples/mux.vhdl b/examples/mux.vhdl
new file mode 100644
index 0000000..e2c6345
--- /dev/null
+++ b/examples/mux.vhdl
@@ -0,0 +1,32 @@
+-------------------------------------------------------
+--! @file
+--! @brief 2:1 Mux using with-select
+-------------------------------------------------------
+
+--! Use standard library
+library ieee;
+--! Use logic elements
+ use ieee.std_logic_1164.all;
+
+--! Mux entity brief description
+
+--! Detailed description of this
+--! mux design element.
+entity mux_using_with is
+ port (
+ din_0 : in std_logic; --! Mux first input
+ din_1 : in std_logic; --! Mux Second input
+ sel : in std_logic; --! Select input
+ mux_out : out std_logic --! Mux output
+ );
+end entity;
+
+--! @brief Architecture definition of the MUX
+--! @details More details about this mux element.
+architecture behavior of mux_using_with is
+begin
+ with (sel) select
+ mux_out <= din_0 when '0',
+ din_1 when others;
+end architecture;
+
diff --git a/examples/overload.cfg b/examples/overload.cfg
new file mode 100644
index 0000000..d29cb9c
--- /dev/null
+++ b/examples/overload.cfg
@@ -0,0 +1,11 @@
+PROJECT_NAME = "Overloaded Command"
+OUTPUT_DIRECTORY = overload
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+SORT_MEMBER_DOCS = NO
+INPUT = overload.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/overload.cpp b/examples/overload.cpp
new file mode 100644
index 0000000..02bcced
--- /dev/null
+++ b/examples/overload.cpp
@@ -0,0 +1,25 @@
+class Test
+{
+ public:
+ void drawRect(int,int,int,int);
+ void drawRect(const Rect &r);
+};
+
+void Test::drawRect(int x,int y,int w,int h) {}
+void Test::drawRect(const Rect &r) {}
+
+/*! \class Test
+ * \brief A short description.
+ *
+ * More text.
+ */
+
+/*! \fn void Test::drawRect(int x,int y,int w,int h)
+ * This command draws a rectangle with a left upper corner at ( \a x , \a y ),
+ * width \a w and height \a h.
+ */
+
+/*!
+ * \overload void Test::drawRect(const Rect &r)
+ */
+
diff --git a/examples/page.cfg b/examples/page.cfg
new file mode 100644
index 0000000..cd1ff84
--- /dev/null
+++ b/examples/page.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Page Command"
+OUTPUT_DIRECTORY = page
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = page.doc
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/page.doc b/examples/page.doc
new file mode 100644
index 0000000..f83f896
--- /dev/null
+++ b/examples/page.doc
@@ -0,0 +1,15 @@
+/*! \page page1 A documentation page
+ \tableofcontents
+ Leading text.
+ \section sec An example section
+ This page contains the subsections \ref subsection1 and \ref subsection2.
+ For more info see page \ref page2.
+ \subsection subsection1 The first subsection
+ Text.
+ \subsection subsection2 The second subsection
+ More text.
+*/
+
+/*! \page page2 Another page
+ Even more info.
+*/
diff --git a/examples/par.cfg b/examples/par.cfg
new file mode 100644
index 0000000..de6caa9
--- /dev/null
+++ b/examples/par.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Par Command"
+OUTPUT_DIRECTORY = par
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = par.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/par.cpp b/examples/par.cpp
new file mode 100644
index 0000000..6fd2c4e
--- /dev/null
+++ b/examples/par.cpp
@@ -0,0 +1,20 @@
+/*! \class Test
+ * Normal text.
+ *
+ * \par User defined paragraph:
+ * Contents of the paragraph.
+ *
+ * \par
+ * New paragraph under the same heading.
+ *
+ * \note
+ * This note consists of two paragraphs.
+ * This is the first paragraph.
+ *
+ * \par
+ * And this is the second paragraph.
+ *
+ * More normal text.
+ */
+
+class Test {};
diff --git a/examples/pyexample.cfg b/examples/pyexample.cfg
new file mode 100644
index 0000000..27db0f7
--- /dev/null
+++ b/examples/pyexample.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Python"
+OUTPUT_DIRECTORY = pyexample
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+OPTIMIZE_OUTPUT_JAVA = YES
+INPUT = pyexample.py
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/pyexample.py b/examples/pyexample.py
new file mode 100644
index 0000000..666c25b
--- /dev/null
+++ b/examples/pyexample.py
@@ -0,0 +1,30 @@
+## @package pyexample
+# Documentation for this module.
+#
+# More details.
+
+## Documentation for a function.
+#
+# More details.
+def func():
+ pass
+
+## Documentation for a class.
+#
+# More details.
+class PyClass:
+
+ ## The constructor.
+ def __init__(self):
+ self._memVar = 0;
+
+ ## Documentation for a method.
+ # @param self The object pointer.
+ def PyMethod(self):
+ pass
+
+ ## A class variable.
+ classVar = 0;
+
+ ## @var _memVar
+ # a member variable
diff --git a/examples/qtstyle.cfg b/examples/qtstyle.cfg
new file mode 100644
index 0000000..0a930be
--- /dev/null
+++ b/examples/qtstyle.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Qt Style"
+OUTPUT_DIRECTORY = qtstyle
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = qtstyle.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/qtstyle.cpp b/examples/qtstyle.cpp
new file mode 100644
index 0000000..e24d541
--- /dev/null
+++ b/examples/qtstyle.cpp
@@ -0,0 +1,65 @@
+//! A test class.
+/*!
+ A more elaborate class description.
+*/
+
+class Test
+{
+ public:
+
+ //! An enum.
+ /*! More detailed enum description. */
+ enum TEnum {
+ TVal1, /*!< Enum value TVal1. */
+ TVal2, /*!< Enum value TVal2. */
+ TVal3 /*!< Enum value TVal3. */
+ }
+ //! Enum pointer.
+ /*! Details. */
+ *enumPtr,
+ //! Enum variable.
+ /*! Details. */
+ enumVar;
+
+ //! A constructor.
+ /*!
+ A more elaborate description of the constructor.
+ */
+ Test();
+
+ //! A destructor.
+ /*!
+ A more elaborate description of the destructor.
+ */
+ ~Test();
+
+ //! A normal member taking two arguments and returning an integer value.
+ /*!
+ \param a an integer argument.
+ \param s a constant character pointer.
+ \return The test results
+ \sa Test(), ~Test(), testMeToo() and publicVar()
+ */
+ int testMe(int a,const char *s);
+
+ //! A pure virtual member.
+ /*!
+ \sa testMe()
+ \param c1 the first argument.
+ \param c2 the second argument.
+ */
+ virtual void testMeToo(char c1,char c2) = 0;
+
+ //! A public variable.
+ /*!
+ Details.
+ */
+ int publicVar;
+
+ //! A function variable.
+ /*!
+ Details.
+ */
+ int (*handler)(int a,int b);
+};
+
diff --git a/examples/relates.cfg b/examples/relates.cfg
new file mode 100644
index 0000000..4e1d90b
--- /dev/null
+++ b/examples/relates.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Relates Command"
+OUTPUT_DIRECTORY = relates
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = relates.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/relates.cpp b/examples/relates.cpp
new file mode 100644
index 0000000..c6f7dc9
--- /dev/null
+++ b/examples/relates.cpp
@@ -0,0 +1,23 @@
+/*!
+ * A String class.
+ */
+
+class String
+{
+ friend int strcmp(const String &,const String &);
+};
+
+/*!
+ * Compares two strings.
+ */
+
+int strcmp(const String &s1,const String &s2)
+{
+}
+
+/*! \relates String
+ * A string debug function.
+ */
+void stringDebug()
+{
+}
diff --git a/examples/restypedef.cfg b/examples/restypedef.cfg
new file mode 100644
index 0000000..c55926e
--- /dev/null
+++ b/examples/restypedef.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Resolving Typedefs"
+OUTPUT_DIRECTORY = restypedef
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = restypedef.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/restypedef.cpp b/examples/restypedef.cpp
new file mode 100644
index 0000000..923cf70
--- /dev/null
+++ b/examples/restypedef.cpp
@@ -0,0 +1,25 @@
+/*! \file restypedef.cpp
+ * An example of resolving typedefs.
+ */
+
+/*! \struct CoordStruct
+ * A coordinate pair.
+ */
+struct CoordStruct
+{
+ /*! The x coordinate */
+ float x;
+ /*! The y coordinate */
+ float y;
+};
+
+/*! Creates a type name for CoordStruct */
+typedef CoordStruct Coord;
+
+/*!
+ * This function returns the addition of \a c1 and \a c2, i.e:
+ * (c1.x+c2.x,c1.y+c2.y)
+ */
+Coord add(Coord c1,Coord c2)
+{
+}
diff --git a/examples/structcmd.cfg b/examples/structcmd.cfg
new file mode 100644
index 0000000..f956ad4
--- /dev/null
+++ b/examples/structcmd.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Structural commands"
+OUTPUT_DIRECTORY = structcmd
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = structcmd.h
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/structcmd.h b/examples/structcmd.h
new file mode 100644
index 0000000..3e27029
--- /dev/null
+++ b/examples/structcmd.h
@@ -0,0 +1,57 @@
+/*! \file structcmd.h
+ \brief A Documented file.
+
+ Details.
+*/
+
+/*! \def MAX(a,b)
+ \brief A macro that returns the maximum of \a a and \a b.
+
+ Details.
+*/
+
+/*! \var typedef unsigned int UINT32
+ \brief A type definition for a .
+
+ Details.
+*/
+
+/*! \var int errno
+ \brief Contains the last error code.
+
+ \warning Not thread safe!
+*/
+
+/*! \fn int open(const char *pathname,int flags)
+ \brief Opens a file descriptor.
+
+ \param pathname The name of the descriptor.
+ \param flags Opening flags.
+*/
+
+/*! \fn int close(int fd)
+ \brief Closes the file descriptor \a fd.
+ \param fd The descriptor to close.
+*/
+
+/*! \fn size_t write(int fd,const char *buf, size_t count)
+ \brief Writes \a count bytes from \a buf to the filedescriptor \a fd.
+ \param fd The descriptor to write to.
+ \param buf The data buffer to write.
+ \param count The number of bytes to write.
+*/
+
+/*! \fn int read(int fd,char *buf,size_t count)
+ \brief Read bytes from a file descriptor.
+ \param fd The descriptor to read from.
+ \param buf The buffer to read into.
+ \param count The number of bytes to read.
+*/
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+typedef unsigned int UINT32;
+int errno;
+int open(const char *,int);
+int close(int);
+size_t write(int,const char *, size_t);
+int read(int,char *,size_t);
diff --git a/examples/tag.cfg b/examples/tag.cfg
new file mode 100644
index 0000000..3627281
--- /dev/null
+++ b/examples/tag.cfg
@@ -0,0 +1,12 @@
+PROJECT_NAME = "Tag Files"
+OUTPUT_DIRECTORY = tag
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = tag.cpp
+TAGFILES = example.tag=../../example/html
+PERL_PATH = perl
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/tag.cpp b/examples/tag.cpp
new file mode 100644
index 0000000..6497dd4
--- /dev/null
+++ b/examples/tag.cpp
@@ -0,0 +1,9 @@
+/*! A class that is inherited from the external class Test.
+*/
+
+class Tag : public Test
+{
+ public:
+ /*! an overloaded member. */
+ void example();
+};
diff --git a/examples/tclexample.cfg b/examples/tclexample.cfg
new file mode 100644
index 0000000..bde5cc4
--- /dev/null
+++ b/examples/tclexample.cfg
@@ -0,0 +1,12 @@
+PROJECT_NAME = "Tcl"
+OUTPUT_DIRECTORY = tclexample
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = tclexample.tcl
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
+INLINE_SOURCES = YES
+HIDE_UNDOC_MEMBERS = YES
diff --git a/examples/tclexample.tcl b/examples/tclexample.tcl
new file mode 100644
index 0000000..6edef66
--- /dev/null
+++ b/examples/tclexample.tcl
@@ -0,0 +1,82 @@
+## \file tclexample.tcl
+# File documentation.
+#\verbatim
+
+# Startup code:\
+exec tclsh "$0" "$@"
+#\endverbatim
+## Documented namespace \c ns .
+# The code is inserted here:
+#\code
+namespace eval ns {
+ ## Documented proc \c ns_proc .
+ # param[in] arg some argument
+ proc ns_proc {arg} {}
+ ## Documented var \c ns_var .
+ # Some documentation.
+ variable ns_var
+ ## Documented itcl class \c itcl_class .
+ itcl::class itcl_class {
+ ## Create object.
+ constructor {args} {eval $args}
+ ## Destroy object.
+ destructor {exit}
+ ## Documented itcl method \c itcl_method_x .
+ # param[in] arg Argument
+ private method itcl_method_x {arg}
+ ## Documented itcl method \c itcl_method_y .
+ # param[in] arg Argument
+ protected method itcl_method_y {arg} {}
+ ## Documented itcl method \c itcl_method_z .
+ # param[in] arg Argument
+ public method itcl_method_z {arg} {}
+ ## Documented common itcl var \c itcl_Var .
+ common itcl_Var
+ ## \protectedsection
+
+ variable itcl_var1;#< Documented itcl var \c itcl_var1 .
+ variable itcl_var2;#< Documented itcl var \c itcl_var2 .
+ }
+ ## Documented oo class \c oo_class .
+ oo::class create oo_class {
+ ## Create object.
+ # Configure with args
+ constructor {args} {eval $args}
+ ## Destroy object.
+ # Exit.
+ destructor {exit}
+ ## Documented oo var \c oo_var .
+ # Defined inside class
+ variable oo_var
+ ## \private Documented oo method \c oo_method_x .
+ # param[in] arg Argument
+ method oo_method_x {arg} {}
+ ## \protected Documented oo method \c oo_method_y .
+ # param[in] arg Argument
+ method oo_method_y {arg} {}
+ ## \public Documented oo method \c oo_method_z .
+ # param[in] arg Argument
+ method oo_method_z {arg} {}
+ }
+}
+#\endcode
+
+itcl::body ::ns::itcl_class::itcl_method_x {argx} {
+ puts "$argx OK"
+}
+
+oo::define ns::oo_class {
+ ## \public Outside defined variable \c oo_var_out .
+ # Inside oo_class
+ variable oo_var_out
+}
+
+## Documented global proc \c glob_proc .
+# param[in] arg Argument
+proc glob_proc {arg} {puts $arg}
+
+variable glob_var;#< Documented global var \c glob_var\
+ with newline
+#< and continued line
+
+# end of file
diff --git a/examples/templ.cfg b/examples/templ.cfg
new file mode 100644
index 0000000..c8d9514
--- /dev/null
+++ b/examples/templ.cfg
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Template Test"
+OUTPUT_DIRECTORY = template
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = templ.cpp
+QUIET = YES
+JAVADOC_AUTOBRIEF = YES
+SEARCHENGINE = NO
diff --git a/examples/templ.cpp b/examples/templ.cpp
new file mode 100644
index 0000000..9ed48fb
--- /dev/null
+++ b/examples/templ.cpp
@@ -0,0 +1,35 @@
+
+/*! A template class */
+template<class T,int i=100> class Test
+{
+ public:
+ Test();
+ Test(const Test &);
+};
+
+/*! complete specialization */
+template<> class Test<void *,200>
+{
+ public:
+ Test();
+};
+
+/*! A partial template specialization */
+template<class T> class Test<T *> : public Test<void *,200>
+{
+ public:
+ Test();
+};
+
+/*! The constructor of the template class*/
+template<class T,int i> Test<T,i>::Test() {}
+
+/*! The copy constructor */
+template<class T,int i> Test<T,i>::Test(const Test &t) {}
+
+/*! The constructor of the partial specilization */
+template<class T> Test<T *>::Test() {}
+
+/*! The constructor of the specilization */
+template<> Test<void *,200>::Test() {}
+
diff --git a/jquery/Makefile b/jquery/Makefile
new file mode 100644
index 0000000..2290ef9
--- /dev/null
+++ b/jquery/Makefile
@@ -0,0 +1,48 @@
+JQUERY_VERSION = 1.7.1
+JQUERY_UI_VERSION = 1.8.18
+HASHCHANGE_VERSION = 1.3
+SCROLL_VERSION = 1.4.2
+POWERTIP_VERSION = 1.2.0
+MINIFIER ?= /usr/local/bin/yuicompressor-2.4.7
+SCRIPTS = jquery-$(JQUERY_VERSION).js \
+ jquery.ui-$(JQUERY_UI_VERSION).core.js \
+ jquery.ui-$(JQUERY_UI_VERSION).widget.js \
+ jquery.ui-$(JQUERY_UI_VERSION).mouse.js \
+ jquery.ui-$(JQUERY_UI_VERSION).resizable.js \
+ jquery.ba-$(HASHCHANGE_VERSION)-hashchange.js \
+ jquery.scrollTo-$(SCROLL_VERSION).js \
+ jquery.powertip-$(POWERTIP_VERSION).js
+RESULTS = jquery_p1.js jquery_p2.js jquery_p3.js \
+ jquery_ui.js jquery_fx.js jquery_pt.js
+
+SCRIPTS_MIN = $(SCRIPTS:%.js=%-min.js)
+
+all: $(RESULTS)
+
+install: $(RESULTS)
+ cp $(RESULTS) ../src/
+
+jquery_ui.js: scripts
+ cat jquery.ui-$(JQUERY_UI_VERSION).core-min.js \
+ jquery.ui-$(JQUERY_UI_VERSION).widget-min.js \
+ jquery.ui-$(JQUERY_UI_VERSION).mouse-min.js \
+ jquery.ui-$(JQUERY_UI_VERSION).resizable-min.js \
+ jquery.ba-$(HASHCHANGE_VERSION)-hashchange-min.js > jquery_ui.js
+
+jquery_pt.js: scripts
+ cat jquery.powertip-$(POWERTIP_VERSION)-min.js > jquery_pt.js
+
+jquery_fx.js: scripts
+ cat jquery.scrollTo-$(SCROLL_VERSION)-min.js > jquery_fx.js
+
+jquery_p1.js jquery_p2.js jquery_p3.js: scripts
+ perl split_jquery.pl jquery-$(JQUERY_VERSION)-min.js $@
+
+scripts: $(SCRIPTS_MIN)
+
+clean:
+ rm -f $(SCRIPTS_MIN) $(RESULTS)
+
+%-min.js: %.js
+ java -jar $(MINIFIER).jar --line-break 13000 $^ > $@
+
diff --git a/jquery/README b/jquery/README
new file mode 100644
index 0000000..7fd4dcd
--- /dev/null
+++ b/jquery/README
@@ -0,0 +1,17 @@
+Doxygen's jquery.js script is composed of minified versions of the following
+packages:
+- jquery 1.7.1: http://jquery.com/download/
+- jquery.ui 1.8.18: https://code.google.com/p/jquery-ui/downloads/list
+ modules required:
+ - jquery.ui.core
+ - jquery.ui.widget
+ - jquery.ui.mouse
+ - jquery.ui.resizable
+- jquery.hashchange: 1.3: http://benalman.com/projects/jquery-hashchange-plugin/
+- jquery.scrollTo: 1.4.2: https://github.com/flesler/jquery.scrollTo
+- jquery.powertip: 1.2.0: http://stevenbenner.github.io/jquery-powertip/
+
+The Makefile will built the jquery_*.js files used by doxygen.
+Some files are split into smaller parts to make sure Visual Studio can compile them
+as strings.
+
diff --git a/jquery/jquery-1.7.1.js b/jquery/jquery-1.7.1.js
new file mode 100644
index 0000000..8ccd0ea
--- /dev/null
+++ b/jquery/jquery-1.7.1.js
@@ -0,0 +1,9266 @@
+/*!
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+ navigator = window.navigator,
+ location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context, rootjQuery );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+ rmsie = /(msie) ([\w.]+)/,
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Matches dashed string for camelizing
+ rdashAlpha = /-([a-z]|[0-9])/ig,
+ rmsPrefix = /^-ms-/,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return ( letter + "" ).toUpperCase();
+ },
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // The deferred used on DOM ready
+ readyList,
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+ constructor: jQuery,
+ init: function( selector, context, rootjQuery ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context && document.body ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = quickExpr.exec( selector );
+ }
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+ doc = ( context ? context.ownerDocument || context : document );
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || rootjQuery ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if ( selector.selector !== undefined ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.7.1",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = this.constructor();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // Add the callback
+ readyList.add( fn );
+
+ return this;
+ },
+
+ eq: function( i ) {
+ i = +i;
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // Either a released hold or an DOMready/load event and not yet ready
+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.fireWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).off( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyList ) {
+ return;
+ }
+
+ readyList = jQuery.Callbacks( "once memory" );
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow: function( obj ) {
+ return obj && typeof obj === "object" && "setInterval" in obj;
+ },
+
+ isNumeric: function( obj ) {
+ return !isNaN( parseFloat(obj) ) && isFinite( obj );
+ },
+
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ try {
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+ } catch ( e ) {
+ // IE8,9 Will throw exceptions on certain host objects #9897
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return ( new Function( "return " + data ) )();
+
+ }
+ jQuery.error( "Invalid JSON: " + data );
+ },
+
+ // Cross-browser xml parsing
+ parseXML: function( data ) {
+ var xml, tmp;
+ try {
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+ } catch( e ) {
+ xml = undefined;
+ }
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+ return xml;
+ },
+
+ noop: function() {},
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction( object );
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: trim ?
+ function( text ) {
+ return text == null ?
+ "" :
+ trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+ var type = jQuery.type( array );
+
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array, i ) {
+ var len;
+
+ if ( array ) {
+ if ( indexOf ) {
+ return indexOf.call( array, elem, i );
+ }
+
+ len = array.length;
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+ for ( ; i < len; i++ ) {
+ // Skip accessing in sparse arrays
+ if ( i in array && array[ i ] === elem ) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length,
+ j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value, key, ret = [],
+ i = 0,
+ length = elems.length,
+ // jquery objects are treated as arrays
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+ // Go through the array, translating each of the items to their
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( key in elems ) {
+ value = callback( elems[ key ], key, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ if ( typeof context === "string" ) {
+ var tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ var args = slice.call( arguments, 2 ),
+ proxy = function() {
+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a collection
+ // The value/s can optionally be executed if it's a function
+ access: function( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ jQuery.access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+ },
+
+ now: function() {
+ return ( new Date() ).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec( ua ) ||
+ ropera.exec( ua ) ||
+ rmsie.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ sub: function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+ jQuery.extend( true, jQuerySub, this );
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ },
+
+ browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+return jQuery;
+
+})();
+
+
+// String to Object flags format cache
+var flagsCache = {};
+
+// Convert String-formatted flags into Object-formatted ones and store in cache
+function createFlags( flags ) {
+ var object = flagsCache[ flags ] = {},
+ i, length;
+ flags = flags.split( /\s+/ );
+ for ( i = 0, length = flags.length; i < length; i++ ) {
+ object[ flags[i] ] = true;
+ }
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * flags: an optional list of space-separated flags that will change how
+ * the callback list behaves
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible flags:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( flags ) {
+
+ // Convert flags from String-formatted to Object-formatted
+ // (we check in cache first)
+ flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
+
+ var // Actual callback list
+ list = [],
+ // Stack of fire calls for repeatable lists
+ stack = [],
+ // Last fire value (for non-forgettable lists)
+ memory,
+ // Flag to know if list is currently firing
+ firing,
+ // First callback to fire (used internally by add and fireWith)
+ firingStart,
+ // End of the loop when firing
+ firingLength,
+ // Index of currently firing callback (modified by remove if needed)
+ firingIndex,
+ // Add one or several callbacks to the list
+ add = function( args ) {
+ var i,
+ length,
+ elem,
+ type,
+ actual;
+ for ( i = 0, length = args.length; i < length; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ // Inspect recursively
+ add( elem );
+ } else if ( type === "function" ) {
+ // Add if not in unique mode and callback is not in
+ if ( !flags.unique || !self.has( elem ) ) {
+ list.push( elem );
+ }
+ }
+ }
+ },
+ // Fire callbacks
+ fire = function( context, args ) {
+ args = args || [];
+ memory = !flags.memory || [ context, args ];
+ firing = true;
+ firingIndex = firingStart || 0;
+ firingStart = 0;
+ firingLength = list.length;
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+ if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
+ memory = true; // Mark as halted
+ break;
+ }
+ }
+ firing = false;
+ if ( list ) {
+ if ( !flags.once ) {
+ if ( stack && stack.length ) {
+ memory = stack.shift();
+ self.fireWith( memory[ 0 ], memory[ 1 ] );
+ }
+ } else if ( memory === true ) {
+ self.disable();
+ } else {
+ list = [];
+ }
+ }
+ },
+ // Actual Callbacks object
+ self = {
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+ var length = list.length;
+ add( arguments );
+ // Do we need to add the callbacks to the
+ // current firing batch?
+ if ( firing ) {
+ firingLength = list.length;
+ // With memory, if we're not firing then
+ // we should call right away, unless previous
+ // firing was halted (stopOnFalse)
+ } else if ( memory && memory !== true ) {
+ firingStart = length;
+ fire( memory[ 0 ], memory[ 1 ] );
+ }
+ }
+ return this;
+ },
+ // Remove a callback from the list
+ remove: function() {
+ if ( list ) {
+ var args = arguments,
+ argIndex = 0,
+ argLength = args.length;
+ for ( ; argIndex < argLength ; argIndex++ ) {
+ for ( var i = 0; i < list.length; i++ ) {
+ if ( args[ argIndex ] === list[ i ] ) {
+ // Handle firingIndex and firingLength
+ if ( firing ) {
+ if ( i <= firingLength ) {
+ firingLength--;
+ if ( i <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ }
+ // Remove the element
+ list.splice( i--, 1 );
+ // If we have some unicity property then
+ // we only need to do this once
+ if ( flags.unique ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return this;
+ },
+ // Control if a given callback is in the list
+ has: function( fn ) {
+ if ( list ) {
+ var i = 0,
+ length = list.length;
+ for ( ; i < length; i++ ) {
+ if ( fn === list[ i ] ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ // Remove all callbacks from the list
+ empty: function() {
+ list = [];
+ return this;
+ },
+ // Have the list do nothing anymore
+ disable: function() {
+ list = stack = memory = undefined;
+ return this;
+ },
+ // Is it disabled?
+ disabled: function() {
+ return !list;
+ },
+ // Lock the list in its current state
+ lock: function() {
+ stack = undefined;
+ if ( !memory || memory === true ) {
+ self.disable();
+ }
+ return this;
+ },
+ // Is it locked?
+ locked: function() {
+ return !stack;
+ },
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( stack ) {
+ if ( firing ) {
+ if ( !flags.once ) {
+ stack.push( [ context, args ] );
+ }
+ } else if ( !( flags.once && memory ) ) {
+ fire( context, args );
+ }
+ }
+ return this;
+ },
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!memory;
+ }
+ };
+
+ return self;
+};
+
+
+
+
+var // Static reference to slice
+ sliceDeferred = [].slice;
+
+jQuery.extend({
+
+ Deferred: function( func ) {
+ var doneList = jQuery.Callbacks( "once memory" ),
+ failList = jQuery.Callbacks( "once memory" ),
+ progressList = jQuery.Callbacks( "memory" ),
+ state = "pending",
+ lists = {
+ resolve: doneList,
+ reject: failList,
+ notify: progressList
+ },
+ promise = {
+ done: doneList.add,
+ fail: failList.add,
+ progress: progressList.add,
+
+ state: function() {
+ return state;
+ },
+
+ // Deprecated
+ isResolved: doneList.fired,
+ isRejected: failList.fired,
+
+ then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
+ deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
+ return this;
+ },
+ always: function() {
+ deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
+ return this;
+ },
+ pipe: function( fnDone, fnFail, fnProgress ) {
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( {
+ done: [ fnDone, "resolve" ],
+ fail: [ fnFail, "reject" ],
+ progress: [ fnProgress, "notify" ]
+ }, function( handler, data ) {
+ var fn = data[ 0 ],
+ action = data[ 1 ],
+ returned;
+ if ( jQuery.isFunction( fn ) ) {
+ deferred[ handler ](function() {
+ returned = fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
+ } else {
+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
+ }
+ });
+ } else {
+ deferred[ handler ]( newDefer[ action ] );
+ }
+ });
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ if ( obj == null ) {
+ obj = promise;
+ } else {
+ for ( var key in promise ) {
+ obj[ key ] = promise[ key ];
+ }
+ }
+ return obj;
+ }
+ },
+ deferred = promise.promise({}),
+ key;
+
+ for ( key in lists ) {
+ deferred[ key ] = lists[ key ].fire;
+ deferred[ key + "With" ] = lists[ key ].fireWith;
+ }
+
+ // Handle state
+ deferred.done( function() {
+ state = "resolved";
+ }, failList.disable, progressList.lock ).fail( function() {
+ state = "rejected";
+ }, doneList.disable, progressList.lock );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( firstParam ) {
+ var args = sliceDeferred.call( arguments, 0 ),
+ i = 0,
+ length = args.length,
+ pValues = new Array( length ),
+ count = length,
+ pCount = length,
+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+ firstParam :
+ jQuery.Deferred(),
+ promise = deferred.promise();
+ function resolveFunc( i ) {
+ return function( value ) {
+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+ if ( !( --count ) ) {
+ deferred.resolveWith( deferred, args );
+ }
+ };
+ }
+ function progressFunc( i ) {
+ return function( value ) {
+ pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+ deferred.notifyWith( promise, pValues );
+ };
+ }
+ if ( length > 1 ) {
+ for ( ; i < length; i++ ) {
+ if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
+ args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
+ } else {
+ --count;
+ }
+ }
+ if ( !count ) {
+ deferred.resolveWith( deferred, args );
+ }
+ } else if ( deferred !== firstParam ) {
+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+ }
+ return promise;
+ }
+});
+
+
+
+
+jQuery.support = (function() {
+
+ var support,
+ all,
+ a,
+ select,
+ opt,
+ input,
+ marginDiv,
+ fragment,
+ tds,
+ events,
+ eventName,
+ i,
+ isSupported,
+ div = document.createElement( "div" ),
+ documentElement = document.documentElement;
+
+ // Preliminary tests
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ all = div.getElementsByTagName( "*" );
+ a = div.getElementsByTagName( "a" )[ 0 ];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return {};
+ }
+
+ // First batch of supports tests
+ select = document.createElement( "select" );
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName( "input" )[ 0 ];
+
+ support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: ( a.getAttribute("href") === "/a" ),
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: ( input.value === "on" ),
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // Tests for enctype support on a form(#6743)
+ enctype: !!document.createElement("form").enctype,
+
+ // Makes sure cloning an html5 element does not cause problems
+ // Where outerHTML is undefined, this still works
+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
+
+ // Will be defined later
+ submitBubbles: true,
+ changeBubbles: true,
+ focusinBubbles: false,
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode( true ).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+ div.attachEvent( "onclick", function() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ support.noCloneEvent = false;
+ });
+ div.cloneNode( true ).fireEvent( "onclick" );
+ }
+
+ // Check if a radio maintains its value
+ // after being appended to the DOM
+ input = document.createElement("input");
+ input.value = "t";
+ input.setAttribute("type", "radio");
+ support.radioValue = input.value === "t";
+
+ input.setAttribute("checked", "checked");
+ div.appendChild( input );
+ fragment = document.createDocumentFragment();
+ fragment.appendChild( div.lastChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ fragment.removeChild( input );
+ fragment.appendChild( div );
+
+ div.innerHTML = "";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ if ( window.getComputedStyle ) {
+ marginDiv = document.createElement( "div" );
+ marginDiv.style.width = "0";
+ marginDiv.style.marginRight = "0";
+ div.style.width = "2px";
+ div.appendChild( marginDiv );
+ support.reliableMarginRight =
+ ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+ }
+
+ // Technique from Juriy Zaytsev
+ // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
+ // We only care about the case where non-standard event systems
+ // are used, namely in IE. Short-circuiting here helps us to
+ // avoid an eval call (in setAttribute) which can cause CSP
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ if ( div.attachEvent ) {
+ for( i in {
+ submit: 1,
+ change: 1,
+ focusin: 1
+ }) {
+ eventName = "on" + i;
+ isSupported = ( eventName in div );
+ if ( !isSupported ) {
+ div.setAttribute( eventName, "return;" );
+ isSupported = ( typeof div[ eventName ] === "function" );
+ }
+ support[ i + "Bubbles" ] = isSupported;
+ }
+ }
+
+ fragment.removeChild( div );
+
+ // Null elements to avoid leaks in IE
+ fragment = select = opt = marginDiv = div = input = null;
+
+ // Run tests that need a body at doc ready
+ jQuery(function() {
+ var container, outer, inner, table, td, offsetSupport,
+ conMarginTop, ptlm, vb, style, html,
+ body = document.getElementsByTagName("body")[0];
+
+ if ( !body ) {
+ // Return for frameset docs that don't have a body
+ return;
+ }
+
+ conMarginTop = 1;
+ ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";
+ vb = "visibility:hidden;border:0;";
+ style = "style='" + ptlm + "border:5px solid #000;padding:0;'";
+ html = "<div " + style + "><div></div></div>" +
+ "<table " + style + " cellpadding='0' cellspacing='0'>" +
+ "<tr><td></td></tr></table>";
+
+ container = document.createElement("div");
+ container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
+ body.insertBefore( container, body.firstChild );
+
+ // Construct the test element
+ div = document.createElement("div");
+ container.appendChild( div );
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName( "td" );
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE <= 8 fail this test)
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+ // Figure out if the W3C box model works as expected
+ div.innerHTML = "";
+ div.style.width = div.style.paddingLeft = "1px";
+ jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
+
+ if ( typeof div.style.zoom !== "undefined" ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+ }
+
+ div.style.cssText = ptlm + vb;
+ div.innerHTML = html;
+
+ outer = div.firstChild;
+ inner = outer.firstChild;
+ td = outer.nextSibling.firstChild.firstChild;
+
+ offsetSupport = {
+ doesNotAddBorder: ( inner.offsetTop !== 5 ),
+ doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
+ };
+
+ inner.style.position = "fixed";
+ inner.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
+ inner.style.position = inner.style.top = "";
+
+ outer.style.overflow = "hidden";
+ outer.style.position = "relative";
+
+ offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
+ offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
+
+ body.removeChild( container );
+ div = container = null;
+
+ jQuery.extend( support, offsetSupport );
+ });
+
+ return support;
+})();
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+ rmultiDash = /([A-Z])/g;
+
+jQuery.extend({
+ cache: {},
+
+ // Please use with caution
+ uuid: 0,
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ hasData: function( elem ) {
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+ return !!elem && !isEmptyDataObject( elem );
+ },
+
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var privateCache, thisCache, ret,
+ internalKey = jQuery.expando,
+ getByName = typeof name === "string",
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
+ isEvents = name === "events";
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
+ return;
+ }
+
+ if ( !id ) {
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ elem[ internalKey ] = id = ++jQuery.uuid;
+ } else {
+ id = internalKey;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
+
+ // Avoids exposing jQuery metadata on plain JS objects when the object
+ // is serialized using JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ] = jQuery.extend( cache[ id ], name );
+ } else {
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+ }
+ }
+
+ privateCache = thisCache = cache[ id ];
+
+ // jQuery data() is stored in a separate object inside the object's internal data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data.
+ if ( !pvt ) {
+ if ( !thisCache.data ) {
+ thisCache.data = {};
+ }
+
+ thisCache = thisCache.data;
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // Users should not attempt to inspect the internal events object using jQuery.data,
+ // it is undocumented and subject to change. But does anyone listen? No.
+ if ( isEvents && !thisCache[ name ] ) {
+ return privateCache.events;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( getByName ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+ },
+
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache, i, l,
+
+ // Reference to internal data cache key
+ internalKey = jQuery.expando,
+
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+
+ // See jQuery.data for more information
+ id = isNode ? elem[ internalKey ] : internalKey;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+ if ( thisCache ) {
+
+ // Support array or space separated string names for data keys
+ if ( !jQuery.isArray( name ) ) {
+
+ // try the string as a key before any manipulation
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+
+ // split the camel cased version by spaces unless a key with the spaces exists
+ name = jQuery.camelCase( name );
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+ name = name.split( " " );
+ }
+ }
+ }
+
+ for ( i = 0, l = name.length; i < l; i++ ) {
+ delete thisCache[ name[i] ];
+ }
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( !pvt ) {
+ delete cache[ id ].data;
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject(cache[ id ]) ) {
+ return;
+ }
+ }
+
+ // Browsers that fail expando deletion also refuse to delete expandos on
+ // the window, but it will allow it on all other JS objects; other browsers
+ // don't care
+ // Ensure that `cache` is not a window object #10080
+ if ( jQuery.support.deleteExpando || !cache.setInterval ) {
+ delete cache[ id ];
+ } else {
+ cache[ id ] = null;
+ }
+
+ // We destroyed the cache and need to eliminate the expando on the node to avoid
+ // false lookups in the cache for entries that no longer exist
+ if ( isNode ) {
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ internalKey ];
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( internalKey );
+ } else {
+ elem[ internalKey ] = null;
+ }
+ }
+ },
+
+ // For internal use only.
+ _data: function( elem, name, data ) {
+ return jQuery.data( elem, name, data, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ if ( elem.nodeName ) {
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ if ( match ) {
+ return !(match === true || elem.getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var parts, attr, name,
+ data = null;
+
+ if ( typeof key === "undefined" ) {
+ if ( this.length ) {
+ data = jQuery.data( this[0] );
+
+ if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {
+ attr = this[0].attributes;
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
+ name = attr[i].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.substring(5) );
+
+ dataAttr( this[0], name, data[ name ] );
+ }
+ }
+ jQuery._data( this[0], "parsedAttrs", true );
+ }
+ }
+
+ return data;
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ // Try to fetch any internally stored data first
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ data = dataAttr( this[0], key, data );
+ }
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+
+ } else {
+ return this.each(function() {
+ var self = jQuery( this ),
+ args = [ parts[0], value ];
+
+ self.triggerHandler( "setData" + parts[1] + "!", args );
+ jQuery.data( this, key, value );
+ self.triggerHandler( "changeData" + parts[1] + "!", args );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ jQuery.isNumeric( data ) ? parseFloat( data ) :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+ for ( var name in obj ) {
+
+ // if the public data object is empty, the private is still empty
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+ continue;
+ }
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+ var deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ defer = jQuery._data( elem, deferDataKey );
+ if ( defer &&
+ ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
+ ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
+ // Give room for hard-coded callbacks to fire first
+ // and eventually mark/queue something else on the element
+ setTimeout( function() {
+ if ( !jQuery._data( elem, queueDataKey ) &&
+ !jQuery._data( elem, markDataKey ) ) {
+ jQuery.removeData( elem, deferDataKey, true );
+ defer.fire();
+ }
+ }, 0 );
+ }
+}
+
+jQuery.extend({
+
+ _mark: function( elem, type ) {
+ if ( elem ) {
+ type = ( type || "fx" ) + "mark";
+ jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
+ }
+ },
+
+ _unmark: function( force, elem, type ) {
+ if ( force !== true ) {
+ type = elem;
+ elem = force;
+ force = false;
+ }
+ if ( elem ) {
+ type = type || "fx";
+ var key = type + "mark",
+ count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
+ if ( count ) {
+ jQuery._data( elem, key, count );
+ } else {
+ jQuery.removeData( elem, key, true );
+ handleQueueMarkDefer( elem, type, "mark" );
+ }
+ }
+ },
+
+ queue: function( elem, type, data ) {
+ var q;
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ q = jQuery._data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery._data( elem, type, jQuery.makeArray(data) );
+ } else {
+ q.push( data );
+ }
+ }
+ return q || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift(),
+ hooks = {};
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ jQuery._data( elem, type + ".run", hooks );
+ fn.call( elem, function() {
+ jQuery.dequeue( elem, type );
+ }, hooks );
+ }
+
+ if ( !queue.length ) {
+ jQuery.removeData( elem, type + "queue " + type + ".run", true );
+ handleQueueMarkDefer( elem, type, "queue" );
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function( next, hooks ) {
+ var timeout = setTimeout( next, time );
+ hooks.stop = function() {
+ clearTimeout( timeout );
+ };
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, object ) {
+ if ( typeof type !== "string" ) {
+ object = type;
+ type = undefined;
+ }
+ type = type || "fx";
+ var defer = jQuery.Deferred(),
+ elements = this,
+ i = elements.length,
+ count = 1,
+ deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ tmp;
+ function resolve() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ }
+ while( i-- ) {
+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+ jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
+ count++;
+ tmp.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise();
+ }
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rtype = /^(?:button|input)$/i,
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
+ rclickable = /^a(?:rea)?$/i,
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+ getSetAttribute = jQuery.support.getSetAttribute,
+ nodeHook, boolHook, fixSpecified;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.prop );
+ },
+
+ removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
+ });
+ },
+
+ addClass: function( value ) {
+ var classNames, i, l, elem,
+ setClass, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).addClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ classNames = value.split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className && classNames.length === 1 ) {
+ elem.className = value;
+
+ } else {
+ setClass = " " + elem.className + " ";
+
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
+ setClass += classNames[ c ] + " ";
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ var classNames, i, l, elem, className, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ classNames = ( value || "" ).split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ className = (" " + elem.className + " ").replace( rclass, " " );
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[ c ] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery._data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ",
+ i = 0,
+ l = this.length;
+ for ( ; i < l; i++ ) {
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ var hooks, ret, isFunction,
+ elem = this[0];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ return typeof ret === "string" ?
+ // handle most common string cases
+ ret.replace(rreturn, "") :
+ // handle cases where value is null/undef or number
+ ret == null ? "" : ret;
+ }
+
+ return;
+ }
+
+ isFunction = jQuery.isFunction( value );
+
+ return this.each(function( i ) {
+ var self = jQuery(this), val;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, self.val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ valHooks: {
+ option: {
+ get: function( elem ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value, i, max, option,
+ index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ i = one ? index : 0;
+ max = one ? index + 1 : options.length;
+ for ( ; i < max; i++ ) {
+ option = options[ i ];
+
+ // Don't return options that are disabled or in a disabled optgroup
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+ if ( one && !values.length && options.length ) {
+ return jQuery( options[ index ] ).val();
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
+
+ jQuery(elem).find("option").each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ var ret, hooks, notxml,
+ nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery( elem )[ name ]( value );
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( typeof elem.getAttribute === "undefined" ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // All attributes are lowercase
+ // Grab necessary hook if one is defined
+ if ( notxml ) {
+ name = name.toLowerCase();
+ hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
+ }
+
+ if ( value !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return;
+
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ elem.setAttribute( name, "" + value );
+ return value;
+ }
+
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+
+ ret = elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret === null ?
+ undefined :
+ ret;
+ }
+ },
+
+ removeAttr: function( elem, value ) {
+ var propName, attrNames, name, l,
+ i = 0;
+
+ if ( value && elem.nodeType === 1 ) {
+ attrNames = value.toLowerCase().split( rspace );
+ l = attrNames.length;
+
+ for ( ; i < l; i++ ) {
+ name = attrNames[ i ];
+
+ if ( name ) {
+ propName = jQuery.propFix[ name ] || name;
+
+ // See #9699 for explanation of this approach (setting first, then removal)
+ jQuery.attr( elem, name, "" );
+ elem.removeAttribute( getSetAttribute ? name : propName );
+
+ // Set corresponding property to false for boolean attributes
+ if ( rboolean.test( name ) && propName in elem ) {
+ elem[ propName ] = false;
+ }
+ }
+ }
+ }
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+ // Setting the type on a radio button after the value resets the value in IE6-9
+ // Reset value to it's default in case type is set after value
+ // This is for element creation
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ },
+ // Use the value property for back compat
+ // Use the nodeHook for button elements in IE6/7 (#1954)
+ value: {
+ get: function( elem, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.get( elem, name );
+ }
+ return name in elem ?
+ elem.value :
+ null;
+ },
+ set: function( elem, value, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.set( elem, value, name );
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+ }
+ },
+
+ propFix: {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ cellpadding: "cellPadding",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder",
+ contenteditable: "contentEditable"
+ },
+
+ prop: function( elem, name, value ) {
+ var ret, hooks, notxml,
+ nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return;
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ if ( notxml ) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return ( elem[ name ] = value );
+ }
+
+ } else {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+ return elem[ name ];
+ }
+ }
+ },
+
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem.getAttributeNode("tabindex");
+
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+ }
+ }
+});
+
+// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
+jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
+
+// Hook for boolean attributes
+boolHook = {
+ get: function( elem, name ) {
+ // Align boolean attributes with corresponding properties
+ // Fall back to attribute presence where some booleans are not supported
+ var attrNode,
+ property = jQuery.prop( elem, name );
+ return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ var propName;
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ // value is true since we know at this point it's type boolean and not false
+ // Set boolean attributes to the same name and set the DOM property
+ propName = jQuery.propFix[ name ] || name;
+ if ( propName in elem ) {
+ // Only set the IDL specifically if it already exists on the element
+ elem[ propName ] = true;
+ }
+
+ elem.setAttribute( name, name.toLowerCase() );
+ }
+ return name;
+ }
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+ fixSpecified = {
+ name: true,
+ id: true
+ };
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret;
+ ret = elem.getAttributeNode( name );
+ return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
+ ret.nodeValue :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode( name );
+ if ( !ret ) {
+ ret = document.createAttribute( name );
+ elem.setAttributeNode( ret );
+ }
+ return ( ret.nodeValue = value + "" );
+ }
+ };
+
+ // Apply the nodeHook to tabindex
+ jQuery.attrHooks.tabindex.set = nodeHook.set;
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+
+ // Set contenteditable to false on removals(#10429)
+ // Setting to empty string throws an error as an invalid value
+ jQuery.attrHooks.contenteditable = {
+ get: nodeHook.get,
+ set: function( elem, value, name ) {
+ if ( value === "" ) {
+ value = "false";
+ }
+ nodeHook.set( elem, value, name );
+ }
+ };
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret === null ? undefined : ret;
+ }
+ });
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
+ },
+ set: function( elem, value ) {
+ return ( elem.style.cssText = "" + value );
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+}
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+ jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ get: function( elem ) {
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+ };
+ });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+ set: function( elem, value ) {
+ if ( jQuery.isArray( value ) ) {
+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+ }
+ }
+ });
+});
+
+
+
+
+var rformElems = /^(?:textarea|input|select)$/i,
+ rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
+ rhoverHack = /\bhover(\.\S+)?\b/,
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+ rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
+ quickParse = function( selector ) {
+ var quick = rquickIs.exec( selector );
+ if ( quick ) {
+ // 0 1 2 3
+ // [ _, tag, id, class ]
+ quick[1] = ( quick[1] || "" ).toLowerCase();
+ quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
+ }
+ return quick;
+ },
+ quickIs = function( elem, m ) {
+ var attrs = elem.attributes || {};
+ return (
+ (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
+ (!m[2] || (attrs.id || {}).value === m[2]) &&
+ (!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
+ );
+ },
+ hoverHack = function( events ) {
+ return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
+ };
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var elemData, eventHandle, events,
+ t, tns, type, namespaces, handleObj,
+ handleObjIn, quick, handlers, special;
+
+ // Don't attach events to noData or text/comment nodes (allow plain objects tho)
+ if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ events = elemData.events;
+ if ( !events ) {
+ elemData.events = events = {};
+ }
+ eventHandle = elemData.handle;
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+ eventHandle.elem = elem;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = jQuery.trim( hoverHack(types) ).split( " " );
+ for ( t = 0; t < types.length; t++ ) {
+
+ tns = rtypenamespace.exec( types[t] ) || [];
+ type = tns[1];
+ namespaces = ( tns[2] || "" ).split( "." ).sort();
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend({
+ type: type,
+ origType: tns[1],
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ quick: quickParse( selector ),
+ namespace: namespaces.join(".")
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ handlers = events[ type ];
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener/attachEvent if the special events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+ t, tns, type, origType, namespaces, origCount,
+ j, events, special, handle, eventType, handleObj;
+
+ if ( !elemData || !(events = elemData.events) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
+ for ( t = 0; t < types.length; t++ ) {
+ tns = rtypenamespace.exec( types[t] ) || [];
+ type = origType = tns[1];
+ namespaces = tns[2];
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector? special.delegateType : special.bindType ) || type;
+ eventType = events[ type ] || [];
+ origCount = eventType.length;
+ namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
+
+ // Remove matching events
+ for ( j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ eventType.splice( j--, 1 );
+
+ if ( handleObj.selector ) {
+ eventType.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( eventType.length === 0 && origCount !== eventType.length ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ // removeData also checks for emptiness and clears the expando if empty
+ // so use it instead of delete
+ jQuery.removeData( elem, [ "events", "handle" ], true );
+ }
+ },
+
+ // Events that are safe to short-circuit if no handlers are attached.
+ // Native DOM events should not be added, they may have inline handlers.
+ customEvent: {
+ "getData": true,
+ "setData": true,
+ "changeData": true
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+ // Don't do events on text and comment nodes
+ if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
+ return;
+ }
+
+ // Event object or event type
+ var type = event.type || event,
+ namespaces = [],
+ cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
+
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+ return;
+ }
+
+ if ( type.indexOf( "!" ) >= 0 ) {
+ // Exclusive events trigger only for the exact event (no namespaces)
+ type = type.slice(0, -1);
+ exclusive = true;
+ }
+
+ if ( type.indexOf( "." ) >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+ // No jQuery handlers for this event type, and it can't have inline handlers
+ return;
+ }
+
+ // Caller can pass in an Event, Object, or just an event type string
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[ jQuery.expando ] ? event :
+ // Object literal
+ new jQuery.Event( type, event ) :
+ // Just the event type (string)
+ new jQuery.Event( type );
+
+ event.type = type;
+ event.isTrigger = true;
+ event.exclusive = exclusive;
+ event.namespace = namespaces.join( "." );
+ event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
+ ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
+
+ // Handle a global trigger
+ if ( !elem ) {
+
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
+ cache = jQuery.cache;
+ for ( i in cache ) {
+ if ( cache[ i ].events && cache[ i ].events[ type ] ) {
+ jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
+ }
+ }
+ return;
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ if ( !event.target ) {
+ event.target = elem;
+ }
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data != null ? jQuery.makeArray( data ) : [];
+ data.unshift( event );
+
+ // Allow special events to draw outside the lines
+ special = jQuery.event.special[ type ] || {};
+ if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
+ return;
+ }
+
+ // Determine event propagation path in advance, per W3C events spec (#9951)
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+ eventPath = [[ elem, special.bindType || type ]];
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+ bubbleType = special.delegateType || type;
+ cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
+ old = null;
+ for ( ; cur; cur = cur.parentNode ) {
+ eventPath.push([ cur, bubbleType ]);
+ old = cur;
+ }
+
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
+ if ( old && old === elem.ownerDocument ) {
+ eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
+ }
+ }
+
+ // Fire handlers on the event path
+ for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
+
+ cur = eventPath[i][0];
+ event.type = eventPath[i][1];
+
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+ // Note that this is a bare JS function and not a jQuery handler
+ handle = ontype && cur[ ontype ];
+ if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
+ event.preventDefault();
+ }
+ }
+ event.type = type;
+
+ // If nobody prevented the default action, do it now
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+ if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
+ // Don't do default actions on window, that's where global variables be (#6170)
+ // IE<9 dies on focus/blur to hidden element (#1486)
+ if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
+
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ old = elem[ ontype ];
+
+ if ( old ) {
+ elem[ ontype ] = null;
+ }
+
+ // Prevent re-triggering of the same event, since we already bubbled it above
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ jQuery.event.triggered = undefined;
+
+ if ( old ) {
+ elem[ ontype ] = old;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ dispatch: function( event ) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( event || window.event );
+
+ var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
+ delegateCount = handlers.delegateCount,
+ args = [].slice.call( arguments, 0 ),
+ run_all = !event.exclusive && !event.namespace,
+ handlerQueue = [],
+ i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[0] = event;
+ event.delegateTarget = this;
+
+ // Determine handlers that should run if there are delegated events
+ // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
+ if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) {
+
+ // Pregenerate a single jQuery object for reuse with .is()
+ jqcur = jQuery(this);
+ jqcur.context = this.ownerDocument || this;
+
+ for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
+ selMatch = {};
+ matches = [];
+ jqcur[0] = cur;
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+ sel = handleObj.selector;
+
+ if ( selMatch[ sel ] === undefined ) {
+ selMatch[ sel ] = (
+ handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
+ );
+ }
+ if ( selMatch[ sel ] ) {
+ matches.push( handleObj );
+ }
+ }
+ if ( matches.length ) {
+ handlerQueue.push({ elem: cur, matches: matches });
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ if ( handlers.length > delegateCount ) {
+ handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
+ }
+
+ // Run delegates first; they may want to stop propagation beneath us
+ for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
+ matched = handlerQueue[ i ];
+ event.currentTarget = matched.elem;
+
+ for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
+ handleObj = matched.matches[ j ];
+
+ // Triggered event must either 1) be non-exclusive and have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+ if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
+
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+ .apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ // Includes some event props shared by KeyEvent and MouseEvent
+ // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
+ props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+ fixHooks: {},
+
+ keyHooks: {
+ props: "char charCode key keyCode".split(" "),
+ filter: function( event, original ) {
+
+ // Add which for key events
+ if ( event.which == null ) {
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
+ }
+
+ return event;
+ }
+ },
+
+ mouseHooks: {
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+ filter: function( event, original ) {
+ var eventDoc, doc, body,
+ button = original.button,
+ fromElement = original.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && original.clientX != null ) {
+ eventDoc = event.target.ownerDocument || document;
+ doc = eventDoc.documentElement;
+ body = eventDoc.body;
+
+ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && fromElement ) {
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && button !== undefined ) {
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+ }
+
+ return event;
+ }
+ },
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // Create a writable copy of the event object and normalize some properties
+ var i, prop,
+ originalEvent = event,
+ fixHook = jQuery.event.fixHooks[ event.type ] || {},
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+ event = jQuery.Event( originalEvent );
+
+ for ( i = copy.length; i; ) {
+ prop = copy[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
+ if ( !event.target ) {
+ event.target = originalEvent.srcElement || document;
+ }
+
+ // Target should not be a text node (#504, Safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
+ if ( event.metaKey === undefined ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
+ },
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady
+ },
+
+ load: {
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+
+ focus: {
+ delegateType: "focusin"
+ },
+ blur: {
+ delegateType: "focusout"
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( jQuery.isWindow( this ) ) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ },
+
+ simulate: function( type, elem, event, bubble ) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the donor.
+ var e = jQuery.extend(
+ new jQuery.Event(),
+ event,
+ { type: type,
+ isSimulated: true,
+ originalEvent: {}
+ }
+ );
+ if ( bubble ) {
+ jQuery.event.trigger( e, null, elem );
+ } else {
+ jQuery.event.dispatch.call( elem, e );
+ }
+ if ( e.isDefaultPrevented() ) {
+ event.preventDefault();
+ }
+ }
+};
+
+// Some plugins are using, but it's undocumented/deprecated and will be removed.
+// The 1.7 special event interface should provide all the hooks needed now.
+jQuery.event.handle = jQuery.event.dispatch;
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, handle );
+ }
+ };
+
+jQuery.Event = function( src, props ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !(this instanceof jQuery.Event) ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ delegateType: fix,
+ bindType: fix,
+
+ handle: function( event ) {
+ var target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj,
+ selector = handleObj.selector,
+ ret;
+
+ // For mousenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply( this, arguments );
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+ // Node name check avoids a VML-related crash in IE (#9807)
+ var elem = e.target,
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+ if ( form && !form._submit_attached ) {
+ jQuery.event.add( form, "submit._submit", function( event ) {
+ // If form was submitted by the user, bubble the event up the tree
+ if ( this.parentNode && !event.isTrigger ) {
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
+ }
+ });
+ form._submit_attached = true;
+ }
+ });
+ // return undefined since we don't need an event listener
+ },
+
+ teardown: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+ jQuery.event.remove( this, "._submit" );
+ }
+ };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+ jQuery.event.special.change = {
+
+ setup: function() {
+
+ if ( rformElems.test( this.nodeName ) ) {
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
+ // after a propertychange. Eat the blur-change in special.change.handle.
+ // This still fires onchange a second time for check/radio after blur.
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ jQuery.event.add( this, "propertychange._change", function( event ) {
+ if ( event.originalEvent.propertyName === "checked" ) {
+ this._just_changed = true;
+ }
+ });
+ jQuery.event.add( this, "click._change", function( event ) {
+ if ( this._just_changed && !event.isTrigger ) {
+ this._just_changed = false;
+ jQuery.event.simulate( "change", this, event, true );
+ }
+ });
+ }
+ return false;
+ }
+ // Delegated event; lazy-add a change handler on descendant inputs
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
+ var elem = e.target;
+
+ if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
+ jQuery.event.add( elem, "change._change", function( event ) {
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+ jQuery.event.simulate( "change", this.parentNode, event, true );
+ }
+ });
+ elem._change_attached = true;
+ }
+ });
+ },
+
+ handle: function( event ) {
+ var elem = event.target;
+
+ // Swallow native change events from checkbox/radio, we already triggered them above
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+ return event.handleObj.handler.apply( this, arguments );
+ }
+ },
+
+ teardown: function() {
+ jQuery.event.remove( this, "._change" );
+
+ return rformElems.test( this.nodeName );
+ }
+ };
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0,
+ handler = function( event ) {
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+ };
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+ });
+}
+
+jQuery.fn.extend({
+
+ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+ // ( types-Object, data )
+ data = selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ this.on( type, selector, data, types[ type ], one );
+ }
+ return this;
+ }
+
+ if ( data == null && fn == null ) {
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return this;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return this.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ });
+ },
+ one: function( types, selector, data, fn ) {
+ return this.on.call( this, types, selector, data, fn, 1 );
+ },
+ off: function( types, selector, fn ) {
+ if ( types && types.preventDefault && types.handleObj ) {
+ // ( event ) dispatched jQuery.Event
+ var handleObj = types.handleObj;
+ jQuery( types.delegateTarget ).off(
+ handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
+ handleObj.selector,
+ handleObj.handler
+ );
+ return this;
+ }
+ if ( typeof types === "object" ) {
+ // ( types-object [, selector] )
+ for ( var type in types ) {
+ this.off( type, selector, types[ type ] );
+ }
+ return this;
+ }
+ if ( selector === false || typeof selector === "function" ) {
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ }
+ return this.each(function() {
+ jQuery.event.remove( this, types, fn, selector );
+ });
+ },
+
+ bind: function( types, data, fn ) {
+ return this.on( types, null, data, fn );
+ },
+ unbind: function( types, fn ) {
+ return this.off( types, null, fn );
+ },
+
+ live: function( types, data, fn ) {
+ jQuery( this.context ).on( types, this.selector, data, fn );
+ return this;
+ },
+ die: function( types, fn ) {
+ jQuery( this.context ).off( types, this.selector || "**", fn );
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.on( types, selector, data, fn );
+ },
+ undelegate: function( selector, types, fn ) {
+ // ( namespace ) or ( selector, types [, fn] )
+ return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ return jQuery.event.trigger( type, data, this[0], true );
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ guid = fn.guid || jQuery.guid++,
+ i = 0,
+ toggler = function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ };
+
+ // link all the functions, so any of them can unbind this click handler
+ toggler.guid = guid;
+ while ( i < args.length ) {
+ args[ i++ ].guid = guid;
+ }
+
+ return this.click( toggler );
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ if ( fn == null ) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ?
+ this.on( name, null, data, fn ) :
+ this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+
+ if ( rkeyEvent.test( name ) ) {
+ jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
+ }
+
+ if ( rmouseEvent.test( name ) ) {
+ jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
+ }
+});
+
+
+
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ expando = "sizcache" + (Math.random() + '').replace('.', ''),
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true,
+ rBackslash = /\\/g,
+ rReturn = /\r\n/g,
+ rNonWord = /\W/;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i,
+ prune = true,
+ contextXML = Sizzle.isXML( context ),
+ parts = [],
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec( "" );
+ m = chunker.exec( soFar );
+
+ if ( m ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while ( m );
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context, seed );
+
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set, seed );
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+ ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set )[0] :
+ ret.set[0];
+ }
+
+ if ( context ) {
+ ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+ set = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set ) :
+ ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray( set );
+
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ cur = parts.pop();
+ pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+
+ } else if ( context && context.nodeType === 1 ) {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+
+ } else {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+ return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+ return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+ var set, i, len, match, type, left;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( i = 0, len = Expr.order.length; i < len; i++ ) {
+ type = Expr.order[i];
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ left = match[1];
+ match.splice( 1, 1 );
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace( rBackslash, "" );
+ set = Expr.find[ type ]( match, context, isXML );
+
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( "*" ) :
+ [];
+ }
+
+ return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+ var match, anyFound,
+ type, found, item, filter, left,
+ i, pass,
+ old = expr,
+ result = [],
+ curLoop = set,
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+ while ( expr && set.length ) {
+ for ( type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ filter = Expr.filter[ type ];
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ pass = not ^ found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Utility function for retreiving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+var getText = Sizzle.getText = function( elem ) {
+ var i, node,
+ nodeType = elem.nodeType,
+ ret = "";
+
+ if ( nodeType ) {
+ if ( nodeType === 1 || nodeType === 9 ) {
+ // Use textContent || innerText for elements
+ if ( typeof elem.textContent === 'string' ) {
+ return elem.textContent;
+ } else if ( typeof elem.innerText === 'string' ) {
+ // Replace IE's carriage returns
+ return elem.innerText.replace( rReturn, '' );
+ } else {
+ // Traverse it's children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for ( i = 0; (node = elem[i]); i++ ) {
+ // Do not traverse comment nodes
+ if ( node.nodeType !== 8 ) {
+ ret += getText( node );
+ }
+ }
+ }
+ return ret;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch: {},
+
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+
+ attrHandle: {
+ href: function( elem ) {
+ return elem.getAttribute( "href" );
+ },
+ type: function( elem ) {
+ return elem.getAttribute( "type" );
+ }
+ },
+
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !rNonWord.test( part ),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+
+ ">": function( checkSet, part ) {
+ var elem,
+ isPartStr = typeof part === "string",
+ i = 0,
+ l = checkSet.length;
+
+ if ( isPartStr && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+
+ } else {
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+
+ "": function(checkSet, part, isXML){
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+ },
+
+ "~": function( checkSet, part, isXML ) {
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+ }
+ },
+
+ find: {
+ ID: function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ },
+
+ NAME: function( match, context ) {
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [],
+ results = context.getElementsByName( match[1] );
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG: function( match, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( match[1] );
+ }
+ }
+ },
+ preFilter: {
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+ match = " " + match[1].replace( rBackslash, "" ) + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID: function( match ) {
+ return match[1].replace( rBackslash, "" );
+ },
+
+ TAG: function( match, curLoop ) {
+ return match[1].replace( rBackslash, "" ).toLowerCase();
+ },
+
+ CHILD: function( match ) {
+ if ( match[1] === "nth" ) {
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ match[2] = match[2].replace(/^\+|\s*/g, '');
+
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+ else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+ var name = match[1] = match[1].replace( rBackslash, "" );
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ // Handle if an un-quoted value was used
+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+
+ return false;
+ }
+
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS: function( match ) {
+ match.unshift( true );
+
+ return match;
+ }
+ },
+
+ filters: {
+ enabled: function( elem ) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled: function( elem ) {
+ return elem.disabled === true;
+ },
+
+ checked: function( elem ) {
+ return elem.checked === true;
+ },
+
+ selected: function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ parent: function( elem ) {
+ return !!elem.firstChild;
+ },
+
+ empty: function( elem ) {
+ return !elem.firstChild;
+ },
+
+ has: function( elem, i, match ) {
+ return !!Sizzle( match[3], elem ).length;
+ },
+
+ header: function( elem ) {
+ return (/h\d/i).test( elem.nodeName );
+ },
+
+ text: function( elem ) {
+ var attr = elem.getAttribute( "type" ), type = elem.type;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
+ },
+
+ radio: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
+ },
+
+ checkbox: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
+ },
+
+ file: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
+ },
+
+ password: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
+ },
+
+ submit: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "submit" === elem.type;
+ },
+
+ image: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
+ },
+
+ reset: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "reset" === elem.type;
+ },
+
+ button: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && "button" === elem.type || name === "button";
+ },
+
+ input: function( elem ) {
+ return (/input|select|textarea|button/i).test( elem.nodeName );
+ },
+
+ focus: function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+ setFilters: {
+ first: function( elem, i ) {
+ return i === 0;
+ },
+
+ last: function( elem, i, match, array ) {
+ return i === array.length - 1;
+ },
+
+ even: function( elem, i ) {
+ return i % 2 === 0;
+ },
+
+ odd: function( elem, i ) {
+ return i % 2 === 1;
+ },
+
+ lt: function( elem, i, match ) {
+ return i < match[3] - 0;
+ },
+
+ gt: function( elem, i, match ) {
+ return i > match[3] - 0;
+ },
+
+ nth: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ },
+
+ eq: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function( elem, match, i, array ) {
+ var name = match[1],
+ filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var j = 0, l = not.length; j < l; j++ ) {
+ if ( not[j] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error( name );
+ }
+ },
+
+ CHILD: function( elem, match ) {
+ var first, last,
+ doneName, parent, cache,
+ count, diff,
+ type = match[1],
+ node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ first = match[2];
+ last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ doneName = match[0];
+ parent = elem.parentNode;
+
+ if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
+ count = 0;
+
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent[ expando ] = doneName;
+ }
+
+ diff = elem.nodeIndex - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+
+ ID: function( elem, match ) {
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+
+ TAG: function( elem, match ) {
+ return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS: function( elem, match ) {
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+
+ ATTR: function( elem, match ) {
+ var name = match[1],
+ result = Sizzle.attr ?
+ Sizzle.attr( elem, name ) :
+ Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ !type && Sizzle.attr ?
+ result != null :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+
+ POS: function( elem, match, i, array ) {
+ var name = match[2],
+ filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS,
+ fescape = function(all, num){
+ return "\\" + (num - 0 + 1);
+ };
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+ makeArray = function( array, results ) {
+ var i = 0,
+ ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+
+ } else {
+ for ( ; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date()).getTime(),
+ root = document.documentElement;
+
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+
+ return m ?
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+
+ Expr.filter.ID = function( elem, match ) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+
+ // release memory in IE
+ root = form = null;
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function( match, context ) {
+ var results = context.getElementsByTagName( match[1] );
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+
+ Expr.attrHandle.href = function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ };
+ }
+
+ // release memory in IE
+ div = null;
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle,
+ div = document.createElement("div"),
+ id = "__sizzle__";
+
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function( query, context, extra, seed ) {
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && !Sizzle.isXML(context) ) {
+ // See if we find a selector to speed up
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+ // Speed-up: Sizzle("TAG")
+ if ( match[1] ) {
+ return makeArray( context.getElementsByTagName( query ), extra );
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
+ }
+ }
+
+ if ( context.nodeType === 9 ) {
+ // Speed-up: Sizzle("body")
+ // The body element only exists once, optimize finding it
+ if ( query === "body" && context.body ) {
+ return makeArray( [ context.body ], extra );
+
+ // Speed-up: Sizzle("#ID")
+ } else if ( match && match[3] ) {
+ var elem = context.getElementById( match[3] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id === match[3] ) {
+ return makeArray( [ elem ], extra );
+ }
+
+ } else {
+ return makeArray( [], extra );
+ }
+ }
+
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(qsaError) {}
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var oldContext = context,
+ old = context.getAttribute( "id" ),
+ nid = old || id,
+ hasParent = context.parentNode,
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+ if ( !old ) {
+ context.setAttribute( "id", nid );
+ } else {
+ nid = nid.replace( /'/g, "\\$&" );
+ }
+ if ( relativeHierarchySelector && hasParent ) {
+ context = context.parentNode;
+ }
+
+ try {
+ if ( !relativeHierarchySelector || hasParent ) {
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+ }
+
+ } catch(pseudoError) {
+ } finally {
+ if ( !old ) {
+ oldContext.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+}
+
+(function(){
+ var html = document.documentElement,
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
+
+ if ( matches ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9 fails this)
+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+ pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( document.documentElement, "[test!='']:sizzle" );
+
+ } catch( pseudoError ) {
+ pseudoWorks = true;
+ }
+
+ Sizzle.matchesSelector = function( node, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if ( !Sizzle.isXML( node ) ) {
+ try {
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+ var ret = matches.call( node, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || !disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9, so check for that
+ node.document && node.document.nodeType !== 11 ) {
+ return ret;
+ }
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle(expr, null, null, [node]).length > 0;
+ };
+ }
+})();
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function( match, context, isXML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem[ expando ] === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem[ expando ] = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem[ expando ] === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem[ expando ] = doneName;
+ elem.sizset = i;
+ }
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+if ( document.documentElement.contains ) {
+ Sizzle.contains = function( a, b ) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+ Sizzle.contains = function( a, b ) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+} else {
+ Sizzle.contains = function() {
+ return false;
+ };
+}
+
+Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context, seed ) {
+ var match,
+ tmpSet = [],
+ later = "",
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet, seed );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+// Override sizzle attribute retrieval
+Sizzle.attr = jQuery.attr;
+Sizzle.selectors.attrMap = {};
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ slice = Array.prototype.slice,
+ POS = jQuery.expr.match.POS,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var self = this,
+ i, l;
+
+ if ( typeof selector !== "string" ) {
+ return jQuery( selector ).filter(function() {
+ for ( i = 0, l = self.length; i < l; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ });
+ }
+
+ var ret = this.pushStack( "", "find", selector ),
+ length, n, r;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( n = length; n < ret.length; n++ ) {
+ for ( r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && (
+ typeof selector === "string" ?
+ // If this is a positional selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ POS.test( selector ) ?
+ jQuery( selector, this.context ).index( this[0] ) >= 0 :
+ jQuery.filter( selector, this ).length > 0 :
+ this.filter( selector ).length > 0 );
+ },
+
+ closest: function( selectors, context ) {
+ var ret = [], i, l, cur = this[0];
+
+ // Array (deprecated as of jQuery 1.7)
+ if ( jQuery.isArray( selectors ) ) {
+ var level = 1;
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( i = 0; i < selectors.length; i++ ) {
+
+ if ( jQuery( cur ).is( selectors[ i ] ) ) {
+ ret.push({ selector: selectors[ i ], elem: cur, level: level });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+
+ return ret;
+ }
+
+ // String
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+ return this.pushStack( ret, "closest", selectors );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
+ }
+
+ // index in selector
+ if ( typeof elem === "string" ) {
+ return jQuery.inArray( this[0], jQuery( elem ) );
+ }
+
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context ) :
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call( arguments ).join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return ( elem === qualifier ) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
+ });
+}
+
+
+
+
+function createSafeFragment( document ) {
+ var list = nodeNames.split( "|" ),
+ safeFrag = document.createDocumentFragment();
+
+ if ( safeFrag.createElement ) {
+ while ( list.length ) {
+ safeFrag.createElement(
+ list.pop()
+ );
+ }
+ }
+ return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" +
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+ rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnoInnerhtml = /<(?:script|style)/i,
+ rnocache = /<(?:script|object|embed|option|style)/i,
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")", "i"),
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptType = /\/(java|ecma)script/i,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ },
+ safeFragment = createSafeFragment( document );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery( this );
+
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ var isFunction = jQuery.isFunction( html );
+
+ return this.each(function(i) {
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery.clean( arguments );
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery.clean(arguments) );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function () {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ });
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, "<$1></$2>");
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery( this );
+
+ self.html( value.call(this, i, self.html()) );
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery( value ).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ jQuery( this ).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.length ?
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+ this;
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, fragment, parent,
+ value = args[0],
+ scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = jQuery.buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ // Make sure that we do not leak memory by inadvertently discarding
+ // the original fragment (which might have attached data) instead of
+ // using it; in addition, use the original fragment object for the last
+ // item instead of first because it can end up being emptied incorrectly
+ // in certain situations (Bug #8070).
+ // Fragments from the fragment cache must always be cloned and never used
+ // in place.
+ results.cacheable || ( l > 1 && i < lastIndex ) ?
+ jQuery.clone( fragment, true, true ) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+ }
+});
+
+function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var type, i, l,
+ oldData = jQuery._data( src ),
+ curData = jQuery._data( dest, oldData ),
+ events = oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( type in events ) {
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
+ }
+ }
+ }
+
+ // make the cloned public data object a copy from the original
+ if ( curData.data ) {
+ curData.data = jQuery.extend( {}, curData.data );
+ }
+}
+
+function cloneFixAttributes( src, dest ) {
+ var nodeName;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ // clearAttributes removes the attributes, which we don't want,
+ // but also removes the attachEvent events, which we *do* want
+ if ( dest.clearAttributes ) {
+ dest.clearAttributes();
+ }
+
+ // mergeAttributes, in contrast, only merges back on the
+ // original attributes, not the events
+ if ( dest.mergeAttributes ) {
+ dest.mergeAttributes( src );
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 fail to clone children inside object elements that use
+ // the proprietary classid attribute value (rather than the type
+ // attribute) to identify the type of content to display
+ if ( nodeName === "object" ) {
+ dest.outerHTML = src.outerHTML;
+
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+ // IE6-8 fails to persist the checked state of a cloned checkbox
+ // or radio button. Worse, IE6-7 fail to give the cloned element
+ // a checked appearance if the defaultChecked value isn't also set
+ if ( src.checked ) {
+ dest.defaultChecked = dest.checked = src.checked;
+ }
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.selected = src.defaultSelected;
+
+ // IE6-8 fails to set the defaultValue to the correct value when
+ // cloning other types of input fields
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+
+ // Event data gets referenced instead of copied if the expando
+ // gets copied too
+ dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults, doc,
+ first = args[ 0 ];
+
+ // nodes may contain either an explicit document object,
+ // a jQuery collection or context object.
+ // If nodes[0] contains a valid object to assign to doc
+ if ( nodes && nodes[0] ) {
+ doc = nodes[0].ownerDocument || nodes[0];
+ }
+
+ // Ensure that an attr object doesn't incorrectly stand in as a document object
+ // Chrome and Firefox seem to allow this to occur and will throw exception
+ // Fixes #8950
+ if ( !doc.createDocumentFragment ) {
+ doc = document;
+ }
+
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
+ if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
+ first.charAt(0) === "<" && !rnocache.test( first ) &&
+ (jQuery.support.checkClone || !rchecked.test( first )) &&
+ (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
+
+ cacheable = true;
+
+ cacheresults = jQuery.fragments[ first ];
+ if ( cacheresults && cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ first ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [],
+ insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = ( i > 0 ? this.clone(true) : this ).get();
+ jQuery( insert[i] )[ original ]( elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+function getAll( elem ) {
+ if ( typeof elem.getElementsByTagName !== "undefined" ) {
+ return elem.getElementsByTagName( "*" );
+
+ } else if ( typeof elem.querySelectorAll !== "undefined" ) {
+ return elem.querySelectorAll( "*" );
+
+ } else {
+ return [];
+ }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( elem.type === "checkbox" || elem.type === "radio" ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+ var nodeName = ( elem.nodeName || "" ).toLowerCase();
+ if ( nodeName === "input" ) {
+ fixDefaultChecked( elem );
+ // Skip scripts, get other children
+ } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+ }
+}
+
+// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
+function shimCloneNode( elem ) {
+ var div = document.createElement( "div" );
+ safeFragment.appendChild( div );
+
+ div.innerHTML = elem.outerHTML;
+ return div.firstChild;
+}
+
+jQuery.extend({
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var srcElements,
+ destElements,
+ i,
+ // IE<=8 does not properly clone detached, unknown element nodes
+ clone = jQuery.support.html5Clone || !rnoshimcache.test( "<" + elem.nodeName ) ?
+ elem.cloneNode( true ) :
+ shimCloneNode( elem );
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+ // IE copies events bound via attachEvent when using cloneNode.
+ // Calling detachEvent on the clone will also remove the events
+ // from the original. In order to get around this, we use some
+ // proprietary methods to clear the events. Thanks to MooTools
+ // guys for this hotness.
+
+ cloneFixAttributes( elem, clone );
+
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ // Weird iteration because IE will replace the length property
+ // with an element if you are cloning the body and one of the
+ // elements on the page has a name or id of "length"
+ for ( i = 0; srcElements[i]; ++i ) {
+ // Ensure that the destination node is not null; Fixes #9587
+ if ( destElements[i] ) {
+ cloneFixAttributes( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ cloneCopyEvent( elem, clone );
+
+ if ( deepDataAndEvents ) {
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ for ( i = 0; srcElements[i]; ++i ) {
+ cloneCopyEvent( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ srcElements = destElements = null;
+
+ // Return the cloned set
+ return clone;
+ },
+
+ clean: function( elems, context, fragment, scripts ) {
+ var checkScriptType;
+
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [], j;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ if ( !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+ } else {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Append wrapper element to unknown element safe doc fragment
+ if ( context === document ) {
+ // Use the fragment we've already created for this document
+ safeFragment.appendChild( div );
+ } else {
+ // Use a fragment created with the owner document
+ createSafeFragment( context ).appendChild( div );
+ }
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+ }
+
+ // Resets defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ var len;
+ if ( !jQuery.support.appendChecked ) {
+ if ( elem[0] && typeof (len = elem.length) === "number" ) {
+ for ( j = 0; j < len; j++ ) {
+ findInputs( elem[j] );
+ }
+ } else {
+ findInputs( elem );
+ }
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ checkScriptType = function( elem ) {
+ return !elem.type || rscriptType.test( elem.type );
+ };
+ for ( i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id,
+ cache = jQuery.cache,
+ special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ continue;
+ }
+
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ];
+
+ if ( data && data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+ if ( data.handle ) {
+ data.handle.elem = null;
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity=([^)]*)/,
+ // fixed for IE9, see #8346
+ rupper = /([A-Z]|^ms)/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+ rrelNum = /^([\-+])=([\-+.\de]+)/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+ curCSS,
+
+ getComputedStyle,
+ currentStyle;
+
+jQuery.fn.css = function( name, value ) {
+ // Setting 'undefined' is a no-op
+ if ( arguments.length === 2 && value === undefined ) {
+ return this;
+ }
+
+ return jQuery.access( this, name, value, true, function( elem, name, value ) {
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ });
+};
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity", "opacity" );
+ return ret === "" ? "1" : ret;
+
+ } else {
+ return elem.style.opacity;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "fillOpacity": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, origName = jQuery.camelCase( name ),
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+ value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( value == null || type === "number" && isNaN( value ) ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra ) {
+ var ret, hooks;
+
+ // Make sure that we're working with the right name
+ name = jQuery.camelCase( name );
+ hooks = jQuery.cssHooks[ name ];
+ name = jQuery.cssProps[ name ] || name;
+
+ // cssFloat needs a special treatment
+ if ( name === "cssFloat" ) {
+ name = "float";
+ }
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+ return ret;
+
+ // Otherwise, if a way to get the computed value exists, use that
+ } else if ( curCSS ) {
+ return curCSS( elem, name );
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ var val;
+
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ return getWH( elem, name, extra );
+ } else {
+ jQuery.swap( elem, cssShow, function() {
+ val = getWH( elem, name, extra );
+ });
+ }
+
+ return val;
+ }
+ },
+
+ set: function( elem, value ) {
+ if ( rnumpx.test( value ) ) {
+ // ignore negative width and height values #1599
+ value = parseFloat( value );
+
+ if ( value >= 0 ) {
+ return value + "px";
+ }
+
+ } else {
+ return value;
+ }
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there there is no filter style applied in a css rule, we are done
+ if ( currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ var ret;
+ jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ ret = curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ ret = elem.style.marginRight;
+ }
+ });
+ return ret;
+ }
+ };
+ }
+});
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ getComputedStyle = function( elem, name ) {
+ var ret, defaultView, computedStyle;
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ if ( (defaultView = elem.ownerDocument.defaultView) &&
+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+ ret = computedStyle.getPropertyValue( name );
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+ }
+
+ return ret;
+ };
+}
+
+if ( document.documentElement.currentStyle ) {
+ currentStyle = function( elem, name ) {
+ var left, rsLeft, uncomputed,
+ ret = elem.currentStyle && elem.currentStyle[ name ],
+ style = elem.style;
+
+ // Avoid setting ret to empty string here
+ // so we don't default to auto
+ if ( ret === null && style && (uncomputed = style[ name ]) ) {
+ ret = uncomputed;
+ }
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+
+ // Remember the original values
+ left = style.left;
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : ( ret || 0 );
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+
+ // Start with offset property
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+ which = name === "width" ? cssWidth : cssHeight,
+ i = 0,
+ len = which.length;
+
+ if ( val > 0 ) {
+ if ( extra !== "border" ) {
+ for ( ; i < len; i++ ) {
+ if ( !extra ) {
+ val -= parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0;
+ } else {
+ val -= parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0;
+ }
+ }
+ }
+
+ return val + "px";
+ }
+
+ // Fall back to computed then uncomputed css if necessary
+ val = curCSS( elem, name, name );
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ] || 0;
+ }
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+
+ // Add padding, border, margin
+ if ( extra ) {
+ for ( ; i < len; i++ ) {
+ val += parseFloat( jQuery.css( elem, "padding" + which[ i ] ) ) || 0;
+ if ( extra !== "padding" ) {
+ val += parseFloat( jQuery.css( elem, "border" + which[ i ] + "Width" ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + which[ i ] ) ) || 0;
+ }
+ }
+ }
+
+ return val + "px";
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth,
+ height = elem.offsetHeight;
+
+ return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+
+
+
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rhash = /#.*$/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rquery = /\?/,
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rspacesAjax = /\s+/,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Document location
+ ajaxLocation,
+
+ // Document location segments
+ ajaxLocParts,
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = ["*/"] + ["*"];
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ if ( jQuery.isFunction( func ) ) {
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+ i = 0,
+ length = dataTypes.length,
+ dataType,
+ list,
+ placeBefore;
+
+ // For each dataType in the dataTypeExpression
+ for ( ; i < length; i++ ) {
+ dataType = dataTypes[ i ];
+ // We control if we're asked to add before
+ // any existing element
+ placeBefore = /^\+/.test( dataType );
+ if ( placeBefore ) {
+ dataType = dataType.substr( 1 ) || "*";
+ }
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ // then we add to the structure accordingly
+ list[ placeBefore ? "unshift" : "push" ]( func );
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+ dataType /* internal */, inspected /* internal */ ) {
+
+ dataType = dataType || options.dataTypes[ 0 ];
+ inspected = inspected || {};
+
+ inspected[ dataType ] = true;
+
+ var list = structure[ dataType ],
+ i = 0,
+ length = list ? list.length : 0,
+ executeOnly = ( structure === prefilters ),
+ selection;
+
+ for ( ; i < length && ( executeOnly || !selection ); i++ ) {
+ selection = list[ i ]( options, originalOptions, jqXHR );
+ // If we got redirected to another dataType
+ // we try there if executing only and not done already
+ if ( typeof selection === "string" ) {
+ if ( !executeOnly || inspected[ selection ] ) {
+ selection = undefined;
+ } else {
+ options.dataTypes.unshift( selection );
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, selection, inspected );
+ }
+ }
+ }
+ // If we're only executing or nothing was selected
+ // we try the catchall dataType if not done already
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, "*", inspected );
+ }
+ // unnecessary when only executing (prefilters)
+ // but it'll be ignored by the caller in that case
+ return selection;
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var key, deep,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+ for ( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+}
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf( " " );
+ if ( off >= 0 ) {
+ var selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ // Complete callback (responseText is used internally)
+ complete: function( jqXHR, status, responseText ) {
+ // Store the response as specified by the jqXHR object
+ responseText = jqXHR.responseText;
+ // If successful, inject the HTML into all the matched elements
+ if ( jqXHR.isResolved() ) {
+ // #4825: Get the actual response in case
+ // a dataFilter is present in ajaxSettings
+ jqXHR.done(function( r ) {
+ responseText = r;
+ });
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [ responseText, status, jqXHR ] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+ jQuery.fn[ o ] = function( f ){
+ return this.on( o, f );
+ };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ type: method,
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ };
+});
+
+jQuery.extend({
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ if ( settings ) {
+ // Building a settings object
+ ajaxExtend( target, jQuery.ajaxSettings );
+ } else {
+ // Extending ajaxSettings
+ settings = target;
+ target = jQuery.ajaxSettings;
+ }
+ ajaxExtend( target, settings );
+ return target;
+ },
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ text: "text/plain",
+ json: "application/json, text/javascript",
+ "*": allTypes
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText"
+ },
+
+ // List of data converters
+ // 1) key format is "source_type destination_type" (a single space in-between)
+ // 2) the catchall symbol "*" can be used for source_type
+ converters: {
+
+ // Convert anything to text
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ context: true,
+ url: true
+ }
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events
+ // It's the callbackContext if one was provided in the options
+ // and if it's a DOM node or a jQuery collection
+ globalEventContext = callbackContext !== s &&
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+ jQuery( callbackContext ) : jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery.Callbacks( "once memory" ),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // ifModified key
+ ifModifiedKey,
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+ // transport
+ transport,
+ // timeout handle
+ timeoutTimer,
+ // Cross-domain detection vars
+ parts,
+ // The jqXHR state
+ state = 0,
+ // To know if global events are to be dispatched
+ fireGlobals,
+ // Loop variable
+ i,
+ // Fake xhr
+ jqXHR = {
+
+ readyState: 0,
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ if ( !state ) {
+ var lname = name.toLowerCase();
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match === undefined ? null : match;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ statusText = statusText || "abort";
+ if ( transport ) {
+ transport.abort( statusText );
+ }
+ done( 0, statusText );
+ return this;
+ }
+ };
+
+ // Callback for when everything is done
+ // It is defined here because jslint complains if it is declared
+ // at the end of the function (which would be more logical and readable)
+ function done( status, nativeStatusText, responses, headers ) {
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ var isSuccess,
+ success,
+ error,
+ statusText = nativeStatusText,
+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+ lastModified,
+ etag;
+
+ // If successful, handle type chaining
+ if ( status >= 200 && status < 300 || status === 304 ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+
+ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+ jQuery.lastModified[ ifModifiedKey ] = lastModified;
+ }
+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+ jQuery.etag[ ifModifiedKey ] = etag;
+ }
+ }
+
+ // If not modified
+ if ( status === 304 ) {
+
+ statusText = "notmodified";
+ isSuccess = true;
+
+ // If we have data
+ } else {
+
+ try {
+ success = ajaxConvert( s, response );
+ statusText = "success";
+ isSuccess = true;
+ } catch(e) {
+ // We have a parsererror
+ statusText = "parsererror";
+ error = e;
+ }
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if ( !statusText || status ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = "" + ( nativeStatusText || statusText );
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ // Attach deferreds
+ deferred.promise( jqXHR );
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+ jqXHR.complete = completeDeferred.add;
+
+ // Status-dependent callbacks
+ jqXHR.statusCode = function( map ) {
+ if ( map ) {
+ var tmp;
+ if ( state < 2 ) {
+ for ( tmp in map ) {
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+ }
+ } else {
+ tmp = map[ jqXHR.status ];
+ jqXHR.then( tmp, tmp );
+ }
+ }
+ return this;
+ };
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+ // Determine if a cross-domain request is in order
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefiler, stop there
+ if ( state === 2 ) {
+ return false;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Get ifModifiedKey before adding the anti-cache parameter
+ ifModifiedKey = s.url;
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+
+ var ts = jQuery.now(),
+ // try replacing _= if it is there
+ ret = s.url.replace( rts, "$1_=" + ts );
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ ifModifiedKey = ifModifiedKey || s.url;
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+ }
+ if ( jQuery.etag[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+ }
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already
+ jqXHR.abort();
+ return false;
+
+ }
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout( function(){
+ jqXHR.abort( "timeout" );
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch (e) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : value;
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+ }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ for ( var name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+ var contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields,
+ ct,
+ type,
+ finalDataType,
+ firstDataType;
+
+ // Fill responseXXX fields
+ for ( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ var dataTypes = s.dataTypes,
+ converters = {},
+ i,
+ key,
+ length = dataTypes.length,
+ tmp,
+ // Current and previous dataTypes
+ current = dataTypes[ 0 ],
+ prev,
+ // Conversion expression
+ conversion,
+ // Conversion function
+ conv,
+ // Conversion functions (transitive conversion)
+ conv1,
+ conv2;
+
+ // For each dataType in the chain
+ for ( i = 1; i < length; i++ ) {
+
+ // Create converters map
+ // with lowercased keys
+ if ( i === 1 ) {
+ for ( key in s.converters ) {
+ if ( typeof key === "string" ) {
+ converters[ key.toLowerCase() ] = s.converters[ key ];
+ }
+ }
+ }
+
+ // Get the dataTypes
+ prev = current;
+ current = dataTypes[ i ];
+
+ // If current is auto dataType, update it to prev
+ if ( current === "*" ) {
+ current = prev;
+ // If no auto and dataTypes are actually different
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Get the converter
+ conversion = prev + " " + current;
+ conv = converters[ conversion ] || converters[ "* " + current ];
+
+ // If there is no direct converter, search transitively
+ if ( !conv ) {
+ conv2 = undefined;
+ for ( conv1 in converters ) {
+ tmp = conv1.split( " " );
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+ conv2 = converters[ tmp[1] + " " + current ];
+ if ( conv2 ) {
+ conv1 = converters[ conv1 ];
+ if ( conv1 === true ) {
+ conv = conv2;
+ } else if ( conv2 === true ) {
+ conv = conv1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ // If we found no converter, dispatch an error
+ if ( !( conv || conv2 ) ) {
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+ }
+ // If found converter is not an equivalence
+ if ( conv !== true ) {
+ // Convert with 1 or 2 converters accordingly
+ response = conv ? conv( response ) : conv2( conv1(response) );
+ }
+ }
+ }
+ return response;
+}
+
+
+
+
+var jsc = jQuery.now(),
+ jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ return jQuery.expando + "_" + ( jsc++ );
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+ ( typeof s.data === "string" );
+
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
+ s.jsonp !== false && ( jsre.test( s.url ) ||
+ inspectData && jsre.test( s.data ) ) ) {
+
+ var responseContainer,
+ jsonpCallback = s.jsonpCallback =
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+ previous = window[ jsonpCallback ],
+ url = s.url,
+ data = s.data,
+ replace = "$1" + jsonpCallback + "$2";
+
+ if ( s.jsonp !== false ) {
+ url = url.replace( jsre, replace );
+ if ( s.url === url ) {
+ if ( inspectData ) {
+ data = data.replace( jsre, replace );
+ }
+ if ( s.data === data ) {
+ // Add callback manually
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+ }
+ }
+ }
+
+ s.url = url;
+ s.data = data;
+
+ // Install callback
+ window[ jsonpCallback ] = function( response ) {
+ responseContainer = [ response ];
+ };
+
+ // Clean-up function
+ jqXHR.always(function() {
+ // Set callback back to previous value
+ window[ jsonpCallback ] = previous;
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
+ window[ jsonpCallback ]( responseContainer[ 0 ] );
+ }
+ });
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( jsonpCallback + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Delegate to script
+ return "script";
+ }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /javascript|ecmascript/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement( "script" );
+
+ script.async = "async";
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+
+ // Dereference the script
+ script = undefined;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( 0, 1 );
+ }
+ }
+ };
+ }
+});
+
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
+ // Abort all pending requests
+ for ( var key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( 0, 1 );
+ }
+ } : false,
+ xhrId = 0,
+ xhrCallbacks;
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+ jQuery.extend( jQuery.support, {
+ ajax: !!xhr,
+ cors: !!xhr && ( "withCredentials" in xhr )
+ });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var xhr = s.xhr(),
+ handle,
+ i;
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( _ ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+
+ var status,
+ statusText,
+ responseHeaders,
+ responses,
+ xml;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occured
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+ responses = {};
+ xml = xhr.responseXML;
+
+ // Construct response list
+ if ( xml && xml.documentElement /* #4958 */ ) {
+ responses.xml = xml;
+ }
+ responses.text = xhr.responseText;
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ // if we're in sync mode or it's in cache
+ // and has been retrieved directly (IE6 & IE7)
+ // we need to manually fire the callback
+ if ( !s.async || xhr.readyState === 4 ) {
+ callback();
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback(0,1);
+ }
+ }
+ };
+ }
+ });
+}
+
+
+
+
+var elemdisplay = {},
+ iframe, iframeDoc,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ],
+ fxNow;
+
+jQuery.fn.extend({
+ show: function( speed, easing, callback ) {
+ var elem, display;
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("show", 3), speed, easing, callback );
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+ display = elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( display === "" && jQuery.css(elem, "display") === "none" ) {
+ jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ if ( display === "" || display === "none" ) {
+ elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
+ }
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, easing, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, easing, callback);
+
+ } else {
+ var elem, display,
+ i = 0,
+ j = this.length;
+
+ for ( ; i < j; i++ ) {
+ elem = this[i];
+ if ( elem.style ) {
+ display = jQuery.css( elem, "display" );
+
+ if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
+ jQuery._data( elem, "olddisplay", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ if ( this[i].style ) {
+ this[i].style.display = "none";
+ }
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2, callback ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, easing, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, easing, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed( speed, easing, callback );
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete, [ false ] );
+ }
+
+ // Do not change referenced properties as per-property easing will be lost
+ prop = jQuery.extend( {}, prop );
+
+ function doAnimation() {
+ // XXX 'this' does not always have a nodeName when running the
+ // test suite
+
+ if ( optall.queue === false ) {
+ jQuery._mark( this );
+ }
+
+ var opt = jQuery.extend( {}, optall ),
+ isElement = this.nodeType === 1,
+ hidden = isElement && jQuery(this).is(":hidden"),
+ name, val, p, e,
+ parts, start, end, unit,
+ method;
+
+ // will store per property easing and be used to determine when an animation is complete
+ opt.animatedProperties = {};
+
+ for ( p in prop ) {
+
+ // property name normalization
+ name = jQuery.camelCase( p );
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ }
+
+ val = prop[ name ];
+
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+ if ( jQuery.isArray( val ) ) {
+ opt.animatedProperties[ name ] = val[ 1 ];
+ val = prop[ name ] = val[ 0 ];
+ } else {
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
+ }
+
+ if ( val === "hide" && hidden || val === "show" && !hidden ) {
+ return opt.complete.call( this );
+ }
+
+ if ( isElement && ( name === "height" || name === "width" ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height animated
+ if ( jQuery.css( this, "display" ) === "inline" &&
+ jQuery.css( this, "float" ) === "none" ) {
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
+ this.style.display = "inline-block";
+
+ } else {
+ this.style.zoom = 1;
+ }
+ }
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ for ( p in prop ) {
+ e = new jQuery.fx( this, opt, p );
+ val = prop[ p ];
+
+ if ( rfxtypes.test( val ) ) {
+
+ // Tracks whether to show or hide based on private
+ // data attached to the element
+ method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
+ if ( method ) {
+ jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
+ e[ method ]();
+ } else {
+ e[ val ]();
+ }
+
+ } else {
+ parts = rfxnum.exec( val );
+ start = e.cur();
+
+ if ( parts ) {
+ end = parseFloat( parts[2] );
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ jQuery.style( this, p, (end || 1) + unit);
+ start = ( (end || 1) / e.cur() ) * start;
+ jQuery.style( this, p, start + unit);
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ }
+
+ // For JS strict compliance
+ return true;
+ }
+
+ return optall.queue === false ?
+ this.each( doAnimation ) :
+ this.queue( optall.queue, doAnimation );
+ },
+
+ stop: function( type, clearQueue, gotoEnd ) {
+ if ( typeof type !== "string" ) {
+ gotoEnd = clearQueue;
+ clearQueue = type;
+ type = undefined;
+ }
+ if ( clearQueue && type !== false ) {
+ this.queue( type || "fx", [] );
+ }
+
+ return this.each(function() {
+ var index,
+ hadTimers = false,
+ timers = jQuery.timers,
+ data = jQuery._data( this );
+
+ // clear marker counters if we know they won't be
+ if ( !gotoEnd ) {
+ jQuery._unmark( true, this );
+ }
+
+ function stopQueue( elem, data, index ) {
+ var hooks = data[ index ];
+ jQuery.removeData( elem, index, true );
+ hooks.stop( gotoEnd );
+ }
+
+ if ( type == null ) {
+ for ( index in data ) {
+ if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {
+ stopQueue( this, data, index );
+ }
+ }
+ } else if ( data[ index = type + ".run" ] && data[ index ].stop ){
+ stopQueue( this, data, index );
+ }
+
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+ if ( gotoEnd ) {
+
+ // force the next step to be the last
+ timers[ index ]( true );
+ } else {
+ timers[ index ].saveState();
+ }
+ hadTimers = true;
+ timers.splice( index, 1 );
+ }
+ }
+
+ // start the next in the queue if the last step wasn't forced
+ // timers currently will call their complete callbacks, which will dequeue
+ // but only if they were gotoEnd
+ if ( !( gotoEnd && hadTimers ) ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ }
+
+});
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout( clearFxNow, 0 );
+ return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+ fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx( "show", 1 ),
+ slideUp: genFx( "hide", 1 ),
+ slideToggle: genFx( "toggle", 1 ),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+ // normalize opt.queue - true/undefined/null -> "fx"
+ if ( opt.queue == null || opt.queue === true ) {
+ opt.queue = "fx";
+ }
+
+ // Queueing
+ opt.old = opt.complete;
+
+ opt.complete = function( noUnmark ) {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue ) {
+ jQuery.dequeue( this, opt.queue );
+ } else if ( noUnmark !== false ) {
+ jQuery._unmark( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ options.orig = options.orig || {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
+ },
+
+ // Get the current size
+ cur: function() {
+ if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var parsed,
+ r = jQuery.css( this.elem, this.prop );
+ // Empty strings, null, undefined and "auto" are converted to 0,
+ // complex values such as "rotate(1rad)" are returned as is,
+ // simple values such as "10px" are parsed to Float.
+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ var self = this,
+ fx = jQuery.fx;
+
+ this.startTime = fxNow || createFxNow();
+ this.end = to;
+ this.now = this.start = from;
+ this.pos = this.state = 0;
+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
+
+ function t( gotoEnd ) {
+ return self.step( gotoEnd );
+ }
+
+ t.queue = this.options.queue;
+ t.elem = this.elem;
+ t.saveState = function() {
+ if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
+ jQuery._data( self.elem, "fxshow" + self.prop, self.start );
+ }
+ };
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval( fx.tick, fx.interval );
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
+
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any flash of content
+ if ( dataShow !== undefined ) {
+ // This show is picking up where a previous hide or show left off
+ this.custom( this.cur(), dataShow );
+ } else {
+ this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
+ }
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom( this.cur(), 0 );
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var p, n, complete,
+ t = fxNow || createFxNow(),
+ done = true,
+ elem = this.elem,
+ options = this.options;
+
+ if ( gotoEnd || t >= options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ options.animatedProperties[ this.prop ] = true;
+
+ for ( p in options.animatedProperties ) {
+ if ( options.animatedProperties[ p ] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ // Reset the overflow
+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+
+ jQuery.each( [ "", "X", "Y" ], function( index, value ) {
+ elem.style[ "overflow" + value ] = options.overflow[ index ];
+ });
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( options.hide ) {
+ jQuery( elem ).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( options.hide || options.show ) {
+ for ( p in options.animatedProperties ) {
+ jQuery.style( elem, p, options.orig[ p ] );
+ jQuery.removeData( elem, "fxshow" + p, true );
+ // Toggle data is no longer needed
+ jQuery.removeData( elem, "toggle" + p, true );
+ }
+ }
+
+ // Execute the complete function
+ // in the event that the complete function throws an exception
+ // we must ensure it won't be called twice. #5684
+
+ complete = options.complete;
+ if ( complete ) {
+
+ options.complete = false;
+ complete.call( elem );
+ }
+ }
+
+ return false;
+
+ } else {
+ // classical easing cannot be used with an Infinity duration
+ if ( options.duration == Infinity ) {
+ this.now = t;
+ } else {
+ n = t - this.startTime;
+ this.state = n / options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
+ this.now = this.start + ( (this.end - this.start) * this.pos );
+ }
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timer,
+ timers = jQuery.timers,
+ i = 0;
+
+ for ( ; i < timers.length; i++ ) {
+ timer = timers[ i ];
+ // Checks the timer has not already been removed
+ if ( !timer() && timers[ i ] === timer ) {
+ timers.splice( i--, 1 );
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ interval: 13,
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style( fx.elem, "opacity", fx.now );
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+// Adds width/height step functions
+// Do not set anything below 0
+jQuery.each([ "width", "height" ], function( i, prop ) {
+ jQuery.fx.step[ prop ] = function( fx ) {
+ jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
+ };
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+// Try to restore the default display value of an element
+function defaultDisplay( nodeName ) {
+
+ if ( !elemdisplay[ nodeName ] ) {
+
+ var body = document.body,
+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
+ display = elem.css( "display" );
+ elem.remove();
+
+ // If the simple way fails,
+ // get element's real default display by attaching it to a temp iframe
+ if ( display === "none" || display === "" ) {
+ // No iframe to use yet, so create it
+ if ( !iframe ) {
+ iframe = document.createElement( "iframe" );
+ iframe.frameBorder = iframe.width = iframe.height = 0;
+ }
+
+ body.appendChild( iframe );
+
+ // Create a cacheable copy of the iframe document on first call.
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
+ if ( !iframeDoc || !iframe.createElement ) {
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+ iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
+ iframeDoc.close();
+ }
+
+ elem = iframeDoc.createElement( nodeName );
+
+ iframeDoc.body.appendChild( elem );
+
+ display = jQuery.css( elem, "display" );
+ body.removeChild( iframe );
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+ rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0], box;
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ try {
+ box = elem.getBoundingClientRect();
+ } catch(e) {}
+
+ var doc = elem.ownerDocument,
+ docElem = doc.documentElement;
+
+ // Make sure we're not dealing with a disconnected DOM node
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
+ }
+
+ var body = doc.body,
+ win = getWindow(doc),
+ clientTop = docElem.clientTop || body.clientTop || 0,
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
+ top = box.top + scrollTop - clientTop,
+ left = box.left + scrollLeft - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ var computedStyle,
+ offsetParent = elem.offsetParent,
+ prevOffsetParent = elem,
+ doc = elem.ownerDocument,
+ docElem = doc.documentElement,
+ body = doc.body,
+ defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop,
+ left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent;
+ offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop,
+ left = body.offsetLeft;
+
+ if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function( val ) {
+ var elem, win;
+
+ if ( val === undefined ) {
+ elem = this[ 0 ];
+
+ if ( !elem ) {
+ return null;
+ }
+
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery( win ).scrollLeft(),
+ i ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+
+
+
+// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn[ "inner" + name ] = function() {
+ var elem = this[0];
+ return elem ?
+ elem.style ?
+ parseFloat( jQuery.css( elem, type, "padding" ) ) :
+ this[ type ]() :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn[ "outer" + name ] = function( margin ) {
+ var elem = this[0];
+ return elem ?
+ elem.style ?
+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
+ this[ type ]() :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ if ( jQuery.isWindow( elem ) ) {
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+ var docElemProp = elem.document.documentElement[ "client" + name ],
+ body = elem.document.body;
+ return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+ body && body[ "client" + name ] || docElemProp;
+
+ // Get document width or height
+ } else if ( elem.nodeType === 9 ) {
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ return Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ );
+
+ // Get or set width or height on the element
+ } else if ( size === undefined ) {
+ var orig = jQuery.css( elem, type ),
+ ret = parseFloat( orig );
+
+ return jQuery.isNumeric( ret ) ? ret : orig;
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ } else {
+ return this.css( type, typeof size === "string" ? size : size + "px" );
+ }
+ };
+
+});
+
+
+
+
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+// Expose jQuery as an AMD module, but only for AMD loaders that
+// understand the issues with loading multiple versions of jQuery
+// in a page that all might call define(). The loader will indicate
+// they have special allowances for multiple jQuery versions by
+// specifying define.amd.jQuery = true. Register as a named module,
+// since jQuery can be concatenated with other files that may use define,
+// but not use a proper concatenation script that understands anonymous
+// AMD modules. A named AMD is safest and most robust way to register.
+// Lowercase jquery is used because AMD module names are derived from
+// file names, and jQuery is normally delivered in a lowercase file name.
+// Do this after creating the global so that if an AMD module wants to call
+// noConflict to hide this version of jQuery, it will work.
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
+ define( "jquery", [], function () { return jQuery; } );
+}
+
+
+
+})( window );
diff --git a/jquery/jquery.ba-1.3-hashchange.js b/jquery/jquery.ba-1.3-hashchange.js
new file mode 100644
index 0000000..47105f4
--- /dev/null
+++ b/jquery/jquery.ba-1.3-hashchange.js
@@ -0,0 +1,390 @@
+/*!
+ * jQuery hashchange event - v1.3 - 7/21/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+// Script: jQuery hashchange event
+//
+// *Version: 1.3, Last updated: 7/21/2010*
+//
+// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
+// GitHub - http://github.com/cowboy/jquery-hashchange/
+// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
+// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
+//
+// About: License
+//
+// Copyright (c) 2010 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+//
+// About: Examples
+//
+// These working examples, complete with fully commented code, illustrate a few
+// ways in which this plugin can be used.
+//
+// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
+// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
+//
+// About: Support and Testing
+//
+// Information about what version or versions of jQuery this plugin has been
+// tested with, what browsers it has been tested in, and where the unit tests
+// reside (so you can test it yourself).
+//
+// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
+// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
+// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
+//
+// About: Known issues
+//
+// While this jQuery hashchange event implementation is quite stable and
+// robust, there are a few unfortunate browser bugs surrounding expected
+// hashchange event-based behaviors, independent of any JavaScript
+// window.onhashchange abstraction. See the following examples for more
+// information:
+//
+// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
+// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
+// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
+// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
+//
+// Also note that should a browser natively support the window.onhashchange
+// event, but not report that it does, the fallback polling loop will be used.
+//
+// About: Release History
+//
+// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
+// "removable" for mobile-only development. Added IE6/7 document.title
+// support. Attempted to make Iframe as hidden as possible by using
+// techniques from http://www.paciellogroup.com/blog/?p=604. Added
+// support for the "shortcut" format $(window).hashchange( fn ) and
+// $(window).hashchange() like jQuery provides for built-in events.
+// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
+// lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
+// and <jQuery.fn.hashchange.src> properties plus document-domain.html
+// file to address access denied issues when setting document.domain in
+// IE6/7.
+// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
+// from a page on another domain would cause an error in Safari 4. Also,
+// IE6/7 Iframe is now inserted after the body (this actually works),
+// which prevents the page from scrolling when the event is first bound.
+// Event can also now be bound before DOM ready, but it won't be usable
+// before then in IE6/7.
+// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
+// where browser version is incorrectly reported as 8.0, despite
+// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
+// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
+// window.onhashchange functionality into a separate plugin for users
+// who want just the basic event & back button support, without all the
+// extra awesomeness that BBQ provides. This plugin will be included as
+// part of jQuery BBQ, but also be available separately.
+
+(function($,window,undefined){
+ '$:nomunge'; // Used by YUI compressor.
+
+ // Reused string.
+ var str_hashchange = 'hashchange',
+
+ // Method / object references.
+ doc = document,
+ fake_onhashchange,
+ special = $.event.special,
+
+ // Does the browser support window.onhashchange? Note that IE8 running in
+ // IE7 compatibility mode reports true for 'onhashchange' in window, even
+ // though the event isn't supported, so also test document.documentMode.
+ doc_mode = doc.documentMode,
+ supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
+
+ // Get location.hash (or what you'd expect location.hash to be) sans any
+ // leading #. Thanks for making this necessary, Firefox!
+ function get_fragment( url ) {
+ url = url || location.href;
+ return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
+ };
+
+ // Method: jQuery.fn.hashchange
+ //
+ // Bind a handler to the window.onhashchange event or trigger all bound
+ // window.onhashchange event handlers. This behavior is consistent with
+ // jQuery's built-in event handlers.
+ //
+ // Usage:
+ //
+ // > jQuery(window).hashchange( [ handler ] );
+ //
+ // Arguments:
+ //
+ // handler - (Function) Optional handler to be bound to the hashchange
+ // event. This is a "shortcut" for the more verbose form:
+ // jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
+ // all bound window.onhashchange event handlers will be triggered. This
+ // is a shortcut for the more verbose
+ // jQuery(window).trigger( 'hashchange' ). These forms are described in
+ // the <hashchange event> section.
+ //
+ // Returns:
+ //
+ // (jQuery) The initial jQuery collection of elements.
+
+ // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
+ // $(elem).hashchange() for triggering, like jQuery does for built-in events.
+ $.fn[ str_hashchange ] = function( fn ) {
+ return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
+ };
+
+ // Property: jQuery.fn.hashchange.delay
+ //
+ // The numeric interval (in milliseconds) at which the <hashchange event>
+ // polling loop executes. Defaults to 50.
+
+ // Property: jQuery.fn.hashchange.domain
+ //
+ // If you're setting document.domain in your JavaScript, and you want hash
+ // history to work in IE6/7, not only must this property be set, but you must
+ // also set document.domain BEFORE jQuery is loaded into the page. This
+ // property is only applicable if you are supporting IE6/7 (or IE8 operating
+ // in "IE7 compatibility" mode).
+ //
+ // In addition, the <jQuery.fn.hashchange.src> property must be set to the
+ // path of the included "document-domain.html" file, which can be renamed or
+ // modified if necessary (note that the document.domain specified must be the
+ // same in both your main JavaScript as well as in this file).
+ //
+ // Usage:
+ //
+ // jQuery.fn.hashchange.domain = document.domain;
+
+ // Property: jQuery.fn.hashchange.src
+ //
+ // If, for some reason, you need to specify an Iframe src file (for example,
+ // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
+ // do so using this property. Note that when using this property, history
+ // won't be recorded in IE6/7 until the Iframe src file loads. This property
+ // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
+ // compatibility" mode).
+ //
+ // Usage:
+ //
+ // jQuery.fn.hashchange.src = 'path/to/file.html';
+
+ $.fn[ str_hashchange ].delay = 50;
+ /*
+ $.fn[ str_hashchange ].domain = null;
+ $.fn[ str_hashchange ].src = null;
+ */
+
+ // Event: hashchange event
+ //
+ // Fired when location.hash changes. In browsers that support it, the native
+ // HTML5 window.onhashchange event is used, otherwise a polling loop is
+ // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
+ // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
+ // compatibility" mode), a hidden Iframe is created to allow the back button
+ // and hash-based history to work.
+ //
+ // Usage as described in <jQuery.fn.hashchange>:
+ //
+ // > // Bind an event handler.
+ // > jQuery(window).hashchange( function(e) {
+ // > var hash = location.hash;
+ // > ...
+ // > });
+ // >
+ // > // Manually trigger the event handler.
+ // > jQuery(window).hashchange();
+ //
+ // A more verbose usage that allows for event namespacing:
+ //
+ // > // Bind an event handler.
+ // > jQuery(window).bind( 'hashchange', function(e) {
+ // > var hash = location.hash;
+ // > ...
+ // > });
+ // >
+ // > // Manually trigger the event handler.
+ // > jQuery(window).trigger( 'hashchange' );
+ //
+ // Additional Notes:
+ //
+ // * The polling loop and Iframe are not created until at least one handler
+ // is actually bound to the 'hashchange' event.
+ // * If you need the bound handler(s) to execute immediately, in cases where
+ // a location.hash exists on page load, via bookmark or page refresh for
+ // example, use jQuery(window).hashchange() or the more verbose
+ // jQuery(window).trigger( 'hashchange' ).
+ // * The event can be bound before DOM ready, but since it won't be usable
+ // before then in IE6/7 (due to the necessary Iframe), recommended usage is
+ // to bind it inside a DOM ready handler.
+
+ // Override existing $.event.special.hashchange methods (allowing this plugin
+ // to be defined after jQuery BBQ in BBQ's source code).
+ special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
+
+ // Called only when the first 'hashchange' event is bound to window.
+ setup: function() {
+ // If window.onhashchange is supported natively, there's nothing to do..
+ if ( supports_onhashchange ) { return false; }
+
+ // Otherwise, we need to create our own. And we don't want to call this
+ // until the user binds to the event, just in case they never do, since it
+ // will create a polling loop and possibly even a hidden Iframe.
+ $( fake_onhashchange.start );
+ },
+
+ // Called only when the last 'hashchange' event is unbound from window.
+ teardown: function() {
+ // If window.onhashchange is supported natively, there's nothing to do..
+ if ( supports_onhashchange ) { return false; }
+
+ // Otherwise, we need to stop ours (if possible).
+ $( fake_onhashchange.stop );
+ }
+
+ });
+
+ // fake_onhashchange does all the work of triggering the window.onhashchange
+ // event for browsers that don't natively support it, including creating a
+ // polling loop to watch for hash changes and in IE 6/7 creating a hidden
+ // Iframe to enable back and forward.
+ fake_onhashchange = (function(){
+ var self = {},
+ timeout_id,
+
+ // Remember the initial hash so it doesn't get triggered immediately.
+ last_hash = get_fragment(),
+
+ fn_retval = function(val){ return val; },
+ history_set = fn_retval,
+ history_get = fn_retval;
+
+ // Start the polling loop.
+ self.start = function() {
+ timeout_id || poll();
+ };
+
+ // Stop the polling loop.
+ self.stop = function() {
+ timeout_id && clearTimeout( timeout_id );
+ timeout_id = undefined;
+ };
+
+ // This polling loop checks every $.fn.hashchange.delay milliseconds to see
+ // if location.hash has changed, and triggers the 'hashchange' event on
+ // window when necessary.
+ function poll() {
+ var hash = get_fragment(),
+ history_hash = history_get( last_hash );
+
+ if ( hash !== last_hash ) {
+ history_set( last_hash = hash, history_hash );
+
+ $(window).trigger( str_hashchange );
+
+ } else if ( history_hash !== last_hash ) {
+ location.href = location.href.replace( /#.*/, '' ) + history_hash;
+ }
+
+ timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
+ };
+
+ // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+ // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
+ // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+ $.browser.msie && !supports_onhashchange && (function(){
+ // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
+ // when running in "IE7 compatibility" mode.
+
+ var iframe,
+ iframe_src;
+
+ // When the event is bound and polling starts in IE 6/7, create a hidden
+ // Iframe for history handling.
+ self.start = function(){
+ if ( !iframe ) {
+ iframe_src = $.fn[ str_hashchange ].src;
+ iframe_src = iframe_src && iframe_src + get_fragment();
+
+ // Create hidden Iframe. Attempt to make Iframe as hidden as possible
+ // by using techniques from http://www.paciellogroup.com/blog/?p=604.
+ iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
+
+ // When Iframe has completely loaded, initialize the history and
+ // start polling.
+ .one( 'load', function(){
+ iframe_src || history_set( get_fragment() );
+ poll();
+ })
+
+ // Load Iframe src if specified, otherwise nothing.
+ .attr( 'src', iframe_src || 'javascript:0' )
+
+ // Append Iframe after the end of the body to prevent unnecessary
+ // initial page scrolling (yes, this works).
+ .insertAfter( 'body' )[0].contentWindow;
+
+ // Whenever `document.title` changes, update the Iframe's title to
+ // prettify the back/next history menu entries. Since IE sometimes
+ // errors with "Unspecified error" the very first time this is set
+ // (yes, very useful) wrap this with a try/catch block.
+ doc.onpropertychange = function(){
+ try {
+ if ( event.propertyName === 'title' ) {
+ iframe.document.title = doc.title;
+ }
+ } catch(e) {}
+ };
+
+ }
+ };
+
+ // Override the "stop" method since an IE6/7 Iframe was created. Even
+ // if there are no longer any bound event handlers, the polling loop
+ // is still necessary for back/next to work at all!
+ self.stop = fn_retval;
+
+ // Get history by looking at the hidden Iframe's location.hash.
+ history_get = function() {
+ return get_fragment( iframe.location.href );
+ };
+
+ // Set a new history item by opening and then closing the Iframe
+ // document, *then* setting its location.hash. If document.domain has
+ // been set, update that as well.
+ history_set = function( hash, history_hash ) {
+ var iframe_doc = iframe.document,
+ domain = $.fn[ str_hashchange ].domain;
+
+ if ( hash !== history_hash ) {
+ // Update Iframe with any initial `document.title` that might be set.
+ iframe_doc.title = doc.title;
+
+ // Opening the Iframe's document after it has been closed is what
+ // actually adds a history entry.
+ iframe_doc.open();
+
+ // Set document.domain for the Iframe document as well, if necessary.
+ domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
+
+ iframe_doc.close();
+
+ // Update the Iframe's hash, for great justice.
+ iframe.location.hash = hash;
+ }
+ };
+
+ })();
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ return self;
+ })();
+
+})(jQuery,this);
diff --git a/jquery/jquery.powertip-1.2.0.js b/jquery/jquery.powertip-1.2.0.js
new file mode 100644
index 0000000..07e87fe
--- /dev/null
+++ b/jquery/jquery.powertip-1.2.0.js
@@ -0,0 +1,1166 @@
+/*!
+ PowerTip - v1.2.0 - 2013-04-03
+ http://stevenbenner.github.com/jquery-powertip/
+ Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+}(function($) {
+
+ // useful private variables
+ var $document = $(document),
+ $window = $(window),
+ $body = $('body');
+
+ // constants
+ var DATA_DISPLAYCONTROLLER = 'displayController',
+ DATA_HASACTIVEHOVER = 'hasActiveHover',
+ DATA_FORCEDOPEN = 'forcedOpen',
+ DATA_HASMOUSEMOVE = 'hasMouseMove',
+ DATA_MOUSEONTOTIP = 'mouseOnToPopup',
+ DATA_ORIGINALTITLE = 'originalTitle',
+ DATA_POWERTIP = 'powertip',
+ DATA_POWERTIPJQ = 'powertipjq',
+ DATA_POWERTIPTARGET = 'powertiptarget',
+ RAD2DEG = 180 / Math.PI;
+
+ /**
+ * Session data
+ * Private properties global to all powerTip instances
+ */
+ var session = {
+ isTipOpen: false,
+ isFixedTipOpen: false,
+ isClosing: false,
+ tipOpenImminent: false,
+ activeHover: null,
+ currentX: 0,
+ currentY: 0,
+ previousX: 0,
+ previousY: 0,
+ desyncTimeout: null,
+ mouseTrackingActive: false,
+ delayInProgress: false,
+ windowWidth: 0,
+ windowHeight: 0,
+ scrollTop: 0,
+ scrollLeft: 0
+ };
+
+ /**
+ * Collision enumeration
+ * @enum {number}
+ */
+ var Collision = {
+ none: 0,
+ top: 1,
+ bottom: 2,
+ left: 4,
+ right: 8
+ };
+
+ /**
+ * Display hover tooltips on the matched elements.
+ * @param {(Object|string)} opts The options object to use for the plugin, or
+ * the name of a method to invoke on the first matched element.
+ * @param {*=} [arg] Argument for an invoked method (optional).
+ * @return {jQuery} jQuery object for the matched selectors.
+ */
+ $.fn.powerTip = function(opts, arg) {
+ // don't do any work if there were no matched elements
+ if (!this.length) {
+ return this;
+ }
+
+ // handle api method calls on the plugin, e.g. powerTip('hide')
+ if ($.type(opts) === 'string' && $.powerTip[opts]) {
+ return $.powerTip[opts].call(this, this, arg);
+ }
+
+ // extend options and instantiate TooltipController
+ var options = $.extend({}, $.fn.powerTip.defaults, opts),
+ tipController = new TooltipController(options);
+
+ // hook mouse and viewport dimension tracking
+ initTracking();
+
+ // setup the elements
+ this.each(function elementSetup() {
+ var $this = $(this),
+ dataPowertip = $this.data(DATA_POWERTIP),
+ dataElem = $this.data(DATA_POWERTIPJQ),
+ dataTarget = $this.data(DATA_POWERTIPTARGET),
+ title;
+
+ // handle repeated powerTip calls on the same element by destroying the
+ // original instance hooked to it and replacing it with this call
+ if ($this.data(DATA_DISPLAYCONTROLLER)) {
+ $.powerTip.destroy($this);
+ }
+
+ // attempt to use title attribute text if there is no data-powertip,
+ // data-powertipjq or data-powertiptarget. If we do use the title
+ // attribute, delete the attribute so the browser will not show it
+ title = $this.attr('title');
+ if (!dataPowertip && !dataTarget && !dataElem && title) {
+ $this.data(DATA_POWERTIP, title);
+ $this.data(DATA_ORIGINALTITLE, title);
+ $this.removeAttr('title');
+ }
+
+ // create hover controllers for each element
+ $this.data(
+ DATA_DISPLAYCONTROLLER,
+ new DisplayController($this, options, tipController)
+ );
+ });
+
+ // attach events to matched elements if the manual options is not enabled
+ if (!options.manual) {
+ this.on({
+ // mouse events
+ 'mouseenter.powertip': function elementMouseEnter(event) {
+ $.powerTip.show(this, event);
+ },
+ 'mouseleave.powertip': function elementMouseLeave() {
+ $.powerTip.hide(this);
+ },
+ // keyboard events
+ 'focus.powertip': function elementFocus() {
+ $.powerTip.show(this);
+ },
+ 'blur.powertip': function elementBlur() {
+ $.powerTip.hide(this, true);
+ },
+ 'keydown.powertip': function elementKeyDown(event) {
+ // close tooltip when the escape key is pressed
+ if (event.keyCode === 27) {
+ $.powerTip.hide(this, true);
+ }
+ }
+ });
+ }
+
+ return this;
+ };
+
+ /**
+ * Default options for the powerTip plugin.
+ */
+ $.fn.powerTip.defaults = {
+ fadeInTime: 200,
+ fadeOutTime: 100,
+ followMouse: false,
+ popupId: 'powerTip',
+ intentSensitivity: 7,
+ intentPollInterval: 100,
+ closeDelay: 100,
+ placement: 'n',
+ smartPlacement: false,
+ offset: 10,
+ mouseOnToPopup: false,
+ manual: false
+ };
+
+ /**
+ * Default smart placement priority lists.
+ * The first item in the array is the highest priority, the last is the lowest.
+ * The last item is also the default, which will be used if all previous options
+ * do not fit.
+ */
+ $.fn.powerTip.smartPlacementLists = {
+ n: ['n', 'ne', 'nw', 's'],
+ e: ['e', 'ne', 'se', 'w', 'nw', 'sw', 'n', 's', 'e'],
+ s: ['s', 'se', 'sw', 'n'],
+ w: ['w', 'nw', 'sw', 'e', 'ne', 'se', 'n', 's', 'w'],
+ nw: ['nw', 'w', 'sw', 'n', 's', 'se', 'nw'],
+ ne: ['ne', 'e', 'se', 'n', 's', 'sw', 'ne'],
+ sw: ['sw', 'w', 'nw', 's', 'n', 'ne', 'sw'],
+ se: ['se', 'e', 'ne', 's', 'n', 'nw', 'se'],
+ 'nw-alt': ['nw-alt', 'n', 'ne-alt', 'sw-alt', 's', 'se-alt', 'w', 'e'],
+ 'ne-alt': ['ne-alt', 'n', 'nw-alt', 'se-alt', 's', 'sw-alt', 'e', 'w'],
+ 'sw-alt': ['sw-alt', 's', 'se-alt', 'nw-alt', 'n', 'ne-alt', 'w', 'e'],
+ 'se-alt': ['se-alt', 's', 'sw-alt', 'ne-alt', 'n', 'nw-alt', 'e', 'w']
+ };
+
+ /**
+ * Public API
+ */
+ $.powerTip = {
+ /**
+ * Attempts to show the tooltip for the specified element.
+ * @param {jQuery|Element} element The element to open the tooltip for.
+ * @param {jQuery.Event=} event jQuery event for hover intent and mouse
+ * tracking (optional).
+ */
+ show: function apiShowTip(element, event) {
+ if (event) {
+ trackMouse(event);
+ session.previousX = event.pageX;
+ session.previousY = event.pageY;
+ $(element).data(DATA_DISPLAYCONTROLLER).show();
+ } else {
+ $(element).first().data(DATA_DISPLAYCONTROLLER).show(true, true);
+ }
+ return element;
+ },
+
+ /**
+ * Repositions the tooltip on the element.
+ * @param {jQuery|Element} element The element the tooltip is shown for.
+ */
+ reposition: function apiResetPosition(element) {
+ $(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();
+ return element;
+ },
+
+ /**
+ * Attempts to close any open tooltips.
+ * @param {(jQuery|Element)=} element The element with the tooltip that
+ * should be closed (optional).
+ * @param {boolean=} immediate Disable close delay (optional).
+ */
+ hide: function apiCloseTip(element, immediate) {
+ if (element) {
+ $(element).first().data(DATA_DISPLAYCONTROLLER).hide(immediate);
+ } else {
+ if (session.activeHover) {
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).hide(true);
+ }
+ }
+ return element;
+ },
+
+ /**
+ * Destroy and roll back any powerTip() instance on the specified element.
+ * @param {jQuery|Element} element The element with the powerTip instance.
+ */
+ destroy: function apiDestroy(element) {
+ $(element).off('.powertip').each(function destroy() {
+ var $this = $(this),
+ dataAttributes = [
+ DATA_ORIGINALTITLE,
+ DATA_DISPLAYCONTROLLER,
+ DATA_HASACTIVEHOVER,
+ DATA_FORCEDOPEN
+ ];
+
+ if ($this.data(DATA_ORIGINALTITLE)) {
+ $this.attr('title', $this.data(DATA_ORIGINALTITLE));
+ dataAttributes.push(DATA_POWERTIP);
+ }
+
+ $this.removeData(dataAttributes);
+ });
+ return element;
+ }
+ };
+
+ // API aliasing
+ $.powerTip.showTip = $.powerTip.show;
+ $.powerTip.closeTip = $.powerTip.hide;
+
+ /**
+ * Creates a new CSSCoordinates object.
+ * @private
+ * @constructor
+ */
+ function CSSCoordinates() {
+ var me = this;
+
+ // initialize object properties
+ me.top = 'auto';
+ me.left = 'auto';
+ me.right = 'auto';
+ me.bottom = 'auto';
+
+ /**
+ * Set a property to a value.
+ * @private
+ * @param {string} property The name of the property.
+ * @param {number} value The value of the property.
+ */
+ me.set = function(property, value) {
+ if ($.isNumeric(value)) {
+ me[property] = Math.round(value);
+ }
+ };
+ }
+
+ /**
+ * Creates a new tooltip display controller.
+ * @private
+ * @constructor
+ * @param {jQuery} element The element that this controller will handle.
+ * @param {Object} options Options object containing settings.
+ * @param {TooltipController} tipController The TooltipController object for
+ * this instance.
+ */
+ function DisplayController(element, options, tipController) {
+ var hoverTimer = null;
+
+ /**
+ * Begins the process of showing a tooltip.
+ * @private
+ * @param {boolean=} immediate Skip intent testing (optional).
+ * @param {boolean=} forceOpen Ignore cursor position and force tooltip to
+ * open (optional).
+ */
+ function openTooltip(immediate, forceOpen) {
+ cancelTimer();
+ if (!element.data(DATA_HASACTIVEHOVER)) {
+ if (!immediate) {
+ session.tipOpenImminent = true;
+ hoverTimer = setTimeout(
+ function intentDelay() {
+ hoverTimer = null;
+ checkForIntent();
+ },
+ options.intentPollInterval
+ );
+ } else {
+ if (forceOpen) {
+ element.data(DATA_FORCEDOPEN, true);
+ }
+ tipController.showTip(element);
+ }
+ }
+ }
+
+ /**
+ * Begins the process of closing a tooltip.
+ * @private
+ * @param {boolean=} disableDelay Disable close delay (optional).
+ */
+ function closeTooltip(disableDelay) {
+ cancelTimer();
+ session.tipOpenImminent = false;
+ if (element.data(DATA_HASACTIVEHOVER)) {
+ element.data(DATA_FORCEDOPEN, false);
+ if (!disableDelay) {
+ session.delayInProgress = true;
+ hoverTimer = setTimeout(
+ function closeDelay() {
+ hoverTimer = null;
+ tipController.hideTip(element);
+ session.delayInProgress = false;
+ },
+ options.closeDelay
+ );
+ } else {
+ tipController.hideTip(element);
+ }
+ }
+ }
+
+ /**
+ * Checks mouse position to make sure that the user intended to hover on the
+ * specified element before showing the tooltip.
+ * @private
+ */
+ function checkForIntent() {
+ // calculate mouse position difference
+ var xDifference = Math.abs(session.previousX - session.currentX),
+ yDifference = Math.abs(session.previousY - session.currentY),
+ totalDifference = xDifference + yDifference;
+
+ // check if difference has passed the sensitivity threshold
+ if (totalDifference < options.intentSensitivity) {
+ tipController.showTip(element);
+ } else {
+ // try again
+ session.previousX = session.currentX;
+ session.previousY = session.currentY;
+ openTooltip();
+ }
+ }
+
+ /**
+ * Cancels active hover timer.
+ * @private
+ */
+ function cancelTimer() {
+ hoverTimer = clearTimeout(hoverTimer);
+ session.delayInProgress = false;
+ }
+
+ /**
+ * Repositions the tooltip on this element.
+ * @private
+ */
+ function repositionTooltip() {
+ tipController.resetPosition(element);
+ }
+
+ // expose the methods
+ this.show = openTooltip;
+ this.hide = closeTooltip;
+ this.cancel = cancelTimer;
+ this.resetPosition = repositionTooltip;
+ }
+
+ /**
+ * Creates a new Placement Calculator.
+ * @private
+ * @constructor
+ */
+ function PlacementCalculator() {
+ /**
+ * Compute the CSS position to display a tooltip at the specified placement
+ * relative to the specified element.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ * @param {string} placement The placement for the tooltip.
+ * @param {number} tipWidth Width of the tooltip element in pixels.
+ * @param {number} tipHeight Height of the tooltip element in pixels.
+ * @param {number} offset Distance to offset tooltips in pixels.
+ * @return {CSSCoordinates} A CSSCoordinates object with the position.
+ */
+ function computePlacementCoords(element, placement, tipWidth, tipHeight, offset) {
+ var placementBase = placement.split('-')[0], // ignore 'alt' for corners
+ coords = new CSSCoordinates(),
+ position;
+
+ if (isSvgElement(element)) {
+ position = getSvgPlacement(element, placementBase);
+ } else {
+ position = getHtmlPlacement(element, placementBase);
+ }
+
+ // calculate the appropriate x and y position in the document
+ switch (placement) {
+ case 'n':
+ coords.set('left', position.left - (tipWidth / 2));
+ coords.set('bottom', session.windowHeight - position.top + offset);
+ break;
+ case 'e':
+ coords.set('left', position.left + offset);
+ coords.set('top', position.top - (tipHeight / 2));
+ break;
+ case 's':
+ coords.set('left', position.left - (tipWidth / 2));
+ coords.set('top', position.top + offset);
+ break;
+ case 'w':
+ coords.set('top', position.top - (tipHeight / 2));
+ coords.set('right', session.windowWidth - position.left + offset);
+ break;
+ case 'nw':
+ coords.set('bottom', session.windowHeight - position.top + offset);
+ coords.set('right', session.windowWidth - position.left - 20);
+ break;
+ case 'nw-alt':
+ coords.set('left', position.left);
+ coords.set('bottom', session.windowHeight - position.top + offset);
+ break;
+ case 'ne':
+ coords.set('left', position.left - 20);
+ coords.set('bottom', session.windowHeight - position.top + offset);
+ break;
+ case 'ne-alt':
+ coords.set('bottom', session.windowHeight - position.top + offset);
+ coords.set('right', session.windowWidth - position.left);
+ break;
+ case 'sw':
+ coords.set('top', position.top + offset);
+ coords.set('right', session.windowWidth - position.left - 20);
+ break;
+ case 'sw-alt':
+ coords.set('left', position.left);
+ coords.set('top', position.top + offset);
+ break;
+ case 'se':
+ coords.set('left', position.left - 20);
+ coords.set('top', position.top + offset);
+ break;
+ case 'se-alt':
+ coords.set('top', position.top + offset);
+ coords.set('right', session.windowWidth - position.left);
+ break;
+ }
+
+ return coords;
+ }
+
+ /**
+ * Finds the tooltip attachment point in the document for a HTML DOM element
+ * for the specified placement.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ * @param {string} placement The placement for the tooltip.
+ * @return {Object} An object with the top,left position values.
+ */
+ function getHtmlPlacement(element, placement) {
+ var objectOffset = element.offset(),
+ objectWidth = element.outerWidth(),
+ objectHeight = element.outerHeight(),
+ left,
+ top;
+
+ // calculate the appropriate x and y position in the document
+ switch (placement) {
+ case 'n':
+ left = objectOffset.left + objectWidth / 2;
+ top = objectOffset.top;
+ break;
+ case 'e':
+ left = objectOffset.left + objectWidth;
+ top = objectOffset.top + objectHeight / 2;
+ break;
+ case 's':
+ left = objectOffset.left + objectWidth / 2;
+ top = objectOffset.top + objectHeight;
+ break;
+ case 'w':
+ left = objectOffset.left;
+ top = objectOffset.top + objectHeight / 2;
+ break;
+ case 'nw':
+ left = objectOffset.left;
+ top = objectOffset.top;
+ break;
+ case 'ne':
+ left = objectOffset.left + objectWidth;
+ top = objectOffset.top;
+ break;
+ case 'sw':
+ left = objectOffset.left;
+ top = objectOffset.top + objectHeight;
+ break;
+ case 'se':
+ left = objectOffset.left + objectWidth;
+ top = objectOffset.top + objectHeight;
+ break;
+ }
+
+ return {
+ top: top,
+ left: left
+ };
+ }
+
+ /**
+ * Finds the tooltip attachment point in the document for a SVG element for
+ * the specified placement.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ * @param {string} placement The placement for the tooltip.
+ * @return {Object} An object with the top,left position values.
+ */
+ function getSvgPlacement(element, placement) {
+ var svgElement = element.closest('svg')[0],
+ domElement = element[0],
+ point = svgElement.createSVGPoint(),
+ boundingBox = domElement.getBBox(),
+ matrix = domElement.getScreenCTM(),
+ halfWidth = boundingBox.width / 2,
+ halfHeight = boundingBox.height / 2,
+ placements = [],
+ placementKeys = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'],
+ coords,
+ rotation,
+ steps,
+ x;
+
+ function pushPlacement() {
+ placements.push(point.matrixTransform(matrix));
+ }
+
+ // get bounding box corners and midpoints
+ point.x = boundingBox.x;
+ point.y = boundingBox.y;
+ pushPlacement();
+ point.x += halfWidth;
+ pushPlacement();
+ point.x += halfWidth;
+ pushPlacement();
+ point.y += halfHeight;
+ pushPlacement();
+ point.y += halfHeight;
+ pushPlacement();
+ point.x -= halfWidth;
+ pushPlacement();
+ point.x -= halfWidth;
+ pushPlacement();
+ point.y -= halfHeight;
+ pushPlacement();
+
+ // determine rotation
+ if (placements[0].y !== placements[1].y || placements[0].x !== placements[7].x) {
+ rotation = Math.atan2(matrix.b, matrix.a) * RAD2DEG;
+ steps = Math.ceil(((rotation % 360) - 22.5) / 45);
+ if (steps < 1) {
+ steps += 8;
+ }
+ while (steps--) {
+ placementKeys.push(placementKeys.shift());
+ }
+ }
+
+ // find placement
+ for (x = 0; x < placements.length; x++) {
+ if (placementKeys[x] === placement) {
+ coords = placements[x];
+ break;
+ }
+ }
+
+ return {
+ top: coords.y + session.scrollTop,
+ left: coords.x + session.scrollLeft
+ };
+ }
+
+ // expose methods
+ this.compute = computePlacementCoords;
+ }
+
+ /**
+ * Creates a new tooltip controller.
+ * @private
+ * @constructor
+ * @param {Object} options Options object containing settings.
+ */
+ function TooltipController(options) {
+ var placementCalculator = new PlacementCalculator(),
+ tipElement = $('#' + options.popupId);
+
+ // build and append tooltip div if it does not already exist
+ if (tipElement.length === 0) {
+ tipElement = $('<div/>', { id: options.popupId });
+ // grab body element if it was not populated when the script loaded
+ // note: this hack exists solely for jsfiddle support
+ if ($body.length === 0) {
+ $body = $('body');
+ }
+ $body.append(tipElement);
+ }
+
+ // hook mousemove for cursor follow tooltips
+ if (options.followMouse) {
+ // only one positionTipOnCursor hook per tooltip element, please
+ if (!tipElement.data(DATA_HASMOUSEMOVE)) {
+ $document.on('mousemove', positionTipOnCursor);
+ $window.on('scroll', positionTipOnCursor);
+ tipElement.data(DATA_HASMOUSEMOVE, true);
+ }
+ }
+
+ // if we want to be able to mouse onto the tooltip then we need to attach
+ // hover events to the tooltip that will cancel a close request on hover and
+ // start a new close request on mouseleave
+ if (options.mouseOnToPopup) {
+ tipElement.on({
+ mouseenter: function tipMouseEnter() {
+ // we only let the mouse stay on the tooltip if it is set to let
+ // users interact with it
+ if (tipElement.data(DATA_MOUSEONTOTIP)) {
+ // check activeHover in case the mouse cursor entered the
+ // tooltip during the fadeOut and close cycle
+ if (session.activeHover) {
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel();
+ }
+ }
+ },
+ mouseleave: function tipMouseLeave() {
+ // check activeHover in case the mouse cursor entered the
+ // tooltip during the fadeOut and close cycle
+ if (session.activeHover) {
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).hide();
+ }
+ }
+ });
+ }
+
+ /**
+ * Gives the specified element the active-hover state and queues up the
+ * showTip function.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ */
+ function beginShowTip(element) {
+ element.data(DATA_HASACTIVEHOVER, true);
+ // show tooltip, asap
+ tipElement.queue(function queueTipInit(next) {
+ showTip(element);
+ next();
+ });
+ }
+
+ /**
+ * Shows the tooltip, as soon as possible.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ */
+ function showTip(element) {
+ var tipContent;
+
+ // it is possible, especially with keyboard navigation, to move on to
+ // another element with a tooltip during the queue to get to this point
+ // in the code. if that happens then we need to not proceed or we may
+ // have the fadeout callback for the last tooltip execute immediately
+ // after this code runs, causing bugs.
+ if (!element.data(DATA_HASACTIVEHOVER)) {
+ return;
+ }
+
+ // if the tooltip is open and we got asked to open another one then the
+ // old one is still in its fadeOut cycle, so wait and try again
+ if (session.isTipOpen) {
+ if (!session.isClosing) {
+ hideTip(session.activeHover);
+ }
+ tipElement.delay(100).queue(function queueTipAgain(next) {
+ showTip(element);
+ next();
+ });
+ return;
+ }
+
+ // trigger powerTipPreRender event
+ element.trigger('powerTipPreRender');
+
+ // set tooltip content
+ tipContent = getTooltipContent(element);
+ if (tipContent) {
+ tipElement.empty().append(tipContent);
+ } else {
+ // we have no content to display, give up
+ return;
+ }
+
+ // trigger powerTipRender event
+ element.trigger('powerTipRender');
+
+ session.activeHover = element;
+ session.isTipOpen = true;
+
+ tipElement.data(DATA_MOUSEONTOTIP, options.mouseOnToPopup);
+
+ // set tooltip position
+ if (!options.followMouse) {
+ positionTipOnElement(element);
+ session.isFixedTipOpen = true;
+ } else {
+ positionTipOnCursor();
+ }
+
+ // fadein
+ tipElement.fadeIn(options.fadeInTime, function fadeInCallback() {
+ // start desync polling
+ if (!session.desyncTimeout) {
+ session.desyncTimeout = setInterval(closeDesyncedTip, 500);
+ }
+
+ // trigger powerTipOpen event
+ element.trigger('powerTipOpen');
+ });
+ }
+
+ /**
+ * Hides the tooltip.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ */
+ function hideTip(element) {
+ // reset session
+ session.isClosing = true;
+ session.activeHover = null;
+ session.isTipOpen = false;
+
+ // stop desync polling
+ session.desyncTimeout = clearInterval(session.desyncTimeout);
+
+ // reset element state
+ element.data(DATA_HASACTIVEHOVER, false);
+ element.data(DATA_FORCEDOPEN, false);
+
+ // fade out
+ tipElement.fadeOut(options.fadeOutTime, function fadeOutCallback() {
+ var coords = new CSSCoordinates();
+
+ // reset session and tooltip element
+ session.isClosing = false;
+ session.isFixedTipOpen = false;
+ tipElement.removeClass();
+
+ // support mouse-follow and fixed position tips at the same time by
+ // moving the tooltip to the last cursor location after it is hidden
+ coords.set('top', session.currentY + options.offset);
+ coords.set('left', session.currentX + options.offset);
+ tipElement.css(coords);
+
+ // trigger powerTipClose event
+ element.trigger('powerTipClose');
+ });
+ }
+
+ /**
+ * Moves the tooltip to the users mouse cursor.
+ * @private
+ */
+ function positionTipOnCursor() {
+ // to support having fixed tooltips on the same page as cursor tooltips,
+ // where both instances are referencing the same tooltip element, we
+ // need to keep track of the mouse position constantly, but we should
+ // only set the tip location if a fixed tip is not currently open, a tip
+ // open is imminent or active, and the tooltip element in question does
+ // have a mouse-follow using it.
+ if (!session.isFixedTipOpen && (session.isTipOpen || (session.tipOpenImminent && tipElement.data(DATA_HASMOUSEMOVE)))) {
+ // grab measurements
+ var tipWidth = tipElement.outerWidth(),
+ tipHeight = tipElement.outerHeight(),
+ coords = new CSSCoordinates(),
+ collisions,
+ collisionCount;
+
+ // grab collisions
+ coords.set('top', session.currentY + options.offset);
+ coords.set('left', session.currentX + options.offset);
+ collisions = getViewportCollisions(
+ coords,
+ tipWidth,
+ tipHeight
+ );
+
+ // handle tooltip view port collisions
+ if (collisions !== Collision.none) {
+ collisionCount = countFlags(collisions);
+ if (collisionCount === 1) {
+ // if there is only one collision (bottom or right) then
+ // simply constrain the tooltip to the view port
+ if (collisions === Collision.right) {
+ coords.set('left', session.windowWidth - tipWidth);
+ } else if (collisions === Collision.bottom) {
+ coords.set('top', session.scrollTop + session.windowHeight - tipHeight);
+ }
+ } else {
+ // if the tooltip has more than one collision then it is
+ // trapped in the corner and should be flipped to get it out
+ // of the users way
+ coords.set('left', session.currentX - tipWidth - options.offset);
+ coords.set('top', session.currentY - tipHeight - options.offset);
+ }
+ }
+
+ // position the tooltip
+ tipElement.css(coords);
+ }
+ }
+
+ /**
+ * Sets the tooltip to the correct position relative to the specified target
+ * element. Based on options settings.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ */
+ function positionTipOnElement(element) {
+ var priorityList,
+ finalPlacement;
+
+ if (options.smartPlacement) {
+ priorityList = $.fn.powerTip.smartPlacementLists[options.placement];
+
+ // iterate over the priority list and use the first placement option
+ // that does not collide with the view port. if they all collide
+ // then the last placement in the list will be used.
+ $.each(priorityList, function(idx, pos) {
+ // place tooltip and find collisions
+ var collisions = getViewportCollisions(
+ placeTooltip(element, pos),
+ tipElement.outerWidth(),
+ tipElement.outerHeight()
+ );
+
+ // update the final placement variable
+ finalPlacement = pos;
+
+ // break if there were no collisions
+ if (collisions === Collision.none) {
+ return false;
+ }
+ });
+ } else {
+ // if we're not going to use the smart placement feature then just
+ // compute the coordinates and do it
+ placeTooltip(element, options.placement);
+ finalPlacement = options.placement;
+ }
+
+ // add placement as class for CSS arrows
+ tipElement.addClass(finalPlacement);
+ }
+
+ /**
+ * Sets the tooltip position to the appropriate values to show the tip at
+ * the specified placement. This function will iterate and test the tooltip
+ * to support elastic tooltips.
+ * @private
+ * @param {jQuery} element The element that the tooltip should target.
+ * @param {string} placement The placement for the tooltip.
+ * @return {CSSCoordinates} A CSSCoordinates object with the top, left, and
+ * right position values.
+ */
+ function placeTooltip(element, placement) {
+ var iterationCount = 0,
+ tipWidth,
+ tipHeight,
+ coords = new CSSCoordinates();
+
+ // set the tip to 0,0 to get the full expanded width
+ coords.set('top', 0);
+ coords.set('left', 0);
+ tipElement.css(coords);
+
+ // to support elastic tooltips we need to check for a change in the
+ // rendered dimensions after the tooltip has been positioned
+ do {
+ // grab the current tip dimensions
+ tipWidth = tipElement.outerWidth();
+ tipHeight = tipElement.outerHeight();
+
+ // get placement coordinates
+ coords = placementCalculator.compute(
+ element,
+ placement,
+ tipWidth,
+ tipHeight,
+ options.offset
+ );
+
+ // place the tooltip
+ tipElement.css(coords);
+ } while (
+ // sanity check: limit to 5 iterations, and...
+ ++iterationCount <= 5 &&
+ // try again if the dimensions changed after placement
+ (tipWidth !== tipElement.outerWidth() || tipHeight !== tipElement.outerHeight())
+ );
+
+ return coords;
+ }
+
+ /**
+ * Checks for a tooltip desync and closes the tooltip if one occurs.
+ * @private
+ */
+ function closeDesyncedTip() {
+ var isDesynced = false;
+ // It is possible for the mouse cursor to leave an element without
+ // firing the mouseleave or blur event. This most commonly happens when
+ // the element is disabled under mouse cursor. If this happens it will
+ // result in a desynced tooltip because the tooltip was never asked to
+ // close. So we should periodically check for a desync situation and
+ // close the tip if such a situation arises.
+ if (session.isTipOpen && !session.isClosing && !session.delayInProgress) {
+ // user moused onto another tip or active hover is disabled
+ if (session.activeHover.data(DATA_HASACTIVEHOVER) === false || session.activeHover.is(':disabled')) {
+ isDesynced = true;
+ } else {
+ // hanging tip - have to test if mouse position is not over the
+ // active hover and not over a tooltip set to let the user
+ // interact with it.
+ // for keyboard navigation: this only counts if the element does
+ // not have focus.
+ // for tooltips opened via the api: we need to check if it has
+ // the forcedOpen flag.
+ if (!isMouseOver(session.activeHover) && !session.activeHover.is(':focus') && !session.activeHover.data(DATA_FORCEDOPEN)) {
+ if (tipElement.data(DATA_MOUSEONTOTIP)) {
+ if (!isMouseOver(tipElement)) {
+ isDesynced = true;
+ }
+ } else {
+ isDesynced = true;
+ }
+ }
+ }
+
+ if (isDesynced) {
+ // close the desynced tip
+ hideTip(session.activeHover);
+ }
+ }
+ }
+
+ // expose methods
+ this.showTip = beginShowTip;
+ this.hideTip = hideTip;
+ this.resetPosition = positionTipOnElement;
+ }
+
+ /**
+ * Determine whether a jQuery object is an SVG element
+ * @private
+ * @param {jQuery} element The element to check
+ * @return {boolean} Whether this is an SVG element
+ */
+ function isSvgElement(element) {
+ return window.SVGElement && element[0] instanceof SVGElement;
+ }
+
+ /**
+ * Initializes the viewport dimension cache and hooks up the mouse position
+ * tracking and viewport dimension tracking events.
+ * Prevents attaching the events more than once.
+ * @private
+ */
+ function initTracking() {
+ if (!session.mouseTrackingActive) {
+ session.mouseTrackingActive = true;
+
+ // grab the current viewport dimensions on load
+ $(function getViewportDimensions() {
+ session.scrollLeft = $window.scrollLeft();
+ session.scrollTop = $window.scrollTop();
+ session.windowWidth = $window.width();
+ session.windowHeight = $window.height();
+ });
+
+ // hook mouse move tracking
+ $document.on('mousemove', trackMouse);
+
+ // hook viewport dimensions tracking
+ $window.on({
+ resize: function trackResize() {
+ session.windowWidth = $window.width();
+ session.windowHeight = $window.height();
+ },
+ scroll: function trackScroll() {
+ var x = $window.scrollLeft(),
+ y = $window.scrollTop();
+ if (x !== session.scrollLeft) {
+ session.currentX += x - session.scrollLeft;
+ session.scrollLeft = x;
+ }
+ if (y !== session.scrollTop) {
+ session.currentY += y - session.scrollTop;
+ session.scrollTop = y;
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Saves the current mouse coordinates to the session object.
+ * @private
+ * @param {jQuery.Event} event The mousemove event for the document.
+ */
+ function trackMouse(event) {
+ session.currentX = event.pageX;
+ session.currentY = event.pageY;
+ }
+
+ /**
+ * Tests if the mouse is currently over the specified element.
+ * @private
+ * @param {jQuery} element The element to check for hover.
+ * @return {boolean}
+ */
+ function isMouseOver(element) {
+ // use getBoundingClientRect() because jQuery's width() and height()
+ // methods do not work with SVG elements
+ // compute width/height because those properties do not exist on the object
+ // returned by getBoundingClientRect() in older versions of IE
+ var elementPosition = element.offset(),
+ elementBox = element[0].getBoundingClientRect(),
+ elementWidth = elementBox.right - elementBox.left,
+ elementHeight = elementBox.bottom - elementBox.top;
+
+ return session.currentX >= elementPosition.left &&
+ session.currentX <= elementPosition.left + elementWidth &&
+ session.currentY >= elementPosition.top &&
+ session.currentY <= elementPosition.top + elementHeight;
+ }
+
+ /**
+ * Fetches the tooltip content from the specified element's data attributes.
+ * @private
+ * @param {jQuery} element The element to get the tooltip content for.
+ * @return {(string|jQuery|undefined)} The text/HTML string, jQuery object, or
+ * undefined if there was no tooltip content for the element.
+ */
+ function getTooltipContent(element) {
+ var tipText = element.data(DATA_POWERTIP),
+ tipObject = element.data(DATA_POWERTIPJQ),
+ tipTarget = element.data(DATA_POWERTIPTARGET),
+ targetElement,
+ content;
+
+ if (tipText) {
+ if ($.isFunction(tipText)) {
+ tipText = tipText.call(element[0]);
+ }
+ content = tipText;
+ } else if (tipObject) {
+ if ($.isFunction(tipObject)) {
+ tipObject = tipObject.call(element[0]);
+ }
+ if (tipObject.length > 0) {
+ content = tipObject.clone(true, true);
+ }
+ } else if (tipTarget) {
+ targetElement = $('#' + tipTarget);
+ if (targetElement.length > 0) {
+ content = targetElement.html();
+ }
+ }
+
+ return content;
+ }
+
+ /**
+ * Finds any viewport collisions that an element (the tooltip) would have if it
+ * were absolutely positioned at the specified coordinates.
+ * @private
+ * @param {CSSCoordinates} coords Coordinates for the element.
+ * @param {number} elementWidth Width of the element in pixels.
+ * @param {number} elementHeight Height of the element in pixels.
+ * @return {number} Value with the collision flags.
+ */
+ function getViewportCollisions(coords, elementWidth, elementHeight) {
+ var viewportTop = session.scrollTop,
+ viewportLeft = session.scrollLeft,
+ viewportBottom = viewportTop + session.windowHeight,
+ viewportRight = viewportLeft + session.windowWidth,
+ collisions = Collision.none;
+
+ if (coords.top < viewportTop || Math.abs(coords.bottom - session.windowHeight) - elementHeight < viewportTop) {
+ collisions |= Collision.top;
+ }
+ if (coords.top + elementHeight > viewportBottom || Math.abs(coords.bottom - session.windowHeight) > viewportBottom) {
+ collisions |= Collision.bottom;
+ }
+ if (coords.left < viewportLeft || coords.right + elementWidth > viewportRight) {
+ collisions |= Collision.left;
+ }
+ if (coords.left + elementWidth > viewportRight || coords.right < viewportLeft) {
+ collisions |= Collision.right;
+ }
+
+ return collisions;
+ }
+
+ /**
+ * Counts the number of bits set on a flags value.
+ * @param {number} value The flags value.
+ * @return {number} The number of bits that have been set.
+ */
+ function countFlags(value) {
+ var count = 0;
+ while (value) {
+ value &= value - 1;
+ count++;
+ }
+ return count;
+ }
+
+}));
diff --git a/jquery/jquery.scrollTo-1.4.2.js b/jquery/jquery.scrollTo-1.4.2.js
new file mode 100644
index 0000000..eec31e1
--- /dev/null
+++ b/jquery/jquery.scrollTo-1.4.2.js
@@ -0,0 +1,215 @@
+/**
+ * jQuery.ScrollTo
+ * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
+ * Dual licensed under MIT and GPL.
+ * Date: 5/25/2009
+ *
+ * @projectDescription Easy element scrolling using jQuery.
+ * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
+ * Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
+ *
+ * @author Ariel Flesler
+ * @version 1.4.2
+ *
+ * @id jQuery.scrollTo
+ * @id jQuery.fn.scrollTo
+ * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
+ * The different options for target are:
+ * - A number position (will be applied to all axes).
+ * - A string position ('44', '100px', '+=90', etc ) will be applied to all axes
+ * - A jQuery/DOM element ( logically, child of the element to scroll )
+ * - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
+ * - A hash { top:x, left:y }, x and y can be any kind of number/string like above.
+* - A percentage of the container's dimension/s, for example: 50% to go to the middle.
+ * - The string 'max' for go-to-end.
+ * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
+ * @param {Object,Function} settings Optional set of settings or the onAfter callback.
+ * @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
+ * @option {Number} duration The OVERALL length of the animation.
+ * @option {String} easing The easing method for the animation.
+ * @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
+ * @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
+ * @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
+ * @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
+ * @option {Function} onAfter Function to be called after the scrolling ends.
+ * @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
+ * @return {jQuery} Returns the same jQuery object, for chaining.
+ *
+ * @desc Scroll to a fixed position
+ * @example $('div').scrollTo( 340 );
+ *
+ * @desc Scroll relatively to the actual position
+ * @example $('div').scrollTo( '+=340px', { axis:'y' } );
+ *
+ * @dec Scroll using a selector (relative to the scrolled element)
+ * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
+ *
+ * @ Scroll to a DOM element (same for jQuery object)
+ * @example var second_child = document.getElementById('container').firstChild.nextSibling;
+ * $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
+ * alert('scrolled!!');
+ * }});
+ *
+ * @desc Scroll on both axes, to different values
+ * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
+ */
+;(function( $ ){
+
+ var $scrollTo = $.scrollTo = function( target, duration, settings ){
+ $(window).scrollTo( target, duration, settings );
+ };
+
+ $scrollTo.defaults = {
+ axis:'xy',
+ duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1
+ };
+
+ // Returns the element that needs to be animated to scroll the window.
+ // Kept for backwards compatibility (specially for localScroll & serialScroll)
+ $scrollTo.window = function( scope ){
+ return $(window)._scrollable();
+ };
+
+ // Hack, hack, hack :)
+ // Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
+ $.fn._scrollable = function(){
+ return this.map(function(){
+ var elem = this,
+ isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;
+
+ if( !isWin )
+ return elem;
+
+ var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;
+
+ return $.browser.safari || doc.compatMode == 'BackCompat' ?
+ doc.body :
+ doc.documentElement;
+ });
+ };
+
+ $.fn.scrollTo = function( target, duration, settings ){
+ if( typeof duration == 'object' ){
+ settings = duration;
+ duration = 0;
+ }
+ if( typeof settings == 'function' )
+ settings = { onAfter:settings };
+
+ if( target == 'max' )
+ target = 9e9;
+
+ settings = $.extend( {}, $scrollTo.defaults, settings );
+ // Speed is still recognized for backwards compatibility
+ duration = duration || settings.speed || settings.duration;
+ // Make sure the settings are given right
+ settings.queue = settings.queue && settings.axis.length > 1;
+
+ if( settings.queue )
+ // Let's keep the overall duration
+ duration /= 2;
+ settings.offset = both( settings.offset );
+ settings.over = both( settings.over );
+
+ return this._scrollable().each(function(){
+ var elem = this,
+ $elem = $(elem),
+ targ = target, toff, attr = {},
+ win = $elem.is('html,body');
+
+ switch( typeof targ ){
+ // A number will pass the regex
+ case 'number':
+ case 'string':
+ if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){
+ targ = both( targ );
+ // We are done
+ break;
+ }
+ // Relative selector, no break!
+ targ = $(targ,this);
+ case 'object':
+ // DOMElement / jQuery
+ if( targ.is || targ.style )
+ // Get the real position of the target
+ toff = (targ = $(targ)).offset();
+ }
+ $.each( settings.axis.split(''), function( i, axis ){
+ var Pos = axis == 'x' ? 'Left' : 'Top',
+ pos = Pos.toLowerCase(),
+ key = 'scroll' + Pos,
+ old = elem[key],
+ max = $scrollTo.max(elem, axis);
+
+ if( toff ){// jQuery / DOMElement
+ attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );
+
+ // If it's a dom element, reduce the margin
+ if( settings.margin ){
+ attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
+ attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
+ }
+
+ attr[key] += settings.offset[pos] || 0;
+
+ if( settings.over[pos] )
+ // Scroll to a fraction of its width/height
+ attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos];
+ }else{
+ var val = targ[pos];
+ // Handle percentage values
+ attr[key] = val.slice && val.slice(-1) == '%' ?
+ parseFloat(val) / 100 * max
+ : val;
+ }
+
+ // Number or 'number'
+ if( /^\d+$/.test(attr[key]) )
+ // Check the limits
+ attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max );
+
+ // Queueing axes
+ if( !i && settings.queue ){
+ // Don't waste time animating, if there's no need.
+ if( old != attr[key] )
+ // Intermediate animation
+ animate( settings.onAfterFirst );
+ // Don't animate this axis again in the next iteration.
+ delete attr[key];
+ }
+ });
+
+ animate( settings.onAfter );
+
+ function animate( callback ){
+ $elem.animate( attr, duration, settings.easing, callback && function(){
+ callback.call(this, target, settings);
+ });
+ };
+
+ }).end();
+ };
+
+ // Max scrolling position, works on quirks mode
+ // It only fails (not too badly) on IE, quirks mode.
+ $scrollTo.max = function( elem, axis ){
+ var Dim = axis == 'x' ? 'Width' : 'Height',
+ scroll = 'scroll'+Dim;
+
+ if( !$(elem).is('html,body') )
+ return elem[scroll] - $(elem)[Dim.toLowerCase()]();
+
+ var size = 'client' + Dim,
+ html = elem.ownerDocument.documentElement,
+ body = elem.ownerDocument.body;
+
+ return Math.max( html[scroll], body[scroll] )
+ - Math.min( html[size] , body[size] );
+
+ };
+
+ function both( val ){
+ return typeof val == 'object' ? val : { top:val, left:val };
+ };
+
+})( jQuery );
\ No newline at end of file
diff --git a/jquery/jquery.ui-1.8.18.core.js b/jquery/jquery.ui-1.8.18.core.js
new file mode 100644
index 0000000..98b4f9b
--- /dev/null
+++ b/jquery/jquery.ui-1.8.18.core.js
@@ -0,0 +1,319 @@
+/*!
+ * jQuery UI 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function( $, undefined ) {
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+ return;
+}
+
+$.extend( $.ui, {
+ version: "1.8.18",
+
+ keyCode: {
+ ALT: 18,
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ COMMAND: 91,
+ COMMAND_LEFT: 91, // COMMAND
+ COMMAND_RIGHT: 93,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ MENU: 93, // COMMAND_RIGHT
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38,
+ WINDOWS: 91 // COMMAND
+ }
+});
+
+// plugins
+$.fn.extend({
+ propAttr: $.fn.prop || $.fn.attr,
+
+ _focus: $.fn.focus,
+ focus: function( delay, fn ) {
+ return typeof delay === "number" ?
+ this.each(function() {
+ var elem = this;
+ setTimeout(function() {
+ $( elem ).focus();
+ if ( fn ) {
+ fn.call( elem );
+ }
+ }, delay );
+ }) :
+ this._focus.apply( this, arguments );
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ },
+
+ zIndex: function( zIndex ) {
+ if ( zIndex !== undefined ) {
+ return this.css( "zIndex", zIndex );
+ }
+
+ if ( this.length ) {
+ var elem = $( this[ 0 ] ), position, value;
+ while ( elem.length && elem[ 0 ] !== document ) {
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
+ // This makes behavior of this function consistent across browsers
+ // WebKit always returns auto if the element is positioned
+ position = elem.css( "position" );
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+ // IE returns 0 when zIndex is not specified
+ // other browsers return a string
+ // we ignore the case of nested elements with an explicit value of 0
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+ value = parseInt( elem.css( "zIndex" ), 10 );
+ if ( !isNaN( value ) && value !== 0 ) {
+ return value;
+ }
+ }
+ elem = elem.parent();
+ }
+ }
+
+ return 0;
+ },
+
+ disableSelection: function() {
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+ ".ui-disableSelection", function( event ) {
+ event.preventDefault();
+ });
+ },
+
+ enableSelection: function() {
+ return this.unbind( ".ui-disableSelection" );
+ }
+});
+
+$.each( [ "Width", "Height" ], function( i, name ) {
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+ type = name.toLowerCase(),
+ orig = {
+ innerWidth: $.fn.innerWidth,
+ innerHeight: $.fn.innerHeight,
+ outerWidth: $.fn.outerWidth,
+ outerHeight: $.fn.outerHeight
+ };
+
+ function reduce( elem, size, border, margin ) {
+ $.each( side, function() {
+ size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
+ if ( border ) {
+ size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
+ }
+ if ( margin ) {
+ size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
+ }
+ });
+ return size;
+ }
+
+ $.fn[ "inner" + name ] = function( size ) {
+ if ( size === undefined ) {
+ return orig[ "inner" + name ].call( this );
+ }
+
+ return this.each(function() {
+ $( this ).css( type, reduce( this, size ) + "px" );
+ });
+ };
+
+ $.fn[ "outer" + name] = function( size, margin ) {
+ if ( typeof size !== "number" ) {
+ return orig[ "outer" + name ].call( this, size );
+ }
+
+ return this.each(function() {
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
+ });
+ };
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+ var nodeName = element.nodeName.toLowerCase();
+ if ( "area" === nodeName ) {
+ var map = element.parentNode,
+ mapName = map.name,
+ img;
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+ return false;
+ }
+ img = $( "img[usemap=#" + mapName + "]" )[0];
+ return !!img && visible( img );
+ }
+ return ( /input|select|textarea|button|object/.test( nodeName )
+ ? !element.disabled
+ : "a" == nodeName
+ ? element.href || isTabIndexNotNaN
+ : isTabIndexNotNaN)
+ // the element and all of its ancestors must be visible
+ && visible( element );
+}
+
+function visible( element ) {
+ return !$( element ).parents().andSelf().filter(function() {
+ return $.curCSS( this, "visibility" ) === "hidden" ||
+ $.expr.filters.hidden( this );
+ }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+ data: function( elem, i, match ) {
+ return !!$.data( elem, match[ 3 ] );
+ },
+
+ focusable: function( element ) {
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+ },
+
+ tabbable: function( element ) {
+ var tabIndex = $.attr( element, "tabindex" ),
+ isTabIndexNaN = isNaN( tabIndex );
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+ }
+});
+
+// support
+$(function() {
+ var body = document.body,
+ div = body.appendChild( div = document.createElement( "div" ) );
+
+ // access offsetHeight before setting the style to prevent a layout bug
+ // in IE 9 which causes the elemnt to continue to take up space even
+ // after it is removed from the DOM (#8026)
+ div.offsetHeight;
+
+ $.extend( div.style, {
+ minHeight: "100px",
+ height: "auto",
+ padding: 0,
+ borderWidth: 0
+ });
+
+ $.support.minHeight = div.offsetHeight === 100;
+ $.support.selectstart = "onselectstart" in div;
+
+ // set display to none to avoid a layout bug in IE
+ // http://dev.jquery.com/ticket/4014
+ body.removeChild( div ).style.display = "none";
+});
+
+
+
+
+
+// deprecated
+$.extend( $.ui, {
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function( module, option, set ) {
+ var proto = $.ui[ module ].prototype;
+ for ( var i in set ) {
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
+ }
+ },
+ call: function( instance, name, args ) {
+ var set = instance.plugins[ name ];
+ if ( !set || !instance.element[ 0 ].parentNode ) {
+ return;
+ }
+
+ for ( var i = 0; i < set.length; i++ ) {
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
+ set[ i ][ 1 ].apply( instance.element, args );
+ }
+ }
+ }
+ },
+
+ // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
+ contains: function( a, b ) {
+ return document.compareDocumentPosition ?
+ a.compareDocumentPosition( b ) & 16 :
+ a !== b && a.contains( b );
+ },
+
+ // only used by resizable
+ hasScroll: function( el, a ) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ( $( el ).css( "overflow" ) === "hidden") {
+ return false;
+ }
+
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+ has = false;
+
+ if ( el[ scroll ] > 0 ) {
+ return true;
+ }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[ scroll ] = 1;
+ has = ( el[ scroll ] > 0 );
+ el[ scroll ] = 0;
+ return has;
+ },
+
+ // these are odd functions, fix the API or move into individual plugins
+ isOverAxis: function( x, reference, size ) {
+ //Determines when x coordinate is over "b" element axis
+ return ( x > reference ) && ( x < ( reference + size ) );
+ },
+ isOver: function( y, x, top, left, height, width ) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
+ }
+});
+
+})( jQuery );
diff --git a/jquery/jquery.ui-1.8.18.mouse.js b/jquery/jquery.ui-1.8.18.mouse.js
new file mode 100644
index 0000000..669d563
--- /dev/null
+++ b/jquery/jquery.ui-1.8.18.mouse.js
@@ -0,0 +1,162 @@
+/*!
+ * jQuery UI Mouse 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var mouseHandled = false;
+$( document ).mouseup( function( e ) {
+ mouseHandled = false;
+});
+
+$.widget("ui.mouse", {
+ options: {
+ cancel: ':input,option',
+ distance: 1,
+ delay: 0
+ },
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, self.widgetName + '.preventClickEvent');
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ if( mouseHandled ) { return };
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ // event.target.nodeName works around a bug in IE 8 with
+ // disabled inputs (#7620)
+ elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // Click event may never have fired (Gecko & Opera)
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ event.preventDefault();
+
+ mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+
+ if (event.target == this._mouseDownEvent.target) {
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
+ }
+
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+});
+
+})(jQuery);
diff --git a/jquery/jquery.ui-1.8.18.resizable.js b/jquery/jquery.ui-1.8.18.resizable.js
new file mode 100644
index 0000000..b441435
--- /dev/null
+++ b/jquery/jquery.ui-1.8.18.resizable.js
@@ -0,0 +1,808 @@
+/*
+ * jQuery UI Resizable 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.resizable", $.ui.mouse, {
+ widgetEventPrefix: "resize",
+ options: {
+ alsoResize: false,
+ animate: false,
+ animateDuration: "slow",
+ animateEasing: "swing",
+ aspectRatio: false,
+ autoHide: false,
+ containment: false,
+ ghost: false,
+ grid: false,
+ handles: "e,s,se",
+ helper: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var self = this, o = this.options;
+ this.element.addClass("ui-resizable");
+
+ $.extend(this, {
+ _aspectRatio: !!(o.aspectRatio),
+ aspectRatio: o.aspectRatio,
+ originalElement: this.element,
+ _proportionallyResizeElements: [],
+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+ });
+
+ //Wrap the element if it cannot hold child nodes
+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+ //Create a wrapper element and set the wrapper to the new current internal element
+ this.element.wrap(
+ $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+ position: this.element.css('position'),
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight(),
+ top: this.element.css('top'),
+ left: this.element.css('left')
+ })
+ );
+
+ //Overwrite the original this.element
+ this.element = this.element.parent().data(
+ "resizable", this.element.data('resizable')
+ );
+
+ this.elementIsWrapper = true;
+
+ //Move margins to the wrapper
+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+ //Prevent Safari textarea resize
+ this.originalResizeStyle = this.originalElement.css('resize');
+ this.originalElement.css('resize', 'none');
+
+ //Push the actual element to our proportionallyResize internal array
+ this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+ // avoid IE jump (hard set the margin)
+ this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+ // fix handlers offset
+ this._proportionallyResize();
+
+ }
+
+ this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
+ if(this.handles.constructor == String) {
+
+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+ var n = this.handles.split(","); this.handles = {};
+
+ for(var i = 0; i < n.length; i++) {
+
+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+ // increase zIndex of sw, se, ne, nw axis
+ //TODO : this modifies original option
+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+ //TODO : What's going on here?
+ if ('se' == handle) {
+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+ };
+
+ //Insert into internal handles object and append to element
+ this.handles[handle] = '.ui-resizable-'+handle;
+ this.element.append(axis);
+ }
+
+ }
+
+ this._renderAxis = function(target) {
+
+ target = target || this.element;
+
+ for(var i in this.handles) {
+
+ if(this.handles[i].constructor == String)
+ this.handles[i] = $(this.handles[i], this.element).show();
+
+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+ var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+ //Checking the correct pad and border
+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+ //The padding type i have to apply...
+ var padPos = [ 'padding',
+ /ne|nw|n/.test(i) ? 'Top' :
+ /se|sw|s/.test(i) ? 'Bottom' :
+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+ target.css(padPos, padWrapper);
+
+ this._proportionallyResize();
+
+ }
+
+ //TODO: What's that good for? There's not anything to be executed left
+ if(!$(this.handles[i]).length)
+ continue;
+
+ }
+ };
+
+ //TODO: make renderAxis a prototype function
+ this._renderAxis(this.element);
+
+ this._handles = $('.ui-resizable-handle', this.element)
+ .disableSelection();
+
+ //Matching axis name
+ this._handles.mouseover(function() {
+ if (!self.resizing) {
+ if (this.className)
+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+ //Axis, default = se
+ self.axis = axis && axis[1] ? axis[1] : 'se';
+ }
+ });
+
+ //If we want to auto hide the elements
+ if (o.autoHide) {
+ this._handles.hide();
+ $(this.element)
+ .addClass("ui-resizable-autohide")
+ .hover(function() {
+ if (o.disabled) return;
+ $(this).removeClass("ui-resizable-autohide");
+ self._handles.show();
+ },
+ function(){
+ if (o.disabled) return;
+ if (!self.resizing) {
+ $(this).addClass("ui-resizable-autohide");
+ self._handles.hide();
+ }
+ });
+ }
+
+ //Initialize the mouse interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+
+ this._mouseDestroy();
+
+ var _destroy = function(exp) {
+ $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+ };
+
+ //TODO: Unwrap at same DOM position
+ if (this.elementIsWrapper) {
+ _destroy(this.element);
+ var wrapper = this.element;
+ wrapper.after(
+ this.originalElement.css({
+ position: wrapper.css('position'),
+ width: wrapper.outerWidth(),
+ height: wrapper.outerHeight(),
+ top: wrapper.css('top'),
+ left: wrapper.css('left')
+ })
+ ).remove();
+ }
+
+ this.originalElement.css('resize', this.originalResizeStyle);
+ _destroy(this.originalElement);
+
+ return this;
+ },
+
+ _mouseCapture: function(event) {
+ var handle = false;
+ for (var i in this.handles) {
+ if ($(this.handles[i])[0] == event.target) {
+ handle = true;
+ }
+ }
+
+ return !this.options.disabled && handle;
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options, iniPos = this.element.position(), el = this.element;
+
+ this.resizing = true;
+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+ // bugfix for http://dev.jquery.com/ticket/1749
+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+ }
+
+ this._renderProxy();
+
+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+ if (o.containment) {
+ curleft += $(o.containment).scrollLeft() || 0;
+ curtop += $(o.containment).scrollTop() || 0;
+ }
+
+ //Store needed variables
+ this.offset = this.helper.offset();
+ this.position = { left: curleft, top: curtop };
+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalPosition = { left: curleft, top: curtop };
+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+ //Aspect Ratio
+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+ el.addClass("ui-resizable-resizing");
+ this._propagate("start", event);
+ return true;
+ },
+
+ _mouseDrag: function(event) {
+
+ //Increase performance, avoid regex
+ var el = this.helper, o = this.options, props = {},
+ self = this, smp = this.originalMousePosition, a = this.axis;
+
+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+ var trigger = this._change[a];
+ if (!trigger) return false;
+
+ // Calculate the attrs that will be change
+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+ // Put this in the mouseDrag handler since the user can start pressing shift while resizing
+ this._updateVirtualBoundaries(event.shiftKey);
+ if (this._aspectRatio || event.shiftKey)
+ data = this._updateRatio(data, event);
+
+ data = this._respectSize(data, event);
+
+ // plugins callbacks need to be called first
+ this._propagate("resize", event);
+
+ el.css({
+ top: this.position.top + "px", left: this.position.left + "px",
+ width: this.size.width + "px", height: this.size.height + "px"
+ });
+
+ if (!this._helper && this._proportionallyResizeElements.length)
+ this._proportionallyResize();
+
+ this._updateCache(data);
+
+ // calling the user callback at the end
+ this._trigger('resize', event, this.ui());
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ this.resizing = false;
+ var o = this.options, self = this;
+
+ if(this._helper) {
+ var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ if (!o.animate)
+ this.element.css($.extend(s, { top: top, left: left }));
+
+ self.helper.height(self.size.height);
+ self.helper.width(self.size.width);
+
+ if (this._helper && !o.animate) this._proportionallyResize();
+ }
+
+ $('body').css('cursor', 'auto');
+
+ this.element.removeClass("ui-resizable-resizing");
+
+ this._propagate("stop", event);
+
+ if (this._helper) this.helper.remove();
+ return false;
+
+ },
+
+ _updateVirtualBoundaries: function(forceAspectRatio) {
+ var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
+
+ b = {
+ minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
+ maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+ minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
+ maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
+ };
+
+ if(this._aspectRatio || forceAspectRatio) {
+ // We want to create an enclosing box whose aspect ration is the requested one
+ // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
+ pMinWidth = b.minHeight * this.aspectRatio;
+ pMinHeight = b.minWidth / this.aspectRatio;
+ pMaxWidth = b.maxHeight * this.aspectRatio;
+ pMaxHeight = b.maxWidth / this.aspectRatio;
+
+ if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
+ if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
+ if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
+ if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
+ }
+ this._vBoundaries = b;
+ },
+
+ _updateCache: function(data) {
+ var o = this.options;
+ this.offset = this.helper.offset();
+ if (isNumber(data.left)) this.position.left = data.left;
+ if (isNumber(data.top)) this.position.top = data.top;
+ if (isNumber(data.height)) this.size.height = data.height;
+ if (isNumber(data.width)) this.size.width = data.width;
+ },
+
+ _updateRatio: function(data, event) {
+
+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+ if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
+ else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
+
+ if (a == 'sw') {
+ data.left = cpos.left + (csize.width - data.width);
+ data.top = null;
+ }
+ if (a == 'nw') {
+ data.top = cpos.top + (csize.height - data.height);
+ data.left = cpos.left + (csize.width - data.width);
+ }
+
+ return data;
+ },
+
+ _respectSize: function(data, event) {
+
+ var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+ if (isminw) data.width = o.minWidth;
+ if (isminh) data.height = o.minHeight;
+ if (ismaxw) data.width = o.maxWidth;
+ if (ismaxh) data.height = o.maxHeight;
+
+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+ if (isminw && cw) data.left = dw - o.minWidth;
+ if (ismaxw && cw) data.left = dw - o.maxWidth;
+ if (isminh && ch) data.top = dh - o.minHeight;
+ if (ismaxh && ch) data.top = dh - o.maxHeight;
+
+ // fixing jump error on top/left - bug #2330
+ var isNotwh = !data.width && !data.height;
+ if (isNotwh && !data.left && data.top) data.top = null;
+ else if (isNotwh && !data.top && data.left) data.left = null;
+
+ return data;
+ },
+
+ _proportionallyResize: function() {
+
+ var o = this.options;
+ if (!this._proportionallyResizeElements.length) return;
+ var element = this.helper || this.element;
+
+ for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+ var prel = this._proportionallyResizeElements[i];
+
+ if (!this.borderDif) {
+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+ this.borderDif = $.map(b, function(v, i) {
+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+ return border + padding;
+ });
+ }
+
+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+ continue;
+
+ prel.css({
+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+ });
+
+ };
+
+ },
+
+ _renderProxy: function() {
+
+ var el = this.element, o = this.options;
+ this.elementOffset = el.offset();
+
+ if(this._helper) {
+
+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+ // fix ie6 offset TODO: This seems broken
+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+ pxyoffset = ( ie6 ? 2 : -1 );
+
+ this.helper.addClass(this._helper).css({
+ width: this.element.outerWidth() + pxyoffset,
+ height: this.element.outerHeight() + pxyoffset,
+ position: 'absolute',
+ left: this.elementOffset.left - ie6offset +'px',
+ top: this.elementOffset.top - ie6offset +'px',
+ zIndex: ++o.zIndex //TODO: Don't modify option
+ });
+
+ this.helper
+ .appendTo("body")
+ .disableSelection();
+
+ } else {
+ this.helper = this.element;
+ }
+
+ },
+
+ _change: {
+ e: function(event, dx, dy) {
+ return { width: this.originalSize.width + dx };
+ },
+ w: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { left: sp.left + dx, width: cs.width - dx };
+ },
+ n: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { top: sp.top + dy, height: cs.height - dy };
+ },
+ s: function(event, dx, dy) {
+ return { height: this.originalSize.height + dy };
+ },
+ se: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ sw: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ },
+ ne: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ nw: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ }
+ },
+
+ _propagate: function(n, event) {
+ $.ui.plugin.call(this, n, [event, this.ui()]);
+ (n != "resize" && this._trigger(n, event, this.ui()));
+ },
+
+ plugins: {},
+
+ ui: function() {
+ return {
+ originalElement: this.originalElement,
+ element: this.element,
+ helper: this.helper,
+ position: this.position,
+ size: this.size,
+ originalSize: this.originalSize,
+ originalPosition: this.originalPosition
+ };
+ }
+
+});
+
+$.extend($.ui.resizable, {
+ version: "1.8.18"
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+ start: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var _store = function (exp) {
+ $(exp).each(function() {
+ var el = $(this);
+ el.data("resizable-alsoresize", {
+ width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+ left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
+ });
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+ else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
+ }else{
+ _store(o.alsoResize);
+ }
+ },
+
+ resize: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+ var delta = {
+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+ },
+
+ _alsoResize = function (exp, c) {
+ $(exp).each(function() {
+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
+ css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
+
+ $.each(css, function (i, prop) {
+ var sum = (start[prop]||0) + (delta[prop]||0);
+ if (sum && sum >= 0)
+ style[prop] = sum || null;
+ });
+
+ el.css(style);
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
+ }else{
+ _alsoResize(o.alsoResize);
+ }
+ },
+
+ stop: function (event, ui) {
+ $(this).removeData("resizable-alsoresize");
+ }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+ stop: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ self.element.animate(
+ $.extend(style, top && left ? { top: top, left: left } : {}), {
+ duration: o.animateDuration,
+ easing: o.animateEasing,
+ step: function() {
+
+ var data = {
+ width: parseInt(self.element.css('width'), 10),
+ height: parseInt(self.element.css('height'), 10),
+ top: parseInt(self.element.css('top'), 10),
+ left: parseInt(self.element.css('left'), 10)
+ };
+
+ if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+ // propagating resize, and updating values for each animation step
+ self._updateCache(data);
+ self._propagate("resize", event);
+
+ }
+ }
+ );
+ }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+ start: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, el = self.element;
+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+ if (!ce) return;
+
+ self.containerElement = $(ce);
+
+ if (/document/.test(oc) || oc == document) {
+ self.containerOffset = { left: 0, top: 0 };
+ self.containerPosition = { left: 0, top: 0 };
+
+ self.parentData = {
+ element: $(document), left: 0, top: 0,
+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+ };
+ }
+
+ // i'm a node, so compute top, left, right, bottom
+ else {
+ var element = $(ce), p = [];
+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+ self.containerOffset = element.offset();
+ self.containerPosition = element.position();
+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+ self.parentData = {
+ element: ce, left: co.left, top: co.top, width: width, height: height
+ };
+ }
+ },
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options,
+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+ pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+ if (cp.left < (self._helper ? co.left : 0)) {
+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ self.position.left = o.helper ? co.left : 0;
+ }
+
+ if (cp.top < (self._helper ? co.top : 0)) {
+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ self.position.top = self._helper ? co.top : 0;
+ }
+
+ self.offset.left = self.parentData.left+self.position.left;
+ self.offset.top = self.parentData.top+self.position.top;
+
+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+ var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+ isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+ if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+ if (woset + self.size.width >= self.parentData.width) {
+ self.size.width = self.parentData.width - woset;
+ if (pRatio) self.size.height = self.size.width / self.aspectRatio;
+ }
+
+ if (hoset + self.size.height >= self.parentData.height) {
+ self.size.height = self.parentData.height - hoset;
+ if (pRatio) self.size.width = self.size.height * self.aspectRatio;
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+ self.ghost = self.originalElement.clone();
+ self.ghost
+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .addClass('ui-resizable-ghost')
+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+ self.ghost.appendTo(self.helper);
+
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+ }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+ if (/^(se|s|e)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ }
+ else if (/^(ne)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ }
+ else if (/^(sw)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.left = op.left - ox;
+ }
+ else {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ self.position.left = op.left - ox;
+ }
+ }
+
+});
+
+var num = function(v) {
+ return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+ return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
diff --git a/jquery/jquery.ui-1.8.18.widget.js b/jquery/jquery.ui-1.8.18.widget.js
new file mode 100644
index 0000000..0c6f53f
--- /dev/null
+++ b/jquery/jquery.ui-1.8.18.widget.js
@@ -0,0 +1,272 @@
+/*!
+ * jQuery UI Widget 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function( $, undefined ) {
+
+// jQuery 1.4+
+if ( $.cleanData ) {
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ _cleanData( elems );
+ };
+} else {
+ var _remove = $.fn.remove;
+ $.fn.remove = function( selector, keepData ) {
+ return this.each(function() {
+ if ( !keepData ) {
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
+ $( "*", this ).add( [ this ] ).each(function() {
+ try {
+ $( this ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ });
+ }
+ }
+ return _remove.call( $(this), selector, keepData );
+ });
+ };
+}
+
+$.widget = function( name, base, prototype ) {
+ var namespace = name.split( "." )[ 0 ],
+ fullName;
+ name = name.split( "." )[ 1 ];
+ fullName = namespace + "-" + name;
+
+ if ( !prototype ) {
+ prototype = base;
+ base = $.Widget;
+ }
+
+ // create selector for plugin
+ $.expr[ ":" ][ fullName ] = function( elem ) {
+ return !!$.data( elem, name );
+ };
+
+ $[ namespace ] = $[ namespace ] || {};
+ $[ namespace ][ name ] = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+ };
+
+ var basePrototype = new base();
+ // we need to make the options hash a property directly on the new instance
+ // otherwise we'll modify the options hash on the prototype that we're
+ // inheriting from
+// $.each( basePrototype, function( key, val ) {
+// if ( $.isPlainObject(val) ) {
+// basePrototype[ key ] = $.extend( {}, val );
+// }
+// });
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+ namespace: namespace,
+ widgetName: name,
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
+ widgetBaseClass: fullName
+ }, prototype );
+
+ $.widget.bridge( name, $[ namespace ][ name ] );
+};
+
+$.widget.bridge = function( name, object ) {
+ $.fn[ name ] = function( options ) {
+ var isMethodCall = typeof options === "string",
+ args = Array.prototype.slice.call( arguments, 1 ),
+ returnValue = this;
+
+ // allow multiple hashes to be passed on init
+ options = !isMethodCall && args.length ?
+ $.extend.apply( null, [ true, options ].concat(args) ) :
+ options;
+
+ // prevent calls to internal methods
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
+ return returnValue;
+ }
+
+ if ( isMethodCall ) {
+ this.each(function() {
+ var instance = $.data( this, name ),
+ methodValue = instance && $.isFunction( instance[options] ) ?
+ instance[ options ].apply( instance, args ) :
+ instance;
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
+// if ( !instance ) {
+// throw "cannot call methods on " + name + " prior to initialization; " +
+// "attempted to call method '" + options + "'";
+// }
+// if ( !$.isFunction( instance[options] ) ) {
+// throw "no such method '" + options + "' for " + name + " widget instance";
+// }
+// var methodValue = instance[ options ].apply( instance, args );
+ if ( methodValue !== instance && methodValue !== undefined ) {
+ returnValue = methodValue;
+ return false;
+ }
+ });
+ } else {
+ this.each(function() {
+ var instance = $.data( this, name );
+ if ( instance ) {
+ instance.option( options || {} )._init();
+ } else {
+ $.data( this, name, new object( options, this ) );
+ }
+ });
+ }
+
+ return returnValue;
+ };
+};
+
+$.Widget = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+};
+
+$.Widget.prototype = {
+ widgetName: "widget",
+ widgetEventPrefix: "",
+ options: {
+ disabled: false
+ },
+ _createWidget: function( options, element ) {
+ // $.widget.bridge stores the plugin instance, but we do it anyway
+ // so that it's stored even before the _create function runs
+ $.data( element, this.widgetName, this );
+ this.element = $( element );
+ this.options = $.extend( true, {},
+ this.options,
+ this._getCreateOptions(),
+ options );
+
+ var self = this;
+ this.element.bind( "remove." + this.widgetName, function() {
+ self.destroy();
+ });
+
+ this._create();
+ this._trigger( "create" );
+ this._init();
+ },
+ _getCreateOptions: function() {
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+ },
+ _create: function() {},
+ _init: function() {},
+
+ destroy: function() {
+ this.element
+ .unbind( "." + this.widgetName )
+ .removeData( this.widgetName );
+ this.widget()
+ .unbind( "." + this.widgetName )
+ .removeAttr( "aria-disabled" )
+ .removeClass(
+ this.widgetBaseClass + "-disabled " +
+ "ui-state-disabled" );
+ },
+
+ widget: function() {
+ return this.element;
+ },
+
+ option: function( key, value ) {
+ var options = key;
+
+ if ( arguments.length === 0 ) {
+ // don't return a reference to the internal hash
+ return $.extend( {}, this.options );
+ }
+
+ if (typeof key === "string" ) {
+ if ( value === undefined ) {
+ return this.options[ key ];
+ }
+ options = {};
+ options[ key ] = value;
+ }
+
+ this._setOptions( options );
+
+ return this;
+ },
+ _setOptions: function( options ) {
+ var self = this;
+ $.each( options, function( key, value ) {
+ self._setOption( key, value );
+ });
+
+ return this;
+ },
+ _setOption: function( key, value ) {
+ this.options[ key ] = value;
+
+ if ( key === "disabled" ) {
+ this.widget()
+ [ value ? "addClass" : "removeClass"](
+ this.widgetBaseClass + "-disabled" + " " +
+ "ui-state-disabled" )
+ .attr( "aria-disabled", value );
+ }
+
+ return this;
+ },
+
+ enable: function() {
+ return this._setOption( "disabled", false );
+ },
+ disable: function() {
+ return this._setOption( "disabled", true );
+ },
+
+ _trigger: function( type, event, data ) {
+ var prop, orig,
+ callback = this.options[ type ];
+
+ data = data || {};
+ event = $.Event( event );
+ event.type = ( type === this.widgetEventPrefix ?
+ type :
+ this.widgetEventPrefix + type ).toLowerCase();
+ // the original event may come from any element
+ // so we need to reset the target on the new event
+ event.target = this.element[ 0 ];
+
+ // copy original event properties over to the new event
+ orig = event.originalEvent;
+ if ( orig ) {
+ for ( prop in orig ) {
+ if ( !( prop in event ) ) {
+ event[ prop ] = orig[ prop ];
+ }
+ }
+ }
+
+ this.element.trigger( event, data );
+
+ return !( $.isFunction(callback) &&
+ callback.call( this.element[0], event, data ) === false ||
+ event.isDefaultPrevented() );
+ }
+};
+
+})( jQuery );
diff --git a/jquery/split_jquery.pl b/jquery/split_jquery.pl
new file mode 100644
index 0000000..3edc763
--- /dev/null
+++ b/jquery/split_jquery.pl
@@ -0,0 +1,25 @@
+# script to split file into parts of roughly 32kb
+#!/bin/perl
+my $file = shift;
+my $target = shift;
+my $count = 1;
+my $len = 0;
+$target=~/p(\d+).js/;
+my $part = $1;
+open(F,"<$file") || die ("cannot open file for reading: $!");
+open(G,">$target") || die("cannot open file for writing: $!");
+while (<F>)
+{
+ if ($part==$count)
+ {
+ print G "$_";
+ }
+ $len+=length($_);
+ if ($len>32768)
+ {
+ $len=0;
+ $count++;
+ }
+}
+close(F);
+close(G);
diff --git a/libmd5/Makefile b/libmd5/Makefile
new file mode 100644
index 0000000..8afa249
--- /dev/null
+++ b/libmd5/Makefile
@@ -0,0 +1,40 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+all: Makefile.libmd5
+ $(MAKE) -f Makefile.libmd5
+
+clean: Makefile.libmd5
+ $(MAKE) -f Makefile.libmd5 clean
+
+distclean: clean
+ $(RM) -f Makefile.libmd5 libmd5.pro Makefile
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" libmd5.pro >Makefile.libmd5
+
+Makefile.libmd5: libmd5.pro
+ $(ENV) $(PERL) "$(TMAKE)" libmd5.pro >Makefile.libmd5
+
+install:
diff --git a/libmd5/Makefile.in b/libmd5/Makefile.in
new file mode 100644
index 0000000..08c03b8
--- /dev/null
+++ b/libmd5/Makefile.in
@@ -0,0 +1,18 @@
+all: Makefile.libmd5
+ $(MAKE) -f Makefile.libmd5
+
+clean: Makefile.libmd5
+ $(MAKE) -f Makefile.libmd5 clean
+
+distclean: clean
+ $(RM) -f Makefile.libmd5 libmd5.pro Makefile
+
+realclean: distclean
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" libmd5.pro >Makefile.libmd5
+
+Makefile.libmd5: libmd5.pro
+ $(ENV) $(PERL) "$(TMAKE)" libmd5.pro >Makefile.libmd5
+
+install:
diff --git a/libmd5/Makefile.libmd5 b/libmd5/Makefile.libmd5
new file mode 100644
index 0000000..f0a1810
--- /dev/null
+++ b/libmd5/Makefile.libmd5
@@ -0,0 +1,82 @@
+#############################################################################
+# Makefile for building ../lib/libmd5.a
+# Generated by tmake at 10:48, 2014/08/21
+# Project: libmd5
+# Template: lib
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I/opt/local/include
+AR = ar cq
+RANLIB = ranlib
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = md5.h \
+ md5_loc.h
+SOURCES = md5.c
+OBJECTS = ../objects/md5/md5.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../lib/libmd5.a
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ ranlib $(TARGET)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake libmd5.pro
+
+dist:
+ $(TAR) libmd5.tar libmd5.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) libmd5.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../objects/md5/md5.o: md5.c \
+ md5.h \
+ md5_loc.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o ../objects/md5/md5.o md5.c
+
diff --git a/libmd5/libmd5.pro b/libmd5/libmd5.pro
new file mode 100644
index 0000000..6714f3e
--- /dev/null
+++ b/libmd5/libmd5.pro
@@ -0,0 +1,17 @@
+#
+# This file was generated from libmd5.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = lib
+CONFIG = warn_on staticlib debug
+HEADERS = md5.h md5_loc.h
+SOURCES = md5.c
+win32:INCLUDEPATH += .
+win32-g++:TMAKE_CFLAGS += -D__CYGWIN__ -DALL_STATIC
+DESTDIR = ../lib
+TARGET = md5
+OBJECTS_DIR = ../objects/md5
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/libmd5/libmd5.pro.in b/libmd5/libmd5.pro.in
new file mode 100644
index 0000000..5516174
--- /dev/null
+++ b/libmd5/libmd5.pro.in
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+CONFIG = warn_on staticlib $extraopts
+HEADERS = md5.h md5_loc.h
+SOURCES = md5.c
+win32:INCLUDEPATH += .
+win32-g++:TMAKE_CFLAGS += -D__CYGWIN__ -DALL_STATIC
+DESTDIR = ../lib
+TARGET = md5
+OBJECTS_DIR = ../objects/md5
+
diff --git a/libmd5/md5.c b/libmd5/md5.c
new file mode 100644
index 0000000..5210d92
--- /dev/null
+++ b/libmd5/md5.c
@@ -0,0 +1,313 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h' header
+ * definitions; now uses stuff from dpkg's config.h.
+ * - Ian Jackson <ian at chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#include <string.h> /* for memcpy() */
+#include <sys/types.h> /* for stupid systems */
+
+#include "md5.h"
+
+void
+MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
+
+int g_bigEndian = 0;
+int g_endianessDetected = 0;
+
+static void
+detectEndianess()
+{
+ int nl = 0x12345678;
+ short ns = 0x1234;
+
+ unsigned char *p = (unsigned char *)(&nl);
+ unsigned char *sp = (unsigned char *)(&ns);
+
+ if (g_endianessDetected) return;
+ if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
+ {
+ g_bigEndian = 1;
+ }
+ else if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
+ {
+ g_bigEndian = 0;
+ }
+ else
+ {
+ g_bigEndian = *sp != 0x12;
+ }
+
+ g_endianessDetected=1;
+}
+
+static void
+byteSwap(UWORD32 *buf, unsigned words)
+{
+ md5byte *p;
+
+ if (!g_bigEndian) return;
+
+ p = (md5byte *)buf;
+
+ do {
+ *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
+ ((unsigned)p[1] << 8 | p[0]);
+ p += 4;
+ } while (--words);
+}
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(struct MD5Context *ctx)
+{
+ detectEndianess();
+
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bytes[0] = 0;
+ ctx->bytes[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
+{
+ UWORD32 t;
+
+ /* Update byte count */
+
+ t = ctx->bytes[0];
+ if ((ctx->bytes[0] = t + len) < t)
+ ctx->bytes[1]++; /* Carry from low to high */
+
+ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
+ if (t > len) {
+ memcpy((md5byte *)ctx->in + 64 - t, buf, len);
+ return;
+ }
+ /* First chunk is an odd size */
+ memcpy((md5byte *)ctx->in + 64 - t, buf, t);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += t;
+ len -= t;
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(md5byte digest[16], struct MD5Context *ctx)
+{
+ int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
+ md5byte *p = (md5byte *)ctx->in + count;
+
+ /* Set the first char of padding to 0x80. There is always room. */
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 56 bytes (-8..55) */
+ count = 56 - 1 - count;
+
+ if (count < 0) { /* Padding forces an extra block */
+ memset(p, 0, count + 8);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ p = (md5byte *)ctx->in;
+ count = 56;
+ }
+ memset(p, 0, count);
+ byteSwap(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ctx->in[14] = ctx->bytes[0] << 3;
+ ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
+ MD5Transform(ctx->buf, ctx->in);
+
+ byteSwap(ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f,w,x,y,z,in,s) \
+ (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
+{
+ register UWORD32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
+
+void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16])
+{
+ struct MD5Context md5;
+ MD5Init(&md5);
+ MD5Update(&md5,buf,len);
+ MD5Final(sig,&md5);
+}
+
+#define HEX_STRING "0123456789abcdef" /* to convert to hex */
+
+void MD5SigToString(unsigned char signature[16],char *str,int len)
+{
+ unsigned char *sig_p;
+ char *str_p, *max_p;
+ unsigned int high, low;
+
+ str_p = str;
+ max_p = str + len;
+
+ for (sig_p = (unsigned char *)signature;
+ sig_p < (unsigned char *)signature + 16;
+ sig_p++)
+ {
+ high = *sig_p / 16;
+ low = *sig_p % 16;
+ /* account for 2 chars */
+ if (str_p + 1 >= max_p) {
+ break;
+ }
+ *str_p++ = HEX_STRING[high];
+ *str_p++ = HEX_STRING[low];
+ }
+ /* account for 2 chars */
+ if (str_p < max_p) {
+ *str_p++ = '\0';
+ }
+}
+
+
diff --git a/libmd5/md5.h b/libmd5/md5.h
new file mode 100644
index 0000000..03f8ff6
--- /dev/null
+++ b/libmd5/md5.h
@@ -0,0 +1,57 @@
+/*
+ * This is the header file for the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h'
+ * header definitions; now uses stuff from dpkg's config.h
+ * - Ian Jackson <ian at chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "md5_loc.h"
+
+#define md5byte unsigned char
+
+//#if SIZEOF_UNSIGNED_LONG==4
+//# define UWORD32 unsigned long
+//#elif SIZEOF_UNSIGNED_INT==4
+//#else
+//# error I do not know what to use for a UWORD32.
+//#endif
+
+struct MD5Context {
+ UWORD32 buf[4];
+ UWORD32 bytes[2];
+ UWORD32 in[16];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16]);
+void MD5SigToString(unsigned char sig[16],char *str,int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !MD5_H */
diff --git a/libmd5/md5_loc.h b/libmd5/md5_loc.h
new file mode 100644
index 0000000..ef67c02
--- /dev/null
+++ b/libmd5/md5_loc.h
@@ -0,0 +1,6 @@
+#ifndef _MD5LOC_H
+#define _MD5LOC_H
+
+# define UWORD32 unsigned int
+
+#endif
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
new file mode 100644
index 0000000..b86ead3
--- /dev/null
+++ b/packages/rpm/doxygen.spec
@@ -0,0 +1,129 @@
+%define version 1.8.8
+%define revision 1
+%define mmn 1
+%define name doxygen
+
+# optionally pass --with-doxywizard to rpmbuild
+
+%define contentdir /var/www
+%define suexec_caller doxygen
+%define buildroot /var/tmp/%{name}-%{version}-%{revision}root
+
+Summary: A documentation system for C/C++.
+Name: doxygen
+Version: %{version}
+Release: %{revision}
+URL: http://www.stack.nl/~dimitri/doxygen/index.html
+Vendor: Dimitri van Heesch
+License: GNU General Public License
+Group: Development/Tools
+Source: %{name}-%{version}.src.tar.gz
+BuildRoot: %{buildroot}
+BuildRequires: libstdc++-devel >= 2.96, /usr/bin/perl, /usr/bin/latex, /usr/bin/dvips, /usr/bin/gs
+Requires: /sbin/chkconfig, /bin/mktemp, /bin/rm, /bin/mv, libstdc++ >= 2.96
+Provides: doxygen = %{mmn}
+
+%description
+Doxygen can generate an online class browser (in HTML) and/or a
+reference manual (in LaTeX) from a set of documented source files. The
+documentation is extracted directly from the sources. Doxygen can
+also be configured to extract the code structure from undocumented
+source files.
+
+%if %{?_with_doxywizard:1}%{!?_with_doxywizard:0}
+%package doxywizard
+Group: Development/Libraries
+Summary: GUI Interface for doxygen.
+Requires: doxygen = %{mmn}
+Requires: qt >= 3.3
+Provides: doxywizard = %{mmn}
+# Obsoletes:
+
+%description doxywizard
+Doxygen can generate an online class browser (in HTML) and/or a
+reference manual (in LaTeX) from a set of documented source files. The
+documentation is extracted directly from the sources. Doxygen can
+also be configured to extract the code structure from undocumented
+source files.
+
+This is the GUI interface for doxygen. It requires qt and X11 to
+install.
+%endif
+
+%if %{?_with_doxysearch:1}%{!?_with_doxysearch:0}
+%package doxysearch
+Group: Development/Libraries
+Summary: external indexer and search engine for doxygen.
+Requires: doxygen = %{mmn}
+Requires: libxapian-devel >= 1.2
+Provides: doxysearch.cgi = %{mmn}
+Provides: doxyindexer = %{mmn}
+# Obsoletes:
+
+%description doxysearch
+External indexing and search tools for searching through doxygen
+generated HTML documentation.
+%endif
+
+%prep
+%setup -q -n %{name}-%{version}
+./configure %{?_with_doxywizard} %{?_with_doxysearch} --prefix $RPM_BUILD_ROOT/usr
+
+%build
+make %{?_smp_mflags}
+make %{?_smp_mflags} pdf
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+%doc README.md LICENSE LANGUAGE.HOWTO examples ./latex/*.pdf
+%doc /usr/man/man1/doxygen.1.gz
+
+%{_bindir}/doxygen
+
+%if %{?_with_doxywizard:1}%{!?_with_doxywizard:0}
+%files doxywizard
+%defattr(-,root,root)
+%{_bindir}/doxywizard
+%doc /usr/man/man1/doxywizard.1.gz
+%endif
+
+%if %{?_with_doxysearch:1}%{!?_with_doxysearch:0}
+%files doxysearch
+%defattr(-,root,root)
+%{_bindir}/doxyindexer
+%{_bindir}/doxysearch.cgi
+%doc /usr/man/man1/doxyindexer.1.gz
+%doc /usr/man/man1/doxysearch.1.gz
+%endif
+
+%changelog
+* Tue Dec 25 2012 Dimitri van Heesch <dimitri at stack.nl> 1.8.3
+- added doxyindexer and doxysearch
+
+* Fri Apr 18 2008 Kenneth Porter <shiva+doxygenspec at sewingwitch.com> 1.5.5-1
+- consolidate with and without doxywizard spec files with rpm macro
+- add gs BuildPrereq
+
+* Sun Nov 18 2007 Kevin McBride <kevin at planetsaphire.com> 1.5.4
+- consolidated manual package in lieu of --excludedocs flag for rpm --install
+
+* Mon Oct 10 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.5
+- fixed versioning bugs.
+
+* Tue Oct 4 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.5
+- added obsoletes and proides sections.
+
+* Sun Sep 20 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.4
+- modified rpm spec file for Fedora Core acceptance criteria.
+
+* Sun Aug 7 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.4
+- created initial rpm spec file for doxygen-1.4.4
+
diff --git a/packages/rpm/doxygen.spec.in b/packages/rpm/doxygen.spec.in
new file mode 100644
index 0000000..f78322a
--- /dev/null
+++ b/packages/rpm/doxygen.spec.in
@@ -0,0 +1,126 @@
+%define name doxygen
+
+# optionally pass --with-doxywizard to rpmbuild
+
+%define contentdir /var/www
+%define suexec_caller doxygen
+%define buildroot /var/tmp/%{name}-%{version}-%{revision}root
+
+Summary: A documentation system for C/C++.
+Name: doxygen
+Version: %{version}
+Release: %{revision}
+URL: http://www.stack.nl/~dimitri/doxygen/index.html
+Vendor: Dimitri van Heesch
+License: GNU General Public License
+Group: Development/Tools
+Source: %{name}-%{version}.src.tar.gz
+BuildRoot: %{buildroot}
+BuildRequires: libstdc++-devel >= 2.96, /usr/bin/perl, /usr/bin/latex, /usr/bin/dvips, /usr/bin/gs
+Requires: /sbin/chkconfig, /bin/mktemp, /bin/rm, /bin/mv, libstdc++ >= 2.96
+Provides: doxygen = %{mmn}
+
+%description
+Doxygen can generate an online class browser (in HTML) and/or a
+reference manual (in LaTeX) from a set of documented source files. The
+documentation is extracted directly from the sources. Doxygen can
+also be configured to extract the code structure from undocumented
+source files.
+
+%if %{?_with_doxywizard:1}%{!?_with_doxywizard:0}
+%package doxywizard
+Group: Development/Libraries
+Summary: GUI Interface for doxygen.
+Requires: doxygen = %{mmn}
+Requires: qt >= 3.3
+Provides: doxywizard = %{mmn}
+# Obsoletes:
+
+%description doxywizard
+Doxygen can generate an online class browser (in HTML) and/or a
+reference manual (in LaTeX) from a set of documented source files. The
+documentation is extracted directly from the sources. Doxygen can
+also be configured to extract the code structure from undocumented
+source files.
+
+This is the GUI interface for doxygen. It requires qt and X11 to
+install.
+%endif
+
+%if %{?_with_doxysearch:1}%{!?_with_doxysearch:0}
+%package doxysearch
+Group: Development/Libraries
+Summary: external indexer and search engine for doxygen.
+Requires: doxygen = %{mmn}
+Requires: libxapian-devel >= 1.2
+Provides: doxysearch.cgi = %{mmn}
+Provides: doxyindexer = %{mmn}
+# Obsoletes:
+
+%description doxysearch
+External indexing and search tools for searching through doxygen
+generated HTML documentation.
+%endif
+
+%prep
+%setup -q -n %{name}-%{version}
+./configure %{?_with_doxywizard} %{?_with_doxysearch} --prefix $RPM_BUILD_ROOT/usr
+
+%build
+make %{?_smp_mflags}
+make %{?_smp_mflags} pdf
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+%doc README.md LICENSE LANGUAGE.HOWTO examples ./latex/*.pdf
+%doc /usr/man/man1/doxygen.1.gz
+
+%{_bindir}/doxygen
+
+%if %{?_with_doxywizard:1}%{!?_with_doxywizard:0}
+%files doxywizard
+%defattr(-,root,root)
+%{_bindir}/doxywizard
+%doc /usr/man/man1/doxywizard.1.gz
+%endif
+
+%if %{?_with_doxysearch:1}%{!?_with_doxysearch:0}
+%files doxysearch
+%defattr(-,root,root)
+%{_bindir}/doxyindexer
+%{_bindir}/doxysearch.cgi
+%doc /usr/man/man1/doxyindexer.1.gz
+%doc /usr/man/man1/doxysearch.1.gz
+%endif
+
+%changelog
+* Tue Dec 25 2012 Dimitri van Heesch <dimitri at stack.nl> 1.8.3
+- added doxyindexer and doxysearch
+
+* Fri Apr 18 2008 Kenneth Porter <shiva+doxygenspec at sewingwitch.com> 1.5.5-1
+- consolidate with and without doxywizard spec files with rpm macro
+- add gs BuildPrereq
+
+* Sun Nov 18 2007 Kevin McBride <kevin at planetsaphire.com> 1.5.4
+- consolidated manual package in lieu of --excludedocs flag for rpm --install
+
+* Mon Oct 10 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.5
+- fixed versioning bugs.
+
+* Tue Oct 4 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.5
+- added obsoletes and proides sections.
+
+* Sun Sep 20 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.4
+- modified rpm spec file for Fedora Core acceptance criteria.
+
+* Sun Aug 7 2005 Kevin McBride <kevin at planetsaphire.com> 1.4.4
+- created initial rpm spec file for doxygen-1.4.4
+
diff --git a/qtools/Doxyfile b/qtools/Doxyfile
new file mode 100644
index 0000000..9e9743c
--- /dev/null
+++ b/qtools/Doxyfile
@@ -0,0 +1,309 @@
+# Doxyfile 1.8.4
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = Qtools
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = ../qtools_docs
+CREATE_SUBDIRS = YES
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = $(PWD)/
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text "
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = .
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.h \
+ *.cpp \
+ *.doc
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+CLANG_ASSISTED_PARSING = YES
+CLANG_OPTIONS =
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 4
+IGNORE_PREFIX = Q
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = YES
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = YES
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = YES
+QCH_FILE =
+QHP_NAMESPACE = com.qtools
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = YES
+ECLIPSE_DOC_ID = org.doxygen.qtools
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL = http://macbookpro/~dimitri/doxysearch.cgi
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = YES
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT =
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = Q_EXPORT=
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE = ../qtools_docs/qtools.tag
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+DOT_NUM_THREADS = 0
+DOT_FONTNAME =
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = svg
+INTERACTIVE_SVG = YES
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = YES
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
diff --git a/qtools/Doxyfile.bak b/qtools/Doxyfile.bak
new file mode 100644
index 0000000..aa8de17
--- /dev/null
+++ b/qtools/Doxyfile.bak
@@ -0,0 +1,308 @@
+# Doxyfile 1.8.3.1
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = Qtools
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = ../qtools_docs
+CREATE_SUBDIRS = YES
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = $(PWD)/
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text "
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = .
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.h \
+ *.cpp \
+ *.doc
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+CLANG_ASSISTED_PARSING = YES
+CLANG_OPTIONS =
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 4
+IGNORE_PREFIX = Q
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT =
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = YES
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = YES
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = YES
+QCH_FILE =
+QHP_NAMESPACE = com.qtools
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = YES
+ECLIPSE_DOC_ID = org.doxygen.qtools
+DISABLE_INDEX = YES
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = YES
+EXTERNAL_SEARCH = YES
+SEARCHENGINE_URL = http://macbookpro/~dimitri/doxysearch.cgi
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT =
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = YES
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT =
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT =
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = Q_EXPORT=
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE = ../qtools_docs/qtools.tag
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+DOT_NUM_THREADS = 0
+DOT_FONTNAME =
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = svg
+INTERACTIVE_SVG = YES
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = YES
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
diff --git a/qtools/LICENSE.GPL b/qtools/LICENSE.GPL
new file mode 100644
index 0000000..935a2a0
--- /dev/null
+++ b/qtools/LICENSE.GPL
@@ -0,0 +1,349 @@
+
+ The Qt GUI Toolkit is Copyright (C) 1994-2000 Trolltech AS.
+
+ You may use, distribute and copy the Qt GUI Toolkit under the terms of
+ GNU General Public License version 2, which is display below.
+
+-------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+-------------------------------------------------------------------------
diff --git a/qtools/LICENSE.QPL b/qtools/LICENSE.QPL
new file mode 100644
index 0000000..ecdad6e
--- /dev/null
+++ b/qtools/LICENSE.QPL
@@ -0,0 +1,103 @@
+ THE Q PUBLIC LICENSE
+ version 1.0
+
+ Copyright (C) 1999-2000 Trolltech AS, Norway.
+ Everyone is permitted to copy and
+ distribute this license document.
+
+The intent of this license is to establish freedom to share and change the
+software regulated by this license under the open source model.
+
+This license applies to any software containing a notice placed by the
+copyright holder saying that it may be distributed under the terms of
+the Q Public License version 1.0. Such software is herein referred to as
+the Software. This license covers modification and distribution of the
+Software, use of third-party application programs based on the Software,
+and development of free software which uses the Software.
+
+ Granted Rights
+
+1. You are granted the non-exclusive rights set forth in this license
+ provided you agree to and comply with any and all conditions in this
+ license. Whole or partial distribution of the Software, or software
+ items that link with the Software, in any form signifies acceptance of
+ this license.
+
+2. You may copy and distribute the Software in unmodified form provided
+ that the entire package, including - but not restricted to - copyright,
+ trademark notices and disclaimers, as released by the initial developer
+ of the Software, is distributed.
+
+3. You may make modifications to the Software and distribute your
+ modifications, in a form that is separate from the Software, such as
+ patches. The following restrictions apply to modifications:
+
+ a. Modifications must not alter or remove any copyright notices in
+ the Software.
+
+ b. When modifications to the Software are released under this
+ license, a non-exclusive royalty-free right is granted to the
+ initial developer of the Software to distribute your modification
+ in future versions of the Software provided such versions remain
+ available under these terms in addition to any other license(s) of
+ the initial developer.
+
+4. You may distribute machine-executable forms of the Software or
+ machine-executable forms of modified versions of the Software, provided
+ that you meet these restrictions:
+
+ a. You must include this license document in the distribution.
+
+ b. You must ensure that all recipients of the machine-executable forms
+ are also able to receive the complete machine-readable source code
+ to the distributed Software, including all modifications, without
+ any charge beyond the costs of data transfer, and place prominent
+ notices in the distribution explaining this.
+
+ c. You must ensure that all modifications included in the
+ machine-executable forms are available under the terms of this
+ license.
+
+5. You may use the original or modified versions of the Software to
+ compile, link and run application programs legally developed by you
+ or by others.
+
+6. You may develop application programs, reusable components and other
+ software items that link with the original or modified versions of the
+ Software. These items, when distributed, are subject to the following
+ requirements:
+
+ a. You must ensure that all recipients of machine-executable forms of
+ these items are also able to receive and use the complete
+ machine-readable source code to the items without any charge
+ beyond the costs of data transfer.
+
+ b. You must explicitly license all recipients of your items to use
+ and re-distribute original and modified versions of the items in
+ both machine-executable and source code forms. The recipients must
+ be able to do so without any charges whatsoever, and they must be
+ able to re-distribute to anyone they choose.
+
+
+ c. If the items are not available to the general public, and the
+ initial developer of the Software requests a copy of the items,
+ then you must supply one.
+
+ Limitations of Liability
+
+In no event shall the initial developers or copyright holders be liable
+for any damages whatsoever, including - but not restricted to - lost
+revenue or profits or other direct, indirect, special, incidental or
+consequential damages, even if they have been advised of the possibility
+of such damages, except to the extent invariable law, if any, provides
+otherwise.
+
+ No Warranty
+
+The Software and this license document are provided AS IS with NO WARRANTY
+OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE.
+ Choice of Law
+
+This license is governed by the Laws of Norway. Disputes shall be settled
+by Oslo City Court.
diff --git a/qtools/Makefile b/qtools/Makefile
new file mode 100644
index 0000000..c085ff3
--- /dev/null
+++ b/qtools/Makefile
@@ -0,0 +1,52 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+#
+#
+#
+# Copyright (C) 1997-2000 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+all: Makefile.qtools Makefile
+ $(MAKE) -f Makefile.qtools $@
+
+Makefile.qtools: qtools.pro
+ $(ENV) $(PERL) "$(TMAKE)" qtools.pro >Makefile.qtools
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" qtools.pro >Makefile.qtools
+
+clean: Makefile.qtools
+ $(MAKE) -f Makefile.qtools clean
+
+distclean: clean
+
+FORCE:
diff --git a/qtools/Makefile.in b/qtools/Makefile.in
new file mode 100644
index 0000000..ca66cc1
--- /dev/null
+++ b/qtools/Makefile.in
@@ -0,0 +1,30 @@
+#
+#
+#
+# Copyright (C) 1997-2000 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+all: Makefile.qtools Makefile
+ $(MAKE) -f Makefile.qtools $@
+
+Makefile.qtools: qtools.pro
+ $(ENV) $(PERL) "$(TMAKE)" qtools.pro >Makefile.qtools
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" qtools.pro >Makefile.qtools
+
+clean: Makefile.qtools
+ $(MAKE) -f Makefile.qtools clean
+
+distclean: clean
+
+FORCE:
diff --git a/qtools/README b/qtools/README
new file mode 100644
index 0000000..1e7fc8d
--- /dev/null
+++ b/qtools/README
@@ -0,0 +1,4 @@
+This directory contains a small subset of Troll-Tech's Qt library
+The subset is enough to build the doxygen executable, but lacks many of
+the features found in the Qt library. See http://www.trolltech.com
+for the full package.
diff --git a/qtools/qarray.doc b/qtools/qarray.doc
new file mode 100644
index 0000000..6914dbc
--- /dev/null
+++ b/qtools/qarray.doc
@@ -0,0 +1,486 @@
+/****************************************************************************
+**
+**
+** QArray class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QArray documentation
+ *****************************************************************************/
+
+/*!
+ \class QArray qarray.h
+ \brief The QArray class is a template class that provides arrays of simple types.
+
+ \ingroup tools
+
+ QArray is implemented as a template class. Define a template
+ instance QArray\<X\> to create an array that contains X items.
+
+ QArray stores the array elements directly in the array. It can only
+ deal with simple types, i.e. C++ types, structs and classes that have
+ no constructors, destructors or virtual functions. QArray uses
+ bitwise operations to copy and compare array elements.
+
+ The QVector collection class is also a kind of array. Like most
+ \link collection.html collection classes\endlink, it has pointers to the
+ contained items.
+
+ QArray uses explicit \link shclass.html sharing\endlink with a reference
+ count. If more than one array share common data, and one array is
+ modified, all arrays will be modified.
+
+ The benefit of sharing is that a program does not need to duplicate
+ data when it is not required, which results in less memory usage and
+ less copying of data.
+
+ Example:
+ \code
+ #include <qarray.h>
+ #include <stdio.h>
+
+ QArray<int> fib( int num ) // returns fibonacci array
+ {
+ ASSERT( num > 2 );
+ QArray<int> f( num ); // array of ints
+
+ f[0] = f[1] = 1; // initialize first two numbers
+ for ( int i=2; i<num; i++ )
+ f[i] = f[i-1] + f[i-2];
+
+ return f;
+ }
+
+ void main()
+ {
+ QArray<int> a = fib( 6 ); // get 6 first fibonaccis
+ int i;
+
+ for ( i=0; i<a.size(); i++ ) // print them
+ prinf( "%d: %d\n", i, a[i] );
+
+ printf( "1 is found %d time(s)\n", a.contains(1) );
+ printf( "5 is found at index %d\n", a.find(5) );
+ }
+ \endcode
+
+ Program output:
+ \code
+ 0: 1
+ 1: 1
+ 2: 2
+ 3: 3
+ 4: 5
+ 5: 8
+ 1 is found 2 times
+ 5 is found at index 4
+ \endcode
+
+ Note about using QArray for manipulating structs or classes:
+ Compilers will often pad the size of structs of odd sizes up to the
+ nearest word boundary. This will then be the size QArray will use
+ for its bitwise element comparisons. Since the remaining bytes will
+ typically be uninitialized, this can cause find() etc. to fail to
+ find the element. Example:
+
+ \code
+ struct MyStruct
+ {
+ short i; // 2 bytes
+ char c; // 1 byte
+ }; // sizeof(MyStruct) may be padded to 4 bytes
+
+ QArray<MyStruct> a(1);
+ a[0].i = 5;
+ a[0].c = 't';
+
+ MyStruct x;
+ x.i = '5';
+ x.c = 't';
+ int i = a.find( x ); // May return -1 if the pad bytes differ
+ \endcode
+
+ To workaround this, make sure that you use a struct where sizeof()
+ returns the same as the sum of the sizes of the members, either by
+ changing the types of the struct members or by adding dummy members.
+
+ \sa \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ \fn QArray::QArray()
+ Constructs a null array.
+ \sa isNull()
+*/
+
+/*!
+ \fn QArray::QArray( int size )
+ Constructs an array with room for \e size elements.
+ Makes a null array if \e size == 0.
+
+ Note that the elements are not initialized.
+
+ \sa resize(), isNull()
+*/
+
+/*!
+ \fn QArray::QArray( const QArray<type> &a )
+ Constructs a shallow copy of \e a.
+ \sa assign()
+*/
+
+/*!
+ \fn QArray::QArray( int, int )
+ Constructs an array <em>without allocating</em> array space.
+ The arguments should be (0, 0). Use at own risk.
+*/
+
+/*!
+ \fn QArray::~QArray()
+ Dereferences the array data and deletes it if this was the last
+ reference.
+*/
+
+/*!
+ \fn QArray<type> &QArray::operator=( const QArray<type> &a )
+ Assigns a shallow copy of \e a to this array and returns a reference
+ to this array.
+
+ Equivalent to assign( a ).
+*/
+
+/*!
+ \fn type *QArray::data() const
+ Returns a pointer to the actual array data.
+
+ The array is a null array if data() == 0 (null pointer).
+
+ \sa isNull()
+*/
+
+/*!
+ \fn uint QArray::nrefs() const
+ Returns the reference count for the shared array data. This reference count
+ is always greater than zero.
+*/
+
+/*!
+ \fn uint QArray::size() const
+ Returns the size of the array (max number of elements).
+
+ The array is a null array if size() == 0.
+
+ \sa isNull(), resize()
+*/
+
+/*!
+ \fn uint QArray::count() const
+ Returns the same as size().
+
+ \sa size()
+*/
+
+/*!
+ \fn bool QArray::isEmpty() const
+ Returns TRUE if the array is empty, i.e. size() == 0, otherwise FALSE.
+
+ isEmpty() is equivalent with isNull() for QArray. Note that this is not
+ the case for QCString::isEmpty().
+*/
+
+/*!
+ \fn bool QArray::isNull() const
+ Returns TRUE if the array is null, otherwise FALSE.
+
+ A null array has size() == 0 and data() == 0.
+*/
+
+/*!
+ \fn bool QArray::resize( uint size )
+ Resizes (expands or shrinks) the array to \e size elements. The array
+ becomes a null array if \e size == 0.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated.
+
+ New elements will not be initialized.
+
+ \sa size()
+*/
+
+/*!
+ \fn bool QArray::truncate( uint pos )
+ Truncates the array at position \e pos.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated.
+
+ Equivalent to resize(\e pos).
+
+ \sa resize()
+*/
+
+/*!
+ \fn bool QArray::fill( const type &v, int size )
+ Fills the array with the value \e v. If \e size is specified as different
+ from -1, then the array will be resized before filled.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated
+ (only when \e size != -1).
+
+ \sa resize()
+*/
+
+/*!
+ \fn void QArray::detach()
+ Detaches this array from shared array data, i.e. makes a private, deep
+ copy of the data.
+
+ Copying will only be performed if the
+ \link nrefs() reference count\endlink is greater than one.
+
+ \sa copy()
+*/
+
+/*!
+ \fn QArray<type> QArray::copy() const
+ Returns a deep copy of this array.
+ \sa detach(), duplicate()
+*/
+
+/*!
+ \fn QArray<type> &QArray::assign( const QArray<type> &a )
+ Shallow copy. Dereferences the current array and references the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa operator=()
+*/
+
+/*!
+ \fn QArray<type> &QArray::assign( const type *data, uint size )
+ Shallow copy. Dereferences the current array and references the
+ array data \e data, which contains \e size elements.
+ Returns a reference to this array.
+
+ Do not delete \e data later, QArray takes care of that.
+*/
+
+/*!
+ \fn QArray<type> &QArray::duplicate( const QArray<type> &a )
+ Deep copy. Dereferences the current array and obtains a copy of the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa copy()
+*/
+
+/*!
+ \fn QArray<type> &QArray::duplicate( const type *data, uint size )
+ Deep copy. Dereferences the current array and obtains a copy of the
+ array data \e data instead. Returns a reference to this array.
+ \sa copy()
+*/
+
+/*!
+ \fn QArray<type> &QArray::setRawData( const type *data, uint size )
+
+ Sets raw data and returns a reference to the array.
+
+ Dereferences the current array and sets the new array data to \e data and
+ the new array size to \e size. Do not attempt to resize or re-assign the
+ array data when raw data has been set.
+ Call resetRawData(d,len) to reset the array.
+
+ Setting raw data is useful because it sets QArray data without allocating
+ memory or copying data.
+
+ Example I (intended use):
+ \code
+ static char bindata[] = { 231, 1, 44, ... };
+ QByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ QDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> <something>; // read raw bindata
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ Example II (you don't want to do this):
+ \code
+ static char bindata[] = { 231, 1, 44, ... };
+ QByteArray a, b;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ a.resize( 8 ); // will crash
+ b = a; // will crash
+ a[2] = 123; // might crash
+ // forget to resetRawData - will crash
+ \endcode
+
+ \warning If you do not call resetRawData(), QArray will attempt to
+ deallocate or reallocate the raw data, which might not be too good.
+ Be careful.
+
+ \sa resetRawData()
+*/
+
+/*!
+ \fn void QArray::resetRawData( const type *data, uint size )
+ Resets raw data that was set using setRawData().
+
+ The arguments must be the data and length that were passed to
+ setRawData(). This is for consistency checking.
+
+ \sa setRawData()
+*/
+
+/*!
+ \fn int QArray::find( const type &v, uint index ) const
+ Finds the first occurrence of \e v, starting at position \e index.
+
+ Returns the position of \e v, or -1 if \e v could not be found.
+
+ \sa contains()
+*/
+
+/*!
+ \fn int QArray::contains( const type &v ) const
+ Returns the number of times \e v occurs in the array.
+ \sa find()
+*/
+
+/*!
+ \fn void QArray::sort()
+ Sorts the array elements in ascending order, using bitwise
+ comparison (memcmp()).
+
+ \sa bsearch()
+*/
+
+/*!
+ \fn int QArray::bsearch( const type &v ) const
+ In a sorted array, finds the first occurrence of \e v using binary
+ search. For a sorted array, this is generally much faster than
+ find(), which does a linear search.
+
+ Returns the position of \e v, or -1 if \e v could not be found.
+
+ \sa sort(), find()
+*/
+
+/*!
+ \fn type &QArray::operator[]( int index ) const
+ Returns a reference to the element at position \e index in the array.
+
+ This can be used to both read and set an element. Equivalent to at().
+
+ \sa at()
+*/
+
+/*!
+ \fn type &QArray::at( uint index ) const
+ Returns a reference to the element at position \e index in the array.
+
+ This can be used to both read and set an element.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn QArray::operator const type *() const
+ Cast operator. Returns a pointer to the array.
+ \sa data()
+*/
+
+/*!
+ \fn bool QArray::operator==( const QArray<type> &a ) const
+ Returns TRUE if this array is equal to \e a, otherwise FALSE.
+
+ The two arrays are bitwise compared.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QArray::operator!=( const QArray<type> &a ) const
+ Returns TRUE if this array is different from \e a, otherwise FALSE.
+
+ The two arrays are bitwise compared.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn Iterator QArray::begin()
+ Returns an iterator pointing at the beginning of this array.
+ This iterator can be used as the iterators of QValueList and QMap
+ for example. In fact it does not only behave like a usual pointer:
+ It is a pointer.
+*/
+
+/*!
+ \fn Iterator QArray::end()
+ Returns an iterator pointing behind the last element of this array.
+ This iterator can be used as the iterators of QValueList and QMap
+ for example. In fact it does not only behave like a usual pointer:
+ It is a pointer.
+*/
+
+/*!
+ \fn ConstIterator QArray::begin() const
+ Returns a const iterator pointing at the beginning of this array.
+ This iterator can be used as the iterators of QValueList and QMap
+ for example. In fact it does not only behave like a usual pointer:
+ It is a pointer.
+*/
+
+/*!
+ \fn ConstIterator QArray::end() const
+ Returns a const iterator pointing behind the last element of this array.
+ This iterator can be used as the iterators of QValueList and QMap
+ for example. In fact it does not only behave like a usual pointer:
+ It is a pointer.
+*/
+
+
+/*****************************************************************************
+ QByteArray documentation
+ *****************************************************************************/
+
+/*!
+ \class QByteArray qcstring.h
+ \brief The QByteArray class provides an array of bytes.
+
+ \inherit QArray
+
+ \ingroup tools
+
+ The QByteArray class provides an explicitly shared array of
+ bytes. It is useful for manipulating memory areas with custom
+ data. QByteArray is implemented as QArray<char>. See the QArray
+ documentation for further information.
+*/
diff --git a/qtools/qarray.h b/qtools/qarray.h
new file mode 100644
index 0000000..3d67fe9
--- /dev/null
+++ b/qtools/qarray.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+**
+** Definition of QArray template/macro class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QARRAY_H
+#define QARRAY_H
+
+#ifndef QT_H
+#include "qgarray.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QArray : public QGArray
+{
+public:
+ typedef type* Iterator;
+ typedef const type* ConstIterator;
+ typedef type ValueType;
+
+protected:
+ QArray( int, int ) : QGArray( 0, 0 ) {}
+
+public:
+ QArray() {}
+ QArray( int size ) : QGArray(size*(int)sizeof(type)) {}
+ QArray( const QArray<type> &a ) : QGArray(a) {}
+ ~QArray() {}
+ QArray<type> &operator=(const QArray<type> &a)
+ { return (QArray<type>&)QGArray::assign(a); }
+ type *data() const { return (type *)QGArray::data(); }
+ uint nrefs() const { return QGArray::nrefs(); }
+ uint size() const { return QGArray::size()/(int)sizeof(type); }
+ uint count() const { return size(); }
+ bool isEmpty() const { return QGArray::size() == 0; }
+ bool isNull() const { return QGArray::data() == 0; }
+ bool resize( uint size ) { return QGArray::resize(size*(int)sizeof(type)); }
+ bool truncate( uint pos ) { return QGArray::resize(pos*(int)sizeof(type)); }
+ bool fill( const type &d, int size = -1 )
+ { return QGArray::fill((char*)&d,size,sizeof(type) ); }
+ void detach() { QGArray::detach(); }
+ QArray<type> copy() const
+ { QArray<type> tmp; return tmp.duplicate(*this); }
+ QArray<type>& assign( const QArray<type>& a )
+ { return (QArray<type>&)QGArray::assign(a); }
+ QArray<type>& assign( const type *a, uint n )
+ { return (QArray<type>&)QGArray::assign((char*)a,n*sizeof(type)); }
+ QArray<type>& duplicate( const QArray<type>& a )
+ { return (QArray<type>&)QGArray::duplicate(a); }
+ QArray<type>& duplicate( const type *a, uint n )
+ { return (QArray<type>&)QGArray::duplicate((char*)a,n*sizeof(type)); }
+ QArray<type>& setRawData( const type *a, uint n )
+ { return (QArray<type>&)QGArray::setRawData((char*)a,
+ n*sizeof(type)); }
+ void resetRawData( const type *a, uint n )
+ { QGArray::resetRawData((char*)a,n*sizeof(type)); }
+ int find( const type &d, uint i=0 ) const
+ { return QGArray::find((char*)&d,i,sizeof(type)); }
+ int contains( const type &d ) const
+ { return QGArray::contains((char*)&d,sizeof(type)); }
+ void sort() { QGArray::sort(sizeof(type)); }
+ int bsearch( const type &d ) const
+ { return QGArray::bsearch((const char*)&d,sizeof(type)); }
+ type& operator[]( int i ) const
+ { return (type &)(*(type *)QGArray::at(i*(int)sizeof(type))); }
+ type& at( uint i ) const
+ { return (type &)(*(type *)QGArray::at(i*(int)sizeof(type))); }
+ operator const type*() const { return (const type *)QGArray::data(); }
+ bool operator==( const QArray<type> &a ) const { return isEqual(a); }
+ bool operator!=( const QArray<type> &a ) const { return !isEqual(a); }
+ Iterator begin() { return data(); }
+ Iterator end() { return data() + size(); }
+ ConstIterator begin() const { return data(); }
+ ConstIterator end() const { return data() + size(); }
+};
+
+
+#endif // QARRAY_H
diff --git a/qtools/qasciidict.h b/qtools/qasciidict.h
new file mode 100644
index 0000000..29fcf2f
--- /dev/null
+++ b/qtools/qasciidict.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+**
+** Definition of QAsciiDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QASCIIDICT_H
+#define QASCIIDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QAsciiDict : public QGDict
+{
+public:
+ QAsciiDict(int size=17, bool caseSensitive=TRUE, bool copyKeys=TRUE )
+ : QGDict(size,AsciiKey,caseSensitive,copyKeys) {}
+ QAsciiDict( const QAsciiDict<type> &d ) : QGDict(d) {}
+ ~QAsciiDict() { clear(); }
+ QAsciiDict<type> &operator=(const QAsciiDict<type> &d)
+ { return (QAsciiDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+
+ void insert( const char *k, const type *d )
+ { QGDict::look_ascii(k,(Item)d,1); }
+ void replace( const char *k, const type *d )
+ { QGDict::look_ascii(k,(Item)d,2); }
+ bool remove( const char *k ) { return QGDict::remove_ascii(k); }
+ type *take( const char *k ) { return (type *)QGDict::take_ascii(k); }
+ type *find( const char *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
+ type *operator[]( const char *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
+
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QAsciiDict<void>::deleteItem( Item )
+{
+}
+#endif
+
+template<class type> inline void QAsciiDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QAsciiDictIterator : public QGDictIterator
+{
+public:
+ QAsciiDictIterator(const QAsciiDict<type> &d)
+ : QGDictIterator((QGDict &)d) {}
+ ~QAsciiDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ const char *currentKey() const { return QGDictIterator::getKeyAscii(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QASCIIDICT_H
diff --git a/qtools/qbuffer.cpp b/qtools/qbuffer.cpp
new file mode 100644
index 0000000..f68ef54
--- /dev/null
+++ b/qtools/qbuffer.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+**
+** Implementation of QBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qbuffer.h"
+#include <stdlib.h>
+
+// REVISED: paul
+/*!
+ \class QBuffer qbuffer.h
+ \brief The QBuffer class is an I/O device that operates on a QByteArray
+
+ \ingroup io
+
+ QBuffer allows reading and writing a memory buffer. It is normally
+ used together with a QTextStream or a QDataStream. QBuffer has an
+ associated QByteArray which holds the buffer data. The size() of the
+ buffer is automatically adjusted as data is written.
+
+ The constructor \c QBuffer(QByteArray) creates a QBuffer with an
+ existing byte array. The byte array can also be set with setBuffer().
+ Writing to the QBuffer will modify the original byte array, since
+ QByteArray is \link shclass.html explicitly shared.\endlink
+
+ Use open() to open the buffer before use, and to set the mode
+ (read-only,write-only, etc.). close() closes the buffer. The buffer
+ must be closed before reopening or calling setBuffer().
+
+ The common way to use QBuffer is through \l QDataStream or \l QTextStream
+ which have constructors that take a QBuffer parameter. For
+ convenience, there are also QDataStream and QTextStream constructors
+ that take a QByteArray parameter. These constructors create and open
+ an internal QBuffer.
+
+ Note that QTextStream can also operate on a QString (a Unicode
+ string); a QBuffer cannot.
+
+ You can also use QBuffer directly through the standard QIODevice
+ functions readBlock(), writeBlock() readLine(), at(), getch(), putch() and
+ ungetch().
+
+ \sa QFile, QDataStream, QTextStream, QByteArray, \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ Constructs an empty buffer.
+*/
+
+QBuffer::QBuffer()
+{
+ setFlags( IO_Direct );
+ a_inc = 16; // initial increment
+ a_len = 0;
+ ioIndex = 0;
+}
+
+
+/*!
+ Constructs a buffer that operates on \a buf.
+ If you open the buffer in write mode (\c IO_WriteOnly or
+ \c IO_ReadWrite) and write something into the buffer, \a buf
+ will be modified.
+
+
+ Example:
+ \code
+ QCString str = "abc";
+ QBuffer b( str );
+ b.open( IO_WriteOnly );
+ b.at( 3 ); // position at \0
+ b.writeBlock( "def", 4 ); // write including \0
+ b.close();
+ // Now, str == "abcdef"
+ \endcode
+
+
+ \sa setBuffer()
+*/
+
+QBuffer::QBuffer( QByteArray buf ) : a(buf)
+{
+ setFlags( IO_Direct );
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+}
+
+/*!
+ Destructs the buffer.
+*/
+
+QBuffer::~QBuffer()
+{
+}
+
+
+/*!
+ Replaces the buffer's contents with \a buf.
+
+ This may not be done when isOpen() is TRUE.
+
+ Note that if you open the buffer in write mode (\c IO_WriteOnly or
+ IO_ReadWrite) and write something into the buffer, \a buf is also
+ modified because QByteArray is an explicitly shared class.
+
+ \sa buffer(), open(), close()
+*/
+
+bool QBuffer::setBuffer( QByteArray buf )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QBuffer::setBuffer: Buffer is open");
+#endif
+ return FALSE;
+ }
+ a = buf;
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+ return TRUE;
+}
+
+/*!
+ \fn QByteArray QBuffer::buffer() const
+
+ Returns this buffer's byte array.
+
+ \sa setBuffer()
+*/
+
+/*!
+ \reimp
+ Opens the buffer in the mode \a m. Returns TRUE if successful,
+ otherwise FALSE. The buffer must be opened before use.
+
+ The mode parameter \a m must be a combination of the following flags.
+ <ul>
+ <li>\c IO_ReadOnly opens a buffer in read-only mode.
+ <li>\c IO_WriteOnly opens a buffer in write-only mode.
+ <li>\c IO_ReadWrite opens a buffer in read/write mode.
+ <li>\c IO_Append sets the buffer index to the end of the buffer.
+ <li>\c IO_Truncate truncates the buffer.
+ </ul>
+
+ \sa close(), isOpen()
+*/
+
+bool QBuffer::open( int m )
+{
+ if ( isOpen() ) { // buffer already open
+#if defined(CHECK_STATE)
+ qWarning( "QBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate ) { // truncate buffer
+ a.resize( 0 );
+ a_len = 0;
+ }
+ if ( m & IO_Append ) { // append to end of buffer
+ ioIndex = a.size();
+ } else {
+ ioIndex = 0;
+ }
+ a_inc = 16;
+ setState( IO_Open );
+ setStatus( 0 );
+ return TRUE;
+}
+
+/*!
+ \reimp
+ Closes an open buffer.
+ \sa open()
+*/
+
+void QBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ a_inc = 16;
+ }
+}
+
+/*!
+ \reimp
+ The flush function does nothing for a QBuffer.
+*/
+
+void QBuffer::flush()
+{
+ return;
+}
+
+
+/*!
+ \fn int QBuffer::at() const
+ \reimp
+*/
+
+/*!
+ \fn uint QBuffer::size() const
+ \reimp
+*/
+
+/*!
+ \reimp
+*/
+
+bool QBuffer::at( int pos )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "QBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( (uint)pos > a_len ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QBuffer::at: Index %d out of range", pos );
+#endif
+ return FALSE;
+ }
+ ioIndex = pos;
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::readBlock( char *p, uint len )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len > a.size() ) { // overflow
+ if ( (uint)ioIndex >= a.size() ) {
+ setStatus( IO_ReadError );
+ return -1;
+ } else {
+ len = a.size() - (uint)ioIndex;
+ }
+ }
+ memcpy( p, a.data()+ioIndex, len );
+ ioIndex += len;
+ return len;
+}
+
+/*!
+ \reimp
+
+ Writes \a len bytes from \a p into the buffer at the current index,
+ overwriting any characters there and extending the buffer if necessary.
+ Returns the number of bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \sa readBlock()
+*/
+
+int QBuffer::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QBuffer::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len >= a_len ) { // overflow
+ uint new_len = a_len + a_inc*(((uint)ioIndex+len-a_len)/a_inc+1);
+ if ( !a.resize( new_len ) ) { // could not resize
+#if defined(CHECK_NULL)
+ qWarning( "QBuffer::writeBlock: Memory allocation error" );
+#endif
+ setStatus( IO_ResourceError );
+ return -1;
+ }
+ a_inc *= 2; // double increment
+ a_len = new_len;
+ a.shd->len = (uint)ioIndex + len;
+ }
+ memcpy( a.data()+ioIndex, p, len );
+ ioIndex += len;
+ if ( a.shd->len < (uint)ioIndex )
+ a.shd->len = (uint)ioIndex; // fake (not alloc'd) length
+ return len;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::readLine( char *p, uint maxlen )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::readLine: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( maxlen == 0 )
+ return 0;
+ uint start = (uint)ioIndex;
+ char *d = a.data() + ioIndex;
+ maxlen--; // make room for 0-terminator
+ if ( a.size() - (uint)ioIndex < maxlen )
+ maxlen = a.size() - (uint)ioIndex;
+ while ( maxlen-- ) {
+ if ( (*p++ = *d++) == '\n' )
+ break;
+ }
+ *p = '\0';
+ ioIndex = (int)(d - a.data());
+ return (uint)ioIndex - start;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex+1 > a.size() ) { // overflow
+ setStatus( IO_ReadError );
+ return -1;
+ }
+ return uchar(*(a.data()+ioIndex++));
+}
+
+/*!
+ \reimp
+ Writes the character \a ch into the buffer, overwriting
+ the character at the current index, extending the buffer
+ if necessary.
+
+ Returns \a ch, or -1 if some error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int QBuffer::putch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::putch: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QBuffer::putch: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + 1 >= a_len ) { // overflow
+ char buf[1];
+ buf[0] = (char)ch;
+ if ( writeBlock(buf,1) != 1 )
+ return -1; // write error
+ } else {
+ *(a.data() + ioIndex++) = (char)ch;
+ if ( a.shd->len < (uint)ioIndex )
+ a.shd->len = (uint)ioIndex;
+ }
+ return ch;
+}
+
+/*!
+ \reimp
+*/
+
+int QBuffer::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) {
+ if ( ioIndex )
+ ioIndex--;
+ else
+ ch = -1;
+ }
+ return ch;
+}
diff --git a/qtools/qbuffer.h b/qtools/qbuffer.h
new file mode 100644
index 0000000..9dcd286
--- /dev/null
+++ b/qtools/qbuffer.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+**
+** Definition of QBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QBUFFER_H
+#define QBUFFER_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#endif // QT_H
+
+
+class Q_EXPORT QBuffer : public QIODevice
+{
+public:
+ QBuffer();
+ QBuffer( QByteArray );
+ ~QBuffer();
+
+ QByteArray buffer() const;
+ bool setBuffer( QByteArray );
+
+ bool open( int );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const;
+ bool at( int );
+
+ int readBlock( char *p, uint );
+ int writeBlock( const char *p, uint );
+ int readLine( char *p, uint );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+protected:
+ QByteArray a;
+
+private:
+ uint a_len;
+ uint a_inc;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QBuffer( const QBuffer & );
+ QBuffer &operator=( const QBuffer & );
+#endif
+};
+
+
+inline QByteArray QBuffer::buffer() const
+{ return a; }
+
+inline uint QBuffer::size() const
+{ return a.size(); }
+
+inline int QBuffer::at() const
+{ return ioIndex; }
+
+
+#endif // QBUFFER_H
diff --git a/qtools/qcache.h b/qtools/qcache.h
new file mode 100644
index 0000000..e1f13d6
--- /dev/null
+++ b/qtools/qcache.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+**
+** Definition of QCache template class
+**
+** Created : 950209
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QCACHE_H
+#define QCACHE_H
+
+#ifndef QT_H
+#include "qgcache.h"
+#endif // QT_H
+
+#define USE_ASCII_STRING
+
+#ifndef USE_ASCII_STRING
+
+template<class type> class Q_EXPORT QCache : public QGCache
+{
+public:
+ QCache( const QCache<type> &c ) : QGCache(c) {}
+ QCache( int maxCost=100, int size=17, bool caseSensitive=TRUE )
+ : QGCache( maxCost, size, StringKey, caseSensitive, FALSE ) {}
+ ~QCache() { clear(); }
+ QCache<type> &operator=( const QCache<type> &c )
+ { return (QCache<type>&)QGCache::operator=(c); }
+ int maxCost() const { return QGCache::maxCost(); }
+ int totalCost() const { return QGCache::totalCost(); }
+ void setMaxCost( int m ) { QGCache::setMaxCost(m); }
+ uint count() const { return QGCache::count(); }
+ uint size() const { return QGCache::size(); }
+ bool isEmpty() const { return QGCache::count() == 0; }
+ void clear() { QGCache::clear(); }
+ bool insert( const QString &k, const type *d, int c=1, int p=0 )
+ { return QGCache::insert_string(k,(Item)d,c,p);}
+ bool remove( const QString &k )
+ { return QGCache::remove_string(k); }
+ type *take( const QString &k )
+ { return (type *)QGCache::take_string(k); }
+ type *find( const QString &k, bool ref=TRUE ) const
+ { return (type *)QGCache::find_string(k,ref);}
+ type *operator[]( const QString &k ) const
+ { return (type *)QGCache::find_string(k);}
+ void statistics() const { QGCache::statistics(); }
+ int hits() const { return QGCache::hits(); }
+ int misses() const { return QGCache::misses(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+#else
+
+
+template<class type> class Q_EXPORT QCache : public QGCache
+{
+public:
+ QCache( const QCache<type> &c ) : QGCache(c) {}
+ QCache( int maxCost=100, int size=17, bool caseSensitive=TRUE )
+ : QGCache( maxCost, size, AsciiKey, caseSensitive, TRUE ) {}
+ ~QCache() { clear(); }
+ QCache<type> &operator=( const QCache<type> &c )
+ { return (QCache<type>&)QGCache::operator=(c); }
+ int maxCost() const { return QGCache::maxCost(); }
+ int totalCost() const { return QGCache::totalCost(); }
+ void setMaxCost( int m ) { QGCache::setMaxCost(m); }
+ uint count() const { return QGCache::count(); }
+ uint size() const { return QGCache::size(); }
+ bool isEmpty() const { return QGCache::count() == 0; }
+ void clear() { QGCache::clear(); }
+ bool insert( const char *k, const type *d, int c=1, int p=0 )
+ { return QGCache::insert_other(k,(Item)d,c,p);}
+ bool remove( const char *k )
+ { return QGCache::remove_other(k); }
+ type *take( const char *k )
+ { return (type *)QGCache::take_other(k); }
+ type *find( const char *k, bool ref=TRUE ) const
+ { return (type *)QGCache::find_other(k,ref);}
+ type *operator[]( const char *k ) const
+ { return (type *)QGCache::find_other(k);}
+ void statistics() const { QGCache::statistics(); }
+ int hits() const { return QGCache::hits(); }
+ int misses() const { return QGCache::misses(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif
+
+
+
+template<class type> class Q_EXPORT QCacheIterator : public QGCacheIterator
+{
+public:
+ QCacheIterator( const QCache<type> &c ):QGCacheIterator((QGCache &)c) {}
+ QCacheIterator( const QCacheIterator<type> &ci)
+ : QGCacheIterator( (QGCacheIterator &)ci ) {}
+ QCacheIterator<type> &operator=(const QCacheIterator<type>&ci)
+ { return ( QCacheIterator<type>&)QGCacheIterator::operator=( ci ); }
+ uint count() const { return QGCacheIterator::count(); }
+ bool isEmpty() const { return QGCacheIterator::count() == 0; }
+ bool atFirst() const { return QGCacheIterator::atFirst(); }
+ bool atLast() const { return QGCacheIterator::atLast(); }
+ type *toFirst() { return (type *)QGCacheIterator::toFirst(); }
+ type *toLast() { return (type *)QGCacheIterator::toLast(); }
+ operator type *() const { return (type *)QGCacheIterator::get(); }
+ type *current() const { return (type *)QGCacheIterator::get(); }
+#ifndef USE_ASCII_STRING
+ QString currentKey() const{ return QGCacheIterator::getKeyString(); }
+#else
+ const char *currentKey() const{ return QGCacheIterator::getKeyAscii(); }
+#endif
+ type *operator()() { return (type *)QGCacheIterator::operator()();}
+ type *operator++() { return (type *)QGCacheIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGCacheIterator::operator+=(j);}
+ type *operator--() { return (type *)QGCacheIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)QGCacheIterator::operator-=(j);}
+};
+
+
+#endif // QCACHE_H
diff --git a/qtools/qcollection.cpp b/qtools/qcollection.cpp
new file mode 100644
index 0000000..e70b64b
--- /dev/null
+++ b/qtools/qcollection.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+**
+** Implementation of base class for all collection classes
+**
+** Created : 920820
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qcollection.h"
+
+// NOT REVISED
+/*!
+ \class QCollection qcollection.h
+ \brief The QCollection class is the base class of all Qt collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ The QCollection class is an abstract base class for the Qt \link
+ collection.html collection classes\endlink QDict, QList etc. via QGDict,
+ QGList etc.
+
+ A QCollection knows only about the number of objects in the
+ collection and the deletion strategy (see setAutoDelete()).
+
+ A collection is implemented using the \c Item (generic collection
+ item) type, which is a \c void*. The template classes that create
+ the real collections cast the \c Item to the required type.
+
+ \sa \link collection.html Collection Classes\endlink
+*/
+
+
+/*! \enum QCollection::Item
+
+ This type is the generic "item" in a QCollection.
+*/
+
+
+/*!
+ \fn QCollection::QCollection()
+
+ Constructs a collection. The constructor is protected because
+ QCollection is an abstract class.
+*/
+
+/*!
+ \fn QCollection::QCollection( const QCollection & source )
+
+ Constructs a copy of \a source with autoDelete() set to FALSE. The
+ constructor is protected because QCollection is an abstract class.
+
+ Note that if \a source has autoDelete turned on, copying it is a
+ good way to get memory leaks, reading freed memory, or both.
+*/
+
+/*!
+ \fn QCollection::~QCollection()
+ Destroys the collection. The destructor is protected because QCollection
+ is an abstract class.
+*/
+
+
+/*!
+ \fn bool QCollection::autoDelete() const
+ Returns the setting of the auto-delete option (default is FALSE).
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn void QCollection::setAutoDelete( bool enable )
+
+ Sets the auto-delete option of the collection.
+
+ Enabling auto-delete (\e enable is TRUE) will delete objects that
+ are removed from the collection. This can be useful if the
+ collection has the only reference to the objects. (Note that the
+ object can still be copied using the copy constructor - copying such
+ objects is a good way to get memory leaks, reading freed memory or
+ both.)
+
+ Disabling auto-delete (\e enable is FALSE) will \e not delete objects
+ that are removed from the collection. This is useful if the objects
+ are part of many collections.
+
+ The default setting is FALSE.
+
+ \sa autoDelete()
+*/
+
+
+/*!
+ \fn virtual uint QCollection::count() const
+ Returns the number of objects in the collection.
+*/
+
+/*!
+ \fn virtual void QCollection::clear()
+ Removes all objects from the collection. The objects will be deleted
+ if auto-delete has been enabled.
+ \sa setAutoDelete()
+*/
+
+
+/*!
+ Virtual function that creates a copy of an object that is about to
+ be inserted into the collection.
+
+ The default implementation returns the \e d pointer, i.e. no copy
+ is made.
+
+ This function is seldom reimplemented in the collection template
+ classes. It is not common practice to make a copy of something
+ that is being inserted.
+
+ \sa deleteItem()
+*/
+
+QCollection::Item QCollection::newItem( Item d )
+{
+ return d; // just return reference
+}
+
+/*!
+ Virtual function that deletes an item that is about to be removed from
+ the collection.
+
+ The default implementation deletes \e d pointer if and only if
+ auto-delete has been enabled.
+
+ This function is always reimplemented in the collection template
+ classes.
+
+ \warning If you reimplement this function you must also reimplement
+ the destructor and call the virtual function clear() from your
+ destructor. This is due to the way virtual functions and
+ destructors work in C++: virtual functions in derived classes cannot
+ be called from a destructor. If you do not do this your
+ deleteItem() function will not be called when the container is
+ destructed.
+
+ \sa newItem(), setAutoDelete()
+*/
+
+void QCollection::deleteItem( Item d )
+{
+ if ( del_item )
+#if defined(Q_DELETING_VOID_UNDEFINED)
+ delete (char *)d; // default operation
+#else
+ delete d; // default operation
+#endif
+}
diff --git a/qtools/qcollection.h b/qtools/qcollection.h
new file mode 100644
index 0000000..a169b7c
--- /dev/null
+++ b/qtools/qcollection.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+**
+** Definition of base class for all collection classes
+**
+** Created : 920629
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QCOLLECTION_H
+#define QCOLLECTION_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#endif // QT_H
+
+
+class QGVector;
+class QGList;
+class QGDict;
+
+
+class Q_EXPORT QCollection // inherited by all collections
+{
+public:
+ bool autoDelete() const { return del_item; }
+ void setAutoDelete( bool enable ) { del_item = enable; }
+
+ virtual uint count() const = 0;
+ virtual void clear() = 0; // delete all objects
+
+ typedef void *Item; // generic collection item
+
+protected:
+ QCollection() { del_item = FALSE; } // no deletion of objects
+ QCollection(const QCollection &) { del_item = FALSE; }
+ virtual ~QCollection() {}
+
+ bool del_item; // default FALSE
+
+ virtual Item newItem( Item ); // create object
+ virtual void deleteItem( Item ); // delete object
+};
+
+
+#endif // QCOLLECTION_H
diff --git a/qtools/qconfig.h b/qtools/qconfig.h
new file mode 100644
index 0000000..7a880f9
--- /dev/null
+++ b/qtools/qconfig.h
@@ -0,0 +1 @@
+// Everything
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
new file mode 100644
index 0000000..4038d55
--- /dev/null
+++ b/qtools/qcstring.cpp
@@ -0,0 +1,799 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "qcstring.h"
+#include "qgstring.h"
+
+#include <qstring.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <qregexp.h>
+#include <qdatastream.h>
+
+
+QCString::QCString(int size)
+{
+ if (size>0)
+ {
+ m_data = (char *)malloc(size);
+ if (m_data)
+ {
+ if (size>1) memset(m_data,' ',size-1);
+ m_data[size-1]='\0';
+ }
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+QCString::QCString( const QCString &s )
+{
+ duplicate(s);
+}
+
+QCString::QCString( const char *str )
+{
+ duplicate(str);
+}
+
+QCString::QCString( const char *str, uint maxlen )
+{
+ uint l;
+ if (str && ( l = QMIN(qstrlen(str),maxlen) ))
+ {
+ m_data=(char *)malloc(l+1);
+ strncpy(m_data,str,l+1);
+ m_data[l]='\0';
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+QCString::~QCString()
+{
+ if (m_data) free(m_data);
+ m_data=0;
+}
+
+QCString &QCString::assign( const char *str )
+{
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
+}
+
+bool QCString::resize( uint newlen )
+{
+ if (newlen==0)
+ {
+ if (m_data) { free(m_data); m_data=0; }
+ return TRUE;
+ }
+ if (m_data==0) // newlen>0
+ {
+ m_data = (char *)malloc(newlen);
+ }
+ else
+ {
+ m_data = (char *)realloc(m_data,newlen);
+ }
+ if (m_data==0) return FALSE;
+ m_data[newlen-1]='\0';
+ return TRUE;
+}
+
+bool QCString::fill( char c, int len )
+{
+ uint l=length();
+ if (len<0) len=l;
+ if ((uint)len!=l)
+ {
+ if (m_data) free(m_data);
+ if (len>0)
+ {
+ m_data=(char *)malloc(len+1);
+ if (m_data==0) return FALSE;
+ m_data[len]='\0';
+ }
+ else
+ {
+ m_data=0;
+ }
+ }
+ if (len>0)
+ {
+ uint i;
+ for (i=0;i<(uint)len;i++) m_data[i]=c;
+ }
+ return TRUE;
+}
+
+QCString &QCString::sprintf( const char *format, ... )
+{
+ va_list ap;
+ va_start( ap, format );
+ uint l = length();
+ const uint minlen=256;
+ if (l<minlen)
+ {
+ if (m_data)
+ m_data = (char *)realloc(m_data,minlen);
+ else
+ m_data = (char *)malloc(minlen);
+ }
+ vsprintf( m_data, format, ap );
+ resize( qstrlen(m_data) + 1 ); // truncate
+ va_end( ap );
+ return *this;
+}
+
+
+int QCString::find( char c, int index, bool cs ) const
+{
+ uint len = length();
+ if ( m_data==0 || (uint)index>len ) // index outside string
+ return -1;
+ register const char *d;
+ if ( cs ) // case sensitive
+ {
+ d = strchr( m_data+index, c );
+ }
+ else
+ {
+ d = m_data+index;
+ c = tolower( (uchar) c );
+ while ( *d && tolower((uchar) *d) != c )
+ d++;
+ if ( !*d && c ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - m_data) : -1;
+}
+
+int QCString::find( const char *str, int index, bool cs ) const
+{
+ uint l = length();
+ if ( m_data==0 || (uint)index > l ) // index outside string
+ return -1;
+ if ( !str ) // no search string
+ return -1;
+ if ( !*str ) // zero-length search string
+ return index;
+ register const char *d;
+ if ( cs ) // case sensitive
+ {
+ d = strstr( m_data+index, str );
+ }
+ else // case insensitive
+ {
+ d = m_data+index;
+ int len = qstrlen( str );
+ while ( *d )
+ {
+ if ( qstrnicmp(d, str, len) == 0 )
+ break;
+ d++;
+ }
+ if ( !*d ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - m_data) : -1;
+}
+
+int QCString::find( const QCString &str,int index,bool cs) const
+{
+ return find(str.data(),index,cs);
+}
+
+int QCString::find( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.find( rx, index );
+}
+
+int QCString::findRev( char c, int index, bool cs) const
+{
+ const char *b = m_data;
+ const char *d;
+ uint len = length();
+ if ( b == 0 ) return -1; // empty string
+ if ( index < 0 ) // neg index ==> start from end
+ {
+ if ( len == 0 ) return -1;
+ if ( cs )
+ {
+ d = strrchr( b, c );
+ return d ? (int)(d - b) : -1;
+ }
+ index = len;
+ }
+ else if ( (uint)index > len ) // bad index
+ {
+ return -1;
+ }
+ d = b+index;
+ if ( cs ) // case sensitive
+ {
+ while ( d >= b && *d != c )
+ d--;
+ }
+ else // case insensitive
+ {
+ c = tolower( (uchar) c );
+ while ( d >= b && tolower((uchar) *d) != c )
+ d--;
+ }
+ return d >= b ? (int)(d - b) : -1;
+}
+
+int QCString::findRev( const char *str, int index, bool cs) const
+{
+ int slen = qstrlen(str);
+ uint len = length();
+ if ( index < 0 ) // neg index ==> start from end
+ index = len-slen;
+ else if ( (uint)index > len ) // bad index
+ return -1;
+ else if ( (uint)(index + slen) > len ) // str would be too long
+ index = len - slen;
+ if ( index < 0 )
+ return -1;
+
+ register char *d = m_data + index;
+ if ( cs ) // case sensitive
+ {
+ for ( int i=index; i>=0; i-- )
+ if ( qstrncmp(d--,str,slen)==0 )
+ return i;
+ }
+ else // case insensitive
+ {
+ for ( int i=index; i>=0; i-- )
+ if ( qstrnicmp(d--,str,slen)==0 )
+ return i;
+ }
+ return -1;
+
+}
+
+int QCString::findRev( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.findRev( rx, index );
+}
+
+int QCString::contains( char c, bool cs ) const
+{
+ int count = 0;
+ char *d = m_data;
+ if ( !d )
+ return 0;
+ if ( cs ) // case sensitive
+ {
+ while ( *d )
+ if ( *d++ == c )
+ count++;
+ }
+ else // case insensitive
+ {
+ c = tolower( (uchar) c );
+ while ( *d ) {
+ if ( tolower((uchar) *d) == c )
+ count++;
+ d++;
+ }
+ }
+ return count;
+}
+
+int QCString::contains( const char *str, bool cs ) const
+{
+ int count = 0;
+ char *d = data();
+ if ( !d )
+ return 0;
+ int len = qstrlen( str );
+ while ( *d ) // counts overlapping strings
+ {
+ if ( cs )
+ {
+ if ( qstrncmp( d, str, len ) == 0 )
+ count++;
+ }
+ else
+ {
+ if ( qstrnicmp(d, str, len) == 0 )
+ count++;
+ }
+ d++;
+ }
+ return count;
+}
+
+int QCString::contains( const QRegExp &rx ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.contains( rx );
+}
+
+QCString QCString::left( uint len ) const
+{
+ if ( isEmpty() )
+ {
+ return QCString();
+ }
+ else if ( len >= length() )
+ {
+ return *this;
+ }
+ else
+ {
+ QCString s( len+1 );
+ strncpy( s.data(), m_data, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+QCString QCString::right( uint len ) const
+{
+ if ( isEmpty() )
+ {
+ return QCString();
+ }
+ else
+ {
+ uint l = length();
+ if ( len > l ) len = l;
+ char *p = m_data + (l - len);
+ return QCString( p );
+ }
+}
+
+QCString QCString::mid( uint index, uint len) const
+{
+ uint slen = length();
+ if ( len == 0xffffffff ) len = slen-index;
+ if ( isEmpty() || index >= slen )
+ {
+ return QCString();
+ }
+ else
+ {
+ register char *p = data()+index;
+ QCString s( len+1 );
+ strncpy( s.data(), p, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+QCString QCString::lower() const
+{
+ QCString s( m_data );
+ register char *p = s.data();
+ if ( p )
+ {
+ while ( *p )
+ {
+ *p = tolower((uchar) *p);
+ p++;
+ }
+ }
+ return s;
+}
+
+QCString QCString::upper() const
+{
+ QCString s( m_data );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = toupper((uchar)*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+QCString QCString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+
+ register char *s = m_data;
+ int reslen = length();
+ if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
+ return *this; // returns a copy
+
+ QCString result(s);
+ s = result.data();
+ int start = 0;
+ int end = reslen - 1;
+ while ( isspace((uchar) s[start]) ) // skip white space from start
+ start++;
+ if ( s[start] == '\0' )
+ { // only white space
+ return QCString();
+ }
+ while ( end && isspace((uchar) s[end]) ) // skip white space from end
+ end--;
+ end -= start - 1;
+ memmove( result.data(), &s[start], end );
+ result.resize( end + 1 );
+ return result;
+}
+
+QCString QCString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+
+ QCString result( length()+1 );
+ char *from = data();
+ char *to = result.data();
+ char *first = to;
+ while ( TRUE )
+ {
+ while ( *from && isspace((uchar) *from) )
+ from++;
+ while ( *from && !isspace((uchar)*from) )
+ *to++ = *from++;
+ if ( *from )
+ *to++ = 0x20; // ' '
+ else
+ break;
+ }
+ if ( to > first && *(to-1) == 0x20 )
+ to--;
+ *to = '\0';
+ result.resize( (int)((long)to - (long)result.data()) + 1 );
+ return result;
+}
+
+QCString &QCString::insert( uint index, const char *s )
+{
+ int len = s ? qstrlen(s) : 0;
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+ if ( index >= olen ) // insert after end of string
+ {
+ m_data = (char *)realloc(m_data,nlen+index-olen+1);
+ if ( m_data )
+ {
+ memset( m_data+olen, ' ', index-olen );
+ memcpy( m_data+index, s, len+1 );
+ }
+ }
+ else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert
+ {
+ memmove( m_data+index+len, m_data+index, olen-index+1 );
+ memcpy( m_data+index, s, len );
+ }
+ return *this;
+}
+
+QCString &QCString::insert( uint index, char c ) // insert char
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ return insert( index, buf );
+}
+
+QCString& QCString::operator+=( const char *str )
+{
+ if ( !str ) return *this; // nothing to append
+ uint len1 = length();
+ uint len2 = qstrlen(str);
+ char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
+ if (newData)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, str, len2 + 1 );
+ }
+ return *this;
+}
+
+QCString &QCString::operator+=( char c )
+{
+ uint len = length();
+ char *newData = (char *)realloc( m_data, length()+2 );
+ if (newData)
+ {
+ m_data = newData;
+ m_data[len] = c;
+ m_data[len+1] = '\0';
+ }
+ return *this;
+}
+
+QCString &QCString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) // range problems
+ {
+ if ( index < olen ) // index ok
+ {
+ resize( index+1 );
+ }
+ }
+ else if ( len != 0 )
+ {
+ memmove( m_data+index, m_data+index+len, olen-index-len+1 );
+ resize( olen-len+1 );
+ }
+ return *this;
+}
+
+QCString &QCString::replace( uint index, uint len, const char *s )
+{
+ remove( index, len );
+ insert( index, s );
+ return *this;
+}
+
+QCString &QCString::replace( const QRegExp &rx, const char *str )
+{
+ QString d = QString::fromLatin1( m_data );
+ QString r = QString::fromLatin1( str );
+ d.replace( rx, r );
+ operator=( d.ascii() );
+ return *this;
+}
+
+long QCString::toLong( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toLong(ok);
+}
+
+ulong QCString::toULong( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toULong(ok);
+}
+
+short QCString::toShort( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toShort(ok);
+}
+
+ushort QCString::toUShort( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toUShort(ok);
+}
+
+int QCString::toInt( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toInt(ok);
+}
+
+uint QCString::toUInt( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toUInt(ok);
+}
+
+QCString &QCString::setNum( long n )
+{
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if ( n < 0 )
+ {
+ neg = TRUE;
+ n = -n;
+ }
+ else
+ {
+ neg = FALSE;
+ }
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg ) *--p = '-';
+ operator=( p );
+ return *this;
+}
+
+QCString &QCString::setNum( ulong n )
+{
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ operator=( p );
+ return *this;
+}
+
+void QCString::msg_index( uint index )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QCString::at: Absolute index %d out of range", index );
+#else
+ Q_UNUSED( index )
+#endif
+}
+
+bool QCString::stripPrefix(const char *prefix)
+{
+ if (prefix==0) return FALSE;
+ uint plen = qstrlen(prefix);
+ if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
+ {
+ uint len = qstrlen(m_data);
+ uint newlen = len-plen+1;
+ qmemmove(m_data,m_data+plen,newlen);
+ resize(newlen);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+void *qmemmove( void *dst, const void *src, uint len )
+{
+ register char *d;
+ register char *s;
+ if ( dst > src ) {
+ d = (char *)dst + len - 1;
+ s = (char *)src + len - 1;
+ while ( len-- )
+ *d-- = *s--;
+ } else if ( dst < src ) {
+ d = (char *)dst;
+ s = (char *)src;
+ while ( len-- )
+ *d++ = *s++;
+ }
+ return dst;
+}
+
+char *qstrdup( const char *str )
+{
+ if ( !str )
+ return 0;
+ char *dst = new char[strlen(str)+1];
+ CHECK_PTR( dst );
+ return strcpy( dst, str );
+}
+
+char *qstrncpy( char *dst, const char *src, uint len )
+{
+ if ( !src )
+ return 0;
+ strncpy( dst, src, len );
+ if ( len > 0 )
+ dst[len-1] = '\0';
+ return dst;
+}
+
+int qstricmp( const char *str1, const char *str2 )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
+ for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
+ if ( !c ) // strings are equal
+ break;
+ return res;
+}
+
+int qstrnicmp( const char *str1, const char *str2, uint len )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return (int)((long)s2 - (long)s1);
+ for ( ; len--; s1++, s2++ ) {
+ if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
+ return res;
+ if ( !c ) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+QDataStream &operator<<( QDataStream &s, const QByteArray &a )
+{
+ return s.writeBytes( a.data(), a.size() );
+}
+
+QDataStream &operator>>( QDataStream &s, QByteArray &a )
+{
+ Q_UINT32 len;
+ s >> len; // read size of array
+ if ( len == 0 || s.eof() ) { // end of file reached
+ a.resize( 0 );
+ return s;
+ }
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QByteArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( a.data(), (uint)len );
+ return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const QCString &str )
+{
+ return s.writeBytes( str.data(), str.size() );
+}
+
+QDataStream &operator>>( QDataStream &s, QCString &str )
+{
+ Q_UINT32 len;
+ s >> len; // read size of string
+ if ( len == 0 || s.eof() ) { // end of file reached
+ str.resize( 0 );
+ return s;
+ }
+ if ( !str.resize( (uint)len )) {// resize string
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QCString" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( str.data(), (uint)len );
+ return s;
+}
+
+#endif //QT_NO_DATASTREAM
+
+inline QCString operator+( const QCString &s1, const QGString &s2 )
+{
+ QCString tmp(s1);
+ tmp += s2.data();
+ return tmp;
+}
+
+inline QCString operator+( const QGString &s1, const QCString &s2 )
+{
+ QCString tmp(s1.data());
+ tmp += s2;
+ return tmp;
+}
+
diff --git a/qtools/qcstring.h b/qtools/qcstring.h
new file mode 100644
index 0000000..f7d2c95
--- /dev/null
+++ b/qtools/qcstring.h
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+**
+** Definition of the extended char array operations,
+** and QByteArray and QCString classes
+**
+** Created : 920609
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QCSTRING_H
+#define QCSTRING_H
+
+#ifndef QT_H
+#include "qarray.h"
+#endif // QT_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(_OS_WIN32_) || defined(__MINGW32__)
+#include <stdint.h>
+#endif
+
+#if defined(_OS_SUN_) && defined(_CC_GNU_)
+#include <strings.h>
+#endif
+
+
+class QGString;
+
+/*****************************************************************************
+ Fixes and workarounds for some platforms
+ *****************************************************************************/
+
+#if defined(_OS_HPUX_)
+// HP-UX has badly defined strstr() etc.
+// ### fix in 3.0: change hack_* to qt_hack_*
+// by the way HP-UX is probably right, the standard has evolved and
+// we'll have to adapt to it
+inline char *hack_strstr( const char *s1, const char *s2 )
+{ return (char *)strstr(s1, s2); }
+inline char *hack_strchr( const char *s, int c )
+{ return (char *)strchr(s, c); }
+inline char *hack_strrchr( const char *s, int c )
+{ return (char *)strrchr(s, c); }
+#define strstr(s1,s2) hack_strstr((s1),(s2))
+#define strchr(s,c) hack_strchr((s),(c))
+#define strrchr(s,c) hack_strrchr((s),(c))
+#endif
+
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+Q_EXPORT void *qmemmove( void *dst, const void *src, uint len );
+
+#if defined(_OS_SUN_) || defined(_CC_OC_)
+#define memmove(s1,s2,n) qmemmove((s1),(s2),(n))
+#endif
+
+#if defined(_OS_WIN32_)
+#define qsnprintf _snprintf
+#else
+#define qsnprintf snprintf
+#endif
+
+Q_EXPORT char *qstrdup( const char * );
+
+Q_EXPORT inline uint cstrlen( const char *str )
+{ return (uint)strlen(str); }
+
+Q_EXPORT inline uint qstrlen( const char *str )
+{ return str ? (uint)strlen(str) : 0; }
+
+Q_EXPORT inline char *cstrcpy( char *dst, const char *src )
+{ return strcpy(dst,src); }
+
+Q_EXPORT inline char *qstrcpy( char *dst, const char *src )
+{ return src ? strcpy(dst, src) : 0; }
+
+Q_EXPORT char * qstrncpy(char *src,const char *dst, uint len);
+
+Q_EXPORT inline int cstrcmp( const char *str1, const char *str2 )
+{ return strcmp(str1,str2); }
+
+Q_EXPORT inline int qstrcmp( const char *str1, const char *str2 )
+{ return (str1 && str2) ? strcmp(str1,str2) : (int)((intptr_t)str2 - (intptr_t)str1); }
+
+Q_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len )
+{ return strncmp(str1,str2,len); }
+
+Q_EXPORT inline int qstrncmp( const char *str1, const char *str2, uint len )
+{ return (str1 && str2) ? strncmp(str1,str2,len) :
+ (int)((intptr_t)str2 - (intptr_t)str1); }
+
+Q_EXPORT int qstricmp( const char *str1, const char *str2 );
+
+Q_EXPORT int qstrnicmp( const char *str1, const char *str2, uint len );
+
+#if 0
+// ### TODO for 3.0: these and the cstr* functions should be used if
+// !defined(QT_CLEAN_NAMESPACE)
+// We want to keep source compatibility for 2.x
+// ### TODO for 4.0: completely remove these and the cstr* functions
+
+#if !defined(QT_GENUINE_STR)
+
+#undef strlen
+#define strlen qstrlen
+
+#undef strcpy
+#define strcpy qstrcpy
+
+#undef strcmp
+#define strcmp qstrcmp
+
+#undef strncmp
+#define strncmp qstrncmp
+
+#undef stricmp
+#define stricmp qstricmp
+
+#undef strnicmp
+#define strnicmp qstrnicmp
+
+#endif
+#endif
+
+// qChecksum: Internet checksum
+
+Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len );
+
+/*****************************************************************************
+ QByteArray class
+ *****************************************************************************/
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QArray<char>;
+#endif
+typedef QArray<char> QByteArray;
+
+
+/*****************************************************************************
+ QByteArray stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
+#endif
+
+class QRegExp;
+
+/** This is an alternative implementation of QCString. It provides basically
+ * the same functions but uses less memory for administration. This class
+ * is just a wrapper around a plain C string requiring only 4 bytes "overhead".
+ * QCString features sharing of data and stores the string length, but
+ * requires 4 + 12 bytes for this (even for the empty string). As doxygen
+ * uses a LOT of string during a run it saves a lot of memory to use a
+ * more memory efficient implementation at the cost of relatively low
+ * runtime overhead.
+ */
+class QCString
+{
+public:
+ QCString() : m_data(0) {} // make null string
+ QCString( const QCString &s );
+ QCString( int size );
+ QCString( const char *str );
+ QCString( const char *str, uint maxlen );
+ ~QCString();
+
+ QCString &operator=( const QCString &s );// deep copy
+ QCString &operator=( const char *str ); // deep copy
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ uint size() const { return m_data ? length()+1 : 0; }
+ char * data() const { return m_data; }
+ bool resize( uint newlen );
+ bool truncate( uint pos );
+ bool fill( char c, int len = -1 );
+
+ QCString copy() const;
+
+ QCString &sprintf( const char *format, ... );
+
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const char *str, int index=0, bool cs=TRUE ) const;
+ int find( const QCString &str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &, int index=0 ) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const char *str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &, int index=-1 ) const;
+ int contains( char c, bool cs=TRUE ) const;
+ int contains( const char *str, bool cs=TRUE ) const;
+ int contains( const QRegExp & ) const;
+ bool stripPrefix(const char *prefix);
+
+ QCString left( uint len ) const;
+ QCString right( uint len ) const;
+ QCString mid( uint index, uint len=0xffffffff) const;
+
+ QCString lower() const;
+ QCString upper() const;
+
+ QCString stripWhiteSpace() const;
+ QCString simplifyWhiteSpace() const;
+
+ QCString &assign( const char *str );
+ QCString &insert( uint index, const char * );
+ QCString &insert( uint index, char );
+ QCString &append( const char *s );
+ QCString &prepend( const char *s );
+ QCString &remove( uint index, uint len );
+ QCString &replace( uint index, uint len, const char * );
+ QCString &replace( const QRegExp &, const char * );
+
+ short toShort( bool *ok=0 ) const;
+ ushort toUShort( bool *ok=0 ) const;
+ int toInt( bool *ok=0 ) const;
+ uint toUInt( bool *ok=0 ) const;
+ long toLong( bool *ok=0 ) const;
+ ulong toULong( bool *ok=0 ) const;
+
+ QCString &setNum( short );
+ QCString &setNum( ushort );
+ QCString &setNum( int );
+ QCString &setNum( uint );
+ QCString &setNum( long );
+ QCString &setNum( ulong );
+ QCString &setNum( float, char f='g', int prec=6 );
+ QCString &setNum( double, char f='g', int prec=6 );
+
+ operator const char *() const;
+ QCString &operator+=( const char *str );
+ QCString &operator+=( char c );
+ char &at( uint index ) const;
+ char &operator[]( int i ) const { return at(i); }
+
+ private:
+ static void msg_index( uint );
+ void duplicate( const QCString &s );
+ void duplicate( const char *str);
+ QCString &duplicate( const char *str, int);
+
+ char * m_data;
+};
+
+inline char &QCString::at( uint index ) const
+{
+ return m_data[index];
+}
+
+inline void QCString::duplicate( const QCString &s )
+{
+ if (!s.isEmpty())
+ {
+ uint l = (uint)strlen(s.data());
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,s.data(),l+1);
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+inline void QCString::duplicate( const char *str)
+{
+ if (str && str[0]!='\0')
+ {
+ uint l = (uint)strlen(str);
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,str,l+1);
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+inline QCString &QCString::duplicate( const char *str, int)
+{
+ if (m_data==str) return *this;
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
+}
+
+/*****************************************************************************
+ QCString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QCString & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QCString & );
+#endif
+
+/*****************************************************************************
+ QCString inline functions
+ *****************************************************************************/
+
+inline QCString &QCString::operator=( const QCString &s )
+{ return (QCString&)assign( s ); }
+
+inline QCString &QCString::operator=( const char *str )
+{ return (QCString&)duplicate( str, qstrlen(str)+1 ); }
+
+inline bool QCString::isNull() const
+{ return data() == 0; }
+
+inline bool QCString::isEmpty() const
+{ return data() == 0 || *data() == '\0'; }
+
+inline uint QCString::length() const
+{ return qstrlen( data() ); }
+
+inline bool QCString::truncate( uint pos )
+{ return resize(pos+1); }
+
+inline QCString QCString::copy() const
+{ return QCString( data() ); }
+
+inline QCString &QCString::prepend( const char *s )
+{ return insert(0,s); }
+
+inline QCString &QCString::append( const char *s )
+{ return operator+=(s); }
+
+inline QCString &QCString::setNum( short n )
+{ return setNum((long)n); }
+
+inline QCString &QCString::setNum( ushort n )
+{ return setNum((ulong)n); }
+
+inline QCString &QCString::setNum( int n )
+{ return setNum((long)n); }
+
+inline QCString &QCString::setNum( uint n )
+{ return setNum((ulong)n); }
+
+inline QCString &QCString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline QCString::operator const char *() const
+{ return (const char *)data(); }
+
+
+/*****************************************************************************
+ QCString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT inline bool operator==( const QCString &s1, const QCString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) == 0; }
+
+Q_EXPORT inline bool operator==( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) == 0; }
+
+Q_EXPORT inline bool operator==( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) == 0; }
+
+Q_EXPORT inline bool operator!=( const QCString &s1, const QCString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) != 0; }
+
+Q_EXPORT inline bool operator!=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) != 0; }
+
+Q_EXPORT inline bool operator!=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) != 0; }
+
+Q_EXPORT inline bool operator<( const QCString &s1, const QCString& s2 )
+{ return qstrcmp(s1.data(),s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) < 0; }
+
+Q_EXPORT inline bool operator<( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) <= 0; }
+
+Q_EXPORT inline bool operator<=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) <= 0; }
+
+Q_EXPORT inline bool operator>( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) > 0; }
+
+Q_EXPORT inline bool operator>( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) > 0; }
+
+Q_EXPORT inline bool operator>=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) >= 0; }
+
+Q_EXPORT inline bool operator>=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) >= 0; }
+
+Q_EXPORT inline QCString operator+( const QCString &s1, const QCString &s2 )
+{
+ QCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+
+inline QCString operator+( const QCString &s1, const QGString &s2 );
+inline QCString operator+( const QGString &s1, const QCString &s2 );
+
+
+Q_EXPORT inline QCString operator+( const QCString &s1, const char *s2 )
+{
+ QCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( const char *s1, const QCString &s2 )
+{
+ QCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( const QCString &s1, char c2 )
+{
+ QCString tmp( s1.data() );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( char c1, const QCString &s2 )
+{
+ QCString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+inline const char *qPrint(const char *s)
+{
+ if (s) return s; else return "";
+}
+
+inline const char *qPrint(const QCString &s)
+{
+ if (!s.isEmpty()) return s.data(); else return "";
+}
+
+
+#endif // QCSTRING_H
diff --git a/qtools/qdatastream.cpp b/qtools/qdatastream.cpp
new file mode 100644
index 0000000..8505dd4
--- /dev/null
+++ b/qtools/qdatastream.cpp
@@ -0,0 +1,951 @@
+/****************************************************************************
+**
+**
+** Implementation of QDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qdatastream.h"
+
+#ifndef QT_NO_DATASTREAM
+#include "qbuffer.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+// REVISED: warwick
+/*!
+ \class QDataStream qdatastream.h
+
+ \brief The QDataStream class provides serialization of
+ binary data to a QIODevice.
+
+ \ingroup io
+
+ A data stream is a binary stream of encoded information which is 100%
+ independent of the host computer operation system, CPU or byte order. A
+ stream that is written by a PC under DOS/Windows can be read by a
+ Sun SPARC running Solaris.
+
+ The QDataStream class implements serialization of primitive types, like
+ \c char, \c short, \c int, \c char* etc. Serialization of more complex
+ data is accomplished by breaking up the data into primitive units.
+
+ The programmer can select which byte order to use when serializing data.
+ The default setting is big endian (MSB first). Changing it to little
+ endian breaks the portability (unless the reader also changes to little
+ endian). We recommend keeping this setting unless you have
+ special requirements.
+
+ A data stream cooperates closely with a QIODevice. A QIODevice
+ represents an input/output medium one can read data from and write data
+ to. The QFile class is an example of an IO device.
+
+ Example (write data to a stream):
+ \code
+ QFile f( "file.dta" );
+ f.open( IO_WriteOnly ); // open file for writing
+ QDataStream s( &f ); // serialize using f
+ s << "the answer is"; // serialize string
+ s << (Q_INT32)42; // serialize integer
+ \endcode
+
+ Example (read data from a stream):
+ \code
+ QFile f( "file.dta" );
+ f.open( IO_ReadOnly ); // open file for reading
+ QDataStream s( &f ); // serialize using f
+ char *str;
+ Q_INT32 a;
+ s >> str >> a; // "the answer is" and 42
+ delete str; // delete string
+ \endcode
+
+ In the last example, if you read into a QString instead of a \c char*
+ you do not have to delete it.
+
+ Normally, each item written to the stream is written in a fixed binary
+ format.
+ For example, a \c char* is written as a 32-bit integer equal to the
+ length of the string including the NUL byte, followed by all the
+ characters of the string including the NUL byte. Similarly when
+ reading a string, 4 bytes are read to create the 32-bit length value,
+ then that many characters for the string including the NUL. For a complete
+ description of all Qt types supporting data streaming see \link
+ datastreamformat.html Format of the QDataStream operators \endlink .
+
+ If you want a "parsing" input stream, see QTextStream. If you just want the
+ data to be human-readable to aid in debugging, you can set the data
+ stream into printable data mode with setPrintableData(). The data is
+ then written slower, in a human readable bloated form that is sufficient
+ for debugging.
+
+ If you are producing a new binary data format, such as a file format
+ for documents created by your application, you could use a QDataStream
+ to write the data in a portable format. Typically, you would write
+ a brief header containing a magic string and a version number to give
+ yourself room for future expansion. For example:
+
+ \code
+ // Open the file.
+ QFile f( "file.xxx" );
+ f.open( IO_WriteOnly );
+ QDataStream s( &f );
+
+ // Write a header with a "magic number" and a version
+ s << 0xa0b0c0d0;
+ s << 123;
+
+ // Write the data
+ s << [lots of interesting data]
+ \endcode
+
+ Then read it in with:
+
+ \code
+ // Open the file.
+ QFile f( "file.xxx" );
+ f.open( IO_ReadOnly );
+ QDataStream s( &f );
+
+ // Read and check the header
+ Q_UINT32 magic;
+ s >> magic;
+ if ( magic != 0xa0b0c0d0 )
+ return XXX_BAD_FILE_FORMAT;
+
+ // Read the version
+ Q_INT32 version;
+ s >> version;
+ if ( version < 100 )
+ return XXX_BAD_FILE_TOO_OLD;
+ if ( version > 123 )
+ return XXX_BAD_FILE_TOO_NEW;
+ if ( version <= 110 )
+ s.setVersion(1);
+
+ // Read the data
+ s >> [lots of interesting data];
+ if ( version > 120 )
+ s >> [data new in XXX version 1.2];
+ s >> [other interesting data];
+ \endcode
+
+ \sa QTextStream QVariant
+*/
+
+
+/*****************************************************************************
+ QDataStream member functions
+ *****************************************************************************/
+
+#if defined(CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "QDataStream: No device" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+static int systemWordSize = 0;
+static bool systemBigEndian;
+
+static const int DefaultStreamVersion = 3;
+// 3 is default in Qt 2.1
+// 2 is the Qt 2.0.x format
+// 1 is the Qt 1.x format
+
+/*!
+ Constructs a data stream that has no IO device.
+
+ \sa setDevice()
+*/
+
+QDataStream::QDataStream()
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = 0; // no device set
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that uses the IO device \a d.
+
+ \sa setDevice(), device()
+*/
+
+QDataStream::QDataStream( QIODevice *d )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = d; // set device
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that operates on a byte array through an
+ internal QBuffer device.
+
+ Example:
+ \code
+ static char bindata[] = { 231, 1, 44, ... };
+ QByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ QDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> [something]; // read raw bindata
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ The QArray::setRawData() function is not for the inexperienced.
+*/
+
+QDataStream::QDataStream( QByteArray a, int mode )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = new QBuffer( a ); // create device
+ ((QBuffer *)dev)->open( mode ); // open device
+ owndev = TRUE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Destructs the data stream.
+
+ The destructor will not affect the current IO device, unless it
+ is an internal IO device processing a QByteArray passed in the constructor.
+*/
+
+QDataStream::~QDataStream()
+{
+ if ( owndev )
+ delete dev;
+}
+
+
+/*!
+ \fn QIODevice *QDataStream::device() const
+ Returns the IO device currently set.
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ void QDataStream::setDevice(QIODevice *d )
+ Sets the IO device to \a d.
+ \sa device(), unsetDevice()
+*/
+
+void QDataStream::setDevice(QIODevice *d )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = d;
+}
+
+/*!
+ Unsets the IO device. This is the same as calling setDevice( 0 ).
+ \sa device(), setDevice()
+*/
+
+void QDataStream::unsetDevice()
+{
+ setDevice( 0 );
+}
+
+
+/*!
+ \fn bool QDataStream::atEnd() const
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!\fn bool QDataStream::eof() const
+
+ \obsolete
+
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!
+ \fn int QDataStream::byteOrder() const
+ Returns the current byte order setting - either \c BigEndian or
+ \c LittleEndian.
+
+ \sa setByteOrder()
+*/
+
+/*!
+ Sets the serialization byte order to \a bo.
+
+ The \a bo parameter can be \c QDataStream::BigEndian or
+ \c QDataStream::LittleEndian.
+
+ The default setting is big endian. We recommend leaving this setting unless
+ you have special requirements.
+
+ \sa byteOrder()
+*/
+
+void QDataStream::setByteOrder( int bo )
+{
+ byteorder = bo;
+ if ( systemBigEndian )
+ noswap = byteorder == BigEndian;
+ else
+ noswap = byteorder == LittleEndian;
+}
+
+
+/*!
+ \fn bool QDataStream::isPrintableData() const
+ Returns TRUE if the printable data flag has been set.
+ \sa setPrintableData()
+*/
+
+/*!
+ \fn void QDataStream::setPrintableData( bool enable )
+ Sets or clears the printable data flag.
+
+ If this flag is set, the write functions will generate output that
+ consists of printable characters (7 bit ASCII).
+
+ We recommend enabling printable data only for debugging purposes
+ (it is slower and creates larger output).
+*/
+
+
+/*!
+ \fn int QDataStream::version() const
+ Returns the version number of the data serialization format.
+ In Qt 2.1, this number is by default 3.
+ \sa setVersion()
+*/
+
+/*!
+ \fn void QDataStream::setVersion( int v )
+ Sets the version number of the data serialization format.
+
+ In order to accomodate for new functionality, the datastream
+ serialization format of some Qt classes has changed in some versions of
+ Qt. If you want to read data that was created by an earlier version of
+ Qt, or write data that can be read by a program that was compiled with
+ an earlier version of Qt, use this function to modify the serialization
+ format of QDataStream.
+
+ For Qt 1.x compatibility, use \a v == 1.
+
+ For Qt 2.0.x compatibility, use \a v == 2 (Not required for reading in
+ Qt 2.1).
+
+ \sa version()
+*/
+
+/*****************************************************************************
+ QDataStream read functions
+ *****************************************************************************/
+
+
+static Q_INT32 read_int_ascii( QDataStream *s )
+{
+ register int n = 0;
+ char buf[40];
+ while ( TRUE ) {
+ buf[n] = s->device()->getch();
+ if ( buf[n] == '\n' || n > 38 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+ return (Q_INT32)atol( buf );
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT8 &i )
+ Reads an unsigned byte from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed byte from the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT8 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (Q_INT8)dev->getch();
+ if ( i == '\\' ) { // read octal code
+ char buf[4];
+ dev->readBlock( buf, 3 );
+ i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
+ }
+ } else { // data or text
+ i = (Q_INT8)dev->getch();
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT16 &i )
+ Reads an unsigned 16-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed 16-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT16 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (Q_INT16)read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ dev->readBlock( b, 2 );
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT32 &i )
+ Reads an unsigned 32-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed 32-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT32 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT32) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT64 &i )
+ Reads an unsigned 64-bit integer from the stream and returns a reference to
+ the stream, or uses the Q_UINT32 operator if 64 bit is not available.
+*/
+
+/*!
+ Reads a signed 64-bit integer from the stream and returns a reference to
+ the stream, or uses the Q_UINT32 operator if 64 bit is not available.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT64 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT64) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(Q_INT64)];
+ dev->readBlock( b, sizeof(Q_INT64) );
+ if ( sizeof(Q_INT64) == 8 ) {
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ }
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+static double read_double_ascii( QDataStream *s )
+{
+ register int n = 0;
+ char buf[80];
+ while ( TRUE ) {
+ buf[n] = s->device()->getch();
+ if ( buf[n] == '\n' || n > 78 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+ return atof( buf );
+}
+
+
+/*!
+ Reads a 32-bit floating point number from the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = (float)read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(float) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ Reads a 64-bit floating point number from the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ dev->readBlock( b, 8 );
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ Reads the '\0'-terminated string \a s from the stream and returns
+ a reference to the stream.
+
+ Space for the string is allocated using \c new - the caller must
+ eventually call delete[] on the value.
+*/
+
+QDataStream &QDataStream::operator>>( char *&s )
+{
+ uint len = 0;
+ return readBytes( s, len );
+}
+
+
+/*!
+ Reads the buffer \a s from the stream and returns a reference to the
+ stream.
+
+ The buffer \a s is allocated using \c new. Destroy it with the \c delete[]
+ operator. If the length is zero or \a s cannot be allocated, \a s is
+ set to 0.
+
+ The \a l parameter will be set to the length of the buffer.
+
+ The serialization format is an Q_UINT32 length specifier first, then the
+ data (\a l bytes).
+
+ \sa readRawBytes(), writeBytes()
+*/
+
+QDataStream &QDataStream::readBytes( char *&s, uint &l )
+{
+ CHECK_STREAM_PRECOND
+ Q_UINT32 len;
+ *this >> len; // first read length spec
+ l = (uint)len;
+ if ( len == 0 || eof() ) {
+ s = 0;
+ return *this;
+ } else {
+ s = new char[len]; // create char array
+ CHECK_PTR( s );
+ if ( !s ) // no memory
+ return *this;
+ return readRawBytes( s, (uint)len );
+ }
+}
+
+
+/*!
+ Reads \a len bytes from the stream into \a s and returns a reference to
+ the stream.
+
+ The buffer \a s must be preallocated.
+
+ \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
+*/
+
+QDataStream &QDataStream::readRawBytes( char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ register Q_INT8 *p = (Q_INT8*)s;
+ while ( len-- )
+ *this >> *p++;
+ } else { // read data char array
+ dev->readBlock( s, len );
+ }
+ return *this;
+}
+
+
+/*****************************************************************************
+ QDataStream write functions
+ *****************************************************************************/
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT8 i )
+ Writes an unsigned byte to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Writes a signed byte to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT8 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable && (i == '\\' || !isprint(i)) ) {
+ char buf[6]; // write octal code
+ buf[0] = '\\';
+ buf[1] = '0' + ((i >> 6) & 0x07);
+ buf[2] = '0' + ((i >> 3) & 0x07);
+ buf[3] = '0' + (i & 0x07);
+ buf[4] = '\0';
+ dev->writeBlock( buf, 4 );
+ } else {
+ dev->putch( i );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT16 i )
+ Writes an unsigned 16-bit integer to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ Writes a signed 16-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT16 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 2 );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT32 i )
+ Writes an unsigned 32-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Writes a signed 32-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT32 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT64 i )
+ Writes an unsigned 64-bit integer to the stream and returns a reference to
+ the stream, or uses the Q_UINT32-operator if 64 bit is not available.
+*/
+
+/*!
+ Writes a signed 64-bit integer to the stream and returns a reference to
+ the stream, or calls the Q_INT32-operator if 64 bit is not available.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT64 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[20];
+ sprintf( buf, "%ld\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT64) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(Q_INT64)];
+ if ( sizeof(Q_INT64) == 8 ) {
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ }
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, sizeof(Q_INT64) );
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( uint i )
+ Writes an unsigned integer to the stream as a 32-bit unsigned integer
+ (Q_UINT32).
+ Returns a reference to the stream.
+*/
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( int i )
+ Writes a signed integer to the stream as a 32-bit signed integer (Q_INT32).
+ Returns a reference to the stream.
+*/
+
+
+/*!
+ Writes a 32-bit floating point number to the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( float f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[32];
+ sprintf( buf, "%g\n", (double)f );
+ dev->writeBlock( buf, strlen(buf) );
+ } else {
+ float g = f; // fixes float-on-stack problem
+ if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&g, sizeof(float) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&g);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ }
+ return *this;
+}
+
+
+/*!
+ Writes a 64-bit floating point number to the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[32];
+ sprintf( buf, "%g\n", f );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 8 );
+ }
+ return *this;
+}
+
+
+/*!
+ Writes the '\0'-terminated string \a s to the stream and returns
+ a reference to the stream.
+
+ The string is serialized using writeBytes().
+*/
+
+QDataStream &QDataStream::operator<<( const char *s )
+{
+ if ( !s ) {
+ *this << (Q_UINT32)0;
+ return *this;
+ }
+ uint len = qstrlen( s ) + 1; // also write null terminator
+ *this << (Q_UINT32)len; // write length specifier
+ return writeRawBytes( s, len );
+}
+
+
+/*!
+ Writes the length specifier \a len and the buffer \a s to the stream and
+ returns a reference to the stream.
+
+ The \a len is serialized as an Q_UINT32, followed by \a len bytes from
+ \a s.
+
+ \sa writeRawBytes(), readBytes()
+*/
+
+QDataStream &QDataStream::writeBytes(const char *s, uint len)
+{
+ CHECK_STREAM_PRECOND
+ *this << (Q_UINT32)len; // write length specifier
+ if ( len )
+ writeRawBytes( s, len );
+ return *this;
+}
+
+
+/*!
+ Writes \a len bytes from \a s to the stream and returns a reference to the
+ stream.
+
+ \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
+*/
+
+QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // write printable
+ register char *p = (char *)s;
+ while ( len-- )
+ *this << *p++;
+ } else { // write data char array
+ dev->writeBlock( s, len );
+ }
+ return *this;
+}
+
+#endif // QT_NO_DATASTREAM
diff --git a/qtools/qdatastream.h b/qtools/qdatastream.h
new file mode 100644
index 0000000..3d18062
--- /dev/null
+++ b/qtools/qdatastream.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+**
+** Definition of QDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QDATASTREAM_H
+#define QDATASTREAM_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_DATASTREAM
+class Q_EXPORT QDataStream // data stream class
+{
+public:
+ QDataStream();
+ QDataStream( QIODevice * );
+ QDataStream( QByteArray, int mode );
+ virtual ~QDataStream();
+
+ QIODevice *device() const;
+ void setDevice( QIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ enum ByteOrder { BigEndian, LittleEndian };
+ int byteOrder() const;
+ void setByteOrder( int );
+
+ bool isPrintableData() const;
+ void setPrintableData( bool );
+
+ int version() const;
+ void setVersion( int );
+
+ QDataStream &operator>>( Q_INT8 &i );
+ QDataStream &operator>>( Q_UINT8 &i );
+ QDataStream &operator>>( Q_INT16 &i );
+ QDataStream &operator>>( Q_UINT16 &i );
+ QDataStream &operator>>( Q_INT32 &i );
+ QDataStream &operator>>( Q_UINT32 &i );
+ QDataStream &operator>>( Q_INT64 &i );
+ QDataStream &operator>>( Q_UINT64 &i );
+
+ QDataStream &operator>>( float &f );
+ QDataStream &operator>>( double &f );
+ QDataStream &operator>>( char *&str );
+
+ QDataStream &operator<<( Q_INT8 i );
+ QDataStream &operator<<( Q_UINT8 i );
+ QDataStream &operator<<( Q_INT16 i );
+ QDataStream &operator<<( Q_UINT16 i );
+ QDataStream &operator<<( Q_INT32 i );
+ QDataStream &operator<<( Q_UINT32 i );
+ QDataStream &operator<<( Q_INT64 i );
+ QDataStream &operator<<( Q_UINT64 i );
+ QDataStream &operator<<( float f );
+ QDataStream &operator<<( double f );
+ QDataStream &operator<<( const char *str );
+
+ QDataStream &readBytes( char *&, uint &len );
+ QDataStream &readRawBytes( char *, uint len );
+
+ QDataStream &writeBytes( const char *, uint len );
+ QDataStream &writeRawBytes( const char *, uint len );
+
+private:
+ QIODevice *dev;
+ bool owndev;
+ int byteorder;
+ bool printable;
+ bool noswap;
+ int ver;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QDataStream( const QDataStream & );
+ QDataStream &operator=( const QDataStream & );
+#endif
+};
+
+
+/*****************************************************************************
+ QDataStream inline functions
+ *****************************************************************************/
+
+inline QIODevice *QDataStream::device() const
+{ return dev; }
+
+inline bool QDataStream::atEnd() const
+{ return dev ? dev->atEnd() : TRUE; }
+
+inline bool QDataStream::eof() const
+{ return atEnd(); }
+
+inline int QDataStream::byteOrder() const
+{ return byteorder; }
+
+inline bool QDataStream::isPrintableData() const
+{ return printable; }
+
+inline void QDataStream::setPrintableData( bool p )
+{ printable = p; }
+
+inline int QDataStream::version() const
+{ return ver; }
+
+inline void QDataStream::setVersion( int v )
+{ ver = v; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT8 &i )
+{ return *this >> (Q_INT8&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT16 &i )
+{ return *this >> (Q_INT16&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT32 &i )
+{ return *this >> (Q_INT32&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT64 &i )
+{ return *this >> (Q_INT64&)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT8 i )
+{ return *this << (Q_INT8)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT16 i )
+{ return *this << (Q_INT16)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT32 i )
+{ return *this << (Q_INT32)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT64 i )
+{ return *this << (Q_INT64)i; }
+
+
+#endif // QT_NO_DATASTREAM
+#endif // QDATASTREAM_H
diff --git a/qtools/qdatetime.cpp b/qtools/qdatetime.cpp
new file mode 100644
index 0000000..d0cc36e
--- /dev/null
+++ b/qtools/qdatetime.cpp
@@ -0,0 +1,1434 @@
+/****************************************************************************
+**
+**
+** Implementation of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#define gettimeofday __hide_gettimeofday
+#include "qdatetime.h"
+#include "qdatastream.h"
+#include <stdio.h>
+#include <time.h>
+#if defined(_OS_WIN32_)
+#if defined(_CC_BOOL_DEF_)
+#undef bool
+#include <windows.h>
+#define bool int
+#else
+#include <windows.h>
+#endif
+#elif defined(_OS_MSDOS_)
+#include <dos.h>
+#elif defined(_OS_OS2_)
+#include <os2.h>
+#elif defined(_OS_UNIX_) || defined(_OS_MAC_)
+#include <sys/time.h>
+#include <unistd.h>
+#undef gettimeofday
+extern "C" int gettimeofday( struct timeval *, struct timezone * );
+#endif
+
+static const uint FIRST_DAY = 2361222; // Julian day for 1752/09/14
+static const int FIRST_YEAR = 1752; // ### wrong for many countries
+static const uint SECS_PER_DAY = 86400;
+static const uint MSECS_PER_DAY = 86400000;
+static const uint SECS_PER_HOUR = 3600;
+static const uint MSECS_PER_HOUR= 3600000;
+static const uint SECS_PER_MIN = 60;
+static const uint MSECS_PER_MIN = 60000;
+
+static const short monthDays[] ={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+// ##### Localize.
+
+const char * const QDate::monthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+const char * const QDate::weekdayNames[] ={
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+
+
+/*****************************************************************************
+ QDate member functions
+ *****************************************************************************/
+
+// REVISED: aavit
+
+/*!
+ \class QDate qdatetime.h
+ \brief The QDate class provides date functions.
+
+ \ingroup time
+
+ A QDate object contains a calendar date, i.e. year, month, and day
+ numbers in the modern western (Gregorian) calendar. It can read the
+ current date from the system clock. It provides functions for
+ comparing dates and for manipulating a date by adding a number of
+ days.
+
+ A QDate object is typically created either by giving the year, month
+ and day numbers explicitly, or by using the static function
+ currentDate(), which makes a QDate object which contains the
+ system's clock date. An explicit date can also be set using
+ setYMD().
+
+ The year(), month(), and day() functions provide access to the year,
+ month, and day numbers. Also, dayOfWeek() and dayOfYear() functions
+ are provided. The same information is provided in textual format by
+ the toString(), dayName(), and monthName() functions.
+
+ QDate provides a full set of operators to compare two QDate
+ objects. A date is considered smaller than another if it is earlier
+ than the other.
+
+ The date a given number of days later than a given date can be found
+ using the addDays() function. Correspondingly, the number of days
+ between two dates can be found using the daysTo() function.
+
+ The daysInMonth() and daysInYear() functions tell how many days
+ there are in this date's month and year, respectively. The
+ isLeapYear() function tells whether this date is in a leap year.
+
+ Note that QDate may not be used for date calculations for dates in
+ the remote past, i.e. prior to the introduction of the Gregorian
+ calendar. This calendar was adopted by England Sep. 14. 1752 (hence
+ this is the earliest valid QDate), and subsequently by most other
+ western countries, until 1923.
+
+ The end of time is reached around 8000AD, by which time we expect Qt
+ to be obsolete.
+
+ \sa QTime, QDateTime
+*/
+
+
+/*!
+ \fn QDate::QDate()
+ Constructs a null date. Null dates are invalid.
+
+ \sa isNull(), isValid()
+*/
+
+
+/*!
+ Constructs a date with the year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752-ca. 8000, \a m must be in the range
+ 1-12, and \a d must be in the range 1-31. Exception: if \a y is in
+ the range 0-99, it is interpreted as 1900-1999.
+
+ \sa isValid()
+*/
+
+QDate::QDate( int y, int m, int d )
+{
+ jd = 0;
+ setYMD( y, m, d );
+}
+
+
+/*!
+ \fn bool QDate::isNull() const
+
+ Returns TRUE if the date is null. A null date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Returns TRUE if this date is valid.
+
+ \sa isNull()
+*/
+
+bool QDate::isValid() const
+{
+ return jd >= FIRST_DAY;
+}
+
+
+/*!
+ Returns the year (>= 1752) of this date.
+
+ \sa month(), day()
+*/
+
+int QDate::year() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return y;
+}
+
+/*!
+ Returns the month (January=1 .. December=12) of this date.
+
+ \sa year(), day()
+*/
+
+int QDate::month() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return m;
+}
+
+/*!
+ Returns the day of the month (1..31) of this date.
+
+ \sa year(), month(), dayOfWeek()
+*/
+
+int QDate::day() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return d;
+}
+
+/*!
+ Returns the weekday (Monday=1 .. Sunday=7) for this date.
+
+ \sa day(), dayOfYear()
+*/
+
+int QDate::dayOfWeek() const
+{
+ return (((jd+1) % 7) + 6)%7 + 1;
+}
+
+/*!
+ Returns the day of the year (1..365) for this date.
+
+ \sa day(), dayOfWeek()
+*/
+
+int QDate::dayOfYear() const
+{
+ return jd - greg2jul(year(), 1, 1) + 1;
+}
+
+/*!
+ Returns the number of days in the month (28..31) for this date.
+
+ \sa day(), daysInYear()
+*/
+
+int QDate::daysInMonth() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ if ( m == 2 && leapYear(y) )
+ return 29;
+ else
+ return monthDays[m];
+}
+
+/*!
+ Returns the number of days in the year (365 or 366) for this date.
+
+ \sa day(), daysInMonth()
+*/
+
+int QDate::daysInYear() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return leapYear(y) ? 366 : 365;
+}
+
+
+/*!
+ Returns the name of the \a month.
+
+ Month 1 == "Jan", month 2 == "Feb" etc.
+
+ \sa toString(), dayName()
+*/
+
+QString QDate::monthName( int month ) const
+{
+#if defined(CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "QDate::monthName: Parameter out ouf range." );
+ month = 1;
+ }
+#endif
+ // ### Remove the fromLatin1 during localization
+ return QString::fromLatin1(monthNames[month-1]);
+}
+
+/*!
+ Returns the name of the \a weekday.
+
+ Weekday 1 == "Mon", day 2 == "Tue" etc.
+
+ \sa toString(), monthName()
+*/
+
+QString QDate::dayName( int weekday ) const
+{
+#if defined(CHECK_RANGE)
+ if ( weekday < 1 || weekday > 7 ) {
+ qWarning( "QDate::dayName: Parameter out of range." );
+ weekday = 1;
+ }
+#endif
+ // ### Remove the fromLatin1 during localization
+ return QString::fromLatin1(weekdayNames[weekday-1]);
+}
+
+
+/*!
+ Returns the date as a string.
+
+ The string format is "Sat May 20 1995". This function uses the
+ dayName() and monthName() functions to generate the string.
+
+ \sa dayName(), monthName()
+*/
+
+QString QDate::toString() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ QString buf = dayName(dayOfWeek());
+ buf += ' ';
+ buf += monthName(m);
+ QString t;
+ t.sprintf( " %d %d", d, y);
+ buf += t;
+ return buf;
+}
+
+
+/*!
+ Sets the year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752-ca. 8000, \a m must be in the range
+ 1-12, and \a d must be in the range 1-31. Exception: if \a y is in
+ the range 0-99, it is interpreted as 1900-1999.
+
+ Returns TRUE if the date is valid, otherwise FALSE.
+*/
+
+bool QDate::setYMD( int y, int m, int d )
+{
+ if ( !isValid(y,m,d) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QDate::setYMD: Invalid date %04d/%02d/%02d", y, m, d );
+#endif
+ return FALSE;
+ }
+ jd = greg2jul( y, m, d );
+#if defined(DEBUG)
+ ASSERT( year() == (y > 99 ? y : 1900+y) && month() == m && day() == d );
+#endif
+ return TRUE;
+}
+
+/*!
+ Returns a QDate object containing a date \a ndays later than the
+ date of this object (or earlier if \a ndays is negative).
+
+ \sa daysTo()
+*/
+
+QDate QDate::addDays( int ndays ) const
+{
+ QDate d;
+ d.jd = jd + ndays;
+ return d;
+}
+
+/*!
+ Returns the number of days from this date to \a d (which is negative
+ if \a d is earlier than this date).
+
+ Example:
+ \code
+ QDate d1( 1995, 5, 17 ); // May 17th 1995
+ QDate d2( 1995, 5, 20 ); // May 20th 1995
+ d1.daysTo( d2 ); // returns 3
+ d2.daysTo( d1 ); // returns -3
+ \endcode
+
+ \sa addDays()
+*/
+
+int QDate::daysTo( const QDate &d ) const
+{
+ return d.jd - jd;
+}
+
+
+/*!
+ \fn bool QDate::operator==( const QDate &d ) const
+ Returns TRUE if this date is equal to \a d, or FALSE if
+ they are different.
+*/
+
+/*!
+ \fn bool QDate::operator!=( const QDate &d ) const
+ Returns TRUE if this date is different from \a d, or FALSE if
+ they are equal.
+*/
+
+/*!
+ \fn bool QDate::operator<( const QDate &d ) const
+ Returns TRUE if this date is earlier than \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator<=( const QDate &d ) const
+ Returns TRUE if this date is earlier than or equal to \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator>( const QDate &d ) const
+ Returns TRUE if this date is later than \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator>=( const QDate &d ) const
+ Returns TRUE if this date is later than or equal to \a d, otherwise FALSE.
+*/
+
+
+/*!
+ Returns the current date, as reported by the system clock.
+
+ \sa QTime::currentTime(), QDateTime::currentDateTime()
+*/
+
+QDate QDate::currentDate()
+{
+#if defined(_OS_WIN32_)
+
+ SYSTEMTIME t;
+ GetLocalTime( &t );
+ QDate d;
+ d.jd = greg2jul( t.wYear, t.wMonth, t.wDay );
+ return d;
+
+#else
+
+ time_t ltime;
+ time( <ime );
+ tm *t = localtime( <ime );
+ QDate d;
+ d.jd = greg2jul( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
+ return d;
+
+#endif
+}
+
+/*!
+ Returns TRUE if the specified date (year \a y, month \a m and day \a
+ d) is valid.
+
+ Example:
+ \code
+ QDate::isValid( 2002, 5, 17 ); // TRUE; May 17th 2002 is OK.
+ QDate::isValid( 2002, 2, 30 ); // FALSE; Feb 30th does not exist
+ QDate::isValid( 2004, 2, 29 ); // TRUE; 2004 is a leap year
+ QDate::isValid( 1202, 6, 6 ); // FALSE; 1202 is pre-Gregorian
+ \endcode
+
+ Note that a \a y value in the range 00-99 is interpreted as
+ 1900-1999.
+
+ \sa isNull(), setYMD()
+*/
+
+bool QDate::isValid( int y, int m, int d )
+{
+ if ( y >= 0 && y <= 99 )
+ y += 1900;
+ else if ( y < FIRST_YEAR || (y == FIRST_YEAR && (m < 9 ||
+ (m == 9 && d < 14))) )
+ return FALSE;
+ return (d > 0 && m > 0 && m <= 12) &&
+ (d <= monthDays[m] || (d == 29 && m == 2 && leapYear(y)));
+}
+
+/*!
+ Returns TRUE if the specified year \a y is a leap year.
+*/
+
+bool QDate::leapYear( int y )
+{
+ return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
+}
+
+/*!
+ \internal
+ Converts a Gregorian date to a Julian day.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa jul2greg()
+*/
+
+uint QDate::greg2jul( int y, int m, int d )
+{
+ uint c, ya;
+ if ( y <= 99 )
+ y += 1900;
+ if ( m > 2 ) {
+ m -= 3;
+ } else {
+ m += 9;
+ y--;
+ }
+ c = y; // NOTE: Sym C++ 6.0 bug
+ c /= 100;
+ ya = y - 100*c;
+ return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5;
+}
+
+/*!
+ \internal
+ Converts a Julian day to a Gregorian date.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa greg2jul()
+*/
+
+void QDate::jul2greg( uint jd, int &y, int &m, int &d )
+{
+ uint x;
+ uint j = jd - 1721119;
+ y = (j*4 - 1)/146097;
+ j = j*4 - 146097*y - 1;
+ x = j/4;
+ j = (x*4 + 3) / 1461;
+ y = 100*y + j;
+ x = (x*4) + 3 - 1461*j;
+ x = (x + 4)/4;
+ m = (5*x - 3)/153;
+ x = 5*x - 3 - 153*m;
+ d = (x + 5)/5;
+ if ( m < 10 ) {
+ m += 3;
+ } else {
+ m -= 9;
+ y++;
+ }
+}
+
+
+/*****************************************************************************
+ QTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QTime qdatetime.h
+
+ \brief The QTime class provides clock time functions.
+
+ \ingroup time
+
+ A QTime object contains a clock time, i.e. a number of hours,
+ minutes, seconds and milliseconds since midnight. It can read the
+ current time from the system clock, and measure a span of elapsed
+ time. It provides functions for comparing times and for manipulating
+ a time by adding a number of (milli)seconds.
+
+ QTime operates with 24-hour clock format; it has no concept of
+ AM/PM. It operates with local time; it does not know anything about
+ time zones or daylight savings time.
+
+ A QTime object is typically created either by giving the number of
+ hours, minutes, seconds, and milliseconds explicitly, or by using
+ the static function currentTime(), which makes a QTime object which
+ contains the system's clock time. Note that the accuracy depends on
+ the accuracy of the underlying operating system; not all systems
+ provide 1-millisecond accuracy.
+
+ The hour(), minute(), second(), and msec() functions provide access
+ to the number of hours, minutes, seconds, and milliseconds of the
+ time. The same information is provided in textual format by the
+ toString() function.
+
+ QTime provides a full set of operators to compare two QTime
+ objects. A time is considered smaller than another if it is earlier
+ than the other.
+
+ The time a given number of seconds or milliseconds later than a
+ given time can be found using the addSecs() or addMSecs()
+ functions. Correspondingly, the number of (milli)seconds between two
+ times can be found using the secsTo() or msecsTo() functions.
+
+ QTime can be used to measure a span of elapsed time using the
+ start(), restart(), and elapsed() functions.
+
+ \sa QDate, QDateTime
+*/
+
+/*!
+ \fn QTime::QTime()
+
+ Constructs the time 0 hours, minutes, seconds and milliseconds,
+ i.e. 00:00:00.000 (midnight). This is a valid time.
+
+ \sa isValid()
+*/
+
+/*!
+ Constructs a time with hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0-23, \a m and \a s must be in the range
+ 0-59, and \a ms must be in the range 0-999.
+
+ \sa isValid()
+*/
+
+QTime::QTime( int h, int m, int s, int ms )
+{
+ setHMS( h, m, s, ms );
+}
+
+
+/*!
+ \fn bool QTime::isNull() const
+ Returns TRUE if the time is equal to 00:00:00.000. A null time is valid.
+
+ \sa isValid()
+*/
+
+/*!
+ Returns TRUE if the time is valid, or FALSE if the time is invalid.
+ The time 23:30:55.746 is valid, while 24:12:30 is invalid.
+
+ \sa isNull()
+*/
+
+bool QTime::isValid() const
+{
+ return ds < MSECS_PER_DAY;
+}
+
+
+/*!
+ Returns the hour part (0..23) of the time.
+*/
+
+int QTime::hour() const
+{
+ return ds / MSECS_PER_HOUR;
+}
+
+/*!
+ Returns the minute part (0..59) of the time.
+*/
+
+int QTime::minute() const
+{
+ return (ds % MSECS_PER_HOUR)/MSECS_PER_MIN;
+}
+
+/*!
+ Returns the second part (0..59) of the time.
+*/
+
+int QTime::second() const
+{
+ return (ds / 1000)%SECS_PER_MIN;
+}
+
+/*!
+ Returns the millisecond part (0..999) of the time.
+*/
+
+int QTime::msec() const
+{
+ return ds % 1000;
+}
+
+
+/*!
+ Returns the time of this object in a textual format. Milliseconds
+ are not included. The string format is HH:MM:SS, e.g. 1 second
+ before midnight would be "23:59:59".
+*/
+
+QString QTime::toString() const
+{
+ QString buf;
+ buf.sprintf( "%.2d:%.2d:%.2d", hour(), minute(), second() );
+ return buf;
+}
+
+
+/*!
+ Sets the time to hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0-23, \a m and \a s must be in the range
+ 0-59, and \a ms must be in the range 0-999. Returns TRUE if the set
+ time is valid, otherwise FALSE.
+
+ \sa isValid()
+*/
+
+bool QTime::setHMS( int h, int m, int s, int ms )
+{
+ if ( !isValid(h,m,s,ms) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QTime::setHMS Invalid time %02d:%02d:%02d.%03d", h, m, s,
+ ms );
+#endif
+ ds = MSECS_PER_DAY; // make this invalid
+ return FALSE;
+ }
+ ds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
+ return TRUE;
+}
+
+/*!
+ Returns a QTime object containing a time \a nsecs seconds later than
+ the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight.
+
+ Example:
+ \code
+ QTime n( 14, 0, 0 ); // n == 14:00:00
+ QTime t;
+ t = n.addSecs( 70 ); // t == 14:01:10
+ t = n.addSecs( -70 ); // t == 13:58:50
+ t = n.addSecs( 10*60*60 + 5 ); // t == 00:00:05
+ t = n.addSecs( -15*60*60 ); // t == 23:00:00
+ \endcode
+
+ \sa addMSecs(), secsTo(), QDateTime::addSecs()
+*/
+
+QTime QTime::addSecs( int nsecs ) const
+{
+ return addMSecs(nsecs*1000);
+}
+
+/*!
+ Returns the number of seconds from this time to \a t (which is
+ negative if \a t is earlier than this time).
+
+ Since QTime measures time within a day and there are 86400 seconds
+ in a day, the result is between -86400 and 86400.
+
+ \sa addSecs() QDateTime::secsTo()
+*/
+
+int QTime::secsTo( const QTime &t ) const
+{
+ return ((int)t.ds - (int)ds)/1000;
+}
+
+/*!
+ Returns a QTime object containing a time \a ms milliseconds later than
+ the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight. See addSecs()
+ for an example.
+
+ \sa addSecs(), msecsTo()
+*/
+
+QTime QTime::addMSecs( int ms ) const
+{
+ QTime t;
+ if ( ms < 0 ) {
+ // % not well-defined for -ve, but / is.
+ int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
+ t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
+ % MSECS_PER_DAY;
+ } else {
+ t.ds = ((int)ds + ms) % MSECS_PER_DAY;
+ }
+ return t;
+}
+
+/*!
+ Returns the number of milliseconds from this time to \a t (which is
+ negative if \a t is earlier than this time).
+
+ Since QTime measures time within a day and there are 86400000
+ milliseconds in a day, the result is between -86400000 and 86400000.
+
+ \sa secsTo()
+*/
+
+int QTime::msecsTo( const QTime &t ) const
+{
+ return (int)t.ds - (int)ds;
+}
+
+
+/*!
+ \fn bool QTime::operator==( const QTime &t ) const
+
+ Returns TRUE if this time is equal to \a t, or FALSE if they are
+ different.
+*/
+
+/*!
+ \fn bool QTime::operator!=( const QTime &t ) const
+
+ Returns TRUE if this time is different from \a t, or FALSE if they
+ are equal.
+*/
+
+/*!
+ \fn bool QTime::operator<( const QTime &t ) const
+
+ Returns TRUE if this time is earlier than \a t, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator<=( const QTime &t ) const
+
+ Returns TRUE if this time is earlier than or equal to \a t,
+ otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator>( const QTime &t ) const
+
+ Returns TRUE if this time is later than \a t, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator>=( const QTime &t ) const
+
+ Returns TRUE if this time is later than or equal to \a t, otherwise
+ FALSE.
+*/
+
+
+
+/*!
+ Returns the current time, as reported by the system clock.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+*/
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+ currentTime( &ct );
+ return ct;
+}
+
+/*!
+ \internal
+
+ Fetches the current time and returns TRUE if the time is within one
+ minute after midnight, otherwise FALSE. The return value is used by
+ QDateTime::currentDateTime() to ensure that the date there is correct.
+*/
+
+bool QTime::currentTime( QTime *ct )
+{
+ if ( !ct ) {
+#if defined(CHECK_NULL)
+ qWarning( "QTime::currentTime(QTime *): Null pointer not allowed" );
+#endif
+ return FALSE;
+ }
+
+#if defined(_OS_WIN32_)
+
+ SYSTEMTIME t;
+ GetLocalTime( &t );
+ ct->ds = MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
+ 1000*t.wSecond + t.wMilliseconds;
+ return (t.wHour == 0 && t.wMinute == 0);
+
+#elif defined(_OS_OS2_)
+
+ DATETIME t;
+ DosGetDateTime( &t );
+ ct->ds = MSECS_PER_HOUR*t.hours + MSECS_PER_MIN*t.minutes +
+ 1000*t.seconds + 10*t.hundredths;
+ return (t.hours == 0 && t.minutes == 0);
+
+#elif defined(_OS_MSDOS_)
+
+ _dostime_t t;
+ _dos_gettime( &t );
+ ct->ds = MSECS_PER_HOUR*t.hour + MSECS_PER_MIN*t.minute +
+ t.second*1000 + t.hsecond*10;
+ return (t.hour== 0 && t.minute == 0);
+
+#elif defined(_OS_UNIX_) || defined(_OS_MAC_)
+
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ time_t ltime = tv.tv_sec;
+ tm *t = localtime( <ime );
+ ct->ds = (uint)( MSECS_PER_HOUR*t->tm_hour + MSECS_PER_MIN*t->tm_min +
+ 1000*t->tm_sec + tv.tv_usec/1000 );
+ return (t->tm_hour== 0 && t->tm_min == 0);
+
+#else
+
+ time_t ltime; // no millisecond resolution!!
+ ::time( <ime );
+ tm *t = localtime( <ime );
+ ct->ds = MSECS_PER_HOUR*t->tm_hour + MSECS_PER_MIN*t->tm_min +
+ 1000*t->tm_sec;
+ return (t->tm_hour== 0 && t->tm_min == 0);
+#endif
+}
+
+/*!
+ Returns TRUE if the specified time is valid, otherwise FALSE.
+
+ The time is valid if \a h is in the range 0-23, \a m and \a s are in
+ the range 0-59, and \a ms is in the range 0-999.
+
+ Example:
+ \code
+ QTime::isValid(21, 10, 30); // returns TRUE
+ QTime::isValid(22, 5, 62); // returns FALSE
+ \endcode
+*/
+
+bool QTime::isValid( int h, int m, int s, int ms )
+{
+ return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
+}
+
+
+/*!
+ Sets this time to the current time. This is practical for timing:
+
+ \code
+ QTime t;
+ t.start(); // start clock
+ ... // some lengthy task
+ qDebug( "%d\n", t.elapsed() ); // prints # msecs elapsed
+ \endcode
+
+ \sa restart(), elapsed(), currentTime()
+*/
+
+void QTime::start()
+{
+ *this = currentTime();
+}
+
+/*!
+ Sets this time to the current time, and returns the number of
+ milliseconds that have elapsed since the last time start() or
+ restart() was called.
+
+ This function is guaranteed to be atomic, and is thus very handy for
+ repeated measurements: call start() to start the first measurement,
+ then restart() for each later measurement.
+
+ Note that the counter wraps to zero 24 hours after the last call to
+ start() or restart().
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is undefined.
+ This can happen e.g. when daylight saving is turned on or off.
+
+ \sa start(), elapsed(), currentTime()
+*/
+
+int QTime::restart()
+{
+ QTime t = currentTime();
+ int n = msecsTo( t );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ *this = t;
+ return n;
+}
+
+/*!
+ Returns the number of milliseconds that have elapsed since the last
+ time start() or restart() was called.
+
+ Note that the counter wraps to zero 24 hours after the last call to
+ start() or restart.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is undefined.
+ This can happen e.g. when daylight saving is turned on or off.
+
+ \sa start(), restart()
+*/
+
+int QTime::elapsed()
+{
+ int n = msecsTo( currentTime() );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ return n;
+}
+
+
+/*****************************************************************************
+ QDateTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QDateTime qdatetime.h
+ \brief The QDateTime class provides date and time functions.
+
+ \ingroup time
+
+ A QDateTime object contains a calendar date and a clock time (a
+ "datetime"). It is a combination of the QDate and QTime classes. It
+ can read the current datetime from the system clock. It provides
+ functions for comparing datetimes and for manipulating a datetime by
+ adding a number of seconds or days.
+
+ A QDateTime object is typically created either by giving a date and
+ time explicitly, or by using the static function currentTime(),
+ which makes a QDateTime object which contains the system's clock
+ time.
+
+ The date() and time() functions provide access to the date and time
+ parts of the datetime. The same information is provided in textual
+ format by the toString() function.
+
+ QDateTime provides a full set of operators to compare two QDateTime
+ objects. A datetime is considered smaller than another if it is
+ earlier than the other.
+
+ The datetime a given number of days or seconds later than a given
+ datetime can be found using the addDays() and addSecs()
+ functions. Correspondingly, the number of days or seconds between
+ two times can be found using the daysTo() or secsTo() functions.
+
+ A datetime can also be set using the setTime_t() function, which
+ takes a POSIX-standard "number of seconds since 00:00:00 on January
+ 1, 1970" value.
+
+ The limitations regarding range and resolution mentioned in the
+ QDate and QTime documentation apply for QDateTime also.
+
+ \sa QDate, QTime
+*/
+
+
+/*!
+ \fn QDateTime::QDateTime()
+
+ Constructs a null datetime (i.e. null date and null time). A null
+ datetime is invalid, since the date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Constructs a datetime with date \a date and null time (00:00:00.000).
+*/
+
+QDateTime::QDateTime( const QDate &date )
+ : d(date)
+{
+}
+
+/*!
+ Constructs a datetime with date \a date and time \a time.
+*/
+
+QDateTime::QDateTime( const QDate &date, const QTime &time )
+ : d(date), t(time)
+{
+}
+
+
+/*!
+ \fn bool QDateTime::isNull() const
+
+ Returns TRUE if both the date and the time are null. A null date is invalid.
+
+ \sa QDate::isNull(), QTime::isNull()
+*/
+
+/*!
+ \fn bool QDateTime::isValid() const
+
+ Returns TRUE if both the date and the time are valid.
+
+ \sa QDate::isValid(), QTime::isValid()
+*/
+
+/*!
+ \fn QDate QDateTime::date() const
+
+ Returns the date part of this datetime.
+
+ \sa setDate(), time()
+*/
+
+/*!
+ \fn QTime QDateTime::time() const
+
+ Returns the time part of this datetime.
+
+ \sa setTime(), date()
+*/
+
+/*!
+ \fn void QDateTime::setDate( const QDate &date )
+
+ Sets the date part of this datetime.
+
+ \sa date(), setTime()
+*/
+
+/*!
+ \fn void QDateTime::setTime( const QTime &time )
+
+ Sets the time part of this datetime.
+
+ \sa time(), setDate()
+*/
+
+
+/*!
+ Sets the local date and time given the number of seconds that have passed
+ since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
+ On systems that do not support timezones this function will behave as if
+ local time were UTC.
+
+ Note that Microsoft Windows supports only a limited range of values for
+ \a secsSince1Jan1970UTC.
+*/
+
+void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
+{
+ time_t tmp = (time_t) secsSince1Jan1970UTC;
+ tm *tM = localtime( &tmp );
+ if ( !tM ) {
+ tM = gmtime( &tmp );
+ if ( !tM ) {
+ d.jd = QDate::greg2jul( 1970, 1, 1 );
+ t.ds = 0;
+ return;
+ }
+ }
+ d.jd = QDate::greg2jul( tM->tm_year + 1900, tM->tm_mon + 1, tM->tm_mday );
+ t.ds = MSECS_PER_HOUR*tM->tm_hour + MSECS_PER_MIN*tM->tm_min +
+ 1000*tM->tm_sec;
+}
+
+
+/*!
+ Returns the datetime as a string.
+
+ The string format is "Sat May 20 03:40:13 1998".
+
+ This function uses QDate::dayName(), QDate::monthName(), and
+ QTime::toString() to generate the string.
+
+*/
+
+QString QDateTime::toString() const
+{
+ QString buf = d.dayName(d.dayOfWeek());
+ buf += ' ';
+ buf += d.monthName(d.month());
+ buf += ' ';
+ buf += QString().setNum(d.day());
+ buf += ' ';
+ buf += t.toString();
+ buf += ' ';
+ buf += QString().setNum(d.year());
+ return buf;
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a ndays days later
+ than the datetime of this object (or earlier if \a ndays is
+ negative).
+
+ \sa daysTo(), addSecs()
+*/
+
+QDateTime QDateTime::addDays( int ndays ) const
+{
+ return QDateTime( d.addDays(ndays), t );
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a nsecs seconds
+ later than the datetime of this object (or earlier if \a nsecs is
+ negative).
+
+ \sa secsTo(), addDays()
+*/
+
+QDateTime QDateTime::addSecs( int nsecs ) const
+{
+ uint dd = d.jd;
+ int tt = t.ds;
+ int sign = 1;
+ if ( nsecs < 0 ) {
+ nsecs = -nsecs;
+ sign = -1;
+ }
+ if ( nsecs >= (int)SECS_PER_DAY ) {
+ dd += sign*(nsecs/SECS_PER_DAY);
+ nsecs %= SECS_PER_DAY;
+ }
+ tt += sign*nsecs*1000;
+ if ( tt < 0 ) {
+ tt = MSECS_PER_DAY - tt - 1;
+ dd -= tt / MSECS_PER_DAY;
+ tt = tt % MSECS_PER_DAY;
+ tt = MSECS_PER_DAY - tt - 1;
+ } else if ( tt >= (int)MSECS_PER_DAY ) {
+ dd += ( tt / MSECS_PER_DAY );
+ tt = tt % MSECS_PER_DAY;
+ }
+ QDateTime ret;
+ ret.t.ds = tt;
+ ret.d.jd = dd;
+ return ret;
+}
+
+/*!
+ Returns the number of days from this datetime to \a dt (which is
+ negative if \a dt is earlier than this datetime).
+
+ \sa addDays(), secsTo()
+*/
+
+int QDateTime::daysTo( const QDateTime &dt ) const
+{
+ return d.daysTo( dt.d );
+}
+
+/*!
+ Returns the number of seconds from this datetime to \a dt (which is
+ negative if \a dt is earlier than this datetime).
+
+ Example:
+ \code
+ QDateTime dt = QDateTime::currentDateTime();
+ QDateTime x( QDate(dt.year(),12,24), QTime(17,00) );
+ qDebug( "There are %d seconds to Christmas", dt.secsTo(x) );
+ \endcode
+
+ \sa addSecs(), daysTo(), QTime::secsTo()
+*/
+
+int QDateTime::secsTo( const QDateTime &dt ) const
+{
+ return t.secsTo(dt.t) + d.daysTo(dt.d)*SECS_PER_DAY;
+}
+
+
+/*!
+ Returns TRUE if this datetime is equal to \a dt, or FALSE if
+ they are different.
+ \sa operator!=()
+*/
+
+bool QDateTime::operator==( const QDateTime &dt ) const
+{
+ return t == dt.t && d == dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is different from \a dt, or FALSE if
+ they are equal.
+ \sa operator==()
+*/
+
+bool QDateTime::operator!=( const QDateTime &dt ) const
+{
+ return t != dt.t || d != dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than \a dt, otherwise FALSE.
+*/
+
+bool QDateTime::operator<( const QDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t < dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than or equal to \a dt,
+ otherwise FALSE.
+*/
+
+bool QDateTime::operator<=( const QDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t <= dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than \a dt, otherwise FALSE.
+*/
+
+bool QDateTime::operator>( const QDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t > dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than or equal to \a dt,
+ otherwise FALSE.
+*/
+
+bool QDateTime::operator>=( const QDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t >= dt.t : FALSE;
+}
+
+/*!
+ Returns the current datetime, as reported by the system clock.
+
+ \sa QDate::currentDate(), QTime::currentTime()
+*/
+
+QDateTime QDateTime::currentDateTime()
+{
+ QDate cd = QDate::currentDate();
+ QTime ct;
+ if ( QTime::currentTime(&ct) ) // too close to midnight?
+ cd = QDate::currentDate(); // YES! time for some midnight
+ // voodoo, fetch date again
+ return QDateTime( cd, ct );
+}
+
+
+/*****************************************************************************
+ Date/time stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QDate
+ Writes the date to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QDate &d )
+{
+ return s << (Q_UINT32)(d.jd);
+}
+
+/*!
+ \relates QDate
+ Reads a date from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QDate &d )
+{
+ Q_UINT32 jd;
+ s >> jd;
+ d.jd = jd;
+ return s;
+}
+
+/*!
+ \relates QTime
+ Writes a time to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QTime &t )
+{
+ return s << (Q_UINT32)(t.ds);
+}
+
+/*!
+ \relates QTime
+ Reads a time from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QTime &t )
+{
+ Q_UINT32 ds;
+ s >> ds;
+ t.ds = ds;
+ return s;
+}
+
+/*!
+ \relates QDateTime
+ Writes a datetime to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QDateTime &dt )
+{
+ return s << dt.d << dt.t;
+}
+
+/*!
+ \relates QDateTime
+ Reads a datetime from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QDateTime &dt )
+{
+ s >> dt.d >> dt.t;
+ return s;
+}
+#endif //QT_NO_DATASTREAM
diff --git a/qtools/qdatetime.h b/qtools/qdatetime.h
new file mode 100644
index 0000000..2d5869c
--- /dev/null
+++ b/qtools/qdatetime.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+**
+** Definition of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QDATETIME_H
+#define QDATETIME_H
+
+#ifndef QT_H
+#include "qstring.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ QDate class
+ *****************************************************************************/
+
+class Q_EXPORT QDate
+{
+public:
+ QDate() { jd=0; } // set null date
+ QDate( int y, int m, int d ); // set date
+ virtual ~QDate() {}
+
+ bool isNull() const { return jd == 0; }
+ bool isValid() const; // valid date
+
+ int year() const; // 1752..
+ int month() const; // 1..12
+ int day() const; // 1..31
+ int dayOfWeek() const; // 1..7 (monday==1)
+ int dayOfYear() const; // 1..365
+ int daysInMonth() const; // 28..31
+ int daysInYear() const; // 365 or 366
+
+ virtual QString monthName( int month ) const;
+ virtual QString dayName( int weekday ) const;
+
+ QString toString() const;
+
+ bool setYMD( int y, int m, int d );
+
+ QDate addDays( int days ) const;
+ int daysTo( const QDate & ) const;
+
+ bool operator==( const QDate &d ) const { return jd == d.jd; }
+ bool operator!=( const QDate &d ) const { return jd != d.jd; }
+ bool operator<( const QDate &d ) const { return jd < d.jd; }
+ bool operator<=( const QDate &d ) const { return jd <= d.jd; }
+ bool operator>( const QDate &d ) const { return jd > d.jd; }
+ bool operator>=( const QDate &d ) const { return jd >= d.jd; }
+
+ static QDate currentDate();
+ static bool isValid( int y, int m, int d );
+ static bool leapYear( int year );
+
+protected:
+ static uint greg2jul( int y, int m, int d );
+ static void jul2greg( uint jd, int &y, int &m, int &d );
+private:
+ static const char * const monthNames[];
+ static const char * const weekdayNames[];
+ uint jd;
+ friend class QDateTime;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
+#endif
+};
+
+
+/*****************************************************************************
+ QTime class
+ *****************************************************************************/
+
+class Q_EXPORT QTime
+{
+public:
+ QTime() { ds=0; } // set null time
+ QTime( int h, int m, int s=0, int ms=0 ); // set time
+
+ bool isNull() const { return ds == 0; }
+ bool isValid() const; // valid time
+
+ int hour() const; // 0..23
+ int minute() const; // 0..59
+ int second() const; // 0..59
+ int msec() const; // 0..999
+
+ QString toString() const;
+
+ bool setHMS( int h, int m, int s, int ms=0 );
+
+ QTime addSecs( int secs ) const;
+ int secsTo( const QTime & ) const;
+ QTime addMSecs( int ms ) const;
+ int msecsTo( const QTime & ) const;
+
+ bool operator==( const QTime &d ) const { return ds == d.ds; }
+ bool operator!=( const QTime &d ) const { return ds != d.ds; }
+ bool operator<( const QTime &d ) const { return ds < d.ds; }
+ bool operator<=( const QTime &d ) const { return ds <= d.ds; }
+ bool operator>( const QTime &d ) const { return ds > d.ds; }
+ bool operator>=( const QTime &d ) const { return ds >= d.ds; }
+
+ static QTime currentTime();
+ static bool isValid( int h, int m, int s, int ms=0 );
+
+ void start();
+ int restart();
+ int elapsed();
+
+private:
+ static bool currentTime( QTime * );
+
+ uint ds;
+ friend class QDateTime;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ QDateTime class
+ *****************************************************************************/
+
+class Q_EXPORT QDateTime
+{
+public:
+ QDateTime() {} // set null date and null time
+ QDateTime( const QDate & );
+ QDateTime( const QDate &, const QTime & );
+
+ bool isNull() const { return d.isNull() && t.isNull(); }
+ bool isValid() const { return d.isValid() && t.isValid(); }
+
+ QDate date() const { return d; }
+ QTime time() const { return t; }
+ void setDate( const QDate &date ) { d=date; }
+ void setTime( const QTime &time ) { t=time; }
+ void setTime_t( uint secsSince1Jan1970UTC );
+
+ QString toString() const;
+
+ QDateTime addDays( int days ) const;
+ QDateTime addSecs( int secs ) const;
+ int daysTo( const QDateTime & ) const;
+ int secsTo( const QDateTime & ) const;
+
+ bool operator==( const QDateTime &dt ) const;
+ bool operator!=( const QDateTime &dt ) const;
+ bool operator<( const QDateTime &dt ) const;
+ bool operator<=( const QDateTime &dt ) const;
+ bool operator>( const QDateTime &dt ) const;
+ bool operator>=( const QDateTime &dt ) const;
+
+ static QDateTime currentDateTime();
+
+private:
+ QDate d;
+ QTime t;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime &);
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ Date and time stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
+#endif // QT_NO_DATASTREAM
+
+#endif // QDATETIME_H
diff --git a/qtools/qdict.doc b/qtools/qdict.doc
new file mode 100644
index 0000000..d9f6ca5
--- /dev/null
+++ b/qtools/qdict.doc
@@ -0,0 +1,492 @@
+/****************************************************************************
+**
+**
+** QDict and QDictIterator class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QDict documentation
+ *****************************************************************************/
+
+/*!
+ \class QDict qdict.h
+ \brief The QDict class is a template class that provides a dictionary based on \c QString keys.
+
+ \ingroup collection
+ \ingroup tools
+
+ QDict is implemented as a template class. Define a template instance
+ QDict\<X\> to create a dictionary that operates on pointers to X, or X*.
+
+ A dictionary is a collection that associates an item with a key.
+ The key is used for inserting and looking up an item. QDict has
+ \l QString keys, which are Unicode strings. If you want to use
+ non-Unicode, plain 8-bit \c char* keys, use the QAsciiDict template.
+ A QDict has the same performace as a QAsciiDict.
+
+ The dictionary has very fast insertion and lookup.
+
+ Example:
+ \code
+ #include <qdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ // Creates a dictionary that maps QString ==> char* (case insensitive)
+ QDict<char> dict( 17, FALSE );
+
+ dict.insert( "France", "Paris" );
+ dict.insert( "Russia", "Moscow" );
+ dict.insert( "Norway", "Oslo" );
+
+ printf( "%s\n", dict["Norway"] );
+ printf( "%s\n", dict["FRANCE"] );
+ printf( "%s\n", dict["russia"] );
+
+ if ( !dict["Italy"] )
+ printf( "Italy not defined\n" );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Oslo
+ Paris
+ Moscow
+ Italy not defined
+ \endcode
+
+ The dictionary in our example maps \c QString keys to \c char* items.
+ Note that the mapping is case insensitive (specified in the
+ \link QDict::QDict() constructor\endlink).
+ QDict implements the \link operator[] [] operator\endlink to lookup an item.
+
+ QDict is implemented by QGDict as a hash array with a fixed number of
+ entries. Each array entry points to a singly linked list of buckets, in
+ which the dictionary items are stored.
+
+ When an item is inserted with a key, the key is converted (hashed) to
+ an integer index into the hash array. The item is inserted before the
+ first bucket in the list of buckets.
+
+ Looking up an item is normally very fast. The key is again hashed to an
+ array index. Then QDict scans the list of buckets and returns the item
+ found or null if the item was not found. You cannot insert null pointers
+ into a dictionary.
+
+ The size of the hash array is very important. In order to get good
+ performance, you should use a suitably large \link primes.html prime
+ number\endlink. Suitable means equal to or larger than the maximum
+ expected number of dictionary items.
+
+ Items with equal keys are allowed. When inserting two items with the
+ same key, only the last inserted item will be visible (last in, first out)
+ until it is removed.
+
+ Example:
+ \code
+ #include <qdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ // Creates a dictionary that maps QString ==> char* (case sensitive)
+ QDict<char> dict;
+
+ dict.insert( "Germany", "Berlin" );
+ dict.insert( "Germany", "Bonn" );
+
+ printf( "%s\n", dict["Germany"] );
+ dict.remove( "Germany" ); // Oct 3rd 1990
+ printf( "%s\n", dict["Germany"] );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Bonn
+ Berlin
+ \endcode
+
+ The QDictIterator class can traverse the dictionary contents, but only
+ in an arbitrary order. Multiple iterators may independently traverse the
+ same dictionary.
+
+ Calling setAutoDelete(TRUE) for a dictionary tells it to delete items
+ that are removed . The default is to not delete items when they are
+ removed.
+
+ When inserting an item into a dictionary, only the pointer is copied, not
+ the item itself. This is called a shallow copy. It is possible to make the
+ dictionary copy all of the item's data (known as a deep copy) when an
+ item is inserted. insert() calls the virtual function
+ QCollection::newItem() for the item to be inserted.
+ Inherit a dictionary and reimplement it if you want deep copies.
+
+ When removing a dictionary item, the virtual function
+ QCollection::deleteItem() is called. QDict's default implementation
+ is to delete the item if auto-deletion is enabled.
+
+ \sa QDictIterator, QAsciiDict, QIntDict, QPtrDict,
+ \link collection.html Collection Classes\endlink
+*/
+
+
+/*!
+ \fn QDict::QDict( int size, bool caseSensitive )
+ Constructs a dictionary with the following properties:
+ \arg \e size is the size of the internal hash array.
+ \arg \e caseSensitive specifies whether to use case sensitive lookup or not.
+
+ Setting \e size to a suitably large \link primes.html prime
+ number\endlink (equal to or greater than the expected number of entries)
+ makes the hash distribution better and hence the loopup faster.
+
+ Setting \e caseSensitive to TRUE will treat "abc" and "Abc" as different
+ keys. Setting it to FALSE will make the dictionary ignore case.
+ Case insensitive comparison includes the whole Unicode alphabeth.
+*/
+
+/*!
+ \fn QDict::QDict( const QDict<type> &dict )
+ Constructs a copy of \e dict.
+
+ Each item in \e dict are inserted into this dictionary.
+ Only the pointers are copied (shallow copy).
+*/
+
+/*!
+ \fn QDict::~QDict()
+ Removes all items from the dictionary and destroys it.
+ All iterators that access this dictionary will be reset.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn QDict<type> &QDict::operator=(const QDict<type> &dict)
+ Assigns \e dict to this dictionary and returns a reference to this
+ dictionary.
+
+ This dictionary is first cleared, then each item in \e dict is inserted
+ into this dictionary.
+ Only the pointers are copied (shallow copy), unless newItem() has been
+ reimplemented().
+*/
+
+/*!
+ \fn uint QDict::count() const
+ Returns the number of items in the dictionary.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn uint QDict::size() const
+ Returns the size of the internal hash array (as specified in the
+ constructor).
+ \sa count()
+*/
+
+/*!
+ \fn void QDict::resize( uint newsize )
+ Changes the size of the hashtable the \a newsize.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+
+/*!
+ \fn bool QDict::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn void QDict::insert( const QString &key, const type *item )
+
+ Inserts the \e key with the \e item into the dictionary.
+
+ The key does not have to be a unique dictionary key. If multiple items
+ are inserted with the same key, only the last item will be visible.
+
+ Null items are not allowed.
+
+ \sa replace()
+*/
+
+/*!
+ \fn void QDict::replace( const QString &key, const type *item )
+
+ Replaces an item which has a key equal to \e key with \e item.
+
+ If the item does not already exist, it will be inserted.
+
+ Null items are not allowed.
+
+ Equivalent to:
+ \code
+ QDict<char> dict;
+ ...
+ if ( dict.find(key) )
+ dict.remove( key );
+ dict.insert( key, item );
+ \endcode
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be replaced.
+
+ \sa insert()
+*/
+
+/*!
+ \fn bool QDict::remove( const QString &key )
+
+ Removes the item associated with \e key from the dictionary.
+ Returns TRUE if successful, or FALSE if the key does not exist in the
+ dictionary.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be removed.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that refer to the removed item will be set to
+ point to the next item in the dictionary traversing order.
+
+ \sa take(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QDict::take( const QString &key )
+
+ Takes the item associated with \e key out of the dictionary without
+ deleting it (even if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled).
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be taken.
+
+ Returns a pointer to the item taken out, or null if the key does not
+ exist in the dictionary.
+
+ All dictionary iterators that refer to the taken item will be set to
+ point to the next item in the dictionary traversal order.
+
+ \sa remove(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn void QDict::clear()
+
+ Removes all items from the dictionary.
+
+ The removed items are deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that operate on dictionary are reset.
+
+ \sa remove(), take(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QDict::find( const QString &key ) const
+
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the [] operator.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn type *QDict::operator[]( const QString &key ) const
+
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the find() function.
+
+ \sa find()
+*/
+
+/*!
+ \fn void QDict::statistics() const
+ Debugging-only function that prints out the dictionary distribution
+ using qDebug().
+*/
+
+
+/*****************************************************************************
+ QDictIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QDictIterator qdict.h
+ \brief The QDictIterator class provides an iterator for QDict collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ QDictIterator is implemented as a template class.
+ Define a template instance QDictIterator\<X\> to create a
+ dictionary iterator that operates on QDict\<X\> (dictionary of X*).
+
+ Example:
+ \code
+ #include <qdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ // Creates a dictionary that maps QString ==> char* (case insensitive)
+ QDict<char> dict( 17, FALSE );
+
+ dict.insert( "France", "Paris" );
+ dict.insert( "Russia", "Moscow" );
+ dict.insert( "Norway", "Oslo" );
+
+ QDictIterator<char> it( dict ); // iterator for dict
+
+ while ( it.current() ) {
+ printf( "%s -> %s\n", it.currentKey().latin1(), it.current() );
+ ++it;
+ }
+ }
+ \endcode
+
+ Program output:
+ \code
+ Russia -> Moscow
+ Norway -> Oslo
+ France -> Paris
+ \endcode
+
+ Note that the traversal order is arbitrary, you are not guaranteed the
+ order above.
+
+ Multiple iterators may independently traverse the same dictionary.
+ A QDict knows about all iterators that are operating on the dictionary.
+ When an item is removed from the dictionary, QDict update all iterators
+ that are referring the removed item to point to the next item in the
+ traversing order.
+
+ \sa QDict, \link collection.html Collection Classes\endlink
+*/
+
+/*!
+ \fn QDictIterator::QDictIterator( const QDict<type> &dict )
+ Constructs an iterator for \e dict. The current iterator item is
+ set to point on the first item in the \e dict.
+*/
+
+/*!
+ \fn QDictIterator::~QDictIterator()
+ Destroys the iterator.
+*/
+
+/*!
+ \fn uint QDictIterator::count() const
+ Returns the number of items in the dictionary this iterator operates on.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn bool QDictIterator::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0, otherwise FALSE.
+ \sa count()
+*/
+
+/*!
+ \fn type *QDictIterator::toFirst()
+ Sets the current iterator item to point to the first item in the
+ dictionary and returns a pointer to the item.
+ If the dictionary is empty it sets the current item to null and
+ returns null.
+*/
+
+/*!
+ \fn QDictIterator::operator type *() const
+ Cast operator. Returns a pointer to the current iterator item.
+ Same as current().
+*/
+
+/*!
+ \fn type *QDictIterator::current() const
+ Returns a pointer to the current iterator item.
+*/
+
+/*!
+ \fn QString QDictIterator::currentKey() const
+ Returns a pointer to the key for the current iterator item.
+*/
+
+/*!
+ \fn type *QDictIterator::operator()()
+ Makes the succeeding item current and returns the original current item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QDictIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns the new current
+ item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QDictIterator::operator+=( uint jump )
+ Sets the current item to the item \e jump positions after the current item,
+ and returns a pointer to that item.
+
+ If that item is beyond the last item or if the dictionary is empty,
+ it sets the current item to null and returns null.
+*/
+
+
diff --git a/qtools/qdict.h b/qtools/qdict.h
new file mode 100644
index 0000000..efc5bd0
--- /dev/null
+++ b/qtools/qdict.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+**
+** Definition of QDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QDICT_H
+#define QDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+#define USE_ASCII_STRING
+
+#ifdef USE_ASCII_STRING
+
+#define QAsciiDict QDict
+#define QAsciiDictIterator QDictIterator
+#include "qasciidict.h"
+
+#else
+
+template<class type> class Q_EXPORT QDict : private QGDict
+{
+public:
+ QDict(int size=17, bool caseSensitive=TRUE)
+ : QGDict(size,StringKey,caseSensitive,FALSE) {}
+ QDict( const QDict<type> &d ) : QGDict(d) {}
+ ~QDict() { clear(); }
+ QDict<type> &operator=(const QDict<type> &d)
+ { return (QDict<type>&)QGDict::operator=(d); }
+
+ // capacity
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+
+ // modifiers
+ void insert( const QString &k, const type *d )
+ { QGDict::look_string(k,(Item)d,1); }
+ void replace( const QString &k, const type *d )
+ { QGDict::look_string(k,(Item)d,2); }
+ bool remove( const QString &k ) { return QGDict::remove_string(k); }
+ type *take( const QString &k ) { return (type *)QGDict::take_string(k); }
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+
+ // search
+ type *find( const QString &k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
+ type *operator[]( const QString &k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
+
+ // operations
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+
+ // new to be reimplemented methods
+ virtual int compareValues(const type *t1,const type *t2) const
+ { return const_cast<QDict<type>*>(this)->QGDict::compareItems((QCollection::Item)t1,(QCollection::Item)t2); }
+
+ // reimplemented methods
+ virtual int compareItems(QCollection::Item i1,QCollection::Item i2)
+ { return compareValues((const type*)i1,(const type*)i2); }
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QDict<void>::deleteItem( Item )
+{
+}
+#endif
+
+template<class type> inline void QDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QDictIterator : public QGDictIterator
+{
+public:
+ QDictIterator(const QDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ QString currentKey() const{ return QGDictIterator::getKeyString(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+#endif // USE_ASCII_STRING
+
+#endif // QDICT_H
diff --git a/qtools/qdir.cpp b/qtools/qdir.cpp
new file mode 100644
index 0000000..120abe7
--- /dev/null
+++ b/qtools/qdir.cpp
@@ -0,0 +1,1200 @@
+/****************************************************************************
+**
+**
+** Implementation of QDir class
+**
+** Created : 950427
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qdir.h"
+
+#ifndef QT_NO_DIR
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+// NOT REVISED
+/*!
+ \class QDir qdir.h
+ \brief Traverses directory structures and contents in a
+ platform-independent way.
+
+ \ingroup io
+
+ A QDir can point to a file using either a relative or an absolute file
+ path. Absolute file paths begin with the directory separator ('/') or a
+ drive specification (not applicable to UNIX). Relative file names begin
+ with a directory name or a file name and specify a path relative to the
+ current directory.
+
+ An example of an absolute path is the string "/tmp/quartz", a relative
+ path might look like "src/fatlib". You can use the function isRelative()
+ to check if a QDir is using a relative or an absolute file path. You can
+ call the function convertToAbs() to convert a relative QDir to an
+ absolute one.
+
+ The directory "example" under the current directory is checked for existence
+ in the example below:
+
+ \code
+ QDir d( "example" ); // "./example"
+ if ( !d.exists() )
+ qWarning( "Cannot find the example directory" );
+ \endcode
+
+ If you always use '/' as a directory separator, Qt will translate your
+ paths to conform to the underlying operating system.
+
+ cd() and cdUp() can be used to navigate the directory tree. Note that the
+ logical cd and cdUp operations are not performed if the new directory does
+ not exist.
+
+ Example:
+ \code
+ QDir d = QDir::root(); // "/"
+ if ( !d.cd("tmp") ) { // "/tmp"
+ qWarning( "Cannot find the \"/tmp\" directory" );
+ } else {
+ QFile f( d.filePath("ex1.txt") ); // "/tmp/ex1.txt"
+ if ( !f.open(IO_ReadWrite) )
+ qWarning( "Cannot create the file %s", f.name() );
+ }
+ \endcode
+
+ To read the contents of a directory you can use the entryList() and
+ entryInfoList() functions.
+
+ Example:
+ \code
+ #include <stdio.h>
+ #include <qdir.h>
+
+ //
+ // This program scans the current directory and lists all files
+ // that are not symbolic links, sorted by size with the smallest files
+ // first.
+ //
+
+ int main( int argc, char **argv )
+ {
+ QDir d;
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+ d.setSorting( QDir::Size | QDir::Reversed );
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list ); // create list iterator
+ QFileInfo *fi; // pointer for traversing
+
+ printf( " BYTES FILENAME\n" ); // print header
+ while ( (fi=it.current()) ) { // for each file...
+ printf( "%10li %s\n", fi->size(), fi->fileName().data() );
+ ++it; // goto next list element
+ }
+ }
+ \endcode
+*/
+
+
+/*!
+ Constructs a QDir pointing to the current directory.
+ \sa currentDirPath()
+*/
+
+QDir::QDir()
+{
+ dPath = QString::fromLatin1(".");
+ init();
+}
+
+/*!
+ Constructs a QDir.
+
+ \arg \e path is the directory.
+ \arg \e nameFilter is the file name filter.
+ \arg \e sortSpec is the sort specification, which describes how to
+ sort the files in the directory.
+ \arg \e filterSpec is the filter specification, which describes how
+ to filter the files in the directory.
+
+ Most of these arguments (except \e path) have optional values.
+
+ Example:
+ \code
+ // lists all files in /tmp
+
+ QDir d( "/tmp" );
+ for ( int i=0; i<d.count(); i++ )
+ printf( "%s\n", d[i] );
+ \endcode
+
+ If \e path is "" or null, the directory is set to "." (the current
+ directory). If \e nameFilter is "" or null, it is set to "*" (all
+ files).
+
+ No check is made to ensure that the directory exists.
+
+ \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
+*/
+
+QDir::QDir( const QString &path, const QString &nameFilter,
+ int sortSpec, int filterSpec )
+{
+ init();
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = QString::fromLatin1(".");
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = QString::fromLatin1("*");
+ filtS = (FilterSpec)filterSpec;
+ sortS = (SortSpec)sortSpec;
+}
+
+/*!
+ Constructs a QDir that is a copy of the given directory.
+ \sa operator=()
+*/
+
+QDir::QDir( const QDir &d )
+{
+ dPath = d.dPath;
+ fList = 0;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+}
+
+
+void QDir::init()
+{
+ fList = 0;
+ fiList = 0;
+ nameFilt = QString::fromLatin1("*");
+ dirty = TRUE;
+ allDirs = FALSE;
+ filtS = All;
+ sortS = SortSpec(Name | IgnoreCase);
+}
+
+/*!
+ Destructs the QDir and cleans up.
+*/
+
+QDir::~QDir()
+{
+ if ( fList )
+ delete fList;
+ if ( fiList )
+ delete fiList;
+}
+
+
+/*!
+ Sets the path of the directory. The path is cleaned of redundant ".", ".."
+ and multiple separators. No check is made to ensure that a directory
+ with this path exists.
+
+ The path can be either absolute or relative. Absolute paths begin with the
+ directory separator ('/') or a drive specification (not
+ applicable to UNIX).
+ Relative file names begin with a directory name or a file name and specify
+ a path relative to the current directory. An example of
+ an absolute path is the string "/tmp/quartz", a relative path might look like
+ "src/fatlib". You can use the function isRelative() to check if a QDir
+ is using a relative or an absolute file path. You can call the function
+ convertToAbs() to convert a relative QDir to an absolute one.
+
+ \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath(), isRelative(), convertToAbs()
+*/
+
+void QDir::setPath( const QString &path )
+{
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = QString::fromLatin1(".");
+ dirty = TRUE;
+}
+
+/*!
+ \fn QString QDir::path() const
+ Returns the path, this may contain symbolic links, but never contains
+ redundant ".", ".." or multiple separators.
+
+ The returned path can be either absolute or relative (see setPath()).
+
+ \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath(), convertSeparators()
+*/
+
+/*!
+ Returns the absolute (a path that starts with '/') path, which may
+ contain symbolic links, but never contains redundant ".", ".." or
+ multiple separators.
+
+ \sa setPath(), canonicalPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath()
+*/
+
+QString QDir::absPath() const
+{
+ if ( QDir::isRelativePath(dPath) ) {
+ QString tmp = currentDirPath();
+ if ( tmp.right(1) != QString::fromLatin1("/") )
+ tmp += '/';
+ tmp += dPath;
+ return cleanDirPath( tmp );
+ } else {
+ return cleanDirPath( dPath );
+ }
+}
+
+/*!
+ Returns the name of the directory, this is NOT the same as the path, e.g.
+ a directory with the name "mail", might have the path "/var/spool/mail".
+ If the directory has no name (e.g. the root directory) a null string is
+ returned.
+
+ No check is made to ensure that a directory with this name actually exists.
+
+ \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
+*/
+
+QString QDir::dirName() const
+{
+ int pos = dPath.findRev( '/' );
+ if ( pos == -1 )
+ return dPath;
+ return dPath.right( dPath.length() - pos - 1 );
+}
+
+/*!
+ Returns the path name of a file in the directory. Does NOT check if
+ the file actually exists in the directory. If the QDir is relative
+ the returned path name will also be relative. Redundant multiple separators
+ or "." and ".." directories in \e fileName will not be removed (see
+ cleanDirPath()).
+
+ If \e acceptAbsPath is TRUE a \e fileName starting with a separator
+ ('/') will be returned without change.
+ If \e acceptAbsPath is FALSE an absolute path will be appended to
+ the directory path.
+
+ \sa absFilePath(), isRelative(), canonicalPath()
+*/
+
+QString QDir::filePath( const QString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath(fileName) )
+ return QString(fileName);
+
+ QString tmp = dPath;
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ return tmp;
+}
+
+/*!
+ Returns the absolute path name of a file in the directory. Does NOT check if
+ the file actually exists in the directory. Redundant multiple separators
+ or "." and ".." directories in \e fileName will NOT be removed (see
+ cleanDirPath()).
+
+ If \e acceptAbsPath is TRUE a \e fileName starting with a separator
+ ('/') will be returned without change.
+ if \e acceptAbsPath is FALSE an absolute path will be appended to
+ the directory path.
+
+ \sa filePath()
+*/
+
+QString QDir::absFilePath( const QString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath( fileName ) )
+ return fileName;
+
+ QString tmp = absPath();
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ return tmp;
+}
+
+
+/*!
+ Converts the '/' separators in \a pathName to system native
+ separators. Returns the translated string.
+
+ On Windows, convertSeparators("c:/winnt/system32") returns
+ "c:\winnt\system32".
+
+ No conversion is done on UNIX.
+*/
+
+QString QDir::convertSeparators( const QString &pathName )
+{
+ QString n( pathName );
+#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
+ for ( int i=0; i<(int)n.length(); i++ ) {
+ if ( n[i] == '/' )
+ n[i] = '\\';
+ }
+#endif
+ return n;
+}
+
+
+/*!
+ Changes directory by descending into the given directory. Returns
+ TRUE if the new directory exists and is readable. Note that the logical
+ cd operation is NOT performed if the new directory does not exist.
+
+ If \e acceptAbsPath is TRUE a path starting with a separator ('/')
+ will cd to the absolute directory, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e dirName will be removed.
+
+ Example:
+ \code
+ QDir d = QDir::home(); // now points to home directory
+ if ( !d.cd("c++") ) { // now points to "c++" under home directory if OK
+ QFileInfo fi( d, "c++" );
+ if ( fi.exists() ) {
+ if ( fi.isDir() )
+ qWarning( "Cannot cd into \"%s\".", (char*)d.absFilePath("c++") );
+ else
+ qWarning( "Cannot create directory \"%s\"\n"
+ "A file named \"c++\" already exists in \"%s\"",
+ (const char *)d.absFilePath("c++"),
+ (const char *)d.path() );
+ return;
+ } else {
+ qWarning( "Creating directory \"%s\"",
+ (const char *) d.absFilePath("c++") );
+ if ( !d.mkdir( "c++" ) ) {
+ qWarning("Could not create directory \"%s\"",
+ (const char *)d.absFilePath("c++") );
+ return;
+ }
+ }
+ }
+ \endcode
+
+ Calling cd( ".." ) is equivalent to calling cdUp().
+
+ \sa cdUp(), isReadable(), exists(), path()
+*/
+
+bool QDir::cd( const QString &dirName, bool acceptAbsPath )
+{
+ if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
+ return TRUE;
+ QString old = dPath;
+ if ( acceptAbsPath && !isRelativePath(dirName) ) {
+ dPath = cleanDirPath( dirName );
+ } else {
+ if ( !isRoot() )
+ dPath += '/';
+ dPath += dirName;
+ if ( dirName.find('/') >= 0
+ || old == QString::fromLatin1(".")
+ || dirName == QString::fromLatin1("..") )
+ dPath = cleanDirPath( dPath );
+ }
+ if ( !exists() ) {
+ dPath = old; // regret
+ return FALSE;
+ }
+ dirty = TRUE;
+ return TRUE;
+}
+
+/*!
+ Changes directory by moving one directory up the path followed to arrive
+ at the current directory.
+
+ Returns TRUE if the new directory exists and is readable. Note that the
+ logical cdUp() operation is not performed if the new directory does not
+ exist.
+
+ \sa cd(), isReadable(), exists(), path()
+*/
+
+bool QDir::cdUp()
+{
+ return cd( QString::fromLatin1("..") );
+}
+
+/*!
+ \fn QString QDir::nameFilter() const
+ Returns the string set by setNameFilter()
+*/
+
+/*!
+ Sets the name filter used by entryList() and entryInfoList().
+
+ The name filter is a wildcarding filter that understands "*" and "?"
+ wildcards, You may specify several filter entries separated by a " " or a ";". If
+ you want entryList() and entryInfoList() to list all files ending with
+ ".cpp" and all files ending with ".h", you simply call
+ dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
+
+ \sa nameFilter(), setFilter()
+*/
+
+void QDir::setNameFilter( const QString &nameFilter )
+{
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = QString::fromLatin1("*");
+ dirty = TRUE;
+}
+
+/*!
+ \fn QDir::FilterSpec QDir::filter() const
+ Returns the value set by setFilter()
+*/
+
+/*! \enum QDir::FilterSpec
+
+ This enum describes how QDir is to select what entries in a
+ directory to return. The filter value is specified by or-ing
+ together values from the following list: <ul>
+
+ <li> \c Dirs - List directories only
+ <li> \c Files - List files only
+
+ <li> \c Drives - List disk drives (does nothing under unix)
+ <li> \c NoSymLinks - Do not list symbolic links (where they exist)
+ <li> \c Readable - List files for which the application has read access.
+ <li> \c Writable - List files for which the application has write access.
+ <li> \c Executable - List files for which the application has execute access
+ <li> \c Modified - Only list files that have been modified (does nothing
+ under unix)
+ <li> \c Hidden - List hidden files (on unix, files starting with a .)
+ <li> \c System - List system files (does nothing under unix)
+ </ul>
+
+ If you do not set any of \c Readable, \c Writable or \c Executable,
+ QDir will set all three of them. This makes the default easy to
+ write and at the same time useful.
+
+ Examples: \c Readable|Writable means list all files for which the
+ application has read access, write access or both. \c Dirs|Drives
+ means list drives, directories, all files that the application can
+ read, write or execute, and also symlinks to such files/directories.
+*/
+
+
+/*!
+ Sets the filter used by entryList() and entryInfoList(). The filter is used
+ to specify the kind of files that should be returned by entryList() and
+ entryInfoList().
+
+ \sa filter(), setNameFilter()
+*/
+
+void QDir::setFilter( int filterSpec )
+{
+ if ( filtS == (FilterSpec) filterSpec )
+ return;
+ filtS = (FilterSpec) filterSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn QDir::SortSpec QDir::sorting() const
+
+ Returns the value set by setSorting()
+
+ \sa setSorting()
+*/
+
+/*! \enum QDir::SortSpec
+
+ This enum describes how QDir is to sort entries in a directory when
+ it returns a list of them. The sort value is specified by or-ing
+ together values from the following list: <ul>
+
+ <li> \c Name - sort by name
+ <li> \c Time - sort by time (modification time)
+ <li> \c Size - sort by file size
+ <li> \c Unsorted - do not sort
+
+ <li> \c DirsFirst - put all directories first in the list
+ <li> \c Reversed - reverse the sort order
+ <li> \c IgnoreCase - sort case-insensitively
+
+ </ul>
+
+ You can only specify one of the first four. If you specify both \c
+ DirsFirst and \c Reversed, directories are still put first but the
+ list is otherwise reversed.
+*/
+
+// ### Unsorted+DirsFirst ? Unsorted+Reversed?
+
+/*!
+ Sets the sorting order used by entryList() and entryInfoList().
+
+ The \e sortSpec is specified by or-ing values from the enum
+ SortSpec. The different values are:
+
+ One of these:
+ <dl compact>
+ <dt>Name<dd> Sort by name (alphabetical order).
+ <dt>Time<dd> Sort by time (most recent first).
+ <dt>Size<dd> Sort by size (largest first).
+ <dt>Unsorted<dd> Use the operating system order (UNIX does NOT sort
+ alphabetically).
+
+ ORed with zero or more of these:
+
+ <dt>DirsFirst<dd> Always put directory names first.
+ <dt>Reversed<dd> Reverse sort order.
+ <dt>IgnoreCase<dd> Ignore case when sorting by name.
+ </dl>
+*/
+
+void QDir::setSorting( int sortSpec )
+{
+ if ( sortS == (SortSpec) sortSpec )
+ return;
+ sortS = (SortSpec) sortSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn bool QDir::matchAllDirs() const
+ Returns the value set by setMatchAllDirs()
+
+ \sa setMatchAllDirs()
+*/
+
+/*!
+ If \e enable is TRUE, all directories will be listed (even if they do not
+ match the filter or the name filter), otherwise only matched directories
+ will be listed.
+
+ \bug Currently, directories that do not match the filter will not be
+ included (the name filter will be ignored as expected).
+
+ \sa matchAllDirs()
+*/
+
+void QDir::setMatchAllDirs( bool enable )
+{
+ if ( (bool)allDirs == enable )
+ return;
+ allDirs = enable;
+ dirty = TRUE;
+}
+
+
+/*!
+ Returns the number of files that was found.
+ Equivalent to entryList().count().
+ \sa operator[](), entryList()
+*/
+
+uint QDir::count() const
+{
+ return entryList().count();
+}
+
+/*!
+ Returns the file name at position \e index in the list of found file
+ names.
+ Equivalent to entryList().at(index).
+
+ Returns null if the \e index is out of range or if the entryList()
+ function failed.
+
+ \sa count(), entryList()
+*/
+
+QString QDir::operator[]( int index ) const
+{
+ entryList();
+ return fList && index >= 0 && index < (int)fList->count() ?
+ (*fList)[index] : QString::null;
+}
+
+
+/*!
+ This function is included to easy porting from Qt 1.x to Qt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using QFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
+{
+ QStrList r;
+ QStringList l = entryList(filterSpec,sortSpec);
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( QFile::encodeName(*it) );
+ }
+ return r;
+}
+
+/*!
+ This function is included to easy porting from Qt 1.x to Qt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using QFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+QStrList QDir::encodedEntryList( const QString &nameFilter,
+ int filterSpec,
+ int sortSpec ) const
+{
+ QStrList r;
+ QStringList l = entryList(nameFilter,filterSpec,sortSpec);
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( QFile::encodeName(*it) );
+ }
+ return r;
+}
+
+
+
+/*!
+ Returns a list of the names of all files and directories in the directory
+ indicated by the setSorting(), setFilter() and setNameFilter()
+ specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e filterSpec and \e sortSpec arguments.
+
+ Returns an empty list if the directory is unreadable or does not exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
+ encodedEntryList()
+*/
+
+QStringList QDir::entryList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return *fList;
+ return entryList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of the names of all files and directories in the directory
+ indicated by the setSorting(), setFilter() and setNameFilter()
+ specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e nameFilter, \e filterSpec and \e sortSpec arguments.
+
+ Returns and empty list if the directory is unreadable or does not exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
+ encodedEntryList()
+*/
+
+QStringList QDir::entryList( const QString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ QDir *that = (QDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
+ return *that->fList;
+ else
+ return QStringList();
+}
+
+/*!
+ Returns a list of QFileInfo objects for all files and directories in
+ the directory pointed to using the setSorting(), setFilter() and
+ setNameFilter() specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e filterSpec and \e sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a QFileInfoList. The list is
+ owned by the QDir object and will be reused on the next call to
+ entryInfoList() for the same QDir instance. If you want to keep the
+ entries of the list after a subsequent call to this function you will
+ need to copy them.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return fiList;
+ return entryInfoList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of QFileInfo objects for all files and directories in
+ the directory pointed to using the setSorting(), setFilter() and
+ setNameFilter() specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e nameFilter, \e filterSpec and \e sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a QFileInfoList. The list is
+ owned by the QDir object and will be reused on the next call to
+ entryInfoList() for the same QDir instance. If you want to keep the
+ entries of the list after a subsequent call to this function you will
+ need to copy them.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ QDir *that = (QDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
+ return that->fiList;
+ else
+ return 0;
+}
+
+/*!
+ Returns TRUE if the directory exists. (If a file with the same
+ name is found this function will of course return FALSE).
+
+ \sa QFileInfo::exists(), QFile::exists()
+*/
+
+bool QDir::exists() const
+{
+ QFileInfo fi( dPath );
+ return fi.exists() && fi.isDir();
+}
+
+/*!
+ Returns TRUE if the directory path is relative to the current directory,
+ FALSE if the path is absolute (e.g. under UNIX a path is relative if it
+ does not start with a '/').
+
+ According to Einstein this function should always return TRUE.
+
+ \sa convertToAbs()
+*/
+
+bool QDir::isRelative() const
+{
+ return isRelativePath( dPath );
+}
+
+/*!
+ Converts the directory path to an absolute path. If it is already
+ absolute nothing is done.
+
+ \sa isRelative()
+*/
+
+void QDir::convertToAbs()
+{
+ dPath = absPath();
+}
+
+/*!
+ Makes a copy of d and assigns it to this QDir.
+*/
+
+QDir &QDir::operator=( const QDir &d )
+{
+ dPath = d.dPath;
+ delete fList;
+ fList = 0;
+ delete fiList;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+ return *this;
+}
+
+/*!
+ Sets the directory path to be the given path.
+*/
+
+QDir &QDir::operator=( const QString &path )
+{
+ dPath = cleanDirPath( path );
+ dirty = TRUE;
+ return *this;
+}
+
+
+/*!
+ \fn bool QDir::operator!=( const QDir &d ) const
+ Returns TRUE if the \e d and this dir have different path or
+ different sort/filter settings, otherwise FALSE.
+*/
+
+/*!
+ Returns TRUE if the \e d and this dir have the same path and all sort
+ and filter settings are equal, otherwise FALSE.
+*/
+
+bool QDir::operator==( const QDir &d ) const
+{
+ return dPath == d.dPath &&
+ nameFilt == d.nameFilt &&
+ allDirs == d.allDirs &&
+ filtS == d.filtS &&
+ sortS == d.sortS;
+}
+
+
+/*!
+ Removes a file.
+
+ If \e acceptAbsPath is TRUE a path starting with a separator ('/')
+ will remove the file with the absolute path, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e fileName will be removed.
+
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QDir::remove( const QString &fileName, bool acceptAbsPath )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ QString p = filePath( fileName, acceptAbsPath );
+ return QFile::remove( p );
+}
+
+/*!
+ Checks for existence of a file.
+
+ If \e acceptAbsPaths is TRUE a path starting with a separator ('/')
+ will check the file with the absolute path, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e name will be removed.
+
+ Returns TRUE if the file exists, otherwise FALSE.
+
+ \sa QFileInfo::exists(), QFile::exists()
+*/
+
+bool QDir::exists( const QString &name, bool acceptAbsPath )
+{
+ if ( name.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::exists: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ QString tmp = filePath( name, acceptAbsPath );
+ return QFile::exists( tmp );
+}
+
+/*!
+ Returns the native directory separator; '/' under UNIX and '\' under
+ MS-DOS, Windows NT and OS/2.
+
+ You do not need to use this function to build file paths. If you always
+ use '/', Qt will translate your paths to conform to the underlying
+ operating system.
+*/
+
+char QDir::separator()
+{
+#if defined(_OS_UNIX_)
+ return '/';
+#elif defined (_OS_FATFS_)
+ return '\\';
+#elif defined (_OS_MAC_)
+ return ':';
+#else
+ return '/';
+#endif
+}
+
+/*!
+ Returns the current directory.
+ \sa currentDirPath(), QDir::QDir()
+*/
+
+QDir QDir::current()
+{
+ return QDir( currentDirPath() );
+}
+
+/*!
+ Returns the home directory.
+ \sa homeDirPath()
+*/
+
+QDir QDir::home()
+{
+ return QDir( homeDirPath() );
+}
+
+/*!
+ Returns the root directory.
+ \sa rootDirPath() drives()
+*/
+
+QDir QDir::root()
+{
+ return QDir( rootDirPath() );
+}
+
+/*!
+ \fn QString QDir::homeDirPath()
+
+ Returns the absolute path for the user's home directory,
+ \sa home()
+*/
+
+QStringList qt_makeFilterList( const QString &filter )
+{
+ if ( filter.isEmpty() )
+ return QStringList();
+
+ QChar sep( ';' );
+ int i = filter.find( sep, 0 );
+ if ( i == -1 && filter.find( ' ', 0 ) != -1 )
+ sep = QChar( ' ' );
+
+ QStringList lst = QStringList::split( sep, filter );
+ QStringList lst2;
+ QStringList::Iterator it = lst.begin();
+
+ for ( ; it != lst.end(); ++it ) {
+ QString s = *it;
+ lst2 << s.stripWhiteSpace();
+ }
+ return lst2;
+}
+
+/*!
+ Returns TRUE if the \e fileName matches one of the wildcards in the list \e filters.
+ \sa QRegExp
+*/
+
+bool QDir::match( const QStringList &filters, const QString &fileName )
+{
+ QStringList::ConstIterator sit = filters.begin();
+ bool matched = FALSE;
+ for ( ; sit != filters.end(); ++sit ) {
+ QRegExp regexp( (*sit).data(), FALSE, TRUE );
+ if ( regexp.match( fileName.data() ) != -1 ) {
+ matched = TRUE;
+ break;
+ }
+ }
+
+ return matched;
+}
+
+/*!
+ Returns TRUE if the \e fileName matches the wildcard \e filter.
+ \a Filter may also contain multiple wildcards separated by spaces or
+ semicolons.
+ \sa QRegExp
+*/
+
+bool QDir::match( const QString &filter, const QString &fileName )
+{
+ QStringList lst = qt_makeFilterList( filter );
+ return match( lst, fileName );
+}
+
+
+/*!
+ Removes all multiple directory separators ('/') and resolves
+ any "." or ".." found in the path.
+
+ Symbolic links are kept. This function does not return the
+ canonical path, but rather the most simplified version of the input.
+ "../stuff" becomes "stuff", "stuff/../nonsense" becomes "nonsense"
+ and "\\stuff\\more\\..\\nonsense" becomes "\\stuff\\nonsense".
+
+ \sa absPath() canonicalPath()
+*/
+
+QString QDir::cleanDirPath( const QString &filePath )
+{
+ QString name = filePath;
+ QString newPath;
+
+ if ( name.isEmpty() )
+ return name;
+
+ slashify( name );
+
+ bool addedSeparator;
+ if ( isRelativePath(name) ) {
+ addedSeparator = TRUE;
+ name.insert( 0, '/' );
+ } else {
+ addedSeparator = FALSE;
+ }
+
+ int ePos, pos, upLevel;
+
+ pos = ePos = name.length();
+ upLevel = 0;
+ int len;
+
+ while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
+ len = ePos - pos - 1;
+ if ( len == 2 && name.at(pos + 1) == '.'
+ && name.at(pos + 2) == '.' ) {
+ upLevel++;
+ } else {
+ if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
+ if ( !upLevel )
+ newPath = QString::fromLatin1("/")
+ + name.mid(pos + 1, len) + newPath;
+ else
+ upLevel--;
+ }
+ }
+ ePos = pos;
+ }
+ if ( addedSeparator ) {
+ while ( upLevel-- )
+ newPath.insert( 0, QString::fromLatin1("/..") );
+ if ( !newPath.isEmpty() )
+ newPath.remove( 0, 1 );
+ else
+ newPath = QString::fromLatin1(".");
+ } else {
+ if ( newPath.isEmpty() )
+ newPath = QString::fromLatin1("/");
+#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
+ if ( name[0] == '/' ) {
+ if ( name[1] == '/' ) // "\\machine\x\ ..."
+ newPath.insert( 0, '/' );
+ } else {
+ newPath = name.left(2) + newPath;
+ }
+#endif
+ }
+ return newPath;
+}
+
+int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+int qt_cmp_si( const void *n1, const void *n2 )
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ QDirSortItem* f1 = (QDirSortItem*)n1;
+ QDirSortItem* f2 = (QDirSortItem*)n2;
+
+ if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
+ if ( f1->item->isDir() != f2->item->isDir() )
+ return f1->item->isDir() ? -1 : 1;
+
+ int r = 0;
+ int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
+
+ switch ( sortBy ) {
+ case QDir::Time:
+ r = f1->item->lastModified().secsTo(f2->item->lastModified());
+ break;
+ case QDir::Size:
+ r = f2->item->size() - f1->item->size();
+ break;
+ default:
+ ;
+ }
+
+ if ( r == 0 && sortBy != QDir::Unsorted ) {
+ // Still not sorted - sort by name
+ bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
+
+ if ( f1->filename_cache.isNull() )
+ f1->filename_cache = ic ? f1->item->fileName().lower()
+ : f1->item->fileName();
+ if ( f2->filename_cache.isNull() )
+ f2->filename_cache = ic ? f2->item->fileName().lower()
+ : f2->item->fileName();
+
+ r = f1->filename_cache.compare(f2->filename_cache);
+ }
+
+ if ( r == 0 ) {
+ // Enforce an order - the order the items appear in the array
+ r = (int)((char*)n1 - (char*)n2);
+ }
+
+ if ( qt_cmp_si_sortSpec & QDir::Reversed )
+ return -r;
+ else
+ return r;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#endif // QT_NO_DIR
diff --git a/qtools/qdir.h b/qtools/qdir.h
new file mode 100644
index 0000000..cec3897
--- /dev/null
+++ b/qtools/qdir.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+**
+** Definition of QDir class
+**
+** Created : 950427
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QDIR_H
+#define QDIR_H
+
+#ifndef QT_H
+#include "qstrlist.h"
+#include "qfileinfo.h"
+#endif // QT_H
+
+#ifndef QT_NO_DIR
+typedef QInternalList<QFileInfo> QFileInfoList;
+typedef QInternalListIterator<QFileInfo> QFileInfoListIterator;
+class QStringList;
+
+
+class Q_EXPORT QDir
+{
+public:
+ enum FilterSpec { Dirs = 0x001,
+ Files = 0x002,
+ Drives = 0x004,
+ NoSymLinks = 0x008,
+ All = 0x007,
+ TypeMask = 0x00F,
+
+ Readable = 0x010,
+ Writable = 0x020,
+ Executable = 0x040,
+ RWEMask = 0x070,
+
+ Modified = 0x080,
+ Hidden = 0x100,
+ System = 0x200,
+ AccessMask = 0x3F0,
+
+ DefaultFilter = -1 };
+
+ enum SortSpec { Name = 0x00,
+ Time = 0x01,
+ Size = 0x02,
+ Unsorted = 0x03,
+ SortByMask = 0x03,
+
+ DirsFirst = 0x04,
+ Reversed = 0x08,
+ IgnoreCase = 0x10,
+ DefaultSort = -1 };
+
+ QDir();
+ QDir( const QString &path, const QString &nameFilter = QString::null,
+ int sortSpec = Name | IgnoreCase, int filterSpec = All );
+ QDir( const QDir & );
+
+ virtual ~QDir();
+
+ QDir &operator=( const QDir & );
+ QDir &operator=( const QString &path );
+
+ virtual void setPath( const QString &path );
+ virtual QString path() const;
+ virtual QString absPath() const;
+ virtual QString canonicalPath() const;
+
+ virtual QString dirName() const;
+ virtual QString filePath( const QString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual QString absFilePath( const QString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+
+ static QString convertSeparators( const QString &pathName );
+
+ virtual bool cd( const QString &dirName, bool acceptAbsPath = TRUE );
+ virtual bool cdUp();
+
+ QString nameFilter() const;
+ virtual void setNameFilter( const QString &nameFilter );
+ FilterSpec filter() const;
+ virtual void setFilter( int filterSpec );
+ SortSpec sorting() const;
+ virtual void setSorting( int sortSpec );
+
+ bool matchAllDirs() const;
+ virtual void setMatchAllDirs( bool );
+
+ uint count() const;
+ QString operator[]( int ) const;
+
+ virtual QStrList encodedEntryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStrList encodedEntryList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStringList entryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStringList entryList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ virtual const QFileInfoList *entryInfoList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual const QFileInfoList *entryInfoList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ static const QFileInfoList *drives();
+
+ virtual bool mkdir( const QString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual bool rmdir( const QString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+
+ virtual bool isReadable() const;
+ virtual bool exists() const;
+ virtual bool isRoot() const;
+
+ virtual bool isRelative() const;
+ virtual void convertToAbs();
+
+ virtual bool operator==( const QDir & ) const;
+ virtual bool operator!=( const QDir & ) const;
+
+ virtual bool remove( const QString &fileName,
+ bool acceptAbsPath = TRUE );
+ virtual bool rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths = TRUE );
+ virtual bool exists( const QString &name,
+ bool acceptAbsPath = TRUE );
+
+ static char separator();
+
+ static bool setCurrent( const QString &path );
+ static QDir current();
+ static QDir home();
+ static QDir root();
+ static QString currentDirPath();
+ static QString homeDirPath();
+ static QString rootDirPath();
+
+ static bool match( const QStringList &filters, const QString &fileName );
+ static bool match( const QString &filter, const QString &fileName );
+ static QString cleanDirPath( const QString &dirPath );
+ static bool isRelativePath( const QString &path );
+
+private:
+ void init();
+ virtual bool readDirEntries( const QString &nameFilter,
+ int FilterSpec, int SortSpec );
+
+ static void slashify ( QString &);
+
+ QString dPath;
+ QStringList *fList;
+ QFileInfoList *fiList;
+ QString nameFilt;
+ FilterSpec filtS;
+ SortSpec sortS;
+ uint dirty : 1;
+ uint allDirs : 1;
+};
+
+
+inline QString QDir::path() const
+{
+ return dPath;
+}
+
+inline QString QDir::nameFilter() const
+{
+ return nameFilt;
+}
+
+inline QDir::FilterSpec QDir::filter() const
+{
+ return filtS;
+}
+
+inline QDir::SortSpec QDir::sorting() const
+{
+ return sortS;
+}
+
+inline bool QDir::matchAllDirs() const
+{
+ return allDirs;
+}
+
+inline bool QDir::operator!=( const QDir &d ) const
+{
+ return !(*this == d);
+}
+
+
+struct QDirSortItem {
+ QString filename_cache;
+ QFileInfo* item;
+};
+
+#endif // QT_NO_DIR
+#endif // QDIR_H
diff --git a/qtools/qdir_unix.cpp b/qtools/qdir_unix.cpp
new file mode 100644
index 0000000..2257265
--- /dev/null
+++ b/qtools/qdir_unix.cpp
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+**
+** Implementation of QDirclass
+**
+** Created : 950628
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
+** with the Qt Commercial License Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qdir.h"
+#ifndef QT_NO_DIR
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+extern QStringList qt_makeFilterList( const QString &filter );
+
+extern int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+extern int qt_cmp_si( const void *, const void * );
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+void QDir::slashify( QString& )
+{
+}
+
+QString QDir::homeDirPath()
+{
+ QString d;
+ d = QFile::decodeName(getenv("HOME"));
+ slashify( d );
+ if ( d.isNull() )
+ d = rootDirPath();
+ return d;
+}
+
+QString QDir::canonicalPath() const
+{
+ QString r;
+
+ char cur[PATH_MAX];
+ char tmp[PATH_MAX];
+ if (GETCWD( cur, PATH_MAX )) {
+ if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
+ if (GETCWD( tmp, PATH_MAX )) {
+ r = QFile::decodeName(tmp);
+ }
+ (void)CHDIR( cur );
+ }
+ }
+
+ slashify( r );
+ return r;
+}
+
+bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
+{
+ return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 )
+ == 0;
+}
+
+bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
+{
+ return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+}
+
+bool QDir::isReadable() const
+{
+ return ACCESS( QFile::encodeName(dPath), R_OK | X_OK ) == 0;
+}
+
+bool QDir::isRoot() const
+{
+ return dPath == QString::fromLatin1("/");
+}
+
+bool QDir::rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths )
+{
+ if ( name.isEmpty() || newName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::rename: Empty or null file name(s)" );
+#endif
+ return FALSE;
+ }
+ QString fn1 = filePath( name, acceptAbsPaths );
+ QString fn2 = filePath( newName, acceptAbsPaths );
+ return ::rename( QFile::encodeName(fn1),
+ QFile::encodeName(fn2) ) == 0;
+}
+
+bool QDir::setCurrent( const QString &path )
+{
+ int r;
+ r = CHDIR( QFile::encodeName(path) );
+ return r >= 0;
+}
+
+QString QDir::currentDirPath()
+{
+ QString result;
+
+ STATBUF st;
+ if ( STAT( ".", &st ) == 0 ) {
+ char currentName[PATH_MAX];
+ if ( GETCWD( currentName, PATH_MAX ) != 0 )
+ result = QFile::decodeName(currentName);
+#if defined(DEBUG)
+ if ( result.isNull() )
+ qWarning( "QDir::currentDirPath: getcwd() failed" );
+#endif
+ } else {
+#if defined(DEBUG)
+ qWarning( "QDir::currentDirPath: stat(\".\") failed" );
+#endif
+ }
+ slashify( result );
+ return result;
+}
+
+QString QDir::rootDirPath()
+{
+ QString d = QString::fromLatin1( "/" );
+ return d;
+}
+
+bool QDir::isRelativePath( const QString &path )
+{
+ int len = path.length();
+ if ( len == 0 )
+ return TRUE;
+ return path[0] != '/';
+}
+
+bool QDir::readDirEntries( const QString &nameFilter,
+ int filterSpec, int sortSpec )
+{
+ int i;
+ if ( !fList ) {
+ fList = new QStringList;
+ CHECK_PTR( fList );
+ fiList = new QFileInfoList;
+ CHECK_PTR( fiList );
+ fiList->setAutoDelete( TRUE );
+ } else {
+ fList->clear();
+ fiList->clear();
+ }
+
+ QStringList filters = qt_makeFilterList( nameFilter );
+
+ bool doDirs = (filterSpec & Dirs) != 0;
+ bool doFiles = (filterSpec & Files) != 0;
+ bool noSymLinks = (filterSpec & NoSymLinks) != 0;
+ bool doReadable = (filterSpec & Readable) != 0;
+ bool doWritable = (filterSpec & Writable) != 0;
+ bool doExecable = (filterSpec & Executable) != 0;
+ bool doHidden = (filterSpec & Hidden) != 0;
+
+#if defined(_OS_OS2EMX_)
+ //QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive
+#else
+ //QRegExp wc( nameFilter, TRUE, TRUE ); // wild card, case sensitive
+#endif
+ QFileInfo fi;
+ DIR *dir;
+ dirent *file;
+
+ dir = opendir( QFile::encodeName(dPath) );
+ if ( !dir ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::readDirEntries: Cannot read the directory: %s",
+ QFile::encodeName(dPath).data() );
+#endif
+ return FALSE;
+ }
+
+ while ( (file = readdir(dir)) ) {
+ QString fn = QFile::decodeName(file->d_name);
+ fi.setFile( *this, fn );
+ if ( !match( filters, fn ) && !(allDirs && fi.isDir()) )
+ continue;
+ if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ) {
+ if ( noSymLinks && fi.isSymLink() )
+ continue;
+ if ( (filterSpec & RWEMask) != 0 )
+ if ( (doReadable && !fi.isReadable()) ||
+ (doWritable && !fi.isWritable()) ||
+ (doExecable && !fi.isExecutable()) )
+ continue;
+ if ( !doHidden && fn[0] == '.' &&
+ fn != QString::fromLatin1(".")
+ && fn != QString::fromLatin1("..") )
+ continue;
+ fiList->append( new QFileInfo( fi ) );
+ }
+ }
+ if ( closedir(dir) != 0 ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::readDirEntries: Cannot close the directory: %s",
+ dPath.local8Bit().data() );
+#endif
+ }
+
+ // Sort...
+ if(fiList->count()) {
+ QDirSortItem* si= new QDirSortItem[fiList->count()];
+ QFileInfo* itm;
+ i=0;
+ for (itm = fiList->first(); itm; itm = fiList->next())
+ si[i++].item = itm;
+ qt_cmp_si_sortSpec = sortSpec;
+ qsort( si, i, sizeof(si[0]), qt_cmp_si );
+ // put them back in the list
+ fiList->setAutoDelete( FALSE );
+ fiList->clear();
+ int j;
+ for ( j=0; j<i; j++ ) {
+ fiList->append( si[j].item );
+ fList->append( si[j].item->fileName() );
+ }
+ delete [] si;
+ fiList->setAutoDelete( TRUE );
+ }
+
+ if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
+ nameFilter == nameFilt )
+ dirty = FALSE;
+ else
+ dirty = TRUE;
+ return TRUE;
+}
+
+const QFileInfoList * QDir::drives()
+{
+ // at most one instance of QFileInfoList is leaked, and this variable
+ // points to that list
+ static QFileInfoList * knownMemoryLeak = 0;
+
+ if ( !knownMemoryLeak ) {
+ knownMemoryLeak = new QFileInfoList;
+ // non-win32 versions both use just one root directory
+ knownMemoryLeak->append( new QFileInfo( rootDirPath() ) );
+ }
+
+ return knownMemoryLeak;
+}
+#endif //QT_NO_DIR
diff --git a/qtools/qdir_win32.cpp b/qtools/qdir_win32.cpp
new file mode 100644
index 0000000..324ff24
--- /dev/null
+++ b/qtools/qdir_win32.cpp
@@ -0,0 +1,485 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2001 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qdir_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+
+#include "qglobal.h"
+
+#include "qdir.h"
+#ifndef QT_NO_DIR
+
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+#if defined(_OS_WIN32_)
+#if defined(_CC_BOOL_DEF_)
+#undef bool
+#include <windows.h>
+#define bool int
+#else
+#include <windows.h>
+#endif
+#endif
+#if defined(_OS_OS2EMX_)
+extern Q_UINT32 DosQueryCurrentDisk(Q_UINT32*,Q_UINT32*);
+#define NO_ERROR 0
+#endif
+
+extern QStringList qt_makeFilterList( const QString &filter );
+
+extern int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+extern int qt_cmp_si( const void *, const void * );
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+static QString p_getenv( QString name )
+{
+ DWORD len = GetEnvironmentVariableW( ( LPCWSTR ) qt_winTchar ( name, TRUE ), NULL, 0 );
+ if ( len == 0 )
+ return QString::null;
+ /* ansi: we allocate too much memory, but this shouldn't be the problem here ... */
+ LPWSTR buf = (LPWSTR)new WCHAR[ len ];
+ len = GetEnvironmentVariableW ( ( LPCWSTR ) qt_winTchar ( name, TRUE ), buf, len );
+ if ( len == 0 )
+ {
+ delete[] buf;
+ return QString::null;
+ }
+ QString ret = qt_winQString ( buf );
+ delete[] buf;
+ return ret;
+}
+
+
+void QDir::slashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '\\' )
+ n[i] = '/';
+ }
+}
+
+QString QDir::homeDirPath()
+{
+ QString d = p_getenv ( "HOME" );
+ if ( d.isNull () ) {
+ d = p_getenv ( "USERPROFILE" );
+ if ( d.isNull () ) {
+ QString homeDrive = p_getenv ( "HOMEDRIVE" );
+ QString homePath = p_getenv ( "HOMEPATH" );
+ if ( !homeDrive.isNull () && !homePath.isNull () ) {
+ d = homeDrive + homePath;
+ } else {
+ d = rootDirPath ();
+ }
+ }
+ }
+ slashify( d );
+ return d;
+}
+
+QString QDir::canonicalPath() const
+{
+ QString r;
+
+ char cur[PATH_MAX];
+ char tmp[PATH_MAX];
+ GETCWD( cur, PATH_MAX );
+ if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
+ GETCWD( tmp, PATH_MAX );
+ r = QFile::decodeName(tmp);
+ }
+ CHDIR( cur );
+
+ slashify( r );
+ return r;
+}
+
+bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
+{
+#if defined(__CYGWIN32_)
+ return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) == 0;
+#else
+ return _wmkdir( ( LPCWSTR ) filePath( dirName, acceptAbsPath ).ucs2() ) == 0;
+#endif
+}
+
+bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
+{
+#if defined(__CYGWIN32_)
+ return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+#else
+ return _wrmdir( ( LPCWSTR ) filePath( dirName, acceptAbsPath ).ucs2() ) == 0;
+#endif
+}
+
+bool QDir::isReadable() const
+{
+ QString path = dPath;
+ if ( ( path[ 0 ] == '\\' ) || ( path[ 0 ] == '/' ) )
+ path = rootDirPath() + path;
+#if defined(__CYGWIN32_)
+ return ACCESS( QFile::encodeName(dPath), R_OK ) == 0;
+#else
+ return ( _waccess( (wchar_t*) path.ucs2(), R_OK ) == 0 );
+#endif
+}
+
+bool QDir::isRoot() const
+{
+ QString path = dPath;
+ slashify( path );
+ return path == rootDirPath ();
+}
+
+bool QDir::rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths )
+{
+ if ( name.isEmpty() || newName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::rename: Empty or null file name(s)" );
+#endif
+ return FALSE;
+ }
+ QString fn1 = filePath( name, acceptAbsPaths );
+ QString fn2 = filePath( newName, acceptAbsPaths );
+#if defined(__CYGWIN32_)
+ return ::rename( QFile::encodeName(fn1),
+ QFile::encodeName(fn2) ) == 0;
+#else
+ return MoveFileW( ( LPCWSTR ) fn1.ucs2(), ( LPCWSTR ) fn2.ucs2() ) != 0;
+#endif
+}
+
+bool QDir::setCurrent( const QString &path )
+{
+#if defined(__CYGWIN32_)
+ int r;
+ r = CHDIR( QFile::encodeName(path) );
+ return r >= 0;
+#else
+ if ( !QDir( path ).exists() )
+ return false;
+ return ( SetCurrentDirectoryW( ( LPCWSTR ) path.ucs2() ) >= 0 );
+#endif
+}
+
+QString QDir::currentDirPath()
+{
+ QString result;
+
+#if defined(__CYGWIN32_)
+
+ STATBUF st;
+ if ( STAT( ".", &st ) == 0 ) {
+ char currentName[PATH_MAX];
+ if ( GETCWD( currentName, PATH_MAX ) != 0 )
+ result = QFile::decodeName(currentName);
+#if defined(DEBUG)
+ if ( result.isNull() )
+ qWarning( "QDir::currentDirPath: getcwd() failed" );
+#endif
+ } else {
+#if defined(DEBUG)
+ qWarning( "QDir::currentDirPath: stat(\".\") failed" );
+#endif
+ }
+
+#else
+
+ DWORD size = 0;
+ WCHAR currentName[ PATH_MAX ];
+ size = ::GetCurrentDirectoryW( PATH_MAX, currentName );
+ if ( size != 0 ) {
+ if ( size > PATH_MAX ) {
+ WCHAR * newCurrentName = new WCHAR[ size ];
+ if ( ::GetCurrentDirectoryW( PATH_MAX, newCurrentName ) != 0 )
+ result = QString::fromUcs2( ( ushort* ) newCurrentName );
+ delete [] newCurrentName;
+ } else {
+ result = QString::fromUcs2( ( ushort* ) currentName );
+ }
+ }
+
+ if ( result.length() >= 2 && result[ 1 ] == ':' )
+ result[ 0 ] = result.at( 0 ).upper(); // Force uppercase drive letters.
+#endif
+ slashify( result );
+ return result;
+}
+
+QString QDir::rootDirPath()
+{
+ QString d = p_getenv ( "SystemDrive" );
+ if ( d.isNull () )
+ d = QString::fromLatin1( "c:" ); // not "c:\\" !
+ slashify ( d );
+ return d;
+}
+
+bool QDir::isRelativePath( const QString &path )
+{
+ if ( path.isEmpty() )
+ return TRUE;
+ int p = 0;
+ if ( path[ 0 ].isLetter() && path[ 1 ] == ':' )
+ p = 2; // we have checked the first 2.
+ return ( ( path[ p ] != '/' ) && ( path[ p ] != '\\' ) );
+}
+
+#undef IS_SUBDIR
+#undef IS_RDONLY
+#undef IS_ARCH
+#undef IS_HIDDEN
+#undef IS_SYSTEM
+#undef FF_GETFIRST
+#undef FF_GETNEXT
+#undef FF_ERROR
+
+#if defined(_OS_WIN32_)
+#define IS_SUBDIR FILE_ATTRIBUTE_DIRECTORY
+#define IS_RDONLY FILE_ATTRIBUTE_READONLY
+#define IS_ARCH FILE_ATTRIBUTE_ARCHIVE
+#define IS_HIDDEN FILE_ATTRIBUTE_HIDDEN
+#define IS_SYSTEM FILE_ATTRIBUTE_SYSTEM
+#define FF_GETFIRST FindFirstFile
+#define FF_GETNEXT FindNextFile
+#define FF_ERROR INVALID_HANDLE_VALUE
+#else
+#define IS_SUBDIR _A_SUBDIR
+#define IS_RDONLY _A_RDONLY
+#define IS_ARCH _A_ARCH
+#define IS_HIDDEN _A_HIDDEN
+#define IS_SYSTEM _A_SYSTEM
+#define FF_GETFIRST _findfirst
+#define FF_GETNEXT _findnext
+#define FF_ERROR -1
+#endif
+
+
+bool QDir::readDirEntries( const QString &nameFilter,
+ int filterSpec, int sortSpec )
+{
+ int i;
+ if ( !fList ) {
+ fList = new QStringList;
+ CHECK_PTR( fList );
+ fiList = new QFileInfoList;
+ CHECK_PTR( fiList );
+ fiList->setAutoDelete( TRUE );
+ } else {
+ fList->clear();
+ fiList->clear();
+ }
+
+ QStringList filters = qt_makeFilterList( nameFilter );
+
+ bool doDirs = (filterSpec & Dirs) != 0;
+ bool doFiles = (filterSpec & Files) != 0;
+ bool noSymLinks = (filterSpec & NoSymLinks) != 0;
+ bool doReadable = (filterSpec & Readable) != 0;
+ bool doWritable = (filterSpec & Writable) != 0;
+ bool doExecable = (filterSpec & Executable) != 0;
+ bool doHidden = (filterSpec & Hidden) != 0;
+ // show hidden files if the user asks explicitly for e.g. .*
+ if ( !doHidden && !nameFilter.isEmpty() && nameFilter[0] == '.' )
+ doHidden = TRUE;
+ bool doModified = (filterSpec & Modified) != 0;
+ bool doSystem = (filterSpec & System) != 0;
+
+ QRegExp wc( nameFilter.data(), FALSE, TRUE ); // wild card, case insensitive
+ bool first = TRUE;
+ QString p = dPath.copy();
+ int plen = p.length();
+#if defined(_OS_WIN32_)
+ HANDLE ff;
+ WIN32_FIND_DATAW finfo;
+#else
+ long ff;
+ _finddata_t finfo;
+#endif
+ QFileInfo fi;
+ if ( plen == 0 )
+ {
+#if defined(CHECK_NULL)
+ warning( "QDir::readDirEntries: No directory name specified" );
+#endif
+ return FALSE;
+ }
+ if ( p.at(plen-1) != '/' && p.at(plen-1) != '\\' )
+ p += '/';
+ p += "*.*";
+
+#if defined(__CYGWIN32_)
+ ff = FF_GETFIRST( p.data(), &finfo );
+#else
+ ff = FindFirstFileW ( ( LPCWSTR ) p.ucs2(), &finfo );
+#endif
+ if ( ff == FF_ERROR )
+ {
+#if defined(DEBUG)
+ warning( "QDir::readDirEntries: Cannot read the directory: %s",
+ (const char *)dPath.utf8() );
+#endif
+ return FALSE;
+ }
+
+ while ( TRUE )
+ {
+ if ( first )
+ first = FALSE;
+ else
+ {
+#if defined(__CYGWIN32_)
+ if ( FF_GETNEXT(ff,&finfo) == -1 )
+ break;
+#else
+ //if ( !FF_GETNEXT(ff,&finfo) )
+ // break;
+ if (!FindNextFileW(ff, &finfo ))
+ break;
+#endif
+ }
+#if defined(__CYGWIN32_)
+ int attrib = finfo.attrib;
+#else
+ int attrib = finfo.dwFileAttributes;
+#endif
+ bool isDir = (attrib & IS_SUBDIR) != 0;
+ bool isFile = !isDir;
+ bool isSymLink = FALSE;
+ bool isReadable = TRUE;
+ bool isWritable = (attrib & IS_RDONLY) == 0;
+ bool isExecable = FALSE;
+ bool isModified = (attrib & IS_ARCH) != 0;
+ bool isHidden = (attrib & IS_HIDDEN) != 0;
+ bool isSystem = (attrib & IS_SYSTEM) != 0;
+
+#if defined(__CYGWIN32_)
+ const char *fname = finfo.name;
+#else
+ //const char *fname = finfo.cFileName;
+ QString fname = QString::fromUcs2( ( const unsigned short* ) finfo.cFileName);
+#endif
+ if ( wc.match(fname.utf8()) == -1 && !(allDirs && isDir) )
+ continue;
+
+ QString name = fname;
+ if ( doExecable )
+ {
+ QString ext = name.right(4).lower();
+ if ( ext == ".exe" || ext == ".com" || ext == ".bat" ||
+ ext == ".pif" || ext == ".cmd" )
+ isExecable = TRUE;
+ }
+
+ if ( (doDirs && isDir) || (doFiles && isFile) )
+ {
+ if ( noSymLinks && isSymLink )
+ continue;
+ if ( (filterSpec & RWEMask) != 0 )
+ if ( (doReadable && !isReadable) ||
+ (doWritable && !isWritable) ||
+ (doExecable && !isExecable) )
+ continue;
+ if ( doModified && !isModified )
+ continue;
+ if ( !doHidden && isHidden )
+ continue;
+ if ( !doSystem && isSystem )
+ continue;
+ fi.setFile( *this, name );
+ fiList->append( new QFileInfo( fi ) );
+ }
+ }
+#if defined(__CYGWIN32_)
+ _findclose( ff );
+#else
+ FindClose( ff );
+#endif
+
+ // Sort...
+ QDirSortItem* si= new QDirSortItem[fiList->count()];
+ QFileInfo* itm;
+ i=0;
+ for (itm = fiList->first(); itm; itm = fiList->next())
+ si[i++].item = itm;
+ qt_cmp_si_sortSpec = sortSpec;
+ qsort( si, i, sizeof(si[0]), qt_cmp_si );
+ // put them back in the list
+ fiList->setAutoDelete( FALSE );
+ fiList->clear();
+ int j;
+ for ( j=0; j<i; j++ ) {
+ fiList->append( si[j].item );
+ fList->append( si[j].item->fileName() );
+ }
+ delete [] si;
+ fiList->setAutoDelete( TRUE );
+
+ if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
+ nameFilter == nameFilt )
+ dirty = FALSE;
+ else
+ dirty = TRUE;
+ return TRUE;
+}
+
+const QFileInfoList * QDir::drives()
+{
+ // at most one instance of QFileInfoList is leaked, and this variable
+ // points to that list
+ static QFileInfoList * knownMemoryLeak = 0;
+
+ if ( !knownMemoryLeak ) {
+ knownMemoryLeak = new QFileInfoList;
+
+#if defined(_OS_WIN32_)
+ Q_UINT32 driveBits = (Q_UINT32) GetLogicalDrives() & 0x3ffffff;
+#elif defined(_OS_OS2EMX_)
+ Q_UINT32 driveBits, cur;
+ if (DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR)
+ exit(1);
+ driveBits &= 0x3ffffff;
+#endif
+ char driveName[4];
+ qstrcpy( driveName, "a:/" );
+ while( driveBits ) {
+ if ( driveBits & 1 )
+ knownMemoryLeak->append( new QFileInfo( driveName ) );
+ driveName[0]++;
+ driveBits = driveBits >> 1;
+ }
+ }
+
+ return knownMemoryLeak;
+}
+#endif //QT_NO_DIR
diff --git a/qtools/qfeatures.h b/qtools/qfeatures.h
new file mode 100644
index 0000000..84fa715
--- /dev/null
+++ b/qtools/qfeatures.h
@@ -0,0 +1,978 @@
+/****************************************************************************
+**
+**
+** Global feature selection
+**
+** Created : 000417
+**
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QFEATURES_H
+#define QFEATURES_H
+
+/*! \page features....html
+ ...
+*/
+
+// Qt ships with a number of pre-defined configurations. If none suit
+// your needs, define QCONFIG_LOCAL and create a "qconfig-local.h" file.
+//
+// Note that disabling some features will produce a libqt that is not
+// compatible with other libqt builds. Such modifications are only
+// supported on Qt/Embedded where reducing the library size is important
+// and where the application-suite is often a fixed set.
+//
+#if defined(QCONFIG_LOCAL)
+#include <qconfig-local.h>
+#elif defined(QCONFIG_MINIMAL)
+#include <qconfig-minimal.h>
+#elif defined(QCONFIG_SMALL)
+#include <qconfig-small.h>
+#elif defined(QCONFIG_MEDIUM)
+#include <qconfig-medium.h>
+#elif defined(QCONFIG_LARGE)
+#include <qconfig-large.h>
+#else // everything...
+#include <qconfig.h>
+#endif
+
+
+// Data structures
+/*!
+ QStringList
+*/
+//#define QT_NO_STRINGLIST
+
+#if defined(QT_NO_IMAGE_SMOOTHSCALE)
+/*!
+ QIconSet
+*/
+# define QT_NO_ICONSET
+#endif
+
+// File I/O
+#if defined(QT_NO_STRINGLIST)
+ /*!
+ QDir
+ */
+# define QT_NO_DIR
+#endif
+
+/*!
+ Palettes
+*/
+//#define QT_NO_PALETTE
+
+/*!
+ QTextStream
+*/
+//#define QT_NO_TEXTSTREAM
+/*!
+ QDataStream
+*/
+//#define QT_NO_DATASTREAM
+
+/*!
+ Dynamic module linking
+*/
+//#define QT_NO_PLUGIN
+
+
+// Images
+/*!
+ BMP image I/O
+ <p>The Windows Bitmap (BMP) image format is common on MS-Windows.
+ <p>This is an uncompressed image format
+ offering few advantages over PNG or JPEG.
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_IMAGEIO_BMP
+#endif
+/*!
+ PPM image I/O
+ <p>The Portable PixMap (PPM) image format is common on Unix.
+ <p>This is an uncompressed image format
+ offering few advantages over PNG or JPEG.
+*/
+//#define QT_NO_IMAGEIO_PPM
+/*!
+ XBM image I/O
+ <p>The X11 BitMap (XBM) image format is common on X11.
+ <p>This is an uncompressed monochrome image format.
+ Qt uses this format for some internal images (eg. mouse cursors).
+*/
+//#define QT_NO_IMAGEIO_XBM
+/*!
+ XPM image I/O
+ <p>The X11 PixMap (XPM) image format is common on X11.
+ <p>This is an uncompressed image format.
+ XPM images have the small advantage that they can be trivially
+ included in source files as they are C code.
+ Qt uses this format for some internal images (eg. QMessageBox icons).
+*/
+#if defined(QT_NO_TEXTSTREAM)
+# define QT_NO_IMAGEIO_XPM
+#endif
+/*!
+ PNG image I/O
+ <p>The Portable Network Graphics (PNG) is a compressed image format.
+ <p>See <a href=http://www.libpng.org/pub/png/>The PNG Home Site</a> for
+ details of the format.
+*/
+//#define QT_NO_IMAGEIO_PNG
+/*!
+ MNG image I/O
+ <p>The Multiple-image Network Graphics (MNG) is a compressed animation format.
+ <p>See <a href=http://www.libpng.org/pub/mng/>The MNG Home Site</a> for
+ details of the format.
+*/
+//#define QT_NO_IMAGEIO_MNG
+/*!
+ JPEG image I/O
+ <p>The Joint Photographic Experts Group (JPEG) is a compressed lossy image format that gives high compression
+ for real-world and photo-realistic images.
+*/
+//#define QT_NO_IMAGEIO_JPEG
+
+/*!
+ Asynchronous I/O
+ <p>Allows push-driven data processing.
+*/
+//#define QT_NO_ASYNC_IO
+/*!
+ Asynchronous image I/O
+ <p>Allows push-driven images.
+*/
+//#define QT_NO_ASYNC_IMAGE_IO
+#if defined(QT_NO_ASYNC_IO) || defined(QT_NO_ASYNC_IMAGE_IO)
+ /*!
+ Animated images
+ <p>This includes animated GIFs.
+ <p><b>Note: this currently also requires <tt>QT_BUILTIN_GIF_READER</tt> to
+ be defined when building Qt.</b>
+ */
+# define QT_NO_MOVIE
+#endif
+
+// Fonts
+/*!
+ TrueType font files
+ <p>Scalable font format common on MS-Windows and becoming common on Unix.
+ <p>Only supported on Qt/Embedded.
+*/
+//#define QT_NO_TRUETYPE
+/*!
+ BDF font files
+ <p>The Bitmap Distribution Format (BDF) font file format, common
+ on Unix.
+ <p>Only supported on Qt/Embedded.
+*/
+#if defined(QT_NO_TEXTSTREAM) || defined(QT_NO_STRINGLIST)
+# define QT_NO_BDF
+#endif
+/*!
+ QFontDatabase
+*/
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_FONTDATABASE
+#endif
+
+// Internationalization
+
+/*!
+ QObject::tr()
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_TRANSLATION
+#endif
+
+/*!
+ QTextCodec class and subclasses
+*/
+//#define QT_NO_TEXTCODEC
+
+#if defined(QT_NO_TEXTCODEC)
+ /*!
+ QTextCodec classes
+ <p>This includes some large conversion tables.
+ */
+# define QT_NO_CODECS
+#endif
+#if defined(QT_LITE_UNICODE)
+ /*!
+ Unicode property tables
+ <p>These include some large tables.
+ */
+# define QT_NO_UNICODETABLES
+#endif
+
+/*!
+ MIME
+*/
+#if defined(QT_NO_DIR)
+# define QT_NO_MIME
+#endif
+#if defined(QT_NO_MIME) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_DRAWUTIL) || defined(QT_NO_IMAGE_SMOOTHSCALE)
+ /*!
+ RichText (HTML) display
+ */
+# define QT_NO_RICHTEXT
+#endif
+
+/*!
+ XML
+*/
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_TEXTCODEC)
+# define QT_NO_XML
+#endif
+
+/*!
+ Document Object Model
+*/
+#if defined(QT_NO_XML) || defined(QT_NO_MIME)
+# define QT_NO_DOM
+#endif
+
+// Sound
+/*!
+ Playing sounds
+*/
+//#define QT_NO_SOUND
+
+/*!
+ Properties
+*/
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_ICONSET)
+# define QT_NO_PROPERTIES
+#endif
+
+
+
+// Networking
+
+/*!
+ Network support
+*/
+//#define QT_NO_NETWORK
+
+#if defined(QT_NO_NETWORK) || defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM)
+ /*!
+ DNS
+ */
+# define QT_NO_DNS
+#endif
+/*!
+ Network file access
+*/
+#if defined(QT_NO_NETWORK) || defined(QT_NO_DIR) || defined(QT_NO_STRINGLIST)
+# define QT_NO_NETWORKPROTOCOL
+#endif
+#if defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS)
+ /*!
+ FTP file access
+ */
+# define QT_NO_NETWORKPROTOCOL_FTP
+ /*!
+ HTTP file access
+ */
+# define QT_NO_NETWORKPROTOCOL_HTTP
+#endif
+
+/*!
+ External process invocation.
+*/
+//#define QT_NO_PROCESS
+
+
+// Qt/Embedded-specific
+
+#if defined(QT_NO_NETWORK)
+ /*!
+ Multi-process support.
+ */
+# define QT_NO_QWS_MULTIPROCESS
+#endif
+
+#if defined(QT_NO_QWS_MULTIPROCESS) || defined(QT_NO_DATASTREAM)
+ /*!
+ Palmtop Communication Protocol
+ */
+# define QT_NO_COP
+#endif
+
+/*!
+ Console keyboard support
+*/
+//#define QT_NO_QWS_KEYBOARD
+
+/*!
+ Visible cursor
+*/
+#if defined(QT_NO_CURSOR)
+# define QT_NO_QWS_CURSOR
+#endif
+
+/*!
+ Alpha-blended cursor
+*/
+//#define QT_NO_QWS_ALPHA_CURSOR
+/*!
+ Mach64 acceleration
+*/
+//#define QT_NO_QWS_MACH64
+/*!
+ Voodoo3 acceleration
+*/
+//#define QT_NO_QWS_VOODOO3
+/*!
+ Matrox MGA acceleration (Millennium/Millennium II/Mystique/G200/G400)
+*/
+//#define QT_NO_QWS_MATROX
+/*!
+ Virtual frame buffer
+*/
+
+//#define QT_NO_QWS_VFB
+/*!
+ Transformed frame buffer
+*/
+//#define QT_NO_QWS_TRANSFORMED
+#if defined(QT_NO_NETWORK)
+/*!
+ Remote frame buffer (VNC)
+*/
+# ifndef QT_NO_QWS_VNC
+# define QT_NO_QWS_VNC
+# endif
+#endif
+/*!
+ 1-bit monochrome
+*/
+//#define QT_NO_QWS_DEPTH_1
+/*!
+ 4-bit greyscale
+*/
+//#define QT_NO_QWS_DEPTH_4
+/*!
+ 4-bit VGA
+*/
+//#define QT_NO_QWS_VGA_16
+/*!
+ SVGALib Support
+ Not implemented yet
+*/
+#define QT_NO_QWS_SVGALIB
+/*!
+ 8-bit grayscale
+*/
+#define QT_NO_QWS_DEPTH_8GRAYSCALE
+/*!
+ 8-bit color
+*/
+//#define QT_NO_QWS_DEPTH_8
+/*!
+ 15 or 16-bit color (define QT_QWS_DEPTH16_RGB as 555 for 15-bit)
+*/
+//#define QT_NO_QWS_DEPTH_16
+/*!
+ 24-bit color
+*/
+//#define QT_NO_QWS_DEPTH_24
+/*!
+ 32-bit color
+*/
+//#define QT_NO_QWS_DEPTH_32
+
+/*!
+ Window Manager
+*/
+//#define QT_NO_QWS_MANAGER
+
+/*!
+ Window Manager Styles
+*/
+#define QT_NO_QWS_KDE2_WM_STYLE
+#if defined( QT_NO_QWS_MANAGER ) || defined( QT_NO_IMAGEIO_XPM )
+# define QT_NO_QWS_AQUA_WM_STYLE
+# define QT_NO_QWS_BEOS_WM_STYLE
+# define QT_NO_QWS_KDE_WM_STYLE
+# define QT_NO_QWS_QPE_WM_STYLE
+# define QT_NO_QWS_WINDOWS_WM_STYLE
+#endif
+
+/*!
+ Saving of fonts
+*/
+//#define QT_NO_QWS_SAVEFONTS
+
+/*!
+ Favour code size over graphics speed
+ <p>Smaller, slower code will be used for drawing operations.
+ <p>Only supported on Qt/Embedded.
+*/
+//#define QT_NO_QWS_GFX_SPEED
+
+/*!
+ Qt/Embedded window system properties.
+*/
+//#define QT_NO_QWS_PROPERTIES
+
+#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME)
+ /*!
+ Cut and paste
+ */
+# define QT_NO_CLIPBOARD
+#endif
+
+#if defined(QT_NO_MIME) || defined(QT_NO_QWS_PROPERTIES)
+ /*!
+ Drag and drop
+ */
+# define QT_NO_DRAGANDDROP
+#endif
+
+#if defined(QT_NO_PROPERTIES)
+ /*!
+ SQL
+ */
+# define QT_NO_SQL
+#endif
+
+#if defined(QT_NO_CLIPBOARD) || defined(QT_NO_MIME) || defined(_WS_QWS_)
+ /*!
+ Cut and paste of complex data types (non-text)
+ Not yet implemented for QWS.
+ */
+# define QT_NO_MIMECLIPBOARD
+#endif
+
+
+/*!
+ Drawing utility functions
+*/
+//#define QT_NO_DRAWUTIL
+/*!
+ TrueColor QImage
+*/
+//#define QT_NO_IMAGE_TRUECOLOR
+/*!
+ Smooth QImage scaling
+*/
+//#define QT_NO_IMAGE_SMOOTHSCALE
+/*!
+ Image file text strings
+*/
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_IMAGE_TEXT
+#endif
+
+#if defined(QT_NO_IMAGE_TRUECOLOR)
+ /*!
+ 16-bit QImage
+ */
+# define QT_NO_IMAGE_16_BIT
+#endif
+/*!
+ Cursors
+*/
+//#define QT_NO_CURSOR
+
+// Painting
+/*!
+ Named colors
+*/
+//#define QT_NO_COLORNAMES
+/*!
+ Scaling and rotation
+*/
+//#define QT_NO_TRANSFORMATIONS
+
+/*!
+ Printing
+*/
+#if defined(QT_NO_TEXTSTREAM)
+# define QT_NO_PRINTER
+#endif
+
+/*!
+ QPicture
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_PICTURE
+#endif
+
+// Layout
+/*!
+ Automatic widget layout
+*/
+//#define QT_NO_LAYOUT
+
+// Widgets
+#if defined(QT_NO_DRAWUTIL) || defined(QT_NO_PALETTE)
+/*!
+ QStyle
+*/
+# define QT_NO_STYLE
+#endif
+
+
+/*!
+ Dialogs
+*/
+//#define QT_NO_DIALOG
+/*!
+ Semi-modal dialogs
+*/
+//#define QT_NO_SEMIMODAL
+/*!
+ Framed widgets
+*/
+//#define QT_NO_FRAME
+
+/*!
+ Special widget effects (fading, scrolling)
+*/
+//#define QT_NO_EFFECTS
+
+
+/*!
+ QLabel
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_LABEL
+#endif
+
+/*!
+ Toolbars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_TOOLBAR
+#endif
+
+/*!
+ Buttons
+*/
+#if defined(QT_NO_BUTTON) || defined(QT_NO_STYLE)
+/*!
+ Check-boxes
+*/
+# define QT_NO_CHECKBOX
+/*!
+ Radio-buttons
+*/
+# define QT_NO_RADIOBUTTON
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_TOOLBAR) || defined(QT_NO_ICONSET)
+/*!
+ Tool-buttons
+*/
+# define QT_NO_TOOLBUTTON
+#endif
+/*!
+ Grid layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GRID
+#endif
+/*!
+ Group boxes
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GROUPBOX
+#endif
+#if defined(QT_NO_GROUPBOX)
+/*!
+ Button groups
+*/
+# define QT_NO_BUTTONGROUP
+/*!
+ Horizontal group boxes
+*/
+# define QT_NO_HGROUPBOX
+#endif
+#if defined(QT_NO_HGROUPBOX)
+/*!
+ Vertical group boxes
+*/
+# define QT_NO_VGROUPBOX
+#endif
+#if defined(QT_NO_BUTTONGROUP)
+/*!
+ Horizontal button groups
+*/
+# define QT_NO_HBUTTONGROUP
+#endif
+#if defined(QT_NO_HBUTTONGROUP)
+/*!
+ Vertical button groups
+*/
+# define QT_NO_VBUTTONGROUP
+#endif
+/*!
+ Horizonal box layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_HBOX
+#endif
+#if defined(QT_NO_HBOX)
+/*!
+ Vertical box layout widgets
+*/
+# define QT_NO_VBOX
+#endif
+/*!
+ Single-line edits
+*/
+#if defined(QT_NO_PALETTE)
+# define QT_NO_LINEEDIT
+#endif
+#if defined(QT_NO_TOOLBAR)
+/*!
+ Main-windows
+*/
+# define QT_NO_MAINWINDOW
+#endif
+#if defined(QT_NO_ICONSET)
+/*!
+ Menu-like widgets
+*/
+# define QT_NO_MENUDATA
+#endif
+#if defined(QT_NO_MENUDATA)
+/*!
+ Popup-menus
+*/
+# define QT_NO_POPUPMENU
+/*!
+ Menu bars
+*/
+# define QT_NO_MENUBAR
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_ICONSET) || defined(QT_NO_POPUPMENU)
+/*!
+ Push-buttons
+*/
+# define QT_NO_PUSHBUTTON
+#endif
+/*!
+ Progress bars
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_PROGRESSBAR
+#endif
+/*!
+ Range-control widgets
+*/
+//#define QT_NO_RANGECONTROL
+#if defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE)
+/*!
+ Scroll bars
+*/
+# define QT_NO_SCROLLBAR
+/*!
+ Sliders
+*/
+# define QT_NO_SLIDER
+/*!
+ Spin boxes
+*/
+# define QT_NO_SPINBOX
+/*!
+ Dials
+*/
+# define QT_NO_DIAL
+#endif
+
+
+#if defined(QT_NO_SCROLLBAR) || defined(QT_NO_FRAME)
+/*!
+ Scrollable view widgets
+*/
+# define QT_NO_SCROLLVIEW
+#endif
+#if defined(QT_NO_SCROLLVIEW)
+/*!
+ QCanvas
+*/
+# define QT_NO_CANVAS
+/*!
+ QIconView
+*/
+# define QT_NO_ICONVIEW
+#endif
+
+#if defined(QT_NO_SCROLLBAR)
+/*!
+ Table-like widgets
+*/
+# define QT_NO_TABLEVIEW
+#endif
+#if defined(QT_NO_TABLEVIEW)
+/*!
+ Multi-line edits
+*/
+# define QT_NO_MULTILINEEDIT
+#endif
+
+/*!
+ Splitters
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_SPLITTER
+#endif
+/*!
+ Status bars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_STATUSBAR
+#endif
+/*!
+ Tab-bars
+*/
+#if defined(QT_NO_ICONSET)
+# define QT_NO_TABBAR
+#endif
+#if defined(QT_NO_TABBAR)
+/*!
+ Tab widgets
+*/
+# define QT_NO_TABWIDGET
+#endif
+/*!
+ Tool tips
+*/
+#if defined( QT_NO_LABEL ) || defined( QT_NO_PALETTE )
+# define QT_NO_TOOLTIP
+#endif
+/*!
+ Input validators
+*/
+//#define QT_NO_VALIDATOR
+/*!
+ "What's this" help
+*/
+#if defined( QT_NO_TOOLTIP )
+# define QT_NO_WHATSTHIS
+#endif
+/*!
+ Widget stacks
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_WIDGETSTACK
+#endif
+
+#if defined(QT_NO_RICHTEXT) || defined(QT_NO_SCROLLVIEW)
+ /*!
+ QTextView
+ */
+# define QT_NO_TEXTVIEW
+#endif
+
+#if defined(QT_NO_TEXTVIEW)
+ /*!
+ QTextBrowser
+ */
+# define QT_NO_TEXTBROWSER
+#endif
+
+#if defined(QT_NO_STYLE)
+ /*!
+ Windows style
+ */
+# define QT_NO_STYLE_WINDOWS
+ /*!
+ Motif style
+ */
+# define QT_NO_STYLE_MOTIF
+#endif
+
+#if defined(QT_NO_STYLE_MOTIF)
+ /*!
+ Motif-plus style
+ */
+# define QT_NO_STYLE_MOTIFPLUS
+#endif
+
+
+#if defined(QT_NO_SCROLLVIEW) || defined(QT_NO_STRINGLIST)
+ /*!
+ QListBox
+ */
+# define QT_NO_LISTBOX
+#endif
+
+/*!
+ QAccel
+*/
+//#define QT_NO_ACCEL
+
+/*!
+ QSizeGrip
+*/
+#ifdef QT_NO_PALETTE
+# define QT_NO_SIZEGRIP
+#endif
+/*!
+ QHeader
+*/
+#ifdef QT_NO_ICONSET
+# define QT_NO_HEADER
+#endif
+/*!
+ QWorkSpace
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_WORKSPACE
+#endif
+/*!
+ QLCDNumber
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_LCDNUMBER
+#endif
+/*!
+ QAction
+*/
+//#define QT_NO_ACTION
+
+#if defined(QT_NO_HEADER)
+ /*!
+ QTable
+ */
+# define QT_NO_TABLE
+#endif
+
+#if defined(QT_NO_LISTBOX)
+ /*!
+ QComboBox
+ */
+# define QT_NO_COMBOBOX
+#endif
+
+#if defined(QT_NO_HEADER) || defined(QT_NO_SCROLLVIEW)
+ /*!
+ QListView
+ */
+# define QT_NO_LISTVIEW
+#endif
+
+#if defined(QT_NO_STYLE_WINDOWS)
+ /*!
+ Compact Windows style
+ */
+# define QT_NO_STYLE_COMPACT
+#endif
+
+#if defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS)
+ /*!
+ CDE style
+ */
+# define QT_NO_STYLE_CDE
+ /*!
+ SGI style
+ */
+# define QT_NO_STYLE_SGI
+#endif
+#if defined(QT_NO_STYLE_WINDOWS)
+ /*!
+ Platinum style
+ */
+# define QT_NO_STYLE_PLATINUM
+#endif
+
+/*!
+ QColorDialog
+*/
+#if defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_DIALOG)
+# define QT_NO_COLORDIALOG
+#endif
+#if defined(QT_NO_DIALOG)
+/*!
+ QMessageBox
+*/
+# define QT_NO_MESSAGEBOX
+#endif
+#if defined(QT_NO_DIALOG) || defined(QT_NO_TABBAR)
+/*!
+ QTabDialog
+*/
+#define QT_NO_TABDIALOG
+#endif
+
+#if defined(QT_NO_DIALOG)
+/*!
+ QWizard
+*/
+# define QT_NO_WIZARD
+#endif
+
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_MESSAGEBOX) || defined(QT_NO_SEMIMODAL)
+ /*!
+ QFileDialog
+ */
+# define QT_NO_FILEDIALOG
+#endif
+
+#if defined(QT_NO_DIALOG) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX)
+ /*!
+ QFontDialog
+ */
+# define QT_NO_FONTDIALOG
+#endif
+
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL)
+ /*!
+ QPrintDialog
+ */
+# define QT_NO_PRINTDIALOG
+#endif
+
+#if defined(QT_NO_SEMIMODAL)
+ /*!
+ QProgressDialog
+ */
+# define QT_NO_PROGRESSDIALOG
+#endif
+#if defined(QT_NO_DIALOG) || defined(QT_NO_COMBOBOX)
+ /*!
+ QInputDialog
+ */
+# define QT_NO_INPUTDIALOG
+#endif
+
+#if defined(QT_NO_STRINGLIST)
+ /*!
+ Session management support
+ */
+# define QT_NO_SESSIONMANAGER
+#endif
+
+#endif // QFEATURES_H
diff --git a/qtools/qfile.cpp b/qtools/qfile.cpp
new file mode 100644
index 0000000..98ed9a3
--- /dev/null
+++ b/qtools/qfile.cpp
@@ -0,0 +1,550 @@
+/****************************************************************************
+**
+**
+** Implementation of QFile class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+#if defined(_OS_WIN32_)
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#endif
+#endif
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+extern bool qt_file_access( const QString& fn, int t );
+
+// NOT REVISED
+/*!
+ \class QFile qfile.h
+ \brief The QFile class is an I/O device that operates on files.
+
+ \ingroup io
+
+ QFile is an I/O device for reading and writing binary and text files. A
+ QFile may be used by itself (readBlock and writeBlock) or by more
+ conveniently using QDataStream or QTextStream.
+
+ Here is a code fragment that uses QTextStream to read a text
+ file line by line. It prints each line with a line number.
+ \code
+ QFile f("file.txt");
+ if ( f.open(IO_ReadOnly) ) { // file opened successfully
+ QTextStream t( &f ); // use a text stream
+ QString s;
+ int n = 1;
+ while ( !t.eof() ) { // until end of file...
+ s = t.readLine(); // line of text excluding '\n'
+ printf( "%3d: %s\n", n++, (const char *)s );
+ }
+ f.close();
+ }
+ \endcode
+
+ The QFileInfo class holds detailed information about a file, such as
+ access permissions, file dates and file types.
+
+ The QDir class manages directories and lists of file names.
+
+ \sa QDataStream, QTextStream
+*/
+
+
+/*!
+ Constructs a QFile with no name.
+*/
+
+QFile::QFile()
+{
+ init();
+}
+
+/*!
+ Constructs a QFile with a file name \e name.
+ \sa setName()
+*/
+
+QFile::QFile( const QString &name )
+ : fn(name)
+{
+ init();
+}
+
+
+/*!
+ Destructs a QFile. Calls close().
+*/
+
+QFile::~QFile()
+{
+ close();
+}
+
+
+/*!
+ \internal
+ Initialize internal data.
+*/
+
+void QFile::init()
+{
+ setFlags( IO_Direct );
+ setStatus( IO_Ok );
+ fh = 0;
+ fd = 0;
+ length = 0;
+ ioIndex = 0;
+ ext_f = FALSE; // not an external file handle
+}
+
+
+/*!
+ \fn QString QFile::name() const
+ Returns the name set by setName().
+ \sa setName(), QFileInfo::fileName()
+*/
+
+/*!
+ Sets the name of the file. The name can include an absolute directory
+ path or it can be a name or a path relative to the current directory.
+
+ Do not call this function if the file has already been opened.
+
+ Note that if the name is relative QFile does not associate it with the
+ current directory. If you change directory before calling open(), open
+ uses the new current directory.
+
+ Example:
+ \code
+ QFile f;
+ QDir::setCurrent( "/tmp" );
+ f.setName( "readme.txt" );
+ QDir::setCurrent( "/home" );
+ f.open( IO_ReadOnly ); // opens "/home/readme.txt" under UNIX
+ \endcode
+
+ Also note that the directory separator '/' works for all operating
+ systems supported by Qt.
+
+ \sa name(), QFileInfo, QDir
+*/
+
+void QFile::setName( const QString &name )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::setName: File is open" );
+#endif
+ close();
+ }
+ fn = name;
+}
+
+/*!
+ Returns TRUE if this file exists, otherwise FALSE.
+ \sa name()
+*/
+
+bool QFile::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Returns TRUE if the file given by \e fileName exists, otherwise FALSE.
+*/
+
+bool QFile::exists( const QString &fileName )
+{
+ return qt_file_access( fileName, F_OK );
+}
+
+
+/*!
+ Removes the file specified by the file name currently set.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The file is closed before it is removed.
+*/
+
+bool QFile::remove()
+{
+ close();
+ return remove( fn );
+}
+
+#if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_) || defined(_OS_CYGWIN_)
+# define HAS_TEXT_FILEMODE // has translate/text filemode
+#endif
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Flushes the file buffer to the disk.
+
+ close() also flushes the file buffer.
+*/
+
+void QFile::flush()
+{
+ if ( isOpen() && fh ) // can only flush open/buffered
+ fflush( fh ); // file
+}
+
+/*!
+ Returns TRUE if the end of file has been reached, otherwise FALSE.
+ \sa size()
+*/
+
+bool QFile::atEnd() const
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::atEnd: File is not open" );
+#endif
+ return FALSE;
+ }
+ if ( isDirectAccess() && !isTranslated() ) {
+ if ( at() < length )
+ return FALSE;
+ }
+ return QIODevice::atEnd();
+}
+
+/*!
+ Reads a line of text.
+
+ Reads bytes from the file until end-of-line is reached, or up to \a
+ maxlen bytes, and returns the number of bytes read, or -1 in case of
+ error. The terminating newline is not stripped.
+
+ This function is efficient only for buffered files. Avoid
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QFile::readLine( char *p, uint maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readLine: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = QIODevice::readLine( p, maxlen );
+ } else { // buffered file
+ p = fgets( p, maxlen, fh );
+ if ( p ) {
+ nread = qstrlen( p );
+ ioIndex += nread;
+ } else {
+ nread = -1;
+ setStatus(IO_ReadError);
+ }
+ }
+ return nread;
+}
+
+
+/*!
+ Reads a line of text.
+
+ Reads bytes from the file until end-of-line is reached, or up to \a
+ maxlen bytes, and returns the number of bytes read, or -1 in case of
+ error. The terminating newline is not stripped.
+
+ This function is efficient only for buffered files. Avoid
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ Note that the string is read as plain Latin1 bytes, not Unicode.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QFile::readLine( QString& s, uint maxlen )
+{
+ QByteArray ba(maxlen);
+ int l = readLine(ba.data(),maxlen);
+ if ( l >= 0 ) {
+ ba.truncate(l);
+ s = QString(ba);
+ }
+ return l;
+}
+
+
+/*!
+ Reads a single byte/character from the file.
+
+ Returns the byte/character read, or -1 if the end of the file has been
+ reached.
+
+ \sa putch(), ungetch()
+*/
+
+int QFile::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::getch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::getch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+
+ int ch;
+
+ if ( !ungetchBuffer.isEmpty() ) {
+ int len = ungetchBuffer.length();
+ ch = ungetchBuffer[ len-1 ];
+ ungetchBuffer.truncate( len - 1 );
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
+ } else { // buffered file
+ if ( (ch = getc( fh )) != EOF )
+ ioIndex++;
+ else
+ setStatus(IO_ReadError);
+ }
+ return ch;
+}
+
+/*!
+ \fn int QFile::writeBlock( const QByteArray& data )
+ \reimp
+ \internal
+ Should be removed in 3.0
+*/
+
+/*!
+ Writes the character \e ch to the file.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int QFile::putch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::putch: File not open" );
+ return EOF;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::putch: Write operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ buf[0] = ch;
+ ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
+ } else { // buffered file
+ if ( (ch = putc( ch, fh )) != EOF ) {
+ ioIndex++;
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ } else {
+ setStatus(IO_WriteError);
+ }
+ }
+ return ch;
+}
+
+/*!
+ Puts the character \e ch back into the file and decrements the index if it
+ is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ \sa getch(), putch()
+*/
+
+int QFile::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::ungetch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::ungetch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( ch == EOF ) // cannot unget EOF
+ return ch;
+
+ if ( isSequentialAccess() && !fh) {
+ // pipe or similar => we cannot ungetch, so do it manually
+ ungetchBuffer +=ch;
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (very inefficient)
+ char buf[1];
+ at( ioIndex-1 );
+ buf[0] = ch;
+ if ( writeBlock(buf, 1) == 1 )
+ at ( ioIndex-1 );
+ else
+ ch = EOF;
+ } else { // buffered file
+ if ( (ch = ungetc(ch, fh)) != EOF )
+ ioIndex--;
+ else
+ setStatus( IO_ReadError );
+ }
+ return ch;
+}
+
+
+static QCString locale_encoder( const QString &fileName )
+{
+ return fileName.local8Bit();
+}
+
+
+static QFile::EncoderFn encoder = locale_encoder;
+
+/*!
+ When you use QFile, QFileInfo, and QDir to access the filesystem
+ with Qt, you can use Unicode filenames. On Unix, these filenames
+ are converted to an 8-bit encoding. If you want to do your own
+ file I/O on Unix, you should convert the filename using this
+ function. On Windows NT, Unicode filenames are supported directly
+ in the filesystem and this function should be avoided. On Windows 95,
+ non-Latin1 locales are not supported at this time.
+
+ By default, this function converts to the local 8-bit encoding
+ determined by the user's locale. This is sufficient for
+ filenames that the user chooses. Filenames hard-coded into the
+ application should only use 7-bit ASCII filename characters.
+
+ The conversion scheme can be changed using setEncodingFunction().
+ This might be useful if you wish to give the user an option to
+ store in filenames in UTF-8, etc., but beware that such filenames
+ would probably then be unrecognizable when seen by other programs.
+
+ \sa decodeName()
+*/
+
+QCString QFile::encodeName( const QString &fileName )
+{
+ return (*encoder)(fileName);
+}
+
+/*!
+ \enum QFile::EncoderFn
+
+ This is used by QFile::setEncodingFunction().
+*/
+
+/*!
+ Sets the function for encoding Unicode filenames.
+ The default encodes in the locale-specific 8-bit encoding.
+
+ \sa encodeName()
+*/
+void QFile::setEncodingFunction( EncoderFn f )
+{
+ encoder = f;
+}
+
+static
+QString locale_decoder( const QCString &localFileName )
+{
+ return QString::fromLocal8Bit(localFileName);
+}
+
+static QFile::DecoderFn decoder = locale_decoder;
+
+/*!
+ This does the reverse of QFile::encodeName().
+
+ \sa setDecodingFunction()
+*/
+QString QFile::decodeName( const QCString &localFileName )
+{
+ return (*decoder)(localFileName);
+}
+
+/*!
+ \enum QFile::DecoderFn
+
+ This is used by QFile::setDecodingFunction().
+*/
+
+/*!
+ Sets the function for decoding 8-bit filenames.
+ The default uses the locale-specific 8-bit encoding.
+
+ \sa encodeName(), decodeName()
+*/
+
+void QFile::setDecodingFunction( DecoderFn f )
+{
+ decoder = f;
+}
diff --git a/qtools/qfile.h b/qtools/qfile.h
new file mode 100644
index 0000000..a447d2f
--- /dev/null
+++ b/qtools/qfile.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+**
+** Definition of QFile class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QFILE_H
+#define QFILE_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#include <stdio.h>
+#endif // QT_H
+
+class QDir;
+
+
+class Q_EXPORT QFile : public QIODevice // file I/O device class
+{
+public:
+ QFile();
+ QFile( const QString &name );
+ virtual ~QFile();
+
+ QString name() const;
+ void setName( const QString &name );
+
+ typedef QCString (*EncoderFn)( const QString &fileName );
+ typedef QString (*DecoderFn)( const QCString &localfileName );
+ static QCString encodeName( const QString &fileName );
+ static QString decodeName( const QCString &localFileName );
+ static void setEncodingFunction( EncoderFn );
+ static void setDecodingFunction( DecoderFn );
+
+ bool exists() const;
+ static bool exists( const QString &fileName );
+
+ bool remove();
+ static bool remove( const QString &fileName );
+
+ bool open( int );
+ bool open( int, FILE * );
+ bool open( int, int );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const;
+ bool at( int );
+ bool atEnd() const;
+
+ int readBlock( char *data, uint len );
+ int writeBlock( const char *data, uint len );
+ int writeBlock( const QByteArray& data )
+ { return QIODevice::writeBlock(data); }
+ int readLine( char *data, uint maxlen );
+ int readLine( QString &, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+ int handle() const;
+
+ int64 pos() const;
+ int64 toEnd();
+ bool seek(int64 pos);
+
+protected:
+ QString fn;
+ FILE *fh;
+ int fd;
+ int length;
+ bool ext_f;
+ void * d;
+
+private:
+ void init();
+ QCString ungetchBuffer;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QFile( const QFile & );
+ QFile &operator=( const QFile & );
+#endif
+};
+
+
+inline QString QFile::name() const
+{ return fn; }
+
+inline int QFile::at() const
+{ return ioIndex; }
+
+
+#endif // QFILE_H
diff --git a/qtools/qfile_unix.cpp b/qtools/qfile_unix.cpp
new file mode 100644
index 0000000..0422fb4
--- /dev/null
+++ b/qtools/qfile_unix.cpp
@@ -0,0 +1,668 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
+** with the Qt Commercial License Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+#if (defined(_OS_MAC_) && (!defined(_OS_UNIX_))) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_) || defined(_OS_CYGWIN_)
+# define HAS_TEXT_FILEMODE // has translate/text filemode
+#endif
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+bool qt_file_access( const QString& fn, int t )
+{
+ if ( fn.isEmpty() )
+ return FALSE;
+ return ACCESS( QFile::encodeName(fn), t ) == 0;
+}
+
+/*!
+ Removes the file \a fileName.
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QFile::remove( const QString &fileName )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QFile::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ return unlink( QFile::encodeName(fileName) ) == 0;
+ // unlink more common in UNIX
+}
+
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Opens the file specified by the file name currently set, using the mode \e m.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The mode parameter \e m must be a combination of the following flags:
+ <ul>
+ <li>\c IO_Raw specified raw (non-buffered) file access.
+ <li>\c IO_ReadOnly opens the file in read-only mode.
+ <li>\c IO_WriteOnly opens the file in write-only mode (and truncates).
+ <li>\c IO_ReadWrite opens the file in read/write mode, equivalent to
+ \c (IO_ReadOnly|IO_WriteOnly).
+ <li>\c IO_Append opens the file in append mode. This mode is very useful
+ when you want to write something to a log file. The file index is set to
+ the end of the file. Note that the result is undefined if you position the
+ file index manually using at() in append mode.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Windows and OS/2.
+ </ul>
+
+ The raw access mode is best when I/O is block-operated using 4kB block size
+ or greater. Buffered access works better when reading small portions of
+ data at a time.
+
+ <strong>Important:</strong> When working with buffered files, data may
+ not be written to the file at once. Call \link flush() flush\endlink
+ to make sure the data is really written.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is
+ specified, it is created.
+
+ Example:
+ \code
+ QFile f1( "/tmp/data.bin" );
+ QFile f2( "readme.txt" );
+ f1.open( IO_Raw | IO_ReadWrite | IO_Append );
+ f2.open( IO_ReadOnly | IO_Translate );
+ \endcode
+
+ \sa name(), close(), isOpen(), flush()
+*/
+
+bool QFile::open( int m )
+{
+ if ( isOpen() ) { // file already open
+#if defined(CHECK_STATE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ if ( fn.isNull() ) { // no file name defined
+#if defined(CHECK_NULL)
+ qWarning( "QFile::open: No file name specified" );
+#endif
+ return FALSE;
+ }
+ init(); // reset params
+ setMode( m );
+ if ( !(isReadable() || isWritable()) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File access not specified" );
+#endif
+ return FALSE;
+ }
+ bool ok = TRUE;
+ STATBUF st;
+ if ( isRaw() ) { // raw file I/O
+ int oflags = OPEN_RDONLY;
+ if ( isReadable() && isWritable() )
+ oflags = OPEN_RDWR;
+ else if ( isWritable() )
+ oflags = OPEN_WRONLY;
+ if ( flags() & IO_Append ) { // append to end of file?
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= (OPEN_APPEND | OPEN_CREAT);
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ } else if ( isWritable() ) { // create/trunc if writable
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= OPEN_CREAT;
+ }
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+#ifdef __CYGWIN__
+ /* Do nothing, allowing the Cygwin mount mode to take effect. */;
+#else
+ oflags |= OPEN_TEXT;
+#endif
+ else
+ oflags |= OPEN_BINARY;
+#endif
+#if defined(HAS_ASYNC_FILEMODE)
+ if ( isAsynchronous() )
+ oflags |= OPEN_ASYNC;
+#endif
+ fd = OPEN( QFile::encodeName(fn), oflags, 0666 );
+
+ if ( fd != -1 ) { // open successful
+ FSTAT( fd, &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ } else { // buffered file I/O
+ QCString perm;
+ char perm2[4];
+ bool try_create = FALSE;
+ if ( flags() & IO_Append ) { // append to end of file?
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ perm = isReadable() ? "a+" : "a";
+ } else {
+ if ( isReadWrite() ) {
+ if ( flags() & IO_Truncate ) {
+ perm = "w+";
+ } else {
+ perm = "r+";
+ try_create = TRUE; // try to create if not exists
+ }
+ } else if ( isReadable() ) {
+ perm = "r";
+ } else if ( isWritable() ) {
+ perm = "w";
+ }
+ }
+ qstrcpy( perm2, perm );
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+#ifdef __CYGWIN__
+ /* Do nothing, allowing the Cygwin mount mode to take effect. */;
+#else
+ strcat( perm2, "t" );
+#endif
+ else
+ strcat( perm2, "b" );
+#endif
+ while (1) { // At most twice
+
+ fh = fopen( QFile::encodeName(fn), perm2 );
+
+ if ( !fh && try_create ) {
+ perm2[0] = 'w'; // try "w+" instead of "r+"
+ try_create = FALSE;
+ } else {
+ break;
+ }
+ }
+ if ( fh ) {
+ FSTAT( FILENO(fh), &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ }
+ if ( ok ) {
+ setState( IO_Open );
+ // on successful open the file stat was got; now test what type
+ // of file we have
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ } else {
+ length = (int)st.st_size;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ } else {
+ init();
+ if ( errno == EMFILE ) // no more file handles/descrs
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_OpenError );
+ }
+ return ok;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file handle \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ #include <stdio.h>
+
+ void printError( const char* msg )
+ {
+ QFile f;
+ f.open( IO_WriteOnly, stderr );
+ f.writeBlock( msg, qstrlen(msg) ); // write to stderr
+ f.close();
+ }
+ \endcode
+
+ When a QFile is opened using this function, close() does not actually
+ close the file, only flushes it.
+
+ \warning If \e f is \c stdin, \c stdout, \c stderr, you may not
+ be able to seek. See QIODevice::isSequentialAccess() for more
+ information.
+
+ \sa close()
+*/
+
+bool QFile::open( int m, FILE *f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m &~IO_Raw );
+ setState( IO_Open );
+ fh = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( FILENO(fh), &st );
+ ioIndex = (int)ftell( fh );
+ if ( (st.st_mode & STAT_MASK) != STAT_REG || f == stdin ) { //stdin is non seekable
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file descriptor \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ When a QFile is opened using this function, close() does not actually
+ close the file.
+
+ \warning If \e f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
+ be able to seek. size() is set to \c INT_MAX (in limits.h).
+
+ \sa close()
+*/
+
+
+bool QFile::open( int m, int f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m |IO_Raw );
+ setState( IO_Open );
+ fd = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( fd, &st );
+ ioIndex = (int)LSEEK(fd, 0, SEEK_CUR);
+ if ( (st.st_mode & STAT_MASK) != STAT_REG || f == 0 ) { // stdin is not seekable...
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ resetStatus();
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the file size.
+ \sa at()
+*/
+
+uint QFile::size() const
+{
+ STATBUF st;
+ if ( isOpen() ) {
+ FSTAT( fh ? FILENO(fh) : fd, &st );
+ } else {
+ STAT( QFile::encodeName(fn), &st );
+ }
+ return (uint)st.st_size;
+}
+
+/*!
+ \fn int QFile::at() const
+ Returns the file index.
+ \sa size()
+*/
+
+/*!
+ Sets the file index to \e pos. Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ QFile f( "data.bin" );
+ f.open( IO_ReadOnly ); // index set to 0
+ f.at( 100 ); // set index to 100
+ f.at( f.at()+50 ); // set index to 150
+ f.at( f.size()-80 ); // set index to 80 before EOF
+ f.close();
+ \endcode
+
+ \warning The result is undefined if the file was \link open() opened\endlink
+ using the \c IO_Append specifier.
+
+ \sa size(), open()
+*/
+
+bool QFile::at( int pos )
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::at: File is not open" );
+#endif
+ return FALSE;
+ }
+ bool ok;
+ if ( isRaw() ) { // raw file
+ pos = (int)LSEEK(fd, pos, SEEK_SET);
+ ok = pos != -1;
+ } else { // buffered file
+ ok = fseek(fh, pos, SEEK_SET) == 0;
+ }
+ if ( ok )
+ ioIndex = pos;
+#if defined(CHECK_RANGE)
+ else
+ qWarning( "QFile::at: Cannot set file position %d", pos );
+#endif
+ return ok;
+}
+
+/*!
+ Reads at most \e len bytes from the file into \e p and returns the
+ number of bytes actually read.
+
+ Returns -1 if a serious error occurred.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ \sa writeBlock()
+*/
+
+int QFile::readBlock( char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( !p )
+ qWarning( "QFile::readBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readBlock: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread = 0; // number of bytes read
+ if ( !ungetchBuffer.isEmpty() ) {
+ // need to add these to the returned string.
+ int l = ungetchBuffer.length();
+ while( nread < l ) {
+ *p = ungetchBuffer[ l - nread - 1 ];
+ p++;
+ nread++;
+ }
+ ungetchBuffer.truncate( l - nread );
+ }
+
+ if ( nread < (int)len ) {
+ if ( isRaw() ) { // raw file
+ nread += (int)READ( fd, p, len-nread );
+ if ( len && nread <= 0 ) {
+ nread = 0;
+ setStatus(IO_ReadError);
+ }
+ } else { // buffered file
+ nread += (int)fread( p, 1, len-nread, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 )
+ setStatus(IO_ReadError);
+ }
+ }
+ }
+ ioIndex += nread;
+ return nread;
+}
+
+/*! \overload int writeBlock( const QByteArray& data )
+*/
+
+/*! \reimp
+
+ Writes \e len bytes from \e p to the file and returns the number of
+ bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure the data is really
+ written.
+
+ \sa readBlock()
+*/
+
+int QFile::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QFile::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::writeBlock: File not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ int nwritten; // number of bytes written
+ if ( isRaw() ) // raw file
+ nwritten = (int)WRITE( fd, p, len );
+ else // buffered file
+ nwritten = (int)fwrite( p, 1, len, fh );
+ if ( nwritten != (int)len ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_WriteError );
+ if ( isRaw() ) // recalc file position
+ ioIndex = (int)LSEEK( fd, 0, SEEK_CUR );
+ else
+ ioIndex = fseek( fh, 0, SEEK_CUR );
+ } else {
+ ioIndex += nwritten;
+ }
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ return nwritten;
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
+
+ If the file is not open or there is an error, handle() returns -1.
+
+ \sa QSocketNotifier
+*/
+
+int QFile::handle() const
+{
+ if ( !isOpen() )
+ return -1;
+ else if ( fh )
+ return FILENO( fh );
+ else
+ return fd;
+}
+
+/*!
+ Closes an open file.
+
+ The file is not closed if it was opened with an existing file handle.
+ If the existing file handle is a \c FILE*, the file is flushed.
+ If the existing file handle is an \c int file descriptor, nothing
+ is done to the file.
+
+ Some "write-behind" filesystems may report an unspecified error on
+ closing the file. These errors only indicate that something may
+ have gone wrong since the previous open(). In such a case status()
+ reports IO_UnspecifiedError after close(), otherwise IO_Ok.
+
+ \sa open(), flush()
+*/
+
+
+void QFile::close()
+{
+ bool ok = FALSE;
+ if ( isOpen() ) { // file is not open
+ if ( fh ) { // buffered file
+ if ( ext_f )
+ ok = fflush( fh ) != -1; // flush instead of closing
+ else
+ ok = fclose( fh ) != -1;
+ } else { // raw file
+ if ( ext_f )
+ ok = TRUE; // cannot close
+ else
+ ok = CLOSE( fd ) != -1;
+ }
+ init(); // restore internal state
+ }
+ if (!ok)
+ setStatus (IO_UnspecifiedError);
+
+ return;
+}
+
+int64 QFile::pos() const
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ return ftell( fh );
+ }
+ return -1;
+}
+
+int64 QFile::toEnd()
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ if (fseek( fh, 0, SEEK_END )!=-1)
+ {
+ return ftell( fh );
+ }
+ }
+ return -1;
+}
+
+bool QFile::seek( int64 pos )
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ return fseek( fh, (long)pos, SEEK_SET )!=-1;
+ }
+ return FALSE;
+}
+
diff --git a/qtools/qfile_win32.cpp b/qtools/qfile_win32.cpp
new file mode 100644
index 0000000..80ad628
--- /dev/null
+++ b/qtools/qfile_win32.cpp
@@ -0,0 +1,678 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2001 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qfile_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+#include "qglobal.h"
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+#if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_)
+# define HAS_TEXT_FILEMODE // has translate/text filemode
+#endif
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+static void reslashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '/' )
+ n[i] = '\\';
+ }
+}
+
+bool qt_file_access( const QString& fn, int t )
+{
+ if ( fn.isEmpty() )
+ return FALSE;
+#if defined(__CYGWIN32_)
+ return ACCESS( QFile::encodeName(fn), t ) == 0;
+#else
+ QString str = fn;
+ reslashify(str);
+ return ( _waccess( (wchar_t*) str.ucs2(), t ) == 0 );
+#endif
+}
+
+/*!
+ Removes the file \a fileName.
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QFile::remove( const QString &fileName )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QFile::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+#if defined(__CYGWIN32_)
+ // unlink more common in UNIX
+ return ::remove( QFile::encodeName(fileName) ) == 0;
+#else
+ QString str = fileName;
+ reslashify(str);
+ return ( _wunlink( (wchar_t*) str.ucs2() ) == 0 );
+#endif
+}
+
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Opens the file specified by the file name currently set, using the mode \e m.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The mode parameter \e m must be a combination of the following flags:
+ <ul>
+ <li>\c IO_Raw specified raw (non-buffered) file access.
+ <li>\c IO_ReadOnly opens the file in read-only mode.
+ <li>\c IO_WriteOnly opens the file in write-only mode (and truncates).
+ <li>\c IO_ReadWrite opens the file in read/write mode, equivalent to
+ \c (IO_ReadOnly|IO_WriteOnly).
+ <li>\c IO_Append opens the file in append mode. This mode is very useful
+ when you want to write something to a log file. The file index is set to
+ the end of the file. Note that the result is undefined if you position the
+ file index manually using at() in append mode.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Windows and OS/2.
+ </ul>
+
+ The raw access mode is best when I/O is block-operated using 4kB block size
+ or greater. Buffered access works better when reading small portions of
+ data at a time.
+
+ <strong>Important:</strong> When working with buffered files, data may
+ not be written to the file at once. Call \link flush() flush\endlink
+ to make sure the data is really written.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is
+ specified, it is created.
+
+ Example:
+ \code
+ QFile f1( "/tmp/data.bin" );
+ QFile f2( "readme.txt" );
+ f1.open( IO_Raw | IO_ReadWrite | IO_Append );
+ f2.open( IO_ReadOnly | IO_Translate );
+ \endcode
+
+ \sa name(), close(), isOpen(), flush()
+*/
+
+bool QFile::open( int m )
+{
+ if ( isOpen() ) { // file already open
+#if defined(CHECK_STATE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ if ( fn.isNull() ) { // no file name defined
+#if defined(CHECK_NULL)
+ qWarning( "QFile::open: No file name specified" );
+#endif
+ return FALSE;
+ }
+ init(); // reset params
+ setMode( m );
+ if ( !(isReadable() || isWritable()) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File access not specified" );
+#endif
+ return FALSE;
+ }
+ bool ok = TRUE;
+ STATBUF st;
+ if ( isRaw() ) { // raw file I/O
+ int oflags = OPEN_RDONLY;
+ if ( isReadable() && isWritable() )
+ oflags = OPEN_RDWR;
+ else if ( isWritable() )
+ oflags = OPEN_WRONLY;
+ if ( flags() & IO_Append ) { // append to end of file?
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= (OPEN_APPEND | OPEN_CREAT);
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ } else if ( isWritable() ) { // create/trunc if writable
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= OPEN_CREAT;
+ }
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ oflags |= OPEN_TEXT;
+ else
+ oflags |= OPEN_BINARY;
+#endif
+#if defined(HAS_ASYNC_FILEMODE)
+ if ( isAsynchronous() )
+ oflags |= OPEN_ASYNC;
+#endif
+
+
+#if defined(__CYGWIN32_)
+ fd = OPEN( QFile::encodeName(fn), oflags, 0666 );
+#else
+ QString str = fn;
+ reslashify(str);
+ fd = _wopen( (wchar_t*) str.ucs2(), oflags, 0666 );
+#endif
+
+ if ( fd != -1 ) { // open successful
+ FSTAT( fd, &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ } else { // buffered file I/O
+ QCString perm;
+ char perm2[4];
+ bool try_create = FALSE;
+ if ( flags() & IO_Append ) { // append to end of file?
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ perm = isReadable() ? "a+" : "a";
+ } else {
+ if ( isReadWrite() ) {
+ if ( flags() & IO_Truncate ) {
+ perm = "w+";
+ } else {
+ perm = "r+";
+ try_create = TRUE; // try to create if not exists
+ }
+ } else if ( isReadable() ) {
+ perm = "r";
+ } else if ( isWritable() ) {
+ perm = "w";
+ }
+ }
+ qstrcpy( perm2, perm );
+ if ( isTranslated() )
+ strcat( perm2, "t" );
+ else
+ strcat( perm2, "b" );
+ while (1) { // At most twice
+
+#if defined(__CYGWIN32_)
+ fh = fopen( QFile::encodeName(fn), perm2 );
+#else
+ QString str = fn;
+ QString prm( perm2 );
+ reslashify(str);
+ fh = _wfopen( (wchar_t*) str.ucs2(), (wchar_t*) prm.ucs2() );
+#endif
+
+ if ( !fh && try_create ) {
+ perm2[0] = 'w'; // try "w+" instead of "r+"
+ try_create = FALSE;
+ } else {
+ break;
+ }
+ }
+ if ( fh ) {
+ FSTAT( FILENO(fh), &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ }
+ if ( ok ) {
+ setState( IO_Open );
+ // on successful open the file stat was got; now test what type
+ // of file we have
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ } else {
+ length = (int)st.st_size;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ } else {
+ init();
+ if ( errno == EMFILE ) // no more file handles/descrs
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_OpenError );
+ }
+ return ok;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file handle \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ #include <stdio.h>
+
+ void printError( const char* msg )
+ {
+ QFile f;
+ f.open( IO_WriteOnly, stderr );
+ f.writeBlock( msg, qstrlen(msg) ); // write to stderr
+ f.close();
+ }
+ \endcode
+
+ When a QFile is opened using this function, close() does not actually
+ close the file, only flushes it.
+
+ \warning If \e f is \c stdin, \c stdout, \c stderr, you may not
+ be able to seek. See QIODevice::isSequentialAccess() for more
+ information.
+
+ \sa close()
+*/
+
+bool QFile::open( int m, FILE *f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m &~IO_Raw );
+ setState( IO_Open );
+ fh = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( FILENO(fh), &st );
+ ioIndex = (int)ftell( fh );
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file descriptor \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ When a QFile is opened using this function, close() does not actually
+ close the file.
+
+ \warning If \e f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
+ be able to seek. size() is set to \c INT_MAX (in limits.h).
+
+ \sa close()
+*/
+
+
+bool QFile::open( int m, int f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m |IO_Raw );
+ setState( IO_Open );
+ fd = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( fd, &st );
+ ioIndex = (int)LSEEK(fd, 0, SEEK_CUR);
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the file size.
+ \sa at()
+*/
+
+uint QFile::size() const
+{
+ STATBUF st;
+ if ( isOpen() ) {
+ FSTAT( fh ? FILENO(fh) : fd, &st );
+ return st.st_size;
+ } else {
+#if defined(__CYGWIN32_)
+ STAT( QFile::encodeName(fn), &st );
+#else
+ QString str = fn;
+ reslashify(str);
+#ifdef QT_LARGEFILE_SUPPORT
+ if ( _wstati64( (wchar_t*) str.ucs2(), &st ) != -1 ) {
+#else
+ if ( _wstat( (wchar_t*) str.ucs2(), &st ) != -1 ) {
+#endif
+#endif
+ return st.st_size;
+ }
+ }
+ return 0;
+}
+
+/*!
+ \fn int QFile::at() const
+ Returns the file index.
+ \sa size()
+*/
+
+/*!
+ Sets the file index to \e pos. Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ QFile f( "data.bin" );
+ f.open( IO_ReadOnly ); // index set to 0
+ f.at( 100 ); // set index to 100
+ f.at( f.at()+50 ); // set index to 150
+ f.at( f.size()-80 ); // set index to 80 before EOF
+ f.close();
+ \endcode
+
+ \warning The result is undefined if the file was \link open() opened\endlink
+ using the \c IO_Append specifier.
+
+ \sa size(), open()
+*/
+
+bool QFile::at( int pos )
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::at: File is not open" );
+#endif
+ return FALSE;
+ }
+ bool ok;
+ if ( isRaw() ) { // raw file
+ pos = (int)LSEEK(fd, pos, SEEK_SET);
+ ok = pos != -1;
+ } else { // buffered file
+ ok = fseek(fh, pos, SEEK_SET) == 0;
+ }
+ if ( ok )
+ ioIndex = pos;
+#if defined(CHECK_RANGE)
+ else
+ qWarning( "QFile::at: Cannot set file position %d", pos );
+#endif
+ return ok;
+}
+
+/*!
+ Reads at most \e len bytes from the file into \e p and returns the
+ number of bytes actually read.
+
+ Returns -1 if a serious error occurred.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ \sa writeBlock()
+*/
+
+int QFile::readBlock( char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( !p )
+ qWarning( "QFile::readBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readBlock: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = READ( fd, p, len );
+ if ( len && nread <= 0 ) {
+ nread = 0;
+ setStatus(IO_ReadError);
+ }
+ } else { // buffered file
+ nread = fread( p, 1, len, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 )
+ setStatus(IO_ReadError);
+ }
+ }
+ ioIndex += nread;
+ return nread;
+}
+
+/*! \overload int writeBlock( const QByteArray& data )
+*/
+
+/*! \reimp
+
+ Writes \e len bytes from \e p to the file and returns the number of
+ bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure the data is really
+ written.
+
+ \sa readBlock()
+*/
+
+int QFile::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QFile::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::writeBlock: File not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ int nwritten; // number of bytes written
+ if ( isRaw() ) // raw file
+ nwritten = WRITE( fd, p, len );
+ else // buffered file
+ nwritten = fwrite( p, 1, len, fh );
+ if ( nwritten != (int)len ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_WriteError );
+ if ( isRaw() ) // recalc file position
+ ioIndex = (int)LSEEK( fd, 0, SEEK_CUR );
+ else
+ ioIndex = fseek( fh, 0, SEEK_CUR );
+ } else {
+ ioIndex += nwritten;
+ }
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ return nwritten;
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
+
+ If the file is not open or there is an error, handle() returns -1.
+
+ \sa QSocketNotifier
+*/
+
+int QFile::handle() const
+{
+ if ( !isOpen() )
+ return -1;
+ else if ( fh )
+ return FILENO( fh );
+ else
+ return fd;
+}
+
+/*!
+ Closes an open file.
+
+ The file is not closed if it was opened with an existing file handle.
+ If the existing file handle is a \c FILE*, the file is flushed.
+ If the existing file handle is an \c int file descriptor, nothing
+ is done to the file.
+
+ Some "write-behind" filesystems may report an unspecified error on
+ closing the file. These errors only indicate that something may
+ have gone wrong since the previous open(). In such a case status()
+ reports IO_UnspecifiedError after close(), otherwise IO_Ok.
+
+ \sa open(), flush()
+*/
+
+
+void QFile::close()
+{
+ bool ok = FALSE;
+ if ( isOpen() ) { // file is not open
+ if ( fh ) { // buffered file
+ if ( ext_f )
+ ok = fflush( fh ) != -1; // flush instead of closing
+ else
+ ok = fclose( fh ) != -1;
+ } else { // raw file
+ if ( ext_f )
+ ok = TRUE; // cannot close
+ else
+ ok = CLOSE( fd ) != -1;
+ }
+ init(); // restore internal state
+ }
+ if (!ok)
+ setStatus (IO_UnspecifiedError);
+
+ return;
+}
+
+int64 QFile::pos() const
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ return ftell( fh );
+ }
+ return -1;
+}
+
+int64 QFile::toEnd()
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ if (fseek( fh, 0, SEEK_END )!=-1)
+ {
+ return ftell( fh );
+ }
+ }
+ return -1;
+}
+
+bool QFile::seek( int64 pos )
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ return fseek( fh, pos, SEEK_SET )!=-1;
+ }
+ return FALSE;
+}
+
+
+
diff --git a/qtools/qfiledefs_p.h b/qtools/qfiledefs_p.h
new file mode 100644
index 0000000..5a7cfe2
--- /dev/null
+++ b/qtools/qfiledefs_p.h
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+**
+** Common macros and system include files for QFile, QFileInfo and QDir.
+**
+** Created : 930812
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QFILEDEFS_P_H
+#define QFILEDEFS_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qfile.cpp, qfileinfo.cpp and qdir.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+//
+#if defined(_CC_MWERKS_)
+# include <stdlib.h>
+# include <stat.h>
+#elif !defined(_OS_MAC_)
+# include <sys/types.h>
+# include <sys/stat.h>
+#elif defined(_OS_MAC_)
+# include <sys/types.h>
+# include <sys/stat.h>
+# define _OS_UNIX_
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#if defined(_OS_UNIX_)
+# include <dirent.h>
+# include <unistd.h>
+#endif
+#if defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_)
+# define _OS_FATFS_
+# if defined(__CYGWIN32__)
+# include <dirent.h>
+# include <unistd.h>
+# if !defined(_OS_UNIX_)
+# define _OS_UNIX_
+# endif
+# else
+# include <io.h>
+# if !defined(_CC_MWERKS_)
+# include <dos.h>
+# endif
+# include <direct.h>
+# endif
+#endif
+#include <limits.h>
+
+
+#if !defined(PATH_MAX)
+#if defined( MAXPATHLEN )
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+
+#undef STATBUF
+#undef STAT
+#undef STAT_REG
+#undef STAT_DIR
+#undef STAT_LNK
+#undef STAT_MASK
+#undef FILENO
+#undef OPEN
+#undef CLOSE
+#undef LSEEK
+#undef READ
+#undef WRITE
+#undef ACCESS
+#undef GETCWD
+#undef CHDIR
+#undef MKDIR
+#undef RMDIR
+#undef OPEN_RDONLY
+#undef OPEN_WRONLY
+#undef OPEN_CREAT
+#undef OPEN_TRUNC
+#undef OPEN_APPEND
+#undef OPEN_TEXT
+#undef OPEN_BINARY
+
+
+#if defined(_CC_MSVC_) || defined(_CC_SYM_)
+
+# define STATBUF struct _stat // non-ANSI defs
+# define STATBUF4TSTAT struct _stat // non-ANSI defs
+# define STAT ::_stat
+# define FSTAT ::_fstat
+# define STAT_REG _S_IFREG
+# define STAT_DIR _S_IFDIR
+# define STAT_MASK _S_IFMT
+# if defined(_S_IFLNK)
+# define STAT_LNK _S_IFLNK
+# endif
+# define FILENO _fileno
+# define OPEN ::_open
+# define CLOSE ::_close
+# define LSEEK ::_lseek
+# define READ ::_read
+# define WRITE ::_write
+# define ACCESS ::_access
+# define GETCWD ::_getcwd
+# define CHDIR ::_chdir
+# define MKDIR ::_mkdir
+# define RMDIR ::_rmdir
+# define OPEN_RDONLY _O_RDONLY
+# define OPEN_WRONLY _O_WRONLY
+# define OPEN_RDWR _O_RDWR
+# define OPEN_CREAT _O_CREAT
+# define OPEN_TRUNC _O_TRUNC
+# define OPEN_APPEND _O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT _O_TEXT
+# define OPEN_BINARY _O_BINARY
+# endif
+
+#elif defined(_CC_BOR_) && __BORLANDC__ >= 0x550
+
+# define STATBUF struct stat // non-ANSI defs
+# define STATBUF4TSTAT struct _stat // non-ANSI defs
+# define STAT ::stat
+# define FSTAT ::fstat
+# define STAT_REG _S_IFREG
+# define STAT_DIR _S_IFDIR
+# define STAT_MASK _S_IFMT
+# if defined(_S_IFLNK)
+# define STAT_LNK _S_IFLNK
+# endif
+# define FILENO _fileno
+# define OPEN ::open
+# define CLOSE ::_close
+# define LSEEK ::_lseek
+# define READ ::_read
+# define WRITE ::_write
+# define ACCESS ::_access
+# define GETCWD ::_getcwd
+# define CHDIR ::chdir
+# define MKDIR ::_mkdir
+# define RMDIR ::_rmdir
+# define OPEN_RDONLY _O_RDONLY
+# define OPEN_WRONLY _O_WRONLY
+# define OPEN_RDWR _O_RDWR
+# define OPEN_CREAT _O_CREAT
+# define OPEN_TRUNC _O_TRUNC
+# define OPEN_APPEND _O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT _O_TEXT
+# define OPEN_BINARY _O_BINARY
+# endif
+
+#else // all other systems
+
+#ifdef __MINGW32__
+# define STATBUF struct _stat
+# define STATBUF4TSTAT struct _stat
+# define STAT _stat
+# define FSTAT _fstat
+#else
+# define STATBUF struct stat
+# define STATBUF4TSTAT struct stat
+# define STAT ::stat
+# define FSTAT ::fstat
+#endif
+# define STAT_REG S_IFREG
+# define STAT_DIR S_IFDIR
+# define STAT_MASK S_IFMT
+# if defined(S_IFLNK)
+# define STAT_LNK S_IFLNK
+# endif
+# define FILENO fileno
+# define OPEN ::open
+# define CLOSE ::close
+# define LSEEK ::lseek
+# define READ ::read
+# define WRITE ::write
+# define ACCESS ::access
+# if defined(_OS_OS2EMX_)
+# define GETCWD ::_getcwd2
+# define CHDIR ::_chdir2
+# else
+# define GETCWD ::getcwd
+# define CHDIR ::chdir
+# endif
+# define MKDIR ::mkdir
+# define RMDIR ::rmdir
+# define OPEN_RDONLY O_RDONLY
+# define OPEN_WRONLY O_WRONLY
+# define OPEN_RDWR O_RDWR
+# define OPEN_CREAT O_CREAT
+# define OPEN_TRUNC O_TRUNC
+# define OPEN_APPEND O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT O_TEXT
+# define OPEN_BINARY O_BINARY
+# endif
+#endif
+
+#if defined(_CC_MWERKS_)
+#undef mkdir
+#undef MKDIR
+#define MKDIR _mkdir
+#undef rmdir
+#undef RMDIR
+#define RMDIR _rmdir
+#endif
+
+
+#if defined(_OS_FATFS_)
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#if defined(_OS_MAC_) && !defined(_OS_UNIX_)
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+struct QFileInfoCache
+{
+ STATBUF st;
+ bool isSymLink;
+};
+
+#endif
diff --git a/qtools/qfileinfo.cpp b/qtools/qfileinfo.cpp
new file mode 100644
index 0000000..5053b76
--- /dev/null
+++ b/qtools/qfileinfo.cpp
@@ -0,0 +1,458 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+extern bool qt_file_access( const QString& fn, int t );
+
+// NOT REVISED
+/*!
+ \class QFileInfo qfileinfo.h
+ \brief The QFileInfo class provides system-independent file information.
+
+ \ingroup io
+
+ QFileInfo provides information about a file's name and position (path) in
+ the file system, its access rights and whether it is a directory or a
+ symbolic link. Its size and last modified/read times are also available.
+
+ To speed up performance QFileInfo caches information about the file. Since
+ files can be changed by other users or programs, or even by other parts of
+ the same program there is a function that refreshes the file information;
+ refresh(). If you would rather like a QFileInfo to access the file system
+ every time you request information from it, you can call the function
+ setCaching( FALSE ).
+
+ A QFileInfo can point to a file using either a relative or an absolute
+ file path. Absolute file paths begin with the directory separator
+ ('/') or a drive specification (not applicable to UNIX).
+ Relative file names begin with a directory name or a file name and specify
+ a path relative to the current directory. An example of
+ an absolute path is the string "/tmp/quartz". A relative path might look like
+ "src/fatlib". You can use the function isRelative() to check if a QFileInfo
+ is using a relative or an absolute file path. You can call the function
+ convertToAbs() to convert a relative QFileInfo to an absolute one.
+
+ If you need to read and traverse directories, see the QDir class.
+*/
+
+
+/*!
+ Constructs a new empty QFileInfo.
+*/
+
+QFileInfo::QFileInfo()
+{
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about the given file.
+ The string given can be an absolute or a relative file path.
+
+ \sa bool setFile(QString ), isRelative(), QDir::setCurrent(),
+ QDir::isRelativePath()
+*/
+
+QFileInfo::QFileInfo( const QString &file )
+{
+ fn = file;
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about \e file.
+
+ If the file has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+
+QFileInfo::QFileInfo( const QFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about the file
+ named \e fileName in the directory \e d.
+
+ If the directory has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+#ifndef QT_NO_DIR
+QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+#endif
+/*!
+ Constructs a new QFileInfo that is a copy of \e fi.
+*/
+
+QFileInfo::QFileInfo( const QFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( fi.fic ) {
+ fic = new QFileInfoCache;
+ *fic = *fi.fic;
+ } else {
+ fic = 0;
+ }
+ cache = fi.cache;
+}
+
+/*!
+ Destructs the QFileInfo.
+*/
+
+QFileInfo::~QFileInfo()
+{
+ delete fic;
+}
+
+
+/*!
+ Makes a copy of \e fi and assigns it to this QFileInfo.
+*/
+
+QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( !fi.fic ) {
+ delete fic;
+ fic = 0;
+ } else {
+ if ( !fic ) {
+ fic = new QFileInfoCache;
+ CHECK_PTR( fic );
+ }
+ *fic = *fi.fic;
+ }
+ cache = fi.cache;
+ return *this;
+}
+
+
+/*!
+ Sets the file to obtain information about.
+
+ The string given can be an absolute or a relative file path. Absolute file
+ paths begin with the directory separator (e.g. '/' under UNIX) or a drive
+ specification (not applicable to UNIX). Relative file names begin with a
+ directory name or a file name and specify a path relative to the current
+ directory.
+
+ Example:
+ \code
+ #include <qfileinfo.h>
+ #include <qdir.h>
+
+ void test()
+ {
+ QString absolute = "/liver/aorta";
+ QString relative = "liver/aorta";
+ QFileInfo fi1( absolute );
+ QFileInfo fi2( relative );
+
+ QDir::setCurrent( QDir::rootDirPath() );
+ // fi1 and fi2 now point to the same file
+
+ QDir::setCurrent( "/tmp" );
+ // fi1 now points to "/liver/aorta",
+ // while fi2 points to "/tmp/liver/aorta"
+ }
+ \endcode
+
+ \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
+*/
+
+void QFileInfo::setFile( const QString &file )
+{
+ fn = file;
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ Sets the file to obtain information about.
+
+ If the file has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+
+void QFileInfo::setFile( const QFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ Sets the file to obtains information about to \e fileName in the
+ directory \e d.
+
+ If the directory has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+#ifndef QT_NO_DIR
+void QFileInfo::setFile( const QDir &d, const QString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+#endif
+
+/*!
+ Returns TRUE if the file pointed to exists, otherwise FALSE.
+*/
+
+bool QFileInfo::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Refresh the information about the file, i.e. read in information from the
+ file system the next time a cached property is fetched.
+
+ \sa setCaching()
+*/
+
+void QFileInfo::refresh() const
+{
+ QFileInfo *that = (QFileInfo*)this; // Mutable function
+ delete that->fic;
+ that->fic = 0;
+}
+
+/*!
+ \fn bool QFileInfo::caching() const
+ Returns TRUE if caching is enabled.
+ \sa setCaching(), refresh()
+*/
+
+/*!
+ Enables caching of file information if \e enable is TRUE, or disables it
+ if \e enable is FALSE.
+
+ When caching is enabled, QFileInfo reads the file information the first
+ time
+
+ Caching is enabled by default.
+
+ \sa refresh(), caching()
+*/
+
+void QFileInfo::setCaching( bool enable )
+{
+ if ( cache == enable )
+ return;
+ cache = enable;
+ if ( cache ) {
+ delete fic;
+ fic = 0;
+ }
+}
+
+
+/*!
+ Returns the name, i.e. the file name including the path (which can be
+ absolute or relative).
+
+ \sa isRelative(), absFilePath()
+*/
+
+QString QFileInfo::filePath() const
+{
+ return fn;
+}
+
+/*!
+ Returns the base name of the file.
+
+ The base name consists of all characters in the file name up to (but not
+ including) the first '.' character. The path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString base = fi.baseName(); // base = "abdomen"
+ \endcode
+
+ \sa fileName(), extension()
+*/
+
+QString QFileInfo::baseName() const
+{
+ QString tmp = fileName();
+ int pos = tmp.find( '.' );
+ if ( pos == -1 )
+ return tmp;
+ else
+ return tmp.left( pos );
+}
+
+/*!
+ Returns the extension name of the file.
+
+ If \a complete is TRUE (the default), extension() returns the string
+ of all characters in the file name after (but not including) the
+ first '.' character. For a file named "archive.tar.gz" this
+ returns "tar.gz".
+
+ If \a complete is FALSE, extension() returns the string of all
+ characters in the file name after (but not including) the last '.'
+ character. For a file named "archive.tar.gz" this returns "gz".
+
+ Example:
+ \code
+ QFileInfo fi( "lex.yy.c" );
+ QString ext = fi.extension(); // ext = "yy.c"
+ QString ext = fi.extension( FALSE ); // ext = "c"
+ \endcode
+
+ \sa fileName(), baseName()
+
+*/
+
+QString QFileInfo::extension( bool complete ) const
+{
+ QString s = fileName();
+ int pos = complete ? s.find( '.' ) : s.findRev( '.' );
+ if ( pos < 0 )
+ return QString::fromLatin1( "" );
+ else
+ return s.right( s.length() - pos - 1 );
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If the QFileInfo is relative and \e absPath is FALSE, the QDir will be
+ relative, otherwise it will be absolute.
+
+ \sa dirPath(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QDir QFileInfo::dir( bool absPath ) const
+{
+ return QDir( dirPath(absPath) );
+}
+#endif
+
+
+/*!
+ Returns TRUE if the file is readable.
+ \sa isWritable(), isExecutable(), permission()
+*/
+
+bool QFileInfo::isReadable() const
+{
+ return qt_file_access( fn, R_OK );
+}
+
+/*!
+ Returns TRUE if the file is writable.
+ \sa isReadable(), isExecutable(), permission()
+*/
+
+bool QFileInfo::isWritable() const
+{
+ return qt_file_access( fn, W_OK );
+}
+
+/*!
+ Returns TRUE if the file is executable.
+ \sa isReadable(), isWritable(), permission()
+*/
+
+bool QFileInfo::isExecutable() const
+{
+ return qt_file_access( fn, X_OK );
+}
+
+
+/*!
+ Returns TRUE if the file path name is relative to the current directory,
+ FALSE if the path is absolute (e.g. under UNIX a path is relative if it
+ does not start with a '/').
+
+ According to Einstein this function should always return TRUE.
+*/
+#ifndef QT_NO_DIR
+bool QFileInfo::isRelative() const
+{
+ return QDir::isRelativePath( fn );
+}
+
+/*!
+ Converts the file path name to an absolute path.
+
+ If it is already absolute nothing is done.
+
+ \sa filePath(), isRelative()
+*/
+
+bool QFileInfo::convertToAbs()
+{
+ if ( isRelative() )
+ fn = absFilePath();
+ return QDir::isRelativePath( fn );
+}
+#endif
diff --git a/qtools/qfileinfo.h b/qtools/qfileinfo.h
new file mode 100644
index 0000000..76ef8c2
--- /dev/null
+++ b/qtools/qfileinfo.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+**
+** Definition of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QFILEINFO_H
+#define QFILEINFO_H
+
+#ifndef QT_H
+#include "qfile.h"
+#include "qdatetime.h"
+#endif // QT_H
+
+
+class QDir;
+struct QFileInfoCache;
+
+
+class Q_EXPORT QFileInfo // file information class
+{
+public:
+ enum PermissionSpec {
+ ReadUser = 0400, WriteUser = 0200, ExeUser = 0100,
+ ReadGroup = 0040, WriteGroup = 0020, ExeGroup = 0010,
+ ReadOther = 0004, WriteOther = 0002, ExeOther = 0001 };
+
+ QFileInfo();
+ QFileInfo( const QString &file );
+ QFileInfo( const QFile & );
+#ifndef QT_NO_DIR
+ QFileInfo( const QDir &, const QString &fileName );
+#endif
+ QFileInfo( const QFileInfo & );
+ ~QFileInfo();
+
+ QFileInfo &operator=( const QFileInfo & );
+
+ void setFile( const QString &file );
+ void setFile( const QFile & );
+#ifndef QT_NO_DIR
+ void setFile( const QDir &, const QString &fileName );
+#endif
+ bool exists() const;
+ void refresh() const;
+ bool caching() const;
+ void setCaching( bool );
+
+ QString filePath() const;
+ QString fileName() const;
+#ifndef QT_NO_DIR //###
+ QString absFilePath() const;
+#endif
+ QString baseName() const;
+ QString extension( bool complete = TRUE ) const;
+
+#ifndef QT_NO_DIR //###
+ QString dirPath( bool absPath = FALSE ) const;
+#endif
+#ifndef QT_NO_DIR
+ QDir dir( bool absPath = FALSE ) const;
+#endif
+ bool isReadable() const;
+ bool isWritable() const;
+ bool isExecutable() const;
+
+#ifndef QT_NO_DIR //###
+ bool isRelative() const;
+ bool convertToAbs();
+#endif
+
+ bool isFile() const;
+ bool isDir() const;
+ bool isSymLink() const;
+
+ QString readLink() const;
+
+ QString owner() const;
+ uint ownerId() const;
+ QString group() const;
+ uint groupId() const;
+
+ bool permission( int permissionSpec ) const;
+
+ uint size() const;
+
+ QDateTime lastModified() const;
+ QDateTime lastRead() const;
+
+private:
+ void doStat() const;
+ static void slashify( QString & );
+ static void makeAbs( QString & );
+
+ QString fn;
+ QFileInfoCache *fic;
+ bool cache;
+};
+
+
+inline bool QFileInfo::caching() const
+{
+ return cache;
+}
+
+
+#endif // QFILEINFO_H
diff --git a/qtools/qfileinfo_unix.cpp b/qtools/qfileinfo_unix.cpp
new file mode 100644
index 0000000..f2b438c
--- /dev/null
+++ b/qtools/qfileinfo_unix.cpp
@@ -0,0 +1,425 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
+** with the Qt Commercial License Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#if defined(_OS_SUN_)
+#define readlink _qt_hide_readlink
+#endif
+
+#include <pwd.h>
+#include <grp.h>
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+#if defined(_OS_SUN_)
+#undef readlink
+extern "C" int readlink( const char *, void *, uint );
+#endif
+
+
+void QFileInfo::slashify( QString& )
+{
+ return;
+}
+
+
+void QFileInfo::makeAbs( QString & )
+{
+ return;
+}
+
+extern bool qt_file_access( const QString& fn, int t );
+
+/*!
+ Returns TRUE if we are pointing to a real file.
+ \sa isDir(), isSymLink()
+*/
+bool QFileInfo::isFile() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a directory or a symbolic link to
+ a directory.
+ \sa isFile(), isSymLink()
+*/
+
+bool QFileInfo::isDir() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a symbolic link.
+ \sa isFile(), isDir(), readLink()
+*/
+
+bool QFileInfo::isSymLink() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? fic->isSymLink : FALSE;
+}
+
+
+/*!
+ Returns the name a symlink points to, or a null QString if the
+ object does not refer to a symbolic link.
+
+ This name may not represent an existing file; it is only a string.
+ QFileInfo::exists() returns TRUE if the symlink points to an
+ existing file.
+
+ \sa exists(), isSymLink(), isDir(), isFile()
+*/
+
+QString QFileInfo::readLink() const
+{
+ QString r;
+
+#if defined(_OS_UNIX_) && !defined(_OS_OS2EMX_)
+ char s[PATH_MAX+1];
+ if ( !isSymLink() )
+ return QString();
+ int len = (int)readlink( QFile::encodeName(fn).data(), s, PATH_MAX );
+ if ( len >= 0 ) {
+ s[len] = '\0';
+ r = QFile::decodeName(s);
+ }
+#endif
+
+ return r;
+}
+
+static const uint nobodyID = (uint) -2;
+
+/*!
+ Returns the owner of the file.
+
+ On systems where files do not have owners this function returns 0.
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa ownerId(), group(), groupId()
+*/
+
+QString QFileInfo::owner() const
+{
+ passwd *pw = getpwuid( ownerId() );
+ if ( pw )
+ return QFile::decodeName( pw->pw_name );
+ return QString::null;
+}
+
+/*!
+ Returns the id of the owner of the file.
+
+ On systems where files do not have owners this function returns ((uint) -2).
+
+ \sa owner(), group(), groupId()
+*/
+
+uint QFileInfo::ownerId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_uid;
+ return nobodyID;
+}
+
+/*!
+ Returns the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns 0.
+
+ Note that this function can be time-consuming under UNIX (in the order of
+ milliseconds on a 486 DX2/66 running Linux).
+
+ \sa groupId(), owner(), ownerId()
+*/
+
+QString QFileInfo::group() const
+{
+ struct group *gr = getgrgid( groupId() );
+ if ( gr )
+ return QFile::decodeName( gr->gr_name );
+ return QString::null;
+}
+
+/*!
+ Returns the id of the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns ((uind) -2).
+
+ \sa group(), owner(), ownerId()
+*/
+
+uint QFileInfo::groupId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_gid;
+ return nobodyID;
+}
+
+
+/*!
+ \fn bool QFileInfo::permission( int permissionSpec ) const
+
+ Tests for file permissions. The \e permissionSpec argument can be several
+ flags of type PermissionSpec or'ed together to check for permission
+ combinations.
+
+ On systems where files do not have permissions this function always
+ returns TRUE.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/tonsils" );
+ if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
+ qWarning( "Tonsils can be changed by me, and the group can read them.");
+ if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
+ qWarning( "Danger! Tonsils can be changed by the group or others!" );
+ \endcode
+
+ \sa isReadable(), isWritable(), isExecutable()
+*/
+
+bool QFileInfo::permission( int permissionSpec ) const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic ) {
+ uint mask = 0;
+ if ( permissionSpec & ReadUser)
+ mask |= S_IRUSR;
+ if ( permissionSpec & WriteUser)
+ mask |= S_IWUSR;
+ if ( permissionSpec & ExeUser)
+ mask |= S_IXUSR;
+ if ( permissionSpec & ReadGroup)
+ mask |= S_IRGRP;
+ if ( permissionSpec & WriteGroup)
+ mask |= S_IWGRP;
+ if ( permissionSpec & ExeGroup)
+ mask |= S_IXGRP;
+ if ( permissionSpec & ReadOther)
+ mask |= S_IROTH;
+ if ( permissionSpec & WriteOther)
+ mask |= S_IWOTH;
+ if ( permissionSpec & ExeOther)
+ mask |= S_IXOTH;
+ if ( mask ) {
+ return (fic->st.st_mode & mask) == mask;
+ } else {
+#if defined(CHECK_NULL)
+ qWarning( "QFileInfo::permission: permissionSpec is 0" );
+#endif
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the file size in bytes, or 0 if the file does not exist if the size
+ cannot be fetched.
+*/
+
+uint QFileInfo::size() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return (uint)fic->st.st_size;
+ else
+ return 0;
+}
+
+
+/*!
+ Returns the date and time when the file was last modified.
+ \sa lastRead()
+*/
+
+QDateTime QFileInfo::lastModified() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( (uint)fic->st.st_mtime );
+ return dt;
+}
+
+/*!
+ Returns the date and time when the file was last read (accessed).
+
+ On systems that do not support last read times, the modification time is
+ returned.
+
+ \sa lastModified()
+*/
+
+QDateTime QFileInfo::lastRead() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( (uint)fic->st.st_atime );
+ return dt;
+}
+
+
+void QFileInfo::doStat() const
+{
+ QFileInfo *that = ((QFileInfo*)this); // mutable function
+ if ( !that->fic )
+ that->fic = new QFileInfoCache;
+ STATBUF *b = &that->fic->st;
+ that->fic->isSymLink = FALSE;
+
+#if defined(_OS_UNIX_) && defined(S_IFLNK)
+ if ( ::lstat(QFile::encodeName(fn),b) == 0 ) {
+ if ( S_ISLNK( b->st_mode ) )
+ that->fic->isSymLink = TRUE;
+ else
+ return;
+ }
+#endif
+ int r;
+
+ r = STAT( QFile::encodeName(fn), b );
+
+ if ( r != 0 ) {
+ delete that->fic;
+ that->fic = 0;
+ }
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If \e absPath is TRUE an absolute path is always returned.
+
+ \sa dir(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::dirPath( bool absPath ) const
+{
+ QString s;
+ if ( absPath )
+ s = absFilePath();
+ else
+ s = fn;
+ int pos = s.findRev( '/' );
+ if ( pos == -1 ) {
+ return QString::fromLatin1(".");
+ } else {
+ if ( pos == 0 )
+ return QString::fromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+#endif
+/*!
+ Returns the name of the file, the file path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString name = fi.fileName(); // name = "abdomen.lower"
+ \endcode
+
+ \sa isRelative(), filePath(), baseName(), extension()
+*/
+
+QString QFileInfo::fileName() const
+{
+ int p = fn.findRev( '/' );
+ if ( p == -1 ) {
+ return fn;
+ } else {
+ return fn.mid(p+1);
+ }
+}
+
+/*!
+ Returns the absolute path name.
+
+ The absolute path name is the file name including the absolute path. If
+ the QFileInfo is absolute (i.e. not relative) this function will return
+ the same string as filePath().
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa isRelative(), filePath()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::absFilePath() const
+{
+ if ( QDir::isRelativePath(fn) ) {
+ QString tmp = QDir::currentDirPath();
+ tmp += '/';
+ tmp += fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ } else {
+ QString tmp = fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ }
+
+}
+#endif
diff --git a/qtools/qfileinfo_win32.cpp b/qtools/qfileinfo_win32.cpp
new file mode 100644
index 0000000..1061fae
--- /dev/null
+++ b/qtools/qfileinfo_win32.cpp
@@ -0,0 +1,357 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2001 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qfileinfo_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+#include "qglobal.h"
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+static void reslashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '/' )
+ n[i] = '\\';
+ }
+}
+
+void QFileInfo::slashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '\\' )
+ n[i] = '/';
+ }
+}
+
+void QFileInfo::makeAbs( QString & )
+{
+ // TODO: what to do here?
+ return;
+}
+
+extern bool qt_file_access( const QString& fn, int t );
+
+/*!
+ Returns TRUE if we are pointing to a real file.
+ \sa isDir(), isSymLink()
+*/
+bool QFileInfo::isFile() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a directory or a symbolic link to
+ a directory.
+ \sa isFile(), isSymLink()
+*/
+
+bool QFileInfo::isDir() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a symbolic link.
+ \sa isFile(), isDir(), readLink()
+*/
+
+bool QFileInfo::isSymLink() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? fic->isSymLink : FALSE;
+}
+
+
+/*!
+ Returns the name a symlink points to, or a null QString if the
+ object does not refer to a symbolic link.
+
+ This name may not represent an existing file; it is only a string.
+ QFileInfo::exists() returns TRUE if the symlink points to an
+ existing file.
+
+ \sa exists(), isSymLink(), isDir(), isFile()
+*/
+
+QString QFileInfo::readLink() const
+{
+ QString r;
+ return r;
+}
+
+static const uint nobodyID = (uint) -2;
+
+/*!
+ Returns the owner of the file.
+
+ On systems where files do not have owners this function returns
+ a null string.
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa ownerId(), group(), groupId()
+*/
+
+QString QFileInfo::owner() const
+{
+ return QString::null;
+}
+
+/*!
+ Returns the id of the owner of the file.
+
+ On systems where files do not have owners this function returns ((uint) -2).
+
+ \sa owner(), group(), groupId()
+*/
+
+uint QFileInfo::ownerId() const
+{
+ return (uint)-2;
+}
+
+/*!
+ Returns the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns 0.
+
+ Note that this function can be time-consuming under UNIX (in the order of
+ milliseconds on a 486 DX2/66 running Linux).
+
+ \sa groupId(), owner(), ownerId()
+*/
+
+QString QFileInfo::group() const
+{
+ return QString::null;
+}
+
+/*!
+ Returns the id of the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns ((uind) -2).
+
+ \sa group(), owner(), ownerId()
+*/
+
+uint QFileInfo::groupId() const
+{
+ return (uint)-2;
+}
+
+
+/*!
+ \fn bool QFileInfo::permission( int permissionSpec ) const
+
+ Tests for file permissions. The \e permissionSpec argument can be several
+ flags of type PermissionSpec or'ed together to check for permission
+ combinations.
+
+ On systems where files do not have permissions this function always
+ returns TRUE.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/tonsils" );
+ if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
+ qWarning( "Tonsils can be changed by me, and the group can read them.");
+ if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
+ qWarning( "Danger! Tonsils can be changed by the group or others!" );
+ \endcode
+
+ \sa isReadable(), isWritable(), isExecutable()
+*/
+
+bool QFileInfo::permission( int permissionSpec ) const
+{
+ return TRUE;
+}
+
+/*!
+ Returns the file size in bytes, or 0 if the file does not exist if the size
+ cannot be fetched.
+*/
+
+uint QFileInfo::size() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return (uint)fic->st.st_size;
+ else
+ return 0;
+}
+
+
+/*!
+ Returns the date and time when the file was last modified.
+ \sa lastRead()
+*/
+
+QDateTime QFileInfo::lastModified() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_mtime );
+ return dt;
+}
+
+/*!
+ Returns the date and time when the file was last read (accessed).
+
+ On systems that do not support last read times, the modification time is
+ returned.
+
+ \sa lastModified()
+*/
+
+QDateTime QFileInfo::lastRead() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_atime );
+ return dt;
+}
+
+
+void QFileInfo::doStat() const
+{
+ QFileInfo *that = ((QFileInfo*)this); // mutable function
+ if ( !that->fic )
+ that->fic = new QFileInfoCache;
+ STATBUF *b = &that->fic->st;
+ that->fic->isSymLink = FALSE;
+
+#if defined(__CYGWIN32_)
+ int r;
+
+ r = STAT( QFile::encodeName(fn), b );
+
+ if ( r != 0 ) {
+ delete that->fic;
+ that->fic = 0;
+ }
+#else
+ QString file = fn;
+ file = QDir::cleanDirPath(file);
+ reslashify(file);
+#ifdef QT_LARGEFILE_SUPPORT
+ if ( _wstati64( (wchar_t*) file.ucs2(), b ) == -1 ) {
+#else
+ if ( _wstat( (wchar_t*) file.ucs2(), b ) == -1 ) {
+#endif
+ delete that->fic;
+ that->fic = 0;
+ }
+#endif
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If \e absPath is TRUE an absolute path is always returned.
+
+ \sa dir(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::dirPath( bool absPath ) const
+{
+ QString s;
+ if ( absPath )
+ s = absFilePath();
+ else
+ s = fn;
+ int pos = s.findRev( '/' );
+ if ( pos == -1 ) {
+ return QString::fromLatin1(".");
+ } else {
+ if ( pos == 0 )
+ return QString::fromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+#endif
+/*!
+ Returns the name of the file, the file path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString name = fi.fileName(); // name = "abdomen.lower"
+ \endcode
+
+ \sa isRelative(), filePath(), baseName(), extension()
+*/
+
+QString QFileInfo::fileName() const
+{
+ int p = fn.findRev( '/' );
+ if ( p == -1 ) {
+ return fn;
+ } else {
+ return fn.mid(p+1);
+ }
+}
+
+/*!
+ Returns the absolute path name.
+
+ The absolute path name is the file name including the absolute path. If
+ the QFileInfo is absolute (i.e. not relative) this function will return
+ the same string as filePath().
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa isRelative(), filePath()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::absFilePath() const
+{
+ if ( QDir::isRelativePath(fn) ) {
+ QString tmp = QDir::currentDirPath();
+ tmp += '/';
+ tmp += fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ } else {
+ QString tmp = fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ }
+
+}
+#endif
diff --git a/qtools/qgarray.cpp b/qtools/qgarray.cpp
new file mode 100644
index 0000000..df31363
--- /dev/null
+++ b/qtools/qgarray.cpp
@@ -0,0 +1,747 @@
+/****************************************************************************
+**
+**
+** Implementation of QGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#define QGARRAY_CPP
+#include "qgarray.h"
+#include "qstring.h"
+#include <stdlib.h>
+
+#define USE_MALLOC // comment to use new/delete
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+
+// NOT REVISED
+/*!
+ \class QShared qshared.h
+ \brief The QShared struct is internally used for implementing shared classes.
+
+ It only contains a reference count and member functions to increment and
+ decrement it.
+
+ Shared classes normally have internal classes that inherit QShared and
+ add the shared data.
+
+ \sa \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ \class QGArray qgarray.h
+ \brief The QGArray class is an internal class for implementing the QArray class.
+
+ QGArray is a strictly internal class that acts as base class for the
+ QArray template array.
+
+ It contains an array of bytes and has no notion of an array element.
+*/
+
+
+/*!
+ \internal
+ Constructs a null array.
+*/
+
+QGArray::QGArray()
+{
+ shd = newData();
+ CHECK_PTR( shd );
+}
+
+/*!
+ \internal
+ Dummy constructor; does not allocate any data.
+
+ This constructor does not initialize any array data so subclasses
+ must do it. The intention is to make the code more efficient.
+*/
+
+QGArray::QGArray( int, int )
+{
+}
+
+/*!
+ \internal
+ Constructs an array with room for \e size bytes.
+*/
+
+QGArray::QGArray( int size )
+{
+ if ( size < 0 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray: Cannot allocate array with negative length" );
+#endif
+ size = 0;
+ }
+ shd = newData();
+ CHECK_PTR( shd );
+ if ( size == 0 ) // zero length
+ return;
+ shd->data = NEW(char,size);
+ CHECK_PTR( shd->data );
+ shd->len = size;
+}
+
+/*!
+ \internal
+ Constructs a shallow copy of \e a.
+*/
+
+QGArray::QGArray( const QGArray &a )
+{
+ shd = a.shd;
+ shd->ref();
+}
+
+/*!
+ \internal
+ Dereferences the array data and deletes it if this was the last
+ reference.
+*/
+
+QGArray::~QGArray()
+{
+ if ( shd && shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ }
+}
+
+
+/*!
+ \fn QGArray &QGArray::operator=( const QGArray &a )
+ \internal
+ Assigns a shallow copy of \e a to this array and returns a reference to
+ this array. Equivalent to assign().
+*/
+
+/*!
+ \fn void QGArray::detach()
+ \internal
+ Detaches this array from shared array data.
+*/
+
+/*!
+ \fn char *QGArray::data() const
+ \internal
+ Returns a pointer to the actual array data.
+*/
+
+/*!
+ \fn uint QGArray::nrefs() const
+ \internal
+ Returns the reference count.
+*/
+
+/*!
+ \fn uint QGArray::size() const
+ \internal
+ Returns the size of the array, in bytes.
+*/
+
+
+/*!
+ \internal
+ Returns TRUE if this array is equal to \e a, otherwise FALSE.
+ The comparison is bitwise, of course.
+*/
+
+bool QGArray::isEqual( const QGArray &a ) const
+{
+ if ( size() != a.size() ) // different size
+ return FALSE;
+ if ( data() == a.data() ) // has same data
+ return TRUE;
+ return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
+}
+
+
+/*!
+ \internal
+ Resizes the array to \e newsize bytes.
+*/
+
+bool QGArray::resize( uint newsize )
+{
+ if ( newsize == shd->len ) // nothing to do
+ return TRUE;
+ if ( newsize == 0 ) { // remove array
+ duplicate( 0, 0 );
+ return TRUE;
+ }
+ if ( shd->data ) { // existing data
+#if defined(DONT_USE_REALLOC)
+ char *newdata = NEW(char,newsize); // manual realloc
+ memcpy( newdata, shd->data, QMIN(shd->len,newsize) );
+ DELETE(shd->data);
+ shd->data = newdata;
+#else
+ shd->data = (char *)realloc( shd->data, newsize );
+#endif
+ } else {
+ shd->data = NEW(char,newsize);
+ }
+ CHECK_PTR( shd->data );
+ if ( !shd->data ) // no memory
+ return FALSE;
+ shd->len = newsize;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Fills the array with the repeated occurrences of \e d, which is
+ \e sz bytes long.
+ If \e len is specified as different from -1, then the array will be
+ resized to \e len*sz before it is filled.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated
+ (only when \e len != -1).
+
+ \sa resize()
+*/
+
+bool QGArray::fill( const char *d, int len, uint sz )
+{
+ if ( len < 0 )
+ len = shd->len/sz; // default: use array length
+ else if ( !resize( len*sz ) )
+ return FALSE;
+ if ( sz == 1 ) // 8 bit elements
+ memset( data(), *d, len );
+ else if ( sz == 4 ) { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)data();
+ Q_INT32 v = *((Q_INT32*)d);
+ while ( len-- )
+ *x++ = v;
+ } else if ( sz == 2 ) { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)data();
+ Q_INT16 v = *((Q_INT16*)d);
+ while ( len-- )
+ *x++ = v;
+ } else { // any other size elements
+ register char *x = data();
+ while ( len-- ) { // more complicated
+ memcpy( x, d, sz );
+ x += sz;
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+ Shallow copy. Dereference the current array and references the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa operator=()
+*/
+
+QGArray &QGArray::assign( const QGArray &a )
+{
+ a.shd->ref(); // avoid 'a = a'
+ if ( shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ }
+ shd = a.shd;
+ return *this;
+}
+
+/*!
+ \internal
+ Shallow copy. Dereference the current array and references the
+ array data \e d, which contains \e len bytes.
+ Returns a reference to this array.
+
+ Do not delete \e d later, because QGArray takes care of that.
+*/
+
+QGArray &QGArray::assign( const char *d, uint len )
+{
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else {
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = (char *)d;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Deep copy. Dereference the current array and obtains a copy of the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa assign(), operator=()
+*/
+
+QGArray &QGArray::duplicate( const QGArray &a )
+{
+ if ( a.shd == shd ) { // a.duplicate(a) !
+ if ( shd->count > 1 ) {
+ shd->count--;
+ register array_data *n = newData();
+ CHECK_PTR( n );
+ if ( (n->len=shd->len) ) {
+ n->data = NEW(char,n->len);
+ CHECK_PTR( n->data );
+ if ( n->data )
+ memcpy( n->data, shd->data, n->len );
+ } else {
+ n->data = 0;
+ }
+ shd = n;
+ }
+ return *this;
+ }
+ char *oldptr = 0;
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else { // delete after copy was made
+ oldptr = shd->data;
+ }
+ if ( a.shd->len ) { // duplicate data
+ shd->data = NEW(char,a.shd->len);
+ CHECK_PTR( shd->data );
+ if ( shd->data )
+ memcpy( shd->data, a.shd->data, a.shd->len );
+ } else {
+ shd->data = 0;
+ }
+ shd->len = a.shd->len;
+ if ( oldptr )
+ DELETE(oldptr);
+ return *this;
+}
+
+/*!
+ \internal
+ Deep copy. Dereferences the current array and obtains a copy of the
+ array data \e d instead. Returns a reference to this array.
+ \sa assign(), operator=()
+*/
+
+QGArray &QGArray::duplicate( const char *d, uint len )
+{
+ char *data;
+ if ( d == 0 || len == 0 ) {
+ data = 0;
+ len = 0;
+ } else {
+ if ( shd->count == 1 && shd->len == len ) {
+ memcpy( shd->data, d, len ); // use same buffer
+ return *this;
+ }
+ data = NEW(char,len);
+ CHECK_PTR( data );
+ memcpy( data, d, len );
+ }
+ if ( shd->count > 1 ) { // detach
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else { // just a single reference
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = data;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Resizes this array to \e len bytes and copies the \e len bytes at
+ address \e into it.
+
+ \warning This function disregards the reference count mechanism. If
+ other QGArrays reference the same data as this, all will be updated.
+*/
+
+void QGArray::store( const char *d, uint len )
+{ // store, but not deref
+ resize( len );
+ memcpy( shd->data, d, len );
+}
+
+
+/*!
+ \fn array_data *QGArray::sharedBlock() const
+ \internal
+ Returns a pointer to the shared array block.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+/*!
+ \fn void QGArray::setSharedBlock( array_data *p )
+ \internal
+ Sets the shared array block to \e p.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+
+/*!
+ \internal
+ Sets raw data and returns a reference to the array.
+
+ Dereferences the current array and sets the new array data to \e d and
+ the new array size to \e len. Do not attempt to resize or re-assign the
+ array data when raw data has been set.
+ Call resetRawData(d,len) to reset the array.
+
+ Setting raw data is useful because it set QArray data without allocating
+ memory or copying data.
+
+ Example of intended use:
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ QByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ QDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> <something>; // read raw bindata
+ s.close();
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ Example of misuse (do not do this):
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ QByteArray a, b;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ a.resize( 8 ); // will crash
+ b = a; // will crash
+ a[2] = 123; // might crash
+ // forget to resetRawData - will crash
+ \endcode
+
+ \warning If you do not call resetRawData(), QGArray will attempt to
+ deallocate or reallocate the raw data, which might not be too good.
+ Be careful.
+*/
+
+QGArray &QGArray::setRawData( const char *d, uint len )
+{
+ duplicate( 0, 0 ); // set null data
+ shd->data = (char *)d;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Resets raw data.
+
+ The arguments must be the data and length that were passed to
+ setRawData(). This is for consistency checking.
+*/
+
+void QGArray::resetRawData( const char *d, uint len )
+{
+ if ( d != shd->data || len != shd->len ) {
+#if defined(CHECK_STATE)
+ qWarning( "QGArray::resetRawData: Inconsistent arguments" );
+#endif
+ return;
+ }
+ shd->data = 0;
+ shd->len = 0;
+}
+
+
+/*!
+ \internal
+ Finds the first occurrence of \e d in the array from position \e index,
+ where \e sz is the size of the \e d element.
+
+ Note that \e index is given in units of \e sz, not bytes.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int QGArray::find( const char *d, uint index, uint sz ) const
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray::find: Index %d out of range", index/sz );
+#endif
+ return -1;
+ }
+ register uint i;
+ uint ii;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data() + index;
+ char v = *d;
+ for ( i=index; i<shd->len; i++ ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i;
+ }
+ break;
+ case 2: { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)(data() + index);
+ Q_INT16 v = *((Q_INT16*)d);
+ for ( i=index; i<shd->len; i+=2 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/2;
+ }
+ break;
+ case 4: { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)(data() + index);
+ Q_INT32 v = *((Q_INT32*)d);
+ for ( i=index; i<shd->len; i+=4 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/4;
+ }
+ break;
+ default: { // any size elements
+ for ( i=index; i<shd->len; i+=sz ) {
+ if ( memcmp( d, &shd->data[i], sz ) == 0 )
+ break;
+ }
+ ii = i/sz;
+ }
+ break;
+ }
+ return i<shd->len ? (int)ii : -1;
+}
+
+/*!
+ \internal
+ Returns the number of occurrences of \e d in the array, where \e sz is
+ the size of the \e d element.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int QGArray::contains( const char *d, uint sz ) const
+{
+ register uint i = shd->len;
+ int count = 0;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data();
+ char v = *d;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 2: { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)data();
+ Q_INT16 v = *((Q_INT16*)d);
+ i /= 2;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 4: { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)data();
+ Q_INT32 v = *((Q_INT32*)d);
+ i /= 4;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ default: { // any size elements
+ for ( i=0; i<shd->len; i+=sz ) {
+ if ( memcmp(d, &shd->data[i], sz) == 0 )
+ count++;
+ }
+ }
+ break;
+ }
+ return count;
+}
+
+static int cmp_item_size = 0;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int cmp_arr( const void *n1, const void *n2 )
+{
+ return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size )
+ : (int)((intptr_t)n1 - (intptr_t)n2);
+ // Qt 3.0: Add a virtual compareItems() method and call that instead
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+/*!
+ \internal
+
+ Sort the array.
+*/
+
+void QGArray::sort( uint sz )
+{
+ int numItems = size() / sz;
+ if ( numItems < 2 )
+ return;
+ cmp_item_size = sz;
+ qsort( shd->data, numItems, sz, cmp_arr );
+}
+
+/*!
+ \internal
+
+ Binary search; assumes sorted array
+*/
+
+int QGArray::bsearch( const char *d, uint sz ) const
+{
+ int numItems = size() / sz;
+ if ( !numItems )
+ return -1;
+ cmp_item_size = sz;
+ char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
+ if ( !r )
+ return -1;
+ while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) )
+ r -= sz; // search to first of equal elements; bsearch is undef
+ return (int)(( r - shd->data ) / sz);
+}
+
+
+/*!
+ \fn char *QGArray::at( uint index ) const
+ \internal
+ Returns a pointer to the byte at offset \e index in the array.
+*/
+
+/*!
+ \internal
+ Expand the array if necessary, and copies (the first part of) its
+ contents from the \e index*zx bytes at \e d.
+
+ Returns TRUE if the operation succeeds, FALSE if it runs out of
+ memory.
+
+ \warning This function disregards the reference count mechanism. If
+ other QGArrays reference the same data as this, all will be changed.
+*/
+
+bool QGArray::setExpand( uint index, const char *d, uint sz )
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+ if ( !resize( index+sz ) ) // no memory
+ return FALSE;
+ }
+ memcpy( data() + index, d, sz );
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Prints a warning message if at() or [] is given a bad index.
+*/
+
+void QGArray::msg_index( uint index )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray::at: Absolute index %d out of range", index );
+#else
+ Q_UNUSED( index )
+#endif
+}
+
+
+/*!
+ \internal
+ Returns a new shared array block.
+*/
+
+QGArray::array_data * QGArray::newData()
+{
+ return new array_data;
+}
+
+
+/*!
+ \internal
+ Deletes the shared array block.
+*/
+
+void QGArray::deleteData( array_data *p )
+{
+ delete p;
+ p = 0;
+}
diff --git a/qtools/qgarray.h b/qtools/qgarray.h
new file mode 100644
index 0000000..12c463b
--- /dev/null
+++ b/qtools/qgarray.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+**
+** Definition of QGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGARRAY_H
+#define QGARRAY_H
+
+#ifndef QT_H
+#include "qshared.h"
+#endif // QT_H
+
+
+class Q_EXPORT QGArray // generic array
+{
+friend class QBuffer;
+public:
+ //### DO NOT USE THIS. IT IS PUBLIC BUT DO NOT USE IT IN NEW CODE.
+ struct array_data : public QShared { // shared array
+ array_data() { data=0; len=0; }
+ char *data; // actual array data
+ uint len;
+ };
+ QGArray();
+protected:
+ QGArray( int, int ); // dummy; does not alloc
+ QGArray( int size ); // allocate 'size' bytes
+ QGArray( const QGArray &a ); // shallow copy
+ virtual ~QGArray();
+
+ QGArray &operator=( const QGArray &a ) { return assign( a ); }
+
+ virtual void detach() { duplicate(*this); }
+
+ char *data() const { return shd->data; }
+ uint nrefs() const { return shd->count; }
+ uint size() const { return shd->len; }
+ bool isEqual( const QGArray &a ) const;
+
+ bool resize( uint newsize );
+
+ bool fill( const char *d, int len, uint sz );
+
+ QGArray &assign( const QGArray &a );
+ QGArray &assign( const char *d, uint len );
+ QGArray &duplicate( const QGArray &a );
+ QGArray &duplicate( const char *d, uint len );
+ void store( const char *d, uint len );
+
+ array_data *sharedBlock() const { return shd; }
+ void setSharedBlock( array_data *p ) { shd=(array_data*)p; }
+
+ QGArray &setRawData( const char *d, uint len );
+ void resetRawData( const char *d, uint len );
+
+ int find( const char *d, uint index, uint sz ) const;
+ int contains( const char *d, uint sz ) const;
+
+ void sort( uint sz );
+ int bsearch( const char *d, uint sz ) const;
+
+ char *at( uint index ) const;
+
+ bool setExpand( uint index, const char *d, uint sz );
+
+protected:
+ virtual array_data *newData();
+ virtual void deleteData( array_data *p );
+
+private:
+ static void msg_index( uint );
+ array_data *shd;
+};
+
+
+inline char *QGArray::at( uint index ) const
+{
+#if defined(CHECK_RANGE)
+ if ( index >= size() ) {
+ msg_index( index );
+ index = 0;
+ }
+#endif
+ return &shd->data[index];
+}
+
+
+#endif // QGARRAY_H
diff --git a/qtools/qgcache.cpp b/qtools/qgcache.cpp
new file mode 100644
index 0000000..683c2a7
--- /dev/null
+++ b/qtools/qgcache.cpp
@@ -0,0 +1,878 @@
+/****************************************************************************
+**
+**
+** Implementation of QGCache and QGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qgcache.h"
+#include "qinternallist.h"
+#include "qdict.h"
+#include "qstring.h"
+
+
+// NOT REVISED
+/*!
+ \class QGCache qgcache.h
+
+ \brief The QGCache class is an internal class for implementing QCache template classes.
+
+ QGCache is a strictly internal class that acts as a base class for the
+ \link collection.html collection classes\endlink QCache and QIntCache.
+*/
+
+
+/*****************************************************************************
+ QGCacheItem class (internal cache item)
+ *****************************************************************************/
+
+struct QCacheItem
+{
+ QCacheItem( void *k, QCollection::Item d, int c, short p )
+ : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {}
+ short priority;
+ short skipPriority;
+ int cost;
+ void *key;
+ QCollection::Item data;
+ QLNode *node;
+};
+
+
+/*****************************************************************************
+ QCList class (internal list of cache items)
+ *****************************************************************************/
+
+class QCList : private QInternalList<QCacheItem>
+{
+friend class QGCacheIterator;
+friend class QCListIt;
+public:
+ QCList() {}
+ ~QCList();
+
+ void insert( QCacheItem * ); // insert according to priority
+ void insert( int, QCacheItem * );
+ void take( QCacheItem * );
+ void reference( QCacheItem * );
+
+ void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+
+ bool removeFirst() { return QInternalList<QCacheItem>::removeFirst(); }
+ bool removeLast() { return QInternalList<QCacheItem>::removeLast(); }
+
+ QCacheItem *first() { return QInternalList<QCacheItem>::first(); }
+ QCacheItem *last() { return QInternalList<QCacheItem>::last(); }
+ QCacheItem *prev() { return QInternalList<QCacheItem>::prev(); }
+ QCacheItem *next() { return QInternalList<QCacheItem>::next(); }
+
+#if defined(DEBUG)
+ int inserts; // variables for statistics
+ int insertCosts;
+ int insertMisses;
+ int finds;
+ int hits;
+ int hitCosts;
+ int dumps;
+ int dumpCosts;
+#endif
+};
+
+
+QCList::~QCList()
+{
+#if defined(DEBUG)
+ ASSERT( count() == 0 );
+#endif
+}
+
+
+void QCList::insert( QCacheItem *ci )
+{
+ QCacheItem *item = first();
+ while( item && item->skipPriority > ci->priority ) {
+ item->skipPriority--;
+ item = next();
+ }
+ if ( item )
+ QInternalList<QCacheItem>::insert( at(), ci );
+ else
+ append( ci );
+#if defined(DEBUG)
+ ASSERT( ci->node == 0 );
+#endif
+ ci->node = currentNode();
+}
+
+inline void QCList::insert( int i, QCacheItem *ci )
+{
+ QInternalList<QCacheItem>::insert( i, ci );
+#if defined(DEBUG)
+ ASSERT( ci->node == 0 );
+#endif
+ ci->node = currentNode();
+}
+
+
+void QCList::take( QCacheItem *ci )
+{
+ if ( ci ) {
+#if defined(DEBUG)
+ ASSERT( ci->node != 0 );
+#endif
+ takeNode( ci->node );
+ ci->node = 0;
+ }
+}
+
+
+inline void QCList::reference( QCacheItem *ci )
+{
+#if defined(DEBUG)
+ ASSERT( ci != 0 && ci->node != 0 );
+#endif
+ ci->skipPriority = ci->priority;
+ relinkNode( ci->node ); // relink as first item
+}
+
+
+class QCListIt: public QInternalListIterator<QCacheItem>
+{
+public:
+ QCListIt( const QCList *p ): QInternalListIterator<QCacheItem>( *p ) {}
+ QCListIt( const QCListIt *p ): QInternalListIterator<QCacheItem>( *p ) {}
+};
+
+
+/*****************************************************************************
+ QCDict class (internal dictionary of cache items)
+ *****************************************************************************/
+
+//
+// Since we need to decide if the dictionary should use an int or const
+// char * key (the "bool trivial" argument in the constructor below)
+// we cannot use the macro/template dict, but inherit directly from QGDict.
+//
+
+class QCDict : public QGDict
+{
+public:
+ QCDict( uint size, uint kt, bool caseSensitive, bool copyKeys )
+ : QGDict( size, (KeyType)kt, caseSensitive, copyKeys ) {}
+
+ QCacheItem *find_string(const QString &key) const
+ { return (QCacheItem*)((QCDict*)this)->look_string(key, 0, 0); }
+ QCacheItem *find_ascii(const char *key) const
+ { return (QCacheItem*)((QCDict*)this)->look_ascii(key, 0, 0); }
+ QCacheItem *find_int(long key) const
+ { return (QCacheItem*)((QCDict*)this)->look_int(key, 0, 0); }
+
+ QCacheItem *take_string(const QString &key)
+ { return (QCacheItem*)QGDict::take_string(key); }
+ QCacheItem *take_ascii(const char *key)
+ { return (QCacheItem*)QGDict::take_ascii(key); }
+ QCacheItem *take_int(long key)
+ { return (QCacheItem*)QGDict::take_int(key); }
+
+ bool insert_string( const QString &key, const QCacheItem *ci )
+ { return QGDict::look_string(key,(Item)ci,1)!=0;}
+ bool insert_ascii( const char *key, const QCacheItem *ci )
+ { return QGDict::look_ascii(key,(Item)ci,1)!=0;}
+ bool insert_int( long key, const QCacheItem *ci )
+ { return QGDict::look_int(key,(Item)ci,1)!=0;}
+
+ bool remove_string( QCacheItem *item )
+ { return QGDict::remove_string(*((QString*)(item->key)),item); }
+ bool remove_ascii( QCacheItem *item )
+ { return QGDict::remove_ascii((const char *)item->key,item); }
+ bool remove_int( QCacheItem *item )
+ { return QGDict::remove_int((intptr_t)item->key,item);}
+
+ void statistics() { QGDict::statistics(); }
+};
+
+
+/*****************************************************************************
+ QGDict member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Constructs a cache.
+*/
+
+QGCache::QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+ bool copyKeys )
+{
+ keytype = kt;
+ lruList = new QCList;
+ CHECK_PTR( lruList );
+ lruList->setAutoDelete( TRUE );
+ copyk = ((keytype == AsciiKey) && copyKeys);
+ dict = new QCDict( size, kt, caseSensitive, FALSE );
+ CHECK_PTR( dict );
+ mCost = maxCost;
+ tCost = 0;
+#if defined(DEBUG)
+ lruList->inserts = 0;
+ lruList->insertCosts = 0;
+ lruList->insertMisses = 0;
+ lruList->finds = 0;
+ lruList->hits = 0;
+ lruList->hitCosts = 0;
+ lruList->dumps = 0;
+ lruList->dumpCosts = 0;
+#endif
+}
+
+/*!
+ \internal
+ Cannot copy a cache.
+*/
+
+QGCache::QGCache( const QGCache & )
+ : QCollection()
+{
+#if defined(CHECK_NULL)
+ qFatal( "QGCache::QGCache(QGCache &): Cannot copy a cache" );
+#endif
+}
+
+/*!
+ \internal
+ Removes all items from the cache and destroys it.
+*/
+
+QGCache::~QGCache()
+{
+ clear(); // delete everything first
+ delete dict;
+ delete lruList;
+}
+
+/*!
+ \internal
+ Cannot assign a cache.
+*/
+
+QGCache &QGCache::operator=( const QGCache & )
+{
+#if defined(CHECK_NULL)
+ qFatal( "QGCache::operator=: Cannot copy a cache" );
+#endif
+ return *this; // satisfy the compiler
+}
+
+
+/*!
+ \fn uint QGCache::count() const
+ \internal
+ Returns the number of items in the cache.
+*/
+
+/*!
+ \fn uint QGCache::size() const
+ \internal
+ Returns the size of the hash array.
+*/
+
+/*!
+ \fn int QGCache::maxCost() const
+ \internal
+ Returns the maximum cache cost.
+*/
+
+/*!
+ \fn int QGCache::totalCost() const
+ \internal
+ Returns the total cache cost.
+*/
+
+/*!
+ \internal
+ Sets the maximum cache cost.
+*/
+
+void QGCache::setMaxCost( int maxCost )
+{
+ if ( maxCost < tCost ) {
+ if ( !makeRoomFor(tCost - maxCost) ) // remove excess cost
+ return;
+ }
+ mCost = maxCost;
+}
+
+
+/*!
+ \internal
+ Inserts an item into the cache.
+
+ \warning If this function returns FALSE, you must delete \a data
+ yourself. Additionally, be very careful about using \a data after
+ calling this function, as any other insertions into the cache, from
+ anywhere in the application, or within Qt itself, could cause the
+ data to be discarded from the cache, and the pointer to become
+ invalid.
+*/
+
+bool QGCache::insert_string( const QString &key, QCollection::Item data,
+ int cost, int priority)
+{
+ if ( tCost + cost > mCost ) {
+ if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(DEBUG)
+ lruList->insertMisses++;
+#endif
+ return FALSE;
+ }
+ }
+#if defined(DEBUG)
+ ASSERT( keytype == StringKey );
+ lruList->inserts++;
+ lruList->insertCosts += cost;
+#endif
+ if ( priority < -32768 )
+ priority = -32768;
+ else if ( priority > 32767 )
+ priority = 32677;
+ QCacheItem *ci = new QCacheItem( new QString(key), newItem(data),
+ cost, (short)priority );
+ CHECK_PTR( ci );
+ lruList->insert( 0, ci );
+ dict->insert_string( key, ci );
+ tCost += cost;
+ return TRUE;
+}
+
+
+/*! \internal */
+
+bool QGCache::insert_other( const char *key, QCollection::Item data,
+ int cost, int priority)
+{
+ if ( tCost + cost > mCost ) {
+ if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(DEBUG)
+ lruList->insertMisses++;
+#endif
+ return FALSE;
+ }
+ }
+#if defined(DEBUG)
+ ASSERT( keytype != StringKey );
+ lruList->inserts++;
+ lruList->insertCosts += cost;
+#endif
+ if ( keytype == AsciiKey && copyk )
+ key = qstrdup( key );
+ if ( priority < -32768 )
+ priority = -32768;
+ else if ( priority > 32767 )
+ priority = 32677;
+ QCacheItem *ci = new QCacheItem( (void*)key, newItem(data), cost,
+ (short)priority );
+ CHECK_PTR( ci );
+ lruList->insert( 0, ci );
+ if ( keytype == AsciiKey )
+ dict->insert_ascii( key, ci );
+ else
+ dict->insert_int( (intptr_t)key, ci );
+ tCost += cost;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Removes an item from the cache.
+*/
+
+bool QGCache::remove_string( const QString &key )
+{
+ Item d = take_string( key );
+ if ( d )
+ deleteItem( d );
+ return d != 0;
+}
+
+
+/*! \internal */
+
+bool QGCache::remove_other( const char *key )
+{
+ Item d = take_other( key );
+ if ( d )
+ deleteItem( d );
+ return d != 0;
+}
+
+
+/*!
+ \internal
+ Takes an item out of the cache (no delete).
+*/
+
+QCollection::Item QGCache::take_string( const QString &key )
+{
+ QCacheItem *ci = dict->take_string( key ); // take from dict
+ Item d;
+ if ( ci ) {
+ d = ci->data;
+ tCost -= ci->cost;
+ lruList->take( ci ); // take from list
+ delete (QString*)ci->key;
+ delete ci;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+/*!
+ \internal
+ Takes an item out of the cache (no delete).
+*/
+
+QCollection::Item QGCache::take_other( const char *key )
+{
+ QCacheItem *ci;
+ if ( keytype == AsciiKey )
+ ci = dict->take_ascii( key );
+ else
+ ci = dict->take_int( (intptr_t)key );
+ Item d;
+ if ( ci ) {
+ d = ci->data;
+ tCost -= ci->cost;
+ lruList->take( ci ); // take from list
+ if ( copyk )
+ delete [] (char *)ci->key;
+ delete ci;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*!
+ \internal
+ Clears the cache.
+*/
+
+void QGCache::clear()
+{
+ QCacheItem *ci;
+ while ( (ci = lruList->first()) ) {
+ switch ( keytype ) {
+ case StringKey:
+ dict->remove_string( ci );
+ delete (QString*)ci->key;
+ break;
+ case AsciiKey:
+ dict->remove_ascii( ci );
+ if ( copyk )
+ delete [] (char*)ci->key;
+ break;
+ case IntKey:
+ dict->remove_int( ci );
+ break;
+ case PtrKey: // unused
+ break;
+ }
+ deleteItem( ci->data ); // delete data
+ lruList->removeFirst(); // remove from list
+ }
+ tCost = 0;
+}
+
+
+/*!
+ \internal
+ Finds an item in the cache.
+*/
+
+QCollection::Item QGCache::find_string( const QString &key, bool ref ) const
+{
+ QCacheItem *ci = dict->find_string( key );
+#if defined(DEBUG)
+ lruList->finds++;
+#endif
+ if ( ci ) {
+#if defined(DEBUG)
+ lruList->hits++;
+ lruList->hitCosts += ci->cost;
+#endif
+ if ( ref )
+ lruList->reference( ci );
+ return ci->data;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Finds an item in the cache.
+*/
+
+QCollection::Item QGCache::find_other( const char *key, bool ref ) const
+{
+ QCacheItem *ci = keytype == AsciiKey ? dict->find_ascii(key)
+ : dict->find_int((intptr_t)key);
+#if defined(DEBUG)
+ lruList->finds++;
+#endif
+ if ( ci ) {
+#if defined(DEBUG)
+ lruList->hits++;
+ lruList->hitCosts += ci->cost;
+#endif
+ if ( ref )
+ lruList->reference( ci );
+ return ci->data;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Allocates cache space for one or more items.
+*/
+
+bool QGCache::makeRoomFor( int cost, int priority )
+{
+ if ( cost > mCost ) // cannot make room for more
+ return FALSE; // than maximum cost
+ if ( priority == -1 )
+ priority = 32767;
+ register QCacheItem *ci = lruList->last();
+ int cntCost = 0;
+ int dumps = 0; // number of items to dump
+ while ( cntCost < cost && ci && ci->skipPriority <= priority ) {
+ cntCost += ci->cost;
+ ci = lruList->prev();
+ dumps++;
+ }
+ if ( cntCost < cost ) // can enough cost be dumped?
+ return FALSE; // no
+#if defined(DEBUG)
+ ASSERT( dumps > 0 );
+#endif
+ while ( dumps-- ) {
+ ci = lruList->last();
+#if defined(DEBUG)
+ lruList->dumps++;
+ lruList->dumpCosts += ci->cost;
+#endif
+ switch ( keytype ) {
+ case StringKey:
+ dict->remove_string( ci );
+ delete (QString*)ci->key;
+ break;
+ case AsciiKey:
+ dict->remove_ascii( ci );
+ if ( copyk )
+ delete [] (char *)ci->key;
+ break;
+ case IntKey:
+ dict->remove_int( ci );
+ break;
+ case PtrKey: // unused
+ break;
+ }
+ deleteItem( ci->data ); // delete data
+ lruList->removeLast(); // remove from list
+ }
+ tCost -= cntCost;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Outputs debug statistics.
+*/
+
+void QGCache::statistics() const
+{
+#if defined(DEBUG)
+ QString line;
+ line.fill( '*', 80 );
+ qDebug( "%s",line.ascii() );
+ qDebug( "CACHE STATISTICS:" );
+ qDebug( "cache contains %d item%s, with a total cost of %d",
+ count(), count() != 1 ? "s" : "", tCost );
+ qDebug( "maximum cost is %d, cache is %d%% full.",
+ mCost, (200*tCost + mCost) / (mCost*2) );
+ qDebug( "find() has been called %d time%s",
+ lruList->finds, lruList->finds != 1 ? "s" : "" );
+ qDebug( "%d of these were hits, items found had a total cost of %d.",
+ lruList->hits,lruList->hitCosts );
+ qDebug( "%d item%s %s been inserted with a total cost of %d.",
+ lruList->inserts,lruList->inserts != 1 ? "s" : "",
+ lruList->inserts != 1 ? "have" : "has", lruList->insertCosts );
+ qDebug( "%d item%s %s too large or had too low priority to be inserted.",
+ lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "",
+ lruList->insertMisses != 1 ? "were" : "was" );
+ qDebug( "%d item%s %s been thrown away with a total cost of %d.",
+ lruList->dumps, lruList->dumps != 1 ? "s" : "",
+ lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts );
+ qDebug( "Statistics from internal dictionary class:" );
+ dict->statistics();
+ qDebug( "%s",line.ascii() );
+#endif
+}
+
+int QGCache::hits() const
+{
+ return lruList->hits;
+}
+
+int QGCache::misses() const
+{
+ return lruList->finds - lruList->hits;
+}
+
+
+/*****************************************************************************
+ QGCacheIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class QGCacheIterator qgcache.h
+
+ \brief An internal class for implementing QCacheIterator and QIntCacheIterator.
+
+ QGCacheIterator is a strictly internal class that does the heavy work for
+ QCacheIterator and QIntCacheIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the cache \e c.
+*/
+
+QGCacheIterator::QGCacheIterator( const QGCache &c )
+{
+ it = new QCListIt( c.lruList );
+#if defined(DEBUG)
+ ASSERT( it != 0 );
+#endif
+}
+
+/*!
+ \internal
+ Constructs an iterator that operates on the same cache as \e ci.
+*/
+
+QGCacheIterator::QGCacheIterator( const QGCacheIterator &ci )
+{
+ it = new QCListIt( ci.it );
+#if defined(DEBUG)
+ ASSERT( it != 0 );
+#endif
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+QGCacheIterator::~QGCacheIterator()
+{
+ delete it;
+}
+
+/*!
+ \internal
+ Assigns the iterator \e ci to this cache iterator.
+*/
+
+QGCacheIterator &QGCacheIterator::operator=( const QGCacheIterator &ci )
+{
+ *it = *ci.it;
+ return *this;
+}
+
+/*!
+ \internal
+ Returns the number of items in the cache.
+*/
+
+uint QGCacheIterator::count() const
+{
+ return it->count();
+}
+
+/*!
+ \internal
+ Returns TRUE if the iterator points to the first item.
+*/
+
+bool QGCacheIterator::atFirst() const
+{
+ return it->atFirst();
+}
+
+/*!
+ \internal
+ Returns TRUE if the iterator points to the last item.
+*/
+
+bool QGCacheIterator::atLast() const
+{
+ return it->atLast();
+}
+
+/*!
+ \internal
+ Sets the list iterator to point to the first item in the cache.
+*/
+
+QCollection::Item QGCacheIterator::toFirst()
+{
+ QCacheItem *item = it->toFirst();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Sets the list iterator to point to the last item in the cache.
+*/
+
+QCollection::Item QGCacheIterator::toLast()
+{
+ QCacheItem *item = it->toLast();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Returns the current item.
+*/
+
+QCollection::Item QGCacheIterator::get() const
+{
+ QCacheItem *item = it->current();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Returns the key of the current item.
+*/
+
+QString QGCacheIterator::getKeyString() const
+{
+ QCacheItem *item = it->current();
+ return item ? *((QString*)item->key) : QString::null;
+}
+
+/*!
+ \internal
+ Returns the key of the current item, as a \0-terminated C string.
+*/
+
+const char *QGCacheIterator::getKeyAscii() const
+{
+ QCacheItem *item = it->current();
+ return item ? (const char *)item->key : 0;
+}
+
+/*!
+ \internal
+ Returns the key of the current item, as a long.
+*/
+
+intptr_t QGCacheIterator::getKeyInt() const
+{
+ QCacheItem *item = it->current();
+ return item ? (intptr_t)item->key : 0;
+}
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+QCollection::Item QGCacheIterator::operator()()
+{
+ QCacheItem *item = it->operator()();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+QCollection::Item QGCacheIterator::operator++()
+{
+ QCacheItem *item = it->operator++();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGCacheIterator::operator+=( uint jump )
+{
+ QCacheItem *item = it->operator+=(jump);
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Moves to the previous item (prefix).
+*/
+
+QCollection::Item QGCacheIterator::operator--()
+{
+ QCacheItem *item = it->operator--();
+ return item ? item->data : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions backward.
+*/
+
+QCollection::Item QGCacheIterator::operator-=( uint jump )
+{
+ QCacheItem *item = it->operator-=(jump);
+ return item ? item->data : 0;
+}
diff --git a/qtools/qgcache.h b/qtools/qgcache.h
new file mode 100644
index 0000000..a71f6d3
--- /dev/null
+++ b/qtools/qgcache.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+**
+** Definition of QGCache and QGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGCACHE_H
+#define QGCACHE_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#include "qglist.h"
+#include "qgdict.h"
+#endif // QT_H
+
+
+class QCList; // internal classes
+class QCListIt;
+class QCDict;
+
+
+class Q_EXPORT QGCache : public QCollection // generic LRU cache
+{
+friend class QGCacheIterator;
+protected:
+ enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+ // identical to QGDict's, but PtrKey is not used at the moment
+
+ QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+ bool copyKeys );
+ QGCache( const QGCache & ); // not allowed, calls fatal()
+ ~QGCache();
+ QGCache &operator=( const QGCache & ); // not allowed, calls fatal()
+
+ uint count() const { return ((QGDict*)dict)->count(); }
+ uint size() const { return ((QGDict*)dict)->size(); }
+ int maxCost() const { return mCost; }
+ int totalCost() const { return tCost; }
+ void setMaxCost( int maxCost );
+ void clear();
+
+ bool insert_string( const QString &key, QCollection::Item,
+ int cost, int priority );
+ bool insert_other( const char *key, QCollection::Item,
+ int cost, int priority );
+ bool remove_string( const QString &key );
+ bool remove_other( const char *key );
+ QCollection::Item take_string( const QString &key );
+ QCollection::Item take_other( const char *key );
+
+ QCollection::Item find_string( const QString &key, bool ref=TRUE ) const;
+ QCollection::Item find_other( const char *key, bool ref=TRUE ) const;
+
+ void statistics() const;
+ int hits() const;
+ int misses() const;
+
+private:
+ bool makeRoomFor( int cost, int priority = -1 );
+ KeyType keytype;
+ QCList *lruList;
+ QCDict *dict;
+ int mCost;
+ int tCost;
+ bool copyk;
+};
+
+
+class Q_EXPORT QGCacheIterator // generic cache iterator
+{
+protected:
+ QGCacheIterator( const QGCache & );
+ QGCacheIterator( const QGCacheIterator & );
+ ~QGCacheIterator();
+ QGCacheIterator &operator=( const QGCacheIterator & );
+
+ uint count() const;
+ bool atFirst() const;
+ bool atLast() const;
+ QCollection::Item toFirst();
+ QCollection::Item toLast();
+
+ QCollection::Item get() const;
+ QString getKeyString() const;
+ const char *getKeyAscii() const;
+ intptr_t getKeyInt() const;
+
+ QCollection::Item operator()();
+ QCollection::Item operator++();
+ QCollection::Item operator+=( uint );
+ QCollection::Item operator--();
+ QCollection::Item operator-=( uint );
+
+protected:
+ QCListIt *it; // iterator on cache list
+};
+
+
+#endif // QGCACHE_H
diff --git a/qtools/qgdict.cpp b/qtools/qgdict.cpp
new file mode 100644
index 0000000..2530986
--- /dev/null
+++ b/qtools/qgdict.cpp
@@ -0,0 +1,1218 @@
+/****************************************************************************
+**
+**
+** Implementation of QGDict and QGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qgdict.h"
+#include "qinternallist.h"
+#include "qstring.h"
+#include "qdatastream.h"
+#include <ctype.h>
+
+// NOT REVISED
+/*!
+ \class QGDict qgdict.h
+ \brief The QGDict class is an internal class for implementing QDict template classes.
+
+ QGDict is a strictly internal class that acts as a base class for the
+ \link collection.html collection classes\endlink QDict and QIntDict.
+
+ QGDict has some virtual functions that can be reimplemented to customize
+ the subclasses.
+ <ul>
+ <li> read() reads a collection/dictionary item from a QDataStream.
+ <li> write() writes a collection/dictionary item to a QDataStream.
+ </ul>
+ Normally, you do not have to reimplement any of these functions.
+*/
+
+static const int op_find = 0;
+static const int op_insert = 1;
+static const int op_replace = 2;
+
+
+class QGDItList : public QInternalList<QGDictIterator>
+{
+public:
+ QGDItList() : QInternalList<QGDictIterator>() {}
+ QGDItList( const QGDItList &list ) : QInternalList<QGDictIterator>(list) {}
+ ~QGDItList() { clear(); }
+ QGDItList &operator=(const QGDItList &list)
+ { return (QGDItList&)QInternalList<QGDictIterator>::operator=(list); }
+};
+
+
+/*****************************************************************************
+ Default implementation of special and virtual functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Returns the hash key for \e key, when key is a string.
+*/
+
+int QGDict::hashKeyString( const QString &key )
+{
+#if defined(CHECK_NULL)
+ if ( key.isNull() )
+ qWarning( "QGDict::hashStringKey: Invalid null key" );
+#endif
+ int i;
+ register uint h=0;
+ uint g;
+ int len = key.length();
+ const QChar *p = key.unicode();
+ if ( cases ) { // case sensitive
+ for ( i=0; i<len; i++ ) {
+ h = (h<<4) + p[i].cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ for ( i=0; i<len; i++ ) {
+ h = (h<<4) + p[i].lower().cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+/*!
+ \internal
+ Returns the hash key for \a key, which is a C string.
+*/
+
+int QGDict::hashKeyAscii( const char *key )
+{
+#if defined(CHECK_NULL)
+ if ( key == 0 )
+ {
+ qWarning( "QGDict::hashAsciiKey: Invalid null key" );
+ return 0;
+ }
+#endif
+ register const char *k = key;
+ register uint h=0;
+ uint g;
+ if ( cases ) { // case sensitive
+ while ( *k ) {
+ h = (h<<4) + *k++;
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ while ( *k ) {
+ h = (h<<4) + tolower(*k);
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ k++;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ Reads a collection/dictionary item from the stream \e s and returns a
+ reference to the stream.
+
+ The default implementation sets \e item to 0.
+
+ \sa write()
+*/
+
+QDataStream& QGDict::read( QDataStream &s, QCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/dictionary item to the stream \e s and returns a
+ reference to the stream.
+
+ \sa read()
+*/
+
+QDataStream& QGDict::write( QDataStream &s, QCollection::Item ) const
+{
+ return s;
+}
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGDict member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Constructs a dictionary.
+*/
+
+QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ init( len, kt, caseSensitive, copyKeys );
+}
+
+
+void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ vec = new QBaseBucket *[vlen = len]; // allocate hash table
+ CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
+ numItems = 0;
+ iterators = 0;
+ // The caseSensitive and copyKey options don't make sense for
+ // all dict types.
+ switch ( (keytype = (uint)kt) ) {
+ case StringKey:
+ cases = caseSensitive;
+ copyk = FALSE;
+ break;
+ case AsciiKey:
+ cases = caseSensitive;
+ copyk = copyKeys;
+ break;
+ default:
+ cases = FALSE;
+ copyk = FALSE;
+ break;
+ }
+}
+
+
+/*!
+ \internal
+ Constructs a copy of \e dict.
+*/
+
+QGDict::QGDict( const QGDict & dict )
+ : QCollection( dict )
+{
+ init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk );
+ QGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+}
+
+
+/*!
+ \internal
+ Removes all items from the dictionary and destroys it.
+*/
+
+QGDict::~QGDict()
+{
+ clear(); // delete everything
+ delete [] vec;
+ if ( !iterators ) // no iterators for this dict
+ return;
+ QGDictIterator *i = iterators->first();
+ while ( i ) { // notify all iterators that
+ i->dict = 0; // this dict is deleted
+ i = iterators->next();
+ }
+ delete iterators;
+}
+
+
+/*!
+ \internal
+ Assigns \e dict to this dictionary.
+*/
+
+QGDict &QGDict::operator=( const QGDict &dict )
+{
+ clear();
+ QGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+ return *this;
+}
+
+
+/*! \fn QCollection::Item QGDictIterator::get() const
+
+ \internal
+*/
+
+
+/*! \fn QString QGDictIterator::getKeyString() const
+
+ \internal
+*/
+
+
+/*! \fn const char * QGDictIterator::getKeyAscii() const
+
+ \internal
+*/
+
+
+/*! \fn void * QGDictIterator::getKeyPtr() const
+
+ \internal
+*/
+
+
+/*! \fn long QGDictIterator::getKeyInt() const
+
+ \internal
+*/
+
+
+/*!
+ \fn uint QGDict::count() const
+ \internal
+ Returns the number of items in the dictionary.
+*/
+
+/*!
+ \fn uint QGDict::size() const
+ \internal
+ Returns the size of the hash array.
+*/
+
+
+/*!
+ \internal
+ The do-it-all function; op is one of op_find, op_insert, op_replace
+*/
+
+QCollection::Item QGDict::look_string( const QString &key, QCollection::Item d, int op )
+{
+ QStringBucket *n;
+ int index = hashKeyString(key) % vlen;
+ if ( op == op_find ) { // find
+ if ( cases ) {
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ if ( key == n->getKey() )
+ return n->getData(); // item found
+ }
+ } else {
+ QString k = key.lower();
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ if ( k == n->getKey().lower() )
+ return n->getData(); // item found
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_string( key );
+ }
+ // op_insert or op_replace
+ n = new QStringBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_ascii( const char *key, QCollection::Item d, int op )
+{
+ QAsciiBucket *n;
+ int index = hashKeyAscii(key) % vlen;
+ if ( op == op_find ) { // find
+ if ( cases ) {
+ for ( n=(QAsciiBucket*)vec[index]; n;
+ n=(QAsciiBucket*)n->getNext() ) {
+ if ( qstrcmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ } else {
+ for ( n=(QAsciiBucket*)vec[index]; n;
+ n=(QAsciiBucket*)n->getNext() ) {
+ if ( qstricmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ascii( key );
+ }
+ // op_insert or op_replace
+ n = new QAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QAsciiDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_int( long key, QCollection::Item d, int op )
+{
+ QIntBucket *n;
+ int index = (int)((ulong)key % vlen); // simple hash
+ if ( op == op_find ) { // find
+ for ( n=(QIntBucket*)vec[index]; n;
+ n=(QIntBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_int( key );
+ }
+ // op_insert or op_replace
+ n = new QIntBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QIntDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_ptr( void *key, QCollection::Item d, int op )
+{
+ QPtrBucket *n;
+ int index = (int)((uintptr_t)key % vlen); // simple hash
+ if ( op == op_find ) { // find
+ for ( n=(QPtrBucket*)vec[index]; n;
+ n=(QPtrBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ptr( key );
+ }
+ // op_insert or op_replace
+ n = new QPtrBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QPtrDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*!
+ \internal
+ Changes the size of the hashtable.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+void QGDict::resize( uint newsize )
+{
+ // Save old information
+ QBaseBucket **old_vec = vec;
+ uint old_vlen = vlen;
+ bool old_copyk = copyk;
+
+ vec = new QBaseBucket *[vlen = newsize];
+ CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
+ numItems = 0;
+ copyk = FALSE;
+
+ // Reinsert every item from vec, deleting vec as we go
+ for ( uint index = 0; index < old_vlen; index++ ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QStringBucket *n=(QStringBucket *)old_vec[index];
+ while ( n ) {
+ look_string( n->getKey(), n->getData(), op_insert );
+ QStringBucket *t=(QStringBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ QAsciiBucket *n=(QAsciiBucket *)old_vec[index];
+ while ( n ) {
+ look_ascii( n->getKey(), n->getData(), op_insert );
+ QAsciiBucket *t=(QAsciiBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ QIntBucket *n=(QIntBucket *)old_vec[index];
+ while ( n ) {
+ look_int( n->getKey(), n->getData(), op_insert );
+ QIntBucket *t=(QIntBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ QPtrBucket *n=(QPtrBucket *)old_vec[index];
+ while ( n ) {
+ look_ptr( n->getKey(), n->getData(), op_insert );
+ QPtrBucket *t=(QPtrBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ }
+ }
+ delete [] old_vec;
+
+ // Restore state
+ copyk = old_copyk;
+
+ // Invalidate all iterators, since order is lost
+ if ( iterators && iterators->count() ) {
+ QGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->toFirst();
+ i = iterators->next();
+ }
+ }
+}
+
+/*!
+ \internal
+ Unlinks the bucket with the specified key (and specified data pointer,
+ if it is set).
+*/
+
+void QGDict::unlink_common( int index, QBaseBucket *node, QBaseBucket *prev )
+{
+ if ( iterators && iterators->count() ) { // update iterators
+ QGDictIterator *i = iterators->first();
+ while ( i ) { // invalidate all iterators
+ if ( i->curNode == node ) // referring to pending node
+ i->operator++();
+ i = iterators->next();
+ }
+ }
+ if ( prev ) // unlink node
+ prev->setNext( node->getNext() );
+ else
+ vec[index] = node->getNext();
+ numItems--;
+}
+
+QStringBucket *QGDict::unlink_string( const QString &key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QStringBucket *n;
+ QStringBucket *prev = 0;
+ int index = hashKeyString(key) % vlen;
+ if ( cases ) {
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ bool found = (key == n->getKey());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ } else {
+ QString k = key.lower();
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ bool found = (k == n->getKey().lower());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ }
+ return 0;
+}
+
+QAsciiBucket *QGDict::unlink_ascii( const char *key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QAsciiBucket *n;
+ QAsciiBucket *prev = 0;
+ int index = hashKeyAscii(key) % vlen;
+ for ( n=(QAsciiBucket *)vec[index]; n; n=(QAsciiBucket *)n->getNext() ) {
+ bool found = (cases ? qstrcmp(n->getKey(),key)
+ : qstricmp(n->getKey(),key)) == 0;
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+QIntBucket *QGDict::unlink_int( long key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QIntBucket *n;
+ QIntBucket *prev = 0;
+ int index = (int)((ulong)key % vlen);
+ for ( n=(QIntBucket *)vec[index]; n; n=(QIntBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+QPtrBucket *QGDict::unlink_ptr( void *key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QPtrBucket *n;
+ QPtrBucket *prev = 0;
+ int index = (int)((uintptr_t)key % vlen);
+ for ( n=(QPtrBucket *)vec[index]; n; n=(QPtrBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Removes the item with the specified key. If item is non-null,
+ the remove will match the \a item as well (used to remove an
+ item when several items have the same key).
+*/
+
+bool QGDict::remove_string( const QString &key, QCollection::Item item )
+{
+ QStringBucket *n = unlink_string( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_ascii( const char *key, QCollection::Item item )
+{
+ QAsciiBucket *n = unlink_ascii( key, item );
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_int( long key, QCollection::Item item )
+{
+ QIntBucket *n = unlink_int( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_ptr( void *key, QCollection::Item item )
+{
+ QPtrBucket *n = unlink_ptr( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_string( const QString &key )
+{
+ QStringBucket *n = unlink_string( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_ascii( const char *key )
+{
+ QAsciiBucket *n = unlink_ascii( key );
+ Item d;
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_int( long key )
+{
+ QIntBucket *n = unlink_int( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_ptr( void *key )
+{
+ QPtrBucket *n = unlink_ptr( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*!
+ \internal
+ Removes all items from the dictionary.
+*/
+
+void QGDict::clear()
+{
+ if ( !numItems )
+ return;
+ numItems = 0; // disable remove() function
+ for ( uint j=0; j<vlen; j++ ) { // destroy hash table
+ if ( vec[j] ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QStringBucket *n=(QStringBucket *)vec[j];
+ while ( n ) {
+ QStringBucket *next = (QStringBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ QAsciiBucket *n=(QAsciiBucket *)vec[j];
+ while ( n ) {
+ QAsciiBucket *next = (QAsciiBucket*)n->getNext();
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ QIntBucket *n=(QIntBucket *)vec[j];
+ while ( n ) {
+ QIntBucket *next = (QIntBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ QPtrBucket *n=(QPtrBucket *)vec[j];
+ while ( n ) {
+ QPtrBucket *next = (QPtrBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ }
+ vec[j] = 0; // detach list of buckets
+ }
+ }
+ if ( iterators && iterators->count() ) { // invalidate all iterators
+ QGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->curNode = 0;
+ i = iterators->next();
+ }
+ }
+}
+
+
+/*!
+ \internal
+ Outputs debug statistics.
+*/
+
+void QGDict::statistics() const
+{
+#if defined(DEBUG)
+ QString line;
+ line.fill( '-', 60 );
+ double real, ideal;
+ qDebug( "%s",line.ascii() );
+ qDebug( "DICTIONARY STATISTICS:" );
+ if ( count() == 0 ) {
+ qDebug( "Empty!" );
+ qDebug( "%s", line.ascii() );
+ return;
+ }
+ real = 0.0;
+ ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1);
+ uint i = 0;
+ while ( i<size() ) {
+ QBaseBucket *n = vec[i];
+ int b = 0;
+ while ( n ) { // count number of buckets
+ b++;
+ n = n->getNext();
+ }
+ real = real + (double)b * ((double)b+1.0)/2.0;
+ char buf[80], *pbuf;
+ if ( b > 78 )
+ b = 78;
+ pbuf = buf;
+ while ( b-- )
+ *pbuf++ = '*';
+ *pbuf = '\0';
+ qDebug( "%s", buf );
+ i++;
+ }
+ qDebug( "Array size = %d", size() );
+ qDebug( "# items = %d", count() );
+ qDebug( "Real dist = %g", real );
+ qDebug( "Rand dist = %g", ideal );
+ qDebug( "Real/Rand = %g", real/ideal );
+ qDebug( "%s",line.ascii() );
+#endif // DEBUG
+}
+
+
+/*****************************************************************************
+ QGDict stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGDict &dict )
+{
+ return dict.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGDict &dict )
+{
+ return dict.write( s );
+}
+
+#if defined(_CC_DEC_) && defined(__alpha) && (__DECCXX_VER >= 50190001)
+#pragma message disable narrowptr
+#endif
+
+/*!
+ \internal
+ Reads a dictionary from the stream \e s.
+*/
+
+QDataStream &QGDict::read( QDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear dict
+ while ( num-- ) { // read all items
+ Item d;
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QString k;
+ s >> k;
+ read( s, d );
+ look_string( k, d, op_insert );
+ }
+ break;
+ case AsciiKey:
+ {
+ char *k;
+ s >> k;
+ read( s, d );
+ look_ascii( k, d, op_insert );
+ if ( copyk )
+ delete [] k;
+ }
+ break;
+ case IntKey:
+ {
+ Q_UINT32 k;
+ s >> k;
+ read( s, d );
+ look_int( k, d, op_insert );
+ }
+ break;
+ case PtrKey:
+ {
+ Q_UINT32 k;
+ s >> k;
+ read( s, d );
+ // ### cannot insert 0 - this renders the thing
+ // useless since all pointers are written as 0,
+ // but hey, serializing pointers? can it be done
+ // at all, ever?
+ if ( k )
+ look_ptr( (void *)(uintptr_t)k, d, op_insert );
+ }
+ break;
+ }
+ }
+ return s;
+}
+
+/*!
+ \internal
+ Writes the dictionary to the stream \e s.
+*/
+
+QDataStream& QGDict::write( QDataStream &s ) const
+{
+ s << count(); // write number of items
+ uint i = 0;
+ while ( i<size() ) {
+ QBaseBucket *n = vec[i];
+ while ( n ) { // write all buckets
+ switch ( keytype ) {
+ case StringKey:
+ s << ((QStringBucket*)n)->getKey();
+ break;
+ case AsciiKey:
+ s << ((QAsciiBucket*)n)->getKey();
+ break;
+ case IntKey:
+ s << (Q_UINT32)((QIntBucket*)n)->getKey();
+ break;
+ case PtrKey:
+ s << (Q_UINT32)0; // ### cannot serialize a pointer
+ break;
+ }
+ write( s, n->getData() ); // write data
+ n = n->getNext();
+ }
+ i++;
+ }
+ return s;
+}
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGDictIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class QGDictIterator qgdict.h
+ \brief An internal class for implementing QDictIterator and QIntDictIterator.
+
+ QGDictIterator is a strictly internal class that does the heavy work for
+ QDictIterator and QIntDictIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the dictionary \e d.
+*/
+
+QGDictIterator::QGDictIterator( const QGDict &d )
+{
+ dict = (QGDict *)&d; // get reference to dict
+ toFirst(); // set to first noe
+ if ( !dict->iterators ) {
+ dict->iterators = new QGDItList; // create iterator list
+ CHECK_PTR( dict->iterators );
+ }
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ \internal
+ Constructs a copy of the iterator \e it.
+*/
+
+QGDictIterator::QGDictIterator( const QGDictIterator &it )
+{
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ \internal
+ Assigns a copy of the iterator \e it and returns a reference to this
+ iterator.
+*/
+
+QGDictIterator &QGDictIterator::operator=( const QGDictIterator &it )
+{
+ if ( dict ) // detach from old dict
+ dict->iterators->removeRef( this );
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+QGDictIterator::~QGDictIterator()
+{
+ if ( dict ) // detach iterator from dict
+ dict->iterators->removeRef( this );
+}
+
+
+/*!
+ \internal
+ Sets the iterator to point to the first item in the dictionary.
+*/
+
+QCollection::Item QGDictIterator::toFirst()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::toFirst: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( dict->count() == 0 ) { // empty dictionary
+ curNode = 0;
+ return 0;
+ }
+ register uint i = 0;
+ register QBaseBucket **v = dict->vec;
+ while ( !(*v++) )
+ i++;
+ curNode = dict->vec[i];
+ curIndex = i;
+ return curNode->getData();
+}
+
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+QCollection::Item QGDictIterator::operator()()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::operator(): Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ QCollection::Item d = curNode->getData();
+ this->operator++();
+ return d;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+QCollection::Item QGDictIterator::operator++()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::operator++: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ curNode = curNode->getNext();
+ if ( !curNode ) { // no next bucket
+ register uint i = curIndex + 1; // look from next vec element
+ register QBaseBucket **v = &dict->vec[i];
+ while ( i < dict->size() && !(*v++) )
+ i++;
+ if ( i == dict->size() ) { // nothing found
+ curNode = 0;
+ return 0;
+ }
+ curNode = dict->vec[i];
+ curIndex = i;
+ }
+ return curNode->getData();
+}
+
+/*!
+ \internal
+ Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGDictIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ operator++();
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/qtools/qgdict.h b/qtools/qgdict.h
new file mode 100644
index 0000000..a5c8aa0
--- /dev/null
+++ b/qtools/qgdict.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+**
+** Definition of QGDict and QGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGDICT_H
+#define QGDICT_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#include "qstring.h"
+#endif // QT_H
+
+class QGDictIterator;
+class QGDItList;
+
+
+class QBaseBucket // internal dict node
+{
+public:
+ QCollection::Item getData() { return data; }
+ QCollection::Item setData( QCollection::Item d ) { return data = d; }
+ QBaseBucket *getNext() { return next; }
+ void setNext( QBaseBucket *n) { next = n; }
+protected:
+ QBaseBucket( QCollection::Item d, QBaseBucket *n ) : data(d), next(n) {}
+ QCollection::Item data;
+ QBaseBucket *next;
+};
+
+class QStringBucket : public QBaseBucket
+{
+public:
+ QStringBucket( const QString &k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ const QString &getKey() const { return key; }
+private:
+ QString key;
+};
+
+class QAsciiBucket : public QBaseBucket
+{
+public:
+ QAsciiBucket( const char *k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ const char *getKey() const { return key; }
+private:
+ const char *key;
+};
+
+class QIntBucket : public QBaseBucket
+{
+public:
+ QIntBucket( intptr_t k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ intptr_t getKey() const { return key; }
+private:
+ intptr_t key;
+};
+
+class QPtrBucket : public QBaseBucket
+{
+public:
+ QPtrBucket( void *k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ void *getKey() const { return key; }
+private:
+ void *key;
+};
+
+
+class Q_EXPORT QGDict : public QCollection // generic dictionary class
+{
+public:
+ uint count() const { return numItems; }
+ uint size() const { return vlen; }
+ QCollection::Item look_string( const QString& key, QCollection::Item,
+ int );
+ QCollection::Item look_ascii( const char *key, QCollection::Item, int );
+ QCollection::Item look_int( long key, QCollection::Item, int );
+ QCollection::Item look_ptr( void *key, QCollection::Item, int );
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & );
+ QDataStream &write( QDataStream & ) const;
+#endif
+protected:
+ enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+
+ QGDict( uint len, KeyType kt, bool cs, bool ck );
+ QGDict( const QGDict & );
+ ~QGDict();
+
+ QGDict &operator=( const QGDict & );
+
+ bool remove_string( const QString &key, QCollection::Item item=0 );
+ bool remove_ascii( const char *key, QCollection::Item item=0 );
+ bool remove_int( long key, QCollection::Item item=0 );
+ bool remove_ptr( void *key, QCollection::Item item=0 );
+ QCollection::Item take_string( const QString &key );
+ QCollection::Item take_ascii( const char *key );
+ QCollection::Item take_int( long key );
+ QCollection::Item take_ptr( void *key );
+
+ void clear();
+ void resize( uint );
+
+ int hashKeyString( const QString & );
+ int hashKeyAscii( const char * );
+
+ void statistics() const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, QCollection::Item & );
+ virtual QDataStream &write( QDataStream &, QCollection::Item ) const;
+#endif
+private:
+ QBaseBucket **vec;
+ uint vlen;
+ uint numItems;
+ uint keytype : 2;
+ uint cases : 1;
+ uint copyk : 1;
+ QGDItList *iterators;
+ void unlink_common( int, QBaseBucket *, QBaseBucket * );
+ QStringBucket *unlink_string( const QString &,
+ QCollection::Item item = 0 );
+ QAsciiBucket *unlink_ascii( const char *, QCollection::Item item = 0 );
+ QIntBucket *unlink_int( long, QCollection::Item item = 0 );
+ QPtrBucket *unlink_ptr( void *, QCollection::Item item = 0 );
+ void init( uint, KeyType, bool, bool );
+ friend class QGDictIterator;
+};
+
+
+class Q_EXPORT QGDictIterator // generic dictionary iterator
+{
+friend class QGDict;
+public:
+ QGDictIterator( const QGDict & );
+ QGDictIterator( const QGDictIterator & );
+ QGDictIterator &operator=( const QGDictIterator & );
+ ~QGDictIterator();
+
+ QCollection::Item toFirst();
+
+ QCollection::Item get() const;
+ QString getKeyString() const;
+ const char *getKeyAscii() const;
+ intptr_t getKeyInt() const;
+ void *getKeyPtr() const;
+
+ QCollection::Item operator()();
+ QCollection::Item operator++();
+ QCollection::Item operator+=(uint);
+
+protected:
+ QGDict *dict;
+
+private:
+ QBaseBucket *curNode;
+ uint curIndex;
+};
+
+inline QCollection::Item QGDictIterator::get() const
+{
+ return curNode ? curNode->getData() : 0;
+}
+
+inline QString QGDictIterator::getKeyString() const
+{
+ return curNode ? ((QStringBucket*)curNode)->getKey() : QString::null;
+}
+
+inline const char *QGDictIterator::getKeyAscii() const
+{
+ return curNode ? ((QAsciiBucket*)curNode)->getKey() : 0;
+}
+
+inline intptr_t QGDictIterator::getKeyInt() const
+{
+ return curNode ? ((QIntBucket*)curNode)->getKey() : 0;
+}
+
+inline void *QGDictIterator::getKeyPtr() const
+{
+ return curNode ? ((QPtrBucket*)curNode)->getKey() : 0;
+}
+
+
+#endif // QGDICT_H
diff --git a/qtools/qgeneric.h b/qtools/qgeneric.h
new file mode 100644
index 0000000..c2892a0
--- /dev/null
+++ b/qtools/qgeneric.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+**
+** Macros for pasting tokens; utilized by our generic classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGENERIC_H
+#define QGENERIC_H
+
+#error "do not include qgeneric.h any more"
+
+#endif // QGENERIC_H
diff --git a/qtools/qglist.cpp b/qtools/qglist.cpp
new file mode 100644
index 0000000..f464a73
--- /dev/null
+++ b/qtools/qglist.cpp
@@ -0,0 +1,1223 @@
+/****************************************************************************
+**
+**
+** Implementation of QGList and QGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglist.h"
+#include "qgvector.h"
+#include "qdatastream.h"
+
+
+// NOT REVISED
+/*!
+ \class QLNode qglist.h
+ \brief The QLNode class is an internal class for the QList template collection.
+
+ QLNode is a doubly linked list node; it has three pointers:
+ <ol>
+ <li> Pointer to the previous node.
+ <li> Pointer to the next node.
+ <li> Pointer to the actual data.
+ </ol>
+
+ Sometimes it might be practical to have direct access to the list nodes
+ in a QList, but it is seldom required.
+
+ \warning Be very careful if you want to access the list nodes. The heap
+ can easily get corrupted if you make a mistake.
+
+ \sa QList::currentNode(), QList::removeNode(), QList::takeNode()
+*/
+
+/*!
+ \fn QCollection::Item QLNode::getData()
+ Returns a pointer (\c void*) to the actual data in the list node.
+*/
+
+
+/*!
+ \class QGList qglist.h
+ \brief The QGList class is an internal class for implementing Qt collection classes.
+
+ QGList is a strictly internal class that acts as a base class for several
+ \link collection.html collection classes\endlink; QList, QQueue and
+ QStack.
+
+ QGList has some virtual functions that can be reimplemented to customize
+ the subclasses.
+ <ul>
+ <li> compareItems() compares two collection/list items.
+ <li> read() reads a collection/list item from a QDataStream.
+ <li> write() writes a collection/list item to a QDataStream.
+ </ul>
+ Normally, you do not have to reimplement any of these functions.
+ If you still want to reimplement them, see the QStrList class (qstrlist.h),
+ which is a good example.
+*/
+
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ This virtual function compares two list items.
+
+ Returns:
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> non-zero if \e item1 != \e item2
+ </ul>
+
+ This function returns \e int rather than \e bool so that
+ reimplementations can return three values and use it to sort by:
+
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> \> 0 (positive integer) if \e item1 \> \e item2
+ <li> \< 0 (negative integer) if \e item1 \< \e item2
+ </ul>
+
+ The QList::inSort() function requires that compareItems() is implemented
+ as described here.
+
+ This function should not modify the list because some const functions
+ call compareItems().
+
+ The default implementation compares the pointers:
+ \code
+
+ \endcode
+*/
+
+int QGList::compareItems( QCollection::Item item1, QCollection::Item item2 )
+{
+ return item1 != item2; // compare pointers
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ Reads a collection/list item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \a item to 0.
+
+ \sa write()
+*/
+
+QDataStream &QGList::read( QDataStream &s, QCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/list item to the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+QDataStream &QGList::write( QDataStream &s, QCollection::Item ) const
+{
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGList member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Constructs an empty list.
+*/
+
+QGList::QGList()
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+}
+
+/*!
+ \internal
+ Constructs a copy of \e list.
+*/
+
+QGList::QGList( const QGList & list )
+ : QCollection( list )
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+ QLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+}
+
+/*!
+ \internal
+ Removes all items from the list and destroys the list.
+*/
+
+QGList::~QGList()
+{
+ clear();
+ if ( !iterators ) // no iterators for this list
+ return;
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // notify all iterators that
+ i->list = 0; // this list is deleted
+ i->curNode = 0;
+ i = (QGListIterator*)iterators->next();
+ }
+ delete iterators;
+}
+
+
+/*!
+ \internal
+ Assigns \e list to this list.
+*/
+
+QGList& QGList::operator=( const QGList &list )
+{
+ clear();
+ if ( list.count() > 0 ) {
+ QLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ return *this;
+}
+
+/*!
+ Compares this list with \a list. Retruns TRUE if the lists
+ contain the same data, else FALSE.
+*/
+
+bool QGList::operator==( const QGList &list ) const
+{
+ if ( count() != list.count() )
+ return FALSE;
+
+ if ( count() == 0 )
+ return TRUE;
+
+ QLNode *n1 = firstNode;
+ QLNode *n2 = list.firstNode;
+ while ( n1 && n2 ) {
+ // should be mutable
+ if ( ( (QGList*)this )->compareItems( n1->data, n2->data ) != 0 )
+ return FALSE;
+ n1 = n1->next;
+ n2 = n2->next;
+ }
+
+ return TRUE;
+}
+
+/*!
+ \fn uint QGList::count() const
+ \internal
+ Returns the number of items in the list.
+*/
+
+
+/*!
+ \internal
+ Returns the node at position \e index. Sets this node to current.
+*/
+
+QLNode *QGList::locate( uint index )
+{
+ if ( index == (uint)curIndex ) // current node ?
+ return curNode;
+ if ( !curNode && firstNode ) { // set current node
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ register QLNode *node;
+ int distance = index - curIndex; // node distance to cur node
+ bool forward; // direction to traverse
+
+ if ( index >= numNodes ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGList::locate: Index %d out of range", index );
+#endif
+ return 0;
+ }
+
+ if ( distance < 0 )
+ distance = -distance;
+ if ( (uint)distance < index && (uint)distance < numNodes - index ) {
+ node = curNode; // start from current node
+ forward = index > (uint)curIndex;
+ } else if ( index < numNodes - index ) { // start from first node
+ node = firstNode;
+ distance = index;
+ forward = TRUE;
+ } else { // start from last node
+ node = lastNode;
+ distance = numNodes - index - 1;
+ if ( distance < 0 )
+ distance = 0;
+ forward = FALSE;
+ }
+ if ( forward ) { // now run through nodes
+ while ( distance-- )
+ node = node->next;
+ } else {
+ while ( distance-- )
+ node = node->prev;
+ }
+ curIndex = index; // must update index
+ return curNode = node;
+}
+
+
+/*!
+ \internal
+ Inserts an item at its sorted position in the list.
+*/
+
+void QGList::inSort( QCollection::Item d )
+{
+ int index = 0;
+ register QLNode *n = firstNode;
+ while ( n && compareItems(n->data,d) < 0 ){ // find position in list
+ n = n->next;
+ index++;
+ }
+ insertAt( index, d );
+}
+
+
+/*!
+ \internal
+ Inserts an item at the start of the list.
+*/
+
+void QGList::prepend( QCollection::Item d )
+{
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ \internal
+ Inserts an item at the end of the list.
+*/
+
+void QGList::append( QCollection::Item d )
+{
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = curNode = n; // curNode affected
+ curIndex = numNodes;
+ numNodes++;
+}
+
+
+/*!
+ \internal
+ Inserts an item at position \e index in the list.
+*/
+
+bool QGList::insertAt( uint index, QCollection::Item d )
+{
+ if ( index == 0 ) { // insert at head of list
+ prepend( d );
+ return TRUE;
+ } else if ( index == numNodes ) { // append at tail of list
+ append( d );
+ return TRUE;
+ }
+ QLNode *nextNode = locate( index );
+ if ( !nextNode ) // illegal position
+ return FALSE;
+ QLNode *prevNode = nextNode->prev;
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ nextNode->prev = n;
+ prevNode->next = n;
+ n->prev = prevNode; // link new node into list
+ n->next = nextNode;
+ curNode = n; // curIndex set by locate()
+ numNodes++;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Relinks node \e n and makes it the first node in the list.
+*/
+
+void QGList::relinkNode( QLNode *n )
+{
+ if ( n == firstNode ) // already first
+ return;
+ curNode = n;
+ unlink();
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ \internal
+ Unlinks the current list node and returns a pointer to this node.
+*/
+
+QLNode *QGList::unlink()
+{
+ if ( curNode == 0 ) // null current node
+ return 0;
+ register QLNode *n = curNode; // unlink this node
+ if ( n == firstNode ) { // removing first node ?
+ if ( (firstNode = n->next) ) {
+ firstNode->prev = 0;
+ } else {
+ lastNode = curNode = 0; // list becomes empty
+ curIndex = -1;
+ }
+ } else {
+ if ( n == lastNode ) { // removing last node ?
+ lastNode = n->prev;
+ lastNode->next = 0;
+ } else { // neither last nor first node
+ n->prev->next = n->next;
+ n->next->prev = n->prev;
+ }
+ }
+ if ( n->next ) { // change current node
+ curNode = n->next;
+ } else if ( n->prev ) {
+ curNode = n->prev;
+ curIndex--;
+ }
+ if ( iterators && iterators->count() ) { // update iterators
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // fix all iterators that
+ if ( i->curNode == n ) // refers to pending node
+ i->curNode = curNode;
+ i = (QGListIterator*)iterators->next();
+ }
+ }
+ numNodes--;
+ return n;
+}
+
+
+/*!
+ \internal
+ Removes the node \e n from the list.
+*/
+
+bool QGList::removeNode( QLNode *n )
+{
+#if defined(CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "QGList::removeNode: Corrupted node" );
+ return FALSE;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Removes the item \e d from the list. Uses compareItems() to find the item.
+*/
+
+bool QGList::remove( QCollection::Item d )
+{
+ if ( d ) { // find the item
+ if ( find(d) == -1 )
+ return FALSE;
+ }
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Removes the item \e d from the list.
+*/
+
+bool QGList::removeRef( QCollection::Item d )
+{
+ if ( d ) { // find the item
+ if ( findRef(d) == -1 )
+ return FALSE;
+ }
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+/*!
+ \fn bool QGList::removeFirst()
+ \internal
+ Removes the first item in the list.
+*/
+
+/*!
+ \fn bool QGList::removeLast()
+ \internal
+ Removes the last item in the list.
+*/
+
+/*!
+ \internal
+ Removes the item at position \e index from the list.
+*/
+
+bool QGList::removeAt( uint index )
+{
+ if ( !locate(index) )
+ return FALSE;
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Takes the node \e n out of the list.
+*/
+
+QCollection::Item QGList::takeNode( QLNode *n )
+{
+#if defined(CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "QGList::takeNode: Corrupted node" );
+ return 0;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ Item d = n->data;
+ delete n; // delete the node, not data
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return d;
+}
+
+/*!
+ \internal
+ Takes the current item out of the list.
+*/
+
+QCollection::Item QGList::take()
+{
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ \internal
+ Takes the item at position \e index out of the list.
+*/
+
+QCollection::Item QGList::takeAt( uint index )
+{
+ if ( !locate(index) )
+ return 0;
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ \internal
+ Takes the first item out of the list.
+*/
+
+QCollection::Item QGList::takeFirst()
+{
+ first();
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+/*!
+ \internal
+ Takes the last item out of the list.
+*/
+
+QCollection::Item QGList::takeLast()
+{
+ last();
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+
+/*!
+ \internal
+ Removes all items from the list.
+*/
+
+void QGList::clear()
+{
+ register QLNode *n = firstNode;
+
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+
+ if ( iterators && iterators->count() ) {
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // notify all iterators that
+ i->curNode = 0; // this list is empty
+ i = (QGListIterator*)iterators->next();
+ }
+ }
+
+ QLNode *prevNode;
+ while ( n ) { // for all nodes ...
+ deleteItem( n->data ); // deallocate data
+ prevNode = n;
+ n = n->next;
+ delete prevNode; // deallocate node
+ }
+}
+
+
+/*!
+ \internal
+ Finds an item in the list.
+*/
+
+int QGList::findRef( QCollection::Item d, bool fromStart )
+{
+ register QLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && n->data != d ) { // find exact match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+/*!
+ \internal
+ Finds an item in the list. Uses compareItems().
+*/
+
+int QGList::find( QCollection::Item d, bool fromStart )
+{
+ register QLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && compareItems(n->data,d) ){ // find equal match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+
+/*!
+ \internal
+ Counts the number an item occurs in the list.
+*/
+
+uint QGList::containsRef( QCollection::Item d ) const
+{
+ register QLNode *n = firstNode;
+ uint count = 0;
+ while ( n ) { // for all nodes...
+ if ( n->data == d ) // count # exact matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+/*!
+ \internal
+ Counts the number an item occurs in the list. Uses compareItems().
+*/
+
+uint QGList::contains( QCollection::Item d ) const
+{
+ register QLNode *n = firstNode;
+ uint count = 0;
+ QGList *that = (QGList*)this; // mutable for compareItems()
+ while ( n ) { // for all nodes...
+ if ( !that->compareItems(n->data,d) ) // count # equal matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+
+/*!
+ \fn QCollection::Item QGList::at( uint index )
+ \internal
+ Sets the item at position \e index to the current item.
+*/
+
+/*!
+ \fn int QGList::at() const
+ \internal
+ Returns the current index.
+*/
+
+/*!
+ \fn QLNode *QGList::currentNode() const
+ \internal
+ Returns the current node.
+*/
+
+/*!
+ \fn QCollection::Item QGList::get() const
+ \internal
+ Returns the current item.
+*/
+
+/*!
+ \fn QCollection::Item QGList::cfirst() const
+ \internal
+ Returns the first item in the list.
+*/
+
+/*!
+ \fn QCollection::Item QGList::clast() const
+ \internal
+ Returns the last item in the list.
+*/
+
+
+/*!
+ \internal
+ Returns the first list item. Sets this to current.
+*/
+
+QCollection::Item QGList::first()
+{
+ if ( firstNode ) {
+ curIndex = 0;
+ return (curNode=firstNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the last list item. Sets this to current.
+*/
+
+QCollection::Item QGList::last()
+{
+ if ( lastNode ) {
+ curIndex = numNodes-1;
+ return (curNode=lastNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the next list item (after current). Sets this to current.
+*/
+
+QCollection::Item QGList::next()
+{
+ if ( curNode ) {
+ if ( curNode->next ) {
+ curIndex++;
+ curNode = curNode->next;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the previous list item (before current). Sets this to current.
+*/
+
+QCollection::Item QGList::prev()
+{
+ if ( curNode ) {
+ if ( curNode->prev ) {
+ curIndex--;
+ curNode = curNode->prev;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Converts the list to a vector.
+*/
+
+void QGList::toVector( QGVector *vector ) const
+{
+ vector->clear();
+ if ( !vector->resize( count() ) )
+ return;
+ register QLNode *n = firstNode;
+ uint i = 0;
+ while ( n ) {
+ vector->insert( i, n->data );
+ n = n->next;
+ i++;
+ }
+}
+
+void QGList::heapSortPushDown( QCollection::Item* heap, int first, int last )
+{
+ int r = first;
+ while( r <= last/2 ) {
+ // Node r has only one child ?
+ if ( last == 2*r ) {
+ // Need for swapping ?
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) {
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ }
+ // That's it ...
+ r = last;
+ } else {
+ // Node has two children
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 &&
+ compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) {
+ // Swap with left child
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ r *= 2;
+ } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 &&
+ compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) {
+ // Swap with right child
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r+1 ];
+ heap[ 2*r+1 ] = tmp;
+ r = 2*r+1;
+ } else {
+ // We are done
+ r = last;
+ }
+ }
+ }
+}
+
+
+/*! Sorts the list by the result of the virtual compareItems() function.
+
+ The Heap-Sort algorithm is used for sorting. It sorts n items with
+ O(n*log n) compares. This is the asymptotic optimal solution of the
+ sorting problem.
+*/
+
+void QGList::sort()
+{
+ uint n = count();
+ if ( n < 2 )
+ return;
+
+ // Create the heap
+ QCollection::Item* realheap = new QCollection::Item[ n ];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ QCollection::Item* heap = realheap - 1;
+ int size = 0;
+ QLNode* insert = firstNode;
+ for( ; insert != 0; insert = insert->next ) {
+ heap[++size] = insert->data;
+ int i = size;
+ while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) {
+ QCollection::Item tmp = heap[ i ];
+ heap[ i ] = heap[ i/2 ];
+ heap[ i/2 ] = tmp;
+ i /= 2;
+ }
+ }
+
+ insert = firstNode;
+ // Now do the sorting
+ for ( int i = n; i > 0; i-- ) {
+ insert->data = heap[1];
+ insert = insert->next;
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ heapSortPushDown( heap, 1, i - 1 );
+ }
+ }
+
+ delete [] realheap;
+}
+
+
+/*****************************************************************************
+ QGList stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGList &list )
+{ // read list
+ return list.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGList &list )
+{ // write list
+ return list.write( s );
+}
+
+/*!
+ \internal
+ Reads a list from the stream \e s.
+*/
+
+QDataStream &QGList::read( QDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear list
+ while ( num-- ) { // read all items
+ Item d;
+ read( s, d );
+ CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ QLNode *n = new QLNode( d );
+ CHECK_PTR( n );
+ if ( !n ) // no memory
+ break;
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = n;
+ numNodes++;
+ }
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return s;
+}
+
+/*!
+ \internal
+ Writes the list to the stream \e s.
+*/
+
+QDataStream &QGList::write( QDataStream &s ) const
+{
+ s << count(); // write number of items
+ QLNode *n = firstNode;
+ while ( n ) { // write all items
+ write( s, n->data );
+ n = n->next;
+ }
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGListIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class QGListIterator qglist.h
+ \brief The QGListIterator class is an internal class for implementing QListIterator.
+
+ QGListIterator is a strictly internal class that does the heavy work for
+ QListIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the list \e l.
+*/
+
+QGListIterator::QGListIterator( const QGList &l )
+{
+ list = (QGList *)&l; // get reference to list
+ curNode = list->firstNode; // set to first node
+ if ( !list->iterators ) {
+ list->iterators = new QGList; // create iterator list
+ CHECK_PTR( list->iterators );
+ }
+ list->iterators->append( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Constructs a copy of the iterator \e it.
+*/
+
+QGListIterator::QGListIterator( const QGListIterator &it )
+{
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->append( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Assigns a copy of the iterator \e it and returns a reference to this
+ iterator.
+*/
+
+QGListIterator &QGListIterator::operator=( const QGListIterator &it )
+{
+ if ( list ) // detach from old list
+ list->iterators->removeRef( this );
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->append( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+QGListIterator::~QGListIterator()
+{
+ if ( list ) // detach iterator from list
+ list->iterators->removeRef(this);
+}
+
+
+/*!
+ \fn bool QGListIterator::atFirst() const
+ \internal
+ Returns TRUE if the iterator points to the first item, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QGListIterator::atLast() const
+ \internal
+ Returns TRUE if the iterator points to the last item, otherwise FALSE.
+*/
+
+
+/*!
+ \internal
+ Sets the list iterator to point to the first item in the list.
+*/
+
+QCollection::Item QGListIterator::toFirst()
+{
+ if ( !list ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGListIterator::toFirst: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->firstNode ? (curNode = list->firstNode)->getData() : 0;
+}
+
+/*!
+ \internal
+ Sets the list iterator to point to the last item in the list.
+*/
+
+QCollection::Item QGListIterator::toLast()
+{
+ if ( !list ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGListIterator::toLast: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->lastNode ? (curNode = list->lastNode)->getData() : 0;
+}
+
+
+/*!
+ \fn QCollection::Item QGListIterator::get() const
+ \internal
+ Returns the iterator item.
+*/
+
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+QCollection::Item QGListIterator::operator()()
+{
+ if ( !curNode )
+ return 0;
+ QCollection::Item d = curNode->getData();
+ curNode = curNode->next;
+ return d;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+QCollection::Item QGListIterator::operator++()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGListIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves to the previous item (prefix).
+*/
+
+QCollection::Item QGListIterator::operator--()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions backward.
+*/
+
+QCollection::Item QGListIterator::operator-=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/qtools/qglist.h b/qtools/qglist.h
new file mode 100644
index 0000000..f400b64
--- /dev/null
+++ b/qtools/qglist.h
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+**
+** Definition of QGList and QGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGLIST_H
+#define QGLIST_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ QLNode class (internal doubly linked list node)
+ *****************************************************************************/
+
+class Q_EXPORT QLNode
+{
+friend class QGList;
+friend class QGListIterator;
+public:
+ QCollection::Item getData() { return data; }
+private:
+ QCollection::Item data;
+ QLNode *prev;
+ QLNode *next;
+ QLNode( QCollection::Item d ) { data = d; }
+};
+
+
+/*****************************************************************************
+ QGList class
+ *****************************************************************************/
+
+class Q_EXPORT QGList : public QCollection // doubly linked generic list
+{
+friend class QGListIterator;
+friend class QGVector; // needed by QGVector::toList
+public:
+ uint count() const; // return number of nodes
+
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & ); // read list from stream
+ QDataStream &write( QDataStream & ) const; // write list to stream
+#endif
+protected:
+ QGList(); // create empty list
+ QGList( const QGList & ); // make copy of other list
+ virtual ~QGList();
+
+ QGList &operator=( const QGList & ); // assign from other list
+ bool operator==( const QGList& ) const;
+
+ void inSort( QCollection::Item ); // add item sorted in list
+ void append( QCollection::Item ); // add item at end of list
+ bool insertAt( uint index, QCollection::Item ); // add item at i'th position
+ void relinkNode( QLNode * ); // relink as first item
+ bool removeNode( QLNode * ); // remove node
+ bool remove( QCollection::Item = 0 ); // remove item (0=current)
+ bool removeRef( QCollection::Item = 0 ); // remove item (0=current)
+ bool removeFirst(); // remove first item
+ bool removeLast(); // remove last item
+ bool removeAt( uint index ); // remove item at i'th position
+ QCollection::Item takeNode( QLNode * ); // take out node
+ QCollection::Item take(); // take out current item
+ QCollection::Item takeAt( uint index ); // take out item at i'th pos
+ QCollection::Item takeFirst(); // take out first item
+ QCollection::Item takeLast(); // take out last item
+
+ void sort(); // sort all items;
+ void clear(); // remove all items
+
+ int findRef( QCollection::Item, bool = TRUE ); // find exact item in list
+ int find( QCollection::Item, bool = TRUE ); // find equal item in list
+
+ uint containsRef( QCollection::Item ) const; // get number of exact matches
+ uint contains( QCollection::Item ) const; // get number of equal matches
+
+ QCollection::Item at( uint index ); // access item at i'th pos
+ int at() const; // get current index
+ QLNode *currentNode() const; // get current node
+
+ QCollection::Item get() const; // get current item
+
+ QCollection::Item cfirst() const; // get ptr to first list item
+ QCollection::Item clast() const; // get ptr to last list item
+ QCollection::Item first(); // set first item in list curr
+ QCollection::Item last(); // set last item in list curr
+ QCollection::Item next(); // set next item in list curr
+ QCollection::Item prev(); // set prev item in list curr
+
+ void toVector( QGVector * ) const; // put items in vector
+
+ virtual int compareItems( QCollection::Item, QCollection::Item );
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, QCollection::Item & );
+ virtual QDataStream &write( QDataStream &, QCollection::Item ) const;
+#endif
+private:
+ void prepend( QCollection::Item ); // add item at start of list
+
+ void heapSortPushDown( QCollection::Item* heap, int first, int last );
+
+ QLNode *firstNode; // first node
+ QLNode *lastNode; // last node
+ QLNode *curNode; // current node
+ int curIndex; // current index
+ uint numNodes; // number of nodes
+ QGList *iterators; // list of iterators
+
+ QLNode *locate( uint ); // get node at i'th pos
+ QLNode *unlink(); // unlink node
+};
+
+
+inline uint QGList::count() const
+{
+ return numNodes;
+}
+
+inline bool QGList::removeFirst()
+{
+ first();
+ return remove();
+}
+
+inline bool QGList::removeLast()
+{
+ last();
+ return remove();
+}
+
+inline int QGList::at() const
+{
+ return curIndex;
+}
+
+inline QCollection::Item QGList::at( uint index )
+{
+ QLNode *n = locate( index );
+ return n ? n->data : 0;
+}
+
+inline QLNode *QGList::currentNode() const
+{
+ return curNode;
+}
+
+inline QCollection::Item QGList::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+inline QCollection::Item QGList::cfirst() const
+{
+ return firstNode ? firstNode->data : 0;
+}
+
+inline QCollection::Item QGList::clast() const
+{
+ return lastNode ? lastNode->data : 0;
+}
+
+
+/*****************************************************************************
+ QGList stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream &, QGList & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QGList & );
+#endif
+
+/*****************************************************************************
+ QGListIterator class
+ *****************************************************************************/
+
+class Q_EXPORT QGListIterator // QGList iterator
+{
+friend class QGList;
+protected:
+ QGListIterator( const QGList & );
+ QGListIterator( const QGListIterator & );
+ QGListIterator &operator=( const QGListIterator & );
+ ~QGListIterator();
+
+ bool atFirst() const; // test if at first item
+ bool atLast() const; // test if at last item
+ QCollection::Item toFirst(); // move to first item
+ QCollection::Item toLast(); // move to last item
+
+ QCollection::Item get() const; // get current item
+ QCollection::Item operator()(); // get current and move to next
+ QCollection::Item operator++(); // move to next item (prefix)
+ QCollection::Item operator+=(uint); // move n positions forward
+ QCollection::Item operator--(); // move to prev item (prefix)
+ QCollection::Item operator-=(uint); // move n positions backward
+
+protected:
+ QGList *list; // reference to list
+
+private:
+ QLNode *curNode; // current node in list
+};
+
+
+inline bool QGListIterator::atFirst() const
+{
+ return curNode == list->firstNode;
+}
+
+inline bool QGListIterator::atLast() const
+{
+ return curNode == list->lastNode;
+}
+
+inline QCollection::Item QGListIterator::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+
+#endif // QGLIST_H
diff --git a/qtools/qglobal.cpp b/qtools/qglobal.cpp
new file mode 100644
index 0000000..50f5202
--- /dev/null
+++ b/qtools/qglobal.cpp
@@ -0,0 +1,685 @@
+/****************************************************************************
+**
+**
+** Global functions
+**
+** Created : 920604
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+#include "qasciidict.h"
+#include "qstring.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+// NOT REVISED
+
+/*!
+ \relates QApplication
+ Returns the Qt version number for the library, typically "1.30"
+ or "2.1.0".
+*/
+
+const char *qVersion()
+{
+ return QT_VERSION_STR;
+}
+
+
+/*****************************************************************************
+ System detection routines
+ *****************************************************************************/
+
+static bool si_alreadyDone = FALSE;
+static int si_wordSize;
+static bool si_bigEndian;
+
+/*!
+ \relates QApplication
+ Obtains information about the system.
+
+ The system's word size in bits (typically 32) is returned in \e *wordSize.
+ The \e *bigEndian is set to TRUE if this is a big-endian machine,
+ or to FALSE if this is a little-endian machine.
+
+ This function calls qFatal() with a message if the computer is truly weird
+ (i.e. different endianness for 16 bit and 32 bit integers).
+*/
+
+bool qSysInfo( int *wordSize, bool *bigEndian )
+{
+#if defined(CHECK_NULL)
+ ASSERT( wordSize != 0 );
+ ASSERT( bigEndian != 0 );
+#endif
+
+ if ( si_alreadyDone ) { // run it only once
+ *wordSize = si_wordSize;
+ *bigEndian = si_bigEndian;
+ return TRUE;
+ }
+ si_alreadyDone = TRUE;
+
+ si_wordSize = 0;
+ uint n = (uint)(~0);
+ while ( n ) { // detect word size
+ si_wordSize++;
+ n /= 2;
+ }
+ *wordSize = si_wordSize;
+
+ if ( *wordSize != 64 &&
+ *wordSize != 32 &&
+ *wordSize != 16 ) { // word size: 16, 32 or 64
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system word size %d", *wordSize );
+#endif
+ return FALSE;
+ }
+ if ( sizeof(Q_INT8) != 1 || sizeof(Q_INT16) != 2 || sizeof(Q_INT32) != 4 ||
+ sizeof(float) != 4 || sizeof(double) != 8 ) {
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system data type size" );
+#endif
+ return FALSE;
+ }
+
+ bool be16, be32; // determine byte ordering
+ short ns = 0x1234;
+ int nl = 0x12345678;
+
+ unsigned char *p = (unsigned char *)(&ns); // 16-bit integer
+ be16 = *p == 0x12;
+
+ p = (unsigned char *)(&nl); // 32-bit integer
+ if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
+ be32 = TRUE;
+ else
+ if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
+ be32 = FALSE;
+ else
+ be32 = !be16;
+
+ if ( be16 != be32 ) { // strange machine!
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Inconsistent system byte order" );
+#endif
+ return FALSE;
+ }
+
+ *bigEndian = si_bigEndian = be32;
+ return TRUE;
+}
+
+
+/*****************************************************************************
+ Debug output routines
+ *****************************************************************************/
+
+/*!
+ \fn void qDebug( const char *msg, ... )
+
+ \relates QApplication
+ Prints a debug message, or calls the message handler (if it has been
+ installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ qDebug( "my window handle = %x", myWidget->id() );
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qWarning(), qFatal(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qWarning( const char *msg, ... )
+
+ \relates QApplication
+ Prints a warning message, or calls the message handler (if it has been
+ installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ void f( int c )
+ {
+ if ( c > 200 )
+ qWarning( "f: bad argument, c == %d", c );
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qDebug(), qFatal(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qFatal( const char *msg, ... )
+
+ \relates QApplication
+ Prints a fatal error message and exits, or calls the message handler (if it
+ has been installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ int divide( int a, int b )
+ {
+ if ( b == 0 ) // program error
+ qFatal( "divide: cannot divide by zero" );
+ return a/b;
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qDebug(), qWarning(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+
+static msg_handler handler = 0; // pointer to debug handler
+
+
+#ifdef _OS_MAC_
+
+static FILE * mac_debug=0;
+
+void qDebug( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ } else {
+ exit(0);
+ }
+}
+
+// copied... this looks really bad.
+void debug( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+void qWarning( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+// copied... this looks really bad.
+void warning( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+void qFatal( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+");
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+ exit(0);
+}
+
+// copied... this looks really bad.
+void fatal( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+ exit(0);
+}
+
+#else
+
+void qDebug( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap ); // ### vsnprintf would be great here
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+// copied... this looks really bad.
+void debug( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+void qWarning( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtWarningMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+
+// again, copied
+void warning( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtWarningMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+void qFatal( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtFatalMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+#if defined(_OS_UNIX_) && defined(DEBUG)
+ abort(); // trap; generates core dump
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+// yet again, copied
+void fatal( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtFatalMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+#if defined(_OS_UNIX_) && defined(DEBUG)
+ abort(); // trap; generates core dump
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+#endif
+
+
+/*!
+ \fn void ASSERT( bool test )
+ \relates QApplication
+ Prints a warning message containing the source code file name and line number
+ if \e test is FALSE.
+
+ This is really a macro defined in qglobal.h.
+
+ ASSERT is useful for testing required conditions in your program.
+
+ Example:
+ \code
+ //
+ // File: div.cpp
+ //
+
+ #include <qglobal.h>
+
+ int divide( int a, int b )
+ {
+ ASSERT( b != 0 ); // this is line 9
+ return a/b;
+ }
+ \endcode
+
+ If \c b is zero, the ASSERT statement will output the following message
+ using the qWarning() function:
+ \code
+ ASSERT: "b == 0" in div.cpp (9)
+ \endcode
+
+ \sa qWarning(), \link debug.html Debugging\endlink
+*/
+
+
+/*!
+ \fn void CHECK_PTR( void *p )
+ \relates QApplication
+ If \e p is null, a fatal messages says that the program ran out of memory
+ and exits. If \e p is not null, nothing happens.
+
+ This is really a macro defined in qglobal.h.
+
+ Example:
+ \code
+ int *a;
+ CHECK_PTR( a = new int[80] ); // never do this!
+ // do this instead:
+ a = new int[80];
+ CHECK_PTR( a ); // this is fine
+ \endcode
+
+ \sa qFatal(), \link debug.html Debugging\endlink
+*/
+
+
+//
+// The CHECK_PTR macro calls this function to check if an allocation went ok.
+//
+
+bool qt_check_pointer( bool c, const char *n, int l )
+{
+ if ( c )
+ qFatal( "In file %s, line %d: Out of memory", n, l );
+ return TRUE;
+}
+
+
+static bool firstObsoleteWarning(const char *obj, const char *oldfunc )
+{
+ static QAsciiDict<int> *obsoleteDict = 0;
+ if ( !obsoleteDict ) { // first time func is called
+ obsoleteDict = new QAsciiDict<int>;
+#if defined(DEBUG)
+ qDebug(
+ "You are using obsolete functions in the Qt library. Call the function\n"
+ "qSuppressObsoleteWarnings() to suppress obsolete warnings.\n"
+ );
+#endif
+ }
+ QCString s( obj );
+ s += "::";
+ s += oldfunc;
+ if ( obsoleteDict->find(s.data()) == 0 ) {
+ obsoleteDict->insert( s.data(), (int*)1 ); // anything different from 0
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool suppressObsolete = FALSE;
+
+void qSuppressObsoleteWarnings( bool suppress )
+{
+ suppressObsolete = suppress;
+}
+
+void qObsolete( const char *obj, const char *oldfunc, const char *newfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ if ( obj )
+ qDebug( "%s::%s: This function is obsolete, use %s instead.",
+ obj, oldfunc, newfunc );
+ else
+ qDebug( "%s: This function is obsolete, use %s instead.",
+ oldfunc, newfunc );
+}
+
+void qObsolete( const char *obj, const char *oldfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ if ( obj )
+ qDebug( "%s::%s: This function is obsolete.", obj, oldfunc );
+ else
+ qDebug( "%s: This function is obsolete.", oldfunc );
+}
+
+void qObsolete( const char *message )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning( "Qt", message) )
+ return;
+ qDebug( "%s", message );
+}
+
+
+/*!
+ \relates QApplication
+ Installs a Qt message handler. Returns a pointer to the message handler
+ previously defined.
+
+ The message handler is a function that prints out debug messages,
+ warnings and fatal error messages. The Qt library (debug version)
+ contains hundreds of warning messages that are printed when internal
+ errors (usually invalid function arguments) occur. If you implement
+ your own message handler, you get total control of these messages.
+
+ The default message handler prints the message to the standard output
+ under X11 or to the debugger under Windows. If it is a fatal message,
+ the application aborts immediately.
+
+ Only one message handler can be defined, since this is usually done on
+ an application-wide basis to control debug output.
+
+ To restore the message handler, call \c qInstallMsgHandler(0).
+
+ Example:
+ \code
+ #include <qapplication.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ void myMessageOutput( QtMsgType type, const char *msg )
+ {
+ switch ( type ) {
+ case QtDebugMsg:
+ fprintf( stderr, "Debug: %s\n", msg );
+ break;
+ case QtWarningMsg:
+ fprintf( stderr, "Warning: %s\n", msg );
+ break;
+ case QtFatalMsg:
+ fprintf( stderr, "Fatal: %s\n", msg );
+ abort(); // dump core on purpose
+ }
+ }
+
+ int main( int argc, char **argv )
+ {
+ qInstallMsgHandler( myMessageOutput );
+ QApplication a( argc, argv );
+ ...
+ return a.exec();
+ }
+ \endcode
+
+ \sa qDebug(), qWarning(), qFatal(), \link debug.html Debugging\endlink
+*/
+
+msg_handler qInstallMsgHandler( msg_handler h )
+{
+ msg_handler old = handler;
+ handler = h;
+ return old;
+}
+
+
+#ifdef _WS_WIN_
+bool qt_winunicode=FALSE;
+#endif
diff --git a/qtools/qglobal.h b/qtools/qglobal.h
new file mode 100644
index 0000000..024b40c
--- /dev/null
+++ b/qtools/qglobal.h
@@ -0,0 +1,650 @@
+/****************************************************************************
+**
+**
+** Global type declarations and definitions
+**
+** Created : 920529
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGLOBAL_H
+#define QGLOBAL_H
+
+
+#define QT_VERSION 223
+#define QT_VERSION_STR "2.2.3"
+
+
+//
+// The operating system, must be one of: (_OS_x_)
+//
+// MAC - Macintosh
+// MSDOS - MS-DOS and Windows
+// OS2 - OS/2
+// OS2EMX - XFree86 on OS/2 (not PM)
+// WIN32 - Win32 (Windows 95/98 and Windows NT)
+// SUN - SunOS
+// SOLARIS - Sun Solaris
+// HPUX - HP-UX
+// ULTRIX - DEC Ultrix
+// LINUX - Linux
+// FREEBSD - FreeBSD
+// NETBSD - NetBSD
+// OPENBSD - OpenBSD
+// IRIX - SGI Irix
+// OSF - OSF Unix
+// BSDI - BSDI Unix
+// SCO - SCO of some sort
+// AIX - AIX Unix
+// UNIXWARE - SCO UnixWare
+// GNU - GNU Hurd
+// DGUX - DG Unix
+// UNIX - Any UNIX bsd/sysv system
+//
+
+#if defined(__APPLE__) || defined(macintosh)
+#define _OS_MAC_
+# ifdef MAC_OS_X_VERSION_MIN_REQUIRED
+# undef MAC_OS_X_VERSION_MIN_REQUIRED
+# endif
+# define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_3
+# include <AvailabilityMacros.h>
+# if !defined(MAC_OS_X_VERSION_10_3)
+# define MAC_OS_X_VERSION_10_3 MAC_OS_X_VERSION_10_2 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_4)
+# define MAC_OS_X_VERSION_10_4 MAC_OS_X_VERSION_10_3 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_5)
+# define MAC_OS_X_VERSION_10_5 MAC_OS_X_VERSION_10_4 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_6)
+# define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_7)
+# define MAC_OS_X_VERSION_10_7 MAC_OS_X_VERSION_10_6 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_8)
+# define MAC_OS_X_VERSION_10_8 MAC_OS_X_VERSION_10_7 + 10
+# endif
+# if !defined(MAC_OS_X_VERSION_10_9)
+# define MAC_OS_X_VERSION_10_9 MAC_OS_X_VERSION_10_8 + 10
+# endif
+# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9)
+# warning "This version of Mac OS X is unsupported"
+# endif
+#elif defined(MSDOS) || defined(_MSDOS) || defined(__MSDOS__)
+#define _OS_MSDOS_
+#elif defined(OS2) || defined(_OS2) || defined(__OS2__)
+#if defined(__EMX__)
+#define _OS_OS2EMX_
+#else
+#define _OS_OS2_
+#endif
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+#define _OS_WIN32_
+#elif defined(__MWERKS__) && defined(__INTEL__)
+#define _OS_WIN32_
+#elif defined(sun) || defined(__sun) || defined(__sun__)
+#if defined(__SVR4)
+#define _OS_SOLARIS_
+#else
+#define _OS_SUN_
+#endif
+#elif defined(hpux) || defined(__hpux) || defined(__hpux__)
+#define _OS_HPUX_
+#elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__)
+#define _OS_ULTRIX_
+#elif defined(reliantunix)
+#define _OS_RELIANTUNIX_
+#elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
+#define _OS_LINUX_
+#elif defined(__FreeBSD__)
+#define _OS_FREEBSD_
+#elif defined(__NetBSD__)
+#define _OS_NETBSD_
+#elif defined(__OpenBSD__)
+#define _OS_OPENBSD_
+#elif defined(sgi) || defined(__sgi)
+#define _OS_IRIX_
+#elif defined(__osf__)
+#define _OS_OSF_
+#elif defined(bsdi) || defined(__bsdi__)
+#define _OS_BSDI_
+#elif defined(_AIX)
+#define _OS_AIX_
+#elif defined(__Lynx__)
+#define _OS_LYNXOS_
+#elif defined(_UNIXWARE)
+#define _OS_UNIXWARE_
+#elif defined(DGUX)
+#define _OS_DGUX_
+#elif defined(__QNX__)
+#define _OS_QNX_
+#elif defined(_SCO_DS) || defined(M_UNIX) || defined(M_XENIX)
+#define _OS_SCO_
+#elif defined(sco) || defined(_UNIXWARE7)
+#define _OS_UNIXWARE7_
+#elif !defined(_SCO_DS) && defined(__USLC__) && defined(__SCO_VERSION__)
+#define _OS_UNIXWARE7_
+#elif defined(__CYGWIN__)
+#define _OS_CYGWIN_
+#elif defined(__BEOS__)
+#define _OS_BEOS_
+#elif defined(__MINT__)
+#define _OS_MINT_
+#else
+#error "Qt has not been ported to this OS - talk to qt-bugs at trolltech.com"
+#endif
+
+#if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_OS2_) || defined(_OS_WIN32_)
+#undef _OS_UNIX_
+#elif !defined(_OS_UNIX_)
+#define _OS_UNIX_
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE) && !defined(UNIX)
+// ### remove 3.0
+#define UNIX
+#endif
+#endif
+
+
+//
+// The compiler, must be one of: (_CC_x_)
+//
+// SYM - Symantec C++ for both PC and Macintosh
+// MPW - MPW C++
+// MWERKS - Metrowerks CodeWarrior
+// MSVC - Microsoft Visual C/C++
+// BOR - Borland/Turbo C++
+// WAT - Watcom C++
+// GNU - GNU C++
+// COMEAU - Comeau C++
+// EDG - Edison Design Group C++
+// OC - CenterLine C++
+// SUN - Sun C++
+// DEC - DEC C++
+// HP - HPUX C++
+// USLC - SCO UnixWare7 C++
+// CDS - Reliant C++
+// KAI - KAI C++
+//
+
+
+// Should be sorted most-authorative to least-authorative
+
+#if defined(__SC__)
+#define _CC_SYM_
+#elif defined( __KCC )
+#define _CC_KAI_
+#define _CC_EDG_
+#define Q_HAS_BOOL_TYPE
+#elif defined(applec)
+#define _CC_MPW_
+#elif defined(__MWERKS__)
+#define _CC_MWERKS_
+#define Q_HAS_BOOL_TYPE
+#elif defined(_MSC_VER)
+#define _CC_MSVC_
+#elif defined(__BORLANDC__) || defined(__TURBOC__)
+#define _CC_BOR_
+#elif defined(__WATCOMC__)
+#define _CC_WAT_
+#define Q_HAS_BOOL_TYPE
+#elif defined(__GNUC__)
+#define _CC_GNU_
+#if __GNUC__ == 2 && __GNUC_MINOR__ <= 7
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#define Q_TEMPLATE_NEEDS_CLASS_DECLARATION
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#define Q_SPURIOUS_NON_VOID_WARNING
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 95
+#define Q_DELETING_VOID_UNDEFINED
+#endif
+#if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP)
+#define Q_PACKED __attribute__ ((packed))
+#endif
+#elif defined(__xlC__)
+#define _CC_XLC_
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#if __xlC__ >= 0x400
+#define Q_HAS_BOOL_TYPE
+#endif
+#if __xlC__ <= 0x0306
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#endif
+#elif defined(como40)
+#define _CC_EDG_
+#define _CC_COMEAU_
+#define Q_HAS_BOOL_TYPE
+#define Q_C_CALLBACKS
+#elif defined(__USLC__)
+#define _CC_USLC_
+#ifdef __EDG__ // UnixWare7
+#define Q_HAS_BOOL_TYPE
+#endif
+#elif defined(__DECCXX)
+#define _CC_DEC_
+#if __DECCXX_VER >= 60060005
+#define Q_HAS_BOOL_TYPE
+#endif
+#elif defined(__EDG) || defined(__EDG__)
+// one observed on SGI DCC, the other documented
+#define _CC_EDG_
+#elif defined(OBJECTCENTER) || defined(CENTERLINE_CLPP)
+#define _CC_OC_
+#if defined(_BOOL)
+#define Q_HAS_BOOL_TYPE
+#endif
+#elif defined(__SUNPRO_CC)
+#define _CC_SUN_
+#if __SUNPRO_CC >= 0x500
+#define Q_HAS_BOOL_TYPE
+#define Q_C_CALLBACKS
+#endif
+#elif defined(__CDS__)
+#define _CC_CDS_
+#define Q_HAS_BOOL_TYPE
+#elif defined(_OS_HPUX_)
+// this test is from aCC online help
+#if defined(__HP_aCC) || __cplusplus >= 199707L
+// this is the aCC
+#define _CC_HP_ACC_
+#define Q_HAS_BOOL_TYPE
+#else
+// this is the CC
+#define _CC_HP_
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#endif // __HP_aCC
+#else
+#error "Qt has not been tested with this compiler - talk to qt-bugs at trolltech.com"
+#endif
+
+// detect Microsoft compiler version
+#ifdef _CC_MSVC_
+#if _MSC_VER >= 1400
+#define _CC_V2005
+#elif _MSC_VER >= 1310
+#define _CC_V2003
+#elif _MSC_VER > 1300
+#define _CC_V2002
+#else
+#define _CC_V1998
+#endif
+#endif
+
+#ifndef Q_PACKED
+#define Q_PACKED
+#endif
+
+// Window system setting
+
+#if defined(_OS_MAC_)
+#define _WS_MAC_
+#elif defined(_OS_MSDOS_)
+#define _WS_WIN16_
+#error "Qt requires Win32 and does not work with Windows 3.x"
+#elif defined(_WIN32_X11_)
+#define _WS_X11_
+#elif defined(_OS_WIN32_)
+#define _WS_WIN32_
+#elif defined(_OS_OS2_)
+#error "Qt does not work with OS/2 Presentation Manager or Workplace Shell"
+#elif defined(_OS_UNIX_)
+#ifdef QWS
+#define _WS_QWS_
+#else
+#define _WS_X11_
+#endif
+#endif
+
+#if defined(_WS_WIN16_) || defined(_WS_WIN32_)
+#define _WS_WIN_
+#endif
+
+
+//
+// Some classes do not permit copies to be made of an object.
+// These classes contains a private copy constructor and operator=
+// to disable copying (the compiler gives an error message).
+// Undefine Q_DISABLE_COPY to turn off this checking.
+//
+
+#define Q_DISABLE_COPY
+
+
+//
+// Useful type definitions for Qt
+//
+
+#if defined(bool)
+#define Q_HAS_BOOL_TYPE
+#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)
+#define Q_HAS_BOOL_TYPE
+#elif _MSC_VER >= 1100 || __BORLANDC__ >= 0x500
+#define Q_HAS_BOOL_TYPE
+#elif defined(sgi) && defined(_BOOL)
+#define Q_HAS_BOOL_TYPE
+#endif
+
+#if (QT_VERSION >= 300)
+#error "Use an enum for bool"
+#endif
+
+#if !defined(Q_HAS_BOOL_TYPE)
+#if defined(_CC_MSVC_)
+#define _CC_BOOL_DEF_
+#define bool int
+#else
+typedef int bool;
+#endif
+#endif
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned uint;
+typedef unsigned long ulong;
+typedef char *pchar;
+typedef uchar *puchar;
+typedef const char *pcchar;
+#if defined(_OS_WIN32_) && !defined(_CC_GNU_)
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
+
+
+//
+// Constant bool values
+//
+
+#ifndef TRUE
+const bool FALSE = 0;
+const bool TRUE = !0;
+#endif
+
+
+#if defined(_CC_MSVC_)
+// Workaround for static const members.
+#define QT_STATIC_CONST static
+#define QT_STATIC_CONST_IMPL
+#else
+#define QT_STATIC_CONST static const
+#define QT_STATIC_CONST_IMPL const
+#endif
+
+
+
+//
+// Utility macros and inline functions
+//
+
+#define QMAX(a,b) ((a) > (b) ? (a) : (b))
+#define QMIN(a,b) ((a) < (b) ? (a) : (b))
+#define QABS(a) ((a) >= 0 ? (a) : -(a))
+
+inline int qRound( double d )
+{
+ return d > 0.0 ? int(d+0.5) : int(d-0.5);
+}
+
+
+//
+// Size-dependent types (architechture-dependent byte order)
+//
+
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE)
+typedef signed char INT8; // 8 bit signed
+typedef unsigned char UINT8; // 8 bit unsigned
+typedef short INT16; // 16 bit signed
+typedef unsigned short UINT16; // 16 bit unsigned
+typedef int INT32; // 32 bit signed
+typedef unsigned int UINT32; // 32 bit unsigned
+#endif
+
+typedef signed char Q_INT8; // 8 bit signed
+typedef unsigned char Q_UINT8; // 8 bit unsigned
+typedef short Q_INT16; // 16 bit signed
+typedef unsigned short Q_UINT16; // 16 bit unsigned
+typedef int Q_INT32; // 32 bit signed
+typedef unsigned int Q_UINT32; // 32 bit unsigned
+typedef long Q_INT64; // up to 64 bit signed
+typedef unsigned long Q_UINT64; // up to 64 bit unsigned
+
+//
+// Data stream functions is provided by many classes (defined in qdatastream.h)
+//
+
+class QDataStream;
+
+
+
+#ifdef _WS_WIN_
+extern bool qt_winunicode;
+#endif
+
+#ifndef QT_H
+#include <qfeatures.h>
+#endif // QT_H
+
+//
+// Create Qt DLL if QT_DLL is defined (Windows only)
+//
+
+#if defined(_OS_WIN32_)
+#if defined(QT_NODLL)
+#undef QT_MAKEDLL
+#undef QT_DLL
+#endif
+#ifdef QT_DLL
+#if defined(QT_MAKEDLL) /* create a Qt DLL library */
+#undef QT_DLL
+#define Q_EXPORT __declspec(dllexport)
+#define Q_TEMPLATEDLL
+#undef Q_DISABLE_COPY /* avoid unresolved externals */
+#endif
+#endif
+#if defined(QT_DLL) /* use a Qt DLL library */
+#define Q_EXPORT __declspec(dllimport)
+#define Q_TEMPLATEDLL
+#undef Q_DISABLE_COPY /* avoid unresolved externals */
+#endif
+#else // ! _OS_WIN32_
+#undef QT_MAKEDLL /* ignore these for other platforms */
+#undef QT_DLL
+#endif
+
+#ifndef Q_EXPORT
+#define Q_EXPORT
+#endif
+
+//
+// System information
+//
+
+Q_EXPORT const char *qVersion();
+Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
+
+
+//
+// Debugging and error handling
+//
+
+#if !defined(NO_CHECK)
+#define CHECK_STATE // check state of objects etc.
+#define CHECK_RANGE // check range of indexes etc.
+#define CHECK_NULL // check null pointers
+#define CHECK_MATH // check math functions
+#endif
+
+#if !defined(NO_DEBUG) && !defined(DEBUG)
+#define DEBUG // display debug messages
+#endif
+
+//
+// Avoid some particularly useless warnings from some stupid compilers.
+// To get ALL C++ compiler warnings, define CC_WARNINGS or comment out
+// the line "#define Q_NO_WARNINGS"
+//
+
+#if !defined(CC_WARNINGS)
+#define Q_NO_WARNINGS
+#endif
+#if defined(Q_NO_WARNINGS)
+#if defined(_CC_MSVC_)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4275)
+#pragma warning(disable: 4514)
+#pragma warning(disable: 4800)
+#pragma warning(disable: 4097)
+#pragma warning(disable: 4706)
+#elif defined(_CC_BOR_)
+#pragma option -w-inl
+#pragma option -w-aus
+#pragma warn -inl
+#pragma warn -pia
+#pragma warn -ccc
+#pragma warn -rch
+#pragma warn -sig
+#elif defined(_CC_MWERKS_)
+#pragma warn_possunwant off
+#endif
+#endif // Q_NO_WARNINGS
+
+//
+// Avoid dead code
+//
+
+#if defined(_CC_EDG_) || defined(_CC_WAT_)
+#define Q_NO_DEAD_CODE
+#endif
+
+//
+// Use to avoid "unused parameter" warnings
+//
+
+#define Q_UNUSED(x) x=x;
+#define Q_CONST_UNUSED(x) (void)x;
+
+Q_EXPORT void qDebug( const char *, ... ) // print debug message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void qWarning( const char *, ... ) // print warning message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void qFatal( const char *, ... ) // print fatal message and exit
+#if defined(_CC_GNU_)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE)
+// in that case, also define the old ones...
+
+Q_EXPORT void debug( const char *, ... ) // print debug message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void warning( const char *, ... ) // print warning message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void fatal( const char *, ... ) // print fatal message and exit
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+// okay, that was debug()/warning()/fatal()
+#endif
+
+#if !defined(ASSERT)
+#if defined(CHECK_STATE)
+#if defined(QT_FATAL_ASSERT)
+#define ASSERT(x) if ( !(x) )\
+ qFatal("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)
+#else
+#define ASSERT(x) if ( !(x) )\
+ qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)
+#endif
+#else
+#define ASSERT(x)
+#endif
+#endif
+
+Q_EXPORT bool qt_check_pointer( bool c, const char *, int );
+
+#if defined(CHECK_NULL)
+#define CHECK_PTR(p) (qt_check_pointer((p)==0,__FILE__,__LINE__))
+#else
+#define CHECK_PTR(p)
+#endif
+
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtFatalMsg };
+
+typedef void (*msg_handler)(QtMsgType, const char *);
+Q_EXPORT msg_handler qInstallMsgHandler( msg_handler );
+
+
+Q_EXPORT void qSuppressObsoleteWarnings( bool = TRUE );
+
+#if !defined(QT_REJECT_OBSOLETE)
+#define QT_OBSOLETE
+Q_EXPORT void qObsolete( const char *obj, const char *oldfunc,
+ const char *newfunc );
+Q_EXPORT void qObsolete( const char *obj, const char *oldfunc );
+Q_EXPORT void qObsolete( const char *message );
+#endif
+
+// DvH: added to avoid warnings on recent gcc versions
+#define Q_DELETING_VOID_UNDEFINED
+
+#endif // QGLOBAL_H
diff --git a/qtools/qgstring.cpp b/qtools/qgstring.cpp
new file mode 100644
index 0000000..85dd879
--- /dev/null
+++ b/qtools/qgstring.cpp
@@ -0,0 +1,258 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include "qgstring.h"
+
+#include <assert.h>
+
+#define BLOCK_SIZE 64
+#define ROUND_SIZE(x) ((x)+BLOCK_SIZE-1)&~(BLOCK_SIZE-1)
+
+#define DBG_STR(x) do { } while(0)
+//#define DBG_STR(x) printf x
+
+QGString::QGString() // make null string
+ : m_data(0), m_len(0), m_memSize(0)
+{
+ DBG_STR(("%p: QGString::QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+}
+
+QGString::QGString(uint size)
+{
+ if (size==0)
+ {
+ m_data=0;
+ m_len=0;
+ }
+ else
+ {
+ m_memSize = ROUND_SIZE(size+1);
+ m_data = (char*)malloc(m_memSize);
+ memset(m_data,' ',size);
+ m_data[size]='\0';
+ m_len=size;
+ }
+ DBG_STR(("%p: QGString::QGString(uint size=%d) %d:%s\n",
+ this,size,m_len,m_data?m_data:"<none>"));
+}
+
+QGString::QGString( const QGString &s )
+{
+ if (s.m_memSize==0)
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_data = (char *)malloc(s.m_memSize);
+ m_len = s.m_len;
+ m_memSize = s.m_memSize;
+ qstrcpy(m_data,s.m_data);
+ }
+ DBG_STR(("%p: QGString::QGString(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+}
+
+QGString::QGString( const char *str )
+{
+ if (str==0)
+ {
+ m_data=0;
+ m_len=0;
+ m_memSize=0;
+ }
+ else
+ {
+ m_len = qstrlen(str);
+ m_memSize = ROUND_SIZE(m_len+1);
+ assert(m_memSize>=m_len+1);
+ m_data = (char *)malloc(m_memSize);
+ qstrcpy(m_data,str);
+ }
+ DBG_STR(("%p: QGString::QGString(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+}
+
+QGString::~QGString()
+{
+ free(m_data);
+ m_data=0;
+ DBG_STR(("%p: QGString::~QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+}
+
+bool QGString::resize( uint newlen )
+{
+ m_len = 0;
+ if (newlen==0)
+ {
+ if (m_data) { free(m_data); m_data=0; }
+ m_memSize=0;
+ DBG_STR(("%p: 1.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return TRUE;
+ }
+ m_memSize = ROUND_SIZE(newlen+1);
+ assert(m_memSize>=newlen+1);
+ if (m_data==0)
+ {
+ m_data = (char *)malloc(m_memSize);
+ }
+ else
+ {
+ m_data = (char *)realloc(m_data,m_memSize);
+ }
+ if (m_data==0)
+ {
+ DBG_STR(("%p: 2.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return FALSE;
+ }
+ m_data[newlen]='\0';
+ m_len = qstrlen(m_data);
+ DBG_STR(("%p: 3.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return TRUE;
+}
+
+bool QGString::enlarge( uint newlen )
+{
+ if (newlen==0)
+ {
+ if (m_data) { free(m_data); m_data=0; }
+ m_memSize=0;
+ m_len=0;
+ return TRUE;
+ }
+ uint newMemSize = ROUND_SIZE(newlen+1);
+ if (newMemSize==m_memSize) return TRUE;
+ m_memSize = newMemSize;
+ if (m_data==0)
+ {
+ m_data = (char *)malloc(m_memSize);
+ }
+ else
+ {
+ m_data = (char *)realloc(m_data,m_memSize);
+ }
+ if (m_data==0)
+ {
+ return FALSE;
+ }
+ m_data[newlen-1]='\0';
+ if (m_len>newlen) m_len=newlen;
+ return TRUE;
+}
+
+void QGString::setLen( uint newlen )
+{
+ m_len = newlen<=m_memSize ? newlen : m_memSize;
+}
+
+QGString &QGString::operator=( const QGString &s )
+{
+ if (m_data) free(m_data);
+ if (s.m_memSize==0) // null string
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_len = s.m_len;
+ m_memSize = s.m_memSize;
+ m_data = (char*)malloc(m_memSize);
+ qstrcpy(m_data,s.m_data);
+ }
+ DBG_STR(("%p: QGString::operator=(const QGString &%p) %d:%s\n",
+ this,&s,m_len,m_data?m_data:"<none>"));
+ return *this;
+}
+
+QGString &QGString::operator=( const char *str )
+{
+ if (m_data) free(m_data);
+ if (str==0) // null string
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_len = qstrlen(str);
+ m_memSize = ROUND_SIZE(m_len+1);
+ assert(m_memSize>=m_len+1);
+ m_data = (char*)malloc(m_memSize);
+ qstrcpy(m_data,str);
+ }
+ DBG_STR(("%p: QGString::operator=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return *this;
+}
+
+QGString &QGString::operator+=( const QGString &s )
+{
+ if (s.m_memSize==0) return *this;
+ uint len1 = length();
+ uint len2 = s.length();
+ uint memSize = ROUND_SIZE(len1 + len2 + 1);
+ assert(memSize>=len1+len2+1);
+ char *newData = memSize!=m_memSize ? (char*)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (m_data)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, s, len2 + 1 );
+ }
+ m_len = len1+len2;
+ DBG_STR(("%p: QGString::operator+=(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return *this;
+}
+
+QGString &QGString::operator+=( const char *str )
+{
+ if (!str) return *this;
+ uint len1 = length();
+ uint len2 = qstrlen(str);
+ uint memSize = ROUND_SIZE(len1 + len2 + 1);
+ assert(memSize>=len1+len2+1);
+ char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (newData)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, str, len2 + 1 );
+ }
+ m_len+=len2;
+ DBG_STR(("%p: QGString::operator+=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return *this;
+}
+
+QGString &QGString::operator+=( char c )
+{
+ uint len = m_len;
+ uint memSize = ROUND_SIZE(len+2);
+ assert(memSize>=len+2);
+ char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (newData)
+ {
+ m_data = newData;
+ m_data[len] = c;
+ m_data[len+1] = '\0';
+ }
+ m_len++;
+ DBG_STR(("%p: QGString::operator+=(char s) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+ return *this;
+}
+
diff --git a/qtools/qgstring.h b/qtools/qgstring.h
new file mode 100644
index 0000000..6934c93
--- /dev/null
+++ b/qtools/qgstring.h
@@ -0,0 +1,139 @@
+#ifndef QGSTRING_H
+#define QGSTRING_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_OS_SUN_) && defined(_CC_GNU_)
+#include <strings.h>
+#endif
+
+#include "qcstring.h"
+
+/*****************************************************************************
+ Fixes and workarounds for some platforms
+ *****************************************************************************/
+
+/** This is an alternative implementation of QCString.
+ */
+class QGString
+{
+ public:
+ QGString(); // make null string
+ QGString(uint size);
+ QGString( const QGString &s );
+ QGString( const char *str );
+ ~QGString() ;
+
+ bool resize( uint newlen );
+ bool enlarge( uint newlen );
+ void setLen( uint newlen );
+
+ QGString &operator=( const QGString &s );
+ QGString &operator=( const char *str );
+ QGString &operator+=( const QGString &s );
+ QGString &operator+=( const char *str );
+ QGString &operator+=( char c );
+
+ bool isNull() const { return m_data==0; }
+ bool isEmpty() const { return m_len==0; }
+ uint length() const { return m_len; }
+ uint size() const { return m_memSize; }
+ char * data() const { return m_data; }
+ bool truncate( uint pos ) { return resize(pos+1); }
+ operator const char *() const { return (const char *)data(); }
+ char &at( uint index ) const { return m_data[index]; }
+ char &operator[]( int i ) const { return at(i); }
+
+ private:
+ char * m_data;
+ uint m_len;
+ uint m_memSize;
+};
+
+/*****************************************************************************
+ QGString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT inline bool operator==( const QGString &s1, const QGString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) == 0; }
+
+Q_EXPORT inline bool operator==( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) == 0; }
+
+Q_EXPORT inline bool operator==( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) == 0; }
+
+Q_EXPORT inline bool operator!=( const QGString &s1, const QGString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) != 0; }
+
+Q_EXPORT inline bool operator!=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) != 0; }
+
+Q_EXPORT inline bool operator!=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) != 0; }
+
+Q_EXPORT inline bool operator<( const QGString &s1, const QGString& s2 )
+{ return qstrcmp(s1.data(),s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) < 0; }
+
+Q_EXPORT inline bool operator<( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) <= 0; }
+
+Q_EXPORT inline bool operator<=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) <= 0; }
+
+Q_EXPORT inline bool operator>( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) > 0; }
+
+Q_EXPORT inline bool operator>( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) > 0; }
+
+Q_EXPORT inline bool operator>=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) >= 0; }
+
+Q_EXPORT inline bool operator>=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) >= 0; }
+
+Q_EXPORT inline QGString operator+( const QGString &s1, const QGString &s2 )
+{
+ QGString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const QGString &s1, const char *s2 )
+{
+ QGString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const char *s1, const QGString &s2 )
+{
+ QGString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const QGString &s1, char c2 )
+{
+ QGString tmp( s1.data() );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( char c1, const QGString &s2 )
+{
+ QGString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#endif // QGSTRING_H
diff --git a/qtools/qgvector.cpp b/qtools/qgvector.cpp
new file mode 100644
index 0000000..88409ce
--- /dev/null
+++ b/qtools/qgvector.cpp
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+**
+** Implementation of QGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#define QGVECTOR_CPP
+#include "qgvector.h"
+#include "qglist.h"
+#include "qstring.h"
+#include "qdatastream.h"
+#include <stdlib.h>
+
+#define USE_MALLOC // comment to use new/delete
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+// NOT REVISED
+
+/*!
+ \class QGVector qgvector.h
+
+ \brief The QGVector class is an internal class for implementing Qt
+ collection classes.
+
+ QGVector is a strictly internal class that acts as a base class for
+ the QVector collection class.
+
+ QGVector has some virtual functions that may be reimplemented in
+ subclasses to to customize behavior.
+
+ <ul>
+ <li> compareItems() compares two collection/vector items.
+ <li> read() reads a collection/vector item from a QDataStream.
+ <li> write() writes a collection/vector item to a QDataStream.
+ </ul>
+*/
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ This virtual function compares two list items.
+
+ Returns:
+ <ul>
+ <li> 0 if \a item1 == \a item2
+ <li> non-zero if \a item1 != \a item2
+ </ul>
+
+ This function returns \e int rather than \e bool so that
+ reimplementations can return one of three values and use it to sort
+ by:
+
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> \> 0 (positive integer) if \a item1 \> \a item2
+ <li> \< 0 (negative integer) if \a item1 \< \a item2
+ </ul>
+
+ The QVector::sort() and QVector::bsearch() functions require that
+ compareItems() is implemented as described here.
+
+ This function should not modify the vector because some const
+ functions call compareItems().
+*/
+
+int QGVector::compareItems( Item d1, Item d2 )
+{
+ return d1 != d2; // compare pointers
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ Reads a collection/vector item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \e item to 0.
+
+ \sa write()
+*/
+
+QDataStream &QGVector::read( QDataStream &s, Item &d )
+{ // read item from stream
+ d = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/vector item to the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+QDataStream &QGVector::write( QDataStream &s, Item ) const
+{ // write item to stream
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGVector member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+*/
+
+QGVector::QGVector() // create empty vector
+{
+ vec = 0;
+ len = numItems = 0;
+}
+
+/*!
+ \internal
+*/
+QGVector::QGVector( uint size ) // create vectors with nullptrs
+{
+ len = size;
+ numItems = 0;
+ if ( len == 0 ) { // zero length
+ vec = 0;
+ return;
+ }
+ vec = NEW(Item,len);
+ CHECK_PTR( vec );
+ memset( (void*)vec, 0, len*sizeof(Item) ); // fill with nulls
+}
+
+/*!
+ \internal
+*/
+
+QGVector::QGVector( const QGVector &a ) // make copy of other vector
+ : QCollection( a )
+{
+ len = a.len;
+ numItems = a.numItems;
+ vec = NEW(Item,len);
+ CHECK_PTR( vec );
+ for ( uint i=0; i<len; i++ ) {
+ vec[i] = a.vec[i] ? newItem( a.vec[i] ) : 0;
+ CHECK_PTR( vec[i] );
+ }
+}
+
+/*!
+ \internal
+*/
+
+QGVector::~QGVector()
+{
+ clear();
+}
+
+
+/*!
+ \internal
+*/
+
+QGVector& QGVector::operator=( const QGVector &v )
+{ // assign from other vector
+ clear(); // first delete old vector
+ len = v.len;
+ numItems = v.numItems;
+ vec = NEW(Item,len); // create new vector
+ CHECK_PTR( vec );
+ for ( uint i=0; i<len; i++ ) { // copy elements
+ vec[i] = v.vec[i] ? newItem( v.vec[i] ) : 0;
+ CHECK_PTR( vec[i] );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn Item *QGVector::data() const
+ \internal
+*/
+
+/*!
+ \fn uint QGVector::size() const
+ \internal
+*/
+
+/*!
+ \fn uint QGVector::count() const
+ \internal
+*/
+
+/*!
+ \fn Item QGVector::at( uint index ) const
+ \internal
+*/
+
+/*!
+ \internal
+*/
+
+bool QGVector::insert( uint index, Item d ) // insert item at index
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::insert: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // remove old item
+ deleteItem( vec[index] );
+ numItems--;
+ }
+ if ( d ) {
+ vec[index] = newItem( d );
+ CHECK_PTR( vec[index] );
+ numItems++;
+ return vec[index] != 0;
+ } else {
+ vec[index] = 0; // reset item
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+
+bool QGVector::remove( uint index ) // remove item at index
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::remove: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // valid item
+ deleteItem( vec[index] ); // delete it
+ vec[index] = 0; // reset pointer
+ numItems--;
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+
+QCollection::Item QGVector::take( uint index ) // take out item
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::take: Index %d out of range", index );
+ return 0;
+ }
+#endif
+ Item d = vec[index]; // don't delete item
+ if ( d )
+ numItems--;
+ vec[index] = 0;
+ return d;
+}
+
+
+/*!
+ \internal
+*/
+
+void QGVector::clear() // clear vector
+{
+ if ( vec ) {
+ for ( uint i=0; i<len; i++ ) { // delete each item
+ if ( vec[i] )
+ deleteItem( vec[i] );
+ }
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ }
+}
+
+/*!
+ \internal
+*/
+
+bool QGVector::resize( uint newsize ) // resize array
+{
+ if ( newsize == len ) // nothing to do
+ return TRUE;
+ if ( vec ) { // existing data
+ if ( newsize < len ) { // shrink vector
+ uint i = newsize;
+ while ( i < len ) { // delete lost items
+ if ( vec[i] ) {
+ deleteItem( vec[i] );
+ numItems--;
+ }
+ i++;
+ }
+ }
+ if ( newsize == 0 ) { // vector becomes empty
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ return TRUE;
+ }
+#if defined(DONT_USE_REALLOC)
+ Item *newvec = NEW(Item,newsize); // manual realloc
+ memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
+ DELETE(vec);
+ vec = newvec;
+#else
+ vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
+#endif
+ } else { // create new vector
+ vec = NEW(Item,newsize);
+ len = numItems = 0;
+ }
+ CHECK_PTR( vec );
+ if ( !vec ) // no memory
+ return FALSE;
+ if ( newsize > len ) // init extra space added
+ memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
+ len = newsize;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+*/
+
+bool QGVector::fill( Item d, int flen ) // resize and fill vector
+{
+ if ( flen < 0 )
+ flen = len; // default: use vector length
+ else if ( !resize( flen ) )
+ return FALSE;
+ for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index
+ insert( i, d );
+ return TRUE;
+}
+
+
+static QGVector *sort_vec=0; // current sort vector
+
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int cmp_vec( const void *n1, const void *n2 )
+{
+ return sort_vec->compareItems( *((QCollection::Item*)n1), *((QCollection::Item*)n2) );
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+/*!
+ \internal
+*/
+
+void QGVector::sort() // sort vector
+{
+ if ( count() == 0 ) // no elements
+ return;
+ register Item *start = &vec[0];
+ register Item *end = &vec[len-1];
+ Item tmp;
+ while ( TRUE ) { // put all zero elements behind
+ while ( start < end && *start != 0 )
+ start++;
+ while ( end > start && *end == 0 )
+ end--;
+ if ( start < end ) {
+ tmp = *start;
+ *start = *end;
+ *end = tmp;
+ } else {
+ break;
+ }
+ }
+ sort_vec = (QGVector*)this;
+ qsort( vec, count(), sizeof(Item), cmp_vec );
+ sort_vec = 0;
+}
+
+/*!
+ \internal
+*/
+
+int QGVector::bsearch( Item d ) const // binary search; when sorted
+{
+ if ( !len )
+ return -1;
+ if ( !d ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGVector::bsearch: Cannot search for null object" );
+#endif
+ return -1;
+ }
+ int n1 = 0;
+ int n2 = len - 1;
+ int mid = 0;
+ bool found = FALSE;
+ while ( n1 <= n2 ) {
+ int res;
+ mid = (n1 + n2)/2;
+ if ( vec[mid] == 0 ) // null item greater
+ res = -1;
+ else
+ res = ((QGVector*)this)->compareItems( d, vec[mid] );
+ if ( res < 0 )
+ n2 = mid - 1;
+ else if ( res > 0 )
+ n1 = mid + 1;
+ else { // found it
+ found = TRUE;
+ break;
+ }
+ }
+ if ( !found )
+ return -1;
+ // search to first of equal items
+ while ( (mid - 1 >= 0) && !((QGVector*)this)->compareItems(d, vec[mid-1]) )
+ mid--;
+ return mid;
+}
+
+
+/*!
+ \internal
+*/
+
+int QGVector::findRef( Item d, uint index) const // find exact item in vector
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::findRef: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == d )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+*/
+
+int QGVector::find( Item d, uint index ) const // find equal item in vector
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::find: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // found null item
+ return i;
+ if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+*/
+
+uint QGVector::containsRef( Item d ) const // get number of exact matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == d )
+ count++;
+ }
+ return count;
+}
+
+/*!
+ \internal
+*/
+
+uint QGVector::contains( Item d ) const // get number of equal matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // count null items
+ count++;
+ if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
+ count++;
+ }
+ return count;
+}
+
+
+/*!
+ \internal
+*/
+
+bool QGVector::insertExpand( uint index, Item d )// insert and grow if necessary
+{
+ if ( index >= len ) {
+ if ( !resize( index+1 ) ) // no memory
+ return FALSE;
+ }
+ insert( index, d );
+ return TRUE;
+}
+
+
+/*!
+ \internal
+*/
+
+void QGVector::toList( QGList *list ) const // store items in list
+{
+ list->clear();
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] )
+ list->append( vec[i] );
+ }
+}
+
+
+void QGVector::warningIndexRange( uint i )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QGVector::operator[]: Index %d out of range", i );
+#else
+ Q_UNUSED( i )
+#endif
+}
+
+
+/*****************************************************************************
+ QGVector stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGVector &vec )
+{ // read vector
+ return vec.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGVector &vec )
+{ // write vector
+ return vec.write( s );
+}
+
+/*!
+ \internal
+*/
+
+QDataStream &QGVector::read( QDataStream &s ) // read vector from stream
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear vector
+ resize( num );
+ for (uint i=0; i<num; i++) { // read all items
+ Item d;
+ read( s, d );
+ CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ vec[i] = d;
+ }
+ return s;
+}
+
+/*!
+ \internal
+*/
+
+QDataStream &QGVector::write( QDataStream &s ) const
+{ // write vector to stream
+ uint num = count();
+ s << num; // number of items to write
+ num = size();
+ for (uint i=0; i<num; i++) { // write non-null items
+ if ( vec[i] )
+ write( s, vec[i] );
+ }
+ return s;
+}
+#endif // QT_NO_DATASTREAM
diff --git a/qtools/qgvector.h b/qtools/qgvector.h
new file mode 100644
index 0000000..6a7999d
--- /dev/null
+++ b/qtools/qgvector.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+**
+** Definition of QGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGVECTOR_H
+#define QGVECTOR_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#endif // QT_H
+
+
+class Q_EXPORT QGVector : public QCollection // generic vector
+{
+friend class QGList; // needed by QGList::toVector
+public:
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & ); // read vector from stream
+ QDataStream &write( QDataStream & ) const; // write vector to stream
+#endif
+ virtual int compareItems( Item, Item );
+
+protected:
+ QGVector(); // create empty vector
+ QGVector( uint size ); // create vector with nullptrs
+ QGVector( const QGVector &v ); // make copy of other vector
+ ~QGVector();
+
+ QGVector &operator=( const QGVector &v ); // assign from other vector
+
+ Item *data() const { return vec; }
+ uint size() const { return len; }
+ uint count() const { return numItems; }
+
+ bool insert( uint index, Item ); // insert item at index
+ bool remove( uint index ); // remove item
+ Item take( uint index ); // take out item
+
+ void clear(); // clear vector
+ bool resize( uint newsize ); // resize vector
+
+ bool fill( Item, int flen ); // resize and fill vector
+
+ void sort(); // sort vector
+ int bsearch( Item ) const; // binary search (when sorted)
+
+ int findRef( Item, uint index ) const; // find exact item in vector
+ int find( Item, uint index ) const; // find equal item in vector
+ uint containsRef( Item ) const; // get number of exact matches
+ uint contains( Item ) const; // get number of equal matches
+
+ Item at( uint index ) const // return indexed item
+ {
+#if defined(CHECK_RANGE)
+ if ( index >= len )
+ warningIndexRange( index );
+#endif
+ return vec[index];
+ }
+
+ bool insertExpand( uint index, Item ); // insert, expand if necessary
+
+ void toList( QGList * ) const; // put items in list
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, Item & );
+ virtual QDataStream &write( QDataStream &, Item ) const;
+#endif
+private:
+ Item *vec;
+ uint len;
+ uint numItems;
+
+ static void warningIndexRange( uint );
+};
+
+
+/*****************************************************************************
+ QGVector stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream &, QGVector & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QGVector & );
+#endif
+
+#endif // QGVECTOR_H
diff --git a/qtools/qintdict.doc b/qtools/qintdict.doc
new file mode 100644
index 0000000..e027fb2
--- /dev/null
+++ b/qtools/qintdict.doc
@@ -0,0 +1,475 @@
+/****************************************************************************
+**
+**
+** QIntDict and QIntDictIterator class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QIntDict documentation
+ *****************************************************************************/
+
+/*!
+ \class QIntDict qintdict.h
+ \brief The QIntDict class is a template class that provides a dictionary based on \c long keys.
+
+ \ingroup collection
+ \ingroup tools
+
+ QIntDict is implemented as a template class. Define a
+ template instance QIntDict\<X\> to create a dictionary that operates on
+ pointers to X, or X*.
+
+ A dictionary is a collection that associates an item with a key.
+ The key is used for inserting and looking up an item. QIntDict has
+ \c long keys.
+
+ The dictionary has very fast insertion and lookup.
+
+ Example:
+ \code
+ #include <qintdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ QIntDict<char> dict; // maps long ==> char*
+
+ dict.insert( 33, "France" );
+ dict.insert( 7, "Russia" );
+ dict.insert( 49, "Norway" );
+
+ printf( "%s\n", dict[49] );
+ printf( "%s\n", dict[33] );
+ printf( "%s\n", dict[7] );
+
+ if ( !dict[39] )
+ printf( "39 not defined\n" );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Norway
+ France
+ Russia
+ 39 not defined
+ \endcode
+
+ The dictionary in our example maps \c long keys to \c char* items.
+ QIntDict implements the \link operator[] [] operator\endlink to lookup
+ an item.
+
+ QIntDict is implemented by QGDict as a hash array with a fixed number of
+ entries. Each array entry points to a singly linked list of buckets, in
+ which the dictionary items are stored.
+
+ When an item is inserted with a key, the key is converted (hashed) to
+ an integer index into the hash array using the \c mod operation. The
+ item is inserted before the first bucket in the list of buckets.
+
+ Looking up an item is normally very fast. The key is again hashed to an
+ array index. Then QIntDict scans the list of buckets and returns the item
+ found or null if the item was not found. You cannot insert null pointers
+ into a dictionary.
+
+ The size of the hash array is very important. In order to get good
+ performance, you should use a suitably large \link primes.html prime
+ number\endlink. Suitable means equal to or larger than the maximum
+ expected number of dictionary items.
+
+ Items with equal keys are allowed. When inserting two items with the
+ same key, only the last inserted item will be visible (last in, first out)
+ until it is removed.
+
+ Example:
+ \code
+ #include <qintdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ QIntDict<char> dict; // maps long ==> char*
+
+ dict.insert( 7, "Russia" );
+ dict.insert( 7, "USSR" );
+
+ printf( "%s\n", dict[7] );
+ dict.remove( 7 ); // Gorbie was here
+ printf( "%s\n", dict[7] );
+ }
+ \endcode
+
+ Program output:
+ \code
+ USSR
+ Russia
+ \endcode
+
+ The QIntDictIterator class can traverse the dictionary contents, but only
+ in an arbitrary order. Multiple iterators may independently traverse the
+ same dictionary.
+
+ Calling setAutoDelete(TRUE) for a dictionary tells it to delete items
+ that are removed . The default is to not delete items when they are
+ removed.
+
+ When inserting an item into a dictionary, only the pointer is copied, not
+ the item itself. This is called a shallow copy. It is possible to make the
+ dictionary copy all of the item's data (known as a deep copy) when an
+ item is inserted. insert() calls the virtual function
+ QCollection::newItem() for the item to be inserted.
+ Inherit a dictionary and reimplement it if you want deep copies.
+
+ When removing a dictionary item, the virtual function
+ QCollection::deleteItem() is called. QIntDict's default implementation
+ is to delete the item if auto-deletion is enabled.
+
+ \sa QIntDictIterator, QDict, QAsciiDict, QPtrDict,
+ \link collection.html Collection Classes\endlink
+*/
+
+
+/*!
+ \fn QIntDict::QIntDict( int size )
+ Constructs a dictionary using an internal hash array with the size
+ \e size.
+
+ Setting \e size to a suitably large \link primes.html prime number\endlink
+ (equal to or greater than the expected number of entries) makes the hash
+ distribution better and hence the loopup faster.
+*/
+
+/*!
+ \fn QIntDict::QIntDict( const QIntDict<type> &dict )
+ Constructs a copy of \e dict.
+
+ Each item in \e dict are inserted into this dictionary.
+ Only the pointers are copied (shallow copy).
+*/
+
+/*!
+ \fn QIntDict::~QIntDict()
+ Removes all items from the dictionary and destroys it.
+
+ All iterators that access this dictionary will be reset.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn QIntDict<type> &QIntDict::operator=(const QIntDict<type> &dict)
+ Assigns \e dict to this dictionary and returns a reference to this
+ dictionary.
+
+ This dictionary is first cleared, then each item in \e dict is inserted
+ into this dictionary.
+ Only the pointers are copied (shallow copy), unless newItem() has been
+ reimplemented.
+*/
+
+/*!
+ \fn uint QIntDict::count() const
+ Returns the number of items in the dictionary.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn uint QIntDict::size() const
+ Returns the size of the internal hash array (as specified in the
+ constructor).
+ \sa count()
+*/
+
+/*!
+ \fn void QIntDict::resize( uint newsize )
+ Changes the size of the hashtable the \a newsize.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+
+/*!
+ \fn bool QIntDict::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn void QIntDict::insert( long key, const type *item )
+ Inserts the \e key with the \e item into the dictionary.
+
+ The key does not have to be a unique dictionary key. If multiple items
+ are inserted with the same key, only the last item will be visible.
+
+ Null items are not allowed.
+
+ \sa replace()
+*/
+
+/*!
+ \fn void QIntDict::replace( long key, const type *item )
+ Replaces an item which has a key equal to \e key with \e item.
+
+ If the item does not already exist, it will be inserted.
+
+ Null items are not allowed.
+
+ Equivalent to:
+ \code
+ QIntDict<char> dict;
+ ...
+ if ( dict.find(key) )
+ dict.remove( key );
+ dict.insert( key, item );
+ \endcode
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be replaced.
+
+ \sa insert()
+*/
+
+/*!
+ \fn bool QIntDict::remove( long key )
+ Removes the item associated with \e key from the dictionary.
+ Returns TRUE if successful, or FALSE if the key does not exist in the
+ dictionary.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be removed.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that refer to the removed item will be set to
+ point to the next item in the dictionary traversing order.
+
+ \sa take(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QIntDict::take( long key )
+ Takes the item associated with \e key out of the dictionary without
+ deleting it (even if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled).
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be taken.
+
+ Returns a pointer to the item taken out, or null if the key does not
+ exist in the dictionary.
+
+ All dictionary iterators that refer to the taken item will be set to
+ point to the next item in the dictionary traversing order.
+
+ \sa remove(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn void QIntDict::clear()
+ Removes all items from the dictionary.
+
+ The removed items are deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that access this dictionary will be reset.
+
+ \sa remove(), take(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QIntDict::find( long key ) const
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the [] operator.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn type *QIntDict::operator[]( long key ) const
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the find() function.
+
+ \sa find()
+*/
+
+/*!
+ \fn void QIntDict::statistics() const
+ Debugging-only function that prints out the dictionary distribution
+ using qDebug().
+*/
+
+
+/*****************************************************************************
+ QIntDictIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QIntDictIterator qintdict.h
+ \brief The QIntDictIterator class provides an iterator for QIntDict collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ QIntDictIterator is implemented as a template class.
+ Define a template instance QIntDictIterator\<X\> to create a
+ dictionary iterator that operates on QIntDict\<X\> (dictionary of X*).
+
+ Example:
+ \code
+ #include <qintdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ QIntDict<char> dict; // maps long ==> char*
+
+ dict.insert( 33, "France" );
+ dict.insert( 7, "Russia" );
+ dict.insert( 49, "Norway" );
+
+ QIntDictIterator<char> it( dict ); // iterator for dict
+
+ while ( it.current() ) {
+ printf( "%d -> %s\n", it.currentKey(), it.current() );
+ ++it;
+ }
+ }
+ \endcode
+
+ Program output:
+ \code
+ 7 -> Russia
+ 49 -> Norway
+ 33 -> France
+ \endcode
+
+ Note that the traversal order is arbitrary, you are not guaranteed the
+ order above.
+
+ Multiple iterators may independently traverse the same dictionary.
+ A QIntDict knows about all iterators that are operating on the dictionary.
+ When an item is removed from the dictionary, QIntDict update all
+ iterators that are referring the removed item to point to the next item
+ in the traversing order.
+
+ \sa QIntDict, \link collection.html Collection Classes\endlink
+*/
+
+/*!
+ \fn QIntDictIterator::QIntDictIterator( const QIntDict<type> &dict )
+ Constructs an iterator for \e dict. The current iterator item is
+ set to point on the first item in the \e dict.
+*/
+
+/*!
+ \fn QIntDictIterator::~QIntDictIterator()
+ Destroys the iterator.
+*/
+
+/*!
+ \fn uint QIntDictIterator::count() const
+ Returns the number of items in the dictionary this iterator operates on.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn bool QIntDictIterator::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn type *QIntDictIterator::toFirst()
+ Sets the current iterator item to point to the first item in the
+ dictionary and returns a pointer to the item.
+ If the dictionary is empty it sets the current item to null and
+ returns null.
+*/
+
+/*!
+ \fn QIntDictIterator::operator type *() const
+ Cast operator. Returns a pointer to the current iterator item.
+ Same as current().
+*/
+
+/*!
+ \fn type *QIntDictIterator::current() const
+ Returns a pointer to the current iterator item.
+*/
+
+/*!
+ \fn long QIntDictIterator::currentKey() const
+ Returns the key for the current iterator item.
+*/
+
+/*!
+ \fn type *QIntDictIterator::operator()()
+ Makes the succeeding item current and returns the original current item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QIntDictIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns the new current
+ item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QIntDictIterator::operator+=( uint jump )
+ Sets the current item to the item \e jump positions after the current item,
+ and returns a pointer to that item.
+
+ If that item is beyond the last item or if the dictionary is empty,
+ it sets the current item to null and returns null.
+*/
diff --git a/qtools/qintdict.h b/qtools/qintdict.h
new file mode 100644
index 0000000..ddc5fdf
--- /dev/null
+++ b/qtools/qintdict.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+**
+** Definition of QIntDict template class
+**
+** Created : 940624
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QINTDICT_H
+#define QINTDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QIntDict : public QGDict
+{
+public:
+ QIntDict(int size=17) : QGDict(size,IntKey,0,0) {}
+ QIntDict( const QIntDict<type> &d ) : QGDict(d) {}
+ ~QIntDict() { clear(); }
+ QIntDict<type> &operator=(const QIntDict<type> &d)
+ { return (QIntDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+ void insert( long k, const type *d )
+ { QGDict::look_int(k,(Item)d,1); }
+ void replace( long k, const type *d )
+ { QGDict::look_int(k,(Item)d,2); }
+ bool remove( long k ) { return QGDict::remove_int(k); }
+ type *take( long k ) { return (type*)QGDict::take_int(k); }
+ type *find( long k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
+ type *operator[]( long k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QIntDict<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QIntDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type> class Q_EXPORT QIntDictIterator : public QGDictIterator
+{
+public:
+ QIntDictIterator(const QIntDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QIntDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ long currentKey() const { return QGDictIterator::getKeyInt(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QINTDICT_H
diff --git a/qtools/qinternallist.h b/qtools/qinternallist.h
new file mode 100644
index 0000000..09dbfce
--- /dev/null
+++ b/qtools/qinternallist.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+**
+** Definition of QList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QINTERNALLIST_H
+#define QINTERNALLIST_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QInternalList : public QGList
+{
+public:
+ QInternalList() {}
+ QInternalList( const QInternalList<type> &l ) : QGList(l) {}
+ ~QInternalList() { clear(); }
+ QInternalList<type> &operator=(const QInternalList<type> &l)
+ { return (QInternalList<type>&)QGList::operator=(l); }
+ bool operator==( const QInternalList<type> &list ) const
+ { return QGList::operator==( list ); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ bool insert( uint i, const type *d){ return QGList::insertAt(i,(QCollection::Item)d); }
+ void inSort( const type *d ) { QGList::inSort((QCollection::Item)d); }
+ void prepend( const type *d ) { QGList::insertAt(0,(QCollection::Item)d); }
+ void append( const type *d ) { QGList::append((QCollection::Item)d); }
+ bool remove( uint i ) { return QGList::removeAt(i); }
+ bool remove() { return QGList::remove((QCollection::Item)0); }
+ bool remove( const type *d ) { return QGList::remove((QCollection::Item)d); }
+ bool removeRef( const type *d ) { return QGList::removeRef((QCollection::Item)d); }
+ void removeNode( QLNode *n ) { QGList::removeNode(n); }
+ bool removeFirst() { return QGList::removeFirst(); }
+ bool removeLast() { return QGList::removeLast(); }
+ type *take( uint i ) { return (type *)QGList::takeAt(i); }
+ type *take() { return (type *)QGList::take(); }
+ type *takeNode( QLNode *n ) { return (type *)QGList::takeNode(n); }
+ void clear() { QGList::clear(); }
+ void sort() { QGList::sort(); }
+ int find( const type *d ) { return QGList::find((QCollection::Item)d); }
+ int findNext( const type *d ) { return QGList::find((QCollection::Item)d,FALSE); }
+ int findRef( const type *d ) { return QGList::findRef((QCollection::Item)d); }
+ int findNextRef( const type *d ){ return QGList::findRef((QCollection::Item)d,FALSE);}
+ uint contains( const type *d ) const { return QGList::contains((QCollection::Item)d); }
+ uint containsRef( const type *d ) const
+ { return QGList::containsRef((QCollection::Item)d); }
+ type *at( uint i ) { return (type *)QGList::at(i); }
+ int at() const { return QGList::at(); }
+ type *current() const { return (type *)QGList::get(); }
+ QLNode *currentNode() const { return QGList::currentNode(); }
+ type *getFirst() const { return (type *)QGList::cfirst(); }
+ type *getLast() const { return (type *)QGList::clast(); }
+ type *first() { return (type *)QGList::first(); }
+ type *last() { return (type *)QGList::last(); }
+ type *next() { return (type *)QGList::next(); }
+ type *prev() { return (type *)QGList::prev(); }
+ void toVector( QGVector *vec )const{ QGList::toVector(vec); }
+private:
+ void deleteItem( QCollection::Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QInternalList<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QInternalList<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QInternalListIterator : public QGListIterator
+{
+public:
+ QInternalListIterator(const QInternalList<type> &l) :QGListIterator((QGList &)l) {}
+ ~QInternalListIterator() {}
+ uint count() const { return list->count(); }
+ bool isEmpty() const { return list->count() == 0; }
+ bool atFirst() const { return QGListIterator::atFirst(); }
+ bool atLast() const { return QGListIterator::atLast(); }
+ type *toFirst() { return (type *)QGListIterator::toFirst(); }
+ type *toLast() { return (type *)QGListIterator::toLast(); }
+ operator type *() const { return (type *)QGListIterator::get(); }
+ type *operator*() { return (type *)QGListIterator::get(); }
+
+ // No good, since QList<char> (ie. QStrList fails...
+ //
+ // MSVC++ gives warning
+ // Sunpro C++ 4.1 gives error
+ // type *operator->() { return (type *)QGListIterator::get(); }
+
+ type *current() const { return (type *)QGListIterator::get(); }
+ type *operator()() { return (type *)QGListIterator::operator()();}
+ type *operator++() { return (type *)QGListIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGListIterator::operator+=(j);}
+ type *operator--() { return (type *)QGListIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)QGListIterator::operator-=(j);}
+ QInternalListIterator<type>& operator=(const QInternalListIterator<type>&it)
+ { QGListIterator::operator=(it); return *this; }
+};
+
+
+#endif // QINTERNALLIST_H
diff --git a/qtools/qiodevice.cpp b/qtools/qiodevice.cpp
new file mode 100644
index 0000000..b52475c
--- /dev/null
+++ b/qtools/qiodevice.cpp
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+**
+** Implementation of QIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qiodevice.h"
+
+// NOT REVISED
+/*!
+ \class QIODevice qiodevice.h
+
+ \brief The QIODevice class is the base class of I/O devices.
+
+ \ingroup io
+
+ An I/O device represents a medium that one can read bytes from
+ and/or write bytes to. The QIODevice class is the abstract
+ superclass of all such devices; classes like QFile, QBuffer and
+ QSocket inherit QIODevice and implement virtual functions like
+ write() appropriately.
+
+ While applications sometimes use QIODevice directly, mostly it is
+ better to go through QTextStream and QDataStream, which provide
+ stream operations on any QIODevice subclass. QTextStream provides
+ text-oriented stream functionality (for human-readable ASCII files,
+ for example), while QDataStream deals with binary data in a totally
+ platform-independent manner.
+
+ The public member functions in QIODevice roughly fall into two
+ groups: The action functions and the state access functions. The
+ most important action functions are: <ul>
+
+ <li> open() opens a device for reading and/or writing, depending on
+ the argument to open().
+
+ <li> close() closes the device and tidies up.
+
+ <li> readBlock() reads a block of data from the device.
+
+ <li> writeBlock() writes a block of data to the device.
+
+ <li> readLine() reads a line (of text, usually) from the device.
+
+ <li> flush() ensures that all buffered data are written to the real device.
+
+ </ul>There are also some other, less used, action functions: <ul>
+
+ <li> getch() reads a single character.
+
+ <li> ungetch() forgets the last call to getch(), if possible.
+
+ <li> putch() writes a single character.
+
+ <li> size() returns the size of the device, if there is one.
+
+ <li> at() returns the current read/write pointer, if there is one
+ for this device, or it moves the pointer.
+
+ <li> atEnd() says whether there is more to read, if that is a
+ meaningful question for this device.
+
+ <li> reset() moves the read/write pointer to the start of the
+ device, if that is possible for this device.
+
+ </ul>The state access are all "get" functions. The QIODevice subclass
+ calls setState() to update the state, and simple access functions
+ tell the user of the device what the device's state is. Here are
+ the settings, and their associated access functions: <ul>
+
+ <li> Access type. Some devices are direct access (it is possible to
+ read/write anywhere) while others are sequential. QIODevice
+ provides the access functions isDirectAccess(), isSequentialAccess()
+ and isCombinedAccess() to tell users what a given I/O device
+ supports.
+
+ <li> Buffering. Some devices are accessed in raw mode while others
+ are buffered. Buffering usually provides greater efficiency,
+ particularly for small read/write operations. isBuffered() tells
+ the user whether a given device is buffered. (This can often be set
+ by the application in the call to open().)
+
+ <li> Synchronicity. Synchronous devices work there and then, for
+ example files. When you read from a file, the file delivers its
+ data right away. Others, such as a socket connected to a HTTP
+ server, may not deliver the data until seconds after you ask to read
+ it. isSynchronous() and isAsynchronous() tells the user how this
+ device operates.
+
+ <li> CR/LF translation. For simplicity, applications often like to
+ see just a single CR/LF style, and QIODevice subclasses can provide
+ that. isTranslated() returns TRUE if this object translates CR/LF
+ to just LF. (This can often be set by the application in the call
+ to open().)
+
+ <li> Accessibility. Some files cannot be written, for example.
+ isReadable(), isWritable and isReadWrite() tells the application
+ whether it can read from and write to a given device. (This can
+ often be set by the application in the call to open().)
+
+ <li> Finally, isOpen() returns TRUE if the device is open. This can
+ quite obviously be set using open() :)
+
+ </ul>
+
+ QIODevice provides numerous pure virtual functions you need to
+ implement when subclassing it. Here is a skeleton subclass with all
+ the members you are certain to need, and some it's likely that you
+ will need:
+
+ \code
+ class YourDevice : public QIODevice
+ {
+ public:
+ YourDevice();
+ ~YourDevice();
+
+ bool open( int mode );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const; // not a pure virtual function
+ bool at( int ); // not a pure virtual function
+ bool atEnd() const; // not a pure virtual function
+
+ int readBlock( char *data, uint maxlen );
+ int writeBlock( const char *data, uint len );
+ int readLine( char *data, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+ };
+ \endcode
+
+ The three non-pure virtual functions can be ignored if your device
+ is sequential (e.g. an RS-232 port).
+
+ \sa QDataStream, QTextStream
+*/
+
+
+/*!
+ Constructs an I/O device.
+*/
+
+QIODevice::QIODevice()
+{
+ ioMode = 0; // initial mode
+ ioSt = IO_Ok;
+ ioIndex = 0;
+}
+
+/*!
+ Destructs the I/O device.
+*/
+
+QIODevice::~QIODevice()
+{
+}
+
+
+/*!
+ \fn int QIODevice::flags() const
+ Returns the current I/O device flags setting.
+
+ Flags consists of mode flags and state flags.
+
+ \sa mode(), state()
+*/
+
+/*!
+ \fn int QIODevice::mode() const
+ Returns bits OR'ed together that specify the current operation mode.
+
+ These are the flags that were given to the open() function.
+
+ The flags are: \c IO_ReadOnly, \c IO_WriteOnly, \c IO_ReadWrite,
+ \c IO_Append, \c IO_Truncate and \c IO_Translate.
+*/
+
+/*!
+ \fn int QIODevice::state() const
+ Returns bits OR'ed together that specify the current state.
+
+ The flags are: \c IO_Open.
+
+ Subclasses may define more flags.
+*/
+
+/*!
+ \fn bool QIODevice::isDirectAccess() const
+ Returns TRUE if the I/O device is a direct access (not sequential) device,
+ otherwise FALSE.
+ \sa isSequentialAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isSequentialAccess() const
+ Returns TRUE if the I/O device is a sequential access (not direct) device,
+ otherwise FALSE. Operations involving size() and at(int) are not valid
+ on sequential devices.
+ \sa isDirectAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isCombinedAccess() const
+ Returns TRUE if the I/O device is a combined access (both direct and
+ sequential) device, otherwise FALSE.
+
+ This access method is currently not in use.
+*/
+
+/*!
+ \fn bool QIODevice::isBuffered() const
+ Returns TRUE if the I/O device is a buffered (not raw) device, otherwise
+ FALSE.
+ \sa isRaw()
+*/
+
+/*!
+ \fn bool QIODevice::isRaw() const
+ Returns TRUE if the I/O device is a raw (not buffered) device, otherwise
+ FALSE.
+ \sa isBuffered()
+*/
+
+/*!
+ \fn bool QIODevice::isSynchronous() const
+ Returns TRUE if the I/O device is a synchronous device, otherwise
+ FALSE.
+ \sa isAsynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isAsynchronous() const
+ Returns TRUE if the I/O device is a asynchronous device, otherwise
+ FALSE.
+
+ This mode is currently not in use.
+
+ \sa isSynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isTranslated() const
+ Returns TRUE if the I/O device translates carriage-return and linefeed
+ characters.
+
+ A QFile is translated if it is opened with the \c IO_Translate mode
+ flag.
+*/
+
+/*!
+ \fn bool QIODevice::isReadable() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadOnly or
+ \c IO_ReadWrite mode.
+ \sa isWritable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isWritable() const
+ Returns TRUE if the I/O device was opened using \c IO_WriteOnly or
+ \c IO_ReadWrite mode.
+ \sa isReadable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isReadWrite() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadWrite mode.
+ \sa isReadable(), isWritable()
+*/
+
+/*!
+ \fn bool QIODevice::isInactive() const
+ Returns TRUE if the I/O device state is 0, i.e. the device is not open.
+ \sa isOpen()
+*/
+
+/*!
+ \fn bool QIODevice::isOpen() const
+ Returns TRUE if the I/O device state has been opened, otherwise FALSE.
+ \sa isInactive()
+*/
+
+
+/*!
+ \fn int QIODevice::status() const
+ Returns the I/O device status.
+
+ The I/O device status returns an error code. If open() returns FALSE
+ or readBlock() or writeBlock() return -1, this function can be called to
+ get the reason why the operation did not succeed.
+
+ The status codes are:
+ <ul>
+ <li>\c IO_Ok The operation was successful.
+ <li>\c IO_ReadError Could not read from the device.
+ <li>\c IO_WriteError Could not write to the device.
+ <li>\c IO_FatalError A fatal unrecoverable error occurred.
+ <li>\c IO_OpenError Could not open the device.
+ <li>\c IO_ConnectError Could not connect to the device.
+ <li>\c IO_AbortError The operation was unexpectedly aborted.
+ <li>\c IO_TimeOutError The operation timed out.
+ <li>\c IO_OnCloseError An unspecified error happened on close.
+ </ul>
+
+ \sa resetStatus()
+*/
+
+/*!
+ \fn void QIODevice::resetStatus()
+
+ Sets the I/O device status to \c IO_Ok.
+
+ \sa status()
+*/
+
+
+/*!
+ \fn void QIODevice::setFlags( int f )
+ \internal
+ Used by subclasses to set the device flags.
+*/
+
+/*!
+ \internal
+ Used by subclasses to set the device type.
+*/
+
+void QIODevice::setType( int t )
+{
+#if defined(CHECK_RANGE)
+ if ( (t & IO_TypeMask) != t )
+ qWarning( "QIODevice::setType: Specified type out of range" );
+#endif
+ ioMode &= ~IO_TypeMask; // reset type bits
+ ioMode |= t;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device mode.
+*/
+
+void QIODevice::setMode( int m )
+{
+#if defined(CHECK_RANGE)
+ if ( (m & IO_ModeMask) != m )
+ qWarning( "QIODevice::setMode: Specified mode out of range" );
+#endif
+ ioMode &= ~IO_ModeMask; // reset mode bits
+ ioMode |= m;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device state.
+*/
+
+void QIODevice::setState( int s )
+{
+#if defined(CHECK_RANGE)
+ if ( ((uint)s & IO_StateMask) != (uint)s )
+ qWarning( "QIODevice::setState: Specified state out of range" );
+#endif
+ ioMode &= ~IO_StateMask; // reset state bits
+ ioMode |= (uint)s;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device status (not state).
+*/
+
+void QIODevice::setStatus( int s )
+{
+ ioSt = s;
+}
+
+
+/*!
+ \fn bool QIODevice::open( int mode )
+ Opens the I/O device using the specified \e mode.
+ Returns TRUE if successful, or FALSE if the device could not be opened.
+
+ The mode parameter \e m must be a combination of the following flags.
+ <ul>
+ <li>\c IO_Raw specified raw (unbuffered) file access.
+ <li>\c IO_ReadOnly opens a file in read-only mode.
+ <li>\c IO_WriteOnly opens a file in write-only mode.
+ <li>\c IO_ReadWrite opens a file in read/write mode.
+ <li>\c IO_Append sets the file index to the end of the file.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Window, OS/2 and Macintosh. On Unix systems
+ this flag has no effect. Use with caution as it will also transform every linefeed
+ written to the file into a CRLF pair. This is likely to corrupt your file when
+ writing binary data to it. Cannot be combined with \c IO_Raw.
+ </ul>
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa close()
+*/
+
+/*!
+ \fn void QIODevice::close()
+ Closes the I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa open()
+*/
+
+/*!
+ \fn void QIODevice::flush()
+
+ Flushes an open I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+*/
+
+
+/*!
+ \fn uint QIODevice::size() const
+ Virtual function that returns the size of the I/O device.
+ \sa at()
+*/
+
+/*!
+ Virtual function that returns the current I/O device index.
+
+ This index is the data read/write head of the I/O device.
+
+ \sa size()
+*/
+
+int QIODevice::at() const
+{
+ return ioIndex;
+}
+
+/*!
+ Virtual function that sets the I/O device index to \e pos.
+ \sa size()
+*/
+
+bool QIODevice::at( int pos )
+{
+#if defined(CHECK_RANGE)
+ if ( (uint)pos > size() ) {
+ qWarning( "QIODevice::at: Index %d out of range", pos );
+ return FALSE;
+ }
+#endif
+ ioIndex = pos;
+ return TRUE;
+}
+
+/*!
+ Virtual function that returns TRUE if the I/O device index is at the
+ end of the input.
+*/
+
+bool QIODevice::atEnd() const
+{
+ if ( isSequentialAccess() || isTranslated() ) {
+ QIODevice* that = (QIODevice*)this;
+ int c = that->getch();
+ bool result = c < 0;
+ that->ungetch(c);
+ return result;
+ } else {
+ return at() == (int)size();
+ }
+}
+
+/*!
+ \fn bool QIODevice::reset()
+ Sets the device index to 0.
+ \sa at()
+*/
+
+
+/*!
+ \fn int QIODevice::readBlock( char *data, uint maxlen )
+ Reads at most \e maxlen bytes from the I/O device into \e data and
+ returns the number of bytes actually read.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa writeBlock()
+*/
+
+/*!
+ This convenience function returns all of the remaining data in the
+ device. Note that this only works for direct access devices, such
+ as QFile.
+
+ \sa isDirectAccess()
+*/
+QByteArray QIODevice::readAll()
+{
+ int n = size()-at();
+ QByteArray ba(size()-at());
+ char* c = ba.data();
+ while ( n ) {
+ int r = readBlock( c, n );
+ if ( r < 0 )
+ return QByteArray();
+ n -= r;
+ c += r;
+ }
+ return ba;
+}
+
+/*!
+ \fn int QIODevice::writeBlock( const char *data, uint len )
+ Writes \e len bytes from \e p to the I/O device and returns the number of
+ bytes actually written.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa readBlock()
+*/
+
+/*!
+ This convenience function is the same as calling
+ writeBlock( data.data(), data.size() ).
+*/
+int QIODevice::writeBlock( const QByteArray& data )
+{
+ return writeBlock( data.data(), data.size() );
+}
+
+/*!
+ Reads a line of text, up to \e maxlen bytes including a terminating
+ \0. If there is a newline at the end if the line, it is not stripped.
+
+ Returns the number of bytes read, or -1 in case of error.
+
+ This virtual function can be reimplemented much more efficiently by
+ the most subclasses.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QIODevice::readLine( char *data, uint maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+ int pos = at(); // get current position
+ int s = (int)size(); // size of I/O device
+ char *p = data;
+ if ( pos >= s )
+ return 0;
+ while ( pos++ < s && --maxlen ) { // read one byte at a time
+ readBlock( p, 1 );
+ if ( *p++ == '\n' ) // end of line
+ break;
+ }
+ *p++ = '\0';
+ return (int)((intptr_t)p - (intptr_t)data);
+}
+
+
+/*!
+ \fn int QIODevice::getch()
+
+ Reads a single byte/character from the I/O device.
+
+ Returns the byte/character read, or -1 if the end of the I/O device has been
+ reached.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa putch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::putch( int ch )
+
+ Writes the character \e ch to the I/O device.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::ungetch( int ch )
+
+ Puts the character \e ch back into the I/O device and decrements the
+ index if it is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), putch()
+*/
diff --git a/qtools/qiodevice.h b/qtools/qiodevice.h
new file mode 100644
index 0000000..1c54217
--- /dev/null
+++ b/qtools/qiodevice.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+**
+** Definition of QIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QIODEVICE_H
+#define QIODEVICE_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#include "qcstring.h"
+#endif // QT_H
+
+
+// IO device access types
+
+#define IO_Direct 0x0100 // direct access device
+#define IO_Sequential 0x0200 // sequential access device
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO device open modes
+
+#define IO_ReadOnly 0x0001 // readable device
+#define IO_WriteOnly 0x0002 // writable device
+#define IO_ReadWrite 0x0003 // read+write device
+#define IO_Append 0x0004 // append
+#define IO_Truncate 0x0008 // truncate device
+#define IO_Translate 0x0010 // translate CR+LF
+#define IO_ModeMask 0x00ff
+
+// IO device state
+
+#define IO_Open 0x1000 // device is open
+#define IO_StateMask 0xf000
+
+
+// IO device status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open device
+#define IO_ConnectError 5 // cannot connect to device
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+class Q_EXPORT QIODevice // IO device class
+{
+public:
+ QIODevice();
+ virtual ~QIODevice();
+
+ int flags() const { return ioMode; }
+ int mode() const { return ioMode & IO_ModeMask; }
+ int state() const { return ioMode & IO_StateMask; }
+
+ bool isDirectAccess() const { return ((ioMode & IO_Direct) == IO_Direct); }
+ bool isSequentialAccess() const { return ((ioMode & IO_Sequential) == IO_Sequential); }
+ bool isCombinedAccess() const { return ((ioMode & IO_Combined) == IO_Combined); }
+ bool isBuffered() const { return ((ioMode & IO_Raw) != IO_Raw); }
+ bool isRaw() const { return ((ioMode & IO_Raw) == IO_Raw); }
+ bool isSynchronous() const { return ((ioMode & IO_Async) != IO_Async); }
+ bool isAsynchronous() const { return ((ioMode & IO_Async) == IO_Async); }
+ bool isTranslated() const { return ((ioMode & IO_Translate) == IO_Translate); }
+ bool isReadable() const { return ((ioMode & IO_ReadOnly) == IO_ReadOnly); }
+ bool isWritable() const { return ((ioMode & IO_WriteOnly) == IO_WriteOnly); }
+ bool isReadWrite() const { return ((ioMode & IO_ReadWrite) == IO_ReadWrite); }
+ bool isInactive() const { return state() == 0; }
+ bool isOpen() const { return state() == IO_Open; }
+
+ int status() const { return ioSt; }
+ void resetStatus() { ioSt = IO_Ok; }
+
+ virtual bool open( int mode ) = 0;
+ virtual void close() = 0;
+ virtual void flush() = 0;
+
+ virtual uint size() const = 0;
+ virtual int at() const;
+ virtual bool at( int );
+ virtual bool atEnd() const;
+ bool reset() { return at(0); }
+
+ virtual int readBlock( char *data, uint maxlen ) = 0;
+ virtual int writeBlock( const char *data, uint len ) = 0;
+ virtual int readLine( char *data, uint maxlen );
+ int writeBlock( const QByteArray& data );
+ QByteArray readAll();
+
+ virtual int getch() = 0;
+ virtual int putch( int ) = 0;
+ virtual int ungetch( int ) = 0;
+
+protected:
+ void setFlags( int f ) { ioMode = f; }
+ void setType( int );
+ void setMode( int );
+ void setState( int );
+ void setStatus( int );
+ int ioIndex;
+
+private:
+ int ioMode;
+ int ioSt;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QIODevice( const QIODevice & );
+ QIODevice &operator=( const QIODevice & );
+#endif
+};
+
+
+#endif // QIODEVICE_H
diff --git a/qtools/qlist.doc b/qtools/qlist.doc
new file mode 100644
index 0000000..6b4278c
--- /dev/null
+++ b/qtools/qlist.doc
@@ -0,0 +1,1044 @@
+/****************************************************************************
+**
+**
+** QList and QListIterator class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QList documentation
+ *****************************************************************************/
+
+/*!
+ \class QList qlist.h
+ \brief The QList class is a template class that provides doubly linked lists.
+
+ \ingroup collection
+ \ingroup tools
+
+ In Qt 2.0 QList is only implemented as a template class. Define a
+ template instance QList\<X\> to create a list that operates on pointers
+ to X, or X*.
+
+ Example:
+ \code
+ #include <qlist.h>
+ #include <qstring.h>
+ #include <stdio.h>
+
+ class Employee
+ {
+ public:
+ Employee( const QString& name, int salary ) { n=name; s=salary; }
+ QString name() const { return n; }
+ int salary() const { return s; }
+ private:
+ QString n;
+ int s;
+ };
+
+ void main()
+ {
+ QList<Employee> list; // list of pointers to Employee
+ list.setAutoDelete( TRUE ); // delete items when they are removed
+
+ list.append( new Employee("Bill", 50000) );
+ list.append( new Employee("Steve",80000) );
+ list.append( new Employee("Ron", 60000) );
+
+ Employee *emp;
+ for ( emp=list.first(); emp != 0; emp=list.next() )
+ printf( "%s earns %d\n", emp->name().latin1(), emp->salary() );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Bill earns 50000
+ Steve earns 80000
+ Ron earns 60000
+ \endcode
+
+ The list class is indexable and has a \link at() current index\endlink
+ and a \link current() current item\endlink. The first item corresponds
+ to index 0. The current index is -1 if the current item is null.
+
+ QList has several member functions for traversing the list, but using
+ a QListIterator can be more practical. Multiple list iterators may
+ traverse the same list, independent of each other and independent of
+ the current list item.
+
+ In the example above, we make the call setAutoDelete(TRUE).
+ Enabling auto-deletion tells the list to delete items that are removed
+ from the list. The default is to not delete items when they are
+ removed, but that would cause a memory leak in our example since we have
+ no other references to the list items.
+
+ List items are stored as \c void* in an internal QLNode, which also
+ holds pointers to the next and previous list items. The functions
+ currentNode(), removeNode() and takeNode() operate directly on the
+ QLNode, but they should be used with care.
+
+ When inserting an item into a list, only the pointer is copied, not the
+ item itself. This is called a shallow copy. It is possible to make the
+ list copy all of the item's data (known as a deep copy) when an item is
+ inserted. insert(), inSort() and append() call the virtual function
+ QCollection::newItem() for the item to be inserted.
+ Inherit a list and reimplement it if you want deep copies.
+
+ When removing an item from a list, the virtual function
+ QCollection::deleteItem() is called. QList's default implementation
+ is to delete the item if auto-deletion is enabled.
+
+ The virtual function QGList::compareItems() can be reimplemented to
+ compare two list items. This function is called from all list functions
+ that need to compare list items, for instance remove(const type*).
+ If you only want to deal with pointers, there are functions that
+ compare pointers instead, for instance removeRef(const type*).
+ These functions are somewhat faster than those that call compareItems().
+
+ The QStrList class in qstrlist.h is a list of \c char*. QStrList is
+ a good example of a list that reimplements newItem(), deleteItem() and
+ compareItems()
+
+ \sa QListIterator, \link collection.html Collection Classes\endlink
+*/
+
+
+/*!
+ \fn QList::QList()
+ Constructs an empty list.
+*/
+
+/*!
+ \fn QList::QList( const QList<type> &list )
+ Constructs a copy of \e list.
+
+ Each item in \e list is \link append() appended\endlink to this list.
+ Only the pointers are copied (shallow copy).
+*/
+
+/*!
+ \fn QList::~QList()
+ Removes all items from the list and destroys the list.
+
+ All list iterators that access this list will be reset.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn QList<type> &QList::operator=(const QList<type> &list)
+ Assigns \e list to this list and returns a reference to this list.
+
+ This list is first cleared, then each item in \e list is
+ \link append() appended\endlink to this list. Only the pointers are copied
+ (shallow copy), unless newItem() has been reimplemented().
+*/
+
+/*!
+ \fn bool QList::operator==(const QList<type> &list ) const
+
+ Compares this list with \a list. Retruns TRUE if the lists
+ contain the same data, else FALSE.
+*/
+
+/*!
+ \fn uint QList::count() const
+ Returns the number of items in the list.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn void QList::sort()
+
+ Sorts the list by the result of the virtual compareItems() function.
+
+ The Heap-Sort algorithm is used for sorting. It sorts n items with
+ O(n*log n) compares. This is the asymptotic optimal solution of the
+ sorting problem.
+
+ If the items in your list support operator< and operator== then you
+ might be better off with QSortedList since it implements the
+ compareItems() function for you using these two operators.
+
+ \sa inSort()
+*/
+
+/*!
+ \fn bool QList::isEmpty() const
+ Returns TRUE if the list is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn bool QList::insert( uint index, const type *item )
+ Inserts the \e item at the position \e index in the list.
+
+ Returns TRUE if successful, or FALSE if \e index is out of range.
+ The valid range is <code>0 .. count()</code> inclusive.
+ The item is appended if \e index == count().
+
+ The inserted item becomes the current list item.
+
+ The \e item must not be a null pointer.
+
+ \sa append(), current()
+*/
+
+/*!
+ \fn void QList::inSort( const type *item )
+ Inserts the \e item at its sorted position in the list.
+
+ The sort order depends on the virtual QGList::compareItems() function.
+ All items must be inserted with inSort() to maintain the sorting order.
+
+ The inserted item becomes the current list item.
+
+ The \e item must not be a null pointer.
+
+ Please note that inSort is slow. If you want to insert lots of items
+ in a list and sort after inserting then you should use sort().
+ inSort() takes up to O(n) compares. That means inserting n items in
+ your list will need O(n^2) compares while sort() only needs O(n*logn)
+ for the same task. So you inSort() only if you already have a pre-sorted
+ list and want to insert only few additional items.
+
+ \sa insert(), QGList::compareItems(), current(), sort()
+*/
+
+/*!
+ \fn void QList::append( const type *item )
+ Inserts the \e item at the end of the list.
+
+ The inserted item becomes the current list item.
+ This is equivalent to \c insert(count(),item).
+
+
+ The \e item must not be a null pointer.
+
+ \sa insert(), current(), prepend()
+*/
+
+/*!
+ \fn void QList::prepend( const type *item )
+
+ Inserts the \e item at the start of the list.
+
+ The inserted item becomes the current list item.
+ This is equivalent to \c insert(0,item).
+
+ The \e item must not be a null pointer.
+
+ \sa append(), insert(), current()
+*/
+
+/*!
+ \fn bool QList::remove( uint index )
+ Removes the item at position \e index in the list.
+
+ Returns TRUE if successful, or FALSE if \e index is out of range.
+ The valid range is <code>0 .. (count() - 1)</code> inclusive.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The item after the removed item becomes the new current list item if
+ the removed item is not the last item in the list. If the last item
+ is removed, the new last item becomes the current item in Qt 2.x.
+ In 3.0, the current item will be set to null. The current item is
+ set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa take(), clear(), setAutoDelete(), current() removeRef()
+*/
+
+/*!
+ \fn bool QList::remove()
+ Removes the current list item.
+
+ Returns TRUE if successful, or FALSE if the current item is null.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The item after the removed item becomes the new current list item if
+ the removed item is not the last item in the list. If the last item
+ is removed, the new last item becomes the current item in Qt 2.x.
+ In 3.0, the current item will be set to null. The current item is
+ set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa take(), clear(), setAutoDelete(), current() removeRef()
+*/
+
+/*!
+ \fn bool QList::remove( const type *item )
+ Removes the first occurrence of \e item from the list.
+
+ Returns TRUE if successful, or FALSE if the item could not be found in the
+ list.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The compareItems() function is called when searching for the item
+ in the list. If compareItems() is not reimplemented, it is more
+ efficient to call removeRef().
+
+ The item after the removed item becomes the new current list item if
+ the removed item is not the last item in the list. If the last item
+ is removed, the new last item becomes the current item in Qt 2.x.
+ In 3.0, the current item will be set to null. The current item is
+ set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa removeRef(), take(), clear(), setAutoDelete(), compareItems(), current()
+*/
+
+/*!
+ \fn bool QList::removeRef( const type *item )
+ Removes the first occurrence of \e item from the list.
+
+ Returns TRUE if successful, or FALSE if the item cannot be found in the
+ list.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The list is scanned until the pointer \e item is found. It is removed
+ if it is found.
+
+ Equivalent to:
+ \code
+ if ( list.findRef(item) != -1 )
+ list.remove();
+ \endcode
+
+ The item after the removed item becomes the new current list item if
+ the removed item is not the last item in the list. If the last item
+ is removed, the new last item becomes the current item in Qt 2.x.
+ In 3.0, the current item will be set to null. The current item is
+ set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa remove(), clear(), setAutoDelete(), current()
+*/
+
+/*!
+ \fn void QList::removeNode( QLNode *node )
+ Removes the \e node from the list.
+
+ This node must exist in the list, otherwise the program may crash.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The first item in the list will become the new current list item.
+ The current item is set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point to
+ the item succeeding this item, or the preceding item if the removed item
+ was the last item.
+
+ \warning Do not call this function unless you are an expert.
+
+ \sa takeNode(), currentNode() remove() removeRef()
+*/
+
+/*!
+ \fn bool QList::removeFirst()
+ Removes the first item from the list.
+ Returns TRUE if successful, or FALSE if the list is empty.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The first item in the list becomes the new current list item.
+ The current item is set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa removeLast(), setAutoDelete(), current() remove()
+*/
+
+/*!
+ \fn bool QList::removeLast()
+ Removes the last item from the list.
+ Returns TRUE if successful, or FALSE if the list is empty.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ The last item in the list becomes the new current list item.
+ The current item is set to null if the list becomes empty.
+
+ All list iterators that refer to the removed item will be set to point
+ to the new current item.
+
+ \sa removeFirst(), setAutoDelete(), current()
+*/
+
+/*!
+ \fn type *QList::take( uint index )
+ Takes the item at position \e index out of the list without
+ deleting it (even if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled).
+
+ Returns a pointer to the item taken out of the list, or null if
+ the index is out of range.
+ The valid range is <code>0 .. (count() - 1)</code> inclusive.
+
+ The item after the taken item becomes the new current list item if
+ the taken item is not the last item in the list. If the last item
+ is taken, the new last item becomes the current item in Qt 2.x. In
+ 3.0, the current item will be set to null. The current item is set
+ to null if the list becomes empty.
+
+ All list iterators that refer to the taken item will be set to point to
+ the new current item.
+
+ \sa remove(), clear(), current()
+*/
+
+/*!
+ \fn type *QList::take()
+ Takes the current item out of the list without deleting it (even if
+ \link QCollection::setAutoDelete() auto-deletion\endlink is enabled).
+ Returns a pointer to the item taken out of the list, or null if
+ the current item is null.
+
+ The item after the taken item becomes the new current list item if
+ the taken item is not the last item in the list. If the last item
+ is taken, the new last item becomes the current item in Qt 2.x. In
+ 3.0, the current item will be set to null. The current item is set
+ to null if the list becomes empty.
+
+ All list iterators that refer to the taken item will be set to point to
+ the new current item.
+
+ \sa remove(), clear(), current()
+*/
+
+/*!
+ \fn type *QList::takeNode( QLNode *node )
+ Takes the \e node out of the list without deleting its item (even if
+ \link QCollection::setAutoDelete() auto-deletion\endlink is enabled).
+ Returns a pointer to the item taken out of the list.
+
+ This node must exist in the list, otherwise the program may crash.
+
+ The first item in the list becomes the new current list item.
+
+ All list iterators that refer to the taken item will be set to point to
+ the item succeeding this item, or the preceding item if the taken item
+ was the last item.
+
+ \warning Do not call this function unless you are an expert.
+
+ \sa removeNode(), currentNode()
+*/
+
+/*!
+ \fn void QList::clear()
+ Removes all items from the list.
+
+ The removed items are deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All list iterators that access this list will be reset.
+
+ \sa remove(), take(), setAutoDelete()
+*/
+
+/*!
+ \fn int QList::find( const type *item )
+ Finds the first occurrence of \e item in the list.
+
+ If the item is found, the list sets the current item to point to
+ the found item and returns the index of this item.
+ If the item is not found, the list sets the current item to null,
+ the current index to -1 and returns -1.
+
+ The compareItems() function is called when searching for the item
+ in the list. If compareItems() is not reimplemented, it is more
+ efficient to call findRef().
+
+ \sa findNext(), findRef(), compareItems(), current()
+*/
+
+/*!
+ \fn int QList::findNext( const type *item )
+ Finds the next occurrence of \e item in the list, starting from
+ the current list item.
+
+ If the item is found, the list sets the current item to point to
+ the found item and returns the index of this item.
+ If the item is not found, the list sets the current item to null,
+ the current index to -1 and returns -1.
+
+ The compareItems() function is called when searching for the item
+ in the list. If compareItems() is not reimplemented, it is more
+ efficient to call findNextRef().
+
+ \sa find(), findNextRef(), compareItems(), current()
+*/
+
+/*!
+ \fn int QList::findRef( const type *item )
+ Finds the first occurrence of \e item in the list.
+
+ If the item is found, the list sets the current item to point to
+ the found item and returns the index of this item.
+ If the item is not found, the list sets the current item to null,
+ the current index to -1 and returns -1.
+
+ Calling this function is must faster than find(), because find()
+ compares \e item with each list item using compareItems().
+ This function only compares the pointers.
+
+ \sa findNextRef(), find(), current()
+*/
+
+/*!
+ \fn int QList::findNextRef( const type *item )
+ Finds the next occurrence of \e item in the list, starting from the
+ current list item.
+
+ If the item is found, the list sets the current item to point to
+ the found item and returns the index of this item.
+ If the item is not found, the list sets the current item to null,
+ the current index to -1 and returns -1.
+
+ Calling this function is must faster than findNext(), because findNext()
+ compares \e item with each list item using compareItems().
+ This function only compares the pointers.
+
+ \sa findRef(), findNext(), current()
+*/
+
+/*!
+ \fn uint QList::contains( const type *item ) const
+ Counts and returns the number of occurrences of \e item in the list.
+
+ The compareItems() function is called when looking for the \e item
+ in the list. If compareItems() is not reimplemented, it is more
+ efficient to call containsRef().
+
+ Does not affect the current list item.
+
+ \sa containsRef(), compareItems()
+*/
+
+/*!
+ \fn uint QList::containsRef( const type *item ) const
+ Counts and returns the number of occurrences of \e item in the list.
+
+ Calling this function is must faster than contains(), because contains()
+ compares \e item with each list item using compareItems().
+ This function only compares the pointers.
+
+ Does not affect the current list item.
+
+ \sa contains()
+*/
+
+/*!
+ \fn type *QList::at( uint index )
+ Returns a pointer to the item at position \e index in the list, or
+ null if the index is out of range.
+
+ Sets the current list item to this item if \e index is valid.
+ The valid range is <code>0 .. (count() - 1)</code> inclusive.
+
+ This function is very efficient. It starts scanning from the first
+ item, last item or current item, whichever is closest to \e index.
+
+ \sa current()
+*/
+
+/*!
+ \fn int QList::at() const
+ Returns the index of the current list item. The returned value is -1
+ if the current item is null.
+ \sa current()
+*/
+
+/*!
+ \fn type *QList::current() const
+ Returns a pointer to the current list item. The current item may be
+ null (implies that the current index is -1).
+ \sa at()
+*/
+
+/*!
+ \fn QLNode *QList::currentNode() const
+ Returns a pointer to the current list node.
+
+ The node can be kept and removed later using removeNode().
+ The advantage is that the item can be removed directly without
+ searching the list.
+
+ \warning Do not call this function unless you are an expert.
+
+ \sa removeNode(), takeNode(), current()
+*/
+
+/*!
+ \fn type *QList::getFirst() const
+ Returns a pointer to the first item in the list, or null if the
+ list is empty.
+
+ Does not affect the current list item.
+
+ \sa first(), getLast()
+*/
+
+/*!
+ \fn type *QList::getLast() const
+ Returns a pointer to the last item in the list, or null if the
+ list is empty.
+
+ Does not affect the current list item.
+
+ \sa last(), getFirst()
+*/
+
+/*!
+ \fn type *QList::first()
+ Returns a pointer to the first item in the list and makes this the
+ current list item, or null if the list is empty.
+ \sa getFirst(), last(), next(), prev(), current()
+*/
+
+/*!
+ \fn type *QList::last()
+ Returns a pointer to the last item in the list and makes this the
+ current list item, or null if the list is empty.
+ \sa getLast(), first(), next(), prev(), current()
+*/
+
+/*!
+ \fn type *QList::next()
+ Returns a pointer to the item succeeding the current item.
+ Returns null if the current item is null or equal to the last item.
+
+ Makes the succeeding item current. If the current item before this
+ function call was the last item, the current item will be set to null.
+ If the current item was null, this function does nothing.
+
+ \sa first(), last(), prev(), current()
+*/
+
+/*!
+ \fn type *QList::prev()
+ Returns a pointer to the item preceding the current item.
+ Returns null if the current item is null or equal to the first item.
+
+ Makes the preceding item current. If the current item before this
+ function call was the first item, the current item will be set to null.
+ If the current item was null, this function does nothing.
+
+ \sa first(), last(), next(), current()
+*/
+
+/*!
+ \fn void QList::toVector( QGVector *vec ) const
+ Stores all list items in the vector \e vec.
+
+ The vector must be have the same item type, otherwise the result
+ will be undefined.
+*/
+
+
+/*****************************************************************************
+ QListIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QListIterator qlist.h
+ \brief The QListIterator class provides an iterator for QList collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ Define a template instance QListIterator\<X\> to create a list iterator
+ that operates on QList\<X\> (list of X*).
+
+ Example:
+ \code
+ #include <qlist.h>
+ #include <qstring.h>
+ #include <stdio.h>
+
+ class Employee
+ {
+ public:
+ Employee( const char *name, int salary ) { n=name; s=salary; }
+ const char *name() const { return n; }
+ int salary() const { return s; }
+ private:
+ QString n;
+ int s;
+ };
+
+ void main()
+ {
+ QList<Employee> list; // list of pointers to Employee
+ list.setAutoDelete( TRUE ); // delete items when they are removed
+
+ list.append( new Employee("Bill", 50000) );
+ list.append( new Employee("Steve",80000) );
+ list.append( new Employee("Ron", 60000) );
+
+ QListIterator<Employee> it(list); // iterator for employee list
+ for ( ; it.current(); ++it ) {
+ Employee *emp = it.current();
+ printf( "%s earns %d\n", emp->name().latin1(), emp->salary() );
+ }
+ }
+ \endcode
+
+ Program output:
+ \code
+ Bill earns 50000
+ Steve earns 80000
+ Ron earns 60000
+ \endcode
+
+ Although QList has member functions to traverse the doubly linked list
+ structure, using a list iterator is a much more robust way of traversing
+ the list, because multiple list iterators can operate on the same list,
+ independent of each other and independent of the QList's current item.
+ An iterator has its own current list item and can get the next and
+ previous list items. It can only traverse the list, never modify it.
+
+ A QList knows about all list iterators that are operating on the list.
+ When an item is removed from the list, the list update all iterators
+ that are pointing the removed item to point to the new current list item.
+
+ Example:
+ \code
+ #include <qlist.h>
+ #include <qstring.h>
+ #include <stdio.h>
+
+ class Employee
+ {
+ ... // same as above
+ };
+
+ void main()
+ {
+ QList<Employee> list; // list of pointers to Employee
+ list.setAutoDelete( TRUE ); // delete items when they are removed
+
+ list.append( new Employee("Bill", 50000) );
+ list.append( new Employee("Steve",80000) );
+ list.append( new Employee("Ron", 60000) );
+
+ QListIterator<Employee> it(list);
+
+ list.at( 1 ); // current list item: "Steve"
+ it.toLast(); // it: "Ron"
+ --it; // it: "Steve"
+
+ // Now, both the list and the iterator are referring the same item
+
+ list.remove();
+ printf( "%s\n", it.current()->name().latin1() );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Ron
+ \endcode
+
+ \sa QList, \link collection.html collection classes\endlink
+*/
+
+/*!
+ \fn QListIterator::QListIterator( const QList<type> &list )
+ Constructs an iterator for \e list. The current iterator item is
+ set to point on the first item in the \e list.
+*/
+
+/*!
+ \fn QListIterator::~QListIterator()
+ Destroys the iterator.
+*/
+
+/*!
+ \fn uint QListIterator::count() const
+ Returns the number of items in the list this iterator operates on.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn bool QListIterator::isEmpty() const
+ Returns TRUE if the list is empty, i.e. count() == 0, otherwise FALSE.
+ \sa count()
+*/
+
+/*!
+ \fn bool QListIterator::atFirst() const
+ Returns TRUE if the current iterator item is the first list item, otherwise
+ FALSE.
+ \sa toFirst(), atLast()
+*/
+
+/*!
+ \fn bool QListIterator::atLast() const
+ Returns TRUE if the current iterator item is the last list item, otherwise
+ FALSE.
+ \sa toLast(), atFirst()
+*/
+
+/*!
+ \fn type *QListIterator::toFirst()
+ Sets the current iterator item to point to the first list item and returns
+ a pointer to the item. Sets the current item to null and returns null
+ if the list is empty.
+ \sa toLast(), atFirst()
+*/
+
+/*!
+ \fn type *QListIterator::toLast()
+ Sets the current iterator item to point to the last list item and returns
+ a pointer to the item. Sets the current item to null and returns null
+ if the list is empty.
+ \sa toFirst(), atLast()
+*/
+
+/*!
+ \fn QListIterator::operator type *() const
+ Cast operator. Returns a pointer to the current iterator item.
+ Same as current().
+*/
+
+/*!
+ \fn type *QListIterator::operator*()
+ Asterix operator. Returns a pointer to the current iterator item.
+ Same as current().
+*/
+
+/*!
+ \fn type *QListIterator::current() const
+ Returns a pointer to the current iterator item.
+*/
+
+/*!
+ \fn type *QListIterator::operator()()
+ Makes the succeeding item current and returns the original current item.
+
+ If the current iterator item was the last item in the list or if it was
+ null, null is returned.
+*/
+
+/*!
+ \fn char *QStrListIterator::operator()()
+ Makes the succeeding item current and returns the original current item.
+
+ If the current iterator item was the last item in the list or if it was
+ null, null is returned.
+*/
+
+/*!
+ \fn type *QListIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns the new current
+ item.
+
+ If the current iterator item was the last item in the list or if it was
+ null, null is returned.
+*/
+
+/*!
+ \fn type *QListIterator::operator+=( uint jump )
+ Sets the current item to the item \e jump positions after the current item,
+ and returns a pointer to that item.
+
+ If that item is beyond the last item or if the dictionary is empty,
+ it sets the current item to null and returns null
+*/
+
+/*!
+ \fn type *QListIterator::operator--()
+ Prefix -- makes the preceding item current and returns the new current
+ item.
+
+ If the current iterator item was the first item in the list or if it was
+ null, null is returned.
+*/
+
+/*!
+ \fn type *QListIterator::operator-=( uint jump )
+ Returns the item \e jump positions before the current item, or null if
+ it is beyond the first item. Makes this the current item.
+*/
+
+/*!
+ \fn QListIterator<type>& QListIterator::operator=( const QListIterator<type> &it )
+ Assignment. Makes a copy of the iterator \a it and returns a reference
+ to this iterator.
+*/
+
+
+/*****************************************************************************
+ QStrList documentation
+ *****************************************************************************/
+
+//typedef QList<char> QStrList
+
+/*!
+ \class QStrList qstrlist.h
+ \brief The QStrList class provides a doubly linked list of \c char*.
+
+ \ingroup collection
+ \ingroup tools
+
+ This class is a QList\<char\> instance (a list of char*).
+
+ QStrList can make deep or shallow copies of the strings that are inserted.
+
+ A deep copy means to allocate space for the string and then copy the string
+ data into it. A shallow copy is just a copy of the pointer value and not
+ the string data.
+
+ The disadvantage with shallow copies is that since a pointer can only
+ be deleted once, the program must put all strings in a central place and
+ know when it is safe to delete them (i.e. when the strings are no longer
+ referenced by other parts of the program). This can make the program
+ more complex. The advantage of shallow copies is that shallow copies
+ consume far less memory than deep copies. It is also much faster
+ to copy a pointer (typically 4 or 8 bytes) than to copy string data.
+
+ A QStrList that operates on deep copies will by default turn on
+ auto-deletion (see setAutoDelete()). Thus, by default, QStrList will
+ deallocate any string copies it allocates.
+
+ The virtual compareItems() function is reimplemented and does a case
+ sensitive string comparison. The inSort() function will insert
+ strings in a sorted order.
+
+ The QStrListIterator class is an iterator for QStrList.
+*/
+
+/*!
+ \fn QStrList::QStrList( bool deepCopies )
+ Constructs an empty list of strings. Will make deep copies of all inserted
+ strings if \e deepCopies is TRUE, or uses shallow copies if \e deepCopies
+ is FALSE.
+*/
+
+/*!
+ \fn QStrList::QStrList( const QStrList &list )
+ Constructs a copy of \e list.
+
+ If \e list has deep copies, this list will also get deep copies.
+ Only the pointers are copied (shallow copy) if the other list does not
+ use deep copies.
+*/
+
+/*!
+ \fn QStrList::~QStrList()
+ Destroys the list. All strings are removed.
+*/
+
+/*!
+ \fn QStrList& QStrList::operator=( const QStrList& list )
+ Assigns \e list to this list and returns a reference to this list.
+
+ If \e list has deep copies, this list will also get deep copies.
+ Only the pointers are copied (shallow copy) if the other list does not
+ use deep copies.
+*/
+
+
+/*****************************************************************************
+ QStrIList documentation
+ *****************************************************************************/
+
+/*!
+ \class QStrIList qstrlist.h
+ \brief The QStrIList class provides a doubly linked list of \c char* with
+case insensitive compare.
+
+ \ingroup collection
+ \ingroup tools
+
+ This class is a QList\<char\> instance (a list of char*).
+
+ QStrIList is similar to QStrList except that it is case insensitive.
+ The virtual compareItems() function is reimplemented and does a
+ case insensitive string comparison.
+ The inSort() function will insert strings in a sorted order.
+
+ The QStrListIterator class is an iterator for QStrList.
+*/
+
+/*!
+ \fn QStrIList::QStrIList( bool deepCopies )
+ Constructs a list of strings. Will make deep copies of all inserted
+ strings if \e deepCopies is TRUE, or uses shallow copies if \e deepCopies
+ is FALSE.
+*/
+
+/*!
+ \fn QStrIList::~QStrIList()
+ Destroys the list. All strings are removed.
+*/
+
+
+/*****************************************************************************
+ QStrListIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QStrListIterator qstrlist.h
+ \brief The QStrListIterator class is an iterator for the QStrList and QStrIList classes.
+
+ \ingroup tools
+
+ This class is a QListIterator\<char\> instance.
+ It can traverse the strings in the QStrList and QStrIList classes.
+*/
diff --git a/qtools/qlist.h b/qtools/qlist.h
new file mode 100644
index 0000000..e9b908d
--- /dev/null
+++ b/qtools/qlist.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+**
+** Definition of QList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/* This is a stripped version of the original QList, which has been renamed to
+ QInternalList. This implementation doesn't expose the current node and index,
+ nor direct access to the list nodes.
+ This makes it possible to have more constant methods. It also provides
+ a typesafe method to compare elements called compareValues() and a typesafe
+ methods to create and delete elements called newValue() and deleteValue().
+ */
+
+#ifndef QLIST_H
+#define QLIST_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QList : private QGList
+{
+public:
+ QList() {}
+ QList( const QList<type> &l ) : QGList(l) {}
+ ~QList() { clear(); }
+ QList<type> &operator=(const QList<type> &l)
+ { return (QList<type>&)QGList::operator=(l); }
+ bool operator==( const QList<type> &list ) const
+ { return QGList::operator==( list ); }
+
+ // capacity
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+
+ // modifiers add
+ bool insert( uint i, const type *d){ return QGList::insertAt(i,(QCollection::Item)d); }
+ void inSort( const type *d ) { QGList::inSort((QCollection::Item)d); }
+ void prepend( const type *d ) { QGList::insertAt(0,(QCollection::Item)d); }
+ void append( const type *d ) { QGList::append((QCollection::Item)d); }
+
+ // modifiers remove
+ bool remove( uint i ) { return QGList::removeAt(i); }
+ bool remove( const type *d ) { return QGList::remove((QCollection::Item)d); }
+ bool removeRef( const type *d ) { return QGList::removeRef((QCollection::Item)d); }
+ bool removeFirst() { return QGList::removeFirst(); }
+ bool removeLast() { return QGList::removeLast(); }
+ type *take( uint i ) { return (type *)QGList::takeAt(i); }
+ void clear() { QGList::clear(); }
+
+ // operations
+ void sort() { QGList::sort(); }
+
+ // search
+ int find( const type *d ) const { return const_cast<QList<type>*>(this)->QGList::find((QCollection::Item)d); }
+ int findRef( const type *d ) const { return const_cast<QList<type>*>(this)->QGList::findRef((QCollection::Item)d); }
+ uint contains( const type *d ) const { return QGList::contains((QCollection::Item)d); }
+ uint containsRef( const type *d ) const { return QGList::containsRef((QCollection::Item)d); }
+
+ // element access
+ type *at( uint i ) const { return (type *)const_cast<QList<type>*>(this)->QGList::at(i); }
+ type *getFirst() const { return (type *)QGList::cfirst(); }
+ type *getLast() const { return (type *)QGList::clast(); }
+
+ // ownership
+ void setAutoDelete( bool enable ) { QGList::setAutoDelete(enable); }
+
+private:
+ // new to be reimplemented methods
+ virtual int compareValues(const type *t1,const type *t2) const
+ { return const_cast<QList<type>*>(this)->QGList::compareItems((QCollection::Item)t1,(QCollection::Item)t2); }
+ virtual type *newValue(type *item) const
+ { return item; }
+ virtual void deleteValue(type *item) const
+ { if (del_item) delete item; }
+
+ // reimplemented methods
+ virtual Item newItem( Item item)
+ { return (Item)newValue((type*)item); }
+ virtual void deleteItem( QCollection::Item item )
+ { deleteValue((type *)item); }
+ virtual int compareItems(QCollection::Item i1,QCollection::Item i2)
+ { return compareValues((const type*)i1,(const type*)i2); }
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QList<void>::deleteValue(void *) const
+{
+}
+#endif
+
+
+template<class type> class Q_EXPORT QListIterator : public QGListIterator
+{
+public:
+ QListIterator(const QList<type> &l) :QGListIterator((QGList &)l) {}
+ ~QListIterator() {}
+ uint count() const { return list->count(); }
+ bool isEmpty() const { return list->count() == 0; }
+ bool atFirst() const { return QGListIterator::atFirst(); }
+ bool atLast() const { return QGListIterator::atLast(); }
+ type *toFirst() { return (type *)QGListIterator::toFirst(); }
+ type *toLast() { return (type *)QGListIterator::toLast(); }
+ operator type *() const { return (type *)QGListIterator::get(); }
+ type *operator*() { return (type *)QGListIterator::get(); }
+
+ // No good, since QList<char> (ie. QStrList fails...
+ //
+ // MSVC++ gives warning
+ // Sunpro C++ 4.1 gives error
+ // type *operator->() { return (type *)QGListIterator::get(); }
+
+ type *current() const { return (type *)QGListIterator::get(); }
+ type *operator()() { return (type *)QGListIterator::operator()();}
+ type *operator++() { return (type *)QGListIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGListIterator::operator+=(j);}
+ type *operator--() { return (type *)QGListIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)QGListIterator::operator-=(j);}
+ QListIterator<type>& operator=(const QListIterator<type>&it)
+ { QGListIterator::operator=(it); return *this; }
+};
+
+
+#endif // QLIST_H
diff --git a/qtools/qmap.cpp b/qtools/qmap.cpp
new file mode 100644
index 0000000..1d2510a
--- /dev/null
+++ b/qtools/qmap.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+**
+** Implementation of QMap
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qmap.h"
+
+typedef QMapNodeBase* NodePtr;
+typedef QMapNodeBase Node;
+
+
+void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
+{
+ NodePtr y = x->right;
+ x->right = y->left;
+ if (y->left !=0)
+ y->left->parent = x;
+ y->parent = x->parent;
+ if (x == root)
+ root = y;
+ else if (x == x->parent->left)
+ x->parent->left = y;
+ else
+ x->parent->right = y;
+ y->left = x;
+ x->parent = y;
+}
+
+
+void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
+{
+ NodePtr y = x->left;
+ x->left = y->right;
+ if (y->right != 0)
+ y->right->parent = x;
+ y->parent = x->parent;
+ if (x == root)
+ root = y;
+ else if (x == x->parent->right)
+ x->parent->right = y;
+ else
+ x->parent->left = y;
+ y->right = x;
+ x->parent = y;
+}
+
+
+void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
+{
+ x->color = Node::Red;
+ while ( x != root && x->parent->color == Node::Red ) {
+ if ( x->parent == x->parent->parent->left ) {
+ NodePtr y = x->parent->parent->right;
+ if (y && y->color == Node::Red) {
+ x->parent->color = Node::Black;
+ y->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ x = x->parent->parent;
+ } else {
+ if (x == x->parent->right) {
+ x = x->parent;
+ rotateLeft( x, root );
+ }
+ x->parent->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ rotateRight (x->parent->parent, root );
+ }
+ } else {
+ NodePtr y = x->parent->parent->left;
+ if ( y && y->color == Node::Red ) {
+ x->parent->color = Node::Black;
+ y->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ x = x->parent->parent;
+ } else {
+ if (x == x->parent->left) {
+ x = x->parent;
+ rotateRight( x, root );
+ }
+ x->parent->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ rotateLeft( x->parent->parent, root );
+ }
+ }
+ }
+ root->color = Node::Black;
+}
+
+
+NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
+ NodePtr& leftmost,
+ NodePtr& rightmost )
+{
+ NodePtr y = z;
+ NodePtr x;
+ NodePtr x_parent;
+ if (y->left == 0) {
+ x = y->right;
+ } else {
+ if (y->right == 0)
+ x = y->left;
+ else
+ {
+ y = y->right;
+ while (y->left != 0)
+ y = y->left;
+ x = y->right;
+ }
+ }
+ if (y != z) {
+ z->left->parent = y;
+ y->left = z->left;
+ if (y != z->right) {
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ y->parent->left = x;
+ y->right = z->right;
+ z->right->parent = y;
+ } else {
+ x_parent = y;
+ }
+ if (root == z)
+ root = y;
+ else if (z->parent->left == z)
+ z->parent->left = y;
+ else
+ z->parent->right = y;
+ y->parent = z->parent;
+ // Swap the colors
+ Node::Color c = y->color;
+ y->color = z->color;
+ z->color = c;
+ y = z;
+ } else {
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ if (root == z)
+ root = x;
+ else if (z->parent->left == z)
+ z->parent->left = x;
+ else
+ z->parent->right = x;
+ if ( leftmost == z ) {
+ if (z->right == 0)
+ leftmost = z->parent;
+ else
+ leftmost = x->minimum();
+ }
+ if (rightmost == z) {
+ if (z->left == 0)
+ rightmost = z->parent;
+ else
+ rightmost = x->maximum();
+ }
+ }
+ if (y->color != Node::Red) {
+ while (x != root && (x == 0 || x->color == Node::Black)) {
+ if (x == x_parent->left) {
+ NodePtr w = x_parent->right;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_parent->color = Node::Red;
+ rotateLeft(x_parent, root);
+ w = x_parent->right;
+ }
+ if ((w->left == 0 || w->left->color == Node::Black) &&
+ (w->right == 0 || w->right->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->right == 0 || w->right->color == Node::Black) {
+ if (w->left)
+ w->left->color = Node::Black;
+ w->color = Node::Red;
+ rotateRight(w, root);
+ w = x_parent->right;
+ }
+ w->color = x_parent->color;
+ x_parent->color = Node::Black;
+ if (w->right)
+ w->right->color = Node::Black;
+ rotateLeft(x_parent, root);
+ break;
+ }
+ } else {
+ NodePtr w = x_parent->left;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_parent->color = Node::Red;
+ rotateRight(x_parent, root);
+ w = x_parent->left;
+ }
+ if ((w->right == 0 || w->right->color == Node::Black) &&
+ (w->left == 0 || w->left->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->left == 0 || w->left->color == Node::Black) {
+ if (w->right)
+ w->right->color = Node::Black;
+ w->color = Node::Red;
+ rotateLeft(w, root);
+ w = x_parent->left;
+ }
+ w->color = x_parent->color;
+ x_parent->color = Node::Black;
+ if (w->left)
+ w->left->color = Node::Black;
+ rotateRight(x_parent, root);
+ break;
+ }
+ }
+ }
+ if (x)
+ x->color = Node::Black;
+ }
+ return y;
+}
diff --git a/qtools/qmap.h b/qtools/qmap.h
new file mode 100644
index 0000000..f384a3d
--- /dev/null
+++ b/qtools/qmap.h
@@ -0,0 +1,606 @@
+/****************************************************************************
+**
+**
+** Definition of QMap class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QMAP_H
+#define QMAP_H
+
+#ifndef QT_H
+#include "qshared.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+struct QMapNodeBase
+{
+ enum Color { Red, Black };
+
+ QMapNodeBase* left;
+ QMapNodeBase* right;
+ QMapNodeBase* parent;
+
+ Color color;
+
+ QMapNodeBase* minimum() {
+ QMapNodeBase* x = this;
+ while ( x->left )
+ x = x->left;
+ return x;
+ }
+
+ QMapNodeBase* maximum() {
+ QMapNodeBase* x = this;
+ while ( x->right )
+ x = x->right;
+ return x;
+ }
+};
+
+
+template <class K, class T>
+struct QMapNode : public QMapNodeBase
+{
+ QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
+ QMapNode( const K& _key ) { key = _key; }
+ QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
+ QMapNode() { }
+ T data;
+ K key;
+};
+
+
+template<class K, class T>
+class Q_EXPORT QMapIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QMapNode< K, T >* NodePtr;
+
+ /**
+ * Variables
+ */
+ QMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ QMapIterator() : node( 0 ) {}
+ QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
+ QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
+ T& operator*() { return node->data; }
+ const T& operator*() const { return node->data; }
+
+ // Cannot have this - some compilers are too stupid
+ //T* operator->() const { return &(node->data); }
+
+ const K& key() const { return node->key; }
+ T& data() { return node->data; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc() {
+ QMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->parent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+ int dec() {
+ QMapNodeBase* tmp = node;
+ if (tmp->color == QMapNodeBase::Red &&
+ tmp->parent->parent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ QMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->parent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+public:
+ QMapIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ QMapIterator<K,T> operator++(int) {
+ QMapIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ QMapIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ QMapIterator<K,T> operator--(int) {
+ QMapIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+template<class K, class T>
+class Q_EXPORT QMapConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QMapNode< K, T >* NodePtr;
+
+ /**
+ * Variables
+ */
+ QMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ QMapConstIterator() : node( 0 ) {}
+ QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
+ QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
+ QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+
+ // Cannot have this - some compilers are too stupid
+ //const T* operator->() const { return &(node->data); }
+
+ const K& key() const { return node->key; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc() {
+ QMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->parent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+ int dec() {
+ QMapNodeBase* tmp = node;
+ if (tmp->color == QMapNodeBase::Red &&
+ tmp->parent->parent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ QMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->parent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+public:
+ QMapConstIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ QMapConstIterator<K,T> operator++(int) {
+ QMapConstIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ QMapConstIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ QMapConstIterator<K,T> operator--(int) {
+ QMapConstIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+
+class Q_EXPORT QMapPrivateBase : public QShared
+{
+public:
+ QMapPrivateBase() {
+ node_count = 0;
+ }
+ QMapPrivateBase( const QMapPrivateBase* _map) {
+ node_count = _map->node_count;
+ }
+
+ /**
+ * Implementations of basic tree algorithms
+ */
+ void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
+ void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
+ void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
+ QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
+ QMapNodeBase*& leftmost,
+ QMapNodeBase*& rightmost );
+
+ /**
+ * Variables
+ */
+ int node_count;
+};
+
+
+template <class Key, class T>
+class QMapPrivate : public QMapPrivateBase
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QMapIterator< Key, T > Iterator;
+ typedef QMapConstIterator< Key, T > ConstIterator;
+ typedef QMapNode< Key, T > Node;
+ typedef QMapNode< Key, T >* NodePtr;
+
+ /**
+ * Functions
+ */
+ QMapPrivate() {
+ header = new Node;
+ header->color = QMapNodeBase::Red; // Mark the header
+ header->parent = 0;
+ header->left = header->right = header;
+ }
+ QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
+ header = new Node;
+ header->color = QMapNodeBase::Red; // Mark the header
+ if ( _map->header->parent == 0 ) {
+ header->parent = 0;
+ header->left = header->right = header;
+ } else {
+ header->parent = copy( (NodePtr)(_map->header->parent) );
+ header->parent->parent = header;
+ header->left = header->parent->minimum();
+ header->right = header->parent->maximum();
+ }
+ }
+ ~QMapPrivate() { clear(); delete header; }
+
+ NodePtr copy( NodePtr p ) {
+ if ( !p )
+ return 0;
+ NodePtr n = new Node( *p );
+ n->color = p->color;
+ if ( p->left ) {
+ n->left = copy( (NodePtr)(p->left) );
+ n->left->parent = n;
+ } else {
+ n->left = 0;
+ }
+ if ( p->right ) {
+ n->right = copy( (NodePtr)(p->right) );
+ n->right->parent = n;
+ } else {
+ n->right = 0;
+ }
+ return n;
+ }
+
+ void clear() {
+ clear( (NodePtr)(header->parent) );
+ header->color = QMapNodeBase::Red;
+ header->parent = 0;
+ header->left = header->right = header;
+ node_count = 0;
+ }
+
+ void clear( NodePtr p ) {
+ while ( p != 0 ) {
+ clear( (NodePtr)p->right );
+ NodePtr y = (NodePtr)p->left;
+ delete p;
+ p = y;
+ }
+ }
+
+ Iterator begin() { return Iterator( (NodePtr)(header->left ) ); }
+ Iterator end() { return Iterator( header ); }
+ ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
+ ConstIterator end() const { return ConstIterator( header ); }
+
+ ConstIterator find(const Key& k) const {
+ QMapNodeBase* y = header; // Last node
+ QMapNodeBase* x = header->parent; // Root node.
+
+ while ( x != 0 ) {
+ // If as k <= key(x) go left
+ if ( !( key(x) < k ) ) {
+ y = x;
+ x = x->left;
+ } else {
+ x = x->right;
+ }
+ }
+
+ // Was k bigger/smaller then the biggest/smallest
+ // element of the tree ? Return end()
+ if ( y == header || k < key(y) )
+ return ConstIterator( header );
+ return ConstIterator( (NodePtr)y );
+ }
+
+ void remove( Iterator it ) {
+ NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
+ delete del;
+ --node_count;
+ }
+
+#ifdef QT_QMAP_DEBUG
+ void inorder( QMapNodeBase* x = 0, int level = 0 ){
+ if ( !x )
+ x = header->parent;
+ if ( x->left )
+ inorder( x->left, level + 1 );
+ //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
+ if ( x->right )
+ inorder( x->right, level + 1 );
+ }
+#endif
+
+ Iterator insertMulti(const Key& v){
+ QMapNodeBase* y = header;
+ QMapNodeBase* x = header->parent;
+ while (x != 0){
+ y = x;
+ x = ( v < key(x) ) ? x->left : x->right;
+ }
+ return insert(x, y, v);
+ }
+
+ Iterator insertSingle( const Key& k ) {
+ // Search correct position in the tree
+ QMapNodeBase* y = header;
+ QMapNodeBase* x = header->parent;
+ bool result = TRUE;
+ while ( x != 0 ) {
+ result = ( k < key(x) );
+ y = x;
+ x = result ? x->left : x->right;
+ }
+ // Get iterator on the last not empty one
+ Iterator j( (NodePtr)y );
+ if ( result ) {
+ // Smaller then the leftmost one ?
+ if ( j == begin() ) {
+ return insert(x, y, k );
+ } else {
+ // Perhaps daddy is the right one ?
+ --j;
+ }
+ }
+ // Really bigger ?
+ if ( (j.node->key) < k )
+ return insert(x, y, k );
+ // We are going to replace a node
+ return j;
+ }
+
+ Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k ) {
+ NodePtr z = new Node( k );
+ if (y == header || x != 0 || k < key(y) ) {
+ y->left = z; // also makes leftmost = z when y == header
+ if ( y == header ) {
+ header->parent = z;
+ header->right = z;
+ } else if ( y == header->left )
+ header->left = z; // maintain leftmost pointing to min node
+ } else {
+ y->right = z;
+ if ( y == header->right )
+ header->right = z; // maintain rightmost pointing to max node
+ }
+ z->parent = y;
+ z->left = 0;
+ z->right = 0;
+ rebalance( z, header->parent );
+ ++node_count;
+ return Iterator(z);
+ }
+
+protected:
+ /**
+ * Helpers
+ */
+ const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
+
+ /**
+ * Variables
+ */
+ NodePtr header;
+};
+
+
+template<class Key, class T>
+class Q_EXPORT QMap
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QMapIterator< Key, T > Iterator;
+ typedef QMapConstIterator< Key, T > ConstIterator;
+ typedef T ValueType;
+ typedef QMapPrivate< Key, T > Priv;
+
+ /**
+ * API
+ */
+ QMap() { sh = new QMapPrivate< Key, T >; }
+ QMap( const QMap<Key,T>& m ) { sh = m.sh; sh->ref(); }
+ ~QMap() { if ( sh->deref() ) delete sh; }
+
+ QMap<Key,T>& operator= ( const QMap<Key,T>& m )
+ { m.sh->ref(); if ( sh->deref() ) delete sh; sh = m.sh; return *this; }
+
+ Iterator begin() { detach(); return sh->begin(); }
+ Iterator end() { detach(); return sh->end(); }
+ ConstIterator begin() const { return ((const Priv*)sh)->begin(); }
+ ConstIterator end() const { return ((const Priv*)sh)->end(); }
+
+ Iterator find ( const Key& k )
+ { detach(); return Iterator( sh->find( k ).node ); }
+ ConstIterator find ( const Key& k ) const
+ { return sh->find( k ); }
+ T& operator[] ( const Key& k ) {
+ detach(); QMapNode<Key,T>* p = sh->find( k ).node;
+ if ( p != sh->end().node ) return p->data;
+ return insert( k, T() ).data(); }
+ const T& operator[] ( const Key& k ) const
+ { return sh->find( k ).data(); }
+ bool contains ( const Key& k ) const
+ { return find( k ) != end(); }
+ //{ return sh->find( k ) != ((const Priv*)sh)->end(); }
+
+ uint count() const { return sh->node_count; }
+
+ bool isEmpty() const { return sh->node_count == 0; }
+
+ Iterator insert( const Key& key, const T& value ) {
+ detach();
+ Iterator it = sh->insertSingle( key );
+ it.data() = value;
+ return it;
+ }
+
+ void remove( Iterator it ) { detach(); sh->remove( it ); }
+ void remove( const Key& k ) {
+ detach();
+ Iterator it( sh->find( k ).node );
+ if ( it != end() )
+ sh->remove( it );
+ }
+
+ Iterator replace( const Key& k, const T& v ) {
+ remove( k );
+ return insert( k, v );
+ }
+
+ void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QMapPrivate<Key,T>; } }
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+ bool operator==( const QMap<Key,T>& ) const { return FALSE; }
+#endif
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QMapPrivate<Key,T>( sh ); } }
+
+ Priv* sh;
+};
+
+
+#ifndef QT_NO_DATASTREAM
+template<class Key, class T>
+inline QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
+ m.clear();
+ Q_UINT32 c;
+ s >> c;
+ for( Q_UINT32 i = 0; i < c; ++i ) {
+ Key k; T t;
+ s >> k >> t;
+ m.insert( k, t );
+ }
+ return s;
+}
+
+
+template<class Key, class T>
+inline QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
+ s << (Q_UINT32)m.count();
+ QMapConstIterator<Key,T> it = m.begin();
+ for( ; it != m.end(); ++it )
+ s << it.key() << it.data();
+ return s;
+}
+#endif
+
+#endif // QMAP_H
diff --git a/qtools/qmodules.h b/qtools/qmodules.h
new file mode 100644
index 0000000..08f0baf
--- /dev/null
+++ b/qtools/qmodules.h
@@ -0,0 +1,11 @@
+// These modules are licensed to you
+#define QT_MODULE_TOOLS
+#define QT_MODULE_KERNEL
+#define QT_MODULE_WIDGETS
+#define QT_MODULE_DIALOGS
+#define QT_MODULE_ICONVIEW
+#define QT_MODULE_WORKSPACE
+#define QT_MODULE_NETWORK
+#define QT_MODULE_CANVAS
+#define QT_MODULE_TABLE
+#define QT_MODULE_XML
diff --git a/qtools/qmutex.cpp b/qtools/qmutex.cpp
new file mode 100644
index 0000000..08a13bc
--- /dev/null
+++ b/qtools/qmutex.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdio.h>
+
+#include "qglobal.h"
+
+#include "qmutex.h"
+#include "qmutex_p.h"
+
+QMutex::QMutex() : d(new QMutexPrivate())
+{
+}
+
+QMutex::~QMutex()
+{
+ delete d;
+}
+
+void QMutex::lock()
+{
+ //printf("%p: QMutex::lock(): enter\n",this);
+ bool isLocked;
+ isLocked = d->contenders.testAndSet(0, 1);
+ if (!isLocked)
+ {
+ isLocked = d->contenders.fetchAndAdd(1)==0;
+ if (!isLocked)
+ {
+ // didn't get the lock, wait for it
+ //printf("%p: QMutex::lock(): wait() %d\n",this,(int)d->contenders);
+ d->wait();
+
+ // release lock
+ d->contenders.fetchAndAdd(-1);
+ }
+ }
+ //printf("%p: QMutex::lock(): leave\n",this);
+}
+
+bool QMutex::tryLock()
+{
+ bool isLocked = d->contenders.testAndSet(0, 1);
+ return isLocked;
+}
+
+void QMutex::unlock()
+{
+ //printf("%p: QMutex::unlock(): enter %d\n",this,(int)d->contenders);
+ if (!d->contenders.testAndSet(1, 0))
+ {
+ //printf("%p: QMutex::unlock(): wakeUp()\n",this);
+ d->wakeUp();
+ }
+ //printf("%p: QMutex::unlock(): leave\n",this);
+}
+
diff --git a/qtools/qmutex.h b/qtools/qmutex.h
new file mode 100644
index 0000000..d3d2ac0
--- /dev/null
+++ b/qtools/qmutex.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMUTEX_H
+#define QMUTEX_H
+
+#include "qglobal.h"
+
+class QMutexPrivate;
+
+class QMutex
+{
+public:
+ QMutex();
+ ~QMutex();
+
+ void lock();
+ bool tryLock();
+ void unlock();
+
+private:
+ QMutex(const QMutex &);
+ QMutex &operator=(const QMutex &);
+
+ QMutexPrivate *d;
+};
+
+class QMutexLocker
+{
+ public:
+ QMutexLocker(QMutex *m) : m_mutex(m)
+ {
+ m_mutex->lock();
+ }
+ ~QMutexLocker()
+ {
+ m_mutex->unlock();
+ }
+ QMutex *mutex() const { return m_mutex; }
+
+ private:
+ QMutex *m_mutex;
+};
+
+#endif // QMUTEX_H
diff --git a/qtools/qmutex_p.h b/qtools/qmutex_p.h
new file mode 100644
index 0000000..a47b407
--- /dev/null
+++ b/qtools/qmutex_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMUTEX_P_H
+#define QMUTEX_P_H
+
+#include "qglobal.h"
+
+#if defined(_OS_UNIX_) || defined(_OS_MAC_)
+#include <pthread.h>
+#elif defined(_OS_WIN32_)
+#include <windows.h>
+#endif
+
+class QAtomicInt
+{
+ public:
+ QAtomicInt(int v=0) : m_value(v) {}
+ bool testAndSet(int expectedValue,int newValue);
+ int fetchAndAdd(int valueToAdd);
+ operator int () const { return m_value; }
+ bool operator==(int value) const { return m_value == value; }
+ bool operator!=(int value) const { return m_value != value; }
+ bool operator!() const { return m_value == 0; }
+
+ private:
+ volatile int m_value;
+};
+
+class QMutexPrivate
+{
+public:
+ QMutexPrivate();
+ ~QMutexPrivate();
+
+ void wait();
+ void wakeUp();
+
+ QAtomicInt contenders;
+
+#if defined(_OS_UNIX_) || defined(_OS_MAC_)
+ volatile bool wakeup;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#elif defined(_OS_WIN32_)
+ HANDLE event;
+#else
+#error "unsupported platform"
+#endif
+};
+
+#endif // QMUTEX_P_H
diff --git a/qtools/qmutex_unix.cpp b/qtools/qmutex_unix.cpp
new file mode 100644
index 0000000..4fe9a58
--- /dev/null
+++ b/qtools/qmutex_unix.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <errno.h>
+#include <pthread.h>
+
+#include "qglobal.h"
+#include "qmutex.h"
+#include "qmutex_p.h"
+
+static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void report_error(int code, const char *where, const char *what)
+{
+ if (code != 0)
+ qWarning("%s: %s failure: %d", where, what, code);
+}
+
+
+QMutexPrivate::QMutexPrivate()
+ : contenders(0), wakeup(FALSE)
+{
+ report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init");
+ report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init");
+}
+
+QMutexPrivate::~QMutexPrivate()
+{
+ report_error(pthread_cond_destroy(&cond), "QMutex", "cv destroy");
+ report_error(pthread_mutex_destroy(&mutex), "QMutex", "mutex destroy");
+}
+
+void QMutexPrivate::wait()
+{
+ report_error(pthread_mutex_lock(&mutex), "QMutex::lock", "mutex lock");
+ int errorCode = 0;
+ while (!wakeup)
+ {
+ errorCode = pthread_cond_wait(&cond, &mutex);
+ if (errorCode)
+ {
+ report_error(errorCode, "QMutex::lock()", "cv wait");
+ }
+ }
+ wakeup = FALSE;
+ report_error(pthread_mutex_unlock(&mutex), "QMutex::lock", "mutex unlock");
+}
+
+void QMutexPrivate::wakeUp()
+{
+ report_error(pthread_mutex_lock(&mutex), "QMutex::unlock", "mutex lock");
+ wakeup = TRUE;
+ report_error(pthread_cond_signal(&cond), "QMutex::unlock", "cv signal");
+ report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock");
+}
+
+bool QAtomicInt::testAndSet(int expectedValue,int newValue)
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (m_value == expectedValue)
+ {
+ m_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+int QAtomicInt::fetchAndAdd(int valueToAdd)
+{
+ int returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = m_value;
+ m_value += valueToAdd;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
diff --git a/qtools/qmutex_win32.cpp b/qtools/qmutex_win32.cpp
new file mode 100644
index 0000000..2d662ea
--- /dev/null
+++ b/qtools/qmutex_win32.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <windows.h>
+
+#include "qmutex.h"
+#include "qmutex_p.h"
+
+QMutexPrivate::QMutexPrivate()
+ : contenders(0)
+{
+ event = CreateEvent(0, FALSE, FALSE, 0);
+ if (!event)
+ qWarning("QMutexPrivate::QMutexPrivate: Cannot create event");
+}
+
+QMutexPrivate::~QMutexPrivate()
+{
+ CloseHandle(event);
+}
+
+void QMutexPrivate::wait()
+{
+ WaitForSingleObject(event, INFINITE);
+}
+
+void QMutexPrivate::wakeUp()
+{
+ SetEvent(event);
+}
+
+//----------------------------------------------------------------------
+
+class QCriticalSection
+{
+ public:
+ QCriticalSection() { InitializeCriticalSection(§ion); }
+ ~QCriticalSection() { DeleteCriticalSection(§ion); }
+ void lock() { EnterCriticalSection(§ion); }
+ void unlock() { LeaveCriticalSection(§ion); }
+
+ private:
+ CRITICAL_SECTION section;
+};
+
+static QCriticalSection qAtomicCriticalSection;
+
+bool QAtomicInt::testAndSet(int expectedValue,int newValue)
+{
+ bool returnValue = false;
+ qAtomicCriticalSection.lock();
+ if (m_value == expectedValue)
+ {
+ m_value = newValue;
+ returnValue = true;
+ }
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+int QAtomicInt::fetchAndAdd(int valueToAdd)
+{
+ int returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = m_value;
+ m_value += valueToAdd;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
diff --git a/qtools/qptrdict.doc b/qtools/qptrdict.doc
new file mode 100644
index 0000000..bff6a15
--- /dev/null
+++ b/qtools/qptrdict.doc
@@ -0,0 +1,486 @@
+/****************************************************************************
+**
+**
+** QPtrDict and QPtrDictIterator class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QPtrDict documentation
+ *****************************************************************************/
+
+/*!
+ \class QPtrDict qptrdict.h
+ \brief The QPtrDict class is a template class that provides a dictionary based on \c void* keys.
+
+ \ingroup collection
+ \ingroup tools
+
+ QPtrDict is implemented as a template class. Define a
+ template instance QPtrDict\<X\> to create a dictionary that operates on
+ pointers to X, or X*.
+
+ A dictionary is a collection that associates an item with a key.
+ The key is used for inserting and looking up an item. QPtrDict has
+ \c void* keys.
+
+ The dictionary has very fast insertion and lookup.
+
+ Example:
+ \code
+ #include <qptrdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ int *a = new int[12];
+ int *b = new int[10];
+ int *c = new int[18];
+ int *d = new int[13];
+
+ QPtrDict<char> dict; // maps void* -> char*
+
+ dict.insert( a, "a is int[12]" ); // describe pointers
+ dict.insert( b, "b is int[10]" );
+ dict.insert( c, "c is int[18]" );
+
+ printf( "%s\n", dict[a] ); // print descriptions
+ printf( "%s\n", dict[b] );
+ printf( "%s\n", dict[c] );
+
+ if ( !dict[d] )
+ printf( "d not in dictionary\n" );
+ }
+ \endcode
+
+ Program output:
+ \code
+ a is int[12]
+ b is int[10]
+ c is int[18]
+ d not in dictionary
+ \endcode
+
+ The dictionary in our example maps \c int* keys to \c char* items.
+ QPtrDict implements the \link operator[] [] operator\endlink to lookup
+ an item.
+
+ QPtrDict is implemented by QGDict as a hash array with a fixed number of
+ entries. Each array entry points to a singly linked list of buckets, in
+ which the dictionary items are stored.
+
+ When an item is inserted with a key, the key is converted (hashed) to
+ an integer index into the hash array using the \c mod operation. The
+ item is inserted before the first bucket in the list of buckets.
+
+ Looking up an item is normally very fast. The key is again hashed to an
+ array index. Then QPtrDict scans the list of buckets and returns the item
+ found or null if the item was not found. You cannot insert null pointers
+ into a dictionary.
+
+ The size of the hash array is very important. In order to get good
+ performance, you should use a suitably large \link primes.html prime
+ number\endlink. Suitable means equal to or larger than the maximum
+ expected number of dictionary items.
+
+ Items with equal keys are allowed. When inserting two items with the
+ same key, only the last inserted item will be visible (last in, first out)
+ until it is removed.
+
+ Example:
+ \code
+ #include <qptrdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ QPtrDict<char> dict; // maps char* ==> char*
+
+ double *ptr = new double[28];
+ dict.insert( ptr, "first" );
+ dict.insert( ptr, "second" );
+
+ printf( "%s\n", dict[ptr] );
+ dict.remove( ptr );
+ printf( "%s\n", dict[ptr] );
+ }
+ \endcode
+
+ Program output:
+ \code
+ second
+ first
+ \endcode
+
+ The QPtrDictIterator class can traverse the dictionary contents, but only
+ in an arbitrary order. Multiple iterators may independently traverse the
+ same dictionary.
+
+ Calling setAutoDelete(TRUE) for a dictionary tells it to delete items
+ that are removed . The default is to not delete items when they are
+ removed.
+
+ When inserting an item into a dictionary, only the pointer is copied, not
+ the item itself. This is called a shallow copy. It is possible to make the
+ dictionary copy all of the item's data (known as a deep copy) when an
+ item is inserted. insert() calls the virtual function
+ QCollection::newItem() for the item to be inserted.
+ Inherit a dictionary and reimplement it if you want deep copies.
+
+ When removing a dictionary item, the virtual function
+ QCollection::deleteItem() is called. QPtrDict's default implementation
+ is to delete the item if auto-deletion is enabled.
+
+ \sa QPtrDictIterator, QDict, QAsciiDict, QIntDict,
+ \link collection.html Collection Classes\endlink
+*/
+
+
+/*!
+ \fn QPtrDict::QPtrDict( int size )
+ Constructs a dictionary using an internal hash array with the size
+ \e size.
+
+ Setting \e size to a suitably large \link primes.html prime number\endlink
+ (equal to or greater than the expected number of entries) makes the hash
+ distribution better and hence the loopup faster.
+*/
+
+/*!
+ \fn QPtrDict::QPtrDict( const QPtrDict<type> &dict )
+ Constructs a copy of \e dict.
+
+ Each item in \e dict are inserted into this dictionary.
+ Only the pointers are copied (shallow copy).
+*/
+
+/*!
+ \fn QPtrDict::~QPtrDict()
+ Removes all items from the dictionary and destroys it.
+
+ All iterators that access this dictionary will be reset.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn QPtrDict<type> &QPtrDict::operator=(const QPtrDict<type> &dict)
+ Assigns \e dict to this dictionary and returns a reference to this
+ dictionary.
+
+ This dictionary is first cleared, then each item in \e dict is inserted
+ into this dictionary.
+ Only the pointers are copied (shallow copy), unless newItem() has been
+ reimplemented().
+*/
+
+/*!
+ \fn uint QPtrDict::count() const
+ Returns the number of items in the dictionary.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn uint QPtrDict::size() const
+ Returns the size of the internal hash array (as specified in the
+ constructor).
+ \sa count()
+*/
+
+/*!
+ \fn void QPtrDict::resize( uint newsize )
+ Changes the size of the hashtable the \a newsize.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+
+/*!
+ \fn bool QPtrDict::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn void QPtrDict::insert( void *key, const type *item )
+ Inserts the \e key with the \e item into the dictionary.
+
+ The key does not have to be a unique dictionary key. If multiple items
+ are inserted with the same key, only the last item will be visible.
+
+ Null items are not allowed.
+
+ \sa replace()
+*/
+
+/*!
+ \fn void QPtrDict::replace( void *key, const type *item )
+ Replaces an item which has a key equal to \e key with \e item.
+
+ If the item does not already exist, it will be inserted.
+
+ Null items are not allowed.
+
+ Equivalent to:
+ \code
+ QPtrDict<char> dict;
+ ...
+ if ( dict.find(key) )
+ dict.remove( key );
+ dict.insert( key, item );
+ \endcode
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be replaced.
+
+ \sa insert()
+*/
+
+/*!
+ \fn bool QPtrDict::remove( void *key )
+ Removes the item associated with \e key from the dictionary.
+ Returns TRUE if successful, or FALSE if the key does not exist in the
+ dictionary.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be removed.
+
+ The removed item is deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that refer to the removed item will be set to
+ point to the next item in the dictionary traversing order.
+
+ \sa take(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QPtrDict::take( void *key )
+ Takes the item associated with \e key out of the dictionary without
+ deleting it (even if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled).
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be taken.
+
+ Returns a pointer to the item taken out, or null if the key does not
+ exist in the dictionary.
+
+ All dictionary iterators that refer to the taken item will be set to
+ point to the next item in the dictionary traversing order.
+
+ \sa remove(), clear(), setAutoDelete()
+*/
+
+/*!
+ \fn void QPtrDict::clear()
+ Removes all items from the dictionary.
+
+ The removed items are deleted if \link QCollection::setAutoDelete()
+ auto-deletion\endlink is enabled.
+
+ All dictionary iterators that access this dictionary will be reset.
+
+ \sa remove(), take(), setAutoDelete()
+*/
+
+/*!
+ \fn type *QPtrDict::find( void *key ) const
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the [] operator.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn type *QPtrDict::operator[]( void *key ) const
+ Returns the item associated with \e key, or null if the key does not
+ exist in the dictionary.
+
+ This function uses an internal hashing algorithm to optimize lookup.
+
+ If there are two or more items with equal keys, then the last inserted
+ of these will be found.
+
+ Equivalent to the find() function.
+
+ \sa find()
+*/
+
+/*!
+ \fn void QPtrDict::statistics() const
+ Debugging-only function that prints out the dictionary distribution
+ using qDebug().
+*/
+
+
+/*****************************************************************************
+ QPtrDictIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QPtrDictIterator qptrdict.h
+ \brief The QPtrDictIterator class provides an iterator for QPtrDict collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ QPtrDictIterator is implemented as a template class.
+ Define a template instance QPtrDictIterator\<X\> to create a
+ dictionary iterator that operates on QPtrDict\<X\> (dictionary of X*).
+
+ Example:
+ \code
+ #include <qptrdict.h>
+ #include <stdio.h>
+
+ void main()
+ {
+ int *a = new int[12];
+ int *b = new int[10];
+ int *c = new int[18];
+ int *d = new int[13];
+
+ QPtrDict<char> dict; // maps void* -> char*
+
+ dict.insert( a, "a is int[12]" ); // describe pointers
+ dict.insert( b, "b is int[10]" );
+ dict.insert( c, "c is int[18]" );
+
+ QPtrDictIterator<char> it( dict ); // iterator for dict
+
+ while ( it.current() ) {
+ printf( "%x -> %s\n", it.currentKey(), it.current() );
+ ++it;
+ }
+ }
+ \endcode
+
+ Program output:
+ \code
+ 804a788 -> a is int[12]
+ 804a7f0 -> c is int[18]
+ 804a7c0 -> b is int[10]
+ \endcode
+
+ Note that the traversal order is arbitrary, you are not guaranteed the
+ order above.
+
+ Multiple iterators may independently traverse the same dictionary.
+ A QPtrDict knows about all iterators that are operating on the dictionary.
+ When an item is removed from the dictionary, QPtrDict update all
+ iterators that are referring the removed item to point to the next item
+ in the traversing order.
+
+ \sa QPtrDict, \link collection.html Collection Classes\endlink
+*/
+
+/*!
+ \fn QPtrDictIterator::QPtrDictIterator( const QPtrDict<type> &dict )
+ Constructs an iterator for \e dict. The current iterator item is
+ set to point on the first item in the \e dict.
+*/
+
+/*!
+ \fn QPtrDictIterator::~QPtrDictIterator()
+ Destroys the iterator.
+*/
+
+/*!
+ \fn uint QPtrDictIterator::count() const
+ Returns the number of items in the dictionary this iterator operates on.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn bool QPtrDictIterator::isEmpty() const
+ Returns TRUE if the dictionary is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn type *QPtrDictIterator::toFirst()
+ Sets the current iterator item to point to the first item in the
+ dictionary and returns a pointer to the item.
+ If the dictionary is empty it sets the current item to null and
+ returns null.
+*/
+
+/*!
+ \fn QPtrDictIterator::operator type *() const
+ Cast operator. Returns a pointer to the current iterator item.
+ Same as current().
+*/
+
+/*!
+ \fn type *QPtrDictIterator::current() const
+ Returns a pointer to the current iterator item.
+*/
+
+/*!
+ \fn void *QPtrDictIterator::currentKey() const
+ Returns the key for the current iterator item.
+*/
+
+/*!
+ \fn type *QPtrDictIterator::operator()()
+ Makes the succeeding item current and returns the original current item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QPtrDictIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns the new current
+ item.
+
+ If the current iterator item was the last item in the dictionary or if it
+ was null, null is returned.
+*/
+
+/*!
+ \fn type *QPtrDictIterator::operator+=( uint jump )
+ Sets the current item to the item \e jump positions after the current item,
+ and returns a pointer to that item.
+
+ If that item is beyond the last item or if the dictionary is empty,
+ it sets the current item to null and returns null.
+*/
diff --git a/qtools/qptrdict.h b/qtools/qptrdict.h
new file mode 100644
index 0000000..c075e30
--- /dev/null
+++ b/qtools/qptrdict.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+**
+** Definition of QPtrDict template class
+**
+** Created : 970415
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QPTRDICT_H
+#define QPTRDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QPtrDict : public QGDict
+{
+public:
+ QPtrDict(int size=17) : QGDict(size,PtrKey,0,0) {}
+ QPtrDict( const QPtrDict<type> &d ) : QGDict(d) {}
+ ~QPtrDict() { clear(); }
+ QPtrDict<type> &operator=(const QPtrDict<type> &d)
+ { return (QPtrDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+ void insert( void *k, const type *d )
+ { QGDict::look_ptr(k,(Item)d,1); }
+ void replace( void *k, const type *d )
+ { QGDict::look_ptr(k,(Item)d,2); }
+ bool remove( void *k ) { return QGDict::remove_ptr(k); }
+ type *take( void *k ) { return (type*)QGDict::take_ptr(k); }
+ type *find( void *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ptr(k,0,0); }
+ type *operator[]( void *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ptr(k,0,0); }
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QPtrDict<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QPtrDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QPtrDictIterator : public QGDictIterator
+{
+public:
+ QPtrDictIterator(const QPtrDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QPtrDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ void *currentKey() const { return QGDictIterator::getKeyPtr(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QPTRDICT_H
diff --git a/qtools/qqueue.h b/qtools/qqueue.h
new file mode 100644
index 0000000..94bc130
--- /dev/null
+++ b/qtools/qqueue.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+**
+** Definition of QQueue template/macro class
+**
+** Created : 920917
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QQUEUE_H
+#define QQUEUE_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class QQueue : private QGList
+{
+public:
+ QQueue() {}
+ QQueue( const QQueue<type> &q ) : QGList(q) {}
+ ~QQueue() { clear(); }
+ QQueue<type>& operator=(const QQueue<type> &q)
+ { return (QQueue<type>&)QGList::operator=(q); }
+ bool autoDelete() const { return QCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ void enqueue( const type *d ) { QGList::append(Item(d)); }
+ type *dequeue() { return (type *)QGList::takeFirst();}
+ bool remove() { return QGList::removeFirst(); }
+ void clear() { QGList::clear(); }
+ type *head() const { return (type *)QGList::cfirst(); }
+ operator type *() const { return (type *)QGList::cfirst(); }
+ type *current() const { return (type *)QGList::cfirst(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QQUEUE_H
diff --git a/qtools/qregexp.cpp b/qtools/qregexp.cpp
new file mode 100644
index 0000000..d958f0a
--- /dev/null
+++ b/qtools/qregexp.cpp
@@ -0,0 +1,1092 @@
+/****************************************************************************
+**
+**
+** Implementation of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qregexp.h"
+#include <ctype.h>
+#include <stdlib.h>
+
+// NOT REVISED
+/*!
+ \class QRegExp qregexp.h
+ \ingroup tools
+ \ingroup misc
+ \brief The QRegExp class provides pattern matching using regular
+ expressions or wildcards.
+
+ QRegExp knows these regexp primitives:
+ <ul plain>
+ <li><dfn>c</dfn> matches the character 'c'
+ <li><dfn>.</dfn> matches any character
+ <li><dfn>^</dfn> matches start of input
+ <li><dfn>$</dfn> matches end of input
+ <li><dfn>[]</dfn> matches a defined set of characters - see below.
+ <li><dfn>a*</dfn> matches a sequence of zero or more a's
+ <li><dfn>a+</dfn> matches a sequence of one or more a's
+ <li><dfn>a?</dfn> matches an optional a
+ <li><dfn>\c</dfn> escape code for matching special characters such
+ as \, [, *, +, . etc.
+ <li><dfn>\t</dfn> matches the TAB character (9)
+ <li><dfn>\n</dfn> matches newline (10)
+ <li><dfn>\r</dfn> matches return (13)
+ <li><dfn>\s</dfn> matches a white space (defined as any character
+ for which QChar::isSpace() returns TRUE. This includes at least
+ ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12(FF), 13 (CR) and 32
+ (Space)).
+ <li><dfn>\d</dfn> matches a digit (defined as any character for
+ which QChar::isDigit() returns TRUE. This includes at least ASCII
+ characters '0'-'9').
+ <li><dfn>\x1f6b</dfn> matches the character with unicode point U1f6b
+ (hexadecimal 1f6b). \x0012 will match the ASCII/Latin1 character
+ 0x12 (18 decimal, 12 hexadecimal).
+ <li><dfn>\022</dfn> matches the ASCII/Latin1 character 022 (18
+ decimal, 22 octal).
+ </ul>
+
+ In wildcard mode, it only knows four primitives:
+ <ul plain>
+ <li><dfn>c</dfn> matches the character 'c'
+ <li><dfn>?</dfn> matches any character
+ <li><dfn>*</dfn> matches any sequence of characters
+ <li><dfn>[]</dfn> matches a defined set of characters - see below.
+ </ul>
+
+ QRegExp supports Unicode both in the pattern strings and in the
+ strings to be matched.
+
+ When writing regular expressions in C++ code, remember that C++
+ processes \ characters. So in order to match e.g. a "." character,
+ you must write "\\." in C++ source, not "\.".
+
+ A character set matches a defined set of characters. For example,
+ [BSD] matches any of 'B', 'D' and 'S'. Within a character set, the
+ special characters '.', '*', '?', '^', '$', '+' and '[' lose their
+ special meanings. The following special characters apply:
+ <ul plain>
+ <li><dfn>^</dfn> When placed first in the list, changes the
+ character set to match any character \e not in the list. To include
+ the character '^' itself in the set, escape it or place it anywhere
+ but first.
+ <li><dfn>-</dfn> Defines a range of characters. To include the
+ character '-' itself in the set, escape it or place it last.
+ <li><dfn>]</dfn> Ends the character set definition. To include the
+ character ']' itself in the set, escape it or place it first (but
+ after the negation operator '^', if present)
+ </ul>
+ Thus, [a-zA-Z0-9.] matches upper and lower case ASCII letters,
+ digits and dot; and [^\s] matches everything except white space.
+
+ \bug Case insensitive matching is not supported for non-ASCII/Latin1
+ (non-8bit) characters. Any character with a non-zero QChar.row() is
+ matched case sensitively even if the QRegExp is in case insensitive
+ mode.
+
+ \note In Qt 3.0, the language of regular expressions will contain
+ five more special characters, namely '(', ')', '{', '|' and '}'. To
+ ease porting, it's a good idea to escape these characters with a
+ backslash in all the regular expressions you'll write from now on.
+*/
+
+
+//
+// The regexp pattern is internally represented as an array of uints,
+// each element containing an 16-bit character or a 32-bit code
+// (listed below). User-defined character classes (e.g. [a-zA-Z])
+// are encoded as this:
+// uint no: 1 2 3 ...
+// value: CCL | n from | to from | to
+//
+// where n is the (16-bit) number of following range definitions and
+// from and to define the ranges inclusive. from <= to is always true,
+// otherwise it is a built-in charclass (Pxx, eg \s - PWS). Single
+// characters in the class are coded as from==to. Negated classes
+// (e.g. [^a-z]) use CCN instead of CCL.
+
+const uint END = 0x00000000;
+const uint PWS = 0x10010000; // predef charclass: whitespace (\s)
+const uint PDG = 0x10020000; // predef charclass: digit (\d)
+const uint CCL = 0x20010000; // character class []
+const uint CCN = 0x20020000; // neg character class [^]
+const uint CHR = 0x40000000; // character
+const uint BOL = 0x80010000; // beginning of line ^
+const uint EOL = 0x80020000; // end of line $
+const uint BOW = 0x80030000; // beginning of word \<
+const uint EOW = 0x80040000; // end of word \>
+const uint ANY = 0x80050000; // any character .
+const uint CLO = 0x80070000; // Kleene closure *
+const uint OPT = 0x80080000; // Optional closure ?
+
+const uint MCC = 0x20000000; // character class bitmask
+const uint MCD = 0xffff0000; // code mask
+const uint MVL = 0x0000ffff; // value mask
+
+//
+// QRegExp::error codes (internal)
+//
+
+const int PatOk = 0; // pattern ok
+const int PatNull = 1; // no pattern defined
+const int PatSyntax = 2; // pattern syntax error
+const int PatOverflow = 4; // pattern too long
+
+
+/*****************************************************************************
+ QRegExp member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an empty regular expression.
+*/
+
+QRegExp::QRegExp()
+{
+ rxdata = 0;
+ cs = TRUE;
+ wc = FALSE;
+ error = PatOk;
+}
+
+/*!
+ Constructs a regular expression.
+
+ \arg \e pattern is the regular expression pattern string.
+ \arg \e caseSensitive specifies whether or not to use case sensitive
+ matching.
+ \arg \e wildcard specifies whether the pattern string should be used for
+ wildcard matching (also called globbing expression), normally used for
+ matching file names.
+
+ \sa setWildcard()
+*/
+
+QRegExp::QRegExp( const QCString &pattern, bool caseSensitive, bool wildcard )
+{
+ rxstring = pattern;
+ rxdata = 0;
+ cs = caseSensitive;
+ wc = wildcard;
+ compile();
+}
+
+/*!
+ Constructs a regular expression which is a copy of \e r.
+ \sa operator=(const QRegExp&)
+*/
+
+QRegExp::QRegExp( const QRegExp &r )
+{
+ rxstring = r.pattern();
+ rxdata = 0;
+ cs = r.caseSensitive();
+ wc = r.wildcard();
+ compile();
+}
+
+/*!
+ Destructs the regular expression and cleans up its internal data.
+*/
+
+QRegExp::~QRegExp()
+{
+ if ( rxdata ) // Avoid purify complaints
+ delete [] rxdata;
+}
+
+/*!
+ Copies the regexp \e r and returns a reference to this regexp.
+ The case sensitivity and wildcard options are copied, as well.
+*/
+
+QRegExp &QRegExp::operator=( const QRegExp &r )
+{
+ rxstring = r.rxstring;
+ cs = r.cs;
+ wc = r.wc;
+ compile();
+ return *this;
+}
+
+/*!
+ \obsolete
+ Consider using setPattern() instead of this method.
+
+ Sets the pattern string to \e pattern and returns a reference to this regexp.
+ The case sensitivity or wildcard options do not change.
+*/
+
+QRegExp &QRegExp::operator=( const QCString &pattern )
+{
+ rxstring = pattern;
+ compile();
+ return *this;
+}
+
+
+/*!
+ Returns TRUE if this regexp is equal to \e r.
+
+ Two regexp objects are equal if they have equal pattern strings,
+ case sensitivity options and wildcard options.
+*/
+
+bool QRegExp::operator==( const QRegExp &r ) const
+{
+ return rxstring == r.rxstring && cs == r.cs && wc == r.wc;
+}
+
+/*!
+ \fn bool QRegExp::operator!=( const QRegExp &r ) const
+
+ Returns TRUE if this regexp is \e not equal to \e r.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QRegExp::isEmpty() const
+ Returns TRUE if the regexp is empty.
+*/
+
+/*!
+ \fn bool QRegExp::isValid() const
+ Returns TRUE if the regexp is valid, or FALSE if it is invalid.
+
+ The pattern "[a-z" is an example of an invalid pattern, since it lacks a
+ closing bracket.
+*/
+
+
+/*!
+ \fn bool QRegExp::wildcard() const
+ Returns TRUE if wildcard mode is on, otherwise FALSE. \sa setWildcard().
+*/
+
+/*!
+ Sets the wildcard option for the regular expression. The default
+ is FALSE.
+
+ Setting \e wildcard to TRUE makes it convenient to match filenames
+ instead of plain text.
+
+ For example, "qr*.cpp" matches the string "qregexp.cpp" in wildcard mode,
+ but not "qicpp" (which would be matched in normal mode).
+
+ \sa wildcard()
+*/
+
+void QRegExp::setWildcard( bool wildcard )
+{
+ if ( wildcard != wc ) {
+ wc = wildcard;
+ compile();
+ }
+}
+
+/*!
+ \fn bool QRegExp::caseSensitive() const
+
+ Returns TRUE if case sensitivity is enabled, otherwise FALSE. The
+ default is TRUE.
+
+ \sa setCaseSensitive()
+*/
+
+/*!
+ Enables or disables case sensitive matching.
+
+ In case sensitive mode, "a.e" matches "axe" but not "Axe".
+
+ See also: caseSensitive()
+*/
+
+void QRegExp::setCaseSensitive( bool enable )
+{
+ if ( cs != enable ) {
+ cs = enable;
+ compile();
+ }
+}
+
+
+/*!
+ \fn QCString QRegExp::pattern() const
+ Returns the pattern string of the regexp.
+*/
+
+
+/*!
+ \fn void QRegExp::setPattern(const QCString & pattern)
+ Sets the pattern string to \a pattern and returns a reference to this regexp.
+ The case sensitivity or wildcard options do not change.
+*/
+
+static inline bool iswordchar( int x )
+{
+ return isalnum(x) || x == '_'; //# Only 8-bit support
+}
+
+
+/*!
+ \internal
+ Match character class
+*/
+
+static bool matchcharclass( uint *rxd, char c )
+{
+ uint *d = rxd;
+ uint clcode = *d & MCD;
+ bool neg = clcode == CCN;
+ if ( clcode != CCL && clcode != CCN)
+ qWarning("QRegExp: Internal error, please report to qt-bugs at trolltech.com");
+ uint numFields = *d & MVL;
+ uint cval = (unsigned char)c; //(((uint)(c.row())) << 8) | ((uint)c.cell());
+ bool found = FALSE;
+ for ( int i = 0; i < (int)numFields; i++ ) {
+ d++;
+ if ( *d == PWS && isspace(c) ) {
+ found = TRUE;
+ break;
+ }
+ if ( *d == PDG && isdigit(c) ) {
+ found = TRUE;
+ break;
+ }
+ else {
+ uint from = ( *d & MCD ) >> 16;
+ uint to = *d & MVL;
+ if ( (cval >= from) && (cval <= to) ) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ return neg ? !found : found;
+}
+
+
+
+/*
+ Internal: Recursively match string.
+*/
+
+static int matchstring( uint *rxd, const char *str, uint strlength,
+ const char *bol, bool cs )
+{
+ const char *p = str;
+ const char *start = p;
+ uint pl = strlength;
+ uint *d = rxd;
+
+ //### in all cases here: handle pl == 0! (don't read past strlen)
+ while ( *d ) {
+ if ( *d & CHR ) { // match char
+ if ( !pl )
+ return -1;
+ char c = *d;
+ if ( !cs /*&& !c.row()*/ ) { // case insensitive, #Only 8bit
+ if ( tolower(*p) != c )
+ return -1;
+ p++;
+ pl--;
+ } else { // case insensitive
+ if ( *p != c )
+ return -1;
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ if ( !pl )
+ return -1;
+ if ( !matchcharclass( d, *p ) )
+ return -1;
+ p++;
+ pl--;
+ d += (*d & MVL) + 1;
+ }
+ else switch ( *d++ ) {
+ case PWS: // match whitespace
+ if ( !pl || !isspace(*p) )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case PDG: // match digits
+ if ( !pl || !isdigit(*p) )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case ANY: // match anything
+ if ( !pl )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case BOL: // match beginning of line
+ if ( p != bol )
+ return -1;
+ break;
+ case EOL: // match end of line
+ if ( pl )
+ return -1;
+ break;
+ case BOW: // match beginning of word
+ if ( !iswordchar(*p) || (p > bol && iswordchar(*(p-1)) ) )
+ return -1;
+ break;
+ case EOW: // match end of word
+ if ( iswordchar(*p) || p == bol || !iswordchar(*(p-1)) )
+ return -1;
+ break;
+ case CLO: // Kleene closure
+ {
+ const char *first_p = p;
+ if ( *d & CHR ) { // match char
+ char c = *d;
+ if ( !cs /*&& !c.row()*/ ) { // case insensitive, #only 8bit
+ while ( pl /*&& !p->row()*/ && tolower(*p)==c ) {
+ p++;
+ pl--;
+ }
+ }
+ else { // case sensitive
+ while ( pl && *p == c ) {
+ p++;
+ pl--;
+ }
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ while( pl && matchcharclass( d, *p ) ) {
+ p++;
+ pl--;
+ }
+ d += (*d & MVL) + 1;
+ }
+ else if ( *d == PWS ) {
+ while ( pl && isspace(*p) ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == PDG ) {
+ while ( pl && isdigit(*p) ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == ANY ) {
+ p += pl;
+ pl = 0;
+ d++;
+ }
+ else {
+ return -1; // error
+ }
+ d++; // skip CLO's END
+ while ( p >= first_p ) { // go backwards
+ int end = matchstring( d, p, pl, bol, cs );
+ if ( end >= 0 )
+ return ( (int)(p - start) ) + end;
+ if ( !p )
+ return -1;
+ --p;
+ ++pl;
+ }
+ }
+ return -1;
+ case OPT: // optional closure
+ {
+ const char *first_p = p;
+ if ( *d & CHR ) { // match char
+ char c = *d;
+ if ( !cs /*&& !c.row()*/ ) { // case insensitive, #only 8bit
+ if ( pl && /*!p->row() &&*/ tolower(*p) == c ) {
+ p++;
+ pl--;
+ }
+ }
+ else { // case sensitive
+ if ( pl && *p == c ) {
+ p++;
+ pl--;
+ }
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ if ( pl && matchcharclass( d, *p ) ) {
+ p++;
+ pl--;
+ }
+ d += (*d & MVL) + 1;
+ }
+ else if ( *d == PWS ) {
+ if ( pl && isspace(*p) ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == PDG ) {
+ if ( pl && isdigit(*p) ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == ANY ) {
+ if ( pl ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else {
+ return -1; // error
+ }
+ d++; // skip OPT's END
+ while ( p >= first_p ) { // go backwards
+ int end = matchstring( d, p, pl, bol, cs );
+ if ( end >= 0 )
+ return ( (int)(p - start) ) + end;
+ if ( !p )
+ return -1;
+ --p;
+ ++pl;
+ }
+ }
+ return -1;
+
+ default: // error
+ return -1;
+ }
+ }
+ return (int)(p - start);
+}
+
+
+/*!
+ \internal
+ Recursively match string.
+*/
+
+// This is obsolete now, but since it is protected (not private), it
+// is still implemented on the off-chance that somebody has made a
+// class derived from QRegExp and calls this directly.
+// Qt 3.0: Remove this?
+
+#if 0
+const char *QRegExp::matchstr( uint *rxd, const QChar *str, uint strlength,
+ const QChar *bol ) const
+{
+ int len = matchstring( rxd, str, strlength, bol, cs );
+ if ( len < 0 )
+ return 0;
+ return str + len;
+}
+#endif
+
+/*!
+ Attempts to match in \e str, starting from position \e index.
+ Returns the position of the match, or -1 if there was no match.
+
+ If \e len is not a null pointer, the length of the match is stored in
+ \e *len.
+
+ If \e indexIsStart is TRUE (the default), the position \e index in
+ the string will match the start-of-input primitive (^) in the
+ regexp, if present. Otherwise, position 0 in \e str will match.
+
+ Example:
+ \code
+ QRegExp r("[0-9]*\\.[0-9]+"); // matches floating point
+ int len;
+ r.match("pi = 3.1416", 0, &len); // returns 5, len == 6
+ \endcode
+
+ \note In Qt 3.0, this function will be replaced by find().
+*/
+
+int QRegExp::match( const QCString &str, int index, int *len,
+ bool indexIsStart ) const
+{
+ if ( !isValid() || isEmpty() )
+ return -1;
+ if ( str.length() < (uint)index )
+ return -1;
+ const char *start = str.data();
+ const char *p = start + index;
+ uint pl = str.length() - index;
+ uint *d = rxdata;
+ int ep = -1;
+
+ if ( *d == BOL ) { // match from beginning of line
+ ep = matchstring( d, p, pl, indexIsStart ? p : start, cs );
+ } else {
+ if ( *d & CHR ) {
+ char c = *d;
+ if ( !cs /*&& !c.row()*/ ) { // case sensitive, # only 8bit
+ while ( pl && ( /*p->row() ||*/ tolower(*p) != c ) ) {
+ p++;
+ pl--;
+ }
+ } else { // case insensitive
+ while ( pl && *p != c ) {
+ p++;
+ pl--;
+ }
+ }
+ }
+ while( 1 ) { // regular match
+ ep = matchstring( d, p, pl, indexIsStart ? start+index : start, cs );
+ if ( ep >= 0 )
+ break;
+ if ( !pl )
+ break;
+ p++;
+ pl--;
+ }
+ }
+ if ( len )
+ *len = ep >= 0 ? ep : 0; // No match -> 0, for historical reasons
+ return ep >= 0 ? (int)(p - start) : -1; // return index;
+}
+
+/*! \fn int QRegExp::find( const QCString& str, int index )
+
+ Attempts to match in \e str, starting from position \e index.
+ Returns the position of the match, or -1 if there was no match.
+
+ \sa match()
+*/
+
+//
+// Translate wildcard pattern to standard regexp pattern.
+// Ex: *.cpp ==> ^.*\.cpp$
+//
+
+static QCString wc2rx( const QCString &pattern )
+{
+ int patlen = (int)pattern.length();
+ QCString wcpattern("^");
+
+ char c;
+ for( int i = 0; i < patlen; i++ ) {
+ c = pattern[i];
+ switch ( (char)c ) {
+ case '*': // '*' ==> '.*'
+ wcpattern += '.';
+ break;
+ case '?': // '?' ==> '.'
+ c = '.';
+ break;
+ case '.': // quote special regexp chars
+ case '+':
+ case '\\':
+ case '$':
+ case '^':
+ wcpattern += '\\';
+ break;
+ case '[':
+ if ( (char)pattern[i+1] == '^' ) { // don't quote '^' after '['
+ wcpattern += '[';
+ c = pattern[i+1];
+ i++;
+ }
+ break;
+ }
+ wcpattern += c;
+
+ }
+ wcpattern += '$';
+ return wcpattern; // return new regexp pattern
+}
+
+
+//
+// Internal: Get char value and increment pointer.
+//
+
+static uint char_val( const char **str, uint *strlength ) // get char value
+{
+ const char *p = *str;
+ uint pl = *strlength;
+ uint len = 1;
+ uint v = 0;
+ if ( (char)*p == '\\' ) { // escaped code
+ p++;
+ pl--;
+ if ( !pl ) { // it is just a '\'
+ (*str)++;
+ (*strlength)--;
+ return '\\';
+ }
+ len++; // length at least 2
+ int i;
+ char c;
+ char ch = tolower((char)*p);
+ switch ( ch ) {
+ case 'b': v = '\b'; break; // bell
+ case 'f': v = '\f'; break; // form feed
+ case 'n': v = '\n'; break; // newline
+ case 'r': v = '\r'; break; // return
+ case 't': v = '\t'; break; // tab
+ case 's': v = PWS; break; // whitespace charclass
+ case 'd': v = PDG; break; // digit charclass
+ case '<': v = BOW; break; // word beginning matcher
+ case '>': v = EOW; break; // word ending matcher
+
+ case 'x': { // hex code
+ p++;
+ pl--;
+ for ( i = 0; (i < 4) && pl; i++ ) { //up to 4 hex digits
+ c = tolower((char)*p);
+ bool a = ( c >= 'a' && c <= 'f' );
+ if ( (c >= '0' && c <= '9') || a ) {
+ v <<= 4;
+ v += a ? 10 + c - 'a' : c - '0';
+ len++;
+ }
+ else {
+ break;
+ }
+ p++;
+ pl--;
+ }
+ }
+ break;
+
+ default: {
+ if ( ch >= '0' && ch <= '7' ) { //octal code
+ len--;
+ for ( i = 0; (i < 3) && pl; i++ ) { // up to 3 oct digits
+ c = (char)*p;
+ if ( c >= '0' && c <= '7' ) {
+ v <<= 3;
+ v += c - '0';
+ len++;
+ }
+ else {
+ break;
+ }
+ p++;
+ pl--;
+ }
+ }
+ else { // not an octal number
+ v = (uint)*p; //(((uint)(p->row())) << 8) | ((uint)p->cell());
+ }
+ }
+ }
+ } else {
+ v = (uint)*p; //(((uint)(p->row())) << 8) | ((uint)p->cell());
+ }
+ *str += len;
+ *strlength -= len;
+ return v;
+}
+
+
+#if 0 //defined(DEBUG)
+static uint *dump( uint *p )
+{
+ while ( *p != END ) {
+ if ( *p & CHR ) {
+ uchar uc = (uchar)*p;
+ char c = (char)uc;
+ uint u = (uint)uc; //(((uint)(uc.row())) << 8) | ((uint)uc.cell());
+ qDebug( "\tCHR\tU%04x (%c)", u, (c ? c : ' '));
+ p++;
+ }
+ else if ( *p & MCC ) {
+ uint clcode = *p & MCD;
+ uint numFields = *p & MVL;
+ if ( clcode == CCL )
+ qDebug( "\tCCL\t%i", numFields );
+ else if ( clcode == CCN )
+ qDebug( "\tCCN\t%i", numFields );
+ else
+ qDebug("coding error!");
+ for ( int i = 0; i < (int)numFields; i++ ) {
+ p++;
+ if ( *p == PWS )
+ qDebug( "\t\tPWS" );
+ else if ( *p == PDG )
+ qDebug( "\t\tPDG" );
+ else {
+ uint from = ( *p & MCD ) >> 16;
+ uint to = *p & MVL;
+ char fc = (char)from;
+ char tc = (char)to;
+ qDebug( "\t\tU%04x (%c) - U%04x (%c)", from,
+ (fc ? fc : ' '), to, (tc ? tc : ' ') );
+ }
+ }
+ p++;
+ }
+ else switch ( *p++ ) {
+ case PWS:
+ qDebug( "\tPWS" );
+ break;
+ case PDG:
+ qDebug( "\tPDG" );
+ break;
+ case BOL:
+ qDebug( "\tBOL" );
+ break;
+ case EOL:
+ qDebug( "\tEOL" );
+ break;
+ case BOW:
+ qDebug( "\tBOW" );
+ break;
+ case EOW:
+ qDebug( "\tEOW" );
+ break;
+ case ANY:
+ qDebug( "\tANY" );
+ break;
+ case CLO:
+ qDebug( "\tCLO" );
+ p = dump( p );
+ break;
+ case OPT:
+ qDebug( "\tOPT" );
+ p = dump( p );
+ break;
+ }
+ }
+ qDebug( "\tEND" );
+ return p+1;
+}
+#endif // DEBUG
+
+
+static const int maxlen = 1024; // max length of regexp array
+static uint rxarray[ maxlen ]; // tmp regexp array
+
+/*!
+ \internal
+ Compiles the regular expression and stores the result in rxdata.
+ The 'error' flag is set to non-zero if an error is detected.
+ NOTE! This function is not reentrant!
+*/
+
+void QRegExp::compile()
+{
+ if ( rxdata ) { // delete old data
+ delete [] rxdata;
+ rxdata = 0;
+ }
+ if ( rxstring.isEmpty() ) { // no regexp pattern set
+ error = PatNull;
+ return;
+ }
+
+ error = PatOk; // assume pattern is ok
+
+ QCString pattern;
+ if ( wc )
+ pattern = wc2rx(rxstring);
+ else
+ pattern = rxstring;
+ const char *start = pattern.data(); // pattern pointer
+ const char *p = start; // pattern pointer
+ uint pl = pattern.length();
+ uint *d = rxarray; // data pointer
+ uint *prev_d = 0;
+
+#define GEN(x) *d++ = (x)
+
+ while ( pl ) {
+ char ch = (char)*p;
+ switch ( ch ) {
+
+ case '^': // beginning of line
+ prev_d = d;
+ GEN( p == start ? BOL : (CHR | ch) );
+ p++;
+ pl--;
+ break;
+
+ case '$': // end of line
+ prev_d = d;
+ GEN( pl == 1 ? EOL : (CHR | ch) );
+ p++;
+ pl--;
+ break;
+
+ case '.': // any char
+ prev_d = d;
+ GEN( ANY );
+ p++;
+ pl--;
+ break;
+
+ case '[': // character class
+ {
+ prev_d = d;
+ p++;
+ pl--;
+ if ( !pl ) {
+ error = PatSyntax;
+ return;
+ }
+ bool firstIsEscaped = ( (char)*p == '\\' );
+ uint cch = char_val( &p, &pl );
+ if ( cch == '^' && !firstIsEscaped ) { // negate!
+ GEN( CCN );
+ if ( !pl ) {
+ error = PatSyntax;
+ return;
+ }
+ cch = char_val( &p, &pl );
+ } else {
+ GEN( CCL );
+ }
+ uint numFields = 0;
+ while ( pl ) {
+ if ((pl>2) && ((char)*p == '-') && ((char)*(p+1) != ']')) {
+ // Found a range
+ char_val( &p, &pl ); // Read the '-'
+ uint cch2 = char_val( &p, &pl ); // Read the range end
+ if ( cch > cch2 ) { // swap start and stop
+ int tmp = cch;
+ cch = cch2;
+ cch2 = tmp;
+ }
+ GEN( (cch << 16) | cch2 ); // from < to
+ numFields++;
+ }
+ else {
+ // Found a single character
+ if ( cch & MCD ) // It's a code; will not be mistaken
+ GEN( cch ); // for a range, since from > to
+ else
+ GEN( (cch << 16) | cch ); // from == to range
+ numFields++;
+ }
+ if ( d >= rxarray + maxlen ) { // pattern too long
+ error = PatOverflow;
+ return;
+ }
+ if ( !pl ) { // At least ']' should be left
+ error = PatSyntax;
+ return;
+ }
+ bool nextIsEscaped = ( (char)*p == '\\' );
+ cch = char_val( &p, &pl );
+ if ( cch == (uint)']' && !nextIsEscaped )
+ break;
+ if ( !pl ) { // End, should have seen ']'
+ error = PatSyntax;
+ return;
+ }
+ }
+ *prev_d |= numFields; // Store number of fields
+ }
+ break;
+
+ case '*': // Kleene closure, or
+ case '+': // positive closure, or
+ case '?': // optional closure
+ {
+ if ( prev_d == 0 ) { // no previous expression
+ error = PatSyntax; // empty closure
+ return;
+ }
+ switch ( *prev_d ) { // test if invalid closure
+ case BOL:
+ case BOW:
+ case EOW:
+ case CLO:
+ case OPT:
+ error = PatSyntax;
+ return;
+ }
+ int ddiff = (int)(d - prev_d);
+ if ( *p == '+' ) { // convert to Kleene closure
+ if ( d + ddiff >= rxarray + maxlen ) {
+ error = PatOverflow; // pattern too long
+ return;
+ }
+ memcpy( d, prev_d, ddiff*sizeof(uint) );
+ d += ddiff;
+ prev_d += ddiff;
+ }
+ memmove( prev_d+1, prev_d, ddiff*sizeof(uint) );
+ *prev_d = ch == '?' ? OPT : CLO;
+ d++;
+ GEN( END );
+ p++;
+ pl--;
+ }
+ break;
+
+ default:
+ {
+ prev_d = d;
+ uint cv = char_val( &p, &pl );
+ if ( cv & MCD ) { // It's a code
+ GEN( cv );
+ }
+ else {
+ if ( !cs && cv <= 0xff ) // #only 8bit support
+ cv = tolower( cv );
+ GEN( CHR | cv );
+ }
+ }
+ }
+ if ( d >= rxarray + maxlen ) { // oops!
+ error = PatOverflow; // pattern too long
+ return;
+ }
+ }
+ GEN( END );
+ int len = (int)(d - rxarray);
+ rxdata = new uint[ len ]; // copy from rxarray to rxdata
+ CHECK_PTR( rxdata );
+ memcpy( rxdata, rxarray, len*sizeof(uint) );
+#if defined(DEBUG)
+ //dump( rxdata ); // uncomment this line for debugging
+#endif
+}
diff --git a/qtools/qregexp.h b/qtools/qregexp.h
new file mode 100644
index 0000000..4bb0230
--- /dev/null
+++ b/qtools/qregexp.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+**
+** Definition of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QREGEXP_H
+#define QREGEXP_H
+
+#ifndef QT_H
+#include "qcstring.h"
+#endif // QT_H
+
+
+class Q_EXPORT QRegExp
+{
+public:
+ QRegExp();
+ QRegExp( const QCString &, bool caseSensitive=TRUE, bool wildcard=FALSE );
+ QRegExp( const QRegExp & );
+ ~QRegExp();
+ QRegExp &operator=( const QRegExp & );
+ QRegExp &operator=( const QCString &pattern );
+
+ bool operator==( const QRegExp & ) const;
+ bool operator!=( const QRegExp &r ) const
+ { return !(this->operator==(r)); }
+
+ bool isEmpty() const { return rxdata == 0; }
+ bool isValid() const { return error == 0; }
+
+ bool caseSensitive() const { return cs; }
+ void setCaseSensitive( bool );
+
+ bool wildcard() const { return wc; }
+ void setWildcard( bool );
+
+ QCString pattern() const { return rxstring; }
+ // ### in Qt 3.0, provide a real implementation
+ void setPattern( const QCString& pattern )
+ { operator=( pattern ); }
+
+ int match( const QCString &str, int index=0, int *len=0,
+ bool indexIsStart = TRUE ) const;
+ int find( const QCString& str, int index )
+ { return match( str, index ); }
+
+protected:
+ void compile();
+ const char *matchstr( uint *, const char *, uint, const char * ) const;
+
+private:
+ QCString rxstring; // regular expression pattern
+ uint *rxdata; // compiled regexp pattern
+ int error; // error status
+ bool cs; // case sensitive
+ bool wc; // wildcard
+};
+
+
+#endif // QREGEXP_H
diff --git a/qtools/qshared.h b/qtools/qshared.h
new file mode 100644
index 0000000..79fab7b
--- /dev/null
+++ b/qtools/qshared.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+**
+** Definition of QShared struct
+**
+** Created : 940112
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSHARED_H
+#define QSHARED_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#endif // QT_H
+
+
+struct QShared
+{
+ QShared() { count = 1; }
+ void ref() { count++; }
+ bool deref() { return !--count; }
+ uint count;
+};
+
+
+#endif // QSHARED_H
diff --git a/qtools/qsortedlist.doc b/qtools/qsortedlist.doc
new file mode 100644
index 0000000..6f16f19
--- /dev/null
+++ b/qtools/qsortedlist.doc
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+**
+** QSortedList documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QSortedList documentation
+ *****************************************************************************/
+
+/*!
+ \class QSortedList qsortedlist.h
+ \brief The QSortedList class provides a list sorted by operator< and operator==
+
+ \ingroup collection
+ \ingroup tools
+
+ If you want to sort a QList you have to reimplement the
+ QGList::compareItems() method. If the elements of your list support
+ operator<() and operator==() then you can use QSortedList instead.
+ Its compareItems() calls operator<() and operator==() and returns an
+ appropriate result.
+
+ Otherwise, this is as QList.
+
+ \sa QList, \link collection.html Collection Classes\endlink
+*/
+
+
+/*!
+ \fn QSortedList::QSortedList()
+ Constructs an empty list.
+*/
+
+/*!
+ \fn QSortedList::QSortedList( const QSortedList<type> &list )
+ Constructs a copy of \e list.
+
+ Each item in \e list is copied to this new list.
+*/
+
+/*!
+ \fn QSortedList::~QSortedList()
+ Removes all items from the list and destroys the list.
+
+ All list iterators that access this list will be reset.
+*/
+
+/*!
+ \fn QSortedList<type>& QSortedList::operator=(const QSortedList<type>& list)
+ Assigns \e list to this list and returns a reference to this list.
+
+ This list is first cleared, then each item in \e list is
+ appended to this list. Only the pointers are copied
+ (shallow copy), unless newItem() has been reimplemented().
+*/
+
+/*!
+ \fn int QSortedList::compareItems( QCollection::Item s1, QCollection::Item s2 )
+
+ \reimp
+
+ This reimplementation uses operator< and operator== to compare.
+*/
diff --git a/qtools/qsortedlist.h b/qtools/qsortedlist.h
new file mode 100644
index 0000000..aeadd90
--- /dev/null
+++ b/qtools/qsortedlist.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+**
+** Definition of QList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSORTEDLIST_H
+#define QSORTEDLIST_H
+
+#ifndef QT_H
+#include "qlist.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QSortedList : public QList<type>
+{
+public:
+ QSortedList() {}
+ QSortedList( const QSortedList<type> &l ) : QList<type>(l) {}
+ ~QSortedList() { clear(); }
+ QSortedList<type> &operator=(const QSortedList<type> &l)
+ { return (QSortedList<type>&)QList<type>::operator=(l); }
+
+ virtual int compareItems( QCollection::Item s1, QCollection::Item s2 )
+ { if ( *((type*)s1) == *((type*)s2) ) return 0; return ( *((type*)s1) < *((type*)s2) ? -1 : 1 ); }
+};
+
+#endif
diff --git a/qtools/qstack.doc b/qtools/qstack.doc
new file mode 100644
index 0000000..ece1e2a
--- /dev/null
+++ b/qtools/qstack.doc
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+**
+** QStack class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QStack documentation
+ *****************************************************************************/
+
+/*!
+ \class QStack qstack.h
+ \brief The QStack class is a template class that provides a stack.
+
+ \ingroup collection
+ \ingroup tools
+
+ QStack is implemented as a template class. Define a template
+ instance QStack\<X\> to create a stack that operates on pointers to
+ X, or X*.
+
+ A stack is a Last In, First Out (LIFO) structure. Items are added to
+ the top of the stack with push() and retrieved from the top
+ with pop().
+
+ \sa \link collection.html Collection Classes\endlink
+*/
+
+/*! \fn QStack::QStack ()
+ Creates and empty stack.
+*/
+
+/*! \fn QStack::QStack (const QStack<type>& s)
+ Creates a stack by making a shallow copy of another stack.
+*/
+
+/*! \fn QStack::~QStack ()
+ Destroys the stack. All items will be deleted if autoDelete() is TRUE.
+*/
+
+/*! \fn QStack<type>& QStack::operator= (const QStack<type>& s)
+ Sets the contents of this stack by making a shallow copy of another stack.
+ Elements currently in this stack will be deleted if autoDelete() is TRUE.
+*/
+
+/*! \fn bool QStack::isEmpty () const
+ Returns TRUE is the stack contains no elements to be \link pop() popped\endlink.
+*/
+
+/*! \fn void QStack::push (const type* d)
+ Adds an element to the top of the stack. Last in, first out.
+*/
+
+/*! \fn type* QStack::pop ()
+ Removes the top item from the stack and returns it.
+*/
+
+/*! \fn bool QStack::remove ()
+ Removes the top item from the stack and deletes it if
+ autoDelete() is TRUE. Returns TRUE if there was an item to pop.
+
+ \sa clear()
+*/
+
+/*! \fn void QStack::clear()
+ Removes all items from the stack, deleting them if
+ autoDelete() is TRUE.
+
+ \sa remove()
+*/
+
+/*! \fn uint QStack::count() const
+ Returns the number of items in the stack.
+
+ \sa isEmpty()
+*/
+
+/*! \fn type* QStack::top () const
+ Returns a reference to the top item on the stack (most recently pushed).
+ The stack is not changed.
+*/
+
+/*! \fn QStack::operator type* ()const
+ Returns a reference to the top item on the stack (most recently pushed).
+ The stack is not changed.
+*/
+
+/*! \fn type* QStack::current () const
+ Returns a reference to the top item on the stack (most recently pushed).
+ The stack is not changed.
+*/
+
+/*! \fn bool QStack::autoDelete() const
+
+ The same as QCollection::autoDelete().
+
+ \sa setAutoDelete()
+*/
+
+/*! \fn void QStack::setAutoDelete( bool enable )
+
+ The same as QCollection::setAutoDelete().
+
+ \sa autoDelete()
+*/
diff --git a/qtools/qstack.h b/qtools/qstack.h
new file mode 100644
index 0000000..c84d8d2
--- /dev/null
+++ b/qtools/qstack.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+**
+** Definition of QStack template/macro class
+**
+** Created : 920917
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSTACK_H
+#define QSTACK_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class QStack : private QGList
+{
+public:
+ QStack() {}
+ QStack( const QStack<type> &s ) : QGList(s) {}
+ ~QStack() { clear(); }
+ QStack<type> &operator=(const QStack<type> &s)
+ { return (QStack<type>&)QGList::operator=(s); }
+ bool autoDelete() const { return QCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ void push( const type *d ) { QGList::insertAt(0,Item(d)); }
+ type *pop() { return (type *)QGList::takeFirst(); }
+ bool remove() { return QGList::removeFirst(); }
+ void clear() { QGList::clear(); }
+ type *bottom() const { return (type *)QGList::clast(); }
+ type *top() const { return (type *)QGList::cfirst(); }
+ operator type *() const { return (type *)QGList::cfirst(); }
+ type *current() const { return (type *)QGList::cfirst(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QSTACK_H
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
new file mode 100644
index 0000000..fa8f1d3
--- /dev/null
+++ b/qtools/qstring.cpp
@@ -0,0 +1,15319 @@
+/****************************************************************************
+**
+**
+** Implementation of the QString class and related Unicode functions
+**
+** Created : 920722
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+// Don't define it while compiling this module, or USERS of Qt will
+// not be able to link.
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+
+#include "qstring.h"
+#include "qregexp.h"
+#include "qdatastream.h"
+#include "qtextcodec.h"
+#include "qstack.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/* -------------------------------------------------------------------------
+ * unicode information
+ * these tables are generated from the unicode reference file
+ * ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html
+ *
+ * Lars Knoll <knoll at mpi-hd.mpg.de>
+ * -------------------------------------------------------------------------
+ */
+
+/* Perl script to generate (run perl -x tools/qstring.cpp)
+
+#!perl
+
+sub numberize
+{
+ my(%r, $n, $id);
+ for $id ( @_ ) {
+ $id="" if $id eq "EMPTY";
+ $r{$id}=$n++;
+ }
+ return %r;
+}
+
+
+# Code to integer mappings...
+#
+%category_code = numberize(qw{
+ EMPTY
+ Mn Mc Me
+ Nd Nl No
+ Zs Zl Zp
+ Cc Cf Cs Co Cn
+
+ Lu Ll Lt Lm Lo
+ Pc Pd Ps Pe Pi Pf Po
+ Sm Sc Sk So
+});
+%bidi_category_code = numberize(qw{
+ L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN});
+%character_decomposition_tag = numberize(qw{
+ <single> <canonical> <font> <noBreak> <initial> <medial>
+ <final> <isolated> <circle> <super> <sub> <vertical>
+ <wide> <narrow> <small> <square> <compat> <fraction>
+});
+%mirrored_code = numberize(qw{N Y});
+
+%joining_code = numberize(qw{U D R C});
+
+# Read data into hashes...
+#
+open IN, "UnicodeData.txt";
+$position = 1;
+while (<IN>) {
+ @fields = split /;/;
+ $code = shift @fields;
+ for $n (qw{
+ name category combining_class bidi_category
+ character_decomposition decimal_digit_value digit_value
+ numeric_value mirrored oldname comment
+ uppercase lowercase titlecase})
+ {
+ $id = shift @fields;
+ $codes = "${n}_code";
+ if ( defined %$codes && defined $$codes{$id} ) {
+ $id = $$codes{$id};
+ }
+ ${$n}{$code}=$id;
+ }
+ $decomp = $character_decomposition{$code};
+ if ( length $decomp == 0 ) {
+ $decomp = "<single>";
+ }
+ if (substr($decomp, 0, 1) ne '<') {
+ $decomp = "<canonical> " . $decomp;
+ }
+ @fields = split(" ", $decomp);
+ $tag = shift @fields;
+ $tag = $character_decomposition_tag{$tag};
+ $decomp = join( ", 0x", @fields );
+ $decomp = "0x".$decomp;
+ $decomposition{$code} = $decomp;
+ $decomposition_tag{$code} = $tag;
+ $decomposition_pos{$code} = $position;
+ $len = scalar(@fields);
+ $decomposition_len{$code} = $len;
+
+# we use canonical decompositions longer than 1 char
+# and all arabic ligatures for the ligature table
+ if(($len > 1 and $tag == 1) or ($tag > 3 and $tag < 8)) {
+# ligature to add...
+ $start = shift @fields;
+ $ligature{$start} = $ligature{$start}." ".$code;
+ }
+
+# adjust position
+ if($len != 0) {
+ $position += $len + 3;
+ }
+
+
+}
+
+open IN2, "ArabicShaping.txt";
+$position = 1;
+while (<IN2>) {
+ @fields = split /;/;
+ $code = shift @fields;
+ $dummy = shift @fields;
+ $join = shift @fields;
+ $join =~ s/ //g;
+ $join = $joining_code{$join};
+ $joining{$code}=$join;
+}
+
+# Build pages...
+#
+$rowtable_txt =
+ "static const Q_UINT8 * const unicode_info[256] = {";
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $info = $category{$code};
+ $info = 0 if !defined $info;
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $row{$txt};
+ if ( !defined $therow ) {
+ $size+=256;
+ $therow = "ui_".sprintf("%02X",$row);
+ $rowtext{$therow} =
+ "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
+ $row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+print "// START OF GENERATED DATA\n\n";
+print "#ifndef QT_NO_UNICODETABLES\n\n";
+
+# Print pages...
+#
+for $r ( sort keys %rowtext ) {
+ print $rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+# Build decomposition tables
+#
+$rowtable_txt =
+ "static const Q_UINT16 * const decomposition_info[256] = {";
+$table_txt =
+ "static const Q_UINT16 decomposition_map[] = {\n 0,\n";
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $txt .= "\n " if $cell%8 == 0;
+ if( $decomposition_tag{$code} != 0 ) {
+ $txt .= " $decomposition_pos{$code},";
+ $table_txt .= " $decomposition_tag{$code},";
+ $table_txt .= " 0x$code,";
+ $table_txt .= " $decomposition{$code}, 0,\n";
+ $size += 2 * $decomposition_len{$code} + 6;
+ } else {
+ $txt .= " 0,";
+ }
+ }
+ $therow = $row{$txt};
+ if ( !defined $therow ) {
+ $size+=512;
+ $therow = "di_".sprintf("%02X",$row);
+ $dec_rowtext{$therow} =
+ "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
+ $row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print decomposition tables
+#
+print "$table_txt\n};\n\n";
+for $r ( sort keys %dec_rowtext ) {
+ print $dec_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+
+# build ligature tables
+#
+$size = 0;
+$position = 1;
+$rowtable_txt =
+ "static const Q_UINT16 * const ligature_info[256] = {";
+$table_txt =
+ "static const Q_UINT16 ligature_map[] = {\n 0,\n";
+for $lig_row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$lig_row,$cell);
+ $txt .= "\n " if $cell%8 == 0;
+ if( defined $ligature{$code} ) {
+ $txt .= " $position,";
+ @ligature = split(" ", $ligature{$code});
+# we need to sort ligatures according to their length.
+# long ones have to come first!
+ @ligature_sort = sort { $decomposition_len{$b} <=> $decomposition_len{$a} } @ligature;
+# now replace each code by it's position in
+# the decomposition map.
+ undef(@lig_pos);
+ for $n (@ligature_sort) {
+ push(@lig_pos, $decomposition_pos{$n});
+ }
+# debug info
+ if( 0 ) {
+ print "ligatures: $ligature{$code}\n";
+ $sort = join(" ", @ligature_sort);
+ print "sorted : $sort\n";
+ }
+ $lig = join(", ", @lig_pos);
+ $table_txt .= " $lig, 0,\n";
+ $size += 2 * scalar(@ligature) + 2;
+ $position += scalar(@ligature) + 1;
+ } else {
+ $txt .= " 0,";
+ }
+ }
+ $therow = $lig_row{$txt};
+ if ( !defined $therow ) {
+ $size+=512;
+ $therow = "li_".sprintf("%02X",$lig_row);
+ $lig_rowtext{$therow} =
+ "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
+ $lig_row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $lig_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print ligature tables
+#
+print "$table_txt\n};\n\n";
+for $r ( sort keys %lig_rowtext ) {
+ print $lig_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+
+
+# Build direction/joining/mirrored pages...
+#
+$rowtable_txt =
+ "static const Q_UINT8 * const direction_info[256] = {";
+for $dir_row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$dir_row,$cell);
+ $dir = $bidi_category{$code};
+ $dir = 0 if !defined $dir;
+ $join = $joining{$code};
+ $join = 0 if !defined $join;
+ $mirr = $mirrored{$code};
+ $mirr = 0 if !defined $mirr;
+ $info = $dir + 32*$join + 128*$mirr;
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $dir_row{$txt};
+ if ( !defined $therow ) {
+ $size+=256;
+ $therow = "dir_".sprintf("%02X",$dir_row);
+ $dir_rowtext{$therow} =
+ "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
+ $dir_row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $dir_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print pages...
+#
+for $r ( sort keys %dir_rowtext ) {
+ print $dir_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+
+
+print "#endif\n\n";
+print "// END OF GENERATED DATA\n\n";
+
+
+__END__
+
+*/
+
+
+// START OF GENERATED DATA
+
+static const Q_UINT8 ui_00[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 26, 26, 28, 26, 26, 26,
+ 22, 23, 26, 27, 26, 21, 26, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 27, 27, 27, 26,
+ 26, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 22, 26, 23, 29, 20,
+ 29, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 27, 23, 27, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 28, 28, 28, 28, 30, 30,
+ 29, 30, 16, 24, 27, 21, 30, 29,
+ 30, 27, 6, 6, 29, 16, 30, 26,
+ 29, 6, 16, 25, 6, 6, 6, 26,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 27,
+ 15, 15, 15, 15, 15, 15, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 27,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+};
+
+#ifndef QT_NO_UNICODETABLES
+
+static const Q_UINT8 ui_01[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 15, 16, 15, 16, 15, 16, 16,
+ 16, 15, 15, 16, 15, 16, 15, 15,
+ 16, 15, 15, 15, 16, 16, 15, 15,
+ 15, 15, 16, 15, 15, 16, 15, 15,
+ 15, 16, 16, 16, 15, 15, 16, 15,
+ 15, 16, 15, 16, 15, 16, 15, 15,
+ 16, 15, 16, 16, 15, 16, 15, 15,
+ 16, 15, 15, 15, 16, 15, 16, 15,
+ 15, 16, 16, 19, 15, 16, 16, 16,
+ 19, 19, 19, 19, 15, 17, 16, 15,
+ 17, 16, 15, 17, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 15, 17, 16, 15, 16, 15, 15,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+};
+
+static const Q_UINT8 ui_02[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 0, 0, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 29, 29, 18, 18, 18, 18, 18,
+ 18, 18, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 18, 18, 18, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 18, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_03[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29, 29, 0, 0,
+ 0, 0, 18, 0, 0, 0, 26, 0,
+ 0, 0, 0, 0, 29, 29, 15, 26,
+ 15, 15, 15, 0, 15, 0, 15, 15,
+ 16, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 16, 16, 15, 15, 15, 16, 16, 16,
+ 0, 0, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 16, 16, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_04[] = {
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 30, 1, 1, 1, 1, 0,
+ 3, 3, 0, 0, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 15, 16, 15, 16, 0, 0, 15,
+ 16, 0, 0, 15, 16, 0, 0, 0,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 0, 0,
+ 15, 16, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 0,
+ 0, 18, 26, 26, 26, 26, 26, 26,
+ 0, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 26, 21, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 1, 26, 1,
+ 26, 1, 1, 26, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 19, 19, 19, 26, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 26, 0, 0, 0, 26,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 18, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 26, 26, 0, 0,
+ 1, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 26, 19, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 1,
+ 1, 1, 1, 1, 1, 18, 18, 1,
+ 1, 30, 1, 1, 1, 1, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 19, 19, 19, 30, 30, 0,
+};
+
+static const Q_UINT8 ui_07[] = {
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 0, 11,
+ 19, 1, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_08[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_09[] = {
+ 0, 1, 1, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 1, 0, 0,
+ 19, 1, 1, 1, 1, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 1, 1, 26, 26, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 26, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 0, 0, 0, 19, 19,
+ 19, 19, 0, 0, 1, 0, 2, 2,
+ 2, 1, 1, 1, 1, 0, 0, 2,
+ 2, 0, 0, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 19, 19, 0, 19,
+ 19, 19, 1, 1, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 19, 19, 28, 28, 6, 6, 6, 6,
+ 6, 6, 30, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0A[] = {
+ 0, 0, 1, 0, 0, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 19, 19, 0,
+ 19, 19, 0, 0, 1, 0, 2, 2,
+ 2, 1, 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 19, 19, 19, 0, 19, 0,
+ 0, 0, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1, 19, 19, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 0, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 2,
+ 2, 1, 1, 1, 1, 1, 0, 1,
+ 1, 2, 0, 2, 2, 1, 0, 0,
+ 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 0, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0B[] = {
+ 0, 1, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 0, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 1,
+ 2, 1, 1, 1, 0, 0, 0, 2,
+ 2, 0, 0, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 0, 19, 19, 0, 19,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 0, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 0, 19, 19, 0, 19, 0, 19, 19,
+ 0, 0, 0, 19, 19, 0, 0, 0,
+ 19, 19, 19, 0, 0, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 19,
+ 19, 19, 0, 0, 0, 0, 2, 2,
+ 1, 2, 2, 0, 0, 0, 2, 2,
+ 2, 0, 2, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 6, 6, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0C[] = {
+ 0, 2, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 1, 1,
+ 1, 2, 2, 2, 2, 0, 1, 1,
+ 1, 0, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 2, 1,
+ 2, 2, 2, 2, 2, 0, 1, 2,
+ 2, 0, 2, 2, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 19, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0D[] = {
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 2, 2,
+ 2, 1, 1, 1, 0, 0, 2, 2,
+ 2, 0, 2, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 1, 0, 0, 0, 0, 2,
+ 2, 2, 1, 1, 1, 0, 1, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0E[] = {
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 1, 19, 19, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 28,
+ 19, 19, 19, 19, 19, 19, 18, 1,
+ 1, 1, 1, 1, 1, 1, 1, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 19, 0, 19, 0, 0, 19,
+ 19, 0, 19, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 19, 19, 19, 19,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 0, 19, 19, 19, 0, 19, 0, 19,
+ 0, 0, 19, 19, 0, 19, 19, 19,
+ 19, 1, 19, 19, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 19, 0, 0,
+ 19, 19, 19, 19, 19, 0, 18, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 19, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_0F[] = {
+ 19, 30, 30, 30, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 30, 30, 30, 30, 30,
+ 1, 1, 30, 30, 30, 30, 30, 30,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 1, 30, 1,
+ 30, 1, 22, 23, 22, 23, 2, 2,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 26, 1, 1,
+ 19, 19, 19, 19, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 30, 30,
+ 30, 30, 30, 30, 30, 30, 1, 30,
+ 30, 30, 30, 30, 30, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_10[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 0, 19, 19, 0, 2, 1, 1, 1,
+ 1, 2, 1, 0, 0, 0, 1, 1,
+ 2, 1, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 26, 26, 26, 26,
+ 19, 19, 19, 19, 19, 19, 2, 2,
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 0, 26, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_11[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_12[] = {
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+};
+
+static const Q_UINT8 ui_13[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 0, 26, 26, 26, 26, 26, 26, 26,
+ 26, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_14[] = {
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+};
+
+static const Q_UINT8 ui_15[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+};
+
+static const Q_UINT8 ui_16[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 26, 26, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 22, 23, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 26, 26, 26, 6, 6,
+ 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_17[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 26, 26, 26, 26,
+ 26, 26, 26, 28, 26, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_18[] = {
+ 26, 26, 26, 26, 26, 26, 21, 26,
+ 26, 26, 26, 11, 11, 11, 11, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 18, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_1E[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 16, 16,
+ 16, 16, 16, 16, 0, 0, 0, 0,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_1F[] = {
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 15, 0, 15, 0, 15, 0, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 16, 29,
+ 29, 29, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 29, 29,
+ 16, 16, 16, 16, 0, 0, 16, 16,
+ 15, 15, 15, 15, 0, 29, 29, 29,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 29, 29, 29,
+ 0, 0, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 29, 0,
+};
+
+static const Q_UINT8 ui_20[] = {
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 11, 11, 11, 11,
+ 21, 21, 21, 21, 21, 21, 26, 26,
+ 24, 25, 22, 24, 24, 25, 22, 24,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 8, 9, 11, 11, 11, 11, 11, 7,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 24, 25, 26, 26, 26, 26, 20,
+ 20, 26, 26, 26, 27, 22, 23, 0,
+ 26, 26, 26, 26, 26, 26, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 11, 11, 11, 11, 11,
+ 6, 0, 0, 0, 6, 6, 6, 6,
+ 6, 6, 27, 27, 27, 22, 23, 16,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 27, 27, 27, 22, 23, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 3,
+ 3, 1, 3, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_21[] = {
+ 30, 30, 15, 30, 30, 30, 30, 15,
+ 30, 30, 16, 15, 15, 15, 16, 16,
+ 15, 15, 15, 16, 30, 15, 30, 30,
+ 30, 15, 15, 15, 15, 15, 30, 30,
+ 30, 30, 30, 30, 15, 30, 15, 30,
+ 15, 30, 15, 15, 15, 15, 30, 16,
+ 15, 15, 30, 15, 16, 19, 19, 19,
+ 19, 16, 30, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 27, 27, 27, 27, 27, 30, 30, 30,
+ 30, 30, 27, 27, 30, 30, 30, 30,
+ 27, 30, 30, 27, 30, 30, 27, 30,
+ 30, 30, 30, 30, 30, 30, 27, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 27, 27,
+ 30, 30, 27, 30, 27, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_22[] = {
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_23[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 27, 27, 27, 27, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 27, 27, 30, 30, 30, 30, 30, 30,
+ 30, 22, 23, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_24[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_25[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 27,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 27, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_26[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 27,
+ 30, 30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_27[] = {
+ 0, 30, 30, 30, 30, 0, 30, 30,
+ 30, 30, 0, 0, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 30, 0, 30,
+ 30, 30, 30, 0, 0, 0, 30, 0,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_28[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+};
+
+static const Q_UINT8 ui_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 0, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_2F[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_30[] = {
+ 7, 26, 26, 26, 30, 18, 19, 5,
+ 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 30, 30, 22, 23, 22, 23,
+ 22, 23, 22, 23, 21, 22, 23, 23,
+ 30, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 1, 1, 1, 1, 1, 1,
+ 21, 18, 18, 18, 18, 18, 30, 30,
+ 5, 5, 5, 0, 0, 0, 30, 30,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 0, 1, 1, 29, 29, 18, 18, 0,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 20, 18, 18, 18, 0,
+};
+
+static const Q_UINT8 ui_31[] = {
+ 0, 0, 0, 0, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 30, 30, 6, 6, 6, 6, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_32[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 30,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+};
+
+static const Q_UINT8 ui_33[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+};
+
+static const Q_UINT8 ui_34[] = {
+ 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_4D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_9F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_A4[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 0, 0, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 0, 30, 30, 30, 0, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_D7[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 19, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_D8[] = {
+ 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_DB[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12,
+ 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12,
+};
+
+static const Q_UINT8 ui_DF[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12,
+};
+
+static const Q_UINT8 ui_E0[] = {
+ 13, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_F8[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13,
+};
+
+static const Q_UINT8 ui_FA[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_FB[] = {
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 16, 16, 16, 16,
+ 0, 0, 0, 0, 0, 19, 1, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 27, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 0, 19, 0,
+ 19, 19, 0, 19, 19, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+};
+
+static const Q_UINT8 ui_FD[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 22, 23,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 26, 21, 21, 20, 20, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22,
+ 23, 22, 23, 22, 23, 0, 0, 0,
+ 0, 26, 26, 26, 26, 20, 20, 20,
+ 26, 26, 26, 0, 26, 26, 26, 26,
+ 21, 22, 23, 22, 23, 22, 23, 26,
+ 26, 26, 27, 21, 27, 27, 27, 0,
+ 26, 28, 26, 26, 0, 0, 0, 0,
+ 19, 19, 19, 0, 19, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 11,
+};
+
+static const Q_UINT8 ui_FF[] = {
+ 0, 26, 26, 26, 28, 26, 26, 26,
+ 22, 23, 26, 27, 26, 21, 26, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 27, 27, 27, 26,
+ 26, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 22, 26, 23, 29, 20,
+ 29, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 27, 23, 27, 0,
+ 0, 26, 22, 23, 26, 20, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 18, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 0, 0, 0,
+ 28, 28, 27, 29, 30, 28, 28, 0,
+ 30, 27, 27, 27, 27, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 11, 11, 11, 30, 30, 0, 0,
+};
+
+static const Q_UINT8 * const unicode_info[256] = {
+ ui_00, ui_01, ui_02, ui_03, ui_04, ui_05, ui_06, ui_07,
+ ui_08, ui_09, ui_0A, ui_0B, ui_0C, ui_0D, ui_0E, ui_0F,
+ ui_10, ui_11, ui_12, ui_13, ui_14, ui_15, ui_16, ui_17,
+ ui_18, ui_08, ui_08, ui_08, ui_08, ui_08, ui_1E, ui_1F,
+ ui_20, ui_21, ui_22, ui_23, ui_24, ui_25, ui_26, ui_27,
+ ui_28, ui_08, ui_08, ui_08, ui_08, ui_08, ui_2E, ui_2F,
+ ui_30, ui_31, ui_32, ui_33, ui_34, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_4D, ui_34, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_9F,
+ ui_15, ui_15, ui_15, ui_15, ui_A4, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_34, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_D7,
+ ui_D8, ui_08, ui_08, ui_DB, ui_D8, ui_08, ui_08, ui_DF,
+ ui_E0, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_F8, ui_15, ui_FA, ui_FB, ui_15, ui_FD, ui_FE, ui_FF,
+};
+// 15616 bytes
+
+static const Q_UINT16 decomposition_map [] = {
+ 0,
+ 3, 0x00A0, 0x0020, 0,
+ 16, 0x00A8, 0x0020, 0x0308, 0,
+ 9, 0x00AA, 0x0061, 0,
+ 16, 0x00AF, 0x0020, 0x0304, 0,
+ 9, 0x00B2, 0x0032, 0,
+ 9, 0x00B3, 0x0033, 0,
+ 16, 0x00B4, 0x0020, 0x0301, 0,
+ 16, 0x00B5, 0x03BC, 0,
+ 16, 0x00B8, 0x0020, 0x0327, 0,
+ 9, 0x00B9, 0x0031, 0,
+ 9, 0x00BA, 0x006F, 0,
+ 17, 0x00BC, 0x0031, 0x2044, 0x0034, 0,
+ 17, 0x00BD, 0x0031, 0x2044, 0x0032, 0,
+ 17, 0x00BE, 0x0033, 0x2044, 0x0034, 0,
+ 1, 0x00C0, 0x0041, 0x0300, 0,
+ 1, 0x00C1, 0x0041, 0x0301, 0,
+ 1, 0x00C2, 0x0041, 0x0302, 0,
+ 1, 0x00C3, 0x0041, 0x0303, 0,
+ 1, 0x00C4, 0x0041, 0x0308, 0,
+ 1, 0x00C5, 0x0041, 0x030A, 0,
+ 1, 0x00C7, 0x0043, 0x0327, 0,
+ 1, 0x00C8, 0x0045, 0x0300, 0,
+ 1, 0x00C9, 0x0045, 0x0301, 0,
+ 1, 0x00CA, 0x0045, 0x0302, 0,
+ 1, 0x00CB, 0x0045, 0x0308, 0,
+ 1, 0x00CC, 0x0049, 0x0300, 0,
+ 1, 0x00CD, 0x0049, 0x0301, 0,
+ 1, 0x00CE, 0x0049, 0x0302, 0,
+ 1, 0x00CF, 0x0049, 0x0308, 0,
+ 1, 0x00D1, 0x004E, 0x0303, 0,
+ 1, 0x00D2, 0x004F, 0x0300, 0,
+ 1, 0x00D3, 0x004F, 0x0301, 0,
+ 1, 0x00D4, 0x004F, 0x0302, 0,
+ 1, 0x00D5, 0x004F, 0x0303, 0,
+ 1, 0x00D6, 0x004F, 0x0308, 0,
+ 1, 0x00D9, 0x0055, 0x0300, 0,
+ 1, 0x00DA, 0x0055, 0x0301, 0,
+ 1, 0x00DB, 0x0055, 0x0302, 0,
+ 1, 0x00DC, 0x0055, 0x0308, 0,
+ 1, 0x00DD, 0x0059, 0x0301, 0,
+ 1, 0x00E0, 0x0061, 0x0300, 0,
+ 1, 0x00E1, 0x0061, 0x0301, 0,
+ 1, 0x00E2, 0x0061, 0x0302, 0,
+ 1, 0x00E3, 0x0061, 0x0303, 0,
+ 1, 0x00E4, 0x0061, 0x0308, 0,
+ 1, 0x00E5, 0x0061, 0x030A, 0,
+ 1, 0x00E7, 0x0063, 0x0327, 0,
+ 1, 0x00E8, 0x0065, 0x0300, 0,
+ 1, 0x00E9, 0x0065, 0x0301, 0,
+ 1, 0x00EA, 0x0065, 0x0302, 0,
+ 1, 0x00EB, 0x0065, 0x0308, 0,
+ 1, 0x00EC, 0x0069, 0x0300, 0,
+ 1, 0x00ED, 0x0069, 0x0301, 0,
+ 1, 0x00EE, 0x0069, 0x0302, 0,
+ 1, 0x00EF, 0x0069, 0x0308, 0,
+ 1, 0x00F1, 0x006E, 0x0303, 0,
+ 1, 0x00F2, 0x006F, 0x0300, 0,
+ 1, 0x00F3, 0x006F, 0x0301, 0,
+ 1, 0x00F4, 0x006F, 0x0302, 0,
+ 1, 0x00F5, 0x006F, 0x0303, 0,
+ 1, 0x00F6, 0x006F, 0x0308, 0,
+ 1, 0x00F9, 0x0075, 0x0300, 0,
+ 1, 0x00FA, 0x0075, 0x0301, 0,
+ 1, 0x00FB, 0x0075, 0x0302, 0,
+ 1, 0x00FC, 0x0075, 0x0308, 0,
+ 1, 0x00FD, 0x0079, 0x0301, 0,
+ 1, 0x00FF, 0x0079, 0x0308, 0,
+ 1, 0x0100, 0x0041, 0x0304, 0,
+ 1, 0x0101, 0x0061, 0x0304, 0,
+ 1, 0x0102, 0x0041, 0x0306, 0,
+ 1, 0x0103, 0x0061, 0x0306, 0,
+ 1, 0x0104, 0x0041, 0x0328, 0,
+ 1, 0x0105, 0x0061, 0x0328, 0,
+ 1, 0x0106, 0x0043, 0x0301, 0,
+ 1, 0x0107, 0x0063, 0x0301, 0,
+ 1, 0x0108, 0x0043, 0x0302, 0,
+ 1, 0x0109, 0x0063, 0x0302, 0,
+ 1, 0x010A, 0x0043, 0x0307, 0,
+ 1, 0x010B, 0x0063, 0x0307, 0,
+ 1, 0x010C, 0x0043, 0x030C, 0,
+ 1, 0x010D, 0x0063, 0x030C, 0,
+ 1, 0x010E, 0x0044, 0x030C, 0,
+ 1, 0x010F, 0x0064, 0x030C, 0,
+ 1, 0x0112, 0x0045, 0x0304, 0,
+ 1, 0x0113, 0x0065, 0x0304, 0,
+ 1, 0x0114, 0x0045, 0x0306, 0,
+ 1, 0x0115, 0x0065, 0x0306, 0,
+ 1, 0x0116, 0x0045, 0x0307, 0,
+ 1, 0x0117, 0x0065, 0x0307, 0,
+ 1, 0x0118, 0x0045, 0x0328, 0,
+ 1, 0x0119, 0x0065, 0x0328, 0,
+ 1, 0x011A, 0x0045, 0x030C, 0,
+ 1, 0x011B, 0x0065, 0x030C, 0,
+ 1, 0x011C, 0x0047, 0x0302, 0,
+ 1, 0x011D, 0x0067, 0x0302, 0,
+ 1, 0x011E, 0x0047, 0x0306, 0,
+ 1, 0x011F, 0x0067, 0x0306, 0,
+ 1, 0x0120, 0x0047, 0x0307, 0,
+ 1, 0x0121, 0x0067, 0x0307, 0,
+ 1, 0x0122, 0x0047, 0x0327, 0,
+ 1, 0x0123, 0x0067, 0x0327, 0,
+ 1, 0x0124, 0x0048, 0x0302, 0,
+ 1, 0x0125, 0x0068, 0x0302, 0,
+ 1, 0x0128, 0x0049, 0x0303, 0,
+ 1, 0x0129, 0x0069, 0x0303, 0,
+ 1, 0x012A, 0x0049, 0x0304, 0,
+ 1, 0x012B, 0x0069, 0x0304, 0,
+ 1, 0x012C, 0x0049, 0x0306, 0,
+ 1, 0x012D, 0x0069, 0x0306, 0,
+ 1, 0x012E, 0x0049, 0x0328, 0,
+ 1, 0x012F, 0x0069, 0x0328, 0,
+ 1, 0x0130, 0x0049, 0x0307, 0,
+ 16, 0x0132, 0x0049, 0x004A, 0,
+ 16, 0x0133, 0x0069, 0x006A, 0,
+ 1, 0x0134, 0x004A, 0x0302, 0,
+ 1, 0x0135, 0x006A, 0x0302, 0,
+ 1, 0x0136, 0x004B, 0x0327, 0,
+ 1, 0x0137, 0x006B, 0x0327, 0,
+ 1, 0x0139, 0x004C, 0x0301, 0,
+ 1, 0x013A, 0x006C, 0x0301, 0,
+ 1, 0x013B, 0x004C, 0x0327, 0,
+ 1, 0x013C, 0x006C, 0x0327, 0,
+ 1, 0x013D, 0x004C, 0x030C, 0,
+ 1, 0x013E, 0x006C, 0x030C, 0,
+ 16, 0x013F, 0x004C, 0x00B7, 0,
+ 16, 0x0140, 0x006C, 0x00B7, 0,
+ 1, 0x0143, 0x004E, 0x0301, 0,
+ 1, 0x0144, 0x006E, 0x0301, 0,
+ 1, 0x0145, 0x004E, 0x0327, 0,
+ 1, 0x0146, 0x006E, 0x0327, 0,
+ 1, 0x0147, 0x004E, 0x030C, 0,
+ 1, 0x0148, 0x006E, 0x030C, 0,
+ 16, 0x0149, 0x02BC, 0x006E, 0,
+ 1, 0x014C, 0x004F, 0x0304, 0,
+ 1, 0x014D, 0x006F, 0x0304, 0,
+ 1, 0x014E, 0x004F, 0x0306, 0,
+ 1, 0x014F, 0x006F, 0x0306, 0,
+ 1, 0x0150, 0x004F, 0x030B, 0,
+ 1, 0x0151, 0x006F, 0x030B, 0,
+ 1, 0x0154, 0x0052, 0x0301, 0,
+ 1, 0x0155, 0x0072, 0x0301, 0,
+ 1, 0x0156, 0x0052, 0x0327, 0,
+ 1, 0x0157, 0x0072, 0x0327, 0,
+ 1, 0x0158, 0x0052, 0x030C, 0,
+ 1, 0x0159, 0x0072, 0x030C, 0,
+ 1, 0x015A, 0x0053, 0x0301, 0,
+ 1, 0x015B, 0x0073, 0x0301, 0,
+ 1, 0x015C, 0x0053, 0x0302, 0,
+ 1, 0x015D, 0x0073, 0x0302, 0,
+ 1, 0x015E, 0x0053, 0x0327, 0,
+ 1, 0x015F, 0x0073, 0x0327, 0,
+ 1, 0x0160, 0x0053, 0x030C, 0,
+ 1, 0x0161, 0x0073, 0x030C, 0,
+ 1, 0x0162, 0x0054, 0x0327, 0,
+ 1, 0x0163, 0x0074, 0x0327, 0,
+ 1, 0x0164, 0x0054, 0x030C, 0,
+ 1, 0x0165, 0x0074, 0x030C, 0,
+ 1, 0x0168, 0x0055, 0x0303, 0,
+ 1, 0x0169, 0x0075, 0x0303, 0,
+ 1, 0x016A, 0x0055, 0x0304, 0,
+ 1, 0x016B, 0x0075, 0x0304, 0,
+ 1, 0x016C, 0x0055, 0x0306, 0,
+ 1, 0x016D, 0x0075, 0x0306, 0,
+ 1, 0x016E, 0x0055, 0x030A, 0,
+ 1, 0x016F, 0x0075, 0x030A, 0,
+ 1, 0x0170, 0x0055, 0x030B, 0,
+ 1, 0x0171, 0x0075, 0x030B, 0,
+ 1, 0x0172, 0x0055, 0x0328, 0,
+ 1, 0x0173, 0x0075, 0x0328, 0,
+ 1, 0x0174, 0x0057, 0x0302, 0,
+ 1, 0x0175, 0x0077, 0x0302, 0,
+ 1, 0x0176, 0x0059, 0x0302, 0,
+ 1, 0x0177, 0x0079, 0x0302, 0,
+ 1, 0x0178, 0x0059, 0x0308, 0,
+ 1, 0x0179, 0x005A, 0x0301, 0,
+ 1, 0x017A, 0x007A, 0x0301, 0,
+ 1, 0x017B, 0x005A, 0x0307, 0,
+ 1, 0x017C, 0x007A, 0x0307, 0,
+ 1, 0x017D, 0x005A, 0x030C, 0,
+ 1, 0x017E, 0x007A, 0x030C, 0,
+ 16, 0x017F, 0x0073, 0,
+ 1, 0x01A0, 0x004F, 0x031B, 0,
+ 1, 0x01A1, 0x006F, 0x031B, 0,
+ 1, 0x01AF, 0x0055, 0x031B, 0,
+ 1, 0x01B0, 0x0075, 0x031B, 0,
+ 16, 0x01C4, 0x0044, 0x017D, 0,
+ 16, 0x01C5, 0x0044, 0x017E, 0,
+ 16, 0x01C6, 0x0064, 0x017E, 0,
+ 16, 0x01C7, 0x004C, 0x004A, 0,
+ 16, 0x01C8, 0x004C, 0x006A, 0,
+ 16, 0x01C9, 0x006C, 0x006A, 0,
+ 16, 0x01CA, 0x004E, 0x004A, 0,
+ 16, 0x01CB, 0x004E, 0x006A, 0,
+ 16, 0x01CC, 0x006E, 0x006A, 0,
+ 1, 0x01CD, 0x0041, 0x030C, 0,
+ 1, 0x01CE, 0x0061, 0x030C, 0,
+ 1, 0x01CF, 0x0049, 0x030C, 0,
+ 1, 0x01D0, 0x0069, 0x030C, 0,
+ 1, 0x01D1, 0x004F, 0x030C, 0,
+ 1, 0x01D2, 0x006F, 0x030C, 0,
+ 1, 0x01D3, 0x0055, 0x030C, 0,
+ 1, 0x01D4, 0x0075, 0x030C, 0,
+ 1, 0x01D5, 0x00DC, 0x0304, 0,
+ 1, 0x01D6, 0x00FC, 0x0304, 0,
+ 1, 0x01D7, 0x00DC, 0x0301, 0,
+ 1, 0x01D8, 0x00FC, 0x0301, 0,
+ 1, 0x01D9, 0x00DC, 0x030C, 0,
+ 1, 0x01DA, 0x00FC, 0x030C, 0,
+ 1, 0x01DB, 0x00DC, 0x0300, 0,
+ 1, 0x01DC, 0x00FC, 0x0300, 0,
+ 1, 0x01DE, 0x00C4, 0x0304, 0,
+ 1, 0x01DF, 0x00E4, 0x0304, 0,
+ 1, 0x01E0, 0x0226, 0x0304, 0,
+ 1, 0x01E1, 0x0227, 0x0304, 0,
+ 1, 0x01E2, 0x00C6, 0x0304, 0,
+ 1, 0x01E3, 0x00E6, 0x0304, 0,
+ 1, 0x01E6, 0x0047, 0x030C, 0,
+ 1, 0x01E7, 0x0067, 0x030C, 0,
+ 1, 0x01E8, 0x004B, 0x030C, 0,
+ 1, 0x01E9, 0x006B, 0x030C, 0,
+ 1, 0x01EA, 0x004F, 0x0328, 0,
+ 1, 0x01EB, 0x006F, 0x0328, 0,
+ 1, 0x01EC, 0x01EA, 0x0304, 0,
+ 1, 0x01ED, 0x01EB, 0x0304, 0,
+ 1, 0x01EE, 0x01B7, 0x030C, 0,
+ 1, 0x01EF, 0x0292, 0x030C, 0,
+ 1, 0x01F0, 0x006A, 0x030C, 0,
+ 16, 0x01F1, 0x0044, 0x005A, 0,
+ 16, 0x01F2, 0x0044, 0x007A, 0,
+ 16, 0x01F3, 0x0064, 0x007A, 0,
+ 1, 0x01F4, 0x0047, 0x0301, 0,
+ 1, 0x01F5, 0x0067, 0x0301, 0,
+ 1, 0x01F8, 0x004E, 0x0300, 0,
+ 1, 0x01F9, 0x006E, 0x0300, 0,
+ 1, 0x01FA, 0x00C5, 0x0301, 0,
+ 1, 0x01FB, 0x00E5, 0x0301, 0,
+ 1, 0x01FC, 0x00C6, 0x0301, 0,
+ 1, 0x01FD, 0x00E6, 0x0301, 0,
+ 1, 0x01FE, 0x00D8, 0x0301, 0,
+ 1, 0x01FF, 0x00F8, 0x0301, 0,
+ 1, 0x0200, 0x0041, 0x030F, 0,
+ 1, 0x0201, 0x0061, 0x030F, 0,
+ 1, 0x0202, 0x0041, 0x0311, 0,
+ 1, 0x0203, 0x0061, 0x0311, 0,
+ 1, 0x0204, 0x0045, 0x030F, 0,
+ 1, 0x0205, 0x0065, 0x030F, 0,
+ 1, 0x0206, 0x0045, 0x0311, 0,
+ 1, 0x0207, 0x0065, 0x0311, 0,
+ 1, 0x0208, 0x0049, 0x030F, 0,
+ 1, 0x0209, 0x0069, 0x030F, 0,
+ 1, 0x020A, 0x0049, 0x0311, 0,
+ 1, 0x020B, 0x0069, 0x0311, 0,
+ 1, 0x020C, 0x004F, 0x030F, 0,
+ 1, 0x020D, 0x006F, 0x030F, 0,
+ 1, 0x020E, 0x004F, 0x0311, 0,
+ 1, 0x020F, 0x006F, 0x0311, 0,
+ 1, 0x0210, 0x0052, 0x030F, 0,
+ 1, 0x0211, 0x0072, 0x030F, 0,
+ 1, 0x0212, 0x0052, 0x0311, 0,
+ 1, 0x0213, 0x0072, 0x0311, 0,
+ 1, 0x0214, 0x0055, 0x030F, 0,
+ 1, 0x0215, 0x0075, 0x030F, 0,
+ 1, 0x0216, 0x0055, 0x0311, 0,
+ 1, 0x0217, 0x0075, 0x0311, 0,
+ 1, 0x0218, 0x0053, 0x0326, 0,
+ 1, 0x0219, 0x0073, 0x0326, 0,
+ 1, 0x021A, 0x0054, 0x0326, 0,
+ 1, 0x021B, 0x0074, 0x0326, 0,
+ 1, 0x021E, 0x0048, 0x030C, 0,
+ 1, 0x021F, 0x0068, 0x030C, 0,
+ 1, 0x0226, 0x0041, 0x0307, 0,
+ 1, 0x0227, 0x0061, 0x0307, 0,
+ 1, 0x0228, 0x0045, 0x0327, 0,
+ 1, 0x0229, 0x0065, 0x0327, 0,
+ 1, 0x022A, 0x00D6, 0x0304, 0,
+ 1, 0x022B, 0x00F6, 0x0304, 0,
+ 1, 0x022C, 0x00D5, 0x0304, 0,
+ 1, 0x022D, 0x00F5, 0x0304, 0,
+ 1, 0x022E, 0x004F, 0x0307, 0,
+ 1, 0x022F, 0x006F, 0x0307, 0,
+ 1, 0x0230, 0x022E, 0x0304, 0,
+ 1, 0x0231, 0x022F, 0x0304, 0,
+ 1, 0x0232, 0x0059, 0x0304, 0,
+ 1, 0x0233, 0x0079, 0x0304, 0,
+ 9, 0x02B0, 0x0068, 0,
+ 9, 0x02B1, 0x0266, 0,
+ 9, 0x02B2, 0x006A, 0,
+ 9, 0x02B3, 0x0072, 0,
+ 9, 0x02B4, 0x0279, 0,
+ 9, 0x02B5, 0x027B, 0,
+ 9, 0x02B6, 0x0281, 0,
+ 9, 0x02B7, 0x0077, 0,
+ 9, 0x02B8, 0x0079, 0,
+ 16, 0x02D8, 0x0020, 0x0306, 0,
+ 16, 0x02D9, 0x0020, 0x0307, 0,
+ 16, 0x02DA, 0x0020, 0x030A, 0,
+ 16, 0x02DB, 0x0020, 0x0328, 0,
+ 16, 0x02DC, 0x0020, 0x0303, 0,
+ 16, 0x02DD, 0x0020, 0x030B, 0,
+ 9, 0x02E0, 0x0263, 0,
+ 9, 0x02E1, 0x006C, 0,
+ 9, 0x02E2, 0x0073, 0,
+ 9, 0x02E3, 0x0078, 0,
+ 9, 0x02E4, 0x0295, 0,
+ 1, 0x0340, 0x0300, 0,
+ 1, 0x0341, 0x0301, 0,
+ 1, 0x0343, 0x0313, 0,
+ 1, 0x0344, 0x0308, 0x0301, 0,
+ 1, 0x0374, 0x02B9, 0,
+ 16, 0x037A, 0x0020, 0x0345, 0,
+ 1, 0x037E, 0x003B, 0,
+ 16, 0x0384, 0x0020, 0x0301, 0,
+ 1, 0x0385, 0x00A8, 0x0301, 0,
+ 1, 0x0386, 0x0391, 0x0301, 0,
+ 1, 0x0387, 0x00B7, 0,
+ 1, 0x0388, 0x0395, 0x0301, 0,
+ 1, 0x0389, 0x0397, 0x0301, 0,
+ 1, 0x038A, 0x0399, 0x0301, 0,
+ 1, 0x038C, 0x039F, 0x0301, 0,
+ 1, 0x038E, 0x03A5, 0x0301, 0,
+ 1, 0x038F, 0x03A9, 0x0301, 0,
+ 1, 0x0390, 0x03CA, 0x0301, 0,
+ 1, 0x03AA, 0x0399, 0x0308, 0,
+ 1, 0x03AB, 0x03A5, 0x0308, 0,
+ 1, 0x03AC, 0x03B1, 0x0301, 0,
+ 1, 0x03AD, 0x03B5, 0x0301, 0,
+ 1, 0x03AE, 0x03B7, 0x0301, 0,
+ 1, 0x03AF, 0x03B9, 0x0301, 0,
+ 1, 0x03B0, 0x03CB, 0x0301, 0,
+ 1, 0x03CA, 0x03B9, 0x0308, 0,
+ 1, 0x03CB, 0x03C5, 0x0308, 0,
+ 1, 0x03CC, 0x03BF, 0x0301, 0,
+ 1, 0x03CD, 0x03C5, 0x0301, 0,
+ 1, 0x03CE, 0x03C9, 0x0301, 0,
+ 16, 0x03D0, 0x03B2, 0,
+ 16, 0x03D1, 0x03B8, 0,
+ 16, 0x03D2, 0x03A5, 0,
+ 1, 0x03D3, 0x03D2, 0x0301, 0,
+ 1, 0x03D4, 0x03D2, 0x0308, 0,
+ 16, 0x03D5, 0x03C6, 0,
+ 16, 0x03D6, 0x03C0, 0,
+ 16, 0x03F0, 0x03BA, 0,
+ 16, 0x03F1, 0x03C1, 0,
+ 16, 0x03F2, 0x03C2, 0,
+ 1, 0x0400, 0x0415, 0x0300, 0,
+ 1, 0x0401, 0x0415, 0x0308, 0,
+ 1, 0x0403, 0x0413, 0x0301, 0,
+ 1, 0x0407, 0x0406, 0x0308, 0,
+ 1, 0x040C, 0x041A, 0x0301, 0,
+ 1, 0x040D, 0x0418, 0x0300, 0,
+ 1, 0x040E, 0x0423, 0x0306, 0,
+ 1, 0x0419, 0x0418, 0x0306, 0,
+ 1, 0x0439, 0x0438, 0x0306, 0,
+ 1, 0x0450, 0x0435, 0x0300, 0,
+ 1, 0x0451, 0x0435, 0x0308, 0,
+ 1, 0x0453, 0x0433, 0x0301, 0,
+ 1, 0x0457, 0x0456, 0x0308, 0,
+ 1, 0x045C, 0x043A, 0x0301, 0,
+ 1, 0x045D, 0x0438, 0x0300, 0,
+ 1, 0x045E, 0x0443, 0x0306, 0,
+ 1, 0x0476, 0x0474, 0x030F, 0,
+ 1, 0x0477, 0x0475, 0x030F, 0,
+ 1, 0x04C1, 0x0416, 0x0306, 0,
+ 1, 0x04C2, 0x0436, 0x0306, 0,
+ 1, 0x04D0, 0x0410, 0x0306, 0,
+ 1, 0x04D1, 0x0430, 0x0306, 0,
+ 1, 0x04D2, 0x0410, 0x0308, 0,
+ 1, 0x04D3, 0x0430, 0x0308, 0,
+ 1, 0x04D6, 0x0415, 0x0306, 0,
+ 1, 0x04D7, 0x0435, 0x0306, 0,
+ 1, 0x04DA, 0x04D8, 0x0308, 0,
+ 1, 0x04DB, 0x04D9, 0x0308, 0,
+ 1, 0x04DC, 0x0416, 0x0308, 0,
+ 1, 0x04DD, 0x0436, 0x0308, 0,
+ 1, 0x04DE, 0x0417, 0x0308, 0,
+ 1, 0x04DF, 0x0437, 0x0308, 0,
+ 1, 0x04E2, 0x0418, 0x0304, 0,
+ 1, 0x04E3, 0x0438, 0x0304, 0,
+ 1, 0x04E4, 0x0418, 0x0308, 0,
+ 1, 0x04E5, 0x0438, 0x0308, 0,
+ 1, 0x04E6, 0x041E, 0x0308, 0,
+ 1, 0x04E7, 0x043E, 0x0308, 0,
+ 1, 0x04EA, 0x04E8, 0x0308, 0,
+ 1, 0x04EB, 0x04E9, 0x0308, 0,
+ 1, 0x04EC, 0x042D, 0x0308, 0,
+ 1, 0x04ED, 0x044D, 0x0308, 0,
+ 1, 0x04EE, 0x0423, 0x0304, 0,
+ 1, 0x04EF, 0x0443, 0x0304, 0,
+ 1, 0x04F0, 0x0423, 0x0308, 0,
+ 1, 0x04F1, 0x0443, 0x0308, 0,
+ 1, 0x04F2, 0x0423, 0x030B, 0,
+ 1, 0x04F3, 0x0443, 0x030B, 0,
+ 1, 0x04F4, 0x0427, 0x0308, 0,
+ 1, 0x04F5, 0x0447, 0x0308, 0,
+ 1, 0x04F8, 0x042B, 0x0308, 0,
+ 1, 0x04F9, 0x044B, 0x0308, 0,
+ 16, 0x0587, 0x0565, 0x0582, 0,
+ 1, 0x0622, 0x0627, 0x0653, 0,
+ 1, 0x0623, 0x0627, 0x0654, 0,
+ 1, 0x0624, 0x0648, 0x0654, 0,
+ 1, 0x0625, 0x0627, 0x0655, 0,
+ 1, 0x0626, 0x064A, 0x0654, 0,
+ 16, 0x0675, 0x0627, 0x0674, 0,
+ 16, 0x0676, 0x0648, 0x0674, 0,
+ 16, 0x0677, 0x06C7, 0x0674, 0,
+ 16, 0x0678, 0x064A, 0x0674, 0,
+ 1, 0x06C0, 0x06D5, 0x0654, 0,
+ 1, 0x06C2, 0x06C1, 0x0654, 0,
+ 1, 0x06D3, 0x06D2, 0x0654, 0,
+ 1, 0x0929, 0x0928, 0x093C, 0,
+ 1, 0x0931, 0x0930, 0x093C, 0,
+ 1, 0x0934, 0x0933, 0x093C, 0,
+ 1, 0x0958, 0x0915, 0x093C, 0,
+ 1, 0x0959, 0x0916, 0x093C, 0,
+ 1, 0x095A, 0x0917, 0x093C, 0,
+ 1, 0x095B, 0x091C, 0x093C, 0,
+ 1, 0x095C, 0x0921, 0x093C, 0,
+ 1, 0x095D, 0x0922, 0x093C, 0,
+ 1, 0x095E, 0x092B, 0x093C, 0,
+ 1, 0x095F, 0x092F, 0x093C, 0,
+ 1, 0x09CB, 0x09C7, 0x09BE, 0,
+ 1, 0x09CC, 0x09C7, 0x09D7, 0,
+ 1, 0x09DC, 0x09A1, 0x09BC, 0,
+ 1, 0x09DD, 0x09A2, 0x09BC, 0,
+ 1, 0x09DF, 0x09AF, 0x09BC, 0,
+ 1, 0x0A33, 0x0A32, 0x0A3C, 0,
+ 1, 0x0A36, 0x0A38, 0x0A3C, 0,
+ 1, 0x0A59, 0x0A16, 0x0A3C, 0,
+ 1, 0x0A5A, 0x0A17, 0x0A3C, 0,
+ 1, 0x0A5B, 0x0A1C, 0x0A3C, 0,
+ 1, 0x0A5E, 0x0A2B, 0x0A3C, 0,
+ 1, 0x0B48, 0x0B47, 0x0B56, 0,
+ 1, 0x0B4B, 0x0B47, 0x0B3E, 0,
+ 1, 0x0B4C, 0x0B47, 0x0B57, 0,
+ 1, 0x0B5C, 0x0B21, 0x0B3C, 0,
+ 1, 0x0B5D, 0x0B22, 0x0B3C, 0,
+ 1, 0x0B94, 0x0B92, 0x0BD7, 0,
+ 1, 0x0BCA, 0x0BC6, 0x0BBE, 0,
+ 1, 0x0BCB, 0x0BC7, 0x0BBE, 0,
+ 1, 0x0BCC, 0x0BC6, 0x0BD7, 0,
+ 1, 0x0C48, 0x0C46, 0x0C56, 0,
+ 1, 0x0CC0, 0x0CBF, 0x0CD5, 0,
+ 1, 0x0CC7, 0x0CC6, 0x0CD5, 0,
+ 1, 0x0CC8, 0x0CC6, 0x0CD6, 0,
+ 1, 0x0CCA, 0x0CC6, 0x0CC2, 0,
+ 1, 0x0CCB, 0x0CCA, 0x0CD5, 0,
+ 1, 0x0D4A, 0x0D46, 0x0D3E, 0,
+ 1, 0x0D4B, 0x0D47, 0x0D3E, 0,
+ 1, 0x0D4C, 0x0D46, 0x0D57, 0,
+ 1, 0x0DDA, 0x0DD9, 0x0DCA, 0,
+ 1, 0x0DDC, 0x0DD9, 0x0DCF, 0,
+ 1, 0x0DDD, 0x0DDC, 0x0DCA, 0,
+ 1, 0x0DDE, 0x0DD9, 0x0DDF, 0,
+ 16, 0x0E33, 0x0E4D, 0x0E32, 0,
+ 16, 0x0EB3, 0x0ECD, 0x0EB2, 0,
+ 16, 0x0EDC, 0x0EAB, 0x0E99, 0,
+ 16, 0x0EDD, 0x0EAB, 0x0EA1, 0,
+ 3, 0x0F0C, 0x0F0B, 0,
+ 1, 0x0F43, 0x0F42, 0x0FB7, 0,
+ 1, 0x0F4D, 0x0F4C, 0x0FB7, 0,
+ 1, 0x0F52, 0x0F51, 0x0FB7, 0,
+ 1, 0x0F57, 0x0F56, 0x0FB7, 0,
+ 1, 0x0F5C, 0x0F5B, 0x0FB7, 0,
+ 1, 0x0F69, 0x0F40, 0x0FB5, 0,
+ 1, 0x0F73, 0x0F71, 0x0F72, 0,
+ 1, 0x0F75, 0x0F71, 0x0F74, 0,
+ 1, 0x0F76, 0x0FB2, 0x0F80, 0,
+ 16, 0x0F77, 0x0FB2, 0x0F81, 0,
+ 1, 0x0F78, 0x0FB3, 0x0F80, 0,
+ 16, 0x0F79, 0x0FB3, 0x0F81, 0,
+ 1, 0x0F81, 0x0F71, 0x0F80, 0,
+ 1, 0x0F93, 0x0F92, 0x0FB7, 0,
+ 1, 0x0F9D, 0x0F9C, 0x0FB7, 0,
+ 1, 0x0FA2, 0x0FA1, 0x0FB7, 0,
+ 1, 0x0FA7, 0x0FA6, 0x0FB7, 0,
+ 1, 0x0FAC, 0x0FAB, 0x0FB7, 0,
+ 1, 0x0FB9, 0x0F90, 0x0FB5, 0,
+ 1, 0x1026, 0x1025, 0x102E, 0,
+ 1, 0x1E00, 0x0041, 0x0325, 0,
+ 1, 0x1E01, 0x0061, 0x0325, 0,
+ 1, 0x1E02, 0x0042, 0x0307, 0,
+ 1, 0x1E03, 0x0062, 0x0307, 0,
+ 1, 0x1E04, 0x0042, 0x0323, 0,
+ 1, 0x1E05, 0x0062, 0x0323, 0,
+ 1, 0x1E06, 0x0042, 0x0331, 0,
+ 1, 0x1E07, 0x0062, 0x0331, 0,
+ 1, 0x1E08, 0x00C7, 0x0301, 0,
+ 1, 0x1E09, 0x00E7, 0x0301, 0,
+ 1, 0x1E0A, 0x0044, 0x0307, 0,
+ 1, 0x1E0B, 0x0064, 0x0307, 0,
+ 1, 0x1E0C, 0x0044, 0x0323, 0,
+ 1, 0x1E0D, 0x0064, 0x0323, 0,
+ 1, 0x1E0E, 0x0044, 0x0331, 0,
+ 1, 0x1E0F, 0x0064, 0x0331, 0,
+ 1, 0x1E10, 0x0044, 0x0327, 0,
+ 1, 0x1E11, 0x0064, 0x0327, 0,
+ 1, 0x1E12, 0x0044, 0x032D, 0,
+ 1, 0x1E13, 0x0064, 0x032D, 0,
+ 1, 0x1E14, 0x0112, 0x0300, 0,
+ 1, 0x1E15, 0x0113, 0x0300, 0,
+ 1, 0x1E16, 0x0112, 0x0301, 0,
+ 1, 0x1E17, 0x0113, 0x0301, 0,
+ 1, 0x1E18, 0x0045, 0x032D, 0,
+ 1, 0x1E19, 0x0065, 0x032D, 0,
+ 1, 0x1E1A, 0x0045, 0x0330, 0,
+ 1, 0x1E1B, 0x0065, 0x0330, 0,
+ 1, 0x1E1C, 0x0228, 0x0306, 0,
+ 1, 0x1E1D, 0x0229, 0x0306, 0,
+ 1, 0x1E1E, 0x0046, 0x0307, 0,
+ 1, 0x1E1F, 0x0066, 0x0307, 0,
+ 1, 0x1E20, 0x0047, 0x0304, 0,
+ 1, 0x1E21, 0x0067, 0x0304, 0,
+ 1, 0x1E22, 0x0048, 0x0307, 0,
+ 1, 0x1E23, 0x0068, 0x0307, 0,
+ 1, 0x1E24, 0x0048, 0x0323, 0,
+ 1, 0x1E25, 0x0068, 0x0323, 0,
+ 1, 0x1E26, 0x0048, 0x0308, 0,
+ 1, 0x1E27, 0x0068, 0x0308, 0,
+ 1, 0x1E28, 0x0048, 0x0327, 0,
+ 1, 0x1E29, 0x0068, 0x0327, 0,
+ 1, 0x1E2A, 0x0048, 0x032E, 0,
+ 1, 0x1E2B, 0x0068, 0x032E, 0,
+ 1, 0x1E2C, 0x0049, 0x0330, 0,
+ 1, 0x1E2D, 0x0069, 0x0330, 0,
+ 1, 0x1E2E, 0x00CF, 0x0301, 0,
+ 1, 0x1E2F, 0x00EF, 0x0301, 0,
+ 1, 0x1E30, 0x004B, 0x0301, 0,
+ 1, 0x1E31, 0x006B, 0x0301, 0,
+ 1, 0x1E32, 0x004B, 0x0323, 0,
+ 1, 0x1E33, 0x006B, 0x0323, 0,
+ 1, 0x1E34, 0x004B, 0x0331, 0,
+ 1, 0x1E35, 0x006B, 0x0331, 0,
+ 1, 0x1E36, 0x004C, 0x0323, 0,
+ 1, 0x1E37, 0x006C, 0x0323, 0,
+ 1, 0x1E38, 0x1E36, 0x0304, 0,
+ 1, 0x1E39, 0x1E37, 0x0304, 0,
+ 1, 0x1E3A, 0x004C, 0x0331, 0,
+ 1, 0x1E3B, 0x006C, 0x0331, 0,
+ 1, 0x1E3C, 0x004C, 0x032D, 0,
+ 1, 0x1E3D, 0x006C, 0x032D, 0,
+ 1, 0x1E3E, 0x004D, 0x0301, 0,
+ 1, 0x1E3F, 0x006D, 0x0301, 0,
+ 1, 0x1E40, 0x004D, 0x0307, 0,
+ 1, 0x1E41, 0x006D, 0x0307, 0,
+ 1, 0x1E42, 0x004D, 0x0323, 0,
+ 1, 0x1E43, 0x006D, 0x0323, 0,
+ 1, 0x1E44, 0x004E, 0x0307, 0,
+ 1, 0x1E45, 0x006E, 0x0307, 0,
+ 1, 0x1E46, 0x004E, 0x0323, 0,
+ 1, 0x1E47, 0x006E, 0x0323, 0,
+ 1, 0x1E48, 0x004E, 0x0331, 0,
+ 1, 0x1E49, 0x006E, 0x0331, 0,
+ 1, 0x1E4A, 0x004E, 0x032D, 0,
+ 1, 0x1E4B, 0x006E, 0x032D, 0,
+ 1, 0x1E4C, 0x00D5, 0x0301, 0,
+ 1, 0x1E4D, 0x00F5, 0x0301, 0,
+ 1, 0x1E4E, 0x00D5, 0x0308, 0,
+ 1, 0x1E4F, 0x00F5, 0x0308, 0,
+ 1, 0x1E50, 0x014C, 0x0300, 0,
+ 1, 0x1E51, 0x014D, 0x0300, 0,
+ 1, 0x1E52, 0x014C, 0x0301, 0,
+ 1, 0x1E53, 0x014D, 0x0301, 0,
+ 1, 0x1E54, 0x0050, 0x0301, 0,
+ 1, 0x1E55, 0x0070, 0x0301, 0,
+ 1, 0x1E56, 0x0050, 0x0307, 0,
+ 1, 0x1E57, 0x0070, 0x0307, 0,
+ 1, 0x1E58, 0x0052, 0x0307, 0,
+ 1, 0x1E59, 0x0072, 0x0307, 0,
+ 1, 0x1E5A, 0x0052, 0x0323, 0,
+ 1, 0x1E5B, 0x0072, 0x0323, 0,
+ 1, 0x1E5C, 0x1E5A, 0x0304, 0,
+ 1, 0x1E5D, 0x1E5B, 0x0304, 0,
+ 1, 0x1E5E, 0x0052, 0x0331, 0,
+ 1, 0x1E5F, 0x0072, 0x0331, 0,
+ 1, 0x1E60, 0x0053, 0x0307, 0,
+ 1, 0x1E61, 0x0073, 0x0307, 0,
+ 1, 0x1E62, 0x0053, 0x0323, 0,
+ 1, 0x1E63, 0x0073, 0x0323, 0,
+ 1, 0x1E64, 0x015A, 0x0307, 0,
+ 1, 0x1E65, 0x015B, 0x0307, 0,
+ 1, 0x1E66, 0x0160, 0x0307, 0,
+ 1, 0x1E67, 0x0161, 0x0307, 0,
+ 1, 0x1E68, 0x1E62, 0x0307, 0,
+ 1, 0x1E69, 0x1E63, 0x0307, 0,
+ 1, 0x1E6A, 0x0054, 0x0307, 0,
+ 1, 0x1E6B, 0x0074, 0x0307, 0,
+ 1, 0x1E6C, 0x0054, 0x0323, 0,
+ 1, 0x1E6D, 0x0074, 0x0323, 0,
+ 1, 0x1E6E, 0x0054, 0x0331, 0,
+ 1, 0x1E6F, 0x0074, 0x0331, 0,
+ 1, 0x1E70, 0x0054, 0x032D, 0,
+ 1, 0x1E71, 0x0074, 0x032D, 0,
+ 1, 0x1E72, 0x0055, 0x0324, 0,
+ 1, 0x1E73, 0x0075, 0x0324, 0,
+ 1, 0x1E74, 0x0055, 0x0330, 0,
+ 1, 0x1E75, 0x0075, 0x0330, 0,
+ 1, 0x1E76, 0x0055, 0x032D, 0,
+ 1, 0x1E77, 0x0075, 0x032D, 0,
+ 1, 0x1E78, 0x0168, 0x0301, 0,
+ 1, 0x1E79, 0x0169, 0x0301, 0,
+ 1, 0x1E7A, 0x016A, 0x0308, 0,
+ 1, 0x1E7B, 0x016B, 0x0308, 0,
+ 1, 0x1E7C, 0x0056, 0x0303, 0,
+ 1, 0x1E7D, 0x0076, 0x0303, 0,
+ 1, 0x1E7E, 0x0056, 0x0323, 0,
+ 1, 0x1E7F, 0x0076, 0x0323, 0,
+ 1, 0x1E80, 0x0057, 0x0300, 0,
+ 1, 0x1E81, 0x0077, 0x0300, 0,
+ 1, 0x1E82, 0x0057, 0x0301, 0,
+ 1, 0x1E83, 0x0077, 0x0301, 0,
+ 1, 0x1E84, 0x0057, 0x0308, 0,
+ 1, 0x1E85, 0x0077, 0x0308, 0,
+ 1, 0x1E86, 0x0057, 0x0307, 0,
+ 1, 0x1E87, 0x0077, 0x0307, 0,
+ 1, 0x1E88, 0x0057, 0x0323, 0,
+ 1, 0x1E89, 0x0077, 0x0323, 0,
+ 1, 0x1E8A, 0x0058, 0x0307, 0,
+ 1, 0x1E8B, 0x0078, 0x0307, 0,
+ 1, 0x1E8C, 0x0058, 0x0308, 0,
+ 1, 0x1E8D, 0x0078, 0x0308, 0,
+ 1, 0x1E8E, 0x0059, 0x0307, 0,
+ 1, 0x1E8F, 0x0079, 0x0307, 0,
+ 1, 0x1E90, 0x005A, 0x0302, 0,
+ 1, 0x1E91, 0x007A, 0x0302, 0,
+ 1, 0x1E92, 0x005A, 0x0323, 0,
+ 1, 0x1E93, 0x007A, 0x0323, 0,
+ 1, 0x1E94, 0x005A, 0x0331, 0,
+ 1, 0x1E95, 0x007A, 0x0331, 0,
+ 1, 0x1E96, 0x0068, 0x0331, 0,
+ 1, 0x1E97, 0x0074, 0x0308, 0,
+ 1, 0x1E98, 0x0077, 0x030A, 0,
+ 1, 0x1E99, 0x0079, 0x030A, 0,
+ 16, 0x1E9A, 0x0061, 0x02BE, 0,
+ 1, 0x1E9B, 0x017F, 0x0307, 0,
+ 1, 0x1EA0, 0x0041, 0x0323, 0,
+ 1, 0x1EA1, 0x0061, 0x0323, 0,
+ 1, 0x1EA2, 0x0041, 0x0309, 0,
+ 1, 0x1EA3, 0x0061, 0x0309, 0,
+ 1, 0x1EA4, 0x00C2, 0x0301, 0,
+ 1, 0x1EA5, 0x00E2, 0x0301, 0,
+ 1, 0x1EA6, 0x00C2, 0x0300, 0,
+ 1, 0x1EA7, 0x00E2, 0x0300, 0,
+ 1, 0x1EA8, 0x00C2, 0x0309, 0,
+ 1, 0x1EA9, 0x00E2, 0x0309, 0,
+ 1, 0x1EAA, 0x00C2, 0x0303, 0,
+ 1, 0x1EAB, 0x00E2, 0x0303, 0,
+ 1, 0x1EAC, 0x1EA0, 0x0302, 0,
+ 1, 0x1EAD, 0x1EA1, 0x0302, 0,
+ 1, 0x1EAE, 0x0102, 0x0301, 0,
+ 1, 0x1EAF, 0x0103, 0x0301, 0,
+ 1, 0x1EB0, 0x0102, 0x0300, 0,
+ 1, 0x1EB1, 0x0103, 0x0300, 0,
+ 1, 0x1EB2, 0x0102, 0x0309, 0,
+ 1, 0x1EB3, 0x0103, 0x0309, 0,
+ 1, 0x1EB4, 0x0102, 0x0303, 0,
+ 1, 0x1EB5, 0x0103, 0x0303, 0,
+ 1, 0x1EB6, 0x1EA0, 0x0306, 0,
+ 1, 0x1EB7, 0x1EA1, 0x0306, 0,
+ 1, 0x1EB8, 0x0045, 0x0323, 0,
+ 1, 0x1EB9, 0x0065, 0x0323, 0,
+ 1, 0x1EBA, 0x0045, 0x0309, 0,
+ 1, 0x1EBB, 0x0065, 0x0309, 0,
+ 1, 0x1EBC, 0x0045, 0x0303, 0,
+ 1, 0x1EBD, 0x0065, 0x0303, 0,
+ 1, 0x1EBE, 0x00CA, 0x0301, 0,
+ 1, 0x1EBF, 0x00EA, 0x0301, 0,
+ 1, 0x1EC0, 0x00CA, 0x0300, 0,
+ 1, 0x1EC1, 0x00EA, 0x0300, 0,
+ 1, 0x1EC2, 0x00CA, 0x0309, 0,
+ 1, 0x1EC3, 0x00EA, 0x0309, 0,
+ 1, 0x1EC4, 0x00CA, 0x0303, 0,
+ 1, 0x1EC5, 0x00EA, 0x0303, 0,
+ 1, 0x1EC6, 0x1EB8, 0x0302, 0,
+ 1, 0x1EC7, 0x1EB9, 0x0302, 0,
+ 1, 0x1EC8, 0x0049, 0x0309, 0,
+ 1, 0x1EC9, 0x0069, 0x0309, 0,
+ 1, 0x1ECA, 0x0049, 0x0323, 0,
+ 1, 0x1ECB, 0x0069, 0x0323, 0,
+ 1, 0x1ECC, 0x004F, 0x0323, 0,
+ 1, 0x1ECD, 0x006F, 0x0323, 0,
+ 1, 0x1ECE, 0x004F, 0x0309, 0,
+ 1, 0x1ECF, 0x006F, 0x0309, 0,
+ 1, 0x1ED0, 0x00D4, 0x0301, 0,
+ 1, 0x1ED1, 0x00F4, 0x0301, 0,
+ 1, 0x1ED2, 0x00D4, 0x0300, 0,
+ 1, 0x1ED3, 0x00F4, 0x0300, 0,
+ 1, 0x1ED4, 0x00D4, 0x0309, 0,
+ 1, 0x1ED5, 0x00F4, 0x0309, 0,
+ 1, 0x1ED6, 0x00D4, 0x0303, 0,
+ 1, 0x1ED7, 0x00F4, 0x0303, 0,
+ 1, 0x1ED8, 0x1ECC, 0x0302, 0,
+ 1, 0x1ED9, 0x1ECD, 0x0302, 0,
+ 1, 0x1EDA, 0x01A0, 0x0301, 0,
+ 1, 0x1EDB, 0x01A1, 0x0301, 0,
+ 1, 0x1EDC, 0x01A0, 0x0300, 0,
+ 1, 0x1EDD, 0x01A1, 0x0300, 0,
+ 1, 0x1EDE, 0x01A0, 0x0309, 0,
+ 1, 0x1EDF, 0x01A1, 0x0309, 0,
+ 1, 0x1EE0, 0x01A0, 0x0303, 0,
+ 1, 0x1EE1, 0x01A1, 0x0303, 0,
+ 1, 0x1EE2, 0x01A0, 0x0323, 0,
+ 1, 0x1EE3, 0x01A1, 0x0323, 0,
+ 1, 0x1EE4, 0x0055, 0x0323, 0,
+ 1, 0x1EE5, 0x0075, 0x0323, 0,
+ 1, 0x1EE6, 0x0055, 0x0309, 0,
+ 1, 0x1EE7, 0x0075, 0x0309, 0,
+ 1, 0x1EE8, 0x01AF, 0x0301, 0,
+ 1, 0x1EE9, 0x01B0, 0x0301, 0,
+ 1, 0x1EEA, 0x01AF, 0x0300, 0,
+ 1, 0x1EEB, 0x01B0, 0x0300, 0,
+ 1, 0x1EEC, 0x01AF, 0x0309, 0,
+ 1, 0x1EED, 0x01B0, 0x0309, 0,
+ 1, 0x1EEE, 0x01AF, 0x0303, 0,
+ 1, 0x1EEF, 0x01B0, 0x0303, 0,
+ 1, 0x1EF0, 0x01AF, 0x0323, 0,
+ 1, 0x1EF1, 0x01B0, 0x0323, 0,
+ 1, 0x1EF2, 0x0059, 0x0300, 0,
+ 1, 0x1EF3, 0x0079, 0x0300, 0,
+ 1, 0x1EF4, 0x0059, 0x0323, 0,
+ 1, 0x1EF5, 0x0079, 0x0323, 0,
+ 1, 0x1EF6, 0x0059, 0x0309, 0,
+ 1, 0x1EF7, 0x0079, 0x0309, 0,
+ 1, 0x1EF8, 0x0059, 0x0303, 0,
+ 1, 0x1EF9, 0x0079, 0x0303, 0,
+ 1, 0x1F00, 0x03B1, 0x0313, 0,
+ 1, 0x1F01, 0x03B1, 0x0314, 0,
+ 1, 0x1F02, 0x1F00, 0x0300, 0,
+ 1, 0x1F03, 0x1F01, 0x0300, 0,
+ 1, 0x1F04, 0x1F00, 0x0301, 0,
+ 1, 0x1F05, 0x1F01, 0x0301, 0,
+ 1, 0x1F06, 0x1F00, 0x0342, 0,
+ 1, 0x1F07, 0x1F01, 0x0342, 0,
+ 1, 0x1F08, 0x0391, 0x0313, 0,
+ 1, 0x1F09, 0x0391, 0x0314, 0,
+ 1, 0x1F0A, 0x1F08, 0x0300, 0,
+ 1, 0x1F0B, 0x1F09, 0x0300, 0,
+ 1, 0x1F0C, 0x1F08, 0x0301, 0,
+ 1, 0x1F0D, 0x1F09, 0x0301, 0,
+ 1, 0x1F0E, 0x1F08, 0x0342, 0,
+ 1, 0x1F0F, 0x1F09, 0x0342, 0,
+ 1, 0x1F10, 0x03B5, 0x0313, 0,
+ 1, 0x1F11, 0x03B5, 0x0314, 0,
+ 1, 0x1F12, 0x1F10, 0x0300, 0,
+ 1, 0x1F13, 0x1F11, 0x0300, 0,
+ 1, 0x1F14, 0x1F10, 0x0301, 0,
+ 1, 0x1F15, 0x1F11, 0x0301, 0,
+ 1, 0x1F18, 0x0395, 0x0313, 0,
+ 1, 0x1F19, 0x0395, 0x0314, 0,
+ 1, 0x1F1A, 0x1F18, 0x0300, 0,
+ 1, 0x1F1B, 0x1F19, 0x0300, 0,
+ 1, 0x1F1C, 0x1F18, 0x0301, 0,
+ 1, 0x1F1D, 0x1F19, 0x0301, 0,
+ 1, 0x1F20, 0x03B7, 0x0313, 0,
+ 1, 0x1F21, 0x03B7, 0x0314, 0,
+ 1, 0x1F22, 0x1F20, 0x0300, 0,
+ 1, 0x1F23, 0x1F21, 0x0300, 0,
+ 1, 0x1F24, 0x1F20, 0x0301, 0,
+ 1, 0x1F25, 0x1F21, 0x0301, 0,
+ 1, 0x1F26, 0x1F20, 0x0342, 0,
+ 1, 0x1F27, 0x1F21, 0x0342, 0,
+ 1, 0x1F28, 0x0397, 0x0313, 0,
+ 1, 0x1F29, 0x0397, 0x0314, 0,
+ 1, 0x1F2A, 0x1F28, 0x0300, 0,
+ 1, 0x1F2B, 0x1F29, 0x0300, 0,
+ 1, 0x1F2C, 0x1F28, 0x0301, 0,
+ 1, 0x1F2D, 0x1F29, 0x0301, 0,
+ 1, 0x1F2E, 0x1F28, 0x0342, 0,
+ 1, 0x1F2F, 0x1F29, 0x0342, 0,
+ 1, 0x1F30, 0x03B9, 0x0313, 0,
+ 1, 0x1F31, 0x03B9, 0x0314, 0,
+ 1, 0x1F32, 0x1F30, 0x0300, 0,
+ 1, 0x1F33, 0x1F31, 0x0300, 0,
+ 1, 0x1F34, 0x1F30, 0x0301, 0,
+ 1, 0x1F35, 0x1F31, 0x0301, 0,
+ 1, 0x1F36, 0x1F30, 0x0342, 0,
+ 1, 0x1F37, 0x1F31, 0x0342, 0,
+ 1, 0x1F38, 0x0399, 0x0313, 0,
+ 1, 0x1F39, 0x0399, 0x0314, 0,
+ 1, 0x1F3A, 0x1F38, 0x0300, 0,
+ 1, 0x1F3B, 0x1F39, 0x0300, 0,
+ 1, 0x1F3C, 0x1F38, 0x0301, 0,
+ 1, 0x1F3D, 0x1F39, 0x0301, 0,
+ 1, 0x1F3E, 0x1F38, 0x0342, 0,
+ 1, 0x1F3F, 0x1F39, 0x0342, 0,
+ 1, 0x1F40, 0x03BF, 0x0313, 0,
+ 1, 0x1F41, 0x03BF, 0x0314, 0,
+ 1, 0x1F42, 0x1F40, 0x0300, 0,
+ 1, 0x1F43, 0x1F41, 0x0300, 0,
+ 1, 0x1F44, 0x1F40, 0x0301, 0,
+ 1, 0x1F45, 0x1F41, 0x0301, 0,
+ 1, 0x1F48, 0x039F, 0x0313, 0,
+ 1, 0x1F49, 0x039F, 0x0314, 0,
+ 1, 0x1F4A, 0x1F48, 0x0300, 0,
+ 1, 0x1F4B, 0x1F49, 0x0300, 0,
+ 1, 0x1F4C, 0x1F48, 0x0301, 0,
+ 1, 0x1F4D, 0x1F49, 0x0301, 0,
+ 1, 0x1F50, 0x03C5, 0x0313, 0,
+ 1, 0x1F51, 0x03C5, 0x0314, 0,
+ 1, 0x1F52, 0x1F50, 0x0300, 0,
+ 1, 0x1F53, 0x1F51, 0x0300, 0,
+ 1, 0x1F54, 0x1F50, 0x0301, 0,
+ 1, 0x1F55, 0x1F51, 0x0301, 0,
+ 1, 0x1F56, 0x1F50, 0x0342, 0,
+ 1, 0x1F57, 0x1F51, 0x0342, 0,
+ 1, 0x1F59, 0x03A5, 0x0314, 0,
+ 1, 0x1F5B, 0x1F59, 0x0300, 0,
+ 1, 0x1F5D, 0x1F59, 0x0301, 0,
+ 1, 0x1F5F, 0x1F59, 0x0342, 0,
+ 1, 0x1F60, 0x03C9, 0x0313, 0,
+ 1, 0x1F61, 0x03C9, 0x0314, 0,
+ 1, 0x1F62, 0x1F60, 0x0300, 0,
+ 1, 0x1F63, 0x1F61, 0x0300, 0,
+ 1, 0x1F64, 0x1F60, 0x0301, 0,
+ 1, 0x1F65, 0x1F61, 0x0301, 0,
+ 1, 0x1F66, 0x1F60, 0x0342, 0,
+ 1, 0x1F67, 0x1F61, 0x0342, 0,
+ 1, 0x1F68, 0x03A9, 0x0313, 0,
+ 1, 0x1F69, 0x03A9, 0x0314, 0,
+ 1, 0x1F6A, 0x1F68, 0x0300, 0,
+ 1, 0x1F6B, 0x1F69, 0x0300, 0,
+ 1, 0x1F6C, 0x1F68, 0x0301, 0,
+ 1, 0x1F6D, 0x1F69, 0x0301, 0,
+ 1, 0x1F6E, 0x1F68, 0x0342, 0,
+ 1, 0x1F6F, 0x1F69, 0x0342, 0,
+ 1, 0x1F70, 0x03B1, 0x0300, 0,
+ 1, 0x1F71, 0x03AC, 0,
+ 1, 0x1F72, 0x03B5, 0x0300, 0,
+ 1, 0x1F73, 0x03AD, 0,
+ 1, 0x1F74, 0x03B7, 0x0300, 0,
+ 1, 0x1F75, 0x03AE, 0,
+ 1, 0x1F76, 0x03B9, 0x0300, 0,
+ 1, 0x1F77, 0x03AF, 0,
+ 1, 0x1F78, 0x03BF, 0x0300, 0,
+ 1, 0x1F79, 0x03CC, 0,
+ 1, 0x1F7A, 0x03C5, 0x0300, 0,
+ 1, 0x1F7B, 0x03CD, 0,
+ 1, 0x1F7C, 0x03C9, 0x0300, 0,
+ 1, 0x1F7D, 0x03CE, 0,
+ 1, 0x1F80, 0x1F00, 0x0345, 0,
+ 1, 0x1F81, 0x1F01, 0x0345, 0,
+ 1, 0x1F82, 0x1F02, 0x0345, 0,
+ 1, 0x1F83, 0x1F03, 0x0345, 0,
+ 1, 0x1F84, 0x1F04, 0x0345, 0,
+ 1, 0x1F85, 0x1F05, 0x0345, 0,
+ 1, 0x1F86, 0x1F06, 0x0345, 0,
+ 1, 0x1F87, 0x1F07, 0x0345, 0,
+ 1, 0x1F88, 0x1F08, 0x0345, 0,
+ 1, 0x1F89, 0x1F09, 0x0345, 0,
+ 1, 0x1F8A, 0x1F0A, 0x0345, 0,
+ 1, 0x1F8B, 0x1F0B, 0x0345, 0,
+ 1, 0x1F8C, 0x1F0C, 0x0345, 0,
+ 1, 0x1F8D, 0x1F0D, 0x0345, 0,
+ 1, 0x1F8E, 0x1F0E, 0x0345, 0,
+ 1, 0x1F8F, 0x1F0F, 0x0345, 0,
+ 1, 0x1F90, 0x1F20, 0x0345, 0,
+ 1, 0x1F91, 0x1F21, 0x0345, 0,
+ 1, 0x1F92, 0x1F22, 0x0345, 0,
+ 1, 0x1F93, 0x1F23, 0x0345, 0,
+ 1, 0x1F94, 0x1F24, 0x0345, 0,
+ 1, 0x1F95, 0x1F25, 0x0345, 0,
+ 1, 0x1F96, 0x1F26, 0x0345, 0,
+ 1, 0x1F97, 0x1F27, 0x0345, 0,
+ 1, 0x1F98, 0x1F28, 0x0345, 0,
+ 1, 0x1F99, 0x1F29, 0x0345, 0,
+ 1, 0x1F9A, 0x1F2A, 0x0345, 0,
+ 1, 0x1F9B, 0x1F2B, 0x0345, 0,
+ 1, 0x1F9C, 0x1F2C, 0x0345, 0,
+ 1, 0x1F9D, 0x1F2D, 0x0345, 0,
+ 1, 0x1F9E, 0x1F2E, 0x0345, 0,
+ 1, 0x1F9F, 0x1F2F, 0x0345, 0,
+ 1, 0x1FA0, 0x1F60, 0x0345, 0,
+ 1, 0x1FA1, 0x1F61, 0x0345, 0,
+ 1, 0x1FA2, 0x1F62, 0x0345, 0,
+ 1, 0x1FA3, 0x1F63, 0x0345, 0,
+ 1, 0x1FA4, 0x1F64, 0x0345, 0,
+ 1, 0x1FA5, 0x1F65, 0x0345, 0,
+ 1, 0x1FA6, 0x1F66, 0x0345, 0,
+ 1, 0x1FA7, 0x1F67, 0x0345, 0,
+ 1, 0x1FA8, 0x1F68, 0x0345, 0,
+ 1, 0x1FA9, 0x1F69, 0x0345, 0,
+ 1, 0x1FAA, 0x1F6A, 0x0345, 0,
+ 1, 0x1FAB, 0x1F6B, 0x0345, 0,
+ 1, 0x1FAC, 0x1F6C, 0x0345, 0,
+ 1, 0x1FAD, 0x1F6D, 0x0345, 0,
+ 1, 0x1FAE, 0x1F6E, 0x0345, 0,
+ 1, 0x1FAF, 0x1F6F, 0x0345, 0,
+ 1, 0x1FB0, 0x03B1, 0x0306, 0,
+ 1, 0x1FB1, 0x03B1, 0x0304, 0,
+ 1, 0x1FB2, 0x1F70, 0x0345, 0,
+ 1, 0x1FB3, 0x03B1, 0x0345, 0,
+ 1, 0x1FB4, 0x03AC, 0x0345, 0,
+ 1, 0x1FB6, 0x03B1, 0x0342, 0,
+ 1, 0x1FB7, 0x1FB6, 0x0345, 0,
+ 1, 0x1FB8, 0x0391, 0x0306, 0,
+ 1, 0x1FB9, 0x0391, 0x0304, 0,
+ 1, 0x1FBA, 0x0391, 0x0300, 0,
+ 1, 0x1FBB, 0x0386, 0,
+ 1, 0x1FBC, 0x0391, 0x0345, 0,
+ 16, 0x1FBD, 0x0020, 0x0313, 0,
+ 1, 0x1FBE, 0x03B9, 0,
+ 16, 0x1FBF, 0x0020, 0x0313, 0,
+ 16, 0x1FC0, 0x0020, 0x0342, 0,
+ 1, 0x1FC1, 0x00A8, 0x0342, 0,
+ 1, 0x1FC2, 0x1F74, 0x0345, 0,
+ 1, 0x1FC3, 0x03B7, 0x0345, 0,
+ 1, 0x1FC4, 0x03AE, 0x0345, 0,
+ 1, 0x1FC6, 0x03B7, 0x0342, 0,
+ 1, 0x1FC7, 0x1FC6, 0x0345, 0,
+ 1, 0x1FC8, 0x0395, 0x0300, 0,
+ 1, 0x1FC9, 0x0388, 0,
+ 1, 0x1FCA, 0x0397, 0x0300, 0,
+ 1, 0x1FCB, 0x0389, 0,
+ 1, 0x1FCC, 0x0397, 0x0345, 0,
+ 1, 0x1FCD, 0x1FBF, 0x0300, 0,
+ 1, 0x1FCE, 0x1FBF, 0x0301, 0,
+ 1, 0x1FCF, 0x1FBF, 0x0342, 0,
+ 1, 0x1FD0, 0x03B9, 0x0306, 0,
+ 1, 0x1FD1, 0x03B9, 0x0304, 0,
+ 1, 0x1FD2, 0x03CA, 0x0300, 0,
+ 1, 0x1FD3, 0x0390, 0,
+ 1, 0x1FD6, 0x03B9, 0x0342, 0,
+ 1, 0x1FD7, 0x03CA, 0x0342, 0,
+ 1, 0x1FD8, 0x0399, 0x0306, 0,
+ 1, 0x1FD9, 0x0399, 0x0304, 0,
+ 1, 0x1FDA, 0x0399, 0x0300, 0,
+ 1, 0x1FDB, 0x038A, 0,
+ 1, 0x1FDD, 0x1FFE, 0x0300, 0,
+ 1, 0x1FDE, 0x1FFE, 0x0301, 0,
+ 1, 0x1FDF, 0x1FFE, 0x0342, 0,
+ 1, 0x1FE0, 0x03C5, 0x0306, 0,
+ 1, 0x1FE1, 0x03C5, 0x0304, 0,
+ 1, 0x1FE2, 0x03CB, 0x0300, 0,
+ 1, 0x1FE3, 0x03B0, 0,
+ 1, 0x1FE4, 0x03C1, 0x0313, 0,
+ 1, 0x1FE5, 0x03C1, 0x0314, 0,
+ 1, 0x1FE6, 0x03C5, 0x0342, 0,
+ 1, 0x1FE7, 0x03CB, 0x0342, 0,
+ 1, 0x1FE8, 0x03A5, 0x0306, 0,
+ 1, 0x1FE9, 0x03A5, 0x0304, 0,
+ 1, 0x1FEA, 0x03A5, 0x0300, 0,
+ 1, 0x1FEB, 0x038E, 0,
+ 1, 0x1FEC, 0x03A1, 0x0314, 0,
+ 1, 0x1FED, 0x00A8, 0x0300, 0,
+ 1, 0x1FEE, 0x0385, 0,
+ 1, 0x1FEF, 0x0060, 0,
+ 1, 0x1FF2, 0x1F7C, 0x0345, 0,
+ 1, 0x1FF3, 0x03C9, 0x0345, 0,
+ 1, 0x1FF4, 0x03CE, 0x0345, 0,
+ 1, 0x1FF6, 0x03C9, 0x0342, 0,
+ 1, 0x1FF7, 0x1FF6, 0x0345, 0,
+ 1, 0x1FF8, 0x039F, 0x0300, 0,
+ 1, 0x1FF9, 0x038C, 0,
+ 1, 0x1FFA, 0x03A9, 0x0300, 0,
+ 1, 0x1FFB, 0x038F, 0,
+ 1, 0x1FFC, 0x03A9, 0x0345, 0,
+ 1, 0x1FFD, 0x00B4, 0,
+ 16, 0x1FFE, 0x0020, 0x0314, 0,
+ 1, 0x2000, 0x2002, 0,
+ 1, 0x2001, 0x2003, 0,
+ 16, 0x2002, 0x0020, 0,
+ 16, 0x2003, 0x0020, 0,
+ 16, 0x2004, 0x0020, 0,
+ 16, 0x2005, 0x0020, 0,
+ 16, 0x2006, 0x0020, 0,
+ 3, 0x2007, 0x0020, 0,
+ 16, 0x2008, 0x0020, 0,
+ 16, 0x2009, 0x0020, 0,
+ 16, 0x200A, 0x0020, 0,
+ 3, 0x2011, 0x2010, 0,
+ 16, 0x2017, 0x0020, 0x0333, 0,
+ 16, 0x2024, 0x002E, 0,
+ 16, 0x2025, 0x002E, 0x002E, 0,
+ 16, 0x2026, 0x002E, 0x002E, 0x002E, 0,
+ 3, 0x202F, 0x0020, 0,
+ 16, 0x2033, 0x2032, 0x2032, 0,
+ 16, 0x2034, 0x2032, 0x2032, 0x2032, 0,
+ 16, 0x2036, 0x2035, 0x2035, 0,
+ 16, 0x2037, 0x2035, 0x2035, 0x2035, 0,
+ 16, 0x203C, 0x0021, 0x0021, 0,
+ 16, 0x203E, 0x0020, 0x0305, 0,
+ 16, 0x2048, 0x003F, 0x0021, 0,
+ 16, 0x2049, 0x0021, 0x003F, 0,
+ 9, 0x2070, 0x0030, 0,
+ 9, 0x2074, 0x0034, 0,
+ 9, 0x2075, 0x0035, 0,
+ 9, 0x2076, 0x0036, 0,
+ 9, 0x2077, 0x0037, 0,
+ 9, 0x2078, 0x0038, 0,
+ 9, 0x2079, 0x0039, 0,
+ 9, 0x207A, 0x002B, 0,
+ 9, 0x207B, 0x2212, 0,
+ 9, 0x207C, 0x003D, 0,
+ 9, 0x207D, 0x0028, 0,
+ 9, 0x207E, 0x0029, 0,
+ 9, 0x207F, 0x006E, 0,
+ 10, 0x2080, 0x0030, 0,
+ 10, 0x2081, 0x0031, 0,
+ 10, 0x2082, 0x0032, 0,
+ 10, 0x2083, 0x0033, 0,
+ 10, 0x2084, 0x0034, 0,
+ 10, 0x2085, 0x0035, 0,
+ 10, 0x2086, 0x0036, 0,
+ 10, 0x2087, 0x0037, 0,
+ 10, 0x2088, 0x0038, 0,
+ 10, 0x2089, 0x0039, 0,
+ 10, 0x208A, 0x002B, 0,
+ 10, 0x208B, 0x2212, 0,
+ 10, 0x208C, 0x003D, 0,
+ 10, 0x208D, 0x0028, 0,
+ 10, 0x208E, 0x0029, 0,
+ 16, 0x20A8, 0x0052, 0x0073, 0,
+ 16, 0x2100, 0x0061, 0x002F, 0x0063, 0,
+ 16, 0x2101, 0x0061, 0x002F, 0x0073, 0,
+ 2, 0x2102, 0x0043, 0,
+ 16, 0x2103, 0x00B0, 0x0043, 0,
+ 16, 0x2105, 0x0063, 0x002F, 0x006F, 0,
+ 16, 0x2106, 0x0063, 0x002F, 0x0075, 0,
+ 16, 0x2107, 0x0190, 0,
+ 16, 0x2109, 0x00B0, 0x0046, 0,
+ 2, 0x210A, 0x0067, 0,
+ 2, 0x210B, 0x0048, 0,
+ 2, 0x210C, 0x0048, 0,
+ 2, 0x210D, 0x0048, 0,
+ 2, 0x210E, 0x0068, 0,
+ 2, 0x210F, 0x0127, 0,
+ 2, 0x2110, 0x0049, 0,
+ 2, 0x2111, 0x0049, 0,
+ 2, 0x2112, 0x004C, 0,
+ 2, 0x2113, 0x006C, 0,
+ 2, 0x2115, 0x004E, 0,
+ 16, 0x2116, 0x004E, 0x006F, 0,
+ 2, 0x2119, 0x0050, 0,
+ 2, 0x211A, 0x0051, 0,
+ 2, 0x211B, 0x0052, 0,
+ 2, 0x211C, 0x0052, 0,
+ 2, 0x211D, 0x0052, 0,
+ 9, 0x2120, 0x0053, 0x004D, 0,
+ 16, 0x2121, 0x0054, 0x0045, 0x004C, 0,
+ 9, 0x2122, 0x0054, 0x004D, 0,
+ 2, 0x2124, 0x005A, 0,
+ 1, 0x2126, 0x03A9, 0,
+ 2, 0x2128, 0x005A, 0,
+ 1, 0x212A, 0x004B, 0,
+ 1, 0x212B, 0x00C5, 0,
+ 2, 0x212C, 0x0042, 0,
+ 2, 0x212D, 0x0043, 0,
+ 2, 0x212F, 0x0065, 0,
+ 2, 0x2130, 0x0045, 0,
+ 2, 0x2131, 0x0046, 0,
+ 2, 0x2133, 0x004D, 0,
+ 2, 0x2134, 0x006F, 0,
+ 16, 0x2135, 0x05D0, 0,
+ 16, 0x2136, 0x05D1, 0,
+ 16, 0x2137, 0x05D2, 0,
+ 16, 0x2138, 0x05D3, 0,
+ 2, 0x2139, 0x0069, 0,
+ 17, 0x2153, 0x0031, 0x2044, 0x0033, 0,
+ 17, 0x2154, 0x0032, 0x2044, 0x0033, 0,
+ 17, 0x2155, 0x0031, 0x2044, 0x0035, 0,
+ 17, 0x2156, 0x0032, 0x2044, 0x0035, 0,
+ 17, 0x2157, 0x0033, 0x2044, 0x0035, 0,
+ 17, 0x2158, 0x0034, 0x2044, 0x0035, 0,
+ 17, 0x2159, 0x0031, 0x2044, 0x0036, 0,
+ 17, 0x215A, 0x0035, 0x2044, 0x0036, 0,
+ 17, 0x215B, 0x0031, 0x2044, 0x0038, 0,
+ 17, 0x215C, 0x0033, 0x2044, 0x0038, 0,
+ 17, 0x215D, 0x0035, 0x2044, 0x0038, 0,
+ 17, 0x215E, 0x0037, 0x2044, 0x0038, 0,
+ 17, 0x215F, 0x0031, 0x2044, 0,
+ 16, 0x2160, 0x0049, 0,
+ 16, 0x2161, 0x0049, 0x0049, 0,
+ 16, 0x2162, 0x0049, 0x0049, 0x0049, 0,
+ 16, 0x2163, 0x0049, 0x0056, 0,
+ 16, 0x2164, 0x0056, 0,
+ 16, 0x2165, 0x0056, 0x0049, 0,
+ 16, 0x2166, 0x0056, 0x0049, 0x0049, 0,
+ 16, 0x2167, 0x0056, 0x0049, 0x0049, 0x0049, 0,
+ 16, 0x2168, 0x0049, 0x0058, 0,
+ 16, 0x2169, 0x0058, 0,
+ 16, 0x216A, 0x0058, 0x0049, 0,
+ 16, 0x216B, 0x0058, 0x0049, 0x0049, 0,
+ 16, 0x216C, 0x004C, 0,
+ 16, 0x216D, 0x0043, 0,
+ 16, 0x216E, 0x0044, 0,
+ 16, 0x216F, 0x004D, 0,
+ 16, 0x2170, 0x0069, 0,
+ 16, 0x2171, 0x0069, 0x0069, 0,
+ 16, 0x2172, 0x0069, 0x0069, 0x0069, 0,
+ 16, 0x2173, 0x0069, 0x0076, 0,
+ 16, 0x2174, 0x0076, 0,
+ 16, 0x2175, 0x0076, 0x0069, 0,
+ 16, 0x2176, 0x0076, 0x0069, 0x0069, 0,
+ 16, 0x2177, 0x0076, 0x0069, 0x0069, 0x0069, 0,
+ 16, 0x2178, 0x0069, 0x0078, 0,
+ 16, 0x2179, 0x0078, 0,
+ 16, 0x217A, 0x0078, 0x0069, 0,
+ 16, 0x217B, 0x0078, 0x0069, 0x0069, 0,
+ 16, 0x217C, 0x006C, 0,
+ 16, 0x217D, 0x0063, 0,
+ 16, 0x217E, 0x0064, 0,
+ 16, 0x217F, 0x006D, 0,
+ 1, 0x219A, 0x2190, 0x0338, 0,
+ 1, 0x219B, 0x2192, 0x0338, 0,
+ 1, 0x21AE, 0x2194, 0x0338, 0,
+ 1, 0x21CD, 0x21D0, 0x0338, 0,
+ 1, 0x21CE, 0x21D4, 0x0338, 0,
+ 1, 0x21CF, 0x21D2, 0x0338, 0,
+ 1, 0x2204, 0x2203, 0x0338, 0,
+ 1, 0x2209, 0x2208, 0x0338, 0,
+ 1, 0x220C, 0x220B, 0x0338, 0,
+ 1, 0x2224, 0x2223, 0x0338, 0,
+ 1, 0x2226, 0x2225, 0x0338, 0,
+ 16, 0x222C, 0x222B, 0x222B, 0,
+ 16, 0x222D, 0x222B, 0x222B, 0x222B, 0,
+ 16, 0x222F, 0x222E, 0x222E, 0,
+ 16, 0x2230, 0x222E, 0x222E, 0x222E, 0,
+ 1, 0x2241, 0x223C, 0x0338, 0,
+ 1, 0x2244, 0x2243, 0x0338, 0,
+ 1, 0x2247, 0x2245, 0x0338, 0,
+ 1, 0x2249, 0x2248, 0x0338, 0,
+ 1, 0x2260, 0x003D, 0x0338, 0,
+ 1, 0x2262, 0x2261, 0x0338, 0,
+ 1, 0x226D, 0x224D, 0x0338, 0,
+ 1, 0x226E, 0x003C, 0x0338, 0,
+ 1, 0x226F, 0x003E, 0x0338, 0,
+ 1, 0x2270, 0x2264, 0x0338, 0,
+ 1, 0x2271, 0x2265, 0x0338, 0,
+ 1, 0x2274, 0x2272, 0x0338, 0,
+ 1, 0x2275, 0x2273, 0x0338, 0,
+ 1, 0x2278, 0x2276, 0x0338, 0,
+ 1, 0x2279, 0x2277, 0x0338, 0,
+ 1, 0x2280, 0x227A, 0x0338, 0,
+ 1, 0x2281, 0x227B, 0x0338, 0,
+ 1, 0x2284, 0x2282, 0x0338, 0,
+ 1, 0x2285, 0x2283, 0x0338, 0,
+ 1, 0x2288, 0x2286, 0x0338, 0,
+ 1, 0x2289, 0x2287, 0x0338, 0,
+ 1, 0x22AC, 0x22A2, 0x0338, 0,
+ 1, 0x22AD, 0x22A8, 0x0338, 0,
+ 1, 0x22AE, 0x22A9, 0x0338, 0,
+ 1, 0x22AF, 0x22AB, 0x0338, 0,
+ 1, 0x22E0, 0x227C, 0x0338, 0,
+ 1, 0x22E1, 0x227D, 0x0338, 0,
+ 1, 0x22E2, 0x2291, 0x0338, 0,
+ 1, 0x22E3, 0x2292, 0x0338, 0,
+ 1, 0x22EA, 0x22B2, 0x0338, 0,
+ 1, 0x22EB, 0x22B3, 0x0338, 0,
+ 1, 0x22EC, 0x22B4, 0x0338, 0,
+ 1, 0x22ED, 0x22B5, 0x0338, 0,
+ 1, 0x2329, 0x3008, 0,
+ 1, 0x232A, 0x3009, 0,
+ 8, 0x2460, 0x0031, 0,
+ 8, 0x2461, 0x0032, 0,
+ 8, 0x2462, 0x0033, 0,
+ 8, 0x2463, 0x0034, 0,
+ 8, 0x2464, 0x0035, 0,
+ 8, 0x2465, 0x0036, 0,
+ 8, 0x2466, 0x0037, 0,
+ 8, 0x2467, 0x0038, 0,
+ 8, 0x2468, 0x0039, 0,
+ 8, 0x2469, 0x0031, 0x0030, 0,
+ 8, 0x246A, 0x0031, 0x0031, 0,
+ 8, 0x246B, 0x0031, 0x0032, 0,
+ 8, 0x246C, 0x0031, 0x0033, 0,
+ 8, 0x246D, 0x0031, 0x0034, 0,
+ 8, 0x246E, 0x0031, 0x0035, 0,
+ 8, 0x246F, 0x0031, 0x0036, 0,
+ 8, 0x2470, 0x0031, 0x0037, 0,
+ 8, 0x2471, 0x0031, 0x0038, 0,
+ 8, 0x2472, 0x0031, 0x0039, 0,
+ 8, 0x2473, 0x0032, 0x0030, 0,
+ 16, 0x2474, 0x0028, 0x0031, 0x0029, 0,
+ 16, 0x2475, 0x0028, 0x0032, 0x0029, 0,
+ 16, 0x2476, 0x0028, 0x0033, 0x0029, 0,
+ 16, 0x2477, 0x0028, 0x0034, 0x0029, 0,
+ 16, 0x2478, 0x0028, 0x0035, 0x0029, 0,
+ 16, 0x2479, 0x0028, 0x0036, 0x0029, 0,
+ 16, 0x247A, 0x0028, 0x0037, 0x0029, 0,
+ 16, 0x247B, 0x0028, 0x0038, 0x0029, 0,
+ 16, 0x247C, 0x0028, 0x0039, 0x0029, 0,
+ 16, 0x247D, 0x0028, 0x0031, 0x0030, 0x0029, 0,
+ 16, 0x247E, 0x0028, 0x0031, 0x0031, 0x0029, 0,
+ 16, 0x247F, 0x0028, 0x0031, 0x0032, 0x0029, 0,
+ 16, 0x2480, 0x0028, 0x0031, 0x0033, 0x0029, 0,
+ 16, 0x2481, 0x0028, 0x0031, 0x0034, 0x0029, 0,
+ 16, 0x2482, 0x0028, 0x0031, 0x0035, 0x0029, 0,
+ 16, 0x2483, 0x0028, 0x0031, 0x0036, 0x0029, 0,
+ 16, 0x2484, 0x0028, 0x0031, 0x0037, 0x0029, 0,
+ 16, 0x2485, 0x0028, 0x0031, 0x0038, 0x0029, 0,
+ 16, 0x2486, 0x0028, 0x0031, 0x0039, 0x0029, 0,
+ 16, 0x2487, 0x0028, 0x0032, 0x0030, 0x0029, 0,
+ 16, 0x2488, 0x0031, 0x002E, 0,
+ 16, 0x2489, 0x0032, 0x002E, 0,
+ 16, 0x248A, 0x0033, 0x002E, 0,
+ 16, 0x248B, 0x0034, 0x002E, 0,
+ 16, 0x248C, 0x0035, 0x002E, 0,
+ 16, 0x248D, 0x0036, 0x002E, 0,
+ 16, 0x248E, 0x0037, 0x002E, 0,
+ 16, 0x248F, 0x0038, 0x002E, 0,
+ 16, 0x2490, 0x0039, 0x002E, 0,
+ 16, 0x2491, 0x0031, 0x0030, 0x002E, 0,
+ 16, 0x2492, 0x0031, 0x0031, 0x002E, 0,
+ 16, 0x2493, 0x0031, 0x0032, 0x002E, 0,
+ 16, 0x2494, 0x0031, 0x0033, 0x002E, 0,
+ 16, 0x2495, 0x0031, 0x0034, 0x002E, 0,
+ 16, 0x2496, 0x0031, 0x0035, 0x002E, 0,
+ 16, 0x2497, 0x0031, 0x0036, 0x002E, 0,
+ 16, 0x2498, 0x0031, 0x0037, 0x002E, 0,
+ 16, 0x2499, 0x0031, 0x0038, 0x002E, 0,
+ 16, 0x249A, 0x0031, 0x0039, 0x002E, 0,
+ 16, 0x249B, 0x0032, 0x0030, 0x002E, 0,
+ 16, 0x249C, 0x0028, 0x0061, 0x0029, 0,
+ 16, 0x249D, 0x0028, 0x0062, 0x0029, 0,
+ 16, 0x249E, 0x0028, 0x0063, 0x0029, 0,
+ 16, 0x249F, 0x0028, 0x0064, 0x0029, 0,
+ 16, 0x24A0, 0x0028, 0x0065, 0x0029, 0,
+ 16, 0x24A1, 0x0028, 0x0066, 0x0029, 0,
+ 16, 0x24A2, 0x0028, 0x0067, 0x0029, 0,
+ 16, 0x24A3, 0x0028, 0x0068, 0x0029, 0,
+ 16, 0x24A4, 0x0028, 0x0069, 0x0029, 0,
+ 16, 0x24A5, 0x0028, 0x006A, 0x0029, 0,
+ 16, 0x24A6, 0x0028, 0x006B, 0x0029, 0,
+ 16, 0x24A7, 0x0028, 0x006C, 0x0029, 0,
+ 16, 0x24A8, 0x0028, 0x006D, 0x0029, 0,
+ 16, 0x24A9, 0x0028, 0x006E, 0x0029, 0,
+ 16, 0x24AA, 0x0028, 0x006F, 0x0029, 0,
+ 16, 0x24AB, 0x0028, 0x0070, 0x0029, 0,
+ 16, 0x24AC, 0x0028, 0x0071, 0x0029, 0,
+ 16, 0x24AD, 0x0028, 0x0072, 0x0029, 0,
+ 16, 0x24AE, 0x0028, 0x0073, 0x0029, 0,
+ 16, 0x24AF, 0x0028, 0x0074, 0x0029, 0,
+ 16, 0x24B0, 0x0028, 0x0075, 0x0029, 0,
+ 16, 0x24B1, 0x0028, 0x0076, 0x0029, 0,
+ 16, 0x24B2, 0x0028, 0x0077, 0x0029, 0,
+ 16, 0x24B3, 0x0028, 0x0078, 0x0029, 0,
+ 16, 0x24B4, 0x0028, 0x0079, 0x0029, 0,
+ 16, 0x24B5, 0x0028, 0x007A, 0x0029, 0,
+ 8, 0x24B6, 0x0041, 0,
+ 8, 0x24B7, 0x0042, 0,
+ 8, 0x24B8, 0x0043, 0,
+ 8, 0x24B9, 0x0044, 0,
+ 8, 0x24BA, 0x0045, 0,
+ 8, 0x24BB, 0x0046, 0,
+ 8, 0x24BC, 0x0047, 0,
+ 8, 0x24BD, 0x0048, 0,
+ 8, 0x24BE, 0x0049, 0,
+ 8, 0x24BF, 0x004A, 0,
+ 8, 0x24C0, 0x004B, 0,
+ 8, 0x24C1, 0x004C, 0,
+ 8, 0x24C2, 0x004D, 0,
+ 8, 0x24C3, 0x004E, 0,
+ 8, 0x24C4, 0x004F, 0,
+ 8, 0x24C5, 0x0050, 0,
+ 8, 0x24C6, 0x0051, 0,
+ 8, 0x24C7, 0x0052, 0,
+ 8, 0x24C8, 0x0053, 0,
+ 8, 0x24C9, 0x0054, 0,
+ 8, 0x24CA, 0x0055, 0,
+ 8, 0x24CB, 0x0056, 0,
+ 8, 0x24CC, 0x0057, 0,
+ 8, 0x24CD, 0x0058, 0,
+ 8, 0x24CE, 0x0059, 0,
+ 8, 0x24CF, 0x005A, 0,
+ 8, 0x24D0, 0x0061, 0,
+ 8, 0x24D1, 0x0062, 0,
+ 8, 0x24D2, 0x0063, 0,
+ 8, 0x24D3, 0x0064, 0,
+ 8, 0x24D4, 0x0065, 0,
+ 8, 0x24D5, 0x0066, 0,
+ 8, 0x24D6, 0x0067, 0,
+ 8, 0x24D7, 0x0068, 0,
+ 8, 0x24D8, 0x0069, 0,
+ 8, 0x24D9, 0x006A, 0,
+ 8, 0x24DA, 0x006B, 0,
+ 8, 0x24DB, 0x006C, 0,
+ 8, 0x24DC, 0x006D, 0,
+ 8, 0x24DD, 0x006E, 0,
+ 8, 0x24DE, 0x006F, 0,
+ 8, 0x24DF, 0x0070, 0,
+ 8, 0x24E0, 0x0071, 0,
+ 8, 0x24E1, 0x0072, 0,
+ 8, 0x24E2, 0x0073, 0,
+ 8, 0x24E3, 0x0074, 0,
+ 8, 0x24E4, 0x0075, 0,
+ 8, 0x24E5, 0x0076, 0,
+ 8, 0x24E6, 0x0077, 0,
+ 8, 0x24E7, 0x0078, 0,
+ 8, 0x24E8, 0x0079, 0,
+ 8, 0x24E9, 0x007A, 0,
+ 8, 0x24EA, 0x0030, 0,
+ 16, 0x2E9F, 0x6BCD, 0,
+ 16, 0x2EF3, 0x9F9F, 0,
+ 16, 0x2F00, 0x4E00, 0,
+ 16, 0x2F01, 0x4E28, 0,
+ 16, 0x2F02, 0x4E36, 0,
+ 16, 0x2F03, 0x4E3F, 0,
+ 16, 0x2F04, 0x4E59, 0,
+ 16, 0x2F05, 0x4E85, 0,
+ 16, 0x2F06, 0x4E8C, 0,
+ 16, 0x2F07, 0x4EA0, 0,
+ 16, 0x2F08, 0x4EBA, 0,
+ 16, 0x2F09, 0x513F, 0,
+ 16, 0x2F0A, 0x5165, 0,
+ 16, 0x2F0B, 0x516B, 0,
+ 16, 0x2F0C, 0x5182, 0,
+ 16, 0x2F0D, 0x5196, 0,
+ 16, 0x2F0E, 0x51AB, 0,
+ 16, 0x2F0F, 0x51E0, 0,
+ 16, 0x2F10, 0x51F5, 0,
+ 16, 0x2F11, 0x5200, 0,
+ 16, 0x2F12, 0x529B, 0,
+ 16, 0x2F13, 0x52F9, 0,
+ 16, 0x2F14, 0x5315, 0,
+ 16, 0x2F15, 0x531A, 0,
+ 16, 0x2F16, 0x5338, 0,
+ 16, 0x2F17, 0x5341, 0,
+ 16, 0x2F18, 0x535C, 0,
+ 16, 0x2F19, 0x5369, 0,
+ 16, 0x2F1A, 0x5382, 0,
+ 16, 0x2F1B, 0x53B6, 0,
+ 16, 0x2F1C, 0x53C8, 0,
+ 16, 0x2F1D, 0x53E3, 0,
+ 16, 0x2F1E, 0x56D7, 0,
+ 16, 0x2F1F, 0x571F, 0,
+ 16, 0x2F20, 0x58EB, 0,
+ 16, 0x2F21, 0x5902, 0,
+ 16, 0x2F22, 0x590A, 0,
+ 16, 0x2F23, 0x5915, 0,
+ 16, 0x2F24, 0x5927, 0,
+ 16, 0x2F25, 0x5973, 0,
+ 16, 0x2F26, 0x5B50, 0,
+ 16, 0x2F27, 0x5B80, 0,
+ 16, 0x2F28, 0x5BF8, 0,
+ 16, 0x2F29, 0x5C0F, 0,
+ 16, 0x2F2A, 0x5C22, 0,
+ 16, 0x2F2B, 0x5C38, 0,
+ 16, 0x2F2C, 0x5C6E, 0,
+ 16, 0x2F2D, 0x5C71, 0,
+ 16, 0x2F2E, 0x5DDB, 0,
+ 16, 0x2F2F, 0x5DE5, 0,
+ 16, 0x2F30, 0x5DF1, 0,
+ 16, 0x2F31, 0x5DFE, 0,
+ 16, 0x2F32, 0x5E72, 0,
+ 16, 0x2F33, 0x5E7A, 0,
+ 16, 0x2F34, 0x5E7F, 0,
+ 16, 0x2F35, 0x5EF4, 0,
+ 16, 0x2F36, 0x5EFE, 0,
+ 16, 0x2F37, 0x5F0B, 0,
+ 16, 0x2F38, 0x5F13, 0,
+ 16, 0x2F39, 0x5F50, 0,
+ 16, 0x2F3A, 0x5F61, 0,
+ 16, 0x2F3B, 0x5F73, 0,
+ 16, 0x2F3C, 0x5FC3, 0,
+ 16, 0x2F3D, 0x6208, 0,
+ 16, 0x2F3E, 0x6236, 0,
+ 16, 0x2F3F, 0x624B, 0,
+ 16, 0x2F40, 0x652F, 0,
+ 16, 0x2F41, 0x6534, 0,
+ 16, 0x2F42, 0x6587, 0,
+ 16, 0x2F43, 0x6597, 0,
+ 16, 0x2F44, 0x65A4, 0,
+ 16, 0x2F45, 0x65B9, 0,
+ 16, 0x2F46, 0x65E0, 0,
+ 16, 0x2F47, 0x65E5, 0,
+ 16, 0x2F48, 0x66F0, 0,
+ 16, 0x2F49, 0x6708, 0,
+ 16, 0x2F4A, 0x6728, 0,
+ 16, 0x2F4B, 0x6B20, 0,
+ 16, 0x2F4C, 0x6B62, 0,
+ 16, 0x2F4D, 0x6B79, 0,
+ 16, 0x2F4E, 0x6BB3, 0,
+ 16, 0x2F4F, 0x6BCB, 0,
+ 16, 0x2F50, 0x6BD4, 0,
+ 16, 0x2F51, 0x6BDB, 0,
+ 16, 0x2F52, 0x6C0F, 0,
+ 16, 0x2F53, 0x6C14, 0,
+ 16, 0x2F54, 0x6C34, 0,
+ 16, 0x2F55, 0x706B, 0,
+ 16, 0x2F56, 0x722A, 0,
+ 16, 0x2F57, 0x7236, 0,
+ 16, 0x2F58, 0x723B, 0,
+ 16, 0x2F59, 0x723F, 0,
+ 16, 0x2F5A, 0x7247, 0,
+ 16, 0x2F5B, 0x7259, 0,
+ 16, 0x2F5C, 0x725B, 0,
+ 16, 0x2F5D, 0x72AC, 0,
+ 16, 0x2F5E, 0x7384, 0,
+ 16, 0x2F5F, 0x7389, 0,
+ 16, 0x2F60, 0x74DC, 0,
+ 16, 0x2F61, 0x74E6, 0,
+ 16, 0x2F62, 0x7518, 0,
+ 16, 0x2F63, 0x751F, 0,
+ 16, 0x2F64, 0x7528, 0,
+ 16, 0x2F65, 0x7530, 0,
+ 16, 0x2F66, 0x758B, 0,
+ 16, 0x2F67, 0x7592, 0,
+ 16, 0x2F68, 0x7676, 0,
+ 16, 0x2F69, 0x767D, 0,
+ 16, 0x2F6A, 0x76AE, 0,
+ 16, 0x2F6B, 0x76BF, 0,
+ 16, 0x2F6C, 0x76EE, 0,
+ 16, 0x2F6D, 0x77DB, 0,
+ 16, 0x2F6E, 0x77E2, 0,
+ 16, 0x2F6F, 0x77F3, 0,
+ 16, 0x2F70, 0x793A, 0,
+ 16, 0x2F71, 0x79B8, 0,
+ 16, 0x2F72, 0x79BE, 0,
+ 16, 0x2F73, 0x7A74, 0,
+ 16, 0x2F74, 0x7ACB, 0,
+ 16, 0x2F75, 0x7AF9, 0,
+ 16, 0x2F76, 0x7C73, 0,
+ 16, 0x2F77, 0x7CF8, 0,
+ 16, 0x2F78, 0x7F36, 0,
+ 16, 0x2F79, 0x7F51, 0,
+ 16, 0x2F7A, 0x7F8A, 0,
+ 16, 0x2F7B, 0x7FBD, 0,
+ 16, 0x2F7C, 0x8001, 0,
+ 16, 0x2F7D, 0x800C, 0,
+ 16, 0x2F7E, 0x8012, 0,
+ 16, 0x2F7F, 0x8033, 0,
+ 16, 0x2F80, 0x807F, 0,
+ 16, 0x2F81, 0x8089, 0,
+ 16, 0x2F82, 0x81E3, 0,
+ 16, 0x2F83, 0x81EA, 0,
+ 16, 0x2F84, 0x81F3, 0,
+ 16, 0x2F85, 0x81FC, 0,
+ 16, 0x2F86, 0x820C, 0,
+ 16, 0x2F87, 0x821B, 0,
+ 16, 0x2F88, 0x821F, 0,
+ 16, 0x2F89, 0x826E, 0,
+ 16, 0x2F8A, 0x8272, 0,
+ 16, 0x2F8B, 0x8278, 0,
+ 16, 0x2F8C, 0x864D, 0,
+ 16, 0x2F8D, 0x866B, 0,
+ 16, 0x2F8E, 0x8840, 0,
+ 16, 0x2F8F, 0x884C, 0,
+ 16, 0x2F90, 0x8863, 0,
+ 16, 0x2F91, 0x897E, 0,
+ 16, 0x2F92, 0x898B, 0,
+ 16, 0x2F93, 0x89D2, 0,
+ 16, 0x2F94, 0x8A00, 0,
+ 16, 0x2F95, 0x8C37, 0,
+ 16, 0x2F96, 0x8C46, 0,
+ 16, 0x2F97, 0x8C55, 0,
+ 16, 0x2F98, 0x8C78, 0,
+ 16, 0x2F99, 0x8C9D, 0,
+ 16, 0x2F9A, 0x8D64, 0,
+ 16, 0x2F9B, 0x8D70, 0,
+ 16, 0x2F9C, 0x8DB3, 0,
+ 16, 0x2F9D, 0x8EAB, 0,
+ 16, 0x2F9E, 0x8ECA, 0,
+ 16, 0x2F9F, 0x8F9B, 0,
+ 16, 0x2FA0, 0x8FB0, 0,
+ 16, 0x2FA1, 0x8FB5, 0,
+ 16, 0x2FA2, 0x9091, 0,
+ 16, 0x2FA3, 0x9149, 0,
+ 16, 0x2FA4, 0x91C6, 0,
+ 16, 0x2FA5, 0x91CC, 0,
+ 16, 0x2FA6, 0x91D1, 0,
+ 16, 0x2FA7, 0x9577, 0,
+ 16, 0x2FA8, 0x9580, 0,
+ 16, 0x2FA9, 0x961C, 0,
+ 16, 0x2FAA, 0x96B6, 0,
+ 16, 0x2FAB, 0x96B9, 0,
+ 16, 0x2FAC, 0x96E8, 0,
+ 16, 0x2FAD, 0x9751, 0,
+ 16, 0x2FAE, 0x975E, 0,
+ 16, 0x2FAF, 0x9762, 0,
+ 16, 0x2FB0, 0x9769, 0,
+ 16, 0x2FB1, 0x97CB, 0,
+ 16, 0x2FB2, 0x97ED, 0,
+ 16, 0x2FB3, 0x97F3, 0,
+ 16, 0x2FB4, 0x9801, 0,
+ 16, 0x2FB5, 0x98A8, 0,
+ 16, 0x2FB6, 0x98DB, 0,
+ 16, 0x2FB7, 0x98DF, 0,
+ 16, 0x2FB8, 0x9996, 0,
+ 16, 0x2FB9, 0x9999, 0,
+ 16, 0x2FBA, 0x99AC, 0,
+ 16, 0x2FBB, 0x9AA8, 0,
+ 16, 0x2FBC, 0x9AD8, 0,
+ 16, 0x2FBD, 0x9ADF, 0,
+ 16, 0x2FBE, 0x9B25, 0,
+ 16, 0x2FBF, 0x9B2F, 0,
+ 16, 0x2FC0, 0x9B32, 0,
+ 16, 0x2FC1, 0x9B3C, 0,
+ 16, 0x2FC2, 0x9B5A, 0,
+ 16, 0x2FC3, 0x9CE5, 0,
+ 16, 0x2FC4, 0x9E75, 0,
+ 16, 0x2FC5, 0x9E7F, 0,
+ 16, 0x2FC6, 0x9EA5, 0,
+ 16, 0x2FC7, 0x9EBB, 0,
+ 16, 0x2FC8, 0x9EC3, 0,
+ 16, 0x2FC9, 0x9ECD, 0,
+ 16, 0x2FCA, 0x9ED1, 0,
+ 16, 0x2FCB, 0x9EF9, 0,
+ 16, 0x2FCC, 0x9EFD, 0,
+ 16, 0x2FCD, 0x9F0E, 0,
+ 16, 0x2FCE, 0x9F13, 0,
+ 16, 0x2FCF, 0x9F20, 0,
+ 16, 0x2FD0, 0x9F3B, 0,
+ 16, 0x2FD1, 0x9F4A, 0,
+ 16, 0x2FD2, 0x9F52, 0,
+ 16, 0x2FD3, 0x9F8D, 0,
+ 16, 0x2FD4, 0x9F9C, 0,
+ 16, 0x2FD5, 0x9FA0, 0,
+ 12, 0x3000, 0x0020, 0,
+ 16, 0x3036, 0x3012, 0,
+ 16, 0x3038, 0x5341, 0,
+ 16, 0x3039, 0x5344, 0,
+ 16, 0x303A, 0x5345, 0,
+ 1, 0x304C, 0x304B, 0x3099, 0,
+ 1, 0x304E, 0x304D, 0x3099, 0,
+ 1, 0x3050, 0x304F, 0x3099, 0,
+ 1, 0x3052, 0x3051, 0x3099, 0,
+ 1, 0x3054, 0x3053, 0x3099, 0,
+ 1, 0x3056, 0x3055, 0x3099, 0,
+ 1, 0x3058, 0x3057, 0x3099, 0,
+ 1, 0x305A, 0x3059, 0x3099, 0,
+ 1, 0x305C, 0x305B, 0x3099, 0,
+ 1, 0x305E, 0x305D, 0x3099, 0,
+ 1, 0x3060, 0x305F, 0x3099, 0,
+ 1, 0x3062, 0x3061, 0x3099, 0,
+ 1, 0x3065, 0x3064, 0x3099, 0,
+ 1, 0x3067, 0x3066, 0x3099, 0,
+ 1, 0x3069, 0x3068, 0x3099, 0,
+ 1, 0x3070, 0x306F, 0x3099, 0,
+ 1, 0x3071, 0x306F, 0x309A, 0,
+ 1, 0x3073, 0x3072, 0x3099, 0,
+ 1, 0x3074, 0x3072, 0x309A, 0,
+ 1, 0x3076, 0x3075, 0x3099, 0,
+ 1, 0x3077, 0x3075, 0x309A, 0,
+ 1, 0x3079, 0x3078, 0x3099, 0,
+ 1, 0x307A, 0x3078, 0x309A, 0,
+ 1, 0x307C, 0x307B, 0x3099, 0,
+ 1, 0x307D, 0x307B, 0x309A, 0,
+ 1, 0x3094, 0x3046, 0x3099, 0,
+ 16, 0x309B, 0x0020, 0x3099, 0,
+ 16, 0x309C, 0x0020, 0x309A, 0,
+ 1, 0x309E, 0x309D, 0x3099, 0,
+ 1, 0x30AC, 0x30AB, 0x3099, 0,
+ 1, 0x30AE, 0x30AD, 0x3099, 0,
+ 1, 0x30B0, 0x30AF, 0x3099, 0,
+ 1, 0x30B2, 0x30B1, 0x3099, 0,
+ 1, 0x30B4, 0x30B3, 0x3099, 0,
+ 1, 0x30B6, 0x30B5, 0x3099, 0,
+ 1, 0x30B8, 0x30B7, 0x3099, 0,
+ 1, 0x30BA, 0x30B9, 0x3099, 0,
+ 1, 0x30BC, 0x30BB, 0x3099, 0,
+ 1, 0x30BE, 0x30BD, 0x3099, 0,
+ 1, 0x30C0, 0x30BF, 0x3099, 0,
+ 1, 0x30C2, 0x30C1, 0x3099, 0,
+ 1, 0x30C5, 0x30C4, 0x3099, 0,
+ 1, 0x30C7, 0x30C6, 0x3099, 0,
+ 1, 0x30C9, 0x30C8, 0x3099, 0,
+ 1, 0x30D0, 0x30CF, 0x3099, 0,
+ 1, 0x30D1, 0x30CF, 0x309A, 0,
+ 1, 0x30D3, 0x30D2, 0x3099, 0,
+ 1, 0x30D4, 0x30D2, 0x309A, 0,
+ 1, 0x30D6, 0x30D5, 0x3099, 0,
+ 1, 0x30D7, 0x30D5, 0x309A, 0,
+ 1, 0x30D9, 0x30D8, 0x3099, 0,
+ 1, 0x30DA, 0x30D8, 0x309A, 0,
+ 1, 0x30DC, 0x30DB, 0x3099, 0,
+ 1, 0x30DD, 0x30DB, 0x309A, 0,
+ 1, 0x30F4, 0x30A6, 0x3099, 0,
+ 1, 0x30F7, 0x30EF, 0x3099, 0,
+ 1, 0x30F8, 0x30F0, 0x3099, 0,
+ 1, 0x30F9, 0x30F1, 0x3099, 0,
+ 1, 0x30FA, 0x30F2, 0x3099, 0,
+ 1, 0x30FE, 0x30FD, 0x3099, 0,
+ 16, 0x3131, 0x1100, 0,
+ 16, 0x3132, 0x1101, 0,
+ 16, 0x3133, 0x11AA, 0,
+ 16, 0x3134, 0x1102, 0,
+ 16, 0x3135, 0x11AC, 0,
+ 16, 0x3136, 0x11AD, 0,
+ 16, 0x3137, 0x1103, 0,
+ 16, 0x3138, 0x1104, 0,
+ 16, 0x3139, 0x1105, 0,
+ 16, 0x313A, 0x11B0, 0,
+ 16, 0x313B, 0x11B1, 0,
+ 16, 0x313C, 0x11B2, 0,
+ 16, 0x313D, 0x11B3, 0,
+ 16, 0x313E, 0x11B4, 0,
+ 16, 0x313F, 0x11B5, 0,
+ 16, 0x3140, 0x111A, 0,
+ 16, 0x3141, 0x1106, 0,
+ 16, 0x3142, 0x1107, 0,
+ 16, 0x3143, 0x1108, 0,
+ 16, 0x3144, 0x1121, 0,
+ 16, 0x3145, 0x1109, 0,
+ 16, 0x3146, 0x110A, 0,
+ 16, 0x3147, 0x110B, 0,
+ 16, 0x3148, 0x110C, 0,
+ 16, 0x3149, 0x110D, 0,
+ 16, 0x314A, 0x110E, 0,
+ 16, 0x314B, 0x110F, 0,
+ 16, 0x314C, 0x1110, 0,
+ 16, 0x314D, 0x1111, 0,
+ 16, 0x314E, 0x1112, 0,
+ 16, 0x314F, 0x1161, 0,
+ 16, 0x3150, 0x1162, 0,
+ 16, 0x3151, 0x1163, 0,
+ 16, 0x3152, 0x1164, 0,
+ 16, 0x3153, 0x1165, 0,
+ 16, 0x3154, 0x1166, 0,
+ 16, 0x3155, 0x1167, 0,
+ 16, 0x3156, 0x1168, 0,
+ 16, 0x3157, 0x1169, 0,
+ 16, 0x3158, 0x116A, 0,
+ 16, 0x3159, 0x116B, 0,
+ 16, 0x315A, 0x116C, 0,
+ 16, 0x315B, 0x116D, 0,
+ 16, 0x315C, 0x116E, 0,
+ 16, 0x315D, 0x116F, 0,
+ 16, 0x315E, 0x1170, 0,
+ 16, 0x315F, 0x1171, 0,
+ 16, 0x3160, 0x1172, 0,
+ 16, 0x3161, 0x1173, 0,
+ 16, 0x3162, 0x1174, 0,
+ 16, 0x3163, 0x1175, 0,
+ 16, 0x3164, 0x1160, 0,
+ 16, 0x3165, 0x1114, 0,
+ 16, 0x3166, 0x1115, 0,
+ 16, 0x3167, 0x11C7, 0,
+ 16, 0x3168, 0x11C8, 0,
+ 16, 0x3169, 0x11CC, 0,
+ 16, 0x316A, 0x11CE, 0,
+ 16, 0x316B, 0x11D3, 0,
+ 16, 0x316C, 0x11D7, 0,
+ 16, 0x316D, 0x11D9, 0,
+ 16, 0x316E, 0x111C, 0,
+ 16, 0x316F, 0x11DD, 0,
+ 16, 0x3170, 0x11DF, 0,
+ 16, 0x3171, 0x111D, 0,
+ 16, 0x3172, 0x111E, 0,
+ 16, 0x3173, 0x1120, 0,
+ 16, 0x3174, 0x1122, 0,
+ 16, 0x3175, 0x1123, 0,
+ 16, 0x3176, 0x1127, 0,
+ 16, 0x3177, 0x1129, 0,
+ 16, 0x3178, 0x112B, 0,
+ 16, 0x3179, 0x112C, 0,
+ 16, 0x317A, 0x112D, 0,
+ 16, 0x317B, 0x112E, 0,
+ 16, 0x317C, 0x112F, 0,
+ 16, 0x317D, 0x1132, 0,
+ 16, 0x317E, 0x1136, 0,
+ 16, 0x317F, 0x1140, 0,
+ 16, 0x3180, 0x1147, 0,
+ 16, 0x3181, 0x114C, 0,
+ 16, 0x3182, 0x11F1, 0,
+ 16, 0x3183, 0x11F2, 0,
+ 16, 0x3184, 0x1157, 0,
+ 16, 0x3185, 0x1158, 0,
+ 16, 0x3186, 0x1159, 0,
+ 16, 0x3187, 0x1184, 0,
+ 16, 0x3188, 0x1185, 0,
+ 16, 0x3189, 0x1188, 0,
+ 16, 0x318A, 0x1191, 0,
+ 16, 0x318B, 0x1192, 0,
+ 16, 0x318C, 0x1194, 0,
+ 16, 0x318D, 0x119E, 0,
+ 16, 0x318E, 0x11A1, 0,
+ 9, 0x3192, 0x4E00, 0,
+ 9, 0x3193, 0x4E8C, 0,
+ 9, 0x3194, 0x4E09, 0,
+ 9, 0x3195, 0x56DB, 0,
+ 9, 0x3196, 0x4E0A, 0,
+ 9, 0x3197, 0x4E2D, 0,
+ 9, 0x3198, 0x4E0B, 0,
+ 9, 0x3199, 0x7532, 0,
+ 9, 0x319A, 0x4E59, 0,
+ 9, 0x319B, 0x4E19, 0,
+ 9, 0x319C, 0x4E01, 0,
+ 9, 0x319D, 0x5929, 0,
+ 9, 0x319E, 0x5730, 0,
+ 9, 0x319F, 0x4EBA, 0,
+ 16, 0x3200, 0x0028, 0x1100, 0x0029, 0,
+ 16, 0x3201, 0x0028, 0x1102, 0x0029, 0,
+ 16, 0x3202, 0x0028, 0x1103, 0x0029, 0,
+ 16, 0x3203, 0x0028, 0x1105, 0x0029, 0,
+ 16, 0x3204, 0x0028, 0x1106, 0x0029, 0,
+ 16, 0x3205, 0x0028, 0x1107, 0x0029, 0,
+ 16, 0x3206, 0x0028, 0x1109, 0x0029, 0,
+ 16, 0x3207, 0x0028, 0x110B, 0x0029, 0,
+ 16, 0x3208, 0x0028, 0x110C, 0x0029, 0,
+ 16, 0x3209, 0x0028, 0x110E, 0x0029, 0,
+ 16, 0x320A, 0x0028, 0x110F, 0x0029, 0,
+ 16, 0x320B, 0x0028, 0x1110, 0x0029, 0,
+ 16, 0x320C, 0x0028, 0x1111, 0x0029, 0,
+ 16, 0x320D, 0x0028, 0x1112, 0x0029, 0,
+ 16, 0x320E, 0x0028, 0x1100, 0x1161, 0x0029, 0,
+ 16, 0x320F, 0x0028, 0x1102, 0x1161, 0x0029, 0,
+ 16, 0x3210, 0x0028, 0x1103, 0x1161, 0x0029, 0,
+ 16, 0x3211, 0x0028, 0x1105, 0x1161, 0x0029, 0,
+ 16, 0x3212, 0x0028, 0x1106, 0x1161, 0x0029, 0,
+ 16, 0x3213, 0x0028, 0x1107, 0x1161, 0x0029, 0,
+ 16, 0x3214, 0x0028, 0x1109, 0x1161, 0x0029, 0,
+ 16, 0x3215, 0x0028, 0x110B, 0x1161, 0x0029, 0,
+ 16, 0x3216, 0x0028, 0x110C, 0x1161, 0x0029, 0,
+ 16, 0x3217, 0x0028, 0x110E, 0x1161, 0x0029, 0,
+ 16, 0x3218, 0x0028, 0x110F, 0x1161, 0x0029, 0,
+ 16, 0x3219, 0x0028, 0x1110, 0x1161, 0x0029, 0,
+ 16, 0x321A, 0x0028, 0x1111, 0x1161, 0x0029, 0,
+ 16, 0x321B, 0x0028, 0x1112, 0x1161, 0x0029, 0,
+ 16, 0x321C, 0x0028, 0x110C, 0x116E, 0x0029, 0,
+ 16, 0x3220, 0x0028, 0x4E00, 0x0029, 0,
+ 16, 0x3221, 0x0028, 0x4E8C, 0x0029, 0,
+ 16, 0x3222, 0x0028, 0x4E09, 0x0029, 0,
+ 16, 0x3223, 0x0028, 0x56DB, 0x0029, 0,
+ 16, 0x3224, 0x0028, 0x4E94, 0x0029, 0,
+ 16, 0x3225, 0x0028, 0x516D, 0x0029, 0,
+ 16, 0x3226, 0x0028, 0x4E03, 0x0029, 0,
+ 16, 0x3227, 0x0028, 0x516B, 0x0029, 0,
+ 16, 0x3228, 0x0028, 0x4E5D, 0x0029, 0,
+ 16, 0x3229, 0x0028, 0x5341, 0x0029, 0,
+ 16, 0x322A, 0x0028, 0x6708, 0x0029, 0,
+ 16, 0x322B, 0x0028, 0x706B, 0x0029, 0,
+ 16, 0x322C, 0x0028, 0x6C34, 0x0029, 0,
+ 16, 0x322D, 0x0028, 0x6728, 0x0029, 0,
+ 16, 0x322E, 0x0028, 0x91D1, 0x0029, 0,
+ 16, 0x322F, 0x0028, 0x571F, 0x0029, 0,
+ 16, 0x3230, 0x0028, 0x65E5, 0x0029, 0,
+ 16, 0x3231, 0x0028, 0x682A, 0x0029, 0,
+ 16, 0x3232, 0x0028, 0x6709, 0x0029, 0,
+ 16, 0x3233, 0x0028, 0x793E, 0x0029, 0,
+ 16, 0x3234, 0x0028, 0x540D, 0x0029, 0,
+ 16, 0x3235, 0x0028, 0x7279, 0x0029, 0,
+ 16, 0x3236, 0x0028, 0x8CA1, 0x0029, 0,
+ 16, 0x3237, 0x0028, 0x795D, 0x0029, 0,
+ 16, 0x3238, 0x0028, 0x52B4, 0x0029, 0,
+ 16, 0x3239, 0x0028, 0x4EE3, 0x0029, 0,
+ 16, 0x323A, 0x0028, 0x547C, 0x0029, 0,
+ 16, 0x323B, 0x0028, 0x5B66, 0x0029, 0,
+ 16, 0x323C, 0x0028, 0x76E3, 0x0029, 0,
+ 16, 0x323D, 0x0028, 0x4F01, 0x0029, 0,
+ 16, 0x323E, 0x0028, 0x8CC7, 0x0029, 0,
+ 16, 0x323F, 0x0028, 0x5354, 0x0029, 0,
+ 16, 0x3240, 0x0028, 0x796D, 0x0029, 0,
+ 16, 0x3241, 0x0028, 0x4F11, 0x0029, 0,
+ 16, 0x3242, 0x0028, 0x81EA, 0x0029, 0,
+ 16, 0x3243, 0x0028, 0x81F3, 0x0029, 0,
+ 8, 0x3260, 0x1100, 0,
+ 8, 0x3261, 0x1102, 0,
+ 8, 0x3262, 0x1103, 0,
+ 8, 0x3263, 0x1105, 0,
+ 8, 0x3264, 0x1106, 0,
+ 8, 0x3265, 0x1107, 0,
+ 8, 0x3266, 0x1109, 0,
+ 8, 0x3267, 0x110B, 0,
+ 8, 0x3268, 0x110C, 0,
+ 8, 0x3269, 0x110E, 0,
+ 8, 0x326A, 0x110F, 0,
+ 8, 0x326B, 0x1110, 0,
+ 8, 0x326C, 0x1111, 0,
+ 8, 0x326D, 0x1112, 0,
+ 8, 0x326E, 0x1100, 0x1161, 0,
+ 8, 0x326F, 0x1102, 0x1161, 0,
+ 8, 0x3270, 0x1103, 0x1161, 0,
+ 8, 0x3271, 0x1105, 0x1161, 0,
+ 8, 0x3272, 0x1106, 0x1161, 0,
+ 8, 0x3273, 0x1107, 0x1161, 0,
+ 8, 0x3274, 0x1109, 0x1161, 0,
+ 8, 0x3275, 0x110B, 0x1161, 0,
+ 8, 0x3276, 0x110C, 0x1161, 0,
+ 8, 0x3277, 0x110E, 0x1161, 0,
+ 8, 0x3278, 0x110F, 0x1161, 0,
+ 8, 0x3279, 0x1110, 0x1161, 0,
+ 8, 0x327A, 0x1111, 0x1161, 0,
+ 8, 0x327B, 0x1112, 0x1161, 0,
+ 8, 0x3280, 0x4E00, 0,
+ 8, 0x3281, 0x4E8C, 0,
+ 8, 0x3282, 0x4E09, 0,
+ 8, 0x3283, 0x56DB, 0,
+ 8, 0x3284, 0x4E94, 0,
+ 8, 0x3285, 0x516D, 0,
+ 8, 0x3286, 0x4E03, 0,
+ 8, 0x3287, 0x516B, 0,
+ 8, 0x3288, 0x4E5D, 0,
+ 8, 0x3289, 0x5341, 0,
+ 8, 0x328A, 0x6708, 0,
+ 8, 0x328B, 0x706B, 0,
+ 8, 0x328C, 0x6C34, 0,
+ 8, 0x328D, 0x6728, 0,
+ 8, 0x328E, 0x91D1, 0,
+ 8, 0x328F, 0x571F, 0,
+ 8, 0x3290, 0x65E5, 0,
+ 8, 0x3291, 0x682A, 0,
+ 8, 0x3292, 0x6709, 0,
+ 8, 0x3293, 0x793E, 0,
+ 8, 0x3294, 0x540D, 0,
+ 8, 0x3295, 0x7279, 0,
+ 8, 0x3296, 0x8CA1, 0,
+ 8, 0x3297, 0x795D, 0,
+ 8, 0x3298, 0x52B4, 0,
+ 8, 0x3299, 0x79D8, 0,
+ 8, 0x329A, 0x7537, 0,
+ 8, 0x329B, 0x5973, 0,
+ 8, 0x329C, 0x9069, 0,
+ 8, 0x329D, 0x512A, 0,
+ 8, 0x329E, 0x5370, 0,
+ 8, 0x329F, 0x6CE8, 0,
+ 8, 0x32A0, 0x9805, 0,
+ 8, 0x32A1, 0x4F11, 0,
+ 8, 0x32A2, 0x5199, 0,
+ 8, 0x32A3, 0x6B63, 0,
+ 8, 0x32A4, 0x4E0A, 0,
+ 8, 0x32A5, 0x4E2D, 0,
+ 8, 0x32A6, 0x4E0B, 0,
+ 8, 0x32A7, 0x5DE6, 0,
+ 8, 0x32A8, 0x53F3, 0,
+ 8, 0x32A9, 0x533B, 0,
+ 8, 0x32AA, 0x5B97, 0,
+ 8, 0x32AB, 0x5B66, 0,
+ 8, 0x32AC, 0x76E3, 0,
+ 8, 0x32AD, 0x4F01, 0,
+ 8, 0x32AE, 0x8CC7, 0,
+ 8, 0x32AF, 0x5354, 0,
+ 8, 0x32B0, 0x591C, 0,
+ 16, 0x32C0, 0x0031, 0x6708, 0,
+ 16, 0x32C1, 0x0032, 0x6708, 0,
+ 16, 0x32C2, 0x0033, 0x6708, 0,
+ 16, 0x32C3, 0x0034, 0x6708, 0,
+ 16, 0x32C4, 0x0035, 0x6708, 0,
+ 16, 0x32C5, 0x0036, 0x6708, 0,
+ 16, 0x32C6, 0x0037, 0x6708, 0,
+ 16, 0x32C7, 0x0038, 0x6708, 0,
+ 16, 0x32C8, 0x0039, 0x6708, 0,
+ 16, 0x32C9, 0x0031, 0x0030, 0x6708, 0,
+ 16, 0x32CA, 0x0031, 0x0031, 0x6708, 0,
+ 16, 0x32CB, 0x0031, 0x0032, 0x6708, 0,
+ 8, 0x32D0, 0x30A2, 0,
+ 8, 0x32D1, 0x30A4, 0,
+ 8, 0x32D2, 0x30A6, 0,
+ 8, 0x32D3, 0x30A8, 0,
+ 8, 0x32D4, 0x30AA, 0,
+ 8, 0x32D5, 0x30AB, 0,
+ 8, 0x32D6, 0x30AD, 0,
+ 8, 0x32D7, 0x30AF, 0,
+ 8, 0x32D8, 0x30B1, 0,
+ 8, 0x32D9, 0x30B3, 0,
+ 8, 0x32DA, 0x30B5, 0,
+ 8, 0x32DB, 0x30B7, 0,
+ 8, 0x32DC, 0x30B9, 0,
+ 8, 0x32DD, 0x30BB, 0,
+ 8, 0x32DE, 0x30BD, 0,
+ 8, 0x32DF, 0x30BF, 0,
+ 8, 0x32E0, 0x30C1, 0,
+ 8, 0x32E1, 0x30C4, 0,
+ 8, 0x32E2, 0x30C6, 0,
+ 8, 0x32E3, 0x30C8, 0,
+ 8, 0x32E4, 0x30CA, 0,
+ 8, 0x32E5, 0x30CB, 0,
+ 8, 0x32E6, 0x30CC, 0,
+ 8, 0x32E7, 0x30CD, 0,
+ 8, 0x32E8, 0x30CE, 0,
+ 8, 0x32E9, 0x30CF, 0,
+ 8, 0x32EA, 0x30D2, 0,
+ 8, 0x32EB, 0x30D5, 0,
+ 8, 0x32EC, 0x30D8, 0,
+ 8, 0x32ED, 0x30DB, 0,
+ 8, 0x32EE, 0x30DE, 0,
+ 8, 0x32EF, 0x30DF, 0,
+ 8, 0x32F0, 0x30E0, 0,
+ 8, 0x32F1, 0x30E1, 0,
+ 8, 0x32F2, 0x30E2, 0,
+ 8, 0x32F3, 0x30E4, 0,
+ 8, 0x32F4, 0x30E6, 0,
+ 8, 0x32F5, 0x30E8, 0,
+ 8, 0x32F6, 0x30E9, 0,
+ 8, 0x32F7, 0x30EA, 0,
+ 8, 0x32F8, 0x30EB, 0,
+ 8, 0x32F9, 0x30EC, 0,
+ 8, 0x32FA, 0x30ED, 0,
+ 8, 0x32FB, 0x30EF, 0,
+ 8, 0x32FC, 0x30F0, 0,
+ 8, 0x32FD, 0x30F1, 0,
+ 8, 0x32FE, 0x30F2, 0,
+ 15, 0x3300, 0x30A2, 0x30D1, 0x30FC, 0x30C8, 0,
+ 15, 0x3301, 0x30A2, 0x30EB, 0x30D5, 0x30A1, 0,
+ 15, 0x3302, 0x30A2, 0x30F3, 0x30DA, 0x30A2, 0,
+ 15, 0x3303, 0x30A2, 0x30FC, 0x30EB, 0,
+ 15, 0x3304, 0x30A4, 0x30CB, 0x30F3, 0x30B0, 0,
+ 15, 0x3305, 0x30A4, 0x30F3, 0x30C1, 0,
+ 15, 0x3306, 0x30A6, 0x30A9, 0x30F3, 0,
+ 15, 0x3307, 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, 0,
+ 15, 0x3308, 0x30A8, 0x30FC, 0x30AB, 0x30FC, 0,
+ 15, 0x3309, 0x30AA, 0x30F3, 0x30B9, 0,
+ 15, 0x330A, 0x30AA, 0x30FC, 0x30E0, 0,
+ 15, 0x330B, 0x30AB, 0x30A4, 0x30EA, 0,
+ 15, 0x330C, 0x30AB, 0x30E9, 0x30C3, 0x30C8, 0,
+ 15, 0x330D, 0x30AB, 0x30ED, 0x30EA, 0x30FC, 0,
+ 15, 0x330E, 0x30AC, 0x30ED, 0x30F3, 0,
+ 15, 0x330F, 0x30AC, 0x30F3, 0x30DE, 0,
+ 15, 0x3310, 0x30AE, 0x30AC, 0,
+ 15, 0x3311, 0x30AE, 0x30CB, 0x30FC, 0,
+ 15, 0x3312, 0x30AD, 0x30E5, 0x30EA, 0x30FC, 0,
+ 15, 0x3313, 0x30AE, 0x30EB, 0x30C0, 0x30FC, 0,
+ 15, 0x3314, 0x30AD, 0x30ED, 0,
+ 15, 0x3315, 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, 0,
+ 15, 0x3316, 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
+ 15, 0x3317, 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, 0,
+ 15, 0x3318, 0x30B0, 0x30E9, 0x30E0, 0,
+ 15, 0x3319, 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, 0,
+ 15, 0x331A, 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, 0,
+ 15, 0x331B, 0x30AF, 0x30ED, 0x30FC, 0x30CD, 0,
+ 15, 0x331C, 0x30B1, 0x30FC, 0x30B9, 0,
+ 15, 0x331D, 0x30B3, 0x30EB, 0x30CA, 0,
+ 15, 0x331E, 0x30B3, 0x30FC, 0x30DD, 0,
+ 15, 0x331F, 0x30B5, 0x30A4, 0x30AF, 0x30EB, 0,
+ 15, 0x3320, 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, 0,
+ 15, 0x3321, 0x30B7, 0x30EA, 0x30F3, 0x30B0, 0,
+ 15, 0x3322, 0x30BB, 0x30F3, 0x30C1, 0,
+ 15, 0x3323, 0x30BB, 0x30F3, 0x30C8, 0,
+ 15, 0x3324, 0x30C0, 0x30FC, 0x30B9, 0,
+ 15, 0x3325, 0x30C7, 0x30B7, 0,
+ 15, 0x3326, 0x30C9, 0x30EB, 0,
+ 15, 0x3327, 0x30C8, 0x30F3, 0,
+ 15, 0x3328, 0x30CA, 0x30CE, 0,
+ 15, 0x3329, 0x30CE, 0x30C3, 0x30C8, 0,
+ 15, 0x332A, 0x30CF, 0x30A4, 0x30C4, 0,
+ 15, 0x332B, 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, 0,
+ 15, 0x332C, 0x30D1, 0x30FC, 0x30C4, 0,
+ 15, 0x332D, 0x30D0, 0x30FC, 0x30EC, 0x30EB, 0,
+ 15, 0x332E, 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, 0,
+ 15, 0x332F, 0x30D4, 0x30AF, 0x30EB, 0,
+ 15, 0x3330, 0x30D4, 0x30B3, 0,
+ 15, 0x3331, 0x30D3, 0x30EB, 0,
+ 15, 0x3332, 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, 0,
+ 15, 0x3333, 0x30D5, 0x30A3, 0x30FC, 0x30C8, 0,
+ 15, 0x3334, 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, 0,
+ 15, 0x3335, 0x30D5, 0x30E9, 0x30F3, 0,
+ 15, 0x3336, 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, 0,
+ 15, 0x3337, 0x30DA, 0x30BD, 0,
+ 15, 0x3338, 0x30DA, 0x30CB, 0x30D2, 0,
+ 15, 0x3339, 0x30D8, 0x30EB, 0x30C4, 0,
+ 15, 0x333A, 0x30DA, 0x30F3, 0x30B9, 0,
+ 15, 0x333B, 0x30DA, 0x30FC, 0x30B8, 0,
+ 15, 0x333C, 0x30D9, 0x30FC, 0x30BF, 0,
+ 15, 0x333D, 0x30DD, 0x30A4, 0x30F3, 0x30C8, 0,
+ 15, 0x333E, 0x30DC, 0x30EB, 0x30C8, 0,
+ 15, 0x333F, 0x30DB, 0x30F3, 0,
+ 15, 0x3340, 0x30DD, 0x30F3, 0x30C9, 0,
+ 15, 0x3341, 0x30DB, 0x30FC, 0x30EB, 0,
+ 15, 0x3342, 0x30DB, 0x30FC, 0x30F3, 0,
+ 15, 0x3343, 0x30DE, 0x30A4, 0x30AF, 0x30ED, 0,
+ 15, 0x3344, 0x30DE, 0x30A4, 0x30EB, 0,
+ 15, 0x3345, 0x30DE, 0x30C3, 0x30CF, 0,
+ 15, 0x3346, 0x30DE, 0x30EB, 0x30AF, 0,
+ 15, 0x3347, 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, 0,
+ 15, 0x3348, 0x30DF, 0x30AF, 0x30ED, 0x30F3, 0,
+ 15, 0x3349, 0x30DF, 0x30EA, 0,
+ 15, 0x334A, 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, 0,
+ 15, 0x334B, 0x30E1, 0x30AC, 0,
+ 15, 0x334C, 0x30E1, 0x30AC, 0x30C8, 0x30F3, 0,
+ 15, 0x334D, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
+ 15, 0x334E, 0x30E4, 0x30FC, 0x30C9, 0,
+ 15, 0x334F, 0x30E4, 0x30FC, 0x30EB, 0,
+ 15, 0x3350, 0x30E6, 0x30A2, 0x30F3, 0,
+ 15, 0x3351, 0x30EA, 0x30C3, 0x30C8, 0x30EB, 0,
+ 15, 0x3352, 0x30EA, 0x30E9, 0,
+ 15, 0x3353, 0x30EB, 0x30D4, 0x30FC, 0,
+ 15, 0x3354, 0x30EB, 0x30FC, 0x30D6, 0x30EB, 0,
+ 15, 0x3355, 0x30EC, 0x30E0, 0,
+ 15, 0x3356, 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, 0,
+ 15, 0x3357, 0x30EF, 0x30C3, 0x30C8, 0,
+ 16, 0x3358, 0x0030, 0x70B9, 0,
+ 16, 0x3359, 0x0031, 0x70B9, 0,
+ 16, 0x335A, 0x0032, 0x70B9, 0,
+ 16, 0x335B, 0x0033, 0x70B9, 0,
+ 16, 0x335C, 0x0034, 0x70B9, 0,
+ 16, 0x335D, 0x0035, 0x70B9, 0,
+ 16, 0x335E, 0x0036, 0x70B9, 0,
+ 16, 0x335F, 0x0037, 0x70B9, 0,
+ 16, 0x3360, 0x0038, 0x70B9, 0,
+ 16, 0x3361, 0x0039, 0x70B9, 0,
+ 16, 0x3362, 0x0031, 0x0030, 0x70B9, 0,
+ 16, 0x3363, 0x0031, 0x0031, 0x70B9, 0,
+ 16, 0x3364, 0x0031, 0x0032, 0x70B9, 0,
+ 16, 0x3365, 0x0031, 0x0033, 0x70B9, 0,
+ 16, 0x3366, 0x0031, 0x0034, 0x70B9, 0,
+ 16, 0x3367, 0x0031, 0x0035, 0x70B9, 0,
+ 16, 0x3368, 0x0031, 0x0036, 0x70B9, 0,
+ 16, 0x3369, 0x0031, 0x0037, 0x70B9, 0,
+ 16, 0x336A, 0x0031, 0x0038, 0x70B9, 0,
+ 16, 0x336B, 0x0031, 0x0039, 0x70B9, 0,
+ 16, 0x336C, 0x0032, 0x0030, 0x70B9, 0,
+ 16, 0x336D, 0x0032, 0x0031, 0x70B9, 0,
+ 16, 0x336E, 0x0032, 0x0032, 0x70B9, 0,
+ 16, 0x336F, 0x0032, 0x0033, 0x70B9, 0,
+ 16, 0x3370, 0x0032, 0x0034, 0x70B9, 0,
+ 15, 0x3371, 0x0068, 0x0050, 0x0061, 0,
+ 15, 0x3372, 0x0064, 0x0061, 0,
+ 15, 0x3373, 0x0041, 0x0055, 0,
+ 15, 0x3374, 0x0062, 0x0061, 0x0072, 0,
+ 15, 0x3375, 0x006F, 0x0056, 0,
+ 15, 0x3376, 0x0070, 0x0063, 0,
+ 15, 0x337B, 0x5E73, 0x6210, 0,
+ 15, 0x337C, 0x662D, 0x548C, 0,
+ 15, 0x337D, 0x5927, 0x6B63, 0,
+ 15, 0x337E, 0x660E, 0x6CBB, 0,
+ 15, 0x337F, 0x682A, 0x5F0F, 0x4F1A, 0x793E, 0,
+ 15, 0x3380, 0x0070, 0x0041, 0,
+ 15, 0x3381, 0x006E, 0x0041, 0,
+ 15, 0x3382, 0x03BC, 0x0041, 0,
+ 15, 0x3383, 0x006D, 0x0041, 0,
+ 15, 0x3384, 0x006B, 0x0041, 0,
+ 15, 0x3385, 0x004B, 0x0042, 0,
+ 15, 0x3386, 0x004D, 0x0042, 0,
+ 15, 0x3387, 0x0047, 0x0042, 0,
+ 15, 0x3388, 0x0063, 0x0061, 0x006C, 0,
+ 15, 0x3389, 0x006B, 0x0063, 0x0061, 0x006C, 0,
+ 15, 0x338A, 0x0070, 0x0046, 0,
+ 15, 0x338B, 0x006E, 0x0046, 0,
+ 15, 0x338C, 0x03BC, 0x0046, 0,
+ 15, 0x338D, 0x03BC, 0x0067, 0,
+ 15, 0x338E, 0x006D, 0x0067, 0,
+ 15, 0x338F, 0x006B, 0x0067, 0,
+ 15, 0x3390, 0x0048, 0x007A, 0,
+ 15, 0x3391, 0x006B, 0x0048, 0x007A, 0,
+ 15, 0x3392, 0x004D, 0x0048, 0x007A, 0,
+ 15, 0x3393, 0x0047, 0x0048, 0x007A, 0,
+ 15, 0x3394, 0x0054, 0x0048, 0x007A, 0,
+ 15, 0x3395, 0x03BC, 0x2113, 0,
+ 15, 0x3396, 0x006D, 0x2113, 0,
+ 15, 0x3397, 0x0064, 0x2113, 0,
+ 15, 0x3398, 0x006B, 0x2113, 0,
+ 15, 0x3399, 0x0066, 0x006D, 0,
+ 15, 0x339A, 0x006E, 0x006D, 0,
+ 15, 0x339B, 0x03BC, 0x006D, 0,
+ 15, 0x339C, 0x006D, 0x006D, 0,
+ 15, 0x339D, 0x0063, 0x006D, 0,
+ 15, 0x339E, 0x006B, 0x006D, 0,
+ 15, 0x339F, 0x006D, 0x006D, 0x00B2, 0,
+ 15, 0x33A0, 0x0063, 0x006D, 0x00B2, 0,
+ 15, 0x33A1, 0x006D, 0x00B2, 0,
+ 15, 0x33A2, 0x006B, 0x006D, 0x00B2, 0,
+ 15, 0x33A3, 0x006D, 0x006D, 0x00B3, 0,
+ 15, 0x33A4, 0x0063, 0x006D, 0x00B3, 0,
+ 15, 0x33A5, 0x006D, 0x00B3, 0,
+ 15, 0x33A6, 0x006B, 0x006D, 0x00B3, 0,
+ 15, 0x33A7, 0x006D, 0x2215, 0x0073, 0,
+ 15, 0x33A8, 0x006D, 0x2215, 0x0073, 0x00B2, 0,
+ 15, 0x33A9, 0x0050, 0x0061, 0,
+ 15, 0x33AA, 0x006B, 0x0050, 0x0061, 0,
+ 15, 0x33AB, 0x004D, 0x0050, 0x0061, 0,
+ 15, 0x33AC, 0x0047, 0x0050, 0x0061, 0,
+ 15, 0x33AD, 0x0072, 0x0061, 0x0064, 0,
+ 15, 0x33AE, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0,
+ 15, 0x33AF, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, 0,
+ 15, 0x33B0, 0x0070, 0x0073, 0,
+ 15, 0x33B1, 0x006E, 0x0073, 0,
+ 15, 0x33B2, 0x03BC, 0x0073, 0,
+ 15, 0x33B3, 0x006D, 0x0073, 0,
+ 15, 0x33B4, 0x0070, 0x0056, 0,
+ 15, 0x33B5, 0x006E, 0x0056, 0,
+ 15, 0x33B6, 0x03BC, 0x0056, 0,
+ 15, 0x33B7, 0x006D, 0x0056, 0,
+ 15, 0x33B8, 0x006B, 0x0056, 0,
+ 15, 0x33B9, 0x004D, 0x0056, 0,
+ 15, 0x33BA, 0x0070, 0x0057, 0,
+ 15, 0x33BB, 0x006E, 0x0057, 0,
+ 15, 0x33BC, 0x03BC, 0x0057, 0,
+ 15, 0x33BD, 0x006D, 0x0057, 0,
+ 15, 0x33BE, 0x006B, 0x0057, 0,
+ 15, 0x33BF, 0x004D, 0x0057, 0,
+ 15, 0x33C0, 0x006B, 0x03A9, 0,
+ 15, 0x33C1, 0x004D, 0x03A9, 0,
+ 15, 0x33C2, 0x0061, 0x002E, 0x006D, 0x002E, 0,
+ 15, 0x33C3, 0x0042, 0x0071, 0,
+ 15, 0x33C4, 0x0063, 0x0063, 0,
+ 15, 0x33C5, 0x0063, 0x0064, 0,
+ 15, 0x33C6, 0x0043, 0x2215, 0x006B, 0x0067, 0,
+ 15, 0x33C7, 0x0043, 0x006F, 0x002E, 0,
+ 15, 0x33C8, 0x0064, 0x0042, 0,
+ 15, 0x33C9, 0x0047, 0x0079, 0,
+ 15, 0x33CA, 0x0068, 0x0061, 0,
+ 15, 0x33CB, 0x0048, 0x0050, 0,
+ 15, 0x33CC, 0x0069, 0x006E, 0,
+ 15, 0x33CD, 0x004B, 0x004B, 0,
+ 15, 0x33CE, 0x004B, 0x004D, 0,
+ 15, 0x33CF, 0x006B, 0x0074, 0,
+ 15, 0x33D0, 0x006C, 0x006D, 0,
+ 15, 0x33D1, 0x006C, 0x006E, 0,
+ 15, 0x33D2, 0x006C, 0x006F, 0x0067, 0,
+ 15, 0x33D3, 0x006C, 0x0078, 0,
+ 15, 0x33D4, 0x006D, 0x0062, 0,
+ 15, 0x33D5, 0x006D, 0x0069, 0x006C, 0,
+ 15, 0x33D6, 0x006D, 0x006F, 0x006C, 0,
+ 15, 0x33D7, 0x0050, 0x0048, 0,
+ 15, 0x33D8, 0x0070, 0x002E, 0x006D, 0x002E, 0,
+ 15, 0x33D9, 0x0050, 0x0050, 0x004D, 0,
+ 15, 0x33DA, 0x0050, 0x0052, 0,
+ 15, 0x33DB, 0x0073, 0x0072, 0,
+ 15, 0x33DC, 0x0053, 0x0076, 0,
+ 15, 0x33DD, 0x0057, 0x0062, 0,
+ 16, 0x33E0, 0x0031, 0x65E5, 0,
+ 16, 0x33E1, 0x0032, 0x65E5, 0,
+ 16, 0x33E2, 0x0033, 0x65E5, 0,
+ 16, 0x33E3, 0x0034, 0x65E5, 0,
+ 16, 0x33E4, 0x0035, 0x65E5, 0,
+ 16, 0x33E5, 0x0036, 0x65E5, 0,
+ 16, 0x33E6, 0x0037, 0x65E5, 0,
+ 16, 0x33E7, 0x0038, 0x65E5, 0,
+ 16, 0x33E8, 0x0039, 0x65E5, 0,
+ 16, 0x33E9, 0x0031, 0x0030, 0x65E5, 0,
+ 16, 0x33EA, 0x0031, 0x0031, 0x65E5, 0,
+ 16, 0x33EB, 0x0031, 0x0032, 0x65E5, 0,
+ 16, 0x33EC, 0x0031, 0x0033, 0x65E5, 0,
+ 16, 0x33ED, 0x0031, 0x0034, 0x65E5, 0,
+ 16, 0x33EE, 0x0031, 0x0035, 0x65E5, 0,
+ 16, 0x33EF, 0x0031, 0x0036, 0x65E5, 0,
+ 16, 0x33F0, 0x0031, 0x0037, 0x65E5, 0,
+ 16, 0x33F1, 0x0031, 0x0038, 0x65E5, 0,
+ 16, 0x33F2, 0x0031, 0x0039, 0x65E5, 0,
+ 16, 0x33F3, 0x0032, 0x0030, 0x65E5, 0,
+ 16, 0x33F4, 0x0032, 0x0031, 0x65E5, 0,
+ 16, 0x33F5, 0x0032, 0x0032, 0x65E5, 0,
+ 16, 0x33F6, 0x0032, 0x0033, 0x65E5, 0,
+ 16, 0x33F7, 0x0032, 0x0034, 0x65E5, 0,
+ 16, 0x33F8, 0x0032, 0x0035, 0x65E5, 0,
+ 16, 0x33F9, 0x0032, 0x0036, 0x65E5, 0,
+ 16, 0x33FA, 0x0032, 0x0037, 0x65E5, 0,
+ 16, 0x33FB, 0x0032, 0x0038, 0x65E5, 0,
+ 16, 0x33FC, 0x0032, 0x0039, 0x65E5, 0,
+ 16, 0x33FD, 0x0033, 0x0030, 0x65E5, 0,
+ 16, 0x33FE, 0x0033, 0x0031, 0x65E5, 0,
+ 1, 0xF900, 0x8C48, 0,
+ 1, 0xF901, 0x66F4, 0,
+ 1, 0xF902, 0x8ECA, 0,
+ 1, 0xF903, 0x8CC8, 0,
+ 1, 0xF904, 0x6ED1, 0,
+ 1, 0xF905, 0x4E32, 0,
+ 1, 0xF906, 0x53E5, 0,
+ 1, 0xF907, 0x9F9C, 0,
+ 1, 0xF908, 0x9F9C, 0,
+ 1, 0xF909, 0x5951, 0,
+ 1, 0xF90A, 0x91D1, 0,
+ 1, 0xF90B, 0x5587, 0,
+ 1, 0xF90C, 0x5948, 0,
+ 1, 0xF90D, 0x61F6, 0,
+ 1, 0xF90E, 0x7669, 0,
+ 1, 0xF90F, 0x7F85, 0,
+ 1, 0xF910, 0x863F, 0,
+ 1, 0xF911, 0x87BA, 0,
+ 1, 0xF912, 0x88F8, 0,
+ 1, 0xF913, 0x908F, 0,
+ 1, 0xF914, 0x6A02, 0,
+ 1, 0xF915, 0x6D1B, 0,
+ 1, 0xF916, 0x70D9, 0,
+ 1, 0xF917, 0x73DE, 0,
+ 1, 0xF918, 0x843D, 0,
+ 1, 0xF919, 0x916A, 0,
+ 1, 0xF91A, 0x99F1, 0,
+ 1, 0xF91B, 0x4E82, 0,
+ 1, 0xF91C, 0x5375, 0,
+ 1, 0xF91D, 0x6B04, 0,
+ 1, 0xF91E, 0x721B, 0,
+ 1, 0xF91F, 0x862D, 0,
+ 1, 0xF920, 0x9E1E, 0,
+ 1, 0xF921, 0x5D50, 0,
+ 1, 0xF922, 0x6FEB, 0,
+ 1, 0xF923, 0x85CD, 0,
+ 1, 0xF924, 0x8964, 0,
+ 1, 0xF925, 0x62C9, 0,
+ 1, 0xF926, 0x81D8, 0,
+ 1, 0xF927, 0x881F, 0,
+ 1, 0xF928, 0x5ECA, 0,
+ 1, 0xF929, 0x6717, 0,
+ 1, 0xF92A, 0x6D6A, 0,
+ 1, 0xF92B, 0x72FC, 0,
+ 1, 0xF92C, 0x90CE, 0,
+ 1, 0xF92D, 0x4F86, 0,
+ 1, 0xF92E, 0x51B7, 0,
+ 1, 0xF92F, 0x52DE, 0,
+ 1, 0xF930, 0x64C4, 0,
+ 1, 0xF931, 0x6AD3, 0,
+ 1, 0xF932, 0x7210, 0,
+ 1, 0xF933, 0x76E7, 0,
+ 1, 0xF934, 0x8001, 0,
+ 1, 0xF935, 0x8606, 0,
+ 1, 0xF936, 0x865C, 0,
+ 1, 0xF937, 0x8DEF, 0,
+ 1, 0xF938, 0x9732, 0,
+ 1, 0xF939, 0x9B6F, 0,
+ 1, 0xF93A, 0x9DFA, 0,
+ 1, 0xF93B, 0x788C, 0,
+ 1, 0xF93C, 0x797F, 0,
+ 1, 0xF93D, 0x7DA0, 0,
+ 1, 0xF93E, 0x83C9, 0,
+ 1, 0xF93F, 0x9304, 0,
+ 1, 0xF940, 0x9E7F, 0,
+ 1, 0xF941, 0x8AD6, 0,
+ 1, 0xF942, 0x58DF, 0,
+ 1, 0xF943, 0x5F04, 0,
+ 1, 0xF944, 0x7C60, 0,
+ 1, 0xF945, 0x807E, 0,
+ 1, 0xF946, 0x7262, 0,
+ 1, 0xF947, 0x78CA, 0,
+ 1, 0xF948, 0x8CC2, 0,
+ 1, 0xF949, 0x96F7, 0,
+ 1, 0xF94A, 0x58D8, 0,
+ 1, 0xF94B, 0x5C62, 0,
+ 1, 0xF94C, 0x6A13, 0,
+ 1, 0xF94D, 0x6DDA, 0,
+ 1, 0xF94E, 0x6F0F, 0,
+ 1, 0xF94F, 0x7D2F, 0,
+ 1, 0xF950, 0x7E37, 0,
+ 1, 0xF951, 0x96FB, 0,
+ 1, 0xF952, 0x52D2, 0,
+ 1, 0xF953, 0x808B, 0,
+ 1, 0xF954, 0x51DC, 0,
+ 1, 0xF955, 0x51CC, 0,
+ 1, 0xF956, 0x7A1C, 0,
+ 1, 0xF957, 0x7DBE, 0,
+ 1, 0xF958, 0x83F1, 0,
+ 1, 0xF959, 0x9675, 0,
+ 1, 0xF95A, 0x8B80, 0,
+ 1, 0xF95B, 0x62CF, 0,
+ 1, 0xF95C, 0x6A02, 0,
+ 1, 0xF95D, 0x8AFE, 0,
+ 1, 0xF95E, 0x4E39, 0,
+ 1, 0xF95F, 0x5BE7, 0,
+ 1, 0xF960, 0x6012, 0,
+ 1, 0xF961, 0x7387, 0,
+ 1, 0xF962, 0x7570, 0,
+ 1, 0xF963, 0x5317, 0,
+ 1, 0xF964, 0x78FB, 0,
+ 1, 0xF965, 0x4FBF, 0,
+ 1, 0xF966, 0x5FA9, 0,
+ 1, 0xF967, 0x4E0D, 0,
+ 1, 0xF968, 0x6CCC, 0,
+ 1, 0xF969, 0x6578, 0,
+ 1, 0xF96A, 0x7D22, 0,
+ 1, 0xF96B, 0x53C3, 0,
+ 1, 0xF96C, 0x585E, 0,
+ 1, 0xF96D, 0x7701, 0,
+ 1, 0xF96E, 0x8449, 0,
+ 1, 0xF96F, 0x8AAA, 0,
+ 1, 0xF970, 0x6BBA, 0,
+ 1, 0xF971, 0x8FB0, 0,
+ 1, 0xF972, 0x6C88, 0,
+ 1, 0xF973, 0x62FE, 0,
+ 1, 0xF974, 0x82E5, 0,
+ 1, 0xF975, 0x63A0, 0,
+ 1, 0xF976, 0x7565, 0,
+ 1, 0xF977, 0x4EAE, 0,
+ 1, 0xF978, 0x5169, 0,
+ 1, 0xF979, 0x51C9, 0,
+ 1, 0xF97A, 0x6881, 0,
+ 1, 0xF97B, 0x7CE7, 0,
+ 1, 0xF97C, 0x826F, 0,
+ 1, 0xF97D, 0x8AD2, 0,
+ 1, 0xF97E, 0x91CF, 0,
+ 1, 0xF97F, 0x52F5, 0,
+ 1, 0xF980, 0x5442, 0,
+ 1, 0xF981, 0x5973, 0,
+ 1, 0xF982, 0x5EEC, 0,
+ 1, 0xF983, 0x65C5, 0,
+ 1, 0xF984, 0x6FFE, 0,
+ 1, 0xF985, 0x792A, 0,
+ 1, 0xF986, 0x95AD, 0,
+ 1, 0xF987, 0x9A6A, 0,
+ 1, 0xF988, 0x9E97, 0,
+ 1, 0xF989, 0x9ECE, 0,
+ 1, 0xF98A, 0x529B, 0,
+ 1, 0xF98B, 0x66C6, 0,
+ 1, 0xF98C, 0x6B77, 0,
+ 1, 0xF98D, 0x8F62, 0,
+ 1, 0xF98E, 0x5E74, 0,
+ 1, 0xF98F, 0x6190, 0,
+ 1, 0xF990, 0x6200, 0,
+ 1, 0xF991, 0x649A, 0,
+ 1, 0xF992, 0x6F23, 0,
+ 1, 0xF993, 0x7149, 0,
+ 1, 0xF994, 0x7489, 0,
+ 1, 0xF995, 0x79CA, 0,
+ 1, 0xF996, 0x7DF4, 0,
+ 1, 0xF997, 0x806F, 0,
+ 1, 0xF998, 0x8F26, 0,
+ 1, 0xF999, 0x84EE, 0,
+ 1, 0xF99A, 0x9023, 0,
+ 1, 0xF99B, 0x934A, 0,
+ 1, 0xF99C, 0x5217, 0,
+ 1, 0xF99D, 0x52A3, 0,
+ 1, 0xF99E, 0x54BD, 0,
+ 1, 0xF99F, 0x70C8, 0,
+ 1, 0xF9A0, 0x88C2, 0,
+ 1, 0xF9A1, 0x8AAA, 0,
+ 1, 0xF9A2, 0x5EC9, 0,
+ 1, 0xF9A3, 0x5FF5, 0,
+ 1, 0xF9A4, 0x637B, 0,
+ 1, 0xF9A5, 0x6BAE, 0,
+ 1, 0xF9A6, 0x7C3E, 0,
+ 1, 0xF9A7, 0x7375, 0,
+ 1, 0xF9A8, 0x4EE4, 0,
+ 1, 0xF9A9, 0x56F9, 0,
+ 1, 0xF9AA, 0x5BE7, 0,
+ 1, 0xF9AB, 0x5DBA, 0,
+ 1, 0xF9AC, 0x601C, 0,
+ 1, 0xF9AD, 0x73B2, 0,
+ 1, 0xF9AE, 0x7469, 0,
+ 1, 0xF9AF, 0x7F9A, 0,
+ 1, 0xF9B0, 0x8046, 0,
+ 1, 0xF9B1, 0x9234, 0,
+ 1, 0xF9B2, 0x96F6, 0,
+ 1, 0xF9B3, 0x9748, 0,
+ 1, 0xF9B4, 0x9818, 0,
+ 1, 0xF9B5, 0x4F8B, 0,
+ 1, 0xF9B6, 0x79AE, 0,
+ 1, 0xF9B7, 0x91B4, 0,
+ 1, 0xF9B8, 0x96B8, 0,
+ 1, 0xF9B9, 0x60E1, 0,
+ 1, 0xF9BA, 0x4E86, 0,
+ 1, 0xF9BB, 0x50DA, 0,
+ 1, 0xF9BC, 0x5BEE, 0,
+ 1, 0xF9BD, 0x5C3F, 0,
+ 1, 0xF9BE, 0x6599, 0,
+ 1, 0xF9BF, 0x6A02, 0,
+ 1, 0xF9C0, 0x71CE, 0,
+ 1, 0xF9C1, 0x7642, 0,
+ 1, 0xF9C2, 0x84FC, 0,
+ 1, 0xF9C3, 0x907C, 0,
+ 1, 0xF9C4, 0x9F8D, 0,
+ 1, 0xF9C5, 0x6688, 0,
+ 1, 0xF9C6, 0x962E, 0,
+ 1, 0xF9C7, 0x5289, 0,
+ 1, 0xF9C8, 0x677B, 0,
+ 1, 0xF9C9, 0x67F3, 0,
+ 1, 0xF9CA, 0x6D41, 0,
+ 1, 0xF9CB, 0x6E9C, 0,
+ 1, 0xF9CC, 0x7409, 0,
+ 1, 0xF9CD, 0x7559, 0,
+ 1, 0xF9CE, 0x786B, 0,
+ 1, 0xF9CF, 0x7D10, 0,
+ 1, 0xF9D0, 0x985E, 0,
+ 1, 0xF9D1, 0x516D, 0,
+ 1, 0xF9D2, 0x622E, 0,
+ 1, 0xF9D3, 0x9678, 0,
+ 1, 0xF9D4, 0x502B, 0,
+ 1, 0xF9D5, 0x5D19, 0,
+ 1, 0xF9D6, 0x6DEA, 0,
+ 1, 0xF9D7, 0x8F2A, 0,
+ 1, 0xF9D8, 0x5F8B, 0,
+ 1, 0xF9D9, 0x6144, 0,
+ 1, 0xF9DA, 0x6817, 0,
+ 1, 0xF9DB, 0x7387, 0,
+ 1, 0xF9DC, 0x9686, 0,
+ 1, 0xF9DD, 0x5229, 0,
+ 1, 0xF9DE, 0x540F, 0,
+ 1, 0xF9DF, 0x5C65, 0,
+ 1, 0xF9E0, 0x6613, 0,
+ 1, 0xF9E1, 0x674E, 0,
+ 1, 0xF9E2, 0x68A8, 0,
+ 1, 0xF9E3, 0x6CE5, 0,
+ 1, 0xF9E4, 0x7406, 0,
+ 1, 0xF9E5, 0x75E2, 0,
+ 1, 0xF9E6, 0x7F79, 0,
+ 1, 0xF9E7, 0x88CF, 0,
+ 1, 0xF9E8, 0x88E1, 0,
+ 1, 0xF9E9, 0x91CC, 0,
+ 1, 0xF9EA, 0x96E2, 0,
+ 1, 0xF9EB, 0x533F, 0,
+ 1, 0xF9EC, 0x6EBA, 0,
+ 1, 0xF9ED, 0x541D, 0,
+ 1, 0xF9EE, 0x71D0, 0,
+ 1, 0xF9EF, 0x7498, 0,
+ 1, 0xF9F0, 0x85FA, 0,
+ 1, 0xF9F1, 0x96A3, 0,
+ 1, 0xF9F2, 0x9C57, 0,
+ 1, 0xF9F3, 0x9E9F, 0,
+ 1, 0xF9F4, 0x6797, 0,
+ 1, 0xF9F5, 0x6DCB, 0,
+ 1, 0xF9F6, 0x81E8, 0,
+ 1, 0xF9F7, 0x7ACB, 0,
+ 1, 0xF9F8, 0x7B20, 0,
+ 1, 0xF9F9, 0x7C92, 0,
+ 1, 0xF9FA, 0x72C0, 0,
+ 1, 0xF9FB, 0x7099, 0,
+ 1, 0xF9FC, 0x8B58, 0,
+ 1, 0xF9FD, 0x4EC0, 0,
+ 1, 0xF9FE, 0x8336, 0,
+ 1, 0xF9FF, 0x523A, 0,
+ 1, 0xFA00, 0x5207, 0,
+ 1, 0xFA01, 0x5EA6, 0,
+ 1, 0xFA02, 0x62D3, 0,
+ 1, 0xFA03, 0x7CD6, 0,
+ 1, 0xFA04, 0x5B85, 0,
+ 1, 0xFA05, 0x6D1E, 0,
+ 1, 0xFA06, 0x66B4, 0,
+ 1, 0xFA07, 0x8F3B, 0,
+ 1, 0xFA08, 0x884C, 0,
+ 1, 0xFA09, 0x964D, 0,
+ 1, 0xFA0A, 0x898B, 0,
+ 1, 0xFA0B, 0x5ED3, 0,
+ 1, 0xFA0C, 0x5140, 0,
+ 1, 0xFA0D, 0x55C0, 0,
+ 1, 0xFA10, 0x585A, 0,
+ 1, 0xFA12, 0x6674, 0,
+ 1, 0xFA15, 0x51DE, 0,
+ 1, 0xFA16, 0x732A, 0,
+ 1, 0xFA17, 0x76CA, 0,
+ 1, 0xFA18, 0x793C, 0,
+ 1, 0xFA19, 0x795E, 0,
+ 1, 0xFA1A, 0x7965, 0,
+ 1, 0xFA1B, 0x798F, 0,
+ 1, 0xFA1C, 0x9756, 0,
+ 1, 0xFA1D, 0x7CBE, 0,
+ 1, 0xFA1E, 0x7FBD, 0,
+ 1, 0xFA20, 0x8612, 0,
+ 1, 0xFA22, 0x8AF8, 0,
+ 1, 0xFA25, 0x9038, 0,
+ 1, 0xFA26, 0x90FD, 0,
+ 1, 0xFA2A, 0x98EF, 0,
+ 1, 0xFA2B, 0x98FC, 0,
+ 1, 0xFA2C, 0x9928, 0,
+ 1, 0xFA2D, 0x9DB4, 0,
+ 16, 0xFB00, 0x0066, 0x0066, 0,
+ 16, 0xFB01, 0x0066, 0x0069, 0,
+ 16, 0xFB02, 0x0066, 0x006C, 0,
+ 16, 0xFB03, 0x0066, 0x0066, 0x0069, 0,
+ 16, 0xFB04, 0x0066, 0x0066, 0x006C, 0,
+ 16, 0xFB05, 0x017F, 0x0074, 0,
+ 16, 0xFB06, 0x0073, 0x0074, 0,
+ 16, 0xFB13, 0x0574, 0x0576, 0,
+ 16, 0xFB14, 0x0574, 0x0565, 0,
+ 16, 0xFB15, 0x0574, 0x056B, 0,
+ 16, 0xFB16, 0x057E, 0x0576, 0,
+ 16, 0xFB17, 0x0574, 0x056D, 0,
+ 1, 0xFB1D, 0x05D9, 0x05B4, 0,
+ 1, 0xFB1F, 0x05F2, 0x05B7, 0,
+ 2, 0xFB20, 0x05E2, 0,
+ 2, 0xFB21, 0x05D0, 0,
+ 2, 0xFB22, 0x05D3, 0,
+ 2, 0xFB23, 0x05D4, 0,
+ 2, 0xFB24, 0x05DB, 0,
+ 2, 0xFB25, 0x05DC, 0,
+ 2, 0xFB26, 0x05DD, 0,
+ 2, 0xFB27, 0x05E8, 0,
+ 2, 0xFB28, 0x05EA, 0,
+ 2, 0xFB29, 0x002B, 0,
+ 1, 0xFB2A, 0x05E9, 0x05C1, 0,
+ 1, 0xFB2B, 0x05E9, 0x05C2, 0,
+ 1, 0xFB2C, 0xFB49, 0x05C1, 0,
+ 1, 0xFB2D, 0xFB49, 0x05C2, 0,
+ 1, 0xFB2E, 0x05D0, 0x05B7, 0,
+ 1, 0xFB2F, 0x05D0, 0x05B8, 0,
+ 1, 0xFB30, 0x05D0, 0x05BC, 0,
+ 1, 0xFB31, 0x05D1, 0x05BC, 0,
+ 1, 0xFB32, 0x05D2, 0x05BC, 0,
+ 1, 0xFB33, 0x05D3, 0x05BC, 0,
+ 1, 0xFB34, 0x05D4, 0x05BC, 0,
+ 1, 0xFB35, 0x05D5, 0x05BC, 0,
+ 1, 0xFB36, 0x05D6, 0x05BC, 0,
+ 1, 0xFB38, 0x05D8, 0x05BC, 0,
+ 1, 0xFB39, 0x05D9, 0x05BC, 0,
+ 1, 0xFB3A, 0x05DA, 0x05BC, 0,
+ 1, 0xFB3B, 0x05DB, 0x05BC, 0,
+ 1, 0xFB3C, 0x05DC, 0x05BC, 0,
+ 1, 0xFB3E, 0x05DE, 0x05BC, 0,
+ 1, 0xFB40, 0x05E0, 0x05BC, 0,
+ 1, 0xFB41, 0x05E1, 0x05BC, 0,
+ 1, 0xFB43, 0x05E3, 0x05BC, 0,
+ 1, 0xFB44, 0x05E4, 0x05BC, 0,
+ 1, 0xFB46, 0x05E6, 0x05BC, 0,
+ 1, 0xFB47, 0x05E7, 0x05BC, 0,
+ 1, 0xFB48, 0x05E8, 0x05BC, 0,
+ 1, 0xFB49, 0x05E9, 0x05BC, 0,
+ 1, 0xFB4A, 0x05EA, 0x05BC, 0,
+ 1, 0xFB4B, 0x05D5, 0x05B9, 0,
+ 1, 0xFB4C, 0x05D1, 0x05BF, 0,
+ 1, 0xFB4D, 0x05DB, 0x05BF, 0,
+ 1, 0xFB4E, 0x05E4, 0x05BF, 0,
+ 16, 0xFB4F, 0x05D0, 0x05DC, 0,
+ 7, 0xFB50, 0x0671, 0,
+ 6, 0xFB51, 0x0671, 0,
+ 7, 0xFB52, 0x067B, 0,
+ 6, 0xFB53, 0x067B, 0,
+ 4, 0xFB54, 0x067B, 0,
+ 5, 0xFB55, 0x067B, 0,
+ 7, 0xFB56, 0x067E, 0,
+ 6, 0xFB57, 0x067E, 0,
+ 4, 0xFB58, 0x067E, 0,
+ 5, 0xFB59, 0x067E, 0,
+ 7, 0xFB5A, 0x0680, 0,
+ 6, 0xFB5B, 0x0680, 0,
+ 4, 0xFB5C, 0x0680, 0,
+ 5, 0xFB5D, 0x0680, 0,
+ 7, 0xFB5E, 0x067A, 0,
+ 6, 0xFB5F, 0x067A, 0,
+ 4, 0xFB60, 0x067A, 0,
+ 5, 0xFB61, 0x067A, 0,
+ 7, 0xFB62, 0x067F, 0,
+ 6, 0xFB63, 0x067F, 0,
+ 4, 0xFB64, 0x067F, 0,
+ 5, 0xFB65, 0x067F, 0,
+ 7, 0xFB66, 0x0679, 0,
+ 6, 0xFB67, 0x0679, 0,
+ 4, 0xFB68, 0x0679, 0,
+ 5, 0xFB69, 0x0679, 0,
+ 7, 0xFB6A, 0x06A4, 0,
+ 6, 0xFB6B, 0x06A4, 0,
+ 4, 0xFB6C, 0x06A4, 0,
+ 5, 0xFB6D, 0x06A4, 0,
+ 7, 0xFB6E, 0x06A6, 0,
+ 6, 0xFB6F, 0x06A6, 0,
+ 4, 0xFB70, 0x06A6, 0,
+ 5, 0xFB71, 0x06A6, 0,
+ 7, 0xFB72, 0x0684, 0,
+ 6, 0xFB73, 0x0684, 0,
+ 4, 0xFB74, 0x0684, 0,
+ 5, 0xFB75, 0x0684, 0,
+ 7, 0xFB76, 0x0683, 0,
+ 6, 0xFB77, 0x0683, 0,
+ 4, 0xFB78, 0x0683, 0,
+ 5, 0xFB79, 0x0683, 0,
+ 7, 0xFB7A, 0x0686, 0,
+ 6, 0xFB7B, 0x0686, 0,
+ 4, 0xFB7C, 0x0686, 0,
+ 5, 0xFB7D, 0x0686, 0,
+ 7, 0xFB7E, 0x0687, 0,
+ 6, 0xFB7F, 0x0687, 0,
+ 4, 0xFB80, 0x0687, 0,
+ 5, 0xFB81, 0x0687, 0,
+ 7, 0xFB82, 0x068D, 0,
+ 6, 0xFB83, 0x068D, 0,
+ 7, 0xFB84, 0x068C, 0,
+ 6, 0xFB85, 0x068C, 0,
+ 7, 0xFB86, 0x068E, 0,
+ 6, 0xFB87, 0x068E, 0,
+ 7, 0xFB88, 0x0688, 0,
+ 6, 0xFB89, 0x0688, 0,
+ 7, 0xFB8A, 0x0698, 0,
+ 6, 0xFB8B, 0x0698, 0,
+ 7, 0xFB8C, 0x0691, 0,
+ 6, 0xFB8D, 0x0691, 0,
+ 7, 0xFB8E, 0x06A9, 0,
+ 6, 0xFB8F, 0x06A9, 0,
+ 4, 0xFB90, 0x06A9, 0,
+ 5, 0xFB91, 0x06A9, 0,
+ 7, 0xFB92, 0x06AF, 0,
+ 6, 0xFB93, 0x06AF, 0,
+ 4, 0xFB94, 0x06AF, 0,
+ 5, 0xFB95, 0x06AF, 0,
+ 7, 0xFB96, 0x06B3, 0,
+ 6, 0xFB97, 0x06B3, 0,
+ 4, 0xFB98, 0x06B3, 0,
+ 5, 0xFB99, 0x06B3, 0,
+ 7, 0xFB9A, 0x06B1, 0,
+ 6, 0xFB9B, 0x06B1, 0,
+ 4, 0xFB9C, 0x06B1, 0,
+ 5, 0xFB9D, 0x06B1, 0,
+ 7, 0xFB9E, 0x06BA, 0,
+ 6, 0xFB9F, 0x06BA, 0,
+ 7, 0xFBA0, 0x06BB, 0,
+ 6, 0xFBA1, 0x06BB, 0,
+ 4, 0xFBA2, 0x06BB, 0,
+ 5, 0xFBA3, 0x06BB, 0,
+ 7, 0xFBA4, 0x06C0, 0,
+ 6, 0xFBA5, 0x06C0, 0,
+ 7, 0xFBA6, 0x06C1, 0,
+ 6, 0xFBA7, 0x06C1, 0,
+ 4, 0xFBA8, 0x06C1, 0,
+ 5, 0xFBA9, 0x06C1, 0,
+ 7, 0xFBAA, 0x06BE, 0,
+ 6, 0xFBAB, 0x06BE, 0,
+ 4, 0xFBAC, 0x06BE, 0,
+ 5, 0xFBAD, 0x06BE, 0,
+ 7, 0xFBAE, 0x06D2, 0,
+ 6, 0xFBAF, 0x06D2, 0,
+ 7, 0xFBB0, 0x06D3, 0,
+ 6, 0xFBB1, 0x06D3, 0,
+ 7, 0xFBD3, 0x06AD, 0,
+ 6, 0xFBD4, 0x06AD, 0,
+ 4, 0xFBD5, 0x06AD, 0,
+ 5, 0xFBD6, 0x06AD, 0,
+ 7, 0xFBD7, 0x06C7, 0,
+ 6, 0xFBD8, 0x06C7, 0,
+ 7, 0xFBD9, 0x06C6, 0,
+ 6, 0xFBDA, 0x06C6, 0,
+ 7, 0xFBDB, 0x06C8, 0,
+ 6, 0xFBDC, 0x06C8, 0,
+ 7, 0xFBDD, 0x0677, 0,
+ 7, 0xFBDE, 0x06CB, 0,
+ 6, 0xFBDF, 0x06CB, 0,
+ 7, 0xFBE0, 0x06C5, 0,
+ 6, 0xFBE1, 0x06C5, 0,
+ 7, 0xFBE2, 0x06C9, 0,
+ 6, 0xFBE3, 0x06C9, 0,
+ 7, 0xFBE4, 0x06D0, 0,
+ 6, 0xFBE5, 0x06D0, 0,
+ 4, 0xFBE6, 0x06D0, 0,
+ 5, 0xFBE7, 0x06D0, 0,
+ 4, 0xFBE8, 0x0649, 0,
+ 5, 0xFBE9, 0x0649, 0,
+ 7, 0xFBEA, 0x0626, 0x0627, 0,
+ 6, 0xFBEB, 0x0626, 0x0627, 0,
+ 7, 0xFBEC, 0x0626, 0x06D5, 0,
+ 6, 0xFBED, 0x0626, 0x06D5, 0,
+ 7, 0xFBEE, 0x0626, 0x0648, 0,
+ 6, 0xFBEF, 0x0626, 0x0648, 0,
+ 7, 0xFBF0, 0x0626, 0x06C7, 0,
+ 6, 0xFBF1, 0x0626, 0x06C7, 0,
+ 7, 0xFBF2, 0x0626, 0x06C6, 0,
+ 6, 0xFBF3, 0x0626, 0x06C6, 0,
+ 7, 0xFBF4, 0x0626, 0x06C8, 0,
+ 6, 0xFBF5, 0x0626, 0x06C8, 0,
+ 7, 0xFBF6, 0x0626, 0x06D0, 0,
+ 6, 0xFBF7, 0x0626, 0x06D0, 0,
+ 4, 0xFBF8, 0x0626, 0x06D0, 0,
+ 7, 0xFBF9, 0x0626, 0x0649, 0,
+ 6, 0xFBFA, 0x0626, 0x0649, 0,
+ 4, 0xFBFB, 0x0626, 0x0649, 0,
+ 7, 0xFBFC, 0x06CC, 0,
+ 6, 0xFBFD, 0x06CC, 0,
+ 4, 0xFBFE, 0x06CC, 0,
+ 5, 0xFBFF, 0x06CC, 0,
+ 7, 0xFC00, 0x0626, 0x062C, 0,
+ 7, 0xFC01, 0x0626, 0x062D, 0,
+ 7, 0xFC02, 0x0626, 0x0645, 0,
+ 7, 0xFC03, 0x0626, 0x0649, 0,
+ 7, 0xFC04, 0x0626, 0x064A, 0,
+ 7, 0xFC05, 0x0628, 0x062C, 0,
+ 7, 0xFC06, 0x0628, 0x062D, 0,
+ 7, 0xFC07, 0x0628, 0x062E, 0,
+ 7, 0xFC08, 0x0628, 0x0645, 0,
+ 7, 0xFC09, 0x0628, 0x0649, 0,
+ 7, 0xFC0A, 0x0628, 0x064A, 0,
+ 7, 0xFC0B, 0x062A, 0x062C, 0,
+ 7, 0xFC0C, 0x062A, 0x062D, 0,
+ 7, 0xFC0D, 0x062A, 0x062E, 0,
+ 7, 0xFC0E, 0x062A, 0x0645, 0,
+ 7, 0xFC0F, 0x062A, 0x0649, 0,
+ 7, 0xFC10, 0x062A, 0x064A, 0,
+ 7, 0xFC11, 0x062B, 0x062C, 0,
+ 7, 0xFC12, 0x062B, 0x0645, 0,
+ 7, 0xFC13, 0x062B, 0x0649, 0,
+ 7, 0xFC14, 0x062B, 0x064A, 0,
+ 7, 0xFC15, 0x062C, 0x062D, 0,
+ 7, 0xFC16, 0x062C, 0x0645, 0,
+ 7, 0xFC17, 0x062D, 0x062C, 0,
+ 7, 0xFC18, 0x062D, 0x0645, 0,
+ 7, 0xFC19, 0x062E, 0x062C, 0,
+ 7, 0xFC1A, 0x062E, 0x062D, 0,
+ 7, 0xFC1B, 0x062E, 0x0645, 0,
+ 7, 0xFC1C, 0x0633, 0x062C, 0,
+ 7, 0xFC1D, 0x0633, 0x062D, 0,
+ 7, 0xFC1E, 0x0633, 0x062E, 0,
+ 7, 0xFC1F, 0x0633, 0x0645, 0,
+ 7, 0xFC20, 0x0635, 0x062D, 0,
+ 7, 0xFC21, 0x0635, 0x0645, 0,
+ 7, 0xFC22, 0x0636, 0x062C, 0,
+ 7, 0xFC23, 0x0636, 0x062D, 0,
+ 7, 0xFC24, 0x0636, 0x062E, 0,
+ 7, 0xFC25, 0x0636, 0x0645, 0,
+ 7, 0xFC26, 0x0637, 0x062D, 0,
+ 7, 0xFC27, 0x0637, 0x0645, 0,
+ 7, 0xFC28, 0x0638, 0x0645, 0,
+ 7, 0xFC29, 0x0639, 0x062C, 0,
+ 7, 0xFC2A, 0x0639, 0x0645, 0,
+ 7, 0xFC2B, 0x063A, 0x062C, 0,
+ 7, 0xFC2C, 0x063A, 0x0645, 0,
+ 7, 0xFC2D, 0x0641, 0x062C, 0,
+ 7, 0xFC2E, 0x0641, 0x062D, 0,
+ 7, 0xFC2F, 0x0641, 0x062E, 0,
+ 7, 0xFC30, 0x0641, 0x0645, 0,
+ 7, 0xFC31, 0x0641, 0x0649, 0,
+ 7, 0xFC32, 0x0641, 0x064A, 0,
+ 7, 0xFC33, 0x0642, 0x062D, 0,
+ 7, 0xFC34, 0x0642, 0x0645, 0,
+ 7, 0xFC35, 0x0642, 0x0649, 0,
+ 7, 0xFC36, 0x0642, 0x064A, 0,
+ 7, 0xFC37, 0x0643, 0x0627, 0,
+ 7, 0xFC38, 0x0643, 0x062C, 0,
+ 7, 0xFC39, 0x0643, 0x062D, 0,
+ 7, 0xFC3A, 0x0643, 0x062E, 0,
+ 7, 0xFC3B, 0x0643, 0x0644, 0,
+ 7, 0xFC3C, 0x0643, 0x0645, 0,
+ 7, 0xFC3D, 0x0643, 0x0649, 0,
+ 7, 0xFC3E, 0x0643, 0x064A, 0,
+ 7, 0xFC3F, 0x0644, 0x062C, 0,
+ 7, 0xFC40, 0x0644, 0x062D, 0,
+ 7, 0xFC41, 0x0644, 0x062E, 0,
+ 7, 0xFC42, 0x0644, 0x0645, 0,
+ 7, 0xFC43, 0x0644, 0x0649, 0,
+ 7, 0xFC44, 0x0644, 0x064A, 0,
+ 7, 0xFC45, 0x0645, 0x062C, 0,
+ 7, 0xFC46, 0x0645, 0x062D, 0,
+ 7, 0xFC47, 0x0645, 0x062E, 0,
+ 7, 0xFC48, 0x0645, 0x0645, 0,
+ 7, 0xFC49, 0x0645, 0x0649, 0,
+ 7, 0xFC4A, 0x0645, 0x064A, 0,
+ 7, 0xFC4B, 0x0646, 0x062C, 0,
+ 7, 0xFC4C, 0x0646, 0x062D, 0,
+ 7, 0xFC4D, 0x0646, 0x062E, 0,
+ 7, 0xFC4E, 0x0646, 0x0645, 0,
+ 7, 0xFC4F, 0x0646, 0x0649, 0,
+ 7, 0xFC50, 0x0646, 0x064A, 0,
+ 7, 0xFC51, 0x0647, 0x062C, 0,
+ 7, 0xFC52, 0x0647, 0x0645, 0,
+ 7, 0xFC53, 0x0647, 0x0649, 0,
+ 7, 0xFC54, 0x0647, 0x064A, 0,
+ 7, 0xFC55, 0x064A, 0x062C, 0,
+ 7, 0xFC56, 0x064A, 0x062D, 0,
+ 7, 0xFC57, 0x064A, 0x062E, 0,
+ 7, 0xFC58, 0x064A, 0x0645, 0,
+ 7, 0xFC59, 0x064A, 0x0649, 0,
+ 7, 0xFC5A, 0x064A, 0x064A, 0,
+ 7, 0xFC5B, 0x0630, 0x0670, 0,
+ 7, 0xFC5C, 0x0631, 0x0670, 0,
+ 7, 0xFC5D, 0x0649, 0x0670, 0,
+ 7, 0xFC5E, 0x0020, 0x064C, 0x0651, 0,
+ 7, 0xFC5F, 0x0020, 0x064D, 0x0651, 0,
+ 7, 0xFC60, 0x0020, 0x064E, 0x0651, 0,
+ 7, 0xFC61, 0x0020, 0x064F, 0x0651, 0,
+ 7, 0xFC62, 0x0020, 0x0650, 0x0651, 0,
+ 7, 0xFC63, 0x0020, 0x0651, 0x0670, 0,
+ 6, 0xFC64, 0x0626, 0x0631, 0,
+ 6, 0xFC65, 0x0626, 0x0632, 0,
+ 6, 0xFC66, 0x0626, 0x0645, 0,
+ 6, 0xFC67, 0x0626, 0x0646, 0,
+ 6, 0xFC68, 0x0626, 0x0649, 0,
+ 6, 0xFC69, 0x0626, 0x064A, 0,
+ 6, 0xFC6A, 0x0628, 0x0631, 0,
+ 6, 0xFC6B, 0x0628, 0x0632, 0,
+ 6, 0xFC6C, 0x0628, 0x0645, 0,
+ 6, 0xFC6D, 0x0628, 0x0646, 0,
+ 6, 0xFC6E, 0x0628, 0x0649, 0,
+ 6, 0xFC6F, 0x0628, 0x064A, 0,
+ 6, 0xFC70, 0x062A, 0x0631, 0,
+ 6, 0xFC71, 0x062A, 0x0632, 0,
+ 6, 0xFC72, 0x062A, 0x0645, 0,
+ 6, 0xFC73, 0x062A, 0x0646, 0,
+ 6, 0xFC74, 0x062A, 0x0649, 0,
+ 6, 0xFC75, 0x062A, 0x064A, 0,
+ 6, 0xFC76, 0x062B, 0x0631, 0,
+ 6, 0xFC77, 0x062B, 0x0632, 0,
+ 6, 0xFC78, 0x062B, 0x0645, 0,
+ 6, 0xFC79, 0x062B, 0x0646, 0,
+ 6, 0xFC7A, 0x062B, 0x0649, 0,
+ 6, 0xFC7B, 0x062B, 0x064A, 0,
+ 6, 0xFC7C, 0x0641, 0x0649, 0,
+ 6, 0xFC7D, 0x0641, 0x064A, 0,
+ 6, 0xFC7E, 0x0642, 0x0649, 0,
+ 6, 0xFC7F, 0x0642, 0x064A, 0,
+ 6, 0xFC80, 0x0643, 0x0627, 0,
+ 6, 0xFC81, 0x0643, 0x0644, 0,
+ 6, 0xFC82, 0x0643, 0x0645, 0,
+ 6, 0xFC83, 0x0643, 0x0649, 0,
+ 6, 0xFC84, 0x0643, 0x064A, 0,
+ 6, 0xFC85, 0x0644, 0x0645, 0,
+ 6, 0xFC86, 0x0644, 0x0649, 0,
+ 6, 0xFC87, 0x0644, 0x064A, 0,
+ 6, 0xFC88, 0x0645, 0x0627, 0,
+ 6, 0xFC89, 0x0645, 0x0645, 0,
+ 6, 0xFC8A, 0x0646, 0x0631, 0,
+ 6, 0xFC8B, 0x0646, 0x0632, 0,
+ 6, 0xFC8C, 0x0646, 0x0645, 0,
+ 6, 0xFC8D, 0x0646, 0x0646, 0,
+ 6, 0xFC8E, 0x0646, 0x0649, 0,
+ 6, 0xFC8F, 0x0646, 0x064A, 0,
+ 6, 0xFC90, 0x0649, 0x0670, 0,
+ 6, 0xFC91, 0x064A, 0x0631, 0,
+ 6, 0xFC92, 0x064A, 0x0632, 0,
+ 6, 0xFC93, 0x064A, 0x0645, 0,
+ 6, 0xFC94, 0x064A, 0x0646, 0,
+ 6, 0xFC95, 0x064A, 0x0649, 0,
+ 6, 0xFC96, 0x064A, 0x064A, 0,
+ 4, 0xFC97, 0x0626, 0x062C, 0,
+ 4, 0xFC98, 0x0626, 0x062D, 0,
+ 4, 0xFC99, 0x0626, 0x062E, 0,
+ 4, 0xFC9A, 0x0626, 0x0645, 0,
+ 4, 0xFC9B, 0x0626, 0x0647, 0,
+ 4, 0xFC9C, 0x0628, 0x062C, 0,
+ 4, 0xFC9D, 0x0628, 0x062D, 0,
+ 4, 0xFC9E, 0x0628, 0x062E, 0,
+ 4, 0xFC9F, 0x0628, 0x0645, 0,
+ 4, 0xFCA0, 0x0628, 0x0647, 0,
+ 4, 0xFCA1, 0x062A, 0x062C, 0,
+ 4, 0xFCA2, 0x062A, 0x062D, 0,
+ 4, 0xFCA3, 0x062A, 0x062E, 0,
+ 4, 0xFCA4, 0x062A, 0x0645, 0,
+ 4, 0xFCA5, 0x062A, 0x0647, 0,
+ 4, 0xFCA6, 0x062B, 0x0645, 0,
+ 4, 0xFCA7, 0x062C, 0x062D, 0,
+ 4, 0xFCA8, 0x062C, 0x0645, 0,
+ 4, 0xFCA9, 0x062D, 0x062C, 0,
+ 4, 0xFCAA, 0x062D, 0x0645, 0,
+ 4, 0xFCAB, 0x062E, 0x062C, 0,
+ 4, 0xFCAC, 0x062E, 0x0645, 0,
+ 4, 0xFCAD, 0x0633, 0x062C, 0,
+ 4, 0xFCAE, 0x0633, 0x062D, 0,
+ 4, 0xFCAF, 0x0633, 0x062E, 0,
+ 4, 0xFCB0, 0x0633, 0x0645, 0,
+ 4, 0xFCB1, 0x0635, 0x062D, 0,
+ 4, 0xFCB2, 0x0635, 0x062E, 0,
+ 4, 0xFCB3, 0x0635, 0x0645, 0,
+ 4, 0xFCB4, 0x0636, 0x062C, 0,
+ 4, 0xFCB5, 0x0636, 0x062D, 0,
+ 4, 0xFCB6, 0x0636, 0x062E, 0,
+ 4, 0xFCB7, 0x0636, 0x0645, 0,
+ 4, 0xFCB8, 0x0637, 0x062D, 0,
+ 4, 0xFCB9, 0x0638, 0x0645, 0,
+ 4, 0xFCBA, 0x0639, 0x062C, 0,
+ 4, 0xFCBB, 0x0639, 0x0645, 0,
+ 4, 0xFCBC, 0x063A, 0x062C, 0,
+ 4, 0xFCBD, 0x063A, 0x0645, 0,
+ 4, 0xFCBE, 0x0641, 0x062C, 0,
+ 4, 0xFCBF, 0x0641, 0x062D, 0,
+ 4, 0xFCC0, 0x0641, 0x062E, 0,
+ 4, 0xFCC1, 0x0641, 0x0645, 0,
+ 4, 0xFCC2, 0x0642, 0x062D, 0,
+ 4, 0xFCC3, 0x0642, 0x0645, 0,
+ 4, 0xFCC4, 0x0643, 0x062C, 0,
+ 4, 0xFCC5, 0x0643, 0x062D, 0,
+ 4, 0xFCC6, 0x0643, 0x062E, 0,
+ 4, 0xFCC7, 0x0643, 0x0644, 0,
+ 4, 0xFCC8, 0x0643, 0x0645, 0,
+ 4, 0xFCC9, 0x0644, 0x062C, 0,
+ 4, 0xFCCA, 0x0644, 0x062D, 0,
+ 4, 0xFCCB, 0x0644, 0x062E, 0,
+ 4, 0xFCCC, 0x0644, 0x0645, 0,
+ 4, 0xFCCD, 0x0644, 0x0647, 0,
+ 4, 0xFCCE, 0x0645, 0x062C, 0,
+ 4, 0xFCCF, 0x0645, 0x062D, 0,
+ 4, 0xFCD0, 0x0645, 0x062E, 0,
+ 4, 0xFCD1, 0x0645, 0x0645, 0,
+ 4, 0xFCD2, 0x0646, 0x062C, 0,
+ 4, 0xFCD3, 0x0646, 0x062D, 0,
+ 4, 0xFCD4, 0x0646, 0x062E, 0,
+ 4, 0xFCD5, 0x0646, 0x0645, 0,
+ 4, 0xFCD6, 0x0646, 0x0647, 0,
+ 4, 0xFCD7, 0x0647, 0x062C, 0,
+ 4, 0xFCD8, 0x0647, 0x0645, 0,
+ 4, 0xFCD9, 0x0647, 0x0670, 0,
+ 4, 0xFCDA, 0x064A, 0x062C, 0,
+ 4, 0xFCDB, 0x064A, 0x062D, 0,
+ 4, 0xFCDC, 0x064A, 0x062E, 0,
+ 4, 0xFCDD, 0x064A, 0x0645, 0,
+ 4, 0xFCDE, 0x064A, 0x0647, 0,
+ 5, 0xFCDF, 0x0626, 0x0645, 0,
+ 5, 0xFCE0, 0x0626, 0x0647, 0,
+ 5, 0xFCE1, 0x0628, 0x0645, 0,
+ 5, 0xFCE2, 0x0628, 0x0647, 0,
+ 5, 0xFCE3, 0x062A, 0x0645, 0,
+ 5, 0xFCE4, 0x062A, 0x0647, 0,
+ 5, 0xFCE5, 0x062B, 0x0645, 0,
+ 5, 0xFCE6, 0x062B, 0x0647, 0,
+ 5, 0xFCE7, 0x0633, 0x0645, 0,
+ 5, 0xFCE8, 0x0633, 0x0647, 0,
+ 5, 0xFCE9, 0x0634, 0x0645, 0,
+ 5, 0xFCEA, 0x0634, 0x0647, 0,
+ 5, 0xFCEB, 0x0643, 0x0644, 0,
+ 5, 0xFCEC, 0x0643, 0x0645, 0,
+ 5, 0xFCED, 0x0644, 0x0645, 0,
+ 5, 0xFCEE, 0x0646, 0x0645, 0,
+ 5, 0xFCEF, 0x0646, 0x0647, 0,
+ 5, 0xFCF0, 0x064A, 0x0645, 0,
+ 5, 0xFCF1, 0x064A, 0x0647, 0,
+ 5, 0xFCF2, 0x0640, 0x064E, 0x0651, 0,
+ 5, 0xFCF3, 0x0640, 0x064F, 0x0651, 0,
+ 5, 0xFCF4, 0x0640, 0x0650, 0x0651, 0,
+ 7, 0xFCF5, 0x0637, 0x0649, 0,
+ 7, 0xFCF6, 0x0637, 0x064A, 0,
+ 7, 0xFCF7, 0x0639, 0x0649, 0,
+ 7, 0xFCF8, 0x0639, 0x064A, 0,
+ 7, 0xFCF9, 0x063A, 0x0649, 0,
+ 7, 0xFCFA, 0x063A, 0x064A, 0,
+ 7, 0xFCFB, 0x0633, 0x0649, 0,
+ 7, 0xFCFC, 0x0633, 0x064A, 0,
+ 7, 0xFCFD, 0x0634, 0x0649, 0,
+ 7, 0xFCFE, 0x0634, 0x064A, 0,
+ 7, 0xFCFF, 0x062D, 0x0649, 0,
+ 7, 0xFD00, 0x062D, 0x064A, 0,
+ 7, 0xFD01, 0x062C, 0x0649, 0,
+ 7, 0xFD02, 0x062C, 0x064A, 0,
+ 7, 0xFD03, 0x062E, 0x0649, 0,
+ 7, 0xFD04, 0x062E, 0x064A, 0,
+ 7, 0xFD05, 0x0635, 0x0649, 0,
+ 7, 0xFD06, 0x0635, 0x064A, 0,
+ 7, 0xFD07, 0x0636, 0x0649, 0,
+ 7, 0xFD08, 0x0636, 0x064A, 0,
+ 7, 0xFD09, 0x0634, 0x062C, 0,
+ 7, 0xFD0A, 0x0634, 0x062D, 0,
+ 7, 0xFD0B, 0x0634, 0x062E, 0,
+ 7, 0xFD0C, 0x0634, 0x0645, 0,
+ 7, 0xFD0D, 0x0634, 0x0631, 0,
+ 7, 0xFD0E, 0x0633, 0x0631, 0,
+ 7, 0xFD0F, 0x0635, 0x0631, 0,
+ 7, 0xFD10, 0x0636, 0x0631, 0,
+ 6, 0xFD11, 0x0637, 0x0649, 0,
+ 6, 0xFD12, 0x0637, 0x064A, 0,
+ 6, 0xFD13, 0x0639, 0x0649, 0,
+ 6, 0xFD14, 0x0639, 0x064A, 0,
+ 6, 0xFD15, 0x063A, 0x0649, 0,
+ 6, 0xFD16, 0x063A, 0x064A, 0,
+ 6, 0xFD17, 0x0633, 0x0649, 0,
+ 6, 0xFD18, 0x0633, 0x064A, 0,
+ 6, 0xFD19, 0x0634, 0x0649, 0,
+ 6, 0xFD1A, 0x0634, 0x064A, 0,
+ 6, 0xFD1B, 0x062D, 0x0649, 0,
+ 6, 0xFD1C, 0x062D, 0x064A, 0,
+ 6, 0xFD1D, 0x062C, 0x0649, 0,
+ 6, 0xFD1E, 0x062C, 0x064A, 0,
+ 6, 0xFD1F, 0x062E, 0x0649, 0,
+ 6, 0xFD20, 0x062E, 0x064A, 0,
+ 6, 0xFD21, 0x0635, 0x0649, 0,
+ 6, 0xFD22, 0x0635, 0x064A, 0,
+ 6, 0xFD23, 0x0636, 0x0649, 0,
+ 6, 0xFD24, 0x0636, 0x064A, 0,
+ 6, 0xFD25, 0x0634, 0x062C, 0,
+ 6, 0xFD26, 0x0634, 0x062D, 0,
+ 6, 0xFD27, 0x0634, 0x062E, 0,
+ 6, 0xFD28, 0x0634, 0x0645, 0,
+ 6, 0xFD29, 0x0634, 0x0631, 0,
+ 6, 0xFD2A, 0x0633, 0x0631, 0,
+ 6, 0xFD2B, 0x0635, 0x0631, 0,
+ 6, 0xFD2C, 0x0636, 0x0631, 0,
+ 4, 0xFD2D, 0x0634, 0x062C, 0,
+ 4, 0xFD2E, 0x0634, 0x062D, 0,
+ 4, 0xFD2F, 0x0634, 0x062E, 0,
+ 4, 0xFD30, 0x0634, 0x0645, 0,
+ 4, 0xFD31, 0x0633, 0x0647, 0,
+ 4, 0xFD32, 0x0634, 0x0647, 0,
+ 4, 0xFD33, 0x0637, 0x0645, 0,
+ 5, 0xFD34, 0x0633, 0x062C, 0,
+ 5, 0xFD35, 0x0633, 0x062D, 0,
+ 5, 0xFD36, 0x0633, 0x062E, 0,
+ 5, 0xFD37, 0x0634, 0x062C, 0,
+ 5, 0xFD38, 0x0634, 0x062D, 0,
+ 5, 0xFD39, 0x0634, 0x062E, 0,
+ 5, 0xFD3A, 0x0637, 0x0645, 0,
+ 5, 0xFD3B, 0x0638, 0x0645, 0,
+ 6, 0xFD3C, 0x0627, 0x064B, 0,
+ 7, 0xFD3D, 0x0627, 0x064B, 0,
+ 4, 0xFD50, 0x062A, 0x062C, 0x0645, 0,
+ 6, 0xFD51, 0x062A, 0x062D, 0x062C, 0,
+ 4, 0xFD52, 0x062A, 0x062D, 0x062C, 0,
+ 4, 0xFD53, 0x062A, 0x062D, 0x0645, 0,
+ 4, 0xFD54, 0x062A, 0x062E, 0x0645, 0,
+ 4, 0xFD55, 0x062A, 0x0645, 0x062C, 0,
+ 4, 0xFD56, 0x062A, 0x0645, 0x062D, 0,
+ 4, 0xFD57, 0x062A, 0x0645, 0x062E, 0,
+ 6, 0xFD58, 0x062C, 0x0645, 0x062D, 0,
+ 4, 0xFD59, 0x062C, 0x0645, 0x062D, 0,
+ 6, 0xFD5A, 0x062D, 0x0645, 0x064A, 0,
+ 6, 0xFD5B, 0x062D, 0x0645, 0x0649, 0,
+ 4, 0xFD5C, 0x0633, 0x062D, 0x062C, 0,
+ 4, 0xFD5D, 0x0633, 0x062C, 0x062D, 0,
+ 6, 0xFD5E, 0x0633, 0x062C, 0x0649, 0,
+ 6, 0xFD5F, 0x0633, 0x0645, 0x062D, 0,
+ 4, 0xFD60, 0x0633, 0x0645, 0x062D, 0,
+ 4, 0xFD61, 0x0633, 0x0645, 0x062C, 0,
+ 6, 0xFD62, 0x0633, 0x0645, 0x0645, 0,
+ 4, 0xFD63, 0x0633, 0x0645, 0x0645, 0,
+ 6, 0xFD64, 0x0635, 0x062D, 0x062D, 0,
+ 4, 0xFD65, 0x0635, 0x062D, 0x062D, 0,
+ 6, 0xFD66, 0x0635, 0x0645, 0x0645, 0,
+ 6, 0xFD67, 0x0634, 0x062D, 0x0645, 0,
+ 4, 0xFD68, 0x0634, 0x062D, 0x0645, 0,
+ 6, 0xFD69, 0x0634, 0x062C, 0x064A, 0,
+ 6, 0xFD6A, 0x0634, 0x0645, 0x062E, 0,
+ 4, 0xFD6B, 0x0634, 0x0645, 0x062E, 0,
+ 6, 0xFD6C, 0x0634, 0x0645, 0x0645, 0,
+ 4, 0xFD6D, 0x0634, 0x0645, 0x0645, 0,
+ 6, 0xFD6E, 0x0636, 0x062D, 0x0649, 0,
+ 6, 0xFD6F, 0x0636, 0x062E, 0x0645, 0,
+ 4, 0xFD70, 0x0636, 0x062E, 0x0645, 0,
+ 6, 0xFD71, 0x0637, 0x0645, 0x062D, 0,
+ 4, 0xFD72, 0x0637, 0x0645, 0x062D, 0,
+ 4, 0xFD73, 0x0637, 0x0645, 0x0645, 0,
+ 6, 0xFD74, 0x0637, 0x0645, 0x064A, 0,
+ 6, 0xFD75, 0x0639, 0x062C, 0x0645, 0,
+ 6, 0xFD76, 0x0639, 0x0645, 0x0645, 0,
+ 4, 0xFD77, 0x0639, 0x0645, 0x0645, 0,
+ 6, 0xFD78, 0x0639, 0x0645, 0x0649, 0,
+ 6, 0xFD79, 0x063A, 0x0645, 0x0645, 0,
+ 6, 0xFD7A, 0x063A, 0x0645, 0x064A, 0,
+ 6, 0xFD7B, 0x063A, 0x0645, 0x0649, 0,
+ 6, 0xFD7C, 0x0641, 0x062E, 0x0645, 0,
+ 4, 0xFD7D, 0x0641, 0x062E, 0x0645, 0,
+ 6, 0xFD7E, 0x0642, 0x0645, 0x062D, 0,
+ 6, 0xFD7F, 0x0642, 0x0645, 0x0645, 0,
+ 6, 0xFD80, 0x0644, 0x062D, 0x0645, 0,
+ 6, 0xFD81, 0x0644, 0x062D, 0x064A, 0,
+ 6, 0xFD82, 0x0644, 0x062D, 0x0649, 0,
+ 4, 0xFD83, 0x0644, 0x062C, 0x062C, 0,
+ 6, 0xFD84, 0x0644, 0x062C, 0x062C, 0,
+ 6, 0xFD85, 0x0644, 0x062E, 0x0645, 0,
+ 4, 0xFD86, 0x0644, 0x062E, 0x0645, 0,
+ 6, 0xFD87, 0x0644, 0x0645, 0x062D, 0,
+ 4, 0xFD88, 0x0644, 0x0645, 0x062D, 0,
+ 4, 0xFD89, 0x0645, 0x062D, 0x062C, 0,
+ 4, 0xFD8A, 0x0645, 0x062D, 0x0645, 0,
+ 6, 0xFD8B, 0x0645, 0x062D, 0x064A, 0,
+ 4, 0xFD8C, 0x0645, 0x062C, 0x062D, 0,
+ 4, 0xFD8D, 0x0645, 0x062C, 0x0645, 0,
+ 4, 0xFD8E, 0x0645, 0x062E, 0x062C, 0,
+ 4, 0xFD8F, 0x0645, 0x062E, 0x0645, 0,
+ 4, 0xFD92, 0x0645, 0x062C, 0x062E, 0,
+ 4, 0xFD93, 0x0647, 0x0645, 0x062C, 0,
+ 4, 0xFD94, 0x0647, 0x0645, 0x0645, 0,
+ 4, 0xFD95, 0x0646, 0x062D, 0x0645, 0,
+ 6, 0xFD96, 0x0646, 0x062D, 0x0649, 0,
+ 6, 0xFD97, 0x0646, 0x062C, 0x0645, 0,
+ 4, 0xFD98, 0x0646, 0x062C, 0x0645, 0,
+ 6, 0xFD99, 0x0646, 0x062C, 0x0649, 0,
+ 6, 0xFD9A, 0x0646, 0x0645, 0x064A, 0,
+ 6, 0xFD9B, 0x0646, 0x0645, 0x0649, 0,
+ 6, 0xFD9C, 0x064A, 0x0645, 0x0645, 0,
+ 4, 0xFD9D, 0x064A, 0x0645, 0x0645, 0,
+ 6, 0xFD9E, 0x0628, 0x062E, 0x064A, 0,
+ 6, 0xFD9F, 0x062A, 0x062C, 0x064A, 0,
+ 6, 0xFDA0, 0x062A, 0x062C, 0x0649, 0,
+ 6, 0xFDA1, 0x062A, 0x062E, 0x064A, 0,
+ 6, 0xFDA2, 0x062A, 0x062E, 0x0649, 0,
+ 6, 0xFDA3, 0x062A, 0x0645, 0x064A, 0,
+ 6, 0xFDA4, 0x062A, 0x0645, 0x0649, 0,
+ 6, 0xFDA5, 0x062C, 0x0645, 0x064A, 0,
+ 6, 0xFDA6, 0x062C, 0x062D, 0x0649, 0,
+ 6, 0xFDA7, 0x062C, 0x0645, 0x0649, 0,
+ 6, 0xFDA8, 0x0633, 0x062E, 0x0649, 0,
+ 6, 0xFDA9, 0x0635, 0x062D, 0x064A, 0,
+ 6, 0xFDAA, 0x0634, 0x062D, 0x064A, 0,
+ 6, 0xFDAB, 0x0636, 0x062D, 0x064A, 0,
+ 6, 0xFDAC, 0x0644, 0x062C, 0x064A, 0,
+ 6, 0xFDAD, 0x0644, 0x0645, 0x064A, 0,
+ 6, 0xFDAE, 0x064A, 0x062D, 0x064A, 0,
+ 6, 0xFDAF, 0x064A, 0x062C, 0x064A, 0,
+ 6, 0xFDB0, 0x064A, 0x0645, 0x064A, 0,
+ 6, 0xFDB1, 0x0645, 0x0645, 0x064A, 0,
+ 6, 0xFDB2, 0x0642, 0x0645, 0x064A, 0,
+ 6, 0xFDB3, 0x0646, 0x062D, 0x064A, 0,
+ 4, 0xFDB4, 0x0642, 0x0645, 0x062D, 0,
+ 4, 0xFDB5, 0x0644, 0x062D, 0x0645, 0,
+ 6, 0xFDB6, 0x0639, 0x0645, 0x064A, 0,
+ 6, 0xFDB7, 0x0643, 0x0645, 0x064A, 0,
+ 4, 0xFDB8, 0x0646, 0x062C, 0x062D, 0,
+ 6, 0xFDB9, 0x0645, 0x062E, 0x064A, 0,
+ 4, 0xFDBA, 0x0644, 0x062C, 0x0645, 0,
+ 6, 0xFDBB, 0x0643, 0x0645, 0x0645, 0,
+ 6, 0xFDBC, 0x0644, 0x062C, 0x0645, 0,
+ 6, 0xFDBD, 0x0646, 0x062C, 0x062D, 0,
+ 6, 0xFDBE, 0x062C, 0x062D, 0x064A, 0,
+ 6, 0xFDBF, 0x062D, 0x062C, 0x064A, 0,
+ 6, 0xFDC0, 0x0645, 0x062C, 0x064A, 0,
+ 6, 0xFDC1, 0x0641, 0x0645, 0x064A, 0,
+ 6, 0xFDC2, 0x0628, 0x062D, 0x064A, 0,
+ 4, 0xFDC3, 0x0643, 0x0645, 0x0645, 0,
+ 4, 0xFDC4, 0x0639, 0x062C, 0x0645, 0,
+ 4, 0xFDC5, 0x0635, 0x0645, 0x0645, 0,
+ 6, 0xFDC6, 0x0633, 0x062E, 0x064A, 0,
+ 6, 0xFDC7, 0x0646, 0x062C, 0x064A, 0,
+ 7, 0xFDF0, 0x0635, 0x0644, 0x06D2, 0,
+ 7, 0xFDF1, 0x0642, 0x0644, 0x06D2, 0,
+ 7, 0xFDF2, 0x0627, 0x0644, 0x0644, 0x0647, 0,
+ 7, 0xFDF3, 0x0627, 0x0643, 0x0628, 0x0631, 0,
+ 7, 0xFDF4, 0x0645, 0x062D, 0x0645, 0x062F, 0,
+ 7, 0xFDF5, 0x0635, 0x0644, 0x0639, 0x0645, 0,
+ 7, 0xFDF6, 0x0631, 0x0633, 0x0648, 0x0644, 0,
+ 7, 0xFDF7, 0x0639, 0x0644, 0x064A, 0x0647, 0,
+ 7, 0xFDF8, 0x0648, 0x0633, 0x0644, 0x0645, 0,
+ 7, 0xFDF9, 0x0635, 0x0644, 0x0649, 0,
+ 7, 0xFDFA, 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0,
+ 7, 0xFDFB, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0,
+ 11, 0xFE30, 0x2025, 0,
+ 11, 0xFE31, 0x2014, 0,
+ 11, 0xFE32, 0x2013, 0,
+ 11, 0xFE33, 0x005F, 0,
+ 11, 0xFE34, 0x005F, 0,
+ 11, 0xFE35, 0x0028, 0,
+ 11, 0xFE36, 0x0029, 0,
+ 11, 0xFE37, 0x007B, 0,
+ 11, 0xFE38, 0x007D, 0,
+ 11, 0xFE39, 0x3014, 0,
+ 11, 0xFE3A, 0x3015, 0,
+ 11, 0xFE3B, 0x3010, 0,
+ 11, 0xFE3C, 0x3011, 0,
+ 11, 0xFE3D, 0x300A, 0,
+ 11, 0xFE3E, 0x300B, 0,
+ 11, 0xFE3F, 0x3008, 0,
+ 11, 0xFE40, 0x3009, 0,
+ 11, 0xFE41, 0x300C, 0,
+ 11, 0xFE42, 0x300D, 0,
+ 11, 0xFE43, 0x300E, 0,
+ 11, 0xFE44, 0x300F, 0,
+ 16, 0xFE49, 0x203E, 0,
+ 16, 0xFE4A, 0x203E, 0,
+ 16, 0xFE4B, 0x203E, 0,
+ 16, 0xFE4C, 0x203E, 0,
+ 16, 0xFE4D, 0x005F, 0,
+ 16, 0xFE4E, 0x005F, 0,
+ 16, 0xFE4F, 0x005F, 0,
+ 14, 0xFE50, 0x002C, 0,
+ 14, 0xFE51, 0x3001, 0,
+ 14, 0xFE52, 0x002E, 0,
+ 14, 0xFE54, 0x003B, 0,
+ 14, 0xFE55, 0x003A, 0,
+ 14, 0xFE56, 0x003F, 0,
+ 14, 0xFE57, 0x0021, 0,
+ 14, 0xFE58, 0x2014, 0,
+ 14, 0xFE59, 0x0028, 0,
+ 14, 0xFE5A, 0x0029, 0,
+ 14, 0xFE5B, 0x007B, 0,
+ 14, 0xFE5C, 0x007D, 0,
+ 14, 0xFE5D, 0x3014, 0,
+ 14, 0xFE5E, 0x3015, 0,
+ 14, 0xFE5F, 0x0023, 0,
+ 14, 0xFE60, 0x0026, 0,
+ 14, 0xFE61, 0x002A, 0,
+ 14, 0xFE62, 0x002B, 0,
+ 14, 0xFE63, 0x002D, 0,
+ 14, 0xFE64, 0x003C, 0,
+ 14, 0xFE65, 0x003E, 0,
+ 14, 0xFE66, 0x003D, 0,
+ 14, 0xFE68, 0x005C, 0,
+ 14, 0xFE69, 0x0024, 0,
+ 14, 0xFE6A, 0x0025, 0,
+ 14, 0xFE6B, 0x0040, 0,
+ 7, 0xFE70, 0x0020, 0x064B, 0,
+ 5, 0xFE71, 0x0640, 0x064B, 0,
+ 7, 0xFE72, 0x0020, 0x064C, 0,
+ 7, 0xFE74, 0x0020, 0x064D, 0,
+ 7, 0xFE76, 0x0020, 0x064E, 0,
+ 5, 0xFE77, 0x0640, 0x064E, 0,
+ 7, 0xFE78, 0x0020, 0x064F, 0,
+ 5, 0xFE79, 0x0640, 0x064F, 0,
+ 7, 0xFE7A, 0x0020, 0x0650, 0,
+ 5, 0xFE7B, 0x0640, 0x0650, 0,
+ 7, 0xFE7C, 0x0020, 0x0651, 0,
+ 5, 0xFE7D, 0x0640, 0x0651, 0,
+ 7, 0xFE7E, 0x0020, 0x0652, 0,
+ 5, 0xFE7F, 0x0640, 0x0652, 0,
+ 7, 0xFE80, 0x0621, 0,
+ 7, 0xFE81, 0x0622, 0,
+ 6, 0xFE82, 0x0622, 0,
+ 7, 0xFE83, 0x0623, 0,
+ 6, 0xFE84, 0x0623, 0,
+ 7, 0xFE85, 0x0624, 0,
+ 6, 0xFE86, 0x0624, 0,
+ 7, 0xFE87, 0x0625, 0,
+ 6, 0xFE88, 0x0625, 0,
+ 7, 0xFE89, 0x0626, 0,
+ 6, 0xFE8A, 0x0626, 0,
+ 4, 0xFE8B, 0x0626, 0,
+ 5, 0xFE8C, 0x0626, 0,
+ 7, 0xFE8D, 0x0627, 0,
+ 6, 0xFE8E, 0x0627, 0,
+ 7, 0xFE8F, 0x0628, 0,
+ 6, 0xFE90, 0x0628, 0,
+ 4, 0xFE91, 0x0628, 0,
+ 5, 0xFE92, 0x0628, 0,
+ 7, 0xFE93, 0x0629, 0,
+ 6, 0xFE94, 0x0629, 0,
+ 7, 0xFE95, 0x062A, 0,
+ 6, 0xFE96, 0x062A, 0,
+ 4, 0xFE97, 0x062A, 0,
+ 5, 0xFE98, 0x062A, 0,
+ 7, 0xFE99, 0x062B, 0,
+ 6, 0xFE9A, 0x062B, 0,
+ 4, 0xFE9B, 0x062B, 0,
+ 5, 0xFE9C, 0x062B, 0,
+ 7, 0xFE9D, 0x062C, 0,
+ 6, 0xFE9E, 0x062C, 0,
+ 4, 0xFE9F, 0x062C, 0,
+ 5, 0xFEA0, 0x062C, 0,
+ 7, 0xFEA1, 0x062D, 0,
+ 6, 0xFEA2, 0x062D, 0,
+ 4, 0xFEA3, 0x062D, 0,
+ 5, 0xFEA4, 0x062D, 0,
+ 7, 0xFEA5, 0x062E, 0,
+ 6, 0xFEA6, 0x062E, 0,
+ 4, 0xFEA7, 0x062E, 0,
+ 5, 0xFEA8, 0x062E, 0,
+ 7, 0xFEA9, 0x062F, 0,
+ 6, 0xFEAA, 0x062F, 0,
+ 7, 0xFEAB, 0x0630, 0,
+ 6, 0xFEAC, 0x0630, 0,
+ 7, 0xFEAD, 0x0631, 0,
+ 6, 0xFEAE, 0x0631, 0,
+ 7, 0xFEAF, 0x0632, 0,
+ 6, 0xFEB0, 0x0632, 0,
+ 7, 0xFEB1, 0x0633, 0,
+ 6, 0xFEB2, 0x0633, 0,
+ 4, 0xFEB3, 0x0633, 0,
+ 5, 0xFEB4, 0x0633, 0,
+ 7, 0xFEB5, 0x0634, 0,
+ 6, 0xFEB6, 0x0634, 0,
+ 4, 0xFEB7, 0x0634, 0,
+ 5, 0xFEB8, 0x0634, 0,
+ 7, 0xFEB9, 0x0635, 0,
+ 6, 0xFEBA, 0x0635, 0,
+ 4, 0xFEBB, 0x0635, 0,
+ 5, 0xFEBC, 0x0635, 0,
+ 7, 0xFEBD, 0x0636, 0,
+ 6, 0xFEBE, 0x0636, 0,
+ 4, 0xFEBF, 0x0636, 0,
+ 5, 0xFEC0, 0x0636, 0,
+ 7, 0xFEC1, 0x0637, 0,
+ 6, 0xFEC2, 0x0637, 0,
+ 4, 0xFEC3, 0x0637, 0,
+ 5, 0xFEC4, 0x0637, 0,
+ 7, 0xFEC5, 0x0638, 0,
+ 6, 0xFEC6, 0x0638, 0,
+ 4, 0xFEC7, 0x0638, 0,
+ 5, 0xFEC8, 0x0638, 0,
+ 7, 0xFEC9, 0x0639, 0,
+ 6, 0xFECA, 0x0639, 0,
+ 4, 0xFECB, 0x0639, 0,
+ 5, 0xFECC, 0x0639, 0,
+ 7, 0xFECD, 0x063A, 0,
+ 6, 0xFECE, 0x063A, 0,
+ 4, 0xFECF, 0x063A, 0,
+ 5, 0xFED0, 0x063A, 0,
+ 7, 0xFED1, 0x0641, 0,
+ 6, 0xFED2, 0x0641, 0,
+ 4, 0xFED3, 0x0641, 0,
+ 5, 0xFED4, 0x0641, 0,
+ 7, 0xFED5, 0x0642, 0,
+ 6, 0xFED6, 0x0642, 0,
+ 4, 0xFED7, 0x0642, 0,
+ 5, 0xFED8, 0x0642, 0,
+ 7, 0xFED9, 0x0643, 0,
+ 6, 0xFEDA, 0x0643, 0,
+ 4, 0xFEDB, 0x0643, 0,
+ 5, 0xFEDC, 0x0643, 0,
+ 7, 0xFEDD, 0x0644, 0,
+ 6, 0xFEDE, 0x0644, 0,
+ 4, 0xFEDF, 0x0644, 0,
+ 5, 0xFEE0, 0x0644, 0,
+ 7, 0xFEE1, 0x0645, 0,
+ 6, 0xFEE2, 0x0645, 0,
+ 4, 0xFEE3, 0x0645, 0,
+ 5, 0xFEE4, 0x0645, 0,
+ 7, 0xFEE5, 0x0646, 0,
+ 6, 0xFEE6, 0x0646, 0,
+ 4, 0xFEE7, 0x0646, 0,
+ 5, 0xFEE8, 0x0646, 0,
+ 7, 0xFEE9, 0x0647, 0,
+ 6, 0xFEEA, 0x0647, 0,
+ 4, 0xFEEB, 0x0647, 0,
+ 5, 0xFEEC, 0x0647, 0,
+ 7, 0xFEED, 0x0648, 0,
+ 6, 0xFEEE, 0x0648, 0,
+ 7, 0xFEEF, 0x0649, 0,
+ 6, 0xFEF0, 0x0649, 0,
+ 7, 0xFEF1, 0x064A, 0,
+ 6, 0xFEF2, 0x064A, 0,
+ 4, 0xFEF3, 0x064A, 0,
+ 5, 0xFEF4, 0x064A, 0,
+ 7, 0xFEF5, 0x0644, 0x0622, 0,
+ 6, 0xFEF6, 0x0644, 0x0622, 0,
+ 7, 0xFEF7, 0x0644, 0x0623, 0,
+ 6, 0xFEF8, 0x0644, 0x0623, 0,
+ 7, 0xFEF9, 0x0644, 0x0625, 0,
+ 6, 0xFEFA, 0x0644, 0x0625, 0,
+ 7, 0xFEFB, 0x0644, 0x0627, 0,
+ 6, 0xFEFC, 0x0644, 0x0627, 0,
+ 12, 0xFF01, 0x0021, 0,
+ 12, 0xFF02, 0x0022, 0,
+ 12, 0xFF03, 0x0023, 0,
+ 12, 0xFF04, 0x0024, 0,
+ 12, 0xFF05, 0x0025, 0,
+ 12, 0xFF06, 0x0026, 0,
+ 12, 0xFF07, 0x0027, 0,
+ 12, 0xFF08, 0x0028, 0,
+ 12, 0xFF09, 0x0029, 0,
+ 12, 0xFF0A, 0x002A, 0,
+ 12, 0xFF0B, 0x002B, 0,
+ 12, 0xFF0C, 0x002C, 0,
+ 12, 0xFF0D, 0x002D, 0,
+ 12, 0xFF0E, 0x002E, 0,
+ 12, 0xFF0F, 0x002F, 0,
+ 12, 0xFF10, 0x0030, 0,
+ 12, 0xFF11, 0x0031, 0,
+ 12, 0xFF12, 0x0032, 0,
+ 12, 0xFF13, 0x0033, 0,
+ 12, 0xFF14, 0x0034, 0,
+ 12, 0xFF15, 0x0035, 0,
+ 12, 0xFF16, 0x0036, 0,
+ 12, 0xFF17, 0x0037, 0,
+ 12, 0xFF18, 0x0038, 0,
+ 12, 0xFF19, 0x0039, 0,
+ 12, 0xFF1A, 0x003A, 0,
+ 12, 0xFF1B, 0x003B, 0,
+ 12, 0xFF1C, 0x003C, 0,
+ 12, 0xFF1D, 0x003D, 0,
+ 12, 0xFF1E, 0x003E, 0,
+ 12, 0xFF1F, 0x003F, 0,
+ 12, 0xFF20, 0x0040, 0,
+ 12, 0xFF21, 0x0041, 0,
+ 12, 0xFF22, 0x0042, 0,
+ 12, 0xFF23, 0x0043, 0,
+ 12, 0xFF24, 0x0044, 0,
+ 12, 0xFF25, 0x0045, 0,
+ 12, 0xFF26, 0x0046, 0,
+ 12, 0xFF27, 0x0047, 0,
+ 12, 0xFF28, 0x0048, 0,
+ 12, 0xFF29, 0x0049, 0,
+ 12, 0xFF2A, 0x004A, 0,
+ 12, 0xFF2B, 0x004B, 0,
+ 12, 0xFF2C, 0x004C, 0,
+ 12, 0xFF2D, 0x004D, 0,
+ 12, 0xFF2E, 0x004E, 0,
+ 12, 0xFF2F, 0x004F, 0,
+ 12, 0xFF30, 0x0050, 0,
+ 12, 0xFF31, 0x0051, 0,
+ 12, 0xFF32, 0x0052, 0,
+ 12, 0xFF33, 0x0053, 0,
+ 12, 0xFF34, 0x0054, 0,
+ 12, 0xFF35, 0x0055, 0,
+ 12, 0xFF36, 0x0056, 0,
+ 12, 0xFF37, 0x0057, 0,
+ 12, 0xFF38, 0x0058, 0,
+ 12, 0xFF39, 0x0059, 0,
+ 12, 0xFF3A, 0x005A, 0,
+ 12, 0xFF3B, 0x005B, 0,
+ 12, 0xFF3C, 0x005C, 0,
+ 12, 0xFF3D, 0x005D, 0,
+ 12, 0xFF3E, 0x005E, 0,
+ 12, 0xFF3F, 0x005F, 0,
+ 12, 0xFF40, 0x0060, 0,
+ 12, 0xFF41, 0x0061, 0,
+ 12, 0xFF42, 0x0062, 0,
+ 12, 0xFF43, 0x0063, 0,
+ 12, 0xFF44, 0x0064, 0,
+ 12, 0xFF45, 0x0065, 0,
+ 12, 0xFF46, 0x0066, 0,
+ 12, 0xFF47, 0x0067, 0,
+ 12, 0xFF48, 0x0068, 0,
+ 12, 0xFF49, 0x0069, 0,
+ 12, 0xFF4A, 0x006A, 0,
+ 12, 0xFF4B, 0x006B, 0,
+ 12, 0xFF4C, 0x006C, 0,
+ 12, 0xFF4D, 0x006D, 0,
+ 12, 0xFF4E, 0x006E, 0,
+ 12, 0xFF4F, 0x006F, 0,
+ 12, 0xFF50, 0x0070, 0,
+ 12, 0xFF51, 0x0071, 0,
+ 12, 0xFF52, 0x0072, 0,
+ 12, 0xFF53, 0x0073, 0,
+ 12, 0xFF54, 0x0074, 0,
+ 12, 0xFF55, 0x0075, 0,
+ 12, 0xFF56, 0x0076, 0,
+ 12, 0xFF57, 0x0077, 0,
+ 12, 0xFF58, 0x0078, 0,
+ 12, 0xFF59, 0x0079, 0,
+ 12, 0xFF5A, 0x007A, 0,
+ 12, 0xFF5B, 0x007B, 0,
+ 12, 0xFF5C, 0x007C, 0,
+ 12, 0xFF5D, 0x007D, 0,
+ 12, 0xFF5E, 0x007E, 0,
+ 13, 0xFF61, 0x3002, 0,
+ 13, 0xFF62, 0x300C, 0,
+ 13, 0xFF63, 0x300D, 0,
+ 13, 0xFF64, 0x3001, 0,
+ 13, 0xFF65, 0x30FB, 0,
+ 13, 0xFF66, 0x30F2, 0,
+ 13, 0xFF67, 0x30A1, 0,
+ 13, 0xFF68, 0x30A3, 0,
+ 13, 0xFF69, 0x30A5, 0,
+ 13, 0xFF6A, 0x30A7, 0,
+ 13, 0xFF6B, 0x30A9, 0,
+ 13, 0xFF6C, 0x30E3, 0,
+ 13, 0xFF6D, 0x30E5, 0,
+ 13, 0xFF6E, 0x30E7, 0,
+ 13, 0xFF6F, 0x30C3, 0,
+ 13, 0xFF70, 0x30FC, 0,
+ 13, 0xFF71, 0x30A2, 0,
+ 13, 0xFF72, 0x30A4, 0,
+ 13, 0xFF73, 0x30A6, 0,
+ 13, 0xFF74, 0x30A8, 0,
+ 13, 0xFF75, 0x30AA, 0,
+ 13, 0xFF76, 0x30AB, 0,
+ 13, 0xFF77, 0x30AD, 0,
+ 13, 0xFF78, 0x30AF, 0,
+ 13, 0xFF79, 0x30B1, 0,
+ 13, 0xFF7A, 0x30B3, 0,
+ 13, 0xFF7B, 0x30B5, 0,
+ 13, 0xFF7C, 0x30B7, 0,
+ 13, 0xFF7D, 0x30B9, 0,
+ 13, 0xFF7E, 0x30BB, 0,
+ 13, 0xFF7F, 0x30BD, 0,
+ 13, 0xFF80, 0x30BF, 0,
+ 13, 0xFF81, 0x30C1, 0,
+ 13, 0xFF82, 0x30C4, 0,
+ 13, 0xFF83, 0x30C6, 0,
+ 13, 0xFF84, 0x30C8, 0,
+ 13, 0xFF85, 0x30CA, 0,
+ 13, 0xFF86, 0x30CB, 0,
+ 13, 0xFF87, 0x30CC, 0,
+ 13, 0xFF88, 0x30CD, 0,
+ 13, 0xFF89, 0x30CE, 0,
+ 13, 0xFF8A, 0x30CF, 0,
+ 13, 0xFF8B, 0x30D2, 0,
+ 13, 0xFF8C, 0x30D5, 0,
+ 13, 0xFF8D, 0x30D8, 0,
+ 13, 0xFF8E, 0x30DB, 0,
+ 13, 0xFF8F, 0x30DE, 0,
+ 13, 0xFF90, 0x30DF, 0,
+ 13, 0xFF91, 0x30E0, 0,
+ 13, 0xFF92, 0x30E1, 0,
+ 13, 0xFF93, 0x30E2, 0,
+ 13, 0xFF94, 0x30E4, 0,
+ 13, 0xFF95, 0x30E6, 0,
+ 13, 0xFF96, 0x30E8, 0,
+ 13, 0xFF97, 0x30E9, 0,
+ 13, 0xFF98, 0x30EA, 0,
+ 13, 0xFF99, 0x30EB, 0,
+ 13, 0xFF9A, 0x30EC, 0,
+ 13, 0xFF9B, 0x30ED, 0,
+ 13, 0xFF9C, 0x30EF, 0,
+ 13, 0xFF9D, 0x30F3, 0,
+ 13, 0xFF9E, 0x3099, 0,
+ 13, 0xFF9F, 0x309A, 0,
+ 13, 0xFFA0, 0x3164, 0,
+ 13, 0xFFA1, 0x3131, 0,
+ 13, 0xFFA2, 0x3132, 0,
+ 13, 0xFFA3, 0x3133, 0,
+ 13, 0xFFA4, 0x3134, 0,
+ 13, 0xFFA5, 0x3135, 0,
+ 13, 0xFFA6, 0x3136, 0,
+ 13, 0xFFA7, 0x3137, 0,
+ 13, 0xFFA8, 0x3138, 0,
+ 13, 0xFFA9, 0x3139, 0,
+ 13, 0xFFAA, 0x313A, 0,
+ 13, 0xFFAB, 0x313B, 0,
+ 13, 0xFFAC, 0x313C, 0,
+ 13, 0xFFAD, 0x313D, 0,
+ 13, 0xFFAE, 0x313E, 0,
+ 13, 0xFFAF, 0x313F, 0,
+ 13, 0xFFB0, 0x3140, 0,
+ 13, 0xFFB1, 0x3141, 0,
+ 13, 0xFFB2, 0x3142, 0,
+ 13, 0xFFB3, 0x3143, 0,
+ 13, 0xFFB4, 0x3144, 0,
+ 13, 0xFFB5, 0x3145, 0,
+ 13, 0xFFB6, 0x3146, 0,
+ 13, 0xFFB7, 0x3147, 0,
+ 13, 0xFFB8, 0x3148, 0,
+ 13, 0xFFB9, 0x3149, 0,
+ 13, 0xFFBA, 0x314A, 0,
+ 13, 0xFFBB, 0x314B, 0,
+ 13, 0xFFBC, 0x314C, 0,
+ 13, 0xFFBD, 0x314D, 0,
+ 13, 0xFFBE, 0x314E, 0,
+ 13, 0xFFC2, 0x314F, 0,
+ 13, 0xFFC3, 0x3150, 0,
+ 13, 0xFFC4, 0x3151, 0,
+ 13, 0xFFC5, 0x3152, 0,
+ 13, 0xFFC6, 0x3153, 0,
+ 13, 0xFFC7, 0x3154, 0,
+ 13, 0xFFCA, 0x3155, 0,
+ 13, 0xFFCB, 0x3156, 0,
+ 13, 0xFFCC, 0x3157, 0,
+ 13, 0xFFCD, 0x3158, 0,
+ 13, 0xFFCE, 0x3159, 0,
+ 13, 0xFFCF, 0x315A, 0,
+ 13, 0xFFD2, 0x315B, 0,
+ 13, 0xFFD3, 0x315C, 0,
+ 13, 0xFFD4, 0x315D, 0,
+ 13, 0xFFD5, 0x315E, 0,
+ 13, 0xFFD6, 0x315F, 0,
+ 13, 0xFFD7, 0x3160, 0,
+ 13, 0xFFDA, 0x3161, 0,
+ 13, 0xFFDB, 0x3162, 0,
+ 13, 0xFFDC, 0x3163, 0,
+ 12, 0xFFE0, 0x00A2, 0,
+ 12, 0xFFE1, 0x00A3, 0,
+ 12, 0xFFE2, 0x00AC, 0,
+ 12, 0xFFE3, 0x00AF, 0,
+ 12, 0xFFE4, 0x00A6, 0,
+ 12, 0xFFE5, 0x00A5, 0,
+ 12, 0xFFE6, 0x20A9, 0,
+ 13, 0xFFE8, 0x2502, 0,
+ 13, 0xFFE9, 0x2190, 0,
+ 13, 0xFFEA, 0x2191, 0,
+ 13, 0xFFEB, 0x2192, 0,
+ 13, 0xFFEC, 0x2193, 0,
+ 13, 0xFFED, 0x25A0, 0,
+ 13, 0xFFEE, 0x25CB, 0,
+
+};
+
+static const Q_UINT16 di_00[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 5, 0, 10, 0, 0, 0, 0, 14,
+ 0, 0, 19, 23, 27, 32, 0, 0,
+ 36, 41, 45, 0, 49, 55, 61, 0,
+ 67, 72, 77, 82, 87, 92, 0, 97,
+ 102, 107, 112, 117, 122, 127, 132, 137,
+ 0, 142, 147, 152, 157, 162, 167, 0,
+ 0, 172, 177, 182, 187, 192, 0, 0,
+ 197, 202, 207, 212, 217, 222, 0, 227,
+ 232, 237, 242, 247, 252, 257, 262, 267,
+ 0, 272, 277, 282, 287, 292, 297, 0,
+ 0, 302, 307, 312, 317, 322, 0, 327,
+};
+
+static const Q_UINT16 di_01[] = {
+ 332, 337, 342, 347, 352, 357, 362, 367,
+ 372, 377, 382, 387, 392, 397, 402, 407,
+ 0, 0, 412, 417, 422, 427, 432, 437,
+ 442, 447, 452, 457, 462, 467, 472, 477,
+ 482, 487, 492, 497, 502, 507, 0, 0,
+ 512, 517, 522, 527, 532, 537, 542, 547,
+ 552, 0, 557, 562, 567, 572, 577, 582,
+ 0, 587, 592, 597, 602, 607, 612, 617,
+ 622, 0, 0, 627, 632, 637, 642, 647,
+ 652, 657, 0, 0, 662, 667, 672, 677,
+ 682, 687, 0, 0, 692, 697, 702, 707,
+ 712, 717, 722, 727, 732, 737, 742, 747,
+ 752, 757, 762, 767, 772, 777, 0, 0,
+ 782, 787, 792, 797, 802, 807, 812, 817,
+ 822, 827, 832, 837, 842, 847, 852, 857,
+ 862, 867, 872, 877, 882, 887, 892, 897,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 901, 906, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 911,
+ 916, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 921, 926, 931, 936,
+ 941, 946, 951, 956, 961, 966, 971, 976,
+ 981, 986, 991, 996, 1001, 1006, 1011, 1016,
+ 1021, 1026, 1031, 1036, 1041, 0, 1046, 1051,
+ 1056, 1061, 1066, 1071, 0, 0, 1076, 1081,
+ 1086, 1091, 1096, 1101, 1106, 1111, 1116, 1121,
+ 1126, 1131, 1136, 1141, 1146, 1151, 0, 0,
+ 1156, 1161, 1166, 1171, 1176, 1181, 1186, 1191,
+};
+
+static const Q_UINT16 di_02[] = {
+ 1196, 1201, 1206, 1211, 1216, 1221, 1226, 1231,
+ 1236, 1241, 1246, 1251, 1256, 1261, 1266, 1271,
+ 1276, 1281, 1286, 1291, 1296, 1301, 1306, 1311,
+ 1316, 1321, 1326, 1331, 0, 0, 1336, 1341,
+ 0, 0, 0, 0, 0, 0, 1346, 1351,
+ 1356, 1361, 1366, 1371, 1376, 1381, 1386, 1391,
+ 1396, 1401, 1406, 1411, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1416, 1420, 1424, 1428, 1432, 1436, 1440, 1444,
+ 1448, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1452, 1457, 1462, 1467, 1472, 1477, 0, 0,
+ 1482, 1486, 1490, 1494, 1498, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_03[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1502, 1506, 0, 1510, 1514, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1519, 0, 0, 0,
+ 0, 0, 1523, 0, 0, 0, 1528, 0,
+ 0, 0, 0, 0, 1532, 1537, 1542, 1547,
+ 1551, 1556, 1561, 0, 1566, 0, 1571, 1576,
+ 1581, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1586, 1591, 1596, 1601, 1606, 1611,
+ 1616, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1621, 1626, 1631, 1636, 1641, 0,
+ 1646, 1650, 1654, 1658, 1663, 1668, 1672, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1676, 1680, 1684, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_04[] = {
+ 1688, 1693, 0, 1698, 0, 0, 0, 1703,
+ 0, 0, 0, 0, 1708, 1713, 1718, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1723, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1728, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1733, 1738, 0, 1743, 0, 0, 0, 1748,
+ 0, 0, 0, 0, 1753, 1758, 1763, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1768, 1773,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1778, 1783, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1788, 1793, 1798, 1803, 0, 0, 1808, 1813,
+ 0, 0, 1818, 1823, 1828, 1833, 1838, 1843,
+ 0, 0, 1848, 1853, 1858, 1863, 1868, 1873,
+ 0, 0, 1878, 1883, 1888, 1893, 1898, 1903,
+ 1908, 1913, 1918, 1923, 1928, 1933, 0, 0,
+ 1938, 1943, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1948,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1953, 1958, 1963, 1968, 1973, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1978, 1983, 1988,
+ 1993, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1998, 0, 2003, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2008, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_07[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_09[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2013, 0, 0, 0, 0, 0, 0,
+ 0, 2018, 0, 0, 2023, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2028, 2033, 2038, 2043, 2048, 2053, 2058, 2063,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2068, 2073, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2078, 2083, 0, 2088,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0A[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2093, 0, 0, 2098, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2103, 2108, 2113, 0, 0, 2118, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0B[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2123, 0, 0, 2128, 2133, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2138, 2143, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2148, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2153, 2158, 2163, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2168, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2173, 0, 0, 0, 0, 0, 0, 2178,
+ 2183, 0, 2188, 2193, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2198, 2203, 2208, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2213, 0, 2218, 2223, 2228, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2233, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2238, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2243, 2248, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2253, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2257, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2262, 0, 0,
+ 0, 0, 2267, 0, 0, 0, 0, 2272,
+ 0, 0, 0, 0, 2277, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2282, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2287, 0, 2292, 2297, 2302,
+ 2307, 2312, 0, 0, 0, 0, 0, 0,
+ 0, 2317, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2322, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2327, 0, 0,
+ 0, 0, 2332, 0, 0, 0, 0, 2337,
+ 0, 0, 0, 0, 2342, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2347, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_10[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2352, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_1E[] = {
+ 2357, 2362, 2367, 2372, 2377, 2382, 2387, 2392,
+ 2397, 2402, 2407, 2412, 2417, 2422, 2427, 2432,
+ 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472,
+ 2477, 2482, 2487, 2492, 2497, 2502, 2507, 2512,
+ 2517, 2522, 2527, 2532, 2537, 2542, 2547, 2552,
+ 2557, 2562, 2567, 2572, 2577, 2582, 2587, 2592,
+ 2597, 2602, 2607, 2612, 2617, 2622, 2627, 2632,
+ 2637, 2642, 2647, 2652, 2657, 2662, 2667, 2672,
+ 2677, 2682, 2687, 2692, 2697, 2702, 2707, 2712,
+ 2717, 2722, 2727, 2732, 2737, 2742, 2747, 2752,
+ 2757, 2762, 2767, 2772, 2777, 2782, 2787, 2792,
+ 2797, 2802, 2807, 2812, 2817, 2822, 2827, 2832,
+ 2837, 2842, 2847, 2852, 2857, 2862, 2867, 2872,
+ 2877, 2882, 2887, 2892, 2897, 2902, 2907, 2912,
+ 2917, 2922, 2927, 2932, 2937, 2942, 2947, 2952,
+ 2957, 2962, 2967, 2972, 2977, 2982, 2987, 2992,
+ 2997, 3002, 3007, 3012, 3017, 3022, 3027, 3032,
+ 3037, 3042, 3047, 3052, 3057, 3062, 3067, 3072,
+ 3077, 3082, 3087, 3092, 3097, 3102, 3107, 3112,
+ 3117, 3122, 3127, 3132, 0, 0, 0, 0,
+ 3137, 3142, 3147, 3152, 3157, 3162, 3167, 3172,
+ 3177, 3182, 3187, 3192, 3197, 3202, 3207, 3212,
+ 3217, 3222, 3227, 3232, 3237, 3242, 3247, 3252,
+ 3257, 3262, 3267, 3272, 3277, 3282, 3287, 3292,
+ 3297, 3302, 3307, 3312, 3317, 3322, 3327, 3332,
+ 3337, 3342, 3347, 3352, 3357, 3362, 3367, 3372,
+ 3377, 3382, 3387, 3392, 3397, 3402, 3407, 3412,
+ 3417, 3422, 3427, 3432, 3437, 3442, 3447, 3452,
+ 3457, 3462, 3467, 3472, 3477, 3482, 3487, 3492,
+ 3497, 3502, 3507, 3512, 3517, 3522, 3527, 3532,
+ 3537, 3542, 3547, 3552, 3557, 3562, 3567, 3572,
+ 3577, 3582, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_1F[] = {
+ 3587, 3592, 3597, 3602, 3607, 3612, 3617, 3622,
+ 3627, 3632, 3637, 3642, 3647, 3652, 3657, 3662,
+ 3667, 3672, 3677, 3682, 3687, 3692, 0, 0,
+ 3697, 3702, 3707, 3712, 3717, 3722, 0, 0,
+ 3727, 3732, 3737, 3742, 3747, 3752, 3757, 3762,
+ 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3802,
+ 3807, 3812, 3817, 3822, 3827, 3832, 3837, 3842,
+ 3847, 3852, 3857, 3862, 3867, 3872, 3877, 3882,
+ 3887, 3892, 3897, 3902, 3907, 3912, 0, 0,
+ 3917, 3922, 3927, 3932, 3937, 3942, 0, 0,
+ 3947, 3952, 3957, 3962, 3967, 3972, 3977, 3982,
+ 0, 3987, 0, 3992, 0, 3997, 0, 4002,
+ 4007, 4012, 4017, 4022, 4027, 4032, 4037, 4042,
+ 4047, 4052, 4057, 4062, 4067, 4072, 4077, 4082,
+ 4087, 4092, 4096, 4101, 4105, 4110, 4114, 4119,
+ 4123, 4128, 4132, 4137, 4141, 4146, 0, 0,
+ 4150, 4155, 4160, 4165, 4170, 4175, 4180, 4185,
+ 4190, 4195, 4200, 4205, 4210, 4215, 4220, 4225,
+ 4230, 4235, 4240, 4245, 4250, 4255, 4260, 4265,
+ 4270, 4275, 4280, 4285, 4290, 4295, 4300, 4305,
+ 4310, 4315, 4320, 4325, 4330, 4335, 4340, 4345,
+ 4350, 4355, 4360, 4365, 4370, 4375, 4380, 4385,
+ 4390, 4395, 4400, 4405, 4410, 0, 4415, 4420,
+ 4425, 4430, 4435, 4440, 4444, 4449, 4454, 4458,
+ 4463, 4468, 4473, 4478, 4483, 0, 4488, 4493,
+ 4498, 4503, 4507, 4512, 4516, 4521, 4526, 4531,
+ 4536, 4541, 4546, 4551, 0, 0, 4555, 4560,
+ 4565, 4570, 4575, 4580, 0, 4584, 4589, 4594,
+ 4599, 4604, 4609, 4614, 4618, 4623, 4628, 4633,
+ 4638, 4643, 4648, 4653, 4657, 4662, 4667, 4671,
+ 0, 0, 4675, 4680, 4685, 0, 4690, 4695,
+ 4700, 4705, 4709, 4714, 4718, 4723, 4727, 0,
+};
+
+static const Q_UINT16 di_20[] = {
+ 4732, 4736, 4740, 4744, 4748, 4752, 4756, 4760,
+ 4764, 4768, 4772, 0, 0, 0, 0, 0,
+ 0, 4776, 0, 0, 0, 0, 0, 4780,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4785, 4789, 4794, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4800,
+ 0, 0, 0, 4804, 4809, 0, 4815, 4820,
+ 0, 0, 0, 0, 4826, 0, 4831, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4836, 4841, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4846, 0, 0, 0, 4850, 4854, 4858, 4862,
+ 4866, 4870, 4874, 4878, 4882, 4886, 4890, 4894,
+ 4898, 4902, 4906, 4910, 4914, 4918, 4922, 4926,
+ 4930, 4934, 4938, 4942, 4946, 4950, 4954, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4958, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_21[] = {
+ 4963, 4969, 4975, 4979, 0, 4984, 4990, 4996,
+ 0, 5000, 5005, 5009, 5013, 5017, 5021, 5025,
+ 5029, 5033, 5037, 5041, 0, 5045, 5049, 0,
+ 0, 5054, 5058, 5062, 5066, 5070, 0, 0,
+ 5074, 5079, 5085, 0, 5090, 0, 5094, 0,
+ 5098, 0, 5102, 5106, 5110, 5114, 0, 5118,
+ 5122, 5126, 0, 5130, 5134, 5138, 5142, 5146,
+ 5150, 5154, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5158, 5164, 5170, 5176, 5182,
+ 5188, 5194, 5200, 5206, 5212, 5218, 5224, 5230,
+ 5235, 5239, 5244, 5250, 5255, 5259, 5264, 5270,
+ 5277, 5282, 5286, 5291, 5297, 5301, 5305, 5309,
+ 5313, 5317, 5322, 5328, 5333, 5337, 5342, 5348,
+ 5355, 5360, 5364, 5369, 5375, 5379, 5383, 5387,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5391, 5396, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5401, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5406, 5411, 5416,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_22[] = {
+ 0, 0, 0, 0, 5421, 0, 0, 0,
+ 0, 5426, 0, 0, 5431, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5436, 0, 5441, 0,
+ 0, 0, 0, 0, 5446, 5451, 0, 5457,
+ 5462, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5468, 0, 0, 5473, 0, 0, 5478,
+ 0, 5483, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5488, 0, 5493, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5498, 5503, 5508,
+ 5513, 5518, 0, 0, 5523, 5528, 0, 0,
+ 5533, 5538, 0, 0, 0, 0, 0, 0,
+ 5543, 5548, 0, 0, 5553, 5558, 0, 0,
+ 5563, 5568, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5573, 5578, 5583, 5588,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5593, 5598, 5603, 5608, 0, 0, 0, 0,
+ 0, 0, 5613, 5618, 5623, 5628, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_23[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5633, 5637, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_24[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5641, 5645, 5649, 5653, 5657, 5661, 5665, 5669,
+ 5673, 5677, 5682, 5687, 5692, 5697, 5702, 5707,
+ 5712, 5717, 5722, 5727, 5732, 5738, 5744, 5750,
+ 5756, 5762, 5768, 5774, 5780, 5786, 5793, 5800,
+ 5807, 5814, 5821, 5828, 5835, 5842, 5849, 5856,
+ 5863, 5868, 5873, 5878, 5883, 5888, 5893, 5898,
+ 5903, 5908, 5914, 5920, 5926, 5932, 5938, 5944,
+ 5950, 5956, 5962, 5968, 5974, 5980, 5986, 5992,
+ 5998, 6004, 6010, 6016, 6022, 6028, 6034, 6040,
+ 6046, 6052, 6058, 6064, 6070, 6076, 6082, 6088,
+ 6094, 6100, 6106, 6112, 6118, 6124, 6130, 6134,
+ 6138, 6142, 6146, 6150, 6154, 6158, 6162, 6166,
+ 6170, 6174, 6178, 6182, 6186, 6190, 6194, 6198,
+ 6202, 6206, 6210, 6214, 6218, 6222, 6226, 6230,
+ 6234, 6238, 6242, 6246, 6250, 6254, 6258, 6262,
+ 6266, 6270, 6274, 6278, 6282, 6286, 6290, 6294,
+ 6298, 6302, 6306, 6310, 6314, 6318, 6322, 6326,
+ 6330, 6334, 6338, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6342,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6346, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_2F[] = {
+ 6350, 6354, 6358, 6362, 6366, 6370, 6374, 6378,
+ 6382, 6386, 6390, 6394, 6398, 6402, 6406, 6410,
+ 6414, 6418, 6422, 6426, 6430, 6434, 6438, 6442,
+ 6446, 6450, 6454, 6458, 6462, 6466, 6470, 6474,
+ 6478, 6482, 6486, 6490, 6494, 6498, 6502, 6506,
+ 6510, 6514, 6518, 6522, 6526, 6530, 6534, 6538,
+ 6542, 6546, 6550, 6554, 6558, 6562, 6566, 6570,
+ 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602,
+ 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634,
+ 6638, 6642, 6646, 6650, 6654, 6658, 6662, 6666,
+ 6670, 6674, 6678, 6682, 6686, 6690, 6694, 6698,
+ 6702, 6706, 6710, 6714, 6718, 6722, 6726, 6730,
+ 6734, 6738, 6742, 6746, 6750, 6754, 6758, 6762,
+ 6766, 6770, 6774, 6778, 6782, 6786, 6790, 6794,
+ 6798, 6802, 6806, 6810, 6814, 6818, 6822, 6826,
+ 6830, 6834, 6838, 6842, 6846, 6850, 6854, 6858,
+ 6862, 6866, 6870, 6874, 6878, 6882, 6886, 6890,
+ 6894, 6898, 6902, 6906, 6910, 6914, 6918, 6922,
+ 6926, 6930, 6934, 6938, 6942, 6946, 6950, 6954,
+ 6958, 6962, 6966, 6970, 6974, 6978, 6982, 6986,
+ 6990, 6994, 6998, 7002, 7006, 7010, 7014, 7018,
+ 7022, 7026, 7030, 7034, 7038, 7042, 7046, 7050,
+ 7054, 7058, 7062, 7066, 7070, 7074, 7078, 7082,
+ 7086, 7090, 7094, 7098, 7102, 7106, 7110, 7114,
+ 7118, 7122, 7126, 7130, 7134, 7138, 7142, 7146,
+ 7150, 7154, 7158, 7162, 7166, 7170, 7174, 7178,
+ 7182, 7186, 7190, 7194, 7198, 7202, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_30[] = {
+ 7206, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7210, 0,
+ 7214, 7218, 7222, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7226, 0, 7231, 0,
+ 7236, 0, 7241, 0, 7246, 0, 7251, 0,
+ 7256, 0, 7261, 0, 7266, 0, 7271, 0,
+ 7276, 0, 7281, 0, 0, 7286, 0, 7291,
+ 0, 7296, 0, 0, 0, 0, 0, 0,
+ 7301, 7306, 0, 7311, 7316, 0, 7321, 7326,
+ 0, 7331, 7336, 0, 7341, 7346, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7351, 0, 0, 0,
+ 0, 0, 0, 7356, 7361, 0, 7366, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7371, 0, 7376, 0,
+ 7381, 0, 7386, 0, 7391, 0, 7396, 0,
+ 7401, 0, 7406, 0, 7411, 0, 7416, 0,
+ 7421, 0, 7426, 0, 0, 7431, 0, 7436,
+ 0, 7441, 0, 0, 0, 0, 0, 0,
+ 7446, 7451, 0, 7456, 7461, 0, 7466, 7471,
+ 0, 7476, 7481, 0, 7486, 7491, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7496, 0, 0, 7501,
+ 7506, 7511, 7516, 0, 0, 0, 7521, 0,
+};
+
+static const Q_UINT16 di_31[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7526, 7530, 7534, 7538, 7542, 7546, 7550,
+ 7554, 7558, 7562, 7566, 7570, 7574, 7578, 7582,
+ 7586, 7590, 7594, 7598, 7602, 7606, 7610, 7614,
+ 7618, 7622, 7626, 7630, 7634, 7638, 7642, 7646,
+ 7650, 7654, 7658, 7662, 7666, 7670, 7674, 7678,
+ 7682, 7686, 7690, 7694, 7698, 7702, 7706, 7710,
+ 7714, 7718, 7722, 7726, 7730, 7734, 7738, 7742,
+ 7746, 7750, 7754, 7758, 7762, 7766, 7770, 7774,
+ 7778, 7782, 7786, 7790, 7794, 7798, 7802, 7806,
+ 7810, 7814, 7818, 7822, 7826, 7830, 7834, 7838,
+ 7842, 7846, 7850, 7854, 7858, 7862, 7866, 7870,
+ 7874, 7878, 7882, 7886, 7890, 7894, 7898, 0,
+ 0, 0, 7902, 7906, 7910, 7914, 7918, 7922,
+ 7926, 7930, 7934, 7938, 7942, 7946, 7950, 7954,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_32[] = {
+ 7958, 7964, 7970, 7976, 7982, 7988, 7994, 8000,
+ 8006, 8012, 8018, 8024, 8030, 8036, 8042, 8049,
+ 8056, 8063, 8070, 8077, 8084, 8091, 8098, 8105,
+ 8112, 8119, 8126, 8133, 8140, 0, 0, 0,
+ 8147, 8153, 8159, 8165, 8171, 8177, 8183, 8189,
+ 8195, 8201, 8207, 8213, 8219, 8225, 8231, 8237,
+ 8243, 8249, 8255, 8261, 8267, 8273, 8279, 8285,
+ 8291, 8297, 8303, 8309, 8315, 8321, 8327, 8333,
+ 8339, 8345, 8351, 8357, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 8363, 8367, 8371, 8375, 8379, 8383, 8387, 8391,
+ 8395, 8399, 8403, 8407, 8411, 8415, 8419, 8424,
+ 8429, 8434, 8439, 8444, 8449, 8454, 8459, 8464,
+ 8469, 8474, 8479, 8484, 0, 0, 0, 0,
+ 8489, 8493, 8497, 8501, 8505, 8509, 8513, 8517,
+ 8521, 8525, 8529, 8533, 8537, 8541, 8545, 8549,
+ 8553, 8557, 8561, 8565, 8569, 8573, 8577, 8581,
+ 8585, 8589, 8593, 8597, 8601, 8605, 8609, 8613,
+ 8617, 8621, 8625, 8629, 8633, 8637, 8641, 8645,
+ 8649, 8653, 8657, 8661, 8665, 8669, 8673, 8677,
+ 8681, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 8685, 8690, 8695, 8700, 8705, 8710, 8715, 8720,
+ 8725, 8730, 8736, 8742, 0, 0, 0, 0,
+ 8748, 8752, 8756, 8760, 8764, 8768, 8772, 8776,
+ 8780, 8784, 8788, 8792, 8796, 8800, 8804, 8808,
+ 8812, 8816, 8820, 8824, 8828, 8832, 8836, 8840,
+ 8844, 8848, 8852, 8856, 8860, 8864, 8868, 8872,
+ 8876, 8880, 8884, 8888, 8892, 8896, 8900, 8904,
+ 8908, 8912, 8916, 8920, 8924, 8928, 8932, 0,
+};
+
+static const Q_UINT16 di_33[] = {
+ 8936, 8943, 8950, 8957, 8963, 8970, 8976, 8982,
+ 8990, 8997, 9003, 9009, 9015, 9022, 9029, 9035,
+ 9041, 9046, 9052, 9059, 9066, 9071, 9079, 9088,
+ 9096, 9102, 9110, 9118, 9125, 9131, 9137, 9143,
+ 9150, 9158, 9165, 9171, 9177, 9183, 9188, 9193,
+ 9198, 9203, 9209, 9215, 9223, 9229, 9236, 9244,
+ 9250, 9255, 9260, 9268, 9275, 9283, 9289, 9297,
+ 9302, 9308, 9314, 9320, 9326, 9332, 9339, 9345,
+ 9350, 9356, 9362, 9368, 9375, 9381, 9387, 9393,
+ 9401, 9408, 9413, 9421, 9426, 9433, 9440, 9446,
+ 9452, 9458, 9465, 9470, 9476, 9483, 9488, 9496,
+ 9502, 9507, 9512, 9517, 9522, 9527, 9532, 9537,
+ 9542, 9547, 9552, 9558, 9564, 9570, 9576, 9582,
+ 9588, 9594, 9600, 9606, 9612, 9618, 9624, 9630,
+ 9636, 9642, 9648, 9653, 9658, 9664, 9669, 0,
+ 0, 0, 0, 9674, 9679, 9684, 9689, 9694,
+ 9701, 9706, 9711, 9716, 9721, 9726, 9731, 9736,
+ 9741, 9747, 9754, 9759, 9764, 9769, 9774, 9779,
+ 9784, 9789, 9795, 9801, 9807, 9813, 9818, 9823,
+ 9828, 9833, 9838, 9843, 9848, 9853, 9858, 9863,
+ 9869, 9875, 9880, 9886, 9892, 9898, 9903, 9909,
+ 9915, 9922, 9927, 9933, 9939, 9945, 9951, 9959,
+ 9968, 9973, 9978, 9983, 9988, 9993, 9998, 10003,
+ 10008, 10013, 10018, 10023, 10028, 10033, 10038, 10043,
+ 10048, 10053, 10058, 10065, 10070, 10075, 10080, 10087,
+ 10093, 10098, 10103, 10108, 10113, 10118, 10123, 10128,
+ 10133, 10138, 10143, 10149, 10154, 10159, 10165, 10171,
+ 10176, 10183, 10189, 10194, 10199, 10204, 0, 0,
+ 10209, 10214, 10219, 10224, 10229, 10234, 10239, 10244,
+ 10249, 10254, 10260, 10266, 10272, 10278, 10284, 10290,
+ 10296, 10302, 10308, 10314, 10320, 10326, 10332, 10338,
+ 10344, 10350, 10356, 10362, 10368, 10374, 10380, 0,
+};
+
+static const Q_UINT16 di_F9[] = {
+ 10386, 10390, 10394, 10398, 10402, 10406, 10410, 10414,
+ 10418, 10422, 10426, 10430, 10434, 10438, 10442, 10446,
+ 10450, 10454, 10458, 10462, 10466, 10470, 10474, 10478,
+ 10482, 10486, 10490, 10494, 10498, 10502, 10506, 10510,
+ 10514, 10518, 10522, 10526, 10530, 10534, 10538, 10542,
+ 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574,
+ 10578, 10582, 10586, 10590, 10594, 10598, 10602, 10606,
+ 10610, 10614, 10618, 10622, 10626, 10630, 10634, 10638,
+ 10642, 10646, 10650, 10654, 10658, 10662, 10666, 10670,
+ 10674, 10678, 10682, 10686, 10690, 10694, 10698, 10702,
+ 10706, 10710, 10714, 10718, 10722, 10726, 10730, 10734,
+ 10738, 10742, 10746, 10750, 10754, 10758, 10762, 10766,
+ 10770, 10774, 10778, 10782, 10786, 10790, 10794, 10798,
+ 10802, 10806, 10810, 10814, 10818, 10822, 10826, 10830,
+ 10834, 10838, 10842, 10846, 10850, 10854, 10858, 10862,
+ 10866, 10870, 10874, 10878, 10882, 10886, 10890, 10894,
+ 10898, 10902, 10906, 10910, 10914, 10918, 10922, 10926,
+ 10930, 10934, 10938, 10942, 10946, 10950, 10954, 10958,
+ 10962, 10966, 10970, 10974, 10978, 10982, 10986, 10990,
+ 10994, 10998, 11002, 11006, 11010, 11014, 11018, 11022,
+ 11026, 11030, 11034, 11038, 11042, 11046, 11050, 11054,
+ 11058, 11062, 11066, 11070, 11074, 11078, 11082, 11086,
+ 11090, 11094, 11098, 11102, 11106, 11110, 11114, 11118,
+ 11122, 11126, 11130, 11134, 11138, 11142, 11146, 11150,
+ 11154, 11158, 11162, 11166, 11170, 11174, 11178, 11182,
+ 11186, 11190, 11194, 11198, 11202, 11206, 11210, 11214,
+ 11218, 11222, 11226, 11230, 11234, 11238, 11242, 11246,
+ 11250, 11254, 11258, 11262, 11266, 11270, 11274, 11278,
+ 11282, 11286, 11290, 11294, 11298, 11302, 11306, 11310,
+ 11314, 11318, 11322, 11326, 11330, 11334, 11338, 11342,
+ 11346, 11350, 11354, 11358, 11362, 11366, 11370, 11374,
+ 11378, 11382, 11386, 11390, 11394, 11398, 11402, 11406,
+};
+
+static const Q_UINT16 di_FA[] = {
+ 11410, 11414, 11418, 11422, 11426, 11430, 11434, 11438,
+ 11442, 11446, 11450, 11454, 11458, 11462, 0, 0,
+ 11466, 0, 11470, 0, 0, 11474, 11478, 11482,
+ 11486, 11490, 11494, 11498, 11502, 11506, 11510, 0,
+ 11514, 0, 11518, 0, 0, 11522, 11526, 0,
+ 0, 0, 11530, 11534, 11538, 11542, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FB[] = {
+ 11546, 11551, 11556, 11561, 11567, 11573, 11578, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 11583, 11588, 11593, 11598, 11603,
+ 0, 0, 0, 0, 0, 11608, 0, 11613,
+ 11618, 11622, 11626, 11630, 11634, 11638, 11642, 11646,
+ 11650, 11654, 11658, 11663, 11668, 11673, 11678, 11683,
+ 11688, 11693, 11698, 11703, 11708, 11713, 11718, 0,
+ 11723, 11728, 11733, 11738, 11743, 0, 11748, 0,
+ 11753, 11758, 0, 11763, 11768, 0, 11773, 11778,
+ 11783, 11788, 11793, 11798, 11803, 11808, 11813, 11818,
+ 11823, 11827, 11831, 11835, 11839, 11843, 11847, 11851,
+ 11855, 11859, 11863, 11867, 11871, 11875, 11879, 11883,
+ 11887, 11891, 11895, 11899, 11903, 11907, 11911, 11915,
+ 11919, 11923, 11927, 11931, 11935, 11939, 11943, 11947,
+ 11951, 11955, 11959, 11963, 11967, 11971, 11975, 11979,
+ 11983, 11987, 11991, 11995, 11999, 12003, 12007, 12011,
+ 12015, 12019, 12023, 12027, 12031, 12035, 12039, 12043,
+ 12047, 12051, 12055, 12059, 12063, 12067, 12071, 12075,
+ 12079, 12083, 12087, 12091, 12095, 12099, 12103, 12107,
+ 12111, 12115, 12119, 12123, 12127, 12131, 12135, 12139,
+ 12143, 12147, 12151, 12155, 12159, 12163, 12167, 12171,
+ 12175, 12179, 12183, 12187, 12191, 12195, 12199, 12203,
+ 12207, 12211, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12215, 12219, 12223, 12227, 12231,
+ 12235, 12239, 12243, 12247, 12251, 12255, 12259, 12263,
+ 12267, 12271, 12275, 12279, 12283, 12287, 12291, 12295,
+ 12299, 12303, 12307, 12312, 12317, 12322, 12327, 12332,
+ 12337, 12342, 12347, 12352, 12357, 12362, 12367, 12372,
+ 12377, 12382, 12387, 12392, 12397, 12401, 12405, 12409,
+};
+
+static const Q_UINT16 di_FC[] = {
+ 12413, 12418, 12423, 12428, 12433, 12438, 12443, 12448,
+ 12453, 12458, 12463, 12468, 12473, 12478, 12483, 12488,
+ 12493, 12498, 12503, 12508, 12513, 12518, 12523, 12528,
+ 12533, 12538, 12543, 12548, 12553, 12558, 12563, 12568,
+ 12573, 12578, 12583, 12588, 12593, 12598, 12603, 12608,
+ 12613, 12618, 12623, 12628, 12633, 12638, 12643, 12648,
+ 12653, 12658, 12663, 12668, 12673, 12678, 12683, 12688,
+ 12693, 12698, 12703, 12708, 12713, 12718, 12723, 12728,
+ 12733, 12738, 12743, 12748, 12753, 12758, 12763, 12768,
+ 12773, 12778, 12783, 12788, 12793, 12798, 12803, 12808,
+ 12813, 12818, 12823, 12828, 12833, 12838, 12843, 12848,
+ 12853, 12858, 12863, 12868, 12873, 12878, 12883, 12889,
+ 12895, 12901, 12907, 12913, 12919, 12924, 12929, 12934,
+ 12939, 12944, 12949, 12954, 12959, 12964, 12969, 12974,
+ 12979, 12984, 12989, 12994, 12999, 13004, 13009, 13014,
+ 13019, 13024, 13029, 13034, 13039, 13044, 13049, 13054,
+ 13059, 13064, 13069, 13074, 13079, 13084, 13089, 13094,
+ 13099, 13104, 13109, 13114, 13119, 13124, 13129, 13134,
+ 13139, 13144, 13149, 13154, 13159, 13164, 13169, 13174,
+ 13179, 13184, 13189, 13194, 13199, 13204, 13209, 13214,
+ 13219, 13224, 13229, 13234, 13239, 13244, 13249, 13254,
+ 13259, 13264, 13269, 13274, 13279, 13284, 13289, 13294,
+ 13299, 13304, 13309, 13314, 13319, 13324, 13329, 13334,
+ 13339, 13344, 13349, 13354, 13359, 13364, 13369, 13374,
+ 13379, 13384, 13389, 13394, 13399, 13404, 13409, 13414,
+ 13419, 13424, 13429, 13434, 13439, 13444, 13449, 13454,
+ 13459, 13464, 13469, 13474, 13479, 13484, 13489, 13494,
+ 13499, 13504, 13509, 13514, 13519, 13524, 13529, 13534,
+ 13539, 13544, 13549, 13554, 13559, 13564, 13569, 13574,
+ 13579, 13584, 13589, 13594, 13599, 13604, 13609, 13614,
+ 13619, 13624, 13629, 13635, 13641, 13647, 13652, 13657,
+ 13662, 13667, 13672, 13677, 13682, 13687, 13692, 13697,
+};
+
+static const Q_UINT16 di_FD[] = {
+ 13702, 13707, 13712, 13717, 13722, 13727, 13732, 13737,
+ 13742, 13747, 13752, 13757, 13762, 13767, 13772, 13777,
+ 13782, 13787, 13792, 13797, 13802, 13807, 13812, 13817,
+ 13822, 13827, 13832, 13837, 13842, 13847, 13852, 13857,
+ 13862, 13867, 13872, 13877, 13882, 13887, 13892, 13897,
+ 13902, 13907, 13912, 13917, 13922, 13927, 13932, 13937,
+ 13942, 13947, 13952, 13957, 13962, 13967, 13972, 13977,
+ 13982, 13987, 13992, 13997, 14002, 14007, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14012, 14018, 14024, 14030, 14036, 14042, 14048, 14054,
+ 14060, 14066, 14072, 14078, 14084, 14090, 14096, 14102,
+ 14108, 14114, 14120, 14126, 14132, 14138, 14144, 14150,
+ 14156, 14162, 14168, 14174, 14180, 14186, 14192, 14198,
+ 14204, 14210, 14216, 14222, 14228, 14234, 14240, 14246,
+ 14252, 14258, 14264, 14270, 14276, 14282, 14288, 14294,
+ 14300, 14306, 14312, 14318, 14324, 14330, 14336, 14342,
+ 14348, 14354, 14360, 14366, 14372, 14378, 14384, 14390,
+ 0, 0, 14396, 14402, 14408, 14414, 14420, 14426,
+ 14432, 14438, 14444, 14450, 14456, 14462, 14468, 14474,
+ 14480, 14486, 14492, 14498, 14504, 14510, 14516, 14522,
+ 14528, 14534, 14540, 14546, 14552, 14558, 14564, 14570,
+ 14576, 14582, 14588, 14594, 14600, 14606, 14612, 14618,
+ 14624, 14630, 14636, 14642, 14648, 14654, 14660, 14666,
+ 14672, 14678, 14684, 14690, 14696, 14702, 14708, 14714,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14720, 14726, 14732, 14739, 14746, 14753, 14760, 14767,
+ 14774, 14781, 14787, 14808, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14819, 14823, 14827, 14831, 14835, 14839, 14843, 14847,
+ 14851, 14855, 14859, 14863, 14867, 14871, 14875, 14879,
+ 14883, 14887, 14891, 14895, 14899, 0, 0, 0,
+ 0, 14903, 14907, 14911, 14915, 14919, 14923, 14927,
+ 14931, 14935, 14939, 0, 14943, 14947, 14951, 14955,
+ 14959, 14963, 14967, 14971, 14975, 14979, 14983, 14987,
+ 14991, 14995, 14999, 15003, 15007, 15011, 15015, 0,
+ 15019, 15023, 15027, 15031, 0, 0, 0, 0,
+ 15035, 15040, 15045, 0, 15050, 0, 15055, 15060,
+ 15065, 15070, 15075, 15080, 15085, 15090, 15095, 15100,
+ 15105, 15109, 15113, 15117, 15121, 15125, 15129, 15133,
+ 15137, 15141, 15145, 15149, 15153, 15157, 15161, 15165,
+ 15169, 15173, 15177, 15181, 15185, 15189, 15193, 15197,
+ 15201, 15205, 15209, 15213, 15217, 15221, 15225, 15229,
+ 15233, 15237, 15241, 15245, 15249, 15253, 15257, 15261,
+ 15265, 15269, 15273, 15277, 15281, 15285, 15289, 15293,
+ 15297, 15301, 15305, 15309, 15313, 15317, 15321, 15325,
+ 15329, 15333, 15337, 15341, 15345, 15349, 15353, 15357,
+ 15361, 15365, 15369, 15373, 15377, 15381, 15385, 15389,
+ 15393, 15397, 15401, 15405, 15409, 15413, 15417, 15421,
+ 15425, 15429, 15433, 15437, 15441, 15445, 15449, 15453,
+ 15457, 15461, 15465, 15469, 15473, 15477, 15481, 15485,
+ 15489, 15493, 15497, 15501, 15505, 15509, 15513, 15517,
+ 15521, 15525, 15529, 15533, 15537, 15541, 15545, 15549,
+ 15553, 15557, 15561, 15565, 15569, 15573, 15578, 15583,
+ 15588, 15593, 15598, 15603, 15608, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FF[] = {
+ 0, 15613, 15617, 15621, 15625, 15629, 15633, 15637,
+ 15641, 15645, 15649, 15653, 15657, 15661, 15665, 15669,
+ 15673, 15677, 15681, 15685, 15689, 15693, 15697, 15701,
+ 15705, 15709, 15713, 15717, 15721, 15725, 15729, 15733,
+ 15737, 15741, 15745, 15749, 15753, 15757, 15761, 15765,
+ 15769, 15773, 15777, 15781, 15785, 15789, 15793, 15797,
+ 15801, 15805, 15809, 15813, 15817, 15821, 15825, 15829,
+ 15833, 15837, 15841, 15845, 15849, 15853, 15857, 15861,
+ 15865, 15869, 15873, 15877, 15881, 15885, 15889, 15893,
+ 15897, 15901, 15905, 15909, 15913, 15917, 15921, 15925,
+ 15929, 15933, 15937, 15941, 15945, 15949, 15953, 15957,
+ 15961, 15965, 15969, 15973, 15977, 15981, 15985, 0,
+ 0, 15989, 15993, 15997, 16001, 16005, 16009, 16013,
+ 16017, 16021, 16025, 16029, 16033, 16037, 16041, 16045,
+ 16049, 16053, 16057, 16061, 16065, 16069, 16073, 16077,
+ 16081, 16085, 16089, 16093, 16097, 16101, 16105, 16109,
+ 16113, 16117, 16121, 16125, 16129, 16133, 16137, 16141,
+ 16145, 16149, 16153, 16157, 16161, 16165, 16169, 16173,
+ 16177, 16181, 16185, 16189, 16193, 16197, 16201, 16205,
+ 16209, 16213, 16217, 16221, 16225, 16229, 16233, 16237,
+ 16241, 16245, 16249, 16253, 16257, 16261, 16265, 16269,
+ 16273, 16277, 16281, 16285, 16289, 16293, 16297, 16301,
+ 16305, 16309, 16313, 16317, 16321, 16325, 16329, 16333,
+ 16337, 16341, 16345, 16349, 16353, 16357, 16361, 0,
+ 0, 0, 16365, 16369, 16373, 16377, 16381, 16385,
+ 0, 0, 16389, 16393, 16397, 16401, 16405, 16409,
+ 0, 0, 16413, 16417, 16421, 16425, 16429, 16433,
+ 0, 0, 16437, 16441, 16445, 0, 0, 0,
+ 16449, 16453, 16457, 16461, 16465, 16469, 16473, 0,
+ 16477, 16481, 16485, 16489, 16493, 16497, 16501, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 * const decomposition_info[256] = {
+ di_00, di_01, di_02, di_03, di_04, di_05, di_06, di_07,
+ di_07, di_09, di_0A, di_0B, di_0C, di_0D, di_0E, di_0F,
+ di_10, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_1E, di_1F,
+ di_20, di_21, di_22, di_23, di_24, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_2E, di_2F,
+ di_30, di_31, di_32, di_33, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_F9, di_FA, di_FB, di_FC, di_FD, di_FE, di_FF,
+};
+// 68080 bytes
+
+static const Q_UINT16 ligature_map [] = {
+ 0,
+ 12883, 12889, 12895, 12901, 12907, 12913, 15035, 15045, 15050, 15055, 15065, 15075, 15085, 15095, 0,
+ 5503, 0,
+ 5488, 0,
+ 5508, 0,
+ 67, 72, 77, 82, 87, 92, 332, 342, 352, 966, 1196, 1206, 1346, 2357, 3137, 3147, 0,
+ 2367, 2377, 2387, 0,
+ 97, 362, 372, 382, 392, 0,
+ 402, 2407, 2417, 2427, 2437, 2447, 0,
+ 102, 107, 112, 117, 412, 422, 432, 442, 452, 1216, 1226, 1356, 2477, 2487, 3257, 3267, 3277, 0,
+ 2507, 0,
+ 462, 472, 482, 492, 1076, 1146, 2517, 0,
+ 502, 1336, 2527, 2537, 2547, 2557, 2567, 0,
+ 122, 127, 132, 137, 512, 522, 532, 542, 552, 976, 1236, 1246, 2577, 3337, 3347, 0,
+ 567, 0,
+ 577, 1086, 2597, 2607, 2617, 0,
+ 587, 597, 607, 2627, 2647, 2657, 0,
+ 2667, 2677, 2687, 0,
+ 142, 627, 637, 647, 1156, 2697, 2707, 2717, 2727, 0,
+ 147, 152, 157, 162, 167, 662, 672, 682, 901, 986, 1096, 1256, 1266, 1386, 3357, 3367, 0,
+ 2777, 2787, 0,
+ 692, 702, 712, 1276, 1286, 2797, 2807, 2827, 0,
+ 722, 732, 742, 752, 1316, 2837, 2847, 0,
+ 762, 772, 1326, 2887, 2897, 2907, 2917, 0,
+ 172, 177, 182, 187, 782, 792, 802, 812, 822, 832, 911, 996, 1296, 1306, 2927, 2937, 2947, 3477, 3487, 0,
+ 2977, 2987, 0,
+ 842, 2997, 3007, 3017, 3027, 3037, 0,
+ 3047, 3057, 0,
+ 192, 852, 862, 1406, 3067, 3547, 3557, 3567, 3577, 0,
+ 867, 877, 887, 3077, 3087, 3097, 0,
+ 197, 202, 207, 212, 217, 222, 337, 347, 357, 971, 1201, 1211, 1351, 2362, 3142, 3152, 0,
+ 2372, 2382, 2392, 0,
+ 227, 367, 377, 387, 397, 0,
+ 407, 2412, 2422, 2432, 2442, 2452, 0,
+ 232, 237, 242, 247, 417, 427, 437, 447, 457, 1221, 1231, 1361, 2482, 2492, 3262, 3272, 3282, 0,
+ 2512, 0,
+ 467, 477, 487, 497, 1081, 1151, 2522, 0,
+ 507, 1341, 2532, 2542, 2552, 2562, 2572, 3107, 0,
+ 252, 257, 262, 267, 517, 527, 537, 547, 981, 1241, 1251, 2582, 3342, 3352, 0,
+ 572, 1126, 0,
+ 582, 1091, 2602, 2612, 2622, 0,
+ 592, 602, 612, 2632, 2652, 2662, 0,
+ 2672, 2682, 2692, 0,
+ 272, 632, 642, 652, 1161, 2702, 2712, 2722, 2732, 0,
+ 277, 282, 287, 292, 297, 667, 677, 687, 906, 991, 1101, 1261, 1271, 1391, 3362, 3372, 0,
+ 2782, 2792, 0,
+ 697, 707, 717, 1281, 1291, 2802, 2812, 2832, 0,
+ 727, 737, 747, 757, 1321, 2842, 2852, 0,
+ 767, 777, 1331, 2892, 2902, 2912, 2922, 3112, 0,
+ 302, 307, 312, 317, 787, 797, 807, 817, 827, 837, 916, 1001, 1301, 1311, 2932, 2942, 2952, 3482, 3492, 0,
+ 2982, 2992, 0,
+ 847, 3002, 3012, 3022, 3032, 3042, 3117, 0,
+ 3052, 3062, 0,
+ 322, 327, 857, 1411, 3072, 3122, 3552, 3562, 3572, 3582, 0,
+ 872, 882, 892, 3082, 3092, 3102, 0,
+ 1537, 4468, 4662, 0,
+ 3157, 3167, 3177, 3187, 0,
+ 1046, 0,
+ 1166, 0,
+ 1066, 1176, 0,
+ 2397, 0,
+ 3287, 3297, 3307, 3317, 0,
+ 2587, 0,
+ 3377, 3387, 3397, 3407, 0,
+ 1376, 2737, 2747, 0,
+ 1366, 0,
+ 1186, 0,
+ 1006, 1016, 1026, 1036, 0,
+ 3162, 3172, 3182, 3192, 0,
+ 1051, 0,
+ 1171, 0,
+ 1071, 1181, 0,
+ 2402, 0,
+ 3292, 3302, 3312, 3322, 0,
+ 2592, 0,
+ 3382, 3392, 3402, 3412, 0,
+ 1381, 2742, 2752, 0,
+ 1371, 0,
+ 1191, 0,
+ 1011, 1021, 1031, 1041, 0,
+ 3207, 3217, 3227, 3237, 0,
+ 3212, 3222, 3232, 3242, 0,
+ 2457, 2467, 0,
+ 2462, 2472, 0,
+ 2757, 2767, 0,
+ 2762, 2772, 0,
+ 2857, 0,
+ 2862, 0,
+ 2867, 0,
+ 2872, 0,
+ 2957, 0,
+ 2962, 0,
+ 2967, 0,
+ 2972, 0,
+ 3132, 0,
+ 3427, 3437, 3447, 3457, 3467, 0,
+ 3432, 3442, 3452, 3462, 3472, 0,
+ 3497, 3507, 3517, 3527, 3537, 0,
+ 3502, 3512, 3522, 3532, 3542, 0,
+ 1116, 0,
+ 1106, 0,
+ 1111, 0,
+ 1056, 0,
+ 1061, 0,
+ 2497, 0,
+ 2502, 0,
+ 1396, 0,
+ 1401, 0,
+ 1121, 0,
+ 1514, 0,
+ 1542, 3627, 3632, 4425, 4430, 4435, 4444, 0,
+ 1551, 3697, 3702, 4498, 0,
+ 1556, 3767, 3772, 4507, 4516, 0,
+ 1561, 1586, 3847, 3852, 4565, 4570, 4575, 0,
+ 1566, 3917, 3922, 4700, 0,
+ 4657, 0,
+ 1571, 1591, 3987, 4638, 4643, 4648, 0,
+ 1576, 4047, 4052, 4709, 4718, 0,
+ 4410, 0,
+ 4483, 0,
+ 1596, 3587, 3592, 4087, 4390, 4395, 4405, 4415, 0,
+ 1601, 3667, 3672, 4096, 0,
+ 1606, 3727, 3732, 4105, 4478, 4488, 0,
+ 1611, 1621, 3807, 3812, 4114, 4536, 4541, 4555, 0,
+ 1631, 3887, 3892, 4123, 0,
+ 4618, 4623, 0,
+ 1626, 1636, 3947, 3952, 4132, 4599, 4604, 4628, 0,
+ 1641, 4007, 4012, 4141, 4680, 4690, 0,
+ 1581, 4546, 4560, 0,
+ 1616, 4609, 4633, 0,
+ 4685, 0,
+ 1658, 1663, 0,
+ 1703, 0,
+ 1788, 1798, 0,
+ 1698, 0,
+ 1688, 1693, 1808, 0,
+ 1778, 1828, 0,
+ 1838, 0,
+ 1713, 1723, 1848, 1858, 0,
+ 1708, 0,
+ 1868, 0,
+ 1718, 1898, 1908, 1918, 0,
+ 1928, 0,
+ 1938, 0,
+ 1888, 0,
+ 1793, 1803, 0,
+ 1743, 0,
+ 1733, 1738, 1813, 0,
+ 1783, 1833, 0,
+ 1843, 0,
+ 1728, 1758, 1853, 1863, 0,
+ 1753, 0,
+ 1873, 0,
+ 1763, 1903, 1913, 1923, 0,
+ 1933, 0,
+ 1943, 0,
+ 1893, 0,
+ 1748, 0,
+ 1768, 0,
+ 1773, 0,
+ 1818, 0,
+ 1823, 0,
+ 1878, 0,
+ 1883, 0,
+ 11678, 11683, 11688, 0,
+ 11693, 11803, 0,
+ 11698, 0,
+ 11703, 0,
+ 11708, 0,
+ 11713, 11798, 0,
+ 11718, 0,
+ 11723, 0,
+ 11608, 11728, 0,
+ 11733, 0,
+ 11738, 11808, 0,
+ 11743, 0,
+ 11748, 0,
+ 11753, 0,
+ 11758, 0,
+ 11763, 0,
+ 11768, 11813, 0,
+ 11773, 0,
+ 11778, 0,
+ 11783, 0,
+ 11658, 11663, 11788, 0,
+ 11793, 0,
+ 11613, 0,
+ 15105, 0,
+ 15109, 15113, 0,
+ 15117, 15121, 0,
+ 15125, 15129, 0,
+ 15133, 15137, 0,
+ 12307, 12312, 12317, 12322, 12327, 12332, 12337, 12342, 12347, 12352, 12357, 12362, 12367, 12372, 12377, 12382, 12387, 12392, 12413, 12418, 12423, 12428, 12433, 12919, 12924, 12929, 12934, 12939, 12944, 13174, 13179, 13184, 13189, 13194, 13534, 13539, 15141, 15145, 15149, 15153, 0,
+ 14732, 14739, 1958, 1968, 14007, 14002, 1953, 15157, 15161, 0,
+ 14468, 14684, 12448, 12453, 12458, 12463, 12949, 12954, 12959, 12964, 12969, 12974, 13199, 13204, 13209, 13214, 13219, 13544, 13549, 12438, 12443, 15165, 15169, 15173, 15177, 0,
+ 15181, 15185, 0,
+ 14012, 14018, 14024, 14030, 14036, 14042, 14048, 14054, 14474, 14480, 14486, 14492, 14498, 14504, 13229, 13234, 13239, 13244, 13559, 13554, 12468, 12473, 12478, 12483, 12488, 12493, 12979, 12984, 12989, 12994, 12999, 13004, 13224, 15189, 15193, 15197, 15201, 0,
+ 12498, 12503, 12508, 12513, 13009, 13014, 13019, 13024, 13029, 13034, 13249, 13564, 13569, 15205, 15209, 15213, 15217, 0,
+ 14808, 14660, 14060, 14066, 14510, 14516, 14522, 12518, 12523, 13254, 13259, 13707, 13712, 13847, 13852, 15221, 15225, 15229, 15233, 0,
+ 14072, 14078, 14666, 13264, 13269, 13697, 13702, 13842, 13837, 12528, 12533, 15237, 15241, 15245, 15249, 0,
+ 12538, 12543, 12548, 13274, 13279, 13717, 13722, 13857, 13862, 15253, 15257, 15261, 15265, 0,
+ 15269, 15273, 0,
+ 12868, 15277, 15281, 0,
+ 14760, 12873, 15285, 15289, 0,
+ 15293, 15297, 0,
+ 14084, 14090, 14096, 14102, 14108, 14114, 14120, 14126, 14528, 14708, 13677, 13682, 13772, 13817, 13822, 13912, 13947, 13962, 13967, 13972, 12553, 12558, 12563, 12568, 13284, 13289, 13294, 13299, 13574, 13579, 15301, 15305, 15309, 15313, 0,
+ 14150, 14156, 14162, 14168, 14174, 14180, 14186, 14540, 13767, 13827, 13832, 13887, 13892, 13897, 13902, 13907, 13927, 13932, 13937, 13942, 13952, 13977, 13982, 13987, 13584, 13589, 13687, 13692, 13747, 13752, 13757, 13762, 15317, 15321, 15325, 15329, 0,
+ 14787, 14753, 14781, 14138, 14132, 14144, 14534, 14702, 14720, 12573, 12578, 13304, 13309, 13314, 13727, 13732, 13777, 13872, 13917, 13867, 15333, 15337, 15341, 15345, 0,
+ 14192, 14198, 14204, 14546, 13319, 13324, 13329, 13334, 13737, 13742, 13782, 13877, 13882, 13922, 12583, 12588, 12593, 12598, 15349, 15353, 15357, 15361, 0,
+ 14210, 14216, 14222, 14228, 13647, 13652, 13787, 13792, 13992, 13957, 12603, 12608, 13339, 15365, 15369, 15373, 15377, 0,
+ 12613, 13344, 13997, 15381, 15385, 15389, 15393, 0,
+ 14767, 14696, 14234, 14240, 14246, 14252, 14612, 12618, 12623, 13349, 13354, 13657, 13662, 13797, 13802, 15397, 15401, 15405, 15409, 0,
+ 14258, 14264, 14270, 13359, 13364, 13667, 13672, 13812, 13807, 12628, 12633, 15413, 15417, 15421, 15425, 0,
+ 13629, 13635, 13641, 15040, 15060, 15070, 15080, 15090, 15100, 0,
+ 14276, 14282, 14678, 12653, 12658, 12663, 13039, 13044, 13369, 13374, 13379, 13384, 12638, 12643, 12648, 15429, 15433, 15437, 15441, 0,
+ 14600, 14726, 14294, 14288, 14588, 12668, 12673, 12678, 12683, 13049, 13054, 13389, 13394, 15445, 15449, 15453, 15457, 0,
+ 14618, 14642, 14690, 12703, 12708, 12713, 12718, 12723, 13059, 13064, 13069, 13074, 13079, 13399, 13404, 13409, 13414, 13419, 13594, 13599, 12688, 12693, 12698, 15461, 15465, 15469, 15473, 0,
+ 14648, 14300, 14306, 14312, 14318, 14324, 14330, 14336, 14342, 14348, 14552, 14558, 14606, 14636, 12728, 12733, 12738, 12743, 12748, 12753, 13084, 13089, 13094, 13424, 13429, 13434, 13439, 13444, 13604, 15573, 15578, 15583, 15588, 15593, 15598, 15603, 15608, 15477, 15481, 15485, 15489, 0,
+ 14746, 14354, 14360, 14366, 14372, 14378, 14384, 14390, 14396, 14582, 14630, 14672, 12758, 12763, 12768, 12773, 12778, 12783, 13099, 13104, 13449, 13454, 13459, 13464, 15493, 15497, 15501, 15505, 0,
+ 14414, 14420, 14426, 14432, 14438, 14444, 14450, 14594, 14624, 14654, 14714, 13134, 13469, 13474, 13479, 13484, 13489, 13609, 13614, 12788, 12793, 12798, 12803, 12808, 12813, 13109, 13114, 13119, 13124, 13129, 15509, 15513, 15517, 15521, 0,
+ 14402, 14408, 12823, 12828, 12833, 13494, 13504, 13499, 12818, 15525, 15529, 15533, 15537, 0,
+ 14774, 1963, 15541, 15545, 0,
+ 12878, 13139, 12299, 12303, 15549, 15553, 0,
+ 14456, 14462, 14564, 14570, 14576, 12858, 12863, 13144, 13149, 13154, 13159, 13164, 13169, 13509, 13514, 13519, 13524, 13529, 13619, 13624, 1973, 12838, 12843, 12848, 12853, 15557, 15561, 15565, 15569, 0,
+ 11823, 11827, 0,
+ 12255, 0,
+ 11911, 11915, 11919, 11923, 0,
+ 11879, 11883, 11887, 11891, 0,
+ 11831, 11835, 11839, 11843, 0,
+ 11847, 11851, 11855, 11859, 0,
+ 11895, 11899, 11903, 11907, 0,
+ 11863, 11867, 11871, 11875, 0,
+ 11975, 11979, 11983, 11987, 0,
+ 11959, 11963, 11967, 11971, 0,
+ 11991, 11995, 11999, 12003, 0,
+ 12007, 12011, 12015, 12019, 0,
+ 12047, 12051, 0,
+ 12031, 12035, 0,
+ 12023, 12027, 0,
+ 12039, 12043, 0,
+ 12063, 12067, 0,
+ 12055, 12059, 0,
+ 11927, 11931, 11935, 11939, 0,
+ 11943, 11947, 11951, 11955, 0,
+ 12071, 12075, 12079, 12083, 0,
+ 12215, 12219, 12223, 12227, 0,
+ 12087, 12091, 12095, 12099, 0,
+ 12119, 12123, 12127, 12131, 0,
+ 12103, 12107, 12111, 12115, 0,
+ 12135, 12139, 0,
+ 12143, 12147, 12151, 12155, 0,
+ 12183, 12187, 12191, 12195, 0,
+ 12159, 12163, 0,
+ 2003, 12167, 12171, 12175, 12179, 0,
+ 12267, 12271, 0,
+ 12239, 12243, 0,
+ 12231, 12235, 0,
+ 12247, 12251, 0,
+ 12275, 12279, 0,
+ 12259, 12263, 0,
+ 12397, 12401, 12405, 12409, 0,
+ 12283, 12287, 12291, 12295, 0,
+ 2008, 12199, 12203, 0,
+ 12207, 12211, 0,
+ 1998, 0,
+ 2028, 0,
+ 2033, 0,
+ 2038, 0,
+ 2043, 0,
+ 2048, 0,
+ 2053, 0,
+ 2013, 0,
+ 2058, 0,
+ 2063, 0,
+ 2018, 0,
+ 2023, 0,
+ 2078, 0,
+ 2083, 0,
+ 2088, 0,
+ 2068, 2073, 0,
+ 2103, 0,
+ 2108, 0,
+ 2113, 0,
+ 2118, 0,
+ 2093, 0,
+ 2098, 0,
+ 2138, 0,
+ 2143, 0,
+ 2123, 2128, 2133, 0,
+ 2148, 0,
+ 2153, 2163, 0,
+ 2158, 0,
+ 2168, 0,
+ 2173, 0,
+ 2178, 2183, 2188, 0,
+ 2193, 0,
+ 2198, 2208, 0,
+ 2203, 0,
+ 2213, 2218, 2228, 0,
+ 2223, 0,
+ 2282, 0,
+ 2257, 0,
+ 2262, 0,
+ 2267, 0,
+ 2272, 0,
+ 2277, 0,
+ 2287, 2292, 2317, 0,
+ 2347, 0,
+ 2322, 0,
+ 2327, 0,
+ 2332, 0,
+ 2337, 0,
+ 2342, 0,
+ 2297, 0,
+ 2307, 0,
+ 2352, 0,
+ 2637, 0,
+ 2642, 0,
+ 2817, 0,
+ 2822, 0,
+ 2877, 0,
+ 2882, 0,
+ 3197, 3247, 0,
+ 3202, 3252, 0,
+ 3327, 0,
+ 3332, 0,
+ 3417, 0,
+ 3422, 0,
+ 3597, 3607, 3617, 4150, 0,
+ 3602, 3612, 3622, 4155, 0,
+ 4160, 0,
+ 4165, 0,
+ 4170, 0,
+ 4175, 0,
+ 4180, 0,
+ 4185, 0,
+ 3637, 3647, 3657, 4190, 0,
+ 3642, 3652, 3662, 4195, 0,
+ 4200, 0,
+ 4205, 0,
+ 4210, 0,
+ 4215, 0,
+ 4220, 0,
+ 4225, 0,
+ 3677, 3687, 0,
+ 3682, 3692, 0,
+ 3707, 3717, 0,
+ 3712, 3722, 0,
+ 3737, 3747, 3757, 4230, 0,
+ 3742, 3752, 3762, 4235, 0,
+ 4240, 0,
+ 4245, 0,
+ 4250, 0,
+ 4255, 0,
+ 4260, 0,
+ 4265, 0,
+ 3777, 3787, 3797, 4270, 0,
+ 3782, 3792, 3802, 4275, 0,
+ 4280, 0,
+ 4285, 0,
+ 4290, 0,
+ 4295, 0,
+ 4300, 0,
+ 4305, 0,
+ 3817, 3827, 3837, 0,
+ 3822, 3832, 3842, 0,
+ 3857, 3867, 3877, 0,
+ 3862, 3872, 3882, 0,
+ 3897, 3907, 0,
+ 3902, 3912, 0,
+ 3927, 3937, 0,
+ 3932, 3942, 0,
+ 3957, 3967, 3977, 0,
+ 3962, 3972, 3982, 0,
+ 3992, 3997, 4002, 0,
+ 4017, 4027, 4037, 4310, 0,
+ 4022, 4032, 4042, 4315, 0,
+ 4320, 0,
+ 4325, 0,
+ 4330, 0,
+ 4335, 0,
+ 4340, 0,
+ 4345, 0,
+ 4057, 4067, 4077, 4350, 0,
+ 4062, 4072, 4082, 4355, 0,
+ 4360, 0,
+ 4365, 0,
+ 4370, 0,
+ 4375, 0,
+ 4380, 0,
+ 4385, 0,
+ 4400, 0,
+ 4473, 0,
+ 4675, 0,
+ 4420, 0,
+ 4521, 4526, 4531, 0,
+ 4493, 0,
+ 4695, 0,
+ 4584, 4589, 4594, 0,
+ 5391, 0,
+ 5396, 0,
+ 5401, 0,
+ 5406, 0,
+ 5416, 0,
+ 5411, 0,
+ 5421, 0,
+ 5426, 0,
+ 5431, 0,
+ 5436, 0,
+ 5441, 0,
+ 5468, 0,
+ 5473, 0,
+ 5478, 0,
+ 5483, 0,
+ 5498, 0,
+ 5493, 0,
+ 5513, 0,
+ 5518, 0,
+ 5523, 0,
+ 5528, 0,
+ 5533, 0,
+ 5538, 0,
+ 5543, 0,
+ 5548, 0,
+ 5593, 0,
+ 5598, 0,
+ 5553, 0,
+ 5558, 0,
+ 5563, 0,
+ 5568, 0,
+ 5603, 0,
+ 5608, 0,
+ 5573, 0,
+ 5578, 0,
+ 5583, 0,
+ 5588, 0,
+ 5613, 0,
+ 5618, 0,
+ 5623, 0,
+ 5628, 0,
+ 7351, 0,
+ 7226, 0,
+ 7231, 0,
+ 7236, 0,
+ 7241, 0,
+ 7246, 0,
+ 7251, 0,
+ 7256, 0,
+ 7261, 0,
+ 7266, 0,
+ 7271, 0,
+ 7276, 0,
+ 7281, 0,
+ 7286, 0,
+ 7291, 0,
+ 7296, 0,
+ 7301, 7306, 0,
+ 7311, 7316, 0,
+ 7321, 7326, 0,
+ 7331, 7336, 0,
+ 7341, 7346, 0,
+ 7366, 0,
+ 7496, 0,
+ 7371, 0,
+ 7376, 0,
+ 7381, 0,
+ 7386, 0,
+ 7391, 0,
+ 7396, 0,
+ 7401, 0,
+ 7406, 0,
+ 7411, 0,
+ 7416, 0,
+ 7421, 0,
+ 7426, 0,
+ 7431, 0,
+ 7436, 0,
+ 7441, 0,
+ 7446, 7451, 0,
+ 7456, 7461, 0,
+ 7466, 7471, 0,
+ 7476, 7481, 0,
+ 7486, 7491, 0,
+ 7501, 0,
+ 7506, 0,
+ 7511, 0,
+ 7516, 0,
+ 7521, 0,
+ 11668, 11673, 0,
+
+};
+
+static const Q_UINT16 li_00[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 18, 20, 0,
+ 0, 22, 39, 43, 49, 56, 74, 76,
+ 84, 92, 108, 110, 116, 123, 127, 137,
+ 154, 0, 157, 166, 174, 182, 202, 205,
+ 212, 215, 225, 0, 0, 0, 0, 0,
+ 0, 232, 249, 253, 259, 266, 284, 286,
+ 294, 303, 318, 321, 327, 334, 338, 348,
+ 365, 0, 368, 377, 385, 394, 414, 417,
+ 425, 428, 439, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 446, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 450, 0, 455, 457, 459, 462,
+ 0, 0, 464, 0, 0, 0, 0, 469,
+ 0, 0, 0, 0, 471, 476, 480, 0,
+ 482, 0, 0, 0, 484, 0, 0, 0,
+ 0, 0, 489, 0, 494, 496, 498, 501,
+ 0, 0, 503, 0, 0, 0, 0, 508,
+ 0, 0, 0, 0, 510, 515, 519, 0,
+ 521, 0, 0, 0, 523, 0, 0, 0,
+};
+
+static const Q_UINT16 li_01[] = {
+ 0, 0, 528, 533, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 538, 541, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 544, 547, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 550, 552, 0, 0, 0, 0,
+ 554, 556, 0, 0, 0, 0, 0, 0,
+ 558, 560, 562, 564, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 566,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 568, 574, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 580,
+ 586, 0, 0, 0, 0, 0, 0, 592,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 594, 596, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_02[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 598, 600,
+ 602, 604, 0, 0, 0, 0, 606, 608,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 610, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_03[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 612, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 614, 0, 0, 0, 622, 0, 627,
+ 0, 633, 0, 0, 0, 0, 0, 641,
+ 0, 646, 0, 0, 0, 648, 0, 0,
+ 0, 655, 0, 0, 661, 0, 663, 0,
+ 0, 665, 0, 0, 0, 674, 0, 679,
+ 0, 686, 0, 0, 0, 0, 0, 695,
+ 0, 700, 0, 0, 0, 703, 0, 0,
+ 0, 712, 719, 723, 0, 0, 727, 0,
+ 0, 0, 729, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_04[] = {
+ 0, 0, 0, 0, 0, 0, 732, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 734, 0, 0, 737, 0, 739, 743, 746,
+ 748, 0, 753, 0, 0, 0, 755, 0,
+ 0, 0, 0, 757, 0, 0, 0, 762,
+ 0, 0, 0, 764, 0, 766, 0, 0,
+ 768, 0, 0, 771, 0, 773, 777, 780,
+ 782, 0, 787, 0, 0, 0, 789, 0,
+ 0, 0, 0, 791, 0, 0, 0, 796,
+ 0, 0, 0, 798, 0, 800, 0, 0,
+ 0, 0, 0, 0, 0, 0, 802, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 804, 806, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 808, 810, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 812, 814, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 816, 820, 823, 825, 827, 829, 832, 0,
+ 834, 836, 839, 841, 844, 0, 846, 0,
+ 848, 850, 0, 852, 854, 0, 857, 859,
+ 861, 863, 867, 0, 0, 0, 0, 0,
+ 0, 0, 869, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 871, 873, 876, 879, 882, 885, 926,
+ 936, 962, 965, 1003, 1021, 1041, 1057, 1071,
+ 1074, 1078, 1083, 1086, 1121, 1158, 1183, 1206,
+ 1224, 1232, 1252, 0, 0, 0, 0, 0,
+ 1268, 1278, 1298, 1316, 1344, 1386, 1415, 1450,
+ 1464, 1469, 1476, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1506, 0, 0, 0, 0, 0, 1509,
+ 0, 1511, 1516, 1521, 0, 0, 1526, 1531,
+ 1536, 0, 0, 1541, 1546, 0, 1551, 1556,
+ 1561, 0, 0, 0, 1564, 1567, 1570, 0,
+ 0, 1573, 0, 0, 0, 0, 0, 0,
+ 1576, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1579, 0, 1584, 0,
+ 0, 1589, 0, 0, 0, 1594, 0, 1599,
+ 0, 1604, 0, 1609, 0, 0, 0, 0,
+ 0, 0, 1614, 1617, 0, 0, 1622, 0,
+ 1627, 1630, 0, 0, 0, 1636, 1639, 1642,
+ 1645, 1648, 0, 1651, 1654, 0, 0, 0,
+ 1659, 0, 1664, 1668, 0, 1671, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_07[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_09[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1673, 1675, 1677,
+ 0, 0, 0, 0, 1679, 0, 0, 0,
+ 0, 1681, 1683, 0, 0, 0, 0, 0,
+ 1685, 0, 0, 1687, 0, 0, 0, 1689,
+ 1691, 0, 0, 1693, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1695, 1697, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1699,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1701,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0A[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1704, 1706,
+ 0, 0, 0, 0, 1708, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1710, 0, 0, 0, 0,
+ 0, 0, 1712, 0, 0, 0, 0, 0,
+ 1714, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0B[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1716, 1718, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1720,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1724, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1726, 1729,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1731, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1733,
+ 0, 0, 0, 0, 0, 0, 1735, 0,
+ 0, 0, 1739, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1741, 1744,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1746, 0, 0, 1750, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1752, 0, 1754, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1756, 0, 0, 0,
+ 0, 1758, 0, 0, 0, 0, 1760, 0,
+ 0, 0, 0, 1762, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1764, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1768, 0, 1770, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1772, 0, 0, 0,
+ 0, 1774, 0, 0, 0, 0, 1776, 0,
+ 0, 0, 0, 1778, 0, 0, 0, 0,
+ 0, 0, 1780, 1782, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_10[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1784, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_1E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1786, 1788,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1790, 1792, 0, 0, 0, 0,
+ 0, 0, 1794, 1796, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1798, 1801, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1804, 1806, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1808, 1810, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_1F[] = {
+ 1812, 1817, 1822, 1824, 1826, 1828, 1830, 1832,
+ 1834, 1839, 1844, 1846, 1848, 1850, 1852, 1854,
+ 1856, 1859, 0, 0, 0, 0, 0, 0,
+ 1862, 1865, 0, 0, 0, 0, 0, 0,
+ 1868, 1873, 1878, 1880, 1882, 1884, 1886, 1888,
+ 1890, 1895, 1900, 1902, 1904, 1906, 1908, 1910,
+ 1912, 1916, 0, 0, 0, 0, 0, 0,
+ 1920, 1924, 0, 0, 0, 0, 0, 0,
+ 1928, 1931, 0, 0, 0, 0, 0, 0,
+ 1934, 1937, 0, 0, 0, 0, 0, 0,
+ 1940, 1944, 0, 0, 0, 0, 0, 0,
+ 0, 1948, 0, 0, 0, 0, 0, 0,
+ 1952, 1957, 1962, 1964, 1966, 1968, 1970, 1972,
+ 1974, 1979, 1984, 1986, 1988, 1990, 1992, 1994,
+ 1996, 0, 0, 0, 1998, 0, 0, 0,
+ 0, 0, 0, 0, 2000, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2002, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2004,
+ 0, 0, 0, 0, 0, 0, 2008, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2010, 0,
+ 0, 0, 0, 0, 0, 0, 2012, 0,
+};
+
+static const Q_UINT16 li_21[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2016, 0, 2018, 0, 2020, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2022, 0, 2024, 0, 2026, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_22[] = {
+ 0, 0, 0, 2028, 0, 0, 0, 0,
+ 2030, 0, 0, 2032, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2034, 0, 2036, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2038, 0, 0, 0,
+ 0, 0, 0, 2040, 0, 2042, 0, 0,
+ 2044, 0, 0, 0, 0, 2046, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2048, 0, 0, 2050, 2052, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2054, 2056, 0, 0, 2058, 2060,
+ 0, 0, 2062, 2064, 2066, 2068, 0, 0,
+ 0, 0, 2070, 2072, 0, 0, 2074, 2076,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2078, 2080, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2082, 0, 0, 0, 0, 0,
+ 2084, 2086, 0, 2088, 0, 0, 0, 0,
+ 0, 0, 2090, 2092, 2094, 2096, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_30[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2098, 0,
+ 0, 0, 0, 2100, 0, 2102, 0, 2104,
+ 0, 2106, 0, 2108, 0, 2110, 0, 2112,
+ 0, 2114, 0, 2116, 0, 2118, 0, 2120,
+ 0, 2122, 0, 0, 2124, 0, 2126, 0,
+ 2128, 0, 0, 0, 0, 0, 0, 2130,
+ 0, 0, 2133, 0, 0, 2136, 0, 0,
+ 2139, 0, 0, 2142, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2145, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2147, 0,
+ 0, 0, 0, 2149, 0, 2151, 0, 2153,
+ 0, 2155, 0, 2157, 0, 2159, 0, 2161,
+ 0, 2163, 0, 2165, 0, 2167, 0, 2169,
+ 0, 2171, 0, 0, 2173, 0, 2175, 0,
+ 2177, 0, 0, 0, 0, 0, 0, 2179,
+ 0, 0, 2182, 0, 0, 2185, 0, 0,
+ 2188, 0, 0, 2191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2194,
+ 2196, 2198, 2200, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2202, 0, 0,
+};
+
+static const Q_UINT16 li_FB[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2204, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 * const ligature_info[256] = {
+ li_00, li_01, li_02, li_03, li_04, li_05, li_06, li_07,
+ li_07, li_09, li_0A, li_0B, li_0C, li_0D, li_07, li_0F,
+ li_10, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_1E, li_1F,
+ li_07, li_21, li_22, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_30, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_FB, li_07, li_07, li_07, li_07,
+};
+// 16188 bytes
+
+static const Q_UINT8 dir_00[] = {
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 8, 7, 8, 9, 7, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 7, 7, 7, 8,
+ 9, 10, 10, 4, 4, 4, 10, 10,
+ 138, 138, 10, 4, 6, 4, 6, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 10, 138, 10, 138, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 18,
+ 18, 18, 18, 18, 18, 7, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 6, 10, 4, 4, 4, 4, 10, 10,
+ 10, 10, 0, 138, 10, 10, 10, 10,
+ 4, 4, 2, 2, 10, 0, 10, 10,
+ 10, 2, 0, 138, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_01[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_02[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 10, 0, 0, 0, 0, 0,
+ 0, 0, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_03[] = {
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 10, 10, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_04[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 17, 17, 17, 17, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 17, 1, 17,
+ 1, 17, 17, 1, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 13, 77, 77, 77, 77, 45, 77,
+ 45, 77, 45, 45, 45, 45, 45, 77,
+ 77, 77, 77, 45, 45, 45, 45, 45,
+ 45, 45, 45, 0, 0, 0, 0, 0,
+ 109, 45, 45, 45, 45, 45, 45, 45,
+ 77, 77, 45, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 4, 5, 5, 13, 0, 0,
+ 17, 13, 77, 77, 13, 77, 77, 77,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 45, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 45, 77, 45, 77,
+ 45, 45, 77, 77, 13, 13, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 13, 13, 17,
+ 17, 10, 17, 17, 17, 17, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 45, 45, 45, 13, 13, 0,
+};
+
+static const Q_UINT8 dir_07[] = {
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 0, 18,
+ 77, 17, 45, 45, 45, 77, 77, 77,
+ 77, 77, 45, 45, 45, 45, 77, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 45, 77, 45, 77, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_09[] = {
+ 0, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 0, 0, 0, 0, 17, 0, 0,
+ 0, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0A[] = {
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 0, 0, 0, 0, 17,
+ 17, 0, 0, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 0, 17,
+ 17, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0B[] = {
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 17,
+ 0, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 17,
+ 17, 0, 0, 0, 0, 0, 17, 17,
+ 17, 0, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 17, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_0F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 17,
+ 0, 17, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0,
+ 17, 17, 17, 17, 17, 0, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_10[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 17, 17,
+ 17, 0, 17, 0, 0, 0, 17, 17,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_16[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_17[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_18[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 18, 18, 18, 18, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_1F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 10,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 0,
+};
+
+static const Q_UINT8 dir_20[] = {
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 18, 18, 18, 0, 1,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 9, 7, 11, 14, 16, 12, 15, 9,
+ 4, 4, 4, 4, 4, 10, 10, 10,
+ 10, 138, 138, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 138, 138, 0,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 18, 18, 18, 18, 18, 18,
+ 2, 0, 0, 0, 2, 2, 2, 2,
+ 2, 2, 4, 4, 10, 138, 138, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 4, 4, 10, 138, 138, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_21[] = {
+ 10, 10, 0, 10, 10, 10, 10, 0,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 0, 10, 10,
+ 10, 0, 0, 0, 0, 0, 10, 10,
+ 10, 10, 10, 10, 0, 10, 0, 10,
+ 0, 10, 0, 0, 0, 0, 4, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_22[] = {
+ 10, 138, 138, 138, 138, 10, 10, 10,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 10, 138, 4, 4, 10, 138, 138, 10,
+ 10, 10, 138, 138, 138, 138, 10, 138,
+ 138, 138, 138, 10, 138, 10, 138, 10,
+ 10, 10, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 138, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 10, 10, 10,
+ 10, 10, 138, 138, 138, 138, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 138,
+ 138, 10, 138, 10, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 10, 10, 138,
+ 138, 138, 138, 10, 10, 10, 10, 10,
+ 138, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 138, 138, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 10, 10, 10, 10, 10, 138, 138,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 138, 138, 138, 138, 138, 10, 10,
+ 138, 138, 10, 10, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 138, 138, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_23[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 10, 10, 10, 10, 10, 10,
+ 10, 138, 138, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 0, 10, 10,
+ 10, 10, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_24[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_25[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_26[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_27[] = {
+ 0, 10, 10, 10, 10, 0, 10, 10,
+ 10, 10, 0, 0, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 10, 0, 10,
+ 10, 10, 10, 0, 0, 0, 10, 0,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_28[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+};
+
+static const Q_UINT8 dir_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 0, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_2F[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_30[] = {
+ 9, 10, 10, 10, 10, 0, 0, 0,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 10, 10, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 17, 17, 17,
+ 10, 0, 0, 0, 0, 0, 10, 10,
+ 0, 0, 0, 0, 0, 0, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 10, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_A4[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 0, 0, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 0, 10, 10, 10, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_FB[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 17, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 0, 1, 0,
+ 1, 1, 0, 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+};
+
+static const Q_UINT8 dir_FC[] = {
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+};
+
+static const Q_UINT8 dir_FD[] = {
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 0, 0, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 0, 0, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 6, 10, 6, 0, 10, 6, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 4,
+ 10, 10, 4, 4, 10, 10, 10, 0,
+ 10, 4, 4, 10, 0, 0, 0, 0,
+ 13, 13, 13, 0, 13, 0, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 0, 0, 18,
+};
+
+static const Q_UINT8 dir_FF[] = {
+ 0, 10, 10, 4, 4, 4, 10, 10,
+ 10, 10, 10, 4, 6, 4, 6, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 10, 10, 10, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 10, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 10, 10, 0,
+ 0, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 10, 10, 10, 4, 4, 0,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 18, 18, 18, 10, 10, 0, 0,
+};
+
+static const Q_UINT8 * const direction_info[256] = {
+ dir_00, dir_01, dir_02, dir_03, dir_04, dir_05, dir_06, dir_07,
+ dir_01, dir_09, dir_0A, dir_0B, dir_0C, dir_0D, dir_0E, dir_0F,
+ dir_10, dir_01, dir_01, dir_01, dir_01, dir_01, dir_16, dir_17,
+ dir_18, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_1F,
+ dir_20, dir_21, dir_22, dir_23, dir_24, dir_25, dir_26, dir_27,
+ dir_28, dir_01, dir_01, dir_01, dir_01, dir_01, dir_2E, dir_2F,
+ dir_30, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_A4, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_FB, dir_FC, dir_FD, dir_FE, dir_FF,
+};
+// 26940 bytes
+
+#endif
+
+// END OF GENERATED DATA
+
+// This is generated too. Script?
+
+#ifndef QT_NO_UNICODETABLES
+
+static const Q_UINT16 case_0 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0,
+ 0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0x0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x0, 0, 0,
+ 0, 0, 0x0, 0, 0, 0, 0, 0,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x0,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178,
+};
+
+static const Q_UINT16 case_1 [] = {
+ 0x101, 0x100, 0x103, 0x102, 0x105, 0x104, 0x107, 0x106,
+ 0x109, 0x108, 0x10b, 0x10a, 0x10d, 0x10c, 0x10f, 0x10e,
+ 0x111, 0x110, 0x113, 0x112, 0x115, 0x114, 0x117, 0x116,
+ 0x119, 0x118, 0x11b, 0x11a, 0x11d, 0x11c, 0x11f, 0x11e,
+ 0x121, 0x120, 0x123, 0x122, 0x125, 0x124, 0x127, 0x126,
+ 0x129, 0x128, 0x12b, 0x12a, 0x12d, 0x12c, 0x12f, 0x12e,
+ 0x69, 0x49, 0x133, 0x132, 0x135, 0x134, 0x137, 0x136,
+ 0x0, 0x13a, 0x139, 0x13c, 0x13b, 0x13e, 0x13d, 0x140,
+ 0x13f, 0x142, 0x141, 0x144, 0x143, 0x146, 0x145, 0x148,
+ 0x147, 0x0, 0x14b, 0x14a, 0x14d, 0x14c, 0x14f, 0x14e,
+ 0x151, 0x150, 0x153, 0x152, 0x155, 0x154, 0x157, 0x156,
+ 0x159, 0x158, 0x15b, 0x15a, 0x15d, 0x15c, 0x15f, 0x15e,
+ 0x161, 0x160, 0x163, 0x162, 0x165, 0x164, 0x167, 0x166,
+ 0x169, 0x168, 0x16b, 0x16a, 0x16d, 0x16c, 0x16f, 0x16e,
+ 0x171, 0x170, 0x173, 0x172, 0x175, 0x174, 0x177, 0x176,
+ 0xff, 0x17a, 0x179, 0x17c, 0x17b, 0x17e, 0x17d, 0x53,
+ 0x0, 0x253, 0x183, 0x182, 0x185, 0x184, 0x254, 0x188,
+ 0x187, 0x256, 0x257, 0x18c, 0x18b, 0x0, 0x1dd, 0x259,
+ 0x25b, 0x192, 0x191, 0x260, 0x263, 0x3d9, 0x269, 0x268,
+ 0x199, 0x198, 0x51, 0x0, 0x26f, 0x272, 0x0, 0x275,
+ 0x1a1, 0x1a0, 0x1a3, 0x1a2, 0x1a5, 0x1a4, 0x280, 0x1a8,
+ 0x1a7, 0x283, 0, 0x0, 0x1ad, 0x1ac, 0x288, 0x1b0,
+ 0x1af, 0x28a, 0x28b, 0x1b4, 0x1b3, 0x1b6, 0x1b5, 0x292,
+ 0x1b9, 0x1b8, 0x0, 0, 0x1bd, 0x1bc, 0, 0,
+ 0, 0, 0, 0, 0x1c6, 0, 0x1c4, 0x1c9,
+ 0, 0x1c7, 0x1cc, 0, 0x1ca, 0x1ce, 0x1cd, 0x1d0,
+ 0x1cf, 0x1d2, 0x1d1, 0x1d4, 0x1d3, 0x1d6, 0x1d5, 0x1d8,
+ 0x1d7, 0x1da, 0x1d9, 0x1dc, 0x1db, 0x18e, 0x1df, 0x1de,
+ 0x1e1, 0x1e0, 0x1e3, 0x1e2, 0x1e5, 0x1e4, 0x1e7, 0x1e6,
+ 0x1e9, 0x1e8, 0x1eb, 0x1ea, 0x1ed, 0x1ec, 0x1ef, 0x1ee,
+ 0x0, 0x1f3, 0, 0x1f1, 0x1f5, 0x1f4, 0, 0,
+ 0, 0, 0x1fb, 0x1fa, 0x1fd, 0x1fc, 0x1ff, 0x1fe,
+};
+
+static const Q_UINT16 case_2 [] = {
+ 0x201, 0x200, 0x203, 0x202, 0x205, 0x204, 0x207, 0x206,
+ 0x209, 0x208, 0x20b, 0x20a, 0x20d, 0x20c, 0x20f, 0x20e,
+ 0x211, 0x210, 0x213, 0x212, 0x215, 0x214, 0x217, 0x216,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x0, 0x0, 0x0, 0x181, 0x186, 0x0, 0x189, 0x18a,
+ 0x0, 0x18f, 0x0, 0x190, 0x0, 0x0, 0x0, 0x0,
+ 0x193, 0x0, 0x0, 0x194, 0x0, 0x0, 0x631, 0x579,
+ 0x197, 0x196, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19c,
+ 0x0, 0x0, 0x19d, 0x0, 0x0, 0x19f, 0x0, 0x0,
+ 0x0, 0x0, 0x7e1, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1a6, 0x0, 0x0, 0x1a9, 0x0, 0x0, 0x0, 0x0,
+ 0x1ae, 0x0, 0x1b1, 0x1b2, 0x0, 0xa21, 0x971, 0x0,
+ 0x0, 0x0, 0x1b7, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_3 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0x3ac, 0,
+ 0x3ad, 0x3ae, 0x3af, 0, 0x3cc, 0, 0x3cd, 0x3ce,
+ 0x0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7,
+ 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf,
+ 0x3c0, 0x3c1, 0, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7,
+ 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x386, 0x388, 0x389, 0x38a,
+ 0x0, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397,
+ 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f,
+ 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7,
+ 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0,
+ 0x392, 0x398, 0x0, 0x0, 0x0, 0x3a6, 0x3a0, 0,
+ 0, 0, 0x0, 0, 0x0, 0, 0x0, 0,
+ 0x0, 0, 0x3e3, 0x3e2, 0x3e5, 0x3e4, 0x3e7, 0x3e6,
+ 0x3e9, 0x3e8, 0x3eb, 0x3ea, 0x3ed, 0x3ec, 0x3ef, 0x3ee,
+ 0x39a, 0x3a1, 0x3a3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_4 [] = {
+ 0, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457,
+ 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0, 0x45e, 0x45f,
+ 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
+ 0x438, 0x439, 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f,
+ 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
+ 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, 0x44e, 0x44f,
+ 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
+ 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f,
+ 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
+ 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f,
+ 0, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,
+ 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0, 0x40e, 0x40f,
+ 0x461, 0x460, 0x463, 0x462, 0x465, 0x464, 0x467, 0x466,
+ 0x469, 0x468, 0x46b, 0x46a, 0x46d, 0x46c, 0x46f, 0x46e,
+ 0x471, 0x470, 0x473, 0x472, 0x475, 0x474, 0x477, 0x476,
+ 0x479, 0x478, 0x47b, 0x47a, 0x47d, 0x47c, 0x47f, 0x47e,
+ 0x481, 0x480, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x491, 0x490, 0x493, 0x492, 0x495, 0x494, 0x497, 0x496,
+ 0x499, 0x498, 0x49b, 0x49a, 0x49d, 0x49c, 0x49f, 0x49e,
+ 0x4a1, 0x4a0, 0x4a3, 0x4a2, 0x4a5, 0x4a4, 0x4a7, 0x4a6,
+ 0x4a9, 0x4a8, 0x4ab, 0x4aa, 0x4ad, 0x4ac, 0x4af, 0x4ae,
+ 0x4b1, 0x4b0, 0x4b3, 0x4b2, 0x4b5, 0x4b4, 0x4b7, 0x4b6,
+ 0x4b9, 0x4b8, 0x4bb, 0x4ba, 0x4bd, 0x4bc, 0x4bf, 0x4be,
+ 0, 0x4c2, 0x4c1, 0x4c4, 0x4c3, 0, 0, 0x4c8,
+ 0x4c7, 0, 0, 0x4cc, 0x4cb, 0, 0, 0,
+ 0x4d1, 0x4d0, 0x4d3, 0x4d2, 0x4d5, 0x4d4, 0x4d7, 0x4d6,
+ 0x4d9, 0x4d8, 0x4db, 0x4da, 0x4dd, 0x4dc, 0x4df, 0x4de,
+ 0x4e1, 0x4e0, 0x4e3, 0x4e2, 0x4e5, 0x4e4, 0x4e7, 0x4e6,
+ 0x4e9, 0x4e8, 0x4eb, 0x4ea, 0, 0, 0x4ef, 0x4ee,
+ 0x4f1, 0x4f0, 0x4f3, 0x4f2, 0x4f5, 0x4f4, 0, 0,
+ 0x4f9, 0x4f8, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_5 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567,
+ 0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d, 0x56e, 0x56f,
+ 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577,
+ 0x578, 0x579, 0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f,
+ 0x580, 0x581, 0x582, 0x583, 0x584, 0x585, 0x586, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537,
+ 0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f,
+ 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546, 0x547,
+ 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f,
+ 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_10 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7,
+ 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df,
+ 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7,
+ 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef,
+ 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_1e [] = {
+ 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06,
+ 0x1e09, 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e,
+ 0x1e11, 0x1e10, 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16,
+ 0x1e19, 0x1e18, 0x1e1b, 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e,
+ 0x1e21, 0x1e20, 0x1e23, 0x1e22, 0x1e25, 0x1e24, 0x1e27, 0x1e26,
+ 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, 0x1e2c, 0x1e2f, 0x1e2e,
+ 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, 0x1e37, 0x1e36,
+ 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, 0x1e3e,
+ 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46,
+ 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e,
+ 0x1e51, 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56,
+ 0x1e59, 0x1e58, 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e,
+ 0x1e61, 0x1e60, 0x1e63, 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66,
+ 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e,
+ 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, 0x1e74, 0x1e77, 0x1e76,
+ 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, 0x1e7f, 0x1e7e,
+ 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, 0x1e86,
+ 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e,
+ 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1e60, 0, 0, 0, 0,
+ 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6,
+ 0x1ea9, 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae,
+ 0x1eb1, 0x1eb0, 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6,
+ 0x1eb9, 0x1eb8, 0x1ebb, 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe,
+ 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6,
+ 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, 0x1ecc, 0x1ecf, 0x1ece,
+ 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, 0x1ed7, 0x1ed6,
+ 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, 0x1ede,
+ 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6,
+ 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee,
+ 0x1ef1, 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6,
+ 0x1ef9, 0x1ef8, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_1f [] = {
+ 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f,
+ 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07,
+ 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0, 0,
+ 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0, 0,
+ 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f,
+ 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27,
+ 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f,
+ 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37,
+ 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0, 0,
+ 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0, 0,
+ 0x0, 0x1f59, 0x0, 0x1f5b, 0x0, 0x1f5d, 0x0, 0x1f5f,
+ 0, 0x1f51, 0, 0x1f53, 0, 0x1f55, 0, 0x1f57,
+ 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f,
+ 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67,
+ 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb,
+ 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0, 0,
+ 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
+ 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
+ 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
+ 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
+ 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
+ 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
+ 0x1fb8, 0x1fb9, 0x0, 0x1fbc, 0x0, 0, 0x0, 0x0,
+ 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0, 0x399, 0,
+ 0, 0, 0x0, 0x1fcc, 0x0, 0, 0x0, 0x0,
+ 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0, 0, 0,
+ 0x1fd8, 0x1fd9, 0x0, 0x0, 0, 0, 0x0, 0x0,
+ 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0, 0, 0, 0,
+ 0x1fe8, 0x1fe9, 0x0, 0x0, 0x0, 0x1fec, 0x0, 0x0,
+ 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0, 0, 0,
+ 0, 0, 0x0, 0x1ffc, 0x0, 0, 0x0, 0x0,
+ 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0, 0, 0,
+};
+
+static const Q_UINT16 case_20 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_21 [] = {
+ 0, 0, 0x0, 0, 0, 0, 0, 0x0,
+ 0, 0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0, 0x0, 0, 0,
+ 0x761, 0x0, 0x0, 0x0, 0x0, 0x0, 0, 0,
+ 0, 0, 0, 0, 0x0, 0, 0x0, 0,
+ 0x0, 0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0, 0x0, 0x0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_fb [] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_ff [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
+ 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
+ 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
+ 0xff58, 0xff59, 0xff5a, 0, 0, 0, 0, 0,
+ 0, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+ 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f,
+ 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37,
+ 0xff38, 0xff39, 0xff3a, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 * const case_info[256] = {
+
+ case_0, case_1, case_2, case_3, case_4, case_5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ case_10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, case_1e, case_1f,
+ case_20, case_21, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, case_fb, 0, 0, 0, case_ff,
+};
+
+static const Q_INT8 num_0 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, -1, -1, -1, -1,
+ -1, 1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_6 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_9 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_b [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_d [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_e [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_f [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_20 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, -1, -1, -1, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 num_ff [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+static const Q_INT8 * const decimal_info[256] = {
+ num_0, 0, 0, 0, 0, 0, num_6, 0,
+ 0, num_9, num_9, num_b, num_9, num_d, num_e, num_f,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ num_20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, num_ff,
+};
+
+static const Q_UINT16 symmetricPairs[] = {
+ 0x0028, 0x0029, 0x0029, 0x0028, 0x003C, 0x003E, 0x003E, 0x003C,
+ 0x005B, 0x005D, 0x005D, 0x005B, 0x007B, 0x007D, 0x007D, 0x007B,
+ 0x2045, 0x2046, 0x2046, 0x2045, 0x207D, 0x207E, 0x207E, 0x207D,
+ 0x208D, 0x208E, 0x208E, 0x208D, 0x3008, 0x3009, 0x3009, 0x3008,
+ 0x300A, 0x300B, 0x300B, 0x300A, 0x300C, 0x300D, 0x300D, 0x300C,
+ 0x300E, 0x300F, 0x300F, 0x300E, 0x3010, 0x3011, 0x3011, 0x3010,
+ 0x3014, 0x3015, 0x3015, 0x3014, 0x3016, 0x3017, 0x3017, 0x3016,
+ 0x3018, 0x3019, 0x3019, 0x3018, 0x301A, 0x301B, 0x301B, 0x301A,
+ 0xFD3E, 0xFD3F, 0xFD3F, 0xFD3E, 0xFE59, 0xFE5A, 0xFE5A, 0xFE59,
+ 0xFE5B, 0xFE5C, 0xFE5C, 0xFE5B, 0xFE5D, 0xFE5E, 0xFE5E, 0xFE5D,
+ 0xFF08, 0xFF09, 0xFF09, 0xFF08, 0xFF3B, 0xFF3D, 0xFF3D, 0xFF3B,
+ 0xFF5B, 0xFF5D, 0xFF5D, 0xFF5B, 0xFF62, 0xFF63, 0xFF63, 0xFF62,
+};
+
+static int symmetricPairsSize =
+ sizeof(symmetricPairs)/sizeof(symmetricPairs[0]);
+
+/*
+ * ----------------------------------------------------------------------
+ * End of unicode tables
+ * ----------------------------------------------------------------------
+ */
+
+#endif
+
+
+static int ucstrcmp( const QString &as, const QString &bs )
+{
+ const QChar *a = as.unicode();
+ const QChar *b = bs.unicode();
+ if ( a == b )
+ return 0;
+ if ( a == 0 )
+ return 1;
+ if ( b == 0 )
+ return -1;
+ int l=QMIN(as.length(),bs.length());
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return ( as.length()-bs.length() );
+ return a->unicode() - b->unicode();
+}
+
+static int ucstrncmp( const QChar *a, const QChar *b, int l )
+{
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ return a->unicode() - b->unicode();
+}
+
+static int ucstrnicmp( const QChar *a, const QChar *b, int l )
+{
+ while ( l-- && a->lower() == b->lower() )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ QChar al = a->lower();
+ QChar bl = b->lower();
+ return al.unicode() - bl.unicode();
+}
+
+// NOT REVISED
+/*! \class QCharRef qstring.h
+ \brief The QCharRef class is a helper class for QString.
+
+ It provides the ability to work on characters in a QString in a natural
+ fashion.
+
+ When you get an object of type QCharRef, you can assign to it, which
+ will operate on the string from which you got it. That is its whole
+ purpose in life. It becomes invalid once further modifications are
+ made to the string: If you want to keep it, copy it into a QChar.
+
+ Most of the QChar member functions also exist in QCharRef. However,
+ they are not explicitly documented here.
+
+ \sa QString::operator[]() QString::at() QChar
+*/
+
+/*! \class QChar qstring.h
+
+\brief The QChar class provides a light-weight Unicode character.
+
+Unicode characters are (so far) 16-bit entities without any markup or
+structure. This class represents such an entity. It is rather
+light-weight, so it can be used everywhere. Most compilers treat it
+approximately like "short int". (In a few years, it may be necessary
+to make QChar 32-bit, once more than 65536 Unicode code points have
+been defined and come into use.)
+
+QChar provides a full complement of testing/classification functions,
+conversion to and from other formats, from composed to decomposed
+unicode, and will try to compare and case-convert if you ask it to.
+
+The classification functions include functions like those in ctype.h,
+but operating on the full range of unicode characters. They all
+return TRUE if the character is a certain type of character, and FALSE
+otherwise.
+
+These functions are: isNull() (returns TRUE if the character is
+U+0000), isPrint() (TRUE if the character is any sort of printable
+character, including whitespace), isPunct() (any sort of punctation),
+isMark() (Unicode Marks), isLetter (letters), isNumber() (any sort of
+numeric characters), isLetterOrNumber(), and isDigit() (decimal digits).
+All of these are wrappers around category(), which returns the
+unicode-defined category of each character.
+
+QChar further provides direction(), which indicates the "natural"
+writing direction of this character, joining(), which indicates how
+this character joins with its neighbors (needed mostly for Arabic)
+and finally mirrored(), which indicates whether this character needs
+to be mirrored when it is printed in its unnatural writing
+direction.
+
+Composed Unicode characters (like å) can be converted to
+decomposed Unicode ("a" followed by "ring above") using
+decomposition().
+
+In Unicode, comparison is not necessarily possible, and case
+conversion is at best very hard. Unicode, covering the "entire"
+globe, also includes a globe-sized collection of case and sorting
+problems. Qt tries, but not very hard: operator== and friends will do
+comparison based purely on the numeric Unicode value (code point) of
+the characters, and upper() and lower() will do case changes when the
+character has a well-defined upper/lower-case equivalent. There is no
+provision for locale-dependent case folding rules or comparison: These
+functions are meant to be fast, so they can be used unambiguously in
+data structures.
+
+The conversion functions include unicode() (to a scalar), latin1() (to
+scalar, but converts all non-Latin1 characters to 0), row() (gives the
+Unicode row), cell() (gives the unicode cell), digitValue() (gives the
+integer value of any of the numerous digit characters), and a host of
+constructors.
+
+\sa QString QCharRef \link unicode.html About Unicode \endlink
+*/
+
+/*! \enum QChar::Category
+
+This enum maps the Unicode character categories. The currently known
+categories are: <ul>
+
+<li> \c NoCategory - used when Qt is dazed and confused and cannot
+make sense of anything.
+
+<li> \c Mark_NonSpacing - (Mn) -
+
+<li> \c Mark_SpacingCombining - (Mc) -
+
+<li> \c Mark_Enclosing - (Me) -
+
+<li> \c Number_DecimalDigit - (Nd) -
+
+<li> \c Number_Letter - (Nl) -
+
+<li> \c Number_Other - (No) -
+
+<li> \c Separator_Space - (Zs) -
+
+<li> \c Separator_Line - (Zl) -
+
+<li> \c Separator_Paragraph - (Zp) -
+
+<li> \c Other_Control - (Cc) -
+
+<li> \c Other_Format - (Cf) -
+
+<li> \c Other_Surrogate - (Cs) -
+
+<li> \c Other_PrivateUse - (Co) -
+
+<li> \c Other_NotAssigned - (Cn) -
+
+<li> \c Letter_Uppercase - (Lu) -
+
+<li> \c Letter_Lowercase - (Ll) -
+
+<li> \c Letter_Titlecase - (Lt) -
+
+<li> \c Letter_Modifier - (Lm) -
+
+<li> \c Letter_Other - (Lo) -
+
+<li> \c Punctuation_Connector - (Pc) -
+
+<li> \c Punctuation_Dask - (Pd) -
+
+<li> \c Punctuation_Open - (Ps) -
+
+<li> \c Punctuation_Close - (Pe) -
+
+<li> \c Punctuation_InitialQuote - (Pi) -
+
+<li> \c Punctuation_FinalQuote - (Pf) -
+
+<li> \c Punctuation_Other - (Po) -
+
+<li> \c Symbol_Math - (Sm) -
+
+<li> \c Symbol_Currency - (Sc) -
+
+<li> \c Symbol_Modifier - (Sk) -
+
+<li> \c Symbol_Other - (So) -
+
+</ul>
+*/
+
+/*! \enum QChar::Direction
+
+ This enum type defines the Unicode direction attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+
+ In order to conform to C/C++ naming conventions "Dir" is
+ prepended to the codes used in The Unicode Standard.
+*/
+
+/*! \enum QChar::Decomposition
+
+ This enum type defines the Unicode decomposition attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+*/
+
+/*! \enum QChar::Joining
+
+ This enum type defines the Unicode decomposition attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+*/
+
+
+
+/*! \fn QChar::QChar()
+
+Constructs a null QChar (one that isNull()).
+*/
+
+
+/*! \fn QChar::QChar( char c )
+
+Constructs a QChar corresponding to ASCII/Latin1 character \a c.
+*/
+
+
+/*! \fn QChar::QChar( uchar c )
+
+Constructs a QChar corresponding to ASCII/Latin1 character \a c.
+*/
+
+
+/*! \fn QChar::QChar( uchar c, uchar r )
+
+Constructs a QChar for Unicode cell \a c in row \a r.
+*/
+
+
+/*! \fn QChar::QChar( const QChar& c )
+
+Constructs a copy of \a c. This is a deep copy, if such a
+light-weight object can be said to have deep copies.
+*/
+
+
+/*! \fn QChar::QChar( ushort rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( short rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( uint rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( int rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn bool QChar::networkOrdered ()
+
+ Returns TRUE if this character is in network byte order (MSB first),
+ and FALSE if it is not. This is a platform-dependent property, so
+ we strongly advise against using this function in portable code.
+*/
+
+
+/*!
+ \fn bool QChar::isNull() const
+ Returns TRUE if the characters is the unicode character 0x0000,
+ ie. ASCII NUL.
+*/
+
+/*!
+ \fn uchar QChar::cell () const
+ Returns the cell (least significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar QChar::row () const
+ Returns the row (most significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar& QChar::cell ()
+ Returns a reference to the cell (least significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar& QChar::row ()
+ Returns a reference to the row (most significant byte) of the Unicode character.
+*/
+
+/*!
+ Returns whether the character is a printable character. This is
+ any character not of category Cc or Cn. Note that this gives no indication
+ of whether the character is available in some font.
+*/
+bool QChar::isPrint() const
+{
+ Category c = category();
+ return !(c == Other_Control || c == Other_NotAssigned);
+}
+
+/*!
+ Returns whether the character is a separator
+ character (Separator_* categories).
+*/
+bool QChar::isSpace() const
+{
+ if( !row() )
+ if( cell() >= 9 && cell() <=13 ) return TRUE;
+ Category c = category();
+ return c >= Separator_Space && c <= Separator_Paragraph;
+}
+
+/*!
+ Returns whether the character is a mark (Mark_* categories).
+*/
+bool QChar::isMark() const
+{
+ Category c = category();
+ return c >= Mark_NonSpacing && c <= Mark_Enclosing;
+}
+
+/*!
+ Returns whether the character is punctuation (Punctuation_* categories).
+*/
+bool QChar::isPunct() const
+{
+ Category c = category();
+ return (c >= Punctuation_Connector && c <= Punctuation_Other);
+}
+
+/*!
+ Returns whether the character is a letter (Letter_* categories).
+*/
+bool QChar::isLetter() const
+{
+ Category c = category();
+ return (c >= Letter_Uppercase && c <= Letter_Other);
+}
+
+/*!
+ Returns whether the character is a number (of any sort - Number_* categories).
+
+ \sa isDigit()
+*/
+bool QChar::isNumber() const
+{
+ Category c = category();
+ return c >= Number_DecimalDigit && c <= Number_Other;
+}
+
+/*!
+ Returns whether the character is a letter or number (Letter_* or Number_* categories).
+*/
+bool QChar::isLetterOrNumber() const
+{
+ Category c = category();
+ return (c >= Letter_Uppercase && c <= Letter_Other)
+ || (c >= Number_DecimalDigit && c <= Number_Other);
+}
+
+
+/*!
+ Returns whether the character is a decimal digit (Number_DecimalDigit).
+ */
+bool QChar::isDigit() const
+{
+ return (category() == Number_DecimalDigit);
+}
+
+/*!
+ Returns the numeric value of the digit, or -1 if the character is not
+ a digit.
+*/
+int QChar::digitValue() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_INT8 *dec_row = decimal_info[row()];
+ if( !dec_row )
+ return -1;
+ return decimal_info[row()][cell()];
+#else
+ // ##### just latin1
+ if ( rw != 0 || cl < '0' || cl > '9' )
+ return -1;
+ else
+ return cl - '0';
+#endif
+}
+
+/*!
+ Returns the character category.
+
+ \sa Category
+*/
+QChar::Category QChar::category() const
+{
+#ifndef QT_NO_UNICODETABLES
+ return (Category)(unicode_info[row()][cell()]);
+#else
+// ### just ASCII
+ if ( rw == 0 ) {
+ return (Category)(ui_00[cell()]);
+ }
+ return Letter_Uppercase; //#######
+#endif
+}
+
+/*!
+ Returns the characters directionality.
+
+ \sa Direction
+*/
+QChar::Direction QChar::direction() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if(!rowp) return QChar::DirL;
+ return (Direction) ( *(rowp+cell()) &0x1f );
+#else
+ return DirL;
+#endif
+}
+
+/*!
+ This function is not supported (it may change to use Unicode
+ character classes).
+
+ Returns information about the joining properties of the
+ character (needed for arabic).
+*/
+QChar::Joining QChar::joining() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if ( !rowp )
+ return QChar::OtherJoining;
+ return (Joining) ((*(rowp+cell()) >> 5) &0x3);
+#else
+ return OtherJoining;
+#endif
+}
+
+
+/*!
+ Returns whether the character is a mirrored character (one that
+ should be reversed if the text direction is reversed).
+*/
+bool QChar::mirrored() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if ( !rowp )
+ return FALSE;
+ return *(rowp+cell())>128;
+#else
+ return FALSE;
+#endif
+}
+
+/*!
+ Returns the mirrored char if this character is a mirrored char, the char
+ itself otherwise
+*/
+QChar QChar::mirroredChar() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(!mirrored()) return *this;
+
+ int i;
+ int c = unicode();
+ for (i = 0; i < symmetricPairsSize; i += 2) {
+ if (symmetricPairs[i] == c)
+ return symmetricPairs[i+1];
+ }
+ return 0;
+#else
+ return *this;
+#endif
+}
+
+/*!
+ Decomposes a character into its parts. Returns QString::null if
+ no decomposition exists.
+*/
+QString QChar::decomposition() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT16 *r = decomposition_info[row()];
+ if(!r) return QString::null;
+
+ Q_UINT16 pos = r[cell()];
+ if(!pos) return QString::null;
+ pos+=2;
+
+ QString s;
+ Q_UINT16 c;
+ while((c = decomposition_map[pos++]) != 0) s += QChar(c);
+
+ return s;
+#else
+ return null;
+#endif
+}
+
+/*!
+ Returns the tag defining the composition of the character.
+ Returns QChar::Single if no decomposition exists.
+*/
+QChar::Decomposition QChar::decompositionTag() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT16 *r = decomposition_info[row()];
+ if(!r) return QChar::Single;
+
+ Q_UINT16 pos = r[cell()];
+ if(!pos) return QChar::Single;
+
+ return (QChar::Decomposition) decomposition_map[pos];
+#else
+ return Single; // ########### FIX eg. just latin1
+#endif
+}
+
+/*!
+ Returns the lowercase equivalent if the character is uppercase,
+ or the character itself otherwise.
+*/
+QChar QChar::lower() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(category() != Letter_Uppercase) return *this;
+ Q_UINT16 lower = *(case_info[row()]+cell());
+ if(lower == 0) return *this;
+ return lower;
+#else
+ if (row())
+ return *this;
+ else
+ return QChar(tolower(latin1()));
+#endif
+}
+
+/*!
+ Returns the uppercase equivalent if the character is lowercase,
+ or the character itself otherwise.
+*/
+QChar QChar::upper() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(category() != Letter_Lowercase) return *this;
+ Q_UINT16 upper = *(case_info[row()]+cell());
+ if(upper == 0) return *this;
+ return upper;
+#else
+ if (row())
+ return *this;
+ else
+ return QChar(toupper(latin1()));
+#endif
+}
+
+/*!
+ \fn QChar::operator char() const
+
+ Returns the Latin1 character equivalent to the QChar,
+ or 0. This is mainly useful for non-internationalized software.
+
+ \sa unicode()
+*/
+
+/*!
+ \fn ushort QChar::unicode() const
+
+ Returns the numeric Unicode value equal to the QChar. Normally, you
+ should use QChar objects as they are equivalent, but for some low-level
+ tasks (eg. indexing into an array of Unicode information), this function
+ is useful.
+*/
+
+/*****************************************************************************
+ Documentation of QChar related functions
+ *****************************************************************************/
+
+/*!
+ \fn int operator==( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if \a c1 and \a c2 are the same Unicode character.
+*/
+
+/*!
+ \fn int operator==( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if \a c is the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator==( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if \a c is the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator!=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if \a c1 and \a c2 are not the same Unicode character.
+*/
+
+/*!
+ \fn int operator!=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if \a c is not the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator!=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if \a c is not the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than that
+ of \a c2, or they are the same Unicode character.
+*/
+
+/*!
+ \fn int operator<=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than or
+ equal to that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is less than or equal to that of \a c.
+*/
+
+/*!
+ \fn int operator>=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than that
+ of \a c2, or they are the same Unicode character.
+*/
+
+/*!
+ \fn int operator>=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than or
+ equal to that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator>=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is greater than or equal to that of \a c.
+*/
+
+/*!
+ \fn int operator<( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than that
+ of \a c2.
+*/
+
+/*!
+ \fn int operator<( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than that
+ of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is less than that of \a c.
+*/
+
+/*!
+ \fn int operator>( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than
+ that of \a c2.
+*/
+
+/*!
+ \fn int operator>( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than
+ that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator>( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is greater than that of \a c.
+*/
+
+#ifndef QT_NO_UNICODETABLES
+
+// small class used internally in QString::Compose()
+class QLigature
+{
+public:
+ QLigature( QChar c );
+
+ Q_UINT16 first() { cur = ligatures; return cur ? *cur : 0; }
+ Q_UINT16 next() { return cur && *cur ? *(cur++) : 0; }
+ Q_UINT16 current() { return cur ? *cur : 0; }
+
+ int match(QString & str, unsigned int index);
+ QChar head();
+ QChar::Decomposition tag();
+
+private:
+ Q_UINT16 *ligatures;
+ Q_UINT16 *cur;
+};
+
+QLigature::QLigature( QChar c )
+{
+ const Q_UINT16 *r = ligature_info[c.row()];
+ if( !r )
+ ligatures = 0;
+ else
+ {
+ const Q_UINT16 pos = r[c.cell()];
+ ligatures = (Q_UINT16 *)&(ligature_map[pos]);
+ }
+ cur = ligatures;
+}
+
+QChar QLigature::head()
+{
+ if(current())
+ return QChar(decomposition_map[current()+1]);
+
+ return QChar::null;
+}
+
+QChar::Decomposition QLigature::tag()
+{
+ if(current())
+ return (QChar::Decomposition) decomposition_map[current()];
+
+ return QChar::Canonical;
+}
+
+int QLigature::match(QString & str, unsigned int index)
+{
+ unsigned int i=index;
+
+ if(!current()) return 0;
+
+ Q_UINT16 lig = current() + 2;
+ Q_UINT16 ch;
+
+ while ((i < str.length()) && (ch = decomposition_map[lig])) {
+ if (str[(int)i] != QChar(ch))
+ return 0;
+ i++; lig++;
+ }
+
+ if (!decomposition_map[lig])
+ {
+ return i-index;
+ }
+ return 0;
+}
+
+// this function is just used in QString::compose()
+static inline bool format(QChar::Decomposition tag, QString & str,
+ int index, int len)
+{
+ unsigned int l = index + len;
+ unsigned int r = index;
+
+ bool left = FALSE, right = FALSE;
+
+ left = ((l < str.length()) &&
+ ((str[(int)l].joining() == QChar::Dual) ||
+ (str[(int)l].joining() == QChar::Right)));
+ if (r > 0) {
+ r--;
+ //printf("joining(right) = %d\n", str[(int)r].joining());
+ right = (str[(int)r].joining() == QChar::Dual);
+ }
+
+
+ switch (tag) {
+ case QChar::Medial:
+ return (left && right);
+ case QChar::Initial:
+ return (left && !right);
+ case QChar::Final:
+ return (right);// && !left);
+ case QChar::Isolated:
+ default:
+ return (!right && !left);
+ }
+} // format()
+#endif
+
+/*
+ QString::compose() and visual() were developed by Gordon Tisher
+ <tisher at uniserve.ca>, with input from Lars Knoll <knoll at mpi-hd.mpg.de>,
+ who developed the unicode data tables.
+*/
+/*!
+ Note that this function is not supported in Qt 2.0, and is merely
+ for experimental and illustrative purposes. It is mainly of interest
+ to those experimenting with Arabic and other composition-rich texts.
+
+ Applies possible ligatures to a QString, useful when composition-rich
+ text requires rendering with glyph-poor fonts, but also
+ makes compositions such as QChar(0x0041) ('A') and QChar(0x0308)
+ (Unicode accent diaresis) giving QChar(0x00c4) (German A Umlaut).
+*/
+void QString::compose()
+{
+#ifndef QT_NO_UNICODETABLES
+ unsigned int index=0, len;
+ unsigned int cindex = 0;
+
+ QChar code, head;
+
+ QArray<QChar> dia;
+
+ QString composed = *this;
+
+ while (index < length()) {
+ code = at(index);
+ //printf("\n\nligature for 0x%x:\n", code.unicode());
+ QLigature ligature(code);
+ ligature.first();
+ while(ligature.current()) {
+ if ((len = ligature.match(*this, index)) != 0) {
+ head = ligature.head();
+ unsigned short code = head.unicode();
+ // we exclude Arabic presentation forms A and a few
+ // other ligatures, which are undefined in most fonts
+ if(!(code > 0xfb50 && code < 0xfe80) &&
+ !(code > 0xfb00 && code < 0xfb2a)) {
+ // joining info is only needed for arabic
+ if (format(ligature.tag(), *this, index, len)) {
+ //printf("using ligature 0x%x, len=%d\n",code,len);
+ // replace letter
+ composed.replace(cindex, len, QChar(head));
+ index += len-1;
+ // we continue searching in case we have a final
+ // form because medial ones are preferred.
+ if ( len != 1 || ligature.tag() !=QChar::Final )
+ break;
+ }
+ }
+ }
+ ligature.next();
+ }
+ cindex++;
+ index++;
+ }
+ *this = composed;
+#endif
+}
+
+static QChar LRM ((ushort)0x200e);
+static QChar RLM ((ushort)0x200f);
+static QChar LRE ((ushort)0x202a);
+static QChar RLE ((ushort)0x202b);
+static QChar RLO ((ushort)0x202e);
+static QChar LRO ((ushort)0x202d);
+static QChar PDF ((ushort)0x202c);
+
+#if 0
+static inline bool is_arabic(unsigned short x) {
+ return (((x >= 0x0600) && (x <= 0x07bf)) ||
+ ((x >= 0xfb50) && (x <= 0xfdff)) ||
+ ((x >= 0xfe70) && (x <= 0xfeff)));
+}
+#endif
+
+#ifndef QT_NO_UNICODETABLES
+static inline bool is_neutral(unsigned short dir) {
+ return ((dir == QChar::DirB) ||
+ (dir == QChar::DirS) ||
+ (dir == QChar::DirWS) ||
+ (dir == QChar::DirON) ||
+ (dir == QChar::DirNSM));
+}
+#endif
+
+/*!
+ This function returns the basic directionality of the string (QChar::DirR for
+ right to left and QChar::DirL for left to right). Useful to find the right
+ alignment.
+ */
+QChar::Direction QString::basicDirection()
+{
+#ifndef QT_NO_UNICODETABLES
+ // find base direction
+ unsigned int pos = 0;
+ while ((pos < length()) &&
+ (at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)) // not R and not L
+ pos++;
+
+ if ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO))
+ return QChar::DirR;
+#endif
+
+ return QChar::DirL;
+}
+
+#ifndef QT_NO_UNICODETABLES
+// reverses part of the QChar array to get visual ordering
+// called from QString::visual()
+//
+static unsigned int reverse( QString &chars, unsigned char *level,
+ unsigned int a, unsigned int b)
+{
+ unsigned int c = a;
+ unsigned char lev = level[c];
+
+ while ((c < b) && (level[c] >= lev)) {
+ if (level[c] > lev)
+ c = reverse(chars, level, c, b);
+ c++;
+ }
+
+ if (lev > 0) {
+ QChar temp;
+ unsigned int d = a, e = c-1;
+ while (d < e) {
+ temp = chars[(int)d];
+ chars[(int)d] = chars[(int)e];
+ chars[(int)e] = temp;
+
+ d++; e--;
+ }
+ }
+
+ return c;
+}
+
+// small class used for the ordering algorithm in QString::visual()
+class QBidiState {
+public:
+ unsigned char level;
+ signed char override;
+
+ QBidiState(unsigned char l, signed char o) : level(l), override(o) {};
+};
+
+// matrix for resolving neutral types
+
+#define NEG1 (QChar::Direction)(-1)
+
+static QChar::Direction resolv[5][5] =
+{
+ { NEG1, QChar::DirR, QChar::DirL, QChar::DirEN, QChar::DirAN },
+ { QChar::DirR, QChar::DirR, NEG1, QChar::DirR, QChar::DirR },
+ { QChar::DirL, NEG1, QChar::DirL, QChar::DirL, NEG1 },
+ { QChar::DirEN, QChar::DirR, QChar::DirL, QChar::DirEN, QChar::DirR },
+ { QChar::DirAN, QChar::DirR, NEG1, NEG1, QChar::DirAN }
+};
+
+#endif
+
+/*!
+ This function returns the QString ordered visually. Useful for
+ painting the string or when transforming to a visually ordered
+ encoding.
+*/
+QString QString::visual(int index, int len)
+{
+#ifndef QT_NO_UNICODETABLES
+ // #### This needs much more optimizing - it is called for
+ // #### every text operation.
+
+ unsigned char *level;
+ QChar::Direction *dir;
+ unsigned char base = 0;
+
+ unsigned int l = length();
+
+ // check bounds
+ if (len == -1)
+ len = length()-index;
+ if ((uint)index > l)
+ return QString::null;
+
+ // find base direction
+ unsigned int pos = 0;
+ while ((pos < length()) &&
+ (at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)
+ ) // not R and not L
+ pos++;
+
+ if ((pos < length()) &&
+ ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO)))
+ base = 1;
+
+ // is there any BiDi char at all?
+ if ( base == 0 && pos == l ) {
+ return mid(index, len);
+ }
+
+
+ level = new uchar[l];
+ dir = new QChar::Direction[l];
+
+ // explicit override pass
+ //unsigned int code_count = 0;
+
+ QStack<QBidiState> stack;
+ stack.setAutoDelete(TRUE);
+
+ unsigned char clevel = base;
+ signed char override = -1;
+
+ for (pos = 0; pos < l; pos++) {
+
+ if (at(pos) == RLE) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 1 + clevel % 2;
+ override = -1;
+ }
+ else if (at(pos) == LRE) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 2 - clevel % 2;
+ override = -1;
+ }
+ else if (at(pos) == RLO) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 1 + clevel % 2;
+ override = QChar::DirR;
+ }
+ else if (at(pos) == LRO) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 2 - clevel % 2;
+ override = QChar::DirL;
+ }
+ else if (at(pos) == PDF) {
+ //code_count++;
+ if (!stack.isEmpty()) {
+ override = stack.top()->override;
+ clevel = stack.top()->level;
+ stack.remove();
+ }
+ }
+
+ // TODO: catch block separators (newlines, paras, etc.)
+
+ level[pos] = clevel;
+ if (override != -1)
+ dir[pos] = (QChar::Direction) override;
+ else
+ dir[pos] = at(pos).direction();
+ }
+
+ // weak type pass
+ for (pos = 0; pos < l; pos++) {
+
+ int i;
+
+ switch (at(pos).direction()) {
+ case QChar::DirEN:
+ i = pos-1;
+ while ((i >= 0) &&
+ !(at(i).direction() == QChar::DirAN) &&
+ !(at(i).direction() == QChar::DirAL) &&
+ !(at(i).direction() == QChar::DirB))
+ i--;
+
+ if ((i >= 0) &&
+ ((at(i).direction() == QChar::DirAN) ||
+ (at(i).direction() == QChar::DirAL)))
+ dir[pos] = QChar::DirAN;
+
+ break;
+ case QChar::DirES:
+ case QChar::DirCS:
+ if ((pos > 0) && (pos < l-1) &&
+ (dir[pos-1] == dir[pos+1]))
+ dir[pos] = dir[pos-1];
+ else
+ dir[pos] = QChar::DirON;
+
+ break;
+ case QChar::DirET:
+ if (((pos > 0) && (dir[pos-1] == QChar::DirEN)) ||
+ ((pos < l-1) && (dir[pos+1] == QChar::DirEN)))
+ dir[pos] = QChar::DirEN;
+ else
+ dir[pos] = QChar::DirON;
+
+ break;
+ case QChar::DirAL:
+ dir[pos] = QChar::DirR;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // neutral type pass
+ for (pos = 0; pos < l; pos++) {
+ QChar::Direction left,right; // declaring l here shadowed previous l
+
+ if (is_neutral(dir[pos])) {
+ if (pos > 0)
+ left = dir[pos-1];
+ else
+ left = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ int i = pos;
+
+ while ((i < (int)l-1) && is_neutral(dir[i+1]))
+ i++;
+
+ if (i < (int)l-1)
+ right = dir[i+1];
+ else
+ right = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ for (int j=pos; j <= i; j++) {
+ int a = 1, b = 1;
+ while ((a < 5) && (left != resolv[0][a]))
+ a++;
+ while ((b < 5) && (right != resolv[0][b]))
+ b++;
+ if ((a == 5) || (b == 5))
+ dir[j] = (base == 0 ? QChar::DirL : QChar::DirR);
+ else
+ dir[j] = resolv[a][b];
+
+ if (dir[j] == (QChar::Direction)(-1))
+ dir[j] = (base == 0 ? QChar::DirL : QChar::DirR);
+ }
+ }
+ }
+
+ // implicit level pass
+ QChar::Direction prec = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ for (pos = 0; pos < l; pos++) {
+ if (level[pos] % 2) {
+ switch (dir[pos]) {
+ case QChar::DirL:
+ case QChar::DirAN:
+ case QChar::DirEN:
+ level[pos] += 1;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (dir[pos]) {
+ case QChar::DirL:
+ // do nothing
+ break;
+ case QChar::DirR:
+ level[pos] += 1;
+ break;
+ case QChar::DirEN:
+ if (prec == QChar::DirL)
+ continue;
+ // fall through
+ case QChar::DirAN:
+ level[pos] += 2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ prec = dir[pos];
+ }
+
+ // now do the work!
+ QString ret(*this);
+ reverse(ret, level, index, index+len);
+
+ delete [] level;
+ delete [] dir;
+
+ return ret;
+#else
+ return mid(index,len);
+#endif
+}
+
+
+
+// These macros are used for efficient allocation of QChar strings.
+// IMPORTANT! If you change these, make sure you also change the
+// "delete unicode" statement in ~QStringData() in qstring.h correspondingly!
+
+#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ]
+#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))
+
+
+/*!
+ This utility function converts the 8-bit string
+ \a ba to Unicode, returning the result.
+
+ The caller is responsible for deleting the return value with delete[].
+*/
+
+QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ char* str = ba.data();
+ QChar *uc = new QChar[ l ]; // Can't use macro, since function is public
+ QChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ char* str = ba.data();
+ QChar *uc = QT_ALLOC_QCHAR_VEC( l );
+ QChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+/*!
+ This utility function converts the NUL-terminated 8-bit string
+ \a str to Unicode, returning the result and setting \a len to
+ the length of the Unicode string.
+
+ The caller is responsible for deleting the return value with delete[].
+*/
+
+QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen )
+{
+ QChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = qstrlen(str);
+ }
+ QChar *uc = new QChar[ l ]; // Can't use macro since function is public
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+static QChar* internalAsciiToUnicode( const char *str, uint* len,
+ uint maxlen = (uint)-1 )
+{
+ QChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = qstrlen(str);
+ }
+ QChar *uc = QT_ALLOC_QCHAR_VEC( l );
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+/*!
+ This utility function converts \a l 16-bit characters from
+ \a uc to ASCII, returning a NUL-terminated string.
+
+ The caller is responsible for deleting the string with delete[].
+*/
+char* QString::unicodeToAscii(const QChar *uc, uint l)
+{
+ if (!uc) {
+ return 0;
+ }
+ char *a = new char[l+1];
+ char *result = a;
+ while (l--)
+ *a++ = *uc++;
+ *a = '\0';
+ return result;
+}
+
+static uint computeNewMax( uint len )
+{
+ if (len >= 0x80000000)
+ return len;
+
+ uint newMax = 4;
+ while ( newMax < len )
+ newMax *= 2;
+ // try to save some memory
+ if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
+ newMax -= newMax >> 2;
+ return newMax;
+}
+
+/*!
+ Returns the QString as a zero terminated array of unsigned shorts
+ if the string is not null; otherwise returns zero.
+
+ The result remains valid so long as one unmodified
+ copy of the source string exists.
+ */
+const unsigned short *QString::ucs2() const
+{
+ if ( ! d->unicode )
+ return 0;
+ unsigned int len = d->len;
+ if ( d->maxl < len + 1 ) {
+ // detach, grow or shrink
+ uint newMax = computeNewMax( len + 1 );
+ QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
+ if ( nd ) {
+ if ( d->unicode )
+ memcpy( nd, d->unicode, sizeof(QChar)*len );
+ ((QString *)this)->deref();
+ ((QString *)this)->d = new QStringData( nd, len, newMax );
+ }
+ }
+ d->unicode[len] = 0;
+ return (unsigned short *) d->unicode;
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str, interpreted as a
+ UCS2 encoded, zero terminated, Unicode string.
+
+ If \a str is 0, then a null string is created.
+ \sa isNull()
+ */
+QString QString::fromUcs2( const unsigned short *str )
+{
+ if ( !str ) {
+ return QString::null;
+ } else {
+ int length = 0;
+ while ( str[length] != 0 )
+ length++;
+ QChar* uc = QT_ALLOC_QCHAR_VEC( length );
+ memcpy( uc, str, length*sizeof(QChar) );
+ return QString( new QStringData( uc, length, length ), TRUE );
+ }
+}
+
+
+/*****************************************************************************
+ QString member functions
+ *****************************************************************************/
+
+/*!
+ \class QString qstring.h
+
+ \brief The QString class provides an abstraction of Unicode text and
+ the classic C null-terminated char array (<var>char*</var>).
+
+ \ingroup tools
+ \ingroup shared
+
+ QString uses \link shclass.html implicit sharing\endlink, and so it
+ is very efficient and easy to use.
+
+ In all QString methods that take <var>const char*</var> parameters,
+ the <var>const char*</var> is interpreted as a classic C-style
+ 0-terminated ASCII string. It is legal for the <var>const
+ char*</var> parameter to be 0. The results are undefined if the
+ <var>const char*</var> string is not 0-terminated. Functions that
+ copy classic C strings into a QString will not copy the terminating
+ 0-character. The QChar array of the QString (as returned by
+ unicode()) is not terminated by a null.
+
+ A QString that has not been assigned to anything is \a null, i.e. both
+ the length and data pointer is 0. A QString that references the empty
+ string ("", a single '\0' char) is \a empty. Both null and empty
+ QStrings are legal parameters to the methods. Assigning <var>const char
+ * 0</var> to QString gives a null QString.
+
+ Note that if you find that you are mixing usage of QCString, QString,
+ and QByteArray, this causes lots of unnecessary copying and might
+ indicate that the true nature of the data you are dealing with is
+ uncertain. If the data is NUL-terminated 8-bit data, use QCString;
+ if it is unterminated (ie. contains NULs) 8-bit data, use QByteArray;
+ if it is text, use QString.
+
+ \sa QChar \link shclass.html Shared classes\endlink
+*/
+
+Q_EXPORT QStringData *QString::shared_null = 0;
+//QT_STATIC_CONST_IMPL QString QString::null;
+QT_STATIC_CONST_IMPL QChar QChar::null;
+QT_STATIC_CONST_IMPL QChar QChar::replacement((ushort)0xfffd);
+QT_STATIC_CONST_IMPL QChar QChar::byteOrderMark((ushort)0xfeff);
+QT_STATIC_CONST_IMPL QChar QChar::byteOrderSwapped((ushort)0xfffe);
+QT_STATIC_CONST_IMPL QChar QChar::nbsp((ushort)0x00a0);
+
+#if defined(_CC_MSVC_) && _MSC_VER <= 1300
+const QString::Null QString::null;
+#else
+const QString::Null QString::null = { };
+#endif
+
+
+QStringData* QString::makeSharedNull()
+{
+ return shared_null=new QStringData;
+}
+
+// Uncomment this to get some useful statistics.
+// #define Q2HELPER(x) x
+
+#ifdef Q2HELPER
+static int stat_construct_charstar=0;
+static int stat_construct_charstar_size=0;
+static int stat_construct_null=0;
+static int stat_construct_int=0;
+static int stat_construct_int_size=0;
+static int stat_construct_ba=0;
+static int stat_get_ascii=0;
+static int stat_get_ascii_size=0;
+static int stat_copy_on_write=0;
+static int stat_copy_on_write_size=0;
+static int stat_fast_copy=0;
+Q_EXPORT void qt_qstring_stats()
+{
+ qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size);
+ qDebug("construct_null = %d", stat_construct_null);
+ qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size);
+ qDebug("construct_ba = %d", stat_construct_ba);
+ qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size);
+ qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size);
+ qDebug("fast_copy = %d", stat_fast_copy);
+}
+#else
+#define Q2HELPER(x)
+#endif
+
+/*!
+ \fn QString::QString()
+
+ Constructs a null string.
+ \sa isNull()
+*/
+
+/*!
+ Constructs a string containing the one character \a ch.
+*/
+QString::QString( QChar ch )
+{
+ d = new QStringData( QT_ALLOC_QCHAR_VEC( 1 ), 1, 1 );
+ d->unicode[0] = ch;
+}
+
+/*!
+ Constructs an implicitly-shared copy of \a s.
+*/
+QString::QString( const QString &s ) :
+ d(s.d)
+{
+ Q2HELPER(stat_fast_copy++)
+ d->ref();
+}
+
+/*!
+ Private function.
+
+ Constructs a string with preallocated space for \a size characters.
+
+ The string is empty.
+
+ \sa isNull()
+*/
+
+QString::QString( int size, bool /*dummy*/ )
+{
+ if ( size ) {
+ Q2HELPER(stat_construct_int++)
+ int l = size;
+ Q2HELPER(stat_construct_int_size+=l)
+ QChar* uc = QT_ALLOC_QCHAR_VEC( l );
+ d = new QStringData( uc, 0, l );
+ } else {
+ Q2HELPER(stat_construct_null++)
+ d = shared_null ? shared_null : (shared_null=new QStringData);
+ d->ref();
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a ba interpreted as
+ a classic C string.
+*/
+
+QString::QString( const QByteArray& ba )
+{
+ Q2HELPER(stat_construct_ba++)
+ uint l;
+ QChar *uc = internalAsciiToUnicode(ba,&l);
+ d = new QStringData(uc,l,l);
+}
+
+QString::QString( const QCString& ba )
+{
+ //Q2HELPER(stat_construct_ba++)
+ //uint l;
+ //QChar *uc = internalAsciiToUnicode(ba,&l);
+ //d = new QStringData(uc,l,l);
+ Q2HELPER(stat_fast_copy++)
+ QString s = QString::fromUtf8(ba.data(),ba.length());
+ d = s.d;
+ d->ref();
+}
+
+/*!
+ Constructs a string that is a deep copy of the
+ first \a length QChar in the array \a unicode.
+
+ If \a unicode and \a length are 0, a null string is created.
+
+ If only \a unicode is 0, the string is empty, but has
+ \a length characters of space preallocated - QString expands
+ automatically anyway, but this may speed some cases up a little.
+
+ \sa isNull()
+*/
+
+QString::QString( const QChar* unicode, uint length )
+{
+ if ( !unicode && !length ) {
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ } else {
+ QChar* uc = QT_ALLOC_QCHAR_VEC( length );
+ if ( unicode )
+ memcpy(uc, unicode, length*sizeof(QChar));
+ d = new QStringData(uc,unicode ? length : 0,length);
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str, interpreted as a
+ classic C string.
+
+ If \a str is 0 a null string is created.
+
+ This is a cast constructor, but it is perfectly safe: converting a Latin1
+ const char* to QString preserves all the information.
+ You can disable this constructor by
+ defining QT_NO_CAST_ASCII when you compile your applications.
+ You can also make QString objects by using setLatin1()/fromLatin1(), or
+ fromLocal8Bit(), fromUtf8(), or whatever encoding is appropriate for
+ the 8-bit data you have.
+
+ \sa isNull()
+*/
+
+QString::QString( const char *str )
+{
+ //Q2HELPER(stat_construct_charstar++)
+ //uint l;
+ //QChar *uc = internalAsciiToUnicode(str,&l);
+ //Q2HELPER(stat_construct_charstar_size+=l)
+ //d = new QStringData(uc,l,l);
+ Q2HELPER(stat_fast_copy++)
+ QString s = QString::fromUtf8(str);
+ d = s.d;
+ d->ref();
+}
+
+
+/*! \fn QString::~QString()
+
+Destroys the string and frees the "real" string, if this was the last
+copy of that string.
+*/
+
+
+/*!
+ Deallocates any space reserved solely by this QString.
+*/
+
+void QString::real_detach()
+{
+ setLength( length() );
+}
+
+void QString::deref()
+{
+ if ( d->deref() ) {
+ if ( d == shared_null )
+ shared_null = 0;
+ delete d;
+ d = 0; // helps debugging
+ }
+}
+
+void QStringData::deleteSelf()
+{
+ delete this;
+}
+
+/*!
+ \fn QString& QString::operator=( QChar c )
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ \fn QString& QString::operator=( char c )
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string.
+*/
+QString &QString::operator=( const QString &s )
+{
+ Q2HELPER(stat_fast_copy++)
+ s.d->ref();
+ deref();
+ d = s.d;
+ return *this;
+}
+
+/*!
+ Assigns a deep copy of \a cs, interpreted as a classic C string, to
+ this string and returns a reference to this string.
+*/
+QString &QString::operator=( const QCString& cs )
+{
+ return setLatin1(cs);
+}
+
+
+/*!
+ Assigns a deep copy of \a str, interpreted as a classic C string,
+ to this string and returns a reference to this string.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+QString &QString::operator=( const char *str )
+{
+ return setLatin1(str);
+}
+
+
+/*!
+ \fn bool QString::isNull() const
+
+ Returns TRUE if the string is null.
+ A null string is also an empty string.
+
+ Example:
+ \code
+ QString a; // a.unicode() == 0, a.length() == 0
+ QString b = ""; // b.unicode() == "", b.length() == 0
+ a.isNull(); // TRUE, because a.unicode() == 0
+ a.isEmpty(); // TRUE, because a.length() == 0
+ b.isNull(); // FALSE, because b.unicode() != 0
+ b.isEmpty(); // TRUE, because b.length() == 0
+ \endcode
+
+ \sa isEmpty(), length()
+*/
+
+/*!
+ \fn bool QString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0.
+ An empty string is not always a null string.
+
+ See example in isNull().
+
+ \sa isNull(), length()
+*/
+
+/*!
+ \fn uint QString::length() const
+
+ Returns the length of the string.
+
+ Null strings and empty strings have zero length.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ Truncates the string at position \a newLen if newLen is less than the
+ current length . Otherwise, nothing happens.
+
+ Example:
+ \code
+ QString s = "truncate this string";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ In Qt 1.x, it was possible to "truncate" a string to a longer
+ length. This is no longer possible.
+
+*/
+
+void QString::truncate( uint newLen )
+{
+ if ( newLen < d->len )
+ setLength( newLen );
+}
+
+/*### Make this public in 3.0
+ Ensures that at least \a newLen characters are allocated, and
+ sets the length to \a newLen. This function always detaches the
+ string from other references to the same data. Any new space
+ allocated is \e not defined.
+
+ If \a newLen is 0, this string becomes empty, unless this string is
+ null, in which case it remains null.
+
+ \sa truncate(), isNull(), isEmpty()
+*/
+
+void QString::setLength( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl || // detach, grow, or
+ ( newLen*4 < d->maxl && d->maxl > 4 ) ) { // shrink
+ Q2HELPER(stat_copy_on_write++)
+ Q2HELPER(stat_copy_on_write_size+=d->len)
+ uint newMax = 4;
+ while ( newMax < newLen )
+ newMax *= 2;
+ QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
+ uint len = QMIN( d->len, newLen );
+ if ( d->unicode )
+ memcpy( nd, d->unicode, sizeof(QChar)*len );
+ deref();
+ d = new QStringData( nd, newLen, newMax );
+ } else {
+ d->len = newLen;
+ d->dirtyascii = 1;
+ }
+}
+
+/*! Returns a string equal to this one, but with the lowest-numbered
+ occurrence of \c %i (for a positive integer i) replaced by \a a.
+
+ \code
+ label.setText( tr("Rename %1 to %2?").arg(oldName).arg(newName) );
+ \endcode
+
+ \a fieldwidth is the minimum amount of space \a a is padded to. A
+ positive value produces right-aligned text, while a negative value
+ produces left aligned text.
+
+ \warning Using arg() for constructing "real" sentences
+ programmatically is likely to lead to translation problems.
+ Inserting objects like numbers or file names is fairly safe.
+
+ \warning Relying on spaces to create alignment is prone to lead to
+ translation problems.
+
+ If there is no \c %i pattern, a warning message (qWarning()) is
+ printed and the text as appended at the end of the string. This is
+ error recovery and should not occur in correct code.
+
+ \sa QObject::tr()
+*/
+QString QString::arg(const QString& a, int fieldwidth) const
+{
+ int pos, len;
+ QString r = *this;
+
+ if ( !findArg( pos, len ) ) {
+ qWarning( "QString::arg(): Argument missing: %s, %s",
+ (const char *)ascii(), (const char *)ascii() );
+ // Make sure the text at least appears SOMEWHERE
+ r += ' ';
+ pos = r.length();
+ len = 0;
+ }
+
+ r.replace( pos, len, a );
+ if ( fieldwidth < 0 ) {
+ QString s;
+ while ( (uint)-fieldwidth > a.length() ) {
+ s += ' ';
+ fieldwidth++;
+ }
+ r.insert( pos + a.length(), s );
+ } else if ( fieldwidth ) {
+ QString s;
+ while ( (uint)fieldwidth > a.length() ) {
+ s += ' ';
+ fieldwidth--;
+ }
+ r.insert( pos, s );
+ }
+
+ return r;
+}
+
+
+/*! \overload
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+QString QString::arg(long a, int fieldwidth, int base) const
+{
+ return arg( QString::number( a, base ), fieldwidth );
+}
+
+/*! \overload
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+QString QString::arg(ulong a, int fieldwidth, int base) const
+{
+ return arg( QString::number( a, base ), fieldwidth );
+}
+
+/*!
+ \overload QString QString::arg(int a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+
+*/
+
+/*!
+ \overload QString QString::arg(uint a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+/*!
+ \overload QString QString::arg(short a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+/*!
+ \overload QString QString::arg(ushort a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+
+/*! \overload
+
+ \a a is assumed to be in the Latin1 character set.
+*/
+QString QString::arg(char a, int fieldwidth) const
+{
+ QString c;
+ c += a;
+ return arg( c, fieldwidth );
+}
+
+/*! \overload
+*/
+QString QString::arg(QChar a, int fieldwidth) const
+{
+ QString c;
+ c += a;
+ return arg( c, fieldwidth );
+}
+
+/*! \overload
+
+ \a is formatted according to the \a fmt format specified, which is
+ 'g' by default and can be any of 'f', 'F', 'e', 'E', 'g' or 'G', all
+ of which have the same meaning as for sprintf(). \a prec determines
+ the precision, just as for number() and sprintf().
+*/
+QString QString::arg(double a, int fieldwidth, char fmt, int prec) const
+{
+ return arg( QString::number( a, fmt, prec ), fieldwidth );
+}
+
+
+/*!
+ Just 1-digit arguments.
+*/
+bool QString::findArg(int& pos, int& len) const
+{
+ char lowest=0;
+ for (uint i=0; i<length(); i++) {
+ if ( at(i) == '%' && i+1<length() ) {
+ char dig = at(i+1);
+ if ( dig >= '0' && dig <= '9' ) {
+ if ( !lowest || dig < lowest ) {
+ lowest = dig;
+ pos = i;
+ len = 2;
+ }
+ }
+ }
+ }
+ return lowest != 0;
+}
+
+/*!
+ Safely builds a formatted string from a format string and an
+ arbitrary list of arguments. The format string supports all
+ the escape sequences of printf() in the standard C library.
+
+ The %s escape sequence expects a utf8() encoded string.
+ The format string \e cformat is expected to be in latin1. If you need a unicode
+ format string, use QString::arg() instead. For typesafe
+ string building, with full Unicode support, you can use QTextOStream
+ like this:
+
+ \code
+ QString str;
+ QString s = ...;
+ int x = ...;
+ QTextOStream(&str) << s << " : " << x;
+ \endcode
+
+ For \link QObject::tr() translations,\endlink especially if the
+ strings contains more than one escape sequence, you should consider
+ using the arg() function instead. This allows the order of the
+ replacements to be controlled by the translator, and has Unicode
+ support.
+
+ \sa arg()
+*/
+
+QString &QString::sprintf( const char* cformat, ... )
+{
+ va_list ap;
+ va_start( ap, cformat );
+
+ if ( !cformat || !*cformat ) {
+ // Qt 1.x compat
+ *this = QString::fromLatin1( "" );
+ return *this;
+ }
+ QString format = QString::fromLatin1( cformat );
+
+ static QRegExp *escape = 0;
+ if (!escape)
+ escape = new QRegExp( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" );
+
+ QString result;
+ uint last = 0;
+
+ int len = 0;
+ int pos;
+ while ( 1 ) {
+ pos = escape->match( cformat, last, &len );
+ // Non-escaped text
+ if ( pos > (int)last )
+ result += format.mid(last,pos-last);
+ if ( pos < 0 ) {
+ // The rest
+ if ( last < format.length() )
+ result += format.mid(last);
+ break;
+ }
+ last = pos + len + 1;
+
+ // Escape
+ QString f = format.mid( pos, len );
+ uint width, decimals;
+ int params = 0;
+ int wpos = f.find('*');
+ if ( wpos >= 0 ) {
+ params++;
+ width = va_arg( ap, int );
+ if ( f.find('*', wpos + 1) >= 0 ) {
+ decimals = va_arg( ap, int );
+ params++;
+ } else {
+ decimals = 0;
+ }
+ } else {
+ decimals = width = 0;
+ }
+ QString replacement;
+ if ( format[pos+len] == 's' ||
+ format[pos+len] == 'S' ||
+ format[pos+len] == 'c' )
+ {
+ bool rightjust = ( f.find('-') < 0 );
+ // Yes, %-5s really means left adjust in sprintf
+
+ if ( wpos < 0 ) {
+ QRegExp num( "[0-9]+" );
+ QRegExp dot( "\\." );
+ int nlen;
+ int p = num.match( f.data(), 0, &nlen );
+ int q = dot.match( f.data(), 0 );
+ if ( q < 0 || (p < q && p >= 0) )
+ width = f.mid( p, nlen ).toInt();
+ if ( q >= 0 ) {
+ p = num.match( f.data(), q );
+ // "decimals" is used to specify string truncation
+ if ( p >= 0 )
+ decimals = f.mid( p, nlen ).toInt();
+ }
+ }
+
+ if ( format[pos+len] == 's' ) {
+#ifndef QT_NO_TEXTCODEC
+ QString s = QString::fromUtf8(va_arg(ap, char*));
+#else
+ QString s = QString::fromLatin1(va_arg(ap, char*));
+#endif
+ if ( decimals <= 0 )
+ replacement = s;
+ else
+ replacement = s.left(decimals);
+ } else {
+ int ch = va_arg(ap, int);
+ replacement = QChar((ushort)ch);
+ }
+ if ( replacement.length() < width ) {
+ replacement = rightjust
+ ? replacement.rightJustify(width)
+ : replacement.leftJustify(width);
+ }
+ } else if ( format[pos+len] == '%' ) {
+ replacement = '%';
+ } else if ( format[pos+len] == 'n' ) {
+ int* n = va_arg(ap, int*);
+ *n = result.length();
+ } else {
+ char in[64], out[330] = "";
+ strncpy(in,f.latin1(),63);
+ char fch = format[pos+len].latin1();
+ in[f.length()] = fch;
+ switch ( fch ) {
+ case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
+ int value = va_arg(ap, int);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ case 'e': case 'E': case 'f': case 'g': case 'G': {
+ double value = va_arg(ap, double);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ case 'p': {
+ void* value = va_arg(ap, void*);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ }
+ replacement = QString::fromLatin1(out);
+ }
+ result += replacement;
+ }
+ *this = result;
+
+ va_end( ap );
+ return *this;
+}
+
+/*!
+ Fills the string with \a len characters of value \a c.
+
+ If \a len is negative, the current string length is used.
+*/
+
+void QString::fill( QChar c, int len )
+{
+ if ( len < 0 )
+ len = length();
+ if ( len == 0 ) {
+ *this = "";
+ } else {
+ deref();
+ QChar * nd = QT_ALLOC_QCHAR_VEC( len );
+ d = new QStringData(nd,len,len);
+ while (len--) *nd++ = c;
+ }
+}
+
+
+/*!
+ \fn QString QString::copy() const
+
+ \obsolete
+
+ Returns a deep copy of this string.
+
+ Doing this is redundant in Qt 2.x, since QString is implicitly
+ shared, and so will automatically be deeply copied as necessary.
+*/
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index. If \a index is -1, the search starts at the
+ last character; if -2, at the next to last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+*/
+
+int QString::find( QChar c, int index, bool cs ) const
+{
+ if ( index < 0 )
+ index += length();
+ if ( (uint)index >= length() ) // index outside string
+ return -1;
+ register const QChar *uc;
+ uc = unicode()+index;
+ int n = length()-index;
+ if ( cs ) {
+ while ( n-- && *uc != c )
+ uc++;
+ } else {
+ c = c.lower();
+ while ( n-- && uc->lower() != c )
+ uc++;
+ }
+ if ( uint(uc - unicode()) >= length() )
+ return -1;
+ return (int)(uc - unicode());
+}
+
+/*!
+ Finds the first occurrence of the string \a str, starting at position
+ \a index. If \a index is -1, the search starts at the last character;
+ if -2, at the next to last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if
+ \a cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be found.
+*/
+
+int QString::find( const QString& str, int index, bool cs ) const
+{
+ /*
+ We use some weird hashing for efficiency's sake. Instead of
+ comparing strings, we compare the hash value of str with that of
+ a part of this QString. Only if that matches, we call ucstrncmp
+ or ucstrnicmp.
+
+ The hash value of a string is the sum of the cells of its
+ QChars.
+ */
+ if ( index < 0 )
+ index += length();
+ int lstr = str.length();
+ int lthis = length() - index;
+ if ( (uint)lthis > length() )
+ return -1;
+ int delta = lthis - lstr;
+ if ( delta < 0 )
+ return -1;
+
+ const QChar *uthis = unicode() + index;
+ const QChar *ustr = str.unicode();
+ uint hthis = 0;
+ uint hstr = 0;
+ int i;
+ if ( cs ) {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[i].cell();
+ hstr += ustr[i].cell();
+ }
+ i = 0;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ return index + i;
+ if ( i == delta )
+ return -1;
+ hthis += uthis[i + lstr].cell();
+ hthis -= uthis[i].cell();
+ i++;
+ }
+ } else {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[i].lower().cell();
+ hstr += ustr[i].lower().cell();
+ }
+ i = 0;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ return index + i;
+ if ( i == delta )
+ return -1;
+ hthis += uthis[i + lstr].lower().cell();
+ hthis -= uthis[i].lower().cell();
+ i++;
+ }
+ }
+#if defined(Q_SPURIOUS_NON_VOID_WARNING)
+ return -1;
+#endif
+}
+
+/*!
+ \fn int QString::findRev( const char* str, int index ) const
+
+ Equivalent to findRev(QString(str), index).
+*/
+
+/*!
+ \fn int QString::find( const char* str, int index ) const
+
+ Equivalent to find(QString(str), index).
+*/
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index and searching backwards. If \a index is -1,
+ the search starts at the last character; if -2, at the next to
+ last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if \a
+ cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+*/
+
+int QString::findRev( QChar c, int index, bool cs ) const
+{
+ QString t( c );
+ return findRev( t, index, cs );
+}
+
+/*!
+ Finds the first occurrence of the string \a str, starting at
+ position \a index and searching backwards. If \a index is -1,
+ the search starts at the last character; -2, at the next to last
+ character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be found.
+*/
+
+int QString::findRev( const QString& str, int index, bool cs ) const
+{
+ /*
+ See QString::find() for explanations.
+ */
+ int lthis = length();
+ if ( index < 0 )
+ index += lthis;
+
+ int lstr = str.length();
+ int delta = lthis - lstr;
+ if ( index < 0 || index > lthis || delta < 0 )
+ return -1;
+ if ( index > delta )
+ index = delta;
+
+ const QChar *uthis = unicode();
+ const QChar *ustr = str.unicode();
+ uint hthis = 0;
+ uint hstr = 0;
+ int i;
+ if ( cs ) {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[index + i].cell();
+ hstr += ustr[i].cell();
+ }
+ i = index;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ return i;
+ if ( i == 0 )
+ return -1;
+ i--;
+ hthis -= uthis[i + lstr].cell();
+ hthis += uthis[i].cell();
+ }
+ } else {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[index + i].lower().cell();
+ hstr += ustr[i].lower().cell();
+ }
+ i = index;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ return i;
+ if ( i == 0 )
+ return -1;
+ i--;
+ hthis -= uthis[i + lstr].lower().cell();
+ hthis += uthis[i].lower().cell();
+ }
+ }
+#if defined(Q_SPURIOUS_NON_VOID_WARNING)
+ return -1;
+#endif
+}
+
+
+/*!
+ Returns the number of times the character \a c occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive if \a cs
+ is FALSE.
+*/
+
+int QString::contains( QChar c, bool cs ) const
+{
+ int count = 0;
+ const QChar *uc = unicode();
+ if ( !uc )
+ return 0;
+ int n = length();
+ if ( cs ) { // case sensitive
+ while ( n-- )
+ if ( *uc++ == c )
+ count++;
+ } else { // case insensitive
+ c = c.lower();
+ while ( n-- ) {
+ if ( uc->lower() == c )
+ count++;
+ uc++;
+ }
+ }
+ return count;
+}
+
+/*!
+ \overload
+*/
+int QString::contains( const char* str, bool cs ) const
+{
+ return contains(QString(str),cs);
+}
+
+/*!
+ \overload int QString::contains (char c, bool cs) const
+*/
+
+/*!
+ \overload int QString::find (char c, int index, bool cs) const
+
+*/
+
+/*!
+ \overload int QString::findRev (char c, int index, bool cs) const
+
+*/
+
+/*!
+ Returns the number of times \a str occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ This function counts overlapping substrings, for example, "banana"
+ contains two occurrences of "ana".
+
+ \sa findRev()
+*/
+
+int QString::contains( const QString &str, bool cs ) const
+{
+ int count = 0;
+ const QChar *uc = unicode();
+ if ( !uc )
+ return 0;
+ int len = str.length();
+ int n = length();
+ while ( n-- ) { // counts overlapping strings
+ // ### Doesn't account for length of this - searches over "end"
+ if ( cs ) {
+ if ( ucstrncmp( uc, str.unicode(), len ) == 0 )
+ count++;
+ } else {
+ if ( ucstrnicmp(uc, str.unicode(), len) == 0 )
+ count++;
+ }
+ uc++;
+ }
+ return count;
+}
+
+/*!
+ Returns a substring that contains the \a len leftmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+
+ Example:
+ \code
+ QString s = "Pineapple";
+ QString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid(), isEmpty()
+*/
+
+QString QString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else if ( len > length() ) {
+ return *this;
+ } else {
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode, len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that contains the \a len rightmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ Example:
+ \code
+ QString s = "Pineapple";
+ QString t = s.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid(), isEmpty()
+*/
+
+QString QString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else {
+ uint l = length();
+ if ( len > l )
+ len = l;
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode+(l-len), len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that contains the \a len characters of this
+ string, starting at position \a index.
+
+ Returns a null string if the string is empty or \a index is out
+ of range. Returns the whole string from \a index if \a index+len exceeds
+ the length of the string.
+
+ Example:
+ \code
+ QString s = "Five pineapples";
+ QString t = s.mid( 5, 4 ); // t == "pine"
+ \endcode
+
+ \sa left(), right()
+*/
+
+QString QString::mid( uint index, uint len ) const
+{
+ uint slen = length();
+ if ( isEmpty() || index >= slen ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else {
+ if ( len > slen-index )
+ len = slen - index;
+ if ( index == 0 && len == length() )
+ return *this;
+ register const QChar *p = unicode()+index;
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, p, len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string of length \a width that contains this
+ string and padded by the \a fill character.
+
+ If the length of the string exceeds \a width and \a truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \a width and \a truncate is TRUE,
+ then the returned string is a left(\a width).
+
+ Example:
+ \code
+ QString s("apple");
+ QString t = s.leftJustify(8, '.'); // t == "apple..."
+ \endcode
+
+ \sa rightJustify()
+*/
+
+QString QString::leftJustify( uint width, QChar fill, bool truncate ) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength(len+padlen);
+ if ( len )
+ memcpy( result.d->unicode, unicode(), sizeof(QChar)*len );
+ QChar* uc = result.d->unicode + len;
+ while (padlen--)
+ *uc++ = fill;
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \a width that contains pad
+ characters followed by the string.
+
+ If the length of the string exceeds \a width and \a truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \a width and \a truncate is TRUE,
+ then the returned string is a left(\a width).
+
+ Example:
+ \code
+ QString s("pie");
+ QString t = s.rightJustify(8, '.'); // t == ".....pie"
+ \endcode
+
+ \sa leftJustify()
+*/
+
+QString QString::rightJustify( uint width, QChar fill, bool truncate ) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength( len+padlen );
+ QChar* uc = result.d->unicode;
+ while (padlen--)
+ *uc++ = fill;
+ if ( len )
+ memcpy( uc, unicode(), sizeof(QChar)*len );
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a new string that is the string converted to lower case.
+
+ Example:
+ \code
+ QString s("TeX");
+ QString t = s.lower(); // t == "tex"
+ \endcode
+
+ \sa upper()
+*/
+
+QString QString::lower() const
+{
+ QString s(*this);
+ int l=length();
+ if ( l ) {
+ s.real_detach(); // could do this only when we find a change
+ register QChar *p=s.d->unicode;
+ if ( p ) {
+ while ( l-- ) {
+ *p = p->lower();
+ p++;
+ }
+ }
+ }
+ return s;
+}
+
+/*!
+ Returns a new string that is the string converted to upper case.
+
+ Example:
+ \code
+ QString s("TeX");
+ QString t = s.upper(); // t == "TEX"
+ \endcode
+
+ \sa lower()
+*/
+
+QString QString::upper() const
+{
+ QString s(*this);
+ int l=length();
+ if ( l ) {
+ s.real_detach(); // could do this only when we find a change
+ register QChar *p=s.d->unicode;
+ if ( p ) {
+ while ( l-- ) {
+ *p = p->upper();
+ p++;
+ }
+ }
+ }
+ return s;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end.
+
+ White space means any character for which QChar::isSpace() returns
+ TRUE. This includes ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12
+ (FF), 13 (CR), and 32 (Space).
+
+ Example:
+ \code
+ QString s = " space ";
+ QString t = s.stripWhiteSpace(); // t == "space"
+ \endcode
+
+ \sa simplifyWhiteSpace()
+*/
+
+QString QString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+ if ( !at(0).isSpace() && !at(length()-1).isSpace() )
+ return *this;
+
+ register const QChar *s = unicode();
+ QString result = fromLatin1("");
+
+ int start = 0;
+ int end = length() - 1;
+ while ( start<=end && s[start].isSpace() ) // skip white space from start
+ start++;
+ if ( start > end ) { // only white space
+ return result;
+ }
+ while ( end && s[end].isSpace() ) // skip white space from end
+ end--;
+ int l = end - start + 1;
+ result.setLength( l );
+ if ( l )
+ memcpy( result.d->unicode, &s[start], sizeof(QChar)*l );
+ return result;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end,
+ plus any sequence of internal white space replaced with a single space
+ (ASCII 32).
+
+ White space means any character for which QChar::isSpace() returns
+ TRUE. This includes ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12
+ (FF), 13 (CR), and 32 (Space).
+
+ \code
+ QString s = " lots\t of\nwhite space ";
+ QString t = s.simplifyWhiteSpace(); // t == "lots of white space"
+ \endcode
+
+ \sa stripWhiteSpace()
+*/
+
+QString QString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+ QString result;
+ result.setLength( length() );
+ const QChar *from = unicode();
+ const QChar *fromend = from+length();
+ int outc=0;
+ QChar *to = result.d->unicode;
+ while ( TRUE ) {
+ while ( from!=fromend && from->isSpace() )
+ from++;
+ while ( from!=fromend && !from->isSpace() )
+ to[outc++] = *from++;
+ if ( from!=fromend )
+ to[outc++] = ' ';
+ else
+ break;
+ }
+ if ( outc > 0 && to[outc-1] == ' ' )
+ outc--;
+ result.truncate( outc );
+ return result;
+}
+
+
+/*!
+ Insert \a s into the string before position \a index.
+
+ If \a index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \a index and \a s is then appended.
+
+ \code
+ QString s = "I like fish";
+ s.insert( 2, "don't "); // s == "I don't like fish"
+ s = "x";
+ s.insert( 3, "yz" ); // s == "x yz"
+ \endcode
+*/
+
+QString &QString::insert( uint index, const QString &s )
+{
+ // the sub function takes care of &s == this case.
+ return insert( index, s.unicode(), s.length() );
+}
+
+/*!
+ Insert \a len units of QChar data from \a s into the string before
+ position \a index.
+*/
+
+QString &QString::insert( uint index, const QChar* s, uint len )
+{
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+
+ int df = (int)(s - d->unicode); // ### pointer subtraction, cast down to int
+ if ( df >= 0 && (uint)df < d->maxl ) {
+ // Part of me - take a copy.
+ QChar *tmp = QT_ALLOC_QCHAR_VEC( len );
+ memcpy(tmp,s,len*sizeof(QChar));
+ insert(index,tmp,len);
+ QT_DELETE_QCHAR_VEC( tmp );
+ return *this;
+ }
+
+ if ( index >= olen ) { // insert after end of string
+ setLength( len+index );
+ int n = index-olen;
+ QChar* uc = d->unicode+olen;
+ while (n--)
+ *uc++ = ' ';
+ memcpy( d->unicode+index, s, sizeof(QChar)*len );
+ } else { // normal insert
+ setLength( nlen );
+ memmove( d->unicode+index+len, unicode()+index,
+ sizeof(QChar)*(olen-index) );
+ memcpy( d->unicode+index, s, sizeof(QChar)*len );
+ }
+ return *this;
+}
+
+/*!
+ Insert \a c into the string at (before) position \a index and returns
+ a reference to the string.
+
+ If \a index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \a index and \a c is then appended.
+
+ Example:
+ \code
+ QString s = "Ys";
+ s.insert( 1, 'e' ); // s == "Yes"
+ s.insert( 3, '!'); // s == "Yes!"
+ \endcode
+
+ \sa remove(), replace()
+*/
+
+QString &QString::insert( uint index, QChar c ) // insert char
+{
+ QString s( c );
+ return insert( index, s );
+}
+
+/*!
+ \overload QString& QString::insert( uint index, char c )
+*/
+
+/*!
+ \fn QString &QString::prepend( const QString &s )
+
+ Prepend \a s to the string. Equivalent to insert(0,s).
+
+ \sa insert()
+*/
+
+/*!
+ \fn QString& QString::prepend( char ch )
+ Prepends \a ch to the string and returns a reference to the result.
+
+ \sa insert()
+ */
+
+/*!
+ \fn QString& QString::prepend( QChar ch )
+ Prepends \a ch to the string and returns a reference to the result.
+
+ \sa insert()
+ */
+
+
+/*!
+ Removes \a len characters starting at position \a index from the
+ string and returns a reference to the string.
+
+ If \a index is too big, nothing happens. If \a index is valid, but
+ \a len is too large, the rest of the string is removed.
+
+ \code
+ QString s = "Montreal";
+ s.remove( 1, 4 );
+ // s == "Meal"
+ \endcode
+
+ \sa insert(), replace()
+*/
+
+QString &QString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) { // range problems
+ if ( index < olen ) { // index ok
+ setLength( index );
+ }
+ } else if ( len != 0 ) {
+ real_detach();
+ memmove( d->unicode+index, d->unicode+index+len,
+ sizeof(QChar)*(olen-index-len) );
+ setLength( olen-len );
+ }
+ return *this;
+}
+
+/*!
+ Replaces \a len characters starting at position \a index from the
+ string with \a s, and returns a reference to the string.
+
+ If \a index is too big, nothing is deleted and \a s is inserted at the
+ end of the string. If \a index is valid, but \a len is too large, \e
+ str replaces the rest of the string.
+
+ \code
+ QString s = "Say yes!";
+ s.replace( 4, 3, "NO" ); // s == "Say NO!"
+ \endcode
+
+ \sa insert(), remove()
+*/
+
+QString &QString::replace( uint index, uint len, const QString &s )
+{
+ return replace( index, len, s.unicode(), s.length() );
+}
+
+
+/*!
+ Replaces \a len characters starting at position \a index by
+ \a slen units ot QChar data from \a s, and returns a reference to the string.
+
+ \sa insert(), remove()
+*/
+
+QString &QString::replace( uint index, uint len, const QChar* s, uint slen )
+{
+ if ( len == slen && index + len <= length() ) {
+ // Optimized common case: replace without size change
+ real_detach();
+ memcpy( d->unicode+index, s, len*sizeof(QChar) );
+ } else {
+ int df = (int)(s - d->unicode); // ### pointer subtraction, cast down to int
+ if ( df >= 0 && (uint)df < d->maxl ) {
+ // Part of me - take a copy.
+ QChar *tmp = QT_ALLOC_QCHAR_VEC( slen );
+ memcpy(tmp,s,slen*sizeof(QChar));
+ replace(index,len,tmp,slen);
+ QT_DELETE_QCHAR_VEC( tmp );
+ return *this;
+ }
+
+ remove( index, len );
+ insert( index, s, slen );
+ }
+ return *this;
+}
+
+
+
+/*!
+ Finds the first occurrence of the regular expression \a rx, starting at
+ position \a index. If \a index is -1, the search starts at the last
+ character; if -2, at the next to last character; etc.
+
+ Returns the position of the next match, or -1 if \a rx was not found.
+
+ \sa findRev() replace() contains()
+*/
+
+int QString::find( const QRegExp &rx, int index ) const
+{
+ if ( index < 0 )
+ index += length();
+ return rx.match( data(), index );
+}
+
+/*!
+ Finds the first occurrence of the regular expression \a rx, starting at
+ position \a index and searching backwards. If \a index is -1, the
+ search starts at the last character; if -2, at the next to last
+ character; etc.
+
+ Returns the position of the next match (backwards), or -1 if \a rx was not
+ found.
+
+ \sa find()
+*/
+
+int QString::findRev( const QRegExp &rx, int index ) const
+{
+ if ( index < 0 ) // neg index ==> start from end
+ index += length();
+ if ( (uint)index > length() ) // bad index
+ return -1;
+ while( index >= 0 ) {
+ if ( rx.match( data(), index ) == index )
+ return index;
+ index--;
+ }
+ return -1;
+}
+
+/*!
+ Counts the number of overlapping occurrences of \a rx in the string.
+
+ Example:
+ \code
+ QString s = "banana and panama";
+ QRegExp r = QRegExp("a[nm]a", TRUE, FALSE);
+ s.contains( r ); // 4 matches
+ \endcode
+
+ \sa find() findRev()
+*/
+
+int QString::contains( const QRegExp &rx ) const
+{
+ if ( isEmpty() )
+ return rx.match( data() ) < 0 ? 0 : 1;
+ int count = 0;
+ int index = -1;
+ int len = length();
+ while ( index < len-1 ) { // count overlapping matches
+ index = rx.match( data(), index+1 );
+ if ( index < 0 )
+ break;
+ count++;
+ }
+ return count;
+}
+
+
+/*!
+ Replaces every occurrence of \a rx in the string with \a str.
+ Returns a reference to the string.
+
+ Examples:
+ \code
+ QString s = "banana";
+ s.replace( QRegExp("a.*a"), "" ); // becomes "b"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), " " ); // becomes " nana"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), "" ); // NOTE! becomes ""
+ \endcode
+
+ \sa find() findRev()
+*/
+
+QString &QString::replace( const QRegExp &rx, const QString &str )
+{
+ if ( isEmpty() )
+ return *this;
+ int index = 0;
+ int slen = str.length();
+ int len;
+ while ( index < (int)length() ) {
+ index = rx.match( data(), index, &len, FALSE );
+ if ( index >= 0 ) {
+ replace( index, len, str );
+ index += slen;
+ if ( !len )
+ break; // Avoid infinite loop on 0-length matches, e.g. [a-z]*
+ }
+ else
+ break;
+ }
+ return *this;
+}
+
+static bool
+ok_in_base( QChar c, int base )
+{
+ if ( base <= 10 )
+ return c.isDigit() && c.digitValue() < base;
+ else
+ return c.isDigit() || (c >= 'a' && c < char('a'+base-10))
+ || (c >= 'A' && c < char('A'+base-10));
+}
+
+/*!
+ Returns the string converted to a <code>long</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+long QString::toLong( bool *ok, int base ) const
+{
+ const QChar *p = unicode();
+ long val=0;
+ int l = length();
+ const long max_mult = INT_MAX / base;
+ bool is_ok = FALSE;
+ int neg = 0;
+ if ( !p )
+ goto bye;
+ while ( l && p->isSpace() ) // skip leading space
+ l--,p++;
+ if ( l && *p == '-' ) {
+ l--;
+ p++;
+ neg = 1;
+ } else if ( *p == '+' ) {
+ l--;
+ p++;
+ }
+
+ // NOTE: toULong() code is similar
+ if ( !l || !ok_in_base(*p,base) )
+ goto bye;
+ while ( l && ok_in_base(*p,base) ) {
+ l--;
+ int dv;
+ if ( p->isDigit() ) {
+ dv = p->digitValue();
+ } else {
+ if ( *p >= 'a' && *p <= 'z' )
+ dv = *p - 'a' + 10;
+ else
+ dv = *p - 'A' + 10;
+ }
+ if ( val > max_mult || (val == max_mult && dv > (INT_MAX%base)+neg) )
+ goto bye;
+ val = base*val + dv;
+ p++;
+ }
+ if ( neg )
+ val = -val;
+ while ( l && p->isSpace() ) // skip trailing space
+ l--,p++;
+ if ( !l )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned long</code>
+ value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+ulong QString::toULong( bool *ok, int base ) const
+{
+ const QChar *p = unicode();
+ ulong val=0;
+ int l = length();
+ const ulong max_mult = 429496729; // UINT_MAX/10, rounded down
+ bool is_ok = FALSE;
+ if ( !p )
+ goto bye;
+ while ( l && p->isSpace() ) // skip leading space
+ l--,p++;
+ if ( *p == '+' )
+ l--,p++;
+
+ // NOTE: toLong() code is similar
+ if ( !l || !ok_in_base(*p,base) )
+ goto bye;
+ while ( l && ok_in_base(*p,base) ) {
+ l--;
+ uint dv;
+ if ( p->isDigit() ) {
+ dv = p->digitValue();
+ } else {
+ if ( *p >= 'a' && *p <= 'z' )
+ dv = *p - 'a' + 10;
+ else
+ dv = *p - 'A' + 10;
+ }
+ if ( val > max_mult || (val == max_mult && dv > (UINT_MAX%base)) )
+ goto bye;
+ val = base*val + dv;
+ p++;
+ }
+
+ while ( l && p->isSpace() ) // skip trailing space
+ l--,p++;
+ if ( !l )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to a <code>short</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+short QString::toShort( bool *ok, int base ) const
+{
+ long v = toLong( ok, base );
+ if ( ok && *ok && (v < -32768 || v > 32767) ) {
+ *ok = FALSE;
+ v = 0;
+ }
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned short</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+ushort QString::toUShort( bool *ok, int base ) const
+{
+ ulong v = toULong( ok, base );
+ if ( ok && *ok && (v > 65535) ) {
+ *ok = FALSE;
+ v = 0;
+ }
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a <code>int</code> value.
+
+ \code
+ QString str("FF");
+ bool ok;
+ int hex = str.toInt( &ok, 16 ); // will return 255, and ok set to TRUE
+ int dec = str.toInt( &ok, 10 ); // will return 0, and ok set to FALSE
+ \endcode
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+int QString::toInt( bool *ok, int base ) const
+{
+ return (int)toLong( ok, base );
+}
+
+/*!
+ Returns the string converted to an <code>unsigned int</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+uint QString::toUInt( bool *ok, int base ) const
+{
+ return (uint)toULong( ok, base );
+}
+
+/*!
+ Returns the string converted to a <code>double</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no conceivable
+ errors, and FALSE if the string is not a number at all, or if it has
+ trailing garbage.
+*/
+
+double QString::toDouble( bool *ok ) const
+{
+ char *end;
+
+ QCString a = latin1();
+ // Just latin1() is not sufficient, since U0131 would look like '1'.
+ for (uint i=0; i<d->len; i++)
+ if ( d->unicode[i].row() )
+ a[(int)i]='z';
+
+ double val = strtod( a.data() ? a.data() : "", &end );
+ if ( ok )
+ *ok = ( a && *a && ( end == 0 || *end == '\0' ) );
+ return val;
+}
+
+/*!
+ Returns the string converted to a <code>float</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+float QString::toFloat( bool *ok ) const
+{
+ return (float)toDouble( ok );
+}
+
+
+/*!
+ Sets the string to the printed value of \a n and returns a
+ reference to the string.
+
+ The value is converted to \a base notation (default is decimal).
+ The base must be a value from 2 to 36.
+*/
+
+QString &QString::setNum( long n, int base )
+{
+#if defined(CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "QString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ char charbuf[65*sizeof(QChar)];
+ QChar *buf = (QChar*)charbuf;
+ QChar *p = &buf[64];
+ int len = 0;
+ bool neg;
+ if ( n < 0 ) {
+ neg = TRUE;
+ if ( n == INT_MIN ) {
+ // Cannot always negate this special case
+ QString s1, s2;
+ s1.setNum(n/base);
+ s2.setNum((-(n+base))%base);
+ *this = s1 + s2;
+ return *this;
+ }
+ n = -n;
+ } else {
+ neg = FALSE;
+ }
+ do {
+ *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
+ n /= base;
+ len++;
+ } while ( n );
+ if ( neg ) {
+ *--p = '-';
+ len++;
+ }
+ return setUnicode( p, len );
+}
+
+/*!
+ Sets the string to the printed unsigned value of \a n and
+ returns a reference to the string.
+
+ The value is converted to \a base notation (default is decimal).
+ The base must be a value from 2 to 36.
+*/
+
+QString &QString::setNum( ulong n, int base )
+{
+#if defined(CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "QString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ char charbuf[65*sizeof(QChar)];
+ QChar *buf = (QChar*)charbuf;
+ QChar *p = &buf[64];
+ int len = 0;
+ do {
+ *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
+ n /= base;
+ len++;
+ } while ( n );
+ return setUnicode(p,len);
+}
+
+/*!
+ \fn QString &QString::setNum( int n, int base )
+ Sets the string to the printed value of \a n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( uint n, int base )
+ Sets the string to the printed unsigned value of \a n and returns a
+ reference to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( short n, int base )
+ Sets the string to the printed value of \a n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( ushort n, int base )
+ Sets the string to the printed unsigned value of \a n and returns a
+ reference to the string.
+*/
+
+/*! Sets the string to the printed value of \a n, formatted in the \a f
+ format with \a prec precision, and returns a reference to the
+ string.
+
+ \a f can be 'f', 'F', 'e', 'E', 'g' or 'G', all of which have the
+ same meaning as for sprintf().
+*/
+
+QString &QString::setNum( double n, char f, int prec )
+{
+#if defined(CHECK_RANGE)
+ if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') ) {
+ qWarning( "QString::setNum: Invalid format char '%c'", f );
+ f = 'f';
+ }
+#endif
+ char format[20];
+ char buf[120]; // enough for 99 precision?
+ char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f>"
+ if ( prec >= 0 ) {
+ if ( prec > 99 ) // buf big enough for precision?
+ prec = 99;
+ *fs++ = '.';
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ }
+ *fs++ = 'l';
+ *fs++ = f;
+ *fs = '\0';
+ ::sprintf( buf, format, n );
+ return setLatin1(buf);
+}
+
+/*!
+ \overload QString &QString::setNum( float n, char f, int prec )
+*/
+
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( long n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( ulong n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( int n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( uint n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ This static function returns the printed value of \a n, formatted in the
+ \a f format with \a prec precision.
+
+ \a f can be 'f', 'F', 'e', 'E', 'g' or 'G', all of which have the
+ same meaning as for sprintf().
+
+ \sa setNum()
+ */
+QString QString::number( double n, char f, int prec )
+{
+ QString s;
+ s.setNum( n, f, prec );
+ return s;
+}
+
+
+/*! \obsolete
+
+ Sets the character at position \a index to \a c and expands the
+ string if necessary, filling with spaces.
+
+ This method is redundant in Qt 2.x, because operator[] will expand
+ the string as necessary.
+*/
+
+void QString::setExpand( uint index, QChar c )
+{
+ int spaces = index - d->len;
+ at(index) = c;
+ while (spaces-->0)
+ d->unicode[--index]=' ';
+}
+
+
+/*!
+ \fn const char* QString::data() const
+
+ \obsolete
+
+ Returns a pointer to a 0-terminated classic C string.
+
+ In Qt 1.x, this returned a char* allowing direct manipulation of the
+ string as a sequence of bytes. In Qt 2.x where QString is a Unicode
+ string, char* conversion constructs a temporary string, and hence
+ direct character operations are meaningless.
+*/
+
+/*!
+ \fn bool QString::operator!() const
+ Returns TRUE if it is a null string, otherwise FALSE. Thus
+ you can write:
+
+\code
+ QString name = getName();
+ if ( !name )
+ name = "Rodney";
+\endcode
+
+ Note that if you say:
+
+\code
+ QString name = getName();
+ if ( name )
+ doSomethingWith(name);
+\endcode
+
+ Then this will call <tt>operator const char*()</tt>, which will do what
+ you want, but rather inefficiently - you may wish to define the macro
+ QT_NO_ASCII_CAST when writing code which you wish to strictly remain
+ Unicode-clean.
+
+ When you want the above semantics, use <tt>!isNull()</tt>
+ or even <tt>!!</tt>:
+
+\code
+ QString name = getName();
+ if ( !!name )
+ doSomethingWith(name);
+\endcode
+*/
+
+
+/*!
+ \fn QString& QString::append( const QString& str )
+ Appends \a str to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ \fn QString& QString::append( char ch )
+ Appends \a ch to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ \fn QString& QString::append( QChar ch )
+ Appends \a ch to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ Appends \a str to the string and returns a reference to the string.
+*/
+QString& QString::operator+=( const QString &str )
+{
+ uint len1 = length();
+ uint len2 = str.length();
+ if ( len2 ) {
+ setLength(len1+len2);
+ memcpy( d->unicode+len1, str.unicode(), sizeof(QChar)*len2 );
+ } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
+ *this = fromLatin1("");
+ }
+ return *this;
+}
+
+/*!
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+QString &QString::operator+=( QChar c )
+{
+ setLength(length()+1);
+ d->unicode[length()-1] = c;
+ return *this;
+}
+
+/*!
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+QString &QString::operator+=( char c )
+{
+ setLength(length()+1);
+ d->unicode[length()-1] = c;
+ return *this;
+}
+
+
+
+/*! \fn char QChar::latin1() const
+
+ Returns a latin-1 copy of this character, if this character is in
+ the latin-1 character set. If not, this function returns 0.
+*/
+
+
+/*!
+ Returns a Latin-1 representation of the string. Note that the returned
+ value is undefined if the string contains non-Latin-1 characters. If you
+ want to convert strings into formats other than Unicode, see the
+ QTextCodec classes.
+
+ This function is mainly useful for boot-strapping legacy code to
+ use Unicode.
+
+ The result remains valid so long as one unmodified
+ copy of the source string exists.
+
+ \sa utf8(), local8Bit()
+*/
+const char* QString::latin1() const
+{
+ if ( d->ascii ) {
+ if ( d->dirtyascii )
+ delete [] d->ascii;
+ else
+ return d->ascii;
+ }
+ Q2HELPER(stat_get_ascii++)
+ Q2HELPER(stat_get_ascii_size+=d->len)
+ static QTextCodec* codec = QTextCodec::codecForMib(106);
+ if (codec) // we use utf8 coding also for latin1 if possible
+ {
+ QCString utf8str(codec->fromUnicode(*this));
+ d->ascii = new char[utf8str.length()+1];
+ if (utf8str.isEmpty())
+ {
+ d->ascii[0]='\0'; // make empty string
+ }
+ else // copy string
+ {
+ qstrcpy(d->ascii,utf8str.data());
+ }
+ }
+ else // fall back to latin1
+ {
+ d->ascii = unicodeToAscii( d->unicode, d->len );
+ }
+ QCString utf8str(utf8());
+ d->dirtyascii = 0;
+ return d->ascii;
+}
+
+/*! \obsolete
+
+ This functions simply calls latin1() and returns the result.
+*/
+const char* QString::ascii() const
+{
+ return latin1();
+}
+
+#ifndef QT_NO_TEXTCODEC
+/*!
+ Returns the string encoded in UTF8 format.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa QString::fromUtf8(), local8Bit(), latin1()
+*/
+QCString QString::utf8() const
+{
+ static QTextCodec* codec = QTextCodec::codecForMib(106);
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+}
+
+/*!
+ Returns the unicode string decoded from the
+ first \a len bytes of \a utf8. If \a len is -1 (the default), the
+ length of \a utf8 is used. If trailing partial characters are in
+ \a utf8, they are ignored.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+QString QString::fromUtf8(const char* utf8, int len)
+{
+ static QTextCodec* codec = QTextCodec::codecForMib(106);
+ if ( len < 0 ) len = qstrlen(utf8);
+ return codec
+ ? codec->toUnicode(utf8, len)
+ : QString::fromLatin1(utf8, len);
+}
+#endif // QT_NO_TEXTCODEC
+/*!
+ Creates a QString from Latin1 text. This is the same as the
+ QString(const char*) constructor, but you can make that constructor
+ invisible if you compile with the define QT_NO_CAST_ASCII, in which
+ case you can explicitly create a QString from Latin-1 text using
+ this function.
+*/
+QString QString::fromLatin1(const char* chars, int len)
+{
+ uint l;
+ QChar *uc;
+ if ( len < 0 ) {
+ uc = internalAsciiToUnicode(chars,&l);
+ } else {
+ uc = internalAsciiToUnicode(chars,&l,len);
+ }
+ return QString(new QStringData(uc,l,l), TRUE);
+}
+
+/*!
+ \fn const QChar* QString::unicode() const
+
+ Returns the Unicode representation of the string. The result
+ remains valid until the string is modified.
+*/
+
+/*!
+ Returns the string encoded in a locale-specific format. On X11, this
+ is the QTextCodec::codecForLocale(). On Windows, it is a system-defined
+ encoding.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa QString::fromLocal8Bit(), latin1(), utf8()
+*/
+
+
+QCString QString::local8Bit() const
+{
+#ifdef QT_NO_TEXTCODEC
+ return latin1();
+#else
+#ifdef _WS_X11_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+#endif
+#ifdef _WS_MAC_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+#endif
+#ifdef _WS_WIN_
+ return qt_winQString2MB( *this );
+#endif
+#ifdef _WS_QWS_
+ return utf8(); // ##### if there is ANY 8 bit format supported?
+#endif
+#endif
+}
+
+/*!
+ Returns the unicode string decoded from the
+ first \a len bytes of \a local8Bit. If \a len is -1 (the default), the
+ length of \a local8Bit is used. If trailing partial characters are in
+ \a local8Bit, they are ignored.
+
+ \a local8Bit is assumed to be encoded in a locale-specific format.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+QString QString::fromLocal8Bit(const char* local8Bit, int len)
+{
+#ifdef QT_NO_TEXTCODEC
+ return fromLatin1( local8Bit, len );
+#else
+
+ if ( !local8Bit )
+ return QString::null;
+#ifdef _WS_X11_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ if ( len < 0 ) len = qstrlen(local8Bit);
+ return codec
+ ? codec->toUnicode(local8Bit, len)
+ : QString::fromLatin1(local8Bit,len);
+#endif
+#ifdef _WS_MAC_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ if ( len < 0 ) len = qstrlen(local8Bit);
+ return codec
+ ? codec->toUnicode(local8Bit, len)
+ : QString::fromLatin1(local8Bit,len);
+#endif
+// Should this be OS_WIN32?
+#ifdef _WS_WIN_
+ if ( len >= 0 ) {
+ QCString s(local8Bit,len+1);
+ return qt_winMB2QString(s);
+ }
+ return qt_winMB2QString( local8Bit );
+#endif
+#ifdef _WS_QWS_
+ return fromUtf8(local8Bit,len);
+#endif
+#endif // QT_NO_TEXTCODEC
+}
+
+/*!
+ \fn QString::operator const char *() const
+
+ Returns latin1(). Be sure to see the warnings documented there.
+ Note that for new code which you wish to be strictly Unicode-clean,
+ you can define the macro QT_NO_ASCII_CAST when compiling your code
+ to hide this function so that automatic casts are not done. This
+ has the added advantage that you catch the programming error
+ described under operator!().
+*/
+
+/*!
+ \fn QChar QString::at( uint ) const
+
+ Returns the character at \a i, or 0 if \a i is beyond the length
+ of the string.
+
+ Note: If this QString is not const or const&, the non-const at()
+ will be used instead, which will expand the string if \a i is beyond
+ the length of the string.
+*/
+
+/*!
+ \fn QChar QString::constref(uint i) const
+ Equivalent to at(i), this returns the QChar at \a i by value.
+
+ \sa ref()
+*/
+
+/*!
+ \fn QChar& QString::ref(uint i)
+ Returns the QChar at \a i by reference.
+
+ \sa constref()
+*/
+
+/*!
+ \fn QChar QString::operator[](int) const
+
+ Returns the character at \a i, or QChar::null if \a i is beyond the
+ length of the string.
+
+ Note: If this QString is not const or const&, the non-const operator[]
+ will be used instead, which will expand the string if \a i is beyond
+ the length of the string.
+*/
+
+/*!
+ \fn QCharRef QString::operator[](int)
+
+ Returns an object that references the character at \a i.
+ This reference
+ can then be assigned to, or otherwise used immediately, but
+ becomes invalid once further modifications are made to the string.
+ The QCharRef internal class can be used much like a constant QChar, but
+ if you assign to it, you change the original string (which enlarges
+ and detaches itself). You will get compilation errors if you try to
+ use the result as anything but a QChar.
+*/
+
+/*!
+ \fn QCharRef QString::at( uint i )
+ Returns a reference to the character at \a i, expanding
+ the string with QChar::null if necessary. The resulting reference
+ can then be assigned to, or otherwise used immediately, but
+ becomes invalid once further modifications are made to the string.
+*/
+
+/*!
+ Internal chunk of code to handle the
+ uncommon cases of at() above.
+*/
+void QString::subat( uint i )
+{
+ uint olen = d->len;
+ if ( i >= olen ) {
+ setLength( i+1 ); // i is index; i+1 is needed length
+ for ( uint j=olen; j<=i; j++ )
+ d->unicode[j] = QChar::null;
+ } else {
+ // Just be sure to detach
+ real_detach();
+ }
+}
+
+
+/*!
+ Resizes the string to \a len unicode characters and copies \a unicode
+ into the string. If \a unicode is null, nothing is copied, but the
+ string is resized to \a len anyway. If \a len is zero, the string
+ becomes a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+
+QString& QString::setUnicode( const QChar *unicode, uint len )
+{
+ if ( len == 0 ) { // set to null string
+ if ( d != shared_null ) { // beware of nullstring being set to nullstring
+ deref();
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ }
+ } else if ( d->count != 1 || len > d->maxl ||
+ ( len*4 < d->maxl && d->maxl > 4 ) ) { // detach, grown or shrink
+ Q2HELPER(stat_copy_on_write++)
+ Q2HELPER(stat_copy_on_write_size+=d->len)
+ uint newMax = 4;
+ while ( newMax < len )
+ newMax *= 2;
+ QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
+ if ( unicode )
+ memcpy( nd, unicode, sizeof(QChar)*len );
+ deref();
+ d = new QStringData( nd, len, newMax );
+ } else {
+ d->len = len;
+ d->dirtyascii = 1;
+ if ( unicode )
+ memcpy( d->unicode, unicode, sizeof(QChar)*len );
+ }
+ return *this;
+}
+
+/*!
+ Resizes the string to \a len unicode characters and copies
+ \a unicode_as_ushorts into the string (on some X11 client
+ platforms this will involve a byte-swapping pass).
+
+ If \a unicode is null, nothing is copied, but the
+ string is resized to \a len anyway. If \a len is zero, the string
+ becomes a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len )
+{
+ setUnicode((const QChar*)unicode_as_ushorts, len);
+ QChar t(0x1234);
+ if ( unicode_as_ushorts && *((ushort*)&t) == 0x3412 ) {
+ // Need to byteswap
+ char* b = (char*)d->unicode;
+ while ( len-- ) {
+ char c = b[0];
+ b[0] = b[1];
+ b[1] = c;
+ b += sizeof(QChar);
+ }
+ }
+ return *this;
+}
+
+
+/*!
+ Sets this string to \a str, interpreted as a classic Latin 1 C string.
+ If the \a len argument is negative (default), it is set to strlen(str).
+
+ If \a str is 0 a null string is created. If \a str is "" an empty
+ string is created.
+
+ \sa isNull(), isEmpty()
+*/
+
+QString &QString::setLatin1( const char *str, int len )
+{
+ if ( str == 0 )
+ return setUnicode(0,0);
+ if ( len < 0 )
+ len = qstrlen(str);
+ if ( len == 0 ) { // won't make a null string
+ deref();
+ uint l;
+ QChar *uc = internalAsciiToUnicode(str,&l);
+ d = new QStringData(uc,l,l);
+ } else {
+ setUnicode( 0, len ); // resize but not copy
+ QChar *p = d->unicode;
+ while ( len-- )
+ *p++ = *str++;
+ }
+ return *this;
+}
+
+
+/*!
+ \fn int QString::compare (const QString & s1, const QString & s2)
+
+ Compare \a s1 to \a s2 returning an integer less than, equal to, or
+ greater than zero if s1 is, respectively, lexically less than, equal to,
+ or greater than s2.
+*/
+
+/*!
+ Compares this string to \a s, returning an integer less than, equal to, or
+ greater than zero if it is, respectively, lexically less than, equal to,
+ or greater than \a s.
+*/
+int QString::compare( const QString& s ) const
+{
+ return ucstrcmp(*this,s);
+}
+
+bool operator==( const QString &s1, const QString &s2 )
+{
+ return (s1.length() == s2.length()) && s1.isNull() == s2.isNull() &&
+ (memcmp((char*)s1.unicode(),(char*)s2.unicode(),
+ s1.length()*sizeof(QChar)) ==0);
+}
+
+bool operator!=( const QString &s1, const QString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+bool operator==( const QString &s1, const char *s2 )
+{ return s1==QString(s2); }
+
+bool operator==( const char *s1, const QString &s2 )
+{ return QString(s1)==s2; }
+
+bool operator!=( const QString &s1, const char *s2 )
+{ return !(s1==s2); }
+
+bool operator!=( const char *s1, const QString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator<=( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+bool operator>=( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+/*****************************************************************************
+ Documentation for QString related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+ A null string is different from an empty, non-null string.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn QString operator+( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const QString &s1, const char *s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const char *s1, const QString &s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const QString &s, char c )
+ \relates QString
+ Returns the concatenated string of s and c.
+*/
+
+/*!
+ \fn QString operator+( char c, const QString &s )
+ \relates QString
+ Returns the concatenated string of c and s.
+*/
+
+
+/*****************************************************************************
+ QString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QString
+ Writes a string to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QString &str )
+{
+ if ( s.version() == 1 ) {
+ QCString l( str.latin1() );
+ s << l;
+ }
+ else {
+ const char* ub = (const char*)str.unicode();
+ if ( ub || s.version() < 3 ) {
+ if ( QChar::networkOrdered() ==
+ (s.byteOrder()==QDataStream::BigEndian) ) {
+ s.writeBytes( ub, (int)sizeof(QChar)*str.length() );
+ } else {
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( str.length()*sizeof(QChar) > auto_size ) {
+ b = new char[str.length()*sizeof(QChar)];
+ } else {
+ b = t;
+ }
+ int l = str.length();
+ char *c=b;
+ while ( l-- ) {
+ *c++ = ub[1];
+ *c++ = ub[0];
+ ub+=sizeof(QChar);
+ }
+ s.writeBytes( b, (int)sizeof(QChar)*str.length() );
+ if ( str.length()*sizeof(QChar) > auto_size )
+ delete [] b;
+ }
+ } else {
+ // write null marker
+ s << (Q_UINT32)0xffffffff;
+ }
+ }
+ return s;
+}
+
+/*!
+ \relates QString
+ Reads a string from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QString &str )
+{
+#ifdef QT_QSTRING_UCS_4
+#if defined(_CC_GNU_)
+#warning "operator>> not working properly"
+#endif
+#endif
+ if ( s.version() == 1 ) {
+ QCString l;
+ s >> l;
+ str = QString( l );
+ }
+ else {
+ Q_UINT32 bytes;
+ s >> bytes; // read size of string
+ if ( bytes == 0xffffffff ) { // null string
+ str = QString::null;
+ } else if ( bytes > 0 ) { // not empty
+ str.setLength( bytes/2 );
+ char* b = (char*)str.d->unicode;
+ s.readRawBytes( b, bytes );
+ if ( QChar::networkOrdered() !=
+ (s.byteOrder()==QDataStream::BigEndian) ) {
+ bytes /= 2;
+ while ( bytes-- ) {
+ char c = b[0];
+ b[0] = b[1];
+ b[1] = c;
+ b += 2;
+ }
+ }
+ } else {
+ str = "";
+ }
+ }
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QConstString member functions
+ *****************************************************************************/
+
+/*!
+ \class QConstString qstring.h
+ \brief A QString which uses constant Unicode data.
+
+ In order to minimize copying, highly optimized applications can use
+ QConstString to provide a QString-compatible object from existing
+ Unicode data. It is then the user's responsibility to make sure
+ that the Unicode data must exist for the entire lifetime of the
+ QConstString object.
+*/
+
+/*!
+ Constructs a QConstString that uses the first \a length Unicode
+ characters in the array \a unicode. Any attempt to modify
+ copies of the string will cause it to create a copy of the
+ data, thus it remains forever unmodified.
+
+ Note that \a unicode is \e not \e copied. The caller \e must be
+ able to guarantee that \a unicode will not be deleted or
+ modified. Since that is generally not the case with \c const strings
+ (they are references), this constructor demands a non-const pointer
+ even though it never modifies \a unicode.
+*/
+QConstString::QConstString( QChar* unicode, uint length ) :
+ QString(new QStringData(unicode, length, length),TRUE)
+{
+}
+
+/*!
+ Destroys the QConstString, creating a copy of the data if
+ other strings are still using it.
+*/
+QConstString::~QConstString()
+{
+ if ( d->count > 1 ) {
+ QChar* cp = QT_ALLOC_QCHAR_VEC( d->len );
+ memcpy( cp, d->unicode, d->len*sizeof(QChar) );
+ d->unicode = cp;
+ } else {
+ d->unicode = 0;
+ }
+
+ // The original d->unicode is now unlinked.
+}
+
+/*!
+ \fn const QString& QConstString::string() const
+
+ Returns a constant string referencing the data passed during
+ construction.
+*/
+
+/*!
+ Returns whether the strings starts with \a s, or not.
+ */
+bool QString::startsWith( const QString& s ) const
+{
+ for ( int i =0; i < (int) s.length(); i++ ) {
+ if ( i >= (int) length() || d->unicode[i] != s[i] )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+#if defined(_OS_WIN32_)
+
+#include <windows.h>
+
+/*!
+ Returns a static Windows TCHAR* from a QString, possibly adding NUL.
+
+ The lifetime of the return value is until the next call to this function.
+*/
+const void* qt_winTchar(const QString& str_in, bool addnul)
+{
+ // So that the return value lives long enough.
+ static QString str;
+ str = str_in;
+
+#ifdef UNICODE
+ static uint buflen = 256;
+ static TCHAR *buf = new TCHAR[buflen];
+
+ const QChar* uc = str.unicode();
+
+#define EXTEND if (str.length() > buflen) { delete buf; buf = new TCHAR[buflen=str.length()+1]; }
+
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_)
+ EXTEND
+ for ( int i=str.length(); i--; )
+ buf[i] = uc[i].row() << 8 | uc[i].cell();
+ if ( addnul )
+ buf[str.length()] = 0;
+#else
+ // Same endianness of TCHAR
+ if ( addnul ) {
+ EXTEND
+ memcpy(buf,uc,sizeof(TCHAR)*str.length());
+ buf[str.length()] = 0;
+ } else {
+ return uc;
+ }
+#endif
+ return buf;
+#undef EXTEND
+
+#else
+ return str.latin1();
+#endif
+}
+
+/*!
+ Makes a new null terminated Windows TCHAR* from a QString.
+*/
+void* qt_winTchar_new(const QString& str)
+{
+ TCHAR* result = new TCHAR[str.length()+1];
+ memcpy(result, qt_winTchar(str,FALSE), sizeof(TCHAR)*str.length());
+ result[str.length()] = 0;
+ return result;
+}
+
+/*!
+ Makes a QString from a Windows TCHAR*.
+*/
+QString qt_winQString(void* tc)
+{
+#ifdef UNICODE
+
+ int len=0;
+ while ( ((TCHAR*)tc)[len] )
+ len++;
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_)
+ QString r;
+ for ( int i=0; i<len; i++ )
+ r += QChar(((TCHAR*)tc)[i]&0xff,((TCHAR*)tc)[i]>>8);
+ return r;
+#else
+ // Same endianness of TCHAR
+ return QString((QChar*)tc,len);
+#endif
+#undef EXTEND
+#else
+ return (TCHAR*)tc;
+#endif
+}
+
+QCString qt_winQString2MB( const QString& s, int uclen )
+{
+ if ( uclen < 0 )
+ uclen = s.length();
+ if ( uclen == 0 )
+ return QCString();
+ BOOL used_def;
+ int bufSize=4096;
+ QCString mb(bufSize);
+ int len;
+ while ( !(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)s.unicode(), uclen,
+ mb.data(), bufSize-1, 0, &used_def)) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ bufSize=1+WideCharToMultiByte( CP_ACP, 0,
+ (const WCHAR*)s.unicode(), uclen,
+ 0, 0, 0, &used_def);
+ mb.resize(bufSize);
+ // and try again...
+ } else {
+ // Fail.
+ qWarning("WideCharToMultiByte cannot convert multibyte text (error %d): %s (UTF8)",
+ r, s.utf8().data());
+ break;
+ }
+ }
+ mb[len]='\0';
+ return mb;
+}
+
+// WATCH OUT: mblen must include the NUL (or just use -1)
+QString qt_winMB2QString( const char* mb, int mblen )
+{
+ if ( !mb || !mblen )
+ return QString::null;
+ const int wclen_auto = 4096;
+ WCHAR wc_auto[wclen_auto];
+ int wclen = wclen_auto;
+ WCHAR *wc = wc_auto;
+ int len;
+ while ( !(len=MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, wc, wclen )) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ if ( wc != wc_auto ) {
+ qWarning("Size changed in MultiByteToWideChar");
+ break;
+ } else {
+ wclen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, 0, 0 );
+ wc = new WCHAR[wclen];
+ // and try again...
+ }
+ } else {
+ // Fail.
+ qWarning("MultiByteToWideChar cannot convert multibyte text");
+ break;
+ }
+ }
+ if ( len <= 0 )
+ return QString::null;
+ QString s( (QChar*)wc, len-1 ); // len-1: we don't want terminator
+ if ( wc != wc_auto )
+ delete [] wc;
+ return s;
+}
+
+
+#endif // _OS_WIN32_
diff --git a/qtools/qstring.h b/qtools/qstring.h
new file mode 100644
index 0000000..a64fabf
--- /dev/null
+++ b/qtools/qstring.h
@@ -0,0 +1,834 @@
+/****************************************************************************
+**
+**
+** Definition of the QString class, and related Unicode
+** functions.
+**
+** Created : 920609
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSTRING_H
+#define QSTRING_H
+
+#ifndef QT_H
+#include "qcstring.h"
+#endif // QT_H
+
+#define QT_NO_ASCII_CAST
+
+/*****************************************************************************
+ QString class
+ *****************************************************************************/
+
+class QRegExp;
+class QString;
+class QCharRef;
+
+class Q_EXPORT Q_PACKED QChar {
+public:
+ QChar();
+ QChar( char c );
+ QChar( uchar c );
+ QChar( uchar c, uchar r );
+ QChar( const QChar& c );
+ QChar( ushort rc );
+ QChar( short rc );
+ QChar( uint rc );
+ QChar( int rc );
+
+ QT_STATIC_CONST QChar null; // 0000
+ QT_STATIC_CONST QChar replacement; // FFFD
+ QT_STATIC_CONST QChar byteOrderMark; // FEFF
+ QT_STATIC_CONST QChar byteOrderSwapped; // FFFE
+ QT_STATIC_CONST QChar nbsp; // 00A0
+
+ // Unicode information
+
+ enum Category
+ {
+ NoCategory,
+
+ Mark_NonSpacing, // Mn
+ Mark_SpacingCombining, // Mc
+ Mark_Enclosing, // Me
+
+ Number_DecimalDigit, // Nd
+ Number_Letter, // Nl
+ Number_Other, // No
+
+ Separator_Space, // Zs
+ Separator_Line, // Zl
+ Separator_Paragraph, // Zp
+
+ Other_Control, // Cc
+ Other_Format, // Cf
+ Other_Surrogate, // Cs
+ Other_PrivateUse, // Co
+ Other_NotAssigned, // Cn
+
+ Letter_Uppercase, // Lu
+ Letter_Lowercase, // Ll
+ Letter_Titlecase, // Lt
+ Letter_Modifier, // Lm
+ Letter_Other, // Lo
+
+ Punctuation_Connector, // Pc
+ Punctuation_Dask, // Pd
+ Punctuation_Open, // Ps
+ Punctuation_Close, // Pe
+ Punctuation_InitialQuote, // Pi
+ Punctuation_FinalQuote, // Pf
+ Punctuation_Other, // Po
+
+ Symbol_Math, // Sm
+ Symbol_Currency, // Sc
+ Symbol_Modifier, // Sk
+ Symbol_Other // So
+ };
+
+ enum Direction
+ {
+ DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
+ };
+
+ enum Decomposition
+ {
+ Single, Canonical, Font, NoBreak, Initial, Medial,
+ Final, Isolated, Circle, Super, Sub, Vertical,
+ Wide, Narrow, Small, Square, Compat, Fraction
+ };
+
+ enum Joining
+ {
+ OtherJoining, Dual, Right, Center
+ };
+
+ // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
+
+ int digitValue() const;
+ QChar lower() const;
+ QChar upper() const;
+
+ Category category() const;
+ Direction direction() const;
+ Joining joining() const;
+ bool mirrored() const;
+ QChar mirroredChar() const;
+ QString decomposition() const;
+ Decomposition decompositionTag() const;
+
+ char latin1() const { return rw ? 0 : cl; }
+ ushort unicode() const { return (rw << 8) | cl; }
+#ifndef QT_NO_CAST_ASCII
+ // like all ifdef'd code this is undocumented
+ operator char() const { return latin1(); }
+#endif
+
+ bool isNull() const { return unicode()==0; }
+ bool isPrint() const;
+ bool isPunct() const;
+ bool isSpace() const;
+ bool isMark() const;
+ bool isLetter() const;
+ bool isNumber() const;
+ bool isLetterOrNumber() const;
+ bool isDigit() const;
+
+ uchar& cell() { return cl; }
+ uchar& row() { return rw; }
+ uchar cell() const { return cl; }
+ uchar row() const { return rw; }
+
+ static bool networkOrdered() { return (int)net_ordered == 1; }
+
+ friend inline int operator==( char ch, QChar c );
+ friend inline int operator==( QChar c, char ch );
+ friend inline int operator==( QChar c1, QChar c2 );
+ friend inline int operator!=( QChar c1, QChar c2 );
+ friend inline int operator!=( char ch, QChar c );
+ friend inline int operator!=( QChar c, char ch );
+ friend inline int operator<=( QChar c, char ch );
+ friend inline int operator<=( char ch, QChar c );
+ friend inline int operator<=( QChar c1, QChar c2 );
+
+private:
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_) || defined( _WS_QWS_ )
+ // XChar2b on X11, ushort on _OS_WIN32_BYTESWAP_
+ //### QWS must be defined on a platform by platform basis
+ uchar rw;
+ uchar cl;
+#if defined(QT_QSTRING_UCS_4)
+ ushort grp;
+#endif
+ enum { net_ordered = 1 };
+#else
+ // ushort on _OS_WIN32_
+ uchar cl;
+ uchar rw;
+#if defined(QT_QSTRING_UCS_4)
+ ushort grp;
+#endif
+ enum { net_ordered = 0 };
+#endif
+};
+
+inline QChar::QChar()
+{
+ rw = 0; cl = 0;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( char c )
+{
+ rw = 0; cl = (uchar)c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uchar c )
+{
+ rw = 0; cl = c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uchar c, uchar r )
+{
+ rw = r; cl = c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( const QChar& c )
+{
+ rw = c.rw; cl = c.cl;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( ushort rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( short rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uint rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( int rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+
+
+inline int operator==( char ch, QChar c )
+{
+ return ch == c.cl && !c.rw;
+}
+
+inline int operator==( QChar c, char ch )
+{
+ return ch == c.cl && !c.rw;
+}
+
+inline int operator==( QChar c1, QChar c2 )
+{
+ return c1.cl == c2.cl
+ && c1.rw == c2.rw;
+}
+
+inline int operator!=( QChar c1, QChar c2 )
+{
+ return c1.cl != c2.cl
+ || c1.rw != c2.rw;
+}
+
+inline int operator!=( char ch, QChar c )
+{
+ return ch != c.cl || c.rw;
+}
+
+inline int operator!=( QChar c, char ch )
+{
+ return ch != c.cl || c.rw;
+}
+
+inline int operator<=( QChar c, char ch )
+{
+ return !(ch < c.cl || c.rw);
+}
+
+inline int operator<=( char ch, QChar c )
+{
+ return ch <= c.cl || c.rw;
+}
+
+inline int operator<=( QChar c1, QChar c2 )
+{
+ return c1.rw > c2.rw
+ ? FALSE
+ : c1.rw < c2.rw
+ ? TRUE
+ : c1.cl <= c2.cl;
+}
+
+inline int operator>=( QChar c, char ch ) { return ch <= c; }
+inline int operator>=( char ch, QChar c ) { return c <= ch; }
+inline int operator>=( QChar c1, QChar c2 ) { return c2 <= c1; }
+inline int operator<( QChar c, char ch ) { return !(ch<=c); }
+inline int operator<( char ch, QChar c ) { return !(c<=ch); }
+inline int operator<( QChar c1, QChar c2 ) { return !(c2<=c1); }
+inline int operator>( QChar c, char ch ) { return !(ch>=c); }
+inline int operator>( char ch, QChar c ) { return !(c>=ch); }
+inline int operator>( QChar c1, QChar c2 ) { return !(c2>=c1); }
+
+// internal
+struct Q_EXPORT QStringData : public QShared {
+ QStringData() :
+ unicode(0), ascii(0), len(0), maxl(0), dirtyascii(0) { ref(); }
+ QStringData(QChar *u, uint l, uint m) :
+ unicode(u), ascii(0), len(l), maxl(m), dirtyascii(0) { }
+
+ ~QStringData() { if ( unicode ) delete[] ((char*)unicode);
+ if ( ascii ) delete[] ascii; }
+
+ void deleteSelf();
+ QChar *unicode;
+ char *ascii;
+ uint len;
+ uint maxl:30;
+ uint dirtyascii:1;
+};
+
+
+class Q_EXPORT QString
+{
+public:
+ QString(); // make null string
+ QString( QChar ); // one-char string
+ QString( const QString & ); // impl-shared copy
+ QString( const QByteArray& ); // deep copy
+ QString( const QCString& ); // deep copy
+ QString( const QChar* unicode, uint length ); // deep copy
+#ifndef QT_NO_CAST_ASCII
+ QString( const char *str ); // deep copy
+#endif
+ ~QString();
+
+ QString &operator=( const QString & ); // impl-shared copy
+#ifndef QT_NO_CAST_ASCII
+ QString &operator=( const char * ); // deep copy
+#endif
+ QString &operator=( const QCString& ); // deep copy
+ QString &operator=( QChar c );
+ QString &operator=( char c );
+
+ //QT_STATIC_CONST QString null;
+ //bool isNull() const;
+
+ struct Null { };
+ static const Null null;
+ inline QString(const Null &): d(shared_null) { d->ref(); }
+ inline QString &operator=(const Null &) { *this = QString(); return *this; }
+ inline bool isNull() const { return d == shared_null; }
+
+ bool isEmpty() const;
+ uint length() const;
+ void truncate( uint pos );
+
+#if QT_VERSION >= 300
+#error "fill() Should return *this, or QChar constructor should take count=1"
+#endif
+ void fill( QChar c, int len = -1 );
+
+ QString copy() const;
+
+ QString arg(long a, int fieldwidth=0, int base=10) const;
+ QString arg(ulong a, int fieldwidth=0, int base=10) const;
+ QString arg(int a, int fieldwidth=0, int base=10) const;
+ QString arg(uint a, int fieldwidth=0, int base=10) const;
+ QString arg(short a, int fieldwidth=0, int base=10) const;
+ QString arg(ushort a, int fieldwidth=0, int base=10) const;
+ QString arg(char a, int fieldwidth=0) const;
+ QString arg(QChar a, int fieldwidth=0) const;
+ QString arg(const QString& a, int fieldwidth=0) const;
+ QString arg(double a, int fieldwidth=0, char fmt='g', int prec=-1) const;
+
+ QString &sprintf( const char* format, ... )
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+
+ int find( QChar c, int index=0, bool cs=TRUE ) const;
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const QString &str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &, int index=0 ) const;
+#ifndef QT_NO_CAST_ASCII
+ int find( const char* str, int index=0 ) const;
+#endif
+ int findRev( QChar c, int index=-1, bool cs=TRUE) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const QString &str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &, int index=-1 ) const;
+#ifndef QT_NO_CAST_ASCII
+ int findRev( const char* str, int index=-1 ) const;
+#endif
+ int contains( QChar c, bool cs=TRUE ) const;
+ int contains( char c, bool cs=TRUE ) const
+ { return contains(QChar(c), cs); }
+#ifndef QT_NO_CAST_ASCII
+ int contains( const char* str, bool cs=TRUE ) const;
+#endif
+ int contains( const QString &str, bool cs=TRUE ) const;
+ int contains( const QRegExp & ) const;
+
+ QString left( uint len ) const;
+ QString right( uint len ) const;
+ QString mid( uint index, uint len=0xffffffff) const;
+
+ QString leftJustify( uint width, QChar fill=' ', bool trunc=FALSE)const;
+ QString rightJustify( uint width, QChar fill=' ',bool trunc=FALSE)const;
+
+ QString lower() const;
+ QString upper() const;
+
+ QString stripWhiteSpace() const;
+ QString simplifyWhiteSpace() const;
+
+ QString &insert( uint index, const QString & );
+ QString &insert( uint index, const QChar*, uint len );
+ QString &insert( uint index, QChar );
+ QString &insert( uint index, char c ) { return insert(index,QChar(c)); }
+ QString &append( char );
+ QString &append( QChar );
+ QString &append( const QString & );
+ QString &prepend( char );
+ QString &prepend( QChar );
+ QString &prepend( const QString & );
+ QString &remove( uint index, uint len );
+ QString &replace( uint index, uint len, const QString & );
+ QString &replace( uint index, uint len, const QChar*, uint clen );
+ QString &replace( const QRegExp &, const QString & );
+
+ short toShort( bool *ok=0, int base=10 ) const;
+ ushort toUShort( bool *ok=0, int base=10 ) const;
+ int toInt( bool *ok=0, int base=10 ) const;
+ uint toUInt( bool *ok=0, int base=10 ) const;
+ long toLong( bool *ok=0, int base=10 ) const;
+ ulong toULong( bool *ok=0, int base=10 ) const;
+ float toFloat( bool *ok=0 ) const;
+ double toDouble( bool *ok=0 ) const;
+
+ QString &setNum( short, int base=10 );
+ QString &setNum( ushort, int base=10 );
+ QString &setNum( int, int base=10 );
+ QString &setNum( uint, int base=10 );
+ QString &setNum( long, int base=10 );
+ QString &setNum( ulong, int base=10 );
+ QString &setNum( float, char f='g', int prec=6 );
+ QString &setNum( double, char f='g', int prec=6 );
+
+ static QString number( long, int base=10 );
+ static QString number( ulong, int base=10);
+ static QString number( int, int base=10 );
+ static QString number( uint, int base=10);
+ static QString number( double, char f='g', int prec=6 );
+
+ void setExpand( uint index, QChar c );
+
+ QString &operator+=( const QString &str );
+ QString &operator+=( QChar c );
+ QString &operator+=( char c );
+
+ // Your compiler is smart enough to use the const one if it can.
+ QChar at( uint i ) const
+ { return i<d->len ? d->unicode[i] : QChar::null; }
+ QChar operator[]( int i ) const { return at((uint)i); }
+ QCharRef at( uint i );
+ QCharRef operator[]( int i );
+
+ QChar constref(uint i) const
+ { return at(i); }
+ QChar& ref(uint i)
+ { // Optimized for easy-inlining by simple compilers.
+ if (d->count!=1 || i>=d->len)
+ subat(i);
+ d->dirtyascii=1;
+ return d->unicode[i];
+ }
+
+ const QChar* unicode() const { return d->unicode; }
+ const char* ascii() const;
+ const char* latin1() const;
+ static QString fromLatin1(const char*, int len=-1);
+ const unsigned short *ucs2() const;
+ static QString fromUcs2( const unsigned short *ucs2 );
+#ifndef QT_NO_TEXTCODEC
+ QCString utf8() const;
+ static QString fromUtf8(const char*, int len=-1);
+#endif
+ QCString local8Bit() const;
+ static QString fromLocal8Bit(const char*, int len=-1);
+ bool operator!() const;
+#ifndef QT_NO_ASCII_CAST
+ operator const char *() const { return latin1(); }
+#endif
+
+ QString &setUnicode( const QChar* unicode, uint len );
+ QString &setUnicodeCodes( const ushort* unicode_as_ushorts, uint len );
+ QString &setLatin1( const char*, int len=-1 );
+
+ int compare( const QString& s ) const;
+ static int compare( const QString& s1, const QString& s2 )
+ { return s1.compare(s2); }
+
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
+#endif
+ // new functions for BiDi
+ void compose();
+ QChar::Direction basicDirection();
+ QString visual(int index = 0, int len = -1);
+
+#ifndef QT_NO_COMPAT
+ const char* data() const { return latin1(); }
+#endif
+
+ bool startsWith( const QString& ) const;
+
+private:
+ QString( int size, bool dummy ); // allocate size incl. \0
+
+ void deref();
+ void real_detach();
+ void setLength( uint pos );
+ void subat( uint );
+ bool findArg(int& pos, int& len) const;
+
+ static QChar* asciiToUnicode( const char*, uint * len, uint maxlen=(uint)-1 );
+ static QChar* asciiToUnicode( const QByteArray&, uint * len );
+ static char* unicodeToAscii( const QChar*, uint len );
+
+ QStringData *d;
+ static QStringData* shared_null;
+ static QStringData* makeSharedNull();
+
+ friend class QConstString;
+ QString(QStringData* dd, bool /*dummy*/) : d(dd) { }
+};
+
+class Q_EXPORT QCharRef {
+ friend class QString;
+ QString& s;
+ uint p;
+ QCharRef(QString* str, uint pos) : s(*str), p(pos) { }
+
+public:
+ // Most QChar operations repeated here...
+
+ // all this is not documented: We just say "like QChar" and let it be.
+#if 1
+ ushort unicode() const { return s.constref(p).unicode(); }
+ char latin1() const { return s.constref(p).latin1(); }
+
+ // An operator= for each QChar cast constructor...
+ QCharRef operator=(char c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(QChar c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(const QCharRef& c ) { s.ref(p)=c.unicode(); return *this; }
+ QCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
+
+ operator QChar () const { return s.constref(p); }
+
+ // each function...
+ bool isNull() const { return unicode()==0; }
+ bool isPrint() const { return s.constref(p).isPrint(); }
+ bool isPunct() const { return s.constref(p).isPunct(); }
+ bool isSpace() const { return s.constref(p).isSpace(); }
+ bool isMark() const { return s.constref(p).isMark(); }
+ bool isLetter() const { return s.constref(p).isLetter(); }
+ bool isNumber() const { return s.constref(p).isNumber(); }
+ bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
+ bool isDigit() const { return s.constref(p).isDigit(); }
+
+ int digitValue() const { return s.constref(p).digitValue(); }
+ QChar lower() { return s.constref(p).lower(); }
+ QChar upper() { return s.constref(p).upper(); }
+
+ QChar::Category category() const { return s.constref(p).category(); }
+ QChar::Direction direction() const { return s.constref(p).direction(); }
+ QChar::Joining joining() const { return s.constref(p).joining(); }
+ bool mirrored() const { return s.constref(p).mirrored(); }
+ QChar mirroredChar() const { return s.constref(p).mirroredChar(); }
+ QString decomposition() const { return s.constref(p).decomposition(); }
+ QChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
+
+ // Not the non-const ones of these.
+ uchar cell() const { return s.constref(p).cell(); }
+ uchar row() const { return s.constref(p).row(); }
+#endif
+};
+
+inline QCharRef QString::at( uint i ) { return QCharRef(this,i); }
+inline QCharRef QString::operator[]( int i ) { return at((uint)i); }
+
+
+class Q_EXPORT QConstString : private QString {
+public:
+ QConstString( QChar* unicode, uint length );
+ ~QConstString();
+ const QString& string() const { return *this; }
+};
+
+
+/*****************************************************************************
+ QString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QString & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
+#endif
+
+/*****************************************************************************
+ QString inline functions
+ *****************************************************************************/
+
+// These two move code into makeSharedNull() and deletesData()
+// to improve cache-coherence (and reduce code bloat), while
+// keeping the common cases fast.
+//
+// No safe way to pre-init shared_null on ALL compilers/linkers.
+inline QString::QString() :
+ d(shared_null ? shared_null : makeSharedNull())
+{
+ d->ref();
+}
+//
+inline QString::~QString()
+{
+ if ( d->deref() ) {
+ if ( d == shared_null )
+ shared_null = 0;
+ d->deleteSelf();
+ }
+}
+
+inline QString &QString::operator=( QChar c )
+{ return *this = QString(c); }
+
+inline QString &QString::operator=( char c )
+{ return *this = QString(QChar(c)); }
+
+//inline bool QString::isNull() const
+//{ return unicode() == 0; }
+
+inline bool QString::operator!() const
+{ return isNull(); }
+
+inline uint QString::length() const
+{ return d->len; }
+
+inline bool QString::isEmpty() const
+{ return length() == 0; }
+
+inline QString QString::copy() const
+{ return QString( *this ); }
+
+inline QString &QString::prepend( const QString & s )
+{ return insert(0,s); }
+
+inline QString &QString::prepend( QChar c )
+{ return insert(0,c); }
+
+inline QString &QString::prepend( char c )
+{ return insert(0,c); }
+
+inline QString &QString::append( const QString & s )
+{ return operator+=(s); }
+
+inline QString &QString::append( QChar c )
+{ return operator+=(c); }
+
+inline QString &QString::append( char c )
+{ return operator+=(c); }
+
+inline QString &QString::setNum( short n, int base )
+{ return setNum((long)n, base); }
+
+inline QString &QString::setNum( ushort n, int base )
+{ return setNum((ulong)n, base); }
+
+inline QString &QString::setNum( int n, int base )
+{ return setNum((long)n, base); }
+
+inline QString &QString::setNum( uint n, int base )
+{ return setNum((ulong)n, base); }
+
+inline QString &QString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline QString QString::arg(int a, int fieldwidth, int base) const
+{ return arg((long)a, fieldwidth, base); }
+
+inline QString QString::arg(uint a, int fieldwidth, int base) const
+{ return arg((ulong)a, fieldwidth, base); }
+
+inline QString QString::arg(short a, int fieldwidth, int base) const
+{ return arg((long)a, fieldwidth, base); }
+
+inline QString QString::arg(ushort a, int fieldwidth, int base) const
+{ return arg((ulong)a, fieldwidth, base); }
+
+inline int QString::find( char c, int index, bool cs ) const
+{ return find(QChar(c), index, cs); }
+
+inline int QString::findRev( char c, int index, bool cs) const
+{ return findRev( QChar(c), index, cs ); }
+
+
+#ifndef QT_NO_CAST_ASCII
+inline int QString::find( const char* str, int index ) const
+{ return find(QString::fromLatin1(str), index); }
+
+inline int QString::findRev( const char* str, int index ) const
+{ return findRev(QString::fromLatin1(str), index); }
+#endif
+
+
+/*****************************************************************************
+ QString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT bool operator!=( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator<( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator<=( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator==( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator>( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator>=( const QString &s1, const QString &s2 );
+#ifndef QT_NO_CAST_ASCII
+Q_EXPORT bool operator!=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator<( const QString &s1, const char *s2 );
+Q_EXPORT bool operator<=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator==( const QString &s1, const char *s2 );
+Q_EXPORT bool operator>( const QString &s1, const char *s2 );
+Q_EXPORT bool operator>=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator!=( const char *s1, const QString &s2 );
+Q_EXPORT bool operator<( const char *s1, const QString &s2 );
+Q_EXPORT bool operator<=( const char *s1, const QString &s2 );
+Q_EXPORT bool operator==( const char *s1, const QString &s2 );
+//Q_EXPORT bool operator>( const char *s1, const QString &s2 ); // MSVC++
+Q_EXPORT bool operator>=( const char *s1, const QString &s2 );
+#endif
+
+Q_EXPORT inline QString operator+( const QString &s1, const QString &s2 )
+{
+ QString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef QT_NO_CAST_ASCII
+Q_EXPORT inline QString operator+( const QString &s1, const char *s2 )
+{
+ QString tmp( s1 );
+ tmp += QString::fromLatin1(s2);
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( const char *s1, const QString &s2 )
+{
+ QString tmp = QString::fromLatin1( s1 );
+ tmp += s2;
+ return tmp;
+}
+#endif
+
+Q_EXPORT inline QString operator+( const QString &s1, QChar c2 )
+{
+ QString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( const QString &s1, char c2 )
+{
+ QString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( QChar c1, const QString &s2 )
+{
+ QString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( char c1, const QString &s2 )
+{
+ QString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#if defined(_OS_WIN32_)
+extern Q_EXPORT QString qt_winQString(void*);
+extern Q_EXPORT const void* qt_winTchar(const QString& str, bool addnul);
+extern Q_EXPORT void* qt_winTchar_new(const QString& str);
+extern Q_EXPORT QCString qt_winQString2MB( const QString& s, int len=-1 );
+extern Q_EXPORT QString qt_winMB2QString( const char* mb, int len=-1 );
+#endif
+
+#endif // QSTRING_H
diff --git a/qtools/qstringlist.cpp b/qtools/qstringlist.cpp
new file mode 100644
index 0000000..7696340
--- /dev/null
+++ b/qtools/qstringlist.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+**
+** Implementation of QStringList
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qstringlist.h"
+
+#ifndef QT_NO_STRINGLIST
+#include "qstrlist.h"
+#include "qdatastream.h"
+#include "qtl.h"
+
+// NOT REVISED
+/*!
+ \class QStringList qstringlist.h
+ \brief A list of strings.
+
+ \ingroup qtl
+ \ingroup tools
+ \ingroup shared
+
+ QStringList is basically a QValueList of QString objects. As opposed
+ to QStrList, that stores pointers to characters, QStringList deals
+ with real QString objects. It is the class of choice whenever you
+ work with unicode strings.
+
+ Like QString itself, QStringList objects are implicit shared.
+ Passing them around as value-parameters is both fast and safe.
+
+ Example:
+ \code
+ QStringList list;
+
+ // three different ways of appending values:
+ list.append( "Torben");
+ list += "Warwick";
+ list << "Matthias" << "Arnt" << "Paul";
+
+ // sort the list, Arnt's now first
+ list.sort();
+
+ // print it out
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
+ printf( "%s \n", (*it).latin1() );
+ }
+ \endcode
+
+ Convenience methods such as sort(), split(), join() and grep() make
+ working with QStringList easy.
+*/
+
+/*!
+ \fn QStringList::QStringList()
+ Creates an empty list.
+*/
+
+/*! \fn QStringList::QStringList( const QStringList& l )
+ Creates a copy of the list. This function is very fast since
+ QStringList is implicit shared. However, for the programmer this
+ is the same as a deep copy. If this list or the original one or some
+ other list referencing the same shared data is modified, then the
+ modifying list makes a copy first.
+*/
+
+/*!
+ \fn QStringList::QStringList (const QString & i)
+ Constructs a string list consisting of the single string \a i.
+ To make longer lists easily, use:
+ \code
+ QString s1,s2,s3;
+ ...
+ QStringList mylist = QStringList() << s1 << s2 << s3;
+ \endcode
+*/
+
+/*!
+ \fn QStringList::QStringList (const char* i)
+ Constructs a string list consisting of the single latin-1 string \a i.
+*/
+
+/*! \fn QStringList::QStringList( const QValueList<QString>& l )
+
+ Constructs a new string list that is a copy of \a l.
+*/
+
+/*!
+ Sorts the list of strings in ascending order.
+
+ Sorting is very fast. It uses the Qt Template Library's
+ efficient HeapSort implementation that operates in O(n*log n).
+*/
+void QStringList::sort()
+{
+ qHeapSort(*this);
+}
+
+/*!
+ Splits the string \a str using \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QChar &sep, const QString &str, bool allowEmptyEntries )
+{
+ return split( QString( sep ), str, allowEmptyEntries );
+}
+
+/*!
+ Splits the string \a str using \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QString &sep, const QString &str, bool allowEmptyEntries )
+{
+ QStringList lst;
+
+ int j = 0;
+ int i = str.find( sep, j );
+
+ while ( i != -1 ) {
+ if ( str.mid( j, i - j ).length() > 0 )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+ j = i + sep.length();
+ i = str.find( sep, j );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+
+ return lst;
+}
+
+QStringList QStringList::split( const QCString &sep, const QCString &str, bool allowEmptyEntries )
+{
+ return split(QString(sep.data()),QString(str.data()),allowEmptyEntries);
+}
+
+/*!
+ Splits the string \a str using the regular expression \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QRegExp &sep, const QString &str, bool allowEmptyEntries )
+{
+ QStringList lst;
+
+ int j = 0;
+ int len = 0;
+ int i = sep.match( str.data(), j, &len );
+
+ while ( i != -1 ) {
+ if ( str.mid( j, i - j ).length() > 0 )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+ j = i + len;
+ i = sep.match( str.data(), j, &len );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+
+ return lst;
+}
+
+/*!
+ Returns a list of all strings containing the substring \a str.
+
+ If \a cs is TRUE, the grep is done case sensitively, else not.
+*/
+
+QStringList QStringList::grep( const QString &str, bool cs ) const
+{
+ QStringList res;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).contains( str, cs ) )
+ res << *it;
+
+ return res;
+}
+
+/*!
+ Returns a list of all strings containing a substring that matches
+ the regular expression \a expr.
+*/
+
+QStringList QStringList::grep( const QRegExp &expr ) const
+{
+ QStringList res;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).contains( expr ) )
+ res << *it;
+
+ return res;
+}
+
+/*!
+ Joins the stringlist into a single string with each element
+ separated by \a sep.
+
+ \sa split()
+*/
+QString QStringList::join( const QString &sep ) const
+{
+ QString res;
+ bool alredy = FALSE;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it ) {
+ if ( alredy )
+ res += sep;
+ alredy = TRUE;
+ res += *it;
+ }
+
+ return res;
+}
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream & s, QStringList& l )
+{
+ return s >> (QValueList<QString>&)l;
+}
+
+Q_EXPORT QDataStream &operator<<( QDataStream & s, const QStringList& l )
+{
+ return s << (const QValueList<QString>&)l;
+}
+#endif
+
+/*!
+ Converts from a QStrList (ASCII) to a QStringList (Unicode).
+*/
+QStringList QStringList::fromStrList(const QStrList& ascii)
+{
+ QStringList res;
+ const char * s;
+ for ( QStrListIterator it(ascii); (s=it.current()); ++it )
+ res << s;
+ return res;
+}
+
+#endif //QT_NO_STRINGLIST
diff --git a/qtools/qstringlist.h b/qtools/qstringlist.h
new file mode 100644
index 0000000..3f9fbb2
--- /dev/null
+++ b/qtools/qstringlist.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+**
+** Definition of QStringList class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSTRINGLIST_H
+#define QSTRINGLIST_H
+
+#ifndef QT_H
+#include "qvaluelist.h"
+#include "qstring.h"
+#include "qregexp.h"
+#endif // QT_H
+
+#ifndef QT_NO_STRINGLIST
+
+class QStrList;
+
+class Q_EXPORT QStringList : public QValueList<QString>
+{
+public:
+ QStringList() { }
+ QStringList( const QStringList& l ) : QValueList<QString>(l) { }
+ QStringList( const QValueList<QString>& l ) : QValueList<QString>(l) { }
+ QStringList( const QString& i ) { append(i); }
+#ifndef QT_NO_CAST_ASCII
+ QStringList( const char* i ) { append(i); }
+#endif
+
+ static QStringList fromStrList(const QStrList&);
+
+ void sort();
+
+ static QStringList split( const QString &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ static QStringList split( const QCString &sep, const QCString &str, bool allowEmptyEntries = FALSE );
+ static QStringList split( const QChar &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ static QStringList split( const QRegExp &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ QString join( const QString &sep ) const;
+
+ QStringList grep( const QString &str, bool cs = TRUE ) const;
+ QStringList grep( const QRegExp &expr ) const;
+};
+
+#ifndef QT_NO_DATASTREAM
+class QDataStream;
+extern Q_EXPORT QDataStream &operator>>( QDataStream &, QStringList& );
+extern Q_EXPORT QDataStream &operator<<( QDataStream &, const QStringList& );
+#endif
+#endif // QT_NO_STRINGLIST
+#endif // QSTRINGLIST_H
diff --git a/qtools/qstrlist.doc b/qtools/qstrlist.doc
new file mode 100644
index 0000000..751c6c2
--- /dev/null
+++ b/qtools/qstrlist.doc
@@ -0,0 +1,5 @@
+/****************************************************************************
+**
+*****************************************************************************/
+
+//typedef QListIterator<char> QStrListIterator;
diff --git a/qtools/qstrlist.h b/qtools/qstrlist.h
new file mode 100644
index 0000000..ebf97c5
--- /dev/null
+++ b/qtools/qstrlist.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+**
+** Definition of QStrList, QStrIList and QStrListIterator classes
+**
+** Created : 920730
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSTRLIST_H
+#define QSTRLIST_H
+
+#ifndef QT_H
+#include "qstring.h"
+#include "qinternallist.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QInternalList<char>;
+template class Q_EXPORT QInternalListIterator<char>;
+#endif
+
+typedef QInternalList<char> QStrListBase;
+typedef QInternalListIterator<char> QStrListIterator;
+
+
+class Q_EXPORT QStrList : public QStrListBase
+{
+public:
+ QStrList( bool deepCopies=TRUE ) { dc = deepCopies; del_item = deepCopies; }
+ QStrList( const QStrList & );
+ ~QStrList() { clear(); }
+ QStrList& operator=( const QStrList & );
+
+private:
+ QCollection::Item newItem( QCollection::Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( QCollection::Item d ) { if ( del_item ) delete[] (char*)d; }
+ int compareItems( QCollection::Item s1, QCollection::Item s2 ) { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream &s, QCollection::Item &d )
+ { s >> (char *&)d; return s; }
+ QDataStream &write( QDataStream &s, QCollection::Item d ) const
+ { return s << (const char *)d; }
+#endif
+ bool dc;
+};
+
+
+class Q_EXPORT QStrIList : public QStrList // case insensitive string list
+{
+public:
+ QStrIList( bool deepCopies=TRUE ) : QStrList( deepCopies ) {}
+ ~QStrIList() { clear(); }
+private:
+ int compareItems( QCollection::Item s1, QCollection::Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+inline QStrList & QStrList::operator=( const QStrList &strList )
+{
+ clear();
+ dc = strList.dc;
+ del_item = dc;
+ QStrListBase::operator=(strList);
+ return *this;
+}
+
+inline QStrList::QStrList( const QStrList &strList )
+ : QStrListBase( strList )
+{
+ dc = FALSE;
+ operator=(strList);
+}
+
+
+#endif // QSTRLIST_H
diff --git a/qtools/qstrvec.h b/qtools/qstrvec.h
new file mode 100644
index 0000000..15d3abb
--- /dev/null
+++ b/qtools/qstrvec.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+**
+** Definition of QStrVec and QStrIVec classes
+**
+** Created : 931203
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QSTRVEC_H
+#define QSTRVEC_H
+
+#ifndef QT_H
+#include "qstring.h"
+#include "qvector.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QVector<char>
+#endif
+
+typedef QVector<char> QStrVecBase;
+
+
+class Q_EXPORT QStrVec : public QStrVecBase
+{
+public:
+ QStrVec() { dc = TRUE; }
+ QStrVec( uint size, bool deepc = TRUE ) : QStrVecBase(size) {dc=deepc;}
+ ~QStrVec() { clear(); }
+private:
+ Item newItem( Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( Item d ) { if ( dc ) delete[] (char*)d; }
+ int compareItems( Item s1, Item s2 )
+ { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream &s, Item &d )
+ { s >> (char *&)d; return s; }
+ QDataStream &write( QDataStream &s, Item d ) const
+ { return s << (const char*)d; }
+#endif
+ bool dc;
+};
+
+
+class Q_EXPORT QStrIVec : public QStrVec // case insensitive string vec
+{
+public:
+ QStrIVec() {}
+ QStrIVec( uint size, bool dc = TRUE ) : QStrVec( size, dc ) {}
+ ~QStrIVec() { clear(); }
+private:
+ int compareItems( Item s1, Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+#endif // QSTRVEC_H
diff --git a/qtools/qtextcodec.cpp b/qtools/qtextcodec.cpp
new file mode 100644
index 0000000..168445f
--- /dev/null
+++ b/qtools/qtextcodec.cpp
@@ -0,0 +1,2071 @@
+/****************************************************************************
+**
+**
+** Implementation of QTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C)1998-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qtextcodec.h"
+#ifndef QT_NO_TEXTCODEC
+
+#include "qinternallist.h"
+#ifndef QT_NO_CODECS
+#include "qutfcodec.h"
+//#include "qgbkcodec.h"
+//#include "qeucjpcodec.h"
+//#include "qjiscodec.h"
+//#include "qsjiscodec.h"
+//#include "qeuckrcodec.h"
+//#include "qbig5codec.h"
+//#include "qrtlcodec.h"
+//#include "qtsciicodec.h"
+#endif
+
+#include "qfile.h"
+#include "qstrlist.h"
+#include "qstring.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <locale.h>
+
+
+static QInternalList<QTextCodec> * all = 0;
+static bool destroying_is_ok; // starts out as 0
+
+/*! Deletes all the created codecs.
+
+ \warning Do not call this function.
+
+ QApplication calls this just before exiting, to delete any
+ QTextCodec objects that may be lying around. Since various other
+ classes hold pointers to QTextCodec objects, it is not safe to call
+ this function earlier.
+
+ If you are using the utility classes (like QString) but not using
+ QApplication, calling this function at the very end of your
+ application can be helpful to chasing down memory leaks, as
+ QTextCodec objects will not show up.
+*/
+
+void QTextCodec::deleteAllCodecs()
+{
+ if ( !all )
+ return;
+
+ destroying_is_ok = TRUE;
+ QInternalList<QTextCodec> * ball = all;
+ all = 0;
+ ball->clear();
+ delete ball;
+ destroying_is_ok = FALSE;
+}
+
+
+static void setupBuiltinCodecs();
+
+
+static void realSetup()
+{
+#if defined(CHECK_STATE)
+ if ( destroying_is_ok )
+ qWarning( "creating new codec during codec cleanup" );
+#endif
+ all = new QInternalList<QTextCodec>;
+ all->setAutoDelete( TRUE );
+ setupBuiltinCodecs();
+}
+
+
+static inline void setup()
+{
+ if ( !all )
+ realSetup();
+}
+
+
+class QTextStatelessEncoder: public QTextEncoder {
+ const QTextCodec* codec;
+public:
+ QTextStatelessEncoder(const QTextCodec*);
+ QCString fromUnicode(const QString& uc, int& lenInOut);
+};
+
+
+class QTextStatelessDecoder : public QTextDecoder {
+ const QTextCodec* codec;
+public:
+ QTextStatelessDecoder(const QTextCodec*);
+ QString toUnicode(const char* chars, int len);
+};
+
+QTextStatelessEncoder::QTextStatelessEncoder(const QTextCodec* c) :
+ codec(c)
+{
+}
+
+
+QCString QTextStatelessEncoder::fromUnicode(const QString& uc, int& lenInOut)
+{
+ return codec->fromUnicode(uc,lenInOut);
+}
+
+
+QTextStatelessDecoder::QTextStatelessDecoder(const QTextCodec* c) :
+ codec(c)
+{
+}
+
+
+QString QTextStatelessDecoder::toUnicode(const char* chars, int len)
+{
+ return codec->toUnicode(chars,len);
+}
+
+
+
+// NOT REVISED
+/*!
+ \class QTextCodec qtextcodec.h
+ \brief Provides conversion between text encodings.
+
+ By making objects of subclasses of QTextCodec, support for
+ new text encodings can be added to Qt.
+
+ The abstract virtual functions describe the encoder to the
+ system and the coder is used as required in the different
+ text file formats supported QTextStream and, under X11 for the
+ locale-specific character input and output (under Windows NT
+ codecs are not needed for GUI I/O since the system works
+ with Unicode already, and Windows 95/98 has built-in convertors
+ for the 8-bit local encoding).
+
+ More recently created QTextCodec objects take precedence
+ over earlier ones.
+
+ To add support for another 8-bit encoding to Qt, make a subclass
+ or QTextCodec and implement at least the following methods:
+ <dl>
+ <dt>\c const char* name() const
+ <dd>Return the official name for the encoding.
+ <dt>\c int mibEnum() const
+ <dd>Return the MIB enum for the encoding if it is listed in the
+ <a href=ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets>
+ IANA character-sets encoding file</a>.
+ </dl>
+ If the encoding is multi-byte then it will have "state"; that is,
+ the interpretation of some bytes will be dependent on some preceding
+ bytes. For such an encoding, you will need to implement
+ <dl>
+ <dt> \c QTextDecoder* makeDecoder() const
+ <dd>Return a QTextDecoder that remembers incomplete multibyte
+ sequence prefixes or other required state.
+ </dl>
+ If the encoding does \e not require state, you should implement:
+ <dl>
+ <dt> \c QString toUnicode(const char* chars, int len) const
+ <dd>Converts \e len characters from \e chars to Unicode.
+ </dl>
+ The base QTextCodec class has default implementations of the above
+ two functions, <i>but they are mutually recursive</i>, so you must
+ re-implement at least one of them, or both for improved efficiency.
+
+ For conversion from Unicode to 8-bit encodings, it is rarely necessary
+ to maintain state. However, two functions similar to the two above
+ are used for encoding:
+ <dl>
+ <dt> \c QTextEncoder* makeEncoder() const
+ <dd>Return a QTextDecoder.
+ <dt> \c QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+ <dd>Converts \e lenInOut characters (of type QChar) from the start
+ of the string \a uc, returning a QCString result, and also returning
+ the \link QCString::length() length\endlink
+ of the result in lenInOut.
+ </dl>
+ Again, these are mutually recursive so only one needs to be implemented,
+ or both if better efficiency is possible.
+
+ Finally, you must implement:
+ <dl>
+ <dt> \c int heuristicContentMatch(const char* chars, int len) const
+ <dd>Gives a value indicating how likely it is that \e len characters
+ from \e chars are in the encoding.
+ </dl>
+ A good model for this function is the
+ QWindowsLocalCodec::heuristicContentMatch function found in the Qt sources.
+
+ A QTextCodec subclass might have improved performance if you also
+ re-implement:
+ <dl>
+ <dt> \c bool canEncode( QChar ) const
+ <dd>Test if a Unicode character can be encoded.
+ <dt> \c bool canEncode( const QString& ) const
+ <dd>Test if a string of Unicode characters can be encoded.
+ <dt> \c int heuristicNameMatch(const char* hint) const
+ <dd>Test if a possibly non-standard name is referring to the codec.
+ </dl>
+*/
+
+
+/*!
+ Constructs a QTextCodec, making it of highest precedence.
+ The QTextCodec should always be constructed on the heap
+ (with new), and once constructed it becomes the responsibility
+ of Qt to delete it (which is done at QApplication destruction).
+*/
+QTextCodec::QTextCodec()
+{
+ setup();
+ all->insert(0,this);
+}
+
+
+/*!
+ Destructs the QTextCodec. Note that you should not delete
+ codecs yourself - once created they become the responsibility
+ of Qt to delete.
+*/
+QTextCodec::~QTextCodec()
+{
+ if ( !destroying_is_ok )
+ qWarning("QTextCodec::~QTextCodec() called by application");
+ if ( all )
+ all->remove( this );
+}
+
+
+/*!
+ Returns a value indicating how likely this decoder is
+ for decoding some format that has the given name.
+
+ A good match returns a positive number around
+ the length of the string. A bad match is negative.
+
+ The default implementation calls simpleHeuristicNameMatch()
+ with the name of the codec.
+*/
+int QTextCodec::heuristicNameMatch(const char* hint) const
+{
+ return simpleHeuristicNameMatch(name(),hint);
+}
+
+
+// returns a string cotnaining the letters and numbers from input,
+// with a space separating run of a character class. e.g. "iso8859-1"
+// becomes "iso 8859 1"
+static QString lettersAndNumbers( const char * input )
+{
+ QString result;
+ QChar c;
+
+ while( input && *input ) {
+ c = *input;
+ if ( c.isLetter() || c.isNumber() )
+ result += c.lower();
+ if ( input[1] ) {
+ // add space at character class transition, except
+ // transition from upper-case to lower-case letter
+ QChar n( input[1] );
+ if ( c.isLetter() && n.isLetter() ) {
+ if ( c == c.lower() && n == n.upper() )
+ result += ' ';
+ } else if ( c.category() != n.category() ) {
+ result += ' ';
+ }
+ }
+ input++;
+ }
+ return result.simplifyWhiteSpace();
+}
+
+/*!
+ A simple utility function for heuristicNameMatch() - it
+ does some very minor character-skipping
+ so that almost-exact matches score high.
+*/
+int QTextCodec::simpleHeuristicNameMatch(const char* name, const char* hint)
+{
+ // if they're the same, return a perfect score.
+ if ( name && hint && qstrcmp( name, hint ) == 0 )
+ return qstrlen( hint );
+
+ // if the letters and numbers are the same, we have an "almost"
+ // perfect match.
+ QString h( lettersAndNumbers( hint ) );
+ QString n( lettersAndNumbers( name ) );
+ if ( h == n )
+ return qstrlen( hint )-1;
+
+ if ( h.stripWhiteSpace() == n.stripWhiteSpace() )
+ return qstrlen( hint )-2;
+
+ // could do some more here, but I don't think it's worth it
+
+ return 0;
+}
+
+
+/*!
+ Returns the QTextCodec \a i places from the more recently
+ inserted, or NULL if there is no such QTextCodec. Thus,
+ codecForIndex(0) returns the most recently created QTextCodec.
+*/
+QTextCodec* QTextCodec::codecForIndex(int i)
+{
+ setup();
+ return (uint)i >= all->count() ? 0 : all->at(i);
+}
+
+
+/*!
+ Returns the QTextCodec which matches the
+ \link QTextCodec::mibEnum() MIBenum\endlink \a mib.
+*/
+QTextCodec* QTextCodec::codecForMib(int mib)
+{
+ setup();
+ QInternalListIterator<QTextCodec> i(*all);
+ QTextCodec* result;
+ for ( ; (result=i); ++i ) {
+ if ( result->mibEnum()==mib )
+ break;
+ }
+ return result;
+}
+
+
+
+
+
+#ifdef _OS_WIN32_
+class QWindowsLocalCodec: public QTextCodec
+{
+public:
+ QWindowsLocalCodec();
+ ~QWindowsLocalCodec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+QWindowsLocalCodec::QWindowsLocalCodec()
+{
+}
+
+QWindowsLocalCodec::~QWindowsLocalCodec()
+{
+}
+
+
+QString QWindowsLocalCodec::toUnicode(const char* chars, int len) const
+{
+ if ( len == 1 && chars ) { // Optimization; avoids allocation
+ char c[2];
+ c[0] = *chars;
+ c[1] = 0;
+ return qt_winMB2QString( c, 2 );
+ }
+ if ( len < 0 )
+ return qt_winMB2QString( chars );
+ QCString s(chars,len+1);
+ return qt_winMB2QString(s);
+}
+
+QCString QWindowsLocalCodec::fromUnicode(const QString& uc, int& lenInOut ) const
+{
+ QCString r = qt_winQString2MB( uc, lenInOut );
+ lenInOut = r.length();
+ return r;
+}
+
+
+const char* QWindowsLocalCodec::name() const
+{
+ return "System";
+}
+
+int QWindowsLocalCodec::mibEnum() const
+{
+ return 0;
+}
+
+
+int QWindowsLocalCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ // ### Not a bad default implementation?
+ QString t = toUnicode(chars,len);
+ int l = t.length();
+ QCString mb = fromUnicode(t,l);
+ int i=0;
+ while ( i < len )
+ if ( chars[i] == mb[i] )
+ i++;
+ return i;
+}
+
+#else
+
+/* locale names mostly copied from XFree86 */
+static const char * const iso8859_2locales[] = {
+ "croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
+ "hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
+ "ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
+ "sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
+
+static const char * const iso8859_3locales[] = {
+ "eo", 0 };
+
+static const char * const iso8859_4locales[] = {
+ "ee", "ee_EE", "lt", "lt_LT", "lv", "lv_LV", 0 };
+
+static const char * const iso8859_5locales[] = {
+ "bg", "bg_BG", "bulgarian", "mk", "mk_MK",
+ "sp", "sp_YU", 0 };
+
+static const char * const iso8859_6locales[] = {
+ "ar_AA", "ar_SA", "arabic", 0 };
+
+static const char * const iso8859_7locales[] = {
+ "el", "el_GR", "greek", 0 };
+
+static const char * const iso8859_8locales[] = {
+ "hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
+
+static const char * const iso8859_9locales[] = {
+ "tr", "tr_TR", "turkish", 0 };
+
+static const char * const iso8859_15locales[] = {
+ "fr", "fi", "french", "finnish", "et", "et_EE", 0 };
+
+static const char * const koi8_ulocales[] = {
+ "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
+
+static const char * const tis_620locales[] = {
+ "th", "th_TH", "thai", 0 };
+
+
+static bool try_locale_list( const char * const locale[], const char * lang )
+{
+ int i;
+ for( i=0; locale[i] && qstrcmp(locale[i], lang); i++ )
+ { }
+ return locale[i] != 0;
+}
+
+// For the probably_koi8_locales we have to look. the standard says
+// these are 8859-5, but almsot all Russion users uses KOI8-R and
+// incorrectly set $LANG to ru_RU. We'll check tolower() to see what
+// tolower() thinks ru_RU means.
+
+// If you read the history, it seems that many Russians blame ISO and
+// Peristroika for the confusion.
+//
+// The real bug is that some programs break if the user specifies
+// ru_RU.KOI8-R.
+
+static const char * const probably_koi8_rlocales[] = {
+ "ru", "ru_SU", "ru_RU", "russian", 0 };
+
+// this means ANY of these locale aliases. if they're aliases for
+// different locales, the code breaks.
+static QTextCodec * ru_RU_codec = 0;
+
+static QTextCodec * ru_RU_hack( const char * i ) {
+ if ( ! ru_RU_codec ) {
+ QCString origlocale = setlocale( LC_CTYPE, i );
+ // unicode koi8r latin5 name
+ // 0x044E 0xC0 0xEE CYRILLIC SMALL LETTER YU
+ // 0x042E 0xE0 0xCE CYRILLIC CAPITAL LETTER YU
+ int latin5 = tolower( 0xCE );
+ int koi8r = tolower( 0xE0 );
+ if ( koi8r == 0xC0 && latin5 != 0xEE ) {
+ ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
+ } else if ( koi8r != 0xC0 && latin5 == 0xEE ) {
+ ru_RU_codec = QTextCodec::codecForName( "ISO 8859-5" );
+ } else {
+ // something else again... let's assume... *throws dice*
+ ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
+ qWarning( "QTextCodec: using KOI8-R, probe failed (%02x %02x %s)",
+ koi8r, latin5, i );
+ }
+ setlocale( LC_CTYPE, origlocale.data() );
+ }
+ return ru_RU_codec;
+}
+
+#endif
+
+static QTextCodec * localeMapper = 0;
+
+void qt_set_locale_codec( QTextCodec *codec )
+{
+ localeMapper = codec;
+}
+
+/*! Returns a pointer to the codec most suitable for this locale. */
+
+QTextCodec* QTextCodec::codecForLocale()
+{
+ if ( localeMapper )
+ return localeMapper;
+
+ setup();
+
+#ifdef _OS_WIN32_
+ localeMapper = new QWindowsLocalCodec;
+#else
+ // Very poorly defined and followed standards causes lots of code
+ // to try to get all the cases...
+
+ char * lang = qstrdup( getenv("LANG") );
+
+ char * p = lang ? strchr( lang, '.' ) : 0;
+ if ( !p || *p != '.' ) {
+ // Some versions of setlocale return encoding, others not.
+ char *ctype = qstrdup( setlocale( LC_CTYPE, 0 ) );
+ // Some Linux distributions have broken locales which will return
+ // "C" for LC_CTYPE
+ if ( qstrcmp( ctype, "C" ) == 0 ) {
+ delete [] ctype;
+ } else {
+ if ( lang )
+ delete [] lang;
+ lang = ctype;
+ p = lang ? strchr( lang, '.' ) : 0;
+ }
+ }
+
+ if( p && *p == '.' ) {
+ // if there is an encoding and we don't know it, we return 0
+ // User knows what they are doing. Codecs will believe them.
+ localeMapper = codecForName( lang );
+ if ( !localeMapper ) {
+ // Use or codec disagree.
+ localeMapper = codecForName( p+1 );
+ }
+ }
+ if ( !localeMapper || !(p && *p == '.') ) {
+ // if there is none, we default to 8859-1
+ // We could perhaps default to 8859-15.
+ if ( try_locale_list( iso8859_2locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-2" );
+ else if ( try_locale_list( iso8859_3locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-3" );
+ else if ( try_locale_list( iso8859_4locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-4" );
+ else if ( try_locale_list( iso8859_5locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-5" );
+ else if ( try_locale_list( iso8859_6locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-6-I" );
+ else if ( try_locale_list( iso8859_7locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-7" );
+ else if ( try_locale_list( iso8859_8locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-8-I" );
+ else if ( try_locale_list( iso8859_9locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-9" );
+ else if ( try_locale_list( iso8859_15locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-15" );
+ else if ( try_locale_list( tis_620locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-11" );
+ else if ( try_locale_list( koi8_ulocales, lang ) )
+ localeMapper = codecForName( "KOI8-U" );
+ else if ( try_locale_list( probably_koi8_rlocales, lang ) )
+ localeMapper = ru_RU_hack( lang );
+ else if (!lang || !(localeMapper = codecForName(lang) ))
+ localeMapper = codecForName( "ISO 8859-1" );
+ }
+ delete[] lang;
+#endif
+
+ return localeMapper;
+}
+
+
+/*!
+ Searches all installed QTextCodec objects, returning the one
+ which best matches given name. Returns NULL if no codec has
+ a match closeness above \a accuracy.
+
+ \sa heuristicNameMatch()
+*/
+QTextCodec* QTextCodec::codecForName(const char* hint, int accuracy)
+{
+ setup();
+ QInternalListIterator<QTextCodec> i(*all);
+ QTextCodec* result = 0;
+ int best=accuracy;
+ for ( QTextCodec* cursor; (cursor=i); ++i ) {
+ int s = cursor->heuristicNameMatch(hint);
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+ return result;
+}
+
+
+/*!
+ Searches all installed QTextCodec objects, returning the one
+ which most recognizes the given content. May return 0.
+
+ Note that this is often a poor choice, since character
+ encodings often use most of the available character sequences,
+ and so only by linguistic analysis could a true match be made.
+
+ \sa heuristicContentMatch()
+*/
+QTextCodec* QTextCodec::codecForContent(const char* chars, int len)
+{
+ setup();
+ QInternalListIterator<QTextCodec> i(*all);
+ QTextCodec* result = 0;
+ int best=0;
+ for ( QTextCodec* cursor; (cursor=i); ++i ) {
+ int s = cursor->heuristicContentMatch(chars,len);
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+ return result;
+}
+
+
+/*!
+ \fn const char* QTextCodec::name() const
+ Subclasses of QTextCodec must reimplement this function. It returns
+ the name of the encoding supported by the subclass. When choosing
+ a name for an encoding, consider these points:
+ <ul>
+ <li>On X11, heuristicNameMatch( const char * hint )
+ is used to test if a the QTextCodec
+ can convert between Unicode and the encoding of a font
+ with encoding \e hint, such as "iso8859-1" for Latin-1 fonts,
+ "koi8-r" for Russian KOI8 fonts.
+ The default algorithm of heuristicNameMatch() uses name().
+ <li>Some applications may use this function to present
+ encodings to the end user.
+ </ul>
+*/
+
+/*!
+ \fn int QTextCodec::mibEnum() const
+
+ Subclasses of QTextCodec must reimplement this function. It returns the
+ MIBenum (see
+ <a href="ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets">
+ the IANA character-sets encoding file</a> for more information).
+ It is important that each QTextCodec subclass return the correct unique
+ value for this function.
+*/
+
+
+/*!
+ \fn int QTextCodec::heuristicContentMatch(const char* chars, int len) const
+
+ Subclasses of QTextCodec must reimplement this function. It examines
+ the first \a len bytes of \a chars and returns a value indicating how
+ likely it is that the string is a prefix of text encoded in the
+ encoding of the subclass. Any negative return value indicates that the text
+ is detectably not in the encoding (eg. it contains undefined characters).
+ A return value of 0 indicates that the text should be decoded with this
+ codec rather than as ASCII, but there
+ is no particular evidence. The value should range up to \a len. Thus,
+ most decoders will return -1, 0, or -\a len.
+
+ The characters are not null terminated.
+
+ \sa codecForContent().
+*/
+
+
+/*!
+ Creates a QTextDecoder which stores enough state to decode chunks
+ of char* data to create chunks of Unicode data. The default implementation
+ creates a stateless decoder, which is sufficient for only the simplest
+ encodings where each byte corresponds to exactly one Unicode character.
+
+ The caller is responsible for deleting the returned object.
+*/
+QTextDecoder* QTextCodec::makeDecoder() const
+{
+ return new QTextStatelessDecoder(this);
+}
+
+
+/*!
+ Creates a QTextEncoder which stores enough state to encode chunks
+ of Unicode data as char* data. The default implementation
+ creates a stateless encoder, which is sufficient for only the simplest
+ encodings where each Unicode character corresponds to exactly one char.
+
+ The caller is responsible for deleting the returned object.
+*/
+QTextEncoder* QTextCodec::makeEncoder() const
+{
+ return new QTextStatelessEncoder(this);
+}
+
+
+/*!
+ Subclasses of QTextCodec must reimplement this function or
+ makeDecoder(). It converts the first \a len characters of \a chars
+ to Unicode.
+
+ The default implementation makes a decoder with makeDecoder() and
+ converts the input with that. Note that the default makeDecoder()
+ implementation makes a decoder that simply calls
+ this function, hence subclasses \e must reimplement one function or
+ the other to avoid infinite recursion.
+*/
+QString QTextCodec::toUnicode(const char* chars, int len) const
+{
+ QTextDecoder* i = makeDecoder();
+ QString result = i->toUnicode(chars,len);
+ delete i;
+ return result;
+}
+
+
+/*!
+ Subclasses of QTextCodec must reimplement either this function or
+ makeEncoder(). It converts the first \a lenInOut characters of \a
+ uc from Unicode to the encoding of the subclass. If \a lenInOut
+ is negative or too large, the length of \a uc is used instead.
+
+ The value returned is the property of the caller, which is
+ responsible for deleting it with "delete []". The length of the
+ resulting Unicode character sequence is returned in \a lenInOut.
+
+ The default implementation makes an encoder with makeEncoder() and
+ converts the input with that. Note that the default makeEncoder()
+ implementation makes an encoder that simply calls
+ this function, hence subclasses \e must reimplement one function or
+ the other to avoid infinite recursion.
+*/
+
+QCString QTextCodec::fromUnicode(const QString& uc, int& lenInOut) const
+{
+ QTextEncoder* i = makeEncoder();
+ QCString result = i->fromUnicode(uc, lenInOut);
+ delete i;
+ return result;
+}
+
+/*!
+ \overload QCString QTextCodec::fromUnicode(const QString& uc) const
+*/
+QCString QTextCodec::fromUnicode(const QString& uc) const
+{
+ int l = uc.length();
+ return fromUnicode(uc,l);
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const QByteArray& a, int len) const
+*/
+QString QTextCodec::toUnicode(const QByteArray& a, int len) const
+{
+ int l = a.size();
+ if( l > 0 && a.data()[l - 1] == '\0' ) l--;
+ l = QMIN( l, len );
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const QByteArray& a) const
+*/
+QString QTextCodec::toUnicode(const QByteArray& a) const
+{
+ int l = a.size();
+ if( l > 0 && a.data()[l - 1] == '\0' ) l--;
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const char* chars) const
+*/
+QString QTextCodec::toUnicode(const char* chars) const
+{
+ return toUnicode(chars,qstrlen(chars));
+}
+
+/*!
+ Returns TRUE if the unicode character \a ch can be fully encoded
+ with this codec. The default implementation tests if the result of
+ toUnicode(fromUnicode(ch)) is the original \a ch. Subclasses may be
+ able to improve the efficiency.
+*/
+bool QTextCodec::canEncode( QChar ch ) const
+{
+ return toUnicode(fromUnicode(ch)) == ch;
+}
+
+/*!
+ Returns TRUE if the unicode string \a s can be fully encoded
+ with this codec. The default implementation tests if the result of
+ toUnicode(fromUnicode(s)) is the original \a s. Subclasses may be
+ able to improve the efficiency.
+*/
+bool QTextCodec::canEncode( const QString& s ) const
+{
+ return toUnicode(fromUnicode(s)) == s;
+}
+
+
+
+/*!
+ \class QTextEncoder qtextcodec.h
+ \brief State-based encoder
+
+ A QTextEncoder converts Unicode into another format, remembering
+ any state that is required between calls.
+
+ \sa QTextCodec::makeEncoder()
+*/
+
+/*!
+ Destructs the encoder.
+*/
+QTextEncoder::~QTextEncoder()
+{
+}
+/*!
+ \fn QCString QTextEncoder::fromUnicode(const QString& uc, int& lenInOut)
+
+ Converts \a lenInOut characters (not bytes) from \a uc, producing
+ a QCString. \a lenInOut will also be set to the
+ \link QCString::length() length\endlink of the result (in bytes).
+
+ The encoder is free to record state to use when subsequent calls are
+ made to this function (for example, it might change modes with escape
+ sequences if needed during the encoding of one string, then assume that
+ mode applies when a subsequent call begins).
+*/
+
+/*!
+ \class QTextDecoder qtextcodec.h
+ \brief State-based decoder
+
+ A QTextEncoder converts a text format into Unicode, remembering
+ any state that is required between calls.
+
+ \sa QTextCodec::makeEncoder()
+*/
+
+
+/*!
+ Destructs the decoder.
+*/
+QTextDecoder::~QTextDecoder()
+{
+}
+
+/*!
+ \fn QString QTextDecoder::toUnicode(const char* chars, int len)
+
+ Converts the first \a len bytes at \a chars to Unicode, returning the
+ result.
+
+ If not all characters are used (eg. only part of a multi-byte
+ encoding is at the end of the characters), the decoder remembers
+ enough state to continue with the next call to this function.
+*/
+
+#define CHAINED 0xffff
+
+struct QMultiByteUnicodeTable {
+ // If multibyte, ignore unicode and index into multibyte
+ // with the next character.
+ QMultiByteUnicodeTable() : unicode(0xfffd), multibyte(0) { }
+
+ ~QMultiByteUnicodeTable()
+ {
+ if ( multibyte )
+ delete [] multibyte;
+ }
+
+ ushort unicode;
+ QMultiByteUnicodeTable* multibyte;
+};
+
+#ifndef QT_NO_CODECS
+static int getByte(char* &cursor)
+{
+ int byte = 0;
+ if ( *cursor ) {
+ if ( cursor[1] == 'x' )
+ byte = (int)strtol(cursor+2,&cursor,16);
+ else if ( cursor[1] == 'd' )
+ byte = (int)strtol(cursor+2,&cursor,10);
+ else
+ byte = (int)strtol(cursor+2,&cursor,8);
+ }
+ return byte&0xff;
+}
+
+class QTextCodecFromIOD;
+
+class QTextCodecFromIODDecoder : public QTextDecoder {
+ const QTextCodecFromIOD* codec;
+ QMultiByteUnicodeTable* mb;
+public:
+ QTextCodecFromIODDecoder(const QTextCodecFromIOD* c);
+ QString toUnicode(const char* chars, int len);
+};
+
+class QTextCodecFromIOD : public QTextCodec {
+ friend class QTextCodecFromIODDecoder;
+
+ QCString n;
+
+ // If from_unicode_page[row()][cell()] is 0 and from_unicode_page_multibyte,
+ // use from_unicode_page_multibyte[row()][cell()] as string.
+ char** from_unicode_page;
+ char*** from_unicode_page_multibyte;
+ char unkn;
+
+ // Only one of these is used
+ ushort* to_unicode;
+ QMultiByteUnicodeTable* to_unicode_multibyte;
+ int max_bytes_per_char;
+ QStrList aliases;
+
+ bool stateless() const { return !to_unicode_multibyte; }
+
+public:
+ QTextCodecFromIOD(QIODevice* iod)
+ {
+ from_unicode_page = 0;
+ to_unicode_multibyte = 0;
+ to_unicode = 0;
+ from_unicode_page_multibyte = 0;
+ max_bytes_per_char = 1;
+
+ const int maxlen=100;
+ char line[maxlen];
+ char esc='\\';
+ char comm='%';
+ bool incmap = FALSE;
+ while (iod->readLine(line,maxlen) > 0) {
+ if (0==qstrnicmp(line,"<code_set_name>",15))
+ n = line+15;
+ else if (0==qstrnicmp(line,"<escape_char> ",14))
+ esc = line[14];
+ else if (0==qstrnicmp(line,"<comment_char> ",15))
+ comm = line[15];
+ else if (line[0]==comm && 0==qstrnicmp(line+1," alias ",7)) {
+ aliases.append(line+8);
+ } else if (0==qstrnicmp(line,"CHARMAP",7)) {
+ if (!from_unicode_page) {
+ from_unicode_page = new char*[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page[i]=0;
+ }
+ if (!to_unicode) {
+ to_unicode = new ushort[256];
+ }
+ incmap = TRUE;
+ } else if (0==qstrnicmp(line,"END CHARMAP",11))
+ break;
+ else if (incmap) {
+ char* cursor = line;
+ int byte=0,unicode=-1;
+ ushort* mb_unicode=0;
+ const int maxmb=8; // more -> we'll need to improve datastructures
+ char mb[maxmb+1];
+ int nmb=0;
+
+ while (*cursor) {
+ if (cursor[0]=='<' && cursor[1]=='U' &&
+ cursor[2]>='0' && cursor[2]<='9' &&
+ cursor[3]>='0' && cursor[3]<='9') {
+
+ unicode = (int)strtol(cursor+2,&cursor,16);
+
+ } else if (*cursor==esc) {
+
+ byte = getByte(cursor);
+
+ if ( *cursor == esc ) {
+ if ( !to_unicode_multibyte ) {
+ to_unicode_multibyte =
+ new QMultiByteUnicodeTable[256];
+ for (int i=0; i<256; i++) {
+ to_unicode_multibyte[i].unicode =
+ to_unicode[i];
+ to_unicode_multibyte[i].multibyte = 0;
+ }
+ delete [] to_unicode;
+ to_unicode = 0;
+ }
+ QMultiByteUnicodeTable* mbut =
+ to_unicode_multibyte+byte;
+ mb[nmb++] = byte;
+ while ( nmb < maxmb && *cursor == esc ) {
+ // Always at least once
+
+ mbut->unicode = CHAINED;
+ byte = getByte(cursor);
+ mb[nmb++] = byte;
+ if (!mbut->multibyte) {
+ mbut->multibyte =
+ new QMultiByteUnicodeTable[256];
+ }
+ mbut = mbut->multibyte+byte;
+ mb_unicode = & mbut->unicode;
+ }
+
+ if ( nmb > max_bytes_per_char )
+ max_bytes_per_char = nmb;
+ }
+ } else {
+ cursor++;
+ }
+ }
+
+ if (unicode >= 0 && unicode <= 0xffff)
+ {
+ QChar ch((ushort)unicode);
+ if (!from_unicode_page[ch.row()]) {
+ from_unicode_page[ch.row()] = new char[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page[ch.row()][i]=0;
+ }
+ if ( mb_unicode ) {
+ from_unicode_page[ch.row()][ch.cell()] = 0;
+ if (!from_unicode_page_multibyte) {
+ from_unicode_page_multibyte = new char**[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page_multibyte[i]=0;
+ }
+ if (!from_unicode_page_multibyte[ch.row()]) {
+ from_unicode_page_multibyte[ch.row()] = new char*[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page_multibyte[ch.row()][i] = 0;
+ }
+ mb[nmb++] = 0;
+ from_unicode_page_multibyte[ch.row()][ch.cell()]
+ = qstrdup(mb);
+ *mb_unicode = unicode;
+ } else {
+ from_unicode_page[ch.row()][ch.cell()] = (char)byte;
+ if ( to_unicode )
+ to_unicode[byte] = unicode;
+ else
+ to_unicode_multibyte[byte].unicode = unicode;
+ }
+ } else {
+ }
+ }
+ }
+ n = n.stripWhiteSpace();
+
+ unkn = '?'; // ##### Might be a bad choice.
+ }
+
+ ~QTextCodecFromIOD()
+ {
+ if ( from_unicode_page ) {
+ for (int i=0; i<256; i++)
+ if (from_unicode_page[i])
+ delete [] from_unicode_page[i];
+ }
+ if ( from_unicode_page_multibyte ) {
+ for (int i=0; i<256; i++)
+ if (from_unicode_page_multibyte[i])
+ for (int j=0; j<256; j++)
+ if (from_unicode_page_multibyte[i][j])
+ delete [] from_unicode_page_multibyte[i][j];
+ }
+ if ( to_unicode )
+ delete [] to_unicode;
+ if ( to_unicode_multibyte )
+ delete [] to_unicode_multibyte;
+ }
+
+ bool ok() const
+ {
+ return !!from_unicode_page;
+ }
+
+ QTextDecoder* makeDecoder() const
+ {
+ if ( stateless() )
+ return QTextCodec::makeDecoder();
+ else
+ return new QTextCodecFromIODDecoder(this);
+ }
+
+ const char* name() const
+ {
+ return n;
+ }
+
+ int mibEnum() const
+ {
+ return 0; // #### Unknown.
+ }
+
+ int heuristicContentMatch(const char*, int) const
+ {
+ return 0;
+ }
+
+ int heuristicNameMatch(const char* hint) const
+ {
+ int bestr = QTextCodec::heuristicNameMatch(hint);
+ QStrListIterator it(aliases);
+ char* a;
+ while ((a=it.current())) {
+ ++it;
+ int r = simpleHeuristicNameMatch(a,hint);
+ if (r > bestr)
+ bestr = r;
+ }
+ return bestr;
+ }
+
+ QString toUnicode(const char* chars, int len) const
+ {
+ const uchar* uchars = (const uchar*)chars;
+ QString result;
+ QMultiByteUnicodeTable* multibyte=to_unicode_multibyte;
+ if ( multibyte ) {
+ while (len--) {
+ QMultiByteUnicodeTable& mb = multibyte[*uchars];
+ if ( mb.multibyte ) {
+ // Chained multi-byte
+ multibyte = mb.multibyte;
+ } else {
+ result += QChar(mb.unicode);
+ multibyte=to_unicode_multibyte;
+ }
+ uchars++;
+ }
+ } else {
+ while (len--)
+ result += QChar(to_unicode[*uchars++]);
+ }
+ return result;
+ }
+
+ QCString fromUnicode(const QString& uc, int& lenInOut) const
+ {
+ if (lenInOut > (int)uc.length())
+ lenInOut = uc.length();
+ int rlen = lenInOut*max_bytes_per_char;
+ QCString rstr(rlen);
+ char* cursor = rstr.data();
+ char* s=0;
+ int l = lenInOut;
+ int lout = 0;
+ for (int i=0; i<l; i++) {
+ QChar ch = uc[i];
+ if ( ch == QChar::null ) {
+ // special
+ *cursor++ = 0;
+ } else if ( from_unicode_page[ch.row()] &&
+ from_unicode_page[ch.row()][ch.cell()] )
+ {
+ *cursor++ = from_unicode_page[ch.row()][ch.cell()];
+ lout++;
+ } else if ( from_unicode_page_multibyte &&
+ from_unicode_page_multibyte[ch.row()] &&
+ (s=from_unicode_page_multibyte[ch.row()][ch.cell()]) )
+ {
+ while (*s) {
+ *cursor++ = *s++;
+ lout++;
+ }
+ } else {
+ *cursor++ = unkn;
+ lout++;
+ }
+ }
+ *cursor = 0;
+ lenInOut = lout;
+ return rstr;
+ }
+};
+
+QTextCodecFromIODDecoder::QTextCodecFromIODDecoder(const QTextCodecFromIOD* c) :
+ codec(c)
+{
+ mb = codec->to_unicode_multibyte;
+}
+
+QString QTextCodecFromIODDecoder::toUnicode(const char* chars, int len)
+{
+ const uchar* uchars = (const uchar*)chars;
+ QString result;
+ while (len--) {
+ QMultiByteUnicodeTable& t = mb[*uchars];
+ if ( t.multibyte ) {
+ // Chained multi-byte
+ mb = t.multibyte;
+ } else {
+ if ( t.unicode )
+ result += QChar(t.unicode);
+ mb=codec->to_unicode_multibyte;
+ }
+ uchars++;
+ }
+ return result;
+}
+
+/*!
+ Reads a POSIX2 charmap definition from \a iod.
+ The parser recognizes the following lines:
+<pre>
+ <code_set_name> <i>name</i>
+ <escape_char> <i>character</i>
+ % alias <i>alias</i>
+ CHARMAP
+ <<i>token</i>> /x<i>hexbyte</i> <U<i>unicode</i>> ...
+ <<i>token</i>> /d<i>decbyte</i> <U<i>unicode</i>> ...
+ <<i>token</i>> /<i>octbyte</i> <U<i>unicode</i>> ...
+ <<i>token</i>> /<i>any</i>/<i>any</i>... <U<i>unicode</i>> ...
+ END CHARMAP
+</pre>
+
+ The resulting QTextCodec is returned (and also added to the
+ global list of codecs). The name() of the result is taken
+ from the code_set_name.
+
+ Note that a codec constructed in this way uses much more memory
+ and is slower than a hand-written QTextCodec subclass, since
+ tables in code are in memory shared by all applications simultaneously
+ using Qt.
+
+ \sa loadCharmapFile()
+*/
+QTextCodec* QTextCodec::loadCharmap(QIODevice* iod)
+{
+ QTextCodecFromIOD* r = new QTextCodecFromIOD(iod);
+ if ( !r->ok() ) {
+ delete r;
+ r = 0;
+ }
+ return r;
+}
+
+/*!
+ A convenience function for loadCharmap().
+*/
+QTextCodec* QTextCodec::loadCharmapFile(QString filename)
+{
+ QFile f(filename);
+ if (f.open(IO_ReadOnly)) {
+ QTextCodecFromIOD* r = new QTextCodecFromIOD(&f);
+ if ( !r->ok() )
+ delete r;
+ else
+ return r;
+ }
+ return 0;
+}
+#endif //QT_NO_CODECS
+
+
+/*!
+ Returns a string representing the current language.
+*/
+
+const char* QTextCodec::locale()
+{
+ static QCString lang;
+ if ( lang.isEmpty() ) {
+ lang = getenv( "LANG" ); //########Windows??
+ if ( lang.isEmpty() )
+ lang = "C";
+ }
+ return lang;
+}
+
+
+
+#ifndef QT_NO_CODECS
+
+class QSimpleTextCodec: public QTextCodec
+{
+public:
+ QSimpleTextCodec( int );
+ ~QSimpleTextCodec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ int heuristicNameMatch(const char* hint) const;
+
+private:
+ int forwardIndex;
+};
+
+
+#define LAST_MIB 2259
+
+static struct {
+ const char * cs;
+ int mib;
+ Q_UINT16 values[128];
+} unicodevalues[] = {
+ // from RFC 1489, ftp://ftp.isi.edu/in-notes/rfc1489.txt
+ { "KOI8-R", 2084,
+ { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219/**/, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+ // /**/ - The BULLET OPERATOR is confused. Some people think
+ // it should be 0x2022 (BULLET).
+
+ // from RFC 2319, ftp://ftp.isi.edu/in-notes/rfc2319.txt
+ { "KOI8-U", 2088,
+ { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+
+ // next bits generated from tables on the Unicode 2.0 CD. we can
+ // use these tables since this is part of the transition to using
+ // unicode everywhere in qt.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo 0x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; for a in 8859-* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ; cat /tmp/digits ) | sort | uniq -w4 | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ // then I inserted the files manually.
+ { "ISO 8859-2", 5,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
+ 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
+ 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
+ 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "ISO 8859-3", 6,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7,
+ 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B,
+ 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
+ 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C,
+ 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
+ 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
+ 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9} },
+ { "ISO 8859-4", 7,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
+ 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
+ 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
+ 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
+ 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
+ 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9} },
+ { "ISO 8859-5", 8,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F} },
+ { "ISO 8859-6-I", 82,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F,
+ 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+ 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+ 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
+ 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO 8859-7", 10,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "ISO 8859-8-I", 85,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO 8859-9", 12,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "ISO 8859-10", 13,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
+ 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
+ 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
+ 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138} },
+ { "ISO 8859-13", 109,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019} },
+ { "ISO 8859-14", 110,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7,
+ 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
+ 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56,
+ 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF} },
+ { "ISO 8859-15", 111,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
+ 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
+ 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+
+ // next bits generated again from tables on the Unicode 3.0 CD.
+
+ // $ for a in CP* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ) | sort | sed -e 's/#UNDEF.*$/0xFFFD/' | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ { "CP 874", 0, //### what is the mib?
+ { 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2026, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "CP 1250", 2250,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
+ 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
+ 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "CP 1251", 2251,
+ { 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+ 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+ 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
+ 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+ 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
+ 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F} },
+ { "CP 1252", 2252,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+ { "CP 1253", 2253,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "CP 1254", 2254,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "CP 1255", 2255,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+ 0x05B8, 0x05B9, 0xFFFD, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
+ 0x05F4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD} },
+ { "CP 1256", 2256,
+ { 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+ 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
+ 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
+ 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
+ 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
+ 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
+ 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
+ 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2} },
+ { "CP 1257", 2257,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0x00A8, 0x02C7, 0x00B8,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0x00AF, 0x02DB, 0xFFFD,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9} },
+ { "CP 1258", 2258,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+ 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+ 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF} },
+
+ // this one is generated from the charmap file located in /usr/share/i18n/charmaps
+ // on most Linux distributions. The thai character set tis620 is byte by byte equivalent
+ // to iso8859-11, so we name it 8859-11 here, but recognise the name tis620 too.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; ( cut -c25- < TIS-620 ; cat /tmp/digits ) | awk '/^x[89ABCDEF]/{ print $1, $2 }' | sed -e 's/<U/0x/' -e 's/>//' | sort | uniq -w4 | cut -c5- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/tis-620
+ { "ISO 8859-11", 2259, // Thai character set mib enum taken from tis620 (which is byte by byte equivalent)
+ { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+
+ // change LAST_MIB if you add more, and edit unicodevalues in
+ // kernel/qpsprinter.cpp too.
+};
+
+
+static const QSimpleTextCodec * reverseOwner = 0;
+static QArray<char> * reverseMap = 0;
+
+
+QSimpleTextCodec::QSimpleTextCodec( int i )
+ : QTextCodec(), forwardIndex( i )
+{
+}
+
+
+QSimpleTextCodec::~QSimpleTextCodec()
+{
+ if ( reverseOwner == this ) {
+ delete reverseMap;
+ reverseMap = 0;
+ reverseOwner = 0;
+ }
+}
+
+// what happens if strlen(chars)<len? what happens if !chars? if len<1?
+QString QSimpleTextCodec::toUnicode(const char* chars, int len) const
+{
+ if(len <= 0)
+ return QString::null;
+
+ int clen = qstrlen(chars);
+ len = QMIN(len, clen); // Note: NUL ends string
+
+ QString r;
+ r.setUnicode(0, len);
+ QChar* uc = (QChar*)r.unicode(); // const_cast
+ const unsigned char * c = (const unsigned char *)chars;
+ for( int i=0; i<len; i++ ) {
+ if ( c[i] > 127 )
+ uc[i] = unicodevalues[forwardIndex].values[c[i]-128];
+ else
+ uc[i] = c[i];
+ }
+ return r;
+}
+
+
+QCString QSimpleTextCodec::fromUnicode(const QString& uc, int& len ) const
+{
+ if ( reverseOwner != this ) {
+ int m = 0;
+ int i = 0;
+ while( i < 128 ) {
+ if ( unicodevalues[forwardIndex].values[i] > m &&
+ unicodevalues[forwardIndex].values[i] < 0xfffd )
+ m = unicodevalues[forwardIndex].values[i];
+ i++;
+ }
+ m++;
+ if ( !reverseMap )
+ reverseMap = new QArray<char>( m );
+ if ( m > (int)(reverseMap->size()) )
+ reverseMap->resize( m );
+ for( i = 0; i < 128 && i < m; i++ )
+ (*reverseMap)[i] = (char)i;
+ for( ;i < m; i++ )
+ (*reverseMap)[i] = '?';
+ for( i=128; i<256; i++ ) {
+ int u = unicodevalues[forwardIndex].values[i-128];
+ if ( u < m )
+ (*reverseMap)[u] = (char)(unsigned char)(i);
+ }
+ reverseOwner = this;
+ }
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ QCString r( len+1 );
+ int i = len;
+ int u;
+ const QChar* ucp = uc.unicode();
+ char* rp = r.data();
+ char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ while( i-- )
+ {
+ u = ucp->unicode();
+ *rp++ = u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : '?' );
+ ucp++;
+ }
+ r[len] = 0;
+ return r;
+}
+
+
+const char* QSimpleTextCodec::name() const
+{
+ return unicodevalues[forwardIndex].cs;
+}
+
+
+int QSimpleTextCodec::mibEnum() const
+{
+ return unicodevalues[forwardIndex].mib;
+}
+
+int QSimpleTextCodec::heuristicNameMatch(const char* hint) const
+{
+ if ( hint[0]=='k' ) {
+ // Help people with messy fonts
+ if ( QCString(hint) == "koi8-1" )
+ return QTextCodec::heuristicNameMatch("koi8-r")-1;
+ if ( QCString(hint) == "koi8-ru" )
+ return QTextCodec::heuristicNameMatch("koi8-r")-1;
+ } else if ( hint[0] == 't' && QCString(name()) == "ISO 8859-11" ) {
+ // 8859-11 and tis620 are byte by bute equivalent
+ int i = simpleHeuristicNameMatch("tis620-0", hint);
+ if( !i )
+ i = simpleHeuristicNameMatch("tis-620", hint);
+ if( i ) return i;
+ }
+ return QTextCodec::heuristicNameMatch(hint);
+}
+
+int QSimpleTextCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 128 ) {
+ if ( unicodevalues[forwardIndex].values[(*c)-128] == 0xfffd )
+ return -1;
+ }
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ if ( mibEnum()==4 )
+ r+=1;
+ return r;
+}
+
+
+#endif // QT_NO_CODECS
+
+class QLatin1Codec: public QTextCodec
+{
+public:
+ QLatin1Codec();
+ ~QLatin1Codec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ int heuristicNameMatch(const char* hint) const;
+
+private:
+ //int forwardIndex;
+};
+
+
+QLatin1Codec::QLatin1Codec()
+ : QTextCodec()
+{
+}
+
+
+QLatin1Codec::~QLatin1Codec()
+{
+}
+
+// what happens if strlen(chars)<len? what happens if !chars? if len<1?
+QString QLatin1Codec::toUnicode(const char* chars, int len) const
+{
+ if(len <= 0)
+ return QString::null;
+
+ return QString::fromLatin1(chars, len);
+}
+
+
+QCString QLatin1Codec::fromUnicode(const QString& uc, int& len ) const
+{
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ QCString r( len+1 );
+ int i = 0;
+ const QChar *ch = uc.unicode();
+ while ( i < len ) {
+ r[i] = ch->row() ? '?' : ch->cell();
+ i++;
+ ch++;
+ }
+ r[len] = 0;
+ return r;
+}
+
+
+const char* QLatin1Codec::name() const
+{
+ return "ISO 8859-1";
+}
+
+
+int QLatin1Codec::mibEnum() const
+{
+ return 4;
+}
+
+int QLatin1Codec::heuristicNameMatch(const char* hint) const
+{
+ return QTextCodec::heuristicNameMatch(hint);
+}
+
+int QLatin1Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 0x80 && *c < 0xa0 )
+ return -1;
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ return r;
+}
+
+
+static void setupBuiltinCodecs()
+{
+ (void)new QLatin1Codec;
+
+#ifndef QT_NO_CODECS
+ int i = 0;
+ do {
+ (void)new QSimpleTextCodec( i );
+ } while( unicodevalues[i++].mib != LAST_MIB );
+
+ //(void)new QEucJpCodec;
+ //(void)new QSjisCodec;
+ //(void)new QJisCodec;
+ //(void)new QEucKrCodec;
+ //(void)new QGbkCodec;
+ //(void)new QBig5Codec;
+ (void)new QUtf8Codec;
+ (void)new QUtf16Codec;
+ //(void)new QHebrewCodec;
+ //(void)new QArabicCodec;
+ //(void)new QTsciiCodec;
+#endif // QT_NO_CODECS
+}
+
+#endif // QT_NO_TEXTCODEC
diff --git a/qtools/qtextcodec.h b/qtools/qtextcodec.h
new file mode 100644
index 0000000..18ece20
--- /dev/null
+++ b/qtools/qtextcodec.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+**
+** Definition of QTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QTEXTCODEC_H
+#define QTEXTCODEC_H
+
+#ifndef QT_H
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_TEXTCODEC
+
+class QTextCodec;
+class QIODevice;
+
+class Q_EXPORT QTextEncoder {
+public:
+ virtual ~QTextEncoder();
+ virtual QCString fromUnicode(const QString& uc, int& lenInOut) = 0;
+};
+
+class Q_EXPORT QTextDecoder {
+public:
+ virtual ~QTextDecoder();
+ virtual QString toUnicode(const char* chars, int len) = 0;
+};
+
+class Q_EXPORT QTextCodec {
+public:
+ virtual ~QTextCodec();
+
+#ifndef QT_NO_CODECS
+ static QTextCodec* loadCharmap(QIODevice*);
+ static QTextCodec* loadCharmapFile(QString filename);
+#endif
+ static QTextCodec* codecForMib(int mib);
+ static QTextCodec* codecForName(const char* hint, int accuracy=0);
+ static QTextCodec* codecForContent(const char* chars, int len);
+ static QTextCodec* codecForIndex(int i);
+ static QTextCodec* codecForLocale();
+
+ static void deleteAllCodecs();
+
+ static const char* locale();
+
+ virtual const char* name() const = 0;
+ virtual int mibEnum() const = 0;
+
+ virtual QTextDecoder* makeDecoder() const;
+ virtual QTextEncoder* makeEncoder() const;
+
+ virtual QString toUnicode(const char* chars, int len) const;
+ virtual QCString fromUnicode(const QString& uc, int& lenInOut) const;
+
+ QCString fromUnicode(const QString& uc) const;
+ QString toUnicode(const QByteArray&, int len) const;
+ QString toUnicode(const QByteArray&) const;
+ QString toUnicode(const char* chars) const;
+ virtual bool canEncode( QChar ) const;
+ virtual bool canEncode( const QString& ) const;
+
+ virtual int heuristicContentMatch(const char* chars, int len) const = 0;
+ virtual int heuristicNameMatch(const char* hint) const;
+
+protected:
+ QTextCodec();
+ static int simpleHeuristicNameMatch(const char* name, const char* hint);
+};
+#endif // QT_NO_TEXTCODEC
+#endif // QTEXTCODEC_H
diff --git a/qtools/qtextstream.cpp b/qtools/qtextstream.cpp
new file mode 100644
index 0000000..bae072d
--- /dev/null
+++ b/qtools/qtextstream.cpp
@@ -0,0 +1,2237 @@
+/****************************************************************************
+**
+**
+** Implementation of QTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qtextstream.h"
+
+#ifndef QT_NO_TEXTSTREAM
+#include "qtextcodec.h"
+#include "qregexp.h"
+#include "qbuffer.h"
+#include "qfile.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(_OS_WIN32_)
+#include <windows.h>
+#endif
+
+// NOT REVISED
+/*!
+ \class QTextStream qtextstream.h
+
+ \brief The QTextStream class provides basic functions for reading and
+ writing text using a QIODevice.
+
+ \ingroup io
+
+ \define endl
+ \define bin
+ \define oct
+ \define dec
+ \define hex
+ \define flush
+ \define ws
+
+ The text stream class has a functional interface that is very
+ similar to that of the standard C++ iostream class. The difference
+ between iostream and QTextStream is that our stream operates on a
+ QIODevice, which is easily subclassed, while iostream operates on
+ FILE * pointers, which can not be subclassed.
+
+ Qt provides several global functions similar to the ones in iostream:
+ <ul>
+ <li> \c bin sets the QTextStream to read/write binary numbers
+ <li> \c oct sets the QTextStream to read/write octal numbers
+ <li> \c dec sets the QTextStream to read/write decimal numbers
+ <li> \c hex sets the QTextStream to read/write hexadecimal numbers
+ <li> \c endl forces a line break
+ <li> \c flush forces the QIODevice to flush any buffered data
+ <li> \c ws eats any available white space (on input)
+ <li> \c reset resets the QTextStream to its default mode (see reset()).
+ </ul>
+
+ \warning By default, QTextStream will automatically detect whether
+ integers in the stream are in decimal, octal, hexadecimal or binary
+ format when reading from the stream. In particular, a leading '0'
+ signifies octal, ie. the sequence "0100" will be interpreted as
+ 64.
+
+ The QTextStream class reads and writes text and it is not
+ appropriate for dealing with binary data (but QDataStream is).
+
+ By default output of Unicode text (ie. QString) is done using the
+ local 8-bit encoding. This can be changed using the setEncoding()
+ method. For input, the QTextStream will auto-detect standard
+ Unicode "byte order marked" text files, but otherwise the local
+ 8-bit encoding is used.
+
+ \sa QDataStream
+*/
+
+/*
+ \class QTSManip qtextstream.h
+
+ \brief The QTSManip class is an internal helper class for the
+ QTextStream.
+
+ It is generally a very bad idea to use this class directly in
+ application programs.
+
+ \internal
+
+ This class makes it possible to give the QTextStream function objects
+ with arguments, like this:
+ \code
+ QTextStream cout( stdout, IO_WriteOnly );
+ cout << setprecision( 8 ); // QTSManip used here!
+ cout << 3.14159265358979323846;
+ \endcode
+
+ The setprecision() function returns a QTSManip object.
+ The QTSManip object contains a pointer to a member function in
+ QTextStream and an integer argument.
+ When serializing a QTSManip into a QTextStream, the function
+ is executed with the argument.
+*/
+
+/*! \fn QTSManip::QTSManip (QTSMFI m, int a)
+
+ Constructs a QTSManip object which will call \a m (a member function
+ in QTextStream which accepts a single int) with argument \a a when
+ QTSManip::exec() is called. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+/*! \fn void QTSManip::exec (QTextStream& s)
+
+ Calls the member function specified in the constructor, for object
+ \a s. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+
+/*****************************************************************************
+ QTextStream member functions
+ *****************************************************************************/
+
+#if defined(CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "QTextStream: No device" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+
+#define I_SHORT 0x0010
+#define I_INT 0x0020
+#define I_LONG 0x0030
+#define I_TYPE_MASK 0x00f0
+
+#define I_BASE_2 QTS::bin
+#define I_BASE_8 QTS::oct
+#define I_BASE_10 QTS::dec
+#define I_BASE_16 QTS::hex
+#define I_BASE_MASK (QTS::bin | QTS::oct | QTS::dec | QTS::hex)
+
+#define I_SIGNED 0x0100
+#define I_UNSIGNED 0x0200
+#define I_SIGN_MASK 0x0f00
+
+
+static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.
+
+const int QTextStream::basefield = I_BASE_MASK;
+const int QTextStream::adjustfield = ( QTextStream::left |
+ QTextStream::right |
+ QTextStream::internal );
+const int QTextStream::floatfield = ( QTextStream::scientific |
+ QTextStream::fixed );
+
+
+class QTextStreamPrivate {
+public:
+#ifndef QT_NO_TEXTCODEC
+ QTextStreamPrivate() : decoder( 0 ), sourceType( NotSet ) {}
+ ~QTextStreamPrivate() { delete decoder; }
+ QTextDecoder *decoder; //???
+#else
+ QTextStreamPrivate() : sourceType( NotSet ) {}
+ ~QTextStreamPrivate() { }
+#endif
+ QString ungetcBuf;
+
+ enum SourceType { NotSet, IODevice, String, ByteArray, File };
+ SourceType sourceType;
+};
+
+
+// skips whitespace and returns the first non-whitespace character
+QChar QTextStream::eat_ws()
+{
+ QChar c;
+ do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );
+ return c;
+}
+
+void QTextStream::init()
+{
+ // ### ungetcBuf = QEOF;
+ dev = 0; // no device set
+ fstrm = owndev = FALSE;
+ mapper = 0;
+ d = new QTextStreamPrivate;
+ doUnicodeHeader = TRUE; //default to autodetect
+ latin1 = TRUE; // ### should use local?
+ internalOrder = QChar::networkOrdered(); //default to network order
+}
+
+/*!
+ Constructs a data stream that has no IO device.
+*/
+
+QTextStream::QTextStream()
+{
+ init();
+ setEncoding( Locale ); //###
+ reset();
+ d->sourceType = QTextStreamPrivate::NotSet;
+}
+
+/*!
+ Constructs a text stream that uses the IO device \a iod.
+*/
+
+QTextStream::QTextStream( QIODevice *iod )
+{
+ init();
+ setEncoding( Locale ); //###
+ dev = iod; // set device
+ reset();
+ d->sourceType = QTextStreamPrivate::IODevice;
+}
+
+// TODO: use special-case handling of this case in QTextStream, and
+// simplify this class to only deal with QChar or QString data.
+class QStringBuffer : public QIODevice {
+public:
+ QStringBuffer( QString* str );
+ ~QStringBuffer();
+ bool open( int m );
+ void close();
+ void flush();
+ uint size() const;
+ int at() const;
+ bool at( int pos );
+ int readBlock( char *p, uint len );
+ int writeBlock( const char *p, uint len );
+ int getch();
+ int putch( int ch );
+ int ungetch( int ch );
+protected:
+ QString* s;
+
+private: // Disabled copy constructor and operator=
+ QStringBuffer( const QStringBuffer & );
+ QStringBuffer &operator=( const QStringBuffer & );
+};
+
+
+QStringBuffer::QStringBuffer( QString* str )
+{
+ s = str;
+}
+
+QStringBuffer::~QStringBuffer()
+{
+}
+
+
+bool QStringBuffer::open( int m )
+{
+ if ( !s ) {
+#if defined(CHECK_STATE)
+ qWarning( "QStringBuffer::open: No string" );
+#endif
+ return FALSE;
+ }
+ if ( isOpen() ) { // buffer already open
+#if defined(CHECK_STATE)
+ qWarning( "QStringBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate ) { // truncate buffer
+ s->truncate( 0 );
+ }
+ if ( m & IO_Append ) { // append to end of buffer
+ ioIndex = s->length()*(int)sizeof(QChar);
+ } else {
+ ioIndex = 0;
+ }
+ setState( IO_Open );
+ setStatus( 0 );
+ return TRUE;
+}
+
+void QStringBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ }
+}
+
+void QStringBuffer::flush()
+{
+}
+
+uint QStringBuffer::size() const
+{
+ return s ? s->length()*(int)sizeof(QChar) : 0;
+}
+
+int QStringBuffer::at() const
+{
+ return ioIndex;
+}
+
+bool QStringBuffer::at( int pos )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "QStringBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( (uint)pos >= s->length()*2 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QStringBuffer::at: Index %d out of range", pos );
+#endif
+ return FALSE;
+ }
+ ioIndex = pos;
+ return TRUE;
+}
+
+
+int QStringBuffer::readBlock( char *p, uint len )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len > s->length()*sizeof(QChar) ) {
+ // overflow
+ if ( (uint)ioIndex >= s->length()*sizeof(QChar) ) {
+ setStatus( IO_ReadError );
+ return -1;
+ } else {
+ len = s->length()*2 - (uint)ioIndex;
+ }
+ }
+ memcpy( p, ((const char*)(s->unicode()))+ioIndex, len );
+ ioIndex += len;
+ return len;
+}
+
+int QStringBuffer::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QStringBuffer::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+ if ( ioIndex&1 ) {
+ qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );
+ return -1;
+ }
+ if ( len&1 ) {
+ qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );
+ return -1;
+ }
+#endif
+ s->replace(ioIndex/2, len/2, (QChar*)p, len/2);
+ ioIndex += len;
+ return len;
+}
+
+int QStringBuffer::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex >= s->length()*2 ) { // overflow
+ setStatus( IO_ReadError );
+ return -1;
+ }
+ return *((char*)s->unicode() + ioIndex++);
+}
+
+int QStringBuffer::putch( int ch )
+{
+ char c = ch;
+ if ( writeBlock(&c,1) < 0 )
+ return -1;
+ else
+ return ch;
+}
+
+int QStringBuffer::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) { // something to do with eof
+ if ( ioIndex )
+ ioIndex--;
+ else
+ ch = -1;
+ }
+ return ch;
+}
+
+
+/*!
+ Constructs a text stream that operates on a Unicode QString through an
+ internal device.
+
+ If you set an encoding or codec with setEncoding() or setCodec(), this
+ setting is ignored for text streams that operate on QString.
+
+ Example:
+ \code
+ QString str;
+ QTextStream ts( &str, IO_WriteOnly );
+ ts << "pi = " << 3.14; // str == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the string.
+ The string will be expanded when data is written beyond the end of the
+ string. Note that the string will not be truncated:
+ \code
+ QString str = "pi = 3.14";
+ QTextStream ts( &str, IO_WriteOnly );
+ ts << "2+2 = " << 2+2; // str == "2+2 = 414"
+ \endcode
+
+ Note that since QString is Unicode, you should not use readRawBytes()
+ or writeRawBytes() on such a stream.
+*/
+
+QTextStream::QTextStream( QString* str, int filemode )
+{
+ // TODO: optimize for this case as it becomes more common
+ // (see QStringBuffer above)
+ init();
+ dev = new QStringBuffer( str );
+ ((QStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = QTextStreamPrivate::String;
+}
+
+/*! \obsolete
+
+ This constructor is equivalent to the constructor taking a QString*
+ parameter.
+*/
+
+QTextStream::QTextStream( QString& str, int filemode )
+{
+ init();
+ dev = new QStringBuffer( &str );
+ ((QStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = QTextStreamPrivate::String;
+}
+
+/*!
+ Constructs a text stream that operates on a byte array through an
+ internal QBuffer device.
+
+ Example:
+ \code
+ QByteArray array;
+ QTextStream ts( array, IO_WriteOnly );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the array.
+ The array will be expanded when data is written beyond the end of the
+ string.
+
+ Same example, using a QBuffer:
+ \code
+ QByteArray array;
+ QBuffer buf( array );
+ buf.open( IO_WriteOnly );
+ QTextStream ts( &buf );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ buf.close();
+ \endcode
+*/
+
+QTextStream::QTextStream( QByteArray a, int mode )
+{
+ init();
+ dev = new QBuffer( a );
+ ((QBuffer *)dev)->open( mode );
+ owndev = TRUE;
+ setEncoding( Locale ); //### Locale???
+ reset();
+ d->sourceType = QTextStreamPrivate::ByteArray;
+}
+
+/*!
+ Constructs a text stream that operates on an existing file handle \e fh
+ through an internal QFile device.
+
+ Example:
+ \code
+ QTextStream cout( stdout, IO_WriteOnly );
+ QTextStream cin ( stdin, IO_ReadOnly );
+ QTextStream cerr( stderr, IO_WriteOnly );
+ \endcode
+*/
+
+QTextStream::QTextStream( FILE *fh, int mode )
+{
+ init();
+ setEncoding( Locale ); //###
+ dev = new QFile;
+ ((QFile *)dev)->open( mode, fh );
+ fstrm = owndev = TRUE;
+ reset();
+ d->sourceType = QTextStreamPrivate::File;
+}
+
+/*!
+ Destructs the text stream.
+
+ The destructor does not affect the current IO device.
+*/
+
+QTextStream::~QTextStream()
+{
+ if ( owndev )
+ delete dev;
+ delete d;
+}
+
+/*!
+ Positions the read pointer at the first non-whitespace character.
+*/
+void QTextStream::skipWhiteSpace()
+{
+ ts_ungetc( eat_ws() );
+}
+
+
+/*!
+ \fn Encoding QTextStream::encoding() const
+
+ Returns the encoding mode of the stream.
+
+ \sa setEncoding()
+*/
+
+/*!
+ Tries to read len characters from the stream and stores them in \a buf.
+ Returns the number of characters really read.
+ Attention: There will no QEOF appended if the read reaches the end of
+ the file. EOF is reached when the return value does not equal \a len.
+*/
+uint QTextStream::ts_getbuf( QChar* buf, uint len )
+{
+ if( len<1 )
+ return 0;
+
+ uint rnum=0; // the number of QChars really read
+
+ if ( d && d->ungetcBuf.length() ) {
+ while( rnum < len && rnum < d->ungetcBuf.length() ) {
+ buf[rnum] = d->ungetcBuf.constref(rnum);
+ rnum++;
+ }
+ d->ungetcBuf = d->ungetcBuf.mid( rnum );
+ if ( rnum >= len )
+ return rnum;
+ }
+
+ // we use dev->ungetch() for one of the bytes of the unicode
+ // byte-order mark, but a local unget hack for the other byte:
+ int ungetHack = EOF;
+
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE; //only at the top
+ int c1 = dev->getch();
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev->getch();
+ if ( c1 == 0xfe && c2 == 0xff ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = QChar::networkOrdered(); //network order
+ } else if ( c1 == 0xff && c2 == 0xfe ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = !QChar::networkOrdered(); //reverse network order
+ } else {
+ if ( c2 != EOF ) {
+ dev->ungetch( c2 );
+ ungetHack = c1;
+ } else {
+ dev->ungetch( c1 );
+ // note that a small possible bug might hide here
+ // here, if only the first byte of a file has made it
+ // so far, and that first byte is half of the
+ // byte-order mark, then the utfness will not be
+ // detected. whether or not this is a bug depends on
+ // taste. I can't really decide.
+ }
+ }
+ }
+
+#ifndef QT_NO_TEXTCODEC
+ if ( mapper ) {
+ bool shortRead = FALSE;
+ if ( !d->decoder )
+ d->decoder = mapper->makeDecoder();
+ while( rnum < len ) {
+ QString s;
+ bool readBlock = !( len == 1+rnum );
+ while ( TRUE ) {
+ // for efficiency: normally read a whole block
+ if ( readBlock ) {
+ // guess buffersize; this may be wrong (too small or too
+ // big). But we can handle this (either iterate reading
+ // or use ungetcBuf).
+ // Note that this might cause problems for codecs where
+ // one byte can result in >1 Unicode Characters if bytes
+ // are written to the stream in the meantime (loss of
+ // synchronicity).
+ uint rlen = len - rnum;
+ char *cbuf = new char[ rlen ];
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ s += d->decoder->toUnicode( cbuf, rlen );
+ delete[] cbuf;
+ // use buffered reading only for the first time, because we
+ // have to get the stream synchronous again (this is easier
+ // with single character reading)
+ readBlock = FALSE;
+ }
+ // get stream (and codec) in sync
+ int c;
+ if ( ungetHack == EOF ) {
+ c = dev->getch();
+ } else {
+ c = ungetHack;
+ ungetHack = EOF;
+ }
+ if ( c == EOF ) {
+ shortRead = TRUE;
+ break;
+ }
+ char b = c;
+ uint lengthBefore = s.length();
+ s += d->decoder->toUnicode( &b, 1 );
+ if ( s.length() > lengthBefore )
+ break; // it seems we are in sync now
+ }
+ uint i = 0;
+ while( rnum < len && i < s.length() )
+ buf[rnum++] = s.constref(i++);
+ if ( s.length() > i )
+ // could be = but append is clearer
+ d->ungetcBuf.append( s.mid( i ) );
+ if ( shortRead )
+ return rnum;
+ }
+ } else
+#endif
+ if ( latin1 ) {
+ if ( len == 1+rnum ) {
+ // use this method for one character because it is more efficient
+ // (arnt doubts whether it makes a difference, but lets it stand)
+ int c = (ungetHack == EOF) ? dev->getch() : ungetHack;
+ if ( c != EOF )
+ buf[rnum++] = (char)c;
+ } else {
+ if ( ungetHack != EOF ) {
+ buf[rnum++] = (char)ungetHack;
+ ungetHack = EOF;
+ }
+ char *cbuf = new char[len - rnum];
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = len - rnum;
+ rlen = dev->readBlock( cbuf, rlen );
+ uint i = 0;
+ while( i < rlen )
+ buf[rnum++] = cbuf[i++];
+ }
+ delete[] cbuf;
+ }
+ } else { // UCS-2 or UTF-16
+ if ( len == 1+rnum ) {
+ int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev->getch();
+ if ( c2 == EOF )
+ return rnum;
+ if ( isNetworkOrder() )
+ buf[rnum++] = QChar( c2, c1 );
+ else
+ buf[rnum++] = QChar( c1, c2 );
+ } else {
+ char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = 2 * ( len-rnum );
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ // We can't use an odd number of bytes, so put it back. But
+ // do it only if we are capable of reading more -- normally
+ // there should not be an odd number, but the file might be
+ // truncated or not in UTF-16...
+ if ( (rlen & 1) == 1 )
+ if ( !dev->atEnd() )
+ dev->ungetch( cbuf[--rlen] );
+ uint i = 0;
+ if ( isNetworkOrder() ) {
+ while( i < rlen ) {
+ buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );
+ i+=2;
+ }
+ } else {
+ while( i < rlen ) {
+ buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
+ i+=2;
+ }
+ }
+ }
+ delete[] cbuf;
+ }
+ }
+ return rnum;
+}
+
+
+/*!
+ Puts one character to the stream.
+*/
+void QTextStream::ts_putc( QChar c )
+{
+#ifndef QT_NO_TEXTCODEC
+ if ( mapper ) {
+ int len = 1;
+ QString s = c;
+ QCString block = mapper->fromUnicode( s, len );
+ dev->writeBlock( block, len );
+ } else
+#endif
+ if ( latin1 ) {
+ if( c.row() )
+ dev->putch( '?' ); //######unknown character???
+ else
+ dev->putch( c.cell() );
+ } else {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( QChar::byteOrderMark );
+ }
+ if ( internalOrder ) {
+ dev->writeBlock( (char*)&c, sizeof(QChar) );
+ } else if ( isNetworkOrder() ) {
+ dev->putch(c.row());
+ dev->putch(c.cell());
+ } else {
+ dev->putch(c.cell());
+ dev->putch(c.row());
+ }
+ }
+}
+
+/*!
+ Puts one character to the stream.
+*/
+void QTextStream::ts_putc(int ch)
+{
+ ts_putc(QChar((ushort)ch));
+}
+
+bool QTextStream::ts_isdigit(QChar c)
+{
+ return c.isDigit();
+}
+
+bool QTextStream::ts_isspace( QChar c )
+{
+ return c.isSpace();
+}
+
+void QTextStream::ts_ungetc( QChar c )
+{
+ if ( c.unicode() == 0xffff )
+ return;
+
+ d->ungetcBuf.prepend( c );
+}
+
+
+
+/*!
+ Reads \e len bytes from the stream into \e e s and returns a reference to
+ the stream.
+
+ The buffer \e s must be preallocated.
+
+ Note that no encoding is done by this function.
+
+ \warning The behaviour of this function is undefined unless the
+ stream's encoding is set to Unicode or Latin1.
+
+ \sa QIODevice::readBlock()
+*/
+
+QTextStream &QTextStream::readRawBytes( char *s, uint len )
+{
+ dev->readBlock( s, len );
+ return *this;
+}
+
+/*!
+ Writes the \e len bytes from \e s to the stream and returns a reference to
+ the stream.
+
+ Note that no encoding is done by this function.
+
+ \sa QIODevice::writeBlock()
+*/
+
+QTextStream &QTextStream::writeRawBytes( const char* s, uint len )
+{
+ dev->writeBlock( s, len );
+ return *this;
+}
+
+
+QTextStream &QTextStream::writeBlock( const char* p, uint len )
+{
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ if ( !mapper && !latin1 )
+ ts_putc( QChar::byteOrderMark );
+ }
+ //All QCStrings and const char* are defined to be in Latin1
+ if ( !mapper && latin1 ) {
+ dev->writeBlock( p, len );
+ } else if ( !mapper && internalOrder ) {
+ QChar *u = new QChar[len];
+ for (uint i=0; i<len; i++)
+ u[i] = p[i];
+ dev->writeBlock( (char*)u, len*(int)sizeof(QChar) );
+ delete [] u;
+ } else {
+ for (uint i=0; i<len; i++)
+ ts_putc( (uchar)p[i] );
+ }
+ return *this;
+}
+
+QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
+{
+ if ( !mapper && !latin1 && internalOrder ) {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( QChar::byteOrderMark );
+ }
+ dev->writeBlock( (char*)p, (int)sizeof(QChar)*len );
+ } else {
+ for (uint i=0; i<len; i++)
+ ts_putc( p[i] );
+ }
+ return *this;
+}
+
+
+
+/*!
+ Resets the text stream.
+
+ <ul>
+ <li> All flags are set to 0.
+ <li> The field width is set to 0.
+ <li> The fill character is set to ' ' (space).
+ <li> The precision is set to 6.
+ </ul>
+
+ \sa setf(), width(), fill(), precision()
+*/
+
+void QTextStream::reset()
+{
+ fflags = 0;
+ fwidth = 0;
+ fillchar = ' ';
+ fprec = 6;
+}
+
+
+/*!
+ \fn QIODevice *QTextStream::device() const
+ Returns the IO device currently set.
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ Sets the IO device to \a iod.
+ \sa device(), unsetDevice()
+*/
+
+void QTextStream::setDevice( QIODevice *iod )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = iod;
+ d->sourceType = QTextStreamPrivate::IODevice;
+}
+
+/*!
+ Unsets the IO device. Equivalent to setDevice( 0 ).
+ \sa device(), setDevice()
+*/
+
+void QTextStream::unsetDevice()
+{
+ setDevice( 0 );
+ d->sourceType = QTextStreamPrivate::NotSet;
+}
+
+/*!
+ \fn bool QTextStream::atEnd() const
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!\fn bool QTextStream::eof() const
+
+ \obsolete
+
+ This function has been renamed to atEnd().
+
+ \sa QIODevice::atEnd()
+*/
+
+/*****************************************************************************
+ QTextStream read functions
+ *****************************************************************************/
+
+
+/*!
+ Reads a \c char from the stream and returns a reference to the stream.
+ Note that whitespace is skipped.
+*/
+
+QTextStream &QTextStream::operator>>( char &c )
+{
+ CHECK_STREAM_PRECOND
+ c = eat_ws();
+ return *this;
+}
+
+/*!
+ Reads a \c char from the stream and returns a reference to the stream.
+ Note that whitespace is \e not skipped.
+*/
+
+QTextStream &QTextStream::operator>>( QChar &c )
+{
+ CHECK_STREAM_PRECOND
+ c = ts_getc();
+ return *this;
+}
+
+
+ulong QTextStream::input_bin()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv == 0 || dv == 1 ) {
+ val = ( val << 1 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_oct()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv >= 0 && dv <= 7 ) {
+ val = ( val << 3 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( dv == 8 || dv == 9 ) {
+ while ( ts_isdigit(ch) )
+ ch = ts_getc();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_dec()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( ts_isdigit(ch) ) {
+ val = val * 10 + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_hex()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ char c = ch;
+ while ( isxdigit(c) ) {
+ val <<= 4;
+ if ( ts_isdigit(c) )
+ val += c - '0';
+ else
+ val += 10 + tolower(c) - 'a';
+ c = ch = ts_getc();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+long QTextStream::input_int()
+{
+ long val;
+ QChar ch;
+ char c;
+ switch ( flags() & basefield ) {
+ case bin:
+ val = (long)input_bin();
+ break;
+ case oct:
+ val = (long)input_oct();
+ break;
+ case dec:
+ c = ch = eat_ws();
+ if ( ch == QEOF ) {
+ val = 0;
+ } else {
+ if ( !(c == '-' || c == '+') )
+ ts_ungetc( ch );
+ if ( c == '-' ) {
+ ulong v = input_dec();
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)input_dec();
+ }
+ }
+ break;
+ case hex:
+ val = (long)input_hex();
+ break;
+ default:
+ val = 0;
+ c = ch = eat_ws();
+ if ( c == '0' ) { // bin, oct or hex
+ c = ch = ts_getc();
+ if ( tolower(c) == 'x' )
+ val = (long)input_hex();
+ else if ( tolower(c) == 'b' )
+ val = (long)input_bin();
+ else { // octal
+ ts_ungetc( ch );
+ if ( c >= '0' && c <= '7' ) {
+ val = (long)input_oct();
+ } else {
+ val = 0;
+ }
+ }
+ } else if ( ts_isdigit(ch) ) {
+ ts_ungetc( ch );
+ val = (long)input_dec();
+ } else if ( c == '-' || c == '+' ) {
+ ulong v = input_dec();
+ if ( c == '-' ) {
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)v;
+ }
+ }
+ }
+ return val;
+}
+
+//
+// We use a table-driven FSM to parse floating point numbers
+// strtod() cannot be used directly since we're reading from a QIODevice
+//
+
+double QTextStream::input_double()
+{
+ const int Init = 0; // states
+ const int Sign = 1;
+ const int Mantissa = 2;
+ const int Dot = 3;
+ const int Abscissa = 4;
+ const int ExpMark = 5;
+ const int ExpSign = 6;
+ const int Exponent = 7;
+ const int Done = 8;
+
+ const int InputSign = 1; // input tokens
+ const int InputDigit = 2;
+ const int InputDot = 3;
+ const int InputExp = 4;
+
+ static uchar table[8][5] = {
+ /* None InputSign InputDigit InputDot InputExp */
+ { 0, Sign, Mantissa, Dot, 0, }, // Init
+ { 0, 0, Mantissa, Dot, 0, }, // Sign
+ { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa
+ { 0, 0, Abscissa, 0, 0, }, // Dot
+ { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa
+ { 0, ExpSign, Exponent, 0, 0, }, // ExpMark
+ { 0, 0, Exponent, 0, 0, }, // ExpSign
+ { Done, Done, Exponent, Done, Done } // Exponent
+ };
+
+ int state = Init; // parse state
+ int input; // input token
+
+ char buf[256];
+ int i = 0;
+ QChar c = eat_ws();
+
+ while ( TRUE ) {
+
+ switch ( c ) {
+ case '+':
+ case '-':
+ input = InputSign;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ input = InputDigit;
+ break;
+ case '.':
+ input = InputDot;
+ break;
+ case 'e':
+ case 'E':
+ input = InputExp;
+ break;
+ default:
+ input = 0;
+ break;
+ }
+
+ state = table[state][input];
+
+ if ( state == 0 || state == Done || i > 250 ) {
+ if ( i > 250 ) { // ignore rest of digits
+ do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );
+ }
+ if ( c != QEOF )
+ ts_ungetc( c );
+ buf[i] = '\0';
+ char *end;
+ return strtod( buf, &end );
+ }
+
+ buf[i++] = c;
+ c = ts_getc();
+ }
+
+#if !defined(_CC_EGG_)
+ return 0.0;
+#endif
+}
+
+
+/*!
+ Reads a signed \c short integer from the stream and returns a reference to
+ the stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed short)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c short integer from the stream and returns a reference to
+ the stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned short)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a signed \c int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed int)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned int)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a signed \c long int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed long)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c long int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned long)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a \c float from the stream and returns a reference to the stream.
+ See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ f = (float)input_double();
+ return *this;
+}
+
+
+/*!
+ Reads a \c double from the stream and returns a reference to the stream.
+ See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ f = input_double();
+ return *this;
+}
+
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( char *s )
+{
+ CHECK_STREAM_PRECOND
+ int maxlen = width( 0 );
+ QChar c = eat_ws();
+ if ( !maxlen )
+ maxlen = -1;
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) || maxlen-- == 0 ) {
+ ts_ungetc( c );
+ break;
+ }
+ *s++ = c;
+ c = ts_getc();
+ }
+
+ *s = '\0';
+ return *this;
+}
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( QString &str )
+{
+ CHECK_STREAM_PRECOND
+ str=QString::fromLatin1("");
+ QChar c = eat_ws();
+
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ str += c;
+ c = ts_getc();
+ }
+ return *this;
+}
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( QCString &str )
+{
+ CHECK_STREAM_PRECOND
+ QCString *dynbuf = 0;
+ const int buflen = 256;
+ char buffer[buflen];
+ char *s = buffer;
+ int i = 0;
+ QChar c = eat_ws();
+
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ if ( i >= buflen-1 ) {
+ if ( !dynbuf ) { // create dynamic buffer
+ dynbuf = new QCString(buflen*2);
+ memcpy( dynbuf->data(), s, i ); // copy old data
+ } else if ( i >= (int)dynbuf->size()-1 ) {
+ dynbuf->resize( dynbuf->size()*2 );
+ }
+ s = dynbuf->data();
+ }
+ s[i++] = c;
+ c = ts_getc();
+ }
+ str.resize( i+1 );
+ memcpy( str.data(), s, i );
+ delete dynbuf;
+ return *this;
+}
+
+
+/*!
+ Reads a line from the stream and returns a string containing the text.
+
+ The returned string does not contain any trailing newline or carriage
+ return. Note that this is different from QIODevice::readLine(), which
+ does not strip the newline at the end of the line.
+
+ On EOF you will get a QString that is null. On reading an empty line the
+ returned QString is empty but not null.
+
+ \sa QIODevice::readLine()
+*/
+
+QString QTextStream::readLine()
+{
+#if defined(CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "QTextStream::readLine: No device" );
+ return QString::null;
+ }
+#endif
+ QString result( "" );
+ const int buf_size = 256;
+ QChar c[buf_size];
+ int pos = 0;
+
+ c[pos] = ts_getc();
+ if ( c[pos] == QEOF )
+ return QString::null;
+
+ while ( c[pos] != QEOF && c[pos] != '\n' ) {
+ pos++;
+ if ( pos >= buf_size ) {
+ result += QString( c, pos );
+ pos = 0;
+ }
+ c[pos] = ts_getc();
+ }
+ result += QString( c, pos );
+
+ int len = (int)result.length();
+ if ( len && result[len-1] == '\r' )
+ result.truncate(len-1); // (if there are two \r, let one stay)
+
+ return result;
+}
+
+
+/*!
+ Reads the entire stream and returns a string containing the text.
+
+ \sa QIODevice::readLine()
+*/
+
+QString QTextStream::read()
+{
+#if defined(CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "QTextStream::read: No device" );
+ return QString::null;
+ }
+#endif
+ QString result;
+ const uint bufsize = 512;
+ QChar buf[bufsize];
+ uint i, num, start;
+ bool skipped_cr = FALSE;
+
+ while ( 1 ) {
+ num = ts_getbuf(buf,bufsize);
+ // do a s/\r\n/\n
+ start = 0;
+ for ( i=0; i<num; i++ ) {
+ if ( buf[i] == '\r' ) {
+ // Only skip single cr's preceding lf's
+ if ( skipped_cr ) {
+ result += buf[i];
+ start++;
+ } else {
+ result += QString( &buf[start], i-start );
+ start = i+1;
+ skipped_cr = TRUE;
+ }
+ } else {
+ if ( skipped_cr ) {
+ if ( buf[i] != '\n' ) {
+ // Should not have skipped it
+ result += '\r';
+ }
+ skipped_cr = FALSE;
+ }
+ }
+ }
+ if ( start < num )
+ result += QString( &buf[start], i-start );
+ if ( num != bufsize ) // if ( EOF )
+ break;
+ }
+ return result;
+}
+
+
+
+/*****************************************************************************
+ QTextStream write functions
+ *****************************************************************************/
+
+/*!
+ Writes a \c char to the stream and returns a reference to the stream.
+
+ The character \a c is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
+*/
+QTextStream &QTextStream::operator<<( QChar c )
+{
+ CHECK_STREAM_PRECOND
+ ts_putc( c );
+ return *this;
+}
+
+/*!
+ Writes a \c char to the stream and returns a reference to the stream.
+*/
+QTextStream &QTextStream::operator<<( char c )
+{
+ CHECK_STREAM_PRECOND
+ unsigned char uc = (unsigned char) c;
+ ts_putc( uc );
+ return *this;
+}
+
+QTextStream &QTextStream::output_int( int format, ulong n, bool neg )
+{
+ static char hexdigits_lower[] = "0123456789abcdef";
+ static char hexdigits_upper[] = "0123456789ABCDEF";
+ CHECK_STREAM_PRECOND
+ char buf[76];
+ register char *p;
+ int len;
+ char *hexdigits;
+
+ switch ( flags() & I_BASE_MASK ) {
+
+ case I_BASE_2: // output binary number
+ switch ( format & I_TYPE_MASK ) {
+ case I_SHORT: len=16; break;
+ case I_INT: len=sizeof(int)*8; break;
+ case I_LONG: len=32; break;
+ default: len = 0;
+ }
+ p = &buf[74]; // go reverse order
+ *p = '\0';
+ while ( len-- ) {
+ *--p = (char)(n&1) + '0';
+ n >>= 1;
+ if ( !n )
+ break;
+ }
+ if ( flags() & showbase ) { // show base
+ *--p = (flags() & uppercase) ? 'B' : 'b';
+ *--p = '0';
+ }
+ break;
+
+ case I_BASE_8: // output octal number
+ p = &buf[74];
+ *p = '\0';
+ do {
+ *--p = (char)(n&7) + '0';
+ n >>= 3;
+ } while ( n );
+ if ( flags() & showbase )
+ *--p = '0';
+ break;
+
+ case I_BASE_16: // output hexadecimal number
+ p = &buf[74];
+ *p = '\0';
+ hexdigits = (flags() & uppercase) ?
+ hexdigits_upper : hexdigits_lower;
+ do {
+ *--p = hexdigits[(int)n&0xf];
+ n >>= 4;
+ } while ( n );
+ if ( flags() & showbase ) {
+ *--p = (flags() & uppercase) ? 'X' : 'x';
+ *--p = '0';
+ }
+ break;
+
+ default: // decimal base is default
+ p = &buf[74];
+ *p = '\0';
+ if ( neg )
+ n = (ulong)(-(long)n);
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg )
+ *--p = '-';
+ else if ( flags() & showpos )
+ *--p = '+';
+ if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
+ ts_putc( *p ); // special case for internal
+ ++p; // padding
+ fwidth--;
+ return *this << (const char*)p;
+ }
+ }
+ if ( fwidth ) { // adjustment required
+ if ( !(flags() & left) ) { // but NOT left adjustment
+ len = qstrlen(p);
+ int padlen = fwidth - len;
+ if ( padlen <= 0 ) { // no padding required
+ writeBlock( p, len );
+ } else if ( padlen < (int)(p-buf) ) { // speeds up padding
+ memset( p-padlen, (char)fillchar, padlen );
+ writeBlock( p-padlen, padlen+len );
+ }
+ else // standard padding
+ *this << (const char*)p;
+ }
+ else
+ *this << (const char*)p;
+ fwidth = 0; // reset field width
+ }
+ else
+ writeBlock( p, qstrlen(p) );
+ return *this;
+}
+
+
+/*!
+ Writes a \c short integer to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed short i )
+{
+ return output_int( I_SHORT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c short integer to the stream and returns a reference
+ to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned short i )
+{
+ return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes an \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed int i )
+{
+ return output_int( I_INT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned int i )
+{
+ return output_int( I_INT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes a \c long \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed long i )
+{
+ return output_int( I_LONG | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c long \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned long i )
+{
+ return output_int( I_LONG | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes a \c float to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( float f )
+{
+ return *this << (double)f;
+}
+
+
+/*!
+ Writes a \c double to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ char buf[64];
+ char f_char;
+ char format[16];
+ if ( (flags()&floatfield) == fixed )
+ f_char = 'f';
+ else if ( (flags()&floatfield) == scientific )
+ f_char = (flags() & uppercase) ? 'E' : 'e';
+ else
+ f_char = (flags() & uppercase) ? 'G' : 'g';
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f_char>"
+ *fs++ = '.';
+ int prec = precision();
+ if ( prec > 99 )
+ prec = 99;
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f_char;
+ *fs = '\0';
+ sprintf( buf, format, f ); // convert to text
+ if ( fwidth ) // padding
+ *this << (const char*)buf;
+ else // just write it
+ writeBlock( buf, qstrlen(buf) );
+ return *this;
+}
+
+
+/*!
+ Writes a string to the stream and returns a reference to the stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
+*/
+
+QTextStream &QTextStream::operator<<( const char* s )
+{
+ CHECK_STREAM_PRECOND
+ char padbuf[48];
+ uint len = qstrlen( s ); // don't write null terminator
+ if ( fwidth ) { // field width set
+ int padlen = fwidth - len;
+ fwidth = 0; // reset width
+ if ( padlen > 0 ) {
+ char *ppad;
+ if ( padlen > 46 ) { // create extra big fill buffer
+ ppad = new char[padlen];
+ CHECK_PTR( ppad );
+ } else {
+ ppad = padbuf;
+ }
+ memset( ppad, (char)fillchar, padlen ); // fill with fillchar
+ if ( !(flags() & left) ) {
+ writeBlock( ppad, padlen );
+ padlen = 0;
+ }
+ writeBlock( s, len );
+ if ( padlen )
+ writeBlock( ppad, padlen );
+ if ( ppad != padbuf ) // delete extra big fill buf
+ delete[] ppad;
+ return *this;
+ }
+ }
+ writeBlock( s, len );
+ return *this;
+}
+
+/*!
+ Writes \a s to the stream and returns a reference to the stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
+*/
+
+QTextStream &QTextStream::operator<<( const QCString & s )
+{
+ return operator<<(s.data());
+}
+
+/*!
+ Writes \a s to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( const QString& s )
+{
+ CHECK_STREAM_PRECOND
+ uint len = s.length();
+ QString s1 = s;
+ if ( fwidth ) { // field width set
+ if ( !(flags() & left) ) {
+ s1 = s.rightJustify(fwidth, (char)fillchar);
+ } else {
+ s1 = s.leftJustify(fwidth, (char)fillchar);
+ }
+ fwidth = 0; // reset width
+ }
+ writeBlock( s1.unicode(), len );
+ return *this;
+}
+
+
+/*!
+ Writes a pointer to the stream and returns a reference to the stream.
+
+ The \e ptr is output as an unsigned long hexadecimal integer.
+*/
+
+QTextStream &QTextStream::operator<<( void *ptr )
+{
+ int f = flags();
+ setf( hex, basefield );
+ setf( showbase );
+ unsetf( uppercase );
+ output_int( I_LONG | I_UNSIGNED, (uintptr_t)ptr, FALSE );
+ flags( f );
+ return *this;
+}
+
+
+/*!
+ \fn int QTextStream::flags() const
+ Returns the current stream flags. The default value is 0.
+
+ The meaning of the flags are:
+ <ul>
+ <li> \e skipws - Not currently used - whitespace always skipped
+ <li> \e left - Numeric fields are left-aligned
+ <li> \e right - Not currently used (by default numerics are right aligned)
+ <li> \e internal - Put any padding spaces between +/- and value
+ <li> \e bin - Output \e and input only in binary
+ <li> \e oct - Output \e and input only in octal
+ <li> \e dec - Output \e and input only in decimal
+ <li> \e hex - Output \e and input only in hexadecimal
+ <li> \e showbase - Annotate numeric outputs with 0b, 0, or 0x if in
+ \e bin, \e oct, or \e hex format
+ <li> \e showpoint - Not currently used
+ <li> \e uppercase - Use 0B and 0X rather than 0b and 0x
+ <li> \e showpos - Show + for positive numeric values
+ <li> \e scientific - Use scientific notation for floating point values
+ <li> \e fixed - Use fixed-point notation for floating point values
+ </ul>
+
+ Note that unless \e bin, \e oct, \e dec, or \e hex is set, the input base is
+ octal if the value starts with 0, hexadecimal if it starts with 0x, binary
+ if the value starts with 0b, and decimal otherwise.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::flags( int f )
+ Sets the stream flags to \e f.
+ Returns the previous stream flags.
+
+ \sa setf(), unsetf(), flags()
+*/
+
+/*!
+ \fn int QTextStream::setf( int bits )
+ Sets the stream flag bits \e bits.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( flags() | bits )</code>.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::setf( int bits, int mask )
+ Sets the stream flag bits \e bits with a bit mask \e mask.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( (flags() & ~mask) | (bits & mask) )</code>.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::unsetf( int bits )
+ Clears the stream flag bits \e bits.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( flags() & ~mask )</code>.
+
+ \sa setf()
+*/
+
+/*!
+ \fn int QTextStream::width() const
+ Returns the field width. The default value is 0.
+*/
+
+/*!
+ \fn int QTextStream::width( int w )
+ Sets the field width to \e w. Returns the previous field width.
+*/
+
+/*!
+ \fn int QTextStream::fill() const
+ Returns the fill character. The default value is ' ' (space).
+*/
+
+/*!
+ \fn int QTextStream::fill( int f )
+ Sets the fill character to \e f. Returns the previous fill character.
+*/
+
+/*!
+ \fn int QTextStream::precision() const
+ Returns the precision. The default value is 6.
+*/
+
+/*!
+ \fn int QTextStream::precision( int p )
+ Sets the precision to \e p. Returns the previous precision setting.
+*/
+
+
+ /*****************************************************************************
+ QTextStream manipulators
+ *****************************************************************************/
+
+QTextStream &bin( QTextStream &s )
+{
+ s.setf(QTS::bin,QTS::basefield);
+ return s;
+}
+
+QTextStream &oct( QTextStream &s )
+{
+ s.setf(QTS::oct,QTS::basefield);
+ return s;
+}
+
+QTextStream &dec( QTextStream &s )
+{
+ s.setf(QTS::dec,QTS::basefield);
+ return s;
+}
+
+QTextStream &hex( QTextStream &s )
+{
+ s.setf(QTS::hex,QTS::basefield);
+ return s;
+}
+
+QTextStream &endl( QTextStream &s )
+{
+ return s << '\n';
+}
+
+QTextStream &flush( QTextStream &s )
+{
+ if ( s.device() )
+ s.device()->flush();
+ return s;
+}
+
+QTextStream &ws( QTextStream &s )
+{
+ s.skipWhiteSpace();
+ return s;
+}
+
+QTextStream &reset( QTextStream &s )
+{
+ s.reset();
+ return s;
+}
+
+
+/*!
+ \class QTextIStream qtextstream.h
+ \brief A convenience class for input streams.
+
+ For simple tasks, code should be simple. Hence this
+ class is a shorthand to avoid passing the \e mode argument
+ to the normal QTextStream constructors.
+
+ This makes it easy for example, to write things like this:
+\code
+ QString data = "123 456";
+ int a, b;
+ QTextIStream(&data) >> a >> b;
+\endcode
+
+ \sa QTextOStream
+*/
+
+/*!
+ \fn QTextIStream::QTextIStream( QString *s )
+
+ Constructs a stream to read from string \a s.
+*/
+/*!
+ \fn QTextIStream::QTextIStream( QByteArray ba )
+
+ Constructs a stream to read from the array \a ba.
+*/
+/*!
+ \fn QTextIStream::QTextIStream( FILE *f )
+
+ Constructs a stream to read from the file \a f.
+*/
+
+
+/*!
+ \class QTextOStream qtextstream.h
+ \brief A convenience class for output streams.
+
+ For simple tasks, code should be simple. Hence this
+ class is a shorthand to avoid passing the \e mode argument
+ to the normal QTextStream constructors.
+
+ This makes it easy for example, to write things like this:
+\code
+ QString result;
+ QTextOStream(&result) << "pi = " << 3.14;
+\endcode
+*/
+
+/*!
+ \fn QTextOStream::QTextOStream( QString *s )
+
+ Constructs a stream to write to string \a s.
+*/
+/*!
+ \fn QTextOStream::QTextOStream( QByteArray ba )
+
+ Constructs a stream to write to the array \a ba.
+*/
+/*!
+ \fn QTextOStream::QTextOStream( FILE *f )
+
+ Constructs a stream to write to the file \a f.
+*/
+
+
+
+/*!
+ Sets the encoding of this stream to \a e, where \a e is one of:
+ <ul>
+ <li> \c Locale Using local file format (Latin1 if locale is not
+ set), but autodetecting Unicode(utf16) on input.
+ <li> \c Unicode Using Unicode(utf16) for input and output. Output
+ will be written in the order most efficient for the current platform
+ (i.e. the order used internally in QString).
+ <li> \c UnicodeUTF8 Using Unicode(utf8) for input and output. If you use it
+ for input it will autodetect utf16 and use it instead of utf8.
+ <li> \c Latin1 ISO-8859-1. Will not autodetect utf16.
+ <li> \c UnicodeNetworkOrder Using network order Unicode(utf16) for
+ input and output. Useful when reading Unicode data that does not
+ start with the byte order marker.
+ <li> \c UnicodeReverse Using reverse network order Unicode(utf16)
+ for input and output. Useful when reading Unicode data that does not
+ start with the byte order marker, or writing data that should be
+ read by buggy Windows applications.
+ <li> \c RawUnicode Like Unicode, but does not write the byte order
+ marker, nor does it autodetect the byte order. Only useful when
+ writing to non-persistent storage used by a single process.
+ </ul>
+
+ \c Locale and all Unicode encodings, except \c RawUnicode, will look at
+ the first two bytes in a input stream to determine the byte order. The
+ initial byte order marker will be stripped off before data is read.
+
+ Note that this function should be called before any data is read
+ to/written from the stream.
+ \sa setCodec()
+*/
+
+void QTextStream::setEncoding( Encoding e )
+{
+ if ( d->sourceType == QTextStreamPrivate::String )
+ return; // QString does not need any encoding
+ switch ( e ) {
+ case Unicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+ break;
+ case UnicodeUTF8:
+#ifndef QT_NO_CODECS
+ mapper = QTextCodec::codecForMib( 106 );
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+#else
+ mapper = 0;
+ latin1 = TRUE;
+ doUnicodeHeader = TRUE;
+#endif
+ break;
+ case UnicodeNetworkOrder:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = QChar::networkOrdered();
+ break;
+ case UnicodeReverse:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = !QChar::networkOrdered(); //reverse network ordered
+ break;
+ case RawUnicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = FALSE;
+ internalOrder = TRUE;
+ break;
+ case Locale:
+ latin1 = TRUE; // fallback to Latin 1
+#ifndef QT_NO_TEXTCODEC
+ mapper = QTextCodec::codecForLocale();
+#if defined(_OS_WIN32_)
+ if ( GetACP() == 1252 )
+ mapper = 0; // Optimized latin1 processing
+#endif
+ if ( mapper && mapper->mibEnum() == 4 )
+#endif
+ mapper = 0; // Optimized latin1 processing
+ doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
+ break;
+ case Latin1:
+ mapper = 0;
+ doUnicodeHeader = FALSE;
+ latin1 = TRUE;
+ break;
+ }
+}
+
+
+#ifndef QT_NO_TEXTCODEC
+/*! Sets the codec for this stream to \a codec. Will not try to
+ autodetect Unicode.
+
+ Note that this function should be called before any data is read
+ to/written from the stream.
+
+ \sa setEncoding()
+*/
+
+void QTextStream::setCodec( QTextCodec *codec )
+{
+ if ( d->sourceType == QTextStreamPrivate::String )
+ return; // QString does not need any codec
+ mapper = codec;
+ doUnicodeHeader = FALSE;
+}
+#endif
+
+#endif // QT_NO_TEXTSTREAM
diff --git a/qtools/qtextstream.h b/qtools/qtextstream.h
new file mode 100644
index 0000000..c5f5ba1
--- /dev/null
+++ b/qtools/qtextstream.h
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+**
+** Definition of QTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QTEXTSTREAM_H
+#define QTEXTSTREAM_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#include <stdio.h>
+#endif // QT_H
+
+#ifndef QT_NO_TEXTSTREAM
+class QTextCodec;
+class QTextDecoder;
+
+class QTextStreamPrivate;
+
+class Q_EXPORT QTextStream // text stream class
+{
+public:
+ enum Encoding { Locale, Latin1, Unicode, UnicodeNetworkOrder,
+ UnicodeReverse, RawUnicode, UnicodeUTF8 };
+
+ void setEncoding( Encoding );
+#ifndef QT_NO_TEXTCODEC
+ void setCodec( QTextCodec* );
+#endif
+
+ // Encoding encoding() const { return cmode; }
+
+ QTextStream();
+ QTextStream( QIODevice * );
+ QTextStream( QString*, int mode );
+ QTextStream( QString&, int mode ); // obsolete
+ QTextStream( QByteArray, int mode );
+ QTextStream( FILE *, int mode );
+ virtual ~QTextStream();
+
+ QIODevice *device() const;
+ void setDevice( QIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ QTextStream &operator>>( QChar & );
+ QTextStream &operator>>( char & );
+ QTextStream &operator>>( signed short & );
+ QTextStream &operator>>( unsigned short & );
+ QTextStream &operator>>( signed int & );
+ QTextStream &operator>>( unsigned int & );
+ QTextStream &operator>>( signed long & );
+ QTextStream &operator>>( unsigned long & );
+ QTextStream &operator>>( float & );
+ QTextStream &operator>>( double & );
+ QTextStream &operator>>( char * );
+ QTextStream &operator>>( QString & );
+ QTextStream &operator>>( QCString & );
+
+ QTextStream &operator<<( QChar );
+ QTextStream &operator<<( char );
+ QTextStream &operator<<( signed short );
+ QTextStream &operator<<( unsigned short );
+ QTextStream &operator<<( signed int );
+ QTextStream &operator<<( unsigned int );
+ QTextStream &operator<<( signed long );
+ QTextStream &operator<<( unsigned long );
+ QTextStream &operator<<( float );
+ QTextStream &operator<<( double );
+ QTextStream &operator<<( const char* );
+ QTextStream &operator<<( const QString & );
+ QTextStream &operator<<( const QCString & );
+ QTextStream &operator<<( void * ); // any pointer
+
+ QTextStream &readRawBytes( char *, uint len );
+ QTextStream &writeRawBytes( const char* , uint len );
+
+ QString readLine();
+ QString read();
+ void skipWhiteSpace();
+
+ enum {
+ skipws = 0x0001, // skip whitespace on input
+ left = 0x0002, // left-adjust output
+ right = 0x0004, // right-adjust output
+ internal = 0x0008, // pad after sign
+ bin = 0x0010, // binary format integer
+ oct = 0x0020, // octal format integer
+ dec = 0x0040, // decimal format integer
+ hex = 0x0080, // hex format integer
+ showbase = 0x0100, // show base indicator
+ showpoint = 0x0200, // force decimal point (float)
+ uppercase = 0x0400, // upper-case hex output
+ showpos = 0x0800, // add '+' to positive integers
+ scientific= 0x1000, // scientific float output
+ fixed = 0x2000 // fixed float output
+ };
+
+ static const int basefield; // bin | oct | dec | hex
+ static const int adjustfield; // left | right | internal
+ static const int floatfield; // scientific | fixed
+
+ int flags() const;
+ int flags( int f );
+ int setf( int bits );
+ int setf( int bits, int mask );
+ int unsetf( int bits );
+
+ void reset();
+
+ int width() const;
+ int width( int );
+ int fill() const;
+ int fill( int );
+ int precision() const;
+ int precision( int );
+
+private:
+ long input_int();
+ void init();
+ QTextStream &output_int( int, ulong, bool );
+ QIODevice *dev;
+ bool isNetworkOrder() { return internalOrder == QChar::networkOrdered(); }
+
+ int fflags;
+ int fwidth;
+ int fillchar;
+ int fprec;
+ bool fstrm;
+ bool owndev;
+ QTextCodec *mapper;
+ QTextStreamPrivate * d;
+ QChar ungetcBuf;
+ bool latin1;
+ bool internalOrder;
+ bool doUnicodeHeader;
+ void *reserved_ptr;
+
+ QChar eat_ws();
+ void ts_ungetc( QChar );
+ QChar ts_getc();
+ uint ts_getbuf( QChar*, uint );
+ void ts_putc(int);
+ void ts_putc(QChar);
+ bool ts_isspace(QChar);
+ bool ts_isdigit(QChar);
+ ulong input_bin();
+ ulong input_oct();
+ ulong input_dec();
+ ulong input_hex();
+ double input_double();
+ QTextStream &writeBlock( const char* p, uint len );
+ QTextStream &writeBlock( const QChar* p, uint len );
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QTextStream( const QTextStream & );
+ QTextStream &operator=( const QTextStream & );
+#endif
+};
+
+typedef QTextStream QTS;
+
+class Q_EXPORT QTextIStream : public QTextStream {
+public:
+ QTextIStream( QString* s ) :
+ QTextStream(s,IO_ReadOnly) { }
+ QTextIStream( QByteArray ba ) :
+ QTextStream(ba,IO_ReadOnly) { }
+ QTextIStream( FILE *f ) :
+ QTextStream(f,IO_ReadOnly) { }
+};
+
+class Q_EXPORT QTextOStream : public QTextStream {
+public:
+ QTextOStream( QString* s ) :
+ QTextStream(s,IO_WriteOnly) { }
+ QTextOStream( QByteArray ba ) :
+ QTextStream(ba,IO_WriteOnly) { }
+ QTextOStream( FILE *f ) :
+ QTextStream(f,IO_WriteOnly) { }
+};
+
+/*****************************************************************************
+ QTextStream inline functions
+ *****************************************************************************/
+
+inline QIODevice *QTextStream::device() const
+{ return dev; }
+
+inline bool QTextStream::atEnd() const
+{ return dev ? dev->atEnd() : FALSE; }
+
+inline bool QTextStream::eof() const
+{ return atEnd(); }
+
+inline int QTextStream::flags() const
+{ return fflags; }
+
+inline int QTextStream::flags( int f )
+{ int oldf = fflags; fflags = f; return oldf; }
+
+inline int QTextStream::setf( int bits )
+{ int oldf = fflags; fflags |= bits; return oldf; }
+
+inline int QTextStream::setf( int bits, int mask )
+{ int oldf = fflags; fflags = (fflags & ~mask) | (bits & mask); return oldf; }
+
+inline int QTextStream::unsetf( int bits )
+{ int oldf = fflags; fflags &= ~bits; return oldf; }
+
+inline int QTextStream::width() const
+{ return fwidth; }
+
+inline int QTextStream::width( int w )
+{ int oldw = fwidth; fwidth = w; return oldw; }
+
+inline int QTextStream::fill() const
+{ return fillchar; }
+
+inline int QTextStream::fill( int f )
+{ int oldc = fillchar; fillchar = f; return oldc; }
+
+inline int QTextStream::precision() const
+{ return fprec; }
+
+inline int QTextStream::precision( int p )
+{ int oldp = fprec; fprec = p; return oldp; }
+
+/*!
+ Returns one character from the stream, or EOF.
+*/
+inline QChar QTextStream::ts_getc()
+{ QChar r; return ( ts_getbuf( &r,1 ) == 1 ? r : QChar((ushort)0xffff) ); }
+
+/*****************************************************************************
+ QTextStream manipulators
+ *****************************************************************************/
+
+typedef QTextStream & (*QTSFUNC)(QTextStream &);// manipulator function
+typedef int (QTextStream::*QTSMFI)(int); // manipulator w/int argument
+
+class Q_EXPORT QTSManip { // text stream manipulator
+public:
+ QTSManip( QTSMFI m, int a ) { mf=m; arg=a; }
+ void exec( QTextStream &s ) { (s.*mf)(arg); }
+private:
+ QTSMFI mf; // QTextStream member function
+ int arg; // member function argument
+};
+
+Q_EXPORT inline QTextStream &operator>>( QTextStream &s, QTSFUNC f )
+{ return (*f)( s ); }
+
+Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSFUNC f )
+{ return (*f)( s ); }
+
+Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSManip m )
+{ m.exec(s); return s; }
+
+Q_EXPORT QTextStream &bin( QTextStream &s ); // set bin notation
+Q_EXPORT QTextStream &oct( QTextStream &s ); // set oct notation
+Q_EXPORT QTextStream &dec( QTextStream &s ); // set dec notation
+Q_EXPORT QTextStream &hex( QTextStream &s ); // set hex notation
+Q_EXPORT QTextStream &endl( QTextStream &s ); // insert EOL ('\n')
+Q_EXPORT QTextStream &flush( QTextStream &s ); // flush output
+Q_EXPORT QTextStream &ws( QTextStream &s ); // eat whitespace on input
+Q_EXPORT QTextStream &reset( QTextStream &s ); // set default flags
+
+Q_EXPORT inline QTSManip qSetW( int w )
+{
+ QTSMFI func = &QTextStream::width;
+ return QTSManip(func,w);
+}
+
+Q_EXPORT inline QTSManip qSetFill( int f )
+{
+ QTSMFI func = &QTextStream::fill;
+ return QTSManip(func,f);
+}
+
+Q_EXPORT inline QTSManip qSetPrecision( int p )
+{
+ QTSMFI func = &QTextStream::precision;
+ return QTSManip(func,p);
+}
+
+
+#ifndef QT_ALTERNATE_QTSMANIP
+
+// These will go away in Qt 3.0, as they conflict with std libs
+//
+// If you get conflicts now, #define QT_ALTERNATE_QTSMANIP before
+// including this file.
+
+Q_EXPORT inline QTSManip setw( int w )
+{
+ QTSMFI func = &QTextStream::width;
+ return QTSManip(func,w);
+}
+
+Q_EXPORT inline QTSManip setfill( int f )
+{
+ QTSMFI func = &QTextStream::fill;
+ return QTSManip(func,f);
+}
+
+Q_EXPORT inline QTSManip setprecision( int p )
+{
+ QTSMFI func = &QTextStream::precision;
+ return QTSManip(func,p);
+}
+#endif
+
+#endif // QT_NO_TEXTSTREAM
+#endif // QTEXTSTREAM_H
diff --git a/qtools/qthread.cpp b/qtools/qthread.cpp
new file mode 100644
index 0000000..db2a0de
--- /dev/null
+++ b/qtools/qthread.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qthread.h"
+#include "qthread_p.h"
+
+QThread::QThread()
+ : d(new QThreadPrivate)
+{
+}
+
+QThread::~QThread()
+{
+ QMutexLocker locker(&d->mutex);
+ if (d->running && !d->finished)
+ qWarning("QThread: Destroyed while thread is still running");
+}
+
+bool QThread::isFinished() const
+{
+ QMutexLocker locker(&d->mutex);
+ return d->finished;
+}
+
+bool QThread::isRunning() const
+{
+ QMutexLocker locker(&d->mutex);
+ return d->running;
+}
+
+void QThread::setStackSize(unsigned int stackSize)
+{
+ QMutexLocker locker(&d->mutex);
+ if (d->running)
+ {
+ qWarning("QThread: Cannot change stack size while thread is running!");
+ return;
+ }
+ d->stackSize = stackSize;
+}
+
+unsigned int QThread::stackSize() const
+{
+ QMutexLocker locker(&d->mutex);
+ return d->stackSize;
+}
+
diff --git a/qtools/qthread.h b/qtools/qthread.h
new file mode 100644
index 0000000..81868bd
--- /dev/null
+++ b/qtools/qthread.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHREAD_H
+#define QTHREAD_H
+
+class QThreadPrivate;
+
+class QThread
+{
+ public:
+ explicit QThread();
+ virtual ~QThread();
+
+ bool isFinished() const;
+ bool isRunning() const;
+
+ void start();
+ void terminate();
+ void wait();
+ void setStackSize(unsigned int stackSize);
+ unsigned int stackSize() const;
+ static int idealThreadCount();
+
+protected:
+ // events
+ virtual void started() {}
+ virtual void finished() {}
+ virtual void terminated() {}
+
+ // main loop
+ virtual void run() {}
+
+private:
+ QThreadPrivate *d;
+ friend class QThreadPrivate;
+};
+
+#endif // QTHREAD_H
diff --git a/qtools/qthread_p.h b/qtools/qthread_p.h
new file mode 100644
index 0000000..87692aa
--- /dev/null
+++ b/qtools/qthread_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHREAD_P_H
+#define QTHREAD_P_H
+
+#include "qglobal.h"
+
+#if defined(_OS_UNIX_) || defined(_OS_MAC_)
+#include <pthread.h>
+#elif defined(_OS_WIN32_)
+#include <windows.h>
+#endif
+
+#include "qthread.h"
+#include "qmutex.h"
+#include "qwaitcondition.h"
+
+class QThreadPrivate
+{
+public:
+ QThreadPrivate();
+ ~QThreadPrivate();
+
+ mutable QMutex mutex;
+
+ bool running;
+ bool finished;
+ bool terminated;
+ uint stackSize;
+
+#if defined(_OS_UNIX_) || defined(_OS_MAC_)
+ pthread_t thread_id;
+ QWaitCondition thread_done;
+ static void *start(void *arg);
+ static void finish(void *arg);
+#elif defined(_OS_WIN32_)
+ HANDLE handle;
+ static unsigned int __stdcall start(void *);
+ static void finish(void *,bool lockAnyway=TRUE);
+ int waiters;
+#else
+#error "unsupported platform!"
+#endif
+};
+
+#endif // QTHREAD_P_H
diff --git a/qtools/qthread_unix.cpp b/qtools/qthread_unix.cpp
new file mode 100644
index 0000000..b536583
--- /dev/null
+++ b/qtools/qthread_unix.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#if defined(_OS_HPUX_)
+#include <sys/pstat.h>
+#elif defined(_OS_MAC_)
+#undef DEBUG
+#include <CoreServices/CoreServices.h>
+#elif defined(_OS_BSDI_)
+#include <mach/mach_types.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "qthread.h"
+#include "qthread_p.h"
+
+
+/**************************************************************************
+ ** QThreadPrivate
+ *************************************************************************/
+
+QThreadPrivate::QThreadPrivate() :
+ running(FALSE), finished(FALSE), terminated(FALSE), stackSize(0)
+{
+ thread_id = 0;
+}
+
+QThreadPrivate::~QThreadPrivate()
+{
+}
+
+void *QThreadPrivate::start(void *arg)
+{
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ pthread_cleanup_push(QThreadPrivate::finish, arg);
+
+ QThread *thr = reinterpret_cast<QThread *>(arg);
+
+ thr->started();
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_testcancel();
+ thr->run();
+
+ pthread_cleanup_pop(1);
+ return 0;
+}
+
+void QThreadPrivate::finish(void *arg)
+{
+ QThread *thr = reinterpret_cast<QThread *>(arg);
+ QThreadPrivate *d = thr->d;
+ QMutexLocker locker(&d->mutex);
+
+ d->running = FALSE;
+ d->finished = TRUE;
+ if (d->terminated)
+ thr->terminated();
+ d->terminated = FALSE;
+ thr->finished();
+
+ d->thread_id = 0;
+ d->thread_done.wakeAll();
+}
+
+
+
+
+/**************************************************************************
+ ** QThread
+ *************************************************************************/
+
+void QThread::start()
+{
+ QMutexLocker locker(&d->mutex);
+ if (d->running) return;
+
+ // Block the SIGINT signal. The threads will inherit the signal mask.
+ // This will avoid them catching SIGINT instead of this thread.
+ sigset_t sigset, oldset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ pthread_sigmask(SIG_BLOCK, &sigset, &oldset);
+
+ d->running = TRUE;
+ d->finished = FALSE;
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+ if (d->stackSize>0)
+ {
+#if defined(_POSIX_THREAD_ATTR_STACKSIZE) && (_POSIX_THREAD_ATTR_STACKSIZE-0>0)
+ pthread_attr_setstacksize(&attr,d->stackSize);
+#endif
+ }
+ int code = pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
+ pthread_attr_destroy(&attr);
+
+ if (code)
+ {
+ qWarning("QThread::start: Thread creation error: %d", code);
+
+ d->running = FALSE;
+ d->finished = FALSE;
+ d->thread_id = 0;
+ }
+ else
+ {
+ // Restore the old signal mask only for this thread.
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ }
+}
+
+void QThread::terminate()
+{
+ QMutexLocker locker(&d->mutex);
+
+ if (!d->thread_id) return;
+
+ int code = pthread_cancel(d->thread_id);
+ if (code)
+ {
+ qWarning("QThread::start: Thread termination error: %d", code);
+ }
+ else
+ {
+ d->terminated = TRUE;
+ }
+}
+
+void QThread::wait()
+{
+ QMutexLocker locker(&d->mutex);
+ if (d->finished || !d->running) return;
+
+ while (d->running)
+ {
+ d->thread_done.wait(locker.mutex());
+ }
+}
+
+#if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)
+// LSB doesn't define _SC_NPROCESSORS_ONLN.
+# define _SC_NPROCESSORS_ONLN 84
+#endif
+
+int QThread::idealThreadCount()
+{
+ int cores = -1;
+#if defined(_OS_MAC_)
+ // Mac OS X
+ cores = (int)MPProcessorsScheduled();
+#elif defined(_OS_HPUX_)
+ // HP-UX
+ struct pst_dynamic psd;
+ if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1)
+ {
+ perror("pstat_getdynamic");
+ cores = -1;
+ }
+ else
+ {
+ cores = (int)psd.psd_proc_cnt;
+ }
+#elif defined(_OS_BSDI_)
+ // FreeBSD, OpenBSD, NetBSD, BSD/OS
+ size_t len = sizeof(cores);
+ int mib[2];
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+
+ if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0)
+ {
+ perror("sysctl");
+ cores = -1;
+ }
+#elif defined(_OS_IRIX_)
+ // IRIX
+ cores = (int)sysconf(_SC_NPROC_ONLN);
+#else
+ // the rest: Linux, Solaris, AIX, Tru64
+ cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+ return cores;
+}
+
diff --git a/qtools/qthread_win32.cpp b/qtools/qthread_win32.cpp
new file mode 100644
index 0000000..2c62e93
--- /dev/null
+++ b/qtools/qthread_win32.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qthread.h"
+#include "qthread_p.h"
+
+/**************************************************************************
+ ** QThreadPrivate
+ *************************************************************************/
+
+QThreadPrivate::QThreadPrivate() :
+ running(FALSE), finished(FALSE), terminated(FALSE), stackSize(0)
+{
+ handle = NULL;
+ waiters = 0;
+}
+
+QThreadPrivate::~QThreadPrivate()
+{
+}
+
+unsigned int __stdcall QThreadPrivate::start(void *arg)
+{
+ QThread *thr = reinterpret_cast<QThread *>(arg);
+ thr->started();
+ thr->run();
+ finish(arg);
+ return 0;
+}
+
+void QThreadPrivate::finish(void *arg,bool lockAnyway)
+{
+ QThread *thr = reinterpret_cast<QThread *>(arg);
+ QThreadPrivate *d = thr->d;
+
+ if (lockAnyway) d->mutex.lock();
+
+ d->running = FALSE;
+ d->finished = TRUE;
+ if (d->terminated) thr->terminated();
+ d->terminated = FALSE;
+ thr->finished();
+
+ if (!d->waiters)
+ {
+ CloseHandle(d->handle);
+ d->handle = 0;
+ }
+
+ if (lockAnyway) d->mutex.unlock();
+}
+
+/**************************************************************************
+ ** QThread
+ *************************************************************************/
+
+void QThread::start()
+{
+ QMutexLocker locker(&d->mutex);
+
+ if (d->running) return;
+
+ d->running = TRUE;
+ d->finished = FALSE;
+ d->terminated = FALSE;
+
+ d->handle = CreateThread(NULL,d->stackSize,
+ (LPTHREAD_START_ROUTINE)QThreadPrivate::start,this,0,NULL);
+
+ if (!d->handle)
+ {
+ qWarning("QThread::start: Failed to create thread: errno=%d",errno);
+ d->running = FALSE;
+ d->finished = TRUE;
+ return;
+ }
+}
+
+void QThread::terminate()
+{
+ QMutexLocker locker(&d->mutex);
+ if (!d->running) return;
+ TerminateThread(d->handle, 0);
+ d->terminated = TRUE;
+ QThreadPrivate::finish(this);
+}
+
+void QThread::wait()
+{
+ QMutexLocker locker(&d->mutex);
+ if (d->finished || !d->running) return;
+
+ ++d->waiters;
+ locker.mutex()->unlock();
+
+ WaitForSingleObject(d->handle,INFINITE);
+
+ locker.mutex()->lock();
+ --d->waiters;
+ if (!d->finished) // thread was terminated by someone else
+ {
+ d->terminated = TRUE;
+ QThreadPrivate::finish(this);
+ }
+
+ if (d->finished && d->waiters)
+ {
+ CloseHandle(d->handle);
+ d->handle = 0;
+ }
+}
+
+int QThread::idealThreadCount()
+{
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+}
+
+
diff --git a/qtools/qtl.doc b/qtools/qtl.doc
new file mode 100644
index 0000000..db5b994
--- /dev/null
+++ b/qtools/qtl.doc
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+**
+** Qt template library classes documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/*!
+\page qtl.html
+
+\title Qt Template library
+
+Thq Qt Template Library is a set of templates within Qt dealing with
+containers of objects. It provides a list of objects, a stack of
+objects, a map (or dictionary) from one type to another, and
+associated iterators and algorithms.
+
+Qt also contains similar classes that deal with pointers to objects;
+\l QValueList vs. \l QList, etc. Compared to the pointer-based
+templates, the QTL offers easy copying of the container, real support
+for classes that e.g. require constructors, expand to much more object
+code, can often be a bit faster, require that the objects stored can
+be copied, and finally, have a worse record of compiler problems.
+
+Compared to the STL, the QTL contains only the most important features
+of the STL, has more regular function naming, has no platform
+differences, is often a little slower and often expands to less object
+code.
+
+
+If you can not make copies of the objects you want to store you are
+better off with QCollection and friends. They were designed to handle
+exactly that kind of pointer semantics. This applies for example to
+all classes derived from \l QObject. A QObject does not have a copy
+constructor, so using it as value is impossible. You may choose be
+store pointers to QObjects in a QValueList, but using QList directly
+seems to be the better choice for this kind of application
+domain. QList, like all other QCollection based containers, provides
+far more sanity checking than a speed-optimized value
+based container.
+
+If you have objects that implement value semantics, use the Qt
+template library. Value semantics require at least
+<ul>
+<li>a copy constructor,
+<li>an assignment operator and
+<li> a default constructor, i.e. a constructor that does not take
+any arguments.
+</ul>
+Note that a fast copy constructor is absolutely crucial for a good
+overall performance of the container, since many copy operations are
+going to happen.
+
+Examples for value based classes are QRect, QPoint, QSize and all
+simple C++ types like int, bool or double.
+
+The Qt template library is designed for speed. Especially iterators
+are extremely fast. On the drawback side, less error checking is done
+than in the QCollection based containers. A template library container
+for example does not track associated iterators. This makes certain
+validity checks, like on removing items, impossible to perform
+automatically.
+
+<h2> Iterators </h2>
+
+The Qt template library deals with value objects, not with pointers.
+For that reason, there is no other way of iterating over containers
+than using iterators. This is no disadvantage as the size of an
+iterator matches the size of a normal pointer - 32 or 64 bits
+depending on your CPU architecture.
+
+To iterate over a container, use a loop like this:
+
+\code
+ typedef QValueList<int> List;
+ List l;
+ for( List::Iterator it = l.begin(); it != l.end(); ++it )
+ printf("Number is %i\n",*it);
+\endcode
+
+begin() returns the iterator pointing at the first element, while
+end() returns an iterator that points \e after the last
+element. end() marks an invalid position, it can never be
+dereferenced. It's the break condition in any iteration, may it be
+from begin() or fromLast(). For maximum speed, use increment or
+decrement iterators with the prefix operator (++it, --it) instead of the the
+postfix one (it++, it--), since the former is slightly faster.
+
+The same concept applies to the other container classes:
+
+\code
+ typedef QMap<QString,QString> Map;
+ Map map;
+ for( Map::Iterator it = map.begin(); it != map.end(); ++it )
+ printf("Key=%s Data=%s\n", it.key().ascii(), it.data().ascii() );
+
+ typedef QArray<int> Array;
+ Array array;
+ for( Array::Iterator it = array.begin(); it != array.end(); ++it )
+ printf("Data=%i\n", *it );
+\endcode
+
+There are two kind of iterators, the volatile iterator shown in the
+examples above and a version that returns a const reference to its
+current object, the ConstIterator. Const iterators are required
+whenever the container itself is const, such as a member variable
+inside a const function. Assigning a ConstIterator to a normal
+Iterator is not allowed as it would violate const semantics.
+
+<h2> Algorithms </h2>
+
+The template library defines a number of algorithms that operate on
+its containers: qHeapSort(), qBubbleSort(), qSwap() and
+qCopy(). These algorithms are implemented as template functions.
+
+qHeapSort() and qBubbleSort() provide the well known sorting
+algorithms. You can use them like this:
+
+\code
+ typedef QValueList<int> List;
+ List l;
+ l << 42 << 100 << 1234 << 12 << 8;
+ qHeapSort( l );
+
+ List l2;
+ l2 << 42 << 100 << 1234 << 12 << 8;
+ List::Iterator b = l2.find( 100 );
+ List::Iterator e = l2.find( 8 );
+ qHeapSort( b, e );
+
+ double arr[] = { 3.2, 5.6, 8.9 };
+ qHeapSort( arr, arr + 3 );
+\endcode
+
+The first example sorts the entire list. The second one sorts all
+elements enclosed in the two iterators, namely 100, 1234 and 12. The
+third example shows that iterators act like pointers and can be
+treated as such.
+
+Naturally, the sorting templates won't work with const iterators.
+
+Another utility is qSwap(). It exchanges the values of two variables:
+
+\code
+ QString second( "Einstein" );
+ QString name( "Albert" );
+ qSwap( second, name );
+\endcode
+
+Another template function is qCopy(). It copies a container or a slice
+of it to an OutputIterator, in this case a QTextOStreamIterator:
+
+\code
+ typedef QValueList<int> List;
+ List l;
+ l << 100 << 200 << 300;
+ QTextOStream str( stdout );
+ qCopy( l, QTextOStreamIterator( str ) );
+\endcode
+
+In addition, you can use any Qt template library iterator as the
+OutputIterator. Just make sure that the right hand of the iterator has
+as many elements present as you want to insert. The following example
+illustrates this:
+
+\code
+ QStringList l1, l2;
+ l1 << "Weis" << "Ettrich" << "Arnt" << "Sue";
+ l2 << "Torben" << "Matthias";
+ qCopy( l2, l1.begin();
+\endcode
+
+At the end of this code fragment, the List l1 contains "Torben",
+"Matthias", "Arnt" and "Sue", with the prior contents being
+overwritten. Another flavor of qCopy() takes three arguments to make
+it possible to copy a slice of a container:
+
+\code
+ typedef QValueList<int> List;
+ List l;
+ l << 42 << 100 << 1234 << 12 << 8;
+ List::Iterator b = l.find( 100 );
+ List::Iterator e = l.find( 8 );
+ QTextOStream str( stdout );
+ qCopy( b, e, QTextOStreamIterator( str ) );
+\endcode
+
+If you write new algorithms, consider writing them as template
+functions in order to make them usable with as many containers
+possible. In the above example, you could just as easily print out a
+standard C++ array with qCopy():
+
+\code
+ int arr[] = { 100, 200, 300 };
+ QTextOStream str( stdout );
+ qCopy( arr, arr + 3, QTextOStreamIterator( str ) );
+\endcode
+
+
+<h2> Streaming </h2>
+
+All mentioned containers can be serialized with the respective
+streaming operators. Here is an example.
+
+\code
+ QDataStream str(...);
+ QValueList<QRect> l;
+ // ... fill the list here
+ str << l;
+\endcode
+
+The container can be read in again with:
+
+\code
+ QValueList<QRect> l;
+ str >> l;
+\endcode
+
+The same applies to QStringList, QValueStack and QMap.
+
+*/
diff --git a/qtools/qtl.h b/qtools/qtl.h
new file mode 100644
index 0000000..bd72e7d
--- /dev/null
+++ b/qtools/qtl.h
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+**
+** Definition of Qt template library classes
+**
+** Created : 990128
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef QTL_H
+#define QTL_H
+
+#ifndef QT_H
+#include "qtextstream.h"
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_TEXTSTREAM
+template <class T>
+class QTextOStreamIterator
+{
+protected:
+ QTextOStream& stream;
+ QString separator;
+
+public:
+ QTextOStreamIterator( QTextOStream& s) : stream( s ) {}
+ QTextOStreamIterator( QTextOStream& s, const QString& sep )
+ : stream( s ), separator( sep ) {}
+ QTextOStreamIterator<T>& operator= ( const T& x ) {
+ stream << x;
+ if ( !separator.isEmpty() )
+ stream << separator;
+ return *this;
+ }
+ QTextOStreamIterator<T>& operator*() { return *this; }
+ QTextOStreamIterator<T>& operator++() { return *this; }
+ QTextOStreamIterator<T>& operator++(int) { return *this; }
+};
+#endif //QT_NO_TEXTSTREAM
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator qCopy( InputIterator _begin, InputIterator _end,
+ OutputIterator _dest )
+{
+ while( _begin != _end )
+ *_dest++ = *_begin++;
+ return _dest;
+}
+
+
+template <class T>
+inline void qSwap( T& _value1, T& _value2 )
+{
+ T tmp = _value1;
+ _value1 = _value2;
+ _value2 = tmp;
+}
+
+
+template <class InputIterator>
+inline void qBubbleSort( InputIterator b, InputIterator e )
+{
+ // Goto last element;
+ InputIterator last = e;
+ --last;
+ // only one element or no elements ?
+ if ( last == b )
+ return;
+
+ // So we have at least two elements in here
+ while( b != last ) {
+ bool swapped = FALSE;
+ InputIterator swap_pos = b;
+ InputIterator x = e;
+ InputIterator y = x;
+ y--;
+ do {
+ --x;
+ --y;
+ if ( *x < *y ) {
+ swapped = TRUE;
+ qSwap( *x, *y );
+ swap_pos = y;
+ }
+ } while( y != b );
+ if ( !swapped )
+ return;
+ b = swap_pos;
+ b++;
+ }
+}
+
+
+template <class Container>
+inline void qBubbleSort( Container &c )
+{
+ qBubbleSort( c.begin(), c.end() );
+}
+
+
+template <class Value>
+inline void qHeapSortPushDown( Value* heap, int first, int last )
+{
+ int r = first;
+ while( r <= last/2 ) {
+ // Node r has only one child ?
+ if ( last == 2*r ) {
+ // Need for swapping ?
+ if ( heap[r] > heap[ 2*r ] )
+ qSwap( heap[r], heap[ 2*r ] );
+ // That's it ...
+ r = last;
+ } else { // Node has two children
+ if ( heap[r] > heap[ 2*r ] && heap[ 2*r ] <= heap[ 2*r+1 ] ) {
+ // Swap with left child
+ qSwap( heap[r], heap[ 2*r ] );
+ r *= 2;
+ } else if ( heap[r] > heap[ 2*r+1 ] &&
+ heap[ 2*r+1 ] < heap[ 2*r ] ) {
+ // Swap with right child
+ qSwap( heap[r], heap[ 2*r+1 ] );
+ r = 2*r+1;
+ } else {
+ // We are done
+ r = last;
+ }
+ }
+ }
+}
+
+
+template <class InputIterator, class Value>
+inline void qHeapSortHelper( InputIterator b, InputIterator e, Value, uint n )
+{
+ // Create the heap
+ InputIterator insert = b;
+ Value* realheap = new Value[ n ];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ Value* heap = realheap - 1;
+ int size = 0;
+ for( ; insert != e; ++insert ) {
+ heap[++size] = *insert;
+ int i = size;
+ while( i > 1 && heap[i] < heap[ i / 2 ] ) {
+ qSwap( heap[i], heap[ i / 2 ] );
+ i /= 2;
+ }
+ }
+
+ // Now do the sorting
+ for( uint i = n; i > 0; i-- ) {
+ *b++ = heap[1];
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ qHeapSortPushDown( heap, 1, (int)i - 1 );
+ }
+ }
+
+ delete[] realheap;
+}
+
+
+template <class InputIterator>
+inline void qHeapSort( InputIterator b, InputIterator e )
+{
+ // Empty ?
+ if ( b == e )
+ return;
+
+ // How many entries have to be sorted ?
+ InputIterator it = b;
+ uint n = 0;
+ while ( it != e ) {
+ ++n;
+ ++it;
+ }
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( b, e, *b, n );
+}
+
+
+template <class Container>
+inline void qHeapSort( Container &c )
+{
+ if ( c.isEmpty() )
+ return;
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( c.begin(), c.end(), *(c.begin()), c.count() );
+}
+
+#endif
diff --git a/qtools/qtools.pro b/qtools/qtools.pro
new file mode 100644
index 0000000..6679fdb
--- /dev/null
+++ b/qtools/qtools.pro
@@ -0,0 +1,109 @@
+#
+# This file was generated from qtools.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = lib
+CONFIG = warn_on staticlib debug
+HEADERS = qarray.h \
+ qbuffer.h \
+ qcache.h \
+ qgcache.h \
+ qcollection.h \
+ qconfig.h \
+ qcstring.h \
+ scstring.h \
+ qdatastream.h \
+ qdatetime.h \
+ qdict.h \
+ qdir.h \
+ qfeatures.h \
+ qfile.h \
+ qfiledefs_p.h \
+ qfileinfo.h \
+ qgarray.h \
+ qfeatures.h \
+ qgdict.h \
+ qgeneric.h \
+ qglist.h \
+ qglobal.h \
+ qgstring.h \
+ qgvector.h \
+ qintdict.h \
+ qiodevice.h \
+ qinternallist.h \
+ qptrdict.h \
+ qqueue.h \
+ qregexp.h \
+ qshared.h \
+ qsortedlist.h \
+ qstack.h \
+ qstring.h \
+ qstringlist.h \
+ qstrlist.h \
+ qstrvec.h \
+ qtextstream.h \
+ qtl.h \
+ qvaluelist.h \
+ qvector.h \
+ qxml.h \
+ qvaluestack.h \
+ qmap.h \
+ qmodules.h \
+ qthread.h \
+ qthread_p.h \
+ qmutex.h \
+ qmutex_p.h \
+ qutfcodec.h \
+ qwaitcondition.h
+
+SOURCES = qbuffer.cpp \
+ qcollection.cpp \
+ scstring.cpp \
+ qdatastream.cpp \
+ qdatetime.cpp \
+ qdir.cpp \
+ qfile.cpp \
+ qfileinfo.cpp \
+ qgarray.cpp \
+ qgcache.cpp \
+ qgdict.cpp \
+ qglist.cpp \
+ qglobal.cpp \
+ qgstring.cpp \
+ qgvector.cpp \
+ qiodevice.cpp \
+ qregexp.cpp \
+ qstring.cpp \
+ qtextstream.cpp \
+ qtextcodec.cpp \
+ qstringlist.cpp \
+ qxml.cpp \
+ qmap.cpp \
+ qthread.cpp \
+ qmutex.cpp \
+ qutfcodec.cpp
+
+unix:SOURCES += qfile_unix.cpp \
+ qdir_unix.cpp \
+ qfileinfo_unix.cpp \
+ qthread_unix.cpp \
+ qmutex_unix.cpp \
+ qwaitcondition_unix.cpp
+
+win32:SOURCES += qfile_win32.cpp \
+ qdir_win32.cpp \
+ qfileinfo_win32.cpp \
+ qthread_win32.cpp \
+ qmutex_win32.cpp \
+ qwaitcondition_win32.cpp
+
+INCLUDEPATH = .
+#TMAKE_CXXFLAGS += -DQT_NO_CODECS -DQT_LITE_UNICODE
+TMAKE_CXXFLAGS += -DQT_LITE_UNICODE
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -D__CYGWIN__ -DALL_STATIC
+OBJECTS_DIR = ../objects/qtools
+DESTDIR = ../lib
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
new file mode 100644
index 0000000..f287d34
--- /dev/null
+++ b/qtools/qtools.pro.in
@@ -0,0 +1,102 @@
+TEMPLATE = lib
+CONFIG = warn_on staticlib $extraopts
+HEADERS = qarray.h \
+ qbuffer.h \
+ qcache.h \
+ qgcache.h \
+ qcollection.h \
+ qconfig.h \
+ qcstring.h \
+ scstring.h \
+ qdatastream.h \
+ qdatetime.h \
+ qdict.h \
+ qdir.h \
+ qfeatures.h \
+ qfile.h \
+ qfiledefs_p.h \
+ qfileinfo.h \
+ qgarray.h \
+ qfeatures.h \
+ qgdict.h \
+ qgeneric.h \
+ qglist.h \
+ qglobal.h \
+ qgstring.h \
+ qgvector.h \
+ qintdict.h \
+ qiodevice.h \
+ qinternallist.h \
+ qptrdict.h \
+ qqueue.h \
+ qregexp.h \
+ qshared.h \
+ qsortedlist.h \
+ qstack.h \
+ qstring.h \
+ qstringlist.h \
+ qstrlist.h \
+ qstrvec.h \
+ qtextstream.h \
+ qtl.h \
+ qvaluelist.h \
+ qvector.h \
+ qxml.h \
+ qvaluestack.h \
+ qmap.h \
+ qmodules.h \
+ qthread.h \
+ qthread_p.h \
+ qmutex.h \
+ qmutex_p.h \
+ qutfcodec.h \
+ qwaitcondition.h
+
+SOURCES = qbuffer.cpp \
+ qcollection.cpp \
+ scstring.cpp \
+ qdatastream.cpp \
+ qdatetime.cpp \
+ qdir.cpp \
+ qfile.cpp \
+ qfileinfo.cpp \
+ qgarray.cpp \
+ qgcache.cpp \
+ qgdict.cpp \
+ qglist.cpp \
+ qglobal.cpp \
+ qgstring.cpp \
+ qgvector.cpp \
+ qiodevice.cpp \
+ qregexp.cpp \
+ qstring.cpp \
+ qtextstream.cpp \
+ qtextcodec.cpp \
+ qstringlist.cpp \
+ qxml.cpp \
+ qmap.cpp \
+ qthread.cpp \
+ qmutex.cpp \
+ qutfcodec.cpp
+
+unix:SOURCES += qfile_unix.cpp \
+ qdir_unix.cpp \
+ qfileinfo_unix.cpp \
+ qthread_unix.cpp \
+ qmutex_unix.cpp \
+ qwaitcondition_unix.cpp
+
+win32:SOURCES += qfile_win32.cpp \
+ qdir_win32.cpp \
+ qfileinfo_win32.cpp \
+ qthread_win32.cpp \
+ qmutex_win32.cpp \
+ qwaitcondition_win32.cpp
+
+INCLUDEPATH = .
+#TMAKE_CXXFLAGS += -DQT_NO_CODECS -DQT_LITE_UNICODE
+TMAKE_CXXFLAGS += -DQT_LITE_UNICODE
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -D__CYGWIN__ -DALL_STATIC
+OBJECTS_DIR = ../objects/qtools
+DESTDIR = ../lib
diff --git a/qtools/qutfcodec.cpp b/qtools/qutfcodec.cpp
new file mode 100644
index 0000000..c7094ad
--- /dev/null
+++ b/qtools/qutfcodec.cpp
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+**
+** Implementation of QEucCodec class
+**
+** Created : 981015
+**
+** Copyright (C)1998-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qutfcodec.h"
+
+#ifndef QT_NO_TEXTCODEC
+
+int QUtf8Codec::mibEnum() const
+{
+ return 106;
+}
+
+QCString QUtf8Codec::fromUnicode(const QString& uc, int& len_in_out) const
+{
+ int l = QMIN((int)uc.length(),len_in_out);
+ int rlen = l*3+1;
+ QCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ QChar ch = uc[i];
+ if ( !ch.row() && ch.cell() < 0x80 ) {
+ *cursor++ = ch.cell();
+ } else {
+ uchar b = (ch.row() << 2) | (ch.cell() >> 6);
+ if ( ch.row() < 0x08 ) {
+ *cursor++ = 0xc0 | b;
+ } else {
+ *cursor++ = 0xe0 | (ch.row() >> 4);
+ *cursor++ = 0x80 | (b&0x3f);
+ }
+ *cursor++ = 0x80 | (ch.cell()&0x3f);
+ }
+ }
+ len_in_out = (int)(cursor - (uchar*)rstr.data());
+ rstr.truncate(len_in_out);
+ return rstr;
+}
+
+const char* QUtf8Codec::name() const
+{
+ return "UTF-8";
+}
+
+int QUtf8Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 128 ) {
+ // Inconclusive
+ score++;
+ } else if ( (ch&0xe0) == 0xc0 ) {
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( (c2&0xc0) != 0x80 )
+ return -1;
+ score+=3;
+ }
+ } else if ( (ch&0xf0) == 0xe0 ) {
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( (c2&0xc0) != 0x80 ) {
+ return -1;
+#if 0
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if ( (c3&0xc0) != 0x80 )
+ return -1;
+ score+=3;
+ }
+#endif
+ }
+ score+=2;
+ }
+ }
+ }
+ return score;
+}
+
+
+
+
+class QUtf8Decoder : public QTextDecoder {
+ ushort uc;
+ int need;
+public:
+ QUtf8Decoder() : need(0)
+ {
+ }
+
+ QString toUnicode(const char* chars, int len)
+ {
+ QString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if (need) {
+ if ( (ch&0xc0) == 0x80 ) {
+ uc = (uc << 6) | (ch & 0x3f);
+ need--;
+ if ( !need ) {
+ result += QChar(uc);
+ }
+ } else {
+ // error
+ result += QChar::replacement;
+ need = 0;
+ }
+ } else {
+ if ( ch < 128 ) {
+ result += QChar(ch);
+ } else if ( (ch&0xe0) == 0xc0 ) {
+ uc = ch &0x1f;
+ need = 1;
+ } else if ( (ch&0xf0) == 0xe0 ) {
+ uc = ch &0x0f;
+ need = 2;
+ }
+ }
+ }
+ return result;
+ }
+};
+
+QTextDecoder* QUtf8Codec::makeDecoder() const
+{
+ return new QUtf8Decoder;
+}
+
+
+
+
+
+
+int QUtf16Codec::mibEnum() const
+{
+ return 1000;
+}
+
+const char* QUtf16Codec::name() const
+{
+ return "ISO-10646-UCS-2";
+}
+
+int QUtf16Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ uchar* uchars = (uchar*)chars;
+ if ( len >= 2 && ((uchars[0] == 0xff && uchars[1] == 0xfe) ||
+ (uchars[1] == 0xff && uchars[0] == 0xfe)) )
+ return len;
+ else
+ return 0;
+}
+
+
+
+
+class QUtf16Encoder : public QTextEncoder {
+ bool headerdone;
+public:
+ QUtf16Encoder() : headerdone(FALSE)
+ {
+ }
+
+ QCString fromUnicode(const QString& uc, int& len_in_out)
+ {
+ if ( headerdone ) {
+ len_in_out = uc.length()*(int)sizeof(QChar);
+ QCString d(len_in_out);
+ memcpy(d.data(),uc.unicode(),len_in_out);
+ return d;
+ } else {
+ headerdone = TRUE;
+ len_in_out = (1+uc.length())*(int)sizeof(QChar);
+ QCString d(len_in_out);
+ memcpy(d.data(),&QChar::byteOrderMark,sizeof(QChar));
+ memcpy(d.data()+sizeof(QChar),uc.unicode(),uc.length()*sizeof(QChar));
+ return d;
+ }
+ }
+};
+
+class QUtf16Decoder : public QTextDecoder {
+ uchar buf;
+ bool half;
+ bool swap;
+ bool headerdone;
+
+public:
+ QUtf16Decoder() : half(FALSE), swap(FALSE), headerdone(FALSE)
+ {
+ }
+
+ QString toUnicode(const char* chars, int len)
+ {
+ QString r;
+
+ while ( len-- ) {
+ if ( half ) {
+ QChar ch;
+ if ( swap ) {
+ ch.row() = *chars++;
+ ch.cell() = buf;
+ } else {
+ ch.row() = buf;
+ ch.cell() = *chars++;
+ }
+ if ( !headerdone ) {
+ if ( ch == QChar::byteOrderSwapped ) {
+ swap = !swap;
+ } else if ( ch == QChar::byteOrderMark ) {
+ // Ignore ZWNBSP
+ } else {
+ r += ch;
+ }
+ headerdone = TRUE;
+ } else
+ r += ch;
+ half = FALSE;
+ } else {
+ buf = *chars++;
+ half = TRUE;
+ }
+ }
+
+ return r;
+ }
+};
+
+QTextDecoder* QUtf16Codec::makeDecoder() const
+{
+ return new QUtf16Decoder;
+}
+
+QTextEncoder* QUtf16Codec::makeEncoder() const
+{
+ return new QUtf16Encoder;
+}
+
+#endif // QT_NO_TEXTCODEC
diff --git a/qtools/qutfcodec.h b/qtools/qutfcodec.h
new file mode 100644
index 0000000..af864be
--- /dev/null
+++ b/qtools/qutfcodec.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+**
+** Definition of QEucCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QUTFCODEC_H
+#define QUTFCODEC_H
+
+#ifndef QT_H
+#include "qtextcodec.h"
+#endif // QT_H
+
+#ifndef QT_NO_TEXTCODEC
+
+class Q_EXPORT QUtf8Codec : public QTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ QTextDecoder* makeDecoder() const;
+
+ QCString fromUnicode(const QString& uc, int& len_in_out) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+class Q_EXPORT QUtf16Codec : public QTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ QTextDecoder* makeDecoder() const;
+ QTextEncoder* makeEncoder() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+#endif //QT_NO_TEXTCODEC
+#endif // QUTFCODEC_H
diff --git a/qtools/qvaluelist.doc b/qtools/qvaluelist.doc
new file mode 100644
index 0000000..e4621d5
--- /dev/null
+++ b/qtools/qvaluelist.doc
@@ -0,0 +1,772 @@
+/****************************************************************************
+**
+**
+** QValueList and QValueListIterator class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QValueList documentation
+ *****************************************************************************/
+
+/*!
+ \class QValueList qvaluelist.h
+ \brief The QValueList class is a value based template class that provides doubly linked lists.
+
+ \ingroup qtl
+ \ingroup tools
+ \ingroup shared
+
+ Define a template instance QValueList\<X\> to create a list of values which all
+ have the class X. Please notice that QValueList does not store pointers to the
+ members of the list. It holds a copy of every member. That is the reason why this
+ kind of classes are called "value based" while QList and QDict are "reference based".
+
+ Some classes can not be used within a QValueList, for example everything
+ derived from QObject and thus all classes that implement widgets.
+ Only values can be used in a QValueList. To qualify as a value, the class
+ must provide
+ <ul>
+ <li>a copy constructor,
+ <li>an assignment operator and
+ <li> a default constructor, i.e. a constructor that does not take any arguments.
+ </ul>
+
+ Note that C++ defaults to field-by-field assignment operators and
+ copy constructors if no explicit version is supplied. In many cases,
+ this is sufficient.
+
+ Example:
+ \code
+ #include <qvaluelist.h>
+ #include <qstring.h>
+ #include <stdio.h>
+
+ class Employee
+ {
+ public:
+ Employee(): s(0) {}
+ Employee( const QString& name, int salary )
+ : n(name), s(salary)
+ {}
+
+ QString name() const { return n; }
+ int salary() const { return s; }
+ void setSalary( int salary ) { s = salary; }
+ private:
+ QString n;
+ int s;
+ };
+
+ void main()
+ {
+ typedef QValueList<Employee> EmployeeList;
+ EmployeeList list; // list of Employee
+
+ list.append( Employee("Bill", 50000) );
+ list.append( Employee("Steve",80000) );
+ list.append( Employee("Ron", 60000) );
+
+ Employee joe( "Joe", 50000 );
+ list.append( joe );
+ joe.setSalary( 4000 );
+
+ EmployeeList::Iterator it;
+ for( it = list.begin(); it != list.end(); ++it )
+ printf( "%s earns %d\n", (*it).name().latin1(), (*it).salary().latin1() );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Bill earns 50000
+ Steve earns 80000
+ Ron earns 60000
+ Joe earns 50000
+ \endcode
+
+ As you can see, the latest changes to Joes salary did not affect the value
+ in the list because the list created a copy of Joes entry.
+
+ There are three ways of finding items in the list. The first one is by using
+ the at() function. It returns an iterator. The advantages of
+ getting an iterator is that you can now move forward or backward from this
+ position by incrementing/decrementing the iterator. To get the amount of
+ items in the list call count(). Valid indices are 0..count().
+
+ The second way of accessing a list is with operator[]. That means you can address
+ it like an array. The return value is a reference to the value stored in the list.
+ There exist two versions of this operator. The first one is const and returns a
+ const reference to the value. The second on is non const and returns a non const
+ reference to the value. It is up to your compiler to choose the correct one.
+
+ The third method is to use the functions begin() and end().
+ With a simple for loop as shown in the example you can iterate over the complete list.
+ It is save to have multiple iterators at the same time. If some member of the list is
+ removed then only iterators pointing to the removed member become invalid. Inserting in
+ the list does not invalidate any iterator. For convenience the function last() returns
+ an iterator for the last and first() for the first element in the list.
+
+ In addition you can search items in the list with the find() function. It exists in a const
+ and a non const version. It starts searching from the beginning of the list, but another
+ flavor of the find() function allows you to specify where searching should start.
+ If you just want to know wether a certain item is at least once in the list, then you
+ can use the contains() function.
+
+ Since QValueList is value based there is no need to care about deleting elements in the
+ list. The list holds its own copies and will free them if the corresponding member or
+ the list itself is deleted. You can force the list to free all of its item with clear().
+
+ QValueList is implicitly shared. That means you can just make copies of the list
+ in time O(1). If multiple QValueList instances share the same data and one
+ is doing a modification of the lists data then this modifying instance makes a copy
+ and modifies its private copy. So it does not affect the other instances.
+ From a developers point of view you can think that a QValueList and a copy of this
+ list have nothing to do with each other. Developers may only notice that copying is
+ very fast. People known to a CPUs MMU architecture will know this pattern as "copy on write".
+
+ There exist three functions to insert items in the list. append()
+ inserts an item at the end, prepend() inserts at the beginning
+ and insert() inserts in front of the position given by an iterator.
+
+ Items can be removed from the list in two ways. The first is to pass an iterator to
+ the remove(). The other possibility is to pass a value to remove() which will
+ delete all members which match this value.
+
+ Lists can be sorted with the algorithms provided by the <a
+ href="qtl.html">Qt Template Library</a>, for example with
+ qHeapSort():
+
+ Example:
+ \code
+ QValueList l;
+ l.append( 5 );
+ l.append( 8 );
+ l.append( 3 );
+ l.append( 4 );
+ qHeapSort( l );
+ \endcode
+
+ \sa QValueListIterator
+*/
+
+
+/*!
+ \fn QValueList::QValueList()
+ Constructs an empty list.
+*/
+
+/*!
+ \fn QValueList::QValueList( const QValueList<T>& l )
+ Constructs a copy of \e l.
+
+ This operation costs O(1) time since QValueList is implicit shared.
+ The first instance applying modifications to a shared list will create
+ a copy which takes in turn O(n) time. However returning a QValueList from
+ a function is very fast.
+*/
+
+/*!
+ \fn QValueList::~QValueList()
+ Destroys the list. References to the values in the list and all iterators
+ of this list become invalidated. Since QValueList is highly tuned for performance
+ you wont see warnings if you use invalid iterators,
+ because it is impossible for
+ an iterator to check wether it is valid or not.
+*/
+
+/*!
+ \fn QValueList<T>& QValueList::operator= ( const QValueList<T>& l )
+ Assigns \e l to this list and returns a reference to this list.
+
+ All iterators of the current list become invalidated by this operation.
+ The cost of such an assignment is O(1) since QValueList is implicitly shared.
+*/
+
+/*!
+ \fn QValueList<T> QValueList::operator+ ( const QValueList<T>& l ) const
+ Creates a new list and fills it with the elements of this list. Then the
+ elements of \e l are appended.
+
+ Returns the new list.
+*/
+
+/*!
+ \fn QValueList<T>& QValueList::operator+= ( const QValueList<T>& l )
+ Adds \e list to this list.
+
+ Returns a reference to this list.
+*/
+
+/*!
+ \fn bool QValueList::operator== ( const QValueList<T>& l ) const
+ Compares both lists.
+
+ Returns TRUE if both list are equal.
+*/
+
+/*!
+ \fn bool QValueList::operator!= ( const QValueList<T>& l ) const
+ Compares both lists.
+
+ Returns TRUE if both list are unequal.
+*/
+
+/*!
+ \fn QValueList<T>& QValueList::operator+= ( const T& x )
+ Adds the value \e x to the end of the list.
+
+ Returns a reference to the list.
+*/
+
+/*!
+ \fn QValueList<T>& QValueList::operator<< ( const T& x )
+ Adds the value \e x to the end of the list.
+
+ Returns a reference to the list.
+*/
+
+/*!
+ \fn const T& QValueList::operator[] ( uint i ) const
+ Returns a const reference to the item with index \e i in the list.
+ It is up to you to check wether this item really exists. You can do that easily
+ with the count() function. However this operator does not check wether \e i
+ is in range and will deliver undefined results if it does not exist.
+*/
+
+/*!
+ \fn T& QValueList::operator[] ( uint i )
+ Returns a reference to the item with index \e i in the list.
+ It is up to you to check wether this item really exists. You can do that easily
+ with the count() function. However this operator does not check wether \e i
+ is in range and will deliver undefined results if it does not exist.
+ In contrast to the const operator[] you may manipulate the value returned by this
+ operator.
+*/
+
+/*!
+ \fn uint QValueList::count() const
+ Returns the number of items in the list.
+ \sa isEmpty()
+*/
+
+/*!
+ \fn bool QValueList::isEmpty() const
+ Returns TRUE if the list is empty, i.e. count() == 0. Returns FALSE
+ otherwise.
+ \sa count()
+*/
+
+/*!
+ \fn Iterator QValueList::insert( Iterator it, const T& x )
+ Inserts the value \e x in front of the iterator \e it.
+
+ Returns an iterator pointing at the inserted item.
+
+ \sa append(), prepend()
+*/
+
+/*!
+ \fn Iterator QValueList::append( const T& x )
+ Inserts the value \e x at the end of the list.
+
+ Returns an iterator pointing at the inserted item.
+
+ \sa insert(), prepend()
+*/
+
+/*!
+ \fn Iterator QValueList::prepend( const T& x )
+ Inserts the value \e x at the beginning of the list.
+
+ Returns an iterator pointing at the inserted item.
+
+ \sa insert(), append()
+*/
+
+/*!
+ \fn Iterator QValueList::remove( Iterator it )
+ Removes the item at position \e it in the list.
+
+ Returns an iterator pointing to the item following the
+ removed on or end() if the last item was deleted.
+
+ \sa clear()
+*/
+
+/*!
+ \fn void QValueList::remove( const T& x )
+ Removes all items which have the value \e x.
+
+ \sa clear()
+*/
+
+/*!
+ \fn void QValueList::clear()
+ Removes all items from the list.
+
+ \sa remove()
+*/
+
+/*!
+ \fn Iterator QValueList::find( const T& x )
+ Finds the first occurrence of \e x in the list.
+
+ Returns end() if no item did match.
+*/
+
+/*!
+ \fn ConstIterator QValueList::find( const T& x ) const
+ Finds the first occurrence of \e x in the list.
+
+ Returns end() if no item did match.
+*/
+
+/*!
+ \fn Iterator QValueList::find( Iterator it, const T& x )
+ Finds the first occurrence of \e x in the list starting at
+ the position given by \e it.
+
+ Returns end() if no item did match.
+*/
+
+/*!
+ \fn ConstIterator QValueList::find( ConstIterator it, const T& x ) const
+ Finds the first occurrence of \e x in the list starting at
+ the position given by \e it.
+
+ Returns end() if no item did match.
+*/
+
+/*!
+ \fn uint QValueList::contains( const T& x ) const
+ Counts and returns the number of occurrences of the value \e x in the list.
+*/
+
+/*!
+ \fn int QValueList::findIndex( const T& x ) const
+ Returns the first index of the value \e x in the list or -1 if no such value
+ can be found in the list.
+*/
+
+/*!
+ \fn Iterator QValueList::at( uint i )
+ Returns an iterator pointing to the item at position \e i in the list, or
+ end() if the index is out of range.
+*/
+
+/*!
+ \fn ConstIterator QValueList::at( uint i ) const
+ Returns an iterator pointing to the item at position \e i in the list, or
+ end() if the index is out of range.
+*/
+
+/*!
+ \fn T& QValueList::first()
+ Returns a reference to the first item in the list or the item
+ referenced by end()
+ if no such items exists. Please note that you may not change
+ the value the end() Iterator is pointing to.
+
+ \sa begin(), last()
+*/
+
+/*!
+ \fn const T& QValueList::first() const
+ Returns a reference to the first item in the list or the item
+ referenced by end() if
+ no such items exists.
+
+ \sa begin(), last()
+*/
+
+/*!
+ \fn Iterator QValueList::fromLast()
+ Returns an iterator pointing to the last element in the list or
+ end() if no such item exists.
+
+ \sa last()
+*/
+
+/*!
+ \fn ConstIterator QValueList::fromLast() const
+ Returns an iterator pointing to the last element in the list or
+ end() if no such item exists.
+
+ \sa last()
+*/
+
+/*!
+ \fn T& QValueList::last()
+ Returns a reference to the last item in the list or the item
+ referenced by end() if no
+ such item exists. Please note that you may not change
+ the value the end() Iterator is pointing to.
+
+ \sa end(), first(), fromLast()
+*/
+
+/*!
+ \fn const T& QValueList::last() const
+ Returns a reference to the last item in the list or the item
+ referenced by end() if no such item exists.
+
+ \sa end(), first(), fromLast()
+*/
+
+/*!
+ \fn Iterator QValueList::begin()
+ Returns an iterator pointing to the first element in the list. This
+ iterator equals end() if the list is empty;
+ \sa first(), end()
+*/
+
+/*!
+ \fn ConstIterator QValueList::begin() const
+ Returns an iterator pointing to the first element in the list. This
+ iterator equals end() if the list is empty;
+ \sa first(), end()
+*/
+
+/*!
+ \fn Iterator QValueList::end()
+ Returns an iterator pointing behind the last element in the list. This
+ iterator equals begin() if the list is empty.
+
+ \sa last(), begin()
+*/
+
+/*!
+ \fn ConstIterator QValueList::end() const
+ Returns an iterator pointing behind the last element in the list. This
+ iterator equals begin() if the list is empty.
+
+ \sa last(), begin()
+*/
+
+/*!
+ \fn void QValueList::detach()
+ If the list does not share its data with another QValueList instance, then nothing
+ happens, otherwise the function creates a new copy of this data and detaches
+ from the shared one. This function is called whenever the list is modified.
+ The implicit sharing mechanism is implemented this way.
+*/
+
+/*!
+ \fn QDataStream& operator>>( QDataStream& s, QValueList<T>& l )
+ \relates QValueList
+ Reads a list from the stream. The type \e T stored in the list must implement
+ the streaming operator, too.
+*/
+
+/*!
+ \fn QDataStream& operator<<( QDataStream& s, const QValueList<T>& l )
+ \relates QValueList
+ Writes a list to the stream. The type \e T stored in the list must implement
+ the streaming operator, too.
+*/
+
+/*****************************************************************************
+ QValueListIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QValueListIterator qvaluelist.h
+ \brief The QValueListIterator class provides an iterator for QValueList.
+
+ \ingroup qtl
+ \ingroup tools
+
+ You can not create an iterator by yourself. Instead you have to
+ ask a list to give you one. An iterator has only the size of a pointer.
+ On 32 bit machines that means 4 bytes otherwise 8 bytes. That makes them
+ very fast. In fact they resemble the semantics of pointers as good as possible
+ and they are almost as fast as usual pointers.
+
+ Example:
+ \code
+ #include <qvaluelist.h>
+ #include <qstring.h>
+ #include <stdio.h>
+
+ class Employee
+ {
+ public:
+ Employee(): s(0) {}
+ Employee( const QString& name, int salary )
+ : n(name), s(salary)
+ {}
+
+ QString name() const { return n; }
+ int salary() const { return s; }
+ void setSalary( int salary ) { s = salary; }
+ private:
+ QString n;
+ int s;
+ };
+
+ void main()
+ {
+ typedef QValueList<Employee> EmployeeList;
+ EmployeeList list; // list of Employee
+
+ list.append( Employee("Bill", 50000) );
+ list.append( Employee("Steve",80000) );
+ list.append( Employee("Ron", 60000) );
+
+ Employee joe( "Joe", 50000 );
+ list.append( joe );
+ joe.setSalary( 4000 );
+
+ EmployeeList::Iterator it;
+ for( it = list.begin(); it != list.end(); ++it )
+ printf( "%s earns %d\n", (*it).name().latin1(), (*it).salary() );
+ }
+ \endcode
+
+ Program output:
+ \code
+ Bill earns 50000
+ Steve earns 80000
+ Ron earns 60000
+ Joe earns 50000
+ \endcode
+
+ In contrast to QList there are no built in functions in QValueList to
+ traverse the list. The only way to do this is to use iterators.
+ QValueList is highly optimized for performance and memory usage.
+ On the other hand that means that you have to be a bit more careful
+ by what you are doing. QValueList does not know about all its iterators
+ and the iterators dont even know to which list they belong. That makes
+ things fast and slim but a bit dangerous because it is up to you to make
+ sure that iterators you are using are still valid. QListIterator will be able
+ to give warnings while QValueListIterator may end up in an undefined state.
+
+ For every Iterator there is a ConstIterator. When accessing a QValueList
+ in a const environment or if the reference or pointer to the list is itself
+ const, then you have to use the ConstIterator. Its semantics are the same,
+ but it returns only const references to the item it points to.
+
+ \sa QValueList, QValueListConstIterator
+*/
+
+/*!
+ \fn QValueListIterator::QValueListIterator()
+ Creates un uninitialized iterator.
+*/
+
+/*!
+ \fn QValueListIterator::QValueListIterator( NodePtr p )
+ Internal function.
+*/
+
+/*!
+ \fn QValueListIterator::QValueListIterator( const QValueListIterator<T>& it )
+ Constructs a copy of the iterator \e it.
+*/
+
+/*!
+ \fn QValueListIterator::~QValueListIterator()
+ Destroys the iterator.
+*/
+
+/* Unfortunately not with MSVC
+ \fn T *QValueListIterator::operator->()
+ Pointer operator. Returns a pointer to the current iterator item.
+ The great advantage of this operator is that you can treat the
+ iterator like a pointer.
+
+ Example:
+ \code
+ QValueList<int>::Iterator it = list.begin();
+ for( ; it != end(); ++it )
+ it->show();
+ \endcode
+*/
+
+/*!
+ \fn T& QValueListIterator::operator*()
+ Asterix operator. Returns a reference to the current iterator item.
+*/
+
+/*!
+ \fn const T& QValueListIterator::operator*() const
+ Asterix operator. Returns a reference to the current iterator item.
+*/
+
+/*!
+ \fn QValueListIterator<T>& QValueListIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the end of the list. Incrementing
+ the iterator as returned by end() causes undefined results.
+*/
+
+/*!
+ \fn QValueListIterator<T> QValueListIterator::operator++(int)
+ Postfix ++ makes the succeeding item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the end of the list. Incrementing
+ the iterator as returned by end() causes undefined results.
+*/
+
+/*!
+ \fn QValueListIterator<T>& QValueListIterator::operator--()
+ Prefix -- makes the previous item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the beginning of the list. Decrementing
+ the iterator as returned by begin() causes undefined results.
+*/
+
+/*!
+ \fn QValueListIterator<T> QValueListIterator::operator--(int)
+ Postfix -- makes the previous item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the beginning of the list. Decrementing
+ the iterator as returned by begin() causes undefined results.
+*/
+
+/*!
+ \fn bool QValueListIterator::operator==( const QValueListIterator<T>& it ) const
+ Compares both iterators and returns TRUE if they point to the same item.
+*/
+
+/*!
+ \fn bool QValueListIterator::operator!=( const QValueListIterator<T>& it ) const
+ Compares both iterators and returns TRUE if they point to different items.
+*/
+
+/*****************************************************************************
+ QValueListConstIterator documentation
+ *****************************************************************************/
+
+/*!
+ \class QValueListConstIterator qvaluelist.h
+ \brief The QValueListConstIterator class provides an iterator for QValueList.
+
+ \ingroup qtl
+ \ingroup tools
+
+ In contrast to QValueListIterator this class is used to iterate over a const
+ list. It does not allow to modify the values of the list since this would
+ break the const semantics.
+
+ For more informations on QValueList iterators see QValueListIterator.
+
+ \sa QValueListIterator, QValueList
+*/
+
+/*!
+ \fn QValueListConstIterator::QValueListConstIterator()
+ Creates un uninitialized iterator.
+*/
+
+/*!
+ \fn QValueListConstIterator::QValueListConstIterator( NodePtr p )
+ Internal function.
+*/
+
+/*!
+ \fn QValueListConstIterator::QValueListConstIterator( const QValueListConstIterator<T>& it )
+ Constructs a copy of the iterator \e it.
+*/
+
+/*!
+ \fn QValueListConstIterator::QValueListConstIterator( const QValueListIterator<T>& it )
+ Constructs a copy of the iterator \e it.
+*/
+
+/*!
+ \fn QValueListConstIterator::~QValueListConstIterator()
+ Destroys the iterator.
+*/
+
+/* Unfortunately not with MSVC
+ \fn const T *QValueListConstIterator::operator->()
+ Pointer operator. Returns a pointer to the current iterator item.
+ The great advantage of this operator is that you can treat the
+ iterator like a pointer.
+
+ Example:
+ \code
+ QValueList<int>::Iterator it = list.begin();
+ for( ; it != end(); ++it )
+ it->show();
+ \endcode
+*/
+
+/*!
+ \fn const T& QValueListConstIterator::operator*() const
+ Asterix operator. Returns a reference to the current iterator item.
+*/
+
+/*!
+ \fn QValueListConstIterator<T>& QValueListConstIterator::operator++()
+ Prefix ++ makes the succeeding item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the end of the list. Incrementing
+ the iterator as returned by end() causes undefined results.
+*/
+
+/*!
+ \fn QValueListConstIterator<T> QValueListConstIterator::operator++(int)
+ Postfix ++ makes the succeeding item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the end of the list. Incrementing
+ the iterator as returned by end() causes undefined results.
+*/
+
+/*!
+ \fn QValueListConstIterator<T>& QValueListConstIterator::operator--()
+ Prefix -- makes the previous item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the beginning of the list. Decrementing
+ the iterator as returned by begin() causes undefined results.
+*/
+
+/*!
+ \fn QValueListConstIterator<T> QValueListConstIterator::operator--(int)
+ Postfix -- makes the previous item current and returns
+ an iterator pointing to the new current item.
+ The iterator can not check wether it reached the beginning of the list. Decrementing
+ the iterator as returned by begin() causes undefined results.
+*/
+
+/*!
+ \fn bool QValueListConstIterator::operator==( const QValueListConstIterator<T>& it ) const
+ Compares both iterators and returns TRUE if they point to the same item.
+*/
+
+/*!
+ \fn bool QValueListConstIterator::operator!=( const QValueListConstIterator<T>& it ) const
+ Compares both iterators and returns TRUE if they point to different items.
+*/
diff --git a/qtools/qvaluelist.h b/qtools/qvaluelist.h
new file mode 100644
index 0000000..a1014ed
--- /dev/null
+++ b/qtools/qvaluelist.h
@@ -0,0 +1,449 @@
+/****************************************************************************
+**
+**
+** Definition of QValueList class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QVALUELIST_H
+#define QVALUELIST_H
+
+#ifndef QT_H
+#include "qshared.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+#if defined(_CC_MSVC_)
+#pragma warning(disable:4284) // "return type for operator -> is not a UDT"
+#endif
+
+template <class T>
+class Q_EXPORT QValueListNode
+{
+public:
+ QValueListNode( const T& t ) : data( t ) { }
+ QValueListNode() { }
+#if defined(Q_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual ~QValueListNode() { }
+#endif
+
+ QValueListNode<T>* next;
+ QValueListNode<T>* prev;
+ T data;
+};
+
+template<class T>
+class Q_EXPORT QValueListIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ QValueListIterator() : node( 0 ) {}
+ QValueListIterator( NodePtr p ) : node( p ) {}
+ QValueListIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const QValueListIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const QValueListIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+ T& operator*() { return node->data; }
+
+ // Compilers are too dumb to understand this for QValueList<int>
+ //T* operator->() const { return &(node->data); }
+
+ QValueListIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ QValueListIterator<T> operator++(int) {
+ QValueListIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ QValueListIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ QValueListIterator<T> operator--(int) {
+ QValueListIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+};
+
+template<class T>
+class Q_EXPORT QValueListConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ QValueListConstIterator() : node( 0 ) {}
+ QValueListConstIterator( NodePtr p ) : node( p ) {}
+ QValueListConstIterator( const QValueListConstIterator<T>& it ) : node( it.node ) {}
+ QValueListConstIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const QValueListConstIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const QValueListConstIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+
+ // Compilers are too dumb to understand this for QValueList<int>
+ //const T* operator->() const { return &(node->data); }
+
+ QValueListConstIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ QValueListConstIterator<T> operator++(int) {
+ QValueListConstIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ QValueListConstIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ QValueListConstIterator<T> operator--(int) {
+ QValueListConstIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+};
+
+template <class T>
+class Q_EXPORT QValueListPrivate : public QShared
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListIterator<T> Iterator;
+ typedef QValueListConstIterator<T> ConstIterator;
+ typedef QValueListNode<T> Node;
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Functions
+ */
+ QValueListPrivate() { node = new Node; node->next = node->prev = node; nodes = 0; }
+ QValueListPrivate( const QValueListPrivate<T>& _p ) : QShared() {
+ node = new Node; node->next = node->prev = node; nodes = 0;
+ Iterator b( _p.node->next );
+ Iterator e( _p.node );
+ Iterator i( node );
+ while( b != e )
+ insert( i, *b++ );
+ }
+
+ void derefAndDelete() // ### hack to get around hp-cc brain damage
+ {
+ if ( deref() )
+ delete this;
+ }
+
+#if defined(Q_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual
+#endif
+ ~QValueListPrivate() {
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr x = p->next;
+ delete p;
+ p = x;
+ }
+ delete node;
+ }
+
+ Iterator insert( Iterator it, const T& x ) {
+ NodePtr p = new Node( x );
+ p->next = it.node;
+ p->prev = it.node->prev;
+ it.node->prev->next = p;
+ it.node->prev = p;
+ nodes++;
+ return p;
+ }
+
+ Iterator remove( Iterator it ) {
+ ASSERT ( it.node != node );
+ NodePtr next = it.node->next;
+ NodePtr prev = it.node->prev;
+ prev->next = next;
+ next->prev = prev;
+ delete it.node;
+ nodes--;
+ return Iterator( next );
+ }
+
+ NodePtr find( NodePtr start, const T& x ) const {
+ ConstIterator first( start );
+ ConstIterator last( node );
+ while( first != last) {
+ if ( *first == x )
+ return first.node;
+ ++first;
+ }
+ return last.node;
+ }
+
+ int findIndex( NodePtr start, const T& x ) const {
+ ConstIterator first( start );
+ ConstIterator last( node );
+ int pos = 0;
+ while( first != last) {
+ if ( *first == x )
+ return pos;
+ ++first;
+ ++pos;
+ }
+ return -1;
+ }
+
+ uint contains( const T& x ) const {
+ uint result = 0;
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x )
+ ++result;
+ ++first;
+ }
+ return result;
+ }
+
+ void remove( const T& x ) {
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x )
+ first = remove( first );
+ else
+ ++first;
+ }
+ }
+
+ NodePtr at( uint i ) const {
+ ASSERT( i <= nodes );
+ NodePtr p = node->next;
+ for( uint x = 0; x < i; ++x )
+ p = p->next;
+ return p;
+ }
+
+ void clear() {
+ nodes = 0;
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr next = p->next;
+ delete p;
+ p = next;
+ }
+ node->next = node->prev = node;
+ }
+
+ NodePtr node;
+ uint nodes;
+};
+
+template <class T>
+class Q_EXPORT QValueList
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListIterator<T> Iterator;
+ typedef QValueListConstIterator<T> ConstIterator;
+ typedef T ValueType;
+
+ /**
+ * API
+ */
+ QValueList() { sh = new QValueListPrivate<T>; }
+ QValueList( const QValueList<T>& l ) { sh = l.sh; sh->ref(); }
+ ~QValueList() { sh->derefAndDelete(); }
+
+ QValueList<T>& operator= ( const QValueList<T>& l )
+ {
+ l.sh->ref();
+ sh->derefAndDelete();
+ sh = l.sh;
+ return *this;
+ }
+
+ QValueList<T> operator+ ( const QValueList<T>& l ) const
+ {
+ QValueList<T> l2( *this );
+ for( ConstIterator it = l.begin(); it != l.end(); ++it )
+ l2.append( *it );
+ return l2;
+ }
+
+ QValueList<T>& operator+= ( const QValueList<T>& l )
+ {
+ for( ConstIterator it = l.begin(); it != l.end(); ++it )
+ append( *it );
+ return *this;
+ }
+
+ bool operator== ( const QValueList<T>& l ) const
+ {
+ if ( count() != l.count() )
+ return FALSE;
+ ConstIterator it2 = begin();
+ ConstIterator it = l.begin();
+ for( ; it != l.end(); ++it, ++it2 )
+ if ( !( *it == *it2 ) )
+ return FALSE;
+ return TRUE;
+ }
+
+ bool operator!= ( const QValueList<T>& l ) const { return !( *this == l ); }
+
+ Iterator begin() { detach(); return Iterator( sh->node->next ); }
+ ConstIterator begin() const { return ConstIterator( sh->node->next ); }
+ Iterator end() { detach(); return Iterator( sh->node ); }
+ ConstIterator end() const { return ConstIterator( sh->node ); }
+ Iterator fromLast() { detach(); return Iterator( sh->node->prev ); }
+ ConstIterator fromLast() const { return ConstIterator( sh->node->prev ); }
+
+ bool isEmpty() const { return ( sh->nodes == 0 ); }
+
+ Iterator insert( Iterator it, const T& x ) { detach(); return sh->insert( it, x ); }
+
+ Iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }
+ Iterator prepend( const T& x ) { detach(); return sh->insert( begin(), x ); }
+
+ Iterator remove( Iterator it ) { detach(); return sh->remove( it ); }
+ void remove( const T& x ) { detach(); sh->remove( x ); }
+
+ T& first() { detach(); return sh->node->next->data; }
+ const T& first() const { return sh->node->next->data; }
+ T& last() { detach(); return sh->node->prev->data; }
+ const T& last() const { return sh->node->prev->data; }
+
+ T& operator[] ( uint i ) { detach(); return sh->at(i)->data; }
+ const T& operator[] ( uint i ) const { return sh->at(i)->data; }
+ Iterator at( uint i ) { detach(); return Iterator( sh->at(i) ); }
+ ConstIterator at( uint i ) const { return ConstIterator( sh->at(i) ); }
+ Iterator find ( const T& x ) { detach(); return Iterator( sh->find( sh->node->next, x) ); }
+ ConstIterator find ( const T& x ) const { return ConstIterator( sh->find( sh->node->next, x) ); }
+ Iterator find ( Iterator it, const T& x ) { detach(); return Iterator( sh->find( it.node, x ) ); }
+ ConstIterator find ( ConstIterator it, const T& x ) const { return ConstIterator( sh->find( it.node, x ) ); }
+ int findIndex( const T& x ) const { return sh->findIndex( sh->node->next, x) ; }
+ uint contains( const T& x ) const { return sh->contains( x ); }
+
+ uint count() const { return sh->nodes; }
+
+ void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QValueListPrivate<T>; } }
+
+
+ QValueList<T>& operator+= ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+ QValueList<T>& operator<< ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QValueListPrivate<T>( *sh ); } }
+
+ /**
+ * Variables
+ */
+ QValueListPrivate<T>* sh;
+};
+
+#ifndef QT_NO_DATASTREAM
+template<class T>
+inline QDataStream& operator>>( QDataStream& s, QValueList<T>& l )
+{
+ l.clear();
+ Q_UINT32 c;
+ s >> c;
+ for( Q_UINT32 i = 0; i < c; ++i )
+ {
+ T t;
+ s >> t;
+ l.append( t );
+ }
+ return s;
+}
+
+template<class T>
+inline QDataStream& operator<<( QDataStream& s, const QValueList<T>& l )
+{
+ s << (Q_UINT32)l.count();
+ QValueListConstIterator<T> it = l.begin();
+ for( ; it != l.end(); ++it )
+ s << *it;
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+#endif // QVALUELIST_H
diff --git a/qtools/qvaluestack.h b/qtools/qvaluestack.h
new file mode 100644
index 0000000..fe4462a
--- /dev/null
+++ b/qtools/qvaluestack.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+**
+** Definition of QValueStack class
+**
+** Created : 990925
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QVALUESTACK_H
+#define QVALUESTACK_H
+
+#ifndef QT_H
+#include "qvaluelist.h"
+#endif // QT_H
+
+
+template<class T>
+class Q_EXPORT QValueStack : public QValueList<T>
+{
+public:
+ QValueStack() {}
+ ~QValueStack() {}
+ void push( const T& d ) { QValueList<T>::append(d); }
+ T pop()
+ {
+ T elem( this->last() );
+ if ( !this->isEmpty() )
+ this->remove( this->fromLast() );
+ return elem;
+ }
+ T& top() { return this->last(); }
+ const T& top() const { return this->last(); }
+};
+
+#endif
diff --git a/qtools/qvector.doc b/qtools/qvector.doc
new file mode 100644
index 0000000..2acf567
--- /dev/null
+++ b/qtools/qvector.doc
@@ -0,0 +1,344 @@
+/****************************************************************************
+**
+**
+** QVector class documentation
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/*****************************************************************************
+ QVector documentation
+ *****************************************************************************/
+
+// BEING REVISED: ettrich
+/*!
+ \class QVector qvector.h
+
+ \brief The QVector class is a template collection class that
+ provides a vector (array).
+
+ \ingroup tools
+
+ QVector is implemented as a template class. Define a template
+ instance QVector\<X\> to create a vector that contains pointers to
+ X, or X*.
+
+ A vector is the same as an array. The main difference between
+ QVector and QArray is that QVector stores pointers to the elements,
+ while QArray stores the elements themselves (i.e. QArray is
+ value-based).
+
+ Unless where otherwise stated, all functions that remove items from
+ the vector will also delete the element pointed to if auto-deletion
+ is enabled - see setAutoDelete(). By default, auto-deletion is
+ disabled. This behaviour can be changed in a subclass by
+ reimplementing the virtual method deleteItem().
+
+ Functions that compares items, e.g. find() and sort(), will do so
+ using the virtual function compareItems(). The default
+ implementation of this function will only compare the absolute
+ pointer values. Reimplement compareItems() in a subclass to get
+ searching and sorting based on the item contents.
+
+ \sa \link collection.html Collection Classes\endlink, QArray
+*/
+
+/*!
+ \fn QVector::QVector()
+
+ Constructs a null vector.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QVector::QVector( uint size )
+
+ Constructs an vector with room for \a size items. Makes a null
+ vector if \a size == 0.
+
+ All \a size positions in the vector are initialized to 0.
+
+ \sa size(), resize(), isNull()
+*/
+
+/*!
+ \fn QVector::QVector( const QVector<type> &v )
+
+ Constructs a copy of \a v. Only the pointers are copied (i.e. shallow copy).
+*/
+
+/*!
+ \fn QVector::~QVector()
+
+ Removes all items from the vector, and destroys the vector itself.
+
+ \sa clear()
+*/
+
+/*!
+ \fn QVector<type> &QVector::operator=( const QVector<type> &v )
+
+ Assigns \a v to this vector and returns a reference to this vector.
+
+ This vector is first cleared, then all the items from \a v is copied
+ into this vector. Only the pointers are copied (i.e. shallow copy).
+
+ \sa clear()
+*/
+
+/*!
+ \fn type **QVector::data() const
+ Returns a pointer to the actual vector data, which is an array of type*.
+
+ The vector is a null vector if data() == 0 (null pointer).
+
+ \sa isNull()
+*/
+
+/*!
+ \fn uint QVector::size() const
+
+ Returns the size of the vector, i.e. the number of vector
+ positions. This is also the maximum number of items the vector can
+ hold.
+
+ The vector is a null vector if size() == 0.
+
+ \sa isNull(), resize(), count()
+*/
+
+/*!
+ \fn uint QVector::count() const
+
+ Returns the number of items in the vector. The vector is empty if
+ count() == 0.
+
+ \sa isEmpty(), size()
+*/
+
+/*!
+ \fn bool QVector::isEmpty() const
+
+ Returns TRUE if the vector is empty, i.e. count() == 0, otherwise FALSE.
+
+ \sa count()
+*/
+
+/*!
+ \fn bool QVector::isNull() const
+
+ Returns TRUE if the vector is null, otherwise FALSE.
+
+ A null vector has size() == 0 and data() == 0.
+
+ \sa size()
+*/
+
+/*!
+ \fn bool QVector::resize( uint size )
+ Resizes (expands or shrinks) the vector to \a size elements. The array
+ becomes a null array if \a size == 0.
+
+ Any items in position \a size or beyond in the vector are removed.
+ New positions are initialized 0.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated.
+
+ \sa size(), isNull()
+*/
+
+/*!
+ \fn bool QVector::insert( uint i, const type *d )
+
+ Sets position \a i in the vector to contain the item \a d. \a i must
+ be less than size(). Any previous element in position \a i is removed.
+
+ \sa at()
+*/
+
+/*!
+ \fn bool QVector::remove( uint i )
+
+ Removes the item at position \a i in the vector, if there is one.
+ \a i must be less than size().
+
+ Returns TRUE unless \a i is out of range.
+
+ \sa take(), at()
+*/
+
+/*!
+ \fn type* QVector::take( uint i )
+
+ Returns the item at position \a i in the vector, and removes that
+ item from the vector. \a i must be less than size(). If there is no
+ item at position \a i, 0 is returned.
+
+ In contrast to remove(), this function does \e not call deleteItem()
+ for the removed item.
+
+ \sa remove(), at()
+*/
+
+/*!
+ \fn void QVector::clear()
+
+ Removes all items from the vector, and destroys the vector
+ itself.
+
+ The vector becomes a null vector.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool QVector::fill( const type *d, int size )
+
+ Inserts item \a d in all positions in the vector. Any existing items
+ are removed. If \a d is 0, the vector becomes empty.
+
+ If \a size >= 0, the vector is first resized to \a size. By default,
+ \a size is -1.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated
+ (only if a resize has been requested).
+
+ \sa resize(), insert(), isEmpty()
+*/
+
+/*!
+ \fn void QVector::sort()
+
+ Sorts the items in ascending order. Any empty positions will be put
+ last.
+
+ Compares items using the virtual function compareItems().
+
+ \sa bsearch()
+*/
+
+/*!
+ \fn int QVector::bsearch( const type* d ) const
+
+ In a sorted array, finds the first occurrence of \a d using binary
+ search. For a sorted array, this is generally much faster than
+ find(), which does a linear search.
+
+ Returns the position of \a d, or -1 if \a d could not be found. \a d
+ may not be 0.
+
+ Compares items using the virtual function compareItems().
+
+ \sa sort(), find()
+*/
+
+
+/*!
+ \fn int QVector::findRef( const type *d, uint i ) const
+
+ Finds the first occurrence of the item pointer \a d in the vector,
+ using linear search. The search starts at position \a i, which must
+ be less than size(). \a i is by default 0; i.e. the search starts at
+ the start of the vector.
+
+ Returns the position of \a d, or -1 if \a d could not be found.
+
+ This function does \e not use compareItems() to compare items.
+
+ \sa find(), bsearch()
+*/
+
+/*!
+ \fn int QVector::find( const type *d, uint i ) const
+
+ Finds the first occurrence of item \a d in the vector, using linear
+ search. The search starts at position \a i, which must be less than
+ size(). \a i is by default 0; i.e. the search starts at the start of
+ the vector.
+
+ Returns the position of \e v, or -1 if \e v could not be found.
+
+ Compares items using the virtual function compareItems().
+
+ \sa findRef(), bsearch()
+*/
+
+
+/*!
+ \fn uint QVector::containsRef( const type *d ) const
+
+ Returns the number of occurrences of the item pointer \a d in the
+ vector.
+
+ This function does \e not use compareItems() to compare items.
+
+ \sa findRef()
+*/
+
+/*!
+ \fn uint QVector::contains( const type *d ) const
+
+ Returns the number of occurrences of item \a d in the vector.
+
+ Compares items using the virtual function compareItems().
+
+ \sa containsRef()
+*/
+
+/*!
+ \fn type *QVector::operator[]( int i ) const
+
+ Returns the item at position \a i, or 0 if there is no item at
+ that position. \a i must be less than size().
+
+ Equivalent to at( \a i ).
+
+ \sa at()
+*/
+
+/*!
+ \fn type *QVector::at( uint i ) const
+
+ Returns the item at position \a i, or 0 if there is no item at
+ that position. \a i must be less than size().
+*/
+
+
+/*!
+ \fn void QVector::toList( QGList *list ) const
+
+ Copies all items in this vector to the list \a list. First, \a list
+ is cleared, then all items are appended to \a list.
+
+ \sa QList, QStack, QQueue
+*/
+
diff --git a/qtools/qvector.h b/qtools/qvector.h
new file mode 100644
index 0000000..36f0be7
--- /dev/null
+++ b/qtools/qvector.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+**
+** Definition of QVector template/macro class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QVECTOR_H
+#define QVECTOR_H
+
+#ifndef QT_H
+#include "qgvector.h"
+#endif // QT_H
+
+
+template<class type> class QVector : public QGVector
+{
+public:
+ QVector() {}
+ QVector( uint size ) : QGVector(size) {}
+ QVector( const QVector<type> &v ) : QGVector(v) {}
+ ~QVector() { clear(); }
+ QVector<type> &operator=(const QVector<type> &v)
+ { return (QVector<type>&)QGVector::operator=(v); }
+ type **data() const { return (type **)QGVector::data(); }
+ uint size() const { return QGVector::size(); }
+ uint count() const { return QGVector::count(); }
+ bool isEmpty() const { return QGVector::count() == 0; }
+ bool isNull() const { return QGVector::size() == 0; }
+ bool resize( uint size ) { return QGVector::resize(size); }
+ bool insert( uint i, const type *d){ return QGVector::insert(i,(Item)d); }
+ bool remove( uint i ) { return QGVector::remove(i); }
+ type *take( uint i ) { return (type *)QGVector::take(i); }
+ void clear() { QGVector::clear(); }
+ bool fill( const type *d, int size=-1 )
+ { return QGVector::fill((Item)d,size);}
+ void sort() { QGVector::sort(); }
+ int bsearch( const type *d ) const{ return QGVector::bsearch((Item)d); }
+ int findRef( const type *d, uint i=0 ) const
+ { return QGVector::findRef((Item)d,i);}
+ int find( const type *d, uint i= 0 ) const
+ { return QGVector::find((Item)d,i); }
+ uint containsRef( const type *d ) const
+ { return QGVector::containsRef((Item)d); }
+ uint contains( const type *d ) const
+ { return QGVector::contains((Item)d); }
+ type *operator[]( int i ) const { return (type *)QGVector::at(i); }
+ type *at( uint i ) const { return (type *)QGVector::at(i); }
+ void toList( QGList *list ) const { QGVector::toList(list); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QVECTOR_H
diff --git a/qtools/qwaitcondition.h b/qtools/qwaitcondition.h
new file mode 100644
index 0000000..4d5b3bd
--- /dev/null
+++ b/qtools/qwaitcondition.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAITCONDITION_H
+#define QWAITCONDITION_H
+
+#include "qglobal.h"
+
+class QWaitConditionPrivate;
+class QMutex;
+
+class QWaitCondition
+{
+public:
+ QWaitCondition();
+ ~QWaitCondition();
+
+ void wait(QMutex *mutex);
+
+ void wakeOne();
+ void wakeAll();
+
+private:
+ QWaitCondition(const QWaitCondition &);
+ QWaitCondition &operator=(const QWaitCondition &);
+
+ QWaitConditionPrivate * d;
+};
+
+#endif // QWAITCONDITION_H
diff --git a/qtools/qwaitcondition_unix.cpp b/qtools/qwaitcondition_unix.cpp
new file mode 100644
index 0000000..d1ff27e
--- /dev/null
+++ b/qtools/qwaitcondition_unix.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaitcondition.h"
+#include "qmutex.h"
+#include <pthread.h>
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+static void report_error(int code, const char *where, const char *what)
+{
+ if (code != 0)
+ qWarning("%s: %s failure: %d", where, what, code);
+}
+
+class QWaitConditionPrivate
+{
+ public:
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int waiters;
+ int wakeups;
+
+ void wait()
+ {
+ int code;
+ for (;;)
+ {
+ code = pthread_cond_wait(&cond, &mutex);
+ if (code == 0 && wakeups == 0)
+ {
+ // many vendors warn of spurios wakeups from
+ // pthread_cond_wait(), especially after signal delivery,
+ // even though POSIX doesn't allow for it... sigh
+ continue;
+ }
+ break;
+ }
+
+ --waiters;
+ if (code == 0)
+ {
+ --wakeups;
+ }
+ else
+ {
+ report_error(code, "QWaitCondition::wait()", "cv wait");
+ }
+ report_error(pthread_mutex_unlock(&mutex), "QWaitCondition::wait()", "mutex unlock");
+ }
+};
+
+
+QWaitCondition::QWaitCondition()
+{
+ d = new QWaitConditionPrivate;
+ report_error(pthread_mutex_init(&d->mutex, NULL), "QWaitCondition", "mutex init");
+ report_error(pthread_cond_init(&d->cond, NULL), "QWaitCondition", "cv init");
+ d->waiters = d->wakeups = 0;
+}
+
+
+QWaitCondition::~QWaitCondition()
+{
+ report_error(pthread_cond_destroy(&d->cond), "QWaitCondition", "cv destroy");
+ report_error(pthread_mutex_destroy(&d->mutex), "QWaitCondition", "mutex destroy");
+ delete d;
+}
+
+void QWaitCondition::wakeOne()
+{
+ report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeOne()", "mutex lock");
+ d->wakeups = MIN(d->wakeups + 1, d->waiters);
+ report_error(pthread_cond_signal(&d->cond), "QWaitCondition::wakeOne()", "cv signal");
+ report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeOne()", "mutex unlock");
+}
+
+void QWaitCondition::wakeAll()
+{
+ report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeAll()", "mutex lock");
+ d->wakeups = d->waiters;
+ report_error(pthread_cond_broadcast(&d->cond), "QWaitCondition::wakeAll()", "cv broadcast");
+ report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");
+}
+
+void QWaitCondition::wait(QMutex *mutex)
+{
+ if (!mutex) return;
+
+ report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
+ ++d->waiters;
+ mutex->unlock();
+ d->wait();
+ mutex->lock();
+}
+
diff --git a/qtools/qwaitcondition_win32.cpp b/qtools/qwaitcondition_win32.cpp
new file mode 100644
index 0000000..80b7b67
--- /dev/null
+++ b/qtools/qwaitcondition_win32.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info at nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <windows.h>
+#include "qwaitcondition.h"
+#include "qmutex.h"
+#include "qinternallist.h"
+
+//***********************************************************************
+// QWaitConditionPrivate
+// **********************************************************************
+
+class QWaitConditionEvent
+{
+public:
+ QWaitConditionEvent() : priority(0), wokenUp(false)
+ {
+ event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ }
+ ~QWaitConditionEvent() { CloseHandle(event); }
+ int priority;
+ bool wokenUp;
+ HANDLE event;
+};
+
+class EventQueue : public QInternalList<QWaitConditionEvent>
+{
+ public:
+ EventQueue() { setAutoDelete(TRUE); }
+ ~EventQueue() {}
+};
+
+class QWaitConditionPrivate
+{
+public:
+ QMutex mtx;
+ EventQueue queue;
+ EventQueue freeQueue;
+
+ QWaitConditionEvent *pre();
+ void wait(QWaitConditionEvent *wce);
+ void post(QWaitConditionEvent *wce);
+};
+
+QWaitConditionEvent *QWaitConditionPrivate::pre()
+{
+ mtx.lock();
+ QWaitConditionEvent *wce =
+ freeQueue.isEmpty() ? new QWaitConditionEvent : freeQueue.take(0);
+ wce->priority = GetThreadPriority(GetCurrentThread());
+ wce->wokenUp = FALSE;
+
+ // insert 'wce' into the queue (sorted by priority)
+ uint index = 0;
+ for (; index < queue.count(); ++index)
+ {
+ QWaitConditionEvent *current = queue.at(index);
+ if (current->priority < wce->priority)
+ break;
+ }
+ queue.insert(index, wce);
+ mtx.unlock();
+
+ return wce;
+}
+
+void QWaitConditionPrivate::wait(QWaitConditionEvent *wce)
+{
+ WaitForSingleObject(wce->event, INFINITE);
+}
+
+void QWaitConditionPrivate::post(QWaitConditionEvent *wce)
+{
+ mtx.lock();
+
+ // remove 'wce' from the queue
+ int idx = queue.find(wce);
+ ASSERT(idx!=-1);
+ queue.take(idx);
+ ResetEvent(wce->event);
+ freeQueue.append(wce);
+
+ // wakeups delivered after the timeout should be forwarded to the next waiter
+ if (wce->wokenUp && !queue.isEmpty())
+ {
+ QWaitConditionEvent *other = queue.getFirst();
+ SetEvent(other->event);
+ other->wokenUp = TRUE;
+ }
+
+ mtx.unlock();
+}
+
+//***********************************************************************
+// QWaitCondition implementation
+//***********************************************************************
+
+QWaitCondition::QWaitCondition()
+{
+ d = new QWaitConditionPrivate;
+}
+
+QWaitCondition::~QWaitCondition()
+{
+ if (!d->queue.isEmpty())
+ {
+ qWarning("QWaitCondition: Destroyed while threads are still waiting");
+ }
+ delete d;
+}
+
+void QWaitCondition::wait(QMutex *mutex)
+{
+ if (!mutex) return;
+
+ QWaitConditionEvent *wce = d->pre();
+ mutex->unlock();
+ d->wait(wce);
+ mutex->lock();
+ d->post(wce);
+}
+
+void QWaitCondition::wakeOne()
+{
+ // wake up the first waiting thread in the queue
+ QMutexLocker locker(&d->mtx);
+ for (uint i = 0; i < d->queue.count(); ++i)
+ {
+ QWaitConditionEvent *current = d->queue.at(i);
+ if (current->wokenUp) continue;
+ SetEvent(current->event);
+ current->wokenUp = TRUE;
+ break;
+ }
+}
+
+void QWaitCondition::wakeAll()
+{
+ // wake up the all threads in the queue
+ QMutexLocker locker(&d->mtx);
+ for (uint i = 0; i < d->queue.count(); ++i)
+ {
+ QWaitConditionEvent *current = d->queue.at(i);
+ SetEvent(current->event);
+ current->wokenUp = TRUE;
+ }
+}
+
diff --git a/qtools/qxml.cpp b/qtools/qxml.cpp
new file mode 100644
index 0000000..806bd42
--- /dev/null
+++ b/qtools/qxml.cpp
@@ -0,0 +1,6061 @@
+/****************************************************************************
+**
+**
+** Implementation of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#define QT_XML_CPP
+#include "qxml.h"
+#include "qtextcodec.h"
+#include "qbuffer.h"
+
+#ifndef QT_NO_XML
+// NOT REVISED
+
+// Error strings for the XML reader
+#define XMLERR_OK "no error occured"
+#define XMLERR_TAGMISMATCH "tag mismatch"
+#define XMLERR_UNEXPECTEDEOF "unexpected end of file"
+#define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached"
+#define XMLERR_LETTEREXPECTED "letter is expected"
+#define XMLERR_ERRORPARSINGELEMENT "error while parsing element"
+#define XMLERR_ERRORPARSINGPROLOG "error while parsing prolog"
+#define XMLERR_ERRORPARSINGMAINELEMENT "error while parsing main element"
+#define XMLERR_ERRORPARSINGCONTENT "error while parsing content"
+#define XMLERR_ERRORPARSINGNAME "error while parsing name"
+#define XMLERR_ERRORPARSINGNMTOKEN "error while parsing Nmtoken"
+#define XMLERR_ERRORPARSINGATTRIBUTE "error while parsing attribute"
+#define XMLERR_ERRORPARSINGMISC "error while parsing misc"
+#define XMLERR_ERRORPARSINGCHOICE "error while parsing choice or seq"
+#define XMLERR_ERRORBYCONSUMER "error triggered by consumer"
+#define XMLERR_UNEXPECTEDCHARACTER "unexpected character"
+#define XMLERR_EQUALSIGNEXPECTED "expected '=' but not found"
+#define XMLERR_QUOTATIONEXPECTED "expected \" or ' but not found"
+#define XMLERR_ERRORPARSINGREFERENCE "error while parsing reference"
+#define XMLERR_ERRORPARSINGPI "error while parsing processing instruction"
+#define XMLERR_ERRORPARSINGATTLISTDECL "error while parsing attribute list declaration"
+#define XMLERR_ERRORPARSINGATTTYPE "error while parsing attribute type declaration"
+#define XMLERR_ERRORPARSINGATTVALUE "error while parsing attribute value declaration"
+#define XMLERR_ERRORPARSINGELEMENTDECL "error while parsing element declaration"
+#define XMLERR_ERRORPARSINGENTITYDECL "error while parsing entity declaration"
+#define XMLERR_ERRORPARSINGNOTATIONDECL "error while parsing notation declaration"
+#define XMLERR_ERRORPARSINGEXTERNALID "error while parsing external id"
+#define XMLERR_ERRORPARSINGCOMMENT "error while parsing comment"
+#define XMLERR_ERRORPARSINGENTITYVALUE "error while parsing entity value declaration"
+#define XMLERR_CDSECTHEADEREXPECTED "expected the header for a cdata section"
+#define XMLERR_MORETHANONEDOCTYPE "more than one document type definition"
+#define XMLERR_ERRORPARSINGDOCTYPE "error while parsing document type definition"
+#define XMLERR_INVALIDNAMEFORPI "invalid name for processing instruction"
+#define XMLERR_VERSIONEXPECTED "version expected while reading the XML declaration"
+#define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration"
+#define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration"
+#define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration"
+#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference in wrong context"
+#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value"
+
+
+// the constants for the lookup table
+static const signed char cltWS = 0; // white space
+static const signed char cltPer = 1; // %
+static const signed char cltAmp = 2; // &
+static const signed char cltGt = 3; // >
+static const signed char cltLt = 4; // <
+static const signed char cltSlash = 5; // /
+static const signed char cltQm = 6; // ?
+static const signed char cltEm = 7; // !
+static const signed char cltDash = 8; // -
+static const signed char cltCB = 9; // ]
+static const signed char cltOB = 10; // [
+static const signed char cltEq = 11; // =
+static const signed char cltDq = 12; // "
+static const signed char cltSq = 13; // '
+static const signed char cltUnknown = 14;
+
+// character lookup table
+static const signed char charLookupTable[256]={
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+ cltUnknown, // 0x08
+ cltWS, // 0x09 \t
+ cltWS, // 0x0A \n
+ cltUnknown, // 0x0B
+ cltUnknown, // 0x0C
+ cltWS, // 0x0D \r
+ cltUnknown, // 0x0E
+ cltUnknown, // 0x0F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+ cltWS, // 0x20 Space
+ cltEm, // 0x21 !
+ cltDq, // 0x22 "
+ cltUnknown, // 0x23
+ cltUnknown, // 0x24
+ cltPer, // 0x25 %
+ cltAmp, // 0x26 &
+ cltSq, // 0x27 '
+ cltUnknown, // 0x28
+ cltUnknown, // 0x29
+ cltUnknown, // 0x2A
+ cltUnknown, // 0x2B
+ cltUnknown, // 0x2C
+ cltDash, // 0x2D -
+ cltUnknown, // 0x2E
+ cltSlash, // 0x2F /
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+ cltUnknown, // 0x38
+ cltUnknown, // 0x39
+ cltUnknown, // 0x3A
+ cltUnknown, // 0x3B
+ cltLt, // 0x3C <
+ cltEq, // 0x3D =
+ cltGt, // 0x3E >
+ cltQm, // 0x3F ?
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+ cltUnknown, // 0x58
+ cltUnknown, // 0x59
+ cltUnknown, // 0x5A
+ cltOB, // 0x5B [
+ cltUnknown, // 0x5C
+ cltCB, // 0x5D ]
+ cltUnknown, // 0x5E
+ cltUnknown, // 0x5F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
+};
+
+
+class QXmlNamespaceSupportPrivate
+{
+};
+class QXmlAttributesPrivate
+{
+};
+class QXmlInputSourcePrivate
+{
+};
+class QXmlParseExceptionPrivate
+{
+};
+class QXmlLocatorPrivate
+{
+};
+class QXmlDefaultHandlerPrivate
+{
+};
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+bool operator==( const QMap<QString, QString>, const QMap<QString, QString> )
+{
+ return FALSE;
+}
+#endif
+
+/*!
+ \class QXmlParseException qxml.h
+ \brief The QXmlParseException class is used to report errors with the
+ QXmlErrorHandler interface.
+
+ \module XML
+
+ \sa QXmlErrorHandler
+*/
+/*!
+ \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
+
+ Constructs a parse exception with the error string \a name in the column
+ \a c and line \a l for the public identifier \a p and the system identifier
+ \a s.
+*/
+/*!
+ Returns the error message.
+*/
+QString QXmlParseException::message() const
+{
+ return msg;
+}
+/*!
+ Returns the column number the error occured.
+*/
+int QXmlParseException::columnNumber() const
+{
+ return column;
+}
+/*!
+ Returns the line number the error occured.
+*/
+int QXmlParseException::lineNumber() const
+{
+ return line;
+}
+/*!
+ Returns the public identifier the error occured.
+*/
+QString QXmlParseException::publicId() const
+{
+ return pub;
+}
+/*!
+ Returns the system identifier the error occured.
+*/
+QString QXmlParseException::systemId() const
+{
+ return sys;
+}
+
+
+/*!
+ \class QXmlLocator qxml.h
+ \brief The QXmlLocator class provides the XML handler classes with
+ information about the actual parsing position.
+
+ \module XML
+
+ The reader reports a QXmlLocator to the content handler before he starts to
+ parse the document. This is done with the
+ QXmlContentHandler::setDocumentLocator() function. The handler classes can
+ now use this locator to get the actual position the reader is at.
+*/
+/*!
+ \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent )
+
+ Constructor.
+*/
+/*!
+ \fn QXmlLocator::~QXmlLocator()
+
+ Destructor.
+*/
+/*!
+ Gets the column number (starting with 1) or -1 if there is no column number
+ available.
+*/
+int QXmlLocator::columnNumber()
+{
+ return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
+}
+/*!
+ Gets the line number (starting with 1) or -1 if there is no line number
+ available.
+*/
+int QXmlLocator::lineNumber()
+{
+ return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
+}
+
+
+/*********************************************
+ *
+ * QXmlNamespaceSupport
+ *
+ *********************************************/
+
+/*!
+ \class QXmlNamespaceSupport qxml.h
+ \brief The QXmlNamespaceSupport class is a helper class for XML readers which
+ want to include namespace support.
+
+ \module XML
+
+ It provides some functions that makes it easy to handle namespaces. Its main
+ use is for subclasses of QXmlReader which want to provide namespace
+ support.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+
+/*!
+ Constructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::QXmlNamespaceSupport()
+{
+ reset();
+}
+
+/*!
+ Destructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::~QXmlNamespaceSupport()
+{
+}
+
+/*!
+ This function declares a prefix in the current namespace context; the prefix
+ will remain in force until this context is popped, unless it is shadowed in a
+ descendant context.
+
+ Note that there is an asymmetry in this library: while prefix() will not
+ return the default "" prefix, even if you have declared one; to check for a
+ default prefix, you have to look it up explicitly using uri(). This
+ asymmetry exists to make it easier to look up prefixes for attribute names,
+ where the default prefix is not allowed.
+*/
+void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
+{
+ if( pre.isNull() ) {
+ ns.insert( "", uri );
+ } else {
+ ns.insert( pre, uri );
+ }
+}
+
+/*!
+ Returns one of the prefixes mapped to a namespace URI.
+
+ If more than one prefix is currently mapped to the same URI, this function
+ will make an arbitrary selection; if you want all of the prefixes, use the
+ prefixes() function instead.
+
+ Note: this will never return the empty (default) prefix; to check for a
+ default prefix, use the uri() function with an argument of "".
+*/
+QString QXmlNamespaceSupport::prefix( const QString& uri ) const
+{
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ return itc.key();
+ }
+ return "";
+}
+
+/*!
+ Looks up a prefix in the current context and returns the currently-mapped
+ namespace URI. Use the empty string ("") for the default namespace.
+*/
+QString QXmlNamespaceSupport::uri( const QString& prefix ) const
+{
+ const QString& returi = ns[ prefix ];
+ return returi;
+}
+
+/*!
+ Splits the name at the ':' and returns the prefix and the local name.
+*/
+void QXmlNamespaceSupport::splitName( const QString& qname,
+ QString& prefix, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ // and split
+ prefix = qname.left( pos );
+ localname = qname.mid( pos+1 );
+}
+
+/*!
+ Processes a raw XML 1.0 name in the current context by removing the prefix
+ and looking it up among the prefixes currently declared.
+
+ First parameter is the raw XML 1.0 name to be processed. The second parameter
+ is a flag wheter the name is the name of an attribute (TRUE) or not (FALSE).
+
+ The return values will be stored in the last two parameters as follows:
+ <ul>
+ <li> The namespace URI, or an empty string if none is in use.
+ <li> The local name (without prefix).
+ </ul>
+
+ If the raw name has a prefix that has not been declared, then the return
+ value will be empty.
+
+ Note that attribute names are processed differently than element names: an
+ unprefixed element name will received the default namespace (if any), while
+ an unprefixed element name will not
+*/
+void QXmlNamespaceSupport::processName( const QString& qname,
+ bool isAttribute,
+ QString& nsuri, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ if ( pos < qname.length() ) {
+ // there was a ':'
+ nsuri = uri( qname.left( pos ) );
+ localname = qname.mid( pos+1 );
+ } else {
+ // there was no ':'
+ if ( isAttribute ) {
+ nsuri = ""; // attributes don't take default namespace
+ } else {
+ nsuri = uri( "" ); // get default namespace
+ }
+ localname = qname;
+ }
+}
+
+/*!
+ Returns an enumeration of all prefixes currently declared.
+
+ Note: if there is a default prefix, it will not be returned in this
+ enumeration; check for the default prefix using uri() with an argument
+ of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes() const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Returns a list of all prefixes currently declared for a URI.
+
+ The xml: prefix will be included. If you want only one prefix that's
+ mapped to the namespace URI, and you don't care which one you get, use the
+ prefix() function instead.
+
+ Note: the empty (default) prefix is never included in this enumeration; to
+ check for the presence of a default namespace, use uri() with an
+ argument of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Starts a new namespace context.
+
+ Normally, you should push a new context at the beginning of each XML element:
+ the new context will automatically inherit the declarations of its parent
+ context, but it will also keep track of which declarations were made within
+ this context.
+*/
+void QXmlNamespaceSupport::pushContext()
+{
+ nsStack.push( ns );
+}
+
+/*!
+ Reverts to the previous namespace context.
+
+ Normally, you should pop the context at the end of each XML element. After
+ popping the context, all namespace prefix mappings that were previously in
+ force are restored.
+*/
+void QXmlNamespaceSupport::popContext()
+{
+ if( !nsStack.isEmpty() )
+ ns = nsStack.pop();
+}
+
+/*!
+ Resets this namespace support object for reuse.
+*/
+void QXmlNamespaceSupport::reset()
+{
+ nsStack.clear();
+ ns.clear();
+ ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
+}
+
+
+
+/*********************************************
+ *
+ * QXmlAttributes
+ *
+ *********************************************/
+
+/*!
+ \class QXmlAttributes qxml.h
+ \brief The QXmlAttributes class provides XML attributes.
+
+ \module XML
+
+ If attributes are reported by QXmlContentHandler::startElement() this
+ class is used to pass the attribute values. It provides you with different
+ functions to access the attribute names and values.
+*/
+/*!
+ \fn QXmlAttributes::QXmlAttributes()
+
+ Constructs an empty attribute list.
+*/
+/*!
+ \fn QXmlAttributes::~QXmlAttributes()
+
+ Destructs attributes.
+*/
+
+/*!
+ Look up the index of an attribute by an XML 1.0 qualified name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& qName ) const
+{
+ return qnameList.findIndex( qName );
+}
+
+/*!
+ Looks up the index of an attribute by a namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localPart specifies the attribute's local name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
+{
+ uint count = uriList.count();
+ for ( uint i=0; i<count; i++ ) {
+ if ( uriList[i] == uri && localnameList[i] == localPart )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Returns the number of attributes in the list.
+*/
+int QXmlAttributes::length() const
+{
+ return valueList.count();
+}
+
+/*!
+ Looks up an attribute's local name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::localName( int index ) const
+{
+ return localnameList[index];
+}
+
+/*!
+ Looks up an attribute's XML 1.0 qualified name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::qName( int index ) const
+{
+ return qnameList[index];
+}
+
+/*!
+ Looks up an attribute's namespace URI by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::uri( int index ) const
+{
+ return uriList[index];
+}
+
+/*!
+ Looks up an attribute's type by index (starting with 0).
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( int ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by XML 1.0 qualified name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by namespace name.
+
+ The first parameter specifies the namespace URI, or the empty string if
+ the name has no namespace URI. The second parameter specifies the
+ attribute's local name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString&, const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's value by index (starting with 0).
+*/
+QString QXmlAttributes::value( int index ) const
+{
+ return valueList[index];
+}
+
+/*!
+ Looks up an attribute's value by XML 1.0 qualified name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& qName ) const
+{
+ int i = index( qName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+/*!
+ Looks up an attribute's value by namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localName specifies the attribute's local name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
+{
+ int i = index( uri, localName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+
+/*********************************************
+ *
+ * QXmlInputSource
+ *
+ *********************************************/
+
+/*!
+ \class QXmlInputSource qxml.h
+ \brief The QXmlInputSource class is the source where XML data is read from.
+
+ \module XML
+
+ All subclasses of QXmlReader read the input from this class.
+*/
+
+/*!
+ Returns all the data this input source contains.
+*/
+const QString& QXmlInputSource::data() const
+{
+ return input;
+}
+
+/*!
+ Constructs a input source which contains no data.
+*/
+QXmlInputSource::QXmlInputSource( )
+{
+ input = "";
+}
+
+/*!
+ Constructs a input source and get the data from the text stream.
+*/
+QXmlInputSource::QXmlInputSource( QTextStream& stream )
+{
+ QByteArray rawData;
+ if ( stream.device()->isDirectAccess() ) {
+ rawData = stream.device()->readAll();
+ } else {
+ int nread = 0;
+ const int bufsize = 512;
+ while ( !stream.device()->atEnd() ) {
+ rawData.resize( nread + bufsize );
+ nread += stream.device()->readBlock( rawData.data()+nread, bufsize );
+ }
+ rawData.resize( nread );
+ }
+ readInput( rawData );
+}
+
+/*!
+ Constructs a input source and get the data from a file. If the file cannot be
+ read the input source is empty.
+*/
+QXmlInputSource::QXmlInputSource( QFile& file )
+{
+ if ( !file.open(IO_ReadOnly) ) {
+ input = "";
+ return;
+ }
+ QByteArray rawData = file.readAll();
+ readInput( rawData );
+ file.close();
+}
+
+/*!
+ Destructor.
+*/
+QXmlInputSource::~QXmlInputSource()
+{
+}
+
+/*!
+ Sets the data of the input source to \a dat.
+*/
+void QXmlInputSource::setData( const QString& dat )
+{
+ input = dat;
+}
+
+/*!
+ Read the XML file from the byte array; try to recoginize the encoding.
+*/
+// ### The input source should not do the encoding detection!
+void QXmlInputSource::readInput( QByteArray& rawData )
+{
+ QBuffer buf( rawData );
+ buf.open( IO_ReadOnly );
+ QTextStream *stream = new QTextStream( &buf );
+ QChar tmp;
+ // assume UTF8 or UTF16 at first
+ stream->setEncoding( QTextStream::UnicodeUTF8 );
+ input = "";
+ // read the first 5 characters
+ for ( int i=0; i<5; i++ ) {
+ *stream >> tmp;
+ input += tmp;
+ }
+ // starts the document with an XML declaration?
+ if ( input == "<?xml" ) {
+ // read the whole XML declaration
+ do {
+ *stream >> tmp;
+ input += tmp;
+ } while( tmp != '>' );
+ // and try to find out if there is an encoding
+ int pos = input.find( "encoding" );
+ if ( pos != -1 ) {
+ QString encoding;
+ do {
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ } while( input[pos] != '"' && input[pos] != '\'' );
+ pos++;
+ while( input[pos] != '"' && input[pos] != '\'' ) {
+ encoding += input[pos];
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ }
+ delete stream;
+ stream = new QTextStream( &buf );
+ stream->setCodec( QTextCodec::codecForName( encoding.utf8() ) );
+ buf.reset();
+ input = "";
+ }
+ }
+finished:
+ input += stream->read();
+ delete stream;
+ buf.close();
+}
+
+
+/*********************************************
+ *
+ * QXmlDefaultHandler
+ *
+ *********************************************/
+
+/*!
+ \class QXmlContentHandler qxml.h
+ \brief The QXmlContentHandler class provides an interface to report logical
+ content of XML data.
+
+ \module XML
+
+ If the application needs to be informed of basic parsing events, it
+ implements this interface and sets it with QXmlReader::setContentHandler().
+ The reader reports basic document-related events like the start and end of
+ elements and character data through this interface.
+
+ The order of events in this interface is very important, and mirrors the
+ order of information in the document itself. For example, all of an element's
+ content (character data, processing instructions, and/or subelements) will
+ appear, in order, between the startElement() event and the corresponding
+ endElement() event.
+
+ The class QXmlDefaultHandler gives a default implementation for this
+ interface; subclassing from this class is very convenient if you want only be
+ informed of some parsing events.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
+
+ The reader calls this function before he starts parsing the document. The
+ argument \a locator is a pointer to a QXmlLocator which allows the
+ application to get the actual position of the parsing in the document.
+
+ Do not destroy the \a locator; it is destroyed when the reader is destroyed
+ (do not use the \a locator after the reader got destroyed).
+*/
+/*!
+ \fn bool QXmlContentHandler::startDocument()
+
+ The reader calls this function when he starts parsing the document.
+ The reader will call this function only once before any other functions in
+ this class or in the QXmlDTDHandler class are called (except
+ QXmlContentHandler::setDocumentLocator()).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::endDocument()
+
+ The reader calls this function after he has finished the parsing. It
+ is only called once. It is the last function of all handler functions that is
+ called. It is called after the reader has read all input or has abandoned
+ parsing because of a fatal error.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
+
+ The reader calls this function to signal the begin of a prefix-URI
+ namespace mapping scope. This information is not necessary for normal
+ namespace processing since the reader automatically replaces prefixes for
+ element and attribute names.
+
+ Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to
+ be properly nested relative to each-other: all startPrefixMapping events will
+ occur before the corresponding startElement event, and all endPrefixMapping
+ events will occur after the corresponding endElement event, but their order
+ is not otherwise guaranteed.
+
+ The argument \a prefix is the namespace prefix being declared and the
+ argument \a uri is the namespace URI the prefix is mapped to.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
+
+ The reader calls this function to signal the end of a prefix mapping.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
+
+ The reader calls this function when he has parsed a start element tag.
+
+ There will be a corresponding endElement() call when the corresponding end
+ element tag was read. The startElement() and endElement() calls are always
+ nested correctly. Empty element tags (e.g. <a/>) are reported by
+ startElement() directly followed by a call to endElement().
+
+ The attribute list provided will contain only attributes with explicit
+ values. The attribute list will contain attributes used for namespace
+ declaration (i.e. attributes starting with xmlns) only if the
+ namespace-prefix property of the reader is TRUE.
+
+ The argument \a uri is the namespace URI, or the empty string if the element
+ has no namespace URI or if namespace processing is not being performed, \a
+ localName is the local name (without prefix), or the empty string if
+ namespace processing is not being performed, \a qName is the qualified name
+ (with prefix), or the empty string if qualified names are not available and
+ \a atts are the attributes attached to the element. If there are no
+ attributes, \a atts is an empty attributes object
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
+
+ The reader calls this function when he has parsed an end element tag.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::characters( const QString& ch )
+
+ The reader calls this function when he has parsed a chunk of character
+ data (either normal character data or character data inside a CDATA section;
+ if you have to distinguish between those two types you have to use
+ QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in
+ addition).
+
+ Some readers will report whitespace in element content using the
+ ignorableWhitespace() function rather than this one (QXmlSimpleReader will
+ do it not though).
+
+ A reader is allowed to report the character data of an element in more than
+ one chunk; e.g. a reader might want to report "a < b" in three
+ characters() events ("a ", "<" and " b").
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
+
+ Some readers may use this function to report each chunk of whitespace in
+ element content (QXmlSimpleReader does not though).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
+
+ The reader calls this function when he has parsed a processing
+ instruction.
+
+ \a target is the target name of the processing instruction and \a data is the
+ data of the processing instruction.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::skippedEntity( const QString& name )
+
+ Some readers may skip entities if they have not seen the declarations (e.g.
+ because they are in an external DTD). If they do so they will report it by
+ calling this function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlContentHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlErrorHandler qxml.h
+ \brief The QXmlErrorHandler class provides an interface to report errors in
+ XML data.
+
+ \module XML
+
+ If the application is interested in reporting errors to the user or any other
+ customized error handling, you should subclass this class.
+
+ You can set the error handler with QXmlReader::setErrorHandler().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
+
+ A reader might use this function to report a warning. Warnings are conditions
+ that are not errors or fatal errors as defined by the XML 1.0 specification.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
+
+ A reader might use this function to report a recoverable error. A recoverable
+ error corresponds to the definiton of "error" in section 1.2 of the XML 1.0
+ specification.
+
+ The reader must continue to provide normal parsing events after invoking this
+ function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
+
+ A reader must use this function to report a non-recoverable error.
+
+ If this function returns TRUE the reader might try to go on parsing and
+ reporting further errors; but no regular parsing events are reported.
+*/
+/*!
+ \fn QString QXmlErrorHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDTDHandler qxml.h
+ \brief The QXmlDTDHandler class provides an interface to report DTD content
+ of XML data.
+
+ \module XML
+
+ If an application needs information about notations and unparsed entities,
+ then the application implements this interface and registers an instance with
+ QXmlReader::setDTDHandler().
+
+ Note that this interface includes only those DTD events that the XML
+ recommendation requires processors to report: notation and unparsed entity
+ declarations.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function when he has parsed a notation
+ declaration.
+
+ The argument \a name is the notation name, \a publicId is the notations's
+ public identifier and \a systemId is the notations's system identifier.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
+
+ The reader calls this function when he finds an unparsed entity declaration.
+
+ The argument \a name is the unparsed entity's name, \a publicId is the
+ entity's public identifier, \a systemId is the entity's system identifier and
+ \a notation is the name of the associated notation.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDTDHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlEntityResolver qxml.h
+ \brief The QXmlEntityResolver class provides an interface to resolve extern
+ entities contained in XML data.
+
+ \module XML
+
+ If an application needs to implement customized handling for external
+ entities, it must implement this interface and register it with
+ QXmlReader::setEntityResolver().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret )
+
+ The reader will call this function before he opens any external entity,
+ except the top-level document entity. The application may request the reader
+ to resolve the entity itself (\a ret is 0) or to use an entirely different
+ input source (\a ret points to the input source).
+
+ The reader will delete the input source \a ret when he no longer needs it. So
+ you should allocate it on the heap with \c new.
+
+ The argument \a publicId is the public identifier of the external entity, \a
+ systemId is the system identifier of the external entity and \a ret is the
+ return value of this function: if it is 0 the reader should resolve the
+ entity itself, if it is non-zero it must point to an input source which the
+ reader will use instead.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlEntityResolver::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlLexicalHandler qxml.h
+ \brief The QXmlLexicalHandler class provides an interface to report lexical
+ content of XML data.
+
+ \module XML
+
+ The events in the lexical handler apply to the entire document, not just to
+ the document element, and all lexical handler events appear between the
+ content handler's startDocument and endDocument events.
+
+ You can set the lexical handler with QXmlReader::setLexicalHandler().
+
+ This interface is designed after the SAX2 extension LexicalHandler. The
+ functions startEntity() and endEntity() are not included though.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report the start of a DTD declaration, if
+ any.
+
+ All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear
+ between the startDTD() and endDTD() calls.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endDTD()
+
+ The reader calls this function to report the end of a DTD declaration, if
+ any.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startCDATA()
+
+ The reader calls this function to report the start of a CDATA section. The
+ content of the CDATA section will be reported through the regular
+ QXmlContentHandler::characters(). This function is intended only to report
+ the boundary.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endCDATA()
+
+ The reader calls this function to report the end of a CDATA section.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::comment( const QString& ch )
+
+ The reader calls this function to report an XML comment anywhere in the
+ document.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlLexicalHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDeclHandler qxml.h
+ \brief The QXmlDeclHandler class provides an interface to report declaration
+ content of XML data.
+
+ \module XML
+
+ You can set the declaration handler with QXmlReader::setDeclHandler().
+
+ This interface is designed after the SAX2 extension DeclHandler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
+
+ The reader calls this function to report an attribute type declaration. Only
+ the effective (first) declaration for an attribute will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
+
+ The reader calls this function to report an internal entity declaration. Only
+ the effective (first) declaration will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report a parsed external entity
+ declaration. Only the effective (first) declaration for each entity will be
+ reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDeclHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDefaultHandler qxml.h
+ \brief The QXmlDefaultHandler class provides a default implementation of all
+ XML handler classes.
+
+ \module XML
+
+ Very often you are only interested in parts of the things that that the
+ reader reports to you. This class simply implements a default behaviour of
+ the handler classes (most of the time: do nothing). Normally this is the
+ class you subclass for implementing your customized handler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler QXmlLexicalHandler
+*/
+/*!
+ \fn QXmlDefaultHandler::QXmlDefaultHandler()
+
+ Constructor.
+*/
+/*!
+ \fn QXmlDefaultHandler::~QXmlDefaultHandler()
+
+ Destructor.
+*/
+
+/*!
+ Does nothing.
+*/
+void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* )
+{
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endPrefixMapping( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startElement( const QString&, const QString&,
+ const QString&, const QXmlAttributes& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endElement( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::characters( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::ignorableWhitespace( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::processingInstruction( const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::skippedEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::warning( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::error( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::fatalError( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::notationDecl( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&,
+ const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Always sets \a ret to 0, so that the reader will use the system identifier
+ provided in the XML document.
+*/
+bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&,
+ QXmlInputSource* &ret )
+{
+ ret = 0;
+ return TRUE;
+}
+
+/*!
+ Returns the default error string.
+*/
+QString QXmlDefaultHandler::errorString()
+{
+ return QString( XMLERR_ERRORBYCONSUMER );
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDTD()
+{
+ return TRUE;
+}
+
+#if 0
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endEntity( const QString& )
+{
+ return TRUE;
+}
+#endif
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::comment( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+
+/*********************************************
+ *
+ * QXmlSimpleReaderPrivate
+ *
+ *********************************************/
+
+class QXmlSimpleReaderPrivate
+{
+private:
+ // constructor
+ QXmlSimpleReaderPrivate()
+ { }
+
+
+ // used for entity declarations
+ struct ExternParameterEntity
+ {
+ ExternParameterEntity( ) {}
+ ExternParameterEntity( const QString &p, const QString &s )
+ : publicId(p), systemId(s) {}
+ QString publicId;
+ QString systemId;
+ };
+ struct ExternEntity
+ {
+ ExternEntity( ) {}
+ ExternEntity( const QString &p, const QString &s, const QString &n )
+ : publicId(p), systemId(s), notation(n) {}
+ QString publicId;
+ QString systemId;
+ QString notation;
+ };
+ QMap<QString,ExternParameterEntity> externParameterEntities;
+ QMap<QString,QString> parameterEntities;
+ QMap<QString,ExternEntity> externEntities;
+ QMap<QString,QString> entities;
+
+ // used for standalone declaration
+ enum Standalone { Yes, No, Unknown };
+
+ QString doctype; // only used for the doctype
+ QString xmlVersion; // only used to store the version information
+ QString encoding; // only used to store the encoding
+ Standalone standalone; // used to store the value of the standalone declaration
+
+ QString publicId; // used by parseExternalID() to store the public ID
+ QString systemId; // used by parseExternalID() to store the system ID
+ QString attDeclEName; // use by parseAttlistDecl()
+ QString attDeclAName; // use by parseAttlistDecl()
+
+ // flags for some features support
+ bool useNamespaces;
+ bool useNamespacePrefixes;
+ bool reportWhitespaceCharData;
+
+ // used to build the attribute list
+ QXmlAttributes attList;
+
+ // helper classes
+ QXmlLocator *locator;
+ QXmlNamespaceSupport namespaceSupport;
+
+ // error string
+ QString error;
+
+ // friend declarations
+ friend class QXmlSimpleReader;
+};
+
+
+/*********************************************
+ *
+ * QXmlSimpleReader
+ *
+ *********************************************/
+
+/*!
+ \class QXmlReader qxml.h
+ \brief The QXmlReader class provides an interface for XML readers (i.e.
+ parsers).
+
+ \module XML
+
+ This abstract class describes an interface for all XML readers in Qt. At the
+ moment there is only one implementation of a reader included in the XML
+ module of Qt (QXmlSimpleReader). In future releases there might be more
+ readers with different properties available (e.g. a validating parser).
+
+ The design of the XML classes follow the
+ <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>.
+ It was adopted to fit into the Qt naming conventions; so it should be very
+ easy for anybody who has worked with SAX2 to get started with the Qt XML
+ classes.
+
+ All readers use the class QXmlInputSource to read the input document from.
+ Since you are normally interested in certain contents of the XML document,
+ the reader reports those contents through special handler classes
+ (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ QXmlErrorHandler and QXmlLexicalHandler).
+
+ You have to subclass these classes. Since the handler classes describe only
+ interfaces you must implement all functions; there is a class
+ (QXmlDefaultHandler) to make this easier; it implements a default behaviour
+ (do nothing) for all functions.
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+
+ \sa QXmlSimpleReader
+*/
+/*!
+ \fn bool QXmlReader::feature( const QString& name, bool *ok ) const
+
+ If the reader has the feature \a name, this function returns the value of the
+ feature.
+
+ If the reader has not the feature \a name, the return value may be anything.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the feature
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setFeature() hasFeature()
+*/
+/*!
+ \fn void QXmlReader::setFeature( const QString& name, bool value )
+
+ Sets the feature \a name to \a value. If the reader has not the feature \a
+ name, this value is ignored.
+
+ \sa feature() hasFeature()
+*/
+/*!
+ \fn bool QXmlReader::hasFeature( const QString& name ) const
+
+ Returns \c TRUE if the reader has the feature \a name, otherwise FALSE.
+
+ \sa feature() setFeature()
+*/
+/*!
+ \fn void* QXmlReader::property( const QString& name, bool *ok ) const
+
+ If the reader has the property \a name, this function returns the value of
+ the property.
+
+ If the reader has not the property \a name, the return value is 0.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the property
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setProperty() hasProperty()
+*/
+/*!
+ \fn void QXmlReader::setProperty( const QString& name, void* value )
+
+ Sets the property \a name to \a value. If the reader has not the property \a
+ name, this value is ignored.
+
+ \sa property() hasProperty()
+*/
+/*!
+ \fn bool QXmlReader::hasProperty( const QString& name ) const
+
+ Returns TRUE if the reader has the property \a name, otherwise FALSE.
+
+ \sa property() setProperty()
+*/
+/*!
+ \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
+
+ Sets the entity resolver to \a handler.
+
+ \sa entityResolver()
+*/
+/*!
+ \fn QXmlEntityResolver* QXmlReader::entityResolver() const
+
+ Returns the entity resolver or 0 if none was set.
+
+ \sa setEntityResolver()
+*/
+/*!
+ \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
+
+ Sets the DTD handler to \a handler.
+
+ \sa DTDHandler()
+*/
+/*!
+ \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+
+ Returns the DTD handler or 0 if none was set.
+
+ \sa setDTDHandler()
+*/
+/*!
+ \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
+
+ Sets the content handler to \a handler.
+
+ \sa contentHandler()
+*/
+/*!
+ \fn QXmlContentHandler* QXmlReader::contentHandler() const
+
+ Returns the content handler or 0 if none was set.
+
+ \sa setContentHandler()
+*/
+/*!
+ \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
+
+ Sets the error handler to \a handler.
+
+ \sa errorHandler()
+*/
+/*!
+ \fn QXmlErrorHandler* QXmlReader::errorHandler() const
+
+ Returns the error handler or 0 if none was set
+
+ \sa setErrorHandler()
+*/
+/*!
+ \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
+
+ Sets the lexical handler to \a handler.
+
+ \sa lexicalHandler()
+*/
+/*!
+ \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+
+ Returns the lexical handler or 0 if none was set.
+
+ \sa setLexicalHandler()
+*/
+/*!
+ \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
+
+ Sets the declaration handler to \a handler.
+
+ \sa declHandler()
+*/
+/*!
+ \fn QXmlDeclHandler* QXmlReader::declHandler() const
+
+ Returns the declaration handler or 0 if none was set.
+
+ \sa setDeclHandler()
+*/
+/*!
+ \fn bool QXmlReader::parse( const QXmlInputSource& input )
+
+ Parses the XML document \a input. Returns TRUE if the parsing was successful,
+ otherwise FALSE.
+*/
+/*!
+ \fn bool QXmlReader::parse( const QString& systemId )
+
+ Parses the XML document at the location \a systemId. Returns TRUE if the
+ parsing was successful, otherwise FALSE.
+*/
+
+
+/*!
+ \class QXmlSimpleReader qxml.h
+ \brief The QXmlSimpleReader class provides an implementation of a simple XML
+ reader (i.e. parser).
+
+ \module XML
+
+ This XML reader is sufficient for simple parsing tasks. Here is a short list
+ of the properties of this reader:
+ <ul>
+ <li> well-formed parser
+ <li> does not parse any external entities
+ <li> can do namespace processing
+ </ul>
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+*/
+
+//guaranteed not to be a characater
+const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff);
+
+/*!
+ Constructs a simple XML reader.
+*/
+QXmlSimpleReader::QXmlSimpleReader()
+{
+ d = new QXmlSimpleReaderPrivate();
+ d->locator = new QXmlLocator( this );
+
+ entityRes = 0;
+ dtdHnd = 0;
+ contentHnd = 0;
+ errorHnd = 0;
+ lexicalHnd = 0;
+ declHnd = 0;
+
+ // default feature settings
+ d->useNamespaces = TRUE;
+ d->useNamespacePrefixes = FALSE;
+ d->reportWhitespaceCharData = TRUE;
+}
+
+/*!
+ Destroys a simple XML reader.
+*/
+QXmlSimpleReader::~QXmlSimpleReader()
+{
+ delete d->locator;
+ delete d;
+}
+
+/*!
+ Gets the state of a feature.
+
+ \sa setFeature() hasFeature()
+*/
+bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = TRUE;
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ return d->useNamespaces;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ return d->useNamespacePrefixes;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return d->reportWhitespaceCharData;
+ } else {
+ qWarning( "Unknown feature %s", name.ascii() );
+ if ( ok != 0 )
+ *ok = FALSE;
+ }
+ return FALSE;
+}
+
+/*!
+ Sets the state of a feature.
+
+ Supported features are:
+ <ul>
+ <li> http://xml.org/sax/features/namespaces:
+ if this feature is TRUE, namespace processing is performed
+ <li> http://xml.org/sax/features/namespace-prefixes:
+ if this feature is TRUE, the the original prefixed names and attributes
+ used for namespace declarations are reported
+ <li> http://trolltech.com/xml/features/report-whitespace-only-CharData:
+ if this feature is TRUE, CharData that consists only of whitespace (and
+ no other characters) is not reported via
+ QXmlContentHandler::characters()
+ </ul>
+
+ \sa feature() hasFeature()
+*/
+void QXmlSimpleReader::setFeature( const QString& name, bool value )
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ d->useNamespaces = value;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ d->useNamespacePrefixes = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ d->reportWhitespaceCharData = value;
+ } else {
+ qWarning( "Unknown feature %s", name.ascii() );
+ }
+}
+
+/*!
+ Returns TRUE if the class has a feature named \a feature, otherwise FALSE.
+
+ \sa setFeature() feature()
+*/
+bool QXmlSimpleReader::hasFeature( const QString& name ) const
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ||
+ name == "http://xml.org/sax/features/namespace-prefixes" ||
+ name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*!
+ Returns 0 since this class does not support any properties.
+*/
+void* QXmlSimpleReader::property( const QString&, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = FALSE;
+ return 0;
+}
+
+/*!
+ Does nothing since this class does not support any properties.
+*/
+void QXmlSimpleReader::setProperty( const QString&, void* )
+{
+}
+
+/*!
+ Returns FALSE since this class does not support any properties.
+*/
+bool QXmlSimpleReader::hasProperty( const QString& ) const
+{
+ return FALSE;
+}
+
+/*! \reimp */
+void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler )
+{ entityRes = handler; }
+
+/*! \reimp */
+QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
+{ return entityRes; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler )
+{ dtdHnd = handler; }
+
+/*! \reimp */
+QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
+{ return dtdHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler )
+{ contentHnd = handler; }
+
+/*! \reimp */
+QXmlContentHandler* QXmlSimpleReader::contentHandler() const
+{ return contentHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler )
+{ errorHnd = handler; }
+
+/*! \reimp */
+QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
+{ return errorHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler )
+{ lexicalHnd = handler; }
+
+/*! \reimp */
+QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
+{ return lexicalHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler )
+{ declHnd = handler; }
+
+/*! \reimp */
+QXmlDeclHandler* QXmlSimpleReader::declHandler() const
+{ return declHnd; }
+
+
+
+/*! \reimp */
+bool QXmlSimpleReader::parse( const QXmlInputSource& input )
+{
+ init( input );
+ // call the handler
+ if ( contentHnd ) {
+ contentHnd->setDocumentLocator( d->locator );
+ if ( !contentHnd->startDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ // parse prolog
+ if ( !parseProlog() ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // parse element
+ if ( !parseElement() ) {
+ d->error = XMLERR_ERRORPARSINGMAINELEMENT;
+ goto parseError;
+ }
+ // parse Misc*
+ while ( !atEnd() ) {
+ if ( !parseMisc() ) {
+ d->error = XMLERR_ERRORPARSINGMISC;
+ goto parseError;
+ }
+ }
+ // is stack empty?
+ if ( !tags.isEmpty() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->endDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+
+ return TRUE;
+
+ // error handling
+
+parseError:
+ reportParseError();
+ tags.clear();
+ return FALSE;
+}
+
+/*!
+ Parses the prolog [22].
+*/
+bool QXmlSimpleReader::parseProlog()
+{
+ bool xmldecl_possible = TRUE;
+ bool doctype_read = FALSE;
+
+ const signed char Init = 0;
+ const signed char EatWS = 1; // eat white spaces
+ const signed char Lt = 2; // '<' read
+ const signed char Em = 3; // '!' read
+ const signed char DocType = 4; // read doctype
+ const signed char Comment = 5; // read comment
+ const signed char PI = 6; // read PI
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpD = 4; // D
+ const signed char InpDash = 5; // -
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][7] = {
+ /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
+ { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
+ { -1, -1, PI, Em, Done, -1, Done }, // Lt
+ { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
+ { EatWS, Lt, -1, -1, -1, -1, -1 } // PI
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case EatWS:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // eat white spaces
+ eat_ws();
+ break;
+ case Lt:
+ // next character
+ next();
+ break;
+ case Em:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // next character
+ next();
+ break;
+ case DocType:
+ parseOk = parseDoctype();
+ break;
+ case Comment:
+ parseOk = parseComment();
+ break;
+ case PI:
+ parseOk = parsePI( xmldecl_possible );
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DocType:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( doctype_read ) {
+ d->error = XMLERR_MORETHANONEDOCTYPE;
+ goto parseError;
+ } else {
+ doctype_read = FALSE;
+ }
+ break;
+ case Comment:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) {
+ QString value( "version = '" );
+ value += d->xmlVersion;
+ value += "'";
+ if ( !d->encoding.isEmpty() ) {
+ value += " encoding = '";
+ value += d->encoding;
+ value += "'";
+ }
+ if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
+ value += " standalone = 'yes'";
+ } else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
+ value += " standalone = 'no'";
+ }
+ if ( !contentHnd->processingInstruction( "xml", value ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ } else {
+ if ( !contentHnd->processingInstruction( name(), string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse an element [39].
+
+ Precondition: the opening '<' is already read.
+*/
+bool QXmlSimpleReader::parseElement()
+{
+ static QString uri, lname, prefix;
+ static bool t;
+
+ const signed char Init = 0;
+ const signed char ReadName = 1;
+ const signed char Ws1 = 2;
+ const signed char STagEnd = 3;
+ const signed char STagEnd2 = 4;
+ const signed char ETagBegin = 5;
+ const signed char ETagBegin2 = 6;
+ const signed char Ws2 = 7;
+ const signed char EmptyTag = 8;
+ const signed char Attribute = 9;
+ const signed char Ws3 = 10;
+ const signed char Done = 11;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_NameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpSlash = 3; // /
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[11][5] = {
+ /* InpWs InpNameBe InpGt InpSlash InpUnknown */
+ { -1, ReadName, -1, -1, -1 }, // Init
+ { Ws1, Attribute, STagEnd, EmptyTag, -1 }, // ReadName
+ { -1, Attribute, STagEnd, EmptyTag, -1 }, // Ws1
+ { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
+ { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
+ { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
+ { Ws2, -1, Done, -1, -1 }, // ETagBegin2
+ { -1, -1, Done, -1, -1 }, // Ws2
+ { -1, -1, Done, -1, -1 }, // EmptyTag
+ { Ws3, Attribute, STagEnd, EmptyTag, -1 }, // Attribute
+ { -1, Attribute, STagEnd, EmptyTag, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '/' ) {
+ input = InpSlash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case ReadName:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case STagEnd:
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+ } else {
+ t = contentHnd->startElement( "", "", tags.top(), d->attList );
+ }
+ if ( !t ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ case STagEnd2:
+ parseOk = parseContent();
+ break;
+ case ETagBegin:
+ next();
+ break;
+ case ETagBegin2:
+ // get the name of the tag
+ parseOk = parseName();
+ break;
+ case EmptyTag:
+ if ( tags.isEmpty() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ goto parseError;
+ }
+ if ( !parseElementEmptyTag( t, uri, lname ) )
+ goto parseError;
+ // next character
+ next();
+ break;
+ case Attribute:
+ // get name and value of attribute
+ parseOk = parseAttribute();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ReadName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // store it on the stack
+ tags.push( name() );
+ // empty the attributes
+ d->attList.qnameList.clear();
+ d->attList.uriList.clear();
+ d->attList.localnameList.clear();
+ d->attList.valueList.clear();
+ // namespace support?
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.pushContext();
+ }
+ break;
+ case STagEnd2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+ break;
+ case ETagBegin2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( !parseElementETagBegin2( uri, lname ) )
+ goto parseError;
+ break;
+ case Attribute:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTRIBUTE;
+ goto parseError;
+ }
+ if ( !parseElementAttribute( prefix, uri, lname ) )
+ goto parseError;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementEmptyTag( bool &t, QString &uri, QString &lname )
+{
+ // pop the stack and call the handler
+ if ( contentHnd ) {
+ // report startElement first...
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+ } else {
+ t = contentHnd->startElement( "", "", tags.top(), d->attList );
+ }
+ if ( !t ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ // ... followed by endElement
+ if ( d->useNamespaces ) {
+ if ( !contentHnd->endElement( uri, lname,tags.pop() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ else {
+ if ( !contentHnd->endElement( "","",tags.pop() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ // namespace support?
+ if ( d->useNamespaces ) {
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ tags.pop();
+ }
+ return TRUE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementETagBegin2( QString &uri, QString &lname )
+{
+
+ // pop the stack and compare it with the name
+ if ( tags.pop() != name() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ return FALSE;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( name(), FALSE, uri, lname );
+ if ( !contentHnd->endElement(uri,lname,name()) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ else {
+ if ( !contentHnd->endElement("","",name()) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ // namespace support?
+ if ( d->useNamespaces ) {
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementAttribute( QString &prefix, QString &uri, QString &lname )
+{
+ // add the attribute to the list
+ if ( d->useNamespaces ) {
+ // is it a namespace declaration?
+ d->namespaceSupport.splitName( name(), prefix, lname );
+ if ( prefix == "xmlns" ) {
+ // namespace declaration
+ d->namespaceSupport.setPrefix( lname, string() );
+ if ( d->useNamespacePrefixes ) {
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ } else {
+ // no namespace delcaration
+ d->namespaceSupport.processName( name(), TRUE, uri, lname );
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( uri );
+ d->attList.localnameList.append( lname );
+ d->attList.valueList.append( string() );
+ }
+ } else {
+ // no namespace support
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ return TRUE;
+}
+
+/*!
+ Parse a content [43].
+
+ A content is only used between tags. If a end tag is found the < is already
+ read and the head stand on the '/' of the end tag '</name>'.
+*/
+bool QXmlSimpleReader::parseContent()
+{
+ bool charDataRead = FALSE;
+
+ const signed char Init = 0;
+ const signed char ChD = 1; // CharData
+ const signed char ChD1 = 2; // CharData help state
+ const signed char ChD2 = 3; // CharData help state
+ const signed char Ref = 4; // Reference
+ const signed char Lt = 5; // '<' read
+ const signed char PI = 6; // PI
+ const signed char Elem = 7; // Element
+ const signed char Em = 8; // '!' read
+ const signed char Com = 9; // Comment
+ const signed char CDS = 10; // CDSect
+ const signed char CDS1 = 11; // read a CDSect
+ const signed char CDS2 = 12; // read a CDSect (help state)
+ const signed char CDS3 = 13; // read a CDSect (help state)
+ const signed char Done = 14; // finished reading content
+
+ const signed char InpLt = 0; // <
+ const signed char InpGt = 1; // >
+ const signed char InpSlash = 2; // /
+ const signed char InpQMark = 3; // ?
+ const signed char InpEMark = 4; // !
+ const signed char InpAmp = 5; // &
+ const signed char InpDash = 6; // -
+ const signed char InpOpenB = 7; // [
+ const signed char InpCloseB = 8; // ]
+ const signed char InpUnknown = 9;
+
+ static signed char mapCLT2FSMChar[] = {
+ InpUnknown, // white space
+ InpUnknown, // %
+ InpAmp, // &
+ InpGt, // >
+ InpLt, // <
+ InpSlash, // /
+ InpQMark, // ?
+ InpEMark, // !
+ InpDash, // -
+ InpCloseB, // ]
+ InpOpenB, // [
+ InpUnknown, // =
+ InpUnknown, // "
+ InpUnknown, // '
+ InpUnknown // unknown
+ };
+
+ // use some kind of state machine for parsing
+ static signed char const table[14][10] = {
+ /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
+ { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
+ { -1, -1, Done, PI, Em, -1, -1, -1, -1, Elem }, // Lt
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PI (same as Init)
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
+ { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
+ { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input (use lookup-table instead of nested ifs for performance
+ // reasons)
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else {
+ input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Init:
+ // next character
+ next();
+ break;
+ case ChD:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD1:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD2:
+ stringAddC();
+ next();
+ break;
+ case Ref:
+ if ( !charDataRead) {
+ // reference may be CharData; so clear string to be safe
+ stringClear();
+ parseOk = parseReference( charDataRead, InContent );
+ } else {
+ bool tmp;
+ parseOk = parseReference( tmp, InContent );
+ }
+ break;
+ case Lt:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ charDataRead = FALSE;
+ // next character
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Elem:
+ parseOk = parseElement();
+ break;
+ case Em:
+ // next character
+ next();
+ break;
+ case Com:
+ parseOk = parseComment();
+ break;
+ case CDS:
+ parseOk = parseString( "[CDATA[" );
+ break;
+ case CDS1:
+ // read one character and add it
+ stringAddC();
+ next();
+ break;
+ case CDS2:
+ // skip ']'
+ next();
+ break;
+ case CDS3:
+ // skip ']'...
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ref:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Elem:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+ break;
+ case Com:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case CDS:
+ if( !parseOk ) {
+ d->error = XMLERR_CDSECTHEADEREXPECTED;
+ goto parseError;
+ }
+ // empty string
+ stringClear();
+ break;
+ case CDS2:
+ if (c != ']') {
+ stringAddC( ']' );
+ }
+ break;
+ case CDS3:
+ // test if this skipping was legal
+ if ( c == '>' ) {
+ // the end of the CDSect
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else if (c == ']') {
+ // three or more ']'
+ stringAddC( ']' );
+ } else {
+ // after ']]' comes another character
+ stringAddC( ']' );
+ stringAddC( ']' );
+ }
+ break;
+ case Done:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse Misc [27].
+*/
+bool QXmlSimpleReader::parseMisc()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // '<' was read
+ const signed char Comment = 2; // read comment
+ const signed char eatWS = 3; // eat whitespaces
+ const signed char PI = 4; // read PI
+ const signed char Comment2 = 5; // read comment
+
+ const signed char InpWs = 0; // S
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][5] = {
+ /* InpWs InpLt InpQm InpEm InpUnknown */
+ { eatWS, Lt, -1, -1, -1 }, // Init
+ { -1, -1, PI, Comment, -1 }, // Lt
+ { -1, -1, -1, -1, Comment2 } // Comment
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case eatWS:
+ eat_ws();
+ break;
+ case Lt:
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Comment:
+ next();
+ break;
+ case Comment2:
+ parseOk = parseComment();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case eatWS:
+ return TRUE;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case Comment2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a processing instruction [16].
+
+ If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
+
+ Precondition: the beginning '<' of the PI is already read and the head stand
+ on the '?' of '<?'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the PI.
+*/
+bool QXmlSimpleReader::parsePI( bool xmldecl )
+{
+ const signed char Init = 0;
+ const signed char QmI = 1; // ? was read
+ const signed char Name = 2; // read Name
+ const signed char XMLDecl = 3; // read XMLDecl
+ const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
+ const signed char PI = 5; // read PI
+ const signed char Ws2 = 6; // eat ws after Name of PI
+ const signed char Version = 7; // read versionInfo
+ const signed char Ws3 = 8; // eat ws after versionInfo
+ const signed char EorSD = 9; // read EDecl or SDDecl
+ const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
+ const signed char SD = 11; // read SDDecl
+ const signed char Ws5 = 12; // eat ws after SDDecl
+ const signed char ADone = 13; // almost done
+ const signed char Char = 14; // Char was read
+ const signed char Qm = 15; // Qm was read
+ const signed char Done = 16; // finished reading content
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_nameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpQm = 3; // ?
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[16][5] = {
+ /* InpWs, InpNameBe InpGt InpQm InpUnknown */
+ { -1, -1, -1, QmI, -1 }, // Init
+ { -1, Name, -1, -1, -1 }, // QmI
+ { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
+ { Ws1, -1, -1, -1, -1 }, // XMLDecl
+ { -1, Version, -1, -1, -1 }, // Ws1
+ { Ws2, -1, -1, Qm, -1 }, // PI
+ { Char, Char, Char, Qm, Char }, // Ws2
+ { Ws3, -1, -1, ADone, -1 }, // Version
+ { -1, EorSD, -1, ADone, -1 }, // Ws3
+ { Ws4, -1, -1, ADone, -1 }, // EorSD
+ { -1, SD, -1, ADone, -1 }, // Ws4
+ { Ws5, -1, -1, ADone, -1 }, // SD
+ { -1, -1, -1, ADone, -1 }, // Ws5
+ { -1, -1, Done, -1, -1 }, // ADone
+ { Char, Char, Char, Qm, Char }, // Char
+ { Char, Char, Done, Qm, Char }, // Qm
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case QmI:
+ next();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ case Ws5:
+ eat_ws();
+ break;
+ case Version:
+ parseOk = parseAttribute();
+ break;
+ case EorSD:
+ parseOk = parseAttribute();
+ break;
+ case SD:
+ // get the SDDecl (syntax like an attribute)
+ if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
+ // already parsed the standalone declaration
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ parseOk = parseAttribute();
+ break;
+ case ADone:
+ next();
+ break;
+ case Char:
+ stringAddC();
+ next();
+ break;
+ case Qm:
+ // skip the '?'
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // test what name was read and determine the next state
+ // (not very beautiful, I admit)
+ if ( name().lower() == "xml" ) {
+ if ( xmldecl && name()=="xml" ) {
+ state = XMLDecl;
+ } else {
+ d->error = XMLERR_INVALIDNAMEFORPI;
+ goto parseError;
+ }
+ } else {
+ state = PI;
+ stringClear();
+ }
+ break;
+ case Version:
+ // get version (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "version" ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ d->xmlVersion = string();
+ break;
+ case EorSD:
+ // get the EDecl or SDDecl (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() == "standalone" ) {
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ } else if ( name() == "encoding" ) {
+ d->encoding = string();
+ } else {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ break;
+ case SD:
+ if ( !parseOk ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "standalone" ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ break;
+ case Qm:
+ // test if the skipping was legal
+ if ( c != '>' ) {
+ stringAddC( '?' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a document type definition (doctypedecl [28]).
+
+ Precondition: the beginning '<!' of the doctype is already read the head
+ stands on the 'D' of '<!DOCTYPE'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the document type definition.
+*/
+bool QXmlSimpleReader::parseDoctype()
+{
+ // some init-stuff
+ d->systemId = QString::null;
+ d->publicId = QString::null;
+
+ const signed char Init = 0;
+ const signed char Doctype = 1; // read the doctype
+ const signed char Ws1 = 2; // eat_ws
+ const signed char Doctype2 = 3; // read the doctype, part 2
+ const signed char Ws2 = 4; // eat_ws
+ const signed char Sys = 5; // read SYSTEM
+ const signed char Ws3 = 6; // eat_ws
+ const signed char MP = 7; // markupdecl or PEReference
+ const signed char PER = 8; // PERReference
+ const signed char Mup = 9; // markupdecl
+ const signed char Ws4 = 10; // eat_ws
+ const signed char MPE = 11; // end of markupdecl or PEReference
+ const signed char Done = 12;
+
+ const signed char InpWs = 0;
+ const signed char InpD = 1; // 'D'
+ const signed char InpS = 2; // 'S' or 'P'
+ const signed char InpOB = 3; // [
+ const signed char InpCB = 4; // ]
+ const signed char InpPer = 5; // %
+ const signed char InpGt = 6; // >
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static signed char table[12][8] = {
+ /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
+ { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
+ { Ws1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Doctype
+ { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
+ { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
+ { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
+ { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
+ { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
+ { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpS;
+ } else if ( c == '[' ) {
+ input = InpOB;
+ } else if ( c == ']' ) {
+ input = InpCB;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Doctype:
+ parseOk = parseString( "DOCTYPE" );
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ eat_ws();
+ break;
+ case Doctype2:
+ parseName();
+ break;
+ case Sys:
+ parseOk = parseExternalID();
+ break;
+ case MP:
+ next_eat_ws();
+ break;
+ case PER:
+ parseOk = parsePEReference( InDTD );
+ break;
+ case Mup:
+ parseOk = parseMarkupdecl();
+ break;
+ case MPE:
+ next_eat_ws();
+ break;
+ case Done:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endDTD() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Doctype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ if ( !is_S(c) ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Doctype2:
+ d->doctype = name();
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Sys:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case PER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Mup:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a ExternalID [75].
+
+ If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
+*/
+bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
+{
+ // some init-stuff
+ d->systemId = QString::null;
+ d->publicId = QString::null;
+
+ const signed char Init = 0;
+ const signed char Sys = 1; // parse 'SYSTEM'
+ const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
+ const signed char SysSQ = 3; // parse SystemLiteral with '
+ const signed char SysSQ2 = 4; // parse SystemLiteral with '
+ const signed char SysDQ = 5; // parse SystemLiteral with "
+ const signed char SysDQ2 = 6; // parse SystemLiteral with "
+ const signed char Pub = 7; // parse 'PUBLIC'
+ const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
+ const signed char PubSQ = 9; // parse PubidLiteral with '
+ const signed char PubSQ2 = 10; // parse PubidLiteral with '
+ const signed char PubDQ = 11; // parse PubidLiteral with "
+ const signed char PubDQ2 = 12; // parse PubidLiteral with "
+ const signed char PubE = 13; // finished parsing the PubidLiteral
+ const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
+ const signed char PDone = 15; // done if allowPublicID is TRUE
+ const signed char Done = 16;
+
+ const signed char InpSQ = 0; // '
+ const signed char InpDQ = 1; // "
+ const signed char InpS = 2; // S
+ const signed char InpP = 3; // P
+ const signed char InpWs = 4; // white space
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static signed char table[15][6] = {
+ /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
+ { -1, -1, Sys, Pub, -1, -1 }, // Init
+ { -1, -1, -1, -1, SysWS, -1 }, // Sys
+ { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
+ { -1, -1, -1, -1, PubWS, -1 }, // Pub
+ { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
+ { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
+ { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '\'' ) {
+ input = InpSQ;
+ } else if ( c == '"' ) {
+ input = InpDQ;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpP;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Sys:
+ parseOk = parseString( "SYSTEM" );
+ break;
+ case SysWS:
+ eat_ws();
+ break;
+ case SysSQ:
+ case SysDQ:
+ stringClear();
+ next();
+ break;
+ case SysSQ2:
+ case SysDQ2:
+ stringAddC();
+ next();
+ break;
+ case Pub:
+ parseOk = parseString( "PUBLIC" );
+ break;
+ case PubWS:
+ eat_ws();
+ break;
+ case PubSQ:
+ case PubDQ:
+ stringClear();
+ next();
+ break;
+ case PubSQ2:
+ case PubDQ2:
+ stringAddC();
+ next();
+ break;
+ case PubE:
+ next();
+ break;
+ case PubWS2:
+ d->publicId = string();
+ eat_ws();
+ break;
+ case Done:
+ d->systemId = string();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Sys:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Pub:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case PDone:
+ if ( allowPublicID ) {
+ d->publicId = string();
+ return TRUE;
+ } else {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a markupdecl [29].
+*/
+bool QXmlSimpleReader::parseMarkupdecl()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // < was read
+ const signed char Em = 2; // ! was read
+ const signed char CE = 3; // E was read
+ const signed char Qm = 4; // ? was read
+ const signed char Dash = 5; // - was read
+ const signed char CA = 6; // A was read
+ const signed char CEL = 7; // EL was read
+ const signed char CEN = 8; // EN was read
+ const signed char CN = 9; // N was read
+ const signed char Done = 10;
+
+ const signed char InpLt = 0; // <
+ const signed char InpQm = 1; // ?
+ const signed char InpEm = 2; // !
+ const signed char InpDash = 3; // -
+ const signed char InpA = 4; // A
+ const signed char InpE = 5; // E
+ const signed char InpL = 6; // L
+ const signed char InpN = 7; // N
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static signed char table[4][9] = {
+ /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
+ { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
+ { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
+ { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Lt:
+ next();
+ break;
+ case Em:
+ next();
+ break;
+ case CE:
+ next();
+ break;
+ case Qm:
+ parseOk = parsePI();
+ break;
+ case Dash:
+ parseOk = parseComment();
+ break;
+ case CA:
+ parseOk = parseAttlistDecl();
+ break;
+ case CEL:
+ parseOk = parseElementDecl();
+ break;
+ case CEN:
+ parseOk = parseEntityDecl();
+ break;
+ case CN:
+ parseOk = parseNotationDecl();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Qm:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case Dash:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case CA:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTLISTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEL:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNOTATIONDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a PEReference [69]
+*/
+bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context )
+{
+ const signed char Init = 0;
+ const signed char Next = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpSemi = 0; // ;
+ const signed char InpPer = 1; // %
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][3] = {
+ /* InpSemi InpPer InpUnknown */
+ { -1, Next, -1 }, // Init
+ { -1, -1, Name }, // Next
+ { Done, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == ';' ) {
+ input = InpSemi;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Next:
+ next();
+ break;
+ case Name:
+ parseOk = parseName( TRUE );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) {
+ // ### skip it???
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else {
+ if ( context == InEntityValue ) {
+ // Included in literal
+ xmlRef = d->parameterEntities.find( ref() )
+ .data().replace( QRegExp("\""), """ ).replace( QRegExp("'"), "'" )
+ + xmlRef;
+ } else if ( context == InDTD ) {
+ // Included as PE
+ xmlRef = QString(" ") +
+ d->parameterEntities.find( ref() ).data() +
+ QString(" ") + xmlRef;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttlistDecl [52].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'A' of '<!ATTLIST'
+*/
+bool QXmlSimpleReader::parseAttlistDecl()
+{
+ const signed char Init = 0;
+ const signed char Attlist = 1; // parse the string "ATTLIST"
+ const signed char Ws = 2; // whitespace read
+ const signed char Name = 3; // parse name
+ const signed char Ws1 = 4; // whitespace read
+ const signed char Attdef = 5; // parse the AttDef
+ const signed char Ws2 = 6; // whitespace read
+ const signed char Atttype = 7; // parse the AttType
+ const signed char Ws3 = 8; // whitespace read
+ const signed char DDecH = 9; // DefaultDecl with #
+ const signed char DefReq = 10; // parse the string "REQUIRED"
+ const signed char DefImp = 11; // parse the string "IMPLIED"
+ const signed char DefFix = 12; // parse the string "FIXED"
+ const signed char Attval = 13; // parse the AttValue
+ const signed char Ws4 = 14; // whitespace read
+ const signed char Done = 15;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpGt = 1; // >
+ const signed char InpHash = 2; // #
+ const signed char InpA = 3; // A
+ const signed char InpI = 4; // I
+ const signed char InpF = 5; // F
+ const signed char InpR = 6; // R
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static signed char table[15][8] = {
+ /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
+ { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
+ { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
+ { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
+ { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
+ { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
+ { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
+ { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'F' ) {
+ input = InpF;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Attlist:
+ parseOk = parseString( "ATTLIST" );
+ break;
+ case Ws:
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Attdef:
+ parseOk = parseName();
+ break;
+ case Atttype:
+ parseOk = parseAttType();
+ break;
+ case DDecH:
+ next();
+ break;
+ case DefReq:
+ parseOk = parseString( "REQUIRED" );
+ break;
+ case DefImp:
+ parseOk = parseString( "IMPLIED" );
+ break;
+ case DefFix:
+ parseOk = parseString( "FIXED" );
+ break;
+ case Attval:
+ parseOk = parseAttValue();
+ break;
+ case Ws4:
+ if ( declHnd ) {
+ // TODO: not all values are computed yet...
+ if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Attlist:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclEName = name();
+ break;
+ case Attdef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclAName = name();
+ break;
+ case Atttype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTTYPE;
+ goto parseError;
+ }
+ break;
+ case DefReq:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefImp:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefFix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Attval:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttType [54]
+*/
+bool QXmlSimpleReader::parseAttType()
+{
+ const signed char Init = 0;
+ const signed char ST = 1; // StringType
+ const signed char TTI = 2; // TokenizedType starting with 'I'
+ const signed char TTI2 = 3; // TokenizedType helpstate
+ const signed char TTI3 = 4; // TokenizedType helpstate
+ const signed char TTE = 5; // TokenizedType starting with 'E'
+ const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
+ const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
+ const signed char N = 8; // N read (TokenizedType or Notation)
+ const signed char TTNM = 9; // TokenizedType starting with 'NM'
+ const signed char TTNM2 = 10; // TokenizedType helpstate
+ const signed char NO = 11; // Notation
+ const signed char NO2 = 12; // Notation helpstate
+ const signed char NO3 = 13; // Notation helpstate
+ const signed char NOName = 14; // Notation, read name
+ const signed char NO4 = 15; // Notation helpstate
+ const signed char EN = 16; // Enumeration
+ const signed char ENNmt = 17; // Enumeration, read Nmtoken
+ const signed char EN2 = 18; // Enumeration helpstate
+ const signed char ADone = 19; // almost done (make next and accept)
+ const signed char Done = 20;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpPipe = 3; // |
+ const signed char InpC = 4; // C
+ const signed char InpE = 5; // E
+ const signed char InpI = 6; // I
+ const signed char InpM = 7; // M
+ const signed char InpN = 8; // N
+ const signed char InpO = 9; // O
+ const signed char InpR = 10; // R
+ const signed char InpS = 11; // S
+ const signed char InpY = 12; // Y
+ const signed char InpUnknown = 13;
+
+ // use some kind of state machine for parsing
+ static signed char table[19][14] = {
+ /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
+ { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
+ { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
+ { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
+ { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
+ { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
+ { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
+ { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
+ { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
+ { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
+ { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
+ { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == 'C' ) {
+ input = InpC;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'M' ) {
+ input = InpM;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else if ( c == 'O' ) {
+ input = InpO;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'Y' ) {
+ input = InpY;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case ST:
+ parseOk = parseString( "CDATA" );
+ break;
+ case TTI:
+ parseOk = parseString( "ID" );
+ break;
+ case TTI2:
+ parseOk = parseString( "REF" );
+ break;
+ case TTI3:
+ next(); // S
+ break;
+ case TTE:
+ parseOk = parseString( "ENTIT" );
+ break;
+ case TTEY:
+ next(); // Y
+ break;
+ case TTEI:
+ parseOk = parseString( "IES" );
+ break;
+ case N:
+ next(); // N
+ break;
+ case TTNM:
+ parseOk = parseString( "MTOKEN" );
+ break;
+ case TTNM2:
+ next(); // S
+ break;
+ case NO:
+ parseOk = parseString( "OTATION" );
+ break;
+ case NO2:
+ eat_ws();
+ break;
+ case NO3:
+ next_eat_ws();
+ break;
+ case NOName:
+ parseOk = parseName();
+ break;
+ case NO4:
+ eat_ws();
+ break;
+ case EN:
+ next_eat_ws();
+ break;
+ case ENNmt:
+ parseOk = parseNmtoken();
+ break;
+ case EN2:
+ eat_ws();
+ break;
+ case ADone:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ST:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI2:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTE:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTEI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTNM:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NO:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NOName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ENNmt:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNMTOKEN;
+ goto parseError;
+ }
+ break;
+ case ADone:
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttValue [10]
+
+ Precondition: the head stands on the beginning " or '
+
+ If this function was successful, the head stands on the first
+ character after the closing " or ' and the value of the attribute
+ is in string().
+*/
+bool QXmlSimpleReader::parseAttValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // double quotes were read
+ const signed char DqRef = 2; // read references in double quotes
+ const signed char DqC = 3; // signed character read in double quotes
+ const signed char Sq = 4; // single quotes were read
+ const signed char SqRef = 5; // read references in single quotes
+ const signed char SqC = 6; // signed character read in single quotes
+ const signed char Done = 7;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpLt = 3; // <
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][5] = {
+ /* InpDq InpSq InpAmp InpLt InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, -1, DqC }, // Dq
+ { Done, DqC, DqRef, -1, DqC }, // DqRef
+ { Done, DqC, DqRef, -1, DqC }, // DqC
+ { SqC, Done, SqRef, -1, SqC }, // Sq
+ { SqC, Done, SqRef, -1, SqC }, // SqRef
+ { SqC, Done, SqRef, -1, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InAttributeValue );
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a elementdecl [45].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stands on the 'L' of '<!ELEMENT'
+*/
+bool QXmlSimpleReader::parseElementDecl()
+{
+ const signed char Init = 0;
+ const signed char Elem = 1; // parse the beginning string
+ const signed char Ws1 = 2; // whitespace required
+ const signed char Nam = 3; // parse Name
+ const signed char Ws2 = 4; // whitespace required
+ const signed char Empty = 5; // read EMPTY
+ const signed char Any = 6; // read ANY
+ const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
+ const signed char Mix = 8; // read Mixed
+ const signed char Mix2 = 9; //
+ const signed char Mix3 = 10; //
+ const signed char MixN1 = 11; //
+ const signed char MixN2 = 12; //
+ const signed char MixN3 = 13; //
+ const signed char MixN4 = 14; //
+ const signed char Cp = 15; // parse cp
+ const signed char Cp2 = 16; //
+ const signed char WsD = 17; // eat whitespace before Done
+ const signed char Done = 18;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpPipe = 2; // |
+ const signed char InpOp = 3; // (
+ const signed char InpCp = 4; // )
+ const signed char InpHash = 5; // #
+ const signed char InpQm = 6; // ?
+ const signed char InpAst = 7; // *
+ const signed char InpPlus = 8; // +
+ const signed char InpA = 9; // A
+ const signed char InpE = 10; // E
+ const signed char InpL = 11; // L
+ const signed char InpUnknown = 12;
+
+ // use some kind of state machine for parsing
+ static signed char table[18][13] = {
+ /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
+ { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
+ { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
+ { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
+ { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
+ { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
+ { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
+ { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
+ { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
+ { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
+ { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case Elem:
+ parseOk = parseString( "LEMENT" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case Empty:
+ parseOk = parseString( "EMPTY" );
+ break;
+ case Any:
+ parseOk = parseString( "ANY" );
+ break;
+ case Cont:
+ next_eat_ws();
+ break;
+ case Mix:
+ parseOk = parseString( "#PCDATA" );
+ break;
+ case Mix2:
+ eat_ws();
+ break;
+ case Mix3:
+ next();
+ break;
+ case MixN1:
+ next_eat_ws();
+ break;
+ case MixN2:
+ parseOk = parseName();
+ break;
+ case MixN3:
+ eat_ws();
+ break;
+ case MixN4:
+ next();
+ break;
+ case Cp:
+ parseOk = parseChoiceSeq();
+ break;
+ case Cp2:
+ next();
+ break;
+ case WsD:
+ next_eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Elem:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Empty:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Any:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Mix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case MixN2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Cp:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a NotationDecl [82].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'N' of '<!NOTATION'
+*/
+bool QXmlSimpleReader::parseNotationDecl()
+{
+ const signed char Init = 0;
+ const signed char Not = 1; // read NOTATION
+ const signed char Ws1 = 2; // eat whitespaces
+ const signed char Nam = 3; // read Name
+ const signed char Ws2 = 4; // eat whitespaces
+ const signed char ExtID = 5; // parse ExternalID
+ const signed char Ws3 = 6; // eat whitespaces
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpN = 2; // N
+ const signed char InpUnknown = 3;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][4] = {
+ /* InpWs InpGt InpN InpUnknown */
+ { -1, -1, Not, -1 }, // Init
+ { Ws1, -1, -1, -1 }, // Not
+ { -1, -1, Nam, Nam }, // Ws1
+ { Ws2, Done, -1, -1 }, // Nam
+ { -1, Done, ExtID, ExtID }, // Ws2
+ { Ws3, Done, -1, -1 }, // ExtID
+ { -1, Done, -1, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Not:
+ parseOk = parseString( "NOTATION" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case ExtID:
+ parseOk = parseExternalID( TRUE );
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Not:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ // call the handler
+ if ( dtdHnd ) {
+ if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = dtdHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse choice [49] or seq [50].
+
+ Precondition: the beginning '('S? is already read and the head
+ stands on the first non-whitespace character after it.
+*/
+bool QXmlSimpleReader::parseChoiceSeq()
+{
+ const signed char Init = 0;
+ const signed char Ws1 = 1; // eat whitespace
+ const signed char CS_ = 2; // choice or set
+ const signed char Ws2 = 3; // eat whitespace
+ const signed char More = 4; // more cp to read
+ const signed char Name = 5; // read name
+ const signed char Done = 6; //
+
+ const signed char InpWs = 0; // S
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpQm = 3; // ?
+ const signed char InpAst = 4; // *
+ const signed char InpPlus = 5; // +
+ const signed char InpPipe = 6; // |
+ const signed char InpComm = 7; // ,
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static signed char table[6][9] = {
+ /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
+ { -1, CS_, -1, -1, -1, -1, -1, -1, CS_ }, // Ws1
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS_
+ { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS_)
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == ',' ) {
+ input = InpComm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ws1:
+ next_eat_ws();
+ break;
+ case CS_:
+ parseOk = parseChoiceSeq();
+ break;
+ case Ws2:
+ next_eat_ws();
+ break;
+ case More:
+ next_eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case CS_:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityDecl [70].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stand on the 'N' of '<!ENTITY'
+*/
+bool QXmlSimpleReader::parseEntityDecl()
+{
+ const signed char Init = 0;
+ const signed char Ent = 1; // parse "ENTITY"
+ const signed char Ws1 = 2; // white space read
+ const signed char Name = 3; // parse name
+ const signed char Ws2 = 4; // white space read
+ const signed char EValue = 5; // parse entity value
+ const signed char ExtID = 6; // parse ExternalID
+ const signed char Ws3 = 7; // white space read
+ const signed char Ndata = 8; // parse "NDATA"
+ const signed char Ws4 = 9; // white space read
+ const signed char NNam = 10; // parse name
+ const signed char PEDec = 11; // parse PEDecl
+ const signed char Ws6 = 12; // white space read
+ const signed char PENam = 13; // parse name
+ const signed char Ws7 = 14; // white space read
+ const signed char PEVal = 15; // parse entity value
+ const signed char PEEID = 16; // parse ExternalID
+ const signed char WsE = 17; // white space read
+ const signed char EDDone = 19; // done, but also report an external, unparsed entity decl
+ const signed char Done = 18;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpPer = 1; // %
+ const signed char InpQuot = 2; // " or '
+ const signed char InpGt = 3; // >
+ const signed char InpN = 4; // N
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static signed char table[18][6] = {
+ /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
+ { -1, -1, -1, -1, Ent, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1 }, // Ent
+ { -1, PEDec, -1, -1, Name, Name }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1 }, // Name
+ { -1, -1, EValue, -1, -1, ExtID }, // Ws2
+ { WsE, -1, -1, Done, -1, -1 }, // EValue
+ { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
+ { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
+ { Ws4, -1, -1, -1, -1, -1 }, // Ndata
+ { -1, -1, -1, -1, NNam, NNam }, // Ws4
+ { WsE, -1, -1, Done, -1, -1 }, // NNam
+ { Ws6, -1, -1, -1, -1, -1 }, // PEDec
+ { -1, -1, -1, -1, PENam, PENam }, // Ws6
+ { Ws7, -1, -1, -1, -1, -1 }, // PENam
+ { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
+ { WsE, -1, -1, Done, -1, -1 }, // PEVal
+ { WsE, -1, -1, Done, -1, -1 }, // PEEID
+ { -1, -1, -1, Done, -1, -1 } // WsE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '"' || c == '\'' ) {
+ input = InpQuot;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ent:
+ parseOk = parseString( "NTITY" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case EValue:
+ parseOk = parseEntityValue();
+ break;
+ case ExtID:
+ parseOk = parseExternalID();
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Ndata:
+ parseOk = parseString( "NDATA" );
+ break;
+ case Ws4:
+ eat_ws();
+ break;
+ case NNam:
+ parseOk = parseName( TRUE );
+ break;
+ case PEDec:
+ next();
+ break;
+ case Ws6:
+ eat_ws();
+ break;
+ case PENam:
+ parseOk = parseName();
+ break;
+ case Ws7:
+ eat_ws();
+ break;
+ case PEVal:
+ parseOk = parseEntityValue();
+ break;
+ case PEEID:
+ parseOk = parseExternalID();
+ break;
+ case WsE:
+ eat_ws();
+ break;
+ case EDDone:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ent:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case EValue:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->entities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ break;
+ case Ndata:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NNam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
+ if ( dtdHnd ) {
+ if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PENam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case PEVal:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->parameterEntities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PEEID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case EDDone:
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityValue [9]
+*/
+bool QXmlSimpleReader::parseEntityValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // EntityValue is double quoted
+ const signed char DqC = 2; // signed character
+ const signed char DqPER = 3; // PERefence
+ const signed char DqRef = 4; // Reference
+ const signed char Sq = 5; // EntityValue is double quoted
+ const signed char SqC = 6; // signed character
+ const signed char SqPER = 7; // PERefence
+ const signed char SqRef = 8; // Reference
+ const signed char Done = 9;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpPer = 3; // %
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[9][5] = {
+ /* InpDq InpSq InpAmp InpPer InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, DqPER, DqC }, // Dq
+ { Done, DqC, DqRef, DqPER, DqC }, // DqC
+ { Done, DqC, DqRef, DqPER, DqC }, // DqPER
+ { Done, DqC, DqRef, DqPER, DqC }, // DqRef
+ { SqC, Done, SqRef, SqPER, SqC }, // Sq
+ { SqC, Done, SqRef, SqPER, SqC }, // SqC
+ { SqC, Done, SqRef, SqPER, SqC }, // SqPER
+ { SqC, Done, SqRef, SqPER, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case DqPER:
+ case SqPER:
+ parseOk = parsePEReference( InEntityValue );
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InEntityValue );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqPER:
+ case SqPER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a comment [15].
+
+ Precondition: the beginning '<!' of the comment is already read and the head
+ stands on the first '-' of '<!--'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the comment.
+*/
+bool QXmlSimpleReader::parseComment()
+{
+ const signed char Init = 0;
+ const signed char Dash1 = 1; // the first dash was read
+ const signed char Dash2 = 2; // the second dash was read
+ const signed char Com = 3; // read comment
+ const signed char Com2 = 4; // read comment (help state)
+ const signed char ComE = 5; // finished reading comment
+ const signed char Done = 6;
+
+ const signed char InpDash = 0; // -
+ const signed char InpGt = 1; // >
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[6][3] = {
+ /* InpDash InpGt InpUnknown */
+ { Dash1, -1, -1 }, // Init
+ { Dash2, -1, -1 }, // Dash1
+ { Com2, Com, Com }, // Dash2
+ { Com2, Com, Com }, // Com
+ { ComE, Com, Com }, // Com2
+ { -1, Done, -1 } // ComE
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dash1:
+ next();
+ break;
+ case Dash2:
+ next();
+ break;
+ case Com:
+ stringAddC();
+ next();
+ break;
+ case Com2:
+ next();
+ break;
+ case ComE:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Dash2:
+ stringClear();
+ break;
+ case Com2:
+ // if next character is not a dash than don't skip it
+ if ( c != '-' ) {
+ stringAddC( '-' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Attribute [41].
+
+ Precondition: the head stands on the first character of the name of the
+ attribute (i.e. all whitespaces are already parsed).
+
+ The head stand on the next character after the end quotes. The variable name
+ contains the name of the attribute and the variable string contains the value
+ of the attribute.
+*/
+bool QXmlSimpleReader::parseAttribute()
+{
+ const signed char Init = 0;
+ const signed char PName = 1; // parse name
+ const signed char Ws = 2; // eat ws
+ const signed char Eq = 3; // the '=' was read
+ const signed char Quotes = 4; // " or ' were read
+
+ const signed char InpNameBe = 0;
+ const signed char InpEq = 1; // =
+ const signed char InpDq = 2; // "
+ const signed char InpSq = 3; // '
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[4][5] = {
+ /* InpNameBe InpEq InpDq InpSq InpUnknown */
+ { PName, -1, -1, -1, -1 }, // Init
+ { -1, Eq, -1, -1, Ws }, // PName
+ { -1, Eq, -1, -1, -1 }, // Ws
+ { -1, -1, Quotes, Quotes, -1 } // Eq
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '=' ) {
+ input = InpEq;
+ } else if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case PName:
+ parseOk = parseName();
+ break;
+ case Ws:
+ eat_ws();
+ break;
+ case Eq:
+ next_eat_ws();
+ break;
+ case Quotes:
+ parseOk = parseAttValue();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case PName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Quotes:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
+*/
+bool QXmlSimpleReader::parseName( bool useRef )
+{
+ const signed char Init = 0;
+ const signed char Name1 = 1; // parse first signed character of the name
+ const signed char Name = 2; // parse name
+ const signed char Done = 3;
+
+ const signed char InpNameBe = 0; // name beginning signed characters
+ const signed char InpNameCh = 1; // NameChar without InpNameBe
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][3] = {
+ /* InpNameBe InpNameCh InpUnknown */
+ { Name1, -1, -1 }, // Init
+ { Name, Name, Done }, // Name1
+ { Name, Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Name1:
+ if ( useRef ) {
+ refClear();
+ refAddC();
+ } else {
+ nameClear();
+ nameAddC();
+ }
+ next();
+ break;
+ case Name:
+ if ( useRef ) {
+ refAddC();
+ } else {
+ nameAddC();
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Nmtoken [7] and store the name in name.
+*/
+bool QXmlSimpleReader::parseNmtoken()
+{
+ const signed char Init = 0;
+ const signed char NameF = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpNameCh = 0; // NameChar without InpNameBe
+ const signed char InpUnknown = 1;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][2] = {
+ /* InpNameCh InpUnknown */
+ { NameF, -1 }, // Init
+ { Name, Done }, // NameF
+ { Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case NameF:
+ nameClear();
+ nameAddC();
+ next();
+ break;
+ case Name:
+ nameAddC();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Reference [67].
+
+ charDataRead is set to TRUE if the reference must not be parsed. The
+ character(s) which the reference mapped to are appended to string. The
+ head stands on the first character after the reference.
+
+ charDataRead is set to FALSE if the reference must be parsed. The
+ charachter(s) which the reference mapped to are inserted at the reference
+ position. The head stands on the first character of the replacement).
+*/
+bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ // temporary variables
+ uint tmp;
+ bool ok;
+
+ const signed char Init = 0;
+ const signed char SRef = 1; // start of a reference
+ const signed char ChRef = 2; // parse CharRef
+ const signed char ChDec = 3; // parse CharRef decimal
+ const signed char ChHexS = 4; // start CharRef hexadecimal
+ const signed char ChHex = 5; // parse CharRef hexadecimal
+ const signed char Name = 6; // parse name
+ const signed char DoneD = 7; // done CharRef decimal
+ const signed char DoneH = 8; // done CharRef hexadecimal
+ const signed char DoneN = 9; // done EntityRef
+
+ const signed char InpAmp = 0; // &
+ const signed char InpSemi = 1; // ;
+ const signed char InpHash = 2; // #
+ const signed char InpX = 3; // x
+ const signed char InpNum = 4; // 0-9
+ const signed char InpHex = 5; // a-f A-F
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static signed char table[8][7] = {
+ /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
+ { SRef, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
+ { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
+ { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
+ { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
+ { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
+ { -1, DoneN, -1, -1, -1, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else if ( c.cell() == '&' ) {
+ input = InpAmp;
+ } else if ( c.cell() == ';' ) {
+ input = InpSemi;
+ } else if ( c.cell() == '#' ) {
+ input = InpHash;
+ } else if ( c.cell() == 'x' ) {
+ input = InpX;
+ } else if ( '0' <= c.cell() && c.cell() <= '9' ) {
+ input = InpNum;
+ } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
+ input = InpHex;
+ } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
+ input = InpHex;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case SRef:
+ refClear();
+ next();
+ break;
+ case ChRef:
+ next();
+ break;
+ case ChDec:
+ refAddC();
+ next();
+ break;
+ case ChHexS:
+ next();
+ break;
+ case ChHex:
+ refAddC();
+ next();
+ break;
+ case Name:
+ // read the name into the ref
+ parseName( TRUE );
+ break;
+ case DoneD:
+ tmp = ref().toUInt( &ok, 10 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneH:
+ tmp = ref().toUInt( &ok, 16 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneN:
+ if ( !processReference( charDataRead, context ) )
+ goto parseError;
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DoneD:
+ return TRUE;
+ case DoneH:
+ return TRUE;
+ case DoneN:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Helper function for parseReference()
+*/
+bool QXmlSimpleReader::processReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ QString reference = ref();
+ if ( reference == "amp" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '&' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "lt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '<' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "gt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '>' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "apos" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '\'' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "quot" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '"' );
+ }
+ charDataRead = TRUE;
+ } else {
+ QMap<QString,QString>::Iterator it;
+ it = d->entities.find( reference );
+ if ( it != d->entities.end() ) {
+ // "Internal General"
+ switch ( context ) {
+ case InContent:
+ // Included
+ xmlRef = it.data() + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Included in literal
+ xmlRef = it.data().replace( QRegExp("\""), """ ).replace( QRegExp("'"), "'" )
+ + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_INTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ itExtern = d->externEntities.find( reference );
+ if ( itExtern == d->externEntities.end() ) {
+ // entity not declared
+ // ### check this case for conformance
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ } else {
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ }
+ } else if ( (*itExtern).notation.isNull() ) {
+ // "External Parsed General"
+ switch ( context ) {
+ case InContent:
+ // Included if validating
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINAV;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ // "Unparsed"
+ // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
+ // Forbidden
+ d->error = XMLERR_UNPARSEDENTITYREFERENCE;
+ charDataRead = FALSE;
+ return FALSE; // error
+ }
+ }
+ }
+ return TRUE; // no error
+}
+
+
+/*!
+ Parse over a simple string.
+
+ After the string was successfully parsed, the head is on the first
+ character after the string.
+*/
+bool QXmlSimpleReader::parseString( const QString& s )
+{
+ signed char Done = s.length();
+
+ const signed char InpCharExpected = 0; // the character that was expected
+ const signed char InpUnknown = 1;
+
+ signed char state = 0; // state in this function is the position in the string s
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == s[(int)state] ) {
+ input = InpCharExpected;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ if ( input == InpCharExpected ) {
+ state++;
+ } else {
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ // do some actions according to state
+ next();
+ // no input is read after this
+ if ( state == Done ) {
+ return TRUE;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+
+/*!
+ Inits the data values.
+*/
+void QXmlSimpleReader::init( const QXmlInputSource& i )
+{
+ xml = i.data();
+ xmlLength = xml.length();
+ xmlRef = "";
+
+ d->externParameterEntities.clear();
+ d->parameterEntities.clear();
+ d->externEntities.clear();
+ d->entities.clear();
+
+ tags.clear();
+
+ d->doctype = "";
+ d->xmlVersion = "";
+ d->encoding = "";
+ d->standalone = QXmlSimpleReaderPrivate::Unknown;
+
+ lineNr = 0;
+ columnNr = -1;
+ pos = 0;
+ next();
+ d->error = XMLERR_OK;
+}
+
+/*!
+ Returns TRUE if a entity with the name \a e exists,
+ otherwise returns FALSE.
+*/
+bool QXmlSimpleReader::entityExist( const QString& e ) const
+{
+ if ( d->parameterEntities.find(e) == d->parameterEntities.end() &&
+ d->externParameterEntities.find(e) == d->externParameterEntities.end() ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+void QXmlSimpleReader::reportParseError()
+{
+ if ( errorHnd )
+ errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
+}
+
+#endif //QT_NO_XML
diff --git a/qtools/qxml.h b/qtools/qxml.h
new file mode 100644
index 0000000..b44e42c
--- /dev/null
+++ b/qtools/qxml.h
@@ -0,0 +1,671 @@
+/****************************************************************************
+**
+**
+** Definition of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales at trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info at trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QXML_H
+#define QXML_H
+
+#include <qmodules.h>
+
+#if !defined(QT_MODULE_XML)
+#define QM_EXPORT
+#else
+#define QM_EXPORT Q_EXPORT
+#endif
+
+#ifndef QT_H
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluestack.h>
+#include <qmap.h>
+#endif // QT_H
+
+#ifndef QT_NO_XML
+
+class QXmlNamespaceSupport;
+class QXmlAttributes;
+class QXmlContentHandler;
+class QXmlDefaultHandler;
+class QXmlDTDHandler;
+class QXmlEntityResolver;
+class QXmlErrorHandler;
+class QXmlLexicalHandler;
+class QXmlDeclHandler;
+class QXmlInputSource;
+class QXmlLocator;
+class QXmlNamespaceSupport;
+class QXmlParseException;
+
+class QXmlReader;
+class QXmlSimpleReader;
+
+class QXmlSimpleReaderPrivate;
+class QXmlNamespaceSupportPrivate;
+class QXmlAttributesPrivate;
+class QXmlInputSourcePrivate;
+class QXmlParseExceptionPrivate;
+class QXmlLocatorPrivate;
+class QXmlDefaultHandlerPrivate;
+
+
+//
+// SAX Namespace Support
+//
+
+#if defined(Q_TEMPLATEDLL)
+// MOC_SKIP_BEGIN
+template class QM_EXPORT QMap<QString, QString>;
+template class QM_EXPORT QValueStack<QMap<QString, QString> >;
+template class QM_EXPORT QValueStack<QString>;
+// MOC_SKIP_END
+#endif
+
+class QM_EXPORT QXmlNamespaceSupport
+{
+public:
+ QXmlNamespaceSupport();
+ ~QXmlNamespaceSupport();
+
+ void setPrefix( const QString&, const QString& );
+
+ QString prefix( const QString& ) const;
+ QString uri( const QString& ) const;
+ void splitName( const QString&, QString&, QString& ) const;
+ void processName( const QString&, bool, QString&, QString& ) const;
+ QStringList prefixes() const;
+ QStringList prefixes( const QString& ) const;
+
+ void pushContext();
+ void popContext();
+ void reset();
+private:
+ QValueStack<QMap<QString, QString> > nsStack;
+ QMap<QString, QString> ns;
+
+ //QXmlNamespaceSupportPrivate *d;
+};
+
+
+//
+// SAX Attributes
+//
+
+class QM_EXPORT QXmlAttributes
+{
+public:
+ QXmlAttributes() {}
+ virtual ~QXmlAttributes() {}
+
+ int index( const QString& qName ) const;
+ int index( const QString& uri, const QString& localPart ) const;
+ int length() const;
+ QString localName( int index ) const;
+ QString qName( int index ) const;
+ QString uri( int index ) const;
+ QString type( int index ) const;
+ QString type( const QString& qName ) const;
+ QString type( const QString& uri, const QString& localName ) const;
+ QString value( int index ) const;
+ QString value( const QString& qName ) const;
+ QString value( const QString& uri, const QString& localName ) const;
+
+private:
+ QStringList qnameList;
+ QStringList uriList;
+ QStringList localnameList;
+ QStringList valueList;
+
+ //QXmlAttributesPrivate *d;
+
+ friend class QXmlSimpleReader;
+};
+
+//
+// SAX Input Source
+//
+
+class QM_EXPORT QXmlInputSource
+{
+public:
+ QXmlInputSource();
+ QXmlInputSource( QTextStream& stream );
+ QXmlInputSource( QFile& file );
+ virtual ~QXmlInputSource();
+
+ virtual const QString& data() const;
+ virtual void setData( const QString& d );
+
+private:
+ void readInput( QByteArray& rawData );
+
+ QString input;
+
+ //QXmlInputSourcePrivate *d;
+};
+
+//
+// SAX Exception Classes
+//
+
+class QM_EXPORT QXmlParseException
+{
+public:
+ QXmlParseException( const QString& name="", int c=-1, int l=-1, const QString& p="", const QString& s="" )
+ : msg( name ), column( c ), line( l ), pub( p ), sys( s )
+ { }
+
+ int columnNumber() const;
+ int lineNumber() const;
+ QString publicId() const;
+ QString systemId() const;
+ QString message() const;
+
+private:
+ QString msg;
+ int column;
+ int line;
+ QString pub;
+ QString sys;
+
+ //QXmlParseExceptionPrivate *d;
+};
+
+
+//
+// XML Reader
+//
+
+class QM_EXPORT QXmlReader
+{
+public:
+ virtual ~QXmlReader() {}
+ virtual bool feature( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setFeature( const QString& name, bool value ) = 0;
+ virtual bool hasFeature( const QString& name ) const = 0;
+ virtual void* property( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setProperty( const QString& name, void* value ) = 0;
+ virtual bool hasProperty( const QString& name ) const = 0;
+ virtual void setEntityResolver( QXmlEntityResolver* handler ) = 0;
+ virtual QXmlEntityResolver* entityResolver() const = 0;
+ virtual void setDTDHandler( QXmlDTDHandler* handler ) = 0;
+ virtual QXmlDTDHandler* DTDHandler() const = 0;
+ virtual void setContentHandler( QXmlContentHandler* handler ) = 0;
+ virtual QXmlContentHandler* contentHandler() const = 0;
+ virtual void setErrorHandler( QXmlErrorHandler* handler ) = 0;
+ virtual QXmlErrorHandler* errorHandler() const = 0;
+ virtual void setLexicalHandler( QXmlLexicalHandler* handler ) = 0;
+ virtual QXmlLexicalHandler* lexicalHandler() const = 0;
+ virtual void setDeclHandler( QXmlDeclHandler* handler ) = 0;
+ virtual QXmlDeclHandler* declHandler() const = 0;
+ virtual bool parse( const QXmlInputSource& input ) = 0;
+};
+
+class QM_EXPORT QXmlSimpleReader : public QXmlReader
+{
+public:
+ QXmlSimpleReader();
+ virtual ~QXmlSimpleReader();
+
+ bool feature( const QString& name, bool *ok = 0 ) const;
+ void setFeature( const QString& name, bool value );
+ bool hasFeature( const QString& name ) const;
+
+ void* property( const QString& name, bool *ok = 0 ) const;
+ void setProperty( const QString& name, void* value );
+ bool hasProperty( const QString& name ) const;
+
+ void setEntityResolver( QXmlEntityResolver* handler );
+ QXmlEntityResolver* entityResolver() const;
+ void setDTDHandler( QXmlDTDHandler* handler );
+ QXmlDTDHandler* DTDHandler() const;
+ void setContentHandler( QXmlContentHandler* handler );
+ QXmlContentHandler* contentHandler() const;
+ void setErrorHandler( QXmlErrorHandler* handler );
+ QXmlErrorHandler* errorHandler() const;
+ void setLexicalHandler( QXmlLexicalHandler* handler );
+ QXmlLexicalHandler* lexicalHandler() const;
+ void setDeclHandler( QXmlDeclHandler* handler );
+ QXmlDeclHandler* declHandler() const;
+
+ bool parse( const QXmlInputSource& input );
+
+private:
+ // variables
+ QXmlContentHandler* contentHnd;
+ QXmlErrorHandler* errorHnd;
+ QXmlDTDHandler* dtdHnd;
+ QXmlEntityResolver* entityRes;
+ QXmlLexicalHandler* lexicalHnd;
+ QXmlDeclHandler* declHnd;
+
+ QChar c; // the character at reading position
+ int lineNr; // number of line
+ int columnNr; // position in line
+ int pos; // position in string
+
+ int namePos;
+ QChar nameArray[256]; // only used for names
+ QString nameValue; // only used for names
+ int refPos;
+ QChar refArray[256]; // only used for references
+ QString refValue; // only used for references
+ int stringPos;
+ QChar stringArray[256]; // used for any other strings that are parsed
+ QString stringValue; // used for any other strings that are parsed
+
+ QString xml;
+ int xmlLength;
+ QString xmlRef; // used for parsing of entity references
+
+ QValueStack<QString> tags;
+
+ QXmlSimpleReaderPrivate* d;
+
+ static const QChar QEOF;
+
+ // inlines
+ virtual bool is_S( const QChar& );
+ virtual bool is_Letter( const QChar& );
+ virtual bool is_NameBeginning( const QChar& );
+ virtual bool is_Digit( const QChar& );
+ virtual bool is_CombiningChar( const QChar& );
+ virtual bool is_Extender( const QChar& );
+ virtual bool is_NameChar( const QChar& );
+
+ QString& string();
+ void stringClear();
+ void stringAddC();
+ void stringAddC(const QChar&);
+ QString& name();
+ void nameClear();
+ void nameAddC();
+ void nameAddC(const QChar&);
+ QString& ref();
+ void refClear();
+ void refAddC();
+ void refAddC(const QChar&);
+
+ // used by parseReference() and parsePEReference()
+ enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+
+ // private functions
+ void eat_ws();
+ void next_eat_ws();
+
+ void next();
+ bool atEnd();
+
+ void init( const QXmlInputSource& i );
+
+ bool entityExist( const QString& ) const;
+
+ bool parseProlog();
+ bool parseElement();
+ bool parseElementEmptyTag( bool &t, QString &uri, QString &lname );
+ bool parseElementETagBegin2( QString &uri, QString &lname );
+ bool parseElementAttribute( QString &prefix, QString &uri, QString &lname );
+ bool parseMisc();
+ bool parseContent();
+
+ bool parsePI(bool xmldecl=FALSE);
+ bool parseDoctype();
+ bool parseComment();
+
+ bool parseName( bool useRef=FALSE );
+ bool parseNmtoken();
+ bool parseAttribute();
+ bool parseReference( bool &charDataRead, EntityRecognitionContext context );
+ bool processReference( bool &charDataRead, EntityRecognitionContext context );
+
+ bool parseExternalID( bool allowPublicID = FALSE );
+ bool parsePEReference( EntityRecognitionContext context );
+ bool parseMarkupdecl();
+ bool parseAttlistDecl();
+ bool parseAttType();
+ bool parseAttValue();
+ bool parseElementDecl();
+ bool parseNotationDecl();
+ bool parseChoiceSeq();
+ bool parseEntityDecl();
+ bool parseEntityValue();
+
+ bool parseString( const QString& s );
+
+ void reportParseError();
+
+ friend class QXmlSimpleReaderPrivate;
+ friend class QXmlLocator;
+};
+
+//
+// SAX Locator
+//
+
+class QM_EXPORT QXmlLocator
+{
+public:
+ QXmlLocator( QXmlSimpleReader* parent )
+ { reader = parent; }
+ ~QXmlLocator()
+ { }
+
+ int columnNumber();
+ int lineNumber();
+// QString getPublicId()
+// QString getSystemId()
+
+private:
+ QXmlSimpleReader* reader;
+
+ //QXmlLocatorPrivate *d;
+};
+
+//
+// SAX handler classes
+//
+
+class QM_EXPORT QXmlContentHandler
+{
+public:
+ virtual ~QXmlContentHandler() {}
+ virtual void setDocumentLocator( QXmlLocator* locator ) = 0;
+ virtual bool startDocument() = 0;
+ virtual bool endDocument() = 0;
+ virtual bool startPrefixMapping( const QString& prefix, const QString& uri ) = 0;
+ virtual bool endPrefixMapping( const QString& prefix ) = 0;
+ virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) = 0;
+ virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) = 0;
+ virtual bool characters( const QString& ch ) = 0;
+ virtual bool ignorableWhitespace( const QString& ch ) = 0;
+ virtual bool processingInstruction( const QString& target, const QString& data ) = 0;
+ virtual bool skippedEntity( const QString& name ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlErrorHandler
+{
+public:
+ virtual ~QXmlErrorHandler() {}
+ virtual bool warning( const QXmlParseException& exception ) = 0;
+ virtual bool error( const QXmlParseException& exception ) = 0;
+ virtual bool fatalError( const QXmlParseException& exception ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDTDHandler
+{
+public:
+ virtual ~QXmlDTDHandler() {}
+ virtual bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlEntityResolver
+{
+public:
+ virtual ~QXmlEntityResolver() {}
+ virtual bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* &ret ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlLexicalHandler
+{
+public:
+ virtual ~QXmlLexicalHandler() {}
+ virtual bool startDTD( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool endDTD() = 0;
+// virtual bool startEntity( const QString& name ) = 0;
+// virtual bool endEntity( const QString& name ) = 0;
+ virtual bool startCDATA() = 0;
+ virtual bool endCDATA() = 0;
+ virtual bool comment( const QString& ch ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDeclHandler
+{
+public:
+ virtual ~QXmlDeclHandler() {}
+ virtual bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) = 0;
+ virtual bool internalEntityDecl( const QString& name, const QString& value ) = 0;
+ virtual bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual QString errorString() = 0;
+};
+
+
+class QM_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler
+{
+public:
+ QXmlDefaultHandler() { }
+ virtual ~QXmlDefaultHandler() { }
+
+ void setDocumentLocator( QXmlLocator* locator );
+ bool startDocument();
+ bool endDocument();
+ bool startPrefixMapping( const QString& prefix, const QString& uri );
+ bool endPrefixMapping( const QString& prefix );
+ bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+ bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+ bool characters( const QString& ch );
+ bool ignorableWhitespace( const QString& ch );
+ bool processingInstruction( const QString& target, const QString& data );
+ bool skippedEntity( const QString& name );
+
+ bool warning( const QXmlParseException& exception );
+ bool error( const QXmlParseException& exception );
+ bool fatalError( const QXmlParseException& exception );
+
+ bool notationDecl( const QString& name, const QString& publicId, const QString& systemId );
+ bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName );
+
+ bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* &ret );
+
+ bool startDTD( const QString& name, const QString& publicId, const QString& systemId );
+ bool endDTD();
+// bool startEntity( const QString& name );
+// bool endEntity( const QString& name );
+ bool startCDATA();
+ bool endCDATA();
+ bool comment( const QString& ch );
+
+ bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value );
+ bool internalEntityDecl( const QString& name, const QString& value );
+ bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId );
+
+ QString errorString();
+
+private:
+ //QXmlDefaultHandlerPrivate *d;
+};
+
+#ifdef _WS_QWS_
+#ifdef QT_XML_CPP
+#define inline
+#else
+#define QT_NO_XML_INLINE
+#endif
+#endif
+
+#ifndef QT_NO_XML_INLINE
+//
+// inlines
+//
+
+inline bool QXmlSimpleReader::is_S(const QChar& ch)
+{ return ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'; }
+
+inline bool QXmlSimpleReader::is_Letter( const QChar& ch )
+{ return ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_NameBeginning( const QChar& ch )
+{ return ch=='_' || ch==':' || ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_Digit( const QChar& ch )
+{ return ch.isDigit(); }
+
+inline bool QXmlSimpleReader::is_CombiningChar( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_Extender( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_NameChar( const QChar& ch )
+{
+ return ch=='.' || ch=='-' || ch=='_' || ch==':' ||
+ is_Letter(ch) || is_Digit(ch) ||
+ is_CombiningChar(ch) || is_Extender(ch);
+}
+
+inline void QXmlSimpleReader::next()
+{
+ if ( !xmlRef.isEmpty() ) {
+ c = xmlRef[0];
+ xmlRef.remove( 0, 1 );
+ } else {
+ if ( c=='\n' || c=='\r' ) {
+ lineNr++;
+ columnNr = -1;
+ }
+ if ( pos >= xmlLength ) {
+ c = QEOF;
+ } else {
+ c = xml[pos];
+ columnNr++;
+ pos++;
+ }
+ }
+}
+
+inline bool QXmlSimpleReader::atEnd()
+{ return c == QEOF; }
+
+inline void QXmlSimpleReader::eat_ws()
+{ while ( !atEnd() && is_S(c) ) next(); }
+
+inline void QXmlSimpleReader::next_eat_ws()
+{ next(); eat_ws(); }
+
+
+// use buffers instead of QString::operator+= when single characters are read
+inline QString& QXmlSimpleReader::string()
+{
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ return stringValue;
+}
+inline QString& QXmlSimpleReader::name()
+{
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ return nameValue;
+}
+inline QString& QXmlSimpleReader::ref()
+{
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ return refValue;
+}
+
+inline void QXmlSimpleReader::stringClear()
+{ stringValue = ""; stringPos = 0; }
+inline void QXmlSimpleReader::nameClear()
+{ nameValue = ""; namePos = 0; }
+inline void QXmlSimpleReader::refClear()
+{ refValue = ""; refPos = 0; }
+
+inline void QXmlSimpleReader::stringAddC()
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = c;
+}
+inline void QXmlSimpleReader::nameAddC()
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = c;
+}
+inline void QXmlSimpleReader::refAddC()
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = c;
+}
+
+inline void QXmlSimpleReader::stringAddC(const QChar& ch)
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = ch;
+}
+inline void QXmlSimpleReader::nameAddC(const QChar& ch)
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = ch;
+}
+inline void QXmlSimpleReader::refAddC(const QChar& ch)
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = ch;
+}
+#endif
+
+#ifdef _WS_QWS_
+#ifdef QT_XML_CPP
+#undef inline
+#endif
+#endif
+
+#endif //QT_NO_XML
+
+#endif
diff --git a/qtools/scstring.cpp b/qtools/scstring.cpp
new file mode 100644
index 0000000..26d3a52
--- /dev/null
+++ b/qtools/scstring.cpp
@@ -0,0 +1,798 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+// with this switch you can choose between the original qcstring implementation,
+// which implicitly shares data so copying is faster, but requires at least 12 bytes, and
+// the new implementation in this file, which has a smaller footprint (only 4 bytes for
+// an empty string), but always copies strings.
+#define SMALLSTRING
+
+#include "qcstring.h"
+#ifndef SMALLSTRING
+#include "qcstring.cpp"
+#else
+#define SCString QCString
+
+#include <qstring.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <qregexp.h>
+#include <qdatastream.h>
+
+
+SCString::SCString(int size)
+{
+ if (size>0)
+ {
+ m_data = (char *)malloc(size);
+ if (m_data)
+ {
+ if (size>1) memset(m_data,' ',size-1);
+ m_data[size-1]='\0';
+ }
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+SCString::SCString( const SCString &s )
+{
+ duplicate(s);
+}
+
+SCString::SCString( const char *str )
+{
+ duplicate(str);
+}
+
+SCString::SCString( const char *str, uint maxlen )
+{
+ uint l;
+ if (str && ( l = QMIN(qstrlen(str),maxlen) ))
+ {
+ m_data=(char *)malloc(l+1);
+ strncpy(m_data,str,l+1);
+ m_data[l]='\0';
+ }
+ else
+ {
+ m_data=0;
+ }
+}
+
+SCString::~SCString()
+{
+ if (m_data) free(m_data);
+ m_data=0;
+}
+
+SCString &SCString::assign( const char *str )
+{
+ if (m_data==str) return *this;
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
+}
+
+bool SCString::resize( uint newlen )
+{
+ if (newlen==0)
+ {
+ if (m_data) { free(m_data); m_data=0; }
+ return TRUE;
+ }
+ if (m_data==0) // newlen>0
+ {
+ m_data = (char *)malloc(newlen);
+ }
+ else
+ {
+ m_data = (char *)realloc(m_data,newlen);
+ }
+ if (m_data==0) return FALSE;
+ m_data[newlen-1]='\0';
+ return TRUE;
+}
+
+bool SCString::fill( char c, int len )
+{
+ uint l=length();
+ if (len<0) len=l;
+ if ((uint)len!=l)
+ {
+ if (m_data) free(m_data);
+ if (len>0)
+ {
+ m_data=(char *)malloc(len+1);
+ if (m_data==0) return FALSE;
+ m_data[len]='\0';
+ }
+ else
+ {
+ m_data=0;
+ }
+ }
+ if (len>0)
+ {
+ uint i;
+ for (i=0;i<(uint)len;i++) m_data[i]=c;
+ }
+ return TRUE;
+}
+
+SCString &SCString::sprintf( const char *format, ... )
+{
+ va_list ap;
+ va_start( ap, format );
+ uint l = length();
+ const uint minlen=4095;
+ if (l<minlen)
+ {
+ if (m_data)
+ m_data = (char *)realloc(m_data,minlen+1);
+ else
+ m_data = (char *)malloc(minlen+1);
+ m_data[minlen]='\0';
+ }
+ vsnprintf( m_data, minlen, format, ap );
+ resize( qstrlen(m_data) + 1 ); // truncate
+ va_end( ap );
+ return *this;
+}
+
+
+int SCString::find( char c, int index, bool cs ) const
+{
+ uint len = length();
+ if ( m_data==0 || (uint)index>len ) // index outside string
+ return -1;
+ register const char *d;
+ if ( cs ) // case sensitive
+ {
+ d = strchr( m_data+index, c );
+ }
+ else
+ {
+ d = m_data+index;
+ c = tolower( (uchar) c );
+ while ( *d && tolower((uchar) *d) != c )
+ d++;
+ if ( !*d && c ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - m_data) : -1;
+}
+
+int SCString::find( const char *str, int index, bool cs ) const
+{
+ uint l = length();
+ if ( m_data==0 || (uint)index > l ) // index outside string
+ return -1;
+ if ( !str ) // no search string
+ return -1;
+ if ( !*str ) // zero-length search string
+ return index;
+ register const char *d;
+ if ( cs ) // case sensitive
+ {
+ d = strstr( m_data+index, str );
+ }
+ else // case insensitive
+ {
+ d = m_data+index;
+ int len = qstrlen( str );
+ while ( *d )
+ {
+ if ( qstrnicmp(d, str, len) == 0 )
+ break;
+ d++;
+ }
+ if ( !*d ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - m_data) : -1;
+}
+
+int SCString::find( const QCString &str, int index, bool cs ) const
+{
+ return find(str.data(),index,cs);
+}
+
+int SCString::find( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.find( rx, index );
+}
+
+int SCString::findRev( char c, int index, bool cs) const
+{
+ const char *b = m_data;
+ const char *d;
+ uint len = length();
+ if ( b == 0 ) return -1; // empty string
+ if ( index < 0 ) // neg index ==> start from end
+ {
+ if ( len == 0 ) return -1;
+ if ( cs )
+ {
+ d = strrchr( b, c );
+ return d ? (int)(d - b) : -1;
+ }
+ index = len;
+ }
+ else if ( (uint)index > len ) // bad index
+ {
+ return -1;
+ }
+ d = b+index;
+ if ( cs ) // case sensitive
+ {
+ while ( d >= b && *d != c )
+ d--;
+ }
+ else // case insensitive
+ {
+ c = tolower( (uchar) c );
+ while ( d >= b && tolower((uchar) *d) != c )
+ d--;
+ }
+ return d >= b ? (int)(d - b) : -1;
+}
+
+int SCString::findRev( const char *str, int index, bool cs) const
+{
+ int slen = qstrlen(str);
+ uint len = length();
+ if ( index < 0 ) // neg index ==> start from end
+ index = len-slen;
+ else if ( (uint)index > len ) // bad index
+ return -1;
+ else if ( (uint)(index + slen) > len ) // str would be too long
+ index = len - slen;
+ if ( index < 0 )
+ return -1;
+
+ register char *d = m_data + index;
+ if ( cs ) // case sensitive
+ {
+ for ( int i=index; i>=0; i-- )
+ if ( qstrncmp(d--,str,slen)==0 )
+ return i;
+ }
+ else // case insensitive
+ {
+ for ( int i=index; i>=0; i-- )
+ if ( qstrnicmp(d--,str,slen)==0 )
+ return i;
+ }
+ return -1;
+
+}
+
+int SCString::findRev( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.findRev( rx, index );
+}
+
+int SCString::contains( char c, bool cs ) const
+{
+ int count = 0;
+ char *d = m_data;
+ if ( !d )
+ return 0;
+ if ( cs ) // case sensitive
+ {
+ while ( *d )
+ if ( *d++ == c )
+ count++;
+ }
+ else // case insensitive
+ {
+ c = tolower( (uchar) c );
+ while ( *d ) {
+ if ( tolower((uchar) *d) == c )
+ count++;
+ d++;
+ }
+ }
+ return count;
+}
+
+int SCString::contains( const char *str, bool cs ) const
+{
+ int count = 0;
+ char *d = data();
+ if ( !d )
+ return 0;
+ int len = qstrlen( str );
+ while ( *d ) // counts overlapping strings
+ {
+ if ( cs )
+ {
+ if ( qstrncmp( d, str, len ) == 0 )
+ count++;
+ }
+ else
+ {
+ if ( qstrnicmp(d, str, len) == 0 )
+ count++;
+ }
+ d++;
+ }
+ return count;
+}
+
+int SCString::contains( const QRegExp &rx ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.contains( rx );
+}
+
+SCString SCString::left( uint len ) const
+{
+ if ( isEmpty() )
+ {
+ return SCString();
+ }
+ else if ( len >= length() )
+ {
+ return *this;
+ }
+ else
+ {
+ SCString s( len+1 );
+ strncpy( s.data(), m_data, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+SCString SCString::right( uint len ) const
+{
+ if ( isEmpty() )
+ {
+ return SCString();
+ }
+ else
+ {
+ uint l = length();
+ if ( len > l ) len = l;
+ char *p = m_data + (l - len);
+ return SCString( p );
+ }
+}
+
+SCString SCString::mid( uint index, uint len) const
+{
+ uint slen = length();
+ if ( len == 0xffffffff ) len = slen-index;
+ if ( isEmpty() || index >= slen )
+ {
+ return SCString();
+ }
+ else
+ {
+ register char *p = data()+index;
+ SCString s( len+1 );
+ strncpy( s.data(), p, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+SCString SCString::lower() const
+{
+ SCString s( m_data );
+ register char *p = s.data();
+ if ( p )
+ {
+ while ( *p )
+ {
+ *p = tolower((uchar) *p);
+ p++;
+ }
+ }
+ return s;
+}
+
+SCString SCString::upper() const
+{
+ SCString s( m_data );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = toupper((uchar)*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+SCString SCString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+
+ register char *s = m_data;
+ int reslen = length();
+ if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
+ return *this; // returns a copy
+
+ SCString result(s);
+ s = result.data();
+ int start = 0;
+ int end = reslen - 1;
+ while ( isspace((uchar) s[start]) ) // skip white space from start
+ start++;
+ if ( s[start] == '\0' )
+ { // only white space
+ return SCString();
+ }
+ while ( end && isspace((uchar) s[end]) ) // skip white space from end
+ end--;
+ end -= start - 1;
+ memmove( result.data(), &s[start], end );
+ result.resize( end + 1 );
+ return result;
+}
+
+SCString SCString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+
+ SCString result( length()+1 );
+ char *from = data();
+ char *to = result.data();
+ char *first = to;
+ while ( TRUE )
+ {
+ while ( *from && isspace((uchar) *from) )
+ from++;
+ while ( *from && !isspace((uchar)*from) )
+ *to++ = *from++;
+ if ( *from )
+ *to++ = 0x20; // ' '
+ else
+ break;
+ }
+ if ( to > first && *(to-1) == 0x20 )
+ to--;
+ *to = '\0';
+ result.resize( (int)((long)to - (long)result.data()) + 1 );
+ return result;
+}
+
+SCString &SCString::insert( uint index, const char *s )
+{
+ int len = qstrlen(s);
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+ if ( index >= olen ) // insert after end of string
+ {
+ m_data = (char *)realloc(m_data,nlen+index-olen+1);
+ if ( m_data )
+ {
+ memset( m_data+olen, ' ', index-olen );
+ memcpy( m_data+index, s, len+1 );
+ }
+ }
+ else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert
+ {
+ memmove( m_data+index+len, m_data+index, olen-index+1 );
+ memcpy( m_data+index, s, len );
+ }
+ return *this;
+}
+
+SCString &SCString::insert( uint index, char c ) // insert char
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ return insert( index, buf );
+}
+
+SCString& SCString::operator+=( const char *str )
+{
+ if ( !str ) return *this; // nothing to append
+ uint len1 = length();
+ uint len2 = qstrlen(str);
+ char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
+ if (newData)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, str, len2 + 1 );
+ }
+ return *this;
+}
+
+SCString &SCString::operator+=( char c )
+{
+ uint len = length();
+ char *newData = (char *)realloc( m_data, length()+2 );
+ if (newData)
+ {
+ m_data = newData;
+ m_data[len] = c;
+ m_data[len+1] = '\0';
+ }
+ return *this;
+}
+
+SCString &SCString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) // range problems
+ {
+ if ( index < olen ) // index ok
+ {
+ resize( index+1 );
+ }
+ }
+ else if ( len != 0 )
+ {
+ memmove( m_data+index, m_data+index+len, olen-index-len+1 );
+ resize( olen-len+1 );
+ }
+ return *this;
+}
+
+SCString &SCString::replace( uint index, uint len, const char *s )
+{
+ remove( index, len );
+ insert( index, s );
+ return *this;
+}
+
+SCString &SCString::replace( const QRegExp &rx, const char *str )
+{
+ QString d = QString::fromLatin1( m_data );
+ QString r = QString::fromLatin1( str );
+ d.replace( rx, r );
+ return assign(d.ascii());
+}
+
+long SCString::toLong( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toLong(ok);
+}
+
+ulong SCString::toULong( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toULong(ok);
+}
+
+short SCString::toShort( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toShort(ok);
+}
+
+ushort SCString::toUShort( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toUShort(ok);
+}
+
+int SCString::toInt( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toInt(ok);
+}
+
+uint SCString::toUInt( bool *ok ) const
+{
+ QString s(m_data);
+ return s.toUInt(ok);
+}
+
+SCString &SCString::setNum( long n )
+{
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if ( n < 0 )
+ {
+ neg = TRUE;
+ n = -n;
+ }
+ else
+ {
+ neg = FALSE;
+ }
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg ) *--p = '-';
+ operator=( p );
+ return *this;
+}
+
+SCString &SCString::setNum( ulong n )
+{
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ operator=( p );
+ return *this;
+}
+
+void SCString::msg_index( uint index )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "SCString::at: Absolute index %d out of range", index );
+#else
+ Q_UNUSED( index )
+#endif
+}
+
+bool SCString::stripPrefix(const char *prefix)
+{
+ if (prefix==0) return FALSE;
+ uint plen = qstrlen(prefix);
+ if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
+ {
+ uint len = qstrlen(m_data);
+ uint newlen = len-plen+1;
+ qmemmove(m_data,m_data+plen,newlen);
+ resize(newlen);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+void *qmemmove( void *dst, const void *src, uint len )
+{
+ register char *d;
+ register char *s;
+ if ( dst > src ) {
+ d = (char *)dst + len - 1;
+ s = (char *)src + len - 1;
+ while ( len-- )
+ *d-- = *s--;
+ } else if ( dst < src ) {
+ d = (char *)dst;
+ s = (char *)src;
+ while ( len-- )
+ *d++ = *s++;
+ }
+ return dst;
+}
+
+char *qstrdup( const char *str )
+{
+ if ( !str )
+ return 0;
+ char *dst = new char[strlen(str)+1];
+ CHECK_PTR( dst );
+ return strcpy( dst, str );
+}
+
+char *qstrncpy( char *dst, const char *src, uint len )
+{
+ if ( !src )
+ return 0;
+ strncpy( dst, src, len );
+ if ( len > 0 )
+ dst[len-1] = '\0';
+ return dst;
+}
+
+int qstricmp( const char *str1, const char *str2 )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
+ for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
+ if ( !c ) // strings are equal
+ break;
+ return res;
+}
+
+int qstrnicmp( const char *str1, const char *str2, uint len )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return (int)((long)s2 - (long)s1);
+ for ( ; len--; s1++, s2++ ) {
+ if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
+ return res;
+ if ( !c ) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+QDataStream &operator<<( QDataStream &s, const QByteArray &a )
+{
+ return s.writeBytes( a.data(), a.size() );
+}
+
+QDataStream &operator>>( QDataStream &s, QByteArray &a )
+{
+ Q_UINT32 len;
+ s >> len; // read size of array
+ if ( len == 0 || s.eof() ) { // end of file reached
+ a.resize( 0 );
+ return s;
+ }
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QByteArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( a.data(), (uint)len );
+ return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const SCString &str )
+{
+ return s.writeBytes( str.data(), str.size() );
+}
+
+QDataStream &operator>>( QDataStream &s, SCString &str )
+{
+ Q_UINT32 len;
+ s >> len; // read size of string
+ if ( len == 0 || s.eof() ) { // end of file reached
+ str.resize( 0 );
+ return s;
+ }
+ if ( !str.resize( (uint)len )) {// resize string
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QCString" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( str.data(), (uint)len );
+ return s;
+}
+
+#endif //QT_NO_DATASTREAM
+
+
+
+#endif
diff --git a/qtools/scstring.h b/qtools/scstring.h
new file mode 100644
index 0000000..a9b462c
--- /dev/null
+++ b/qtools/scstring.h
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCSTRING_H
+#define SCSTRING_H
+
+#include <stdlib.h>
+
+class QRegExp;
+
+/** This is an alternative implementation of QCString. It provides basically
+ * the same functions but uses less memory for administration. This class
+ * is just a wrapper around a plain C string requiring only 4 bytes "overhead".
+ * QCString features sharing of data and stores the string length, but
+ * requires 4 + 12 bytes for this (even for the empty string). As doxygen
+ * uses a LOT of string during a run it saves a lot of memory to use a
+ * more memory efficient implementation at the cost of relatively low
+ * runtime overhead.
+ */
+class SCString
+{
+public:
+ SCString() : m_data(0) {} // make null string
+ SCString( const SCString &s );
+ SCString( int size );
+ SCString( const char *str );
+ SCString( const char *str, uint maxlen );
+ ~SCString();
+
+ SCString &operator=( const SCString &s );// deep copy
+ SCString &operator=( const char *str ); // deep copy
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ uint size() const { return m_data ? length()+1 : 0; }
+ char * data() const { return m_data; }
+ bool resize( uint newlen );
+ bool truncate( uint pos );
+ bool fill( char c, int len = -1 );
+
+ SCString copy() const;
+
+ SCString &sprintf( const char *format, ... );
+
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const char *str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &, int index=0 ) const;
+ int find( const QCString &str, int index, bool cs ) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const char *str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &, int index=-1 ) const;
+ int contains( char c, bool cs=TRUE ) const;
+ int contains( const char *str, bool cs=TRUE ) const;
+ int contains( const QRegExp & ) const;
+ bool stripPrefix(const char *prefix);
+
+ SCString left( uint len ) const;
+ SCString right( uint len ) const;
+ SCString mid( uint index, uint len=0xffffffff) const;
+
+ SCString lower() const;
+ SCString upper() const;
+
+ SCString stripWhiteSpace() const;
+ SCString simplifyWhiteSpace() const;
+
+ SCString &assign( const char *str );
+ SCString &insert( uint index, const char * );
+ SCString &insert( uint index, char );
+ SCString &append( const char *s );
+ SCString &prepend( const char *s );
+ SCString &remove( uint index, uint len );
+ SCString &replace( uint index, uint len, const char * );
+ SCString &replace( const QRegExp &, const char * );
+
+ short toShort( bool *ok=0 ) const;
+ ushort toUShort( bool *ok=0 ) const;
+ int toInt( bool *ok=0 ) const;
+ uint toUInt( bool *ok=0 ) const;
+ long toLong( bool *ok=0 ) const;
+ ulong toULong( bool *ok=0 ) const;
+
+ SCString &setNum( short );
+ SCString &setNum( ushort );
+ SCString &setNum( int );
+ SCString &setNum( uint );
+ SCString &setNum( long );
+ SCString &setNum( ulong );
+ QCString &setNum( float, char f='g', int prec=6 );
+ QCString &setNum( double, char f='g', int prec=6 );
+
+ operator const char *() const;
+ SCString &operator+=( const char *str );
+ SCString &operator+=( char c );
+ char &at( uint index ) const;
+ char &operator[]( int i ) const { return at(i); }
+
+ private:
+ static void msg_index( uint );
+ void duplicate( const SCString &s );
+ void duplicate( const char *str);
+ SCString &duplicate( const char *str, int);
+
+ char * m_data;
+};
+
+inline char &SCString::at( uint index ) const
+{
+ return m_data[index];
+}
+
+inline void SCString::duplicate( const SCString &s )
+{
+ if (!s.isEmpty())
+ {
+ uint l = strlen(s.data());
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,s.data(),l+1);
+ }
+ else
+ m_data=0;
+}
+inline void SCString::duplicate( const char *str)
+{
+ if (str && str[0]!='\0')
+ {
+ uint l = strlen(str);
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,str,l+1);
+ }
+ else
+ m_data=0;
+}
+inline SCString &SCString::duplicate( const char *str, int)
+{
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
+}
+
+#endif
+
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..6b7b841
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,75 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+GENERATED_SRC = ../generated_src/doxygen
+
+all: Makefile.libdoxygen Makefile.libdoxycfg Makefile.doxygen Makefile
+ $(MAKE) -f Makefile.libdoxycfg $@
+ $(MAKE) -f Makefile.libdoxygen $@
+ $(MAKE) -f Makefile.doxygen $@
+
+Makefile.libdoxygen: libdoxygen.pro libdoxygen.t
+ $(ENV) $(PERL) "$(TMAKE)" libdoxygen.pro >Makefile.libdoxygen
+ echo 'HEADERS += ' `ls -1 translator_??.h` >>Makefile.libdoxygen
+
+Makefile.libdoxycfg: libdoxycfg.pro libdoxycfg.t
+ $(ENV) $(PERL) "$(TMAKE)" libdoxycfg.pro >Makefile.libdoxycfg
+
+Makefile.doxygen: doxygen.pro
+ $(ENV) $(PERL) "$(TMAKE)" doxygen.pro >Makefile.doxygen
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" libdoxygen.pro >Makefile.libdoxygen
+ $(ENV) $(PERL) "$(TMAKE)" libdoxycfg.pro >Makefile.libdoxycfg
+ $(ENV) $(PERL) "$(TMAKE)" doxygen.pro >Makefile.doxygen
+
+# clean objects
+clean: Makefile.libdoxygen Makefile.libdoxycfg Makefile.doxygen
+ $(MAKE) -f Makefile.libdoxygen clean
+ $(MAKE) -f Makefile.libdoxycfg clean
+ $(MAKE) -f Makefile.doxygen clean
+
+# also clean flex/bison generated files
+distclean: clean
+ -cd $(GENERATED_SRC) && $(RM) scanner.cpp code.cpp config.cpp pre.cpp constexp.cpp \
+ ce_parse.cpp ce_parse.h tag.cpp commentscan.cpp \
+ declinfo.cpp defargs.cpp commentcnv.cpp doctokenizer.cpp \
+ pycode.cpp pyscanner.cpp fortrancode.cpp fortranscanner.cpp \
+ vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp
+
+FORCE:
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..ffe7c16
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,53 @@
+
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+GENERATED_SRC = ../generated_src/doxygen
+
+all: Makefile.libdoxygen Makefile.libdoxycfg Makefile.doxygen Makefile
+ $(MAKE) -f Makefile.libdoxycfg $@
+ $(MAKE) -f Makefile.libdoxygen $@
+ $(MAKE) -f Makefile.doxygen $@
+
+Makefile.libdoxygen: libdoxygen.pro libdoxygen.t
+ $(ENV) $(PERL) "$(TMAKE)" libdoxygen.pro >Makefile.libdoxygen
+ echo 'HEADERS += ' `ls -1 translator_??.h` >>Makefile.libdoxygen
+
+Makefile.libdoxycfg: libdoxycfg.pro libdoxycfg.t
+ $(ENV) $(PERL) "$(TMAKE)" libdoxycfg.pro >Makefile.libdoxycfg
+
+Makefile.doxygen: doxygen.pro
+ $(ENV) $(PERL) "$(TMAKE)" doxygen.pro >Makefile.doxygen
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" libdoxygen.pro >Makefile.libdoxygen
+ $(ENV) $(PERL) "$(TMAKE)" libdoxycfg.pro >Makefile.libdoxycfg
+ $(ENV) $(PERL) "$(TMAKE)" doxygen.pro >Makefile.doxygen
+
+# clean objects
+clean: Makefile.libdoxygen Makefile.libdoxycfg Makefile.doxygen
+ $(MAKE) -f Makefile.libdoxygen clean
+ $(MAKE) -f Makefile.libdoxycfg clean
+ $(MAKE) -f Makefile.doxygen clean
+
+# also clean flex/bison generated files
+distclean: clean
+ -cd $(GENERATED_SRC) && $(RM) scanner.cpp code.cpp config.cpp pre.cpp constexp.cpp \
+ ce_parse.cpp ce_parse.h tag.cpp commentscan.cpp \
+ declinfo.cpp defargs.cpp commentcnv.cpp doctokenizer.cpp \
+ pycode.cpp pyscanner.cpp fortrancode.cpp fortranscanner.cpp \
+ vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp
+
+FORCE:
diff --git a/src/Makefile.libdoxycfg b/src/Makefile.libdoxycfg
new file mode 100644
index 0000000..da7416f
--- /dev/null
+++ b/src/Makefile.libdoxycfg
@@ -0,0 +1,137 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#############################################################################
+# Makefile for building ../lib/libdoxycfg.a
+# Generated by tmake at 10:48, 2014/08/21
+# Project: libdoxycfg
+# Template: libdoxycfg.t
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I../generated_src/doxygen -I. -I../qtools -I/opt/local/include
+AR = ar cq
+RANLIB = ranlib
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = config.h \
+ configoptions.h \
+ portable.h
+SOURCES = ../generated_src/doxygen/config.cpp \
+ ../generated_src/doxygen/configoptions.cpp \
+ portable.cpp \
+ portable_c.c
+OBJECTS = ../objects/doxygen/config.o \
+ ../objects/doxygen/configoptions.o \
+ ../objects/doxygen/portable.o \
+ ../objects/doxygen/portable_c.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../lib/libdoxycfg.a
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ ranlib $(TARGET)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake libdoxycfg.pro
+
+dist:
+ $(TAR) libdoxycfg.tar libdoxycfg.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) libdoxycfg.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../objects/doxygen/config.o: ../generated_src/doxygen/config.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/doxygen/config.o ../generated_src/doxygen/config.cpp
+
+../objects/doxygen/configoptions.o: ../generated_src/doxygen/configoptions.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/doxygen/configoptions.o ../generated_src/doxygen/configoptions.cpp
+
+../objects/doxygen/portable.o: portable.cpp \
+ portable.h \
+ debug.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/doxygen/portable.o portable.cpp
+
+../objects/doxygen/portable_c.o: portable_c.c
+ $(CC) -c $(CFLAGS) $(INCPATH) -o ../objects/doxygen/portable_c.o portable_c.c
+
+
+LEX = /usr/bin/flex
+YACC = /opt/local/bin/bison
+PYTHON = /opt/local/bin/python2
+
+
+####################
+
+../generated_src/doxygen/config.cpp: config.l \
+ config.h \
+ ftextstream.h \
+ version.h \
+ portable.h \
+ util.h \
+ types.h \
+ sortdict.h \
+ docparser.h \
+ docvisitor.h \
+ htmlattrib.h \
+ message.h \
+ configoptions.h
+ $(LEX) -PconfigYY -t config.l >../generated_src/doxygen/config.cpp
+
+../generated_src/doxygen/configoptions.cpp: config.xml configgen.py
+ $(PYTHON) configgen.py -cpp config.xml >../generated_src/doxygen/configoptions.cpp
+
diff --git a/src/arguments.cpp b/src/arguments.cpp
new file mode 100644
index 0000000..2acf855
--- /dev/null
+++ b/src/arguments.cpp
@@ -0,0 +1,96 @@
+#include "arguments.h"
+#include "marshal.h"
+#include <assert.h>
+
+/*! the argument list is documented if one of its
+ * arguments is documented
+ */
+bool ArgumentList::hasDocumentation() const
+{
+ bool hasDocs=FALSE;
+ ArgumentListIterator ali(*this);
+ Argument *a;
+ for (ali.toFirst();!hasDocs && (a=ali.current());++ali)
+ {
+ hasDocs = a->hasDocumentation();
+ }
+ return hasDocs;
+}
+
+ArgumentList *ArgumentList::deepCopy() const
+{
+ ArgumentList *argList = new ArgumentList;
+ argList->setAutoDelete(TRUE);
+
+ QListIterator<Argument> ali(*this);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ argList->append(new Argument(*a));
+ }
+ argList->constSpecifier = constSpecifier;
+ argList->volatileSpecifier = volatileSpecifier;
+ argList->pureSpecifier = pureSpecifier;
+ argList->trailingReturnType = trailingReturnType;
+
+ return argList;
+}
+
+ArgumentList *ArgumentList::unmarshal(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ ArgumentList *result = new ArgumentList;
+ assert(count<1000000);
+ //printf("unmarshalArgumentList: %d\n",count);
+ for (i=0;i<count;i++)
+ {
+ Argument *a = new Argument;
+ a->attrib = unmarshalQCString(s);
+ a->type = unmarshalQCString(s);
+ a->canType = unmarshalQCString(s);
+ a->name = unmarshalQCString(s);
+ a->array = unmarshalQCString(s);
+ a->defval = unmarshalQCString(s);
+ a->docs = unmarshalQCString(s);
+ result->append(a);
+ }
+ result->constSpecifier = unmarshalBool(s);
+ result->volatileSpecifier = unmarshalBool(s);
+ result->pureSpecifier = unmarshalBool(s);
+ result->trailingReturnType = unmarshalQCString(s);
+ return result;
+}
+
+void ArgumentList::marshal(StorageIntf *s,ArgumentList *argList)
+{
+ if (argList==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,argList->count());
+ if (argList->count()>0)
+ {
+ ArgumentListIterator ali(*argList);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ marshalQCString(s,a->attrib);
+ marshalQCString(s,a->type);
+ marshalQCString(s,a->canType);
+ marshalQCString(s,a->name);
+ marshalQCString(s,a->array);
+ marshalQCString(s,a->defval);
+ marshalQCString(s,a->docs);
+ }
+ }
+ marshalBool(s,argList->constSpecifier);
+ marshalBool(s,argList->volatileSpecifier);
+ marshalBool(s,argList->pureSpecifier);
+ marshalQCString(s,argList->trailingReturnType);
+ }
+}
+
diff --git a/src/arguments.h b/src/arguments.h
new file mode 100644
index 0000000..ed09869
--- /dev/null
+++ b/src/arguments.h
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef ARGUMENTS_H
+#define ARGUMENTS_H
+
+#include <qlist.h>
+#include <qcstring.h>
+
+class StorageIntf;
+
+/*! \brief This class contains the information about the argument of a
+ * function or template
+ *
+ */
+struct Argument
+{
+ /*! Construct a new argument. */
+ Argument() {}
+ /*! Copy an argument (does a deep copy of all strings). */
+ Argument(const Argument &a)
+ {
+ attrib=a.attrib.copy();
+ type=a.type.copy();
+ name=a.name.copy();
+ defval=a.defval.copy();
+ docs=a.docs.copy();
+ array=a.array.copy();
+ }
+ /*! Assignment of an argument (does a deep copy of all strings). */
+ Argument &operator=(const Argument &a)
+ {
+ if (this!=&a)
+ {
+ attrib=a.attrib.copy();
+ type=a.type.copy();
+ name=a.name.copy();
+ defval=a.defval.copy();
+ docs=a.docs.copy();
+ array=a.array.copy();
+ }
+ return *this;
+ }
+ /*! return TRUE if this argument is documentation and the argument has a
+ * non empty name.
+ */
+ bool hasDocumentation() const
+ {
+ return !name.isEmpty() && !docs.isEmpty();
+ }
+
+ QCString attrib; /*!< Argument's attribute (IDL only) */
+ QCString type; /*!< Argument's type */
+ QCString canType; /*!< Cached value of canonical type (after type resolution). Empty initially. */
+ QCString name; /*!< Argument's name (may be empty) */
+ QCString array; /*!< Argument's array specifier (may be empty) */
+ QCString defval; /*!< Argument's default value (may be empty) */
+ QCString docs; /*!< Argument's documentation (may be empty) */
+};
+
+/*! \brief This class represents an function or template argument list.
+ *
+ * This class also stores some information about member that is typically
+ * put after the argument list, such as whether the member is const,
+ * volatile or pure virtual.
+ */
+class ArgumentList : public QList<Argument>
+{
+ public:
+ /*! Creates an empty argument list */
+ ArgumentList() : QList<Argument>(),
+ constSpecifier(FALSE),
+ volatileSpecifier(FALSE),
+ pureSpecifier(FALSE)
+ { setAutoDelete(TRUE); }
+ /*! Destroys the argument list */
+ ~ArgumentList() {}
+ /*! Makes a deep copy of this object */
+ ArgumentList *deepCopy() const;
+ /*! Does any argument of this list have documentation? */
+ bool hasDocumentation() const;
+ /*! Does the member modify the state of the class? default: FALSE. */
+ bool constSpecifier;
+ /*! Is the member volatile? default: FALSE. */
+ bool volatileSpecifier;
+ /*! Is this a pure virtual member? default: FALSE */
+ bool pureSpecifier;
+ /*! C++11 style Trailing return type? */
+ QCString trailingReturnType;
+ /*! C++11 defaulted method */
+
+ static ArgumentList *unmarshal(StorageIntf *s);
+ static void marshal(StorageIntf *s,ArgumentList *argList);
+};
+
+typedef QListIterator<Argument> ArgumentListIterator;
+
+#endif
diff --git a/src/bib2xhtml.pl b/src/bib2xhtml.pl
new file mode 100755
index 0000000..da6dc62
--- /dev/null
+++ b/src/bib2xhtml.pl
@@ -0,0 +1,319 @@
+#
+# Below is a stripped down version of bib2xhtml used by doxygen.
+# For the full version see http://www.spinellis.gr/sw/textproc/bib2xhtml/
+#
+# Convert from bibtex to XHTML.
+#
+# (C) Copyright 1995, 1996 David Hull.
+# (David Hull / hull at cs.uiuc.edu / http://www.uiuc.edu/ph/www/dlhull)
+#
+# (C) Copyright 2002-2010 Diomidis Spinellis
+# http://www.spinellis.gr
+#
+# This program is free software. You can redistribute it and/or modify
+# it under the terms of the GNU General Public License. See the
+# files README and COPYING for details.
+#
+# This source code contains UTF-8 characters. You might want to use
+# an appropriate editor, if you want to view/modify the LaTeX to Unicode
+# substitution commands.
+#
+
+use Getopt::Std;
+use open IO => ':crlf';
+$label_styles{'numbered'} = $LABEL_NUMBERED = 2;
+$list_start[$LABEL_NUMBERED] = 'dl class="citelist"';
+$list_end[$LABEL_NUMBERED] = "/dl";
+ at tmpfiles = ();
+sub html_ent {
+ s/\\i\b/i/g;
+ s/\\\'(\001\d+)\{([AEIOUaeiou])\1\}/&$2acute;/gs;
+ s/\\\'([AEIOUaeiou])/&$1acute;/g;
+ s/\\\`(\001\d+)\{([AEIOUaeiou])\1\}/&$2grave;/gs;
+ s/\\\`([AEIOUaeiou])/&$1grave;/g;
+ s/\\\"(\001\d+)\{([AEIOUaeiouy])\1\}/&$2uml;/gs;
+ s/\\\"([AEIOUaeiouy])/&$1uml;/g;
+ s/\\\~(\001\d+)\{([ANOano])\1\}/&$2tilde;/gs;
+ s/\\\~([ANOano])/&$1tilde;/g;
+ s/\\\^(\001\d+)\{([AEIOUaeiou])\1\}/&$2circ;/gs;
+ s/\\\^([AEIOUaeiou])/&$1circ;/g;
+ s/\\c(\001\d+)\{([Cc])\1\}/&$2cedil;/gs;
+ s/\\u(\001\d+)\{(.)\1\}/$2/gs;
+ s/\\v(\001\d+)\{(.)\1\}/$2/gs;
+ s/\\([lL])\b/$1/g;
+ s/\\\=(\001\d+)\{(.)\1\}/$2/gs;
+ s/\\\=(.)/$1/g;
+ s/\\\.(\001\d+)\{(.)\1\}/$2/gs;
+ s/\\\.(.)/$1/g;
+ s/\\([Oo])\b\s*/&$1slash;/g;
+ s/\\AA\b\s*/Å/g;
+ s/\\aa\b\s*/å/g;
+ s/\\AE\b\s*/Æ/g;
+ s/\\ae\b\s*/æ/g;
+ s/\\ss\b\s*/ß/g;
+ s/\\S\b\s*/§/g;
+ s/\\P\b\s*/¶/g;
+ s/\\pounds\b\s*/£/g;
+ s/\?\`/¿/g;
+ s/\!\`/¡/g;
+ s/\-\-\-/—/g;
+ s/([^\!])\-\-([^\>])/$1–$2/g;
+ s/\\([aA]lpha)\b/&$1;/g;
+ s/\\([bB]eta)\b/&$1;/g;
+ s/\\([gG]amma)\b/&$1;/g;
+ s/\\([dD]elta)\b/&$1;/g;
+ s/\\varepsilon\b/ε/g;
+ s/\\([eE]psilon)\b/&$1;/g;
+ s/\\([zZ]eta)\b/&$1;/g;
+ s/\\([eE]ta)\b/&$1;/g;
+ s/\\([tT]heta)\b/&$1;/g;
+ s/\\vartheta\b/θ/g;
+ s/\\([iI]ota)\b/&$1;/g;
+ s/\\([kK]appa)\b/&$1;/g;
+ s/\\([lL]ambda)\b/&$1;/g;
+ s/\\([mM]u)\b/&$1;/g;
+ s/\\([nN]u)\b/&$1;/g;
+ s/\\([xX]i)\b/&$1;/g;
+ s/\\([oO]micron)\b/&$1;/g;
+ s/\\([pP]i)\b/&$1;/g;
+ s/\\varpi\b/π/g;
+ s/\\([rR]ho)\b/&$1;/g;
+ s/\\varrho\b/ρ/g;
+ s/\\([sS]igma)\b/&$1;/g;
+ s/\\varsigma\b/ς/g;
+ s/\\([tT]au)\b/&$1;/g;
+ s/\\([uU]psilon)\b/&$1;/g;
+ s/\\([pP]hi)\b/&$1;/g;
+ s/\\varphi\b/φ/g;
+ s/\\([cC]hi)\b/&$1;/g;
+ s/\\([pP]si)\b/&$1;/g;
+ s/\\([oO]mega)\b/&$1;/g;
+ s/\\S\b/§/g;
+ s/^\\circ\b/°/g;
+ s/\\infty\b/∞/g;
+ s/\\emptyset\b/∅/g;
+ s/\\pm\b/±/g;
+ s/\\times\b/×/g;
+ s/\\cdot\b/⋅/g;
+ s/\\partial\b/∂/g;
+ s/\\nabla\b/∇/g;
+ s/\\surd\b/√/g;
+ s/\\perp\b/⊥/g;
+ s/\\sum\b/∑/g;
+ s/\\int\b/∫/g;
+ s/\\prod\b/∏/g;
+ s/\\sim\b/∼/g;
+ s/\\approx\b/≈/g;
+ s/\\ne\b/≠/g;
+ s/\\equiv\b/≡/g;
+ s/\\propto\b/∝/g;
+ s/\\le\b/≤/g;
+ s/\\ge\b/≥/g;
+ s/\\leftarrow\b/←/g;
+ s/\\rightarrow\b/→/g;
+ s/\\in\b/∈/g;
+ s/\\notin\b/∉/g;
+ s/\\lceil\b/⌈/g;
+ s/\\rceil\b/⌉/g;
+ s/\\lfloor\b/⌊/g;
+ s/\\rfloor\b/⌋/g;
+}
+foreach (@ARGV) {
+ if (/\.bib$/) {
+ $bibfile = $_;
+ $bibfile =~ s/\.bib$//;
+ push(@bibfiles,$bibfile);
+ } else {
+ $htmlfile = $_;
+ }
+}
+exit(1) unless defined($htmlfile);
+$bibdatacmd="\\bibdata{".join(',', at bibfiles)."}";
+$label_style = $LABEL_NUMBERED;
+$bstfile = "doxygen";
+umask(077);
+open(HTMLFILE,">$htmlfile$$");
+if (open(OHTMLFILE, "$htmlfile")) {
+ $mode = (stat OHTMLFILE)[2] & 0xfff;
+} else {
+ print "Error opening $htmlfile\n";
+ exit(1);
+}
+$beginstring = "<!-- BEGIN CITATIONS -->";
+$endstring = "<!-- END CITATIONS -->";
+ at citations = ();
+loop:
+while (<OHTMLFILE>) {
+ print HTMLFILE;
+ last loop if m/^$beginstring$/;
+}
+loop:
+while (<OHTMLFILE>) {
+ print HTMLFILE;
+ last loop if m/^$endstring$/;
+ push(@citations, $2) if m/^([^\\]*)?(.+\})(.*)?$/;
+}
+push(@citations, $bibdatacmd);
+$auxfile = "bib$$";
+push(@tmpfiles, "$auxfile.aux");
+open(AUXFILE, ">$auxfile" . ".aux");
+print AUXFILE "\\relax\n\\bibstyle{$bstfile}\n";
+foreach $citation (@citations) {
+ print AUXFILE "$citation\n";
+}
+close(AUXFILE);
+push(@tmpfiles, "$auxfile.blg");
+push(@tmpfiles, "$auxfile.bbl");
+`bibtex $auxfile 2>&1`;
+if ($?==-1)
+{
+ print "bibtex command failed: $!\n";
+}
+$beginstring = "<!-- BEGIN BIBLIOGRAPHY -->";
+$endstring = "<!-- END BIBLIOGRAPHY -->";
+loop:
+while (<OHTMLFILE>) {
+ last loop if m/^$beginstring$/;
+ print HTMLFILE;
+}
+loop:
+while (<OHTMLFILE>) {
+ last loop if m/^$endstring$/;
+}
+print HTMLFILE "$beginstring\n";
+$t = $auxfile . ".bbl";
+$/ = "";
+open(BBLFILE, "<$t") || die "error opening $t: $!\n";
+$nentry = 0;
+loop:
+while (<BBLFILE>) {
+ if (($nentry == 0) && (m/^#/)) {
+ if ((m/#\s*label-style:\s*(\S+)/) && (! defined $label_style)) {
+ $label_style = $label_styles{$1};
+ if (! defined $label_style) {
+ print STDERR "label style unknown: \n";
+ next loop;
+ }
+ }
+ next loop;
+ }
+ $nentry++;
+ ($bcite, $blabel) = m+<dt><a name=\"([^\"]*)\">\[([^\]]*)\]</a></dt><dd>+;
+ $blabel = "$nentry";
+ $bibcite{$bcite} = $blabel;
+}
+close(BBLFILE);
+$label_style = $LABEL_DEFAULT if (! defined $label_style);
+$list_start = $list_start[$label_style];
+$list_end = $list_end[$label_style];
+print HTMLFILE "<$list_start>\n\n";
+open(BBLFILE, "<$t") || die "error opening $t: $!\n";
+$nentry = 0;
+loop:
+while (<BBLFILE>) {
+ next loop if (($nentry == 0) && (m/^#/));
+ $nentry++;
+ s/\\\{/\002/g;
+ s/\\\}/\003/g;
+ s/\\\$/\004/g;
+ {
+ local ($c, $l, $z) = (0, 0, ());
+ s/([\{\}])/join("","\001",($1 eq "\{" ? $z[$l++]=$c++ : $z[--$l]),$1)/ge;
+ }
+ s/\%\n//g;
+ s/(\.(<\/cite>|<\/a>|\')+)\./$1/g;
+ s:(<dt><a name=\"[^\"]*\">\[)[^\]]*(\]</a></dt><dd>):$1$nentry$2:;
+ while (m/(\\(cite(label)?)(\001\d+)\{([^\001]+)\4\})/) {
+ $old = $1;
+ $cmd = $2;
+ $doxref = defined($3);
+ $bcite = $5;
+ if (! defined $bibcite{$bcite}) {
+ $blabel = " [" . $bcite . "]";
+ } elsif ($doxref) {
+ $blabel = " <a href=\"#$bcite\">[" . $bibcite{$bcite} . "]<\/a>";
+ } else {
+ $blabel = " [" . $bibcite{$bcite} . "]";
+ }
+ $old =~ s/(\W)/\\$1/g;
+ s/\s*$old/$blabel/g;
+ }
+ s/In (<a href=\"[^\"]*\">)([^\[]+) \[(\2)/In $1\[$2/;
+ s/\\htmladdnormallink(foot)?(\001\d+)\{([^\001]+)\2\}(\001\d+)\{([^\001]+)\4\}/<a href="$5">$3<\/a>/gs;
+ s/\&/\005/g;
+ s/\\?&/&/g;
+ s/\005/&/g;
+ html_ent();
+ while (m/\\char([\'\"]?[0-9a-fA-F]+)/) {
+ $o = $r = $1;
+ if ($r =~ s/^\'//) {
+ $r = oct($r);
+ } elsif ($r =~ s/^\"//) {
+ $r = hex($r);
+ }
+ s/\\char$o\s*/&#$r;/g;
+ }
+ s/{\\etalchar\001(\d+)\{(.)}\001\1\}/$2/g;
+ s/\\par\b/<p \/>/g;
+ s/\\url(\001\d+)\{(.*)\1\}/<a href="$2">$2<\/a>/gs;
+ s/\\href(\001\d+)\{(.*)\1\}(\001\d+)\{([^\001]*)\3\}/<a href="$2">$4<\/a>/gs;
+ s/\\href(\001\d+)\{(.*)\1\}/<a href="$2">$2<\/a>/gs;
+ s/(\001\d+)\{\\rm\s+(.*)\1\}/$2/gs;
+ s/\\textrm(\001\d+)\{(.*)\1\}/$2/gs;
+ s/(\001\d+)\{\\em\s+(.*)\1\}/<em>$2<\/em>/gs;
+ s/(\001\d+)\{\\it\s+(.*)\1\}/<i>$2<\/i>/gs;
+ s/(\001\d+)\{\\bf\s+(.*)\1\}/<b>$2<\/b>/gs;
+ s/(\001\d+)\{\\tt\s+(.*)\1\}/<tt>$2<\/tt>/gs;
+ s/\\emph(\001\d+)\{(.*)\1\}/<em>$2<\/em>/gs;
+ s/\\textit(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
+ s/\\textbf(\001\d+)\{(.*)\1\}/<b>$2<\/b>/gs;
+ s/\\texttt(\001\d+)\{(.*)\1\}/<tt>$2<\/tt>/gs;
+ s/\\mathrm(\001\d+)\{(.*)\1\}/$2/gs;
+ s/\\mathnormal(\001\d+)\{(.*)\1\}/$2/gs;
+ s/\\mathsf(\001\d+)\{(.*)\1\}/$2/gs;
+ s/\\mathbf(\001\d+)\{(.*)\1\}/<b>$2<\/b>/gs;
+ s/\\mathcal(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
+ s/\\mathit(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
+ s/\\mathtt(\001\d+)\{(.*)\1\}/<tt>$2<\/tt>/gs;
+ s/\\bibxhtmlname(\001\d+)\{(.*)\1\}/$2/ges;
+ sub domath {
+ local($t) = @_;
+ $t =~ s/\^(\001\d+)\{\\circ\1\}/\&\#176;/gs;
+ $t =~ s/\^\\circ/\&\#176;/g;
+ $t =~ s/\^(\001\d+)\{(.*)\1\}/<sup>$2<\/sup>/gs;
+ $t =~ s/\^(\w)/<sup>$1<\/sup>/g;
+ $t =~ s/\_(\001\d+)\{(.*)\1\}/<sub>$2<\/sub>/gs;
+ $t =~ s/\_(\w)/<sub>$1<\/sub>/g;
+ $t;
+ }
+ s/(\$([^\$]+)\$)/&domath($2)/ge;
+ s/(\\\((([^\\]|\\[^\(\)])+)\\\))/&domath($2)/ge;
+ s/\\mbox(\001\d+)\{(.*)\1\}/$2/gs;
+ while (s/(\<a href\=\"[^"]*?)\~/$1\005/g) { ; }
+ s/([^\\])~/$1 /g;
+ s/\\\,/ /g;
+ s/\\ldots\b/…/g;
+ s/\\dots\b/…/g;
+ s/\005/\~/g;
+ s/\\ / /g;
+ s/\\textasciitilde\b\s*/~/g;
+ s/\\([\#\&\%\~\_\^\|])/$1/g;
+ s/\\\W//g;
+ s/\001(\d+)\{\\[A-Za-z]+\001(\d+)\{([^\001]*)\001\2\}\001\1\}/$3/g;
+ s/\\([A-Za-z]+)/ $1 /g;
+ s+In <a href=\"[^\"]*\"></a>++;
+ s/\001\d+[\{\}]//gs;
+ tr/\002\003\004/{}$/;
+ print HTMLFILE $_;
+}
+close(BBLFILE);
+print HTMLFILE "<$list_end>\n\n$endstring\n";
+while (<OHTMLFILE>) {
+ print HTMLFILE;
+}
+close (OHTMLFILE);
+close(HTMLFILE);
+chmod($mode, "$htmlfile$$");
+rename("$htmlfile$$", $htmlfile);
+unlink(@tmpfiles);
+exit(0);
diff --git a/src/bufstr.h b/src/bufstr.h
new file mode 100644
index 0000000..7fb7d40
--- /dev/null
+++ b/src/bufstr.h
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#ifndef _BUFSTR_H
+#define _BUFSTR_H
+
+#include <qglobal.h>
+#include <qcstring.h>
+#include <stdlib.h>
+
+/*! @brief Buffer used to store strings
+ *
+ * This buffer is used append characters and strings. It will automatically
+ * resize itself, yet provide efficient random access to the content.
+ */
+class BufStr
+{
+ public:
+ BufStr(int size)
+ : m_size(size), m_writeOffset(0), m_spareRoom(10240), m_buf(0)
+ {
+ m_buf = (char *)calloc(size,1);
+ }
+ ~BufStr()
+ {
+ free(m_buf);
+ }
+ void addChar(char c)
+ {
+ makeRoomFor(1);
+ m_buf[m_writeOffset++]=c;
+ }
+ void addArray(const char *a,int len)
+ {
+ makeRoomFor(len);
+ memcpy(m_buf+m_writeOffset,a,len);
+ m_writeOffset+=len;
+ }
+ void skip(uint s)
+ {
+ makeRoomFor(s);
+ m_writeOffset+=s;
+ }
+ void shrink( uint newlen )
+ {
+ m_writeOffset=newlen;
+ resize(newlen);
+ }
+ void resize( uint newlen )
+ {
+ uint oldsize = m_size;
+ m_size=newlen;
+ if (m_writeOffset>=m_size) // offset out of range -> enlarge
+ {
+ m_size=m_writeOffset+m_spareRoom;
+ }
+ m_buf = (char *)realloc(m_buf,m_size);
+ if (m_size>oldsize)
+ {
+ memset(m_buf+oldsize,0,m_size-oldsize);
+ }
+ }
+ int size() const
+ {
+ return m_size;
+ }
+ char *data() const
+ {
+ return m_buf;
+ }
+ char &at(uint i) const
+ {
+ return m_buf[i];
+ }
+ bool isEmpty() const
+ {
+ return m_writeOffset==0;
+ }
+ operator const char *() const
+ {
+ return m_buf;
+ }
+ uint curPos() const
+ {
+ return m_writeOffset;
+ }
+ void dropFromStart(uint bytes)
+ {
+ if (bytes>m_size) bytes=m_size;
+ if (bytes>0) qmemmove(m_buf,m_buf+bytes,m_size-bytes);
+ m_size-=bytes;
+ m_writeOffset-=bytes;
+ }
+ private:
+ void makeRoomFor(uint size)
+ {
+ if (m_writeOffset+size>=m_size)
+ {
+ resize(m_size+size+m_spareRoom);
+ }
+ }
+ uint m_size;
+ uint m_writeOffset;
+ const int m_spareRoom; // 10Kb extra room to avoid frequent resizing
+ char *m_buf;
+};
+
+
+#endif
diff --git a/src/cite.cpp b/src/cite.cpp
new file mode 100644
index 0000000..a33f12f
--- /dev/null
+++ b/src/cite.cpp
@@ -0,0 +1,307 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011 by Dimitri van Heesch
+ * Based on a patch by David Munger
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "cite.h"
+#include "portable.h"
+#include "config.h"
+#include "message.h"
+#include "util.h"
+#include "language.h"
+#include "ftextstream.h"
+#include <qdir.h>
+
+//--------------------------------------------------------------------------
+
+static const char *doxygen_bst =
+#include "doxygen.bst.h"
+;
+
+static const char *bib2xhtml_pl =
+#include "bib2xhtml.pl.h"
+;
+
+//--------------------------------------------------------------------------
+
+const QCString CiteConsts::fileName("citelist");
+const QCString CiteConsts::anchorPrefix("CITEREF_");
+const QCString bibTmpFile("bibTmpFile_");
+const QCString bibTmpDir("bibTmpDir/");
+
+//--------------------------------------------------------------------------
+
+CiteDict::CiteDict(int size) : m_entries(size, FALSE)
+{
+ m_entries.setAutoDelete(TRUE);
+}
+
+void CiteDict::writeLatexBibliography(FTextStream &t)
+{
+ if (m_entries.isEmpty())
+ return;
+
+ QCString style = Config_getString("LATEX_BIB_STYLE");
+ if (style.isEmpty())
+ style="plain";
+ QCString unit;
+ if (Config_getBool("COMPACT_LATEX"))
+ unit = "section";
+ else
+ unit = "chapter";
+ t << "% Bibliography\n"
+ "\\newpage\n"
+ "\\phantomsection\n"
+ "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"
+ "\\bibliographystyle{" << style << "}\n"
+ "\\bibliography{";
+ QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
+ QCString latexOutputDir = Config_getString("LATEX_OUTPUT")+"/";
+ int i = 0;
+ const char *bibdata = citeDataList.first();
+ while (bibdata)
+ {
+ QCString bibFile = bibdata;
+ // Note: file can now have multiple dots
+ if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
+ QFileInfo fi(bibFile);
+ if (fi.exists())
+ {
+ if (!bibFile.isEmpty())
+ {
+ if (i) t << ",";
+ i++;
+ t << bibTmpFile << QString().setNum(i);
+ }
+ }
+ bibdata = citeDataList.next();
+ }
+ t << "}\n"
+ "\n";
+}
+
+void CiteDict::insert(const char *label)
+{
+ m_entries.insert(label,new CiteInfo(label));
+}
+
+CiteInfo *CiteDict::find(const char *label) const
+{
+ return label ? m_entries.find(label) : 0;
+}
+
+void CiteDict::clear()
+{
+ m_entries.clear();
+}
+
+bool CiteDict::isEmpty() const
+{
+ QStrList &citeBibFiles = Config_getList("CITE_BIB_FILES");
+ return (citeBibFiles.count()==0 || m_entries.isEmpty());
+}
+
+void CiteDict::generatePage() const
+{
+ //printf("** CiteDict::generatePage() count=%d\n",m_ordering.count());
+
+ // do not generate an empty citations page
+ if (isEmpty()) return; // nothing to cite
+
+ // 1. generate file with markers and citations to OUTPUT_DIRECTORY
+ QFile f;
+ QCString outputDir = Config_getString("OUTPUT_DIRECTORY");
+ QCString citeListFile = outputDir+"/citelist.doc";
+ f.setName(citeListFile);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("could not open file %s for writing\n",citeListFile.data());
+ }
+ FTextStream t(&f);
+ t << "<!-- BEGIN CITATIONS -->" << endl;
+ t << "<!--" << endl;
+ QDictIterator<CiteInfo> it(m_entries);
+ CiteInfo *ci;
+ for (it.toFirst();(ci=it.current());++it)
+ {
+ t << "\\citation{" << ci->label << "}" << endl;
+ }
+ t << "-->" << endl;
+ t << "<!-- END CITATIONS -->" << endl;
+ t << "<!-- BEGIN BIBLIOGRAPHY -->" << endl;
+ t << "<!-- END BIBLIOGRAPHY -->" << endl;
+ f.close();
+
+ // 2. generate bib2xhtml
+ QCString bib2xhtmlFile = outputDir+"/bib2xhtml.pl";
+ f.setName(bib2xhtmlFile);
+ QCString bib2xhtml = bib2xhtml_pl;
+ if (!f.open(IO_WriteOnly))
+ {
+ err("could not open file %s for writing\n",bib2xhtmlFile.data());
+ }
+ f.writeBlock(bib2xhtml, bib2xhtml.length());
+ f.close();
+
+ // 3. generate doxygen.bst
+ QCString doxygenBstFile = outputDir+"/doxygen.bst";
+ QCString bstData = doxygen_bst;
+ f.setName(doxygenBstFile);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("could not open file %s for writing\n",doxygenBstFile.data());
+ }
+ f.writeBlock(bstData, bstData.length());
+ f.close();
+
+ // 4. for all formats we just copy the bib files to as special output directory
+ // so bibtex can find them without path (bibtex doesn't support paths or
+ // filenames with spaces!)
+ // Strictly not required when only latex is generated
+ QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
+ QCString bibOutputDir = outputDir+"/"+bibTmpDir;
+ QCString bibOutputFiles = "";
+ QDir thisDir;
+ thisDir.mkdir(bibOutputDir);
+ const char *bibdata = citeDataList.first();
+ int i = 0;
+ while (bibdata)
+ {
+ QCString bibFile = bibdata;
+ if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
+ QFileInfo fi(bibFile);
+ if (fi.exists())
+ {
+ if (!bibFile.isEmpty())
+ {
+ ++i;
+ copyFile(bibFile,bibOutputDir + bibTmpFile + QCString().setNum(i) + ".bib");
+ bibOutputFiles = bibOutputFiles + " " + bibTmpDir + bibTmpFile + QCString().setNum(i) + ".bib";
+ }
+ }
+ else if (!fi.exists())
+ {
+ err("bib file %s not found!\n",bibFile.data());
+ }
+ bibdata = citeDataList.next();
+ }
+
+ QString oldDir = QDir::currentDirPath();
+ QDir::setCurrent(outputDir);
+
+ // 5. run bib2xhtml perl script on the generated file which will insert the
+ // bibliography in citelist.doc
+ portable_system("perl","\""+bib2xhtmlFile+"\" "+bibOutputFiles+" \""+
+ citeListFile+"\"");
+
+ QDir::setCurrent(oldDir);
+
+ // 6. read back the file
+ f.setName(citeListFile);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("could not open file %s for reading\n",citeListFile.data());
+ }
+ bool insideBib=FALSE;
+
+ QCString doc;
+ QFileInfo fi(citeListFile);
+ QCString input(fi.size()+1);
+ f.readBlock(input.data(),fi.size());
+ f.close();
+ input.at(fi.size())='\0';
+ int p=0,s;
+ //printf("input=[%s]\n",input.data());
+ while ((s=input.find('\n',p))!=-1)
+ {
+ QCString line = input.mid(p,s-p);
+ //printf("p=%d s=%d line=[%s]\n",p,s,line.data());
+ p=s+1;
+
+ if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE;
+ else if (line.find("<!-- END BIBLIOGRAPH")!=-1) insideBib=FALSE;
+ else if (insideBib) doc+=line+"\n";
+ int i;
+ // determine text to use at the location of the @cite command
+ if (insideBib && (i=line.find("<a name=\"CITEREF_"))!=-1)
+ {
+ int j=line.find("\">[");
+ int k=line.find("]</a>");
+ if (j!=-1 && k!=-1)
+ {
+ QCString label = line.mid(i+17,j-i-17);
+ QCString number = line.mid(j+2,k-j-1);
+ CiteInfo *ci = m_entries.find(label);
+ //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci);
+ if (ci)
+ {
+ ci->text = number;
+ }
+ }
+ }
+ }
+ //printf("doc=[%s]\n",doc.data());
+
+ // 7. add it as a page
+ addRelatedPage(CiteConsts::fileName,
+ theTranslator->trCiteReferences(),doc,0,CiteConsts::fileName,1,0,0,0);
+
+ // 8. for latex we just copy the bib files to the output and let
+ // latex do this work.
+ if (Config_getBool("GENERATE_LATEX"))
+ {
+ // copy bib files to the latex output dir
+ QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
+ QCString latexOutputDir = Config_getString("LATEX_OUTPUT")+"/";
+ int i = 0;
+ const char *bibdata = citeDataList.first();
+ while (bibdata)
+ {
+ QCString bibFile = bibdata;
+ // Note: file can now have multiple dots
+ if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
+ QFileInfo fi(bibFile);
+ if (fi.exists())
+ {
+ if (!bibFile.isEmpty())
+ {
+ // bug_700510, multile times the same name were overwriting; creating new names
+ // also for names with spaces
+ ++i;
+ copyFile(bibFile,latexOutputDir + bibTmpFile + QCString().setNum(i) + ".bib");
+ }
+ }
+ else
+ {
+ err("bib file %s not found!\n",bibFile.data());
+ }
+ bibdata = citeDataList.next();
+ }
+ }
+
+ // 9. Remove temporary files
+ thisDir.remove(citeListFile);
+ thisDir.remove(doxygenBstFile);
+ thisDir.remove(bib2xhtmlFile);
+ bibdata = citeDataList.first();
+ // we might try to remove too many files as empty files didn't get a coresponding new file
+ // but the remove function does not emit an error for it and we don't catch the error return
+ // so no problem.
+ for (unsigned int j = 1; j <= citeDataList.count(); j++)
+ {
+ thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib");
+ }
+ thisDir.rmdir(bibOutputDir);
+}
+
diff --git a/src/cite.h b/src/cite.h
new file mode 100644
index 0000000..1c59553
--- /dev/null
+++ b/src/cite.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 2011 by Dimitri van Heesch
+ * Based on a patch by David Munger
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CITEDB_H
+#define CITEDB_H
+
+#include <qdict.h>
+
+class FTextStream;
+
+/// String constants for citations
+struct CiteConsts
+{
+ static const QCString fileName;
+ static const QCString anchorPrefix;
+};
+
+/// Citation-related data.
+struct CiteInfo
+{
+ CiteInfo(const char *label_, const char *text_=0, const char *fullText_=0,
+ const char *ref_=0) :
+ label(label_), text(text_), fullText(fullText_), ref(ref_)
+ { }
+
+ CiteInfo(const CiteInfo &o)
+ { label=o.label.copy(); text=o.text.copy(); fullText=o.fullText.copy(); ref=o.ref.copy(); }
+
+ QCString label;
+ QCString text;
+ QCString fullText;
+ QCString ref;
+
+};
+
+/**
+ * @brief Cite database access class.
+ * @details This class provides access do the database of bibliographic
+ * references through the bibtex backend.
+ */
+class CiteDict
+{
+ public:
+ /** Create the database, with an expected maximum of \a size entries */
+ CiteDict(int size);
+
+// /** Resolve references to citations */
+// void resolve();
+
+ /** Insert a citation identified by \a label into the database */
+ void insert(const char *label);
+
+ /** Return the citation info for a given \a label */
+ CiteInfo *find(const char *label) const;
+
+ /** Generate the citations page */
+ void generatePage() const;
+
+ /** clears the database */
+ void clear();
+
+ /** return TRUE if there are no citations.
+ * Only valid after calling resolve()
+ */
+ bool isEmpty() const;
+
+ /** writes the latex code for the standard bibliography
+ * section to text stream \a t
+ */
+ void writeLatexBibliography(FTextStream &t);
+
+ private:
+// bool writeAux();
+// bool writeBst();
+// bool execute();
+// void parse();
+// void clean();
+ QDict<CiteInfo> m_entries;
+// QList<QCString> m_ordering;
+ QCString m_baseFileName;
+};
+
+#endif
diff --git a/src/clangparser.cpp b/src/clangparser.cpp
new file mode 100644
index 0000000..9913b12
--- /dev/null
+++ b/src/clangparser.cpp
@@ -0,0 +1,942 @@
+#include "clangparser.h"
+#include "settings.h"
+#include <stdio.h>
+
+#if USE_LIBCLANG
+#include <clang-c/Index.h>
+#include <qfileinfo.h>
+#include <stdlib.h>
+#include "message.h"
+#include "sortdict.h"
+#include "outputgen.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "doxygen.h"
+#include "util.h"
+#include "config.h"
+#include "growbuf.h"
+#include "membername.h"
+#include "filename.h"
+#include "tooltip.h"
+
+static Definition *g_currentDefinition=0;
+static MemberDef *g_currentMemberDef=0;
+static uint g_currentLine=0;
+static bool g_searchForBody=FALSE;
+static bool g_insideBody=FALSE;
+static uint g_bracketCount=0;
+#endif
+
+ClangParser *ClangParser::instance()
+{
+ if (!s_instance) s_instance = new ClangParser;
+ return s_instance;
+}
+
+ClangParser *ClangParser::s_instance = 0;
+
+//--------------------------------------------------------------------------
+#if USE_LIBCLANG
+
+class ClangParser::Private
+{
+ public:
+ enum DetectedLang { Detected_Cpp, Detected_ObjC, Detected_ObjCpp };
+ Private() : tu(0), tokens(0), numTokens(0), cursors(0),
+ ufs(0), sources(0), numFiles(0), fileMapping(257),
+ detectedLang(Detected_Cpp)
+ { fileMapping.setAutoDelete(TRUE); }
+ int getCurrentTokenLine();
+ CXIndex index;
+ CXTranslationUnit tu;
+ QCString fileName;
+ CXToken *tokens;
+ uint numTokens;
+ CXCursor *cursors;
+ uint curLine;
+ uint curToken;
+ CXUnsavedFile *ufs;
+ QCString *sources;
+ uint numFiles;
+ QDict<uint> fileMapping;
+ DetectedLang detectedLang;
+};
+
+static QCString detab(const QCString &s)
+{
+ static int tabSize = Config_getInt("TAB_SIZE");
+ GrowBuf out;
+ int size = s.length();
+ const char *data = s.data();
+ int i=0;
+ int col=0;
+ const int maxIndent=1000000; // value representing infinity
+ int minIndent=maxIndent;
+ while (i<size)
+ {
+ char c = data[i++];
+ switch(c)
+ {
+ case '\t': // expand tab
+ {
+ int stop = tabSize - (col%tabSize);
+ //printf("expand at %d stop=%d\n",col,stop);
+ col+=stop;
+ while (stop--) out.addChar(' ');
+ }
+ break;
+ case '\n': // reset colomn counter
+ out.addChar(c);
+ col=0;
+ break;
+ case ' ': // increment column counter
+ out.addChar(c);
+ col++;
+ break;
+ default: // non-whitespace => update minIndent
+ out.addChar(c);
+ if (c<0 && i<size) // multibyte sequence
+ {
+ out.addChar(data[i++]); // >= 2 bytes
+ if (((uchar)c&0xE0)==0xE0 && i<size)
+ {
+ out.addChar(data[i++]); // 3 bytes
+ }
+ if (((uchar)c&0xF0)==0xF0 && i<size)
+ {
+ out.addChar(data[i++]); // 4 byres
+ }
+ }
+ if (col<minIndent) minIndent=col;
+ col++;
+ }
+ }
+ out.addChar(0);
+ //printf("detab refIndent=%d\n",refIndent);
+ return out.get();
+}
+
+/** Callback function called for each include in a translation unit */
+static void inclusionVisitor(CXFile includedFile,
+ CXSourceLocation* /*inclusionStack*/,
+ unsigned /*includeLen*/,
+ CXClientData clientData)
+{
+ QDict<void> *fileDict = (QDict<void> *)clientData;
+ CXString incFileName = clang_getFileName(includedFile);
+ //printf("--- file %s includes %s\n",fileName,clang_getCString(incFileName));
+ fileDict->insert(clang_getCString(incFileName),(void*)0x8);
+ clang_disposeString(incFileName);
+}
+
+/** filter the \a files and only keep those that are found as include files
+ * within the current translation unit.
+ * @param[in,out] files The list of files to filter.
+ */
+void ClangParser::determineInputFilesInSameTu(QStrList &files)
+{
+ // put the files in this translation unit in a dictionary
+ QDict<void> incFound(257);
+ clang_getInclusions(p->tu,
+ inclusionVisitor,
+ (CXClientData)&incFound
+ );
+ // create a new filtered file list
+ QStrList resultIncludes;
+ QStrListIterator it2(files);
+ for (it2.toFirst();it2.current();++it2)
+ {
+ if (incFound.find(it2.current()))
+ {
+ resultIncludes.append(it2.current());
+ }
+ }
+ // replace the original list
+ files=resultIncludes;
+}
+
+void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
+{
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ static QStrList &includePath = Config_getList("INCLUDE_PATH");
+ static QStrList clangOptions = Config_getList("CLANG_OPTIONS");
+ if (!clangAssistedParsing) return;
+ //printf("ClangParser::start(%s)\n",fileName);
+ p->fileName = fileName;
+ p->index = clang_createIndex(0, 0);
+ p->curLine = 1;
+ p->curToken = 0;
+ char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()));
+ QDictIterator<void> di(Doxygen::inputPaths);
+ int argc=0;
+ // add include paths for input files
+ for (di.toFirst();di.current();++di,++argc)
+ {
+ QCString inc = QCString("-I")+di.currentKey();
+ argv[argc]=strdup(inc.data());
+ //printf("argv[%d]=%s\n",argc,argv[argc]);
+ }
+ // add external include paths
+ for (uint i=0;i<includePath.count();i++)
+ {
+ QCString inc = QCString("-I")+includePath.at(i);
+ argv[argc++]=strdup(inc.data());
+ }
+ // user specified options
+ for (uint i=0;i<clangOptions.count();i++)
+ {
+ argv[argc++]=strdup(clangOptions.at(i));
+ }
+ // extra options
+ argv[argc++]=strdup("-ferror-limit=0");
+ argv[argc++]=strdup("-x");
+
+ // Since we can be presented with a .h file that can contain C/C++ or
+ // Objective C code and we need to configure the parser before knowing this,
+ // we use the source file to detected the language. Detection will fail if you
+ // pass a bunch of .h files containing ObjC code, and no sources :-(
+ SrcLangExt lang = getLanguageFromFileName(fileName);
+ if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
+ {
+ QCString fn = fileName;
+ if (p->detectedLang==ClangParser::Private::Detected_Cpp &&
+ (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
+ fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
+ { // fall back to C/C++ once we see an extension that indicates this
+ p->detectedLang = ClangParser::Private::Detected_Cpp;
+ }
+ else if (fn.right(3).lower()==".mm") // switch to Objective C++
+ {
+ p->detectedLang = ClangParser::Private::Detected_ObjCpp;
+ }
+ else if (fn.right(2).lower()==".m") // switch to Objective C
+ {
+ p->detectedLang = ClangParser::Private::Detected_ObjC;
+ }
+ }
+ switch(p->detectedLang)
+ {
+ case ClangParser::Private::Detected_Cpp:
+ argv[argc++]=strdup("c++");
+ break;
+ case ClangParser::Private::Detected_ObjC:
+ argv[argc++]=strdup("objective-c");
+ break;
+ case ClangParser::Private::Detected_ObjCpp:
+ argv[argc++]=strdup("objective-c++");
+ break;
+ }
+
+ // provide the input and and its dependencies as unsaved files so we can
+ // pass the filtered versions
+ argv[argc++]=strdup(fileName);
+ static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
+ //printf("source %s ----------\n%s\n-------------\n\n",
+ // fileName,p->source.data());
+ uint numUnsavedFiles = filesInTranslationUnit.count()+1;
+ p->numFiles = numUnsavedFiles;
+ p->sources = new QCString[numUnsavedFiles];
+ p->ufs = new CXUnsavedFile[numUnsavedFiles];
+ p->sources[0] = detab(fileToString(fileName,filterSourceFiles,TRUE));
+ p->ufs[0].Filename = strdup(fileName);
+ p->ufs[0].Contents = p->sources[0].data();
+ p->ufs[0].Length = p->sources[0].length();
+ QStrListIterator it(filesInTranslationUnit);
+ uint i=1;
+ for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
+ {
+ p->fileMapping.insert(it.current(),new uint(i));
+ p->sources[i] = detab(fileToString(it.current(),filterSourceFiles,TRUE));
+ p->ufs[i].Filename = strdup(it.current());
+ p->ufs[i].Contents = p->sources[i].data();
+ p->ufs[i].Length = p->sources[i].length();
+ }
+
+ // let libclang do the actual parsing
+ p->tu = clang_parseTranslationUnit(p->index, 0,
+ argv, argc, p->ufs, numUnsavedFiles,
+ CXTranslationUnit_DetailedPreprocessingRecord);
+ // free arguments
+ for (int i=0;i<argc;++i)
+ {
+ free(argv[i]);
+ }
+ free(argv);
+
+ if (p->tu)
+ {
+ // filter out any includes not found by the clang parser
+ determineInputFilesInSameTu(filesInTranslationUnit);
+
+ // show any warnings that the compiler produced
+ for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i)
+ {
+ CXDiagnostic diag = clang_getDiagnostic(p->tu, i);
+ CXString string = clang_formatDiagnostic(diag,
+ clang_defaultDiagnosticDisplayOptions());
+ err("%s [clang]\n",clang_getCString(string));
+ clang_disposeString(string);
+ clang_disposeDiagnostic(diag);
+ }
+
+ // create a source range for the given file
+ QFileInfo fi(fileName);
+ CXFile f = clang_getFile(p->tu, fileName);
+ CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
+ CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
+ CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd);
+
+ // produce a token stream for the file
+ clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
+
+ // produce cursors for each token in the stream
+ p->cursors=new CXCursor[p->numTokens];
+ clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
+ }
+ else
+ {
+ p->tokens = 0;
+ p->numTokens = 0;
+ p->cursors = 0;
+ err("clang: Failed to parse translation unit %s\n",fileName);
+ }
+}
+
+void ClangParser::switchToFile(const char *fileName)
+{
+ if (p->tu)
+ {
+ delete[] p->cursors;
+ clang_disposeTokens(p->tu,p->tokens,p->numTokens);
+ p->tokens = 0;
+ p->numTokens = 0;
+ p->cursors = 0;
+
+ QFileInfo fi(fileName);
+ CXFile f = clang_getFile(p->tu, fileName);
+ uint *pIndex=p->fileMapping.find(fileName);
+ if (pIndex && *pIndex<p->numFiles)
+ {
+ uint i=*pIndex;
+ //printf("switchToFile %s: len=%ld\n",fileName,p->ufs[i].Length);
+ CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
+ CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[i].Length);
+ CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd);
+
+ clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
+ p->cursors=new CXCursor[p->numTokens];
+ clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
+
+ p->curLine = 1;
+ p->curToken = 0;
+ }
+ else
+ {
+ err("clang: Failed to find input file %s in mapping\n",fileName);
+ }
+ }
+}
+
+void ClangParser::finish()
+{
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (!clangAssistedParsing) return;
+ if (p->tu)
+ {
+ //printf("ClangParser::finish()\n");
+ delete[] p->cursors;
+ clang_disposeTokens(p->tu,p->tokens,p->numTokens);
+ clang_disposeTranslationUnit(p->tu);
+ clang_disposeIndex(p->index);
+ p->fileMapping.clear();
+ p->tokens = 0;
+ p->numTokens = 0;
+ p->cursors = 0;
+ }
+ for (uint i=0;i<p->numFiles;i++)
+ {
+ free((void *)p->ufs[i].Filename);
+ }
+ delete[] p->ufs;
+ delete[] p->sources;
+ p->ufs = 0;
+ p->sources = 0;
+ p->numFiles = 0;
+ p->tu = 0;
+}
+
+int ClangParser::Private::getCurrentTokenLine()
+{
+ uint l, c;
+ if (numTokens==0) return 1;
+ // guard against filters that reduce the number of lines
+ if (curToken>=numTokens) curToken=numTokens-1;
+ CXSourceLocation start = clang_getTokenLocation(tu,tokens[curToken]);
+ clang_getSpellingLocation(start, 0, &l, &c, 0);
+ return l;
+}
+
+QCString ClangParser::lookup(uint line,const char *symbol)
+{
+ //printf("ClangParser::lookup(%d,%s)\n",line,symbol);
+ QCString result;
+ if (symbol==0) return result;
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (!clangAssistedParsing) return result;
+
+ int sl = strlen(symbol);
+ uint l = p->getCurrentTokenLine();
+ while (l>=line && p->curToken>0)
+ {
+ if (l==line) // already at the right line
+ {
+ p->curToken--; // linear search to start of the line
+ l = p->getCurrentTokenLine();
+ }
+ else
+ {
+ p->curToken/=2; // binary search backward
+ l = p->getCurrentTokenLine();
+ }
+ }
+ bool found=FALSE;
+ while (l<=line && p->curToken<p->numTokens && !found)
+ {
+ CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[p->curToken]);
+ //if (l==line)
+ //{
+ // printf("try to match symbol %s with token %s\n",symbol,clang_getCString(tokenString));
+ //}
+ const char *ts = clang_getCString(tokenString);
+ int tl = strlen(ts);
+ int startIndex = p->curToken;
+ if (l==line && strncmp(ts,symbol,tl)==0) // found partial match at the correct line
+ {
+ int offset = tl;
+ while (offset<sl) // symbol spans multiple tokens
+ {
+ //printf("found partial match\n");
+ p->curToken++;
+ if (p->curToken>=p->numTokens)
+ {
+ break; // end of token stream
+ }
+ l = p->getCurrentTokenLine();
+ clang_disposeString(tokenString);
+ tokenString = clang_getTokenSpelling(p->tu, p->tokens[p->curToken]);
+ ts = clang_getCString(tokenString);
+ tl = ts ? strlen(ts) : 0;
+ // skip over any spaces in the symbol
+ char c;
+ while (offset<sl && ((c=symbol[offset])==' ' || c=='\t' || c=='\r' || c=='\n'))
+ {
+ offset++;
+ }
+ if (strncmp(ts,symbol+offset,tl)!=0) // next token matches?
+ {
+ //printf("no match '%s'<->'%s'\n",ts,symbol+offset);
+ break; // no match
+ }
+ //printf("partial match '%s'<->'%s'\n",ts,symbol+offset);
+ offset+=tl;
+ }
+ if (offset==sl) // symbol matches the token(s)
+ {
+ CXCursor c = p->cursors[p->curToken];
+ CXString usr = clang_getCursorUSR(c);
+ //printf("found full match %s usr='%s'\n",symbol,clang_getCString(usr));
+ result = clang_getCString(usr);
+ clang_disposeString(usr);
+ found=TRUE;
+ }
+ else // reset token cursor to start of the search
+ {
+ p->curToken = startIndex;
+ }
+ }
+ clang_disposeString(tokenString);
+ p->curToken++;
+ if (p->curToken<p->numTokens)
+ {
+ l = p->getCurrentTokenLine();
+ }
+ }
+ //if (!found)
+ //{
+ // printf("Did not find symbol %s at line %d :-(\n",symbol,line);
+ //}
+ //else
+ //{
+ // printf("Found symbol %s usr=%s\n",symbol,result.data());
+ //}
+ return result;
+}
+
+static QCString keywordToType(const char *keyword)
+{
+ static bool init=TRUE;
+ static QDict<void> flowKeywords(47);
+ static QDict<void> typeKeywords(47);
+ if (init)
+ {
+ flowKeywords.insert("break",(void*)0x8);
+ flowKeywords.insert("case",(void*)0x8);
+ flowKeywords.insert("catch",(void*)0x8);
+ flowKeywords.insert("continue",(void*)0x8);
+ flowKeywords.insert("default",(void*)0x8);
+ flowKeywords.insert("do",(void*)0x8);
+ flowKeywords.insert("else",(void*)0x8);
+ flowKeywords.insert("finally",(void*)0x8);
+ flowKeywords.insert("for",(void*)0x8);
+ flowKeywords.insert("foreach",(void*)0x8);
+ flowKeywords.insert("for each",(void*)0x8);
+ flowKeywords.insert("goto",(void*)0x8);
+ flowKeywords.insert("if",(void*)0x8);
+ flowKeywords.insert("return",(void*)0x8);
+ flowKeywords.insert("switch",(void*)0x8);
+ flowKeywords.insert("throw",(void*)0x8);
+ flowKeywords.insert("throws",(void*)0x8);
+ flowKeywords.insert("try",(void*)0x8);
+ flowKeywords.insert("while",(void*)0x8);
+ flowKeywords.insert("@try",(void*)0x8);
+ flowKeywords.insert("@catch",(void*)0x8);
+ flowKeywords.insert("@finally",(void*)0x8);
+
+ typeKeywords.insert("bool",(void*)0x8);
+ typeKeywords.insert("char",(void*)0x8);
+ typeKeywords.insert("double",(void*)0x8);
+ typeKeywords.insert("float",(void*)0x8);
+ typeKeywords.insert("int",(void*)0x8);
+ typeKeywords.insert("long",(void*)0x8);
+ typeKeywords.insert("object",(void*)0x8);
+ typeKeywords.insert("short",(void*)0x8);
+ typeKeywords.insert("signed",(void*)0x8);
+ typeKeywords.insert("unsigned",(void*)0x8);
+ typeKeywords.insert("void",(void*)0x8);
+ typeKeywords.insert("wchar_t",(void*)0x8);
+ typeKeywords.insert("size_t",(void*)0x8);
+ typeKeywords.insert("boolean",(void*)0x8);
+ typeKeywords.insert("id",(void*)0x8);
+ typeKeywords.insert("SEL",(void*)0x8);
+ typeKeywords.insert("string",(void*)0x8);
+ typeKeywords.insert("nullptr",(void*)0x8);
+ init=FALSE;
+ }
+ if (flowKeywords[keyword]) return "keywordflow";
+ if (typeKeywords[keyword]) return "keywordtype";
+ return "keyword";
+}
+
+static void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
+{
+ Definition *d = fd ? fd->getSourceDefinition(line) : 0;
+ if (d && d->isLinkable())
+ {
+ g_currentDefinition=d;
+ g_currentLine=line;
+ MemberDef *md = fd->getSourceMember(line);
+ if (md && md->isLinkable()) // link to member
+ {
+ if (g_currentMemberDef!=md) // new member, start search for body
+ {
+ g_searchForBody=TRUE;
+ g_insideBody=FALSE;
+ g_bracketCount=0;
+ }
+ g_currentMemberDef=md;
+ ol.writeLineNumber(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),
+ line);
+ }
+ else // link to compound
+ {
+ g_currentMemberDef=0;
+ ol.writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ d->anchor(),
+ line);
+ }
+ }
+ else // no link
+ {
+ ol.writeLineNumber(0,0,0,line);
+ }
+
+ // set search page target
+ if (Doxygen::searchIndex)
+ {
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",line);
+ ol.setCurrentDoc(fd,lineAnchor,TRUE);
+ }
+
+ //printf("writeLineNumber(%d) g_searchForBody=%d\n",line,g_searchForBody);
+}
+
+static void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
+ uint &line,uint &column,const char *fontClass=0)
+{
+ if (fontClass) ol.startFontClass(fontClass);
+ const char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') { column++; }
+ if (c=='\n')
+ {
+ line++;
+ int l = (int)(p-sp-1);
+ column=l+1;
+ char *tmp = (char*)malloc(l+1);
+ memcpy(tmp,sp,l);
+ tmp[l]='\0';
+ ol.codify(tmp);
+ free(tmp);
+ if (fontClass) ol.endFontClass();
+ ol.endCodeLine();
+ ol.startCodeLine(TRUE);
+ writeLineNumber(ol,fd,line);
+ if (fontClass) ol.startFontClass(fontClass);
+ }
+ else
+ {
+ ol.codify(sp);
+ done=TRUE;
+ }
+ }
+ if (fontClass) ol.endFontClass();
+}
+
+static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ FileDef *fd,uint &line,uint &column,
+ Definition *d,
+ const char *text)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ TooltipManager::instance()->addTooltip(d);
+ QCString ref = d->getReference();
+ QCString file = d->getOutputFileBase();
+ QCString anchor = d->anchor();
+ QCString tooltip;
+ if (!sourceTooltips) // fall back to simple "title" tooltips
+ {
+ tooltip = d->briefDescriptionAsTooltip();
+ }
+ bool done=FALSE;
+ char *p=(char *)text;
+ while (!done)
+ {
+ char *sp=p;
+ char c;
+ while ((c=*p++) && c!='\n') { column++; }
+ if (c=='\n')
+ {
+ line++;
+ *(p-1)='\0';
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ ol.endCodeLine();
+ ol.startCodeLine(TRUE);
+ writeLineNumber(ol,fd,line);
+ }
+ else
+ {
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ done=TRUE;
+ }
+ }
+}
+
+void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,const char *text)
+{
+ QCString incName = text;
+ incName = incName.mid(1,incName.length()-2); // strip ".." or <..>
+ FileDef *ifd=0;
+ if (!incName.isEmpty())
+ {
+ FileName *fn = Doxygen::inputNameDict->find(incName);
+ if (fn)
+ {
+ bool found=false;
+ FileNameIterator fni(*fn);
+ // for each include name
+ for (fni.toFirst();!found && (ifd=fni.current());++fni)
+ {
+ // see if this source file actually includes the file
+ found = fd->isIncluded(ifd->absFilePath());
+ //printf(" include file %s found=%d\n",ifd->absFilePath().data(),found);
+ }
+ }
+ }
+ if (ifd)
+ {
+ ol.writeCodeLink(ifd->getReference(),ifd->getOutputFileBase(),0,text,ifd->briefDescriptionAsTooltip());
+ }
+ else
+ {
+ codifyLines(ol,ifd,text,line,column,"preprocessor");
+ }
+}
+
+void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,const char *text)
+{
+ MemberName *mn=Doxygen::functionNameSDict->find(text);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->isDefine())
+ {
+ writeMultiLineCodeLink(ol,fd,line,column,md,text);
+ return;
+ }
+ }
+ }
+ codifyLines(ol,fd,text,line,column);
+}
+
+
+void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,const char *text,int tokenIndex)
+{
+ CXCursor c = p->cursors[tokenIndex];
+ CXCursor r = clang_getCursorReferenced(c);
+ if (!clang_equalCursors(r, c))
+ {
+ c=r; // link to referenced location
+ }
+ CXCursor t = clang_getSpecializedCursorTemplate(c);
+ if (!clang_Cursor_isNull(t) && !clang_equalCursors(t,c))
+ {
+ c=t; // link to template
+ }
+ CXString usr = clang_getCursorUSR(c);
+ const char *usrStr = clang_getCString(usr);
+
+ Definition *d = usrStr ? Doxygen::clangUsrMap->find(usrStr) : 0;
+ //CXCursorKind kind = clang_getCursorKind(c);
+ //if (d==0)
+ //{
+ // printf("didn't find definition for '%s' usr='%s' kind=%d\n",
+ // text,usrStr,kind);
+ //}
+ //else
+ //{
+ // printf("found definition for '%s' usr='%s' name='%s'\n",
+ // text,usrStr,d->name().data());
+ //}
+ if (d && d->isLinkable())
+ {
+ if (g_insideBody &&
+ g_currentMemberDef && d->definitionType()==Definition::TypeMember &&
+ (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference
+ {
+ addDocCrossReference(g_currentMemberDef,(MemberDef*)d);
+ }
+ writeMultiLineCodeLink(ol,fd,line,column,d,text);
+ }
+ else
+ {
+ codifyLines(ol,fd,text,line,column);
+ }
+ clang_disposeString(usr);
+}
+
+static void detectFunctionBody(const char *s)
+{
+ //printf("punct=%s g_searchForBody=%d g_insideBody=%d g_bracketCount=%d\n",
+ // s,g_searchForBody,g_insideBody,g_bracketCount);
+
+ if (g_searchForBody && (qstrcmp(s,":")==0 || qstrcmp(s,"{")==0)) // start of 'body' (: is for constructor)
+ {
+ g_searchForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ else if (g_searchForBody && qstrcmp(s,";")==0) // declaration only
+ {
+ g_searchForBody=FALSE;
+ g_insideBody=FALSE;
+ }
+ if (g_insideBody && qstrcmp(s,"{")==0) // increase scoping level
+ {
+ g_bracketCount++;
+ }
+ if (g_insideBody && qstrcmp(s,"}")==0) // decrease scoping level
+ {
+ g_bracketCount--;
+ if (g_bracketCount<=0) // got outside of function body
+ {
+ g_insideBody=FALSE;
+ g_bracketCount=0;
+ }
+ }
+}
+
+void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
+{
+ TooltipManager::instance()->clearTooltips();
+ // (re)set global parser state
+ g_currentDefinition=0;
+ g_currentMemberDef=0;
+ g_currentLine=0;
+ g_searchForBody=FALSE;
+ g_insideBody=FALSE;
+ g_bracketCount=0;
+
+ unsigned int line=1,column=1;
+ QCString lineNumber,lineAnchor;
+ ol.startCodeLine(TRUE);
+ writeLineNumber(ol,fd,line);
+ for (unsigned int i=0;i<p->numTokens;i++)
+ {
+ CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]);
+ unsigned int l, c;
+ clang_getSpellingLocation(start, 0, &l, &c, 0);
+ if (l > line) column = 1;
+ while (line<l)
+ {
+ line++;
+ ol.endCodeLine();
+ ol.startCodeLine(TRUE);
+ writeLineNumber(ol,fd,line);
+ }
+ while (column<c) { ol.codify(" "); column++; }
+ CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]);
+ char const *s = clang_getCString(tokenString);
+ CXCursorKind cursorKind = clang_getCursorKind(p->cursors[i]);
+ CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]);
+ //printf("%d:%d %s cursorKind=%d tokenKind=%d\n",line,column,s,cursorKind,tokenKind);
+ switch (tokenKind)
+ {
+ case CXToken_Keyword:
+ if (strcmp(s,"operator")==0)
+ {
+ linkIdentifier(ol,fd,line,column,s,i);
+ }
+ else
+ {
+ codifyLines(ol,fd,s,line,column,
+ cursorKind==CXCursor_PreprocessingDirective ? "preprocessor" :
+ keywordToType(s));
+ }
+ break;
+ case CXToken_Literal:
+ if (cursorKind==CXCursor_InclusionDirective)
+ {
+ linkInclude(ol,fd,line,column,s);
+ }
+ else if (s[0]=='"' || s[0]=='\'')
+ {
+ codifyLines(ol,fd,s,line,column,"stringliteral");
+ }
+ else
+ {
+ codifyLines(ol,fd,s,line,column);
+ }
+ break;
+ case CXToken_Comment:
+ codifyLines(ol,fd,s,line,column,"comment");
+ break;
+ default: // CXToken_Punctuation or CXToken_Identifier
+ if (tokenKind==CXToken_Punctuation)
+ {
+ detectFunctionBody(s);
+ //printf("punct %s: %d\n",s,cursorKind);
+ }
+ switch (cursorKind)
+ {
+ case CXCursor_PreprocessingDirective:
+ codifyLines(ol,fd,s,line,column,"preprocessor");
+ break;
+ case CXCursor_MacroDefinition:
+ codifyLines(ol,fd,s,line,column,"preprocessor");
+ break;
+ case CXCursor_InclusionDirective:
+ linkInclude(ol,fd,line,column,s);
+ break;
+ case CXCursor_MacroExpansion:
+ linkMacro(ol,fd,line,column,s);
+ break;
+ default:
+ if (tokenKind==CXToken_Identifier ||
+ (tokenKind==CXToken_Punctuation && // for operators
+ (cursorKind==CXCursor_DeclRefExpr ||
+ cursorKind==CXCursor_MemberRefExpr ||
+ cursorKind==CXCursor_CallExpr ||
+ cursorKind==CXCursor_ObjCMessageExpr)
+ )
+ )
+ {
+ linkIdentifier(ol,fd,line,column,s,i);
+ if (Doxygen::searchIndex)
+ {
+ ol.addWord(s,FALSE);
+ }
+ }
+ else
+ {
+ codifyLines(ol,fd,s,line,column);
+ }
+ break;
+ }
+ }
+ clang_disposeString(tokenString);
+ }
+ ol.endCodeLine();
+ TooltipManager::instance()->writeTooltips(ol);
+}
+
+ClangParser::ClangParser()
+{
+ p = new Private;
+}
+
+ClangParser::~ClangParser()
+{
+ delete p;
+}
+
+//--------------------------------------------------------------------------
+#else // use stubbed functionality in case libclang support is disabled.
+
+void ClangParser::start(const char *,QStrList &)
+{
+}
+
+void ClangParser::switchToFile(const char *)
+{
+}
+
+void ClangParser::finish()
+{
+}
+
+QCString ClangParser::lookup(uint,const char *)
+{
+ return "";
+}
+
+void ClangParser::writeSources(CodeOutputInterface &,FileDef *)
+{
+}
+
+ClangParser::ClangParser()
+{
+}
+
+ClangParser::~ClangParser()
+{
+}
+
+
+#endif
+//--------------------------------------------------------------------------
+
diff --git a/src/clangparser.h b/src/clangparser.h
new file mode 100644
index 0000000..6072208
--- /dev/null
+++ b/src/clangparser.h
@@ -0,0 +1,67 @@
+#ifndef CLANGPARSER_H
+#define CLANGPARSER_H
+
+#include <qcstring.h>
+#include <qstrlist.h>
+
+class CodeOutputInterface;
+class FileDef;
+
+/** @brief Wrapper for to let libclang assisted parsing. */
+class ClangParser
+{
+ public:
+ /** Returns the one and only instance of the class */
+ static ClangParser *instance();
+
+ /** Start parsing a file.
+ * @param[in] fileName The name of the file to parse.
+ * @param[in,out] filesInTranslationUnit Other files that are
+ * part of the input and included by the file.
+ * The function will return a subset of the files,
+ * only including the onces that were actually found
+ * during parsing.
+ */
+ void start(const char *fileName,QStrList &filesInTranslationUnit);
+
+ /** Switches to another file within the translation unit started
+ * with start().
+ * @param[in] fileName The name of the file to switch to.
+ */
+ void switchToFile(const char *fileName);
+
+ /** Finishes parsing a translation unit. Free any resources that
+ * were needed for parsing.
+ */
+ void finish();
+
+ /** Looks for \a symbol which should be found at \a line and
+ * returns a clang unique reference to the symbol.
+ */
+ QCString lookup(uint line,const char *symbol);
+
+ /** writes the syntax highlighted source code for a file
+ * @param[out] ol The output generator list to write to.
+ * @param[in] fd The file to write sources for.
+ */
+ void writeSources(CodeOutputInterface &ol,FileDef *fd);
+
+ private:
+ void linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,
+ const char *text,int tokenIndex);
+ void linkMacro(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,
+ const char *text);
+ void linkInclude(CodeOutputInterface &ol,FileDef *fd,
+ uint &line,uint &column,
+ const char *text);
+ void determineInputFilesInSameTu(QStrList &filesInTranslationUnit);
+ class Private;
+ Private *p;
+ ClangParser();
+ virtual ~ClangParser();
+ static ClangParser *s_instance;
+};
+
+#endif
diff --git a/src/classdef.cpp b/src/classdef.cpp
new file mode 100644
index 0000000..c36a83f
--- /dev/null
+++ b/src/classdef.cpp
@@ -0,0 +1,4623 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include "classdef.h"
+#include "classlist.h"
+#include "entry.h"
+#include "doxygen.h"
+#include "membername.h"
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "diagram.h"
+#include "language.h"
+#include "htmlhelp.h"
+#include "example.h"
+#include "outputlist.h"
+#include "dot.h"
+#include "defargs.h"
+#include "debug.h"
+#include "docparser.h"
+#include "searchindex.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "groupdef.h"
+#include "filedef.h"
+#include "namespacedef.h"
+#include "membergroup.h"
+
+//-----------------------------------------------------------------------------
+
+/** Private data associated with a ClassDef object. */
+class ClassDefImpl
+{
+ public:
+ ClassDefImpl();
+ ~ClassDefImpl();
+ void init(const char *defFileName, const char *name,
+ const QCString &ctStr, const char *fName);
+
+ /*! file name that forms the base for the output file containing the
+ * class documentation. For compatibility with Qt (e.g. links via tag
+ * files) this name cannot be derived from the class name directly.
+ */
+ QCString fileName;
+
+ /*! Include information about the header file should be included
+ * in the documentation. 0 by default, set by setIncludeFile().
+ */
+ IncludeInfo *incInfo;
+
+ /*! List of base class (or super-classes) from which this class derives
+ * directly.
+ */
+ BaseClassList *inherits;
+
+ /*! List of sub-classes that directly derive from this class
+ */
+ BaseClassList *inheritedBy;
+
+ /*! Namespace this class is part of
+ * (this is the inner most namespace in case of nested namespaces)
+ */
+ NamespaceDef *nspace;
+
+ /*! File this class is defined in */
+ FileDef *fileDef;
+
+ /*! List of all members (including inherited members) */
+ MemberNameInfoSDict *allMemberNameInfoSDict;
+
+ /*! Template arguments of this class */
+ ArgumentList *tempArgs;
+
+ /*! Type constraints for template parameters */
+ ArgumentList *typeConstraints;
+
+ /*! Files that were used for generating the class documentation. */
+ FileList files;
+
+ /*! Examples that use this class */
+ ExampleSDict *exampleSDict;
+
+ /*! Holds the kind of "class" this is. */
+ ClassDef::CompoundType compType;
+
+ /*! The protection level in which this class was found.
+ * Typically Public, but for nested classes this can also be Protected
+ * or Private.
+ */
+ Protection prot;
+
+ /*! The inner classes contained in this class. Will be 0 if there are
+ * no inner classes.
+ */
+ ClassSDict *innerClasses;
+
+ /* classes for the collaboration diagram */
+ UsesClassDict *usesImplClassDict;
+ UsesClassDict *usedByImplClassDict;
+ UsesClassDict *usesIntfClassDict;
+
+ /*! Template instances that exists of this class, the key in the
+ * dictionary is the template argument list.
+ */
+ QDict<ClassDef> *templateInstances;
+
+ /*! Template instances that exists of this class, as defined by variables.
+ * We do NOT want to document these individually. The key in the
+ * dictionary is the template argument list.
+ */
+ QDict<ClassDef> *variableInstances;
+
+ QDict<int> *templBaseClassNames;
+
+ /*! The class this class is an instance of. */
+ ClassDef *templateMaster;
+
+ /*! local class name which could be a typedef'ed alias name. */
+ QCString className;
+
+ /*! If this class is a Objective-C category, then this points to the
+ * class which is extended.
+ */
+ ClassDef *categoryOf;
+
+ QList<MemberList> memberLists;
+
+ /* user defined member groups */
+ MemberGroupSDict *memberGroupSDict;
+
+ /*! Is this an abstact class? */
+ bool isAbstract;
+
+ /*! Is the class part of an unnamed namespace? */
+ bool isStatic;
+
+ /*! TRUE if classes members are merged with those of the base classes. */
+ bool membersMerged;
+
+ /*! TRUE if the class is defined in a source file rather than a header file. */
+ bool isLocal;
+
+ bool isTemplArg;
+
+ /*! Does this class group its user-grouped members
+ * as a sub-section of the normal (public/protected/..)
+ * groups?
+ */
+ bool subGrouping;
+
+ /** Reason of existence is a "use" relation */
+ bool usedOnly;
+
+ /** List of titles to use for the summary */
+ SDict<QCString> vhdlSummaryTitles;
+
+ /** Is this a simple (non-nested) C structure? */
+ bool isSimple;
+
+ /** Does this class overloaded the -> operator? */
+ MemberDef *arrowOperator;
+
+ ClassList *taggedInnerClasses;
+ ClassDef *tagLessRef;
+
+ /** Does this class represent a Java style enum? */
+ bool isJavaEnum;
+
+ bool isGeneric;
+
+ bool isAnonymous;
+
+ uint64 spec;
+};
+
+void ClassDefImpl::init(const char *defFileName, const char *name,
+ const QCString &ctStr, const char *fName)
+{
+ if (fName)
+ {
+ fileName=stripExtension(fName);
+ }
+ else
+ {
+ fileName=ctStr+name;
+ }
+ exampleSDict = 0;
+ inherits = 0;
+ inheritedBy = 0;
+ allMemberNameInfoSDict = 0;
+ incInfo=0;
+ tempArgs=0;
+ typeConstraints=0;
+ prot=Public;
+ nspace=0;
+ fileDef=0;
+ usesImplClassDict=0;
+ usedByImplClassDict=0;
+ usesIntfClassDict=0;
+ memberGroupSDict = 0;
+ innerClasses = 0;
+ subGrouping=Config_getBool("SUBGROUPING");
+ templateInstances = 0;
+ variableInstances = 0;
+ templateMaster =0;
+ templBaseClassNames = 0;
+ isAbstract = FALSE;
+ isStatic = FALSE;
+ isTemplArg = FALSE;
+ membersMerged = FALSE;
+ categoryOf = 0;
+ usedOnly = FALSE;
+ isSimple = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ arrowOperator = 0;
+ taggedInnerClasses = 0;
+ tagLessRef = 0;
+ spec=0;
+ //QCString ns;
+ //extractNamespaceName(name,className,ns);
+ //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
+
+ // we cannot use getLanguage at this point, as setLanguage has not been called.
+ SrcLangExt lang = getLanguageFromFileName(defFileName);
+ if ((lang==SrcLangExt_Cpp || lang==SrcLangExt_ObjC) &&
+ guessSection(defFileName)==Entry::SOURCE_SEC)
+ {
+ isLocal=TRUE;
+ }
+ else
+ {
+ isLocal=FALSE;
+ }
+ isGeneric = (lang==SrcLangExt_CSharp || lang==SrcLangExt_Java) && QCString(name).find('<')!=-1;
+ isAnonymous = QCString(name).find('@')!=-1;
+}
+
+ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)
+{
+ vhdlSummaryTitles.setAutoDelete(TRUE);
+}
+
+ClassDefImpl::~ClassDefImpl()
+{
+ delete inherits;
+ delete inheritedBy;
+ delete allMemberNameInfoSDict;
+ delete exampleSDict;
+ delete usesImplClassDict;
+ delete usedByImplClassDict;
+ delete usesIntfClassDict;
+ delete incInfo;
+ delete memberGroupSDict;
+ delete innerClasses;
+ delete templateInstances;
+ delete variableInstances;
+ delete templBaseClassNames;
+ delete tempArgs;
+ delete typeConstraints;
+ delete taggedInnerClasses;
+}
+
+// constructs a new class definition
+ClassDef::ClassDef(
+ const char *defFileName,int defLine,int defColumn,
+ const char *nm,CompoundType ct,
+ const char *lref,const char *fName,
+ bool isSymbol,bool isJavaEnum)
+ : Definition(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol)
+{
+ visited=FALSE;
+ setReference(lref);
+ m_impl = new ClassDefImpl;
+ m_impl->compType = ct;
+ m_impl->isJavaEnum = isJavaEnum;
+ m_impl->init(defFileName,name(),compoundTypeString(),fName);
+}
+
+// destroy the class definition
+ClassDef::~ClassDef()
+{
+ delete m_impl;
+}
+
+QCString ClassDef::getMemberListFileName() const
+{
+ return convertNameToFile(compoundTypeString()+name()+"-members");
+}
+
+QCString ClassDef::displayName(bool includeScope) const
+{
+ //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ SrcLangExt lang = getLanguage();
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString n;
+ if (lang==SrcLangExt_VHDL)
+ {
+ n = VhdlDocGen::getClassName(this);
+ }
+ else
+ {
+ if (includeScope)
+ {
+ n=qualifiedNameWithTemplateParameters();
+ }
+ else
+ {
+ n=className();
+ }
+ }
+ QCString sep=getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ n=substitute(n,"::",sep);
+ }
+ if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
+ {
+ n="<"+n.left(n.length()-2)+">";
+ }
+ //else if (n.right(2)=="-g")
+ //{
+ // n = n.left(n.length()-2);
+ //}
+ //printf("ClassDef::displayName()=%s\n",n.data());
+ if (n.find('@')!=-1)
+ {
+ return removeAnonymousScopes(n);
+ }
+ else
+ {
+ return n;
+ }
+}
+
+// inserts a base/super class in the inheritance list
+void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,
+ Specifier s,const char *t)
+{
+ //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
+ //inherits->inSort(new BaseClassDef(cd,p,s,t));
+ if (m_impl->inherits==0)
+ {
+ m_impl->inherits = new BaseClassList;
+ m_impl->inherits->setAutoDelete(TRUE);
+ }
+ m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
+ m_impl->isSimple = FALSE;
+}
+
+// inserts a derived/sub class in the inherited-by list
+void ClassDef::insertSubClass(ClassDef *cd,Protection p,
+ Specifier s,const char *t)
+{
+ //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ if (!extractPrivate && cd->protection()==Private) return;
+ if (m_impl->inheritedBy==0)
+ {
+ m_impl->inheritedBy = new BaseClassList;
+ m_impl->inheritedBy->setAutoDelete(TRUE);
+ }
+ m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
+ m_impl->isSimple = FALSE;
+}
+
+void ClassDef::addMembersToMemberGroup()
+{
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
+ }
+ }
+
+ // add members inside sections to their groups
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (mg->allMembersInSameSection() && m_impl->subGrouping)
+ {
+ //printf("addToDeclarationSection(%s)\n",mg->header().data());
+ mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+// adds new member definition to the class
+void ClassDef::internalInsertMember(MemberDef *md,
+ Protection prot,
+ bool addToAllList
+ )
+{
+ //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
+ if (md->isHidden()) return;
+
+ if (getLanguage()==SrcLangExt_VHDL)
+ {
+ QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
+ if (!m_impl->vhdlSummaryTitles.find(title))
+ {
+ m_impl->vhdlSummaryTitles.append(title,new QCString(title));
+ }
+ }
+
+ if (1 /*!isReference()*/) // changed to 1 for showing members of external
+ // classes when HAVE_DOT and UML_LOOK are enabled.
+ {
+ bool isSimple=FALSE;
+
+ /********************************************/
+ /* insert member in the declaration section */
+ /********************************************/
+ if (md->isRelated() && protectionLevelVisible(prot))
+ {
+ addMemberToList(MemberListType_related,md,TRUE);
+ }
+ else if (md->isFriend())
+ {
+ addMemberToList(MemberListType_friends,md,TRUE);
+ }
+ else
+ {
+ switch (md->memberType())
+ {
+ case MemberType_Service: // UNO IDL
+ addMemberToList(MemberListType_services,md,TRUE);
+ break;
+ case MemberType_Interface: // UNO IDL
+ addMemberToList(MemberListType_interfaces,md,TRUE);
+ break;
+ case MemberType_Signal: // Qt specific
+ addMemberToList(MemberListType_signals,md,TRUE);
+ break;
+ case MemberType_DCOP: // KDE2 specific
+ addMemberToList(MemberListType_dcopMethods,md,TRUE);
+ break;
+ case MemberType_Property:
+ addMemberToList(MemberListType_properties,md,TRUE);
+ break;
+ case MemberType_Event:
+ addMemberToList(MemberListType_events,md,TRUE);
+ break;
+ case MemberType_Slot: // Qt specific
+ switch (prot)
+ {
+ case Protected:
+ case Package: // slots in packages are not possible!
+ addMemberToList(MemberListType_proSlots,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubSlots,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberListType_priSlots,md,TRUE);
+ break;
+ }
+ break;
+ default: // any of the other members
+ if (md->isStatic())
+ {
+ if (md->isVariable())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberListType_proStaticAttribs,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberListType_pacStaticAttribs,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubStaticAttribs,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberListType_priStaticAttribs,md,TRUE);
+ break;
+ }
+ }
+ else // function
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberListType_proStaticMethods,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberListType_pacStaticMethods,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubStaticMethods,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberListType_priStaticMethods,md,TRUE);
+ break;
+ }
+ }
+ }
+ else // not static
+ {
+ if (md->isVariable())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberListType_proAttribs,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberListType_pacAttribs,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubAttribs,md,TRUE);
+ isSimple=!md->isFunctionPtr();
+ break;
+ case Private:
+ addMemberToList(MemberListType_priAttribs,md,TRUE);
+ break;
+ }
+ }
+ else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberListType_proTypes,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberListType_pacTypes,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubTypes,md,TRUE);
+ isSimple=QCString(md->typeString()).find(")(")==-1;
+ break;
+ case Private:
+ addMemberToList(MemberListType_priTypes,md,TRUE);
+ break;
+ }
+ }
+ else // member function
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberListType_proMethods,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberListType_pacMethods,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberListType_pubMethods,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberListType_priMethods,md,TRUE);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (!isSimple) // not a simple field -> not a simple struct
+ {
+ m_impl->isSimple = FALSE;
+ }
+ //printf("adding %s simple=%d total_simple=%d\n",name().data(),isSimple,m_impl->isSimple);
+
+ /*******************************************************/
+ /* insert member in the detailed documentation section */
+ /*******************************************************/
+ if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
+ {
+ addMemberToList(MemberListType_relatedMembers,md,FALSE);
+ }
+ else
+ {
+ switch (md->memberType())
+ {
+ case MemberType_Service: // UNO IDL
+ addMemberToList(MemberListType_serviceMembers,md,FALSE);
+ break;
+ case MemberType_Interface: // UNO IDL
+ addMemberToList(MemberListType_interfaceMembers,md,FALSE);
+ break;
+ case MemberType_Property:
+ addMemberToList(MemberListType_propertyMembers,md,FALSE);
+ break;
+ case MemberType_Event:
+ addMemberToList(MemberListType_eventMembers,md,FALSE);
+ break;
+ case MemberType_Signal: // fall through
+ case MemberType_DCOP:
+ addMemberToList(MemberListType_functionMembers,md,FALSE);
+ break;
+ case MemberType_Slot:
+ if (protectionLevelVisible(prot))
+ {
+ addMemberToList(MemberListType_functionMembers,md,FALSE);
+ }
+ break;
+ default: // any of the other members
+ if (protectionLevelVisible(prot))
+ {
+ switch (md->memberType())
+ {
+ case MemberType_Typedef:
+ addMemberToList(MemberListType_typedefMembers,md,FALSE);
+ break;
+ case MemberType_Enumeration:
+ addMemberToList(MemberListType_enumMembers,md,FALSE);
+ break;
+ case MemberType_EnumValue:
+ addMemberToList(MemberListType_enumValMembers,md,FALSE);
+ break;
+ case MemberType_Function:
+ if (md->isConstructor() || md->isDestructor())
+ {
+ MemberList *ml = createMemberList(MemberListType_constructors);
+ ml->append(md);
+ }
+ else
+ {
+ addMemberToList(MemberListType_functionMembers,md,FALSE);
+ }
+ break;
+ case MemberType_Variable:
+ addMemberToList(MemberListType_variableMembers,md,FALSE);
+ break;
+ default:
+ err("Unexpected member type %d found!\n",md->memberType());
+ }
+ }
+ break;
+ }
+ }
+
+ /*************************************************/
+ /* insert member in the appropriate member group */
+ /*************************************************/
+ // Note: this must be done AFTER inserting the member in the
+ // regular groups
+ //addMemberToGroup(md,groupId);
+
+ }
+
+ if (md->virtualness()==Pure)
+ {
+ m_impl->isAbstract=TRUE;
+ }
+
+ if (md->name()=="operator->")
+ {
+ m_impl->arrowOperator=md;
+ }
+
+ //::addClassMemberNameToIndex(md);
+ if (addToAllList &&
+ !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
+ md->isFriend() &&
+ (QCString(md->typeString())=="friend class" ||
+ QCString(md->typeString())=="friend struct" ||
+ QCString(md->typeString())=="friend union")))
+ {
+ //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
+ MemberInfo *mi = new MemberInfo((MemberDef *)md,
+ prot,md->virtualness(),FALSE);
+ MemberNameInfo *mni=0;
+ if (m_impl->allMemberNameInfoSDict==0)
+ {
+ m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
+ m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
+ }
+ if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
+ {
+ mni->append(mi);
+ }
+ else
+ {
+ mni = new MemberNameInfo(md->name());
+ mni->append(mi);
+ m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
+ }
+ }
+}
+
+void ClassDef::insertMember(MemberDef *md)
+{
+ internalInsertMember(md,md->protection(),TRUE);
+}
+
+// compute the anchors for all members
+void ClassDef::computeAnchors()
+{
+ //ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;
+ //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ //int index = 0;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ setAnchors(ml);
+ }
+ }
+
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->setAnchors();
+ }
+ }
+}
+
+void ClassDef::distributeMemberGroupDocumentation()
+{
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->distributeMemberGroupDocumentation();
+ }
+ }
+}
+
+void ClassDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ }
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ ml->findSectionsInDocumentation();
+ }
+ }
+}
+
+
+// add a file name to the used files set
+void ClassDef::insertUsedFile(FileDef *fd)
+{
+ if (fd==0) return;
+ if (m_impl->files.find(fd)==-1) m_impl->files.append(fd);
+ if (m_impl->templateInstances)
+ {
+ QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
+ ClassDef *cd;
+ for (qdi.toFirst();(cd=qdi.current());++qdi)
+ {
+ cd->insertUsedFile(fd);
+ }
+ }
+}
+
+static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
+{
+ if (bcd->prot!=Public || bcd->virt!=Normal)
+ {
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (bcd->prot==Protected) sl.append("protected");
+ else if (bcd->prot==Private) sl.append("private");
+ if (bcd->virt==Virtual) sl.append("virtual");
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+}
+
+void ClassDef::setIncludeFile(FileDef *fd,
+ const char *includeName,bool local, bool force)
+{
+ //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
+ if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
+ if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
+ (fd!=0 && m_impl->incInfo->fileDef==0)
+ )
+ {
+ //printf("Setting file info\n");
+ m_impl->incInfo->fileDef = fd;
+ m_impl->incInfo->includeName = includeName;
+ m_impl->incInfo->local = local;
+ }
+ if (force && includeName)
+ {
+ m_impl->incInfo->includeName = includeName;
+ m_impl->incInfo->local = local;
+ }
+}
+
+// TODO: fix this: a nested template class can have multiple outer templates
+//ArgumentList *ClassDef::outerTemplateArguments() const
+//{
+// int ti;
+// ClassDef *pcd=0;
+// int pi=0;
+// if (m_impl->tempArgs) return m_impl->tempArgs;
+// // find the outer most class scope
+// while ((ti=name().find("::",pi))!=-1 &&
+// (pcd=getClass(name().left(ti)))==0
+// ) pi=ti+2;
+// if (pcd)
+// {
+// return pcd->templateArguments();
+// }
+// return 0;
+//}
+
+static void searchTemplateSpecs(/*in*/ Definition *d,
+ /*out*/ QList<ArgumentList> &result,
+ /*out*/ QCString &name)
+{
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ if (d->getOuterScope())
+ {
+ searchTemplateSpecs(d->getOuterScope(),result,name);
+ }
+ ClassDef *cd=(ClassDef *)d;
+ if (!name.isEmpty()) name+="::";
+ QCString clName = d->localName();
+ if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p")
+ {
+ clName = clName.left(clName.length()-2);
+ }
+ name+=clName;
+ bool isSpecialization = d->localName().find('<')!=-1;
+ if (cd->templateArguments())
+ {
+ result.append(cd->templateArguments());
+ if (!isSpecialization)
+ {
+ name+=tempArgListToString(cd->templateArguments());
+ }
+ }
+ }
+ else
+ {
+ name+=d->qualifiedName();
+ }
+}
+
+static void writeTemplateSpec(OutputList &ol,Definition *d,
+ const QCString &type)
+{
+ QList<ArgumentList> specs;
+ QCString name;
+ searchTemplateSpecs(d,specs,name);
+ if (specs.count()>0) // class has template scope specifiers
+ {
+ ol.startSubsubsection();
+ QListIterator<ArgumentList> spi(specs);
+ ArgumentList *al;
+ for (spi.toFirst();(al=spi.current());++spi)
+ {
+ ol.docify("template<");
+ QListIterator<Argument> ali(*al);
+ Argument *a;
+ while ((a=ali.current()))
+ {
+ ol.docify(a->type);
+ if (!a->name.isEmpty())
+ {
+ ol.docify(" ");
+ ol.docify(a->name);
+ }
+ if (a->defval.length()!=0)
+ {
+ ol.docify(" = ");
+ ol.docify(a->defval);
+ }
+ ++ali;
+ a=ali.current();
+ if (a) ol.docify(", ");
+ }
+ ol.docify(">");
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.lineBreak();
+ ol.popGeneratorState();
+ }
+ ol.docify(type.lower()+" "+name);
+ ol.endSubsubsection();
+ ol.writeString("\n");
+ }
+}
+
+void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
+{
+ if (hasBriefDescription())
+ {
+ ol.startParagraph();
+ ol.generateDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+ ol.popGeneratorState();
+
+ if (hasDetailedDescription() || exampleFlag)
+ {
+ writeMoreLink(ol,anchor());
+ }
+
+ ol.endParagraph();
+ }
+ ol.writeSynopsis();
+}
+
+void ClassDef::writeDetailedDocumentationBody(OutputList &ol)
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+
+ ol.startTextBlock();
+
+ if (getLanguage()==SrcLangExt_Cpp)
+ {
+ writeTemplateSpec(ol,this,compoundTypeString());
+ }
+
+ // repeat brief description
+ if (!briefDescription().isEmpty() && repeatBrief)
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ if (!briefDescription().isEmpty() && repeatBrief &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+ // write documentation
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
+ }
+ // write type constraints
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+
+ // write examples
+ if (hasExamples() && m_impl->exampleSDict)
+ {
+ ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
+ ol.startDescForItem();
+ //ol.startParagraph();
+ writeExample(ol,m_impl->exampleSDict);
+ //ol.endParagraph();
+ ol.endDescForItem();
+ ol.endSimpleSect();
+ }
+ //ol.newParagraph();
+ writeSourceDef(ol,name());
+ ol.endTextBlock();
+}
+
+bool ClassDef::hasDetailedDescription() const
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ return ((!briefDescription().isEmpty() && repeatBrief) ||
+ !documentation().isEmpty() ||
+ (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
+}
+
+// write the detailed description for this class
+void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
+ const QCString &title,const QCString &anchor)
+{
+ if (hasDetailedDescription() || exampleFlag)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
+ ol.popGeneratorState();
+
+ if (!anchor.isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ ol.writeAnchor(getOutputFileBase(),anchor);
+ ol.popGeneratorState();
+ }
+
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ writeDetailedDocumentationBody(ol);
+ }
+ else
+ {
+ //writeTemplateSpec(ol,this,pageType);
+ }
+}
+
+QCString ClassDef::generatedFromFiles() const
+{
+ QCString result;
+ SrcLangExt lang = getLanguage();
+ if (lang==SrcLangExt_Fortran)
+ {
+ result = theTranslator->trGeneratedFromFilesFortran(
+ getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
+ m_impl->files.count()==1);
+ }
+ else if (isJavaEnum())
+ {
+ result = theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1);
+ }
+ else if (m_impl->compType==Service)
+ {
+ result = theTranslator->trServiceGeneratedFromFiles(m_impl->files.count()==1);
+ }
+ else if (m_impl->compType==Singleton)
+ {
+ result = theTranslator->trSingletonGeneratedFromFiles(m_impl->files.count()==1);
+ }
+ else
+ {
+ result = theTranslator->trGeneratedFromFiles(
+ getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
+ m_impl->files.count()==1);
+ }
+ return result;
+}
+
+void ClassDef::showUsedFiles(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+
+
+ ol.writeRuler();
+ ol.parseText(generatedFromFiles());
+
+ bool first=TRUE;
+ QListIterator<FileDef> li(m_impl->files);
+ FileDef *fd;
+ for (;(fd=li.current());++li)
+ {
+ if (first)
+ {
+ first=FALSE;
+ ol.startItemList();
+ }
+
+ ol.startItemListItem();
+ QCString path=fd->getPath();
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ ol.docify(stripFromPath(path));
+ }
+
+ QCString fname = fd->name();
+ if (!fd->getVersion().isEmpty()) // append version if available
+ {
+ fname += " (" + fd->getVersion() + ")";
+ }
+
+ // for HTML
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ if (fd->generateSourceFile())
+ {
+ ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
+ }
+ else if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
+ fname);
+ }
+ else
+ {
+ ol.docify(fname);
+ }
+ ol.popGeneratorState();
+
+ // for other output formats
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
+ fname);
+ }
+ else
+ {
+ ol.docify(fname);
+ }
+ ol.popGeneratorState();
+
+ ol.endItemListItem();
+ }
+ if (!first) ol.endItemList();
+
+ ol.popGeneratorState();
+}
+
+int ClassDef::countInheritanceNodes()
+{
+ int count=0;
+ BaseClassDef *ibcd;
+ if (m_impl->inheritedBy)
+ {
+ BaseClassListIterator it(*m_impl->inheritedBy);
+ for (;(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ }
+ }
+ if (m_impl->inherits)
+ {
+ BaseClassListIterator it(*m_impl->inherits);
+ for (;(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ }
+ }
+ return count;
+}
+
+void ClassDef::writeInheritanceGraph(OutputList &ol)
+{
+ // count direct inheritance relations
+ int count=countInheritanceNodes();
+
+ bool renderDiagram = FALSE;
+ if (Config_getBool("HAVE_DOT") &&
+ (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))
+ // write class diagram using dot
+ {
+ DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.endDotGraph(inheritanceGraph);
+ ol.popGeneratorState();
+ renderDiagram = TRUE;
+ }
+ }
+ else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
+ // write class diagram using build-in generator
+ {
+ ClassDiagram diagram(this); // create a diagram of this class.
+ ol.startClassDiagram();
+ ol.disable(OutputGenerator::Man);
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.enable(OutputGenerator::Man);
+ ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
+ renderDiagram = TRUE;
+ }
+
+ if (renderDiagram) // if we already show the inheritance relations graphically,
+ // then hide the text version
+ {
+ ol.disableAllBut(OutputGenerator::Man);
+ }
+
+ if (m_impl->inherits && (count=m_impl->inherits->count())>0)
+ {
+ ol.startParagraph();
+ //parseText(ol,theTranslator->trInherits()+" ");
+
+ QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+
+ // use the class name but with the template arguments as given
+ // in the inheritance relation
+ QCString displayName = insertTemplateSpecifierInScope(
+ cd->displayName(),bcd->templSpecifiers);
+
+ if (cd->isLinkable())
+ {
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <base";
+ if (bcd->prot==Protected)
+ {
+ Doxygen::tagFile << " protection=\"protected\"";
+ }
+ else if (bcd->prot==Private)
+ {
+ Doxygen::tagFile << " protection=\"private\"";
+ }
+ if (bcd->virt==Virtual)
+ {
+ Doxygen::tagFile << " virtualness=\"virtual\"";
+ }
+ Doxygen::tagFile << ">" << convertToXML(cd->name())
+ << "</base>" << endl;
+ }
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ displayName);
+ }
+ else
+ {
+ ol.docify(displayName);
+ }
+ }
+ else
+ {
+ err("invalid marker %d in inherits list!\n",entryIndex);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.endParagraph();
+ }
+
+ // write subclasses
+ if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
+ {
+ ol.startParagraph();
+ QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+ if (cd->isLinkable())
+ {
+ ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
+ }
+ else
+ {
+ ol.docify(cd->displayName());
+ }
+ writeInheritanceSpecifier(ol,bcd);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.endParagraph();
+ }
+
+ if (renderDiagram)
+ {
+ ol.enableAll();
+ }
+}
+
+void ClassDef::writeCollaborationGraph(OutputList &ol)
+{
+ if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)
+ {
+ DotClassGraph usageImplGraph(this,DotNode::Collaboration);
+ if (!usageImplGraph.isTrivial())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
+ ol.endDotGraph(usageImplGraph);
+ ol.popGeneratorState();
+ }
+ }
+}
+
+QCString ClassDef::includeStatement() const
+{
+ SrcLangExt lang = getLanguage();
+ bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ if (isIDLorJava)
+ {
+ return "import";
+ }
+ else if (isObjectiveC())
+ {
+ return "#import ";
+ }
+ else
+ {
+ return "#include ";
+ }
+}
+
+void ClassDef::writeIncludeFiles(OutputList &ol)
+{
+ if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
+ {
+ QCString nm=m_impl->incInfo->includeName.isEmpty() ?
+ (m_impl->incInfo->fileDef ?
+ m_impl->incInfo->fileDef->docName().data() : ""
+ ) :
+ m_impl->incInfo->includeName.data();
+ if (!nm.isEmpty())
+ {
+ ol.startParagraph();
+ ol.startTypewriter();
+ ol.docify(includeStatement());
+ SrcLangExt lang = getLanguage();
+ bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ if (m_impl->incInfo->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify("<");
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.docify(nm);
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.enable(OutputGenerator::Html);
+ if (m_impl->incInfo->fileDef)
+ {
+ ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);
+ }
+ else
+ {
+ ol.docify(nm);
+ }
+ ol.popGeneratorState();
+ if (m_impl->incInfo->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify(">");
+ if (isIDLorJava)
+ ol.docify(";");
+ ol.endTypewriter();
+ ol.endParagraph();
+ }
+ }
+}
+
+#if 0
+void ClassDef::writeAllMembersLink(OutputList &ol)
+{
+ // write link to list of all members (HTML only)
+ if (m_impl->allMemberNameInfoSDict &&
+ !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
+ )
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startParagraph();
+ ol.startTextLink(getMemberListFileName(),0);
+ ol.parseText(theTranslator->trListOfAllMembers());
+ ol.endTextLink();
+ ol.endParagraph();
+ ol.enableAll();
+ ol.popGeneratorState();
+ }
+}
+#endif
+
+void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)
+{
+ // write user defined member groups
+ if (m_impl->memberGroupSDict)
+ {
+ m_impl->memberGroupSDict->sort();
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
+ {
+ mg->writeDeclarations(ol,this,0,0,0,showInline);
+ }
+ else // add this group to the corresponding member section
+ {
+ //printf("addToDeclarationSection(%s)\n",mg->header().data());
+ //mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
+{
+ // nested classes
+ if (m_impl->innerClasses)
+ {
+ m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
+ }
+}
+
+void ClassDef::writeInlineClasses(OutputList &ol)
+{
+ if (m_impl->innerClasses)
+ {
+ m_impl->innerClasses->writeDocumentation(ol,this);
+ }
+}
+
+void ClassDef::startMemberDocumentation(OutputList &ol)
+{
+ //printf("%s: ClassDef::startMemberDocumentation()\n",name().data());
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.disable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = TRUE;
+ }
+}
+
+void ClassDef::endMemberDocumentation(OutputList &ol)
+{
+ //printf("%s: ClassDef::endMemberDocumentation()\n",name().data());
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.enable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = FALSE;
+ }
+}
+
+void ClassDef::startMemberDeclarations(OutputList &ol)
+{
+ //printf("%s: ClassDef::startMemberDeclarations()\n",name().data());
+ ol.startMemberSections();
+}
+
+void ClassDef::endMemberDeclarations(OutputList &ol)
+{
+ //printf("%s: ClassDef::endMemberDeclarations()\n",name().data());
+ static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
+ if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
+ {
+ ol.startMemberHeader("inherited");
+ ol.parseText(theTranslator->trAdditionalInheritedMembers());
+ ol.endMemberHeader();
+ writeAdditionalInheritedMembers(ol);
+ }
+ ol.endMemberSections();
+}
+
+void ClassDef::writeAuthorSection(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.writeString("\n");
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
+ ol.popGeneratorState();
+}
+
+
+void ClassDef::writeSummaryLinks(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ bool first=TRUE;
+ SrcLangExt lang = getLanguage();
+
+ if (lang!=SrcLangExt_VHDL)
+ {
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::ClassNestedClasses &&
+ m_impl->innerClasses &&
+ m_impl->innerClasses->declVisible()
+ )
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ ol.writeSummaryLink(0,"nested-classes",ls->title(lang),first);
+ first=FALSE;
+ }
+ else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
+ m_impl->allMemberNameInfoSDict &&
+ !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
+ )
+ {
+ ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first);
+ first=FALSE;
+ }
+ else if (lde->kind()== LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList * ml = getMemberList(lmd->type);
+ if (ml && ml->declVisible())
+ {
+ ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
+ first=FALSE;
+ }
+ }
+ }
+ }
+ else // VDHL only
+ {
+ SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);
+ for (li.toFirst();li.current();++li)
+ {
+ ol.writeSummaryLink(0,li.current()->data(),li.current()->data(),first);
+ first=FALSE;
+ }
+ }
+ if (!first)
+ {
+ ol.writeString(" </div>\n");
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeTagFileMarker()
+{
+ // write section to the tag file
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"" << compoundTypeString();
+ Doxygen::tagFile << "\"";
+ if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }
+ Doxygen::tagFile << ">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
+ if (!anchor().isEmpty())
+ {
+ Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
+ }
+ QCString idStr = id();
+ if (!idStr.isEmpty())
+ {
+ Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
+ }
+ if (m_impl->tempArgs)
+ {
+ ArgumentListIterator ali(*m_impl->tempArgs);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
+ }
+ }
+ }
+}
+
+/** Write class documentation inside another container (i.e. a group) */
+void ClassDef::writeInlineDocumentation(OutputList &ol)
+{
+ bool isSimple = m_impl->isSimple;
+
+ ol.addIndexItem(name(),0);
+ //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+
+ // part 1: anchor and title
+ QCString s = compoundTypeString()+" "+name();
+
+ // part 1a
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ { // only HTML only
+ ol.writeAnchor(0,anchor());
+ ol.startMemberDoc(0,0,0,0,FALSE);
+ ol.startMemberDocName(FALSE);
+ ol.parseText(s);
+ ol.endMemberDocName();
+ ol.endMemberDoc(FALSE);
+ ol.writeString("</div>");
+ ol.startIndent();
+ }
+ ol.popGeneratorState();
+
+ // part 1b
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ { // for LaTeX/RTF only
+ ol.writeAnchor(getOutputFileBase(),anchor());
+ }
+ ol.popGeneratorState();
+
+ // part 1c
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ {
+ // for LaTeX/RTF/Man
+ ol.startGroupHeader(1);
+ ol.parseText(s);
+ ol.endGroupHeader(1);
+ }
+ ol.popGeneratorState();
+
+ SrcLangExt lang=getLanguage();
+
+ // part 2: the header and detailed description
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ {
+ // since we already shown the brief description in the
+ // declaration part of the container, so we use this to
+ // show the details on top.
+ writeDetailedDocumentationBody(ol);
+ }
+ break;
+ case LayoutDocEntry::ClassInheritanceGraph:
+ writeInheritanceGraph(ol);
+ break;
+ case LayoutDocEntry::ClassCollaborationGraph:
+ writeCollaborationGraph(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ if (!isSimple) startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (!isSimple) writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
+ }
+ break;
+ case LayoutDocEntry::MemberGroups:
+ if (!isSimple) writeMemberGroups(ol,TRUE);
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ if (!isSimple) endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ if (!isSimple) startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ if (isSimple)
+ {
+ writeSimpleMemberDocumentation(ol,lmd->type);
+ }
+ else
+ {
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
+ }
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ if (!isSimple) endMemberDocumentation(ol);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // part 3: close the block
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ { // HTML only
+ ol.endIndent();
+ }
+ ol.popGeneratorState();
+
+ // part 4: write tag file information
+ writeTagFileMarker();
+}
+
+void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
+{
+ // TODO: clean up this mess by moving it to
+ // the output generators...
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool rtfHyperlinks = Config_getBool("RTF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ // HTML only
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(getOutputFileBase(),
+ anchor.isEmpty() ? QCString("details") : anchor);
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ ol.popGeneratorState();
+
+ if (!anchor.isEmpty())
+ {
+ ol.pushGeneratorState();
+ // LaTeX + RTF
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ if (!(usePDFLatex && pdfHyperlinks))
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ if (!rtfHyperlinks)
+ {
+ ol.disable(OutputGenerator::RTF);
+ }
+ ol.docify(" ");
+ ol.startTextLink(getOutputFileBase(), anchor);
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ // RTF only
+ ol.disable(OutputGenerator::Latex);
+ ol.writeString("\\par");
+ ol.popGeneratorState();
+ }
+}
+
+bool ClassDef::visibleInParentsDeclList() const
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
+ static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
+ bool linkable = isLinkable();
+ return (!isAnonymous() && !isExtension() &&
+ (protection()!=::Private || extractPrivate) &&
+ (linkable || (!hideUndocClasses && (!isLocal() || extractLocalClasses)))
+ );
+}
+
+void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)
+{
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ SrcLangExt lang = getLanguage();
+ if (visibleInParentsDeclList())
+ {
+ if (!found) // first class
+ {
+ ol.startMemberHeader("nested-classes");
+ if (header)
+ {
+ ol.parseText(header);
+ }
+ else if (lang==SrcLangExt_VHDL)
+ {
+ ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
+ }
+ else
+ {
+ ol.parseText(lang==SrcLangExt_Fortran ?
+ theTranslator->trDataTypes() :
+ theTranslator->trCompounds());
+ }
+ ol.endMemberHeader();
+ ol.startMemberList();
+ found=TRUE;
+ }
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() &&
+ !isReference()) // skip classes found in tag files
+ {
+ Doxygen::tagFile << " <class kind=\"" << compoundTypeString()
+ << "\">" << convertToXML(name()) << "</class>" << endl;
+ }
+ ol.startMemberDeclaration();
+ ol.startMemberItem(anchor(),FALSE);
+ QCString ctype = compoundTypeString();
+ QCString cname = displayName(!localNames);
+
+ if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
+ {
+ ol.writeString(ctype);
+ ol.writeString(" ");
+ ol.insertMemberAlign();
+ }
+ if (isLinkable())
+ {
+ ol.writeObjectLink(getReference(),
+ getOutputFileBase(),
+ anchor(),
+ cname
+ );
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cname);
+ ol.endBold();
+ }
+ if (lang==SrcLangExt_VHDL) // now write the type
+ {
+ ol.writeString(" ");
+ ol.insertMemberAlign();
+ ol.writeString(VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)protection()));
+ }
+ ol.endMemberItem();
+
+ // add the brief description if available
+ if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startMemberDescription(anchor());
+ ol.writeDoc(rootNode,this,0);
+ if (isLinkableInProject())
+ {
+ writeMoreLink(ol,anchor());
+ }
+ ol.endMemberDescription();
+ }
+ delete rootNode;
+ }
+ ol.endMemberDeclaration(anchor(),0);
+ }
+}
+
+void ClassDef::addClassAttributes(OutputList &ol)
+{
+ QStrList sl;
+ if (isFinal()) sl.append("final");
+ if (isSealed()) sl.append("sealed");
+ if (isAbstract()) sl.append("abstract");
+ if (getLanguage()==SrcLangExt_IDL && isPublished()) sl.append("published");
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ if (sl.count()>0)
+ {
+ ol.startLabels();
+ const char *s=sl.first();
+ while (s)
+ {
+ const char *ns = sl.next();
+ ol.writeLabel(s,ns==0);
+ s=ns;
+ }
+ ol.endLabels();
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/)
+{
+ ol.startContents();
+
+ QCString pageType = " ";
+ pageType += compoundTypeString();
+ toupper(pageType.at(1));
+
+ writeTagFileMarker();
+
+ Doxygen::indexList->addIndexItem(this,0);
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ }
+ bool exampleFlag=hasExamples();
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang = getLanguage();
+
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol,exampleFlag);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ writeIncludeFiles(ol);
+ break;
+ case LayoutDocEntry::ClassInheritanceGraph:
+ writeInheritanceGraph(ol);
+ break;
+ case LayoutDocEntry::ClassCollaborationGraph:
+ writeCollaborationGraph(ol);
+ break;
+ case LayoutDocEntry::ClassAllMembersLink:
+ //writeAllMembersLink(ol); // this is now part of the summary links
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberGroups:
+ writeMemberGroups(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang));
+ }
+ break;
+ case LayoutDocEntry::ClassNestedClasses:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNestedClasses(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::ClassInlineClasses:
+ writeInlineClasses(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ endMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::ClassUsedFiles:
+ showUsedFiles(ol);
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileConstantGroups:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Class entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+ ol.endContents();
+}
+
+QCString ClassDef::title() const
+{
+ QCString pageTitle;
+ SrcLangExt lang = getLanguage();
+
+ if (lang==SrcLangExt_Fortran)
+ {
+ pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),
+ m_impl->compType,
+ m_impl->tempArgs != 0);
+ }
+ else if (lang==SrcLangExt_VHDL)
+ {
+ pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
+ }
+ else if (isJavaEnum())
+ {
+ pageTitle = theTranslator->trEnumReference(displayName());
+ }
+ else if (m_impl->compType==Service)
+ {
+ pageTitle = theTranslator->trServiceReference(displayName());
+ }
+ else if (m_impl->compType==Singleton)
+ {
+ pageTitle = theTranslator->trSingletonReference(displayName());
+ }
+ else
+ {
+ pageTitle = theTranslator->trCompoundReference(displayName(),
+ m_impl->compType == Interface && getLanguage()==SrcLangExt_ObjC ? Class : m_impl->compType,
+ m_impl->tempArgs != 0);
+ }
+ return pageTitle;
+}
+
+// write all documentation for this class
+void ClassDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString pageTitle = title();
+
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView);
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+
+ startTitle(ol,getOutputFileBase(),this);
+ ol.parseText(pageTitle);
+ addClassAttributes(ol);
+ addGroupListToTitle(ol,this);
+ endTitle(ol,getOutputFileBase(),displayName());
+ writeDocumentationContents(ol,pageTitle);
+
+ endFileWithNavPath(this,ol);
+
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ writeMemberPages(ol);
+ }
+}
+
+void ClassDef::writeMemberPages(OutputList &ol)
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //// Member definitions on separate pages
+ ///////////////////////////////////////////////////////////////////////////
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ ml->countDocMembers();
+ if (ml->numDocMembers()>0 && (ml->listType()&MemberListType_detailedLists))
+ {
+ ml->writeDocumentationPage(ol,displayName(),this);
+ }
+ }
+
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
+{
+ static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
+
+ ol.writeString(" <div class=\"navtab\">\n");
+ ol.writeString(" <table>\n");
+
+ if (m_impl->allMemberNameInfoSDict)
+ {
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->getClassDef()==this && md->isLinkable() && !md->isEnumValue())
+ {
+ ol.writeString(" <tr><td class=\"navtab\">");
+ if (md->isLinkableInProject())
+ {
+ if (md==currentMd) // selected item => highlight
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ ol.writeString("href=\"");
+ if (createSubDirs) ol.writeString("../../");
+ ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
+ ol.writeString("\">");
+ ol.writeString(convertToHtml(md->name()));
+ ol.writeString("</a>");
+ }
+ ol.writeString("</td></tr>\n");
+ }
+ }
+ }
+ }
+
+ ol.writeString(" </table>\n");
+ ol.writeString(" </div>\n");
+}
+
+
+
+void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)
+{
+ // write inner classes after the parent, so the tag files contain
+ // the definition in proper order!
+ if (m_impl->innerClasses)
+ {
+ ClassSDict::Iterator cli(*m_impl->innerClasses);
+ ClassDef *innerCd;
+ for (cli.toFirst();(innerCd=cli.current());++cli)
+ {
+ if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
+ protectionLevelVisible(innerCd->protection()) &&
+ !innerCd->isEmbeddedInOuterScope()
+ )
+ {
+ msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
+ innerCd->writeDocumentation(ol);
+ innerCd->writeMemberList(ol);
+ }
+ innerCd->writeDocumentationForInnerClasses(ol);
+ }
+ }
+}
+
+// write the list of all (inherited) members for this class
+void ClassDef::writeMemberList(OutputList &ol)
+{
+ static bool cOpt = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
+ // only for HTML
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString memListFile = getMemberListFileName();
+ startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),
+ HLI_ClassVisible,!generateTreeView,getOutputFileBase());
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+ startTitle(ol,0);
+ ol.parseText(displayName()+" "+theTranslator->trMemberList());
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startParagraph();
+ ol.parseText(theTranslator->trThisIsTheListOfAllMembers());
+ ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),displayName());
+ ol.parseText(theTranslator->trIncludingInheritedMembers());
+ ol.endParagraph();
+
+ //ol.startItemList();
+ ol.writeString("<table class=\"directory\">\n");
+
+ int idx=0;
+ //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
+ MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberNameInfoIterator it(*mni);
+ MemberInfo *mi;
+ for (;(mi=it.current());++it)
+ {
+ MemberDef *md=mi->memberDef;
+ ClassDef *cd=md->getClassDef();
+ Protection prot = mi->prot;
+ Specifier virt=md->virtualness();
+
+ //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
+ // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
+
+ if (cd && !md->name().isEmpty() && md->name()[0]!='@')
+ {
+ bool memberWritten=FALSE;
+ if (cd->isLinkable() && md->isLinkable())
+ // create a link to the documentation
+ {
+ QCString name=mi->ambiguityResolutionScope+md->name();
+ //ol.writeListItem();
+ ol.writeString(" <tr");
+ if ((idx&1)==0) ol.writeString(" class=\"even\"");
+ idx++;
+ ol.writeString("><td class=\"entry\">");
+ if (cd->isObjectiveC())
+ {
+ if (md->isObjCMethod())
+ {
+ if (md->isStatic())
+ ol.writeString("+ </td><td>");
+ else
+ ol.writeString("- </td><td>");
+ }
+ else
+ ol.writeString("</td><td class=\"entry\">");
+ }
+ if (md->isObjCMethod())
+ {
+ ol.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),md->name());
+ }
+ else
+ {
+ //Definition *bd = md->getGroupDef();
+ //if (bd==0) bd=cd;
+ ol.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),name);
+
+ if ( md->isFunction() || md->isSignal() || md->isSlot() ||
+ (md->isFriend() && md->argsString()))
+ ol.docify(md->argsString());
+ else if (md->isEnumerate())
+ ol.parseText(" "+theTranslator->trEnumName());
+ else if (md->isEnumValue())
+ ol.parseText(" "+theTranslator->trEnumValue());
+ else if (md->isTypedef())
+ ol.docify(" typedef");
+ else if (md->isFriend() && !qstrcmp(md->typeString(),"friend class"))
+ ol.docify(" class");
+ //ol.writeString("\n");
+ }
+ ol.writeString("</td>");
+ memberWritten=TRUE;
+ }
+ else if (!cd->isArtificial() &&
+ !Config_getBool("HIDE_UNDOC_MEMBERS") &&
+ (protectionLevelVisible(md->protection()) || md->isFriend())
+ ) // no documentation,
+ // generate link to the class instead.
+ {
+ //ol.writeListItem();
+ ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
+ if ((idx&1)==0) ol.writeString(" class=\"even\"");
+ idx++;
+ ol.writeString("><td class=\"entry\">");
+ if (cd->isObjectiveC())
+ {
+ if (md->isObjCMethod())
+ {
+ if (md->isStatic())
+ ol.writeString("+ </td><td class=\"entry\">");
+ else
+ ol.writeString("- </td><td class=\"entry\">");
+ }
+ else
+ ol.writeString("</td><td class=\"entry\">");
+ }
+ ol.startBold();
+ ol.docify(md->name());
+ ol.endBold();
+ if (!md->isObjCMethod())
+ {
+ if ( md->isFunction() || md->isSignal() || md->isSlot() )
+ ol.docify(md->argsString());
+ else if (md->isEnumerate())
+ ol.parseText(" "+theTranslator->trEnumName());
+ else if (md->isEnumValue())
+ ol.parseText(" "+theTranslator->trEnumValue());
+ else if (md->isTypedef())
+ ol.docify(" typedef");
+ }
+ ol.writeString(" (");
+ ol.parseText(theTranslator->trDefinedIn()+" ");
+ if (cd->isLinkable())
+ {
+ ol.writeObjectLink(
+ cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ cd->displayName());
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cd->displayName());
+ ol.endBold();
+ }
+ ol.writeString(")");
+ ol.writeString("</td>");
+ memberWritten=TRUE;
+ }
+ if (memberWritten)
+ {
+ ol.writeString("<td class=\"entry\">");
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ md->category() ?
+ md->category()->displayName() :
+ cd->displayName());
+ ol.writeString("</td>");
+ ol.writeString("<td class=\"entry\">");
+ }
+ SrcLangExt lang = md->getLanguage();
+ if (
+ (prot!=Public || (virt!=Normal && getLanguage()!=SrcLangExt_ObjC) ||
+ md->isFriend() || md->isRelated() || md->isExplicit() ||
+ md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
+ md->isSignal() || md->isSlot() ||
+ (getLanguage()==SrcLangExt_IDL &&
+ (md->isOptional() || md->isAttribute() || md->isUNOProperty())) ||
+ md->isStatic() || lang==SrcLangExt_VHDL
+ )
+ && memberWritten)
+ {
+ ol.writeString("<span class=\"mlabel\">");
+ QStrList sl;
+ if (lang==SrcLangExt_VHDL)
+ {
+ sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type
+ }
+ else if (md->isFriend()) sl.append("friend");
+ else if (md->isRelated()) sl.append("related");
+ else
+ {
+ if (Config_getBool("INLINE_INFO") && md->isInline())
+ sl.append("inline");
+ if (md->isExplicit()) sl.append("explicit");
+ if (md->isMutable()) sl.append("mutable");
+ if (prot==Protected) sl.append("protected");
+ else if (prot==Private) sl.append("private");
+ else if (prot==Package) sl.append("package");
+ if (virt==Virtual && getLanguage()!=SrcLangExt_ObjC)
+ sl.append("virtual");
+ else if (virt==Pure) sl.append("pure virtual");
+ if (md->isStatic()) sl.append("static");
+ if (md->isSignal()) sl.append("signal");
+ if (md->isSlot()) sl.append("slot");
+// this is the extra member page
+ if (md->isOptional()) sl.append("optional");
+ if (md->isAttribute()) sl.append("attribute");
+ if (md->isUNOProperty()) sl.append("property");
+ if (md->isReadonly()) sl.append("readonly");
+ if (md->isBound()) sl.append("bound");
+ if (md->isRemovable()) sl.append("removable");
+ if (md->isConstrained()) sl.append("constrained");
+ if (md->isTransient()) sl.append("transient");
+ if (md->isMaybeVoid()) sl.append("maybevoid");
+ if (md->isMaybeDefault()) sl.append("maybedefault");
+ if (md->isMaybeAmbiguous())sl.append("maybeambiguous");
+ }
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.writeString("</span><span class=\"mlabel\">");
+ }
+ ol.writeString("</span>");
+ }
+ if (memberWritten)
+ {
+ ol.writeString("</td>");
+ ol.writeString("</tr>\n");
+ }
+ }
+ }
+ }
+ //ol.endItemList();
+
+ ol.writeString("</table>");
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+
+// add a reference to an example
+bool ClassDef::addExample(const char *anchor,const char *nameStr,
+ const char *file)
+{
+ if (m_impl->exampleSDict==0)
+ {
+ m_impl->exampleSDict = new ExampleSDict;
+ m_impl->exampleSDict->setAutoDelete(TRUE);
+ }
+ if (!m_impl->exampleSDict->find(nameStr))
+ {
+ Example *e=new Example;
+ e->anchor=anchor;
+ e->name=nameStr;
+ e->file=file;
+ m_impl->exampleSDict->inSort(nameStr,e);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// returns TRUE if this class is used in an example
+bool ClassDef::hasExamples() const
+{
+ bool result=FALSE;
+ if (m_impl->exampleSDict)
+ result = m_impl->exampleSDict->count()>0;
+ return result;
+}
+
+
+void ClassDef::setTemplateArguments(ArgumentList *al)
+{
+ if (al==0) return;
+ if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
+ m_impl->tempArgs=new ArgumentList;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->tempArgs->append(new Argument(*a));
+ }
+}
+
+void ClassDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
+/*! Returns \c TRUE iff this class or a class inheriting from this class
+ * is \e not defined in an external tag file.
+ */
+bool ClassDef::hasNonReferenceSuperClass()
+{
+ bool found=!isReference() && isLinkableInProject() && !isHidden();
+ if (found)
+ {
+ return TRUE; // we're done if this class is not a reference
+ }
+ if (m_impl->inheritedBy)
+ {
+ BaseClassListIterator bcli(*m_impl->inheritedBy);
+ for ( ; bcli.current() && !found ; ++bcli ) // for each super class
+ {
+ ClassDef *bcd=bcli.current()->classDef;
+ // recurse into the super class branch
+ found = found || bcd->hasNonReferenceSuperClass();
+ if (!found)
+ {
+ // look for template instances that might have non-reference super classes
+ QDict<ClassDef> *cil = bcd->getTemplateInstances();
+ if (cil)
+ {
+ QDictIterator<ClassDef> tidi(*cil);
+ for ( ; tidi.current() && !found ; ++tidi) // for each template instance
+ {
+ // recurse into the template instance branch
+ found = found || tidi.current()->hasNonReferenceSuperClass();
+ }
+ }
+ }
+ }
+ }
+ return found;
+}
+
+/*! called from MemberDef::writeDeclaration() to (recusively) write the
+ * definition of an anonymous struct, union or class.
+ */
+void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup,
+ ClassDef *inheritedFrom,const char *inheritId)
+{
+ //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
+
+ ol.docify(compoundTypeString());
+ QCString cn = displayName(FALSE);
+ if (!cn.isEmpty())
+ {
+ ol.docify(" ");
+ if (md && isLinkable())
+ {
+ ol.writeObjectLink(0,0,md->anchor(),cn);
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cn);
+ ol.endBold();
+ }
+ }
+ ol.docify(" {");
+ ol.endMemberItem();
+
+ // write user defined member groups
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->setInGroup(inGroup);
+ mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
+ }
+ }
+
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writePlainMemberDeclaration(ol,lmd->type,inGroup,inheritedFrom,inheritId);
+ }
+ }
+}
+
+/*! a link to this class is possible within this project */
+bool ClassDef::isLinkableInProject() const
+{
+ static bool extractLocal = Config_getBool("EXTRACT_LOCAL_CLASSES");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ static bool hideUndoc = Config_getBool("HIDE_UNDOC_CLASSES");
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkableInProject();
+ }
+ else
+ {
+ return !name().isEmpty() && /* has a name */
+ !isArtificial() && !isHidden() && /* not hidden */
+ !isAnonymous() && /* not anonymous */
+ protectionLevelVisible(m_impl->prot) && /* private/internal */
+ (!m_impl->isLocal || extractLocal) && /* local */
+ (hasDocumentation() || !hideUndoc) && /* documented */
+ (!m_impl->isStatic || extractStatic) && /* static */
+ !isReference(); /* not an external reference */
+ }
+}
+
+bool ClassDef::isLinkable() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkable();
+ }
+ else
+ {
+ return isLinkableInProject() || isReference();
+ }
+}
+
+
+/*! the class is visible in a class diagram, or class hierarchy */
+bool ClassDef::isVisibleInHierarchy()
+{
+ static bool allExternals = Config_getBool("ALLEXTERNALS");
+ static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+
+ return // show all classes or a subclass is visible
+ (allExternals || hasNonReferenceSuperClass()) &&
+ // and not an anonymous compound
+ !isAnonymous() &&
+ // not an artificially introduced class
+ /*!isArtificial() &&*/ // 1.8.2: allowed these to appear
+ // and not privately inherited
+ protectionLevelVisible(m_impl->prot) &&
+ // documented or shown anyway or documentation is external
+ (hasDocumentation() ||
+ !hideUndocClasses ||
+ (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) ||
+ isReference()
+ ) &&
+ // is not part of an unnamed namespace or shown anyway
+ (!m_impl->isStatic || extractStatic);
+}
+
+bool ClassDef::hasDocumentation() const
+{
+ return Definition::hasDocumentation();
+}
+
+//----------------------------------------------------------------------
+// recursive function:
+// returns TRUE iff class definition `bcd' represents an (in)direct base
+// class of class definition `cd'.
+
+bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
+{
+ bool found=FALSE;
+ //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
+ if (level>256)
+ {
+ err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
+ return FALSE;
+ }
+ if (baseClasses())
+ {
+ // Beware: trying to optimise the iterator away using ->first() & ->next()
+ // causes bug 625531
+ BaseClassListIterator bcli(*baseClasses());
+ for ( ; bcli.current() && !found ; ++bcli)
+ {
+ ClassDef *ccd=bcli.current()->classDef;
+ if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
+ //printf("isBaseClass() baseclass %s\n",ccd->name().data());
+ if (ccd==bcd)
+ found=TRUE;
+ else
+ found=ccd->isBaseClass(bcd,followInstances,level+1);
+ }
+ }
+ return found;
+}
+
+//----------------------------------------------------------------------
+
+bool ClassDef::isSubClass(ClassDef *cd,int level)
+{
+ bool found=FALSE;
+ if (level>256)
+ {
+ err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
+ return FALSE;
+ }
+ if (subClasses())
+ {
+ BaseClassListIterator bcli(*subClasses());
+ for ( ; bcli.current() && !found ; ++bcli)
+ {
+ ClassDef *ccd=bcli.current()->classDef;
+ if (ccd==cd)
+ found=TRUE;
+ else
+ found=ccd->isSubClass(cd,level+1);
+ }
+ }
+ return found;
+}
+
+//----------------------------------------------------------------------------
+
+static bool isStandardFunc(MemberDef *md)
+{
+ return md->name()=="operator=" || // assignment operator
+ md->isConstructor() || // constructor
+ md->isDestructor(); // destructor
+}
+
+/*!
+ * recusively merges the `all members' lists of a class base
+ * with that of this class. Must only be called for classes without
+ * subclasses!
+ */
+void ClassDef::mergeMembers()
+{
+ if (m_impl->membersMerged) return;
+
+ //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ SrcLangExt lang = getLanguage();
+ QCString sep=getLanguageSpecificSeparator(lang,TRUE);
+ int sepLen = sep.length();
+
+ m_impl->membersMerged=TRUE;
+ //printf(" mergeMembers for %s\n",name().data());
+ bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );
+ if (baseClasses())
+ {
+ //printf(" => has base classes!\n");
+ BaseClassListIterator bcli(*baseClasses());
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ ClassDef *bClass=bcd->classDef;
+
+ // merge the members in the base class of this inheritance branch first
+ bClass->mergeMembers();
+
+ MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
+ MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
+
+ if (srcMnd)
+ {
+ MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
+ MemberNameInfo *srcMni;
+ for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
+ {
+ //printf(" Base member name %s\n",srcMni->memberName());
+ MemberNameInfo *dstMni;
+ if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
+ // a member with that name is already in the class.
+ // the member may hide or reimplement the one in the sub class
+ // or there may be another path to the base class that is already
+ // visited via another branch in the class hierarchy.
+ {
+ MemberNameInfoIterator srcMnii(*srcMni);
+ MemberInfo *srcMi;
+ for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
+ {
+ MemberDef *srcMd = srcMi->memberDef;
+ bool found=FALSE;
+ bool ambigue=FALSE;
+ bool hidden=FALSE;
+ MemberNameInfoIterator dstMnii(*dstMni);
+ MemberInfo *dstMi;
+ ClassDef *srcCd = srcMd->getClassDef();
+ for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
+ {
+ MemberDef *dstMd = dstMi->memberDef;
+ if (srcMd!=dstMd) // different members
+ {
+ ClassDef *dstCd = dstMd->getClassDef();
+ //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
+ if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
+ // member is in the same or a base class
+ {
+ ArgumentList *srcAl = srcMd->argumentList();
+ ArgumentList *dstAl = dstMd->argumentList();
+ found=matchArguments2(
+ srcMd->getOuterScope(),srcMd->getFileDef(),srcAl,
+ dstMd->getOuterScope(),dstMd->getFileDef(),dstAl,
+ TRUE
+ );
+ //printf(" Yes, matching (%s<->%s): %d\n",
+ // argListToString(srcMd->argumentList()).data(),
+ // argListToString(dstMd->argumentList()).data(),
+ // found);
+ hidden = hidden || !found;
+ }
+ else // member is in a non base class => multiple inheritance
+ // using the same base class.
+ {
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
+
+ QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
+ dstMi->ambiguityResolutionScope.prepend(scope);
+ ambigue=TRUE;
+ }
+ }
+ else // same members
+ {
+ // do not add if base class is virtual or
+ // if scope paths are equal or
+ // if base class is an interface (and thus implicitly virtual).
+ //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
+ if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
+ bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
+ dstMd->getClassDef()->compoundType()==Interface
+ )
+ {
+ found=TRUE;
+ }
+ else // member can be reached via multiple paths in the
+ // inheritance tree
+ {
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
+
+ QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
+ {
+ dstMi->ambiguityResolutionScope.prepend(scope);
+ }
+ ambigue=TRUE;
+ }
+ }
+ }
+ //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
+ // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
+
+ // TODO: fix the case where a member is hidden by inheritance
+ // of a member with the same name but with another prototype,
+ // while there is more than one path to the member in the
+ // base class due to multiple inheritance. In this case
+ // it seems that the member is not reachable by prefixing a
+ // scope name either (according to my compiler). Currently,
+ // this case is shown anyway.
+ if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
+ {
+ Protection prot=srcMd->protection();
+ if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
+ else if (bcd->prot==Private) prot=bcd->prot;
+
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(srcMd))
+ {
+ //printf(" insertMember `%s'\n",srcMd->name().data());
+ internalInsertMember(srcMd,prot,FALSE);
+ }
+ }
+
+ Specifier virt=srcMi->virt;
+ if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+
+ MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
+ newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
+ if (ambigue)
+ {
+ //printf("$$ New member %s %s add scope %s::\n",
+ // srcMi->ambiguityResolutionScope.data(),
+ // srcMd->name().data(),
+ // bClass->name().data());
+
+ QCString scope=bClass->name()+sep;
+ if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
+ {
+ newMi->ambiguityResolutionScope=
+ scope+srcMi->ambiguityResolutionScope.copy();
+ }
+ }
+ if (hidden)
+ {
+ if (srcMi->ambigClass==0)
+ {
+ newMi->ambigClass=bClass;
+ newMi->ambiguityResolutionScope=bClass->name()+sep;
+ }
+ else
+ {
+ newMi->ambigClass=srcMi->ambigClass;
+ newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
+ }
+ }
+ dstMni->append(newMi);
+ }
+ }
+ }
+ else // base class has a member that is not in the sub class => copy
+ {
+ // create a deep copy of the list (only the MemberInfo's will be
+ // copied, not the actual MemberDef's)
+ MemberNameInfo *newMni = 0;
+ newMni = new MemberNameInfo(srcMni->memberName());
+
+ // copy the member(s) from the base to the sub class
+ MemberNameInfoIterator mnii(*srcMni);
+ MemberInfo *mi;
+ for (;(mi=mnii.current());++mnii)
+ {
+ if (!mi->memberDef->isFriend()) // don't inherit friends
+ {
+ Protection prot = mi->prot;
+ if (bcd->prot==Protected)
+ {
+ if (prot==Public) prot=Protected;
+ }
+ else if (bcd->prot==Private)
+ {
+ prot=Private;
+ }
+ //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
+ // name().data(),mi->memberDef->name().data(),mi->prot,
+ // bcd->prot,prot);
+
+ if (mi->prot!=Private)
+ {
+ Specifier virt=mi->virt;
+ if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(mi->memberDef))
+ {
+ //printf(" insertMember `%s'\n",mi->memberDef->name().data());
+ internalInsertMember(mi->memberDef,prot,FALSE);
+ }
+ }
+ //printf("Adding!\n");
+ MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
+ newMi->scopePath=bClass->name()+sep+mi->scopePath;
+ newMi->ambigClass=mi->ambigClass;
+ newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
+ newMni->append(newMi);
+ }
+ }
+ }
+
+ if (dstMnd==0)
+ {
+ m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
+ m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
+ dstMnd = m_impl->allMemberNameInfoSDict;
+ }
+ // add it to the dictionary
+ dstMnd->append(newMni->memberName(),newMni);
+ }
+ }
+ }
+ }
+ }
+ //printf(" end mergeMembers\n");
+}
+
+//----------------------------------------------------------------------------
+
+/*! Merges the members of a Objective-C category into this class.
+ */
+void ClassDef::mergeCategory(ClassDef *category)
+{
+ static bool extractLocalMethods = Config_getBool("EXTRACT_LOCAL_METHODS");
+ bool makePrivate = category->isLocal();
+ // in case extract local methods is not enabled we don't add the methods
+ // of the category in case it is defined in the .m file.
+ if (makePrivate && !extractLocalMethods) return;
+ bool isExtension = category->isExtension();
+
+ category->setCategoryOf(this);
+ if (isExtension)
+ {
+ category->setArtificial(TRUE);
+
+ // copy base classes/protocols from extension
+ if (category->baseClasses())
+ {
+ BaseClassListIterator bcli(*category->baseClasses());
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
+ // correct bcd->classDef so that they do no longer derive from
+ // category, but from this class!
+ if (bcd->classDef->subClasses())
+ {
+ BaseClassListIterator scli(*bcd->classDef->subClasses());
+ BaseClassDef *scd;
+ for ( ; (scd=scli.current()) ; ++scli )
+ {
+ if (scd->classDef==category)
+ {
+ scd->classDef=this;
+ }
+ }
+ }
+ }
+ }
+
+ }
+ // make methods private for categories defined in the .m file
+ //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate);
+
+ MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
+ MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
+
+ if (srcMnd && dstMnd)
+ {
+ MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
+ MemberNameInfo *srcMni;
+ for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
+ {
+ MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
+ if (dstMni) // method is already defined in the class
+ {
+ //printf("Existing member %s\n",srcMni->memberName());
+ MemberInfo *dstMi = dstMni->getFirst();
+ MemberInfo *srcMi = srcMni->getFirst();
+ //if (dstMi)
+ //{
+ // Protection prot = dstMi->prot;
+ // if (makePrivate || isExtension)
+ // {
+ // prot = Private;
+ // removeMemberFromLists(dstMi->memberDef);
+ // internalInsertMember(dstMi->memberDef,prot,FALSE);
+ // }
+ //}
+ if (srcMi && dstMi)
+ {
+ combineDeclarationAndDefinition(srcMi->memberDef,dstMi->memberDef);
+ dstMi->memberDef->setCategory(category);
+ dstMi->memberDef->setCategoryRelation(srcMi->memberDef);
+ srcMi->memberDef->setCategoryRelation(dstMi->memberDef);
+ }
+ }
+ else // new method name
+ {
+ //printf("New member %s\n",srcMni->memberName());
+ // create a deep copy of the list
+ MemberNameInfo *newMni = 0;
+ newMni = new MemberNameInfo(srcMni->memberName());
+
+ // copy the member(s) from the category to this class
+ MemberNameInfoIterator mnii(*srcMni);
+ MemberInfo *mi;
+ for (;(mi=mnii.current());++mnii)
+ {
+ //printf("Adding '%s'\n",mi->memberDef->name().data());
+ Protection prot = mi->prot;
+ //if (makePrivate) prot = Private;
+ MemberDef *newMd = mi->memberDef->deepCopy();
+ //printf("Copying member %s\n",mi->memberDef->name().data());
+ newMd->moveTo(this);
+
+ MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited);
+ newMi->scopePath=mi->scopePath;
+ newMi->ambigClass=mi->ambigClass;
+ newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;
+ newMni->append(newMi);
+
+ // also add the newly created member to the global members list
+ if (newMd)
+ {
+ MemberName *mn;
+ QCString name = newMd->name();
+ if ((mn=Doxygen::memberNameSDict->find(name)))
+ {
+ mn->append(newMd);
+ }
+ else
+ {
+ mn = new MemberName(newMd->name());
+ mn->append(newMd);
+ Doxygen::memberNameSDict->append(name,mn);
+ }
+ }
+
+ newMd->setCategory(category);
+ newMd->setCategoryRelation(mi->memberDef);
+ mi->memberDef->setCategoryRelation(newMd);
+ if (makePrivate || isExtension)
+ {
+ newMd->makeImplementationDetail();
+ }
+ internalInsertMember(newMd,prot,FALSE);
+ }
+
+ // add it to the dictionary
+ dstMnd->append(newMni->memberName(),newMni);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ClassDef::addUsedClass(ClassDef *cd,const char *accessName,
+ Protection prot)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ static bool umlLook = Config_getBool("UML_LOOK");
+ if (prot==Private && !extractPrivate) return;
+ //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
+ if (m_impl->usesImplClassDict==0)
+ {
+ m_impl->usesImplClassDict = new UsesClassDict(17);
+ m_impl->usesImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ //printf("Adding used class %s to class %s via accessor %s\n",
+ // cd->name().data(),name().data(),accessName);
+ }
+ QCString acc = accessName;
+ if (umlLook)
+ {
+ switch(prot)
+ {
+ case Public: acc.prepend("+"); break;
+ case Private: acc.prepend("-"); break;
+ case Protected: acc.prepend("#"); break;
+ case Package: acc.prepend("~"); break;
+ }
+ }
+ ucd->addAccessor(acc);
+}
+
+void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName,
+ Protection prot)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ static bool umlLook = Config_getBool("UML_LOOK");
+ if (prot==Private && !extractPrivate) return;
+ //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
+ if (m_impl->usedByImplClassDict==0)
+ {
+ m_impl->usedByImplClassDict = new UsesClassDict(17);
+ m_impl->usedByImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usedByImplClassDict->insert(cd->name(),ucd);
+ //printf("Adding used by class %s to class %s\n",
+ // cd->name().data(),name().data());
+ }
+ QCString acc = accessName;
+ if (umlLook)
+ {
+ switch(prot)
+ {
+ case Public: acc.prepend("+"); break;
+ case Private: acc.prepend("-"); break;
+ case Protected: acc.prepend("#"); break;
+ case Package: acc.prepend("~"); break;
+ }
+ }
+ ucd->addAccessor(acc);
+}
+
+
+#if 0
+/*! Builds up a dictionary of all classes that are used by the state of this
+ * class (the "implementation").
+ * Must be called before mergeMembers() is called!
+ */
+
+void ClassDef::determineImplUsageRelation()
+{
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->isVariable()) // for each member variable in this class
+ {
+ QCString type=removeRedundantWhiteSpace(md->typeString());
+ //printf("in class %s found var type=`%s' name=`%s'\n",
+ // name().data(),type.data(),md->name().data());
+ int pos=0;
+ QCString usedClassName;
+ QCString templSpec;
+ bool found=FALSE;
+ while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
+ {
+ //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
+ // check if usedClassName is a template argument of its class
+ ClassDef *cd=md->getClassDef();
+ if (cd && cd->templateArguments())
+ {
+ ArgumentListIterator ali(*cd->templateArguments());
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,++count)
+ {
+ if (arg->name==usedClassName) // type is a template argument
+ {
+ found=TRUE;
+ if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257);
+ cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
+ usedClassName,ClassDef::Class);
+ cd->setIsTemplateBaseClass(count);
+ UsesClassDef *ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ ucd->templSpecifiers = templSpec;
+ ucd->addAccessor(md->name());
+ Doxygen::hiddenClasses.append(cd);
+ //printf("Adding used template argument %s to class %s\n",
+ // cd->name().data(),name().data());
+ //printf("Adding accessor %s to class %s\n",
+ // md->name().data(),ucd->classDef->name().data());
+ }
+ }
+ }
+
+ if (!found)
+ {
+ cd=0;
+ if (getNamespaceDef()!=0)
+ {
+ cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
+ }
+ if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
+ if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try in-between scopes!
+ //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
+ if (cd) // class exists
+ {
+ found=TRUE;
+ if (m_impl->usesImplClassDict==0)
+ {
+ m_impl->usesImplClassDict = new UsesClassDict(257);
+ m_impl->usesImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
+ if (ucd==0 || ucd->templSpecifiers!=templSpec)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ ucd->templSpecifiers = templSpec;
+ //printf("Adding used class %s to class %s\n",
+ // cd->name().data(),name().data());
+ }
+ ucd->addAccessor(md->name());
+ //printf("Adding accessor %s to class %s\n",
+ // md->name().data(),ucd->classDef->name().data());
+ }
+ }
+ }
+ }
+ }
+ }
+#ifdef DUMP
+ if (m_impl->usesClassDict)
+ {
+ msg("Class %s uses the following classes:\n",name().data());
+ UsesClassDictIterator ucdi(*m_impl->usesClassDict);
+ UsesClassDef *ucd;
+ for (;(ucd=ucdi.current());++ucdi)
+ {
+ msg(" %s via ",ucd->classDef->name().data());
+ QDictIterator<void> dvi(*ucd->accessors);
+ const char *s;
+ for (;(s=dvi.currentKey());++dvi)
+ {
+ msg("%s ",s);
+ }
+ msg("\n");
+ }
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+
+// I have disabled this code because the graphs it renders quickly become
+// too large to be of practical use.
+
+void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
+{
+ QCString type = typeStr;
+ static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
+ int p=0,i,l;
+ while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
+ {
+ ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
+ if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try in-between scopes!
+ if (cd && cd!=this && !isBaseClass(cd))
+ {
+ if (m_impl->usesIntfClassDict==0)
+ {
+ m_impl->usesIntfClassDict = new UsesClassDict(257);
+ }
+ UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesIntfClassDict->insert(cd->name(),ucd);
+ //printf("in class `%s' adding used intf class `%s'\n",
+ // name().data(),cd->name().data());
+ }
+ ucd->addAccessor(md->name());
+ //printf("in class `%s' adding accessor `%s' to class `%s'\n",
+ // name().data(),md->name().data(),ucd->classDef->name().data());
+ }
+ p=i+l;
+ }
+}
+
+void ClassDef::determineIntfUsageRelation()
+{
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+
+ // compute the protection level for this member
+ Protection protect=md->protection();
+ if (mi->prot==Protected) // inherited protection
+ {
+ if (protect==Public) protect=Protected;
+ else if (protect==Protected) protect=Private;
+ }
+
+ if (!md->name().isEmpty() && md->name()[0]!='@' &&
+ (mi->prot!=Private && protect!=Private)
+ )
+ {
+ // add classes found in the return type
+ addUsedInterfaceClasses(md,md->typeString());
+ ArgumentList *al = md->argumentList();
+ if (al) // member has arguments
+ {
+ // add classes found in the types of the argument list
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ if (!a->type.isEmpty() && a->type.at(0)!='@')
+ {
+ addUsedInterfaceClasses(md,a->type);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+QCString ClassDef::compoundTypeString() const
+{
+ if (getLanguage()==SrcLangExt_Fortran)
+ {
+ switch (m_impl->compType)
+ {
+ case Class: return "module";
+ case Struct: return "type";
+ case Union: return "union";
+ case Interface: return "interface";
+ case Protocol: return "protocol";
+ case Category: return "category";
+ case Exception: return "exception";
+ default: return "unknown";
+ }
+ }
+ else
+ {
+ switch (m_impl->compType)
+ {
+ case Class: return isJavaEnum() ? "enum" : "class";
+ case Struct: return "struct";
+ case Union: return "union";
+ case Interface: return getLanguage()==SrcLangExt_ObjC ? "class" : "interface";
+ case Protocol: return "protocol";
+ case Category: return "category";
+ case Exception: return "exception";
+ case Service: return "service";
+ case Singleton: return "singleton";
+ default: return "unknown";
+ }
+ }
+}
+
+QCString ClassDef::getOutputFileBase() const
+{
+ static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ if (!Doxygen::generatingXmlOutput)
+ {
+ Definition *scope=0;
+ if (inlineGroupedClasses && partOfGroups()!=0)
+ {
+ // point to the group that embeds this class
+ return partOfGroups()->at(0)->getOutputFileBase();
+ }
+ else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
+ {
+ // point to simple struct inside a group
+ return partOfGroups()->at(0)->getOutputFileBase();
+ }
+ else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
+ {
+ if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
+ {
+ return getFileDef()->getOutputFileBase();
+ }
+ else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
+ {
+ return getOuterScope()->getOutputFileBase();
+ }
+ }
+ }
+ if (m_impl->templateMaster)
+ {
+ // point to the template of which this class is an instance
+ return m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (isReference())
+ {
+ // point to the external location
+ return m_impl->fileName;
+ }
+ else
+ {
+ // normal locally defined class
+ return convertNameToFile(m_impl->fileName);
+ }
+}
+
+QCString ClassDef::getInstanceOutputFileBase() const
+{
+ if (isReference())
+ {
+ return m_impl->fileName;
+ }
+ else
+ {
+ return convertNameToFile(m_impl->fileName);
+ }
+}
+
+QCString ClassDef::getFileBase() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getFileBase();
+ }
+ else
+ {
+ return m_impl->fileName;
+ }
+}
+
+QCString ClassDef::getSourceFileBase() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getSourceFileBase();
+ }
+ else
+ {
+ return Definition::getSourceFileBase();
+ }
+}
+
+void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
+{
+ gd->addClass(this);
+ //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
+ if (m_impl->allMemberNameInfoSDict==0) return;
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
+ gd->insertMember(md,TRUE);
+ ClassDef *innerClass = md->getClassDefOfAnonymousType();
+ if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
+ }
+ }
+}
+
+void ClassDef::addInnerCompound(Definition *d)
+{
+ //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
+ if (d->definitionType()==Definition::TypeClass) // only classes can be
+ // nested in classes.
+ {
+ if (m_impl->innerClasses==0)
+ {
+ m_impl->innerClasses = new ClassSDict(17);
+ }
+ m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);
+ }
+}
+
+Definition *ClassDef::findInnerCompound(const char *name)
+{
+ Definition *result=0;
+ if (name==0) return 0;
+ if (m_impl->innerClasses)
+ {
+ result = m_impl->innerClasses->find(name);
+ }
+ return result;
+}
+
+//void ClassDef::initTemplateMapping()
+//{
+// m_impl->templateMapping->clear();
+// ArgumentList *al = templateArguments();
+// if (al)
+// {
+// ArgumentListIterator ali(*al);
+// Argument *arg;
+// for (ali.toFirst();(arg=ali.current());++ali)
+// {
+// setTemplateArgumentMapping(arg->name,arg->defval);
+// }
+// }
+//}
+//void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
+//{
+// //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
+// if (m_impl->templateMapping && formal)
+// {
+// if (m_impl->templateMapping->find(formal))
+// {
+// m_impl->templateMapping->remove(formal);
+// }
+// m_impl->templateMapping->insert(formal,new QCString(actual));
+// }
+//}
+//
+//QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
+//{
+// if (m_impl->templateMapping && formal)
+// {
+// QCString *s = m_impl->templateMapping->find(formal);
+// if (s)
+// {
+// return *s;
+// }
+// }
+// return "";
+//}
+
+ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
+ int startLine, int startColumn, const QCString &templSpec,bool &freshInstance)
+{
+ freshInstance = FALSE;
+ if (m_impl->templateInstances==0)
+ {
+ m_impl->templateInstances = new QDict<ClassDef>(17);
+ }
+ ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
+ if (templateClass==0)
+ {
+ Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data());
+ QCString tcname = removeRedundantWhiteSpace(localName()+templSpec);
+ templateClass = new ClassDef(
+ fileName,startLine,startColumn,tcname,ClassDef::Class);
+ templateClass->setTemplateMaster(this);
+ templateClass->setOuterScope(getOuterScope());
+ templateClass->setHidden(isHidden());
+ m_impl->templateInstances->insert(templSpec,templateClass);
+ freshInstance=TRUE;
+ }
+ return templateClass;
+}
+
+ClassDef *ClassDef::getVariableInstance(const char *templSpec)
+{
+ if (m_impl->variableInstances==0)
+ {
+ m_impl->variableInstances = new QDict<ClassDef>(17);
+ m_impl->variableInstances->setAutoDelete(TRUE);
+ }
+ ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
+ if (templateClass==0)
+ {
+ Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
+ QCString tcname = removeRedundantWhiteSpace(name()+templSpec);
+ templateClass = new ClassDef("<code>",1,1,tcname,
+ ClassDef::Class,0,0,FALSE);
+ templateClass->addMembersToTemplateInstance( this, templSpec );
+ templateClass->setTemplateMaster(this);
+ m_impl->variableInstances->insert(templSpec,templateClass);
+ }
+ return templateClass;
+}
+
+void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
+{
+ if (templateNames==0) return;
+ if (m_impl->templBaseClassNames==0)
+ {
+ m_impl->templBaseClassNames = new QDict<int>(17);
+ m_impl->templBaseClassNames->setAutoDelete(TRUE);
+ }
+ // make a deep copy of the dictionary.
+ QDictIterator<int> qdi(*templateNames);
+ for (;qdi.current();++qdi)
+ {
+ if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
+ {
+ m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
+ }
+ }
+}
+
+QDict<int> *ClassDef::getTemplateBaseClassNames() const
+{
+ return m_impl->templBaseClassNames;
+}
+
+void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
+{
+ //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
+ if (cd->memberNameInfoSDict()==0) return;
+ MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ ArgumentList *actualArguments = new ArgumentList;
+ stringToArgumentList(templSpec,actualArguments);
+ MemberDef *md = mi->memberDef;
+ MemberDef *imd = md->createTemplateInstanceMember(
+ cd->templateArguments(),actualArguments);
+ delete actualArguments;
+ //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
+ imd->setMemberClass(this);
+ imd->setTemplateMaster(md);
+ imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+ imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+ imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+ imd->setMemberSpecifiers(md->getMemberSpecifiers());
+ imd->setMemberGroupId(md->getMemberGroupId());
+ insertMember(imd);
+ //printf("Adding member=%s %s%s to class %s templSpec %s\n",
+ // imd->typeString(),imd->name().data(),imd->argsString(),
+ // imd->getClassDef()->name().data(),templSpec);
+ // insert imd in the list of all members
+ //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
+ MemberName *mn = Doxygen::memberNameSDict->find(imd->name());
+ if (mn==0)
+ {
+ mn = new MemberName(imd->name());
+ Doxygen::memberNameSDict->append(imd->name(),mn);
+ }
+ mn->append(imd);
+ }
+ }
+}
+
+QCString ClassDef::getReference() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getReference();
+ }
+ else
+ {
+ return Definition::getReference();
+ }
+}
+
+bool ClassDef::isReference() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isReference();
+ }
+ else
+ {
+ return Definition::isReference();
+ }
+}
+
+void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
+{
+ Definition *d=getOuterScope();
+ if (d)
+ {
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd=(ClassDef *)d;
+ cd->getTemplateParameterLists(lists);
+ }
+ }
+ if (templateArguments())
+ {
+ lists.append(templateArguments());
+ }
+}
+
+QCString ClassDef::qualifiedNameWithTemplateParameters(
+ QList<ArgumentList> *actualParams,int *actualParamIndex) const
+{
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
+ QCString scName;
+ Definition *d=getOuterScope();
+ if (d)
+ {
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd=(ClassDef *)d;
+ scName = cd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex);
+ }
+ else if (!hideScopeNames)
+ {
+ scName = d->qualifiedName();
+ }
+ }
+
+ SrcLangExt lang = getLanguage();
+ QCString scopeSeparator = getLanguageSpecificSeparator(lang);
+ if (!scName.isEmpty()) scName+=scopeSeparator;
+
+ bool isSpecialization = localName().find('<')!=-1;
+
+ QCString clName = className();
+ //bool isGeneric = getLanguage()==SrcLangExt_CSharp;
+ //if (isGeneric && clName.right(2)=="-g")
+ //{
+ // clName = clName.left(clName.length()-2);
+ //}
+ //printf("m_impl->lang=%d clName=%s\n",m_impl->lang,clName.data());
+ scName+=clName;
+ ArgumentList *al=0;
+ if (templateArguments())
+ {
+ if (actualParams && *actualParamIndex<(int)actualParams->count())
+ {
+ al = actualParams->at(*actualParamIndex);
+ if (!isSpecialization)
+ {
+ scName+=tempArgListToString(al);
+ }
+ (*actualParamIndex)++;
+ }
+ else
+ {
+ if (!isSpecialization)
+ {
+ scName+=tempArgListToString(templateArguments());
+ }
+ }
+ }
+ //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
+ return scName;
+}
+
+QCString ClassDef::className() const
+{
+ if (m_impl->className.isEmpty())
+ {
+ return localName();
+ }
+ else
+ {
+ return m_impl->className;
+ }
+};
+
+void ClassDef::setClassName(const char *name)
+{
+ m_impl->className = name;
+}
+
+void ClassDef::addListReferences()
+{
+ SrcLangExt lang = getLanguage();
+ if (!isLinkableInProject()) return;
+ //printf("ClassDef(%s)::addListReferences()\n",name().data());
+ {
+ QList<ListItemInfo> *xrefItems = xrefListItems();
+ addRefItem(xrefItems,
+ qualifiedName(),
+ lang==SrcLangExt_Fortran ? theTranslator->trType(TRUE,TRUE)
+ : theTranslator->trClass(TRUE,TRUE),
+ getOutputFileBase(),
+ displayName(),
+ 0
+ );
+ }
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(this);
+ }
+ }
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_detailedLists)
+ {
+ ml->addListReferences(this);
+ }
+ }
+}
+
+MemberDef *ClassDef::getMemberByName(const QCString &name) const
+{
+ MemberDef *xmd = 0;
+ if (m_impl->allMemberNameInfoSDict)
+ {
+ MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);
+ if (mni)
+ {
+ const int maxInheritanceDepth = 100000;
+ int mdist=maxInheritanceDepth;
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ ClassDef *mcd=mi->memberDef->getClassDef();
+ int m=minClassDistance(this,mcd);
+ //printf("found member in %s linkable=%d m=%d\n",
+ // mcd->name().data(),mcd->isLinkable(),m);
+ if (m<mdist && mcd->isLinkable())
+ {
+ mdist=m;
+ xmd=mi->memberDef;
+ }
+ }
+ }
+ }
+ //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
+ return xmd;
+}
+
+bool ClassDef::isAccessibleMember(MemberDef *md)
+{
+ return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
+}
+
+MemberList *ClassDef::createMemberList(MemberListType lt)
+{
+ m_impl->memberLists.setAutoDelete(TRUE);
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ // not found, create a new member list
+ ml = new MemberList(lt);
+ m_impl->memberLists.append(ml);
+ return ml;
+}
+
+MemberList *ClassDef::getMemberList(MemberListType lt)
+{
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ return 0;
+}
+
+void ClassDef::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
+ MemberList *ml = createMemberList(lt);
+ ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
+ ml->append(md);
+
+ // for members in the declaration lists we set the section, needed for member grouping
+ if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(this,ml);
+}
+
+void ClassDef::sortMemberLists()
+{
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
+ }
+ if (m_impl->innerClasses)
+ {
+ m_impl->innerClasses->sort();
+ }
+}
+
+int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom,
+ int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
+{
+ //printf("%s: countMemberDeclarations for %d and %d\n",name().data(),lt,lt2);
+ int count=0;
+ MemberList * ml = getMemberList(lt);
+ MemberList * ml2 = getMemberList((MemberListType)lt2);
+ if (getLanguage()!=SrcLangExt_VHDL) // use specific declarations function
+ {
+ if (ml)
+ {
+ ml->countDecMembers();
+ count+=ml->numDecMembers();
+ //printf("-> ml=%d\n",ml->numDecMembers());
+ }
+ if (ml2)
+ {
+ ml2->countDecMembers();
+ count+=ml2->numDecMembers();
+ //printf("-> ml2=%d\n",ml2->numDecMembers());
+ }
+ // also include grouped members that have their own section in the class (see bug 722759)
+ if (inheritedFrom && m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ count+=mg->countGroupedInheritedMembers(lt);
+ if (lt2!=1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2);
+ }
+ }
+ static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
+ if (!inlineInheritedMembers) // show inherited members as separate lists
+ {
+ QPtrDict<void> visited(17);
+ count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses);
+ }
+ }
+ //printf("-> %d\n",count);
+ return count;
+}
+
+
+int ClassDef::countInheritedDecMembers(MemberListType lt,
+ ClassDef *inheritedFrom,bool invert,bool showAlways,
+ QPtrDict<void> *visitedClasses)
+{
+ int inhCount = 0;
+ int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
+ bool process = count>0;
+ //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
+ // name().data(),lt,process,count,invert);
+ if ((process^invert) || showAlways)
+ {
+ if (m_impl->inherits)
+ {
+ BaseClassListIterator it(*m_impl->inherits);
+ BaseClassDef *ibcd;
+ for (it.toFirst();(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ int lt1,lt2;
+ if (icd->isLinkable())
+ {
+ convertProtectionLevel(lt,ibcd->prot,<1,<2);
+ //printf("%s: convert %d->(%d,%d) prot=%d\n",
+ // icd->name().data(),lt,lt1,lt2,ibcd->prot);
+ if (visitedClasses->find(icd)==0)
+ {
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
+ {
+ inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
+ }
+ }
+ }
+ }
+ }
+ }
+ return inhCount;
+}
+
+void ClassDef::getTitleForMemberListType(MemberListType type,
+ QCString &title,QCString &subtitle)
+{
+ SrcLangExt lang = getLanguage();
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (lmd->type==type)
+ {
+ title = lmd->title(lang);
+ subtitle = lmd->subtitle(lang);
+ return;
+ }
+ }
+ }
+ title="";
+ subtitle="";
+}
+
+int ClassDef::countAdditionalInheritedMembers()
+{
+ int totalCount=0;
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (lmd->type!=MemberListType_friends) // friendship is not inherited
+ {
+ //MemberList *ml = getMemberList(lmd->type);
+ //if (ml==0 || ml->numDecMembers()==0)
+ //{
+ QPtrDict<void> visited(17);
+ totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,&visited);
+ //}
+ }
+ }
+ }
+ //printf("countAdditonalInheritedMembers()=%d\n",totalCount);
+ return totalCount;
+}
+
+void ClassDef::writeAdditionalInheritedMembers(OutputList &ol)
+{
+ //printf("**** writeAdditionalInheritedMembers()\n");
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (lmd->type!=MemberListType_friends)
+ {
+ QPtrDict<void> visited(17);
+ writeInheritedMemberDeclarations(ol,lmd->type,-1,lmd->title(getLanguage()),this,TRUE,FALSE,&visited);
+ }
+ }
+ }
+}
+
+int ClassDef::countMembersIncludingGrouped(MemberListType lt,
+ ClassDef *inheritedFrom,bool additional)
+{
+ int count=0;
+ MemberList *ml = getMemberList(lt);
+ if (ml)
+ {
+ count=ml->countInheritableMembers(inheritedFrom);
+ }
+ //printf("%s:countMembersIncludingGrouped: count=%d\n",name().data(),count);
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ bool hasOwnSection = !mg->allMembersInSameSection() ||
+ !m_impl->subGrouping; // group is in its own section
+ if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
+ {
+ count+=mg->countGroupedInheritedMembers(lt);
+ }
+ }
+ }
+ //printf("%s:countMembersIncludingGrouped(lt=%d,%s)=%d\n",
+ // name().data(),lt,ml?ml->listTypeAsString(ml->listType()).data():"<none>",count);
+ return count;
+}
+
+void ClassDef::writeInheritedMemberDeclarations(OutputList &ol,
+ MemberListType lt,int lt2,const QCString &title,
+ ClassDef *inheritedFrom,bool invert,bool showAlways,
+ QPtrDict<void> *visitedClasses)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
+ bool process = count>0;
+ //printf("%s: writeInheritedMemberDec: lt=%d process=%d invert=%d always=%d\n",
+ // name().data(),lt,process,invert,showAlways);
+ if ((process^invert) || showAlways)
+ {
+ if (m_impl->inherits)
+ {
+ BaseClassListIterator it(*m_impl->inherits);
+ BaseClassDef *ibcd;
+ for (it.toFirst();(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if (icd->isLinkable())
+ {
+ int lt1,lt3;
+ convertProtectionLevel(lt,ibcd->prot,<1,<3);
+ if (lt2==-1 && lt3!=-1)
+ {
+ lt2=lt3;
+ }
+ //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot);
+ if (visitedClasses->find(icd)==0)
+ {
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
+ {
+ icd->writeMemberDeclarations(ol,(MemberListType)lt1,
+ title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
+ }
+ }
+ else
+ {
+ //printf("%s: class already visited!\n",icd->name().data());
+ }
+ }
+ }
+ }
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title,
+ const char *subTitle,bool showInline,ClassDef *inheritedFrom,int lt2,
+ bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
+{
+ //printf("%s: ClassDef::writeMemberDeclarations lt=%d lt2=%d\n",name().data(),lt,lt2);
+ MemberList * ml = getMemberList(lt);
+ MemberList * ml2 = getMemberList((MemberListType)lt2);
+ if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function
+ {
+ if (ml)
+ {
+ VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0,0);
+ }
+ }
+ else
+ {
+ //printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",name().data(),title.data(),ml,ml2);
+ QCString tt = title, st = subTitle;
+ if (ml)
+ {
+ //printf(" writeDeclaration type=%d count=%d\n",lt,ml->numDecMembers());
+ ml->writeDeclarations(ol,this,0,0,0,tt,st,definitionType(),FALSE,showInline,inheritedFrom,lt);
+ tt.resize(0);
+ st.resize(0);
+ }
+ if (ml2)
+ {
+ //printf(" writeDeclaration type=%d count=%d\n",lt2,ml2->numDecMembers());
+ ml2->writeDeclarations(ol,this,0,0,0,tt,st,definitionType(),FALSE,showInline,inheritedFrom,lt);
+ }
+ static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
+ if (!inlineInheritedMembers) // show inherited members as separate lists
+ {
+ QPtrDict<void> visited(17);
+ writeInheritedMemberDeclarations(ol,lt,lt2,title,
+ inheritedFrom ? inheritedFrom : this,
+ invert,showAlways,
+ visitedClasses==0 ? &visited: visitedClasses);
+ }
+ }
+}
+
+void ClassDef::addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
+ ClassDef *inheritedFrom,const QCString &inheritId)
+{
+ //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data());
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
+ {
+ mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
+ }
+ }
+ }
+}
+
+void ClassDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline)
+{
+ //printf("%s: ClassDef::writeMemberDocumentation()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline);
+}
+
+void ClassDef::writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt)
+{
+ //printf("%s: ClassDef::writeSimpleMemberDocumentation()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeSimpleDocumentation(ol,this);
+}
+
+void ClassDef::writePlainMemberDeclaration(OutputList &ol,
+ MemberListType lt,bool inGroup,
+ ClassDef *inheritedFrom,const char *inheritId)
+{
+ //printf("%s: ClassDef::writePlainMemberDeclaration()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml)
+ {
+ ml->setInGroup(inGroup);
+ ml->writePlainDeclarations(ol,this,0,0,0,definitionType(),inheritedFrom,inheritId);
+ }
+}
+
+bool ClassDef::isLocal() const
+{
+ return m_impl->isLocal;
+}
+
+ClassSDict *ClassDef::getClassSDict()
+{
+ return m_impl->innerClasses;
+}
+
+ClassDef::CompoundType ClassDef::compoundType() const
+{
+ return m_impl->compType;
+}
+
+BaseClassList *ClassDef::baseClasses() const
+{
+ return m_impl->inherits;
+}
+
+BaseClassList *ClassDef::subClasses() const
+{
+ return m_impl->inheritedBy;
+}
+
+MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const
+{
+ return m_impl->allMemberNameInfoSDict;
+}
+
+Protection ClassDef::protection() const
+{
+ return m_impl->prot;
+}
+
+ArgumentList *ClassDef::templateArguments() const
+{
+ return m_impl->tempArgs;
+}
+
+NamespaceDef *ClassDef::getNamespaceDef() const
+{
+ return m_impl->nspace;
+}
+
+FileDef *ClassDef::getFileDef() const
+{
+ return m_impl->fileDef;
+}
+
+QDict<ClassDef> *ClassDef::getTemplateInstances() const
+{
+ return m_impl->templateInstances;
+}
+
+ClassDef *ClassDef::templateMaster() const
+{
+ return m_impl->templateMaster;
+}
+
+bool ClassDef::isTemplate() const
+{
+ return m_impl->tempArgs!=0;
+}
+
+IncludeInfo *ClassDef::includeInfo() const
+{
+ return m_impl->incInfo;
+}
+
+UsesClassDict *ClassDef::usedImplementationClasses() const
+{
+ return m_impl->usesImplClassDict;
+}
+
+UsesClassDict *ClassDef::usedByImplementationClasses() const
+{
+ return m_impl->usedByImplClassDict;
+}
+
+UsesClassDict *ClassDef::usedInterfaceClasses() const
+{
+ return m_impl->usesIntfClassDict;
+}
+
+bool ClassDef::isTemplateArgument() const
+{
+ return m_impl->isTemplArg;
+}
+
+bool ClassDef::isAbstract() const
+{
+ return m_impl->isAbstract || (m_impl->spec&Entry::Abstract);
+}
+
+bool ClassDef::isFinal() const
+{
+ return m_impl->spec&Entry::Final;
+}
+
+bool ClassDef::isSealed() const
+{
+ return m_impl->spec&Entry::Sealed;
+}
+
+bool ClassDef::isPublished() const
+{
+ return m_impl->spec&Entry::Published;
+}
+
+bool ClassDef::isForwardDeclared() const
+{
+ return m_impl->spec&Entry::ForwardDecl;
+}
+
+bool ClassDef::isObjectiveC() const
+{
+ return getLanguage()==SrcLangExt_ObjC;
+}
+
+bool ClassDef::isCSharp() const
+{
+ return getLanguage()==SrcLangExt_CSharp;
+}
+
+ClassDef *ClassDef::categoryOf() const
+{
+ return m_impl->categoryOf;
+}
+
+const QList<MemberList> &ClassDef::getMemberLists() const
+{
+ return m_impl->memberLists;
+}
+
+MemberGroupSDict *ClassDef::getMemberGroupSDict() const
+{
+ return m_impl->memberGroupSDict;
+}
+
+void ClassDef::setNamespace(NamespaceDef *nd)
+{
+ m_impl->nspace = nd;
+}
+
+void ClassDef::setFileDef(FileDef *fd)
+{
+ m_impl->fileDef=fd;
+}
+
+void ClassDef::setSubGrouping(bool enabled)
+{
+ m_impl->subGrouping = enabled;
+}
+
+void ClassDef::setProtection(Protection p)
+{
+ m_impl->prot=p;
+}
+
+void ClassDef::setIsStatic(bool b)
+{
+ m_impl->isStatic=b;
+}
+
+void ClassDef::setCompoundType(CompoundType t)
+{
+ m_impl->compType = t;
+}
+
+void ClassDef::setTemplateMaster(ClassDef *tm)
+{
+ m_impl->templateMaster=tm;
+}
+
+void ClassDef::makeTemplateArgument(bool b)
+{
+ m_impl->isTemplArg = b;
+}
+
+void ClassDef::setCategoryOf(ClassDef *cd)
+{
+ m_impl->categoryOf = cd;
+}
+
+void ClassDef::setUsedOnly(bool b)
+{
+ m_impl->usedOnly = b;
+}
+
+bool ClassDef::isUsedOnly() const
+{
+ return m_impl->usedOnly;
+}
+
+bool ClassDef::isSimple() const
+{
+ return m_impl->isSimple;
+}
+
+MemberDef *ClassDef::isSmartPointer() const
+{
+ return m_impl->arrowOperator;
+}
+
+void ClassDef::reclassifyMember(MemberDef *md,MemberType t)
+{
+ md->setMemberType(t);
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ ml->remove(md);
+ }
+ insertMember(md);
+}
+
+QCString ClassDef::anchor() const
+{
+ QCString anc;
+ if (isEmbeddedInOuterScope() && !Doxygen::generatingXmlOutput)
+ {
+ if (m_impl->templateMaster)
+ {
+ // point to the template of which this class is an instance
+ anc = m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (isReference())
+ {
+ // point to the external location
+ anc = m_impl->fileName;
+ }
+ else
+ {
+ // normal locally defined class
+ anc = convertNameToFile(m_impl->fileName);
+ }
+ }
+ return anc;
+}
+
+bool ClassDef::isEmbeddedInOuterScope() const
+{
+ static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+
+ Definition *container = getOuterScope();
+
+ bool containerLinkable =
+ container &&
+ (
+ (container==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) || // global class in documented file
+ container->isLinkableInProject() // class in documented scope
+ );
+
+ // inline because of INLINE_GROUPED_CLASSES=YES ?
+ bool b1 = (inlineGroupedClasses && partOfGroups()!=0); // a grouped class
+ // inline because of INLINE_SIMPLE_STRUCTS=YES ?
+ bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
+ (containerLinkable || // in a documented container
+ partOfGroups()!=0 // or part of a group
+ )
+ );
+ //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
+ // "inlineSimpleClasses=%d partOfGroups()=%p m_impl->isSimple=%d "
+ // "getOuterScope()=%s b1=%d b2=%d\n",
+ // name().data(),inlineGroupedClasses,inlineSimpleClasses,
+ // partOfGroups().pointer(),m_impl->isSimple,getOuterScope()?getOuterScope()->name().data():"<none>",b1,b2);
+ return b1 || b2; // either reason will do
+}
+
+const ClassList *ClassDef::taggedInnerClasses() const
+{
+ return m_impl->taggedInnerClasses;
+}
+
+void ClassDef::addTaggedInnerClass(ClassDef *cd)
+{
+ if (m_impl->taggedInnerClasses==0)
+ {
+ m_impl->taggedInnerClasses = new ClassList;
+ }
+ m_impl->taggedInnerClasses->append(cd);
+}
+
+ClassDef *ClassDef::tagLessReference() const
+{
+ return m_impl->tagLessRef;
+}
+
+void ClassDef::setTagLessReference(ClassDef *cd)
+{
+ m_impl->tagLessRef = cd;
+}
+
+void ClassDef::removeMemberFromLists(MemberDef *md)
+{
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ ml->remove(md);
+ }
+}
+
+bool ClassDef::isJavaEnum() const
+{
+ return m_impl->isJavaEnum;
+}
+
+bool ClassDef::isGeneric() const
+{
+ return m_impl->isGeneric;
+}
+
+void ClassDef::setClassSpecifier(uint64 spec)
+{
+ m_impl->spec = spec;
+}
+
+bool ClassDef::isExtension() const
+{
+ QCString n = name();
+ int si = n.find('(');
+ int ei = n.find(')');
+ bool b = ei>si && n.mid(si+1,ei-si-1).stripWhiteSpace().isEmpty();
+ return b;
+}
+
+const ClassSDict *ClassDef::innerClasses() const
+{
+ return m_impl->innerClasses;
+}
+
+const FileList &ClassDef::usedFiles() const
+{
+ return m_impl->files;
+}
+
+const ArgumentList *ClassDef::typeConstraints() const
+{
+ return m_impl->typeConstraints;
+}
+
+const ExampleSDict *ClassDef::exampleList() const
+{
+ return m_impl->exampleSDict;
+}
+
+bool ClassDef::subGrouping() const
+{
+ return m_impl->subGrouping;
+}
+
+void ClassDef::setName(const char *name)
+{
+ m_impl->isAnonymous = QCString(name).find('@')!=-1;
+ Definition::setName(name);
+}
+
+bool ClassDef::isAnonymous() const
+{
+ return m_impl->isAnonymous;
+}
diff --git a/src/classdef.h b/src/classdef.h
new file mode 100644
index 0000000..9f0ae5f
--- /dev/null
+++ b/src/classdef.h
@@ -0,0 +1,560 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CLASSDEF_H
+#define CLASSDEF_H
+
+#include <qlist.h>
+#include <qdict.h>
+#include <qptrdict.h>
+
+#include "definition.h"
+
+class MemberDef;
+class MemberList;
+class MemberDict;
+class ClassList;
+class ClassSDict;
+class OutputList;
+class FileDef;
+class FileList;
+class BaseClassList;
+class NamespaceDef;
+class MemberDef;
+class ExampleSDict;
+class MemberNameInfoSDict;
+class UsesClassDict;
+class MemberGroupSDict;
+class QTextStream;
+class PackageDef;
+class GroupDef;
+class StringDict;
+struct IncludeInfo;
+class ClassDefImpl;
+class ArgumentList;
+
+/** A class representing of a compound symbol.
+ *
+ * A compound can be a class, struct, union, interface, service, singleton,
+ * or exception.
+ * \note This class should be renamed to CompoundDef
+ */
+class ClassDef : public Definition
+{
+ public:
+ /** The various compound types */
+ enum CompoundType { Class, //=Entry::CLASS_SEC,
+ Struct, //=Entry::STRUCT_SEC,
+ Union, //=Entry::UNION_SEC,
+ Interface, //=Entry::INTERFACE_SEC,
+ Protocol, //=Entry::PROTOCOL_SEC,
+ Category, //=Entry::CATEGORY_SEC,
+ Exception, //=Entry::EXCEPTION_SEC
+ Service, //=Entry::CLASS_SEC
+ Singleton, //=Entry::CLASS_SEC
+ };
+
+ /** Creates a new compound definition.
+ * \param fileName full path and file name in which this compound was
+ * found.
+ * \param startLine line number where the definition of this compound
+ * starts.
+ * \param startColumn column number where the definition of this compound
+ * starts.
+ * \param name the name of this compound (including scope)
+ * \param ct the kind of Compound
+ * \param ref the tag file from which this compound is extracted
+ * or 0 if the compound doesn't come from a tag file
+ * \param fName the file name as found in the tag file.
+ * This overwrites the file that doxygen normally
+ * generates based on the compound type & name.
+ * \param isSymbol If TRUE this class name is added as a publicly
+ * visible (and referencable) symbol.
+ * \param isJavaEnum If TRUE this class is actually a Java enum.
+ * I didn't add this to CompoundType to avoid having
+ * to adapt all translators.
+ */
+ ClassDef(const char *fileName,int startLine,int startColumn,
+ const char *name,CompoundType ct,
+ const char *ref=0,const char *fName=0,
+ bool isSymbol=TRUE,bool isJavaEnum=FALSE);
+ /** Destroys a compound definition. */
+ ~ClassDef();
+
+ //-----------------------------------------------------------------------------------
+ // --- getters
+ //-----------------------------------------------------------------------------------
+
+ /** Used for RTTI, this is a class */
+ DefType definitionType() const { return TypeClass; }
+
+ /** Returns the unique base name (without extension) of the class's file on disk */
+ QCString getOutputFileBase() const;
+ QCString getInstanceOutputFileBase() const;
+ QCString getFileBase() const;
+
+ /** Returns the base name for the source code file */
+ QCString getSourceFileBase() const;
+
+ /** If this class originated from a tagfile, this will return the tag file reference */
+ QCString getReference() const;
+
+ /** Returns TRUE if this class is imported via a tag file */
+ bool isReference() const;
+
+ /** Returns TRUE if this is a local class definition, see EXTRACT_LOCAL_CLASSES */
+ bool isLocal() const;
+
+ /** returns the classes nested into this class */
+ ClassSDict *getClassSDict();
+
+ /** returns TRUE if this class has documentation */
+ bool hasDocumentation() const;
+
+ /** returns TRUE if this class has a non-empty detailed description */
+ bool hasDetailedDescription() const;
+
+ /** Returns the name as it is appears in the documentation */
+ QCString displayName(bool includeScope=TRUE) const;
+
+ /** Returns the type of compound this is, i.e. class/struct/union/.. */
+ CompoundType compoundType() const;
+
+ /** Returns the type of compound as a string */
+ QCString compoundTypeString() const;
+
+ /** Returns the list of base classes from which this class directly
+ * inherits.
+ */
+ BaseClassList *baseClasses() const;
+
+ /** Returns the list of sub classes that directly derive from this class
+ */
+ BaseClassList *subClasses() const;
+
+ /** Returns a dictionary of all members. This includes any inherited
+ * members. Members are sorted alphabetically.
+ */
+ MemberNameInfoSDict *memberNameInfoSDict() const;
+
+ /** Return the protection level (Public,Protected,Private) in which
+ * this compound was found.
+ */
+ Protection protection() const;
+
+ /** returns TRUE iff a link is possible to this item within this project.
+ */
+ bool isLinkableInProject() const;
+
+ /** return TRUE iff a link to this class is possible (either within
+ * this project, or as a cross-reference to another project).
+ */
+ bool isLinkable() const;
+
+ /** the class is visible in a class diagram, or class hierarchy */
+ bool isVisibleInHierarchy();
+
+ /** show this class in the declaration section of its parent? */
+ bool visibleInParentsDeclList() const;
+
+ /** Returns the template arguments of this class
+ * Will return 0 if not applicable.
+ */
+ ArgumentList *templateArguments() const;
+
+ /** Returns the namespace this compound is in, or 0 if it has a global
+ * scope.
+ */
+ NamespaceDef *getNamespaceDef() const;
+
+ /** Returns the file in which this compound's definition can be found.
+ * Should not return 0 (but it might be a good idea to check anyway).
+ */
+ FileDef *getFileDef() const;
+
+ /** Returns the Java package this class is in or 0 if not applicable.
+ */
+
+ MemberDef *getMemberByName(const QCString &) const;
+
+ /** Returns TRUE iff \a bcd is a direct or indirect base class of this
+ * class. This function will recusively traverse all branches of the
+ * inheritance tree.
+ */
+ bool isBaseClass(ClassDef *bcd,bool followInstances,int level=0);
+
+ /** Returns TRUE iff \a bcd is a direct or indirect sub class of this
+ * class.
+ */
+ bool isSubClass(ClassDef *bcd,int level=0);
+
+ /** returns TRUE iff \a md is a member of this class or of the
+ * the public/protected members of a base class
+ */
+ bool isAccessibleMember(MemberDef *md);
+
+ /** Returns a sorted dictionary with all template instances found for
+ * this template class. Returns 0 if not a template or no instances.
+ */
+ QDict<ClassDef> *getTemplateInstances() const;
+
+ /** Returns the template master of which this class is an instance.
+ * Returns 0 if not applicable.
+ */
+ ClassDef *templateMaster() const;
+
+ /** Returns TRUE if this class is a template */
+ bool isTemplate() const;
+
+ IncludeInfo *includeInfo() const;
+
+ UsesClassDict *usedImplementationClasses() const;
+
+ UsesClassDict *usedByImplementationClasses() const;
+
+ UsesClassDict *usedInterfaceClasses() const;
+
+ bool isTemplateArgument() const;
+
+ /** Returns the definition of a nested compound if
+ * available, or 0 otherwise.
+ * @param name The name of the nested compound
+ */
+ virtual Definition *findInnerCompound(const char *name);
+
+ /** Returns the template parameter lists that form the template
+ * declaration of this class.
+ *
+ * Example: <code>template<class T> class TC {};</code>
+ * will return a list with one ArgumentList containing one argument
+ * with type="class" and name="T".
+ */
+ void getTemplateParameterLists(QList<ArgumentList> &lists) const;
+
+ QCString qualifiedNameWithTemplateParameters(
+ QList<ArgumentList> *actualParams=0,int *actualParamIndex=0) const;
+
+ /** Returns TRUE if there is at least one pure virtual member in this
+ * class.
+ */
+ bool isAbstract() const;
+
+ /** Returns TRUE if this class is implemented in Objective-C */
+ bool isObjectiveC() const;
+
+ /** Returns TRUE if this class is implemented in C# */
+ bool isCSharp() const;
+
+ /** Returns TRUE if this class is marked as final */
+ bool isFinal() const;
+
+ /** Returns TRUE if this class is marked as sealed */
+ bool isSealed() const;
+
+ /** Returns TRUE if this class is marked as published */
+ bool isPublished() const;
+
+ /** Returns TRUE if this class represents an Objective-C 2.0 extension (nameless category) */
+ bool isExtension() const;
+
+ /** Returns TRUE if this class represents a forward declaration of a template class */
+ bool isForwardDeclared() const;
+
+ /** Returns the class of which this is a category (Objective-C only) */
+ ClassDef *categoryOf() const;
+
+ /** Returns the name of the class including outer classes, but not
+ * including namespaces.
+ */
+ QCString className() const;
+
+ /** Returns the members in the list identified by \a lt */
+ MemberList *getMemberList(MemberListType lt);
+
+ /** Returns the list containing the list of members sorted per type */
+ const QList<MemberList> &getMemberLists() const;
+
+ /** Returns the member groups defined for this class */
+ MemberGroupSDict *getMemberGroupSDict() const;
+
+ QDict<int> *getTemplateBaseClassNames() const;
+
+ ClassDef *getVariableInstance(const char *templSpec);
+
+ bool isUsedOnly() const;
+
+ QCString anchor() const;
+ bool isEmbeddedInOuterScope() const;
+
+ bool isSimple() const;
+
+ const ClassList *taggedInnerClasses() const;
+ ClassDef *tagLessReference() const;
+
+ MemberDef *isSmartPointer() const;
+
+ bool isJavaEnum() const;
+
+ bool isGeneric() const;
+ bool isAnonymous() const;
+ const ClassSDict *innerClasses() const;
+ QCString title() const;
+
+ QCString generatedFromFiles() const;
+ const FileList &usedFiles() const;
+
+ const ArgumentList *typeConstraints() const;
+ const ExampleSDict *exampleList() const;
+ bool hasExamples() const;
+ QCString getMemberListFileName() const;
+ bool subGrouping() const;
+
+
+ //-----------------------------------------------------------------------------------
+ // --- setters ----
+ //-----------------------------------------------------------------------------------
+
+ void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0);
+ void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0);
+ void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force);
+ void insertMember(MemberDef *);
+ void insertUsedFile(FileDef *);
+ bool addExample(const char *anchor,const char *name, const char *file);
+ void mergeCategory(ClassDef *category);
+ void setNamespace(NamespaceDef *nd);
+ void setFileDef(FileDef *fd);
+ void setSubGrouping(bool enabled);
+ void setProtection(Protection p);
+ void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs);
+ void addInnerCompound(Definition *d);
+ ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn,
+ const QCString &templSpec,bool &freshInstance);
+ void addUsedClass(ClassDef *cd,const char *accessName,Protection prot);
+ void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot);
+ void setIsStatic(bool b);
+ void setCompoundType(CompoundType t);
+ void setClassName(const char *name);
+ void setClassSpecifier(uint64 spec);
+
+ void setTemplateArguments(ArgumentList *al);
+ void setTemplateBaseClassNames(QDict<int> *templateNames);
+ void setTemplateMaster(ClassDef *tm);
+ void setTypeConstraints(ArgumentList *al);
+ void addMembersToTemplateInstance(ClassDef *cd,const char *templSpec);
+ void makeTemplateArgument(bool b=TRUE);
+ void setCategoryOf(ClassDef *cd);
+ void setUsedOnly(bool b);
+
+ void addTaggedInnerClass(ClassDef *cd);
+ void setTagLessReference(ClassDef *cd);
+ void setName(const char *name);
+
+ //-----------------------------------------------------------------------------------
+ // --- actions ----
+ //-----------------------------------------------------------------------------------
+
+ void findSectionsInDocumentation();
+ void addMembersToMemberGroup();
+ void addListReferences();
+ void computeAnchors();
+ void mergeMembers();
+ void sortMemberLists();
+ void distributeMemberGroupDocumentation();
+ void writeDocumentation(OutputList &ol);
+ void writeDocumentationForInnerClasses(OutputList &ol);
+ void writeMemberPages(OutputList &ol);
+ void writeMemberList(OutputList &ol);
+ void writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup,
+ ClassDef *inheritedFrom,const char *inheritId);
+ void writeQuickMemberLinks(OutputList &ol,MemberDef *md) const;
+ void writeSummaryLinks(OutputList &ol);
+ void reclassifyMember(MemberDef *md,MemberType t);
+ void writeInlineDocumentation(OutputList &ol);
+ void writeDeclarationLink(OutputList &ol,bool &found,
+ const char *header,bool localNames);
+ void removeMemberFromLists(MemberDef *md);
+ void addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
+ ClassDef *inheritedFrom,const QCString &inheritId);
+ int countMembersIncludingGrouped(MemberListType lt,ClassDef *inheritedFrom,bool additional);
+ int countInheritanceNodes();
+
+ bool visited;
+
+ protected:
+ void addUsedInterfaceClasses(MemberDef *md,const char *typeStr);
+ bool hasNonReferenceSuperClass();
+ void showUsedFiles(OutputList &ol);
+
+ private:
+ void writeTagFileMarker();
+ void writeDocumentationContents(OutputList &ol,const QCString &pageTitle);
+ void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList);
+ void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief);
+ MemberList *createMemberList(MemberListType lt);
+ void writeInheritedMemberDeclarations(OutputList &ol,MemberListType lt,int lt2,const QCString &title,ClassDef *inheritedFrom,bool invert,bool showAlways,QPtrDict<void> *visitedClasses);
+ void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title,
+ const char *subTitle=0,bool showInline=FALSE,ClassDef *inheritedFrom=0,int lt2=-1,bool invert=FALSE,bool showAlways=FALSE,QPtrDict<void> *visitedClasses=0);
+ void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline=FALSE);
+ void writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt);
+ void writePlainMemberDeclaration(OutputList &ol,MemberListType lt,bool inGroup,ClassDef *inheritedFrom,const char *inheritId);
+ void writeBriefDescription(OutputList &ol,bool exampleFlag);
+ void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag,
+ const QCString &title,const QCString &anchor=QCString());
+ void writeIncludeFiles(OutputList &ol);
+ //void writeAllMembersLink(OutputList &ol);
+ void writeInheritanceGraph(OutputList &ol);
+ void writeCollaborationGraph(OutputList &ol);
+ void writeMemberGroups(OutputList &ol,bool showInline=FALSE);
+ void writeNestedClasses(OutputList &ol,const QCString &title);
+ void writeInlineClasses(OutputList &ol);
+ void startMemberDeclarations(OutputList &ol);
+ void endMemberDeclarations(OutputList &ol);
+ void startMemberDocumentation(OutputList &ol);
+ void endMemberDocumentation(OutputList &ol);
+ void writeAuthorSection(OutputList &ol);
+ void writeMoreLink(OutputList &ol,const QCString &anchor);
+ void writeDetailedDocumentationBody(OutputList &ol);
+
+ int countAdditionalInheritedMembers();
+ void writeAdditionalInheritedMembers(OutputList &ol);
+ void addClassAttributes(OutputList &ol);
+ int countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom,
+ int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses);
+ int countInheritedDecMembers(MemberListType lt,
+ ClassDef *inheritedFrom,bool invert,bool showAlways,
+ QPtrDict<void> *visitedClasses);
+ void getTitleForMemberListType(MemberListType type,
+ QCString &title,QCString &subtitle);
+ QCString includeStatement() const;
+
+
+ ClassDefImpl *m_impl;
+
+};
+
+/** Class that contains information about a usage relation.
+ */
+struct UsesClassDef
+{
+ UsesClassDef(ClassDef *cd) : classDef(cd)
+ {
+ accessors = new QDict<void>(17);
+ containment = TRUE;
+ }
+ ~UsesClassDef()
+ {
+ delete accessors;
+ }
+ void addAccessor(const char *s)
+ {
+ if (accessors->find(s)==0)
+ {
+ accessors->insert(s,(void *)666);
+ }
+ }
+ /** Class definition that this relation uses. */
+ ClassDef *classDef;
+
+ /** Dictionary of member variable names that form the edge labels of the
+ * usage relation.
+ */
+ QDict<void> *accessors;
+
+ /** Template arguments used for the base class */
+ QCString templSpecifiers;
+
+ bool containment;
+};
+
+/** Dictionary of usage relations.
+ */
+class UsesClassDict : public QDict<UsesClassDef>
+{
+ public:
+ UsesClassDict(int size) : QDict<UsesClassDef>(size) {}
+ ~UsesClassDict() {}
+};
+
+/** Iterator class to iterate over a dictionary of usage relations.
+ */
+class UsesClassDictIterator : public QDictIterator<UsesClassDef>
+{
+ public:
+ UsesClassDictIterator(const QDict<UsesClassDef> &d)
+ : QDictIterator<UsesClassDef>(d) {}
+ ~UsesClassDictIterator() {}
+};
+
+/** Class that contains information about an inheritance relation.
+ */
+struct BaseClassDef
+{
+ BaseClassDef(ClassDef *cd,const char *n,Protection p,
+ Specifier v,const char *t) :
+ classDef(cd), usedName(n), prot(p), virt(v), templSpecifiers(t) {}
+
+ /** Class definition that this relation inherits from. */
+ ClassDef *classDef;
+
+ /** name used in the inheritance list
+ * (may be a typedef name instead of the class name)
+ */
+ QCString usedName;
+
+ /** Protection level of the inheritance relation:
+ * Public, Protected, or Private
+ */
+ Protection prot;
+
+ /** Virtualness of the inheritance relation:
+ * Normal, or Virtual
+ */
+ Specifier virt;
+
+ /** Template arguments used for the base class */
+ QCString templSpecifiers;
+};
+
+/** List of base classes.
+ *
+ * The classes are alphabetically sorted on name if inSort() is used.
+ */
+class BaseClassList : public QList<BaseClassDef>
+{
+ public:
+ ~BaseClassList() {}
+ int compareValues(const BaseClassDef *item1,const BaseClassDef *item2) const
+ {
+ const ClassDef *c1=item1->classDef;
+ const ClassDef *c2=item2->classDef;
+ if (c1==0 || c2==0)
+ return FALSE;
+ else
+ return qstricmp(c1->name(),c2->name());
+ }
+};
+
+/** Iterator for a list of base classes.
+ */
+class BaseClassListIterator : public QListIterator<BaseClassDef>
+{
+ public:
+ BaseClassListIterator(const BaseClassList &bcl) :
+ QListIterator<BaseClassDef>(bcl) {}
+};
+
+#endif
diff --git a/src/classlist.cpp b/src/classlist.cpp
new file mode 100644
index 0000000..6615a99
--- /dev/null
+++ b/src/classlist.cpp
@@ -0,0 +1,211 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "classlist.h"
+#include "config.h"
+#include "util.h"
+#include "outputlist.h"
+#include "language.h"
+#include "doxygen.h"
+#include "vhdldocgen.h"
+#include "defargs.h"
+#include "arguments.h"
+#include "groupdef.h"
+
+ClassList::ClassList() : QList<ClassDef>()
+{
+}
+
+ClassList::~ClassList()
+{
+}
+
+static int compItems(const ClassDef *c1,const ClassDef *c2)
+{
+ static bool b = Config_getBool("SORT_BY_SCOPE_NAME");
+ if (b)
+ {
+ return qstricmp(c1->name(), c2->name());
+ }
+ else
+ {
+ return qstricmp(c1->className(), c2->className());
+ }
+}
+
+int ClassList::compareValues(const ClassDef *item1, const ClassDef *item2) const
+{
+ return compItems(item1,item2);
+}
+
+int ClassSDict::compareValues(const ClassDef *item1, const ClassDef *item2) const
+{
+ return compItems(item1,item2);
+}
+
+ClassListIterator::ClassListIterator(const ClassList &cllist) :
+ QListIterator<ClassDef>(cllist)
+{
+}
+
+bool ClassSDict::declVisible(const ClassDef::CompoundType *filter) const
+{
+ static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
+ static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
+ if (count()>0)
+ {
+ ClassSDict::Iterator sdi(*this);
+ ClassDef *cd=0;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->name().find('@')==-1 &&
+ (filter==0 || *filter==cd->compoundType())
+ )
+ {
+ bool isLink = cd->isLinkable();
+ if (isLink ||
+ (!hideUndocClasses &&
+ (!cd->isLocal() || extractLocalClasses)
+ )
+ )
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter,
+ const char *header,bool localNames)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ if (count()>0)
+ {
+ ClassSDict::Iterator sdi(*this);
+ ClassDef *cd=0;
+ bool found=FALSE;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ //printf(" ClassSDict::writeDeclaration for %s\n",cd->name().data());
+ if (cd->name().find('@')==-1 &&
+ !cd->isExtension() &&
+ (cd->protection()!=Private || extractPrivate) &&
+ (filter==0 || *filter==cd->compoundType())
+ )
+ {
+ cd->writeDeclarationLink(ol,found,header,localNames);
+ }
+ }
+ if (found) ol.endMemberList();
+ }
+}
+
+void ClassSDict::writeDocumentation(OutputList &ol,Definition * container)
+{
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+
+ static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ if (!inlineGroupedClasses && !inlineSimpleClasses) return;
+
+ if (count()>0)
+ {
+ bool found=FALSE;
+
+ ClassSDict::Iterator sdi(*this);
+ ClassDef *cd=0;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ //printf("%s:writeDocumentation() %p linkable=%d embedded=%d container=%p partOfGroups=%d\n",
+ // cd->name().data(),cd->getOuterScope(),cd->isLinkableInProject(),cd->isEmbeddedInOuterScope(),
+ // container,cd->partOfGroups() ? cd->partOfGroups()->count() : 0);
+
+ if (cd->name().find('@')==-1 &&
+ cd->isLinkableInProject() &&
+ cd->isEmbeddedInOuterScope() &&
+ (container==0 || cd->partOfGroups()==0) // if container==0 -> show as part of the group docs, otherwise only show if not part of a group
+ )
+ {
+ //printf(" showing class %s\n",cd->name().data());
+ if (!found)
+ {
+ ol.writeRuler();
+ ol.startGroupHeader();
+ ol.parseText(fortranOpt?theTranslator->trTypeDocumentation():
+ theTranslator->trClassDocumentation());
+ ol.endGroupHeader();
+ found=TRUE;
+ }
+ cd->writeInlineDocumentation(ol);
+ }
+ }
+ }
+}
+
+//-------------------------------------------
+
+void GenericsSDict::insert(const QCString &key,ClassDef *cd)
+{
+ int i=key.find('<');
+ if (i==-1) return;
+ ArgumentList argList;
+ stringToArgumentList(key.mid(i),&argList);
+ int c = argList.count();
+ if (c==0) return;
+ GenericsCollection *collection = m_dict.find(key.left(i));
+ if (collection==0) // new name
+ {
+ collection = new GenericsCollection;
+ m_dict.append(key.left(i),collection);
+ }
+ if (collection->find(c)==0) // should always be 0!
+ {
+ collection->insert(c,cd);
+ }
+}
+
+ClassDef *GenericsSDict::find(const QCString &key)
+{
+ int i=key.find('<');
+ if (i==-1)
+ {
+ GenericsCollection *collection = m_dict.find(key);
+ if (collection && collection->count()==1)
+ {
+ QIntDictIterator<ClassDef> it(*collection);
+ return it.current();
+ }
+ }
+ else
+ {
+ GenericsCollection *collection = m_dict.find(key.left(i));
+ if (collection)
+ {
+ ArgumentList argList;
+ stringToArgumentList(key.mid(i),&argList);
+ int c = argList.count();
+ return collection->find(c);
+ }
+ }
+ return 0;
+}
+
+
+
+
diff --git a/src/classlist.h b/src/classlist.h
new file mode 100644
index 0000000..3f15b3e
--- /dev/null
+++ b/src/classlist.h
@@ -0,0 +1,87 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CLASSLIST_H
+#define CLASSLIST_H
+
+#include <qlist.h>
+#include <qdict.h>
+
+#include "classdef.h"
+#include "sortdict.h"
+
+class Definition;
+
+/** A list of ClassDef objects. */
+class ClassList : public QList<ClassDef>
+{
+ public:
+ ClassList();
+ ~ClassList();
+
+ private:
+ int compareValues(const ClassDef *item1,const ClassDef *item2) const;
+};
+
+/** An iterator for ClassDef objects in a ClassList. */
+class ClassListIterator : public QListIterator<ClassDef>
+{
+ public:
+ ClassListIterator(const ClassList &list);
+};
+
+/** An unsorted dictionary of ClassDef objects. */
+class ClassDict : public QDict<ClassDef>
+{
+ public:
+ ClassDict(int size) : QDict<ClassDef>(size) {}
+ ~ClassDict() {}
+};
+
+/** A sorted dictionary of ClassDef objects. */
+class ClassSDict : public SDict<ClassDef>
+{
+ public:
+ ClassSDict(int size=17) : SDict<ClassDef>(size) {}
+ ~ClassSDict() {}
+ void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0,
+ const char *header=0,bool localNames=FALSE);
+ void writeDocumentation(OutputList &ol,Definition *container=0);
+ bool declVisible(const ClassDef::CompoundType *filter=0) const;
+ private:
+ int compareValues(const ClassDef *item1,const ClassDef *item2) const;
+};
+
+class GenericsCollection : public QIntDict<ClassDef>
+{
+ public:
+ GenericsCollection() : QIntDict<ClassDef>(17) {}
+ ~GenericsCollection() {}
+};
+
+class GenericsSDict
+{
+ public:
+ GenericsSDict() : m_dict(17) { m_dict.setAutoDelete(TRUE); }
+ ~GenericsSDict() {}
+ void insert(const QCString &key,ClassDef *cd);
+ ClassDef *find(const QCString &key);
+ private:
+ SDict<GenericsCollection> m_dict;
+};
+
+#endif
diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp
new file mode 100644
index 0000000..b0ca85f
--- /dev/null
+++ b/src/cmdmapper.cpp
@@ -0,0 +1,246 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "cmdmapper.h"
+
+/** Call representing a mapping from a command name to a command ID. */
+struct CommandMap
+{
+ const char *cmdName;
+ int cmdId;
+};
+
+CommandMap cmdMap[] =
+{
+ { "a", CMD_EMPHASIS },
+ { "addindex", CMD_ADDINDEX },
+ { "anchor", CMD_ANCHOR },
+ { "arg", CMD_LI },
+ { "attention", CMD_ATTENTION },
+ { "author", CMD_AUTHOR },
+ { "authors", CMD_AUTHORS },
+ { "b", CMD_BOLD },
+ { "c", CMD_CODE },
+ { "cite", CMD_CITE },
+ { "code", CMD_STARTCODE },
+ { "copydoc", CMD_COPYDOC },
+ { "copybrief", CMD_COPYBRIEF },
+ { "copydetails", CMD_COPYDETAILS },
+ { "copyright", CMD_COPYRIGHT },
+ { "date", CMD_DATE },
+ { "dontinclude", CMD_DONTINCLUDE },
+ { "dotfile", CMD_DOTFILE },
+ { "e", CMD_EMPHASIS },
+ { "em", CMD_EMPHASIS },
+ { "endcode", CMD_ENDCODE },
+ { "endhtmlonly", CMD_ENDHTMLONLY },
+ { "endlatexonly", CMD_ENDLATEXONLY },
+ { "endlink", CMD_ENDLINK },
+ { "endsecreflist", CMD_ENDSECREFLIST },
+ { "endverbatim", CMD_ENDVERBATIM },
+ { "endxmlonly", CMD_ENDXMLONLY },
+ { "exception", CMD_EXCEPTION },
+ { "form", CMD_FORMULA },
+ { "htmlinclude", CMD_HTMLINCLUDE },
+ { "htmlonly", CMD_HTMLONLY },
+ { "image", CMD_IMAGE },
+ { "include", CMD_INCLUDE },
+ { "internal", CMD_INTERNAL },
+ { "invariant", CMD_INVARIANT },
+ { "javalink", CMD_JAVALINK },
+ { "latexinclude", CMD_LATEXINCLUDE },
+ { "latexonly", CMD_LATEXONLY },
+ { "li", CMD_LI },
+ { "line", CMD_LINE },
+ { "link", CMD_LINK },
+ { "n", CMD_LINEBREAK },
+ { "note", CMD_NOTE },
+ { "p", CMD_CODE },
+ { "par", CMD_PAR },
+ { "param", CMD_PARAM },
+ { "post", CMD_POST },
+ { "pre", CMD_PRE },
+ { "ref", CMD_REF },
+ { "refitem", CMD_SECREFITEM },
+ { "remark", CMD_REMARK },
+ { "remarks", CMD_REMARK },
+ { "result", CMD_RETURN },
+ { "return", CMD_RETURN },
+ { "returns", CMD_RETURN },
+ { "retval", CMD_RETVAL },
+ { "rtfonly", CMD_RTFONLY },
+ { "sa", CMD_SA },
+ { "secreflist", CMD_SECREFLIST },
+ { "section", CMD_SECTION },
+ { "snippet", CMD_SNIPPET },
+ { "subpage", CMD_SUBPAGE },
+ { "subsection", CMD_SUBSECTION },
+ { "subsubsection", CMD_SUBSUBSECTION },
+ { "paragraph", CMD_PARAGRAPH },
+ { "see", CMD_SA },
+ { "since", CMD_SINCE },
+ { "skip", CMD_SKIP },
+ { "skipline", CMD_SKIPLINE },
+ { "xmlonly", CMD_XMLONLY },
+ { "xrefitem", CMD_XREFITEM },
+ { "throw", CMD_EXCEPTION },
+ { "until", CMD_UNTIL },
+ { "verbatim", CMD_VERBATIM },
+ { "verbinclude", CMD_VERBINCLUDE },
+ { "version", CMD_VERSION },
+ { "warning", CMD_WARNING },
+ { "throws", CMD_EXCEPTION },
+ { "tparam", CMD_TPARAM },
+ { "\\", CMD_BSLASH },
+ { "@", CMD_AT },
+ { "<", CMD_LESS },
+ { ">", CMD_GREATER },
+ { "&", CMD_AMP },
+ { "$", CMD_DOLLAR },
+ { "#", CMD_HASH },
+ { "%", CMD_PERCENT },
+ { "|", CMD_PIPE },
+ { "::", CMD_DCOLON },
+ { "\"", CMD_QUOTE },
+ { "_internalref", CMD_INTERNALREF },
+ { "dot", CMD_DOT },
+ { "msc", CMD_MSC },
+ { "startuml", CMD_STARTUML },
+ { "enddot", CMD_ENDDOT },
+ { "endmsc", CMD_ENDMSC },
+ { "enduml", CMD_ENDUML },
+ { "manonly", CMD_MANONLY },
+ { "endmanonly", CMD_ENDMANONLY },
+ { "includelineno", CMD_INCWITHLINES },
+ { "inheritdoc", CMD_INHERITDOC },
+ { "mscfile", CMD_MSCFILE },
+ { "rtfonly", CMD_RTFONLY },
+ { "endrtfonly", CMD_ENDRTFONLY },
+ { "vhdlflow", CMD_VHDLFLOW },
+ { "docbookonly", CMD_DBONLY },
+ { "enddocbookonly",CMD_ENDDBONLY },
+ { "endinternal", CMD_ENDINTERNAL },
+ { "parblock", CMD_PARBLOCK },
+ { "endparblock", CMD_ENDPARBLOCK },
+ { "diafile", CMD_DIAFILE },
+ { "--", CMD_NDASH },
+ { "---", CMD_MDASH },
+ { 0, 0 },
+};
+
+//----------------------------------------------------------------------------
+
+CommandMap htmlTagMap[] =
+{
+ { "strong", HTML_BOLD },
+ { "center", HTML_CENTER },
+ { "table", HTML_TABLE },
+ { "caption", HTML_CAPTION },
+ { "small", HTML_SMALL },
+ { "code", HTML_CODE },
+ { "dfn", HTML_CODE },
+ { "var", HTML_EMPHASIS },
+ { "img", HTML_IMG },
+ { "pre", HTML_PRE },
+ { "sub", HTML_SUB },
+ { "sup", HTML_SUP },
+ { "tr", HTML_TR },
+ { "td", HTML_TD },
+ { "th", HTML_TH },
+ { "ol", HTML_OL },
+ { "ul", HTML_UL },
+ { "li", HTML_LI },
+ { "tt", XML_C /*HTML_CODE*/ },
+ { "kbd", XML_C /*HTML_CODE*/ },
+ { "em", HTML_EMPHASIS },
+ { "hr", HTML_HR },
+ { "dl", HTML_DL },
+ { "dt", HTML_DT },
+ { "dd", HTML_DD },
+ { "br", HTML_BR },
+ { "i", HTML_EMPHASIS },
+ { "a", HTML_A },
+ { "b", HTML_BOLD },
+ { "p", HTML_P },
+ { "h1", HTML_H1 },
+ { "h2", HTML_H2 },
+ { "h3", HTML_H3 },
+ { "h4", HTML_H4 },
+ { "h5", HTML_H5 },
+ { "h6", HTML_H6 },
+ { "span", HTML_SPAN },
+ { "div", HTML_DIV },
+ { "blockquote", HTML_BLOCKQUOTE },
+
+ { "c", XML_C },
+ // { "code", XML_CODE }, <= ambiguous <code> is also a HTML tag
+ { "description", XML_DESCRIPTION },
+ { "example", XML_EXAMPLE },
+ { "exception", XML_EXCEPTION },
+ { "include", XML_INCLUDE },
+ { "item", XML_ITEM },
+ { "list", XML_LIST }, // type="table|bullet|number"
+ { "listheader", XML_LISTHEADER },
+ { "para", XML_PARA },
+ { "param", XML_PARAM },
+ { "paramref", XML_PARAMREF },
+ { "typeparam", XML_TYPEPARAM },
+ { "typeparamref", XML_TYPEPARAMREF },
+ { "permission", XML_PERMISSION },
+ { "remarks", XML_REMARKS },
+ { "returns", XML_RETURNS },
+ { "see", XML_SEE },
+ { "seealso", XML_SEEALSO },
+ { "summary", XML_SUMMARY },
+ { "term", XML_TERM },
+ { "value", XML_VALUE },
+ { "inheritdoc", XML_INHERITDOC },
+ { 0, 0 }
+};
+
+//----------------------------------------------------------------------------
+
+Mapper *Mappers::cmdMapper = new Mapper(cmdMap,TRUE);
+Mapper *Mappers::htmlTagMapper = new Mapper(htmlTagMap,FALSE);
+
+int Mapper::map(const char *n)
+{
+ QCString name=n;
+ if (!m_cs) name=name.lower();
+ int *result;
+ return !name.isEmpty() && (result=m_map.find(name)) ? *result: 0;
+}
+
+Mapper::Mapper(const CommandMap *cm,bool caseSensitive) : m_map(89), m_cs(caseSensitive)
+{
+ m_map.setAutoDelete(TRUE);
+ const CommandMap *p = cm;
+ while (p->cmdName)
+ {
+ m_map.insert(p->cmdName,new int(p->cmdId));
+ p++;
+ }
+}
+
+void Mappers::freeMappers()
+{
+ delete cmdMapper; cmdMapper = 0;
+ delete htmlTagMapper; htmlTagMapper = 0;
+}
+
+
diff --git a/src/cmdmapper.h b/src/cmdmapper.h
new file mode 100644
index 0000000..75fd8ec
--- /dev/null
+++ b/src/cmdmapper.h
@@ -0,0 +1,219 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _CMDMAPPER_H
+#define _CMDMAPPER_H
+
+#include <qdict.h>
+
+struct CommandMap;
+
+const int SIMPLESECT_BIT = 0x1000;
+
+enum CommandType
+{
+ CMD_UNKNOWN = 0,
+ CMD_ADDINDEX = 1,
+ CMD_AMP = 2,
+ CMD_ANCHOR = 3,
+ CMD_AT = 4,
+ CMD_ATTENTION = 5 | SIMPLESECT_BIT,
+ CMD_AUTHOR = 6 | SIMPLESECT_BIT,
+ CMD_AUTHORS = 7 | SIMPLESECT_BIT,
+ CMD_BOLD = 8,
+ CMD_BSLASH = 9,
+ CMD_CODE = 10,
+ CMD_COPYDOC = 11,
+ CMD_DATE = 12 | SIMPLESECT_BIT,
+ CMD_DOLLAR = 13,
+ CMD_DONTINCLUDE = 14,
+ CMD_DOTFILE = 15,
+ CMD_EMPHASIS = 16,
+ CMD_ENDCODE = 17,
+ CMD_ENDHTMLONLY = 18,
+ CMD_ENDLATEXONLY = 19,
+ CMD_ENDLINK = 20,
+ CMD_ENDSECREFLIST= 21,
+ CMD_ENDVERBATIM = 22,
+ CMD_ENDXMLONLY = 23,
+ CMD_EXCEPTION = 24 | SIMPLESECT_BIT,
+ CMD_FORMULA = 25,
+ CMD_GREATER = 26,
+ CMD_HASH = 27,
+ CMD_HTMLINCLUDE = 28,
+ CMD_HTMLONLY = 29,
+ CMD_IMAGE = 30,
+ CMD_INCLUDE = 31,
+ CMD_INTERNAL = 32,
+ CMD_INTERNALREF = 33,
+ CMD_INVARIANT = 34 | SIMPLESECT_BIT ,
+ CMD_LATEXONLY = 35,
+ CMD_LESS = 36,
+ CMD_LI = 37,
+ CMD_LINE = 38,
+ CMD_LINEBREAK = 39,
+ CMD_LINK = 40,
+ CMD_NOTE = 41 | SIMPLESECT_BIT,
+ CMD_PAR = 42 | SIMPLESECT_BIT,
+ CMD_PARAM = 43 | SIMPLESECT_BIT,
+ CMD_PERCENT = 44,
+ CMD_POST = 45 | SIMPLESECT_BIT,
+ CMD_PRE = 46 | SIMPLESECT_BIT,
+ CMD_REF = 47,
+ CMD_SECREFITEM = 48,
+ CMD_REMARK = 49 | SIMPLESECT_BIT ,
+ CMD_RETURN = 50 | SIMPLESECT_BIT ,
+ CMD_RETVAL = 51 | SIMPLESECT_BIT,
+ CMD_SA = 52 | SIMPLESECT_BIT ,
+ CMD_SECREFLIST = 53,
+ CMD_SECTION = 54,
+ CMD_SUBPAGE = 55,
+ CMD_SUBSECTION = 56,
+ CMD_SUBSUBSECTION= 57,
+ CMD_PARAGRAPH = 58,
+ CMD_SINCE = 59 | SIMPLESECT_BIT,
+ CMD_SKIP = 60,
+ CMD_SKIPLINE = 61,
+ CMD_STARTCODE = 62,
+ CMD_JAVALINK = 63,
+ CMD_UNTIL = 64,
+ CMD_VERBATIM = 65,
+ CMD_VERBINCLUDE = 66,
+ CMD_VERSION = 67 | SIMPLESECT_BIT,
+ CMD_WARNING = 68 | SIMPLESECT_BIT,
+ CMD_XREFITEM = 69 | SIMPLESECT_BIT,
+ CMD_XMLONLY = 70,
+ CMD_DOT = 71,
+ CMD_ENDDOT = 72,
+ CMD_MSC = 73,
+ CMD_ENDMSC = 74,
+ CMD_MANONLY = 75,
+ CMD_ENDMANONLY = 76,
+ CMD_INCWITHLINES = 77,
+ CMD_INHERITDOC = 78,
+ CMD_TPARAM = 79 | SIMPLESECT_BIT,
+ CMD_COPYBRIEF = 80,
+ CMD_COPYDETAILS = 81,
+ CMD_QUOTE = 82,
+ CMD_MSCFILE = 83,
+ CMD_DCOLON = 84,
+ CMD_COPYRIGHT = 85 | SIMPLESECT_BIT,
+ CMD_CITE = 86,
+ CMD_SNIPPET = 87,
+ CMD_RTFONLY = 88,
+ CMD_ENDRTFONLY = 89,
+ CMD_PIPE = 90,
+ CMD_VHDLFLOW = 91,
+ CMD_DBONLY = 92,
+ CMD_ENDDBONLY = 93,
+ CMD_ENDINTERNAL = 94,
+ CMD_PARBLOCK = 95,
+ CMD_ENDPARBLOCK = 96,
+ CMD_DIAFILE = 97,
+ CMD_LATEXINCLUDE = 98,
+ CMD_NDASH = 99,
+ CMD_MDASH = 100,
+ CMD_STARTUML = 101,
+ CMD_ENDUML = 102
+};
+
+enum HtmlTagType
+{
+ HTML_UNKNOWN = 0,
+ HTML_CENTER = 1,
+ HTML_TABLE = 2,
+ HTML_CAPTION = 3,
+ HTML_SMALL = 4,
+ HTML_CODE = 5,
+ HTML_IMG = 6,
+ HTML_PRE = 7,
+ HTML_SUB = 8,
+ HTML_SUP = 9,
+ HTML_TR = 10,
+ HTML_TD = 11,
+ HTML_TH = 12,
+ HTML_OL = 13,
+ HTML_UL = 14,
+ HTML_LI = 15,
+ HTML_EMPHASIS = 16,
+ HTML_HR = 17,
+ HTML_DL = 18,
+ HTML_DT = 19,
+ HTML_DD = 20,
+ HTML_BR = 21,
+ HTML_A = 22,
+ HTML_BOLD = 23,
+ HTML_P = 24,
+ HTML_H1 = 25,
+ HTML_H2 = 26,
+ HTML_H3 = 27,
+ HTML_H4 = 28,
+ HTML_H5 = 29,
+ HTML_H6 = 30,
+ HTML_SPAN = 31,
+ HTML_DIV = 32,
+ HTML_BLOCKQUOTE= 33,
+
+ XML_CmdMask = 0x100,
+
+ XML_C = XML_CmdMask + 0,
+ XML_CODE = XML_CmdMask + 1,
+ XML_DESCRIPTION = XML_CmdMask + 2,
+ XML_EXAMPLE = XML_CmdMask + 3,
+ XML_EXCEPTION = XML_CmdMask + 4,
+ XML_INCLUDE = XML_CmdMask + 5,
+ XML_ITEM = XML_CmdMask + 6,
+ XML_LIST = XML_CmdMask + 7,
+ XML_LISTHEADER = XML_CmdMask + 8,
+ XML_PARA = XML_CmdMask + 9,
+ XML_PARAM = XML_CmdMask + 10,
+ XML_PARAMREF = XML_CmdMask + 11,
+ XML_PERMISSION = XML_CmdMask + 12,
+ XML_REMARKS = XML_CmdMask + 13,
+ XML_RETURNS = XML_CmdMask + 14,
+ XML_SEE = XML_CmdMask + 15,
+ XML_SEEALSO = XML_CmdMask + 16,
+ XML_SUMMARY = XML_CmdMask + 17,
+ XML_TERM = XML_CmdMask + 18,
+ XML_TYPEPARAM = XML_CmdMask + 19,
+ XML_TYPEPARAMREF = XML_CmdMask + 20,
+ XML_VALUE = XML_CmdMask + 21,
+ XML_INHERITDOC = XML_CmdMask + 22
+};
+
+/** Class representing a mapping from command names to command IDs. */
+class Mapper
+{
+ public:
+ int map(const char *n);
+ Mapper(const CommandMap *cm,bool caseSensitive);
+ private:
+ QDict<int> m_map;
+ bool m_cs;
+};
+
+/** Class representing a namespace for the doxygen and HTML command mappers. */
+struct Mappers
+{
+ static void freeMappers();
+ static Mapper *cmdMapper;
+ static Mapper *htmlTagMapper;
+};
+
+
+#endif
diff --git a/src/code.h b/src/code.h
new file mode 100644
index 0000000..72a906c
--- /dev/null
+++ b/src/code.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CODE_H
+#define CODE_H
+
+#include "types.h"
+
+class CodeOutputInterface;
+class FileDef;
+class MemberDef;
+class QCString;
+class Definition;
+
+void parseCCode(CodeOutputInterface &,const char *,const QCString &,
+ SrcLangExt lang, bool isExample, const char *exName,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
+ bool collectXRefs);
+void resetCCodeParserState();
+void codeFreeScanner();
+
+#endif
diff --git a/src/code.l b/src/code.l
new file mode 100644
index 0000000..d96067e
--- /dev/null
+++ b/src/code.l
@@ -0,0 +1,3702 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <qregexp.h>
+#include <qdir.h>
+
+#include "entry.h"
+#include "doxygen.h"
+#include "message.h"
+#include "outputlist.h"
+#include "util.h"
+#include "membername.h"
+#include "searchindex.h"
+#include "arguments.h"
+#include "config.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "filename.h"
+#include "namespacedef.h"
+#include "tooltip.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+
+#define CLASSBLOCK (int *)4
+#define SCOPEBLOCK (int *)8
+#define INNERBLOCK (int *)12
+
+/* -----------------------------------------------------------------
+ * statics
+ */
+
+static CodeOutputInterface * g_code;
+
+static ClassSDict *g_codeClassSDict = 0;
+static QCString g_curClassName;
+static QStrList g_curClassBases;
+
+static QCString g_parmType;
+static QCString g_parmName;
+
+static const char * g_inputString; //!< the code fragment as text
+static int g_inputPosition; //!< read offset during parsing
+static int g_inputLines; //!< number of line in the code fragment
+static int g_yyLineNr; //!< current line number
+static int g_yyColNr; //!< current column number
+static bool g_needsTermination;
+
+static bool g_exampleBlock;
+static QCString g_exampleName;
+static QCString g_exampleFile;
+
+static bool g_insideTemplate = FALSE;
+static QCString g_type;
+static QCString g_name;
+static QCString g_args;
+static QCString g_classScope;
+static QCString g_realScope;
+static QStack<int> g_scopeStack; //!< 1 if bracket starts a scope,
+ // 2 for internal blocks
+static int g_anchorCount;
+static FileDef * g_sourceFileDef;
+static bool g_lineNumbers;
+static Definition * g_currentDefinition;
+static MemberDef * g_currentMemberDef;
+static bool g_includeCodeFragment;
+static const char * g_currentFontClass;
+static bool g_searchingForBody;
+static bool g_insideBody;
+static int g_bodyCurlyCount;
+static QCString g_saveName;
+static QCString g_saveType;
+static QCString g_delimiter;
+
+static int g_bracketCount = 0;
+static int g_curlyCount = 0;
+static int g_sharpCount = 0;
+static bool g_inFunctionTryBlock = FALSE;
+static bool g_inForEachExpression = FALSE;
+
+static int g_lastTemplCastContext;
+static int g_lastSpecialCContext;
+static int g_lastStringContext;
+static int g_lastSkipCppContext;
+static int g_lastVerbStringContext;
+static int g_memCallContext;
+static int g_lastCContext;
+static int g_skipInlineInitContext;
+
+static bool g_insideObjC;
+static bool g_insideJava;
+static bool g_insideCS;
+static bool g_insidePHP;
+static bool g_insideProtocolList;
+
+static bool g_lexInit = FALSE;
+
+static QStack<int> g_classScopeLengthStack;
+
+static Definition *g_searchCtx;
+static bool g_collectXRefs;
+
+// context for an Objective-C method call
+struct ObjCCallCtx
+{
+ int id;
+ QCString methodName;
+ QCString objectTypeOrName;
+ ClassDef *objectType;
+ MemberDef *objectVar;
+ MemberDef *method;
+ QCString format;
+ int lexState;
+ int braceCount;
+};
+
+// globals for objective-C method calls
+static ObjCCallCtx *g_currentCtx=0;
+static int g_currentCtxId=0;
+static int g_currentNameId=0;
+static int g_currentObjId=0;
+static int g_currentWordId=0;
+static QStack<ObjCCallCtx> g_contextStack;
+static QIntDict<ObjCCallCtx> g_contextDict;
+static QIntDict<QCString> g_nameDict;
+static QIntDict<QCString> g_objectDict;
+static QIntDict<QCString> g_wordDict;
+static int g_braceCount=0;
+
+static void saveObjCContext();
+static void restoreObjCContext();
+
+static QCString g_forceTagReference;
+
+
+//-------------------------------------------------------------------
+
+/*! Represents a stack of variable to class mappings as found in the
+ * code. Each scope is enclosed in pushScope() and popScope() calls.
+ * Variables are added by calling addVariables() and one can search
+ * for variable using findVariable().
+ */
+class VariableContext
+{
+ public:
+ static const ClassDef *dummyContext;
+
+ class Scope : public SDict<ClassDef>
+ {
+ public:
+ Scope() : SDict<ClassDef>(17) {}
+ };
+
+ VariableContext()
+ {
+ m_scopes.setAutoDelete(TRUE);
+ }
+ virtual ~VariableContext()
+ {
+ }
+
+ void pushScope()
+ {
+ m_scopes.append(new Scope);
+ DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count()));
+ }
+
+ void popScope()
+ {
+ if (m_scopes.count()>0)
+ {
+ DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count()));
+ m_scopes.remove(m_scopes.count()-1);
+ }
+ else
+ {
+ DBG_CTX((stderr,"** ILLEGAL: Pop var context\n"));
+ }
+ }
+
+ void clear()
+ {
+ m_scopes.clear();
+ m_globalScope.clear();
+ }
+
+ void clearExceptGlobal()
+ {
+ DBG_CTX((stderr,"** Clear var context\n"));
+ m_scopes.clear();
+ }
+
+ void addVariable(const QCString &type,const QCString &name);
+ ClassDef *findVariable(const QCString &name);
+
+ int count() const { return m_scopes.count(); }
+
+ private:
+ Scope m_globalScope;
+ QList<Scope> m_scopes;
+};
+
+void VariableContext::addVariable(const QCString &type,const QCString &name)
+{
+ //printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data());
+ QCString ltype = type.simplifyWhiteSpace();
+ QCString lname = name.simplifyWhiteSpace();
+ if (ltype.left(7)=="struct ")
+ {
+ ltype = ltype.right(ltype.length()-7);
+ }
+ else if (ltype.left(6)=="union ")
+ {
+ ltype = ltype.right(ltype.length()-6);
+ }
+ if (ltype.isEmpty() || lname.isEmpty()) return;
+ DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n",
+ ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>"));
+ Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
+ ClassDef *varType;
+ int i=0;
+ if (
+ (varType=g_codeClassSDict->find(ltype)) || // look for class definitions inside the code block
+ (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
+ )
+ {
+ DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data()));
+ scope->append(lname,varType); // add it to a list
+ }
+ else if ((i=ltype.find('<'))!=-1)
+ {
+ // probably a template class
+ QCString typeName(ltype.left(i));
+ ClassDef* newDef = 0;
+ QCString templateArgs(ltype.right(ltype.length() - i));
+ if (
+ ( // look for class definitions inside the code block
+ (varType=g_codeClassSDict->find(typeName)) ||
+ // otherwise look for global class definitions
+ (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,typeName,0,0,TRUE,TRUE))
+ ) && // and it must be a template
+ varType->templateArguments())
+ {
+ newDef = varType->getVariableInstance( templateArgs );
+ }
+ if (newDef)
+ {
+ DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data()));
+ scope->append(lname, newDef);
+ }
+ else
+ {
+ // Doesn't seem to be a template. Try just the base name.
+ addVariable(typeName,name);
+ }
+ }
+ else
+ {
+ if (m_scopes.count()>0) // for local variables add a dummy entry so the name
+ // is hidden to avoid false links to global variables with the same name
+ // TODO: make this work for namespaces as well!
+ {
+ DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data()));
+ scope->append(lname,dummyContext);
+ }
+ else
+ {
+ DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
+ }
+ }
+}
+
+ClassDef *VariableContext::findVariable(const QCString &name)
+{
+ if (name.isEmpty()) return 0;
+ ClassDef *result = 0;
+ QListIterator<Scope> sli(m_scopes);
+ Scope *scope;
+ QCString key = name;
+ // search from inner to outer scope
+ for (sli.toLast();(scope=sli.current());--sli)
+ {
+ result = scope->find(key);
+ if (result)
+ {
+ DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
+ return result;
+ }
+ }
+ // nothing found -> also try the global scope
+ result=m_globalScope.find(name);
+ DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
+ return result;
+}
+
+static VariableContext g_theVarContext;
+const ClassDef *VariableContext::dummyContext = (ClassDef*)0x8;
+
+//-------------------------------------------------------------------
+
+class CallContext
+{
+ public:
+ struct Ctx
+ {
+ Ctx() : name(g_name), type(g_type), d(0) {}
+ QCString name;
+ QCString type;
+ Definition *d;
+ };
+
+ CallContext()
+ {
+ m_defList.append(new Ctx);
+ m_defList.setAutoDelete(TRUE);
+ }
+ virtual ~CallContext() {}
+ void setScope(Definition *d)
+ {
+ Ctx *ctx = m_defList.getLast();
+ if (ctx)
+ {
+ DBG_CTX((stderr,"** Set call context %s (%p)\n",d==0 ? "<null>" : d->name().data(),d));
+ ctx->d=d;
+ }
+ }
+ void pushScope()
+ {
+ m_defList.append(new Ctx);
+ DBG_CTX((stderr,"** Push call context %d\n",m_defList.count()));
+ }
+ void popScope()
+ {
+ if (m_defList.count()>1)
+ {
+ DBG_CTX((stderr,"** Pop call context %d\n",m_defList.count()));
+ Ctx *ctx = m_defList.getLast();
+ if (ctx)
+ {
+ g_name = ctx->name;
+ g_type = ctx->type;
+ }
+ m_defList.removeLast();
+ }
+ else
+ {
+ DBG_CTX((stderr,"** ILLEGAL: Pop call context\n"));
+ }
+ }
+ void clear()
+ {
+ DBG_CTX((stderr,"** Clear call context\n"));
+ m_defList.clear();
+ m_defList.append(new Ctx);
+ }
+ Definition *getScope() const
+ {
+ Ctx *ctx = m_defList.getLast();
+ if (ctx) return ctx->d; else return 0;
+ }
+
+ private:
+ QList<Ctx> m_defList;
+};
+
+static CallContext g_theCallContext;
+
+//-------------------------------------------------------------------
+
+/*! add class/namespace name s to the scope */
+static void pushScope(const char *s)
+{
+ g_classScopeLengthStack.push(new int(g_classScope.length()));
+ if (g_classScope.isEmpty() || leftScopeMatch(s,g_classScope))
+ {
+ g_classScope = s;
+ }
+ else
+ {
+ g_classScope += "::";
+ g_classScope += s;
+ }
+ //printf("pushScope(%s) result: `%s'\n",s,g_classScope.data());
+}
+
+/*! remove the top class/namespace name from the scope */
+static void popScope()
+{
+ if (!g_classScopeLengthStack.isEmpty())
+ {
+ int *pLength = g_classScopeLengthStack.pop();
+ g_classScope.truncate(*pLength);
+ delete pLength;
+ }
+ else
+ {
+ //err("Too many end of scopes found!\n");
+ }
+ //printf("popScope() result: `%s'\n",g_classScope.data());
+}
+
+static void setCurrentDoc(const QCString &anchor)
+{
+ if (Doxygen::searchIndex)
+ {
+ if (g_searchCtx)
+ {
+ g_code->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
+ }
+ else
+ {
+ g_code->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
+ }
+ }
+}
+
+static void addToSearchIndex(const char *text)
+{
+ if (Doxygen::searchIndex)
+ {
+ g_code->addWord(text,FALSE);
+ }
+}
+
+static void setClassScope(const QCString &name)
+{
+ //printf("setClassScope(%s)\n",name.data());
+ QCString n=name;
+ n=n.simplifyWhiteSpace();
+ int ts=n.find('<'); // start of template
+ int te=n.findRev('>'); // end of template
+ //printf("ts=%d te=%d\n",ts,te);
+ if (ts!=-1 && te!=-1 && te>ts)
+ {
+ // remove template from scope
+ n=n.left(ts)+n.right(n.length()-te-1);
+ }
+ while (!g_classScopeLengthStack.isEmpty())
+ {
+ popScope();
+ }
+ g_classScope.resize(0);
+ int i;
+ while ((i=n.find("::"))!=-1)
+ {
+ pushScope(n.left(i));
+ n = n.mid(i+2);
+ }
+ pushScope(n);
+ //printf("--->New class scope `%s'\n",g_classScope.data());
+}
+
+/*! start a new line of code, inserting a line number if g_sourceFileDef
+ * is TRUE. If a definition starts at the current line, then the line
+ * number is linked to the documentation of that definition.
+ */
+static void startCodeLine()
+{
+ //if (g_currentFontClass) { g_code->endFontClass(); }
+ if (g_sourceFileDef && g_lineNumbers)
+ {
+ //QCString lineNumber,lineAnchor;
+ //lineNumber.sprintf("%05d",g_yyLineNr);
+ //lineAnchor.sprintf("l%05d",g_yyLineNr);
+
+ Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
+ //printf("%s:startCodeLine(%d)=%p\n",g_sourceFileDef->name().data(),g_yyLineNr,d);
+ if (!g_includeCodeFragment && d)
+ {
+ g_currentDefinition = d;
+ g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
+ g_insideBody = FALSE;
+ g_searchingForBody = TRUE;
+ g_realScope = d->name();
+ //g_classScope = "";
+ g_type.resize(0);
+ g_name.resize(0);
+ g_args.resize(0);
+ g_parmType.resize(0);
+ g_parmName.resize(0);
+ //printf("Real scope: `%s'\n",g_realScope.data());
+ g_bodyCurlyCount = 0;
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",g_yyLineNr);
+ if (g_currentMemberDef)
+ {
+ g_code->writeLineNumber(g_currentMemberDef->getReference(),
+ g_currentMemberDef->getOutputFileBase(),
+ g_currentMemberDef->anchor(),g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ else if (d->isLinkableInProject())
+ {
+ g_code->writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ 0,g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ }
+ else
+ {
+ g_code->writeLineNumber(0,0,0,g_yyLineNr);
+ }
+ }
+ DBG_CTX((stderr,"startCodeLine(%d)\n",g_yyLineNr));
+ g_code->startCodeLine(g_sourceFileDef && g_lineNumbers);
+ if (g_currentFontClass)
+ {
+ g_code->startFontClass(g_currentFontClass);
+ }
+}
+
+
+static void endFontClass();
+static void startFontClass(const char *s);
+
+static void endCodeLine()
+{
+ DBG_CTX((stderr,"endCodeLine(%d)\n",g_yyLineNr));
+ endFontClass();
+ g_code->endCodeLine();
+}
+
+static void nextCodeLine()
+{
+ const char * fc = g_currentFontClass;
+ endCodeLine();
+ if (g_yyLineNr<g_inputLines)
+ {
+ g_currentFontClass = fc;
+ startCodeLine();
+ }
+}
+
+/*! write a code fragment `text' that may span multiple lines, inserting
+ * line numbers for each line.
+ */
+static void codifyLines(const char *text)
+{
+ //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
+ const char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') { g_yyColNr++; }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ g_yyColNr=1;
+ //*(p-1)='\0';
+ int l = (int)(p-sp-1);
+ char *tmp = (char*)malloc(l+1);
+ memcpy(tmp,sp,l);
+ tmp[l]='\0';
+ g_code->codify(tmp);
+ free(tmp);
+ nextCodeLine();
+ }
+ else
+ {
+ g_code->codify(sp);
+ done=TRUE;
+ }
+ }
+}
+
+/*! writes a link to a fragment \a text that may span multiple lines, inserting
+ * line numbers for each line. If \a text contains newlines, the link will be
+ * split into multiple links with the same destination, one for each line.
+ */
+static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ Definition *d,
+ const char *text)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ TooltipManager::instance()->addTooltip(d);
+ QCString ref = d->getReference();
+ QCString file = d->getOutputFileBase();
+ QCString anchor = d->anchor();
+ QCString tooltip;
+ if (!sourceTooltips) // fall back to simple "title" tooltips
+ {
+ tooltip = d->briefDescriptionAsTooltip();
+ }
+ bool done=FALSE;
+ char *p=(char *)text;
+ while (!done)
+ {
+ char *sp=p;
+ char c;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ nextCodeLine();
+ }
+ else
+ {
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ done=TRUE;
+ }
+ }
+}
+
+static void addType()
+{
+ if (g_name=="const") { g_name.resize(0); return; }
+ if (!g_type.isEmpty()) g_type += ' ' ;
+ g_type += g_name ;
+ g_name.resize(0) ;
+ if (!g_type.isEmpty()) g_type += ' ' ;
+ g_type += g_args ;
+ g_args.resize(0) ;
+}
+
+static void addParmType()
+{
+ if (g_parmName=="const") { g_parmName.resize(0); return; }
+ if (!g_parmType.isEmpty()) g_parmType += ' ' ;
+ g_parmType += g_parmName ;
+ g_parmName.resize(0) ;
+}
+
+static void addUsingDirective(const char *name)
+{
+ if (g_sourceFileDef && name)
+ {
+ NamespaceDef *nd = Doxygen::namespaceSDict->find(name);
+ if (nd)
+ {
+ g_sourceFileDef->addUsingDirective(nd);
+ }
+ }
+}
+
+static void setParameterList(MemberDef *md)
+{
+ g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
+ ArgumentList *al = md->argumentList();
+ if (al==0) return;
+ ArgumentListIterator it(*al);
+ Argument *a;
+ for (;(a=it.current());++it)
+ {
+ g_parmName = a->name.copy();
+ g_parmType = a->type.copy();
+ int i = g_parmType.find('*');
+ if (i!=-1) g_parmType = g_parmType.left(i);
+ i = g_parmType.find('&');
+ if (i!=-1) g_parmType = g_parmType.left(i);
+ g_parmType.stripPrefix("const ");
+ g_parmType=g_parmType.stripWhiteSpace();
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ }
+}
+
+static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition)
+{
+ int pos=0;
+ QCString type = s;
+ QCString className;
+ QCString templSpec;
+ while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
+ {
+ QCString clName=className+templSpec;
+ ClassDef *cd=0;
+ if (!g_classScope.isEmpty())
+ {
+ cd=getResolvedClass(d,g_sourceFileDef,g_classScope+"::"+clName);
+ }
+ if (cd==0)
+ {
+ cd=getResolvedClass(d,g_sourceFileDef,clName);
+ }
+ //printf("stripClass trying `%s' = %p\n",clName.data(),cd);
+ if (cd)
+ {
+ return cd;
+ }
+ }
+
+ return 0;
+}
+
+static MemberDef *setCallContextForVar(const QCString &name)
+{
+ if (name.isEmpty()) return 0;
+ DBG_CTX((stderr,"setCallContextForVar(%s) g_classScope=%s\n",name.data(),g_classScope.data()));
+
+ int scopeEnd = name.findRev("::");
+ if (scopeEnd!=-1) // name with explicit scope
+ {
+ QCString scope = name.left(scopeEnd);
+ QCString locName = name.right(name.length()-scopeEnd-2);
+ //printf("explicit scope: name=%s scope=%s\n",locName.data(),scope.data());
+ ClassDef *mcd = getClass(scope);
+ if (mcd && !locName.isEmpty())
+ {
+ MemberDef *md=mcd->getMemberByName(locName);
+ if (md)
+ {
+ //printf("name=%s scope=%s\n",locName.data(),scope.data());
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ return md;
+ }
+ }
+ else // check namespace as well
+ {
+ NamespaceDef *mnd = getResolvedNamespace(scope);
+ if (mnd && !locName.isEmpty())
+ {
+ MemberDef *md=mnd->getMemberByName(locName);
+ if (md)
+ {
+ //printf("name=%s scope=%s\n",locName.data(),scope.data());
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ return md;
+ }
+ }
+ }
+ }
+
+ MemberName *mn;
+ ClassDef *mcd = g_theVarContext.findVariable(name);
+ if (mcd) // local variable
+ {
+ DBG_CTX((stderr,"local variable?\n"));
+ if (mcd!=VariableContext::dummyContext)
+ {
+ DBG_CTX((stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data()));
+ g_theCallContext.setScope(mcd);
+ }
+ }
+ else
+ {
+ DBG_CTX((stderr,"class member? scope=%s\n",g_classScope.data()));
+ // look for a class member
+ mcd = getClass(g_classScope);
+ if (mcd)
+ {
+ DBG_CTX((stderr,"Inside class %s\n",mcd->name().data()));
+ MemberDef *md=mcd->getMemberByName(name);
+ if (md)
+ {
+ DBG_CTX((stderr,"Found member %s\n",md->name().data()));
+ if (g_scopeStack.top()!=CLASSBLOCK)
+ {
+ DBG_CTX((stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data()));
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ }
+ return md;
+ }
+ }
+ }
+
+ // look for a global member
+ if ((mn=Doxygen::functionNameSDict->find(name)))
+ {
+ //printf("global var `%s'\n",name.data());
+ if (mn->count()==1) // global defined only once
+ {
+ MemberDef *md=mn->getFirst();
+ if (!md->isStatic() || md->getBodyDef()==g_sourceFileDef)
+ {
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ return md;
+ }
+ return 0;
+ }
+ else if (mn->count()>1) // global defined more than once
+ {
+ MemberNameIterator it(*mn);
+ MemberDef *md;
+ for (;(md=it.current());++it)
+ {
+ //printf("mn=%p md=%p md->getBodyDef()=%p g_sourceFileDef=%p\n",
+ // mn,md,
+ // md->getBodyDef(),g_sourceFileDef);
+
+ // in case there are multiple members we could link to, we
+ // only link to members if defined in the same file or
+ // defined as external.
+ if ((!md->isStatic() || md->getBodyDef()==g_sourceFileDef) &&
+ (g_forceTagReference.isEmpty() || g_forceTagReference==md->getReference())
+ )
+ {
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ //printf("returning member %s in source file %s\n",md->name().data(),g_sourceFileDef->name().data());
+ return md;
+ }
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static void updateCallContextForSmartPointer()
+{
+ Definition *d = g_theCallContext.getScope();
+ //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>");
+ MemberDef *md;
+ if (d && d->definitionType()==Definition::TypeClass && (md=((ClassDef*)d)->isSmartPointer()))
+ {
+ ClassDef *ncd = stripClassName(md->typeString(),md->getOuterScope());
+ if (ncd)
+ {
+ g_theCallContext.setScope(ncd);
+ //printf("Found smart pointer call %s->%s!\n",cd->name().data(),ncd->name().data());
+ }
+ }
+}
+
+static bool getLinkInScope(const QCString &c, // scope
+ const QCString &m, // member
+ const char *memberText, // exact text
+ CodeOutputInterface &ol,
+ const char *text,
+ bool varOnly=FALSE
+ )
+{
+ MemberDef *md;
+ ClassDef *cd;
+ FileDef *fd;
+ NamespaceDef *nd;
+ GroupDef *gd;
+ DBG_CTX((stderr,"getLinkInScope: trying `%s'::`%s' varOnly=%d\n",c.data(),m.data(),varOnly));
+ if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef,FALSE,g_forceTagReference) &&
+ md->isLinkable() && (!varOnly || md->isVariable()))
+ {
+ //printf("found it %s!\n",md->qualifiedName().data());
+ if (g_exampleBlock)
+ {
+ QCString anchor;
+ anchor.sprintf("a%d",g_anchorCount);
+ //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
+ // g_exampleFile.data());
+ if (md->addExample(anchor,g_exampleName,g_exampleFile))
+ {
+ ol.writeCodeAnchor(anchor);
+ g_anchorCount++;
+ }
+ }
+
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getFileDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable())
+ {
+ g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
+ //printf("g_currentDefinition=%p g_currentMemberDef=%p g_insideBody=%d\n",
+ // g_currentDefinition,g_currentMemberDef,g_insideBody);
+
+ if (g_currentDefinition && g_currentMemberDef &&
+ md!=g_currentMemberDef && g_insideBody && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ //printf("d->getReference()=`%s' d->getOutputBase()=`%s' name=`%s' member name=`%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data());
+
+ writeMultiLineCodeLink(ol,md, text ? text : memberText);
+ addToSearchIndex(text ? text : memberText);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool getLink(const char *className,
+ const char *memberName,
+ CodeOutputInterface &ol,
+ const char *text=0,
+ bool varOnly=FALSE)
+{
+ //printf("getLink(%s,%s) g_curClassName=%s\n",className,memberName,g_curClassName.data());
+ QCString m=removeRedundantWhiteSpace(memberName);
+ QCString c=className;
+ if (!getLinkInScope(c,m,memberName,ol,text,varOnly))
+ {
+ if (!g_curClassName.isEmpty())
+ {
+ if (!c.isEmpty()) c.prepend("::");
+ c.prepend(g_curClassName);
+ return getLinkInScope(c,m,memberName,ol,text,varOnly);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName,
+ bool typeOnly=FALSE,bool varOnly=FALSE)
+{
+ int i=0;
+ if (*clName=='~') // correct for matching negated values i.s.o. destructors.
+ {
+ g_code->codify("~");
+ clName++;
+ }
+ QCString className=clName;
+ if (className.isEmpty()) return;
+ if (g_insideProtocolList) // for Obj-C
+ {
+ className+="-p";
+ }
+ if (g_insidePHP)
+ {
+ className = substitute(className,"\\","::"); // for PHP namespaces
+ }
+ else if (g_insideCS || g_insideJava)
+ {
+ className = substitute(className,".","::"); // for PHP namespaces
+ }
+ ClassDef *cd=0,*lcd=0;
+ MemberDef *md=0;
+ bool isLocal=FALSE;
+
+ //printf("generateClassOrGlobalLink(className=%s)\n",className.data());
+ if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable
+ {
+ Definition *d = g_currentDefinition;
+ //printf("d=%s g_sourceFileDef=%s\n",d?d->name().data():"<none>",g_sourceFileDef?g_sourceFileDef->name().data():"<none>");
+ cd = getResolvedClass(d,g_sourceFileDef,className,&md);
+ DBG_CTX((stderr,"non-local variable name=%s context=%d cd=%s md=%s!\n",
+ className.data(),g_theVarContext.count(),cd?cd->name().data():"<none>",
+ md?md->name().data():"<none>"));
+ if (cd==0 && md==0 && (i=className.find('<'))!=-1)
+ {
+ QCString bareName = className.left(i); //stripTemplateSpecifiersFromScope(className);
+ DBG_CTX((stderr,"bareName=%s\n",bareName.data()));
+ if (bareName!=className)
+ {
+ cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version
+ }
+ }
+ NamespaceDef *nd = getResolvedNamespace(className);
+ if (nd)
+ {
+ g_theCallContext.setScope(nd);
+ addToSearchIndex(className);
+ writeMultiLineCodeLink(*g_code,nd,clName);
+ return;
+ }
+ //printf("md=%s\n",md?md->name().data():"<none>");
+ DBG_CTX((stderr,"is found as a type cd=%s nd=%s\n",
+ cd?cd->name().data():"<null>",
+ nd?nd->name().data():"<null>"));
+ if (cd==0 && md==0) // also see if it is variable or enum or enum value
+ {
+ if (getLink(g_classScope,clName,ol,clName,varOnly))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ //printf("local variable!\n");
+ if (lcd!=VariableContext::dummyContext)
+ {
+ //printf("non-dummy context lcd=%s!\n",lcd->name().data());
+ g_theCallContext.setScope(lcd);
+
+ // to following is needed for links to a global variable, but is
+ // no good for a link to a local variable that is also a global symbol.
+
+ //if (getLink(g_classScope,clName,ol,clName))
+ //{
+ //return;
+ //}
+ }
+ isLocal=TRUE;
+ DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
+ }
+ if (cd && cd->isLinkable()) // is it a linkable class
+ {
+ DBG_CTX((stderr,"is linkable class %s\n",clName));
+ if (g_exampleBlock)
+ {
+ QCString anchor;
+ anchor.sprintf("_a%d",g_anchorCount);
+ //printf("addExampleClass(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
+ // g_exampleFile.data());
+ if (cd->addExample(anchor,g_exampleName,g_exampleFile))
+ {
+ ol.writeCodeAnchor(anchor);
+ g_anchorCount++;
+ }
+ }
+ writeMultiLineCodeLink(ol,cd,clName);
+ addToSearchIndex(className);
+ g_theCallContext.setScope(cd);
+ if (md)
+ {
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getFileDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable() && md->isLinkable() &&
+ g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ }
+ }
+ else // not a class, maybe a global member
+ {
+ DBG_CTX((stderr,"class %s not linkable! cd=%p md=%p typeOnly=%d\n",clName,cd,md,typeOnly));
+ if (!isLocal && (md!=0 || (cd==0 && !typeOnly))) // not a class, see if it is a global enum/variable/typedef.
+ {
+ if (md==0) // not found as a typedef
+ {
+ md = setCallContextForVar(clName);
+ //printf("setCallContextForVar(%s) md=%p g_currentDefinition=%p\n",clName,md,g_currentDefinition);
+ if (md && g_currentDefinition)
+ {
+ DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n",
+ md->name().data(),g_currentDefinition->name().data(),
+ isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md),
+ md->getOuterScope()->name().data()));
+ }
+
+ if (md && g_currentDefinition &&
+ isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md)==-1)
+ {
+ md=0; // variable not accessible
+ }
+ }
+ if (md && (!varOnly || md->isVariable()))
+ {
+ DBG_CTX((stderr,"is a global md=%p g_currentDefinition=%s linkable=%d\n",md,g_currentDefinition?g_currentDefinition->name().data():"<none>",md->isLinkable()));
+ if (md->isLinkable())
+ {
+ QCString text;
+ if (!g_forceTagReference.isEmpty()) // explicit reference to symbol in tag file
+ {
+ text=g_forceTagReference;
+ if (text.right(4)==".tag") // strip .tag if present
+ {
+ text=text.left(text.length()-4);
+ }
+ text+=getLanguageSpecificSeparator(md->getLanguage());
+ text+=clName;
+ md->setName(text);
+ md->setLocalName(text);
+ }
+ else // normal reference
+ {
+ text=clName;
+ }
+ writeMultiLineCodeLink(ol,md,text);
+ addToSearchIndex(clName);
+ if (g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ return;
+ }
+ }
+ }
+
+ // nothing found, just write out the word
+ DBG_CTX((stderr,"not found!\n"));
+ codifyLines(clName);
+ addToSearchIndex(clName);
+ }
+}
+
+static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const char *memName)
+{
+ // extract class definition of the return type in order to resolve
+ // a->b()->c() like call chains
+
+ //printf("type=`%s' args=`%s' class=%s\n",
+ // xmd->typeString(),xmd->argsString(),
+ // xmd->getClassDef()->name().data());
+
+ if (g_exampleBlock)
+ {
+ QCString anchor;
+ anchor.sprintf("a%d",g_anchorCount);
+ //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(),
+ // g_exampleFile.data());
+ if (xmd->addExample(anchor,g_exampleName,g_exampleFile))
+ {
+ ol.writeCodeAnchor(anchor);
+ g_anchorCount++;
+ }
+ }
+
+ ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope());
+ DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass));
+ g_theCallContext.setScope(typeClass);
+
+ Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
+ xmd->getFileDef() : xmd->getOuterScope();
+ if (xmd->getGroupDef()) xd = xmd->getGroupDef();
+ if (xd && xd->isLinkable())
+ {
+
+ //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody);
+
+ if (xmd->templateMaster()) xmd = xmd->templateMaster();
+
+ if (xmd->isLinkable())
+ {
+ // add usage reference
+ if (g_currentDefinition && g_currentMemberDef &&
+ /*xmd!=g_currentMemberDef &&*/ g_insideBody && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,xmd);
+ }
+
+ // write the actual link
+ writeMultiLineCodeLink(ol,xmd,memName);
+ addToSearchIndex(memName);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool generateClassMemberLink(CodeOutputInterface &ol,Definition *def,const char *memName)
+{
+ if (def && def->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd = (ClassDef*)def;
+ MemberDef *xmd = cd->getMemberByName(memName);
+ //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",def->name().data(),memName,xmd);
+ if (xmd)
+ {
+ return generateClassMemberLink(ol,xmd,memName);
+ }
+ else
+ {
+ Definition *innerDef = cd->findInnerCompound(memName);
+ if (innerDef)
+ {
+ g_theCallContext.setScope(innerDef);
+ addToSearchIndex(memName);
+ writeMultiLineCodeLink(*g_code,innerDef,memName);
+ return TRUE;
+ }
+ }
+ }
+ else if (def && def->definitionType()==Definition::TypeNamespace)
+ {
+ NamespaceDef *nd = (NamespaceDef*)def;
+ //printf("Looking for %s inside namespace %s\n",memName,nd->name().data());
+ Definition *innerDef = nd->findInnerCompound(memName);
+ if (innerDef)
+ {
+ g_theCallContext.setScope(innerDef);
+ addToSearchIndex(memName);
+ writeMultiLineCodeLink(*g_code,innerDef,memName);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName,
+ char *memName)
+{
+ //printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n",
+ // varName.data(),memName,g_classScope.data());
+
+ if (varName.isEmpty()) return;
+
+ // look for the variable in the current context
+ ClassDef *vcd = g_theVarContext.findVariable(varName);
+ if (vcd)
+ {
+ if (vcd!=VariableContext::dummyContext)
+ {
+ //printf("Class found!\n");
+ if (getLink(vcd->name(),memName,ol))
+ {
+ //printf("Found result!\n");
+ return;
+ }
+ if (vcd->baseClasses())
+ {
+ BaseClassListIterator bcli(*vcd->baseClasses());
+ for ( ; bcli.current() ; ++bcli)
+ {
+ if (getLink(bcli.current()->classDef->name(),memName,ol))
+ {
+ //printf("Found result!\n");
+ return;
+ }
+ }
+ }
+ }
+ }
+ else // variable not in current context, maybe it is in a parent context
+ {
+ vcd = getResolvedClass(g_currentDefinition,g_sourceFileDef,g_classScope);
+ if (vcd && vcd->isLinkable())
+ {
+ //printf("Found class %s for variable `%s'\n",g_classScope.data(),varName.data());
+ MemberName *vmn=Doxygen::memberNameSDict->find(varName);
+ if (vmn==0)
+ {
+ int vi;
+ QCString vn=varName;
+ QCString scope;
+ if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member
+ {
+ ClassDef *jcd = getClass(vn.left(vi));
+ vn=vn.right(vn.length()-vi-2);
+ vmn=Doxygen::memberNameSDict->find(vn);
+ //printf("Trying name `%s' scope=%s\n",vn.data(),scope.data());
+ if (vmn)
+ {
+ MemberNameIterator vmni(*vmn);
+ MemberDef *vmd;
+ for (;(vmd=vmni.current());++vmni)
+ {
+ if (/*(vmd->isVariable() || vmd->isFunction()) && */
+ vmd->getClassDef()==jcd)
+ {
+ //printf("Found variable type=%s\n",vmd->typeString());
+ ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope());
+ if (mcd && mcd->isLinkable())
+ {
+ if (generateClassMemberLink(ol,mcd,memName)) return;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (vmn)
+ {
+ //printf("There is a variable with name `%s'\n",varName);
+ MemberNameIterator vmni(*vmn);
+ MemberDef *vmd;
+ for (;(vmd=vmni.current());++vmni)
+ {
+ if (/*(vmd->isVariable() || vmd->isFunction()) && */
+ vmd->getClassDef()==vcd)
+ {
+ //printf("Found variable type=%s\n",vmd->typeString());
+ ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope());
+ if (mcd && mcd->isLinkable())
+ {
+ if (generateClassMemberLink(ol,mcd,memName)) return;
+ }
+ }
+ }
+ }
+ }
+ }
+ // nothing found -> write result as is
+ codifyLines(memName);
+ addToSearchIndex(memName);
+ return;
+}
+
+static void generatePHPVariableLink(CodeOutputInterface &ol,const char *varName)
+{
+ QCString name = varName+7; // strip $this->
+ name.prepend("$");
+ //printf("generatePHPVariableLink(%s) name=%s scope=%s\n",varName,name.data(),g_classScope.data());
+ if (!getLink(g_classScope,name,ol,varName))
+ {
+ codifyLines(varName);
+ }
+}
+
+static void generateFunctionLink(CodeOutputInterface &ol,const char *funcName)
+{
+ //CodeClassDef *ccd=0;
+ ClassDef *ccd=0;
+ QCString locScope=g_classScope;
+ QCString locFunc=removeRedundantWhiteSpace(funcName);
+ QCString funcScope;
+ QCString funcWithScope=locFunc;
+ QCString funcWithFullScope=locFunc;
+ QCString fullScope=locScope;
+ DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data()));
+ int len=2;
+ int i=locFunc.findRev("::");
+ if (g_currentMemberDef && g_currentMemberDef->getClassDef() &&
+ funcName==g_currentMemberDef->localName() &&
+ g_currentMemberDef->getDefLine()==g_yyLineNr &&
+ generateClassMemberLink(ol,g_currentMemberDef,funcName)
+ )
+ {
+ // special case where funcName is the name of a method that is also
+ // defined on this line. In this case we can directly link to
+ // g_currentMemberDef, which is not only faster, but
+ // in case of overloaded methods, this will make sure that we link to
+ // the correct method, and thereby get the correct reimplemented relations.
+ // See also bug 549022.
+ goto exit;
+ }
+ if (i==-1) i=locFunc.findRev("."),len=1;
+ if (i==-1) i=locFunc.findRev("\\"),len=1; // for PHP
+ if (i>0)
+ {
+ funcScope=locFunc.left(i);
+ locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace();
+ int ts=locScope.find('<'); // start of template
+ int te=locScope.findRev('>'); // end of template
+ //printf("ts=%d te=%d\n",ts,te);
+ if (ts!=-1 && te!=-1 && te>ts)
+ {
+ // remove template from scope
+ locScope=locScope.left(ts)+locScope.right(locScope.length()-te-1);
+ }
+ ts=funcScope.find('<'); // start of template
+ te=funcScope.findRev('>'); // end of template
+ //printf("ts=%d te=%d\n",ts,te);
+ if (ts!=-1 && te!=-1 && te>ts)
+ {
+ // remove template from scope
+ funcScope=funcScope.left(ts)+funcScope.right(funcScope.length()-te-1);
+ }
+ if (!funcScope.isEmpty())
+ {
+ funcWithScope = funcScope+"::"+locFunc;
+ if (!locScope.isEmpty())
+ {
+ fullScope=locScope+"::"+funcScope;
+ }
+ }
+ if (!locScope.isEmpty())
+ {
+ funcWithFullScope = locScope+"::"+funcWithScope;
+ }
+ }
+ if (!fullScope.isEmpty() && (ccd=g_codeClassSDict->find(fullScope)))
+ {
+ //printf("using classScope %s\n",g_classScope.data());
+ if (ccd->baseClasses())
+ {
+ BaseClassListIterator bcli(*ccd->baseClasses());
+ for ( ; bcli.current() ; ++bcli)
+ {
+ if (getLink(bcli.current()->classDef->name(),locFunc,ol,funcName))
+ {
+ goto exit;
+ }
+ }
+ }
+ }
+ if (!locScope.isEmpty() && fullScope!=locScope && (ccd=g_codeClassSDict->find(locScope)))
+ {
+ //printf("using classScope %s\n",g_classScope.data());
+ if (ccd->baseClasses())
+ {
+ BaseClassListIterator bcli(*ccd->baseClasses());
+ for ( ; bcli.current() ; ++bcli)
+ {
+ if (getLink(bcli.current()->classDef->name(),funcWithScope,ol,funcName))
+ {
+ goto exit;
+ }
+ }
+ }
+ }
+ if (!getLink(locScope,funcWithScope,ol,funcName))
+ {
+ generateClassOrGlobalLink(ol,funcName);
+ }
+exit:
+ g_forceTagReference.resize(0);
+ return;
+}
+
+/*! counts the number of lines in the input */
+static int countLines()
+{
+ const char *p=g_inputString;
+ char c;
+ int count=1;
+ while ((c=*p))
+ {
+ p++ ;
+ if (c=='\n') count++;
+ }
+ if (p>g_inputString && *(p-1)!='\n')
+ { // last line does not end with a \n, so we add an extra
+ // line and explicitly terminate the line after parsing.
+ count++,
+ g_needsTermination=TRUE;
+ }
+ return count;
+}
+
+static void endFontClass()
+{
+ if (g_currentFontClass)
+ {
+ g_code->endFontClass();
+ g_currentFontClass=0;
+ }
+}
+
+static void startFontClass(const char *s)
+{
+ endFontClass();
+ g_code->startFontClass(s);
+ g_currentFontClass=s;
+}
+
+//----------------------------------------------------------------------------
+
+// recursively writes a linkified Objective-C method call
+static void writeObjCMethodCall(ObjCCallCtx *ctx)
+{
+ if (ctx==0) return;
+ char c;
+ const char *p = ctx->format.data();
+ if (!ctx->methodName.isEmpty())
+ {
+ //printf("writeObjCMethodCall(%s) obj=%s method=%s\n",
+ // ctx->format.data(),ctx->objectTypeOrName.data(),ctx->methodName.data());
+ if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$')
+ {
+ //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(),
+ // ctx->methodName.data());
+ ClassDef *cd = g_theVarContext.findVariable(ctx->objectTypeOrName);
+ if (cd==0) // not a local variable
+ {
+ if (ctx->objectTypeOrName=="self")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectType = (ClassDef *)g_currentDefinition;
+ }
+ }
+ else
+ {
+ ctx->objectType = getResolvedClass(
+ g_currentDefinition,
+ g_sourceFileDef,
+ ctx->objectTypeOrName,
+ &ctx->method);
+ }
+ //printf(" object is class? %p\n",ctx->objectType);
+ if (ctx->objectType) // found class
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():"<none>");
+ }
+ else if (ctx->method==0) // search for class variable with the same name
+ {
+ //printf(" no\n");
+ //printf("g_currentDefinition=%p\n",g_currentDefinition);
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectVar = ((ClassDef *)g_currentDefinition)->getMemberByName(ctx->objectTypeOrName);
+ //printf(" ctx->objectVar=%p\n",ctx->objectVar);
+ if (ctx->objectVar)
+ {
+ ctx->objectType = stripClassName(ctx->objectVar->typeString());
+ //printf(" ctx->objectType=%p\n",ctx->objectType);
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ //printf(" ctx->method=%p\n",ctx->method);
+ }
+ }
+ }
+ }
+ }
+ else // local variable
+ {
+ //printf(" object is local variable\n");
+ if (cd!=VariableContext::dummyContext)
+ {
+ ctx->method = cd->getMemberByName(ctx->methodName);
+ //printf(" class=%p method=%p\n",cd,ctx->method);
+ }
+ }
+ }
+ }
+
+ //printf("[");
+ while ((c=*p++)) // for each character in ctx->format
+ {
+ if (c=='$')
+ {
+ char nc=*p++;
+ if (nc=='$') // escaped $
+ {
+ g_code->codify("$");
+ }
+ else // name fragment or reference to a nested call
+ {
+ if (nc=='n') // name fragment
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ QCString *pName = g_nameDict.find(refId);
+ if (pName)
+ {
+ if (ctx->method && ctx->method->isLinkable())
+ {
+ writeMultiLineCodeLink(*g_code,ctx->method,pName->data());
+ if (g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,ctx->method);
+ }
+ }
+ else
+ {
+ codifyLines(pName->data());
+ }
+ }
+ else
+ {
+ //printf("Invalid name: id=%d\n",refId);
+ }
+ }
+ else if (nc=='o') // reference to potential object name
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ QCString *pObject = g_objectDict.find(refId);
+ if (pObject)
+ {
+ if (*pObject=="self")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectType = (ClassDef *)g_currentDefinition;
+ if (ctx->objectType->categoryOf())
+ {
+ ctx->objectType = ctx->objectType->categoryOf();
+ }
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ startFontClass("keyword");
+ codifyLines(pObject->data());
+ endFontClass();
+ }
+ else if (*pObject=="super")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd = (ClassDef *)g_currentDefinition;
+ if (cd->categoryOf())
+ {
+ cd = cd->categoryOf();
+ }
+ BaseClassList *bcd = cd->baseClasses();
+ if (bcd) // get direct base class (there should be only one)
+ {
+ BaseClassListIterator bli(*bcd);
+ BaseClassDef *bclass;
+ for (bli.toFirst();(bclass=bli.current());++bli)
+ {
+ if (bclass->classDef->compoundType()!=ClassDef::Protocol)
+ {
+ ctx->objectType = bclass->classDef;
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ }
+ }
+ }
+ startFontClass("keyword");
+ codifyLines(pObject->data());
+ endFontClass();
+ }
+ else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable
+ {
+ writeMultiLineCodeLink(*g_code,ctx->objectVar,pObject->data());
+ if (g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,ctx->objectVar);
+ }
+ }
+ else if (ctx->objectType &&
+ ctx->objectType!=VariableContext::dummyContext &&
+ ctx->objectType->isLinkable()
+ ) // object is class name
+ {
+ ClassDef *cd = ctx->objectType;
+ writeMultiLineCodeLink(*g_code,cd,pObject->data());
+ }
+ else // object still needs to be resolved
+ {
+ ClassDef *cd = getResolvedClass(g_currentDefinition,
+ g_sourceFileDef, *pObject);
+ if (cd && cd->isLinkable())
+ {
+ if (ctx->objectType==0) ctx->objectType=cd;
+ writeMultiLineCodeLink(*g_code,cd,pObject->data());
+ }
+ else
+ {
+ codifyLines(pObject->data());
+ }
+ }
+ }
+ else
+ {
+ //printf("Invalid object: id=%d\n",refId);
+ }
+ }
+ else if (nc=='c') // reference to nested call
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ ObjCCallCtx *ictx = g_contextDict.find(refId);
+ if (ictx) // recurse into nested call
+ {
+ writeObjCMethodCall(ictx);
+ if (ictx->method) // link to nested call successfully
+ {
+ // get the ClassDef representing the method's return type
+ if (QCString(ictx->method->typeString())=="id")
+ {
+ // see if the method name is unique, if so we link to it
+ MemberName *mn=Doxygen::memberNameSDict->find(ctx->methodName);
+ //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n",
+ // mn==0?-1:(int)mn->count(),
+ // ictx->method->name().data(),
+ // ctx->methodName.data());
+ if (mn && mn->count()==1) // member name unique
+ {
+ ctx->method = mn->getFirst();
+ }
+ }
+ else
+ {
+ ctx->objectType = stripClassName(ictx->method->typeString());
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType);
+ }
+ }
+ else
+ {
+ //printf("Invalid context: id=%d\n",refId);
+ }
+ }
+ else if (nc=='w') // some word
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ QCString *pWord = g_wordDict.find(refId);
+ if (pWord)
+ {
+ codifyLines(pWord->data());
+ }
+ }
+ else // illegal marker
+ {
+ ASSERT(!"invalid escape sequence");
+ }
+ }
+ }
+ else // normal non-marker character
+ {
+ char s[2];
+ s[0]=c;s[1]=0;
+ codifyLines(s);
+ }
+ }
+ //printf("%s %s]\n",ctx->objectTypeOrName.data(),ctx->methodName.data());
+ //printf("}=(type='%s',name='%s')",
+ // ctx->objectTypeOrName.data(),
+ // ctx->methodName.data());
+}
+
+// Replaces an Objective-C method name fragment s by a marker of the form
+// $n12, the number (12) can later be used as a key for obtaining the name
+// fragment, from g_nameDict
+static QCString escapeName(const char *s)
+{
+ QCString result;
+ result.sprintf("$n%d",g_currentNameId);
+ g_nameDict.insert(g_currentNameId,new QCString(s));
+ g_currentNameId++;
+ return result;
+}
+
+static QCString escapeObject(const char *s)
+{
+ QCString result;
+ result.sprintf("$o%d",g_currentObjId);
+ g_objectDict.insert(g_currentObjId,new QCString(s));
+ g_currentObjId++;
+ return result;
+}
+
+static QCString escapeWord(const char *s)
+{
+ QCString result;
+ result.sprintf("$w%d",g_currentWordId);
+ g_wordDict.insert(g_currentWordId,new QCString(s));
+ g_currentWordId++;
+ return result;
+}
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+B [ \t]
+BN [ \t\n\r]
+ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+SEP ("::"|"\\")
+SCOPENAME ({SEP}{BN}*)?({ID}{BN}*{SEP}{BN}*)*("~"{BN}*)?{ID}
+TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">"
+SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID})
+SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+
+KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize"|"@property")
+KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"sizeof"|"static"|"struct"|"__super"|"function"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|"align [...]
+FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while"|"@try"|"@catch"|"@finally")
+TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string"|"nullptr")
+CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast")
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
+ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
+ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
+LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
+BITOP "&"|"|"|"^"|"<<"|">>"|"~"
+OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
+RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
+RAWEND ")"[^ \t\(\)\\]{0,16}\"
+
+%option noyywrap
+
+%x SkipString
+%x SkipStringS
+%x SkipVerbString
+%x SkipCPP
+%x SkipComment
+%x SkipCxxComment
+%x RemoveSpecialCComment
+%x StripSpecialCComment
+%x Body
+%x FuncCall
+%x MemberCall
+%x MemberCall2
+%x SkipInits
+%x ClassName
+%x AlignAs
+%x AlignAsEnd
+%x PackageName
+%x ClassVar
+%x CppCliTypeModifierFollowup
+%x Bases
+%x SkipSharp
+%x ReadInclude
+%x TemplDecl
+%x TemplCast
+%x CallEnd
+%x ObjCMethod
+%x ObjCParams
+%x ObjCParamType
+%x ObjCCall
+%x ObjCMName
+%x ObjCSkipStr
+%x OldStyleArgs
+%x UsingName
+%x RawString
+%x InlineInit
+
+%%
+
+<*>\x0d
+<Body>^([ \t]*"#"[ \t]*("include"|"import")[ \t]*)("<"|"\"") {
+ startFontClass("preprocessor");
+ g_code->codify(yytext);
+ BEGIN( ReadInclude );
+ }
+<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ {
+ g_insideObjC=TRUE;
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ if (!g_insideTemplate)
+ BEGIN( ClassName );
+ }
+<Body>(("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") {
+ if (g_insideTemplate) REJECT;
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN( ClassName );
+ }
+<Body>"property"|"event"/{BN}* {
+ if (g_insideTemplate) REJECT;
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Body>(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"|"interface"){B}+ {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ if (!g_insideTemplate)
+ BEGIN( ClassName );
+ }
+<Body>("package")[ \t\n]+ {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN( PackageName );
+ }
+<ClassVar>\n {
+ if (!g_insideObjC) REJECT;
+ codifyLines(yytext);
+ BEGIN(Body);
+ }
+<Body,ClassVar,Bases>"-"|"+" {
+ if (!g_insideObjC || g_insideBody)
+ {
+ g_code->codify(yytext);
+ }
+ else // Start of Objective-C method
+ {
+ //printf("Method!\n");
+ g_code->codify(yytext);
+ BEGIN(ObjCMethod);
+ }
+ }
+<ObjCMethod>":" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParams);
+ }
+<ObjCParams>"(" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParamType);
+ }
+<ObjCParams,ObjCMethod>";"|"{" {
+ g_code->codify(yytext);
+ if (*yytext=='{')
+ {
+ g_curlyCount++;
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ if (g_insideBody) g_bodyCurlyCount++;
+ if (!g_curClassName.isEmpty()) // valid class name
+ {
+ pushScope(g_curClassName);
+ DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
+ g_scopeStack.push(SCOPEBLOCK);
+ }
+ }
+ g_type.resize(0);
+ g_name.resize(0);
+ BEGIN(Body);
+ }
+<ObjCParams>{ID}{B}*":" {
+ g_code->codify(yytext);
+ }
+<ObjCParamType>{TYPEKW} {
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ g_parmType=yytext;
+ }
+<ObjCParamType>{ID} {
+ generateClassOrGlobalLink(*g_code,yytext);
+ g_parmType=yytext;
+ }
+<ObjCParamType>")" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParams);
+ }
+<ObjCParams>{ID} {
+ g_code->codify(yytext);
+ g_parmName=yytext;
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ g_parmType.resize(0);g_parmName.resize(0);
+ }
+<ObjCMethod,ObjCParams,ObjCParamType>{ID} {
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+<ObjCMethod,ObjCParams,ObjCParamType>. {
+ g_code->codify(yytext);
+ }
+<ObjCMethod,ObjCParams,ObjCParamType>\n {
+ codifyLines(yytext);
+ }
+<ReadInclude>[^\n\"\>]+/(">"|"\"") {
+ //FileInfo *f;
+ bool ambig;
+ bool found=FALSE;
+ //QCString absPath = yytext;
+ //if (g_sourceFileDef && QDir::isRelativePath(absPath))
+ //{
+ // absPath = QDir::cleanDirPath(g_sourceFileDef->getPath()+"/"+absPath);
+ //}
+
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,yytext,ambig);
+ //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd);
+ if (fd && fd->isLinkable())
+ {
+ if (ambig) // multiple input files match the name
+ {
+ //printf("===== yes %s is ambiguous\n",yytext);
+ QCString name = QDir::cleanDirPath(yytext).utf8();
+ if (!name.isEmpty() && g_sourceFileDef)
+ {
+ FileName *fn = Doxygen::inputNameDict->find(name);
+ if (fn)
+ {
+ FileNameIterator fni(*fn);
+ // for each include name
+ for (fni.toFirst();!found && (fd=fni.current());++fni)
+ {
+ // see if this source file actually includes the file
+ found = g_sourceFileDef->isIncluded(fd->absFilePath());
+ //printf(" include file %s found=%d\n",fd->absFilePath().data(),found);
+ }
+ }
+ }
+ }
+ else // not ambiguous
+ {
+ found = TRUE;
+ }
+ }
+ //printf(" include file %s found=%d\n",fd ? fd->absFilePath().data() : "<none>",found);
+ if (found)
+ {
+ writeMultiLineCodeLink(*g_code,fd,yytext);
+ }
+ else
+ {
+ g_code->codify(yytext);
+ }
+ char c=yyinput();
+ QCString text;
+ text+=c;
+ g_code->codify(text);
+ endFontClass();
+ BEGIN( Body );
+ }
+<Body,Bases>^[ \t]*"#" {
+ startFontClass("preprocessor");
+ g_lastSkipCppContext = YY_START;
+ g_code->codify(yytext);
+ BEGIN( SkipCPP ) ;
+ }
+<SkipCPP>. {
+ g_code->codify(yytext);
+ }
+<SkipCPP>[^\n\/\\]+ {
+ g_code->codify(yytext);
+ }
+<SkipCPP>\\[\r]?\n {
+ codifyLines(yytext);
+ }
+<SkipCPP>"//" {
+ g_code->codify(yytext);
+ }
+<Body,FuncCall>"{" {
+ g_theVarContext.pushScope();
+
+ DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
+ g_scopeStack.push(INNERBLOCK);
+
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ g_code->codify(yytext);
+ g_curlyCount++;
+ if (g_insideBody)
+ {
+ g_bodyCurlyCount++;
+ }
+ g_type.resize(0);
+ g_name.resize(0);
+ BEGIN( Body );
+ }
+<Body,MemberCall,MemberCall2>"}" {
+ g_theVarContext.popScope();
+ g_type.resize(0);
+ g_name.resize(0);
+
+ int *scope = g_scopeStack.pop();
+ DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
+ if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
+ {
+ popScope();
+ }
+
+ g_code->codify(yytext);
+
+ DBG_CTX((stderr,"g_bodyCurlyCount=%d\n",g_bodyCurlyCount));
+ if (--g_bodyCurlyCount<=0)
+ {
+ g_insideBody=FALSE;
+ g_currentMemberDef=0;
+ if (g_currentDefinition)
+ g_currentDefinition=g_currentDefinition->getOuterScope();
+ }
+ BEGIN(Body);
+ }
+<Body,ClassVar>"@end" {
+ //printf("End of objc scope fd=%s\n",g_sourceFileDef->name().data());
+ if (g_sourceFileDef)
+ {
+ FileDef *fd=g_sourceFileDef;
+ g_insideObjC = fd->name().lower().right(2)==".m" ||
+ fd->name().lower().right(3)==".mm";
+ //printf("insideObjC=%d\n",g_insideObjC);
+ }
+ else
+ {
+ g_insideObjC = FALSE;
+ }
+ if (g_insideBody)
+ {
+ g_theVarContext.popScope();
+
+ int *scope = g_scopeStack.pop();
+ DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
+ if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
+ {
+ popScope();
+ }
+ g_insideBody=FALSE;
+ }
+
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+
+ g_currentMemberDef=0;
+ if (g_currentDefinition)
+ g_currentDefinition=g_currentDefinition->getOuterScope();
+ BEGIN(Body);
+ }
+<ClassName,ClassVar>";" {
+ g_code->codify(yytext);
+ g_searchingForBody=FALSE;
+ BEGIN( Body );
+ }
+<ClassName,ClassVar>[*&^%]+ {
+ g_type=g_curClassName.copy();
+ g_name.resize(0);
+ g_code->codify(yytext);
+ BEGIN( Body ); // variable of type struct *
+ }
+<ClassName>"__declspec"{B}*"("{B}*{ID}{B}*")" {
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<ClassName>{ID}("::"{ID})* {
+ g_curClassName=yytext;
+ addType();
+ if (g_curClassName=="alignas")
+ {
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ BEGIN( AlignAs );
+ }
+ else
+ {
+ generateClassOrGlobalLink(*g_code,yytext);
+ BEGIN( ClassVar );
+ }
+ }
+<AlignAs>"(" {
+ g_bracketCount=1;
+ g_code->codify(yytext);
+ BEGIN( AlignAsEnd );
+ }
+<AlignAs>\n { g_yyLineNr++;
+ codifyLines(yytext);
+ }
+<AlignAs>. { g_code->codify(yytext); }
+<AlignAsEnd>"(" { g_code->codify(yytext);
+ g_bracketCount++;
+ }
+<AlignAsEnd>")" {
+ g_code->codify(yytext);
+ if (--g_bracketCount<=0)
+ {
+ BEGIN(ClassName);
+ }
+ }
+<AlignAsEnd>\n { g_yyLineNr++;
+ codifyLines(yytext);
+ }
+<AlignAsEnd>. { g_code->codify(yytext); }
+<ClassName>{ID}("\\"{ID})* { // PHP namespace
+ g_curClassName=substitute(yytext,"\\","::");
+ g_scopeStack.push(CLASSBLOCK);
+ pushScope(g_curClassName);
+ addType();
+ generateClassOrGlobalLink(*g_code,yytext);
+ BEGIN( ClassVar );
+ }
+<ClassName>{ID}{B}*"("{ID}")" { // Obj-C category
+ g_curClassName=removeRedundantWhiteSpace(yytext);
+ g_scopeStack.push(CLASSBLOCK);
+ pushScope(g_curClassName);
+ addType();
+ generateClassOrGlobalLink(*g_code,yytext);
+ BEGIN( ClassVar );
+ }
+<PackageName>{ID}("."{ID})* {
+ g_curClassName=substitute(yytext,".","::");
+ //printf("found package: %s\n",g_curClassName.data());
+ addType();
+ codifyLines(yytext);
+ }
+<ClassVar>"=" {
+ unput(*yytext);
+ BEGIN( Body );
+ }
+<ClassVar>("extends"|"implements") { // Java
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ g_curClassBases.clear();
+ BEGIN( Bases );
+ }
+<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
+ DBG_CTX((stderr,"***** C++/CLI modifier %s on g_curClassName=%s\n",yytext,g_curClassName.data()));
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN( CppCliTypeModifierFollowup );
+ }
+<ClassVar>{ID} {
+ g_type = g_curClassName.copy();
+ g_name = yytext;
+ if (g_insideBody)
+ {
+ g_theVarContext.addVariable(g_type,g_name);
+ }
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+<ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* {
+ codifyLines(yytext);
+ g_curClassBases.clear();
+ BEGIN( Bases );
+ }
+<PackageName>[ \t]*";" |
+<Bases>^{B}*/"@"{ID} | // Objective-C interface
+<Bases,ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*"{"{B}* {
+ g_theVarContext.pushScope();
+ g_code->codify(yytext);
+ g_curlyCount++;
+ if (YY_START==ClassVar && g_curClassName.isEmpty())
+ {
+ g_curClassName = g_name.copy();
+ }
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ if (g_insideBody) g_bodyCurlyCount++;
+ if (!g_curClassName.isEmpty()) // valid class name
+ {
+ DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n"));
+ g_scopeStack.push(CLASSBLOCK);
+ pushScope(g_curClassName);
+ DBG_CTX((stderr,"***** g_curClassName=%s\n",g_curClassName.data()));
+ if (getResolvedClass(g_currentDefinition,g_sourceFileDef,g_curClassName)==0)
+ {
+ DBG_CTX((stderr,"Adding new class %s\n",g_curClassName.data()));
+ ClassDef *ncd=new ClassDef("<code>",1,1,
+ g_curClassName,ClassDef::Class,0,0,FALSE);
+ g_codeClassSDict->append(g_curClassName,ncd);
+ // insert base classes.
+ char *s=g_curClassBases.first();
+ while (s)
+ {
+ ClassDef *bcd;
+ bcd=g_codeClassSDict->find(s);
+ if (bcd==0) bcd=getResolvedClass(g_currentDefinition,g_sourceFileDef,s);
+ if (bcd && bcd!=ncd)
+ {
+ ncd->insertBaseClass(bcd,s,Public,Normal);
+ }
+ s=g_curClassBases.next();
+ }
+ }
+ //printf("g_codeClassList.count()=%d\n",g_codeClassList.count());
+ }
+ else // not a class name -> assume inner block
+ {
+ DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
+ g_scopeStack.push(INNERBLOCK);
+ }
+ g_curClassName.resize(0);
+ g_curClassBases.clear();
+ BEGIN( Body );
+ }
+<Bases>"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" {
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<Bases>{SEP}?({ID}{SEP})*{ID} {
+ DBG_CTX((stderr,"%s:addBase(%s)\n",g_curClassName.data(),yytext));
+ g_curClassBases.inSort(yytext);
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+<Bases>"<" {
+ g_code->codify(yytext);
+ if (!g_insideObjC)
+ {
+ g_sharpCount=1;
+ BEGIN ( SkipSharp );
+ }
+ else
+ {
+ g_insideProtocolList=TRUE;
+ }
+ }
+<Bases>">" {
+ g_code->codify(yytext);
+ g_insideProtocolList=FALSE;
+ }
+<SkipSharp>"<" {
+ g_code->codify(yytext);
+ ++g_sharpCount;
+ }
+<SkipSharp>">" {
+ g_code->codify(yytext);
+ if (--g_sharpCount<=0)
+ BEGIN ( Bases );
+ }
+<Bases>"(" {
+ g_code->codify(yytext);
+ g_sharpCount=1;
+ BEGIN ( SkipSharp );
+ }
+<SkipSharp>"(" {
+ g_code->codify(yytext);
+ ++g_sharpCount;
+ }
+<SkipSharp>")" {
+ g_code->codify(yytext);
+ if (--g_sharpCount<=0)
+ BEGIN ( Bases );
+ }
+
+
+<Bases>"," {
+ g_code->codify(yytext);
+ }
+
+
+<Body>{SCOPEPREFIX}?"operator"{B}*"()"{B}*/"(" {
+ addType();
+ generateFunctionLink(*g_code,yytext);
+ g_bracketCount=0;
+ g_args.resize(0);
+ g_name+=yytext;
+ BEGIN( FuncCall );
+ }
+<Body>{SCOPEPREFIX}?"operator"/"(" {
+ addType();
+ generateFunctionLink(*g_code,yytext);
+ g_bracketCount=0;
+ g_args.resize(0);
+ g_name+=yytext;
+ BEGIN( FuncCall );
+ }
+<Body>{SCOPEPREFIX}?"operator"[^a-z_A-Z0-9\(\n]+/"(" {
+ addType();
+ generateFunctionLink(*g_code,yytext);
+ g_bracketCount=0;
+ g_args.resize(0);
+ g_name+=yytext;
+ BEGIN( FuncCall );
+ }
+<Body,TemplDecl>("template"|"generic")/([^a-zA-Z0-9]) {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ g_insideTemplate=TRUE;
+ g_sharpCount=0;
+ }
+<Body>"using"{BN}+"namespace"{BN}+ {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN(UsingName);
+ }
+<UsingName>{ID}("::"{ID})* { addUsingDirective(yytext);
+ generateClassOrGlobalLink(*g_code,yytext);
+ DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n"));
+ g_scopeStack.push(CLASSBLOCK);
+ pushScope(yytext);
+ BEGIN(Body);
+ }
+<UsingName>\n { codifyLines(yytext); BEGIN(Body); }
+<UsingName>. { codifyLines(yytext); BEGIN(Body); }
+<Body,FuncCall>"$"?"this"("->"|".") { g_code->codify(yytext); // this-> for C++, this. for C#
+ }
+<Body>{KEYWORD}/([^a-z_A-Z0-9]) {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ if (QCString(yytext)=="typedef")
+ {
+ addType();
+ g_name+=yytext;
+ }
+ endFontClass();
+ }
+<Body>{KEYWORD}/{B}* {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Body>{KEYWORD}/{BN}*"(" {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ g_name.resize(0);g_type.resize(0);
+ }
+<FuncCall>"in"/{BN}* {
+ if (!g_inForEachExpression) REJECT;
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ // insert the variable in the parent scope, see bug 546158
+ g_theVarContext.popScope();
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ g_theVarContext.pushScope();
+ g_name.resize(0);g_type.resize(0);
+ }
+<Body>{FLOWKW}/{BN}*"(" {
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ g_name.resize(0);g_type.resize(0);
+ g_inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0);
+ BEGIN(FuncCall);
+ }
+<Body>{FLOWKW}/([^a-z_A-Z0-9]) {
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ if (g_inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0))
+ {
+ g_inFunctionTryBlock=FALSE;
+ }
+ }
+<Body>{FLOWKW}/{B}* {
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Body>"*"{B}*")" { // end of cast?
+ g_code->codify(yytext);
+ g_theCallContext.popScope();
+ g_bracketCount--;
+ g_parmType = g_name;
+ BEGIN(FuncCall);
+ }
+<Body>[\\|\)\+\-\/\%\~\!] {
+ g_code->codify(yytext);
+ g_name.resize(0);g_type.resize(0);
+ if (*yytext==')')
+ {
+ g_theCallContext.popScope();
+ g_bracketCount--;
+ BEGIN(FuncCall);
+ }
+ }
+<Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* {
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ addType();
+ g_name+=yytext;
+ }
+<Body>"generic"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* {
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ g_sharpCount=0;
+ BEGIN(TemplDecl);
+ }
+<Body>"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...>
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ g_sharpCount=0;
+ BEGIN(TemplDecl);
+ }
+<TemplDecl>"class"|"typename" {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<TemplDecl>"<" {
+ g_code->codify(yytext);
+ g_sharpCount++;
+ }
+<TemplDecl>">" {
+ g_code->codify(yytext);
+ g_sharpCount--;
+ if (g_sharpCount<=0)
+ {
+ BEGIN(Body);
+ }
+ }
+<TemplCast>">" {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN( g_lastTemplCastContext );
+ }
+<TemplCast>{ID}("::"{ID})* {
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+<TemplCast>("const"|"volatile"){B}* {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<TemplCast>[*^]* {
+ codifyLines(yytext);
+ }
+<Body,FuncCall>{CASTKW}"<" { // static_cast<T>(
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ g_lastTemplCastContext = YY_START;
+ BEGIN(TemplCast);
+ }
+<Body>"$this->"{SCOPENAME}/{BN}*[;,)\]] { // PHP member variable
+ addType();
+ generatePHPVariableLink(*g_code,yytext);
+ g_name+=yytext+7;
+ }
+<Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"("::"{ID})*/{B}* { // A<T> *pt;
+ int i=QCString(yytext).find('<');
+ QCString kw = QCString(yytext).left(i).stripWhiteSpace();
+ if (kw.right(5)=="_cast" && YY_START==Body)
+ {
+ REJECT;
+ }
+ addType();
+ generateClassOrGlobalLink(*g_code,yytext);
+ g_name+=yytext;
+ }
+<Body>{SCOPENAME}/{BN}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro"
+ addType();
+ // changed this to generateFunctionLink, see bug 624514
+ //generateClassOrGlobalLink(*g_code,yytext,FALSE,TRUE);
+ generateFunctionLink(*g_code,yytext);
+ g_name+=yytext;
+ }
+<Body>{SCOPENAME}/{B}* { // p->func()
+ addType();
+ generateClassOrGlobalLink(*g_code,yytext);
+ g_name+=yytext;
+ }
+<Body>"("{B}*("*"{B}*)+{SCOPENAME}*{B}*")"/{B}* { // (*p)->func() but not "if (p) ..."
+ g_code->codify(yytext);
+ int s=0;while (s<(int)yyleng && !isId(yytext[s])) s++;
+ int e=(int)yyleng-1;while (e>=0 && !isId(yytext[e])) e--;
+ QCString varname = ((QCString)yytext).mid(s,e-s+1);
+ addType();
+ g_name=varname;
+ }
+<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo()
+ addType();
+ generateFunctionLink(*g_code,yytext);
+ g_bracketCount=0;
+ g_args.resize(0);
+ g_name+=yytext;
+ BEGIN( FuncCall );
+ }
+<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{RAWBEGIN} {
+ QCString text=yytext;
+ int i=text.find('R');
+ g_code->codify(text.left(i+1));
+ startFontClass("stringliteral");
+ g_code->codify(yytext+i+1);
+ g_lastStringContext=YY_START;
+ g_inForEachExpression = FALSE;
+ g_delimiter = yytext+i+2;
+ g_delimiter=g_delimiter.left(g_delimiter.length()-1);
+ BEGIN( RawString );
+ }
+<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\" {
+ startFontClass("stringliteral");
+ g_code->codify(yytext);
+ g_lastStringContext=YY_START;
+ g_inForEachExpression = FALSE;
+ BEGIN( SkipString );
+ }
+<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\' {
+ startFontClass("stringliteral");
+ g_code->codify(yytext);
+ g_lastStringContext=YY_START;
+ g_inForEachExpression = FALSE;
+ BEGIN( SkipStringS );
+ }
+<SkipString>[^\"\\\r\n]* {
+ g_code->codify(yytext);
+ }
+<SkipStringS>[^\'\\\r\n]* {
+ g_code->codify(yytext);
+ }
+<SkipString,SkipStringS>"//"|"/*" {
+ g_code->codify(yytext);
+ }
+<SkipString>@?\" {
+ g_code->codify(yytext);
+ endFontClass();
+ BEGIN( g_lastStringContext );
+ }
+<SkipStringS>\' {
+ g_code->codify(yytext);
+ endFontClass();
+ BEGIN( g_lastStringContext );
+ }
+<SkipString,SkipStringS>\\. {
+ g_code->codify(yytext);
+ }
+<RawString>{RAWEND} {
+ g_code->codify(yytext);
+ QCString delimiter = yytext+1;
+ delimiter=delimiter.left(delimiter.length()-1);
+ if (delimiter==g_delimiter)
+ {
+ BEGIN( g_lastStringContext );
+ }
+ }
+<RawString>[^)\n]+ { g_code->codify(yytext); }
+<RawString>. { g_code->codify(yytext); }
+<RawString>\n { codifyLines(yytext); }
+<SkipVerbString>[^"\n]+ {
+ g_code->codify(yytext);
+ }
+<SkipVerbString>\"\" { // escaped quote
+ g_code->codify(yytext);
+ }
+<SkipVerbString>\" { // end of string
+ g_code->codify(yytext);
+ endFontClass();
+ BEGIN( g_lastVerbStringContext );
+ }
+<SkipVerbString>. {
+ g_code->codify(yytext);
+ }
+<SkipVerbString>\n {
+ codifyLines(yytext);
+ }
+<Body>":" {
+ g_code->codify(yytext);
+ g_name.resize(0);g_type.resize(0);
+ }
+<Body>"<" {
+ if (g_insideTemplate)
+ {
+ g_sharpCount++;
+ }
+ g_code->codify(yytext);
+ }
+<Body>">" {
+ if (g_insideTemplate)
+ {
+ if (--g_sharpCount<=0)
+ {
+ g_insideTemplate=FALSE;
+ }
+ }
+ g_code->codify(yytext);
+ }
+<Body,MemberCall,MemberCall2,FuncCall>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" {
+ startFontClass("charliteral");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<Body>"."|"->" {
+ if (yytext[0]=='-') // -> could be overloaded
+ {
+ updateCallContextForSmartPointer();
+ }
+ g_code->codify(yytext);
+ g_memCallContext = YY_START;
+ BEGIN( MemberCall );
+ }
+<MemberCall>{SCOPETNAME}/{BN}*"(" {
+ if (g_theCallContext.getScope())
+ {
+ if (!generateClassMemberLink(*g_code,g_theCallContext.getScope(),yytext))
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(yytext);
+ }
+ g_name.resize(0);
+ }
+ else
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(yytext);
+ g_name.resize(0);
+ }
+ g_type.resize(0);
+ g_bracketCount=0;
+ if (g_memCallContext==Body)
+ {
+ BEGIN(FuncCall);
+ }
+ else
+ {
+ BEGIN(g_memCallContext);
+ }
+ }
+<MemberCall>{SCOPENAME}/{B}* {
+ if (g_theCallContext.getScope())
+ {
+ DBG_CTX((stderr,"g_theCallContext.getClass()=%p\n",g_theCallContext.getScope()));
+ if (!generateClassMemberLink(*g_code,g_theCallContext.getScope(),yytext))
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(yytext);
+ }
+ g_name.resize(0);
+ }
+ else
+ {
+ DBG_CTX((stderr,"no class context!\n"));
+ g_code->codify(yytext);
+ addToSearchIndex(yytext);
+ g_name.resize(0);
+ }
+ g_type.resize(0);
+ BEGIN(g_memCallContext);
+ }
+<Body>[,=;\[] {
+ if (g_insideObjC && *yytext=='[')
+ {
+ //printf("Found start of ObjC call!\n");
+ // start of a method call
+ g_contextDict.setAutoDelete(TRUE);
+ g_nameDict.setAutoDelete(TRUE);
+ g_objectDict.setAutoDelete(TRUE);
+ g_wordDict.setAutoDelete(TRUE);
+ g_contextDict.clear();
+ g_nameDict.clear();
+ g_objectDict.clear();
+ g_wordDict.clear();
+ g_currentCtxId = 0;
+ g_currentNameId = 0;
+ g_currentObjId = 0;
+ g_currentCtx = 0;
+ g_braceCount = 0;
+ unput('[');
+ BEGIN(ObjCCall);
+ }
+ else
+ {
+ g_code->codify(yytext);
+ g_saveName = g_name.copy();
+ g_saveType = g_type.copy();
+ if (*yytext!='[' && !g_type.isEmpty())
+ {
+ //printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom());
+ //if (g_scopeStack.top()!=CLASSBLOCK) // commented out for bug731363
+ {
+ //printf("AddVariable: '%s' '%s' context=%d\n",
+ // g_type.data(),g_name.data(),g_theVarContext.count());
+ g_theVarContext.addVariable(g_type,g_name);
+ }
+ g_name.resize(0);
+ }
+ if (*yytext==';' || *yytext=='=')
+ {
+ g_type.resize(0);
+ g_name.resize(0);
+ }
+ else if (*yytext=='[')
+ {
+ g_theCallContext.pushScope();
+ }
+ g_args.resize(0);
+ g_parmType.resize(0);
+ g_parmName.resize(0);
+ }
+ }
+ /*
+<ObjCMemberCall>{ID} {
+ if (qstrcmp(yytext,"self")==0 || qstrcmp(yytext,"super")==0)
+ {
+ // TODO: get proper base class for "super"
+ g_theCallContext.setClass(getClass(g_curClassName));
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+ else
+ {
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+ g_name.resize(0);
+ BEGIN(ObjCMemberCall2);
+ }
+<ObjCMemberCall>"[" {
+ g_code->codify(yytext);
+ g_theCallContext.pushScope();
+ }
+<ObjCMemberCall2>{ID}":"? {
+ g_name+=yytext;
+ if (g_theCallContext.getClass())
+ {
+ //printf("Calling method %s\n",g_name.data());
+ if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),g_name))
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(g_name);
+ }
+ }
+ else
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(g_name);
+ }
+ g_name.resize(0);
+ BEGIN(ObjCMemberCall3);
+ }
+<ObjCMemberCall2,ObjCMemberCall3>"]" {
+ g_theCallContext.popScope();
+ g_code->codify(yytext);
+ BEGIN(Body);
+ }
+ */
+<ObjCCall,ObjCMName>"[" {
+ saveObjCContext();
+ g_currentCtx->format+=*yytext;
+ BEGIN(ObjCCall);
+ //printf("open\n");
+ }
+<ObjCCall,ObjCMName>"]" {
+ g_currentCtx->format+=*yytext;
+ restoreObjCContext();
+ BEGIN(ObjCMName);
+ if (g_currentCtx==0)
+ {
+ // end of call
+ writeObjCMethodCall(g_contextDict.find(0));
+ BEGIN(Body);
+ }
+ //printf("close\n");
+ }
+<ObjCCall>{ID} {
+ g_currentCtx->format+=escapeObject(yytext);
+ if (g_braceCount==0)
+ {
+ g_currentCtx->objectTypeOrName=yytext;
+ //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
+ BEGIN(ObjCMName);
+ }
+ }
+<ObjCMName>{ID}/{BN}*"]" {
+ if (g_braceCount==0 &&
+ g_currentCtx->methodName.isEmpty())
+ {
+ g_currentCtx->methodName=yytext;
+ g_currentCtx->format+=escapeName(yytext);
+ }
+ else
+ {
+ g_currentCtx->format+=escapeWord(yytext);
+ }
+ }
+<ObjCMName>{ID}/{BN}*":" {
+ if (g_braceCount==0)
+ {
+ g_currentCtx->methodName+=yytext;
+ g_currentCtx->methodName+=":";
+ }
+ g_currentCtx->format+=escapeName(yytext);
+ }
+<ObjCSkipStr>[^\n\"$\\]* { g_currentCtx->format+=yytext; }
+<ObjCSkipStr>\\. { g_currentCtx->format+=yytext; }
+<ObjCSkipStr>"\"" { g_currentCtx->format+=yytext;
+ BEGIN(g_lastStringContext);
+ }
+<ObjCCall,ObjCMName>{CHARLIT} { g_currentCtx->format+=yytext; }
+<ObjCCall,ObjCMName>"@"?"\"" { g_currentCtx->format+=yytext;
+ g_lastStringContext=YY_START;
+ BEGIN(ObjCSkipStr);
+ }
+<ObjCCall,ObjCMName,ObjCSkipStr>"$" { g_currentCtx->format+="$$"; }
+<ObjCCall,ObjCMName>"(" { g_currentCtx->format+=*yytext; g_braceCount++; }
+<ObjCCall,ObjCMName>")" { g_currentCtx->format+=*yytext; g_braceCount--; }
+<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#)
+ g_currentCtx->format+=yytext;
+ }
+<ObjCCall,ObjCMName,ObjCSkipStr>{ID} { g_currentCtx->format+=escapeWord(yytext); }
+<ObjCCall,ObjCMName,ObjCSkipStr>. { g_currentCtx->format+=*yytext; }
+<ObjCCall,ObjCMName,ObjCSkipStr>\n { g_currentCtx->format+=*yytext; }
+
+<Body>"]" {
+ g_theCallContext.popScope();
+ g_code->codify(yytext);
+ // TODO: nested arrays like: a[b[0]->func()]->func()
+ g_name = g_saveName.copy();
+ g_type = g_saveType.copy();
+ }
+<Body>[0-9]+ {
+ g_code->codify(yytext);
+ }
+<Body>[0-9]+[xX][0-9A-Fa-f]+ {
+ g_code->codify(yytext);
+ }
+<MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
+ //addParmType();
+ //g_parmName=yytext;
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) {
+ addParmType();
+ g_parmName=yytext;
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) {
+ addParmType();
+ g_parmName=yytext;
+ startFontClass("keywordflow");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<MemberCall2,FuncCall>{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* {
+ addParmType();
+ g_parmName=yytext;
+ generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
+ }
+<FuncCall>";" { // probably a cast, not a function call
+ g_code->codify(yytext);
+ g_inForEachExpression = FALSE;
+ BEGIN( Body );
+ }
+<MemberCall2,FuncCall>, {
+ g_code->codify(yytext);
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ g_parmType.resize(0);g_parmName.resize(0);
+ }
+<MemberCall2,FuncCall>"{" {
+ if (g_bracketCount>0)
+ {
+ g_code->codify(yytext);
+ g_skipInlineInitContext=YY_START;
+ g_curlyCount=0;
+ BEGIN(InlineInit);
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<InlineInit>"{" { g_curlyCount++;
+ g_code->codify(yytext);
+ }
+<InlineInit>"}" {
+ g_code->codify(yytext);
+ if (--g_curlyCount<=0)
+ {
+ BEGIN(g_skipInlineInitContext);
+ }
+ }
+<InlineInit>\n {
+ codifyLines(yytext);
+ }
+<InlineInit>. {
+ g_code->codify(yytext);
+ }
+<MemberCall2,FuncCall>"(" {
+ g_parmType.resize(0);g_parmName.resize(0);
+ g_code->codify(yytext);
+ g_bracketCount++;
+ g_theCallContext.pushScope();
+ if (YY_START==FuncCall && !g_insideBody)
+ {
+ g_theVarContext.pushScope();
+ }
+ }
+<MemberCall2,FuncCall>{OPERATOR} { // operator
+ if (qstrcmp(yytext,"*") &&
+ qstrcmp(yytext,"&") &&
+ qstrcmp(yytext,"^") &&
+ qstrcmp(yytext,"%")) // typically a pointer or reference
+ {
+ // not a * or &, or C++/CLI's ^ or %
+ g_parmType.resize(0);g_parmName.resize(0);
+ }
+ g_code->codify(yytext);
+ }
+<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" {
+ if (yytext[0]==')') // no a pointer cast
+ {
+ //printf("addVariable(%s,%s)\n",g_parmType.data(),g_parmName.data());
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ }
+ else
+ {
+ g_parmType.resize(0);
+ g_parmName.resize(0);
+ }
+ g_theCallContext.popScope();
+ g_inForEachExpression = FALSE;
+ //g_theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b().
+ g_code->codify(yytext);
+ if (--g_bracketCount<=0)
+ {
+ if (g_name.isEmpty())
+ {
+ BEGIN( Body );
+ }
+ else
+ {
+ BEGIN( CallEnd );
+ }
+ }
+ }
+<CallEnd>[ \t\n]* { codifyLines(yytext); }
+ /*
+<MemberCall2,FuncCall>")"[ \t\n]*[;:] {
+ */
+<CallEnd>[;:] {
+ codifyLines(yytext);
+ g_bracketCount=0;
+ if (*yytext==';') g_searchingForBody=FALSE;
+ if (!g_type.isEmpty())
+ {
+ DBG_CTX((stderr,"add variable g_type=%s g_name=%s)\n",g_type.data(),g_name.data()));
+ g_theVarContext.addVariable(g_type,g_name);
+ }
+ g_parmType.resize(0);g_parmName.resize(0);
+ g_theCallContext.setScope(0);
+ if (*yytext==';' || g_insideBody)
+ {
+ if (!g_insideBody)
+ {
+ g_theVarContext.popScope();
+ }
+ g_name.resize(0);g_type.resize(0);
+ BEGIN( Body );
+ }
+ else
+ {
+ g_bracketCount=0;
+ BEGIN( SkipInits );
+ }
+ }
+<CallEnd>("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"sealed"|"override"))*/{BN}*(";"|"="|"throw"{BN}*"(") {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
+ if (g_insideBody)
+ {
+ g_theVarContext.pushScope();
+ }
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ //g_theCallContext.popScope();
+ g_parmType.resize(0);g_parmName.resize(0);
+ int index = g_name.findRev("::");
+ DBG_CTX((stderr,"g_name=%s\n",g_name.data()));
+ if (index!=-1)
+ {
+ QCString scope = g_name.left(index);
+ if (!g_classScope.isEmpty()) scope.prepend(g_classScope+"::");
+ ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope);
+ if (cd)
+ {
+ setClassScope(cd->name());
+ g_scopeStack.push(SCOPEBLOCK);
+ DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
+ }
+ else
+ {
+ //setClassScope(g_realScope);
+ g_scopeStack.push(INNERBLOCK);
+ DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
+ }
+ }
+ else
+ {
+ DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
+ g_scopeStack.push(INNERBLOCK);
+ }
+ yytext[yyleng-1]='\0';
+ QCString cv(yytext);
+ if (!cv.stripWhiteSpace().isEmpty())
+ {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ else // just whitespace
+ {
+ codifyLines(yytext);
+ }
+ g_code->codify("{");
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ if (g_insideBody) g_bodyCurlyCount++;
+ g_curlyCount++;
+ g_type.resize(0); g_name.resize(0);
+ BEGIN( Body );
+ }
+<CallEnd>"try" { // function-try-block
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ g_inFunctionTryBlock=TRUE;
+ }
+<CallEnd>{ID} {
+ if (g_insideBody || !g_parmType.isEmpty())
+ {
+ REJECT;
+ }
+ // could be K&R style definition
+ addParmType();
+ g_parmName=yytext;
+ generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
+ BEGIN(OldStyleArgs);
+ }
+<OldStyleArgs>{ID} {
+ addParmType();
+ g_parmName=yytext;
+ generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
+ }
+<OldStyleArgs>[,;] {
+ g_code->codify(yytext);
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ if (*yytext==';') g_parmType.resize(0);
+ g_parmName.resize(0);
+ }
+<CallEnd,OldStyleArgs>"#" {
+ startFontClass("preprocessor");
+ g_lastSkipCppContext = Body;
+ g_code->codify(yytext);
+ BEGIN( SkipCPP );
+ }
+<CallEnd>. {
+ unput(*yytext);
+ if (!g_insideBody)
+ {
+ g_theVarContext.popScope();
+ }
+ g_name.resize(0);g_args.resize(0);
+ g_parmType.resize(0);g_parmName.resize(0);
+ BEGIN( Body );
+ }
+<SkipInits>";" {
+ g_code->codify(yytext);
+ g_type.resize(0); g_name.resize(0);
+ BEGIN( Body );
+ }
+<SkipInits>"{" {
+ g_code->codify(yytext);
+ g_curlyCount++;
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ if (g_insideBody) g_bodyCurlyCount++;
+ if (g_name.find("::")!=-1)
+ {
+ DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
+ g_scopeStack.push(SCOPEBLOCK);
+ setClassScope(g_realScope);
+ }
+ else
+ {
+ DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
+ g_scopeStack.push(INNERBLOCK);
+ }
+ g_type.resize(0); g_name.resize(0);
+ BEGIN( Body );
+ }
+<SkipInits>{ID} {
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+<FuncCall>{ID}/"(" {
+ generateFunctionLink(*g_code,yytext);
+ }
+<FuncCall>{ID}/("."|"->") {
+ g_name=yytext;
+ generateClassOrGlobalLink(*g_code,yytext);
+ BEGIN( MemberCall2 );
+ }
+<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") {
+ g_code->codify(yytext);
+ int s=0;while (!isId(yytext[s])) s++;
+ int e=(int)yyleng-1;while (!isId(yytext[e])) e--;
+ g_name=((QCString)yytext).mid(s,e-s+1);
+ BEGIN( MemberCall2 );
+ }
+<MemberCall2>{ID}/([ \t\n]*"(") {
+ if (!g_args.isEmpty())
+ generateMemberLink(*g_code,g_args,yytext);
+ else
+ generateClassOrGlobalLink(*g_code,yytext);
+ g_args.resize(0);
+ BEGIN( FuncCall );
+ }
+<MemberCall2>{ID}/([ \t\n]*("."|"->")) {
+ //g_code->codify(yytext);
+ g_name=yytext;
+ generateClassOrGlobalLink(*g_code,yytext);
+ BEGIN( MemberCall2 );
+ }
+<MemberCall2>"->"|"." {
+ if (yytext[0]=='-') // -> could be overloaded
+ {
+ updateCallContextForSmartPointer();
+ }
+ g_code->codify(yytext);
+ g_memCallContext = YY_START;
+ BEGIN( MemberCall );
+ }
+<SkipComment>"/*"("!"?)"*/" {
+ g_code->codify(yytext);
+ endFontClass();
+ BEGIN( g_lastCContext ) ;
+ }
+<SkipComment>"//"|"/*" {
+ g_code->codify(yytext);
+ }
+<SkipComment>[^*/\n]+ {
+ g_code->codify(yytext);
+ }
+<SkipComment>[ \t]*"*/" {
+ g_code->codify(yytext);
+ endFontClass();
+ if (g_lastCContext==SkipCPP)
+ {
+ startFontClass("preprocessor");
+ }
+ BEGIN( g_lastCContext ) ;
+ }
+<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation
+ codifyLines(yytext);
+ }
+<SkipCxxComment>[^\r\n]+ {
+ g_code->codify(yytext);
+ }
+<SkipCxxComment>\r
+<SkipCxxComment>\n {
+ unput('\n');
+ endFontClass();
+ BEGIN( g_lastCContext ) ;
+ }
+<SkipCxxComment>. {
+ g_code->codify(yytext);
+ }
+<RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)?{B}*"/*"[*!]/[^/*] {
+ g_yyLineNr+=QCString(yytext).contains('\n');
+ }
+<RemoveSpecialCComment>"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)? {
+ g_yyLineNr+=QCString(yytext).contains('\n');
+ nextCodeLine();
+ if (g_lastSpecialCContext==SkipCxxComment)
+ { // force end of C++ comment here
+ endFontClass();
+ BEGIN( g_lastCContext ) ;
+ }
+ else
+ {
+ BEGIN(g_lastSpecialCContext);
+ }
+ }
+<RemoveSpecialCComment>"*/" {
+ BEGIN(g_lastSpecialCContext);
+ }
+<RemoveSpecialCComment>[^*\n]+
+<RemoveSpecialCComment>"//"|"/*"
+<RemoveSpecialCComment>\n { g_yyLineNr++; }
+<RemoveSpecialCComment>.
+<MemberCall>[^a-z_A-Z0-9(\n] {
+ g_code->codify(yytext);
+ g_type.resize(0);
+ g_name.resize(0);
+ BEGIN(g_memCallContext);
+ }
+<*>\n({B}*"//"[!/][^\n]*\n)+ { // remove special one-line comment
+ if (YY_START==SkipCPP) REJECT;
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr+=((QCString)yytext).contains('\n');
+ nextCodeLine();
+ }
+ else
+ {
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ if (YY_START==SkipCxxComment)
+ {
+ endFontClass();
+ BEGIN( g_lastCContext ) ;
+ }
+ }
+<SkipCPP>\n/.*\n {
+ endFontClass();
+ codifyLines(yytext);
+ BEGIN( g_lastSkipCppContext ) ;
+ }
+<*>\n{B}*"//@"[{}].*\n { // remove one-line group marker
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr+=2;
+ nextCodeLine();
+ }
+ else
+ {
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ if (YY_START==SkipCxxComment)
+ {
+ endFontClass();
+ BEGIN( g_lastCContext ) ;
+ }
+ }
+<*>\n{B}*"/*@"[{}] { // remove one-line group marker
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_lastSpecialCContext = YY_START;
+ g_yyLineNr++;
+ BEGIN(RemoveSpecialCComment);
+ }
+ else
+ {
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ startFontClass("comment");
+ codifyLines(yytext);
+ BEGIN(SkipComment);
+ }
+ }
+<*>^{B}*"//@"[{}].*\n { // remove one-line group marker
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr++;
+ nextCodeLine();
+ }
+ else
+ {
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ }
+<*>^{B}*"/*@"[{}] { // remove multi-line group marker
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_lastSpecialCContext = YY_START;
+ BEGIN(RemoveSpecialCComment);
+ }
+ else
+ {
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ startFontClass("comment");
+ g_code->codify(yytext);
+ BEGIN(SkipComment);
+ }
+ }
+<*>^{B}*"//"[!/][^\n]*\n { // remove special one-line comment
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr++;
+ //nextCodeLine();
+ }
+ else
+ {
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ }
+<*>"//"[!/][^\n]*\n { // strip special one-line comment
+ if (YY_START==SkipComment || YY_START==SkipString) REJECT;
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ char c[2]; c[0]='\n'; c[1]=0;
+ codifyLines(c);
+ }
+ else
+ {
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ }
+<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file
+ g_forceTagReference=yytext;
+ int s=g_forceTagReference.find(':');
+ int e=g_forceTagReference.findRev(']');
+ g_forceTagReference = g_forceTagReference.mid(s+1,e-s-1);
+ }
+<*>\n{B}*"/*"[!*]/[^/*] {
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_lastSpecialCContext = YY_START;
+ g_yyLineNr++;
+ BEGIN(RemoveSpecialCComment);
+ }
+ else
+ {
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ startFontClass("comment");
+ codifyLines(yytext);
+ BEGIN(SkipComment);
+ }
+ }
+<*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_lastSpecialCContext = YY_START;
+ BEGIN(RemoveSpecialCComment);
+ }
+ else
+ {
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ startFontClass("comment");
+ g_code->codify(yytext);
+ BEGIN(SkipComment);
+ }
+ }
+<*>"/*"[!*]/[^/*] { // special C comment block half way a line
+ if (YY_START==SkipString) REJECT;
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_lastSpecialCContext = YY_START;
+ BEGIN(RemoveSpecialCComment);
+ }
+ else
+ {
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ startFontClass("comment");
+ g_code->codify(yytext);
+ BEGIN(SkipComment);
+ }
+ }
+<*>"/*"("!"?)"*/" {
+ if (YY_START==SkipString) REJECT;
+ if (!Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ startFontClass("comment");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+ }
+<*>"/*" {
+ startFontClass("comment");
+ g_code->codify(yytext);
+ // check is to prevent getting stuck in skipping C++ comments
+ if (YY_START != SkipCxxComment)
+ {
+ g_lastCContext = YY_START ;
+ }
+ BEGIN( SkipComment ) ;
+ }
+<*>@\" { // C# verbatim string
+ startFontClass("stringliteral");
+ g_code->codify(yytext);
+ g_lastVerbStringContext=YY_START;
+ BEGIN(SkipVerbString);
+ }
+<*>"//" {
+ startFontClass("comment");
+ g_code->codify(yytext);
+ g_lastCContext = YY_START ;
+ BEGIN( SkipCxxComment ) ;
+ }
+<*>"("|"[" {
+ g_code->codify(yytext);
+ g_theCallContext.pushScope();
+ }
+<*>")"|"]" {
+ g_code->codify(yytext);
+ g_theCallContext.popScope();
+ }
+<*>\n {
+ g_yyColNr++;
+ codifyLines(yytext);
+ }
+<*>. {
+ g_yyColNr++;
+ g_code->codify(yytext);
+ }
+ /*
+<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines
+ //QCString sepLine=yytext;
+ //g_code->codify("\n\n");
+ //g_yyLineNr+=sepLine.contains('\n');
+ //char sepLine[3]="\n\n";
+ codifyLines(yytext);
+ }
+ */
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+static void saveObjCContext()
+{
+ if (g_currentCtx)
+ {
+ g_currentCtx->format+=QCString().sprintf("$c%d",g_currentCtxId);
+ if (g_braceCount==0 && YY_START==ObjCCall)
+ {
+ g_currentCtx->objectTypeOrName=g_currentCtx->format.mid(1);
+ //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
+ }
+ g_contextStack.push(g_currentCtx);
+ }
+ else
+ {
+ //printf("Trying to save NULL context!\n");
+ }
+ ObjCCallCtx *newCtx = new ObjCCallCtx;
+ newCtx->id = g_currentCtxId;
+ newCtx->lexState = YY_START;
+ newCtx->braceCount = g_braceCount;
+ newCtx->objectType = 0;
+ newCtx->objectVar = 0;
+ newCtx->method = 0;
+ //printf("save state=%d\n",YY_START);
+ g_contextDict.insert(g_currentCtxId,newCtx);
+ g_currentCtx = newCtx;
+ g_braceCount = 0;
+ g_currentCtxId++;
+}
+
+static void restoreObjCContext()
+{
+ //printf("restore state=%d->%d\n",YY_START,g_currentCtx->lexState);
+ BEGIN(g_currentCtx->lexState);
+ g_braceCount = g_currentCtx->braceCount;
+ if (!g_contextStack.isEmpty())
+ {
+ g_currentCtx = g_contextStack.pop();
+ }
+ else
+ {
+ g_currentCtx = 0;
+ //printf("Trying to pop context while g_contextStack is empty!\n");
+ }
+}
+
+void resetCCodeParserState()
+{
+ //printf("***initParseCodeContext()\n");
+ g_forceTagReference.resize(0);
+ g_theVarContext.clear();
+ g_classScopeLengthStack.setAutoDelete(TRUE);
+ g_classScopeLengthStack.clear();
+ delete g_codeClassSDict;
+ g_codeClassSDict = new ClassSDict(17);
+ g_codeClassSDict->setAutoDelete(TRUE);
+ g_codeClassSDict->clear();
+ g_curClassBases.clear();
+ g_anchorCount = 0;
+}
+
+void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s,
+ SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
+ bool collectXRefs)
+{
+ //printf("***parseCode() exBlock=%d exName=%s fd=%p className=%s searchCtx=%s\n",
+ // exBlock,exName,fd,className,searchCtx?searchCtx->name().data():"<none>");
+
+ if (s.isEmpty()) return;
+
+ printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
+
+ TooltipManager::instance()->clearTooltips();
+ if (g_codeClassSDict==0)
+ {
+ resetCCodeParserState();
+ }
+ g_code = &od;
+ g_inputString = s;
+ g_inputPosition = 0;
+ g_currentFontClass = 0;
+ g_needsTermination = FALSE;
+ g_searchCtx = searchCtx;
+ g_collectXRefs = collectXRefs;
+ g_inFunctionTryBlock = FALSE;
+ if (endLine!=-1)
+ g_inputLines = endLine+1;
+ else
+ g_inputLines = countLines();
+
+ if (startLine!=-1)
+ g_yyLineNr = startLine;
+ else
+ g_yyLineNr = 1;
+
+ g_curlyCount = 0;
+ g_bodyCurlyCount = 0;
+ g_bracketCount = 0;
+ g_sharpCount = 0;
+ g_insideTemplate = FALSE;
+ g_theCallContext.clear();
+ g_scopeStack.clear();
+ g_classScope = className;
+ //printf("parseCCode %s\n",className);
+ g_exampleBlock = exBlock;
+ g_exampleName = exName;
+ g_sourceFileDef = fd;
+ g_lineNumbers = fd!=0 && showLineNumbers;
+ bool cleanupSourceDef = FALSE;
+ if (fd==0)
+ {
+ // create a dummy filedef for the example
+ g_sourceFileDef = new FileDef("",(exName?exName:"generated"));
+ cleanupSourceDef = TRUE;
+ }
+ g_insideObjC = lang==SrcLangExt_ObjC;
+ g_insideJava = lang==SrcLangExt_Java;
+ g_insideCS = lang==SrcLangExt_CSharp;
+ g_insidePHP = lang==SrcLangExt_PHP;
+ if (g_sourceFileDef)
+ {
+ setCurrentDoc("l00001");
+ }
+ g_currentDefinition = 0;
+ g_currentMemberDef = 0;
+ g_searchingForBody = exBlock;
+ g_insideBody = FALSE;
+ g_bracketCount = 0;
+ if (!g_exampleName.isEmpty())
+ {
+ g_exampleFile = convertNameToFile(g_exampleName+"-example",FALSE,TRUE);
+ //printf("g_exampleFile=%s\n",g_exampleFile.data());
+ }
+ g_includeCodeFragment = inlineFragment;
+ //printf("** exBlock=%d exName=%s include=%d\n",exBlock,exName,inlineFragment);
+ startCodeLine();
+ g_type.resize(0);
+ g_name.resize(0);
+ g_args.resize(0);
+ g_parmName.resize(0);
+ g_parmType.resize(0);
+ if (memberDef) setParameterList(memberDef);
+ codeYYrestart( codeYYin );
+ BEGIN( Body );
+ codeYYlex();
+ g_lexInit=TRUE;
+ if (g_needsTermination)
+ {
+ endFontClass();
+ DBG_CTX((stderr,"endCodeLine(%d)\n",g_yyLineNr));
+ g_code->endCodeLine();
+ }
+ if (fd)
+ {
+ TooltipManager::instance()->writeTooltips(*g_code);
+ }
+ if (cleanupSourceDef)
+ {
+ // delete the temporary file definition used for this example
+ delete g_sourceFileDef;
+ g_sourceFileDef=0;
+ }
+
+ printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
+ return;
+}
+
+void codeFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+ if (g_lexInit)
+ {
+ codeYYlex_destroy();
+ }
+#endif
+}
+
+
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void codeYYdummy() { yy_flex_realloc(0,0); }
+}
+#elif YY_FLEX_SUBMINOR_VERSION<33
+#error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
+#endif
+
diff --git a/src/commentcnv.h b/src/commentcnv.h
new file mode 100644
index 0000000..6255a73
--- /dev/null
+++ b/src/commentcnv.h
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _COMMENTCNV_H
+#define _COMMENTCNV_H
+
+class BufStr;
+
+extern void convertCppComments(BufStr *inBuf,BufStr *outBuf,
+ const char *fileName);
+
+#endif
+
diff --git a/src/commentcnv.l b/src/commentcnv.l
new file mode 100644
index 0000000..ec56b90
--- /dev/null
+++ b/src/commentcnv.l
@@ -0,0 +1,1039 @@
+/*****************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+#define YY_NEVER_INTERACTIVE 1
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qstack.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qglobal.h>
+
+#include "bufstr.h"
+#include "debug.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "condparser.h"
+
+#include <assert.h>
+
+#define YY_NO_INPUT 1
+
+#define ADDCHAR(c) g_outBuf->addChar(c)
+#define ADDARRAY(a,s) g_outBuf->addArray(a,s)
+
+struct CondCtx
+{
+ CondCtx(int line,QCString id,bool b)
+ : lineNr(line),sectionId(id), skip(b) {}
+ int lineNr;
+ QCString sectionId;
+ bool skip;
+};
+
+struct CommentCtx
+{
+ CommentCtx(int line)
+ : lineNr(line) {}
+ int lineNr;
+};
+
+static BufStr * g_inBuf;
+static BufStr * g_outBuf;
+static int g_inBufPos;
+static int g_col;
+static int g_blockHeadCol;
+static bool g_mlBrief;
+static int g_readLineCtx;
+static bool g_skip;
+static QCString g_fileName;
+static int g_lineNr;
+static int g_condCtx;
+static QStack<CondCtx> g_condStack;
+static QStack<CommentCtx> g_commentStack;
+static QCString g_blockName;
+static int g_lastCommentContext;
+static bool g_inSpecialComment;
+static bool g_inRoseComment;
+static int g_stringContext;
+static int g_charContext;
+static int g_javaBlock;
+static bool g_specialComment;
+
+static QCString g_aliasString;
+static int g_blockCount;
+static bool g_lastEscaped;
+static int g_lastBlockContext;
+static bool g_pythonDocString;
+static int g_nestingCount;
+
+static SrcLangExt g_lang;
+static bool isFixedForm; // For Fortran
+
+static void replaceCommentMarker(const char *s,int len)
+{
+ const char *p=s;
+ char c;
+ // copy leading blanks
+ while ((c=*p) && (c==' ' || c=='\t' || c=='\n'))
+ {
+ ADDCHAR(c);
+ g_lineNr += c=='\n';
+ p++;
+ }
+ // replace start of comment marker by blanks and the last character by a *
+ int blanks=0;
+ while ((c=*p) && (c=='/' || c=='!' || c=='#'))
+ {
+ blanks++;
+ p++;
+ if (*p=='<') // comment-after-item marker
+ {
+ blanks++;
+ p++;
+ }
+ if (c=='!') // end after first !
+ {
+ break;
+ }
+ }
+ if (blanks>0)
+ {
+ while (blanks>2)
+ {
+ ADDCHAR(' ');
+ blanks--;
+ }
+ if (blanks>1) ADDCHAR('*');
+ ADDCHAR(' ');
+ }
+ // copy comment line to output
+ ADDARRAY(p,len-(int)(p-s));
+}
+
+static inline int computeIndent(const char *s)
+{
+ int col=0;
+ static int tabSize=Config_getInt("TAB_SIZE");
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ if (c==' ') col++;
+ else if (c=='\t') col+=tabSize-(col%tabSize);
+ else break;
+ }
+ return col;
+}
+
+static inline void copyToOutput(const char *s,int len)
+{
+ int i;
+ if (g_skip) // only add newlines.
+ {
+ for (i=0;i<len;i++)
+ {
+ if (s[i]=='\n')
+ {
+ ADDCHAR('\n');
+ //fprintf(stderr,"---> skip %d\n",g_lineNr);
+ g_lineNr++;
+ }
+ }
+ }
+ else if (len>0)
+ {
+ ADDARRAY(s,len);
+ static int tabSize=Config_getInt("TAB_SIZE");
+ for (i=0;i<len;i++)
+ {
+ switch (s[i])
+ {
+ case '\n': g_col=0;
+ //fprintf(stderr,"---> copy %d\n",g_lineNr);
+ g_lineNr++; break;
+ case '\t': g_col+=tabSize-(g_col%tabSize); break;
+ default: g_col++; break;
+ }
+ }
+ }
+}
+
+static void startCondSection(const char *sectId)
+{
+ //printf("startCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
+ CondParser prs;
+ bool expResult = prs.parse(g_fileName,g_lineNr,sectId);
+ g_condStack.push(new CondCtx(g_lineNr,sectId,g_skip));
+ if (!expResult) // not enabled
+ {
+ g_skip=TRUE;
+ }
+}
+
+static void endCondSection()
+{
+ if (g_condStack.isEmpty())
+ {
+ warn(g_fileName,g_lineNr,"Found \\endcond command without matching \\cond");
+ g_skip=FALSE;
+ }
+ else
+ {
+ CondCtx *ctx = g_condStack.pop();
+ g_skip=ctx->skip;
+ }
+ //printf("endCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
+}
+
+/** copies string \a s with length \a len to the output, while
+ * replacing any alias commands found in the string.
+ */
+static void replaceAliases(const char *s)
+{
+ QCString result = resolveAliasCmd(s);
+ //printf("replaceAliases(%s)->'%s'\n",s,result.data());
+ copyToOutput(result,result.length());
+}
+
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int bytesInBuf = g_inBuf->curPos()-g_inBufPos;
+ int bytesToCopy = QMIN(max_size,bytesInBuf);
+ memcpy(buf,g_inBuf->data()+g_inBufPos,bytesToCopy);
+ g_inBufPos+=bytesToCopy;
+ return bytesToCopy;
+}
+
+void replaceComment(int offset);
+
+%}
+
+%option noyywrap
+
+%x Scan
+%x SkipString
+%x SkipChar
+%x SComment
+%x CComment
+%x Verbatim
+%x VerbatimCode
+%x ReadLine
+%x CondLine
+%x ReadAliasArgs
+
+%%
+
+<Scan>[^"'!\/\n\\#-,]* { /* eat anything that is not " / , or \n */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Scan>[,] { /* eat , so we have a nice separator in long initialization lines */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Scan>"\"\"\""! { /* start of python long comment */
+ if (g_lang!=SrcLangExt_Python)
+ {
+ REJECT;
+ }
+ else
+ {
+ g_pythonDocString = TRUE;
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ }
+<Scan>![><!]/.*\n {
+ if (g_lang!=SrcLangExt_Fortran)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ }
+<Scan>[Cc\*][><!]/.*\n {
+ if (g_lang!=SrcLangExt_Fortran)
+ {
+ REJECT;
+ }
+ else
+ {
+ /* check for fixed format; we might have some conditional as part of multilene if like C<5 .and. & */
+ if (isFixedForm && (g_col == 0))
+ {
+ copyToOutput(yytext,(int)yyleng);
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+ }
+<Scan>!.*\n {
+ if (g_lang!=SrcLangExt_Fortran)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ }
+ }
+<Scan>[Cc\*].*\n {
+ if (g_lang!=SrcLangExt_Fortran)
+ {
+ REJECT;
+ }
+ else
+ {
+ if (g_col == 0)
+ {
+ copyToOutput(yytext,(int)yyleng);
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+ }
+<Scan>"\"" { /* start of a string */
+ copyToOutput(yytext,(int)yyleng);
+ g_stringContext = YY_START;
+ BEGIN(SkipString);
+ }
+<Scan>' {
+ copyToOutput(yytext,(int)yyleng);
+ g_charContext = YY_START;
+ if (g_lang!=SrcLangExt_VHDL)
+ {
+ BEGIN(SkipChar);
+ }
+ }
+<Scan>\n { /* new line */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Scan>"//!"/.*\n[ \t]*"//"[\/!][^\/] | /* start C++ style special comment block */
+<Scan>("///"[/]*)/[^/].*\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */
+ if (g_mlBrief)
+ {
+ REJECT; // bail out if we do not need to convert
+ }
+ else
+ {
+ int i=3;
+ if (yytext[2]=='/')
+ {
+ while (i<(int)yyleng && yytext[i]=='/') i++;
+ }
+ g_blockHeadCol=g_col;
+ copyToOutput("/**",3);
+ replaceAliases(yytext+i);
+ g_inSpecialComment=TRUE;
+ //BEGIN(SComment);
+ g_readLineCtx=SComment;
+ BEGIN(ReadLine);
+ }
+ }
+<Scan>"//##Documentation".*/\n { /* Start of Rational Rose ANSI C++ comment block */
+ if (g_mlBrief) REJECT;
+ int i=17; //=strlen("//##Documentation");
+ g_blockHeadCol=g_col;
+ copyToOutput("/**",3);
+ replaceAliases(yytext+i);
+ g_inRoseComment=TRUE;
+ BEGIN(SComment);
+ }
+<Scan>"//"/.*\n { /* one line C++ comment */
+ g_inSpecialComment=yytext[2]=='/' || yytext[2]=='!';
+ copyToOutput(yytext,(int)yyleng);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+<Scan>"/**/" { /* avoid matching next rule for empty C comment, see bug 711723 */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Scan>"/*"[*!]? { /* start of a C comment */
+ g_specialComment=(int)yyleng==3;
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+<Scan>"#"("#")? {
+ if (g_lang!=SrcLangExt_Python)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ }
+<Scan>"--!" {
+ if (g_lang!=SrcLangExt_VHDL)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ }
+<Scan>![><!] {
+ if (g_lang!=SrcLangExt_Fortran)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ g_nestingCount=0;
+ g_commentStack.clear(); /* to be on the save side */
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ }
+<CComment>"{@code"/[ \t\n] {
+ copyToOutput("@code",5);
+ g_lastCommentContext = YY_START;
+ g_javaBlock=1;
+ g_blockName=&yytext[1];
+ BEGIN(VerbatimCode);
+ }
+<CComment,ReadLine>[\\@]("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] { /* start of a verbatim block */
+ copyToOutput(yytext,(int)yyleng);
+ g_lastCommentContext = YY_START;
+ g_javaBlock=0;
+ g_blockName=&yytext[1];
+ BEGIN(VerbatimCode);
+ }
+<CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) {
+ copyToOutput(yytext,(int)yyleng);
+ g_blockName=&yytext[1];
+ if (g_blockName.at(1)=='[')
+ {
+ g_blockName.at(1)=']';
+ }
+ else if (g_blockName.at(1)=='{')
+ {
+ g_blockName.at(1)='}';
+ }
+ g_lastCommentContext = YY_START;
+ BEGIN(Verbatim);
+ }
+<CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */
+ copyToOutput(yytext,(int)yyleng);
+ g_blockName=&yytext[1];
+ g_lastCommentContext = YY_START;
+ BEGIN(Verbatim);
+ }
+<Scan>. { /* any ather character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Verbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"docbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}") { /* end of verbatim block */
+ copyToOutput(yytext,(int)yyleng);
+ if (yytext[1]=='f') // end of formula
+ {
+ BEGIN(g_lastCommentContext);
+ }
+ else if (&yytext[4]==g_blockName)
+ {
+ BEGIN(g_lastCommentContext);
+ }
+ }
+<VerbatimCode>"{" {
+ if (g_javaBlock==0)
+ {
+ REJECT;
+ }
+ else
+ {
+ g_javaBlock++;
+ copyToOutput(yytext,(int)yyleng);
+ }
+ }
+<VerbatimCode>"}" {
+ if (g_javaBlock==0)
+ {
+ REJECT;
+ }
+ else
+ {
+ g_javaBlock--;
+ if (g_javaBlock==0)
+ {
+ copyToOutput(" @endcode ",10);
+ BEGIN(g_lastCommentContext);
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ }
+ }
+ }
+<VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc"|"enduml") { /* end of verbatim block */
+ copyToOutput(yytext,(int)yyleng);
+ if (&yytext[4]==g_blockName)
+ {
+ BEGIN(g_lastCommentContext);
+ }
+ }
+<VerbatimCode>^[ \t]*"//"[\!\/]? { /* skip leading comments */
+ if (!g_inSpecialComment)
+ {
+ copyToOutput(yytext,(int)yyleng);
+ }
+ else
+ {
+ int l=0;
+ while (yytext[l]==' ' || yytext[l]=='\t')
+ {
+ l++;
+ }
+ copyToOutput(yytext,l);
+ if (yyleng-l==3) // ends with //! or ///
+ {
+ copyToOutput(" * ",3);
+ }
+ else // ends with //
+ {
+ copyToOutput("//",2);
+ }
+ }
+ }
+<Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Verbatim,VerbatimCode>\n { /* new line in verbatim block */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<Verbatim>^[ \t]*"///" {
+ if (g_blockName=="dot" || g_blockName=="msc" || g_blockName=="startuml" || g_blockName.at(0)=='f')
+ {
+ // see bug 487871, strip /// from dot images and formulas.
+ int l=0;
+ while (yytext[l]==' ' || yytext[l]=='\t')
+ {
+ l++;
+ }
+ copyToOutput(yytext,l);
+ copyToOutput(" ",3);
+ }
+ else // even slashes are verbatim (e.g. \verbatim, \code)
+ {
+ REJECT;
+ }
+ }
+<Verbatim,VerbatimCode>. { /* any other character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipString>\\. { /* escaped character in string */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipString>"\"" { /* end of string */
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(g_stringContext);
+ }
+<SkipString>. { /* any other string character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipString>\n { /* new line inside string (illegal for some compilers) */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipChar>\\. { /* escaped character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipChar>' { /* end of character literal */
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(g_charContext);
+ }
+<SkipChar>. { /* any other string character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SkipChar>\n { /* new line character */
+ copyToOutput(yytext,(int)yyleng);
+ }
+
+<CComment>[^\\!@*\n{\"\/]* { /* anything that is not a '*' or command */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<CComment>"*"+[^*/\\@\n{\"]* { /* stars without slashes */
+ copyToOutput(yytext,(int)yyleng);
+ }
+<CComment>"\"\"\"" { /* end of Python docstring */
+ if (g_lang!=SrcLangExt_Python)
+ {
+ REJECT;
+ }
+ else
+ {
+ g_pythonDocString = FALSE;
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(Scan);
+ }
+ }
+<CComment>\n { /* new line in comment */
+ copyToOutput(yytext,(int)yyleng);
+ /* in case of Fortran always end of comment */
+ if (g_lang==SrcLangExt_Fortran)
+ {
+ BEGIN(Scan);
+ }
+ }
+<CComment>"/"+"*" { /* nested C comment */
+ g_nestingCount++;
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ copyToOutput(yytext,(int)yyleng);
+ }
+<CComment>"*"+"/" { /* end of C comment */
+ if (g_lang==SrcLangExt_Python)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ if (g_nestingCount<=0)
+ {
+ BEGIN(Scan);
+ }
+ else
+ {
+ g_nestingCount--;
+ delete g_commentStack.pop();
+ }
+ }
+ }
+<CComment>"\n"/[ \t]*[^#] { /* end of Python comment */
+ if (g_lang!=SrcLangExt_Python || g_pythonDocString)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(Scan);
+ }
+ }
+<CComment>"\n"/[ \t]*[^\-] { /* end of VHDL comment */
+ if (g_lang!=SrcLangExt_VHDL)
+ {
+ REJECT;
+ }
+ else
+ {
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(Scan);
+ }
+ }
+ /* removed for bug 674842 (bug was introduced in rev 768)
+<CComment>"'" {
+ g_charContext = YY_START;
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(SkipChar);
+ }
+<CComment>"\"" {
+ g_stringContext = YY_START;
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(SkipString);
+ }
+ */
+<CComment>. {
+ copyToOutput(yytext,(int)yyleng);
+ }
+<SComment>^[ \t]*"///"[\/]*/\n {
+ replaceComment(0);
+ }
+<SComment>\n[ \t]*"///"[\/]*/\n {
+ replaceComment(1);
+ }
+<SComment>^[ \t]*"///"[^\/\n]/.*\n {
+ replaceComment(0);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+<SComment>\n[ \t]*"///"[^\/\n]/.*\n {
+ replaceComment(1);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+<SComment>^[ \t]*"//!" | // just //!
+<SComment>^[ \t]*"//!<"/.*\n | // or //!< something
+<SComment>^[ \t]*"//!"[^<]/.*\n { // or //!something
+ replaceComment(0);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+<SComment>\n[ \t]*"//!" |
+<SComment>\n[ \t]*"//!<"/.*\n |
+<SComment>\n[ \t]*"//!"[^<\n]/.*\n {
+ replaceComment(1);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+<SComment>^[ \t]*"//##"/.*\n {
+ if (!g_inRoseComment)
+ {
+ REJECT;
+ }
+ else
+ {
+ replaceComment(0);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+ }
+<SComment>\n[ \t]*"//##"/.*\n {
+ if (!g_inRoseComment)
+ {
+ REJECT;
+ }
+ else
+ {
+ replaceComment(1);
+ g_readLineCtx=YY_START;
+ BEGIN(ReadLine);
+ }
+ }
+<SComment>\n { /* end of special comment */
+ copyToOutput(" */",3);
+ copyToOutput(yytext,(int)yyleng);
+ g_inSpecialComment=FALSE;
+ g_inRoseComment=FALSE;
+ BEGIN(Scan);
+ }
+<ReadLine>[^\\@\n]*/\n {
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(g_readLineCtx);
+ }
+<CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
+ copyToOutput(yytext,(int)yyleng);
+ }
+<CComment,ReadLine>[\\@]"cond"/[^a-z_A-Z0-9] { // conditional section
+ g_condCtx = YY_START;
+ BEGIN(CondLine);
+ }
+<CComment,ReadLine>[\\@]"endcond"/[^a-z_A-Z0-9] { // end of conditional section
+ bool oldSkip=g_skip;
+ endCondSection();
+ if (YY_START==CComment && oldSkip && !g_skip)
+ {
+ //printf("** Adding start of comment!\n");
+ if (g_lang!=SrcLangExt_Python &&
+ g_lang!=SrcLangExt_VHDL &&
+ g_lang!=SrcLangExt_Fortran)
+ {
+ ADDCHAR('/');
+ ADDCHAR('*');
+ if (g_specialComment)
+ {
+ ADDCHAR('*');
+ }
+ }
+ }
+ }
+<CondLine>[!()&| \ta-z_A-Z0-9.\-]+ {
+ bool oldSkip=g_skip;
+ startCondSection(yytext);
+ if ((g_condCtx==CComment || g_readLineCtx==SComment) &&
+ !oldSkip && g_skip)
+ {
+ if (g_lang!=SrcLangExt_Python &&
+ g_lang!=SrcLangExt_VHDL &&
+ g_lang!=SrcLangExt_Fortran)
+ {
+ ADDCHAR('*');
+ ADDCHAR('/');
+ }
+ }
+ if (g_readLineCtx==SComment)
+ {
+ BEGIN(SComment);
+ }
+ else
+ {
+ BEGIN(g_condCtx);
+ }
+ }
+<CondLine>[ \t]*
+<CComment,ReadLine>[\\@]"cond"[ \t\r]*/\n |
+<CondLine>. { // forgot section id?
+ if (YY_START!=CondLine) g_condCtx=YY_START;
+ bool oldSkip=g_skip;
+ startCondSection(" "); // fake section id causing the section to be hidden unconditionally
+ if ((g_condCtx==CComment || g_readLineCtx==SComment) &&
+ !oldSkip && g_skip)
+ {
+ //printf("** Adding terminator for comment!\n");
+ if (g_lang!=SrcLangExt_Python &&
+ g_lang!=SrcLangExt_VHDL)
+ {
+ ADDCHAR('*');
+ ADDCHAR('/');
+ }
+ }
+ if (*yytext=='\n') g_lineNr++;
+ if (g_readLineCtx==SComment)
+ {
+ BEGIN(SComment);
+ }
+ else
+ {
+ BEGIN(g_condCtx);
+ }
+ }
+<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias without arguments
+ replaceAliases(yytext);
+ }
+<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]*"{" { // expand alias with arguments
+ g_lastBlockContext=YY_START;
+ g_blockCount=1;
+ g_aliasString=yytext;
+ g_lastEscaped=0;
+ BEGIN( ReadAliasArgs );
+ }
+<ReadAliasArgs>^[ \t]*"//"[/!]/[^\n]+ { // skip leading special comments (see bug 618079)
+ }
+<ReadAliasArgs>"*/" { // oops, end of comment in the middle of an alias?
+ if (g_lang==SrcLangExt_Python)
+ {
+ REJECT;
+ }
+ else // abort the alias, restart scanning
+ {
+ copyToOutput(g_aliasString,g_aliasString.length());
+ copyToOutput(yytext,(int)yyleng);
+ BEGIN(Scan);
+ }
+ }
+<ReadAliasArgs>[^{}\n\\\*]+ {
+ g_aliasString+=yytext;
+ g_lastEscaped=FALSE;
+ }
+<ReadAliasArgs>"\\" {
+ if (g_lastEscaped) g_lastEscaped=FALSE;
+ else g_lastEscaped=TRUE;
+ g_aliasString+=yytext;
+ }
+<ReadAliasArgs>\n {
+ g_aliasString+=yytext;
+ g_lineNr++;
+ g_lastEscaped=FALSE;
+ }
+<ReadAliasArgs>"{" {
+ g_aliasString+=yytext;
+ if (!g_lastEscaped) g_blockCount++;
+ g_lastEscaped=FALSE;
+ }
+<ReadAliasArgs>"}" {
+ g_aliasString+=yytext;
+ if (!g_lastEscaped) g_blockCount--;
+ if (g_blockCount==0)
+ {
+ replaceAliases(g_aliasString);
+ BEGIN( g_lastBlockContext );
+ }
+ g_lastEscaped=FALSE;
+ }
+<ReadAliasArgs>. {
+ g_aliasString+=yytext;
+ g_lastEscaped=FALSE;
+ }
+<ReadLine>. {
+ copyToOutput(yytext,(int)yyleng);
+ }
+
+%%
+
+void replaceComment(int offset)
+{
+ if (g_mlBrief || g_skip)
+ {
+ copyToOutput(yytext,(int)yyleng);
+ }
+ else
+ {
+ //printf("replaceComment(%s)\n",yytext);
+ int i=computeIndent(&yytext[offset]);
+ if (i==g_blockHeadCol)
+ {
+ replaceCommentMarker(yytext,(int)yyleng);
+ }
+ else
+ {
+ copyToOutput(" */",3);
+ int i;for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]);
+ g_inSpecialComment=FALSE;
+ BEGIN(Scan);
+ }
+ }
+}
+
+// simplified way to know if this is fixed form
+// duplicate in fortrancode.l
+static bool recognizeFixedForm(const char* contents)
+{
+ int column=0;
+ bool skipLine=FALSE;
+
+ for(int i=0;;i++) {
+ column++;
+
+ switch(contents[i]) {
+ case '\n':
+ column=0;
+ skipLine=FALSE;
+ break;
+ case ' ':
+ break;
+ case '\000':
+ return FALSE;
+ case 'C':
+ case 'c':
+ case '*':
+ if(column==1) return TRUE;
+ if(skipLine) break;
+ return FALSE;
+ case '!':
+ if(column>1 && column<7) return FALSE;
+ skipLine=TRUE;
+ break;
+ default:
+ if(skipLine) break;
+ if(column==7) return TRUE;
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+
+/*! This function does three things:
+ * -# It converts multi-line C++ style comment blocks (that are aligned)
+ * to C style comment blocks (if MULTILINE_CPP_IS_BRIEF is set to NO).
+ * -# It replaces aliases with their definition (see ALIASES)
+ * -# It handles conditional sections (cond...endcond blocks)
+ */
+void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
+{
+ //printf("convertCppComments(%s)\n",fileName);
+ g_inBuf = inBuf;
+ g_outBuf = outBuf;
+ g_inBufPos = 0;
+ g_col = 0;
+ g_mlBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF");
+ g_skip = FALSE;
+ g_fileName = fileName;
+ g_lang = getLanguageFromFileName(fileName);
+ g_pythonDocString = FALSE;
+ g_lineNr = 1;
+ g_condStack.clear();
+ g_condStack.setAutoDelete(TRUE);
+ g_commentStack.clear();
+ g_commentStack.setAutoDelete(TRUE);
+
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+ isFixedForm = FALSE;
+ if (g_lang==SrcLangExt_Fortran)
+ {
+ isFixedForm = recognizeFixedForm(inBuf->data());
+ }
+
+ if (g_lang==SrcLangExt_Markdown)
+ {
+ g_nestingCount=0;
+ BEGIN(CComment);
+ g_commentStack.push(new CommentCtx(g_lineNr));
+ }
+ else
+ {
+ BEGIN(Scan);
+ }
+ yylex();
+ while (!g_condStack.isEmpty())
+ {
+ CondCtx *ctx = g_condStack.pop();
+ QCString sectionInfo = " ";
+ if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label %s ",ctx->sectionId.data());
+ warn(g_fileName,ctx->lineNr,"Conditional section%sdoes not have "
+ "a corresponding \\endcond command within this file.",sectionInfo.data());
+ }
+ if (g_nestingCount>0 || (YY_START==CComment && g_lang!=SrcLangExt_Markdown))
+ {
+ QCString tmp= "(probable line reference: ";
+ bool first = TRUE;
+ while (!g_commentStack.isEmpty())
+ {
+ CommentCtx *ctx = g_commentStack.pop();
+ if (!first) tmp += ", ";
+ tmp += QCString().setNum(ctx->lineNr);
+ first = FALSE;
+ delete ctx;
+ }
+ tmp += ")";
+ warn(g_fileName,g_lineNr,"Reached end of file while still inside a (nested) comment. "
+ "Nesting level %d %s",g_nestingCount+1,tmp.data()); // add one for "normal" expected end of comment
+ }
+ g_commentStack.clear();
+ if (Debug::isFlagSet(Debug::CommentCnv))
+ {
+ g_outBuf->at(g_outBuf->curPos())='\0';
+ msg("-------------\n%s\n-------------\n",g_outBuf->data());
+ }
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+
+//----------------------------------------------------------------------------
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void commentcnvYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/commentscan.h b/src/commentscan.h
new file mode 100644
index 0000000..ce28ea2
--- /dev/null
+++ b/src/commentscan.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef COMMENTSCAN_H
+#define COMMENTSCAN_H
+
+#include "types.h"
+
+class Entry;
+class ParserInterface;
+
+/** @file
+ * @brief Interface for the comment block parser */
+
+/** Invokes the comment block parser with the request to parse a
+ * single comment block.
+ * @param[in] parser The language parse that invoked this function.
+ * The comment block parse may invoke
+ * ParserInterface::parsePrototype() in order to parse
+ * the argument of a @@fn command.
+ * @param[in] curEntry The Entry to which the comment block belongs.
+ * Any information (like documentation) that is found in
+ * the comment block will be stored in this entry.
+ * @param[in] comment A string representing the actual comment block.
+ * Note that leading *'s are already stripped from the comment block.
+ * @param[in] fileName The name of the file in which the comment is found.
+ * Mainly used for producing warnings.
+ * @param[in,out] lineNr The line number at which the comment block was found.
+ * When the function returns it will be set to the last line parsed.
+ * @param[in] isBrief TRUE iff this comment block represents a brief description.
+ * @param[in] isJavaDocStyle TRUE iff this comment block is in "JavaDoc" style.
+ * This means that it starts as a brief description until the end of
+ * the sentences is found and then proceeds as a detailed description.
+ * @param[in] isInbody TRUE iff this comment block is located in the body of
+ * a function.
+ * @param[in,out] prot The protection level in which this comment block was
+ * found. Commands in the comment block may override this.
+ * @param[in,out] position The character position within \a comment where the
+ * comment block starts. Typically used in case the comment block
+ * contains multiple structural commands.
+ * @param[out] newEntryNeeded Boolean that is TRUE if the comment block parser
+ * finds that a the comment block finishes the entry and a new one
+ * needs to be started.
+ * @returns TRUE if the comment requires further processing. The
+ * parameter \a newEntryNeeded will typically be true in this case and
+ * \a position will indicate the offset inside the \a comment string
+ * where to proceed parsing. FALSE indicates no further processing is
+ * needed.
+ */
+bool parseCommentBlock(ParserInterface *parser,
+ Entry *curEntry,
+ const QCString &comment,
+ const QCString &fileName,
+ int &lineNr,
+ bool isBrief,
+ bool isJavaDocStyle,
+ bool isInbody,
+ Protection &prot,
+ int &position,
+ bool &newEntryNeeded
+ );
+
+void groupEnterFile(const char *file,int line);
+void groupLeaveFile(const char *file,int line);
+void groupLeaveCompound(const char *file,int line,const char *name);
+void groupEnterCompound(const char *file,int line,const char *name);
+void openGroup(Entry *e,const char *file,int line);
+void closeGroup(Entry *,const char *file,int line,bool foundInline=FALSE);
+void initGroupInfo(Entry *e);
+
+
+#endif
diff --git a/src/commentscan.l b/src/commentscan.l
new file mode 100644
index 0000000..168907f
--- /dev/null
+++ b/src/commentscan.l
@@ -0,0 +1,3194 @@
+/*****************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <unistd.h>
+#include <qfile.h>
+
+#include "scanner.h"
+#include "entry.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "index.h"
+#include "defargs.h"
+#include "language.h"
+#include "outputlist.h"
+#include "membergroup.h"
+#include "reflist.h"
+#include "debug.h"
+#include "parserintf.h"
+#include "cite.h"
+#include "markdown.h"
+#include "condparser.h"
+#include "formula.h"
+
+#define YY_NO_INPUT 1
+
+// forward declarations
+static bool handleBrief(const QCString &);
+static bool handleFn(const QCString &);
+static bool handleDef(const QCString &);
+static bool handleOverload(const QCString &);
+static bool handleEnum(const QCString &);
+static bool handleDefGroup(const QCString &);
+static bool handleAddToGroup(const QCString &);
+static bool handleWeakGroup(const QCString &);
+static bool handleNamespace(const QCString &);
+static bool handlePackage(const QCString &);
+static bool handleClass(const QCString &);
+static bool handleHeaderFile(const QCString &);
+static bool handleProtocol(const QCString &);
+static bool handleCategory(const QCString &);
+static bool handleUnion(const QCString &);
+static bool handleStruct(const QCString &);
+static bool handleInterface(const QCString &);
+static bool handleIdlException(const QCString &);
+static bool handlePage(const QCString &);
+static bool handleMainpage(const QCString &);
+static bool handleFile(const QCString &);
+static bool handleDir(const QCString &);
+static bool handleExample(const QCString &);
+static bool handleDetails(const QCString &);
+static bool handleName(const QCString &);
+static bool handleTodo(const QCString &);
+static bool handleTest(const QCString &);
+static bool handleBug(const QCString &);
+static bool handleSubpage(const QCString &s);
+static bool handleDeprecated(const QCString &);
+static bool handleXRefItem(const QCString &);
+static bool handleRelated(const QCString &);
+static bool handleRelatedAlso(const QCString &);
+static bool handleMemberOf(const QCString &);
+static bool handleRefItem(const QCString &);
+static bool handleSection(const QCString &);
+static bool handleAnchor(const QCString &);
+static bool handleCite(const QCString &);
+static bool handleFormatBlock(const QCString &);
+static bool handleAddIndex(const QCString &);
+static bool handleIf(const QCString &);
+static bool handleIfNot(const QCString &);
+static bool handleElseIf(const QCString &);
+static bool handleElse(const QCString &);
+static bool handleEndIf(const QCString &);
+static bool handleIngroup(const QCString &);
+static bool handleNoSubGrouping(const QCString &);
+static bool handleShowInitializer(const QCString &);
+static bool handleHideInitializer(const QCString &);
+static bool handleCallgraph(const QCString &);
+static bool handleCallergraph(const QCString &);
+static bool handleInternal(const QCString &);
+static bool handleLineBr(const QCString &);
+static bool handleStatic(const QCString &);
+static bool handlePure(const QCString &);
+static bool handlePrivate(const QCString &);
+static bool handlePrivateSection(const QCString &);
+static bool handleProtected(const QCString &);
+static bool handleProtectedSection(const QCString &);
+static bool handlePublic(const QCString &s);
+static bool handlePublicSection(const QCString &s);
+static bool handleToc(const QCString &s);
+static bool handleInherit(const QCString &);
+static bool handleExtends(const QCString &);
+static bool handleCopyDoc(const QCString &);
+static bool handleCopyBrief(const QCString &);
+static bool handleCopyDetails(const QCString &);
+static bool handleParBlock(const QCString &);
+static bool handleEndParBlock(const QCString &);
+
+typedef bool (*DocCmdFunc)(const QCString &name);
+
+struct DocCmdMap
+{
+ const char *cmdName;
+ DocCmdFunc handler;
+ bool endsBrief;
+};
+
+// map of command to handler function
+static DocCmdMap docCmdMap[] =
+{
+ // command name handler function ends brief description
+ { "brief", &handleBrief, FALSE },
+ { "short", &handleBrief, FALSE },
+ { "fn", &handleFn, FALSE },
+ { "var", &handleFn, FALSE },
+ { "typedef", &handleFn, FALSE },
+ { "property", &handleFn, FALSE },
+ { "def", &handleDef, FALSE },
+ { "overload", &handleOverload, FALSE },
+ { "enum", &handleEnum, FALSE },
+ { "defgroup", &handleDefGroup, FALSE },
+ { "addtogroup", &handleAddToGroup, FALSE },
+ { "weakgroup", &handleWeakGroup, FALSE },
+ { "namespace", &handleNamespace, FALSE },
+ { "package", &handlePackage, FALSE },
+ { "class", &handleClass, FALSE },
+ { "headerfile", &handleHeaderFile, FALSE },
+ { "protocol", &handleProtocol, FALSE },
+ { "category", &handleCategory, FALSE },
+ { "union", &handleUnion, FALSE },
+ { "struct", &handleStruct, FALSE },
+ { "interface", &handleInterface, FALSE },
+ { "idlexcept", &handleIdlException, FALSE },
+ { "page", &handlePage, FALSE },
+ { "mainpage", &handleMainpage, FALSE },
+ { "file", &handleFile, FALSE },
+ { "dir", &handleDir, FALSE },
+ { "example", &handleExample, FALSE },
+ { "details", &handleDetails, TRUE },
+ { "name", &handleName, FALSE },
+ { "todo", &handleTodo, FALSE }, // end brief will be done differently
+ { "test", &handleTest, FALSE }, // end brief will be done differently
+ { "bug", &handleBug, FALSE }, // end brief will be done differently
+ { "deprecated", &handleDeprecated, FALSE }, // end brief will be done differently
+ { "xrefitem", &handleXRefItem, FALSE }, // end brief will be done differently
+ { "related", &handleRelated, TRUE },
+ { "relates", &handleRelated, TRUE },
+ { "relatedalso", &handleRelatedAlso, TRUE },
+ { "relatesalso", &handleRelatedAlso, TRUE },
+ { "parblock", &handleParBlock, TRUE },
+ { "endparblock", &handleEndParBlock, TRUE },
+ { "refitem", &handleRefItem, TRUE },
+ { "cite", &handleCite, FALSE },
+ { "subpage", &handleSubpage, TRUE },
+ { "section", &handleSection, TRUE },
+ { "subsection", &handleSection, TRUE },
+ { "subsubsection", &handleSection, TRUE },
+ { "paragraph", &handleSection, TRUE },
+ { "anchor", &handleAnchor, TRUE },
+ { "verbatim", &handleFormatBlock, TRUE },
+ { "latexonly", &handleFormatBlock, FALSE },
+ { "htmlonly", &handleFormatBlock, FALSE },
+ { "xmlonly", &handleFormatBlock, FALSE },
+ { "docbookonly", &handleFormatBlock, FALSE },
+ { "rtfonly", &handleFormatBlock, FALSE },
+ { "manonly", &handleFormatBlock, FALSE },
+ { "dot", &handleFormatBlock, TRUE },
+ { "msc", &handleFormatBlock, TRUE },
+ { "startuml", &handleFormatBlock, TRUE },
+ { "code", &handleFormatBlock, TRUE },
+ { "addindex", &handleAddIndex, FALSE },
+ { "if", &handleIf, FALSE },
+ { "ifnot", &handleIfNot, FALSE },
+ { "elseif", &handleElseIf, FALSE },
+ { "else", &handleElse, FALSE },
+ { "endif", &handleEndIf, FALSE },
+ { "ingroup", &handleIngroup, FALSE },
+ { "nosubgrouping", &handleNoSubGrouping, FALSE },
+ { "showinitializer", &handleShowInitializer, FALSE },
+ { "hideinitializer", &handleHideInitializer, FALSE },
+ { "callgraph", &handleCallgraph, FALSE },
+ { "callergraph", &handleCallergraph, FALSE },
+ { "internal", &handleInternal, TRUE },
+ { "_linebr", &handleLineBr, FALSE },
+ { "static", &handleStatic, FALSE },
+ { "pure", &handlePure, FALSE },
+ { "private", &handlePrivate, FALSE },
+ { "privatesection", &handlePrivateSection, FALSE },
+ { "protected", &handleProtected, FALSE },
+ { "protectedsection",&handleProtectedSection, FALSE },
+ { "public", &handlePublic, FALSE },
+ { "publicsection", &handlePublicSection, FALSE },
+ { "tableofcontents", &handleToc, FALSE },
+ { "inherit", &handleInherit, TRUE },
+ { "extends", &handleExtends, TRUE },
+ { "implements", &handleExtends, TRUE },
+ { "memberof", &handleMemberOf, TRUE },
+ { "arg", 0, TRUE },
+ { "attention", 0, TRUE },
+ { "author", 0, TRUE },
+ { "authors", 0, TRUE },
+ { "copydoc", &handleCopyDoc, TRUE },
+ { "copybrief", &handleCopyBrief, FALSE },
+ { "copydetails", &handleCopyDetails, TRUE },
+ { "copyright", 0, TRUE },
+ { "date", 0, TRUE },
+ { "dotfile", 0, TRUE },
+ { "htmlinclude", 0, FALSE },
+ { "image", 0, TRUE },
+ { "include", 0, TRUE },
+ { "includelineno", 0, TRUE },
+ { "invariant", 0, TRUE },
+ { "latexinclude", 0, FALSE },
+ { "li", 0, TRUE },
+ { "line", 0, TRUE },
+ { "note", 0, TRUE },
+ { "par", 0, TRUE },
+ { "param", 0, TRUE },
+ { "tparam", 0, TRUE },
+ { "post", 0, TRUE },
+ { "pre", 0, TRUE },
+ { "remark", 0, TRUE },
+ { "remarks", 0, TRUE },
+ { "result", 0, TRUE },
+ { "return", 0, TRUE },
+ { "returns", 0, TRUE },
+ { "retval", 0, TRUE },
+ { "sa", 0, TRUE },
+ { "see", 0, TRUE },
+ { "since", 0, TRUE },
+ { "throw", 0, TRUE },
+ { "throws", 0, TRUE },
+ { "until", 0, TRUE },
+ { "verbinclude", 0, FALSE },
+ { "version", 0, TRUE },
+ { "warning", 0, TRUE },
+ { 0, 0, FALSE }
+};
+
+/** @brief Command mapper.
+ *
+ * Maps a command name (as found in a comment block) onto a
+ * specific handler function.
+ */
+class DocCmdMapper
+{
+ public:
+ struct Cmd
+ {
+ DocCmdFunc func;
+ bool endsBrief;
+ };
+
+ /** maps a command name to a handler function */
+ static Cmd *map(const char *name)
+ {
+ return instance()->find(name);
+ }
+
+ /** release the singleton */
+ static void freeInstance()
+ {
+ delete s_instance; s_instance=0;
+ }
+
+ private:
+ static DocCmdMapper *instance()
+ {
+ if (s_instance==0) s_instance = new DocCmdMapper;
+ return s_instance;
+ }
+
+ DocCmdMapper() : m_map(113)
+ {
+ m_map.setAutoDelete(TRUE);
+ DocCmdMap *p = docCmdMap;
+ while (p->cmdName)
+ {
+ if (m_map.find(p->cmdName)!=0)
+ {
+ err("DocCmdMapper: command %s already added\n",p->cmdName);
+ exit(1);
+ }
+ Cmd *cmd = new Cmd;
+ cmd->func = p->handler;
+ cmd->endsBrief = p->endsBrief;
+ m_map.insert(p->cmdName,cmd);
+ p++;
+ }
+ }
+
+ Cmd *find(const char *name)
+ {
+ return m_map.find(name);
+ }
+ QDict<Cmd> m_map;
+ static DocCmdMapper *s_instance;
+};
+
+DocCmdMapper *DocCmdMapper::s_instance=0;
+
+bool inInternalDocs = FALSE;
+
+#define YY_NEVER_INTERACTIVE 1
+
+enum XRefKind
+{
+ XRef_Item,
+ XRef_Todo,
+ XRef_Test,
+ XRef_Bug,
+ XRef_Deprecated,
+ XRef_None
+};
+
+enum OutputContext
+{
+ OutputDoc,
+ OutputBrief,
+ OutputXRef,
+ OutputInbody
+};
+
+enum GuardType
+{
+ Guard_If,
+ Guard_IfNot,
+ Guard_Skip
+};
+
+class GuardedSection
+{
+ public:
+ GuardedSection(bool enabled,bool parentVisible)
+ : m_enabled(enabled),m_parentVisible(parentVisible) {}
+ bool isEnabled() const { return m_enabled; }
+ bool parentVisible() const { return m_parentVisible; }
+
+ private:
+ bool m_enabled;
+ bool m_parentVisible;
+};
+
+void openGroup(Entry *e,const char *file,int line);
+void closeGroup(Entry *e,const char *file,int line,bool foundInline=FALSE);
+void initGroupInfo(Entry *e);
+static void groupAddDocs(Entry *e,const char *fileName);
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+
+static ParserInterface *langParser; // the language parser that is calling us
+static QCString inputString; // input string
+static int inputPosition; // read pointer
+static QCString yyFileName; // file name that is read from
+static int yyLineNr; // line number in the input
+static bool inBody; // was the comment found inside the body of a function?
+static OutputContext inContext; // are we inside the brief, details or xref part
+static bool briefEndsAtDot; // does the brief description stop at a dot?
+static QCString formulaText; // Running text of a formula
+static QCString formulaEnv; // environment name
+static int formulaNewLines; // amount of new lines in the formula
+static QCString *pOutputString; // pointer to string to which the output is appended.
+static QCString outputXRef; // temp argument of todo/test/../xrefitem commands
+static QCString blockName; // preformatted block name (e.g. verbatim, latexonly,...)
+static XRefKind xrefKind; // kind of cross-reference command
+static XRefKind newXRefKind; //
+static GuardType guardType; // kind of guard for conditional section
+static bool enabledSectionFound;
+static QCString functionProto; // function prototype
+static QStack<GuardedSection> guards; // tracks nested conditional sections (if,ifnot,..)
+static Entry* current = 0 ; // working entry
+//static Entry* current_root = 0 ; // parent of working entry
+
+
+//static Entry* previous = 0 ; // TODO: remove need for this
+static bool needNewEntry;
+
+static QCString g_sectionLabel;
+static QCString g_sectionTitle;
+static int g_sectionLevel;
+static QCString xrefItemKey;
+static QCString newXRefItemKey;
+static QCString xrefItemTitle;
+static QCString xrefListTitle;
+static Protection protection;
+
+static bool xrefAppendFlag;
+static bool inGroupParamFound;
+static int braceCount;
+static bool insidePre;
+static bool parseMore;
+static int g_condCount;
+
+static int g_commentCount;
+static QCString g_spaceBeforeCmd;
+static QCString g_spaceBeforeIf;
+static QCString g_copyDocArg;
+
+static QCString g_guardExpr;
+static int g_roundCount;
+
+static bool g_insideParBlock;
+
+//-----------------------------------------------------------------------------
+
+static QStack<Grouping> g_autoGroupStack;
+static int g_memberGroupId = DOX_NOGROUP;
+static QCString g_memberGroupHeader;
+static QCString g_memberGroupDocs;
+static QCString g_memberGroupRelates;
+static QCString g_compoundName;
+
+//-----------------------------------------------------------------------------
+
+static void initParser()
+{
+ g_sectionLabel.resize(0);
+ g_sectionTitle.resize(0);
+ g_memberGroupHeader.resize(0);
+ g_insideParBlock = FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+static bool getDocSectionName(int s)
+{
+ switch(s)
+ {
+ case Entry::CLASSDOC_SEC:
+ case Entry::STRUCTDOC_SEC:
+ case Entry::UNIONDOC_SEC:
+ case Entry::EXCEPTIONDOC_SEC:
+ case Entry::NAMESPACEDOC_SEC:
+ case Entry::PROTOCOLDOC_SEC:
+ case Entry::CATEGORYDOC_SEC:
+ case Entry::ENUMDOC_SEC:
+ case Entry::PAGEDOC_SEC:
+ case Entry::VARIABLEDOC_SEC:
+ case Entry::MEMBERDOC_SEC:
+ case Entry::OVERLOADDOC_SEC:
+ case Entry::FILEDOC_SEC:
+ case Entry::DEFINEDOC_SEC:
+ case Entry::GROUPDOC_SEC:
+ case Entry::MAINPAGEDOC_SEC:
+ case Entry::PACKAGEDOC_SEC:
+ case Entry::DIRDOC_SEC:
+ case Entry::EXAMPLE_SEC:
+ case Entry::MEMBERGRP_SEC:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+static bool makeStructuralIndicator(Entry::Sections s)
+{
+ //printf("current->section=%x\n",current->section);
+ if (getDocSectionName(current->section))
+ {
+ return TRUE;
+ }
+ else
+ {
+ needNewEntry = TRUE;
+ current->section = s;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ return FALSE;
+ }
+}
+
+static void lineCount()
+{
+ for( const char* c = yytext ; *c ; ++c )
+ yyLineNr += (*c == '\n') ;
+}
+
+
+static QCString stripQuotes(const char *s)
+{
+ QCString name;
+ if (s==0 || *s==0) return name;
+ name=s;
+ if (name.at(0)=='"' && name.at(name.length()-1)=='"')
+ {
+ name=name.mid(1,name.length()-2);
+ }
+ return name;
+}
+
+//-----------------------------------------------------------------
+
+static void addXRefItem(const char *listName,const char *itemTitle,
+ const char *listTitle,bool append)
+{
+ Entry *docEntry = current; // inBody && previous ? previous : current;
+ if (listName==0) return;
+ //printf("addXRefItem(%s,%s,%s,%d)\n",listName,itemTitle,listTitle,append);
+
+ ListItemInfo *lii=0;
+ RefList *refList = Doxygen::xrefLists->find(listName);
+ if (refList==0) // new list
+ {
+ refList = new RefList(listName,listTitle,itemTitle);
+ Doxygen::xrefLists->insert(listName,refList);
+ //printf("new list!\n");
+ }
+ if (docEntry->sli)
+ {
+ QListIterator<ListItemInfo> slii(*docEntry->sli);
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ if (qstrcmp(lii->type,listName)==0)
+ {
+ //printf("found %s lii->type=%s\n",listName,lii->type);
+ break;
+ }
+ }
+ }
+ if (lii && append) // already found item of same type just before this one
+ {
+ //printf("listName=%s item id = %d existing\n",listName,lii->itemId);
+ RefItem *item = refList->getRefItem(lii->itemId);
+ ASSERT(item!=0);
+ item->text += " <p>";
+ if (Doxygen::markdownSupport)
+ {
+ item->text += processMarkdown(yyFileName,yyLineNr,current,outputXRef);
+ }
+ else
+ {
+ item->text += outputXRef;
+ }
+ //printf("%s: text +=%s\n",listName,item->text.data());
+ }
+ else // new item
+ {
+ int itemId = refList->addRefItem();
+ //printf("listName=%s item id = %d new current=%p\n",listName,itemId,current);
+
+ // if we have already an item from the same list type (e.g. a second @todo)
+ // in the same Entry (i.e. lii!=0) then we reuse its link anchor.
+ char anchorLabel[1024];
+ //sprintf(anchorLabel,"_%s%06d",listName,lii ? lii->itemId : itemId);
+ sprintf(anchorLabel,"_%s%06d",listName,itemId);
+ RefItem *item = refList->getRefItem(itemId);
+ ASSERT(item!=0);
+ if (Doxygen::markdownSupport)
+ {
+ item->text = processMarkdown(yyFileName,yyLineNr,current,outputXRef);
+ }
+ else
+ {
+ item->text = outputXRef;
+ }
+ item->listAnchor = anchorLabel;
+ docEntry->addSpecialListItem(listName,itemId);
+ QCString cmdString;
+ cmdString.sprintf("\\xrefitem %s %d.",listName,itemId);
+ if (inBody)
+ {
+ docEntry->inbodyDocs += cmdString;
+ }
+ else
+ {
+ docEntry->doc += cmdString;
+ }
+ SectionInfo *si = Doxygen::sectionDict->find(anchorLabel);
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(listName,yyLineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",anchorLabel,si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(listName,yyLineNr,"multiple use of section label '%s', (first occurrence: %s)",anchorLabel,si->fileName.data());
+ }
+ }
+ else
+ {
+ si=new SectionInfo(listName,yyLineNr,anchorLabel,
+ g_sectionTitle,SectionInfo::Anchor,
+ g_sectionLevel);
+ Doxygen::sectionDict->append(anchorLabel,si);
+ docEntry->anchors->append(si);
+ }
+ }
+ outputXRef.resize(0);
+}
+
+//-----------------------------------------------------------------------------
+
+// Adds a formula text to the list/dictionary of formulas if it was
+// not already added. Returns the label of the formula.
+static QCString addFormula()
+{
+ QCString formLabel;
+ QCString fText=formulaText.simplifyWhiteSpace();
+ Formula *f=0;
+ if ((f=Doxygen::formulaDict->find(fText))==0)
+ {
+ f = new Formula(fText);
+ Doxygen::formulaList->append(f);
+ Doxygen::formulaDict->insert(fText,f);
+ formLabel.sprintf("\\form#%d",f->getId());
+ Doxygen::formulaNameDict->insert(formLabel,f);
+ }
+ else
+ {
+ formLabel.sprintf("\\form#%d",f->getId());
+ }
+ int i;
+ for (i=0;i<formulaNewLines;i++) formLabel+="@_fakenl"; // add fake newlines to
+ // keep the warnings
+ // correctly aligned.
+ return formLabel;
+}
+
+//-----------------------------------------------------------------------------
+
+static void checkFormula();
+//-----------------------------------------------------------------------------
+
+static SectionInfo::SectionType sectionLevelToType(int level)
+{
+ if (level>=0 && level<5) return (SectionInfo::SectionType)level;
+ return SectionInfo::Anchor;
+}
+
+static void addSection()
+{
+ SectionInfo *si = Doxygen::sectionDict->find(g_sectionLabel);
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s, line %d)",g_sectionLabel.data(),si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding section, (first occurrence: %s)",g_sectionLabel.data(),si->fileName.data());
+ }
+ }
+ else
+ {
+ // create a new section element
+ g_sectionTitle+=yytext;
+ g_sectionTitle=g_sectionTitle.stripWhiteSpace();
+ si = new SectionInfo(yyFileName,yyLineNr,g_sectionLabel,
+ g_sectionTitle,sectionLevelToType(g_sectionLevel),g_sectionLevel);
+
+ // add section to this entry
+ current->anchors->append(si);
+
+ // add section to the global dictionary
+ Doxygen::sectionDict->append(g_sectionLabel,si);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+static void addCite()
+{
+ Doxygen::citeDict->insert(yytext);
+}
+
+//-----------------------------------------------------------------------------
+
+// strip trailing whitespace (excluding newlines) from string s
+static void stripTrailingWhiteSpace(QCString &s)
+{
+ uint len = s.length();
+ int i = (int)len-1;
+ char c;
+ while (i>=0 && ((c = s.at(i))==' ' || c=='\t' || c=='\r')) i--;
+ if (i!=(int)len-1)
+ {
+ s.resize(i+2); // string up to and including char at pos i and \0 terminator
+ }
+}
+
+// selects the output to write to
+static inline void setOutput(OutputContext ctx)
+{
+ bool xrefAppendToPrev = xrefAppendFlag;
+ // determine append flag for the next item (i.e. the end of this item)
+ xrefAppendFlag = !inBody &&
+ inContext==OutputXRef && ctx==OutputXRef && // two consecutive xref items
+ newXRefKind==xrefKind && // of the same kind
+ (xrefKind!=XRef_Item ||
+ newXRefItemKey==xrefItemKey); // with the same key if \xrefitem
+ //printf("%d && %d && %d && (%d || %d)\n",
+ // inContext==OutputXRef,
+ // ctx==OutputXRef,
+ // newXRefKind==xrefKind,
+ // xrefKind!=XRef_Item,
+ // newXRefItemKey==xrefItemKey);
+
+ //printf("refKind=%d newXRefKind=%d xrefAppendToPrev=%d xrefAppendFlag=%d\n",
+ // xrefKind,newXRefKind,xrefAppendToPrev,xrefAppendFlag);
+
+ //printf("setOutput(inContext=%d ctx=%d)\n",inContext,ctx);
+ if (inContext==OutputXRef) // end of XRef section => add the item
+ {
+ // See if we can append this new xref item to the previous one.
+ // We know this at the start of the next item of the same
+ // type and need to remember this until the end of that item.
+ switch(xrefKind)
+ {
+ case XRef_Todo:
+ addXRefItem("todo",
+ theTranslator->trTodo(),
+ theTranslator->trTodoList(),
+ xrefAppendToPrev
+ );
+ break;
+ case XRef_Test:
+ addXRefItem("test",
+ theTranslator->trTest(),
+ theTranslator->trTestList(),
+ xrefAppendToPrev
+ );
+ break;
+ case XRef_Bug:
+ addXRefItem("bug",
+ theTranslator->trBug(),
+ theTranslator->trBugList(),
+ xrefAppendToPrev
+ );
+ break;
+ case XRef_Deprecated:
+ addXRefItem("deprecated",
+ theTranslator->trDeprecated(),
+ theTranslator->trDeprecatedList(),
+ xrefAppendToPrev
+ );
+ break;
+ case XRef_Item: // user defined list
+ addXRefItem(xrefItemKey,
+ xrefItemTitle,
+ xrefListTitle,
+ xrefAppendToPrev
+ );
+ break;
+ case XRef_None:
+ ASSERT(0);
+ break;
+ }
+ }
+ xrefItemKey = newXRefItemKey;
+
+ int oldContext = inContext;
+ inContext = ctx;
+ if (inContext!=OutputXRef && inBody) inContext=OutputInbody;
+ switch(inContext)
+ {
+ case OutputDoc:
+ if (oldContext!=inContext)
+ {
+ stripTrailingWhiteSpace(current->doc);
+ if (current->docFile.isEmpty())
+ {
+ current->docFile = yyFileName;
+ current->docLine = yyLineNr;
+ }
+ }
+ pOutputString = ¤t->doc;
+ break;
+ case OutputBrief:
+ if (oldContext!=inContext)
+ {
+ if (current->briefFile.isEmpty())
+ {
+ current->briefFile = yyFileName;
+ current->briefLine = yyLineNr;
+ }
+ }
+ if (current->brief.stripWhiteSpace().isEmpty()) // we only want one brief
+ // description even if multiple
+ // are given...
+ {
+ pOutputString = ¤t->brief;
+ }
+ else
+ {
+ pOutputString = ¤t->doc;
+ inContext = OutputDoc; // need to switch to detailed docs, see bug 631380
+ }
+ break;
+ case OutputXRef:
+ pOutputString = &outputXRef;
+ // first item found, so can't append to previous
+ //xrefAppendFlag = FALSE;
+ break;
+ case OutputInbody:
+ pOutputString = ¤t->inbodyDocs;
+ break;
+ }
+}
+
+// add a string to the output
+static inline void addOutput(const char *s)
+{
+ //printf("addOutput(%s)\n",s);
+ *pOutputString+=s;
+}
+
+// add a character to the output
+static inline void addOutput(char c)
+{
+ *pOutputString+=c;
+}
+
+static void endBrief(bool addToOutput=TRUE)
+{
+ if (!current->brief.stripWhiteSpace().isEmpty())
+ { // only go to the detailed description if we have
+ // found some brief description and not just whitespace
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ if (addToOutput) addOutput(yytext);
+ }
+}
+
+static void handleGuard(const QCString &expr);
+/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int prevPosition=0;
+
+static int yyread(char *buf,int max_size)
+{
+ prevPosition=inputPosition;
+ int c=0;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ //printf("%d (%c)\n",*buf,*buf);
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+ /* start command character */
+CMD ("\\"|"@")
+DCMD1 ("arg"|"attention"|"author"|"cite"|"code")
+DCMD2 ("date"|"dot"|"msc"|"dotfile"|"example"|"startuml")
+DCMD3 ("htmlinclude"|"htmlonly"|"image"|"include")
+DCMD4 ("includelineno"|"internal"|"invariant")
+DCMD5 ("latexinclude"|"latexonly"|"li"|"line"|"manonly"|"name")
+DCMD6 ("note"|"par"|"paragraph"|"param"|"post")
+DCMD7 ("pre"|"remarks"|(("relate"[sd])("also")?))
+DCMD8 ("remarks"|("return"[s]?)|"retval"|"sa"|"section")
+DCMD9 ("see"|"since"|"subsection"|"subsubsection")
+DCMD10 ("throw"|"until"|"verbatim")
+DCMD11 ("verbinclude"|"version"|"warning")
+DETAILEDCMD {CMD}({DCMD1}|{DCMD2}|{DCMD3}|{DCMD4}|{DCMD5}|{DCMD6}|{DCMD7}|{DCMD8}|{DCMD9}|{DCMD10}|{DCMD11})
+XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem")
+PRE [pP][rR][eE]
+TABLE [tT][aA][bB][lL][eE]
+P [pP]
+UL [uU][lL]
+OL [oO][lL]
+DL [dD][lL]
+IMG [iI][mM][gG]
+HR [hH][rR]
+PARA [pP][aA][rR][aA]
+CODE [cC][oO][dD][eE]
+DETAILEDHTML {PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA}
+DETAILEDHTMLOPT {CODE}
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
+ATTR ({B}+[^>\n]*)?
+DOCNL "\n"|"\\_linebr"
+LC "\\"{B}*"\n"
+NW [^a-z_A-Z0-9]
+FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+@&#]
+FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+@&#]
+FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]*"\"")
+ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
+CITESCHAR [a-z_A-Z\x80-\xFF]
+CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/]*
+CITEID {CITESCHAR}*{CITEECHAR}+("."{CITESCHAR}*{CITEECHAR}+)*
+SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
+SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID})
+TMPLSPEC "<"{BN}*[^>]+{BN}*">"
+MAILADDR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+
+RCSTAG "$"{ID}":"[^\n$]+"$"
+
+%option noyywrap
+
+ /* comment parsing states. */
+%x Comment
+%x PageDocArg1
+%x PageDocArg2
+%x RelatesParam1
+%x ClassDocArg1
+%x ClassDocArg2
+%x ClassDocArg3
+%x CategoryDocArg1
+%x XRefItemParam1
+%x XRefItemParam2
+%x XRefItemParam3
+%x FileDocArg1
+%x EnumDocArg1
+%x NameSpaceDocArg1
+%x PackageDocArg1
+%x GroupDocArg1
+%x GroupDocArg2
+%x SectionLabel
+%x SectionTitle
+%x SubpageLabel
+%x SubpageTitle
+%x FormatBlock
+%x LineParam
+%x GuardParam
+%x GuardParamEnd
+%x SkipGuardedSection
+%x SkipInternal
+%x NameParam
+%x InGroupParam
+%x FnParam
+%x OverloadParam
+%x InheritParam
+%x ExtendsParam
+%x ReadFormulaShort
+%x ReadFormulaLong
+%x AnchorLabel
+%x HtmlComment
+%x SkipLang
+%x CiteLabel
+%x CopyDoc
+%x GuardExpr
+
+%%
+
+ /* What can happen in while parsing a comment block:
+ * commands (e.g. @page, or \page)
+ * escaped commands (e.g. @@page or \\page).
+ * formulas (e.g. \f$ \f[ \f{..)
+ * directories (e.g. \doxygen\src\)
+ * autolist end. (e.g. a dot on an otherwise empty line)
+ * newlines.
+ * end of brief description due to blank line.
+ * end of brief description due to some command (@command, or <command>).
+ * words and whitespace and other characters (#,?!, etc).
+ * grouping commands (e.g. @{ and @})
+ * language switch (e.g. \~english or \~).
+ * mail address (e.g. dimitri at stack.nl).
+ * quoted text, such as "foo at bar"
+ * XML commands, <summary></summary><remarks></remarks>
+ */
+
+<Comment>{CMD}{CMD}[a-z_A-Z]+{B}* { // escaped command
+ addOutput(yytext);
+ }
+<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
+ addOutput(yytext);
+ }
+<Comment>{MAILADDR} { // mail address
+ addOutput(yytext);
+ }
+<Comment>"\""[^"\n]*"\"" { // quoted text
+ addOutput(yytext);
+ }
+<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
+ addOutput(yytext);
+ }
+<Comment>{XREFCMD}/[^a-z_A-Z]* { // xref command
+ if (inContext!=OutputXRef)
+ {
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ }
+ // continue with the same input
+ REJECT;
+ }
+ /*
+<Comment>{DETAILEDCMD}/[^a-z_A-Z]* { // command that can end a brief description
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ // continue with the same input
+ REJECT;
+ }
+ */
+<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
+ setOutput(OutputDoc);
+ // continue with the same input
+ REJECT;
+ }
+<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML command that ends a brief description
+ if (current->lang==SrcLangExt_CSharp)
+ {
+ setOutput(OutputDoc);
+ }
+ // continue with the same input
+ REJECT;
+ }
+<Comment>"<summary>" { // start of a .NET XML style brief description
+ setOutput(OutputBrief);
+ addOutput(yytext);
+ }
+<Comment>"<remarks>" { // start of a .NET XML style detailed description
+ setOutput(OutputDoc);
+ addOutput(yytext);
+ }
+<Comment>"</summary>" { // start of a .NET XML style detailed description
+ addOutput(yytext);
+ setOutput(OutputDoc);
+ }
+<Comment>"</remarks>" { // end of a brief or detailed description
+ addOutput(yytext);
+ }
+<Comment>"<"{PRE}{ATTR}">" {
+ insidePre=TRUE;
+ addOutput(yytext);
+ }
+<Comment>"</"{PRE}">" {
+ insidePre=FALSE;
+ addOutput(yytext);
+ }
+<Comment>{RCSTAG} { // RCS tag which end a brief description
+ setOutput(OutputDoc);
+ REJECT;
+ }
+<Comment>"<!--" {
+ BEGIN(HtmlComment);
+ }
+<Comment>{B}*{CMD}"endinternal"{B}* {
+ addOutput("\\endinternal ");
+ if (!inInternalDocs)
+ warn(yyFileName,yyLineNr,
+ "found \\endinternal without matching \\internal"
+ );
+ inInternalDocs = FALSE;
+ }
+<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
+ // the {B}* in the front was added for bug620924
+ QCString cmdName = QCString(yytext).stripWhiteSpace().data()+1;
+ DocCmdMapper::Cmd *cmdPtr = DocCmdMapper::map(cmdName);
+ if (cmdPtr) // special action is required
+ {
+ int i=0;
+ while (yytext[i]==' ' || yytext[i]=='\t') i++;
+ g_spaceBeforeCmd = QCString(yytext).left(i);
+ if (cmdPtr->endsBrief && inContext!=OutputXRef)
+ {
+ briefEndsAtDot=FALSE;
+ // this command forces the end of brief description
+ setOutput(OutputDoc);
+ }
+ //if (i>0) addOutput(QCString(yytext).left(i)); // removed for bug 689341
+ if (cmdPtr->func && cmdPtr->func(cmdName))
+ {
+ // implicit split of the comment block into two
+ // entries. Restart the next block at the start
+ // of this command.
+ parseMore=TRUE;
+
+ // yuk, this is probably not very portable across lex implementations,
+ // but we need to know the position in the input buffer where this
+ // rule matched.
+ // for flex 2.5.33+ we should use YY_CURRENT_BUFFER_LVALUE
+#if YY_FLEX_MINOR_VERSION>=5 && YY_FLEX_SUBMINOR_VERSION>=33
+ inputPosition=prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
+#else
+ inputPosition=prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf);
+#endif
+ yyterminate();
+ }
+ else if (cmdPtr->func==0)
+ {
+ // command without handler, to be processed
+ // later by parsedoc.cpp
+ addOutput(yytext);
+ }
+ }
+ else // command not relevant
+ {
+ addOutput(yytext);
+ }
+ }
+<Comment>{B}*("\\\\"|"@@")"f"[$\[{] { // escaped formula command
+ addOutput(yytext);
+ }
+<Comment>{B}*{CMD}"~"[a-z_A-Z]* { // language switch command
+ QCString langId = QString(yytext).stripWhiteSpace().data()+2;
+ if (!langId.isEmpty() &&
+ qstricmp(Config_getEnum("OUTPUT_LANGUAGE"),langId)!=0)
+ { // enable language specific section
+ BEGIN(SkipLang);
+ }
+ }
+<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
+ formulaText="\\begin";
+ formulaEnv=QString(yytext).stripWhiteSpace().data()+2;
+ if (formulaEnv.at(formulaEnv.length()-1)=='{')
+ {
+ // remove trailing open brace
+ formulaEnv=formulaEnv.left(formulaEnv.length()-1);
+ }
+ formulaText+=formulaEnv;
+ formulaNewLines=0;
+ BEGIN(ReadFormulaLong);
+ }
+<Comment>{B}*{CMD}"f$" { // start of a inline formula
+ formulaText="$";
+ formulaNewLines=0;
+ BEGIN(ReadFormulaShort);
+ }
+<Comment>{B}*{CMD}"f[" { // start of a block formula
+ formulaText="\\[";
+ formulaNewLines=0;
+ BEGIN(ReadFormulaLong);
+ }
+<Comment>{B}*{CMD}"{" { // begin of a group
+ //langParser->handleGroupStartCommand(g_memberGroupHeader);
+ openGroup(current,yyFileName,yyLineNr);
+ }
+<Comment>{B}*{CMD}"}" { // end of a group
+ //langParser->handleGroupEndCommand();
+ closeGroup(current,yyFileName,yyLineNr,TRUE);
+ g_memberGroupHeader.resize(0);
+ parseMore=TRUE;
+ needNewEntry = TRUE;
+#if YY_FLEX_MINOR_VERSION>=5 && YY_FLEX_SUBMINOR_VERSION>=33
+ inputPosition=prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + strlen(yytext);
+#else
+ inputPosition=prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf) + strlen(yytext);
+#endif
+ yyterminate();
+ }
+<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
+ addOutput(yytext);
+ }
+<Comment>[a-z_A-Z]+ { // normal word
+ addOutput(yytext);
+ }
+<Comment>^{B}*"."{B}*/\n { // explicit end autolist: e.g " ."
+ addOutput(yytext);
+ }
+<Comment>^{B}*[1-9][0-9]*"."{B}+ |
+<Comment>^{B}*[*+]{B}+ { // start of autolist
+ if (!Doxygen::markdownSupport)
+ {
+ REJECT;
+ }
+ else
+ {
+ if (inContext!=OutputXRef)
+ {
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ }
+ addOutput(yytext);
+ }
+ }
+<Comment>^{B}*"-"{B}+ { // start of autolist
+ if (inContext!=OutputXRef)
+ {
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ }
+ addOutput(yytext);
+ }
+<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{B}*/\n { // horizontal line (dashed)
+ addOutput(yytext);
+ }
+<Comment>{CMD}"---" { // escaped mdash
+ addOutput(yytext);
+ }
+<Comment>{CMD}"--" { // escaped mdash
+ addOutput(yytext);
+ }
+<Comment>"---" { // mdash
+ addOutput(insidePre || Doxygen::markdownSupport ? yytext : "—");
+ }
+<Comment>"--" { // ndash
+ addOutput(insidePre || Doxygen::markdownSupport ? yytext : "–");
+ }
+<Comment>"-#"{B}+ { // numbered item
+ addOutput(yytext);
+ }
+<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
+ addOutput(yytext);
+ }
+<Comment>".\\"[ \t] { // . with escaped space.
+ addOutput(yytext[0]);
+ addOutput(yytext[2]);
+ }
+<Comment>".," { // . with comma such as "e.g.,"
+ addOutput(yytext);
+ }
+<Comment>"...\\"[ \t] { // ellipsis with escaped space.
+ addOutput("... ");
+ }
+<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
+ addOutput(yytext);
+ }
+<Comment>(\n|\\_linebr)({B}*(\n|\\_linebr))+ { // at least one blank line (or blank line command)
+ if (inContext==OutputXRef)
+ {
+ // see bug 613024, we need to put the newlines after ending the XRef section.
+ if (!g_insideParBlock) setOutput(OutputDoc);
+ int i;
+ for (i=0;i<yyleng;)
+ {
+ if (yytext[i]=='\n') addOutput('\n'),i++;
+ else if (strcmp(yytext+i,"\\_linebr")==0) addOutput('\n'),i+=8;
+ else i++;
+ }
+ }
+ else if (inContext!=OutputBrief)
+ {
+ int i;
+ for (i=0;i<yyleng;)
+ {
+ if (yytext[i]=='\n') addOutput('\n'),i++;
+ else if (strcmp(yytext+i,"\\_linebr")==0) addOutput('\n'),i+=8;
+ else i++;
+ }
+ setOutput(OutputDoc);
+ }
+ else // inContext==OutputBrief
+ { // only go to the detailed description if we have
+ // found some brief description and not just whitespace
+ endBrief(FALSE);
+ }
+ lineCount();
+ }
+<Comment>"." { // potential end of a JavaDoc style comment
+ addOutput(*yytext);
+ if (briefEndsAtDot)
+ {
+ setOutput(OutputDoc);
+ briefEndsAtDot=FALSE;
+ }
+ }
+<Comment>\n { // newline
+ addOutput(*yytext);
+ yyLineNr++;
+ }
+<Comment>. { // catch-all for anything else
+ addOutput(*yytext);
+ }
+
+
+ /* -------------- Rules for handling HTML comments ----------- */
+
+<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
+<HtmlComment>{DOCNL} {
+ if (*yytext=='\n') yyLineNr++;
+ }
+<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
+ }
+<HtmlComment>. { // ignore every else
+ }
+
+ /* -------------- Rules for handling formulas ---------------- */
+
+<ReadFormulaShort>{CMD}"f$" { // end of inline formula
+ formulaText+="$";
+ addOutput(" "+addFormula());
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f]" { // end of block formula
+ formulaText+="\\]";
+ addOutput(" "+addFormula());
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
+ formulaText+="\\end";
+ formulaText+=formulaEnv;
+ addOutput(" "+addFormula());
+ BEGIN(Comment);
+ }
+<ReadFormulaLong,ReadFormulaShort>[^\\@\n]+ { // any non-special character
+ formulaText+=yytext;
+ }
+<ReadFormulaLong,ReadFormulaShort>\n { // new line
+ formulaNewLines++;
+ formulaText+=*yytext;
+ yyLineNr++;
+ }
+<ReadFormulaLong,ReadFormulaShort>. { // any othe character
+ formulaText+=*yytext;
+ }
+
+ /* ------------ handle argument of enum command --------------- */
+
+<EnumDocArg1>{SCOPEID} { // handle argument
+ current->name = yytext;
+ BEGIN( Comment );
+ }
+<EnumDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<EnumDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "missing argument after \\enum."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<EnumDocArg1>. { // ignore other stuff
+ }
+
+ /* ------------ handle argument of namespace command --------------- */
+
+<NameSpaceDocArg1>{SCOPENAME} { // handle argument
+ current->name = substitute(yytext,".","::");
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<NameSpaceDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "missing argument after "
+ "\\namespace."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>. { // ignore other stuff
+ }
+
+ /* ------------ handle argument of package command --------------- */
+
+<PackageDocArg1>{ID}("."{ID})* { // handle argument
+ current->name = yytext;
+ BEGIN( Comment );
+ }
+<PackageDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<PackageDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "missing argument after "
+ "\\package."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<PackageDocArg1>. { // ignore other stuff
+ }
+
+ /* ------ handle argument of class/struct/union command --------------- */
+
+<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
+ current->name = substitute(removeRedundantWhiteSpace(yytext),".","::");
+ BEGIN( ClassDocArg2 );
+ }
+<ClassDocArg1>{SCOPENAME} { // first argument
+ current->name = substitute(yytext,".","::");
+ if (current->section==Entry::PROTOCOLDOC_SEC)
+ {
+ current->name+="-p";
+ }
+ // prepend outer scope name
+ BEGIN( ClassDocArg2 );
+ }
+<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
+ current->name = substitute(yytext,".","::");
+ BEGIN( ClassDocArg2 );
+ }
+<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg1,CategoryDocArg1>{DOCNL} {
+ warn(yyFileName,yyLineNr,
+ "missing argument after "
+ "\\%s.",YY_START==ClassDocArg1?"class":"category"
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
+ }
+
+<ClassDocArg2>{FILE}|"<>" { // second argument; include file
+ current->includeFile = yytext;
+ BEGIN( ClassDocArg3 );
+ }
+<ClassDocArg2>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg2>{DOCNL} {
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg2>. { // ignore other stuff
+ }
+
+<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
+ current->includeName = yytext;
+ BEGIN( Comment );
+ }
+<ClassDocArg3>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg3>{DOCNL} {
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg3>. { // ignore other stuff
+ }
+
+ /* --------- handle arguments of {def,add,weak}group commands --------- */
+
+<GroupDocArg1>{LABELID}(".html"?) { // group name
+ current->name = yytext;
+ //lastDefGroup.groupname = yytext;
+ //lastDefGroup.pri = current->groupingPri();
+ // the .html stuff is for Qt compatibility
+ if (current->name.right(5)==".html")
+ {
+ current->name=current->name.left(current->name.length()-5);
+ }
+ current->type.resize(0);
+ BEGIN(GroupDocArg2);
+ }
+<GroupDocArg1>"\\"{B}*"\n" { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GroupDocArg1>{DOCNL} { // missing argument!
+ warn(yyFileName,yyLineNr,
+ "missing group name after %s",
+ current->groupDocCmd()
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<GroupDocArg2>"\\"{B}*"\n" { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GroupDocArg2>[^\n\\\*]+ { // title (stored in type)
+ current->type += yytext;
+ current->type = current->type.stripWhiteSpace();
+ }
+<GroupDocArg2>{DOCNL} {
+ if ( current->groupDocType==Entry::GROUPDOC_NORMAL &&
+ current->type.isEmpty()
+ ) // defgroup requires second argument
+ {
+ warn(yyFileName,yyLineNr,
+ "missing title after "
+ "\\defgroup %s", current->name.data()
+ );
+ }
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+
+ /* --------- handle arguments of page/mainpage command ------------------- */
+
+<PageDocArg1>{FILE} { // first argument; page name
+ current->name = stripQuotes(yytext);
+ BEGIN( PageDocArg2 );
+ }
+<PageDocArg1>{LC} { yyLineNr++;
+ addOutput('\n');
+ }
+<PageDocArg1>{DOCNL} {
+ warn(yyFileName,yyLineNr,
+ "missing argument after "
+ "\\page."
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<PageDocArg1>. { // ignore other stuff
+ }
+<PageDocArg2>.*"\n" { // second argument; page title
+ yyLineNr++;
+ current->args = yytext;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+
+ /* --------- handle arguments of the file/dir/example command ------------ */
+
+<FileDocArg1>{DOCNL} { // no file name specfied
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<FileDocArg1>{FILE} { // first argument; name
+ current->name = stripQuotes(yytext);
+ BEGIN( Comment );
+ }
+<FileDocArg1>{LC} { yyLineNr++;
+ addOutput('\n');
+ }
+<FileDocArg1>. { // ignore other stuff
+ }
+
+ /* --------- handle arguments of the xrefitem command ------------ */
+
+<XRefItemParam1>{LABELID} { // first argument
+ newXRefItemKey=yytext;
+ setOutput(OutputXRef);
+ BEGIN(XRefItemParam2);
+ }
+<XRefItemParam1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam1>{DOCNL} { // missing arguments
+ warn(yyFileName,yyLineNr,
+ "Missing first argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam1>. { // ignore other stuff
+ }
+
+<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
+ xrefItemTitle = stripQuotes(yytext);
+ BEGIN(XRefItemParam3);
+ }
+<XRefItemParam2>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam2>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Missing second argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam2>. { // ignore other stuff
+ }
+
+<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
+ xrefListTitle = stripQuotes(yytext);
+ xrefKind = XRef_Item;
+ BEGIN( Comment );
+ }
+<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam3>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Missing third argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam3>. { // ignore other stuff
+ }
+
+
+ /* ----- handle arguments of the relates(also)/memberof command ------- */
+
+<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
+ current->relates = yytext;
+ //if (current->mGrpId!=DOX_NOGROUP)
+ //{
+ // memberGroupRelates = yytext;
+ //}
+ BEGIN( Comment );
+ }
+<RelatesParam1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<RelatesParam1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Missing argument of \\relates or \\memberof command"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<RelatesParam1>. { // ignore other stuff
+ }
+
+
+ /* ----- handle arguments of the relates(also)/addindex commands ----- */
+
+<LineParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<LineParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<LineParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+
+ /* ----- handle arguments of the section/subsection/.. commands ------- */
+
+<SectionLabel>{LABELID} { // first argyment
+ g_sectionLabel=yytext;
+ addOutput(yytext);
+ g_sectionTitle.resize(0);
+ BEGIN(SectionTitle);
+ }
+<SectionLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\section command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<SectionLabel>. { // invalid character for section label
+ warn(yyFileName,yyLineNr,
+ "Invalid or missing section label"
+ );
+ BEGIN(Comment);
+ }
+<SectionTitle>[^\n@\\*]*/"\n" { // end of section title
+ addSection();
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>[^\n@\\]*/"\\_linebr" { // end of section title
+ addSection();
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<SectionTitle>[^\n@\\]* { // any character without special meaning
+ g_sectionTitle+=yytext;
+ addOutput(yytext);
+ }
+<SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command
+ g_sectionTitle+=&yytext[1];
+ addOutput(yytext);
+ }
+<SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character
+ g_sectionTitle+=yytext[1];
+ addOutput(yytext);
+ }
+<SectionTitle>. { // anything else
+ g_sectionTitle+=yytext;
+ addOutput(*yytext);
+ }
+
+ /* ----- handle arguments of the subpage command ------- */
+
+<SubpageLabel>{LABELID} { // first argument
+ addOutput(yytext);
+ // we add subpage labels as a kind of "inheritance" relation to prevent
+ // needing to add another list to the Entry class.
+ current->extends->append(new BaseInfo(yytext,Public,Normal));
+ BEGIN(SubpageTitle);
+ }
+<SubpageLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\subpage command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<SubpageTitle>{DOCNL} { // no title, end command
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SubpageTitle>. { // no title, end of command
+ unput(*yytext);
+ BEGIN( Comment );
+ }
+
+ /* ----- handle arguments of the anchor command ------- */
+
+<AnchorLabel>{LABELID} { // found argument
+ SectionInfo *si = Doxygen::sectionDict->find(yytext);
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s, line %d)",yytext,si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,"multiple use of section label '%s' while adding anchor, (first occurrence: %s)",yytext,si->fileName.data());
+ }
+ }
+ else
+ {
+ si = new SectionInfo(yyFileName,yyLineNr,yytext,0,SectionInfo::Anchor,0);
+ Doxygen::sectionDict->append(yytext,si);
+ current->anchors->append(si);
+ }
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<AnchorLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\anchor command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<AnchorLabel>. { // invalid character for anchor label
+ warn(yyFileName,yyLineNr,
+ "Invalid or missing anchor label"
+ );
+ BEGIN(Comment);
+ }
+
+
+ /* ----- handle arguments of the preformatted block commands ------- */
+
+<FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endmsc"|"endvhdlflow")/{NW} { // possible ends
+ addOutput(yytext);
+ if (&yytext[4]==blockName) // found end of the block
+ {
+ BEGIN(Comment);
+ }
+ }
+<FormatBlock>{CMD}"enduml" {
+ addOutput(yytext);
+ if (blockName=="startuml") // found end of the block
+ {
+ BEGIN(Comment);
+ }
+ }
+<FormatBlock>[^ \@\*\/\\\n]* { // some word
+ addOutput(yytext);
+ }
+<FormatBlock>{DOCNL} { // new line
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ }
+<FormatBlock>"/*" { // start of a C-comment
+ g_commentCount++;
+ addOutput(yytext);
+ }
+<FormatBlock>"*/" { // end of a C-comment
+ addOutput(yytext);
+ g_commentCount--;
+ if (g_commentCount<0 && blockName!="verbatim")
+ {
+ warn(yyFileName,yyLineNr,
+ "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",blockName.data(),blockName.data());
+ }
+ }
+<FormatBlock>. {
+ addOutput(*yytext);
+ }
+<FormatBlock><<EOF>> {
+ QCString endTag = "@end"+blockName;
+ if (blockName=="startuml") endTag="enduml";
+ warn(yyFileName,yyLineNr,
+ "reached end of comment while inside a @%s block; check for missing @%s tag!",
+ blockName.data(),endTag.data()
+ );
+ yyterminate();
+ }
+
+ /* ----- handle arguments of if/ifnot commands ------- */
+
+<GuardParam>{B}*"(" {
+ g_guardExpr=yytext;
+ g_roundCount=1;
+ BEGIN(GuardExpr);
+ }
+<GuardExpr>[^()]* {
+ g_guardExpr+=yytext;
+ }
+<GuardExpr>"(" {
+ g_guardExpr+=yytext;
+ g_roundCount++;
+ }
+<GuardExpr>")" {
+ g_guardExpr+=yytext;
+ g_roundCount--;
+ if (g_roundCount==0)
+ {
+ handleGuard(g_guardExpr);
+ }
+ }
+<GuardExpr>\n {
+ warn(yyFileName,yyLineNr,
+ "invalid expression '%s' for guard",g_guardExpr.data());
+ unput(*yytext);
+ BEGIN(GuardParam);
+ }
+<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot guard
+ handleGuard(yytext);
+ }
+<GuardParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ //next line is commented out due to bug620924
+ //addOutput('\n');
+ BEGIN( Comment );
+ }
+<GuardParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GuardParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+<GuardParamEnd>{B}*{DOCNL} {
+ g_spaceBeforeIf.resize(0);
+ BEGIN(Comment);
+ }
+<GuardParamEnd>{B}* {
+ if (!g_spaceBeforeIf.isEmpty()) // needed for 665313 in combation with bug620924
+ {
+ addOutput(g_spaceBeforeIf);
+ }
+ g_spaceBeforeIf.resize(0);
+ BEGIN(Comment);
+ }
+<GuardParamEnd>. {
+ unput(*yytext);
+ BEGIN(Comment);
+ }
+
+ /* ----- handle skipping of conditional sections ------- */
+
+<SkipGuardedSection>{CMD}"ifnot"/{NW} {
+ guardType = Guard_IfNot;
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"if"/{NW} {
+ guardType = Guard_If;
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"endif"/{NW} {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found @endif without matching start command");
+ }
+ else
+ {
+ GuardedSection *s = guards.pop();
+ bool parentVisible = s->parentVisible();
+ delete s;
+ if (parentVisible)
+ {
+ enabledSectionFound=TRUE;
+ BEGIN( GuardParamEnd );
+ }
+ }
+ }
+<SkipGuardedSection>{CMD}"else"/{NW} {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found @else without matching start command");
+ }
+ else
+ {
+ if (!enabledSectionFound && guards.top()->parentVisible())
+ {
+ delete guards.pop();
+ guards.push(new GuardedSection(TRUE,TRUE));
+ enabledSectionFound=TRUE;
+ BEGIN( GuardParamEnd );
+ }
+ }
+ }
+<SkipGuardedSection>{CMD}"elseif"/{NW} {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found @elseif without matching start command");
+ }
+ else
+ {
+ if (!enabledSectionFound && guards.top()->parentVisible())
+ {
+ guardType=Guard_If;
+ delete guards.pop();
+ BEGIN( GuardParam );
+ }
+ }
+ }
+<SkipGuardedSection>{DOCNL} { // skip line
+ if (*yytext=='\n') yyLineNr++;
+ //addOutput('\n');
+ }
+<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipGuardedSection>. { // any other character
+ }
+
+
+ /* ----- handle skipping of internal section ------- */
+
+<SkipInternal>{DOCNL} { // skip line
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ }
+<SkipInternal>[@\\]"if"/[ \t] {
+ g_condCount++;
+ }
+<SkipInternal>[@\\]"ifnot"/[ \t] {
+ g_condCount++;
+ }
+<SkipInternal>[@\\]/"endif" {
+ g_condCount--;
+ if (g_condCount<0) // handle conditional section around of \internal, see bug607743
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"section"[ \t] {
+ if (g_sectionLevel>0)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"subsection"[ \t] {
+ if (g_sectionLevel>1)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"subsubsection"[ \t] {
+ if (g_sectionLevel>2)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"paragraph"[ \t] {
+ if (g_sectionLevel>3)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]"endinternal"[ \t]* {
+ addOutput("\\endinternal ");
+ BEGIN(Comment);
+ }
+<SkipInternal>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipInternal>. { // any other character
+ }
+
+
+ /* ----- handle argument of name command ------- */
+
+<NameParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<NameParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ g_memberGroupHeader+=' ';
+ }
+<NameParam>. { // ignore other stuff
+ g_memberGroupHeader+=*yytext;
+ current->name+=*yytext;
+ }
+
+ /* ----- handle argument of ingroup command ------- */
+
+<InGroupParam>{LABELID} { // group id
+ current->groups->append(
+ new Grouping(yytext, Grouping::GROUPING_INGROUP)
+ );
+ inGroupParamFound=TRUE;
+ }
+<InGroupParam>{DOCNL} { // missing argument
+ if (!inGroupParamFound)
+ {
+ warn(yyFileName,yyLineNr,
+ "Missing group name for \\ingroup command"
+ );
+ }
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<InGroupParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<InGroupParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+
+ /* ----- handle argument of fn command ------- */
+
+<FnParam>{DOCNL} { // end of argument
+ if (braceCount==0)
+ {
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ langParser->parsePrototype(functionProto);
+ BEGIN( Comment );
+ }
+ }
+<FnParam>{LC} { // line continuation
+ yyLineNr++;
+ functionProto+=' ';
+ }
+<FnParam>[^@\\\n()]+ { // non-special characters
+ functionProto+=yytext;
+ }
+<FnParam>"(" {
+ functionProto+=yytext;
+ braceCount++;
+ }
+<FnParam>")" {
+ functionProto+=yytext;
+ braceCount--;
+ }
+<FnParam>. { // add other stuff
+ functionProto+=*yytext;
+ }
+
+
+ /* ----- handle argument of overload command ------- */
+
+
+<OverloadParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ if (functionProto.stripWhiteSpace().isEmpty())
+ { // plain overload command
+ addOutput(getOverloadDocs());
+ addOutput('\n');
+ }
+ else // overload declaration
+ {
+ makeStructuralIndicator(Entry::OVERLOADDOC_SEC);
+ langParser->parsePrototype(functionProto);
+ }
+ BEGIN( Comment );
+ }
+<OverloadParam>{LC} { // line continuation
+ yyLineNr++;
+ functionProto+=' ';
+ }
+<OverloadParam>. { // add other stuff
+ functionProto+=*yytext;
+ }
+
+ /* ----- handle argument of inherit command ------- */
+
+<InheritParam>({ID}("::"|"."))*{ID} { // found argument
+ current->extends->append(
+ new BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
+ );
+ BEGIN( Comment );
+ }
+<InheritParam>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\inherit command has no argument"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<InheritParam>. { // invalid character for anchor label
+ warn(yyFileName,yyLineNr,
+ "Invalid or missing name for \\inherit command"
+ );
+ BEGIN(Comment);
+ }
+
+ /* ----- handle argument of extends and implements commands ------- */
+
+<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
+ current->extends->append(
+ new BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
+ );
+ BEGIN( Comment );
+ }
+<ExtendsParam>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\extends or \\implements command has no argument"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<ExtendsParam>. { // ignore other stuff
+ }
+
+ /* ----- handle language specific sections ------- */
+
+<SkipLang>[\\@]"~"[a-zA-Z]* { /* language switch */
+ QCString langId = &yytext[2];
+ if (langId.isEmpty() ||
+ qstricmp(Config_getEnum("OUTPUT_LANGUAGE"),langId)==0)
+ { // enable language specific section
+ BEGIN(Comment);
+ }
+ }
+<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
+ }
+<SkipLang>{DOCNL} { /* new line in verbatim block */
+ if (*yytext=='\n') yyLineNr++;
+ }
+<SkipLang>. { /* any other character */
+ }
+
+ /* ----- handle arguments of the cite command ------- */
+
+<CiteLabel>{CITEID} { // found argyment
+ addCite();
+ addOutput(yytext);
+ BEGIN(Comment);
+ }
+<CiteLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "\\cite command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<CiteLabel>. { // invalid character for cite label
+ warn(yyFileName,yyLineNr,
+ "Invalid or missing cite label"
+ );
+ BEGIN(Comment);
+ }
+
+ /* ----- handle argument of the copydoc command ------- */
+
+<CopyDoc><<EOF>> |
+<CopyDoc>{DOCNL} {
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ setOutput(OutputDoc);
+ addOutput("\\copydetails ");
+ addOutput(g_copyDocArg);
+ addOutput("\n");
+ BEGIN(Comment);
+ }
+<CopyDoc>[^\n\\]+ {
+ g_copyDocArg+=yytext;
+ addOutput(yytext);
+ }
+<CopyDoc>. {
+ g_copyDocArg+=yytext;
+ addOutput(yytext);
+ }
+
+
+%%
+
+//----------------------------------------------------------------------------
+
+static bool handleBrief(const QCString &)
+{
+ //printf("handleBrief\n");
+ setOutput(OutputBrief);
+ return FALSE;
+}
+
+static bool handleFn(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::MEMBERDOC_SEC);
+ functionProto.resize(0);
+ braceCount=0;
+ BEGIN(FnParam);
+ return stop;
+}
+
+static bool handleDef(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::DEFINEDOC_SEC);
+ functionProto.resize(0);
+ BEGIN(FnParam);
+ return stop;
+}
+
+static bool handleOverload(const QCString &)
+{
+ functionProto.resize(0);
+ BEGIN(OverloadParam);
+ return FALSE;
+}
+
+static bool handleEnum(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::ENUMDOC_SEC);
+ BEGIN(EnumDocArg1);
+ return stop;
+}
+
+static bool handleDefGroup(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_NORMAL;
+ BEGIN( GroupDocArg1 );
+ return stop;
+}
+
+static bool handleAddToGroup(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_ADD;
+ BEGIN( GroupDocArg1 );
+ return stop;
+}
+
+static bool handleWeakGroup(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_WEAK;
+ BEGIN( GroupDocArg1 );
+ return stop;
+}
+
+static bool handleNamespace(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::NAMESPACEDOC_SEC);
+ BEGIN( NameSpaceDocArg1 );
+ return stop;
+}
+
+static bool handlePackage(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::PACKAGEDOC_SEC);
+ BEGIN( PackageDocArg1 );
+ return stop;
+}
+
+static bool handleClass(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::CLASSDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handleHeaderFile(const QCString &)
+{
+ BEGIN( ClassDocArg2 );
+ return FALSE;
+}
+
+static bool handleProtocol(const QCString &)
+{ // Obj-C protocol
+ bool stop=makeStructuralIndicator(Entry::PROTOCOLDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handleCategory(const QCString &)
+{ // Obj-C category
+ bool stop=makeStructuralIndicator(Entry::CATEGORYDOC_SEC);
+ BEGIN( CategoryDocArg1 );
+ return stop;
+}
+
+static bool handleUnion(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::UNIONDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handleStruct(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::STRUCTDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handleInterface(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::INTERFACEDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handleIdlException(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC);
+ BEGIN( ClassDocArg1 );
+ return stop;
+}
+
+static bool handlePage(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::PAGEDOC_SEC);
+ BEGIN( PageDocArg1 );
+ return stop;
+}
+
+static bool handleMainpage(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::MAINPAGEDOC_SEC);
+ if (!stop)
+ {
+ current->name = "mainpage";
+ }
+ BEGIN( PageDocArg2 );
+ return stop;
+}
+
+static bool handleFile(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::FILEDOC_SEC);
+ if (!stop)
+ {
+ current->name = yyFileName;
+ }
+ BEGIN( FileDocArg1 );
+ return stop;
+}
+
+static bool handleDir(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::DIRDOC_SEC);
+ if (!stop) current->name = yyFileName;
+ BEGIN( FileDocArg1 );
+ return stop;
+}
+
+static bool handleExample(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::EXAMPLE_SEC);
+ if (!stop) current->name = yyFileName;
+ BEGIN( FileDocArg1 );
+ return stop;
+}
+
+static bool handleDetails(const QCString &)
+{
+ if (inContext!=OutputBrief)
+ {
+ addOutput("\n\n"); // treat @details outside brief description
+ // as a new paragraph
+ }
+ setOutput(OutputDoc);
+ return FALSE;
+}
+
+static bool handleName(const QCString &)
+{
+ bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC);
+ if (!stop)
+ {
+ g_memberGroupHeader.resize(0);
+ BEGIN( NameParam );
+ if (g_memberGroupId!=DOX_NOGROUP) // end of previous member group
+ {
+ closeGroup(current,yyFileName,yyLineNr,TRUE);
+ }
+ }
+ return stop;
+}
+
+static bool handleTodo(const QCString &)
+{
+ newXRefKind = XRef_Todo;
+ setOutput(OutputXRef);
+ xrefKind = XRef_Todo;
+ return FALSE;
+}
+
+static bool handleTest(const QCString &)
+{
+ newXRefKind = XRef_Test;
+ setOutput(OutputXRef);
+ xrefKind = XRef_Test;
+ return FALSE;
+}
+
+static bool handleBug(const QCString &)
+{
+ newXRefKind = XRef_Bug;
+ setOutput(OutputXRef);
+ xrefKind = XRef_Bug;
+ return FALSE;
+}
+
+static bool handleDeprecated(const QCString &)
+{
+ newXRefKind = XRef_Deprecated;
+ setOutput(OutputXRef);
+ xrefKind = XRef_Deprecated;
+ return FALSE;
+}
+
+static bool handleXRefItem(const QCString &)
+{
+ newXRefKind = XRef_Item;
+ BEGIN(XRefItemParam1);
+ return FALSE;
+}
+
+static bool handleParBlock(const QCString &)
+{
+ if (g_insideParBlock)
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\parblock command while already in a parblock!");
+ }
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("@parblock ");
+ g_insideParBlock = TRUE;
+ return FALSE;
+}
+
+static bool handleEndParBlock(const QCString &)
+{
+ if (!g_insideParBlock)
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\endparblock command without matching \\parblock!");
+ }
+ addOutput("@endparblock");
+ setOutput(OutputDoc); // to end a parblock inside a xrefitem like context
+ g_insideParBlock = FALSE;
+ return FALSE;
+}
+
+static bool handleRelated(const QCString &)
+{
+ BEGIN(RelatesParam1);
+ return FALSE;
+}
+
+static bool handleRelatedAlso(const QCString &)
+{
+ current->relatesType = Duplicate;
+ BEGIN(RelatesParam1);
+ return FALSE;
+}
+
+static bool handleMemberOf(const QCString &)
+{
+ current->relatesType = MemberOf;
+ BEGIN(RelatesParam1);
+ return FALSE;
+}
+
+static bool handleRefItem(const QCString &)
+{
+ addOutput("@refitem ");
+ BEGIN(LineParam);
+ return FALSE;
+}
+
+static bool handleSection(const QCString &s)
+{
+ setOutput(OutputDoc);
+ addOutput("@"+s+" ");
+ BEGIN(SectionLabel);
+ if (s=="section") g_sectionLevel=1;
+ else if (s=="subsection") g_sectionLevel=2;
+ else if (s=="subsubsection") g_sectionLevel=3;
+ else if (s=="paragraph") g_sectionLevel=4;
+ return FALSE;
+}
+
+static bool handleSubpage(const QCString &s)
+{
+ if (current->section!=Entry::EMPTY_SEC &&
+ current->section!=Entry::PAGEDOC_SEC &&
+ current->section!=Entry::MAINPAGEDOC_SEC
+ )
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\subpage command in a comment block that is not marked as a page!");
+ }
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("@"+s+" ");
+ BEGIN(SubpageLabel);
+ return FALSE;
+}
+
+static bool handleAnchor(const QCString &s)
+{
+ addOutput("@"+s+" ");
+ BEGIN(AnchorLabel);
+ return FALSE;
+}
+
+static bool handleCite(const QCString &s)
+{
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("@"+s+" ");
+ BEGIN(CiteLabel);
+ return FALSE;
+}
+
+static bool handleFormatBlock(const QCString &s)
+{
+ addOutput("@"+s+" ");
+ //printf("handleFormatBlock(%s)\n",s.data());
+ blockName=s;
+ g_commentCount=0;
+ BEGIN(FormatBlock);
+ return FALSE;
+}
+
+static bool handleAddIndex(const QCString &)
+{
+ addOutput("@addindex ");
+ BEGIN(LineParam);
+ return FALSE;
+}
+
+static bool handleIf(const QCString &)
+{
+ enabledSectionFound=FALSE;
+ guardType = Guard_If;
+ g_spaceBeforeIf = g_spaceBeforeCmd;
+ BEGIN(GuardParam);
+ return FALSE;
+}
+
+static bool handleIfNot(const QCString &)
+{
+ enabledSectionFound=FALSE;
+ guardType = Guard_IfNot;
+ g_spaceBeforeIf = g_spaceBeforeCmd;
+ BEGIN(GuardParam);
+ return FALSE;
+}
+
+static bool handleElseIf(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\else without matching start command");
+ }
+ else
+ {
+ guardType = enabledSectionFound ? Guard_Skip : Guard_If;
+ BEGIN(GuardParam);
+ }
+ return FALSE;
+}
+
+static bool handleElse(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\else without matching start command");
+ }
+ else
+ {
+ BEGIN( SkipGuardedSection );
+ }
+ return FALSE;
+}
+
+static bool handleEndIf(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "found \\endif without matching start command");
+ }
+ else
+ {
+ delete guards.pop();
+ }
+ enabledSectionFound=FALSE;
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ BEGIN( GuardParamEnd );
+ return FALSE;
+}
+
+static bool handleIngroup(const QCString &)
+{
+ inGroupParamFound=FALSE;
+ BEGIN( InGroupParam );
+ return FALSE;
+}
+
+static bool handleNoSubGrouping(const QCString &)
+{
+ current->subGrouping = FALSE;
+ return FALSE;
+}
+
+static bool handleShowInitializer(const QCString &)
+{
+ current->initLines = 100000; // ON
+ return FALSE;
+}
+
+static bool handleHideInitializer(const QCString &)
+{
+ current->initLines = 0; // OFF
+ return FALSE;
+}
+
+static bool handleCallgraph(const QCString &)
+{
+ current->callGraph = TRUE; // ON
+ return FALSE;
+}
+
+static bool handleCallergraph(const QCString &)
+{
+ current->callerGraph = TRUE; // ON
+ return FALSE;
+}
+
+static bool handleInternal(const QCString &)
+{
+ if (!Config_getBool("INTERNAL_DOCS"))
+ {
+ // make sure some whitespace before a \internal command
+ // is not treated as "documentation"
+ if (current->doc.stripWhiteSpace().isEmpty())
+ {
+ current->doc.resize(0);
+ }
+ g_condCount=0;
+ BEGIN( SkipInternal );
+ }
+ else
+ {
+ // re-enabled for bug640828
+ addOutput("\\internal ");
+ inInternalDocs = TRUE;
+ }
+ return FALSE;
+}
+
+static bool handleLineBr(const QCString &)
+{
+ addOutput('\n');
+ return FALSE;
+}
+
+static bool handleStatic(const QCString &)
+{
+ endBrief();
+ current->stat = TRUE;
+ return FALSE;
+}
+
+static bool handlePure(const QCString &)
+{
+ endBrief();
+ current->virt = Pure;
+ return FALSE;
+}
+
+static bool handlePrivate(const QCString &)
+{
+ current->protection = Private;
+ return FALSE;
+}
+
+static bool handlePrivateSection(const QCString &)
+{
+ current->protection = protection = Private;
+ return FALSE;
+}
+
+static bool handleProtected(const QCString &)
+{
+ current->protection = Protected;
+ return FALSE;
+}
+
+static bool handleProtectedSection(const QCString &)
+{
+ current->protection = protection = Protected ;
+ return FALSE;
+}
+
+static bool handlePublic(const QCString &)
+{
+ current->protection = Public;
+ return FALSE;
+}
+
+static bool handlePublicSection(const QCString &)
+{
+ current->protection = protection = Public;
+ return FALSE;
+}
+
+static bool handleToc(const QCString &)
+{
+ if (current->section==Entry::PAGEDOC_SEC ||
+ current->section==Entry::MAINPAGEDOC_SEC)
+ {
+ current->stat=TRUE; // we 'abuse' stat to pass whether or the TOC is enabled
+ }
+ return FALSE;
+}
+
+static bool handleInherit(const QCString &)
+{
+ BEGIN(InheritParam);
+ return FALSE;
+}
+
+static bool handleExtends(const QCString &)
+{
+ BEGIN(ExtendsParam);
+ return FALSE;
+}
+
+static bool handleCopyBrief(const QCString &)
+{
+ if (current->brief.isEmpty() && current->doc.isEmpty())
+ { // if we don't have a brief or detailed description yet,
+ // then the @copybrief should end up in the brief description.
+ // otherwise it will be copied inline (see bug691315 & bug700788)
+ setOutput(OutputBrief);
+ }
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("\\copybrief ");
+ return FALSE;
+}
+
+static bool handleCopyDetails(const QCString &)
+{
+ setOutput(OutputDoc);
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("\\copydetails ");
+ return FALSE;
+}
+
+static bool handleCopyDoc(const QCString &)
+{
+ setOutput(OutputBrief);
+ if (!g_spaceBeforeCmd.isEmpty())
+ {
+ addOutput(g_spaceBeforeCmd);
+ g_spaceBeforeCmd.resize(0);
+ }
+ addOutput("\\copybrief ");
+ g_copyDocArg.resize(0);
+ BEGIN(CopyDoc);
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+
+static void checkFormula()
+{
+ if (YY_START==ReadFormulaShort || YY_START==ReadFormulaLong)
+ {
+ warn(yyFileName,yyLineNr,"End of comment block while inside formula.");
+ }
+}
+
+//----------------------------------------------------------------------------
+
+bool parseCommentBlock(/* in */ ParserInterface *parser,
+ /* in */ Entry *curEntry,
+ /* in */ const QCString &comment,
+ /* in */ const QCString &fileName,
+ /* in,out */ int &lineNr,
+ /* in */ bool isBrief,
+ /* in */ bool isAutoBriefOn,
+ /* in */ bool isInbody,
+ /* in,out */ Protection &prot,
+ /* in,out */ int &position,
+ /* out */ bool &newEntryNeeded
+ )
+{
+ //printf("parseCommentBlock() isBrief=%d isAutoBriefOn=%d lineNr=%d\n",
+ // isBrief,isAutoBriefOn,lineNr);
+
+ initParser();
+ guards.setAutoDelete(TRUE);
+ guards.clear();
+ langParser = parser;
+ current = curEntry;
+ if (comment.isEmpty()) return FALSE; // avoid empty strings
+ inputString = comment;
+ inputString.append(" ");
+ inputPosition = position;
+ yyLineNr = lineNr;
+ yyFileName = fileName;
+ protection = prot;
+ needNewEntry = FALSE;
+ xrefKind = XRef_None;
+ xrefAppendFlag = FALSE;
+ insidePre = FALSE;
+ parseMore = FALSE;
+ inBody = isInbody;
+ outputXRef.resize(0);
+ setOutput( isBrief || isAutoBriefOn ? OutputBrief : OutputDoc );
+ briefEndsAtDot = isAutoBriefOn;
+ g_condCount = 0;
+ g_sectionLevel = 0;
+ g_spaceBeforeCmd.resize(0);
+ g_spaceBeforeIf.resize(0);
+
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName ? fileName.data(): NULL);
+ if (!current->inbodyDocs.isEmpty() && isInbody) // separate in body fragments
+ {
+ current->inbodyDocs+="\n\n";
+ }
+
+ Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\n"
+ "input=[\n%s]\n",fileName.data(),lineNr,comment.data()
+ );
+
+ commentscanYYrestart( commentscanYYin );
+ BEGIN( Comment );
+ commentscanYYlex();
+ setOutput( OutputDoc );
+
+ if (YY_START==OverloadParam) // comment ended with \overload
+ {
+ addOutput(getOverloadDocs());
+ }
+
+ if (!guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ }
+
+ if (g_insideParBlock)
+ {
+ warn(yyFileName,yyLineNr,
+ "Documentation block ended while inside a \\parblock. Missing \\endparblock");
+ }
+
+ current->doc=stripLeadingAndTrailingEmptyLines(current->doc,current->docLine);
+
+ if (current->section==Entry::FILEDOC_SEC && current->doc.isEmpty())
+ {
+ // to allow a comment block with just a @file command.
+ current->doc="\n\n";
+ }
+
+ if (current->section==Entry::MEMBERGRP_SEC &&
+ g_memberGroupId==DOX_NOGROUP) // @name section but no group started yet
+ {
+ openGroup(current,yyFileName,yyLineNr);
+ }
+
+ if (Doxygen::markdownSupport)
+ {
+ current->brief = processMarkdown(fileName,lineNr,current,current->brief);
+ current->doc = processMarkdown(fileName,lineNr,current,current->doc);
+ current->inbodyDocs = processMarkdown(fileName,lineNr,current,current->inbodyDocs);
+ }
+
+ Debug::print(Debug::CommentScan,0,
+ "brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n===========\n",
+ current->briefLine,current->brief.data(),
+ current->docLine,current->doc.data(),
+ current->inbodyLine,current->inbodyDocs.data()
+ );
+
+ checkFormula();
+ prot = protection;
+
+ groupAddDocs(curEntry,fileName);
+
+ newEntryNeeded = needNewEntry;
+
+ // if we did not proceed during this call, it does not make
+ // sense to continue, since we get stuck. See bug 567346 for situations
+ // were this happens
+ if (parseMore && position==inputPosition) parseMore=FALSE;
+
+ if (parseMore) position=inputPosition; else position=0;
+
+ lineNr = yyLineNr;
+ //printf("position=%d parseMore=%d newEntryNeeded=%d\n",
+ // position,parseMore,newEntryNeeded);
+
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName ? fileName.data(): NULL);
+ return parseMore;
+}
+
+//---------------------------------------------------------------------------
+
+void groupEnterFile(const char *fileName,int)
+{
+ g_autoGroupStack.setAutoDelete(TRUE);
+ g_autoGroupStack.clear();
+ g_memberGroupId = DOX_NOGROUP;
+ g_memberGroupDocs.resize(0);
+ g_memberGroupRelates.resize(0);
+ g_compoundName=fileName;
+}
+
+void groupLeaveFile(const char *fileName,int line)
+{
+ //if (g_memberGroupId!=DOX_NOGROUP)
+ //{
+ // warn(fileName,line,"end of file while inside a member group\n");
+ //}
+ g_memberGroupId=DOX_NOGROUP;
+ g_memberGroupRelates.resize(0);
+ g_memberGroupDocs.resize(0);
+ if (!g_autoGroupStack.isEmpty())
+ {
+ warn(fileName,line,"end of file while inside a group\n");
+ }
+}
+
+void groupEnterCompound(const char *fileName,int line,const char *name)
+{
+ if (g_memberGroupId!=DOX_NOGROUP)
+ {
+ warn(fileName,line,"try to put compound %s inside a member group\n",name);
+ }
+ g_memberGroupId=DOX_NOGROUP;
+ g_memberGroupRelates.resize(0);
+ g_memberGroupDocs.resize(0);
+ g_compoundName = name;
+ int i = g_compoundName.find('(');
+ if (i!=-1)
+ {
+ g_compoundName=g_compoundName.left(i); // strip category (Obj-C)
+ }
+ if (g_compoundName.isEmpty())
+ {
+ g_compoundName=fileName;
+ }
+ //printf("groupEnterCompound(%s)\n",name);
+}
+
+void groupLeaveCompound(const char *,int,const char * /*name*/)
+{
+ //printf("groupLeaveCompound(%s)\n",name);
+ //if (g_memberGroupId!=DOX_NOGROUP)
+ //{
+ // warn(fileName,line,"end of compound %s while inside a member group\n",name);
+ //}
+ g_memberGroupId=DOX_NOGROUP;
+ g_memberGroupRelates.resize(0);
+ g_memberGroupDocs.resize(0);
+ g_compoundName.resize(0);
+}
+
+static int findExistingGroup(int &groupId,const MemberGroupInfo *info)
+{
+ //printf("findExistingGroup %s:%s\n",info->header.data(),info->compoundName.data());
+ QIntDictIterator<MemberGroupInfo> di(Doxygen::memGrpInfoDict);
+ MemberGroupInfo *mi;
+ for (di.toFirst();(mi=di.current());++di)
+ {
+ if (g_compoundName==mi->compoundName && // same file or scope
+ !mi->header.isEmpty() && // not a nameless group
+ qstricmp(mi->header,info->header)==0 // same header name
+ )
+ {
+ //printf("Found it!\n");
+ return (int)di.currentKey(); // put the item in this group
+ }
+ }
+ groupId++; // start new group
+ return groupId;
+}
+
+void openGroup(Entry *e,const char *,int)
+{
+ //printf("==> openGroup(name=%s,sec=%x) g_autoGroupStack=%d\n",
+ // e->name.data(),e->section,g_autoGroupStack.count());
+ if (e->section==Entry::GROUPDOC_SEC) // auto group
+ {
+ g_autoGroupStack.push(new Grouping(e->name,e->groupingPri()));
+ }
+ else // start of a member group
+ {
+ //printf(" membergroup id=%d %s\n",g_memberGroupId,g_memberGroupHeader.data());
+ if (g_memberGroupId==DOX_NOGROUP) // no group started yet
+ {
+ static int curGroupId=0;
+
+ MemberGroupInfo *info = new MemberGroupInfo;
+ info->header = g_memberGroupHeader.stripWhiteSpace();
+ info->compoundName = g_compoundName;
+ g_memberGroupId = findExistingGroup(curGroupId,info);
+ //printf(" use membergroup %d\n",g_memberGroupId);
+ Doxygen::memGrpInfoDict.insert(g_memberGroupId,info);
+
+ g_memberGroupRelates = e->relates;
+ e->mGrpId = g_memberGroupId;
+ }
+ }
+}
+
+void closeGroup(Entry *e,const char *fileName,int,bool foundInline)
+{
+ //printf("==> closeGroup(name=%s,sec=%x) g_autoGroupStack=%d\n",
+ // e->name.data(),e->section,g_autoGroupStack.count());
+ if (g_memberGroupId!=DOX_NOGROUP) // end of member group
+ {
+ MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId);
+ if (info) // known group
+ {
+ info->doc = g_memberGroupDocs;
+ info->docFile = fileName;
+ }
+ g_memberGroupId=DOX_NOGROUP;
+ g_memberGroupRelates.resize(0);
+ g_memberGroupDocs.resize(0);
+ e->mGrpId=DOX_NOGROUP;
+ //printf("new group id=%d\n",g_memberGroupId);
+ }
+ else if (!g_autoGroupStack.isEmpty()) // end of auto group
+ {
+ Grouping *grp = g_autoGroupStack.pop();
+ // see bug577005: we should not remove the last group for e
+ if (!foundInline) e->groups->removeLast();
+ //printf("Removing %s e=%p\n",grp->groupname.data(),e);
+ delete grp;
+ if (!foundInline) initGroupInfo(e);
+ }
+}
+
+void initGroupInfo(Entry *e)
+{
+ //printf("==> initGroup(id=%d,related=%s,e=%p)\n",g_memberGroupId,
+ // g_memberGroupRelates.data(),e);
+ e->mGrpId = g_memberGroupId;
+ e->relates = g_memberGroupRelates;
+ if (!g_autoGroupStack.isEmpty())
+ {
+ //printf("Appending group %s to %s: count=%d entry=%p\n",
+ // g_autoGroupStack.top()->groupname.data(),
+ // e->name.data(),e->groups->count(),e);
+ e->groups->append(new Grouping(*g_autoGroupStack.top()));
+ }
+}
+
+static void groupAddDocs(Entry *e,const char *fileName)
+{
+ if (e->section==Entry::MEMBERGRP_SEC)
+ {
+ g_memberGroupDocs=e->brief.stripWhiteSpace();
+ e->doc = stripLeadingAndTrailingEmptyLines(e->doc,e->docLine);
+ if (!g_memberGroupDocs.isEmpty() && !e->doc.isEmpty())
+ {
+ g_memberGroupDocs+="\n\n";
+ }
+ g_memberGroupDocs+=e->doc;
+ MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId);
+ if (info)
+ {
+ info->doc = g_memberGroupDocs;
+ info->docFile = fileName;
+ info->setRefItems(e->sli);
+ }
+ e->doc.resize(0);
+ e->brief.resize(0);
+ }
+}
+
+static void handleGuard(const QCString &expr)
+{
+ CondParser prs;
+ bool sectionEnabled=prs.parse(yyFileName,yyLineNr,expr.stripWhiteSpace());
+ bool parentEnabled = TRUE;
+ if (!guards.isEmpty()) parentEnabled = guards.top()->isEnabled();
+ if (parentEnabled)
+ {
+ if (
+ (sectionEnabled && guardType==Guard_If) ||
+ (!sectionEnabled && guardType==Guard_IfNot)
+ ) // section is visible
+ {
+ guards.push(new GuardedSection(TRUE,TRUE));
+ enabledSectionFound=TRUE;
+ BEGIN( GuardParamEnd );
+ }
+ else // section is invisible
+ {
+ if (guardType!=Guard_Skip)
+ {
+ guards.push(new GuardedSection(FALSE,TRUE));
+ }
+ BEGIN( SkipGuardedSection );
+ }
+ }
+ else // invisible because of parent
+ {
+ guards.push(new GuardedSection(FALSE,FALSE));
+ BEGIN( SkipGuardedSection );
+ }
+}
+
+
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void commentscanYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/compound.xsd b/src/compound.xsd
new file mode 100644
index 0000000..be897c3
--- /dev/null
+++ b/src/compound.xsd
@@ -0,0 +1,844 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="doxygen" type="DoxygenType"/>
+
+ <!-- Complex types -->
+
+ <xsd:complexType name="DoxygenType">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="version" type="DoxVersionNumber" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="compounddefType">
+ <xsd:sequence>
+ <xsd:element name="compoundname" type="xsd:string"/>
+ <xsd:element name="title" type="xsd:string" minOccurs="0" />
+ <xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
+ <xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
+ <xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
+ <xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
+ <xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
+ <xsd:element name="programlisting" type="listingType" minOccurs="0" />
+ <xsd:element name="location" type="locationType" minOccurs="0" />
+ <xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ <xsd:attribute name="kind" type="DoxCompoundKind" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" />
+ <xsd:attribute name="final" type="DoxBool" use="optional"/>
+ <xsd:attribute name="sealed" type="DoxBool" use="optional"/>
+ <xsd:attribute name="abstract" type="DoxBool" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="listofallmembersType">
+ <xsd:sequence>
+ <xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="memberRefType">
+ <xsd:sequence>
+ <xsd:element name="scope" />
+ <xsd:element name="name" />
+ </xsd:sequence>
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" />
+ <xsd:attribute name="virt" type="DoxVirtualKind" />
+ <xsd:attribute name="ambiguityscope" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="compoundRefType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="refid" type="xsd:string" use="optional" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" />
+ <xsd:attribute name="virt" type="DoxVirtualKind" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="reimplementType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="refid" type="xsd:string" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="incType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="local" type="DoxBool" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="refTextType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="kindref" type="DoxRefKind" />
+ <xsd:attribute name="external" type="xsd:string" use="optional"/>
+ <xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="sectiondefType">
+ <xsd:sequence>
+ <xsd:element name="header" type="xsd:string" minOccurs="0" />
+ <xsd:element name="description" type="descriptionType" minOccurs="0" />
+ <xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="kind" type="DoxSectionKind" />
+ </xsd:complexType>
+
+ <xsd:complexType name="memberdefType">
+ <xsd:sequence>
+ <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
+ <xsd:element name="type" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="definition" minOccurs="0" />
+ <xsd:element name="argsstring" minOccurs="0" />
+ <xsd:element name="name" />
+ <xsd:element name="read" minOccurs="0" />
+ <xsd:element name="write" minOccurs="0" />
+ <xsd:element name="bitfield" minOccurs="0" />
+ <xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="location" type="locationType" />
+ <xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="kind" type="DoxMemberKind" />
+ <xsd:attribute name="id" type="xsd:string" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" />
+ <xsd:attribute name="static" type="DoxBool" />
+ <xsd:attribute name="const" type="DoxBool" use="optional"/>
+ <xsd:attribute name="explicit" type="DoxBool" use="optional"/>
+ <xsd:attribute name="inline" type="DoxBool" use="optional"/>
+ <xsd:attribute name="virt" type="DoxVirtualKind" use="optional"/>
+ <xsd:attribute name="volatile" type="DoxBool" use="optional"/>
+ <xsd:attribute name="mutable" type="DoxBool" use="optional"/>
+ <!-- Qt property -->
+ <xsd:attribute name="readable" type="DoxBool" use="optional"/>
+ <xsd:attribute name="writable" type="DoxBool" use="optional"/>
+ <!-- C++/CLI variable -->
+ <xsd:attribute name="initonly" type="DoxBool" use="optional"/>
+ <!-- C++/CLI and C# property -->
+ <xsd:attribute name="settable" type="DoxBool" use="optional"/>
+ <xsd:attribute name="gettable" type="DoxBool" use="optional"/>
+ <!-- C++/CLI function -->
+ <xsd:attribute name="final" type="DoxBool" use="optional"/>
+ <xsd:attribute name="sealed" type="DoxBool" use="optional"/>
+ <xsd:attribute name="new" type="DoxBool" use="optional"/>
+ <!-- C++/CLI event -->
+ <xsd:attribute name="add" type="DoxBool" use="optional"/>
+ <xsd:attribute name="remove" type="DoxBool" use="optional"/>
+ <xsd:attribute name="raise" type="DoxBool" use="optional"/>
+ <!-- Objective-C 2.0 protocol method -->
+ <xsd:attribute name="optional" type="DoxBool" use="optional"/>
+ <xsd:attribute name="required" type="DoxBool" use="optional"/>
+ <!-- Objective-C 2.0 property accessor -->
+ <xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
+ <!-- UNO IDL -->
+ <xsd:attribute name="attribute" type="DoxBool" use="optional"/>
+ <xsd:attribute name="property" type="DoxBool" use="optional"/>
+ <xsd:attribute name="readonly" type="DoxBool" use="optional"/>
+ <xsd:attribute name="bound" type="DoxBool" use="optional"/>
+ <xsd:attribute name="removable" type="DoxBool" use="optional"/>
+ <xsd:attribute name="contrained" type="DoxBool" use="optional"/>
+ <xsd:attribute name="transient" type="DoxBool" use="optional"/>
+ <xsd:attribute name="maybevoid" type="DoxBool" use="optional"/>
+ <xsd:attribute name="maybedefault" type="DoxBool" use="optional"/>
+ <xsd:attribute name="maybeambiguous" type="DoxBool" use="optional"/>
+
+ </xsd:complexType>
+
+ <xsd:complexType name="descriptionType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="title" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalType" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="enumvalueType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="name" />
+ <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
+ <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ <xsd:attribute name="prot" type="DoxProtectionKind" />
+ </xsd:complexType>
+
+ <xsd:complexType name="templateparamlistType">
+ <xsd:sequence>
+ <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="paramType">
+ <xsd:sequence>
+ <xsd:element name="type" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="declname" minOccurs="0" />
+ <xsd:element name="defname" minOccurs="0" />
+ <xsd:element name="array" minOccurs="0" />
+ <xsd:element name="defval" type="linkedTextType" minOccurs="0" />
+ <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="linkedTextType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="graphType">
+ <xsd:sequence>
+ <xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="nodeType">
+ <xsd:sequence>
+ <xsd:element name="label" />
+ <xsd:element name="link" type="linkType" minOccurs="0" />
+ <xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="childnodeType">
+ <xsd:sequence>
+ <xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="relation" type="DoxGraphRelation" />
+ </xsd:complexType>
+
+ <xsd:complexType name="linkType">
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="external" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="listingType">
+ <xsd:sequence>
+ <xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="codelineType">
+ <xsd:sequence>
+ <xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="lineno" type="xsd:integer" />
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="refkind" type="DoxRefKind" />
+ <xsd:attribute name="external" type="DoxBool" />
+ </xsd:complexType>
+
+ <xsd:complexType name="highlightType" mixed="true">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="sp" />
+ <xsd:element name="ref" type="refTextType" />
+ </xsd:choice>
+ <xsd:attribute name="class" type="DoxHighlightClass" />
+ </xsd:complexType>
+
+ <xsd:complexType name="referenceType" mixed="true">
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="compoundref" type="xsd:string" use="optional" />
+ <xsd:attribute name="startline" type="xsd:integer" />
+ <xsd:attribute name="endline" type="xsd:integer" />
+ </xsd:complexType>
+
+ <xsd:complexType name="locationType">
+ <xsd:attribute name="file" type="xsd:string" />
+ <xsd:attribute name="line" type="xsd:integer" />
+ <xsd:attribute name="column" type="xsd:integer" use="optional"/>
+ <xsd:attribute name="bodyfile" type="xsd:string" />
+ <xsd:attribute name="bodystart" type="xsd:integer" />
+ <xsd:attribute name="bodyend" type="xsd:integer" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docSect1Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="title" type="xsd:string" />
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docSect2Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="title" type="xsd:string" />
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docSect3Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="title" type="xsd:string" />
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docSect4Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="title" type="xsd:string" />
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docInternalType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docInternalS1Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docInternalS2Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docInternalS3Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docInternalS4Type" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:group name="docTitleCmdGroup">
+ <xsd:choice>
+ <xsd:element name="ulink" type="docURLLink" />
+ <xsd:element name="bold" type="docMarkupType" />
+ <xsd:element name="emphasis" type="docMarkupType" />
+ <xsd:element name="computeroutput" type="docMarkupType" />
+ <xsd:element name="subscript" type="docMarkupType" />
+ <xsd:element name="superscript" type="docMarkupType" />
+ <xsd:element name="center" type="docMarkupType" />
+ <xsd:element name="small" type="docMarkupType" />
+ <xsd:element name="htmlonly" type="xsd:string" />
+ <xsd:element name="manonly" type="xsd:string" />
+ <xsd:element name="xmlonly" type="xsd:string" />
+ <xsd:element name="rtfonly" type="xsd:string" />
+ <xsd:element name="latexonly" type="xsd:string" />
+ <xsd:element name="dot" type="xsd:string" />
+ <xsd:element name="plantuml" type="xsd:string" />
+ <xsd:element name="anchor" type="docAnchorType" />
+ <xsd:element name="formula" type="docFormulaType" />
+ <xsd:element name="ref" type="docRefTextType" />
+ <!-- Automatically insert here the HTML entities -->
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="docTitleType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:complexType>
+
+ <xsd:group name="docCmdGroup">
+ <xsd:choice>
+ <xsd:group ref="docTitleCmdGroup"/>
+ <xsd:element name="linebreak" type="docEmptyType" />
+ <xsd:element name="hruler" type="docEmptyType" />
+ <xsd:element name="preformatted" type="docMarkupType" />
+ <xsd:element name="programlisting" type="listingType" />
+ <xsd:element name="verbatim" type="xsd:string" />
+ <xsd:element name="indexentry" type="docIndexEntryType" />
+ <xsd:element name="orderedlist" type="docListType" />
+ <xsd:element name="itemizedlist" type="docListType" />
+ <xsd:element name="simplesect" type="docSimpleSectType" />
+ <xsd:element name="title" type="docTitleType" />
+ <xsd:element name="variablelist" type="docVariableListType" />
+ <xsd:element name="table" type="docTableType" />
+ <xsd:element name="heading" type="docHeadingType" />
+ <xsd:element name="image" type="docImageType" />
+ <xsd:element name="dotfile" type="docFileType" />
+ <xsd:element name="mscfile" type="docFileType" />
+ <xsd:element name="diafile" type="docFileType" />
+ <xsd:element name="toclist" type="docTocListType" />
+ <xsd:element name="language" type="docLanguageType" />
+ <xsd:element name="parameterlist" type="docParamListType" />
+ <xsd:element name="xrefsect" type="docXRefSectType" />
+ <xsd:element name="copydoc" type="docCopyType" />
+ <xsd:element name="blockquote" type="docBlockQuoteType" />
+ <xsd:element name="parblock" type="docParBlockType" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="docParaType" mixed="true">
+ <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docMarkupType" mixed="true">
+ <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docURLLink" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="url" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docAnchorType" mixed="true">
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docFormulaType" mixed="true">
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docIndexEntryType">
+ <xsd:sequence>
+ <xsd:element name="primaryie" type="xsd:string" />
+ <xsd:element name="secondaryie" type="xsd:string" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docListType">
+ <xsd:sequence>
+ <xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docListItemType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docSimpleSectType">
+ <xsd:sequence>
+ <xsd:element name="title" type="docTitleType" minOccurs="0" />
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:sequence>
+ <xsd:attribute name="kind" type="DoxSimpleSectKind" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docVarListEntryType">
+ <xsd:sequence>
+ <xsd:element name="term" type="docTitleType" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:group name="docVariableListGroup">
+ <xsd:sequence>
+ <xsd:element name="varlistentry" type="docVarListEntryType" />
+ <xsd:element name="listitem" type="docListItemType" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="docVariableListType">
+ <xsd:sequence>
+ <xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docRefTextType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="refid" type="xsd:string" />
+ <xsd:attribute name="kindref" type="DoxRefKind" />
+ <xsd:attribute name="external" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docTableType">
+ <xsd:sequence>
+ <xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="caption" type="docCaptionType" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="rows" type="xsd:integer" />
+ <xsd:attribute name="cols" type="xsd:integer" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docRowType">
+ <xsd:sequence>
+ <xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docEntryType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="thead" type="DoxBool" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docCaptionType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docHeadingType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
+ </xsd:complexType>
+
+ <xsd:complexType name="docImageType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="type" type="DoxImageKind" />
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="width" type="xsd:string" />
+ <xsd:attribute name="height" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docFileType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docTocItemType" mixed="true">
+ <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docTocListType">
+ <xsd:sequence>
+ <xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docLanguageType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="langid" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docParamListType">
+ <xsd:sequence>
+ <xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="kind" type="DoxParamListKind" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docParamListItem">
+ <xsd:sequence>
+ <xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="parameterdescription" type="descriptionType" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docParamNameList">
+ <xsd:sequence>
+ <xsd:element name="parametertype" type="docParamType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docParamType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docParamName" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="direction" type="DoxParamDir" use="optional" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docXRefSectType">
+ <xsd:sequence>
+ <xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="xrefdescription" type="descriptionType" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docCopyType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="internal" type="docInternalType" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="link" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="docBlockQuoteType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docParBlockType">
+ <xsd:sequence>
+ <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="docEmptyType"/>
+
+ <!-- Simple types -->
+
+ <xsd:simpleType name="DoxBool">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="yes" />
+ <xsd:enumeration value="no" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxGraphRelation">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="include" />
+ <xsd:enumeration value="usage" />
+ <xsd:enumeration value="template-instance" />
+ <xsd:enumeration value="public-inheritance" />
+ <xsd:enumeration value="protected-inheritance" />
+ <xsd:enumeration value="private-inheritance" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxRefKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="compound" />
+ <xsd:enumeration value="member" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxMemberKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="define" />
+ <xsd:enumeration value="property" />
+ <xsd:enumeration value="event" />
+ <xsd:enumeration value="variable" />
+ <xsd:enumeration value="typedef" />
+ <xsd:enumeration value="enum" />
+ <xsd:enumeration value="function" />
+ <xsd:enumeration value="signal" />
+ <xsd:enumeration value="prototype" />
+ <xsd:enumeration value="friend" />
+ <xsd:enumeration value="dcop" />
+ <xsd:enumeration value="slot" />
+ <xsd:enumeration value="interface" />
+ <xsd:enumeration value="service" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxProtectionKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="public" />
+ <xsd:enumeration value="protected" />
+ <xsd:enumeration value="private" />
+ <xsd:enumeration value="package" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxVirtualKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="non-virtual" />
+ <xsd:enumeration value="virtual" />
+ <xsd:enumeration value="pure-virtual" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxCompoundKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="class" />
+ <xsd:enumeration value="struct" />
+ <xsd:enumeration value="union" />
+ <xsd:enumeration value="interface" />
+ <xsd:enumeration value="protocol" />
+ <xsd:enumeration value="category" />
+ <xsd:enumeration value="exception" />
+ <xsd:enumeration value="service" />
+ <xsd:enumeration value="singleton" />
+ <xsd:enumeration value="module" />
+ <xsd:enumeration value="type" />
+ <xsd:enumeration value="file" />
+ <xsd:enumeration value="namespace" />
+ <xsd:enumeration value="group" />
+ <xsd:enumeration value="page" />
+ <xsd:enumeration value="example" />
+ <xsd:enumeration value="dir" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxSectionKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="user-defined" />
+ <xsd:enumeration value="public-type" />
+ <xsd:enumeration value="public-func" />
+ <xsd:enumeration value="public-attrib" />
+ <xsd:enumeration value="public-slot" />
+ <xsd:enumeration value="signal" />
+ <xsd:enumeration value="dcop-func" />
+ <xsd:enumeration value="property" />
+ <xsd:enumeration value="event" />
+ <xsd:enumeration value="public-static-func" />
+ <xsd:enumeration value="public-static-attrib" />
+ <xsd:enumeration value="protected-type" />
+ <xsd:enumeration value="protected-func" />
+ <xsd:enumeration value="protected-attrib" />
+ <xsd:enumeration value="protected-slot" />
+ <xsd:enumeration value="protected-static-func" />
+ <xsd:enumeration value="protected-static-attrib" />
+ <xsd:enumeration value="package-type" />
+ <xsd:enumeration value="package-func" />
+ <xsd:enumeration value="package-attrib" />
+ <xsd:enumeration value="package-static-func" />
+ <xsd:enumeration value="package-static-attrib" />
+ <xsd:enumeration value="private-type" />
+ <xsd:enumeration value="private-func" />
+ <xsd:enumeration value="private-attrib" />
+ <xsd:enumeration value="private-slot" />
+ <xsd:enumeration value="private-static-func" />
+ <xsd:enumeration value="private-static-attrib" />
+ <xsd:enumeration value="friend" />
+ <xsd:enumeration value="related" />
+ <xsd:enumeration value="define" />
+ <xsd:enumeration value="prototype" />
+ <xsd:enumeration value="typedef" />
+ <xsd:enumeration value="enum" />
+ <xsd:enumeration value="func" />
+ <xsd:enumeration value="var" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxHighlightClass">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="comment" />
+ <xsd:enumeration value="normal" />
+ <xsd:enumeration value="preprocessor" />
+ <xsd:enumeration value="keyword" />
+ <xsd:enumeration value="keywordtype" />
+ <xsd:enumeration value="keywordflow" />
+ <xsd:enumeration value="stringliteral" />
+ <xsd:enumeration value="charliteral" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxSimpleSectKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="see" />
+ <xsd:enumeration value="return" />
+ <xsd:enumeration value="author" />
+ <xsd:enumeration value="authors" />
+ <xsd:enumeration value="version" />
+ <xsd:enumeration value="since" />
+ <xsd:enumeration value="date" />
+ <xsd:enumeration value="note" />
+ <xsd:enumeration value="warning" />
+ <xsd:enumeration value="pre" />
+ <xsd:enumeration value="post" />
+ <xsd:enumeration value="copyright" />
+ <xsd:enumeration value="invariant" />
+ <xsd:enumeration value="remark" />
+ <xsd:enumeration value="attention" />
+ <xsd:enumeration value="par" />
+ <xsd:enumeration value="rcs" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxVersionNumber">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="\d+\.\d+.*" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxImageKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="html" />
+ <xsd:enumeration value="latex" />
+ <xsd:enumeration value="rtf" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxParamListKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="param" />
+ <xsd:enumeration value="retval" />
+ <xsd:enumeration value="exception" />
+ <xsd:enumeration value="templateparam" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxCharRange">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="[aeiouncAEIOUNC]" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxParamDir">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="in"/>
+ <xsd:enumeration value="out"/>
+ <xsd:enumeration value="inout"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DoxAccessor">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="retain"/>
+ <xsd:enumeration value="copy"/>
+ <xsd:enumeration value="assign"/>
+ <xsd:enumeration value="weak"/>
+ <xsd:enumeration value="strong"/>
+ <xsd:enumeration value="unretained"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema>
+
diff --git a/src/condparser.cpp b/src/condparser.cpp
new file mode 100644
index 0000000..67da1e3
--- /dev/null
+++ b/src/condparser.cpp
@@ -0,0 +1,309 @@
+/**
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * C++ Expression parser for ENABLED_SECTIONS in Doxygen
+ *
+ * Features used:
+ * Operators:
+ * && AND operator
+ * || OR operator
+ * ! NOT operator
+ */
+
+#include "condparser.h"
+#include "config.h"
+#include "message.h"
+
+// declarations
+
+/**
+ * parses and evaluates the given expression.
+ * @returns
+ * - On error, an error message is returned.
+ * - On success, the result of the expression is either "1" or "0".
+ */
+bool CondParser::parse(const char *fileName,int lineNr,const char *expr)
+{
+ m_expr = expr;
+ m_tokenType = NOTHING;
+
+ // initialize all variables
+ m_e = m_expr; // let m_e point to the start of the expression
+
+ bool answer=FALSE;
+ getToken();
+ if (m_tokenType==DELIMITER && m_token.isEmpty())
+ {
+ // empty expression: answer==FALSE
+ }
+ else if (m_err.isEmpty())
+ {
+ answer = parseLevel1();
+
+#if 0
+ // check for garbage at the end of the expression
+ // an expression ends with a character '\0' and token_type = delimeter
+ if (m_tokenType!=DELIMITER || !m_token.isEmpty())
+ {
+ if (m_tokenType == DELIMITER)
+ {
+ if (m_token=="(" || m_token==")")
+ {
+ m_err=QCString("Unexpected parenthesis ")+m_token+"'";
+ }
+ else
+ {
+ // user entered a not existing operator like "//"
+ m_err=QCString("Unexpected operator ")+m_token+"'";
+ }
+ }
+ else
+ {
+ m_err=QCString("Unexpected part '")+m_token+"'";
+ }
+ }
+#endif
+ }
+ if (m_err)
+ {
+ warn(fileName,lineNr,"problem evaluating expression '%s': %s",
+ expr,m_err.data());
+ }
+ //printf("expr='%s' answer=%d\n",expr,answer);
+ return answer;
+}
+
+
+/**
+ * checks if the given char c is a delimeter
+ * minus is checked apart, can be unary minus
+ */
+static bool isDelimiter(const char c)
+{
+ return c=='&' || c=='|' || c=='!';
+}
+
+/**
+ * checks if the given char c is a letter or underscore
+ */
+static bool isAlpha(const char c)
+{
+ return (c>='A' && c<='Z') || (c>='a' && c<='z') || c=='_';
+}
+
+static bool isAlphaNum(const char c)
+{
+ return isAlpha(c) || (c>='0' && c<='9');
+}
+
+/**
+ * returns the id of the given operator
+ * returns -1 if the operator is not recognized
+ */
+int CondParser::getOperatorId(const QCString &opName)
+{
+ // level 2
+ if (opName=="&&") { return AND; }
+ if (opName=="||") { return OR; }
+
+ // not operator
+ if (opName=="!") { return NOT; }
+
+ return UNKNOWN_OP;
+}
+
+/**
+ * Get next token in the current string expr.
+ * Uses the data in m_expr pointed to by m_e to
+ * produce m_tokenType and m_token, set m_err in case of an error
+ */
+void CondParser::getToken()
+{
+ m_tokenType = NOTHING;
+ m_token.resize(0);
+
+ //printf("\tgetToken e:{%c}, ascii=%i, col=%i\n", *e, *e, e-expr);
+
+ // skip over whitespaces
+ while (*m_e == ' ' || *m_e == '\t') // space or tab
+ {
+ m_e++;
+ }
+
+ // check for end of expression
+ if (*m_e=='\0')
+ {
+ // token is still empty
+ m_tokenType = DELIMITER;
+ return;
+ }
+
+ // check for parentheses
+ if (*m_e == '(' || *m_e == ')')
+ {
+ m_tokenType = DELIMITER;
+ m_token += *m_e++;
+ return;
+ }
+
+ // check for operators (delimeters)
+ if (isDelimiter(*m_e))
+ {
+ m_tokenType = DELIMITER;
+ while (isDelimiter(*m_e))
+ {
+ m_token += *m_e++;
+ }
+ return;
+ }
+
+ // check for variables
+ if (isAlpha(*m_e))
+ {
+ m_tokenType = VARIABLE;
+ while (isAlphaNum(*m_e))
+ {
+ m_token += *m_e++;
+ }
+ return;
+ }
+
+ // something unknown is found, wrong characters -> a syntax error
+ m_tokenType = UNKNOWN;
+ while (*m_e)
+ {
+ m_token += *m_e++;
+ }
+ m_err = QCString("Syntax error in part '")+m_token+"'";
+ return;
+}
+
+
+/**
+ * conditional operators AND and OR
+ */
+bool CondParser::parseLevel1()
+{
+ bool ans = parseLevel2();
+ int opId = getOperatorId(m_token);
+
+ while (opId==AND || opId==OR)
+ {
+ getToken();
+ ans = evalOperator(opId, ans, parseLevel2());
+ opId = getOperatorId(m_token);
+ }
+
+ return ans;
+}
+
+/**
+ * NOT
+ */
+bool CondParser::parseLevel2()
+{
+ bool ans;
+ int opId = getOperatorId(m_token);
+ if (opId == NOT)
+ {
+ getToken();
+ ans = !parseLevel3();
+ }
+ else
+ {
+ ans = parseLevel3();
+ }
+
+ return ans;
+}
+
+
+/**
+ * parenthesized expression or variable
+ */
+bool CondParser::parseLevel3()
+{
+ // check if it is a parenthesized expression
+ if (m_tokenType == DELIMITER)
+ {
+ if (m_token=="(")
+ {
+ getToken();
+ int ans = parseLevel1();
+ if (m_tokenType!=DELIMITER || m_token!=")")
+ {
+ m_err="Parenthesis ) missing";
+ return FALSE;
+ }
+ getToken();
+ return ans;
+ }
+ }
+
+ // if not parenthesized then the expression is a variable
+ return parseVar();
+}
+
+
+bool CondParser::parseVar()
+{
+ bool ans = 0;
+ switch (m_tokenType)
+ {
+ case VARIABLE:
+ // this is a variable
+ ans = evalVariable(m_token);
+ getToken();
+ break;
+
+ default:
+ // syntax error or unexpected end of expression
+ if (m_token.isEmpty())
+ {
+ m_err="Unexpected end of expression";
+ return FALSE;
+ }
+ else
+ {
+ m_err="Value expected";
+ return FALSE;
+ }
+ break;
+ }
+ return ans;
+}
+
+/**
+ * evaluate an operator for given valuess
+ */
+bool CondParser::evalOperator(int opId, bool lhs, bool rhs)
+{
+ switch (opId)
+ {
+ // level 2
+ case AND: return lhs && rhs;
+ case OR: return lhs || rhs;
+ }
+
+ m_err = "Internal error unknown operator: id="+QCString().setNum(opId);
+ return FALSE;
+}
+
+/**
+ * evaluate a variable
+ */
+bool CondParser::evalVariable(const char *varName)
+{
+ if (Config_getList("ENABLED_SECTIONS").find(varName)==-1) return FALSE;
+ return TRUE;
+}
+
diff --git a/src/condparser.h b/src/condparser.h
new file mode 100644
index 0000000..0310f36
--- /dev/null
+++ b/src/condparser.h
@@ -0,0 +1,75 @@
+#ifndef CONDPARSER_H
+#define CONDPARSER_H
+
+/**
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * C++ Expression parser for EXTABLED_SETIONS in Doxygen
+ *
+ * Features used:
+ * Operators:
+ * && AND operator
+ * || OR operator
+ * ! NOT operator
+ */
+
+#include <qcstring.h>
+
+class CondParser
+{
+ // public functions
+ public:
+ bool parse(const char *fileName,int lineNr,const char *expr);
+
+ // enumerations
+ private:
+ enum TOKENTYPE
+ {
+ NOTHING = -1,
+ DELIMITER,
+ VARIABLE,
+ UNKNOWN
+ };
+ enum OPERATOR_ID
+ {
+ UNKNOWN_OP = -1,
+ AND = 1,
+ OR,
+ NOT
+ };
+
+ // data
+ private:
+
+ QCString m_err; //!< error state
+ QCString m_expr; //!< holds the expression
+ const char *m_e; //!< points to a character in expr
+
+ QCString m_token; //!< holds the token
+ TOKENTYPE m_tokenType; //!< type of the token
+
+ // private functions
+ private:
+ void getToken();
+
+ bool parseLevel1();
+ bool parseLevel2();
+ bool parseLevel3();
+ bool parseVar();
+
+ bool evalOperator(const int opId, bool lhs, bool rhs);
+ bool evalVariable(const char *varName);
+ int getOperatorId(const QCString &opName);
+};
+
+#endif
+
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..505e4d1
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,559 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <qstrlist.h>
+#include <qdict.h>
+#include <qlist.h>
+#include <qregexp.h>
+#include "ftextstream.h"
+
+
+/** Abstract base class for any configuration option.
+ */
+class ConfigOption
+{
+ friend class Config;
+
+ public:
+
+ /*! The type of option */
+ enum OptionType
+ {
+ O_Info, //<! A section header
+ O_List, //<! A list of items
+ O_Enum, //<! A fixed set of items
+ O_String, //<! A single item
+ O_Int, //<! An integer value
+ O_Bool, //<! A boolean value
+ O_Obsolete, //<! An obsolete option
+ O_Disabled //<! Disabled compile time option
+ };
+ enum
+ {
+ /*! Maximum length of an option in the config file. Used for
+ * alignment purposes.
+ */
+ MAX_OPTION_LENGTH = 23
+ };
+ ConfigOption(OptionType t) : m_kind(t)
+ {
+ m_spaces.fill(' ',40);
+ }
+ virtual ~ConfigOption()
+ {
+ }
+
+ /*! returns the kind of option this is. */
+ OptionType kind() const { return m_kind; }
+ QCString name() const { return m_name; }
+ QCString docs() const { return m_doc; }
+
+ QCString dependsOn() const { return m_dependency; }
+ void addDependency(const char *dep) { m_dependency = dep; }
+ void setEncoding(const QCString &e) { m_encoding = e; }
+ void setUserComment(const QCString &u) { m_userComment = u; }
+
+ protected:
+ virtual void writeTemplate(FTextStream &t,bool sl,bool upd) = 0;
+ virtual void convertStrToVal() {}
+ virtual void substEnvVars() = 0;
+ virtual void init() {}
+
+ void writeBoolValue(FTextStream &t,bool v);
+ void writeIntValue(FTextStream &t,int i);
+ void writeStringValue(FTextStream &t,QCString &s);
+ void writeStringList(FTextStream &t,QStrList &l);
+
+ QCString m_spaces;
+ QCString m_name;
+ QCString m_doc;
+ QCString m_dependency;
+ QCString m_encoding;
+ QCString m_userComment;
+ OptionType m_kind;
+};
+
+/** Section marker for grouping the configuration options.
+ */
+class ConfigInfo : public ConfigOption
+{
+ public:
+ ConfigInfo(const char *name,const char *doc)
+ : ConfigOption(O_Info)
+ {
+ m_name = name;
+ m_doc = doc;
+ }
+ void writeTemplate(FTextStream &t, bool sl,bool);
+ void substEnvVars() {}
+};
+
+/** Class respresenting a list type option.
+ */
+class ConfigList : public ConfigOption
+{
+ public:
+ enum WidgetType { String, File, Dir, FileAndDir };
+ ConfigList(const char *name,const char *doc)
+ : ConfigOption(O_List)
+ {
+ m_name = name;
+ m_doc = doc;
+ m_widgetType = String;
+ }
+ void addValue(const char *v) { m_value.append(v); }
+ void setWidgetType(WidgetType w) { m_widgetType = w; }
+ WidgetType widgetType() const { return m_widgetType; }
+ QStrList *valueRef() { return &m_value; }
+ void writeTemplate(FTextStream &t,bool sl,bool);
+ void substEnvVars();
+ void init() { m_value.clear(); }
+ private:
+ QStrList m_value;
+ WidgetType m_widgetType;
+};
+
+/** Class representing an enum type option.
+ */
+class ConfigEnum : public ConfigOption
+{
+ public:
+ ConfigEnum(const char *name,const char *doc,const char *defVal)
+ : ConfigOption(O_Enum)
+ {
+ m_name = name;
+ m_doc = doc;
+ m_value = defVal;
+ m_defValue = defVal;
+ }
+ void addValue(const char *v) { m_valueRange.append(v); }
+ QStrListIterator iterator()
+ {
+ return QStrListIterator(m_valueRange);
+ }
+ QCString *valueRef() { return &m_value; }
+ void substEnvVars();
+ void writeTemplate(FTextStream &t,bool sl,bool);
+ void init() { m_value = m_defValue.copy(); }
+
+ private:
+ QStrList m_valueRange;
+ QCString m_value;
+ QCString m_defValue;
+};
+
+/** Class representing a string type option.
+ */
+class ConfigString : public ConfigOption
+{
+ public:
+ enum WidgetType { String, File, Dir, Image };
+ ConfigString(const char *name,const char *doc)
+ : ConfigOption(O_String)
+ {
+ m_name = name;
+ m_doc = doc;
+ m_widgetType = String;
+ }
+ ~ConfigString()
+ {
+ }
+ void setWidgetType(WidgetType w) { m_widgetType = w; }
+ WidgetType widgetType() const { return m_widgetType; }
+ void setDefaultValue(const char *v) { m_defValue = v; }
+ QCString *valueRef() { return &m_value; }
+ void writeTemplate(FTextStream &t,bool sl,bool);
+ void substEnvVars();
+ void init() { m_value = m_defValue.copy(); }
+
+ private:
+ QCString m_value;
+ QCString m_defValue;
+ WidgetType m_widgetType;
+};
+
+/** Class representing an integer type option.
+ */
+class ConfigInt : public ConfigOption
+{
+ public:
+ ConfigInt(const char *name,const char *doc,int minVal,int maxVal,int defVal)
+ : ConfigOption(O_Int)
+ {
+ m_name = name;
+ m_doc = doc;
+ m_value = defVal;
+ m_defValue = defVal;
+ m_minVal = minVal;
+ m_maxVal = maxVal;
+ }
+ QCString *valueStringRef() { return &m_valueString; }
+ int *valueRef() { return &m_value; }
+ int minVal() const { return m_minVal; }
+ int maxVal() const { return m_maxVal; }
+ void convertStrToVal();
+ void substEnvVars();
+ void writeTemplate(FTextStream &t,bool sl,bool upd);
+ void init() { m_value = m_defValue; }
+ private:
+ int m_value;
+ int m_defValue;
+ int m_minVal;
+ int m_maxVal;
+ QCString m_valueString;
+};
+
+/** Class representing a Boolean type option.
+ */
+class ConfigBool : public ConfigOption
+{
+ public:
+ ConfigBool(const char *name,const char *doc,bool defVal)
+ : ConfigOption(O_Bool)
+ {
+ m_name = name;
+ m_doc = doc;
+ m_value = defVal;
+ m_defValue = defVal;
+ }
+ QCString *valueStringRef() { return &m_valueString; }
+ bool *valueRef() { return &m_value; }
+ void convertStrToVal();
+ void substEnvVars();
+ void setValueString(const QCString &v) { m_valueString = v; }
+ void writeTemplate(FTextStream &t,bool sl,bool upd);
+ void init() { m_value = m_defValue; }
+ private:
+ bool m_value;
+ bool m_defValue;
+ QCString m_valueString;
+};
+
+/** Section marker for obsolete options
+ */
+class ConfigObsolete : public ConfigOption
+{
+ public:
+ ConfigObsolete(const char *name) : ConfigOption(O_Obsolete)
+ { m_name = name; }
+ void writeTemplate(FTextStream &,bool,bool);
+ void substEnvVars() {}
+};
+
+/** Section marker for compile time optional options
+ */
+class ConfigDisabled : public ConfigOption
+{
+ public:
+ ConfigDisabled(const char *name) : ConfigOption(O_Disabled)
+ { m_name = name; }
+ void writeTemplate(FTextStream &,bool,bool);
+ void substEnvVars() {}
+};
+
+
+// some convenience macros for access the config options
+#define Config_getString(val) Config::instance()->getString(__FILE__,__LINE__,val)
+#define Config_getInt(val) Config::instance()->getInt(__FILE__,__LINE__,val)
+#define Config_getList(val) Config::instance()->getList(__FILE__,__LINE__,val)
+#define Config_getEnum(val) Config::instance()->getEnum(__FILE__,__LINE__,val)
+#define Config_getBool(val) Config::instance()->getBool(__FILE__,__LINE__,val)
+
+/** Singleton for configuration variables.
+ *
+ * This object holds the global static variables
+ * read from a user-supplied configuration file.
+ * The static member instance() can be used to get
+ * a pointer to the one and only instance.
+ *
+ * Set all variables to their default values by
+ * calling Config::instance()->init()
+ *
+ */
+class Config
+{
+ public:
+ /////////////////////////////
+ // public API
+ /////////////////////////////
+
+ /*! Returns the one and only instance of this class */
+ static Config *instance()
+ {
+ if (m_instance==0) m_instance = new Config;
+ return m_instance;
+ }
+ /*! Delete the instance */
+ static void deleteInstance()
+ {
+ delete m_instance;
+ m_instance=0;
+ }
+
+ /*! Returns an iterator that can by used to iterate over the
+ * configuration options.
+ */
+ QListIterator<ConfigOption> iterator()
+ {
+ return QListIterator<ConfigOption>(*m_options);
+ }
+
+ /*!
+ * @name Getting configuration values.
+ * @{
+ */
+
+ /*! Returns the value of the string option with name \a fileName.
+ * The arguments \a num and \a name are for debugging purposes only.
+ * There is a convenience function Config_getString() for this.
+ */
+ QCString &getString(const char *fileName,int num,const char *name) const;
+
+ /*! Returns the value of the list option with name \a fileName.
+ * The arguments \a num and \a name are for debugging purposes only.
+ * There is a convenience function Config_getList() for this.
+ */
+ QStrList &getList(const char *fileName,int num,const char *name) const;
+
+ /*! Returns the value of the enum option with name \a fileName.
+ * The arguments \a num and \a name are for debugging purposes only.
+ * There is a convenience function Config_getEnum() for this.
+ */
+ QCString &getEnum(const char *fileName,int num,const char *name) const;
+
+ /*! Returns the value of the integer option with name \a fileName.
+ * The arguments \a num and \a name are for debugging purposes only.
+ * There is a convenience function Config_getInt() for this.
+ */
+ int &getInt(const char *fileName,int num,const char *name) const;
+
+ /*! Returns the value of the boolean option with name \a fileName.
+ * The arguments \a num and \a name are for debugging purposes only.
+ * There is a convenience function Config_getBool() for this.
+ */
+ bool &getBool(const char *fileName,int num,const char *name) const;
+
+ /*! Returns the ConfigOption corresponding with \a name or 0 if
+ * the option is not supported.
+ */
+ ConfigOption *get(const char *name) const
+ {
+ return m_dict->find(name);
+ }
+ /* @} */
+
+ /*!
+ * @name Adding configuration options.
+ * @{
+ */
+
+ /*! Starts a new configuration section with \a name and description \a doc.
+ * \returns An object representing the option.
+ */
+ ConfigInfo *addInfo(const char *name,const char *doc)
+ {
+ ConfigInfo *result = new ConfigInfo(name,doc);
+ m_options->append(result);
+ return result;
+ }
+
+ /*! Adds a new string option with \a name and documentation \a doc.
+ * \returns An object representing the option.
+ */
+ ConfigString *addString(const char *name,
+ const char *doc)
+ {
+ ConfigString *result = new ConfigString(name,doc);
+ m_options->append(result);
+ m_dict->insert(name,result);
+ return result;
+ }
+
+ /*! Adds a new enumeration option with \a name and documentation \a doc
+ * and initial value \a defVal.
+ * \returns An object representing the option.
+ */
+ ConfigEnum *addEnum(const char *name,
+ const char *doc,
+ const char *defVal)
+ {
+ ConfigEnum *result = new ConfigEnum(name,doc,defVal);
+ m_options->append(result);
+ m_dict->insert(name,result);
+ return result;
+ }
+
+ /*! Adds a new string option with \a name and documentation \a doc.
+ * \returns An object representing the option.
+ */
+ ConfigList *addList(const char *name,
+ const char *doc)
+ {
+ ConfigList *result = new ConfigList(name,doc);
+ m_options->append(result);
+ m_dict->insert(name,result);
+ return result;
+ }
+
+ /*! Adds a new integer option with \a name and documentation \a doc.
+ * The integer has a range between \a minVal and \a maxVal and a
+ * default value of \a defVal.
+ * \returns An object representing the option.
+ */
+ ConfigInt *addInt(const char *name,
+ const char *doc,
+ int minVal,int maxVal,int defVal)
+ {
+ ConfigInt *result = new ConfigInt(name,doc,minVal,maxVal,defVal);
+ m_options->append(result);
+ m_dict->insert(name,result);
+ return result;
+ }
+
+ /*! Adds a new boolean option with \a name and documentation \a doc.
+ * The boolean has a default value of \a defVal.
+ * \returns An object representing the option.
+ */
+ ConfigBool *addBool(const char *name,
+ const char *doc,
+ bool defVal)
+ {
+ ConfigBool *result = new ConfigBool(name,doc,defVal);
+ m_options->append(result);
+ m_dict->insert(name,result);
+ return result;
+ }
+ /*! Adds an option that has become obsolete. */
+ ConfigOption *addObsolete(const char *name)
+ {
+ ConfigObsolete *option = new ConfigObsolete(name);
+ m_dict->insert(name,option);
+ m_obsolete->append(option);
+ return option;
+ }
+ /*! Adds an option that has been disabled at compile time. */
+ ConfigOption *addDisabled(const char *name)
+ {
+ ConfigDisabled *option = new ConfigDisabled(name);
+ m_dict->insert(name,option);
+ m_disabled->append(option);
+ return option;
+ }
+ /*! @} */
+
+ /*! Writes a template configuration to stream \a t. If \a shortIndex
+ * is \c TRUE the description of each configuration option will
+ * be omitted.
+ */
+ void writeTemplate(FTextStream &t,bool shortIndex,bool updateOnly);
+
+ void setHeader(const char *header) { m_header = header; }
+
+ /////////////////////////////
+ // internal API
+ /////////////////////////////
+
+ /*! Converts the string values read from the configuration file
+ * to real values for non-string type options (like int, and bools)
+ */
+ void convertStrToVal();
+
+ /*! Replaces references to environment variable by the actual value
+ * of the environment variable.
+ */
+ void substituteEnvironmentVars();
+
+ /*! Checks if the values of the variable are correct, adjusts them
+ * if needed, and report any errors.
+ */
+ void check();
+
+ /*! Initialize config variables to their default value */
+ void init();
+
+ /*! Parse a configuration data in string \a str.
+ * \returns TRUE if successful, or FALSE if the string could not be
+ * parsed.
+ */
+ //bool parseString(const char *fn,const char *str);
+ bool parseString(const char *fn,const char *str,bool upd = FALSE);
+
+ /*! Parse a configuration file with name \a fn.
+ * \returns TRUE if successful, FALSE if the file could not be
+ * opened or read.
+ */
+ bool parse(const char *fn,bool upd = FALSE);
+
+ /*! Called from the constructor, will add doxygen's default options
+ * to the configuration object
+ */
+ void create();
+
+ /*! Append user comment
+ */
+ void appendUserComment(const QCString &u)
+ {
+ m_userComment += u;
+ }
+ /*! Take the user comment and reset it internally
+ * \returns user comment
+ */
+ QCString takeUserComment()
+ {
+ QCString result=m_userComment;
+ m_userComment.resize(0);
+ return result.replace(QRegExp("\r"),"");
+ }
+
+ protected:
+
+ Config()
+ {
+ m_options = new QList<ConfigOption>;
+ m_obsolete = new QList<ConfigOption>;
+ m_disabled = new QList<ConfigOption>;
+ m_dict = new QDict<ConfigOption>(257);
+ m_options->setAutoDelete(TRUE);
+ m_obsolete->setAutoDelete(TRUE);
+ m_initialized = FALSE;
+ create();
+ }
+ ~Config()
+ {
+ delete m_options;
+ delete m_obsolete;
+ delete m_disabled;
+ delete m_dict;
+ }
+
+ private:
+ void checkFileName(const char *);
+ QList<ConfigOption> *m_options;
+ QList<ConfigOption> *m_obsolete;
+ QList<ConfigOption> *m_disabled;
+ QDict<ConfigOption> *m_dict;
+ static Config *m_instance;
+ QCString m_userComment;
+ bool m_initialized;
+ QCString m_header;
+};
+
+#endif
diff --git a/src/config.l b/src/config.l
new file mode 100644
index 0000000..a237faf
--- /dev/null
+++ b/src/config.l
@@ -0,0 +1,1772 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qstack.h>
+#include <qglobal.h>
+
+#include "config.h"
+#include "version.h"
+#include "portable.h"
+#include "util.h"
+#include "message.h"
+
+#include "lang_cfg.h"
+#include "configoptions.h"
+
+#undef Config_getString
+#undef Config_getInt
+#undef Config_getList
+#undef Config_getEnum
+#undef Config_getBool
+
+#define YY_NO_INPUT 1
+
+// use in-class definitions
+#define Config_getString(val) getString(__FILE__,__LINE__,val)
+#define Config_getInt(val) getInt(__FILE__,__LINE__,val)
+#define Config_getList(val) getList(__FILE__,__LINE__,val)
+#define Config_getEnum(val) getEnum(__FILE__,__LINE__,val)
+#define Config_getBool(val) getBool(__FILE__,__LINE__,val)
+
+void config_err(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+void config_warn(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+static QCString configStringRecode(
+ const QCString &str,
+ const char *fromEncoding,
+ const char *toEncoding);
+
+#define MAX_INCLUDE_DEPTH 10
+#define YY_NEVER_INTERACTIVE 1
+
+/* -----------------------------------------------------------------
+ */
+static QCString convertToComment(const QCString &s, const QCString &u)
+{
+ //printf("convertToComment(%s)=%s\n",s.data(),u.data());
+ QCString result;
+ if (!s.isEmpty())
+ {
+ QCString tmp=s.stripWhiteSpace();
+ char *p=tmp.data();
+ char c;
+ result+="#";
+ if (*p && *p!='\n')
+ result+=" ";
+ while ((c=*p++))
+ {
+ if (c=='\n')
+ {
+ result+="\n#";
+ if (*p && *p!='\n')
+ result+=" ";
+ }
+ else result+=c;
+ }
+ result+='\n';
+ }
+ if (!u.isEmpty())
+ {
+ if (!result.isEmpty()) result+='\n';
+ result+= u;
+ }
+ return result;
+}
+
+void ConfigOption::writeBoolValue(FTextStream &t,bool v)
+{
+ t << " ";
+ if (v) t << "YES"; else t << "NO";
+}
+
+void ConfigOption::writeIntValue(FTextStream &t,int i)
+{
+ t << " " << i;
+}
+
+void ConfigOption::writeStringValue(FTextStream &t,QCString &s)
+{
+ char c;
+ bool needsEscaping=FALSE;
+ // convert the string back to it original encoding
+ QCString se = configStringRecode(s,"UTF-8",m_encoding);
+ const char *p=se.data();
+ if (p)
+ {
+ t << " ";
+ while ((c=*p++)!=0 && !needsEscaping)
+ needsEscaping = (c==' ' || c=='\n' || c=='\t' || c=='"' || c=='#');
+ if (needsEscaping)
+ {
+ t << "\"";
+ p=se.data();
+ while (*p)
+ {
+ if (*p==' ' && *(p+1)=='\0') break; // skip inserted space at the end
+ if (*p=='"') t << "\\"; // escape quotes
+ t << *p++;
+ }
+ t << "\"";
+ }
+ else
+ {
+ t << se;
+ }
+ }
+}
+
+void ConfigOption::writeStringList(FTextStream &t,QStrList &l)
+{
+ const char *p = l.first();
+ bool first=TRUE;
+ while (p)
+ {
+ QCString s=p;
+ if (!first)
+ t << " ";
+ first=FALSE;
+ writeStringValue(t,s);
+ p = l.next();
+ if (p) t << " \\" << endl;
+ }
+}
+
+/* -----------------------------------------------------------------
+ */
+
+Config *Config::m_instance = 0;
+
+void ConfigInt::convertStrToVal()
+{
+ if (!m_valueString.isEmpty())
+ {
+ bool ok;
+ int val = m_valueString.toInt(&ok);
+ if (!ok || val<m_minVal || val>m_maxVal)
+ {
+ config_warn("Warning: argument `%s' for option %s is not a valid number in the range [%d..%d]!\n"
+ "Using the default: %d!\n",m_valueString.data(),m_name.data(),m_minVal,m_maxVal,m_value);
+ }
+ else
+ {
+ m_value=val;
+ }
+ }
+}
+
+void ConfigBool::convertStrToVal()
+{
+ QCString val = m_valueString.stripWhiteSpace().lower();
+ if (!val.isEmpty())
+ {
+ if (val=="yes" || val=="true" || val=="1" || val=="all")
+ {
+ m_value=TRUE;
+ }
+ else if (val=="no" || val=="false" || val=="0" || val=="none")
+ {
+ m_value=FALSE;
+ }
+ else
+ {
+ config_warn("Warning: argument `%s' for option %s is not a valid boolean value\n"
+ "Using the default: %s!\n",m_valueString.data(),m_name.data(),m_value?"YES":"NO");
+ }
+ }
+}
+
+QCString &Config::getString(const char *fileName,int num,const char *name) const
+{
+ ConfigOption *opt = m_dict->find(name);
+ if (opt==0)
+ {
+ config_err("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
+ exit(1);
+ }
+ else if (opt->kind()!=ConfigOption::O_String)
+ {
+ config_err("%s<%d>: Internal error: Requested option %s not of string type!\n",fileName,num,name);
+ exit(1);
+ }
+ return *((ConfigString *)opt)->valueRef();
+}
+
+QStrList &Config::getList(const char *fileName,int num,const char *name) const
+{
+ ConfigOption *opt = m_dict->find(name);
+ if (opt==0)
+ {
+ config_err("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
+ exit(1);
+ }
+ else if (opt->kind()!=ConfigOption::O_List)
+ {
+ config_err("%d<%d>: Internal error: Requested option %s not of list type!\n",fileName,num,name);
+ exit(1);
+ }
+ return *((ConfigList *)opt)->valueRef();
+}
+
+QCString &Config::getEnum(const char *fileName,int num,const char *name) const
+{
+ ConfigOption *opt = m_dict->find(name);
+ if (opt==0)
+ {
+ config_err("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
+ exit(1);
+ }
+ else if (opt->kind()!=ConfigOption::O_Enum)
+ {
+ config_err("%s<%d>: Internal error: Requested option %s not of enum type!\n",fileName,num,name);
+ exit(1);
+ }
+ return *((ConfigEnum *)opt)->valueRef();
+}
+
+int &Config::getInt(const char *fileName,int num,const char *name) const
+{
+ ConfigOption *opt = m_dict->find(name);
+ if (opt==0)
+ {
+ config_err("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
+ exit(1);
+ }
+ else if (opt->kind()!=ConfigOption::O_Int)
+ {
+ config_err("%s<%d>: Internal error: Requested option %s not of integer type!\n",fileName,num,name);
+ exit(1);
+ }
+ return *((ConfigInt *)opt)->valueRef();
+}
+
+bool &Config::getBool(const char *fileName,int num,const char *name) const
+{
+ ConfigOption *opt = m_dict->find(name);
+ if (opt==0)
+ {
+ config_err("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
+ exit(1);
+ }
+ else if (opt->kind()!=ConfigOption::O_Bool)
+ {
+ config_err("%s<%d>: Internal error: Requested option %s not of boolean type!\n",fileName,num,name);
+ exit(1);
+ }
+ return *((ConfigBool *)opt)->valueRef();
+}
+
+/* ------------------------------------------ */
+
+void ConfigInfo::writeTemplate(FTextStream &t, bool sl,bool)
+{
+ if (!sl)
+ {
+ t << "\n";
+ }
+ t << "#---------------------------------------------------------------------------\n";
+ t << "# " << m_doc << endl;
+ t << "#---------------------------------------------------------------------------\n";
+}
+
+void ConfigList::writeTemplate(FTextStream &t,bool sl,bool)
+{
+ if (!sl)
+ {
+ t << endl;
+ t << convertToComment(m_doc, m_userComment);
+ t << endl;
+ }
+ else if (!m_userComment.isEmpty())
+ {
+ t << convertToComment("", m_userComment);
+ }
+ t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
+ writeStringList(t,m_value);
+ t << "\n";
+}
+
+void ConfigEnum::writeTemplate(FTextStream &t,bool sl,bool)
+{
+ if (!sl)
+ {
+ t << endl;
+ t << convertToComment(m_doc, m_userComment);
+ t << endl;
+ }
+ else if (!m_userComment.isEmpty())
+ {
+ t << convertToComment("", m_userComment);
+ }
+ t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
+ writeStringValue(t,m_value);
+ t << "\n";
+}
+
+void ConfigString::writeTemplate(FTextStream &t,bool sl,bool)
+{
+ if (!sl)
+ {
+ t << endl;
+ t << convertToComment(m_doc, m_userComment);
+ t << endl;
+ }
+ else if (!m_userComment.isEmpty())
+ {
+ t << convertToComment("", m_userComment);
+ }
+ t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
+ writeStringValue(t,m_value);
+ t << "\n";
+}
+
+void ConfigInt::writeTemplate(FTextStream &t,bool sl,bool upd)
+{
+ if (!sl)
+ {
+ t << endl;
+ t << convertToComment(m_doc, m_userComment);
+ t << endl;
+ }
+ else if (!m_userComment.isEmpty())
+ {
+ t << convertToComment("", m_userComment);
+ }
+ t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
+ if (upd && !m_valueString.isEmpty())
+ {
+ writeStringValue(t,m_valueString);
+ }
+ else
+ {
+ writeIntValue(t,m_value);
+ }
+ t << "\n";
+}
+
+void ConfigBool::writeTemplate(FTextStream &t,bool sl,bool upd)
+{
+ if (!sl)
+ {
+ t << endl;
+ t << convertToComment(m_doc, m_userComment);
+ t << endl;
+ }
+ else if (!m_userComment.isEmpty())
+ {
+ t << convertToComment("", m_userComment);
+ }
+ t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
+ if (upd && !m_valueString.isEmpty())
+ {
+ writeStringValue(t,m_valueString);
+ }
+ else
+ {
+ writeBoolValue(t,m_value);
+ }
+ t << "\n";
+}
+
+void ConfigObsolete::writeTemplate(FTextStream &,bool,bool) {}
+void ConfigDisabled::writeTemplate(FTextStream &,bool,bool) {}
+
+/* -----------------------------------------------------------------
+ *
+ * static variables
+ */
+
+struct ConfigFileState
+{
+ int lineNr;
+ FILE *filePtr;
+ YY_BUFFER_STATE oldState;
+ YY_BUFFER_STATE newState;
+ QCString fileName;
+};
+
+static const char *inputString;
+static int inputPosition;
+static int yyLineNr;
+static QCString yyFileName;
+static QCString tmpString;
+static QCString *s=0;
+static bool *b=0;
+static QStrList *l=0;
+static int lastState;
+static QCString elemStr;
+static QCString includeName;
+static QStrList includePathList;
+static QStack<ConfigFileState> includeStack;
+static int includeDepth;
+static bool config_upd = FALSE;
+
+static QCString tabSizeString;
+static QCString maxInitLinesString;
+static QCString colsInAlphaIndexString;
+static QCString enumValuesPerLineString;
+static QCString treeViewWidthString;
+static QCString maxDotGraphWidthString;
+static QCString maxDotGraphHeightString;
+static QCString encoding;
+
+static Config *config;
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ // no file included
+ if (includeStack.isEmpty())
+ {
+ int c=0;
+ if (inputString==0) return c;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+ }
+ else
+ {
+ //assert(includeStack.current()->newState==YY_CURRENT_BUFFER);
+ return (int)fread(buf,1,max_size,includeStack.current()->filePtr);
+ }
+}
+
+
+static QCString configStringRecode(
+ const QCString &str,
+ const char *fromEncoding,
+ const char *toEncoding)
+{
+ QCString inputEncoding = fromEncoding;
+ QCString outputEncoding = toEncoding;
+ if (inputEncoding.isEmpty() || outputEncoding.isEmpty() || inputEncoding==outputEncoding) return str;
+ int inputSize=str.length();
+ int outputSize=inputSize*4+1;
+ QCString output(outputSize);
+ void *cd = portable_iconv_open(outputEncoding,inputEncoding);
+ if (cd==(void *)(-1))
+ {
+ fprintf(stderr,"Error: unsupported character conversion: '%s'->'%s'\n",
+ inputEncoding.data(),outputEncoding.data());
+ exit(1);
+ }
+ size_t iLeft=(size_t)inputSize;
+ size_t oLeft=(size_t)outputSize;
+ char *inputPtr = str.data();
+ char *outputPtr = output.data();
+ if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
+ {
+ outputSize-=(int)oLeft;
+ output.resize(outputSize+1);
+ output.at(outputSize)='\0';
+ //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,srcBuf.data());
+ }
+ else
+ {
+ fprintf(stderr,"Error: failed to translate characters from %s to %s: %s\n",
+ inputEncoding.data(),outputEncoding.data(),strerror(errno));
+ exit(1);
+ }
+ portable_iconv_close(cd);
+ return output;
+}
+
+static void checkEncoding()
+{
+ ConfigString *option = (ConfigString*)config->get("DOXYFILE_ENCODING");
+ encoding = *option->valueRef();
+}
+
+static FILE *tryPath(const char *path,const char *fileName)
+{
+ QCString absName=(path ? (QCString)path+"/"+fileName : (QCString)fileName);
+ QFileInfo fi(absName);
+ if (fi.exists() && fi.isFile())
+ {
+ FILE *f=portable_fopen(absName,"r");
+ if (!f) config_err("Error: could not open file %s for reading\n",absName.data());
+ return f;
+ }
+ return 0;
+}
+
+static void substEnvVarsInStrList(QStrList &sl);
+static void substEnvVarsInString(QCString &s);
+
+static FILE *findFile(const char *fileName)
+{
+ if (fileName==0)
+ {
+ return 0;
+ }
+ if (portable_isAbsolutePath(fileName))
+ {
+ return tryPath(NULL, fileName);
+ }
+ substEnvVarsInStrList(includePathList);
+ char *s=includePathList.first();
+ while (s) // try each of the include paths
+ {
+ FILE *f = tryPath(s,fileName);
+ if (f) return f;
+ s=includePathList.next();
+ }
+ // try cwd if includePathList fails
+ return tryPath(".",fileName);
+}
+
+static void readIncludeFile(const char *incName)
+{
+ if (includeDepth==MAX_INCLUDE_DEPTH) {
+ config_err("Error: maximum include depth (%d) reached, %s is not included. Aborting...\n",
+ MAX_INCLUDE_DEPTH,incName);
+ exit(1);
+ }
+
+ QCString inc = incName;
+ substEnvVarsInString(inc);
+ inc = inc.stripWhiteSpace();
+ uint incLen = inc.length();
+ if (incLen>0 && inc.at(0)=='"' && inc.at(incLen-1)=='"') // strip quotes
+ {
+ inc=inc.mid(1,incLen-2);
+ }
+
+ FILE *f;
+
+ if ((f=findFile(inc))) // see if the include file can be found
+ {
+ // For debugging
+#if SHOW_INCLUDES
+ for (i=0;i<includeStack.count();i++) msg(" ");
+ msg("@INCLUDE = %s: parsing...\n",inc.data());
+#endif
+
+ // store the state of the old file
+ ConfigFileState *fs=new ConfigFileState;
+ fs->oldState=YY_CURRENT_BUFFER;
+ fs->lineNr=yyLineNr;
+ fs->fileName=yyFileName;
+ fs->filePtr=f;
+ // push the state on the stack
+ includeStack.push(fs);
+ // set the scanner to the include file
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ fs->newState=YY_CURRENT_BUFFER;
+ yyFileName=inc;
+ includeDepth++;
+ }
+ else
+ {
+ config_err("Error: @INCLUDE = %s: not found!\n",inc.data());
+ exit(1);
+ }
+}
+
+
+%}
+
+%option nounput
+%option noyywrap
+
+%x Start
+%x SkipComment
+%x SkipInvalid
+%x GetString
+%x GetBool
+%x GetStrList
+%x GetQuotedString
+%x GetEnvVar
+%x Include
+
+%%
+
+<*>\0x0d
+<Start,GetString,GetStrList,GetBool,SkipInvalid>"##".*"\n" { config->appendUserComment(yytext);}
+<Start,GetString,GetStrList,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QCString cmd=yytext;
+ cmd=cmd.left(cmd.length()-1).stripWhiteSpace();
+ ConfigOption *option = config->get(cmd);
+ if (option==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ yytext,yyLineNr,yyFileName.data());
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ option->setUserComment(config->takeUserComment());
+ option->setEncoding(encoding);
+ switch(option->kind())
+ {
+ case ConfigOption::O_Info:
+ // shouldn't get here!
+ BEGIN(SkipInvalid);
+ break;
+ case ConfigOption::O_List:
+ l = ((ConfigList *)option)->valueRef();
+ l->clear();
+ elemStr="";
+ BEGIN(GetStrList);
+ break;
+ case ConfigOption::O_Enum:
+ s = ((ConfigEnum *)option)->valueRef();
+ s->resize(0);
+ BEGIN(GetString);
+ break;
+ case ConfigOption::O_String:
+ s = ((ConfigString *)option)->valueRef();
+ s->resize(0);
+ BEGIN(GetString);
+ break;
+ case ConfigOption::O_Int:
+ s = ((ConfigInt *)option)->valueStringRef();
+ s->resize(0);
+ BEGIN(GetString);
+ break;
+ case ConfigOption::O_Bool:
+ s = ((ConfigBool *)option)->valueStringRef();
+ s->resize(0);
+ BEGIN(GetString);
+ break;
+ case ConfigOption::O_Obsolete:
+ if (config_upd)
+ {
+ config_err("Warning: Tag `%s' at line %d of file `%s' has become obsolete.\n"
+ " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data());
+ }
+ else
+ {
+ config_err("Warning: Tag `%s' at line %d of file `%s' has become obsolete.\n"
+ " To avoid this warning please remove this line from your configuration "
+ "file or upgrade it using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data());
+ }
+ BEGIN(SkipInvalid);
+ break;
+ case ConfigOption::O_Disabled:
+ if (config_upd)
+ {
+ config_err("Warning: Tag `%s' at line %d of file `%s' belongs to an option that was not enabled at compile time.\n"
+ " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data());
+ }
+ else
+ {
+ config_err("Warning: Tag `%s' at line %d of file `%s' belongs to an option that was not enabled at compile time.\n"
+ " To avoid this warning please remove this line from your configuration "
+ "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data());
+ }
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QCString cmd=yytext;
+ cmd=cmd.left(cmd.length()-2).stripWhiteSpace();
+ ConfigOption *option = config->get(cmd);
+ if (option==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ yytext,yyLineNr,yyFileName.data());
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ option->setUserComment(config->takeUserComment());
+ switch(option->kind())
+ {
+ case ConfigOption::O_Info:
+ // shouldn't get here!
+ BEGIN(SkipInvalid);
+ break;
+ case ConfigOption::O_List:
+ l = ((ConfigList *)option)->valueRef();
+ elemStr="";
+ BEGIN(GetStrList);
+ break;
+ case ConfigOption::O_Enum:
+ case ConfigOption::O_String:
+ case ConfigOption::O_Int:
+ case ConfigOption::O_Bool:
+ config_err("Warning: operator += not supported for `%s'. Ignoring line at line %d, file %s\n",
+ yytext,yyLineNr,yyFileName.data());
+ BEGIN(SkipInvalid);
+ break;
+ case ConfigOption::O_Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data());
+ BEGIN(SkipInvalid);
+ break;
+ case ConfigOption::O_Disabled:
+ config_err("Warning: Tag `%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n"
+ "To avoid this warning please remove this line from your configuration "
+ "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data());
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&includePathList; l->clear(); elemStr=""; }
+ /* include a config file */
+<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
+<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
+ readIncludeFile(configStringRecode(yytext,encoding,"UTF-8"));
+ BEGIN(Start);
+ }
+<<EOF>> {
+ //printf("End of include file\n");
+ //printf("Include stack depth=%d\n",g_includeStack.count());
+ if (includeStack.isEmpty())
+ {
+ //printf("Terminating scanner!\n");
+ yyterminate();
+ }
+ else
+ {
+ ConfigFileState *fs=includeStack.pop();
+ fclose(fs->filePtr);
+ YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer( fs->oldState );
+ yy_delete_buffer( oldBuf );
+ yyLineNr=fs->lineNr;
+ yyFileName=fs->fileName;
+ delete fs; fs=0;
+ includeDepth--;
+ }
+ }
+
+<Start>[a-z_A-Z0-9]+ { config_err("Warning: ignoring unknown tag `%s' at line %d, file %s\n",yytext,yyLineNr,yyFileName.data()); }
+<GetString,GetBool,SkipInvalid>\n { yyLineNr++; BEGIN(Start); }
+<GetStrList>\n {
+ yyLineNr++;
+ if (!elemStr.isEmpty())
+ {
+ //printf("elemStr1=`%s'\n",elemStr.data());
+ l->append(elemStr);
+ }
+ BEGIN(Start);
+ }
+<GetStrList>[ \t]+ {
+ if (!elemStr.isEmpty())
+ {
+ //printf("elemStr2=`%s'\n",elemStr.data());
+ l->append(elemStr);
+ }
+ elemStr.resize(0);
+ }
+<GetString>[^ \"\t\r\n]+ { (*s)+=configStringRecode(yytext,encoding,"UTF-8");
+ checkEncoding();
+ }
+<GetString,GetStrList,SkipInvalid>"\"" { lastState=YY_START;
+ BEGIN(GetQuotedString);
+ tmpString.resize(0);
+ }
+<GetQuotedString>"\""|"\n" {
+ // we add a bogus space to signal that the string was quoted. This space will be stripped later on.
+ tmpString+=" ";
+ //printf("Quoted String = `%s'\n",tmpString.data());
+ if (lastState==GetString)
+ {
+ (*s)+=configStringRecode(tmpString,encoding,"UTF-8");
+ checkEncoding();
+ }
+ else
+ {
+ elemStr+=configStringRecode(tmpString,encoding,"UTF-8");
+ }
+ if (*yytext=='\n')
+ {
+ config_err("Warning: Missing end quote (\") on line %d, file %s\n",yyLineNr,yyFileName.data());
+ yyLineNr++;
+ }
+ BEGIN(lastState);
+ }
+<GetQuotedString>"\\\"" {
+ tmpString+='"';
+ }
+<GetQuotedString>. { tmpString+=*yytext; }
+<GetBool>[a-zA-Z]+ {
+ QCString bs=yytext;
+ bs=bs.upper();
+ if (bs=="YES" || bs=="1")
+ *b=TRUE;
+ else if (bs=="NO" || bs=="0")
+ *b=FALSE;
+ else
+ {
+ *b=FALSE;
+ config_warn("Warning: Invalid value `%s' for "
+ "boolean tag in line %d, file %s; use YES or NO\n",
+ bs.data(),yyLineNr,yyFileName.data());
+ }
+ }
+<GetStrList>[^ \#\"\t\r\n]+ {
+ elemStr+=configStringRecode(yytext,encoding,"UTF-8");
+ }
+<SkipComment>\n { yyLineNr++; BEGIN(Start); }
+<SkipComment>\\[ \r\t]*\n { yyLineNr++; BEGIN(Start); }
+<*>\\[ \r\t]*\n { yyLineNr++; }
+<*>.
+<*>\n { yyLineNr++ ; }
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+void Config::writeTemplate(FTextStream &t,bool sl,bool upd)
+{
+ t << "# Doxyfile " << versionString << endl << endl;
+ if (!sl)
+ {
+ t << convertToComment(m_header,"");
+ }
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (;(option=it.current());++it)
+ {
+ option->writeTemplate(t,sl,upd);
+ }
+ /* print last lines of user comment that were at the end of the file */
+ if (m_userComment)
+ {
+ t << "\n";
+ t << takeUserComment();
+ }
+}
+
+void Config::convertStrToVal()
+{
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (;(option=it.current());++it)
+ {
+ option->convertStrToVal();
+ }
+}
+
+static void substEnvVarsInString(QCString &s)
+{
+ static QRegExp re("\\$\\([a-z_A-Z0-9.-]+\\)");
+ static QRegExp re2("\\$\\([a-z_A-Z0-9.-]+\\([a-z_A-Z0-9.-]+\\)\\)"); // For e.g. PROGRAMFILES(X86)
+ if (s.isEmpty()) return;
+ int p=0;
+ int i,l;
+ //printf("substEnvVarInString(%s) start\n",s.data());
+ while ((i=re.match(s,p,&l))!=-1 || (i=re2.match(s,p,&l))!=-1)
+ {
+ //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).data());
+ QCString env=portable_getenv(s.mid(i+2,l-3));
+ substEnvVarsInString(env); // recursively expand variables if needed.
+ s = s.left(i)+env+s.right(s.length()-i-l);
+ p=i+env.length(); // next time start at the end of the expanded string
+ }
+ s=s.stripWhiteSpace(); // to strip the bogus space that was added when an argument
+ // has quotes
+ //printf("substEnvVarInString(%s) end\n",s.data());
+}
+
+static void substEnvVarsInStrList(QStrList &sl)
+{
+ char *s = sl.first();
+ while (s)
+ {
+ QCString result(s);
+ // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
+ bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1);
+ // here we strip the quote again
+ substEnvVarsInString(result);
+
+ //printf("Result %s was quoted=%d\n",result.data(),wasQuoted);
+
+ if (!wasQuoted) /* as a result of the expansion, a single string
+ may have expanded into a list, which we'll
+ add to sl. If the original string already
+ contained multiple elements no further
+ splitting is done to allow quoted items with spaces! */
+ {
+ int l=result.length();
+ int i,p=0;
+ // skip spaces
+ // search for a "word"
+ for (i=0;i<l;i++)
+ {
+ char c=0;
+ // skip until start of new word
+ while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++;
+ p=i; // p marks the start index of the word
+ // skip until end of a word
+ while (i<l && ((c=result.at(i))!=' ' && c!='\t' && c!='"')) i++;
+ if (i<l) // not at the end of the string
+ {
+ if (c=='"') // word within quotes
+ {
+ p=i+1;
+ for (i++;i<l;i++)
+ {
+ c=result.at(i);
+ if (c=='"') // end quote
+ {
+ // replace the string in the list and go to the next item.
+ sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item.
+ sl.next(); // current item is now the old item
+ p=i+1;
+ break;
+ }
+ else if (c=='\\') // skip escaped stuff
+ {
+ i++;
+ }
+ }
+ }
+ else if (c==' ' || c=='\t') // separator
+ {
+ // replace the string in the list and go to the next item.
+ sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item.
+ sl.next(); // current item is now the old item
+ p=i+1;
+ }
+ }
+ }
+ if (p!=l) // add the leftover as a string
+ {
+ // replace the string in the list and go to the next item.
+ sl.insert(sl.at(),result.right(l-p)); // insert new item before current item.
+ sl.next(); // current item is now the old item
+ }
+ }
+ else // just goto the next element in the list
+ {
+ sl.insert(sl.at(),result);
+ sl.next();
+ }
+ // remove the old unexpanded string from the list
+ int i=sl.at();
+ sl.remove(); // current item index changes if the last element is removed.
+ if (sl.at()==i) // not last item
+ s = sl.current();
+ else // just removed last item
+ s = 0;
+ }
+}
+
+void ConfigString::substEnvVars()
+{
+ substEnvVarsInString(m_value);
+}
+
+void ConfigList::substEnvVars()
+{
+ substEnvVarsInStrList(m_value);
+}
+
+void ConfigBool::substEnvVars()
+{
+ substEnvVarsInString(m_valueString);
+}
+
+void ConfigInt::substEnvVars()
+{
+ substEnvVarsInString(m_valueString);
+}
+
+void ConfigEnum::substEnvVars()
+{
+ substEnvVarsInString(m_value);
+}
+
+void Config::substituteEnvironmentVars()
+{
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (;(option=it.current());++it)
+ {
+ option->substEnvVars();
+ }
+}
+
+static void cleanUpPaths(QStrList &str)
+{
+ char *sfp = str.first();
+ while (sfp)
+ {
+ register char *p = sfp;
+ if (p)
+ {
+ char c;
+ while ((c=*p))
+ {
+ if (c=='\\') *p='/';
+ p++;
+ }
+ }
+ QCString path = sfp;
+ if ((path.at(0)!='/' && (path.length()<=2 || path.at(1)!=':')) ||
+ path.at(path.length()-1)!='/'
+ )
+ {
+ QFileInfo fi(path);
+ if (fi.exists() && fi.isDir())
+ {
+ int i = str.at();
+ str.remove();
+ if (str.at()==i) // did not remove last item
+ str.insert(i,fi.absFilePath().utf8()+"/");
+ else
+ str.append(fi.absFilePath().utf8()+"/");
+ }
+ }
+ sfp = str.next();
+ }
+}
+
+void Config::checkFileName(const char *optionName)
+{
+ QCString &s = Config_getString(optionName);
+ QCString val = s.stripWhiteSpace().lower();
+ if ((val=="yes" || val=="true" || val=="1" || val=="all") ||
+ (val=="no" || val=="false" || val=="0" || val=="none"))
+ {
+ config_err("Error: file name expected for option %s, got %s instead. Ignoring...\n",optionName,s.data());
+ s=""; // note tihe use of &s above: this will change the option value!
+ }
+}
+
+void Config::check()
+{
+ //if (!projectName.isEmpty())
+ //{
+ // projectName[0]=toupper(projectName[0]);
+ //}
+
+ QCString &warnFormat = Config_getString("WARN_FORMAT");
+ if (warnFormat.stripWhiteSpace().isEmpty())
+ {
+ warnFormat="$file:$line $text";
+ }
+ else
+ {
+ if (warnFormat.find("$file")==-1)
+ {
+ config_err("Warning: warning format does not contain a $file tag!\n");
+ }
+ if (warnFormat.find("$line")==-1)
+ {
+ config_err("Warning: warning format does not contain a $line tag!\n");
+ }
+ if (warnFormat.find("$text")==-1)
+ {
+ config_err("Warning: warning format foes not contain a $text tag!\n");
+ }
+ }
+
+ QCString &manExtension = Config_getString("MAN_EXTENSION");
+
+ // set default man page extension if non is given by the user
+ if (manExtension.isEmpty())
+ {
+ manExtension=".3";
+ }
+
+ QCString &paperType = Config_getEnum("PAPER_TYPE");
+ paperType=paperType.lower().stripWhiteSpace();
+ if (paperType.isEmpty())
+ {
+ paperType = "a4";
+ }
+ if (paperType!="a4" && paperType!="a4wide" && paperType!="letter" &&
+ paperType!="legal" && paperType!="executive")
+ {
+ config_err("Error: Unknown page type specified\n");
+ }
+
+ QCString &outputLanguage=Config_getEnum("OUTPUT_LANGUAGE");
+ outputLanguage=outputLanguage.stripWhiteSpace();
+ if (outputLanguage.isEmpty())
+ {
+ outputLanguage = "English";
+ }
+
+ QCString &htmlFileExtension=Config_getString("HTML_FILE_EXTENSION");
+ htmlFileExtension=htmlFileExtension.stripWhiteSpace();
+ if (htmlFileExtension.isEmpty())
+ {
+ htmlFileExtension = ".html";
+ }
+
+ // expand the relative stripFromPath values
+ QStrList &stripFromPath = Config_getList("STRIP_FROM_PATH");
+ char *sfp = stripFromPath.first();
+ if (sfp==0) // by default use the current path
+ {
+ stripFromPath.append(QDir::currentDirPath().utf8()+"/");
+ }
+ else
+ {
+ cleanUpPaths(stripFromPath);
+ }
+
+ // expand the relative stripFromPath values
+ QStrList &stripFromIncPath = Config_getList("STRIP_FROM_INC_PATH");
+ cleanUpPaths(stripFromIncPath);
+
+ // Test to see if HTML header is valid
+ QCString &headerFile = Config_getString("HTML_HEADER");
+ if (!headerFile.isEmpty())
+ {
+ QFileInfo fi(headerFile);
+ if (!fi.exists())
+ {
+ config_err("Error: tag HTML_HEADER: header file `%s' "
+ "does not exist\n",headerFile.data());
+ exit(1);
+ }
+ }
+ // Test to see if HTML footer is valid
+ QCString &footerFile = Config_getString("HTML_FOOTER");
+ if (!footerFile.isEmpty())
+ {
+ QFileInfo fi(footerFile);
+ if (!fi.exists())
+ {
+ config_err("Error: tag HTML_FOOTER: footer file `%s' "
+ "does not exist\n",footerFile.data());
+ exit(1);
+ }
+ }
+ // Test to see if MathJax code file is valid
+ if (Config_getBool("USE_MATHJAX"))
+ {
+ QCString &MathJaxCodefile = Config_getString("MATHJAX_CODEFILE");
+ if (!MathJaxCodefile.isEmpty())
+ {
+ QFileInfo fi(MathJaxCodefile);
+ if (!fi.exists())
+ {
+ config_err("Error: tag MATHJAX_CODEFILE file `%s' "
+ "does not exist\n",MathJaxCodefile.data());
+ exit(1);
+ }
+ }
+ }
+ // Test to see if LaTeX header is valid
+ QCString &latexHeaderFile = Config_getString("LATEX_HEADER");
+ if (!latexHeaderFile.isEmpty())
+ {
+ QFileInfo fi(latexHeaderFile);
+ if (!fi.exists())
+ {
+ config_err("Error: tag LATEX_HEADER: header file `%s' "
+ "does not exist\n",latexHeaderFile.data());
+ exit(1);
+ }
+ }
+ // check include path
+ QStrList &includePath = Config_getList("INCLUDE_PATH");
+ char *s=includePath.first();
+ while (s)
+ {
+ QFileInfo fi(s);
+ if (!fi.exists()) config_err("Warning: tag INCLUDE_PATH: include path `%s' "
+ "does not exist\n",s);
+ s=includePath.next();
+ }
+
+ // check aliases
+ QStrList &aliasList = Config_getList("ALIASES");
+ s=aliasList.first();
+ while (s)
+ {
+ QRegExp re1("[a-z_A-Z][a-z_A-Z0-9]*[ \t]*="); // alias without argument
+ QRegExp re2("[a-z_A-Z][a-z_A-Z0-9]*{[0-9]*}[ \t]*="); // alias with argument
+ QCString alias=s;
+ alias=alias.stripWhiteSpace();
+ if (alias.find(re1)!=0 && alias.find(re2)!=0)
+ {
+ config_err("Error: Illegal alias format `%s'. Use \"name=value\" or \"name(n)=value\", where n is the number of arguments\n",
+ alias.data());
+ }
+ s=aliasList.next();
+ }
+
+ // check if GENERATE_TREEVIEW and GENERATE_HTMLHELP are both enabled
+ if (Config_getBool("GENERATE_TREEVIEW") && Config_getBool("GENERATE_HTMLHELP"))
+ {
+ config_err("Error: When enabling GENERATE_HTMLHELP the tree view (GENERATE_TREEVIEW) should be disabled. I'll do it for you.\n");
+ Config_getBool("GENERATE_TREEVIEW")=FALSE;
+ }
+ if (Config_getBool("SEARCHENGINE") && Config_getBool("GENERATE_HTMLHELP"))
+ {
+ config_err("Error: When enabling GENERATE_HTMLHELP the search engine (SEARCHENGINE) should be disabled. I'll do it for you.\n");
+ Config_getBool("SEARCHENGINE")=FALSE;
+ }
+
+ // check if SEPARATE_MEMBER_PAGES and INLINE_GROUPED_CLASSES are both enabled
+ if (Config_getBool("SEPARATE_MEMBER_PAGES") && Config_getBool("INLINE_GROUPED_CLASSES"))
+ {
+ config_err("Error: When enabling INLINE_GROUPED_CLASSES the SEPARATE_MEMBER_PAGES option should be disabled. I'll do it for you.\n");
+ Config_getBool("SEPARATE_MEMBER_PAGES")=FALSE;
+ }
+
+ // check dot image format
+ QCString &dotImageFormat=Config_getEnum("DOT_IMAGE_FORMAT");
+ dotImageFormat=dotImageFormat.stripWhiteSpace();
+ if (dotImageFormat.isEmpty())
+ {
+ dotImageFormat = "png";
+ }
+ //else if (dotImageFormat!="gif" && dotImageFormat!="png" && dotImageFormat!="jpg")
+ //{
+ // config_err("Invalid value for DOT_IMAGE_FORMAT: `%s'. Using the default.\n",dotImageFormat.data());
+ // dotImageFormat = "png";
+ //}
+
+ QCString &dotFontName=Config_getString("DOT_FONTNAME");
+ if (dotFontName=="FreeSans" || dotFontName=="FreeSans.ttf")
+ {
+ config_err("Warning: doxygen no longer ships with the FreeSans font.\n"
+ "You may want to clear or change DOT_FONTNAME.\n"
+ "Otherwise you run the risk that the wrong font is being used for dot generated graphs.\n");
+ }
+
+
+ // check dot path
+ QCString &dotPath = Config_getString("DOT_PATH");
+ if (!dotPath.isEmpty())
+ {
+ QFileInfo fi(dotPath);
+ if (fi.exists() && fi.isFile()) // user specified path + exec
+ {
+ dotPath=fi.dirPath(TRUE).utf8()+"/";
+ }
+ else
+ {
+ QFileInfo dp(dotPath+"/dot"+portable_commandExtension());
+ if (!dp.exists() || !dp.isFile())
+ {
+ config_err("Warning: the dot tool could not be found at %s\n",dotPath.data());
+ dotPath="";
+ }
+ else
+ {
+ dotPath=dp.dirPath(TRUE).utf8()+"/";
+ }
+ }
+#if defined(_WIN32) // convert slashes
+ uint i=0,l=dotPath.length();
+ for (i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
+#endif
+ }
+ else // make sure the string is empty but not null!
+ {
+ dotPath="";
+ }
+
+ // check mscgen path
+ QCString &mscgenPath = Config_getString("MSCGEN_PATH");
+ if (!mscgenPath.isEmpty())
+ {
+ QFileInfo dp(mscgenPath+"/mscgen"+portable_commandExtension());
+ if (!dp.exists() || !dp.isFile())
+ {
+ config_err("Warning: the mscgen tool could not be found at %s\n",mscgenPath.data());
+ mscgenPath="";
+ }
+ else
+ {
+ mscgenPath=dp.dirPath(TRUE).utf8()+"/";
+#if defined(_WIN32) // convert slashes
+ uint i=0,l=mscgenPath.length();
+ for (i=0;i<l;i++) if (mscgenPath.at(i)=='/') mscgenPath.at(i)='\\';
+#endif
+ }
+ }
+ else // make sure the string is empty but not null!
+ {
+ mscgenPath="";
+ }
+
+ // check plantuml path
+ QCString &plantumlJarPath = Config_getString("PLANTUML_JAR_PATH");
+ if (!plantumlJarPath.isEmpty())
+ {
+ QFileInfo pu(plantumlJarPath);
+ if (pu.exists() && pu.isDir()) // PLANTUML_JAR_PATH is directory
+ {
+ QFileInfo jar(plantumlJarPath+portable_pathSeparator()+"plantuml.jar");
+ if (jar.exists() && jar.isFile())
+ {
+ plantumlJarPath = jar.dirPath(TRUE).utf8()+portable_pathSeparator();
+ }
+ else
+ {
+ config_err("Jar file plantuml.jar not found at location "
+ "specified via PLANTUML_JAR_PATH: '%s'\n",plantumlJarPath.data());
+ plantumlJarPath="";
+ }
+ }
+ else if (pu.exists() && pu.isFile() && plantumlJarPath.right(4)==".jar") // PLANTUML_JAR_PATH is file
+ {
+ plantumlJarPath = pu.dirPath(TRUE).utf8()+portable_pathSeparator();
+ }
+ else
+ {
+ config_err("path specified via PLANTUML_JAR_PATH does not exist or not a directory: %s\n",
+ plantumlJarPath.data());
+ plantumlJarPath="";
+ }
+ }
+
+ // check dia path
+ QCString &diaPath = Config_getString("DIA_PATH");
+ if (!diaPath.isEmpty())
+ {
+ QFileInfo dp(diaPath+"/dia"+portable_commandExtension());
+ if (!dp.exists() || !dp.isFile())
+ {
+ config_err("Warning: dia could not be found at %s\n",diaPath.data());
+ diaPath="";
+ }
+ else
+ {
+ diaPath=dp.dirPath(TRUE).utf8()+"/";
+#if defined(_WIN32) // convert slashes
+ uint i=0,l=diaPath.length();
+ for (i=0;i<l;i++) if (diaPath.at(i)=='/') diaPath.at(i)='\\';
+#endif
+ }
+ }
+ else // make sure the string is empty but not null!
+ {
+ diaPath="";
+ }
+
+ // check input
+ QStrList &inputSources=Config_getList("INPUT");
+ if (inputSources.count()==0)
+ {
+ // use current dir as the default
+ inputSources.append(QDir::currentDirPath().utf8());
+ }
+ else
+ {
+ s=inputSources.first();
+ while (s)
+ {
+ QFileInfo fi(s);
+ if (!fi.exists())
+ {
+ config_err("Warning: tag INPUT: input source `%s' does not exist\n",s);
+ }
+ s=inputSources.next();
+ }
+ }
+
+ // add default pattern if needed
+ QStrList &filePatternList = Config_getList("FILE_PATTERNS");
+ if (filePatternList.isEmpty())
+ {
+ filePatternList.append("*.c");
+ filePatternList.append("*.cc");
+ filePatternList.append("*.cxx");
+ filePatternList.append("*.cpp");
+ filePatternList.append("*.c++");
+ //filePatternList.append("*.d");
+ filePatternList.append("*.java");
+ filePatternList.append("*.ii");
+ filePatternList.append("*.ixx");
+ filePatternList.append("*.ipp");
+ filePatternList.append("*.i++");
+ filePatternList.append("*.inl");
+ filePatternList.append("*.h");
+ filePatternList.append("*.hh");
+ filePatternList.append("*.hxx");
+ filePatternList.append("*.hpp");
+ filePatternList.append("*.h++");
+ filePatternList.append("*.idl");
+ filePatternList.append("*.odl");
+ filePatternList.append("*.cs");
+ filePatternList.append("*.php");
+ filePatternList.append("*.php3");
+ filePatternList.append("*.inc");
+ filePatternList.append("*.m");
+ filePatternList.append("*.mm");
+ filePatternList.append("*.dox");
+ filePatternList.append("*.py");
+ filePatternList.append("*.f90");
+ filePatternList.append("*.f");
+ filePatternList.append("*.for");
+ filePatternList.append("*.vhd");
+ filePatternList.append("*.vhdl");
+ filePatternList.append("*.tcl");
+ filePatternList.append("*.md");
+ filePatternList.append("*.markdown");
+ if (portable_fileSystemIsCaseSensitive())
+ {
+ // unix => case sensitive match => also include useful uppercase versions
+ filePatternList.append("*.C");
+ filePatternList.append("*.CC");
+ filePatternList.append("*.C++");
+ filePatternList.append("*.II");
+ filePatternList.append("*.I++");
+ filePatternList.append("*.H");
+ filePatternList.append("*.HH");
+ filePatternList.append("*.H++");
+ filePatternList.append("*.CS");
+ filePatternList.append("*.PHP");
+ filePatternList.append("*.PHP3");
+ filePatternList.append("*.M");
+ filePatternList.append("*.MM");
+ filePatternList.append("*.PY");
+ filePatternList.append("*.F90");
+ filePatternList.append("*.F");
+ filePatternList.append("*.VHD");
+ filePatternList.append("*.VHDL");
+ filePatternList.append("*.TCL");
+ filePatternList.append("*.MD");
+ filePatternList.append("*.MARKDOWN");
+ }
+ }
+
+ // add default pattern if needed
+ QStrList &examplePatternList = Config_getList("EXAMPLE_PATTERNS");
+ if (examplePatternList.isEmpty())
+ {
+ examplePatternList.append("*");
+ }
+
+ // if no output format is enabled, warn the user
+ if (!Config_getBool("GENERATE_HTML") &&
+ !Config_getBool("GENERATE_LATEX") &&
+ !Config_getBool("GENERATE_MAN") &&
+ !Config_getBool("GENERATE_RTF") &&
+ !Config_getBool("GENERATE_XML") &&
+ !Config_getBool("GENERATE_PERLMOD") &&
+ !Config_getBool("GENERATE_RTF") &&
+ !Config_getBool("GENERATE_AUTOGEN_DEF") &&
+ Config_getString("GENERATE_TAGFILE").isEmpty()
+ )
+ {
+ config_err("Warning: No output formats selected! Set at least one of the main GENERATE_* options to YES.\n");
+ }
+
+ // check HTMLHELP creation requirements
+ if (!Config_getBool("GENERATE_HTML") &&
+ Config_getBool("GENERATE_HTMLHELP"))
+ {
+ config_err("Warning: GENERATE_HTMLHELP=YES requires GENERATE_HTML=YES.\n");
+ }
+
+ // check QHP creation requirements
+ if (Config_getBool("GENERATE_QHP"))
+ {
+ if (Config_getString("QHP_NAMESPACE").isEmpty())
+ {
+ config_err("Error: GENERATE_QHP=YES requires QHP_NAMESPACE to be set. Using 'org.doxygen.doc' as default!.\n");
+ Config_getString("QHP_NAMESPACE")="org.doxygen.doc";
+ }
+
+ if (Config_getString("QHP_VIRTUAL_FOLDER").isEmpty())
+ {
+ config_err("Error: GENERATE_QHP=YES requires QHP_VIRTUAL_FOLDER to be set. Using 'doc' as default!\n");
+ Config_getString("QHP_VIRTUAL_FOLDER")="doc";
+ }
+ }
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_JAVA") && Config_getBool("INLINE_INFO"))
+ {
+ // don't show inline info for Java output, since Java has no inline
+ // concept.
+ Config_getBool("INLINE_INFO")=FALSE;
+ }
+
+ int &depth = Config_getInt("MAX_DOT_GRAPH_DEPTH");
+ if (depth==0)
+ {
+ depth=1000;
+ }
+
+ int &hue = Config_getInt("HTML_COLORSTYLE_HUE");
+ if (hue<0)
+ {
+ hue=0;
+ }
+ else if (hue>=360)
+ {
+ hue=hue%360;
+ }
+
+ int &sat = Config_getInt("HTML_COLORSTYLE_SAT");
+ if (sat<0)
+ {
+ sat=0;
+ }
+ else if (sat>255)
+ {
+ sat=255;
+ }
+ int &gamma = Config_getInt("HTML_COLORSTYLE_GAMMA");
+ if (gamma<40)
+ {
+ gamma=40;
+ }
+ else if (gamma>240)
+ {
+ gamma=240;
+ }
+
+ QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT");
+ if (!mathJaxFormat.isEmpty() && mathJaxFormat!="HTML-CSS" &&
+ mathJaxFormat!="NativeMML" && mathJaxFormat!="SVG")
+ {
+ config_err("Error: Unsupported value for MATHJAX_FORMAT: Should be one of HTML-CSS, NativeMML, or SVG\n");
+ Config_getEnum("MATHJAX_FORMAT")="HTML-CSS";
+ }
+
+ // add default words if needed
+ QStrList &annotationFromBrief = Config_getList("ABBREVIATE_BRIEF");
+ if (annotationFromBrief.isEmpty())
+ {
+ annotationFromBrief.append("The $name class");
+ annotationFromBrief.append("The $name widget");
+ annotationFromBrief.append("The $name file");
+ annotationFromBrief.append("is");
+ annotationFromBrief.append("provides");
+ annotationFromBrief.append("specifies");
+ annotationFromBrief.append("contains");
+ annotationFromBrief.append("represents");
+ annotationFromBrief.append("a");
+ annotationFromBrief.append("an");
+ annotationFromBrief.append("the");
+ }
+
+ // some default settings for vhdl
+ if (Config_getBool("OPTIMIZE_OUTPUT_VHDL") &&
+ (Config_getBool("INLINE_INHERITED_MEMB") ||
+ Config_getBool("INHERIT_DOCS") ||
+ !Config_getBool("HIDE_SCOPE_NAMES") ||
+ !Config_getBool("EXTRACT_PRIVATE") ||
+ !Config_getBool("EXTRACT_PACKAGE")
+ )
+ )
+ {
+ bool b1 = Config_getBool("INLINE_INHERITED_MEMB");
+ bool b2 = Config_getBool("INHERIT_DOCS");
+ bool b3 = Config_getBool("HIDE_SCOPE_NAMES");
+ bool b4 = Config_getBool("EXTRACT_PRIVATE");
+ bool b5 = Config_getBool("SKIP_FUNCTION_MACROS");
+ bool b6 = Config_getBool("EXTRACT_PACKAGE");
+ const char *s1,*s2,*s3,*s4,*s5,*s6;
+ if (b1) s1=" INLINE_INHERITED_MEMB = NO (was YES)\n"; else s1="";
+ if (b2) s2=" INHERIT_DOCS = NO (was YES)\n"; else s2="";
+ if (!b3) s3=" HIDE_SCOPE_NAMES = YES (was NO)\n"; else s3="";
+ if (!b4) s4=" EXTRACT_PRIVATE = YES (was NO)\n"; else s4="";
+ if (b5) s5=" ENABLE_PREPROCESSING = NO (was YES)\n"; else s5="";
+ if (!b6) s6=" EXTRACT_PACKAGE = YES (was NO)\n"; else s6="";
+
+
+ config_err("Warning: enabling OPTIMIZE_OUTPUT_VHDL assumes the following settings:\n"
+ "%s%s%s%s%s%s",s1,s2,s3,s4,s5,s6
+ );
+
+ Config_getBool("INLINE_INHERITED_MEMB") = FALSE;
+ Config_getBool("INHERIT_DOCS") = FALSE;
+ Config_getBool("HIDE_SCOPE_NAMES") = TRUE;
+ Config_getBool("EXTRACT_PRIVATE") = TRUE;
+ Config_getBool("ENABLE_PREPROCESSING") = FALSE;
+ Config_getBool("EXTRACT_PACKAGE") = TRUE;
+ }
+
+ checkFileName("GENERATE_TAGFILE");
+
+#if 0 // TODO: this breaks test 25; SOURCEBROWSER = NO and SOURCE_TOOLTIPS = YES.
+ // So this and other regressions should be analysed and fixed before this can be enabled
+ // disable any boolean options that depend on disabled options
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (it.toFirst();(option=it.current());++it)
+ {
+ QCString depName = option->dependsOn(); // option has a dependency
+ if (!depName.isEmpty())
+ {
+ ConfigOption * dep = Config::instance()->get(depName);
+ if (dep->kind()==ConfigOption::O_Bool &&
+ Config_getBool(depName)==FALSE) // dependent option is disabled
+ {
+ if (option->kind()==ConfigOption::O_Bool)
+ {
+ printf("disabling option %s\n",option->name().data());
+ Config_getBool(option->name())=FALSE; // also disable this option
+ }
+ }
+ }
+ }
+#endif
+}
+
+void Config::init()
+{
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (;(option=it.current());++it)
+ {
+ option->init();
+ }
+
+ // sanity check if all depends relations are valid
+ for (it.toFirst();(option=it.current());++it)
+ {
+ QCString depName = option->dependsOn();
+ if (!depName.isEmpty())
+ {
+ ConfigOption * opt = Config::instance()->get(depName);
+ if (opt==0)
+ {
+ config_err("Warning: Config option '%s' has invalid depends relation on unknown option '%s'\n",
+ option->name().data(),depName.data());
+ exit(1);
+ }
+ }
+ }
+}
+
+void Config::create()
+{
+ if (m_initialized) return;
+ m_initialized = TRUE;
+ addConfigOptions(this);
+}
+
+static QCString configFileToString(const char *name)
+{
+ if (name==0 || name[0]==0) return 0;
+ QFile f;
+
+ bool fileOpened=FALSE;
+ if (name[0]=='-' && name[1]==0) // read from stdin
+ {
+ fileOpened=f.open(IO_ReadOnly,stdin);
+ if (fileOpened)
+ {
+ const int bSize=4096;
+ QCString contents(bSize);
+ int totalSize=0;
+ int size;
+ while ((size=f.readBlock(contents.data()+totalSize,bSize))==bSize)
+ {
+ totalSize+=bSize;
+ contents.resize(totalSize+bSize);
+ }
+ totalSize+=size+2;
+ contents.resize(totalSize);
+ contents.at(totalSize-2)='\n'; // to help the scanner
+ contents.at(totalSize-1)='\0';
+ return contents;
+ }
+ }
+ else // read from file
+ {
+ QFileInfo fi(name);
+ if (!fi.exists() || !fi.isFile())
+ {
+ config_err("Error: file `%s' not found\n",name);
+ return "";
+ }
+ f.setName(name);
+ fileOpened=f.open(IO_ReadOnly);
+ if (fileOpened)
+ {
+ int fsize=f.size();
+ QCString contents(fsize+2);
+ f.readBlock(contents.data(),fsize);
+ f.close();
+ if (fsize==0 || contents[fsize-1]=='\n')
+ contents[fsize]='\0';
+ else
+ contents[fsize]='\n'; // to help the scanner
+ contents[fsize+1]='\0';
+ return contents;
+ }
+ }
+ if (!fileOpened)
+ {
+ config_err("Error: cannot open file `%s' for reading\n",name);
+ }
+ return "";
+}
+
+bool Config::parseString(const char *fn,const char *str,bool update)
+{
+ config = Config::instance();
+ inputString = str;
+ inputPosition = 0;
+ yyFileName = fn;
+ yyLineNr = 1;
+ includeStack.setAutoDelete(TRUE);
+ includeStack.clear();
+ includeDepth = 0;
+ configYYrestart( configYYin );
+ BEGIN( Start );
+ config_upd = update;
+ configYYlex();
+ config_upd = FALSE;
+ inputString = 0;
+ return TRUE;
+}
+
+bool Config::parse(const char *fn,bool update)
+{
+ int retval;
+ encoding = "UTF-8";
+ printlex(yy_flex_debug, TRUE, __FILE__, fn);
+ retval = parseString(fn,configFileToString(fn), update);
+ printlex(yy_flex_debug, FALSE, __FILE__, fn);
+ return retval;
+}
+
+extern "C" { // some bogus code to keep the compiler happy
+ //int configYYwrap() { return 1 ; }
+}
diff --git a/src/config.xml b/src/config.xml
new file mode 100644
index 0000000..f83ee55
--- /dev/null
+++ b/src/config.xml
@@ -0,0 +1,3394 @@
+<doxygenconfig>
+ <header>
+ <docs doxywizard='0' doxyfile='0'>
+ <![CDATA[
+/*
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*! \page config Configuration
+
+\tableofcontents
+\section config_format Format
+
+A configuration file is a free-form ASCII text file with a structure
+that is similar to that of a \c Makefile, with the default name \c Doxyfile. It is
+parsed by \c doxygen. The file may contain tabs and newlines for
+formatting purposes. The statements in the file are case-sensitive.
+Comments may be placed anywhere within the file (except within quotes).
+Comments beginning with two hash characters (\c \#\#) are kept when updating
+the configuration file and are placed in front of the TAG are in front of.
+Comments beginning with two hash characters (\c \#\#) at the end of the
+configuration file are also kept and placed at the end of the file.
+Comments begin with the hash character (\c \#) and ends at the end of the line.
+
+The file essentially consists of a list of assignment statements.
+Each statement consists of a \c TAG_NAME written in capitals,
+followed by the equal sign (<code>=</code>) and one or more values. If the same tag
+is assigned more than once, the last assignment overwrites any earlier
+assignment. For tags that take a list as their argument,
+the <code>+=</code> operator can be used instead of <code>=</code> to append
+new values to the list. Values are sequences of non-blanks. If the value should
+contain one or more blanks it must be surrounded by quotes (<code>"..."</code>).
+Multiple lines can be concatenated by inserting a backslash (\c \\)
+as the last character of a line. Environment variables can be expanded
+using the pattern <code>\$(ENV_VARIABLE_NAME)</code>.
+
+You can also include part of a configuration file from another configuration
+file using a <code>\@INCLUDE</code> tag as follows:
+\verbatim
+ at INCLUDE = config_file_name
+\endverbatim
+The include file is searched in the current working directory. You can
+also specify a list of directories that should be searched before looking
+in the current working directory. Do this by putting a <code>\@INCLUDE_PATH</code> tag
+with these paths before the <code>\@INCLUDE</code> tag, e.g.:
+\verbatim
+ at INCLUDE_PATH = my_config_dir
+\endverbatim
+
+The configuration options can be divided into several categories.
+Below is an alphabetical index of the tags that are recognized
+followed by the descriptions of the tags grouped by category.
+]]>
+ </docs>
+ <docs doxywizard='0' documentation='0'>
+ <![CDATA[
+This file describes the settings to be used by the documentation system
+doxygen (www.doxygen.org) for a project.
+<br>
+All text after a double hash (##) is considered a comment and is placed
+in front of the TAG it is preceding.<br>
+All text after a single hash (#) is considered a comment and will be ignored.
+The format is:
+\verbatim
+ TAG = value [value, ...]
+\endverbatim
+For lists, items can also be appended using:
+\verbatim
+ TAG += value [value, ...]
+\endverbatim
+Values that contain spaces should be placed between quotes (\" \").
+]]>
+ </docs>
+ </header>
+ <footer>
+ <docs doxywizard='0' doxyfile='0'>
+ <![CDATA[
+\section config_examples Examples
+
+Suppose you have a simple project consisting of two files: a source file
+\c example.cc and a header file \c example.h.
+Then a minimal configuration file is as simple as:
+\verbatim
+INPUT = example.cc example.h
+\endverbatim
+
+Assuming the example makes use of Qt classes and \c perl is located
+in <code>/usr/bin</code>, a more realistic configuration file would be:
+\verbatim
+PROJECT_NAME = Example
+INPUT = example.cc example.h
+WARNINGS = YES
+TAGFILES = qt.tag
+PERL_PATH = /usr/local/bin/perl
+SEARCHENGINE = NO
+\endverbatim
+
+To generate the documentation for the
+<a href="http://www.stack.nl/~dimitri/qdbttabular/index.html">QdbtTabular</a> package
+I have used the following configuration file:
+\verbatim
+PROJECT_NAME = QdbtTabular
+OUTPUT_DIRECTORY = html
+WARNINGS = YES
+INPUT = examples/examples.doc src
+FILE_PATTERNS = *.cc *.h
+INCLUDE_PATH = examples
+TAGFILES = qt.tag
+PERL_PATH = /usr/bin/perl
+SEARCHENGINE = YES
+\endverbatim
+
+To regenerate the Qt-1.44 documentation from the sources, you could use the
+following config file:
+\verbatim
+PROJECT_NAME = Qt
+OUTPUT_DIRECTORY = qt_docs
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = $(QTDIR)/
+PREDEFINED = USE_TEMPLATECLASS Q_EXPORT= \
+ QArrayT:=QArray \
+ QListT:=QList \
+ QDictT:=QDict \
+ QQueueT:=QQueue \
+ QVectorT:=QVector \
+ QPtrDictT:=QPtrDict \
+ QIntDictT:=QIntDict \
+ QStackT:=QStack \
+ QDictIteratorT:=QDictIterator \
+ QListIteratorT:=QListIterator \
+ QCacheT:=QCache \
+ QCacheIteratorT:=QCacheIterator \
+ QIntCacheT:=QIntCache \
+ QIntCacheIteratorT:=QIntCacheIterator \
+ QIntDictIteratorT:=QIntDictIterator \
+ QPtrDictIteratorT:=QPtrDictIterator
+INPUT = $(QTDIR)/doc \
+ $(QTDIR)/src/widgets \
+ $(QTDIR)/src/kernel \
+ $(QTDIR)/src/dialogs \
+ $(QTDIR)/src/tools
+FILE_PATTERNS = *.cpp *.h q*.doc
+INCLUDE_PATH = $(QTDIR)/include
+RECURSIVE = YES
+\endverbatim
+
+For the Qt-2.1 sources I recommend to use the following settings:
+\verbatim
+PROJECT_NAME = Qt
+PROJECT_NUMBER = 2.1
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+SOURCE_BROWSER = YES
+INPUT = $(QTDIR)/src
+FILE_PATTERNS = *.cpp *.h q*.doc
+RECURSIVE = YES
+EXCLUDE_PATTERNS = *codec.cpp moc_* */compat/* */3rdparty/*
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 3
+IGNORE_PREFIX = Q
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+INCLUDE_PATH = $(QTDIR)/include
+PREDEFINED = Q_PROPERTY(x)= \
+ Q_OVERRIDE(x)= \
+ Q_EXPORT= \
+ Q_ENUMS(x)= \
+ "QT_STATIC_CONST=static const " \
+ _WS_X11_ \
+ INCLUDE_MENUITEM_DEF
+EXPAND_ONLY_PREDEF = YES
+EXPAND_AS_DEFINED = Q_OBJECT_FAKE Q_OBJECT ACTIVATE_SIGNAL_WITH_PARAM \
+ Q_VARIANT_AS
+\endverbatim
+
+Here doxygen's preprocessor is used to substitute some
+macro names that are normally substituted by the C preprocessor,
+but without doing full macro expansion.
+
+
+\htmlonly
+Go to the <a href="commands.html">next</a> section or return to the
+ <a href="index.html">index</a>.
+\endhtmlonly
+
+*/
+]]>
+ </docs>
+ </footer>
+
+ <group name='Project' docs='Project related configuration options'>
+ <option type='string' id='DOXYFILE_ENCODING' format='string' defval='UTF-8'>
+ <docs>
+<![CDATA[
+ This tag specifies the encoding used for all characters in the config file that
+ follow. The default is UTF-8 which is also the encoding used for all text before
+ the first occurrence of this tag. Doxygen uses \c libiconv (or the iconv built into
+ \c libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+ possible encodings.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PROJECT_NAME' format='string' defval='My Project'>
+ <docs>
+<![CDATA[
+ The \c PROJECT_NAME tag is a single word (or a sequence of words
+ surrounded by double-quotes, unless you are using Doxywizard) that should identify the project for which the
+ documentation is generated. This name is used in the title of most
+ generated pages and in a few other places.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PROJECT_NUMBER' format='string' defval=''>
+ <docs>
+<![CDATA[
+ The \c PROJECT_NUMBER tag can be used to enter a project or revision number.
+ This could be handy for archiving the generated documentation or
+ if some version control system is used.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PROJECT_BRIEF' format='string' defval=''>
+ <docs>
+<![CDATA[
+ Using the \c PROJECT_BRIEF tag one can provide an optional one line description
+ for a project that appears at the top of each page and should give viewer
+ a quick idea about the purpose of the project. Keep the description short.
+]]>
+ </docs>
+ </option>
+
+ <option type='string' id='PROJECT_LOGO' format='image' defval=''>
+ <docs>
+<![CDATA[
+ With the \c PROJECT_LOGO tag one can specify an logo or icon that is
+ included in the documentation. The maximum height of the logo should not
+ exceed 55 pixels and the maximum width should not exceed 200 pixels.
+ Doxygen will copy the logo to the output directory.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='OUTPUT_DIRECTORY' format='dir' defval=''>
+ <docs>
+<![CDATA[
+ The \c OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+ path into which the generated documentation will be written.
+ If a relative path is entered, it will be relative to the location
+ where doxygen was started. If left blank the current directory will be used.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CREATE_SUBDIRS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c CREATE_SUBDIRS tag is set to \c YES, then doxygen will create
+ 4096 sub-directories (in 2 levels) under the output directory of each output
+ format and will distribute the generated files over these directories.
+ Enabling this option can be useful when feeding doxygen a huge amount of source
+ files, where putting all generated files in the same directory would otherwise
+ causes performance problems for the file system.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='ALLOW_UNICODE_NAMES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c ALLOW_UNICODE_NAMES tag is set to \c YES,
+ doxygen will allow non-ASCII characters to appear in the names of generated files.
+ If set to \c NO, non-ASCII characters will be escaped, for example _xE3_x81_x84
+ will be used for Unicode U+3044.
+]]>
+ </docs>
+ </option>
+ <option type='enum' id='OUTPUT_LANGUAGE' defval='English'>
+ <docs>
+<![CDATA[
+ The \c OUTPUT_LANGUAGE tag is used to specify the language in which all
+ documentation generated by doxygen is written. Doxygen will use this
+ information to generate all constant output in the proper language.
+]]>
+ </docs>
+ <value name='Afrikaans'/>
+ <value name='Arabic'/>
+ <value name='Armenian'/>
+ <value name='Brazilian'/>
+ <value name='Catalan'/>
+ <value name='Chinese'/>
+ <value name='Chinese-Traditional'/>
+ <value name='Croatian'/>
+ <value name='Czech'/>
+ <value name='Danish'/>
+ <value name='Dutch'/>
+ <value name='English' desc='(United States)'/>
+ <value name='Esperanto'/>
+ <value name='Farsi' desc='(Persian)'/>
+ <value name='Finnish'/>
+ <value name='French'/>
+ <value name='German'/>
+ <value name='Greek'/>
+ <value name='Hungarian'/>
+ <value name='Indonesian'/>
+ <value name='Italian'/>
+ <value name='Japanese'/>
+ <value name='Japanese-en' desc='(Japanese with English messages)'/>
+ <value name='Korean'/>
+ <value name='Korean-en' desc='(Korean with English messages)'/>
+ <value name='Latvian'/>
+ <value name='Lithuanian'/>
+ <value name='Macedonian'/>
+ <value name='Norwegian'/>
+ <value name='Persian' desc='(Farsi)'/>
+ <value name='Polish'/>
+ <value name='Portuguese'/>
+ <value name='Romanian'/>
+ <value name='Russian'/>
+ <value name='Serbian'/>
+ <value name='Serbian-Cyrillic'/>
+ <value name='Slovak'/>
+ <value name='Slovene'/>
+ <value name='Spanish'/>
+ <value name='Swedish'/>
+ <value name='Turkish'/>
+ <value name='Ukrainian'/>
+ <value name='Vietnamese'/>
+ </option>
+ <option type='bool' id='BRIEF_MEMBER_DESC' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c BRIEF_MEMBER_DESC tag is set to \c YES doxygen will
+ include brief member descriptions after the members that are listed in
+ the file and class documentation (similar to \c Javadoc).
+ Set to \c NO to disable this.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='REPEAT_BRIEF' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c REPEAT_BRIEF tag is set to \c YES doxygen will
+ prepend the brief description of a member or function before the detailed
+ description
+ <br>Note:
+ If both \ref cfg_hide_undoc_members "HIDE_UNDOC_MEMBERS" and
+ \ref cfg_brief_member_desc "BRIEF_MEMBER_DESC" are set to \c NO, the
+ brief descriptions will be completely suppressed.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='ABBREVIATE_BRIEF' format='string'>
+ <docs>
+<![CDATA[
+ This tag implements a quasi-intelligent brief description abbreviator
+ that is used to form the text in various listings. Each string
+ in this list, if found as the leading text of the brief description, will be
+ stripped from the text and the result, after processing the whole list, is used
+ as the annotated text. Otherwise, the brief description is used as-is. If left
+ blank, the following values are used (`$name` is automatically replaced with the
+ name of the entity):
+]]>
+ </docs>
+ <value name='The $name class'/>
+ <value name='The $name widget'/>
+ <value name='The $name file'/>
+ <value name='is'/>
+ <value name='provides'/>
+ <value name='specifies'/>
+ <value name='contains'/>
+ <value name='represents'/>
+ <value name='a'/>
+ <value name='an'/>
+ <value name='the'/>
+ </option>
+ <option type='bool' id='ALWAYS_DETAILED_SEC' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c ALWAYS_DETAILED_SEC and \ref cfg_repeat_brief "REPEAT_BRIEF" tags
+ are both set to \c YES then
+ doxygen will generate a detailed section even if there is only a brief
+ description.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INLINE_INHERITED_MEMB' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c INLINE_INHERITED_MEMB tag is set to \c YES, doxygen will show all inherited
+ members of a class in the documentation of that class as if those members were
+ ordinary class members. Constructors, destructors and assignment operators of
+ the base classes will not be shown.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='FULL_PATH_NAMES' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c FULL_PATH_NAMES tag is set to \c YES doxygen will prepend the full
+ path before files name in the file list and in the header files. If set
+ to \c NO the shortest path that makes the file name unique will be used
+]]>
+ </docs>
+ </option>
+ <option type='list' id='STRIP_FROM_PATH' format='string' depends='FULL_PATH_NAMES'>
+ <docs>
+<![CDATA[
+ The \c STRIP_FROM_PATH tag
+ can be used to strip a user-defined part of the path. Stripping is
+ only done if one of the specified strings matches the left-hand part of the
+ path. The tag can be used to show relative paths in the file list.
+ If left blank the directory from which doxygen is run is used as the
+ path to strip.
+ <br>Note that you can specify absolute paths here, but also
+ relative paths, which will be relative from the directory where doxygen is
+ started.
+]]>
+ </docs>
+ <value name=''/>
+ </option>
+ <option type='list' id='STRIP_FROM_INC_PATH' format='string'>
+ <docs>
+<![CDATA[
+ The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+ the path mentioned in the documentation of a class, which tells
+ the reader which header file to include in order to use a class.
+ If left blank only the name of the header file containing the class
+ definition is used. Otherwise one should specify the list of include paths that
+ are normally passed to the compiler using the `-I` flag.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHORT_NAMES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SHORT_NAMES tag is set to \c YES, doxygen will generate much shorter
+ (but less readable) file names. This can be useful is your file systems
+ doesn't support long names like on DOS, Mac, or CD-ROM.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='JAVADOC_AUTOBRIEF' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c JAVADOC_AUTOBRIEF tag is set to \c YES then doxygen
+ will interpret the first line (until the first dot) of a Javadoc-style
+ comment as the brief description. If set to \c NO, the
+ Javadoc-style will behave just like regular Qt-style comments
+ (thus requiring an explicit \ref cmdbrief "\@brief" command for a brief description.)
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='QT_AUTOBRIEF' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c QT_AUTOBRIEF tag is set to \c YES then doxygen
+ will interpret the first line (until the first dot) of a Qt-style
+ comment as the brief description. If set to \c NO, the
+ Qt-style will behave just like regular Qt-style comments (thus
+ requiring an explicit \ref cmdbrief "\\brief" command for a brief description.)
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='MULTILINE_CPP_IS_BRIEF' defval='0'>
+ <docs>
+<![CDATA[
+ The \c MULTILINE_CPP_IS_BRIEF tag can be set to \c YES to make doxygen
+ treat a multi-line C++ special comment block (i.e. a block of \c //! or \c ///
+ comments) as a brief description. This used to be the default behavior.
+ The new default is to treat a multi-line C++ comment block as a detailed
+ description. Set this tag to \c YES if you prefer the old behavior instead.
+ <br>Note that setting this tag to \c YES also means that rational rose comments
+ are not recognized any more.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INHERIT_DOCS' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c INHERIT_DOCS tag is set to \c YES then an undocumented
+ member inherits the documentation from any documented member that it
+ re-implements.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SEPARATE_MEMBER_PAGES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SEPARATE_MEMBER_PAGES tag is set to \c YES, then doxygen will produce
+ a new page for each member. If set to \c NO, the documentation of a member will
+ be part of the file/class/namespace that contains it.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='TAB_SIZE' minval='1' maxval='16' defval='4'>
+ <docs>
+<![CDATA[
+ The \c TAB_SIZE tag can be used to set the number of spaces in a tab.
+ Doxygen uses this value to replace tabs by spaces in code fragments.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='ALIASES' format='string'>
+ <docs>
+<![CDATA[
+ This tag can be used to specify a number of aliases that act
+ as commands in the documentation. An alias has the form:
+\verbatim
+ name=value
+\endverbatim
+ For example adding
+\verbatim
+ "sideeffect=@par Side Effects:\n"
+\endverbatim
+ will allow you to
+ put the command \c \\sideeffect (or \c \@sideeffect) in the documentation, which
+ will result in a user-defined paragraph with heading "Side Effects:".
+ You can put \ref cmdn "\\n"'s in the value part of an alias to insert newlines.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='TCL_SUBST' format='string'>
+ <docs>
+<![CDATA[
+ This tag can be used to specify a number of word-keyword mappings (TCL only).
+ A mapping has the form <code>"name=value"</code>. For example adding
+ <code>"class=itcl::class"</code> will allow you to use the command class in the
+ <code>itcl::class</code> meaning.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='OPTIMIZE_OUTPUT_FOR_C' defval='0'>
+ <docs>
+<![CDATA[
+ Set the \c OPTIMIZE_OUTPUT_FOR_C tag to \c YES if your project consists
+ of C sources only. Doxygen will then generate output that is more tailored
+ for C. For instance, some of the names that are used will be different.
+ The list of all members will be omitted, etc.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='OPTIMIZE_OUTPUT_JAVA' defval='0'>
+ <docs>
+<![CDATA[
+ Set the \c OPTIMIZE_OUTPUT_JAVA tag to \c YES if your project consists of Java or
+ Python sources only. Doxygen will then generate output that is more tailored
+ for that language. For instance, namespaces will be presented as packages,
+ qualified scopes will look different, etc.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='OPTIMIZE_FOR_FORTRAN' defval='0'>
+ <docs>
+<![CDATA[
+ Set the \c OPTIMIZE_FOR_FORTRAN tag to \c YES if your project consists of Fortran
+ sources. Doxygen will then generate output that is tailored for Fortran.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='OPTIMIZE_OUTPUT_VHDL' defval='0'>
+ <docs>
+<![CDATA[
+ Set the \c OPTIMIZE_OUTPUT_VHDL tag to \c YES if your project consists of VHDL
+ sources. Doxygen will then generate output that is tailored for VHDL.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXTENSION_MAPPING' format='string'>
+ <docs>
+<![CDATA[
+ Doxygen selects the parser to use depending on the extension of the files it parses.
+ With this tag you can assign which parser to use for a given extension.
+ Doxygen has a built-in mapping, but you can override or extend it using this tag.
+ The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of
+ the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+ Objective-C, Python, Fortran (fixed format Fortran: FortranFixed,
+ free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In
+ the later case the parser tries to guess whether the code is fixed or free
+ formatted code, this is the default for Fortran type files), VHDL.
+
+ For instance to make doxygen treat
+ <code>.inc</code> files as Fortran files (default is PHP), and <code>.f</code> files as C (default is Fortran),
+ use: `inc=Fortran f=C`.
+
+ <br>Note For files without extension you can use `no_extension` as a placeholder.
+ <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the
+ files are not read by doxygen.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='MARKDOWN_SUPPORT' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all
+ comments according to the Markdown format, which allows for more readable
+ documentation. See http://daringfireball.net/projects/markdown/ for details.
+ The output of markdown processing is further processed by doxygen, so you
+ can mix doxygen, HTML, and XML commands with Markdown formatting.
+ Disable only in case of backward compatibilities issues.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='AUTOLINK_SUPPORT' defval='1'>
+ <docs>
+<![CDATA[
+ When enabled doxygen tries to link words that correspond to documented classes,
+ or namespaces to their corresponding documentation. Such a link can be
+ prevented in individual cases by by putting a \c % sign in front of the word or
+ globally by setting \c AUTOLINK_SUPPORT to \c NO.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='BUILTIN_STL_SUPPORT' defval='0'>
+ <docs>
+<![CDATA[
+ If you use STL classes (i.e. `std::string`, `std::vector`, etc.) but do not want to
+ include (a tag file for) the STL sources as input, then you should
+ set this tag to \c YES in order to let doxygen match functions declarations and
+ definitions whose arguments contain STL classes (e.g. `func(std::string`); versus
+ `func(std::string) {}`). This also make the inheritance and collaboration
+ diagrams that involve STL classes more complete and accurate.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CPP_CLI_SUPPORT' defval='0'>
+ <docs>
+<![CDATA[
+ If you use Microsoft's C++/CLI language, you should set this option to \c YES to
+ enable parsing support.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SIP_SUPPORT' defval='0'>
+ <docs>
+<![CDATA[
+ Set the \c SIP_SUPPORT tag to \c YES if your project consists
+ of <a href="http://www.riverbankcomputing.co.uk/software/sip/intro">sip</a> sources only.
+ Doxygen will parse them like normal C++ but will assume all classes use public
+ instead of private inheritance when no explicit protection keyword is present.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='IDL_PROPERTY_SUPPORT' defval='1'>
+ <docs>
+<![CDATA[
+ For Microsoft's IDL there are \c propget and \c propput attributes to indicate getter
+ and setter methods for a property. Setting this option to \c YES
+ will make doxygen to replace the get and set methods by a property in the
+ documentation. This will only work if the methods are indeed getting or
+ setting a simple type. If this is not the case, or you want to show the
+ methods anyway, you should set this option to \c NO.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DISTRIBUTE_GROUP_DOC' defval='0'>
+ <docs>
+<![CDATA[
+ If member grouping is used in the documentation and the \c DISTRIBUTE_GROUP_DOC
+ tag is set to \c YES, then doxygen will reuse the documentation of the first
+ member in the group (if any) for the other members of the group. By default
+ all members of a group must be documented explicitly.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SUBGROUPING' defval='1'>
+ <docs>
+<![CDATA[
+ Set the \c SUBGROUPING tag to \c YES to allow class member groups of
+ the same type (for instance a group of public functions) to be put as a
+ subgroup of that type (e.g. under the Public Functions section). Set it to
+ \c NO to prevent subgrouping. Alternatively, this can be done per class using
+ the \ref cmdnosubgrouping "\\nosubgrouping" command.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INLINE_GROUPED_CLASSES' defval='0'>
+ <docs>
+<![CDATA[
+ When the \c INLINE_GROUPED_CLASSES tag is set to \c YES, classes, structs and
+ unions are shown inside the group in which they are included
+ (e.g. using \ref cmdingroup "\\ingroup") instead of on a separate page (for HTML and Man pages)
+ or section (for \f$\mbox{\LaTeX}\f$ and RTF).
+ <br>Note that this feature does not work in
+ combination with \ref cfg_separate_member_pages "SEPARATE_MEMBER_PAGES".
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INLINE_SIMPLE_STRUCTS' defval='0'>
+ <docs>
+<![CDATA[
+ When the \c INLINE_SIMPLE_STRUCTS tag is set to \c YES, structs, classes, and
+ unions with only public data fields or simple typedef fields will be shown
+ inline in the documentation of the scope in which they are defined (i.e. file,
+ namespace, or group documentation), provided this scope is documented. If set
+ to \c NO, structs, classes, and unions are shown on a separate
+ page (for HTML and Man pages) or section (for \f$\mbox{\LaTeX}\f$ and RTF).
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='TYPEDEF_HIDES_STRUCT' defval='0'>
+ <docs>
+<![CDATA[
+ When \c TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or enum
+ is documented as struct, union, or enum with the name of the typedef. So
+ <code>typedef struct TypeS {} TypeT</code>, will appear in the documentation as a struct
+ with name \c TypeT. When disabled the typedef will appear as a member of a file,
+ namespace, or class. And the struct will be named \c TypeS. This can typically
+ be useful for C code in case the coding convention dictates that all compound
+ types are typedef'ed and only the typedef is referenced, never the tag name.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='LOOKUP_CACHE_SIZE' minval='0' maxval='9' defval='0'>
+ <!-- be carefull when changing these formulas as they are hard coded in the conversion script -->
+ <docs>
+<![CDATA[
+ The size of the symbol lookup cache can be
+ set using \c LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+ their name and scope. Since this can be an expensive process and often the
+ same symbol appears multiple times in the code, doxygen keeps a cache of
+ pre-resolved symbols. If the cache is too small doxygen will become slower.
+ If the cache is too large, memory is wasted. The cache size is given by this
+ formula: \f$2^{(16+\mbox{LOOKUP\_CACHE\_SIZE})}\f$. The valid range is 0..9, the default is 0,
+ corresponding to a cache size of \f$2^{16} = 65536\f$ symbols.
+ At the end of a run doxygen will report the cache usage and suggest the
+ optimal cache size from a speed point of view.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Build' docs='Build related configuration options'>
+ <option type='bool' id='EXTRACT_ALL' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c EXTRACT_ALL tag is set to \c YES doxygen will assume all
+ entities in documentation are documented, even if no documentation was
+ available. Private class members and static file members will be hidden
+ unless the \ref cfg_extract_private "EXTRACT_PRIVATE" respectively
+ \ref cfg_extract_static "EXTRACT_STATIC" tags are set to \c YES.
+
+ \note This will also disable the warnings about undocumented members
+ that are normally produced when \ref cfg_warnings "WARNINGS" is
+ set to \c YES.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_PRIVATE' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c EXTRACT_PRIVATE tag is set to \c YES all private members of a
+ class will be included in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_PACKAGE' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c EXTRACT_PACKAGE tag is set to \c YES all members with package
+ or internal scope will be included in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_STATIC' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c EXTRACT_STATIC tag is set to \c YES all static members of a file
+ will be included in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_LOCAL_CLASSES' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c EXTRACT_LOCAL_CLASSES tag is set to \c YES classes (and structs)
+ defined locally in source files will be included in the documentation.
+ If set to \c NO only classes defined in header files are included. Does not
+ have any effect for Java sources.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_LOCAL_METHODS' defval='0'>
+ <docs>
+<![CDATA[
+ This flag is only useful for Objective-C code. When set to \c YES local
+ methods, which are defined in the implementation section but not in
+ the interface are included in the documentation.
+ If set to \c NO only methods in the interface are included.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTRACT_ANON_NSPACES' defval='0'>
+ <docs>
+<![CDATA[
+ If this flag is set to \c YES, the members of anonymous namespaces will be extracted
+ and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+ where file will be replaced with the base name of the file that contains the anonymous
+ namespace. By default anonymous namespace are hidden.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_UNDOC_MEMBERS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c HIDE_UNDOC_MEMBERS tag is set to \c YES, doxygen will hide all
+ undocumented members inside documented classes or files.
+ If set to \c NO these members will be included in the
+ various overviews, but no documentation section is generated.
+ This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_UNDOC_CLASSES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c HIDE_UNDOC_CLASSES tag is set to \c YES, doxygen will hide all
+ undocumented classes that are normally visible in the class hierarchy.
+ If set to \c NO these classes will be included in the
+ various overviews.
+ This option has no effect if \ref cfg_extract_all "EXTRACT_ALL" is enabled.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_FRIEND_COMPOUNDS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c HIDE_FRIEND_COMPOUNDS tag is set to \c YES, doxygen will hide all
+ friend (class|struct|union) declarations.
+ If set to \c NO these declarations will be included in the
+ documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_IN_BODY_DOCS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c HIDE_IN_BODY_DOCS tag is set to \c YES, doxygen will hide any
+ documentation blocks found inside the body of a function.
+ If set to \c NO these blocks will be appended to the
+ function's detailed documentation block.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INTERNAL_DOCS' defval='0'>
+ <docs>
+<![CDATA[
+ The \c INTERNAL_DOCS tag determines if documentation
+ that is typed after a \ref cmdinternal "\\internal" command is included. If the tag is set
+ to \c NO then the documentation will be excluded.
+ Set it to \c YES to include the internal documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CASE_SENSE_NAMES' defval='0' altdefval='portable_fileSystemIsCaseSensitive()'>
+ <docs>
+<![CDATA[
+ If the \c CASE_SENSE_NAMES tag is set to \c NO then doxygen
+ will only generate file names in lower-case letters. If set to
+ \c YES upper-case letters are also allowed. This is useful if you have
+ classes or files whose names only differ in case and if your file system
+ supports case sensitive file names. Windows and Mac users are advised to set this
+ option to \c NO.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_SCOPE_NAMES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c HIDE_SCOPE_NAMES tag is set to \c NO then doxygen
+ will show members with their full class and namespace scopes in the
+ documentation. If set to \c YES the scope will be hidden.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHOW_INCLUDE_FILES' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c SHOW_INCLUDE_FILES tag is set to \c YES then doxygen
+ will put a list of the files that are included by a file in the documentation
+ of that file.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHOW_GROUPED_MEMB_INC' defval='0'>
+ <docs>
+<![CDATA[
+ If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen
+ will add for each grouped member an include statement to the documentation,
+ telling the reader which file to include in order to use the member.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='FORCE_LOCAL_INCLUDES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c FORCE_LOCAL_INCLUDES tag is set to \c YES then doxygen
+ will list include files with double quotes in the documentation
+ rather than with sharp brackets.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INLINE_INFO' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c INLINE_INFO tag is set to \c YES then a tag [inline]
+ is inserted in the documentation for inline members.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SORT_MEMBER_DOCS' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c SORT_MEMBER_DOCS tag is set to \c YES then doxygen
+ will sort the (detailed) documentation of file and class members
+ alphabetically by member name. If set to \c NO the members will appear in
+ declaration order.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SORT_BRIEF_DOCS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SORT_BRIEF_DOCS tag is set to \c YES then doxygen will sort the
+ brief descriptions of file, namespace and class members alphabetically
+ by member name. If set to \c NO the members will appear in
+ declaration order. Note that this will also influence the order of the
+ classes in the class list.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SORT_MEMBERS_CTORS_1ST' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SORT_MEMBERS_CTORS_1ST tag is set to \c YES then doxygen
+ will sort the (brief and detailed) documentation of class members so that
+ constructors and destructors are listed first. If set to \c NO
+ the constructors will appear in the respective orders defined by
+ \ref cfg_sort_brief_docs "SORT_BRIEF_DOCS" and \ref cfg_sort_member_docs "SORT_MEMBER_DOCS".
+ \note If \ref cfg_sort_brief_docs "SORT_BRIEF_DOCS" is set to \c NO this option is ignored for
+ sorting brief member documentation.
+ \note If \ref cfg_sort_member_docs "SORT_MEMBER_DOCS" is set to \c NO this option is ignored for
+ sorting detailed member documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SORT_GROUP_NAMES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SORT_GROUP_NAMES tag is set to \c YES then doxygen will sort the
+ hierarchy of group names into alphabetical order. If set to \c NO
+ the group names will appear in their defined order.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SORT_BY_SCOPE_NAME' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SORT_BY_SCOPE_NAME tag is set to \c YES, the class list will be
+ sorted by fully-qualified names, including namespaces. If set to
+ \c NO, the class list will be sorted only by class name,
+ not including the namespace part.
+ \note This option is not very useful if \ref cfg_hide_scope_names "HIDE_SCOPE_NAMES" is set to \c YES.
+ \note This option applies only to the class list, not to the
+ alphabetical list.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='STRICT_PROTO_MATCHING' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+ do proper type resolution of all parameters of a function it will reject a
+ match between the prototype and the implementation of a member function even
+ if there is only one candidate or it is obvious which candidate to choose
+ by doing a simple string match. By disabling \c STRICT_PROTO_MATCHING doxygen
+ will still accept a match between prototype and implementation in such cases.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_TODOLIST' defval='1'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_TODOLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the todo list. This list is created by
+ putting \ref cmdtodo "\\todo" commands in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_TESTLIST' defval='1'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_TESTLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the test list. This list is created by
+ putting \ref cmdtest "\\test" commands in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_BUGLIST' defval='1'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_BUGLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the bug list. This list is created by
+ putting \ref cmdbug "\\bug" commands in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_DEPRECATEDLIST' defval='1'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_DEPRECATEDLIST tag can be used to enable (\c YES) or
+ disable (\c NO) the deprecated list. This list is created by
+ putting \ref cmddeprecated "\\deprecated"
+ commands in the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='ENABLED_SECTIONS' format='string'>
+ <docs>
+<![CDATA[
+ The \c ENABLED_SECTIONS tag can be used to enable conditional
+ documentation sections, marked by \ref cmdif "\\if" \<section_label\> ...
+ \ref cmdendif "\\endif" and \ref cmdcond "\\cond" \<section_label\> ...
+ \ref cmdendcond "\\endcond" blocks.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='MAX_INITIALIZER_LINES' minval='0' maxval='10000' defval='30'>
+ <docs>
+<![CDATA[
+ The \c MAX_INITIALIZER_LINES tag determines the maximum number of lines
+ that the initial value of a variable or macro / define can have for it to appear in
+ the documentation. If the initializer
+ consists of more lines than specified here it will be hidden. Use a value
+ of 0 to hide initializers completely. The appearance of the value of
+ individual variables and macros / defines can be controlled using \ref cmdshowinitializer "\\showinitializer"
+ or \ref cmdhideinitializer "\\hideinitializer" command in the documentation regardless of this setting.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHOW_USED_FILES' defval='1'>
+ <docs>
+<![CDATA[
+ Set the \c SHOW_USED_FILES tag to \c NO to disable the list of files generated
+ at the bottom of the documentation of classes and structs. If set to \c YES the
+ list will mention the files that were used to generate the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHOW_FILES' defval='1'>
+ <docs>
+<![CDATA[
+ Set the \c SHOW_FILES tag to \c NO to disable the generation of the Files page.
+ This will remove the Files entry from the Quick Index and from the
+ Folder Tree View (if specified).
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SHOW_NAMESPACES' defval='1'>
+ <docs>
+<![CDATA[
+ Set the \c SHOW_NAMESPACES tag to \c NO to disable the generation of the
+ Namespaces page. This will remove the Namespaces entry from the Quick Index
+ and from the Folder Tree View (if specified).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='FILE_VERSION_FILTER' format='file' defval=''>
+ <docs>
+<![CDATA[
+ The \c FILE_VERSION_FILTER tag can be used to specify a program or script that
+ doxygen should invoke to get the current version for each file (typically from the
+ version control system). Doxygen will invoke the program by executing (via
+ <code>popen()</code>) the command <code>command input-file</code>, where \c command is
+ the value of the \c FILE_VERSION_FILTER tag, and \c input-file is the name
+ of an input file provided by doxygen.
+ Whatever the program writes to standard output is used as the file version.
+]]>
+ </docs>
+ <docs doxywizard='0' doxyfile='0'>
+<![CDATA[
+Example of using a shell script as a filter for Unix:
+\verbatim
+ FILE_VERSION_FILTER = "/bin/sh versionfilter.sh"
+\endverbatim
+<br>
+Example shell script for CVS:
+\verbatim
+#!/bin/sh
+cvs status $1 | sed -n 's/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p'
+\endverbatim
+<br>
+Example shell script for Subversion:
+\verbatim
+#!/bin/sh
+svn stat -v $1 | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p'
+\endverbatim
+<br>
+Example filter for ClearCase:
+\verbatim
+FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
+\endverbatim
+]]>
+ </docs>
+ <docs documentation='0'>
+<![CDATA[
+ For an example see the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LAYOUT_FILE' format='file' defval=''>
+ <docs>
+<![CDATA[
+ The \c LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+ doxygen. The layout file controls the global structure of the generated output files
+ in an output format independent way. To create the layout file that represents
+ doxygen's defaults, run doxygen with the `-l` option. You can optionally specify a
+ file name after the option, if omitted \c DoxygenLayout.xml will be used as the name
+ of the layout file.
+ <br>Note that if you run doxygen from a directory containing
+ a file called \c DoxygenLayout.xml, doxygen will parse it automatically even if
+ the \c LAYOUT_FILE tag is left empty.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='CITE_BIB_FILES' format='file'>
+ <docs>
+<![CDATA[
+ The \c CITE_BIB_FILES tag can be used to specify one or more \c bib files
+ containing the reference definitions. This must be a list of <code>.bib</code> files. The
+ <code>.bib</code> extension is automatically appended if omitted. This requires the
+ \c bibtex tool to be installed. See also http://en.wikipedia.org/wiki/BibTeX for
+ more info. For \f$\mbox{\LaTeX}\f$ the style of the bibliography can be controlled
+ using \ref cfg_latex_bib_style "LATEX_BIB_STYLE".
+ To use this feature you need \c bibtex and \c perl available in the search path.
+ See also \ref cmdcite "\\cite" for info how to create references.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Messages' docs='Configuration options related to warning and progress messages'>
+ <option type='bool' id='QUIET' defval='0'>
+ <docs>
+<![CDATA[
+ The \c QUIET tag can be used to turn on/off the messages that are generated
+ to standard output by doxygen. If \c QUIET is set to \c YES this implies that the messages are off.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='WARNINGS' defval='1'>
+ <docs>
+<![CDATA[
+ The \c WARNINGS tag can be used to turn on/off the warning messages that are
+ generated to standard error (\c stderr) by doxygen. If \c WARNINGS is set to
+ \c YES this implies that the warnings are on.
+<br>
+ \b Tip: Turn warnings on while writing the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='WARN_IF_UNDOCUMENTED' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c WARN_IF_UNDOCUMENTED tag is set to \c YES, then doxygen will generate warnings
+ for undocumented members. If \ref cfg_extract_all "EXTRACT_ALL" is set to \c YES then this flag will
+ automatically be disabled.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='WARN_IF_DOC_ERROR' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c WARN_IF_DOC_ERROR tag is set to \c YES, doxygen will generate warnings for
+ potential errors in the documentation, such as not documenting some
+ parameters in a documented function, or documenting parameters that
+ don't exist or using markup commands wrongly.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='WARN_NO_PARAMDOC' defval='0'>
+ <docs>
+<![CDATA[
+ This \c WARN_NO_PARAMDOC option can be enabled to get warnings for
+ functions that are documented, but have no documentation for their parameters
+ or return value. If set to \c NO doxygen will only warn about
+ wrong or incomplete parameter documentation, but not about the absence of
+ documentation.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='WARN_FORMAT' format='string' defval='$file:$line: $text'>
+ <docs>
+<![CDATA[
+ The \c WARN_FORMAT tag determines the format of the warning messages that
+ doxygen can produce. The string should contain the <code>\$file</code>,
+ <code>\$line</code>, and <code>\$text</code>
+ tags, which will be replaced by the file and line number from which the
+ warning originated and the warning text.
+ Optionally the format may contain
+ <code>$version</code>, which will be replaced by the version of the file (if it could
+ be obtained via \ref cfg_file_version_filter "FILE_VERSION_FILTER")
+]]>
+ </docs>
+ </option>
+ <option type='string' id='WARN_LOGFILE' format='file' defval=''>
+ <docs>
+<![CDATA[
+ The \c WARN_LOGFILE tag can be used to specify a file to which warning
+ and error messages should be written. If left blank the output is written
+ to standard error (`stderr`).
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Input' docs='Configuration options related to the input files'>
+ <option type='list' id='INPUT' format='filedir'>
+ <docs>
+<![CDATA[
+ The \c INPUT tag is used to specify the files and/or directories that contain
+ documented source files. You may enter file names like
+ \c myfile.cpp or directories like \c /usr/src/myproject.
+ Separate the files or directories with spaces.
+
+ \note If this tag is empty the current directory is searched.
+]]>
+ </docs>
+ <value name=''/>
+ </option>
+ <option type='string' id='INPUT_ENCODING' format='string' defval='UTF-8'>
+ <docs>
+<![CDATA[
+ This tag can be used to specify the character encoding of the source files that
+ doxygen parses. Internally doxygen uses the UTF-8 encoding.
+ Doxygen uses `libiconv` (or the `iconv` built into `libc`) for the transcoding.
+ See <a href="http://www.gnu.org/software/libiconv">the libiconv documentation</a> for
+ the list of possible encodings.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='FILE_PATTERNS' format='string'>
+ <docs>
+<![CDATA[
+ If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the
+ \c FILE_PATTERNS tag to specify one or more wildcard patterns
+ (like `*.cpp` and `*.h`) to filter out the source-files
+ in the directories. If left blank the following patterns are tested:
+]]>
+ </docs>
+ <value name='*.c'/>
+ <value name='*.cc'/>
+ <value name='*.cxx'/>
+ <value name='*.cpp'/>
+ <value name='*.c++'/>
+ <value name='*.java'/>
+ <value name='*.ii'/>
+ <value name='*.ixx'/>
+ <value name='*.ipp'/>
+ <value name='*.i++'/>
+ <value name='*.inl'/>
+ <value name='*.idl'/>
+ <value name='*.ddl'/>
+ <value name='*.odl'/>
+ <value name='*.h'/>
+ <value name='*.hh'/>
+ <value name='*.hxx'/>
+ <value name='*.hpp'/>
+ <value name='*.h++'/>
+ <value name='*.cs'/>
+ <value name='*.d'/>
+ <value name='*.php'/>
+ <value name='*.php4'/>
+ <value name='*.php5'/>
+ <value name='*.phtml'/>
+ <value name='*.inc'/>
+ <value name='*.m'/>
+ <value name='*.markdown'/>
+ <value name='*.md'/>
+ <value name='*.mm'/>
+ <value name='*.dox'/>
+ <value name='*.py'/>
+ <value name='*.f90'/>
+ <value name='*.f'/>
+ <value name='*.for'/>
+ <value name='*.tcl'/>
+ <value name='*.vhd'/>
+ <value name='*.vhdl'/>
+ <value name='*.ucf'/>
+ <value name='*.qsf'/>
+ <value name='*.as'/>
+ <value name='*.js'/>
+ </option>
+ <option type='bool' id='RECURSIVE' defval='0'>
+ <docs>
+<![CDATA[
+ The \c RECURSIVE tag can be used to specify whether or not subdirectories
+ should be searched for input files as well.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXCLUDE' format='filedir'>
+ <docs>
+<![CDATA[
+ The \c EXCLUDE tag can be used to specify files and/or directories that should be
+ excluded from the \ref cfg_input "INPUT" source files. This way you can easily exclude a
+ subdirectory from a directory tree whose root is specified with the \ref cfg_input "INPUT" tag.
+ <br>Note that relative paths are relative to the directory from which doxygen is run.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXCLUDE_SYMLINKS' defval='0'>
+ <docs>
+<![CDATA[
+ The \c EXCLUDE_SYMLINKS tag can be used to select whether or not files or directories
+ that are symbolic links (a Unix file system feature) are excluded from the input.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXCLUDE_PATTERNS' format='string'>
+ <docs>
+<![CDATA[
+ If the value of the \ref cfg_input "INPUT" tag contains directories, you can use the
+ \c EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+ certain files from those directories.
+ <br>Note that the wildcards are matched
+ against the file with absolute path, so to exclude all test directories
+ for example use the pattern `*``/test/``*`
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXCLUDE_SYMBOLS' format='string'>
+ <docs>
+<![CDATA[
+ The \c EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+ (namespaces, classes, functions, etc.) that should be excluded from the
+ output. The symbol name can be a fully qualified name, a word, or if the
+ wildcard `*` is used, a substring. Examples: `ANamespace`, `AClass`,
+ `AClass::ANamespace`, `ANamespace::*Test`
+ <br>Note that the wildcards are matched against the file with absolute path,
+ so to exclude all test directories use the pattern
+ `*``/test/``*`
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXAMPLE_PATH' format='filedir'>
+ <docs>
+<![CDATA[
+ The \c EXAMPLE_PATH tag can be used to specify one or more files or
+ directories that contain example code fragments that are included (see
+ the \ref cmdinclude "\\include" command).
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXAMPLE_PATTERNS' format='string'>
+ <docs>
+<![CDATA[
+ If the value of the \ref cfg_example_path "EXAMPLE_PATH" tag contains directories,
+ you can use the
+ \c EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like `*.cpp`
+ and `*.h`) to filter out the source-files in the directories. If left
+ blank all files are included.
+]]>
+ </docs>
+ <value name='*' show_docu='NO'/>
+ </option>
+ <option type='bool' id='EXAMPLE_RECURSIVE' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c EXAMPLE_RECURSIVE tag is set to \c YES then subdirectories will be
+ searched for input files to be used with the \ref cmdinclude "\\include" or
+ \ref cmddontinclude "\\dontinclude"
+ commands irrespective of the value of the \ref cfg_recursive "RECURSIVE" tag.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='IMAGE_PATH' format='filedir'>
+ <docs>
+<![CDATA[
+ The \c IMAGE_PATH tag can be used to specify one or more files or
+ directories that contain images that are to be included in the
+ documentation (see the \ref cmdimage "\\image" command).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='INPUT_FILTER' format='file' defval=''>
+ <docs>
+<![CDATA[
+ The \c INPUT_FILTER tag can be used to specify a program that doxygen should
+ invoke to filter for each input file. Doxygen will invoke the filter program
+ by executing (via <code>popen()</code>) the command:
+ <br>
+ <code>\<filter\> \<input-file\></code>
+ <br>
+ where <code>\<filter\></code>
+ is the value of the \c INPUT_FILTER tag, and <code>\<input-file\></code> is the name of an
+ input file. Doxygen will then use the output that the filter program writes
+ to standard output. If \ref cfg_filter_patterns "FILTER_PATTERNS" is specified, this tag will be ignored.
+ <br>Note that the filter must not add or remove lines; it is applied before the
+ code is scanned, but not when the output code is generated. If lines are added
+ or removed, the anchors will not be placed correctly.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='FILTER_PATTERNS' format='string'>
+ <docs>
+<![CDATA[
+ The \c FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+ basis. Doxygen will compare the file name with each pattern and apply the
+ filter if there is a match. The filters are a list of the form:
+ pattern=filter (like `*.cpp=my_cpp_filter`). See \ref cfg_input_filter "INPUT_FILTER" for further
+ information on how filters are used. If the \c FILTER_PATTERNS tag is empty or if
+ none of the patterns match the file name, \ref cfg_input_filter "INPUT_FILTER" is
+ applied.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='FILTER_SOURCE_FILES' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c FILTER_SOURCE_FILES tag is set to \c YES, the input filter (if set using
+ \ref cfg_input_filter "INPUT_FILTER" ) will also be used to filter the input
+ files that are used for producing the source files to browse
+ (i.e. when \ref cfg_source_browser "SOURCE_BROWSER" is set to \c YES).
+]]>
+ </docs>
+ </option>
+ <option type='list' id='FILTER_SOURCE_PATTERNS' format='string' depends='FILTER_SOURCE_FILES'>
+ <docs>
+<![CDATA[
+ The \c FILTER_SOURCE_PATTERNS tag can be used to specify source filters per
+ file pattern. A pattern will override the setting
+ for \ref cfg_filter_patterns "FILTER_PATTERN" (if any)
+ and it is also possible to disable source filtering for a specific pattern
+ using `*.ext=` (so without naming a filter).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='USE_MDFILE_AS_MAINPAGE' format='string' defval=''>
+ <docs>
+<![CDATA[
+ If the \c USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+ is part of the input, its contents will be placed on the main page (`index.html`).
+ This can be useful if you have a project on for instance GitHub and want to reuse
+ the introduction page also for the doxygen output.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Source_Browser' docs='Configuration options related to source browsing'>
+ <option type='bool' id='SOURCE_BROWSER' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c SOURCE_BROWSER tag is set to \c YES then a list of source files will
+ be generated. Documented entities will be cross-referenced with these sources.
+ <br>Note: To get rid of all source code in the generated output, make sure that also
+ \ref cfg_verbatim_headers "VERBATIM_HEADERS" is set to \c NO.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INLINE_SOURCES' defval='0'>
+ <docs>
+<![CDATA[
+ Setting the \c INLINE_SOURCES tag to \c YES will include the body
+ of functions, classes and enums directly into the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='STRIP_CODE_COMMENTS' defval='1'>
+ <docs>
+<![CDATA[
+ Setting the \c STRIP_CODE_COMMENTS tag to \c YES will instruct
+ doxygen to hide any special comment blocks from generated source code
+ fragments. Normal C, C++ and Fortran comments will always remain visible.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='REFERENCED_BY_RELATION' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c REFERENCED_BY_RELATION tag is set to \c YES
+ then for each documented function all documented
+ functions referencing it will be listed.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='REFERENCES_RELATION' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c REFERENCES_RELATION tag is set to \c YES
+ then for each documented function all documented entities
+ called/used by that function will be listed.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='REFERENCES_LINK_SOURCE' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c REFERENCES_LINK_SOURCE tag is set to \c YES
+ and \ref cfg_source_browser "SOURCE_BROWSER" tag is set to \c YES, then the hyperlinks from
+ functions in \ref cfg_references_relation "REFERENCES_RELATION" and
+ \ref cfg_referenced_by_relation "REFERENCED_BY_RELATION" lists will
+ link to the source code. Otherwise they will link to the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SOURCE_TOOLTIPS' defval='1' depends='SOURCE_BROWSER'>
+ <docs>
+<![CDATA[
+If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+source code will show a tooltip with additional information such as prototype,
+brief description and links to the definition and documentation. Since this will
+make the HTML file larger and loading of large files a bit slower, you can opt
+to disable this feature.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='USE_HTAGS' defval='0' depends='SOURCE_BROWSER'>
+ <docs>
+<![CDATA[
+ If the \c USE_HTAGS tag is set to \c YES then the references to source code
+ will point to the HTML generated by the \c htags(1) tool instead of doxygen
+ built-in source browser. The \c htags tool is part of GNU's global source
+ tagging system (see http://www.gnu.org/software/global/global.html). You
+ will need version 4.8.6 or higher.
+<br>
+ To use it do the following:
+ -# Install the latest version of \c global
+ -# Enable \ref cfg_source_browser "SOURCE_BROWSER" and \c USE_HTAGS in the config file
+ -# Make sure the \ref cfg_input "INPUT" points to the root of the source tree
+ -# Run \c doxygen as normal
+<br>
+ Doxygen will invoke \c htags (and that will in turn invoke \c gtags), so these tools
+ must be available from the command line (i.e. in the search path).
+<br>
+ The result: instead of the source browser generated by doxygen, the links to
+ source code will now point to the output of \c htags.
+]]>
+ </docs>
+ </option>
+
+ <option type='bool' id='VERBATIM_HEADERS' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c VERBATIM_HEADERS tag is set the \c YES then doxygen
+ will generate a verbatim copy of the header file for each class for
+ which an include is specified. Set to \c NO to disable this.
+ \sa Section \ref cmdclass "\\class".
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CLANG_ASSISTED_PARSING' setting='USE_LIBCLANG' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c CLANG_ASSISTED_PARSING tag is set to \c YES, then doxygen will use the
+ <a href="http://clang.llvm.org/">clang parser</a> for more accurate parsing
+ at the cost of reduced performance. This can be particularly helpful with
+ template rich C++ code for which doxygen's built-in parser lacks the
+ necessary type information.
+
+ @note The availability of this option depends on whether or not doxygen
+ was compiled with the `--with-libclang` option.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='CLANG_OPTIONS' format='string' setting='USE_LIBCLANG' depends='CLANG_ASSISTED_PARSING'>
+ <docs>
+<![CDATA[
+ If clang assisted parsing is enabled you can provide the compiler with command
+ line options that you would normally use when invoking the compiler. Note that
+ the include paths will already be set by doxygen for the files and directories
+ specified with \ref cfg_input "INPUT" and \ref cfg_include_path "INCLUDE_PATH".
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Index' docs='Configuration options related to the alphabetical class index'>
+ <option type='bool' id='ALPHABETICAL_INDEX' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c ALPHABETICAL_INDEX tag is set to \c YES, an alphabetical index
+ of all compounds will be generated. Enable this if the project contains
+ a lot of classes, structs, unions or interfaces.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='COLS_IN_ALPHA_INDEX' minval='1' maxval='20' defval='5' depends='ALPHABETICAL_INDEX'>
+ <docs>
+<![CDATA[
+ The \c COLS_IN_ALPHA_INDEX tag can be
+ used to specify the number of columns in which the alphabetical index list will be split.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='IGNORE_PREFIX' format='string' depends='ALPHABETICAL_INDEX'>
+ <docs>
+<![CDATA[
+ In case all classes in a project start with a common prefix, all classes will
+ be put under the same header in the alphabetical index.
+ The \c IGNORE_PREFIX tag can be used to specify a prefix
+ (or a list of prefixes) that should be ignored while generating the index headers.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='HTML' docs='Configuration options related to the HTML output'>
+ <option type='bool' id='GENERATE_HTML' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_HTML tag is set to \c YES doxygen will
+ generate HTML output
+]]>
+ </docs>
+ </option>
+ <option type='string' id='HTML_OUTPUT' format='dir' defval='html' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='HTML_FILE_EXTENSION' format='string' defval='.html' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_FILE_EXTENSION tag can be used to specify the file extension for
+ each generated HTML page (for example: <code>.htm, .php, .asp</code>).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='HTML_HEADER' format='file' defval='' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_HEADER tag can be used to specify a user-defined HTML
+ header file for each generated HTML page.
+ If the tag is left blank doxygen will generate a
+ standard header.
+<br>
+ To get valid HTML the header file that
+ includes any scripts and style sheets that doxygen
+ needs, which is dependent on the configuration options used (e.g. the
+ setting \ref cfg_generate_treeview "GENERATE_TREEVIEW").
+ It is highly recommended to start with a default header using
+\verbatim
+doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFile
+\endverbatim
+ and then modify the file \c new_header.html.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the default header that doxygen normally uses.
+
+ @note The header is subject to change so you typically
+ have to regenerate the default header when upgrading to a newer version of
+ doxygen.
+]]>
+ </docs>
+ <docs doxywizard='0' doxyfile='0'>
+<![CDATA[
+ The following markers have a special meaning inside the header and footer:
+ <dl>
+ <dt><code>\$title</code><dd>will be replaced with the title of the page.
+ <dt><code>\$datetime</code><dd>will be replaced with current the date and time.
+ <dt><code>\$date</code><dd>will be replaced with the current date.
+ <dt><code>\$year</code><dd>will be replaces with the current year.
+ <dt><code>\$doxygenversion</code><dd>will be replaced with the version of doxygen
+ <dt><code>\$projectname</code><dd>will be replaced with the name of
+ the project (see \ref cfg_project_name "PROJECT_NAME")
+ <dt><code>\$projectnumber</code><dd>will be replaced with the project number
+ (see \ref cfg_project_number "PROJECT_NUMBER")
+ <dt><code>\$projectbrief</code><dd>will be replaced with the project brief
+ description (see \ref cfg_project_brief "PROJECT_BRIEF")
+ <dt><code>\$projectlogo</code><dd>will be replaced with the project logo
+ (see \ref cfg_project_logo "PROJECT_LOGO")
+ <dt><code>\$treeview</code><dd>will be replaced with links to
+ the javascript and style sheets needed for the navigation tree
+ (or an empty string when \ref cfg_generate_treeview "GENERATE_TREEVIEW"
+ is disabled).
+ <dt><code>\$search</code><dd>will be replaced with a links to
+ the javascript and style sheets needed for the search engine
+ (or an empty string when \ref cfg_searchengine "SEARCHENGINE"
+ is disabled).
+ <dt><code>\$mathjax</code><dd>will be replaced with a links to
+ the javascript and style sheets needed for the MathJax feature
+ (or an empty string when \ref cfg_use_mathjax "USE_MATHJAX" is disabled).
+ <dt><code>\$relpath^</code><dd>
+ If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command <code>\$relpath^</code> can be
+ used to produce a relative path to the root of the HTML output directory,
+ e.g. use <code>\$relpath^doxygen.css</code>, to refer to the standard style sheet.
+ </dl>
+
+ To cope with differences in the layout of the header and footer that depend on
+ configuration settings, the header can also contain special blocks that
+ will be copied to the output or skipped depending on the configuration.
+ Such blocks have the following form:
+\verbatim
+ <!--BEGIN BLOCKNAME-->
+ Some context copied when condition BLOCKNAME holds
+ <!--END BLOCKNAME-->
+ <!--BEGIN !BLOCKNAME-->
+ Some context copied when condition BLOCKNAME does not hold
+ <!--END !BLOCKNAME-->
+\endverbatim
+ The following block names are supported:
+ <dl>
+ <dt><code>DISABLE_INDEX</code><dd>Content within this block is copied to the output
+ when the \ref cfg_disable_index "DISABLE_INDEX" option is enabled (so when the index is disabled).
+ <dt><code>GENERATE_TREEVIEW</code><dd>Content within this block is copied to the output
+ when the \ref cfg_generate_treeview "GENERATE_TREEVIEW" option is enabled.
+ <dt><code>SEARCHENGINE</code><dd>Content within this block is copied to the output
+ when the \ref cfg_searchengine "SEARCHENGINE" option is enabled.
+ <dt><code>PROJECT_NAME</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_name "PROJECT_NAME" option is not empty.
+ <dt><code>PROJECT_NUMBER</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_number "PROJECT_NUMBER" option is not empty.
+ <dt><code>PROJECT_BRIEF</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_brief "PROJECT_BRIEF" option is not empty.
+ <dt><code>PROJECT_LOGO</code><dd>Content within the block is copied to the output
+ when the \ref cfg_project_logo "PROJECT_LOGO" option is not empty.
+ <dt><code>TITLEAREA</code><dd>Content within this block is copied to the output
+ when a title is visible at the top of each page. This is the case
+ if either \ref cfg_project_name "PROJECT_NAME",
+ \ref cfg_project_brief "PROJECT_BRIEF", \ref cfg_project_logo "PROJECT_LOGO"
+ is filled in or if both \ref cfg_disable_index "DISABLE_INDEX" and
+ \ref cfg_searchengine "SEARCHENGINE" are enabled.
+ </dl>
+]]>
+ </docs>
+ <docs documentation='0'>
+<![CDATA[
+ For a description of the possible markers and block names see the documentation.
+]]>
+ </docs>
+ </option>
+
+ <option type='string' id='HTML_FOOTER' format='file' defval='' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_FOOTER tag can be used to specify a user-defined HTML footer for
+ each generated HTML page.
+ If the tag is left blank doxygen will generate a standard footer.
+
+ See \ref cfg_html_header "HTML_HEADER" for more information on
+ how to generate a default footer and what special commands can be
+ used inside the footer.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the default footer that doxygen normally uses.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='HTML_STYLESHEET' format='file' defval='' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_STYLESHEET tag can be used to specify a user-defined cascading
+ style sheet that is used by each HTML page. It can be used to
+ fine-tune the look of the HTML output. If left blank doxygen
+ will generate a default style sheet.
+
+ See also section \ref doxygen_usage for information on how to generate
+ the style sheet that doxygen normally uses.
+
+ \note It is recommended to use
+ \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" instead of this tag,
+ as it is more robust and
+ this tag (<code>HTML_STYLESHEET</code>) will in the future become obsolete.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='HTML_EXTRA_STYLESHEET' format='file' defval='' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_EXTRA_STYLESHEET tag can be used to specify additional
+ user-defined cascading style sheets that are included after the standard
+ style sheets created by doxygen. Using this option one can overrule
+ certain style aspects. This is preferred over using \ref cfg_html_stylesheet "HTML_STYLESHEET"
+ since it does not replace the standard style sheet and is therefor more
+ robust against future updates. Doxygen will copy the style sheet files to
+ the output directory.
+ \note The order of the extra stylesheet files is of importance (e.g. the last
+ stylesheet in the list overrules the setting of the previous ones in the list).
+]]>
+ </docs>
+ <docs doxywizard='0' doxyfile='0'>
+<![CDATA[
+ Here is an example stylesheet that gives the contents area a fixed width:
+\verbatim
+body {
+ background-color: #CCC;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-bottom: 10px;
+ padding: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 960px;
+ background-color: white;
+ border-radius: 8px;
+}
+
+#titlearea {
+ background-color: white;
+}
+
+hr.footer {
+ display: none;
+}
+
+.footer {
+ background-color: #AAA;
+}
+\endverbatim
+]]>
+ </docs>
+ <docs documentation='0'>
+<![CDATA[
+ For an example see the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='HTML_EXTRA_FILES' format='file' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+ other source files which should be copied to the HTML output directory. Note
+ that these files will be copied to the base HTML output directory. Use the
+ <code>$relpath^</code> marker in the \ref cfg_html_header "HTML_HEADER" and/or
+ \ref cfg_html_footer "HTML_FOOTER" files to load these
+ files. In the \ref cfg_html_stylesheet "HTML_STYLESHEET" file, use the file name only. Also note that
+ the files will be copied as-is; there are no commands or markers available.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='HTML_COLORSTYLE_HUE' minval='0' maxval='359' defval='220' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+ Doxygen will adjust the colors in the stylesheet and background images
+ according to this color. Hue is specified as an angle on a colorwheel,
+ see http://en.wikipedia.org/wiki/Hue for more information.
+ For instance the value 0 represents red, 60 is yellow, 120 is green,
+ 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='HTML_COLORSTYLE_SAT' minval='0' maxval='255' defval='100' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+ the colors in the HTML output. For a value of 0 the output will use
+ grayscales only. A value of 255 will produce the most vivid colors.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='HTML_COLORSTYLE_GAMMA' minval='40' maxval='240' defval='80' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+ the luminance component of the colors in the HTML output. Values below
+ 100 gradually make the output lighter, whereas values above 100 make
+ the output darker. The value divided by 100 is the actual gamma applied,
+ so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+ and 100 does not change the gamma.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HTML_TIMESTAMP' defval='1' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c HTML_TIMESTAMP tag is set to \c YES then the footer of
+ each generated HTML page will contain the date and time when the page
+ was generated. Setting this to \c NO can help when comparing the output of
+ multiple runs.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HTML_DYNAMIC_SECTIONS' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c HTML_DYNAMIC_SECTIONS tag is set to \c YES then the generated HTML
+ documentation will contain sections that can be hidden and shown after the
+ page has loaded.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='HTML_INDEX_NUM_ENTRIES' minval='0' maxval='9999' defval='100' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ With \c HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+ entries shown in the various tree structured indices initially; the user
+ can expand and collapse entries dynamically later on. Doxygen will expand
+ the tree to such a level that at most the specified number of entries are
+ visible (unless a fully collapsed tree already exceeds this amount).
+ So setting the number of entries 1 will produce a full collapsed tree by
+ default. 0 is a special value representing an infinite number of entries
+ and will result in a full expanded tree by default.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_DOCSET' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_DOCSET tag is set to \c YES, additional index files
+ will be generated that can be used as input for
+ <a href="http://developer.apple.com/tools/xcode/">Apple's Xcode 3
+ integrated development environment</a>, introduced with OSX 10.5 (Leopard).
+ To create a documentation set, doxygen will generate a Makefile in the
+ HTML output directory. Running \c make will produce the docset in that
+ directory and running <code>make install</code> will install the docset in
+ <code>~/Library/Developer/Shared/Documentation/DocSets</code>
+ so that Xcode will find it at startup. See
+ http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for
+ more information.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOCSET_FEEDNAME' format='string' defval='Doxygen generated docs' depends='GENERATE_DOCSET'>
+ <docs>
+<![CDATA[
+ This tag determines the name of the docset
+ feed. A documentation feed provides an umbrella under which multiple
+ documentation sets from a single provider (such as a company or product suite)
+ can be grouped.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOCSET_BUNDLE_ID' format='string' defval='org.doxygen.Project' depends='GENERATE_DOCSET'>
+ <docs>
+<![CDATA[
+ This tag specifies a string that
+ should uniquely identify the documentation set bundle. This should be a
+ reverse domain-name style string, e.g. <code>com.mycompany.MyDocSet</code>.
+ Doxygen will append <code>.docset</code> to the name.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOCSET_PUBLISHER_ID' format='string' defval='org.doxygen.Publisher' depends='GENERATE_DOCSET'>
+ <docs>
+<![CDATA[
+The \c DOCSET_PUBLISHER_ID
+tag specifies a string that should uniquely identify
+the documentation publisher. This should be a reverse domain-name style
+string, e.g. <code>com.mycompany.MyDocSet.documentation</code>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOCSET_PUBLISHER_NAME' format='string' defval='Publisher' depends='GENERATE_DOCSET'>
+ <docs>
+<![CDATA[
+The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_HTMLHELP' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_HTMLHELP tag is set to \c YES then
+ doxygen generates three additional HTML index files:
+ \c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a
+ project file that can be read by
+ <a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138">
+ Microsoft's HTML Help Workshop</a>
+ on Windows.
+<br>
+ The HTML Help Workshop contains a compiler that can convert all HTML output
+ generated by doxygen into a single compiled HTML file (`.chm`). Compiled
+ HTML files are now used as the Windows 98 help format, and will replace
+ the old Windows help format (`.hlp`) on all Windows platforms in the future.
+ Compressed HTML files also contain an index, a table of contents,
+ and you can search for words in the documentation.
+ The HTML workshop also contains a viewer for compressed HTML files.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='CHM_FILE' format='file' defval='' depends='GENERATE_HTMLHELP'>
+ <docs>
+<![CDATA[
+ The \c CHM_FILE tag can
+ be used to specify the file name of the resulting `.chm` file. You
+ can add a path in front of the file if the result should not be
+ written to the html output directory.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='HHC_LOCATION' format='file' defval='' depends='GENERATE_HTMLHELP' abspath='1'>
+ <docs>
+<![CDATA[
+ The \c HHC_LOCATION tag can
+ be used to specify the location (absolute path including file name) of
+ the HTML help compiler (\c hhc.exe). If non-empty doxygen will try to run
+ the HTML help compiler on the generated \c index.hhp.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_CHI' defval='0' depends='GENERATE_HTMLHELP'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_CHI flag
+ controls if a separate `.chi` index file is generated (\c YES) or that
+ it should be included in the master `.chm` file (\c NO).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='CHM_INDEX_ENCODING' format='string' defval='' depends='GENERATE_HTMLHELP'>
+ <docs>
+<![CDATA[
+ The \c CHM_INDEX_ENCODING
+ is used to encode HtmlHelp index (\c hhk), content (\c hhc) and project file
+ content.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='BINARY_TOC' defval='0' depends='GENERATE_HTMLHELP'>
+ <docs>
+<![CDATA[
+ The \c BINARY_TOC flag
+ controls whether a binary table of contents is generated (\c YES) or a
+ normal table of contents (\c NO) in the `.chm` file. Furthermore it enables
+ the `Previous` and `Next` buttons.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='TOC_EXPAND' defval='0' depends='GENERATE_HTMLHELP'>
+ <docs>
+<![CDATA[
+ The \c TOC_EXPAND flag can be set to \c YES to add extra items for
+ group members to the table of contents of the HTML help documentation
+ and to the tree view.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_QHP' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_QHP tag is set to \c YES and both \ref cfg_qhp_namespace "QHP_NAMESPACE"
+ and \ref cfg_qhp_virtual_folder "QHP_VIRTUAL_FOLDER" are set, an additional index file will
+ be generated that can be used as input for Qt's qhelpgenerator
+ to generate a Qt Compressed Help (`.qch`) of the generated HTML
+ documentation.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QCH_FILE' format='file' defval='' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ If the \ref cfg_qhg_location "QHG_LOCATION" tag is specified, the \c QCH_FILE tag can
+ be used to specify the file name of the resulting `.qch` file.
+ The path specified is relative to the HTML output folder.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHP_NAMESPACE' format='string' defval='org.doxygen.Project' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ The \c QHP_NAMESPACE tag specifies the namespace to use when generating
+ Qt Help Project output. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHP_VIRTUAL_FOLDER' format='string' defval='doc' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ The \c QHP_VIRTUAL_FOLDER tag specifies the namespace to use when
+ generating Qt Help Project output. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHP_CUST_FILTER_NAME' format='string' defval='' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ If the \c QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom filter to add. For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHP_CUST_FILTER_ATTRS' format='string' defval='' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ The \c QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the custom filter to add.
+ For more information please see
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHP_SECT_FILTER_ATTRS' format='string' defval='' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ The \c QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's filter section matches.
+ <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='QHG_LOCATION' format='file' defval='' depends='GENERATE_QHP'>
+ <docs>
+<![CDATA[
+ The \c QHG_LOCATION tag can be used to specify the location of Qt's qhelpgenerator.
+ If non-empty doxygen will try to run qhelpgenerator on the generated `.qhp` file.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_ECLIPSEHELP' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_ECLIPSEHELP tag is set to \c YES, additional index files
+ will be generated, together with the HTML files, they form an `Eclipse` help
+ plugin.
+
+ To install this plugin and make it available under the help contents
+ menu in `Eclipse`, the contents of the directory containing the HTML and XML
+ files needs to be copied into the plugins directory of eclipse. The name of
+ the directory within the plugins directory should be the same as
+ the \ref cfg_eclipse_doc_id "ECLIPSE_DOC_ID" value.
+
+ After copying `Eclipse` needs to be restarted before the help appears.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='ECLIPSE_DOC_ID' format='string' defval='org.doxygen.Project' depends='GENERATE_ECLIPSEHELP'>
+ <docs>
+<![CDATA[
+ A unique identifier for the `Eclipse` help plugin. When installing the plugin
+ the directory name containing the HTML and XML files should also have
+ this name. Each documentation set should have its own identifier.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DISABLE_INDEX' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If you want full control over the layout of the generated HTML pages it
+ might be necessary to disable the index and replace it with your own.
+ The \c DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at
+ top of each HTML page. A value of \c NO enables the index and the
+ value \c YES disables it. Since the tabs in the index contain the same
+ information as the navigation tree, you can set this option to \c YES if
+ you also set \ref cfg_generate_treeview "GENERATE_TREEVIEW" to \c YES.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_TREEVIEW' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+ structure should be generated to display hierarchical information.
+ If the tag value is set to \c YES, a side panel will be generated
+ containing a tree-like index structure (just like the one that
+ is generated for HTML Help). For this to work a browser that supports
+ JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+ Windows users are probably better off using the HTML help feature.
+
+ Via custom stylesheets (see \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET")
+ one can further \ref doxygen_finetune "fine-tune" the look of the index.
+ As an example, the default style sheet generated by doxygen has an
+ example that shows how to put an image at the root of the tree instead of
+ the \ref cfg_project_name "PROJECT_NAME".
+
+ Since the tree basically has the same information as the tab index, you could
+ consider setting \ref cfg_disable_index "DISABLE_INDEX" to \c YES when
+ enabling this option.
+]]>
+ </docs>
+ </option>
+
+ <option type='int' id='ENUM_VALUES_PER_LINE' minval='0' maxval='20' defval='4' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ The \c ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+ that doxygen will group on one line in the generated HTML documentation.
+ <br>Note that a value of 0 will completely suppress the enum values from
+ appearing in the overview section.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='TREEVIEW_WIDTH' minval='0' maxval='1500' defval='250' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ If the treeview is enabled (see \ref cfg_generate_treeview "GENERATE_TREEVIEW") then this tag can be
+ used to set the initial width (in pixels) of the frame in which the tree
+ is shown.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXT_LINKS_IN_WINDOW' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ When the \c EXT_LINKS_IN_WINDOW option is set to \c YES doxygen will open
+ links to external symbols imported via tag files in a separate window.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='FORMULA_FONTSIZE' minval='8' maxval='50' defval='10' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ Use this tag to change the font size of \f$\mbox{\LaTeX}\f$ formulas included
+ as images in the HTML documentation.
+ When you change the font size after a successful doxygen run you need
+ to manually remove any `form_*.png` images from the HTML
+ output directory to force them to be regenerated.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='FORMULA_TRANSPARENT' defval='1' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ Use the \c FORMULA_TRANPARENT tag to determine whether or not the images
+ generated for formulas are transparent PNGs. Transparent PNGs are
+ not supported properly for IE 6.0, but are supported on all modern browsers.
+ <br>Note that when changing this option you need to delete any `form_*.png` files
+ in the HTML output directory before the changes have effect.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='USE_MATHJAX' defval='0' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ Enable the \c USE_MATHJAX option to render \f$\mbox{\LaTeX}\f$ formulas using MathJax
+ (see http://www.mathjax.org) which uses client side Javascript for the
+ rendering instead of using prerendered bitmaps. Use this if you do not
+ have \f$\mbox{\LaTeX}\f$ installed or if you want to formulas look prettier in the HTML
+ output. When enabled you may also need to install MathJax separately and
+ configure the path to it using the \ref cfg_mathjax_relpath "MATHJAX_RELPATH"
+ option.
+]]>
+ </docs>
+ </option>
+ <option type='enum' id='MATHJAX_FORMAT' defval='HTML-CSS' depends='USE_MATHJAX'>
+ <docs>
+<![CDATA[
+ When MathJax is enabled you can set the default output format to be used for
+ the MathJax output.
+ See <a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a>
+ for more details.
+]]>
+ </docs>
+ <value name="HTML-CSS" desc="(which is slower, but has the best compatibility)"/>
+ <value name="NativeMML" desc="(i.e. MathML)"/>
+ <value name="SVG"/>
+ </option>
+ <option type='string' id='MATHJAX_RELPATH' format='string' defval='http://cdn.mathjax.org/mathjax/latest' depends='USE_MATHJAX'>
+ <docs>
+<![CDATA[
+ When MathJax is enabled you need to specify the location relative to the
+ HTML output directory using the \c MATHJAX_RELPATH option. The destination
+ directory should contain the `MathJax.js` script. For instance, if the \c mathjax
+ directory is located at the same level as the HTML output directory, then
+ \c MATHJAX_RELPATH should be <code>../mathjax</code>. The default value points to
+ the MathJax Content Delivery Network so you can quickly see the result without
+ installing MathJax. However, it is strongly recommended to install a local
+ copy of MathJax from http://www.mathjax.org before deployment.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='MATHJAX_EXTENSIONS' format='string' depends='USE_MATHJAX'>
+ <docs>
+<![CDATA[
+ The \c MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax extension
+ names that should be enabled during MathJax rendering. For example
+\verbatim
+MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+\endverbatim
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MATHJAX_CODEFILE' format='string' depends='USE_MATHJAX'>
+ <docs>
+<![CDATA[
+ The \c MATHJAX_CODEFILE tag can be used to specify a file with javascript
+ pieces of code that will be used on startup of the MathJax code.
+ See
+<a href="http://docs.mathjax.org/en/latest/output.html">the MathJax site</a>
+ for more details.
+]]>
+ </docs>
+ <docs doxywizard='0' doxyfile='0'>
+<![CDATA[
+ As an example to disable the "Math Renderer" menu item in the "Math
+ Settings" menu of MathJax:
+\verbatim
+MATHJAX_CODEFILE = disableRenderer.js
+\endverbatim
+ with in the file <code>disableRenderer.js</code>:
+\verbatim
+ MathJax.Hub.Config({
+ menuSettings: {
+ showRenderer: false,
+ }
+ });
+\endverbatim
+]]>
+ </docs>
+ <docs documentation='0'>
+<![CDATA[
+ For an example see the documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SEARCHENGINE' defval='1' depends='GENERATE_HTML'>
+ <docs>
+<![CDATA[
+ When the \c SEARCHENGINE tag is enabled doxygen will generate a search box
+ for the HTML output. The underlying search engine uses javascript
+ and DHTML and should work on any modern browser. Note that when using
+ HTML help (\ref cfg_generate_htmlhelp "GENERATE_HTMLHELP"),
+ Qt help (\ref cfg_generate_qhp "GENERATE_QHP"), or docsets
+ (\ref cfg_generate_docset "GENERATE_DOCSET") there is already a search
+ function so this one should typically be disabled. For large projects
+ the javascript based search engine can be slow, then enabling
+ \ref cfg_server_based_search "SERVER_BASED_SEARCH" may provide a
+ better solution.
+
+ It is possible to search using the keyboard;
+ to jump to the search box use <code>\<access key\> + S</code> (what the <code>\<access key\></code> is
+ depends on the OS and browser, but it is typically <code>\<CTRL\></code>, <code>\<ALT\></code>/<code>\<option\></code>, or both).
+ Inside the search box use the <code>\<cursor down key\></code> to jump into the search
+ results window, the results can be navigated using the <code>\<cursor keys\></code>.
+ Press <code>\<Enter\></code> to select an item or <code>\<escape\></code> to cancel the search. The
+ filter options can be selected when the cursor is inside the search box
+ by pressing <code>\<Shift\>+\<cursor down\></code>. Also here use the <code>\<cursor keys\></code> to
+ select a filter and <code>\<Enter\></code> or <code>\<escape\></code> to activate or cancel the filter option.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SERVER_BASED_SEARCH' defval='0' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+When the \c SERVER_BASED_SEARCH tag is enabled the search engine will be
+implemented using a web server instead of a web client using Javascript.
+
+There are two flavors of web server based searching depending on the
+\ref cfg_external_search "EXTERNAL_SEARCH" setting. When disabled,
+doxygen will generate a PHP script for searching and an index file used
+by the script. When \ref cfg_external_search "EXTERNAL_SEARCH" is
+enabled the indexing and searching needs to be provided by external tools.
+See the section \ref extsearch for details.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTERNAL_SEARCH' defval='0' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+ When \c EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+ script for searching. Instead the search results are written to an XML file
+ which needs to be processed by an external indexer. Doxygen will invoke an
+ external search engine pointed to by the
+ \ref cfg_searchengine_url "SEARCHENGINE_URL" option to obtain
+ the search results.
+ <br>Doxygen ships with an example indexer (\c doxyindexer) and
+ search engine (<code>doxysearch.cgi</code>) which are based on the open source search
+ engine library <a href="http://xapian.org/">Xapian</a>.
+ <br>See the section \ref extsearch for details.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='SEARCHENGINE_URL' format='string' defval='' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+ The \c SEARCHENGINE_URL should point to a search engine hosted by a web server
+ which will return the search results when \ref cfg_external_search "EXTERNAL_SEARCH"
+ is enabled.
+ <br>Doxygen ships with an example indexer (\c doxyindexer) and
+ search engine (<code>doxysearch.cgi</code>) which are based on the open source search
+ engine library <a href="http://xapian.org/">Xapian</a>.
+ See the section \ref extsearch for details.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='SEARCHDATA_FILE' format='file' defval='searchdata.xml' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and
+\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the unindexed
+search data is written to a file for indexing by an external tool. With the
+\c SEARCHDATA_FILE tag the name of this file can be specified.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='EXTERNAL_SEARCH_ID' format='string' defval='' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+When \ref cfg_server_based_search "SERVER_BASED_SEARCH" and
+\ref cfg_external_search "EXTERNAL_SEARCH" are both enabled the
+\c EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+useful in combination with \ref cfg_extra_search_mappings "EXTRA_SEARCH_MAPPINGS"
+to search through multiple projects and redirect the results back to the right project.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXTRA_SEARCH_MAPPINGS' format='string' depends='SEARCHENGINE'>
+ <docs>
+<![CDATA[
+ The \c EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+ projects other than the one defined by this configuration file, but that are
+ all added to the same external search index. Each project needs to have a
+ unique id set via \ref cfg_external_search_id "EXTERNAL_SEARCH_ID".
+ The search mapping then maps the id of to a relative location where the
+ documentation can be found.
+
+ The format is:
+\verbatim
+EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+\endverbatim
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='LaTeX' docs='Configuration options related to the LaTeX output'>
+ <option type='bool' id='GENERATE_LATEX' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_LATEX tag is set to \c YES doxygen will
+ generate \f$\mbox{\LaTeX}\f$ output.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LATEX_OUTPUT' format='dir' defval='latex' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_OUTPUT tag is used to specify where the \f$\mbox{\LaTeX}\f$
+ docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LATEX_CMD_NAME' format='file' defval='latex' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_CMD_NAME tag can be used to specify the \f$\mbox{\LaTeX}\f$ command name to be invoked.
+ <br>Note that when enabling \ref cfg_use_pdflatex "USE_PDFLATEX" this option is only used for
+ generating bitmaps for formulas in the HTML output, but not in the
+ \c Makefile that is written to the output directory.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MAKEINDEX_CMD_NAME' format='file' defval='makeindex' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+ generate index for \f$\mbox{\LaTeX}\f$.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='COMPACT_LATEX' defval='0' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c COMPACT_LATEX tag is set to \c YES doxygen generates more compact
+ \f$\mbox{\LaTeX}\f$ documents. This may be useful for small projects and may help to
+ save some trees in general.
+]]>
+ </docs>
+ </option>
+ <option type='enum' id='PAPER_TYPE' defval='a4' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c PAPER_TYPE tag can be used to set the paper type that is used
+ by the printer.
+]]>
+ </docs>
+ <value name='a4' desc='(210 x 297 mm)'/>
+ <value name='letter' desc='(8.5 x 11 inches)'/>
+ <value name='legal' desc='(8.5 x 14 inches)'/>
+ <value name='executive' desc='(7.25 x 10.5 inches)'/>
+ </option>
+ <option type='list' id='EXTRA_PACKAGES' format='string' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c EXTRA_PACKAGES tag can be used to specify one or more \f$\mbox{\LaTeX}\f$
+ package names that should be included in the \f$\mbox{\LaTeX}\f$ output.
+ To get the times font for instance you can specify
+\verbatim
+EXTRA_PACKAGES=times
+\endverbatim
+ If left blank no extra packages will be included.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LATEX_HEADER' format='file' defval='' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_HEADER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$
+ header for the generated \f$\mbox{\LaTeX}\f$ document.
+ The header should contain everything until the first chapter.
+
+ If it is left blank doxygen will generate a
+ standard header. See section \ref doxygen_usage for information on how to
+ let doxygen write the default header to a separate file.
+
+ <br>Note: Only use a user-defined header if you know what you are doing!
+
+ The following commands have a special meaning inside the header:
+ <code>\$title</code>, <code>\$datetime</code>, <code>\$date</code>,
+ <code>\$doxygenversion</code>, <code>\$projectname</code>,
+ <code>\$projectnumber</code>, <code>\$projectbrief</code>,
+ <code>\$projectlogo</code>.
+ Doxygen will replace <code>\$title</code> with the empy string, for the replacement values of the
+ other commands the user is refered to \ref cfg_html_header "HTML_HEADER".
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LATEX_FOOTER' format='file' defval='' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_FOOTER tag can be used to specify a personal \f$\mbox{\LaTeX}\f$ footer for
+ the generated \f$\mbox{\LaTeX}\f$ document. The footer should contain everything after
+ the last chapter. If it is left blank doxygen will generate a
+ standard footer.
+ See \ref cfg_latex_header "LATEX_HEADER" for more information on
+ how to generate a default footer and what special commands can be
+ used inside the footer.
+
+ <br>Note: Only use a user-defined footer if you know what you are doing!
+]]>
+ </docs>
+ </option>
+ <option type='list' id='LATEX_EXTRA_FILES' format='file' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+ or other source files which should be copied to the \ref cfg_latex_output "LATEX_OUTPUT"
+ output directory.
+ Note that the files will be copied as-is; there are no commands or markers
+ available.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='PDF_HYPERLINKS' defval='1' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c PDF_HYPERLINKS tag is set to \c YES, the \f$\mbox{\LaTeX}\f$ that
+ is generated is prepared for conversion to PDF (using \c ps2pdf or \c pdflatex).
+ The PDF file will
+ contain links (just like the HTML output) instead of page references.
+ This makes the output suitable for online browsing using a PDF viewer.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='USE_PDFLATEX' defval='1' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c USE_PDFLATEX tag is set to \c YES, doxygen will use
+ \c pdflatex to generate the PDF file directly from the \f$\mbox{\LaTeX}\f$
+ files. Set this option to \c YES to get a higher quality PDF documentation.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='LATEX_BATCHMODE' defval='0' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c LATEX_BATCHMODE tag is set to \c YES, doxygen will add the \c \\batchmode
+ command to the generated \f$\mbox{\LaTeX}\f$ files. This will
+ instruct \f$\mbox{\LaTeX}\f$ to keep running if errors occur, instead of
+ asking the user for help. This option is also used when generating formulas
+ in HTML.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='LATEX_HIDE_INDICES' defval='0' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c LATEX_HIDE_INDICES tag is set to \c YES then doxygen will not
+ include the index chapters (such as File Index, Compound Index, etc.)
+ in the output.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='LATEX_SOURCE_CODE' defval='0' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ If the \c LATEX_SOURCE_CODE tag is set to \c YES then doxygen will include
+ source code with syntax highlighting in the \f$\mbox{\LaTeX}\f$ output.
+ <br>Note that which sources are shown also depends on other settings
+ such as \ref cfg_source_browser "SOURCE_BROWSER".
+]]>
+ </docs>
+ </option>
+ <option type='string' id='LATEX_BIB_STYLE' format='string' defval='plain' depends='GENERATE_LATEX'>
+ <docs>
+<![CDATA[
+ The \c LATEX_BIB_STYLE tag can be used to specify the style to use for the
+ bibliography, e.g. \c plainnat, or \c ieeetr.
+ See http://en.wikipedia.org/wiki/BibTeX and \ref cmdcite "\\cite"
+ for more info.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='RTF' docs='Configuration options related to the RTF output'>
+ <option type='bool' id='GENERATE_RTF' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_RTF tag is set to \c YES doxygen will generate RTF output.
+ The RTF output is optimized for Word 97 and may not look too pretty with
+ other RTF readers/editors.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='RTF_OUTPUT' format='dir' defval='rtf' depends='GENERATE_RTF'>
+ <docs>
+<![CDATA[
+ The \c RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='COMPACT_RTF' defval='0' depends='GENERATE_RTF'>
+ <docs>
+<![CDATA[
+ If the \c COMPACT_RTF tag is set to \c YES doxygen generates more compact
+ RTF documents. This may be useful for small projects and may help to
+ save some trees in general.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='RTF_HYPERLINKS' defval='0' depends='GENERATE_RTF'>
+ <docs>
+<![CDATA[
+ If the \c RTF_HYPERLINKS tag is set to \c YES, the RTF that is generated
+ will contain hyperlink fields. The RTF file will
+ contain links (just like the HTML output) instead of page references.
+ This makes the output suitable for online browsing using Word or some other
+ Word compatible readers that support those fields.
+
+ <br>Note: WordPad (write) and others do not support links.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='RTF_STYLESHEET_FILE' format='file' defval='' depends='GENERATE_RTF'>
+ <docs>
+<![CDATA[
+ Load stylesheet definitions from file. Syntax is similar to doxygen's
+ config file, i.e. a series of assignments. You only have to provide
+ replacements, missing definitions are set to their default value.
+<br>
+ See also section \ref doxygen_usage for information on how to generate
+ the default style sheet that doxygen normally uses.
+
+]]>
+ </docs>
+ </option>
+ <option type='string' id='RTF_EXTENSIONS_FILE' format='file' defval='' depends='GENERATE_RTF'>
+ <docs>
+<![CDATA[
+ Set optional variables used in the generation of an RTF document.
+ Syntax is similar to doxygen's config file.
+ A template extensions file can be generated using
+ <code>doxygen -e rtf extensionFile</code>.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Man' docs='Configuration options related to the man page output'>
+ <option type='bool' id='GENERATE_MAN' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_MAN tag is set to \c YES doxygen will
+ generate man pages for classes and files.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MAN_OUTPUT' format='dir' defval='man' depends='GENERATE_MAN'>
+ <docs>
+<![CDATA[
+ The \c MAN_OUTPUT tag is used to specify where the man pages will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+ A directory \c man3 will be created inside the directory specified by
+ \c MAN_OUTPUT.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MAN_EXTENSION' format='string' defval='.3' depends='GENERATE_MAN'>
+ <docs>
+<![CDATA[
+ The \c MAN_EXTENSION tag determines the extension that is added to
+ the generated man pages. In case
+ the manual section does not start with a number, the number 3 is prepended.
+ The dot (.) at the beginning of the \c MAN_EXTENSION tag is optional.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MAN_SUBDIR' format='string' defval='' depends='GENERATE_MAN'>
+ <docs>
+<![CDATA[
+ The \c MAN_SUBDIR tag determines the name of the directory created within \c MAN_OUTPUT
+ in which the man pages are placed. If defaults to man followed by \c MAN_EXTENSION
+ with the initial . removed.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='MAN_LINKS' defval='0' depends='GENERATE_MAN'>
+ <docs>
+<![CDATA[
+ If the \c MAN_LINKS tag is set to \c YES and doxygen generates man output,
+ then it will generate one additional man file for each entity documented in
+ the real man page(s). These additional files only source the real man page,
+ but without them the \c man command would be unable to find the correct page.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='XML' docs='Configuration options related to the XML output'>
+ <option type='bool' id='GENERATE_XML' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_XML tag is set to \c YES doxygen will
+ generate an XML file that captures the structure of
+ the code including all documentation.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='XML_OUTPUT' format='dir' defval='xml' depends='GENERATE_XML'>
+ <docs>
+<![CDATA[
+ The \c XML_OUTPUT tag is used to specify where the XML pages will be put.
+ If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+ put in front of it.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='XML_PROGRAMLISTING' defval='1' depends='GENERATE_XML'>
+ <docs>
+<![CDATA[
+ If the \c XML_PROGRAMLISTING tag is set to \c YES doxygen will
+ dump the program listings (including syntax highlighting
+ and cross-referencing information) to the XML output. Note that
+ enabling this will significantly increase the size of the XML output.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Docbook' docs='Configuration options related to the DOCBOOK output'>
+ <option type='bool' id='GENERATE_DOCBOOK' defval='0'>
+ <docs>
+<![CDATA[
+If the \c GENERATE_DOCBOOK tag is set to \c YES doxygen will generate Docbook files
+that can be used to generate PDF.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOCBOOK_OUTPUT' format='dir' defval='docbook' depends='GENERATE_DOCBOOK'>
+ <docs>
+<![CDATA[
+The \c DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be put in
+front of it.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DOCBOOK_PROGRAMLISTING' defval='0' depends='GENERATE_DOCBOOK'>
+ <docs>
+<![CDATA[
+ If the \c DOCBOOK_PROGRAMLISTING tag is set to \c YES doxygen will
+ include the program listings (including syntax highlighting
+ and cross-referencing information) to the DOCBOOK output. Note that
+ enabling this will significantly increase the size of the DOCBOOK output.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='AutoGen' docs='Configuration options for the AutoGen Definitions output'>
+ <option type='bool' id='GENERATE_AUTOGEN_DEF' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_AUTOGEN_DEF tag is set to \c YES doxygen will
+ generate an AutoGen Definitions (see http://autogen.sf.net) file
+ that captures the structure of the code including all
+ documentation. Note that this feature is still experimental
+ and incomplete at the moment.
+]]>
+ </docs>
+ </option>
+ </group>
+<!--
+ <group name='Sqlite3' docs='Configuration options related to Sqlite3 output'>
+ <option type='bool' id='GENERATE_SQLITE3' defval='0'>
+ <docs>
+<![CDATA[
+If the \c GENERATE_SQLITE3 tag is set to \c YES doxygen will generate a
+\c Sqlite3 database with symbols found by doxygen stored in tables.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='SQLITE3_OUTPUT' format='dir' defval='sqlite3' depends='GENERATE_SQLITE3'>
+ <docs>
+<![CDATA[
+The \c SQLITE3_OUTPUT tag is used to specify where the \c Sqlite3 database will be put.
+If a relative path is entered the value of \ref cfg_output_directory "OUTPUT_DIRECTORY" will be
+put in front of it.
+]]>
+ </docs>
+ </option>
+
+ </group>
+-->
+ <group name='PerlMod' docs='Configuration options related to the Perl module output'>
+ <option type='bool' id='GENERATE_PERLMOD' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_PERLMOD tag is set to \c YES doxygen will
+ generate a Perl module file that captures the structure of
+ the code including all documentation.
+ <br>Note that this
+ feature is still experimental and incomplete at the
+ moment.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='PERLMOD_LATEX' defval='0' depends='GENERATE_PERLMOD'>
+ <docs>
+<![CDATA[
+ If the \c PERLMOD_LATEX tag is set to \c YES doxygen will generate
+ the necessary \c Makefile rules, \c Perl scripts and \f$\mbox{\LaTeX}\f$ code to be able
+ to generate PDF and DVI output from the Perl module output.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='PERLMOD_PRETTY' defval='1' depends='GENERATE_PERLMOD'>
+ <docs>
+<![CDATA[
+ If the \c PERLMOD_PRETTY tag is set to \c YES the Perl module output will be
+ nicely formatted so it can be parsed by a human reader. This is useful
+ if you want to understand what is going on. On the other hand, if this
+ tag is set to \c NO the size of the Perl module output will be much smaller
+ and Perl will parse it just the same.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PERLMOD_MAKEVAR_PREFIX' format='string' defval='' depends='GENERATE_PERLMOD'>
+ <docs>
+<![CDATA[
+ The names of the make variables in the generated `doxyrules.make` file
+ are prefixed with the string contained in \c PERLMOD_MAKEVAR_PREFIX.
+ This is useful so different `doxyrules.make` files included by the same
+ `Makefile` don't overwrite each other's variables.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Preprocessor' docs='Configuration options related to the preprocessor'>
+ <option type='bool' id='ENABLE_PREPROCESSING' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c ENABLE_PREPROCESSING tag is set to \c YES doxygen will
+ evaluate all C-preprocessor directives found in the sources and include
+ files.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='MACRO_EXPANSION' defval='0' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ If the \c MACRO_EXPANSION tag is set to \c YES doxygen will expand all macro
+ names in the source code. If set to \c NO only conditional
+ compilation will be performed. Macro expansion can be done in a controlled
+ way by setting \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" to \c YES.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXPAND_ONLY_PREDEF' defval='0' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ If the \c EXPAND_ONLY_PREDEF and \ref cfg_macro_expansion "MACRO_EXPANSION" tags are both set to \c YES
+ then the macro expansion is limited to the macros specified with the
+ \ref cfg_predefined "PREDEFINED" and \ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tags.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SEARCH_INCLUDES' defval='1' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ If the \c SEARCH_INCLUDES tag is set to \c YES the includes files
+ in the \ref cfg_include_path "INCLUDE_PATH" will be searched if a \c \#include is found.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='INCLUDE_PATH' format='dir' depends='SEARCH_INCLUDES'>
+ <docs>
+<![CDATA[
+ The \c INCLUDE_PATH tag can be used to specify one or more directories that
+ contain include files that are not input files but should be processed by
+ the preprocessor.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='INCLUDE_FILE_PATTERNS' format='string' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ You can use the \c INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+ patterns (like `*.h` and `*.hpp`) to filter out the header-files in the
+ directories. If left blank, the patterns specified with \ref cfg_file_patterns "FILE_PATTERNS" will
+ be used.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='PREDEFINED' format='string' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ The \c PREDEFINED tag can be used to specify one or more macro names that
+ are defined before the preprocessor is started (similar to the `-D` option of
+ e.g. \c gcc). The argument of the tag is a list of macros of the form:
+ <code>name</code> or <code>name=definition</code> (no spaces).
+ If the definition and the \c "=" are omitted, \c "=1" is assumed. To prevent
+ a macro definition from being undefined via \c \#undef or recursively expanded
+ use the <code>:=</code> operator instead of the \c = operator.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='EXPAND_AS_DEFINED' format='string' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ If the \ref cfg_macro_expansion "MACRO_EXPANSION" and
+ \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" tags are set to \c YES then
+ this tag can be used to specify a list of macro names that should be expanded.
+ The macro definition that is found in the sources will be used.
+ Use the \ref cfg_predefined "PREDEFINED" tag if you want to use a different macro definition that
+ overrules the definition found in the source code.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='SKIP_FUNCTION_MACROS' defval='1' depends='ENABLE_PREPROCESSING'>
+ <docs>
+<![CDATA[
+ If the \c SKIP_FUNCTION_MACROS tag is set to \c YES then
+ doxygen's preprocessor will remove all references to function-like macros that are alone
+ on a line, have an all uppercase name, and do not end with a semicolon.
+ Such function macros are typically
+ used for boiler-plate code, and will confuse the parser if not removed.
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='External' docs='Configuration options related to external references'>
+ <option type='list' id='TAGFILES' format='file'>
+ <docs>
+<![CDATA[
+ The \c TAGFILES tag can be used to specify one or more tag files.
+
+For each
+tag file the location of the external documentation should be added. The
+format of a tag file without this location is as follows:
+\verbatim
+ TAGFILES = file1 file2 ...
+\endverbatim
+Adding location for the tag files is done as follows:
+\verbatim
+ TAGFILES = file1=loc1 "file2 = loc2" ...
+\endverbatim
+where `loc1` and `loc2` can be relative or absolute paths or URLs.
+ See the section \ref external for more information about the use of tag files.
+
+ \note
+ Each tag file must have a unique name
+ (where the name does \e NOT include the path).
+ If a tag file is not located in the directory in which doxygen
+ is run, you must also specify the path to the tagfile here.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='GENERATE_TAGFILE' format='file' defval=''>
+ <docs>
+<![CDATA[
+ When a file name is specified after \c GENERATE_TAGFILE, doxygen will create
+ a tag file that is based on the input files it reads.
+ See section \ref external for more information about the usage of
+ tag files.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='ALLEXTERNALS' defval='0'>
+ <docs>
+<![CDATA[
+ If the \c ALLEXTERNALS tag is set to \c YES all external class will be listed
+ in the class index. If set to \c NO only the inherited external classes
+ will be listed.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTERNAL_GROUPS' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c EXTERNAL_GROUPS tag is set to \c YES all external groups will be listed
+ in the modules index. If set to \c NO, only the current project's groups will
+ be listed.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='EXTERNAL_PAGES' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c EXTERNAL_PAGES tag is set to \c YES all external pages will be listed
+ in the related pages index. If set to \c NO, only the current project's
+ pages will be listed.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PERL_PATH' format='file' defval='/usr/bin/perl' abspath='1'>
+ <docs>
+<![CDATA[
+ The \c PERL_PATH should be the absolute path and name of the perl script
+ interpreter (i.e. the result of `'which perl'`).
+]]>
+ </docs>
+ </option>
+ </group>
+ <group name='Dot' docs='Configuration options related to the dot tool'>
+ <option type='bool' id='CLASS_DIAGRAMS' defval='1'>
+ <docs>
+<![CDATA[
+ If the \c CLASS_DIAGRAMS tag is set to \c YES doxygen will
+ generate a class diagram (in HTML and \f$\mbox{\LaTeX}\f$) for classes with base or
+ super classes. Setting the tag to \c NO turns the diagrams off. Note that
+ this option also works with \ref cfg_have_dot "HAVE_DOT" disabled, but it is recommended to
+ install and use \c dot, since it yields more powerful graphs.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='MSCGEN_PATH' format='dir' defval=''>
+ <docs>
+<![CDATA[
+ You can define message sequence charts within doxygen comments using the \ref cmdmsc "\\msc"
+ command. Doxygen will then run the <a href="http://www.mcternan.me.uk/mscgen/">mscgen tool</a>) to
+ produce the chart and insert it in the documentation. The <code>MSCGEN_PATH</code> tag allows you to
+ specify the directory where the \c mscgen tool resides. If left empty the tool is assumed to
+ be found in the default search path.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DIA_PATH' format='dir' defval=''>
+ <docs>
+<![CDATA[
+You can include diagrams made with dia in doxygen documentation. Doxygen will then run
+dia to produce the diagram and insert it in the documentation. The DIA_PATH tag allows
+you to specify the directory where the dia binary resides. If left empty dia is assumed
+to be found in the default search path.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HIDE_UNDOC_RELATIONS' defval='1'>
+ <docs>
+<![CDATA[
+ If set to \c YES, the inheritance and collaboration graphs will hide
+ inheritance and usage relations if the target is undocumented
+ or is not a class.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='HAVE_DOT' defval='0'>
+ <docs>
+<![CDATA[
+ If you set the \c HAVE_DOT tag to \c YES then doxygen will assume the \c dot tool is
+ available from the \c path. This tool is part of
+ <a href="http://www.graphviz.org/">Graphviz</a>, a graph
+ visualization toolkit from AT\&T and Lucent Bell Labs. The other options in
+ this section have no effect if this option is set to \c NO
+]]>
+ </docs>
+ </option>
+ <option type='int' id='DOT_NUM_THREADS' defval='0' minval='0' maxval='32' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOT_NUM_THREADS specifies the number of \c dot invocations doxygen is
+ allowed to run in parallel. When set to \c 0 doxygen will
+ base this on the number of processors available in the system. You can set it
+ explicitly to a value larger than 0 to get control over the balance
+ between CPU load and processing speed.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOT_FONTNAME' format='string' defval='Helvetica' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ When you want a differently looking font in the dot files that doxygen generates
+ you can specify the font name
+ using \c DOT_FONTNAME. You need to make sure dot is able to find the font,
+ which can be done by putting it in a standard location or by setting the
+ \c DOTFONTPATH environment variable or by setting \ref cfg_dot_fontpath "DOT_FONTPATH" to the
+ directory containing the font.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='DOT_FONTSIZE' minval='4' maxval='24' defval='10' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOT_FONTSIZE tag can be used to set the size (in points) of the font of dot graphs.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOT_FONTPATH' format='dir' defval='' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ By default doxygen will tell \c dot to use the default font as specified with \ref cfg_dot_fontname "DOT_FONTNAME".
+ If you specify a
+ different font using \ref cfg_dot_fontname "DOT_FONTNAME" you can set the path where \c dot
+ can find it using this tag.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CLASS_GRAPH' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c CLASS_GRAPH tag is set to \c YES then doxygen
+ will generate a graph for each documented class showing the direct and
+ indirect inheritance relations. Setting this tag to \c YES will force
+ the \ref cfg_class_diagrams "CLASS_DIAGRAMS" tag to \c NO.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='COLLABORATION_GRAPH' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c COLLABORATION_GRAPH tag is set to \c YES then doxygen
+ will generate a graph for each documented class showing the direct and
+ indirect implementation dependencies (inheritance, containment, and
+ class references variables) of the class with other documented classes.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GROUP_GRAPHS' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c GROUP_GRAPHS tag is set to \c YES then doxygen
+ will generate a graph for groups, showing the direct groups dependencies.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='UML_LOOK' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c UML_LOOK tag is set to \c YES doxygen will generate inheritance and
+ collaboration diagrams in a style similar to the OMG's Unified Modeling
+ Language.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='UML_LIMIT_NUM_FIELDS' defval='10' minval='0' maxval='100' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \ref cfg_uml_look "UML_LOOK" tag is enabled, the fields and methods are shown inside
+ the class node. If there are many fields or methods and many nodes the
+ graph may become too big to be useful. The \c UML_LIMIT_NUM_FIELDS
+ threshold limits the number of items for each type to make the size more
+ manageable. Set this to 0 for no limit. Note that the threshold may be
+ exceeded by 50% before the limit is enforced. So when you set the threshold
+ to 10, up to 15 fields may appear, but if the number exceeds 15, the
+ total amount of fields shown is limited to 10.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='TEMPLATE_RELATIONS' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c TEMPLATE_RELATIONS tag is set to \c YES then
+ the inheritance and collaboration graphs will show the relations between templates and their instances.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INCLUDE_GRAPH' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c INCLUDE_GRAPH, \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" and
+ \ref cfg_search_includes "SEARCH_INCLUDES"
+ tags are set to \c YES then doxygen will generate a graph for each documented file
+ showing the direct and indirect include dependencies of the file with other
+ documented files.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='INCLUDED_BY_GRAPH' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c INCLUDED_BY_GRAPH, \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" and
+ \ref cfg_search_includes "SEARCH_INCLUDES"
+ tags are set to \c YES then doxygen will generate a graph for each documented file
+ showing the direct and indirect include dependencies of the file with other
+ documented files.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CALL_GRAPH' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c CALL_GRAPH tag is set to \c YES then doxygen will
+ generate a call dependency graph for every global function or class method.
+ <br>Note that enabling this option will significantly increase the time of a run.
+ So in most cases it will be better to enable call graphs for selected
+ functions only using the \ref cmdcallgraph "\\callgraph" command.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='CALLER_GRAPH' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c CALLER_GRAPH tag is set to \c YES then doxygen will
+ generate a caller dependency graph for every global function or class method.
+ <br>Note that enabling this option will significantly increase the time of a run.
+ So in most cases it will be better to enable caller graphs for selected
+ functions only using the \ref cmdcallergraph "\\callergraph" command.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GRAPHICAL_HIERARCHY' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c GRAPHICAL_HIERARCHY tag is set to \c YES then
+ doxygen will graphical hierarchy of all classes instead of a textual one.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DIRECTORY_GRAPH' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c DIRECTORY_GRAPH tag is set
+ to \c YES then doxygen will show the dependencies a directory has on other directories
+ in a graphical way. The dependency relations are determined by the \c \#include
+ relations between the files in the directories.
+]]>
+ </docs>
+ </option>
+ <option type='enum' id='DOT_IMAGE_FORMAT' defval='png' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+ generated by \c dot.
+ \note If you choose \c svg you need to set
+ \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order to make the SVG files
+ visible in IE 9+ (other browsers do not have this requirement).
+]]>
+ </docs>
+ <value name='png'/>
+ <value name='jpg'/>
+ <value name='gif'/>
+ <value name='svg'/>
+ </option>
+ <option type='bool' id='INTERACTIVE_SVG' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If \ref cfg_dot_image_format "DOT_IMAGE_FORMAT" is set to \c svg, then this option can be set to \c YES to
+ enable generation of interactive SVG images that allow zooming and panning.
+ <br>Note that this requires a modern browser other than Internet Explorer.
+ Tested and working are Firefox, Chrome, Safari, and Opera.
+ \note For IE 9+ you need to set \ref cfg_html_file_extension "HTML_FILE_EXTENSION" to \c xhtml in order
+ to make the SVG files visible. Older versions of IE do not have SVG support.
+]]>
+ </docs>
+ </option>
+ <option type='string' id='DOT_PATH' format='dir' defval='' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOT_PATH tag can be used to specify the path where the \c dot tool can be found.
+ If left blank, it is assumed the \c dot tool can be found in the \c path.
+]]>
+ </docs>
+ </option>
+ <option type='list' id='DOTFILE_DIRS' format='dir' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOTFILE_DIRS tag can be used to specify one or more directories that
+ contain dot files that are included in the documentation (see the
+ \ref cmddotfile "\\dotfile" command).
+]]>
+ </docs>
+ </option>
+ <option type='list' id='MSCFILE_DIRS' format='dir'>
+ <docs>
+<![CDATA[
+ The \c MSCFILE_DIRS tag can be used to specify one or more directories that
+ contain msc files that are included in the documentation (see the
+ \ref cmdmscfile "\\mscfile" command).
+]]>
+ </docs>
+ </option>
+ <option type='list' id='DIAFILE_DIRS' format='dir'>
+ <docs>
+<![CDATA[
+ The \c DIAFILE_DIRS tag can be used to specify one or more directories that
+ contain dia files that are included in the documentation (see the
+ \ref cmdmscfile "\\diafile" command).
+]]>
+ </docs>
+ </option>
+ <option type='string' id='PLANTUML_JAR_PATH' format='dir' defval='' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ When using plantuml, the \c PLANTUML_JAR_PATH tag should be used to specify the path where
+ java can find the \c plantuml.jar file. If left blank, it is assumed PlantUML is not used or
+ called during a preprocessing step. Doxygen will generate a warning when it encounters a
+ \ref cmdstartuml "\\startuml" command in this case and will not generate output for the diagram.
+]]>
+ </docs>
+ </option>
+ <option type='int' id='DOT_GRAPH_MAX_NODES' minval='0' maxval='10000' defval='50' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+ nodes that will be shown in the graph. If the number of nodes in a graph
+ becomes larger than this value, doxygen will truncate the graph, which is
+ visualized by representing a node as a red box. Note that doxygen if the number
+ of direct children of the root node in a graph is already larger than
+ \c DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+ that the size of a graph can be further restricted by \ref cfg_max_dot_graph_depth "MAX_DOT_GRAPH_DEPTH".
+]]>
+ </docs>
+ </option>
+ <option type='int' id='MAX_DOT_GRAPH_DEPTH' minval='0' maxval='1000' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ The \c MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+ graphs generated by \c dot. A depth value of 3 means that only nodes reachable
+ from the root by following a path via at most 3 edges will be shown. Nodes
+ that lay further from the root node will be omitted. Note that setting this
+ option to 1 or 2 may greatly reduce the computation time needed for large
+ code bases. Also note that the size of a graph can be further restricted by
+ \ref cfg_dot_graph_max_nodes "DOT_GRAPH_MAX_NODES". Using a depth of 0 means no depth restriction.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DOT_TRANSPARENT' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ Set the \c DOT_TRANSPARENT tag to \c YES to generate images with a transparent
+ background. This is disabled by default, because dot on Windows does not
+ seem to support this out of the box.
+ <br>
+ Warning: Depending on the platform used,
+ enabling this option may lead to badly anti-aliased labels on the edges of
+ a graph (i.e. they become hard to read).
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DOT_MULTI_TARGETS' defval='0' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ Set the \c DOT_MULTI_TARGETS tag to \c YES allow dot to generate multiple output
+ files in one run (i.e. multiple -o and -T options on the command line). This
+ makes \c dot run faster, but since only newer versions of \c dot (>1.8.10)
+ support this, this feature is disabled by default.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='GENERATE_LEGEND' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+ If the \c GENERATE_LEGEND tag is set to \c YES doxygen will
+ generate a legend page explaining the meaning of the various boxes and
+ arrows in the dot generated graphs.
+]]>
+ </docs>
+ </option>
+ <option type='bool' id='DOT_CLEANUP' defval='1' depends='HAVE_DOT'>
+ <docs>
+<![CDATA[
+If the \c DOT_CLEANUP tag is set to \c YES doxygen will
+remove the intermediate dot files that are used to generate the various graphs.
+]]>
+ </docs>
+ </option>
+ <option type='obsolete' id='USE_WINDOWS_ENCODING'/>
+ <option type='obsolete' id='DETAILS_AT_TOP'/>
+ <option type='obsolete' id='QTHELP_FILE'/>
+ <option type='obsolete' id='QTHELP_CONFIG'/>
+ <option type='obsolete' id='DOXYGEN2QTHELP_LOC'/>
+ <option type='obsolete' id='MAX_DOT_GRAPH_WIDTH'/>
+ <option type='obsolete' id='MAX_DOT_GRAPH_HEIGHT'/>
+ <option type='obsolete' id='CGI_NAME'/>
+ <option type='obsolete' id='CGI_URL'/>
+ <option type='obsolete' id='DOC_URL'/>
+ <option type='obsolete' id='DOC_ABSPATH'/>
+ <option type='obsolete' id='BIN_ABSPATH'/>
+ <option type='obsolete' id='EXT_DOC_PATHS'/>
+ <option type='obsolete' id='USE_INLINE_TREES'/>
+ <option type='obsolete' id='SHOW_DIRECTORIES'/>
+ <option type='obsolete' id='HTML_ALIGN_MEMBERS'/>
+ <option type='obsolete' id='SYMBOL_CACHE_SIZE'/>
+ <option type='obsolete' id='XML_SCHEMA'/>
+ <option type='obsolete' id='XML_DTD'/>
+ </group>
+</doxygenconfig>
diff --git a/src/configgen.py b/src/configgen.py
new file mode 100755
index 0000000..04ffc8c
--- /dev/null
+++ b/src/configgen.py
@@ -0,0 +1,649 @@
+#!/usr/bin/python
+# python script to generate configoptions.cpp and config.doc from config.xml
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+import xml.dom.minidom
+import sys
+import re
+import textwrap
+from xml.dom import minidom, Node
+
+def transformDocs(doc):
+ # join lines, unless it is an empty line
+ # remove doxygen layout constructs
+ doc = doc.strip()
+ doc = doc.replace("\n", " ")
+ doc = doc.replace("\r", " ")
+ doc = doc.replace("\t", " ")
+ doc = doc.replace("\\&", "&")
+ doc = doc.replace("\\c ", " ")
+ doc = doc.replace("\\b ", " ")
+ doc = doc.replace("\\e ", " ")
+ doc = doc.replace("\\$", "$")
+ doc = doc.replace("\\#include ", "#include ")
+ doc = doc.replace("\\#undef ", "#undef ")
+ doc = doc.replace("-# ", "\n - ")
+ doc = doc.replace(" - ", "\n - ")
+ doc = doc.replace("\\sa", "\nSee also: ")
+ doc = doc.replace("\\par", "\n")
+ doc = doc.replace("@note", "\nNote:")
+ doc = doc.replace("\\note", "\nNote:")
+ doc = doc.replace("\\verbatim", "\n")
+ doc = doc.replace("\\endverbatim", "\n")
+ doc = doc.replace("<code>", "")
+ doc = doc.replace("</code>", "")
+ doc = doc.replace("`", "")
+ doc = doc.replace("\\<", "<")
+ doc = doc.replace("\\>", ">")
+ doc = doc.replace("\\@", "@")
+ doc = doc.replace("\\\\", "\\")
+ # \ref name "description" -> description
+ doc = re.sub('\\\\ref +[^ ]* +"([^"]*)"', '\\1', doc)
+ # \ref specials
+ # \ref <key> -> description
+ doc = re.sub('\\\\ref +doxygen_usage', '"Doxygen usage"', doc)
+ doc = re.sub('\\\\ref +extsearch', '"External Indexing and Searching"',
+ doc)
+ doc = re.sub('\\\\ref +external', '"Linking to external documentation"',
+ doc)
+ # fallback for not handled
+ doc = re.sub('\\\\ref', '', doc)
+ #<a href="address">description</a> -> description (see: address)
+ doc = re.sub('<a +href="([^"]*)" *>([^<]*)</a>', '\\2 (see: \\1)', doc)
+ # LaTeX name as formula -> LaTeX
+ doc = doc.replace("\\f$\\mbox{\\LaTeX}\\f$", "LaTeX")
+ # Other forula's (now just 2) so explicitely mentioned.
+ doc = doc.replace("\\f$2^{(16+\\mbox{LOOKUP\\_CACHE\\_SIZE})}\\f$",
+ "2^(16+LOOKUP_CACHE_SIZE)")
+ doc = doc.replace("\\f$2^{16} = 65536\\f$", "2^16=65536")
+ # remove consecutive spaces
+ doc = re.sub(" +", " ", doc)
+ # a dirty trick to get an extra empty line in Doxyfile documentation.
+ # <br> will be removed later on again, we need it here otherwise splitlines
+ # will filter the extra line.
+ doc = doc.replace("<br>", "\n<br>\n")
+ # a dirty trick to go to the next line in Doxyfile documentation.
+ # <br/> will be removed later on again, we need it here otherwise splitlines
+ # will filter the line break.
+ doc = doc.replace("<br/>", "\n<br/>\n")
+ #
+ doc = doc.splitlines()
+ split_doc = []
+ for line in doc:
+ split_doc += textwrap.wrap(line, 78)
+ # replace \ by \\, replace " by \", and ' ' by a newline with end string
+ # and start string at next line
+ docC = []
+ for line in split_doc:
+ if (line.strip() != "<br/>"):
+ docC.append(line.strip().replace('\\', '\\\\').
+ replace('"', '\\"').replace("<br>", ""))
+ return docC
+
+
+def collectValues(node):
+ values = []
+ for n in node.childNodes:
+ if (n.nodeName == "value"):
+ if n.nodeType == Node.ELEMENT_NODE:
+ if n.getAttribute('name') != "":
+ if n.getAttribute('show_docu') != "NO":
+ name = "<code>" + n.getAttribute('name') + "</code>"
+ desc = n.getAttribute('desc')
+ if (desc != ""):
+ name += " " + desc
+ values.append(name)
+ return values
+
+
+def addValues(var, node):
+ for n in node.childNodes:
+ if (n.nodeName == "value"):
+ if n.nodeType == Node.ELEMENT_NODE:
+ name = n.getAttribute('name')
+ print(" %s->addValue(\"%s\");" % (var, name))
+
+
+def parseHeader(node,objName):
+ doc = ""
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "docs"):
+ if (n.getAttribute('doxyfile') != "0"):
+ doc += parseDocs(n)
+ docC = transformDocs(doc)
+ print(" %s->setHeader(" % (objName))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"" % (line))
+ print(" );")
+
+
+def prepCDocs(node):
+ type = node.getAttribute('type')
+ format = node.getAttribute('format')
+ defval = node.getAttribute('defval')
+ adefval = node.getAttribute('altdefval')
+ doc = "";
+ if (type != 'obsolete'):
+ for n in node.childNodes:
+ if (n.nodeName == "docs"):
+ if (n.getAttribute('doxyfile') != "0"):
+ if n.nodeType == Node.ELEMENT_NODE:
+ doc += parseDocs(n)
+ if (type == 'enum'):
+ values = collectValues(node)
+ doc += "<br/>Possible values are: "
+ rng = len(values)
+ for i in range(rng):
+ val = values[i]
+ if i == rng - 2:
+ doc += "%s and " % (val)
+ elif i == rng - 1:
+ doc += "%s." % (val)
+ else:
+ doc += "%s, " % (val)
+ if (defval != ""):
+ doc += "<br/>The default value is: <code>%s</code>." % (defval)
+ elif (type == 'int'):
+ minval = node.getAttribute('minval')
+ maxval = node.getAttribute('maxval')
+ doc += "<br/>%s: %s, %s: %s, %s: %s." % (" Minimum value", minval,
+ "maximum value", maxval,
+ "default value", defval)
+ elif (type == 'bool'):
+ if (node.hasAttribute('altdefval')):
+ doc += "<br/>%s: %s." % ("The default value is", "system dependent")
+ else:
+ doc += "<br/>%s: %s." % ("The default value is", "YES" if (defval == "1") else "NO")
+ elif (type == 'list'):
+ if format == 'string':
+ values = collectValues(node)
+ rng = len(values)
+ for i in range(rng):
+ val = values[i]
+ if i == rng - 2:
+ doc += "%s and " % (val)
+ elif i == rng - 1:
+ doc += "%s." % (val)
+ else:
+ doc += "%s, " % (val)
+ elif (type == 'string'):
+ if format == 'dir':
+ if defval != '':
+ doc += "<br/>The default directory is: <code>%s</code>." % (
+ defval)
+ elif format == 'file':
+ abspath = node.getAttribute('abspath')
+ if defval != '':
+ if abspath != '1':
+ doc += "<br/>The default file is: <code>%s</code>." % (
+ defval)
+ else:
+ doc += "<br/>%s: %s%s%s." % (
+ "The default file (with absolute path) is",
+ "<code>",defval,"</code>")
+ else:
+ if abspath == '1':
+ doc += "<br/>The file has to be specified with full path."
+ elif format =='image':
+ abspath = node.getAttribute('abspath')
+ if defval != '':
+ if abspath != '1':
+ doc += "<br/>The default image is: <code>%s</code>." % (
+ defval)
+ else:
+ doc += "<br/>%s: %s%s%s." % (
+ "The default image (with absolute path) is",
+ "<code>",defval,"</code>")
+ else:
+ if abspath == '1':
+ doc += "<br/>The image has to be specified with full path."
+ else: # format == 'string':
+ if defval != '':
+ doc += "<br/>The default value is: <code>%s</code>." % (
+ defval)
+ # depends handling
+ if (node.hasAttribute('depends')):
+ depends = node.getAttribute('depends')
+ doc += "<br/>%s \\ref cfg_%s \"%s\" is set to \\c YES." % (
+ "This tag requires that the tag", depends.lower(), depends.upper())
+
+ docC = transformDocs(doc)
+ return docC;
+
+def parseOption(node):
+ # Handling part for Doxyfile
+ name = node.getAttribute('id')
+ type = node.getAttribute('type')
+ format = node.getAttribute('format')
+ defval = node.getAttribute('defval')
+ adefval = node.getAttribute('altdefval')
+ depends = node.getAttribute('depends')
+ setting = node.getAttribute('setting')
+ docC = prepCDocs(node);
+ if len(setting) > 0:
+ print("#if %s" % (setting))
+ print(" //----")
+ if type == 'bool':
+ if len(adefval) > 0:
+ enabled = adefval
+ elif defval == '1':
+ enabled = "TRUE"
+ else:
+ enabled = "FALSE"
+ print(" cb = cfg->addBool(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"," % (line))
+ print(" %s" % (enabled))
+ print(" );")
+ if depends != '':
+ print(" cb->addDependency(\"%s\");" % (depends))
+ elif type == 'string':
+ print(" cs = cfg->addString(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"" % (line))
+ print(" );")
+ if defval != '':
+ print(" cs->setDefaultValue(\"%s\");" % (defval))
+ if format == 'file':
+ print(" cs->setWidgetType(ConfigString::File);")
+ elif format == 'image':
+ print(" cs->setWidgetType(ConfigString::Image);")
+ elif format == 'dir':
+ print(" cs->setWidgetType(ConfigString::Dir);")
+ if depends != '':
+ print(" cs->addDependency(\"%s\");" % (depends))
+ elif type == 'enum':
+ print(" ce = cfg->addEnum(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"," % (line))
+ print(" \"%s\"" % (defval))
+ print(" );")
+ addValues("ce", node)
+ if depends != '':
+ print(" ce->addDependency(\"%s\");" % (depends))
+ elif type == 'int':
+ minval = node.getAttribute('minval')
+ maxval = node.getAttribute('maxval')
+ print(" ci = cfg->addInt(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"," % (line))
+ print(" %s,%s,%s" % (minval, maxval, defval))
+ print(" );")
+ if depends != '':
+ print(" ci->addDependency(\"%s\");" % (depends))
+ elif type == 'list':
+ print(" cl = cfg->addList(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"" % (line))
+ print(" );")
+ addValues("cl", node)
+ if depends != '':
+ print(" cl->addDependency(\"%s\");" % (depends))
+ if format == 'file':
+ print(" cl->setWidgetType(ConfigList::File);")
+ elif format == 'dir':
+ print(" cl->setWidgetType(ConfigList::Dir);")
+ elif format == 'filedir':
+ print(" cl->setWidgetType(ConfigList::FileAndDir);")
+ elif type == 'obsolete':
+ print(" cfg->addObsolete(\"%s\");" % (name))
+ if len(setting) > 0:
+ print("#else")
+ print(" cfg->addDisabled(\"%s\");" % (name))
+ print("#endif")
+
+
+def parseGroups(node):
+ name = node.getAttribute('name')
+ doc = node.getAttribute('docs')
+ print("%s%s" % (" //-----------------------------------------",
+ "----------------------------------"))
+ print(" cfg->addInfo(\"%s\",\"%s\");" % (name, doc))
+ print("%s%s" % (" //-----------------------------------------",
+ "----------------------------------"))
+ print("")
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ parseOption(n)
+
+def parseGroupCDocs(node):
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ type = n.getAttribute('type')
+ name = n.getAttribute('id')
+ docC = prepCDocs(n);
+ if type != 'obsolete':
+ print(" doc->add(")
+ print(" \"%s\"," % (name))
+ rng = len(docC)
+ for i in range(rng):
+ line = docC[i]
+ if i != rng - 1: # since we go from 0 to rng-1
+ print(" \"%s\\n\"" % (line))
+ else:
+ print(" \"%s\"" % (line))
+ print(" );")
+
+def parseOptionDoc(node, first):
+ # Handling part for documentation
+ name = node.getAttribute('id')
+ type = node.getAttribute('type')
+ format = node.getAttribute('format')
+ defval = node.getAttribute('defval')
+ adefval = node.getAttribute('altdefval')
+ depends = node.getAttribute('depends')
+ setting = node.getAttribute('setting')
+ doc = ""
+ if (type != 'obsolete'):
+ for n in node.childNodes:
+ if (n.nodeName == "docs"):
+ if (n.getAttribute('documentation') != "0"):
+ if n.nodeType == Node.ELEMENT_NODE:
+ doc += parseDocs(n)
+ if (first):
+ print(" \\anchor cfg_%s" % (name.lower()))
+ print("<dl>")
+ print("")
+ print("<dt>\\c %s <dd>" % (name))
+ else:
+ print(" \\anchor cfg_%s" % (name.lower()))
+ print("<dt>\\c %s <dd>" % (name))
+ print(" \\addindex %s" % (name))
+ print(doc)
+ if (type == 'enum'):
+ values = collectValues(node)
+ print("")
+ print("Possible values are: ")
+ rng = len(values)
+ for i in range(rng):
+ val = values[i]
+ if i == rng - 2:
+ print("%s and " % (val))
+ elif i == rng - 1:
+ print("%s." % (val))
+ else:
+ print("%s, " % (val))
+ if (defval != ""):
+ print("")
+ print("")
+ print("The default value is: <code>%s</code>." % (defval))
+ print("")
+ elif (type == 'int'):
+ minval = node.getAttribute('minval')
+ maxval = node.getAttribute('maxval')
+ print("")
+ print("")
+ print("%s: %s%s%s, %s: %s%s%s, %s: %s%s%s." % (
+ " Minimum value", "<code>", minval, "</code>",
+ "maximum value", "<code>", maxval, "</code>",
+ "default value", "<code>", defval, "</code>"))
+ print("")
+ elif (type == 'bool'):
+ print("")
+ print("")
+ if (node.hasAttribute('altdefval')):
+ print("The default value is: system dependent.")
+ else:
+ print("The default value is: <code>%s</code>." % (
+ "YES" if (defval == "1") else "NO"))
+ print("")
+ elif (type == 'list'):
+ if format == 'string':
+ values = collectValues(node)
+ rng = len(values)
+ for i in range(rng):
+ val = values[i]
+ if i == rng - 2:
+ print("%s and " % (val))
+ elif i == rng - 1:
+ print("%s." % (val))
+ else:
+ print("%s, " % (val))
+ print("")
+ elif (type == 'string'):
+ if format == 'dir':
+ if defval != '':
+ print("")
+ print("The default directory is: <code>%s</code>." % (
+ defval))
+ elif format == 'file':
+ abspath = node.getAttribute('abspath')
+ if defval != '':
+ print("")
+ if abspath != '1':
+ print("The default file is: <code>%s</code>." % (
+ defval))
+ else:
+ print("%s: %s%s%s." % (
+ "The default file (with absolute path) is",
+ "<code>",defval,"</code>"))
+ else:
+ if abspath == '1':
+ print("")
+ print("The file has to be specified with full path.")
+ elif format =='image':
+ abspath = node.getAttribute('abspath')
+ if defval != '':
+ print("")
+ if abspath != '1':
+ print("The default image is: <code>%s</code>." % (
+ defval))
+ else:
+ print("%s: %s%s%s." % (
+ "The default image (with absolute path) is",
+ "<code>",defval,"</code>"))
+ else:
+ if abspath == '1':
+ print("")
+ print("The image has to be specified with full path.")
+ else: # format == 'string':
+ if defval != '':
+ print("")
+ print("The default value is: <code>%s</code>." % (
+ defval))
+ print("")
+ # depends handling
+ if (node.hasAttribute('depends')):
+ depends = node.getAttribute('depends')
+ print("")
+ print("%s \\ref cfg_%s \"%s\" is set to \\c YES." % (
+ "This tag requires that the tag", depends.lower(), depends.upper()))
+ return False
+
+
+def parseGroupsDoc(node):
+ name = node.getAttribute('name')
+ doc = node.getAttribute('docs')
+ print("\section config_%s %s" % (name.lower(), doc))
+ # Start of list has been moved to the first option for better
+ # anchor placement
+ # print "<dl>"
+ # print ""
+ first = True
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ first = parseOptionDoc(n, first)
+ if (not first):
+ print("</dl>")
+
+
+def parseGroupsList(node, commandsList):
+ list = ()
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ type = n.getAttribute('type')
+ if type != 'obsolete':
+ commandsList = commandsList + (n.getAttribute('id'),)
+ return commandsList
+
+
+def parseDocs(node):
+ doc = ""
+ for n in node.childNodes:
+ if n.nodeType == Node.TEXT_NODE:
+ doc += n.nodeValue.strip()
+ if n.nodeType == Node.CDATA_SECTION_NODE:
+ doc += n.nodeValue.rstrip("\r\n ").lstrip("\r\n")
+ #doc += "<br>"
+ return doc
+
+
+def parseHeaderDoc(node):
+ doc = ""
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "docs"):
+ if (n.getAttribute('documentation') != "0"):
+ doc += parseDocs(n)
+ print(doc)
+
+
+def parseFooterDoc(node):
+ doc = ""
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "docs"):
+ if (n.getAttribute('documentation') != "0"):
+ doc += parseDocs(n)
+ print(doc)
+
+
+def main():
+ if len(sys.argv)<3 or (not sys.argv[1] in ['-doc','-cpp','-wiz']):
+ sys.exit('Usage: %s -doc|-cpp|-wiz config.xml' % sys.argv[0])
+ try:
+ doc = xml.dom.minidom.parse(sys.argv[2])
+ except Exception as inst:
+ sys.stdout = sys.stderr
+ print("")
+ print(inst)
+ print("")
+ sys.exit(1)
+ elem = doc.documentElement
+ if (sys.argv[1] == "-doc"):
+ print("/* WARNING: This file is generated!")
+ print(" * Do not edit this file, but edit config.xml instead and run")
+ print(" * python configgen.py -doc config.xml to regenerate this file!")
+ print(" */")
+ # process header
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "header"):
+ parseHeaderDoc(n)
+ # generate list with all commands
+ commandsList = ()
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ commandsList = parseGroupsList(n, commandsList)
+ print("\\secreflist")
+ for x in sorted(commandsList):
+ print("\\refitem cfg_%s %s" % (x.lower(), x))
+ print("\\endsecreflist")
+ # process groups and options
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ parseGroupsDoc(n)
+ # process footers
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "footer"):
+ parseFooterDoc(n)
+ elif (sys.argv[1] == "-cpp"):
+ print("/* WARNING: This file is generated!")
+ print(" * Do not edit this file, but edit config.xml instead and run")
+ print(" * python configgen.py -cpp config.xml to regenerate this file!")
+ print(" */")
+ print("")
+ print("#include \"configoptions.h\"")
+ print("#include \"config.h\"")
+ print("#include \"portable.h\"")
+ print("#include \"settings.h\"")
+ print("")
+ print("void addConfigOptions(Config *cfg)")
+ print("{")
+ print(" ConfigString *cs;")
+ print(" ConfigEnum *ce;")
+ print(" ConfigList *cl;")
+ print(" ConfigInt *ci;")
+ print(" ConfigBool *cb;")
+ print("")
+ # process header
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "header"):
+ parseHeader(n,'cfg')
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ parseGroups(n)
+ print("}")
+ elif (sys.argv[1] == "-wiz"):
+ print("/* WARNING: This file is generated!")
+ print(" * Do not edit this file, but edit config.xml instead and run")
+ print(" * python configgen.py -wiz config.xml to regenerate this file!")
+ print(" */")
+ print("#include \"configdoc.h\"")
+ print("#include \"docintf.h\"")
+ print("")
+ print("void addConfigDocs(DocIntf *doc)")
+ print("{")
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "header"):
+ parseHeader(n,'doc')
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ parseGroupCDocs(n)
+ print("}")
+
+if __name__ == '__main__':
+ main()
diff --git a/src/configoptions.h b/src/configoptions.h
new file mode 100644
index 0000000..be8ecf6
--- /dev/null
+++ b/src/configoptions.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CONFIGOPTIONS
+#define CONFIGOPTIONS
+
+class Config;
+
+void addConfigOptions(Config *cfg);
+
+#endif
diff --git a/src/constexp.h b/src/constexp.h
new file mode 100644
index 0000000..27ca039
--- /dev/null
+++ b/src/constexp.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _CONSTEXP_H
+#define _CONSTEXP_H
+
+#include "cppvalue.h"
+#include <qcstring.h>
+
+extern bool parseconstexp(const char *fileName,int line,const QCString &s);
+extern int constexpYYparse();
+extern int constexpYYdebug;
+extern QCString g_strToken;
+extern CPPValue g_resultValue;
+extern QCString g_constExpFileName;
+extern int g_constExpLineNr;
+
+#endif
diff --git a/src/constexp.l b/src/constexp.l
new file mode 100644
index 0000000..bb4f842
--- /dev/null
+++ b/src/constexp.l
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+#include "constexp.h"
+#include "cppvalue.h"
+#include "ce_parse.h" // generated header file
+#include "message.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+QCString g_strToken;
+CPPValue g_resultValue;
+int g_constExpLineNr;
+QCString g_constExpFileName;
+
+static const char *g_inputString;
+static int g_inputPosition;
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?)
+
+%option nounput
+
+%%
+
+"?" { return TOK_QUESTIONMARK; }
+":" { return TOK_COLON; }
+"||" { return TOK_OR; }
+"&&" { return TOK_AND; }
+"|" { return TOK_BITWISEOR; }
+"^" { return TOK_BITWISEXOR; }
+"&" { return TOK_AMPERSAND; }
+"!=" { return TOK_NOTEQUAL; }
+"==" { return TOK_EQUAL; }
+"<" { return TOK_LESSTHAN; }
+">" { return TOK_GREATERTHAN; }
+"<=" { return TOK_LESSTHANOREQUALTO; }
+">=" { return TOK_GREATERTHANOREQUALTO; }
+"<<" { return TOK_SHIFTLEFT; }
+">>" { return TOK_SHIFTRIGHT; }
+"+" { return TOK_PLUS; }
+"-" { return TOK_MINUS; }
+"*" { return TOK_STAR; }
+"/" { return TOK_DIVIDE; }
+"%" { return TOK_MOD; }
+"~" { return TOK_TILDE; }
+"!" { return TOK_NOT; }
+"(" { return TOK_LPAREN; }
+")" { return TOK_RPAREN; }
+"'"(([^\'\n\r\\]+)|(\\(([ntvbrfa\\?'\"])|([0-9]+)|([xX][0-9a-fA-F]+))))"'" {
+ g_strToken=yytext;
+ return TOK_CHARACTER;
+ }
+0[0-7]*{CONSTSUFFIX}? { g_strToken=yytext;
+ return TOK_OCTALINT;
+ }
+[1-9][0-9]*{CONSTSUFFIX}? { g_strToken=yytext;
+ return TOK_DECIMALINT;
+ }
+(0x|0X)[0-9a-fA-F]+{CONSTSUFFIX}? { g_strToken=yytext+2;
+ return TOK_HEXADECIMALINT;
+ }
+(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([eE]([\-\+])?[0-9]+)?([fFlL])? {
+ g_strToken=yytext; return TOK_FLOAT;
+ }
+([0-9]+[eE])([\-\+])?[0-9]+([fFlL])? {
+ g_strToken=yytext; return TOK_FLOAT;
+ }
+.
+\n
+
+%%
+
+bool parseconstexp(const char *fileName,int lineNr,const QCString &s)
+{
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+ //printf("Expression: `%s'\n",s.data());
+ g_constExpFileName = fileName;
+ g_constExpLineNr = lineNr;
+ g_inputString = s;
+ g_inputPosition = 0;
+ constexpYYrestart( constexpYYin );
+ constexpYYparse();
+ //printf("Result: %ld\n",(long)g_resultValue);
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+ return (long)g_resultValue!=0;
+}
+
+extern "C" {
+ int constexpYYwrap() { return 1; }
+}
diff --git a/src/constexp.y b/src/constexp.y
new file mode 100644
index 0000000..1475c1c
--- /dev/null
+++ b/src/constexp.y
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+#include "cppvalue.h"
+#include "constexp.h"
+#include "message.h"
+
+#if defined(_MSC_VER)
+#define MSDOS
+#endif
+
+#define YYSTYPE CPPValue
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int constexpYYerror(const char *s)
+{
+ warn(g_constExpFileName,g_constExpLineNr,
+ "preprocessing issue while doing constant expression evaluation: %s",s);
+ return 0;
+}
+
+int constexpYYlex();
+
+%}
+
+%token TOK_QUESTIONMARK
+%token TOK_COLON
+%token TOK_OR
+%token TOK_AND
+%token TOK_BITWISEOR
+%token TOK_BITWISEXOR
+%token TOK_AMPERSAND
+%token TOK_NOTEQUAL
+%token TOK_EQUAL
+%token TOK_LESSTHAN
+%token TOK_GREATERTHAN
+%token TOK_LESSTHANOREQUALTO
+%token TOK_GREATERTHANOREQUALTO
+%token TOK_SHIFTLEFT
+%token TOK_SHIFTRIGHT
+%token TOK_PLUS
+%token TOK_MINUS
+%token TOK_STAR
+%token TOK_DIVIDE
+%token TOK_MOD
+%token TOK_TILDE
+%token TOK_NOT
+%token TOK_LPAREN
+%token TOK_RPAREN
+%token TOK_OCTALINT
+%token TOK_DECIMALINT
+%token TOK_HEXADECIMALINT
+%token TOK_CHARACTER
+%token TOK_FLOAT
+
+%%
+
+start: constant_expression
+ { g_resultValue = $1; return 0; }
+;
+
+constant_expression: logical_or_expression
+ { $$ = $1; }
+ | logical_or_expression
+ TOK_QUESTIONMARK logical_or_expression
+ TOK_COLON logical_or_expression
+ {
+ bool c = ($1.isInt() ? ((long)$1 != 0) : ((double)$1 != 0.0));
+ $$ = c ? $3 : $5;
+ }
+;
+
+logical_or_expression: logical_and_expression
+ { $$ = $1; }
+ | logical_or_expression TOK_OR logical_and_expression
+ {
+ $$ = CPPValue( (long)((long)$1 || (long)$3) );
+ }
+;
+
+logical_and_expression: inclusive_or_expression
+ { $$ = $1; }
+ | logical_and_expression TOK_AND inclusive_or_expression
+ {
+ $$ = CPPValue( (long)((long)$1 && (long)$3) );
+ }
+;
+
+inclusive_or_expression: exclusive_or_expression
+ { $$ = $1; }
+ | inclusive_or_expression TOK_BITWISEOR
+ exclusive_or_expression
+ {
+ $$ = CPPValue( (long)$1 | (long)$3 );
+ }
+;
+
+exclusive_or_expression: and_expression
+ { $$ = $1; }
+ | exclusive_or_expression TOK_BITWISEXOR and_expression
+ {
+ $$ = CPPValue( (long)$1 ^ (long)$3 );
+ }
+;
+
+and_expression: equality_expression
+ { $$ = $1; }
+ | and_expression TOK_AMPERSAND equality_expression
+ {
+ $$ = CPPValue( (long)$1 & (long)$3 );
+ }
+;
+
+equality_expression: relational_expression
+ { $$ = $1; }
+ | equality_expression TOK_EQUAL relational_expression
+ {
+ $$ = CPPValue( (long)((double)$1 == (double)$3) );
+ }
+ | equality_expression TOK_NOTEQUAL relational_expression
+ {
+ $$ = CPPValue( (long)((double)$1 != (double)$3) );
+ }
+;
+
+relational_expression: shift_expression
+ { $$ = $1; }
+ | relational_expression TOK_LESSTHAN shift_expression
+ {
+ $$ = CPPValue( (long)((double)$1 < (double)$3) );
+ }
+ | relational_expression TOK_GREATERTHAN shift_expression
+ {
+ $$ = CPPValue( (long)((double)$1 > (double)$3) );
+ }
+ | relational_expression TOK_LESSTHANOREQUALTO
+ shift_expression
+ {
+ $$ = CPPValue( (long)((double)$1 <= (double)$3) );
+ }
+ | relational_expression TOK_GREATERTHANOREQUALTO
+ shift_expression
+ {
+ $$ = CPPValue( (long)((double)$1 >= (double)$3) );
+ }
+;
+
+shift_expression: additive_expression
+ { $$ = $1; }
+ | shift_expression TOK_SHIFTLEFT additive_expression
+ {
+ $$ = CPPValue( (long)$1 << (long)$3 );
+ }
+ | shift_expression TOK_SHIFTRIGHT additive_expression
+ {
+ $$ = CPPValue( (long)$1 >> (long)$3 );
+ }
+;
+
+additive_expression: multiplicative_expression
+ { $$ = $1; }
+ | additive_expression TOK_PLUS multiplicative_expression
+ {
+ if (!$1.isInt() || !$3.isInt())
+ {
+ $$ = CPPValue( (double)$1 + (double)$3 );
+ }
+ else
+ {
+ $$ = CPPValue( (long)$1 + (long)$3 );
+ }
+ }
+ | additive_expression TOK_MINUS multiplicative_expression
+ {
+ if (!$1.isInt() || !$3.isInt())
+ {
+ $$ = CPPValue( (double)$1 - (double)$3 );
+ }
+ else
+ {
+ $$ = CPPValue( (long)$1 - (long)$3 );
+ }
+ }
+;
+
+multiplicative_expression: unary_expression
+ { $$ = $1; }
+ | multiplicative_expression TOK_STAR unary_expression
+ {
+ if (!$1.isInt() || !$3.isInt())
+ {
+ $$ = CPPValue( (double)$1 * (double)$3 );
+ }
+ else
+ {
+ $$ = CPPValue( (long)$1 * (long)$3 );
+ }
+ }
+ | multiplicative_expression TOK_DIVIDE unary_expression
+ {
+ if (!$1.isInt() || !$3.isInt())
+ {
+ $$ = CPPValue( (double)$1 / (double)$3 );
+ }
+ else
+ {
+ long value = $3;
+ if (value==0) value=1;
+ $$ = CPPValue( (long)$1 / value );
+ }
+ }
+ | multiplicative_expression TOK_MOD unary_expression
+ {
+ long value = $3;
+ if (value==0) value=1;
+ $$ = CPPValue( (long)$1 % value );
+ }
+;
+
+unary_expression: primary_expression
+ { $$ = $1; }
+ | TOK_PLUS unary_expression
+ { $$ = $1; }
+ | TOK_MINUS unary_expression
+ {
+ if ($2.isInt())
+ $$ = CPPValue(-(long)$2);
+ else
+ $$ = CPPValue(-(double)$2);
+ }
+ | TOK_TILDE unary_expression
+ {
+ $$ = CPPValue(~(long)$2);
+ }
+ | TOK_NOT unary_expression
+ {
+ $$ = CPPValue((long)!(long)$2);
+ }
+;
+
+primary_expression: constant
+ { $$ = $1; }
+ | TOK_LPAREN constant_expression TOK_RPAREN
+ { $$ = $2; }
+;
+
+constant: TOK_OCTALINT
+ { $$ = parseOctal(); }
+ | TOK_DECIMALINT
+ { $$ = parseDecimal(); }
+ | TOK_HEXADECIMALINT
+ { $$ = parseHexadecimal(); }
+ | TOK_CHARACTER
+ { $$ = parseCharacter(); }
+ | TOK_FLOAT
+ { $$ = parseFloat(); }
+;
+
+%%
diff --git a/src/context.cpp b/src/context.cpp
new file mode 100644
index 0000000..b35fffa
--- /dev/null
+++ b/src/context.cpp
@@ -0,0 +1,8226 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qdir.h>
+
+#include "context.h"
+#include "config.h"
+#include "index.h"
+#include "classlist.h"
+#include "doxygen.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "pagedef.h"
+#include "groupdef.h"
+#include "util.h"
+#include "version.h"
+#include "language.h"
+#include "message.h"
+#include "vhdldocgen.h"
+#include "filename.h"
+#include "dirdef.h"
+#include "docparser.h"
+#include "htmlgen.h"
+#include "htmldocvisitor.h"
+#include "dot.h"
+#include "diagram.h"
+#include "example.h"
+#include "membername.h"
+#include "parserintf.h"
+#include "portable.h"
+#include "arguments.h"
+#include "groupdef.h"
+
+// TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other
+// files as well
+
+#define ADD_PROPERTY(name) addProperty(#name,this,&Private::name);
+
+struct ContextGlobals
+{
+ enum OutputFormat
+ {
+ Html,
+ LateX,
+ Rtf,
+ ManPage,
+ DocBook,
+ Xml,
+ TagFile
+ };
+ int dynSectionId;
+ QCString outputDir;
+ OutputFormat outputFormat;
+} g_globals;
+
+/** @brief Scoped smart pointer */
+template<class T> class ScopedPtr
+{
+ private:
+ T *m_ptr;
+ ScopedPtr(const ScopedPtr &);
+ ScopedPtr &operator=(const ScopedPtr &);
+ void operator==(const ScopedPtr &) const;
+ void operator!=(const ScopedPtr &) const;
+
+ public:
+ typedef T Type;
+ explicit ScopedPtr(T *p=0) : m_ptr(p) {}
+ ~ScopedPtr() { delete m_ptr; };
+ T &operator*() const { return *m_ptr; }
+ T *operator->() const { return m_ptr; }
+ T *get() const { return m_ptr; }
+ operator bool() const { return m_ptr!=0; }
+ void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } }
+};
+
+/** @brief Reference counting smart pointer */
+template<class T> class SharedPtr
+{
+ private:
+ T *m_ptr;
+ SharedPtr(const SharedPtr &);
+ SharedPtr &operator=(const SharedPtr &p);
+ void operator==(const SharedPtr &) const;
+ void operator!=(const SharedPtr &) const;
+
+ public:
+ typedef T Type;
+ explicit SharedPtr(T *p=0) : m_ptr(p) { if (m_ptr) m_ptr->addRef(); }
+ ~SharedPtr() { if (m_ptr) m_ptr->release(); };
+ T &operator*() const { return *m_ptr; }
+ T *operator->() const { return m_ptr; }
+ T *get() const { return m_ptr; }
+ operator bool() const { return m_ptr!=0; }
+ void reset(T *p=0)
+ {
+ if (p) p->addRef();
+ if (m_ptr) m_ptr->release();
+ m_ptr = p;
+ }
+};
+
+/** @brief Template List iterator support */
+class GenericConstIterator : public TemplateListIntf::ConstIterator
+{
+ public:
+ GenericConstIterator(const QList<TemplateVariant> &list)
+ : m_it(list) { }
+ virtual ~GenericConstIterator() {}
+ void toFirst()
+ {
+ m_it.toFirst();
+ }
+ void toLast()
+ {
+ m_it.toLast();
+ }
+ void toNext()
+ {
+ if (m_it.current()) ++m_it;
+ }
+ void toPrev()
+ {
+ if (m_it.current()) --m_it;
+ }
+ bool current(TemplateVariant &v) const
+ {
+ if (m_it.current())
+ {
+ v = *m_it.current();
+ return TRUE;
+ }
+ else
+ {
+ v = TemplateVariant();
+ return FALSE;
+ }
+ }
+ private:
+ QListIterator<TemplateVariant> m_it;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief standard template list implementation */
+class GenericNodeListContext : public TemplateListIntf
+{
+ public:
+ GenericNodeListContext() : m_refCount(0)
+ {
+ m_children.setAutoDelete(TRUE);
+ }
+ static GenericNodeListContext *alloc()
+ {
+ return new GenericNodeListContext;
+ }
+
+ // TemplateListIntf methods
+ int count() const
+ {
+ return (int)m_children.count();
+ }
+ TemplateVariant at(int index) const
+ {
+ TemplateVariant result;
+ if (index>=0 && index<count())
+ {
+ result = *m_children.at(index);
+ }
+ return result;
+ }
+ TemplateListIntf::ConstIterator *createIterator() const
+ {
+ return new GenericConstIterator(m_children);
+ }
+
+ void append(const TemplateVariant &ctn)
+ {
+ m_children.append(new TemplateVariant(ctn));
+ }
+ bool isEmpty() const
+ {
+ return m_children.isEmpty();
+ }
+ int addRef()
+ {
+ return ++m_refCount;
+ }
+ int release()
+ {
+ int count = --m_refCount;
+ if (count<=0)
+ {
+ delete this;
+ }
+ return count;
+ }
+ private:
+ mutable QList<TemplateVariant> m_children;
+ int m_refCount;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Helper class to map a property name to a handler member function */
+class PropertyMapper
+{
+ private:
+ struct PropertyFuncIntf
+ {
+ virtual ~PropertyFuncIntf() {}
+ virtual TemplateVariant operator()() const = 0;
+ };
+ template<typename T>
+ struct PropertyFunc : public PropertyFuncIntf
+ {
+ typedef TemplateVariant (T::*Handler)() const;
+ PropertyFunc(const T *o,Handler h) : obj(o), handler(h) {}
+ TemplateVariant operator()() const
+ {
+ return (obj->*handler)();
+ }
+ const T *obj;
+ Handler handler;
+ };
+
+ public:
+ PropertyMapper() { m_map.setAutoDelete(TRUE); }
+
+ /** Add a property to the map
+ * @param[in] name The name of the property to add.
+ * @param[in] obj The object handling access to the property.
+ * @param[in] handle The method to call when the property is accessed.
+ */
+ template<typename T>
+ void addProperty(const char *name,const T* obj,
+ typename PropertyFunc<T>::Handler handle)
+ {
+ if (m_map.find(name))
+ {
+ err("Error: adding property '%s' more than once",name);
+ }
+ else
+ {
+ m_map.insert(name,new PropertyFunc<T>(obj,handle));
+ }
+ }
+
+ /** Gets the value of a property.
+ * @param[in] name The name of the property.
+ * @returns A variant representing the properties value or an
+ * invalid variant if it was not found.
+ */
+ TemplateVariant get(const char *name) const
+ {
+ //printf("PropertyMapper::get(%s)\n",name);
+ TemplateVariant result;
+ PropertyFuncIntf *func = m_map.find(name);
+ if (func)
+ {
+ result = (*func)();
+ }
+ return result;
+ }
+
+ private:
+ QDict<PropertyFuncIntf> m_map;
+};
+
+
+//------------------------------------------------------------------------
+
+//%% struct Config : configuration options
+//%% {
+class ConfigContext::Private
+{
+ public:
+ Private() { m_cachedLists.setAutoDelete(TRUE); }
+ virtual ~Private() { }
+ TemplateVariant fetchList(const QCString &name,const QStrList *list)
+ {
+ TemplateVariant *v = m_cachedLists.find(name);
+ if (v==0)
+ {
+ TemplateList *tlist = TemplateList::alloc();
+ m_cachedLists.insert(name,new TemplateVariant(tlist));
+ QStrListIterator li(*list);
+ char *s;
+ for (li.toFirst();(s=li.current());++li)
+ {
+ tlist->append(s);
+ }
+ return tlist;
+ }
+ else
+ {
+ return *v;
+ }
+ }
+ private:
+ QDict<TemplateVariant> m_cachedLists;
+};
+//%% }
+
+ConfigContext::ConfigContext() : RefCountedContext("ConfigContext")
+{
+ p = new Private;
+}
+
+ConfigContext::~ConfigContext()
+{
+ delete p;
+}
+
+TemplateVariant ConfigContext::get(const char *name) const
+{
+ TemplateVariant result;
+ if (name)
+ {
+ ConfigOption *option = Config::instance()->get(name);
+ if (option)
+ {
+ switch (option->kind())
+ {
+ case ConfigOption::O_Bool:
+ return TemplateVariant(*((ConfigBool*)option)->valueRef());
+ case ConfigOption::O_Int:
+ return TemplateVariant(*((ConfigInt*)option)->valueRef());
+ case ConfigOption::O_Enum:
+ return TemplateVariant(*((ConfigEnum*)option)->valueRef());
+ case ConfigOption::O_String:
+ return TemplateVariant(*((ConfigString*)option)->valueRef());
+ case ConfigOption::O_List:
+ return p->fetchList(name,((ConfigList*)option)->valueRef());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Doxygen: global information
+//%% {
+class DoxygenContext::Private : public PropertyMapper
+{
+ public:
+ TemplateVariant version() const
+ {
+ return versionString;
+ }
+ TemplateVariant date() const
+ {
+ return TemplateVariant(dateToString(TRUE));
+ }
+ Private()
+ {
+ //%% string version
+ addProperty("version",this,&Private::version); //makeProperty(this,&Private::version));
+ //%% string date
+ addProperty("date", this,&Private::date);
+ }
+};
+//%% }
+
+DoxygenContext::DoxygenContext() : RefCountedContext("DoxygenContext")
+{
+ p = new Private;
+}
+
+DoxygenContext::~DoxygenContext()
+{
+ delete p;
+}
+
+TemplateVariant DoxygenContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Translator: translation methods
+//%% {
+class TranslateContext::Private : public PropertyMapper
+{
+ public:
+
+ TemplateVariant handleGeneratedAt(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==2)
+ {
+ return theTranslator->trGeneratedAt(args[0].toString(),args[1].toString());
+ }
+ else
+ {
+ err("tr.generateAt should take two arguments, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleInheritanceDiagramFor(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trClassDiagram(args[0].toString());
+ }
+ else
+ {
+ err("tr.inheritanceDiagramFor should take one argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleCollaborationDiagramFor(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trCollaborationDiagram(args[0].toString());
+ }
+ else
+ {
+ err("tr.collaborationDiagramFor should take one argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleInheritsList(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trInheritsList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.inheritsList should take one integer argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleInheritedByList(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trInheritedByList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.inheritedByList should take one integer argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleWriteList(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trWriteList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.*List should take one integer argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleImplementedBy(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trImplementedInList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.implementedBy should take one integer argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleReimplementedBy(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trReimplementedInList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.reimplementedBy should take one integer argument, got %d!\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleSourceRefs(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trReferences()+" "+theTranslator->trWriteList(args[0].toInt())+".";
+ }
+ else
+ {
+ err("tr.sourceRefs should take one integer argument, got %d\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleSourceRefBys(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trReferencedBy()+" "+theTranslator->trWriteList(args[0].toInt())+".";
+ }
+ else
+ {
+ err("tr.sourceRefBys should take one integer argument, got %d\n",args.count());
+ }
+ return TemplateVariant();
+ }
+ TemplateVariant handleIncludeDependencyGraph(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trInclDepGraph(args[0].toString());
+ }
+ else
+ {
+ err("tr.includeDependencyGraph should take one string argument, got %d\n",args.count());
+ }
+ return TemplateVariant();
+ }
+
+
+
+ TemplateVariant generatedBy() const
+ {
+ return theTranslator->trGeneratedBy();
+ }
+ TemplateVariant generatedAt() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleGeneratedAt>(this);
+ }
+ TemplateVariant inheritanceDiagramFor() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritanceDiagramFor>(this);
+ }
+ TemplateVariant collaborationDiagramFor() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleCollaborationDiagramFor>(this);
+ }
+ TemplateVariant search() const
+ {
+ return theTranslator->trSearch();
+ }
+ TemplateVariant mainPage() const
+ {
+ return theTranslator->trMainPage();
+ }
+ TemplateVariant classes() const
+ {
+ return theTranslator->trClasses();
+ // TODO: VHDL: trVhdlType(VhdlDocGen::ENTITY,FALSE)
+ // TODO: Fortran: trDataTypes()
+ }
+ TemplateVariant classList() const
+ {
+ return theTranslator->trCompoundList();
+ }
+ TemplateVariant classListDescription() const
+ {
+ return theTranslator->trCompoundListDescription();
+ }
+ TemplateVariant classIndex() const
+ {
+ return theTranslator->trCompoundIndex();
+ }
+ TemplateVariant classHierarchy() const
+ {
+ return theTranslator->trClassHierarchy();
+ }
+ TemplateVariant classMembers() const
+ {
+ return theTranslator->trCompoundMembers();
+ }
+ TemplateVariant modules() const
+ {
+ return theTranslator->trModules();
+ }
+ TemplateVariant namespaces() const
+ {
+ if (m_javaOpt || m_vhdlOpt)
+ {
+ return theTranslator->trPackages();
+ }
+ else if (m_fortranOpt)
+ {
+ return theTranslator->trModules();
+ }
+ else
+ {
+ return theTranslator->trNamespaces();
+ }
+ }
+ TemplateVariant files() const
+ {
+ return theTranslator->trFile(TRUE,FALSE);
+ }
+ TemplateVariant pages() const
+ {
+ return theTranslator->trRelatedPages();
+ }
+ TemplateVariant examples() const
+ {
+ return theTranslator->trExamples();
+ }
+ TemplateVariant namespaceList() const
+ {
+ if (m_javaOpt || m_vhdlOpt)
+ {
+ return theTranslator->trPackages();
+ }
+ else if (m_fortranOpt)
+ {
+ return theTranslator->trModulesList();
+ }
+ else
+ {
+ return theTranslator->trNamespaceList();
+ }
+ }
+ TemplateVariant namespaceMembers() const
+ {
+ if (m_javaOpt || m_vhdlOpt)
+ {
+ return theTranslator->trPackageMembers();
+ }
+ else if (m_fortranOpt)
+ {
+ return theTranslator->trModulesMembers();
+ }
+ else
+ {
+ return theTranslator->trNamespaceMembers();
+ }
+ }
+ TemplateVariant fileList() const
+ {
+ return theTranslator->trFileList();
+ }
+ TemplateVariant fileMembers() const
+ {
+ return theTranslator->trFileMembers();
+ }
+ TemplateVariant fileMembersDescription() const
+ {
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ return theTranslator->trFileMembersDescription(extractAll);
+ }
+ TemplateVariant namespaceMembersDescription() const
+ {
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ return theTranslator->trNamespaceMemberDescription(extractAll);
+ }
+ TemplateVariant classMembersDescription() const
+ {
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ if (fortranOpt)
+ {
+ return theTranslator->trCompoundMembersDescriptionFortran(extractAll);
+ }
+ else
+ {
+ return theTranslator->trCompoundMembersDescription(extractAll);
+ }
+ }
+ TemplateVariant relatedPagesDesc() const
+ {
+ return theTranslator->trRelatedPagesDescription();
+ }
+ TemplateVariant more() const
+ {
+ return theTranslator->trMore();
+ }
+ TemplateVariant detailedDesc() const
+ {
+ return theTranslator->trDetailedDescription();
+ }
+ TemplateVariant inheritsList() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritsList>(this);
+ }
+ TemplateVariant inheritedByList() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritedByList>(this);
+ }
+ TemplateVariant definedAtLineInSourceFile() const
+ {
+ return theTranslator->trDefinedAtLineInSourceFile();
+ }
+ TemplateVariant typeConstraints() const
+ {
+ return theTranslator->trTypeConstraints();
+ }
+ TemplateVariant exampleList() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleWriteList>(this);
+ }
+ TemplateVariant listOfAllMembers() const
+ {
+ return theTranslator->trListOfAllMembers();
+ }
+ TemplateVariant memberList() const
+ {
+ return theTranslator->trMemberList();
+ }
+ TemplateVariant theListOfAllMembers() const
+ {
+ return theTranslator->trThisIsTheListOfAllMembers();
+ }
+ TemplateVariant incInheritedMembers() const
+ {
+ return theTranslator->trIncludingInheritedMembers();
+ }
+ TemplateVariant defineValue() const
+ {
+ return theTranslator->trDefineValue();
+ }
+ TemplateVariant initialValue() const
+ {
+ return theTranslator->trInitialValue();
+ }
+ TemplateVariant enumerationValues() const
+ {
+ return theTranslator->trEnumerationValues();
+ }
+ TemplateVariant implements() const
+ {
+ return theTranslator->trImplementedFromList(1);
+ }
+ TemplateVariant reimplements() const
+ {
+ return theTranslator->trReimplementedFromList(1);
+ }
+ TemplateVariant implementedBy() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleImplementedBy>(this);
+ }
+ TemplateVariant reimplementedBy() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleReimplementedBy>(this);
+ }
+ TemplateVariant sourceRefs() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefs>(this);
+ }
+ TemplateVariant sourceRefBys() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefBys>(this);
+ }
+ TemplateVariant callGraph() const
+ {
+ return theTranslator->trCallGraph();
+ }
+ TemplateVariant callerGraph() const
+ {
+ return theTranslator->trCallerGraph();
+ }
+ TemplateVariant inheritedFrom() const
+ {
+ return theTranslator->trInheritedFrom("@0","@1");
+ }
+ TemplateVariant additionalInheritedMembers() const
+ {
+ return theTranslator->trAdditionalInheritedMembers();
+ }
+ TemplateVariant includeDependencyGraph() const
+ {
+ return TemplateVariant::Delegate::fromMethod<Private,&Private::handleIncludeDependencyGraph>(this);
+ }
+ TemplateVariant includedByDependencyGraph() const
+ {
+ return theTranslator->trInclByDepGraph();
+ }
+ TemplateVariant gotoSourceCode() const
+ {
+ return theTranslator->trGotoSourceCode();
+ }
+ TemplateVariant gotoDocumentation() const
+ {
+ return theTranslator->trGotoDocumentation();
+ }
+ TemplateVariant constantgroups() const
+ {
+ return theTranslator->trConstantGroups();
+ }
+ TemplateVariant classDocumentation() const
+ {
+ return theTranslator->trClassDocumentation();
+ }
+ TemplateVariant compoundMembers() const
+ {
+ return theTranslator->trCompoundMembers();
+ }
+ TemplateVariant detailLevel() const
+ {
+ return theTranslator->trDetailLevel();
+ }
+ TemplateVariant fileListDescription() const
+ {
+ bool extractAll = Config_getBool("EXTRACT_ALL");
+ return theTranslator->trFileListDescription(extractAll);
+ }
+ TemplateVariant modulesDescription() const
+ {
+ bool extractAll = Config_getBool("EXTRACT_ALL");
+ return theTranslator->trModulesListDescription(extractAll);
+ }
+ TemplateVariant namespaceListDescription() const
+ {
+ bool extractAll = Config_getBool("EXTRACT_ALL");
+ return theTranslator->trNamespaceListDescription(extractAll);
+ }
+ TemplateVariant directories() const
+ {
+ return theTranslator->trDirectories();
+ }
+ TemplateVariant all() const
+ {
+ return theTranslator->trAll();
+ }
+ TemplateVariant functions() const
+ {
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ return fortranOpt ? theTranslator->trSubprograms() :
+ vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
+ theTranslator->trFunctions();
+ }
+ TemplateVariant variables() const
+ {
+ return theTranslator->trVariables();
+ }
+ TemplateVariant typedefs() const
+ {
+ return theTranslator->trTypedefs();
+ }
+ TemplateVariant enums() const
+ {
+ return theTranslator->trEnumerations();
+ }
+ TemplateVariant properties() const
+ {
+ return theTranslator->trProperties();
+ }
+ TemplateVariant events() const
+ {
+ return theTranslator->trEvents();
+ }
+ TemplateVariant related() const
+ {
+ return theTranslator->trRelatedFunctions();
+ }
+ TemplateVariant macros() const
+ {
+ return theTranslator->trDefines();
+ }
+ Private()
+ {
+ //%% string generatedBy
+ addProperty("generatedby", this,&Private::generatedBy);
+ //%% string generatedAt
+ addProperty("generatedAt", this,&Private::generatedAt);
+ //%% string search
+ addProperty("search", this,&Private::search);
+ //%% string mainPage
+ addProperty("mainPage", this,&Private::mainPage);
+ //%% string classes
+ addProperty("classes", this,&Private::classes);
+ //%% string classList
+ addProperty("classList", this,&Private::classList);
+ //%% string classListDescription
+ addProperty("classListDescription", this,&Private::classListDescription);
+ //%% string classIndex
+ addProperty("classIndex", this,&Private::classIndex);
+ //%% string classHierarchy
+ addProperty("classHierarchy", this,&Private::classHierarchy);
+ //%% string classMembers
+ addProperty("classMembers", this,&Private::classMembers);
+ //%% string classMembersDescription
+ addProperty("classMembersDescription",this,&Private::classMembersDescription);
+ //%% string modules
+ addProperty("modules", this,&Private::modules);
+ //%% string namespaces
+ addProperty("namespaces", this,&Private::namespaces);
+ //%% string files
+ addProperty("files", this,&Private::files);
+ //%% string pages
+ addProperty("pages", this,&Private::pages);
+ //%% string examples
+ addProperty("examples", this,&Private::examples);
+ //%% string namespaceList
+ addProperty("namespaceList", this,&Private::namespaceList);
+ //%% string namespaceMembers
+ addProperty("namespaceMembers", this,&Private::namespaceMembers);
+ //%% srting fileList
+ addProperty("fileList", this,&Private::fileList);
+ //%% string fileMembers
+ addProperty("fileMembers", this,&Private::fileMembers);
+ //%% string fileMembersDescription
+ addProperty("fileMembersDescription", this,&Private::fileMembersDescription);
+ //%% string relatedPagesDescripiton
+ addProperty("relatedPagesDesc", this,&Private::relatedPagesDesc);
+ //%% string more
+ addProperty("more", this,&Private::more);
+ //%% string detailedDescription
+ addProperty("detailedDesc", this,&Private::detailedDesc);
+ //%% string inheritanceDiagramFor
+ addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor);
+ //%% string collaborationDiagramFor
+ addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor);
+ //%% markerstring inheritsList
+ addProperty("inheritsList", this,&Private::inheritsList);
+ //%% markerstring inheritedByList
+ addProperty("inheritedByList", this,&Private::inheritedByList);
+ //%% markerstring definedAtLineInSourceFile
+ addProperty("definedAtLineInSourceFile", this,&Private::definedAtLineInSourceFile);
+ //%% string typeConstraints
+ addProperty("typeConstraints", this,&Private::typeConstraints);
+ //%% string exampleList
+ addProperty("exampleList", this,&Private::exampleList);
+ //%% string listOfAllMembers
+ addProperty("listOfAllMembers", this,&Private::listOfAllMembers);
+ //%% string memberList
+ addProperty("memberList", this,&Private::memberList);
+ //%% string theListOfAllMembers
+ addProperty("theListOfAllMembers",this,&Private::theListOfAllMembers);
+ //%% string incInheritedMembers
+ addProperty("incInheritedMembers",this,&Private::incInheritedMembers);
+ //%% string defineValue
+ addProperty("defineValue", this,&Private::defineValue);
+ //%% string initialValue
+ addProperty("initialValue", this,&Private::initialValue);
+ //%% markerstring implements
+ addProperty("implements", this,&Private::implements);
+ //%% markerstring reimplements
+ addProperty("reimplements", this,&Private::reimplements);
+ //%% markerstring implementedBy
+ addProperty("implementedBy", this,&Private::implementedBy);
+ //%% markerstring reimplementedBy
+ addProperty("reimplementedBy", this,&Private::reimplementedBy);
+ //%% markerstring sourceRefs
+ addProperty("sourceRefs", this,&Private::sourceRefs);
+ //%% markerstring sourceRefBys
+ addProperty("sourceRefBys", this,&Private::sourceRefBys);
+ //%% string callGraph
+ addProperty("callGraph", this,&Private::callGraph);
+ //%% string callerGraph
+ addProperty("callerGraph", this,&Private::callerGraph);
+ //%% markerstring inheritedFrom
+ addProperty("inheritedFrom", this,&Private::inheritedFrom);
+ //%% string addtionalInheritedMembers
+ addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers);
+ //%% string includeDependencyGraph:container_name
+ addProperty("includeDependencyGraph",this,&Private::includeDependencyGraph);
+ //%% string includedByDependencyGraph
+ addProperty("includedByDependencyGraph",this,&Private::includedByDependencyGraph);
+ //%% string gotoSourceCode
+ addProperty("gotoSourceCode", this,&Private::gotoSourceCode);
+ //%% string gotoDocumentation
+ addProperty("gotoDocumentation", this,&Private::gotoDocumentation);
+ //%% string constantgroups
+ addProperty("constantgroups", this,&Private::constantgroups);
+ //%% string classDocumentation
+ addProperty("classDocumentation", this,&Private::classDocumentation);
+ //%% string compoundMembers
+ addProperty("compoundMembers", this,&Private::compoundMembers);
+ //%% string detailLevel
+ addProperty("detailLevel", this,&Private::detailLevel);
+ //%% string fileListDescription
+ addProperty("fileListDescription",this,&Private::fileListDescription);
+ //%% string namespaceListDescription
+ addProperty("namespaceListDescription",this,&Private::namespaceListDescription);
+ //%% string directories
+ addProperty("directories", this,&Private::directories);
+ //%% string moduleDescript
+ addProperty("modulesDescription", this,&Private::modulesDescription);
+ //%% string all
+ addProperty("all", this,&Private::all);
+ //%% string functions
+ addProperty("functions", this,&Private::functions);
+ //%% string variables
+ addProperty("variables", this,&Private::variables);
+ //%% string typedefs
+ addProperty("typedefs", this,&Private::typedefs);
+ //%% string enums
+ addProperty("enums", this,&Private::enums);
+ //%% string enumValues
+ addProperty("enumValues", this,&Private::enumerationValues);
+ //%% string properties
+ addProperty("properties", this,&Private::properties);
+ //%% string events
+ addProperty("events", this,&Private::events);
+ //%% string related
+ addProperty("related", this,&Private::related);
+ //%% string macros
+ addProperty("macros", this,&Private::macros);
+ //%% string namespaceMembersDescription
+ addProperty("namespaceMembersDescription",this,&Private::namespaceMembersDescription);
+
+ m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ m_vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ }
+ private:
+ bool m_javaOpt;
+ bool m_fortranOpt;
+ bool m_vhdlOpt;
+};
+//%% }
+
+TranslateContext::TranslateContext() : RefCountedContext("TranslateContext")
+{
+ p = new Private;
+}
+
+TranslateContext::~TranslateContext()
+{
+ delete p;
+}
+
+TemplateVariant TranslateContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+static TemplateVariant parseDoc(Definition *def,const QCString &file,int line,
+ const QCString &relPath,const QCString &docStr,bool isBrief)
+{
+ TemplateVariant result;
+ DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE,0,isBrief,FALSE);
+ QGString docs;
+ {
+ FTextStream ts(&docs);
+ // TODO: support other generators
+ HtmlCodeGenerator codeGen(ts,relPath);
+ HtmlDocVisitor visitor(ts,codeGen,def);
+ root->accept(&visitor);
+ }
+ bool isEmpty = root->isEmpty();
+ if (isEmpty)
+ result = "";
+ else
+ result = TemplateVariant(docs,TRUE);
+ delete root;
+ return result;
+}
+
+static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const QCString &relPath,
+ const QCString &code,int startLine=-1,int endLine=-1,bool showLineNumbers=FALSE)
+{
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(md->getDefFileExtension());
+ pIntf->resetCodeParserState();
+ QGString s;
+ FTextStream t(&s);
+ HtmlCodeGenerator codeGen(t,relPath);
+ pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(),
+ startLine,endLine,TRUE,md,showLineNumbers,md);
+ return TemplateVariant(s.data(),TRUE);
+}
+
+static TemplateVariant parseCode(FileDef *fd,const QCString &relPath)
+{
+ static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(fd->getDefFileExtension());
+ pIntf->resetCodeParserState();
+ QGString s;
+ FTextStream t(&s);
+ HtmlCodeGenerator codeGen(t,relPath);
+ pIntf->parseCode(codeGen,0,
+ fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources
+ fd->getLanguage(), // lang
+ FALSE, // isExampleBlock
+ 0, // exampleName
+ fd, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inlineFragment
+ 0, // memberDef
+ TRUE, // showLineNumbers
+ 0, // searchCtx
+ TRUE // collectXRefs, TODO: should become FALSE
+ );
+ return TemplateVariant(s.data(),TRUE);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Symbol: shared info for all symbols
+//%% {
+template<typename T>
+class DefinitionContext : public PropertyMapper
+{
+ public:
+ DefinitionContext(Definition *d) : m_def(d)
+ {
+ //%% string name: the name of the symbol
+ addProperty("name",this,&DefinitionContext::name);
+ //%% string bareName: the bare name of the symbol with scope info
+ addProperty("bareName",this,&DefinitionContext::bareName);
+ //%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS)
+ addProperty("relPath",this,&DefinitionContext::relPath);
+ //%% string fileName: the file name of the output file associated with the symbol (without extension)
+ addProperty("fileName",this,&DefinitionContext::fileName);
+ //%% string anchor: anchor within the page
+ addProperty("anchor",this,&DefinitionContext::anchor);
+ //%% string details: the detailed documentation for this symbol
+ addProperty("details",this,&DefinitionContext::details);
+ //%% string brief: the brief description for this symbol
+ addProperty("brief",this,&DefinitionContext::brief);
+ //%% string inbodyDocs: the documentation found in the body
+ addProperty("inbodyDocs",this,&DefinitionContext::inbodyDocs);
+ //%% string sourceFileName: the file name of the source file (without extension)
+ addProperty("sourceFileName",this,&DefinitionContext::sourceFileName);
+ //%% bool isLinkable: can the symbol be linked to?
+ addProperty("isLinkable",this,&DefinitionContext::isLinkable);
+ //%% bool isLinkableInProject: can the symbol be linked within this project?
+ addProperty("isLinkableInProject",this,&DefinitionContext::isLinkableInProject);
+ //%% int dynSectionId: identifier that can be used for collapsable sections
+ addProperty("dynSectionId",this,&DefinitionContext::dynSectionId);
+ //%% string language: the programming language in which the symbol is written
+ addProperty("language",this,&DefinitionContext::language);
+ //%% string sourceDef: A link to the source definition
+ addProperty("sourceDef",this,&DefinitionContext::sourceDef);
+ //%% list[Definition] navigationPath: Breadcrumb navigation path to this item
+ addProperty("navigationPath",this,&DefinitionContext::navigationPath);
+
+ m_cache.sourceDef.reset(TemplateList::alloc());
+ m_cache.lineLink.reset(TemplateStruct::alloc());
+ m_cache.fileLink.reset(TemplateStruct::alloc());
+
+ if (m_def && !m_def->getSourceFileBase().isEmpty())
+ {
+ m_cache.lineLink->set("text",m_def->getStartBodyLine());
+ m_cache.lineLink->set("isLinkable",TRUE);
+ m_cache.lineLink->set("fileName",m_def->getSourceFileBase());
+ m_cache.lineLink->set("anchor",m_def->getSourceAnchor());
+ if (m_def->definitionType()==Definition::TypeFile)
+ {
+ m_cache.fileLink->set("text",m_def->name());
+ }
+ else if (m_def->getBodyDef())
+ {
+ m_cache.fileLink->set("text",m_def->getBodyDef()->name());
+ }
+ else
+ {
+ m_cache.fileLink->set("text",name());
+ }
+ m_cache.fileLink->set("isLinkable",TRUE);
+ m_cache.fileLink->set("fileName",m_def->getSourceFileBase());
+ m_cache.fileLink->set("anchor",QCString());
+ m_cache.sourceDef->append(m_cache.lineLink.get());
+ m_cache.sourceDef->append(m_cache.fileLink.get());
+ }
+ }
+ TemplateVariant fileName() const
+ {
+ return m_def->getOutputFileBase();
+ }
+ TemplateVariant anchor() const
+ {
+ return m_def->anchor();
+ }
+ TemplateVariant sourceFileName() const
+ {
+ return m_def->getSourceFileBase();
+ }
+ TemplateVariant isLinkable() const
+ {
+ return m_def->isLinkable();
+ }
+ TemplateVariant isLinkableInProject() const
+ {
+ return m_def->isLinkableInProject();
+ }
+ TemplateVariant name() const
+ {
+ return m_def->displayName(TRUE);
+ }
+ TemplateVariant bareName() const
+ {
+ return m_def->displayName(FALSE);
+ }
+ QCString relPathAsString() const
+ {
+ static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
+ return createSubdirs ? QCString("../../") : QCString("");
+ }
+ virtual TemplateVariant relPath() const
+ {
+ return relPathAsString();
+ }
+ TemplateVariant details() const
+ {
+ if (!m_cache.details)
+ {
+ m_cache.details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(),
+ relPathAsString(),m_def->documentation(),FALSE)));
+ }
+ return *m_cache.details;
+ }
+ TemplateVariant brief() const
+ {
+ if (!m_cache.brief)
+ {
+ if (m_def->hasBriefDescription())
+ {
+ m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
+ relPathAsString(),m_def->briefDescription(),TRUE)));
+ }
+ else
+ {
+ m_cache.brief.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.brief;
+ }
+ TemplateVariant inbodyDocs() const
+ {
+ if (!m_cache.inbodyDocs)
+ {
+ if (!m_def->inbodyDocumentation().isEmpty())
+ {
+ m_cache.inbodyDocs.reset(new TemplateVariant(parseDoc(m_def,m_def->inbodyFile(),m_def->inbodyLine(),
+ relPathAsString(),m_def->inbodyDocumentation(),FALSE)));
+ }
+ else
+ {
+ m_cache.inbodyDocs.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.inbodyDocs;
+ }
+ TemplateVariant dynSectionId() const
+ {
+ return g_globals.dynSectionId;
+ }
+ TemplateVariant language() const
+ {
+ SrcLangExt lang = m_def->getLanguage();
+ QCString result = "unknown";
+ switch (lang)
+ {
+ case SrcLangExt_Unknown: break;
+ case SrcLangExt_IDL: result="idl"; break;
+ case SrcLangExt_Java: result="java"; break;
+ case SrcLangExt_CSharp: result="csharp"; break;
+ case SrcLangExt_D: result="d"; break;
+ case SrcLangExt_PHP: result="php"; break;
+ case SrcLangExt_ObjC: result="objc"; break;
+ case SrcLangExt_Cpp: result="cpp"; break;
+ case SrcLangExt_JS: result="js"; break;
+ case SrcLangExt_Python: result="python"; break;
+ case SrcLangExt_Fortran: result="fortran"; break;
+ case SrcLangExt_VHDL: result="vhdl"; break;
+ case SrcLangExt_XML: result="xml"; break;
+ case SrcLangExt_Tcl: result="tcl"; break;
+ case SrcLangExt_Markdown: result="markdown"; break;
+ }
+ return result;
+ }
+ TemplateVariant sourceDef() const
+ {
+ if (m_cache.sourceDef->count()==2)
+ {
+ return m_cache.sourceDef.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ void fillPath(Definition *def,TemplateList *list) const
+ {
+ Definition *outerScope = def->getOuterScope();
+ Definition::DefType type = def->definitionType();
+ if (outerScope && outerScope!=Doxygen::globalScope)
+ {
+ fillPath(outerScope,list);
+ }
+ else if (type==Definition::TypeFile && ((const FileDef*)def)->getDirDef())
+ {
+ fillPath(((const FileDef*)def)->getDirDef(),list);
+ }
+ list->append(NavPathElemContext::alloc(def));
+ }
+ TemplateVariant navigationPath() const
+ {
+ if (!m_cache.navPath)
+ {
+ TemplateList *list = TemplateList::alloc();
+ if (m_def->getOuterScope() && m_def->getOuterScope()!=Doxygen::globalScope)
+ {
+ fillPath(m_def->getOuterScope(),list);
+ }
+ else if (m_def->definitionType()==Definition::TypeFile && ((const FileDef *)m_def)->getDirDef())
+ {
+ fillPath(((const FileDef *)m_def)->getDirDef(),list);
+ }
+ m_cache.navPath.reset(list);
+ }
+ return m_cache.navPath.get();
+ }
+
+ private:
+ Definition *m_def;
+ struct Cachable
+ {
+ Cachable() { }
+ ScopedPtr<TemplateVariant> details;
+ ScopedPtr<TemplateVariant> brief;
+ ScopedPtr<TemplateVariant> inbodyDocs;
+ SharedPtr<TemplateList> navPath;
+ SharedPtr<TemplateList> sourceDef;
+ SharedPtr<TemplateStruct> fileLink;
+ SharedPtr<TemplateStruct> lineLink;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+//------------------------------------------------------------------------
+
+//%% struct IncludeInfo: include file information
+//%% {
+class IncludeInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(const IncludeInfo *info,SrcLangExt lang) :
+ m_info(info),
+ m_lang(lang)
+ {
+ if (m_info)
+ {
+ addProperty("file",this,&Private::file);
+ addProperty("name",this,&Private::name);
+ addProperty("isImport",this,&Private::isImport);
+ addProperty("isLocal",this,&Private::isLocal);
+ }
+ }
+ TemplateVariant isLocal() const
+ {
+ bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java;
+ return m_info->local || isIDLorJava;
+ }
+ TemplateVariant isImport() const
+ {
+ return m_info->imported;
+ }
+ TemplateVariant file() const
+ {
+ if (!m_fileContext && m_info && m_info->fileDef)
+ {
+ m_fileContext.reset(FileContext::alloc(m_info->fileDef));
+ }
+ if (m_fileContext)
+ {
+ return m_fileContext.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ TemplateVariant name() const
+ {
+ return m_info->includeName;
+ }
+ private:
+ const IncludeInfo *m_info;
+ mutable SharedPtr<FileContext> m_fileContext;
+ SrcLangExt m_lang;
+};
+
+IncludeInfoContext::IncludeInfoContext(const IncludeInfo *info,SrcLangExt lang) : RefCountedContext("IncludeContext")
+{
+ p = new Private(info,lang);
+}
+
+IncludeInfoContext::~IncludeInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant IncludeInfoContext::get(const char *n) const
+{
+ return p->get(n);
+}
+//%% }
+
+//------------------------------------------------------------------------
+
+//%% list IncludeInfoList[Class] : list of nested classes
+class IncludeInfoListContext::Private : public GenericNodeListContext
+{
+ public:
+ Private(const QList<IncludeInfo> &list,SrcLangExt lang)
+ {
+ QListIterator<IncludeInfo> li(list);
+ IncludeInfo *ii;
+ for (li.toFirst();(ii=li.current());++li)
+ {
+ if (!ii->indirect)
+ {
+ append(IncludeInfoContext::alloc(ii,lang));
+ }
+ }
+ }
+};
+
+IncludeInfoListContext::IncludeInfoListContext(const QList<IncludeInfo> &list,SrcLangExt lang) : RefCountedContext("IncludeListContext")
+{
+ p = new Private(list,lang);
+}
+
+IncludeInfoListContext::~IncludeInfoListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int IncludeInfoListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant IncludeInfoListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *IncludeInfoListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Class(Symbol): class information
+//%% {
+class ClassContext::Private : public DefinitionContext<ClassContext::Private>
+{
+ public:
+ Private(ClassDef *cd) : DefinitionContext<ClassContext::Private>(cd),
+ m_classDef(cd)
+ {
+ addProperty("title", this,&Private::title);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight", this,&Private::subHighlight);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("generatedFromFiles", this,&Private::generatedFromFiles);
+ addProperty("usedFiles", this,&Private::usedFiles);
+ addProperty("hasInheritanceDiagram", this,&Private::hasInheritanceDiagram);
+ addProperty("inheritanceDiagram", this,&Private::inheritanceDiagram);
+ addProperty("hasCollaborationDiagram", this,&Private::hasCollaborationDiagram);
+ addProperty("collaborationDiagram", this,&Private::collaborationDiagram);
+ addProperty("includeInfo", this,&Private::includeInfo);
+ addProperty("inherits", this,&Private::inherits);
+ addProperty("inheritedBy", this,&Private::inheritedBy);
+ addProperty("unoIDLServices", this,&Private::unoIDLServices);
+ addProperty("unoIDLInterfaces", this,&Private::unoIDLInterfaces);
+ addProperty("signals", this,&Private::signals);
+ addProperty("publicTypes", this,&Private::publicTypes);
+ addProperty("publicMethods", this,&Private::publicMethods);
+ addProperty("publicStaticMethods", this,&Private::publicStaticMethods);
+ addProperty("publicAttributes", this,&Private::publicAttributes);
+ addProperty("publicStaticAttributes", this,&Private::publicStaticAttributes);
+ addProperty("publicSlots", this,&Private::publicSlots);
+ addProperty("protectedTypes", this,&Private::protectedTypes);
+ addProperty("protectedMethods", this,&Private::protectedMethods);
+ addProperty("protectedStaticMethods", this,&Private::protectedStaticMethods);
+ addProperty("protectedAttributes", this,&Private::protectedAttributes);
+ addProperty("protectedStaticAttributes", this,&Private::protectedStaticAttributes);
+ addProperty("protectedSlots", this,&Private::protectedSlots);
+ addProperty("privateTypes", this,&Private::privateTypes);
+ addProperty("privateMethods", this,&Private::privateMethods);
+ addProperty("privateStaticMethods", this,&Private::privateStaticMethods);
+ addProperty("privateAttributes", this,&Private::privateAttributes);
+ addProperty("privateStaticAttributes", this,&Private::privateStaticAttributes);
+ addProperty("privateSlots", this,&Private::privateSlots);
+ addProperty("packageTypes", this,&Private::packageTypes);
+ addProperty("packageMethods", this,&Private::packageMethods);
+ addProperty("packageStaticMethods", this,&Private::packageStaticMethods);
+ addProperty("packageAttributes", this,&Private::packageAttributes);
+ addProperty("packageStaticAttributes", this,&Private::packageStaticAttributes);
+ addProperty("properties", this,&Private::properties);
+ addProperty("events", this,&Private::events);
+ addProperty("friends", this,&Private::friends);
+ addProperty("related", this,&Private::related);
+ addProperty("detailedTypedefs", this,&Private::detailedTypedefs);
+ addProperty("detailedEnums", this,&Private::detailedEnums);
+ addProperty("detailedServices", this,&Private::detailedServices);
+ addProperty("detailedInterfaces", this,&Private::detailedInterfaces);
+ addProperty("detailedConstructors", this,&Private::detailedConstructors);
+ addProperty("detailedMethods", this,&Private::detailedMethods);
+ addProperty("detailedRelated", this,&Private::detailedRelated);
+ addProperty("detailedVariables", this,&Private::detailedVariables);
+ addProperty("detailedProperties", this,&Private::detailedProperties);
+ addProperty("detailedEvents", this,&Private::detailedEvents);
+ addProperty("classes", this,&Private::classes);
+ addProperty("compoundType", this,&Private::compoundType);
+ addProperty("templateDecls", this,&Private::templateDecls);
+ addProperty("typeConstraints", this,&Private::typeConstraints);
+ addProperty("examples", this,&Private::examples);
+ addProperty("members", this,&Private::members);
+ addProperty("allMembersList", this,&Private::allMembersList);
+ addProperty("allMembersFileName", this,&Private::allMembersFileName);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ return TemplateVariant(m_classDef->title());
+ }
+ TemplateVariant highlight() const
+ {
+ return TemplateVariant("classes");
+ }
+ TemplateVariant subHighlight() const
+ {
+ return TemplateVariant("");
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_classDef->hasDetailedDescription();
+ }
+ TemplateVariant generatedFromFiles() const
+ {
+ return m_classDef->generatedFromFiles();
+ }
+ TemplateVariant usedFiles() const
+ {
+ if (!m_cache.usedFiles)
+ {
+ m_cache.usedFiles.reset(UsedFilesContext::alloc(m_classDef));
+ }
+ return m_cache.usedFiles.get();
+ }
+ DotClassGraph *getClassGraph() const
+ {
+ if (!m_cache.classGraph)
+ {
+ m_cache.classGraph.reset(new DotClassGraph(m_classDef,DotNode::Inheritance));
+ }
+ return m_cache.classGraph.get();
+ }
+ int numInheritanceNodes() const
+ {
+ if (m_cache.inheritanceNodes==-1)
+ {
+ m_cache.inheritanceNodes=m_classDef->countInheritanceNodes();
+ }
+ return m_cache.inheritanceNodes>0;
+ }
+ TemplateVariant hasInheritanceDiagram() const
+ {
+ bool result=FALSE;
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
+ static bool classGraph = Config_getBool("CLASS_GRAPH");
+ if (haveDot && (classDiagrams || classGraph))
+ {
+ DotClassGraph *cg = getClassGraph();
+ result = !cg->isTrivial() && !cg->isTooBig();
+ }
+ else if (classDiagrams)
+ {
+ result = numInheritanceNodes()>0;
+ }
+ return result;
+ }
+ TemplateVariant inheritanceDiagram() const
+ {
+ QGString result;
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
+ static bool classGraph = Config_getBool("CLASS_GRAPH");
+ if (haveDot && (classDiagrams || classGraph))
+ {
+ DotClassGraph *cg = getClassGraph();
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
+ );
+ }
+ else if (classDiagrams)
+ {
+ ClassDiagram d(m_classDef);
+ FTextStream t(&result);
+ QCString name = convertToHtml(m_classDef->displayName());
+ t << "<div class=\"center\">" << endl;
+ t << "<img src=\"";
+ t << relPathAsString() << m_classDef->getOutputFileBase();
+ t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl;
+ t << "<map id=\"" << name << "_map\" name=\"" << name << "_map\">" << endl;
+ d.writeImage(t,g_globals.outputDir,
+ relPathAsString(),
+ m_classDef->getOutputFileBase());
+ t << "</div>";
+ }
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ DotClassGraph *getCollaborationGraph() const
+ {
+ if (!m_cache.collaborationGraph)
+ {
+ m_cache.collaborationGraph.reset(new DotClassGraph(m_classDef,DotNode::Collaboration));
+ }
+ return m_cache.collaborationGraph.get();
+ }
+ TemplateVariant hasCollaborationDiagram() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ return haveDot && !getCollaborationGraph()->isTrivial();
+ }
+ TemplateVariant collaborationDiagram() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ QGString result;
+ if (haveDot)
+ {
+ DotClassGraph *cg = getCollaborationGraph();
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
+ );
+ }
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+
+ TemplateVariant includeInfo() const
+ {
+ if (!m_cache.includeInfo && m_classDef->includeInfo())
+ {
+ m_cache.includeInfo.reset(IncludeInfoContext::alloc(m_classDef->includeInfo(),m_classDef->getLanguage()));
+ }
+ if (m_cache.includeInfo)
+ {
+ return m_cache.includeInfo.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant inherits() const
+ {
+ if (!m_cache.inheritsList)
+ {
+ m_cache.inheritsList.reset(InheritanceListContext::alloc(m_classDef->baseClasses(),TRUE));
+ }
+ return m_cache.inheritsList.get();
+ }
+ TemplateVariant inheritedBy() const
+ {
+ if (!m_cache.inheritedByList)
+ {
+ m_cache.inheritedByList.reset(InheritanceListContext::alloc(m_classDef->subClasses(),FALSE));
+ }
+ return m_cache.inheritedByList.get();
+ }
+ TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
+ MemberListType type,const char *title,bool detailed=FALSE) const
+ {
+ if (!list)
+ {
+ MemberList *ml = m_classDef->getMemberList(type);
+ if (ml)
+ {
+ list.reset(MemberListInfoContext::alloc(m_classDef,relPathAsString(),ml,title,detailed));
+ }
+ }
+ if (list)
+ {
+ return list.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant unoIDLServices() const
+ {
+ return getMemberList(m_cache.unoIDLServices,MemberListType_services,theTranslator->trServices());
+ }
+ TemplateVariant unoIDLInterfaces() const
+ {
+ return getMemberList(m_cache.unoIDLInterfaces,MemberListType_interfaces,theTranslator->trInterfaces());
+ }
+ TemplateVariant signals() const
+ {
+ return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals());
+ }
+ TemplateVariant publicTypes() const
+ {
+ return getMemberList(m_cache.publicTypes,MemberListType_pubTypes,theTranslator->trPublicTypes());
+ }
+ TemplateVariant publicMethods() const
+ {
+ return getMemberList(m_cache.publicMethods,MemberListType_pubMethods,
+ m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods()
+ : theTranslator->trPublicMembers());
+ }
+ TemplateVariant publicStaticMethods() const
+ {
+ return getMemberList(m_cache.publicStaticMethods,MemberListType_pubStaticMethods,
+ m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods()
+ : theTranslator->trStaticPublicMembers());
+ }
+ TemplateVariant publicAttributes() const
+ {
+ return getMemberList(m_cache.publicAttributes,MemberListType_pubAttribs,theTranslator->trPublicAttribs());
+ }
+ TemplateVariant publicStaticAttributes() const
+ {
+ return getMemberList(m_cache.publicStaticAttributes,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs());
+ }
+ TemplateVariant publicSlots() const
+ {
+ return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots());
+ }
+ TemplateVariant protectedTypes() const
+ {
+ return getMemberList(m_cache.protectedTypes,MemberListType_proTypes,theTranslator->trProtectedTypes());
+ }
+ TemplateVariant protectedMethods() const
+ {
+ return getMemberList(m_cache.protectedMethods,MemberListType_proMethods,theTranslator->trProtectedMembers());
+ }
+ TemplateVariant protectedStaticMethods() const
+ {
+ return getMemberList(m_cache.protectedStaticMethods,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers());
+ }
+ TemplateVariant protectedAttributes() const
+ {
+ return getMemberList(m_cache.protectedAttributes,MemberListType_proAttribs,theTranslator->trProtectedAttribs());
+ }
+ TemplateVariant protectedStaticAttributes() const
+ {
+ return getMemberList(m_cache.protectedStaticAttributes,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs());
+ }
+ TemplateVariant protectedSlots() const
+ {
+ return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots());
+ }
+ TemplateVariant privateTypes() const
+ {
+ return getMemberList(m_cache.privateTypes,MemberListType_priTypes,theTranslator->trPrivateTypes());
+ }
+ TemplateVariant privateSlots() const
+ {
+ return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots());
+ }
+ TemplateVariant privateMethods() const
+ {
+ return getMemberList(m_cache.privateMethods,MemberListType_priMethods,theTranslator->trPrivateMembers());
+ }
+ TemplateVariant privateStaticMethods() const
+ {
+ return getMemberList(m_cache.privateStaticMethods,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers());
+ }
+ TemplateVariant privateAttributes() const
+ {
+ return getMemberList(m_cache.privateAttributes,MemberListType_priAttribs,theTranslator->trPrivateAttribs());
+ }
+ TemplateVariant privateStaticAttributes() const
+ {
+ return getMemberList(m_cache.privateStaticAttributes,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs());
+ }
+ TemplateVariant packageTypes() const
+ {
+ return getMemberList(m_cache.packageTypes,MemberListType_pacTypes,theTranslator->trPackageTypes());
+ }
+ TemplateVariant packageMethods() const
+ {
+ return getMemberList(m_cache.packageMethods,MemberListType_pacMethods,theTranslator->trPackageMembers());
+ }
+ TemplateVariant packageStaticMethods() const
+ {
+ return getMemberList(m_cache.packageStaticMethods,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers());
+ }
+ TemplateVariant packageAttributes() const
+ {
+ return getMemberList(m_cache.packageAttributes,MemberListType_pacAttribs,theTranslator->trPackageAttribs());
+ }
+ TemplateVariant packageStaticAttributes() const
+ {
+ return getMemberList(m_cache.packageStaticAttributes,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs());
+ }
+ TemplateVariant properties() const
+ {
+ return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties());
+ }
+ TemplateVariant events() const
+ {
+ return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents());
+ }
+ TemplateVariant friends() const
+ {
+ return getMemberList(m_cache.friends,MemberListType_friends,theTranslator->trFriends());
+ }
+ TemplateVariant related() const
+ {
+ return getMemberList(m_cache.related,MemberListType_related,theTranslator->trRelatedFunctions());
+ }
+ TemplateVariant detailedTypedefs() const
+ {
+ return getMemberList(m_cache.detailedTypedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation(),TRUE);
+ }
+ TemplateVariant detailedEnums() const
+ {
+ return getMemberList(m_cache.detailedEnums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation(),TRUE);
+ }
+ TemplateVariant detailedServices() const
+ {
+ return getMemberList(m_cache.detailedServices,MemberListType_serviceMembers,theTranslator->trServices(),TRUE);
+ }
+ TemplateVariant detailedInterfaces() const
+ {
+ return getMemberList(m_cache.detailedInterfaces,MemberListType_interfaceMembers,theTranslator->trInterfaces(),TRUE);
+ }
+ TemplateVariant detailedConstructors() const
+ {
+ return getMemberList(m_cache.detailedConstructors,MemberListType_constructors,theTranslator->trConstructorDocumentation(),TRUE);
+ }
+ TemplateVariant detailedMethods() const
+ {
+ return getMemberList(m_cache.detailedMethods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation(),TRUE);
+ }
+ TemplateVariant detailedRelated() const
+ {
+ return getMemberList(m_cache.detailedRelated,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation(),TRUE);
+ }
+ TemplateVariant detailedVariables() const
+ {
+ return getMemberList(m_cache.detailedVariables,MemberListType_variableMembers,theTranslator->trMemberDataDocumentation(),TRUE);
+ }
+ TemplateVariant detailedProperties() const
+ {
+ return getMemberList(m_cache.detailedProperties,MemberListType_propertyMembers,theTranslator->trPropertyDocumentation(),TRUE);
+ }
+ TemplateVariant detailedEvents() const
+ {
+ return getMemberList(m_cache.detailedEvents,MemberListType_eventMembers,theTranslator->trEventDocumentation(),TRUE);
+ }
+ TemplateVariant classes() const
+ {
+ if (!m_cache.classes)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_classDef->getClassSDict())
+ {
+ ClassSDict::Iterator sdi(*m_classDef->getClassSDict());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->visibleInParentsDeclList())
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.classes.reset(classList);
+ }
+ return m_cache.classes.get();
+ }
+ TemplateVariant compoundType() const
+ {
+ return m_classDef->compoundTypeString();
+ }
+ void addTemplateDecls(Definition *d,TemplateList *tl) const
+ {
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ Definition *parent = d->getOuterScope();
+ if (parent)
+ {
+ addTemplateDecls(parent,tl);
+ }
+ ClassDef *cd=(ClassDef *)d;
+ if (cd->templateArguments())
+ {
+ ArgumentListContext *al = ArgumentListContext::alloc(cd->templateArguments(),cd,relPathAsString());
+ // since a TemplateVariant does take ownership of the object, we add it
+ // a separate list just to be able to delete it and avoid a memory leak
+ tl->append(al);
+ }
+ }
+ }
+ void addExamples(TemplateList *list) const
+ {
+ if (m_classDef->hasExamples())
+ {
+ ExampleSDict::Iterator it(*m_classDef->exampleList());
+ Example *ex;
+ for (it.toFirst();(ex=it.current());++it)
+ {
+ TemplateStruct *s = TemplateStruct::alloc();
+ s->set("text",ex->name);
+ s->set("isLinkable",TRUE);
+ s->set("anchor",ex->anchor);
+ s->set("fileName",ex->file);
+ list->append(s);
+ }
+ }
+ }
+ TemplateVariant templateDecls() const
+ {
+ if (!m_cache.templateDecls)
+ {
+ TemplateList *tl = TemplateList::alloc();
+ addTemplateDecls(m_classDef,tl);
+ m_cache.templateDecls.reset(tl);
+ }
+ return m_cache.templateDecls.get();
+ }
+ TemplateVariant typeConstraints() const
+ {
+ if (!m_cache.typeConstraints && m_classDef->typeConstraints())
+ {
+ m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_classDef->typeConstraints(),m_classDef,relPathAsString()));
+ }
+ else
+ {
+ m_cache.typeConstraints.reset(ArgumentListContext::alloc());
+ }
+ return m_cache.typeConstraints.get();
+ }
+ TemplateVariant examples() const
+ {
+ if (!m_cache.examples)
+ {
+ TemplateList *exampleList = TemplateList::alloc();
+ addExamples(exampleList);
+ m_cache.examples.reset(exampleList);
+ }
+ return m_cache.examples.get();
+ }
+ void addMembers(ClassDef *cd,MemberListType lt) const
+ {
+ MemberList *ml = cd->getMemberList(lt);
+ if (ml)
+ {
+ MemberListIterator li(*ml);
+ const MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ if (md->isBriefSectionVisible())
+ {
+ m_cache.allMembers.append(md);
+ }
+ }
+ }
+ }
+ TemplateVariant members() const
+ {
+ if (!m_cache.members)
+ {
+ addMembers(m_classDef,MemberListType_pubTypes);
+ addMembers(m_classDef,MemberListType_services);
+ addMembers(m_classDef,MemberListType_interfaces);
+ addMembers(m_classDef,MemberListType_pubSlots);
+ addMembers(m_classDef,MemberListType_signals);
+ addMembers(m_classDef,MemberListType_pubMethods);
+ addMembers(m_classDef,MemberListType_pubStaticMethods);
+ addMembers(m_classDef,MemberListType_pubAttribs);
+ addMembers(m_classDef,MemberListType_pubStaticAttribs);
+ addMembers(m_classDef,MemberListType_proTypes);
+ addMembers(m_classDef,MemberListType_proSlots);
+ addMembers(m_classDef,MemberListType_proMethods);
+ addMembers(m_classDef,MemberListType_proStaticMethods);
+ addMembers(m_classDef,MemberListType_proAttribs);
+ addMembers(m_classDef,MemberListType_proStaticAttribs);
+ addMembers(m_classDef,MemberListType_pacTypes);
+ addMembers(m_classDef,MemberListType_pacMethods);
+ addMembers(m_classDef,MemberListType_pacStaticMethods);
+ addMembers(m_classDef,MemberListType_pacAttribs);
+ addMembers(m_classDef,MemberListType_pacStaticAttribs);
+ addMembers(m_classDef,MemberListType_properties);
+ addMembers(m_classDef,MemberListType_events);
+ addMembers(m_classDef,MemberListType_priTypes);
+ addMembers(m_classDef,MemberListType_priSlots);
+ addMembers(m_classDef,MemberListType_priMethods);
+ addMembers(m_classDef,MemberListType_priStaticMethods);
+ addMembers(m_classDef,MemberListType_priAttribs);
+ addMembers(m_classDef,MemberListType_priStaticAttribs);
+ addMembers(m_classDef,MemberListType_related);
+ m_cache.members.reset(MemberListContext::alloc(&m_cache.allMembers));
+ }
+ return m_cache.members.get();
+ }
+ TemplateVariant allMembersList() const
+ {
+ if (!m_cache.allMembersList)
+ {
+ if (m_classDef->memberNameInfoSDict())
+ {
+ AllMembersListContext *ml = AllMembersListContext::alloc(m_classDef->memberNameInfoSDict());
+ m_cache.allMembersList.reset(ml);
+ }
+ else
+ {
+ m_cache.allMembersList.reset(AllMembersListContext::alloc());
+ }
+ }
+ return m_cache.allMembersList.get();
+ }
+ TemplateVariant allMembersFileName() const
+ {
+ return m_classDef->getMemberListFileName();
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ if (m_classDef->getMemberGroupSDict())
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_classDef,relPathAsString(),m_classDef->getMemberGroupSDict(),m_classDef->subGrouping()));
+ }
+ else
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc());
+ }
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant additionalInheritedMembers() const
+ {
+ if (!m_cache.additionalInheritedMembers)
+ {
+ InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc();
+ ctx->addMemberList(m_classDef,MemberListType_pubTypes,theTranslator->trPublicTypes());
+ ctx->addMemberList(m_classDef,MemberListType_services,theTranslator->trServices());
+ ctx->addMemberList(m_classDef,MemberListType_interfaces,theTranslator->trInterfaces());
+ ctx->addMemberList(m_classDef,MemberListType_pubSlots,theTranslator->trPublicSlots());
+ ctx->addMemberList(m_classDef,MemberListType_signals,theTranslator->trSignals());
+ ctx->addMemberList(m_classDef,MemberListType_pubMethods,
+ m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods()
+ : theTranslator->trPublicMembers());
+ ctx->addMemberList(m_classDef,MemberListType_pubStaticMethods,
+ m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods()
+ : theTranslator->trStaticPublicMembers());
+ ctx->addMemberList(m_classDef,MemberListType_pubAttribs,theTranslator->trPublicAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_proTypes,theTranslator->trProtectedTypes());
+ ctx->addMemberList(m_classDef,MemberListType_proSlots,theTranslator->trProtectedSlots());
+ ctx->addMemberList(m_classDef,MemberListType_proMethods,theTranslator->trProtectedMembers());
+ ctx->addMemberList(m_classDef,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers());
+ ctx->addMemberList(m_classDef,MemberListType_proAttribs,theTranslator->trProtectedAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_pacTypes,theTranslator->trPackageTypes());
+ ctx->addMemberList(m_classDef,MemberListType_pacMethods,theTranslator->trPackageMembers());
+ ctx->addMemberList(m_classDef,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers());
+ ctx->addMemberList(m_classDef,MemberListType_pacAttribs,theTranslator->trPackageAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_properties,theTranslator->trProperties());
+ ctx->addMemberList(m_classDef,MemberListType_events,theTranslator->trEvents());
+ ctx->addMemberList(m_classDef,MemberListType_priTypes,theTranslator->trPrivateTypes());
+ ctx->addMemberList(m_classDef,MemberListType_priSlots,theTranslator->trPrivateSlots());
+ ctx->addMemberList(m_classDef,MemberListType_priMethods,theTranslator->trPrivateMembers());
+ ctx->addMemberList(m_classDef,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers());
+ ctx->addMemberList(m_classDef,MemberListType_priAttribs,theTranslator->trPrivateAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs());
+ ctx->addMemberList(m_classDef,MemberListType_related,theTranslator->trRelatedFunctions());
+ m_cache.additionalInheritedMembers.reset(ctx);
+ }
+ return m_cache.additionalInheritedMembers.get();
+ }
+
+ private:
+ ClassDef *m_classDef;
+ struct Cachable
+ {
+ Cachable() : inheritanceNodes(-1) { }
+ SharedPtr<IncludeInfoContext> includeInfo;
+ SharedPtr<InheritanceListContext> inheritsList;
+ SharedPtr<InheritanceListContext> inheritedByList;
+ ScopedPtr<DotClassGraph> classGraph;
+ ScopedPtr<DotClassGraph> collaborationGraph;
+ SharedPtr<TemplateList> classes;
+ SharedPtr<MemberListInfoContext> publicTypes;
+ SharedPtr<MemberListInfoContext> publicMethods;
+ SharedPtr<MemberListInfoContext> publicStaticMethods;
+ SharedPtr<MemberListInfoContext> publicAttributes;
+ SharedPtr<MemberListInfoContext> publicStaticAttributes;
+ SharedPtr<MemberListInfoContext> publicSlots;
+ SharedPtr<MemberListInfoContext> protectedTypes;
+ SharedPtr<MemberListInfoContext> protectedMethods;
+ SharedPtr<MemberListInfoContext> protectedStaticMethods;
+ SharedPtr<MemberListInfoContext> protectedAttributes;
+ SharedPtr<MemberListInfoContext> protectedStaticAttributes;
+ SharedPtr<MemberListInfoContext> protectedSlots;
+ SharedPtr<MemberListInfoContext> privateTypes;
+ SharedPtr<MemberListInfoContext> privateMethods;
+ SharedPtr<MemberListInfoContext> privateStaticMethods;
+ SharedPtr<MemberListInfoContext> privateAttributes;
+ SharedPtr<MemberListInfoContext> privateStaticAttributes;
+ SharedPtr<MemberListInfoContext> privateSlots;
+ SharedPtr<MemberListInfoContext> packageTypes;
+ SharedPtr<MemberListInfoContext> packageMethods;
+ SharedPtr<MemberListInfoContext> packageStaticMethods;
+ SharedPtr<MemberListInfoContext> packageAttributes;
+ SharedPtr<MemberListInfoContext> packageStaticAttributes;
+ SharedPtr<MemberListInfoContext> unoIDLServices;
+ SharedPtr<MemberListInfoContext> unoIDLInterfaces;
+ SharedPtr<MemberListInfoContext> signals;
+ SharedPtr<MemberListInfoContext> properties;
+ SharedPtr<MemberListInfoContext> events;
+ SharedPtr<MemberListInfoContext> friends;
+ SharedPtr<MemberListInfoContext> related;
+ SharedPtr<MemberListInfoContext> detailedTypedefs;
+ SharedPtr<MemberListInfoContext> detailedEnums;
+ SharedPtr<MemberListInfoContext> detailedServices;
+ SharedPtr<MemberListInfoContext> detailedInterfaces;
+ SharedPtr<MemberListInfoContext> detailedConstructors;
+ SharedPtr<MemberListInfoContext> detailedMethods;
+ SharedPtr<MemberListInfoContext> detailedRelated;
+ SharedPtr<MemberListInfoContext> detailedVariables;
+ SharedPtr<MemberListInfoContext> detailedProperties;
+ SharedPtr<MemberListInfoContext> detailedEvents;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ SharedPtr<AllMembersListContext> allMembersList;
+ SharedPtr<ArgumentListContext> typeConstraints;
+ SharedPtr<TemplateList> examples;
+ SharedPtr<TemplateList> templateDecls;
+ SharedPtr<InheritedMemberInfoListContext> additionalInheritedMembers;
+ SharedPtr<MemberListContext> members;
+ SharedPtr<UsedFilesContext> usedFiles;
+ SharedPtr<TemplateList> exampleList;
+ int inheritanceNodes;
+ MemberList allMembers;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ClassContext::ClassContext(ClassDef *cd) : RefCountedContext("ClassContext")
+{
+ //printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():"<none>");
+ p = new Private(cd);
+}
+
+ClassContext::~ClassContext()
+{
+ delete p;
+}
+
+TemplateVariant ClassContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Namespace(Symbol): namespace information
+//%% {
+class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Private>
+{
+ public:
+ Private(NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>(nd) , m_namespaceDef(nd)
+ {
+ addProperty("title", this,&Private::title);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight", this,&Private::subHighlight);
+ addProperty("compoundType", this,&Private::compoundType);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("classes", this,&Private::classes);
+ addProperty("namespaces", this,&Private::namespaces);
+ addProperty("constantgroups", this,&Private::constantgroups);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("detailedTypedefs", this,&Private::detailedTypedefs);
+ addProperty("detailedEnums", this,&Private::detailedEnums);
+ addProperty("detailedFunctions", this,&Private::detailedFunctions);
+ addProperty("detailedVariables", this,&Private::detailedVariables);
+ addProperty("inlineClasses", this,&Private::inlineClasses);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ return TemplateVariant(m_namespaceDef->title());
+ }
+ TemplateVariant highlight() const
+ {
+ return TemplateVariant("namespaces");
+ }
+ TemplateVariant subHighlight() const
+ {
+ return TemplateVariant("");
+ }
+ TemplateVariant compoundType() const
+ {
+ return m_namespaceDef->compoundTypeString();
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_namespaceDef->hasDetailedDescription();
+ }
+ TemplateVariant classes() const
+ {
+ if (!m_cache.classes)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_namespaceDef->getClassSDict())
+ {
+ ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->visibleInParentsDeclList())
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.classes.reset(classList);
+ }
+ return m_cache.classes.get();
+ }
+ TemplateVariant namespaces() const
+ {
+ if (!m_cache.namespaces)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_namespaceDef->getNamespaceSDict())
+ {
+ NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && !nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.namespaces.reset(namespaceList);
+ }
+ return m_cache.namespaces.get();
+ }
+ TemplateVariant constantgroups() const
+ {
+ if (!m_cache.constantgroups)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_namespaceDef->getNamespaceSDict())
+ {
+ NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.constantgroups.reset(namespaceList);
+ }
+ return m_cache.constantgroups.get();
+ }
+ TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
+ MemberListType type,const char *title,bool detailed=FALSE) const
+ {
+ if (!list)
+ {
+ MemberList *ml = m_namespaceDef->getMemberList(type);
+ if (ml)
+ {
+ list.reset(MemberListInfoContext::alloc(m_namespaceDef,relPathAsString(),ml,title,detailed));
+ }
+ }
+ if (list)
+ {
+ return list.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
+ }
+ TemplateVariant enums() const
+ {
+ return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
+ }
+ TemplateVariant functions() const
+ {
+ QCString title = theTranslator->trFunctions();
+ SrcLangExt lang = m_namespaceDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
+ else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
+ return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
+ }
+ TemplateVariant variables() const
+ {
+ return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ if (m_namespaceDef->getMemberGroupSDict())
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_namespaceDef,relPathAsString(),m_namespaceDef->getMemberGroupSDict(),m_namespaceDef->subGrouping()));
+ }
+ else
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc());
+ }
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant detailedTypedefs() const
+ {
+ return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
+ }
+ TemplateVariant detailedEnums() const
+ {
+ return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
+ }
+ TemplateVariant detailedFunctions() const
+ {
+ QCString title = theTranslator->trFunctionDocumentation();
+ SrcLangExt lang = m_namespaceDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
+ return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
+ }
+ TemplateVariant detailedVariables() const
+ {
+ return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
+ }
+ TemplateVariant inlineClasses() const
+ {
+ if (!m_cache.inlineClasses)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_namespaceDef->getClassSDict())
+ {
+ ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->name().find('@')==-1 &&
+ cd->isLinkableInProject() &&
+ cd->isEmbeddedInOuterScope() &&
+ cd->partOfGroups()==0)
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.inlineClasses.reset(classList);
+ }
+ return m_cache.inlineClasses.get();
+ }
+ private:
+ NamespaceDef *m_namespaceDef;
+ struct Cachable
+ {
+ SharedPtr<TemplateList> classes;
+ SharedPtr<TemplateList> namespaces;
+ SharedPtr<TemplateList> constantgroups;
+ SharedPtr<MemberListInfoContext> typedefs;
+ SharedPtr<MemberListInfoContext> enums;
+ SharedPtr<MemberListInfoContext> functions;
+ SharedPtr<MemberListInfoContext> variables;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ SharedPtr<MemberListInfoContext> detailedTypedefs;
+ SharedPtr<MemberListInfoContext> detailedEnums;
+ SharedPtr<MemberListInfoContext> detailedFunctions;
+ SharedPtr<MemberListInfoContext> detailedVariables;
+ SharedPtr<TemplateList> inlineClasses;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+NamespaceContext::NamespaceContext(NamespaceDef *nd) : RefCountedContext("NamespaceContext")
+{
+ p = new Private(nd);
+}
+
+NamespaceContext::~NamespaceContext()
+{
+ delete p;
+}
+
+TemplateVariant NamespaceContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct File(Symbol): file information
+//%% {
+class FileContext::Private : public DefinitionContext<FileContext::Private>
+{
+ public:
+ Private(FileDef *fd) : DefinitionContext<FileContext::Private>(fd) , m_fileDef(fd)
+ {
+ if (fd==0) abort();
+ addProperty("title", this,&Private::title);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight", this,&Private::subHighlight);
+ addProperty("versionInfo", this,&Private::versionInfo);
+ addProperty("includeList", this,&Private::includeList);
+ addProperty("hasIncludeGraph", this,&Private::hasIncludeGraph);
+ addProperty("hasIncludedByGraph", this,&Private::hasIncludedByGraph);
+ addProperty("includeGraph", this,&Private::includeGraph);
+ addProperty("includedByGraph", this,&Private::includedByGraph);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("hasSourceFile", this,&Private::hasSourceFile);
+ addProperty("sources", this,&Private::sources);
+ addProperty("version", this,&Private::version);
+ addProperty("classes", this,&Private::classes);
+ addProperty("namespaces", this,&Private::namespaces);
+ addProperty("constantgroups", this,&Private::constantgroups);
+ addProperty("macros", this,&Private::macros);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("detailedMacros", this,&Private::detailedMacros);
+ addProperty("detailedTypedefs", this,&Private::detailedTypedefs);
+ addProperty("detailedEnums", this,&Private::detailedEnums);
+ addProperty("detailedFunctions", this,&Private::detailedFunctions);
+ addProperty("detailedVariables", this,&Private::detailedVariables);
+ addProperty("inlineClasses", this,&Private::inlineClasses);
+ addProperty("compoundType", this,&Private::compoundType);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ return m_fileDef->title();
+ }
+ TemplateVariant highlight() const
+ {
+ return TemplateVariant("files");
+ }
+ TemplateVariant subHighlight() const
+ {
+ return TemplateVariant("");
+ }
+ TemplateVariant versionInfo() const
+ {
+ return m_fileDef->getVersion();
+ }
+ TemplateVariant includeList() const
+ {
+ if (!m_cache.includeInfoList && m_fileDef->includeFileList())
+ {
+ m_cache.includeInfoList.reset(IncludeInfoListContext::alloc(
+ *m_fileDef->includeFileList(),m_fileDef->getLanguage()));
+ }
+ if (m_cache.includeInfoList)
+ {
+ return m_cache.includeInfoList.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ DotInclDepGraph *getIncludeGraph() const
+ {
+ if (!m_cache.includeGraph)
+ {
+ m_cache.includeGraph.reset(new DotInclDepGraph(m_fileDef,FALSE));
+ }
+ return m_cache.includeGraph.get();
+ }
+ TemplateVariant hasIncludeGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ DotInclDepGraph *incGraph = getIncludeGraph();
+ return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial());
+ }
+ TemplateVariant includeGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ QGString result;
+ if (haveDot)
+ {
+ DotInclDepGraph *cg = getIncludeGraph();
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,g_globals.dynSectionId
+ );
+ }
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ DotInclDepGraph *getIncludedByGraph() const
+ {
+ if (!m_cache.includedByGraph)
+ {
+ m_cache.includedByGraph.reset(new DotInclDepGraph(m_fileDef,TRUE));
+ }
+ return m_cache.includedByGraph.get();
+ }
+ TemplateVariant hasIncludedByGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ DotInclDepGraph *incGraph = getIncludedByGraph();
+ return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial());
+ }
+ TemplateVariant includedByGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ QGString result;
+ if (haveDot)
+ {
+ DotInclDepGraph *cg = getIncludedByGraph();
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,g_globals.dynSectionId
+ );
+ }
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_fileDef->hasDetailedDescription();
+ }
+ TemplateVariant hasSourceFile() const
+ {
+ return m_fileDef->generateSourceFile();
+ }
+ TemplateVariant sources() const
+ {
+ if (!m_cache.sources)
+ {
+ if (m_fileDef->generateSourceFile())
+ {
+ m_cache.sources.reset(new TemplateVariant(parseCode(m_fileDef,relPathAsString())));
+ }
+ else
+ {
+ m_cache.sources.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.sources;
+ }
+ TemplateVariant version() const
+ {
+ return m_fileDef->fileVersion();
+ }
+ TemplateVariant classes() const
+ {
+ if (!m_cache.classes)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_fileDef->getClassSDict())
+ {
+ ClassSDict::Iterator sdi(*m_fileDef->getClassSDict());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->visibleInParentsDeclList())
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.classes.reset(classList);
+ }
+ return m_cache.classes.get();
+ }
+ TemplateVariant namespaces() const
+ {
+ if (!m_cache.namespaces)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_fileDef->getNamespaceSDict())
+ {
+ NamespaceSDict::Iterator sdi(*m_fileDef->getNamespaceSDict());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && !nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.namespaces.reset(namespaceList);
+ }
+ return m_cache.namespaces.get();
+ }
+ TemplateVariant constantgroups() const
+ {
+ if (!m_cache.constantgroups)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_fileDef->getNamespaceSDict())
+ {
+ NamespaceSDict::Iterator sdi(*m_fileDef->getNamespaceSDict());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.constantgroups.reset(namespaceList);
+ }
+ return m_cache.constantgroups.get();
+ }
+ TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
+ MemberListType type,const char *title,bool detailed=FALSE) const
+ {
+ if (!list)
+ {
+ MemberList *ml = m_fileDef->getMemberList(type);
+ if (ml)
+ {
+ list.reset(MemberListInfoContext::alloc(m_fileDef,relPathAsString(),ml,title,detailed));
+ }
+ }
+ if (list)
+ {
+ return list.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant macros() const
+ {
+ return getMemberList(m_cache.macros,MemberListType_decDefineMembers,theTranslator->trDefines());
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
+ }
+ TemplateVariant enums() const
+ {
+ return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
+ }
+ TemplateVariant functions() const
+ {
+ QCString title = theTranslator->trFunctions();
+ SrcLangExt lang = m_fileDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
+ else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
+ return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
+ }
+ TemplateVariant variables() const
+ {
+ return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ if (m_fileDef->getMemberGroupSDict())
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_fileDef,relPathAsString(),m_fileDef->getMemberGroupSDict(),m_fileDef->subGrouping()));
+ }
+ else
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc());
+ }
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant detailedMacros() const
+ {
+ return getMemberList(m_cache.detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation());
+ }
+ TemplateVariant detailedTypedefs() const
+ {
+ return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
+ }
+ TemplateVariant detailedEnums() const
+ {
+ return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
+ }
+ TemplateVariant detailedFunctions() const
+ {
+ QCString title = theTranslator->trFunctionDocumentation();
+ SrcLangExt lang = m_fileDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
+ return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
+ }
+ TemplateVariant detailedVariables() const
+ {
+ return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
+ }
+ TemplateVariant inlineClasses() const
+ {
+ if (!m_cache.inlineClasses)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_fileDef->getClassSDict())
+ {
+ ClassSDict::Iterator sdi(*m_fileDef->getClassSDict());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->name().find('@')==-1 &&
+ cd->isLinkableInProject() &&
+ cd->isEmbeddedInOuterScope() &&
+ cd->partOfGroups()==0)
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.inlineClasses.reset(classList);
+ }
+ return m_cache.inlineClasses.get();
+ }
+ TemplateVariant compoundType() const
+ {
+ return theTranslator->trFile(FALSE,TRUE);
+ }
+
+ private:
+ FileDef *m_fileDef;
+ struct Cachable
+ {
+ SharedPtr<IncludeInfoListContext> includeInfoList;
+ ScopedPtr<DotInclDepGraph> includeGraph;
+ ScopedPtr<DotInclDepGraph> includedByGraph;
+ ScopedPtr<TemplateVariant> sources;
+ SharedPtr<TemplateList> classes;
+ SharedPtr<TemplateList> namespaces;
+ SharedPtr<TemplateList> constantgroups;
+ SharedPtr<MemberListInfoContext> macros;
+ SharedPtr<MemberListInfoContext> typedefs;
+ SharedPtr<MemberListInfoContext> enums;
+ SharedPtr<MemberListInfoContext> functions;
+ SharedPtr<MemberListInfoContext> variables;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ SharedPtr<MemberListInfoContext> detailedMacros;
+ SharedPtr<MemberListInfoContext> detailedTypedefs;
+ SharedPtr<MemberListInfoContext> detailedEnums;
+ SharedPtr<MemberListInfoContext> detailedFunctions;
+ SharedPtr<MemberListInfoContext> detailedVariables;
+ SharedPtr<TemplateList> inlineClasses;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+FileContext::FileContext(FileDef *fd) : RefCountedContext("FileContext")
+{
+ p = new Private(fd);
+}
+
+FileContext::~FileContext()
+{
+ delete p;
+}
+
+TemplateVariant FileContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Dir(Symbol): directory information
+//%% {
+class DirContext::Private : public DefinitionContext<DirContext::Private>
+{
+ public:
+ Private(DirDef *dd) : DefinitionContext<DirContext::Private>(dd) , m_dirDef(dd)
+ {
+ addProperty("title", this,&Private::title);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight", this,&Private::subHighlight);
+ addProperty("dirName", this,&Private::dirName);
+ addProperty("dirs", this,&Private::dirs);
+ addProperty("files", this,&Private::files);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("compoundType", this,&Private::compoundType);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ return TemplateVariant(m_dirDef->shortTitle());
+ }
+ TemplateVariant highlight() const
+ {
+ return TemplateVariant("files");
+ }
+ TemplateVariant subHighlight() const
+ {
+ return TemplateVariant("");
+ }
+ TemplateVariant dirName() const
+ {
+ return TemplateVariant(m_dirDef->shortName());
+ }
+ TemplateVariant dirs() const
+ {
+ if (!m_cache.dirs)
+ {
+ m_cache.dirs.reset(TemplateList::alloc());
+ const DirList &subDirs = m_dirDef->subDirs();
+ QListIterator<DirDef> it(subDirs);
+ DirDef *dd;
+ for (it.toFirst();(dd=it.current());++it)
+ {
+ DirContext *dc = new DirContext(dd);
+ m_cache.dirs->append(dc);
+ }
+ }
+ return m_cache.dirs.get();
+ }
+ TemplateVariant files() const
+ {
+ // FileList *list = m_dirDef->getFiles();
+ if (!m_cache.files)
+ {
+ m_cache.files.reset(TemplateList::alloc());
+ FileList *files = m_dirDef->getFiles();
+ if (files)
+ {
+ QListIterator<FileDef> it(*files);
+ FileDef *fd;
+ for (it.toFirst();(fd=it.current());++it)
+ {
+ FileContext *fc = FileContext::alloc(fd);
+ m_cache.files->append(fc);
+ }
+ }
+ }
+ return m_cache.files.get();
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_dirDef->hasDetailedDescription();
+ }
+ TemplateVariant compoundType() const
+ {
+ return theTranslator->trDir(FALSE,TRUE);
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+
+ private:
+ DirDef *m_dirDef;
+ struct Cachable
+ {
+ Cachable() {}
+ SharedPtr<TemplateList> dirs;
+ SharedPtr<TemplateList> files;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+DirContext::DirContext(DirDef *fd) : RefCountedContext("DirContext")
+{
+ p = new Private(fd);
+}
+
+DirContext::~DirContext()
+{
+ delete p;
+}
+
+TemplateVariant DirContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Page(Symbol): page information
+//%% {
+class PageContext::Private : public DefinitionContext<PageContext::Private>
+{
+ public:
+ Private(PageDef *pd,bool isMainPage)
+ : DefinitionContext<PageContext::Private>(pd) , m_pageDef(pd), m_isMainPage(isMainPage)
+ {
+ addProperty("title",this,&Private::title);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subHighlight);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ if (m_isMainPage)
+ {
+ if (mainPageHasTitle())
+ {
+ return m_pageDef->title();
+ }
+ else
+ {
+ return theTranslator->trMainPage();
+ }
+ }
+ else
+ {
+ return m_pageDef->title();
+ }
+ }
+ TemplateVariant relPath() const
+ {
+ if (m_pageDef==Doxygen::mainPage)
+ {
+ return "";
+ }
+ else
+ {
+ return DefinitionContext<PageContext::Private>::relPath();
+ }
+ }
+ TemplateVariant highlight() const
+ {
+ if (m_pageDef==Doxygen::mainPage)
+ {
+ return "main";
+ }
+ else
+ {
+ return "pages";
+ }
+ }
+ TemplateVariant subHighlight() const
+ {
+ return "";
+ }
+ private:
+ PageDef *m_pageDef;
+ bool m_isMainPage;
+};
+//%% }
+
+PageContext::PageContext(PageDef *pd,bool isMainPage) : RefCountedContext("PageContext")
+{
+ p = new Private(pd,isMainPage);
+}
+
+PageContext::~PageContext()
+{
+ delete p;
+}
+
+TemplateVariant PageContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+class TextGeneratorHtml : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorHtml(FTextStream &ts,const QCString &relPath)
+ : m_ts(ts), m_relPath(relPath) {}
+ void writeString(const char *s,bool keepSpaces) const
+ {
+ if (s==0) return;
+ //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
+ if (keepSpaces)
+ {
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch(c)
+ {
+ case '<': m_ts << "<"; break;
+ case '>': m_ts << ">"; break;
+ case '\'': m_ts << "'"; break;
+ case '"': m_ts << """; break;
+ case '&': m_ts << "&"; break;
+ case ' ': m_ts << " "; break;
+ }
+ }
+ }
+ else
+ {
+ m_ts << convertToHtml(s);
+ }
+ }
+
+ void writeBreak(int indent) const
+ {
+ m_ts << "<br />";
+ for (int i=0;i<indent;i++)
+ {
+ m_ts << " ";
+ }
+ }
+
+ void writeLink(const char *ref,const char *f,
+ const char *anchor,const char *name
+ ) const
+ {
+ if (ref)
+ {
+ m_ts << "<a class=\"elRef\" ";
+ m_ts << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
+ }
+ else
+ {
+ m_ts << "<a class=\"el\" ";
+ }
+ m_ts << "href=\"";
+ m_ts << externalRef(m_relPath,ref,TRUE);
+ if (f) m_ts << f << Doxygen::htmlFileExtension;
+ if (anchor) m_ts << "#" << anchor;
+ m_ts << "\">";
+ m_ts << convertToHtml(name);
+ m_ts << "</a>";
+ }
+
+ private:
+ FTextStream &m_ts;
+ QCString m_relPath;
+};
+
+class TextGeneratorFactory
+{
+ public:
+ static TextGeneratorFactory *instance()
+ {
+ static TextGeneratorFactory *instance = 0;
+ if (instance==0) instance = new TextGeneratorFactory;
+ return instance;
+ }
+ TextGeneratorIntf *create(FTextStream &ts,const QCString &relPath)
+ {
+ switch (g_globals.outputFormat)
+ {
+ case ContextGlobals::Html:
+ return new TextGeneratorHtml(ts,relPath);
+ break;
+ default:
+ break;
+ }
+ return 0;
+ }
+ private:
+ TextGeneratorFactory() {}
+ virtual ~TextGeneratorFactory() {}
+};
+
+TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const QCString &text)
+{
+ QGString s;
+ FTextStream ts(&s);
+ TextGeneratorIntf *tg = TextGeneratorFactory::instance()->create(ts,relPath);
+ if (tg)
+ {
+ linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text);
+ return TemplateVariant(s.data(),TRUE);
+ }
+ else
+ {
+ return text;
+ }
+}
+
+//%% struct Member(Symbol): member information
+//%% {
+class MemberContext::Private : public DefinitionContext<MemberContext::Private>
+{
+ public:
+ Private(MemberDef *md) : DefinitionContext<MemberContext::Private>(md) , m_memberDef(md)
+ {
+ addProperty("isSignal", this,&Private::isSignal);
+ addProperty("isSlot", this,&Private::isSlot);
+ addProperty("isVariable", this,&Private::isVariable);
+ addProperty("isEnumeration", this,&Private::isEnumeration);
+ addProperty("isEnumValue", this,&Private::isEnumValue);
+ addProperty("isTypedef", this,&Private::isTypedef);
+ addProperty("isFunction", this,&Private::isFunction);
+ addProperty("isFunctionPtr", this,&Private::isFunctionPtr);
+ addProperty("isDefine", this,&Private::isDefine);
+ addProperty("isFriend", this,&Private::isFriend);
+ addProperty("isProperty", this,&Private::isProperty);
+ addProperty("isEvent", this,&Private::isEvent);
+ addProperty("isRelated", this,&Private::isRelated);
+ addProperty("isForeign", this,&Private::isForeign);
+ addProperty("isStatic", this,&Private::isStatic);
+ addProperty("isInline", this,&Private::isInline);
+ addProperty("isExplicit", this,&Private::isExplicit);
+ addProperty("isMutable", this,&Private::isMutable);
+ addProperty("isGettable", this,&Private::isGettable);
+ addProperty("isPrivateGettable", this,&Private::isPrivateGettable);
+ addProperty("isProtectedGettable", this,&Private::isProtectedGettable);
+ addProperty("isSettable", this,&Private::isSettable);
+ addProperty("isPrivateSettable", this,&Private::isPrivateSettable);
+ addProperty("isProtectedSettable", this,&Private::isProtectedSettable);
+ addProperty("isReadable", this,&Private::isReadable);
+ addProperty("isWritable", this,&Private::isWritable);
+ addProperty("isAddable", this,&Private::isAddable);
+ addProperty("isRemovable", this,&Private::isRemovable);
+ addProperty("isRaisable", this,&Private::isRaisable);
+ addProperty("isFinal", this,&Private::isFinal);
+ addProperty("isAbstract", this,&Private::isAbstract);
+ addProperty("isOverride", this,&Private::isOverride);
+ addProperty("isInitonly", this,&Private::isInitonly);
+ addProperty("isOptional", this,&Private::isOptional);
+ addProperty("isRequired", this,&Private::isRequired);
+ addProperty("isNonAtomic", this,&Private::isNonAtomic);
+ addProperty("isCopy", this,&Private::isCopy);
+ addProperty("isAssign", this,&Private::isAssign);
+ addProperty("isRetain", this,&Private::isRetain);
+ addProperty("isWeak", this,&Private::isWeak);
+ addProperty("isStrong", this,&Private::isStrong);
+ addProperty("isUnretained", this,&Private::isUnretained);
+ addProperty("isNew", this,&Private::isNew);
+ addProperty("isSealed", this,&Private::isSealed);
+ addProperty("isImplementation", this,&Private::isImplementation);
+ addProperty("isExternal", this,&Private::isExternal);
+ addProperty("isAlias", this,&Private::isAlias);
+ addProperty("isDefault", this,&Private::isDefault);
+ addProperty("isDelete", this,&Private::isDelete);
+ addProperty("isNoExcept", this,&Private::isNoExcept);
+ addProperty("isAttribute", this,&Private::isAttribute);
+ addProperty("isUNOProperty", this,&Private::isUNOProperty);
+ addProperty("isReadonly", this,&Private::isReadonly);
+ addProperty("isBound", this,&Private::isBound);
+ addProperty("isConstrained", this,&Private::isConstrained);
+ addProperty("isTransient", this,&Private::isTransient);
+ addProperty("isMaybeVoid", this,&Private::isMaybeVoid);
+ addProperty("isMaybeDefault", this,&Private::isMaybeDefault);
+ addProperty("isMaybeAmbiguous", this,&Private::isMaybeAmbiguous);
+ addProperty("isPublished", this,&Private::isPublished);
+ addProperty("isTemplateSpecialization",this,&Private::isTemplateSpecialization);
+ addProperty("isObjCMethod", this,&Private::isObjCMethod);
+ addProperty("isObjCProperty", this,&Private::isObjCProperty);
+ addProperty("isAnonymous", this,&Private::isAnonymous);
+ addProperty("declType", this,&Private::declType);
+ addProperty("declArgs", this,&Private::declArgs);
+ addProperty("anonymousType", this,&Private::anonymousType);
+ addProperty("anonymousMember", this,&Private::anonymousMember);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("exception", this,&Private::exception);
+ addProperty("bitfields", this,&Private::bitfields);
+ addProperty("initializer", this,&Private::initializer);
+ addProperty("initializerAsCode", this,&Private::initializerAsCode);
+ addProperty("hasOneLineInitializer", this,&Private::hasOneLineInitializer);
+ addProperty("hasMultiLineInitializer", this,&Private::hasMultiLineInitializer);
+ addProperty("templateArgs", this,&Private::templateArgs);
+ addProperty("templateAlias", this,&Private::templateAlias);
+ addProperty("propertyAttrs", this,&Private::propertyAttrs);
+ addProperty("eventAttrs", this,&Private::eventAttrs);
+ addProperty("class", this,&Private::getClass);
+ addProperty("file", this,&Private::getFile);
+ addProperty("namespace", this,&Private::getNamespace);
+ addProperty("definition", this,&Private::definition);
+ addProperty("parameters", this,&Private::parameters);
+ addProperty("hasParameterList", this,&Private::hasParameterList);
+ addProperty("hasConstQualifier", this,&Private::hasConstQualifier);
+ addProperty("hasVolatileQualifier",this,&Private::hasVolatileQualifier);
+ addProperty("trailingReturnType", this,&Private::trailingReturnType);
+ addProperty("extraTypeChars", this,&Private::extraTypeChars);
+ addProperty("templateDecls", this,&Private::templateDecls);
+ addProperty("labels", this,&Private::labels);
+ addProperty("enumBaseType", this,&Private::enumBaseType);
+ addProperty("enumValues", this,&Private::enumValues);
+ addProperty("paramDocs", this,&Private::paramDocs);
+ addProperty("reimplements", this,&Private::reimplements);
+ addProperty("implements", this,&Private::implements);
+ addProperty("reimplementedBy", this,&Private::reimplementedBy);
+ addProperty("implementedBy", this,&Private::implementedBy);
+ addProperty("examples", this,&Private::examples);
+ addProperty("typeConstraints", this,&Private::typeConstraints);
+ addProperty("functionQualifier", this,&Private::functionQualifier);
+ addProperty("sourceRefs", this,&Private::sourceRefs);
+ addProperty("sourceRefBys", this,&Private::sourceRefBys);
+ addProperty("hasSources", this,&Private::hasSources);
+ addProperty("sourceCode", this,&Private::sourceCode);
+ addProperty("hasCallGraph", this,&Private::hasCallGraph);
+ addProperty("callGraph", this,&Private::callGraph);
+ addProperty("hasCallerGraph", this,&Private::hasCallerGraph);
+ addProperty("callerGraph", this,&Private::callerGraph);
+ addProperty("fieldType", this,&Private::fieldType);
+
+ m_cache.propertyAttrs.reset(TemplateList::alloc());
+ if (md && md->isProperty())
+ {
+ if (md->isGettable()) m_cache.propertyAttrs->append("get");
+ if (md->isPrivateGettable()) m_cache.propertyAttrs->append("private get");
+ if (md->isProtectedGettable()) m_cache.propertyAttrs->append("protected get");
+ if (md->isSettable()) m_cache.propertyAttrs->append("set");
+ if (md->isPrivateSettable()) m_cache.propertyAttrs->append("private set");
+ if (md->isProtectedSettable()) m_cache.propertyAttrs->append("protected set");
+ }
+ m_cache.eventAttrs.reset(TemplateList::alloc());
+ if (md && md->isEvent())
+ {
+ if (md->isAddable()) m_cache.eventAttrs->append("add");
+ if (md->isRemovable()) m_cache.eventAttrs->append("remove");
+ if (md->isRaisable()) m_cache.eventAttrs->append("raise");
+ }
+ }
+ virtual ~Private() {}
+ TemplateVariant fieldType() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->fieldType());
+ }
+ TemplateVariant declType() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->getDeclType());
+ }
+ TemplateVariant declArgs() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->argsString());
+ }
+ TemplateVariant exception() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->excpString());
+ }
+ TemplateVariant bitfields() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->bitfieldString());
+ }
+ TemplateVariant isStatic() const
+ {
+ return m_memberDef->isStatic();
+ }
+ TemplateVariant isObjCMethod() const
+ {
+ return m_memberDef->isObjCMethod();
+ }
+ TemplateVariant isObjCProperty() const
+ {
+ return m_memberDef->isObjCProperty();
+ }
+ TemplateVariant isImplementation() const
+ {
+ return m_memberDef->isImplementation();
+ }
+ TemplateVariant isSignal() const
+ {
+ return m_memberDef->isSignal();
+ }
+ TemplateVariant isSlot() const
+ {
+ return m_memberDef->isSlot();
+ }
+ TemplateVariant isTypedef() const
+ {
+ return m_memberDef->isTypedef();
+ }
+ TemplateVariant isFunction() const
+ {
+ return m_memberDef->isFunction();
+ }
+ TemplateVariant isFunctionPtr() const
+ {
+ return m_memberDef->isFunctionPtr();
+ }
+ TemplateVariant isFriend() const
+ {
+ return m_memberDef->isFriend();
+ }
+ TemplateVariant isForeign() const
+ {
+ return m_memberDef->isForeign();
+ }
+ TemplateVariant isEvent() const
+ {
+ return m_memberDef->isEvent();
+ }
+ TemplateVariant isInline() const
+ {
+ return m_memberDef->isInline();
+ }
+ TemplateVariant isExplicit() const
+ {
+ return m_memberDef->isExplicit();
+ }
+ TemplateVariant isMutable() const
+ {
+ return m_memberDef->isMutable();
+ }
+ TemplateVariant isGettable() const
+ {
+ return m_memberDef->isGettable();
+ }
+ TemplateVariant isPrivateGettable() const
+ {
+ return m_memberDef->isPrivateGettable();
+ }
+ TemplateVariant isProtectedGettable() const
+ {
+ return m_memberDef->isProtectedGettable();
+ }
+ TemplateVariant isSettable() const
+ {
+ return m_memberDef->isSettable();
+ }
+ TemplateVariant isPrivateSettable() const
+ {
+ return m_memberDef->isPrivateSettable();
+ }
+ TemplateVariant isProtectedSettable() const
+ {
+ return m_memberDef->isProtectedSettable();
+ }
+ TemplateVariant isReadable() const
+ {
+ return m_memberDef->isReadable();
+ }
+ TemplateVariant isWritable() const
+ {
+ return m_memberDef->isWritable();
+ }
+ TemplateVariant isAddable() const
+ {
+ return m_memberDef->isAddable();
+ }
+ TemplateVariant isRemovable() const
+ {
+ return m_memberDef->isRemovable();
+ }
+ TemplateVariant isRaisable() const
+ {
+ return m_memberDef->isRaisable();
+ }
+ TemplateVariant isFinal() const
+ {
+ return m_memberDef->isFinal();
+ }
+ TemplateVariant isAbstract() const
+ {
+ return m_memberDef->isAbstract();
+ }
+ TemplateVariant isOverride() const
+ {
+ return m_memberDef->isOverride();
+ }
+ TemplateVariant isInitonly() const
+ {
+ return m_memberDef->isInitonly();
+ }
+ TemplateVariant isOptional() const
+ {
+ return m_memberDef->isOptional();
+ }
+ TemplateVariant isRequired() const
+ {
+ return m_memberDef->isRequired();
+ }
+ TemplateVariant isNonAtomic() const
+ {
+ return m_memberDef->isNonAtomic();
+ }
+ TemplateVariant isCopy() const
+ {
+ return m_memberDef->isCopy();
+ }
+ TemplateVariant isAssign() const
+ {
+ return m_memberDef->isAssign();
+ }
+ TemplateVariant isRetain() const
+ {
+ return m_memberDef->isRetain();
+ }
+ TemplateVariant isWeak() const
+ {
+ return m_memberDef->isWeak();
+ }
+ TemplateVariant isStrong() const
+ {
+ return m_memberDef->isStrong();
+ }
+ TemplateVariant isUnretained() const
+ {
+ return m_memberDef->isUnretained();
+ }
+ TemplateVariant isNew() const
+ {
+ return m_memberDef->isNew();
+ }
+ TemplateVariant isSealed() const
+ {
+ return m_memberDef->isSealed();
+ }
+ TemplateVariant isExternal() const
+ {
+ return m_memberDef->isExternal();
+ }
+ TemplateVariant isAlias() const
+ {
+ return m_memberDef->isAlias();
+ }
+ TemplateVariant isDefault() const
+ {
+ return m_memberDef->isDefault();
+ }
+ TemplateVariant isDelete() const
+ {
+ return m_memberDef->isDelete();
+ }
+ TemplateVariant isNoExcept() const
+ {
+ return m_memberDef->isNoExcept();
+ }
+ TemplateVariant isAttribute() const
+ {
+ return m_memberDef->isAttribute();
+ }
+ TemplateVariant isUNOProperty() const
+ {
+ return m_memberDef->isUNOProperty();
+ }
+ TemplateVariant isReadonly() const
+ {
+ return m_memberDef->isReadonly();
+ }
+ TemplateVariant isBound() const
+ {
+ return m_memberDef->isBound();
+ }
+ TemplateVariant isConstrained() const
+ {
+ return m_memberDef->isConstrained();
+ }
+ TemplateVariant isTransient() const
+ {
+ return m_memberDef->isTransient();
+ }
+ TemplateVariant isMaybeVoid() const
+ {
+ return m_memberDef->isMaybeVoid();
+ }
+ TemplateVariant isMaybeDefault() const
+ {
+ return m_memberDef->isMaybeDefault();
+ }
+ TemplateVariant isMaybeAmbiguous() const
+ {
+ return m_memberDef->isMaybeAmbiguous();
+ }
+ TemplateVariant isPublished() const
+ {
+ return m_memberDef->isPublished();
+ }
+ TemplateVariant isTemplateSpecialization() const
+ {
+ return m_memberDef->isTemplateSpecialization();
+ }
+ TemplateVariant isProperty() const
+ {
+ return m_memberDef->isProperty();
+ }
+ TemplateVariant isEnumValue() const
+ {
+ return m_memberDef->isEnumValue();
+ }
+ TemplateVariant isVariable() const
+ {
+ return m_memberDef->isVariable();
+ }
+ TemplateVariant isEnumeration() const
+ {
+ return m_memberDef->isEnumerate();
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_memberDef->isDetailedSectionLinkable();
+ }
+ TemplateVariant initializer() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer());
+ }
+ TemplateVariant initializerAsCode() const
+ {
+ if (!m_cache.initializerParsed)
+ {
+ QCString scopeName;
+ if (m_memberDef->getClassDef())
+ {
+ scopeName = m_memberDef->getClassDef()->name();
+ }
+ else if (m_memberDef->getNamespaceDef())
+ {
+ scopeName = m_memberDef->getNamespaceDef()->name();
+ }
+ m_cache.initializer = parseCode(m_memberDef,scopeName,relPathAsString(),
+ m_memberDef->initializer());
+ m_cache.initializerParsed = TRUE;
+ }
+ return m_cache.initializer;
+ }
+ TemplateVariant isDefine() const
+ {
+ return m_memberDef->isDefine();
+ }
+ TemplateVariant isAnonymous() const
+ {
+ QCString name = m_memberDef->name();
+ return !name.isEmpty() && name.at(0)=='@';
+ }
+ TemplateVariant anonymousType() const
+ {
+ if (!m_cache.anonymousType)
+ {
+ ClassDef *cd = m_memberDef->getClassDefOfAnonymousType();
+ if (cd)
+ {
+ m_cache.anonymousType.reset(ClassContext::alloc(cd));
+ }
+ }
+ if (m_cache.anonymousType)
+ {
+ return m_cache.anonymousType.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ TemplateVariant anonymousMember() const
+ {
+ if (!m_cache.anonymousMember)
+ {
+ MemberDef *md = m_memberDef->fromAnonymousMember();
+ if (md)
+ {
+ m_cache.anonymousMember.reset(MemberContext::alloc(md));
+ }
+ }
+ if (m_cache.anonymousMember)
+ {
+ return m_cache.anonymousMember.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ TemplateVariant isRelated() const
+ {
+ return m_memberDef->isRelated();
+ }
+ TemplateVariant enumBaseType() const
+ {
+ return m_memberDef->enumBaseType();
+ }
+ TemplateVariant hasOneLineInitializer() const
+ {
+ return m_memberDef->hasOneLineInitializer();
+ }
+ TemplateVariant hasMultiLineInitializer() const
+ {
+ return m_memberDef->hasMultiLineInitializer();
+ }
+ TemplateVariant enumValues() const
+ {
+ if (!m_cache.enumValues)
+ {
+ MemberList *ml = m_memberDef->enumFieldList();
+ if (ml)
+ {
+ m_cache.enumValues.reset(MemberListContext::alloc(ml));
+ }
+ else
+ {
+ m_cache.enumValues.reset(MemberListContext::alloc());
+ }
+ }
+ return m_cache.enumValues.get();
+ }
+ TemplateVariant templateArgs() const
+ {
+ if (!m_cache.templateArgs && m_memberDef->templateArguments())
+ {
+ m_cache.templateArgs.reset(ArgumentListContext::alloc(m_memberDef->templateArguments(),m_memberDef,relPathAsString()));
+ }
+ if (m_cache.templateArgs)
+ {
+ return m_cache.templateArgs.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant templateAlias() const
+ {
+ if (m_memberDef->isAlias())
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),
+ QCString(" = ")+m_memberDef->typeString());
+ }
+ return "";
+ }
+ TemplateVariant propertyAttrs() const
+ {
+ return m_cache.propertyAttrs.get();
+ }
+ TemplateVariant eventAttrs() const
+ {
+ return m_cache.eventAttrs.get();
+ }
+ TemplateVariant getClass() const
+ {
+ if (!m_cache.classDef && m_memberDef->getClassDef())
+ {
+ m_cache.classDef.reset(ClassContext::alloc(m_memberDef->getClassDef()));
+ }
+ if (m_cache.classDef)
+ {
+ return m_cache.classDef.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getFile() const
+ {
+ if (!m_cache.fileDef && m_memberDef->getFileDef())
+ {
+ m_cache.fileDef.reset(FileContext::alloc(m_memberDef->getFileDef()));
+ }
+ if (m_cache.fileDef)
+ {
+ return m_cache.fileDef.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getNamespace() const
+ {
+ if (!m_cache.namespaceDef && m_memberDef->getNamespaceDef())
+ {
+ m_cache.namespaceDef.reset(NamespaceContext::alloc(m_memberDef->getNamespaceDef()));
+ }
+ if (m_cache.namespaceDef)
+ {
+ return m_cache.namespaceDef.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant definition() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),
+ m_memberDef->displayDefinition());
+ }
+ ArgumentList *getDefArgList() const
+ {
+ return (m_memberDef->isDocsForDefinition()) ?
+ m_memberDef->argumentList() : m_memberDef->declArgumentList();
+ }
+ TemplateVariant parameters() const
+ {
+ if (!m_cache.arguments)
+ {
+ ArgumentList *defArgList = getDefArgList();
+ if (defArgList && !m_memberDef->isProperty())
+ {
+ m_cache.arguments.reset(ArgumentListContext::alloc(defArgList,m_memberDef,relPathAsString()));
+ }
+ else
+ {
+ m_cache.arguments.reset(ArgumentListContext::alloc());
+ }
+ }
+ return m_cache.arguments.get();
+ }
+ TemplateVariant hasParameterList() const
+ {
+ return getDefArgList()!=0;
+ }
+ TemplateVariant hasConstQualifier() const
+ {
+ ArgumentList *al = getDefArgList();
+ return al ? al->constSpecifier : FALSE;
+ }
+ TemplateVariant hasVolatileQualifier() const
+ {
+ ArgumentList *al = getDefArgList();
+ return al ? al->volatileSpecifier : FALSE;
+ }
+ TemplateVariant trailingReturnType() const
+ {
+ ArgumentList *al = getDefArgList();
+ if (al && !al->trailingReturnType.isEmpty())
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),
+ al->trailingReturnType);
+ }
+ else
+ {
+ return "";
+ }
+ }
+ TemplateVariant extraTypeChars() const
+ {
+ return m_memberDef->extraTypeChars();
+ }
+ void addTemplateDecls(TemplateList *tl) const
+ {
+ ClassDef *cd=m_memberDef->getClassDef();
+ if (m_memberDef->definitionTemplateParameterLists())
+ {
+ QListIterator<ArgumentList> ali(*m_memberDef->definitionTemplateParameterLists());
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString());
+ tl->append(al);
+ }
+ }
+ }
+ else
+ {
+ if (cd && !m_memberDef->isRelated() && !m_memberDef->isTemplateSpecialization())
+ {
+ QList<ArgumentList> tempParamLists;
+ cd->getTemplateParameterLists(tempParamLists);
+ //printf("#tempParamLists=%d\n",tempParamLists.count());
+ QListIterator<ArgumentList> ali(tempParamLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString());
+ tl->append(al);
+ }
+ }
+ }
+ if (m_memberDef->templateArguments()) // function template prefix
+ {
+ ArgumentListContext *al = ArgumentListContext::alloc(
+ m_memberDef->templateArguments(),m_memberDef,relPathAsString());
+ tl->append(al);
+ }
+ }
+ }
+ TemplateVariant templateDecls() const
+ {
+ if (!m_cache.templateDecls)
+ {
+ TemplateList *tl = TemplateList::alloc();
+ addTemplateDecls(tl);
+ m_cache.templateDecls.reset(tl);
+ }
+ return m_cache.templateDecls.get();
+ }
+ TemplateVariant labels() const
+ {
+ if (!m_cache.labels)
+ {
+ QStrList sl;
+ m_memberDef->getLabels(sl,m_memberDef->getOuterScope());
+ TemplateList *tl = TemplateList::alloc();
+ if (sl.count()>0)
+ {
+ QStrListIterator it(sl);
+ for (;it.current();++it)
+ {
+ tl->append(*it);
+ }
+ }
+ m_cache.labels.reset(tl);
+ }
+ return m_cache.labels.get();
+ }
+ TemplateVariant paramDocs() const
+ {
+ if (!m_cache.paramDocs)
+ {
+ if (m_memberDef->argumentList() && m_memberDef->argumentList()->hasDocumentation())
+ {
+ QCString paramDocs;
+ ArgumentListIterator ali(*m_memberDef->argumentList());
+ Argument *a;
+ // convert the parameter documentation into a list of @param commands
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (a->hasDocumentation())
+ {
+ QCString direction = extractDirection(a->docs);
+ paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
+ }
+ }
+ m_cache.paramDocs.reset(new TemplateVariant(parseDoc(m_memberDef,
+ m_memberDef->docFile(),m_memberDef->docLine(),
+ relPathAsString(),paramDocs,FALSE)));
+ }
+ else
+ {
+ m_cache.paramDocs.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.paramDocs;
+ }
+ TemplateVariant implements() const
+ {
+ if (!m_cache.implements)
+ {
+ MemberDef *md = m_memberDef->reimplements();
+ m_cache.implements.reset(TemplateList::alloc());
+ if (md)
+ {
+ ClassDef *cd = md->getClassDef();
+ if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
+ {
+ MemberContext *mc = MemberContext::alloc(md);
+ m_cache.implements->append(mc);
+ }
+ }
+ }
+ return m_cache.implements.get();
+ }
+ TemplateVariant reimplements() const
+ {
+ if (!m_cache.reimplements)
+ {
+ MemberDef *md = m_memberDef->reimplements();
+ m_cache.reimplements.reset(TemplateList::alloc());
+ if (md)
+ {
+ ClassDef *cd = md->getClassDef();
+ if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
+ {
+ MemberContext *mc = MemberContext::alloc(md);
+ m_cache.reimplements->append(mc);
+ }
+ }
+ }
+ return m_cache.reimplements.get();
+ }
+ TemplateVariant implementedBy() const
+ {
+ if (!m_cache.implementedBy)
+ {
+ MemberList *ml = m_memberDef->reimplementedBy();
+ m_cache.implementedBy.reset(TemplateList::alloc());
+ if (ml)
+ {
+ MemberListIterator mli(*ml);
+ MemberDef *md=0;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ ClassDef *cd = md->getClassDef();
+ if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
+ {
+ MemberContext *mc = new MemberContext(md);
+ m_cache.implementedBy->append(mc);
+ }
+ }
+ }
+ }
+ return m_cache.implementedBy.get();
+ }
+ TemplateVariant reimplementedBy() const
+ {
+ if (!m_cache.reimplementedBy)
+ {
+ m_cache.reimplementedBy.reset(TemplateList::alloc());
+ MemberList *ml = m_memberDef->reimplementedBy();
+ if (ml)
+ {
+ MemberListIterator mli(*ml);
+ MemberDef *md=0;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ ClassDef *cd = md->getClassDef();
+ if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
+ {
+ MemberContext *mc = new MemberContext(md);
+ m_cache.reimplementedBy->append(mc);
+ }
+ }
+ }
+ }
+ return m_cache.reimplementedBy.get();
+ }
+ void addExamples(TemplateList *list) const
+ {
+ if (m_memberDef->hasExamples())
+ {
+ ExampleSDict::Iterator it(*m_memberDef->getExamples());
+ Example *ex;
+ for (it.toFirst();(ex=it.current());++it)
+ {
+ TemplateStruct *s = TemplateStruct::alloc();
+ s->set("text",ex->name);
+ s->set("isLinkable",TRUE);
+ s->set("anchor",ex->anchor);
+ s->set("fileName",ex->file);
+ list->append(s);
+ }
+ }
+ }
+ TemplateVariant examples() const
+ {
+ if (!m_cache.examples)
+ {
+ TemplateList *exampleList = TemplateList::alloc();
+ addExamples(exampleList);
+ m_cache.examples.reset(exampleList);
+ }
+ return m_cache.examples.get();
+ }
+ TemplateVariant typeConstraints() const
+ {
+ if (!m_cache.typeConstraints && m_memberDef->typeConstraints())
+ {
+ m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_memberDef->typeConstraints(),m_memberDef,relPathAsString()));
+ }
+ else
+ {
+ m_cache.typeConstraints.reset(ArgumentListContext::alloc());
+ }
+ return m_cache.typeConstraints.get();
+ }
+ TemplateVariant functionQualifier() const
+ {
+ if (!m_memberDef->isObjCMethod() &&
+ (m_memberDef->isFunction() || m_memberDef->isSlot() ||
+ m_memberDef->isPrototype() || m_memberDef->isSignal()
+ )
+ )
+ {
+ return "()";
+ }
+ else
+ {
+ return "";
+ }
+ }
+ TemplateVariant sourceRefs() const
+ {
+ if (!m_cache.sourceRefs)
+ {
+ m_cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers(),TRUE));
+ }
+ return m_cache.sourceRefs.get();
+ }
+ TemplateVariant sourceRefBys() const
+ {
+ if (!m_cache.sourceRefBys)
+ {
+ m_cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers(),TRUE));
+ }
+ return m_cache.sourceRefBys.get();
+ }
+ TemplateVariant hasSources() const
+ {
+ return TemplateVariant(m_memberDef->hasSources());
+ }
+ TemplateVariant sourceCode() const
+ {
+ if (!m_cache.sourceCodeParsed)
+ {
+ QCString codeFragment;
+ FileDef *fd = m_memberDef->getBodyDef();
+ int startLine = m_memberDef->getStartBodyLine();
+ int endLine = m_memberDef->getEndBodyLine();
+ if (fd && readCodeFragment(fd->absFilePath(),
+ startLine,endLine,codeFragment)
+ )
+ {
+ QCString scopeName;
+ if (m_memberDef->getClassDef())
+ {
+ scopeName = m_memberDef->getClassDef()->name();
+ }
+ else if (m_memberDef->getNamespaceDef())
+ {
+ scopeName = m_memberDef->getNamespaceDef()->name();
+ }
+ m_cache.sourceCode = parseCode(m_memberDef,scopeName,relPathAsString(),codeFragment,startLine,endLine,TRUE);
+ m_cache.sourceCodeParsed = TRUE;
+ }
+ }
+ return m_cache.sourceCode;
+ }
+ DotCallGraph *getCallGraph() const
+ {
+ if (!m_cache.callGraph)
+ {
+ m_cache.callGraph.reset(new DotCallGraph(m_memberDef,FALSE));
+ }
+ return m_cache.callGraph.get();
+ }
+ TemplateVariant hasCallGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool callGraph = Config_getBool("CALL_GRAPH");
+ if ((callGraph || m_memberDef->hasCallGraph()) && haveDot &&
+ (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
+ {
+ DotCallGraph *cg = getCallGraph();
+ return !cg->isTooBig() && !cg->isTrivial();
+ }
+ return TemplateVariant(FALSE);
+ }
+ TemplateVariant callGraph() const
+ {
+ if (hasCallGraph().toBool())
+ {
+ DotCallGraph *cg = getCallGraph();
+ QGString result;
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,g_globals.dynSectionId
+ );
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ else
+ {
+ return TemplateVariant("");
+ }
+ }
+ DotCallGraph *getCallerGraph() const
+ {
+ if (!m_cache.callerGraph)
+ {
+ m_cache.callerGraph.reset(new DotCallGraph(m_memberDef,TRUE));
+ }
+ return m_cache.callerGraph.get();
+ }
+ TemplateVariant hasCallerGraph() const
+ {
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool callerGraph = Config_getBool("CALLER_GRAPH");
+ if ((callerGraph || m_memberDef->hasCallerGraph()) && haveDot &&
+ (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
+ {
+ DotCallGraph *cg = getCallerGraph();
+ return !cg->isTooBig() && !cg->isTrivial();
+ }
+ return TemplateVariant(FALSE);
+ }
+ TemplateVariant callerGraph() const
+ {
+ if (hasCallerGraph().toBool())
+ {
+ DotCallGraph *cg = getCallerGraph();
+ QGString result;
+ FTextStream t(&result);
+ cg->writeGraph(t,GOF_BITMAP,EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),TRUE,g_globals.dynSectionId
+ );
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ else
+ {
+ return TemplateVariant("");
+ }
+ }
+ private:
+ MemberDef *m_memberDef;
+ struct Cachable
+ {
+ Cachable() : initializerParsed(FALSE), sourceCodeParsed(FALSE)
+ {
+ }
+ SharedPtr<ArgumentListContext> templateArgs;
+ SharedPtr<ArgumentListContext> arguments;
+ SharedPtr<MemberListContext> enumValues;
+ SharedPtr<FileContext> fileDef;
+ SharedPtr<NamespaceContext> namespaceDef;
+ SharedPtr<ClassContext> classDef;
+ SharedPtr<ClassContext> anonymousType;
+ SharedPtr<TemplateList> templateDecls;
+ ScopedPtr<TemplateVariant> paramDocs;
+ SharedPtr<TemplateList> implements;
+ SharedPtr<TemplateList> reimplements;
+ SharedPtr<TemplateList> implementedBy;
+ SharedPtr<MemberListContext> sourceRefs;
+ SharedPtr<MemberListContext> sourceRefBys;
+ ScopedPtr<DotCallGraph> callGraph;
+ ScopedPtr<DotCallGraph> callerGraph;
+ SharedPtr<MemberContext> anonymousMember;
+ SharedPtr<TemplateList> reimplementedBy;
+ SharedPtr<TemplateList> labels;
+ TemplateVariant initializer;
+ bool initializerParsed;
+ TemplateVariant sourceCode;
+ bool sourceCodeParsed;
+ SharedPtr<TemplateList> examples;
+ SharedPtr<TemplateList> exampleList;
+ SharedPtr<ArgumentListContext> typeConstraints;
+ SharedPtr<TemplateList> propertyAttrs;
+ SharedPtr<TemplateList> eventAttrs;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+MemberContext::MemberContext(MemberDef *md) : RefCountedContext("MemberContext")
+{
+ p = new Private(md);
+}
+
+MemberContext::~MemberContext()
+{
+ delete p;
+}
+
+TemplateVariant MemberContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+
+//------------------------------------------------------------------------
+
+//%% struct Module(Symbol): group information
+//%% {
+class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
+{
+ public:
+ Private(GroupDef *gd) : DefinitionContext<ModuleContext::Private>(gd) , m_groupDef(gd)
+ {
+ addProperty("title", this,&Private::title);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight", this,&Private::subHighlight);
+ addProperty("hasGroupGraph", this,&Private::hasGroupGraph);
+ addProperty("groupGraph", this,&Private::groupGraph);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("modules", this,&Private::modules);
+ addProperty("dirs", this,&Private::dirs);
+ addProperty("files", this,&Private::files);
+ addProperty("namespaces", this,&Private::namespaces);
+ addProperty("classes", this,&Private::classes);
+ addProperty("constantgroups", this,&Private::constantgroups);
+ addProperty("examples", this,&Private::examples);
+ addProperty("macros", this,&Private::macros);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("enumvalues", this,&Private::enumValues);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("signals", this,&Private::signals);
+ addProperty("publicSlots", this,&Private::publicSlots);
+ addProperty("protectedSlots", this,&Private::protectedSlots);
+ addProperty("privateSlots", this,&Private::privateSlots);
+ addProperty("events", this,&Private::events);
+ addProperty("properties", this,&Private::properties);
+ addProperty("friends", this,&Private::friends);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("detailedMacros", this,&Private::detailedMacros);
+ addProperty("detailedTypedefs", this,&Private::detailedTypedefs);
+ addProperty("detailedEnums", this,&Private::detailedEnums);
+ addProperty("detailedEnumValues", this,&Private::detailedEnumValues);
+ addProperty("detailedFunctions", this,&Private::detailedFunctions);
+ addProperty("detailedVariables", this,&Private::detailedVariables);
+ addProperty("detailedSignals", this,&Private::detailedSignals);
+ addProperty("detailedPublicSlots", this,&Private::detailedPublicSlots);
+ addProperty("detailedProtectedSlots", this,&Private::detailedProtectedSlots);
+ addProperty("detailedPrivateSlots", this,&Private::detailedPrivateSlots);
+ addProperty("detailedEvents", this,&Private::detailedEvents);
+ addProperty("detailedProperties", this,&Private::detailedProperties);
+ addProperty("detailedFriends", this,&Private::detailedFriends);
+ addProperty("inlineClasses", this,&Private::inlineClasses);
+ addProperty("compoundType", this,&Private::compoundType);
+ }
+ virtual ~Private() {}
+ TemplateVariant title() const
+ {
+ return TemplateVariant(m_groupDef->groupTitle());
+ }
+ TemplateVariant highlight() const
+ {
+ return TemplateVariant("modules");
+ }
+ TemplateVariant subHighlight() const
+ {
+ return TemplateVariant("");
+ }
+ DotGroupCollaboration *getGroupGraph() const
+ {
+ if (!m_cache.groupGraph)
+ {
+ m_cache.groupGraph.reset(new DotGroupCollaboration(m_groupDef));
+ }
+ return m_cache.groupGraph.get();
+ }
+ TemplateVariant hasGroupGraph() const
+ {
+ bool result=FALSE;
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool groupGraphs = Config_getBool("GROUP_GRAPHS");
+ if (haveDot && groupGraphs)
+ {
+ DotGroupCollaboration *graph = getGroupGraph();
+ result = !graph->isTrivial();
+ }
+ return result;
+ }
+ TemplateVariant groupGraph() const
+ {
+ QGString result;
+ static bool haveDot = Config_getBool("HAVE_DOT");
+ static bool groupGraphs = Config_getBool("GROUP_GRAPHS");
+ if (haveDot && groupGraphs)
+ {
+ DotGroupCollaboration *graph = getGroupGraph();
+ FTextStream t(&result);
+ graph->writeGraph(t,GOF_BITMAP,
+ EOF_Html,
+ g_globals.outputDir,
+ g_globals.outputDir+portable_pathSeparator()+m_groupDef->getOutputFileBase()+Doxygen::htmlFileExtension,
+ relPathAsString(),
+ TRUE,
+ g_globals.dynSectionId);
+ }
+ g_globals.dynSectionId++;
+ return TemplateVariant(result.data(),TRUE);
+ }
+ TemplateVariant hasDetails() const
+ {
+ return m_groupDef->hasDetailedDescription();
+ }
+ TemplateVariant modules() const
+ {
+ if (!m_cache.modules)
+ {
+ TemplateList *moduleList = TemplateList::alloc();
+ if (m_groupDef->getSubGroups())
+ {
+ GroupListIterator gli(*m_groupDef->getSubGroups());
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (gd->isVisible())
+ {
+ moduleList->append(ModuleContext::alloc(gd));
+ }
+ }
+ }
+ m_cache.modules.reset(moduleList);
+ }
+ return m_cache.modules.get();
+ }
+ TemplateVariant examples() const
+ {
+ if (!m_cache.examples)
+ {
+ TemplateList *exampleList = TemplateList::alloc();
+ if (m_groupDef->getExamples())
+ {
+ PageSDict::Iterator eli(*m_groupDef->getExamples());
+ PageDef *ex;
+ for (eli.toFirst();(ex=eli.current());++eli)
+ {
+ exampleList->append(PageContext::alloc(ex));
+ }
+ }
+ m_cache.examples.reset(exampleList);
+ }
+ return m_cache.examples.get();
+ }
+ TemplateVariant pages() const
+ {
+ if (!m_cache.pages)
+ {
+ TemplateList *pageList = TemplateList::alloc();
+ if (m_groupDef->getExamples())
+ {
+ PageSDict::Iterator eli(*m_groupDef->getPages());
+ PageDef *ex;
+ for (eli.toFirst();(ex=eli.current());++eli)
+ {
+ pageList->append(PageContext::alloc(ex));
+ }
+ }
+ m_cache.pages.reset(pageList);
+ }
+ return m_cache.pages.get();
+ }
+ TemplateVariant dirs() const
+ {
+ if (!m_cache.dirs)
+ {
+ TemplateList *dirList = TemplateList::alloc();
+ if (m_groupDef->getDirs())
+ {
+ QListIterator<DirDef> it(*m_groupDef->getDirs());
+ DirDef *dd;
+ for (it.toFirst();(dd=it.current());++it)
+ {
+ dirList->append(DirContext::alloc(dd));
+ }
+ }
+ m_cache.dirs.reset(dirList);
+ }
+ return m_cache.dirs.get();
+ }
+ TemplateVariant files() const
+ {
+ if (!m_cache.files)
+ {
+ TemplateList *fileList = TemplateList::alloc();
+ if (m_groupDef->getFiles())
+ {
+ QListIterator<FileDef> it(*m_groupDef->getFiles());
+ FileDef *fd;
+ for (it.toFirst();(fd=it.current());++it)
+ {
+ fileList->append(FileContext::alloc(fd));
+ }
+ }
+ m_cache.files.reset(fileList);
+ }
+ return m_cache.files.get();
+ }
+ TemplateVariant classes() const
+ {
+ if (!m_cache.classes)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_groupDef->getClasses())
+ {
+ ClassSDict::Iterator sdi(*m_groupDef->getClasses());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->visibleInParentsDeclList())
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.classes.reset(classList);
+ }
+ return m_cache.classes.get();
+ }
+ TemplateVariant namespaces() const
+ {
+ if (!m_cache.namespaces)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_groupDef->getNamespaces())
+ {
+ NamespaceSDict::Iterator sdi(*m_groupDef->getNamespaces());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && !nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.namespaces.reset(namespaceList);
+ }
+ return m_cache.namespaces.get();
+ }
+ TemplateVariant constantgroups() const
+ {
+ if (!m_cache.constantgroups)
+ {
+ TemplateList *namespaceList = TemplateList::alloc();
+ if (m_groupDef->getNamespaces())
+ {
+ NamespaceSDict::Iterator sdi(*m_groupDef->getNamespaces());
+ NamespaceDef *nd;
+ for (sdi.toFirst();(nd=sdi.current());++sdi)
+ {
+ if (nd->isLinkable() && nd->isConstantGroup())
+ {
+ namespaceList->append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+ m_cache.constantgroups.reset(namespaceList);
+ }
+ return m_cache.constantgroups.get();
+ }
+
+ TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
+ MemberListType type,const char *title,bool detailed=FALSE) const
+ {
+ if (!list)
+ {
+ MemberList *ml = m_groupDef->getMemberList(type);
+ if (ml)
+ {
+ list.reset(MemberListInfoContext::alloc(m_groupDef,relPathAsString(),ml,title,detailed));
+ }
+ }
+ if (list)
+ {
+ return list.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant macros() const
+ {
+ return getMemberList(m_cache.macros,MemberListType_decDefineMembers,theTranslator->trDefines());
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
+ }
+ TemplateVariant enums() const
+ {
+ return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
+ }
+ TemplateVariant enumValues() const
+ {
+ return getMemberList(m_cache.enums,MemberListType_decEnumValMembers,theTranslator->trEnumerationValues());
+ }
+ TemplateVariant functions() const
+ {
+ QCString title = theTranslator->trFunctions();
+ SrcLangExt lang = m_groupDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
+ else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
+ return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
+ }
+ TemplateVariant variables() const
+ {
+ return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
+ }
+ TemplateVariant signals() const
+ {
+ return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals());
+ }
+ TemplateVariant publicSlots() const
+ {
+ return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots());
+ }
+ TemplateVariant protectedSlots() const
+ {
+ return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots());
+ }
+ TemplateVariant privateSlots() const
+ {
+ return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots());
+ }
+ TemplateVariant events() const
+ {
+ return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents());
+ }
+ TemplateVariant properties() const
+ {
+ return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties());
+ }
+ TemplateVariant friends() const
+ {
+ return getMemberList(m_cache.friends,MemberListType_friends,theTranslator->trFriends());
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ if (m_groupDef->getMemberGroupSDict())
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_groupDef,relPathAsString(),m_groupDef->getMemberGroupSDict(),m_groupDef->subGrouping()));
+ }
+ else
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc());
+ }
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant detailedMacros() const
+ {
+ return getMemberList(m_cache.detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation());
+ }
+ TemplateVariant detailedTypedefs() const
+ {
+ return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
+ }
+ TemplateVariant detailedEnums() const
+ {
+ return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
+ }
+ TemplateVariant detailedEnumValues() const
+ {
+ return getMemberList(m_cache.detailedEnumValues,MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation());
+ }
+ TemplateVariant detailedFunctions() const
+ {
+ QCString title = theTranslator->trFunctionDocumentation();
+ SrcLangExt lang = m_groupDef->getLanguage();
+ if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
+ return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
+ }
+ TemplateVariant detailedVariables() const
+ {
+ return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
+ }
+ TemplateVariant detailedSignals() const
+ {
+ return getMemberList(m_cache.detailedSignals,MemberListType_docSignalMembers,theTranslator->trSignals());
+ }
+ TemplateVariant detailedPublicSlots() const
+ {
+ return getMemberList(m_cache.detailedPublicSlots,MemberListType_docPubSlotMembers,theTranslator->trPublicSlots());
+ }
+ TemplateVariant detailedProtectedSlots() const
+ {
+ return getMemberList(m_cache.detailedProtectedSlots,MemberListType_docProSlotMembers,theTranslator->trProtectedSlots());
+ }
+ TemplateVariant detailedPrivateSlots() const
+ {
+ return getMemberList(m_cache.detailedPrivateSlots,MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots());
+ }
+ TemplateVariant detailedEvents() const
+ {
+ return getMemberList(m_cache.detailedEvents,MemberListType_docEventMembers,theTranslator->trEventDocumentation(),TRUE);
+ }
+ TemplateVariant detailedProperties() const
+ {
+ return getMemberList(m_cache.detailedProperties,MemberListType_docPropMembers,theTranslator->trPropertyDocumentation(),TRUE);
+ }
+ TemplateVariant detailedFriends() const
+ {
+ return getMemberList(m_cache.detailedFriends,MemberListType_docFriendMembers,theTranslator->trFriends(),TRUE);
+ }
+ TemplateVariant inlineClasses() const
+ {
+ if (!m_cache.inlineClasses)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (m_groupDef->getClasses())
+ {
+ ClassSDict::Iterator sdi(*m_groupDef->getClasses());
+ ClassDef *cd;
+ for (sdi.toFirst();(cd=sdi.current());++sdi)
+ {
+ if (cd->name().find('@')==-1 &&
+ cd->isLinkableInProject() &&
+ cd->isEmbeddedInOuterScope() &&
+ cd->partOfGroups()==0)
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.inlineClasses.reset(classList);
+ }
+ return m_cache.inlineClasses.get();
+ }
+ TemplateVariant compoundType() const
+ {
+ return "module"; //theTranslator->trGroup(FALSE,TRUE);
+ }
+ private:
+ GroupDef *m_groupDef;
+ struct Cachable
+ {
+ SharedPtr<TemplateList> modules;
+ SharedPtr<TemplateList> dirs;
+ SharedPtr<TemplateList> files;
+ SharedPtr<TemplateList> classes;
+ SharedPtr<TemplateList> namespaces;
+ SharedPtr<TemplateList> constantgroups;
+ SharedPtr<TemplateList> examples;
+ SharedPtr<TemplateList> pages;
+ SharedPtr<MemberListInfoContext> macros;
+ SharedPtr<MemberListInfoContext> typedefs;
+ SharedPtr<MemberListInfoContext> enums;
+ SharedPtr<MemberListInfoContext> enumValues;
+ SharedPtr<MemberListInfoContext> functions;
+ SharedPtr<MemberListInfoContext> variables;
+ SharedPtr<MemberListInfoContext> signals;
+ SharedPtr<MemberListInfoContext> publicSlots;
+ SharedPtr<MemberListInfoContext> protectedSlots;
+ SharedPtr<MemberListInfoContext> privateSlots;
+ SharedPtr<MemberListInfoContext> events;
+ SharedPtr<MemberListInfoContext> properties;
+ SharedPtr<MemberListInfoContext> friends;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ SharedPtr<MemberListInfoContext> detailedMacros;
+ SharedPtr<MemberListInfoContext> detailedTypedefs;
+ SharedPtr<MemberListInfoContext> detailedEnums;
+ SharedPtr<MemberListInfoContext> detailedEnumValues;
+ SharedPtr<MemberListInfoContext> detailedFunctions;
+ SharedPtr<MemberListInfoContext> detailedVariables;
+ SharedPtr<MemberListInfoContext> detailedSignals;
+ SharedPtr<MemberListInfoContext> detailedPublicSlots;
+ SharedPtr<MemberListInfoContext> detailedProtectedSlots;
+ SharedPtr<MemberListInfoContext> detailedPrivateSlots;
+ SharedPtr<MemberListInfoContext> detailedEvents;
+ SharedPtr<MemberListInfoContext> detailedProperties;
+ SharedPtr<MemberListInfoContext> detailedFriends;
+ SharedPtr<TemplateList> inlineClasses;
+ ScopedPtr<DotGroupCollaboration> groupGraph;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ModuleContext::ModuleContext(GroupDef *gd) : RefCountedContext("ModuleContext")
+{
+ p = new Private(gd);
+}
+
+ModuleContext::~ModuleContext()
+{
+ delete p;
+}
+
+TemplateVariant ModuleContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% list ClassList[Class] : list of classes
+class ClassListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addClasses(const ClassSDict &classSDict)
+ {
+ ClassSDict::Iterator cli(classSDict);
+ ClassDef *cd;
+ for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL &&
+ ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ ) // no architecture
+ {
+ continue;
+ }
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ append(ClassContext::alloc(cd));
+ }
+ }
+ }
+};
+
+ClassListContext::ClassListContext() : RefCountedContext("ClassListContext")
+{
+ p = new Private;
+ p->addClasses(*Doxygen::classSDict);
+ p->addClasses(*Doxygen::hiddenClasses);
+}
+
+ClassListContext::~ClassListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int ClassListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant ClassListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *ClassListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% list ClassIndex[Class] : list of classes
+class ClassIndexContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ addProperty("list", this,&Private::list);
+ addProperty("fileName", this,&Private::fileName);
+ addProperty("relPath", this,&Private::relPath);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title", this,&Private::title);
+ }
+ TemplateVariant list() const
+ {
+ if (!m_cache.classes)
+ {
+ TemplateList *classList = TemplateList::alloc();
+ if (Doxygen::classSDict)
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL &&
+ ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ ) // no architecture
+ {
+ continue;
+ }
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ classList->append(ClassContext::alloc(cd));
+ }
+ }
+ }
+ m_cache.classes.reset(classList);
+ }
+ return m_cache.classes.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "classes";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "classes";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "classindex";
+ }
+ TemplateVariant title() const
+ {
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (fortranOpt)
+ {
+ return theTranslator->trDataTypes();
+ }
+ else if (vhdlOpt)
+ {
+ return VhdlDocGen::trDesignUnits();
+ }
+ else
+ {
+ return theTranslator->trCompoundIndex();
+ }
+ }
+ private:
+ struct Cachable
+ {
+ SharedPtr<TemplateList> classes;
+ };
+ mutable Cachable m_cache;
+};
+
+ClassIndexContext::ClassIndexContext() : RefCountedContext("ClassIndexContext")
+{
+ p = new Private;
+ //p->addClasses(*Doxygen::hiddenClasses);
+}
+
+ClassIndexContext::~ClassIndexContext()
+{
+ delete p;
+}
+
+// TemplateStructIntf
+TemplateVariant ClassIndexContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct ClassInheritanceNode: node in inheritance tree
+//%% {
+class ClassInheritanceNodeContext::Private : public PropertyMapper
+{
+ public:
+ Private(ClassDef *cd) : m_classDef(cd)
+ {
+ //%% bool is_leaf_node: true if this node does not have any children
+ addProperty("is_leaf_node",this,&Private::isLeafNode);
+ //%% ClassInheritance children: list of nested classes/namespaces
+ addProperty("children",this,&Private::children);
+ //%% Class class: class info
+ addProperty("class",this,&Private::getClass);
+ }
+ void addChildren(const BaseClassList *bcl,bool hideSuper)
+ {
+ if (bcl==0) return;
+ BaseClassListIterator bcli(*bcl);
+ BaseClassDef *bcd;
+ for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli)
+ {
+ ClassDef *cd=bcd->classDef;
+ if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
+ {
+ continue;
+ }
+
+ bool b;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ b=hasVisibleRoot(cd->subClasses());
+ }
+ else
+ {
+ b=hasVisibleRoot(cd->baseClasses());
+ }
+
+ if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
+ {
+ bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
+ ClassInheritanceNodeContext *tnc = new ClassInheritanceNodeContext(cd);
+ m_children.append(tnc);
+ if (hasChildren)
+ {
+ //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
+ bool wasVisited=cd->visited;
+ cd->visited=TRUE;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ tnc->addChildren(cd->baseClasses(),wasVisited);
+ }
+ else
+ {
+ tnc->addChildren(cd->subClasses(),wasVisited);
+ }
+ }
+ }
+ }
+ }
+ TemplateVariant isLeafNode() const
+ {
+ return m_children.isEmpty();
+ }
+ TemplateVariant children() const
+ {
+ return TemplateVariant(&m_children);
+ }
+ TemplateVariant getClass() const
+ {
+ if (!m_cache.classContext)
+ {
+ m_cache.classContext.reset(ClassContext::alloc(m_classDef));
+ }
+ return m_cache.classContext.get();
+ }
+ private:
+ ClassDef *m_classDef;
+ GenericNodeListContext m_children;
+ struct Cachable
+ {
+ SharedPtr<ClassContext> classContext;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ClassInheritanceNodeContext::ClassInheritanceNodeContext(ClassDef *cd) : RefCountedContext("ClassInheritanceNodeContext")
+{
+ p = new Private(cd);
+}
+
+ClassInheritanceNodeContext::~ClassInheritanceNodeContext()
+{
+ delete p;
+}
+
+TemplateVariant ClassInheritanceNodeContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+void ClassInheritanceNodeContext::addChildren(const BaseClassList *bcl,bool hideSuper)
+{
+ p->addChildren(bcl,hideSuper);
+}
+
+//------------------------------------------------------------------------
+
+//%% list ClassInheritance[ClassInheritanceNode]: list of classes
+class ClassInheritanceContext::Private : public GenericNodeListContext
+{
+ public:
+ void addClasses(const ClassSDict &classSDict)
+ {
+ ClassSDict::Iterator cli(classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ bool b;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
+ {
+ continue;
+ }
+ b=!hasVisibleRoot(cd->subClasses());
+ }
+ else
+ {
+ b=!hasVisibleRoot(cd->baseClasses());
+ }
+ if (b)
+ {
+ if (cd->isVisibleInHierarchy()) // should it be visible
+ {
+ // new root level class
+ ClassInheritanceNodeContext *tnc = ClassInheritanceNodeContext::alloc(cd);
+ append(tnc);
+ bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
+ if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
+ {
+ tnc->addChildren(cd->baseClasses(),cd->visited);
+ cd->visited=TRUE;
+ }
+ else if (hasChildren)
+ {
+ tnc->addChildren(cd->subClasses(),cd->visited);
+ cd->visited=TRUE;
+ }
+ }
+ }
+ }
+ }
+};
+
+ClassInheritanceContext::ClassInheritanceContext() : RefCountedContext("ClassInheritanceContext")
+{
+ p = new Private;
+ initClassHierarchy(Doxygen::classSDict);
+ initClassHierarchy(Doxygen::hiddenClasses);
+ p->addClasses(*Doxygen::classSDict);
+ p->addClasses(*Doxygen::hiddenClasses);
+}
+
+ClassInheritanceContext::~ClassInheritanceContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int ClassInheritanceContext::count() const
+{
+ return (int)p->count();
+}
+
+TemplateVariant ClassInheritanceContext::at(int index) const
+{
+ TemplateVariant result;
+ if (index>=0 && index<count())
+ {
+ result = p->at(index);
+ }
+ return result;
+}
+
+TemplateListIntf::ConstIterator *ClassInheritanceContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct ClassHierarchy: inheritance tree
+//%% {
+class ClassHierarchyContext::Private : public PropertyMapper
+{
+ public:
+ TemplateVariant tree() const
+ {
+ if (!m_cache.classTree)
+ {
+ m_cache.classTree.reset(ClassInheritanceContext::alloc());
+ }
+ return m_cache.classTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "hierarchy";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "classes";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "classhierarchy";
+ }
+ TemplateVariant title() const
+ {
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (vhdlOpt)
+ {
+ return VhdlDocGen::trDesignUnitHierarchy();
+ }
+ else
+ {
+ return theTranslator->trClassHierarchy();
+ }
+ }
+ Private()
+ {
+ //%% ClassInheritance tree
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ }
+ private:
+ struct Cachable
+ {
+ SharedPtr<ClassInheritanceContext> classTree;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ClassHierarchyContext::ClassHierarchyContext() : RefCountedContext("ClassHierarchyContext")
+{
+ p = new Private;
+}
+
+ClassHierarchyContext::~ClassHierarchyContext()
+{
+ delete p;
+}
+
+TemplateVariant ClassHierarchyContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct NestingNode: node is a nesting relation tree
+//%% {
+class NestingNodeContext::Private : public PropertyMapper
+{
+ public:
+ Private(const NestingNodeContext *parent,const NestingNodeContext *thisNode,
+ Definition *d,int index,int level,bool addCls)
+ : m_parent(parent), m_def(d), m_level(level), m_index(index)
+ {
+ m_children.reset(NestingContext::alloc(thisNode,level+1));
+ //%% bool is_leaf_node: true if this node does not have any children
+ addProperty("is_leaf_node",this,&Private::isLeafNode);
+ //%% Nesting children: list of nested classes/namespaces
+ addProperty("children",this,&Private::children);
+ //%% [optional] Class class: class info (if this node represents a class)
+ addProperty("class",this,&Private::getClass);
+ //%% [optional] Namespace namespace: namespace info (if this node represents a namespace)
+ addProperty("namespace",this,&Private::getNamespace);
+ //%% [optional] File file: file info (if this node represents a file)
+ addProperty("file",this,&Private::getFile);
+ //%% [optional] Dir dir: directory info (if this node represents a directory)
+ addProperty("dir",this,&Private::getDir);
+ //%% [optional] Page page: page info (if this node represents a page)
+ addProperty("page",this,&Private::getPage);
+ //%% [optional] Module module: module info (if this node represents a module)
+ addProperty("module",this,&Private::getModule);
+ //%% int id
+ addProperty("id",this,&Private::id);
+ //%% string level
+ addProperty("level",this,&Private::level);
+ //%% string name
+ addProperty("name",this,&Private::name);
+ //%% string brief
+ addProperty("brief",this,&Private::brief);
+ //%% bool isLinkable
+ addProperty("isLinkable",this,&Private::isLinkable);
+ addProperty("anchor",this,&Private::anchor);
+ addProperty("fileName",this,&Private::fileName);
+
+ addNamespaces(addCls);
+ addClasses();
+ addDirFiles();
+ addPages();
+ addModules();
+ }
+ TemplateVariant isLeafNode() const
+ {
+ return m_children->count()==0;
+ }
+ TemplateVariant children() const
+ {
+ return m_children.get();
+ }
+ TemplateVariant getClass() const
+ {
+ if (!m_cache.classContext && m_def->definitionType()==Definition::TypeClass)
+ {
+ m_cache.classContext.reset(ClassContext::alloc((ClassDef*)m_def));
+ }
+ if (m_cache.classContext)
+ {
+ return m_cache.classContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getNamespace() const
+ {
+ if (!m_cache.namespaceContext && m_def->definitionType()==Definition::TypeNamespace)
+ {
+ m_cache.namespaceContext.reset(NamespaceContext::alloc((NamespaceDef*)m_def));
+ }
+ if (m_cache.namespaceContext)
+ {
+ return m_cache.namespaceContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getDir() const
+ {
+ if (!m_cache.dirContext && m_def->definitionType()==Definition::TypeDir)
+ {
+ m_cache.dirContext.reset(DirContext::alloc((DirDef*)m_def));
+ }
+ if (m_cache.dirContext)
+ {
+ return m_cache.dirContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getFile() const
+ {
+ if (!m_cache.fileContext && m_def->definitionType()==Definition::TypeFile)
+ {
+ m_cache.fileContext.reset(FileContext::alloc((FileDef*)m_def));
+ }
+ if (m_cache.fileContext)
+ {
+ return m_cache.fileContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getPage() const
+ {
+ if (!m_cache.pageContext && m_def->definitionType()==Definition::TypePage)
+ {
+ m_cache.pageContext.reset(PageContext::alloc((PageDef*)m_def));
+ }
+ if (m_cache.pageContext)
+ {
+ return m_cache.pageContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant getModule() const
+ {
+ if (!m_cache.moduleContext && m_def->definitionType()==Definition::TypeGroup)
+ {
+ m_cache.moduleContext.reset(ModuleContext::alloc((GroupDef*)m_def));
+ }
+ if (m_cache.moduleContext)
+ {
+ return m_cache.moduleContext.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant level() const
+ {
+ return m_level;
+ }
+ TemplateVariant id() const
+ {
+ QCString result;
+ if (m_parent) result=m_parent->id();
+ result+=QCString().setNum(m_index)+"_";
+ return result;
+ }
+ TemplateVariant name() const
+ {
+ return m_def->displayName(FALSE);
+ }
+ QCString relPathAsString() const
+ {
+ static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
+ return createSubdirs ? QCString("../../") : QCString("");
+ }
+ TemplateVariant brief() const
+ {
+ if (!m_cache.brief)
+ {
+ if (m_def->hasBriefDescription())
+ {
+ m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
+ "",m_def->briefDescription(),TRUE)));
+ }
+ else
+ {
+ m_cache.brief.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.brief;
+ }
+ TemplateVariant isLinkable() const
+ {
+ return m_def->isLinkable();
+ }
+ TemplateVariant anchor() const
+ {
+ return m_def->anchor();
+ }
+ TemplateVariant fileName() const
+ {
+ return m_def->getOutputFileBase();
+ }
+
+ void addClasses()
+ {
+ ClassDef *cd = m_def->definitionType()==Definition::TypeClass ? (ClassDef*)m_def : 0;
+ if (cd && cd->getClassSDict())
+ {
+ m_children->addClasses(*cd->getClassSDict(),FALSE);
+ }
+ }
+ void addNamespaces(bool addClasses)
+ {
+ NamespaceDef *nd = m_def->definitionType()==Definition::TypeNamespace ? (NamespaceDef*)m_def : 0;
+ if (nd && nd->getNamespaceSDict())
+ {
+ m_children->addNamespaces(*nd->getNamespaceSDict(),FALSE,addClasses);
+ }
+ if (addClasses && nd && nd->getClassSDict())
+ {
+ m_children->addClasses(*nd->getClassSDict(),FALSE);
+ }
+ }
+ void addDirFiles()
+ {
+ DirDef *dd = m_def->definitionType()==Definition::TypeDir ? (DirDef*)m_def : 0;
+ if (dd)
+ {
+ m_children->addDirs(dd->subDirs());
+ if (dd && dd->getFiles())
+ {
+ m_children->addFiles(*dd->getFiles());
+ }
+ }
+ }
+ void addPages()
+ {
+ PageDef *pd = m_def->definitionType()==Definition::TypePage ? (PageDef*)m_def : 0;
+ if (pd && pd->getSubPages())
+ {
+ m_children->addPages(*pd->getSubPages(),FALSE);
+ }
+ }
+ void addModules()
+ {
+ GroupDef *gd = m_def->definitionType()==Definition::TypeGroup ? (GroupDef*)m_def : 0;
+ if (gd && gd->getSubGroups())
+ {
+ m_children->addModules(*gd->getSubGroups());
+ }
+ }
+ private:
+ const NestingNodeContext *m_parent;
+ Definition *m_def;
+ SharedPtr<NestingContext> m_children;
+ int m_level;
+ int m_index;
+ struct Cachable
+ {
+ SharedPtr<ClassContext> classContext;
+ SharedPtr<NamespaceContext> namespaceContext;
+ SharedPtr<DirContext> dirContext;
+ SharedPtr<FileContext> fileContext;
+ SharedPtr<PageContext> pageContext;
+ SharedPtr<ModuleContext> moduleContext;
+ ScopedPtr<TemplateVariant> brief;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+NestingNodeContext::NestingNodeContext(const NestingNodeContext *parent,
+ Definition *d,int index,int level,bool addClass) : RefCountedContext("NestingNodeContext")
+{
+ p = new Private(parent,this,d,index,level,addClass);
+}
+
+NestingNodeContext::~NestingNodeContext()
+{
+ delete p;
+}
+
+TemplateVariant NestingNodeContext::get(const char *n) const
+{
+ return p->get(n);
+}
+
+QCString NestingNodeContext::id() const
+{
+ return p->id().toString();
+}
+
+//------------------------------------------------------------------------
+
+//%% list Nesting[NestingNode]: namespace and class nesting relations
+class NestingContext::Private : public GenericNodeListContext
+{
+ public:
+ Private(const NestingNodeContext *parent,int level)
+ : m_parent(parent), m_level(level), m_index(0) {}
+
+ void addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses)
+ {
+ NamespaceSDict::Iterator nli(nsDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (nd->localName().find('@')==-1 &&
+ (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
+ {
+ bool hasChildren = namespaceHasVisibleChild(nd,addClasses);
+ bool isLinkable = nd->isLinkableInProject();
+ if (isLinkable || hasChildren)
+ {
+ NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,nd,m_index,m_level,addClasses);
+ append(nnc);
+ m_index++;
+ }
+ }
+ }
+ }
+ void addClasses(const ClassSDict &clDict,bool rootOnly)
+ {
+ ClassSDict::Iterator cli(clDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS
+ )// no architecture
+ {
+ continue;
+ }
+ }
+ if (!rootOnly ||
+ cd->getOuterScope()==0 ||
+ cd->getOuterScope()==Doxygen::globalScope
+ )
+ {
+ if (classVisibleInIndex(cd) && cd->templateMaster()==0)
+ {
+ NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE);
+ append(nnc);
+ m_index++;
+ }
+ }
+ }
+ }
+ void addDirs(const DirSDict &dirDict)
+ {
+ SDict<DirDef>::Iterator dli(dirDict);
+ DirDef *dd;
+ for (dli.toFirst();(dd=dli.current());++dli)
+ {
+ if (dd->getOuterScope()==Doxygen::globalScope)
+ {
+ append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ }
+ void addDirs(const DirList &dirList)
+ {
+ QListIterator<DirDef> li(dirList);
+ DirDef *dd;
+ for (li.toFirst();(dd=li.current());++li)
+ {
+ append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ void addFiles(const FileNameList &fnList)
+ {
+ FileNameListIterator fnli(fnList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->getDirDef()==0) // top level file
+ {
+ append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ }
+ }
+ void addFiles(const FileList &fList)
+ {
+ QListIterator<FileDef> li(fList);
+ FileDef *fd;
+ for (li.toFirst();(fd=li.current());++li)
+ {
+ append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ void addPages(const PageSDict &pages,bool rootOnly)
+ {
+ SDict<PageDef>::Iterator pli(pages);
+ PageDef *pd;
+ for (pli.toFirst();(pd=pli.current());++pli)
+ {
+ if (!rootOnly ||
+ pd->getOuterScope()==0 ||
+ pd->getOuterScope()->definitionType()!=Definition::TypePage)
+ {
+ append(NestingNodeContext::alloc(m_parent,pd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ }
+ void addModules(const GroupSDict &groups)
+ {
+ GroupSDict::Iterator gli(groups);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ static bool externalGroups = Config_getBool("EXTERNAL_GROUPS");
+ if (!gd->isASubGroup() && gd->isVisible() &&
+ (!gd->isReference() || externalGroups)
+ )
+ {
+ append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ }
+ void addModules(const GroupList &list)
+ {
+ GroupListIterator gli(list);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (gd->isVisible())
+ {
+ append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE));
+ m_index++;
+ }
+ }
+ }
+ private:
+ const NestingNodeContext *m_parent;
+ int m_level;
+ int m_index;
+};
+
+NestingContext::NestingContext(const NestingNodeContext *parent,int level) : RefCountedContext("NestingContext")
+{
+ p = new Private(parent,level);
+}
+
+NestingContext::~NestingContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int NestingContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant NestingContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *NestingContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+void NestingContext::addClasses(const ClassSDict &clDict,bool rootOnly)
+{
+ p->addClasses(clDict,rootOnly);
+}
+
+void NestingContext::addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses)
+{
+ p->addNamespaces(nsDict,rootOnly,addClasses);
+}
+
+void NestingContext::addDirs(const DirSDict &dirs)
+{
+ p->addDirs(dirs);
+}
+
+void NestingContext::addDirs(const DirList &dirs)
+{
+ p->addDirs(dirs);
+}
+
+void NestingContext::addFiles(const FileNameList &files)
+{
+ p->addFiles(files);
+}
+
+void NestingContext::addFiles(const FileList &files)
+{
+ p->addFiles(files);
+}
+
+void NestingContext::addPages(const PageSDict &pages,bool rootOnly)
+{
+ p->addPages(pages,rootOnly);
+}
+
+void NestingContext::addModules(const GroupSDict &modules)
+{
+ p->addModules(modules);
+}
+
+void NestingContext::addModules(const GroupList &modules)
+{
+ p->addModules(modules);
+}
+
+//------------------------------------------------------------------------
+
+static int computeMaxDepth(const TemplateListIntf *list)
+{
+ int maxDepth=0;
+ if (list)
+ {
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ TemplateVariant v;
+ for (it->toFirst();it->current(v);it->toNext())
+ {
+ const TemplateStructIntf *s = v.toStruct();
+ TemplateVariant child = s->get("children");
+ int d = computeMaxDepth(child.toList())+1;
+ if (d>maxDepth) maxDepth=d;
+ }
+ delete it;
+ }
+ return maxDepth;
+}
+
+static int computeNumNodesAtLevel(const TemplateStructIntf *s,int level,int maxLevel)
+{
+ int num=0;
+ if (level<maxLevel)
+ {
+ num++;
+ TemplateVariant child = s->get("children");
+ if (child.toList())
+ {
+ TemplateListIntf::ConstIterator *it = child.toList()->createIterator();
+ TemplateVariant v;
+ for (it->toFirst();it->current(v);it->toNext())
+ {
+ num+=computeNumNodesAtLevel(v.toStruct(),level+1,maxLevel);
+ }
+ delete it;
+ }
+ }
+ return num;
+}
+
+static int computePreferredDepth(const TemplateListIntf *list,int maxDepth)
+{
+ int preferredNumEntries = Config_getInt("HTML_INDEX_NUM_ENTRIES");
+ int preferredDepth=1;
+ if (preferredNumEntries>0)
+ {
+ int depth = maxDepth;
+ for (int i=1;i<=depth;i++)
+ {
+ int num=0;
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ TemplateVariant v;
+ for (it->toFirst();it->current(v);it->toNext())
+ {
+ num+=computeNumNodesAtLevel(v.toStruct(),0,i);
+ }
+ delete it;
+ if (num<=preferredNumEntries)
+ {
+ preferredDepth=i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return preferredDepth;
+}
+
+
+//%% struct ClassTree: Class nesting relations
+//%% {
+class ClassTreeContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ m_classTree.reset(NestingContext::alloc(0,0));
+ if (Doxygen::namespaceSDict)
+ {
+ m_classTree->addNamespaces(*Doxygen::namespaceSDict,TRUE,TRUE);
+ }
+ if (Doxygen::classSDict)
+ {
+ m_classTree->addClasses(*Doxygen::classSDict,TRUE);
+ }
+ //%% Nesting tree
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ addProperty("preferredDepth",this,&Private::preferredDepth);
+ addProperty("maxDepth",this,&Private::maxDepth);
+ }
+ TemplateVariant tree() const
+ {
+ return m_classTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "annotated";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "classes";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "classlist";
+ }
+ TemplateVariant title() const
+ {
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (fortranOpt)
+ {
+ return theTranslator->trCompoundListFortran();
+ }
+ else if (vhdlOpt)
+ {
+ return VhdlDocGen::trDesignUnitList();
+ }
+ else
+ {
+ return theTranslator->trClasses();
+ }
+ }
+ TemplateVariant maxDepth() const
+ {
+ if (!m_cache.maxDepthComputed)
+ {
+ m_cache.maxDepth = computeMaxDepth(m_classTree.get());
+ m_cache.maxDepthComputed=TRUE;
+ }
+ return m_cache.maxDepth;
+ }
+ TemplateVariant preferredDepth() const
+ {
+ if (!m_cache.preferredDepthComputed)
+ {
+ m_cache.preferredDepth = computePreferredDepth(m_classTree.get(),maxDepth().toInt());
+ m_cache.preferredDepthComputed=TRUE;
+ }
+ return m_cache.preferredDepth;
+ }
+ private:
+ SharedPtr<NestingContext> m_classTree;
+ struct Cachable
+ {
+ Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
+ int maxDepth;
+ bool maxDepthComputed;
+ int preferredDepth;
+ bool preferredDepthComputed;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ClassTreeContext::ClassTreeContext() : RefCountedContext("ClassTreeContext")
+{
+ p = new Private;
+}
+
+ClassTreeContext::~ClassTreeContext()
+{
+ delete p;
+}
+
+TemplateVariant ClassTreeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list NamespaceList[Namespace] : list of namespaces
+class NamespaceListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addNamespaces(const NamespaceSDict &nsDict)
+ {
+ NamespaceSDict::Iterator nli(nsDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ append(NamespaceContext::alloc(nd));
+ }
+ }
+ }
+};
+
+NamespaceListContext::NamespaceListContext() : RefCountedContext("NamespaceListContext")
+{
+ p = new Private;
+ p->addNamespaces(*Doxygen::namespaceSDict);
+}
+
+NamespaceListContext::~NamespaceListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int NamespaceListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant NamespaceListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct NamespaceTree: tree of nested namespace
+//%% {
+class NamespaceTreeContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ m_namespaceTree.reset(NestingContext::alloc(0,0));
+ if (Doxygen::namespaceSDict)
+ {
+ m_namespaceTree->addNamespaces(*Doxygen::namespaceSDict,TRUE,FALSE);
+ }
+ //%% Nesting tree
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ addProperty("preferredDepth",this,&Private::preferredDepth);
+ addProperty("maxDepth",this,&Private::maxDepth);
+ }
+ TemplateVariant tree() const
+ {
+ return m_namespaceTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "namespaces";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "namespaces";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "namespacelist";
+ }
+ TemplateVariant title() const
+ {
+ static bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (javaOpt || vhdlOpt)
+ {
+ return theTranslator->trPackages();
+ }
+ else if (fortranOpt)
+ {
+ return theTranslator->trModulesList();
+ }
+ else
+ {
+ return theTranslator->trNamespaceList();
+ }
+ }
+ TemplateVariant maxDepth() const
+ {
+ if (!m_cache.maxDepthComputed)
+ {
+ m_cache.maxDepth = computeMaxDepth(m_namespaceTree.get());
+ m_cache.maxDepthComputed=TRUE;
+ }
+ return m_cache.maxDepth;
+ }
+ TemplateVariant preferredDepth() const
+ {
+ if (!m_cache.preferredDepthComputed)
+ {
+ m_cache.preferredDepth = computePreferredDepth(m_namespaceTree.get(),maxDepth().toInt());
+ m_cache.preferredDepthComputed=TRUE;
+ }
+ return m_cache.preferredDepth;
+ }
+ private:
+ SharedPtr<NestingContext> m_namespaceTree;
+ struct Cachable
+ {
+ Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
+ int maxDepth;
+ bool maxDepthComputed;
+ int preferredDepth;
+ bool preferredDepthComputed;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+NamespaceTreeContext::NamespaceTreeContext() : RefCountedContext("NamespaceTreeContext")
+{
+ p = new Private;
+}
+
+NamespaceTreeContext::~NamespaceTreeContext()
+{
+ delete p;
+}
+
+TemplateVariant NamespaceTreeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list FileList[File] : list of files
+class FileListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addFiles(const FileNameList &fnList)
+ {
+ // TODO: if FULL_PATH_NAMES is enabled, the ordering should be dir+file
+ FileNameListIterator fnli(fnList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ bool doc = fd->isLinkableInProject();
+ bool src = fd->generateSourceFile();
+ bool nameOk = !fd->isDocumentationFile();
+ if (nameOk && (doc || src) && !fd->isReference())
+ {
+ append(FileContext::alloc(fd));
+ }
+ }
+ }
+ }
+};
+
+FileListContext::FileListContext() : RefCountedContext("FileListContext")
+{
+ p = new Private;
+ if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList);
+}
+
+FileListContext::~FileListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int FileListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant FileListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *FileListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% list DirList[Dir] : list of files
+class DirListContext::Private : public GenericNodeListContext
+{
+ public:
+ Private()
+ {
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ append(DirContext::alloc(dir));
+ }
+ }
+};
+
+DirListContext::DirListContext() : RefCountedContext("DirListContext")
+{
+ p = new Private;
+}
+
+DirListContext::~DirListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int DirListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant DirListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *DirListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+
+//------------------------------------------------------------------------
+
+//%% list UsedFiles[File] : list of files
+class UsedFilesContext::Private : public GenericNodeListContext
+{
+ public:
+ void addFile(FileDef *fd)
+ {
+ append(FileContext::alloc(fd));
+ }
+};
+
+UsedFilesContext::UsedFilesContext(ClassDef *cd) : RefCountedContext("UsedFilesContext")
+{
+ p = new Private;
+ if (cd)
+ {
+ QListIterator<FileDef> li(cd->usedFiles());
+ FileDef *fd;
+ for (li.toFirst();(fd=li.current());++li)
+ {
+ p->addFile(fd);
+ }
+ }
+}
+
+UsedFilesContext::~UsedFilesContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int UsedFilesContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant UsedFilesContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+void UsedFilesContext::addFile(FileDef *fd)
+{
+ p->addFile(fd);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct FileTree: tree of directories and files
+//%% {
+class FileTreeContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ // Add dirs tree
+ m_dirFileTree.reset(NestingContext::alloc(0,0));
+ if (Doxygen::directories)
+ {
+ m_dirFileTree->addDirs(*Doxygen::directories);
+ }
+ if (Doxygen::inputNameList)
+ {
+ m_dirFileTree->addFiles(*Doxygen::inputNameList);
+ }
+ //%% DirFile tree:
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ addProperty("preferredDepth",this,&Private::preferredDepth);
+ addProperty("maxDepth",this,&Private::maxDepth);
+ }
+ TemplateVariant tree() const
+ {
+ return m_dirFileTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "files";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "files";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "filelist";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trFileList();
+ }
+ TemplateVariant maxDepth() const
+ {
+ if (!m_cache.maxDepthComputed)
+ {
+ m_cache.maxDepth = computeMaxDepth(m_dirFileTree.get());
+ m_cache.maxDepthComputed=TRUE;
+ }
+ return m_cache.maxDepth;
+ }
+ TemplateVariant preferredDepth() const
+ {
+ if (!m_cache.preferredDepthComputed)
+ {
+ m_cache.preferredDepth = computePreferredDepth(m_dirFileTree.get(),maxDepth().toInt());
+ m_cache.preferredDepthComputed=TRUE;
+ }
+ return m_cache.preferredDepth;
+ }
+ private:
+ SharedPtr<NestingContext> m_dirFileTree;
+ struct Cachable
+ {
+ Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
+ int maxDepth;
+ bool maxDepthComputed;
+ int preferredDepth;
+ bool preferredDepthComputed;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+FileTreeContext::FileTreeContext() : RefCountedContext("FileTreeContext")
+{
+ p = new Private;
+}
+
+FileTreeContext::~FileTreeContext()
+{
+ delete p;
+}
+
+TemplateVariant FileTreeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct PageTree: tree of related pages
+//%% {
+class PageTreeContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ m_pageTree.reset(NestingContext::alloc(0,0));
+ // Add pages
+ if (Doxygen::pageSDict)
+ {
+ m_pageTree->addPages(*Doxygen::pageSDict,TRUE);
+ }
+
+ //%% PageNodeList tree:
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ addProperty("preferredDepth",this,&Private::preferredDepth);
+ addProperty("maxDepth",this,&Private::maxDepth);
+ }
+ TemplateVariant tree() const
+ {
+ return m_pageTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "pages";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "pages";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trRelatedPages();
+ }
+ TemplateVariant maxDepth() const
+ {
+ if (!m_cache.maxDepthComputed)
+ {
+ m_cache.maxDepth = computeMaxDepth(m_pageTree.get());
+ m_cache.maxDepthComputed=TRUE;
+ }
+ return m_cache.maxDepth;
+ }
+ TemplateVariant preferredDepth() const
+ {
+ if (!m_cache.preferredDepthComputed)
+ {
+ m_cache.preferredDepth = computePreferredDepth(m_pageTree.get(),maxDepth().toInt());
+ m_cache.preferredDepthComputed=TRUE;
+ }
+ return m_cache.preferredDepth;
+ }
+ private:
+ SharedPtr<NestingContext> m_pageTree;
+ struct Cachable
+ {
+ Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
+ int maxDepth;
+ bool maxDepthComputed;
+ int preferredDepth;
+ bool preferredDepthComputed;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+PageTreeContext::PageTreeContext() : RefCountedContext("PageTreeContext")
+{
+ p = new Private;
+}
+
+PageTreeContext::~PageTreeContext()
+{
+ delete p;
+}
+
+TemplateVariant PageTreeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list PageList[Page]: list of pages
+class PageListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addPages(const PageSDict &pages)
+ {
+ PageSDict::Iterator pdi(pages);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (!pd->getGroupDef() && !pd->isReference())
+ {
+ append(PageContext::alloc(pd));
+ }
+ }
+ }
+};
+
+PageListContext::PageListContext(const PageSDict *pages) : RefCountedContext("PageListContext")
+{
+ p = new Private;
+ if (pages) p->addPages(*pages);
+}
+
+PageListContext::~PageListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int PageListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant PageListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *PageListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% list ModuleList[ModuleNode]: list of directories and/or files
+class ModuleListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addModules()
+ {
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (!gd->isReference())
+ {
+ append(ModuleContext::alloc(gd));
+ }
+ }
+ }
+};
+
+ModuleListContext::ModuleListContext() : RefCountedContext("ModuleListContext")
+{
+ p = new Private;
+ p->addModules();
+}
+
+ModuleListContext::~ModuleListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int ModuleListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant ModuleListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *ModuleListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct ModuleTree: tree of modules
+//%% {
+class ModuleTreeContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ m_moduleTree.reset(NestingContext::alloc(0,0));
+ // Add modules
+ if (Doxygen::groupSDict)
+ {
+ m_moduleTree->addModules(*Doxygen::groupSDict);
+ }
+
+ //%% ModuleList tree:
+ addProperty("tree",this,&Private::tree);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ addProperty("preferredDepth",this,&Private::preferredDepth);
+ addProperty("maxDepth",this,&Private::maxDepth);
+ }
+ TemplateVariant tree() const
+ {
+ return m_moduleTree.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "modules";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "modules";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trModules();
+ }
+ TemplateVariant maxDepth() const
+ {
+ if (!m_cache.maxDepthComputed)
+ {
+ m_cache.maxDepth = computeMaxDepth(m_moduleTree.get());
+ m_cache.maxDepthComputed=TRUE;
+ }
+ return m_cache.maxDepth;
+ }
+ TemplateVariant preferredDepth() const
+ {
+ if (!m_cache.preferredDepthComputed)
+ {
+ m_cache.preferredDepth = computePreferredDepth(m_moduleTree.get(),maxDepth().toInt());
+ m_cache.preferredDepthComputed=TRUE;
+ }
+ return m_cache.preferredDepth;
+ }
+ private:
+ SharedPtr<NestingContext> m_moduleTree;
+ struct Cachable
+ {
+ Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
+ int maxDepth;
+ bool maxDepthComputed;
+ int preferredDepth;
+ bool preferredDepthComputed;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ModuleTreeContext::ModuleTreeContext() : RefCountedContext("ModuleTreeContext")
+{
+ p = new Private;
+}
+
+ModuleTreeContext::~ModuleTreeContext()
+{
+ delete p;
+}
+
+TemplateVariant ModuleTreeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct NavPathElem: list of examples page
+//%% {
+class NavPathElemContext::Private : public PropertyMapper
+{
+ public:
+ Private(Definition *def) : m_def(def)
+ {
+ addProperty("isLinkable",this,&Private::isLinkable);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("anchor",this,&Private::anchor);
+ addProperty("text",this,&Private::text);
+ }
+ TemplateVariant isLinkable() const
+ {
+ return m_def->isLinkable();
+ }
+ TemplateVariant anchor() const
+ {
+ return m_def->anchor();
+ }
+ TemplateVariant fileName() const
+ {
+ return m_def->getOutputFileBase();
+ }
+ TemplateVariant text() const
+ {
+ Definition::DefType type = m_def->definitionType();
+ QCString text = m_def->localName();
+ if (type==Definition::TypeGroup)
+ {
+ text = ((const GroupDef*)m_def)->groupTitle();
+ }
+ else if (type==Definition::TypePage && !(((const PageDef*)m_def)->title().isEmpty()))
+ {
+ text = ((const PageDef*)m_def)->title();
+ }
+ else if (type==Definition::TypeClass)
+ {
+ if (text.right(2)=="-p")
+ {
+ text = text.left(text.length()-2);
+ }
+ }
+ return text;
+ }
+ private:
+ Definition *m_def;
+};
+//%% }
+
+NavPathElemContext::NavPathElemContext(Definition *def) : RefCountedContext("NavPathElemContext")
+{
+ p = new Private(def);
+}
+
+NavPathElemContext::~NavPathElemContext()
+{
+ delete p;
+}
+
+TemplateVariant NavPathElemContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+
+//------------------------------------------------------------------------
+
+//%% struct ExampleList: list of examples page
+//%% {
+class ExampleListContext::Private : public PropertyMapper
+{
+ public:
+ TemplateVariant items() const
+ {
+ return m_pageList.get();
+ }
+ TemplateVariant fileName() const
+ {
+ return "examples";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "examples";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trExamples();
+ }
+ Private()
+ {
+ m_pageList.reset(PageListContext::alloc(Doxygen::exampleSDict));
+
+ addProperty("items",this,&Private::items);
+ addProperty("fileName",this,&Private::fileName);
+ addProperty("relPath",this,&Private::relPath);
+ addProperty("highlight",this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title",this,&Private::title);
+ }
+ private:
+ SharedPtr<PageListContext> m_pageList;
+};
+//%% }
+
+ExampleListContext::ExampleListContext() : RefCountedContext("ExampleListContext")
+{
+ p = new Private;
+}
+
+ExampleListContext::~ExampleListContext()
+{
+ delete p;
+}
+
+TemplateVariant ExampleListContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct GlobalsIndex: list of examples page
+//%% {
+class GlobalsIndexContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ addProperty("all", this,&Private::all);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("enumValues", this,&Private::enumValues);
+ addProperty("macros", this,&Private::macros);
+ addProperty("properties", this,&Private::properties);
+ addProperty("events", this,&Private::events);
+ addProperty("related", this,&Private::related);
+ addProperty("fileName", this,&Private::fileName);
+ addProperty("relPath", this,&Private::relPath);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title", this,&Private::title);
+ }
+ typedef bool (MemberDef::*MemberFunc)() const;
+ TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
+ {
+ if (!listRef)
+ {
+ TemplateList *list = TemplateList::alloc();
+ MemberName *mn;
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ FileDef *fd=md->getFileDef();
+ if (fd && fd->isLinkableInProject() &&
+ !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject())
+ {
+ if (filter==0 || (md->*filter)())
+ {
+ list->append(MemberContext::alloc(md));
+ }
+ }
+ }
+ }
+ listRef.reset(list);
+ }
+ return listRef.get();
+ }
+ TemplateVariant all() const
+ {
+ return getMembersFiltered(m_cache.all,0);
+ }
+ TemplateVariant functions() const
+ {
+ return getMembersFiltered(m_cache.functions,&MemberDef::isFunction);
+ }
+ TemplateVariant variables() const
+ {
+ return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
+ }
+ TemplateVariant enums() const
+ {
+ return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
+ }
+ TemplateVariant enumValues() const
+ {
+ return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
+ }
+ TemplateVariant macros() const
+ {
+ return getMembersFiltered(m_cache.macros,&MemberDef::isDefine);
+ }
+ TemplateVariant properties() const
+ {
+ return FALSE;
+ }
+ TemplateVariant events() const
+ {
+ return FALSE;
+ }
+ TemplateVariant related() const
+ {
+ return FALSE;
+ }
+ TemplateVariant fileName() const
+ {
+ return "globals";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "files";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "filemembers";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trFileMembers();
+ }
+ private:
+ struct Cachable
+ {
+ Cachable() {}
+ SharedPtr<TemplateList> all;
+ SharedPtr<TemplateList> functions;
+ SharedPtr<TemplateList> variables;
+ SharedPtr<TemplateList> typedefs;
+ SharedPtr<TemplateList> enums;
+ SharedPtr<TemplateList> enumValues;
+ SharedPtr<TemplateList> macros;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+GlobalsIndexContext::GlobalsIndexContext() : RefCountedContext("GlobalsIndexContext")
+{
+ p = new Private;
+}
+
+GlobalsIndexContext::~GlobalsIndexContext()
+{
+ delete p;
+}
+
+TemplateVariant GlobalsIndexContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct ClassMembersIndex: list of examples page
+//%% {
+class ClassMembersIndexContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ addProperty("all", this,&Private::all);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("enumValues", this,&Private::enumValues);
+ addProperty("macros", this,&Private::macros);
+ addProperty("properties", this,&Private::properties);
+ addProperty("events", this,&Private::events);
+ addProperty("related", this,&Private::related);
+ addProperty("fileName", this,&Private::fileName);
+ addProperty("relPath", this,&Private::relPath);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title", this,&Private::title);
+ }
+ typedef bool (MemberDef::*MemberFunc)() const;
+ TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
+ {
+ if (!listRef)
+ {
+ TemplateList *list = TemplateList::alloc();
+ MemberName *mn;
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ ClassDef *cd = md->getClassDef();
+ if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 &&
+ md->isLinkableInProject() && !md->name().isEmpty())
+ {
+ if (filter==0 || (md->*filter)())
+ {
+ list->append(MemberContext::alloc(md));
+ }
+ }
+ }
+ }
+ listRef.reset(list);
+ }
+ return listRef.get();
+ }
+ TemplateVariant all() const
+ {
+ return getMembersFiltered(m_cache.all,&MemberDef::isNotFriend);
+ }
+ TemplateVariant functions() const
+ {
+ return getMembersFiltered(m_cache.functions,&MemberDef::isFunctionOrSignalSlot);
+ }
+ TemplateVariant variables() const
+ {
+ return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
+ }
+ TemplateVariant enums() const
+ {
+ return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
+ }
+ TemplateVariant enumValues() const
+ {
+ return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
+ }
+ TemplateVariant macros() const
+ {
+ return FALSE;
+ }
+ TemplateVariant properties() const
+ {
+ return getMembersFiltered(m_cache.properties,&MemberDef::isProperty);
+ }
+ TemplateVariant events() const
+ {
+ return getMembersFiltered(m_cache.events,&MemberDef::isEvent);
+ }
+ TemplateVariant related() const
+ {
+ return getMembersFiltered(m_cache.related,&MemberDef::isRelated);
+ }
+ TemplateVariant fileName() const
+ {
+ return "functions";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "classes";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "classmembers";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trCompoundMembers();
+ }
+ private:
+ struct Cachable
+ {
+ Cachable() {}
+ SharedPtr<TemplateList> all;
+ SharedPtr<TemplateList> functions;
+ SharedPtr<TemplateList> variables;
+ SharedPtr<TemplateList> typedefs;
+ SharedPtr<TemplateList> enums;
+ SharedPtr<TemplateList> enumValues;
+ SharedPtr<TemplateList> properties;
+ SharedPtr<TemplateList> events;
+ SharedPtr<TemplateList> related;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ClassMembersIndexContext::ClassMembersIndexContext() : RefCountedContext("ClassMembersIndexContext")
+{
+ p = new Private;
+}
+
+ClassMembersIndexContext::~ClassMembersIndexContext()
+{
+ delete p;
+}
+
+TemplateVariant ClassMembersIndexContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct NamespaceMembersIndex: list of examples page
+//%% {
+class NamespaceMembersIndexContext::Private : public PropertyMapper
+{
+ public:
+ Private()
+ {
+ addProperty("all", this,&Private::all);
+ addProperty("functions", this,&Private::functions);
+ addProperty("variables", this,&Private::variables);
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("enums", this,&Private::enums);
+ addProperty("enumValues", this,&Private::enumValues);
+ addProperty("macros", this,&Private::macros);
+ addProperty("properties", this,&Private::properties);
+ addProperty("events", this,&Private::events);
+ addProperty("related", this,&Private::related);
+ addProperty("fileName", this,&Private::fileName);
+ addProperty("relPath", this,&Private::relPath);
+ addProperty("highlight", this,&Private::highlight);
+ addProperty("subhighlight",this,&Private::subhighlight);
+ addProperty("title", this,&Private::title);
+ }
+ typedef bool (MemberDef::*MemberFunc)() const;
+ TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
+ {
+ if (!listRef)
+ {
+ TemplateList *list = TemplateList::alloc();
+ MemberName *mn;
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ NamespaceDef *nd=md->getNamespaceDef();
+ if (nd && nd->isLinkableInProject() &&
+ !md->name().isEmpty() && md->isLinkableInProject())
+ {
+ if (filter==0 || (md->*filter)())
+ {
+ list->append(MemberContext::alloc(md));
+ }
+ }
+ }
+ }
+ listRef.reset(list);
+ }
+ return listRef.get();
+ }
+ TemplateVariant all() const
+ {
+ return getMembersFiltered(m_cache.all,0);
+ }
+ TemplateVariant functions() const
+ {
+ return getMembersFiltered(m_cache.functions,&MemberDef::isFunction);
+ }
+ TemplateVariant variables() const
+ {
+ return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
+ }
+ TemplateVariant enums() const
+ {
+ return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
+ }
+ TemplateVariant enumValues() const
+ {
+ return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
+ }
+ TemplateVariant macros() const
+ {
+ return FALSE;
+ }
+ TemplateVariant properties() const
+ {
+ return FALSE;
+ }
+ TemplateVariant events() const
+ {
+ return FALSE;
+ }
+ TemplateVariant related() const
+ {
+ return FALSE;
+ }
+ TemplateVariant fileName() const
+ {
+ return "namespacemembers";
+ }
+ TemplateVariant relPath() const
+ {
+ return "";
+ }
+ TemplateVariant highlight() const
+ {
+ return "namespaces";
+ }
+ TemplateVariant subhighlight() const
+ {
+ return "namespacemembers";
+ }
+ TemplateVariant title() const
+ {
+ return theTranslator->trNamespaceMembers();
+ }
+ private:
+ struct Cachable
+ {
+ Cachable() {}
+ SharedPtr<TemplateList> all;
+ SharedPtr<TemplateList> functions;
+ SharedPtr<TemplateList> variables;
+ SharedPtr<TemplateList> typedefs;
+ SharedPtr<TemplateList> enums;
+ SharedPtr<TemplateList> enumValues;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+NamespaceMembersIndexContext::NamespaceMembersIndexContext() : RefCountedContext("NamespaceMembersIndexContext")
+{
+ p = new Private;
+}
+
+NamespaceMembersIndexContext::~NamespaceMembersIndexContext()
+{
+ delete p;
+}
+
+TemplateVariant NamespaceMembersIndexContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+
+//------------------------------------------------------------------------
+
+//%% struct InheritanceNode: a class in the inheritance list
+//%% {
+class InheritanceNodeContext::Private : public PropertyMapper
+{
+ public:
+ Private(ClassDef *cd,const QCString &name) : m_classDef(cd), m_name(name)
+ {
+ addProperty("class",this,&Private::getClass);
+ addProperty("name",this,&Private::name);
+ }
+ TemplateVariant getClass() const
+ {
+ if (!m_classContext)
+ {
+ m_classContext.reset(ClassContext::alloc(m_classDef));
+ }
+ return m_classContext.get();
+ }
+ TemplateVariant name() const
+ {
+ return m_name;
+ }
+ private:
+ ClassDef *m_classDef;
+ mutable SharedPtr<ClassContext> m_classContext;
+ QCString m_name;
+};
+//%% }
+
+InheritanceNodeContext::InheritanceNodeContext(ClassDef *cd,const QCString &name) : RefCountedContext("InheritanceNodeContext")
+{
+ p = new Private(cd,name);
+}
+
+InheritanceNodeContext::~InheritanceNodeContext()
+{
+ delete p;
+}
+
+TemplateVariant InheritanceNodeContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list InheritanceList[InheritanceNode] : list of inherited classes
+class InheritanceListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addClass(ClassDef *cd,const QCString &name)
+ {
+ append(InheritanceNodeContext::alloc(cd,name));
+ }
+};
+
+InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses) : RefCountedContext("InheritanceListContext")
+{
+ p = new Private;
+ if (list)
+ {
+ BaseClassListIterator li(*list);
+ BaseClassDef *bcd;
+ for (li.toFirst();(bcd=li.current());++li)
+ {
+ ClassDef *cd=bcd->classDef;
+ QCString name;
+ if (baseClasses)
+ {
+ name = insertTemplateSpecifierInScope(
+ cd->displayName(),bcd->templSpecifiers);
+ }
+ else
+ {
+ name = cd->displayName();
+ }
+ //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses);
+ p->addClass(cd,name);
+ }
+ }
+}
+
+InheritanceListContext::~InheritanceListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int InheritanceListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant InheritanceListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% list MemberList[Member] : list of inherited classes
+class MemberListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addMember(MemberDef *md)
+ {
+ append(MemberContext::alloc(md));
+ }
+};
+
+MemberListContext::MemberListContext() : RefCountedContext("MemberListContext")
+{
+ p = new Private;
+}
+
+MemberListContext::MemberListContext(const MemberList *list) : RefCountedContext("MemberListContext")
+{
+ p = new Private;
+ if (list)
+ {
+ bool details = list->listType()&MemberListType_detailedLists;
+ MemberListIterator mli(*list);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if ((md->isBriefSectionVisible() && !details) ||
+ (md->isDetailedSectionLinkable() && details)
+ )
+ {
+ p->addMember(md);
+ }
+ }
+ }
+}
+
+MemberListContext::MemberListContext(MemberSDict *list,bool doSort) : RefCountedContext("MemberListContext")
+{
+ p = new Private;
+ if (list)
+ {
+ if (doSort)
+ {
+ list->sort();
+ }
+ MemberSDict::Iterator it(*list);
+ MemberDef *md;
+ for (it.toFirst();(md=it.current());++it)
+ {
+ p->addMember(md);
+ }
+ }
+}
+
+MemberListContext::~MemberListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int MemberListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant MemberListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *MemberListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct MemberInfo: member information
+//%% {
+class MemberInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(const MemberInfo *mi) : m_memberInfo(mi)
+ {
+ //%% string protection
+ addProperty("protection",this,&Private::protection);
+ //%% string virtualness
+ addProperty("virtualness",this,&Private::virtualness);
+ //%% string ambiguityScope
+ addProperty("ambiguityScope",this,&Private::ambiguityScope);
+ //%% Member member
+ addProperty("member",this,&Private::member);
+ }
+ TemplateVariant protection() const
+ {
+ switch (m_memberInfo->prot)
+ {
+ case ::Public: return "public";
+ case ::Protected: return "protected";
+ case ::Private: return "private";
+ case ::Package: return "package";
+ }
+ return "";
+ }
+ TemplateVariant virtualness() const
+ {
+ switch (m_memberInfo->virt)
+ {
+ case ::Normal: return "normal";
+ case ::Virtual: return "virtual";
+ case ::Pure: return "pure";
+ }
+ return "";
+ }
+ TemplateVariant ambiguityScope() const
+ {
+ return m_memberInfo->ambiguityResolutionScope;
+ }
+ TemplateVariant member() const
+ {
+ if (!m_member && m_memberInfo->memberDef)
+ {
+ m_member.reset(MemberContext::alloc(m_memberInfo->memberDef));
+ }
+ if (m_member)
+ {
+ return m_member.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ private:
+ const MemberInfo *m_memberInfo;
+ mutable SharedPtr<MemberContext> m_member;
+};
+//%% }
+
+MemberInfoContext::MemberInfoContext(const MemberInfo *mi) : RefCountedContext("MemberInfoContext")
+{
+ p = new Private(mi);
+}
+
+MemberInfoContext::~MemberInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant MemberInfoContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+
+//------------------------------------------------------------------------
+
+//%% list AllMembersList[MemberList] : list of inherited classes
+class AllMembersListContext::Private : public GenericNodeListContext
+{
+ public:
+ Private(const MemberNameInfoSDict *ml)
+ {
+ if (ml)
+ {
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ MemberNameInfoSDict::Iterator mnii(*ml);
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberNameInfoIterator mnii2(*mni);
+ MemberInfo *mi;
+ for (mnii2.toFirst();(mi=mnii2.current());++mnii2)
+ {
+ MemberDef *md=mi->memberDef;
+ ClassDef *cd=md->getClassDef();
+ if (cd && !md->name().isEmpty() && md->name()[0]!='@')
+ {
+ if ((cd->isLinkable() && md->isLinkable()) ||
+ (!cd->isArtificial() && !hideUndocMembers &&
+ (protectionLevelVisible(md->protection()) || md->isFriend())
+ )
+ )
+ {
+ append(MemberInfoContext::alloc(mi));
+ }
+ }
+ }
+ }
+ }
+ }
+};
+
+AllMembersListContext::AllMembersListContext() : RefCountedContext("AllMembersListContext")
+{
+ p = new Private(0);
+}
+
+AllMembersListContext::AllMembersListContext(const MemberNameInfoSDict *ml) : RefCountedContext("AllMembersListContext")
+{
+ p = new Private(ml);
+}
+
+AllMembersListContext::~AllMembersListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int AllMembersListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant AllMembersListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *AllMembersListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct MemberGroupInfo: member group information
+//%% {
+class MemberGroupInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(Definition *def,const QCString &relPath,const MemberGroup *mg) :
+ m_def(def),
+ m_relPath(relPath),
+ m_memberGroup(mg)
+ {
+ addProperty("members", this,&Private::members);
+ addProperty("title", this,&Private::groupTitle);
+ addProperty("subtitle", this,&Private::groupSubtitle);
+ addProperty("anchor", this,&Private::groupAnchor);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("docs", this,&Private::docs);
+ addProperty("inherited", this,&Private::inherited);
+ }
+ TemplateVariant members() const
+ {
+ if (!m_cache.memberListContext)
+ {
+ m_cache.memberListContext.reset(MemberListContext::alloc(m_memberGroup->members()));
+ }
+ return m_cache.memberListContext.get();
+ }
+ TemplateVariant groupTitle() const
+ {
+ return m_memberGroup->header();
+ }
+ TemplateVariant groupSubtitle() const
+ {
+ return "";
+ }
+ TemplateVariant groupAnchor() const
+ {
+ return m_memberGroup->anchor();
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,0));
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant docs() const
+ {
+ if (!m_cache.docs)
+ {
+ QCString docs = m_memberGroup->documentation();
+ if (!docs.isEmpty())
+ {
+ m_cache.docs.reset(new TemplateVariant(
+ parseDoc(m_def,"[@name docs]",-1, // TODO store file & line
+ m_relPath,
+ m_memberGroup->documentation()+"\n",FALSE)));
+ }
+ else
+ {
+ m_cache.docs.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.docs;
+ }
+ TemplateVariant inherited() const
+ {
+ return FALSE;
+ }
+ private:
+ Definition *m_def;
+ QCString m_relPath;
+ const MemberGroup *m_memberGroup;
+ struct Cachable
+ {
+ SharedPtr<MemberListContext> memberListContext;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ ScopedPtr<TemplateVariant> docs;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+MemberGroupInfoContext::MemberGroupInfoContext(Definition *def,
+ const QCString &relPath,const MemberGroup *mg) : RefCountedContext("MemberGroupInfoContext")
+{
+ p = new Private(def,relPath,mg);
+}
+
+MemberGroupInfoContext::~MemberGroupInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant MemberGroupInfoContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list MemberGroupList[MemberGroupInfo] : list of member groups
+class MemberGroupListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addMemberGroup(Definition *def,const QCString &relPath,const MemberGroup *mg)
+ {
+ append(MemberGroupInfoContext::alloc(def,relPath,mg));
+ }
+};
+
+MemberGroupListContext::MemberGroupListContext() : RefCountedContext("MemberGroupListContext")
+{
+ p = new Private;
+}
+
+MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupList *list) : RefCountedContext("MemberGroupListContext")
+{
+ p = new Private;
+ if (list)
+ {
+ MemberGroupListIterator mgli(*list);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ p->addMemberGroup(def,relPath,mg);
+ }
+ }
+}
+
+MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) : RefCountedContext("MemberGroupListContext")
+{
+ p = new Private;
+ if (dict)
+ {
+ MemberGroupSDict::Iterator di(*dict);
+ const MemberGroup *mg;
+ for (di.toFirst();(mg=di.current());++di)
+ {
+ if (!mg->allMembersInSameSection() || !subGrouping)
+ {
+ p->addMemberGroup(def,relPath,mg);
+ }
+ }
+ }
+}
+
+MemberGroupListContext::~MemberGroupListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int MemberGroupListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant MemberGroupListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *MemberGroupListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+
+//------------------------------------------------------------------------
+
+//%% struct MemberListInfo: member list information
+//%% {
+class MemberListInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) :
+ m_def(def),
+ m_memberList(ml),
+ m_relPath(relPath),
+ m_title(title),
+ m_subtitle(subtitle)
+ {
+ addProperty("members", this,&Private::members);
+ addProperty("title", this,&Private::title);
+ addProperty("subtitle", this,&Private::subtitle);
+ addProperty("anchor", this,&Private::anchor);
+ addProperty("memberGroups", this,&Private::memberGroups);
+ addProperty("inherited", this,&Private::inherited);
+ }
+ TemplateVariant members() const
+ {
+ if (!m_cache.memberListContext)
+ {
+ m_cache.memberListContext.reset(MemberListContext::alloc(m_memberList));
+ }
+ return m_cache.memberListContext.get();
+ }
+ TemplateVariant title() const
+ {
+ return m_title;
+ }
+ TemplateVariant subtitle() const
+ {
+ return m_subtitle;
+ }
+ TemplateVariant anchor() const
+ {
+ return MemberList::listTypeAsString(m_memberList->listType());
+ }
+ TemplateVariant memberGroups() const
+ {
+ if (!m_cache.memberGroups)
+ {
+ m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,m_memberList->getMemberGroupList()));
+ }
+ return m_cache.memberGroups.get();
+ }
+ TemplateVariant inherited() const
+ {
+ if (!m_cache.inherited && (m_memberList->listType()&MemberListType_detailedLists)==0 &&
+ m_def->definitionType()==Definition::TypeClass)
+ {
+ InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc();
+ ctx->addMemberList((ClassDef*)m_def,m_memberList->listType(),m_title,FALSE);
+ m_cache.inherited.reset(ctx);
+ }
+ if (m_cache.inherited)
+ {
+ return m_cache.inherited.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ private:
+ Definition *m_def;
+ const MemberList *m_memberList;
+ QCString m_relPath;
+ QCString m_title;
+ QCString m_subtitle;
+ struct Cachable
+ {
+ SharedPtr<MemberListContext> memberListContext;
+ SharedPtr<MemberGroupListContext> memberGroups;
+ SharedPtr<InheritedMemberInfoListContext> inherited;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+MemberListInfoContext::MemberListInfoContext(
+ Definition *def,const QCString &relPath,const MemberList *ml,
+ const QCString &title,const QCString &subtitle) : RefCountedContext("MemberListInfoContext")
+{
+ p = new Private(def,relPath,ml,title,subtitle);
+}
+
+MemberListInfoContext::~MemberListInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant MemberListInfoContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% struct InheritedMemberInfo: inherited member information
+//%% {
+class InheritedMemberInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(ClassDef *cd,MemberList *ml,const QCString &title)
+ : m_class(cd), m_memberList(ml), m_title(title)
+ {
+ addProperty("class", this,&Private::getClass);
+ addProperty("title", this,&Private::title);
+ addProperty("members", this,&Private::members);
+ addProperty("id", this,&Private::id);
+ addProperty("inheritedFrom", this,&Private::inheritedFrom);
+ }
+ virtual ~Private()
+ {
+ delete m_memberList;
+ }
+ TemplateVariant getClass() const
+ {
+ if (!m_classCtx)
+ {
+ m_classCtx.reset(ClassContext::alloc(m_class));
+ }
+ return m_classCtx.get();
+ }
+ TemplateVariant title() const
+ {
+ return m_title;
+ }
+ TemplateVariant members() const
+ {
+ if (!m_memberListCtx)
+ {
+ m_memberListCtx.reset(MemberListContext::alloc(m_memberList));
+ }
+ return m_memberListCtx.get();
+ }
+ TemplateVariant id() const
+ {
+ return substitute(MemberList::listTypeAsString(m_memberList->listType()),"-","_")+"_"+
+ stripPath(m_class->getOutputFileBase());
+ }
+ TemplateVariant inheritedFrom() const
+ {
+ if (!m_inheritedFrom)
+ {
+ m_inheritedFrom.reset(TemplateList::alloc());
+ m_inheritedFrom->append(title());
+ m_inheritedFrom->append(getClass());
+ }
+ return m_inheritedFrom.get();
+ }
+
+ private:
+ ClassDef * m_class;
+ MemberList *m_memberList;
+ QCString m_title;
+ mutable SharedPtr<ClassContext> m_classCtx;
+ mutable SharedPtr<MemberListContext> m_memberListCtx;
+ mutable SharedPtr<TemplateList> m_inheritedFrom;
+};
+//%% }
+
+InheritedMemberInfoContext::InheritedMemberInfoContext(ClassDef *cd,MemberList *ml,
+ const QCString &title) : RefCountedContext("InheritedMemberInfoContext")
+{
+ p = new Private(cd,ml,title);
+}
+
+InheritedMemberInfoContext::~InheritedMemberInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant InheritedMemberInfoContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list InheritedMemberList[InheritedMemberInfo] : list of inherited classes
+class InheritedMemberInfoListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addMemberList(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList)
+ {
+ if (ml)
+ {
+ MemberListIterator li(*ml);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ if (md->isBriefSectionVisible() && !md->isReimplementedBy(inheritedFrom))
+ {
+ combinedList->append(md);
+ }
+ }
+ }
+ }
+ void addMemberListIncludingGrouped(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList)
+ {
+ if (ml)
+ {
+ addMemberList(inheritedFrom,ml,combinedList);
+ if (ml->getMemberGroupList())
+ {
+ MemberGroupListIterator mgli(*ml->getMemberGroupList());
+ MemberGroup *mg;
+ for (mgli.toFirst();(mg=mgli.current());++mgli)
+ {
+ addMemberList(inheritedFrom,mg->members(),combinedList);
+ }
+ }
+ }
+ }
+ void addMemberGroupsOfClass(ClassDef *inheritedFrom,
+ ClassDef *cd,MemberListType lt,MemberList *combinedList)
+ {
+ if (cd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (mg->members() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section
+ {
+ MemberListIterator li(*mg->members());
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ if (lt==md->getSectionList(mg->parent())->listType() &&
+ !md->isReimplementedBy(inheritedFrom) &&
+ md->isBriefSectionVisible())
+ {
+ combinedList->append(md);
+ }
+ }
+ }
+ }
+ }
+ }
+ void addInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt,
+ MemberListType lt1,int lt2,const QCString &title,bool additionalList)
+ {
+ int count = cd->countMembersIncludingGrouped(lt1,inheritedFrom,additionalList);
+ if (lt2!=-1) count += cd->countMembersIncludingGrouped((MemberListType)lt2,inheritedFrom,additionalList);
+ if (count>0)
+ {
+ MemberList *ml = cd->getMemberList(lt1);
+ MemberList *ml2 = lt2!=-1 ? cd->getMemberList((MemberListType)lt2) : 0;
+ MemberList *combinedList = new MemberList(lt);
+ addMemberListIncludingGrouped(inheritedFrom,ml,combinedList);
+ addMemberListIncludingGrouped(inheritedFrom,ml2,combinedList);
+ addMemberGroupsOfClass(inheritedFrom,cd,lt,combinedList);
+ if (lt2!=-1) addMemberGroupsOfClass(inheritedFrom,cd,(MemberListType)lt2,combinedList);
+ append(InheritedMemberInfoContext::alloc(cd,combinedList,title));
+ }
+ }
+ void findInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt,
+ int lt2, const QCString &title,bool additionalList,
+ QPtrDict<void> *visitedClasses)
+ {
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator it(*cd->baseClasses());
+ BaseClassDef *ibcd;
+ for (it.toFirst();(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if (icd->isLinkable())
+ {
+ int lt1,lt3;
+ convertProtectionLevel(lt,ibcd->prot,<1,<3);
+ if (lt2==-1 && lt3!=-1)
+ {
+ lt2=lt3;
+ }
+ if (visitedClasses->find(icd)==0)
+ {
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
+ {
+ // add member info for members of cd with list type lt
+ addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList);
+ // recurse down the inheritance tree
+ findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses);
+ }
+ }
+ }
+ }
+ }
+ }
+};
+
+InheritedMemberInfoListContext::InheritedMemberInfoListContext() : RefCountedContext("InheritedMemberInfoListContext")
+{
+ p = new Private;
+}
+
+void InheritedMemberInfoListContext::addMemberList(
+ ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList)
+{
+ QPtrDict<void> visited(17);
+ bool memberInSection = cd->countMembersIncludingGrouped(lt,cd,FALSE)>0;
+ bool show = (additionalList && !memberInSection) || // inherited member to show in the additional inherited members list
+ (!additionalList && memberInSection); // inherited member to show in a member list of the class
+ //printf("%s:%s show=%d\n",cd->name().data(),MemberList::listTypeAsString(lt).data(),show);
+ if (show)
+ {
+ p->findInheritedMembers(cd,cd,lt,-1,title,additionalList,&visited);
+ }
+}
+
+InheritedMemberInfoListContext::~InheritedMemberInfoListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int InheritedMemberInfoListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant InheritedMemberInfoListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *InheritedMemberInfoListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+//%% struct Argument: parameter information
+//%% {
+class ArgumentContext::Private : public PropertyMapper
+{
+ public:
+ Private(const Argument *arg,Definition *def,const QCString &relPath) :
+ m_argument(arg), m_def(def), m_relPath(relPath)
+ {
+ addProperty("type", this,&Private::type);
+ addProperty("name", this,&Private::name);
+ addProperty("defVal", this,&Private::defVal);
+ addProperty("docs", this,&Private::docs);
+ addProperty("attrib", this,&Private::attrib);
+ addProperty("array", this,&Private::array);
+ addProperty("namePart", this,&Private::namePart);
+ }
+ TemplateVariant type() const
+ {
+ return createLinkedText(m_def,m_relPath,m_argument->type);
+ }
+ TemplateVariant attrib() const
+ {
+ return m_argument->attrib;
+ }
+ TemplateVariant name() const
+ {
+ return m_argument->name;
+ }
+ TemplateVariant defVal() const
+ {
+ return createLinkedText(m_def,m_relPath,m_argument->defval);
+ }
+ TemplateVariant array() const
+ {
+ return m_argument->array;
+ }
+ TemplateVariant docs() const
+ {
+ if (!m_cache.docs && m_def)
+ {
+ if (!m_argument->docs.isEmpty())
+ {
+ m_cache.docs.reset(new TemplateVariant(
+ parseDoc(m_def,m_def->docFile(),m_def->docLine(),
+ m_relPath,m_argument->docs,TRUE)));
+ }
+ else
+ {
+ m_cache.docs.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.docs;
+ }
+ TemplateVariant namePart() const
+ {
+ QCString result = m_argument->attrib;
+ int l = result.length();
+ if (l>2 && result.at(0)=='[' && result.at(l-1)==']')
+ {
+ result = result.mid(1,l-2);
+ if (result!=",") result+=":"; // for normal keywords add colon
+ }
+ return result;
+ }
+ private:
+ const Argument *m_argument;
+ Definition *m_def;
+ QCString m_relPath;
+ struct Cachable
+ {
+ ScopedPtr<TemplateVariant> docs;
+ };
+ mutable Cachable m_cache;
+};
+//%% }
+
+ArgumentContext::ArgumentContext(const Argument *al,Definition *def,const QCString &relPath) : RefCountedContext("ArgumentContext")
+{
+ p = new Private(al,def,relPath);
+}
+
+ArgumentContext::~ArgumentContext()
+{
+ delete p;
+}
+
+TemplateVariant ArgumentContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+//------------------------------------------------------------------------
+
+//%% list ArgumentList[Argument] : list of inherited classes
+class ArgumentListContext::Private : public GenericNodeListContext
+{
+ public:
+ void addArgument(const Argument *arg,Definition *def,const QCString &relPath)
+ {
+ append(ArgumentContext::alloc(arg,def,relPath));
+ }
+};
+
+ArgumentListContext::ArgumentListContext() : RefCountedContext("ArgumentListContext")
+{
+ p = new Private;
+}
+
+ArgumentListContext::ArgumentListContext(const ArgumentList *list,
+ Definition *def,const QCString &relPath) : RefCountedContext("ArgumentListContext")
+{
+ p = new Private;
+ if (list)
+ {
+ ArgumentListIterator ali(*list);
+ const Argument *arg;
+ for (ali.toFirst();(arg=ali.current());++ali)
+ {
+ p->addArgument(arg,def,relPath);
+ }
+ }
+}
+
+ArgumentListContext::~ArgumentListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int ArgumentListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant ArgumentListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
+class HtmlEscaper : public TemplateEscapeIntf
+{
+ public:
+ QCString escape(const QCString &s)
+ {
+ return convertToHtml(s,TRUE);
+ }
+};
+
+//------------------------------------------------------------------------
+
+class HtmlSpaceless : public TemplateSpacelessIntf
+{
+ public:
+ HtmlSpaceless() { reset(); }
+ void reset()
+ {
+ m_insideTag = FALSE;
+ m_insideString = '\0';
+ m_removeSpaces = TRUE;
+ }
+ QCString remove(const QCString &s)
+ {
+ QGString result;
+ const char *p = s.data();
+ char c;
+ while ((c=*p++))
+ {
+ switch(c)
+ {
+ case '<': // start of a tag
+ if (!m_insideString) m_insideTag=TRUE,m_removeSpaces=FALSE;
+ result+=c;
+ break;
+ case '>': // end of a tag
+ if (!m_insideString) m_insideTag=FALSE,m_removeSpaces=TRUE;
+ result+=c;
+ break;
+ case '\\': // escaped character in a string
+ result+=c;
+ if (m_insideString && *p) result+=*p++;
+ break;
+ case '"': case '\'':
+ if (m_insideTag)
+ {
+ if (m_insideString==c) // end of string
+ {
+ m_insideString='\0';
+ }
+ else // start of string
+ {
+ m_insideString=c;
+ }
+ }
+ result+=c;
+ break;
+ case ' ': case '\t': case '\n': // whitespace
+ if (!m_insideTag) // outside tags strip consecutive whitespace
+ {
+ m_removeSpaces=TRUE;
+ }
+ else
+ {
+ result+=' ';
+ }
+ break;
+ default:
+ //if (m_removeSpaces) result+=' ';
+ result+=c;
+ m_removeSpaces=FALSE;
+ break;
+ }
+ }
+ result+='\0';
+ //printf("HtmlSpaceless::remove({%s})={%s} m_insideTag=%d m_insideString=%d removeSpaces=%d\n",s.data(),result.data(),
+ // m_insideTag,m_insideString,m_removeSpaces);
+ return result.data();
+ }
+ private:
+ bool m_insideTag;
+ char m_insideString;
+ bool m_removeSpaces;
+};
+
+//------------------------------------------------------------------------
+
+#if DEBUG_REF
+int RefCountedContext::s_totalCount;
+#endif
+
+void generateOutputViaTemplate()
+{
+ {
+ TemplateEngine e;
+ TemplateContext *ctx = e.createContext();
+ if (ctx)
+ {
+ SharedPtr<DoxygenContext> doxygen (DoxygenContext::alloc());
+ SharedPtr<ConfigContext> config (ConfigContext::alloc());
+ SharedPtr<TranslateContext> tr (TranslateContext::alloc());
+ SharedPtr<ClassListContext> classList (ClassListContext::alloc());
+ SharedPtr<ClassIndexContext> classIndex (ClassIndexContext::alloc());
+ SharedPtr<ClassTreeContext> classTree (ClassTreeContext::alloc());
+ SharedPtr<ClassHierarchyContext> classHierarchy (ClassHierarchyContext::alloc());
+ SharedPtr<NamespaceListContext> namespaceList (NamespaceListContext::alloc());
+ SharedPtr<NamespaceTreeContext> namespaceTree (NamespaceTreeContext::alloc());
+ SharedPtr<DirListContext> dirList (DirListContext::alloc());
+ SharedPtr<FileListContext> fileList (FileListContext::alloc());
+ SharedPtr<FileTreeContext> fileTree (FileTreeContext::alloc());
+ SharedPtr<PageTreeContext> pageTree (PageTreeContext::alloc());
+ SharedPtr<PageListContext> pageList (PageListContext::alloc(Doxygen::pageSDict));
+ SharedPtr<ExampleListContext> exampleList (ExampleListContext::alloc());
+ SharedPtr<ModuleTreeContext> moduleTree (ModuleTreeContext::alloc());
+ SharedPtr<ModuleListContext> moduleList (ModuleListContext::alloc());
+ SharedPtr<PageContext> mainPage (PageContext::alloc(Doxygen::mainPage,TRUE));
+ SharedPtr<GlobalsIndexContext> globalsIndex (GlobalsIndexContext::alloc());
+ SharedPtr<ClassMembersIndexContext> classMembersIndex (ClassMembersIndexContext::alloc());
+ SharedPtr<NamespaceMembersIndexContext> namespaceMembersIndex(NamespaceMembersIndexContext::alloc());
+
+ //%% Doxygen doxygen:
+ ctx->set("doxygen",doxygen.get());
+ //%% Translator tr:
+ ctx->set("tr",tr.get());
+ //%% Config config:
+ ctx->set("config",config.get());
+ //%% ClassList classList:
+ ctx->set("classList",classList.get()); // not used for standard HTML
+ //%% ClassTree classTree:
+ ctx->set("classTree",classTree.get());
+ //%% ClassIndex classIndex:
+ ctx->set("classIndex",classIndex.get());
+ //%% ClassHierarchy classHierarchy:
+ ctx->set("classHierarchy",classHierarchy.get());
+ //%% NamespaceList namespaceList:
+ ctx->set("namespaceList",namespaceList.get());
+ //%% NamespaceTree namespaceTree:
+ ctx->set("namespaceTree",namespaceTree.get());
+ //%% FileList fileList:
+ ctx->set("fileList",fileList.get());
+ //%% FileTree fileTree:
+ ctx->set("fileTree",fileTree.get());
+ //%% PageList pageList
+ ctx->set("pageList",pageList.get());
+ //%% PageTree pageTree
+ ctx->set("pageTree",pageTree.get());
+ //%% ExampleList exampleList
+ ctx->set("exampleList",exampleList.get());
+ //%% ModuleTree moduleTree
+ ctx->set("moduleTree",moduleTree.get());
+ //%% ModuleList moduleList
+ ctx->set("moduleList",moduleList.get());
+ //%% DirList dirList
+ ctx->set("dirList",dirList.get());
+ //%% Page mainPage
+ ctx->set("mainPage",mainPage.get());
+ //%% GlobalsIndex globalsIndex:
+ ctx->set("globalsIndex",globalsIndex.get());
+ //%% ClassMembersIndex classMembersIndex:
+ ctx->set("classMembersIndex",classMembersIndex.get());
+ //%% NamespaceMembersIndex namespaceMembersIndex:
+ ctx->set("namespaceMembersIndex",namespaceMembersIndex.get());
+
+ // render HTML output
+ Template *tpl = e.loadByName("htmllayout.tpl",1);
+ if (tpl)
+ {
+ g_globals.outputFormat = ContextGlobals::Html;
+ g_globals.dynSectionId = 0;
+ g_globals.outputDir = Config_getString("HTML_OUTPUT");
+ QDir dir(g_globals.outputDir);
+ createSubDirs(dir);
+ HtmlEscaper htmlEsc;
+ ctx->setEscapeIntf(Config_getString("HTML_FILE_EXTENSION"),&htmlEsc);
+ HtmlSpaceless spl;
+ ctx->setSpacelessIntf(&spl);
+ ctx->setOutputDirectory(g_globals.outputDir);
+ FTextStream ts;
+ tpl->render(ts,ctx);
+ e.unload(tpl);
+ }
+
+ // TODO: render other outputs
+
+ e.destroyContext(ctx);
+ }
+ }
+#if DEBUG_REF // should be 0, i.e. all objects are deleted
+ printf("==== total ref count %d\n",RefCountedContext::s_totalCount);
+#endif
+}
+
diff --git a/src/context.h b/src/context.h
new file mode 100644
index 0000000..b39ab40
--- /dev/null
+++ b/src/context.h
@@ -0,0 +1,1135 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include "types.h"
+#include "template.h"
+#include <qlist.h>
+#include <stdio.h>
+
+class Definition;
+class ClassDef;
+class ClassSDict;
+class BaseClassList;
+class PageDef;
+class GroupDef;
+class NamespaceDef;
+class BaseClassList;
+class NamespaceSDict;
+class FileDef;
+class FileList;
+class FileNameList;
+class DirSDict;
+class DirList;
+class DirDef;
+class PageSDict;
+class GroupSDict;
+class GroupDef;
+class GroupList;
+struct IncludeInfo;
+class MemberList;
+class MemberSDict;
+class MemberDef;
+struct Argument;
+class ArgumentList;
+class MemberNameInfoSDict;
+struct MemberInfo;
+class MemberGroup;
+class MemberGroupSDict;
+class MemberGroupList;
+
+//----------------------------------------------------
+
+#define DEBUG_REF 0
+
+/** @brief Helper class to support reference counting */
+#if DEBUG_REF
+class RefCountedContext
+{
+ public:
+ RefCountedContext(const char *className) : m_refCount(0)
+ {
+ m_className=className;
+ m_insideRelease = FALSE;
+ }
+ ~RefCountedContext()
+ {
+ if (!m_insideRelease) abort();
+ }
+ int addRef()
+ {
+ ++s_totalCount;
+ printf("%p:%s::addRef()=%d\n",this,m_className.data(),m_refCount);
+ return ++m_refCount;
+ }
+ int release()
+ {
+ --s_totalCount;
+ printf("%p:%s::release()=%d\n",this,m_className.data(),m_refCount-1);
+ int count = --m_refCount;
+ if (count<=0)
+ {
+ m_insideRelease=TRUE;
+ delete this;
+ }
+ return count;
+ }
+ private:
+ int m_refCount;
+ QCString m_className;
+ bool m_insideRelease;
+ public:
+ static int s_totalCount;
+};
+
+#else // release version
+
+class RefCountedContext
+{
+ public:
+ RefCountedContext(const char *) : m_refCount(0) {}
+ virtual ~RefCountedContext() {}
+ int addRef() { return ++m_refCount; }
+ int release()
+ {
+ int count = --m_refCount;
+ if (count<=0)
+ {
+ delete this;
+ }
+ return count;
+ }
+ private:
+ int m_refCount;
+};
+#endif
+
+
+//----------------------------------------------------
+
+class ConfigContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ConfigContext *alloc() { return new ConfigContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ConfigContext();
+ ~ConfigContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class DoxygenContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static DoxygenContext *alloc() { return new DoxygenContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ DoxygenContext();
+ ~DoxygenContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class TranslateContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static TranslateContext *alloc() { return new TranslateContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ TranslateContext();
+ ~TranslateContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class UsedFilesContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static UsedFilesContext *alloc(ClassDef *cd) { return new UsedFilesContext(cd); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ void addFile(FileDef *fd);
+
+ private:
+ UsedFilesContext(ClassDef *cd);
+ ~UsedFilesContext();
+
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class IncludeInfoContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static IncludeInfoContext *alloc(const IncludeInfo *info,SrcLangExt lang)
+ { return new IncludeInfoContext(info,lang); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ IncludeInfoContext(const IncludeInfo *,SrcLangExt lang);
+ ~IncludeInfoContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class IncludeInfoListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static IncludeInfoListContext *alloc(const QList<IncludeInfo> &list,SrcLangExt lang)
+ { return new IncludeInfoListContext(list,lang); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ IncludeInfoListContext(const QList<IncludeInfo> &list,SrcLangExt lang);
+ ~IncludeInfoListContext();
+ class Private;
+ Private *p;
+};
+
+
+//----------------------------------------------------
+
+class ClassContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassContext *alloc(ClassDef *cd) { return new ClassContext(cd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassContext(ClassDef *);
+ ~ClassContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NamespaceContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static NamespaceContext *alloc(NamespaceDef *nd) { return new NamespaceContext(nd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NamespaceContext(NamespaceDef *);
+ ~NamespaceContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class FileContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static FileContext *alloc(FileDef *fd) { return new FileContext(fd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ FileContext(FileDef *);
+ ~FileContext();
+ class Private;
+ Private *p;
+};
+//----------------------------------------------------
+
+class DirContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static DirContext *alloc(DirDef *dd) { return new DirContext(dd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ DirContext(DirDef *);
+ ~DirContext();
+ class Private;
+ Private *p;
+};
+
+
+//----------------------------------------------------
+
+class PageContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static PageContext *alloc(PageDef *pd,bool isMainPage=FALSE) { return new PageContext(pd,isMainPage); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ PageContext(PageDef *,bool isMainPage);
+ ~PageContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class MemberContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static MemberContext *alloc(MemberDef *md) { return new MemberContext(md); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberContext(MemberDef *);
+ ~MemberContext();
+ class Private;
+ Private *p;
+};
+
+
+//----------------------------------------------------
+
+class ModuleContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ModuleContext *alloc(GroupDef *gd) { return new ModuleContext(gd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ModuleContext(GroupDef *);
+ ~ModuleContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static ClassListContext *alloc() { return new ClassListContext; }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassListContext();
+ ~ClassListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassIndexContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassIndexContext *alloc() { return new ClassIndexContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassIndexContext();
+ ~ClassIndexContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassInheritanceNodeContext *alloc(ClassDef *cd)
+ { return new ClassInheritanceNodeContext(cd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ void addChildren(const BaseClassList *bcl,bool hideSuper);
+
+ private:
+ ClassInheritanceNodeContext(ClassDef *);
+ ~ClassInheritanceNodeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassInheritanceContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static ClassInheritanceContext *alloc() { return new ClassInheritanceContext; }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassInheritanceContext();
+ ~ClassInheritanceContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassHierarchyContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassHierarchyContext *alloc() { return new ClassHierarchyContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassHierarchyContext();
+ ~ClassHierarchyContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NestingNodeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static NestingNodeContext *alloc(const NestingNodeContext *parent,Definition *def,
+ int index,int level,bool addClasses)
+ { return new NestingNodeContext(parent,def,index,level,addClasses); }
+
+ QCString id() const;
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NestingNodeContext(const NestingNodeContext *parent,
+ Definition *,int index,int level,bool addClasses);
+ ~NestingNodeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NestingContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static NestingContext *alloc(const NestingNodeContext *parent,int level)
+ { return new NestingContext(parent,level); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ void addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses);
+ void addClasses(const ClassSDict &clDict,bool rootOnly);
+ void addDirs(const DirSDict &);
+ void addDirs(const DirList &);
+ void addFiles(const FileNameList &);
+ void addFiles(const FileList &);
+ void addPages(const PageSDict &pages,bool rootOnly);
+ void addModules(const GroupSDict &modules);
+ void addModules(const GroupList &modules);
+
+ private:
+ NestingContext(const NestingNodeContext *parent,int level);
+ ~NestingContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassTreeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassTreeContext *alloc() { return new ClassTreeContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassTreeContext();
+ ~ClassTreeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NamespaceListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static NamespaceListContext *alloc() { return new NamespaceListContext; }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NamespaceListContext();
+ ~NamespaceListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NamespaceTreeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static NamespaceTreeContext *alloc() { return new NamespaceTreeContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NamespaceTreeContext();
+ ~NamespaceTreeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class DirListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static DirListContext *alloc() { return new DirListContext; }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ DirListContext();
+ ~DirListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class FileListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static FileListContext *alloc() { return new FileListContext; }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ FileListContext();
+ ~FileListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class FileTreeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static FileTreeContext *alloc() { return new FileTreeContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ FileTreeContext();
+ ~FileTreeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class PageListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static PageListContext *alloc(const PageSDict *pages) { return new PageListContext(pages); }
+
+ // TemplateListIntf methods
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ void addPages(const PageSDict &pages);
+
+ private:
+ PageListContext(const PageSDict *pages);
+ ~PageListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class PageTreeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static PageTreeContext *alloc() { return new PageTreeContext; }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ PageTreeContext();
+ ~PageTreeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ModuleNodeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ModuleNodeContext *alloc(GroupDef *gd) { return new ModuleNodeContext(gd); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ModuleNodeContext(GroupDef *);
+ ~ModuleNodeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ModuleListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static ModuleListContext *alloc() { return new ModuleListContext(); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ void addModules(const GroupSDict &);
+ void addModules(const GroupList &);
+
+ private:
+ ModuleListContext();
+ ~ModuleListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ModuleTreeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ModuleTreeContext *alloc() { return new ModuleTreeContext(); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ModuleTreeContext();
+ ~ModuleTreeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ExampleListContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ExampleListContext *alloc() { return new ExampleListContext(); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ExampleListContext();
+ ~ExampleListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class GlobalsIndexContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static GlobalsIndexContext *alloc() { return new GlobalsIndexContext(); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ GlobalsIndexContext();
+ ~GlobalsIndexContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ClassMembersIndexContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ClassMembersIndexContext *alloc() { return new ClassMembersIndexContext(); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ClassMembersIndexContext();
+ ~ClassMembersIndexContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NamespaceMembersIndexContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static NamespaceMembersIndexContext *alloc() { return new NamespaceMembersIndexContext(); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NamespaceMembersIndexContext();
+ ~NamespaceMembersIndexContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class NavPathElemContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static NavPathElemContext *alloc(Definition *def) { return new NavPathElemContext(def); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ NavPathElemContext(Definition *def);
+ ~NavPathElemContext();
+ class Private;
+ Private *p;
+};
+
+
+//----------------------------------------------------
+
+class InheritanceNodeContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static InheritanceNodeContext *alloc(ClassDef *cd,const QCString &name)
+ { return new InheritanceNodeContext(cd,name); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ InheritanceNodeContext(ClassDef *cd,const QCString &name);
+ ~InheritanceNodeContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class InheritanceListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static InheritanceListContext *alloc(const BaseClassList *list,bool baseClasses)
+ { return new InheritanceListContext(list,baseClasses); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ InheritanceListContext(const BaseClassList *list,bool baseClasses);
+ ~InheritanceListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class MemberListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static MemberListContext *alloc()
+ { return new MemberListContext; }
+ static MemberListContext *alloc(const MemberList *ml)
+ { return new MemberListContext(ml); }
+ static MemberListContext *alloc(MemberSDict *ml,bool doSort)
+ { return new MemberListContext(ml,doSort); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberListContext();
+ MemberListContext(const MemberList *ml);
+ MemberListContext(MemberSDict *ml,bool doSort);
+ ~MemberListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class MemberGroupInfoContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static MemberGroupInfoContext *alloc(Definition *def,const QCString &relPath,const MemberGroup *mg)
+ { return new MemberGroupInfoContext(def,relPath,mg); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberGroupInfoContext(Definition *def,const QCString &relPath,const MemberGroup *mg);
+ ~MemberGroupInfoContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class MemberGroupListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static MemberGroupListContext *alloc()
+ { return new MemberGroupListContext; }
+ static MemberGroupListContext *alloc(Definition *def,const QCString &relPath,const MemberGroupList *list)
+ { return new MemberGroupListContext(def,relPath,list); }
+ static MemberGroupListContext *alloc(Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping)
+ { return new MemberGroupListContext(def,relPath,dict,subGrouping); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberGroupListContext();
+ MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupList *list);
+ MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupSDict *mgDict,bool subGrouping);
+ ~MemberGroupListContext();
+ class Private;
+ Private *p;
+};
+
+
+//----------------------------------------------------
+
+class MemberListInfoContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static MemberListInfoContext *alloc(Definition *def,const QCString &relPath,
+ const MemberList *ml,const QCString &title,
+ const QCString &subtitle=QCString())
+ { return new MemberListInfoContext(def,relPath,ml,title,subtitle); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberListInfoContext(Definition *def,const QCString &relPath,
+ const MemberList *ml,const QCString &title,
+ const QCString &subtitle=QCString());
+ ~MemberListInfoContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class MemberInfoContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static MemberInfoContext *alloc(const MemberInfo *mi) { return new MemberInfoContext(mi); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ MemberInfoContext(const MemberInfo *mi);
+ ~MemberInfoContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class InheritedMemberInfoContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static InheritedMemberInfoContext *alloc(ClassDef *cd,MemberList *ml,const QCString &title)
+ { return new InheritedMemberInfoContext(cd,ml,title); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ InheritedMemberInfoContext(ClassDef *cd,MemberList *ml,const QCString &title);
+ ~InheritedMemberInfoContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class InheritedMemberInfoListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static InheritedMemberInfoListContext *alloc() { return new InheritedMemberInfoListContext; }
+ void addMemberList(ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE);
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ InheritedMemberInfoListContext();
+ ~InheritedMemberInfoListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class AllMembersListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static AllMembersListContext *alloc()
+ { return new AllMembersListContext; }
+ static AllMembersListContext *alloc(const MemberNameInfoSDict *ml)
+ { return new AllMembersListContext(ml); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ AllMembersListContext();
+ AllMembersListContext(const MemberNameInfoSDict *ml);
+ ~AllMembersListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ArgumentContext : public RefCountedContext, public TemplateStructIntf
+{
+ public:
+ static ArgumentContext *alloc(const Argument *arg,Definition *def,const QCString &relPath)
+ { return new ArgumentContext(arg,def,relPath); }
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ArgumentContext(const Argument *arg,Definition *def,const QCString &relPath);
+ ~ArgumentContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class ArgumentListContext : public RefCountedContext, public TemplateListIntf
+{
+ public:
+ static ArgumentListContext *alloc() { return new ArgumentListContext; }
+ static ArgumentListContext *alloc(const ArgumentList *al,Definition *def,const QCString &relPath)
+ { return new ArgumentListContext(al,def,relPath); }
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef() { return RefCountedContext::addRef(); }
+ virtual int release() { return RefCountedContext::release(); }
+
+ private:
+ ArgumentListContext();
+ ArgumentListContext(const ArgumentList *al,Definition *def,const QCString &relPath);
+ ~ArgumentListContext();
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+void generateOutputViaTemplate();
+
+#endif
diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp
new file mode 100644
index 0000000..a99ec56
--- /dev/null
+++ b/src/cppvalue.cpp
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "cppvalue.h"
+#include "constexp.h"
+
+CPPValue parseOctal()
+{
+ long val = 0;
+ for (const char *p = g_strToken.data(); *p != 0; p++)
+ {
+ if (*p >= '0' && *p <= '7') val = val * 8 + *p - '0';
+ }
+ return CPPValue(val);
+}
+
+CPPValue parseDecimal()
+{
+ long val = 0;
+ for (const char *p = g_strToken.data(); *p != 0; p++)
+ {
+ if (*p >= '0' && *p <= '9') val = val * 10 + *p - '0';
+ }
+ return CPPValue(val);
+}
+
+CPPValue parseHexadecimal()
+{
+ long val = 0;
+ for (const char *p = g_strToken.data(); *p != 0; p++)
+ {
+ if (*p >= '0' && *p <= '9') val = val * 16 + *p - '0';
+ else if (*p >= 'a' && *p <= 'f') val = val * 16 + *p - 'a' + 10;
+ else if (*p >= 'A' && *p <= 'F') val = val * 16 + *p - 'A' + 10;
+ }
+ //printf("parseHexadecimal %s->%x\n",g_strToken.data(),val);
+ return CPPValue(val);
+}
+
+CPPValue parseCharacter() // does not work for '\n' and the alike
+{
+ if (g_strToken[1]=='\\')
+ {
+ switch(g_strToken[2])
+ {
+ case 'n': return CPPValue((long)'\n');
+ case 't': return CPPValue((long)'\t');
+ case 'v': return CPPValue((long)'\v');
+ case 'b': return CPPValue((long)'\b');
+ case 'r': return CPPValue((long)'\r');
+ case 'f': return CPPValue((long)'\f');
+ case 'a': return CPPValue((long)'\a');
+ case '\\': return CPPValue((long)'\\');
+ case '?': return CPPValue((long)'\?');
+ case '\'': return CPPValue((long)'\'');
+ case '"': return CPPValue((long)'"');
+ case '0': // fall through
+ case '1': // fall through
+ case '2': // fall through
+ case '3': // fall through
+ case '4': // fall through
+ case '5': // fall through
+ case '6': // fall through
+ case '7': // fall through
+ return parseOctal();
+ case 'x':
+ case 'X': return parseHexadecimal();
+ default: printf("Invalid escape sequence %s found!\n",g_strToken.data());
+ return CPPValue(0L);
+ }
+ }
+ return CPPValue((long)g_strToken[1]);
+}
+
+CPPValue parseFloat()
+{
+ return CPPValue(atof(g_strToken));
+}
diff --git a/src/cppvalue.h b/src/cppvalue.h
new file mode 100644
index 0000000..67c5433
--- /dev/null
+++ b/src/cppvalue.h
@@ -0,0 +1,61 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _CPPVALUE_H
+#define _CPPVALUE_H
+
+#include <stdio.h>
+#include <qglobal.h>
+
+/** A class representing a C-preprocessor value. */
+class CPPValue
+{
+ public:
+ enum Type { Int, Float };
+
+ CPPValue(long val=0) : type(Int) { v.l = val; }
+ CPPValue(double val) : type(Float) { v.d = val; }
+
+ operator double () const { return type==Int ? (double)v.l : v.d; }
+ operator long () const { return type==Int ? v.l : (long)v.d; }
+
+ bool isInt() const { return type == Int; }
+
+ void print() const
+ {
+ if (type==Int)
+ printf("(%ld)\n",v.l);
+ else
+ printf("(%f)\n",v.d);
+ }
+
+ private:
+ Type type;
+ union {
+ double d;
+ long l;
+ } v;
+};
+
+extern CPPValue parseOctal();
+extern CPPValue parseDecimal();
+extern CPPValue parseHexadecimal();
+extern CPPValue parseCharacter();
+extern CPPValue parseFloat();
+
+#endif
diff --git a/src/dbusxmlscanner.cpp b/src/dbusxmlscanner.cpp
new file mode 100644
index 0000000..e841428
--- /dev/null
+++ b/src/dbusxmlscanner.cpp
@@ -0,0 +1,881 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 2009 by Tobias Hunger <tobias at aquazul.com>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "dbusxmlscanner.h"
+
+#include "commentscan.h"
+#include "entry.h"
+
+#include <qfile.h>
+#include <qxml.h>
+#include <qstring.h>
+
+#include "message.h"
+#include "util.h"
+#include "arguments.h"
+
+// -----------------------------------------------------------------------
+// Convenience defines:
+// -----------------------------------------------------------------------
+
+#define CONDITION(cond, msg) \
+ do {\
+ if (cond)\
+ {\
+ if (m_errorString.isEmpty()) { m_errorString = msg; }\
+ return false;\
+ }\
+ }\
+ while (0)
+
+#define DOC_ERROR(msg) \
+ warn_doc_error(m_fileName.data(), lineNumber(), msg.data())
+
+#define COND_DOC_ERROR(cond, msg) \
+ do {\
+ if (cond)\
+ {\
+ DOC_ERROR(msg);\
+ return true;\
+ }\
+ }\
+ while (0)
+
+#define DBUS(name) isDBusElement(namespaceURI, localName, qName, name)
+#define EXTENSION(name) isExtensionElement(namespaceURI, localName, qName, name)
+
+// -----------------------------------------------------------------------
+// DBusXMLHandler class
+// -----------------------------------------------------------------------
+
+const QString EXTENSION_URI("http://psiamp.org/dtd/doxygen_dbusxml.dtd");
+
+/** DBus implementation of the generic QXmlDefaultHandler. */
+class DBusXMLHandler : public QXmlDefaultHandler
+{
+public:
+ DBusXMLHandler(ParserInterface * parser,
+ QXmlSimpleReader * reader,
+ const char * file_name,
+ Entry * root) :
+ m_parser(parser),
+ m_locator(reader),
+ m_currentEntry(0),
+ m_currentInterface(0),
+ m_currentMethod(0),
+ m_currentArgument(0),
+ m_currentProperty(0),
+ m_currentEnum(0),
+ m_fileName(file_name),
+ m_currentComment(0)
+ {
+ setDocumentLocator(&m_locator);
+
+ m_scopeCount = 0;
+
+ // Set up stack cleanup:
+ m_structStack.setAutoDelete(TRUE);
+ m_elementStack.setAutoDelete(TRUE);
+ m_scopeStack.setAutoDelete(TRUE);
+
+ openScopes(root);
+ }
+
+ ~DBusXMLHandler()
+ { closeScopes(); }
+
+ QString errorString()
+ { return m_errorString; }
+
+ bool startElement(const QString &namespaceURI,
+ const QString &localName,
+ const QString &qName,
+ const QXmlAttributes &attributes)
+ {
+ // add to elements stack:
+ m_elementStack.append(new ElementData(qName.utf8()));
+
+ // First we need a node.
+ if (DBUS("node"))
+ {
+ CONDITION(!m_currentNode.isEmpty(), "Node inside a node.");
+
+ const int idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(idx < 0, QCString("Anonymous node found."));
+
+ m_currentNode = attributes.value(idx).utf8();
+ // A node is actually of little interest, so do nothing here.
+ return true;
+ }
+
+ // Then we need an interface.
+ if (DBUS("interface"))
+ {
+ // We need a nodeName for interfaces:
+ CONDITION(m_currentNode.isEmpty(), "Interface without a node.");
+ CONDITION(m_currentInterface, "Interface within another interface.");
+
+ const int idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(idx < 0, QString("Interface without a name found."));
+
+ // A interface is roughly equivalent to a class:
+ m_currentInterface = createEntry();
+
+ m_currentInterface->section = Entry::CLASS_SEC;
+ m_currentInterface->spec |= Entry::Interface;
+ m_currentInterface->type = "Interface";
+ m_currentInterface->name = substitute(attributes.value(idx).utf8(), ".", "::");
+
+ openScopes(m_currentInterface);
+
+ return true;
+ }
+
+ if (DBUS("method") || DBUS("signal"))
+ {
+ // We need a interfaceName for methods and signals:
+ CONDITION(!m_currentInterface, "Method or signal found outside a interface.");
+ CONDITION(m_currentMethod, "Method or signal found inside another method or signal.");
+ CONDITION(m_currentProperty, "Methor or signal found inside a property.");
+ CONDITION(!m_structStack.isEmpty(), "Method or signal found inside a struct.");
+ CONDITION(m_currentEnum, "Methor or signal found inside a enum.");
+
+ const int idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(idx < 0, QString("Method or signal without a name found."));
+
+ m_currentMethod = createEntry();
+
+ m_currentMethod->section = Entry::FUNCTION_SEC;
+ m_currentMethod->name = attributes.value(idx).utf8();
+ m_currentMethod->mtype = Method;
+ m_currentMethod->type = "void";
+
+ if (DBUS("signal"))
+ { m_currentMethod->mtype = Signal; }
+ }
+
+ if (DBUS("arg"))
+ {
+ // We need a method for arguments:
+ CONDITION(!m_currentMethod, "Argument found outside a method or signal.");
+ CONDITION(m_currentArgument, "Argument found inside another argument.");
+
+ const int name_idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(name_idx < 0, QString("Argument without a name found."));
+ COND_DOC_ERROR(!hasType(attributes), QString("Argument without a type found."));
+
+ const int direction_idx(indexOf(attributes, "direction"));
+
+ if ((m_currentMethod->mtype == Signal &&
+ direction_idx >= 0 &&
+ attributes.value(direction_idx) != "in") ||
+ (m_currentMethod->mtype == Method &&
+ direction_idx >= 0 &&
+ attributes.value(direction_idx) != "in" &&
+ attributes.value(direction_idx) != "out"))
+ {
+ m_errorString = "Invalid direction found.";
+ return false;
+ }
+
+ m_currentArgument = new Argument;
+ m_currentArgument->type = getType(attributes).utf8();
+ m_currentArgument->name = attributes.value(name_idx).utf8();
+ if (direction_idx >= 0)
+ { m_currentArgument->attrib = attributes.value(direction_idx).utf8(); }
+ else
+ {
+ if (m_currentMethod->mtype == Signal)
+ { m_currentArgument->attrib = "in"; }
+ else
+ { m_currentArgument->attrib = "out"; }
+ }
+ }
+
+ if (DBUS("property"))
+ {
+ CONDITION(m_currentMethod, "Property found inside a method or signal.");
+ CONDITION(!m_currentInterface, "Property found outside an interface.");
+ CONDITION(m_currentProperty, "Property found inside another property.");
+ CONDITION(!m_structStack.isEmpty(), "Property found inside a struct.");
+ CONDITION(m_currentEnum, "Property found inside a enum.");
+
+ const int name_idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(name_idx < 0, QString("Anonymous property found."));
+ COND_DOC_ERROR(!hasType(attributes), QString("Property without a type found."));
+
+ const int access_idx(indexOf(attributes, "access"));
+ COND_DOC_ERROR(access_idx < 0, QString("Property without a access attribute found."));
+ COND_DOC_ERROR(attributes.value(access_idx) != "read" &&
+ attributes.value(access_idx) != "write" &&
+ attributes.value(access_idx) != "readwrite",
+ QString("Property with invalid access attribute \"%1\" found.").
+ arg(attributes.value(access_idx)));
+
+ m_currentProperty = createEntry();
+
+ m_currentProperty->section = Entry::FUNCTION_SEC;
+
+ if (attributes.value(access_idx) == "read" ||
+ attributes.value(access_idx) == "readwrite")
+ { m_currentProperty->spec |= Entry::Readable; }
+
+ if (attributes.value(access_idx) == "write" ||
+ attributes.value(access_idx) == "readwrite")
+ { m_currentProperty->spec |= Entry::Writable; }
+
+ m_currentProperty->name = attributes.value(name_idx).utf8();
+ m_currentProperty->mtype = Property;
+ m_currentProperty->type = getType(attributes).utf8();
+ }
+
+ if (EXTENSION("namespace"))
+ {
+ CONDITION(m_currentNode.isEmpty(), "Namespace found outside a node.");
+ CONDITION(m_currentInterface, "Namespace found inside an interface.");
+
+ const int idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(idx < 0, QString("Anonymous namespace found."));
+
+ m_namespaceStack.append(openNamespace(attributes.value(idx)));
+ openScopes(m_namespaceStack.getLast());
+ }
+
+ if (EXTENSION("struct"))
+ {
+ CONDITION(m_currentMethod, "Struct found inside a method or signal.");
+ CONDITION(m_currentProperty, "Struct found inside a property.");
+ CONDITION(m_currentEnum, "Struct found inside an enum.");
+
+ const int idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(idx < 0, QString("Anonymous struct found."));
+
+ Entry * current_struct = createEntry();
+ current_struct->section = Entry::CLASS_SEC;
+ current_struct->spec = Entry::Struct;
+ current_struct->name = attributes.value(idx).utf8();
+
+ openScopes(current_struct);
+
+ current_struct->type = current_struct->name + " struct";
+
+ m_structStack.append(new StructData(current_struct));
+ }
+
+ if (EXTENSION("member"))
+ {
+ CONDITION(m_structStack.isEmpty(), "Member found outside of struct.");
+
+ const int name_idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(name_idx < 0, QString("Anonymous member found."));
+ COND_DOC_ERROR(!hasType(attributes), QString("Member without a type found."));
+
+ createEntry();
+
+ m_currentEntry->section = Entry::VARIABLE_SEC;
+ m_currentEntry->name = attributes.value(name_idx).utf8();
+ m_currentEntry->type = getType(attributes).utf8();
+
+ QString type(getDBusType(m_currentEntry->type));
+ m_structStack.getLast()->type.append(type.utf8());
+ }
+
+ if (EXTENSION("enum") || EXTENSION("flagset"))
+ {
+ CONDITION(m_currentMethod, "Enum found inside a method or signal.");
+ CONDITION(m_currentProperty, "Enum found inside a property.");
+
+ const int name_idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(name_idx < 0, QString("Anonymous enum found."));
+
+ const int type_idx(indexOf(attributes, "type"));
+ QString type = "u";
+ if (type_idx >= 0)
+ { type = attributes.value(type_idx); }
+ if (type != "y" && type != "q" && type != "u" && type != "t")
+ { DOC_ERROR(QString("Invalid enum type \"%1\" found.").arg(type)); }
+
+ m_currentEnum = createEntry();
+ m_currentEnum->section = Entry::ENUM_SEC;
+ m_currentEnum->name = attributes.value(name_idx).utf8();
+
+ openScopes(m_currentEnum);
+
+ m_currentEnum->type = m_currentEntry->name + " enum";
+
+ addNamedType(type.utf8());
+ }
+
+ if (EXTENSION("value"))
+ {
+ CONDITION(!m_currentEnum, "Value found outside an enum.");
+
+ const int name_idx(indexOf(attributes, "name"));
+ COND_DOC_ERROR(name_idx < 0, QString("Anonymous value found."));
+
+ const int value_idx(indexOf(attributes, "value"));
+
+ createEntry();
+
+ m_currentEntry->section = Entry::VARIABLE_SEC;
+ m_currentEntry->name = attributes.value(name_idx).utf8();
+ m_currentEntry->type = m_currentEnum->name; // "@"; // enum marker!
+ if (value_idx >= 0)
+ { m_currentEntry->initializer = attributes.value(value_idx).utf8(); }
+ }
+
+ return true;
+ }
+
+ bool endElement(const QString &namespaceURI,
+ const QString &localName,
+ const QString &qName)
+ {
+ // Clean up elements stack:
+ // Since we made sure to get the elements in the proper order when
+ // adding we do not need to do so again here.
+ COND_DOC_ERROR(m_elementStack.getLast()->element != qName.utf8(),
+ QString("Malformed XML: Unexpected closing element found.").
+ arg(m_elementStack.getLast()->element).utf8());
+ m_elementStack.removeLast();
+
+ // Interface:
+ if (DBUS("interface"))
+ {
+ CONDITION(!m_currentInterface, "end of interface found without start.");
+ m_currentInterface->endBodyLine = lineNumber();
+ closeScopes();
+ m_currentInterface = 0;
+ }
+
+ if (DBUS("method") || DBUS("signal"))
+ {
+ CONDITION(!m_currentMethod, "end of method found without start.");
+ CONDITION(!m_currentInterface, "end of method found outside interface.");
+ m_currentMethod->endBodyLine = lineNumber();
+ m_currentInterface->addSubEntry(m_currentMethod);
+ m_currentMethod = 0;
+ }
+
+ if (DBUS("property"))
+ {
+ CONDITION(!m_currentProperty, "end of property found without start.");
+ CONDITION(!m_currentInterface, "end of property found outside interface.");
+ m_currentProperty->endBodyLine = lineNumber();
+ m_currentInterface->addSubEntry(m_currentProperty);
+ m_currentProperty = 0;
+ }
+
+ if (DBUS("arg"))
+ {
+ CONDITION(!m_currentMethod, "end of arg found outside method.");
+ m_currentMethod->argList->append(m_currentArgument);
+ m_currentArgument = 0;
+ }
+
+ if (EXTENSION("namespace"))
+ {
+ Entry * current = m_namespaceStack.getLast();
+ CONDITION(!current, "end of namespace without start.");
+ m_namespaceStack.removeLast();
+
+ current->endBodyLine = lineNumber();
+ closeScopes();
+ }
+
+ if (EXTENSION("struct"))
+ {
+ StructData * data = m_structStack.getLast();
+ CONDITION(!data, "end of struct without start.");
+
+ data->entry->endBodyLine = lineNumber();
+
+ QString current_type;
+ current_type.append(QString("("));
+ current_type.append(data->type);
+ current_type.append(QString(")"));
+
+ addNamedType(current_type.utf8());
+
+ closeScopes();
+
+ m_structStack.removeLast();
+ }
+
+ if (EXTENSION("member"))
+ {
+ StructData * data = m_structStack.getLast();
+ CONDITION(!data, "end of member outside struct.");
+ data->entry->addSubEntry(m_currentEntry);
+ }
+
+ if (EXTENSION("enum") || EXTENSION("flagset"))
+ {
+ CONDITION(!m_currentEnum, "end of enum without start.");
+ m_currentEnum->endBodyLine = lineNumber();
+ closeScopes();
+
+ m_currentEnum = 0;
+ }
+
+ if (EXTENSION("value"))
+ {
+ CONDITION(!m_currentEntry, "end of value without start");
+ m_currentEntry->endBodyLine = lineNumber();
+
+ m_currentEnum->addSubEntry(m_currentEntry);
+ }
+
+ return true;
+ }
+
+ bool characters(const QString & /*chars*/)
+ { return true; }
+
+ bool comment(const QString & comment_)
+ {
+ if (m_currentComment)
+ { handleComment(); }
+
+ m_currentComment = new CommentData(m_fileName, lineNumber(), comment_.utf8());
+
+ if (m_currentComment->shouldIgnore)
+ {
+ delete m_currentComment;
+ m_currentComment = 0;
+ return true;
+ }
+
+ if (m_currentComment->associateWithPrevious)
+ { handleComment(); }
+
+ return true;
+ }
+
+ void handleComment()
+ {
+ if (m_currentComment == 0 || m_currentEntry == 0)
+ { return; }
+
+ QCString text(m_currentComment->text);
+
+ m_currentEntry->docFile = m_currentComment->fileName;
+ m_currentEntry->docLine = m_currentComment->line;
+
+ int position(0);
+ bool needs_entry(false);
+ bool brief(false);
+ Protection prot(Public);
+ int lineNr = lineNumber();
+
+ while (parseCommentBlock(m_parser,
+ m_currentEntry,
+ text, m_fileName.data(),
+ lineNr,
+ brief, m_currentComment->isJavaStyle,
+ false,
+ prot,
+ position,
+ needs_entry))
+ {
+ if (needs_entry) { createEntry(); }
+ }
+ if (needs_entry) { createEntry(); }
+
+ delete m_currentComment;
+ m_currentComment = 0;
+ }
+
+ QXmlLocator * locator()
+ { return &m_locator; }
+
+ int lineNumber()
+ { return m_locator.lineNumber(); }
+
+ void setSection()
+ {
+ Entry * current = createEntry();
+ current->reset();
+
+ current->name = m_fileName;
+ current->section = Entry::SOURCE_SEC;
+
+ // Open/Close the scope to do the bookkeeping:
+ openScopes(current);
+ closeScopes();
+ }
+
+private:
+ bool isDBusElement(const QString & namespaceURI,
+ const QString & localName,
+ const QString & qName,
+ const QString & element)
+ {
+ return (namespaceURI.isEmpty() && localName == element && qName == element) ||
+ (namespaceURI.isEmpty() && localName.isEmpty() && qName == element);
+ }
+
+ bool isExtensionElement(const QString & namespaceURI,
+ const QString & localName,
+ const QString & qName,
+ const QString & element)
+ {
+ (void)qName;
+
+ return namespaceURI == EXTENSION_URI && localName == element;
+ }
+
+ bool hasType(const QXmlAttributes & attributes)
+ {
+ const int type_idx(indexOf(attributes, "type"));
+ const int named_type_idx(indexOf(attributes, "named-type"));
+
+ return named_type_idx >= 0 || type_idx >= 0;
+ }
+
+ QString getType(const QXmlAttributes & attributes)
+ {
+ const int type_idx(indexOf(attributes, "type"));
+ const int named_type_idx(indexOf(attributes, "named-type"));
+
+ QCString type;
+
+ if (named_type_idx >= 0)
+ {
+ type = attributes.value(named_type_idx).utf8();
+ if (type.left(2)!="::")
+ { type = getCurrentScope(attributes.value(named_type_idx).utf8()); }
+ else
+ { type = type.mid(2); }
+ if (m_namedTypeMap.contains(type))
+ {
+ if (type_idx >= 0)
+ {
+ const QCString dbus_type(attributes.value(type_idx).utf8());
+ if (dbus_type != m_namedTypeMap[type])
+ {
+ DOC_ERROR(QString("Type \"%1\" does not match up with "
+ "previous definition of named type \"%2\" (which was \"%3\".").
+ arg(dbus_type).
+ arg(type).
+ arg(m_namedTypeMap[type]));
+ }
+ }
+ return type;
+ }
+
+ DOC_ERROR(QString("Undefined named type \"%1\" used.").arg(type));
+ }
+
+ if (type_idx >= 0)
+ {
+ type = attributes.value(type_idx).utf8();
+
+ QRegExp reg_exp(QCString("(a?[ybnqiuxdtsogv]|a[{]sv[}])"));
+ if (reg_exp.match(type.data()))
+ { return type; }
+
+ DOC_ERROR(QString("Unnamed complex D-Bus type \"%1\" found.").arg(type));
+ }
+
+ return QString();
+ }
+
+ QString getDBusType(const QCString & type)
+ {
+ QCString scoped_type = type;
+ if (!scoped_type.contains("::"))
+ { scoped_type = getCurrentScope(type); }
+
+ if (m_namedTypeMap.contains(scoped_type))
+ { return m_namedTypeMap[scoped_type]; }
+ else
+ { return type; }
+ }
+
+ void addNamedType(const QCString &type)
+ {
+ QCString scoped_name(getCurrentScope());
+
+ if (m_namedTypeMap.contains(scoped_name))
+ {
+ DOC_ERROR(QString("Named type \"%1\" is already defined.").arg(scoped_name));
+ return;
+ }
+
+ m_namedTypeMap.insert(scoped_name, type);
+ }
+
+ QCString getCurrentScope(const QCString & type = QCString())
+ {
+ QCString scoped_name;
+ if (!m_scopeStack.isEmpty())
+ {
+ scoped_name = m_scopeStack.getLast()->scope->name;
+ scoped_name.append("::");
+ }
+ if (!type.isEmpty())
+ { scoped_name.append(type); }
+ else
+ { scoped_name = scoped_name.left(scoped_name.length() - 2); }
+
+ return scoped_name;
+ }
+
+ int indexOf(const QXmlAttributes & attributes, const QString & name,
+ const QString & type = "CDATA", const bool mandatory = true)
+ {
+ const int idx(attributes.index(name));
+ if (idx < 0 || idx > attributes.length()) { return -1; }
+ if (attributes.type(idx) != type) { return -1; }
+ if (mandatory && attributes.value(idx).isEmpty()) { return -1; }
+
+ return idx;
+ }
+
+ Entry * createEntry()
+ {
+ Entry * entry = new Entry();
+
+ entry->protection = Public ;
+ entry->virt = Normal;
+ entry->stat = false;
+ entry->lang = SrcLangExt_XML;
+ entry->spec = 0;
+
+ entry->fileName = m_fileName;
+ entry->startLine = lineNumber();
+ entry->bodyLine = lineNumber();
+
+ entry->callGraph = false;
+ entry->callerGraph = false;
+
+ initGroupInfo(entry);
+
+ m_currentEntry = entry;
+
+ handleComment();
+
+ return entry;
+ }
+
+ void openScopes(Entry * object)
+ {
+ int cur_scope_separator_pos = 0;
+ int last_scope_separator_pos = 0;
+ while (0 <= (cur_scope_separator_pos = object->name.find("::", last_scope_separator_pos)))
+ {
+ QString scope = object->name.mid(last_scope_separator_pos,
+ cur_scope_separator_pos - last_scope_separator_pos);
+ last_scope_separator_pos = cur_scope_separator_pos + 2;
+
+ Entry * current_namespace = openNamespace(scope);
+
+ if (!m_scopeStack.isEmpty())
+ { m_scopeStack.getLast()->scope->addSubEntry(current_namespace); }
+
+ m_scopeStack.append(new ScopeData(current_namespace, m_scopeCount));
+ }
+
+ QCString scoped_name(getCurrentScope());
+ if (!scoped_name.isEmpty())
+ { scoped_name.append("::"); }
+ scoped_name.append(object->name.mid(last_scope_separator_pos));
+
+ object->name = scoped_name;
+
+ if (!m_scopeStack.isEmpty())
+ { m_scopeStack.getLast()->scope->addSubEntry(object); }
+ m_scopeStack.append(new ScopeData(object, m_scopeCount));
+
+ ++m_scopeCount;
+ }
+
+ Entry * openNamespace(const QString & name)
+ {
+ Entry * current_namespace = createEntry();
+ QCString scoped_name(getCurrentScope());
+ if (!scoped_name.isEmpty())
+ { scoped_name.append("::"); }
+ scoped_name.append(name.utf8());
+ current_namespace->name = scoped_name;
+ current_namespace->section = Entry::NAMESPACE_SEC;
+ current_namespace->type = "namespace" ;
+
+ return current_namespace;
+ }
+
+ void closeScopes()
+ {
+ const int current_scope_count(m_scopeStack.getLast()->count);
+
+ // Do not close the root scope.
+ if (current_scope_count == 0)
+ { return; }
+
+ while (current_scope_count == m_scopeStack.getLast()->count)
+ { m_scopeStack.removeLast(); }
+ }
+
+ ParserInterface * m_parser;
+
+ QXmlLocator m_locator;
+ QCString m_currentNode; // Nodes can not be nested, no entry necessary.
+
+ struct ElementData
+ {
+ ElementData(const QCString & e) :
+ element(e)
+ { }
+ ~ElementData() { }
+
+ QCString element; //*< The element name
+ QCString text; //*< The actual xml code.
+ };
+ QList<ElementData> m_elementStack;
+
+ Entry * m_currentEntry; // The currently open entry.
+
+ Entry * m_currentInterface; // Interfaces can not be nested.
+ Entry * m_currentMethod; // Methods can not be nested.
+ Argument * m_currentArgument; // Arguments can not be nested.
+ Entry * m_currentProperty; // Properties can not be nested.
+ Entry * m_currentEnum; // Enums can not be nested.
+ QList<Entry> m_namespaceStack;
+
+ struct StructData
+ {
+ StructData(Entry * e) : entry(e) { }
+ ~StructData() { }
+
+ QCString type;
+ Entry * entry;
+ };
+ QList<StructData> m_structStack; // Structs can be nested.
+
+ struct ScopeData
+ {
+ ScopeData(Entry * s, int c) :
+ scope(s),
+ count(c)
+ { }
+ ~ScopeData() { }
+
+ Entry * scope;
+ int count;
+ };
+ QList<ScopeData> m_scopeStack; // Scopes are nested.
+
+ QCString m_fileName;
+
+ struct CommentData
+ {
+ CommentData(const QCString & f, const int l, const QCString & t) :
+ isJavaStyle(false),
+ isQtStyle(false),
+ line(l),
+ fileName(f)
+ {
+ isJavaStyle = t.length()>0 && t.at(0)=='*';
+ isQtStyle = t.length()>0 && t.at(0)=='!';
+ shouldIgnore = (!isJavaStyle && !isQtStyle);
+ associateWithPrevious = (t.length()>1 && t.at(1)=='<');
+ if (associateWithPrevious)
+ { text = t.mid(2); }
+ else
+ { text = t.mid(1); }
+ }
+ ~CommentData() { }
+
+ QCString text;
+ bool isJavaStyle;
+ bool isQtStyle;
+ bool shouldIgnore;
+ bool associateWithPrevious;
+ int line;
+ QCString fileName;
+ };
+ CommentData * m_currentComment;
+
+ int m_scopeCount; //*< unique scope id.
+
+ QString m_errorString;
+
+ QMap<QCString, QCString> m_namedTypeMap;
+};
+
+// -----------------------------------------------------------------------
+// DBusXMLScanner
+// -----------------------------------------------------------------------
+
+DBusXMLScanner::DBusXMLScanner()
+{ }
+
+DBusXMLScanner::~DBusXMLScanner()
+{ }
+
+void DBusXMLScanner::parseInput(const char * fileName,
+ const char * /* fileBuf */,
+ Entry *root,
+ bool /*sameTranslationUnit*/,
+ QStrList & /*filesInSameTranslationUnit*/)
+{
+ QFile inputFile(fileName);
+
+ QXmlInputSource inputSource(inputFile);
+ QXmlSimpleReader reader;
+
+ DBusXMLHandler handler(this, &reader, fileName, root);
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+ reader.setLexicalHandler(&handler);
+
+ groupEnterFile(fileName, 1);
+ handler.setSection();
+ reader.parse(inputSource);
+
+ if (!handler.errorString().isEmpty())
+ { err("DBus XML Parser: Error at line %d: %s\n",
+ handler.locator()->lineNumber(),handler.errorString().utf8().data()); }
+
+ groupLeaveFile(fileName, 1);
+}
+
+bool DBusXMLScanner::needsPreprocessing(const QCString & /* extension */)
+{ return (false); }
+
+void DBusXMLScanner::parseCode(CodeOutputInterface & /* codeOutIntf */,
+ const char * /* scopeName */,
+ const QCString & /* input */,
+ SrcLangExt /* lang */,
+ bool /* isExampleBlock */,
+ const char * /* exampleName */,
+ FileDef * /* fileDef */,
+ int /* startLine */,
+ int /* endLine */,
+ bool /* inlineFragment */,
+ MemberDef * /* memberDef */,
+ bool /*showLineNumbers*/,
+ Definition * /* searchCtx */,
+ bool /*collectXRefs*/ )
+{ }
+
+void DBusXMLScanner::resetCodeParserState()
+{ }
+
+void DBusXMLScanner::parsePrototype(const char * /* text */)
+{ }
diff --git a/src/dbusxmlscanner.h b/src/dbusxmlscanner.h
new file mode 100644
index 0000000..e1504e9
--- /dev/null
+++ b/src/dbusxmlscanner.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 2009 by Tobias Hunger <tobias at aquazul.com>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCANNER_DBUSXML_H
+#define SCANNER_DBUSXML_H
+
+#include "parserintf.h"
+
+/** D-Bus XML parser.
+ *
+ * This is the D-Bus XML parser for doxygen.
+ */
+class DBusXMLScanner : public ParserInterface
+{
+public:
+ DBusXMLScanner();
+ virtual ~DBusXMLScanner();
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+
+ bool needsPreprocessing(const QCString &extension);
+
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+
+ void resetCodeParserState();
+
+ void parsePrototype(const char *text);
+
+private:
+};
+
+#endif
diff --git a/src/debug.cpp b/src/debug.cpp
new file mode 100644
index 0000000..e27ce11
--- /dev/null
+++ b/src/debug.cpp
@@ -0,0 +1,134 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <qdict.h>
+
+#include "debug.h"
+#include "message.h"
+
+//------------------------------------------------------------------------
+
+/** Helper struct representing a mapping from debug label to a debug ID */
+struct LabelMap
+{
+ const char *name;
+ Debug::DebugMask event;
+};
+
+static LabelMap s_labels[] =
+{
+ { "findmembers", Debug::FindMembers },
+ { "functions", Debug::Functions },
+ { "variables", Debug::Variables },
+ { "preprocessor", Debug::Preprocessor },
+ { "classes", Debug::Classes },
+ { "commentcnv", Debug::CommentCnv },
+ { "commentscan", Debug::CommentScan },
+ { "validate", Debug::Validate },
+ { "printtree", Debug::PrintTree },
+ { "time", Debug::Time },
+ { "extcmd", Debug::ExtCmd },
+ { "markdown", Debug::Markdown },
+ { "filteroutput", Debug::FilterOutput },
+ { "lex", Debug::Lex },
+ { 0, (Debug::DebugMask)0 }
+};
+
+/** Class representing a mapping from debug labels to debug IDs. */
+class LabelMapper
+{
+ public:
+ LabelMapper() : m_map(17)
+ {
+ m_map.setAutoDelete(TRUE);
+ LabelMap *p = s_labels;
+ while (p->name)
+ {
+ m_map.insert(p->name,new Debug::DebugMask(p->event));
+ p++;
+ }
+ }
+ Debug::DebugMask *find(const char *s) const
+ {
+ if (s==0) return 0;
+ return m_map.find(s);
+ }
+ private:
+ QDict<Debug::DebugMask> m_map;
+};
+
+static LabelMapper g_labelMapper;
+
+//------------------------------------------------------------------------
+
+Debug::DebugMask Debug::curMask = Debug::Quiet;
+int Debug::curPrio = 0;
+
+void Debug::print(DebugMask mask,int prio,const char *fmt,...)
+{
+ if ((curMask&mask) && prio<=curPrio)
+ {
+ va_list args;
+ va_start(args,fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+}
+
+static int labelToEnumValue(const char *l)
+{
+ QCString label=l;
+ Debug::DebugMask *event = g_labelMapper.find(label.lower());
+ if (event) return *event; else return 0;
+}
+
+int Debug::setFlag(const char *lab)
+{
+ int retVal = labelToEnumValue(lab);
+ curMask = (DebugMask)(curMask | labelToEnumValue(lab));
+ return retVal;
+}
+
+void Debug::clearFlag(const char *lab)
+{
+ curMask = (DebugMask)(curMask & ~labelToEnumValue(lab));
+}
+
+void Debug::setPriority(int p)
+{
+ curPrio = p;
+}
+
+bool Debug::isFlagSet(DebugMask mask)
+{
+ return (curMask & mask)!=0;
+}
+
+void Debug::printFlags(void)
+{
+ int i;
+ for (i = 0; i < (int)(sizeof(s_labels)/sizeof(*s_labels)); i++)
+ {
+ if (s_labels[i].name)
+ {
+ msg("\t%s\n",s_labels[i].name);
+ }
+ }
+}
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 0000000..e17c03c
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+/** Class containing a print function for diagnostics. */
+class Debug
+{
+ public:
+ enum DebugMask { Quiet = 0x00000000,
+ FindMembers = 0x00000001,
+ Functions = 0x00000002,
+ Variables = 0x00000004,
+ Preprocessor = 0x00000008,
+ Classes = 0x00000010,
+ CommentCnv = 0x00000020,
+ CommentScan = 0x00000040,
+ Validate = 0x00000080,
+ PrintTree = 0x00000100,
+ Time = 0x00000200,
+ ExtCmd = 0x00000400,
+ Markdown = 0x00000800,
+ FilterOutput = 0x00001000,
+ Lex = 0x00002000
+ };
+ static void print(DebugMask mask,int prio,const char *fmt,...);
+ static int setFlag(const char *label);
+ static void clearFlag(const char *label);
+ static bool isFlagSet(DebugMask mask);
+ static void printFlags(void);
+ static void setPriority(int p);
+
+ private:
+ static DebugMask curMask;
+ static int curPrio;
+};
+
+#endif
diff --git a/src/declinfo.h b/src/declinfo.h
new file mode 100644
index 0000000..5f11a1c
--- /dev/null
+++ b/src/declinfo.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DECLINFO_H
+#define DECLINFO_H
+
+#include <stdio.h>
+#include <qcstring.h>
+
+extern void parseFuncDecl(const QCString &decl,
+ bool objC,
+ QCString &clName,
+ QCString &type,
+ QCString &name,
+ QCString &args,
+ QCString &funcTempList,
+ QCString &exceptions
+ );
+#endif
diff --git a/src/declinfo.l b/src/declinfo.l
new file mode 100644
index 0000000..f238be3
--- /dev/null
+++ b/src/declinfo.l
@@ -0,0 +1,361 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+//#include <iostream.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "declinfo.h"
+#include "util.h"
+#include "message.h"
+
+#define YY_NO_INPUT 1
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+
+static const char * inputString;
+static int inputPosition;
+static QCString scope;
+static QCString className;
+static QCString classTempList;
+static QCString funcTempList;
+static QCString type;
+static QCString name;
+static QCString args;
+static QCString tmpType;
+static int sharpCount;
+static bool classTempListFound;
+static bool funcTempListFound;
+static QCString exceptionString;
+static bool insideObjC;
+
+static void addType()
+{
+ //printf("addType() type=`%s' scope=`%s' name=`%s'\n",
+ // type.data(),scope.data(),name.data());
+ if (name.isEmpty() && scope.isEmpty()) return;
+ if (!type.isEmpty()) type+=" ";
+ if (!scope.isEmpty()) type+=scope+"::";
+ type+=name;
+ scope.resize(0);
+ name.resize(0);
+}
+
+static void addTypeName()
+{
+ //printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n",
+ // type.data(),scope.data(),name.data());
+ if (name.isEmpty() ||
+ name.at(name.length()-1)==':') // end of Objective-C keyword => append to name not type
+ {
+ return;
+ }
+ if (!type.isEmpty()) type+=' ';
+ type+=name;
+ name.resize(0);
+}
+
+#define YY_NEVER_INTERACTIVE 1
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+B [ \t]
+ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
+
+%option nounput
+%option noyywrap
+
+%x Start
+%x Template
+%x ReadArgs
+%x Operator
+%x FuncPtr
+%x EndTemplate
+%x StripTempArgs
+%x SkipSharp
+%x ReadExceptions
+
+%%
+
+<Start>"operator"/({B}*"["{B}*"]")* { // operator rule must be before {ID} rule
+ name += yytext;
+ BEGIN(Operator);
+ }
+<Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories
+ if (!insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ name += yytext;
+ }
+ }
+<Start>([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java,
+ // the / was add to deal with multi-
+ // dimensional C++ arrays like A[][15]
+ // the leading ~ is for a destructor
+ // the leading ! is for a C++/CLI finalizer (see bug 456475 and 635198)
+ addTypeName();
+ name += yytext;
+ }
+<Start>{B}*"::"{B}* { // found a scope specifier
+ if (!scope.isEmpty())
+ {
+ scope+="::"+name; // add name to scope
+ }
+ else
+ {
+ scope = name.copy(); // scope becomes name
+ }
+ name.resize(0);
+ }
+<Start>{B}*":" { // Objective-C argument separator
+ name+=yytext;
+ }
+<Start>[*&]+ {
+ addType();
+ type+=yytext;
+ }
+<Start>{B}+ {
+ addType();
+ }
+<Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)? {
+ addType();
+ QCString text=yytext;
+ type+=text.stripWhiteSpace();
+ }
+<Start>{B}*")" {
+ type+=")";
+ }
+<Start>{B}*"(" { // TODO: function pointers
+ args+="(";
+ BEGIN(ReadArgs);
+ }
+<Start>{B}*"[" {
+ args+="[";
+ BEGIN(ReadArgs);
+ }
+<Start>{B}*"<" {
+ name+="<";
+ sharpCount=0;
+ BEGIN(Template);
+ }
+<Template>"<<" { name+="<<"; }
+<Template>">>" { name+=">>"; }
+<Template>"<" {
+ name+="<";
+ sharpCount++;
+ }
+<Template>">" {
+ name+=">";
+ if (sharpCount)
+ --sharpCount;
+ else
+ {
+ BEGIN(Start);
+ }
+ }
+<Template>. {
+ name+=*yytext;
+ }
+<Operator>{B}*"("{B}*")"{B}*"<>"{B}*/"(" {
+ name+="() <>";
+ BEGIN(ReadArgs);
+ }
+<Operator>{B}*"("{B}*")"{B}*/"(" {
+ name+="()";
+ BEGIN(ReadArgs);
+ }
+<Operator>[^(]*{B}*("<>"{B}*)?/"(" {
+ name+=yytext;
+ BEGIN(ReadArgs);
+ }
+<ReadArgs>"throw"{B}*"(" {
+ exceptionString="throw(";
+ BEGIN(ReadExceptions);
+ }
+<ReadArgs>. {
+ args+=*yytext;
+ }
+<ReadExceptions>. {
+ exceptionString+=*yytext;
+ }
+<*>.
+<*>\n
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t,
+ QCString &n,QCString &a,QCString &ftl,QCString &exc)
+{
+ printlex(yy_flex_debug, TRUE, __FILE__, NULL);
+ inputString = decl;
+ //printf("Input=`%s'\n",inputString);
+ if (inputString==0) return;
+ inputPosition = 0;
+ classTempListFound = FALSE;
+ funcTempListFound = FALSE;
+ insideObjC = objC;
+ scope.resize(0);
+ className.resize(0);
+ classTempList.resize(0);
+ funcTempList.resize(0);
+ name.resize(0);
+ type.resize(0);
+ args.resize(0);
+ exceptionString.resize(0);
+ // first we try to find the type, scope, name and arguments
+ declinfoYYrestart( declinfoYYin );
+ BEGIN( Start );
+ declinfoYYlex();
+
+ //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
+ // type.data(),scope.data(),name.data(),args.data());
+
+ int nb = name.findRev('[');
+ if (nb!=-1 && args.isEmpty()) // correct for [] in name ambigity (due to Java return type allowing [])
+ {
+ args.prepend(name.right(name.length()-nb));
+ name=name.left(nb);
+ }
+
+#if 0
+ {
+ int l=scope.length();
+ int i=0;
+ int skipCount=0;
+ cl.resize(0);
+ ctl.resize(0);
+ for (i=0;i<l;i++)
+ {
+ char c=scope.at(i);
+ if (c=='<')
+ skipCount++;
+ else if (c=='>')
+ skipCount--;
+ else if (skipCount==0)
+ cl+=c;
+ }
+ }
+ cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE);
+ ctl.resize(0);
+#endif
+
+ cl=scope;
+ n=removeRedundantWhiteSpace(name);
+ int il,ir;
+ if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1)
+ // TODO: handle cases like where n="operator<< <T>"
+ {
+ ftl=removeRedundantWhiteSpace(n.right(n.length()-il));
+ n=n.left(il);
+ }
+
+ //ctl=classTempList.copy();
+ //ftl=funcTempList.copy();
+ t=removeRedundantWhiteSpace(type);
+ a=removeRedundantWhiteSpace(args);
+ exc=removeRedundantWhiteSpace(exceptionString);
+
+ if (!t.isEmpty() && t.at(t.length()-1)==')') // for function pointers
+ {
+ a.prepend(")");
+ t=t.left(t.length()-1);
+ }
+ //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
+ // t.data(),cl.data(),n.data(),a.data());
+
+ printlex(yy_flex_debug, FALSE, __FILE__, NULL);
+ return;
+
+
+}
+
+//extern "C" { // some bogus code to keep the compiler happy
+// int declinfoYYwrap() { return 1 ; }
+// void declinfoYYdummy() { yy_flex_realloc(0,0); }
+//}
+
+#if 0
+void dumpDecl(const char *s)
+{
+ QCString className;
+ QCString classTNames;
+ QCString type;
+ QCString name;
+ QCString args;
+ QCString funcTNames;
+ msg("-----------------------------------------\n");
+ parseFuncDecl(s,className,classTNames,type,name,args,funcTNames);
+ msg("type=`%s' class=`%s' classTempl=`%s' name=`%s' "
+ "funcTemplateNames=`%s' args=`%s'\n",
+ type.data(),className.data(),classTNames.data(),
+ name.data(),funcTNames.data(),args.data()
+ );
+}
+
+// some test code
+int main()
+{
+ dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
+ dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
+ dumpDecl("func()");
+ dumpDecl("friend void bla<>()");
+ dumpDecl("name< T > :: operator () (int bla)");
+ dumpDecl("name< T > :: operator << (int bla)");
+ dumpDecl("name< T > :: operator << <> (int bla)");
+ dumpDecl("className::func()");
+ dumpDecl("void ( * Name < T > :: bla ) ( int, char * )");
+}
+#endif
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void declinfoYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/defargs.h b/src/defargs.h
new file mode 100644
index 0000000..6ebfe1d
--- /dev/null
+++ b/src/defargs.h
@@ -0,0 +1,27 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DEFARGS_H
+#define DEFARGS_H
+
+class ArgumentList;
+class QCString;
+
+extern void stringToArgumentList(const char *argsString,ArgumentList* argList,
+ QCString *extraTypeChars=0);
+
+#endif
diff --git a/src/defargs.l b/src/defargs.l
new file mode 100644
index 0000000..164c100
--- /dev/null
+++ b/src/defargs.l
@@ -0,0 +1,562 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*! \file
+ * This scanner is used to convert a string into a list of function or
+ * template arguments. Each parsed argument results in a Argument struct,
+ * that is put into an ArgumentList in declaration order.
+ * Comment blocks for arguments can also be included in the string.
+ * The argument string does not contain new-lines (except inside any
+ * comment blocks).
+ * An Argument consists of the string fields:
+ * type,name,default value, and documentation
+ * The Argument list as a whole can be pure, constant or volatile.
+ *
+ * Examples of input strings are:
+ * \code
+ * "(int a,int b) const"
+ * "(const char *s="hello world",int=5) = 0"
+ * "<class T,class N>"
+ * "(char c,const char)"
+ * \endcode
+ *
+ * Note: It is not always possible to distinguish between the name and
+ * type of an argument. In case of doubt the name is added to the
+ * type, and the matchArgumentList in util.cpp is be used to
+ * further determine the correct separation.
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+//#include <iostream.h>
+#include <assert.h>
+#include <ctype.h>
+#include <qregexp.h>
+
+#include "defargs.h"
+#include "entry.h"
+#include "util.h"
+#include "arguments.h"
+#include "message.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+/* -----------------------------------------------------------------
+ * state variables
+ */
+static const char *g_inputString;
+static int g_inputPosition;
+static ArgumentList *g_argList;
+static QCString *g_copyArgValue;
+static QCString g_curArgTypeName;
+static QCString g_curArgDefValue;
+static QCString g_curArgName;
+static QCString g_curArgDocs;
+static QCString g_curArgAttrib;
+static QCString g_curArgArray;
+static QCString g_extraTypeChars;
+static int g_argRoundCount;
+static int g_argSharpCount;
+static int g_argCurlyCount;
+static int g_readArgContext;
+static int g_lastDocContext;
+static int g_lastDocChar;
+static QCString g_delimiter;
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+B [ \t]
+ID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
+RAWEND ")"[^ \t\(\)\\]{0,16}\"
+
+%option noyywrap
+
+%x Start
+%x CopyArgString
+%x CopyRawString
+%x CopyArgRound
+%x CopyArgRound2
+%x CopyArgSharp
+%x CopyArgCurly
+%x ReadFuncArgType
+%x ReadFuncArgDef
+%x ReadFuncArgPtr
+%x FuncQual
+%x ReadDocBlock
+%x ReadDocLine
+%x TrailingReturn
+
+
+%%
+
+<Start>[<(] { BEGIN(ReadFuncArgType); }
+
+<ReadFuncArgType>{B}* {
+ g_curArgTypeName+=" ";
+ }
+<ReadFuncArgType>"["[^\]]*"]" {
+ if (g_curArgTypeName.stripWhiteSpace().isEmpty())
+ {
+ g_curArgAttrib=yytext; // for M$-IDL
+ }
+ else // array type
+ {
+ g_curArgArray+=yytext;
+ }
+ }
+<ReadFuncArgDef>"'"\\[0-7]{1,3}"'" { g_curArgDefValue+=yytext; }
+<ReadFuncArgDef>"'"\\."'" { g_curArgDefValue+=yytext; }
+<ReadFuncArgDef>"'"."'" { g_curArgDefValue+=yytext; }
+<ReadFuncArgDef>{RAWBEGIN} { g_curArgDefValue+=yytext;
+ QCString text=yytext;
+ int i=text.find('"');
+ g_delimiter = yytext+i+1;
+ g_delimiter=g_delimiter.left(g_delimiter.length()-1);
+ BEGIN( CopyRawString );
+ }
+<ReadFuncArgDef>\" {
+ g_curArgDefValue+=*yytext;
+ BEGIN( CopyArgString );
+ }
+<ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*\^]+{B}*/{ID} {
+ // function pointer as argument
+ g_curArgTypeName+=yytext;
+ //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
+ BEGIN( ReadFuncArgPtr );
+ }
+<ReadFuncArgPtr>{ID} {
+ g_curArgName=yytext;
+ }
+<ReadFuncArgPtr>")"{B}*"(" { // function pointer
+ g_curArgTypeName+=yytext;
+ //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
+ g_readArgContext = ReadFuncArgType;
+ g_copyArgValue=&g_curArgTypeName;
+ g_argRoundCount=0;
+ BEGIN( CopyArgRound2 );
+ }
+<ReadFuncArgPtr>")"/{B}*"[" { // pointer to fixed size array
+ g_curArgTypeName+=yytext;
+ g_curArgTypeName+=g_curArgName;
+ //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
+ BEGIN( ReadFuncArgType );
+ }
+<ReadFuncArgPtr>")" { // redundant braces detected / remove them
+ int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length();
+ if (i!=-1)
+ g_curArgTypeName=g_curArgTypeName.left(i)+
+ g_curArgTypeName.right(l-i-1);
+ g_curArgTypeName+=g_curArgName;
+ BEGIN( ReadFuncArgType );
+ }
+<ReadFuncArgType>"<="|">="|"->"|">>"|"<<" { // handle operators in defargs
+ g_curArgTypeName+=yytext;
+ }
+<ReadFuncArgType,ReadFuncArgDef>[({<] {
+ if (YY_START==ReadFuncArgType)
+ {
+ g_curArgTypeName+=*yytext;
+ g_copyArgValue=&g_curArgTypeName;
+ }
+ else // YY_START==ReadFuncArgDef
+ {
+ g_curArgDefValue+=*yytext;
+ g_copyArgValue=&g_curArgDefValue;
+ }
+ g_readArgContext = YY_START;
+ if (*yytext=='(')
+ {
+ g_argRoundCount=0;
+ BEGIN( CopyArgRound );
+ }
+ else if (*yytext=='{')
+ {
+ g_argCurlyCount=0;
+ BEGIN( CopyArgCurly );
+ }
+ else // yytext=='<'
+ {
+ g_argSharpCount=0;
+ g_argRoundCount=0;
+ BEGIN( CopyArgSharp );
+ }
+ }
+<CopyArgRound,CopyArgRound2>"(" {
+ g_argRoundCount++;
+ *g_copyArgValue += *yytext;
+ }
+<CopyArgRound,CopyArgRound2>")"({B}*{ID})* {
+ *g_copyArgValue += yytext;
+ if (g_argRoundCount>0)
+ {
+ g_argRoundCount--;
+ }
+ else
+ {
+ if (YY_START==CopyArgRound2)
+ {
+ *g_copyArgValue+=" "+g_curArgName;
+ }
+ BEGIN( g_readArgContext );
+ }
+ }
+<CopyArgRound>")"/{B}* {
+ *g_copyArgValue += *yytext;
+ if (g_argRoundCount>0) g_argRoundCount--;
+ else BEGIN( g_readArgContext );
+ }
+<CopyArgSharp>"<<" {
+ if (g_argRoundCount>0)
+ {
+ *g_copyArgValue += yytext;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<CopyArgSharp>">>" {
+ if (g_argRoundCount>0)
+ {
+ *g_copyArgValue += yytext;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<CopyArgSharp>"<" {
+ g_argSharpCount++;
+ *g_copyArgValue += *yytext;
+ }
+<CopyArgSharp>">" {
+ *g_copyArgValue += *yytext;
+ if (g_argSharpCount>0) g_argSharpCount--;
+ else BEGIN( g_readArgContext );
+ }
+<CopyArgSharp>"(" {
+ g_argRoundCount++;
+ *g_copyArgValue += *yytext;
+ }
+<CopyArgSharp>")" {
+ g_argRoundCount--;
+ *g_copyArgValue += *yytext;
+ }
+<CopyArgCurly>"{" {
+ g_argCurlyCount++;
+ *g_copyArgValue += *yytext;
+ }
+<CopyArgCurly>"}" {
+ *g_copyArgValue += *yytext;
+ if (g_argCurlyCount>0) g_argCurlyCount--;
+ else BEGIN( g_readArgContext );
+ }
+<CopyArgString>\\. {
+ g_curArgDefValue+=yytext;
+ }
+<CopyRawString>{RAWEND} {
+ g_curArgDefValue+=yytext;
+ QCString delimiter = yytext+1;
+ delimiter=delimiter.left(delimiter.length()-1);
+ if (delimiter==g_delimiter)
+ {
+ BEGIN( ReadFuncArgDef );
+ }
+ }
+<CopyArgString>\" {
+ g_curArgDefValue+=*yytext;
+ BEGIN( ReadFuncArgDef );
+ }
+<ReadFuncArgType>"=" {
+ BEGIN( ReadFuncArgDef );
+ }
+<ReadFuncArgType,ReadFuncArgDef>[,)>]{B}*("/*"[*!]|"//"[/!])"<" {
+ g_lastDocContext=YY_START;
+ g_lastDocChar=*yytext;
+ QCString text=yytext;
+ if (text.find("//")!=-1)
+ BEGIN( ReadDocLine );
+ else
+ BEGIN( ReadDocBlock );
+ }
+<ReadFuncArgType,ReadFuncArgDef>[,)>] {
+ if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty())
+ {
+ g_curArgTypeName+=*yytext;
+ BEGIN(FuncQual);
+ }
+ else
+ {
+ g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName);
+ g_curArgDefValue=g_curArgDefValue.stripWhiteSpace();
+ //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data());
+ int l=g_curArgTypeName.length();
+ if (l>0)
+ {
+ int i=l-1;
+ while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
+ while (i>=0 && (isId(g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='$')) i--;
+ Argument *a = new Argument;
+ a->attrib = g_curArgAttrib.copy();
+ //printf("a->type=%s a->name=%s i=%d l=%d\n",
+ // a->type.data(),a->name.data(),i,l);
+ a->array.resize(0);
+ if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument
+ {
+ int bi=g_curArgTypeName.find('(');
+ int fi=bi-1;
+ //printf("func arg fi=%d\n",fi);
+ while (fi>=0 && isId(g_curArgTypeName.at(fi))) fi--;
+ if (fi>=0)
+ {
+ a->type = g_curArgTypeName.left(fi+1);
+ a->name = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace();
+ a->array = g_curArgTypeName.right(l-bi);
+ }
+ else
+ {
+ a->type = g_curArgTypeName;
+ }
+ }
+ else if (i>=0 && g_curArgTypeName.at(i)!=':')
+ { // type contains a name
+ a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)).stripWhiteSpace();
+ a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace();
+
+ // if the type becomes a type specifier only then we make a mistake
+ // and need to correct it to avoid seeing a nameless parameter
+ // "struct A" as a parameter with type "struct" and name "A".
+ int sv=0;
+ if (a->type.left(6)=="const ") sv=6;
+ else if (a->type.left(9)=="volatile ") sv=9;
+
+ if (a->type.mid(sv)=="struct" ||
+ a->type.mid(sv)=="union" ||
+ a->type.mid(sv)=="class" ||
+ a->type.mid(sv)=="typename" ||
+ a->type=="const" ||
+ a->type=="volatile"
+ )
+ {
+ a->type = a->type + " " + a->name;
+ a->name.resize(0);
+ }
+ //printf(" --> a->type='%s'\n",a->type.data());
+ }
+ else // assume only the type was specified, try to determine name later
+ {
+ a->type = removeRedundantWhiteSpace(g_curArgTypeName);
+ }
+ if (!a->type.isEmpty() && a->type.at(0)=='$') // typeless PHP name?
+ {
+ a->name = a->type;
+ a->type = "";
+ }
+ a->array += removeRedundantWhiteSpace(g_curArgArray);
+ //printf("array=%s\n",a->array.data());
+ int alen = a->array.length();
+ if (alen>2 && a->array.at(0)=='(' &&
+ a->array.at(alen-1)==')') // fix-up for int *(a[10])
+ {
+ int i=a->array.find('[')-1;
+ a->array = a->array.mid(1,alen-2);
+ if (i>0 && a->name.isEmpty())
+ {
+ a->name = a->array.left(i).stripWhiteSpace();
+ a->array = a->array.mid(i);
+ }
+ }
+ a->defval = g_curArgDefValue.copy();
+ //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data());
+ a->docs = g_curArgDocs.stripWhiteSpace();
+ //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data());
+ g_argList->append(a);
+ }
+ g_curArgAttrib.resize(0);
+ g_curArgTypeName.resize(0);
+ g_curArgDefValue.resize(0);
+ g_curArgArray.resize(0);
+ g_curArgDocs.resize(0);
+ if (*yytext==')')
+ {
+ BEGIN(FuncQual);
+ //printf(">>> end of argument list\n");
+ }
+ else
+ {
+ BEGIN( ReadFuncArgType );
+ }
+ }
+ }
+<ReadFuncArgType,ReadFuncArgPtr>"$"?{ID} {
+ QCString name=yytext; //resolveDefines(yytext);
+ if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array
+ {
+ g_curArgTypeName+=" []";
+ g_curArgArray.resize(0);
+ }
+ //printf("resolveName `%s'->`%s'\n",yytext,name.data());
+ g_curArgTypeName+=name;
+ }
+<ReadFuncArgType,ReadFuncArgPtr>. {
+ g_curArgTypeName+=*yytext;
+ }
+
+<ReadFuncArgDef,CopyArgString>"<="|"->"|">="|">>"|"<<" {
+ g_curArgDefValue+=yytext;
+ }
+<ReadFuncArgDef,CopyArgString,CopyRawString>. {
+ g_curArgDefValue+=*yytext;
+ }
+<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID} {
+ QCString name=yytext; //resolveDefines(yytext);
+ *g_copyArgValue+=name;
+ }
+<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>. {
+ *g_copyArgValue += *yytext;
+ }
+<FuncQual>"const" {
+ g_argList->constSpecifier=TRUE;
+ }
+<FuncQual>"volatile" {
+ g_argList->volatileSpecifier=TRUE;
+ }
+<FuncQual,TrailingReturn>"="{B}*"0" {
+ g_argList->pureSpecifier=TRUE;
+ BEGIN(FuncQual);
+ }
+<FuncQual>"->" { // C++11 trailing return type
+ g_argList->trailingReturnType=" -> ";
+ BEGIN(TrailingReturn);
+ }
+<TrailingReturn>{B}/("final"|"override"){B}* {
+ unput(*yytext);
+ BEGIN(FuncQual);
+ }
+<TrailingReturn>. {
+ g_argList->trailingReturnType+=yytext;
+ }
+<TrailingReturn>\n {
+ g_argList->trailingReturnType+=yytext;
+ }
+<FuncQual>")"{B}*"["[^]]*"]" { // for functions returning a pointer to an array,
+ // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]"
+ g_extraTypeChars=yytext;
+ }
+<ReadDocBlock>[^\*\n]+ {
+ g_curArgDocs+=yytext;
+ }
+<ReadDocLine>[^\n]+ {
+ g_curArgDocs+=yytext;
+ }
+<ReadDocBlock>"*/" {
+ if (g_lastDocChar!=0)
+ unput(g_lastDocChar);
+ BEGIN(g_lastDocContext);
+ }
+<ReadDocLine>\n {
+ if (g_lastDocChar!=0)
+ unput(g_lastDocChar);
+ BEGIN(g_lastDocContext);
+ }
+<ReadDocBlock>\n {
+ g_curArgDocs+=*yytext;
+ }
+<ReadDocBlock>. {
+ g_curArgDocs+=*yytext;
+ }
+<*>("/*"[*!]|"//"[/!])("<"?) {
+ g_lastDocContext=YY_START;
+ g_lastDocChar=0;
+ if (yytext[1]=='/')
+ BEGIN( ReadDocLine );
+ else
+ BEGIN( ReadDocBlock );
+ }
+<*>\n
+<*>.
+
+%%
+
+/* ----------------------------------------------------------------------------
+ */
+
+/*! Converts an argument string into an ArgumentList.
+ * \param[in] argsString the list of Arguments.
+ * \param[out] al a reference to resulting argument list pointer.
+ * \param[out] extraTypeChars point to string to which trailing characters
+ * for complex types are written to
+ */
+
+void stringToArgumentList(const char *argsString,ArgumentList* al,QCString *extraTypeChars)
+{
+ if (al==0) return;
+ if (argsString==0) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, NULL);
+
+ g_copyArgValue=0;
+ g_curArgDocs.resize(0);
+ g_curArgAttrib.resize(0);
+ g_curArgArray.resize(0);
+ g_extraTypeChars.resize(0);
+ g_argRoundCount = 0;
+ g_argSharpCount = 0;
+ g_argCurlyCount = 0;
+ g_lastDocChar = 0;
+
+ g_inputString = argsString;
+ g_inputPosition = 0;
+ g_curArgTypeName.resize(0);
+ g_curArgDefValue.resize(0);
+ g_curArgName.resize(0);
+ g_argList = al;
+ defargsYYrestart( defargsYYin );
+ BEGIN( Start );
+ defargsYYlex();
+ if (extraTypeChars) *extraTypeChars=g_extraTypeChars;
+ //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data());
+ printlex(yy_flex_debug, FALSE, __FILE__, NULL);
+}
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void defargsYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/defgen.cpp b/src/defgen.cpp
new file mode 100644
index 0000000..358cd24
--- /dev/null
+++ b/src/defgen.cpp
@@ -0,0 +1,638 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "defgen.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "classlist.h"
+#include "util.h"
+#include "defargs.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "filename.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+#define DEF_DB(x)
+
+inline void writeDEFString(FTextStream &t,const char *s)
+{
+ const char* p=s;
+ char c;
+
+ t << '\'';
+ while ((c = *(p++)))
+ {
+ if (c == '\'')
+ t << '\\';
+ t << c;
+ }
+ t << '\'';
+}
+
+void generateDEFForMember(MemberDef *md,
+ FTextStream &t,
+ Definition *def,
+ const char* Prefix)
+{
+ QCString memPrefix;
+
+ // + declaration
+ // - reimplements
+ // - reimplementedBy
+ // - exceptions
+ // - const/volatile specifiers
+ // - examples
+ // + source definition
+ // - source references
+ // - source referenced by
+ // - include code
+
+ if (md->memberType()==MemberType_EnumValue) return;
+
+ QCString scopeName;
+ if (md->getClassDef())
+ scopeName=md->getClassDef()->name();
+ else if (md->getNamespaceDef())
+ scopeName=md->getNamespaceDef()->name();
+
+ t << " " << Prefix << "-member = {" << endl;
+ memPrefix = " ";
+ memPrefix.append( Prefix );
+ memPrefix.append( "-mem-" );
+
+ QCString memType;
+ bool isFunc=FALSE;
+ switch (md->memberType())
+ {
+ case MemberType_Define: memType="define"; break;
+ case MemberType_EnumValue: ASSERT(0); break;
+ case MemberType_Property: memType="property"; break;
+ case MemberType_Event: memType="event"; break;
+ case MemberType_Variable: memType="variable"; break;
+ case MemberType_Typedef: memType="typedef"; break;
+ case MemberType_Enumeration: memType="enum"; break;
+ case MemberType_Interface: memType="interface"; break;
+ case MemberType_Service: memType="service"; break;
+ case MemberType_Function: memType="function"; isFunc=TRUE; break;
+ case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
+ case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
+ case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
+ case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
+ }
+
+ t << memPrefix << "kind = '" << memType << "';" << endl;
+ t << memPrefix << "id = '"
+ << md->getOutputFileBase() << "_1" << md->anchor()
+ << "';" << endl;
+
+ t << memPrefix << "virt = ";
+ switch (md->virtualness())
+ {
+ case Normal: t << "normal;" << endl; break;
+ case Virtual: t << "virtual;" << endl; break;
+ case Pure: t << "pure-virtual;" << endl; break;
+ default: ASSERT(0);
+ }
+
+ t << memPrefix << "prot = ";
+ switch(md->protection())
+ {
+ case Public: t << "public;" << endl; break;
+ case Protected: t << "protected;" << endl; break;
+ case Private: t << "private;" << endl; break;
+ case Package: t << "package;" << endl; break;
+ }
+
+ if (md->memberType()!=MemberType_Define &&
+ md->memberType()!=MemberType_Enumeration
+ )
+ {
+ QCString typeStr = replaceAnonymousScopes(md->typeString());
+ t << memPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl << typeStr << endl
+ << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+
+ t << memPrefix << "name = '" << md->name() << "';" << endl;
+
+ if (isFunc) //function
+ {
+ ArgumentList *declAl = new ArgumentList;
+ ArgumentList *defAl = md->argumentList();
+ stringToArgumentList(md->argsString(),declAl);
+ QCString fcnPrefix = " " + memPrefix + "param-";
+
+ if (declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ Argument *defArg = defAli.current();
+ t << memPrefix << "param = {" << endl;
+ if (!a->attrib.isEmpty())
+ {
+ t << fcnPrefix << "attributes = ";
+ writeDEFString(t,a->attrib);
+ t << ';' << endl;
+ }
+ if (!a->type.isEmpty())
+ {
+ t << fcnPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl
+ << a->type << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ if (!a->name.isEmpty())
+ {
+ t << fcnPrefix << "declname = ";
+ writeDEFString(t,a->name);
+ t << ';' << endl;
+ }
+ if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
+ {
+ t << fcnPrefix << "defname = ";
+ writeDEFString(t,defArg->name);
+ t << ';' << endl;
+ }
+ if (!a->array.isEmpty())
+ {
+ t << fcnPrefix << "array = ";
+ writeDEFString(t,a->array);
+ t << ';' << endl;
+ }
+ if (!a->defval.isEmpty())
+ {
+ t << fcnPrefix << "defval = <<_EnD_oF_dEf_TeXt_" << endl
+ << a->defval << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ if (defArg) ++defAli;
+ t << " }; /*" << fcnPrefix << "-param */" << endl;
+ }
+ }
+ delete declAl;
+ }
+ else if ( md->memberType()==MemberType_Define
+ && md->argsString()!=0)
+ {
+ ArgumentListIterator ali(*md->argumentList());
+ Argument *a;
+ QCString defPrefix = " " + memPrefix + "def-";
+
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ t << memPrefix << "param = {" << endl;
+ t << defPrefix << "name = '" << a->type << "';" << endl;
+ t << " }; /*" << defPrefix << "-param */" << endl;
+ }
+ }
+
+ if (!md->initializer().isEmpty())
+ {
+ t << memPrefix << "initializer = <<_EnD_oF_dEf_TeXt_" << endl
+ << md->initializer() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ // TODO: exceptions, const volatile
+ if (md->memberType()==MemberType_Enumeration) // enum
+ {
+ MemberList *enumList = md->enumFieldList();
+ if (enumList!=0)
+ {
+ MemberListIterator emli(*enumList);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ t << memPrefix << "enum = { enum-name = " << emd->name() << ';';
+ if (!emd->initializer().isEmpty())
+ {
+ t << " enum-value = ";
+ writeDEFString(t,emd->initializer());
+ t << ';';
+ }
+ t << " };" << endl;
+ }
+ }
+ }
+
+ t << memPrefix << "desc-file = '" << md->getDefFileName() << "';" << endl;
+ t << memPrefix << "desc-line = '" << md->getDefLine() << "';" << endl;
+ t << memPrefix << "briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
+ << md->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ t << memPrefix << "documentation = <<_EnD_oF_dEf_TeXt_" << endl
+ << md->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
+
+ MemberSDict *mdict = md->getReferencesMembers();
+ if (mdict)
+ {
+ MemberSDict::Iterator mdi(*mdict);
+ MemberDef *rmd;
+ QCString refPrefix = " " + memPrefix + "ref-";
+
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
+ {
+ t << memPrefix << "referenceto = {" << endl;
+ t << refPrefix << "id = '"
+ << rmd->getBodyDef()->getOutputFileBase()
+ << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
+ << rmd->anchor() << "';" << endl;
+
+ t << refPrefix << "line = '"
+ << rmd->getStartBodyLine() << "';" << endl;
+
+ QCString scope = rmd->getScopeString();
+ QCString name = rmd->name();
+ if (!scope.isEmpty() && scope!=def->name())
+ {
+ name.prepend(scope+"::");
+ }
+
+ t << refPrefix << "name = ";
+ writeDEFString(t,name);
+ t << ';' << endl << " };" << endl;
+ }
+ } /* for (mdi.toFirst...) */
+ }
+ mdict = md->getReferencedByMembers();
+ if (mdict)
+ {
+ MemberSDict::Iterator mdi(*mdict);
+ MemberDef *rmd;
+ QCString refPrefix = " " + memPrefix + "ref-";
+
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
+ {
+ t << memPrefix << "referenceby = {" << endl;
+ t << refPrefix << "id = '"
+ << rmd->getBodyDef()->getOutputFileBase()
+ << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
+ << rmd->anchor() << "';" << endl;
+
+ t << refPrefix << "line = '"
+ << rmd->getStartBodyLine() << "';" << endl;
+
+ QCString scope = rmd->getScopeString();
+ QCString name = rmd->name();
+ if (!scope.isEmpty() && scope!=def->name())
+ {
+ name.prepend(scope+"::");
+ }
+
+ t << refPrefix << "name = ";
+ writeDEFString(t,name);
+ t << ';' << endl << " };" << endl;
+ }
+ } /* for (mdi.toFirst...) */
+ }
+
+ t << " }; /* " << Prefix << "-member */" << endl;
+}
+
+
+void generateDEFClassSection(ClassDef *cd,
+ FTextStream &t,
+ MemberList *ml,
+ const char *kind)
+{
+ if (cd && ml && ml->count()>0)
+ {
+ t << " cp-section = {" << endl;
+ t << " sec-kind = '" << kind << "';" << endl;
+
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ generateDEFForMember(md,t,cd,"sec");
+ }
+ t << " }; /* cp-section */" << endl;
+ }
+}
+
+void generateDEFForClass(ClassDef *cd,FTextStream &t)
+{
+ // + brief description
+ // + detailed description
+ // - template arguments
+ // - include files
+ // + inheritance diagram
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + collaboration diagram
+ // - list of all members
+ // + user defined member sections
+ // + standard member sections
+ // + detailed member documentation
+ // - examples
+
+ if (cd->isReference()) return; // skip external references.
+ if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
+ if (cd->templateMaster()!=0) return; // skip generated template instances.
+
+ t << cd->compoundTypeString() << " = {" << endl;
+ t << " cp-id = '" << cd->getOutputFileBase() << "';" << endl;
+ t << " cp-name = '" << cd->name() << "';" << endl;
+
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " cp-ref = {" << endl << " ref-type = base;" << endl;
+ t << " ref-id = '"
+ << bcd->classDef->getOutputFileBase() << "';" << endl;
+ t << " ref-prot = ";
+ switch (bcd->prot)
+ {
+ case Public: t << "public;" << endl; break;
+ case Package: // package scope is not possible
+ case Protected: t << "protected;" << endl; break;
+ case Private: t << "private;" << endl; break;
+ }
+ t << " ref-virt = ";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual;"; break;
+ case Virtual: t << "virtual;"; break;
+ case Pure: t << "pure-virtual;"; break;
+ }
+ t << endl << " };" << endl;
+ }
+ }
+
+ if (cd->subClasses())
+ {
+ BaseClassListIterator bcli(*cd->subClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " cp-ref = {" << endl << " ref-type = derived;" << endl;
+ t << " ref-id = '"
+ << bcd->classDef->getOutputFileBase() << "';" << endl;
+ t << " ref-prot = ";
+ switch (bcd->prot)
+ {
+ case Public: t << "public;" << endl; break;
+ case Package: // packet scope is not possible!
+ case Protected: t << "protected;" << endl; break;
+ case Private: t << "private;" << endl; break;
+ }
+ t << " ref-virt = ";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual;"; break;
+ case Virtual: t << "virtual;"; break;
+ case Pure: t << "pure-virtual;"; break;
+ }
+ t << endl << " };" << endl;
+ }
+ }
+
+ int numMembers = 0;
+ QListIterator<MemberList> mli(cd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ numMembers+=ml->count();
+ }
+ }
+ if (numMembers>0)
+ {
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubTypes),"public-type");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_interfaces),"interfaces");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_services),"services");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubMethods),"public-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubAttribs),"public-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubSlots),"public-slot");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_signals),"signal");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_dcopMethods),"dcop-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_properties),"property");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubStaticMethods),"public-static-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubStaticAttribs),"public-static-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proTypes),"protected-type");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proMethods),"protected-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proAttribs),"protected-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proSlots),"protected-slot");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proStaticMethods),"protected-static-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proStaticAttribs),"protected-static-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priTypes),"private-type");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priMethods),"private-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priAttribs),"private-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priSlots),"private-slot");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priStaticMethods),"private-static-func");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priStaticAttribs),"private-static-attrib");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_friends),"signal");
+ generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_related),"related");
+ }
+
+ t << " cp-filename = '" << cd->getDefFileName() << "';" << endl;
+ t << " cp-fileline = '" << cd->getDefLine() << "';" << endl;
+ t << " cp-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
+ << cd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ t << " cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl
+ << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial())
+ {
+ t << " cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl;
+ inheritanceGraph.writeDEF(t);
+ t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
+ if (!collaborationGraph.isTrivial())
+ {
+ t << " cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl;
+ collaborationGraph.writeDEF(t);
+ t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ t << "}; /* " << cd->compoundTypeString() << " */" << endl;
+}
+
+void generateDEFSection(Definition *d,
+ FTextStream &t,
+ MemberList *ml,
+ const char *kind)
+{
+ if (ml && ml->count()>0)
+ {
+ t << " " << kind << " = {" << endl;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ generateDEFForMember(md,t,d,kind);
+ }
+ t << " };" << endl;
+ }
+}
+
+void generateDEFForNamespace(NamespaceDef *nd,FTextStream &t)
+{
+ if (nd->isReference()) return; // skip external references
+ t << " namespace = {" << endl;
+ t << " ns-id = '" << nd->getOutputFileBase() << "';" << endl;
+ t << " ns-name = ";
+ writeDEFString(t,nd->name());
+ t << ';' << endl;
+
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decDefineMembers),"define");
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decProtoMembers),"prototype");
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decTypedefMembers),"typedef");
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decEnumMembers),"enum");
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decFuncMembers),"func");
+ generateDEFSection(nd,t,nd->getMemberList(MemberListType_decVarMembers),"var");
+
+ t << " ns-filename = '" << nd->getDefFileName() << "';" << endl;
+ t << " ns-fileline = '" << nd->getDefLine() << "';" << endl;
+ t << " ns-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
+ << nd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ t << " ns-documentation = <<_EnD_oF_dEf_TeXt_" << endl
+ << nd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+ t << " };" << endl;
+}
+
+void generateDEFForFile(FileDef *fd,FTextStream &t)
+{
+ if (fd->isReference()) return; // skip external references
+
+ t << "file = {" << endl;
+ t << " file-id = '" << fd->getOutputFileBase() << "';" << endl;
+ t << " file-name = ";
+ writeDEFString(t,fd->name());
+ t << ';' << endl;
+
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decDefineMembers),"define");
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decProtoMembers),"prototype");
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decTypedefMembers),"typedef");
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decEnumMembers),"enum");
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decFuncMembers),"func");
+ generateDEFSection(fd,t,fd->getMemberList(MemberListType_decVarMembers),"var");
+
+ t << " file-full-name = '" << fd->getDefFileName() << "';" << endl;
+ t << " file-first-line = '" << fd->getDefLine() << "';" << endl;
+
+ t << " file-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
+ << fd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ t << " file-documentation = <<_EnD_oF_dEf_TeXt_" << endl
+ << fd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
+
+ t << "}; /* file */" << endl;
+}
+
+
+void generateDEF()
+{
+ QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
+ if (outputDirectory.isEmpty())
+ {
+ outputDirectory=QDir::currentDirPath().utf8();
+ }
+ else
+ {
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("tag OUTPUT_DIRECTORY: Output directory `%s' does not "
+ "exist and cannot be created\n",outputDirectory.data());
+ exit(1);
+ }
+ else
+ {
+ msg("Notice: Output directory `%s' does not exist. "
+ "I have created it for you.\n", outputDirectory.data());
+ }
+ dir.cd(outputDirectory);
+ }
+ outputDirectory=dir.absPath().utf8();
+ }
+
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("Cannot create directory %s\n",outputDirectory.data());
+ return;
+ }
+ }
+ QDir defDir(outputDirectory+"/def");
+ if (!defDir.exists() && !defDir.mkdir(outputDirectory+"/def"))
+ {
+ err("Could not create def directory in %s\n",outputDirectory.data());
+ return;
+ }
+
+ QCString fileName=outputDirectory+"/def/doxygen.def";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ t << "AutoGen Definitions dummy;" << endl;
+
+ if (Doxygen::classSDict->count()+Doxygen::inputNameList->count()>0)
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ generateDEFForClass(cd,t);
+ }
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ generateDEFForFile(fd,t);
+ }
+ }
+ }
+ else
+ {
+ t << "dummy_value = true;" << endl;
+ }
+}
diff --git a/src/defgen.h b/src/defgen.h
new file mode 100644
index 0000000..696fb5c
--- /dev/null
+++ b/src/defgen.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef DEFGEN_H
+#define DEFGEN_H
+
+void generateDEF();
+
+#endif
diff --git a/src/define.cpp b/src/define.cpp
new file mode 100644
index 0000000..75459c9
--- /dev/null
+++ b/src/define.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "define.h"
+#include "config.h"
+
+Define::Define()
+{
+ fileDef=0;
+ lineNr=1;
+ columnNr=1;
+ nargs=-1;
+ undef=FALSE;
+ varArgs=FALSE;
+ isPredefined=FALSE;
+ nonRecursive=FALSE;
+}
+
+Define::Define(const Define &d)
+ : name(d.name),definition(d.definition),fileName(d.fileName)
+{
+ //name=d.name; definition=d.definition; fileName=d.fileName;
+ lineNr=d.lineNr;
+ lineNr=d.columnNr;
+ nargs=d.nargs;
+ undef=d.undef;
+ varArgs=d.varArgs;
+ isPredefined=d.isPredefined;
+ nonRecursive=d.nonRecursive;
+ fileDef=0;
+}
+
+Define::~Define()
+{
+}
+
+bool Define::hasDocumentation()
+{
+ return definition && (doc || Config_getBool("EXTRACT_ALL"));
+}
diff --git a/src/define.h b/src/define.h
new file mode 100644
index 0000000..7971cc4
--- /dev/null
+++ b/src/define.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DEFINE_H
+#define DEFINE_H
+
+#include <qdict.h>
+#include <qlist.h>
+
+class FileDef;
+
+/** A class representing a macro definition. */
+class Define
+{
+ public:
+ Define();
+ Define(const Define &d);
+ ~Define();
+ bool hasDocumentation();
+ QCString name;
+ QCString definition;
+ QCString fileName;
+ QCString doc;
+ QCString brief;
+ QCString args;
+ QCString anchor;
+ FileDef *fileDef;
+ int lineNr;
+ int columnNr;
+ int nargs;
+ bool undef;
+ bool varArgs;
+ bool isPredefined;
+ bool nonRecursive;
+};
+
+/** A list of Define objects. */
+class DefineList : public QList<Define>
+{
+ public:
+ DefineList() : QList<Define>() {}
+ ~DefineList() {}
+ private:
+ int compareValues(const Define *d1,const Define *d2) const
+ {
+ return qstricmp(d1->name,d2->name);
+ }
+};
+
+/** A list of Define objects associated with a specific name. */
+class DefineName : public QList<Define>
+{
+ public:
+ DefineName(const char *n) : QList<Define>() { name=n; }
+ ~DefineName() {}
+ const char *nameString() const { return name; }
+
+ private:
+ int compareValues(const Define *d1,const Define *d2) const
+ {
+ return qstricmp(d1->name,d2->name);
+ }
+ QCString name;
+};
+
+/** A list of DefineName objects. */
+class DefineNameList : public QList<DefineName>
+{
+ public:
+ DefineNameList() : QList<DefineName>() {}
+ ~DefineNameList() {}
+ private:
+ int compareValues(const DefineName *n1,const DefineName *n2) const
+ {
+ return qstricmp(n1->nameString(),n2->nameString());
+ }
+};
+
+/** An unsorted dictionary of Define objects. */
+typedef QDict<Define> DefineDict;
+
+/** A sorted dictionary of DefineName object. */
+typedef QDict<DefineName> DefineNameDict;
+
+#endif
diff --git a/src/definition.cpp b/src/definition.cpp
new file mode 100644
index 0000000..4a6a728
--- /dev/null
+++ b/src/definition.cpp
@@ -0,0 +1,1898 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <ctype.h>
+#include <qregexp.h>
+#include "md5.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "config.h"
+#include "definition.h"
+#include "doxygen.h"
+#include "language.h"
+#include "message.h"
+#include "outputlist.h"
+#include "code.h"
+#include "util.h"
+#include "groupdef.h"
+#include "pagedef.h"
+#include "section.h"
+#include "htags.h"
+#include "parserintf.h"
+#include "marshal.h"
+#include "debug.h"
+#include "vhdldocgen.h"
+#include "memberlist.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "dirdef.h"
+
+#define START_MARKER 0x4445465B // DEF[
+#define END_MARKER 0x4445465D // DEF]
+
+//-----------------------------------------------------------------------------------------
+
+
+/** Private data associated with a Symbol Definition object. */
+class DefinitionImpl
+{
+ public:
+ DefinitionImpl();
+ ~DefinitionImpl();
+ void init(const char *df, const char *n);
+
+ SectionDict *sectionDict; // dictionary of all sections, not accessible
+
+ MemberSDict *sourceRefByDict;
+ MemberSDict *sourceRefsDict;
+ QList<ListItemInfo> *xrefListItems;
+ GroupList *partOfGroups;
+
+ DocInfo *details; // not exported
+ DocInfo *inbodyDocs; // not exported
+ BriefInfo *brief; // not exported
+ BodyInfo *body; // not exported
+ QCString briefSignatures;
+ QCString docSignatures;
+
+ QCString localName; // local (unqualified) name of the definition
+ // in the future m_name should become m_localName
+ QCString qualifiedName;
+ QCString ref; // reference to external documentation
+
+ bool hidden;
+ bool isArtificial;
+
+ Definition *outerScope; // not owner
+
+ // where the item was found
+ QCString defFileName;
+ QCString defFileExt;
+
+ SrcLangExt lang;
+
+ QCString id; // clang unique id
+};
+
+DefinitionImpl::DefinitionImpl()
+ : sectionDict(0), sourceRefByDict(0), sourceRefsDict(0),
+ xrefListItems(0), partOfGroups(0),
+ details(0), inbodyDocs(0), brief(0), body(0),
+ outerScope(0)
+{
+}
+
+DefinitionImpl::~DefinitionImpl()
+{
+ delete sectionDict;
+ delete sourceRefByDict;
+ delete sourceRefsDict;
+ delete partOfGroups;
+ delete xrefListItems;
+ delete brief;
+ delete details;
+ delete body;
+ delete inbodyDocs;
+}
+
+void DefinitionImpl::init(const char *df, const char *n)
+{
+ defFileName = df;
+ int lastDot = defFileName.findRev('.');
+ if (lastDot!=-1)
+ {
+ defFileExt = defFileName.mid(lastDot);
+ }
+ QCString name = n;
+ if (name!="<globalScope>")
+ {
+ //extractNamespaceName(m_name,m_localName,ns);
+ localName=stripScope(n);
+ }
+ else
+ {
+ localName=n;
+ }
+ //printf("m_localName=%s\n",m_localName.data());
+
+ brief = 0;
+ details = 0;
+ body = 0;
+ inbodyDocs = 0;
+ sourceRefByDict = 0;
+ sourceRefsDict = 0;
+ sectionDict = 0,
+ outerScope = Doxygen::globalScope;
+ partOfGroups = 0;
+ xrefListItems = 0;
+ hidden = FALSE;
+ isArtificial = FALSE;
+ lang = SrcLangExt_Unknown;
+}
+
+//-----------------------------------------------------------------------------------------
+
+static bool matchExcludedSymbols(const char *name)
+{
+ static QStrList &exclSyms = Config_getList("EXCLUDE_SYMBOLS");
+ if (exclSyms.count()==0) return FALSE; // nothing specified
+ const char *pat = exclSyms.first();
+ QCString symName = name;
+ while (pat)
+ {
+ QCString pattern = pat;
+ bool forceStart=FALSE;
+ bool forceEnd=FALSE;
+ if (pattern.at(0)=='^')
+ pattern=pattern.mid(1),forceStart=TRUE;
+ if (pattern.at(pattern.length()-1)=='$')
+ pattern=pattern.left(pattern.length()-1),forceEnd=TRUE;
+ if (pattern.find('*')!=-1) // wildcard mode
+ {
+ QRegExp re(substitute(pattern,"*",".*"),TRUE);
+ int i,pl;
+ i = re.match(symName,0,&pl);
+ //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data());
+ if (i!=-1) // wildcard match
+ {
+ int sl=symName.length();
+ // check if it is a whole word match
+ if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) &&
+ (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd))
+ )
+ {
+ //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
+ return TRUE;
+ }
+ }
+ }
+ else if (!pattern.isEmpty()) // match words
+ {
+ int i = symName.find(pattern);
+ if (i!=-1) // we have a match!
+ {
+ int pl=pattern.length();
+ int sl=symName.length();
+ // check if it is a whole word match
+ if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) &&
+ (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd))
+ )
+ {
+ //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
+ return TRUE;
+ }
+ }
+ }
+ pat = exclSyms.next();
+ }
+ //printf("--> name=%s: no match\n",name);
+ return FALSE;
+}
+
+void Definition::addToMap(const char *name,Definition *d)
+{
+ bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString symbolName = name;
+ int index=computeQualifiedIndex(symbolName);
+ if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
+ if (!symbolName.isEmpty())
+ {
+ //printf("******* adding symbol `%s' (%p)\n",symbolName.data(),d);
+ DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
+ //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di);
+ if (di==0) // new Symbol
+ {
+ //printf(" new symbol!\n");
+ Doxygen::symbolMap->insert(symbolName,d);
+ }
+ else // existing symbol
+ {
+ //printf(" existing symbol: ");
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols
+ {
+ //printf("adding to exiting list\n");
+ DefinitionList *dl = (DefinitionList*)di;
+ dl->append(d);
+ }
+ else // going from one to two symbols
+ {
+ Doxygen::symbolMap->take(symbolName);
+ DefinitionList *dl = new DefinitionList;
+ //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d);
+ dl->append((Definition*)di);
+ dl->append(d);
+ Doxygen::symbolMap->insert(symbolName,dl);
+ }
+ }
+
+ // auto resize if needed
+ static int sizeIndex=9;
+ if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex])
+ {
+ Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]);
+ }
+
+ d->_setSymbolName(symbolName);
+ }
+}
+
+void Definition::removeFromMap(Definition *d)
+{
+ QCString symbolName = d->m_symbolName;
+ if (!symbolName.isEmpty())
+ {
+ //printf("******* removing symbol `%s' (%p)\n",symbolName.data(),d);
+ DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
+ if (di)
+ {
+ if (di!=d) // symbolName not unique
+ {
+ //printf(" removing from list: %p!\n",di);
+ DefinitionList *dl = (DefinitionList*)di;
+ bool b = dl->removeRef(d);
+ ASSERT(b==TRUE);
+ if (dl->isEmpty())
+ {
+ Doxygen::symbolMap->take(symbolName);
+ }
+ }
+ else // symbolName unique
+ {
+ //printf(" removing symbol %p\n",di);
+ Doxygen::symbolMap->take(symbolName);
+ }
+ }
+ }
+}
+
+Definition::Definition(const char *df,int dl,int dc,
+ const char *name,const char *b,
+ const char *d,bool isSymbol)
+{
+ m_name = name;
+ m_defLine = dl;
+ m_defColumn = dc;
+ m_impl = new DefinitionImpl;
+ m_impl->init(df,name);
+ m_isSymbol = isSymbol;
+ if (isSymbol) addToMap(name,this);
+ _setBriefDescription(b,df,dl);
+ _setDocumentation(d,df,dl,TRUE,FALSE);
+ if (matchExcludedSymbols(name))
+ {
+ m_impl->hidden = TRUE;
+ }
+}
+
+Definition::Definition(const Definition &d) : DefinitionIntf()
+{
+ m_name = d.m_name;
+ m_defLine = d.m_defLine;
+ m_impl = new DefinitionImpl;
+ *m_impl = *d.m_impl;
+ m_impl->sectionDict = 0;
+ m_impl->sourceRefByDict = 0;
+ m_impl->sourceRefsDict = 0;
+ m_impl->partOfGroups = 0;
+ m_impl->xrefListItems = 0;
+ m_impl->brief = 0;
+ m_impl->details = 0;
+ m_impl->body = 0;
+ m_impl->inbodyDocs = 0;
+ if (d.m_impl->sectionDict)
+ {
+ m_impl->sectionDict = new SectionDict(17);
+ SDict<SectionInfo>::Iterator it(*d.m_impl->sectionDict);
+ SectionInfo *si;
+ for (it.toFirst();(si=it.current());++it)
+ {
+ m_impl->sectionDict->append(si->label,si);
+ }
+ }
+ if (d.m_impl->sourceRefByDict)
+ {
+ m_impl->sourceRefByDict = new MemberSDict;
+ MemberSDict::IteratorDict it(*d.m_impl->sourceRefByDict);
+ MemberDef *md;
+ for (it.toFirst();(md=it.current());++it)
+ {
+ m_impl->sourceRefByDict->append(it.currentKey(),md);
+ }
+ }
+ if (d.m_impl->sourceRefsDict)
+ {
+ m_impl->sourceRefsDict = new MemberSDict;
+ MemberSDict::IteratorDict it(*d.m_impl->sourceRefsDict);
+ MemberDef *md;
+ for (it.toFirst();(md=it.current());++it)
+ {
+ m_impl->sourceRefsDict->append(it.currentKey(),md);
+ }
+ }
+ if (d.m_impl->partOfGroups)
+ {
+ GroupListIterator it(*d.m_impl->partOfGroups);
+ GroupDef *gd;
+ for (it.toFirst();(gd=it.current());++it)
+ {
+ makePartOfGroup(gd);
+ }
+ }
+ if (d.m_impl->xrefListItems)
+ {
+ setRefItems(d.m_impl->xrefListItems);
+ }
+ if (d.m_impl->brief)
+ {
+ m_impl->brief = new BriefInfo(*d.m_impl->brief);
+ }
+ if (d.m_impl->details)
+ {
+ m_impl->details = new DocInfo(*d.m_impl->details);
+ }
+ if (d.m_impl->body)
+ {
+ m_impl->body = new BodyInfo(*d.m_impl->body);
+ }
+ if (d.m_impl->inbodyDocs)
+ {
+ m_impl->details = new DocInfo(*d.m_impl->inbodyDocs);
+ }
+
+ m_isSymbol = d.m_isSymbol;
+ if (m_isSymbol) addToMap(m_name,this);
+}
+
+Definition::~Definition()
+{
+ if (m_isSymbol)
+ {
+ removeFromMap(this);
+ }
+ if (m_impl)
+ {
+ delete m_impl;
+ m_impl=0;
+ }
+}
+
+void Definition::setName(const char *name)
+{
+ if (name==0) return;
+ m_name = name;
+}
+
+void Definition::setId(const char *id)
+{
+ if (id==0) return;
+ m_impl->id = id;
+ if (Doxygen::clangUsrMap)
+ {
+ //printf("Definition::setId '%s'->'%s'\n",id,m_name.data());
+ Doxygen::clangUsrMap->insert(id,this);
+ }
+}
+
+QCString Definition::id() const
+{
+ return m_impl->id;
+}
+
+void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList)
+{
+ if (!anchorList) return;
+ //printf("%s: addSectionsToDefinition(%d)\n",name().data(),anchorList->count());
+ QListIterator<SectionInfo> it(*anchorList);
+ SectionInfo *si;
+ for (;(si=it.current());++it)
+ {
+ //printf("Add section `%s' to definition `%s'\n",
+ // si->label.data(),name().data());
+ SectionInfo *gsi=Doxygen::sectionDict->find(si->label);
+ //printf("===== label=%s gsi=%p\n",si->label.data(),gsi);
+ if (gsi==0)
+ {
+ gsi = new SectionInfo(*si);
+ Doxygen::sectionDict->append(si->label,gsi);
+ }
+ if (m_impl->sectionDict==0)
+ {
+ m_impl->sectionDict = new SectionDict(17);
+ }
+ if (m_impl->sectionDict->find(gsi->label)==0)
+ {
+ m_impl->sectionDict->append(gsi->label,gsi);
+ gsi->definition = this;
+ }
+ }
+}
+
+bool Definition::hasSections() const
+{
+ //printf("Definition::hasSections(%s) #sections=%d\n",name().data(),
+ // m_impl->sectionDict ? m_impl->sectionDict->count() : 0);
+ if (m_impl->sectionDict==0) return FALSE;
+ SDict<SectionInfo>::Iterator li(*m_impl->sectionDict);
+ SectionInfo *si;
+ for (li.toFirst();(si=li.current());++li)
+ {
+ if (si->type==SectionInfo::Section ||
+ si->type==SectionInfo::Subsection ||
+ si->type==SectionInfo::Subsubsection ||
+ si->type==SectionInfo::Paragraph)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void Definition::addSectionsToIndex()
+{
+ if (m_impl->sectionDict==0) return;
+ //printf("Definition::addSectionsToIndex()\n");
+ SDict<SectionInfo>::Iterator li(*m_impl->sectionDict);
+ SectionInfo *si;
+ int level=1;
+ for (li.toFirst();(si=li.current());++li)
+ {
+ if (si->type==SectionInfo::Section ||
+ si->type==SectionInfo::Subsection ||
+ si->type==SectionInfo::Subsubsection ||
+ si->type==SectionInfo::Paragraph)
+ {
+ //printf(" level=%d title=%s\n",level,si->title.data());
+ int nextLevel = (int)si->type;
+ int i;
+ if (nextLevel>level)
+ {
+ for (i=level;i<nextLevel;i++)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ }
+ else if (nextLevel<level)
+ {
+ for (i=nextLevel;i<level;i++)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ QCString title = si->title;
+ if (title.isEmpty()) title = si->label;
+ Doxygen::indexList->addContentsItem(TRUE,title,
+ getReference(),
+ getOutputFileBase(),
+ si->label,
+ FALSE,
+ TRUE);
+ level = nextLevel;
+ }
+ }
+ while (level>1)
+ {
+ Doxygen::indexList->decContentsDepth();
+ level--;
+ }
+}
+
+void Definition::writeDocAnchorsToTagFile()
+{
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && m_impl->sectionDict)
+ {
+ //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionDict->count());
+ SDict<SectionInfo>::Iterator sdi(*m_impl->sectionDict);
+ SectionInfo *si;
+ for (;(si=sdi.current());++sdi)
+ {
+ if (!si->generated)
+ {
+ //printf("write an entry!\n");
+ if (definitionType()==TypeMember) Doxygen::tagFile << " ";
+ Doxygen::tagFile << " <docanchor file=\""
+ << si->fileName << "\"";
+ if (!si->title.isEmpty())
+ {
+ Doxygen::tagFile << " title=\"" << convertToXML(si->title) << "\"";
+ }
+ Doxygen::tagFile << ">" << si->label
+ << "</docanchor>" << endl;
+ }
+ }
+ }
+}
+
+bool Definition::_docsAlreadyAdded(const QCString &doc,QCString &sigList)
+{
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ // to avoid mismatches due to differences in indenting, we first remove
+ // double whitespaces...
+ QCString docStr = doc.simplifyWhiteSpace();
+ MD5Buffer((const unsigned char *)docStr.data(),docStr.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ //printf("%s:_docsAlreadyAdded doc='%s' sig='%s' docSigs='%s'\n",
+ // name().data(),doc.data(),sigStr.data(),sigList.data());
+ if (sigList.find(sigStr)==-1) // new docs, add signature to prevent re-adding it
+ {
+ sigList+=":"+sigStr;
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,
+ bool stripWhiteSpace,bool atTop)
+{
+ //printf("%s::setDocumentation(%s,%s,%d,%d)\n",name().data(),d,docFile,docLine,stripWhiteSpace);
+ if (d==0) return;
+ QCString doc = d;
+ if (stripWhiteSpace)
+ {
+ doc = stripLeadingAndTrailingEmptyLines(doc,docLine);
+ }
+ else // don't strip whitespace
+ {
+ doc=d;
+ }
+ if (!_docsAlreadyAdded(doc,m_impl->docSignatures))
+ {
+ //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data());
+ if (m_impl->details==0)
+ {
+ m_impl->details = new DocInfo;
+ }
+ if (m_impl->details->doc.isEmpty()) // fresh detailed description
+ {
+ m_impl->details->doc = doc;
+ }
+ else if (atTop) // another detailed description, append it to the start
+ {
+ m_impl->details->doc = doc+"\n\n"+m_impl->details->doc;
+ }
+ else // another detailed description, append it to the end
+ {
+ m_impl->details->doc += "\n\n"+doc;
+ }
+ if (docLine!=-1) // store location if valid
+ {
+ m_impl->details->file = docFile;
+ m_impl->details->line = docLine;
+ }
+ else
+ {
+ m_impl->details->file = docFile;
+ m_impl->details->line = 1;
+ }
+ }
+}
+
+void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
+{
+ if (d==0) return;
+ _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE);
+}
+
+#define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase)
+
+// do a UTF-8 aware search for the last real character and return TRUE
+// if that is a multibyte one.
+static bool lastCharIsMultibyte(const QCString &s)
+{
+ int l = s.length();
+ int p = 0;
+ int pp = -1;
+ while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p;
+ if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE;
+ return TRUE;
+}
+
+void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine)
+{
+ static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE");
+ static bool needsDot = outputLanguage!="Japanese" &&
+ outputLanguage!="Chinese" &&
+ outputLanguage!="Korean";
+ QCString brief = b;
+ brief = brief.stripWhiteSpace();
+ if (brief.isEmpty()) return;
+ int bl = brief.length();
+ if (bl>0 && needsDot) // add punctuation if needed
+ {
+ int c = brief.at(bl-1);
+ switch(c)
+ {
+ case '.': case '!': case '?': case '>': case ':': case ')': break;
+ default:
+ if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.';
+ break;
+ }
+ }
+
+ if (!_docsAlreadyAdded(brief,m_impl->briefSignatures))
+ {
+ if (m_impl->brief && !m_impl->brief->doc.isEmpty())
+ {
+ //printf("adding to details\n");
+ _setDocumentation(brief,briefFile,briefLine,FALSE,TRUE);
+ }
+ else
+ {
+ //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine);
+ if (m_impl->brief==0)
+ {
+ m_impl->brief = new BriefInfo;
+ }
+ m_impl->brief->doc=brief;
+ if (briefLine!=-1)
+ {
+ m_impl->brief->file = briefFile;
+ m_impl->brief->line = briefLine;
+ }
+ else
+ {
+ m_impl->brief->file = briefFile;
+ m_impl->brief->line = 1;
+ }
+ }
+ }
+ else
+ {
+ //printf("do nothing!\n");
+ }
+}
+
+void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine)
+{
+ if (b==0) return;
+ _setBriefDescription(b,briefFile,briefLine);
+}
+
+void Definition::_setInbodyDocumentation(const char *doc,const char *inbodyFile,int inbodyLine)
+{
+ if (m_impl->inbodyDocs==0)
+ {
+ m_impl->inbodyDocs = new DocInfo;
+ }
+ if (m_impl->inbodyDocs->doc.isEmpty()) // fresh inbody docs
+ {
+ m_impl->inbodyDocs->doc = doc;
+ m_impl->inbodyDocs->file = inbodyFile;
+ m_impl->inbodyDocs->line = inbodyLine;
+ }
+ else // another inbody documentation fragment, append this to the end
+ {
+ m_impl->inbodyDocs->doc += QCString("\n\n")+doc;
+ }
+}
+
+void Definition::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
+{
+ if (d==0) return;
+ _setInbodyDocumentation(d,inbodyFile,inbodyLine);
+}
+
+/*! Reads a fragment of code from file \a fileName starting at
+ * line \a startLine and ending at line \a endLine (inclusive). The fragment is
+ * stored in \a result. If FALSE is returned the code fragment could not be
+ * found.
+ *
+ * The file is scanned for a opening bracket ('{') from \a startLine onward
+ * The line actually containing the bracket is returned via startLine.
+ * The file is scanned for a closing bracket ('}') from \a endLine backward.
+ * The line actually containing the bracket is returned via endLine.
+ * Note that for VHDL code the bracket search is not done.
+ */
+bool readCodeFragment(const char *fileName,
+ int &startLine,int &endLine,QCString &result)
+{
+ static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
+ static int tabSize = Config_getInt("TAB_SIZE");
+ //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine);
+ if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name
+ QCString filter = getFileFilter(fileName,TRUE);
+ FILE *f=0;
+ bool usePipe = !filter.isEmpty() && filterSourceFiles;
+ SrcLangExt lang = getLanguageFromFileName(fileName);
+ if (!usePipe) // no filter given or wanted
+ {
+ f = portable_fopen(fileName,"r");
+ }
+ else // use filter
+ {
+ QCString cmd=filter+" \""+fileName+"\"";
+ Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
+ f = portable_popen(cmd,"r");
+ }
+ bool found = lang==SrcLangExt_VHDL ||
+ lang==SrcLangExt_Tcl ||
+ lang==SrcLangExt_Python ||
+ lang==SrcLangExt_Fortran;
+ // for VHDL, TCL, Python, and Fortran no bracket search is possible
+ if (f)
+ {
+ int c=0;
+ int col=0;
+ int lineNr=1;
+ // skip until the startLine has reached
+ while (lineNr<startLine && !feof(f))
+ {
+ while ((c=fgetc(f))!='\n' && c!=EOF) /* skip */;
+ lineNr++;
+ }
+ if (!feof(f))
+ {
+ // skip until the opening bracket or lonely : is found
+ char cn=0;
+ while (lineNr<=endLine && !feof(f) && !found)
+ {
+ int pc=0;
+ while ((c=fgetc(f))!='{' && c!=':' && c!=EOF)
+ {
+ //printf("parsing char `%c'\n",c);
+ if (c=='\n')
+ {
+ lineNr++,col=0;
+ }
+ else if (c=='\t')
+ {
+ col+=tabSize - (col%tabSize);
+ }
+ else if (pc=='/' && c=='/') // skip single line comment
+ {
+ while ((c=fgetc(f))!='\n' && c!=EOF) pc=c;
+ if (c=='\n') lineNr++,col=0;
+ }
+ else if (pc=='/' && c=='*') // skip C style comment
+ {
+ while (((c=fgetc(f))!='/' || pc!='*') && c!=EOF)
+ {
+ if (c=='\n') lineNr++,col=0;
+ pc=c;
+ }
+ }
+ else
+ {
+ col++;
+ }
+ pc = c;
+ }
+ if (c==':')
+ {
+ cn=fgetc(f);
+ if (cn!=':') found=TRUE;
+ }
+ else if (c=='{') // } so vi matching brackets has no problem
+ {
+ found=TRUE;
+ }
+ }
+ //printf(" -> readCodeFragment(%s,%d,%d) lineNr=%d\n",fileName,startLine,endLine,lineNr);
+ if (found)
+ {
+ // For code with more than one line,
+ // fill the line with spaces until we are at the right column
+ // so that the opening brace lines up with the closing brace
+ if (endLine!=startLine)
+ {
+ QCString spaces;
+ spaces.fill(' ',col);
+ result+=spaces;
+ }
+ // copy until end of line
+ result+=c;
+ startLine=lineNr;
+ if (c==':')
+ {
+ result+=cn;
+ if (cn=='\n') lineNr++;
+ }
+ const int maxLineLength=4096;
+ char lineStr[maxLineLength];
+ do
+ {
+ //printf("reading line %d in range %d-%d\n",lineNr,startLine,endLine);
+ int size_read;
+ do
+ {
+ // read up to maxLineLength-1 bytes, the last byte being zero
+ char *p = fgets(lineStr, maxLineLength,f);
+ //printf(" read %s",p);
+ if (p)
+ {
+ size_read=qstrlen(p);
+ }
+ else // nothing read
+ {
+ size_read=-1;
+ lineStr[0]='\0';
+ }
+ result+=lineStr;
+ } while (size_read == (maxLineLength-1));
+
+ lineNr++;
+ } while (lineNr<=endLine && !feof(f));
+
+ // strip stuff after closing bracket
+ int newLineIndex = result.findRev('\n');
+ int braceIndex = result.findRev('}');
+ if (braceIndex > newLineIndex)
+ {
+ result.truncate(braceIndex+1);
+ }
+ endLine=lineNr-1;
+ }
+ }
+ if (usePipe)
+ {
+ portable_pclose(f);
+ Debug::print(Debug::FilterOutput, 0, "Filter output\n");
+ Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",result.data());
+ }
+ else
+ {
+ fclose(f);
+ }
+ }
+ result = transcodeCharacterStringToUTF8(result);
+ //fprintf(stderr,"readCodeFragement(%d-%d)=%s\n",startLine,endLine,result.data());
+ return found;
+}
+
+QCString Definition::getSourceFileBase() const
+{
+ ASSERT(definitionType()!=Definition::TypeFile); // file overloads this method
+ QCString fn;
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ if (sourceBrowser &&
+ m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->fileDef)
+ {
+ fn = m_impl->body->fileDef->getSourceFileBase();
+ }
+ return fn;
+}
+
+QCString Definition::getSourceAnchor() const
+{
+ QCString anchorStr;
+ if (m_impl->body && m_impl->body->startLine!=-1)
+ {
+ if (Htags::useHtags)
+ {
+ anchorStr.sprintf("L%d",m_impl->body->startLine);
+ }
+ else
+ {
+ anchorStr.sprintf("l%05d",m_impl->body->startLine);
+ }
+ }
+ return anchorStr;
+}
+
+/*! Write a reference to the source code defining this definition */
+void Definition::writeSourceDef(OutputList &ol,const char *)
+{
+ static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
+ ol.pushGeneratorState();
+ //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef);
+ QCString fn = getSourceFileBase();
+ if (!fn.isEmpty())
+ {
+ QCString refText = theTranslator->trDefinedAtLineInSourceFile();
+ int lineMarkerPos = refText.find("@0");
+ int fileMarkerPos = refText.find("@1");
+ if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this.
+ {
+ QCString lineStr;
+ lineStr.sprintf("%d",m_impl->body->startLine);
+ QCString anchorStr = getSourceAnchor();
+ ol.startParagraph();
+ if (lineMarkerPos<fileMarkerPos) // line marker before file marker
+ {
+ // write text left from linePos marker
+ ol.parseText(refText.left(lineMarkerPos));
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write line link (HTML, LaTeX optionally)
+ ol.writeObjectLink(0,fn,anchorStr,lineStr);
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write normal text (Man/RTF, Latex optionally)
+ ol.docify(lineStr);
+ ol.popGeneratorState();
+
+ // write text between markers
+ ol.parseText(refText.mid(lineMarkerPos+2,
+ fileMarkerPos-lineMarkerPos-2));
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write file link (HTML, LaTeX optionally)
+ ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name());
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write normal text (Man/RTF, Latex optionally)
+ ol.docify(m_impl->body->fileDef->name());
+ ol.popGeneratorState();
+
+ // write text right from file marker
+ ol.parseText(refText.right(
+ refText.length()-fileMarkerPos-2));
+ }
+ else // file marker before line marker
+ {
+ // write text left from file marker
+ ol.parseText(refText.left(fileMarkerPos));
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write file link (HTML only)
+ ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name());
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write normal text (Latex/Man only)
+ ol.docify(m_impl->body->fileDef->name());
+ ol.popGeneratorState();
+
+ // write text between markers
+ ol.parseText(refText.mid(fileMarkerPos+2,
+ lineMarkerPos-fileMarkerPos-2));
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ ol.disableAllBut(OutputGenerator::Html);
+ // write line link (HTML only)
+ ol.writeObjectLink(0,fn,anchorStr,lineStr);
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ // write normal text (Latex/Man only)
+ ol.docify(lineStr);
+ ol.popGeneratorState();
+
+ // write text right from linePos marker
+ ol.parseText(refText.right(
+ refText.length()-lineMarkerPos-2));
+ }
+ ol.endParagraph();
+ }
+ else
+ {
+ err("translation error: invalid markers in trDefinedInSourceFile()\n");
+ }
+ }
+ ol.popGeneratorState();
+}
+
+void Definition::setBodySegment(int bls,int ble)
+{
+ //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data());
+ if (m_impl->body==0) m_impl->body = new BodyInfo;
+ m_impl->body->startLine=bls;
+ m_impl->body->endLine=ble;
+}
+
+void Definition::setBodyDef(FileDef *fd)
+{
+ if (m_impl->body==0) m_impl->body = new BodyInfo;
+ m_impl->body->fileDef=fd;
+}
+
+bool Definition::hasSources() const
+{
+ return m_impl->body && m_impl->body->startLine!=-1 &&
+ m_impl->body->endLine>=m_impl->body->startLine &&
+ m_impl->body->fileDef;
+}
+
+/*! Write code of this definition into the documentation */
+void Definition::writeInlineCode(OutputList &ol,const char *scopeName)
+{
+ static bool inlineSources = Config_getBool("INLINE_SOURCES");
+ ol.pushGeneratorState();
+ //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(),
+ // m_startBodyLine,m_endBodyLine,m_bodyDef);
+ if (inlineSources && hasSources())
+ {
+ QCString codeFragment;
+ int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine;
+ if (readCodeFragment(m_impl->body->fileDef->absFilePath(),
+ actualStart,actualEnd,codeFragment)
+ )
+ {
+ //printf("Adding code fragement '%s' ext='%s'\n",
+ // codeFragment.data(),m_impl->defFileExt.data());
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(m_impl->defFileExt);
+ pIntf->resetCodeParserState();
+ //printf("Read:\n`%s'\n\n",codeFragment.data());
+ MemberDef *thisMd = 0;
+ if (definitionType()==TypeMember) thisMd = (MemberDef *)this;
+
+ ol.startCodeFragment();
+ pIntf->parseCode(ol, // codeOutIntf
+ scopeName, // scope
+ codeFragment, // input
+ m_impl->lang, // lang
+ FALSE, // isExample
+ 0, // exampleName
+ m_impl->body->fileDef, // fileDef
+ actualStart, // startLine
+ actualEnd, // endLine
+ TRUE, // inlineFragment
+ thisMd, // memberDef
+ TRUE // show line numbers
+ );
+ ol.endCodeFragment();
+ }
+ }
+ ol.popGeneratorState();
+}
+
+/*! Write a reference to the source code fragments in which this
+ * definition is used.
+ */
+void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
+ const QCString &text,MemberSDict *members,bool /*funcOnly*/)
+{
+ static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ static bool refLinkSource = Config_getBool("REFERENCES_LINK_SOURCE");
+ ol.pushGeneratorState();
+ if (members)
+ {
+ members->sort();
+
+ ol.startParagraph();
+ ol.parseText(text);
+ ol.docify(" ");
+
+ QCString ldefLine=theTranslator->trWriteList(members->count());
+
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1)
+ {
+ bool ok;
+ ol.parseText(ldefLine.mid(index,newIndex-index));
+ uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ MemberDef *md=members->at(entryIndex);
+ if (ok && md)
+ {
+ QCString scope=md->getScopeString();
+ QCString name=md->name();
+ //printf("class=%p scope=%s scopeName=%s\n",md->getClassDef(),scope.data(),scopeName);
+ if (!scope.isEmpty() && scope!=scopeName)
+ {
+ name.prepend(scope+getLanguageSpecificSeparator(m_impl->lang));
+ }
+ if (!md->isObjCMethod() &&
+ (md->isFunction() || md->isSlot() ||
+ md->isPrototype() || md->isSignal()
+ )
+ )
+ {
+ name+="()";
+ }
+ //Definition *d = md->getOutputFileBase();
+ //if (d==Doxygen::globalScope) d=md->getBodyDef();
+ if (sourceBrowser &&
+ !(md->isLinkable() && !refLinkSource) &&
+ md->getStartBodyLine()!=-1 &&
+ md->getBodyDef()
+ )
+ {
+ //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope);
+ // for HTML write a real link
+ ol.pushGeneratorState();
+ //ol.disableAllBut(OutputGenerator::Html);
+
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ QCString lineStr,anchorStr;
+ anchorStr.sprintf("l%05d",md->getStartBodyLine());
+ //printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data());
+ ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name);
+ ol.popGeneratorState();
+
+ // for the other output formats just mention the name
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ ol.docify(name);
+ ol.popGeneratorState();
+ }
+ else if (md->isLinkable() /*&& d && d->isLinkable()*/)
+ {
+ // for HTML write a real link
+ ol.pushGeneratorState();
+ //ol.disableAllBut(OutputGenerator::Html);
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+
+ ol.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),name);
+ ol.popGeneratorState();
+
+ // for the other output formats just mention the name
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ if (latexSourceCode)
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ ol.docify(name);
+ ol.popGeneratorState();
+ }
+ else
+ {
+ ol.docify(name);
+ }
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(ldefLine.right(ldefLine.length()-index));
+ ol.writeString(".");
+ ol.endParagraph();
+ }
+ ol.popGeneratorState();
+}
+
+void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName)
+{
+ if (Config_getBool("REFERENCED_BY_RELATION"))
+ {
+ _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE);
+ }
+}
+
+void Definition::writeSourceRefs(OutputList &ol,const char *scopeName)
+{
+ if (Config_getBool("REFERENCES_RELATION"))
+ {
+ _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE);
+ }
+}
+
+bool Definition::hasDocumentation() const
+{
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ //static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ bool hasDocs =
+ (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs
+ (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description
+ (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty()) || // has inbody docs
+ extractAll //|| // extract everything
+ // (sourceBrowser && m_impl->body &&
+ // m_impl->body->startLine!=-1 && m_impl->body->fileDef)
+ ; // link to definition
+ return hasDocs;
+}
+
+bool Definition::hasUserDocumentation() const
+{
+ bool hasDocs =
+ (m_impl->details && !m_impl->details->doc.isEmpty()) ||
+ (m_impl->brief && !m_impl->brief->doc.isEmpty()) ||
+ (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty());
+ return hasDocs;
+}
+
+
+void Definition::addSourceReferencedBy(MemberDef *md)
+{
+ if (md)
+ {
+ QCString name = md->name();
+ QCString scope = md->getScopeString();
+
+ if (!scope.isEmpty())
+ {
+ name.prepend(scope+"::");
+ }
+
+ if (m_impl->sourceRefByDict==0)
+ {
+ m_impl->sourceRefByDict = new MemberSDict;
+ }
+ if (m_impl->sourceRefByDict->find(name)==0)
+ {
+ m_impl->sourceRefByDict->append(name,md);
+ }
+ }
+}
+
+void Definition::addSourceReferences(MemberDef *md)
+{
+ QCString name = md->name();
+ QCString scope = md->getScopeString();
+
+ if (md)
+ {
+ QCString name = md->name();
+ QCString scope = md->getScopeString();
+
+ if (!scope.isEmpty())
+ {
+ name.prepend(scope+"::");
+ }
+
+ if (m_impl->sourceRefsDict==0)
+ {
+ m_impl->sourceRefsDict = new MemberSDict;
+ }
+ if (m_impl->sourceRefsDict->find(name)==0)
+ {
+ m_impl->sourceRefsDict->append(name,md);
+ }
+ }
+}
+
+Definition *Definition::findInnerCompound(const char *)
+{
+ return 0;
+}
+
+void Definition::addInnerCompound(Definition *)
+{
+ err("Definition::addInnerCompound() called\n");
+}
+
+QCString Definition::qualifiedName() const
+{
+ //static int count=0;
+ //count++;
+ if (!m_impl->qualifiedName.isEmpty())
+ {
+ //count--;
+ return m_impl->qualifiedName;
+ }
+
+ //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data());
+ if (m_impl->outerScope==0)
+ {
+ if (m_impl->localName=="<globalScope>")
+ {
+ //count--;
+ return "";
+ }
+ else
+ {
+ //count--;
+ return m_impl->localName;
+ }
+ }
+
+ if (m_impl->outerScope->name()=="<globalScope>")
+ {
+ m_impl->qualifiedName = m_impl->localName;
+ }
+ else
+ {
+ m_impl->qualifiedName = m_impl->outerScope->qualifiedName()+
+ getLanguageSpecificSeparator(getLanguage())+
+ m_impl->localName;
+ }
+ //printf("end %s::qualifiedName()=%s\n",name().data(),m_impl->qualifiedName.data());
+ //count--;
+ return m_impl->qualifiedName;
+}
+
+void Definition::setOuterScope(Definition *d)
+{
+ //printf("%s::setOuterScope(%s)\n",name().data(),d?d->name().data():"<none>");
+ Definition *p = m_impl->outerScope;
+ bool found=false;
+ // make sure that we are not creating a recursive scope relation.
+ while (p && !found)
+ {
+ found = (p==d);
+ p = p->m_impl->outerScope;
+ }
+ if (!found)
+ {
+ m_impl->qualifiedName.resize(0); // flush cached scope name
+ m_impl->outerScope = d;
+ }
+ m_impl->hidden = m_impl->hidden || d->isHidden();
+}
+
+QCString Definition::localName() const
+{
+ return m_impl->localName;
+}
+
+void Definition::makePartOfGroup(GroupDef *gd)
+{
+ if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList;
+ m_impl->partOfGroups->append(gd);
+}
+
+void Definition::setRefItems(const QList<ListItemInfo> *sli)
+{
+ //printf("%s::setRefItems()\n",name().data());
+ if (sli)
+ {
+ // deep copy the list
+ if (m_impl->xrefListItems==0)
+ {
+ m_impl->xrefListItems=new QList<ListItemInfo>;
+ m_impl->xrefListItems->setAutoDelete(TRUE);
+ }
+ QListIterator<ListItemInfo> slii(*sli);
+ ListItemInfo *lii;
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ m_impl->xrefListItems->append(new ListItemInfo(*lii));
+ }
+ }
+}
+
+void Definition::mergeRefItems(Definition *d)
+{
+ //printf("%s::mergeRefItems()\n",name().data());
+ QList<ListItemInfo> *xrefList = d->xrefListItems();
+ if (xrefList!=0)
+ {
+ // deep copy the list
+ if (m_impl->xrefListItems==0)
+ {
+ m_impl->xrefListItems=new QList<ListItemInfo>;
+ m_impl->xrefListItems->setAutoDelete(TRUE);
+ }
+ QListIterator<ListItemInfo> slii(*xrefList);
+ ListItemInfo *lii;
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ if (_getXRefListId(lii->type)==-1)
+ {
+ m_impl->xrefListItems->append(new ListItemInfo(*lii));
+ }
+ }
+ }
+}
+
+int Definition::_getXRefListId(const char *listName) const
+{
+ if (m_impl->xrefListItems)
+ {
+ QListIterator<ListItemInfo> slii(*m_impl->xrefListItems);
+ ListItemInfo *lii;
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ if (qstrcmp(lii->type,listName)==0)
+ {
+ return lii->itemId;
+ }
+ }
+ }
+ return -1;
+}
+
+QList<ListItemInfo> *Definition::xrefListItems() const
+{
+ return m_impl->xrefListItems;
+}
+
+
+QCString Definition::convertNameToFile(const char *name,bool allowDots) const
+{
+ if (!m_impl->ref.isEmpty())
+ {
+ return name;
+ }
+ else
+ {
+ return ::convertNameToFile(name,allowDots);
+ }
+}
+
+QCString Definition::pathFragment() const
+{
+ QCString result;
+ if (m_impl->outerScope && m_impl->outerScope!=Doxygen::globalScope)
+ {
+ result = m_impl->outerScope->pathFragment();
+ }
+ if (isLinkable())
+ {
+ if (!result.isEmpty()) result+="/";
+ if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
+ {
+ result+=((const GroupDef*)this)->groupTitle();
+ }
+ else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
+ {
+ result+=((const PageDef*)this)->title();
+ }
+ else
+ {
+ result+=m_impl->localName;
+ }
+ }
+ else
+ {
+ result+=m_impl->localName;
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+
+// TODO: move to htmlgen
+/*! Returns the string used in the footer for $navpath when
+ * GENERATE_TREEVIEW is enabled
+ */
+QCString Definition::navigationPathAsString() const
+{
+ QCString result;
+ Definition *outerScope = getOuterScope();
+ QCString locName = localName();
+ if (outerScope && outerScope!=Doxygen::globalScope)
+ {
+ result+=outerScope->navigationPathAsString();
+ }
+ else if (definitionType()==Definition::TypeFile && ((const FileDef*)this)->getDirDef())
+ {
+ result+=((const FileDef*)this)->getDirDef()->navigationPathAsString();
+ }
+ result+="<li class=\"navelem\">";
+ if (isLinkable())
+ {
+ if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle())
+ {
+ result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
+ ((const GroupDef*)this)->groupTitle()+"</a>";
+ }
+ else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty())
+ {
+ result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
+ ((const PageDef*)this)->title()+"</a>";
+ }
+ else if (definitionType()==Definition::TypeClass)
+ {
+ QCString name = locName;
+ if (name.right(2)=="-p" /*|| name.right(2)=="-g"*/)
+ {
+ name = name.left(name.length()-2);
+ }
+ result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension;
+ if (!anchor().isEmpty()) result+="#"+anchor();
+ result+="\">"+name+"</a>";
+ }
+ else
+ {
+ result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+
+ locName+"</a>";
+ }
+ }
+ else
+ {
+ result+="<b>"+locName+"</b>";
+ }
+ result+="</li>";
+ return result;
+}
+
+// TODO: move to htmlgen
+void Definition::writeNavigationPath(OutputList &ol) const
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString navPath;
+ navPath += "<div id=\"nav-path\" class=\"navpath\">\n"
+ " <ul>\n";
+ navPath += navigationPathAsString();
+ navPath += " </ul>\n"
+ "</div>\n";
+ ol.writeNavigationPath(navPath);
+
+ ol.popGeneratorState();
+}
+
+// TODO: move to htmlgen
+void Definition::writeToc(OutputList &ol)
+{
+ SectionDict *sectionDict = m_impl->sectionDict;
+ if (sectionDict==0) return;
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString("<div class=\"toc\">");
+ ol.writeString("<h3>");
+ ol.writeString(theTranslator->trRTFTableOfContents());
+ ol.writeString("</h3>\n");
+ ol.writeString("<ul>");
+ SDict<SectionInfo>::Iterator li(*sectionDict);
+ SectionInfo *si;
+ int level=1,l;
+ char cs[2];
+ cs[1]='\0';
+ bool inLi[5]={ FALSE, FALSE, FALSE, FALSE };
+ for (li.toFirst();(si=li.current());++li)
+ {
+ if (si->type==SectionInfo::Section ||
+ si->type==SectionInfo::Subsection ||
+ si->type==SectionInfo::Subsubsection ||
+ si->type==SectionInfo::Paragraph)
+ {
+ //printf(" level=%d title=%s\n",level,si->title.data());
+ int nextLevel = (int)si->type;
+ if (nextLevel>level)
+ {
+ for (l=level;l<nextLevel;l++)
+ {
+ ol.writeString("<ul>");
+ }
+ }
+ else if (nextLevel<level)
+ {
+ for (l=level;l>nextLevel;l--)
+ {
+ if (inLi[l]) ol.writeString("</li>\n");
+ inLi[l]=FALSE;
+ ol.writeString("</ul>\n");
+ }
+ }
+ cs[0]='0'+nextLevel;
+ if (inLi[nextLevel]) ol.writeString("</li>\n");
+ ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+si->title+"</a>");
+ inLi[nextLevel]=TRUE;
+ level = nextLevel;
+ }
+ }
+ while (level>1)
+ {
+ if (inLi[level]) ol.writeString("</li>\n");
+ inLi[level]=FALSE;
+ ol.writeString("</ul>\n");
+ level--;
+ }
+ if (inLi[level]) ol.writeString("</li>\n");
+ inLi[level]=FALSE;
+ ol.writeString("</ul>\n");
+ ol.writeString("</div>\n");
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------------------
+
+
+QCString Definition::symbolName() const
+{
+ return m_symbolName;
+}
+
+//----------------------
+
+QCString Definition::documentation() const
+{
+ return m_impl->details ? m_impl->details->doc : QCString("");
+}
+
+int Definition::docLine() const
+{
+ return m_impl->details ? m_impl->details->line : 1;
+}
+
+QCString Definition::docFile() const
+{
+ return m_impl->details ? m_impl->details->file : QCString("<"+m_name+">");
+}
+
+//----------------------------------------------------------------------------
+// strips w from s iff s starts with w
+static bool stripWord(QCString &s,QCString w)
+{
+ bool success=FALSE;
+ if (s.left(w.length())==w)
+ {
+ success=TRUE;
+ s=s.right(s.length()-w.length());
+ }
+ return success;
+}
+
+//----------------------------------------------------------------------------
+// some quasi intelligent brief description abbreviator :^)
+QCString abbreviate(const char *s,const char *name)
+{
+ QCString scopelessName=name;
+ int i=scopelessName.findRev("::");
+ if (i!=-1) scopelessName=scopelessName.mid(i+2);
+ QCString result=s;
+ result=result.stripWhiteSpace();
+ // strip trailing .
+ if (!result.isEmpty() && result.at(result.length()-1)=='.')
+ result=result.left(result.length()-1);
+
+ // strip any predefined prefix
+ QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
+ const char *p = briefDescAbbrev.first();
+ while (p)
+ {
+ QCString s = p;
+ s.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name
+ s += " ";
+ stripWord(result,s);
+ p = briefDescAbbrev.next();
+ }
+
+ // capitalize first word
+ if (!result.isEmpty())
+ {
+ int c=result[0];
+ if (c>='a' && c<='z') c+='A'-'a';
+ result[0]=c;
+ }
+ return result;
+}
+
+
+//----------------------
+
+QCString Definition::briefDescription(bool abbr) const
+{
+ //printf("%s::briefDescription(%d)='%s'\n",name().data(),abbr,m_impl->brief?m_impl->brief->doc.data():"<none>");
+ return m_impl->brief ?
+ (abbr ? abbreviate(m_impl->brief->doc,displayName()) : m_impl->brief->doc) :
+ QCString("");
+}
+
+QCString Definition::briefDescriptionAsTooltip() const
+{
+ if (m_impl->brief)
+ {
+ if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty())
+ {
+ static bool reentering=FALSE;
+ if (!reentering)
+ {
+ MemberDef *md = definitionType()==TypeMember ? (MemberDef*)this : 0;
+ const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this;
+ reentering=TRUE; // prevent requests for tooltips while parsing a tooltip
+ m_impl->brief->tooltip = parseCommentAsText(
+ scope,md,
+ m_impl->brief->doc,
+ m_impl->brief->file,
+ m_impl->brief->line);
+ reentering=FALSE;
+ }
+ }
+ return m_impl->brief->tooltip;
+ }
+ return QCString("");
+}
+
+int Definition::briefLine() const
+{
+ return m_impl->brief ? m_impl->brief->line : 1;
+}
+
+QCString Definition::briefFile() const
+{
+ return m_impl->brief ? m_impl->brief->file : QCString("<"+m_name+">");
+}
+
+//----------------------
+
+QCString Definition::inbodyDocumentation() const
+{
+ return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString("");
+}
+
+int Definition::inbodyLine() const
+{
+ return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1;
+}
+
+QCString Definition::inbodyFile() const
+{
+ return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_name+">");
+}
+
+
+//----------------------
+
+QCString Definition::getDefFileName() const
+{
+ return m_impl->defFileName;
+}
+
+QCString Definition::getDefFileExtension() const
+{
+ return m_impl->defFileExt;
+}
+
+bool Definition::isHidden() const
+{
+ return m_impl->hidden;
+}
+
+bool Definition::isVisibleInProject() const
+{
+ return isLinkableInProject() && !m_impl->hidden;
+}
+
+bool Definition::isVisible() const
+{
+ return isLinkable() && !m_impl->hidden;
+}
+
+bool Definition::isArtificial() const
+{
+ return m_impl->isArtificial;
+}
+
+QCString Definition::getReference() const
+{
+ return m_impl->ref;
+}
+
+bool Definition::isReference() const
+{
+ return !m_impl->ref.isEmpty();
+}
+
+int Definition::getStartBodyLine() const
+{
+ return m_impl->body ? m_impl->body->startLine : -1;
+}
+
+int Definition::getEndBodyLine() const
+{
+ return m_impl->body ? m_impl->body->endLine : -1;
+}
+
+FileDef *Definition::getBodyDef() const
+{
+ return m_impl->body ? m_impl->body->fileDef : 0;
+}
+
+GroupList *Definition::partOfGroups() const
+{
+ return m_impl->partOfGroups;
+}
+
+Definition *Definition::getOuterScope() const
+{
+ return m_impl->outerScope;
+}
+
+MemberSDict *Definition::getReferencesMembers() const
+{
+ return m_impl->sourceRefsDict;
+}
+
+MemberSDict *Definition::getReferencedByMembers() const
+{
+ return m_impl->sourceRefByDict;
+}
+
+void Definition::setReference(const char *r)
+{
+ m_impl->ref=r;
+}
+
+SrcLangExt Definition::getLanguage() const
+{
+ return m_impl->lang;
+}
+
+void Definition::setHidden(bool b)
+{
+ m_impl->hidden = m_impl->hidden || b;
+}
+
+void Definition::setArtificial(bool b)
+{
+ m_impl->isArtificial = b;
+}
+
+void Definition::setLocalName(const QCString name)
+{
+ m_impl->localName=name;
+}
+
+void Definition::setLanguage(SrcLangExt lang)
+{
+ m_impl->lang=lang;
+}
+
+
+void Definition::_setSymbolName(const QCString &name)
+{
+ m_symbolName=name;
+}
+
+bool Definition::hasBriefDescription() const
+{
+ static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
+ return !briefDescription().isEmpty() && briefMemberDesc;
+}
+
+
diff --git a/src/definition.h b/src/definition.h
new file mode 100644
index 0000000..05ea621
--- /dev/null
+++ b/src/definition.h
@@ -0,0 +1,398 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DEFINITION_H
+#define DEFINITION_H
+
+#include <qlist.h>
+#include <qdict.h>
+
+#include "types.h"
+
+class FileDef;
+class OutputList;
+class SectionDict;
+class MemberSDict;
+class MemberDef;
+class GroupDef;
+class GroupList;
+struct ListItemInfo;
+struct SectionInfo;
+class Definition;
+class DefinitionImpl;
+
+/** Data associated with a detailed description. */
+struct DocInfo
+{
+ QCString doc;
+ int line;
+ QCString file;
+};
+
+/** Data associated with a brief description. */
+struct BriefInfo
+{
+ QCString doc;
+ QCString tooltip;
+ int line;
+ QCString file;
+};
+
+/** Data associated with description found in the body. */
+struct BodyInfo
+{
+ int startLine; //!< line number of the start of the definition
+ int endLine; //!< line number of the end of the definition
+ FileDef *fileDef; //!< file definition containing the function body
+};
+
+/** Abstract interface for a Definition or DefinitionList */
+class DefinitionIntf
+{
+ public:
+ DefinitionIntf() {}
+ virtual ~DefinitionIntf() {}
+ /*! Types of derived classes */
+ enum DefType
+ {
+ TypeClass = 0,
+ TypeFile = 1,
+ TypeNamespace = 2,
+ TypeMember = 3,
+ TypeGroup = 4,
+ TypePackage = 5,
+ TypePage = 6,
+ TypeDir = 7,
+ TypeSymbolList = 8
+ };
+ /*! Use this for dynamic inspection of the type of the derived class */
+ virtual DefType definitionType() const = 0;
+};
+
+/** The common base class of all entity definitions found in the sources.
+ *
+ * This can be a class or a member function, or a file, or a namespace, etc.
+ * Use definitionType() to find which type of definition this is.
+ */
+class Definition : public DefinitionIntf
+{
+ public:
+
+ /*! Create a new definition */
+ Definition(
+ const char *defFileName,int defLine,int defColumn,
+ const char *name,const char *b=0,const char *d=0,
+ bool isSymbol=TRUE);
+
+ /*! Destroys the definition */
+ virtual ~Definition();
+
+ //-----------------------------------------------------------------------------------
+ // ---- getters -----
+ //-----------------------------------------------------------------------------------
+
+ /*! Returns the name of the definition */
+ const QCString& name() const { return m_name; }
+
+ /*! Returns the name of the definition as it appears in the output */
+ virtual QCString displayName(bool includeScope=TRUE) const = 0;
+
+ /*! Returns the local name without any scope qualifiers. */
+ QCString localName() const;
+
+ /*! Returns the fully qualified name of this definition
+ */
+ virtual QCString qualifiedName() const;
+
+ /*! Returns the name of this definition as it appears in the symbol map.
+ */
+ QCString symbolName() const;
+
+ /*! Returns the base file name (without extension) of this definition.
+ * as it is referenced to/written to disk.
+ */
+ virtual QCString getOutputFileBase() const = 0;
+
+ /*! Returns the anchor within a page where this item can be found */
+ virtual QCString anchor() const = 0;
+
+ /*! Returns the name of the source listing of this definition. */
+ virtual QCString getSourceFileBase() const;
+
+ /*! Returns the anchor of the source listing of this definition. */
+ virtual QCString getSourceAnchor() const;
+
+ /*! Returns the detailed description of this definition */
+ virtual QCString documentation() const;
+
+ /*! Returns the line number at which the detailed documentation was found. */
+ int docLine() const;
+
+ /*! Returns the file in which the detailed documentation block was found.
+ * This can differ from getDefFileName().
+ */
+ QCString docFile() const;
+
+ /*! Returns the brief description of this definition. This can include commands. */
+ virtual QCString briefDescription(bool abbreviate=FALSE) const;
+
+ /*! Returns a plain text version of the brief description suitable for use
+ * as a tool tip.
+ */
+ QCString briefDescriptionAsTooltip() const;
+
+ /*! Returns the line number at which the brief description was found. */
+ int briefLine() const;
+
+ /*! Returns the documentation found inside the body of a member */
+ QCString inbodyDocumentation() const;
+
+ /*! Returns the file in which the in body documentation was found */
+ QCString inbodyFile() const;
+
+ /*! Returns the line at which the first in body documentation
+ part was found */
+ int inbodyLine() const;
+
+ /*! Returns the file in which the brief description was found.
+ * This can differ from getDefFileName().
+ */
+ QCString briefFile() const;
+
+ /*! returns the file in which this definition was found */
+ QCString getDefFileName() const;
+
+ /*! returns the extension of the file in which this definition was found */
+ QCString getDefFileExtension() const;
+
+ /*! returns the line number at which the definition was found */
+ int getDefLine() const { return m_defLine; }
+
+ /*! returns the column number at which the definition was found */
+ int getDefColumn() const { return m_defColumn; }
+
+ /*! Returns TRUE iff the definition is documented
+ * (which could be generated documentation)
+ * @see hasUserDocumentation()
+ */
+ virtual bool hasDocumentation() const;
+
+ /*! Returns TRUE iff the definition is documented by the user. */
+ virtual bool hasUserDocumentation() const;
+
+ /*! Returns TRUE iff it is possible to link to this item within this
+ * project.
+ */
+ virtual bool isLinkableInProject() const = 0;
+
+ /*! Returns TRUE iff it is possible to link to this item. This can
+ * be a link to another project imported via a tag file.
+ */
+ virtual bool isLinkable() const = 0;
+
+ /*! Returns TRUE iff the name is part of this project and
+ * may appear in the output
+ */
+ virtual bool isVisibleInProject() const;
+
+ /*! Returns TRUE iff the name may appear in the output */
+ virtual bool isVisible() const;
+
+ /*! Returns TRUE iff this item is supposed to be hidden from the output. */
+ bool isHidden() const;
+
+ /*! returns TRUE if this entity was artificially introduced, for
+ * instance because it is used to show a template instantiation relation.
+ */
+ bool isArtificial() const;
+
+ /*! If this definition was imported via a tag file, this function
+ * returns the tagfile for the external project. This can be
+ * translated into an external link target via
+ * Doxygen::tagDestinationDict
+ */
+ virtual QCString getReference() const;
+
+ /*! Returns TRUE if this definition is imported via a tag file. */
+ virtual bool isReference() const;
+
+ /*! Returns the first line of the body of this item (applicable to classes and
+ * functions).
+ */
+ int getStartBodyLine() const;
+
+ /*! Returns the last line of the body of this item (applicable to classes and
+ * functions).
+ */
+ int getEndBodyLine() const;
+
+ /*! Returns the file in which the body of this item is located or 0 if no
+ * body is available.
+ */
+ FileDef *getBodyDef() const;
+
+ /** Returns the programming language this definition was written in. */
+ SrcLangExt getLanguage() const;
+
+ GroupList *partOfGroups() const;
+
+ QList<ListItemInfo> *xrefListItems() const;
+
+ virtual Definition *findInnerCompound(const char *name);
+ virtual Definition *getOuterScope() const;
+
+ MemberSDict *getReferencesMembers() const;
+ MemberSDict *getReferencedByMembers() const;
+
+ bool hasSections() const;
+ bool hasSources() const;
+
+ /** returns TRUE if this class has a brief description */
+ bool hasBriefDescription() const;
+
+ QCString id() const;
+
+ //-----------------------------------------------------------------------------------
+ // ---- setters -----
+ //-----------------------------------------------------------------------------------
+
+ /*! Sets a new \a name for the definition */
+ virtual void setName(const char *name);
+
+ /*! Sets a unique id for the symbol. Used for libclang integration. */
+ void setId(const char *name);
+
+ /*! Sets the documentation of this definition to \a d. */
+ virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE);
+
+ /*! Sets the brief description of this definition to \a b.
+ * A dot is added to the sentence if not available.
+ */
+ virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine);
+
+ /*! Set the documentation that was found inside the body of an item.
+ * If there was already some documentation set, the new documentation
+ * will be appended.
+ */
+ virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine);
+
+ /*! Sets the tag file id via which this definition was imported. */
+ void setReference(const char *r);
+
+ /*! Add the list of anchors that mark the sections that are found in the
+ * documentation.
+ */
+ void addSectionsToDefinition(QList<SectionInfo> *anchorList);
+
+ // source references
+ void setBodySegment(int bls,int ble);
+ void setBodyDef(FileDef *fd);
+ void addSourceReferencedBy(MemberDef *d);
+ void addSourceReferences(MemberDef *d);
+
+ void setRefItems(const QList<ListItemInfo> *sli);
+ void mergeRefItems(Definition *d);
+ virtual void addInnerCompound(Definition *d);
+ virtual void setOuterScope(Definition *d);
+
+ virtual void setHidden(bool b);
+
+ void setArtificial(bool b);
+ void setLanguage(SrcLangExt lang);
+
+ //-----------------------------------------------------------------------------------
+ // --- actions ----
+ //-----------------------------------------------------------------------------------
+
+ QCString convertNameToFile(const char *name,bool allowDots=FALSE) const;
+ void writeSourceDef(OutputList &ol,const char *scopeName);
+ void writeInlineCode(OutputList &ol,const char *scopeName);
+ void writeSourceRefs(OutputList &ol,const char *scopeName);
+ void writeSourceReffedBy(OutputList &ol,const char *scopeName);
+ void makePartOfGroup(GroupDef *gd);
+ //void writePathFragment(OutputList &ol) const;
+ void writeNavigationPath(OutputList &ol) const;
+ QCString navigationPathAsString() const;
+ virtual void writeQuickMemberLinks(OutputList &,MemberDef *) const {}
+ virtual void writeSummaryLinks(OutputList &) {}
+ QCString pathFragment() const;
+
+ /*! Writes the documentation anchors of the definition to
+ * the Doxygen::tagFile stream.
+ */
+ void writeDocAnchorsToTagFile();
+ void setLocalName(const QCString name);
+
+ void addSectionsToIndex();
+ void writeToc(OutputList &ol);
+
+ protected:
+
+ Definition(const Definition &d);
+
+ private:
+ static void addToMap(const char *name,Definition *d);
+ static void removeFromMap(Definition *d);
+
+ void _setSymbolName(const QCString &name);
+
+ int _getXRefListId(const char *listName) const;
+ void _writeSourceRefList(OutputList &ol,const char *scopeName,
+ const QCString &text,MemberSDict *members,bool);
+ void _setBriefDescription(const char *b,const char *briefFile,int briefLine);
+ void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace,bool atTop);
+ void _setInbodyDocumentation(const char *d,const char *docFile,int docLine);
+ bool _docsAlreadyAdded(const QCString &doc,QCString &sigList);
+ DefinitionImpl *m_impl; // internal structure holding all private data
+ QCString m_name;
+ bool m_isSymbol;
+ QCString m_symbolName;
+ int m_defLine;
+ int m_defColumn;
+};
+
+/** A list of Definition objects. */
+class DefinitionList : public QList<Definition>, public DefinitionIntf
+{
+ public:
+ ~DefinitionList() {}
+ DefType definitionType() const { return TypeSymbolList; }
+ int compareValues(const Definition *item1,const Definition *item2) const
+ {
+ return qstricmp(item1->name(),item2->name());
+ }
+
+};
+
+/** An iterator for Definition objects in a DefinitionList. */
+class DefinitionListIterator : public QListIterator<Definition>
+{
+ public:
+ DefinitionListIterator(const DefinitionList &l) :
+ QListIterator<Definition>(l) {}
+ ~DefinitionListIterator() {}
+};
+
+/** Reads a fragment from file \a fileName starting with line \a startLine
+ * and ending with line \a endLine. The result is returned as a string
+ * via \a result. The function returns TRUE if successful and FALSE
+ * in case of an error.
+ */
+bool readCodeFragment(const char *fileName,
+ int &startLine,int &endLine,
+ QCString &result);
+#endif
diff --git a/src/dia.cpp b/src/dia.cpp
new file mode 100644
index 0000000..955171c
--- /dev/null
+++ b/src/dia.cpp
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "dia.h"
+#include "portable.h"
+#include "config.h"
+#include "message.h"
+#include "util.h"
+
+#include <qdir.h>
+
+static const int maxCmdLine = 40960;
+
+void writeDiaGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,DiaOutputFormat format)
+{
+ QCString absOutFile = outDir;
+ absOutFile+=portable_pathSeparator();
+ absOutFile+=outFile;
+
+ // chdir to the output dir, so dot can find the font file.
+ QCString oldDir = QDir::currentDirPath().utf8();
+ // go to the html output directory (i.e. path)
+ QDir::setCurrent(outDir);
+ //printf("Going to dir %s\n",QDir::currentDirPath().data());
+ QCString diaExe = Config_getString("DIA_PATH")+"dia"+portable_commandExtension();
+ QCString diaArgs;
+ QCString extension;
+ diaArgs+="-n ";
+ if (format==DIA_BITMAP)
+ {
+ diaArgs+="-t png-libart";
+ extension=".png";
+ }
+ else if (format==DIA_EPS)
+ {
+ diaArgs+="-t eps";
+ extension=".eps";
+ }
+
+ diaArgs+=" -e \"";
+ diaArgs+=outFile;
+ diaArgs+=extension+"\"";
+
+ diaArgs+=" \"";
+ diaArgs+=inFile;
+ diaArgs+="\"";
+
+ int exitCode;
+ //printf("*** running: %s %s outDir:%s %s\n",diaExe.data(),diaArgs.data(),outDir,outFile);
+ portable_sysTimerStart();
+ if ((exitCode=portable_system(diaExe,diaArgs,FALSE))!=0)
+ {
+ portable_sysTimerStop();
+ goto error;
+ }
+ portable_sysTimerStop();
+ if ( (format==DIA_EPS) && (Config_getBool("USE_PDFLATEX")) )
+ {
+ QCString epstopdfArgs(maxCmdLine);
+ epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
+ outFile,outFile);
+ portable_sysTimerStart();
+ if (portable_system("epstopdf",epstopdfArgs)!=0)
+ {
+ err("Problems running epstopdf. Check your TeX installation!\n");
+ }
+ portable_sysTimerStop();
+ }
+
+error:
+ QDir::setCurrent(oldDir);
+}
+
diff --git a/src/dia.h b/src/dia.h
new file mode 100644
index 0000000..ca10332
--- /dev/null
+++ b/src/dia.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DIA_H
+#define _DIA_H
+
+class QCString;
+class FTextStream;
+
+enum DiaOutputFormat { DIA_BITMAP , DIA_EPS };
+
+void writeDiaGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,DiaOutputFormat format);
+
+#endif
+
diff --git a/src/diagram.cpp b/src/diagram.cpp
new file mode 100644
index 0000000..e50baec
--- /dev/null
+++ b/src/diagram.cpp
@@ -0,0 +1,1386 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <qlist.h>
+#include <qarray.h>
+#include "ftextstream.h"
+#include <qfile.h>
+
+#include "diagram.h"
+#include "image.h"
+#include "classdef.h"
+#include "config.h"
+#include "message.h"
+#include "util.h"
+#include "doxygen.h"
+#include "portable.h"
+#include "index.h"
+#include "classlist.h"
+
+//-----------------------------------------------------------------------------
+
+class DiagramItemList;
+
+/** Class representing a single node in the built-in class diagram */
+class DiagramItem
+{
+ public:
+ DiagramItem(DiagramItem *p,int number,ClassDef *cd,
+ Protection prot,Specifier virt,const char *ts);
+ ~DiagramItem();
+ QCString label() const;
+ QCString fileName() const;
+ DiagramItem *parentItem() { return parent; }
+ DiagramItemList *getChildren() { return children; }
+ void move(int dx,int dy) { x+=dx; y+=dy; }
+ int xPos() const { return x; }
+ int yPos() const { return y; }
+ int avgChildPos() const;
+ int numChildren() const;
+ void addChild(DiagramItem *di);
+ int number() const { return num; }
+ Protection protection() const { return prot; }
+ Specifier virtualness() const { return virt; }
+ void putInList() { inList=TRUE; }
+ bool isInList() const { return inList; }
+ ClassDef *getClassDef() const { return classDef; }
+ private:
+ DiagramItemList *children;
+ DiagramItem *parent;
+ int x,y;
+ int num;
+ Protection prot;
+ Specifier virt;
+ QCString templSpec;
+ bool inList;
+ ClassDef *classDef;
+};
+
+/** Class representing a list of DiagramItem object. */
+class DiagramItemList : public QList<DiagramItem>
+{
+ public:
+ DiagramItemList() : QList<DiagramItem>() {}
+ ~DiagramItemList() {}
+};
+
+/** Class representing a row in the built-in class diagram */
+class DiagramRow : public QList<DiagramItem>
+{
+ public:
+ DiagramRow(TreeDiagram *d,int l) : QList<DiagramItem>()
+ {
+ diagram=d;
+ level=l;
+ setAutoDelete(TRUE);
+ }
+ void insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,
+ Protection prot,Specifier virt,const char *ts);
+ uint number() { return level; }
+ private:
+ TreeDiagram *diagram;
+ uint level;
+};
+
+/** Class representing iterator for the rows in the built-in class diagram. */
+class DiagramRowIterator : public QListIterator<DiagramRow>
+{
+ public:
+ DiagramRowIterator(const QList<DiagramRow> &d)
+ : QListIterator<DiagramRow>(d) {}
+};
+
+/** Class represeting the tree layout for the built-in class diagram. */
+class TreeDiagram : public QList<DiagramRow>
+{
+ public:
+ TreeDiagram(ClassDef *root,bool doBases);
+ ~TreeDiagram();
+ void computeLayout();
+ uint computeRows();
+ //uint computeCols();
+ void moveChildren(DiagramItem *root,int dx);
+ void computeExtremes(uint *labelWidth,uint *xpos);
+ void drawBoxes(FTextStream &t,Image *image,
+ bool doBase,bool bitmap,
+ uint baseRows,uint superRows,
+ uint cellWidth,uint cellHeight,
+ QCString relPath="",
+ bool generateMap=TRUE);
+ void drawConnectors(FTextStream &t,Image *image,
+ bool doBase,bool bitmap,
+ uint baseRows,uint superRows,
+ uint cellWidth,uint cellheight);
+ private:
+ bool layoutTree(DiagramItem *root,int row);
+ TreeDiagram &operator=(const TreeDiagram &);
+ TreeDiagram(const TreeDiagram &);
+};
+
+
+
+//-----------------------------------------------------------------------------
+
+const uint maxTreeWidth = 8;
+const int gridWidth = 100;
+const int gridHeight = 100;
+
+const uint labelHorSpacing = 10; // horizontal distance between labels
+const uint labelVertSpacing = 32; // vertical distance between labels
+const uint labelHorMargin = 6; // horiz. spacing between label and box
+const uint fontHeight = 12; // height of a character
+
+//static QCString escapeLatex(const char *s)
+//{
+// QCString result;
+// char c;
+// while ((c=*s++))
+// {
+// if (c=='_') result+="\\_";
+// else result+=c;
+// }
+// return result;
+//}
+
+static uint protToMask(Protection p)
+{
+ switch(p)
+ {
+ case Public: return 0xffffffff;
+ case Package: // package is not possible!
+ case Protected: return 0xcccccccc;
+ case Private: return 0xaaaaaaaa;
+ }
+ return 0;
+}
+
+static uint protToColor(Protection p)
+{
+ switch(p)
+ {
+ case Public: return 6;
+ case Package: // package is not possible!
+ case Protected: return 5;
+ case Private: return 4;
+ }
+ return 0;
+}
+
+static QCString protToString(Protection p)
+{
+ switch(p)
+ {
+ case Public: return "solid";
+ case Package: // package is not possible!
+ case Protected: return "dashed";
+ case Private: return "dotted";
+ }
+ return 0;
+}
+
+static uint virtToMask(Specifier p)
+{
+ switch(p)
+ {
+ case Normal: return 0xffffffff;
+ case Virtual: return 0xf0f0f0f0;
+ default: return 0;
+ }
+ return 0;
+}
+
+// pre: dil is not empty
+static Protection getMinProtectionLevel(DiagramItemList *dil)
+{
+ QListIterator<DiagramItem> it(*dil);
+ DiagramItem *di=it.current();
+ Protection result=di->protection();
+ for (++it;(di=it.current());++it)
+ {
+ Protection p=di->protection();
+ if (p!=result)
+ {
+ if (result==Protected && p==Public) result=p;
+ else if (result==Private) result=p;
+ }
+ }
+ return result;
+}
+
+static void writeBitmapBox(DiagramItem *di,Image *image,
+ int x,int y,int w,int h,bool firstRow,
+ bool hasDocs,bool children=FALSE)
+{
+ int colFill = hasDocs ? (firstRow ? 0 : 2) : 7;
+ int colBorder = (firstRow || !hasDocs) ? 1 : 3;
+ int l = Image::stringLength(di->label());
+ uint mask=virtToMask(di->virtualness());
+ image->fillRect(x+1,y+1,w-2,h-2,colFill,mask);
+ image->drawRect(x,y,w,h,colBorder,mask);
+ image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1);
+ if (children)
+ {
+ int i;
+ for (i=0;i<5;i++)
+ image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff);
+ }
+}
+
+static void writeVectorBox(FTextStream &t,DiagramItem *di,
+ float x,float y,bool children=FALSE)
+{
+ if (di->virtualness()==Virtual) t << "dashed\n";
+ t << " (" << di->label() << ") " << x << " " << y << " box\n";
+ if (children) t << x << " " << y << " mark\n";
+ if (di->virtualness()==Virtual) t << "solid\n";
+}
+
+static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath,
+ int x,int y,int w,int h)
+{
+ if (cd->isLinkable())
+ {
+ QCString ref=cd->getReference();
+ t << "<area ";
+ if (!ref.isEmpty())
+ {
+ t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
+ }
+ t << "href=\"";
+ t << externalRef(relPath,ref,TRUE);
+ t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
+ if (!cd->anchor().isEmpty())
+ {
+ t << "#" << cd->anchor();
+ }
+ t << "\" ";
+ QCString tooltip = cd->briefDescriptionAsTooltip();
+ if (!tooltip.isEmpty())
+ {
+ t << "title=\"" << tooltip << "\" ";
+ }
+ t << "alt=\"" << convertToXML(cd->displayName());
+ t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
+ t << (x+w) << "," << (y+h) << "\"/>" << endl;
+ }
+}
+//-----------------------------------------------------------------------------
+
+DiagramItem::DiagramItem(DiagramItem *p,int number,ClassDef *cd,
+ Protection pr,Specifier vi,const char *ts)
+{
+ parent=p;
+ x=y=0;
+ //name=n;
+ num=number;
+ children = new DiagramItemList;
+ prot=pr;
+ virt=vi;
+ inList=FALSE;
+ classDef=cd;
+ templSpec=ts;
+}
+
+DiagramItem::~DiagramItem()
+{
+ delete children;
+}
+
+QCString DiagramItem::label() const
+{
+ QCString result;
+ if (!templSpec.isEmpty())
+ {
+ // we use classDef->name() here and not diplayName() in order
+ // to get the name used in the inheritance relation.
+ QCString n = classDef->name();
+ if (/*n.right(2)=="-g" ||*/ n.right(2)=="-p")
+ {
+ n = n.left(n.length()-2);
+ }
+ result=insertTemplateSpecifierInScope(n,templSpec);
+ }
+ else
+ {
+ result=classDef->displayName();
+ }
+ if (Config_getBool("HIDE_SCOPE_NAMES")) result=stripScope(result);
+ return result;
+}
+
+QCString DiagramItem::fileName() const
+{
+ return classDef->getOutputFileBase();
+}
+
+int DiagramItem::avgChildPos() const
+{
+ DiagramItem *di;
+ int c=children->count();
+ if (c==0) // no children -> don't move
+ return xPos();
+ if ((di=children->getFirst())->isInList()) // children should be in a list
+ return di->xPos();
+ if (c&1) // odd number of children -> get pos of middle child
+ return children->at(c/2)->xPos();
+ else // even number of children -> get middle of most middle children
+ return (children->at(c/2-1)->xPos()+children->at(c/2)->xPos())/2;
+}
+
+int DiagramItem::numChildren() const
+{
+ return children->count();
+}
+
+void DiagramItem::addChild(DiagramItem *di)
+{
+ children->append(di);
+}
+
+void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,
+ Protection prot,Specifier virt,const char *ts)
+{
+ //if (cd->visited) return; // the visit check does not work in case of
+ // multiple inheritance of the same class!
+ DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),
+ cd,prot,virt,ts);
+ //cd->visited=TRUE;
+ if (parent) parent->addChild(di);
+ di->move(count()*gridWidth,level*gridHeight);
+ append(di);
+ BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses();
+ int count=0;
+ if (bcl)
+ {
+ /* there are base/sub classes */
+ BaseClassListIterator it(*bcl);
+ BaseClassDef *bcd;
+ for (;(bcd=it.current());++it)
+ {
+ ClassDef *ccd=bcd->classDef;
+ if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;
+ }
+ }
+ if (count>0 && (prot!=Private || !doBases))
+ {
+ DiagramRow *row=0;
+ if (diagram->count()<=level+1) /* add new row */
+ {
+ row = new DiagramRow(diagram,level+1);
+ diagram->append(row);
+ }
+ else /* get next row */
+ {
+ row=diagram->at(level+1);
+ }
+ /* insert base classes in the next row */
+ BaseClassListIterator it(*bcl);
+ BaseClassDef *bcd;
+ for (;(bcd=it.current());++it)
+ {
+ ClassDef *ccd=bcd->classDef;
+ if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/)
+ {
+ row->insertClass(di,ccd,doBases,bcd->prot,
+ doBases?bcd->virt:Normal,
+ doBases?bcd->templSpecifiers.data():"");
+ }
+ }
+ }
+}
+
+TreeDiagram::TreeDiagram(ClassDef *root,bool doBases)
+{
+ setAutoDelete(TRUE);
+ DiagramRow *row=new DiagramRow(this,0);
+ append(row);
+ row->insertClass(0,root,doBases,Public,Normal,0);
+}
+
+TreeDiagram::~TreeDiagram()
+{
+}
+
+
+void TreeDiagram::moveChildren(DiagramItem *root,int dx)
+{
+ DiagramItemList *dil=root->getChildren();
+ QListIterator<DiagramItem> it(*dil);
+ DiagramItem *di;
+ for (;(di=it.current());++it)
+ {
+ di->move(dx,0);
+ moveChildren(di,dx);
+ }
+}
+
+bool TreeDiagram::layoutTree(DiagramItem *root,int r)
+{
+ bool moved=FALSE;
+ //printf("layoutTree(%s,%d)\n",root->label().data(),r);
+
+ DiagramItemList *dil=root->getChildren();
+ if (dil->count()>0)
+ {
+ uint k;
+ int pPos=root->xPos();
+ int cPos=root->avgChildPos();
+ if (pPos>cPos) // move children
+ {
+ DiagramRow *row=at(r+1);
+ //printf("Moving children %d-%d in row %d\n",
+ // dil->getFirst()->number(),row->count()-1,r+1);
+ for (k=dil->getFirst()->number();k<row->count();k++)
+ row->at(k)->move(pPos-cPos,0);
+ moved=TRUE;
+ }
+ else if (pPos<cPos) // move parent
+ {
+ DiagramRow *row=at(r);
+ //printf("Moving parents %d-%d in row %d\n",
+ // root->number(),row->count()-1,r);
+ for (k=root->number();k<row->count();k++)
+ row->at(k)->move(cPos-pPos,0);
+ moved=TRUE;
+ }
+
+ // recurse to children
+ QListIterator<DiagramItem> it(*dil);
+ DiagramItem *di;
+ for (;(di=it.current()) && !moved && !di->isInList();++it)
+ {
+ moved = layoutTree(di,r+1);
+ }
+ }
+ return moved;
+}
+
+void TreeDiagram::computeLayout()
+{
+ QListIterator<DiagramRow> it(*this);
+ DiagramRow *row;
+ for (;(row=it.current()) && row->count()<maxTreeWidth;++it) {}
+ if (row)
+ {
+ //printf("computeLayout() list row at %d\n",row->number());
+ QListIterator<DiagramItem> rit(*row);
+ DiagramItem *di;
+ DiagramItem *opi=0;
+ int delta=0;
+ bool first=TRUE;
+ for (;(di=rit.current());++rit)
+ {
+ DiagramItem *pi=di->parentItem();
+ if (pi==opi && !first) { delta-=gridWidth; }
+ first = pi!=opi;
+ opi=pi;
+ di->move(delta,0); // collapse all items in the same
+ // list (except the first)
+ di->putInList();
+ }
+ }
+
+ // re-organize the diagram items
+ DiagramItem *root=getFirst()->getFirst();
+ while (layoutTree(root,0)) { }
+
+ // move first items of the lists
+ if (row)
+ {
+ QListIterator<DiagramItem> rit(*row);
+ DiagramItem *di;
+ while ((di=rit.current()))
+ {
+ DiagramItem *pi=di->parentItem();
+ if (pi->getChildren()->count()>1)
+ {
+ di->move(gridWidth,0);
+ while (di && di->parentItem()==pi) { ++rit; di=rit.current(); }
+ }
+ else
+ {
+ ++rit;
+ }
+ }
+ }
+}
+
+uint TreeDiagram::computeRows()
+{
+ //printf("TreeDiagram::computeRows()=%d\n",count());
+ int count=0;
+ QListIterator<DiagramRow> it(*this);
+ DiagramRow *row;
+ for (;(row=it.current()) && !row->getFirst()->isInList();++it)
+ {
+ count++;
+ }
+ //printf("count=%d row=%p\n",count,row);
+ if (row)
+ {
+ int maxListLen=0;
+ int curListLen=0;
+ DiagramItem *opi=0;
+ QListIterator<DiagramItem> rit(*row);
+ DiagramItem *di;
+ for (;(di=rit.current());++rit)
+ {
+ if (di->parentItem()!=opi) curListLen=1; else curListLen++;
+ if (curListLen>maxListLen) maxListLen=curListLen;
+ opi=di->parentItem();
+ }
+ //printf("maxListLen=%d\n",maxListLen);
+ count+=maxListLen;
+ }
+ return count;
+}
+
+void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos)
+{
+ uint ml=0,mx=0;
+ QListIterator<DiagramRow> it(*this);
+ DiagramRow *dr;
+ bool done=FALSE;
+ for (;(dr=it.current()) && !done;++it)
+ {
+ QListIterator<DiagramItem> rit(*dr);
+ DiagramItem *di;
+ for (;(di=rit.current());++rit)
+ {
+ if (di->isInList()) done=TRUE;
+ if (maxXPos) mx=QMAX(mx,(uint)di->xPos());
+ if (maxLabelLen) ml=QMAX(ml,Image::stringLength(di->label()));
+ }
+ }
+ if (maxLabelLen) *maxLabelLen=ml;
+ if (maxXPos) *maxXPos=mx;
+}
+
+void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
+ bool doBase,bool bitmap,
+ uint baseRows,uint superRows,
+ uint cellWidth,uint cellHeight,
+ QCString relPath,
+ bool generateMap)
+{
+ QListIterator<DiagramRow> it(*this);
+ DiagramRow *dr;
+ if (!doBase) ++it;
+ bool done=FALSE;
+ bool firstRow = doBase;
+ for (;(dr=it.current()) && !done;++it)
+ {
+ int x=0,y=0;
+ float xf=0.0f,yf=0.0f;
+ QListIterator<DiagramItem> rit(*dr);
+ DiagramItem *di = rit.current();
+ if (di->isInList()) // put boxes in a list
+ {
+ DiagramItem *opi=0;
+ if (doBase) rit.toLast(); else rit.toFirst();
+ while ((di=rit.current()))
+ {
+ if (di->parentItem()==opi)
+ {
+ if (bitmap)
+ {
+ if (doBase) y -= cellHeight+labelVertSpacing;
+ else y += cellHeight+labelVertSpacing;
+ }
+ else
+ {
+ if (doBase) yf += 1.0f;
+ else yf -= 1.0f;
+ }
+ }
+ else
+ {
+ if (bitmap)
+ {
+ x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
+ if (doBase)
+ {
+ y = image->getHeight()-
+ superRows*cellHeight-
+ (superRows-1)*labelVertSpacing-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ }
+ else
+ {
+ y = (baseRows-1)*(cellHeight+labelVertSpacing)+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ }
+ }
+ else
+ {
+ xf = di->xPos()/(float)gridWidth;
+ if (doBase)
+ {
+ yf = di->yPos()/(float)gridHeight+superRows-1;
+ }
+ else
+ {
+ yf = superRows-1-di->yPos()/(float)gridHeight;
+ }
+ }
+ }
+ opi=di->parentItem();
+
+ if (bitmap)
+ {
+ bool hasDocs=di->getClassDef()->isLinkable();
+ writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
+ hasDocs,di->getChildren()->count()>0);
+ if (!firstRow && generateMap)
+ writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
+ }
+ else
+ {
+ writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0);
+ }
+
+ if (doBase) --rit; else ++rit;
+ }
+ done=TRUE;
+ }
+ else // draw a tree of boxes
+ {
+ for (rit.toFirst();(di=rit.current());++rit)
+ {
+ if (bitmap)
+ {
+ x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
+ if (doBase)
+ {
+ y = image->getHeight()-
+ superRows*cellHeight-
+ (superRows-1)*labelVertSpacing-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ }
+ else
+ {
+ y = (baseRows-1)*(cellHeight+labelVertSpacing)+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ }
+ bool hasDocs=di->getClassDef()->isLinkable();
+ writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
+ if (!firstRow && generateMap)
+ writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
+ }
+ else
+ {
+ xf=di->xPos()/(float)gridWidth;
+ if (doBase)
+ {
+ yf = di->yPos()/(float)gridHeight+superRows-1;
+ }
+ else
+ {
+ yf = superRows-1-di->yPos()/(float)gridHeight;
+ }
+ writeVectorBox(t,di,xf,yf);
+ }
+ }
+ }
+ firstRow=FALSE;
+ }
+}
+
+void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
+ bool doBase,bool bitmap,
+ uint baseRows,uint superRows,
+ uint cellWidth,uint cellHeight)
+{
+ QListIterator<DiagramRow> it(*this);
+ DiagramRow *dr;
+ bool done=FALSE;
+ for (;(dr=it.current()) && !done;++it) // for each row
+ {
+ QListIterator<DiagramItem> rit(*dr);
+ DiagramItem *di = rit.current();
+ if (di->isInList()) // row consists of list connectors
+ {
+ int x=0,y=0,ys=0;
+ float xf=0.0f,yf=0.0f,ysf=0.0f;
+ for (;(di=rit.current());++rit)
+ {
+ DiagramItem *pi=di->parentItem();
+ DiagramItemList *dil=pi->getChildren();
+ DiagramItem *last=dil->getLast();
+ if (di==last) // single child
+ {
+ if (bitmap) // draw pixels
+ {
+ x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
+ if (doBase) // base classes
+ {
+ y = image->getHeight()-
+ (superRows-1)*(cellHeight+labelVertSpacing)-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ image->drawVertArrow(x,y,y+labelVertSpacing/2,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ }
+ else // super classes
+ {
+ y = (baseRows-1)*(cellHeight+labelVertSpacing)-
+ labelVertSpacing/2+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ image->drawVertLine(x,y,y+labelVertSpacing/2,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ }
+ }
+ else // draw vectors
+ {
+ t << protToString(di->protection()) << endl;
+ if (doBase)
+ {
+ t << "1 " << (di->xPos()/(float)gridWidth) << " "
+ << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
+ }
+ else
+ {
+ t << "0 " << (di->xPos()/(float)gridWidth) << " "
+ << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
+ << " in\n";
+ }
+ }
+ }
+ else // multiple children, put them in a vertical list
+ {
+ if (bitmap)
+ {
+ x = di->parentItem()->xPos()*
+ (cellWidth+labelHorSpacing)/gridWidth+cellWidth/2;
+ if (doBase) // base classes
+ {
+ ys = image->getHeight()-
+ (superRows-1)*(cellHeight+labelVertSpacing)-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ y = ys - cellHeight/2;
+ }
+ else // super classes
+ {
+ ys = (baseRows-1)*(cellHeight+labelVertSpacing)+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ y = ys + cellHeight/2;
+ }
+ }
+ else
+ {
+ xf = di->parentItem()->xPos()/(float)gridWidth;
+ if (doBase)
+ {
+ ysf = di->yPos()/(float)gridHeight+superRows-1;
+ yf = ysf + 0.5f;
+ }
+ else
+ {
+ ysf = (float)superRows-0.25f-di->yPos()/(float)gridHeight;
+ yf = ysf - 0.25f;
+ }
+ }
+ while (di!=last) // more children to add
+ {
+ if (bitmap)
+ {
+ if (doBase) // base classes
+ {
+ image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ y -= cellHeight+labelVertSpacing;
+ }
+ else // super classes
+ {
+ image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ y += cellHeight+labelVertSpacing;
+ }
+ }
+ else
+ {
+ t << protToString(di->protection()) << endl;
+ if (doBase)
+ {
+ t << "1 " << xf << " " << yf << " hedge\n";
+ yf += 1.0f;
+ }
+ else
+ {
+ t << "0 " << xf << " " << yf << " hedge\n";
+ yf -= 1.0f;
+ }
+ }
+ ++rit; di=rit.current();
+ }
+ // add last horizonal line and a vertical connection line
+ if (bitmap)
+ {
+ if (doBase) // base classes
+ {
+ image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ image->drawVertLine(x,y,ys+labelVertSpacing/2,
+ protToColor(getMinProtectionLevel(dil)),
+ protToMask(getMinProtectionLevel(dil)));
+ }
+ else // super classes
+ {
+ image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ image->drawVertLine(x,ys-labelVertSpacing/2,y,
+ protToColor(getMinProtectionLevel(dil)),
+ protToMask(getMinProtectionLevel(dil)));
+ }
+ }
+ else
+ {
+ t << protToString(di->protection()) << endl;
+ if (doBase)
+ {
+ t << "1 " << xf << " " << yf << " hedge\n";
+ }
+ else
+ {
+ t << "0 " << xf << " " << yf << " hedge\n";
+ }
+ t << protToString(getMinProtectionLevel(dil)) << endl;
+ if (doBase)
+ {
+ t << xf << " " << ysf << " " << yf << " vedge\n";
+ }
+ else
+ {
+ t << xf << " " << (ysf + 0.25) << " " << yf << " vedge\n";
+ }
+ }
+ }
+ }
+ done=TRUE; // the tree is drawn now
+ }
+ else // normal tree connector
+ {
+ for (;(di=rit.current());++rit)
+ {
+ int x=0,y=0;
+ DiagramItemList *dil = di->getChildren();
+ DiagramItem *parent = di->parentItem();
+ if (parent) // item has a parent -> connect to it
+ {
+ if (bitmap) // draw pixels
+ {
+ x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
+ if (doBase) // base classes
+ {
+ y = image->getHeight()-
+ (superRows-1)*(cellHeight+labelVertSpacing)-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ /* write input line */
+ image->drawVertArrow(x,y,y+labelVertSpacing/2,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ }
+ else // super classes
+ {
+ y = (baseRows-1)*(cellHeight+labelVertSpacing)-
+ labelVertSpacing/2+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ /* write output line */
+ image->drawVertLine(x,y,y+labelVertSpacing/2,
+ protToColor(di->protection()),
+ protToMask(di->protection()));
+ }
+ }
+ else // draw pixels
+ {
+ t << protToString(di->protection()) << endl;
+ if (doBase)
+ {
+ t << "1 " << di->xPos()/(float)gridWidth << " "
+ << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
+ }
+ else
+ {
+ t << "0 " << di->xPos()/(float)gridWidth << " "
+ << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
+ << " in\n";
+ }
+ }
+ }
+ if (dil->count()>0)
+ {
+ Protection p=getMinProtectionLevel(dil);
+ uint mask=protToMask(p);
+ uint col=protToColor(p);
+ if (bitmap)
+ {
+ x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
+ if (doBase) // base classes
+ {
+ y = image->getHeight()-
+ (superRows-1)*(cellHeight+labelVertSpacing)-
+ cellHeight-labelVertSpacing/2-
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ image->drawVertLine(x,y,y+labelVertSpacing/2-1,col,mask);
+ }
+ else // super classes
+ {
+ y = (baseRows-1)*(cellHeight+labelVertSpacing)+
+ cellHeight+
+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
+ image->drawVertArrow(x,y,y+labelVertSpacing/2-1,col,mask);
+ }
+ }
+ else
+ {
+ t << protToString(p) << endl;
+ if (doBase)
+ {
+ t << "0 " << di->xPos()/(float)gridWidth << " "
+ << (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
+ }
+ else
+ {
+ t << "1 " << di->xPos()/(float)gridWidth << " "
+ << ((float)superRows-1.75-di->yPos()/(float)gridHeight)
+ << " out\n";
+ }
+ }
+ /* write input line */
+ DiagramItem *first = dil->getFirst();
+ DiagramItem *last = dil->getLast();
+ if (first!=last && !first->isInList()) /* connect with all base classes */
+ {
+ if (bitmap)
+ {
+ int xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
+ + cellWidth/2;
+ int xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
+ + cellWidth/2;
+ if (doBase) // base classes
+ {
+ image->drawHorzLine(y,xs,xe,col,mask);
+ }
+ else // super classes
+ {
+ image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
+ }
+ }
+ else
+ {
+ t << protToString(p) << endl;
+ if (doBase)
+ {
+ t << first->xPos()/(float)gridWidth << " "
+ << last->xPos()/(float)gridWidth << " "
+ << (first->yPos()/(float)gridHeight+superRows-1)
+ << " conn\n";
+ }
+ else
+ {
+ t << first->xPos()/(float)gridWidth << " "
+ << last->xPos()/(float)gridWidth << " "
+ << ((float)superRows-first->yPos()/(float)gridHeight)
+ << " conn\n";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void clearVisitFlags()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ cd->visited=FALSE;
+ }
+}
+
+ClassDiagram::ClassDiagram(ClassDef *root)
+{
+ clearVisitFlags();
+ base = new TreeDiagram(root,TRUE);
+ base->computeLayout();
+ clearVisitFlags();
+ super = new TreeDiagram(root,FALSE);
+ super->computeLayout();
+ DiagramItem *baseItem = base->getFirst()->getFirst();
+ DiagramItem *superItem = super->getFirst()->getFirst();
+ int xbase = baseItem->xPos();
+ int xsuper = superItem->xPos();
+ if (xbase>xsuper)
+ {
+ superItem->move(xbase-xsuper,0);
+ super->moveChildren(superItem,xbase-xsuper);
+ }
+ else if (xbase<xsuper)
+ {
+ baseItem->move(xsuper-xbase,0);
+ base->moveChildren(baseItem,xsuper-xbase);
+ }
+}
+
+ClassDiagram::~ClassDiagram()
+{
+ delete base;
+ delete super;
+}
+
+void ClassDiagram::writeFigure(FTextStream &output,const char *path,
+ const char *fileName) const
+{
+ uint baseRows=base->computeRows();
+ uint superRows=super->computeRows();
+ uint baseMaxX, baseMaxLabelWidth, superMaxX, superMaxLabelWidth;
+ base->computeExtremes(&baseMaxLabelWidth,&baseMaxX);
+ super->computeExtremes(&superMaxLabelWidth,&superMaxX);
+
+ uint rows=baseRows+superRows-1;
+ uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
+
+ // Estimate the image aspect width and height in pixels.
+ uint estHeight = rows*40;
+ uint estWidth = cols*(20+QMAX(baseMaxLabelWidth,superMaxLabelWidth));
+ //printf("Estimated size %d x %d\n",estWidth,estHeight);
+
+ const float pageWidth = 14.0f; // estimated page width in cm.
+ // Somewhat lower to deal with estimation
+ // errors.
+
+ // compute the image height in centimeters based on the estimates
+ float realHeight = QMIN(rows,12); // real height in cm
+ float realWidth = realHeight * estWidth/(float)estHeight;
+ if (realWidth>pageWidth) // assume that the page width is about 15 cm
+ {
+ realHeight*=pageWidth/realWidth;
+ realWidth=pageWidth;
+ }
+
+ //output << "}\n";
+ output << "\\begin{figure}[H]\n"
+ "\\begin{center}\n"
+ "\\leavevmode\n";
+ output << "\\includegraphics[height=" << realHeight << "cm]{"
+ << fileName << "}" << endl;
+ output << "\\end{center}\n"
+ "\\end{figure}\n";
+
+ //printf("writeFigure rows=%d cols=%d\n",rows,cols);
+
+ QCString epsBaseName=(QCString)path+"/"+fileName;
+ QCString epsName=epsBaseName+".eps";
+ QFile f1;
+ f1.setName(epsName.data());
+ if (!f1.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",f1.name().data());
+ exit(1);
+ }
+ FTextStream t(&f1);
+
+ //printf("writeEPS() rows=%d cols=%d\n",rows,cols);
+
+ // generate EPS header and postscript variables and procedures
+
+ t << "%!PS-Adobe-2.0 EPSF-2.0\n";
+ t << "%%Title: ClassName\n";
+ t << "%%Creator: Doxygen\n";
+ t << "%%CreationDate: Time\n";
+ t << "%%For: \n";
+ t << "%Magnification: 1.00\n";
+ t << "%%Orientation: Portrait\n";
+ t << "%%BoundingBox: 0 0 500 " << estHeight*500.0/(float)estWidth << "\n";
+ t << "%%Pages: 0\n";
+ t << "%%BeginSetup\n";
+ t << "%%EndSetup\n";
+ t << "%%EndComments\n";
+ t << "\n";
+ t << "% ----- variables -----\n";
+ t << "\n";
+ t << "/boxwidth 0 def\n";
+ t << "/boxheight 40 def\n";
+ t << "/fontheight 24 def\n";
+ t << "/marginwidth 10 def\n";
+ t << "/distx 20 def\n";
+ t << "/disty 40 def\n";
+ t << "/boundaspect " << estWidth/(float)estHeight << " def % aspect ratio of the BoundingBox (width/height)\n";
+ t << "/boundx 500 def\n";
+ t << "/boundy boundx boundaspect div def\n";
+ t << "/xspacing 0 def\n";
+ t << "/yspacing 0 def\n";
+ t << "/rows " << rows << " def\n";
+ t << "/cols " << cols << " def\n";
+ t << "/scalefactor 0 def\n";
+ t << "/boxfont /Times-Roman findfont fontheight scalefont def\n";
+ t << "\n";
+ t << "% ----- procedures -----\n";
+ t << "\n";
+ t << "/dotted { [1 4] 0 setdash } def\n";
+ t << "/dashed { [5] 0 setdash } def\n";
+ t << "/solid { [] 0 setdash } def\n";
+ t << "\n";
+ t << "/max % result = MAX(arg1,arg2)\n";
+ t << "{\n";
+ t << " /a exch def\n";
+ t << " /b exch def\n";
+ t << " a b gt {a} {b} ifelse\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/xoffset % result = MAX(0,(scalefactor-(boxwidth*cols+distx*(cols-1)))/2)\n";
+ t << "{\n";
+ t << " 0 scalefactor boxwidth cols mul distx cols 1 sub mul add sub 2 div max\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/cw % boxwidth = MAX(boxwidth, stringwidth(arg1))\n";
+ t << "{\n";
+ t << " /str exch def\n";
+ t << " /boxwidth boxwidth str stringwidth pop max def\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/box % draws a box with text `arg1' at grid pos (arg2,arg3)\n";
+ t << "{ gsave\n";
+ t << " 2 setlinewidth\n";
+ t << " newpath\n";
+ t << " exch xspacing mul xoffset add\n";
+ t << " exch yspacing mul\n";
+ t << " moveto\n";
+ t << " boxwidth 0 rlineto \n";
+ t << " 0 boxheight rlineto \n";
+ t << " boxwidth neg 0 rlineto \n";
+ t << " 0 boxheight neg rlineto \n";
+ t << " closepath\n";
+ t << " dup stringwidth pop neg boxwidth add 2 div\n";
+ t << " boxheight fontheight 2 div sub 2 div\n";
+ t << " rmoveto show stroke\n";
+ t << " grestore\n";
+ t << "} def \n";
+ t << "\n";
+ t << "/mark\n";
+ t << "{ newpath\n";
+ t << " exch xspacing mul xoffset add boxwidth add\n";
+ t << " exch yspacing mul\n";
+ t << " moveto\n";
+ t << " 0 boxheight 4 div rlineto\n";
+ t << " boxheight neg 4 div boxheight neg 4 div rlineto\n";
+ t << " closepath\n";
+ t << " eofill\n";
+ t << " stroke\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/arrow\n";
+ t << "{ newpath\n";
+ t << " moveto\n";
+ t << " 3 -8 rlineto\n";
+ t << " -6 0 rlineto\n";
+ t << " 3 8 rlineto\n";
+ t << " closepath\n";
+ t << " eofill\n";
+ t << " stroke\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/out % draws an output connector for the block at (arg1,arg2)\n";
+ t << "{\n";
+ t << " newpath\n";
+ t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
+ t << " exch yspacing mul boxheight add\n";
+ t << " /y exch def\n";
+ t << " /x exch def\n";
+ t << " x y moveto\n";
+ t << " 0 disty 2 div rlineto \n";
+ t << " stroke\n";
+ t << " 1 eq { x y disty 2 div add arrow } if\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/in % draws an input connector for the block at (arg1,arg2)\n";
+ t << "{\n";
+ t << " newpath\n";
+ t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
+ t << " exch yspacing mul disty 2 div sub\n";
+ t << " /y exch def\n";
+ t << " /x exch def\n";
+ t << " x y moveto\n";
+ t << " 0 disty 2 div rlineto\n";
+ t << " stroke\n";
+ t << " 1 eq { x y disty 2 div add arrow } if\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/hedge\n";
+ t << "{\n";
+ t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
+ t << " exch yspacing mul boxheight 2 div sub\n";
+ t << " /y exch def\n";
+ t << " /x exch def\n";
+ t << " newpath\n";
+ t << " x y moveto\n";
+ t << " boxwidth 2 div distx add 0 rlineto\n";
+ t << " stroke\n";
+ t << " 1 eq\n";
+ t << " { newpath x boxwidth 2 div distx add add y moveto\n";
+ t << " -8 3 rlineto\n";
+ t << " 0 -6 rlineto\n";
+ t << " 8 3 rlineto\n";
+ t << " closepath\n";
+ t << " eofill\n";
+ t << " stroke\n";
+ t << " } if\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/vedge\n";
+ t << "{\n";
+ t << " /ye exch def\n";
+ t << " /ys exch def\n";
+ t << " /xs exch def\n";
+ t << " newpath\n";
+ t << " xs xspacing mul xoffset add boxwidth 2 div add dup\n";
+ t << " ys yspacing mul boxheight 2 div sub\n";
+ t << " moveto\n";
+ t << " ye yspacing mul boxheight 2 div sub\n";
+ t << " lineto\n";
+ t << " stroke\n";
+ t << "} def\n";
+ t << "\n";
+ t << "/conn % connections the blocks from col `arg1' to `arg2' of row `arg3'\n";
+ t << "{\n";
+ t << " /ys exch def\n";
+ t << " /xe exch def\n";
+ t << " /xs exch def\n";
+ t << " newpath\n";
+ t << " xs xspacing mul xoffset add boxwidth 2 div add\n";
+ t << " ys yspacing mul disty 2 div sub\n";
+ t << " moveto\n";
+ t << " xspacing xe xs sub mul 0\n";
+ t << " rlineto\n";
+ t << " stroke\n";
+ t << "} def\n";
+ t << "\n";
+ t << "% ----- main ------\n";
+ t << "\n";
+ t << "boxfont setfont\n";
+ t << "1 boundaspect scale\n";
+
+
+ bool done=FALSE;
+ QListIterator<DiagramRow> bit(*base);
+ DiagramRow *dr;
+ for (;(dr=bit.current()) && !done;++bit)
+ {
+ QListIterator<DiagramItem> rit(*dr);
+ DiagramItem *di;
+ for (;(di=rit.current());++rit)
+ {
+ done=di->isInList();
+ t << "(" << di->label() << ") cw\n";
+ }
+ }
+ QListIterator<DiagramRow> sit(*super);
+ ++sit;
+ done=FALSE;
+ for (;(dr=sit.current()) && !done;++sit)
+ {
+ QListIterator<DiagramItem> rit(*dr);
+ DiagramItem *di;
+ for (;(di=rit.current());++rit)
+ {
+ done=di->isInList();
+ t << "(" << di->label() << ") cw\n";
+ }
+ }
+
+ t << "/boxwidth boxwidth marginwidth 2 mul add def\n"
+ << "/xspacing boxwidth distx add def\n"
+ << "/yspacing boxheight disty add def\n"
+ << "/scalefactor \n"
+ << " boxwidth cols mul distx cols 1 sub mul add\n"
+ << " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
+ << " max def\n"
+ << "boundx scalefactor div boundy scalefactor div scale\n";
+
+ t << "\n% ----- classes -----\n\n";
+ base->drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0);
+ super->drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0);
+
+ t << "\n% ----- relations -----\n\n";
+ base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
+ super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
+
+ f1.close();
+ if (Config_getBool("USE_PDFLATEX"))
+ {
+ QCString epstopdfArgs(4096);
+ epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
+ epsBaseName.data(),epsBaseName.data());
+ //printf("Converting eps using `%s'\n",epstopdfCmd.data());
+ portable_sysTimerStart();
+ if (portable_system("epstopdf",epstopdfArgs)!=0)
+ {
+ err("Problems running epstopdf. Check your TeX installation!\n");
+ portable_sysTimerStop();
+ return;
+ }
+ portable_sysTimerStop();
+ }
+}
+
+
+void ClassDiagram::writeImage(FTextStream &t,const char *path,
+ const char *relPath,const char *fileName,
+ bool generateMap) const
+{
+ uint baseRows=base->computeRows();
+ uint superRows=super->computeRows();
+ uint rows=baseRows+superRows-1;
+
+ uint lb,ls,xb,xs;
+ base->computeExtremes(&lb,&xb);
+ super->computeExtremes(&ls,&xs);
+
+ uint cellWidth = QMAX(lb,ls)+labelHorMargin*2;
+ uint maxXPos = QMAX(xb,xs);
+ uint labelVertMargin = 6; //QMAX(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
+ uint cellHeight = labelVertMargin*2+fontHeight;
+ uint imageWidth = (maxXPos+gridWidth)*cellWidth/gridWidth+
+ (maxXPos*labelHorSpacing)/gridWidth;
+ uint imageHeight = rows*cellHeight+(rows-1)*labelVertSpacing;
+
+ Image image(imageWidth,imageHeight);
+
+ base->drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
+ super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
+ base->drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
+ super->drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
+
+#define IMAGE_EXT ".png"
+ image.save((QCString)path+"/"+fileName+IMAGE_EXT);
+ Doxygen::indexList->addImageFile(QCString(fileName)+IMAGE_EXT);
+
+ if (generateMap) t << "</map>" << endl;
+}
+
diff --git a/src/diagram.h b/src/diagram.h
new file mode 100644
index 0000000..6ce83f3
--- /dev/null
+++ b/src/diagram.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DIAGRAM_H
+#define DIAGRAM_H
+
+#include <qglobal.h>
+
+class ClassDef;
+class TreeDiagram;
+class FTextStream;
+
+/** Class representing a built-in class diagram. */
+class ClassDiagram
+{
+ public:
+ ClassDiagram(ClassDef *root);
+ ~ClassDiagram();
+ void writeFigure(FTextStream &t,const char *path,
+ const char *file) const;
+ void writeImage(FTextStream &t,const char *path,const char *relPath,
+ const char *file,bool generateMap=TRUE) const;
+ private:
+ TreeDiagram *base;
+ TreeDiagram *super;
+};
+
+#endif
+
diff --git a/src/dirdef.cpp b/src/dirdef.cpp
new file mode 100644
index 0000000..284d1ee
--- /dev/null
+++ b/src/dirdef.cpp
@@ -0,0 +1,938 @@
+#include "md5.h"
+
+#include "dirdef.h"
+#include "filename.h"
+#include "doxygen.h"
+#include "util.h"
+#include "outputlist.h"
+#include "language.h"
+#include "message.h"
+#include "dot.h"
+#include "layout.h"
+#include "ftextstream.h"
+#include "config.h"
+#include "docparser.h"
+
+//----------------------------------------------------------------------
+// method implementation
+
+static int g_dirCount=0;
+
+DirDef::DirDef(const char *path) : Definition(path,1,1,path)
+{
+ bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
+ // get display name (stipping the paths mentioned in STRIP_FROM_PATH)
+ // get short name (last part of path)
+ m_shortName = path;
+ m_diskName = path;
+ if (m_shortName.at(m_shortName.length()-1)=='/')
+ { // strip trailing /
+ m_shortName = m_shortName.left(m_shortName.length()-1);
+ }
+ int pi=m_shortName.findRev('/');
+ if (pi!=-1)
+ { // remove everything till the last /
+ m_shortName = m_shortName.mid(pi+1);
+ }
+ setLocalName(m_shortName);
+ m_dispName = fullPathNames ? stripFromPath(path) : m_shortName;
+ if (m_dispName.length()>0 && m_dispName.at(m_dispName.length()-1)=='/')
+ { // strip trailing /
+ m_dispName = m_dispName.left(m_dispName.length()-1);
+ }
+
+ m_fileList = new FileList;
+ m_usedDirs = new QDict<UsedDir>(257);
+ m_usedDirs->setAutoDelete(TRUE);
+ m_dirCount = g_dirCount++;
+ m_level=-1;
+ m_parent=0;
+}
+
+DirDef::~DirDef()
+{
+ delete m_fileList;
+ delete m_usedDirs;
+}
+
+bool DirDef::isLinkableInProject() const
+{
+ return !isReference();
+}
+
+bool DirDef::isLinkable() const
+{
+ return isReference() || isLinkableInProject();
+}
+
+void DirDef::addSubDir(DirDef *subdir)
+{
+ m_subdirs.inSort(subdir);
+ subdir->setOuterScope(this);
+ subdir->m_parent=this;
+}
+
+void DirDef::addFile(FileDef *fd)
+{
+ m_fileList->inSort(fd);
+ fd->setDirDef(this);
+}
+
+static QCString encodeDirName(const QCString &anchor)
+{
+ QCString result;
+
+ // convert to md5 hash
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)anchor.data(),anchor.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ return sigStr;
+
+ // old algorithm
+
+// int l = anchor.length(),i;
+// for (i=0;i<l;i++)
+// {
+// char c = anchor.at(i);
+// if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'))
+// {
+// result+=c;
+// }
+// else
+// {
+// static char hexStr[]="0123456789ABCDEF";
+// char escChar[]={ '_', 0, 0, 0 };
+// escChar[1]=hexStr[c>>4];
+// escChar[2]=hexStr[c&0xf];
+// result+=escChar;
+// }
+// }
+// return result;
+}
+
+QCString DirDef::getOutputFileBase() const
+{
+ //printf("DirDef::getOutputFileBase() %s->dir_%s\n",
+ // m_diskName.data(),encodeDirName(m_diskName).data());
+ return "dir_"+encodeDirName(m_diskName);
+}
+
+void DirDef::writeDetailedDescription(OutputList &ol,const QCString &title)
+{
+ if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) ||
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,"details");
+ ol.popGeneratorState();
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ // repeat brief description
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ // separator between brief and details
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
+ // ol.newParagraph(); // FIXME:PARA
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.enable(OutputGenerator::Latex);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+
+ // write documentation
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ }
+ }
+}
+
+void DirDef::writeBriefDescription(OutputList &ol)
+{
+ if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ DocRoot *rootNode = validatingParseDoc(
+ briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startParagraph();
+ ol.writeDoc(rootNode,this,0);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+
+ if (Config_getBool("REPEAT_BRIEF") ||
+ !documentation().isEmpty()
+ )
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startTextLink(0,"details");
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ }
+ ol.popGeneratorState();
+
+ ol.endParagraph();
+ }
+ delete rootNode;
+ }
+ ol.writeSynopsis();
+}
+
+void DirDef::writeDirectoryGraph(OutputList &ol)
+{
+ // write graph dependency graph
+ if (Config_getBool("DIRECTORY_GRAPH") && Config_getBool("HAVE_DOT"))
+ {
+ DotDirDeps dirDep(this);
+ if (!dirDep.isTrivial())
+ {
+ msg("Generating dependency graph for directory %s\n",displayName().data());
+ ol.disable(OutputGenerator::Man);
+ //ol.startParagraph();
+ ol.startDirDepGraph();
+ ol.parseText(theTranslator->trDirDepGraph(shortName()));
+ ol.endDirDepGraph(dirDep);
+ //ol.endParagraph();
+ ol.enableAll();
+ }
+ }
+}
+
+void DirDef::writeSubDirList(OutputList &ol)
+{
+ // write subdir list
+ if (m_subdirs.count()>0)
+ {
+ ol.startMemberHeader("subdirs");
+ ol.parseText(theTranslator->trDir(TRUE,FALSE));
+ ol.endMemberHeader();
+ ol.startMemberList();
+ QListIterator<DirDef> it(m_subdirs);
+ DirDef *dd;
+ for (;(dd=it.current());++it)
+ {
+ ol.startMemberDeclaration();
+ ol.startMemberItem(dd->getOutputFileBase(),0);
+ ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
+ ol.insertMemberAlign();
+ ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
+ ol.endMemberItem();
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <dir>" << convertToXML(dd->displayName()) << "</dir>" << endl;
+ }
+ if (!dd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(dd->getOutputFileBase());
+ ol.generateDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),
+ FALSE, // indexWords
+ FALSE, // isExample
+ 0, // exampleName
+ TRUE, // single line
+ TRUE // link from index
+ );
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+
+ ol.endMemberList();
+ }
+}
+
+void DirDef::writeFileList(OutputList &ol)
+{
+ // write file list
+ if (m_fileList->count()>0)
+ {
+ ol.startMemberHeader("files");
+ ol.parseText(theTranslator->trFile(TRUE,FALSE));
+ ol.endMemberHeader();
+ ol.startMemberList();
+ QListIterator<FileDef> it(*m_fileList);
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ ol.startMemberDeclaration();
+ ol.startMemberItem(fd->getOutputFileBase(),0);
+ ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
+ ol.insertMemberAlign();
+ if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(fd->name());
+ ol.endBold();
+ }
+ if (fd->generateSourceFile())
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(fd->includeName(),0);
+ ol.docify("[");
+ ol.parseText(theTranslator->trCode());
+ ol.docify("]");
+ ol.endTextLink();
+ ol.popGeneratorState();
+ }
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl;
+ }
+ ol.endMemberItem();
+ if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(fd->getOutputFileBase());
+ ol.generateDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),
+ FALSE, // indexWords
+ FALSE, // isExample
+ 0, // exampleName
+ TRUE, // single line
+ TRUE // link from index
+ );
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+ ol.endMemberList();
+ }
+}
+
+void DirDef::startMemberDeclarations(OutputList &ol)
+{
+ ol.startMemberSections();
+}
+
+void DirDef::endMemberDeclarations(OutputList &ol)
+{
+ ol.endMemberSections();
+}
+
+QCString DirDef::shortTitle() const
+{
+ return theTranslator->trDirReference(m_shortName);
+}
+
+bool DirDef::hasDetailedDescription() const
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty();
+}
+
+void DirDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ ol.pushGeneratorState();
+
+ QCString title=theTranslator->trDirReference(m_dispName);
+ startFile(ol,getOutputFileBase(),name(),title,HLI_None,!generateTreeView);
+
+ if (!generateTreeView)
+ {
+ // write navigation path
+ writeNavigationPath(ol);
+ ol.endQuickIndices();
+ }
+
+ startTitle(ol,getOutputFileBase());
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.parseText(shortTitle());
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ ol.parseText(title);
+ ol.popGeneratorState();
+ endTitle(ol,getOutputFileBase(),title);
+ ol.startContents();
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"dir\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(displayName()) << "</name>" << endl;
+ Doxygen::tagFile << " <path>" << convertToXML(name()) << "</path>" << endl;
+ Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
+ }
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang = getLanguage();
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Directory));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol);
+ break;
+ case LayoutDocEntry::DirGraph:
+ writeDirectoryGraph(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DirSubDirs:
+ writeSubDirList(ol);
+ break;
+ case LayoutDocEntry::DirFiles:
+ writeFileList(ol);
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ case LayoutDocEntry::ClassInlineClasses:
+ case LayoutDocEntry::ClassInheritanceGraph:
+ case LayoutDocEntry::ClassNestedClasses:
+ case LayoutDocEntry::ClassCollaborationGraph:
+ case LayoutDocEntry::ClassAllMembersLink:
+ case LayoutDocEntry::ClassUsedFiles:
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileConstantGroups:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::AuthorSection:
+ case LayoutDocEntry::MemberGroups:
+ case LayoutDocEntry::MemberDecl:
+ case LayoutDocEntry::MemberDef:
+ case LayoutDocEntry::MemberDefStart:
+ case LayoutDocEntry::MemberDefEnd:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Directory entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ //---------------------------------------- end flexible part -------------------------------
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+
+ ol.endContents();
+
+ endFileWithNavPath(this,ol);
+
+ ol.popGeneratorState();
+}
+
+void DirDef::setLevel()
+{
+ if (m_level==-1) // level not set before
+ {
+ DirDef *p = parent();
+ if (p)
+ {
+ p->setLevel();
+ m_level = p->level()+1;
+ }
+ else
+ {
+ m_level = 0;
+ }
+ }
+}
+
+/** Add as "uses" dependency between \a this dir and \a dir,
+ * that was caused by a dependency on file \a fd.
+ */
+void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd,
+ FileDef *dstFd,bool inherited)
+{
+ if (this==dir) return; // do not add self-dependencies
+ //static int count=0;
+ //printf(" %d add dependency %s->%s due to %s->%s\n",
+ // count++,shortName().data(),
+ // dir->shortName().data(),
+ // srcFd->name().data(),
+ // dstFd->name().data());
+
+ // levels match => add direct dependency
+ bool added=FALSE;
+ UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase());
+ if (usedDir) // dir dependency already present
+ {
+ FilePair *usedPair = usedDir->findFilePair(
+ srcFd->getOutputFileBase()+dstFd->getOutputFileBase());
+ if (usedPair==0) // new file dependency
+ {
+ //printf(" => new file\n");
+ usedDir->addFileDep(srcFd,dstFd);
+ added=TRUE;
+ }
+ else
+ {
+ // dir & file dependency already added
+ }
+ }
+ else // new directory dependency
+ {
+ //printf(" => new file\n");
+ usedDir = new UsedDir(dir,inherited);
+ usedDir->addFileDep(srcFd,dstFd);
+ m_usedDirs->insert(dir->getOutputFileBase(),usedDir);
+ added=TRUE;
+ }
+ if (added)
+ {
+ if (dir->parent())
+ {
+ // add relation to parent of used dir
+ addUsesDependency(dir->parent(),srcFd,dstFd,inherited);
+ }
+ if (parent())
+ {
+ // add relation for the parent of this dir as well
+ parent()->addUsesDependency(dir,srcFd,dstFd,TRUE);
+ }
+ }
+}
+
+/** Computes the dependencies between directories
+ */
+void DirDef::computeDependencies()
+{
+ FileList *fl = m_fileList;
+ if (fl)
+ {
+ QListIterator<FileDef> fli(*fl);
+ FileDef *fd;
+ for (fli.toFirst();(fd=fli.current());++fli) // foreach file in dir dd
+ {
+ //printf(" File %s\n",fd->name().data());
+ //printf("** dir=%s file=%s\n",shortName().data(),fd->name().data());
+ QList<IncludeInfo> *ifl = fd->includeFileList();
+ if (ifl)
+ {
+ QListIterator<IncludeInfo> ifli(*ifl);
+ IncludeInfo *ii;
+ for (ifli.toFirst();(ii=ifli.current());++ifli) // foreach include file
+ {
+ //printf(" > %s\n",ii->includeName.data());
+ //printf(" #include %s\n",ii->includeName.data());
+ if (ii->fileDef && ii->fileDef->isLinkable()) // linkable file
+ {
+ DirDef *usedDir = ii->fileDef->getDirDef();
+ if (usedDir)
+ {
+ // add dependency: thisDir->usedDir
+ //static int count=0;
+ //printf(" %d: add dependency %s->%s\n",count++,name().data(),usedDir->name().data());
+ addUsesDependency(usedDir,fd,ii->fileDef,FALSE);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool DirDef::isParentOf(DirDef *dir) const
+{
+ if (dir->parent()==this) // this is a parent of dir
+ return TRUE;
+ else if (dir->parent()) // repeat for the parent of dir
+ return isParentOf(dir->parent());
+ else
+ return FALSE;
+}
+
+bool DirDef::depGraphIsTrivial() const
+{
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+
+int FilePairDict::compareValues(const FilePair *left,const FilePair *right) const
+{
+ int orderHi = qstricmp(left->source()->name(),right->source()->name());
+ int orderLo = qstricmp(left->destination()->name(),right->destination()->name());
+ return orderHi==0 ? orderLo : orderHi;
+}
+
+//----------------------------------------------------------------------
+
+UsedDir::UsedDir(DirDef *dir,bool inherited) :
+ m_dir(dir), m_filePairs(7), m_inherited(inherited)
+{
+ m_filePairs.setAutoDelete(TRUE);
+}
+
+UsedDir::~UsedDir()
+{
+}
+
+
+void UsedDir::addFileDep(FileDef *srcFd,FileDef *dstFd)
+{
+ m_filePairs.inSort(srcFd->getOutputFileBase()+dstFd->getOutputFileBase(),
+ new FilePair(srcFd,dstFd));
+}
+
+FilePair *UsedDir::findFilePair(const char *name)
+{
+ QCString n=name;
+ return n.isEmpty() ? 0 : m_filePairs.find(n);
+}
+
+DirDef *DirDef::createNewDir(const char *path)
+{
+ ASSERT(path!=0);
+ DirDef *dir = Doxygen::directories->find(path);
+ if (dir==0) // new dir
+ {
+ //printf("Adding new dir %s\n",path);
+ dir = new DirDef(path);
+ //printf("createNewDir %s short=%s\n",path,dir->shortName().data());
+ Doxygen::directories->inSort(path,dir);
+ }
+ return dir;
+}
+
+bool DirDef::matchPath(const QCString &path,QStrList &l)
+{
+ const char *s=l.first();
+ while (s)
+ {
+ QCString prefix = s;
+ if (qstricmp(prefix.left(path.length()),path)==0) // case insensitive compare
+ {
+ return TRUE;
+ }
+ s = l.next();
+ }
+ return FALSE;
+}
+
+/*! strip part of \a path if it matches
+ * one of the paths in the Config_getList("STRIP_FROM_PATH") list
+ */
+DirDef *DirDef::mergeDirectoryInTree(const QCString &path)
+{
+ //printf("DirDef::mergeDirectoryInTree(%s)\n",path.data());
+ int p=0,i=0;
+ DirDef *dir=0;
+ while ((i=path.find('/',p))!=-1)
+ {
+ QCString part=path.left(i+1);
+ if (!matchPath(part,Config_getList("STRIP_FROM_PATH")) && (part!="/" && part!="//"))
+ {
+ dir=createNewDir(part);
+ }
+ p=i+1;
+ }
+ return dir;
+}
+
+void DirDef::writeDepGraph(FTextStream &t)
+{
+ writeDotDirDepGraph(t,this);
+}
+
+//----------------------------------------------------------------------
+
+static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target)
+{
+ if (target->parent()!=root)
+ {
+ writePartialDirPath(ol,root,target->parent());
+ ol.writeString(" / ");
+ }
+ ol.writeObjectLink(target->getReference(),target->getOutputFileBase(),0,target->shortName());
+}
+
+static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef *fd)
+{
+ if (fd->getDirDef() && fd->getDirDef()!=root)
+ {
+ writePartialDirPath(ol,root,fd->getDirDef());
+ ol.writeString(" / ");
+ }
+ if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(fd->name());
+ ol.endBold();
+ }
+}
+
+void DirRelation::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString shortTitle=theTranslator->trDirRelation(
+ m_src->shortName()+" → "+
+ m_dst->dir()->shortName());
+ QCString title=theTranslator->trDirRelation(
+ m_src->displayName()+" -> "+
+ m_dst->dir()->shortName());
+ startFile(ol,getOutputFileBase(),getOutputFileBase(),
+ title,HLI_None,!generateTreeView,m_src->getOutputFileBase());
+
+ if (!generateTreeView)
+ {
+ // write navigation path
+ m_src->writeNavigationPath(ol);
+ ol.endQuickIndices();
+ }
+ ol.startContents();
+
+ ol.writeString("<h3>"+shortTitle+"</h3>");
+ ol.writeString("<table class=\"dirtab\">");
+ ol.writeString("<tr class=\"dirtab\">");
+ ol.writeString("<th class=\"dirtab\">");
+ ol.parseText(theTranslator->trFileIn(m_src->pathFragment()));
+ ol.writeString("</th>");
+ ol.writeString("<th class=\"dirtab\">");
+ ol.parseText(theTranslator->trIncludesFileIn(m_dst->dir()->pathFragment()));
+ ol.writeString("</th>");
+ ol.writeString("</tr>");
+
+ SDict<FilePair>::Iterator fpi(m_dst->filePairs());
+ FilePair *fp;
+ for (fpi.toFirst();(fp=fpi.current());++fpi)
+ {
+ ol.writeString("<tr class=\"dirtab\">");
+ ol.writeString("<td class=\"dirtab\">");
+ writePartialFilePath(ol,m_src,fp->source());
+ ol.writeString("</td>");
+ ol.writeString("<td class=\"dirtab\">");
+ writePartialFilePath(ol,m_dst->dir(),fp->destination());
+ ol.writeString("</td>");
+ ol.writeString("</tr>");
+ }
+ ol.writeString("</table>");
+
+ ol.endContents();
+
+ endFileWithNavPath(m_src,ol);
+
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------
+// external functions
+
+/** In order to create stable, but unique directory names,
+ * we compute the common part of the path shared by all directories.
+ */
+static void computeCommonDirPrefix()
+{
+ QCString path;
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ if (Doxygen::directories->count()>0) // we have at least one dir
+ {
+ // start will full path of first dir
+ sdi.toFirst();
+ dir=sdi.current();
+ path=dir->name();
+ int i=path.findRev('/',path.length()-2);
+ path=path.left(i+1);
+ bool done=FALSE;
+ if (i==-1)
+ {
+ path="";
+ }
+ else
+ {
+ while (!done)
+ {
+ int l = path.length();
+ int count=0;
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ QCString dirName = dir->name();
+ if (dirName.length()>path.length())
+ {
+ if (qstrncmp(dirName,path,l)!=0) // dirName does not start with path
+ {
+ int i=path.findRev('/',l-2);
+ if (i==-1) // no unique prefix -> stop
+ {
+ path="";
+ done=TRUE;
+ }
+ else // restart with shorter path
+ {
+ path=path.left(i+1);
+ break;
+ }
+ }
+ }
+ else // dir is shorter than path -> take path of dir as new start
+ {
+ path=dir->name();
+ int i=path.findRev('/',l-2);
+ if (i==-1) // no unique prefix -> stop
+ {
+ path="";
+ done=TRUE;
+ }
+ else // restart with shorter path
+ {
+ path=path.left(i+1);
+ }
+ break;
+ }
+ count++;
+ }
+ if (count==Doxygen::directories->count())
+ // path matches for all directories -> found the common prefix
+ {
+ done=TRUE;
+ }
+ }
+ }
+ }
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ QCString diskName = dir->name().right(dir->name().length()-path.length());
+ dir->setDiskName(diskName);
+ //printf("set disk name: %s -> %s\n",dir->name().data(),diskName.data());
+ }
+}
+
+void buildDirectories()
+{
+ // for each input file
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ //printf("buildDirectories %s\n",fd->name().data());
+ if (fd->getReference().isEmpty() && !fd->isDocumentationFile())
+ {
+ DirDef *dir;
+ if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory
+ {
+ dir = DirDef::mergeDirectoryInTree(fd->getPath());
+ }
+ if (dir) dir->addFile(fd);
+ }
+ else
+ {
+ // do something for file imported via tag files.
+ }
+ }
+ }
+
+ //DirDef *root = new DirDef("root:");
+ // compute relations between directories => introduce container dirs.
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ //printf("New dir %s\n",dir->displayName().data());
+ QCString name = dir->name();
+ int i=name.findRev('/',name.length()-2);
+ if (i>0)
+ {
+ DirDef *parent = Doxygen::directories->find(name.left(i+1));
+ //if (parent==0) parent=root;
+ if (parent)
+ {
+ parent->addSubDir(dir);
+ //printf("DirDef::addSubdir(): Adding subdir\n%s to\n%s\n",
+ // dir->displayName().data(), parent->displayName().data());
+ }
+ }
+ }
+ computeCommonDirPrefix();
+}
+
+void computeDirDependencies()
+{
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ // compute nesting level for each directory
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ dir->setLevel();
+ }
+ // compute uses dependencies between directories
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ //printf("computeDependencies for %s: #dirs=%d\n",dir->name().data(),Doxygen::directories.count());
+ dir->computeDependencies();
+ }
+
+}
+
+void generateDirDocs(OutputList &ol)
+{
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ dir->writeDocumentation(ol);
+ }
+ if (Config_getBool("DIRECTORY_GRAPH"))
+ {
+ SDict<DirRelation>::Iterator rdi(Doxygen::dirRelations);
+ DirRelation *dr;
+ for (rdi.toFirst();(dr=rdi.current());++rdi)
+ {
+ dr->writeDocumentation(ol);
+ }
+ }
+}
+
diff --git a/src/dirdef.h b/src/dirdef.h
new file mode 100644
index 0000000..8f4fbc2
--- /dev/null
+++ b/src/dirdef.h
@@ -0,0 +1,187 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DIRDEF_H
+#define DIRDEF_H
+
+#include "sortdict.h"
+#include "definition.h"
+
+#include <qlist.h>
+
+class FileList;
+class ClassSDict;
+class QStrList;
+class FileDef;
+class OutputList;
+class UsedDir;
+class FTextStream;
+
+class DirDef;
+
+/** A list of directories. */
+class DirList : public QList<DirDef>
+{
+ public:
+ int compareValues(const DirDef *item1,const DirDef *item2) const;
+};
+
+/** A model of a directory symbol. */
+class DirDef : public Definition
+{
+ public:
+ DirDef(const char *path);
+ virtual ~DirDef();
+
+ // accessors
+ DefType definitionType() const { return TypeDir; }
+ QCString getOutputFileBase() const;
+ QCString anchor() const { return QCString(); }
+ bool isLinkableInProject() const;
+ bool isLinkable() const;
+ QCString displayName(bool=TRUE) const { return m_dispName; }
+ QCString shortName() const { return m_shortName; }
+ void addSubDir(DirDef *subdir);
+ FileList * getFiles() const { return m_fileList; }
+ void addFile(FileDef *fd);
+ const DirList &subDirs() const { return m_subdirs; }
+ bool isCluster() const { return m_subdirs.count()>0; }
+ int level() const { return m_level; }
+ DirDef *parent() const { return m_parent; }
+ int dirCount() const { return m_dirCount; }
+ const QDict<UsedDir> *usedDirs() const { return m_usedDirs; }
+ bool isParentOf(DirDef *dir) const;
+ bool depGraphIsTrivial() const;
+ QCString shortTitle() const;
+ bool hasDetailedDescription() const;
+
+ // generate output
+ void writeDocumentation(OutputList &ol);
+ void writeDepGraph(FTextStream &t);
+
+ static DirDef *mergeDirectoryInTree(const QCString &path);
+ bool visited;
+ void setDiskName(const QCString &name) { m_diskName = name; }
+
+ private:
+ friend void computeDirDependencies();
+
+ void writeDetailedDescription(OutputList &ol,const QCString &title);
+ void writeBriefDescription(OutputList &ol);
+ void writeDirectoryGraph(OutputList &ol);
+ void writeSubDirList(OutputList &ol);
+ void writeFileList(OutputList &ol);
+ void startMemberDeclarations(OutputList &ol);
+ void endMemberDeclarations(OutputList &ol);
+
+ void setLevel();
+ static DirDef *createNewDir(const char *path);
+ static bool matchPath(const QCString &path,QStrList &l);
+ void addUsesDependency(DirDef *usedDir,FileDef *srcFd,
+ FileDef *dstFd,bool inherited);
+ void computeDependencies();
+
+ DirList m_subdirs;
+ QCString m_dispName;
+ QCString m_shortName;
+ QCString m_diskName;
+ FileList *m_fileList; // list of files in the group
+ int m_dirCount;
+ int m_level;
+ DirDef *m_parent;
+ QDict<UsedDir> *m_usedDirs;
+};
+
+/** Class representing a pair of FileDef objects */
+class FilePair
+{
+ public:
+ FilePair(FileDef *src,FileDef *dst) : m_src(src), m_dst(dst) {}
+ const FileDef *source() const { return m_src; }
+ const FileDef *destination() const { return m_dst; }
+ private:
+ FileDef *m_src;
+ FileDef *m_dst;
+};
+
+/** A sorted dictionary of FilePair objects. */
+class FilePairDict : public SDict<FilePair>
+{
+ public:
+ FilePairDict(int size) : SDict<FilePair>(size) {}
+ private:
+ int compareValues(const FilePair *item1,const FilePair *item2) const;
+};
+
+/** Usage information of a directory. */
+class UsedDir
+{
+ public:
+ UsedDir(DirDef *dir,bool inherited);
+ virtual ~UsedDir();
+ void addFileDep(FileDef *srcFd,FileDef *dstFd);
+ FilePair *findFilePair(const char *name);
+ const FilePairDict &filePairs() const { return m_filePairs; }
+ const DirDef *dir() const { return m_dir; }
+ bool inherited() const { return m_inherited; }
+
+ private:
+ DirDef *m_dir;
+ FilePairDict m_filePairs;
+ bool m_inherited;
+};
+
+/** A usage relation between two directories. */
+class DirRelation
+{
+ public:
+ DirRelation(const QCString &name,DirDef *src,UsedDir *dst)
+ : m_name(name), m_src(src), m_dst(dst) {}
+ DirDef *source() const { return m_src; }
+ UsedDir *destination() const { return m_dst; }
+ void writeDocumentation(OutputList &ol);
+ QCString getOutputFileBase() const { return m_name; }
+
+ private:
+ QCString m_name;
+ DirDef *m_src;
+ UsedDir *m_dst;
+};
+
+inline int DirList::compareValues(const DirDef *item1,const DirDef *item2) const
+{
+ return qstricmp(item1->shortName(),item2->shortName());
+}
+
+/** A sorted dictionary of DirDef objects. */
+class DirSDict : public SDict<DirDef>
+{
+ public:
+ DirSDict(int size) : SDict<DirDef>(size) {}
+ int compareValues(const DirDef *item1,const DirDef *item2) const
+ {
+ return qstricmp(item1->shortName(),item2->shortName());
+ }
+};
+
+
+void buildDirectories();
+void generateDirDocs(OutputList &ol);
+void computeDirDependencies();
+void writeDirDependencyGraph(const char *file);
+
+#endif
diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp
new file mode 100644
index 0000000..cabb7ad
--- /dev/null
+++ b/src/docbookgen.cpp
@@ -0,0 +1,1983 @@
+/******************************************************************************
+*
+*
+*
+* Copyright (C) 1997-2014 by Dimitri van Heesch.
+*
+* Permission to use, copy, modify, and distribute this software and its
+* documentation under the terms of the GNU General Public License is hereby
+* granted. No representations are made about the suitability of this software
+* for any purpose. It is provided "as is" without express or implied warranty.
+* See the GNU General Public License for more details.
+*
+* Documents produced by Doxygen are derivative works derived from the
+* input used in their production; they are not affected by this license.
+*
+*/
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qintdict.h>
+#include "docbookgen.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "classlist.h"
+#include "util.h"
+#include "defargs.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "pagedef.h"
+#include "filename.h"
+#include "version.h"
+#include "docbookvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "parserintf.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "groupdef.h"
+#include "memberdef.h"
+#include "namespacedef.h"
+#include "membername.h"
+#include "membergroup.h"
+#include "dirdef.h"
+#include "section.h"
+
+// no debug info
+#define Docbook_DB(x) do {} while(0)
+// debug to stdout
+//#define Docbook_DB(x) printf x
+// debug inside output
+//#define Docbook_DB(x) QCString __t;__t.sprintf x;m_t << __t
+
+//------------------
+
+class DocbookSectionMapper : public QIntDict<char>
+{
+ public:
+ DocbookSectionMapper() : QIntDict<char>(47)
+ {
+ insert(MemberListType_pubTypes,"public-type");
+ insert(MemberListType_pubMethods,"public-func");
+ insert(MemberListType_pubAttribs,"public-attrib");
+ insert(MemberListType_pubSlots,"public-slot");
+ insert(MemberListType_signals,"signal");
+ insert(MemberListType_dcopMethods,"dcop-func");
+ insert(MemberListType_properties,"property");
+ insert(MemberListType_events,"event");
+ insert(MemberListType_pubStaticMethods,"public-static-func");
+ insert(MemberListType_pubStaticAttribs,"public-static-attrib");
+ insert(MemberListType_proTypes,"protected-type");
+ insert(MemberListType_proMethods,"protected-func");
+ insert(MemberListType_proAttribs,"protected-attrib");
+ insert(MemberListType_proSlots,"protected-slot");
+ insert(MemberListType_proStaticMethods,"protected-static-func");
+ insert(MemberListType_proStaticAttribs,"protected-static-attrib");
+ insert(MemberListType_pacTypes,"package-type");
+ insert(MemberListType_pacMethods,"package-func");
+ insert(MemberListType_pacAttribs,"package-attrib");
+ insert(MemberListType_pacStaticMethods,"package-static-func");
+ insert(MemberListType_pacStaticAttribs,"package-static-attrib");
+ insert(MemberListType_priTypes,"private-type");
+ insert(MemberListType_priMethods,"private-func");
+ insert(MemberListType_priAttribs,"private-attrib");
+ insert(MemberListType_priSlots,"private-slot");
+ insert(MemberListType_priStaticMethods,"private-static-func");
+ insert(MemberListType_priStaticAttribs,"private-static-attrib");
+ insert(MemberListType_friends,"friend");
+ insert(MemberListType_related,"related");
+ insert(MemberListType_decDefineMembers,"define");
+ insert(MemberListType_decProtoMembers,"prototype");
+ insert(MemberListType_decTypedefMembers,"typedef");
+ insert(MemberListType_decEnumMembers,"enum");
+ insert(MemberListType_decFuncMembers,"func");
+ insert(MemberListType_decVarMembers,"var");
+ }
+};
+
+static DocbookSectionMapper g_docbookSectionMapper;
+
+
+inline void writeDocbookString(FTextStream &t,const char *s)
+{
+ t << convertToXML(s);
+}
+
+inline void writeDocbookCodeString(FTextStream &t,const char *s, int &col)
+{
+ char c;
+ while ((c=*s++))
+ {
+ switch(c)
+ {
+ case '\t':
+ {
+ static int tabSize = Config_getInt("TAB_SIZE");
+ int spacesToNextTabStop = tabSize - (col%tabSize);
+ col+=spacesToNextTabStop;
+ while (spacesToNextTabStop--) t << " ";
+ break;
+ }
+ case ' ': t << " "; col++; break;
+ case '<': t << "<"; col++; break;
+ case '>': t << ">"; col++; break;
+ case '&': t << "&"; col++; break;
+ case '\'': t << "'"; col++; break;
+ case '"': t << """; col++; break;
+ default: t << c; col++; break;
+ }
+ }
+}
+
+static void writeDocbookHeaderMainpage(FTextStream &t)
+{
+ t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
+ t << "<chapter xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" << endl;
+}
+
+static void writeDocbookHeader_ID(FTextStream &t, QCString id)
+{
+ t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
+ t << "<section xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:id=\"" << id << "\">" << endl;
+}
+
+void writeDocbookLink(FTextStream &t,const char * /*extRef*/,const char *compoundId,
+ const char *anchorId,const char * text,const char * /*tooltip*/)
+{
+ t << "<link linkend=\"" << compoundId;
+ if (anchorId) t << "_1" << anchorId;
+ t << "\"";
+ t << ">";
+ writeDocbookString(t,text);
+ t << "</link>";
+}
+
+class TextGeneratorDocbookImpl : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorDocbookImpl(FTextStream &t): m_t(t) {}
+ void writeString(const char *s,bool /*keepSpaces*/) const
+ {
+ writeDocbookString(m_t,s);
+ }
+ void writeBreak(int) const {}
+ void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const
+ {
+ writeDocbookLink(m_t,extRef,file,anchor,text,0);
+ }
+ private:
+ FTextStream &m_t;
+};
+
+class DocbookCodeGenerator : public CodeOutputInterface
+{
+ public:
+ DocbookCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1),
+ m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE) {}
+ virtual ~DocbookCodeGenerator() {}
+
+ void codify(const char *text)
+ {
+ Docbook_DB(("(codify \"%s\")\n",text));
+ writeDocbookCodeString(m_t,text,col);
+ }
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip)
+ {
+ Docbook_DB(("(writeCodeLink)\n"));
+ writeDocbookLink(m_t,ref,file,anchor,name,tooltip);
+ col+=strlen(name);
+ }
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ )
+ {
+ Docbook_DB(("(writeToolTip)\n"));
+ }
+ void startCodeLine(bool)
+ {
+ Docbook_DB(("(startCodeLine)\n"));
+ if (m_lineNumber!=-1)
+ {
+ if (!m_refId.isEmpty())
+ {
+ m_t << "<link linkend=\"" << m_refId << "\">";
+ }
+ m_t << m_lineNumber << " ";
+ if (!m_refId.isEmpty())
+ {
+ m_t << "</link>";
+ }
+ }
+ m_insideCodeLine=TRUE;
+ col=0;
+ }
+ void endCodeLine()
+ {
+ m_t << endl;
+ Docbook_DB(("(endCodeLine)\n"));
+ m_lineNumber = -1;
+ m_refId.resize(0);
+ m_external.resize(0);
+ m_insideCodeLine=FALSE;
+ }
+ void startFontClass(const char *colorClass)
+ {
+ Docbook_DB(("(startFontClass)\n"));
+ m_t << "<emphasis class=\"" << colorClass << "\">";
+ m_insideSpecialHL=TRUE;
+ }
+ void endFontClass()
+ {
+ Docbook_DB(("(endFontClass)\n"));
+ m_t << "</emphasis>"; // non DocBook
+ m_insideSpecialHL=FALSE;
+ }
+ void writeCodeAnchor(const char *)
+ {
+ Docbook_DB(("(writeCodeAnchor)\n"));
+ }
+ void writeLineNumber(const char *extRef,const char *compId,
+ const char *anchorId,int l)
+ {
+ Docbook_DB(("(writeLineNumber)\n"));
+ // we remember the information provided here to use it
+ // at the <codeline> start tag.
+ m_lineNumber = l;
+ if (compId)
+ {
+ m_refId=compId;
+ if (anchorId) m_refId+=(QCString)"_1"+anchorId;
+ m_isMemberRef = anchorId!=0;
+ if (extRef) m_external=extRef;
+ }
+ }
+ void setCurrentDoc(Definition *,const char *,bool)
+ {
+ }
+ void addWord(const char *,bool)
+ {
+ }
+ void finish()
+ {
+ if (m_insideCodeLine) endCodeLine();
+ }
+
+ private:
+ FTextStream &m_t;
+ QCString m_refId;
+ QCString m_external;
+ int m_lineNumber;
+ bool m_isMemberRef;
+ int col;
+ bool m_insideCodeLine;
+ bool m_insideSpecialHL;
+};
+
+
+static void writeTemplateArgumentList(ArgumentList *al,
+ FTextStream &t,
+ Definition *scope,
+ FileDef *fileScope,
+ int indent)
+{
+ QCString indentStr;
+ indentStr.fill(' ',indent);
+ if (al)
+ {
+ t << indentStr << "<templateparamlist>" << endl;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ t << indentStr << " <param>" << endl;
+ if (!a->type.isEmpty())
+ {
+ t << indentStr << " <type>";
+ linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->type);
+ t << "</type>" << endl;
+ }
+ if (!a->name.isEmpty())
+ {
+ t << indentStr << " <declname>" << a->name << "</declname>" << endl;
+ t << indentStr << " <defname>" << a->name << "</defname>" << endl;
+ }
+ if (!a->defval.isEmpty())
+ {
+ t << indentStr << " <defval>";
+ linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->defval);
+ t << "</defval>" << endl;
+ }
+ t << indentStr << " </param>" << endl;
+ }
+ t << indentStr << "</templateparamlist>" << endl;
+ }
+}
+
+static void writeTemplateList(ClassDef *cd,FTextStream &t)
+{
+ writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
+}
+
+static void writeDocbookDocBlock(FTextStream &t,
+ const QCString &fileName,
+ int lineNr,
+ Definition *scope,
+ MemberDef * md,
+ const QCString &text)
+{
+ QCString stext = text.stripWhiteSpace();
+ if (stext.isEmpty()) return;
+ // convert the documentation string into an abstract syntax tree
+ DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
+ // create a code generator
+ DocbookCodeGenerator *docbookCodeGen = new DocbookCodeGenerator(t);
+ // create a parse tree visitor for Docbook
+ DocbookDocVisitor *visitor = new DocbookDocVisitor(t,*docbookCodeGen);
+ // visit all nodes
+ root->accept(visitor);
+ // clean up
+ delete visitor;
+ delete docbookCodeGen;
+ delete root;
+}
+
+void writeDocbookCodeBlock(FTextStream &t,FileDef *fd)
+{
+ ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
+ SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
+ pIntf->resetCodeParserState();
+ DocbookCodeGenerator *docbookGen = new DocbookCodeGenerator(t);
+ pIntf->parseCode(*docbookGen, // codeOutIntf
+ 0, // scopeName
+ fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
+ langExt, // lang
+ FALSE, // isExampleBlock
+ 0, // exampleName
+ fd, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inlineFragement
+ 0, // memberDef
+ TRUE // showLineNumbers
+ );
+ docbookGen->finish();
+ delete docbookGen;
+}
+
+static QCString classOutputFileBase(ClassDef *cd)
+{
+ //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ //if (inlineGroupedClasses && cd->partOfGroups()!=0)
+ return cd->getOutputFileBase();
+ //else
+ // return cd->getOutputFileBase();
+}
+
+static QCString memberOutputFileBase(MemberDef *md)
+{
+ //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
+ // return md->getClassDef()->getDocbookOutputFileBase();
+ //else
+ // return md->getOutputFileBase();
+ return md->getOutputFileBase();
+}
+
+
+static void generateDocbookForMember(MemberDef *md,FTextStream &t,Definition *def, bool detailed=0)
+{
+
+ // + declaration/definition arg lists
+ // + reimplements
+ // + reimplementedBy
+ // + exceptions
+ // + const/volatile specifiers
+ // - examples
+ // + source definition
+ // + source references
+ // + source referenced by
+ // - body code
+ // + template arguments
+ // (templateArguments(), definitionTemplateParameterLists())
+ // - call graph
+
+ // enum values are written as part of the enum
+ if (md->memberType()==MemberType_EnumValue) return;
+ if (md->isHidden()) return;
+ //if (md->name().at(0)=='@') return; // anonymous member
+
+ // group members are only visible in their group
+ //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
+ QCString memType;
+ switch (md->memberType())
+ {
+ case MemberType_Define: memType="define"; break;
+ case MemberType_Function: memType="function"; break;
+ case MemberType_Variable: memType="variable"; break;
+ case MemberType_Typedef: memType="typedef"; break;
+ case MemberType_Enumeration: memType="enum"; break;
+ case MemberType_EnumValue: ASSERT(0); break;
+ case MemberType_Signal: memType="signal"; break;
+ case MemberType_Slot: memType="slot"; break;
+ case MemberType_Friend: memType="friend"; break;
+ case MemberType_DCOP: memType="dcop"; break;
+ case MemberType_Property: memType="property"; break;
+ case MemberType_Event: memType="event"; break;
+ case MemberType_Interface: memType="interface"; break;
+ case MemberType_Service: memType="service"; break;
+ }
+ QCString scopeName;
+ if (md->getClassDef())
+ {
+ scopeName=md->getClassDef()->name();
+ }
+ else if (md->getNamespaceDef())
+ {
+ scopeName=md->getNamespaceDef()->name();
+ }
+ if (detailed==0)
+ {
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ t << " <listitem>" << endl;
+ //enum
+ bool closePara=TRUE;
+ if (md->memberType()==MemberType_Enumeration)
+ {
+ MemberList *enumFields = md->enumFieldList();
+ t << " <para><literallayout>" << memType << " <link linkend=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>";
+ if (enumFields!=0)
+ {
+ MemberListIterator emli(*enumFields);
+ MemberDef *emd;
+ t << " {" << endl;
+ int cnt=0;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ if (cnt!=0)
+ {
+ t << "," << endl;
+ }
+ t << "<link linkend=\"" << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">";
+ writeDocbookString(t,emd->name());
+ t << "</link>";
+ if (!emd->initializer().isEmpty())
+ {
+ writeDocbookString(t,emd->initializer());
+ }
+ cnt++;
+ }
+ t << endl << "}";
+ t << "</literallayout>" << endl;
+ }
+ }
+ else if (md->memberType()==MemberType_Define)
+ {
+ t << " <para>" << "#" << memType << " <link linkend=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>";
+ if (!md->initializer().isEmpty() && md->initializer().length()<2000)
+ {
+ t << " ";
+ linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->initializer());
+ }
+ if (md->briefDescription())
+ {
+ t << "<para><emphasis>";
+ writeDocbookString(t,md->briefDescription());
+ t << "</emphasis></para>" << endl;
+ }
+ }
+ else if (md->memberType()==MemberType_Variable)
+ {
+ if (md->getClassDef())
+ {
+ t << " <para>" << convertToXML(md->declaration());
+ if (md->briefDescription())
+ {
+ t << "<para><emphasis>";
+ writeDocbookString(t,md->briefDescription());
+ t << "</emphasis></para>";
+ }
+ }
+ else
+ {
+ t << " <para>";
+ linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
+ t << " <link linkend=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>";
+ }
+ }
+ else if (md->memberType()==MemberType_Typedef)
+ {
+ t << " <para>" << memType;
+ t << " ";
+ linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
+ t << " ";
+ t << " <link linkend=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>";
+ }
+ else if (md->memberType()==MemberType_Function)
+ {
+ t << " <para>";
+ linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
+ t << " <link linkend=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << convertToXML(md->name()) << "</link>";
+ t << " (" << endl;
+ ArgumentList *declAl = md->declArgumentList();
+ ArgumentList *defAl = md->argumentList();
+ if (declAl && declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ int cnt=0;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ if (cnt!=0)
+ {
+ t << ", ";
+ }
+ if (!a->type.isEmpty())
+ {
+ linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,a->type);
+ }
+ t << " ";
+ if (!a->name.isEmpty())
+ {
+ writeDocbookString(t,a->name);
+ }
+ cnt++;
+ }
+ }
+ t << ")";
+ }
+ else
+ {
+ closePara = FALSE;
+ }
+ if (closePara) t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+ else
+ {
+ if (md->memberType()==MemberType_Enumeration)
+ {
+ MemberList *enumFields = md->enumFieldList();
+ t << " <section xml:id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << endl;
+ t << " <title>" << memType << " " << convertToXML(md->name()) << " " << "</title>" << endl;
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ if (enumFields!=0)
+ {
+ MemberListIterator emli(*enumFields);
+ MemberDef *emd;
+ t << " <formalpara>" << endl;
+ t << " <title>Enumerator:</title>" << endl;
+ t << " <variablelist>" << endl;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ t << " <varlistentry xml:id=\"";
+ t << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">" << endl;
+ t << " <term>";
+ writeDocbookString(t,emd->name());
+ t << "</term>" << endl;
+ t << " <listitem>" << endl;
+ t << " <para>";
+ writeDocbookString(t,emd->briefDescription());
+ t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </varlistentry>" << endl;
+ }
+ t << " </variablelist>" << endl;
+ t << " </formalpara>" << endl;
+ t << " <para>";
+ t << "Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << endl;
+ t << " <computeroutput><literallayout>" << endl;
+ t << "{" << endl;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ writeDocbookString(t,emd->name());
+ if (!emd->initializer().isEmpty())
+ {
+ writeDocbookString(t,emd->initializer());
+ }
+ t << ", " << endl;
+ }
+ t << "}" << convertToXML(md->name()) << ";" << endl;
+ t << " </literallayout></computeroutput>" << endl;
+ t << " </para>" << endl;
+ t << " </section>" << endl;
+ }
+ }
+ else if (md->memberType()==MemberType_Typedef)
+ {
+ t << " <section xml:id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << endl;
+ t << " <title>" << convertToXML(md->definition()) << "</title>";
+ t << " <emphasis>";
+ writeDocbookString(t,md->briefDescription());
+ t << "</emphasis>" << endl;
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ t << " </section>" << endl;
+ }
+ else if (md->memberType()==MemberType_Function)
+ {
+ t << " <section xml:id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << endl;
+ t << " <title>" << convertToXML(md->definition()) << " " << convertToXML(md->argsString()) << "</title>";
+ t << " <emphasis>";
+ writeDocbookString(t,md->briefDescription());
+ t << "</emphasis>" << endl;
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ t << " </section>" << endl;
+ }
+ else if (md->memberType()==MemberType_Define)
+ {
+ if (md->documentation())
+ {
+ t << " <section xml:id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << endl;
+ t << " <title>" << convertToXML(md->definition()) << "</title>";
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ t << " <para>Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << "</para>" << endl;
+ t << " <para>The Documentation for this define was generated from the following file: </para>" << endl;
+ t << " <para><itemizedlist><listitem><para>" << stripPath(md->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
+ t << " </section>" << endl;
+ }
+ }
+ else if (md->memberType()==MemberType_Variable)
+ {
+ if (md->getClassDef())
+ {
+ if (md->documentation())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>" << convertToXML(md->definition()) << "</title>";
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ t << " <para>Definition at line " << md->getDefLine() << " of file " << stripPath(md->getDefFileName()) << "</para>" << endl;
+ t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl;
+ t << " <para><itemizedlist><listitem><para>" << stripPath(md->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
+ t << " </simplesect>" << endl;
+ }
+ }
+ else
+ {
+ t << " <section xml:id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" << md->anchor() << "\">" << endl;
+ t << " <title>" << convertToXML(md->definition()) << "</title>";
+ t << " <emphasis>";
+ writeDocbookString(t,md->briefDescription());
+ t << "</emphasis>" << endl;
+ t << " ";
+ writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << endl;
+ t << " </section>" << endl;
+ }
+ }
+ }
+}
+
+static void generateDocbookSection(Definition *d,FTextStream &t,MemberList *ml,const char *kind,
+ bool detailed=0, const char *header=0,const char *documentation=0)
+{
+ if (ml==0) return;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ int count=0;
+ int doc_count=0;
+ QCString compkind = kind;
+ QCString title, desctitle;
+
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the Docbook output, we filter those here.
+ if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ count++;
+ }
+ }
+
+ switch (ml->listType())
+ {
+ case MemberListType_decDefineMembers: title="Defines"; desctitle="Define Documentation"; break;
+ case MemberListType_decTypedefMembers: title="Typedefs"; desctitle="Typedef Documentation"; break;
+ case MemberListType_decEnumMembers: title="Enumerations"; desctitle="Enumeration Type documentation"; break;
+ case MemberListType_decFuncMembers: title="Functions"; desctitle="Function Documentation"; break;
+ case MemberListType_decVarMembers: title="Variables"; desctitle="Variable Documentation"; break;
+ case MemberListType_pubAttribs: title="Public Attributes"; desctitle="Member Documentation"; break;
+ case MemberListType_priAttribs: title="Private Attributes"; desctitle="Member Documentation"; break;
+ case MemberListType_proAttribs: title="Protected Attributes";desctitle="Member Documentation"; break;
+ default: title=""; desctitle=""; break;
+ }
+
+ if (count==0) return; // empty list
+
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->documentation())
+ {
+ doc_count++;
+ }
+ }
+
+ if (detailed)
+ {
+ if (desctitle)
+ {
+ if (desctitle=="Member Documentation")
+ {
+ if (doc_count > 0)
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>" << desctitle << "</title>" << endl;
+ }
+ }
+ else if (desctitle=="Define Documentation")
+ {
+ if (doc_count > 0)
+ {
+ t << " <section>" << endl;
+ t << " <title>" << desctitle << "</title>" << endl;
+ }
+ }
+ else
+ {
+ t << " <section>" << endl;
+ t << " <title>" << desctitle << "</title>" << endl;
+ }
+ }
+ } else
+ {
+ t << " <simplesect>" << endl;
+ if (header)
+ {
+ t << " <title>" << convertToXML(header) << "</title>" << endl;
+ }
+ else
+ {
+ t << " <title>" << title << "</title>" << endl;
+ }
+ }
+
+ if (documentation)
+ {
+ t << " <description>";
+ writeDocbookDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
+ t << "</description>" << endl;
+ }
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the Docbook output, we filter those here.
+ if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ generateDocbookForMember(md,t,d,detailed);
+ }
+ }
+ if (detailed)
+ {
+ if (desctitle)
+ {
+ if (desctitle=="Member Documentation")
+ {
+ if (doc_count > 0)
+ {
+ t << " </simplesect>" << endl;
+ }
+ }
+ else if (desctitle=="Define Documentation")
+ {
+ if (doc_count > 0)
+ {
+ t << " </section>" << endl;
+ }
+ }
+ else
+ {
+ t << " </section>" << endl;
+ }
+ }
+ }
+ else
+ {
+ t << " </simplesect>" << endl;
+ }
+}
+
+static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
+{
+ if (cl)
+ {
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ QCString title = "Classes";
+
+ if (cli.toFirst())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title> " << title << " </title>" << endl;
+ }
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (!cd->isHidden() && cd->name().find('@')==-1)
+ {
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ t << " <listitem>" << endl;
+ t << " <para>" << "struct <link linkend=\"" << classOutputFileBase(cd) << "\">" << convertToXML(cd->name()) << "</link>";
+ t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+ }
+ if (cli.toFirst())
+ {
+ t << " </simplesect>" << endl;
+ }
+ }
+}
+
+static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
+{
+ if (nl)
+ {
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ QCString title = "Namespaces";
+
+ if (nli.toFirst())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title> " << title << " </title>" << endl;
+ }
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
+ {
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ t << " <listitem>" << endl;
+ t << " <para>" << "struct <link linkend=\"" << nd->getOutputFileBase() << "\">" << convertToXML(nd->name()) << "</link>";
+ t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+ }
+ if (nli.toFirst())
+ {
+ t << " </simplesect>" << endl;
+ }
+ }
+}
+
+static void writeInnerFiles(const FileList *fl,FTextStream &t)
+{
+ if (fl)
+ {
+ QListIterator<FileDef> fli(*fl);
+ FileDef *fd;
+ QCString title = "Files";
+
+ if (fli.toFirst())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title> " << title << " </title>" << endl;
+ }
+ for (fli.toFirst();(fd=fli.current());++fli)
+ {
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ t << " <listitem>" << endl;
+ t << " <para>" << "file <link linkend=\"" << fd->getOutputFileBase() << "\">" << convertToXML(fd->name()) << "</link>";
+ t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+ if (fli.toFirst())
+ {
+ t << " </simplesect>" << endl;
+ }
+ }
+}
+
+static void writeInnerPages(const PageSDict *pl,FTextStream &t)
+{
+ if (pl)
+ {
+ PageSDict::Iterator pli(*pl);
+ PageDef *pd;
+
+ for (pli.toFirst();(pd=pli.current());++pli)
+ {
+ t << "<xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+ }
+ }
+}
+
+static void writeInnerGroups(const GroupList *gl,FTextStream &t)
+{
+ if (gl)
+ {
+ GroupListIterator gli(*gl);
+ GroupDef *sgd;
+
+ //Docbook header tags for inner groups
+ if (gli.toFirst())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Modules</title>" << endl;
+ t << " </simplesect>" << endl;
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ }
+
+ for (gli.toFirst();(sgd=gli.current());++gli)
+ {
+ t << " <listitem><para><link linkend=\"" << sgd->getOutputFileBase() << "\">" << convertToXML(sgd->groupTitle()) << "</link></para></listitem>" << endl;
+ }
+
+ //Docbook footer tags for inner groups
+ if (gli.toFirst())
+ {
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+
+ }
+}
+
+static void writeInnerDirs(const DirList *dl,FTextStream &t)
+{
+ if (dl)
+ {
+ QListIterator<DirDef> subdirs(*dl);
+ DirDef *subdir;
+ QCString title = "Directories";
+ if (subdirs.toFirst())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title> " << title << " </title>" << endl;
+ }
+ for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
+ {
+ t << " <para>" << endl;
+ t << " <itemizedlist>" << endl;
+ t << " <listitem>" << endl;
+ t << " <para>" << "dir <link linkend=\"" << subdir->getOutputFileBase() << "\">" << convertToXML(subdir->displayName()) << "</link>";
+ t << "</para>" << endl;
+ t << " </listitem>" << endl;
+ t << " </itemizedlist>" << endl;
+ t << " </para>" << endl;
+ }
+ if (subdirs.toFirst())
+ {
+ t << " </simplesect>" << endl;
+ }
+ }
+}
+
+static void writeInnerGroupFiles(const GroupList *gl,FTextStream &t)
+{
+ if (gl)
+ {
+ GroupListIterator gli(*gl);
+ GroupDef *sgd;
+
+ for (gli.toFirst();(sgd=gli.current());++gli)
+ {
+ t << "<xi:include href=\"" << sgd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+ }
+ }
+}
+
+static void generateDocbookForClass(ClassDef *cd,FTextStream &ti)
+{
+ // + brief description
+ // + detailed description
+ // + template argument list(s)
+ // - include file
+ // + member groups
+ // + inheritance diagram
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + list of inner classes
+ // + collaboration diagram
+ // + list of all members
+ // + user defined member sections
+ // + standard member sections
+ // + detailed member documentation
+ // - examples using the class
+
+ if (cd->isReference()) return; // skip external references.
+ if (cd->isHidden()) return; // skip hidden classes.
+ if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
+ if (cd->templateMaster()!=0) return; // skip generated template instances.
+
+ msg("Generating Docbook output for class %s\n",cd->name().data());
+
+ QCString fileDocbook=cd->getOutputFileBase()+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
+ QCString relPath = relativePathToRoot(fileName);
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ writeDocbookHeader_ID(t, classOutputFileBase(cd));
+ t << "<title>";
+ writeDocbookString(t,cd->name());
+ t << " " << cd->compoundTypeString() << " Reference";
+ t << "</title>" << endl;
+
+ IncludeInfo *ii=cd->includeInfo();
+ if (ii)
+ {
+ QCString nm = ii->includeName;
+ if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
+ if (!nm.isEmpty())
+ {
+ t << "<para>" << endl;
+ t << " <programlisting>#include ";
+ if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
+ {
+ t << "<link linkend=\"" << ii->fileDef->getOutputFileBase() << "\">";
+ }
+ if (ii->local)
+ {
+ t << """;
+ }
+ else
+ {
+ t << "<";
+ }
+ t << convertToXML(nm);
+ if (ii->local)
+ {
+ t << """;
+ }
+ else
+ {
+ t << ">";
+ }
+ if (ii->fileDef && !ii->fileDef->isReference())
+ {
+ t << "</link>";
+ }
+ t << "</programlisting>" << endl;
+ t << "</para>" << endl;
+ }
+ }
+
+ if (Config_getBool("HAVE_DOT") && (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))
+ {
+ t << "<para>Inheritance diagram for " << convertToXML(cd->name()) << "</para>" << endl;
+ DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
+ inheritanceGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,TRUE,FALSE);
+ }
+
+ if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
+ {
+ t << "<para>Collaboration diagram for " << convertToXML(cd->name()) << "</para>" << endl;
+ DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
+ collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,TRUE,FALSE);
+ }
+
+ writeInnerClasses(cd->getClassSDict(),t);
+
+ writeTemplateList(cd,t);
+ if (cd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateDocbookSection(cd,t,mg->members(),"user-defined",0,mg->header(),
+ mg->documentation());
+ }
+ }
+
+
+ QListIterator<MemberList> mli(cd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType()));
+ }
+ }
+ if (cd->briefDescription())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Brief Description</title>" << endl;
+ writeDocbookDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
+ t << " </simplesect>" << endl;
+ }
+
+ if (cd->documentation())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Detailed Description</title>" << endl;
+ writeDocbookDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
+ t << " <para>Definition at line " << cd->getDefLine() << " of file " << stripPath(cd->getDefFileName()) << "</para>" << endl;
+ t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl;
+ t << " <para><itemizedlist><listitem><para>" << stripPath(cd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
+ t << " </simplesect>" << endl;
+ }
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
+ }
+ }
+
+ /*// TODO: Handling of Inheritance and Colloboration graph for Docbook to be implemented
+ DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial())
+ {
+ t << " <inheritancegraph>" << endl;
+ inheritanceGraph.writeDocbook(t);
+ t << " </inheritancegraph>" << endl;
+ }
+ DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
+ if (!collaborationGraph.isTrivial())
+ {
+ t << " <collaborationgraph>" << endl;
+ collaborationGraph.writeDocbook(t);
+ t << " </collaborationgraph>" << endl;
+ }
+ t << " <location file=\""
+ << cd->getDefFileName() << "\" line=\""
+ << cd->getDefLine() << "\"";
+ if (cd->getStartBodyLine()!=-1)
+ {
+ FileDef *bodyDef = cd->getBodyDef();
+ if (bodyDef)
+ {
+ t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
+ }
+ t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
+ << cd->getEndBodyLine() << "\"";
+ }
+ t << "/>" << endl;
+ writeListOfAllMembers(cd,t);
+ */
+
+ t << "</section>" << endl;
+
+}
+
+static void generateDocbookForNamespace(NamespaceDef *nd,FTextStream &ti)
+{
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // + location
+ // - files containing (parts of) the namespace definition
+
+ if (nd->isReference() || nd->isHidden()) return; // skip external references
+
+ QCString fileDocbook=nd->getOutputFileBase()+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ writeDocbookHeader_ID(t, nd->getOutputFileBase());
+ t << "<title>";
+ writeDocbookString(t,nd->name());
+ t << "</title>" << endl;
+
+ writeInnerClasses(nd->getClassSDict(),t);
+ writeInnerNamespaces(nd->getNamespaceSDict(),t);
+
+ if (nd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateDocbookSection(nd,t,mg->members(),"user-defined",0,mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(nd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateDocbookSection(nd,t,ml,g_docbookSectionMapper.find(ml->listType()));
+ }
+ }
+
+ if (nd->briefDescription())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Brief Description</title>" << endl;
+ writeDocbookDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
+ t << " </simplesect>" << endl;
+ }
+
+ if (nd->documentation())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Detailed Description</title>" << endl;
+ writeDocbookDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
+ t << " <para>Definition at line " << nd->getDefLine() << " of file " << stripPath(nd->getDefFileName()) << "</para>" << endl;
+ t << " <para>The Documentation for this struct was generated from the following file: </para>" << endl;
+ t << " <para><itemizedlist><listitem><para>" << stripPath(nd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
+ t << " </simplesect>" << endl;
+ }
+ t << "</section>" << endl;
+}
+
+static void generateDocbookForFile(FileDef *fd,FTextStream &ti)
+{
+ // + includes files
+ // + includedby files
+ // + include graph
+ // + included by graph
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // + source code
+ // + location
+ // - number of lines
+
+ if (fd->isReference()) return; // skip external references
+
+ QCString fileDocbook=fd->getOutputFileBase()+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
+ QCString relPath = relativePathToRoot(fileName);
+
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeDocbookHeader_ID(t, fd->getOutputFileBase());
+
+ t << " <title>";
+ writeDocbookString(t,fd->name());
+ t << " File Reference";
+ t << "</title>" << endl;
+
+ IncludeInfo *inc;
+
+ if (fd->includeFileList())
+ {
+ QListIterator<IncludeInfo> ili1(*fd->includeFileList());
+ for (ili1.toFirst();(inc=ili1.current());++ili1)
+ {
+ t << " <programlisting>#include ";
+ if (inc->local)
+ {
+ t << """;
+ }
+ else
+ {
+ t << "<";
+ }
+ t << convertToXML(inc->includeName);
+ if (inc->local)
+ {
+ t << """;
+ }
+ else
+ {
+ t << ">";
+ }
+ t << "</programlisting>" << endl;
+ }
+ }
+ if (Config_getBool("HAVE_DOT"))
+ {
+ if (Config_getBool("INCLUDE_GRAPH"))
+ {
+ t << "<para>Include dependency diagram for " << convertToXML(fd->name()) << "</para>" << endl;
+ DotInclDepGraph idepGraph(fd, FALSE);
+ idepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,FALSE);
+ }
+ if (Config_getBool("INCLUDED_BY_GRAPH"))
+ {
+ t << "<para>Included by dependency diagram for " << convertToXML(fd->name()) << "</para>" << endl;
+ DotInclDepGraph ibdepGraph(fd, TRUE);
+ ibdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,FALSE);
+ }
+ }
+
+ if (fd->getClassSDict())
+ {
+ writeInnerClasses(fd->getClassSDict(),t);
+ }
+ if (fd->getNamespaceSDict())
+ {
+ writeInnerNamespaces(fd->getNamespaceSDict(),t);
+ }
+
+ if (fd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateDocbookSection(fd,t,mg->members(),"user-defined",0,mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(fd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateDocbookSection(fd,t,ml,g_docbookSectionMapper.find(ml->listType()));
+ }
+ }
+
+ t << " <simplesect>" << endl;
+ t << " <title>Detailed Description</title>" << endl;
+ writeDocbookDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
+ writeDocbookDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ t << " <para>Definition in file " << fd->getDefFileName() << "</para>" << endl;
+ }
+ else
+ {
+ t << " <para>Definition in file " << stripPath(fd->getDefFileName()) << "</para>" << endl;
+ }
+ t << " </simplesect>" << endl;
+
+ if (Config_getBool("DOCBOOK_PROGRAMLISTING"))
+ {
+ t << " <literallayout><computeroutput>" << endl;
+ writeDocbookCodeBlock(t,fd);
+ t << " </computeroutput></literallayout>" << endl;
+ }
+
+ t << "</section>" << endl;
+}
+
+static void generateDocbookForGroup(GroupDef *gd,FTextStream &ti)
+{
+ // + members
+ // + member groups
+ // + files
+ // + classes
+ // + namespaces
+ // - packages
+ // + pages
+ // + child groups
+ // - examples
+ // + brief description
+ // + detailed description
+
+ if (gd->isReference()) return; // skip external references
+
+ if (!gd->isASubGroup())
+ {
+ QCString fileDocbook=gd->getOutputFileBase()+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+ }
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
+ QCString relPath = relativePathToRoot(fileName);
+
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeDocbookHeader_ID(t, gd->getOutputFileBase());
+
+ t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
+
+ if (Config_getBool("GROUP_GRAPHS") && Config_getBool("HAVE_DOT"))
+ {
+ t << "<para>Collaboration diagram for " << convertToXML(gd->groupTitle()) << "</para>" << endl;
+ DotGroupCollaboration collaborationGraph(gd);
+ collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,FALSE);
+ }
+
+ if (gd->briefDescription())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Brief Description</title>" << endl;
+ writeDocbookDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
+ t << " </simplesect>" << endl;
+ }
+
+ if (gd->documentation())
+ {
+ t << " <simplesect>" << endl;
+ t << " <title>Detailed Description</title>" << endl;
+ writeDocbookDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
+ t << " </simplesect>" << endl;
+ }
+
+ writeInnerFiles(gd->getFiles(),t);
+ writeInnerClasses(gd->getClasses(),t);
+ writeInnerNamespaces(gd->getNamespaces(),t);
+ writeInnerPages(gd->getPages(),t);
+ writeInnerGroups(gd->getSubGroups(),t);
+
+ if (gd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateDocbookSection(gd,t,mg->members(),"user-defined",0,mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(gd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType()));
+ }
+ }
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
+ }
+ }
+
+ writeInnerGroupFiles(gd->getSubGroups(),t);
+
+ t << "</section>" << endl;
+
+}
+
+static void generateDocbookForDir(DirDef *dd,FTextStream &ti)
+{
+ if (dd->isReference()) return; // skip external references
+
+ QCString fileDocbook=dd->getOutputFileBase()+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ QCString relPath = relativePathToRoot(fileName);
+
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeDocbookHeader_ID(t, dd->getOutputFileBase());
+
+ t << " <title>";
+ writeDocbookString(t, dd->displayName());
+ t << " Directory Reference";
+ t << "</title>" << endl;
+ if (Config_getBool("DIRECTORY_GRAPH") && Config_getBool("HAVE_DOT"))
+ {
+ t << "<para>Directory dependency diagram for " << convertToXML(dd->displayName()) << "</para>" << endl;
+ DotDirDeps dirdepGraph(dd);
+ dirdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString("DOCBOOK_OUTPUT"),fileName,relPath,FALSE);
+ }
+
+ writeInnerDirs(&dd->subDirs(),t);
+ writeInnerFiles(dd->getFiles(),t);
+
+ t << " <simplesect>" << endl;
+ t << " <title>Detailed Description</title>" << endl;
+ writeDocbookDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
+ writeDocbookDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
+ t << " <para>Directory location is " << dd->name() << "</para>" << endl;
+ t << " </simplesect>" << endl;
+
+ t << "</section>" << endl;
+}
+
+static void generateDocbookForPage(PageDef *pd,FTextStream &ti,bool isExample)
+{
+ // + name
+ // + title
+ // + documentation
+
+ if (pd->isReference()) return;
+
+ QCString pageName = pd->getOutputFileBase();
+ if (pd->getGroupDef())
+ {
+ pageName+=(QCString)"_"+pd->name();
+ }
+ if (pageName=="index")
+ {
+ pageName="mainpage"; // to prevent overwriting the generated index page.
+ }
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ QCString fileName=outputDirectory+"/"+pageName+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ if(isExample)
+ {
+ QCString fileDocbook=pageName+".xml";
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+ }
+
+ if (!pd->hasParentPage() && !isExample)
+ {
+ QCString fileDocbook=pageName+".xml";
+ //Add the file Documentation info to index file
+ ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
+ writeDocbookHeaderMainpage(t);
+ }
+ else
+ {
+ QCString pid = pageName+"_1"+pageName;
+ writeDocbookHeader_ID(t, pid);
+ }
+
+ SectionInfo *si = Doxygen::sectionDict->find(pd->name());
+ if (si)
+ {
+ t << " <title>" << convertToXML(si->title) << "</title>" << endl;
+ }
+ else
+ {
+ t << " <title>" << convertToXML(pd->name()) << "</title>" << endl;
+ }
+
+ if (isExample)
+ {
+ writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
+ pd->documentation()+"\n\\include "+pd->name());
+ }
+ else
+ {
+ writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
+ pd->documentation());
+ }
+ writeInnerPages(pd->getSubPages(),t);
+
+ if (!pd->hasParentPage() && !isExample)
+ {
+ t << endl << "</chapter>" << endl;
+ }
+ else
+ {
+ t << endl << "</section>" << endl;
+ }
+}
+
+void generateDocbook()
+{
+
+ // + classes
+ // + namespaces
+ // + files
+ // + groups
+ // + related pages
+ // - examples
+
+ QCString outputDirectory = Config_getString("DOCBOOK_OUTPUT");
+ if (outputDirectory.isEmpty())
+ {
+ outputDirectory=QDir::currentDirPath().utf8();
+ }
+ else
+ {
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("tag DOCBOOK_OUTPUT: Output directory `%s' does not "
+ "exist and cannot be created\n",outputDirectory.data());
+ exit(1);
+ }
+ else
+ {
+ msg("Notice: Output directory `%s' does not exist. "
+ "I have created it for you.\n", outputDirectory.data());
+ }
+ dir.cd(outputDirectory);
+ }
+ outputDirectory=dir.absPath().utf8();
+ }
+
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("Cannot create directory %s\n",outputDirectory.data());
+ return;
+ }
+ }
+ QDir docbookDir(outputDirectory);
+ createSubDirs(docbookDir);
+
+ QCString fileName=outputDirectory+"/index.xml";
+ QCString dbk_projectName = Config_getString("PROJECT_NAME");
+ QFile f(fileName);
+
+ f.setName(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ // write index header for Docbook which calls the structure file
+ t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
+ t << "<book xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" << endl;
+ t << " <info>" << endl;
+ t << " <title>" << dbk_projectName << "</title>" << endl;
+ t << " </info>" << endl;
+
+ // NAMESPACE DOCUMENTATION
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+
+ //Namespace Documentation index header
+ if (nli.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>Namespace Documentation</title>" << endl;
+ }
+
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ msg("Generating Docbook output for namespace %s\n",nd->name().data());
+ generateDocbookForNamespace(nd,t);
+ }
+
+ //Namespace Documentation index footer
+ if (nli.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+
+ /** MAINPAGE DOCUMENTATION **/
+
+ if (Doxygen::mainPage)
+ {
+ msg("Generating Docbook output for the main page\n");
+ generateDocbookForPage(Doxygen::mainPage,t,FALSE);
+ }
+
+ // PAGE DOCUMENTATION
+ {
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating Docbook output for page %s\n",pd->name().data());
+ generateDocbookForPage(pd,t,FALSE);
+ }
+ }
+
+ /** MODULE GROUP DOCUMENTATION **/
+
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+
+ //Module group Documentation index header
+ if (gli.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>Module Documentation</title>" << endl;
+ }
+
+ for (;(gd=gli.current());++gli)
+ {
+ msg("Generating Docbook output for group %s\n",gd->name().data());
+ generateDocbookForGroup(gd,t);
+ }
+
+ //Module group Documentation index footer
+ if (gli.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+
+ //CLASS DOCUMENTATION
+
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+
+ //Class Documentation index header
+ if (cli.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>Class Documentation</title>" << endl;
+ }
+
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ generateDocbookForClass(cd,t);
+ }
+
+ //Class Documentation index footer
+ if (cli.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+ }
+
+ // FILE DOCUMENTATION
+
+ static bool showFiles = Config_getBool("SHOW_FILES");
+ if (showFiles)
+ {
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+
+ //File Documentation index header
+ if (fnli.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>File Documentation</title>" << endl;
+ }
+
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ msg("Generating Docbook output for file %s\n",fd->name().data());
+ generateDocbookForFile(fd,t);
+ }
+ }
+
+ //File Documentation index footer
+ if (fnli.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+ }
+
+ // DIRECTORY DOCUMENTATION
+ if (Config_getBool("DIRECTORY_GRAPH") && Config_getBool("HAVE_DOT"))
+ {
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+
+ //Directory Documentation index header
+ if (sdi.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>Directory Documentation</title>" << endl;
+ }
+
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ msg("Generate Docbook output for dir %s\n",dir->name().data());
+ generateDocbookForDir(dir,t);
+ }
+
+ //Module group Documentation index footer
+ if (sdi.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+ }
+
+ // EXAMPLE PAGE DOCUMENTATION
+
+ {
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=0;
+
+ //Example Page Documentation index header
+ if (pdi.toFirst())
+ {
+ t << " <chapter>" << endl;
+ t << " <title>Example Documentation</title>" << endl;
+ }
+
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating Docbook output for example %s\n",pd->name().data());
+ generateDocbookForPage(pd,t,TRUE);
+ }
+
+ //Example Page Documentation index footer
+ if (pdi.toFirst())
+ {
+ t << " </chapter>" << endl;
+ }
+ }
+
+ t << "</book>" << endl;
+
+}
+
+
diff --git a/src/docbookgen.h b/src/docbookgen.h
new file mode 100644
index 0000000..0431cf2
--- /dev/null
+++ b/src/docbookgen.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+*
+*
+*
+* Copyright (C) 1997-2014 by Dimitri van Heesch.
+*
+* Permission to use, copy, modify, and distribute this software and its
+* documentation under the terms of the GNU General Public License is hereby
+* granted. No representations are made about the suitability of this software
+* for any purpose. It is provided "as is" without express or implied warranty.
+* See the GNU General Public License for more details.
+*
+*/
+
+#ifndef DOCBOOKGEN_H
+#define DOCBOOKGEN_H
+
+void generateDocbook();
+
+#endif
diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp
new file mode 100644
index 0000000..9f2dbe3
--- /dev/null
+++ b/src/docbookvisitor.cpp
@@ -0,0 +1,1456 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfileinfo.h>
+
+#include "docbookvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "docbookgen.h"
+#include "dot.h"
+#include "message.h"
+#include "util.h"
+#include "parserintf.h"
+#include "filename.h"
+#include "config.h"
+#include "filedef.h"
+#include "msc.h"
+#include "dia.h"
+#include "htmlentity.h"
+#include "plantuml.h"
+
+DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci)
+ : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
+{
+}
+
+//--------------------------------------
+// visitor functions for leaf nodes
+//--------------------------------------
+
+void DocbookDocVisitor::visit(DocWord *w)
+{
+ if (m_hide) return;
+ filter(w->word());
+}
+
+void DocbookDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ startLink(w->file(),w->anchor());
+ filter(w->word());
+ endLink();
+}
+
+void DocbookDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ }
+ else
+ {
+ m_t << " ";
+ }
+}
+
+void DocbookDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ const char *res = HtmlEntityMapper::instance()->docbook(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ err("DocBook: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+}
+
+void DocbookDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ m_t << "<link xlink:href=\"";
+ if (u->isEmail()) m_t << "mailto:";
+ filter(u->url());
+ m_t << "\">";
+ filter(u->url());
+ m_t << "</link>";
+}
+
+void DocbookDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ m_t << endl << "<literallayout>\n</literallayout>" << endl;
+}
+
+void DocbookDocVisitor::visit(DocHorRuler *)
+{
+ if (m_hide) return;
+ m_t << "<informaltable frame='bottom'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>\n";
+ m_t << "</entry></row></tbody></tgroup></informaltable>\n";
+}
+
+void DocbookDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "<emphasis role=\"bold\">"; else m_t << "</emphasis>";
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>";
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>";
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "<subscript>"; else m_t << "</subscript>";
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "<superscript>"; else m_t << "</superscript>";
+ break;
+ case DocStyleChange::Center:
+ if (s->enable()) m_t << "<informaltable frame='none'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>";
+ else m_t << "</entry></row></tbody></tgroup></informaltable>";
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ m_t << "<literallayout>";
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_t << "</literallayout>";
+ m_insidePre=FALSE;
+ }
+ break;
+ /* There is no equivalent Docbook tag for rendering Small text */
+ case DocStyleChange::Small: /* XSLT Stylesheets can be used */ break;
+ /* HTML only */
+ case DocStyleChange::Div: /* HTML only */ break;
+ case DocStyleChange::Span: /* HTML only */ break;
+ }
+}
+
+void DocbookDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ switch(s->type())
+ {
+ case DocVerbatim::Code: // fall though
+ m_t << "<literallayout><computeroutput>";
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,s->context(),s->text(),langExt,
+ s->isExample(),s->exampleFile());
+ m_t << "</computeroutput></literallayout>";
+ break;
+ case DocVerbatim::Verbatim:
+ m_t << "<literallayout>";
+ filter(s->text());
+ m_t << "</literallayout>";
+ break;
+ case DocVerbatim::HtmlOnly:
+ break;
+ case DocVerbatim::RtfOnly:
+ break;
+ case DocVerbatim::ManOnly:
+ break;
+ case DocVerbatim::LatexOnly:
+ break;
+ case DocVerbatim::XmlOnly:
+ break;
+ case DocVerbatim::DocbookOnly:
+ break;
+ m_t << s->text();
+ break;
+ case DocVerbatim::Dot:
+ {
+ static int dotindex = 1;
+ QCString baseName(4096);
+ QCString name;
+ QCString stext = s->text();
+ m_t << "<para>" << endl;
+ name.sprintf("%s%d", "dot_inline_dotgraph_", dotindex);
+ baseName.sprintf("%s%d",
+ (Config_getString("DOCBOOK_OUTPUT")+"/inline_dotgraph_").data(),
+ dotindex++
+ );
+ QFile file(baseName+".dot");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s.msc for writing\n",baseName.data());
+ }
+ file.writeBlock( stext, stext.length() );
+ file.close();
+ m_t << " <figure>" << endl;
+ m_t << " <title>" << name << "</title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ writeDotFile(baseName);
+ m_t << " </imageobject>" << endl;
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+ }
+ break;
+ case DocVerbatim::Msc:
+ {
+ static int mscindex = 1;
+ QCString baseName(4096);
+ QCString name;
+ QCString stext = s->text();
+ m_t << "<para>" << endl;
+ name.sprintf("%s%d", "msc_inline_mscgraph_", mscindex);
+ baseName.sprintf("%s%d",
+ (Config_getString("DOCBOOK_OUTPUT")+"/inline_mscgraph_").data(),
+ mscindex++
+ );
+ QFile file(baseName+".msc");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s.msc for writing\n",baseName.data());
+ }
+ QCString text = "msc {";
+ text+=stext;
+ text+="}";
+ file.writeBlock( text, text.length() );
+ file.close();
+ m_t << " <figure>" << endl;
+ m_t << " <title>" << name << "</title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ writeMscFile(baseName);
+ m_t << " </imageobject>" << endl;
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+ }
+ break;
+ case DocVerbatim::PlantUML:
+ {
+ static QCString docbookOutput = Config_getString("DOCBOOK_OUTPUT");
+ QCString baseName = writePlantUMLSource(docbookOutput,s->exampleFile(),s->text());
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ m_t << " <figure>" << endl;
+ m_t << " <title>" << shortName << "</title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ writePlantUMLFile(baseName);
+ m_t << " </imageobject>" << endl;
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+ }
+ break;
+ }
+}
+
+void DocbookDocVisitor::visit(DocAnchor *anc)
+{
+ if (m_hide) return;
+ m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
+}
+
+void DocbookDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ {
+ m_t << "<literallayout><computeroutput>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(), &fd);
+ m_t << "</computeroutput></literallayout>";
+ }
+ break;
+ case DocInclude::Include:
+ m_t << "<literallayout><computeroutput>";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile());
+ m_t << "</computeroutput></literallayout>";
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ break;
+ case DocInclude::LatexInclude:
+ break;
+ case DocInclude::VerbInclude:
+ m_t << "<verbatim>";
+ filter(inc->text());
+ m_t << "</verbatim>";
+ break;
+ case DocInclude::Snippet:
+ m_t << "<literallayout><computeroutput>";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile()
+ );
+ m_t << "</computeroutput></literallayout>";
+ break;
+ }
+}
+
+void DocbookDocVisitor::visit(DocIncOperator *op)
+{
+ if (op->isFirst())
+ {
+ if (!m_hide)
+ {
+ m_t << "<programlisting>";
+ }
+ pushEnabled();
+ m_hide = TRUE;
+ }
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,op->context(),
+ op->text(),langExt,op->isExample(),
+ op->exampleFile());
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide) m_t << "</programlisting>";
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ }
+}
+
+void DocbookDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ m_t << "<equation><title>" << f->name() << "</title>";
+ filter(f->text());
+ m_t << "</equation>";
+}
+
+void DocbookDocVisitor::visit(DocIndexEntry *ie)
+{
+ if (m_hide) return;
+ m_t << "<indexentry><primaryie>" << endl;
+ filter(ie->entry());
+ m_t << "</primaryie><secondaryie></secondaryie></indexentry>" << endl;
+}
+
+void DocbookDocVisitor::visit(DocSimpleSectSep *)
+{
+ m_t << "<simplesect/>";
+}
+
+void DocbookDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ if (!cite->file().isEmpty()) startLink(cite->file(),cite->anchor());
+ filter(cite->text());
+ if (!cite->file().isEmpty()) endLink();
+}
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void DocbookDocVisitor::visitPre(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "<orderedlist>\n";
+ }
+ else
+ {
+ m_t << "<itemizedlist>\n";
+ }
+}
+
+void DocbookDocVisitor::visitPost(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "</orderedlist>\n";
+ }
+ else
+ {
+ m_t << "</itemizedlist>\n";
+ }
+}
+
+void DocbookDocVisitor::visitPre(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void DocbookDocVisitor::visitPost(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>";
+}
+
+void DocbookDocVisitor::visitPre(DocPara *)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_t << "<para>";
+}
+
+void DocbookDocVisitor::visitPost(DocPara *)
+{
+ if (m_hide) return;
+ m_t << "</para>";
+ m_t << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocRoot *)
+{
+ //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocRoot *)
+{
+ //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trSeeAlso() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trSeeAlso()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Return:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trReturns()<< ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trReturns()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Author:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, TRUE) << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, TRUE)) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Authors:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, FALSE) << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, FALSE)) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Version:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trVersion() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trVersion()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Since:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trSince() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trSince()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Date:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trDate() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trDate()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Note:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trNote() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trNote()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Warning:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trWarning() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trWarning()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Pre:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trPrecondition() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trPrecondition()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Post:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trPostcondition() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trPostcondition()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Copyright:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trCopyright() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trCopyright()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Invar:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trInvariant() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trInvariant()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Remark:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trRemarks() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trRemarks()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::Attention:
+ if (m_insidePre)
+ {
+ m_t << "<formalpara><title>" << theTranslator->trAttention() << ": </title>" << endl;
+ }
+ else
+ {
+ m_t << "<formalpara><title>" << convertToXML(theTranslator->trAttention()) << ": </title>" << endl;
+ }
+ break;
+ case DocSimpleSect::User:
+ m_t << "<formalpara><title></title>" << endl;
+ break;
+ case DocSimpleSect::Rcs:
+ m_t << "<formalpara><title></title>" << endl;
+ break;
+ case DocSimpleSect::Unknown: m_t << "<formalpara><title></title>" << endl; break;
+ }
+}
+
+void DocbookDocVisitor::visitPost(DocSimpleSect *)
+{
+ if (m_hide) return;
+ m_t << "</formalpara>" << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "<title>";
+}
+
+void DocbookDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "</title>";
+}
+
+void DocbookDocVisitor::visitPre(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "<itemizedlist>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "</itemizedlist>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void DocbookDocVisitor::visitPost(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ m_t << "<section xml:id=\"" << s->file();
+ if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor();
+ m_t << "\">" << endl;
+ m_t << "<title>";
+ filter(s->title());
+ m_t << "</title>" << endl;
+}
+
+void DocbookDocVisitor::visitPost(DocSection *)
+{
+ m_t << "</section>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "<orderedlist>\n";
+ else
+ m_t << "<itemizedlist>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "</orderedlist>\n";
+ else
+ m_t << "</itemizedlist>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ m_t << "<variablelist>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ m_t << "</variablelist>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "<varlistentry><term>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "</term>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ m_t << "</listitem></varlistentry>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlTable *t)
+{
+ if (m_hide) return;
+ m_t << "<table frame=\"all\">" << endl;
+ m_t << " <title></title>" << endl;
+ m_t << " <tgroup cols=\"" << t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl;
+ m_t << " <tbody>" << endl;
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlTable *)
+{
+ if (m_hide) return;
+ m_t << " </tbody>" << endl;
+ m_t << " </tgroup>" << endl;
+ m_t << "</table>" << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlRow *)
+{
+ if (m_hide) return;
+ m_t << "<row>\n";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlRow *)
+{
+ if (m_hide) return;
+ m_t << "</row>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlCell *)
+{
+ if (m_hide) return;
+ m_t << "<entry>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlCell *)
+{
+ if (m_hide) return;
+ m_t << "</entry>";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "<caption>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "</caption>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ // TODO: to be implemented
+}
+
+void DocbookDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ // TODO: to be implemented
+}
+
+void DocbookDocVisitor::visitPre(DocHRef *href)
+{
+ if (m_hide) return;
+ m_t << "<link xlink:href=\"" << href->url() << "\">";
+}
+
+void DocbookDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "</link>";
+}
+
+void DocbookDocVisitor::visitPre(DocHtmlHeader *)
+{
+ if (m_hide) return;
+ m_t << "<formalpara><title>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlHeader *)
+{
+ if (m_hide) return;
+ m_t << "</title></formalpara>\n";
+}
+
+void DocbookDocVisitor::visitPre(DocImage *img)
+{
+ if (img->type()==DocImage::DocBook)
+ {
+ if (m_hide) return;
+ m_t << endl;
+ m_t << " <figure>" << endl;
+ m_t << " <title>";
+ }
+ else
+ {
+ pushEnabled();
+ m_hide=TRUE;
+ }
+}
+
+void DocbookDocVisitor::visitPost(DocImage *img)
+{
+ if (img->type()==DocImage::DocBook)
+ {
+ if (m_hide) return;
+ QCString typevar;
+ m_t << "</title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ QCString baseName=img->name();
+ int i;
+ if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ m_t << " <imagedata";
+ if (!img->width().isEmpty())
+ {
+ m_t << " width=\"";
+ filter(img->width());
+ m_t << "\"";
+ }
+ else
+ {
+ m_t << " width=\"50%\"";
+ }
+ if (!img->height().isEmpty())
+ {
+ m_t << " depth=\"";
+ filter(img->height());
+ m_t << "\"";
+ }
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << "\">";
+ m_t << "</imagedata>" << endl;
+ m_t << " </imageobject>" << endl;
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ // copy the image to the output dir
+ QCString m_file;
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::imageNameDict, baseName, ambig);
+ if (fd)
+ {
+ m_file=fd->absFilePath();
+ }
+ QFile inImage(m_file);
+ QFile outImage(Config_getString("DOCBOOK_OUTPUT")+"/"+baseName.data());
+ if (inImage.open(IO_ReadOnly))
+ {
+ if (outImage.open(IO_WriteOnly))
+ {
+ char *buffer = new char[inImage.size()];
+ inImage.readBlock(buffer,inImage.size());
+ outImage.writeBlock(buffer,inImage.size());
+ outImage.flush();
+ delete[] buffer;
+ }
+ }
+ }
+ else
+ {
+ popEnabled();
+ }
+}
+
+void DocbookDocVisitor::visitPre(DocDotFile *df)
+{
+ if (m_hide) return;
+ startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void DocbookDocVisitor::visitPost(DocDotFile *df)
+{
+ if (m_hide) return;
+ endDotFile(df->hasCaption());
+}
+
+void DocbookDocVisitor::visitPre(DocMscFile *df)
+{
+ if (m_hide) return;
+ startMscFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void DocbookDocVisitor::visitPost(DocMscFile *df)
+{
+ if (m_hide) return;
+ endMscFile(df->hasCaption());
+}
+void DocbookDocVisitor::visitPre(DocDiaFile *df)
+{
+ if (m_hide) return;
+ startDiaFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void DocbookDocVisitor::visitPost(DocDiaFile *df)
+{
+ if (m_hide) return;
+ endDiaFile(df->hasCaption());
+}
+
+void DocbookDocVisitor::visitPre(DocLink *lnk)
+{
+ if (m_hide) return;
+ startLink(lnk->file(),lnk->anchor());
+}
+
+void DocbookDocVisitor::visitPost(DocLink *)
+{
+ if (m_hide) return;
+ endLink();
+}
+
+void DocbookDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty()) startLink(ref->file(),ref->anchor());
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void DocbookDocVisitor::visitPost(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty()) endLink();
+}
+
+void DocbookDocVisitor::visitPre(DocSecRefItem *ref)
+{
+ if (m_hide) return;
+ m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
+}
+
+void DocbookDocVisitor::visitPost(DocSecRefItem *)
+{
+ if (m_hide) return;
+ m_t << "</tocitem>" << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "<toclist>" << endl;
+}
+
+void DocbookDocVisitor::visitPost(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "</toclist>" << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_t << " <formalpara>" << endl;
+ m_t << " <title/>" << endl;
+ m_t << " <table frame=\"all\">" << endl;
+ m_t << " <title>";
+ switch(s->type())
+ {
+ case DocParamSect::Param: m_t << theTranslator->trParameters(); break;
+ case DocParamSect::RetVal: m_t << theTranslator->trReturnValues(); break;
+ case DocParamSect::Exception: m_t << theTranslator->trExceptions(); break;
+ case DocParamSect::TemplateParam: m_t << theTranslator->trTemplateParameters(); break;
+ default:
+ ASSERT(0);
+ }
+ m_t << " </title>" << endl;
+ m_t << " <tgroup cols=\"2\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl;
+ m_t << " <tbody>" << endl;
+}
+
+void DocbookDocVisitor::visitPost(DocParamSect *)
+{
+ if (m_hide) return;
+ m_t << " </tbody>" << endl;
+ m_t << " </tgroup>" << endl;
+ m_t << " </table>" << endl;
+ m_t << " </formalpara>" << endl;
+ m_t << " ";
+}
+
+void DocbookDocVisitor::visitPre(DocParamList *pl)
+{
+ if (m_hide) return;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ m_t << " <row>" << endl;
+ if (!li.toFirst())
+ {
+ m_t << " <entry></entry>" << endl;
+ }
+ else
+ {
+ m_t << " <entry>";
+ int cnt = 0;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (cnt)
+ {
+ m_t << ", ";
+ }
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ cnt++;
+ }
+ m_t << "</entry>" << endl;
+ }
+ m_t << " <entry>";
+}
+
+void DocbookDocVisitor::visitPost(DocParamList *)
+{
+ if (m_hide) return;
+ m_t << "</entry>" << endl;
+ m_t << " </row>" << endl;
+}
+
+void DocbookDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "<para><link linkend=\"";
+ m_t << x->file() << "_1" << x->anchor();
+ m_t << "\">";
+ filter(x->title());
+ m_t << "</link>";
+ m_t << " ";
+}
+
+void DocbookDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "</para>";
+}
+
+void DocbookDocVisitor::visitPre(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ startLink(ref->file(),ref->anchor());
+}
+
+void DocbookDocVisitor::visitPost(DocInternalRef *)
+{
+ if (m_hide) return;
+ endLink();
+ m_t << " ";
+}
+
+void DocbookDocVisitor::visitPre(DocCopy *)
+{
+ if (m_hide) return;
+ // TODO: to be implemented
+}
+
+
+void DocbookDocVisitor::visitPost(DocCopy *)
+{
+ if (m_hide) return;
+ // TODO: to be implemented
+}
+
+
+void DocbookDocVisitor::visitPre(DocText *)
+{
+ // TODO: to be implemented
+}
+
+
+void DocbookDocVisitor::visitPost(DocText *)
+{
+ // TODO: to be implemented
+}
+
+
+void DocbookDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "<blockquote>";
+}
+
+void DocbookDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "</blockquote>";
+}
+
+void DocbookDocVisitor::visitPre(DocVhdlFlow *)
+{
+ // TODO: to be implemented
+}
+
+
+void DocbookDocVisitor::visitPost(DocVhdlFlow *)
+{
+ // TODO: to be implemented
+}
+
+void DocbookDocVisitor::visitPre(DocParBlock *)
+{
+}
+
+void DocbookDocVisitor::visitPost(DocParBlock *)
+{
+}
+
+
+void DocbookDocVisitor::filter(const char *str)
+{
+ m_t << convertToXML(str);
+}
+
+void DocbookDocVisitor::startLink(const QCString &file,const QCString &anchor)
+{
+ m_t << "<link linkend=\"" << file;
+ if (!anchor.isEmpty()) m_t << "_1" << anchor;
+ m_t << "\">";
+}
+
+void DocbookDocVisitor::endLink()
+{
+ m_t << "</link>";
+}
+
+void DocbookDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void DocbookDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
+void DocbookDocVisitor::writeMscFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP);
+ m_t << " <imagedata";
+ m_t << " width=\"50%\"";
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << ".png" << "\">";
+ m_t << "</imagedata>" << endl;
+}
+
+void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ generatePlantUMLOutput(baseName,outDir,PUML_BITMAP);
+ m_t << " <imagedata";
+ m_t << " width=\"50%\"";
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << ".png" << "\">";
+ m_t << "</imagedata>" << endl;
+}
+
+void DocbookDocVisitor::startMscFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("msc_");
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ writeMscGraphFromFile(fileName,outDir,baseName,MSC_BITMAP);
+ m_t << "<para>" << endl;
+ m_t << " <figure>" << endl;
+ m_t << " <title></title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ m_t << " <imagedata";
+ if (!width.isEmpty())
+ {
+ m_t << " width=\"";
+ m_t << width;
+ m_t << "\"";
+ }
+ else
+ {
+ m_t << " width=\"50%\"";
+ }
+ if (!height.isEmpty())
+ {
+ m_t << " depth=\"";
+ m_t << height;
+ m_t << "\"";
+ }
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << ".png" << "\">";
+ m_t << "</imagedata>" << endl;
+ m_t << " </imageobject>" << endl;
+ if (hasCaption)
+ {
+ m_t << " <caption>" << endl;
+ }
+}
+
+void DocbookDocVisitor::endMscFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "endl";
+ if (hasCaption)
+ {
+ m_t << " </caption>" << endl;
+ }
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+}
+
+void DocbookDocVisitor::writeDiaFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP);
+ m_t << " <imagedata";
+ m_t << " align=\"center\" fileref=\"" << shortName << ".png" << "\">";
+ m_t << "</imagedata>" << endl;
+}
+
+void DocbookDocVisitor::startDiaFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("msc_");
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ writeDiaGraphFromFile(fileName,outDir,baseName,DIA_BITMAP);
+ m_t << "<para>" << endl;
+ m_t << " <figure>" << endl;
+ m_t << " <title></title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ m_t << " <imagedata";
+ if (!width.isEmpty())
+ {
+ m_t << " width=\"";
+ m_t << width;
+ m_t << "\"";
+ }
+ else if (!height.isEmpty())
+ {
+ m_t << " depth=\"";
+ m_t << height;
+ m_t << "\"";
+ }
+ m_t << " align=\"center\" fileref=\"" << baseName << ".png" << "\">";
+ m_t << "</imagedata>" << endl;
+ m_t << " </imageobject>" << endl;
+ if (hasCaption)
+ {
+ m_t << " <caption>" << endl;
+ }
+}
+
+void DocbookDocVisitor::endDiaFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "endl";
+ if (hasCaption)
+ {
+ m_t << " </caption>" << endl;
+ }
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+}
+
+void DocbookDocVisitor::writeDotFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP);
+ m_t << " <imagedata";
+ //If no width is specified use default value for PDF rendering
+ m_t << " width=\"50%\"";
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << "." << imgExt << "\">";
+ m_t << "</imagedata>" << endl;
+}
+
+void DocbookDocVisitor::startDotFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("dot_");
+ QCString outDir = Config_getString("DOCBOOK_OUTPUT");
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ writeDotGraphFromFile(fileName,outDir,baseName,GOF_BITMAP);
+ m_t << "<para>" << endl;
+ m_t << " <figure>" << endl;
+ m_t << " <title></title>" << endl;
+ m_t << " <mediaobject>" << endl;
+ m_t << " <imageobject>" << endl;
+ m_t << " <imagedata";
+ if (!width.isEmpty())
+ {
+ m_t << " width=\"";
+ m_t << width;
+ m_t << "\"";
+ }
+ else
+ {
+ m_t << " width=\"50%\"";
+ }
+ if (!height.isEmpty())
+ {
+ m_t << " depth=\"";
+ m_t << height;
+ m_t << "\"";
+ }
+ m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << "." << imgExt << "\">";
+ m_t << "</imagedata>" << endl;
+ m_t << " </imageobject>" << endl;
+ if (hasCaption)
+ {
+ m_t << " <caption>" << endl;
+ }
+}
+
+void DocbookDocVisitor::endDotFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "endl";
+ if (hasCaption)
+ {
+ m_t << " </caption>" << endl;
+ }
+ m_t << " </mediaobject>" << endl;
+ m_t << " </figure>" << endl;
+ m_t << "</para>" << endl;
+}
+
diff --git a/src/docbookvisitor.h b/src/docbookvisitor.h
new file mode 100644
index 0000000..dd67aba
--- /dev/null
+++ b/src/docbookvisitor.h
@@ -0,0 +1,171 @@
+/******************************************************************************
+*
+*
+*
+* Copyright (C) 1997-2014 by Dimitri van Heesch.
+*
+* Permission to use, copy, modify, and distribute this software and its
+* documentation under the terms of the GNU General Public License is hereby
+* granted. No representations are made about the suitability of this software
+* for any purpose. It is provided "as is" without express or implied warranty.
+* See the GNU General Public License for more details.
+*
+* Documents produced by Doxygen are derivative works derived from the
+* input used in their production; they are not affected by this license.
+*
+*/
+
+#ifndef _DOCBOOKDOCVISITOR_H
+#define _DOCBOOKDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+
+class FTextStream;
+class CodeOutputInterface;
+class QCString;
+
+/*! @brief Concrete visitor implementation for Docbook output. */
+class DocbookDocVisitor : public DocVisitor
+{
+ public:
+ DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci);
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *) ;
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *);
+ void visitPost(DocHtmlList *) ;
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *);
+ void visitPost(DocHtmlTable *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *);
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ //void visitPre(DocLanguage *);
+ //void visitPost(DocLanguage *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+ void filter(const char *str);
+ void startLink(const QCString &file,
+ const QCString &anchor);
+ void endLink();
+ void pushEnabled();
+ void popEnabled();
+ void startMscFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endMscFile(bool hasCaption);
+ void writeMscFile(const QCString &fileName);
+ void startDiaFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endDiaFile(bool hasCaption);
+ void writeDiaFile(const QCString &fileName);
+ void startDotFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endDotFile(bool hasCaption);
+ void writeDotFile(const QCString &fileName);
+ void writePlantUMLFile(const QCString &fileName);
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_hide;
+ QStack<bool> m_enabled;
+ QCString m_langExt;
+};
+
+#endif
diff --git a/src/docparser.cpp b/src/docparser.cpp
new file mode 100644
index 0000000..8be11c6
--- /dev/null
+++ b/src/docparser.cpp
@@ -0,0 +1,7388 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qcstring.h>
+#include <qstack.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <ctype.h>
+
+#include "doxygen.h"
+#include "debug.h"
+#include "util.h"
+#include "pagedef.h"
+#include "docparser.h"
+#include "doctokenizer.h"
+#include "cmdmapper.h"
+#include "printdocvisitor.h"
+#include "message.h"
+#include "section.h"
+#include "searchindex.h"
+#include "language.h"
+#include "portable.h"
+#include "cite.h"
+#include "arguments.h"
+#include "vhdldocgen.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "namespacedef.h"
+#include "reflist.h"
+#include "formula.h"
+#include "config.h"
+#include "growbuf.h"
+#include "markdown.h"
+#include "htmlentity.h"
+
+// debug off
+#define DBG(x) do {} while(0)
+
+// debug to stdout
+//#define DBG(x) printf x
+
+// debug to stderr
+//#define myprintf(x...) fprintf(stderr,x)
+//#define DBG(x) myprintf x
+
+#define INTERNAL_ASSERT(x) do {} while(0)
+//#define INTERNAL_ASSERT(x) if (!(x)) DBG(("INTERNAL_ASSERT(%s) failed retval=0x%x: file=%s line=%d\n",#x,retval,__FILE__,__LINE__));
+
+//---------------------------------------------------------------------------
+
+static const char *sectionLevelToName[] =
+{
+ "page",
+ "section",
+ "subsection",
+ "subsubsection",
+ "paragraph"
+};
+
+//---------------------------------------------------------------------------
+
+// Parser state: global variables during a call to validatingParseDoc
+static Definition * g_scope;
+static QCString g_context;
+static bool g_inSeeBlock;
+static bool g_xmlComment;
+static bool g_insideHtmlLink;
+static QStack<DocNode> g_nodeStack;
+static QStack<DocStyleChange> g_styleStack;
+static QStack<DocStyleChange> g_initialStyleStack;
+static QList<Definition> g_copyStack;
+static QCString g_fileName;
+static QCString g_relPath;
+
+static bool g_hasParamCommand;
+static bool g_hasReturnCommand;
+static QDict<void> g_paramsFound;
+static MemberDef * g_memberDef;
+static bool g_isExample;
+static QCString g_exampleName;
+static SectionDict * g_sectionDict;
+static QCString g_searchUrl;
+
+static QCString g_includeFileText;
+static uint g_includeFileOffset;
+static uint g_includeFileLength;
+
+
+/** Parser's context to store all global variables.
+ */
+struct DocParserContext
+{
+ Definition *scope;
+ QCString context;
+ bool inSeeBlock;
+ bool xmlComment;
+ bool insideHtmlLink;
+ QStack<DocNode> nodeStack;
+ QStack<DocStyleChange> styleStack;
+ QStack<DocStyleChange> initialStyleStack;
+ QList<Definition> copyStack;
+ QCString fileName;
+ QCString relPath;
+
+ bool hasParamCommand;
+ bool hasReturnCommand;
+ MemberDef * memberDef;
+ QDict<void> paramsFound;
+ bool isExample;
+ QCString exampleName;
+ SectionDict *sectionDict;
+ QCString searchUrl;
+
+ QCString includeFileText;
+ uint includeFileOffset;
+ uint includeFileLength;
+
+ TokenInfo *token;
+};
+
+static QStack<DocParserContext> g_parserStack;
+
+//---------------------------------------------------------------------------
+
+static void docParserPushContext(bool saveParamInfo=TRUE)
+{
+ //QCString indent;
+ //indent.fill(' ',g_parserStack.count()*2+2);
+ //printf("%sdocParserPushContext() count=%d\n",indent.data(),g_nodeStack.count());
+
+ doctokenizerYYpushContext();
+ DocParserContext *ctx = new DocParserContext;
+ ctx->scope = g_scope;
+ ctx->context = g_context;
+ ctx->inSeeBlock = g_inSeeBlock;
+ ctx->xmlComment = g_xmlComment;
+ ctx->insideHtmlLink = g_insideHtmlLink;
+ ctx->nodeStack = g_nodeStack;
+ ctx->styleStack = g_styleStack;
+ ctx->initialStyleStack = g_initialStyleStack;
+ ctx->copyStack = g_copyStack;
+ ctx->fileName = g_fileName;
+ ctx->relPath = g_relPath;
+
+ if (saveParamInfo)
+ {
+ ctx->hasParamCommand = g_hasParamCommand;
+ ctx->hasReturnCommand = g_hasReturnCommand;
+ ctx->paramsFound = g_paramsFound;
+ }
+
+ ctx->memberDef = g_memberDef;
+ ctx->isExample = g_isExample;
+ ctx->exampleName = g_exampleName;
+ ctx->sectionDict = g_sectionDict;
+ ctx->searchUrl = g_searchUrl;
+
+ ctx->includeFileText = g_includeFileText;
+ ctx->includeFileOffset = g_includeFileOffset;
+ ctx->includeFileLength = g_includeFileLength;
+
+ ctx->token = g_token;
+ g_token = new TokenInfo;
+
+ g_parserStack.push(ctx);
+}
+
+static void docParserPopContext(bool keepParamInfo=FALSE)
+{
+ DocParserContext *ctx = g_parserStack.pop();
+ g_scope = ctx->scope;
+ g_context = ctx->context;
+ g_inSeeBlock = ctx->inSeeBlock;
+ g_xmlComment = ctx->xmlComment;
+ g_insideHtmlLink = ctx->insideHtmlLink;
+ g_nodeStack = ctx->nodeStack;
+ g_styleStack = ctx->styleStack;
+ g_initialStyleStack = ctx->initialStyleStack;
+ g_copyStack = ctx->copyStack;
+ g_fileName = ctx->fileName;
+ g_relPath = ctx->relPath;
+
+ if (!keepParamInfo)
+ {
+ g_hasParamCommand = ctx->hasParamCommand;
+ g_hasReturnCommand = ctx->hasReturnCommand;
+ g_paramsFound = ctx->paramsFound;
+ }
+ g_memberDef = ctx->memberDef;
+ g_isExample = ctx->isExample;
+ g_exampleName = ctx->exampleName;
+ g_sectionDict = ctx->sectionDict;
+ g_searchUrl = ctx->searchUrl;
+
+ g_includeFileText = ctx->includeFileText;
+ g_includeFileOffset = ctx->includeFileOffset;
+ g_includeFileLength = ctx->includeFileLength;
+
+ delete g_token;
+ g_token = ctx->token;
+
+ delete ctx;
+ doctokenizerYYpopContext();
+
+ //QCString indent;
+ //indent.fill(' ',g_parserStack.count()*2+2);
+ //printf("%sdocParserPopContext() count=%d\n",indent.data(),g_nodeStack.count());
+}
+
+//---------------------------------------------------------------------------
+
+/*! search for an image in the imageNameDict and if found
+ * copies the image to the output directory (which depends on the \a type
+ * parameter).
+ */
+static QCString findAndCopyImage(const char *fileName,DocImage::Type type)
+{
+ QCString result;
+ bool ambig;
+ FileDef *fd;
+ //printf("Search for %s\n",fileName);
+ if ((fd=findFileDef(Doxygen::imageNameDict,fileName,ambig)))
+ {
+ QCString inputFile = fd->absFilePath();
+ QFile inImage(inputFile);
+ if (inImage.open(IO_ReadOnly))
+ {
+ result = fileName;
+ int i;
+ if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1)
+ {
+ result = result.right(result.length()-i-1);
+ }
+ //printf("fileName=%s result=%s\n",fileName,result.data());
+ QCString outputDir;
+ switch(type)
+ {
+ case DocImage::Html:
+ if (!Config_getBool("GENERATE_HTML")) return result;
+ outputDir = Config_getString("HTML_OUTPUT");
+ break;
+ case DocImage::Latex:
+ if (!Config_getBool("GENERATE_LATEX")) return result;
+ outputDir = Config_getString("LATEX_OUTPUT");
+ break;
+ case DocImage::DocBook:
+ if (!Config_getBool("GENERATE_DOCBOOK")) return result;
+ outputDir = Config_getString("DOCBOOK_OUTPUT");
+ break;
+ case DocImage::Rtf:
+ if (!Config_getBool("GENERATE_RTF")) return result;
+ outputDir = Config_getString("RTF_OUTPUT");
+ break;
+ }
+ QCString outputFile = outputDir+"/"+result;
+ QFileInfo outfi(outputFile);
+ if (outfi.isSymLink())
+ {
+ QFile::remove(outputFile);
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "destination of image %s is a symlink, replacing with image",
+ qPrint(outputFile));
+ }
+ if (outputFile!=inputFile) // prevent copying to ourself
+ {
+ QFile outImage(outputFile.data());
+ if (outImage.open(IO_WriteOnly)) // copy the image
+ {
+ char *buffer = new char[inImage.size()];
+ inImage.readBlock(buffer,inImage.size());
+ outImage.writeBlock(buffer,inImage.size());
+ outImage.flush();
+ delete[] buffer;
+ if (type==DocImage::Html) Doxygen::indexList->addImageFile(result);
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "could not write output image %s",qPrint(outputFile));
+ }
+ }
+ else
+ {
+ printf("Source & Destination are the same!\n");
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "could not open image %s",qPrint(fileName));
+ }
+
+ if (type==DocImage::Latex && Config_getBool("USE_PDFLATEX") &&
+ fd->name().right(4)==".eps"
+ )
+ { // we have an .eps image in pdflatex mode => convert it to a pdf.
+ QCString outputDir = Config_getString("LATEX_OUTPUT");
+ QCString baseName = fd->name().left(fd->name().length()-4);
+ QCString epstopdfArgs(4096);
+ epstopdfArgs.sprintf("\"%s/%s.eps\" --outfile=\"%s/%s.pdf\"",
+ outputDir.data(), baseName.data(),
+ outputDir.data(), baseName.data());
+ portable_sysTimerStart();
+ if (portable_system("epstopdf",epstopdfArgs)!=0)
+ {
+ err("Problems running epstopdf. Check your TeX installation!\n");
+ }
+ portable_sysTimerStop();
+ return baseName;
+ }
+ }
+ else if (ambig)
+ {
+ QCString text;
+ text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName));
+ text+="Possible candidates:\n";
+ text+=showFileDefMatches(Doxygen::imageNameDict,fileName);
+ warn_doc_error(g_fileName,doctokenizerYYlineno,text);
+ }
+ else
+ {
+ result=fileName;
+ if (result.left(5)!="http:" && result.left(6)!="https:")
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "image file %s is not found in IMAGE_PATH: "
+ "assuming external image.",qPrint(fileName)
+ );
+ }
+ }
+ return result;
+}
+
+/*! Collects the parameters found with \@param or \@retval commands
+ * in a global list g_paramsFound. If \a isParam is set to TRUE
+ * and the parameter is not an actual parameter of the current
+ * member g_memberDef, then a warning is raised (unless warnings
+ * are disabled altogether).
+ */
+static void checkArgumentName(const QCString &name,bool isParam)
+{
+ if (!Config_getBool("WARN_IF_DOC_ERROR")) return;
+ if (g_memberDef==0) return; // not a member
+ ArgumentList *al=g_memberDef->isDocsForDefinition() ?
+ g_memberDef->argumentList() :
+ g_memberDef->declArgumentList();
+ SrcLangExt lang = g_memberDef->getLanguage();
+ //printf("isDocsForDefinition()=%d\n",g_memberDef->isDocsForDefinition());
+ if (al==0) return; // no argument list
+
+ static QRegExp re("$?[a-zA-Z0-9_\\x80-\\xFF]+\\.*");
+ int p=0,i=0,l;
+ while ((i=re.match(name,p,&l))!=-1) // to handle @param x,y
+ {
+ QCString aName=name.mid(i,l);
+ if (lang==SrcLangExt_Fortran) aName=aName.lower();
+ //printf("aName=`%s'\n",aName.data());
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ bool found=FALSE;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+ if (lang==SrcLangExt_Fortran) argName=argName.lower();
+ argName=argName.stripWhiteSpace();
+ //printf("argName=`%s' aName=%s\n",argName.data(),aName.data());
+ if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
+ if (aName==argName)
+ {
+ g_paramsFound.insert(aName,(void *)(0x8));
+ found=TRUE;
+ break;
+ }
+ }
+ if (!found && isParam)
+ {
+ //printf("member type=%d\n",memberDef->memberType());
+ QCString scope=g_memberDef->getScopeString();
+ if (!scope.isEmpty()) scope+="::"; else scope="";
+ QCString inheritedFrom = "";
+ QCString docFile = g_memberDef->docFile();
+ int docLine = g_memberDef->docLine();
+ MemberDef *inheritedMd = g_memberDef->inheritsDocsFrom();
+ if (inheritedMd) // documentation was inherited
+ {
+ inheritedFrom.sprintf(" inherited from member %s at line "
+ "%d in file %s",qPrint(inheritedMd->name()),
+ inheritedMd->docLine(),qPrint(inheritedMd->docFile()));
+ docFile = g_memberDef->getDefFileName();
+ docLine = g_memberDef->getDefLine();
+
+ }
+ QCString alStr = argListToString(al);
+ warn_doc_error(docFile,docLine,
+ "argument '%s' of command @param "
+ "is not found in the argument list of %s%s%s%s",
+ qPrint(aName), qPrint(scope), qPrint(g_memberDef->name()),
+ qPrint(alStr), qPrint(inheritedFrom));
+ }
+ p=i+l;
+ }
+}
+
+/*! Checks if the parameters that have been specified using \@param are
+ * indeed all parameters.
+ * Must be called after checkArgumentName() has been called for each
+ * argument.
+ */
+static void checkUndocumentedParams()
+{
+ if (g_memberDef && g_hasParamCommand && Config_getBool("WARN_IF_DOC_ERROR"))
+ {
+ ArgumentList *al=g_memberDef->isDocsForDefinition() ?
+ g_memberDef->argumentList() :
+ g_memberDef->declArgumentList();
+ SrcLangExt lang = g_memberDef->getLanguage();
+ if (al!=0)
+ {
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ bool found=FALSE;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+ if (lang==SrcLangExt_Fortran) argName = argName.lower();
+ argName=argName.stripWhiteSpace();
+ if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
+ if (g_memberDef->getLanguage()==SrcLangExt_Python && argName=="self")
+ {
+ // allow undocumented self parameter for Python
+ }
+ else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a->docs.isEmpty())
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found)
+ {
+ bool first=TRUE;
+ QCString errMsg=
+ "The following parameters of "+
+ QCString(g_memberDef->qualifiedName()) +
+ QCString(argListToString(al)) +
+ " are not documented:\n";
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+ if (lang==SrcLangExt_Fortran) argName = argName.lower();
+ argName=argName.stripWhiteSpace();
+ if (g_memberDef->getLanguage()==SrcLangExt_Python && argName=="self")
+ {
+ // allow undocumented self parameter for Python
+ }
+ else if (!argName.isEmpty() && g_paramsFound.find(argName)==0)
+ {
+ if (!first)
+ {
+ errMsg+="\n";
+ }
+ else
+ {
+ first=FALSE;
+ }
+ errMsg+=" parameter '"+argName+"'";
+ }
+ }
+ if (g_memberDef->inheritsDocsFrom())
+ {
+ warn_doc_error(g_memberDef->getDefFileName(),
+ g_memberDef->getDefLine(),
+ substitute(errMsg,"%","%%"));
+ }
+ else
+ {
+ warn_doc_error(g_memberDef->docFile(),
+ g_memberDef->docLine(),
+ substitute(errMsg,"%","%%"));
+ }
+ }
+ }
+ }
+}
+
+/*! Check if a member has documentation for its parameter and or return
+ * type, if applicable. If found this will be stored in the member, this
+ * is needed as a member can have brief and detailed documentation, while
+ * only one of these needs to document the parameters.
+ */
+static void detectNoDocumentedParams()
+{
+ if (g_memberDef && Config_getBool("WARN_NO_PARAMDOC"))
+ {
+ ArgumentList *al = g_memberDef->argumentList();
+ ArgumentList *declAl = g_memberDef->declArgumentList();
+ QCString returnType = g_memberDef->typeString();
+ bool isPython = g_memberDef->getLanguage()==SrcLangExt_Python;
+
+ if (!g_memberDef->hasDocumentedParams() &&
+ g_hasParamCommand)
+ {
+ //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data());
+ g_memberDef->setHasDocumentedParams(TRUE);
+ }
+ else if (!g_memberDef->hasDocumentedParams())
+ {
+ bool allDoc=TRUE; // no paramater => all parameters are documented
+ if ( // member has parameters
+ al!=0 && // but the member has a parameter list
+ al->count()>0 // with at least one parameter (that is not void)
+ )
+ {
+ ArgumentListIterator ali(*al);
+ Argument *a;
+
+ // see if all parameters have documentation
+ for (ali.toFirst();(a=ali.current()) && allDoc;++ali)
+ {
+ if (!a->name.isEmpty() && a->type!="void" &&
+ !(isPython && a->name=="self")
+ )
+ {
+ allDoc = !a->docs.isEmpty();
+ }
+ //printf("a->type=%s a->name=%s doc=%s\n",
+ // a->type.data(),a->name.data(),a->docs.data());
+ }
+ if (!allDoc && declAl!=0) // try declaration arguments as well
+ {
+ allDoc=TRUE;
+ ArgumentListIterator ali(*declAl);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current()) && allDoc;++ali)
+ {
+ if (!a->name.isEmpty() && a->type!="void" &&
+ !(isPython && a->name=="self")
+ )
+ {
+ allDoc = !a->docs.isEmpty();
+ }
+ //printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data());
+ }
+ }
+ }
+ if (allDoc)
+ {
+ //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data());
+ g_memberDef->setHasDocumentedParams(TRUE);
+ }
+ }
+ //printf("Member %s hasReturnCommand=%d\n",g_memberDef->name().data(),g_hasReturnCommand);
+ if (!g_memberDef->hasDocumentedReturnType() && // docs not yet found
+ g_hasReturnCommand)
+ {
+ g_memberDef->setHasDocumentedReturnType(TRUE);
+ }
+ else if ( // see if return needs to documented
+ g_memberDef->hasDocumentedReturnType() ||
+ returnType.isEmpty() || // empty return type
+ returnType.find("void")!=-1 || // void return type
+ returnType.find("subroutine")!=-1 || // fortran subroutine
+ g_memberDef->isConstructor() || // a constructor
+ g_memberDef->isDestructor() // or destructor
+ )
+ {
+ g_memberDef->setHasDocumentedReturnType(TRUE);
+ }
+
+ }
+}
+
+
+//---------------------------------------------------------------------------
+
+/*! Strips known html and tex extensions from \a text. */
+static QCString stripKnownExtensions(const char *text)
+{
+ QCString result=text;
+ if (result.right(4)==".tex")
+ {
+ result=result.left(result.length()-4);
+ }
+ else if (result.right(Doxygen::htmlFileExtension.length())==
+ QCString(Doxygen::htmlFileExtension))
+ {
+ result=result.left(result.length()-Doxygen::htmlFileExtension.length());
+ }
+ return result;
+}
+
+
+//---------------------------------------------------------------------------
+
+/*! Returns TRUE iff node n is a child of a preformatted node */
+static bool insidePRE(DocNode *n)
+{
+ while (n)
+ {
+ if (n->isPreformatted()) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+/*! Returns TRUE iff node n is a child of a html list item node */
+static bool insideLI(DocNode *n)
+{
+ while (n)
+ {
+ if (n->kind()==DocNode::Kind_HtmlListItem) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+/*! Returns TRUE iff node n is a child of a unordered html list node */
+static bool insideUL(DocNode *n)
+{
+ while (n)
+ {
+ if (n->kind()==DocNode::Kind_HtmlList &&
+ ((DocHtmlList *)n)->type()==DocHtmlList::Unordered) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+/*! Returns TRUE iff node n is a child of a ordered html list node */
+static bool insideOL(DocNode *n)
+{
+ while (n)
+ {
+ if (n->kind()==DocNode::Kind_HtmlList &&
+ ((DocHtmlList *)n)->type()==DocHtmlList::Ordered) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+static bool insideTable(DocNode *n)
+{
+ while (n)
+ {
+ if (n->kind()==DocNode::Kind_HtmlTable) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+/*! Looks for a documentation block with name commandName in the current
+ * context (g_context). The resulting documentation string is
+ * put in pDoc, the definition in which the documentation was found is
+ * put in pDef.
+ * @retval TRUE if name was found.
+ * @retval FALSE if name was not found.
+ */
+static bool findDocsForMemberOrCompound(const char *commandName,
+ QCString *pDoc,
+ QCString *pBrief,
+ Definition **pDef)
+{
+ //printf("findDocsForMemberOrCompound(%s)\n",commandName);
+ *pDoc="";
+ *pBrief="";
+ *pDef=0;
+ QCString cmdArg=substitute(commandName,"#","::");
+ int l=cmdArg.length();
+ if (l==0) return FALSE;
+
+ int funcStart=cmdArg.find('(');
+ if (funcStart==-1)
+ {
+ funcStart=l;
+ }
+ else
+ {
+ // Check for the case of operator() and the like.
+ // beware of scenarios like operator()((foo)bar)
+ int secondParen = cmdArg.find('(', funcStart+1);
+ int leftParen = cmdArg.find(')', funcStart+1);
+ if (leftParen!=-1 && secondParen!=-1)
+ {
+ if (leftParen<secondParen)
+ {
+ funcStart=secondParen;
+ }
+ }
+ }
+
+ QCString name=removeRedundantWhiteSpace(cmdArg.left(funcStart));
+ QCString args=cmdArg.right(l-funcStart);
+
+ // try if the link is to a member
+ MemberDef *md=0;
+ ClassDef *cd=0;
+ FileDef *fd=0;
+ NamespaceDef *nd=0;
+ GroupDef *gd=0;
+ PageDef *pd=0;
+ bool found = getDefs(
+ g_context.find('.')==-1?g_context.data():"", // `find('.') is a hack to detect files
+ name,
+ args.isEmpty()?0:args.data(),
+ md,cd,fd,nd,gd,FALSE,0,TRUE);
+ //printf("found=%d context=%s name=%s\n",found,g_context.data(),name.data());
+ if (found && md)
+ {
+ *pDoc=md->documentation();
+ *pBrief=md->briefDescription();
+ *pDef=md;
+ return TRUE;
+ }
+
+
+ int scopeOffset=g_context.length();
+ do // for each scope
+ {
+ QCString fullName=cmdArg;
+ if (scopeOffset>0)
+ {
+ fullName.prepend(g_context.left(scopeOffset)+"::");
+ }
+ //printf("Trying fullName=`%s'\n",fullName.data());
+
+ // try class, namespace, group, page, file reference
+ cd = Doxygen::classSDict->find(fullName);
+ if (cd) // class
+ {
+ *pDoc=cd->documentation();
+ *pBrief=cd->briefDescription();
+ *pDef=cd;
+ return TRUE;
+ }
+ nd = Doxygen::namespaceSDict->find(fullName);
+ if (nd) // namespace
+ {
+ *pDoc=nd->documentation();
+ *pBrief=nd->briefDescription();
+ *pDef=nd;
+ return TRUE;
+ }
+ gd = Doxygen::groupSDict->find(cmdArg);
+ if (gd) // group
+ {
+ *pDoc=gd->documentation();
+ *pBrief=gd->briefDescription();
+ *pDef=gd;
+ return TRUE;
+ }
+ pd = Doxygen::pageSDict->find(cmdArg);
+ if (pd) // page
+ {
+ *pDoc=pd->documentation();
+ *pBrief=pd->briefDescription();
+ *pDef=pd;
+ return TRUE;
+ }
+ bool ambig;
+ fd = findFileDef(Doxygen::inputNameDict,cmdArg,ambig);
+ if (fd && !ambig) // file
+ {
+ *pDoc=fd->documentation();
+ *pBrief=fd->briefDescription();
+ *pDef=fd;
+ return TRUE;
+ }
+
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else
+ {
+ scopeOffset = g_context.findRev("::",scopeOffset-1);
+ if (scopeOffset==-1) scopeOffset=0;
+ }
+ } while (scopeOffset>=0);
+
+
+ return FALSE;
+}
+//---------------------------------------------------------------------------
+
+// forward declaration
+static bool defaultHandleToken(DocNode *parent,int tok,
+ QList<DocNode> &children,bool
+ handleWord=TRUE);
+
+
+static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
+ const QCString &cmdName)
+{
+ DBG(("handleStyleArgument(%s)\n",qPrint(cmdName)));
+ QCString tokenName = g_token->name;
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return tok;
+ }
+ while ((tok=doctokenizerYYlex()) &&
+ tok!=TK_WHITESPACE &&
+ tok!=TK_NEWPARA &&
+ tok!=TK_LISTITEM &&
+ tok!=TK_ENDLIST
+ )
+ {
+ static QRegExp specialChar("[.,|()\\[\\]:;\\?]");
+ if (tok==TK_WORD && g_token->name.length()==1 &&
+ g_token->name.find(specialChar)!=-1)
+ {
+ // special character that ends the markup command
+ return tok;
+ }
+ if (!defaultHandleToken(parent,tok,children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s as the argument of a \\%s command",
+ qPrint(g_token->name),qPrint(cmdName));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found while handling command %s",
+ qPrint(g_token->name),qPrint(cmdName));
+ break;
+ case TK_HTMLTAG:
+ if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag)
+ { // ignore </li> as the end of a style command
+ continue;
+ }
+ return tok;
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s while handling command %s",
+ tokToString(tok),qPrint(cmdName));
+ break;
+ }
+ break;
+ }
+ }
+ DBG(("handleStyleArgument(%s) end tok=%x\n",qPrint(cmdName),tok));
+ return (tok==TK_NEWPARA || tok==TK_LISTITEM || tok==TK_ENDLIST
+ ) ? tok : RetVal_OK;
+}
+
+/*! Called when a style change starts. For instance a \<b\> command is
+ * encountered.
+ */
+static void handleStyleEnter(DocNode *parent,QList<DocNode> &children,
+ DocStyleChange::Style s,const HtmlAttribList *attribs)
+{
+ DBG(("HandleStyleEnter\n"));
+ DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,TRUE,attribs);
+ children.append(sc);
+ g_styleStack.push(sc);
+}
+
+/*! Called when a style change ends. For instance a \</b\> command is
+ * encountered.
+ */
+static void handleStyleLeave(DocNode *parent,QList<DocNode> &children,
+ DocStyleChange::Style s,const char *tagName)
+{
+ DBG(("HandleStyleLeave\n"));
+ if (g_styleStack.isEmpty() || // no style change
+ g_styleStack.top()->style()!=s || // wrong style change
+ g_styleStack.top()->position()!=g_nodeStack.count() // wrong position
+ )
+ {
+ if (g_styleStack.isEmpty())
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> tag without matching <%s>",
+ qPrint(tagName),qPrint(tagName));
+ }
+ else if (g_styleStack.top()->style()!=s)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> tag while expecting </%s>",
+ qPrint(tagName),qPrint(g_styleStack.top()->styleString()));
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> at different nesting level (%d) than expected (%d)",
+ qPrint(tagName),g_nodeStack.count(),g_styleStack.top()->position());
+ }
+ }
+ else // end the section
+ {
+ DocStyleChange *sc= new DocStyleChange(parent,g_nodeStack.count(),s,FALSE);
+ children.append(sc);
+ g_styleStack.pop();
+ }
+}
+
+/*! Called at the end of a paragraph to close all open style changes
+ * (e.g. a <b> without a </b>). The closed styles are pushed onto a stack
+ * and entered again at the start of a new paragraph.
+ */
+static void handlePendingStyleCommands(DocNode *parent,QList<DocNode> &children)
+{
+ if (!g_styleStack.isEmpty())
+ {
+ DocStyleChange *sc = g_styleStack.top();
+ while (sc && sc->position()>=g_nodeStack.count())
+ { // there are unclosed style modifiers in the paragraph
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),sc->style(),FALSE));
+ g_initialStyleStack.push(sc);
+ g_styleStack.pop();
+ sc = g_styleStack.top();
+ }
+ }
+}
+
+static void handleInitialStyleCommands(DocPara *parent,QList<DocNode> &children)
+{
+ DocStyleChange *sc;
+ while ((sc=g_initialStyleStack.pop()))
+ {
+ handleStyleEnter(parent,children,sc->style(),&sc->attribs());
+ }
+}
+
+static int handleAHref(DocNode *parent,QList<DocNode> &children,const HtmlAttribList &tagHtmlAttribs)
+{
+ HtmlAttribListIterator li(tagHtmlAttribs);
+ HtmlAttrib *opt;
+ int index=0;
+ int retval = RetVal_OK;
+ for (li.toFirst();(opt=li.current());++li,++index)
+ {
+ if (opt->name=="name") // <a name=label> tag
+ {
+ if (!opt->value.isEmpty())
+ {
+ DocAnchor *anc = new DocAnchor(parent,opt->value,TRUE);
+ children.append(anc);
+ break; // stop looking for other tag attribs
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found <a> tag with name option but without value!");
+ }
+ }
+ else if (opt->name=="href") // <a href=url>..</a> tag
+ {
+ // copy attributes
+ HtmlAttribList attrList = tagHtmlAttribs;
+ // and remove the href attribute
+ bool result = attrList.remove(index);
+ ASSERT(result);
+ DocHRef *href = new DocHRef(parent,attrList,opt->value,g_relPath);
+ children.append(href);
+ g_insideHtmlLink=TRUE;
+ retval = href->parse();
+ g_insideHtmlLink=FALSE;
+ break;
+ }
+ else // unsupported option for tag a
+ {
+ }
+ }
+ return retval;
+}
+
+const char *DocStyleChange::styleString() const
+{
+ switch (m_style)
+ {
+ case DocStyleChange::Bold: return "b";
+ case DocStyleChange::Italic: return "em";
+ case DocStyleChange::Code: return "code";
+ case DocStyleChange::Center: return "center";
+ case DocStyleChange::Small: return "small";
+ case DocStyleChange::Subscript: return "subscript";
+ case DocStyleChange::Superscript: return "superscript";
+ case DocStyleChange::Preformatted: return "pre";
+ case DocStyleChange::Div: return "div";
+ case DocStyleChange::Span: return "span";
+ }
+ return "<invalid>";
+}
+
+static void handleUnclosedStyleCommands()
+{
+ if (!g_initialStyleStack.isEmpty())
+ {
+ DocStyleChange *sc = g_initialStyleStack.top();
+ g_initialStyleStack.pop();
+ handleUnclosedStyleCommands();
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "end of comment block while expecting "
+ "command </%s>",qPrint(sc->styleString()));
+ }
+}
+
+static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
+{
+ QCString name = linkToText(SrcLangExt_Unknown,g_token->name,TRUE);
+ static bool autolinkSupport = Config_getBool("AUTOLINK_SUPPORT");
+ if (!autolinkSupport) // no autolinking -> add as normal word
+ {
+ children.append(new DocWord(parent,name));
+ return;
+ }
+
+ // ------- try to turn the word 'name' into a link
+
+ Definition *compound=0;
+ MemberDef *member=0;
+ int len = g_token->name.length();
+ ClassDef *cd=0;
+ bool ambig;
+ FileDef *fd = findFileDef(Doxygen::inputNameDict,g_fileName,ambig);
+ //printf("handleLinkedWord(%s) g_context=%s\n",g_token->name.data(),g_context.data());
+ if (!g_insideHtmlLink &&
+ (resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member,TRUE,fd,TRUE)
+ || (!g_context.isEmpty() && // also try with global scope
+ resolveRef("",g_token->name,g_inSeeBlock,&compound,&member,FALSE,0,TRUE))
+ )
+ )
+ {
+ //printf("resolveRef %s = %p (linkable?=%d)\n",qPrint(g_token->name),member,member ? member->isLinkable() : FALSE);
+ if (member && member->isLinkable()) // member link
+ {
+ if (member->isObjCMethod())
+ {
+ bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE;
+ name = member->objCMethodName(localLink,g_inSeeBlock);
+ }
+ children.append(new
+ DocLinkedWord(parent,name,
+ member->getReference(),
+ member->getOutputFileBase(),
+ member->anchor(),
+ member->briefDescriptionAsTooltip()
+ )
+ );
+ }
+ else if (compound->isLinkable()) // compound link
+ {
+ QCString anchor = compound->anchor();
+ if (compound->definitionType()==Definition::TypeFile)
+ {
+ name=g_token->name;
+ }
+ else if (compound->definitionType()==Definition::TypeGroup)
+ {
+ name=((GroupDef*)compound)->groupTitle();
+ }
+ children.append(new
+ DocLinkedWord(parent,name,
+ compound->getReference(),
+ compound->getOutputFileBase(),
+ anchor,
+ compound->briefDescriptionAsTooltip()
+ )
+ );
+ }
+ else if (compound->definitionType()==Definition::TypeFile &&
+ ((FileDef*)compound)->generateSourceFile()
+ ) // undocumented file that has source code we can link to
+ {
+ children.append(new
+ DocLinkedWord(parent,g_token->name,
+ compound->getReference(),
+ compound->getSourceFileBase(),
+ "",
+ compound->briefDescriptionAsTooltip()
+ )
+ );
+ }
+ else // not linkable
+ {
+ children.append(new DocWord(parent,name));
+ }
+ }
+ else if (!g_insideHtmlLink && len>1 && g_token->name.at(len-1)==':')
+ {
+ // special case, where matching Foo: fails to be an Obj-C reference,
+ // but Foo itself might be linkable.
+ g_token->name=g_token->name.left(len-1);
+ handleLinkedWord(parent,children);
+ children.append(new DocWord(parent,":"));
+ }
+ else if (!g_insideHtmlLink && (cd=getClass(g_token->name+"-p")))
+ {
+ // special case 2, where the token name is not a class, but could
+ // be a Obj-C protocol
+ children.append(new
+ DocLinkedWord(parent,name,
+ cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ cd->briefDescriptionAsTooltip()
+ ));
+ }
+// else if (!g_insideHtmlLink && (cd=getClass(g_token->name+"-g")))
+// {
+// // special case 3, where the token name is not a class, but could
+// // be a C# generic
+// children.append(new
+// DocLinkedWord(parent,name,
+// cd->getReference(),
+// cd->getOutputFileBase(),
+// cd->anchor(),
+// cd->briefDescriptionAsTooltip()
+// ));
+// }
+ else // normal non-linkable word
+ {
+ if (g_token->name.left(1)=="#" || g_token->name.left(2)=="::")
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"explicit link request to '%s' could not be resolved",qPrint(name));
+ children.append(new DocWord(parent,g_token->name));
+ }
+ else
+ {
+ children.append(new DocWord(parent,name));
+ }
+ }
+}
+
+static void handleParameterType(DocNode *parent,QList<DocNode> &children,const QCString ¶mTypes)
+{
+ QCString name = g_token->name;
+ int p=0,i;
+ QCString type;
+ while ((i=paramTypes.find('|',p))!=-1)
+ {
+ g_token->name = paramTypes.mid(p,i-p);
+ handleLinkedWord(parent,children);
+ p=i+1;
+ }
+ g_token->name = paramTypes.mid(p);
+ handleLinkedWord(parent,children);
+ g_token->name = name;
+}
+
+static DocInternalRef *handleInternalRef(DocNode *parent)
+{
+ //printf("CMD_INTERNALREF\n");
+ int tok=doctokenizerYYlex();
+ QCString tokenName = g_token->name;
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(tokenName));
+ return 0;
+ }
+ doctokenizerYYsetStateInternalRef();
+ tok=doctokenizerYYlex(); // get the reference id
+ if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(tokenName));
+ return 0;
+ }
+ return new DocInternalRef(parent,g_token->name);
+}
+
+static DocAnchor *handleAnchor(DocNode *parent)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(g_token->name));
+ return 0;
+ }
+ doctokenizerYYsetStateAnchor();
+ tok=doctokenizerYYlex();
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s",qPrint(g_token->name));
+ return 0;
+ }
+ else if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(g_token->name));
+ return 0;
+ }
+ doctokenizerYYsetStatePara();
+ return new DocAnchor(parent,g_token->name,FALSE);
+}
+
+
+/* Helper function that deals with the most common tokens allowed in
+ * title like sections.
+ * @param parent Parent node, owner of the children list passed as
+ * the third argument.
+ * @param tok The token to process.
+ * @param children The list of child nodes to which the node representing
+ * the token can be added.
+ * @param handleWord Indicates if word token should be processed
+ * @retval TRUE The token was handled.
+ * @retval FALSE The token was not handled.
+ */
+static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool
+ handleWord)
+{
+ DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));
+ if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL ||
+ tok==TK_COMMAND || tok==TK_HTMLTAG
+ )
+ {
+ DBG((" name=%s",qPrint(g_token->name)));
+ }
+ DBG(("\n"));
+reparsetoken:
+ QCString tokenName = g_token->name;
+ switch (tok)
+ {
+ case TK_COMMAND:
+ switch (Mappers::cmdMapper->map(tokenName))
+ {
+ case CMD_BSLASH:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_BSlash));
+ break;
+ case CMD_AT:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_At));
+ break;
+ case CMD_LESS:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Less));
+ break;
+ case CMD_GREATER:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Greater));
+ break;
+ case CMD_AMP:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Amp));
+ break;
+ case CMD_DOLLAR:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Dollar));
+ break;
+ case CMD_HASH:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Hash));
+ break;
+ case CMD_DCOLON:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_DoubleColon));
+ break;
+ case CMD_PERCENT:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Percent));
+ break;
+ case CMD_NDASH:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Minus));
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Minus));
+ break;
+ case CMD_MDASH:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Minus));
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Minus));
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Minus));
+ break;
+ case CMD_QUOTE:
+ children.append(new DocSymbol(parent,DocSymbol::Sym_Quot));
+ break;
+ case CMD_EMPHASIS:
+ {
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,TRUE));
+ tok=handleStyleArgument(parent,children,tokenName);
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,FALSE));
+ if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));
+ if (tok==TK_NEWPARA) goto handlepara;
+ else if (tok==TK_WORD || tok==TK_HTMLTAG)
+ {
+ DBG(("CMD_EMPHASIS: reparsing command %s\n",qPrint(g_token->name)));
+ goto reparsetoken;
+ }
+ }
+ break;
+ case CMD_BOLD:
+ {
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,TRUE));
+ tok=handleStyleArgument(parent,children,tokenName);
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Bold,FALSE));
+ if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));
+ if (tok==TK_NEWPARA) goto handlepara;
+ else if (tok==TK_WORD || tok==TK_HTMLTAG)
+ {
+ DBG(("CMD_BOLD: reparsing command %s\n",qPrint(g_token->name)));
+ goto reparsetoken;
+ }
+ }
+ break;
+ case CMD_CODE:
+ {
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,TRUE));
+ tok=handleStyleArgument(parent,children,tokenName);
+ children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Code,FALSE));
+ if (tok!=TK_WORD) children.append(new DocWhiteSpace(parent," "));
+ if (tok==TK_NEWPARA) goto handlepara;
+ else if (tok==TK_WORD || tok==TK_HTMLTAG)
+ {
+ DBG(("CMD_CODE: reparsing command %s\n",qPrint(g_token->name)));
+ goto reparsetoken;
+ }
+ }
+ break;
+ case CMD_HTMLONLY:
+ {
+ doctokenizerYYsetStateHtmlOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName,g_token->name=="block"));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"htmlonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_MANONLY:
+ {
+ doctokenizerYYsetStateManOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"manonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_RTFONLY:
+ {
+ doctokenizerYYsetStateRtfOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::RtfOnly,g_isExample,g_exampleName));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"rtfonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_LATEXONLY:
+ {
+ doctokenizerYYsetStateLatexOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker",doctokenizerYYlineno);
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_XMLONLY:
+ {
+ doctokenizerYYsetStateXmlOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker",doctokenizerYYlineno);
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_DBONLY:
+ {
+ doctokenizerYYsetStateDbOnly();
+ tok = doctokenizerYYlex();
+ children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName));
+ if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker",doctokenizerYYlineno);
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_FORMULA:
+ {
+ DocFormula *form=new DocFormula(parent,g_token->id);
+ children.append(form);
+ }
+ break;
+ case CMD_ANCHOR:
+ {
+ DocAnchor *anchor = handleAnchor(parent);
+ if (anchor)
+ {
+ children.append(anchor);
+ }
+ }
+ break;
+ case CMD_INTERNALREF:
+ {
+ DocInternalRef *ref = handleInternalRef(parent);
+ if (ref)
+ {
+ children.append(ref);
+ ref->parse();
+ }
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ case TK_HTMLTAG:
+ {
+ switch (Mappers::htmlTagMapper->map(tokenName))
+ {
+ case HTML_DIV:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found <div> tag in heading\n");
+ break;
+ case HTML_PRE:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found <pre> tag in heading\n");
+ break;
+ case HTML_BOLD:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Bold,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Bold,tokenName);
+ }
+ break;
+ case HTML_CODE:
+ case XML_C:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Code,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Code,tokenName);
+ }
+ break;
+ case HTML_EMPHASIS:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Italic,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Italic,tokenName);
+ }
+ break;
+ case HTML_SUB:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Subscript,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Subscript,tokenName);
+ }
+ break;
+ case HTML_SUP:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Superscript,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Superscript,tokenName);
+ }
+ break;
+ case HTML_CENTER:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Center,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Center,tokenName);
+ }
+ break;
+ case HTML_SMALL:
+ if (!g_token->endTag)
+ {
+ handleStyleEnter(parent,children,DocStyleChange::Small,&g_token->attribs);
+ }
+ else
+ {
+ handleStyleLeave(parent,children,DocStyleChange::Small,tokenName);
+ }
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ }
+ break;
+ case TK_SYMBOL:
+ {
+ DocSymbol::SymType s = DocSymbol::decodeSymbol(tokenName);
+ if (s!=DocSymbol::Sym_Unknown)
+ {
+ children.append(new DocSymbol(parent,s));
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ break;
+ case TK_WHITESPACE:
+ case TK_NEWPARA:
+handlepara:
+ if (insidePRE(parent) || !children.isEmpty())
+ {
+ children.append(new DocWhiteSpace(parent,g_token->chars));
+ }
+ break;
+ case TK_LNKWORD:
+ if (handleWord)
+ {
+ handleLinkedWord(parent,children);
+ }
+ else
+ return FALSE;
+ break;
+ case TK_WORD:
+ if (handleWord)
+ {
+ children.append(new DocWord(parent,g_token->name));
+ }
+ else
+ return FALSE;
+ break;
+ case TK_URL:
+ if (g_insideHtmlLink)
+ {
+ children.append(new DocWord(parent,g_token->name));
+ }
+ else
+ {
+ children.append(new DocURL(parent,g_token->name,g_token->isEMailAddr));
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//---------------------------------------------------------------------------
+
+static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribList &tagHtmlAttribs)
+{
+ HtmlAttribListIterator li(tagHtmlAttribs);
+ HtmlAttrib *opt;
+ bool found=FALSE;
+ int index=0;
+ for (li.toFirst();(opt=li.current());++li,++index)
+ {
+ //printf("option name=%s value=%s\n",opt->name.data(),opt->value.data());
+ if (opt->name=="src" && !opt->value.isEmpty())
+ {
+ // copy attributes
+ HtmlAttribList attrList = tagHtmlAttribs;
+ // and remove the src attribute
+ bool result = attrList.remove(index);
+ ASSERT(result);
+ DocImage *img = new DocImage(parent,attrList,opt->value,DocImage::Html,opt->value);
+ children.append(img);
+ found = TRUE;
+ }
+ }
+ if (!found)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"IMG tag does not have a SRC attribute!\n");
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName)
+{
+ DBG(("decodeSymbol(%s)\n",qPrint(symName)));
+ return HtmlEntityMapper::instance()->name2sym(symName);
+}
+
+//---------------------------------------------------------------------------
+
+static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children,
+ const QCString &doc)
+{
+ int retval = RetVal_OK;
+
+ if (doc.isEmpty()) return retval;
+
+ doctokenizerYYinit(doc,g_fileName);
+
+ // first parse any number of paragraphs
+ bool isFirst=TRUE;
+ DocPara *lastPar=0;
+ if (!children.isEmpty() && children.getLast()->kind()==DocNode::Kind_Para)
+ { // last child item was a paragraph
+ lastPar = (DocPara*)children.getLast();
+ isFirst=FALSE;
+ }
+ do
+ {
+ DocPara *par = new DocPara(parent);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ retval=par->parse();
+ if (!par->isEmpty())
+ {
+ children.append(par);
+ if (lastPar) lastPar->markLast(FALSE);
+ lastPar=par;
+ }
+ else
+ {
+ delete par;
+ }
+ } while (retval==TK_NEWPARA);
+ if (lastPar) lastPar->markLast();
+
+ //printf("internalValidateParsingDoc: %p: isFirst=%d isLast=%d\n",
+ // lastPar,lastPar?lastPar->isFirst():-1,lastPar?lastPar->isLast():-1);
+
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+static void readTextFileByName(const QCString &file,QCString &text)
+{
+ QStrList &examplePathList = Config_getList("EXAMPLE_PATH");
+ char *s=examplePathList.first();
+ while (s)
+ {
+ QCString absFileName = QCString(s)+portable_pathSeparator()+file;
+ QFileInfo fi(absFileName);
+ if (fi.exists())
+ {
+ text = fileToString(absFileName,Config_getBool("FILTER_SOURCE_FILES"));
+ return;
+ }
+ s=examplePathList.next();
+ }
+
+ // as a fallback we also look in the exampleNameDict
+ bool ambig;
+ FileDef *fd;
+ if ((fd=findFileDef(Doxygen::exampleNameDict,file,ambig)))
+ {
+ text = fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES"));
+ }
+ else if (ambig)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included file name %s is ambiguous"
+ "Possible candidates:\n%s",qPrint(file),
+ qPrint(showFileDefMatches(Doxygen::exampleNameDict,file))
+ );
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included file %s is not found. "
+ "Check your EXAMPLE_PATH",qPrint(file));
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocWord::DocWord(DocNode *parent,const QCString &word) :
+ m_word(word)
+{
+ m_parent = parent;
+ //printf("new word %s url=%s\n",word.data(),g_searchUrl.data());
+ if (Doxygen::searchIndex && !g_searchUrl.isEmpty())
+ {
+ Doxygen::searchIndex->addWord(word,FALSE);
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word,
+ const QCString &ref,const QCString &file,
+ const QCString &anchor,const QCString &tooltip) :
+ m_word(word), m_ref(ref),
+ m_file(file), m_relPath(g_relPath), m_anchor(anchor),
+ m_tooltip(tooltip)
+{
+ m_parent = parent;
+ //printf("DocLinkedWord: new word %s url=%s tooltip='%s'\n",
+ // word.data(),g_searchUrl.data(),tooltip.data());
+ if (Doxygen::searchIndex && !g_searchUrl.isEmpty())
+ {
+ Doxygen::searchIndex->addWord(word,FALSE);
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
+{
+ m_parent = parent;
+ if (id.isEmpty())
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label");
+ }
+ if (newAnchor) // found <a name="label">
+ {
+ m_anchor = id;
+ }
+ else if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix)
+ {
+ CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length()));
+ if (cite)
+ {
+ m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE);
+ m_anchor = id;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid cite anchor id `%s'",qPrint(id));
+ m_anchor = "invalid";
+ m_file = "invalid";
+ }
+ }
+ else // found \anchor label
+ {
+ SectionInfo *sec = Doxygen::sectionDict->find(id);
+ if (sec)
+ {
+ //printf("Found anchor %s\n",id.data());
+ m_file = sec->fileName;
+ m_anchor = sec->label;
+ if (g_sectionDict && g_sectionDict->find(id)==0)
+ {
+ //printf("Inserting in dictionary!\n");
+ g_sectionDict->append(id,sec);
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid anchor id `%s'",qPrint(id));
+ m_anchor = "invalid";
+ m_file = "invalid";
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocVerbatim::DocVerbatim(DocNode *parent,const QCString &context,
+ const QCString &text, Type t,bool isExample,
+ const QCString &exampleFile,bool isBlock,const QCString &lang)
+ : m_context(context), m_text(text), m_type(t),
+ m_isExample(isExample), m_exampleFile(exampleFile),
+ m_relPath(g_relPath), m_lang(lang), m_isBlock(isBlock)
+{
+ m_parent = parent;
+}
+
+
+//---------------------------------------------------------------------------
+
+void DocInclude::parse()
+{
+ DBG(("DocInclude::parse(file=%s,text=%s)\n",qPrint(m_file),qPrint(m_text)));
+ switch(m_type)
+ {
+ case IncWithLines:
+ // fall through
+ case Include:
+ // fall through
+ case DontInclude:
+ readTextFileByName(m_file,m_text);
+ g_includeFileText = m_text;
+ g_includeFileOffset = 0;
+ g_includeFileLength = m_text.length();
+ //printf("g_includeFile=<<%s>>\n",g_includeFileText.data());
+ break;
+ case VerbInclude:
+ // fall through
+ case HtmlInclude:
+ readTextFileByName(m_file,m_text);
+ break;
+ case LatexInclude:
+ readTextFileByName(m_file,m_text);
+ break;
+ case Snippet:
+ readTextFileByName(m_file,m_text);
+ // check here for the existence of the blockId inside the file, so we
+ // only generate the warning once.
+ int count;
+ if (!m_blockId.isEmpty() && (count=m_text.contains(m_blockId.data()))!=2)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n",
+ m_blockId.data(),m_file.data(),count);
+ }
+ break;
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void DocIncOperator::parse()
+{
+ const char *p = g_includeFileText;
+ uint l = g_includeFileLength;
+ uint o = g_includeFileOffset;
+ DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",qPrint(p),o,l));
+ uint so = o,bo;
+ bool nonEmpty = FALSE;
+ switch(type())
+ {
+ case Line:
+ while (o<l)
+ {
+ char c = p[o];
+ if (c=='\n')
+ {
+ if (nonEmpty) break; // we have a pattern to match
+ so=o+1; // no pattern, skip empty line
+ }
+ else if (!isspace((uchar)c)) // no white space char
+ {
+ nonEmpty=TRUE;
+ }
+ o++;
+ }
+ if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)
+ {
+ m_text = g_includeFileText.mid(so,o-so);
+ DBG(("DocIncOperator::parse() Line: %s\n",qPrint(m_text)));
+ }
+ g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line
+ break;
+ case SkipLine:
+ while (o<l)
+ {
+ so=o;
+ while (o<l)
+ {
+ char c = p[o];
+ if (c=='\n')
+ {
+ if (nonEmpty) break; // we have a pattern to match
+ so=o+1; // no pattern, skip empty line
+ }
+ else if (!isspace((uchar)c)) // no white space char
+ {
+ nonEmpty=TRUE;
+ }
+ o++;
+ }
+ if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)
+ {
+ m_text = g_includeFileText.mid(so,o-so);
+ DBG(("DocIncOperator::parse() SkipLine: %s\n",qPrint(m_text)));
+ break;
+ }
+ o++; // skip new line
+ }
+ g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line
+ break;
+ case Skip:
+ while (o<l)
+ {
+ so=o;
+ while (o<l)
+ {
+ char c = p[o];
+ if (c=='\n')
+ {
+ if (nonEmpty) break; // we have a pattern to match
+ so=o+1; // no pattern, skip empty line
+ }
+ else if (!isspace((uchar)c)) // no white space char
+ {
+ nonEmpty=TRUE;
+ }
+ o++;
+ }
+ if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)
+ {
+ break;
+ }
+ o++; // skip new line
+ }
+ g_includeFileOffset = so; // set pointer to start of new line
+ break;
+ case Until:
+ bo=o;
+ while (o<l)
+ {
+ so=o;
+ while (o<l)
+ {
+ char c = p[o];
+ if (c=='\n')
+ {
+ if (nonEmpty) break; // we have a pattern to match
+ so=o+1; // no pattern, skip empty line
+ }
+ else if (!isspace((uchar)c)) // no white space char
+ {
+ nonEmpty=TRUE;
+ }
+ o++;
+ }
+ if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1)
+ {
+ m_text = g_includeFileText.mid(bo,o-bo);
+ DBG(("DocIncOperator::parse() Until: %s\n",qPrint(m_text)));
+ break;
+ }
+ o++; // skip new line
+ }
+ g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line
+ break;
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void DocCopy::parse(QList<DocNode> &children)
+{
+ QCString doc,brief;
+ Definition *def;
+ if (findDocsForMemberOrCompound(m_link,&doc,&brief,&def))
+ {
+ if (g_copyStack.findRef(def)==-1) // definition not parsed earlier
+ {
+ bool hasParamCommand = g_hasParamCommand;
+ bool hasReturnCommand = g_hasReturnCommand;
+ QDict<void> paramsFound = g_paramsFound;
+ //printf("..1 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",
+ // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());
+
+ docParserPushContext(FALSE);
+ g_scope = def;
+ if (def->definitionType()==Definition::TypeMember && def->getOuterScope())
+ {
+ if (def->getOuterScope()!=Doxygen::globalScope)
+ {
+ g_context=def->getOuterScope()->name();
+ }
+ }
+ else if (def!=Doxygen::globalScope)
+ {
+ g_context=def->name();
+ }
+ g_styleStack.clear();
+ g_nodeStack.clear();
+ g_paramsFound.clear();
+ g_copyStack.append(def);
+ // make sure the descriptions end with a newline, so the parser will correctly
+ // handle them in all cases.
+ //printf("doc='%s'\n",doc.data());
+ //printf("brief='%s'\n",brief.data());
+ if (m_copyBrief)
+ {
+ brief+='\n';
+ internalValidatingParseDoc(m_parent,children,brief);
+
+ //printf("..2 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",
+ // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());
+ hasParamCommand = hasParamCommand || g_hasParamCommand;
+ hasReturnCommand = hasReturnCommand || g_hasReturnCommand;
+ QDictIterator<void> it(g_paramsFound);
+ void *item;
+ for (;(item=it.current());++it)
+ {
+ paramsFound.insert(it.currentKey(),it.current());
+ }
+ }
+ if (m_copyDetails)
+ {
+ doc+='\n';
+ internalValidatingParseDoc(m_parent,children,doc);
+
+ //printf("..3 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",
+ // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());
+ hasParamCommand = hasParamCommand || g_hasParamCommand;
+ hasReturnCommand = hasReturnCommand || g_hasReturnCommand;
+ QDictIterator<void> it(g_paramsFound);
+ void *item;
+ for (;(item=it.current());++it)
+ {
+ paramsFound.insert(it.currentKey(),it.current());
+ }
+ }
+ g_copyStack.remove(def);
+ ASSERT(g_styleStack.isEmpty());
+ ASSERT(g_nodeStack.isEmpty());
+ docParserPopContext(TRUE);
+
+ g_hasParamCommand = hasParamCommand;
+ g_hasReturnCommand = hasReturnCommand;
+ g_paramsFound = paramsFound;
+
+ //printf("..4 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n",
+ // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count());
+ }
+ else // oops, recursion
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"recursive call chain of \\copydoc commands detected at %d\n",
+ doctokenizerYYlineno);
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"target %s of \\copydoc command not found",
+ qPrint(m_link));
+ }
+}
+
+//---------------------------------------------------------------------------
+
+DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) :
+ m_id(id), m_key(key), m_relPath(g_relPath)
+{
+ m_parent = parent;
+}
+
+bool DocXRefItem::parse()
+{
+ QCString listName;
+ RefList *refList = Doxygen::xrefLists->find(m_key);
+ if (refList &&
+ (
+ // either not a built-in list or the list is enabled
+ (m_key!="todo" || Config_getBool("GENERATE_TODOLIST")) &&
+ (m_key!="test" || Config_getBool("GENERATE_TESTLIST")) &&
+ (m_key!="bug" || Config_getBool("GENERATE_BUGLIST")) &&
+ (m_key!="deprecated" || Config_getBool("GENERATE_DEPRECATEDLIST"))
+ )
+ )
+ {
+ RefItem *item = refList->getRefItem(m_id);
+ ASSERT(item!=0);
+ if (item)
+ {
+ if (g_memberDef && g_memberDef->name().at(0)=='@')
+ {
+ m_file = "@"; // can't cross reference anonymous enum
+ m_anchor = "@";
+ }
+ else
+ {
+ m_file = convertNameToFile(refList->listName(),FALSE,TRUE);
+ m_anchor = item->listAnchor;
+ }
+ m_title = refList->sectionTitle();
+ //printf("DocXRefItem: file=%s anchor=%s title=%s\n",
+ // m_file.data(),m_anchor.data(),m_title.data());
+
+ if (!item->text.isEmpty())
+ {
+ docParserPushContext();
+ internalValidatingParseDoc(this,m_children,item->text);
+ docParserPopContext();
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+DocFormula::DocFormula(DocNode *parent,int id) :
+ m_relPath(g_relPath)
+{
+ m_parent = parent;
+ QCString formCmd;
+ formCmd.sprintf("\\form#%d",id);
+ Formula *formula=Doxygen::formulaNameDict->find(formCmd);
+ if (formula)
+ {
+ m_id = formula->getId();
+ m_name.sprintf("form_%d",m_id);
+ m_text = formula->getFormulaText();
+ }
+}
+
+//---------------------------------------------------------------------------
+
+//int DocLanguage::parse()
+//{
+// int retval;
+// DBG(("DocLanguage::parse() start\n"));
+// g_nodeStack.push(this);
+//
+// // parse one or more paragraphs
+// bool isFirst=TRUE;
+// DocPara *par=0;
+// do
+// {
+// par = new DocPara(this);
+// if (isFirst) { par->markFirst(); isFirst=FALSE; }
+// m_children.append(par);
+// retval=par->parse();
+// }
+// while (retval==TK_NEWPARA);
+// if (par) par->markLast();
+//
+// DBG(("DocLanguage::parse() end\n"));
+// DocNode *n = g_nodeStack.pop();
+// ASSERT(n==this);
+// return retval;
+//}
+
+//---------------------------------------------------------------------------
+
+void DocSecRefItem::parse()
+{
+ DBG(("DocSecRefItem::parse() start\n"));
+ g_nodeStack.push(this);
+
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\refitem",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+
+ SectionInfo *sec=0;
+ if (!m_target.isEmpty())
+ {
+ sec=Doxygen::sectionDict->find(m_target);
+ if (sec)
+ {
+ m_file = sec->fileName;
+ m_anchor = sec->label;
+ if (g_sectionDict && g_sectionDict->find(m_target)==0)
+ {
+ g_sectionDict->append(m_target,sec);
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to unknown section %s",
+ qPrint(m_target));
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to empty target");
+ }
+
+ DBG(("DocSecRefItem::parse() end\n"));
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+void DocSecRefList::parse()
+{
+ DBG(("DocSecRefList::parse() start\n"));
+ g_nodeStack.push(this);
+
+ int tok=doctokenizerYYlex();
+ // skip white space
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // handle items
+ while (tok)
+ {
+ if (tok==TK_COMMAND)
+ {
+ switch (Mappers::cmdMapper->map(g_token->name))
+ {
+ case CMD_SECREFITEM:
+ {
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\refitem command");
+ break;
+ }
+ tok=doctokenizerYYlex();
+ if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\refitem",
+ tokToString(tok));
+ break;
+ }
+
+ DocSecRefItem *item = new DocSecRefItem(this,g_token->name);
+ m_children.append(item);
+ item->parse();
+ }
+ break;
+ case CMD_ENDSECREFLIST:
+ goto endsecreflist;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\secreflist",
+ qPrint(g_token->name));
+ goto endsecreflist;
+ }
+ }
+ else if (tok==TK_WHITESPACE)
+ {
+ // ignore whitespace
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s inside section reference list",
+ tokToString(tok));
+ goto endsecreflist;
+ }
+ tok=doctokenizerYYlex();
+ }
+
+endsecreflist:
+ DBG(("DocSecRefList::parse() end\n"));
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+DocInternalRef::DocInternalRef(DocNode *parent,const QCString &ref)
+ : m_relPath(g_relPath)
+{
+ m_parent = parent;
+ int i=ref.find('#');
+ if (i!=-1)
+ {
+ m_anchor = ref.right(ref.length()-i-1);
+ m_file = ref.left(i);
+ }
+ else
+ {
+ m_file = ref;
+ }
+}
+
+void DocInternalRef::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocInternalRef::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocInternalRef::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
+ m_refToSection(FALSE), m_refToAnchor(FALSE), m_isSubPage(FALSE)
+{
+ m_parent = parent;
+ Definition *compound = 0;
+ QCString anchor;
+ //printf("DocRef::DocRef(target=%s,context=%s)\n",target.data(),context.data());
+ ASSERT(!target.isEmpty());
+ SrcLangExt lang = getLanguageFromFileName(target);
+ m_relPath = g_relPath;
+ SectionInfo *sec = Doxygen::sectionDict->find(target);
+ if (sec==0 && lang==SrcLangExt_Markdown) // lookup as markdown file
+ {
+ sec = Doxygen::sectionDict->find(markdownFileNameToId(target));
+ }
+ if (sec) // ref to section or anchor
+ {
+ PageDef *pd = 0;
+ if (sec->type==SectionInfo::Page)
+ {
+ pd = Doxygen::pageSDict->find(target);
+ }
+ m_text = sec->title;
+ if (m_text.isEmpty()) m_text = sec->label;
+
+ m_ref = sec->ref;
+ m_file = stripKnownExtensions(sec->fileName);
+ m_refToAnchor = sec->type==SectionInfo::Anchor;
+ m_refToSection = sec->type!=SectionInfo::Anchor;
+ m_isSubPage = pd && pd->hasParentPage();
+ if (sec->type!=SectionInfo::Page || m_isSubPage) m_anchor = sec->label;
+ //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d type=%d\n",
+ // m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor,sec->type);
+ return;
+ }
+ else if (resolveLink(context,target,TRUE,&compound,anchor))
+ {
+ bool isFile = compound ?
+ (compound->definitionType()==Definition::TypeFile ||
+ compound->definitionType()==Definition::TypePage ? TRUE : FALSE) :
+ FALSE;
+ m_text = linkToText(compound?compound->getLanguage():SrcLangExt_Unknown,target,isFile);
+ m_anchor = anchor;
+ if (compound && compound->isLinkable()) // ref to compound
+ {
+ if (anchor.isEmpty() && /* compound link */
+ compound->definitionType()==Definition::TypeGroup && /* is group */
+ ((GroupDef *)compound)->groupTitle() /* with title */
+ )
+ {
+ m_text=((GroupDef *)compound)->groupTitle(); // use group's title as link
+ }
+ else if (compound->definitionType()==Definition::TypeMember &&
+ ((MemberDef*)compound)->isObjCMethod())
+ {
+ // Objective C Method
+ MemberDef *member = (MemberDef*)compound;
+ bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE;
+ m_text = member->objCMethodName(localLink,g_inSeeBlock);
+ }
+
+ m_file = compound->getOutputFileBase();
+ m_ref = compound->getReference();
+ //printf("isFile=%d compound=%s (%d)\n",isFile,compound->name().data(),
+ // compound->definitionType());
+ return;
+ }
+ else if (compound->definitionType()==Definition::TypeFile &&
+ ((FileDef*)compound)->generateSourceFile()
+ ) // undocumented file that has source code we can link to
+ {
+ m_file = compound->getSourceFileBase();
+ m_ref = compound->getReference();
+ return;
+ }
+ }
+ m_text = target;
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to `%s' for \\ref command",
+ qPrint(target));
+}
+
+static void flattenParagraphs(DocNode *root,QList<DocNode> &children)
+{
+ QListIterator<DocNode> li(children);
+ QList<DocNode> newChildren;
+ DocNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (dn->kind()==DocNode::Kind_Para)
+ {
+ DocPara *para = (DocPara*)dn;
+ QList<DocNode> ¶Children = para->children();
+ paraChildren.setAutoDelete(FALSE); // unlink children from paragraph node
+ QListIterator<DocNode> li2(paraChildren);
+ DocNode *dn2;
+ for (li2.toFirst();(dn2=li2.current());++li2)
+ {
+ newChildren.append(dn2); // add them to new node
+ }
+ }
+ }
+ children.clear();
+ QListIterator<DocNode> li3(newChildren);
+ for (li3.toFirst();(dn=li3.current());++li3)
+ {
+ children.append(dn);
+ dn->setParent(root);
+ }
+}
+
+void DocRef::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocRef::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ case TK_HTMLTAG:
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+
+ if (m_children.isEmpty() && !m_text.isEmpty())
+ {
+ g_insideHtmlLink=TRUE;
+ docParserPushContext();
+ internalValidatingParseDoc(this,m_children,m_text);
+ docParserPopContext();
+ g_insideHtmlLink=FALSE;
+ flattenParagraphs(this,m_children);
+ }
+
+ handlePendingStyleCommands(this,m_children);
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //context)
+{
+ static uint numBibFiles = Config_getList("CITE_BIB_FILES").count();
+ m_parent = parent;
+ QCString anchor;
+ //printf("DocCite::DocCite(target=%s)\n",target.data());
+ ASSERT(!target.isEmpty());
+ m_relPath = g_relPath;
+ CiteInfo *cite = Doxygen::citeDict->find(target);
+ if (numBibFiles>0 && cite && !cite->text.isEmpty()) // ref to citation
+ {
+ m_text = cite->text;
+ m_ref = cite->ref;
+ m_anchor = CiteConsts::anchorPrefix+cite->label;
+ m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE);
+ //printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n",
+ // m_text.data(),m_ref.data(),m_file.data(),m_anchor.data());
+ return;
+ }
+ m_text = target;
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to `%s' for \\cite command",
+ qPrint(target));
+}
+
+//---------------------------------------------------------------------------
+
+DocLink::DocLink(DocNode *parent,const QCString &target)
+{
+ m_parent = parent;
+ Definition *compound;
+ //PageInfo *page;
+ QCString anchor;
+ m_refText = target;
+ m_relPath = g_relPath;
+ if (!m_refText.isEmpty() && m_refText.at(0)=='#')
+ {
+ m_refText = m_refText.right(m_refText.length()-1);
+ }
+ if (resolveLink(g_context,stripKnownExtensions(target),g_inSeeBlock,
+ &compound,anchor))
+ {
+ m_anchor = anchor;
+ if (compound && compound->isLinkable())
+ {
+ m_file = compound->getOutputFileBase();
+ m_ref = compound->getReference();
+ }
+ else if (compound->definitionType()==Definition::TypeFile &&
+ ((FileDef*)compound)->generateSourceFile()
+ ) // undocumented file that has source code we can link to
+ {
+ m_file = compound->getSourceFileBase();
+ m_ref = compound->getReference();
+ }
+ return;
+ }
+
+ // bogus link target
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve link to `%s' for \\link command",
+ qPrint(target));
+}
+
+
+QCString DocLink::parse(bool isJavaLink,bool isXmlLink)
+{
+ QCString result;
+ g_nodeStack.push(this);
+ DBG(("DocLink::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children,FALSE))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ switch (Mappers::cmdMapper->map(g_token->name))
+ {
+ case CMD_ENDLINK:
+ if (isJavaLink)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"{@link.. ended with @endlink command");
+ }
+ goto endlink;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\link",
+ qPrint(g_token->name));
+ break;
+ }
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ case TK_HTMLTAG:
+ if (g_token->name!="see" || !isXmlLink)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found",
+ qPrint(g_token->name));
+ }
+ goto endlink;
+ case TK_LNKWORD:
+ case TK_WORD:
+ if (isJavaLink) // special case to detect closing }
+ {
+ QCString w = g_token->name;
+ int p;
+ if (w=="}")
+ {
+ goto endlink;
+ }
+ else if ((p=w.find('}'))!=-1)
+ {
+ uint l=w.length();
+ m_children.append(new DocWord(this,w.left(p)));
+ if ((uint)p<l-1) // something left after the } (for instance a .)
+ {
+ result=w.right(l-p-1);
+ }
+ goto endlink;
+ }
+ }
+ m_children.append(new DocWord(this,g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside"
+ " link command\n");
+ }
+endlink:
+
+ if (m_children.isEmpty()) // no link text
+ {
+ m_children.append(new DocWord(this,m_refText));
+ }
+
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocLink::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return result;
+}
+
+
+//---------------------------------------------------------------------------
+
+DocDotFile::DocDotFile(DocNode *parent,const QCString &name,const QCString &context) :
+ m_name(name), m_relPath(g_relPath), m_context(context)
+{
+ m_parent = parent;
+}
+
+void DocDotFile::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocDotFile::parse() start\n"));
+
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\dotfile",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ tok=doctokenizerYYlex();
+ while (tok==TK_WORD) // there are values following the title
+ {
+ if (g_token->name=="width")
+ {
+ m_width=g_token->chars;
+ }
+ else if (g_token->name=="height")
+ {
+ m_height=g_token->chars;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unknown option %s after image title",
+ qPrint(g_token->name));
+ }
+ tok=doctokenizerYYlex();
+ }
+ ASSERT(tok==0);
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+
+ bool ambig;
+ FileDef *fd = findFileDef(Doxygen::dotFileNameDict,m_name,ambig);
+ if (fd==0 && m_name.right(4)!=".dot") // try with .dot extension as well
+ {
+ fd = findFileDef(Doxygen::dotFileNameDict,m_name+".dot",ambig);
+ }
+ if (fd)
+ {
+ m_file = fd->absFilePath();
+ }
+ else if (ambig)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file name %s is ambiguous.\n"
+ "Possible candidates:\n%s",qPrint(m_name),
+ qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name))
+ );
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file %s is not found "
+ "in any of the paths specified via DOTFILE_DIRS!",qPrint(m_name));
+ }
+
+ DBG(("DocDotFile::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) :
+ m_name(name), m_relPath(g_relPath), m_context(context)
+{
+ m_parent = parent;
+}
+
+void DocMscFile::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocMscFile::parse() start\n"));
+
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\mscfile",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ tok=doctokenizerYYlex();
+ while (tok==TK_WORD) // there are values following the title
+ {
+ if (g_token->name=="width")
+ {
+ m_width=g_token->chars;
+ }
+ else if (g_token->name=="height")
+ {
+ m_height=g_token->chars;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unknown option %s after image title",
+ qPrint(g_token->name));
+ }
+ tok=doctokenizerYYlex();
+ }
+ ASSERT(tok==0);
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+
+ bool ambig;
+ FileDef *fd = findFileDef(Doxygen::mscFileNameDict,m_name,ambig);
+ if (fd==0 && m_name.right(4)!=".msc") // try with .msc extension as well
+ {
+ fd = findFileDef(Doxygen::mscFileNameDict,m_name+".msc",ambig);
+ }
+ if (fd)
+ {
+ m_file = fd->absFilePath();
+ }
+ else if (ambig)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file name %s is ambiguous.\n"
+ "Possible candidates:\n%s",qPrint(m_name),
+ qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name))
+ );
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file %s is not found "
+ "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name));
+ }
+
+ DBG(("DocMscFile::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+DocDiaFile::DocDiaFile(DocNode *parent,const QCString &name,const QCString &context) :
+ m_name(name), m_relPath(g_relPath), m_context(context)
+{
+ m_parent = parent;
+}
+
+void DocDiaFile::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocDiaFile::parse() start\n"));
+
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\diafile",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ tok=doctokenizerYYlex();
+ while (tok==TK_WORD) // there are values following the title
+ {
+ if (g_token->name=="width")
+ {
+ m_width=g_token->chars;
+ }
+ else if (g_token->name=="height")
+ {
+ m_height=g_token->chars;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unknown option %s after image title",
+ qPrint(g_token->name));
+ }
+ tok=doctokenizerYYlex();
+ }
+ ASSERT(tok==0);
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+
+ bool ambig;
+ FileDef *fd = findFileDef(Doxygen::diaFileNameDict,m_name,ambig);
+ if (fd==0 && m_name.right(4)!=".dia") // try with .dia extension as well
+ {
+ fd = findFileDef(Doxygen::diaFileNameDict,m_name+".dia",ambig);
+ }
+ if (fd)
+ {
+ m_file = fd->absFilePath();
+ }
+ else if (ambig)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file name %s is ambiguous.\n"
+ "Possible candidates:\n%s",qPrint(m_name),
+ qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name))
+ );
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file %s is not found "
+ "in any of the paths specified via DIAFILE_DIRS!",qPrint(m_name));
+ }
+
+ DBG(("DocDiaFile::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+//---------------------------------------------------------------------------
+
+DocVhdlFlow::DocVhdlFlow(DocNode *parent)
+{
+ m_parent = parent;
+}
+
+void DocVhdlFlow::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocVhdlFlow::parse() start\n"));
+
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\mscfile",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ tok=doctokenizerYYlex();
+
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+
+ DBG(("DocVhdlFlow::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ VhdlDocGen::createFlowChart(g_memberDef);
+}
+
+
+//---------------------------------------------------------------------------
+
+DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString &name,
+ Type t,const QCString &url) :
+ m_attribs(attribs), m_name(name),
+ m_type(t), m_relPath(g_relPath),
+ m_url(url)
+{
+ m_parent = parent;
+}
+
+void DocImage::parse()
+{
+ g_nodeStack.push(this);
+ DBG(("DocImage::parse() start\n"));
+
+ // parse title
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (tok==TK_WORD && (g_token->name=="width=" || g_token->name=="height="))
+ {
+ // special case: no title, but we do have a size indicator
+ doctokenizerYYsetStateTitleAttrValue();
+ // strip =
+ g_token->name=g_token->name.left(g_token->name.length()-1);
+ break;
+ }
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\image",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ // parse size attributes
+ tok=doctokenizerYYlex();
+ while (tok==TK_WORD) // there are values following the title
+ {
+ if (g_token->name=="width")
+ {
+ m_width=g_token->chars;
+ }
+ else if (g_token->name=="height")
+ {
+ m_height=g_token->chars;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unknown option %s after image title",
+ qPrint(g_token->name));
+ }
+ tok=doctokenizerYYlex();
+ }
+ doctokenizerYYsetStatePara();
+
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocImage::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+
+//---------------------------------------------------------------------------
+
+int DocHtmlHeader::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlHeader::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <h%d> tag",
+ qPrint(g_token->name),m_level);
+ break;
+ case TK_HTMLTAG:
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_H1 && g_token->endTag) // found </h1> tag
+ {
+ if (m_level!=1)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h1>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_H2 && g_token->endTag) // found </h2> tag
+ {
+ if (m_level!=2)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h2>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_H3 && g_token->endTag) // found </h3> tag
+ {
+ if (m_level!=3)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h3>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_H4 && g_token->endTag) // found </h4> tag
+ {
+ if (m_level!=4)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h4>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_H5 && g_token->endTag) // found </h5> tag
+ {
+ if (m_level!=5)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h5>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_H6 && g_token->endTag) // found </h6> tag
+ {
+ if (m_level!=6)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h6>",
+ m_level);
+ }
+ goto endheader;
+ }
+ else if (tagId==HTML_A)
+ {
+ if (!g_token->endTag)
+ {
+ handleAHref(this,m_children,g_token->attribs);
+ }
+ }
+ else if (tagId==HTML_BR)
+ {
+ DocLineBreak *lb = new DocLineBreak(this);
+ m_children.append(lb);
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <h%d> context",
+ g_token->endTag?"/":"",qPrint(g_token->name),m_level);
+ }
+
+ }
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside"
+ " <h%d> tag\n",m_level);
+ }
+endheader:
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocHtmlHeader::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHRef::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHRef::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <a>..</a> block",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ case TK_HTMLTAG:
+
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_A && g_token->endTag) // found </a> tag
+ {
+ goto endhref;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <a href=...> context",
+ g_token->endTag?"/":"",qPrint(g_token->name),doctokenizerYYlineno);
+ }
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok),doctokenizerYYlineno);
+ break;
+ }
+ }
+ }
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside"
+ " <a href=...> tag",doctokenizerYYlineno);
+ }
+endhref:
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocHRef::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocInternal::parse(int level)
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocInternal::parse() start\n"));
+
+ // first parse any number of paragraphs
+ bool isFirst=TRUE;
+ DocPara *lastPar=0;
+ do
+ {
+ DocPara *par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ retval=par->parse();
+ if (!par->isEmpty())
+ {
+ m_children.append(par);
+ lastPar=par;
+ }
+ else
+ {
+ delete par;
+ }
+ if (retval==TK_LISTITEM)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found",doctokenizerYYlineno);
+ }
+ } while (retval!=0 &&
+ retval!=RetVal_Section &&
+ retval!=RetVal_Subsection &&
+ retval!=RetVal_Subsubsection &&
+ retval!=RetVal_Paragraph &&
+ retval!=RetVal_EndInternal
+ );
+ if (lastPar) lastPar->markLast();
+
+ // then parse any number of level-n sections
+ while ((level==1 && retval==RetVal_Section) ||
+ (level==2 && retval==RetVal_Subsection) ||
+ (level==3 && retval==RetVal_Subsubsection) ||
+ (level==4 && retval==RetVal_Paragraph)
+ )
+ {
+ DocSection *s=new DocSection(this,
+ QMIN(level+Doxygen::subpageNestingLevel,5),g_token->sectionId);
+ m_children.append(s);
+ retval = s->parse();
+ }
+
+ if (retval==RetVal_Internal)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"\\internal command found inside internal section");
+ }
+
+ DBG(("DocInternal::parse() end: retval=%x\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocIndexEntry::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocIndexEntry::parse() start\n"));
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\addindex command");
+ goto endindexentry;
+ }
+ doctokenizerYYsetStateTitle();
+ m_entry="";
+ while ((tok=doctokenizerYYlex()))
+ {
+ switch (tok)
+ {
+ case TK_WHITESPACE:
+ m_entry+=" ";
+ break;
+ case TK_WORD:
+ case TK_LNKWORD:
+ m_entry+=g_token->name;
+ break;
+ case TK_SYMBOL:
+ {
+ DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name);
+ switch (s)
+ {
+ case DocSymbol::Sym_BSlash: m_entry+='\\'; break;
+ case DocSymbol::Sym_At: m_entry+='@'; break;
+ case DocSymbol::Sym_Less: m_entry+='<'; break;
+ case DocSymbol::Sym_Greater: m_entry+='>'; break;
+ case DocSymbol::Sym_Amp: m_entry+='&'; break;
+ case DocSymbol::Sym_Dollar: m_entry+='$'; break;
+ case DocSymbol::Sym_Hash: m_entry+='#'; break;
+ case DocSymbol::Sym_Percent: m_entry+='%'; break;
+ case DocSymbol::Sym_apos: m_entry+='\''; break;
+ case DocSymbol::Sym_Quot: m_entry+='"'; break;
+ case DocSymbol::Sym_lsquo: m_entry+='`'; break;
+ case DocSymbol::Sym_rsquo: m_entry+='\''; break;
+ case DocSymbol::Sym_ldquo: m_entry+="``"; break;
+ case DocSymbol::Sym_rdquo: m_entry+="''"; break;
+ case DocSymbol::Sym_ndash: m_entry+="--"; break;
+ case DocSymbol::Sym_mdash: m_entry+="---"; break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected symbol found as argument of \\addindex");
+ break;
+ }
+ }
+ break;
+ case TK_COMMAND:
+ switch (Mappers::cmdMapper->map(g_token->name))
+ {
+ case CMD_BSLASH: m_entry+='\\'; break;
+ case CMD_AT: m_entry+='@'; break;
+ case CMD_LESS: m_entry+='<'; break;
+ case CMD_GREATER: m_entry+='>'; break;
+ case CMD_AMP: m_entry+='&'; break;
+ case CMD_DOLLAR: m_entry+='$'; break;
+ case CMD_HASH: m_entry+='#'; break;
+ case CMD_DCOLON: m_entry+="::"; break;
+ case CMD_PERCENT: m_entry+='%'; break;
+ case CMD_NDASH: m_entry+="--"; break;
+ case CMD_MDASH: m_entry+="---"; break;
+ case CMD_QUOTE: m_entry+='"'; break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex",
+ qPrint(g_token->name));
+ break;
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ if (tok!=0) retval=tok;
+ doctokenizerYYsetStatePara();
+ m_entry = m_entry.stripWhiteSpace();
+endindexentry:
+ DBG(("DocIndexEntry::parse() end retval=%x\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlCaption::parse()
+{
+ int retval=0;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlCaption::parse() start\n"));
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <caption> tag",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ case TK_HTMLTAG:
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_CAPTION && g_token->endTag) // found </caption> tag
+ {
+ retval = RetVal_OK;
+ goto endcaption;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <caption> context",
+ g_token->endTag?"/":"",qPrint(g_token->name));
+ }
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside"
+ " <caption> tag",doctokenizerYYlineno);
+ }
+endcaption:
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocHtmlCaption::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlCell::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlCell::parse() start\n"));
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ if (retval==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_TD && g_token->endTag) // found </dt> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ else if (tagId==HTML_TH && g_token->endTag) // found </th> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ }
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DBG(("DocHtmlCell::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+int DocHtmlCell::parseXml()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlCell::parseXml() start\n"));
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ if (retval==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_ITEM && g_token->endTag) // found </item> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ else if (tagId==XML_DESCRIPTION && g_token->endTag) // found </description> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ }
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DBG(("DocHtmlCell::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+int DocHtmlCell::rowSpan() const
+{
+ int retval = 0;
+ HtmlAttribList attrs = attribs();
+ uint i;
+ for (i=0; i<attrs.count(); ++i)
+ {
+ if (attrs.at(i)->name.lower()=="rowspan")
+ {
+ retval = attrs.at(i)->value.toInt();
+ break;
+ }
+ }
+ return retval;
+}
+
+int DocHtmlCell::colSpan() const
+{
+ int retval = 1;
+ HtmlAttribList attrs = attribs();
+ uint i;
+ for (i=0; i<attrs.count(); ++i)
+ {
+ if (attrs.at(i)->name.lower()=="colspan")
+ {
+ retval = QMAX(1,attrs.at(i)->value.toInt());
+ break;
+ }
+ }
+ return retval;
+}
+
+DocHtmlCell::Alignment DocHtmlCell::alignment() const
+{
+ HtmlAttribList attrs = attribs();
+ uint i;
+ for (i=0; i<attrs.count(); ++i)
+ {
+ if (attrs.at(i)->name.lower()=="align")
+ {
+ if (attrs.at(i)->value.lower()=="center")
+ return Center;
+ else if (attrs.at(i)->value.lower()=="right")
+ return Right;
+ else return Left;
+ }
+ }
+ return Left;
+}
+
+
+//---------------------------------------------------------------------------
+
+int DocHtmlRow::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlRow::parse() start\n"));
+
+ bool isHeading=FALSE;
+ bool isFirst=TRUE;
+ DocHtmlCell *cell=0;
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_TD && !g_token->endTag) // found <td> tag
+ {
+ }
+ else if (tagId==HTML_TH && !g_token->endTag) // found <th> tag
+ {
+ isHeading=TRUE;
+ }
+ else // found some other tag
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but "
+ "found <%s> instead!",qPrint(g_token->name));
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto endrow;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a html description title");
+ goto endrow;
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but found %s token instead!",
+ tokToString(tok));
+ goto endrow;
+ }
+
+ // parse one or more cells
+ do
+ {
+ cell=new DocHtmlCell(this,g_token->attribs,isHeading);
+ cell->markFirst(isFirst);
+ isFirst=FALSE;
+ m_children.append(cell);
+ retval=cell->parse();
+ isHeading = retval==RetVal_TableHCell;
+ }
+ while (retval==RetVal_TableCell || retval==RetVal_TableHCell);
+ if (cell) cell->markLast(TRUE);
+
+endrow:
+ DBG(("DocHtmlRow::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+int DocHtmlRow::parseXml(bool isHeading)
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlRow::parseXml() start\n"));
+
+ bool isFirst=TRUE;
+ DocHtmlCell *cell=0;
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_TERM && !g_token->endTag) // found <term> tag
+ {
+ }
+ else if (tagId==XML_DESCRIPTION && !g_token->endTag) // found <description> tag
+ {
+ }
+ else // found some other tag
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <term> or <description> tag but "
+ "found <%s> instead!",qPrint(g_token->name));
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto endrow;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a html description title");
+ goto endrow;
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but found %s token instead!",
+ tokToString(tok));
+ goto endrow;
+ }
+
+ do
+ {
+ cell=new DocHtmlCell(this,g_token->attribs,isHeading);
+ cell->markFirst(isFirst);
+ isFirst=FALSE;
+ m_children.append(cell);
+ retval=cell->parseXml();
+ }
+ while (retval==RetVal_TableCell || retval==RetVal_TableHCell);
+ if (cell) cell->markLast(TRUE);
+
+endrow:
+ DBG(("DocHtmlRow::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlTable::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlTable::parse() start\n"));
+
+getrow:
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_TR && !g_token->endTag) // found <tr> tag
+ {
+ // no caption, just rows
+ retval=RetVal_TableRow;
+ }
+ else if (tagId==HTML_CAPTION && !g_token->endTag) // found <caption> tag
+ {
+ if (m_caption)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"table already has a caption, found another one");
+ }
+ else
+ {
+ m_caption = new DocHtmlCaption(this,g_token->attribs);
+ retval=m_caption->parse();
+
+ if (retval==RetVal_OK) // caption was parsed ok
+ {
+ goto getrow;
+ }
+ }
+ }
+ else // found wrong token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <tr> or <caption> tag but "
+ "found <%s%s> instead!", g_token->endTag ? "/" : "", qPrint(g_token->name));
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a <tr> or <caption> tag");
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <tr> tag but found %s token instead!",
+ tokToString(tok));
+ }
+
+ // parse one or more rows
+ while (retval==RetVal_TableRow)
+ {
+ DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs);
+ m_children.append(tr);
+ retval=tr->parse();
+ }
+
+ computeTableGrid();
+
+ DBG(("DocHtmlTable::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval==RetVal_EndTable ? RetVal_OK : retval;
+}
+
+int DocHtmlTable::parseXml()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlTable::parseXml() start\n"));
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ int tagId=0;
+ bool isHeader=FALSE;
+ if (tok==TK_HTMLTAG)
+ {
+ tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_ITEM && !g_token->endTag) // found <item> tag
+ {
+ retval=RetVal_TableRow;
+ }
+ if (tagId==XML_LISTHEADER && !g_token->endTag) // found <listheader> tag
+ {
+ retval=RetVal_TableRow;
+ isHeader=TRUE;
+ }
+ }
+
+ // parse one or more rows
+ while (retval==RetVal_TableRow)
+ {
+ DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs);
+ m_children.append(tr);
+ retval=tr->parseXml(isHeader);
+ isHeader=FALSE;
+ }
+
+ computeTableGrid();
+
+ DBG(("DocHtmlTable::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval==RetVal_EndTable ? RetVal_OK : retval;
+}
+
+/** Helper class to compute the grid for an HTML style table */
+struct ActiveRowSpan
+{
+ ActiveRowSpan(int rows,int col) : rowsLeft(rows), column(col) {}
+ int rowsLeft;
+ int column;
+};
+
+/** List of ActiveRowSpan classes. */
+typedef QList<ActiveRowSpan> RowSpanList;
+
+/** determines the location of all cells in a grid, resolving row and
+ column spans. For each the total number of visible cells is computed,
+ and the total number of visible columns over all rows is stored.
+ */
+void DocHtmlTable::computeTableGrid()
+{
+ //printf("computeTableGrid()\n");
+ RowSpanList rowSpans;
+ rowSpans.setAutoDelete(TRUE);
+ int maxCols=0;
+ int rowIdx=1;
+ QListIterator<DocNode> li(children());
+ DocNode *rowNode;
+ for (li.toFirst();(rowNode=li.current());++li)
+ {
+ int colIdx=1;
+ int cells=0;
+ if (rowNode->kind()==DocNode::Kind_HtmlRow)
+ {
+ uint i;
+ DocHtmlRow *row = (DocHtmlRow*)rowNode;
+ QListIterator<DocNode> rli(row->children());
+ DocNode *cellNode;
+ for (rli.toFirst();(cellNode=rli.current());++rli)
+ {
+ if (cellNode->kind()==DocNode::Kind_HtmlCell)
+ {
+ DocHtmlCell *cell = (DocHtmlCell*)cellNode;
+ int rs = cell->rowSpan();
+ int cs = cell->colSpan();
+
+ for (i=0;i<rowSpans.count();i++)
+ {
+ if (rowSpans.at(i)->rowsLeft>0 &&
+ rowSpans.at(i)->column==colIdx)
+ {
+ colIdx=rowSpans.at(i)->column+1;
+ cells++;
+ }
+ }
+ if (rs>0) rowSpans.append(new ActiveRowSpan(rs,colIdx));
+ //printf("found cell at (%d,%d)\n",rowIdx,colIdx);
+ cell->setRowIndex(rowIdx);
+ cell->setColumnIndex(colIdx);
+ colIdx+=cs;
+ cells++;
+ }
+ }
+ for (i=0;i<rowSpans.count();i++)
+ {
+ if (rowSpans.at(i)->rowsLeft>0) rowSpans.at(i)->rowsLeft--;
+ }
+ row->setVisibleCells(cells);
+ row->setRowIndex(rowIdx);
+ rowIdx++;
+ }
+ if (colIdx-1>maxCols) maxCols=colIdx-1;
+ }
+ m_numCols = maxCols;
+}
+
+void DocHtmlTable::accept(DocVisitor *v)
+{
+ v->visitPre(this);
+ // for HTML output we put the caption first
+ if (m_caption && v->id()==DocVisitor_Html) m_caption->accept(v);
+ QListIterator<DocNode> cli(m_children);
+ DocNode *n;
+ for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
+ // for other output formats we put the caption last
+ if (m_caption && v->id()!=DocVisitor_Html) m_caption->accept(v);
+ v->visitPost(this);
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlDescTitle::parse()
+{
+ int retval=0;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlDescTitle::parse() start\n"));
+
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ {
+ QCString cmdName=g_token->name;
+ bool isJavaLink=FALSE;
+ switch (Mappers::cmdMapper->map(cmdName))
+ {
+ case CMD_REF:
+ {
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(g_token->name));
+ }
+ else
+ {
+ doctokenizerYYsetStateRef();
+ tok=doctokenizerYYlex(); // get the reference id
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ }
+ else
+ {
+ DocRef *ref = new DocRef(this,g_token->name,g_context);
+ m_children.append(ref);
+ ref->parse();
+ }
+ doctokenizerYYsetStatePara();
+ }
+ }
+ break;
+ case CMD_JAVALINK:
+ isJavaLink=TRUE;
+ // fall through
+ case CMD_LINK:
+ {
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ }
+ else
+ {
+ doctokenizerYYsetStateLink();
+ tok=doctokenizerYYlex();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ }
+ else
+ {
+ doctokenizerYYsetStatePara();
+ DocLink *lnk = new DocLink(this,g_token->name);
+ m_children.append(lnk);
+ QCString leftOver = lnk->parse(isJavaLink);
+ if (!leftOver.isEmpty())
+ {
+ m_children.append(new DocWord(this,leftOver));
+ }
+ }
+ }
+ }
+
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <dt> tag",
+ qPrint(g_token->name));
+ }
+ }
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ case TK_HTMLTAG:
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_DD && !g_token->endTag) // found <dd> tag
+ {
+ retval = RetVal_DescData;
+ goto endtitle;
+ }
+ else if (tagId==HTML_DT && g_token->endTag)
+ {
+ // ignore </dt> tag.
+ }
+ else if (tagId==HTML_DT)
+ {
+ // missing <dt> tag.
+ retval = RetVal_DescTitle;
+ goto endtitle;
+ }
+ else if (tagId==HTML_DL && g_token->endTag)
+ {
+ retval=RetVal_EndDesc;
+ goto endtitle;
+ }
+ else if (tagId==HTML_A)
+ {
+ if (!g_token->endTag)
+ {
+ handleAHref(this,m_children,g_token->attribs);
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <dt> context",
+ g_token->endTag?"/":"",qPrint(g_token->name));
+ }
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside"
+ " <dt> tag");
+ }
+endtitle:
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocHtmlDescTitle::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlDescData::parse()
+{
+ m_attribs = g_token->attribs;
+ int retval=0;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlDescData::parse() start\n"));
+
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DBG(("DocHtmlDescData::parse() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlDescList::parse()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlDescList::parse() start\n"));
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_DT && !g_token->endTag) // found <dt> tag
+ {
+ // continue
+ }
+ else // found some other tag
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <dt> tag but "
+ "found <%s> instead!",qPrint(g_token->name));
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto enddesclist;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a html description title");
+ goto enddesclist;
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <dt> tag but found %s token instead!",
+ tokToString(tok));
+ goto enddesclist;
+ }
+
+ do
+ {
+ DocHtmlDescTitle *dt=new DocHtmlDescTitle(this,g_token->attribs);
+ m_children.append(dt);
+ DocHtmlDescData *dd=new DocHtmlDescData(this);
+ m_children.append(dd);
+ retval=dt->parse();
+ if (retval==RetVal_DescData)
+ {
+ retval=dd->parse();
+ }
+ else if (retval!=RetVal_DescTitle)
+ {
+ // error
+ break;
+ }
+ } while (retval==RetVal_DescTitle);
+
+ if (retval==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <dl> block");
+ }
+
+enddesclist:
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocHtmlDescList::parse() end\n"));
+ return retval==RetVal_EndDesc ? RetVal_OK : retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlListItem::parse()
+{
+ DBG(("DocHtmlListItem::parse() start\n"));
+ int retval=0;
+ g_nodeStack.push(this);
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocHtmlListItem::parse() end retval=%x\n",retval));
+ return retval;
+}
+
+int DocHtmlListItem::parseXml()
+{
+ DBG(("DocHtmlListItem::parseXml() start\n"));
+ int retval=0;
+ g_nodeStack.push(this);
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ if (retval==0) break;
+
+ //printf("new item: retval=%x g_token->name=%s g_token->endTag=%d\n",
+ // retval,qPrint(g_token->name),g_token->endTag);
+ if (retval==RetVal_ListItem)
+ {
+ break;
+ }
+ }
+ while (retval!=RetVal_CloseXml);
+
+ if (par) par->markLast();
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocHtmlListItem::parseXml() end retval=%x\n",retval));
+ return retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocHtmlList::parse()
+{
+ DBG(("DocHtmlList::parse() start\n"));
+ int retval=RetVal_OK;
+ int num=1;
+ g_nodeStack.push(this);
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace and paragraph breaks
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==HTML_LI && !g_token->endTag) // found <li> tag
+ {
+ // ok, we can go on.
+ }
+ else if (((m_type==Unordered && tagId==HTML_UL) ||
+ (m_type==Ordered && tagId==HTML_OL)
+ ) && g_token->endTag
+ ) // found empty list
+ {
+ // add dummy item to obtain valid HTML
+ m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"empty list!");
+ retval = RetVal_EndList;
+ goto endlist;
+ }
+ else // found some other tag
+ {
+ // add dummy item to obtain valid HTML
+ m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <li> tag but "
+ "found <%s%s> instead!",g_token->endTag?"/":"",qPrint(g_token->name));
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto endlist;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ // add dummy item to obtain valid HTML
+ m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a html list item");
+ goto endlist;
+ }
+ else // token other than html token
+ {
+ // add dummy item to obtain valid HTML
+ m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <li> tag but found %s token instead!",
+ tokToString(tok));
+ goto endlist;
+ }
+
+ do
+ {
+ DocHtmlListItem *li=new DocHtmlListItem(this,g_token->attribs,num++);
+ m_children.append(li);
+ retval=li->parse();
+ } while (retval==RetVal_ListItem);
+
+ if (retval==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <%cl> block",
+ m_type==Unordered ? 'u' : 'o');
+ }
+
+endlist:
+ DBG(("DocHtmlList::parse() end retval=%x\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval==RetVal_EndList ? RetVal_OK : retval;
+}
+
+int DocHtmlList::parseXml()
+{
+ DBG(("DocHtmlList::parseXml() start\n"));
+ int retval=RetVal_OK;
+ int num=1;
+ g_nodeStack.push(this);
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace and paragraph breaks
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ //printf("g_token->name=%s g_token->endTag=%d\n",qPrint(g_token->name),g_token->endTag);
+ if (tagId==XML_ITEM && !g_token->endTag) // found <item> tag
+ {
+ // ok, we can go on.
+ }
+ else // found some other tag
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <item> tag but "
+ "found <%s> instead!",qPrint(g_token->name));
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto endlist;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking"
+ " for a html list item");
+ goto endlist;
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <item> tag but found %s token instead!",
+ tokToString(tok));
+ goto endlist;
+ }
+
+ do
+ {
+ DocHtmlListItem *li=new DocHtmlListItem(this,g_token->attribs,num++);
+ m_children.append(li);
+ retval=li->parseXml();
+ if (retval==0) break;
+ //printf("retval=%x g_token->name=%s\n",retval,qPrint(g_token->name));
+ } while (retval==RetVal_ListItem);
+
+ if (retval==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <list type=\"%s\"> block",
+ m_type==Unordered ? "bullet" : "number");
+ }
+
+endlist:
+ DBG(("DocHtmlList::parseXml() end retval=%x\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval==RetVal_EndList ||
+ (retval==RetVal_CloseXml || g_token->name=="list") ?
+ RetVal_OK : retval;
+}
+
+//--------------------------------------------------------------------------
+
+int DocHtmlBlockQuote::parse()
+{
+ DBG(("DocHtmlBlockQuote::parse() start\n"));
+ int retval=0;
+ g_nodeStack.push(this);
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocHtmlBlockQuote::parse() end retval=%x\n",retval));
+ return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocParBlock::parse()
+{
+ DBG(("DocParBlock::parse() start\n"));
+ int retval=0;
+ g_nodeStack.push(this);
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocParBlock::parse() end retval=%x\n",retval));
+ return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval;
+}
+
+//---------------------------------------------------------------------------
+
+int DocSimpleListItem::parse()
+{
+ g_nodeStack.push(this);
+ int rv=m_paragraph->parse();
+ m_paragraph->markFirst();
+ m_paragraph->markLast();
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return rv;
+}
+
+//--------------------------------------------------------------------------
+
+int DocSimpleList::parse()
+{
+ g_nodeStack.push(this);
+ int rv;
+ do
+ {
+ DocSimpleListItem *li=new DocSimpleListItem(this);
+ m_children.append(li);
+ rv=li->parse();
+ } while (rv==RetVal_ListItem);
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return (rv!=TK_NEWPARA) ? rv : RetVal_OK;
+}
+
+//--------------------------------------------------------------------------
+
+DocAutoListItem::DocAutoListItem(DocNode *parent,int indent,int num)
+ : m_indent(indent), m_itemNum(num)
+{
+ m_parent = parent;
+}
+
+int DocAutoListItem::parse()
+{
+ int retval = RetVal_OK;
+ g_nodeStack.push(this);
+
+ // first parse any number of paragraphs
+ bool isFirst=TRUE;
+ DocPara *lastPar=0;
+ do
+ {
+ DocPara *par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ retval=par->parse();
+ if (!par->isEmpty())
+ {
+ m_children.append(par);
+ if (lastPar) lastPar->markLast(FALSE);
+ lastPar=par;
+ }
+ else
+ {
+ delete par;
+ }
+ // next paragraph should be more indented than the - marker to belong
+ // to this item
+ } while (retval==TK_NEWPARA && g_token->indent>m_indent);
+ if (lastPar) lastPar->markLast();
+
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ //printf("DocAutoListItem: retval=%d indent=%d\n",retval,g_token->indent);
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+DocAutoList::DocAutoList(DocNode *parent,int indent,bool isEnumList,
+ int depth) :
+ m_indent(indent), m_isEnumList(isEnumList),
+ m_depth(depth)
+{
+ m_parent = parent;
+}
+
+int DocAutoList::parse()
+{
+ int retval = RetVal_OK;
+ int num=1;
+ g_nodeStack.push(this);
+ doctokenizerYYstartAutoList();
+ // first item or sub list => create new list
+ do
+ {
+ if (g_token->id!=-1) // explicitly numbered list
+ {
+ num=g_token->id; // override num with real number given
+ }
+ DocAutoListItem *li = new DocAutoListItem(this,m_indent,num++);
+ m_children.append(li);
+ retval=li->parse();
+ //printf("DocAutoList::parse(): retval=0x%x g_token->indent=%d m_indent=%d "
+ // "m_isEnumList=%d g_token->isEnumList=%d g_token->name=%s\n",
+ // retval,g_token->indent,m_indent,m_isEnumList,g_token->isEnumList,
+ // g_token->name.data());
+ //printf("num=%d g_token->id=%d\n",num,g_token->id);
+ }
+ while (retval==TK_LISTITEM && // new list item
+ m_indent==g_token->indent && // at same indent level
+ m_isEnumList==g_token->isEnumList && // of the same kind
+ (g_token->id==-1 || g_token->id>=num) // increasing number (or no number)
+ );
+
+ doctokenizerYYendAutoList();
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+void DocTitle::parse()
+{
+ DBG(("DocTitle::parse() start\n"));
+ g_nodeStack.push(this);
+ doctokenizerYYsetStateTitle();
+ int tok;
+ while ((tok=doctokenizerYYlex()))
+ {
+ if (!defaultHandleToken(this,tok,m_children))
+ {
+ switch (tok)
+ {
+ case TK_COMMAND:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a title section",
+ qPrint(g_token->name));
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+ }
+ doctokenizerYYsetStatePara();
+ handlePendingStyleCommands(this,m_children);
+ DBG(("DocTitle::parse() end\n"));
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+}
+
+void DocTitle::parseFromString(const QCString &text)
+{
+ m_children.append(new DocWord(this,text));
+}
+
+//--------------------------------------------------------------------------
+
+DocSimpleSect::DocSimpleSect(DocNode *parent,Type t) :
+ m_type(t)
+{
+ m_parent = parent;
+ m_title=0;
+}
+
+DocSimpleSect::~DocSimpleSect()
+{
+ delete m_title;
+}
+
+void DocSimpleSect::accept(DocVisitor *v)
+{
+ v->visitPre(this);
+ if (m_title) m_title->accept(v);
+ QListIterator<DocNode> cli(m_children);
+ DocNode *n;
+ for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
+ v->visitPost(this);
+}
+
+int DocSimpleSect::parse(bool userTitle,bool needsSeparator)
+{
+ DBG(("DocSimpleSect::parse() start\n"));
+ g_nodeStack.push(this);
+
+ // handle case for user defined title
+ if (userTitle)
+ {
+ m_title = new DocTitle(this);
+ m_title->parse();
+ }
+
+ // add new paragraph as child
+ DocPara *par = new DocPara(this);
+ if (m_children.isEmpty())
+ {
+ par->markFirst();
+ }
+ else
+ {
+ ASSERT(m_children.getLast()->kind()==DocNode::Kind_Para);
+ ((DocPara *)m_children.getLast())->markLast(FALSE);
+ }
+ par->markLast();
+ if (needsSeparator) m_children.append(new DocSimpleSectSep(this));
+ m_children.append(par);
+
+ // parse the contents of the paragraph
+ int retval = par->parse();
+
+ DBG(("DocSimpleSect::parse() end retval=%d\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval; // 0==EOF, TK_NEWPARA, TK_LISTITEM, TK_ENDLIST, RetVal_SimpleSec
+}
+
+int DocSimpleSect::parseRcs()
+{
+ DBG(("DocSimpleSect::parseRcs() start\n"));
+ g_nodeStack.push(this);
+
+ m_title = new DocTitle(this);
+ m_title->parseFromString(g_token->name);
+
+ QCString text = g_token->text;
+ docParserPushContext(); // this will create a new g_token
+ internalValidatingParseDoc(this,m_children,text);
+ docParserPopContext(); // this will restore the old g_token
+
+ DBG(("DocSimpleSect::parseRcs()\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return RetVal_OK;
+}
+
+int DocSimpleSect::parseXml()
+{
+ DBG(("DocSimpleSect::parse() start\n"));
+ g_nodeStack.push(this);
+
+ int retval = RetVal_OK;
+ for (;;)
+ {
+ // add new paragraph as child
+ DocPara *par = new DocPara(this);
+ if (m_children.isEmpty())
+ {
+ par->markFirst();
+ }
+ else
+ {
+ ASSERT(m_children.getLast()->kind()==DocNode::Kind_Para);
+ ((DocPara *)m_children.getLast())->markLast(FALSE);
+ }
+ par->markLast();
+ m_children.append(par);
+
+ // parse the contents of the paragraph
+ retval = par->parse();
+ if (retval == 0) break;
+ if (retval == RetVal_CloseXml)
+ {
+ retval = RetVal_OK;
+ break;
+ }
+ }
+
+ DBG(("DocSimpleSect::parseXml() end retval=%d\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+void DocSimpleSect::appendLinkWord(const QCString &word)
+{
+ DocPara *p;
+ if (m_children.isEmpty() || m_children.getLast()->kind()!=DocNode::Kind_Para)
+ {
+ p = new DocPara(this);
+ m_children.append(p);
+ }
+ else
+ {
+ p = (DocPara *)m_children.getLast();
+
+ // Comma-seperate <seealso> links.
+ p->injectToken(TK_WORD,",");
+ p->injectToken(TK_WHITESPACE," ");
+ }
+
+ g_inSeeBlock=TRUE;
+ p->injectToken(TK_LNKWORD,word);
+ g_inSeeBlock=FALSE;
+}
+
+QCString DocSimpleSect::typeString() const
+{
+ switch (m_type)
+ {
+ case Unknown: break;
+ case See: return "see";
+ case Return: return "return";
+ case Author: // fall through
+ case Authors: return "author";
+ case Version: return "version";
+ case Since: return "since";
+ case Date: return "date";
+ case Note: return "note";
+ case Warning: return "warning";
+ case Pre: return "pre";
+ case Post: return "post";
+ case Copyright: return "copyright";
+ case Invar: return "invariant";
+ case Remark: return "remark";
+ case Attention: return "attention";
+ case User: return "user";
+ case Rcs: return "rcs";
+ }
+ return "unknown";
+}
+
+//--------------------------------------------------------------------------
+
+int DocParamList::parse(const QCString &cmdName)
+{
+ int retval=RetVal_OK;
+ DBG(("DocParamList::parse() start\n"));
+ g_nodeStack.push(this);
+ DocPara *par=0;
+
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ }
+ doctokenizerYYsetStateParam();
+ tok=doctokenizerYYlex();
+ while (tok==TK_WORD) /* there is a parameter name */
+ {
+ if (m_type==DocParamSect::Param)
+ {
+ int typeSeparator = g_token->name.find('#'); // explicit type position
+ if (typeSeparator!=-1)
+ {
+ handleParameterType(this,m_paramTypes,g_token->name.left(typeSeparator));
+ g_token->name = g_token->name.mid(typeSeparator+1);
+ g_hasParamCommand=TRUE;
+ checkArgumentName(g_token->name,TRUE);
+ ((DocParamSect*)parent())->m_hasTypeSpecifier=TRUE;
+ }
+ else
+ {
+ g_hasParamCommand=TRUE;
+ checkArgumentName(g_token->name,TRUE);
+ }
+ }
+ else if (m_type==DocParamSect::RetVal)
+ {
+ g_hasReturnCommand=TRUE;
+ checkArgumentName(g_token->name,FALSE);
+ }
+ //m_params.append(g_token->name);
+ handleLinkedWord(this,m_params);
+ tok=doctokenizerYYlex();
+ }
+ doctokenizerYYsetStatePara();
+ if (tok==0) /* premature end of comment block */
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s",qPrint(cmdName));
+ retval=0;
+ goto endparamlist;
+ }
+ ASSERT(tok==TK_WHITESPACE);
+
+ par = new DocPara(this);
+ m_paragraphs.append(par);
+ retval = par->parse();
+ par->markFirst();
+ par->markLast();
+
+endparamlist:
+ DBG(("DocParamList::parse() end retval=%d\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+int DocParamList::parseXml(const QCString ¶mName)
+{
+ int retval=RetVal_OK;
+ DBG(("DocParamList::parseXml() start\n"));
+ g_nodeStack.push(this);
+
+ g_token->name = paramName;
+ if (m_type==DocParamSect::Param)
+ {
+ g_hasParamCommand=TRUE;
+ checkArgumentName(g_token->name,TRUE);
+ }
+ else if (m_type==DocParamSect::RetVal)
+ {
+ g_hasReturnCommand=TRUE;
+ checkArgumentName(g_token->name,FALSE);
+ }
+
+ handleLinkedWord(this,m_params);
+
+ do
+ {
+ DocPara *par = new DocPara(this);
+ retval = par->parse();
+ if (par->isEmpty()) // avoid adding an empty paragraph for the whitespace
+ // after </para> and before </param>
+ {
+ delete par;
+ break;
+ }
+ else // append the paragraph to the list
+ {
+ if (m_paragraphs.isEmpty())
+ {
+ par->markFirst();
+ }
+ else
+ {
+ m_paragraphs.getLast()->markLast(FALSE);
+ }
+ par->markLast();
+ m_paragraphs.append(par);
+ }
+
+ if (retval == 0) break;
+
+ } while (retval==RetVal_CloseXml &&
+ Mappers::htmlTagMapper->map(g_token->name)!=XML_PARAM &&
+ Mappers::htmlTagMapper->map(g_token->name)!=XML_TYPEPARAM &&
+ Mappers::htmlTagMapper->map(g_token->name)!=XML_EXCEPTION);
+
+
+ if (retval==0) /* premature end of comment block */
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unterminated param or exception tag");
+ }
+ else
+ {
+ retval=RetVal_OK;
+ }
+
+
+ DBG(("DocParamList::parse() end retval=%d\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+int DocParamSect::parse(const QCString &cmdName,bool xmlContext, Direction d)
+{
+ int retval=RetVal_OK;
+ DBG(("DocParamSect::parse() start\n"));
+ g_nodeStack.push(this);
+
+ if (d!=Unspecified)
+ {
+ m_hasInOutSpecifier=TRUE;
+ }
+
+ DocParamList *pl = new DocParamList(this,m_type,d);
+ if (m_children.isEmpty())
+ {
+ pl->markFirst();
+ pl->markLast();
+ }
+ else
+ {
+ ASSERT(m_children.getLast()->kind()==DocNode::Kind_ParamList);
+ ((DocParamList *)m_children.getLast())->markLast(FALSE);
+ pl->markLast();
+ }
+ m_children.append(pl);
+ if (xmlContext)
+ {
+ retval = pl->parseXml(cmdName);
+ }
+ else
+ {
+ retval = pl->parse(cmdName);
+ }
+ if (retval==RetVal_EndParBlock)
+ {
+ retval = RetVal_OK;
+ }
+
+ DBG(("DocParamSect::parse() end retval=%d\n",retval));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+int DocPara::handleSimpleSection(DocSimpleSect::Type t, bool xmlContext)
+{
+ DocSimpleSect *ss=0;
+ bool needsSeparator = FALSE;
+ if (!m_children.isEmpty() && // previous element
+ m_children.getLast()->kind()==Kind_SimpleSect && // was a simple sect
+ ((DocSimpleSect *)m_children.getLast())->type()==t && // of same type
+ t!=DocSimpleSect::User) // but not user defined
+ {
+ // append to previous section
+ ss=(DocSimpleSect *)m_children.getLast();
+ needsSeparator = TRUE;
+ }
+ else // start new section
+ {
+ ss=new DocSimpleSect(this,t);
+ m_children.append(ss);
+ }
+ int rv = RetVal_OK;
+ if (xmlContext)
+ {
+ return ss->parseXml();
+ }
+ else
+ {
+ rv = ss->parse(t==DocSimpleSect::User,needsSeparator);
+ }
+ return (rv!=TK_NEWPARA) ? rv : RetVal_OK;
+}
+
+int DocPara::handleParamSection(const QCString &cmdName,
+ DocParamSect::Type t,
+ bool xmlContext=FALSE,
+ int direction=DocParamSect::Unspecified)
+{
+ DocParamSect *ps=0;
+ if (!m_children.isEmpty() && // previous element
+ m_children.getLast()->kind()==Kind_ParamSect && // was a param sect
+ ((DocParamSect *)m_children.getLast())->type()==t) // of same type
+ {
+ // append to previous section
+ ps=(DocParamSect *)m_children.getLast();
+ }
+ else // start new section
+ {
+ ps=new DocParamSect(this,t);
+ m_children.append(ps);
+ }
+ int rv=ps->parse(cmdName,xmlContext,(DocParamSect::Direction)direction);
+ return (rv!=TK_NEWPARA) ? rv : RetVal_OK;
+}
+
+void DocPara::handleCite()
+{
+ // get the argument of the cite command.
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint("cite"));
+ return;
+ }
+ doctokenizerYYsetStateCite();
+ tok=doctokenizerYYlex();
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s\n", qPrint("cite"));
+ return;
+ }
+ else if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint("cite"));
+ return;
+ }
+ g_token->sectionId = g_token->name;
+ DocCite *cite = new DocCite(this,g_token->name,g_context);
+ m_children.append(cite);
+ //cite->parse();
+
+ doctokenizerYYsetStatePara();
+}
+
+int DocPara::handleXRefItem()
+{
+ int retval=doctokenizerYYlex();
+ ASSERT(retval==TK_WHITESPACE);
+ doctokenizerYYsetStateXRefItem();
+ retval=doctokenizerYYlex();
+ if (retval==RetVal_OK)
+ {
+ DocXRefItem *ref = new DocXRefItem(this,g_token->id,g_token->name);
+ if (ref->parse())
+ {
+ m_children.append(ref);
+ }
+ else
+ {
+ delete ref;
+ }
+ }
+ doctokenizerYYsetStatePara();
+ return retval;
+}
+
+void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t)
+{
+ DBG(("handleIncludeOperator(%s)\n",qPrint(cmdName)));
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStatePattern();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s", qPrint(cmdName));
+ return;
+ }
+ else if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ DocIncOperator *op = new DocIncOperator(this,t,g_token->name,g_context,g_isExample,g_exampleName);
+ QListIterator<DocNode> it(m_children);
+ DocNode *n1 = it.toLast();
+ --it;
+ DocNode *n2 = n1!=0 ? it.current() : 0;
+ bool isFirst = n1==0 || // no last node
+ (n1->kind()!=DocNode::Kind_IncOperator &&
+ n1->kind()!=DocNode::Kind_WhiteSpace
+ ) || // last node is not operator or whitespace
+ (n1->kind()==DocNode::Kind_WhiteSpace &&
+ n2!=0 && n2->kind()!=DocNode::Kind_IncOperator
+ ); // previous not is not operator
+ op->markFirst(isFirst);
+ op->markLast(TRUE);
+ if (n1!=0 && n1->kind()==DocNode::Kind_IncOperator)
+ {
+ ((DocIncOperator *)n1)->markLast(FALSE);
+ }
+ else if (n1!=0 && n1->kind()==DocNode::Kind_WhiteSpace &&
+ n2!=0 && n2->kind()==DocNode::Kind_IncOperator
+ )
+ {
+ ((DocIncOperator *)n2)->markLast(FALSE);
+ }
+ m_children.append(op);
+ op->parse();
+}
+
+void DocPara::handleImage(const QCString &cmdName)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ tok=doctokenizerYYlex();
+ if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ DocImage::Type t;
+ QCString imgType = g_token->name.lower();
+ if (imgType=="html") t=DocImage::Html;
+ else if (imgType=="latex") t=DocImage::Latex;
+ else if (imgType=="docbook") t=DocImage::DocBook;
+ else if (imgType=="rtf") t=DocImage::Rtf;
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"image type %s specified as the first argument of "
+ "%s is not valid",
+ qPrint(imgType),qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateFile();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ HtmlAttribList attrList;
+ DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t);
+ m_children.append(img);
+ img->parse();
+}
+
+void DocPara::handleDotFile(const QCString &cmdName)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateFile();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ QCString name = g_token->name;
+ DocDotFile *df = new DocDotFile(this,name,g_context);
+ m_children.append(df);
+ df->parse();
+}
+
+void DocPara::handleMscFile(const QCString &cmdName)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateFile();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ QCString name = g_token->name;
+ DocMscFile *df = new DocMscFile(this,name,g_context);
+ m_children.append(df);
+ df->parse();
+}
+
+void DocPara::handleDiaFile(const QCString &cmdName)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateFile();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ QCString name = g_token->name;
+ DocDiaFile *df = new DocDiaFile(this,name,g_context);
+ m_children.append(df);
+ df->parse();
+}
+
+void DocPara::handleVhdlFlow()
+{
+ DocVhdlFlow *vf = new DocVhdlFlow(this);
+ m_children.append(vf);
+ vf->parse();
+}
+
+void DocPara::handleLink(const QCString &cmdName,bool isJavaLink)
+{
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateLink();
+ tok=doctokenizerYYlex();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"%s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStatePara();
+ DocLink *lnk = new DocLink(this,g_token->name);
+ m_children.append(lnk);
+ QCString leftOver = lnk->parse(isJavaLink);
+ if (!leftOver.isEmpty())
+ {
+ m_children.append(new DocWord(this,leftOver));
+ }
+}
+
+void DocPara::handleRef(const QCString &cmdName)
+{
+ DBG(("handleRef(%s)\n",qPrint(cmdName)));
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateRef();
+ tok=doctokenizerYYlex(); // get the reference id
+ DocRef *ref=0;
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ goto endref;
+ }
+ ref = new DocRef(this,g_token->name,g_context);
+ m_children.append(ref);
+ ref->parse();
+endref:
+ doctokenizerYYsetStatePara();
+}
+
+
+void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t)
+{
+ DBG(("handleInclude(%s)\n",qPrint(cmdName)));
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ doctokenizerYYsetStateFile();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s",qPrint(cmdName));
+ return;
+ }
+ else if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ QCString fileName = g_token->name;
+ QCString blockId;
+ if (t==DocInclude::Snippet)
+ {
+ doctokenizerYYsetStateSnippet();
+ tok=doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+ if (tok!=TK_WORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected block identifier, but found token %s instead while parsing the %s command",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ blockId = "["+g_token->name+"]";
+ }
+ DocInclude *inc = new DocInclude(this,fileName,g_context,t,g_isExample,g_exampleName,blockId);
+ m_children.append(inc);
+ inc->parse();
+}
+
+void DocPara::handleSection(const QCString &cmdName)
+{
+ // get the argument of the section command.
+ int tok=doctokenizerYYlex();
+ if (tok!=TK_WHITESPACE)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ qPrint(cmdName));
+ return;
+ }
+ tok=doctokenizerYYlex();
+ if (tok==0)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the "
+ "argument of command %s\n", qPrint(cmdName));
+ return;
+ }
+ else if (tok!=TK_WORD && tok!=TK_LNKWORD)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ tokToString(tok),qPrint(cmdName));
+ return;
+ }
+ g_token->sectionId = g_token->name;
+ doctokenizerYYsetStateSkipTitle();
+ doctokenizerYYlex();
+ doctokenizerYYsetStatePara();
+}
+
+int DocPara::handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level)
+{
+ DocHtmlHeader *header = new DocHtmlHeader(this,tagHtmlAttribs,level);
+ m_children.append(header);
+ int retval = header->parse();
+ return (retval==RetVal_OK) ? TK_NEWPARA : retval;
+}
+
+// For XML tags whose content is stored in attributes rather than
+// contained within the element, we need a way to inject the attribute
+// text into the current paragraph.
+bool DocPara::injectToken(int tok,const QCString &tokText)
+{
+ g_token->name = tokText;
+ return defaultHandleToken(this,tok,m_children);
+}
+
+int DocPara::handleStartCode()
+{
+ int retval = doctokenizerYYlex();
+ QCString lang = g_token->name;
+ if (!lang.isEmpty() && lang.at(0)!='.')
+ {
+ lang="."+lang;
+ }
+ // search for the first non-whitespace line, index is stored in li
+ int i=0,li=0,l=g_token->verb.length();
+ while (i<l && (g_token->verb.at(i)==' ' || g_token->verb.at(i)=='\n'))
+ {
+ if (g_token->verb.at(i)=='\n') li=i+1;
+ i++;
+ }
+ m_children.append(new DocVerbatim(this,g_context,stripIndentation(g_token->verb.mid(li)),DocVerbatim::Code,g_isExample,g_exampleName,FALSE,lang));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"code section ended without end marker");
+ doctokenizerYYsetStatePara();
+ return retval;
+}
+
+void DocPara::handleInheritDoc()
+{
+ if (g_memberDef) // inheriting docs from a member
+ {
+ MemberDef *reMd = g_memberDef->reimplements();
+ if (reMd) // member from which was inherited.
+ {
+ MemberDef *thisMd = g_memberDef;
+ //printf("{InheritDocs:%s=>%s}\n",g_memberDef->qualifiedName().data(),reMd->qualifiedName().data());
+ docParserPushContext();
+ g_scope=reMd->getOuterScope();
+ if (g_scope!=Doxygen::globalScope)
+ {
+ g_context=g_scope->name();
+ }
+ g_memberDef=reMd;
+ g_styleStack.clear();
+ g_nodeStack.clear();
+ g_copyStack.append(reMd);
+ internalValidatingParseDoc(this,m_children,reMd->briefDescription());
+ internalValidatingParseDoc(this,m_children,reMd->documentation());
+ g_copyStack.remove(reMd);
+ docParserPopContext(TRUE);
+ g_memberDef = thisMd;
+ }
+ }
+}
+
+
+int DocPara::handleCommand(const QCString &cmdName)
+{
+ DBG(("handleCommand(%s)\n",qPrint(cmdName)));
+ int retval = RetVal_OK;
+ int cmdId = Mappers::cmdMapper->map(cmdName);
+ switch (cmdId)
+ {
+ case CMD_UNKNOWN:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command `\\%s'",qPrint(cmdName));
+ break;
+ case CMD_EMPHASIS:
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE));
+ retval=handleStyleArgument(this,m_children,cmdName);
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,FALSE));
+ if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));
+ break;
+ case CMD_BOLD:
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE));
+ retval=handleStyleArgument(this,m_children,cmdName);
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE));
+ if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));
+ break;
+ case CMD_CODE:
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,TRUE));
+ retval=handleStyleArgument(this,m_children,cmdName);
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,FALSE));
+ if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));
+ break;
+ case CMD_BSLASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_BSlash));
+ break;
+ case CMD_AT:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_At));
+ break;
+ case CMD_LESS:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Less));
+ break;
+ case CMD_GREATER:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Greater));
+ break;
+ case CMD_AMP:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Amp));
+ break;
+ case CMD_DOLLAR:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Dollar));
+ break;
+ case CMD_HASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Hash));
+ break;
+ case CMD_PIPE:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Pipe));
+ break;
+ case CMD_DCOLON:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_DoubleColon));
+ break;
+ case CMD_PERCENT:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Percent));
+ break;
+ case CMD_NDASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ break;
+ case CMD_MDASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ break;
+ case CMD_QUOTE:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Quot));
+ break;
+ case CMD_SA:
+ g_inSeeBlock=TRUE;
+ retval = handleSimpleSection(DocSimpleSect::See);
+ g_inSeeBlock=FALSE;
+ break;
+ case CMD_RETURN:
+ retval = handleSimpleSection(DocSimpleSect::Return);
+ g_hasReturnCommand=TRUE;
+ break;
+ case CMD_AUTHOR:
+ retval = handleSimpleSection(DocSimpleSect::Author);
+ break;
+ case CMD_AUTHORS:
+ retval = handleSimpleSection(DocSimpleSect::Authors);
+ break;
+ case CMD_VERSION:
+ retval = handleSimpleSection(DocSimpleSect::Version);
+ break;
+ case CMD_SINCE:
+ retval = handleSimpleSection(DocSimpleSect::Since);
+ break;
+ case CMD_DATE:
+ retval = handleSimpleSection(DocSimpleSect::Date);
+ break;
+ case CMD_NOTE:
+ retval = handleSimpleSection(DocSimpleSect::Note);
+ break;
+ case CMD_WARNING:
+ retval = handleSimpleSection(DocSimpleSect::Warning);
+ break;
+ case CMD_PRE:
+ retval = handleSimpleSection(DocSimpleSect::Pre);
+ break;
+ case CMD_POST:
+ retval = handleSimpleSection(DocSimpleSect::Post);
+ break;
+ case CMD_COPYRIGHT:
+ retval = handleSimpleSection(DocSimpleSect::Copyright);
+ break;
+ case CMD_INVARIANT:
+ retval = handleSimpleSection(DocSimpleSect::Invar);
+ break;
+ case CMD_REMARK:
+ retval = handleSimpleSection(DocSimpleSect::Remark);
+ break;
+ case CMD_ATTENTION:
+ retval = handleSimpleSection(DocSimpleSect::Attention);
+ break;
+ case CMD_PAR:
+ retval = handleSimpleSection(DocSimpleSect::User);
+ break;
+ case CMD_LI:
+ {
+ DocSimpleList *sl=new DocSimpleList(this);
+ m_children.append(sl);
+ retval = sl->parse();
+ }
+ break;
+ case CMD_SECTION:
+ {
+ handleSection(cmdName);
+ retval = RetVal_Section;
+ }
+ break;
+ case CMD_SUBSECTION:
+ {
+ handleSection(cmdName);
+ retval = RetVal_Subsection;
+ }
+ break;
+ case CMD_SUBSUBSECTION:
+ {
+ handleSection(cmdName);
+ retval = RetVal_Subsubsection;
+ }
+ break;
+ case CMD_PARAGRAPH:
+ {
+ handleSection(cmdName);
+ retval = RetVal_Paragraph;
+ }
+ break;
+ case CMD_STARTCODE:
+ {
+ doctokenizerYYsetStateCode();
+ retval = handleStartCode();
+ }
+ break;
+ case CMD_HTMLONLY:
+ {
+ doctokenizerYYsetStateHtmlOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName,g_token->name=="block"));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"htmlonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_MANONLY:
+ {
+ doctokenizerYYsetStateManOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"manonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_RTFONLY:
+ {
+ doctokenizerYYsetStateRtfOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::RtfOnly,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"rtfonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_LATEXONLY:
+ {
+ doctokenizerYYsetStateLatexOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_XMLONLY:
+ {
+ doctokenizerYYsetStateXmlOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_DBONLY:
+ {
+ doctokenizerYYsetStateDbOnly();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker",doctokenizerYYlineno);
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_VERBATIM:
+ {
+ doctokenizerYYsetStateVerbatim();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Verbatim,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"verbatim section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_DOT:
+ {
+ doctokenizerYYsetStateDot();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Dot,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"dot section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_MSC:
+ {
+ doctokenizerYYsetStateMsc();
+ retval = doctokenizerYYlex();
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Msc,g_isExample,g_exampleName));
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"msc section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_STARTUML:
+ {
+ static QCString jarPath = Config_getString("PLANTUML_JAR_PATH");
+ doctokenizerYYsetStatePlantUML();
+ retval = doctokenizerYYlex();
+ if (jarPath.isEmpty())
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"ignoring startuml command because PLANTUML_JAR_PATH is not set");
+ }
+ else
+ {
+ m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::PlantUML,FALSE,g_token->sectionId));
+ }
+ if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"startuml section ended without end marker");
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_ENDPARBLOCK:
+ retval=RetVal_EndParBlock;
+ break;
+ case CMD_ENDCODE:
+ case CMD_ENDHTMLONLY:
+ case CMD_ENDMANONLY:
+ case CMD_ENDRTFONLY:
+ case CMD_ENDLATEXONLY:
+ case CMD_ENDXMLONLY:
+ case CMD_ENDDBONLY:
+ case CMD_ENDLINK:
+ case CMD_ENDVERBATIM:
+ case CMD_ENDDOT:
+ case CMD_ENDMSC:
+ case CMD_ENDUML:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name));
+ break;
+ case CMD_PARAM:
+ retval = handleParamSection(cmdName,DocParamSect::Param,FALSE,g_token->paramDir);
+ break;
+ case CMD_TPARAM:
+ retval = handleParamSection(cmdName,DocParamSect::TemplateParam,FALSE,g_token->paramDir);
+ break;
+ case CMD_RETVAL:
+ retval = handleParamSection(cmdName,DocParamSect::RetVal);
+ break;
+ case CMD_EXCEPTION:
+ retval = handleParamSection(cmdName,DocParamSect::Exception);
+ break;
+ case CMD_XREFITEM:
+ retval = handleXRefItem();
+ break;
+ case CMD_LINEBREAK:
+ {
+ DocLineBreak *lb = new DocLineBreak(this);
+ m_children.append(lb);
+ }
+ break;
+ case CMD_ANCHOR:
+ {
+ DocAnchor *anchor = handleAnchor(this);
+ if (anchor)
+ {
+ m_children.append(anchor);
+ }
+ }
+ break;
+ case CMD_ADDINDEX:
+ {
+ DocIndexEntry *ie = new DocIndexEntry(this,
+ g_scope!=Doxygen::globalScope?g_scope:0,
+ g_memberDef);
+ m_children.append(ie);
+ retval = ie->parse();
+ }
+ break;
+ case CMD_INTERNAL:
+ retval = RetVal_Internal;
+ break;
+ case CMD_ENDINTERNAL:
+ retval = RetVal_EndInternal;
+ break;
+ case CMD_PARBLOCK:
+ {
+ DocParBlock *block = new DocParBlock(this);
+ m_children.append(block);
+ retval = block->parse();
+ }
+ break;
+ case CMD_COPYDOC: // fall through
+ case CMD_COPYBRIEF: // fall through
+ case CMD_COPYDETAILS:
+ //retval = RetVal_CopyDoc;
+ // these commands should already be resolved by processCopyDoc()
+ break;
+ case CMD_INCLUDE:
+ handleInclude(cmdName,DocInclude::Include);
+ break;
+ case CMD_INCWITHLINES:
+ handleInclude(cmdName,DocInclude::IncWithLines);
+ break;
+ case CMD_DONTINCLUDE:
+ handleInclude(cmdName,DocInclude::DontInclude);
+ break;
+ case CMD_HTMLINCLUDE:
+ handleInclude(cmdName,DocInclude::HtmlInclude);
+ break;
+ case CMD_LATEXINCLUDE:
+ handleInclude(cmdName,DocInclude::LatexInclude);
+ break;
+ case CMD_VERBINCLUDE:
+ handleInclude(cmdName,DocInclude::VerbInclude);
+ break;
+ case CMD_SNIPPET:
+ handleInclude(cmdName,DocInclude::Snippet);
+ break;
+ case CMD_SKIP:
+ handleIncludeOperator(cmdName,DocIncOperator::Skip);
+ break;
+ case CMD_UNTIL:
+ handleIncludeOperator(cmdName,DocIncOperator::Until);
+ break;
+ case CMD_SKIPLINE:
+ handleIncludeOperator(cmdName,DocIncOperator::SkipLine);
+ break;
+ case CMD_LINE:
+ handleIncludeOperator(cmdName,DocIncOperator::Line);
+ break;
+ case CMD_IMAGE:
+ handleImage(cmdName);
+ break;
+ case CMD_DOTFILE:
+ handleDotFile(cmdName);
+ break;
+ case CMD_VHDLFLOW:
+ handleVhdlFlow();
+ break;
+ case CMD_MSCFILE:
+ handleMscFile(cmdName);
+ break;
+ case CMD_DIAFILE:
+ handleDiaFile(cmdName);
+ break;
+ case CMD_LINK:
+ handleLink(cmdName,FALSE);
+ break;
+ case CMD_JAVALINK:
+ handleLink(cmdName,TRUE);
+ break;
+ case CMD_CITE:
+ handleCite();
+ break;
+ case CMD_REF: // fall through
+ case CMD_SUBPAGE:
+ handleRef(cmdName);
+ break;
+ case CMD_SECREFLIST:
+ {
+ DocSecRefList *list = new DocSecRefList(this);
+ m_children.append(list);
+ list->parse();
+ }
+ break;
+ case CMD_SECREFITEM:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name));
+ break;
+ case CMD_ENDSECREFLIST:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name));
+ break;
+ case CMD_FORMULA:
+ {
+ DocFormula *form=new DocFormula(this,g_token->id);
+ m_children.append(form);
+ }
+ break;
+ //case CMD_LANGSWITCH:
+ // retval = handleLanguageSwitch();
+ // break;
+ case CMD_INTERNALREF:
+ //warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name));
+ {
+ DocInternalRef *ref = handleInternalRef(this);
+ if (ref)
+ {
+ m_children.append(ref);
+ ref->parse();
+ }
+ doctokenizerYYsetStatePara();
+ }
+ break;
+ case CMD_INHERITDOC:
+ handleInheritDoc();
+ break;
+ default:
+ // we should not get here!
+ ASSERT(0);
+ break;
+ }
+ INTERNAL_ASSERT(retval==0 || retval==RetVal_OK || retval==RetVal_SimpleSec ||
+ retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_NEWPARA ||
+ retval==RetVal_Section || retval==RetVal_EndList ||
+ retval==RetVal_Internal || retval==RetVal_SwitchLang ||
+ retval==RetVal_EndInternal
+ );
+ DBG(("handleCommand(%s) end retval=%x\n",qPrint(cmdName),retval));
+ return retval;
+}
+
+static bool findAttribute(const HtmlAttribList &tagHtmlAttribs,
+ const char *attrName,
+ QCString *result)
+{
+
+ HtmlAttribListIterator li(tagHtmlAttribs);
+ HtmlAttrib *opt;
+ for (li.toFirst();(opt=li.current());++li)
+ {
+ if (opt->name==attrName)
+ {
+ *result = opt->value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs)
+{
+ DBG(("handleHtmlStartTag(%s,%d)\n",qPrint(tagName),tagHtmlAttribs.count()));
+ int retval=RetVal_OK;
+ int tagId = Mappers::htmlTagMapper->map(tagName);
+ if (g_token->emptyTag && !(tagId&XML_CmdMask) &&
+ tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tags may not use the 'empty tag' XHTML syntax.");
+ }
+ switch (tagId)
+ {
+ case HTML_UL:
+ {
+ DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Unordered);
+ m_children.append(list);
+ retval=list->parse();
+ }
+ break;
+ case HTML_OL:
+ {
+ DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,DocHtmlList::Ordered);
+ m_children.append(list);
+ retval=list->parse();
+ }
+ break;
+ case HTML_LI:
+ if (!insideUL(this) && !insideOL(this))
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"lonely <li> tag found");
+ }
+ else
+ {
+ retval=RetVal_ListItem;
+ }
+ break;
+ case HTML_BOLD:
+ handleStyleEnter(this,m_children,DocStyleChange::Bold,&g_token->attribs);
+ break;
+ case HTML_CODE:
+ if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment)
+ // for C# source or inside a <summary> or <remark> section we
+ // treat <code> as an XML tag (so similar to @code)
+ {
+ doctokenizerYYsetStateXmlCode();
+ retval = handleStartCode();
+ }
+ else // normal HTML markup
+ {
+ handleStyleEnter(this,m_children,DocStyleChange::Code,&g_token->attribs);
+ }
+ break;
+ case HTML_EMPHASIS:
+ handleStyleEnter(this,m_children,DocStyleChange::Italic,&g_token->attribs);
+ break;
+ case HTML_DIV:
+ handleStyleEnter(this,m_children,DocStyleChange::Div,&g_token->attribs);
+ break;
+ case HTML_SPAN:
+ handleStyleEnter(this,m_children,DocStyleChange::Span,&g_token->attribs);
+ break;
+ case HTML_SUB:
+ handleStyleEnter(this,m_children,DocStyleChange::Subscript,&g_token->attribs);
+ break;
+ case HTML_SUP:
+ handleStyleEnter(this,m_children,DocStyleChange::Superscript,&g_token->attribs);
+ break;
+ case HTML_CENTER:
+ handleStyleEnter(this,m_children,DocStyleChange::Center,&g_token->attribs);
+ break;
+ case HTML_SMALL:
+ handleStyleEnter(this,m_children,DocStyleChange::Small,&g_token->attribs);
+ break;
+ case HTML_PRE:
+ handleStyleEnter(this,m_children,DocStyleChange::Preformatted,&g_token->attribs);
+ setInsidePreformatted(TRUE);
+ doctokenizerYYsetInsidePre(TRUE);
+ break;
+ case HTML_P:
+ retval=TK_NEWPARA;
+ break;
+ case HTML_DL:
+ {
+ DocHtmlDescList *list = new DocHtmlDescList(this,tagHtmlAttribs);
+ m_children.append(list);
+ retval=list->parse();
+ }
+ break;
+ case HTML_DT:
+ retval = RetVal_DescTitle;
+ break;
+ case HTML_DD:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag <dd> found");
+ break;
+ case HTML_TABLE:
+ {
+ DocHtmlTable *table = new DocHtmlTable(this,tagHtmlAttribs);
+ m_children.append(table);
+ retval=table->parse();
+ }
+ break;
+ case HTML_TR:
+ retval = RetVal_TableRow;
+ break;
+ case HTML_TD:
+ retval = RetVal_TableCell;
+ break;
+ case HTML_TH:
+ retval = RetVal_TableHCell;
+ break;
+ case HTML_CAPTION:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag <caption> found");
+ break;
+ case HTML_BR:
+ {
+ DocLineBreak *lb = new DocLineBreak(this);
+ m_children.append(lb);
+ }
+ break;
+ case HTML_HR:
+ {
+ DocHorRuler *hr = new DocHorRuler(this);
+ m_children.append(hr);
+ }
+ break;
+ case HTML_A:
+ retval=handleAHref(this,m_children,tagHtmlAttribs);
+ break;
+ case HTML_H1:
+ retval=handleHtmlHeader(tagHtmlAttribs,1);
+ break;
+ case HTML_H2:
+ retval=handleHtmlHeader(tagHtmlAttribs,2);
+ break;
+ case HTML_H3:
+ retval=handleHtmlHeader(tagHtmlAttribs,3);
+ break;
+ case HTML_H4:
+ retval=handleHtmlHeader(tagHtmlAttribs,4);
+ break;
+ case HTML_H5:
+ retval=handleHtmlHeader(tagHtmlAttribs,5);
+ break;
+ case HTML_H6:
+ retval=handleHtmlHeader(tagHtmlAttribs,6);
+ break;
+ case HTML_IMG:
+ {
+ handleImg(this,m_children,tagHtmlAttribs);
+ }
+ break;
+ case HTML_BLOCKQUOTE:
+ {
+ DocHtmlBlockQuote *block = new DocHtmlBlockQuote(this,tagHtmlAttribs);
+ m_children.append(block);
+ retval = block->parse();
+ }
+ break;
+
+ case XML_SUMMARY:
+ case XML_REMARKS:
+ g_xmlComment=TRUE;
+ // fall through
+ case XML_VALUE:
+ case XML_PARA:
+ if (!m_children.isEmpty())
+ {
+ retval = TK_NEWPARA;
+ }
+ break;
+ case XML_EXAMPLE:
+ case XML_DESCRIPTION:
+ if (insideTable(this))
+ {
+ retval=RetVal_TableCell;
+ }
+ break;
+ case XML_C:
+ handleStyleEnter(this,m_children,DocStyleChange::Code,&g_token->attribs);
+ break;
+ case XML_PARAM:
+ case XML_TYPEPARAM:
+ {
+ QCString paramName;
+ if (findAttribute(tagHtmlAttribs,"name",¶mName))
+ {
+ if (paramName.isEmpty())
+ {
+ if (Config_getBool("WARN_NO_PARAMDOC"))
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"empty 'name' attribute for <param> tag.");
+ }
+ }
+ else
+ {
+ retval = handleParamSection(paramName,
+ tagId==XML_PARAM ? DocParamSect::Param : DocParamSect::TemplateParam,
+ TRUE);
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'name' attribute from <param> tag.");
+ }
+ }
+ break;
+ case XML_PARAMREF:
+ case XML_TYPEPARAMREF:
+ {
+ QCString paramName;
+ if (findAttribute(tagHtmlAttribs,"name",¶mName))
+ {
+ //printf("paramName=%s\n",paramName.data());
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE));
+ m_children.append(new DocWord(this,paramName));
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,FALSE));
+ if (retval!=TK_WORD) m_children.append(new DocWhiteSpace(this," "));
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type");
+ }
+ }
+ break;
+ case XML_EXCEPTION:
+ {
+ QCString exceptName;
+ if (findAttribute(tagHtmlAttribs,"cref",&exceptName))
+ {
+ retval = handleParamSection(exceptName,DocParamSect::Exception,TRUE);
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'name' attribute from <exception> tag.");
+ }
+ }
+ break;
+ case XML_ITEM:
+ case XML_LISTHEADER:
+ if (insideTable(this))
+ {
+ retval=RetVal_TableRow;
+ }
+ else if (insideUL(this) || insideOL(this))
+ {
+ retval=RetVal_ListItem;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"lonely <item> tag found");
+ }
+ break;
+ case XML_RETURNS:
+ retval = handleSimpleSection(DocSimpleSect::Return,TRUE);
+ g_hasReturnCommand=TRUE;
+ break;
+ case XML_TERM:
+ //m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE));
+ if (insideTable(this))
+ {
+ retval=RetVal_TableCell;
+ }
+ break;
+ case XML_SEE:
+ // I'm not sure if <see> is the same as <seealso> or if it
+ // should you link a member without producing a section. The
+ // C# specification is extremely vague about this (but what else
+ // can we expect from Microsoft...)
+ {
+ QCString cref;
+ //printf("XML_SEE: empty tag=%d\n",g_token->emptyTag);
+ if (findAttribute(tagHtmlAttribs,"cref",&cref))
+ {
+ if (g_token->emptyTag) // <see cref="..."/> style
+ {
+ bool inSeeBlock = g_inSeeBlock;
+ g_token->name = cref;
+ g_inSeeBlock = TRUE;
+ handleLinkedWord(this,m_children);
+ g_inSeeBlock = inSeeBlock;
+ }
+ else // <see cref="...">...</see> style
+ {
+ //DocRef *ref = new DocRef(this,cref);
+ //m_children.append(ref);
+ //ref->parse();
+ doctokenizerYYsetStatePara();
+ DocLink *lnk = new DocLink(this,cref);
+ m_children.append(lnk);
+ QCString leftOver = lnk->parse(FALSE,TRUE);
+ if (!leftOver.isEmpty())
+ {
+ m_children.append(new DocWord(this,leftOver));
+ }
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'cref' attribute from <see> tag.");
+ }
+ }
+ break;
+ case XML_SEEALSO:
+ {
+ QCString cref;
+ if (findAttribute(tagHtmlAttribs,"cref",&cref))
+ {
+ // Look for an existing "see" section
+ DocSimpleSect *ss=0;
+ QListIterator<DocNode> cli(m_children);
+ DocNode *n;
+ for (cli.toFirst();(n=cli.current());++cli)
+ {
+ if (n->kind()==Kind_SimpleSect && ((DocSimpleSect *)n)->type()==DocSimpleSect::See)
+ {
+ ss = (DocSimpleSect *)n;
+ }
+ }
+
+ if (!ss) // start new section
+ {
+ ss=new DocSimpleSect(this,DocSimpleSect::See);
+ m_children.append(ss);
+ }
+
+ ss->appendLinkWord(cref);
+ retval = RetVal_OK;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'cref' attribute from <seealso> tag.");
+ }
+ }
+ break;
+ case XML_LIST:
+ {
+ QCString type;
+ findAttribute(tagHtmlAttribs,"type",&type);
+ DocHtmlList::Type listType = DocHtmlList::Unordered;
+ HtmlAttribList emptyList;
+ if (type=="number")
+ {
+ listType=DocHtmlList::Ordered;
+ }
+ if (type=="table")
+ {
+ DocHtmlTable *table = new DocHtmlTable(this,emptyList);
+ m_children.append(table);
+ retval=table->parseXml();
+ }
+ else
+ {
+ DocHtmlList *list = new DocHtmlList(this,emptyList,listType);
+ m_children.append(list);
+ retval=list->parseXml();
+ }
+ }
+ break;
+ case XML_INCLUDE:
+ case XML_PERMISSION:
+ // These tags are defined in .Net but are currently unsupported
+ break;
+ case HTML_UNKNOWN:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported xml/html tag <%s> found", qPrint(tagName));
+ m_children.append(new DocWord(this, "<"+tagName+tagHtmlAttribs.toString()+">"));
+ break;
+ case XML_INHERITDOC:
+ handleInheritDoc();
+ break;
+
+ default:
+ // we should not get here!
+ ASSERT(0);
+ break;
+ }
+ return retval;
+}
+
+int DocPara::handleHtmlEndTag(const QCString &tagName)
+{
+ DBG(("handleHtmlEndTag(%s)\n",qPrint(tagName)));
+ int tagId = Mappers::htmlTagMapper->map(tagName);
+ int retval=RetVal_OK;
+ switch (tagId)
+ {
+ case HTML_UL:
+ if (!insideUL(this))
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ul> tag without matching <ul>");
+ }
+ else
+ {
+ retval=RetVal_EndList;
+ }
+ break;
+ case HTML_OL:
+ if (!insideOL(this))
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ol> tag without matching <ol>");
+ }
+ else
+ {
+ retval=RetVal_EndList;
+ }
+ break;
+ case HTML_LI:
+ if (!insideLI(this))
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found </li> tag without matching <li>");
+ }
+ else
+ {
+ // ignore </li> tags
+ }
+ break;
+ case HTML_BLOCKQUOTE:
+ retval=RetVal_EndBlockQuote;
+ break;
+ //case HTML_PRE:
+ // if (!insidePRE(this))
+ // {
+ // warn_doc_error(g_fileName,doctokenizerYYlineno,"found </pre> tag without matching <pre>");
+ // }
+ // else
+ // {
+ // retval=RetVal_EndPre;
+ // }
+ // break;
+ case HTML_BOLD:
+ handleStyleLeave(this,m_children,DocStyleChange::Bold,"b");
+ break;
+ case HTML_CODE:
+ handleStyleLeave(this,m_children,DocStyleChange::Code,"code");
+ break;
+ case HTML_EMPHASIS:
+ handleStyleLeave(this,m_children,DocStyleChange::Italic,"em");
+ break;
+ case HTML_DIV:
+ handleStyleLeave(this,m_children,DocStyleChange::Div,"div");
+ break;
+ case HTML_SPAN:
+ handleStyleLeave(this,m_children,DocStyleChange::Span,"span");
+ break;
+ case HTML_SUB:
+ handleStyleLeave(this,m_children,DocStyleChange::Subscript,"sub");
+ break;
+ case HTML_SUP:
+ handleStyleLeave(this,m_children,DocStyleChange::Superscript,"sup");
+ break;
+ case HTML_CENTER:
+ handleStyleLeave(this,m_children,DocStyleChange::Center,"center");
+ break;
+ case HTML_SMALL:
+ handleStyleLeave(this,m_children,DocStyleChange::Small,"small");
+ break;
+ case HTML_PRE:
+ handleStyleLeave(this,m_children,DocStyleChange::Preformatted,"pre");
+ setInsidePreformatted(FALSE);
+ doctokenizerYYsetInsidePre(FALSE);
+ break;
+ case HTML_P:
+ retval=TK_NEWPARA;
+ break;
+ case HTML_DL:
+ retval=RetVal_EndDesc;
+ break;
+ case HTML_DT:
+ // ignore </dt> tag
+ break;
+ case HTML_DD:
+ // ignore </dd> tag
+ break;
+ case HTML_TABLE:
+ retval=RetVal_EndTable;
+ break;
+ case HTML_TR:
+ // ignore </tr> tag
+ break;
+ case HTML_TD:
+ // ignore </td> tag
+ break;
+ case HTML_TH:
+ // ignore </th> tag
+ break;
+ case HTML_CAPTION:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </caption> found");
+ break;
+ case HTML_BR:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal </br> tag found\n");
+ break;
+ case HTML_H1:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h1> found");
+ break;
+ case HTML_H2:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h2> found");
+ break;
+ case HTML_H3:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h3> found");
+ break;
+ case HTML_H4:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h4> found");
+ break;
+ case HTML_H5:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h5> found");
+ break;
+ case HTML_H6:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h6> found");
+ break;
+ case HTML_IMG:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </img> found");
+ break;
+ case HTML_HR:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </hr> found");
+ break;
+ case HTML_A:
+ //warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </a> found");
+ // ignore </a> tag (can be part of <a name=...></a>
+ break;
+
+ case XML_TERM:
+ //m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE));
+ break;
+ case XML_SUMMARY:
+ case XML_REMARKS:
+ case XML_PARA:
+ case XML_VALUE:
+ case XML_LIST:
+ case XML_EXAMPLE:
+ case XML_PARAM:
+ case XML_TYPEPARAM:
+ case XML_RETURNS:
+ case XML_SEE:
+ case XML_SEEALSO:
+ case XML_EXCEPTION:
+ case XML_INHERITDOC:
+ retval = RetVal_CloseXml;
+ break;
+ case XML_C:
+ handleStyleLeave(this,m_children,DocStyleChange::Code,"c");
+ break;
+ case XML_ITEM:
+ case XML_LISTHEADER:
+ case XML_INCLUDE:
+ case XML_PERMISSION:
+ case XML_DESCRIPTION:
+ case XML_PARAMREF:
+ case XML_TYPEPARAMREF:
+ // These tags are defined in .Net but are currently unsupported
+ break;
+ case HTML_UNKNOWN:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported xml/html tag </%s> found", qPrint(tagName));
+ m_children.append(new DocWord(this,"</"+tagName+">"));
+ break;
+ default:
+ // we should not get here!
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end tag %s\n",qPrint(tagName));
+ ASSERT(0);
+ break;
+ }
+ return retval;
+}
+
+int DocPara::parse()
+{
+ DBG(("DocPara::parse() start\n"));
+ g_nodeStack.push(this);
+ // handle style commands "inherited" from the previous paragraph
+ handleInitialStyleCommands(this,m_children);
+ int tok;
+ int retval=0;
+ while ((tok=doctokenizerYYlex())) // get the next token
+ {
+reparsetoken:
+ DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));
+ if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL ||
+ tok==TK_COMMAND || tok==TK_HTMLTAG
+ )
+ {
+ DBG((" name=%s",qPrint(g_token->name)));
+ }
+ DBG(("\n"));
+ switch(tok)
+ {
+ case TK_WORD:
+ m_children.append(new DocWord(this,g_token->name));
+ break;
+ case TK_LNKWORD:
+ handleLinkedWord(this,m_children);
+ break;
+ case TK_URL:
+ m_children.append(new DocURL(this,g_token->name,g_token->isEMailAddr));
+ break;
+ case TK_WHITESPACE:
+ {
+ // prevent leading whitespace and collapse multiple whitespace areas
+ DocNode::Kind k;
+ if (insidePRE(this) || // all whitespace is relevant
+ (
+ // remove leading whitespace
+ !m_children.isEmpty() &&
+ // and whitespace after certain constructs
+ (k=m_children.getLast()->kind())!=DocNode::Kind_HtmlDescList &&
+ k!=DocNode::Kind_HtmlTable &&
+ k!=DocNode::Kind_HtmlList &&
+ k!=DocNode::Kind_SimpleSect &&
+ k!=DocNode::Kind_AutoList &&
+ k!=DocNode::Kind_SimpleList &&
+ /*k!=DocNode::Kind_Verbatim &&*/
+ k!=DocNode::Kind_HtmlHeader &&
+ k!=DocNode::Kind_HtmlBlockQuote &&
+ k!=DocNode::Kind_ParamSect &&
+ k!=DocNode::Kind_XRefItem
+ )
+ )
+ {
+ m_children.append(new DocWhiteSpace(this,g_token->chars));
+ }
+ }
+ break;
+ case TK_LISTITEM:
+ {
+ DBG(("found list item at %d parent=%d\n",g_token->indent,parent()->kind()));
+ DocNode *n=parent();
+ while (n && n->kind()!=DocNode::Kind_AutoList) n=n->parent();
+ if (n) // we found an auto list up in the hierarchy
+ {
+ DocAutoList *al = (DocAutoList *)n;
+ DBG(("previous list item at %d\n",al->indent()));
+ if (al->indent()>=g_token->indent)
+ // new item at the same or lower indent level
+ {
+ retval=TK_LISTITEM;
+ goto endparagraph;
+ }
+ }
+
+ // determine list depth
+ int depth = 0;
+ n=parent();
+ while(n)
+ {
+ if (n->kind() == DocNode::Kind_AutoList &&
+ ((DocAutoList*)n)->isEnumList()) depth++;
+ n=n->parent();
+ }
+
+ // first item or sub list => create new list
+ DocAutoList *al=0;
+ do
+ {
+ al = new DocAutoList(this,g_token->indent,
+ g_token->isEnumList,depth);
+ m_children.append(al);
+ retval = al->parse();
+ } while (retval==TK_LISTITEM && // new list
+ al->indent()==g_token->indent // at same indent level
+ );
+
+ // check the return value
+ if (retval==RetVal_SimpleSec) // auto list ended due to simple section command
+ {
+ // Reparse the token that ended the section at this level,
+ // so a new simple section will be started at this level.
+ // This is the same as unputting the last read token and continuing.
+ g_token->name = g_token->simpleSectName;
+ if (g_token->name.left(4)=="rcs:") // RCS section
+ {
+ g_token->name = g_token->name.mid(4);
+ g_token->text = g_token->simpleSectText;
+ tok = TK_RCSTAG;
+ }
+ else // other section
+ {
+ tok = TK_COMMAND;
+ }
+ DBG(("reparsing command %s\n",qPrint(g_token->name)));
+ goto reparsetoken;
+ }
+ else if (retval==TK_ENDLIST)
+ {
+ if (al->indent()>g_token->indent) // end list
+ {
+ goto endparagraph;
+ }
+ else // continue with current paragraph
+ {
+ }
+ }
+ else // paragraph ended due to TK_NEWPARA, TK_LISTITEM, or EOF
+ {
+ goto endparagraph;
+ }
+ }
+ break;
+ case TK_ENDLIST:
+ DBG(("Found end of list inside of paragraph at line %d\n",doctokenizerYYlineno));
+ if (parent()->kind()==DocNode::Kind_AutoListItem)
+ {
+ ASSERT(parent()->parent()->kind()==DocNode::Kind_AutoList);
+ DocAutoList *al = (DocAutoList *)parent()->parent();
+ if (al->indent()>=g_token->indent)
+ {
+ // end of list marker ends this paragraph
+ retval=TK_ENDLIST;
+ goto endparagraph;
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"End of list marker found "
+ "has invalid indent level");
+ }
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"End of list marker found without any preceding "
+ "list items");
+ }
+ break;
+ case TK_COMMAND:
+ {
+ // see if we have to start a simple section
+ int cmd = Mappers::cmdMapper->map(g_token->name);
+ DocNode *n=parent();
+ while (n &&
+ n->kind()!=DocNode::Kind_SimpleSect &&
+ n->kind()!=DocNode::Kind_ParamSect
+ )
+ {
+ n=n->parent();
+ }
+ if (cmd&SIMPLESECT_BIT)
+ {
+ if (n) // already in a simple section
+ {
+ // simple section cannot start in this paragraph, need
+ // to unwind the stack and remember the command.
+ g_token->simpleSectName = g_token->name.copy();
+ retval=RetVal_SimpleSec;
+ goto endparagraph;
+ }
+ }
+ // see if we are in a simple list
+ n=parent();
+ while (n && n->kind()!=DocNode::Kind_SimpleListItem) n=n->parent();
+ if (n)
+ {
+ if (cmd==CMD_LI)
+ {
+ retval=RetVal_ListItem;
+ goto endparagraph;
+ }
+ }
+
+ // handle the command
+ retval=handleCommand(g_token->name);
+ DBG(("handleCommand returns %x\n",retval));
+
+ // check the return value
+ if (retval==RetVal_SimpleSec)
+ {
+ // Reparse the token that ended the section at this level,
+ // so a new simple section will be started at this level.
+ // This is the same as unputting the last read token and continuing.
+ g_token->name = g_token->simpleSectName;
+ if (g_token->name.left(4)=="rcs:") // RCS section
+ {
+ g_token->name = g_token->name.mid(4);
+ g_token->text = g_token->simpleSectText;
+ tok = TK_RCSTAG;
+ }
+ else // other section
+ {
+ tok = TK_COMMAND;
+ }
+ DBG(("reparsing command %s\n",qPrint(g_token->name)));
+ goto reparsetoken;
+ }
+ else if (retval==RetVal_OK)
+ {
+ // the command ended normally, keep scanning for new tokens.
+ retval = 0;
+ }
+ else if (retval>0 && retval<RetVal_OK)
+ {
+ // the command ended with a new command, reparse this token
+ tok = retval;
+ goto reparsetoken;
+ }
+ else // end of file, end of paragraph, start or end of section
+ // or some auto list marker
+ {
+ goto endparagraph;
+ }
+ }
+ break;
+ case TK_HTMLTAG:
+ {
+ if (!g_token->endTag) // found a start tag
+ {
+ retval = handleHtmlStartTag(g_token->name,g_token->attribs);
+ }
+ else // found an end tag
+ {
+ retval = handleHtmlEndTag(g_token->name);
+ }
+ if (retval==RetVal_OK)
+ {
+ // the command ended normally, keep scanner for new tokens.
+ retval = 0;
+ }
+ else
+ {
+ goto endparagraph;
+ }
+ }
+ break;
+ case TK_SYMBOL:
+ {
+ DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name);
+ if (s!=DocSymbol::Sym_Unknown)
+ {
+ m_children.append(new DocSymbol(this,s));
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ }
+ break;
+ }
+ case TK_NEWPARA:
+ retval=TK_NEWPARA;
+ goto endparagraph;
+ case TK_RCSTAG:
+ {
+ DocNode *n=parent();
+ while (n &&
+ n->kind()!=DocNode::Kind_SimpleSect &&
+ n->kind()!=DocNode::Kind_ParamSect
+ )
+ {
+ n=n->parent();
+ }
+ if (n) // already in a simple section
+ {
+ // simple section cannot start in this paragraph, need
+ // to unwind the stack and remember the command.
+ g_token->simpleSectName = "rcs:"+g_token->name;
+ g_token->simpleSectText = g_token->text;
+ retval=RetVal_SimpleSec;
+ goto endparagraph;
+ }
+
+ // see if we are in a simple list
+ DocSimpleSect *ss=new DocSimpleSect(this,DocSimpleSect::Rcs);
+ m_children.append(ss);
+ ss->parseRcs();
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "Found unexpected token (id=%x)\n",tok);
+ break;
+ }
+ }
+ retval=0;
+endparagraph:
+ handlePendingStyleCommands(this,m_children);
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocPara::parse() end retval=%x\n",retval));
+ INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM ||
+ retval==TK_ENDLIST || retval>RetVal_OK
+ );
+
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+int DocSection::parse()
+{
+ DBG(("DocSection::parse() start %s level=%d\n",qPrint(g_token->sectionId),m_level));
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+
+ SectionInfo *sec;
+ if (!m_id.isEmpty())
+ {
+ sec=Doxygen::sectionDict->find(m_id);
+ if (sec)
+ {
+ m_file = sec->fileName;
+ m_anchor = sec->label;
+ m_title = sec->title;
+ if (m_title.isEmpty()) m_title = sec->label;
+ if (g_sectionDict && g_sectionDict->find(m_id)==0)
+ {
+ g_sectionDict->append(m_id,sec);
+ }
+ }
+ }
+
+ // first parse any number of paragraphs
+ bool isFirst=TRUE;
+ DocPara *lastPar=0;
+ do
+ {
+ DocPara *par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ retval=par->parse();
+ if (!par->isEmpty())
+ {
+ m_children.append(par);
+ lastPar=par;
+ }
+ else
+ {
+ delete par;
+ }
+ if (retval==TK_LISTITEM)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found");
+ }
+ if (retval==RetVal_Internal)
+ {
+ DocInternal *in = new DocInternal(this);
+ m_children.append(in);
+ retval = in->parse(m_level+1);
+ if (retval==RetVal_EndInternal)
+ {
+ retval=RetVal_OK;
+ }
+ }
+ } while (retval!=0 &&
+ retval!=RetVal_Section &&
+ retval!=RetVal_Subsection &&
+ retval!=RetVal_Subsubsection &&
+ retval!=RetVal_Paragraph &&
+ retval!=RetVal_EndInternal
+ );
+
+ if (lastPar) lastPar->markLast();
+
+ //printf("m_level=%d <-> %d\n",m_level,Doxygen::subpageNestingLevel);
+
+ if (retval==RetVal_Subsection && m_level==Doxygen::subpageNestingLevel+1)
+ {
+ // then parse any number of nested sections
+ while (retval==RetVal_Subsection) // more sections follow
+ {
+ //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
+ DocSection *s=new DocSection(this,
+ QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId);
+ m_children.append(s);
+ retval = s->parse();
+ }
+ }
+ else if (retval==RetVal_Subsubsection && m_level==Doxygen::subpageNestingLevel+2)
+ {
+ // then parse any number of nested sections
+ while (retval==RetVal_Subsubsection) // more sections follow
+ {
+ //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
+ DocSection *s=new DocSection(this,
+ QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId);
+ m_children.append(s);
+ retval = s->parse();
+ }
+ }
+ else if (retval==RetVal_Paragraph && m_level==QMIN(5,Doxygen::subpageNestingLevel+3))
+ {
+ // then parse any number of nested sections
+ while (retval==RetVal_Paragraph) // more sections follow
+ {
+ //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
+ DocSection *s=new DocSection(this,
+ QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId);
+ m_children.append(s);
+ retval = s->parse();
+ }
+ }
+ else if ((m_level<=1+Doxygen::subpageNestingLevel && retval==RetVal_Subsubsection) ||
+ (m_level<=2+Doxygen::subpageNestingLevel && retval==RetVal_Paragraph)
+ )
+ {
+ int level;
+ if (retval==RetVal_Subsection) level=2;
+ else if (retval==RetVal_Subsubsection) level=3;
+ else level=4;
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected %s "
+ "command found inside %s!",
+ sectionLevelToName[level],sectionLevelToName[m_level]);
+ retval=0; // stop parsing
+
+ }
+ else
+ {
+ }
+
+ INTERNAL_ASSERT(retval==0 ||
+ retval==RetVal_Section ||
+ retval==RetVal_Subsection ||
+ retval==RetVal_Subsubsection ||
+ retval==RetVal_Paragraph ||
+ retval==RetVal_Internal ||
+ retval==RetVal_EndInternal
+ );
+
+ DBG(("DocSection::parse() end: retval=%x\n",retval));
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
+//--------------------------------------------------------------------------
+
+void DocText::parse()
+{
+ DBG(("DocText::parse() start\n"));
+ g_nodeStack.push(this);
+ doctokenizerYYsetStateText();
+
+ int tok;
+ while ((tok=doctokenizerYYlex())) // get the next token
+ {
+ switch(tok)
+ {
+ case TK_WORD:
+ m_children.append(new DocWord(this,g_token->name));
+ break;
+ case TK_WHITESPACE:
+ m_children.append(new DocWhiteSpace(this,g_token->chars));
+ break;
+ case TK_SYMBOL:
+ {
+ DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name);
+ if (s!=DocSymbol::Sym_Unknown)
+ {
+ m_children.append(new DocSymbol(this,s));
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ qPrint(g_token->name));
+ }
+ }
+ break;
+ case TK_COMMAND:
+ switch (Mappers::cmdMapper->map(g_token->name))
+ {
+ case CMD_BSLASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_BSlash));
+ break;
+ case CMD_AT:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_At));
+ break;
+ case CMD_LESS:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Less));
+ break;
+ case CMD_GREATER:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Greater));
+ break;
+ case CMD_AMP:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Amp));
+ break;
+ case CMD_DOLLAR:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Dollar));
+ break;
+ case CMD_HASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Hash));
+ break;
+ case CMD_DCOLON:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_DoubleColon));
+ break;
+ case CMD_PERCENT:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Percent));
+ break;
+ case CMD_NDASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ break;
+ case CMD_MDASH:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus));
+ break;
+ case CMD_QUOTE:
+ m_children.append(new DocSymbol(this,DocSymbol::Sym_Quot));
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command `%s' found",
+ qPrint(g_token->name));
+ break;
+ }
+ break;
+ default:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ tokToString(tok));
+ break;
+ }
+ }
+
+ handleUnclosedStyleCommands();
+
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocText::parse() end\n"));
+}
+
+
+//--------------------------------------------------------------------------
+
+void DocRoot::parse()
+{
+ DBG(("DocRoot::parse() start\n"));
+ g_nodeStack.push(this);
+ doctokenizerYYsetStatePara();
+ int retval=0;
+
+ // first parse any number of paragraphs
+ bool isFirst=TRUE;
+ DocPara *lastPar=0;
+ do
+ {
+ DocPara *par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ retval=par->parse();
+ if (!par->isEmpty())
+ {
+ m_children.append(par);
+ lastPar=par;
+ }
+ else
+ {
+ delete par;
+ }
+ if (retval==TK_LISTITEM)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found");
+ }
+ else if (retval==RetVal_Subsection)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command outside of section context!");
+ }
+ else if (retval==RetVal_Subsubsection)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command outside of subsection context!");
+ }
+ else if (retval==RetVal_Paragraph)
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command outside of subsubsection context!");
+ }
+ if (retval==RetVal_Internal)
+ {
+ DocInternal *in = new DocInternal(this);
+ m_children.append(in);
+ retval = in->parse(1);
+ }
+ } while (retval!=0 && retval!=RetVal_Section);
+ if (lastPar) lastPar->markLast();
+
+ //printf("DocRoot::parse() retval=%d %d\n",retval,RetVal_Section);
+ // then parse any number of level1 sections
+ while (retval==RetVal_Section)
+ {
+ SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId);
+ if (sec)
+ {
+ DocSection *s=new DocSection(this,
+ QMIN(1+Doxygen::subpageNestingLevel,5),g_token->sectionId);
+ m_children.append(s);
+ retval = s->parse();
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid section id `%s'; ignoring section",qPrint(g_token->sectionId));
+ retval = 0;
+ }
+ }
+
+ handleUnclosedStyleCommands();
+
+ DocNode *n = g_nodeStack.pop();
+ ASSERT(n==this);
+ DBG(("DocRoot::parse() end\n"));
+}
+
+static QCString extractCopyDocId(const char *data, uint &j, uint len)
+{
+ uint s=j;
+ uint e=j;
+ int round=0;
+ bool insideDQuote=FALSE;
+ bool insideSQuote=FALSE;
+ bool found=FALSE;
+ while (j<len && !found)
+ {
+ if (!insideSQuote && !insideDQuote)
+ {
+ switch (data[j])
+ {
+ case '(': round++; break;
+ case ')': round--; break;
+ case '"': insideDQuote=TRUE; break;
+ case '\'': insideSQuote=TRUE; break;
+ case ' ': // fall through
+ case '\t': // fall through
+ case '\n':
+ found=(round==0);
+ break;
+ }
+ }
+ else if (insideSQuote) // look for single quote end
+ {
+ if (data[j]=='\'' && (j==0 || data[j]!='\\'))
+ {
+ insideSQuote=FALSE;
+ }
+ }
+ else if (insideDQuote) // look for double quote end
+ {
+ if (data[j]=='"' && (j==0 || data[j]!='\\'))
+ {
+ insideDQuote=FALSE;
+ }
+ }
+ if (!found) j++;
+ }
+ if (qstrncmp(data+j," const",6)==0)
+ {
+ j+=6;
+ }
+ else if (qstrncmp(data+j," volatile",9)==0)
+ {
+ j+=9;
+ }
+ e=j;
+ QCString id(e-s+1);
+ if (e>s) memcpy(id.data(),data+s,e-s);
+ id.at(e-s)='\0';
+ //printf("extractCopyDocId='%s' input='%s'\n",id.data(),&data[s]);
+ return id;
+}
+
+static uint isCopyBriefOrDetailsCmd(const char *data, uint i,uint len,bool &brief)
+{
+ int j=0;
+ if (i==0 || (data[i-1]!='@' && data[i-1]!='\\')) // not an escaped command
+ {
+ if (i+10<len && qstrncmp(data+i+1,"copybrief",9)==0) // @copybrief or \copybrief
+ {
+ j=i+10;
+ brief=TRUE;
+ }
+ else if (i+12<len && qstrncmp(data+i+1,"copydetails",11)==0) // @copydetails or \copydetails
+ {
+ j=i+12;
+ brief=FALSE;
+ }
+ }
+ return j;
+}
+
+static QCString processCopyDoc(const char *data,uint &len)
+{
+ //printf("processCopyDoc start '%s'\n",data);
+ GrowBuf buf;
+ uint i=0;
+ while (i<len)
+ {
+ char c = data[i];
+ if (c=='@' || c=='\\') // look for a command
+ {
+ bool isBrief=TRUE;
+ uint j=isCopyBriefOrDetailsCmd(data,i,len,isBrief);
+ if (j>0)
+ {
+ // skip whitespace
+ while (j<len && (data[j]==' ' || data[j]=='\t')) j++;
+ // extract the argument
+ QCString id = extractCopyDocId(data,j,len);
+ Definition *def;
+ QCString doc,brief;
+ //printf("resolving docs='%s'\n",id.data());
+ if (findDocsForMemberOrCompound(id,&doc,&brief,&def))
+ {
+ //printf("found it def=%p brief='%s' doc='%s' isBrief=%d\n",def,brief.data(),doc.data(),isBrief);
+ if (g_copyStack.findRef(def)==-1) // definition not parsed earlier
+ {
+ g_copyStack.append(def);
+ if (isBrief)
+ {
+ uint l=brief.length();
+ buf.addStr(processCopyDoc(brief,l));
+ }
+ else
+ {
+ uint l=doc.length();
+ buf.addStr(processCopyDoc(doc,l));
+ }
+ g_copyStack.remove(def);
+ }
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,
+ "Found recursive @copy%s or @copydoc relation for argument '%s'.\n",
+ isBrief?"brief":"details",id.data());
+ }
+ }
+ // skip over command
+ i=j;
+ }
+ else
+ {
+ buf.addChar(c);
+ i++;
+ }
+ }
+ else // not a command, just copy
+ {
+ buf.addChar(c);
+ i++;
+ }
+ }
+ len = buf.getPos();
+ buf.addChar(0);
+ return buf.get();
+}
+
+//--------------------------------------------------------------------------
+
+DocRoot *validatingParseDoc(const char *fileName,int startLine,
+ Definition *ctx,MemberDef *md,
+ const char *input,bool indexWords,
+ bool isExample, const char *exampleName,
+ bool singleLine, bool linkFromIndex)
+{
+ //printf("validatingParseDoc(%s,%s)=[%s]\n",ctx?ctx->name().data():"<none>",
+ // md?md->name().data():"<none>",
+ // input);
+ //printf("========== validating %s at line %d\n",fileName,startLine);
+ //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input);
+ //g_token = new TokenInfo;
+
+ // store parser state so we can re-enter this function if needed
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ docParserPushContext();
+
+ if (ctx && ctx!=Doxygen::globalScope &&
+ (ctx->definitionType()==Definition::TypeClass ||
+ ctx->definitionType()==Definition::TypeNamespace
+ )
+ )
+ {
+ g_context = ctx->name();
+ }
+ else if (ctx && ctx->definitionType()==Definition::TypePage)
+ {
+ Definition *scope = ((PageDef*)ctx)->getPageScope();
+ if (scope && scope!=Doxygen::globalScope) g_context = scope->name();
+ }
+ else if (ctx && ctx->definitionType()==Definition::TypeGroup)
+ {
+ Definition *scope = ((GroupDef*)ctx)->getGroupScope();
+ if (scope && scope!=Doxygen::globalScope) g_context = scope->name();
+ }
+ else
+ {
+ g_context = "";
+ }
+ g_scope = ctx;
+
+ if (indexWords && Doxygen::searchIndex)
+ {
+ if (md)
+ {
+ g_searchUrl=md->getOutputFileBase();
+ Doxygen::searchIndex->setCurrentDoc(md,md->anchor(),FALSE);
+ }
+ else if (ctx)
+ {
+ g_searchUrl=ctx->getOutputFileBase();
+ Doxygen::searchIndex->setCurrentDoc(ctx,ctx->anchor(),FALSE);
+ }
+ }
+#if 0
+ if (indexWords && md && Doxygen::searchIndex)
+ {
+ g_searchUrl=md->getOutputFileBase();
+ Doxygen::searchIndex->setCurrentDoc(
+ (md->getLanguage()==SrcLangExt_Fortran ?
+ theTranslator->trSubprogram(TRUE,TRUE):
+ theTranslator->trMember(TRUE,TRUE))+" "+md->qualifiedName(),
+ g_searchUrl,
+ md->anchor());
+ }
+ else if (indexWords && ctx && Doxygen::searchIndex)
+ {
+ g_searchUrl=ctx->getOutputFileBase();
+ QCString name = ctx->qualifiedName();
+
+ SrcLangExt lang = ctx->getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ name = substitute(name,"::",sep);
+ }
+
+ switch (ctx->definitionType())
+ {
+ case Definition::TypePage:
+ {
+ PageDef *pd = (PageDef *)ctx;
+ if (!pd->title().isEmpty())
+ {
+ name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title();
+ }
+ else
+ {
+ name = theTranslator->trPage(TRUE,TRUE)+" "+pd->name();
+ }
+ }
+ break;
+ case Definition::TypeClass:
+ {
+ ClassDef *cd = (ClassDef *)ctx;
+ name.prepend(cd->compoundTypeString()+" ");
+ }
+ break;
+ case Definition::TypeNamespace:
+ {
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
+ {
+ name = theTranslator->trPackage(name);
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ name.prepend(theTranslator->trModule(TRUE,TRUE)+" ");
+ }
+ else
+ {
+ name.prepend(theTranslator->trNamespace(TRUE,TRUE)+" ");
+ }
+ }
+ break;
+ case Definition::TypeGroup:
+ {
+ GroupDef *gd = (GroupDef *)ctx;
+ if (gd->groupTitle())
+ {
+ name = theTranslator->trGroup(TRUE,TRUE)+" "+gd->groupTitle();
+ }
+ else
+ {
+ name.prepend(theTranslator->trGroup(TRUE,TRUE)+" ");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ Doxygen::searchIndex->setCurrentDoc(name,g_searchUrl);
+ }
+#endif
+ else
+ {
+ g_searchUrl="";
+ }
+
+ g_fileName = fileName;
+ g_relPath = (!linkFromIndex && ctx) ?
+ QCString(relativePathToRoot(ctx->getOutputFileBase())) :
+ QCString("");
+ //printf("ctx->name=%s relPath=%s\n",ctx->name().data(),g_relPath.data());
+ g_memberDef = md;
+ g_nodeStack.clear();
+ g_styleStack.clear();
+ g_initialStyleStack.clear();
+ g_inSeeBlock = FALSE;
+ g_xmlComment = FALSE;
+ g_insideHtmlLink = FALSE;
+ g_includeFileText = "";
+ g_includeFileOffset = 0;
+ g_includeFileLength = 0;
+ g_isExample = isExample;
+ g_exampleName = exampleName;
+ g_hasParamCommand = FALSE;
+ g_hasReturnCommand = FALSE;
+ g_paramsFound.setAutoDelete(FALSE);
+ g_paramsFound.clear();
+ g_sectionDict = 0; //sections;
+
+ //printf("Starting comment block at %s:%d\n",g_fileName.data(),startLine);
+ doctokenizerYYlineno=startLine;
+ uint inpLen=qstrlen(input);
+ QCString inpStr = processCopyDoc(input,inpLen);
+ if (inpStr.isEmpty() || inpStr.at(inpStr.length()-1)!='\n')
+ {
+ inpStr+='\n';
+ }
+ //printf("processCopyDoc(in='%s' out='%s')\n",input,inpStr.data());
+ doctokenizerYYinit(inpStr,g_fileName);
+
+ // build abstract syntax tree
+ DocRoot *root = new DocRoot(md!=0,singleLine);
+ root->parse();
+
+
+ if (Debug::isFlagSet(Debug::PrintTree))
+ {
+ // pretty print the result
+ PrintDocVisitor *v = new PrintDocVisitor;
+ root->accept(v);
+ delete v;
+ }
+
+ checkUndocumentedParams();
+ detectNoDocumentedParams();
+
+ // TODO: These should be called at the end of the program.
+ //doctokenizerYYcleanup();
+ //Mappers::cmdMapper->freeInstance();
+ //Mappers::htmlTagMapper->freeInstance();
+
+ // restore original parser state
+ docParserPopContext();
+
+ //printf(">>>>>> end validatingParseDoc(%s,%s)\n",ctx?ctx->name().data():"<none>",
+ // md?md->name().data():"<none>");
+
+ return root;
+}
+
+DocText *validatingParseText(const char *input)
+{
+ // store parser state so we can re-enter this function if needed
+ docParserPushContext();
+
+ //printf("------------ input ---------\n%s\n"
+ // "------------ end input -----\n",input);
+ //g_token = new TokenInfo;
+ g_context = "";
+ g_fileName = "<parseText>";
+ g_relPath = "";
+ g_memberDef = 0;
+ g_nodeStack.clear();
+ g_styleStack.clear();
+ g_initialStyleStack.clear();
+ g_inSeeBlock = FALSE;
+ g_xmlComment = FALSE;
+ g_insideHtmlLink = FALSE;
+ g_includeFileText = "";
+ g_includeFileOffset = 0;
+ g_includeFileLength = 0;
+ g_isExample = FALSE;
+ g_exampleName = "";
+ g_hasParamCommand = FALSE;
+ g_hasReturnCommand = FALSE;
+ g_paramsFound.setAutoDelete(FALSE);
+ g_paramsFound.clear();
+ g_searchUrl="";
+
+ DocText *txt = new DocText;
+
+ if (input)
+ {
+ doctokenizerYYlineno=1;
+ doctokenizerYYinit(input,g_fileName);
+
+ // build abstract syntax tree
+ txt->parse();
+
+ if (Debug::isFlagSet(Debug::PrintTree))
+ {
+ // pretty print the result
+ PrintDocVisitor *v = new PrintDocVisitor;
+ txt->accept(v);
+ delete v;
+ }
+ }
+
+ // restore original parser state
+ docParserPopContext();
+ return txt;
+}
+
+void docFindSections(const char *input,
+ Definition *d,
+ MemberGroup *mg,
+ const char *fileName)
+{
+ doctokenizerYYFindSections(input,d,mg,fileName);
+}
+
diff --git a/src/docparser.h b/src/docparser.h
new file mode 100644
index 0000000..3dc3d84
--- /dev/null
+++ b/src/docparser.h
@@ -0,0 +1,1378 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DOCPARSER_H
+#define _DOCPARSER_H
+
+#include <stdio.h>
+
+#include <qlist.h>
+#include <qcstring.h>
+
+#include "docvisitor.h"
+#include "htmlattrib.h"
+
+class DocNode;
+class MemberDef;
+class Definition;
+class MemberGroup;
+class SectionDict;
+
+//---------------------------------------------------------------------------
+
+
+/*! Main entry point for the documentation parser.
+ * @param fileName File in which the documentation block is found (or the
+ * name of the example file in case isExample is TRUE).
+ * @param startLine Line at which the documentation block is found.
+ * @param context Class or namespace to which this block belongs.
+ * @param md Member definition to which the documentation belongs.
+ * Can be 0.
+ * @param input String representation of the documentation block.
+ * @param indexWords Indicates whether or not words should be put in the
+ * search index.
+ * @param isExample TRUE if the documentation belongs to an example.
+ * @param exampleName Base name of the example file (0 if isExample is FALSE).
+ * @param singleLine Output should be presented on a single line, so without
+ * starting a new paragraph at the end.
+ * @param linkFromIndex TRUE if the documentation is generated from an
+ * index page. In this case context is not used to determine
+ * the relative path when making a link.
+ * @returns Root node of the abstract syntax tree. Ownership of the
+ * pointer is handed over to the caller.
+ */
+DocRoot *validatingParseDoc(const char *fileName,int startLine,
+ Definition *context, MemberDef *md,
+ const char *input,bool indexWords,
+ bool isExample,const char *exampleName=0,
+ bool singleLine=FALSE,bool linkFromIndex=FALSE);
+
+/*! Main entry point for parsing simple text fragments. These
+ * fragments are limited to words, whitespace and symbols.
+ */
+DocText *validatingParseText(const char *input);
+
+/*! Searches for section and anchor commands in the input */
+void docFindSections(const char *input,
+ Definition *d,
+ MemberGroup *m,
+ const char *fileName);
+
+//---------------------------------------------------------------------------
+
+/** Abstract node interface with type information. */
+class DocNode
+{
+ public:
+ /*! Available node types. */
+ enum Kind { Kind_Root = 0,
+ Kind_Word = 1,
+ Kind_WhiteSpace = 2,
+ Kind_Para = 3,
+ Kind_AutoList = 4,
+ Kind_AutoListItem = 5,
+ Kind_Symbol = 6,
+ Kind_URL = 7,
+ Kind_StyleChange = 8,
+ Kind_SimpleSect = 9,
+ Kind_Title = 10,
+ Kind_SimpleList = 11,
+ Kind_SimpleListItem = 12,
+ Kind_Section = 13,
+ Kind_Verbatim = 14,
+ Kind_XRefItem = 15,
+ Kind_HtmlList = 16,
+ Kind_HtmlListItem = 17,
+ Kind_HtmlDescList = 18,
+ Kind_HtmlDescData = 19,
+ Kind_HtmlDescTitle = 20,
+ Kind_HtmlTable = 21,
+ Kind_HtmlRow = 22,
+ Kind_HtmlCell = 23,
+ Kind_HtmlCaption = 24,
+ Kind_LineBreak = 25,
+ Kind_HorRuler = 26,
+ Kind_Anchor = 27,
+ Kind_IndexEntry = 28,
+ Kind_Internal = 29,
+ Kind_HRef = 30,
+ Kind_Include = 31,
+ Kind_IncOperator = 32,
+ Kind_HtmlHeader = 33,
+ Kind_Image = 34,
+ Kind_DotFile = 35,
+ Kind_Link = 36,
+ Kind_Ref = 37,
+ Kind_Formula = 38,
+ Kind_SecRefItem = 39,
+ Kind_SecRefList = 40,
+ Kind_SimpleSectSep = 41,
+ Kind_LinkedWord = 42,
+ Kind_ParamSect = 43,
+ Kind_ParamList = 44,
+ Kind_InternalRef = 45,
+ Kind_Copy = 46,
+ Kind_Text = 47,
+ Kind_MscFile = 48,
+ Kind_HtmlBlockQuote = 49,
+ Kind_VhdlFlow = 50,
+ Kind_ParBlock = 51,
+ Kind_DiaFile = 52
+ };
+ /*! Creates a new node */
+ DocNode() : m_parent(0), m_insidePre(FALSE) {}
+
+ /*! Destroys a node. */
+ virtual ~DocNode() {}
+
+ /*! Returns the kind of node. Provides runtime type information */
+ virtual Kind kind() const = 0;
+
+ /*! Returns the parent of this node or 0 for the root node. */
+ DocNode *parent() const { return m_parent; }
+
+ /*! Sets a new parent for this node. */
+ void setParent(DocNode *parent) { m_parent = parent; }
+
+ /*! Acceptor function for node visitors. Part of the visitor pattern.
+ * @param v Abstract visitor.
+ */
+ virtual void accept(DocVisitor *v) = 0;
+
+ /*! Returns TRUE iff this node is inside a preformatted section */
+ bool isPreformatted() const { return m_insidePre; }
+
+ protected:
+ /*! Sets whether or not this item is inside a preformatted section */
+ void setInsidePreformatted(bool p) { m_insidePre = p; }
+ DocNode *m_parent;
+ private:
+
+ bool m_insidePre;
+};
+
+/** Default accept implementation for compound nodes in the abstract
+ * syntax tree.
+ */
+template<class T> class CompAccept
+{
+ public:
+ CompAccept() { m_children.setAutoDelete(TRUE); }
+ virtual ~CompAccept() {}
+ void accept(T *obj, DocVisitor *v)
+ {
+ v->visitPre(obj);
+ QListIterator<DocNode> cli(m_children);
+ DocNode *n;
+ for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
+ v->visitPost(obj);
+ }
+ const QList<DocNode> &children() const { return m_children; }
+ QList<DocNode> &children() { return m_children; }
+
+ protected:
+ QList<DocNode> m_children;
+};
+
+
+/** Node representing a word
+ */
+class DocWord : public DocNode
+{
+ public:
+ DocWord(DocNode *parent,const QCString &word);
+ QCString word() const { return m_word; }
+ Kind kind() const { return Kind_Word; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+ QCString m_word;
+};
+
+/** Node representing a word that can be linked to something
+ */
+class DocLinkedWord : public DocNode
+{
+ public:
+ DocLinkedWord(DocNode *parent,const QCString &word,
+ const QCString &ref,const QCString &file,
+ const QCString &anchor,const QCString &tooltip);
+ QCString word() const { return m_word; }
+ Kind kind() const { return Kind_LinkedWord; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ QCString ref() const { return m_ref; }
+ QCString anchor() const { return m_anchor; }
+ QCString tooltip() const { return m_tooltip; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+ QCString m_word;
+ QCString m_ref;
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_anchor;
+ QCString m_tooltip;
+};
+
+/** Node representing an URL (or email address) */
+class DocURL : public DocNode
+{
+ public:
+ DocURL(DocNode *parent,const QCString &url,bool isEmail) :
+ m_url(url), m_isEmail(isEmail) { m_parent=parent; }
+ QCString url() const { return m_url; }
+ Kind kind() const { return Kind_URL; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ bool isEmail() const { return m_isEmail; }
+
+ private:
+ QCString m_url;
+ bool m_isEmail;
+};
+
+/** Node representing a line break */
+class DocLineBreak : public DocNode
+{
+ public:
+ DocLineBreak(DocNode *parent) { m_parent=parent; }
+ Kind kind() const { return Kind_LineBreak; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+};
+
+/** Node representing a horizonal ruler */
+class DocHorRuler : public DocNode
+{
+ public:
+ DocHorRuler(DocNode *parent) { m_parent = parent; }
+ Kind kind() const { return Kind_HorRuler; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+};
+
+/** Node representing an anchor */
+class DocAnchor : public DocNode
+{
+ public:
+ DocAnchor(DocNode *parent,const QCString &id,bool newAnchor);
+ Kind kind() const { return Kind_Anchor; }
+ QCString anchor() const { return m_anchor; }
+ QCString file() const { return m_file; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+ QCString m_anchor;
+ QCString m_file;
+};
+
+/** Node representing a citation of some bibliographic reference */
+class DocCite : public DocNode
+{
+ public:
+ DocCite(DocNode *parent,const QCString &target,const QCString &context);
+ Kind kind() const { return Kind_Ref; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ QCString ref() const { return m_ref; }
+ QCString anchor() const { return m_anchor; }
+ QCString text() const { return m_text; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_ref;
+ QCString m_anchor;
+ QCString m_text;
+};
+
+
+/** Node representing a style change */
+class DocStyleChange : public DocNode
+{
+ public:
+ enum Style { Bold, Italic, Code, Center, Small,
+ Subscript, Superscript, Preformatted,
+ Span, Div
+ };
+ DocStyleChange(DocNode *parent,uint position,Style s,bool enable,
+ const HtmlAttribList *attribs=0) :
+ m_position(position), m_style(s), m_enable(enable)
+ { m_parent = parent; if (attribs) m_attribs=*attribs; }
+ Kind kind() const { return Kind_StyleChange; }
+ Style style() const { return m_style; }
+ const char *styleString() const;
+ bool enable() const { return m_enable; }
+ uint position() const { return m_position; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+
+ private:
+ uint m_position;
+ Style m_style;
+ bool m_enable;
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a special symbol */
+class DocSymbol : public DocNode
+{
+ public:
+ enum SymType { Sym_Unknown = -1,
+ Sym_nbsp, Sym_iexcl, Sym_cent, Sym_pound, Sym_curren,
+ Sym_yen, Sym_brvbar, Sym_sect, Sym_uml, Sym_copy,
+ Sym_ordf, Sym_laquo, Sym_not, Sym_shy, Sym_reg,
+ Sym_macr, Sym_deg, Sym_plusmn, Sym_sup2, Sym_sup3,
+ Sym_acute, Sym_micro, Sym_para, Sym_middot, Sym_cedil,
+ Sym_sup1, Sym_ordm, Sym_raquo, Sym_frac14, Sym_frac12,
+ Sym_frac34, Sym_iquest, Sym_Agrave, Sym_Aacute, Sym_Acirc,
+ Sym_Atilde, Sym_Auml, Sym_Aring, Sym_AElig, Sym_Ccedil,
+ Sym_Egrave, Sym_Eacute, Sym_Ecirc, Sym_Euml, Sym_Igrave,
+ Sym_Iacute, Sym_Icirc, Sym_Iuml, Sym_ETH, Sym_Ntilde,
+ Sym_Ograve, Sym_Oacute, Sym_Ocirc, Sym_Otilde, Sym_Ouml,
+ Sym_times, Sym_Oslash, Sym_Ugrave, Sym_Uacute, Sym_Ucirc,
+ Sym_Uuml, Sym_Yacute, Sym_THORN, Sym_szlig, Sym_agrave,
+ Sym_aacute, Sym_acirc, Sym_atilde, Sym_auml, Sym_aring,
+ Sym_aelig, Sym_ccedil, Sym_egrave, Sym_eacute, Sym_ecirc,
+ Sym_euml, Sym_igrave, Sym_iacute, Sym_icirc, Sym_iuml,
+ Sym_eth, Sym_ntilde, Sym_ograve, Sym_oacute, Sym_ocirc,
+ Sym_otilde, Sym_ouml, Sym_divide, Sym_oslash, Sym_ugrave,
+ Sym_uacute, Sym_ucirc, Sym_uuml, Sym_yacute, Sym_thorn,
+ Sym_yuml, Sym_fnof, Sym_Alpha, Sym_Beta, Sym_Gamma,
+ Sym_Delta, Sym_Epsilon, Sym_Zeta, Sym_Eta, Sym_Theta,
+ Sym_Iota, Sym_Kappa, Sym_Lambda, Sym_Mu, Sym_Nu,
+ Sym_Xi, Sym_Omicron, Sym_Pi, Sym_Rho, Sym_Sigma,
+ Sym_Tau, Sym_Upsilon, Sym_Phi, Sym_Chi, Sym_Psi,
+ Sym_Omega, Sym_alpha, Sym_beta, Sym_gamma, Sym_delta,
+ Sym_epsilon, Sym_zeta, Sym_eta, Sym_theta, Sym_iota,
+ Sym_kappa, Sym_lambda, Sym_mu, Sym_nu, Sym_xi,
+ Sym_omicron, Sym_pi, Sym_rho, Sym_sigmaf, Sym_sigma,
+ Sym_tau, Sym_upsilon, Sym_phi, Sym_chi, Sym_psi,
+ Sym_omega, Sym_thetasym, Sym_upsih, Sym_piv, Sym_bull,
+ Sym_hellip, Sym_prime, Sym_Prime, Sym_oline, Sym_frasl,
+ Sym_weierp, Sym_image, Sym_real, Sym_trade, Sym_alefsym,
+ Sym_larr, Sym_uarr, Sym_rarr, Sym_darr, Sym_harr,
+ Sym_crarr, Sym_lArr, Sym_uArr, Sym_rArr, Sym_dArr,
+ Sym_hArr, Sym_forall, Sym_part, Sym_exist, Sym_empty,
+ Sym_nabla, Sym_isin, Sym_notin, Sym_ni, Sym_prod,
+ Sym_sum, Sym_minus, Sym_lowast, Sym_radic, Sym_prop,
+ Sym_infin, Sym_ang, Sym_and, Sym_or, Sym_cap,
+ Sym_cup, Sym_int, Sym_there4, Sym_sim, Sym_cong,
+ Sym_asymp, Sym_ne, Sym_equiv, Sym_le, Sym_ge,
+ Sym_sub, Sym_sup, Sym_nsub, Sym_sube, Sym_supe,
+ Sym_oplus, Sym_otimes, Sym_perp, Sym_sdot, Sym_lceil,
+ Sym_rceil, Sym_lfloor, Sym_rfloor, Sym_lang, Sym_rang,
+ Sym_loz, Sym_spades, Sym_clubs, Sym_hearts, Sym_diams,
+ Sym_quot, Sym_amp, Sym_lt, Sym_gt, Sym_OElig,
+ Sym_oelig, Sym_Scaron, Sym_scaron, Sym_Yuml, Sym_circ,
+ Sym_tilde, Sym_ensp, Sym_emsp, Sym_thinsp, Sym_zwnj,
+ Sym_zwj, Sym_lrm, Sym_rlm, Sym_ndash, Sym_mdash,
+ Sym_lsquo, Sym_rsquo, Sym_sbquo, Sym_ldquo, Sym_rdquo,
+ Sym_bdquo, Sym_dagger, Sym_Dagger, Sym_permil, Sym_lsaquo,
+ Sym_rsaquo, Sym_euro,
+
+ /* doxygen extensions */
+ Sym_tm, Sym_apos,
+
+ /* doxygen commands mapped */
+ Sym_BSlash, Sym_At, Sym_Less, Sym_Greater, Sym_Amp,
+ Sym_Dollar, Sym_Hash, Sym_DoubleColon, Sym_Percent, Sym_Pipe,
+ Sym_Quot, Sym_Minus
+ };
+ enum PerlType { Perl_unknown = 0, Perl_string, Perl_char, Perl_symbol, Perl_umlaut,
+ Perl_acute, Perl_grave, Perl_circ, Perl_slash, Perl_tilde,
+ Perl_cedilla, Perl_ring
+ };
+ typedef struct PerlSymb {
+ const char *symb;
+ const PerlType type;
+ }PerlSymb;
+ DocSymbol(DocNode *parent,SymType s) :
+ m_symbol(s) { m_parent = parent; }
+ SymType symbol() const { return m_symbol; }
+ Kind kind() const { return Kind_Symbol; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ static SymType decodeSymbol(const QCString &symName);
+
+ private:
+ SymType m_symbol;
+};
+
+/** Node representing some amount of white space */
+class DocWhiteSpace : public DocNode
+{
+ public:
+ DocWhiteSpace(DocNode *parent,const QCString &chars) :
+ m_chars(chars) { m_parent = parent; }
+ Kind kind() const { return Kind_WhiteSpace; }
+ QCString chars() const { return m_chars; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ private:
+ QCString m_chars;
+};
+
+/** Node representing a verbatim, unparsed text fragment */
+class DocVerbatim : public DocNode
+{
+ public:
+ enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly, PlantUML };
+ DocVerbatim(DocNode *parent,const QCString &context,
+ const QCString &text, Type t,bool isExample,
+ const QCString &exampleFile,bool isBlock=FALSE,const QCString &lang=QCString());
+ Kind kind() const { return Kind_Verbatim; }
+ Type type() const { return m_type; }
+ QCString text() const { return m_text; }
+ QCString context() const { return m_context; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ bool isExample() const { return m_isExample; }
+ QCString exampleFile() const { return m_exampleFile; }
+ QCString relPath() const { return m_relPath; }
+ QCString language() const { return m_lang; }
+ bool isBlock() const { return m_isBlock; }
+
+ private:
+ QCString m_context;
+ QCString m_text;
+ Type m_type;
+ bool m_isExample;
+ QCString m_exampleFile;
+ QCString m_relPath;
+ QCString m_lang;
+ bool m_isBlock;
+};
+
+
+/** Node representing an included text block from file */
+class DocInclude : public DocNode
+{
+ public:
+ enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, IncWithLines, Snippet };
+ DocInclude(DocNode *parent,const QCString &file,
+ const QCString context, Type t,
+ bool isExample,const QCString exampleFile,
+ const QCString blockId) :
+ m_file(file), m_context(context), m_type(t),
+ m_isExample(isExample), m_exampleFile(exampleFile),
+ m_blockId(blockId) { m_parent = parent; }
+ Kind kind() const { return Kind_Include; }
+ QCString file() const { return m_file; }
+ QCString extension() const { int i=m_file.findRev('.');
+ if (i!=-1)
+ return m_file.right(m_file.length()-i);
+ else
+ return "";
+ }
+ Type type() const { return m_type; }
+ QCString text() const { return m_text; }
+ QCString context() const { return m_context; }
+ QCString blockId() const { return m_blockId; }
+ bool isExample() const { return m_isExample; }
+ QCString exampleFile() const { return m_exampleFile; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ void parse();
+
+ private:
+ QCString m_file;
+ QCString m_context;
+ QCString m_text;
+ Type m_type;
+ bool m_isExample;
+ QCString m_exampleFile;
+ QCString m_blockId;
+};
+
+/** Node representing a include/dontinclude operator block */
+class DocIncOperator : public DocNode
+{
+ public:
+ enum Type { Line, SkipLine, Skip, Until };
+ DocIncOperator(DocNode *parent,Type t,const QCString &pat,
+ const QCString &context,bool isExample,const QCString &exampleFile) :
+ m_type(t), m_pattern(pat), m_context(context),
+ m_isFirst(FALSE), m_isLast(FALSE),
+ m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; }
+ Kind kind() const { return Kind_IncOperator; }
+ Type type() const { return m_type; }
+ QCString text() const { return m_text; }
+ QCString pattern() const { return m_pattern; }
+ QCString context() const { return m_context; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ bool isFirst() const { return m_isFirst; }
+ bool isLast() const { return m_isLast; }
+ void markFirst(bool v=TRUE) { m_isFirst = v; }
+ void markLast(bool v=TRUE) { m_isLast = v; }
+ bool isExample() const { return m_isExample; }
+ QCString exampleFile() const { return m_exampleFile; }
+ void parse();
+
+ private:
+ Type m_type;
+ QCString m_text;
+ QCString m_pattern;
+ QCString m_context;
+ bool m_isFirst;
+ bool m_isLast;
+ bool m_isExample;
+ QCString m_exampleFile;
+};
+
+/** Node representing an item of a cross-referenced list */
+class DocFormula : public DocNode
+{
+ public:
+ DocFormula(DocNode *parent,int id);
+ Kind kind() const { return Kind_Formula; }
+ QCString name() const { return m_name; }
+ QCString text() const { return m_text; }
+ QCString relPath() const { return m_relPath; }
+ int id() const { return m_id; }
+ void accept(DocVisitor *v) { v->visit(this); }
+ bool isInline() { return m_text.length()>0 ? m_text.at(0)!='\\' : TRUE; }
+
+ private:
+ QCString m_name;
+ QCString m_text;
+ QCString m_relPath;
+ int m_id;
+};
+
+/** Node representing an entry in the index. */
+class DocIndexEntry : public DocNode
+{
+ public:
+ DocIndexEntry(DocNode *parent,Definition *scope,MemberDef *md)
+ : m_scope(scope), m_member(md){ m_parent = parent; }
+ Kind kind() const { return Kind_IndexEntry; }
+ int parse();
+ Definition *scope() const { return m_scope; }
+ MemberDef *member() const { return m_member; }
+ QCString entry() const { return m_entry; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+ QCString m_entry;
+ Definition *m_scope;
+ MemberDef *m_member;
+};
+
+//-----------------------------------------------------------------------
+
+/** Node representing a copy of documentation block. */
+class DocCopy : public DocNode
+{
+ public:
+ DocCopy(DocNode *parent,const QCString &link,bool copyBrief,bool copyDetails)
+ : m_link(link),
+ m_copyBrief(copyBrief), m_copyDetails(copyDetails) { m_parent = parent; }
+ Kind kind() const { return Kind_Copy; }
+ QCString link() const { return m_link; }
+ void accept(DocVisitor * /*v*/) { /*CompAccept<DocCopy>::accept(this,v);*/ }
+ void parse(QList<DocNode> &children);
+
+ private:
+ QCString m_link;
+ bool m_copyBrief;
+ bool m_copyDetails;
+};
+
+/** Node representing an auto List */
+class DocAutoList : public CompAccept<DocAutoList>, public DocNode
+{
+ public:
+ DocAutoList(DocNode *parent,int indent,bool isEnumList,int depth);
+ Kind kind() const { return Kind_AutoList; }
+ bool isEnumList() const { return m_isEnumList; }
+ int indent() const { return m_indent; }
+ int depth() const { return m_depth; }
+ void accept(DocVisitor *v) { CompAccept<DocAutoList>::accept(this,v); }
+ int parse();
+
+ private:
+ int m_indent;
+ bool m_isEnumList;
+ int m_depth;
+};
+
+/** Node representing an item of a auto list */
+class DocAutoListItem : public CompAccept<DocAutoListItem>, public DocNode
+{
+ public:
+ DocAutoListItem(DocNode *parent,int indent,int num);
+ Kind kind() const { return Kind_AutoListItem; }
+ int itemNumber() const { return m_itemNum; }
+ void accept(DocVisitor *v) { CompAccept<DocAutoListItem>::accept(this,v); }
+ int parse();
+
+ private:
+ int m_indent;
+ int m_itemNum;
+};
+
+
+
+/** Node representing a simple section title */
+class DocTitle : public CompAccept<DocTitle>, public DocNode
+{
+ public:
+ DocTitle(DocNode *parent) { m_parent = parent; }
+ void parse();
+ void parseFromString(const QCString &title);
+ Kind kind() const { return Kind_Title; }
+ void accept(DocVisitor *v) { CompAccept<DocTitle>::accept(this,v); }
+
+ private:
+};
+
+/** Node representing an item of a cross-referenced list */
+class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
+{
+ public:
+ DocXRefItem(DocNode *parent,int id,const char *key);
+ Kind kind() const { return Kind_XRefItem; }
+ QCString file() const { return m_file; }
+ QCString anchor() const { return m_anchor; }
+ QCString title() const { return m_title; }
+ QCString relPath() const { return m_relPath; }
+ QCString key() const { return m_key; }
+ void accept(DocVisitor *v) { CompAccept<DocXRefItem>::accept(this,v); }
+ bool parse();
+
+ private:
+ int m_id;
+ QCString m_key;
+ QCString m_file;
+ QCString m_anchor;
+ QCString m_title;
+ QCString m_relPath;
+};
+
+/** Node representing an image */
+class DocImage : public CompAccept<DocImage>, public DocNode
+{
+ public:
+ enum Type { Html, Latex, Rtf, DocBook };
+ DocImage(DocNode *parent,const HtmlAttribList &attribs,
+ const QCString &name,Type t,const QCString &url=QCString());
+ Kind kind() const { return Kind_Image; }
+ Type type() const { return m_type; }
+ QCString name() const { return m_name; }
+ bool hasCaption() const { return !m_children.isEmpty(); }
+ QCString width() const { return m_width; }
+ QCString height() const { return m_height; }
+ QCString relPath() const { return m_relPath; }
+ QCString url() const { return m_url; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocImage>::accept(this,v); }
+ void parse();
+
+ private:
+ HtmlAttribList m_attribs;
+ QCString m_name;
+ Type m_type;
+ QCString m_width;
+ QCString m_height;
+ QCString m_relPath;
+ QCString m_url;
+};
+
+/** Node representing a dot file */
+class DocDotFile : public CompAccept<DocDotFile>, public DocNode
+{
+ public:
+ DocDotFile(DocNode *parent,const QCString &name,const QCString &context);
+ void parse();
+ Kind kind() const { return Kind_DotFile; }
+ QCString name() const { return m_name; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ bool hasCaption() const { return !m_children.isEmpty(); }
+ QCString width() const { return m_width; }
+ QCString height() const { return m_height; }
+ QCString context() const { return m_context; }
+ void accept(DocVisitor *v) { CompAccept<DocDotFile>::accept(this,v); }
+ private:
+ QCString m_name;
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_width;
+ QCString m_height;
+ QCString m_context;
+};
+
+/** Node representing a msc file */
+class DocMscFile : public CompAccept<DocMscFile>, public DocNode
+{
+ public:
+ DocMscFile(DocNode *parent,const QCString &name,const QCString &context);
+ void parse();
+ Kind kind() const { return Kind_MscFile; }
+ QCString name() const { return m_name; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ bool hasCaption() const { return !m_children.isEmpty(); }
+ QCString width() const { return m_width; }
+ QCString height() const { return m_height; }
+ QCString context() const { return m_context; }
+ void accept(DocVisitor *v) { CompAccept<DocMscFile>::accept(this,v); }
+ private:
+ QCString m_name;
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_width;
+ QCString m_height;
+ QCString m_context;
+};
+
+/** Node representing a dia file */
+class DocDiaFile : public CompAccept<DocDiaFile>, public DocNode
+{
+ public:
+ DocDiaFile(DocNode *parent,const QCString &name,const QCString &context);
+ void parse();
+ Kind kind() const { return Kind_DiaFile; }
+ QCString name() const { return m_name; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ bool hasCaption() const { return !m_children.isEmpty(); }
+ QCString width() const { return m_width; }
+ QCString height() const { return m_height; }
+ QCString context() const { return m_context; }
+ void accept(DocVisitor *v) { CompAccept<DocDiaFile>::accept(this,v); }
+ private:
+ QCString m_name;
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_width;
+ QCString m_height;
+ QCString m_context;
+};
+
+/** Node representing a VHDL flow chart */
+class DocVhdlFlow : public CompAccept<DocVhdlFlow>, public DocNode
+{
+ public:
+ DocVhdlFlow(DocNode *parent);
+ void parse();
+ Kind kind() const { return Kind_VhdlFlow; }
+ bool hasCaption() { return !m_children.isEmpty(); }
+ void accept(DocVisitor *v) { CompAccept<DocVhdlFlow>::accept(this,v); }
+ private:
+};
+
+/** Node representing a link to some item */
+class DocLink : public CompAccept<DocLink>, public DocNode
+{
+ public:
+ DocLink(DocNode *parent,const QCString &target);
+ QCString parse(bool,bool isXmlLink=FALSE);
+ Kind kind() const { return Kind_Link; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ QCString ref() const { return m_ref; }
+ QCString anchor() const { return m_anchor; }
+ void accept(DocVisitor *v) { CompAccept<DocLink>::accept(this,v); }
+
+ private:
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_ref;
+ QCString m_anchor;
+ QCString m_refText;
+};
+
+/** Node representing a reference to some item */
+class DocRef : public CompAccept<DocRef>, public DocNode
+{
+ public:
+ DocRef(DocNode *parent,const QCString &target,const QCString &context);
+ void parse();
+ Kind kind() const { return Kind_Ref; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ QCString ref() const { return m_ref; }
+ QCString anchor() const { return m_anchor; }
+ QCString targetTitle() const { return m_text; }
+ bool hasLinkText() const { return !m_children.isEmpty(); }
+ bool refToAnchor() const { return m_refToAnchor; }
+ bool refToSection() const { return m_refToSection; }
+ bool isSubPage() const { return m_isSubPage; }
+ void accept(DocVisitor *v) { CompAccept<DocRef>::accept(this,v); }
+
+ private:
+ bool m_refToSection;
+ bool m_refToAnchor;
+ bool m_isSubPage;
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_ref;
+ QCString m_anchor;
+ QCString m_text;
+};
+
+/** Node representing an internal reference to some item */
+class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
+{
+ public:
+ DocInternalRef(DocNode *parent,const QCString &target);
+ void parse();
+ Kind kind() const { return Kind_Ref; }
+ QCString file() const { return m_file; }
+ QCString relPath() const { return m_relPath; }
+ QCString anchor() const { return m_anchor; }
+ void accept(DocVisitor *v) { CompAccept<DocInternalRef>::accept(this,v); }
+
+ private:
+ QCString m_file;
+ QCString m_relPath;
+ QCString m_anchor;
+};
+
+/** Node representing a Hypertext reference */
+class DocHRef : public CompAccept<DocHRef>, public DocNode
+{
+ public:
+ DocHRef(DocNode *parent,const HtmlAttribList &attribs,const QCString &url,
+ const QCString &relPath) :
+ m_attribs(attribs), m_url(url), m_relPath(relPath) { m_parent = parent; }
+ int parse();
+ QCString url() const { return m_url; }
+ QCString relPath() const { return m_relPath; }
+ Kind kind() const { return Kind_HRef; }
+ void accept(DocVisitor *v) { CompAccept<DocHRef>::accept(this,v); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+
+ private:
+ HtmlAttribList m_attribs;
+ QCString m_url;
+ QCString m_relPath;
+};
+
+/** Node Html heading */
+class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode
+{
+ public:
+ DocHtmlHeader(DocNode *parent,const HtmlAttribList &attribs,int level) :
+ m_level(level), m_attribs(attribs) { m_parent = parent; }
+ int level() const { return m_level; }
+ Kind kind() const { return Kind_HtmlHeader; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlHeader>::accept(this,v); }
+ int parse();
+
+ private:
+ int m_level;
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a Html description item */
+class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>, public DocNode
+{
+ public:
+ DocHtmlDescTitle(DocNode *parent,const HtmlAttribList &attribs) :
+ m_attribs(attribs) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlDescTitle; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlDescTitle>::accept(this,v); }
+ int parse();
+
+ private:
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a Html description list */
+class DocHtmlDescList : public CompAccept<DocHtmlDescList>, public DocNode
+{
+ public:
+ DocHtmlDescList(DocNode *parent,const HtmlAttribList &attribs) :
+ m_attribs(attribs) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlDescList; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlDescList>::accept(this,v); }
+ int parse();
+
+ private:
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a normal section */
+class DocSection : public CompAccept<DocSection>, public DocNode
+{
+ public:
+ DocSection(DocNode *parent,int level,const QCString &id) :
+ m_level(level), m_id(id) { m_parent = parent; }
+ Kind kind() const { return Kind_Section; }
+ int level() const { return m_level; }
+ QCString title() const { return m_title; }
+ QCString anchor() const { return m_anchor; }
+ QCString id() const { return m_id; }
+ QCString file() const { return m_file; }
+ void accept(DocVisitor *v) { CompAccept<DocSection>::accept(this,v); }
+ int parse();
+
+ private:
+ int m_level;
+ QCString m_id;
+ QCString m_title;
+ QCString m_anchor;
+ QCString m_file;
+};
+
+/** Node representing a reference to a section */
+class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode
+{
+ public:
+ DocSecRefItem(DocNode *parent,const QCString &target) :
+ m_target(target) { m_parent = parent; }
+ Kind kind() const { return Kind_SecRefItem; }
+ QCString target() const { return m_target; }
+ QCString file() const { return m_file; }
+ QCString anchor() const { return m_anchor; }
+ void accept(DocVisitor *v) { CompAccept<DocSecRefItem>::accept(this,v); }
+ void parse();
+
+ private:
+ QCString m_target;
+ QCString m_file;
+ QCString m_anchor;
+};
+
+/** Node representing a list of section references */
+class DocSecRefList : public CompAccept<DocSecRefList>, public DocNode
+{
+ public:
+ DocSecRefList(DocNode *parent) { m_parent = parent; }
+ void parse();
+ Kind kind() const { return Kind_SecRefList; }
+ void accept(DocVisitor *v) { CompAccept<DocSecRefList>::accept(this,v); }
+
+ private:
+};
+
+/** Node representing an internal section of documentation */
+class DocInternal : public CompAccept<DocInternal>, public DocNode
+{
+ public:
+ DocInternal(DocNode *parent) { m_parent = parent; }
+ int parse(int);
+ Kind kind() const { return Kind_Internal; }
+ void accept(DocVisitor *v) { CompAccept<DocInternal>::accept(this,v); }
+
+ private:
+};
+
+/** Node representing an block of paragraphs */
+class DocParBlock : public CompAccept<DocParBlock>, public DocNode
+{
+ public:
+ DocParBlock(DocNode *parent) { m_parent = parent; }
+ int parse();
+ Kind kind() const { return Kind_ParBlock; }
+ void accept(DocVisitor *v) { CompAccept<DocParBlock>::accept(this,v); }
+
+ private:
+};
+
+
+/** Node representing a simple list */
+class DocSimpleList : public CompAccept<DocSimpleList>, public DocNode
+{
+ public:
+ DocSimpleList(DocNode *parent) { m_parent = parent; }
+ Kind kind() const { return Kind_SimpleList; }
+ void accept(DocVisitor *v) { CompAccept<DocSimpleList>::accept(this,v); }
+ int parse();
+
+ private:
+};
+
+/** Node representing a Html list */
+class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode
+{
+ public:
+ enum Type { Unordered, Ordered };
+ DocHtmlList(DocNode *parent,const HtmlAttribList &attribs,Type t) :
+ m_type(t), m_attribs(attribs) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlList; }
+ Type type() const { return m_type; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlList>::accept(this,v); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ int parse();
+ int parseXml();
+
+ private:
+ Type m_type;
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a simple section */
+class DocSimpleSect : public CompAccept<DocSimpleSect>, public DocNode
+{
+ public:
+ enum Type
+ {
+ Unknown, See, Return, Author, Authors, Version, Since, Date,
+ Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs
+ };
+ DocSimpleSect(DocNode *parent,Type t);
+ virtual ~DocSimpleSect();
+ Kind kind() const { return Kind_SimpleSect; }
+ Type type() const { return m_type; }
+ QCString typeString() const;
+ void accept(DocVisitor *v);
+ int parse(bool userTitle,bool needsSeparator);
+ int parseRcs();
+ int parseXml();
+ void appendLinkWord(const QCString &word);
+
+ private:
+ Type m_type;
+ DocTitle * m_title;
+};
+
+/** Node representing a separator between two simple sections of the
+ * same type.
+ */
+class DocSimpleSectSep : public DocNode
+{
+ public:
+ DocSimpleSectSep(DocNode *parent) { m_parent = parent; }
+ Kind kind() const { return Kind_SimpleSectSep; }
+ void accept(DocVisitor *v) { v->visit(this); }
+
+ private:
+};
+
+/** Node representing a parameter section */
+class DocParamSect : public CompAccept<DocParamSect>, public DocNode
+{
+ friend class DocParamList;
+ public:
+ enum Type
+ {
+ Unknown, Param, RetVal, Exception, TemplateParam
+ };
+ enum Direction
+ {
+ In=1, Out=2, InOut=3, Unspecified=0
+ };
+ DocParamSect(DocNode *parent,Type t)
+ : m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE)
+ { m_parent = parent; }
+ int parse(const QCString &cmdName,bool xmlContext,Direction d);
+ Kind kind() const { return Kind_ParamSect; }
+ Type type() const { return m_type; }
+ void accept(DocVisitor *v) { CompAccept<DocParamSect>::accept(this,v); }
+ bool hasInOutSpecifier() const { return m_hasInOutSpecifier; }
+ bool hasTypeSpecifier() const { return m_hasTypeSpecifier; }
+
+ private:
+ Type m_type;
+ bool m_hasInOutSpecifier;
+ bool m_hasTypeSpecifier;
+};
+
+/** Node representing a paragraph in the documentation tree */
+class DocPara : public CompAccept<DocPara>, public DocNode
+{
+ public:
+ DocPara(DocNode *parent) :
+ m_isFirst(FALSE), m_isLast(FALSE) { m_parent = parent; }
+ int parse();
+ Kind kind() const { return Kind_Para; }
+ bool isEmpty() const { return m_children.isEmpty(); }
+ void accept(DocVisitor *v) { CompAccept<DocPara>::accept(this,v); }
+ void markFirst(bool v=TRUE) { m_isFirst=v; }
+ void markLast(bool v=TRUE) { m_isLast=v; }
+ bool isFirst() const { return m_isFirst; }
+ bool isLast() const { return m_isLast; }
+
+ int handleCommand(const QCString &cmdName);
+ int handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs);
+ int handleHtmlEndTag(const QCString &tagName);
+ int handleSimpleSection(DocSimpleSect::Type t,bool xmlContext=FALSE);
+ int handleXRefItem();
+ int handleParamSection(const QCString &cmdName,DocParamSect::Type t,
+ bool xmlContext,
+ int direction);
+ void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t);
+ void handleImage(const QCString &cmdName);
+ void handleDotFile(const QCString &cmdName);
+ void handleMscFile(const QCString &cmdName);
+ void handleDiaFile(const QCString &cmdName);
+ void handleInclude(const QCString &cmdName,DocInclude::Type t);
+ void handleLink(const QCString &cmdName,bool isJavaLink);
+ void handleCite();
+ void handleRef(const QCString &cmdName);
+ void handleSection(const QCString &cmdName);
+ void handleInheritDoc();
+ void handleVhdlFlow();
+ int handleStartCode();
+ int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level);
+
+ bool injectToken(int tok,const QCString &tokText);
+
+ private:
+ QCString m_sectionId;
+ bool m_isFirst;
+ bool m_isLast;
+};
+
+/** Node representing a parameter list. */
+class DocParamList : public DocNode
+{
+ public:
+ DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d)
+ : m_type(t), m_dir(d), m_isFirst(TRUE), m_isLast(TRUE)
+ { m_paragraphs.setAutoDelete(TRUE);
+ m_params.setAutoDelete(TRUE);
+ m_paramTypes.setAutoDelete(TRUE);
+ m_parent = parent;
+ }
+ virtual ~DocParamList() { }
+ Kind kind() const { return Kind_ParamList; }
+ const QList<DocNode> ¶meters() { return m_params; }
+ const QList<DocNode> ¶mTypes() { return m_paramTypes; }
+ DocParamSect::Type type() const { return m_type; }
+ DocParamSect::Direction direction() const { return m_dir; }
+ void markFirst(bool b=TRUE) { m_isFirst=b; }
+ void markLast(bool b=TRUE) { m_isLast=b; }
+ bool isFirst() const { return m_isFirst; }
+ bool isLast() const { return m_isLast; }
+ void accept(DocVisitor *v)
+ {
+ v->visitPre(this);
+ QListIterator<DocPara> cli(m_paragraphs);
+ DocNode *n;
+ for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
+ v->visitPost(this);
+ }
+ int parse(const QCString &cmdName);
+ int parseXml(const QCString ¶mName);
+
+ private:
+ QList<DocPara> m_paragraphs;
+ QList<DocNode> m_params;
+ QList<DocNode> m_paramTypes;
+ DocParamSect::Type m_type;
+ DocParamSect::Direction m_dir;
+ bool m_isFirst;
+ bool m_isLast;
+};
+
+/** Node representing a simple list item */
+class DocSimpleListItem : public DocNode
+{
+ public:
+ DocSimpleListItem(DocNode *parent)
+ { m_paragraph=new DocPara(this); m_parent = parent; }
+ int parse();
+ virtual ~DocSimpleListItem() { delete m_paragraph; }
+ Kind kind() const { return Kind_SimpleListItem; }
+ void accept(DocVisitor *v)
+ {
+ v->visitPre(this);
+ m_paragraph->accept(v);
+ v->visitPost(this);
+ }
+
+ private:
+ DocPara *m_paragraph;
+};
+
+/** Node representing a HTML list item */
+class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode
+{
+ public:
+ DocHtmlListItem(DocNode *parent,const HtmlAttribList &attribs,int num) :
+ m_attribs(attribs), m_itemNum(num) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlListItem; }
+ int itemNumber() const { return m_itemNum; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlListItem>::accept(this,v); }
+ int parse();
+ int parseXml();
+
+ private:
+ HtmlAttribList m_attribs;
+ int m_itemNum;
+};
+
+/** Node representing a HTML description data */
+class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode
+{
+ public:
+ DocHtmlDescData(DocNode *parent) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlDescData; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlDescData>::accept(this,v); }
+ int parse();
+
+ private:
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a HTML table cell */
+class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
+{
+ friend class DocHtmlTable;
+ public:
+ enum Alignment { Left, Right, Center };
+ DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) :
+ m_isHeading(isHeading),
+ m_isFirst(FALSE), m_isLast(FALSE), m_attribs(attribs),
+ m_rowIdx(-1), m_colIdx(-1) { m_parent = parent; }
+ bool isHeading() const { return m_isHeading; }
+ bool isFirst() const { return m_isFirst; }
+ bool isLast() const { return m_isLast; }
+ Kind kind() const { return Kind_HtmlCell; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlCell>::accept(this,v); }
+ void markFirst(bool v=TRUE) { m_isFirst=v; }
+ void markLast(bool v=TRUE) { m_isLast=v; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ int parse();
+ int parseXml();
+ int rowIndex() const { return m_rowIdx; }
+ int columnIndex() const { return m_colIdx; }
+ int rowSpan() const;
+ int colSpan() const;
+ Alignment alignment() const;
+
+ private:
+ void setRowIndex(int idx) { m_rowIdx = idx; }
+ void setColumnIndex(int idx) { m_colIdx = idx; }
+ bool m_isHeading;
+ bool m_isFirst;
+ bool m_isLast;
+ HtmlAttribList m_attribs;
+ int m_rowIdx;
+ int m_colIdx;
+};
+
+/** Node representing a HTML table caption */
+class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode
+{
+ public:
+ DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs) :
+ m_attribs(attribs) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlCaption; }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlCaption>::accept(this,v); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ int parse();
+
+ private:
+ HtmlAttribList m_attribs;
+};
+
+/** Node representing a HTML table row */
+class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
+{
+ friend class DocHtmlTable;
+ public:
+ DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) :
+ m_attribs(attribs), m_visibleCells(-1), m_rowIdx(-1) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlRow; }
+ uint numCells() const { return m_children.count(); }
+ void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ int parse();
+ int parseXml(bool header);
+ bool isHeading() const { return m_children.count()>0 &&
+ ((DocHtmlCell*)m_children.getFirst())->isHeading();
+ }
+ void setVisibleCells(int n) { m_visibleCells = n; }
+ int visibleCells() const { return m_visibleCells; }
+ int rowIndex() const { return m_rowIdx; }
+
+ private:
+ void setRowIndex(int idx) { m_rowIdx = idx; }
+ HtmlAttribList m_attribs;
+ int m_visibleCells;
+ int m_rowIdx;
+};
+
+/** Node representing a HTML table */
+class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
+{
+ public:
+ DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs)
+ : m_attribs(attribs) { m_caption=0; m_parent = parent; }
+ ~DocHtmlTable() { delete m_caption; }
+ Kind kind() const { return Kind_HtmlTable; }
+ uint numRows() const { return m_children.count(); }
+ bool hasCaption() { return m_caption!=0; }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+ int parse();
+ int parseXml();
+ uint numColumns() const { return m_numCols; }
+ void accept(DocVisitor *v);
+
+ private:
+ void computeTableGrid();
+ DocHtmlCaption *m_caption;
+ HtmlAttribList m_attribs;
+ int m_numCols;
+};
+
+/** Node representing an HTML blockquote */
+class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote>, public DocNode
+{
+ public:
+ DocHtmlBlockQuote(DocNode *parent,const HtmlAttribList &attribs)
+ : m_attribs(attribs) { m_parent = parent; }
+ Kind kind() const { return Kind_HtmlBlockQuote; }
+ int parse();
+ void accept(DocVisitor *v) { CompAccept<DocHtmlBlockQuote>::accept(this,v); }
+ const HtmlAttribList &attribs() const { return m_attribs; }
+
+ private:
+ HtmlAttribList m_attribs;
+};
+
+/** Root node of a text fragment */
+class DocText : public CompAccept<DocText>, public DocNode
+{
+ public:
+ DocText() {}
+ Kind kind() const { return Kind_Text; }
+ void accept(DocVisitor *v) { CompAccept<DocText>::accept(this,v); }
+ void parse();
+ bool isEmpty() const { return m_children.isEmpty(); }
+};
+
+/** Root node of documentation tree */
+class DocRoot : public CompAccept<DocRoot>, public DocNode
+{
+ public:
+ DocRoot(bool indent,bool sl) : m_indent(indent), m_singleLine(sl) {}
+ Kind kind() const { return Kind_Root; }
+ void accept(DocVisitor *v) { CompAccept<DocRoot>::accept(this,v); }
+ void parse();
+ bool indent() const { return m_indent; }
+ bool singleLine() const { return m_singleLine; }
+ bool isEmpty() const { return m_children.isEmpty(); }
+
+ private:
+ bool m_indent;
+ bool m_singleLine;
+};
+
+
+#endif
diff --git a/src/docsets.cpp b/src/docsets.cpp
new file mode 100644
index 0000000..52d24bb
--- /dev/null
+++ b/src/docsets.cpp
@@ -0,0 +1,538 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfile.h>
+#include "docsets.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "groupdef.h"
+#include "classdef.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "namespacedef.h"
+#include "util.h"
+
+DocSets::DocSets() : m_nodes(17), m_scopes(17)
+{
+ m_nf = 0;
+ m_tf = 0;
+ m_dc = 0;
+ m_id = 0;
+ m_nodes.setAutoDelete(TRUE);
+}
+
+DocSets::~DocSets()
+{
+ delete m_nf;
+ delete m_tf;
+}
+
+void DocSets::initialize()
+{
+ // -- get config options
+ QCString projectName = Config_getString("PROJECT_NAME");
+ if (projectName.isEmpty()) projectName="root";
+ QCString bundleId = Config_getString("DOCSET_BUNDLE_ID");
+ if (bundleId.isEmpty()) bundleId="org.doxygen.Project";
+ QCString feedName = Config_getString("DOCSET_FEEDNAME");
+ if (feedName.isEmpty()) feedName="FeedName";
+ QCString publisherId = Config_getString("DOCSET_PUBLISHER_ID");
+ if (publisherId.isEmpty()) publisherId="PublisherId";
+ QCString publisherName = Config_getString("DOCSET_PUBLISHER_NAME");
+ if (publisherName.isEmpty()) publisherName="PublisherName";
+ QCString projectNumber = Config_getString("PROJECT_NUMBER");
+ if (projectNumber.isEmpty()) projectNumber="ProjectNumber";
+
+ // -- write Makefile
+ {
+ QCString mfName = Config_getString("HTML_OUTPUT") + "/Makefile";
+ QFile makefile(mfName);
+ if (!makefile.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",mfName.data());
+ exit(1);
+ }
+ FTextStream ts(&makefile);
+
+ ts << "DOCSET_NAME=" << bundleId << ".docset\n"
+ "DOCSET_CONTENTS=$(DOCSET_NAME)/Contents\n"
+ "DOCSET_RESOURCES=$(DOCSET_CONTENTS)/Resources\n"
+ "DOCSET_DOCUMENTS=$(DOCSET_RESOURCES)/Documents\n"
+ "DESTDIR=~/Library/Developer/Shared/Documentation/DocSets\n"
+ "XCODE_INSTALL=\"$(shell xcode-select -print-path)\"\n"
+ "\n"
+ "all: docset\n"
+ "\n"
+ "docset:\n"
+ "\tmkdir -p $(DOCSET_DOCUMENTS)\n"
+ "\tcp Nodes.xml $(DOCSET_RESOURCES)\n"
+ "\tcp Tokens.xml $(DOCSET_RESOURCES)\n"
+ "\tcp Info.plist $(DOCSET_CONTENTS)\n"
+ "\ttar --exclude $(DOCSET_NAME) \\\n"
+ "\t --exclude Nodes.xml \\\n"
+ "\t --exclude Tokens.xml \\\n"
+ "\t --exclude Info.plist \\\n"
+ "\t --exclude Makefile -c -f - . \\\n"
+ "\t | (cd $(DOCSET_DOCUMENTS); tar xvf -)\n"
+ "\t$(XCODE_INSTALL)/usr/bin/docsetutil index $(DOCSET_NAME)\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Nodes.xml\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Info.plist\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Makefile\n"
+ "\trm -f $(DOCSET_RESOURCES)/Nodes.xml\n"
+ "\trm -f $(DOCSET_RESOURCES)/Tokens.xml\n"
+ "\n"
+ "clean:\n"
+ "\trm -rf $(DOCSET_NAME)\n"
+ "\n"
+ "install: docset\n"
+ "\tmkdir -p $(DESTDIR)\n"
+ "\tcp -R $(DOCSET_NAME) $(DESTDIR)\n"
+ "\n"
+ "uninstall:\n"
+ "\trm -rf $(DESTDIR)/$(DOCSET_NAME)\n"
+ "\n"
+ "always:\n";
+ }
+
+ // -- write Info.plist
+ {
+ QCString plName = Config_getString("HTML_OUTPUT") + "/Info.plist";
+ QFile plist(plName);
+ if (!plist.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",plName.data());
+ exit(1);
+ }
+ FTextStream ts(&plist);
+
+ ts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"\n"
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ " <key>CFBundleName</key>\n"
+ " <string>" << projectName << "</string>\n"
+ " <key>CFBundleIdentifier</key>\n"
+ " <string>" << bundleId << "</string>\n"
+ " <key>CFBundleVersion</key>\n"
+ " <string>" << projectNumber << "</string>\n"
+ " <key>DocSetFeedName</key>\n"
+ " <string>" << feedName << "</string>\n"
+ " <key>DocSetPublisherIdentifier</key>\n"
+ " <string>" << publisherId << "</string>\n"
+ " <key>DocSetPublisherName</key>\n"
+ " <string>" << publisherName << "</string>\n"
+ // markers for Dash
+ " <key>DashDocSetFamily</key>\n"
+ " <string>doxy</string>\n"
+ " <key>DocSetPlatformFamily</key>\n"
+ " <string>doxygen</string>\n"
+ "</dict>\n"
+ "</plist>\n";
+ }
+
+ // -- start Nodes.xml
+ QCString notes = Config_getString("HTML_OUTPUT") + "/Nodes.xml";
+ m_nf = new QFile(notes);
+ if (!m_nf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",notes.data());
+ exit(1);
+ }
+ //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
+ QCString indexName="index";
+ m_nts.setDevice(m_nf);
+ m_nts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ m_nts << "<DocSetNodes version=\"1.0\">" << endl;
+ m_nts << " <TOC>" << endl;
+ m_nts << " <Node>" << endl;
+ m_nts << " <Name>Root</Name>" << endl;
+ m_nts << " <Path>" << indexName << Doxygen::htmlFileExtension << "</Path>" << endl;
+ m_nts << " <Subnodes>" << endl;
+ m_dc = 1;
+ m_firstNode.resize(m_dc);
+ m_firstNode.at(0)=TRUE;
+
+ QCString tokens = Config_getString("HTML_OUTPUT") + "/Tokens.xml";
+ m_tf = new QFile(tokens);
+ if (!m_tf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",tokens.data());
+ exit(1);
+ }
+ m_tts.setDevice(m_tf);
+ m_tts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ m_tts << "<Tokens version=\"1.0\">" << endl;
+}
+
+void DocSets::finalize()
+{
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_dc--;
+ m_nts << " </Subnodes>" << endl;
+ m_nts << " </Node>" << endl;
+ m_nts << " </TOC>" << endl;
+ m_nts << "</DocSetNodes>" << endl;
+ m_nf->close();
+ delete m_nf;
+ m_nf=0;
+
+ m_tts << "</Tokens>" << endl;
+ m_tf->close();
+ delete m_tf;
+ m_tf=0;
+}
+
+QCString DocSets::indent()
+{
+ QCString result;
+ result.fill(' ',(m_dc+2)*2);
+ return result;
+}
+
+void DocSets::incContentsDepth()
+{
+ //printf("DocSets::incContentsDepth() m_dc=%d\n",m_dc);
+ ++m_dc;
+ m_nts << indent() << "<Subnodes>" << endl;
+ m_firstNode.resize(m_dc);
+ if (m_dc>0)
+ {
+ m_firstNode.at(m_dc-1)=TRUE;
+ }
+}
+
+void DocSets::decContentsDepth()
+{
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_nts << indent() << "</Subnodes>" << endl;
+ --m_dc;
+ //printf("DocSets::decContentsDepth() m_dc=%d\n",m_dc);
+}
+
+void DocSets::addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool /* separateIndex */,
+ bool /* addToNavIndex */,
+ Definition * /*def*/)
+{
+ (void)isDir;
+ //printf("DocSets::addContentsItem(%s) m_dc=%d\n",name,m_dc);
+ if (ref==0)
+ {
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_firstNode.at(m_dc-1)=FALSE;
+ m_nts << indent() << " <Node>" << endl;
+ m_nts << indent() << " <Name>" << convertToXML(name) << "</Name>" << endl;
+ if (file && file[0]=='^') // URL marker
+ {
+ m_nts << indent() << " <URL>" << convertToXML(&file[1])
+ << "</URL>" << endl;
+ }
+ else // relative file
+ {
+ m_nts << indent() << " <Path>";
+ if (file && file[0]=='!') // user specified file
+ {
+ m_nts << convertToXML(&file[1]);
+ }
+ else if (file) // doxygen generated file
+ {
+ m_nts << file << Doxygen::htmlFileExtension;
+ }
+ m_nts << "</Path>" << endl;
+ if (file && anchor)
+ {
+ m_nts << indent() << " <Anchor>" << anchor << "</Anchor>" << endl;
+ }
+ }
+ }
+}
+
+void DocSets::addIndexItem(Definition *context,MemberDef *md,
+ const char *,const char *)
+{
+ if (md==0 && context==0) return;
+
+ FileDef *fd = 0;
+ ClassDef *cd = 0;
+ NamespaceDef *nd = 0;
+
+ if (md)
+ {
+ fd = md->getFileDef();
+ cd = md->getClassDef();
+ nd = md->getNamespaceDef();
+ if (!md->isLinkable()) return; // internal symbol
+ }
+
+ QCString scope;
+ QCString type;
+ QCString decl;
+
+ // determine language
+ QCString lang;
+ SrcLangExt langExt = SrcLangExt_Cpp;
+ if (md)
+ {
+ langExt = md->getLanguage();
+ }
+ else if (context)
+ {
+ langExt = context->getLanguage();
+ }
+ switch (langExt)
+ {
+ case SrcLangExt_Cpp:
+ case SrcLangExt_ObjC:
+ {
+ if (md && (md->isObjCMethod() || md->isObjCProperty()))
+ lang="occ"; // Objective C/C++
+ else if (fd && fd->name().right(2).lower()==".c")
+ lang="c"; // Plain C
+ else if (cd==0 && nd==0)
+ lang="c"; // Plain C symbol outside any class or namespace
+ else
+ lang="cpp"; // C++
+ }
+ break;
+ case SrcLangExt_IDL: lang="idl"; break; // IDL
+ case SrcLangExt_CSharp: lang="csharp"; break; // C#
+ case SrcLangExt_PHP: lang="php"; break; // PHP4/5
+ case SrcLangExt_D: lang="d"; break; // D
+ case SrcLangExt_Java: lang="java"; break; // Java
+ case SrcLangExt_JS: lang="javascript"; break; // Javascript
+ case SrcLangExt_Python: lang="python"; break; // Python
+ case SrcLangExt_Fortran: lang="fortran"; break; // Fortran
+ case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL
+ case SrcLangExt_XML: lang="xml"; break; // DBUS XML
+ case SrcLangExt_Tcl: lang="tcl"; break; // Tcl
+ case SrcLangExt_Markdown:lang="markdown"; break; // Markdown
+ case SrcLangExt_Unknown: lang="unknown"; break; // should not happen!
+ }
+
+ if (md)
+ {
+ if (context==0)
+ {
+ if (md->getGroupDef())
+ context = md->getGroupDef();
+ else if (md->getFileDef())
+ context = md->getFileDef();
+ }
+ if (context==0) return; // should not happen
+
+ switch (md->memberType())
+ {
+ case MemberType_Define:
+ type="macro"; break;
+ case MemberType_Function:
+ if (cd && (cd->compoundType()==ClassDef::Interface ||
+ cd->compoundType()==ClassDef::Class))
+ {
+ if (md->isStatic())
+ type="clm"; // class member
+ else
+ type="instm"; // instance member
+ }
+ else if (cd && cd->compoundType()==ClassDef::Protocol)
+ {
+ if (md->isStatic())
+ type="intfcm"; // interface class member
+ else
+ type="intfm"; // interface member
+ }
+ else
+ type="func";
+ break;
+ case MemberType_Variable:
+ type="data"; break;
+ case MemberType_Typedef:
+ type="tdef"; break;
+ case MemberType_Enumeration:
+ type="enum"; break;
+ case MemberType_EnumValue:
+ type="econst"; break;
+ //case MemberDef::Prototype:
+ // type="prototype"; break;
+ case MemberType_Signal:
+ type="signal"; break;
+ case MemberType_Slot:
+ type="slot"; break;
+ case MemberType_Friend:
+ type="ffunc"; break;
+ case MemberType_DCOP:
+ type="dcop"; break;
+ case MemberType_Property:
+ if (cd && cd->compoundType()==ClassDef::Protocol)
+ type="intfp"; // interface property
+ else
+ type="instp"; // instance property
+ break;
+ case MemberType_Event:
+ type="event"; break;
+ case MemberType_Interface:
+ type="ifc"; break;
+ case MemberType_Service:
+ type="svc"; break;
+ }
+ cd = md->getClassDef();
+ nd = md->getNamespaceDef();
+ if (cd)
+ {
+ scope = cd->qualifiedName();
+ }
+ else if (nd)
+ {
+ scope = nd->name();
+ }
+ MemberDef *declMd = md->memberDeclaration();
+ if (declMd==0) declMd = md;
+ {
+ fd = md->getFileDef();
+ if (fd)
+ {
+ decl = fd->name();
+ }
+ }
+ writeToken(m_tts,md,type,lang,scope,md->anchor(),decl);
+ }
+ else if (context && context->isLinkable())
+ {
+ if (fd==0 && context->definitionType()==Definition::TypeFile)
+ {
+ fd = (FileDef*)context;
+ }
+ if (cd==0 && context->definitionType()==Definition::TypeClass)
+ {
+ cd = (ClassDef*)context;
+ }
+ if (nd==0 && context->definitionType()==Definition::TypeNamespace)
+ {
+ nd = (NamespaceDef*)context;
+ }
+ if (fd)
+ {
+ type="file";
+ }
+ else if (cd)
+ {
+ scope = cd->qualifiedName();
+ if (cd->isTemplate())
+ {
+ type="tmplt";
+ }
+ else if (cd->compoundType()==ClassDef::Protocol)
+ {
+ type="intf";
+ if (scope.right(2)=="-p") scope=scope.left(scope.length()-2);
+ }
+ else if (cd->compoundType()==ClassDef::Interface)
+ {
+ type="cl";
+ }
+ else if (cd->compoundType()==ClassDef::Category)
+ {
+ type="cat";
+ }
+ else
+ {
+ type = "cl";
+ }
+ IncludeInfo *ii = cd->includeInfo();
+ if (ii)
+ {
+ decl=ii->includeName;
+ if (decl.isEmpty())
+ {
+ decl=ii->local;
+ }
+ }
+ }
+ else if (nd)
+ {
+ scope = nd->name();
+ type = "ns";
+ }
+ if (m_scopes.find(context->getOutputFileBase())==0)
+ {
+ writeToken(m_tts,context,type,lang,scope,0,decl);
+ m_scopes.append(context->getOutputFileBase(),(void*)0x8);
+ }
+ }
+}
+
+void DocSets::writeToken(FTextStream &t,
+ const Definition *d,
+ const QCString &type,
+ const QCString &lang,
+ const char *scope,
+ const char *anchor,
+ const char *decl)
+{
+ t << " <Token>" << endl;
+ t << " <TokenIdentifier>" << endl;
+ QCString name = d->name();
+ if (name.right(2)=="-p") name=name.left(name.length()-2);
+ t << " <Name>" << convertToXML(name) << "</Name>" << endl;
+ if (!lang.isEmpty())
+ {
+ t << " <APILanguage>" << lang << "</APILanguage>" << endl;
+ }
+ if (!type.isEmpty())
+ {
+ t << " <Type>" << type << "</Type>" << endl;
+ }
+ if (scope)
+ {
+ t << " <Scope>" << convertToXML(scope) << "</Scope>" << endl;
+ }
+ t << " </TokenIdentifier>" << endl;
+ t << " <Path>" << d->getOutputFileBase()
+ << Doxygen::htmlFileExtension << "</Path>" << endl;
+ if (anchor)
+ {
+ t << " <Anchor>" << anchor << "</Anchor>" << endl;
+ }
+ QCString tooltip = d->briefDescriptionAsTooltip();
+ if (!tooltip.isEmpty())
+ {
+ t << " <Abstract>" << convertToXML(tooltip) << "</Abstract>" << endl;
+ }
+ if (decl)
+ {
+ t << " <DeclaredIn>" << convertToXML(decl) << "</DeclaredIn>" << endl;
+ }
+ t << " </Token>" << endl;
+}
+
+void DocSets::addIndexFile(const char *name)
+{
+ (void)name;
+}
+
diff --git a/src/docsets.h b/src/docsets.h
new file mode 100644
index 0000000..eac5bfc
--- /dev/null
+++ b/src/docsets.h
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DOCSETS_H
+#define DOCSETS_H
+
+#include "sortdict.h"
+#include "ftextstream.h"
+#include "index.h"
+
+class QFile;
+class Definition;
+
+/** A class that generates docset files.
+ *
+ * These files can be used to create context help
+ * for use within Apple's Xcode 3.0 development environment
+ */
+class DocSets : public IndexIntf
+{
+
+ public:
+ DocSets();
+ ~DocSets();
+ void initialize();
+ void finalize();
+ void incContentsDepth();
+ void decContentsDepth();
+ void addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool separateIndex,
+ bool addToNavIndex,
+ Definition *def
+ );
+ void addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor,const char *title);
+ void addIndexFile(const char *name);
+ void addImageFile(const char *) {}
+ void addStyleSheetFile(const char *) {}
+
+ private:
+ void writeToken(FTextStream &t, const Definition *d,
+ const QCString &type, const QCString &lang,
+ const char *scope=0, const char *anchor=0,
+ const char *decl=0);
+ struct NodeDef
+ {
+ NodeDef(bool d,const QCString &n,const QCString &r,
+ const QCString &f,const QCString &a,int i) :
+ isDir(d), name(n), ref(r), file(f), anchor(a),id(i) {}
+ bool isDir;
+ QCString name;
+ QCString ref;
+ QCString file;
+ QCString anchor;
+ int id;
+ };
+ QCString indent();
+ QFile *m_nf;
+ QFile *m_tf;
+ FTextStream m_nts;
+ FTextStream m_tts;
+ int m_dc;
+ int m_id;
+ QArray<bool> m_firstNode;
+ SDict<NodeDef> m_nodes;
+ SDict<void> m_scopes;
+};
+
+#endif /* DOCSETS_H */
+
diff --git a/src/doctokenizer.h b/src/doctokenizer.h
new file mode 100644
index 0000000..c95230b
--- /dev/null
+++ b/src/doctokenizer.h
@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ * $Id: $
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DOCTOKENIZER_H
+#define _DOCTOKENIZER_H
+
+#include <qcstring.h>
+#include <qlist.h>
+#include <stdio.h>
+#include "htmlattrib.h"
+
+class Definition;
+class MemberGroup;
+
+enum Tokens
+{
+ TK_WORD = 1,
+ TK_LNKWORD = 2,
+ TK_WHITESPACE = 3,
+ TK_LISTITEM = 4,
+ TK_ENDLIST = 5,
+ TK_COMMAND = 6,
+ TK_HTMLTAG = 7,
+ TK_SYMBOL = 8,
+ TK_NEWPARA = 9,
+ TK_RCSTAG = 10,
+ TK_URL = 11,
+
+ RetVal_OK = 0x10000,
+ RetVal_SimpleSec = 0x10001,
+ RetVal_ListItem = 0x10002,
+ RetVal_Section = 0x10003,
+ RetVal_Subsection = 0x10004,
+ RetVal_Subsubsection = 0x10005,
+ RetVal_Paragraph = 0x10006,
+ RetVal_SubParagraph = 0x10007,
+ RetVal_EndList = 0x10008,
+ RetVal_EndPre = 0x10009,
+ RetVal_DescData = 0x1000A,
+ RetVal_DescTitle = 0x1000B,
+ RetVal_EndDesc = 0x1000C,
+ RetVal_TableRow = 0x1000D,
+ RetVal_TableCell = 0x1000E,
+ RetVal_TableHCell = 0x1000F,
+ RetVal_EndTable = 0x10010,
+ RetVal_Internal = 0x10011,
+ RetVal_SwitchLang = 0x10012,
+ RetVal_CloseXml = 0x10013,
+ RetVal_EndBlockQuote = 0x10014,
+ RetVal_CopyDoc = 0x10015,
+ RetVal_EndInternal = 0x10016,
+ RetVal_EndParBlock = 0x10017
+};
+
+/** @brief Data associated with a token used by the comment block parser. */
+struct TokenInfo
+{
+ // unknown token
+ char unknownChar;
+
+ // command token
+ QCString name;
+
+ // command text (RCS tag)
+ QCString text;
+
+ // comment blocks
+
+ // list token info
+ bool isEnumList;
+ int indent;
+
+ // sections
+ QCString sectionId;
+
+ // simple section
+ QCString simpleSectName;
+ QCString simpleSectText;
+
+ // verbatim fragment
+ QCString verb;
+
+ // xrefitem
+ int id;
+
+ // html tag
+ HtmlAttribList attribs;
+ bool endTag;
+ bool emptyTag;
+
+ // whitespace
+ QCString chars;
+
+ // url
+ bool isEMailAddr;
+
+ // param attributes
+ enum ParamDir { In=1, Out=2, InOut=3, Unspecified=0 };
+ ParamDir paramDir;
+};
+
+// globals
+extern TokenInfo *g_token;
+extern int doctokenizerYYlineno;
+extern FILE *doctokenizerYYin;
+
+// helper functions
+const char *tokToString(int token);
+
+// operations on the scanner
+void doctokenizerYYFindSections(const char *input,Definition *d,
+ MemberGroup *mg,const char *fileName);
+void doctokenizerYYinit(const char *input,const char *fileName);
+void doctokenizerYYcleanup();
+void doctokenizerYYpushContext();
+bool doctokenizerYYpopContext();
+int doctokenizerYYlex();
+void doctokenizerYYsetStatePara();
+void doctokenizerYYsetStateTitle();
+void doctokenizerYYsetStateTitleAttrValue();
+void doctokenizerYYsetStateCode();
+void doctokenizerYYsetStateXmlCode();
+void doctokenizerYYsetStateHtmlOnly();
+void doctokenizerYYsetStateManOnly();
+void doctokenizerYYsetStateLatexOnly();
+void doctokenizerYYsetStateXmlOnly();
+void doctokenizerYYsetStateDbOnly();
+void doctokenizerYYsetStateRtfOnly();
+void doctokenizerYYsetStateVerbatim();
+void doctokenizerYYsetStateDot();
+void doctokenizerYYsetStateMsc();
+void doctokenizerYYsetStateParam();
+void doctokenizerYYsetStateXRefItem();
+void doctokenizerYYsetStateFile();
+void doctokenizerYYsetStatePattern();
+void doctokenizerYYsetStateLink();
+void doctokenizerYYsetStateCite();
+void doctokenizerYYsetStateRef();
+void doctokenizerYYsetStateInternalRef();
+void doctokenizerYYsetStateText();
+void doctokenizerYYsetStateSkipTitle();
+void doctokenizerYYsetStateAnchor();
+void doctokenizerYYsetInsidePre(bool b);
+void doctokenizerYYpushBackHtmlTag(const char *tag);
+void doctokenizerYYsetStateSnippet();
+void doctokenizerYYstartAutoList();
+void doctokenizerYYendAutoList();
+void doctokenizerYYsetStatePlantUML();
+
+#endif
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
new file mode 100644
index 0000000..ea4a1a4
--- /dev/null
+++ b/src/doctokenizer.l
@@ -0,0 +1,1455 @@
+/******************************************************************************
+ *
+ * $Id: $
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+
+%{
+
+#include <ctype.h>
+
+#include <qfile.h>
+#include <qstring.h>
+#include <qstack.h>
+#include <qdict.h>
+#include <qregexp.h>
+
+#include "doctokenizer.h"
+#include "cmdmapper.h"
+#include "config.h"
+#include "message.h"
+#include "section.h"
+#include "membergroup.h"
+#include "definition.h"
+#include "doxygen.h"
+#include "portable.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+//--------------------------------------------------------------------------
+
+// context for tokenizer phase
+static int g_commentState;
+TokenInfo *g_token = 0;
+static int g_inputPos = 0;
+static const char *g_inputString;
+static QCString g_fileName;
+static bool g_insidePre;
+
+// context for section finding phase
+static Definition *g_definition;
+static MemberGroup *g_memberGroup;
+static QCString g_secLabel;
+static QCString g_secTitle;
+static SectionInfo::SectionType g_secType;
+static QCString g_endMarker;
+static int g_autoListLevel;
+
+struct DocLexerContext
+{
+ TokenInfo *token;
+ int rule;
+ int autoListLevel;
+ int inputPos;
+ const char *inputString;
+ YY_BUFFER_STATE state;
+};
+
+static QStack<DocLexerContext> g_lexerStack;
+
+//--------------------------------------------------------------------------
+
+void doctokenizerYYpushContext()
+{
+ DocLexerContext *ctx = new DocLexerContext;
+ ctx->rule = YY_START;
+ ctx->autoListLevel = g_autoListLevel;
+ ctx->token = g_token;
+ ctx->inputPos = g_inputPos;
+ ctx->inputString = g_inputString;
+ ctx->state = YY_CURRENT_BUFFER;
+ g_lexerStack.push(ctx);
+ yy_switch_to_buffer(yy_create_buffer(doctokenizerYYin, YY_BUF_SIZE));
+}
+
+bool doctokenizerYYpopContext()
+{
+ if (g_lexerStack.isEmpty()) return FALSE;
+ DocLexerContext *ctx = g_lexerStack.pop();
+ g_autoListLevel = ctx->autoListLevel;
+ g_inputPos = ctx->inputPos;
+ g_inputString = ctx->inputString;
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(ctx->state);
+ BEGIN(ctx->rule);
+ delete ctx;
+ return TRUE;
+}
+
+
+//--------------------------------------------------------------------------
+
+const char *tokToString(int token)
+{
+ switch (token)
+ {
+ case 0: return "TK_EOF";
+ case TK_WORD: return "TK_WORD";
+ case TK_LNKWORD: return "TK_LNKWORD";
+ case TK_WHITESPACE: return "TK_WHITESPACE";
+ case TK_LISTITEM: return "TK_LISTITEM";
+ case TK_ENDLIST: return "TK_ENDLIST";
+ case TK_COMMAND: return "TK_COMMAND";
+ case TK_HTMLTAG: return "TK_HTMLTAG";
+ case TK_SYMBOL: return "TK_SYMBOL";
+ case TK_NEWPARA: return "TK_NEWPARA";
+ case TK_RCSTAG: return "TK_RCSTAG";
+ case TK_URL: return "TK_URL";
+ }
+ return "ERROR";
+}
+
+static int computeIndent(const char *str,int length)
+{
+ int i;
+ int indent=0;
+ static int tabSize=Config_getInt("TAB_SIZE");
+ for (i=0;i<length;i++)
+ {
+ if (str[i]=='\t')
+ {
+ indent+=tabSize - (indent%tabSize);
+ }
+ else if (str[i]=='\n')
+ {
+ indent=0;
+ }
+ else
+ {
+ indent++;
+ }
+ }
+ return indent;
+}
+
+//--------------------------------------------------------------------------
+
+static void processSection()
+{
+ //printf("%s: found section/anchor with name `%s'\n",g_fileName.data(),g_secLabel.data());
+ QCString file;
+ if (g_memberGroup)
+ {
+ file = g_memberGroup->parent()->getOutputFileBase();
+ }
+ else if (g_definition)
+ {
+ file = g_definition->getOutputFileBase();
+ }
+ else
+ {
+ warn(g_fileName,yylineno,"Found section/anchor %s without context\n",g_secLabel.data());
+ }
+ SectionInfo *si=0;
+ if ((si=Doxygen::sectionDict->find(g_secLabel)))
+ {
+ si->fileName = file;
+ //si = new SectionInfo(file,g_secLabel,g_secTitle,g_secType);
+ //Doxygen::sectionDict.insert(g_secLabel,si);
+ }
+}
+
+static void handleHtmlTag()
+{
+ QCString tagText=yytext;
+ g_token->attribs.clear();
+ g_token->endTag = FALSE;
+ g_token->emptyTag = FALSE;
+
+ // Check for end tag
+ int startNamePos=1;
+ if (tagText.at(1)=='/')
+ {
+ g_token->endTag = TRUE;
+ startNamePos++;
+ }
+
+ // Parse the name portion
+ int i = startNamePos;
+ for (i=startNamePos; i < (int)yyleng; i++)
+ {
+ // Check for valid HTML/XML name chars (including namespaces)
+ char c = tagText.at(i);
+ if (!(isalnum(c) || c=='-' || c=='_' || c==':')) break;
+ }
+ g_token->name = tagText.mid(startNamePos,i-startNamePos);
+
+ // Parse the attributes. Each attribute is a name, value pair
+ // The result is stored in g_token->attribs.
+ int startName,endName,startAttrib,endAttrib;
+ while (i<(int)yyleng)
+ {
+ char c=tagText.at(i);
+ // skip spaces
+ while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); }
+ // check for end of the tag
+ if (c == '>') break;
+ // Check for XML style "empty" tag.
+ if (c == '/')
+ {
+ g_token->emptyTag = TRUE;
+ break;
+ }
+ startName=i;
+ // search for end of name
+ while (i<(int)yyleng && !isspace(c) && c!='=') { c=tagText.at(++i); }
+ endName=i;
+ HtmlAttrib opt;
+ opt.name = tagText.mid(startName,endName-startName).lower();
+ // skip spaces
+ while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); }
+ if (tagText.at(i)=='=') // option has value
+ {
+ c=tagText.at(++i);
+ // skip spaces
+ while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); }
+ if (tagText.at(i)=='\'') // option '...'
+ {
+ c=tagText.at(++i);
+ startAttrib=i;
+
+ // search for matching quote
+ while (i<(int)yyleng && c!='\'') { c=tagText.at(++i); }
+ endAttrib=i;
+ if (i<(int)yyleng) c=tagText.at(++i);
+ }
+ else if (tagText.at(i)=='"') // option "..."
+ {
+ c=tagText.at(++i);
+ startAttrib=i;
+ // search for matching quote
+ while (i<(int)yyleng && c!='"') { c=tagText.at(++i); }
+ endAttrib=i;
+ if (i<(int)yyleng) c=tagText.at(++i);
+ }
+ else // value without any quotes
+ {
+ startAttrib=i;
+ // search for separator or end symbol
+ while (i<(int)yyleng && !isspace(c) && c!='>') { c=tagText.at(++i); }
+ endAttrib=i;
+ if (i<(int)yyleng) c=tagText.at(++i);
+ }
+ opt.value = tagText.mid(startAttrib,endAttrib-startAttrib);
+ }
+ else // start next option
+ {
+ }
+ //printf("=====> Adding option name=<%s> value=<%s>\n",
+ // opt.name.data(),opt.value.data());
+ g_token->attribs.append(&opt);
+ }
+}
+
+static QCString stripEmptyLines(const QCString &s)
+{
+ if (s.isEmpty()) return QCString();
+ int end=s.length();
+ int start=0,p=0;
+ // skip leading empty lines
+ for (;;)
+ {
+ int c;
+ while ((c=s[p]) && (c==' ' || c=='\t')) p++;
+ if (s[p]=='\n')
+ {
+ start=++p;
+ }
+ else
+ {
+ break;
+ }
+ }
+ // skip trailing empty lines
+ p=end-1;
+ if (p>=start && s.at(p)=='\n') p--;
+ while (p>=start)
+ {
+ int c;
+ while ((c=s[p]) && (c==' ' || c=='\t')) p--;
+ if (s[p]=='\n')
+ {
+ end=p;
+ }
+ else
+ {
+ break;
+ }
+ p--;
+ }
+ //printf("stripEmptyLines(%d-%d)\n",start,end);
+ return s.mid(start,end-start);
+}
+
+//--------------------------------------------------------------------------
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ const char *src=g_inputString+g_inputPos;
+ while ( c < max_size && *src ) *buf++ = *src++, c++;
+ g_inputPos+=c;
+ return c;
+}
+
+//--------------------------------------------------------------------------
+#define REAL_YY_DECL int doctokenizerYYlex (void)
+#define YY_DECL static int local_doctokinizer(void)
+#define LOCAL_YY_DECL local_doctokinizer()
+
+%}
+
+CMD ("\\"|"@")
+WS [ \t\r\n]
+NONWS [^ \t\r\n]
+BLANK [ \t\r]
+ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
+PHPTYPE [\\:a-z_A-Z0-9\x80-\xFF\-]+
+CITESCHAR [a-z_A-Z\x80-\xFF]
+CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/]*
+CITEID {CITESCHAR}*{CITEECHAR}+("."{CITESCHAR}*{CITEECHAR}+)*
+MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+
+OPTSTARS ("//"{BLANK}*)?"*"*{BLANK}*
+LISTITEM {BLANK}*[-]("#")?{WS}
+MLISTITEM {BLANK}*[+*]{WS}
+OLISTITEM {BLANK}*[1-9][0-9]*"."{BLANK}
+ENDLIST {BLANK}*"."{BLANK}*\n
+ATTRNAME [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
+ATTRIB {ATTRNAME}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><]+))?
+URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=]
+URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+
+FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+@&#]
+FILEECHAR [a-z_A-Z0-9\-\+@&#]
+HFILEMASK ("."{FILESCHAR}*{FILEECHAR}+)*
+FILEMASK ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|{HFILEMASK}
+LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"){BLANK}+)?
+VERBATIM "verbatim"{BLANK}*
+SPCMD1 {CMD}([a-z_A-Z][a-z_A-Z0-9]*|{VERBATIM}|"--"|"---")
+SPCMD2 {CMD}[\\@<>&$#%~".|]
+SPCMD3 {CMD}form#[0-9]+
+SPCMD4 {CMD}"::"
+INOUT "inout"|"in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in")
+PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]"
+TEMPCHAR [a-z_A-Z0-9.,: \t\*\&\(\)\[\]]
+FUNCCHAR [a-z_A-Z0-9,:\<\> \t\^\*\&\[\]]
+FUNCPART {FUNCCHAR}*("("{FUNCCHAR}*")"{FUNCCHAR}*)?
+SCOPESEP "::"|"#"|"."
+TEMPLPART "<"{TEMPCHAR}*">"
+ANONNS "anonymous_namespace{"[^}]*"}"
+SCOPEPRE (({ID}{TEMPLPART}?)|{ANONNS}){SCOPESEP}
+SCOPEKEYS ":"({ID}":")*
+SCOPECPP {SCOPEPRE}*(~)?{ID}{TEMPLPART}?
+SCOPEOBJC {SCOPEPRE}?{ID}{SCOPEKEYS}?
+SCOPEMASK {SCOPECPP}|{SCOPEOBJC}
+FUNCARG "("{FUNCPART}")"({BLANK}*("volatile"|"const"){BLANK})?
+OPNEW {BLANK}+"new"({BLANK}*"[]")?
+OPDEL {BLANK}+"delete"({BLANK}*"[]")?
+OPNORM {OPNEW}|{OPDEL}|"+"|"-"|"*"|"/"|"%"|"^"|"&"|"|"|"~"|"!"|"="|"<"|">"|"+="|"-="|"*="|"/="|"%="|"^="|"&="|"|="|"<<"|">>"|"<<="|">>="|"=="|"!="|"<="|">="|"&&"|"||"|"++"|"--"|","|"->*"|"->"|"[]"|"()"
+OPCAST {BLANK}+[^<(\r\n.,][^(\r\n.,]*
+OPMASK ({BLANK}*{OPNORM}{FUNCARG})
+OPMASKOPT ({BLANK}*{OPNORM}{FUNCARG}?)|({OPCAST}{FUNCARG})
+LNKWORD1 ("::"|"#")?{SCOPEMASK}
+CVSPEC {BLANK}*("const"|"volatile")
+LNKWORD2 (({SCOPEPRE}*"operator"{OPMASK})|({SCOPEPRE}"operator"{OPMASKOPT})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOPT})){CVSPEC}?
+LNKWORD3 ([0-9a-z_A-Z\-]+("/"|"\\"))*[0-9a-z_A-Z\-]+("."[0-9a-z_A-Z]+)+
+CHARWORDQ [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,."=']
+ESCWORD ("%"{ID}(("::"|"."){ID})*)|("%'")
+WORD1 {ESCWORD}|{CHARWORDQ}+|"{"|"}"|"'\"'"|("\""[^"\n]*\n?[^"\n]*"\"")
+WORD2 "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'"
+WORD1NQ {ESCWORD}|{CHARWORDQ}+|"{"|"}"
+WORD2NQ "."|","|"("|")"|"["|"]"|":"|";"|"\?"|"="|"'"
+HTMLTAG "<"(("/")?){ID}({WS}+{ATTRIB})*{WS}*(("/")?)">"
+HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"
+HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"
+HTMLKEYW {HTMLKEYL}|{HTMLKEYU}
+REFWORD2 ("#"|"::")?((({ID}{TEMPLPART}?)|{ANONNS})("."|"#"|"::"|"-"|"/"))*({ID}{TEMPLPART}?(":")?){FUNCARG}?
+REFWORD3 ({ID}":")*{ID}":"?
+REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{LNKWORD2}
+
+%option noyywrap
+%option yylineno
+
+%x St_Para
+%x St_Comment
+%x St_Title
+%x St_TitleN
+%x St_TitleQ
+%x St_TitleA
+%x St_TitleV
+%x St_Code
+%x St_CodeOpt
+%x St_XmlCode
+%x St_HtmlOnly
+%x St_HtmlOnlyOption
+%x St_ManOnly
+%x St_LatexOnly
+%x St_RtfOnly
+%x St_XmlOnly
+%x St_DbOnly
+%x St_Verbatim
+%x St_Dot
+%x St_Msc
+%x St_PlantUMLOpt
+%x St_PlantUML
+%x St_Param
+%x St_XRefItem
+%x St_XRefItem2
+%x St_File
+%x St_Pattern
+%x St_Link
+%x St_Cite
+%x St_Ref
+%x St_Ref2
+%x St_IntRef
+%x St_Text
+%x St_SkipTitle
+%x St_Anchor
+%x St_Snippet
+
+%x St_Sections
+%s St_SecLabel1
+%s St_SecLabel2
+%s St_SecTitle
+%x St_SecSkip
+
+%%
+<St_Para>\r /* skip carriage return */
+<St_Para>^{LISTITEM} { /* list item */
+ QCString text=yytext;
+ int dashPos = text.findRev('-');
+ g_token->isEnumList = text.at(dashPos+1)=='#';
+ g_token->id = -1;
+ g_token->indent = computeIndent(yytext,dashPos);
+ return TK_LISTITEM;
+ }
+<St_Para>^{MLISTITEM} { /* list item */
+ if (!Doxygen::markdownSupport || g_insidePre)
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString text=yytext;
+ static QRegExp re("[*+]");
+ int listPos = text.findRev(re);
+ g_token->isEnumList = FALSE;
+ g_token->id = -1;
+ g_token->indent = computeIndent(yytext,listPos);
+ return TK_LISTITEM;
+ }
+ }
+<St_Para>^{OLISTITEM} { /* numbered list item */
+ if (!Doxygen::markdownSupport || g_insidePre)
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString text=yytext;
+ static QRegExp re("[1-9]");
+ int digitPos = text.find(re);
+ int dotPos = text.find('.',digitPos);
+ g_token->isEnumList = TRUE;
+ g_token->id = atoi(QCString(yytext).mid(digitPos,dotPos-digitPos));
+ g_token->indent = computeIndent(yytext,digitPos);
+ return TK_LISTITEM;
+ }
+ }
+<St_Para>{BLANK}*\n{LISTITEM} { /* list item on next line */
+ QCString text=yytext;
+ text=text.right(text.length()-text.find('\n')-1);
+ int dashPos = text.findRev('-');
+ g_token->isEnumList = text.at(dashPos+1)=='#';
+ g_token->id = -1;
+ g_token->indent = computeIndent(text,dashPos);
+ return TK_LISTITEM;
+ }
+<St_Para>{BLANK}*\n{MLISTITEM} { /* list item on next line */
+ if (!Doxygen::markdownSupport || g_insidePre)
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString text=yytext;
+ static QRegExp re("[*+]");
+ text=text.right(text.length()-text.find('\n')-1);
+ int markPos = text.findRev(re);
+ g_token->isEnumList = FALSE;
+ g_token->id = -1;
+ g_token->indent = computeIndent(text,markPos);
+ return TK_LISTITEM;
+ }
+ }
+<St_Para>{BLANK}*\n{OLISTITEM} { /* list item on next line */
+ if (!Doxygen::markdownSupport || g_insidePre)
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString text=yytext;
+ int nl=text.findRev('\n');
+ int len=text.length();
+ text=text.right(len-nl-1);
+ static QRegExp re("[1-9]");
+ int digitPos = text.find(re);
+ int dotPos = text.find('.',digitPos);
+ g_token->isEnumList = TRUE;
+ g_token->id = atoi(QCString(text).mid(digitPos,dotPos-digitPos));
+ g_token->indent = computeIndent(text,digitPos);
+ return TK_LISTITEM;
+ }
+ }
+<St_Para>^{ENDLIST} { /* end list */
+ int dotPos = QCString(yytext).findRev('.');
+ g_token->indent = computeIndent(yytext,dotPos);
+ return TK_ENDLIST;
+ }
+<St_Para>{BLANK}*\n{ENDLIST} { /* end list on next line */
+ QCString text=yytext;
+ text=text.right(text.length()-text.find('\n')-1);
+ int dotPos = text.findRev('.');
+ g_token->indent = computeIndent(text,dotPos);
+ return TK_ENDLIST;
+ }
+<St_Para>"{"{BLANK}*"@link" {
+ g_token->name = "javalink";
+ return TK_COMMAND;
+ }
+<St_Para>"{"{BLANK}*"@inheritDoc"{BLANK}*"}" {
+ g_token->name = "inheritdoc";
+ return TK_COMMAND;
+ }
+<St_Para>"@_fakenl" { // artificial new line
+ yylineno++;
+ }
+<St_Para>{SPCMD3} {
+ g_token->name = "form";
+ bool ok;
+ g_token->id = QCString(yytext).right((int)yyleng-6).toInt(&ok);
+ ASSERT(ok);
+ return TK_COMMAND;
+ }
+<St_Para>{CMD}"n"\n { /* \n followed by real newline */
+ yylineno++;
+ g_token->name = yytext+1;
+ g_token->name = g_token->name.stripWhiteSpace();
+ g_token->paramDir=TokenInfo::Unspecified;
+ return TK_COMMAND;
+ }
+<St_Para>{SPCMD1} |
+<St_Para>{SPCMD2} |
+<St_Para>{SPCMD4} { /* special command */
+ g_token->name = yytext+1;
+ g_token->name = g_token->name.stripWhiteSpace();
+ g_token->paramDir=TokenInfo::Unspecified;
+ return TK_COMMAND;
+ }
+<St_Para>{PARAMIO} { /* param [in,out] command */
+ g_token->name = "param";
+ QCString s(yytext);
+ bool isIn = s.find("in")!=-1;
+ bool isOut = s.find("out")!=-1;
+ if (isIn)
+ {
+ if (isOut)
+ {
+ g_token->paramDir=TokenInfo::InOut;
+ }
+ else
+ {
+ g_token->paramDir=TokenInfo::In;
+ }
+ }
+ else if (isOut)
+ {
+ g_token->paramDir=TokenInfo::Out;
+ }
+ else
+ {
+ g_token->paramDir=TokenInfo::Unspecified;
+ }
+ return TK_COMMAND;
+ }
+<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}/\. { // URL.
+ g_token->name=yytext;
+ g_token->isEMailAddr=FALSE;
+ return TK_URL;
+ }
+<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK} { // URL
+ g_token->name=yytext;
+ g_token->isEMailAddr=FALSE;
+ return TK_URL;
+ }
+<St_Para>"<"("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}">" { // URL
+ g_token->name=yytext;
+ g_token->name = g_token->name.mid(1,g_token->name.length()-2);
+ g_token->isEMailAddr=FALSE;
+ return TK_URL;
+ }
+<St_Para>{MAILADR} { // Mail address
+ g_token->name=yytext;
+ g_token->name.stripPrefix("mailto:");
+ g_token->isEMailAddr=TRUE;
+ return TK_URL;
+ }
+<St_Para>"<"{MAILADR}">" { // Mail address
+ g_token->name=yytext;
+ g_token->name = g_token->name.mid(1,g_token->name.length()-2);
+ g_token->name.stripPrefix("mailto:");
+ g_token->isEMailAddr=TRUE;
+ return TK_URL;
+ }
+<St_Para>"$"{ID}":"[^\n$]+"$" { /* RCS tag */
+ QCString tagName(yytext+1);
+ int index=tagName.find(':');
+ g_token->name = tagName.left(index);
+ int text_begin = index+2;
+ int text_end = tagName.length()-1;
+ if (tagName[text_begin-1]==':') /* check for Subversion fixed-length keyword */
+ {
+ ++text_begin;
+ if (tagName[text_end-1]=='#')
+ --text_end;
+ }
+ g_token->text = tagName.mid(text_begin,text_end-text_begin);
+ return TK_RCSTAG;
+ }
+<St_Para,St_HtmlOnly>"$("{ID}")" { /* environment variable */
+ QCString name = &yytext[2];
+ name = name.left(name.length()-1);
+ QCString value = portable_getenv(name);
+ for (int i=value.length()-1;i>=0;i--) unput(value.at(i));
+ }
+<St_Para>{HTMLTAG} { /* html tag */
+ handleHtmlTag();
+ return TK_HTMLTAG;
+ }
+<St_Para,St_Text>"&"{ID}";" { /* special symbol */
+ g_token->name = yytext;
+ return TK_SYMBOL;
+ }
+
+ /********* patterns for linkable words ******************/
+
+<St_Para>{ID}/"<"{HTMLKEYW}">" { /* this rule is to prevent opening html
+ * tag to be recognized as a templated classes
+ */
+ g_token->name = yytext;
+ return TK_LNKWORD;
+ }
+<St_Para>{LNKWORD1}/"<br>" | // prevent <br> html tag to be parsed as template arguments
+<St_Para>{LNKWORD1} |
+<St_Para>{LNKWORD1}{FUNCARG} |
+<St_Para>{LNKWORD2} |
+<St_Para>{LNKWORD3} {
+ g_token->name = yytext;
+ return TK_LNKWORD;
+ }
+<St_Para>{LNKWORD1}{FUNCARG}{CVSPEC}[^a-z_A-Z0-9] {
+ g_token->name = yytext;
+ g_token->name = g_token->name.left(g_token->name.length()-1);
+ unput(yytext[(int)yyleng-1]);
+ return TK_LNKWORD;
+ }
+ /********* patterns for normal words ******************/
+
+<St_Para,St_Text>{WORD1} |
+<St_Para,St_Text>{WORD2} { /* function call */
+ if (yytext[0]=='%') // strip % if present
+ g_token->name = &yytext[1];
+ else
+ g_token->name = yytext;
+ return TK_WORD;
+
+ /* the following is dummy code to please the
+ * compiler, removing this results in a warning
+ * on my machine
+ */
+ goto find_rule;
+ }
+<St_Text>({ID}".")+{ID} {
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_Para,St_Text>"operator"/{BLANK}*"<"[a-zA-Z_0-9]+">" { // Special case: word "operator" followed by a HTML command
+ // avoid interpretation as "operator <"
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+
+ /*******************************************************/
+
+<St_Para,St_Text>{BLANK}+ |
+<St_Para,St_Text>{BLANK}*\n{BLANK}* { /* white space */
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_Text>[\\@<>&$#%~] {
+ g_token->name = yytext;
+ return TK_COMMAND;
+ }
+<St_Para>({BLANK}*\n)+{BLANK}*\n/{LISTITEM} { /* skip trailing paragraph followed by new list item */
+ if (g_insidePre || g_autoListLevel==0)
+ {
+ REJECT;
+ }
+ }
+<St_Para>({BLANK}*\n)+{BLANK}*\n/{MLISTITEM} { /* skip trailing paragraph followed by new list item */
+ if (!Doxygen::markdownSupport || g_insidePre || g_autoListLevel==0)
+ {
+ REJECT;
+ }
+ }
+<St_Para>({BLANK}*\n)+{BLANK}*\n/{OLISTITEM} { /* skip trailing paragraph followed by new list item */
+ if (!Doxygen::markdownSupport || g_insidePre || g_autoListLevel==0)
+ {
+ REJECT;
+ }
+ }
+<St_Para>({BLANK}*\n)+{BLANK}*\n{BLANK}* {
+ g_token->indent=computeIndent(yytext,(int)yyleng);
+ int i;
+ // put back the indentation (needed for list items)
+ for (i=0;i<g_token->indent;i++)
+ {
+ unput(' ');
+ }
+ // tell flex that after putting the last indent
+ // back we are at the beginning of the line
+ YY_CURRENT_BUFFER->yy_at_bol=1;
+ // start of a new paragraph
+ return TK_NEWPARA;
+ }
+<St_CodeOpt>{BLANK}*"{"(".")?{LABELID}"}" {
+ g_token->name = yytext;
+ int i=g_token->name.find('{'); /* } to keep vi happy */
+ g_token->name = g_token->name.mid(i+1,g_token->name.length()-i-2);
+ BEGIN(St_Code);
+ }
+<St_CodeOpt>\n |
+<St_CodeOpt>. {
+ unput(*yytext);
+ BEGIN(St_Code);
+ }
+<St_Code>{WS}*{CMD}"endcode" {
+ return RetVal_OK;
+ }
+<St_XmlCode>{WS}*"</code>" {
+ return RetVal_OK;
+ }
+<St_Code,St_XmlCode>[^\\@\n<]+ |
+<St_Code,St_XmlCode>\n |
+<St_Code,St_XmlCode>. {
+ g_token->verb+=yytext;
+ }
+<St_HtmlOnlyOption>" [block]" { // the space is added in commentscan.l
+ g_token->name="block";
+ BEGIN(St_HtmlOnly);
+ }
+<St_HtmlOnlyOption>.|\n {
+ unput(*yytext);
+ BEGIN(St_HtmlOnly);
+ }
+<St_HtmlOnly>{CMD}"endhtmlonly" {
+ return RetVal_OK;
+ }
+<St_HtmlOnly>[^\\@\n$]+ |
+<St_HtmlOnly>\n |
+<St_HtmlOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_ManOnly>{CMD}"endmanonly" {
+ return RetVal_OK;
+ }
+<St_ManOnly>[^\\@\n$]+ |
+<St_ManOnly>\n |
+<St_ManOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_RtfOnly>{CMD}"endrtfonly" {
+ return RetVal_OK;
+ }
+<St_RtfOnly>[^\\@\n$]+ |
+<St_RtfOnly>\n |
+<St_RtfOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_LatexOnly>{CMD}"endlatexonly" {
+ return RetVal_OK;
+ }
+<St_LatexOnly>[^\\@\n]+ |
+<St_LatexOnly>\n |
+<St_LatexOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_XmlOnly>{CMD}"endxmlonly" {
+ return RetVal_OK;
+ }
+<St_XmlOnly>[^\\@\n]+ |
+<St_XmlOnly>\n |
+<St_XmlOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_DbOnly>{CMD}"enddocbookonly" {
+ return RetVal_OK;
+ }
+<St_DbOnly>[^\\@\n]+ |
+<St_DbOnly>\n |
+<St_DbOnly>. {
+ g_token->verb+=yytext;
+ }
+<St_Verbatim>{CMD}"endverbatim" {
+ g_token->verb=stripEmptyLines(g_token->verb);
+ return RetVal_OK;
+ }
+<St_Verbatim>[^\\@\n]+ |
+<St_Verbatim>\n |
+<St_Verbatim>. { /* Verbatim text */
+ g_token->verb+=yytext;
+ }
+<St_Dot>{CMD}"enddot" {
+ return RetVal_OK;
+ }
+<St_Dot>[^\\@\n]+ |
+<St_Dot>\n |
+<St_Dot>. { /* dot text */
+ g_token->verb+=yytext;
+ }
+<St_Msc>{CMD}("endmsc") {
+ return RetVal_OK;
+ }
+<St_Msc>[^\\@\n]+ |
+<St_Msc>\n |
+<St_Msc>. { /* msc text */
+ g_token->verb+=yytext;
+ }
+<St_PlantUMLOpt>\n {
+ g_token->sectionId=g_token->sectionId.stripWhiteSpace();
+ BEGIN(St_PlantUML);
+ }
+<St_PlantUMLOpt>["{}] { // skip curly brackets or quotes around the optional image name
+ }
+<St_PlantUMLOpt>. {
+ g_token->sectionId += yytext;
+ }
+<St_PlantUML>{CMD}"enduml" {
+ return RetVal_OK;
+ }
+<St_PlantUML>[^\\@\n]+ |
+<St_PlantUML>\n |
+<St_PlantUML>. { /* plantuml text */
+ g_token->verb+=yytext;
+ }
+<St_Title>"\"" { // quoted title
+ BEGIN(St_TitleQ);
+ }
+<St_Title>[ \t]+ {
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_Title>. { // non-quoted title
+ unput(*yytext);
+ BEGIN(St_TitleN);
+ }
+<St_Title>\n {
+ unput(*yytext);
+ return 0;
+ }
+<St_TitleN>"&"{ID}";" { /* symbol */
+ g_token->name = yytext;
+ return TK_SYMBOL;
+ }
+<St_TitleN>{HTMLTAG} {
+ }
+<St_TitleN>{SPCMD1} |
+<St_TitleN>{SPCMD2} { /* special command */
+ g_token->name = yytext+1;
+ g_token->paramDir=TokenInfo::Unspecified;
+ return TK_COMMAND;
+ }
+<St_TitleN>{WORD1} |
+<St_TitleN>{WORD2} { /* word */
+ if (yytext[0]=='%') // strip % if present
+ g_token->name = &yytext[1];
+ else
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_TitleN>[ \t]+ {
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_TitleN>\n { /* new line => end of title */
+ unput(*yytext);
+ return 0;
+ }
+<St_TitleQ>"&"{ID}";" { /* symbol */
+ g_token->name = yytext;
+ return TK_SYMBOL;
+ }
+<St_TitleQ>{SPCMD1} |
+<St_TitleQ>{SPCMD2} { /* special command */
+ g_token->name = yytext+1;
+ g_token->paramDir=TokenInfo::Unspecified;
+ return TK_COMMAND;
+ }
+<St_TitleQ>{WORD1NQ} |
+<St_TitleQ>{WORD2NQ} { /* word */
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_TitleQ>[ \t]+ {
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_TitleQ>"\"" { /* closing quote => end of title */
+ BEGIN(St_TitleA);
+ return 0;
+ }
+<St_TitleQ>\n { /* new line => end of title */
+ unput(*yytext);
+ return 0;
+ }
+<St_TitleA>{BLANK}*{ID}{BLANK}*"="{BLANK}* { // title attribute
+ g_token->name = yytext;
+ g_token->name = g_token->name.left(
+ g_token->name.find('=')).stripWhiteSpace();
+ BEGIN(St_TitleV);
+ }
+<St_TitleV>[^ \t\r\n]+ { // attribute value
+ g_token->chars = yytext;
+ BEGIN(St_TitleN);
+ return TK_WORD;
+ }
+<St_TitleV,St_TitleA>. {
+ unput(*yytext);
+ return 0;
+ }
+<St_TitleV,St_TitleA>\n {
+ return 0;
+ }
+
+<St_Anchor>{LABELID}{WS}? { // anchor
+ g_token->name = QCString(yytext).stripWhiteSpace();
+ return TK_WORD;
+ }
+<St_Anchor>. {
+ unput(*yytext);
+ return 0;
+ }
+<St_Cite>{CITEID} { // label to cite
+ g_token->name=yytext;
+ return TK_WORD;
+ }
+<St_Cite>{BLANK} { // white space
+ unput(' ');
+ return 0;
+ }
+<St_Cite>\n { // new line
+ unput(*yytext);
+ return 0;
+ }
+<St_Cite>. { // any other character
+ unput(*yytext);
+ return 0;
+ }
+<St_Ref>{REFWORD} { // label to refer to
+ g_token->name=yytext;
+ return TK_WORD;
+ }
+<St_Ref>{BLANK} { // white space
+ unput(' ');
+ return 0;
+ }
+<St_Ref>{WS}+"\""{WS}* { // white space following by quoted string
+ BEGIN(St_Ref2);
+ }
+<St_Ref>\n { // new line
+ unput(*yytext);
+ return 0;
+ }
+<St_Ref>. { // any other character
+ unput(*yytext);
+ return 0;
+ }
+<St_IntRef>[A-Z_a-z0-9.:/#\-\+\(\)]+ {
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_IntRef>{BLANK}+"\"" {
+ BEGIN(St_Ref2);
+ }
+<St_Ref2>"&"{ID}";" { /* symbol */
+ g_token->name = yytext;
+ return TK_SYMBOL;
+ }
+<St_Ref2>{SPCMD1} |
+<St_Ref2>{SPCMD2} { /* special command */
+ g_token->name = yytext+1;
+ g_token->paramDir=TokenInfo::Unspecified;
+ return TK_COMMAND;
+ }
+<St_Ref2>{WORD1NQ} |
+<St_Ref2>{WORD2NQ} {
+ /* word */
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_Ref2>[ \t]+ {
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_Ref2>"\""|\n { /* " or \n => end of title */
+ return 0;
+ }
+<St_XRefItem>{LABELID} {
+ g_token->name=yytext;
+ }
+<St_XRefItem>" " {
+ BEGIN(St_XRefItem2);
+ }
+<St_XRefItem2>[0-9]+"." {
+ QCString numStr=yytext;
+ numStr=numStr.left((int)yyleng-1);
+ g_token->id=numStr.toInt();
+ return RetVal_OK;
+ }
+<St_Para,St_Title,St_Ref2>"<!--" { /* html style comment block */
+ g_commentState = YY_START;
+ BEGIN(St_Comment);
+ }
+<St_Param>"\""[^\n\"]+"\"" {
+ g_token->name = yytext+1;
+ g_token->name = g_token->name.left((int)yyleng-2);
+ return TK_WORD;
+ }
+<St_Param>({PHPTYPE}{BLANK}*"|"{BLANK}*)*{PHPTYPE}{WS}+("&")?"$"{LABELID} {
+ QCString params = yytext;
+ int j = params.find('&');
+ int i = params.find('$');
+ if (j<i && j!=-1) i=j;
+ QCString types = params.left(i).stripWhiteSpace();
+ g_token->name = types+"#"+params.mid(i);
+ return TK_WORD;
+ }
+<St_Param>[^ \t\n,@\\]+ {
+ g_token->name = yytext;
+ if (g_token->name.at(yyleng-1)==':')
+ {
+ g_token->name=g_token->name.left(yyleng-1);
+ }
+ return TK_WORD;
+ }
+<St_Param>{WS}*","{WS}* /* param separator */
+<St_Param>{WS} {
+ g_token->chars=yytext;
+ return TK_WHITESPACE;
+ }
+<St_File>{FILEMASK} {
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_File>"\""[^\n\"]+"\"" {
+ QCString text=yytext;
+ g_token->name = text.mid(1,text.length()-2);
+ return TK_WORD;
+ }
+<St_Pattern>[^\r\n]+ {
+ g_token->name = yytext;
+ g_token->name = g_token->name.stripWhiteSpace();
+ return TK_WORD;
+ }
+<St_Link>{LINKMASK}|{REFWORD} {
+ g_token->name = yytext;
+ return TK_WORD;
+ }
+<St_Comment>"-->" { /* end of html comment */
+ BEGIN(g_commentState);
+ }
+<St_Comment>[^-\n]+ /* inside html comment */
+<St_Comment>. /* inside html comment */
+
+ /* State for skipping title (all chars until the end of the line) */
+
+<St_SkipTitle>.
+<St_SkipTitle>\n { return 0; }
+
+ /* State for the pass used to find the anchors and sections */
+
+<St_Sections>[^\n@\\]+
+<St_Sections>"@@"|"\\\\"
+<St_Sections>{CMD}"anchor"{BLANK}+ {
+ g_secType = SectionInfo::Anchor;
+ BEGIN(St_SecLabel1);
+ }
+<St_Sections>{CMD}"section"{BLANK}+ {
+ g_secType = SectionInfo::Section;
+ BEGIN(St_SecLabel2);
+ }
+<St_Sections>{CMD}"subsection"{BLANK}+ {
+ g_secType = SectionInfo::Subsection;
+ BEGIN(St_SecLabel2);
+ }
+<St_Sections>{CMD}"subsubsection"{BLANK}+ {
+ g_secType = SectionInfo::Subsubsection;
+ BEGIN(St_SecLabel2);
+ }
+<St_Sections>{CMD}"paragraph"{BLANK}+ {
+ g_secType = SectionInfo::Paragraph;
+ BEGIN(St_SecLabel2);
+ }
+<St_Sections>{CMD}"verbatim"/[^a-z_A-Z0-9] {
+ g_endMarker="endverbatim";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"dot"/[^a-z_A-Z0-9] {
+ g_endMarker="enddot";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"msc"/[^a-z_A-Z0-9] {
+ g_endMarker="endmsc";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"startuml"/[^a-z_A-Z0-9] {
+ g_endMarker="enduml";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
+ g_endMarker="endhtmlonly";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"latexonly"/[^a-z_A-Z0-9] {
+ g_endMarker="endlatexonly";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"xmlonly"/[^a-z_A-Z0-9] {
+ g_endMarker="endxmlonly";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"docbookonly"/[^a-z_A-Z0-9] {
+ g_endMarker="enddocbookonly";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>{CMD}"code"/[^a-z_A-Z0-9] {
+ g_endMarker="endcode";
+ BEGIN(St_SecSkip);
+ }
+<St_Sections>"<!--" {
+ g_endMarker="-->";
+ BEGIN(St_SecSkip);
+ }
+<St_SecSkip>{CMD}{ID} {
+ if (qstrcmp(yytext+1,g_endMarker)==0)
+ {
+ BEGIN(St_Sections);
+ }
+ }
+<St_SecSkip>"-->" {
+ if (qstrcmp(yytext,g_endMarker)==0)
+ {
+ BEGIN(St_Sections);
+ }
+ }
+<St_SecSkip>[^a-z_A-Z0-9\-\\\@]+
+<St_SecSkip>.
+<St_SecSkip>\n
+<St_Sections>.
+<St_Sections>\n
+<St_SecLabel1>{LABELID} {
+ g_secLabel = yytext;
+ processSection();
+ BEGIN(St_Sections);
+ }
+<St_SecLabel2>{LABELID}{BLANK}+ |
+<St_SecLabel2>{LABELID} {
+ g_secLabel = yytext;
+ g_secLabel = g_secLabel.stripWhiteSpace();
+ BEGIN(St_SecTitle);
+ }
+<St_SecTitle>[^\n]+ |
+<St_SecTitle>[^\n]*\n {
+ g_secTitle = yytext;
+ g_secTitle = g_secTitle.stripWhiteSpace();
+ processSection();
+ BEGIN(St_Sections);
+ }
+<St_SecTitle,St_SecLabel1,St_SecLabel2>. {
+ warn(g_fileName,yylineno,"Unexpected character `%s' while looking for section label or title",yytext);
+ }
+
+<St_Snippet>[^\n]+ |
+<St_Snippet>[^\n]*\n {
+ g_token->name = yytext;
+ g_token->name = g_token->name.stripWhiteSpace();
+ return TK_WORD;
+ }
+
+ /* Generic rules that work for all states */
+<*>\n {
+ warn(g_fileName,yylineno,"Unexpected new line character");
+ }
+<*>[\\@<>&$#%~"=] { /* unescaped special character */
+ //warn(g_fileName,yylineno,"Unexpected character `%s', assuming command \\%s was meant.",yytext,yytext);
+ g_token->name = yytext;
+ return TK_COMMAND;
+ }
+<*>. {
+ warn(g_fileName,yylineno,"Unexpected character `%s'",yytext);
+ }
+%%
+
+//--------------------------------------------------------------------------
+
+void doctokenizerYYFindSections(const char *input,Definition *d,
+ MemberGroup *mg,const char *fileName)
+{
+ if (input==0) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+ g_inputString = input;
+ //printf("parsing --->`%s'<---\n",input);
+ g_inputPos = 0;
+ g_definition = d;
+ g_memberGroup = mg;
+ g_fileName = fileName;
+ BEGIN(St_Sections);
+ doctokenizerYYlineno = 1;
+ doctokenizerYYlex();
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+void doctokenizerYYinit(const char *input,const char *fileName)
+{
+ g_autoListLevel = 0;
+ g_inputString = input;
+ g_inputPos = 0;
+ g_fileName = fileName;
+ g_insidePre = FALSE;
+ BEGIN(St_Para);
+}
+
+void doctokenizerYYsetStatePara()
+{
+ BEGIN(St_Para);
+}
+
+void doctokenizerYYsetStateTitle()
+{
+ BEGIN(St_Title);
+}
+
+void doctokenizerYYsetStateTitleAttrValue()
+{
+ BEGIN(St_TitleV);
+}
+
+void doctokenizerYYsetStateCode()
+{
+ g_token->verb="";
+ g_token->name="";
+ BEGIN(St_CodeOpt);
+}
+
+void doctokenizerYYsetStateXmlCode()
+{
+ g_token->verb="";
+ g_token->name="";
+ BEGIN(St_XmlCode);
+}
+
+void doctokenizerYYsetStateHtmlOnly()
+{
+ g_token->verb="";
+ g_token->name="";
+ BEGIN(St_HtmlOnlyOption);
+}
+
+void doctokenizerYYsetStateManOnly()
+{
+ g_token->verb="";
+ BEGIN(St_ManOnly);
+}
+
+void doctokenizerYYsetStateRtfOnly()
+{
+ g_token->verb="";
+ BEGIN(St_RtfOnly);
+}
+
+void doctokenizerYYsetStateXmlOnly()
+{
+ g_token->verb="";
+ BEGIN(St_XmlOnly);
+}
+
+void doctokenizerYYsetStateDbOnly()
+{
+ g_token->verb="";
+ BEGIN(St_DbOnly);
+}
+
+void doctokenizerYYsetStateLatexOnly()
+{
+ g_token->verb="";
+ BEGIN(St_LatexOnly);
+}
+
+void doctokenizerYYsetStateVerbatim()
+{
+ g_token->verb="";
+ BEGIN(St_Verbatim);
+}
+
+void doctokenizerYYsetStateDot()
+{
+ g_token->verb="";
+ BEGIN(St_Dot);
+}
+
+void doctokenizerYYsetStateMsc()
+{
+ g_token->verb="";
+ BEGIN(St_Msc);
+}
+
+void doctokenizerYYsetStatePlantUML()
+{
+ g_token->verb="";
+ g_token->sectionId="";
+ BEGIN(St_PlantUMLOpt);
+}
+
+void doctokenizerYYsetStateParam()
+{
+ BEGIN(St_Param);
+}
+
+void doctokenizerYYsetStateXRefItem()
+{
+ BEGIN(St_XRefItem);
+}
+
+void doctokenizerYYsetStateFile()
+{
+ BEGIN(St_File);
+}
+
+void doctokenizerYYsetStatePattern()
+{
+ BEGIN(St_Pattern);
+}
+
+void doctokenizerYYsetStateLink()
+{
+ BEGIN(St_Link);
+}
+
+void doctokenizerYYsetStateCite()
+{
+ BEGIN(St_Cite);
+}
+
+void doctokenizerYYsetStateRef()
+{
+ BEGIN(St_Ref);
+}
+
+void doctokenizerYYsetStateInternalRef()
+{
+ BEGIN(St_IntRef);
+}
+
+void doctokenizerYYsetStateText()
+{
+ BEGIN(St_Text);
+}
+
+void doctokenizerYYsetStateSkipTitle()
+{
+ BEGIN(St_SkipTitle);
+}
+
+void doctokenizerYYsetStateAnchor()
+{
+ BEGIN(St_Anchor);
+}
+
+void doctokenizerYYsetStateSnippet()
+{
+ BEGIN(St_Snippet);
+}
+
+void doctokenizerYYcleanup()
+{
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+}
+
+void doctokenizerYYsetInsidePre(bool b)
+{
+ g_insidePre = b;
+}
+
+void doctokenizerYYpushBackHtmlTag(const char *tag)
+{
+ QCString tagName = tag;
+ int i,l = tagName.length();
+ unput('>');
+ for (i=l-1;i>=0;i--)
+ {
+ unput(tag[i]);
+ }
+ unput('<');
+}
+
+void doctokenizerYYstartAutoList()
+{
+ g_autoListLevel++;
+}
+
+void doctokenizerYYendAutoList()
+{
+ g_autoListLevel--;
+}
+
+REAL_YY_DECL
+{
+ printlex(yy_flex_debug, TRUE, __FILE__, g_fileName);
+ int retval = LOCAL_YY_DECL;
+ printlex(yy_flex_debug, FALSE, __FILE__, g_fileName);
+ return retval;
+}
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void doctokenizerYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/docvisitor.h b/src/docvisitor.h
new file mode 100644
index 0000000..a444b47
--- /dev/null
+++ b/src/docvisitor.h
@@ -0,0 +1,201 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DOCVISITOR_H
+#define _DOCVISITOR_H
+
+// ids
+const int DocVisitor_Html = 0;
+const int DocVisitor_Latex = 1;
+const int DocVisitor_XML = 2;
+const int DocVisitor_RTF = 3;
+const int DocVisitor_Man = 4;
+const int DocVisitor_Text = 5;
+const int DocVisitor_Other = 6;
+const int DocVisitor_Docbook = 7;
+
+// forward declarations
+class DocWord;
+class DocWhiteSpace;
+class DocAutoList;
+class DocAutoListItem;
+class DocPara;
+class DocRoot;
+class DocSymbol;
+class DocURL;
+class DocStyleChange;
+class DocSimpleSect;
+class DocTitle;
+class DocSimpleList;
+class DocSimpleListItem;
+class DocSection;
+class DocVerbatim;
+class DocXRefItem;
+class DocHtmlList;
+class DocHtmlListItem;
+class DocHtmlDescList;
+class DocHtmlDescTitle;
+class DocHtmlDescData;
+class DocHtmlTable;
+class DocHtmlRow;
+class DocHtmlCell;
+class DocHtmlCaption;
+class DocLineBreak;
+class DocHorRuler;
+class DocAnchor;
+class DocIndexEntry;
+class DocInternal;
+class DocHRef;
+class DocInclude;
+class DocIncOperator;
+class DocHtmlHeader;
+class DocImage;
+class DocDotFile;
+class DocMscFile;
+class DocDiaFile;
+class DocLink;
+class DocCite;
+class DocRef;
+class DocFormula;
+class DocSecRefItem;
+class DocSecRefList;
+class DocLinkedWord;
+class DocParamSect;
+class DocParamList;
+class DocInternalRef;
+class DocCopy; // TODO: no longer generated => remove
+class DocText;
+class DocSimpleSectSep;
+class DocHtmlBlockQuote;
+class DocVhdlFlow;
+class DocParBlock;
+
+/*! @brief Abstract visitor that participates in the visitor pattern.
+ */
+class DocVisitor
+{
+ int m_id;
+ public:
+ DocVisitor(int id) : m_id(id) {}
+ virtual ~DocVisitor() {}
+ int id() const { return m_id; }
+
+ /*! @name Visitor functions for leaf nodes
+ * @{
+ */
+ virtual void visit(DocWord *) = 0;
+ virtual void visit(DocWhiteSpace *) = 0;
+ virtual void visit(DocSymbol *) = 0;
+ virtual void visit(DocURL *) = 0;
+ virtual void visit(DocStyleChange *) = 0;
+ virtual void visit(DocVerbatim *) = 0;
+ virtual void visit(DocLineBreak *) = 0;
+ virtual void visit(DocHorRuler *) = 0;
+ virtual void visit(DocAnchor *) = 0;
+ virtual void visit(DocInclude *) = 0;
+ virtual void visit(DocIncOperator *) = 0;
+ virtual void visit(DocFormula *) = 0;
+ virtual void visit(DocLinkedWord *) = 0;
+ virtual void visit(DocIndexEntry *) = 0;
+ virtual void visit(DocSimpleSectSep *) = 0;
+ virtual void visit(DocCite *) = 0;
+ /*! @} */
+
+ /*! @name Visitor functions for internal nodes
+ * @{
+ */
+ virtual void visitPre(DocAutoList *) = 0;
+ virtual void visitPost(DocAutoList *) = 0;
+ virtual void visitPre(DocAutoListItem *) = 0;
+ virtual void visitPost(DocAutoListItem *) = 0;
+ virtual void visitPre(DocPara *) = 0;
+ virtual void visitPost(DocPara *) = 0;
+ virtual void visitPre(DocRoot *) = 0;
+ virtual void visitPost(DocRoot *) = 0;
+ virtual void visitPre(DocSimpleSect *) = 0;
+ virtual void visitPost(DocSimpleSect *) = 0;
+ virtual void visitPre(DocTitle *) = 0;
+ virtual void visitPost(DocTitle *) = 0;
+ virtual void visitPre(DocSimpleList *) = 0;
+ virtual void visitPost(DocSimpleList *) = 0;
+ virtual void visitPre(DocSimpleListItem *) = 0;
+ virtual void visitPost(DocSimpleListItem *) = 0;
+ virtual void visitPre(DocSection *) = 0;
+ virtual void visitPost(DocSection *) = 0;
+ virtual void visitPre(DocHtmlList *) = 0;
+ virtual void visitPost(DocHtmlListItem *) = 0;
+ virtual void visitPre(DocHtmlListItem *) = 0;
+ virtual void visitPost(DocHtmlList *) = 0;
+ virtual void visitPre(DocHtmlDescList *) = 0;
+ virtual void visitPost(DocHtmlDescList *) = 0;
+ virtual void visitPre(DocHtmlDescTitle *) = 0;
+ virtual void visitPost(DocHtmlDescTitle *) = 0;
+ virtual void visitPre(DocHtmlDescData *) = 0;
+ virtual void visitPost(DocHtmlDescData *) = 0;
+ virtual void visitPre(DocHtmlTable *) = 0;
+ virtual void visitPost(DocHtmlRow *) = 0;
+ virtual void visitPre(DocHtmlCell *) = 0;
+ virtual void visitPost(DocHtmlCell *) = 0;
+ virtual void visitPre(DocHtmlRow *) = 0;
+ virtual void visitPost(DocHtmlTable *) = 0;
+ virtual void visitPre(DocHtmlCaption *) = 0;
+ virtual void visitPost(DocHtmlCaption *) = 0;
+ virtual void visitPre(DocInternal *) = 0;
+ virtual void visitPost(DocInternal *) = 0;
+ virtual void visitPre(DocHRef *) = 0;
+ virtual void visitPost(DocHRef *) = 0;
+ virtual void visitPre(DocHtmlHeader *) = 0;
+ virtual void visitPost(DocHtmlHeader *) = 0;
+ virtual void visitPre(DocImage *) = 0;
+ virtual void visitPost(DocImage *) = 0;
+ virtual void visitPre(DocDotFile *) = 0;
+ virtual void visitPost(DocDotFile *) = 0;
+ virtual void visitPre(DocMscFile *) = 0;
+ virtual void visitPost(DocMscFile *) = 0;
+ virtual void visitPre(DocDiaFile *) = 0;
+ virtual void visitPost(DocDiaFile *) = 0;
+ virtual void visitPre(DocLink *) = 0;
+ virtual void visitPost(DocLink *) = 0;
+ virtual void visitPre(DocRef *) = 0;
+ virtual void visitPost(DocRef *) = 0;
+ virtual void visitPre(DocSecRefItem *) = 0;
+ virtual void visitPost(DocSecRefItem *) = 0;
+ virtual void visitPre(DocSecRefList *) = 0;
+ virtual void visitPost(DocSecRefList *) = 0;
+ virtual void visitPre(DocParamSect *) = 0;
+ virtual void visitPost(DocParamSect *) = 0;
+ virtual void visitPre(DocParamList *) = 0;
+ virtual void visitPost(DocParamList *) = 0;
+ virtual void visitPre(DocXRefItem *) = 0;
+ virtual void visitPost(DocXRefItem *) = 0;
+ virtual void visitPre(DocInternalRef *) = 0;
+ virtual void visitPost(DocInternalRef *) = 0;
+ virtual void visitPre(DocCopy *) = 0;
+ virtual void visitPost(DocCopy *) = 0;
+ virtual void visitPre(DocText *) = 0;
+ virtual void visitPost(DocText *) = 0;
+ virtual void visitPre(DocHtmlBlockQuote *) = 0;
+ virtual void visitPost(DocHtmlBlockQuote *) = 0;
+ virtual void visitPre(DocVhdlFlow *) = 0;
+ virtual void visitPost(DocVhdlFlow *) = 0;
+ virtual void visitPre(DocParBlock *) = 0;
+ virtual void visitPost(DocParBlock *) = 0;
+ /*! @} */
+};
+
+#endif
diff --git a/src/dot.cpp b/src/dot.cpp
new file mode 100644
index 0000000..c64729a
--- /dev/null
+++ b/src/dot.cpp
@@ -0,0 +1,4851 @@
+/*****************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qqueue.h>
+#include <qthread.h>
+#include <qmutex.h>
+#include <qwaitcondition.h>
+
+#include "dot.h"
+#include "doxygen.h"
+#include "message.h"
+#include "util.h"
+#include "config.h"
+#include "language.h"
+#include "defargs.h"
+#include "docparser.h"
+#include "debug.h"
+#include "pagedef.h"
+#include "portable.h"
+#include "dirdef.h"
+#include "vhdldocgen.h"
+#include "ftextstream.h"
+#include "md5.h"
+#include "memberlist.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filename.h"
+#include "namespacedef.h"
+#include "memberdef.h"
+#include "membergroup.h"
+
+#define MAP_CMD "cmapx"
+
+//#define FONTNAME "Helvetica"
+#define FONTNAME getDotFontName()
+#define FONTSIZE getDotFontSize()
+
+//--------------------------------------------------------------------
+
+static const char svgZoomHeader[] =
+"<svg id=\"main\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" onload=\"init(evt)\">\n"
+"<style type=\"text/css\"><![CDATA[\n"
+".edge:hover path { stroke: red; }\n"
+".edge:hover polygon { stroke: red; fill: red; }\n"
+"]]></style>\n"
+"<script type=\"text/javascript\"><![CDATA[\n"
+"var edges = document.getElementsByTagName('g');\n"
+"if (edges && edges.length) {\n"
+" for (var i=0;i<edges.length;i++) {\n"
+" if (edges[i].id.substr(0,4)=='edge') {\n"
+" edges[i].setAttribute('class','edge');\n"
+" }\n"
+" }\n"
+"}\n"
+"]]></script>\n"
+" <defs>\n"
+" <circle id=\"rim\" cx=\"0\" cy=\"0\" r=\"7\"/>\n"
+" <circle id=\"rim2\" cx=\"0\" cy=\"0\" r=\"3.5\"/>\n"
+" <g id=\"zoomPlus\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomplus.mouseover\" end=\"zoomplus.mouseout\"/>\n"
+" </use>\n"
+" <path d=\"M-4,0h8M0,-4v8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n"
+" </g>\n"
+" <g id=\"zoomMin\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomminus.mouseover\" end=\"zoomminus.mouseout\"/>\n"
+" </use>\n"
+" <path d=\"M-4,0h8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n"
+" </g>\n"
+" <g id=\"dirArrow\">\n"
+" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
+" </g>\n"
+" <g id=\"resetDef\">\n"
+" <use xlink:href=\"#rim2\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"reset.mouseover\" end=\"reset.mouseout\"/>\n"
+" </use>\n"
+" </g>\n"
+" </defs>\n"
+"\n"
+"<script type=\"text/javascript\">\n"
+;
+
+static const char svgZoomFooter[] =
+// navigation panel
+" <g id=\"navigator\" transform=\"translate(0 0)\" fill=\"#404254\">\n"
+" <rect fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\".5\" x=\"0\" y=\"0\" width=\"60\" height=\"60\"/>\n"
+// zoom in
+" <use id=\"zoomplus\" xlink:href=\"#zoomPlus\" x=\"17\" y=\"9\" onmousedown=\"handleZoom(evt,'in')\"/>\n"
+// zoom out
+" <use id=\"zoomminus\" xlink:href=\"#zoomMin\" x=\"42\" y=\"9\" onmousedown=\"handleZoom(evt,'out')\"/>\n"
+// reset zoom
+" <use id=\"reset\" xlink:href=\"#resetDef\" x=\"30\" y=\"36\" onmousedown=\"handleReset()\"/>\n"
+// arrow up
+" <g id=\"arrowUp\" xlink:href=\"#dirArrow\" transform=\"translate(30 24)\" onmousedown=\"handlePan(0,-1)\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowUp.mouseover\" end=\"arrowUp.mouseout\"/>\n"
+" </use>\n"
+" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
+" </g>\n"
+// arrow right
+" <g id=\"arrowRight\" xlink:href=\"#dirArrow\" transform=\"rotate(90) translate(36 -43)\" onmousedown=\"handlePan(1,0)\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowRight.mouseover\" end=\"arrowRight.mouseout\"/>\n"
+" </use>\n"
+" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
+" </g>\n"
+// arrow down
+" <g id=\"arrowDown\" xlink:href=\"#dirArrow\" transform=\"rotate(180) translate(-30 -48)\" onmousedown=\"handlePan(0,1)\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowDown.mouseover\" end=\"arrowDown.mouseout\"/>\n"
+" </use>\n"
+" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
+" </g>\n"
+// arrow left
+" <g id=\"arrowLeft\" xlink:href=\"#dirArrow\" transform=\"rotate(270) translate(-36 17)\" onmousedown=\"handlePan(-1,0)\">\n"
+" <use xlink:href=\"#rim\" fill=\"#404040\">\n"
+" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowLeft.mouseover\" end=\"arrowLeft.mouseout\"/>\n"
+" </use>\n"
+" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
+" </g>\n"
+" </g>\n"
+// link to orginial SVG
+" <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n"
+" <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n"
+" <a xlink:href=\"$orgname\" target=\"_base\">\n"
+" <rect id=\"button\" ry=\"5\" rx=\"5\" y=\"6\" x=\"6\" height=\"38\" width=\"38\"\n"
+" fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\"1.0\"/>\n"
+" <path id=\"arrow\"\n"
+" d=\"M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z\"\n"
+" style=\"fill:#404040;\"/>\n"
+" </a>\n"
+" </g>\n"
+" </svg>\n"
+"</svg>\n"
+;
+
+//--------------------------------------------------------------------
+
+static const int maxCmdLine = 40960;
+
+/*! mapping from protection levels to color names */
+static const char *normalEdgeColorMap[] =
+{
+ "midnightblue", // Public
+ "darkgreen", // Protected
+ "firebrick4", // Private
+ "darkorchid3", // "use" relation
+ "grey75", // Undocumented
+ "orange" // template relation
+};
+
+static const char *normalArrowStyleMap[] =
+{
+ "empty", // Public
+ "empty", // Protected
+ "empty", // Private
+ "open", // "use" relation
+ 0, // Undocumented
+ 0 // template relation
+};
+
+static const char *normalEdgeStyleMap[] =
+{
+ "solid", // inheritance
+ "dashed" // usage
+};
+
+static const char *umlEdgeColorMap[] =
+{
+ "midnightblue", // Public
+ "darkgreen", // Protected
+ "firebrick4", // Private
+ "grey25", // "use" relation
+ "grey75", // Undocumented
+ "orange" // template relation
+};
+
+static const char *umlArrowStyleMap[] =
+{
+ "onormal", // Public
+ "onormal", // Protected
+ "onormal", // Private
+ "odiamond", // "use" relation
+ 0, // Undocumented
+ 0 // template relation
+};
+
+static const char *umlEdgeStyleMap[] =
+{
+ "solid", // inheritance
+ "solid" // usage
+};
+
+/** Helper struct holding the properties of a edge in a dot graph. */
+struct EdgeProperties
+{
+ const char * const *edgeColorMap;
+ const char * const *arrowStyleMap;
+ const char * const *edgeStyleMap;
+};
+
+static EdgeProperties normalEdgeProps =
+{
+ normalEdgeColorMap, normalArrowStyleMap, normalEdgeStyleMap
+};
+
+static EdgeProperties umlEdgeProps =
+{
+ umlEdgeColorMap, umlArrowStyleMap, umlEdgeStyleMap
+};
+
+
+static QCString getDotFontName()
+{
+ static QCString dotFontName = Config_getString("DOT_FONTNAME");
+ if (dotFontName.isEmpty())
+ {
+ //dotFontName="FreeSans.ttf";
+ dotFontName="Helvetica";
+ }
+ return dotFontName;
+}
+
+static int getDotFontSize()
+{
+ static int dotFontSize = Config_getInt("DOT_FONTSIZE");
+ if (dotFontSize<4) dotFontSize=4;
+ return dotFontSize;
+}
+
+static void writeGraphHeader(FTextStream &t,const QCString &title=QCString())
+{
+ static bool interactiveSVG = Config_getBool("INTERACTIVE_SVG");
+ t << "digraph ";
+ if (title.isEmpty())
+ {
+ t << "\"Dot Graph\"";
+ }
+ else
+ {
+ t << "\"" << convertToXML(title) << "\"";
+ }
+ t << endl << "{" << endl;
+ if (interactiveSVG) // insert a comment to force regeneration when this
+ // option is toggled
+ {
+ t << " // INTERACTIVE_SVG=YES\n";
+ }
+ if (Config_getBool("DOT_TRANSPARENT"))
+ {
+ t << " bgcolor=\"transparent\";" << endl;
+ }
+ t << " edge [fontname=\"" << FONTNAME << "\","
+ "fontsize=\"" << FONTSIZE << "\","
+ "labelfontname=\"" << FONTNAME << "\","
+ "labelfontsize=\"" << FONTSIZE << "\"];\n";
+ t << " node [fontname=\"" << FONTNAME << "\","
+ "fontsize=\"" << FONTSIZE << "\",shape=record];\n";
+}
+
+static void writeGraphFooter(FTextStream &t)
+{
+ t << "}" << endl;
+}
+
+static QCString replaceRef(const QCString &buf,const QCString relPath,
+ bool urlOnly,const QCString &context,const QCString &target=QCString())
+{
+ // search for href="...", store ... part in link
+ QCString href = "href";
+ //bool isXLink=FALSE;
+ int len = 6;
+ int indexS = buf.find("href=\""), indexE;
+ if (indexS>5 && buf.find("xlink:href=\"")!=-1) // XLink href (for SVG)
+ {
+ indexS-=6;
+ len+=6;
+ href.prepend("xlink:");
+ //isXLink=TRUE;
+ }
+ if (indexS>=0 && (indexE=buf.find('"',indexS+len))!=-1)
+ {
+ QCString link = buf.mid(indexS+len,indexE-indexS-len);
+ QCString result;
+ if (urlOnly) // for user defined dot graphs
+ {
+ if (link.left(5)=="\\ref " || link.left(5)=="@ref ") // \ref url
+ {
+ result=href+"=\"";
+ // fake ref node to resolve the url
+ DocRef *df = new DocRef( (DocNode*) 0, link.mid(5), context );
+ result+=externalRef(relPath,df->ref(),TRUE);
+ if (!df->file().isEmpty())
+ result += df->file().data() + Doxygen::htmlFileExtension;
+ if (!df->anchor().isEmpty())
+ result += "#" + df->anchor();
+ delete df;
+ result += "\"";
+ }
+ else
+ {
+ result = href+"=\"" + link + "\"";
+ }
+ }
+ else // ref$url (external ref via tag file), or $url (local ref)
+ {
+ int marker = link.find('$');
+ if (marker!=-1)
+ {
+ QCString ref = link.left(marker);
+ QCString url = link.mid(marker+1);
+ if (!ref.isEmpty())
+ {
+ result = externalLinkTarget() + externalRef(relPath,ref,FALSE);
+ }
+ result+= href+"=\"";
+ result+=externalRef(relPath,ref,TRUE);
+ result+= url + "\"";
+ }
+ else // should not happen, but handle properly anyway
+ {
+ result = href+"=\"" + link + "\"";
+ }
+ }
+ if (!target.isEmpty())
+ {
+ result+=" target=\""+target+"\"";
+ }
+ QCString leftPart = buf.left(indexS);
+ QCString rightPart = buf.mid(indexE+1);
+ return leftPart + result + rightPart;
+ }
+ else
+ {
+ return buf;
+ }
+}
+
+/*! converts the rectangles in a client site image map into a stream
+ * \param t the stream to which the result is written.
+ * \param mapName the name of the map file.
+ * \param relPath the relative path to the root of the output directory
+ * (used in case CREATE_SUBDIRS is enabled).
+ * \param urlOnly if FALSE the url field in the map contains an external
+ * references followed by a $ and then the URL.
+ * \param context the context (file, class, or namespace) in which the
+ * map file was found
+ * \returns TRUE if successful.
+ */
+static bool convertMapFile(FTextStream &t,const char *mapName,
+ const QCString relPath, bool urlOnly=FALSE,
+ const QCString &context=QCString())
+{
+ QFile f(mapName);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("problems opening map file %s for inclusion in the docs!\n"
+ "If you installed Graphviz/dot after a previous failing run, \n"
+ "try deleting the output directory and rerun doxygen.\n",mapName);
+ return FALSE;
+ }
+ const int maxLineLen=10240;
+ while (!f.atEnd()) // foreach line
+ {
+ QCString buf(maxLineLen);
+ int numBytes = f.readLine(buf.data(),maxLineLen);
+ buf[numBytes-1]='\0';
+
+ if (buf.left(5)=="<area")
+ {
+ t << replaceRef(buf,relPath,urlOnly,context);
+ }
+ }
+ return TRUE;
+}
+
+static QArray<int> s_newNumber;
+static int s_max_newNumber=0;
+
+inline int reNumberNode(int number, bool doReNumbering)
+{
+ if (!doReNumbering)
+ {
+ return number;
+ }
+ else
+ {
+ int s = s_newNumber.size();
+ if (number>=s)
+ {
+ int ns=0;
+ ns = s * 3 / 2 + 5; // new size
+ if (number>=ns) // number still doesn't fit
+ {
+ ns = number * 3 / 2 + 5;
+ }
+ s_newNumber.resize(ns);
+ for (int i=s;i<ns;i++) // clear new part of the array
+ {
+ s_newNumber.at(i)=0;
+ }
+ }
+ int i = s_newNumber.at(number);
+ if (i == 0) // not yet mapped
+ {
+ i = ++s_max_newNumber; // start from 1
+ s_newNumber.at(number) = i;
+ }
+ return i;
+ }
+}
+
+static void resetReNumbering()
+{
+ s_max_newNumber=0;
+ s_newNumber.resize(s_max_newNumber);
+}
+
+static QCString g_dotFontPath;
+
+static void setDotFontPath(const char *path)
+{
+ ASSERT(g_dotFontPath.isEmpty());
+ g_dotFontPath = portable_getenv("DOTFONTPATH");
+ QCString newFontPath = Config_getString("DOT_FONTPATH");
+ QCString spath = path;
+ if (!newFontPath.isEmpty() && !spath.isEmpty())
+ {
+ newFontPath.prepend(spath+portable_pathListSeparator());
+ }
+ else if (newFontPath.isEmpty() && !spath.isEmpty())
+ {
+ newFontPath=path;
+ }
+ else
+ {
+ portable_unsetenv("DOTFONTPATH");
+ return;
+ }
+ portable_setenv("DOTFONTPATH",newFontPath);
+}
+
+static void unsetDotFontPath()
+{
+ if (g_dotFontPath.isEmpty())
+ {
+ portable_unsetenv("DOTFONTPATH");
+ }
+ else
+ {
+ portable_setenv("DOTFONTPATH",g_dotFontPath);
+ }
+ g_dotFontPath="";
+}
+
+static bool readBoundingBox(const char *fileName,int *width,int *height,bool isEps)
+{
+ QCString bb = isEps ? QCString("%%PageBoundingBox:") : QCString("/MediaBox [");
+ QFile f(fileName);
+ if (!f.open(IO_ReadOnly|IO_Raw))
+ {
+ //printf("readBoundingBox: could not open %s\n",fileName);
+ return FALSE;
+ }
+ const int maxLineLen=1024;
+ char buf[maxLineLen];
+ while (!f.atEnd())
+ {
+ int numBytes = f.readLine(buf,maxLineLen-1); // read line
+ if (numBytes>0)
+ {
+ buf[numBytes]='\0';
+ const char *p = strstr(buf,bb);
+ if (p) // found PageBoundingBox or /MediaBox string
+ {
+ int x,y;
+ if (sscanf(p+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4)
+ {
+ //printf("readBoundingBox sscanf fail\n");
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+ else // read error!
+ {
+ //printf("Read error %d!\n",numBytes);
+ return FALSE;
+ }
+ }
+ err("Failed to extract bounding box from generated diagram file %s\n",fileName);
+ return FALSE;
+}
+
+static bool writeVecGfxFigure(FTextStream &out,const QCString &baseName,
+ const QCString &figureName)
+{
+ int width=400,height=550;
+ static bool usePdfLatex = Config_getBool("USE_PDFLATEX");
+ if (usePdfLatex)
+ {
+ if (!readBoundingBox(figureName+".pdf",&width,&height,FALSE))
+ {
+ //printf("writeVecGfxFigure()=0\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!readBoundingBox(figureName+".eps",&width,&height,TRUE))
+ {
+ //printf("writeVecGfxFigure()=0\n");
+ return FALSE;
+ }
+ }
+ //printf("Got PDF/EPS size %d,%d\n",width,height);
+ int maxWidth = 350; /* approx. page width in points, excl. margins */
+ int maxHeight = 550; /* approx. page height in points, excl. margins */
+ out << "\\nopagebreak\n"
+ "\\begin{figure}[H]\n"
+ "\\begin{center}\n"
+ "\\leavevmode\n";
+ if (width>maxWidth || height>maxHeight) // figure too big for page
+ {
+ // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0
+ if (width*maxHeight>height*maxWidth)
+ {
+ out << "\\includegraphics[width=" << maxWidth << "pt]";
+ }
+ else
+ {
+ out << "\\includegraphics[height=" << maxHeight << "pt]";
+ }
+ }
+ else
+ {
+ out << "\\includegraphics[width=" << width << "pt]";
+ }
+
+ out << "{" << baseName << "}\n"
+ "\\end{center}\n"
+ "\\end{figure}\n";
+
+ //printf("writeVecGfxFigure()=1\n");
+ return TRUE;
+}
+
+// extract size from a dot generated SVG file
+static bool readSVGSize(const QCString &fileName,int *width,int *height)
+{
+ bool found=FALSE;
+ QFile f(fileName);
+ if (!f.open(IO_ReadOnly))
+ {
+ return FALSE;
+ }
+ const int maxLineLen=4096;
+ char buf[maxLineLen];
+ while (!f.atEnd() && !found)
+ {
+ int numBytes = f.readLine(buf,maxLineLen-1); // read line
+ if (numBytes>0)
+ {
+ buf[numBytes]='\0';
+ if (qstrncmp(buf,"<!--zoomable ",13)==0)
+ {
+ *width=-1;
+ *height=-1;
+ sscanf(buf,"<!--zoomable %d",height);
+ //printf("Found zoomable for %s!\n",fileName.data());
+ found=TRUE;
+ }
+ else if (sscanf(buf,"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
+ {
+ //printf("Found fixed size %dx%d for %s!\n",*width,*height,fileName.data());
+ found=TRUE;
+ }
+ }
+ else // read error!
+ {
+ //printf("Read error %d!\n",numBytes);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void writeSVGNotSupported(FTextStream &out)
+{
+ out << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
+}
+
+// check if a reference to a SVG figure can be written and does so if possible.
+// return FALSE if not possible (for instance because the SVG file is not yet generated).
+static bool writeSVGFigureLink(FTextStream &out,const QCString &relPath,
+ const QCString &baseName,const QCString &absImgName)
+{
+ int width=600,height=600;
+ if (!readSVGSize(absImgName,&width,&height))
+ {
+ return FALSE;
+ }
+ if (width==-1)
+ {
+ if (height<=60)
+ height=300;
+ else
+ height+=300; // add some extra space for zooming
+ if (height>600) height=600; // clip to maximum height of 600 pixels
+ out << "<div class=\"zoom\">";
+ //out << "<object type=\"image/svg+xml\" data=\""
+ //out << "<embed type=\"image/svg+xml\" src=\""
+ out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
+ << relPath << baseName << ".svg\" width=\"100%\" height=\"" << height << "\">";
+ }
+ else
+ {
+ //out << "<object type=\"image/svg+xml\" data=\""
+ //out << "<embed type=\"image/svg+xml\" src=\""
+ out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
+ << relPath << baseName << ".svg\" width=\""
+ << ((width*96+48)/72) << "\" height=\""
+ << ((height*96+48)/72) << "\">";
+ }
+ writeSVGNotSupported(out);
+ //out << "</object>";
+ //out << "</embed>";
+ out << "</iframe>";
+ if (width==-1)
+ {
+ out << "</div>";
+ }
+
+ return TRUE;
+}
+
+// since dot silently reproduces the input file when it does not
+// support the PNG format, we need to check the result.
+static void checkDotResult(const QCString &imgName)
+{
+ if (Config_getEnum("DOT_IMAGE_FORMAT")=="png")
+ {
+ FILE *f = portable_fopen(imgName,"rb");
+ if (f)
+ {
+ char data[4];
+ if (fread(data,1,4,f)==4)
+ {
+ if (!(data[1]=='P' && data[2]=='N' && data[3]=='G'))
+ {
+ err("Image `%s' produced by dot is not a valid PNG!\n"
+ "You should either select a different format "
+ "(DOT_IMAGE_FORMAT in the config file) or install a more "
+ "recent version of graphviz (1.7+)\n",imgName.data()
+ );
+ }
+ }
+ else
+ {
+ err("Could not read image `%s' generated by dot!\n",imgName.data());
+ }
+ fclose(f);
+ }
+ else
+ {
+ err("Could not open image `%s' generated by dot!\n",imgName.data());
+ }
+ }
+}
+
+static bool insertMapFile(FTextStream &out,const QCString &mapFile,
+ const QCString &relPath,const QCString &mapLabel)
+{
+ QFileInfo fi(mapFile);
+ if (fi.exists() && fi.size()>0) // reuse existing map file
+ {
+ QGString tmpstr;
+ FTextStream tmpout(&tmpstr);
+ convertMapFile(tmpout,mapFile,relPath);
+ if (!tmpstr.isEmpty())
+ {
+ out << "<map name=\"" << mapLabel << "\" id=\"" << mapLabel << "\">" << endl;
+ out << tmpstr;
+ out << "</map>" << endl;
+ }
+ return TRUE;
+ }
+ return FALSE; // no map file yet, need to generate it
+}
+
+static void removeDotGraph(const QCString &dotName)
+{
+ static bool dotCleanUp = Config_getBool("DOT_CLEANUP");
+ if (dotCleanUp)
+ {
+ QDir d;
+ d.remove(dotName);
+ }
+}
+
+
+
+/*! Checks if a file "baseName".md5 exists. If so the contents
+ * are compared with \a md5. If equal FALSE is returned. If the .md5
+ * file does not exist or its contents are not equal to \a md5,
+ * a new .md5 is generated with the \a md5 string as contents.
+ */
+static bool checkAndUpdateMd5Signature(const QCString &baseName,
+ const QCString &md5)
+{
+ QFile f(baseName+".md5");
+ if (f.open(IO_ReadOnly))
+ {
+ // read checksum
+ QCString md5stored(33);
+ int bytesRead=f.readBlock(md5stored.data(),32);
+ md5stored[32]='\0';
+ // compare checksum
+ if (bytesRead==32 && md5==md5stored)
+ {
+ // bail out if equal
+ return FALSE;
+ }
+ }
+ f.close();
+ // create checksum file
+ if (f.open(IO_WriteOnly))
+ {
+ f.writeBlock(md5.data(),32);
+ f.close();
+ }
+ return TRUE;
+}
+
+static bool checkDeliverables(const QCString &file1,
+ const QCString &file2=QCString())
+{
+ bool file1Ok = TRUE;
+ bool file2Ok = TRUE;
+ if (!file1.isEmpty())
+ {
+ QFileInfo fi(file1);
+ file1Ok = (fi.exists() && fi.size()>0);
+ }
+ if (!file2.isEmpty())
+ {
+ QFileInfo fi(file2);
+ file2Ok = (fi.exists() && fi.size()>0);
+ }
+ return file1Ok && file2Ok;
+}
+
+//--------------------------------------------------------------------
+
+/** Class representing a list of DotNode objects. */
+class DotNodeList : public QList<DotNode>
+{
+ public:
+ DotNodeList() : QList<DotNode>() {}
+ ~DotNodeList() {}
+ private:
+ int compareValues(const DotNode *n1,const DotNode *n2) const
+ {
+ return qstricmp(n1->m_label,n2->m_label);
+ }
+};
+
+//--------------------------------------------------------------------
+
+DotRunner::DotRunner(const QCString &file,const QCString &path,
+ bool checkResult,const QCString &imageName)
+ : m_file(file), m_path(path),
+ m_checkResult(checkResult), m_imageName(imageName)
+{
+ static bool dotCleanUp = Config_getBool("DOT_CLEANUP");
+ m_cleanUp = dotCleanUp;
+ m_jobs.setAutoDelete(TRUE);
+}
+
+void DotRunner::addJob(const char *format,const char *output)
+{
+ QCString args = QCString("-T")+format+" -o \""+output+"\"";
+ m_jobs.append(new QCString(args));
+}
+
+void DotRunner::addPostProcessing(const char *cmd,const char *args)
+{
+ m_postCmd = cmd;
+ m_postArgs = args;
+}
+
+bool DotRunner::run()
+{
+ int exitCode=0;
+ QCString dotExe = Config_getString("DOT_PATH")+"dot";
+ bool multiTargets = Config_getBool("DOT_MULTI_TARGETS");
+ QCString dotArgs;
+ QListIterator<QCString> li(m_jobs);
+ QCString *s;
+ QCString file = m_file;
+ QCString path = m_path;
+ QCString imageName = m_imageName;
+ QCString postCmd = m_postCmd;
+ QCString postArgs = m_postArgs;
+ bool checkResult = m_checkResult;
+ bool cleanUp = m_cleanUp;
+ if (multiTargets)
+ {
+ dotArgs="\""+file+"\"";
+ for (li.toFirst();(s=li.current());++li)
+ {
+ dotArgs+=' ';
+ dotArgs+=*s;
+ }
+ if ((exitCode=portable_system(dotExe,dotArgs,FALSE))!=0)
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ for (li.toFirst();(s=li.current());++li)
+ {
+ dotArgs="\""+file+"\" "+*s;
+ if ((exitCode=portable_system(dotExe,dotArgs,FALSE))!=0)
+ {
+ goto error;
+ }
+ }
+ }
+ if (!postCmd.isEmpty() && portable_system(postCmd,postArgs)!=0)
+ {
+ err("Problems running '%s' as a post-processing step for dot output\n",m_postCmd.data());
+ return FALSE;
+ }
+ if (checkResult) checkDotResult(imageName);
+ if (cleanUp)
+ {
+ //printf("removing dot file %s\n",m_file.data());
+ //QDir(path).remove(file);
+ m_cleanupItem.file = file;
+ m_cleanupItem.path = path;
+ }
+ return TRUE;
+error:
+ err("Problems running dot: exit code=%d, command='%s', arguments='%s'\n",
+ exitCode,dotExe.data(),dotArgs.data());
+ return FALSE;
+}
+
+//--------------------------------------------------------------------
+
+DotFilePatcher::DotFilePatcher(const char *patchFile)
+ : m_patchFile(patchFile)
+{
+ m_maps.setAutoDelete(TRUE);
+}
+
+QCString DotFilePatcher::file() const
+{
+ return m_patchFile;
+}
+
+int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath,
+ bool urlOnly,const QCString &context,const QCString &label)
+{
+ int id = m_maps.count();
+ Map *map = new Map;
+ map->mapFile = mapFile;
+ map->relPath = relPath;
+ map->urlOnly = urlOnly;
+ map->context = context;
+ map->label = label;
+ map->zoomable = FALSE;
+ map->graphId = -1;
+ m_maps.append(map);
+ return id;
+}
+
+int DotFilePatcher::addFigure(const QCString &baseName,
+ const QCString &figureName,bool heightCheck)
+{
+ int id = m_maps.count();
+ Map *map = new Map;
+ map->mapFile = figureName;
+ map->urlOnly = heightCheck;
+ map->label = baseName;
+ map->zoomable = FALSE;
+ map->graphId = -1;
+ m_maps.append(map);
+ return id;
+}
+
+int DotFilePatcher::addSVGConversion(const QCString &relPath,bool urlOnly,
+ const QCString &context,bool zoomable,
+ int graphId)
+{
+ int id = m_maps.count();
+ Map *map = new Map;
+ map->relPath = relPath;
+ map->urlOnly = urlOnly;
+ map->context = context;
+ map->zoomable = zoomable;
+ map->graphId = graphId;
+ m_maps.append(map);
+ return id;
+}
+
+int DotFilePatcher::addSVGObject(const QCString &baseName,
+ const QCString &absImgName,
+ const QCString &relPath)
+{
+ int id = m_maps.count();
+ Map *map = new Map;
+ map->mapFile = absImgName;
+ map->relPath = relPath;
+ map->label = baseName;
+ map->zoomable = FALSE;
+ map->graphId = -1;
+ m_maps.append(map);
+ return id;
+}
+
+bool DotFilePatcher::run()
+{
+ //printf("DotFilePatcher::run(): %s\n",m_patchFile.data());
+ static bool interactiveSVG = Config_getBool("INTERACTIVE_SVG");
+ bool isSVGFile = m_patchFile.right(4)==".svg";
+ int graphId = -1;
+ QCString relPath;
+ if (isSVGFile)
+ {
+ Map *map = m_maps.at(0); // there is only one 'map' for a SVG file
+ interactiveSVG = interactiveSVG && map->zoomable;
+ graphId = map->graphId;
+ relPath = map->relPath;
+ //printf("DotFilePatcher::addSVGConversion: file=%s zoomable=%d\n",
+ // m_patchFile.data(),map->zoomable);
+ }
+ QString tmpName = QString::fromUtf8(m_patchFile+".tmp");
+ QString patchFile = QString::fromUtf8(m_patchFile);
+ if (!QDir::current().rename(patchFile,tmpName))
+ {
+ err("Failed to rename file %s to %s!\n",m_patchFile.data(),tmpName.data());
+ return FALSE;
+ }
+ QFile fi(tmpName);
+ QFile fo(patchFile);
+ if (!fi.open(IO_ReadOnly))
+ {
+ err("problem opening file %s for patching!\n",tmpName.data());
+ QDir::current().rename(tmpName,patchFile);
+ return FALSE;
+ }
+ if (!fo.open(IO_WriteOnly))
+ {
+ err("problem opening file %s for patching!\n",m_patchFile.data());
+ QDir::current().rename(tmpName,patchFile);
+ return FALSE;
+ }
+ FTextStream t(&fo);
+ const int maxLineLen=100*1024;
+ int lineNr=1;
+ int width,height;
+ bool insideHeader=FALSE;
+ bool replacedHeader=FALSE;
+ bool foundSize=FALSE;
+ while (!fi.atEnd()) // foreach line
+ {
+ QCString line(maxLineLen);
+ int numBytes = fi.readLine(line.data(),maxLineLen);
+ if (numBytes<=0)
+ {
+ break;
+ }
+
+ //printf("line=[%s]\n",line.stripWhiteSpace().data());
+ int i;
+ ASSERT(numBytes<maxLineLen);
+ if (isSVGFile)
+ {
+ if (interactiveSVG)
+ {
+ if (line.find("<svg")!=-1 && !replacedHeader)
+ {
+ int count;
+ count = sscanf(line.data(),"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height);
+ //printf("width=%d height=%d\n",width,height);
+ foundSize = count==2 && (width>500 || height>450);
+ if (foundSize) insideHeader=TRUE;
+ }
+ else if (insideHeader && !replacedHeader && line.find("<title>")!=-1)
+ {
+ if (foundSize)
+ {
+ // insert special replacement header for interactive SVGs
+ t << "<!--zoomable " << height << " -->\n";
+ t << svgZoomHeader;
+ t << "var viewWidth = " << width << ";\n";
+ t << "var viewHeight = " << height << ";\n";
+ if (graphId>=0)
+ {
+ t << "var sectionId = 'dynsection-" << graphId << "';\n";
+ }
+ t << "</script>\n";
+ t << "<script xlink:href=\"" << relPath << "svgpan.js\"/>\n";
+ t << "<svg id=\"graph\" class=\"graph\">\n";
+ t << "<g id=\"viewport\">\n";
+ }
+ insideHeader=FALSE;
+ replacedHeader=TRUE;
+ }
+ }
+ if (!insideHeader || !foundSize) // copy SVG and replace refs,
+ // unless we are inside the header of the SVG.
+ // Then we replace it with another header.
+ {
+ Map *map = m_maps.at(0); // there is only one 'map' for a SVG file
+ t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top");
+ }
+ }
+ else if ((i=line.find("<!-- SVG"))!=-1 || (i=line.find("[!-- SVG"))!=-1)
+ {
+ //printf("Found marker at %d\n",i);
+ int mapId=-1;
+ t << line.left(i);
+ int n = sscanf(line.data()+i+1,"!-- SVG %d",&mapId);
+ if (n==1 && mapId>=0 && mapId<(int)m_maps.count())
+ {
+ int e = QMAX(line.find("--]"),line.find("-->"));
+ Map *map = m_maps.at(mapId);
+ //printf("DotFilePatcher::writeSVGFigure: file=%s zoomable=%d\n",
+ // m_patchFile.data(),map->zoomable);
+ if (!writeSVGFigureLink(t,map->relPath,map->label,map->mapFile))
+ {
+ err("Problem extracting size from SVG file %s\n",map->mapFile.data());
+ }
+ if (e!=-1) t << line.mid(e+3);
+ }
+ else // error invalid map id!
+ {
+ err("Found invalid SVG id in file %s!\n",m_patchFile.data());
+ t << line.mid(i);
+ }
+ }
+ else if ((i=line.find("<!-- MAP"))!=-1)
+ {
+ int mapId=-1;
+ t << line.left(i);
+ int n = sscanf(line.data()+i,"<!-- MAP %d",&mapId);
+ if (n==1 && mapId>=0 && mapId<(int)m_maps.count())
+ {
+ Map *map = m_maps.at(mapId);
+ //printf("patching MAP %d in file %s with contents of %s\n",
+ // mapId,m_patchFile.data(),map->mapFile.data());
+ t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl;
+ convertMapFile(t,map->mapFile,map->relPath,map->urlOnly,map->context);
+ t << "</map>" << endl;
+ }
+ else // error invalid map id!
+ {
+ err("Found invalid MAP id in file %s!\n",m_patchFile.data());
+ t << line.mid(i);
+ }
+ }
+ else if ((i=line.find("% FIG"))!=-1)
+ {
+ int mapId=-1;
+ int n = sscanf(line.data()+i+2,"FIG %d",&mapId);
+ //printf("line='%s' n=%d\n",line.data()+i,n);
+ if (n==1 && mapId>=0 && mapId<(int)m_maps.count())
+ {
+ Map *map = m_maps.at(mapId);
+ //printf("patching FIG %d in file %s with contents of %s\n",
+ // mapId,m_patchFile.data(),map->mapFile.data());
+ writeVecGfxFigure(t,map->label,map->mapFile);
+ }
+ else // error invalid map id!
+ {
+ err("Found invalid bounding FIG %d in file %s!\n",mapId,m_patchFile.data());
+ t << line;
+ }
+ }
+ else
+ {
+ t << line;
+ }
+ lineNr++;
+ }
+ fi.close();
+ if (isSVGFile && interactiveSVG && replacedHeader)
+ {
+ QCString orgName=m_patchFile.left(m_patchFile.length()-4)+"_org.svg";
+ t << substitute(svgZoomFooter,"$orgname",stripPath(orgName));
+ fo.close();
+ // keep original SVG file so we can refer to it, we do need to replace
+ // dummy link by real ones
+ QFile fi(tmpName);
+ QFile fo(orgName);
+ if (!fi.open(IO_ReadOnly))
+ {
+ err("problem opening file %s for reading!\n",tmpName.data());
+ return FALSE;
+ }
+ if (!fo.open(IO_WriteOnly))
+ {
+ err("problem opening file %s for writing!\n",orgName.data());
+ return FALSE;
+ }
+ FTextStream t(&fo);
+ while (!fi.atEnd()) // foreach line
+ {
+ QCString line(maxLineLen);
+ int numBytes = fi.readLine(line.data(),maxLineLen);
+ if (numBytes<=0)
+ {
+ break;
+ }
+ Map *map = m_maps.at(0); // there is only one 'map' for a SVG file
+ t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top");
+ }
+ fi.close();
+ fo.close();
+ }
+ // remove temporary file
+ QDir::current().remove(tmpName);
+ return TRUE;
+}
+
+//--------------------------------------------------------------------
+
+void DotRunnerQueue::enqueue(DotRunner *runner)
+{
+ QMutexLocker locker(&m_mutex);
+ m_queue.enqueue(runner);
+ m_bufferNotEmpty.wakeAll();
+}
+
+DotRunner *DotRunnerQueue::dequeue()
+{
+ QMutexLocker locker(&m_mutex);
+ while (m_queue.isEmpty())
+ {
+ // wait until something is added to the queue
+ m_bufferNotEmpty.wait(&m_mutex);
+ }
+ DotRunner *result = m_queue.dequeue();
+ return result;
+}
+
+uint DotRunnerQueue::count() const
+{
+ QMutexLocker locker(&m_mutex);
+ return m_queue.count();
+}
+
+//--------------------------------------------------------------------
+
+DotWorkerThread::DotWorkerThread(DotRunnerQueue *queue)
+ : m_queue(queue)
+{
+ m_cleanupItems.setAutoDelete(TRUE);
+}
+
+void DotWorkerThread::run()
+{
+ DotRunner *runner;
+ while ((runner=m_queue->dequeue()))
+ {
+ runner->run();
+ DotRunner::CleanupItem cleanup = runner->cleanup();
+ if (!cleanup.file.isEmpty())
+ {
+ m_cleanupItems.append(new DotRunner::CleanupItem(cleanup));
+ }
+ }
+}
+
+void DotWorkerThread::cleanup()
+{
+ QListIterator<DotRunner::CleanupItem> it(m_cleanupItems);
+ DotRunner::CleanupItem *ci;
+ for (;(ci=it.current());++it)
+ {
+ QDir(ci->path).remove(ci->file);
+ }
+}
+
+//--------------------------------------------------------------------
+
+DotManager *DotManager::m_theInstance = 0;
+
+DotManager *DotManager::instance()
+{
+ if (!m_theInstance)
+ {
+ m_theInstance = new DotManager;
+ }
+ return m_theInstance;
+}
+
+DotManager::DotManager() : m_dotMaps(1009)
+{
+ m_dotRuns.setAutoDelete(TRUE);
+ m_dotMaps.setAutoDelete(TRUE);
+ m_queue = new DotRunnerQueue;
+ int i;
+ int numThreads = QMIN(32,Config_getInt("DOT_NUM_THREADS"));
+ if (numThreads!=1)
+ {
+ if (numThreads==0) numThreads = QMAX(2,QThread::idealThreadCount()+1);
+ for (i=0;i<numThreads;i++)
+ {
+ DotWorkerThread *thread = new DotWorkerThread(m_queue);
+ thread->start();
+ if (thread->isRunning())
+ {
+ m_workers.append(thread);
+ }
+ else // no more threads available!
+ {
+ delete thread;
+ }
+ }
+ ASSERT(m_workers.count()>0);
+ }
+}
+
+DotManager::~DotManager()
+{
+ delete m_queue;
+}
+
+void DotManager::addRun(DotRunner *run)
+{
+ m_dotRuns.append(run);
+}
+
+int DotManager::addMap(const QCString &file,const QCString &mapFile,
+ const QCString &relPath,bool urlOnly,const QCString &context,
+ const QCString &label)
+{
+ DotFilePatcher *map = m_dotMaps.find(file);
+ if (map==0)
+ {
+ map = new DotFilePatcher(file);
+ m_dotMaps.append(file,map);
+ }
+ return map->addMap(mapFile,relPath,urlOnly,context,label);
+}
+
+int DotManager::addFigure(const QCString &file,const QCString &baseName,
+ const QCString &figureName,bool heightCheck)
+{
+ DotFilePatcher *map = m_dotMaps.find(file);
+ if (map==0)
+ {
+ map = new DotFilePatcher(file);
+ m_dotMaps.append(file,map);
+ }
+ return map->addFigure(baseName,figureName,heightCheck);
+}
+
+int DotManager::addSVGConversion(const QCString &file,const QCString &relPath,
+ bool urlOnly,const QCString &context,bool zoomable,
+ int graphId)
+{
+ DotFilePatcher *map = m_dotMaps.find(file);
+ if (map==0)
+ {
+ map = new DotFilePatcher(file);
+ m_dotMaps.append(file,map);
+ }
+ return map->addSVGConversion(relPath,urlOnly,context,zoomable,graphId);
+}
+
+int DotManager::addSVGObject(const QCString &file,const QCString &baseName,
+ const QCString &absImgName,const QCString &relPath)
+{
+ DotFilePatcher *map = m_dotMaps.find(file);
+ if (map==0)
+ {
+ map = new DotFilePatcher(file);
+ m_dotMaps.append(file,map);
+ }
+ return map->addSVGObject(baseName,absImgName,relPath);
+}
+
+bool DotManager::run()
+{
+ uint numDotRuns = m_dotRuns.count();
+ uint numDotMaps = m_dotMaps.count();
+ if (numDotRuns+numDotMaps>1)
+ {
+ if (m_workers.count()==0)
+ {
+ msg("Generating dot graphs in single threaded mode...\n");
+ }
+ else
+ {
+ msg("Generating dot graphs using %d parallel threads...\n",QMIN(numDotRuns+numDotMaps,m_workers.count()));
+ }
+ }
+ int i=1;
+ QListIterator<DotRunner> li(m_dotRuns);
+
+ bool setPath=FALSE;
+ if (Config_getBool("GENERATE_HTML"))
+ {
+ setDotFontPath(Config_getString("HTML_OUTPUT"));
+ setPath=TRUE;
+ }
+ else if (Config_getBool("GENERATE_LATEX"))
+ {
+ setDotFontPath(Config_getString("LATEX_OUTPUT"));
+ setPath=TRUE;
+ }
+ else if (Config_getBool("GENERATE_RTF"))
+ {
+ setDotFontPath(Config_getString("RTF_OUTPUT"));
+ setPath=TRUE;
+ }
+ portable_sysTimerStart();
+ // fill work queue with dot operations
+ DotRunner *dr;
+ int prev=1;
+ if (m_workers.count()==0) // no threads to work with
+ {
+ for (li.toFirst();(dr=li.current());++li)
+ {
+ msg("Running dot for graph %d/%d\n",prev,numDotRuns);
+ dr->run();
+ prev++;
+ }
+ }
+ else // use multiple threads to run instances of dot in parallel
+ {
+ for (li.toFirst();(dr=li.current());++li)
+ {
+ m_queue->enqueue(dr);
+ }
+ // wait for the queue to become empty
+ while ((i=m_queue->count())>0)
+ {
+ i = numDotRuns - i;
+ while (i>=prev)
+ {
+ msg("Running dot for graph %d/%d\n",prev,numDotRuns);
+ prev++;
+ }
+ portable_sleep(100);
+ }
+ while ((int)numDotRuns>=prev)
+ {
+ msg("Running dot for graph %d/%d\n",prev,numDotRuns);
+ prev++;
+ }
+ // signal the workers we are done
+ for (i=0;i<(int)m_workers.count();i++)
+ {
+ m_queue->enqueue(0); // add terminator for each worker
+ }
+ // wait for the workers to finish
+ for (i=0;i<(int)m_workers.count();i++)
+ {
+ m_workers.at(i)->wait();
+ }
+ // clean up dot files from main thread
+ for (i=0;i<(int)m_workers.count();i++)
+ {
+ m_workers.at(i)->cleanup();
+ }
+ }
+ portable_sysTimerStop();
+ if (setPath)
+ {
+ unsetDotFontPath();
+ }
+
+ // patch the output file and insert the maps and figures
+ i=1;
+ SDict<DotFilePatcher>::Iterator di(m_dotMaps);
+ DotFilePatcher *map;
+ // since patching the svg files may involve patching the header of the SVG
+ // (for zoomable SVGs), and patching the .html files requires reading that
+ // header after the SVG is patched, we first process the .svg files and
+ // then the other files.
+ for (di.toFirst();(map=di.current());++di)
+ {
+ if (map->file().right(4)==".svg")
+ {
+ msg("Patching output file %d/%d\n",i,numDotMaps);
+ if (!map->run()) return FALSE;
+ i++;
+ }
+ }
+ for (di.toFirst();(map=di.current());++di)
+ {
+ if (map->file().right(4)!=".svg")
+ {
+ msg("Patching output file %d/%d\n",i,numDotMaps);
+ if (!map->run()) return FALSE;
+ i++;
+ }
+ }
+ return TRUE;
+}
+
+//--------------------------------------------------------------------
+
+
+/*! helper function that deletes all nodes in a connected graph, given
+ * one of the graph's nodes
+ */
+static void deleteNodes(DotNode *node,SDict<DotNode> *skipNodes=0)
+{
+ //printf("deleteNodes skipNodes=%p\n",skipNodes);
+ static DotNodeList deletedNodes;
+ deletedNodes.setAutoDelete(TRUE);
+ node->deleteNode(deletedNodes,skipNodes); // collect nodes to be deleted.
+ deletedNodes.clear(); // actually remove the nodes.
+}
+
+DotNode::DotNode(int n,const char *lab,const char *tip, const char *url,
+ bool isRoot,ClassDef *cd)
+ : m_subgraphId(-1)
+ , m_number(n)
+ , m_label(lab)
+ , m_tooltip(tip)
+ , m_url(url)
+ , m_parents(0)
+ , m_children(0)
+ , m_edgeInfo(0)
+ , m_deleted(FALSE)
+ , m_written(FALSE)
+ , m_hasDoc(FALSE)
+ , m_isRoot(isRoot)
+ , m_classDef(cd)
+ , m_visible(FALSE)
+ , m_truncated(Unknown)
+ , m_distance(1000)
+{
+}
+
+DotNode::~DotNode()
+{
+ delete m_children;
+ delete m_parents;
+ delete m_edgeInfo;
+}
+
+void DotNode::addChild(DotNode *n,
+ int edgeColor,
+ int edgeStyle,
+ const char *edgeLab,
+ const char *edgeURL,
+ int edgeLabCol
+ )
+{
+ if (m_children==0)
+ {
+ m_children = new QList<DotNode>;
+ m_edgeInfo = new QList<EdgeInfo>;
+ m_edgeInfo->setAutoDelete(TRUE);
+ }
+ m_children->append(n);
+ EdgeInfo *ei = new EdgeInfo;
+ ei->m_color = edgeColor;
+ ei->m_style = edgeStyle;
+ ei->m_label = edgeLab;
+ ei->m_url = edgeURL;
+ if (edgeLabCol==-1)
+ ei->m_labColor=edgeColor;
+ else
+ ei->m_labColor=edgeLabCol;
+ m_edgeInfo->append(ei);
+}
+
+void DotNode::addParent(DotNode *n)
+{
+ if (m_parents==0)
+ {
+ m_parents = new QList<DotNode>;
+ }
+ m_parents->append(n);
+}
+
+void DotNode::removeChild(DotNode *n)
+{
+ if (m_children) m_children->remove(n);
+}
+
+void DotNode::removeParent(DotNode *n)
+{
+ if (m_parents) m_parents->remove(n);
+}
+
+void DotNode::deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes)
+{
+ if (m_deleted) return; // avoid recursive loops in case the graph has cycles
+ m_deleted=TRUE;
+ if (m_parents!=0) // delete all parent nodes of this node
+ {
+ QListIterator<DotNode> dnlip(*m_parents);
+ DotNode *pn;
+ for (dnlip.toFirst();(pn=dnlip.current());++dnlip)
+ {
+ //pn->removeChild(this);
+ pn->deleteNode(deletedList,skipNodes);
+ }
+ }
+ if (m_children!=0) // delete all child nodes of this node
+ {
+ QListIterator<DotNode> dnlic(*m_children);
+ DotNode *cn;
+ for (dnlic.toFirst();(cn=dnlic.current());++dnlic)
+ {
+ //cn->removeParent(this);
+ cn->deleteNode(deletedList,skipNodes);
+ }
+ }
+ // add this node to the list of deleted nodes.
+ //printf("skipNodes=%p find(%p)=%p\n",skipNodes,this,skipNodes ? skipNodes->find((int)this) : 0);
+ if (skipNodes==0 || skipNodes->find((char*)this)==0)
+ {
+ //printf("deleting\n");
+ deletedList.append(this);
+ }
+}
+
+void DotNode::setDistance(int distance)
+{
+ if (distance<m_distance) m_distance = distance;
+}
+
+static QCString convertLabel(const QCString &l)
+{
+ QCString result;
+ QCString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
+ QCString bAfter(">]),:;|"); // break after character set
+ const char *p=l.data();
+ if (p==0) return result;
+ char c,pc=0;
+ char cs[2];
+ cs[1]=0;
+ int len=l.length();
+ int charsLeft=len;
+ int sinceLast=0;
+ int foldLen=17; // ideal text length
+ while ((c=*p++))
+ {
+ QCString replacement;
+ switch(c)
+ {
+ case '\\': replacement="\\\\"; break;
+ case '\n': replacement="\\n"; break;
+ case '<': replacement="\\<"; break;
+ case '>': replacement="\\>"; break;
+ case '|': replacement="\\|"; break;
+ case '{': replacement="\\{"; break;
+ case '}': replacement="\\}"; break;
+ case '"': replacement="\\\""; break;
+ default: cs[0]=c; replacement=cs; break;
+ }
+ // Some heuristics to insert newlines to prevent too long
+ // boxes and at the same time prevent ugly breaks
+ if (c=='\n')
+ {
+ result+=replacement;
+ foldLen = (3*foldLen+sinceLast+2)/4;
+ sinceLast=1;
+ }
+ else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c))
+ {
+ result+="\\l";
+ result+=replacement;
+ foldLen = (foldLen+sinceLast+1)/2;
+ sinceLast=1;
+ }
+ else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
+ !isupper(c) && isupper(*p))
+ {
+ result+=replacement;
+ result+="\\l";
+ foldLen = (foldLen+sinceLast+1)/2;
+ sinceLast=0;
+ }
+ else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || *p!=':'))
+ {
+ result+=replacement;
+ result+="\\l";
+ foldLen = (foldLen+sinceLast+1)/2;
+ sinceLast=0;
+ }
+ else
+ {
+ result+=replacement;
+ sinceLast++;
+ }
+ charsLeft--;
+ pc=c;
+ }
+ return result;
+}
+
+static QCString escapeTooltip(const QCString &tooltip)
+{
+ QCString result;
+ const char *p=tooltip.data();
+ if (p==0) return result;
+ char c;
+ while ((c=*p++))
+ {
+ switch(c)
+ {
+ case '"': result+="\\\""; break;
+ default: result+=c; break;
+ }
+ }
+ return result;
+}
+
+static void writeBoxMemberList(FTextStream &t,
+ char prot,MemberList *ml,ClassDef *scope,
+ bool isStatic=FALSE,const QDict<void> *skipNames=0)
+{
+ (void)isStatic;
+ if (ml)
+ {
+ MemberListIterator mlia(*ml);
+ MemberDef *mma;
+ int totalCount=0;
+ for (mlia.toFirst();(mma = mlia.current());++mlia)
+ {
+ if (mma->getClassDef()==scope &&
+ (skipNames==0 || skipNames->find(mma->name())==0))
+ {
+ totalCount++;
+ }
+ }
+
+ int count=0;
+ for (mlia.toFirst();(mma = mlia.current());++mlia)
+ {
+ if (mma->getClassDef() == scope &&
+ (skipNames==0 || skipNames->find(mma->name())==0))
+ {
+ static int limit = Config_getInt("UML_LIMIT_NUM_FIELDS");
+ if (limit>0 && (totalCount>limit*3/2 && count>=limit))
+ {
+ t << theTranslator->trAndMore(QCString().sprintf("%d",totalCount-count)) << "\\l";
+ break;
+ }
+ else
+ {
+ t << prot << " ";
+ t << convertLabel(mma->name());
+ if (!mma->isObjCMethod() &&
+ (mma->isFunction() || mma->isSlot() || mma->isSignal())) t << "()";
+ t << "\\l";
+ count++;
+ }
+ }
+ }
+ // write member groups within the memberlist
+ MemberGroupList *mgl = ml->getMemberGroupList();
+ if (mgl)
+ {
+ MemberGroupListIterator mgli(*mgl);
+ MemberGroup *mg;
+ for (mgli.toFirst();(mg=mgli.current());++mgli)
+ {
+ if (mg->members())
+ {
+ writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames);
+ }
+ }
+ }
+ }
+}
+
+static QCString stripProtectionPrefix(const QCString &s)
+{
+ if (!s.isEmpty() && (s[0]=='-' || s[0]=='+' || s[0]=='~' || s[0]=='#'))
+ {
+ return s.mid(1);
+ }
+ else
+ {
+ return s;
+ }
+}
+
+void DotNode::writeBox(FTextStream &t,
+ GraphType gt,
+ GraphOutputFormat /*format*/,
+ bool hasNonReachableChildren,
+ bool reNumber)
+{
+ const char *labCol =
+ m_url.isEmpty() ? "grey75" : // non link
+ (
+ (hasNonReachableChildren) ? "red" : "black"
+ );
+ t << " Node" << reNumberNode(m_number,reNumber) << " [label=\"";
+ static bool umlLook = Config_getBool("UML_LOOK");
+
+ if (m_classDef && umlLook && (gt==Inheritance || gt==Collaboration))
+ {
+ // add names shown as relations to a dictionary, so we don't show
+ // them as attributes as well
+ QDict<void> arrowNames(17);
+ if (m_edgeInfo)
+ {
+ // for each edge
+ QListIterator<EdgeInfo> li(*m_edgeInfo);
+ EdgeInfo *ei;
+ for (li.toFirst();(ei=li.current());++li)
+ {
+ if (!ei->m_label.isEmpty()) // labels joined by \n
+ {
+ int li=ei->m_label.find('\n');
+ int p=0;
+ QCString lab;
+ while ((li=ei->m_label.find('\n',p))!=-1)
+ {
+ lab = stripProtectionPrefix(ei->m_label.mid(p,li-p));
+ arrowNames.insert(lab,(void*)0x8);
+ p=li+1;
+ }
+ lab = stripProtectionPrefix(ei->m_label.right(ei->m_label.length()-p));
+ arrowNames.insert(lab,(void*)0x8);
+ }
+ }
+ }
+
+ //printf("DotNode::writeBox for %s\n",m_classDef->name().data());
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ t << "{" << convertLabel(m_label);
+ t << "\\n|";
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubAttribs),m_classDef,FALSE,&arrowNames);
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticAttribs),m_classDef,TRUE,&arrowNames);
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_properties),m_classDef,FALSE,&arrowNames);
+ writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacAttribs),m_classDef,FALSE,&arrowNames);
+ writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticAttribs),m_classDef,TRUE,&arrowNames);
+ writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proAttribs),m_classDef,FALSE,&arrowNames);
+ writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticAttribs),m_classDef,TRUE,&arrowNames);
+ if (extractPrivate)
+ {
+ writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priAttribs),m_classDef,FALSE,&arrowNames);
+ writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticAttribs),m_classDef,TRUE,&arrowNames);
+ }
+ t << "|";
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubMethods),m_classDef);
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticMethods),m_classDef,TRUE);
+ writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubSlots),m_classDef);
+ writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacMethods),m_classDef);
+ writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticMethods),m_classDef,TRUE);
+ writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proMethods),m_classDef);
+ writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticMethods),m_classDef,TRUE);
+ writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proSlots),m_classDef);
+ if (extractPrivate)
+ {
+ writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priMethods),m_classDef);
+ writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticMethods),m_classDef,TRUE);
+ writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priSlots),m_classDef);
+ }
+ if (m_classDef->getLanguage()!=SrcLangExt_Fortran &&
+ m_classDef->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgdi(*m_classDef->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (mgdi.toFirst();(mg=mgdi.current());++mgdi)
+ {
+ if (mg->members())
+ {
+ writeBoxMemberList(t,'*',mg->members(),m_classDef,FALSE,&arrowNames);
+ }
+ }
+ }
+ t << "}";
+ }
+ else // standard look
+ {
+ t << convertLabel(m_label);
+ }
+ t << "\",height=0.2,width=0.4";
+ if (m_isRoot)
+ {
+ t << ",color=\"black\", fillcolor=\"grey75\", style=\"filled\", fontcolor=\"black\"";
+ }
+ else
+ {
+ static bool dotTransparent = Config_getBool("DOT_TRANSPARENT");
+ if (!dotTransparent)
+ {
+ t << ",color=\"" << labCol << "\", fillcolor=\"";
+ t << "white";
+ t << "\", style=\"filled\"";
+ }
+ else
+ {
+ t << ",color=\"" << labCol << "\"";
+ }
+ if (!m_url.isEmpty())
+ {
+ int anchorPos = m_url.findRev('#');
+ if (anchorPos==-1)
+ {
+ t << ",URL=\"" << m_url << Doxygen::htmlFileExtension << "\"";
+ }
+ else
+ {
+ t << ",URL=\"" << m_url.left(anchorPos) << Doxygen::htmlFileExtension
+ << m_url.right(m_url.length()-anchorPos) << "\"";
+ }
+ }
+ if (!m_tooltip.isEmpty())
+ {
+ t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\"";
+ }
+ }
+ t << "];" << endl;
+}
+
+void DotNode::writeArrow(FTextStream &t,
+ GraphType gt,
+ GraphOutputFormat format,
+ DotNode *cn,
+ EdgeInfo *ei,
+ bool topDown,
+ bool pointBack,
+ bool reNumber
+ )
+{
+ t << " Node";
+ if (topDown)
+ t << reNumberNode(cn->number(),reNumber);
+ else
+ t << reNumberNode(m_number,reNumber);
+ t << " -> Node";
+ if (topDown)
+ t << reNumberNode(m_number,reNumber);
+ else
+ t << reNumberNode(cn->number(),reNumber);
+ t << " [";
+
+ static bool umlLook = Config_getBool("UML_LOOK");
+ const EdgeProperties *eProps = umlLook ? ¨EdgeProps : &normalEdgeProps;
+ QCString aStyle = eProps->arrowStyleMap[ei->m_color];
+ bool umlUseArrow = aStyle=="odiamond";
+
+ if (pointBack && !umlUseArrow) t << "dir=\"back\",";
+ t << "color=\"" << eProps->edgeColorMap[ei->m_color]
+ << "\",fontsize=\"" << FONTSIZE << "\",";
+ t << "style=\"" << eProps->edgeStyleMap[ei->m_style] << "\"";
+ if (!ei->m_label.isEmpty())
+ {
+ t << ",label=\" " << convertLabel(ei->m_label) << "\" ";
+ }
+ if (umlLook &&
+ eProps->arrowStyleMap[ei->m_color] &&
+ (gt==Inheritance || gt==Collaboration)
+ )
+ {
+ bool rev = pointBack;
+ if (umlUseArrow) rev=!rev; // UML use relates has arrow on the start side
+ if (rev)
+ t << ",arrowtail=\"" << eProps->arrowStyleMap[ei->m_color] << "\"";
+ else
+ t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->m_color] << "\"";
+ }
+
+ if (format==GOF_BITMAP) t << ",fontname=\"" << FONTNAME << "\"";
+ t << "];" << endl;
+}
+
+void DotNode::write(FTextStream &t,
+ GraphType gt,
+ GraphOutputFormat format,
+ bool topDown,
+ bool toChildren,
+ bool backArrows,
+ bool reNumber
+ )
+{
+ //printf("DotNode::write(%d) name=%s this=%p written=%d\n",distance,m_label.data(),this,m_written);
+ if (m_written) return; // node already written to the output
+ if (!m_visible) return; // node is not visible
+ writeBox(t,gt,format,m_truncated==Truncated,reNumber);
+ m_written=TRUE;
+ QList<DotNode> *nl = toChildren ? m_children : m_parents;
+ if (nl)
+ {
+ if (toChildren)
+ {
+ QListIterator<DotNode> dnli1(*nl);
+ QListIterator<EdgeInfo> dnli2(*m_edgeInfo);
+ DotNode *cn;
+ for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2)
+ {
+ if (cn->isVisible())
+ {
+ //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",cn->label().data());
+ writeArrow(t,gt,format,cn,dnli2.current(),topDown,backArrows,reNumber);
+ }
+ cn->write(t,gt,format,topDown,toChildren,backArrows,reNumber);
+ }
+ }
+ else // render parents
+ {
+ QListIterator<DotNode> dnli(*nl);
+ DotNode *pn;
+ for (dnli.toFirst();(pn=dnli.current());++dnli)
+ {
+ if (pn->isVisible())
+ {
+ //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",pn->label().data());
+ writeArrow(t,
+ gt,
+ format,
+ pn,
+ pn->m_edgeInfo->at(pn->m_children->findRef(this)),
+ FALSE,
+ backArrows,
+ reNumber
+ );
+ }
+ pn->write(t,gt,format,TRUE,FALSE,backArrows,reNumber);
+ }
+ }
+ }
+ //printf("end DotNode::write(%d) name=%s\n",distance,m_label.data());
+}
+
+void DotNode::writeXML(FTextStream &t,bool isClassGraph)
+{
+ t << " <node id=\"" << m_number << "\">" << endl;
+ t << " <label>" << convertToXML(m_label) << "</label>" << endl;
+ if (!m_url.isEmpty())
+ {
+ QCString url(m_url);
+ char *refPtr = url.data();
+ char *urlPtr = strchr(url.data(),'$');
+ if (urlPtr)
+ {
+ *urlPtr++='\0';
+ t << " <link refid=\"" << convertToXML(urlPtr) << "\"";
+ if (*refPtr!='\0')
+ {
+ t << " external=\"" << convertToXML(refPtr) << "\"";
+ }
+ t << "/>" << endl;
+ }
+ }
+ if (m_children)
+ {
+ QListIterator<DotNode> nli(*m_children);
+ QListIterator<EdgeInfo> eli(*m_edgeInfo);
+ DotNode *childNode;
+ EdgeInfo *edgeInfo;
+ for (;(childNode=nli.current());++nli,++eli)
+ {
+ edgeInfo=eli.current();
+ t << " <childnode refid=\"" << childNode->m_number << "\" relation=\"";
+ if (isClassGraph)
+ {
+ switch(edgeInfo->m_color)
+ {
+ case EdgeInfo::Blue: t << "public-inheritance"; break;
+ case EdgeInfo::Green: t << "protected-inheritance"; break;
+ case EdgeInfo::Red: t << "private-inheritance"; break;
+ case EdgeInfo::Purple: t << "usage"; break;
+ case EdgeInfo::Orange: t << "template-instance"; break;
+ case EdgeInfo::Grey: ASSERT(0); break;
+ }
+ }
+ else // include graph
+ {
+ t << "include";
+ }
+ t << "\">" << endl;
+ if (!edgeInfo->m_label.isEmpty())
+ {
+ int p=0;
+ int ni;
+ while ((ni=edgeInfo->m_label.find('\n',p))!=-1)
+ {
+ t << " <edgelabel>"
+ << convertToXML(edgeInfo->m_label.mid(p,ni-p))
+ << "</edgelabel>" << endl;
+ p=ni+1;
+ }
+ t << " <edgelabel>"
+ << convertToXML(edgeInfo->m_label.right(edgeInfo->m_label.length()-p))
+ << "</edgelabel>" << endl;
+ }
+ t << " </childnode>" << endl;
+ }
+ }
+ t << " </node>" << endl;
+}
+
+void DotNode::writeDocbook(FTextStream &t,bool isClassGraph)
+{
+ t << " <node id=\"" << m_number << "\">" << endl;
+ t << " <label>" << convertToXML(m_label) << "</label>" << endl;
+ if (!m_url.isEmpty())
+ {
+ QCString url(m_url);
+ char *refPtr = url.data();
+ char *urlPtr = strchr(url.data(),'$');
+ if (urlPtr)
+ {
+ *urlPtr++='\0';
+ t << " <link refid=\"" << convertToXML(urlPtr) << "\"";
+ if (*refPtr!='\0')
+ {
+ t << " external=\"" << convertToXML(refPtr) << "\"";
+ }
+ t << "/>" << endl;
+ }
+ }
+ if (m_children)
+ {
+ QListIterator<DotNode> nli(*m_children);
+ QListIterator<EdgeInfo> eli(*m_edgeInfo);
+ DotNode *childNode;
+ EdgeInfo *edgeInfo;
+ for (;(childNode=nli.current());++nli,++eli)
+ {
+ edgeInfo=eli.current();
+ t << " <childnode refid=\"" << childNode->m_number << "\" relation=\"";
+ if (isClassGraph)
+ {
+ switch(edgeInfo->m_color)
+ {
+ case EdgeInfo::Blue: t << "public-inheritance"; break;
+ case EdgeInfo::Green: t << "protected-inheritance"; break;
+ case EdgeInfo::Red: t << "private-inheritance"; break;
+ case EdgeInfo::Purple: t << "usage"; break;
+ case EdgeInfo::Orange: t << "template-instance"; break;
+ case EdgeInfo::Grey: ASSERT(0); break;
+ }
+ }
+ else // include graph
+ {
+ t << "include";
+ }
+ t << "\">" << endl;
+ if (!edgeInfo->m_label.isEmpty())
+ {
+ int p=0;
+ int ni;
+ while ((ni=edgeInfo->m_label.find('\n',p))!=-1)
+ {
+ t << " <edgelabel>"
+ << convertToXML(edgeInfo->m_label.mid(p,ni-p))
+ << "</edgelabel>" << endl;
+ p=ni+1;
+ }
+ t << " <edgelabel>"
+ << convertToXML(edgeInfo->m_label.right(edgeInfo->m_label.length()-p))
+ << "</edgelabel>" << endl;
+ }
+ t << " </childnode>" << endl;
+ }
+ }
+ t << " </node>" << endl;
+}
+
+
+void DotNode::writeDEF(FTextStream &t)
+{
+ const char* nodePrefix = " node-";
+
+ t << " node = {" << endl;
+ t << nodePrefix << "id = " << m_number << ';' << endl;
+ t << nodePrefix << "label = '" << m_label << "';" << endl;
+
+ if (!m_url.isEmpty())
+ {
+ QCString url(m_url);
+ char *refPtr = url.data();
+ char *urlPtr = strchr(url.data(),'$');
+ if (urlPtr)
+ {
+ *urlPtr++='\0';
+ t << nodePrefix << "link = {" << endl << " "
+ << nodePrefix << "link-id = '" << urlPtr << "';" << endl;
+
+ if (*refPtr!='\0')
+ {
+ t << " " << nodePrefix << "link-external = '"
+ << refPtr << "';" << endl;
+ }
+ t << " };" << endl;
+ }
+ }
+ if (m_children)
+ {
+ QListIterator<DotNode> nli(*m_children);
+ QListIterator<EdgeInfo> eli(*m_edgeInfo);
+ DotNode *childNode;
+ EdgeInfo *edgeInfo;
+ for (;(childNode=nli.current());++nli,++eli)
+ {
+ edgeInfo=eli.current();
+ t << " node-child = {" << endl;
+ t << " child-id = '" << childNode->m_number << "';" << endl;
+ t << " relation = ";
+
+ switch(edgeInfo->m_color)
+ {
+ case EdgeInfo::Blue: t << "public-inheritance"; break;
+ case EdgeInfo::Green: t << "protected-inheritance"; break;
+ case EdgeInfo::Red: t << "private-inheritance"; break;
+ case EdgeInfo::Purple: t << "usage"; break;
+ case EdgeInfo::Orange: t << "template-instance"; break;
+ case EdgeInfo::Grey: ASSERT(0); break;
+ }
+ t << ';' << endl;
+
+ if (!edgeInfo->m_label.isEmpty())
+ {
+ t << " edgelabel = <<_EnD_oF_dEf_TeXt_" << endl
+ << edgeInfo->m_label << endl
+ << "_EnD_oF_dEf_TeXt_;" << endl;
+ }
+ t << " }; /* node-child */" << endl;
+ } /* for (;childNode...) */
+ }
+ t << " }; /* node */" << endl;
+}
+
+
+void DotNode::clearWriteFlag()
+{
+ m_written=FALSE;
+ if (m_parents!=0)
+ {
+ QListIterator<DotNode> dnlip(*m_parents);
+ DotNode *pn;
+ for (dnlip.toFirst();(pn=dnlip.current());++dnlip)
+ {
+ if (pn->m_written)
+ {
+ pn->clearWriteFlag();
+ }
+ }
+ }
+ if (m_children!=0)
+ {
+ QListIterator<DotNode> dnlic(*m_children);
+ DotNode *cn;
+ for (dnlic.toFirst();(cn=dnlic.current());++dnlic)
+ {
+ if (cn->m_written)
+ {
+ cn->clearWriteFlag();
+ }
+ }
+ }
+}
+
+void DotNode::colorConnectedNodes(int curColor)
+{
+ if (m_children)
+ {
+ QListIterator<DotNode> dnlic(*m_children);
+ DotNode *cn;
+ for (dnlic.toFirst();(cn=dnlic.current());++dnlic)
+ {
+ if (cn->m_subgraphId==-1) // uncolored child node
+ {
+ cn->m_subgraphId=curColor;
+ cn->markAsVisible();
+ cn->colorConnectedNodes(curColor);
+ //printf("coloring node %s (%p): %d\n",cn->m_label.data(),cn,cn->m_subgraphId);
+ }
+ }
+ }
+
+ if (m_parents)
+ {
+ QListIterator<DotNode> dnlip(*m_parents);
+ DotNode *pn;
+ for (dnlip.toFirst();(pn=dnlip.current());++dnlip)
+ {
+ if (pn->m_subgraphId==-1) // uncolored parent node
+ {
+ pn->m_subgraphId=curColor;
+ pn->markAsVisible();
+ pn->colorConnectedNodes(curColor);
+ //printf("coloring node %s (%p): %d\n",pn->m_label.data(),pn,pn->m_subgraphId);
+ }
+ }
+ }
+}
+
+const DotNode *DotNode::findDocNode() const
+{
+ if (!m_url.isEmpty()) return this;
+ //printf("findDocNode(): `%s'\n",m_label.data());
+ if (m_parents)
+ {
+ QListIterator<DotNode> dnli(*m_parents);
+ DotNode *pn;
+ for (dnli.toFirst();(pn=dnli.current());++dnli)
+ {
+ if (!pn->m_hasDoc)
+ {
+ pn->m_hasDoc=TRUE;
+ const DotNode *dn = pn->findDocNode();
+ if (dn) return dn;
+ }
+ }
+ }
+ if (m_children)
+ {
+ QListIterator<DotNode> dnli(*m_children);
+ DotNode *cn;
+ for (dnli.toFirst();(cn=dnli.current());++dnli)
+ {
+ if (!cn->m_hasDoc)
+ {
+ cn->m_hasDoc=TRUE;
+ const DotNode *dn = cn->findDocNode();
+ if (dn) return dn;
+ }
+ }
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+int DotGfxHierarchyTable::m_curNodeNumber;
+
+void DotGfxHierarchyTable::writeGraph(FTextStream &out,
+ const char *path,const char *fileName) const
+{
+ //printf("DotGfxHierarchyTable::writeGraph(%s)\n",name);
+ //printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count());
+
+ if (m_rootSubgraphs->count()==0) return;
+
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+
+ // put each connected subgraph of the hierarchy in a row of the HTML output
+ out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">" << endl;
+
+ QListIterator<DotNode> dnli(*m_rootSubgraphs);
+ DotNode *n;
+ int count=0;
+ for (dnli.toFirst();(n=dnli.current());++dnli)
+ {
+ QCString baseName;
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ baseName.sprintf("inherit_graph_%d",count++);
+ //baseName = convertNameToFile(baseName);
+ QCString imgName = baseName+"."+ imgExt;
+ QCString mapName = baseName+".map";
+ QCString absImgName = QCString(d.absPath().data())+"/"+imgName;
+ QCString absMapName = QCString(d.absPath().data())+"/"+mapName;
+ QCString absBaseName = QCString(d.absPath().data())+"/"+baseName;
+ QListIterator<DotNode> dnli2(*m_rootNodes);
+ DotNode *node;
+
+ // compute md5 checksum of the graph were are about to generate
+ QGString theGraph;
+ FTextStream md5stream(&theGraph);
+ writeGraphHeader(md5stream,theTranslator->trGraphicalHierarchy());
+ md5stream << " rankdir=\"LR\";" << endl;
+ for (dnli2.toFirst();(node=dnli2.current());++dnli2)
+ {
+ if (node->m_subgraphId==n->m_subgraphId)
+ {
+ node->clearWriteFlag();
+ }
+ }
+ for (dnli2.toFirst();(node=dnli2.current());++dnli2)
+ {
+ if (node->m_subgraphId==n->m_subgraphId)
+ {
+ node->write(md5stream,DotNode::Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE,TRUE);
+ }
+ }
+ writeGraphFooter(md5stream);
+ resetReNumbering();
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ bool regenerate=FALSE;
+ if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
+ !checkDeliverables(absImgName,absMapName))
+ {
+ regenerate=TRUE;
+ // image was new or has changed
+ QCString dotName=absBaseName+".dot";
+ QFile f(dotName);
+ if (!f.open(IO_WriteOnly)) return;
+ FTextStream t(&f);
+ t << theGraph;
+ f.close();
+ resetReNumbering();
+
+ DotRunner *dotRun = new DotRunner(dotName,d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+ }
+ else
+ {
+ removeDotGraph(absBaseName+".dot");
+ }
+ Doxygen::indexList->addImageFile(imgName);
+ // write image and map in a table row
+ QCString mapLabel = escapeCharsInString(n->m_label,FALSE);
+ out << "<tr><td>";
+ if (imgExt=="svg") // vector graphics
+ {
+ if (regenerate || !writeSVGFigureLink(out,QCString(),baseName,absImgName))
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,QCString(),
+ FALSE,QCString(),FALSE,0);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,
+ absImgName,QCString());
+ out << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ }
+ else // normal bitmap
+ {
+ out << "<img src=\"" << imgName << "\" border=\"0\" alt=\"\" usemap=\"#"
+ << mapLabel << "\"/>" << endl;
+
+ if (regenerate || !insertMapFile(out,absMapName,QCString(),mapLabel))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,QCString(),
+ FALSE,QCString(),mapLabel);
+ out << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+
+ out << "</td></tr>" << endl;
+ }
+ out << "</table>" << endl;
+}
+
+void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper)
+{
+ //printf("addHierarchy `%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count());
+ if (cd->subClasses())
+ {
+ BaseClassListIterator bcli(*cd->subClasses());
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ ClassDef *bClass=bcd->classDef;
+ //printf(" Trying sub class=`%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count());
+ if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses()))
+ {
+ DotNode *bn;
+ //printf(" Node `%s' Found visible class=`%s'\n",n->m_label.data(),
+ // bClass->name().data());
+ if ((bn=m_usedNodes->find(bClass->name()))) // node already present
+ {
+ if (n->m_children==0 || n->m_children->findRef(bn)==-1) // no arrow yet
+ {
+ n->addChild(bn,bcd->prot);
+ bn->addParent(n);
+ //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
+ // n->m_label.data(),
+ // bn->m_label.data(),
+ // bn->m_children ? bn->m_children->count() : 0,
+ // bn->m_parents ? bn->m_parents->count() : 0
+ // );
+ }
+ //else
+ //{
+ // printf(" Class already has an arrow!\n");
+ //}
+ }
+ else
+ {
+ QCString tmp_url="";
+ if (bClass->isLinkable() && !bClass->isHidden())
+ {
+ tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
+ if (!bClass->anchor().isEmpty())
+ {
+ tmp_url+="#"+bClass->anchor();
+ }
+ }
+ QCString tooltip = bClass->briefDescriptionAsTooltip();
+ bn = new DotNode(m_curNodeNumber++,
+ bClass->displayName(),
+ tooltip,
+ tmp_url.data()
+ );
+ n->addChild(bn,bcd->prot);
+ bn->addParent(n);
+ //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
+ // n->m_label.data(),
+ // bn->m_label.data(),
+ // bn->m_children ? bn->m_children->count() : 0,
+ // bn->m_parents ? bn->m_parents->count() : 0
+ // );
+ //printf(" inserting %s (%p)\n",bClass->name().data(),bn);
+ m_usedNodes->insert(bClass->name(),bn); // add node to the used list
+ }
+ if (!bClass->visited && !hideSuper && bClass->subClasses())
+ {
+ bool wasVisited=bClass->visited;
+ bClass->visited=TRUE;
+ addHierarchy(bn,bClass,wasVisited);
+ }
+ }
+ }
+ }
+ //printf("end addHierarchy\n");
+}
+
+void DotGfxHierarchyTable::addClassList(ClassSDict *cl)
+{
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toLast();(cd=cli.current());--cli)
+ {
+ //printf("Trying %s subClasses=%d\n",cd->name().data(),cd->subClasses()->count());
+ if (cd->getLanguage()==SrcLangExt_VHDL &&
+ (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS
+ )
+ {
+ continue;
+ }
+ if (!hasVisibleRoot(cd->baseClasses()) &&
+ cd->isVisibleInHierarchy()
+ ) // root node in the forest
+ {
+ QCString tmp_url="";
+ if (cd->isLinkable() && !cd->isHidden())
+ {
+ tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
+ if (!cd->anchor().isEmpty())
+ {
+ tmp_url+="#"+cd->anchor();
+ }
+ }
+ //printf("Inserting root class %s\n",cd->name().data());
+ QCString tooltip = cd->briefDescriptionAsTooltip();
+ DotNode *n = new DotNode(m_curNodeNumber++,
+ cd->displayName(),
+ tooltip,
+ tmp_url.data());
+
+ //m_usedNodes->clear();
+ m_usedNodes->insert(cd->name(),n);
+ m_rootNodes->insert(0,n);
+ if (!cd->visited && cd->subClasses())
+ {
+ addHierarchy(n,cd,cd->visited);
+ cd->visited=TRUE;
+ }
+ }
+ }
+}
+
+DotGfxHierarchyTable::DotGfxHierarchyTable()
+{
+ m_curNodeNumber=0;
+ m_rootNodes = new QList<DotNode>;
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes->setAutoDelete(TRUE);
+ m_rootSubgraphs = new DotNodeList;
+
+ // build a graph with each class as a node and the inheritance relations
+ // as edges
+ initClassHierarchy(Doxygen::classSDict);
+ initClassHierarchy(Doxygen::hiddenClasses);
+ addClassList(Doxygen::classSDict);
+ addClassList(Doxygen::hiddenClasses);
+ // m_usedNodes now contains all nodes in the graph
+
+ // color the graph into a set of independent subgraphs
+ bool done=FALSE;
+ int curColor=0;
+ QListIterator<DotNode> dnli(*m_rootNodes);
+ while (!done) // there are still nodes to color
+ {
+ DotNode *n;
+ done=TRUE; // we are done unless there are still uncolored nodes
+ for (dnli.toLast();(n=dnli.current());--dnli)
+ {
+ if (n->m_subgraphId==-1) // not yet colored
+ {
+ //printf("Starting at node %s (%p): %d\n",n->m_label.data(),n,curColor);
+ done=FALSE; // still uncolored nodes
+ n->m_subgraphId=curColor;
+ n->markAsVisible();
+ n->colorConnectedNodes(curColor);
+ curColor++;
+ const DotNode *dn=n->findDocNode();
+ if (dn!=0)
+ m_rootSubgraphs->inSort(dn);
+ else
+ m_rootSubgraphs->inSort(n);
+ }
+ }
+ }
+
+ //printf("Number of independent subgraphs: %d\n",curColor);
+ //QListIterator<DotNode> dnli2(*m_rootSubgraphs);
+ //DotNode *n;
+ //for (dnli2.toFirst();(n=dnli2.current());++dnli2)
+ //{
+ // printf("Node %s color=%d (c=%d,p=%d)\n",
+ // n->m_label.data(),n->m_subgraphId,
+ // n->m_children?n->m_children->count():0,
+ // n->m_parents?n->m_parents->count():0);
+ //}
+}
+
+DotGfxHierarchyTable::~DotGfxHierarchyTable()
+{
+ //printf("DotGfxHierarchyTable::~DotGfxHierarchyTable\n");
+
+ //QDictIterator<DotNode> di(*m_usedNodes);
+ //DotNode *n;
+ //for (;(n=di.current());++di)
+ //{
+ // printf("Node %p: %s\n",n,n->label().data());
+ //}
+
+ delete m_rootNodes;
+ delete m_usedNodes;
+ delete m_rootSubgraphs;
+}
+
+//--------------------------------------------------------------------
+
+int DotClassGraph::m_curNodeNumber = 0;
+
+void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
+ const char *label,const char *usedName,const char *templSpec,bool base,int distance)
+{
+ if (Config_getBool("HIDE_UNDOC_CLASSES") && !cd->isLinkable()) return;
+
+ int edgeStyle = (label || prot==EdgeInfo::Orange) ? EdgeInfo::Dashed : EdgeInfo::Solid;
+ QCString className;
+ if (usedName) // name is a typedef
+ {
+ className=usedName;
+ }
+ else if (templSpec) // name has a template part
+ {
+ className=insertTemplateSpecifierInScope(cd->name(),templSpec);
+ }
+ else // just a normal name
+ {
+ className=cd->displayName();
+ }
+ //printf("DotClassGraph::addClass(class=`%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n",
+ // className.data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base);
+ DotNode *bn = m_usedNodes->find(className);
+ if (bn) // class already inserted
+ {
+ if (base)
+ {
+ n->addChild(bn,prot,edgeStyle,label);
+ bn->addParent(n);
+ }
+ else
+ {
+ bn->addChild(n,prot,edgeStyle,label);
+ n->addParent(bn);
+ }
+ bn->setDistance(distance);
+ //printf(" add exiting node %s of %s\n",bn->m_label.data(),n->m_label.data());
+ }
+ else // new class
+ {
+ QCString displayName=className;
+ if (Config_getBool("HIDE_SCOPE_NAMES")) displayName=stripScope(displayName);
+ QCString tmp_url;
+ if (cd->isLinkable() && !cd->isHidden())
+ {
+ tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
+ if (!cd->anchor().isEmpty())
+ {
+ tmp_url+="#"+cd->anchor();
+ }
+ }
+ QCString tooltip = cd->briefDescriptionAsTooltip();
+ bn = new DotNode(m_curNodeNumber++,
+ displayName,
+ tooltip,
+ tmp_url.data(),
+ FALSE, // rootNode
+ cd
+ );
+ if (base)
+ {
+ n->addChild(bn,prot,edgeStyle,label);
+ bn->addParent(n);
+ }
+ else
+ {
+ bn->addChild(n,prot,edgeStyle,label);
+ n->addParent(bn);
+ }
+ bn->setDistance(distance);
+ m_usedNodes->insert(className,bn);
+ //printf(" add new child node `%s' to %s hidden=%d url=%s\n",
+ // className.data(),n->m_label.data(),cd->isHidden(),tmp_url.data());
+
+ buildGraph(cd,bn,base,distance+1);
+ }
+}
+
+void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includeParents)
+{
+ while (queue.count()>0)
+ {
+ DotNode *n = queue.take(0);
+ if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+ {
+ bool truncated = FALSE;
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (!dn->isVisible())
+ truncated = TRUE;
+ else
+ queue.append(dn);
+ }
+ }
+ if (n->m_parents && includeParents)
+ {
+ QListIterator<DotNode> li(*n->m_parents);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (!dn->isVisible())
+ truncated = TRUE;
+ else
+ queue.append(dn);
+ }
+ }
+ n->markAsTruncated(truncated);
+ }
+ }
+}
+
+bool DotClassGraph::determineVisibleNodes(DotNode *rootNode,
+ int maxNodes,bool includeParents)
+{
+ QList<DotNode> childQueue;
+ QList<DotNode> parentQueue;
+ QArray<int> childTreeWidth;
+ QArray<int> parentTreeWidth;
+ childQueue.append(rootNode);
+ if (includeParents) parentQueue.append(rootNode);
+ bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop
+ // despite being marked visible in the child loop
+ while ((childQueue.count()>0 || parentQueue.count()>0) && maxNodes>0)
+ {
+ static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH");
+ if (childQueue.count()>0)
+ {
+ DotNode *n = childQueue.take(0);
+ int distance = n->distance();
+ if (!n->isVisible() && distance<=maxDistance) // not yet processed
+ {
+ if (distance>0)
+ {
+ int oldSize=(int)childTreeWidth.size();
+ if (distance>oldSize)
+ {
+ childTreeWidth.resize(QMAX(childTreeWidth.size(),(uint)distance));
+ int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0;
+ }
+ childTreeWidth[distance-1]+=n->label().length();
+ }
+ n->markAsVisible();
+ maxNodes--;
+ // add direct children
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ childQueue.append(dn);
+ }
+ }
+ }
+ }
+ if (includeParents && parentQueue.count()>0)
+ {
+ DotNode *n = parentQueue.take(0);
+ if ((!n->isVisible() || firstNode) && n->distance()<=maxDistance) // not yet processed
+ {
+ firstNode=FALSE;
+ int distance = n->distance();
+ if (distance>0)
+ {
+ int oldSize = (int)parentTreeWidth.size();
+ if (distance>oldSize)
+ {
+ parentTreeWidth.resize(QMAX(parentTreeWidth.size(),(uint)distance));
+ int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0;
+ }
+ parentTreeWidth[distance-1]+=n->label().length();
+ }
+ n->markAsVisible();
+ maxNodes--;
+ // add direct parents
+ if (n->m_parents)
+ {
+ QListIterator<DotNode> li(*n->m_parents);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ parentQueue.append(dn);
+ }
+ }
+ }
+ }
+ }
+ if (Config_getBool("UML_LOOK")) return FALSE; // UML graph are always top to bottom
+ int maxWidth=0;
+ int maxHeight=(int)QMAX(childTreeWidth.size(),parentTreeWidth.size());
+ uint i;
+ for (i=0;i<childTreeWidth.size();i++)
+ {
+ if (childTreeWidth.at(i)>maxWidth) maxWidth=childTreeWidth.at(i);
+ }
+ for (i=0;i<parentTreeWidth.size();i++)
+ {
+ if (parentTreeWidth.at(i)>maxWidth) maxWidth=parentTreeWidth.at(i);
+ }
+ //printf("max tree width=%d, max tree height=%d\n",maxWidth,maxHeight);
+ return maxWidth>80 && maxHeight<12; // used metric to decide to render the tree
+ // from left to right instead of top to bottom,
+ // with the idea to render very wide trees in
+ // left to right order.
+}
+
+void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base,int distance)
+{
+ //printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n",
+ // cd->name().data(),distance,base);
+ // ---- Add inheritance relations
+
+ if (m_graphType == DotNode::Inheritance || m_graphType==DotNode::Collaboration)
+ {
+ BaseClassList *bcl = base ? cd->baseClasses() : cd->subClasses();
+ if (bcl)
+ {
+ BaseClassListIterator bcli(*bcl);
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ //printf("-------- inheritance relation %s->%s templ=`%s'\n",
+ // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
+ addClass(bcd->classDef,n,bcd->prot,0,bcd->usedName,
+ bcd->templSpecifiers,base,distance);
+ }
+ }
+ }
+ if (m_graphType == DotNode::Collaboration)
+ {
+ // ---- Add usage relations
+
+ UsesClassDict *dict =
+ base ? cd->usedImplementationClasses() :
+ cd->usedByImplementationClasses()
+ ;
+ if (dict)
+ {
+ UsesClassDictIterator ucdi(*dict);
+ UsesClassDef *ucd;
+ for (;(ucd=ucdi.current());++ucdi)
+ {
+ QCString label;
+ QDictIterator<void> dvi(*ucd->accessors);
+ const char *s;
+ bool first=TRUE;
+ int count=0;
+ int maxLabels=10;
+ for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++count)
+ {
+ if (first)
+ {
+ label=s;
+ first=FALSE;
+ }
+ else
+ {
+ label+=QCString("\n")+s;
+ }
+ }
+ if (count==maxLabels) label+="\n...";
+ //printf("addClass: %s templSpec=%s\n",ucd->classDef->name().data(),ucd->templSpecifiers.data());
+ addClass(ucd->classDef,n,EdgeInfo::Purple,label,0,
+ ucd->templSpecifiers,base,distance);
+ }
+ }
+ }
+
+ // ---- Add template instantiation relations
+
+ static bool templateRelations = Config_getBool("TEMPLATE_RELATIONS");
+ if (templateRelations)
+ {
+ if (base) // template relations for base classes
+ {
+ ClassDef *templMaster=cd->templateMaster();
+ if (templMaster)
+ {
+ QDictIterator<ClassDef> cli(*templMaster->getTemplateInstances());
+ ClassDef *templInstance;
+ for (;(templInstance=cli.current());++cli)
+ {
+ if (templInstance==cd)
+ {
+ addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),0,
+ 0,TRUE,distance);
+ }
+ }
+ }
+ }
+ else // template relations for super classes
+ {
+ QDict<ClassDef> *templInstances = cd->getTemplateInstances();
+ if (templInstances)
+ {
+ QDictIterator<ClassDef> cli(*templInstances);
+ ClassDef *templInstance;
+ for (;(templInstance=cli.current());++cli)
+ {
+ addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),0,
+ 0,FALSE,distance);
+ }
+ }
+ }
+ }
+}
+
+DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t)
+{
+ //printf("--------------- DotClassGraph::DotClassGraph `%s'\n",cd->displayName().data());
+ m_graphType = t;
+ QCString tmp_url="";
+ if (cd->isLinkable() && !cd->isHidden())
+ {
+ tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
+ if (!cd->anchor().isEmpty())
+ {
+ tmp_url+="#"+cd->anchor();
+ }
+ }
+ QCString className = cd->displayName();
+ QCString tooltip = cd->briefDescriptionAsTooltip();
+ m_startNode = new DotNode(m_curNodeNumber++,
+ className,
+ tooltip,
+ tmp_url.data(),
+ TRUE, // is a root node
+ cd
+ );
+ m_startNode->setDistance(0);
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes->insert(className,m_startNode);
+
+ //printf("Root node %s\n",cd->name().data());
+ //if (m_recDepth>0)
+ //{
+ buildGraph(cd,m_startNode,TRUE,1);
+ if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE,1);
+ //}
+
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (t==DotNode::Inheritance && m_startNode->m_parents!=0)
+ // directChildNodes+=m_startNode->m_parents->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ //openNodeQueue.append(m_startNode);
+ m_lrRank = determineVisibleNodes(m_startNode,maxNodes,t==DotNode::Inheritance);
+ QList<DotNode> openNodeQueue;
+ openNodeQueue.append(m_startNode);
+ determineTruncatedNodes(openNodeQueue,t==DotNode::Inheritance);
+
+ m_diskName = cd->getFileBase().copy();
+}
+
+bool DotClassGraph::isTrivial() const
+{
+ static bool umlLook = Config_getBool("UML_LOOK");
+ if (m_graphType==DotNode::Inheritance)
+ return m_startNode->m_children==0 && m_startNode->m_parents==0;
+ else
+ return !umlLook && m_startNode->m_children==0;
+}
+
+bool DotClassGraph::isTooBig() const
+{
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = 0;
+ numNodes+= m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ if (m_graphType==DotNode::Inheritance)
+ {
+ numNodes+= m_startNode->m_parents ? m_startNode->m_parents->count() : 0;
+ }
+ return numNodes>=maxNodes;
+}
+
+DotClassGraph::~DotClassGraph()
+{
+ deleteNodes(m_startNode);
+ delete m_usedNodes;
+}
+
+/*! Computes a 16 byte md5 checksum for a given dot graph.
+ * The md5 checksum is returned as a 32 character ASCII string.
+ */
+QCString computeMd5Signature(DotNode *root,
+ DotNode::GraphType gt,
+ GraphOutputFormat format,
+ bool lrRank,
+ bool renderParents,
+ bool backArrows,
+ const QCString &title,
+ QCString &graphStr
+ )
+{
+ bool reNumber=TRUE;
+
+ //printf("computeMd5Signature\n");
+ QGString buf;
+ FTextStream md5stream(&buf);
+ writeGraphHeader(md5stream,title);
+ if (lrRank)
+ {
+ md5stream << " rankdir=\"LR\";" << endl;
+ }
+ root->clearWriteFlag();
+ root->write(md5stream,
+ gt,
+ format,
+ gt!=DotNode::CallGraph && gt!=DotNode::Dependency,
+ TRUE,
+ backArrows,
+ reNumber);
+ if (renderParents && root->m_parents)
+ {
+ QListIterator<DotNode> dnli(*root->m_parents);
+ DotNode *pn;
+ for (dnli.toFirst();(pn=dnli.current());++dnli)
+ {
+ if (pn->isVisible())
+ {
+ root->writeArrow(md5stream, // stream
+ gt, // graph type
+ format, // output format
+ pn, // child node
+ pn->m_edgeInfo->at(pn->m_children->findRef(root)), // edge info
+ FALSE, // topDown?
+ backArrows, // point back?
+ reNumber // renumber nodes
+ );
+ }
+ pn->write(md5stream, // stream
+ gt, // graph type
+ format, // output format
+ TRUE, // topDown?
+ FALSE, // toChildren?
+ backArrows, // backward pointing arrows?
+ reNumber // renumber nodes?
+ );
+ }
+ }
+ writeGraphFooter(md5stream);
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)buf.data(),buf.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ if (reNumber)
+ {
+ resetReNumbering();
+ }
+ graphStr=buf.data();
+ //printf("md5: %s | file: %s\n",sigStr,baseName.data());
+ return sigStr;
+}
+
+static bool updateDotGraph(DotNode *root,
+ DotNode::GraphType gt,
+ const QCString &baseName,
+ GraphOutputFormat format,
+ bool lrRank,
+ bool renderParents,
+ bool backArrows,
+ const QCString &title=QCString()
+ )
+{
+ QCString theGraph;
+ // TODO: write graph to theGraph, then compute md5 checksum
+ QCString md5 = computeMd5Signature(
+ root,gt,format,lrRank,renderParents,
+ backArrows,title,theGraph);
+ QFile f(baseName+".dot");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << theGraph;
+ }
+ return checkAndUpdateMd5Signature(baseName,md5); // graph needs to be regenerated
+}
+
+QCString DotClassGraph::diskName() const
+{
+ QCString result=m_diskName.copy();
+ switch (m_graphType)
+ {
+ case DotNode::Collaboration:
+ result+="_coll_graph";
+ break;
+ //case Interface:
+ // result+="_intf_graph";
+ // break;
+ case DotNode::Inheritance:
+ result+="_inherit_graph";
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return result;
+}
+
+QCString DotClassGraph::writeGraph(FTextStream &out,
+ GraphOutputFormat graphFormat,
+ EmbeddedOutputFormat textFormat,
+ const char *path,
+ const char *fileName,
+ const char *relPath,
+ bool /*isTBRank*/,
+ bool generateImageMap,
+ int graphId) const
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ QCString baseName;
+ QCString mapName;
+ switch (m_graphType)
+ {
+ case DotNode::Collaboration:
+ mapName="coll_map";
+ break;
+ //case Interface:
+ // mapName="intf_map";
+ // break;
+ case DotNode::Inheritance:
+ mapName="inherit_map";
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ baseName = convertNameToFile(diskName());
+
+ // derive target file names from baseName
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString absBaseName = d.absPath().utf8()+"/"+baseName;
+ QCString absDotName = absBaseName+".dot";
+ QCString absMapName = absBaseName+".map";
+ QCString absPdfName = absBaseName+".pdf";
+ QCString absEpsName = absBaseName+".eps";
+ QCString absImgName = absBaseName+"."+imgExt;
+
+ bool regenerate = FALSE;
+ if (updateDotGraph(m_startNode,
+ m_graphType,
+ absBaseName,
+ graphFormat,
+ m_lrRank,
+ m_graphType==DotNode::Inheritance,
+ TRUE,
+ m_startNode->label()
+ ) ||
+ !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName :
+ usePDFLatex ? absPdfName : absEpsName,
+ graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString())
+ )
+ {
+ regenerate=TRUE;
+ if (graphFormat==GOF_BITMAP) // run dot to create a bitmap image
+ {
+ QCString dotArgs(maxCmdLine);
+
+ DotRunner *dotRun = new DotRunner(absDotName,
+ d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+
+ }
+ else if (graphFormat==GOF_EPS) // run dot to create a .eps image
+ {
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ if (usePDFLatex)
+ {
+ dotRun->addJob("pdf",absPdfName);
+ }
+ else
+ {
+ dotRun->addJob("ps",absEpsName);
+ }
+ DotManager::instance()->addRun(dotRun);
+ }
+ }
+ Doxygen::indexList->addImageFile(baseName+"."+imgExt);
+
+ if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook)
+ {
+ out << "<para>" << endl;
+ out << " <figure>" << endl;
+ out << " <title>";
+ switch (m_graphType)
+ {
+ case DotNode::Collaboration:
+ out << "Collaboration graph";
+ break;
+ case DotNode::Inheritance:
+ out << "Inheritance graph";
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ out << "</title>" << endl;
+ out << " <mediaobject>" << endl;
+ out << " <imageobject>" << endl;
+ out << " <imagedata";
+ out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">";
+ out << "</imagedata>" << endl;
+ out << " </imageobject>" << endl;
+ out << " </mediaobject>" << endl;
+ out << " </figure>" << endl;
+ out << "</para>" << endl;
+ }
+ else if (graphFormat==GOF_BITMAP && generateImageMap) // produce HTML to include the image
+ {
+ QCString mapLabel = escapeCharsInString(m_startNode->m_label,FALSE)+"_"+
+ escapeCharsInString(mapName,FALSE);
+ if (imgExt=="svg") // add link to SVG file without map file
+ {
+ out << "<div class=\"center\">";
+ if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath);
+ out << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ out << "</div>" << endl;
+ }
+ else // add link to bitmap file with image map
+ {
+ out << "<div class=\"center\">";
+ out << "<img src=\"" << relPath << baseName << "."
+ << imgExt << "\" border=\"0\" usemap=\"#"
+ << mapLabel << "\" alt=\"";
+ switch (m_graphType)
+ {
+ case DotNode::Collaboration:
+ out << "Collaboration graph";
+ break;
+ case DotNode::Inheritance:
+ out << "Inheritance graph";
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ out << "\"/>";
+ out << "</div>" << endl;
+ if (regenerate || !insertMapFile(out,absMapName,relPath,mapLabel))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath,
+ FALSE,QCString(),mapLabel);
+ out << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+ }
+ else if (graphFormat==GOF_EPS) // produce tex to include the .eps image
+ {
+ if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName))
+ {
+ int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE /*TRUE*/);
+ out << endl << "% FIG " << figId << endl;
+ }
+ }
+ if (!regenerate) removeDotGraph(absDotName);
+
+ return baseName;
+}
+
+//--------------------------------------------------------------------
+
+void DotClassGraph::writeXML(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeXML(t,TRUE);
+ }
+}
+
+void DotClassGraph::writeDocbook(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeDocbook(t,TRUE);
+ }
+}
+
+void DotClassGraph::writeDEF(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeDEF(t);
+ }
+}
+
+//--------------------------------------------------------------------
+
+int DotInclDepGraph::m_curNodeNumber = 0;
+
+void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
+{
+ QList<IncludeInfo> *includeFiles =
+ m_inverse ? fd->includedByFileList() : fd->includeFileList();
+ if (includeFiles)
+ {
+ QListIterator<IncludeInfo> ili(*includeFiles);
+ IncludeInfo *ii;
+ for (;(ii=ili.current());++ili)
+ {
+ FileDef *bfd = ii->fileDef;
+ QCString in = ii->includeName;
+ //printf(">>>> in=`%s' bfd=%p\n",ii->includeName.data(),bfd);
+ bool doc=TRUE,src=FALSE;
+ if (bfd)
+ {
+ in = bfd->absFilePath();
+ doc = bfd->isLinkable() && !bfd->isHidden();
+ src = bfd->generateSourceFile();
+ }
+ if (doc || src || !Config_getBool("HIDE_UNDOC_RELATIONS"))
+ {
+ QCString url="";
+ if (bfd) url=bfd->getOutputFileBase().copy();
+ if (!doc && src)
+ {
+ url=bfd->getSourceFileBase();
+ }
+ DotNode *bn = m_usedNodes->find(in);
+ if (bn) // file is already a node in the graph
+ {
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ bn->setDistance(distance);
+ }
+ else
+ {
+ QCString tmp_url;
+ QCString tooltip;
+ if (bfd)
+ {
+ tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString();
+ tooltip = bfd->briefDescriptionAsTooltip();
+ }
+ bn = new DotNode(
+ m_curNodeNumber++, // n
+ ii->includeName, // label
+ tooltip, // tip
+ tmp_url, // url
+ FALSE, // rootNode
+ 0 // cd
+ );
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ m_usedNodes->insert(in,bn);
+ bn->setDistance(distance);
+
+ if (bfd) buildGraph(bn,bfd,distance+1);
+ }
+ }
+ }
+ }
+}
+
+void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes)
+{
+ while (queue.count()>0 && maxNodes>0)
+ {
+ static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH");
+ DotNode *n = queue.take(0);
+ if (!n->isVisible() && n->distance()<=maxDistance) // not yet processed
+ {
+ n->markAsVisible();
+ maxNodes--;
+ // add direct children
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ queue.append(dn);
+ }
+ }
+ }
+ }
+}
+
+void DotInclDepGraph::determineTruncatedNodes(QList<DotNode> &queue)
+{
+ while (queue.count()>0)
+ {
+ DotNode *n = queue.take(0);
+ if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+ {
+ bool truncated = FALSE;
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (!dn->isVisible())
+ truncated = TRUE;
+ else
+ queue.append(dn);
+ }
+ }
+ n->markAsTruncated(truncated);
+ }
+ }
+}
+
+
+DotInclDepGraph::DotInclDepGraph(FileDef *fd,bool inverse)
+{
+ m_inverse = inverse;
+ ASSERT(fd!=0);
+ m_diskName = fd->getFileBase().copy();
+ QCString tmp_url=fd->getReference()+"$"+fd->getFileBase();
+ m_startNode = new DotNode(m_curNodeNumber++,
+ fd->docName(),
+ "",
+ tmp_url.data(),
+ TRUE // root node
+ );
+ m_startNode->setDistance(0);
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes->insert(fd->absFilePath(),m_startNode);
+ buildGraph(m_startNode,fd,1);
+
+ static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int maxNodes = nodes;
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ QList<DotNode> openNodeQueue;
+ openNodeQueue.append(m_startNode);
+ determineVisibleNodes(openNodeQueue,maxNodes);
+ openNodeQueue.clear();
+ openNodeQueue.append(m_startNode);
+ determineTruncatedNodes(openNodeQueue);
+}
+
+DotInclDepGraph::~DotInclDepGraph()
+{
+ deleteNodes(m_startNode);
+ delete m_usedNodes;
+}
+
+QCString DotInclDepGraph::diskName() const
+{
+ QCString result=m_diskName.copy();
+ if (m_inverse) result+="_dep";
+ result+="_incl";
+ return convertNameToFile(result);
+}
+
+QCString DotInclDepGraph::writeGraph(FTextStream &out,
+ GraphOutputFormat graphFormat,
+ EmbeddedOutputFormat textFormat,
+ const char *path,
+ const char *fileName,
+ const char *relPath,
+ bool generateImageMap,
+ int graphId
+ ) const
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ QCString baseName=m_diskName;
+ if (m_inverse) baseName+="_dep";
+ baseName+="_incl";
+ baseName=convertNameToFile(baseName);
+ QCString mapName=escapeCharsInString(m_startNode->m_label,FALSE);
+ if (m_inverse) mapName+="dep";
+
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString absBaseName = d.absPath().utf8()+"/"+baseName;
+ QCString absDotName = absBaseName+".dot";
+ QCString absMapName = absBaseName+".map";
+ QCString absPdfName = absBaseName+".pdf";
+ QCString absEpsName = absBaseName+".eps";
+ QCString absImgName = absBaseName+"."+imgExt;
+
+ bool regenerate = FALSE;
+ if (updateDotGraph(m_startNode,
+ DotNode::Dependency,
+ absBaseName,
+ graphFormat,
+ FALSE, // lrRank
+ FALSE, // renderParents
+ m_inverse, // backArrows
+ m_startNode->label()
+ ) ||
+ !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName :
+ usePDFLatex ? absPdfName : absEpsName,
+ graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString())
+ )
+ {
+ regenerate=TRUE;
+ if (graphFormat==GOF_BITMAP)
+ {
+ // run dot to create a bitmap image
+ QCString dotArgs(maxCmdLine);
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ if (usePDFLatex)
+ {
+ dotRun->addJob("pdf",absPdfName);
+ }
+ else
+ {
+ dotRun->addJob("ps",absEpsName);
+ }
+ DotManager::instance()->addRun(dotRun);
+ }
+ }
+ Doxygen::indexList->addImageFile(baseName+"."+imgExt);
+
+ if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook)
+ {
+ out << "<para>" << endl;
+ out << " <figure>" << endl;
+ out << " <title>Dependency diagram";
+ out << "</title>" << endl;
+ out << " <mediaobject>" << endl;
+ out << " <imageobject>" << endl;
+ out << " <imagedata";
+ out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">";
+ out << "</imagedata>" << endl;
+ out << " </imageobject>" << endl;
+ out << " </mediaobject>" << endl;
+ out << " </figure>" << endl;
+ out << "</para>" << endl;
+ }
+ else if (graphFormat==GOF_BITMAP && generateImageMap)
+ {
+ if (imgExt=="svg") // Scalable vector graphics
+ {
+ out << "<div class=\"center\">";
+ if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath);
+ out << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ out << "</div>" << endl;
+ }
+ else // bitmap graphics
+ {
+ out << "<div class=\"center\"><img src=\"" << relPath << baseName << "." << imgExt << "\" border=\"0\" usemap=\"#" << mapName << "\" alt=\"\"/>";
+ out << "</div>" << endl;
+
+ QCString absMapName = absBaseName+".map";
+ if (regenerate || !insertMapFile(out,absMapName,relPath,mapName))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath,
+ FALSE,QCString(),mapName);
+ out << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+ }
+ else if (graphFormat==GOF_EPS) // encapsulated postscript
+ {
+ if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName))
+ {
+ int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE);
+ out << endl << "% FIG " << figId << endl;
+ }
+ }
+ if (!regenerate) removeDotGraph(absDotName);
+
+ return baseName;
+}
+
+bool DotInclDepGraph::isTrivial() const
+{
+ return m_startNode->m_children==0;
+}
+
+bool DotInclDepGraph::isTooBig() const
+{
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ return numNodes>=maxNodes;
+}
+
+void DotInclDepGraph::writeXML(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeXML(t,FALSE);
+ }
+}
+
+void DotInclDepGraph::writeDocbook(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeDocbook(t,FALSE);
+ }
+}
+
+//-------------------------------------------------------------
+
+int DotCallGraph::m_curNodeNumber = 0;
+
+void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance)
+{
+ MemberSDict *refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers();
+ if (refs)
+ {
+ MemberSDict::Iterator mri(*refs);
+ MemberDef *rmd;
+ for (;(rmd=mri.current());++mri)
+ {
+ if (rmd->showInCallGraph())
+ {
+ QCString uniqueId;
+ uniqueId=rmd->getReference()+"$"+
+ rmd->getOutputFileBase()+"#"+rmd->anchor();
+ DotNode *bn = m_usedNodes->find(uniqueId);
+ if (bn) // file is already a node in the graph
+ {
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ bn->setDistance(distance);
+ }
+ else
+ {
+ QCString name;
+ if (Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ name = rmd->getOuterScope()==m_scope ?
+ rmd->name() : rmd->qualifiedName();
+ }
+ else
+ {
+ name = rmd->qualifiedName();
+ }
+ QCString tooltip = rmd->briefDescriptionAsTooltip();
+ bn = new DotNode(
+ m_curNodeNumber++,
+ linkToText(rmd->getLanguage(),name,FALSE),
+ tooltip,
+ uniqueId,
+ 0 //distance
+ );
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ bn->setDistance(distance);
+ m_usedNodes->insert(uniqueId,bn);
+
+ buildGraph(bn,rmd,distance+1);
+ }
+ }
+ }
+ }
+}
+
+void DotCallGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes)
+{
+ while (queue.count()>0 && maxNodes>0)
+ {
+ static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH");
+ DotNode *n = queue.take(0);
+ if (!n->isVisible() && n->distance()<=maxDistance) // not yet processed
+ {
+ n->markAsVisible();
+ maxNodes--;
+ // add direct children
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ queue.append(dn);
+ }
+ }
+ }
+ }
+}
+
+void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue)
+{
+ while (queue.count()>0)
+ {
+ DotNode *n = queue.take(0);
+ if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+ {
+ bool truncated = FALSE;
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (!dn->isVisible())
+ truncated = TRUE;
+ else
+ queue.append(dn);
+ }
+ }
+ n->markAsTruncated(truncated);
+ }
+ }
+}
+
+
+
+DotCallGraph::DotCallGraph(MemberDef *md,bool inverse)
+{
+ m_inverse = inverse;
+ m_diskName = md->getOutputFileBase()+"_"+md->anchor();
+ m_scope = md->getOuterScope();
+ QCString uniqueId;
+ uniqueId = md->getReference()+"$"+
+ md->getOutputFileBase()+"#"+md->anchor();
+ QCString name;
+ if (Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ name = md->name();
+ }
+ else
+ {
+ name = md->qualifiedName();
+ }
+ m_startNode = new DotNode(m_curNodeNumber++,
+ linkToText(md->getLanguage(),name,FALSE),
+ "",
+ uniqueId.data(),
+ TRUE // root node
+ );
+ m_startNode->setDistance(0);
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes->insert(uniqueId,m_startNode);
+ buildGraph(m_startNode,md,1);
+
+ static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int maxNodes = nodes;
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ QList<DotNode> openNodeQueue;
+ openNodeQueue.append(m_startNode);
+ determineVisibleNodes(openNodeQueue,maxNodes);
+ openNodeQueue.clear();
+ openNodeQueue.append(m_startNode);
+ determineTruncatedNodes(openNodeQueue);
+}
+
+DotCallGraph::~DotCallGraph()
+{
+ deleteNodes(m_startNode);
+ delete m_usedNodes;
+}
+
+QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphFormat,
+ EmbeddedOutputFormat textFormat,
+ const char *path,const char *fileName,
+ const char *relPath,bool generateImageMap,int
+ graphId) const
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ QCString baseName = m_diskName + (m_inverse ? "_icgraph" : "_cgraph");
+ QCString mapName = baseName;
+
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString absBaseName = d.absPath().utf8()+"/"+baseName;
+ QCString absDotName = absBaseName+".dot";
+ QCString absMapName = absBaseName+".map";
+ QCString absPdfName = absBaseName+".pdf";
+ QCString absEpsName = absBaseName+".eps";
+ QCString absImgName = absBaseName+"."+imgExt;
+
+ bool regenerate = FALSE;
+ if (updateDotGraph(m_startNode,
+ DotNode::CallGraph,
+ absBaseName,
+ graphFormat,
+ TRUE, // lrRank
+ FALSE, // renderParents
+ m_inverse, // backArrows
+ m_startNode->label()
+ ) ||
+ !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName :
+ usePDFLatex ? absPdfName : absEpsName,
+ graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString())
+ )
+ {
+ regenerate=TRUE;
+ if (graphFormat==GOF_BITMAP)
+ {
+ // run dot to create a bitmap image
+ QCString dotArgs(maxCmdLine);
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ // run dot to create a .eps image
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ if (usePDFLatex)
+ {
+ dotRun->addJob("pdf",absPdfName);
+ }
+ else
+ {
+ dotRun->addJob("ps",absEpsName);
+ }
+ DotManager::instance()->addRun(dotRun);
+
+ }
+ }
+ Doxygen::indexList->addImageFile(baseName+"."+imgExt);
+
+ if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook)
+ {
+ out << "<para>" << endl;
+ out << " <figure>" << endl;
+ out << " <title>Call diagram";
+ out << "</title>" << endl;
+ out << " <mediaobject>" << endl;
+ out << " <imageobject>" << endl;
+ out << " <imagedata";
+ out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">";
+ out << "</imagedata>" << endl;
+ out << " </imageobject>" << endl;
+ out << " </mediaobject>" << endl;
+ out << " </figure>" << endl;
+ out << "</para>" << endl;
+ }
+ else if (graphFormat==GOF_BITMAP && generateImageMap)
+ {
+ if (imgExt=="svg") // Scalable vector graphics
+ {
+ out << "<div class=\"center\">";
+ if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath);
+ out << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ out << "</div>" << endl;
+ }
+ else // bitmap graphics
+ {
+ out << "<div class=\"center\"><img src=\"" << relPath << baseName << "."
+ << imgExt << "\" border=\"0\" usemap=\"#"
+ << mapName << "\" alt=\"";
+ out << "\"/>";
+ out << "</div>" << endl;
+
+ if (regenerate || !insertMapFile(out,absMapName,relPath,mapName))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath,
+ FALSE,QCString(),mapName);
+ out << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+ }
+ else if (graphFormat==GOF_EPS) // encapsulated postscript
+ {
+ if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName))
+ {
+ int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE);
+ out << endl << "% FIG " << figId << endl;
+ }
+ }
+ if (!regenerate) removeDotGraph(absDotName);
+
+ return baseName;
+}
+
+bool DotCallGraph::isTrivial() const
+{
+ return m_startNode->m_children==0;
+}
+
+bool DotCallGraph::isTooBig() const
+{
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ return numNodes>=maxNodes;
+}
+
+//-------------------------------------------------------------
+
+DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir)
+{
+}
+
+DotDirDeps::~DotDirDeps()
+{
+}
+
+QCString DotDirDeps::writeGraph(FTextStream &out,
+ GraphOutputFormat graphFormat,
+ EmbeddedOutputFormat textFormat,
+ const char *path,
+ const char *fileName,
+ const char *relPath,
+ bool generateImageMap,
+ int graphId) const
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ QCString baseName=m_dir->getOutputFileBase()+"_dep";
+ QCString mapName=escapeCharsInString(baseName,FALSE);
+
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString absBaseName = d.absPath().utf8()+"/"+baseName;
+ QCString absDotName = absBaseName+".dot";
+ QCString absMapName = absBaseName+".map";
+ QCString absPdfName = absBaseName+".pdf";
+ QCString absEpsName = absBaseName+".eps";
+ QCString absImgName = absBaseName+"."+imgExt;
+
+ // compute md5 checksum of the graph were are about to generate
+ QGString theGraph;
+ FTextStream md5stream(&theGraph);
+ m_dir->writeDepGraph(md5stream);
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ bool regenerate=FALSE;
+ if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
+ !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName :
+ usePDFLatex ? absPdfName : absEpsName,
+ graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString())
+ )
+ {
+ regenerate=TRUE;
+
+ QFile f(absDotName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot create file %s.dot for writing!\n",baseName.data());
+ }
+ FTextStream t(&f);
+ t << theGraph.data();
+ f.close();
+
+ if (graphFormat==GOF_BITMAP)
+ {
+ // run dot to create a bitmap image
+ QCString dotArgs(maxCmdLine);
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ if (usePDFLatex)
+ {
+ dotRun->addJob("pdf",absPdfName);
+ }
+ else
+ {
+ dotRun->addJob("ps",absEpsName);
+ }
+ DotManager::instance()->addRun(dotRun);
+ }
+ }
+ Doxygen::indexList->addImageFile(baseName+"."+imgExt);
+
+ if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook)
+ {
+ out << "<para>" << endl;
+ out << " <figure>" << endl;
+ out << " <title>Directory Dependency diagram";
+ out << "</title>" << endl;
+ out << " <mediaobject>" << endl;
+ out << " <imageobject>" << endl;
+ out << " <imagedata";
+ out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">";
+ out << "</imagedata>" << endl;
+ out << " </imageobject>" << endl;
+ out << " </mediaobject>" << endl;
+ out << " </figure>" << endl;
+ out << "</para>" << endl;
+ }
+ else if (graphFormat==GOF_BITMAP && generateImageMap)
+ {
+ if (imgExt=="svg") // Scalable vector graphics
+ {
+ out << "<div class=\"center\">";
+ if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath);
+ out << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ out << "</div>" << endl;
+ }
+ else // bitmap graphics
+ {
+ out << "<div class=\"center\"><img src=\"" << relPath << baseName << "."
+ << imgExt << "\" border=\"0\" usemap=\"#"
+ << mapName << "\" alt=\"";
+ out << convertToXML(m_dir->displayName());
+ out << "\"/>";
+ out << "</div>" << endl;
+
+ if (regenerate || !insertMapFile(out,absMapName,relPath,mapName))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath,
+ TRUE,QCString(),mapName);
+ out << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName))
+ {
+ int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE);
+ out << endl << "% FIG " << figId << endl;
+ }
+ }
+ if (!regenerate) removeDotGraph(absDotName);
+
+ return baseName;
+}
+
+bool DotDirDeps::isTrivial() const
+{
+ return m_dir->depGraphIsTrivial();
+}
+
+//-------------------------------------------------------------
+
+void generateGraphLegend(const char *path)
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+
+ QGString theGraph;
+ FTextStream md5stream(&theGraph);
+ writeGraphHeader(md5stream,theTranslator->trLegendTitle());
+ md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n";
+ md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPublicBase" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"grey75\"];\n";
+ md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
+ md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << FONTNAME << "\"];\n";
+ md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension << "\"];\n";
+ writeGraphFooter(md5stream);
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ QCString absBaseName = (QCString)path+"/graph_legend";
+ QCString absDotName = absBaseName+".dot";
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString imgName = "graph_legend."+imgExt;
+ QCString absImgName = absBaseName+"."+imgExt;
+ if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
+ !checkDeliverables(absImgName))
+ {
+ QFile dotFile(absDotName);
+ if (!dotFile.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",dotFile.name().data());
+ return;
+ }
+
+ FTextStream dotText(&dotFile);
+ dotText << theGraph;
+ dotFile.close();
+
+ // run dot to generate the a bitmap image from the graph
+
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName);
+ dotRun->addJob(imgExt,absImgName);
+ DotManager::instance()->addRun(dotRun);
+ }
+ else
+ {
+ removeDotGraph(absDotName);
+ }
+ Doxygen::indexList->addImageFile(imgName);
+
+ if (imgExt=="svg")
+ {
+ DotManager::instance()->addSVGObject(
+ absBaseName+Config_getString("HTML_FILE_EXTENSION"),
+ "graph_legend",
+ absImgName,QCString());
+ }
+
+}
+
+void writeDotGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,GraphOutputFormat format)
+{
+ QDir d(outDir);
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",outDir); exit(1);
+ }
+
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString imgName = (QCString)outFile+"."+imgExt;
+ QCString absImgName = d.absPath().utf8()+"/"+imgName;
+ QCString absOutFile = d.absPath().utf8()+"/"+outFile;
+
+ DotRunner dotRun(inFile,d.absPath().data(),FALSE,absImgName);
+ if (format==GOF_BITMAP)
+ dotRun.addJob(imgExt,absImgName);
+ else // format==GOF_EPS
+ {
+ if (Config_getBool("USE_PDFLATEX"))
+ {
+ dotRun.addJob("pdf",absOutFile+".pdf");
+ }
+ else
+ {
+ dotRun.addJob("ps",absOutFile+".eps");
+ }
+ }
+
+ dotRun.preventCleanUp();
+ if (!dotRun.run())
+ {
+ return;
+ }
+
+ if (format==GOF_BITMAP) checkDotResult(absImgName);
+
+ Doxygen::indexList->addImageFile(imgName);
+
+}
+
+
+/*! Writes user defined image map to the output.
+ * \param t text stream to write to
+ * \param inFile just the basename part of the filename
+ * \param outDir output directory
+ * \param relPath relative path the to root of the output dir
+ * \param baseName the base name of the output files
+ * \param context the scope in which this graph is found (for resolving links)
+ * \param graphId a unique id for this graph, use for dynamic sections
+ */
+void writeDotImageMapFromFile(FTextStream &t,
+ const QCString &inFile, const QCString &outDir,
+ const QCString &relPath, const QCString &baseName,
+ const QCString &context,int graphId)
+{
+
+ QDir d(outDir);
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",outDir.data()); exit(1);
+ }
+
+ QCString mapName = baseName+".map";
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString imgName = baseName+"."+imgExt;
+ QCString absOutFile = d.absPath().utf8()+"/"+mapName;
+
+ DotRunner dotRun(inFile,d.absPath().data(),FALSE);
+ dotRun.addJob(MAP_CMD,absOutFile);
+ dotRun.preventCleanUp();
+ if (!dotRun.run())
+ {
+ return;
+ }
+
+ if (imgExt=="svg") // vector graphics
+ {
+ //writeSVGFigureLink(t,relPath,inFile,inFile+".svg");
+ //DotFilePatcher patcher(inFile+".svg");
+ QCString svgName=outDir+"/"+baseName+".svg";
+ writeSVGFigureLink(t,relPath,baseName,svgName);
+ DotFilePatcher patcher(svgName);
+ patcher.addSVGConversion(relPath,TRUE,context,TRUE,graphId);
+ patcher.run();
+ }
+ else // bitmap graphics
+ {
+ t << "<img src=\"" << relPath << imgName << "\" alt=\""
+ << imgName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl
+ << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">";
+
+ convertMapFile(t, absOutFile, relPath ,TRUE, context);
+
+ t << "</map>" << endl;
+ }
+ d.remove(absOutFile);
+}
+
+//-------------------------------------------------------------
+
+DotGroupCollaboration::DotGroupCollaboration(GroupDef* gd)
+{
+ m_curNodeId = 0;
+ QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase();
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_rootNode = new DotNode(m_curNodeId++, gd->groupTitle(), "", tmp_url, TRUE );
+ m_rootNode->markAsVisible();
+ m_usedNodes->insert(gd->name(), m_rootNode );
+ m_edges.setAutoDelete(TRUE);
+
+ m_diskName = gd->getOutputFileBase();
+
+ buildGraph( gd );
+}
+
+DotGroupCollaboration::~DotGroupCollaboration()
+{
+ delete m_usedNodes;
+}
+
+void DotGroupCollaboration::buildGraph(GroupDef* gd)
+{
+ QCString tmp_url;
+ //===========================
+ // hierarchy.
+
+ // Write parents
+ GroupList *groups = gd->partOfGroups();
+ if ( groups )
+ {
+ GroupListIterator gli(*groups);
+ GroupDef *d;
+ for (gli.toFirst();(d=gli.current());++gli)
+ {
+ DotNode* nnode = m_usedNodes->find(d->name());
+ if ( !nnode )
+ { // add node
+ tmp_url = d->getReference()+"$"+d->getOutputFileBase();
+ QCString tooltip = d->briefDescriptionAsTooltip();
+ nnode = new DotNode(m_curNodeId++, d->groupTitle(), tooltip, tmp_url );
+ nnode->markAsVisible();
+ m_usedNodes->insert(d->name(), nnode );
+ }
+ tmp_url = "";
+ addEdge( nnode, m_rootNode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
+ }
+ }
+
+ // Add subgroups
+ if ( gd->getSubGroups() && gd->getSubGroups()->count() )
+ {
+ QListIterator<GroupDef> defli(*gd->getSubGroups());
+ GroupDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ DotNode* nnode = m_usedNodes->find(def->name());
+ if ( !nnode )
+ { // add node
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase();
+ QCString tooltip = def->briefDescriptionAsTooltip();
+ nnode = new DotNode(m_curNodeId++, def->groupTitle(), tooltip, tmp_url );
+ nnode->markAsVisible();
+ m_usedNodes->insert(def->name(), nnode );
+ }
+ tmp_url = "";
+ addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
+ }
+ }
+
+ //=======================
+ // Write collaboration
+
+ // Add members
+ addMemberList( gd->getMemberList(MemberListType_allMembersList) );
+
+ // Add classes
+ if ( gd->getClasses() && gd->getClasses()->count() )
+ {
+ ClassSDict::Iterator defli(*gd->getClasses());
+ ClassDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+ if (!def->anchor().isEmpty())
+ {
+ tmp_url+="#"+def->anchor();
+ }
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tclass );
+ }
+ }
+
+ // Add namespaces
+ if ( gd->getNamespaces() && gd->getNamespaces()->count() )
+ {
+ NamespaceSDict::Iterator defli(*gd->getNamespaces());
+ NamespaceDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tnamespace );
+ }
+ }
+
+ // Add files
+ if ( gd->getFiles() && gd->getFiles()->count() )
+ {
+ QListIterator<FileDef> defli(*gd->getFiles());
+ FileDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tfile );
+ }
+ }
+
+ // Add pages
+ if ( gd->getPages() && gd->getPages()->count() )
+ {
+ PageSDict::Iterator defli(*gd->getPages());
+ PageDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tpages );
+ }
+ }
+
+ // Add directories
+ if ( gd->getDirs() && gd->getDirs()->count() )
+ {
+ QListIterator<DirDef> defli(*gd->getDirs());
+ DirDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tdir );
+ }
+ }
+}
+
+void DotGroupCollaboration::addMemberList( MemberList* ml )
+{
+ if ( !( ml && ml->count()) ) return;
+ MemberListIterator defli(*ml);
+ MemberDef *def;
+ for (;(def=defli.current());++defli)
+ {
+ QCString tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension
+ +"#"+def->anchor();
+ addCollaborationMember( def, tmp_url, DotGroupCollaboration::tmember );
+ }
+}
+
+DotGroupCollaboration::Edge* DotGroupCollaboration::addEdge(
+ DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType,
+ const QCString& _label, const QCString& _url )
+{
+ // search a existing link.
+ QListIterator<Edge> lli(m_edges);
+ Edge* newEdge = 0;
+ for ( lli.toFirst(); (newEdge=lli.current()); ++lli)
+ {
+ if ( newEdge->pNStart==_pNStart &&
+ newEdge->pNEnd==_pNEnd &&
+ newEdge->eType==_eType
+ )
+ { // edge already found
+ break;
+ }
+ }
+ if ( newEdge==0 ) // new link
+ {
+ newEdge = new Edge(_pNStart,_pNEnd,_eType);
+ m_edges.append( newEdge );
+ }
+
+ if (!_label.isEmpty())
+ {
+ newEdge->links.append(new Link(_label,_url));
+ }
+
+ return newEdge;
+}
+
+void DotGroupCollaboration::addCollaborationMember(
+ Definition* def, QCString& url, EdgeType eType )
+{
+ // Create group nodes
+ if ( !def->partOfGroups() )
+ return;
+ GroupListIterator gli(*def->partOfGroups());
+ GroupDef *d;
+ QCString tmp_str;
+ for (;(d=gli.current());++gli)
+ {
+ DotNode* nnode = m_usedNodes->find(d->name());
+ if ( nnode != m_rootNode )
+ {
+ if ( nnode==0 )
+ { // add node
+ tmp_str = d->getReference()+"$"+d->getOutputFileBase();
+ QCString tooltip = d->briefDescriptionAsTooltip();
+ nnode = new DotNode(m_curNodeId++, d->groupTitle(), tooltip, tmp_str );
+ nnode->markAsVisible();
+ m_usedNodes->insert(d->name(), nnode );
+ }
+ tmp_str = def->qualifiedName();
+ addEdge( m_rootNode, nnode, eType, tmp_str, url );
+ }
+ }
+}
+
+
+QCString DotGroupCollaboration::writeGraph( FTextStream &t,
+ GraphOutputFormat graphFormat, EmbeddedOutputFormat textFormat,
+ const char *path, const char *fileName, const char *relPath,
+ bool writeImageMap,int graphId) const
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path); exit(1);
+ }
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ QGString theGraph;
+ FTextStream md5stream(&theGraph);
+ writeGraphHeader(md5stream,m_rootNode->label());
+
+ // clean write flags
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *pn;
+ for (dni.toFirst();(pn=dni.current());++dni)
+ {
+ pn->clearWriteFlag();
+ }
+
+ // write other nodes.
+ for (dni.toFirst();(pn=dni.current());++dni)
+ {
+ pn->write(md5stream,DotNode::Inheritance,graphFormat,TRUE,FALSE,FALSE,FALSE);
+ }
+
+ // write edges
+ QListIterator<Edge> eli(m_edges);
+ Edge* edge;
+ for (eli.toFirst();(edge=eli.current());++eli)
+ {
+ edge->write( md5stream );
+ }
+
+ writeGraphFooter(md5stream);
+ resetReNumbering();
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ QCString baseName = m_diskName;
+ QCString imgName = baseName+"."+imgExt;
+ QCString mapName = baseName+".map";
+ QCString absPath = d.absPath().data();
+ QCString absBaseName = absPath+"/"+baseName;
+ QCString absDotName = absBaseName+".dot";
+ QCString absImgName = absBaseName+"."+imgExt;
+ QCString absMapName = absBaseName+".map";
+ QCString absPdfName = absBaseName+".pdf";
+ QCString absEpsName = absBaseName+".eps";
+ bool regenerate=FALSE;
+ if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
+ !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName :
+ usePDFLatex ? absPdfName : absEpsName,
+ graphFormat==GOF_BITMAP /*&& generateImageMap*/ ? absMapName : QCString())
+ )
+ {
+ regenerate=TRUE;
+
+ QFile dotfile(absDotName);
+ if (dotfile.open(IO_WriteOnly))
+ {
+ FTextStream tdot(&dotfile);
+ tdot << theGraph;
+ dotfile.close();
+ }
+
+ if (graphFormat==GOF_BITMAP) // run dot to create a bitmap image
+ {
+ QCString dotArgs(maxCmdLine);
+
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ dotRun->addJob(imgExt,absImgName);
+ if (writeImageMap) dotRun->addJob(MAP_CMD,absMapName);
+ DotManager::instance()->addRun(dotRun);
+
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE);
+ if (usePDFLatex)
+ {
+ dotRun->addJob("pdf",absPdfName);
+ }
+ else
+ {
+ dotRun->addJob("ps",absEpsName);
+ }
+ DotManager::instance()->addRun(dotRun);
+ }
+
+ }
+ if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook)
+ {
+ t << "<para>" << endl;
+ t << " <figure>" << endl;
+ t << " <title>Group Collaboration diagram";
+ t << "</title>" << endl;
+ t << " <mediaobject>" << endl;
+ t << " <imageobject>" << endl;
+ t << " <imagedata";
+ t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName << "." << imgExt << "\">";
+ t << "</imagedata>" << endl;
+ t << " </imageobject>" << endl;
+ t << " </mediaobject>" << endl;
+ t << " </figure>" << endl;
+ t << "</para>" << endl;
+ }
+ else if (graphFormat==GOF_BITMAP && writeImageMap)
+ {
+ QCString mapLabel = escapeCharsInString(baseName,FALSE);
+ t << "<center><table><tr><td>";
+
+ if (imgExt=="svg")
+ {
+ t << "<div class=\"center\">";
+ if (regenerate || !writeSVGFigureLink(t,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file
+ {
+ if (regenerate)
+ {
+ DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId);
+ }
+ int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath);
+ t << "<!-- SVG " << mapId << " -->" << endl;
+ }
+ t << "</div>" << endl;
+ }
+ else
+ {
+ t << "<img src=\"" << relPath << imgName
+ << "\" border=\"0\" alt=\"\" usemap=\"#"
+ << mapLabel << "\"/>" << endl;
+ if (regenerate || !insertMapFile(t,absMapName,relPath,mapLabel))
+ {
+ int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath,
+ FALSE,QCString(),mapLabel);
+ t << "<!-- MAP " << mapId << " -->" << endl;
+ }
+ }
+ t << "</td></tr></table></center>" << endl;
+ }
+ else if (graphFormat==GOF_EPS)
+ {
+ if (regenerate || !writeVecGfxFigure(t,baseName,absBaseName))
+ {
+ int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE);
+ t << endl << "% FIG " << figId << endl;
+ }
+ }
+ if (!regenerate) removeDotGraph(absDotName);
+
+ return baseName;
+}
+
+void DotGroupCollaboration::Edge::write( FTextStream &t ) const
+{
+ const char* linkTypeColor[] = {
+ "darkorchid3"
+ ,"orange"
+ ,"blueviolet"
+ ,"darkgreen"
+ ,"firebrick4"
+ ,"grey75"
+ ,"midnightblue"
+ };
+ QCString arrowStyle = "dir=\"none\", style=\"dashed\"";
+ t << " Node" << pNStart->number();
+ t << "->";
+ t << "Node" << pNEnd->number();
+
+ t << " [shape=plaintext";
+ if (links.count()>0) // there are links
+ {
+ t << ", ";
+ // HTML-like edge labels crash on my Mac with Graphviz 2.0! and
+ // are not supported by older version of dot.
+ //
+ //t << label=<<TABLE BORDER=\"0\" CELLBORDER=\"0\">";
+ //QListIterator<Link> lli(links);
+ //Link *link;
+ //for( lli.toFirst(); (link=lli.current()); ++lli)
+ //{
+ // t << "<TR><TD";
+ // if ( !link->url.isEmpty() )
+ // t << " HREF=\"" << link->url << "\"";
+ // t << ">" << link->label << "</TD></TR>";
+ //}
+ //t << "</TABLE>>";
+
+ t << "label=\"";
+ QListIterator<Link> lli(links);
+ Link *link;
+ bool first=TRUE;
+ int count=0;
+ const int maxLabels = 10;
+ for( lli.toFirst(); (link=lli.current()) && count<maxLabels; ++lli,++count)
+ {
+ if (first) first=FALSE; else t << "\\n";
+ t << convertLabel(link->label);
+ }
+ if (count==maxLabels) t << "\\n...";
+ t << "\"";
+
+ }
+ switch( eType )
+ {
+ case thierarchy :
+ arrowStyle = "dir=\"back\", style=\"solid\"";
+ default :
+ t << ", color=\"" << linkTypeColor[(int)eType] << "\"";
+ break;
+ }
+ t << ", " << arrowStyle;
+ t << "];" << endl;
+}
+
+bool DotGroupCollaboration::isTrivial() const
+{
+ return m_usedNodes->count() <= 1;
+}
+
+void DotGroupCollaboration::writeGraphHeader(FTextStream &t,
+ const QCString &title) const
+{
+ t << "digraph ";
+ if (title.isEmpty())
+ {
+ t << "\"Dot Graph\"";
+ }
+ else
+ {
+ t << "\"" << convertToXML(title) << "\"";
+ }
+ t << endl;
+ t << "{" << endl;
+ if (Config_getBool("DOT_TRANSPARENT"))
+ {
+ t << " bgcolor=\"transparent\";" << endl;
+ }
+ t << " edge [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\","
+ "labelfontname=\"" << FONTNAME << "\",labelfontsize=\"" << FONTSIZE << "\"];\n";
+ t << " node [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\",shape=record];\n";
+ t << " rankdir=LR;\n";
+}
+
+void writeDotDirDepGraph(FTextStream &t,DirDef *dd)
+{
+ t << "digraph \"" << dd->displayName() << "\" {\n";
+ if (Config_getBool("DOT_TRANSPARENT"))
+ {
+ t << " bgcolor=transparent;\n";
+ }
+ t << " compound=true\n";
+ t << " node [ fontsize=\"" << FONTSIZE << "\", fontname=\"" << FONTNAME << "\"];\n";
+ t << " edge [ labelfontsize=\"" << FONTSIZE << "\", labelfontname=\"" << FONTNAME << "\"];\n";
+
+ QDict<DirDef> dirsInGraph(257);
+
+ dirsInGraph.insert(dd->getOutputFileBase(),dd);
+ if (dd->parent())
+ {
+ t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n";
+ t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\""
+ << dd->parent()->shortName()
+ << "\" fontname=\"" << FONTNAME << "\", fontsize=\"" << FONTSIZE << "\", URL=\"";
+ t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension;
+ t << "\"]\n";
+ }
+ if (dd->isCluster())
+ {
+ t << " subgraph cluster" << dd->getOutputFileBase() << " {\n";
+ t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\""
+ << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension
+ << "\"];\n";
+ t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\""
+ << dd->shortName() << "\"];\n";
+
+ // add nodes for sub directories
+ QListIterator<DirDef> sdi(dd->subDirs());
+ DirDef *sdir;
+ for (sdi.toFirst();(sdir=sdi.current());++sdi)
+ {
+ t << " " << sdir->getOutputFileBase() << " [shape=box label=\""
+ << sdir->shortName() << "\"";
+ if (sdir->isCluster())
+ {
+ t << " color=\"red\"";
+ }
+ else
+ {
+ t << " color=\"black\"";
+ }
+ t << " fillcolor=\"white\" style=\"filled\"";
+ t << " URL=\"" << sdir->getOutputFileBase()
+ << Doxygen::htmlFileExtension << "\"";
+ t << "];\n";
+ dirsInGraph.insert(sdir->getOutputFileBase(),sdir);
+ }
+ t << " }\n";
+ }
+ else
+ {
+ t << " " << dd->getOutputFileBase() << " [shape=box, label=\""
+ << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\","
+ << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase()
+ << Doxygen::htmlFileExtension << "\"];\n";
+ }
+ if (dd->parent())
+ {
+ t << " }\n";
+ }
+
+ // add nodes for other used directories
+ QDictIterator<UsedDir> udi(*dd->usedDirs());
+ UsedDir *udir;
+ //printf("*** For dir %s\n",shortName().data());
+ for (udi.toFirst();(udir=udi.current());++udi)
+ // for each used dir (=directly used or a parent of a directly used dir)
+ {
+ const DirDef *usedDir=udir->dir();
+ DirDef *dir=dd;
+ while (dir)
+ {
+ //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n",
+ // dir->shortName().data(),usedDir->shortName().data(),
+ // dir->parent()==usedDir->parent(),
+ // usedDir->shortName().data(),
+ // shortName().data(),
+ // !usedDir->isParentOf(this)
+ // );
+ if (dir!=usedDir && dir->parent()==usedDir->parent() &&
+ !usedDir->isParentOf(dd))
+ // include if both have the same parent (or no parent)
+ {
+ t << " " << usedDir->getOutputFileBase() << " [shape=box label=\""
+ << usedDir->shortName() << "\"";
+ if (usedDir->isCluster())
+ {
+ if (!Config_getBool("DOT_TRANSPARENT"))
+ {
+ t << " fillcolor=\"white\" style=\"filled\"";
+ }
+ t << " color=\"red\"";
+ }
+ t << " URL=\"" << usedDir->getOutputFileBase()
+ << Doxygen::htmlFileExtension << "\"];\n";
+ dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir);
+ break;
+ }
+ dir=dir->parent();
+ }
+ }
+
+ // add relations between all selected directories
+ DirDef *dir;
+ QDictIterator<DirDef> di(dirsInGraph);
+ for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph
+ {
+ QDictIterator<UsedDir> udi(*dir->usedDirs());
+ UsedDir *udir;
+ for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir
+ {
+ const DirDef *usedDir=udir->dir();
+ if ((dir!=dd || !udir->inherited()) && // only show direct dependendies for this dir
+ (usedDir!=dd || !udir->inherited()) && // only show direct dependendies for this dir
+ !usedDir->isParentOf(dir) && // don't point to own parent
+ dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph
+ {
+ QCString relationName;
+ relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount());
+ if (Doxygen::dirRelations.find(relationName)==0)
+ {
+ // new relation
+ Doxygen::dirRelations.append(relationName,
+ new DirRelation(relationName,dir,udir));
+ }
+ int nrefs = udir->filePairs().count();
+ t << " " << dir->getOutputFileBase() << "->"
+ << usedDir->getOutputFileBase();
+ t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5";
+ t << " headhref=\"" << relationName << Doxygen::htmlFileExtension
+ << "\"];\n";
+ }
+ }
+ }
+
+ t << "}\n";
+}
diff --git a/src/dot.h b/src/dot.h
new file mode 100644
index 0000000..8906199
--- /dev/null
+++ b/src/dot.h
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _DOT_H
+#define _DOT_H
+
+#include <qlist.h>
+#include <qdict.h>
+#include <qwaitcondition.h>
+#include <qmutex.h>
+#include <qqueue.h>
+#include <qthread.h>
+#include "sortdict.h"
+
+class ClassDef;
+class FileDef;
+class FTextStream;
+class DotNodeList;
+class ClassSDict;
+class MemberDef;
+class Definition;
+class DirDef;
+class GroupDef;
+class DotGroupCollaboration;
+class DotRunnerQueue;
+
+enum GraphOutputFormat { GOF_BITMAP, GOF_EPS };
+enum EmbeddedOutputFormat { EOF_Html, EOF_LaTeX, EOF_Rtf, EOF_DocBook };
+
+/** Attributes of an edge of a dot graph */
+struct EdgeInfo
+{
+ enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5 };
+ enum Styles { Solid=0, Dashed=1 };
+ EdgeInfo() : m_color(0), m_style(0), m_labColor(0) {}
+ ~EdgeInfo() {}
+ int m_color;
+ int m_style;
+ QCString m_label;
+ QCString m_url;
+ int m_labColor;
+};
+
+/** A node in a dot graph */
+class DotNode
+{
+ public:
+ enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph };
+ enum TruncState { Unknown, Truncated, Untruncated };
+ DotNode(int n,const char *lab,const char *tip,const char *url,
+ bool rootNode=FALSE,ClassDef *cd=0);
+ ~DotNode();
+ void addChild(DotNode *n,
+ int edgeColor=EdgeInfo::Purple,
+ int edgeStyle=EdgeInfo::Solid,
+ const char *edgeLab=0,
+ const char *edgeURL=0,
+ int edgeLabCol=-1
+ );
+ void addParent(DotNode *n);
+ void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0);
+ void removeChild(DotNode *n);
+ void removeParent(DotNode *n);
+ int findParent( DotNode *n );
+ void write(FTextStream &t,GraphType gt,GraphOutputFormat f,
+ bool topDown,bool toChildren,bool backArrows,bool reNumber);
+ int m_subgraphId;
+ void clearWriteFlag();
+ void writeXML(FTextStream &t,bool isClassGraph);
+ void writeDocbook(FTextStream &t,bool isClassGraph);
+ void writeDEF(FTextStream &t);
+ QCString label() const { return m_label; }
+ int number() const { return m_number; }
+ bool isVisible() const { return m_visible; }
+ TruncState isTruncated() const { return m_truncated; }
+ int distance() const { return m_distance; }
+
+ private:
+ void colorConnectedNodes(int curColor);
+ void writeBox(FTextStream &t,GraphType gt,GraphOutputFormat f,
+ bool hasNonReachableChildren, bool reNumber=FALSE);
+ void writeArrow(FTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn,
+ EdgeInfo *ei,bool topDown, bool pointBack=TRUE, bool reNumber=FALSE);
+ void setDistance(int distance);
+ const DotNode *findDocNode() const; // only works for acyclic graphs!
+ void markAsVisible(bool b=TRUE) { m_visible=b; }
+ void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; }
+ int m_number;
+ QCString m_label; //!< label text
+ QCString m_tooltip; //!< node's tooltip
+ QCString m_url; //!< url of the node (format: remote$local)
+ QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows)
+ QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows)
+ QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child
+ bool m_deleted; //!< used to mark a node as deleted
+ bool m_written; //!< used to mark a node as written
+ bool m_hasDoc; //!< used to mark a node as documented
+ bool m_isRoot; //!< indicates if this is a root node
+ ClassDef * m_classDef; //!< class representing this node (can be 0)
+ bool m_visible; //!< is the node visible in the output
+ TruncState m_truncated; //!< does the node have non-visible children/parents
+ int m_distance; //!< shortest path to the root node
+
+ friend class DotGfxHierarchyTable;
+ friend class DotClassGraph;
+ friend class DotInclDepGraph;
+ friend class DotNodeList;
+ friend class DotCallGraph;
+ friend class DotGroupCollaboration;
+
+ friend QCString computeMd5Signature(
+ DotNode *root, GraphType gt,
+ GraphOutputFormat f,
+ bool lrRank, bool renderParents,
+ bool backArrows,
+ const QCString &title,
+ QCString &graphStr
+ );
+};
+
+inline int DotNode::findParent( DotNode *n )
+{
+ if( !m_parents )
+ return -1;
+ return m_parents->find(n);
+}
+
+/** Represents a graphical class hierarchy */
+class DotGfxHierarchyTable
+{
+ public:
+ DotGfxHierarchyTable();
+ ~DotGfxHierarchyTable();
+ void writeGraph(FTextStream &t,const char *path, const char *fileName) const;
+
+ private:
+ void addHierarchy(DotNode *n,ClassDef *cd,bool hide);
+ void addClassList(ClassSDict *cl);
+
+ QList<DotNode> *m_rootNodes;
+ QDict<DotNode> *m_usedNodes;
+ static int m_curNodeNumber;
+ DotNodeList *m_rootSubgraphs;
+};
+
+/** Representation of a class inheritance or dependency graph */
+class DotClassGraph
+{
+ public:
+ DotClassGraph(ClassDef *cd,DotNode::GraphType t);
+ ~DotClassGraph();
+ bool isTrivial() const;
+ bool isTooBig() const;
+ QCString writeGraph(FTextStream &t,GraphOutputFormat gf,EmbeddedOutputFormat ef,
+ const char *path, const char *fileName, const char *relPath,
+ bool TBRank=TRUE,bool imageMap=TRUE,int graphId=-1) const;
+
+ void writeXML(FTextStream &t);
+ void writeDocbook(FTextStream &t);
+ void writeDEF(FTextStream &t);
+ QCString diskName() const;
+
+ private:
+ void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance);
+ bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents);
+ void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents);
+ void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,
+ const char *usedName,const char *templSpec,
+ bool base,int distance);
+
+ DotNode * m_startNode;
+ QDict<DotNode> * m_usedNodes;
+ static int m_curNodeNumber;
+ DotNode::GraphType m_graphType;
+ QCString m_diskName;
+ bool m_lrRank;
+};
+
+/** Representation of an include dependency graph */
+class DotInclDepGraph
+{
+ public:
+ DotInclDepGraph(FileDef *fd,bool inverse);
+ ~DotInclDepGraph();
+ QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef,
+ const char *path,const char *fileName,const char *relPath,
+ bool writeImageMap=TRUE,int graphId=-1) const;
+ bool isTrivial() const;
+ bool isTooBig() const;
+ QCString diskName() const;
+ void writeXML(FTextStream &t);
+ void writeDocbook(FTextStream &t);
+ private:
+ void buildGraph(DotNode *n,FileDef *fd,int distance);
+ void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes);
+ void determineTruncatedNodes(QList<DotNode> &queue);
+
+ DotNode *m_startNode;
+ QDict<DotNode> *m_usedNodes;
+ static int m_curNodeNumber;
+ QCString m_diskName;
+ bool m_inverse;
+};
+
+/** Representation of an call graph */
+class DotCallGraph
+{
+ public:
+ DotCallGraph(MemberDef *md,bool inverse);
+ ~DotCallGraph();
+ QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef,
+ const char *path,const char *fileName,
+ const char *relPath,bool writeImageMap=TRUE,
+ int graphId=-1) const;
+ void buildGraph(DotNode *n,MemberDef *md,int distance);
+ bool isTrivial() const;
+ bool isTooBig() const;
+ void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);
+ void determineTruncatedNodes(QList<DotNode> &queue);
+
+ private:
+ DotNode *m_startNode;
+ static int m_curNodeNumber;
+ QDict<DotNode> *m_usedNodes;
+ bool m_inverse;
+ QCString m_diskName;
+ Definition * m_scope;
+};
+
+/** Representation of an directory dependency graph */
+class DotDirDeps
+{
+ public:
+ DotDirDeps(DirDef *dir);
+ ~DotDirDeps();
+ bool isTrivial() const;
+ QCString writeGraph(FTextStream &out,
+ GraphOutputFormat gf,
+ EmbeddedOutputFormat ef,
+ const char *path,
+ const char *fileName,
+ const char *relPath,
+ bool writeImageMap=TRUE,
+ int graphId=-1) const;
+ private:
+ DirDef *m_dir;
+};
+
+/** Representation of a group collaboration graph */
+class DotGroupCollaboration
+{
+ public :
+ enum EdgeType
+ { tmember = 0,
+ tclass,
+ tnamespace,
+ tfile,
+ tpages,
+ tdir,
+ thierarchy
+ };
+
+ class Link
+ {
+ public:
+ Link(const QCString lab,const QCString &u) : label(lab), url(u) {}
+ QCString label;
+ QCString url;
+ };
+
+ class Edge
+ {
+ public :
+ Edge(DotNode *start,DotNode *end,EdgeType type)
+ : pNStart(start), pNEnd(end), eType(type)
+ { links.setAutoDelete(TRUE); }
+
+ DotNode* pNStart;
+ DotNode* pNEnd;
+ EdgeType eType;
+
+ QList<Link> links;
+ void write( FTextStream &t ) const;
+ };
+
+ DotGroupCollaboration(GroupDef* gd);
+ ~DotGroupCollaboration();
+ QCString writeGraph(FTextStream &t, GraphOutputFormat gf,EmbeddedOutputFormat ef,
+ const char *path,const char *fileName,const char *relPath,
+ bool writeImageMap=TRUE,int graphId=-1) const;
+ void buildGraph(GroupDef* gd);
+ bool isTrivial() const;
+ private :
+ void addCollaborationMember( Definition* def, QCString& url, EdgeType eType );
+ void addMemberList( class MemberList* ml );
+ void writeGraphHeader(FTextStream &t,const QCString &title) const;
+ Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType,
+ const QCString& _label, const QCString& _url );
+
+ DotNode *m_rootNode;
+ int m_curNodeId;
+ QDict<DotNode> *m_usedNodes;
+ QCString m_diskName;
+ QList<Edge> m_edges;
+};
+
+/** Helper class to run dot from doxygen.
+ */
+class DotRunner
+{
+ public:
+ struct CleanupItem
+ {
+ QCString path;
+ QCString file;
+ };
+
+ /** Creates a runner for a dot \a file. */
+ DotRunner(const QCString &file,const QCString &fontPath,bool checkResult,
+ const QCString &imageName = QCString());
+
+ /** Adds an additional job to the run.
+ * Performing multiple jobs one file can be faster.
+ */
+ void addJob(const char *format,const char *output);
+
+ void addPostProcessing(const char *cmd,const char *args);
+
+ void preventCleanUp() { m_cleanUp = FALSE; }
+
+ /** Runs dot for all jobs added. */
+ bool run();
+ CleanupItem cleanup() const { return m_cleanupItem; }
+
+ private:
+ QList<QCString> m_jobs;
+ QCString m_postArgs;
+ QCString m_postCmd;
+ QCString m_file;
+ QCString m_path;
+ bool m_checkResult;
+ QCString m_imageName;
+ bool m_cleanUp;
+ CleanupItem m_cleanupItem;
+};
+
+/** Helper class to insert a set of map file into an output file */
+class DotFilePatcher
+{
+ public:
+ struct Map
+ {
+ QCString mapFile;
+ QCString relPath;
+ bool urlOnly;
+ QCString context;
+ QCString label;
+ bool zoomable;
+ int graphId;
+ };
+ DotFilePatcher(const char *patchFile);
+ int addMap(const QCString &mapFile,const QCString &relPath,
+ bool urlOnly,const QCString &context,const QCString &label);
+ int addFigure(const QCString &baseName,
+ const QCString &figureName,bool heightCheck);
+ int addSVGConversion(const QCString &relPath,bool urlOnly,
+ const QCString &context,bool zoomable,int graphId);
+ int addSVGObject(const QCString &baseName, const QCString &figureName,
+ const QCString &relPath);
+ bool run();
+ QCString file() const;
+
+ private:
+ QList<Map> m_maps;
+ QCString m_patchFile;
+};
+
+/** Queue of dot jobs to run. */
+class DotRunnerQueue
+{
+ public:
+ void enqueue(DotRunner *runner);
+ DotRunner *dequeue();
+ uint count() const;
+ private:
+ QWaitCondition m_bufferNotEmpty;
+ QQueue<DotRunner> m_queue;
+ mutable QMutex m_mutex;
+};
+
+/** Worker thread to execute a dot run */
+class DotWorkerThread : public QThread
+{
+ public:
+ DotWorkerThread(DotRunnerQueue *queue);
+ void run();
+ void cleanup();
+ private:
+ DotRunnerQueue *m_queue;
+ QList<DotRunner::CleanupItem> m_cleanupItems;
+};
+
+/** Singleton that manages dot relation actions */
+class DotManager
+{
+ public:
+ static DotManager *instance();
+ void addRun(DotRunner *run);
+ int addMap(const QCString &file,const QCString &mapFile,
+ const QCString &relPath,bool urlOnly,
+ const QCString &context,const QCString &label);
+ int addFigure(const QCString &file,const QCString &baseName,
+ const QCString &figureName,bool heightCheck);
+ int addSVGConversion(const QCString &file,const QCString &relPath,
+ bool urlOnly,const QCString &context,bool zoomable,int graphId);
+ int addSVGObject(const QCString &file,const QCString &baseName,
+ const QCString &figureNAme,const QCString &relPath);
+ bool run();
+
+ private:
+ DotManager();
+ virtual ~DotManager();
+ QList<DotRunner> m_dotRuns;
+ SDict<DotFilePatcher> m_dotMaps;
+ static DotManager *m_theInstance;
+ DotRunnerQueue *m_queue;
+ QList<DotWorkerThread> m_workers;
+};
+
+
+/** Generated a graphs legend page */
+void generateGraphLegend(const char *path);
+
+void writeDotGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,GraphOutputFormat format);
+void writeDotImageMapFromFile(FTextStream &t,
+ const QCString& inFile, const QCString& outDir,
+ const QCString& relPath,const QCString& baseName,
+ const QCString& context,int graphId=-1);
+
+void writeDotDirDepGraph(FTextStream &t,DirDef *dd);
+
+#endif
diff --git a/src/doxygen.bst b/src/doxygen.bst
new file mode 100644
index 0000000..c6ae7a8
--- /dev/null
+++ b/src/doxygen.bst
@@ -0,0 +1,1388 @@
+ % $Id: html-btxbst.doc 1.5 2010/12/08 19:02:34 dds Exp $
+ %
+ % This file is either "html-btxbst.doc" or was derived from
+ % "html-btxbst.doc" using cpp. "html-btxbst.doc" itself was edited
+ % from "btxbst.doc" and "named.bst".
+ % The following copyright information is from btxbst.doc:
+ % version 0.99b for BibTeX versions 0.99a or later, LaTeX version 2.09.
+ % Copyright (C) 1985, all rights reserved.
+ % Copying of this file is authorized only if either
+ % (1) you make absolutely no changes to your copy, including name, or
+ % (2) if you do make changes, you name it something other than
+ % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst.
+ % This restriction helps ensure that all standard styles are identical.
+ % The file btxbst.doc has the documentation for this style.
+ % "named" style (sorted keys of the form [name, year])
+ % Some code for this was taken from "named.bst".
+
+ENTRY
+ { address
+ author
+ booktitle
+ chapter
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ month
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ volume
+ year
+ dvi
+ html
+ keywords
+ pdf
+ postscript
+ url
+ doi
+ mailto
+ }
+ {}
+ { label extra.label sort.label }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+
+STRINGS { s t }
+
+FUNCTION {output.nonnull}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+ { add.period$ write$
+ newline$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+
+FUNCTION {output.bibitem}
+{ newline$
+ author empty$
+ { editor empty$
+ { organization empty$
+ 'skip$
+ { "<!-- Authors: " organization purify$ * " -->" * write$ newline$ }
+ if$
+ }
+ { "<!-- Authors: " editor purify$ * " -->" * write$ newline$ }
+ if$
+ }
+ { "<!-- Authors: " author purify$ * " -->" * write$ newline$ }
+ if$
+ keywords empty$
+ 'skip$
+ { "<!-- Keywords: " keywords * " -->" * write$ newline$ }
+ if$
+ "<dt><a name=" quote$ * "CITEREF_" * cite$ * quote$ * ">[" * label * "]</a></dt><dd>" * write$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {fin.entry}
+{ add.period$
+ write$
+ postscript empty$
+ 'skip$
+ { newline$ "<!-- PostScript: " postscript * " -->" * write$ }
+ if$
+ pdf empty$
+ 'skip$
+ { newline$ "<!-- PDF: " pdf * " -->" * write$ }
+ if$
+ dvi empty$
+ 'skip$
+ { newline$ "<!-- DVI: " dvi * " -->" * write$ }
+ if$
+ doi empty$
+ 'skip$
+ { newline$ "<!-- DOI: " doi * " -->" * write$ }
+ if$
+ "</dd>" write$
+ newline$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+
+FUNCTION {str.to.int}
+{
+ 's :=
+ #0
+ { s empty$ not }
+ { % Multiply the number on the top of the stack by 10 = 1010 binary
+ duplicate$ + % x2
+ duplicate$ % x2 x2
+ duplicate$ + duplicate$ + % x2 x8
+ +
+ s #1 #1 substring$ chr.to.int$ #48 - + % #48 is ascii for '0'
+ s #2 global.max$ substring$ 's :=
+ }
+ while$
+}
+
+FUNCTION {new.block.checka}
+{ empty$
+ 'skip$
+ 'new.block
+ if$
+}
+
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+
+FUNCTION {new.sentence.checka}
+{ empty$
+ 'skip$
+ 'new.sentence
+ if$
+}
+
+FUNCTION {new.sentence.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.sentence
+ if$
+}
+
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+
+FUNCTION {emphasize}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "<em>" swap$ * "</em>" * }
+ if$
+}
+
+FUNCTION {add.link} % title
+{
+ 't :=
+ t empty$
+ { "" }
+ { url empty$
+ { html empty$
+ { t }
+ { "<a href=" quote$ * html * quote$ * ">" * t * "</a>" * }
+ if$ }
+ { "<a href=" quote$ * url * quote$ * ">" * t * "</a>" * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {add.mailto} % authors
+{
+ 't :=
+ t empty$
+ { "" }
+ { mailto empty$
+ { t }
+ { "<a href=" quote$ * "mailto:" * mailto * quote$ * ">" * t * "</a>" * }
+ if$
+ }
+ if$
+}
+
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 's :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't :=
+ "\bibxhtmlname{" t * "}" * 't :=
+ nameptr #1 >
+ { namesleft #1 >
+ { ", " * t * }
+ { numnames #2 >
+ { "," * }
+ 'skip$
+ if$
+ t "others" =
+ { " et~al." * }
+ { " and " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {format.authors}
+{ author empty$
+ { "" }
+ { author format.names }
+ if$
+ add.mailto
+}
+
+FUNCTION {format.editors}
+{ editor empty$
+ { "" }
+ { editor format.names
+ editor num.names$ #1 >
+ { ", editors" * }
+ { ", editor" * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title empty$
+ { "" }
+ { title "t" change.case$ }
+ if$
+ add.link
+}
+
+FUNCTION {n.dashify}
+{ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {format.date}
+{ year empty$
+ { month empty$
+ { "" }
+ { "there's a month but no year in " cite$ * warning$
+ month
+ }
+ if$
+ }
+ { month empty$
+ 'year
+ { month " " * year * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.btitle}
+{ title emphasize
+ add.link
+}
+
+FUNCTION {tie.or.space.connect}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$ * *
+}
+
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+
+FUNCTION {format.bvolume}
+{ volume empty$
+ { "" }
+ { "volume" volume tie.or.space.connect
+ series empty$
+ 'skip$
+ { " of " * series emphasize * }
+ if$
+ "volume and number" number either.or.check
+ }
+ if$
+}
+
+FUNCTION {format.number.series}
+{ volume empty$
+ { number empty$
+ { series field.or.null }
+ { output.state mid.sentence =
+ { "number" }
+ { "Number" }
+ if$
+ number tie.or.space.connect
+ series empty$
+ { "there's a number but no series in " cite$ * warning$ }
+ { " in " * series * }
+ if$
+ }
+ if$
+ }
+ { "" }
+ if$
+}
+
+FUNCTION {format.edition}
+{ edition empty$
+ { "" }
+ { output.state mid.sentence =
+ { edition "l" change.case$ " edition" * }
+ { edition "t" change.case$ " edition" * }
+ if$
+ }
+ if$
+}
+
+INTEGERS { multiresult }
+
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+
+FUNCTION {format.pages}
+{ pages empty$
+ { "" }
+ { pages multi.page.check
+ { "pages" pages n.dashify tie.or.space.connect }
+ { "page" pages tie.or.space.connect }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.vol.num.pages}
+{ volume field.or.null
+ number empty$
+ 'skip$
+ { "(" number * ")" * *
+ volume empty$
+ { "there's a number but no volume in " cite$ * warning$ }
+ 'skip$
+ if$
+ }
+ if$
+ pages empty$
+ 'skip$
+ { duplicate$ empty$
+ { pop$ format.pages }
+ { ":" * pages n.dashify * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+ 'format.pages
+ { type empty$
+ { "chapter" }
+ { type "l" change.case$ }
+ if$
+ chapter tie.or.space.connect
+ pages empty$
+ 'skip$
+ { ", " * format.pages * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.in.ed.booktitle}
+{ booktitle empty$
+ { "" }
+ { editor empty$
+ { "In " booktitle emphasize * }
+ { "In " format.editors * ", " * booktitle emphasize * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {empty.misc.check}
+{ author empty$ title empty$ howpublished empty$
+ month empty$ year empty$ note empty$
+ and and and and and
+ key empty$ not and
+ { "all relevant fields are empty in " cite$ * warning$ }
+ 'skip$
+ if$
+}
+
+FUNCTION {format.thesis.type}
+{ type empty$
+ 'skip$
+ { pop$
+ type "t" change.case$
+ }
+ if$
+}
+
+FUNCTION {format.tr.number}
+{ type empty$
+ { "Technical Report" }
+ 'type
+ if$
+ number empty$
+ { "t" change.case$ }
+ { number tie.or.space.connect }
+ if$
+}
+
+FUNCTION {format.article.crossref}
+{
+ "In <a href=" quote$ * "#" * crossref * quote$ * ">" *
+ key empty$
+ { journal empty$
+ { "need key or journal for " cite$ * " to crossref " * crossref *
+ warning$
+ ""
+ }
+ { "<cite>" * journal * "</cite>" * }
+ if$
+ }
+ { key * }
+ if$
+ "</a> \citelabel{" * crossref * "}" *
+}
+
+FUNCTION {format.crossref.editor}
+{ editor #1 "{vv~}{ll}" format.name$
+ editor num.names$ duplicate$
+ #2 >
+ { pop$ " et~al." * }
+ { #2 <
+ 'skip$
+ { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ { " et~al." * }
+ { " and " * editor #2 "{vv~}{ll}" format.name$ * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.book.crossref}
+{ volume empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ "In "
+ }
+ { "Volume" volume tie.or.space.connect
+ " of " *
+ }
+ if$
+ "<a href=" * quote$ * "#" * crossref * quote$ * ">" *
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { series empty$
+ { "need editor, key, or series for " cite$ * " to crossref " *
+ crossref * warning$
+ "" *
+ }
+ { "<cite>" * series * "</cite>" * }
+ if$
+ }
+ { key * }
+ if$
+ }
+ { format.crossref.editor * }
+ if$
+ "</a> \citelabel{" * crossref * "}" *
+}
+
+FUNCTION {format.incoll.inproc.crossref}
+{
+ "In <a href=" quote$ * "#" * crossref * quote$ * ">" *
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { booktitle empty$
+ { "need editor, key, or booktitle for " cite$ * " to crossref " *
+ crossref * warning$
+ ""
+ }
+ { "<cite>" * booktitle * "</cite>" * }
+ if$
+ }
+ { key * }
+ if$
+ }
+ { format.crossref.editor * }
+ if$
+ "</a> \citelabel{" * crossref * "}" *
+}
+
+FUNCTION {article}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { journal emphasize "journal" output.check
+ format.vol.num.pages output
+ format.date "year" output.check
+ }
+ { format.article.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {book}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ new.block
+ format.btitle "title" output.check
+ crossref missing$
+ { format.bvolume output
+ new.block
+ format.number.series output
+ new.sentence
+ publisher "publisher" output.check
+ address output
+ }
+ { new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.edition output
+ format.date "year" output.check
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {booklet}
+{ output.bibitem
+ format.authors output
+ new.block
+ format.title "title" output.check
+ howpublished address new.block.checkb
+ howpublished output
+ address output
+ format.date output
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {inbook}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ new.block
+ format.btitle "title" output.check
+ crossref missing$
+ { format.bvolume output
+ format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.number.series output
+ new.sentence
+ publisher "publisher" output.check
+ address output
+ }
+ { format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.edition output
+ format.date "year" output.check
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {incollection}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ format.chapter.pages output
+ new.sentence
+ publisher "publisher" output.check
+ address output
+ format.edition output
+ format.date "year" output.check
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.chapter.pages output
+ }
+ if$
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {inproceedings}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ format.pages output
+ address empty$
+ { organization publisher new.sentence.checkb
+ organization output
+ publisher output
+ format.date "year" output.check
+ }
+ { address output.nonnull
+ format.date "year" output.check
+ new.sentence
+ organization output
+ publisher output
+ }
+ if$
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {conference} { inproceedings }
+
+FUNCTION {manual}
+{ output.bibitem
+ author empty$
+ { organization empty$
+ 'skip$
+ { organization output.nonnull
+ address output
+ }
+ if$
+ }
+ { format.authors output.nonnull }
+ if$
+ new.block
+ format.btitle "title" output.check
+ author empty$
+ { organization empty$
+ { address new.block.checka
+ address output
+ }
+ 'skip$
+ if$
+ }
+ { organization address new.block.checkb
+ organization output
+ address output
+ }
+ if$
+ format.edition output
+ format.date output
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ "Master's thesis" format.thesis.type output.nonnull
+ school "school" output.check
+ address output
+ format.date "year" output.check
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {misc}
+{ output.bibitem
+ format.authors output
+ title howpublished new.block.checkb
+ format.title output
+ howpublished new.block.checka
+ howpublished output
+ format.date output
+ new.block
+ note output
+ fin.entry
+ empty.misc.check
+}
+
+FUNCTION {phdthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.btitle "title" output.check
+ new.block
+ "PhD thesis" format.thesis.type output.nonnull
+ school "school" output.check
+ address output
+ format.date "year" output.check
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {proceedings}
+{ output.bibitem
+ editor empty$
+ { organization output }
+ { format.editors output.nonnull }
+ if$
+ new.block
+ format.btitle "title" output.check
+ format.bvolume output
+ format.number.series output
+ address empty$
+ { editor empty$
+ { publisher new.sentence.checka }
+ { organization publisher new.sentence.checkb
+ organization output
+ }
+ if$
+ publisher output
+ format.date "year" output.check
+ }
+ { address output.nonnull
+ format.date "year" output.check
+ new.sentence
+ editor empty$
+ 'skip$
+ { organization output }
+ if$
+ publisher output
+ }
+ if$
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {techreport}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ format.tr.number output.nonnull
+ institution "institution" output.check
+ address output
+ format.date "year" output.check
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {unpublished}
+{ output.bibitem
+ format.authors "author" output.check
+ new.block
+ format.title "title" output.check
+ new.block
+ note "note" output.check
+ format.date output
+ fin.entry
+}
+
+FUNCTION {default.type} { misc }
+
+MACRO {jan} {"January"}
+
+MACRO {feb} {"February"}
+
+MACRO {mar} {"March"}
+
+MACRO {apr} {"April"}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"August"}
+
+MACRO {sep} {"September"}
+
+MACRO {oct} {"October"}
+
+MACRO {nov} {"November"}
+
+MACRO {dec} {"December"}
+
+MACRO {acmcs} {"ACM Computing Surveys"}
+
+MACRO {acta} {"Acta Informatica"}
+
+MACRO {cacm} {"Communications of the ACM"}
+
+MACRO {ibmjrd} {"IBM Journal of Research and Development"}
+
+MACRO {ibmsj} {"IBM Systems Journal"}
+
+MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
+
+MACRO {ieeetc} {"IEEE Transactions on Computers"}
+
+MACRO {ieeetcad}
+ {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
+
+MACRO {ipl} {"Information Processing Letters"}
+
+MACRO {jacm} {"Journal of the ACM"}
+
+MACRO {jcss} {"Journal of Computer and System Sciences"}
+
+MACRO {scp} {"Science of Computer Programming"}
+
+MACRO {sicomp} {"SIAM Journal on Computing"}
+
+MACRO {tocs} {"ACM Transactions on Computer Systems"}
+
+MACRO {tods} {"ACM Transactions on Database Systems"}
+
+MACRO {tog} {"ACM Transactions on Graphics"}
+
+MACRO {toms} {"ACM Transactions on Mathematical Software"}
+
+MACRO {toois} {"ACM Transactions on Office Information Systems"}
+
+MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
+
+MACRO {tcs} {"Theoretical Computer Science"}
+
+READ
+
+FUNCTION {sortify}
+{ purify$
+ "l" change.case$
+}
+
+INTEGERS { len }
+
+FUNCTION {chop.word}
+{ 's :=
+ 'len :=
+ s #1 len substring$ =
+ { s len #1 + global.max$ substring$ }
+ 's
+ if$
+}
+
+
+FUNCTION {format.lab.names}
+{ 's :=
+ s num.names$ 'numnames :=
+ numnames #1 =
+ { s #1 "{vv }{ll}" format.name$ }
+ { numnames #2 =
+ { s #1 "{vv }{ll }and " format.name$ s #2 "{vv }{ll}" format.name$ * }
+ { s #1 "{vv }{ll }" format.name$ "et~al." * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {author.key.label}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {author.editor.key.label}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { editor format.lab.names }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {author.key.organization.label}
+{ author empty$
+ { key empty$
+ { organization empty$
+ { cite$ #1 #3 substring$ }
+ { "The " #4 organization chop.word #3 text.prefix$ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {editor.key.organization.label}
+{ editor empty$
+ { key empty$
+ { organization empty$
+ { cite$ #1 #3 substring$ }
+ { "The " #4 organization chop.word #3 text.prefix$ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { editor format.lab.names }
+ if$
+}
+
+FUNCTION {month.to.int}
+{
+ "l" change.case$ #3 text.prefix$
+ 's :=
+ s "jan" = { #1 } {
+ s "feb" = { #2 } {
+ s "mar" = { #3 } {
+ s "apr" = { #4 } {
+ s "may" = { #5 } {
+ s "jun" = { #6 } {
+ s "jul" = { #7 } {
+ s "aug" = { #8 } {
+ s "sep" = { #9 } {
+ s "oct" = { #10 } {
+ s "nov" = { #11 } {
+ s "dec" = { #12 } { #13 } % 13 if nothing matches
+ if$}if$}if$}if$}if$}if$}if$}if$}if$}if$}if$}if$
+}
+
+INTEGERS { done c }
+FUNCTION { get.day }
+{ month field.or.null 's :=
+
+ % Strip out month name
+ #0 'done :=
+ { s "" = not done not and }
+ { s #1 #1 substring$ " " = 'done :=
+ s #2 global.max$ substring$ 's :=
+ }
+ while$
+
+ % Build up first number in t
+ "0" 't :=
+ #0 'done :=
+ { s "" = not done not and }
+ { s #1 #1 substring$ chr.to.int$ 'c :=
+ c #47 > c #58 < and
+ { t c int.to.chr$ * 't := }
+ { #1 'done := }
+ if$
+ s #2 global.max$ substring$ 's :=
+ }
+ while$
+
+ t str.to.int
+}
+
+FUNCTION { sortify.fourdigit }
+{ 's :=
+ s empty$
+ { "0000" }
+ { s
+ }
+ if$
+}
+
+FUNCTION { sortify.twodigit }
+{ 's :=
+ s empty$
+ { "00" }
+ { s
+ str.to.int #10 + int.to.str$
+ }
+ if$
+}
+
+FUNCTION {calc.label}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.label
+ { type$ "proceedings" =
+ 'editor.key.organization.label
+ { type$ "manual" =
+ 'author.key.organization.label
+ 'author.key.label
+ if$
+ }
+ if$
+ }
+ if$
+ duplicate$
+
+ year empty$
+ 'skip$
+ { ", " * }
+ if$
+ year field.or.null purify$ * % CHANGED - pfps - 15 Feb 1989
+ 'label :=
+
+ year field.or.null purify$
+ #-1 #4 substring$
+ sortify.fourdigit
+ " " *
+ month field.or.null month.to.int int.to.str$ sortify.twodigit *
+ " " *
+ get.day int.to.str$ sortify.twodigit *
+ " " *
+ * sortify 'sort.label :=
+}
+
+FUNCTION {sort.format.names}
+{ 's :=
+ #1 'nameptr :=
+ ""
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { nameptr #1 >
+ { " " * }
+ 'skip$
+ if$
+ s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't :=
+ nameptr numnames = t "others" = and
+ { "et al." * }
+ { t sortify * }
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+ "A " #2
+ "An " #3
+ "The " #4 t chop.word
+ chop.word
+ chop.word
+ sortify
+ #1 global.max$ substring$
+}
+
+FUNCTION {author.sort}
+{ author empty$
+ { key empty$
+ { "to sort, need author or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+
+FUNCTION {author.editor.sort}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { "to sort, need author, editor, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+
+FUNCTION {author.organization.sort}
+{ author empty$
+ { organization empty$
+ { key empty$
+ { "to sort, need author, organization, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { "The " #4 organization chop.word sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+
+FUNCTION {editor.organization.sort}
+{ editor empty$
+ { organization empty$
+ { key empty$
+ { "to sort, need editor, organization, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { "The " #4 organization chop.word sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+}
+
+FUNCTION {presort}
+{ calc.label
+ sort.label
+ " "
+ *
+ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.sort
+ { type$ "proceedings" =
+ 'editor.organization.sort
+ { type$ "manual" =
+ 'author.organization.sort
+ 'author.sort
+ if$
+ }
+ if$
+ }
+ if$
+ *
+ " "
+ *
+ year field.or.null sortify
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+
+ITERATE {presort}
+
+SORT
+
+STRINGS { longest.label last.sort.label next.extra }
+
+INTEGERS { longest.label.width last.extra.num }
+
+FUNCTION {initialize.longest.label}
+{ "" 'longest.label :=
+ #0 int.to.chr$ 'last.sort.label :=
+ "" 'next.extra :=
+ #0 'longest.label.width :=
+ #0 'last.extra.num :=
+}
+
+FUNCTION {forward.pass}
+{ last.sort.label sort.label =
+ { last.extra.num #1 + 'last.extra.num :=
+ last.extra.num int.to.chr$ 'extra.label :=
+ }
+ { "a" chr.to.int$ 'last.extra.num :=
+ "" 'extra.label :=
+ sort.label 'last.sort.label :=
+ }
+ if$
+}
+
+FUNCTION {reverse.pass}
+{ next.extra "b" =
+ { "a" 'extra.label := }
+ 'skip$
+ if$
+ label extra.label * 'label :=
+ label width$ longest.label.width >
+ { label 'longest.label :=
+ label width$ 'longest.label.width :=
+ }
+ 'skip$
+ if$
+ extra.label 'next.extra :=
+}
+
+EXECUTE {initialize.longest.label}
+
+ITERATE {forward.pass}
+
+REVERSE {reverse.pass}
+
+FUNCTION {begin.bib}
+{
+ "# label-style: default" write$ newline$
+}
+
+EXECUTE {begin.bib}
+
+EXECUTE {init.state.consts}
+
+ITERATE {call.type$}
+
+FUNCTION {end.bib}
+{ newline$
+}
+
+EXECUTE {end.bib}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
new file mode 100644
index 0000000..533e6ef
--- /dev/null
+++ b/src/doxygen.cpp
@@ -0,0 +1,11602 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <locale.h>
+
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <qstrlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <qtextcodec.h>
+#include <unistd.h>
+#include <errno.h>
+#include <qptrdict.h>
+#include <qtextstream.h>
+
+#include "version.h"
+#include "doxygen.h"
+#include "scanner.h"
+#include "entry.h"
+#include "index.h"
+#include "logos.h"
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "pre.h"
+#include "tagreader.h"
+#include "dot.h"
+#include "msc.h"
+#include "docparser.h"
+#include "dirdef.h"
+#include "outputlist.h"
+#include "declinfo.h"
+#include "htmlgen.h"
+#include "latexgen.h"
+#include "mangen.h"
+#include "language.h"
+#include "debug.h"
+#include "htmlhelp.h"
+#include "qhp.h"
+#include "ftvhelp.h"
+#include "defargs.h"
+#include "rtfgen.h"
+#include "sqlite3gen.h"
+#include "xmlgen.h"
+#include "docbookgen.h"
+#include "defgen.h"
+#include "perlmodgen.h"
+#include "reflist.h"
+#include "pagedef.h"
+#include "bufstr.h"
+#include "commentcnv.h"
+#include "cmdmapper.h"
+#include "searchindex.h"
+#include "parserintf.h"
+#include "htags.h"
+#include "pyscanner.h"
+#include "fortranscanner.h"
+#include "dbusxmlscanner.h"
+#include "tclscanner.h"
+#include "code.h"
+#include "objcache.h"
+#include "store.h"
+#include "marshal.h"
+#include "portable.h"
+#include "vhdljjparser.h"
+#include "vhdldocgen.h"
+#include "eclipsehelp.h"
+#include "cite.h"
+#include "filestorage.h"
+#include "markdown.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "layout.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "namespacedef.h"
+#include "filename.h"
+#include "membername.h"
+#include "membergroup.h"
+#include "docsets.h"
+#include "formula.h"
+#include "settings.h"
+#include "context.h"
+#include "fileparser.h"
+
+#define RECURSE_ENTRYTREE(func,var) \
+ do { if (var->children()) { \
+ EntryNavListIterator eli(*var->children()); \
+ for (;eli.current();++eli) func(eli.current()); \
+ } } while(0)
+
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <signal.h>
+#define HAS_SIGNALS
+#endif
+
+// globally accessible variables
+ClassSDict *Doxygen::classSDict = 0;
+ClassSDict *Doxygen::hiddenClasses = 0;
+NamespaceSDict *Doxygen::namespaceSDict = 0;
+MemberNameSDict *Doxygen::memberNameSDict = 0;
+MemberNameSDict *Doxygen::functionNameSDict = 0;
+FileNameList *Doxygen::inputNameList = 0; // all input files
+FileNameDict *Doxygen::inputNameDict = 0;
+GroupSDict *Doxygen::groupSDict = 0;
+FormulaList *Doxygen::formulaList = 0; // all formulas
+FormulaDict *Doxygen::formulaDict = 0; // all formulas
+FormulaDict *Doxygen::formulaNameDict = 0; // the label name of all formulas
+PageSDict *Doxygen::pageSDict = 0;
+PageSDict *Doxygen::exampleSDict = 0;
+SectionDict *Doxygen::sectionDict = 0; // all page sections
+CiteDict *Doxygen::citeDict=0; // database of bibliographic references
+StringDict Doxygen::aliasDict(257); // aliases
+QDict<void> Doxygen::inputPaths(1009);
+FileNameDict *Doxygen::includeNameDict = 0; // include names
+FileNameDict *Doxygen::exampleNameDict = 0; // examples
+FileNameDict *Doxygen::imageNameDict = 0; // images
+FileNameDict *Doxygen::dotFileNameDict = 0; // dot files
+FileNameDict *Doxygen::mscFileNameDict = 0; // msc files
+FileNameDict *Doxygen::diaFileNameDict = 0; // dia files
+StringDict Doxygen::namespaceAliasDict(257); // all namespace aliases
+StringDict Doxygen::tagDestinationDict(257); // all tag locations
+QDict<void> Doxygen::expandAsDefinedDict(257); // all macros that should be expanded
+QIntDict<MemberGroupInfo> Doxygen::memGrpInfoDict(1009); // dictionary of the member groups heading
+PageDef *Doxygen::mainPage = 0;
+bool Doxygen::insideMainPage = FALSE; // are we generating docs for the main page?
+FTextStream Doxygen::tagFile;
+NamespaceDef *Doxygen::globalScope = 0;
+QDict<RefList> *Doxygen::xrefLists = new QDict<RefList>; // dictionary of cross-referenced item lists
+bool Doxygen::parseSourcesNeeded = FALSE;
+QTime Doxygen::runningTime;
+SearchIndexIntf *Doxygen::searchIndex=0;
+QDict<DefinitionIntf> *Doxygen::symbolMap = 0;
+QDict<Definition> *Doxygen::clangUsrMap = 0;
+bool Doxygen::outputToWizard=FALSE;
+QDict<int> * Doxygen::htmlDirMap = 0;
+QCache<LookupInfo> *Doxygen::lookupCache;
+DirSDict *Doxygen::directories;
+SDict<DirRelation> Doxygen::dirRelations(257);
+ParserManager *Doxygen::parserManager = 0;
+QCString Doxygen::htmlFileExtension;
+bool Doxygen::suppressDocWarnings = FALSE;
+Store *Doxygen::symbolStorage;
+QCString Doxygen::objDBFileName;
+QCString Doxygen::entryDBFileName;
+bool Doxygen::gatherDefines = TRUE;
+IndexList *Doxygen::indexList;
+int Doxygen::subpageNestingLevel = 0;
+bool Doxygen::userComments = FALSE;
+QCString Doxygen::spaces;
+bool Doxygen::generatingXmlOutput = FALSE;
+bool Doxygen::markdownSupport = TRUE;
+GenericsSDict *Doxygen::genericsDict;
+
+// locally accessible globals
+static QDict<EntryNav> g_classEntries(1009);
+static StringList g_inputFiles;
+static QDict<void> g_compoundKeywordDict(7); // keywords recognised as compounds
+static OutputList *g_outputList = 0; // list of output generating objects
+static QDict<FileDef> g_usingDeclarations(1009); // used classes
+static FileStorage *g_storage = 0;
+static bool g_successfulRun = FALSE;
+static bool g_dumpSymbolMap = FALSE;
+static bool g_useOutputTemplate = FALSE;
+
+void clearAll()
+{
+ g_inputFiles.clear();
+ //g_excludeNameDict.clear();
+ //delete g_outputList; g_outputList=0;
+
+ Doxygen::classSDict->clear();
+ Doxygen::namespaceSDict->clear();
+ Doxygen::pageSDict->clear();
+ Doxygen::exampleSDict->clear();
+ Doxygen::inputNameList->clear();
+ Doxygen::formulaList->clear();
+ Doxygen::sectionDict->clear();
+ Doxygen::inputNameDict->clear();
+ Doxygen::includeNameDict->clear();
+ Doxygen::exampleNameDict->clear();
+ Doxygen::imageNameDict->clear();
+ Doxygen::dotFileNameDict->clear();
+ Doxygen::mscFileNameDict->clear();
+ Doxygen::diaFileNameDict->clear();
+ Doxygen::formulaDict->clear();
+ Doxygen::formulaNameDict->clear();
+ Doxygen::tagDestinationDict.clear();
+ delete Doxygen::citeDict;
+ delete Doxygen::mainPage; Doxygen::mainPage=0;
+}
+
+class Statistics
+{
+ public:
+ Statistics() { stats.setAutoDelete(TRUE); }
+ void begin(const char *name)
+ {
+ msg(name);
+ stat *entry= new stat(name,0);
+ stats.append(entry);
+ time.restart();
+ }
+ void end()
+ {
+ stats.getLast()->elapsed=((double)time.elapsed())/1000.0;
+ }
+ void print()
+ {
+ bool restore=FALSE;
+ if (Debug::isFlagSet(Debug::Time))
+ {
+ Debug::clearFlag("time");
+ restore=TRUE;
+ }
+ msg("----------------------\n");
+ QListIterator<stat> sli(stats);
+ stat *s;
+ for ( sli.toFirst(); (s=sli.current()); ++sli )
+ {
+ msg("Spent %.3f seconds in %s",s->elapsed,s->name);
+ }
+ if (restore) Debug::setFlag("time");
+ }
+ private:
+ struct stat
+ {
+ const char *name;
+ double elapsed;
+ stat() : name(NULL),elapsed(0) {}
+ stat(const char *n, double el) : name(n),elapsed(el) {}
+ };
+ QList<stat> stats;
+ QTime time;
+} g_s;
+
+
+void statistics()
+{
+ fprintf(stderr,"--- inputNameDict stats ----\n");
+ Doxygen::inputNameDict->statistics();
+ fprintf(stderr,"--- includeNameDict stats ----\n");
+ Doxygen::includeNameDict->statistics();
+ fprintf(stderr,"--- exampleNameDict stats ----\n");
+ Doxygen::exampleNameDict->statistics();
+ fprintf(stderr,"--- imageNameDict stats ----\n");
+ Doxygen::imageNameDict->statistics();
+ fprintf(stderr,"--- dotFileNameDict stats ----\n");
+ Doxygen::dotFileNameDict->statistics();
+ fprintf(stderr,"--- mscFileNameDict stats ----\n");
+ Doxygen::mscFileNameDict->statistics();
+ fprintf(stderr,"--- diaFileNameDict stats ----\n");
+ Doxygen::diaFileNameDict->statistics();
+ //fprintf(stderr,"--- g_excludeNameDict stats ----\n");
+ //g_excludeNameDict.statistics();
+ fprintf(stderr,"--- aliasDict stats ----\n");
+ Doxygen::aliasDict.statistics();
+ fprintf(stderr,"--- typedefDict stats ----\n");
+ fprintf(stderr,"--- namespaceAliasDict stats ----\n");
+ Doxygen::namespaceAliasDict.statistics();
+ fprintf(stderr,"--- formulaDict stats ----\n");
+ Doxygen::formulaDict->statistics();
+ fprintf(stderr,"--- formulaNameDict stats ----\n");
+ Doxygen::formulaNameDict->statistics();
+ fprintf(stderr,"--- tagDestinationDict stats ----\n");
+ Doxygen::tagDestinationDict.statistics();
+ fprintf(stderr,"--- g_compoundKeywordDict stats ----\n");
+ g_compoundKeywordDict.statistics();
+ fprintf(stderr,"--- expandAsDefinedDict stats ----\n");
+ Doxygen::expandAsDefinedDict.statistics();
+ fprintf(stderr,"--- memGrpInfoDict stats ----\n");
+ Doxygen::memGrpInfoDict.statistics();
+}
+
+
+
+static void addMemberDocs(EntryNav *rootNav,MemberDef *md, const char *funcDecl,
+ ArgumentList *al,bool over_load,NamespaceSDict *nl=0);
+static void findMember(EntryNav *rootNav,
+ QCString funcDecl,
+ bool overloaded,
+ bool isFunc
+ );
+
+enum FindBaseClassRelation_Mode
+{
+ TemplateInstances,
+ DocumentedOnly,
+ Undocumented
+};
+
+static bool findClassRelation(
+ EntryNav *rootNav,
+ Definition *context,
+ ClassDef *cd,
+ BaseInfo *bi,
+ QDict<int> *templateNames,
+ /*bool insertUndocumented*/
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial
+ );
+
+/** A struct contained the data for an STL class */
+struct STLInfo
+{
+ const char *className;
+ const char *baseClass1;
+ const char *baseClass2;
+ const char *templType1;
+ const char *templName1;
+ const char *templType2;
+ const char *templName2;
+ bool virtualInheritance;
+ bool iterators;
+};
+
+static STLInfo g_stlinfo[] =
+{
+ // className baseClass1 baseClass2 templType1 templName1 templType2 templName2 virtInheritance // iterators
+ { "allocator", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
+ { "array", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, // C++11
+ { "auto_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // deprecated
+ { "smart_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
+ { "unique_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
+ { "weak_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
+ { "ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "error_category", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "system_error", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "error_condition", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "thread", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
+ { "basic_ios", "ios_base", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_istream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE },
+ { "basic_ostream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE },
+ { "basic_iostream", "basic_istream<Char>", "basic_ostream<Char>", "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_ifstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_ofstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_fstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_istringstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_ostringstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "basic_stringstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
+ { "ios", "basic_ios<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wios", "basic_ios<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "istream", "basic_istream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wistream", "basic_istream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "ostream", "basic_ostream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wostream", "basic_ostream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "ifstream", "basic_ifstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wifstream", "basic_ifstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "ofstream", "basic_ofstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wofstream", "basic_ofstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "fstream", "basic_fstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wfstream", "basic_fstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "istringstream", "basic_istringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wistringstream", "basic_istringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "ostringstream", "basic_ostringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wostringstream", "basic_ostringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "stringstream", "basic_stringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "wstringstream", "basic_stringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "basic_string", 0, 0, "Char", 0, 0, 0, FALSE, TRUE },
+ { "string", "basic_string<char>", 0, 0, 0, 0, 0, FALSE, TRUE },
+ { "wstring", "basic_string<wchar_t>", 0, 0, 0, 0, 0, FALSE, TRUE },
+ { "complex", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "bitset", 0, 0, "Bits", 0, 0, 0, FALSE, FALSE },
+ { "deque", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
+ { "list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
+ { "forward_list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, // C++11
+ { "map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE },
+ { "unordered_map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11
+ { "multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE },
+ { "unordered_multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11
+ { "set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE },
+ { "unordered_set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11
+ { "multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE },
+ { "unordered_multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11
+ { "vector", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
+ { "queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
+ { "priority_queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
+ { "stack", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
+ { "valarray", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
+ { "exception", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "bad_alloc", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "bad_cast", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "bad_typeid", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "logic_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "ios_base::failure", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "runtime_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "bad_exception", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "domain_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "invalid_argument", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "length_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "out_of_range", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "range_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "overflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { "underflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
+ { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE }
+};
+
+static void addSTLMember(EntryNav *rootNav,const char *type,const char *name)
+{
+ Entry *memEntry = new Entry;
+ memEntry->name = name;
+ memEntry->type = type;
+ memEntry->protection = Public;
+ memEntry->section = Entry::VARIABLE_SEC;
+ memEntry->brief = "STL member";
+ memEntry->hidden = FALSE;
+ memEntry->artificial = TRUE;
+ //memEntry->parent = root;
+ //root->addSubEntry(memEntry);
+ EntryNav *memEntryNav = new EntryNav(rootNav,memEntry);
+ memEntryNav->setEntry(memEntry);
+ rootNav->addChild(memEntryNav);
+}
+
+static void addSTLIterator(EntryNav *classEntryNav,const char *name)
+{
+ Entry *iteratorClassEntry = new Entry;
+ iteratorClassEntry->fileName = "[STL]";
+ iteratorClassEntry->startLine = 1;
+ iteratorClassEntry->name = name;
+ iteratorClassEntry->section = Entry::CLASS_SEC;
+ iteratorClassEntry->brief = "STL iterator class";
+ iteratorClassEntry->hidden = FALSE;
+ iteratorClassEntry->artificial= TRUE;
+ EntryNav *iteratorClassEntryNav = new EntryNav(classEntryNav,iteratorClassEntry);
+ iteratorClassEntryNav->setEntry(iteratorClassEntry);
+ classEntryNav->addChild(iteratorClassEntryNav);
+}
+
+
+static void addSTLClasses(EntryNav *rootNav)
+{
+ Entry *namespaceEntry = new Entry;
+ namespaceEntry->fileName = "[STL]";
+ namespaceEntry->startLine = 1;
+ //namespaceEntry->parent = rootNav->entry();
+ namespaceEntry->name = "std";
+ namespaceEntry->section = Entry::NAMESPACE_SEC;
+ namespaceEntry->brief = "STL namespace";
+ namespaceEntry->hidden = FALSE;
+ namespaceEntry->artificial= TRUE;
+ //root->addSubEntry(namespaceEntry);
+ EntryNav *namespaceEntryNav = new EntryNav(rootNav,namespaceEntry);
+ namespaceEntryNav->setEntry(namespaceEntry);
+ rootNav->addChild(namespaceEntryNav);
+
+ STLInfo *info = g_stlinfo;
+ while (info->className)
+ {
+ //printf("Adding STL class %s\n",info->className);
+ QCString fullName = info->className;
+ fullName.prepend("std::");
+
+ // add fake Entry for the class
+ Entry *classEntry = new Entry;
+ classEntry->fileName = "[STL]";
+ classEntry->startLine = 1;
+ classEntry->name = fullName;
+ //classEntry->parent = namespaceEntry;
+ classEntry->section = Entry::CLASS_SEC;
+ classEntry->brief = "STL class";
+ classEntry->hidden = FALSE;
+ classEntry->artificial= TRUE;
+ //namespaceEntry->addSubEntry(classEntry);
+ EntryNav *classEntryNav = new EntryNav(namespaceEntryNav,classEntry);
+ classEntryNav->setEntry(classEntry);
+ namespaceEntryNav->addChild(classEntryNav);
+
+ // add template arguments to class
+ if (info->templType1)
+ {
+ ArgumentList *al = new ArgumentList;
+ Argument *a=new Argument;
+ a->type="typename";
+ a->name=info->templType1;
+ al->append(a);
+ if (info->templType2) // another template argument
+ {
+ a=new Argument;
+ a->type="typename";
+ a->name=info->templType2;
+ al->append(a);
+ }
+ classEntry->tArgLists = new QList<ArgumentList>;
+ classEntry->tArgLists->setAutoDelete(TRUE);
+ classEntry->tArgLists->append(al);
+ }
+ // add member variables
+ if (info->templName1)
+ {
+ addSTLMember(classEntryNav,info->templType1,info->templName1);
+ }
+ if (info->templName2)
+ {
+ addSTLMember(classEntryNav,info->templType2,info->templName2);
+ }
+ if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" ||
+ fullName=="std::unique_ptr" || fullName=="std::weak_ptr")
+ {
+ Entry *memEntry = new Entry;
+ memEntry->name = "operator->";
+ memEntry->args = "()";
+ memEntry->type = "T*";
+ memEntry->protection = Public;
+ memEntry->section = Entry::FUNCTION_SEC;
+ memEntry->brief = "STL member";
+ memEntry->hidden = FALSE;
+ memEntry->artificial = FALSE;
+ EntryNav *memEntryNav = new EntryNav(classEntryNav,memEntry);
+ memEntryNav->setEntry(memEntry);
+ classEntryNav->addChild(memEntryNav);
+ }
+ if (info->baseClass1)
+ {
+ classEntry->extends->append(new BaseInfo(info->baseClass1,Public,info->virtualInheritance?Virtual:Normal));
+ }
+ if (info->baseClass2)
+ {
+ classEntry->extends->append(new BaseInfo(info->baseClass2,Public,info->virtualInheritance?Virtual:Normal));
+ }
+ if (info->iterators)
+ {
+ // add iterator class
+ addSTLIterator(classEntryNav,fullName+"::iterator");
+ addSTLIterator(classEntryNav,fullName+"::const_iterator");
+ addSTLIterator(classEntryNav,fullName+"::reverse_iterator");
+ addSTLIterator(classEntryNav,fullName+"::const_reverse_iterator");
+ }
+ info++;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n,
+ FileDef *fileScope,TagInfo *tagInfo);
+
+static void addPageToContext(PageDef *pd,EntryNav *rootNav)
+{
+ if (rootNav->parent()) // add the page to it's scope
+ {
+ QCString scope = rootNav->parent()->name();
+ if (rootNav->parent()->section()==Entry::PACKAGEDOC_SEC)
+ {
+ scope=substitute(scope,".","::");
+ }
+ scope = stripAnonymousNamespaceScope(scope);
+ scope+="::"+pd->name();
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,rootNav->tagInfo());
+ if (d)
+ {
+ pd->setPageScope(d);
+ }
+ }
+}
+
+static void addRelatedPage(EntryNav *rootNav)
+{
+ Entry *root = rootNav->entry();
+ GroupDef *gd=0;
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) break;
+ }
+ //printf("---> addRelatedPage() %s gd=%p\n",root->name.data(),gd);
+ QCString doc;
+ if (root->brief.isEmpty())
+ {
+ doc=root->doc+root->inbodyDocs;
+ }
+ else
+ {
+ doc=root->brief+"\n\n"+root->doc+root->inbodyDocs;
+ }
+ PageDef *pd = addRelatedPage(root->name,root->args,doc,root->anchors,
+ root->docFile,root->docLine,
+ root->sli,
+ gd,rootNav->tagInfo(),
+ root->lang
+ );
+ if (pd)
+ {
+ pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ pd->addSectionsToDefinition(root->anchors);
+ pd->setShowToc(root->stat);
+ addPageToContext(pd,rootNav);
+ }
+}
+
+static void buildGroupListFiltered(EntryNav *rootNav,bool additional, bool includeExternal)
+{
+ if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty() &&
+ ((!includeExternal && rootNav->tagInfo()==0) ||
+ ( includeExternal && rootNav->tagInfo()!=0))
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
+ (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
+ {
+ GroupDef *gd = Doxygen::groupSDict->find(root->name);
+ //printf("Processing group '%s':'%s' add=%d ext=%d gd=%p\n",
+ // root->type.data(),root->name.data(),additional,includeExternal,gd);
+
+ if (gd)
+ {
+ if ( !gd->hasGroupTitle() )
+ {
+ gd->setGroupTitle( root->type );
+ }
+ else if ( root->type.length() > 0 && root->name != root->type && gd->groupTitle() != root->type )
+ {
+ warn( root->fileName,root->startLine,
+ "group %s: ignoring title \"%s\" that does not match old title \"%s\"\n",
+ qPrint(root->name), qPrint(root->type), qPrint(gd->groupTitle()) );
+ }
+ gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ gd->setDocumentation( root->doc, root->docFile, root->docLine );
+ gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
+ gd->addSectionsToDefinition(root->anchors);
+ gd->setRefItems(root->sli);
+ gd->setLanguage(root->lang);
+ }
+ else
+ {
+ if (rootNav->tagInfo())
+ {
+ gd = new GroupDef(root->fileName,root->startLine,root->name,root->type,rootNav->tagInfo()->fileName);
+ gd->setReference(rootNav->tagInfo()->tagName);
+ }
+ else
+ {
+ gd = new GroupDef(root->fileName,root->startLine,root->name,root->type);
+ }
+ gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ // allow empty docs for group
+ gd->setDocumentation(!root->doc.isEmpty() ? root->doc : QCString(" "),root->docFile,root->docLine,FALSE);
+ gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
+ gd->addSectionsToDefinition(root->anchors);
+ Doxygen::groupSDict->append(root->name,gd);
+ gd->setRefItems(root->sli);
+ gd->setLanguage(root->lang);
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ buildGroupListFiltered(e,additional,includeExternal);
+ }
+ }
+}
+
+static void buildGroupList(EntryNav *rootNav)
+{
+ // --- first process only local groups
+ // first process the @defgroups blocks
+ buildGroupListFiltered(rootNav,FALSE,FALSE);
+ // then process the @addtogroup, @weakgroup blocks
+ buildGroupListFiltered(rootNav,TRUE,FALSE);
+
+ // --- then also process external groups
+ // first process the @defgroups blocks
+ buildGroupListFiltered(rootNav,FALSE,TRUE);
+ // then process the @addtogroup, @weakgroup blocks
+ buildGroupListFiltered(rootNav,TRUE,TRUE);
+}
+
+static void findGroupScope(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty() &&
+ rootNav->parent() && !rootNav->parent()->name().isEmpty())
+ {
+ GroupDef *gd;
+ if ((gd=Doxygen::groupSDict->find(rootNav->name())))
+ {
+ QCString scope = rootNav->parent()->name();
+ if (rootNav->parent()->section()==Entry::PACKAGEDOC_SEC)
+ {
+ scope=substitute(scope,".","::");
+ }
+ scope = stripAnonymousNamespaceScope(scope);
+ scope+="::"+gd->name();
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,rootNav->tagInfo());
+ if (d)
+ {
+ gd->setGroupScope(d);
+ }
+ }
+ }
+ RECURSE_ENTRYTREE(findGroupScope,rootNav);
+}
+
+static void organizeSubGroupsFiltered(EntryNav *rootNav,bool additional)
+{
+ if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty())
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
+ (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
+ {
+ GroupDef *gd;
+ if ((gd=Doxygen::groupSDict->find(root->name)))
+ {
+ //printf("adding %s to group %s\n",root->name.data(),gd->name().data());
+ addGroupToGroups(root,gd);
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ organizeSubGroupsFiltered(e,additional);
+ }
+ }
+}
+
+static void organizeSubGroups(EntryNav *rootNav)
+{
+ //printf("Defining groups\n");
+ // first process the @defgroups blocks
+ organizeSubGroupsFiltered(rootNav,FALSE);
+ //printf("Additional groups\n");
+ // then process the @addtogroup, @weakgroup blocks
+ organizeSubGroupsFiltered(rootNav,TRUE);
+}
+
+//----------------------------------------------------------------------
+
+static void buildFileList(EntryNav *rootNav)
+{
+ if (((rootNav->section()==Entry::FILEDOC_SEC) ||
+ ((rootNav->section() & Entry::FILE_MASK) && Config_getBool("EXTRACT_ALL"))) &&
+ !rootNav->name().isEmpty() && !rootNav->tagInfo() // skip any file coming from tag files
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,root->name,ambig);
+ //printf("**************** root->name=%s fd=%p\n",root->name.data(),fd);
+ if (fd && !ambig)
+ {
+#if 0
+ if ((!root->doc.isEmpty() && !fd->documentation().isEmpty()) ||
+ (!root->brief.isEmpty() && !fd->briefDescription().isEmpty()))
+ {
+ warn(
+ root->fileName,root->startLine,
+ "file %s already documented. "
+ "Skipping documentation.",
+ root->name.data()
+ );
+ }
+ else
+#endif
+ {
+ //printf("Adding documentation!\n");
+ // using FALSE in setDocumentation is small hack to make sure a file
+ // is documented even if a \file command is used without further
+ // documentation
+ fd->setDocumentation(root->doc,root->docFile,root->docLine,FALSE);
+ fd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ fd->addSectionsToDefinition(root->anchors);
+ fd->setRefItems(root->sli);
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ {
+ gd->addFile(fd);
+ fd->makePartOfGroup(gd);
+ //printf("File %s: in group %s\n",fd->name().data(),s->data());
+ }
+ }
+ }
+ }
+ else
+ {
+ const char *fn = root->fileName.data();
+ QCString text(4096);
+ text.sprintf("the name `%s' supplied as "
+ "the second argument in the \\file statement ",
+ qPrint(root->name));
+ if (ambig) // name is ambiguous
+ {
+ text+="matches the following input files:\n";
+ text+=showFileDefMatches(Doxygen::inputNameDict,root->name);
+ text+="Please use a more specific name by "
+ "including a (larger) part of the path!";
+ }
+ else // name is not an input file
+ {
+ text+="is not an input file";
+ }
+ warn(fn,root->startLine,text);
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildFileList,rootNav);
+}
+
+static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
+{
+ if (
+ (!root->doc.stripWhiteSpace().isEmpty() ||
+ !root->brief.stripWhiteSpace().isEmpty() ||
+ Config_getBool("EXTRACT_ALL")
+ ) && root->protection!=Private
+ )
+ {
+ //printf(">>>>>> includeFile=%s\n",root->includeFile.data());
+
+ bool local=Config_getBool("FORCE_LOCAL_INCLUDES");
+ QCString includeFile = root->includeFile;
+ if (!includeFile.isEmpty() && includeFile.at(0)=='"')
+ {
+ local = TRUE;
+ includeFile=includeFile.mid(1,includeFile.length()-2);
+ }
+ else if (!includeFile.isEmpty() && includeFile.at(0)=='<')
+ {
+ local = FALSE;
+ includeFile=includeFile.mid(1,includeFile.length()-2);
+ }
+
+ bool ambig;
+ FileDef *fd=0;
+ // see if we need to include a verbatim copy of the header file
+ //printf("root->includeFile=%s\n",root->includeFile.data());
+ if (!includeFile.isEmpty() &&
+ (fd=findFileDef(Doxygen::inputNameDict,includeFile,ambig))==0
+ )
+ { // explicit request
+ QCString text;
+ text.sprintf("the name `%s' supplied as "
+ "the argument of the \\class, \\struct, \\union, or \\include command ",
+ qPrint(includeFile)
+ );
+ if (ambig) // name is ambiguous
+ {
+ text+="matches the following input files:\n";
+ text+=showFileDefMatches(Doxygen::inputNameDict,root->includeFile);
+ text+="Please use a more specific name by "
+ "including a (larger) part of the path!";
+ }
+ else // name is not an input file
+ {
+ text+="is not an input file";
+ }
+ warn(root->fileName,root->startLine,text);
+ }
+ else if (includeFile.isEmpty() && ifd &&
+ // see if the file extension makes sense
+ guessSection(ifd->name())==Entry::HEADER_SEC)
+ { // implicit assumption
+ fd=ifd;
+ }
+
+ // if a file is found, we mark it as a source file.
+ if (fd)
+ {
+ QCString iName = !root->includeName.isEmpty() ?
+ root->includeName : includeFile;
+ if (!iName.isEmpty()) // user specified include file
+ {
+ if (iName.at(0)=='<') local=FALSE; // explicit override
+ else if (iName.at(0)=='"') local=TRUE;
+ if (iName.at(0)=='"' || iName.at(0)=='<')
+ {
+ iName=iName.mid(1,iName.length()-2); // strip quotes or brackets
+ }
+ if (iName.isEmpty())
+ {
+ iName=fd->name();
+ }
+ }
+ else if (!Config_getList("STRIP_FROM_INC_PATH").isEmpty())
+ {
+ iName=stripFromIncludePath(fd->absFilePath());
+ }
+ else // use name of the file containing the class definition
+ {
+ iName=fd->name();
+ }
+ if (fd->generateSourceFile()) // generate code for header
+ {
+ cd->setIncludeFile(fd,iName,local,!root->includeName.isEmpty());
+ }
+ else // put #include in the class documentation without link
+ {
+ cd->setIncludeFile(0,iName,local,TRUE);
+ }
+ }
+ }
+}
+
+#if 0
+static bool addNamespace(Entry *root,ClassDef *cd)
+{
+ // see if this class is defined inside a namespace
+ if (root->section & Entry::COMPOUND_MASK)
+ {
+ Entry *e = root->parent;
+ while (e)
+ {
+ if (e->section==Entry::NAMESPACE_SEC)
+ {
+ NamespaceDef *nd=0;
+ QCString nsName = stripAnonymousNamespaceScope(e->name);
+ //printf("addNameSpace() trying: %s\n",nsName.data());
+ if (!nsName.isEmpty() && nsName.at(0)!='@' &&
+ (nd=getResolvedNamespace(nsName))
+ )
+ {
+ cd->setNamespace(nd);
+ cd->setOuterScope(nd);
+ nd->insertClass(cd);
+ return TRUE;
+ }
+ }
+ e=e->parent;
+ }
+ }
+ return FALSE;
+}
+#endif
+
+#if 0
+static Definition *findScope(Entry *root,int level=0)
+{
+ if (root==0) return 0;
+ //printf("start findScope name=%s\n",root->name.data());
+ Definition *result=0;
+ if (root->section&Entry::SCOPE_MASK)
+ {
+ result = findScope(root->parent,level+1); // traverse to the root of the tree
+ if (result)
+ {
+ //printf("Found %s inside %s at level %d\n",root->name.data(),result->name().data(),level);
+ // TODO: look at template arguments
+ result = result->findInnerCompound(root->name);
+ }
+ else // reached the global scope
+ {
+ // TODO: look at template arguments
+ result = Doxygen::globalScope->findInnerCompound(root->name);
+ //printf("Found in globalScope %s at level %d\n",result->name().data(),level);
+ }
+ }
+ //printf("end findScope(%s,%d)=%s\n",root->name.data(),
+ // level,result==0 ? "<none>" : result->name().data());
+ return result;
+}
+#endif
+
+/*! returns the Definition object belonging to the first \a level levels of
+ * full qualified name \a name. Creates an artificial scope if the scope is
+ * not found and set the parent/child scope relation if the scope is found.
+ */
+static Definition *buildScopeFromQualifiedName(const QCString name,
+ int level,SrcLangExt lang,TagInfo *tagInfo)
+{
+ //printf("buildScopeFromQualifiedName(%s) level=%d\n",name.data(),level);
+ int i=0;
+ int p=0,l;
+ Definition *prevScope=Doxygen::globalScope;
+ QCString fullScope;
+ while (i<level)
+ {
+ int idx=getScopeFragment(name,p,&l);
+ QCString nsName = name.mid(idx,l);
+ if (nsName.isEmpty()) return prevScope;
+ if (!fullScope.isEmpty()) fullScope+="::";
+ fullScope+=nsName;
+ NamespaceDef *nd=Doxygen::namespaceSDict->find(fullScope);
+ Definition *innerScope = nd;
+ ClassDef *cd=0;
+ if (nd==0) cd = getClass(fullScope);
+ if (nd==0 && cd) // scope is a class
+ {
+ innerScope = cd;
+ }
+ else if (nd==0 && cd==0 && fullScope.find('<')==-1) // scope is not known and could be a namespace!
+ {
+ // introduce bogus namespace
+ //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",nsName.data(),prevScope->name().data(),tagInfo);
+ nd=new NamespaceDef(
+ "[generated]",1,1,fullScope,
+ tagInfo?tagInfo->tagName:QCString(),
+ tagInfo?tagInfo->fileName:QCString());
+ nd->setLanguage(lang);
+
+ // add namespace to the list
+ Doxygen::namespaceSDict->inSort(fullScope,nd);
+ innerScope = nd;
+ }
+ else // scope is a namespace
+ {
+ }
+ // make the parent/child scope relation
+ prevScope->addInnerCompound(innerScope);
+ innerScope->setOuterScope(prevScope);
+ // proceed to the next scope fragment
+ p=idx+l+2;
+ prevScope=innerScope;
+ i++;
+ }
+ return prevScope;
+}
+
+static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n,
+ FileDef *fileScope,TagInfo *tagInfo)
+{
+ //printf("<findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data());
+ Definition *resultScope=startScope;
+ if (resultScope==0) resultScope=Doxygen::globalScope;
+ QCString scope=stripTemplateSpecifiersFromScope(n,FALSE);
+ int l1=0,i1;
+ i1=getScopeFragment(scope,0,&l1);
+ if (i1==-1)
+ {
+ //printf(">no fragments!\n");
+ return resultScope;
+ }
+ int p=i1+l1,l2=0,i2;
+ while ((i2=getScopeFragment(scope,p,&l2))!=-1)
+ {
+ QCString nestedNameSpecifier = scope.mid(i1,l1);
+ Definition *orgScope = resultScope;
+ //printf(" nestedNameSpecifier=%s\n",nestedNameSpecifier.data());
+ resultScope = resultScope->findInnerCompound(nestedNameSpecifier);
+ //printf(" resultScope=%p\n",resultScope);
+ if (resultScope==0)
+ {
+ NamespaceSDict *usedNamespaces;
+ if (orgScope==Doxygen::globalScope && fileScope &&
+ (usedNamespaces = fileScope->getUsedNamespaces()))
+ // also search for used namespaces
+ {
+ NamespaceSDict::Iterator ni(*usedNamespaces);
+ NamespaceDef *nd;
+ for (ni.toFirst();((nd=ni.current()) && resultScope==0);++ni)
+ {
+ // restart search within the used namespace
+ resultScope = findScopeFromQualifiedName(nd,n,fileScope,tagInfo);
+ }
+ if (resultScope)
+ {
+ // for a nested class A::I in used namespace N, we get
+ // N::A::I while looking for A, so we should compare
+ // resultScope->name() against scope.left(i2+l2)
+ //printf(" -> result=%s scope=%s\n",resultScope->name().data(),scope.data());
+ if (rightScopeMatch(resultScope->name(),scope.left(i2+l2)))
+ {
+ break;
+ }
+ goto nextFragment;
+ }
+ }
+
+ // also search for used classes. Complication: we haven't been able
+ // to put them in the right scope yet, because we are still resolving
+ // the scope relations!
+ // Therefore loop through all used classes and see if there is a right
+ // scope match between the used class and nestedNameSpecifier.
+ QDictIterator<FileDef> ui(g_usingDeclarations);
+ FileDef *usedFd;
+ for (ui.toFirst();(usedFd=ui.current());++ui)
+ {
+ //printf("Checking using class %s\n",ui.currentKey());
+ if (rightScopeMatch(ui.currentKey(),nestedNameSpecifier))
+ {
+ // ui.currentKey() is the fully qualified name of nestedNameSpecifier
+ // so use this instead.
+ QCString fqn = QCString(ui.currentKey())+
+ scope.right(scope.length()-p);
+ resultScope = buildScopeFromQualifiedName(fqn,fqn.contains("::"),
+ startScope->getLanguage(),0);
+ //printf("Creating scope from fqn=%s result %p\n",fqn.data(),resultScope);
+ if (resultScope)
+ {
+ //printf("> Match! resultScope=%s\n",resultScope->name().data());
+ return resultScope;
+ }
+ }
+ }
+
+ //printf("> name %s not found in scope %s\n",nestedNameSpecifier.data(),orgScope->name().data());
+ return 0;
+ }
+ nextFragment:
+ i1=i2;
+ l1=l2;
+ p=i2+l2;
+ }
+ //printf(">findScopeFromQualifiedName scope %s\n",resultScope->name().data());
+ return resultScope;
+}
+
+ArgumentList *getTemplateArgumentsFromName(
+ const QCString &name,
+ const QList<ArgumentList> *tArgLists)
+{
+ if (tArgLists==0) return 0;
+
+ QListIterator<ArgumentList> ali(*tArgLists);
+ // for each scope fragment, check if it is a template and advance through
+ // the list if so.
+ int i,p=0;
+ while ((i=name.find("::",p))!=-1)
+ {
+ NamespaceDef *nd = Doxygen::namespaceSDict->find(name.left(i));
+ if (nd==0)
+ {
+ ClassDef *cd = getClass(name.left(i));
+ if (cd)
+ {
+ if (cd->templateArguments())
+ {
+ ++ali;
+ }
+ }
+ }
+ p=i+2;
+ }
+ return ali.current();
+}
+
+static
+ClassDef::CompoundType convertToCompoundType(int section,uint64 specifier)
+{
+ ClassDef::CompoundType sec=ClassDef::Class;
+ if (specifier&Entry::Struct)
+ sec=ClassDef::Struct;
+ else if (specifier&Entry::Union)
+ sec=ClassDef::Union;
+ else if (specifier&Entry::Category)
+ sec=ClassDef::Category;
+ else if (specifier&Entry::Interface)
+ sec=ClassDef::Interface;
+ else if (specifier&Entry::Protocol)
+ sec=ClassDef::Protocol;
+ else if (specifier&Entry::Exception)
+ sec=ClassDef::Exception;
+ else if (specifier&Entry::Service)
+ sec=ClassDef::Service;
+ else if (specifier&Entry::Singleton)
+ sec=ClassDef::Singleton;
+
+ switch(section)
+ {
+ //case Entry::UNION_SEC:
+ case Entry::UNIONDOC_SEC:
+ sec=ClassDef::Union;
+ break;
+ //case Entry::STRUCT_SEC:
+ case Entry::STRUCTDOC_SEC:
+ sec=ClassDef::Struct;
+ break;
+ //case Entry::INTERFACE_SEC:
+ case Entry::INTERFACEDOC_SEC:
+ sec=ClassDef::Interface;
+ break;
+ //case Entry::PROTOCOL_SEC:
+ case Entry::PROTOCOLDOC_SEC:
+ sec=ClassDef::Protocol;
+ break;
+ //case Entry::CATEGORY_SEC:
+ case Entry::CATEGORYDOC_SEC:
+ sec=ClassDef::Category;
+ break;
+ //case Entry::EXCEPTION_SEC:
+ case Entry::EXCEPTIONDOC_SEC:
+ sec=ClassDef::Exception;
+ break;
+ case Entry::SERVICEDOC_SEC:
+ sec=ClassDef::Service;
+ break;
+ case Entry::SINGLETONDOC_SEC:
+ sec=ClassDef::Singleton;
+ break;
+ }
+ return sec;
+}
+
+
+static void addClassToContext(EntryNav *rootNav)
+{
+ //printf("Loading entry for rootNav=%p name=%s\n",rootNav,rootNav->name().data());
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //NamespaceDef *nd = 0;
+ FileDef *fd = rootNav->fileDef();
+
+ QCString scName;
+ if (rootNav->parent()->section()&Entry::SCOPE_MASK)
+ {
+ scName=rootNav->parent()->name();
+ }
+ // name without parent's scope
+ QCString fullName = root->name;
+
+ // strip off any template parameters (but not those for specializations)
+ fullName=stripTemplateSpecifiersFromScope(fullName);
+
+ // name with scope (if not present already)
+ QCString qualifiedName = fullName;
+ if (!scName.isEmpty() && !leftScopeMatch(fullName,scName))
+ {
+ qualifiedName.prepend(scName+"::");
+ }
+
+ // see if we already found the class before
+ ClassDef *cd = getClass(qualifiedName);
+
+ Debug::print(Debug::Classes,0, " Found class with name %s (qualifiedName=%s -> cd=%p)\n",
+ cd ? cd->name().data() : root->name.data(), qualifiedName.data(),cd);
+
+ if (cd)
+ {
+ fullName=cd->name();
+ Debug::print(Debug::Classes,0," Existing class %s!\n",cd->name().data());
+ //if (cd->templateArguments()==0)
+ //{
+ // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
+ // cd->setTemplateArguments(tArgList);
+ //}
+
+ cd->setDocumentation(root->doc,root->docFile,root->docLine);
+ cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+
+ if (root->bodyLine!=-1 && cd->getStartBodyLine()==-1)
+ {
+ cd->setBodySegment(root->bodyLine,root->endBodyLine);
+ cd->setBodyDef(fd);
+ }
+ //cd->setName(fullName); // change name to match docs
+
+ if (cd->templateArguments()==0 || (cd->isForwardDeclared() && (root->spec&Entry::ForwardDecl)==0))
+ {
+ // this happens if a template class declared with @class is found
+ // before the actual definition or if a forward declaration has different template
+ // parameter names.
+ ArgumentList *tArgList =
+ getTemplateArgumentsFromName(cd->name(),root->tArgLists);
+ cd->setTemplateArguments(tArgList);
+ }
+
+ cd->setCompoundType(convertToCompoundType(root->section,root->spec));
+ }
+ else // new class
+ {
+ ClassDef::CompoundType sec = convertToCompoundType(root->section,root->spec);
+
+ QCString className;
+ QCString namespaceName;
+ extractNamespaceName(fullName,className,namespaceName);
+
+ //printf("New class: fullname %s namespace `%s' name=`%s' brief=`%s' docs=`%s'\n",
+ // fullName.data(),namespaceName.data(),className.data(),root->brief.data(),root->doc.data());
+
+ QCString tagName;
+ QCString refFileName;
+ TagInfo *tagInfo = rootNav->tagInfo();
+ if (tagInfo)
+ {
+ tagName = tagInfo->tagName;
+ refFileName = tagInfo->fileName;
+ int i;
+ if ((i=fullName.find("::"))!=-1)
+ // symbols imported via tag files may come without the parent scope,
+ // so we artificially create it here
+ {
+ buildScopeFromQualifiedName(fullName,fullName.contains("::"),root->lang,tagInfo);
+ }
+ }
+ cd=new ClassDef(root->fileName,root->startLine,root->startColumn,
+ fullName,sec,tagName,refFileName,TRUE,root->spec&Entry::Enum);
+ Debug::print(Debug::Classes,0," New class `%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p\n",
+ fullName.data(),sec,root->tArgLists ? (int)root->tArgLists->count() : -1, tagInfo);
+ cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+ cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ cd->setLanguage(root->lang);
+ cd->setId(root->id);
+ cd->setHidden(root->hidden);
+ cd->setArtificial(root->artificial);
+ cd->setClassSpecifier(root->spec);
+ cd->setTypeConstraints(root->typeConstr);
+ //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
+
+ ArgumentList *tArgList =
+ getTemplateArgumentsFromName(fullName,root->tArgLists);
+ //printf("class %s template args=%s\n",fullName.data(),
+ // tArgList ? tempArgListToString(tArgList).data() : "<none>");
+ cd->setTemplateArguments(tArgList);
+ cd->setProtection(root->protection);
+ cd->setIsStatic(root->stat);
+
+ // file definition containing the class cd
+ cd->setBodySegment(root->bodyLine,root->endBodyLine);
+ cd->setBodyDef(fd);
+
+ // see if the class is found inside a namespace
+ //bool found=addNamespace(root,cd);
+
+ cd->insertUsedFile(fd);
+
+ // add class to the list
+ //printf("ClassDict.insert(%s)\n",fullName.data());
+ Doxygen::classSDict->append(fullName,cd);
+
+ if (cd->isGeneric()) // generics are also stored in a separate dictionary for fast lookup of instantions
+ {
+ //printf("inserting generic '%s' cd=%p\n",fullName.data(),cd);
+ Doxygen::genericsDict->insert(fullName,cd);
+ }
+ }
+
+ cd->addSectionsToDefinition(root->anchors);
+ if (!root->subGrouping) cd->setSubGrouping(FALSE);
+ if (cd->hasDocumentation())
+ {
+ addIncludeFile(cd,fd,root);
+ }
+ if (fd && (root->section & Entry::COMPOUND_MASK))
+ {
+ //printf(">> Inserting class `%s' in file `%s' (root->fileName=`%s')\n",
+ // cd->name().data(),
+ // fd->name().data(),
+ // root->fileName.data()
+ // );
+ cd->setFileDef(fd);
+ fd->insertClass(cd);
+ }
+ addClassToGroups(root,cd);
+ cd->setRefItems(root->sli);
+
+ rootNav->releaseEntry();
+}
+
+//----------------------------------------------------------------------
+// build a list of all classes mentioned in the documentation
+// and all classes that have a documentation block before their definition.
+static void buildClassList(EntryNav *rootNav)
+{
+ if (
+ ((rootNav->section() & Entry::COMPOUND_MASK) ||
+ rootNav->section()==Entry::OBJCIMPL_SEC) && !rootNav->name().isEmpty()
+ )
+ {
+ addClassToContext(rootNav);
+ }
+ RECURSE_ENTRYTREE(buildClassList,rootNav);
+}
+
+static void buildClassDocList(EntryNav *rootNav)
+{
+ if (
+ (rootNav->section() & Entry::COMPOUNDDOC_MASK) && !rootNav->name().isEmpty()
+ )
+ {
+ addClassToContext(rootNav);
+ }
+ RECURSE_ENTRYTREE(buildClassDocList,rootNav);
+}
+
+static void resolveClassNestingRelations()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+
+ bool done=FALSE;
+ int iteration=0;
+ while (!done)
+ {
+ done=TRUE;
+ ++iteration;
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (!cd->visited)
+ {
+ QCString name = stripAnonymousNamespaceScope(cd->name());
+ //printf("processing=%s, iteration=%d\n",cd->name().data(),iteration);
+ // also add class to the correct structural context
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,
+ name,cd->getFileDef(),0);
+ if (d)
+ {
+ //printf("****** adding %s to scope %s in iteration %d\n",cd->name().data(),d->name().data(),iteration);
+ d->addInnerCompound(cd);
+ cd->setOuterScope(d);
+ cd->visited=TRUE;
+ done=FALSE;
+ }
+ //else
+ //{
+ // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",cd->name().data(),iteration);
+ //}
+ }
+ }
+ }
+
+ //give warnings for unresolved compounds
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (!cd->visited)
+ {
+ QCString name = stripAnonymousNamespaceScope(cd->name());
+ //printf("processing unresolved=%s, iteration=%d\n",cd->name().data(),iteration);
+ /// create the scope artificially
+ // anyway, so we can at least relate scopes properly.
+ Definition *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0);
+ if (d!=cd && !cd->getDefFileName().isEmpty())
+ // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
+ // for this case doxygen assumes the exitance of a namespace N::N in which C is to be found!
+ // also avoid warning for stuff imported via a tagfile.
+ {
+ d->addInnerCompound(cd);
+ cd->setOuterScope(d);
+ warn(cd->getDefFileName(),cd->getDefLine(),
+ "Internal inconsistency: scope for class %s not "
+ "found!",name.data()
+ );
+ }
+ }
+ }
+}
+
+void distributeClassGroupRelations()
+{
+ //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ //if (!inlineGroupedClasses) return;
+ //printf("** distributeClassGroupRelations()\n");
+
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ //printf("Checking %s\n",cd->name().data());
+ // distribute the group to nested classes as well
+ if (!cd->visited && cd->partOfGroups()!=0 && cd->getClassSDict())
+ {
+ //printf(" Candidate for merging\n");
+ ClassSDict::Iterator ncli(*cd->getClassSDict());
+ ClassDef *ncd;
+ GroupDef *gd = cd->partOfGroups()->at(0);
+ for (ncli.toFirst();(ncd=ncli.current());++ncli)
+ {
+ if (ncd->partOfGroups()==0)
+ {
+ //printf(" Adding %s to group '%s'\n",ncd->name().data(),
+ // gd->groupTitle());
+ ncd->makePartOfGroup(gd);
+ gd->addClass(ncd);
+ }
+ }
+ cd->visited=TRUE; // only visit every class once
+ }
+ }
+}
+
+//----------------------------
+
+static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QCString &fieldName)
+{
+ QCString fullName = removeAnonymousScopes(templ->name());
+ if (fullName.right(2)=="::") fullName=fullName.left(fullName.length()-2);
+ fullName+="."+fieldName;
+ ClassDef *cd = new ClassDef(templ->getDefFileName(),
+ templ->getDefLine(),
+ templ->getDefColumn(),
+ fullName,
+ templ->compoundType());
+ cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
+ cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
+ cd->setLanguage(templ->getLanguage());
+ cd->setBodySegment(templ->getStartBodyLine(),templ->getEndBodyLine());
+ cd->setBodyDef(templ->getBodyDef());
+
+ cd->setOuterScope(rootCd->getOuterScope());
+ if (rootCd->getOuterScope()!=Doxygen::globalScope)
+ {
+ rootCd->getOuterScope()->addInnerCompound(cd);
+ }
+
+ FileDef *fd = templ->getFileDef();
+ if (fd)
+ {
+ cd->setFileDef(fd);
+ fd->insertClass(cd);
+ }
+ GroupList *groups = rootCd->partOfGroups();
+ if ( groups!=0 )
+ {
+ GroupListIterator gli(*groups);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ cd->makePartOfGroup(gd);
+ gd->addClass(cd);
+ }
+ }
+ //printf("** adding class %s based on %s\n",fullName.data(),templ->name().data());
+ Doxygen::classSDict->append(fullName,cd);
+
+ MemberList *ml = templ->getMemberList(MemberListType_pubAttribs);
+ if (ml)
+ {
+ MemberListIterator li(*ml);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ //printf(" Member %s type=%s\n",md->name().data(),md->typeString());
+ MemberDef *imd = new MemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
+ md->typeString(),md->name(),md->argsString(),md->excpString(),
+ md->protection(),md->virtualness(),md->isStatic(),Member,
+ md->memberType(),
+ 0,0);
+ imd->setMemberClass(cd);
+ imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+ imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+ imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+ imd->setMemberSpecifiers(md->getMemberSpecifiers());
+ imd->setMemberGroupId(md->getMemberGroupId());
+ imd->setInitializer(md->initializer());
+ imd->setMaxInitLines(md->initializerLines());
+ imd->setBitfields(md->bitfieldString());
+ imd->setLanguage(md->getLanguage());
+ cd->insertMember(imd);
+ }
+ }
+ return cd;
+}
+
+/** Look through the members of class \a cd and its public members.
+ * If there is a member m of a tag less struct/union,
+ * then we create a duplicate of the struct/union with the name of the
+ * member to identify it.
+ * So if cd has name S, then the tag less struct/union will get name S.m
+ * Since tag less structs can be nested we need to call this function
+ * recursively. Later on we need to patch the member types so we keep
+ * track of the hierarchy of classes we create.
+ */
+static void processTagLessClasses(ClassDef *rootCd,
+ ClassDef *cd,
+ ClassDef *tagParentCd,
+ const QCString &prefix,int count)
+{
+ //printf("%d: processTagLessClasses %s\n",count,cd->name().data());
+ //printf("checking members for %s\n",cd->name().data());
+ if (cd->getClassSDict())
+ {
+ MemberList *ml = cd->getMemberList(MemberListType_pubAttribs);
+ if (ml)
+ {
+ MemberListIterator li(*ml);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ QCString type = md->typeString();
+ if (type.find("::@")!=-1) // member of tag less struct/union
+ {
+ ClassSDict::Iterator it(*cd->getClassSDict());
+ ClassDef *icd;
+ for (it.toFirst();(icd=it.current());++it)
+ {
+ //printf(" member %s: type='%s'\n",md->name().data(),type.data());
+ //printf(" comparing '%s'<->'%s'\n",type.data(),icd->name().data());
+ if (type.find(icd->name())!=-1) // matching tag less struct/union
+ {
+ QCString name = md->name();
+ if (name.at(0)=='@') name = "__unnamed__";
+ if (!prefix.isEmpty()) name.prepend(prefix+".");
+ //printf(" found %s for class %s\n",name.data(),cd->name().data());
+ ClassDef *ncd = createTagLessInstance(rootCd,icd,name);
+ processTagLessClasses(rootCd,icd,ncd,name,count+1);
+ //printf(" addTagged %s to %s\n",ncd->name().data(),tagParentCd->name().data());
+ tagParentCd->addTaggedInnerClass(ncd);
+ ncd->setTagLessReference(icd);
+
+ // replace tag-less type for generated/original member
+ // by newly created class name.
+ // note the difference between changing cd and tagParentCd.
+ // for the initial call this is the same pointer, but for
+ // recursive calls cd is the original tag-less struct (of which
+ // there is only one instance) and tagParentCd is the newly
+ // generated tagged struct of which there can be multiple instances!
+ MemberList *pml = tagParentCd->getMemberList(MemberListType_pubAttribs);
+ if (pml)
+ {
+ MemberListIterator pli(*pml);
+ MemberDef *pmd;
+ for (pli.toFirst();(pmd=pli.current());++pli)
+ {
+ if (pmd->name()==md->name())
+ {
+ pmd->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
+ //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void writeMainPageTagFileData()
+{
+ if (Doxygen::mainPage && !Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"page\">" << endl
+ << " <name>"
+ << convertToXML(Doxygen::mainPage->name())
+ << "</name>" << endl
+ << " <title>"
+ << convertToXML(Doxygen::mainPage->title())
+ << "</title>" << endl
+ << " <filename>"
+ << convertToXML(Doxygen::mainPage->getOutputFileBase())
+ << "</filename>" << endl;
+
+ Doxygen::mainPage->writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+}
+
+static void findTagLessClasses(ClassDef *cd)
+{
+ if (cd->getClassSDict())
+ {
+ ClassSDict::Iterator it(*cd->getClassSDict());
+ ClassDef *icd;
+ for (it.toFirst();(icd=it.current());++it)
+ {
+ if (icd->name().find("@")==-1) // process all non-anonymous inner classes
+ {
+ findTagLessClasses(icd);
+ }
+ }
+ }
+
+ processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes (if any)
+}
+
+static void findTagLessClasses()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli) // for each class
+ {
+ Definition *scope = cd->getOuterScope();
+ if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
+ {
+ findTagLessClasses(cd);
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------
+// build a list of all namespaces mentioned in the documentation
+// and all namespaces that have a documentation block before their definition.
+static void buildNamespaceList(EntryNav *rootNav)
+{
+ if (
+ (rootNav->section()==Entry::NAMESPACE_SEC ||
+ rootNav->section()==Entry::NAMESPACEDOC_SEC ||
+ rootNav->section()==Entry::PACKAGEDOC_SEC
+ ) &&
+ !rootNav->name().isEmpty()
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("** buildNamespaceList(%s)\n",root->name.data());
+
+ QCString fName = root->name;
+ if (root->section==Entry::PACKAGEDOC_SEC)
+ {
+ fName=substitute(fName,".","::");
+ }
+
+ QCString fullName = stripAnonymousNamespaceScope(fName);
+ if (!fullName.isEmpty())
+ {
+ //printf("Found namespace %s in %s at line %d\n",root->name.data(),
+ // root->fileName.data(), root->startLine);
+ NamespaceDef *nd;
+ if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace
+ {
+ nd->setDocumentation(root->doc,root->docFile,root->docLine);
+ nd->setName(fullName); // change name to match docs
+ nd->addSectionsToDefinition(root->anchors);
+ nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ if (nd->getLanguage()==SrcLangExt_Unknown)
+ {
+ nd->setLanguage(root->lang);
+ }
+
+ // file definition containing the namespace nd
+ FileDef *fd=rootNav->fileDef();
+ // insert the namespace in the file definition
+ if (fd) fd->insertNamespace(nd);
+ addNamespaceToGroups(root,nd);
+ nd->setRefItems(root->sli);
+ }
+ else // fresh namespace
+ {
+ QCString tagName;
+ QCString tagFileName;
+ TagInfo *tagInfo = rootNav->tagInfo();
+ if (tagInfo)
+ {
+ tagName = tagInfo->tagName;
+ tagFileName = tagInfo->fileName;
+ }
+ //printf("++ new namespace %s lang=%s tagName=%s\n",fullName.data(),langToString(root->lang).data(),tagName.data());
+ NamespaceDef *nd=new NamespaceDef(root->fileName,root->startLine,
+ root->startColumn,fullName,tagName,tagFileName,
+ root->type,root->spec&Entry::Published);
+ nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+ nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ nd->addSectionsToDefinition(root->anchors);
+ nd->setHidden(root->hidden);
+ nd->setArtificial(root->artificial);
+ nd->setLanguage(root->lang);
+ nd->setId(root->id);
+
+ //printf("Adding namespace to group\n");
+ addNamespaceToGroups(root,nd);
+ nd->setRefItems(root->sli);
+
+ // file definition containing the namespace nd
+ FileDef *fd=rootNav->fileDef();
+ // insert the namespace in the file definition
+ if (fd) fd->insertNamespace(nd);
+
+ // the empty string test is needed for extract all case
+ nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ nd->insertUsedFile(fd);
+ nd->setBodySegment(root->bodyLine,root->endBodyLine);
+ nd->setBodyDef(fd);
+ // add class to the list
+ Doxygen::namespaceSDict->inSort(fullName,nd);
+
+ // also add namespace to the correct structural context
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo);
+ //printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"<none>");
+ if (d==0) // we didn't find anything, create the scope artificially
+ // anyway, so we can at least relate scopes properly.
+ {
+ Definition *d = buildScopeFromQualifiedName(fullName,fullName.contains("::"),nd->getLanguage(),tagInfo);
+ d->addInnerCompound(nd);
+ nd->setOuterScope(d);
+ // TODO: Due to the order in which the tag file is written
+ // a nested class can be found before its parent!
+ }
+ else
+ {
+ d->addInnerCompound(nd);
+ nd->setOuterScope(d);
+ }
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildNamespaceList,rootNav);
+}
+
+//----------------------------------------------------------------------
+
+static NamespaceDef *findUsedNamespace(NamespaceSDict *unl,
+ const QCString &name)
+{
+ NamespaceDef *usingNd =0;
+ if (unl)
+ {
+ //printf("Found namespace dict %d\n",unl->count());
+ NamespaceSDict::Iterator unli(*unl);
+ NamespaceDef *und;
+ for (unli.toFirst();(und=unli.current());++unli)
+ {
+ QCString uScope=und->name()+"::";
+ usingNd = getResolvedNamespace(uScope+name);
+ //printf("Also trying with scope=`%s' usingNd=%p\n",(uScope+name).data(),usingNd);
+ }
+ }
+ return usingNd;
+}
+
+static void findUsingDirectives(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::USINGDIR_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("Found using directive %s at line %d of %s\n",
+ // root->name.data(),root->startLine,root->fileName.data());
+ QCString name=substitute(root->name,".","::");
+ if (name.right(2)=="::")
+ {
+ name=name.left(name.length()-2);
+ }
+ if (!name.isEmpty())
+ {
+ NamespaceDef *usingNd = 0;
+ NamespaceDef *nd = 0;
+ FileDef *fd = rootNav->fileDef();
+ QCString nsName;
+
+ // see if the using statement was found inside a namespace or inside
+ // the global file scope.
+ if (rootNav->parent() && rootNav->parent()->section()==Entry::NAMESPACE_SEC &&
+ (fd==0 || fd->getLanguage()!=SrcLangExt_Java) // not a .java file
+ )
+ {
+ nsName=stripAnonymousNamespaceScope(rootNav->parent()->name());
+ if (!nsName.isEmpty())
+ {
+ nd = getResolvedNamespace(nsName);
+ }
+ }
+
+ // find the scope in which the `using' namespace is defined by prepending
+ // the possible scopes in which the using statement was found, starting
+ // with the most inner scope and going to the most outer scope (i.e.
+ // file scope).
+ int scopeOffset = nsName.length();
+ do
+ {
+ QCString scope=scopeOffset>0 ?
+ nsName.left(scopeOffset)+"::" : QCString();
+ usingNd = getResolvedNamespace(scope+name);
+ //printf("Trying with scope=`%s' usingNd=%p\n",(scope+name).data(),usingNd);
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else if ((scopeOffset=nsName.findRev("::",scopeOffset-1))==-1)
+ {
+ scopeOffset=0;
+ }
+ } while (scopeOffset>=0 && usingNd==0);
+
+ if (usingNd==0 && nd) // not found, try used namespaces in this scope
+ // or in one of the parent namespace scopes
+ {
+ NamespaceDef *pnd = nd;
+ while (pnd && usingNd==0)
+ {
+ // also try with one of the used namespaces found earlier
+ usingNd = findUsedNamespace(pnd->getUsedNamespaces(),name);
+
+ // goto the parent
+ Definition *s = pnd->getOuterScope();
+ if (s && s->definitionType()==Definition::TypeNamespace)
+ {
+ pnd = (NamespaceDef*)s;
+ }
+ else
+ {
+ pnd = 0;
+ }
+ }
+ }
+ if (usingNd==0 && fd) // still nothing, also try used namespace in the
+ // global scope
+ {
+ usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
+ }
+
+ //printf("%s -> %s\n",name.data(),usingNd?usingNd->name().data():"<none>");
+
+ // add the namespace the correct scope
+ if (usingNd)
+ {
+ //printf("using fd=%p nd=%p\n",fd,nd);
+ if (nd)
+ {
+ //printf("Inside namespace %s\n",nd->name().data());
+ nd->addUsingDirective(usingNd);
+ }
+ else if (fd)
+ {
+ //printf("Inside file %s\n",fd->name().data());
+ fd->addUsingDirective(usingNd);
+ }
+ }
+ else // unknown namespace, but add it anyway.
+ {
+ //printf("++ new unknown namespace %s lang=%s\n",name.data(),langToString(root->lang).data());
+ NamespaceDef *nd=new NamespaceDef(root->fileName,root->startLine,root->startColumn,name);
+ nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+ nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ nd->addSectionsToDefinition(root->anchors);
+ //printf("** Adding namespace %s hidden=%d\n",name.data(),root->hidden);
+ nd->setHidden(root->hidden);
+ nd->setArtificial(TRUE);
+ nd->setLanguage(root->lang);
+ nd->setId(root->id);
+
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ gd->addNamespace(nd);
+ }
+
+ // insert the namespace in the file definition
+ if (fd)
+ {
+ fd->insertNamespace(nd);
+ fd->addUsingDirective(nd);
+ }
+
+ // the empty string test is needed for extract all case
+ nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ nd->insertUsedFile(fd);
+ // add class to the list
+ Doxygen::namespaceSDict->inSort(name,nd);
+ nd->setRefItems(root->sli);
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findUsingDirectives,rootNav);
+}
+
+//----------------------------------------------------------------------
+
+static void buildListOfUsingDecls(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::USINGDECL_SEC &&
+ !(rootNav->parent()->section()&Entry::COMPOUND_MASK) // not a class/struct member
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ QCString name = substitute(root->name,".","::");
+
+ if (g_usingDeclarations.find(name)==0)
+ {
+ FileDef *fd = rootNav->fileDef();
+ if (fd)
+ {
+ g_usingDeclarations.insert(name,fd);
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildListOfUsingDecls,rootNav);
+}
+
+
+static void findUsingDeclarations(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::USINGDECL_SEC &&
+ !(rootNav->parent()->section()&Entry::COMPOUND_MASK) // not a class/struct member
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("Found using declaration %s at line %d of %s inside section %x\n",
+ // root->name.data(),root->startLine,root->fileName.data(),
+ // rootNav->parent()->section());
+ if (!root->name.isEmpty())
+ {
+ ClassDef *usingCd = 0;
+ NamespaceDef *nd = 0;
+ FileDef *fd = rootNav->fileDef();
+ QCString scName;
+
+ // see if the using statement was found inside a namespace or inside
+ // the global file scope.
+ if (rootNav->parent()->section() == Entry::NAMESPACE_SEC)
+ {
+ scName=rootNav->parent()->name();
+ if (!scName.isEmpty())
+ {
+ nd = getResolvedNamespace(scName);
+ }
+ }
+
+ // Assume the using statement was used to import a class.
+ // Find the scope in which the `using' namespace is defined by prepending
+ // the possible scopes in which the using statement was found, starting
+ // with the most inner scope and going to the most outer scope (i.e.
+ // file scope).
+
+ QCString name = substitute(root->name,".","::"); //Java/C# scope->internal
+ usingCd = getClass(name);
+ if (usingCd==0)
+ {
+ usingCd = Doxygen::hiddenClasses->find(name);
+ }
+
+ //printf("%s -> %p\n",root->name.data(),usingCd);
+ if (usingCd==0) // definition not in the input => add an artificial class
+ {
+ Debug::print(Debug::Classes,0," New using class `%s' (sec=0x%08x)! #tArgLists=%d\n",
+ name.data(),root->section,root->tArgLists ? (int)root->tArgLists->count() : -1);
+ usingCd = new ClassDef(
+ "<using>",1,1,
+ name,
+ ClassDef::Class);
+ Doxygen::hiddenClasses->append(root->name,usingCd);
+ usingCd->setArtificial(TRUE);
+ usingCd->setLanguage(root->lang);
+ }
+ else
+ {
+ Debug::print(Debug::Classes,0," Found used class %s in scope=%s\n",
+ usingCd->name().data(),nd?nd->name().data():fd->name().data());
+ }
+
+ if (usingCd) // add the class to the correct scope
+ {
+ if (nd)
+ {
+ //printf("Inside namespace %s\n",nd->name().data());
+ nd->addUsingDeclaration(usingCd);
+ }
+ else if (fd)
+ {
+ //printf("Inside file %s\n",fd->name().data());
+ fd->addUsingDeclaration(usingCd);
+ }
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findUsingDeclarations,rootNav);
+}
+
+//----------------------------------------------------------------------
+
+static void findUsingDeclImports(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::USINGDECL_SEC &&
+ (rootNav->parent()->section()&Entry::COMPOUND_MASK) // in a class/struct member
+ )
+ {
+ //printf("Found using declaration %s at line %d of %s inside section %x\n",
+ // root->name.data(),root->startLine,root->fileName.data(),
+ // root->parent->section);
+ QCString fullName=removeRedundantWhiteSpace(rootNav->parent()->name());
+ fullName=stripAnonymousNamespaceScope(fullName);
+ fullName=stripTemplateSpecifiersFromScope(fullName);
+ ClassDef *cd = getClass(fullName);
+ if (cd)
+ {
+ //printf("found class %s\n",cd->name().data());
+ int i=rootNav->name().find("::");
+ if (i!=-1)
+ {
+ QCString scope=rootNav->name().left(i);
+ QCString memName=rootNav->name().right(rootNav->name().length()-i-2);
+ ClassDef *bcd = getResolvedClass(cd,0,scope); // todo: file in fileScope parameter
+ if (bcd)
+ {
+ //printf("found class %s\n",bcd->name().data());
+ MemberNameInfoSDict *mndict=bcd->memberNameInfoSDict();
+ if (mndict)
+ {
+ MemberNameInfo *mni = mndict->find(memName);
+ if (mni)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for ( ; (mi=mnii.current()) ; ++mnii )
+ {
+ MemberDef *md = mi->memberDef;
+ if (md && md->protection()!=Private)
+ {
+
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("found member %s\n",mni->memberName());
+ MemberDef *newMd = 0;
+ {
+ ArgumentList *templAl = md->templateArguments();
+ ArgumentList *al = md->templateArguments();
+ newMd = new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ md->typeString(),memName,md->argsString(),
+ md->excpString(),root->protection,root->virt,
+ md->isStatic(),Member,md->memberType(),
+ templAl,al
+ );
+ }
+ newMd->setMemberClass(cd);
+ cd->insertMember(newMd);
+ if (!root->doc.isEmpty() || !root->brief.isEmpty())
+ {
+ newMd->setDocumentation(root->doc,root->docFile,root->docLine);
+ newMd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ newMd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ }
+ else
+ {
+ newMd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+ newMd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+ newMd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+ }
+ newMd->setDefinition(md->definition());
+ newMd->enableCallGraph(root->callGraph);
+ newMd->enableCallerGraph(root->callerGraph);
+ newMd->setBitfields(md->bitfieldString());
+ newMd->addSectionsToDefinition(root->anchors);
+ newMd->setBodySegment(md->getStartBodyLine(),md->getEndBodyLine());
+ newMd->setBodyDef(md->getBodyDef());
+ newMd->setInitializer(md->initializer());
+ newMd->setMaxInitLines(md->initializerLines());
+ newMd->setMemberGroupId(root->mGrpId);
+ newMd->setMemberSpecifiers(md->getMemberSpecifiers());
+ newMd->setLanguage(root->lang);
+ newMd->setId(root->id);
+
+ rootNav->releaseEntry();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ RECURSE_ENTRYTREE(findUsingDeclImports,rootNav);
+}
+
+//----------------------------------------------------------------------
+
+static void findIncludedUsingDirectives()
+{
+ // first mark all files as not visited
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ fd->visited=FALSE;
+ }
+ }
+ // then recursively add using directives found in #include files
+ // to files that have not been visited.
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ if (!fd->visited)
+ {
+ //printf("----- adding using directives for file %s\n",fd->name().data());
+ fd->addIncludedUsingDirectives();
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static MemberDef *addVariableToClass(
+ EntryNav *rootNav,
+ ClassDef *cd,
+ MemberType mtype,
+ const QCString &name,
+ bool fromAnnScope,
+ MemberDef *fromAnnMemb,
+ Protection prot,
+ Relationship related)
+{
+ Entry *root = rootNav->entry();
+
+ QCString qualScope = cd->qualifiedNameWithTemplateParameters();
+ QCString scopeSeparator="::";
+ SrcLangExt lang = cd->getLanguage();
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
+ {
+ qualScope = substitute(qualScope,"::",".");
+ scopeSeparator=".";
+ }
+ Debug::print(Debug::Variables,0,
+ " class variable:\n"
+ " `%s' `%s'::`%s' `%s' prot=`%d ann=%d init=`%s'\n",
+ root->type.data(),
+ qualScope.data(),
+ name.data(),
+ root->args.data(),
+ root->protection,
+ fromAnnScope,
+ root->initializer.data()
+ );
+
+ QCString def;
+ if (!root->type.isEmpty())
+ {
+ if (related || mtype==MemberType_Friend || Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ if (root->spec&Entry::Alias) // turn 'typedef B A' into 'using A = B'
+ {
+ def="using "+name+" = "+root->type.mid(7);
+ }
+ else
+ {
+ def=root->type+" "+name+root->args;
+ }
+ }
+ else
+ {
+ if (root->spec&Entry::Alias) // turn 'typedef B C::A' into 'using C::A = B'
+ {
+ def="using "+qualScope+scopeSeparator+name+" = "+root->type.mid(7);
+ }
+ else
+ {
+ def=root->type+" "+qualScope+scopeSeparator+name+root->args;
+ }
+ }
+ }
+ else
+ {
+ if (Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ def=name+root->args;
+ }
+ else
+ {
+ def=qualScope+scopeSeparator+name+root->args;
+ }
+ }
+ def.stripPrefix("static ");
+
+ // see if the member is already found in the same scope
+ // (this may be the case for a static member that is initialized
+ // outside the class)
+ MemberName *mn=Doxygen::memberNameSDict->find(name);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
+ // md->getClassDef(),cd,root->type.data(),md->typeString());
+ if (md->getClassDef()==cd &&
+ removeRedundantWhiteSpace(root->type)==md->typeString())
+ // member already in the scope
+ {
+
+ if (root->lang==SrcLangExt_ObjC &&
+ root->mtype==Property &&
+ md->memberType()==MemberType_Variable)
+ { // Objective-C 2.0 property
+ // turn variable into a property
+ md->setProtection(root->protection);
+ cd->reclassifyMember(md,MemberType_Property);
+ }
+ addMemberDocs(rootNav,md,def,0,FALSE);
+ //printf(" Member already found!\n");
+ return md;
+ }
+ }
+ }
+
+ // new member variable, typedef or enum value
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ root->type,name,root->args,root->exception,
+ prot,Normal,root->stat,related,
+ mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
+ //md->setDefFile(root->fileName);
+ //md->setDefLine(root->startLine);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDefinition(def);
+ md->setBitfields(root->bitfields);
+ md->addSectionsToDefinition(root->anchors);
+ md->setFromAnonymousScope(fromAnnScope);
+ md->setFromAnonymousMember(fromAnnMemb);
+ //md->setIndentDepth(indentDepth);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setInitializer(root->initializer);
+ md->setMaxInitLines(root->initLines);
+ md->setMemberGroupId(root->mGrpId);
+ md->setMemberSpecifiers(root->spec);
+ md->setReadAccessor(root->read);
+ md->setWriteAccessor(root->write);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ md->setHidden(root->hidden);
+ md->setArtificial(root->artificial);
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ addMemberToGroups(root,md);
+ //if (root->mGrpId!=-1)
+ //{
+ // printf("memberdef %s in memberGroup %d\n",name.data(),root->mGrpId);
+ // md->setMemberGroup(memberGroupDict[root->mGrpId]);
+ //
+ md->setBodyDef(rootNav->fileDef());
+
+ //printf(" Adding member=%s\n",md->name().data());
+ // add the member to the global list
+ if (mn)
+ {
+ mn->append(md);
+ }
+ else // new variable name
+ {
+ mn = new MemberName(name);
+ mn->append(md);
+ //printf("Adding memberName=%s\n",mn->memberName());
+ //Doxygen::memberNameDict.insert(name,mn);
+ //Doxygen::memberNameList.append(mn);
+ Doxygen::memberNameSDict->append(name,mn);
+ // add the member to the class
+ }
+ //printf(" New member adding to %s (%p)!\n",cd->name().data(),cd);
+ cd->insertMember(md);
+ md->setRefItems(root->sli);
+
+ //TODO: insert FileDef instead of filename strings.
+ cd->insertUsedFile(rootNav->fileDef());
+ rootNav->changeSection(Entry::EMPTY_SEC);
+ return md;
+}
+
+//----------------------------------------------------------------------
+
+static MemberDef *addVariableToFile(
+ EntryNav *rootNav,
+ MemberType mtype,
+ const QCString &scope,
+ const QCString &name,
+ bool fromAnnScope,
+ /*int indentDepth,*/
+ MemberDef *fromAnnMemb)
+{
+ Entry *root = rootNav->entry();
+ Debug::print(Debug::Variables,0,
+ " global variable:\n"
+ " type=`%s' scope=`%s' name=`%s' args=`%s' prot=`%d mtype=%d lang=%d\n",
+ root->type.data(),
+ scope.data(),
+ name.data(),
+ root->args.data(),
+ root->protection,
+ mtype,
+ root->lang
+ );
+
+ FileDef *fd = rootNav->fileDef();
+
+ // see if we have a typedef that should hide a struct or union
+ if (mtype==MemberType_Typedef && Config_getBool("TYPEDEF_HIDES_STRUCT"))
+ {
+ QCString type = root->type;
+ type.stripPrefix("typedef ");
+ if (type.left(7)=="struct " || type.left(6)=="union ")
+ {
+ type.stripPrefix("struct ");
+ type.stripPrefix("union ");
+ static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+ int l,s;
+ s = re.match(type,0,&l);
+ if (s>=0)
+ {
+ QCString typeValue = type.mid(s,l);
+ ClassDef *cd = getClass(typeValue);
+ if (cd)
+ {
+ // this typedef should hide compound name cd, so we
+ // change the name that is displayed from cd.
+ cd->setClassName(name);
+ cd->setDocumentation(root->doc,root->docFile,root->docLine);
+ cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ return 0;
+ }
+ }
+ }
+ }
+
+ // see if the function is inside a namespace
+ NamespaceDef *nd = 0;
+ QCString nscope;
+ if (!scope.isEmpty())
+ {
+ if (scope.find('@')!=-1) return 0; // anonymous scope!
+ //nscope=removeAnonymousScopes(scope);
+ //if (!nscope.isEmpty())
+ //{
+ nd = getResolvedNamespace(scope);
+ //}
+ }
+ QCString def;
+
+ // determine the definition of the global variable
+ if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@' &&
+ !Config_getBool("HIDE_SCOPE_NAMES")
+ )
+ // variable is inside a namespace, so put the scope before the name
+ {
+ SrcLangExt lang = nd->getLanguage();
+ QCString sep=getLanguageSpecificSeparator(lang);
+
+ if (!root->type.isEmpty())
+ {
+ if (root->spec&Entry::Alias) // turn 'typedef B NS::A' into 'using NS::A = B'
+ {
+ def="using "+nd->name()+sep+name+" = "+root->type;
+ }
+ else // normal member
+ {
+ def=root->type+" "+nd->name()+sep+name+root->args;
+ }
+ }
+ else
+ {
+ def=nd->name()+sep+name+root->args;
+ }
+ }
+ else
+ {
+ if (!root->type.isEmpty() && !root->name.isEmpty())
+ {
+ if (name.at(0)=='@') // dummy variable representing anonymous union
+ {
+ def=root->type;
+ }
+ else
+ {
+ if (root->spec&Entry::Alias) // turn 'typedef B A' into 'using A = B'
+ {
+ def="using "+root->name+" = "+root->type.mid(7);
+ }
+ else // normal member
+ {
+ def=root->type+" "+name+root->args;
+ }
+ }
+ }
+ else
+ {
+ def=name+root->args;
+ }
+ }
+ def.stripPrefix("static ");
+
+ MemberName *mn=Doxygen::functionNameSDict->find(name);
+ if (mn)
+ {
+ //QCString nscope=removeAnonymousScopes(scope);
+ //NamespaceDef *nd=0;
+ //if (!nscope.isEmpty())
+ if (!scope.isEmpty())
+ {
+ nd = getResolvedNamespace(scope);
+ }
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (
+ ((nd==0 && md->getNamespaceDef()==0 && md->getFileDef() &&
+ root->fileName==md->getFileDef()->absFilePath()
+ ) // both variable names in the same file
+ || (nd!=0 && md->getNamespaceDef()==nd) // both in same namespace
+ )
+ && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
+ && !md->isEnumerate() // in C# an enum value and enum can have the same name
+ )
+ // variable already in the scope
+ {
+ bool isPHPArray = md->getLanguage()==SrcLangExt_PHP &&
+ md->argsString()!=root->args &&
+ root->args.find('[')!=-1;
+ bool staticsInDifferentFiles =
+ root->stat && md->isStatic() &&
+ root->fileName!=md->getDefFileName();
+
+ if (md->getFileDef() &&
+ !isPHPArray && // not a php array
+ !staticsInDifferentFiles
+ )
+ // not a php array variable
+ {
+
+ Debug::print(Debug::Variables,0,
+ " variable already found: scope=%s\n",md->getOuterScope()->name().data());
+ addMemberDocs(rootNav,md,def,0,FALSE);
+ md->setRefItems(root->sli);
+ return md;
+ }
+ }
+ }
+ }
+ Debug::print(Debug::Variables,0,
+ " new variable, nd=%s!\n",nd?nd->name().data():"<global>");
+ // new global variable, enum value or typedef
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ root->type,name,root->args,0,
+ Public, Normal,root->stat,Member,
+ mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setMemberSpecifiers(root->spec);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->addSectionsToDefinition(root->anchors);
+ md->setFromAnonymousScope(fromAnnScope);
+ md->setFromAnonymousMember(fromAnnMemb);
+ md->setInitializer(root->initializer);
+ md->setMaxInitLines(root->initLines);
+ md->setMemberGroupId(root->mGrpId);
+ md->setDefinition(def);
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ md->setExplicitExternal(root->explicitExternal);
+ //md->setOuterScope(fd);
+ if (!root->explicitExternal)
+ {
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(fd);
+ }
+ addMemberToGroups(root,md);
+
+ md->setRefItems(root->sli);
+ if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
+ {
+ md->setNamespace(nd);
+ nd->insertMember(md);
+ }
+
+ // add member to the file (we do this even if we have already inserted
+ // it into the namespace.
+ if (fd)
+ {
+ md->setFileDef(fd);
+ fd->insertMember(md);
+ }
+
+ // add member definition to the list of globals
+ if (mn)
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(name);
+ mn->append(md);
+ Doxygen::functionNameSDict->append(name,mn);
+ }
+ rootNav->changeSection(Entry::EMPTY_SEC);
+ return md;
+}
+
+/*! See if the return type string \a type is that of a function pointer
+ * \returns -1 if this is not a function pointer variable or
+ * the index at which the closing brace of (...*name) was found.
+ */
+static int findFunctionPtr(const QCString &type,int lang, int *pLength=0)
+{
+ if (lang == SrcLangExt_Fortran) return -1; // Fortran does not have function pointers
+ static const QRegExp re("([^)]*[\\*\\^][^)]*)");
+ int i=-1,l;
+ int bb=type.find('<');
+ int be=type.findRev('>');
+ if (!type.isEmpty() && // return type is non-empty
+ (i=re.match(type,0,&l))!=-1 && // contains (...*...)
+ type.find("operator")==-1 && // not an operator
+ (type.find(")(")==-1 || type.find("typedef ")!=-1) &&
+ // not a function pointer return type
+ !(bb<i && i<be) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
+ )
+ {
+ if (pLength) *pLength=l;
+ //printf("findFunctionPtr=%d\n",i);
+ return i;
+ }
+ else
+ {
+ //printf("findFunctionPtr=%d\n",-1);
+ return -1;
+ }
+}
+
+
+/*! Returns TRUE iff \a type is a class within scope \a context.
+ * Used to detect variable declarations that look like function prototypes.
+ */
+static bool isVarWithConstructor(EntryNav *rootNav)
+{
+ static QRegExp initChars("[0-9\"'&*!^]+");
+ static QRegExp idChars("[a-z_A-Z][a-z_A-Z0-9]*");
+ bool result=FALSE;
+ bool typeIsClass;
+ QCString type;
+ Definition *ctx = 0;
+ FileDef *fd = 0;
+ int ti;
+
+ //printf("isVarWithConstructor(%s)\n",rootNav->name().data());
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ if (rootNav->parent()->section() & Entry::COMPOUND_MASK)
+ { // inside a class
+ result=FALSE;
+ goto done;
+ }
+ else if ((fd = rootNav->fileDef()) &&
+ (fd->name().right(2)==".c" || fd->name().right(2)==".h")
+ )
+ { // inside a .c file
+ result=FALSE;
+ goto done;
+ }
+ if (root->type.isEmpty())
+ {
+ result=FALSE;
+ goto done;
+ }
+ if (!rootNav->parent()->name().isEmpty())
+ {
+ ctx=Doxygen::namespaceSDict->find(rootNav->parent()->name());
+ }
+ type = root->type;
+ // remove qualifiers
+ findAndRemoveWord(type,"const");
+ findAndRemoveWord(type,"static");
+ findAndRemoveWord(type,"volatile");
+ //if (type.left(6)=="const ") type=type.right(type.length()-6);
+ typeIsClass=getResolvedClass(ctx,fd,type)!=0;
+ if (!typeIsClass && (ti=type.find('<'))!=-1)
+ {
+ typeIsClass=getResolvedClass(ctx,fd,type.left(ti))!=0;
+ }
+ if (typeIsClass) // now we still have to check if the arguments are
+ // types or values. Since we do not have complete type info
+ // we need to rely on heuristics :-(
+ {
+ //printf("typeIsClass\n");
+ ArgumentList *al = root->argList;
+ if (al==0 || al->isEmpty())
+ {
+ result=FALSE; // empty arg list -> function prototype.
+ goto done;
+ }
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (!a->name.isEmpty() || !a->defval.isEmpty())
+ {
+ if (a->name.find(initChars)==0)
+ {
+ result=TRUE;
+ }
+ else
+ {
+ result=FALSE; // arg has (type,name) pair -> function prototype
+ }
+ goto done;
+ }
+ if (a->type.isEmpty() || getResolvedClass(ctx,fd,a->type)!=0)
+ {
+ result=FALSE; // arg type is a known type
+ goto done;
+ }
+ if (checkIfTypedef(ctx,fd,a->type))
+ {
+ //printf("%s:%d: false (arg is typedef)\n",__FILE__,__LINE__);
+ result=FALSE; // argument is a typedef
+ goto done;
+ }
+ if (a->type.at(a->type.length()-1)=='*' ||
+ a->type.at(a->type.length()-1)=='&')
+ // type ends with * or & => pointer or reference
+ {
+ result=FALSE;
+ goto done;
+ }
+ if (a->type.find(initChars)==0)
+ {
+ result=TRUE; // argument type starts with typical initializer char
+ goto done;
+ }
+ QCString resType=resolveTypeDef(ctx,a->type);
+ if (resType.isEmpty()) resType=a->type;
+ int len;
+ if (idChars.match(resType,0,&len)==0) // resType starts with identifier
+ {
+ resType=resType.left(len);
+ //printf("resType=%s\n",resType.data());
+ if (resType=="int" || resType=="long" || resType=="float" ||
+ resType=="double" || resType=="char" || resType=="signed" ||
+ resType=="const" || resType=="unsigned" || resType=="void")
+ {
+ result=FALSE; // type keyword -> function prototype
+ goto done;
+ }
+ }
+ }
+ result=TRUE;
+ }
+
+done:
+ //printf("isVarWithConstructor(%s,%s)=%d\n",rootNav->parent()->name().data(),
+ // root->type.data(),result);
+ rootNav->releaseEntry();
+ return result;
+}
+
+static void addVariable(EntryNav *rootNav,int isFuncPtr=-1)
+{
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ Debug::print(Debug::Variables,0,
+ "VARIABLE_SEC: \n"
+ " type=`%s' name=`%s' args=`%s' bodyLine=`%d' mGrpId=%d relates=%s\n",
+ root->type.data(),
+ root->name.data(),
+ root->args.data(),
+ root->bodyLine,
+ root->mGrpId,
+ root->relates.data()
+ );
+ //printf("root->parent->name=%s\n",root->parent->name.data());
+
+ if (root->type.isEmpty() && root->name.find("operator")==-1 &&
+ (root->name.find('*')!=-1 || root->name.find('&')!=-1))
+ {
+ // recover from parse error caused by redundant braces
+ // like in "int *(var[10]);", which is parsed as
+ // type="" name="int *" args="(var[10])"
+
+ root->type=root->name;
+ static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*");
+ int l=0;
+ int i=root->args.isEmpty() ? -1 : reName.match(root->args,0,&l);
+ if (i!=-1)
+ {
+ root->name=root->args.mid(i,l);
+ root->args=root->args.mid(i+l,root->args.find(')',i+l)-i-l);
+ }
+ //printf("new: type=`%s' name=`%s' args=`%s'\n",
+ // root->type.data(),root->name.data(),root->args.data());
+ }
+ else
+ {
+ int i=isFuncPtr;
+ if (i==-1 && (root->spec&Entry::Alias)==0) i=findFunctionPtr(root->type,root->lang); // for typedefs isFuncPtr is not yet set
+ Debug::print(Debug::Variables,0," functionPtr? %s\n",i!=-1?"yes":"no");
+ if (i!=-1) // function pointer
+ {
+ int ai = root->type.find('[',i);
+ if (ai>i) // function pointer array
+ {
+ root->args.prepend(root->type.right(root->type.length()-ai));
+ root->type=root->type.left(ai);
+ }
+ else if (root->type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]"
+ {
+ root->type=root->type.left(root->type.length()-1);
+ root->args.prepend(")");
+ //printf("root->type=%s root->args=%s\n",root->type.data(),root->args.data());
+ }
+ }
+ else if (root->type.find("typedef ")!=-1 && root->type.right(2)=="()") // typedef void (func)(int)
+ {
+ root->type=root->type.left(root->type.length()-1);
+ root->args.prepend(")");
+ }
+ }
+
+ QCString scope,name=removeRedundantWhiteSpace(root->name);
+
+ // find the scope of this variable
+ EntryNav *p = rootNav->parent();
+ while ((p->section() & Entry::SCOPE_MASK))
+ {
+ QCString scopeName = p->name();
+ if (!scopeName.isEmpty())
+ {
+ scope.prepend(scopeName);
+ break;
+ }
+ p=p->parent();
+ }
+
+ MemberType mtype;
+ QCString type=root->type.stripWhiteSpace();
+ ClassDef *cd=0;
+ bool isRelated=FALSE;
+ bool isMemberOf=FALSE;
+
+ QCString classScope=stripAnonymousNamespaceScope(scope);
+ classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
+ QCString annScopePrefix=scope.left(scope.length()-classScope.length());
+
+ if (root->name.findRev("::")!=-1)
+ {
+ if (root->type=="friend class" || root->type=="friend struct" ||
+ root->type=="friend union")
+ {
+ cd=getClass(scope);
+ if (cd)
+ {
+ addVariableToClass(rootNav, // entry
+ cd, // class to add member to
+ MemberType_Friend, // type of member
+ name, // name of the member
+ FALSE, // from Anonymous scope
+ 0, // anonymous member
+ Public, // protection
+ Member // related to a class
+ );
+ }
+ }
+ goto nextMember;
+ /* skip this member, because it is a
+ * static variable definition (always?), which will be
+ * found in a class scope as well, but then we know the
+ * correct protection level, so only then it will be
+ * inserted in the correct list!
+ */
+ }
+
+ if (type=="@")
+ mtype=MemberType_EnumValue;
+ else if (type.left(8)=="typedef ")
+ mtype=MemberType_Typedef;
+ else if (type.left(7)=="friend ")
+ mtype=MemberType_Friend;
+ else if (root->mtype==Property)
+ mtype=MemberType_Property;
+ else if (root->mtype==Event)
+ mtype=MemberType_Event;
+ else
+ mtype=MemberType_Variable;
+
+ if (!root->relates.isEmpty()) // related variable
+ {
+ isRelated=TRUE;
+ isMemberOf=(root->relatesType == MemberOf);
+ if (getClass(root->relates)==0 && !scope.isEmpty())
+ scope=mergeScopes(scope,root->relates);
+ else
+ scope=root->relates;
+ }
+
+ cd=getClass(scope);
+ if (cd==0 && classScope!=scope) cd=getClass(classScope);
+ if (cd)
+ {
+ MemberDef *md=0;
+
+ // if cd is an anonymous (=tag less) scope we insert the member
+ // into a non-anonymous parent scope as well. This is needed to
+ // be able to refer to it using \var or \fn
+
+ //int indentDepth=0;
+ int si=scope.find('@');
+ //int anonyScopes = 0;
+ //bool added=FALSE;
+
+ static bool inlineSimpleStructs = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type
+ {
+ QCString pScope;
+ ClassDef *pcd=0;
+ pScope = scope.left(QMAX(si-2,0)); // scope without tag less parts
+ if (!pScope.isEmpty())
+ pScope.prepend(annScopePrefix);
+ else if (annScopePrefix.length()>2)
+ pScope=annScopePrefix.left(annScopePrefix.length()-2);
+ if (name.at(0)!='@')
+ {
+ if (!pScope.isEmpty() && (pcd=getClass(pScope)))
+ {
+ md=addVariableToClass(rootNav, // entry
+ pcd, // class to add member to
+ mtype, // member type
+ name, // member name
+ TRUE, // from anonymous scope
+ 0, // from anonymous member
+ root->protection,
+ isMemberOf ? Foreign : isRelated ? Related : Member
+ );
+ //added=TRUE;
+ }
+ else // anonymous scope inside namespace or file => put variable in the global scope
+ {
+ if (mtype==MemberType_Variable)
+ {
+ md=addVariableToFile(rootNav,mtype,pScope,name,TRUE,0);
+ }
+ //added=TRUE;
+ }
+ }
+ }
+
+ //printf("name=`%s' scope=%s scope.right=%s\n",
+ // name.data(),scope.data(),
+ // scope.right(scope.length()-si).data());
+ addVariableToClass(rootNav, // entry
+ cd, // class to add member to
+ mtype, // member type
+ name, // name of the member
+ FALSE, // from anonymous scope
+ md, // from anonymous member
+ root->protection,
+ isMemberOf ? Foreign : isRelated ? Related : Member);
+ }
+ else if (!name.isEmpty()) // global variable
+ {
+ //printf("Inserting member in global scope %s!\n",scope.data());
+ addVariableToFile(rootNav,mtype,scope,name,FALSE,/*0,*/0);
+ }
+
+nextMember:
+ rootNav->releaseEntry();
+}
+
+//----------------------------------------------------------------------
+// Searches the Entry tree for typedef documentation sections.
+// If found they are stored in their class or in the global list.
+static void buildTypedefList(EntryNav *rootNav)
+{
+ //printf("buildVarList(%s)\n",rootNav->name().data());
+ if (!rootNav->name().isEmpty() &&
+ rootNav->section()==Entry::VARIABLE_SEC &&
+ rootNav->type().find("typedef ")!=-1 // its a typedef
+ )
+ {
+ addVariable(rootNav);
+ }
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ if (e->section()!=Entry::ENUM_SEC)
+ {
+ buildTypedefList(e);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+// Searches the Entry tree for Variable documentation sections.
+// If found they are stored in their class or in the global list.
+
+static void buildVarList(EntryNav *rootNav)
+{
+ //printf("buildVarList(%s) section=%08x\n",rootNav->name().data(),rootNav->section());
+ int isFuncPtr=-1;
+ if (!rootNav->name().isEmpty() &&
+ (rootNav->type().isEmpty() || g_compoundKeywordDict.find(rootNav->type())==0) &&
+ (
+ (rootNav->section()==Entry::VARIABLE_SEC // it's a variable
+ ) ||
+ (rootNav->section()==Entry::FUNCTION_SEC && // or maybe a function pointer variable
+ (isFuncPtr=findFunctionPtr(rootNav->type(),rootNav->lang()))!=-1
+ ) ||
+ (rootNav->section()==Entry::FUNCTION_SEC && // class variable initialized by constructor
+ isVarWithConstructor(rootNav)
+ )
+ )
+ ) // documented variable
+ {
+ addVariable(rootNav,isFuncPtr);
+ }
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ if (e->section()!=Entry::ENUM_SEC)
+ {
+ buildVarList(e);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+// Searches the Entry tree for Interface sections (UNO IDL only).
+// If found they are stored in their service or in the global list.
+//
+
+static void addInterfaceOrServiceToServiceOrSingleton(
+ EntryNav *const rootNav,
+ ClassDef *const cd,
+ QCString const& rname)
+{
+ Entry *const root = rootNav->entry();
+ FileDef *const fd = rootNav->fileDef();
+ enum MemberType const type = (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC)
+ ? MemberType_Interface
+ : MemberType_Service;
+ MemberDef *const md = new MemberDef(
+ root->fileName, root->startLine, root->startColumn, root->type, rname,
+ "", "", root->protection, root->virt, root->stat, Member,
+ type, 0, root->argList);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setMemberClass(cd);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(false);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+ md->setTypeConstraints(root->typeConstr);
+ md->setLanguage(root->lang);
+ md->setBodyDef(fd);
+ md->setFileDef(fd);
+ md->addSectionsToDefinition(root->anchors);
+ QCString const def = root->type + " " + rname;
+ md->setDefinition(def);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+
+ Debug::print(Debug::Functions,0,
+ " Interface Member:\n"
+ " `%s' `%s' proto=%d\n"
+ " def=`%s'\n",
+ root->type.data(),
+ rname.data(),
+ root->proto,
+ def.data()
+ );
+
+ // add member to the global list of all members
+ MemberName *mn;
+ if ((mn=Doxygen::memberNameSDict->find(rname)))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(rname);
+ mn->append(md);
+ Doxygen::memberNameSDict->append(rname,mn);
+ }
+
+ // add member to the class cd
+ cd->insertMember(md);
+ // also add the member as a "base" (to get nicer diagrams)
+ // "optional" interface/service get Protected which turns into dashed line
+ BaseInfo base(rname,
+ (root->spec & (Entry::Optional)) ? Protected : Public,Normal);
+ findClassRelation(rootNav,cd,cd,&base,0,DocumentedOnly,true)
+ || findClassRelation(rootNav,cd,cd,&base,0,Undocumented,true);
+ // add file to list of used files
+ cd->insertUsedFile(fd);
+
+ addMemberToGroups(root,md);
+ rootNav->changeSection(Entry::EMPTY_SEC);
+ md->setRefItems(root->sli);
+}
+
+static void buildInterfaceAndServiceList(EntryNav *const rootNav)
+{
+ if (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC ||
+ rootNav->section()==Entry::INCLUDED_SERVICE_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *const root = rootNav->entry();
+
+ Debug::print(Debug::Functions,0,
+ "EXPORTED_INTERFACE_SEC:\n"
+ " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n",
+ root->type.data(),
+ rootNav->parent()->name().data(),
+ root->name.data(),
+ root->args.data(),
+ root->relates.data(),
+ root->relatesType,
+ root->fileName.data(),
+ root->startLine,
+ root->bodyLine,
+ root->tArgLists ? (int)root->tArgLists->count() : -1,
+ root->mGrpId,
+ root->spec,
+ root->proto,
+ root->docFile.data()
+ );
+
+ QCString const rname = removeRedundantWhiteSpace(root->name);
+
+ if (!rname.isEmpty())
+ {
+ QCString const scope = rootNav->parent()->name();
+ ClassDef *const cd = getClass(scope);
+ assert(cd);
+ if (cd && ((ClassDef::Interface == cd->compoundType()) ||
+ (ClassDef::Service == cd->compoundType()) ||
+ (ClassDef::Singleton == cd->compoundType())))
+ {
+ addInterfaceOrServiceToServiceOrSingleton(rootNav,cd,rname);
+ }
+ else
+ {
+ assert(false); // was checked by scanner.l
+ }
+ }
+ else if (rname.isEmpty())
+ {
+ warn(root->fileName,root->startLine,
+ "Illegal member name found.");
+ }
+
+ rootNav->releaseEntry();
+ }
+ // can only have these in IDL anyway
+ switch (rootNav->lang())
+ {
+ case SrcLangExt_Unknown: // fall through (root node always is Unknown)
+ case SrcLangExt_IDL:
+ RECURSE_ENTRYTREE(buildInterfaceAndServiceList,rootNav);
+ break;
+ default:
+ return; // nothing to do here
+ }
+}
+
+
+//----------------------------------------------------------------------
+// Searches the Entry tree for Function sections.
+// If found they are stored in their class or in the global list.
+
+static void addMethodToClass(EntryNav *rootNav,ClassDef *cd,
+ const QCString &rname,bool isFriend)
+{
+ Entry *root = rootNav->entry();
+ FileDef *fd=rootNav->fileDef();
+
+ int l;
+ static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*");
+ int ts=root->type.find('<');
+ int te=root->type.findRev('>');
+ int i=re.match(root->type,0,&l);
+ if (i!=-1 && ts!=-1 && ts<te && ts<i && i<te) // avoid changing A<int(int*)>, see bug 677315
+ {
+ i=-1;
+ }
+
+ if (cd->getLanguage()==SrcLangExt_Cpp && // only C has pointers
+ !root->type.isEmpty() && (root->spec&Entry::Alias)==0 && i!=-1) // function variable
+ {
+ root->args+=root->type.right(root->type.length()-i-l);
+ root->type=root->type.left(i+l);
+ }
+
+ QCString name=removeRedundantWhiteSpace(rname);
+ if (name.left(2)=="::") name=name.right(name.length()-2);
+
+ MemberType mtype;
+ if (isFriend) mtype=MemberType_Friend;
+ else if (root->mtype==Signal) mtype=MemberType_Signal;
+ else if (root->mtype==Slot) mtype=MemberType_Slot;
+ else if (root->mtype==DCOP) mtype=MemberType_DCOP;
+ else mtype=MemberType_Function;
+
+ // strip redundant template specifier for constructors
+ if ((fd==0 || fd->getLanguage()==SrcLangExt_Cpp) &&
+ name.left(9)!="operator " && (i=name.find('<'))!=-1 && name.find('>')!=-1)
+ {
+ name=name.left(i);
+ }
+
+ //printf("root->name=`%s; root->args=`%s' root->argList=`%s'\n",
+ // root->name.data(),root->args.data(),argListToString(root->argList).data()
+ // );
+
+ // adding class member
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ root->type,name,root->args,root->exception,
+ root->protection,root->virt,
+ root->stat && root->relatesType != MemberOf,
+ root->relates.isEmpty() ? Member :
+ root->relatesType == MemberOf ? Foreign : Related,
+ mtype,root->tArgLists ? root->tArgLists->getLast() : 0,root->argList);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setMemberClass(cd);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+ md->setTypeConstraints(root->typeConstr);
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ md->setBodyDef(fd);
+ md->setFileDef(fd);
+ //md->setScopeTemplateArguments(root->tArgList);
+ md->addSectionsToDefinition(root->anchors);
+ QCString def;
+ QCString qualScope = cd->qualifiedNameWithTemplateParameters();
+ SrcLangExt lang = cd->getLanguage();
+ QCString scopeSeparator=getLanguageSpecificSeparator(lang);
+ if (scopeSeparator!="::")
+ {
+ qualScope = substitute(qualScope,"::",scopeSeparator);
+ }
+ if (lang==SrcLangExt_PHP)
+ {
+ // for PHP we use Class::method and Namespace\method
+ scopeSeparator="::";
+ }
+ if (!root->relates.isEmpty() || isFriend || Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ if (!root->type.isEmpty())
+ {
+ if (root->argList)
+ {
+ def=root->type+" "+name;
+ }
+ else
+ {
+ def=root->type+" "+name+root->args;
+ }
+ }
+ else
+ {
+ if (root->argList)
+ {
+ def=name;
+ }
+ else
+ {
+ def=name+root->args;
+ }
+ }
+ }
+ else
+ {
+ if (!root->type.isEmpty())
+ {
+ if (root->argList)
+ {
+ def=root->type+" "+qualScope+scopeSeparator+name;
+ }
+ else
+ {
+ def=root->type+" "+qualScope+scopeSeparator+name+root->args;
+ }
+ }
+ else
+ {
+ if (root->argList)
+ {
+ def=qualScope+scopeSeparator+name;
+ }
+ else
+ {
+ def=qualScope+scopeSeparator+name+root->args;
+ }
+ }
+ }
+ if (def.left(7)=="friend ") def=def.right(def.length()-7);
+ md->setDefinition(def);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+
+ Debug::print(Debug::Functions,0,
+ " Func Member:\n"
+ " `%s' `%s'::`%s' `%s' proto=%d\n"
+ " def=`%s'\n",
+ root->type.data(),
+ qualScope.data(),
+ rname.data(),
+ root->args.data(),
+ root->proto,
+ def.data()
+ );
+
+ // add member to the global list of all members
+ //printf("Adding member=%s class=%s\n",md->name().data(),cd->name().data());
+ MemberName *mn;
+ if ((mn=Doxygen::memberNameSDict->find(name)))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(name);
+ mn->append(md);
+ Doxygen::memberNameSDict->append(name,mn);
+ }
+
+ // add member to the class cd
+ cd->insertMember(md);
+ // add file to list of used files
+ cd->insertUsedFile(fd);
+
+ addMemberToGroups(root,md);
+ rootNav->changeSection(Entry::EMPTY_SEC);
+ md->setRefItems(root->sli);
+}
+
+
+static void buildFunctionList(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::FUNCTION_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ Debug::print(Debug::Functions,0,
+ "FUNCTION_SEC:\n"
+ " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n",
+ root->type.data(),
+ rootNav->parent()->name().data(),
+ root->name.data(),
+ root->args.data(),
+ root->relates.data(),
+ root->relatesType,
+ root->fileName.data(),
+ root->startLine,
+ root->bodyLine,
+ root->tArgLists ? (int)root->tArgLists->count() : -1,
+ root->mGrpId,
+ root->spec,
+ root->proto,
+ root->docFile.data()
+ );
+
+ bool isFriend=root->type.find("friend ")!=-1;
+ QCString rname = removeRedundantWhiteSpace(root->name);
+ //printf("rname=%s\n",rname.data());
+
+ QCString scope=rootNav->parent()->name(); //stripAnonymousNamespaceScope(root->parent->name);
+ if (!rname.isEmpty() && scope.find('@')==-1)
+ {
+ ClassDef *cd=0;
+ // check if this function's parent is a class
+ scope=stripTemplateSpecifiersFromScope(scope,FALSE);
+
+ FileDef *rfd=rootNav->fileDef();
+
+ int memIndex=rname.findRev("::");
+
+ cd=getClass(scope);
+ if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
+ {
+ // strip scope from name
+ rname=rname.right(rname.length()-rootNav->parent()->name().length()-2);
+ }
+
+ NamespaceDef *nd = 0;
+ bool isMember=FALSE;
+ if (memIndex!=-1)
+ {
+ int ts=rname.find('<');
+ int te=rname.find('>');
+ if (memIndex>0 && (ts==-1 || te==-1))
+ {
+ // note: the following code was replaced by inMember=TRUE to deal with a
+ // function rname='X::foo' of class X inside a namespace also called X...
+ // bug id 548175
+ //nd = Doxygen::namespaceSDict->find(rname.left(memIndex));
+ //isMember = nd==0;
+ //if (nd)
+ //{
+ // // strip namespace scope from name
+ // scope=rname.left(memIndex);
+ // rname=rname.right(rname.length()-memIndex-2);
+ //}
+ isMember = TRUE;
+ }
+ else
+ {
+ isMember=memIndex<ts || memIndex>te;
+ }
+ }
+
+ static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*");
+ int ts=root->type.find('<');
+ int te=root->type.findRev('>');
+ int ti;
+ if (!rootNav->parent()->name().isEmpty() &&
+ (rootNav->parent()->section() & Entry::COMPOUND_MASK) &&
+ cd &&
+ // do some fuzzy things to exclude function pointers
+ (root->type.isEmpty() ||
+ ((ti=root->type.find(re,0))==-1 || // type does not contain ..(..*
+ (ts!=-1 && ts<te && ts<ti && ti<te) || // outside of < ... >
+ root->args.find(")[")!=-1) || // and args not )[.. -> function pointer
+ root->type.find(")(")!=-1 || root->type.find("operator")!=-1 || // type contains ..)(.. and not "operator"
+ cd->getLanguage()!=SrcLangExt_Cpp // language other than C
+ )
+ )
+ {
+ Debug::print(Debug::Functions,0," --> member %s of class %s!\n",
+ rname.data(),cd->name().data());
+ addMethodToClass(rootNav,cd,rname,isFriend);
+ }
+ else if (!((rootNav->parent()->section() & Entry::COMPOUND_MASK)
+ || rootNav->parent()->section()==Entry::OBJCIMPL_SEC
+ ) &&
+ !isMember &&
+ (root->relates.isEmpty() || root->relatesType == Duplicate) &&
+ root->type.left(7)!="extern " && root->type.left(8)!="typedef "
+ )
+ // no member => unrelated function
+ {
+ /* check the uniqueness of the function name in the file.
+ * A file could contain a function prototype and a function definition
+ * or even multiple function prototypes.
+ */
+ bool found=FALSE;
+ MemberName *mn;
+ MemberDef *md=0;
+ if ((mn=Doxygen::functionNameSDict->find(rname)))
+ {
+ Debug::print(Debug::Functions,0," --> function %s already found!\n",rname.data());
+ MemberNameIterator mni(*mn);
+ for (mni.toFirst();(!found && (md=mni.current()));++mni)
+ {
+ NamespaceDef *mnd = md->getNamespaceDef();
+ NamespaceDef *rnd = 0;
+ //printf("root namespace=%s\n",rootNav->parent()->name().data());
+ QCString fullScope = scope;
+ QCString parentScope = rootNav->parent()->name();
+ if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope))
+ {
+ if (!scope.isEmpty()) fullScope.prepend("::");
+ fullScope.prepend(parentScope);
+ }
+ //printf("fullScope=%s\n",fullScope.data());
+ rnd = getResolvedNamespace(fullScope);
+ FileDef *mfd = md->getFileDef();
+ QCString nsName,rnsName;
+ if (mnd) nsName = mnd->name().copy();
+ if (rnd) rnsName = rnd->name().copy();
+ //printf("matching arguments for %s%s %s%s\n",
+ // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data());
+ ArgumentList *mdAl = md->argumentList();
+ ArgumentList *mdTempl = md->templateArguments();
+
+ // in case of template functions, we need to check if the
+ // functions have the same number of template parameters
+ bool sameNumTemplateArgs = TRUE;
+ bool matchingReturnTypes = TRUE;
+ if (mdTempl!=0 && root->tArgLists)
+ {
+ if (mdTempl->count()!=root->tArgLists->getLast()->count())
+ {
+ sameNumTemplateArgs = FALSE;
+ }
+ if (md->typeString()!=removeRedundantWhiteSpace(root->type))
+ {
+ matchingReturnTypes = FALSE;
+ }
+ }
+
+ bool staticsInDifferentFiles =
+ root->stat && md->isStatic() && root->fileName!=md->getDefFileName();
+
+ if (
+ matchArguments2(md->getOuterScope(),mfd,mdAl,
+ rnd ? rnd : Doxygen::globalScope,rfd,root->argList,
+ FALSE) &&
+ sameNumTemplateArgs &&
+ matchingReturnTypes &&
+ !staticsInDifferentFiles
+ )
+ {
+ GroupDef *gd=0;
+ if (root->groups->getFirst()!=0)
+ {
+ gd = Doxygen::groupSDict->find(root->groups->getFirst()->groupname.data());
+ }
+ //printf("match!\n");
+ //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data());
+ // see if we need to create a new member
+ found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
+ ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and
+ mfd->absFilePath()==root->fileName // prototype in the same file
+ )
+ );
+ // otherwise, allow a duplicate global member with the same argument list
+ if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
+ {
+ // member is already in the group, so we don't want to add it again.
+ found=TRUE;
+ }
+
+ //printf("combining function with prototype found=%d in namespace %s\n",
+ // found,nsName.data());
+
+ if (found)
+ {
+ // merge argument lists
+ mergeArguments(mdAl,root->argList,!root->doc.isEmpty());
+ // merge documentation
+ if (md->documentation().isEmpty() && !root->doc.isEmpty())
+ {
+ ArgumentList *argList = new ArgumentList;
+ stringToArgumentList(root->args,argList);
+ if (root->proto)
+ {
+ //printf("setDeclArgumentList to %p\n",argList);
+ md->setDeclArgumentList(argList);
+ }
+ else
+ {
+ md->setArgumentList(argList);
+ }
+ }
+
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
+ {
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(rfd);
+ }
+
+ if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
+ {
+ md->setArgsString(root->args);
+ }
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+
+ md->addSectionsToDefinition(root->anchors);
+
+ md->enableCallGraph(md->hasCallGraph() || root->callGraph);
+ md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph);
+
+ // merge ingroup specifiers
+ if (md->getGroupDef()==0 && root->groups->getFirst()!=0)
+ {
+ addMemberToGroups(root,md);
+ }
+ else if (md->getGroupDef()!=0 && root->groups->count()==0)
+ {
+ //printf("existing member is grouped, new member not\n");
+ root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri()));
+ }
+ else if (md->getGroupDef()!=0 && root->groups->getFirst()!=0)
+ {
+ //printf("both members are grouped\n");
+ }
+
+ // if md is a declaration and root is the corresponding
+ // definition, then turn md into a definition.
+ if (md->isPrototype() && !root->proto)
+ {
+ md->setPrototype(FALSE);
+ }
+ }
+ }
+ }
+ }
+ if (!found) /* global function is unique with respect to the file */
+ {
+ Debug::print(Debug::Functions,0," --> new function %s found!\n",rname.data());
+ //printf("New function type=`%s' name=`%s' args=`%s' bodyLine=%d\n",
+ // root->type.data(),rname.data(),root->args.data(),root->bodyLine);
+
+ // new global function
+ ArgumentList *tArgList = root->tArgLists ? root->tArgLists->getLast() : 0;
+ QCString name=removeRedundantWhiteSpace(rname);
+ md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ root->type,name,root->args,root->exception,
+ root->protection,root->virt,root->stat,Member,
+ MemberType_Function,tArgList,root->argList);
+
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ //md->setDefFile(root->fileName);
+ //md->setDefLine(root->startLine);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setPrototype(root->proto);
+ md->setDocsForDefinition(!root->proto);
+ md->setTypeConstraints(root->typeConstr);
+ //md->setBody(root->body);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ FileDef *fd=rootNav->fileDef();
+ md->setBodyDef(fd);
+ md->addSectionsToDefinition(root->anchors);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+
+ // see if the function is inside a namespace that was not part of
+ // the name already (in that case nd should be non-zero already)
+ if (nd==0 && rootNav->parent()->section() == Entry::NAMESPACE_SEC )
+ {
+ //QCString nscope=removeAnonymousScopes(rootNav->parent()->name());
+ QCString nscope=rootNav->parent()->name();
+ if (!nscope.isEmpty())
+ {
+ nd = getResolvedNamespace(nscope);
+ }
+ }
+
+ if (!scope.isEmpty())
+ {
+ QCString sep = getLanguageSpecificSeparator(root->lang);
+ if (sep!="::")
+ {
+ scope = substitute(scope,"::",sep);
+ }
+ scope+=sep;
+ }
+
+ QCString def;
+ if (!root->type.isEmpty())
+ {
+ if (root->argList)
+ {
+ def=root->type+" "+scope+name;
+ }
+ else
+ {
+ def=root->type+" "+scope+name+root->args;
+ }
+ }
+ else
+ {
+ if (root->argList)
+ {
+ def=scope+name.copy();
+ }
+ else
+ {
+ def=scope+name+root->args;
+ }
+ }
+ Debug::print(Debug::Functions,0,
+ " Global Function:\n"
+ " `%s' `%s'::`%s' `%s' proto=%d\n"
+ " def=`%s'\n",
+ root->type.data(),
+ rootNav->parent()->name().data(),
+ rname.data(),
+ root->args.data(),
+ root->proto,
+ def.data()
+ );
+ md->setDefinition(def);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ //if (root->mGrpId!=-1)
+ //{
+ // md->setMemberGroup(memberGroupDict[root->mGrpId]);
+ //}
+
+ md->setRefItems(root->sli);
+ if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
+ {
+ // add member to namespace
+ md->setNamespace(nd);
+ nd->insertMember(md);
+ }
+ if (fd)
+ {
+ // add member to the file (we do this even if we have already
+ // inserted it into the namespace)
+ md->setFileDef(fd);
+ fd->insertMember(md);
+ }
+
+ // add member to the list of file members
+ //printf("Adding member=%s\n",md->name().data());
+ MemberName *mn;
+ if ((mn=Doxygen::functionNameSDict->find(name)))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(name);
+ mn->append(md);
+ Doxygen::functionNameSDict->append(name,mn);
+ }
+ addMemberToGroups(root,md);
+ if (root->relatesType == Simple) // if this is a relatesalso command,
+ // allow find Member to pick it up
+ {
+ rootNav->changeSection(Entry::EMPTY_SEC); // Otherwise we have finished
+ // with this entry.
+
+ }
+ }
+ else
+ {
+ FileDef *fd=rootNav->fileDef();
+ if (fd)
+ {
+ // add member to the file (we do this even if we have already
+ // inserted it into the namespace)
+ fd->insertMember(md);
+ }
+ }
+
+ //printf("unrelated function %d `%s' `%s' `%s'\n",
+ // root->parent->section,root->type.data(),rname.data(),root->args.data());
+ }
+ else
+ {
+ Debug::print(Debug::Functions,0," --> %s not processed!\n",rname.data());
+ }
+ }
+ else if (rname.isEmpty())
+ {
+ warn(root->fileName,root->startLine,
+ "Illegal member name found."
+ );
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildFunctionList,rootNav);
+}
+
+//----------------------------------------------------------------------
+
+static void findFriends()
+{
+ //printf("findFriends()\n");
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ MemberName *fn;
+ for (;(fn=fnli.current());++fnli) // for each global function name
+ {
+ //printf("Function name=`%s'\n",fn->memberName());
+ MemberName *mn;
+ if ((mn=Doxygen::memberNameSDict->find(fn->memberName())))
+ { // there are members with the same name
+ //printf("Function name is also a member name\n");
+ MemberNameIterator fni(*fn);
+ MemberDef *fmd;
+ for (;(fmd=fni.current());++fni) // for each function with that name
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *mmd;
+ for (;(mmd=mni.current());++mni) // for each member with that name
+ {
+ //printf("Checking for matching arguments
+ // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
+ // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
+ ArgumentList *mmdAl = mmd->argumentList();
+ ArgumentList *fmdAl = fmd->argumentList();
+ if ((mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
+ matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmdAl,
+ fmd->getOuterScope(), fmd->getFileDef(), fmdAl,
+ TRUE
+ )
+
+ ) // if the member is related and the arguments match then the
+ // function is actually a friend.
+ {
+ mergeArguments(mmdAl,fmdAl);
+ if (!fmd->documentation().isEmpty())
+ {
+ mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
+ }
+ else if (!mmd->documentation().isEmpty())
+ {
+ fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
+ }
+ if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
+ {
+ mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
+ }
+ else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
+ {
+ fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
+ }
+ if (!fmd->inbodyDocumentation().isEmpty())
+ {
+ mmd->setInbodyDocumentation(fmd->inbodyDocumentation(),fmd->inbodyFile(),fmd->inbodyLine());
+ }
+ else if (!mmd->inbodyDocumentation().isEmpty())
+ {
+ fmd->setInbodyDocumentation(mmd->inbodyDocumentation(),mmd->inbodyFile(),mmd->inbodyLine());
+ }
+ //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
+ if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
+ {
+ mmd->setBodySegment(fmd->getStartBodyLine(),fmd->getEndBodyLine());
+ mmd->setBodyDef(fmd->getBodyDef());
+ //mmd->setBodyMember(fmd);
+ }
+ else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
+ {
+ fmd->setBodySegment(mmd->getStartBodyLine(),mmd->getEndBodyLine());
+ fmd->setBodyDef(mmd->getBodyDef());
+ //fmd->setBodyMember(mmd);
+ }
+ mmd->setDocsForDefinition(fmd->isDocsForDefinition());
+
+ mmd->enableCallGraph(mmd->hasCallGraph() || fmd->hasCallGraph());
+ mmd->enableCallerGraph(mmd->hasCallerGraph() || fmd->hasCallerGraph());
+ fmd->enableCallGraph(mmd->hasCallGraph() || fmd->hasCallGraph());
+ fmd->enableCallerGraph(mmd->hasCallerGraph() || fmd->hasCallerGraph());
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void transferFunctionDocumentation()
+{
+ //printf("---- transferFunctionDocumentation()\n");
+
+ // find matching function declaration and definitions.
+ MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict);
+ MemberName *mn;
+ for (;(mn=mnli.current());++mnli)
+ {
+ //printf("memberName=%s count=%d\n",mn->memberName(),mn->count());
+ MemberDef *mdef=0,*mdec=0;
+ MemberNameIterator mni1(*mn);
+ /* find a matching function declaration and definition for this function */
+ for (;(mdec=mni1.current());++mni1)
+ {
+ if (mdec->isPrototype() ||
+ (mdec->isVariable() && mdec->isExternal())
+ )
+ {
+ MemberNameIterator mni2(*mn);
+ for (;(mdef=mni2.current());++mni2)
+ {
+ combineDeclarationAndDefinition(mdec,mdef);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void transferFunctionReferences()
+{
+ MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict);
+ MemberName *mn;
+ for (;(mn=mnli.current());++mnli)
+ {
+ MemberDef *md,*mdef=0,*mdec=0;
+ MemberNameIterator mni(*mn);
+ /* find a matching function declaration and definition for this function */
+ for (;(md=mni.current());++mni)
+ {
+ if (md->isPrototype())
+ mdec=md;
+ else if (md->isVariable() && md->isExternal())
+ mdec=md;
+
+ if (md->isFunction() && !md->isStatic() && !md->isPrototype())
+ mdef=md;
+ else if (md->isVariable() && !md->isExternal() && !md->isStatic())
+ mdef=md;
+ }
+ if (mdef && mdec)
+ {
+ ArgumentList *mdefAl = mdef->argumentList();
+ ArgumentList *mdecAl = mdec->argumentList();
+ if (
+ matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
+ mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
+ TRUE
+ )
+ ) /* match found */
+ {
+ MemberSDict *defDict = mdef->getReferencesMembers();
+ MemberSDict *decDict = mdec->getReferencesMembers();
+ if (defDict!=0)
+ {
+ MemberSDict::IteratorDict msdi(*defDict);
+ MemberDef *rmd;
+ for (msdi.toFirst();(rmd=msdi.current());++msdi)
+ {
+ if (decDict==0 || decDict->find(rmd->name())==0)
+ {
+ mdec->addSourceReferences(rmd);
+ }
+ }
+ }
+ if (decDict!=0)
+ {
+ MemberSDict::IteratorDict msdi(*decDict);
+ MemberDef *rmd;
+ for (msdi.toFirst();(rmd=msdi.current());++msdi)
+ {
+ if (defDict==0 || defDict->find(rmd->name())==0)
+ {
+ mdef->addSourceReferences(rmd);
+ }
+ }
+ }
+
+ defDict = mdef->getReferencedByMembers();
+ decDict = mdec->getReferencedByMembers();
+ if (defDict!=0)
+ {
+ MemberSDict::IteratorDict msdi(*defDict);
+ MemberDef *rmd;
+ for (msdi.toFirst();(rmd=msdi.current());++msdi)
+ {
+ if (decDict==0 || decDict->find(rmd->name())==0)
+ {
+ mdec->addSourceReferencedBy(rmd);
+ }
+ }
+ }
+ if (decDict!=0)
+ {
+ MemberSDict::IteratorDict msdi(*decDict);
+ MemberDef *rmd;
+ for (msdi.toFirst();(rmd=msdi.current());++msdi)
+ {
+ if (defDict==0 || defDict->find(rmd->name())==0)
+ {
+ mdef->addSourceReferencedBy(rmd);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void transferRelatedFunctionDocumentation()
+{
+ // find match between function declaration and definition for
+ // related functions
+ MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict);
+ MemberName *mn;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ /* find a matching function declaration and definition for this function */
+ for (mni.toFirst();(md=mni.current());++mni) // for each global function
+ {
+ //printf(" Function `%s'\n",md->name().data());
+ MemberName *rmn;
+ if ((rmn=Doxygen::memberNameSDict->find(md->name()))) // check if there is a member with the same name
+ {
+ //printf(" Member name found\n");
+ MemberDef *rmd;
+ MemberNameIterator rmni(*rmn);
+ for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name
+ {
+ ArgumentList *mdAl = md->argumentList();
+ ArgumentList *rmdAl = rmd->argumentList();
+ //printf(" Member found: related=`%d'\n",rmd->isRelated());
+ if ((rmd->isRelated() || rmd->isForeign()) && // related function
+ matchArguments2( md->getOuterScope(), md->getFileDef(), mdAl,
+ rmd->getOuterScope(),rmd->getFileDef(),rmdAl,
+ TRUE
+ )
+ )
+ {
+ //printf(" Found related member `%s'\n",md->name().data());
+ if (rmd->relatedAlso())
+ md->setRelatedAlso(rmd->relatedAlso());
+ else if (rmd->isForeign())
+ md->makeForeign();
+ else
+ md->makeRelated();
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+/*! make a dictionary of all template arguments of class cd
+ * that are part of the base class name.
+ * Example: A template class A with template arguments <R,S,T>
+ * that inherits from B<T,T,S> will have T and S in the dictionary.
+ */
+static QDict<int> *getTemplateArgumentsInName(ArgumentList *templateArguments,const QCString &name)
+{
+ QDict<int> *templateNames = new QDict<int>(17);
+ templateNames->setAutoDelete(TRUE);
+ static QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
+ if (templateArguments)
+ {
+ ArgumentListIterator ali(*templateArguments);
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,count++)
+ {
+ int i,p=0,l;
+ while ((i=re.match(name,p,&l))!=-1)
+ {
+ QCString n = name.mid(i,l);
+ if (n==arg->name)
+ {
+ if (templateNames->find(n)==0)
+ {
+ templateNames->insert(n,new int(count));
+ }
+ }
+ p=i+l;
+ }
+ }
+ }
+ return templateNames;
+}
+
+/*! Searches a class from within \a context and \a cd and returns its
+ * definition if found (otherwise 0 is returned).
+ */
+static ClassDef *findClassWithinClassContext(Definition *context,ClassDef *cd,const QCString &name)
+{
+ FileDef *fd=cd->getFileDef();
+ ClassDef *result=0;
+ if (context && cd!=context)
+ {
+ result = getResolvedClass(context,0,name,0,0,TRUE,TRUE);
+ }
+ if (result==0)
+ {
+ result = getResolvedClass(cd,fd,name,0,0,TRUE,TRUE);
+ }
+ if (result==0) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
+ {
+ result = getClass(name);
+ }
+ if (result==0 && cd &&
+ (cd->getLanguage()==SrcLangExt_CSharp || cd->getLanguage()==SrcLangExt_Java) &&
+ name.find('<')!=-1)
+ {
+ result = Doxygen::genericsDict->find(name);
+ }
+ //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
+ // name.data(),
+ // context ? context->name().data() : "<none>",
+ // cd ? cd->name().data() : "<none>",
+ // result ? result->name().data() : "<none>",
+ // Doxygen::classSDict->find(name)
+ // );
+ return result;
+}
+
+
+static void findUsedClassesForClass(EntryNav *rootNav,
+ Definition *context,
+ ClassDef *masterCd,
+ ClassDef *instanceCd,
+ bool isArtificial,
+ ArgumentList *actualArgs=0,
+ QDict<int> *templateNames=0
+ )
+{
+ masterCd->visited=TRUE;
+ ArgumentList *formalArgs = masterCd->templateArguments();
+ if (masterCd->memberNameInfoSDict())
+ {
+ MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
+ {
+ //printf(" Found variable %s in class %s\n",md->name().data(),masterCd->name().data());
+ QCString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
+ QCString typedefValue = resolveTypeDef(masterCd,type);
+ if (!typedefValue.isEmpty())
+ {
+ type = typedefValue;
+ }
+ int pos=0;
+ QCString usedClassName;
+ QCString templSpec;
+ bool found=FALSE;
+ // the type can contain template variables, replace them if present
+ if (actualArgs)
+ {
+ type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
+ }
+
+ //printf(" template substitution gives=%s\n",type.data());
+ while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,rootNav->lang())!=-1)
+ {
+ // find the type (if any) that matches usedClassName
+ ClassDef *typeCd = getResolvedClass(masterCd,
+ masterCd->getFileDef(),
+ usedClassName,
+ 0,0,
+ FALSE,TRUE
+ );
+ //printf("====> usedClassName=%s -> typeCd=%s\n",
+ // usedClassName.data(),typeCd?typeCd->name().data():"<none>");
+ if (typeCd)
+ {
+ usedClassName = typeCd->name();
+ }
+
+ int sp=usedClassName.find('<');
+ if (sp==-1) sp=0;
+ int si=usedClassName.findRev("::",sp);
+ if (si!=-1)
+ {
+ // replace any namespace aliases
+ replaceNamespaceAliases(usedClassName,si);
+ }
+ // add any template arguments to the class
+ QCString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
+ //printf(" usedName=%s\n",usedName.data());
+
+ bool delTempNames=FALSE;
+ if (templateNames==0)
+ {
+ templateNames = getTemplateArgumentsInName(formalArgs,usedName);
+ delTempNames=TRUE;
+ }
+ BaseInfo bi(usedName,Public,Normal);
+ findClassRelation(rootNav,context,instanceCd,&bi,templateNames,TemplateInstances,isArtificial);
+
+ if (masterCd->templateArguments())
+ {
+ ArgumentListIterator ali(*masterCd->templateArguments());
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,++count)
+ {
+ if (arg->name==usedName) // type is a template argument
+ {
+ found=TRUE;
+ Debug::print(Debug::Classes,0," New used class `%s'\n", usedName.data());
+
+ ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName);
+ if (usedCd==0)
+ {
+ usedCd = new ClassDef(
+ masterCd->getDefFileName(),masterCd->getDefLine(),
+ masterCd->getDefColumn(),
+ usedName,
+ ClassDef::Class);
+ //printf("making %s a template argument!!!\n",usedCd->name().data());
+ usedCd->makeTemplateArgument();
+ usedCd->setUsedOnly(TRUE);
+ usedCd->setLanguage(masterCd->getLanguage());
+ Doxygen::hiddenClasses->append(usedName,usedCd);
+ }
+ if (usedCd)
+ {
+ if (isArtificial) usedCd->setArtificial(TRUE);
+ Debug::print(Debug::Classes,0," Adding used class `%s' (1)\n", usedCd->name().data());
+ instanceCd->addUsedClass(usedCd,md->name(),md->protection());
+ usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
+ }
+ }
+ }
+ }
+
+ if (!found)
+ {
+ ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
+ //printf("Looking for used class %s: result=%s master=%s\n",
+ // usedName.data(),usedCd?usedCd->name().data():"<none>",masterCd?masterCd->name().data():"<none>");
+
+ if (usedCd)
+ {
+ found=TRUE;
+ Debug::print(Debug::Classes,0," Adding used class `%s' (2)\n", usedCd->name().data());
+ instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
+ usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
+ }
+ }
+ if (delTempNames)
+ {
+ delete templateNames;
+ templateNames=0;
+ }
+ }
+ if (!found && !type.isEmpty()) // used class is not documented in any scope
+ {
+ ClassDef *usedCd = Doxygen::hiddenClasses->find(type);
+ if (usedCd==0 && !Config_getBool("HIDE_UNDOC_RELATIONS"))
+ {
+ if (type.right(2)=="(*" || type.right(2)=="(^") // type is a function pointer
+ {
+ type+=md->argsString();
+ }
+ Debug::print(Debug::Classes,0," New undocumented used class `%s'\n", type.data());
+ usedCd = new ClassDef(
+ masterCd->getDefFileName(),masterCd->getDefLine(),
+ masterCd->getDefColumn(),
+ type,ClassDef::Class);
+ usedCd->setUsedOnly(TRUE);
+ usedCd->setLanguage(masterCd->getLanguage());
+ Doxygen::hiddenClasses->append(type,usedCd);
+ }
+ if (usedCd)
+ {
+ if (isArtificial) usedCd->setArtificial(TRUE);
+ Debug::print(Debug::Classes,0," Adding used class `%s' (3)\n", usedCd->name().data());
+ instanceCd->addUsedClass(usedCd,md->name(),md->protection());
+ usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ //printf("no members for class %s (%p)\n",masterCd->name().data(),masterCd);
+ }
+}
+
+static void findBaseClassesForClass(
+ EntryNav *rootNav,
+ Definition *context,
+ ClassDef *masterCd,
+ ClassDef *instanceCd,
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial,
+ ArgumentList *actualArgs=0,
+ QDict<int> *templateNames=0
+ )
+{
+ Entry *root = rootNav->entry();
+ //if (masterCd->visited) return;
+ masterCd->visited=TRUE;
+ // The base class could ofcouse also be a non-nested class
+ ArgumentList *formalArgs = masterCd->templateArguments();
+ QListIterator<BaseInfo> bii(*root->extends);
+ BaseInfo *bi=0;
+ for (bii.toFirst();(bi=bii.current());++bii)
+ {
+ //printf("masterCd=%s bi->name='%s' #actualArgs=%d\n",
+ // masterCd->localName().data(),bi->name.data(),actualArgs?(int)actualArgs->count():-1);
+ bool delTempNames=FALSE;
+ if (templateNames==0)
+ {
+ templateNames = getTemplateArgumentsInName(formalArgs,bi->name);
+ delTempNames=TRUE;
+ }
+ BaseInfo tbi(bi->name,bi->prot,bi->virt);
+ if (actualArgs) // substitute the formal template arguments of the base class
+ {
+ tbi.name = substituteTemplateArgumentsInString(bi->name,formalArgs,actualArgs);
+ }
+ //printf("bi->name=%s tbi.name=%s\n",bi->name.data(),tbi.name.data());
+
+ if (mode==DocumentedOnly)
+ {
+ // find a documented base class in the correct scope
+ if (!findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,DocumentedOnly,isArtificial))
+ {
+ // 1.8.2: decided to show inheritance relations even if not documented,
+ // we do make them artificial, so they do not appear in the index
+ //if (!Config_getBool("HIDE_UNDOC_RELATIONS"))
+ bool b = Config_getBool("HIDE_UNDOC_RELATIONS") ? TRUE : isArtificial;
+ //{
+ // no documented base class -> try to find an undocumented one
+ findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,Undocumented,b);
+ //}
+ }
+ }
+ else if (mode==TemplateInstances)
+ {
+ findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,TemplateInstances,isArtificial);
+ }
+ if (delTempNames)
+ {
+ delete templateNames;
+ templateNames=0;
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static bool findTemplateInstanceRelation(Entry *root,
+ Definition *context,
+ ClassDef *templateClass,const QCString &templSpec,
+ QDict<int> *templateNames,
+ bool isArtificial)
+{
+ Debug::print(Debug::Classes,0," derived from template %s with parameters %s\n",
+ templateClass->name().data(),templSpec.data());
+ //printf("findTemplateInstanceRelation(base=%s templSpec=%s templateNames=",
+ // templateClass->name().data(),templSpec.data());
+ //if (templateNames)
+ //{
+ // QDictIterator<int> qdi(*templateNames);
+ // int *tempArgIndex;
+ // for (;(tempArgIndex=qdi.current());++qdi)
+ // {
+ // printf("(%s->%d) ",qdi.currentKey(),*tempArgIndex);
+ // }
+ //}
+ //printf("\n");
+
+ bool existingClass = (templSpec ==
+ tempArgListToString(templateClass->templateArguments())
+ );
+ if (existingClass) return TRUE;
+
+ bool freshInstance=FALSE;
+ ClassDef *instanceClass = templateClass->insertTemplateInstance(
+ root->fileName,root->startLine,root->startColumn,templSpec,freshInstance);
+ if (isArtificial) instanceClass->setArtificial(TRUE);
+ instanceClass->setLanguage(root->lang);
+
+ if (freshInstance)
+ {
+ Debug::print(Debug::Classes,0," found fresh instance '%s'!\n",instanceClass->name().data());
+ Doxygen::classSDict->append(instanceClass->name(),instanceClass);
+ instanceClass->setTemplateBaseClassNames(templateNames);
+
+ // search for new template instances caused by base classes of
+ // instanceClass
+ EntryNav *templateRootNav = g_classEntries.find(templateClass->name());
+ if (templateRootNav)
+ {
+ bool unloadNeeded=FALSE;
+ Entry *templateRoot = templateRootNav->entry();
+ if (templateRoot==0) // not yet loaded
+ {
+ templateRootNav->loadEntry(g_storage);
+ templateRoot = templateRootNav->entry();
+ ASSERT(templateRoot!=0); // now it should really be loaded
+ unloadNeeded=TRUE;
+ }
+
+ Debug::print(Debug::Classes,0," template root found %s templSpec=%s!\n",
+ templateRoot->name.data(),templSpec.data());
+ ArgumentList *templArgs = new ArgumentList;
+ stringToArgumentList(templSpec,templArgs);
+ findBaseClassesForClass(templateRootNav,context,templateClass,instanceClass,
+ TemplateInstances,isArtificial,templArgs,templateNames);
+
+ findUsedClassesForClass(templateRootNav,context,templateClass,instanceClass,
+ isArtificial,templArgs,templateNames);
+ delete templArgs;
+
+ if (unloadNeeded) // still cleanup to do
+ {
+ templateRootNav->releaseEntry();
+ }
+ }
+ else
+ {
+ Debug::print(Debug::Classes,0," no template root entry found!\n");
+ // TODO: what happened if we get here?
+ }
+
+ //Debug::print(Debug::Classes,0," Template instance %s : \n",instanceClass->name().data());
+ //ArgumentList *tl = templateClass->templateArguments();
+ }
+ else
+ {
+ Debug::print(Debug::Classes,0," instance already exists!\n");
+ }
+ return TRUE;
+}
+
+static bool isRecursiveBaseClass(const QCString &scope,const QCString &name)
+{
+ QCString n=name;
+ int index=n.find('<');
+ if (index!=-1)
+ {
+ n=n.left(index);
+ }
+ bool result = rightScopeMatch(scope,n);
+ return result;
+}
+
+/*! Searches for the end of a template in prototype \a s starting from
+ * character position \a startPos. If the end was found the position
+ * of the closing \> is returned, otherwise -1 is returned.
+ *
+ * Handles exotic cases such as
+ * \code
+ * Class<(id<0)>
+ * Class<bits<<2>
+ * Class<"<">
+ * Class<'<'>
+ * Class<(")<")>
+ * \endcode
+ */
+static int findEndOfTemplate(const QCString &s,int startPos)
+{
+ // locate end of template
+ int e=startPos;
+ int brCount=1;
+ int roundCount=0;
+ int len = s.length();
+ bool insideString=FALSE;
+ bool insideChar=FALSE;
+ char pc = 0;
+ while (e<len && brCount!=0)
+ {
+ char c=s.at(e);
+ switch(c)
+ {
+ case '<':
+ if (!insideString && !insideChar)
+ {
+ if (e<len-1 && s.at(e+1)=='<')
+ e++;
+ else if (roundCount==0)
+ brCount++;
+ }
+ break;
+ case '>':
+ if (!insideString && !insideChar)
+ {
+ if (e<len-1 && s.at(e+1)=='>')
+ e++;
+ else if (roundCount==0)
+ brCount--;
+ }
+ break;
+ case '(':
+ if (!insideString && !insideChar)
+ roundCount++;
+ break;
+ case ')':
+ if (!insideString && !insideChar)
+ roundCount--;
+ break;
+ case '"':
+ if (!insideChar)
+ {
+ if (insideString && pc!='\\')
+ insideString=FALSE;
+ else
+ insideString=TRUE;
+ }
+ break;
+ case '\'':
+ if (!insideString)
+ {
+ if (insideChar && pc!='\\')
+ insideChar=FALSE;
+ else
+ insideChar=TRUE;
+ }
+ break;
+ }
+ pc = c;
+ e++;
+ }
+ return brCount==0 ? e : -1;
+}
+
+static bool findClassRelation(
+ EntryNav *rootNav,
+ Definition *context,
+ ClassDef *cd,
+ BaseInfo *bi,
+ QDict<int> *templateNames,
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial
+ )
+{
+ //printf("findClassRelation(class=%s base=%s templateNames=",
+ // cd->name().data(),bi->name.data());
+ //if (templateNames)
+ //{
+ // QDictIterator<int> qdi(*templateNames);
+ // int *tempArgIndex;
+ // for (;(tempArgIndex=qdi.current());++qdi)
+ // {
+ // printf("(%s->%d) ",qdi.currentKey(),*tempArgIndex);
+ // }
+ //}
+ //printf("\n");
+
+ Entry *root = rootNav->entry();
+
+ QCString biName=bi->name;
+ bool explicitGlobalScope=FALSE;
+ //printf("findClassRelation: biName=`%s'\n",biName.data());
+ if (biName.left(2)=="::") // explicit global scope
+ {
+ biName=biName.right(biName.length()-2);
+ explicitGlobalScope=TRUE;
+ }
+
+ EntryNav *parentNode=rootNav->parent();
+ bool lastParent=FALSE;
+ do // for each parent scope, starting with the largest scope
+ // (in case of nested classes)
+ {
+ QCString scopeName= parentNode ? parentNode->name().data() : "";
+ int scopeOffset=explicitGlobalScope ? 0 : scopeName.length();
+ do // try all parent scope prefixes, starting with the largest scope
+ {
+ //printf("scopePrefix=`%s' biName=`%s'\n",
+ // scopeName.left(scopeOffset).data(),biName.data());
+
+ QCString baseClassName=biName;
+ if (scopeOffset>0)
+ {
+ baseClassName.prepend(scopeName.left(scopeOffset)+"::");
+ }
+ //QCString stripped;
+ //baseClassName=stripTemplateSpecifiersFromScope
+ // (removeRedundantWhiteSpace(baseClassName),TRUE,
+ // &stripped);
+ MemberDef *baseClassTypeDef=0;
+ QCString templSpec;
+ ClassDef *baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context,
+ cd->getFileDef(),
+ baseClassName,
+ &baseClassTypeDef,
+ &templSpec,
+ mode==Undocumented,
+ TRUE
+ );
+ //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
+ // baseClassName.data(),baseClass,cd,explicitGlobalScope);
+ //printf(" scope=`%s' baseClassName=`%s' baseClass=%s templSpec=%s\n",
+ // cd ? cd->name().data():"<none>",
+ // baseClassName.data(),
+ // baseClass?baseClass->name().data():"<none>",
+ // templSpec.data()
+ // );
+ //if (baseClassName.left(root->name.length())!=root->name ||
+ // baseClassName.at(root->name.length())!='<'
+ // ) // Check for base class with the same name.
+ // // If found then look in the outer scope for a match
+ // // and prevent recursion.
+ if (!isRecursiveBaseClass(rootNav->name(),baseClassName)
+ || explicitGlobalScope
+ // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
+ // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
+ || (rootNav->lang()==SrcLangExt_IDL &&
+ (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC ||
+ rootNav->section()==Entry::INCLUDED_SERVICE_SEC)))
+ {
+ Debug::print(
+ Debug::Classes,0," class relation %s inherited/used by %s found (%s and %s) templSpec='%s'\n",
+ baseClassName.data(),
+ rootNav->name().data(),
+ (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"),
+ (bi->virt==Normal)?"normal":"virtual",
+ templSpec.data()
+ );
+
+ int i=baseClassName.find('<');
+ int si=baseClassName.findRev("::",i==-1 ? baseClassName.length() : i);
+ if (si==-1) si=0;
+ if (baseClass==0 && (root->lang==SrcLangExt_CSharp || root->lang==SrcLangExt_Java))
+ {
+ baseClass = Doxygen::genericsDict->find(baseClassName);
+ //printf("looking for '%s' result=%p\n",baseClassName.data(),baseClass);
+ }
+ if (baseClass==0 && i!=-1)
+ // base class has template specifiers
+ {
+ // TODO: here we should try to find the correct template specialization
+ // but for now, we only look for the unspecializated base class.
+ int e=findEndOfTemplate(baseClassName,i+1);
+ //printf("baseClass==0 i=%d e=%d\n",i,e);
+ if (e!=-1) // end of template was found at e
+ {
+ templSpec=removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
+ baseClassName=baseClassName.left(i)+baseClassName.right(baseClassName.length()-e);
+ baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context,
+ cd->getFileDef(),
+ baseClassName,
+ &baseClassTypeDef,
+ 0, //&templSpec,
+ mode==Undocumented,
+ TRUE
+ );
+ //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
+ // baseClass,baseClassName.data(),templSpec.data());
+ }
+ }
+ else if (baseClass && !templSpec.isEmpty()) // we have a known class, but also
+ // know it is a template, so see if
+ // we can also link to the explicit
+ // instance (for instance if a class
+ // derived from a template argument)
+ {
+ //printf("baseClass=%p templSpec=%s\n",baseClass,templSpec.data());
+ ClassDef *templClass=getClass(baseClass->name()+templSpec);
+ if (templClass)
+ {
+ // use the template instance instead of the template base.
+ baseClass = templClass;
+ templSpec.resize(0);
+ }
+ }
+
+ //printf("cd=%p baseClass=%p\n",cd,baseClass);
+ bool found=baseClass!=0 && (baseClass!=cd || mode==TemplateInstances);
+ //printf("1. found=%d\n",found);
+ if (!found && si!=-1)
+ {
+ QCString tmpTemplSpec;
+ // replace any namespace aliases
+ replaceNamespaceAliases(baseClassName,si);
+ baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context,
+ cd->getFileDef(),
+ baseClassName,
+ &baseClassTypeDef,
+ &tmpTemplSpec,
+ mode==Undocumented,
+ TRUE
+ );
+ found=baseClass!=0 && baseClass!=cd;
+ if (found) templSpec = tmpTemplSpec;
+ }
+ //printf("2. found=%d\n",found);
+
+ //printf("root->name=%s biName=%s baseClassName=%s\n",
+ // root->name.data(),biName.data(),baseClassName.data());
+ //if (cd->isCSharp() && i!=-1) // C# generic -> add internal -g postfix
+ //{
+ // baseClassName+="-g";
+ //}
+
+ if (!found)
+ {
+ baseClass=findClassWithinClassContext(context,cd,baseClassName);
+ //printf("findClassWithinClassContext(%s,%s)=%p\n",
+ // cd->name().data(),baseClassName.data(),baseClass);
+ found = baseClass!=0 && baseClass!=cd;
+
+ }
+ if (!found)
+ {
+ // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
+ // the class name also in the alias mapping.
+ QCString *aliasName = Doxygen::namespaceAliasDict[baseClassName];
+ if (aliasName) // see if it is indeed a class.
+ {
+ baseClass=getClass(*aliasName);
+ found = baseClass!=0 && baseClass!=cd;
+ }
+ }
+ bool isATemplateArgument = templateNames!=0 && templateNames->find(biName)!=0;
+ // make templSpec canonical
+ // warning: the following line doesn't work for Mixin classes (see bug 560623)
+ // templSpec = getCanonicalTemplateSpec(cd, cd->getFileDef(), templSpec);
+
+ //printf("3. found=%d\n",found);
+ if (found)
+ {
+ Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",biName.data(),templSpec.isEmpty()?"":templSpec.data());
+ // add base class to this class
+
+ // if templSpec is not empty then we should "instantiate"
+ // the template baseClass. A new ClassDef should be created
+ // to represent the instance. To be able to add the (instantiated)
+ // members and documentation of a template class
+ // (inserted in that template class at a later stage),
+ // the template should know about its instances.
+ // the instantiation process, should be done in a recursive way,
+ // since instantiating a template may introduce new inheritance
+ // relations.
+ if (!templSpec.isEmpty() && mode==TemplateInstances)
+ {
+ // if baseClass is actually a typedef then we should not
+ // instantiate it, since typedefs are in a different namespace
+ // see bug531637 for an example where this would otherwise hang
+ // doxygen
+ if (baseClassTypeDef==0)
+ {
+ //printf(" => findTemplateInstanceRelation: %p\n",baseClassTypeDef);
+ findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,isArtificial);
+ }
+ }
+ else if (mode==DocumentedOnly || mode==Undocumented)
+ {
+ //printf(" => insert base class\n");
+ QCString usedName;
+ if (baseClassTypeDef || cd->isCSharp())
+ {
+ usedName=biName;
+ //printf("***** usedName=%s templSpec=%s\n",usedName.data(),templSpec.data());
+ }
+ static bool sipSupport = Config_getBool("SIP_SUPPORT");
+ if (sipSupport) bi->prot=Public;
+ if (!cd->isSubClass(baseClass)) // check for recursion, see bug690787
+ {
+ cd->insertBaseClass(baseClass,usedName,bi->prot,bi->virt,templSpec);
+ // add this class as super class to the base class
+ baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
+ }
+ else
+ {
+ warn(root->fileName,root->startLine,
+ "Detected potential recursive class relation "
+ "between class %s and base class %s!",
+ cd->name().data(),baseClass->name().data()
+ );
+ }
+ }
+ return TRUE;
+ }
+ else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
+ {
+ Debug::print(Debug::Classes,0,
+ " New undocumented base class `%s' baseClassName=%s templSpec=%s isArtificial=%d\n",
+ biName.data(),baseClassName.data(),templSpec.data(),isArtificial
+ );
+ baseClass=0;
+ if (isATemplateArgument)
+ {
+ baseClass=Doxygen::hiddenClasses->find(baseClassName);
+ if (baseClass==0)
+ {
+ baseClass=new ClassDef(root->fileName,root->startLine,root->startColumn,
+ baseClassName,
+ ClassDef::Class);
+ Doxygen::hiddenClasses->append(baseClassName,baseClass);
+ if (isArtificial) baseClass->setArtificial(TRUE);
+ baseClass->setLanguage(root->lang);
+ }
+ }
+ else
+ {
+ baseClass=Doxygen::classSDict->find(baseClassName);
+ //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
+ // baseClassName.data(),baseClass,biName.data(),templSpec.data());
+ if (baseClass==0)
+ {
+ baseClass=new ClassDef(root->fileName,root->startLine,root->startColumn,
+ baseClassName,
+ ClassDef::Class);
+ Doxygen::classSDict->append(baseClassName,baseClass);
+ if (isArtificial) baseClass->setArtificial(TRUE);
+ baseClass->setLanguage(root->lang);
+ int si = baseClassName.findRev("::");
+ if (si!=-1) // class is nested
+ {
+ Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,rootNav->tagInfo());
+ if (sd==0 || sd==Doxygen::globalScope) // outer scope not found
+ {
+ baseClass->setArtificial(TRUE); // see bug678139
+ }
+ }
+ }
+ }
+ if (biName.right(2)=="-p")
+ {
+ biName="<"+biName.left(biName.length()-2)+">";
+ }
+ // add base class to this class
+ cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
+ // add this class as super class to the base class
+ baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
+ // the undocumented base was found in this file
+ baseClass->insertUsedFile(rootNav->fileDef());
+ baseClass->setOuterScope(Doxygen::globalScope);
+ if (baseClassName.right(2)=="-p")
+ {
+ baseClass->setCompoundType(ClassDef::Protocol);
+ }
+ return TRUE;
+ }
+ else
+ {
+ Debug::print(Debug::Classes,0," Base class `%s' not found\n",biName.data());
+ }
+ }
+ else
+ {
+ if (mode!=TemplateInstances)
+ {
+ warn(root->fileName,root->startLine,
+ "Detected potential recursive class relation "
+ "between class %s and base class %s!\n",
+ root->name.data(),baseClassName.data()
+ );
+ }
+ // for mode==TemplateInstance this case is quite common and
+ // indicates a relation between a template class and a template
+ // instance with the same name.
+ }
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
+ {
+ scopeOffset=0;
+ }
+ //printf("new scopeOffset=`%d'",scopeOffset);
+ } while (scopeOffset>=0);
+
+ if (parentNode==0)
+ {
+ lastParent=TRUE;
+ }
+ else
+ {
+ parentNode=parentNode->parent();
+ }
+ } while (lastParent);
+
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+// Computes the base and super classes for each class in the tree
+
+static bool isClassSection(EntryNav *rootNav)
+{
+ if ( !rootNav->name().isEmpty() )
+ {
+ if (rootNav->section() & Entry::COMPOUND_MASK)
+ // is it a compound (class, struct, union, interface ...)
+ {
+ return TRUE;
+ }
+ else if (rootNav->section() & Entry::COMPOUNDDOC_MASK)
+ // is it a documentation block with inheritance info.
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+ bool extends = root->extends->count()>0;
+ rootNav->releaseEntry();
+ if (extends) return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/*! Builds a dictionary of all entry nodes in the tree starting with \a root
+ */
+static void findClassEntries(EntryNav *rootNav)
+{
+ if (isClassSection(rootNav))
+ {
+ g_classEntries.insert(rootNav->name(),rootNav);
+ }
+ RECURSE_ENTRYTREE(findClassEntries,rootNav);
+}
+
+/*! Using the dictionary build by findClassEntries(), this
+ * function will look for additional template specialization that
+ * exists as inheritance relations only. These instances will be
+ * added to the template they are derived from.
+ */
+static void findInheritedTemplateInstances()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<EntryNav> edi(g_classEntries);
+ EntryNav *rootNav;
+ for (;(rootNav=edi.current());++edi)
+ {
+ ClassDef *cd;
+ // strip any anonymous scopes first
+ QCString bName=stripAnonymousNamespaceScope(rootNav->name());
+ bName=stripTemplateSpecifiersFromScope(bName);
+ Debug::print(Debug::Classes,0," Inheritance: Class %s : \n",bName.data());
+ if ((cd=getClass(bName)))
+ {
+ rootNav->loadEntry(g_storage);
+ //printf("Class %s %d\n",cd->name().data(),root->extends->count());
+ findBaseClassesForClass(rootNav,cd,cd,cd,TemplateInstances,FALSE);
+ rootNav->releaseEntry();
+ }
+ }
+}
+
+static void findUsedTemplateInstances()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<EntryNav> edi(g_classEntries);
+ EntryNav *rootNav;
+ for (;(rootNav=edi.current());++edi)
+ {
+ ClassDef *cd;
+ // strip any anonymous scopes first
+ QCString bName=stripAnonymousNamespaceScope(rootNav->name());
+ bName=stripTemplateSpecifiersFromScope(bName);
+ Debug::print(Debug::Classes,0," Usage: Class %s : \n",bName.data());
+ if ((cd=getClass(bName)))
+ {
+ rootNav->loadEntry(g_storage);
+ findUsedClassesForClass(rootNav,cd,cd,cd,TRUE);
+ rootNav->releaseEntry();
+ }
+ }
+}
+
+static void computeClassRelations()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<EntryNav> edi(g_classEntries);
+ EntryNav *rootNav;
+ for (;(rootNav=edi.current());++edi)
+ {
+ ClassDef *cd;
+
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ // strip any anonymous scopes first
+ QCString bName=stripAnonymousNamespaceScope(rootNav->name());
+ bName=stripTemplateSpecifiersFromScope(bName);
+ Debug::print(Debug::Classes,0," Relations: Class %s : \n",bName.data());
+ if ((cd=getClass(bName)))
+ {
+ findBaseClassesForClass(rootNav,cd,cd,cd,DocumentedOnly,FALSE);
+ }
+ int numMembers = cd && cd->memberNameInfoSDict() ? cd->memberNameInfoSDict()->count() : 0;
+ if ((cd==0 || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 &&
+ bName.right(2)!="::")
+ {
+ if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
+ (guessSection(root->fileName)==Entry::HEADER_SEC ||
+ Config_getBool("EXTRACT_LOCAL_CLASSES")) && // not defined in source file
+ protectionLevelVisible(root->protection) && // hidden by protection
+ !Config_getBool("HIDE_UNDOC_CLASSES") // undocumented class are visible
+ )
+ warn_undoc(
+ root->fileName,root->startLine,
+ "Compound %s is not documented.",
+ root->name.data()
+ );
+ }
+
+ rootNav->releaseEntry();
+ }
+}
+
+static void computeTemplateClassRelations()
+{
+ QDictIterator<EntryNav> edi(g_classEntries);
+ EntryNav *rootNav;
+ for (;(rootNav=edi.current());++edi)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ QCString bName=stripAnonymousNamespaceScope(root->name);
+ bName=stripTemplateSpecifiersFromScope(bName);
+ ClassDef *cd=getClass(bName);
+ // strip any anonymous scopes first
+ QDict<ClassDef> *templInstances = 0;
+ if (cd && (templInstances=cd->getTemplateInstances()))
+ {
+ Debug::print(Debug::Classes,0," Template class %s : \n",cd->name().data());
+ QDictIterator<ClassDef> tdi(*templInstances);
+ ClassDef *tcd;
+ for (tdi.toFirst();(tcd=tdi.current());++tdi) // for each template instance
+ {
+ Debug::print(Debug::Classes,0," Template instance %s : \n",tcd->name().data());
+ QCString templSpec = tdi.currentKey();
+ ArgumentList *templArgs = new ArgumentList;
+ stringToArgumentList(templSpec,templArgs);
+ QList<BaseInfo> *baseList=root->extends;
+ QListIterator<BaseInfo> it(*baseList);
+ BaseInfo *bi;
+ for (;(bi=it.current());++it) // for each base class of the template
+ {
+ // check if the base class is a template argument
+ BaseInfo tbi(bi->name,bi->prot,bi->virt);
+ ArgumentList *tl = cd->templateArguments();
+ if (tl)
+ {
+ QDict<int> *baseClassNames = tcd->getTemplateBaseClassNames();
+ QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi->name);
+ // for each template name that we inherit from we need to
+ // substitute the formal with the actual arguments
+ QDict<int> *actualTemplateNames = new QDict<int>(17);
+ actualTemplateNames->setAutoDelete(TRUE);
+ QDictIterator<int> qdi(*templateNames);
+ for (qdi.toFirst();qdi.current();++qdi)
+ {
+ int templIndex = *qdi.current();
+ Argument *actArg = 0;
+ if (templIndex<(int)templArgs->count())
+ {
+ actArg=templArgs->at(templIndex);
+ }
+ if (actArg!=0 &&
+ baseClassNames!=0 &&
+ baseClassNames->find(actArg->type)!=0 &&
+ actualTemplateNames->find(actArg->type)==0
+ )
+ {
+ actualTemplateNames->insert(actArg->type,new int(templIndex));
+ }
+ }
+ delete templateNames;
+
+ tbi.name = substituteTemplateArgumentsInString(bi->name,tl,templArgs);
+ // find a documented base class in the correct scope
+ if (!findClassRelation(rootNav,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
+ {
+ // no documented base class -> try to find an undocumented one
+ findClassRelation(rootNav,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
+ }
+ delete actualTemplateNames;
+ }
+ }
+ delete templArgs;
+ } // class has no base classes
+ }
+
+ rootNav->releaseEntry();
+ }
+}
+
+//-----------------------------------------------------------------------
+// compute the references (anchors in HTML) for each function in the file
+
+static void computeMemberReferences()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ cd->computeAnchors();
+ }
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ fd->computeAnchors();
+ }
+ }
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd=0;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ nd->computeAnchors();
+ }
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->computeAnchors();
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void addListReferences()
+{
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ MemberName *mn=0;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ md->visited=FALSE;
+ }
+ }
+ MemberNameSDict::Iterator fmnli(*Doxygen::functionNameSDict);
+ for (fmnli.toFirst();(mn=fmnli.current());++fmnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ md->visited=FALSE;
+ }
+ }
+
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ cd->addListReferences();
+ }
+
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ fd->addListReferences();
+ }
+ }
+
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd=0;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ nd->addListReferences();
+ }
+
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->addListReferences();
+ }
+
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ QCString name = pd->getOutputFileBase();
+ if (pd->getGroupDef())
+ {
+ name = pd->getGroupDef()->getOutputFileBase();
+ }
+ {
+ QList<ListItemInfo> *xrefItems = pd->xrefListItems();
+ addRefItem(xrefItems,
+ name,
+ theTranslator->trPage(TRUE,TRUE),
+ name,pd->title(),0);
+ }
+ }
+
+ DirSDict::Iterator ddi(*Doxygen::directories);
+ DirDef *dd = 0;
+ for (ddi.toFirst();(dd=ddi.current());++ddi)
+ {
+ QCString name = dd->getOutputFileBase();
+ //if (dd->getGroupDef())
+ //{
+ // name = dd->getGroupDef()->getOutputFileBase();
+ //}
+ QList<ListItemInfo> *xrefItems = dd->xrefListItems();
+ addRefItem(xrefItems,
+ name,
+ theTranslator->trDir(TRUE,TRUE),
+ name,dd->displayName(),0);
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void generateXRefPages()
+{
+ QDictIterator<RefList> di(*Doxygen::xrefLists);
+ RefList *rl;
+ for (di.toFirst();(rl=di.current());++di)
+ {
+ rl->generatePage();
+ }
+}
+
+//----------------------------------------------------------------------
+// Copy the documentation in entry `root' to member definition `md' and
+// set the function declaration of the member to `funcDecl'. If the boolean
+// over_load is set the standard overload text is added.
+
+static void addMemberDocs(EntryNav *rootNav,
+ MemberDef *md, const char *funcDecl,
+ ArgumentList *al,
+ bool over_load,
+ NamespaceSDict *
+ )
+{
+ Entry *root = rootNav->entry();
+ //printf("addMemberDocs: `%s'::`%s' `%s' funcDecl=`%s' mSpec=%d\n",
+ // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl,root->spec);
+ QCString fDecl=funcDecl;
+ // strip extern specifier
+ fDecl.stripPrefix("extern ");
+ md->setDefinition(fDecl);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ ClassDef *cd=md->getClassDef();
+ NamespaceDef *nd=md->getNamespaceDef();
+ QCString fullName;
+ if (cd)
+ fullName = cd->name();
+ else if (nd)
+ fullName = nd->name();
+
+ if (!fullName.isEmpty()) fullName+="::";
+ fullName+=md->name();
+ FileDef *rfd=rootNav->fileDef();
+
+ // TODO determine scope based on root not md
+ Definition *rscope = md->getOuterScope();
+
+ ArgumentList *mdAl = md->argumentList();
+ if (al)
+ {
+ //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
+ mergeArguments(mdAl,al,!root->doc.isEmpty());
+ }
+ else
+ {
+ if (
+ matchArguments2( md->getOuterScope(), md->getFileDef(), mdAl,
+ rscope,rfd,root->argList,
+ TRUE
+ )
+ )
+ {
+ //printf("merging arguments (2)\n");
+ mergeArguments(mdAl,root->argList,!root->doc.isEmpty());
+ }
+ }
+ if (over_load) // the \overload keyword was used
+ {
+ QCString doc=getOverloadDocs();
+ if (!root->doc.isEmpty())
+ {
+ doc+="<p>";
+ doc+=root->doc;
+ }
+ md->setDocumentation(doc,root->docFile,root->docLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ }
+ else
+ {
+ //printf("overwrite!\n");
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+
+ //printf("overwrite!\n");
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+
+ if (
+ (md->inbodyDocumentation().isEmpty() ||
+ !rootNav->parent()->name().isEmpty()
+ ) && !root->inbodyDocs.isEmpty()
+ )
+ {
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ }
+ }
+
+ //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
+ // md->initializer().data(),md->initializer().isEmpty(),
+ // root->initializer.data(),root->initializer.isEmpty()
+ // );
+ if (md->initializer().isEmpty() && !root->initializer.isEmpty())
+ {
+ //printf("setInitializer\n");
+ md->setInitializer(root->initializer);
+ }
+
+ md->setMaxInitLines(root->initLines);
+
+ if (rfd)
+ {
+ if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
+ )
+ {
+ //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(rfd);
+ }
+
+ md->setRefItems(root->sli);
+ }
+
+ md->enableCallGraph(md->hasCallGraph() || root->callGraph);
+ md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph);
+
+ md->mergeMemberSpecifiers(root->spec);
+ md->addSectionsToDefinition(root->anchors);
+ addMemberToGroups(root,md);
+ if (cd) cd->insertUsedFile(rfd);
+ //printf("root->mGrpId=%d\n",root->mGrpId);
+ if (root->mGrpId!=-1)
+ {
+ if (md->getMemberGroupId()!=-1)
+ {
+ if (md->getMemberGroupId()!=root->mGrpId)
+ {
+ warn(
+ root->fileName,root->startLine,
+ "member %s belongs to two different groups. The second "
+ "one found here will be ignored.",
+ md->name().data()
+ );
+ }
+ }
+ else // set group id
+ {
+ //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,md->name().data());
+ md->setMemberGroupId(root->mGrpId);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+// find a class definition given the scope name and (optionally) a
+// template list specifier
+
+static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd,
+ const char *scopeName)
+{
+ ClassDef *tcd = getResolvedClass(nd,fd,scopeName,0,0,TRUE,TRUE);
+ return tcd;
+}
+
+
+//----------------------------------------------------------------------
+// Adds the documentation contained in `root' to a global function
+// with name `name' and argument list `args' (for overloading) and
+// function declaration `decl' to the corresponding member definition.
+
+static bool findGlobalMember(EntryNav *rootNav,
+ const QCString &namespaceName,
+ const char *type,
+ const char *name,
+ const char *tempArg,
+ const char *,
+ const char *decl)
+{
+ Entry *root = rootNav->entry();
+ Debug::print(Debug::FindMembers,0,
+ "2. findGlobalMember(namespace=%s,type=%s,name=%s,tempArg=%s,decl=%s)\n",
+ namespaceName.data(),type,name,tempArg,decl);
+ QCString n=name;
+ if (n.isEmpty()) return FALSE;
+ if (n.find("::")!=-1) return FALSE; // skip undefined class members
+ MemberName *mn=Doxygen::functionNameSDict->find(n+tempArg); // look in function dictionary
+ if (mn==0)
+ {
+ mn=Doxygen::functionNameSDict->find(n); // try without template arguments
+ }
+ if (mn) // function name defined
+ {
+ Debug::print(Debug::FindMembers,0,"3. Found symbol scope\n");
+ //int count=0;
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ bool found=FALSE;
+ for (mni.toFirst();(md=mni.current()) && !found;++mni)
+ {
+ NamespaceDef *nd=md->getNamespaceDef();
+
+ //printf("Namespace namespaceName=%s nd=%s\n",
+ // namespaceName.data(),nd ? nd->name().data() : "<none>");
+
+ FileDef *fd=rootNav->fileDef();
+ //printf("File %s\n",fd ? fd->name().data() : "<none>");
+ NamespaceSDict *nl = fd ? fd->getUsedNamespaces() : 0;
+ //SDict<Definition> *cl = fd ? fd->getUsedClasses() : 0;
+ //printf("NamespaceList %p\n",nl);
+
+ // search in the list of namespaces that are imported via a
+ // using declaration
+ bool viaUsingDirective = nl && nd && nl->find(nd->qualifiedName())!=0;
+
+ if ((namespaceName.isEmpty() && nd==0) || // not in a namespace
+ (nd && nd->name()==namespaceName) || // or in the same namespace
+ viaUsingDirective // member in `using' namespace
+ )
+ {
+ Debug::print(Debug::FindMembers,0,"4. Try to add member `%s' to scope `%s'\n",
+ md->name().data(),namespaceName.data());
+ QCString nsName = nd ? nd->name().data() : "";
+
+ NamespaceDef *rnd = 0;
+ if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName);
+
+ ArgumentList *mdAl = md->argumentList();
+ bool matching=
+ (mdAl==0 && root->argList->count()==0) ||
+ md->isVariable() || md->isTypedef() || /* in case of function pointers */
+ matchArguments2(md->getOuterScope(),md->getFileDef(),mdAl,
+ rnd ? rnd : Doxygen::globalScope,fd,root->argList,
+ FALSE);
+
+ // for template members we need to check if the number of
+ // template arguments is the same, otherwise we are dealing with
+ // different functions.
+ if (matching && root->tArgLists)
+ {
+ ArgumentList *mdTempl = md->templateArguments();
+ if (mdTempl)
+ {
+ if (root->tArgLists->getLast()->count()!=mdTempl->count())
+ {
+ matching=FALSE;
+ }
+ }
+ }
+
+ //printf("%s<->%s\n",
+ // argListToString(md->argumentList()).data(),
+ // argListToString(root->argList).data());
+
+ // for static members we also check if the comment block was found in
+ // the same file. This is needed because static members with the same
+ // name can be in different files. Thus it would be wrong to just
+ // put the comment block at the first syntactically matching member.
+ if (matching && md->isStatic() &&
+ md->getDefFileName()!=root->fileName &&
+ mn->count()>1)
+ {
+ matching = FALSE;
+ }
+
+ // for template member we also need to check the return type
+ if (md->templateArguments()!=0 && root->tArgLists!=0)
+ {
+ //printf("Comparing return types '%s'<->'%s'\n",
+ // md->typeString(),type);
+ if (md->templateArguments()->count()!=root->tArgLists->getLast()->count() ||
+ qstrcmp(md->typeString(),type)!=0)
+ {
+ //printf(" ---> no matching\n");
+ matching = FALSE;
+ }
+ }
+
+ if (matching) // add docs to the member
+ {
+ Debug::print(Debug::FindMembers,0,"5. Match found\n");
+ addMemberDocs(rootNav,md,decl,root->argList,FALSE);
+ found=TRUE;
+ }
+ }
+ }
+ if (!found && root->relatesType != Duplicate && root->section==Entry::FUNCTION_SEC) // no match
+ {
+ QCString fullFuncDecl=decl;
+ if (root->argList) fullFuncDecl+=argListToString(root->argList,TRUE);
+ QCString warnMsg =
+ QCString("no matching file member found for \n")+substitute(fullFuncDecl,"%","%%");
+ if (mn->count()>0)
+ {
+ warnMsg+="\nPossible candidates:\n";
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ warnMsg+=" '";
+ warnMsg+=substitute(md->declaration(),"%","%%");
+ warnMsg+="' at line "+QCString().setNum(md->getDefLine())+
+ " of file"+md->getDefFileName()+"\n";
+ }
+ }
+ warn(root->fileName,root->startLine,warnMsg);
+ }
+ }
+ else // got docs for an undefined member!
+ {
+ if (root->type!="friend class" &&
+ root->type!="friend struct" &&
+ root->type!="friend union" &&
+ (!Config_getBool("TYPEDEF_HIDES_STRUCT") ||
+ root->type.find("typedef ")==-1)
+ )
+ {
+ warn(root->fileName,root->startLine,
+ "documented symbol `%s' was not declared or defined.",decl
+ );
+ }
+ }
+ return TRUE;
+}
+
+static bool isSpecialization(
+ const QList<ArgumentList> &srcTempArgLists,
+ const QList<ArgumentList> &dstTempArgLists
+ )
+{
+ QListIterator<ArgumentList> srclali(srcTempArgLists);
+ QListIterator<ArgumentList> dstlali(dstTempArgLists);
+ for (;srclali.current();++srclali,++dstlali)
+ {
+ ArgumentList *sal = srclali.current();
+ ArgumentList *dal = dstlali.current();
+ if (!(sal && dal && sal->count()==dal->count())) return TRUE;
+ }
+ return FALSE;
+}
+
+static bool scopeIsTemplate(Definition *d)
+{
+ bool result=FALSE;
+ if (d && d->definitionType()==Definition::TypeClass)
+ {
+ result = ((ClassDef*)d)->templateArguments() || scopeIsTemplate(d->getOuterScope());
+ }
+ return result;
+}
+
+static QCString substituteTemplatesInString(
+ const QList<ArgumentList> &srcTempArgLists,
+ const QList<ArgumentList> &dstTempArgLists,
+ ArgumentList *funcTempArgList, // can be used to match template specializations
+ const QCString &src
+ )
+{
+ QCString dst;
+ QRegExp re( "[A-Za-z_][A-Za-z_0-9]*");
+ //printf("type=%s\n",sa->type.data());
+ int i,p=0,l;
+ while ((i=re.match(src,p,&l))!=-1) // for each word in srcType
+ {
+ bool found=FALSE;
+ dst+=src.mid(p,i-p);
+ QCString name=src.mid(i,l);
+
+ QListIterator<ArgumentList> srclali(srcTempArgLists);
+ QListIterator<ArgumentList> dstlali(dstTempArgLists);
+ for (;srclali.current() && !found;++srclali,++dstlali)
+ {
+ ArgumentListIterator tsali(*srclali.current());
+ ArgumentListIterator tdali(*dstlali.current());
+ ArgumentListIterator *fali=0;
+ Argument *tsa =0,*tda=0, *fa=0;
+ if (funcTempArgList)
+ {
+ fali = new ArgumentListIterator(*funcTempArgList);
+ fa = fali->current();
+ }
+
+ for (tsali.toFirst();(tsa=tsali.current()) && !found;++tsali)
+ {
+ tda = tdali.current();
+ //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
+ // tsa->type.data(),tsa->name.data(),
+ // tda->type.data(),tda->name.data());
+ if (name==tsa->name)
+ {
+ if (tda && tda->name.isEmpty())
+ {
+ int vc=0;
+ if (tda->type.left(6)=="class ") vc=6;
+ else if (tda->type.left(9)=="typename ") vc=9;
+ if (vc>0) // convert type=="class T" to type=="class" name=="T"
+ {
+ tda->name = tda->type.mid(vc);
+ tda->type = tda->type.left(vc-1);
+ }
+ }
+ if (tda && !tda->name.isEmpty())
+ {
+ name=tda->name; // substitute
+ found=TRUE;
+ }
+ else if (fa)
+ {
+ name=fa->type;
+ found=TRUE;
+ }
+ }
+ if (tda)
+ ++tdali;
+ else if (fali)
+ { ++(*fali); fa=fali->current(); }
+ }
+
+ delete fali;
+ //printf(" srcList='%s' dstList='%s faList='%s'\n",
+ // argListToString(srclali.current()).data(),
+ // argListToString(dstlali.current()).data(),
+ // funcTempArgList ? argListToString(funcTempArgList).data() : "<none>");
+ }
+ dst+=name;
+ p=i+l;
+ }
+ dst+=src.right(src.length()-p);
+ //printf(" substituteTemplatesInString(%s)=%s\n",
+ // src.data(),dst.data());
+ return dst;
+}
+
+static void substituteTemplatesInArgList(
+ const QList<ArgumentList> &srcTempArgLists,
+ const QList<ArgumentList> &dstTempArgLists,
+ ArgumentList *src,
+ ArgumentList *dst,
+ ArgumentList *funcTempArgs = 0
+ )
+{
+ ArgumentListIterator sali(*src);
+ ArgumentListIterator dali(*dst);
+ Argument *sa=0;
+ Argument *da=dali.current();
+
+ for (sali.toFirst();(sa=sali.current());++sali) // for each member argument
+ {
+ QCString dstType = substituteTemplatesInString(
+ srcTempArgLists,dstTempArgLists,funcTempArgs,
+ sa->type);
+ QCString dstArray = substituteTemplatesInString(
+ srcTempArgLists,dstTempArgLists,funcTempArgs,
+ sa->array);
+ if (da==0)
+ {
+ da=new Argument(*sa);
+ dst->append(da);
+ da->type=dstType;
+ da->array=dstArray;
+ da=0;
+ }
+ else
+ {
+ da->type=dstType;
+ da->type=dstArray;
+ ++dali;
+ da=dali.current();
+ }
+ }
+ dst->constSpecifier = src->constSpecifier;
+ dst->volatileSpecifier = src->volatileSpecifier;
+ dst->pureSpecifier = src->pureSpecifier;
+ dst->trailingReturnType = substituteTemplatesInString(
+ srcTempArgLists,dstTempArgLists,
+ funcTempArgs,src->trailingReturnType);
+ //printf("substituteTemplatesInArgList: replacing %s with %s\n",
+ // argListToString(src).data(),argListToString(dst).data()
+ // );
+}
+
+
+
+/*! This function tries to find a member (in a documented class/file/namespace)
+ * that corresponds to the function/variable declaration given in \a funcDecl.
+ *
+ * The boolean \a overloaded is used to specify whether or not a standard
+ * overload documentation line should be generated.
+ *
+ * The boolean \a isFunc is a hint that indicates that this is a function
+ * instead of a variable or typedef.
+ */
+static void findMember(EntryNav *rootNav,
+ QCString funcDecl,
+ bool overloaded,
+ bool isFunc
+ )
+{
+ Entry *root = rootNav->entry();
+
+ Debug::print(Debug::FindMembers,0,
+ "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,"
+ "isFunc=%d mGrpId=%d tArgList=%p (#=%d) "
+ "spec=%lld lang=%x\n",
+ root,funcDecl.data(),root->relates.data(),overloaded,isFunc,root->mGrpId,
+ root->tArgLists,root->tArgLists ? root->tArgLists->count() : 0,
+ root->spec,root->lang
+ );
+
+ QCString scopeName;
+ QCString className;
+ QCString namespaceName;
+ QCString funcType;
+ QCString funcName;
+ QCString funcArgs;
+ QCString funcTempList;
+ QCString exceptions;
+ QCString funcSpec;
+ bool isRelated=FALSE;
+ bool isMemberOf=FALSE;
+ bool isFriend=FALSE;
+ bool done;
+ do
+ {
+ done=TRUE;
+ if (funcDecl.stripPrefix("friend ")) // treat friends as related members
+ {
+ isFriend=TRUE;
+ done=FALSE;
+ }
+ if (funcDecl.stripPrefix("inline "))
+ {
+ root->spec|=Entry::Inline;
+ done=FALSE;
+ }
+ if (funcDecl.stripPrefix("explicit "))
+ {
+ root->spec|=Entry::Explicit;
+ done=FALSE;
+ }
+ if (funcDecl.stripPrefix("mutable "))
+ {
+ root->spec|=Entry::Mutable;
+ done=FALSE;
+ }
+ if (funcDecl.stripPrefix("virtual "))
+ {
+ done=FALSE;
+ }
+ } while (!done);
+
+ // delete any ; from the function declaration
+ int sep;
+ while ((sep=funcDecl.find(';'))!=-1)
+ {
+ funcDecl=(funcDecl.left(sep)+funcDecl.right(funcDecl.length()-sep-1)).stripWhiteSpace();
+ }
+
+ // make sure the first character is a space to simplify searching.
+ if (!funcDecl.isEmpty() && funcDecl[0]!=' ') funcDecl.prepend(" ");
+
+ // remove some superfluous spaces
+ funcDecl= substitute(
+ substitute(
+ substitute(funcDecl,"~ ","~"),
+ ":: ","::"
+ ),
+ " ::","::"
+ ).stripWhiteSpace();
+
+ //printf("funcDecl=`%s'\n",funcDecl.data());
+ if (isFriend && funcDecl.left(6)=="class ")
+ {
+ //printf("friend class\n");
+ funcDecl=funcDecl.right(funcDecl.length()-6);
+ funcName = funcDecl.copy();
+ }
+ else if (isFriend && funcDecl.left(7)=="struct ")
+ {
+ funcDecl=funcDecl.right(funcDecl.length()-7);
+ funcName = funcDecl.copy();
+ }
+ else
+ {
+ // extract information from the declarations
+ parseFuncDecl(funcDecl,root->lang==SrcLangExt_ObjC,scopeName,funcType,funcName,
+ funcArgs,funcTempList,exceptions
+ );
+ }
+ //printf("scopeName=`%s' funcType=`%s' funcName=`%s' funcArgs=`%s'\n",
+ // scopeName.data(),funcType.data(),funcName.data(),funcArgs.data());
+
+ // the class name can also be a namespace name, we decide this later.
+ // if a related class name is specified and the class name could
+ // not be derived from the function declaration, then use the
+ // related field.
+ //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n",
+ // scopeName.data(),className.data(),namespaceName.data());
+ if (!root->relates.isEmpty())
+ { // related member, prefix user specified scope
+ isRelated=TRUE;
+ isMemberOf=(root->relatesType == MemberOf);
+ if (getClass(root->relates)==0 && !scopeName.isEmpty())
+ {
+ scopeName= mergeScopes(scopeName,root->relates);
+ }
+ else
+ {
+ scopeName = root->relates;
+ }
+ }
+
+ if (root->relates.isEmpty() && rootNav->parent() &&
+ ((rootNav->parent()->section()&Entry::SCOPE_MASK) ||
+ (rootNav->parent()->section()==Entry::OBJCIMPL_SEC)
+ ) &&
+ !rootNav->parent()->name().isEmpty()) // see if we can combine scopeName
+ // with the scope in which it was found
+ {
+ QCString joinedName = rootNav->parent()->name()+"::"+scopeName;
+ if (!scopeName.isEmpty() &&
+ (getClass(joinedName) || Doxygen::namespaceSDict->find(joinedName)))
+ {
+ scopeName = joinedName;
+ }
+ else
+ {
+ scopeName = mergeScopes(rootNav->parent()->name(),scopeName);
+ }
+ }
+ else // see if we can prefix a namespace or class that is used from the file
+ {
+ FileDef *fd=rootNav->fileDef();
+ if (fd)
+ {
+ NamespaceSDict *fnl = fd->getUsedNamespaces();
+ if (fnl)
+ {
+ QCString joinedName;
+ NamespaceDef *fnd;
+ NamespaceSDict::Iterator nsdi(*fnl);
+ for (nsdi.toFirst();(fnd=nsdi.current());++nsdi)
+ {
+ joinedName = fnd->name()+"::"+scopeName;
+ if (Doxygen::namespaceSDict->find(joinedName))
+ {
+ scopeName=joinedName;
+ break;
+ }
+ }
+ }
+ }
+ }
+ scopeName=stripTemplateSpecifiersFromScope(
+ removeRedundantWhiteSpace(scopeName),FALSE,&funcSpec);
+
+ // funcSpec contains the last template specifiers of the given scope.
+ // If this method does not have any template arguments or they are
+ // empty while funcSpec is not empty we assume this is a
+ // specialization of a method. If not, we clear the funcSpec and treat
+ // this as a normal method of a template class.
+ if (!(root->tArgLists &&
+ root->tArgLists->count()>0 &&
+ root->tArgLists->getFirst()->count()==0
+ )
+ )
+ {
+ funcSpec.resize(0);
+ }
+
+ // split scope into a namespace and a class part
+ extractNamespaceName(scopeName,className,namespaceName,TRUE);
+ //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n",
+ // scopeName.data(),className.data(),namespaceName.data());
+
+ //namespaceName=removeAnonymousScopes(namespaceName);
+ if (namespaceName.find('@')!=-1) return; // skip stuff in anonymous namespace...
+
+ //printf("namespaceName=`%s' className=`%s'\n",namespaceName.data(),className.data());
+ // merge class and namespace scopes again
+ scopeName.resize(0);
+ if (!namespaceName.isEmpty())
+ {
+ if (className.isEmpty())
+ {
+ scopeName=namespaceName;
+ }
+ else if (!root->relates.isEmpty() || // relates command with explicit scope
+ !getClass(className)) // class name only exists in a namespace
+ {
+ scopeName=namespaceName+"::"+className;
+ }
+ else
+ {
+ scopeName=className;
+ }
+ }
+ else if (!className.isEmpty())
+ {
+ scopeName=className;
+ }
+ //printf("new scope=`%s'\n",scopeName.data());
+
+ QCString tempScopeName=scopeName;
+ ClassDef *cd=getClass(scopeName);
+ if (cd)
+ {
+ if (funcSpec.isEmpty())
+ {
+ int argListIndex=0;
+ tempScopeName=cd->qualifiedNameWithTemplateParameters(root->tArgLists,&argListIndex);
+ }
+ else
+ {
+ tempScopeName=scopeName+funcSpec;
+ }
+ }
+ //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n",
+ // scopeName.data(),cd,root->tArgLists,tempScopeName.data());
+
+ //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data());
+ // rebuild the function declaration (needed to get the scope right).
+ if (!scopeName.isEmpty() && !isRelated && !isFriend && !Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ if (!funcType.isEmpty())
+ {
+ if (isFunc) // a function -> we use argList for the arguments
+ {
+ funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcTempList;
+ }
+ else
+ {
+ funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcArgs;
+ }
+ }
+ else
+ {
+ if (isFunc) // a function => we use argList for the arguments
+ {
+ funcDecl=tempScopeName+"::"+funcName+funcTempList;
+ }
+ else // variable => add `argument' list
+ {
+ funcDecl=tempScopeName+"::"+funcName+funcArgs;
+ }
+ }
+ }
+ else // build declaration without scope
+ {
+ if (!funcType.isEmpty()) // but with a type
+ {
+ if (isFunc) // function => omit argument list
+ {
+ funcDecl=funcType+" "+funcName+funcTempList;
+ }
+ else // variable => add `argument' list
+ {
+ funcDecl=funcType+" "+funcName+funcArgs;
+ }
+ }
+ else // no type
+ {
+ if (isFunc)
+ {
+ funcDecl=funcName+funcTempList;
+ }
+ else
+ {
+ funcDecl=funcName+funcArgs;
+ }
+ }
+ }
+
+ if (funcType=="template class" && !funcTempList.isEmpty())
+ return; // ignore explicit template instantiations
+
+ Debug::print(Debug::FindMembers,0,
+ "findMember() Parse results:\n"
+ " namespaceName=`%s'\n"
+ " className=`%s`\n"
+ " funcType=`%s'\n"
+ " funcSpec=`%s'\n"
+ " funcName=`%s'\n"
+ " funcArgs=`%s'\n"
+ " funcTempList=`%s'\n"
+ " funcDecl=`%s'\n"
+ " related=`%s'\n"
+ " exceptions=`%s'\n"
+ " isRelated=%d\n"
+ " isMemberOf=%d\n"
+ " isFriend=%d\n"
+ " isFunc=%d\n\n",
+ namespaceName.data(),className.data(),
+ funcType.data(),funcSpec.data(),funcName.data(),funcArgs.data(),funcTempList.data(),
+ funcDecl.data(),root->relates.data(),exceptions.data(),isRelated,isMemberOf,isFriend,
+ isFunc
+ );
+
+ MemberName *mn=0;
+ if (!funcName.isEmpty()) // function name is valid
+ {
+ Debug::print(Debug::FindMembers,0,
+ "1. funcName=`%s'\n",funcName.data());
+ if (funcName.left(9)=="operator ") // strip class scope from cast operator
+ {
+ funcName = substitute(funcName,className+"::","");
+ }
+ if (!funcTempList.isEmpty()) // try with member specialization
+ {
+ mn=Doxygen::memberNameSDict->find(funcName+funcTempList);
+ }
+ if (mn==0) // try without specialization
+ {
+ mn=Doxygen::memberNameSDict->find(funcName);
+ }
+ if (!isRelated && mn) // function name already found
+ {
+ Debug::print(Debug::FindMembers,0,
+ "2. member name exists (%d members with this name)\n",mn->count());
+ if (!className.isEmpty()) // class name is valid
+ {
+ if (funcSpec.isEmpty()) // not a member specialization
+ {
+ int count=0;
+ int noMatchCount=0;
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ bool memFound=FALSE;
+ for (mni.toFirst();!memFound && (md=mni.current());++mni)
+ {
+ ClassDef *cd=md->getClassDef();
+ Debug::print(Debug::FindMembers,0,
+ "3. member definition found, "
+ "scope needed=`%s' scope=`%s' args=`%s' fileName=%s\n",
+ scopeName.data(),cd ? cd->name().data() : "<none>",
+ md->argsString(),
+ root->fileName.data());
+ //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data());
+ FileDef *fd=rootNav->fileDef();
+ NamespaceDef *nd=0;
+ if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
+
+ //printf("scopeName %s->%s\n",scopeName.data(),
+ // stripTemplateSpecifiersFromScope(scopeName,FALSE).data());
+
+ ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
+ if (tcd==0 && stripAnonymousNamespaceScope(cd->name())==scopeName)
+ {
+ // don't be fooled by anonymous scopes
+ tcd=cd;
+ }
+ //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n",
+ // scopeName.data(),nd?nd->name().data():"<none>",tcd,tcd?tcd->name().data():"",cd);
+
+ if (cd && tcd==cd) // member's classes match
+ {
+ Debug::print(Debug::FindMembers,0,
+ "4. class definition %s found\n",cd->name().data());
+
+ // get the template parameter lists found at the member declaration
+ QList<ArgumentList> declTemplArgs;
+ cd->getTemplateParameterLists(declTemplArgs);
+ ArgumentList *templAl = md->templateArguments();
+ if (templAl)
+ {
+ declTemplArgs.append(templAl);
+ }
+
+ // get the template parameter lists found at the member definition
+ QList<ArgumentList> *defTemplArgs = root->tArgLists;
+ //printf("defTemplArgs=%p\n",defTemplArgs);
+
+ // do we replace the decl argument lists with the def argument lists?
+ bool substDone=FALSE;
+ ArgumentList *argList=0;
+
+ /* substitute the occurrences of class template names in the
+ * argument list before matching
+ */
+ ArgumentList *mdAl = md->argumentList();
+ if (declTemplArgs.count()>0 && defTemplArgs &&
+ declTemplArgs.count()==defTemplArgs->count() &&
+ mdAl
+ )
+ {
+ /* the function definition has template arguments
+ * and the class definition also has template arguments, so
+ * we must substitute the template names of the class by that
+ * of the function definition before matching.
+ */
+ argList = new ArgumentList;
+ substituteTemplatesInArgList(declTemplArgs,*defTemplArgs,
+ mdAl,argList);
+
+ substDone=TRUE;
+ }
+ else /* no template arguments, compare argument lists directly */
+ {
+ argList = mdAl;
+ }
+
+ Debug::print(Debug::FindMembers,0,
+ "5. matching `%s'<=>`%s' className=%s namespaceName=%s\n",
+ argListToString(argList,TRUE).data(),argListToString(root->argList,TRUE).data(),
+ className.data(),namespaceName.data()
+ );
+
+ bool matching=
+ md->isVariable() || md->isTypedef() || // needed for function pointers
+ (mdAl==0 && root->argList->count()==0) ||
+ matchArguments2(
+ md->getClassDef(),md->getFileDef(),argList,
+ cd,fd,root->argList,
+ TRUE);
+
+ if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC))
+ {
+ matching = FALSE; // don't match methods and attributes with the same name
+ }
+
+ // for template member we also need to check the return type
+ if (md->templateArguments()!=0 && root->tArgLists!=0)
+ {
+ QCString memType = md->typeString();
+ memType.stripPrefix("static "); // see bug700696
+ funcType=substitute(stripTemplateSpecifiersFromScope(funcType,TRUE),
+ className+"::",""); // see bug700693 & bug732594
+ Debug::print(Debug::FindMembers,0,
+ "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n",
+ md->typeString(),funcType.data(),
+ md->templateArguments()->count(),root->tArgLists->getLast()->count());
+ if (md->templateArguments()->count()!=root->tArgLists->getLast()->count() ||
+ qstrcmp(memType,funcType))
+ {
+ //printf(" ---> no matching\n");
+ matching = FALSE;
+ }
+ }
+ bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0;
+ bool classIsTemplate = scopeIsTemplate(md->getClassDef());
+ bool mdIsTemplate = md->templateArguments()!=0;
+ bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
+ bool rootIsTemplate = root->tArgLists!=0;
+ //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
+ if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
+ (mdIsTemplate || rootIsTemplate) && // either md or root is a template
+ ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
+ )
+ {
+ // Method with template return type does not match method without return type
+ // even if the parameters are the same. See also bug709052
+ Debug::print(Debug::FindMembers,0,
+ "5b. Comparing return types: template v.s. non-template\n");
+ matching = FALSE;
+ }
+
+
+ Debug::print(Debug::FindMembers,0,
+ "6. match results of matchArguments2 = %d\n",matching);
+
+ if (substDone) // found a new argument list
+ {
+ if (matching) // replace member's argument list
+ {
+ md->setDefinitionTemplateParameterLists(root->tArgLists);
+ md->setArgumentList(argList); // new owner of the list => no delete
+ }
+ else // no match
+ {
+ if (!funcTempList.isEmpty() &&
+ isSpecialization(declTemplArgs,*defTemplArgs))
+ {
+ // check if we are dealing with a partial template
+ // specialization. In this case we add it to the class
+ // even though the member arguments do not match.
+
+ // TODO: copy other aspects?
+ root->protection=md->protection(); // copy protection level
+ addMethodToClass(rootNav,cd,md->name(),isFriend);
+ return;
+ }
+ delete argList;
+ }
+ }
+ if (matching)
+ {
+ addMemberDocs(rootNav,md,funcDecl,0,overloaded,0/* TODO */);
+ count++;
+ memFound=TRUE;
+ }
+ }
+ else if (cd && cd!=tcd) // we did find a class with the same name as cd
+ // but in a different namespace
+ {
+ noMatchCount++;
+ }
+ }
+ if (count==0 && rootNav->parent() &&
+ rootNav->parent()->section()==Entry::OBJCIMPL_SEC)
+ {
+ goto localObjCMethod;
+ }
+ if (count==0 && !(isFriend && funcType=="class"))
+ {
+ int candidates=0;
+ ClassDef *ecd = 0, *ucd = 0;
+ MemberDef *emd = 0, *umd = 0;
+ if (mn->count()>0)
+ {
+ //printf("Assume template class\n");
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ ClassDef *ccd=md->getClassDef();
+ MemberDef *cmd=md;
+ //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data());
+ if (ccd!=0 && rightScopeMatch(ccd->name(),className))
+ {
+ ArgumentList *templAl = md->templateArguments();
+ if (root->tArgLists && templAl!=0 &&
+ root->tArgLists->getLast()->count()<=templAl->count())
+ {
+ addMethodToClass(rootNav,ccd,md->name(),isFriend);
+ return;
+ }
+ if (md->argsString()==argListToString(root->argList,TRUE,FALSE))
+ { // exact argument list match -> remember
+ ucd = ecd = ccd;
+ umd = emd = cmd;
+ Debug::print(Debug::FindMembers,0,
+ "7. new candidate className=%s scope=%s args=%s exact match\n",
+ className.data(),ccd->name().data(),md->argsString());
+ }
+ else // arguments do not match, but member name and scope do -> remember
+ {
+ ucd = ccd;
+ umd = cmd;
+ Debug::print(Debug::FindMembers,0,
+ "7. new candidate className=%s scope=%s args=%s no match\n",
+ className.data(),ccd->name().data(),md->argsString());
+ }
+ candidates++;
+ }
+ }
+ }
+ static bool strictProtoMatching = Config_getBool("STRICT_PROTO_MATCHING");
+ if (!strictProtoMatching)
+ {
+ if (candidates==1 && ucd && umd)
+ {
+ // we didn't find an actual match on argument lists, but there is only 1 member with this
+ // name in the same scope, so that has to be the one.
+ addMemberDocs(rootNav,umd,funcDecl,0,overloaded,0);
+ return;
+ }
+ else if (candidates>1 && ecd && emd)
+ {
+ // we didn't find a unique match using type resolution,
+ // but one of the matches has the exact same signature so
+ // we take that one.
+ addMemberDocs(rootNav,emd,funcDecl,0,overloaded,0);
+ return;
+ }
+ }
+
+ QCString warnMsg = "no ";
+ if (noMatchCount>1) warnMsg+="uniquely ";
+ warnMsg+="matching class member found for \n";
+
+ if (root->tArgLists)
+ {
+ QListIterator<ArgumentList> alli(*root->tArgLists);
+ ArgumentList *al;
+ for (;(al=alli.current());++alli)
+ {
+ warnMsg+=" template ";
+ warnMsg+=tempArgListToString(al);
+ warnMsg+='\n';
+ }
+ }
+ QCString fullFuncDecl=funcDecl.copy();
+ if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
+
+ warnMsg+=" ";
+ warnMsg+=fullFuncDecl;
+ warnMsg+='\n';
+
+ if (candidates>0)
+ {
+ warnMsg+="Possible candidates:\n";
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ ClassDef *cd=md->getClassDef();
+ if (cd!=0 && rightScopeMatch(cd->name(),className))
+ {
+ ArgumentList *templAl = md->templateArguments();
+ if (templAl!=0)
+ {
+ warnMsg+=" 'template ";
+ warnMsg+=tempArgListToString(templAl);
+ warnMsg+='\n';
+ }
+ warnMsg+=" ";
+ if (md->typeString())
+ {
+ warnMsg+=md->typeString();
+ warnMsg+=' ';
+ }
+ QCString qScope = cd->qualifiedNameWithTemplateParameters();
+ if (!qScope.isEmpty())
+ warnMsg+=qScope+"::"+md->name();
+ if (md->argsString())
+ warnMsg+=md->argsString();
+ if (noMatchCount>1)
+ {
+ warnMsg+="' at line "+QCString().setNum(md->getDefLine()) +
+ " of file "+md->getDefFileName();
+ }
+
+ warnMsg+='\n';
+ }
+ }
+ }
+ warn_simple(root->fileName,root->startLine,warnMsg);
+ }
+ }
+ else if (cd) // member specialization
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *declMd=0;
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->getClassDef()==cd)
+ {
+ // TODO: we should probably also check for matching arguments
+ declMd = md;
+ break;
+ }
+ }
+ MemberType mtype=MemberType_Function;
+ ArgumentList *tArgList = new ArgumentList;
+ // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
+ md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ funcType,funcName,funcArgs,exceptions,
+ declMd ? declMd->protection() : root->protection,
+ root->virt,root->stat,Member,
+ mtype,tArgList,root->argList);
+ //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data());
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ md->setMemberClass(cd);
+ md->setTemplateSpecialization(TRUE);
+ md->setTypeConstraints(root->typeConstr);
+ md->setDefinition(funcDecl);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setPrototype(root->proto);
+ md->addSectionsToDefinition(root->anchors);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ FileDef *fd=rootNav->fileDef();
+ md->setBodyDef(fd);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+ mn->append(md);
+ cd->insertMember(md);
+ md->setRefItems(root->sli);
+ delete tArgList;
+ }
+ else
+ {
+ //printf("*** Specialized member %s of unknown scope %s%s found!\n",
+ // scopeName.data(),funcName.data(),funcArgs.data());
+ }
+ }
+ else if (overloaded) // check if the function belongs to only one class
+ {
+ // for unique overloaded member we allow the class to be
+ // omitted, this is to be Qt compatible. Using this should
+ // however be avoided, because it is error prone
+ MemberNameIterator mni(*mn);
+ MemberDef *md=mni.toFirst();
+ ASSERT(md);
+ ClassDef *cd=md->getClassDef();
+ ASSERT(cd);
+ QCString className=cd->name().copy();
+ ++mni;
+ bool unique=TRUE;
+ for (;(md=mni.current());++mni)
+ {
+ ClassDef *cd=md->getClassDef();
+ if (className!=cd->name()) unique=FALSE;
+ }
+ if (unique)
+ {
+ MemberType mtype;
+ if (root->mtype==Signal) mtype=MemberType_Signal;
+ else if (root->mtype==Slot) mtype=MemberType_Slot;
+ else if (root->mtype==DCOP) mtype=MemberType_DCOP;
+ else mtype=MemberType_Function;
+
+ // new overloaded member function
+ ArgumentList *tArgList =
+ getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
+ //printf("new related member %s args=`%s'\n",md->name().data(),funcArgs.data());
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ funcType,funcName,funcArgs,exceptions,
+ root->protection,root->virt,root->stat,Related,
+ mtype,tArgList,root->argList);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ md->setTypeConstraints(root->typeConstr);
+ md->setMemberClass(cd);
+ md->setDefinition(funcDecl);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ QCString doc=getOverloadDocs();
+ doc+="<p>";
+ doc+=root->doc;
+ md->setDocumentation(doc,root->docFile,root->docLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setPrototype(root->proto);
+ md->addSectionsToDefinition(root->anchors);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ FileDef *fd=rootNav->fileDef();
+ md->setBodyDef(fd);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+ mn->append(md);
+ cd->insertMember(md);
+ cd->insertUsedFile(fd);
+ md->setRefItems(root->sli);
+ }
+ }
+ else // unrelated function with the same name as a member
+ {
+ if (!findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl))
+ {
+ QCString fullFuncDecl=funcDecl.copy();
+ if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
+ warn(root->fileName,root->startLine,
+ "Cannot determine class for function\n%s",
+ fullFuncDecl.data()
+ );
+ }
+ }
+ }
+ else if (isRelated && !root->relates.isEmpty())
+ {
+ Debug::print(Debug::FindMembers,0,"2. related function\n"
+ " scopeName=%s className=%s\n",scopeName.data(),className.data());
+ if (className.isEmpty()) className=root->relates;
+ ClassDef *cd;
+ //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data());
+ if ((cd=getClass(scopeName)))
+ {
+ bool newMember=TRUE; // assume we have a new member
+ bool newMemberName=FALSE;
+ MemberDef *mdDefine=0;
+ bool isDefine=FALSE;
+ {
+ MemberName *mn = Doxygen::functionNameSDict->find(funcName);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ mdDefine = mni.current();
+ while (mdDefine && !isDefine)
+ {
+ isDefine = isDefine || mdDefine->isDefine();
+ if (!isDefine) { ++mni; mdDefine=mni.current(); }
+ }
+ }
+ }
+
+ FileDef *fd=rootNav->fileDef();
+
+ if ((mn=Doxygen::memberNameSDict->find(funcName))==0)
+ {
+ mn=new MemberName(funcName);
+ newMemberName=TRUE; // we create a new member name
+ }
+ else
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *rmd;
+ while ((rmd=mni.current()) && newMember) // see if we got another member with matching arguments
+ {
+ ArgumentList *rmdAl = rmd->argumentList();
+
+ newMember=
+ className!=rmd->getOuterScope()->name() ||
+ !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl,
+ cd,fd,root->argList,
+ TRUE);
+ if (newMember) ++mni;
+ }
+ if (!newMember && rmd) // member already exists as rmd -> add docs
+ {
+ //printf("addMemberDocs for related member %s\n",root->name.data());
+ //rmd->setMemberDefTemplateArguments(root->mtArgList);
+ addMemberDocs(rootNav,rmd,funcDecl,0,overloaded);
+ }
+ }
+
+ if (newMember) // need to create a new member
+ {
+ MemberType mtype;
+ if (isDefine)
+ mtype=MemberType_Define;
+ else if (root->mtype==Signal)
+ mtype=MemberType_Signal;
+ else if (root->mtype==Slot)
+ mtype=MemberType_Slot;
+ else if (root->mtype==DCOP)
+ mtype=MemberType_DCOP;
+ else
+ mtype=MemberType_Function;
+
+ if (isDefine && mdDefine)
+ {
+ mdDefine->setHidden(TRUE);
+ funcType="#define";
+ funcArgs=mdDefine->argsString();
+ funcDecl=funcType + " " + funcName;
+ }
+
+ //printf("New related name `%s' `%d'\n",funcName.data(),
+ // root->argList ? (int)root->argList->count() : -1);
+
+ // first note that we pass:
+ // (root->tArgLists ? root->tArgLists->last() : 0)
+ // for the template arguments fo the new "member."
+ // this accurately reflects the template arguments of
+ // the related function, which don't have to do with
+ // those of the related class.
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ funcType,funcName,funcArgs,exceptions,
+ root->protection,root->virt,
+ root->stat && !isMemberOf,
+ isMemberOf ? Foreign : isRelated ? Related : Member,
+ mtype,
+ (root->tArgLists ? root->tArgLists->getLast() : 0),
+ funcArgs.isEmpty() ? 0 : root->argList);
+
+ if (isDefine && mdDefine)
+ {
+ md->setInitializer(mdDefine->initializer());
+ }
+
+ //
+ // we still have the problem that
+ // MemberDef::writeDocumentation() in memberdef.cpp
+ // writes the template argument list for the class,
+ // as if this member is a member of the class.
+ // fortunately, MemberDef::writeDocumentation() has
+ // a special mechanism that allows us to totally
+ // override the set of template argument lists that
+ // are printed. We use that and set it to the
+ // template argument lists of the related function.
+ //
+ md->setDefinitionTemplateParameterLists(root->tArgLists);
+
+ md->setTagInfo(rootNav->tagInfo());
+
+
+
+ //printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n",
+ // funcName.data(),funcDecl.data(),root->bodyLine);
+
+ // try to find the matching line number of the body from the
+ // global function list
+ bool found=FALSE;
+ if (root->bodyLine==-1)
+ {
+ MemberName *rmn=Doxygen::functionNameSDict->find(funcName);
+ if (rmn)
+ {
+ MemberNameIterator rmni(*rmn);
+ MemberDef *rmd;
+ while ((rmd=rmni.current()) && !found) // see if we got another member with matching arguments
+ {
+ ArgumentList *rmdAl = rmd->argumentList();
+ // check for matching argument lists
+ if (
+ matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl,
+ cd,fd,root->argList,
+ TRUE)
+ )
+ {
+ found=TRUE;
+ }
+ if (!found) ++rmni;
+ }
+ if (rmd) // member found -> copy line number info
+ {
+ md->setBodySegment(rmd->getStartBodyLine(),rmd->getEndBodyLine());
+ md->setBodyDef(rmd->getBodyDef());
+ //md->setBodyMember(rmd);
+ }
+ }
+ }
+ if (!found) // line number could not be found or is available in this
+ // entry
+ {
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(fd);
+ }
+
+ //if (root->mGrpId!=-1)
+ //{
+ // md->setMemberGroup(memberGroupDict[root->mGrpId]);
+ //}
+ md->setMemberClass(cd);
+ md->setMemberSpecifiers(root->spec);
+ md->setDefinition(funcDecl);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setPrototype(root->proto);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->addSectionsToDefinition(root->anchors);
+ md->setMemberGroupId(root->mGrpId);
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ //md->setMemberDefTemplateArguments(root->mtArgList);
+ mn->append(md);
+ cd->insertMember(md);
+ cd->insertUsedFile(fd);
+ md->setRefItems(root->sli);
+ if (root->relatesType == Duplicate) md->setRelatedAlso(cd);
+ if (!isDefine)
+ {
+ addMemberToGroups(root,md);
+ }
+ //printf("Adding member=%s\n",md->name().data());
+ if (newMemberName)
+ {
+ //Doxygen::memberNameList.append(mn);
+ //Doxygen::memberNameDict.insert(funcName,mn);
+ Doxygen::memberNameSDict->append(funcName,mn);
+ }
+ }
+ if (root->relatesType == Duplicate)
+ {
+ if (!findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl))
+ {
+ QCString fullFuncDecl=funcDecl.copy();
+ if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
+ warn(root->fileName,root->startLine,
+ "Cannot determine file/namespace for relatedalso function\n%s",
+ fullFuncDecl.data()
+ );
+ }
+ }
+ }
+ else
+ {
+ warn_undoc(root->fileName,root->startLine,
+ "class `%s' for related function `%s' is not "
+ "documented.",
+ className.data(),funcName.data()
+ );
+ }
+ }
+ else if (rootNav->parent() && rootNav->parent()->section()==Entry::OBJCIMPL_SEC)
+ {
+localObjCMethod:
+ ClassDef *cd;
+ //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data());
+ if (Config_getBool("EXTRACT_LOCAL_METHODS") && (cd=getClass(scopeName)))
+ {
+ Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n"
+ " scopeName=%s className=%s\n",root->name.data(),scopeName.data(),className.data());
+ //printf("Local objective C method `%s' of class `%s' found\n",root->name.data(),cd->name().data());
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ funcType,funcName,funcArgs,exceptions,
+ root->protection,root->virt,root->stat,Member,
+ MemberType_Function,0,root->argList);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ md->makeImplementationDetail();
+ md->setMemberClass(cd);
+ md->setDefinition(funcDecl);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setPrototype(root->proto);
+ md->addSectionsToDefinition(root->anchors);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ FileDef *fd=rootNav->fileDef();
+ md->setBodyDef(fd);
+ md->setMemberSpecifiers(root->spec);
+ md->setMemberGroupId(root->mGrpId);
+ cd->insertMember(md);
+ cd->insertUsedFile(fd);
+ md->setRefItems(root->sli);
+ if ((mn=Doxygen::memberNameSDict->find(root->name)))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(root->name);
+ mn->append(md);
+ Doxygen::memberNameSDict->append(root->name,mn);
+ }
+ }
+ else
+ {
+ // local objective C method found for class without interface
+ }
+ }
+ else // unrelated not overloaded member found
+ {
+ bool globMem = findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl);
+ if (className.isEmpty() && !globMem)
+ {
+ warn(root->fileName,root->startLine,
+ "class for member `%s' cannot "
+ "be found.", funcName.data()
+ );
+ }
+ else if (!className.isEmpty() && !globMem)
+ {
+ warn(root->fileName,root->startLine,
+ "member `%s' of class `%s' cannot be found",
+ funcName.data(),className.data());
+ }
+ }
+ }
+ else
+ {
+ // this should not be called
+ warn(root->fileName,root->startLine,
+ "member with no name found.");
+ }
+ return;
+}
+
+//----------------------------------------------------------------------
+// find the members corresponding to the different documentation blocks
+// that are extracted from the sources.
+
+static void filterMemberDocumentation(EntryNav *rootNav)
+{
+ Entry *root = rootNav->entry();
+ int i=-1,l;
+ Debug::print(Debug::FindMembers,0,
+ "findMemberDocumentation(): root->type=`%s' root->inside=`%s' root->name=`%s' root->args=`%s' section=%x root->spec=%lld root->mGrpId=%d\n",
+ root->type.data(),root->inside.data(),root->name.data(),root->args.data(),root->section,root->spec,root->mGrpId
+ );
+ //printf("rootNav->parent()->name()=%s\n",rootNav->parent()->name().data());
+ bool isFunc=TRUE;
+
+ if (root->relatesType == Duplicate && !root->relates.isEmpty())
+ {
+ QCString tmp = root->relates;
+ root->relates.resize(0);
+ filterMemberDocumentation(rootNav);
+ root->relates = tmp;
+ }
+
+ if ( // detect func variable/typedef to func ptr
+ (i=findFunctionPtr(root->type,root->lang,&l))!=-1
+ )
+ {
+ //printf("Fixing function pointer!\n");
+ // fix type and argument
+ root->args.prepend(root->type.right(root->type.length()-i-l));
+ root->type=root->type.left(i+l);
+ //printf("Results type=%s,name=%s,args=%s\n",root->type.data(),root->name.data(),root->args.data());
+ isFunc=FALSE;
+ }
+ else if ((root->type.left(8)=="typedef " && root->args.find('(')!=-1))
+ // detect function types marked as functions
+ {
+ isFunc=FALSE;
+ }
+
+ //printf("Member %s isFunc=%d\n",root->name.data(),isFunc);
+ if (root->section==Entry::MEMBERDOC_SEC)
+ {
+ //printf("Documentation for inline member `%s' found args=`%s'\n",
+ // root->name.data(),root->args.data());
+ //if (root->relates.length()) printf(" Relates %s\n",root->relates.data());
+ if (root->type.isEmpty())
+ {
+ findMember(rootNav,root->name+root->args+root->exception,FALSE,isFunc);
+ }
+ else
+ {
+ findMember(rootNav,root->type+" "+root->name+root->args+root->exception,FALSE,isFunc);
+ }
+ }
+ else if (root->section==Entry::OVERLOADDOC_SEC)
+ {
+ //printf("Overloaded member %s found\n",root->name.data());
+ findMember(rootNav,root->name,TRUE,isFunc);
+ }
+ else if
+ ((root->section==Entry::FUNCTION_SEC // function
+ ||
+ (root->section==Entry::VARIABLE_SEC && // variable
+ !root->type.isEmpty() && // with a type
+ g_compoundKeywordDict.find(root->type)==0 // that is not a keyword
+ // (to skip forward declaration of class etc.)
+ )
+ )
+ )
+ {
+ //printf("Documentation for member `%s' found args=`%s' excp=`%s'\n",
+ // root->name.data(),root->args.data(),root->exception.data());
+ //if (root->relates.length()) printf(" Relates %s\n",root->relates.data());
+ //printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data());
+ if (root->type=="friend class" || root->type=="friend struct" ||
+ root->type=="friend union")
+ {
+ findMember(rootNav,
+ root->type+" "+
+ root->name,
+ FALSE,FALSE);
+
+ }
+ else if (!root->type.isEmpty())
+ {
+ findMember(rootNav,
+ root->type+" "+
+ root->inside+
+ root->name+
+ root->args+
+ root->exception,
+ FALSE,isFunc);
+ }
+ else
+ {
+ findMember(rootNav,
+ root->inside+
+ root->name+
+ root->args+
+ root->exception,
+ FALSE,isFunc);
+ }
+ }
+ else if (root->section==Entry::DEFINE_SEC && !root->relates.isEmpty())
+ {
+ findMember(rootNav,root->name+root->args,FALSE,!root->args.isEmpty());
+ }
+ else if (root->section==Entry::VARIABLEDOC_SEC)
+ {
+ //printf("Documentation for variable %s found\n",root->name.data());
+ //if (!root->relates.isEmpty()) printf(" Relates %s\n",root->relates.data());
+ findMember(rootNav,root->name,FALSE,FALSE);
+ }
+ else if (root->section==Entry::EXPORTED_INTERFACE_SEC ||
+ root->section==Entry::INCLUDED_SERVICE_SEC)
+ {
+ findMember(rootNav,root->type + " " + root->name,FALSE,FALSE);
+ }
+ else
+ {
+ // skip section
+ //printf("skip section\n");
+ }
+}
+
+static void findMemberDocumentation(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::MEMBERDOC_SEC ||
+ rootNav->section()==Entry::OVERLOADDOC_SEC ||
+ rootNav->section()==Entry::FUNCTION_SEC ||
+ rootNav->section()==Entry::VARIABLE_SEC ||
+ rootNav->section()==Entry::VARIABLEDOC_SEC ||
+ rootNav->section()==Entry::DEFINE_SEC ||
+ rootNav->section()==Entry::INCLUDED_SERVICE_SEC ||
+ rootNav->section()==Entry::EXPORTED_INTERFACE_SEC
+ )
+ {
+ rootNav->loadEntry(g_storage);
+
+ filterMemberDocumentation(rootNav);
+
+ rootNav->releaseEntry();
+ }
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ if (e->section()!=Entry::ENUM_SEC) findMemberDocumentation(e);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void findObjCMethodDefinitions(EntryNav *rootNav)
+{
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ EntryNav *objCImplNav;
+ for (;(objCImplNav=eli.current());++eli)
+ {
+ if (objCImplNav->section()==Entry::OBJCIMPL_SEC && objCImplNav->children())
+ {
+ EntryNavListIterator seli(*objCImplNav->children());
+ EntryNav *objCMethodNav;
+ for (;(objCMethodNav=seli.current());++seli)
+ {
+ if (objCMethodNav->section()==Entry::FUNCTION_SEC)
+ {
+ objCMethodNav->loadEntry(g_storage);
+ Entry *objCMethod = objCMethodNav->entry();
+
+ //Printf(" Found ObjC method definition %s\n",objCMethod->name.data());
+ findMember(objCMethodNav, objCMethod->type+" "+objCImplNav->name()+"::"+
+ objCMethod->name+" "+objCMethod->args, FALSE,TRUE);
+ objCMethod->section=Entry::EMPTY_SEC;
+
+ objCMethodNav->releaseEntry();
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+// find and add the enumeration to their classes, namespaces or files
+
+static void findEnums(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::ENUM_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ MemberDef *md=0;
+ ClassDef *cd=0;
+ FileDef *fd=0;
+ NamespaceDef *nd=0;
+ MemberNameSDict *mnsd=0;
+ bool isGlobal;
+ bool isRelated=FALSE;
+ bool isMemberOf=FALSE;
+ //printf("Found enum with name `%s' relates=%s\n",root->name.data(),root->relates.data());
+ int i;
+
+ QCString name;
+ QCString scope;
+
+ if ((i=root->name.findRev("::"))!=-1) // scope is specified
+ {
+ scope=root->name.left(i); // extract scope
+ name=root->name.right(root->name.length()-i-2); // extract name
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+ else // no scope, check the scope in which the docs where found
+ {
+ if (( rootNav->parent()->section() & Entry::SCOPE_MASK )
+ && !rootNav->parent()->name().isEmpty()
+ ) // found enum docs inside a compound
+ {
+ scope=rootNav->parent()->name();
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+ name=root->name;
+ }
+
+ if (!root->relates.isEmpty())
+ { // related member, prefix user specified scope
+ isRelated=TRUE;
+ isMemberOf=(root->relatesType == MemberOf);
+ if (getClass(root->relates)==0 && !scope.isEmpty())
+ scope=mergeScopes(scope,root->relates);
+ else
+ scope=root->relates.copy();
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+
+ if (cd && !name.isEmpty()) // found a enum inside a compound
+ {
+ //printf("Enum `%s'::`%s'\n",cd->name(),name.data());
+ fd=0;
+ mnsd=Doxygen::memberNameSDict;
+ isGlobal=FALSE;
+ }
+ else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace
+ {
+ mnsd=Doxygen::functionNameSDict;
+ isGlobal=TRUE;
+ }
+ else // found a global enum
+ {
+ fd=rootNav->fileDef();
+ mnsd=Doxygen::functionNameSDict;
+ isGlobal=TRUE;
+ }
+
+ if (!name.isEmpty())
+ {
+ // new enum type
+ md = new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ 0,name,0,0,
+ root->protection,Normal,FALSE,
+ isMemberOf ? Foreign : isRelated ? Related : Member,
+ MemberType_Enumeration,
+ 0,0);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ md->setId(root->id);
+ if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(rootNav->fileDef());
+ md->setMemberSpecifiers(root->spec); // UNO IDL "published"
+ md->setEnumBaseType(root->args);
+ //printf("Enum %s definition at line %d of %s: protection=%d\n",
+ // root->name.data(),root->bodyLine,root->fileName.data(),root->protection);
+ md->addSectionsToDefinition(root->anchors);
+ md->setMemberGroupId(root->mGrpId);
+ md->enableCallGraph(root->callGraph);
+ md->enableCallerGraph(root->callerGraph);
+ //printf("%s::setRefItems(%d)\n",md->name().data(),root->sli?root->sli->count():-1);
+ md->setRefItems(root->sli);
+ //printf("found enum %s nd=%p\n",name.data(),nd);
+ bool defSet=FALSE;
+
+ QCString baseType = root->args;
+ if (!baseType.isEmpty())
+ {
+ baseType.prepend(" : ");
+ }
+
+ if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
+ {
+ if (isRelated || Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ md->setDefinition(name+baseType);
+ }
+ else
+ {
+ md->setDefinition(nd->name()+"::"+name+baseType);
+ }
+ //printf("definition=%s\n",md->definition());
+ defSet=TRUE;
+ md->setNamespace(nd);
+ nd->insertMember(md);
+ }
+
+ // even if we have already added the enum to a namespace, we still
+ // also want to add it to other appropriate places such as file
+ // or class.
+ if (isGlobal)
+ {
+ if (!defSet) md->setDefinition(name+baseType);
+ if (fd==0 && rootNav->parent())
+ {
+ fd=rootNav->parent()->fileDef();
+ }
+ if (fd)
+ {
+ md->setFileDef(fd);
+ fd->insertMember(md);
+ }
+ }
+ else if (cd)
+ {
+ if (isRelated || Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ md->setDefinition(name+baseType);
+ }
+ else
+ {
+ md->setDefinition(cd->name()+"::"+name+baseType);
+ }
+ cd->insertMember(md);
+ cd->insertUsedFile(fd);
+ }
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+
+ //printf("Adding member=%s\n",md->name().data());
+ MemberName *mn;
+ if ((mn=(*mnsd)[name]))
+ {
+ // this is used if the same enum is in multiple namespaces/classes
+ mn->append(md);
+ }
+ else // new enum name
+ {
+ mn = new MemberName(name);
+ mn->append(md);
+ mnsd->append(name,mn);
+ //printf("add %s to new memberName. Now %d members\n",
+ // name.data(),mn->count());
+ }
+ addMemberToGroups(root,md);
+ }
+ rootNav->releaseEntry();
+ }
+ else
+ {
+ RECURSE_ENTRYTREE(findEnums,rootNav);
+ }
+}
+
+//----------------------------------------------------------------------
+
+static void addEnumValuesToEnums(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::ENUM_SEC)
+ // non anonymous enumeration
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ ClassDef *cd=0;
+ FileDef *fd=0;
+ NamespaceDef *nd=0;
+ MemberNameSDict *mnsd=0;
+ bool isGlobal;
+ bool isRelated=FALSE;
+ //printf("Found enum with name `%s' relates=%s\n",root->name.data(),root->relates.data());
+ int i;
+
+ QCString name;
+ QCString scope;
+
+ if ((i=root->name.findRev("::"))!=-1) // scope is specified
+ {
+ scope=root->name.left(i); // extract scope
+ name=root->name.right(root->name.length()-i-2); // extract name
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+ else // no scope, check the scope in which the docs where found
+ {
+ if (( rootNav->parent()->section() & Entry::SCOPE_MASK )
+ && !rootNav->parent()->name().isEmpty()
+ ) // found enum docs inside a compound
+ {
+ scope=rootNav->parent()->name();
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+ name=root->name;
+ }
+
+ if (!root->relates.isEmpty())
+ { // related member, prefix user specified scope
+ isRelated=TRUE;
+ if (getClass(root->relates)==0 && !scope.isEmpty())
+ scope=mergeScopes(scope,root->relates);
+ else
+ scope=root->relates.copy();
+ if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope);
+ }
+
+ if (cd && !name.isEmpty()) // found a enum inside a compound
+ {
+ //printf("Enum in class `%s'::`%s'\n",cd->name().data(),name.data());
+ fd=0;
+ mnsd=Doxygen::memberNameSDict;
+ isGlobal=FALSE;
+ }
+ else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace
+ {
+ //printf("Enum in namespace `%s'::`%s'\n",nd->name().data(),name.data());
+ mnsd=Doxygen::functionNameSDict;
+ isGlobal=TRUE;
+ }
+ else // found a global enum
+ {
+ fd=rootNav->fileDef();
+ //printf("Enum in file `%s': `%s'\n",fd->name().data(),name.data());
+ mnsd=Doxygen::functionNameSDict;
+ isGlobal=TRUE;
+ }
+
+ if (!name.isEmpty())
+ {
+ //printf("** name=%s\n",name.data());
+ MemberName *mn = mnsd->find(name); // for all members with this name
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst(); (md=mni.current()) ; ++mni) // for each enum in this list
+ {
+ if (md->isEnumerate() && rootNav->children())
+ {
+ //printf(" enum with %d children\n",rootNav->children()->count());
+ EntryNavListIterator eli(*rootNav->children()); // for each enum value
+ EntryNav *e;
+ for (;(e=eli.current());++eli)
+ {
+ SrcLangExt sle;
+ if (
+ (sle=rootNav->lang())==SrcLangExt_CSharp ||
+ sle==SrcLangExt_Java ||
+ sle==SrcLangExt_XML ||
+ (root->spec&Entry::Strong)
+ )
+ {
+ // Unlike classic C/C++ enums, for C++11, C# & Java enum
+ // values are only visible inside the enum scope, so we must create
+ // them here and only add them to the enum
+ e->loadEntry(g_storage);
+ Entry *root = e->entry();
+ //printf("md->qualifiedName()=%s rootNav->name()=%s tagInfo=%p name=%s\n",
+ // md->qualifiedName().data(),rootNav->name().data(),rootNav->tagInfo(),root->name.data());
+ if (substitute(md->qualifiedName(),"::",".")== // TODO: add function to get canonical representation
+ substitute(rootNav->name(),"::",".") || // enum value scope matches that of the enum
+ rootNav->tagInfo() // be less strict for tag files as members can have incomplete scope
+ )
+ {
+ MemberDef *fmd=new MemberDef(
+ root->fileName,root->startLine,root->startColumn,
+ root->type,root->name,root->args,0,
+ Public, Normal,root->stat,Member,
+ MemberType_EnumValue,0,0);
+ if (md->getClassDef()) fmd->setMemberClass(md->getClassDef());
+ else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef());
+ else if (md->getFileDef()) fmd->setFileDef(md->getFileDef());
+ fmd->setOuterScope(md->getOuterScope());
+ fmd->setTagInfo(e->tagInfo());
+ fmd->setLanguage(root->lang);
+ fmd->setId(root->id);
+ fmd->setDocumentation(root->doc,root->docFile,root->docLine);
+ fmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ fmd->addSectionsToDefinition(root->anchors);
+ fmd->setInitializer(root->initializer);
+ fmd->setMaxInitLines(root->initLines);
+ fmd->setMemberGroupId(root->mGrpId);
+ fmd->setExplicitExternal(root->explicitExternal);
+ fmd->setRefItems(root->sli);
+ fmd->setAnchor();
+ md->insertEnumField(fmd);
+ fmd->setEnumScope(md,TRUE);
+ MemberName *mn=mnsd->find(root->name);
+ if (mn)
+ {
+ mn->append(fmd);
+ }
+ else
+ {
+ mn = new MemberName(root->name);
+ mn->append(fmd);
+ mnsd->append(root->name,mn);
+ }
+ }
+ e->releaseEntry();
+ }
+ else
+ {
+ //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated);
+ MemberName *fmn=0;
+ MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd;
+ if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()]))
+ // get list of members with the same name as the field
+ {
+ MemberNameIterator fmni(*fmn);
+ MemberDef *fmd;
+ for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni)
+ {
+ if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
+ {
+ //printf("found enum value with same name %s in scope %s\n",
+ // fmd->name().data(),fmd->getOuterScope()->name().data());
+ if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
+ {
+ NamespaceDef *fnd=fmd->getNamespaceDef();
+ if (fnd==nd) // enum value is inside a namespace
+ {
+ md->insertEnumField(fmd);
+ fmd->setEnumScope(md);
+ }
+ }
+ else if (isGlobal)
+ {
+ FileDef *ffd=fmd->getFileDef();
+ if (ffd==fd) // enum value has file scope
+ {
+ md->insertEnumField(fmd);
+ fmd->setEnumScope(md);
+ }
+ }
+ else if (isRelated && cd) // reparent enum value to
+ // match the enum's scope
+ {
+ md->insertEnumField(fmd); // add field def to list
+ fmd->setEnumScope(md); // cross ref with enum name
+ fmd->setEnumClassScope(cd); // cross ref with enum name
+ fmd->setOuterScope(cd);
+ fmd->makeRelated();
+ cd->insertMember(fmd);
+ }
+ else
+ {
+ ClassDef *fcd=fmd->getClassDef();
+ if (fcd==cd) // enum value is inside a class
+ {
+ //printf("Inserting enum field %s in enum scope %s\n",
+ // fmd->name().data(),md->name().data());
+ md->insertEnumField(fmd); // add field def to list
+ fmd->setEnumScope(md); // cross ref with enum name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ else
+ {
+ RECURSE_ENTRYTREE(addEnumValuesToEnums,rootNav);
+ }
+}
+
+
+//----------------------------------------------------------------------
+// find the documentation blocks for the enumerations
+
+static void findEnumDocumentation(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::ENUMDOC_SEC
+ && !rootNav->name().isEmpty()
+ && rootNav->name().at(0)!='@' // skip anonymous enums
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("Found docs for enum with name `%s' in context %s\n",
+ // root->name.data(),root->parent->name.data());
+ int i;
+ QCString name;
+ QCString scope;
+ if ((i=root->name.findRev("::"))!=-1) // scope is specified as part of the name
+ {
+ name=root->name.right(root->name.length()-i-2); // extract name
+ scope=root->name.left(i); // extract scope
+ //printf("Scope=`%s' Name=`%s'\n",scope.data(),name.data());
+ }
+ else // just the name
+ {
+ name=root->name;
+ }
+ if (( rootNav->parent()->section() & Entry::SCOPE_MASK )
+ && !rootNav->parent()->name().isEmpty()
+ ) // found enum docs inside a compound
+ {
+ if (!scope.isEmpty()) scope.prepend("::");
+ scope.prepend(rootNav->parent()->name());
+ }
+ ClassDef *cd=getClass(scope);
+
+ if (!name.isEmpty())
+ {
+ bool found=FALSE;
+ if (cd)
+ {
+ //printf("Enum: scope=`%s' name=`%s'\n",cd->name(),name.data());
+ QCString className=cd->name().copy();
+ MemberName *mn=Doxygen::memberNameSDict->find(name);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst();(md=mni.current()) && !found;++mni)
+ {
+ ClassDef *cd=md->getClassDef();
+ if (cd && cd->name()==className && md->isEnumerate())
+ {
+ // documentation outside a compound overrides the documentation inside it
+#if 0
+ if (!md->documentation() || rootNav->parent()->name().isEmpty())
+#endif
+ {
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ }
+
+ // brief descriptions inside a compound override the documentation
+ // outside it
+#if 0
+ if (!md->briefDescription() || !rootNav->parent()->name().isEmpty())
+#endif
+ {
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ }
+
+ if (!md->inbodyDocumentation() || !rootNav->parent()->name().isEmpty())
+ {
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ }
+
+ if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
+ {
+ md->setMemberGroupId(root->mGrpId);
+ }
+
+ md->addSectionsToDefinition(root->anchors);
+ md->setRefItems(root->sli);
+
+ GroupDef *gd=md->getGroupDef();
+ if (gd==0 &&root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is
+ {
+ addMemberToGroups(root,md);
+ }
+
+ found=TRUE;
+ }
+ }
+ }
+ else
+ {
+ //printf("MemberName %s not found!\n",name.data());
+ }
+ }
+ else // enum outside class
+ {
+ //printf("Enum outside class: %s grpId=%d\n",name.data(),root->mGrpId);
+ MemberName *mn=Doxygen::functionNameSDict->find(name);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (mni.toFirst();(md=mni.current()) && !found;++mni)
+ {
+ if (md->isEnumerate())
+ {
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->addSectionsToDefinition(root->anchors);
+ md->setMemberGroupId(root->mGrpId);
+
+ GroupDef *gd=md->getGroupDef();
+ if (gd==0 && root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is
+ {
+ addMemberToGroups(root,md);
+ }
+
+ found=TRUE;
+ }
+ }
+ }
+ }
+ if (!found)
+ {
+ warn(root->fileName,root->startLine,
+ "Documentation for undefined enum `%s' found.",
+ name.data()
+ );
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findEnumDocumentation,rootNav);
+}
+
+// search for each enum (member or function) in mnl if it has documented
+// enum values.
+static void findDEV(const MemberNameSDict &mnsd)
+{
+ MemberName *mn;
+ MemberNameSDict::Iterator mnli(mnsd);
+ // for each member name
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->isEnumerate()) // member is an enum
+ {
+ MemberList *fmdl = md->enumFieldList();
+ int documentedEnumValues=0;
+ if (fmdl) // enum has values
+ {
+ MemberListIterator fmni(*fmdl);
+ MemberDef *fmd;
+ // for each enum value
+ for (fmni.toFirst();(fmd=fmni.current());++fmni)
+ {
+ if (fmd->isLinkableInProject()) documentedEnumValues++;
+ }
+ }
+ // at least one enum value is documented
+ if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
+ }
+ }
+ }
+}
+
+// search for each enum (member or function) if it has documented enum
+// values.
+static void findDocumentedEnumValues()
+{
+ findDEV(*Doxygen::memberNameSDict);
+ findDEV(*Doxygen::functionNameSDict);
+}
+
+//----------------------------------------------------------------------
+
+static void addMembersToIndex()
+{
+ MemberName *mn;
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ // for each member name
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ addClassMemberNameToIndex(md);
+ }
+ }
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ // for each member name
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->getNamespaceDef())
+ {
+ addNamespaceMemberNameToIndex(md);
+ }
+ else
+ {
+ addFileMemberNameToIndex(md);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+// computes the relation between all members. For each member `m'
+// the members that override the implementation of `m' are searched and
+// the member that `m' overrides is searched.
+
+static void computeMemberRelations()
+{
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ MemberName *mn;
+ for ( ; (mn=mnli.current()) ; ++mnli ) // for each member name
+ {
+ MemberNameIterator mdi(*mn);
+ MemberNameIterator bmdi(*mn);
+ MemberDef *md;
+ MemberDef *bmd;
+ for ( ; (md=mdi.current()) ; ++mdi ) // for each member with a specific name
+ {
+ for ( bmdi.toFirst() ; (bmd=bmdi.current()); ++bmdi ) // for each other member with the same name
+ {
+ ClassDef *mcd = md->getClassDef();
+ if (mcd && mcd->baseClasses())
+ {
+ ClassDef *bmcd = bmd->getClassDef();
+ //printf("Check relation between `%s'::`%s' (%p) and `%s'::`%s' (%p)\n",
+ // mcd->name().data(),md->name().data(),md,
+ // bmcd->name().data(),bmd->name().data(),bmd
+ // );
+ if (md!=bmd && bmcd && mcd && bmcd!=mcd &&
+ (bmd->virtualness()!=Normal ||
+ bmcd->compoundType()==ClassDef::Interface ||
+ bmcd->compoundType()==ClassDef::Protocol
+ ) &&
+ md->isFunction() &&
+ mcd->isLinkable() &&
+ bmcd->isLinkable() &&
+ mcd->isBaseClass(bmcd,TRUE))
+ {
+ //printf(" derived scope\n");
+ ArgumentList *bmdAl = bmd->argumentList();
+ ArgumentList *mdAl = md->argumentList();
+ //printf(" Base argList=`%s'\n Super argList=`%s'\n",
+ // argListToString(bmdAl.pointer()).data(),
+ // argListToString(mdAl.pointer()).data()
+ // );
+ if (
+ matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmdAl,
+ md->getOuterScope(), md->getFileDef(), mdAl,
+ TRUE
+ )
+ )
+ {
+ MemberDef *rmd;
+ if ((rmd=md->reimplements())==0 ||
+ minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef())
+ )
+ {
+ //printf("setting (new) reimplements member\n");
+ md->setReimplements(bmd);
+ }
+ //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data());
+ bmd->insertReimplementedBy(md);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+//static void computeClassImplUsageRelations()
+//{
+// ClassDef *cd;
+// ClassSDict::Iterator cli(*Doxygen::classSDict);
+// for (;(cd=cli.current());++cli)
+// {
+// cd->determineImplUsageRelation();
+// }
+//}
+
+//----------------------------------------------------------------------------
+
+static void createTemplateInstanceMembers()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ // for each class
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ // that is a template
+ QDict<ClassDef> *templInstances = cd->getTemplateInstances();
+ if (templInstances)
+ {
+ QDictIterator<ClassDef> qdi(*templInstances);
+ ClassDef *tcd=0;
+ // for each instance of the template
+ for (qdi.toFirst();(tcd=qdi.current());++qdi)
+ {
+ tcd->addMembersToTemplateInstance(cd,qdi.currentKey());
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void mergeCategories()
+{
+ ClassDef *cd;
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ // merge members of categories into the class they extend
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ int i=cd->name().find('(');
+ if (i!=-1) // it is an Objective-C category
+ {
+ QCString baseName=cd->name().left(i);
+ ClassDef *baseClass=Doxygen::classSDict->find(baseName);
+ if (baseClass)
+ {
+ //printf("*** merging members of category %s into %s\n",
+ // cd->name().data(),baseClass->name().data());
+ baseClass->mergeCategory(cd);
+ }
+ }
+ }
+}
+
+// builds the list of all members for each class
+
+static void buildCompleteMemberLists()
+{
+ ClassDef *cd;
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ // merge the member list of base classes into the inherited classes.
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (// !cd->isReference() && // not an external class
+ cd->subClasses()==0 && // is a root of the hierarchy
+ cd->baseClasses()) // and has at least one base class
+ {
+ //printf("*** merging members for %s\n",cd->name().data());
+ cd->mergeMembers();
+ }
+ }
+ // now sort the member list of all classes.
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (cd->memberNameInfoSDict()) cd->memberNameInfoSDict()->sort();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void generateFileSources()
+{
+ if (Doxygen::inputNameList->count()>0)
+ {
+#if USE_LIBCLANG
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (clangAssistedParsing)
+ {
+ QDict<void> g_processedFiles(10007);
+
+ // create a dictionary with files to process
+ QDict<void> g_filesToProcess(10007);
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ g_filesToProcess.insert(fd->absFilePath(),(void*)0x8);
+ }
+ }
+ // process source files (and their include dependencies)
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->isSource() && !fd->isReference())
+ {
+ QStrList filesInSameTu;
+ fd->getAllIncludeFilesRecursively(filesInSameTu);
+ fd->startParsing();
+ if (fd->generateSourceFile()) // sources need to be shown in the output
+ {
+ msg("Generating code for file %s...\n",fd->docName().data());
+ fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+
+ }
+ else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
+ // we needed to parse the sources even if we do not show them
+ {
+ msg("Parsing code for file %s...\n",fd->docName().data());
+ fd->parseSource(FALSE,filesInSameTu);
+ }
+
+ char *incFile = filesInSameTu.first();
+ while (incFile && g_filesToProcess.find(incFile))
+ {
+ if (fd->absFilePath()!=incFile && !g_processedFiles.find(incFile))
+ {
+ QStrList moreFiles;
+ bool ambig;
+ FileDef *ifd=findFileDef(Doxygen::inputNameDict,incFile,ambig);
+ if (ifd && !ifd->isReference())
+ {
+ if (ifd->generateSourceFile()) // sources need to be shown in the output
+ {
+ msg(" Generating code for file %s...\n",ifd->docName().data());
+ ifd->writeSource(*g_outputList,TRUE,moreFiles);
+
+ }
+ else if (!ifd->isReference() && Doxygen::parseSourcesNeeded)
+ // we needed to parse the sources even if we do not show them
+ {
+ msg(" Parsing code for file %s...\n",ifd->docName().data());
+ ifd->parseSource(TRUE,moreFiles);
+ }
+ g_processedFiles.insert(incFile,(void*)0x8);
+ }
+ }
+ incFile = filesInSameTu.next();
+ }
+ fd->finishParsing();
+ g_processedFiles.insert(fd->absFilePath(),(void*)0x8);
+ }
+ }
+ }
+ // process remaining files
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (!g_processedFiles.find(fd->absFilePath())) // not yet processed
+ {
+ QStrList filesInSameTu;
+ fd->startParsing();
+ if (fd->generateSourceFile()) // sources need to be shown in the output
+ {
+ msg("Generating code for file %s...\n",fd->docName().data());
+ fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+
+ }
+ else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
+ // we needed to parse the sources even if we do not show them
+ {
+ msg("Parsing code for file %s...\n",fd->docName().data());
+ fd->parseSource(FALSE,filesInSameTu);
+ }
+ fd->finishParsing();
+ }
+ }
+ }
+ }
+ else
+#endif
+ {
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ QStrList filesInSameTu;
+ fd->startParsing();
+ if (fd->generateSourceFile()) // sources need to be shown in the output
+ {
+ msg("Generating code for file %s...\n",fd->docName().data());
+ fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+
+ }
+ else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
+ // we needed to parse the sources even if we do not show them
+ {
+ msg("Parsing code for file %s...\n",fd->docName().data());
+ fd->parseSource(FALSE,filesInSameTu);
+ }
+ fd->finishParsing();
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void generateFileDocs()
+{
+ if (documentedHtmlFiles==0) return;
+
+ if (Doxygen::inputNameList->count()>0)
+ {
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ bool doc = fd->isLinkableInProject();
+ if (doc)
+ {
+ msg("Generating docs for file %s...\n",fd->docName().data());
+ fd->writeDocumentation(*g_outputList);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void addSourceReferences()
+{
+ // add source references for class definitions
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ FileDef *fd=cd->getBodyDef();
+ if (fd && cd->isLinkableInProject() && cd->getStartBodyLine()!=-1)
+ {
+ fd->addSourceRef(cd->getStartBodyLine(),cd,0);
+ }
+ }
+ // add source references for namespace definitions
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd=0;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ FileDef *fd=nd->getBodyDef();
+ if (fd && nd->isLinkableInProject() && nd->getStartBodyLine()!=-1)
+ {
+ fd->addSourceRef(nd->getStartBodyLine(),nd,0);
+ }
+ }
+
+ // add source references for member names
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ MemberName *mn=0;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ //printf("class member %s: def=%s body=%d link?=%d\n",
+ // md->name().data(),
+ // md->getBodyDef()?md->getBodyDef()->name().data():"<none>",
+ // md->getStartBodyLine(),md->isLinkableInProject());
+ FileDef *fd=md->getBodyDef();
+ if (fd &&
+ md->getStartBodyLine()!=-1 &&
+ md->isLinkableInProject() &&
+ (fd->generateSourceFile() || Doxygen::parseSourcesNeeded)
+ )
+ {
+ //printf("Found member `%s' in file `%s' at line `%d' def=%s\n",
+ // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data());
+ fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md);
+ }
+ }
+ }
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ FileDef *fd=md->getBodyDef();
+ //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
+ // md->name().data(),
+ // md->getStartBodyLine(),md->getEndBodyLine(),fd,
+ // md->isLinkableInProject(),
+ // Doxygen::parseSourcesNeeded);
+ if (fd &&
+ md->getStartBodyLine()!=-1 &&
+ md->isLinkableInProject() &&
+ (fd->generateSourceFile() || Doxygen::parseSourcesNeeded)
+ )
+ {
+ //printf("Found member `%s' in file `%s' at line `%d' def=%s\n",
+ // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data());
+ fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void sortMemberLists()
+{
+ // sort class member lists
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ cd->sortMemberLists();
+ }
+
+ // sort namespace member lists
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd=0;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ nd->sortMemberLists();
+ }
+
+ // sort file member lists
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ fd->sortMemberLists();
+ }
+ }
+
+ // sort group member lists
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->sortMemberLists();
+ }
+}
+
+//----------------------------------------------------------------------------
+// generate the documentation of all classes
+
+static void generateClassList(ClassSDict &classSDict)
+{
+ ClassSDict::Iterator cli(classSDict);
+ for ( ; cli.current() ; ++cli )
+ {
+ ClassDef *cd=cli.current();
+
+ //printf("cd=%s getOuterScope=%p global=%p\n",cd->name().data(),cd->getOuterScope(),Doxygen::globalScope);
+ if ((cd->getOuterScope()==0 || // <-- should not happen, but can if we read an old tag file
+ cd->getOuterScope()==Doxygen::globalScope // only look at global classes
+ ) && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
+ )
+ {
+ // skip external references, anonymous compounds and
+ // template instances
+ if ( cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ msg("Generating docs for compound %s...\n",cd->name().data());
+
+ cd->writeDocumentation(*g_outputList);
+ cd->writeMemberList(*g_outputList);
+ }
+ // even for undocumented classes, the inner classes can be documented.
+ cd->writeDocumentationForInnerClasses(*g_outputList);
+ }
+ }
+}
+
+static void generateClassDocs()
+{
+ generateClassList(*Doxygen::classSDict);
+ generateClassList(*Doxygen::hiddenClasses);
+}
+
+//----------------------------------------------------------------------------
+
+static void inheritDocumentation()
+{
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ MemberName *mn;
+ //int count=0;
+ for (;(mn=mnli.current());++mnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ for (;(md=mni.current());++mni)
+ {
+ //printf("%04d Member `%s'\n",count++,md->name().data());
+ if (md->documentation().isEmpty() && md->briefDescription().isEmpty())
+ { // no documentation yet
+ MemberDef *bmd = md->reimplements();
+ while (bmd && bmd->documentation().isEmpty() &&
+ bmd->briefDescription().isEmpty()
+ )
+ { // search up the inheritance tree for a documentation member
+ //printf("bmd=%s class=%s\n",bmd->name().data(),bmd->getClassDef()->name().data());
+ bmd = bmd->reimplements();
+ }
+ if (bmd) // copy the documentation from the reimplemented member
+ {
+ md->setInheritsDocsFrom(bmd);
+ md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
+ md->setDocsForDefinition(bmd->isDocsForDefinition());
+ md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
+ md->copyArgumentNames(bmd);
+ md->setInbodyDocumentation(bmd->inbodyDocumentation(),bmd->inbodyFile(),bmd->inbodyLine());
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void combineUsingRelations()
+{
+ // for each file
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ fd->visited=FALSE;
+ }
+ }
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ fd->combineUsingRelations();
+ }
+ }
+
+ // for each namespace
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (nli.toFirst() ; (nd=nli.current()) ; ++nli )
+ {
+ nd->visited=FALSE;
+ }
+ for (nli.toFirst() ; (nd=nli.current()) ; ++nli )
+ {
+ nd->combineUsingRelations();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void addMembersToMemberGroup()
+{
+ // for each class
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for ( ; (cd=cli.current()) ; ++cli )
+ {
+ cd->addMembersToMemberGroup();
+ }
+ // for each file
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ fd->addMembersToMemberGroup();
+ }
+ }
+ // for each namespace
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for ( ; (nd=nli.current()) ; ++nli )
+ {
+ nd->addMembersToMemberGroup();
+ }
+ // for each group
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->addMembersToMemberGroup();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void distributeMemberGroupDocumentation()
+{
+ // for each class
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for ( ; (cd=cli.current()) ; ++cli )
+ {
+ cd->distributeMemberGroupDocumentation();
+ }
+ // for each file
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ fd->distributeMemberGroupDocumentation();
+ }
+ }
+ // for each namespace
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for ( ; (nd=nli.current()) ; ++nli )
+ {
+ nd->distributeMemberGroupDocumentation();
+ }
+ // for each group
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->distributeMemberGroupDocumentation();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void findSectionsInDocumentation()
+{
+ // for each class
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for ( ; (cd=cli.current()) ; ++cli )
+ {
+ cd->findSectionsInDocumentation();
+ }
+ // for each file
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ fd->findSectionsInDocumentation();
+ }
+ }
+ // for each namespace
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for ( ; (nd=nli.current()) ; ++nli )
+ {
+ nd->findSectionsInDocumentation();
+ }
+ // for each group
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->findSectionsInDocumentation();
+ }
+ // for each page
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ pd->findSectionsInDocumentation();
+ }
+ if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
+}
+
+static void flushCachedTemplateRelations()
+{
+ // remove all references to classes from the cache
+ // as there can be new template instances in the inheritance path
+ // to this class. Optimization: only remove those classes that
+ // have inheritance instances as direct or indirect sub classes.
+ QCacheIterator<LookupInfo> ci(*Doxygen::lookupCache);
+ LookupInfo *li=0;
+ for (ci.toFirst();(li=ci.current());++ci)
+ {
+ if (li->classDef)
+ {
+ Doxygen::lookupCache->remove(ci.currentKey());
+ }
+ }
+ // remove all cached typedef resolutions whose target is a
+ // template class as this may now be a template instance
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ MemberName *fn;
+ for (;(fn=fnli.current());++fnli) // for each global function name
+ {
+ MemberNameIterator fni(*fn);
+ MemberDef *fmd;
+ for (;(fmd=fni.current());++fni) // for each function with that name
+ {
+ if (fmd->isTypedefValCached())
+ {
+ ClassDef *cd = fmd->getCachedTypedefVal();
+ if (cd->isTemplate()) fmd->invalidateTypedefValCache();
+ }
+ }
+ }
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ for (;(fn=mnli.current());++mnli) // for each class method name
+ {
+ MemberNameIterator mni(*fn);
+ MemberDef *fmd;
+ for (;(fmd=mni.current());++mni) // for each function with that name
+ {
+ if (fmd->isTypedefValCached())
+ {
+ ClassDef *cd = fmd->getCachedTypedefVal();
+ if (cd->isTemplate()) fmd->invalidateTypedefValCache();
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void flushUnresolvedRelations()
+{
+ // Remove all unresolved references to classes from the cache.
+ // This is needed before resolving the inheritance relations, since
+ // it would otherwise not find the inheritance relation
+ // for C in the example below, as B::I was already found to be unresolvable
+ // (which is correct if you igore the inheritance relation between A and B).
+ //
+ // class A { class I {} };
+ // class B : public A {};
+ // class C : public B::I {};
+ //
+ QCacheIterator<LookupInfo> ci(*Doxygen::lookupCache);
+ LookupInfo *li=0;
+ for (ci.toFirst();(li=ci.current());++ci)
+ {
+ if (li->classDef==0 && li->typeDef==0)
+ {
+ Doxygen::lookupCache->remove(ci.currentKey());
+ }
+ }
+
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ MemberName *fn;
+ for (;(fn=fnli.current());++fnli) // for each global function name
+ {
+ MemberNameIterator fni(*fn);
+ MemberDef *fmd;
+ for (;(fmd=fni.current());++fni) // for each function with that name
+ {
+ fmd->invalidateCachedArgumentTypes();
+ }
+ }
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ for (;(fn=mnli.current());++mnli) // for each class method name
+ {
+ MemberNameIterator mni(*fn);
+ MemberDef *fmd;
+ for (;(fmd=mni.current());++mni) // for each function with that name
+ {
+ fmd->invalidateCachedArgumentTypes();
+ }
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+static void findDefineDocumentation(EntryNav *rootNav)
+{
+ if ((rootNav->section()==Entry::DEFINEDOC_SEC ||
+ rootNav->section()==Entry::DEFINE_SEC) && !rootNav->name().isEmpty()
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ //printf("found define `%s' `%s' brief=`%s' doc=`%s'\n",
+ // root->name.data(),root->args.data(),root->brief.data(),root->doc.data());
+
+ if (rootNav->tagInfo() && !root->name.isEmpty()) // define read from a tag file
+ {
+ MemberDef *md=new MemberDef("<tagfile>",1,1,
+ "#define",root->name,root->args,0,
+ Public,Normal,FALSE,Member,MemberType_Define,0,0);
+ md->setTagInfo(rootNav->tagInfo());
+ md->setLanguage(root->lang);
+ //printf("Searching for `%s' fd=%p\n",filePathName.data(),fd);
+ md->setFileDef(rootNav->parent()->fileDef());
+ //printf("Adding member=%s\n",md->name().data());
+ MemberName *mn;
+ if ((mn=Doxygen::functionNameSDict->find(root->name)))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(root->name);
+ mn->append(md);
+ Doxygen::functionNameSDict->append(root->name,mn);
+ }
+ }
+ MemberName *mn=Doxygen::functionNameSDict->find(root->name);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md;
+ int count=0;
+ for (;(md=mni.current());++mni)
+ {
+ if (md->memberType()==MemberType_Define) count++;
+ }
+ if (count==1)
+ {
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->memberType()==MemberType_Define)
+ {
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ if (md->inbodyDocumentation().isEmpty())
+ {
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ }
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(rootNav->fileDef());
+ md->addSectionsToDefinition(root->anchors);
+ md->setMaxInitLines(root->initLines);
+ md->setRefItems(root->sli);
+ if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
+ addMemberToGroups(root,md);
+ }
+ }
+ }
+ else if (count>1 &&
+ (!root->doc.isEmpty() ||
+ !root->brief.isEmpty() ||
+ root->bodyLine!=-1
+ )
+ )
+ // multiple defines don't know where to add docs
+ // but maybe they are in different files together with their documentation
+ {
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->memberType()==MemberType_Define)
+ {
+ FileDef *fd=md->getFileDef();
+ if (fd && fd->absFilePath()==root->fileName)
+ // doc and define in the same file assume they belong together.
+ {
+#if 0
+ if (md->documentation().isEmpty())
+#endif
+ {
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setDocsForDefinition(!root->proto);
+ }
+#if 0
+ if (md->briefDescription().isEmpty())
+#endif
+ {
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ }
+ if (md->inbodyDocumentation().isEmpty())
+ {
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ }
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ md->setBodyDef(rootNav->fileDef());
+ md->addSectionsToDefinition(root->anchors);
+ md->setRefItems(root->sli);
+ md->setLanguage(root->lang);
+ if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
+ addMemberToGroups(root,md);
+ }
+ }
+ }
+ //warn("define %s found in the following files:\n",root->name.data());
+ //warn("Cannot determine where to add the documentation found "
+ // "at line %d of file %s. \n",
+ // root->startLine,root->fileName.data());
+ }
+ }
+ else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
+ {
+ static bool preEnabled = Config_getBool("ENABLE_PREPROCESSING");
+ if (preEnabled)
+ {
+ warn(root->fileName,root->startLine,
+ "documentation for unknown define %s found.\n",
+ root->name.data()
+ );
+ }
+ else
+ {
+ warn(root->fileName,root->startLine,
+ "found documented #define but ignoring it because "
+ "ENABLE_PREPROCESSING is NO.\n",
+ root->name.data()
+ );
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findDefineDocumentation,rootNav);
+}
+
+//----------------------------------------------------------------------------
+
+static void findDirDocumentation(EntryNav *rootNav)
+{
+ if (rootNav->section() == Entry::DIRDOC_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ QCString normalizedName = root->name;
+ normalizedName = substitute(normalizedName,"\\","/");
+ //printf("root->docFile=%s normalizedName=%s\n",
+ // root->docFile.data(),normalizedName.data());
+ if (root->docFile==normalizedName) // current dir?
+ {
+ int lastSlashPos=normalizedName.findRev('/');
+ if (lastSlashPos!=-1) // strip file name
+ {
+ normalizedName=normalizedName.left(lastSlashPos);
+ }
+ }
+ if (normalizedName.at(normalizedName.length()-1)!='/')
+ {
+ normalizedName+='/';
+ }
+ DirDef *dir,*matchingDir=0;
+ SDict<DirDef>::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ //printf("Dir: %s<->%s\n",dir->name().data(),normalizedName.data());
+ if (dir->name().right(normalizedName.length())==normalizedName)
+ {
+ if (matchingDir)
+ {
+ warn(root->fileName,root->startLine,
+ "\\dir command matches multiple directories.\n"
+ " Applying the command for directory %s\n"
+ " Ignoring the command for directory %s\n",
+ matchingDir->name().data(),dir->name().data()
+ );
+ }
+ else
+ {
+ matchingDir=dir;
+ }
+ }
+ }
+ if (matchingDir)
+ {
+ //printf("Match for with dir %s\n",matchingDir->name().data());
+ matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
+ matchingDir->setRefItems(root->sli);
+ addDirToGroups(root,matchingDir);
+ }
+ else
+ {
+ warn(root->fileName,root->startLine,"No matching "
+ "directory found for command \\dir %s\n",normalizedName.data());
+ }
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findDirDocumentation,rootNav);
+}
+
+
+//----------------------------------------------------------------------------
+// create a (sorted) list of separate documentation pages
+
+static void buildPageList(EntryNav *rootNav)
+{
+ if (rootNav->section() == Entry::PAGEDOC_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ if (!root->name.isEmpty())
+ {
+ addRelatedPage(rootNav);
+ }
+
+ rootNav->releaseEntry();
+ }
+ else if (rootNav->section() == Entry::MAINPAGEDOC_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ QCString title=root->args.stripWhiteSpace();
+ if (title.isEmpty()) title=theTranslator->trMainPage();
+ //QCString name = Config_getBool("GENERATE_TREEVIEW")?"main":"index";
+ QCString name = "index";
+ addRefItem(root->sli,
+ name,
+ "page",
+ name,
+ title,
+ 0
+ );
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildPageList,rootNav);
+}
+
+// search for the main page defined in this project
+static void findMainPage(EntryNav *rootNav)
+{
+ if (rootNav->section() == Entry::MAINPAGEDOC_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+
+ if (Doxygen::mainPage==0 && rootNav->tagInfo()==0)
+ {
+ Entry *root = rootNav->entry();
+ //printf("Found main page! \n======\n%s\n=======\n",root->doc.data());
+ QCString title=root->args.stripWhiteSpace();
+ //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
+ QCString indexName="index";
+ Doxygen::mainPage = new PageDef(root->docFile,root->docLine,
+ indexName, root->brief+root->doc+root->inbodyDocs,title);
+ //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
+ Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ Doxygen::mainPage->setFileName(indexName,TRUE);
+ Doxygen::mainPage->setShowToc(root->stat);
+ addPageToContext(Doxygen::mainPage,rootNav);
+
+ SectionInfo *si = Doxygen::sectionDict->find(Doxygen::mainPage->name());
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s, line %d)",Doxygen::mainPage->name().data(),si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s)",Doxygen::mainPage->name().data(),si->fileName.data());
+ }
+ }
+ else
+ {
+ // a page name is a label as well! but should no be double either
+ si=new SectionInfo(
+ indexName, root->startLine,
+ Doxygen::mainPage->name(),
+ Doxygen::mainPage->title(),
+ SectionInfo::Page,
+ 0); // level 0
+ Doxygen::sectionDict->append(indexName,si);
+ Doxygen::mainPage->addSectionsToDefinition(root->anchors);
+ }
+ }
+ else if (rootNav->tagInfo()==0)
+ {
+ Entry *root = rootNav->entry();
+ warn(root->fileName,root->startLine,
+ "found more than one \\mainpage comment block! Skipping this "
+ "block."
+ );
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(findMainPage,rootNav);
+}
+
+// search for the main page imported via tag files and add only the section labels
+static void findMainPageTagFiles(EntryNav *rootNav)
+{
+ if (rootNav->section() == Entry::MAINPAGEDOC_SEC)
+ {
+ rootNav->loadEntry(g_storage);
+
+ if (Doxygen::mainPage && rootNav->tagInfo())
+ {
+ Entry *root = rootNav->entry();
+ Doxygen::mainPage->addSectionsToDefinition(root->anchors);
+ }
+ }
+ RECURSE_ENTRYTREE(findMainPageTagFiles,rootNav);
+}
+
+static void computePageRelations(EntryNav *rootNav)
+{
+ if ((rootNav->section()==Entry::PAGEDOC_SEC ||
+ rootNav->section()==Entry::MAINPAGEDOC_SEC
+ )
+ && !rootNav->name().isEmpty()
+ )
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ PageDef *pd = root->section==Entry::PAGEDOC_SEC ?
+ Doxygen::pageSDict->find(root->name) :
+ Doxygen::mainPage;
+ if (pd)
+ {
+ QListIterator<BaseInfo> bii(*root->extends);
+ BaseInfo *bi;
+ for (bii.toFirst();(bi=bii.current());++bii)
+ {
+ PageDef *subPd = Doxygen::pageSDict->find(bi->name);
+ if (subPd)
+ {
+ pd->addInnerCompound(subPd);
+ //printf("*** Added subpage relation: %s->%s\n",
+ // pd->name().data(),subPd->name().data());
+ }
+ }
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(computePageRelations,rootNav);
+}
+
+static void checkPageRelations()
+{
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ Definition *ppd = pd->getOuterScope();
+ while (ppd)
+ {
+ if (ppd==pd)
+ {
+ err("page defined at line %d of file %s with label %s is a subpage "
+ "of itself! Please remove this cyclic dependency.\n",
+ pd->docLine(),pd->docFile().data(),pd->name().data());
+ exit(1);
+ }
+ ppd=ppd->getOuterScope();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void resolveUserReferences()
+{
+ SDict<SectionInfo>::Iterator sdi(*Doxygen::sectionDict);
+ SectionInfo *si;
+ for (;(si=sdi.current());++sdi)
+ {
+ //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
+ // si->label.data(),si->definition?si->definition->name().data():"<none>",
+ // si->fileName.data());
+ PageDef *pd=0;
+
+ // hack: the items of a todo/test/bug/deprecated list are all fragments from
+ // different files, so the resulting section's all have the wrong file
+ // name (not from the todo/test/bug/deprecated list, but from the file in
+ // which they are defined). We correct this here by looking at the
+ // generated section labels!
+ QDictIterator<RefList> rli(*Doxygen::xrefLists);
+ RefList *rl;
+ for (rli.toFirst();(rl=rli.current());++rli)
+ {
+ QCString label="_"+rl->listName(); // "_todo", "_test", ...
+ if (si->label.left(label.length())==label)
+ {
+ si->fileName=rl->listName();
+ si->generated=TRUE;
+ break;
+ }
+ }
+
+ //printf("start: si->label=%s si->fileName=%s\n",si->label.data(),si->fileName.data());
+ if (!si->generated)
+ {
+ // if this section is in a page and the page is in a group, then we
+ // have to adjust the link file name to point to the group.
+ if (!si->fileName.isEmpty() &&
+ (pd=Doxygen::pageSDict->find(si->fileName)) &&
+ pd->getGroupDef())
+ {
+ si->fileName=pd->getGroupDef()->getOutputFileBase().copy();
+ }
+
+ if (si->definition)
+ {
+ // TODO: there should be one function in Definition that returns
+ // the file to link to, so we can avoid the following tests.
+ GroupDef *gd=0;
+ if (si->definition->definitionType()==Definition::TypeMember)
+ {
+ gd = ((MemberDef *)si->definition)->getGroupDef();
+ }
+
+ if (gd)
+ {
+ si->fileName=gd->getOutputFileBase().copy();
+ }
+ else
+ {
+ //si->fileName=si->definition->getOutputFileBase().copy();
+ //printf("Setting si->fileName to %s\n",si->fileName.data());
+ }
+ }
+ }
+ //printf("end: si->label=%s si->fileName=%s\n",si->label.data(),si->fileName.data());
+ }
+}
+
+
+
+//----------------------------------------------------------------------------
+// generate all separate documentation pages
+
+
+static void generatePageDocs()
+{
+ //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageSDict->count());
+ if (documentedPages==0) return;
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (!pd->getGroupDef() && !pd->isReference())
+ {
+ msg("Generating docs for page %s...\n",pd->name().data());
+ Doxygen::insideMainPage=TRUE;
+ pd->writeDocumentation(*g_outputList);
+ Doxygen::insideMainPage=FALSE;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+// create a (sorted) list & dictionary of example pages
+
+static void buildExampleList(EntryNav *rootNav)
+{
+ if (rootNav->section()==Entry::EXAMPLE_SEC && !rootNav->name().isEmpty())
+ {
+ rootNav->loadEntry(g_storage);
+ Entry *root = rootNav->entry();
+
+ if (Doxygen::exampleSDict->find(root->name))
+ {
+ warn(root->fileName,root->startLine,
+ "Example %s was already documented. Ignoring "
+ "documentation found here.",
+ root->name.data()
+ );
+ }
+ else
+ {
+ PageDef *pd=new PageDef(root->fileName,root->startLine,
+ root->name,root->brief+root->doc+root->inbodyDocs,root->args);
+ pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE),FALSE);
+ pd->addSectionsToDefinition(root->anchors);
+ pd->setLanguage(root->lang);
+ //pi->addSections(root->anchors);
+
+ Doxygen::exampleSDict->inSort(root->name,pd);
+ //we don't add example to groups
+ //addExampleToGroups(root,pd);
+ }
+
+ rootNav->releaseEntry();
+ }
+ RECURSE_ENTRYTREE(buildExampleList,rootNav);
+}
+
+//----------------------------------------------------------------------------
+// prints the Entry tree (for debugging)
+
+void printNavTree(EntryNav *rootNav,int indent)
+{
+ QCString indentStr;
+ indentStr.fill(' ',indent);
+ msg("%s%s (sec=0x%x)\n",
+ indentStr.isEmpty()?"":indentStr.data(),
+ rootNav->name().isEmpty()?"<empty>":rootNav->name().data(),
+ rootNav->section());
+ if (rootNav->children())
+ {
+ EntryNavListIterator eli(*rootNav->children());
+ for (;eli.current();++eli) printNavTree(eli.current(),indent+2);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// generate the example documentation
+
+static void generateExampleDocs()
+{
+ g_outputList->disable(OutputGenerator::Man);
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating docs for example %s...\n",pd->name().data());
+ resetCCodeParserState();
+ QCString n=pd->getOutputFileBase();
+ startFile(*g_outputList,n,n,pd->name());
+ startTitle(*g_outputList,n);
+ g_outputList->docify(pd->name());
+ endTitle(*g_outputList,n,0);
+ g_outputList->startContents();
+ g_outputList->generateDoc(pd->docFile(), // file
+ pd->docLine(), // startLine
+ pd, // context
+ 0, // memberDef
+ pd->documentation()+"\n\n\\include "+pd->name(), // docs
+ TRUE, // index words
+ TRUE, // is example
+ pd->name()
+ );
+ endFile(*g_outputList); // contains g_outputList->endContents()
+ }
+ g_outputList->enable(OutputGenerator::Man);
+}
+
+//----------------------------------------------------------------------------
+// generate module pages
+
+static void generateGroupDocs()
+{
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (!gd->isReference())
+ {
+ gd->writeDocumentation(*g_outputList);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+//static void generatePackageDocs()
+//{
+// writePackageIndex(*g_outputList);
+//
+// if (Doxygen::packageDict.count()>0)
+// {
+// PackageSDict::Iterator pdi(Doxygen::packageDict);
+// PackageDef *pd;
+// for (pdi.toFirst();(pd=pdi.current());++pdi)
+// {
+// pd->writeDocumentation(*g_outputList);
+// }
+// }
+//}
+
+//----------------------------------------------------------------------------
+// generate module pages
+
+static void generateNamespaceDocs()
+{
+ //writeNamespaceIndex(*g_outputList);
+
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ // for each namespace...
+ for (;(nd=nli.current());++nli)
+ {
+
+ if (nd->isLinkableInProject())
+ {
+ msg("Generating docs for namespace %s\n",nd->name().data());
+ nd->writeDocumentation(*g_outputList);
+ }
+
+ // for each class in the namespace...
+ ClassSDict::Iterator cli(*nd->getClassSDict());
+ for ( ; cli.current() ; ++cli )
+ {
+ ClassDef *cd=cli.current();
+ if ( ( cd->isLinkableInProject() &&
+ cd->templateMaster()==0
+ ) // skip external references, anonymous compounds and
+ // template instances and nested classes
+ && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
+ )
+ {
+ msg("Generating docs for compound %s...\n",cd->name().data());
+
+ cd->writeDocumentation(*g_outputList);
+ cd->writeMemberList(*g_outputList);
+ }
+ cd->writeDocumentationForInnerClasses(*g_outputList);
+ }
+ }
+}
+
+#if defined(_WIN32)
+static QCString fixSlashes(QCString &s)
+{
+ QCString result;
+ uint i;
+ for (i=0;i<s.length();i++)
+ {
+ switch(s.at(i))
+ {
+ case '/':
+ case '\\':
+ result+="\\\\";
+ break;
+ default:
+ result+=s.at(i);
+ }
+ }
+ return result;
+}
+#endif
+
+
+//----------------------------------------------------------------------------
+
+static bool openOutputFile(const char *outFile,QFile &f)
+{
+ bool fileOpened=FALSE;
+ bool writeToStdout=(outFile[0]=='-' && outFile[1]=='\0');
+ if (writeToStdout) // write to stdout
+ {
+ fileOpened = f.open(IO_WriteOnly,stdout);
+ }
+ else // write to file
+ {
+ QFileInfo fi(outFile);
+ if (fi.exists()) // create a backup
+ {
+ QDir dir=fi.dir();
+ QFileInfo backup(fi.fileName()+".bak");
+ if (backup.exists()) // remove existing backup
+ dir.remove(backup.fileName());
+ dir.rename(fi.fileName(),fi.fileName()+".bak");
+ }
+ f.setName(outFile);
+ fileOpened = f.open(IO_WriteOnly|IO_Translate);
+ }
+ return fileOpened;
+}
+
+/*! Generate a template version of the configuration file.
+ * If the \a shortList parameter is TRUE a configuration file without
+ * comments will be generated.
+ */
+static void generateConfigFile(const char *configFile,bool shortList,
+ bool updateOnly=FALSE)
+{
+ QFile f;
+ bool fileOpened=openOutputFile(configFile,f);
+ bool writeToStdout=(configFile[0]=='-' && configFile[1]=='\0');
+ if (fileOpened)
+ {
+ FTextStream t(&f);
+ Config::instance()->writeTemplate(t,shortList,updateOnly);
+ if (!writeToStdout)
+ {
+ if (!updateOnly)
+ {
+ msg("\n\nConfiguration file `%s' created.\n\n",configFile);
+ msg("Now edit the configuration file and enter\n\n");
+ if (qstrcmp(configFile,"Doxyfile") || qstrcmp(configFile,"doxyfile"))
+ msg(" doxygen %s\n\n",configFile);
+ else
+ msg(" doxygen\n\n");
+ msg("to generate the documentation for your project\n\n");
+ }
+ else
+ {
+ msg("\n\nConfiguration file `%s' updated.\n\n",configFile);
+ }
+ }
+ }
+ else
+ {
+ err("Cannot open file %s for writing\n",configFile);
+ exit(1);
+ }
+}
+
+//----------------------------------------------------------------------------
+// read and parse a tag file
+
+//static bool readLineFromFile(QFile &f,QCString &s)
+//{
+// char c=0;
+// s.resize(0);
+// while (!f.atEnd() && (c=f.getch())!='\n') s+=c;
+// return f.atEnd();
+//}
+
+//----------------------------------------------------------------------------
+
+static void readTagFile(Entry *root,const char *tl)
+{
+ QCString tagLine = tl;
+ QCString fileName;
+ QCString destName;
+ int eqPos = tagLine.find('=');
+ if (eqPos!=-1) // tag command contains a destination
+ {
+ fileName = tagLine.left(eqPos).stripWhiteSpace();
+ destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
+ QFileInfo fi(fileName);
+ Doxygen::tagDestinationDict.insert(fi.absFilePath().utf8(),new QCString(destName));
+ //printf("insert tagDestination %s->%s\n",fi.fileName().data(),destName.data());
+ }
+ else
+ {
+ fileName = tagLine;
+ }
+
+ QFileInfo fi(fileName);
+ if (!fi.exists() || !fi.isFile())
+ {
+ err("Tag file `%s' does not exist or is not a file. Skipping it...\n",
+ fileName.data());
+ return;
+ }
+
+ if (!destName.isEmpty())
+ msg("Reading tag file `%s', location `%s'...\n",fileName.data(),destName.data());
+ else
+ msg("Reading tag file `%s'...\n",fileName.data());
+
+ parseTagFile(root,fi.absFilePath().utf8());
+}
+
+//----------------------------------------------------------------------------
+static void copyStyleSheet()
+{
+ QCString &htmlStyleSheet = Config_getString("HTML_STYLESHEET");
+ if (!htmlStyleSheet.isEmpty())
+ {
+ QFileInfo fi(htmlStyleSheet);
+ if (!fi.exists())
+ {
+ err("Style sheet '%s' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet.data());
+ htmlStyleSheet.resize(0); // revert to the default
+ }
+ else
+ {
+ QCString destFileName = Config_getString("HTML_OUTPUT")+"/"+fi.fileName().data();
+ copyFile(htmlStyleSheet,destFileName);
+ }
+ }
+ QStrList htmlExtraStyleSheet = Config_getList("HTML_EXTRA_STYLESHEET");
+ for (uint i=0; i<htmlExtraStyleSheet.count(); ++i)
+ {
+ QCString fileName(htmlExtraStyleSheet.at(i));
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fi(fileName);
+ if (!fi.exists())
+ {
+ err("Style sheet '%s' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName.data());
+ }
+ else
+ {
+ QCString destFileName = Config_getString("HTML_OUTPUT")+"/"+fi.fileName().data();
+ copyFile(fileName, destFileName);
+ }
+ }
+ }
+}
+
+static void copyLogo()
+{
+ QCString &projectLogo = Config_getString("PROJECT_LOGO");
+ if (!projectLogo.isEmpty())
+ {
+ QFileInfo fi(projectLogo);
+ if (!fi.exists())
+ {
+ err("Project logo '%s' specified by PROJECT_LOGO does not exist!\n",projectLogo.data());
+ projectLogo.resize(0); // revert to the default
+ }
+ else
+ {
+ QCString destFileName = Config_getString("HTML_OUTPUT")+"/"+fi.fileName().data();
+ copyFile(projectLogo,destFileName);
+ Doxygen::indexList->addImageFile(fi.fileName().data());
+ }
+ }
+}
+
+static void copyExtraFiles(const QCString& filesOption,const QCString &outputOption)
+{
+ QStrList files = Config_getList(filesOption);
+ uint i;
+ for (i=0; i<files.count(); ++i)
+ {
+ QCString fileName(files.at(i));
+
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fi(fileName);
+ if (!fi.exists())
+ {
+ err("Extra file '%s' specified in " + filesOption + " does not exist!\n", fileName.data());
+ }
+ else
+ {
+ QCString destFileName = Config_getString(outputOption)+"/"+fi.fileName().data();
+ Doxygen::indexList->addImageFile(fi.fileName().utf8());
+ copyFile(fileName, destFileName);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static ParserInterface *getParserForFile(const char *fn)
+{
+ QCString fileName=fn;
+ QCString extension;
+ int ei = fileName.findRev('.');
+ if (ei!=-1)
+ {
+ extension=fileName.right(fileName.length()-ei);
+ }
+ else
+ {
+ extension = ".no_extension";
+ }
+
+ return Doxygen::parserManager->getParser(extension);
+}
+
+static void parseFile(ParserInterface *parser,
+ Entry *root,EntryNav *rootNav,FileDef *fd,const char *fn,
+ bool sameTu,QStrList &filesInSameTu)
+{
+#if USE_LIBCLANG
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+#else
+ static bool clangAssistedParsing = FALSE;
+#endif
+ QCString fileName=fn;
+ QCString extension;
+ int ei = fileName.findRev('.');
+ if (ei!=-1)
+ {
+ extension=fileName.right(fileName.length()-ei);
+ }
+ else
+ {
+ extension = ".no_extension";
+ }
+
+ QFileInfo fi(fileName);
+ BufStr preBuf(fi.size()+4096);
+
+ if (Config_getBool("ENABLE_PREPROCESSING") &&
+ parser->needsPreprocessing(extension))
+ {
+ BufStr inBuf(fi.size()+4096);
+ msg("Preprocessing %s...\n",fn);
+ readInputFile(fileName,inBuf);
+ preprocessFile(fileName,inBuf,preBuf);
+ }
+ else // no preprocessing
+ {
+ msg("Reading %s...\n",fn);
+ readInputFile(fileName,preBuf);
+ }
+
+ BufStr convBuf(preBuf.curPos()+1024);
+
+ // convert multi-line C++ comments to C style comments
+ convertCppComments(&preBuf,&convBuf,fileName);
+
+ convBuf.addChar('\0');
+
+ if (clangAssistedParsing && !sameTu)
+ {
+ fd->getAllIncludeFilesRecursively(filesInSameTu);
+ }
+
+ // use language parse to parse the file
+ parser->parseInput(fileName,convBuf.data(),root,sameTu,filesInSameTu);
+
+ // store the Entry tree in a file and create an index to
+ // navigate/load entries
+ //printf("root->createNavigationIndex for %s\n",fd->name().data());
+ root->createNavigationIndex(rootNav,g_storage,fd);
+}
+
+//! parse the list of input files
+static void parseFiles(Entry *root,EntryNav *rootNav)
+{
+#if USE_LIBCLANG
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (clangAssistedParsing)
+ {
+ QDict<void> g_processedFiles(10007);
+
+ // create a dictionary with files to process
+ QDict<void> g_filesToProcess(10007);
+ StringListIterator it(g_inputFiles);
+ QCString *s;
+ for (;(s=it.current());++it)
+ {
+ g_filesToProcess.insert(*s,(void*)0x8);
+ }
+
+ // process source files (and their include dependencies)
+ for (it.toFirst();(s=it.current());++it)
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig);
+ ASSERT(fd!=0);
+ if (fd->isSource() && !fd->isReference()) // this is a source file
+ {
+ QStrList filesInSameTu;
+ ParserInterface * parser = getParserForFile(s->data());
+ parser->startTranslationUnit(s->data());
+ parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
+ //printf(" got %d extra files in tu\n",filesInSameTu.count());
+
+ // Now process any include files in the same translation unit
+ // first. When libclang is used this is much more efficient.
+ char *incFile = filesInSameTu.first();
+ while (incFile && g_filesToProcess.find(incFile))
+ {
+ if (qstrcmp(incFile,s->data()) && !g_processedFiles.find(incFile))
+ {
+ FileDef *ifd=findFileDef(Doxygen::inputNameDict,incFile,ambig);
+ if (ifd && !ifd->isReference())
+ {
+ QStrList moreFiles;
+ //printf(" Processing %s in same translation unit as %s\n",incFile,s->data());
+ parseFile(parser,root,rootNav,ifd,incFile,TRUE,moreFiles);
+ g_processedFiles.insert(incFile,(void*)0x8);
+ }
+ }
+ incFile = filesInSameTu.next();
+ }
+ parser->finishTranslationUnit();
+ g_processedFiles.insert(*s,(void*)0x8);
+ }
+ }
+ // process remaining files
+ for (it.toFirst();(s=it.current());++it)
+ {
+ if (!g_processedFiles.find(*s)) // not yet processed
+ {
+ bool ambig;
+ QStrList filesInSameTu;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig);
+ ASSERT(fd!=0);
+ ParserInterface * parser = getParserForFile(s->data());
+ parser->startTranslationUnit(s->data());
+ parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
+ parser->finishTranslationUnit();
+ g_processedFiles.insert(*s,(void*)0x8);
+ }
+ }
+ }
+ else // normal pocessing
+#endif
+ {
+ StringListIterator it(g_inputFiles);
+ QCString *s;
+ for (;(s=it.current());++it)
+ {
+ bool ambig;
+ QStrList filesInSameTu;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig);
+ ASSERT(fd!=0);
+ ParserInterface * parser = getParserForFile(s->data());
+ parser->startTranslationUnit(s->data());
+ parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
+ }
+ }
+}
+
+// resolves a path that may include symlinks, if a recursive symlink is
+// found an empty string is returned.
+static QCString resolveSymlink(QCString path)
+{
+ int sepPos=0;
+ int oldPos=0;
+ QFileInfo fi;
+ QDict<void> nonSymlinks;
+ QDict<void> known;
+ QCString result = path;
+ QCString oldPrefix = "/";
+ do
+ {
+#ifdef WIN32
+ // UNC path, skip server and share name
+ if (sepPos==0 && (result.left(2)=="//" || result.left(2)=="\\\\"))
+ sepPos = result.find('/',2);
+ if (sepPos!=-1)
+ sepPos = result.find('/',sepPos+1);
+#else
+ sepPos = result.find('/',sepPos+1);
+#endif
+ QCString prefix = sepPos==-1 ? result : result.left(sepPos);
+ if (nonSymlinks.find(prefix)==0)
+ {
+ fi.setFile(prefix);
+ if (fi.isSymLink())
+ {
+ QString target = fi.readLink();
+ bool isRelative = QFileInfo(target).isRelative();
+ if (isRelative)
+ {
+ target = QDir::cleanDirPath(oldPrefix+"/"+target.data());
+ }
+ if (sepPos!=-1)
+ {
+ if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
+ {
+ target+='/';
+ }
+ target+=result.mid(sepPos);
+ }
+ result = QDir::cleanDirPath(target).data();
+ sepPos = 0;
+ if (known.find(result)) return QCString(); // recursive symlink!
+ known.insert(result,(void*)0x8);
+ if (isRelative)
+ {
+ sepPos = oldPos;
+ }
+ else // link to absolute path
+ {
+ sepPos = 0;
+ oldPrefix = "/";
+ }
+ }
+ else
+ {
+ nonSymlinks.insert(prefix,(void*)0x8);
+ oldPrefix = prefix;
+ }
+ oldPos = sepPos;
+ }
+ }
+ while (sepPos!=-1);
+ return QDir::cleanDirPath(result).data();
+}
+
+static QDict<void> g_pathsVisited(1009);
+
+//----------------------------------------------------------------------------
+// Read all files matching at least one pattern in `patList' in the
+// directory represented by `fi'.
+// The directory is read iff the recusiveFlag is set.
+// The contents of all files is append to the input string
+
+int readDir(QFileInfo *fi,
+ FileNameList *fnList,
+ FileNameDict *fnDict,
+ StringDict *exclDict,
+ QStrList *patList,
+ QStrList *exclPatList,
+ StringList *resultList,
+ StringDict *resultDict,
+ bool errorIfNotExist,
+ bool recursive,
+ QDict<void> *killDict,
+ QDict<void> *paths
+ )
+{
+ QCString dirName = fi->absFilePath().utf8();
+ if (paths && paths->find(dirName)==0)
+ {
+ paths->insert(dirName,(void*)0x8);
+ }
+ if (fi->isSymLink())
+ {
+ dirName = resolveSymlink(dirName.data());
+ if (dirName.isEmpty()) return 0; // recusive symlink
+ if (g_pathsVisited.find(dirName)) return 0; // already visited path
+ g_pathsVisited.insert(dirName,(void*)0x8);
+ }
+ QDir dir(dirName);
+ dir.setFilter( QDir::Files | QDir::Dirs | QDir::Hidden );
+ int totalSize=0;
+ msg("Searching for files in directory %s\n", fi->absFilePath().data());
+ //printf("killDict=%p count=%d\n",killDict,killDict->count());
+
+ const QFileInfoList *list = dir.entryInfoList();
+ if (list)
+ {
+ QFileInfoListIterator it( *list );
+ QFileInfo *cfi;
+
+ while ((cfi=it.current()))
+ {
+ if (exclDict==0 || exclDict->find(cfi->absFilePath().utf8())==0)
+ { // file should not be excluded
+ //printf("killDict->find(%s)\n",cfi->absFilePath().data());
+ if (!cfi->exists() || !cfi->isReadable())
+ {
+ if (errorIfNotExist)
+ {
+ warn_uncond("source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data());
+ }
+ }
+ else if (cfi->isFile() &&
+ (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
+ (patList==0 || patternMatch(*cfi,patList)) &&
+ !patternMatch(*cfi,exclPatList) &&
+ (killDict==0 || killDict->find(cfi->absFilePath().utf8())==0)
+ )
+ {
+ totalSize+=cfi->size()+cfi->absFilePath().length()+4;
+ QCString name=cfi->fileName().utf8();
+ //printf("New file %s\n",name.data());
+ if (fnDict)
+ {
+ FileDef *fd=new FileDef(cfi->dirPath().utf8()+"/",name);
+ FileName *fn=0;
+ if (!name.isEmpty() && (fn=(*fnDict)[name]))
+ {
+ fn->append(fd);
+ }
+ else
+ {
+ fn = new FileName(cfi->absFilePath().utf8(),name);
+ fn->append(fd);
+ if (fnList) fnList->inSort(fn);
+ fnDict->insert(name,fn);
+ }
+ }
+ QCString *rs=0;
+ if (resultList || resultDict)
+ {
+ rs=new QCString(cfi->absFilePath().utf8());
+ }
+ if (resultList) resultList->append(rs);
+ if (resultDict) resultDict->insert(cfi->absFilePath().utf8(),rs);
+ if (killDict) killDict->insert(cfi->absFilePath().utf8(),(void *)0x8);
+ }
+ else if (recursive &&
+ (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
+ cfi->isDir() &&
+ !patternMatch(*cfi,exclPatList) &&
+ cfi->fileName().at(0)!='.') // skip "." ".." and ".dir"
+ {
+ cfi->setFile(cfi->absFilePath());
+ totalSize+=readDir(cfi,fnList,fnDict,exclDict,
+ patList,exclPatList,resultList,resultDict,errorIfNotExist,
+ recursive,killDict,paths);
+ }
+ }
+ ++it;
+ }
+ }
+ return totalSize;
+}
+
+
+//----------------------------------------------------------------------------
+// read a file or all files in a directory and append their contents to the
+// input string. The names of the files are appended to the `fiList' list.
+
+int readFileOrDirectory(const char *s,
+ FileNameList *fnList,
+ FileNameDict *fnDict,
+ StringDict *exclDict,
+ QStrList *patList,
+ QStrList *exclPatList,
+ StringList *resultList,
+ StringDict *resultDict,
+ bool recursive,
+ bool errorIfNotExist,
+ QDict<void> *killDict,
+ QDict<void> *paths
+ )
+{
+ //printf("killDict=%p count=%d\n",killDict,killDict->count());
+ // strip trailing slashes
+ if (s==0) return 0;
+ QCString fs = s;
+ char lc = fs.at(fs.length()-1);
+ if (lc=='/' || lc=='\\') fs = fs.left(fs.length()-1);
+
+ QFileInfo fi(fs);
+ //printf("readFileOrDirectory(%s)\n",s);
+ int totalSize=0;
+ {
+ if (exclDict==0 || exclDict->find(fi.absFilePath().utf8())==0)
+ {
+ if (!fi.exists() || !fi.isReadable())
+ {
+ if (errorIfNotExist)
+ {
+ warn_uncond("source %s is not a readable file or directory... skipping.\n",s);
+ }
+ }
+ else if (!Config_getBool("EXCLUDE_SYMLINKS") || !fi.isSymLink())
+ {
+ if (fi.isFile())
+ {
+ QCString dirPath = fi.dirPath(TRUE).utf8();
+ QCString filePath = fi.absFilePath().utf8();
+ if (paths && paths->find(dirPath))
+ {
+ paths->insert(dirPath,(void*)0x8);
+ }
+ //printf("killDict->find(%s)\n",fi.absFilePath().data());
+ if (killDict==0 || killDict->find(filePath)==0)
+ {
+ totalSize+=fi.size()+fi.absFilePath().length()+4; //readFile(&fi,fiList,input);
+ //fiList->inSort(new FileInfo(fi));
+ QCString name=fi.fileName().utf8();
+ //printf("New file %s\n",name.data());
+ if (fnDict)
+ {
+ FileDef *fd=new FileDef(dirPath+"/",name);
+ FileName *fn=0;
+ if (!name.isEmpty() && (fn=(*fnDict)[name]))
+ {
+ fn->append(fd);
+ }
+ else
+ {
+ fn = new FileName(filePath,name);
+ fn->append(fd);
+ if (fnList) fnList->inSort(fn);
+ fnDict->insert(name,fn);
+ }
+ }
+ QCString *rs=0;
+ if (resultList || resultDict)
+ {
+ rs=new QCString(filePath);
+ if (resultList) resultList->append(rs);
+ if (resultDict) resultDict->insert(filePath,rs);
+ }
+
+ if (killDict) killDict->insert(fi.absFilePath().utf8(),(void *)0x8);
+ }
+ }
+ else if (fi.isDir()) // readable dir
+ {
+ totalSize+=readDir(&fi,fnList,fnDict,exclDict,patList,
+ exclPatList,resultList,resultDict,errorIfNotExist,
+ recursive,killDict,paths);
+ }
+ }
+ }
+ }
+ return totalSize;
+}
+
+//----------------------------------------------------------------------------
+
+void readFormulaRepository()
+{
+ QFile f(Config_getString("HTML_OUTPUT")+"/formula.repository");
+ if (f.open(IO_ReadOnly)) // open repository
+ {
+ msg("Reading formula repository...\n");
+ QTextStream t(&f);
+ QCString line;
+ while (!t.eof())
+ {
+ line=t.readLine().utf8();
+ int se=line.find(':'); // find name and text separator.
+ if (se==-1)
+ {
+ warn_uncond("formula.repository is corrupted!\n");
+ break;
+ }
+ else
+ {
+ QCString formName = line.left(se);
+ QCString formText = line.right(line.length()-se-1);
+ Formula *f=new Formula(formText);
+ Doxygen::formulaList->setAutoDelete(TRUE);
+ Doxygen::formulaList->append(f);
+ Doxygen::formulaDict->insert(formText,f);
+ Doxygen::formulaNameDict->insert(formName,f);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void expandAliases()
+{
+ QDictIterator<QCString> adi(Doxygen::aliasDict);
+ QCString *s;
+ for (adi.toFirst();(s=adi.current());++adi)
+ {
+ *s = expandAlias(adi.currentKey(),*s);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void escapeAliases()
+{
+ QDictIterator<QCString> adi(Doxygen::aliasDict);
+ QCString *s;
+ for (adi.toFirst();(s=adi.current());++adi)
+ {
+ QCString value=*s,newValue;
+ int in,p=0;
+ // for each \n in the alias command value
+ while ((in=value.find("\\n",p))!=-1)
+ {
+ newValue+=value.mid(p,in-p);
+ // expand \n's except if \n is part of a built-in command.
+ if (value.mid(in,5)!="\\note" &&
+ value.mid(in,5)!="\\name" &&
+ value.mid(in,10)!="\\namespace" &&
+ value.mid(in,14)!="\\nosubgrouping"
+ )
+ {
+ newValue+="\\_linebr ";
+ }
+ else
+ {
+ newValue+="\\n";
+ }
+ p=in+2;
+ }
+ newValue+=value.mid(p,value.length()-p);
+ *s=newValue;
+ //printf("Alias %s has value %s\n",adi.currentKey().data(),s->data());
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void readAliases()
+{
+ // add aliases to a dictionary
+ Doxygen::aliasDict.setAutoDelete(TRUE);
+ QStrList &aliasList = Config_getList("ALIASES");
+ const char *s=aliasList.first();
+ while (s)
+ {
+ if (Doxygen::aliasDict[s]==0)
+ {
+ QCString alias=s;
+ int i=alias.find('=');
+ if (i>0)
+ {
+ QCString name=alias.left(i).stripWhiteSpace();
+ QCString value=alias.right(alias.length()-i-1);
+ //printf("Alias: found name=`%s' value=`%s'\n",name.data(),value.data());
+ if (!name.isEmpty())
+ {
+ QCString *dn=Doxygen::aliasDict[name];
+ if (dn==0) // insert new alias
+ {
+ Doxygen::aliasDict.insert(name,new QCString(value));
+ }
+ else // overwrite previous alias
+ {
+ *dn=value;
+ }
+ }
+ }
+ }
+ s=aliasList.next();
+ }
+ expandAliases();
+ escapeAliases();
+}
+
+//----------------------------------------------------------------------------
+
+static void dumpSymbol(FTextStream &t,Definition *d)
+{
+ QCString anchor;
+ if (d->definitionType()==Definition::TypeMember)
+ {
+ MemberDef *md = (MemberDef *)d;
+ anchor=":"+md->anchor();
+ }
+ QCString scope;
+ if (d->getOuterScope() && d->getOuterScope()!=Doxygen::globalScope)
+ {
+ scope = d->getOuterScope()->getOutputFileBase()+Doxygen::htmlFileExtension;
+ }
+ t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
+ << d->getOutputFileBase()+Doxygen::htmlFileExtension+anchor << "','"
+ << scope << "','"
+ << d->name() << "','"
+ << d->getDefFileName() << "','"
+ << d->getDefLine()
+ << "');" << endl;
+}
+
+static void dumpSymbolMap()
+{
+ QFile f("symbols.sql");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap);
+ DefinitionIntf *intf;
+ for (;(intf=di.current());++di)
+ {
+ if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
+ {
+ DefinitionListIterator dli(*(DefinitionList*)intf);
+ Definition *d;
+ // for each symbol
+ for (dli.toFirst();(d=dli.current());++dli)
+ {
+ dumpSymbol(t,d);
+ }
+ }
+ else // single symbol
+ {
+ Definition *d = (Definition *)intf;
+ if (d!=Doxygen::globalScope) dumpSymbol(t,d);
+ }
+ }
+ }
+}
+
+// print developer options of doxygen
+static void devUsage()
+{
+ msg("Developer parameters:\n");
+ msg(" -m dump symbol map\n");
+ msg(" -b output to wizard\n");
+ msg(" -T activates output generation via Django like template\n");
+ msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
+ Debug::printFlags();
+}
+
+
+//----------------------------------------------------------------------------
+// print the usage of doxygen
+
+static void usage(const char *name)
+{
+ msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2014\n\n",versionString);
+ msg("You can use doxygen in a number of ways:\n\n");
+ msg("1) Use doxygen to generate a template configuration file:\n");
+ msg(" %s [-s] -g [configName]\n\n",name);
+ msg(" If - is used for configName doxygen will write to standard output.\n\n");
+ msg("2) Use doxygen to update an old configuration file:\n");
+ msg(" %s [-s] -u [configName]\n\n",name);
+ msg("3) Use doxygen to generate documentation using an existing ");
+ msg("configuration file:\n");
+ msg(" %s [configName]\n\n",name);
+ msg(" If - is used for configName doxygen will read from standard input.\n\n");
+ msg("4) Use doxygen to generate a template file controlling the layout of the\n");
+ msg(" generated documentation:\n");
+ msg(" %s -l layoutFileName.xml\n\n",name);
+ msg("5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.\n");
+ msg(" RTF: %s -w rtf styleSheetFile\n",name);
+ msg(" HTML: %s -w html headerFile footerFile styleSheetFile [configFile]\n",name);
+ msg(" LaTeX: %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",name);
+ msg("6) Use doxygen to generate a rtf extensions file\n");
+ msg(" RTF: %s -e rtf extensionsFile\n\n",name);
+ msg("If -s is specified the comments of the configuration items in the config file will be omitted.\n");
+ msg("If configName is omitted `Doxyfile' will be used as a default.\n\n");
+ msg("-v print version string\n");
+}
+
+//----------------------------------------------------------------------------
+// read the argument of option `c' from the comment argument list and
+// update the option index `optind'.
+
+static const char *getArg(int argc,char **argv,int &optind)
+{
+ char *s=0;
+ if (qstrlen(&argv[optind][2])>0)
+ s=&argv[optind][2];
+ else if (optind+1<argc && argv[optind+1][0]!='-')
+ s=argv[++optind];
+ return s;
+}
+
+//----------------------------------------------------------------------------
+
+void initDoxygen()
+{
+ const char *lang = portable_getenv("LC_ALL");
+ if (lang) portable_setenv("LANG",lang);
+ setlocale(LC_ALL,"");
+ setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
+ setlocale(LC_NUMERIC,"C");
+
+ Doxygen::runningTime.start();
+ initPreprocessor();
+
+ Doxygen::parserManager = new ParserManager;
+ Doxygen::parserManager->registerDefaultParser( new FileParser);
+ Doxygen::parserManager->registerParser("c", new CLanguageScanner);
+ Doxygen::parserManager->registerParser("python", new PythonLanguageScanner);
+ Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner);
+ Doxygen::parserManager->registerParser("fortranfree", new FortranLanguageScannerFree);
+ Doxygen::parserManager->registerParser("fortranfixed", new FortranLanguageScannerFixed);
+ Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner);
+ Doxygen::parserManager->registerParser("dbusxml", new DBusXMLScanner);
+ Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner);
+ Doxygen::parserManager->registerParser("md", new MarkdownFileParser);
+
+ // register any additional parsers here...
+
+ initDefaultExtensionMapping();
+ initClassMemberIndices();
+ initNamespaceMemberIndices();
+ initFileMemberIndices();
+
+ Doxygen::symbolMap = new QDict<DefinitionIntf>(50177);
+#ifdef USE_LIBCLANG
+ Doxygen::clangUsrMap = new QDict<Definition>(50177);
+#endif
+ Doxygen::inputNameList = new FileNameList;
+ Doxygen::inputNameList->setAutoDelete(TRUE);
+ Doxygen::memberNameSDict = new MemberNameSDict(10000);
+ Doxygen::memberNameSDict->setAutoDelete(TRUE);
+ Doxygen::functionNameSDict = new MemberNameSDict(10000);
+ Doxygen::functionNameSDict->setAutoDelete(TRUE);
+ Doxygen::groupSDict = new GroupSDict(17);
+ Doxygen::groupSDict->setAutoDelete(TRUE);
+ Doxygen::globalScope = new NamespaceDef("<globalScope>",1,1,"<globalScope>");
+ Doxygen::namespaceSDict = new NamespaceSDict(20);
+ Doxygen::namespaceSDict->setAutoDelete(TRUE);
+ Doxygen::classSDict = new ClassSDict(1009);
+ Doxygen::classSDict->setAutoDelete(TRUE);
+ Doxygen::hiddenClasses = new ClassSDict(257);
+ Doxygen::hiddenClasses->setAutoDelete(TRUE);
+ Doxygen::directories = new DirSDict(17);
+ Doxygen::directories->setAutoDelete(TRUE);
+ Doxygen::pageSDict = new PageSDict(1009); // all doc pages
+ Doxygen::pageSDict->setAutoDelete(TRUE);
+ Doxygen::exampleSDict = new PageSDict(1009); // all examples
+ Doxygen::exampleSDict->setAutoDelete(TRUE);
+ Doxygen::inputNameDict = new FileNameDict(10007);
+ Doxygen::includeNameDict = new FileNameDict(10007);
+ Doxygen::exampleNameDict = new FileNameDict(1009);
+ Doxygen::exampleNameDict->setAutoDelete(TRUE);
+ Doxygen::imageNameDict = new FileNameDict(257);
+ Doxygen::imageNameDict->setAutoDelete(TRUE);
+ Doxygen::dotFileNameDict = new FileNameDict(257);
+ Doxygen::mscFileNameDict = new FileNameDict(257);
+ Doxygen::diaFileNameDict = new FileNameDict(257);
+ Doxygen::memGrpInfoDict.setAutoDelete(TRUE);
+ Doxygen::tagDestinationDict.setAutoDelete(TRUE);
+ Doxygen::dirRelations.setAutoDelete(TRUE);
+ Doxygen::citeDict = new CiteDict(257);
+ Doxygen::genericsDict = new GenericsSDict;
+ Doxygen::indexList = new IndexList;
+ Doxygen::formulaList = new FormulaList;
+ Doxygen::formulaDict = new FormulaDict(1009);
+ Doxygen::formulaNameDict = new FormulaDict(1009);
+ Doxygen::sectionDict = new SectionDict(257);
+ Doxygen::sectionDict->setAutoDelete(TRUE);
+
+ /**************************************************************************
+ * Initialize some global constants
+ **************************************************************************/
+
+ g_compoundKeywordDict.insert("template class",(void *)8);
+ g_compoundKeywordDict.insert("template struct",(void *)8);
+ g_compoundKeywordDict.insert("class",(void *)8);
+ g_compoundKeywordDict.insert("struct",(void *)8);
+ g_compoundKeywordDict.insert("union",(void *)8);
+ g_compoundKeywordDict.insert("interface",(void *)8);
+ g_compoundKeywordDict.insert("exception",(void *)8);
+
+}
+
+void cleanUpDoxygen()
+{
+ delete Doxygen::sectionDict;
+ delete Doxygen::formulaNameDict;
+ delete Doxygen::formulaDict;
+ delete Doxygen::formulaList;
+ delete Doxygen::indexList;
+ delete Doxygen::genericsDict;
+ delete Doxygen::inputNameDict;
+ delete Doxygen::includeNameDict;
+ delete Doxygen::exampleNameDict;
+ delete Doxygen::imageNameDict;
+ delete Doxygen::dotFileNameDict;
+ delete Doxygen::mscFileNameDict;
+ delete Doxygen::diaFileNameDict;
+ delete Doxygen::mainPage;
+ delete Doxygen::pageSDict;
+ delete Doxygen::exampleSDict;
+ delete Doxygen::globalScope;
+ delete Doxygen::xrefLists;
+ delete Doxygen::parserManager;
+ cleanUpPreprocessor();
+ delete theTranslator;
+ delete g_outputList;
+ Mappers::freeMappers();
+ codeFreeScanner();
+
+ if (Doxygen::symbolMap)
+ {
+ // iterate through Doxygen::symbolMap and delete all
+ // DefinitionList objects, since they have no owner
+ QDictIterator<DefinitionIntf> dli(*Doxygen::symbolMap);
+ DefinitionIntf *di;
+ for (dli.toFirst();(di=dli.current());)
+ {
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList)
+ {
+ DefinitionIntf *tmp = Doxygen::symbolMap->take(dli.currentKey());
+ delete (DefinitionList *)tmp;
+ }
+ else
+ {
+ ++dli;
+ }
+ }
+ }
+
+ delete Doxygen::inputNameList;
+ delete Doxygen::memberNameSDict;
+ delete Doxygen::functionNameSDict;
+ delete Doxygen::groupSDict;
+ delete Doxygen::classSDict;
+ delete Doxygen::hiddenClasses;
+ delete Doxygen::namespaceSDict;
+ delete Doxygen::directories;
+
+ //delete Doxygen::symbolMap; <- we cannot do this unless all static lists
+ // (such as Doxygen::namespaceSDict)
+ // with objects based on Definition are made
+ // dynamic first
+}
+
+static int computeIdealCacheParam(uint v)
+{
+ //printf("computeIdealCacheParam(v=%u)\n",v);
+
+ int r=0;
+ while (v!=0) v>>=1,r++;
+ // r = log2(v)
+
+ // convert to a valid cache size value
+ return QMAX(0,QMIN(r-16,9));
+}
+
+void readConfiguration(int argc, char **argv)
+{
+ /**************************************************************************
+ * Handle arguments *
+ **************************************************************************/
+
+ int optind=1;
+ const char *configName=0;
+ const char *layoutName=0;
+ const char *debugLabel;
+ const char *formatName;
+ bool genConfig=FALSE;
+ bool shortList=FALSE;
+ bool updateConfig=FALSE;
+ bool genLayout=FALSE;
+ int retVal;
+ while (optind<argc && argv[optind][0]=='-' &&
+ (isalpha(argv[optind][1]) || argv[optind][1]=='?' ||
+ argv[optind][1]=='-')
+ )
+ {
+ switch(argv[optind][1])
+ {
+ case 'g':
+ genConfig=TRUE;
+ configName=getArg(argc,argv,optind);
+ if (optind+1<argc && qstrcmp(argv[optind+1],"-")==0)
+ { configName="-"; optind++; }
+ if (!configName)
+ { configName="Doxyfile"; }
+ break;
+ case 'l':
+ genLayout=TRUE;
+ layoutName=getArg(argc,argv,optind);
+ if (!layoutName)
+ { layoutName="DoxygenLayout.xml"; }
+ break;
+ case 'd':
+ debugLabel=getArg(argc,argv,optind);
+ if (!debugLabel)
+ {
+ err("option \"-d\" is missing debug specifier.\n");
+ devUsage();
+ cleanUpDoxygen();
+ exit(1);
+ }
+ retVal = Debug::setFlag(debugLabel);
+ if (!retVal)
+ {
+ err("option \"-d\" has unknown debug specifier: \"%s\".\n",debugLabel);
+ cleanUpDoxygen();
+ exit(1);
+ }
+ break;
+ case 's':
+ shortList=TRUE;
+ break;
+ case 'u':
+ updateConfig=TRUE;
+ break;
+ case 'e':
+ formatName=getArg(argc,argv,optind);
+ if (!formatName)
+ {
+ err("option \"-e\" is missing format specifier rtf.\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+ if (qstricmp(formatName,"rtf")==0)
+ {
+ if (optind+1>=argc)
+ {
+ err("option \"-e rtf\" is missing an extensions file name\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+ QFile f;
+ if (openOutputFile(argv[optind+1],f))
+ {
+ RTFGenerator::writeExtensionsFile(f);
+ }
+ cleanUpDoxygen();
+ exit(0);
+ }
+ err("option \"-e\" has invalid format specifier.\n");
+ cleanUpDoxygen();
+ exit(1);
+ break;
+ case 'w':
+ formatName=getArg(argc,argv,optind);
+ if (!formatName)
+ {
+ err("option \"-w\" is missing format specifier rtf, html or latex\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+ if (qstricmp(formatName,"rtf")==0)
+ {
+ if (optind+1>=argc)
+ {
+ err("option \"-w rtf\" is missing a style sheet file name\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+ QFile f;
+ if (openOutputFile(argv[optind+1],f))
+ {
+ RTFGenerator::writeStyleSheetFile(f);
+ }
+ cleanUpDoxygen();
+ exit(1);
+ }
+ else if (qstricmp(formatName,"html")==0)
+ {
+ if (optind+4<argc || QFileInfo("Doxyfile").exists())
+ {
+ QCString df = optind+4<argc ? argv[optind+4] : QCString("Doxyfile");
+ if (!Config::instance()->parse(df))
+ {
+ err("error opening or reading configuration file %s!\n",argv[optind+4]);
+ cleanUpDoxygen();
+ exit(1);
+ }
+ Config::instance()->substituteEnvironmentVars();
+ Config::instance()->convertStrToVal();
+ // avoid bootstrapping issues when the config file already
+ // refers to the files that we are supposed to parse.
+ Config_getString("HTML_HEADER")="";
+ Config_getString("HTML_FOOTER")="";
+ Config::instance()->check();
+ }
+ else
+ {
+ Config::instance()->init();
+ }
+ if (optind+3>=argc)
+ {
+ err("option \"-w html\" does not have enough arguments\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+
+ QCString outputLanguage=Config_getEnum("OUTPUT_LANGUAGE");
+ if (!setTranslator(outputLanguage))
+ {
+ warn_uncond("Output language %s not supported! Using English instead.\n", outputLanguage.data());
+ }
+
+ QFile f;
+ if (openOutputFile(argv[optind+1],f))
+ {
+ HtmlGenerator::writeHeaderFile(f, argv[optind+3]);
+ }
+ f.close();
+ if (openOutputFile(argv[optind+2],f))
+ {
+ HtmlGenerator::writeFooterFile(f);
+ }
+ f.close();
+ if (openOutputFile(argv[optind+3],f))
+ {
+ HtmlGenerator::writeStyleSheetFile(f);
+ }
+ cleanUpDoxygen();
+ exit(0);
+ }
+ else if (qstricmp(formatName,"latex")==0)
+ {
+ if (optind+4<argc) // use config file to get settings
+ {
+ if (!Config::instance()->parse(argv[optind+4]))
+ {
+ err("error opening or reading configuration file %s!\n",argv[optind+4]);
+ exit(1);
+ }
+ Config::instance()->substituteEnvironmentVars();
+ Config::instance()->convertStrToVal();
+ Config_getString("LATEX_HEADER")="";
+ Config::instance()->check();
+ }
+ else // use default config
+ {
+ Config::instance()->init();
+ }
+ if (optind+3>=argc)
+ {
+ err("option \"-w latex\" does not have enough arguments\n");
+ cleanUpDoxygen();
+ exit(1);
+ }
+
+ QCString outputLanguage=Config_getEnum("OUTPUT_LANGUAGE");
+ if (!setTranslator(outputLanguage))
+ {
+ warn_uncond("Output language %s not supported! Using English instead.\n", outputLanguage.data());
+ }
+
+ QFile f;
+ if (openOutputFile(argv[optind+1],f))
+ {
+ LatexGenerator::writeHeaderFile(f);
+ }
+ f.close();
+ if (openOutputFile(argv[optind+2],f))
+ {
+ LatexGenerator::writeFooterFile(f);
+ }
+ f.close();
+ if (openOutputFile(argv[optind+3],f))
+ {
+ LatexGenerator::writeStyleSheetFile(f);
+ }
+ cleanUpDoxygen();
+ exit(0);
+ }
+ else
+ {
+ err("Illegal format specifier \"%s\": should be one of rtf, html or latex\n",formatName);
+ cleanUpDoxygen();
+ exit(1);
+ }
+ break;
+ case 'm':
+ g_dumpSymbolMap = TRUE;
+ break;
+ case 'v':
+ msg("%s\n",versionString);
+ cleanUpDoxygen();
+ exit(0);
+ break;
+ case '-':
+ if (qstrcmp(&argv[optind][2],"help")==0)
+ {
+ usage(argv[0]);
+ exit(0);
+ }
+ else if (qstrcmp(&argv[optind][2],"version")==0)
+ {
+ msg("%s\n",versionString);
+ cleanUpDoxygen();
+ exit(0);
+ }
+ else
+ {
+ err("Unknown option \"-%s\"\n",&argv[optind][1]);
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'b':
+ setvbuf(stdout,NULL,_IONBF,0);
+ Doxygen::outputToWizard=TRUE;
+ break;
+ case 'T':
+ msg("Warning: this option activates output generation via Django like template files. "
+ "This option is scheduled for doxygen 2.0, is currently incomplete and highly experimental! "
+ "Only use if you are a doxygen developer\n");
+ g_useOutputTemplate=TRUE;
+ break;
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ exit(0);
+ break;
+ default:
+ err("Unknown option \"-%c\"\n",argv[optind][1]);
+ usage(argv[0]);
+ exit(1);
+ }
+ optind++;
+ }
+
+ /**************************************************************************
+ * Parse or generate the config file *
+ **************************************************************************/
+
+ Config::instance()->init();
+
+ if (genConfig)
+ {
+ generateConfigFile(configName,shortList);
+ cleanUpDoxygen();
+ exit(0);
+ }
+ if (genLayout)
+ {
+ writeDefaultLayoutFile(layoutName);
+ cleanUpDoxygen();
+ exit(0);
+ }
+
+ QFileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
+ if (optind>=argc)
+ {
+ if (configFileInfo1.exists())
+ {
+ configName="Doxyfile";
+ }
+ else if (configFileInfo2.exists())
+ {
+ configName="doxyfile";
+ }
+ else
+ {
+ err("Doxyfile not found and no input file specified!\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+ else
+ {
+ QFileInfo fi(argv[optind]);
+ if (fi.exists() || qstrcmp(argv[optind],"-")==0)
+ {
+ configName=argv[optind];
+ }
+ else
+ {
+ err("configuration file %s not found!\n",argv[optind]);
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+
+ if (!Config::instance()->parse(configName,updateConfig))
+ {
+ err("could not open or read configuration file %s!\n",configName);
+ cleanUpDoxygen();
+ exit(1);
+ }
+
+ if (updateConfig)
+ {
+ generateConfigFile(configName,shortList,TRUE);
+ cleanUpDoxygen();
+ exit(0);
+ }
+
+ /* Perlmod wants to know the path to the config file.*/
+ QFileInfo configFileInfo(configName);
+ setPerlModDoxyfile(configFileInfo.absFilePath().data());
+
+}
+
+/** check and resolve config options */
+void checkConfiguration()
+{
+
+ Config::instance()->substituteEnvironmentVars();
+ Config::instance()->convertStrToVal();
+ Config::instance()->check();
+
+ initWarningFormat();
+}
+
+/** adjust globals that depend on configuration settings. */
+void adjustConfiguration()
+{
+ QCString outputLanguage=Config_getEnum("OUTPUT_LANGUAGE");
+ if (!setTranslator(outputLanguage))
+ {
+ warn_uncond("Output language %s not supported! Using English instead.\n",
+ outputLanguage.data());
+ }
+ QStrList &includePath = Config_getList("INCLUDE_PATH");
+ char *s=includePath.first();
+ while (s)
+ {
+ QFileInfo fi(s);
+ addSearchDir(fi.absFilePath().utf8());
+ s=includePath.next();
+ }
+
+ /* Set the global html file extension. */
+ Doxygen::htmlFileExtension = Config_getString("HTML_FILE_EXTENSION");
+
+
+ Doxygen::xrefLists->setAutoDelete(TRUE);
+
+ Doxygen::parseSourcesNeeded = Config_getBool("CALL_GRAPH") ||
+ Config_getBool("CALLER_GRAPH") ||
+ Config_getBool("REFERENCES_RELATION") ||
+ Config_getBool("REFERENCED_BY_RELATION");
+
+ Doxygen::markdownSupport = Config_getBool("MARKDOWN_SUPPORT");
+
+ /**************************************************************************
+ * Add custom extension mappings
+ **************************************************************************/
+
+ QStrList &extMaps = Config_getList("EXTENSION_MAPPING");
+ char *mapping = extMaps.first();
+ while (mapping)
+ {
+ QCString mapStr = mapping;
+ int i;
+ if ((i=mapStr.find('='))!=-1)
+ {
+ QCString ext=mapStr.left(i).stripWhiteSpace().lower();
+ QCString language=mapStr.mid(i+1).stripWhiteSpace().lower();
+ if (!updateLanguageMapping(ext,language))
+ {
+ err("Failed to map file extension '%s' to unsupported language '%s'.\n"
+ "Check the EXTENSION_MAPPING setting in the config file.\n",
+ ext.data(),language.data());
+ }
+ else
+ {
+ msg("Adding custom extension mapping: .%s will be treated as language %s\n",
+ ext.data(),language.data());
+ }
+ }
+ mapping = extMaps.next();
+ }
+
+
+ // add predefined macro name to a dictionary
+ QStrList &expandAsDefinedList =Config_getList("EXPAND_AS_DEFINED");
+ s=expandAsDefinedList.first();
+ while (s)
+ {
+ if (Doxygen::expandAsDefinedDict[s]==0)
+ {
+ Doxygen::expandAsDefinedDict.insert(s,(void *)666);
+ }
+ s=expandAsDefinedList.next();
+ }
+
+ // read aliases and store them in a dictionary
+ readAliases();
+
+ // store number of spaces in a tab into Doxygen::spaces
+ int &tabSize = Config_getInt("TAB_SIZE");
+ Doxygen::spaces.resize(tabSize+1);
+ int sp;for (sp=0;sp<tabSize;sp++) Doxygen::spaces.at(sp)=' ';
+ Doxygen::spaces.at(tabSize)='\0';
+}
+
+#ifdef HAS_SIGNALS
+static void stopDoxygen(int)
+{
+ QDir thisDir;
+ msg("Cleaning up...\n");
+ if (!Doxygen::entryDBFileName.isEmpty())
+ {
+ thisDir.remove(Doxygen::entryDBFileName);
+ }
+ if (!Doxygen::objDBFileName.isEmpty())
+ {
+ thisDir.remove(Doxygen::objDBFileName);
+ }
+ killpg(0,SIGINT);
+ exit(1);
+}
+#endif
+
+static void exitDoxygen()
+{
+ if (!g_successfulRun) // premature exit
+ {
+ QDir thisDir;
+ msg("Exiting...\n");
+ if (!Doxygen::entryDBFileName.isEmpty())
+ {
+ thisDir.remove(Doxygen::entryDBFileName);
+ }
+ if (!Doxygen::objDBFileName.isEmpty())
+ {
+ thisDir.remove(Doxygen::objDBFileName);
+ }
+ }
+}
+
+static QCString createOutputDirectory(const QCString &baseDirName,
+ const char *formatDirOption,
+ const char *defaultDirName)
+{
+ // Note the & on the next line, we modify the formatDirOption!
+ QCString &formatDirName = Config_getString(formatDirOption);
+ if (formatDirName.isEmpty())
+ {
+ formatDirName = baseDirName + defaultDirName;
+ }
+ else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
+ {
+ formatDirName.prepend(baseDirName+'/');
+ }
+ QDir formatDir(formatDirName);
+ if (!formatDir.exists() && !formatDir.mkdir(formatDirName))
+ {
+ err("Could not create output directory %s\n", formatDirName.data());
+ cleanUpDoxygen();
+ exit(1);
+ }
+ return formatDirName;
+}
+
+static QCString getQchFileName()
+{
+ QCString const & qchFile = Config_getString("QCH_FILE");
+ if (!qchFile.isEmpty())
+ {
+ return qchFile;
+ }
+
+ QCString const & projectName = Config_getString("PROJECT_NAME");
+ QCString const & versionText = Config_getString("PROJECT_NUMBER");
+
+ return QCString("../qch/")
+ + (projectName.isEmpty() ? QCString("index") : projectName)
+ + (versionText.isEmpty() ? QCString("") : QCString("-") + versionText)
+ + QCString(".qch");
+}
+
+void searchInputFiles()
+{
+ QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS");
+ bool alwaysRecursive = Config_getBool("RECURSIVE");
+ StringDict excludeNameDict(1009);
+ excludeNameDict.setAutoDelete(TRUE);
+
+ // gather names of all files in the include path
+ g_s.begin("Searching for include files...\n");
+ QStrList &includePathList = Config_getList("INCLUDE_PATH");
+ char *s=includePathList.first();
+ while (s)
+ {
+ QStrList &pl = Config_getList("INCLUDE_FILE_PATTERNS");
+ if (pl.count()==0)
+ {
+ pl = Config_getList("FILE_PATTERNS");
+ }
+ readFileOrDirectory(s,0,Doxygen::includeNameDict,0,&pl,
+ &exclPatterns,0,0,
+ alwaysRecursive);
+ s=includePathList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for example files...\n");
+ QStrList &examplePathList = Config_getList("EXAMPLE_PATH");
+ s=examplePathList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,Doxygen::exampleNameDict,0,
+ &Config_getList("EXAMPLE_PATTERNS"),
+ 0,0,0,
+ (alwaysRecursive || Config_getBool("EXAMPLE_RECURSIVE")));
+ s=examplePathList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for images...\n");
+ QStrList &imagePathList=Config_getList("IMAGE_PATH");
+ s=imagePathList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,Doxygen::imageNameDict,0,0,
+ 0,0,0,
+ alwaysRecursive);
+ s=imagePathList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for dot files...\n");
+ QStrList &dotFileList=Config_getList("DOTFILE_DIRS");
+ s=dotFileList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,Doxygen::dotFileNameDict,0,0,
+ 0,0,0,
+ alwaysRecursive);
+ s=dotFileList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for msc files...\n");
+ QStrList &mscFileList=Config_getList("MSCFILE_DIRS");
+ s=mscFileList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,Doxygen::mscFileNameDict,0,0,
+ 0,0,0,
+ alwaysRecursive);
+ s=mscFileList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for dia files...\n");
+ QStrList &diaFileList=Config_getList("DIAFILE_DIRS");
+ s=diaFileList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,Doxygen::diaFileNameDict,0,0,
+ 0,0,0,
+ alwaysRecursive);
+ s=diaFileList.next();
+ }
+ g_s.end();
+
+ g_s.begin("Searching for files to exclude\n");
+ QStrList &excludeList = Config_getList("EXCLUDE");
+ s=excludeList.first();
+ while (s)
+ {
+ readFileOrDirectory(s,0,0,0,&Config_getList("FILE_PATTERNS"),
+ 0,0,&excludeNameDict,
+ alwaysRecursive,
+ FALSE);
+ s=excludeList.next();
+ }
+ g_s.end();
+
+ /**************************************************************************
+ * Determine Input Files *
+ **************************************************************************/
+
+ g_s.begin("Searching for files to process...\n");
+ QDict<void> *killDict = new QDict<void>(10007);
+ int inputSize=0;
+ QStrList &inputList=Config_getList("INPUT");
+ g_inputFiles.setAutoDelete(TRUE);
+ s=inputList.first();
+ while (s)
+ {
+ QCString path=s;
+ uint l = path.length();
+ if (l>0)
+ {
+ // strip trailing slashes
+ if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
+
+ inputSize+=readFileOrDirectory(
+ path,
+ Doxygen::inputNameList,
+ Doxygen::inputNameDict,
+ &excludeNameDict,
+ &Config_getList("FILE_PATTERNS"),
+ &exclPatterns,
+ &g_inputFiles,0,
+ alwaysRecursive,
+ TRUE,
+ killDict,
+ &Doxygen::inputPaths);
+ }
+ s=inputList.next();
+ }
+ delete killDict;
+ g_s.end();
+}
+
+
+void parseInput()
+{
+ atexit(exitDoxygen);
+
+
+ /**************************************************************************
+ * Make sure the output directory exists
+ **************************************************************************/
+ QCString &outputDirectory = Config_getString("OUTPUT_DIRECTORY");
+ if (outputDirectory.isEmpty())
+ {
+ outputDirectory=QDir::currentDirPath().utf8();
+ }
+ else
+ {
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("tag OUTPUT_DIRECTORY: Output directory `%s' does not "
+ "exist and cannot be created\n",outputDirectory.data());
+ cleanUpDoxygen();
+ exit(1);
+ }
+ else
+ {
+ msg("Notice: Output directory `%s' does not exist. "
+ "I have created it for you.\n", outputDirectory.data());
+ }
+ dir.cd(outputDirectory);
+ }
+ outputDirectory=dir.absPath().utf8();
+ }
+
+ /**************************************************************************
+ * Initialize global lists and dictionaries
+ **************************************************************************/
+
+ Doxygen::symbolStorage = new Store;
+
+ // also scale lookup cache with SYMBOL_CACHE_SIZE
+ int cacheSize = Config_getInt("LOOKUP_CACHE_SIZE");
+ if (cacheSize<0) cacheSize=0;
+ if (cacheSize>9) cacheSize=9;
+ uint lookupSize = 65536 << cacheSize;
+ Doxygen::lookupCache = new QCache<LookupInfo>(lookupSize,lookupSize);
+ Doxygen::lookupCache->setAutoDelete(TRUE);
+
+#ifdef HAS_SIGNALS
+ signal(SIGINT, stopDoxygen);
+#endif
+
+ uint pid = portable_pid();
+ Doxygen::objDBFileName.sprintf("doxygen_objdb_%d.tmp",pid);
+ Doxygen::objDBFileName.prepend(outputDirectory+"/");
+ Doxygen::entryDBFileName.sprintf("doxygen_entrydb_%d.tmp",pid);
+ Doxygen::entryDBFileName.prepend(outputDirectory+"/");
+
+ if (Doxygen::symbolStorage->open(Doxygen::objDBFileName)==-1)
+ {
+ err("Failed to open temporary file %s\n",Doxygen::objDBFileName.data());
+ exit(1);
+ }
+
+
+
+ /**************************************************************************
+ * Check/create output directorties *
+ **************************************************************************/
+
+ QCString htmlOutput;
+ bool &generateHtml = Config_getBool("GENERATE_HTML");
+ if (generateHtml)
+ htmlOutput = createOutputDirectory(outputDirectory,"HTML_OUTPUT","/html");
+
+ QCString docbookOutput;
+ bool &generateDocbook = Config_getBool("GENERATE_DOCBOOK");
+ if (generateDocbook)
+ docbookOutput = createOutputDirectory(outputDirectory,"DOCBOOK_OUTPUT","/docbook");
+
+ QCString xmlOutput;
+ bool &generateXml = Config_getBool("GENERATE_XML");
+ if (generateXml)
+ xmlOutput = createOutputDirectory(outputDirectory,"XML_OUTPUT","/xml");
+
+ QCString latexOutput;
+ bool &generateLatex = Config_getBool("GENERATE_LATEX");
+ if (generateLatex)
+ latexOutput = createOutputDirectory(outputDirectory,"LATEX_OUTPUT","/latex");
+
+ QCString rtfOutput;
+ bool &generateRtf = Config_getBool("GENERATE_RTF");
+ if (generateRtf)
+ rtfOutput = createOutputDirectory(outputDirectory,"RTF_OUTPUT","/rtf");
+
+ QCString manOutput;
+ bool &generateMan = Config_getBool("GENERATE_MAN");
+ if (generateMan)
+ manOutput = createOutputDirectory(outputDirectory,"MAN_OUTPUT","/man");
+
+ //QCString sqlOutput;
+ //bool &generateSql = Config_getBool("GENERATE_SQLITE3");
+ //if (generateSql)
+ // sqlOutput = createOutputDirectory(outputDirectory,"SQLITE3_OUTPUT","/sqlite3");
+
+ if (Config_getBool("HAVE_DOT"))
+ {
+ QCString curFontPath = Config_getString("DOT_FONTPATH");
+ if (curFontPath.isEmpty())
+ {
+ portable_getenv("DOTFONTPATH");
+ QCString newFontPath = ".";
+ if (!curFontPath.isEmpty())
+ {
+ newFontPath+=portable_pathListSeparator();
+ newFontPath+=curFontPath;
+ }
+ portable_setenv("DOTFONTPATH",newFontPath);
+ }
+ else
+ {
+ portable_setenv("DOTFONTPATH",curFontPath);
+ }
+ }
+
+
+
+ /**************************************************************************
+ * Handle layout file *
+ **************************************************************************/
+
+ LayoutDocManager::instance().init();
+ QCString &layoutFileName = Config_getString("LAYOUT_FILE");
+ bool defaultLayoutUsed = FALSE;
+ if (layoutFileName.isEmpty())
+ {
+ layoutFileName = "DoxygenLayout.xml";
+ defaultLayoutUsed = TRUE;
+ }
+
+ QFile layoutFile(layoutFileName);
+ if (layoutFile.open(IO_ReadOnly))
+ {
+ msg("Parsing layout file %s...\n",layoutFileName.data());
+ QTextStream t(&layoutFile);
+ t.setEncoding(QTextStream::Latin1);
+ LayoutDocManager::instance().parse(t,layoutFileName);
+ }
+ else if (!defaultLayoutUsed)
+ {
+ warn_uncond("failed to open layout file '%s' for reading!\n",layoutFileName.data());
+ }
+
+ /**************************************************************************
+ * Read and preprocess input *
+ **************************************************************************/
+
+ // prevent search in the output directories
+ QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS");
+ if (generateHtml) exclPatterns.append(htmlOutput);
+ if (generateDocbook) exclPatterns.append(docbookOutput);
+ if (generateXml) exclPatterns.append(xmlOutput);
+ if (generateLatex) exclPatterns.append(latexOutput);
+ if (generateRtf) exclPatterns.append(rtfOutput);
+ if (generateMan) exclPatterns.append(manOutput);
+
+ searchInputFiles();
+
+ // Notice: the order of the function calls below is very important!
+
+ if (Config_getBool("GENERATE_HTML"))
+ {
+ readFormulaRepository();
+ }
+
+ /**************************************************************************
+ * Handle Tag Files *
+ **************************************************************************/
+
+ g_storage = new FileStorage;
+ g_storage->setName(Doxygen::entryDBFileName);
+ if (!g_storage->open(IO_WriteOnly))
+ {
+ err("Failed to create temporary storage file %s\n",
+ Doxygen::entryDBFileName.data());
+ exit(1);
+ }
+ Entry *root=new Entry;
+ EntryNav *rootNav = new EntryNav(0,root);
+ rootNav->setEntry(root);
+ msg("Reading and parsing tag files\n");
+
+ QStrList &tagFileList = Config_getList("TAGFILES");
+ char *s=tagFileList.first();
+ while (s)
+ {
+ readTagFile(root,s);
+ root->createNavigationIndex(rootNav,g_storage,0);
+ s=tagFileList.next();
+ }
+
+ /**************************************************************************
+ * Parse source files *
+ **************************************************************************/
+
+ if (Config_getBool("BUILTIN_STL_SUPPORT"))
+ {
+ addSTLClasses(rootNav);
+ }
+
+ g_s.begin("Parsing files\n");
+ parseFiles(root,rootNav);
+ g_storage->close();
+ g_s.end();
+
+ // we are done with input scanning now, so free up the buffers used by flex
+ // (can be around 4MB)
+ preFreeScanner();
+ scanFreeScanner();
+ pyscanFreeScanner();
+
+ if (!g_storage->open(IO_ReadOnly))
+ {
+ err("Failed to open temporary storage file %s for reading",
+ Doxygen::entryDBFileName.data());
+ exit(1);
+ }
+
+ /**************************************************************************
+ * Gather information *
+ **************************************************************************/
+
+ g_s.begin("Building group list...\n");
+ buildGroupList(rootNav);
+ organizeSubGroups(rootNav);
+ g_s.end();
+
+ g_s.begin("Building directory list...\n");
+ buildDirectories();
+ findDirDocumentation(rootNav);
+ g_s.end();
+
+ g_s.begin("Building namespace list...\n");
+ buildNamespaceList(rootNav);
+ findUsingDirectives(rootNav);
+ g_s.end();
+
+ g_s.begin("Building file list...\n");
+ buildFileList(rootNav);
+ g_s.end();
+ //generateFileTree();
+
+ g_s.begin("Building class list...\n");
+ buildClassList(rootNav);
+ g_s.end();
+
+ g_s.begin("Associating documentation with classes...\n");
+ buildClassDocList(rootNav);
+
+ // build list of using declarations here (global list)
+ buildListOfUsingDecls(rootNav);
+ g_s.end();
+
+ g_s.begin("Computing nesting relations for classes...\n");
+ resolveClassNestingRelations();
+ g_s.end();
+ // 1.8.2-20121111: no longer add nested classes to the group as well
+ //distributeClassGroupRelations();
+
+ // calling buildClassList may result in cached relations that
+ // become invalid after resolveClassNestingRelations(), that's why
+ // we need to clear the cache here
+ Doxygen::lookupCache->clear();
+ // we don't need the list of using declaration anymore
+ g_usingDeclarations.clear();
+
+ g_s.begin("Building example list...\n");
+ buildExampleList(rootNav);
+ g_s.end();
+
+ g_s.begin("Searching for enumerations...\n");
+ findEnums(rootNav);
+ g_s.end();
+
+ // Since buildVarList calls isVarWithConstructor
+ // and this calls getResolvedClass we need to process
+ // typedefs first so the relations between classes via typedefs
+ // are properly resolved. See bug 536385 for an example.
+ g_s.begin("Searching for documented typedefs...\n");
+ buildTypedefList(rootNav);
+ g_s.end();
+
+ g_s.begin("Searching for members imported via using declarations...\n");
+ findUsingDeclImports(rootNav);
+ // this should be after buildTypedefList in order to properly import
+ // used typedefs
+ findUsingDeclarations(rootNav);
+ g_s.end();
+
+ g_s.begin("Searching for included using directives...\n");
+ findIncludedUsingDirectives();
+ g_s.end();
+
+ g_s.begin("Searching for documented variables...\n");
+ buildVarList(rootNav);
+ g_s.end();
+
+ g_s.begin("Building interface member list...\n");
+ buildInterfaceAndServiceList(rootNav); // UNO IDL
+
+ g_s.begin("Building member list...\n"); // using class info only !
+ buildFunctionList(rootNav);
+ g_s.end();
+
+ g_s.begin("Searching for friends...\n");
+ findFriends();
+ g_s.end();
+
+ g_s.begin("Searching for documented defines...\n");
+ findDefineDocumentation(rootNav);
+ g_s.end();
+
+ g_s.begin("Computing class inheritance relations...\n");
+ findClassEntries(rootNav);
+ findInheritedTemplateInstances();
+ g_s.end();
+
+ g_s.begin("Computing class usage relations...\n");
+ findUsedTemplateInstances();
+ g_s.end();
+
+ if (Config_getBool("INLINE_SIMPLE_STRUCTS"))
+ {
+ g_s.begin("Searching for tag less structs...\n");
+ findTagLessClasses();
+ g_s.end();
+ }
+
+ g_s.begin("Flushing cached template relations that have become invalid...\n");
+ flushCachedTemplateRelations();
+ g_s.end();
+
+ g_s.begin("Creating members for template instances...\n");
+ createTemplateInstanceMembers();
+ g_s.end();
+
+ g_s.begin("Computing class relations...\n");
+ computeTemplateClassRelations();
+ flushUnresolvedRelations();
+ if (Config_getBool("OPTIMIZE_OUTPUT_VHDL"))
+ {
+ VhdlDocGen::computeVhdlComponentRelations();
+ }
+ computeClassRelations();
+ g_classEntries.clear();
+ g_s.end();
+
+ g_s.begin("Add enum values to enums...\n");
+ addEnumValuesToEnums(rootNav);
+ findEnumDocumentation(rootNav);
+ g_s.end();
+
+ g_s.begin("Searching for member function documentation...\n");
+ findObjCMethodDefinitions(rootNav);
+ findMemberDocumentation(rootNav); // may introduce new members !
+
+ transferRelatedFunctionDocumentation();
+ transferFunctionDocumentation();
+ g_s.end();
+
+ g_s.begin("Building page list...\n");
+ buildPageList(rootNav);
+ g_s.end();
+
+ g_s.begin("Search for main page...\n");
+ findMainPage(rootNav);
+ findMainPageTagFiles(rootNav);
+ g_s.end();
+
+ g_s.begin("Computing page relations...\n");
+ computePageRelations(rootNav);
+ checkPageRelations();
+ g_s.end();
+
+ g_s.begin("Determining the scope of groups...\n");
+ findGroupScope(rootNav);
+ g_s.end();
+
+ g_s.begin("Sorting lists...\n");
+ Doxygen::memberNameSDict->sort();
+ Doxygen::functionNameSDict->sort();
+ Doxygen::hiddenClasses->sort();
+ Doxygen::classSDict->sort();
+ g_s.end();
+
+ msg("Freeing entry tree\n");
+ delete rootNav;
+ g_storage->close();
+ delete g_storage;
+ g_storage=0;
+
+ QDir thisDir;
+ thisDir.remove(Doxygen::entryDBFileName);
+
+ g_s.begin("Determining which enums are documented\n");
+ findDocumentedEnumValues();
+ g_s.end();
+
+ g_s.begin("Computing member relations...\n");
+ mergeCategories();
+ computeMemberRelations();
+ g_s.end();
+
+ g_s.begin("Building full member lists recursively...\n");
+ buildCompleteMemberLists();
+ g_s.end();
+
+ g_s.begin("Adding members to member groups.\n");
+ addMembersToMemberGroup();
+ g_s.end();
+
+ if (Config_getBool("DISTRIBUTE_GROUP_DOC"))
+ {
+ g_s.begin("Distributing member group documentation.\n");
+ distributeMemberGroupDocumentation();
+ g_s.end();
+ }
+
+ g_s.begin("Computing member references...\n");
+ computeMemberReferences();
+ g_s.end();
+
+ if (Config_getBool("INHERIT_DOCS"))
+ {
+ g_s.begin("Inheriting documentation...\n");
+ inheritDocumentation();
+ g_s.end();
+ }
+
+ // compute the shortest possible names of all files
+ // without losing the uniqueness of the file names.
+ g_s.begin("Generating disk names...\n");
+ Doxygen::inputNameList->generateDiskNames();
+ g_s.end();
+
+ g_s.begin("Adding source references...\n");
+ addSourceReferences();
+ g_s.end();
+
+ g_s.begin("Adding xrefitems...\n");
+ addListReferences();
+ generateXRefPages();
+ g_s.end();
+
+ g_s.begin("Sorting member lists...\n");
+ sortMemberLists();
+ g_s.end();
+
+ if (Config_getBool("DIRECTORY_GRAPH"))
+ {
+ g_s.begin("Computing dependencies between directories...\n");
+ computeDirDependencies();
+ g_s.end();
+ }
+
+ //g_s.begin("Resolving citations...\n");
+ //Doxygen::citeDict->resolve();
+
+ g_s.begin("Generating citations page...\n");
+ Doxygen::citeDict->generatePage();
+ g_s.end();
+
+ g_s.begin("Counting data structures...\n");
+ countDataStructures();
+ g_s.end();
+
+ g_s.begin("Resolving user defined references...\n");
+ resolveUserReferences();
+ g_s.end();
+
+ g_s.begin("Finding anchors and sections in the documentation...\n");
+ findSectionsInDocumentation();
+ g_s.end();
+
+ g_s.begin("Transferring function references...\n");
+ transferFunctionReferences();
+ g_s.end();
+
+ g_s.begin("Combining using relations...\n");
+ combineUsingRelations();
+ g_s.end();
+
+ g_s.begin("Adding members to index pages...\n");
+ addMembersToIndex();
+ g_s.end();
+}
+
+void generateOutput()
+{
+ /**************************************************************************
+ * Initialize output generators *
+ **************************************************************************/
+
+ //// dump all symbols
+ if (g_dumpSymbolMap)
+ {
+ dumpSymbolMap();
+ exit(0);
+ }
+
+ initSearchIndexer();
+
+ bool generateHtml = Config_getBool("GENERATE_HTML");
+ bool generateLatex = Config_getBool("GENERATE_LATEX");
+ bool generateMan = Config_getBool("GENERATE_MAN");
+ bool generateRtf = Config_getBool("GENERATE_RTF");
+
+
+ g_outputList = new OutputList(TRUE);
+ if (generateHtml)
+ {
+ g_outputList->add(new HtmlGenerator);
+ HtmlGenerator::init();
+
+ // add HTML indexers that are enabled
+ bool generateHtmlHelp = Config_getBool("GENERATE_HTMLHELP");
+ bool generateEclipseHelp = Config_getBool("GENERATE_ECLIPSEHELP");
+ bool generateQhp = Config_getBool("GENERATE_QHP");
+ bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ bool generateDocSet = Config_getBool("GENERATE_DOCSET");
+ if (generateEclipseHelp) Doxygen::indexList->addIndex(new EclipseHelp);
+ if (generateHtmlHelp) Doxygen::indexList->addIndex(new HtmlHelp);
+ if (generateQhp) Doxygen::indexList->addIndex(new Qhp);
+ if (generateTreeView) Doxygen::indexList->addIndex(new FTVHelp(TRUE));
+ if (generateDocSet) Doxygen::indexList->addIndex(new DocSets);
+ Doxygen::indexList->initialize();
+ HtmlGenerator::writeTabData();
+
+ // copy static stuff
+ copyStyleSheet();
+ copyLogo();
+ copyExtraFiles("HTML_EXTRA_FILES","HTML_OUTPUT");
+ FTVHelp::generateTreeViewImages();
+ }
+ if (generateLatex)
+ {
+ g_outputList->add(new LatexGenerator);
+ LatexGenerator::init();
+
+ // copy static stuff
+ copyExtraFiles("LATEX_EXTRA_FILES","LATEX_OUTPUT");
+ }
+ if (generateMan)
+ {
+ g_outputList->add(new ManGenerator);
+ ManGenerator::init();
+ }
+ if (generateRtf)
+ {
+ g_outputList->add(new RTFGenerator);
+ RTFGenerator::init();
+ }
+ if (Config_getBool("USE_HTAGS"))
+ {
+ Htags::useHtags = TRUE;
+ QCString htmldir = Config_getString("HTML_OUTPUT");
+ if (!Htags::execute(htmldir))
+ err("USE_HTAGS is YES but htags(1) failed. \n");
+ if (!Htags::loadFilemap(htmldir))
+ err("htags(1) ended normally but failed to load the filemap. \n");
+ }
+
+ /**************************************************************************
+ * Generate documentation *
+ **************************************************************************/
+
+ QFile *tag=0;
+ QCString &generateTagFile = Config_getString("GENERATE_TAGFILE");
+ if (!generateTagFile.isEmpty())
+ {
+ tag=new QFile(generateTagFile);
+ if (!tag->open(IO_WriteOnly))
+ {
+ err("cannot open tag file %s for writing\n",
+ generateTagFile.data()
+ );
+ cleanUpDoxygen();
+ exit(1);
+ }
+ Doxygen::tagFile.setDevice(tag);
+ Doxygen::tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" << endl;
+ Doxygen::tagFile << "<tagfile>" << endl;
+ }
+
+ if (generateHtml) writeDoxFont(Config_getString("HTML_OUTPUT"));
+ if (generateLatex) writeDoxFont(Config_getString("LATEX_OUTPUT"));
+ if (generateRtf) writeDoxFont(Config_getString("RTF_OUTPUT"));
+
+ g_s.begin("Generating style sheet...\n");
+ //printf("writing style info\n");
+ g_outputList->writeStyleInfo(0); // write first part
+ g_s.end();
+
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+
+ // generate search indices (need to do this before writing other HTML
+ // pages as these contain a drop down menu with options depending on
+ // what categories we find in this function.
+ if (generateHtml && searchEngine)
+ {
+ g_s.begin("Generating search indices...\n");
+ QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
+ QDir searchDir(searchDirName);
+ if (!searchDir.exists() && !searchDir.mkdir(searchDirName))
+ {
+ err("Could not create search results directory '%s' $PWD='%s'\n",
+ searchDirName.data(),QDir::currentDirPath().data());
+ exit(1);
+ }
+ HtmlGenerator::writeSearchData(searchDirName);
+ if (!serverBasedSearch) // client side search index
+ {
+ writeJavascriptSearchIndex();
+ }
+ g_s.end();
+ }
+
+ g_s.begin("Generating example documentation...\n");
+ generateExampleDocs();
+ g_s.end();
+
+ if (!Htags::useHtags)
+ {
+ g_s.begin("Generating file sources...\n");
+ generateFileSources();
+ g_s.end();
+ }
+
+ g_s.begin("Generating file documentation...\n");
+ generateFileDocs();
+ g_s.end();
+
+ g_s.begin("Generating page documentation...\n");
+ generatePageDocs();
+ g_s.end();
+
+ g_s.begin("Generating group documentation...\n");
+ generateGroupDocs();
+ g_s.end();
+
+ g_s.begin("Generating class documentation...\n");
+ generateClassDocs();
+ g_s.end();
+
+ g_s.begin("Generating namespace index...\n");
+ generateNamespaceDocs();
+ g_s.end();
+
+ if (Config_getBool("GENERATE_LEGEND"))
+ {
+ g_s.begin("Generating graph info page...\n");
+ writeGraphInfo(*g_outputList);
+ g_s.end();
+ }
+
+ g_s.begin("Generating directory documentation...\n");
+ generateDirDocs(*g_outputList);
+ g_s.end();
+
+ if (Doxygen::formulaList->count()>0 && generateHtml
+ && !Config_getBool("USE_MATHJAX"))
+ {
+ g_s.begin("Generating bitmaps for formulas in HTML...\n");
+ Doxygen::formulaList->generateBitmaps(Config_getString("HTML_OUTPUT"));
+ g_s.end();
+ }
+
+ if (Config_getBool("SORT_GROUP_NAMES"))
+ {
+ Doxygen::groupSDict->sort();
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ gd->sortSubGroups();
+ }
+ }
+
+ writeMainPageTagFileData();
+
+ if (g_outputList->count()>0)
+ {
+ writeIndexHierarchy(*g_outputList);
+ }
+
+ g_s.begin("finalizing index lists...\n");
+ Doxygen::indexList->finalize();
+ g_s.end();
+
+ if (!generateTagFile.isEmpty())
+ {
+ Doxygen::tagFile << "</tagfile>" << endl;
+ delete tag;
+ }
+
+ if (Config_getBool("DOT_CLEANUP"))
+ {
+ if (generateHtml)
+ removeDoxFont(Config_getString("HTML_OUTPUT"));
+ if (generateRtf)
+ removeDoxFont(Config_getString("RTF_OUTPUT"));
+ if (generateLatex)
+ removeDoxFont(Config_getString("LATEX_OUTPUT"));
+ }
+
+ if (Config_getBool("GENERATE_XML"))
+ {
+ g_s.begin("Generating XML output...\n");
+ Doxygen::generatingXmlOutput=TRUE;
+ generateXML();
+ Doxygen::generatingXmlOutput=FALSE;
+ g_s.end();
+ }
+ if (USE_SQLITE3)
+ {
+ g_s.begin("Generating SQLITE3 output...\n");
+ generateSqlite3();
+ g_s.end();
+ }
+
+ if (Config_getBool("GENERATE_DOCBOOK"))
+ {
+ g_s.begin("Generating Docbook output...\n");
+ generateDocbook();
+ g_s.end();
+ }
+
+ if (Config_getBool("GENERATE_AUTOGEN_DEF"))
+ {
+ g_s.begin("Generating AutoGen DEF output...\n");
+ generateDEF();
+ g_s.end();
+ }
+ if (Config_getBool("GENERATE_PERLMOD"))
+ {
+ g_s.begin("Generating Perl module output...\n");
+ generatePerlMod();
+ g_s.end();
+ }
+ if (generateHtml && searchEngine && serverBasedSearch)
+ {
+ g_s.begin("Generating search index\n");
+ if (Doxygen::searchIndex->kind()==SearchIndexIntf::Internal) // write own search index
+ {
+ HtmlGenerator::writeSearchPage();
+ Doxygen::searchIndex->write(Config_getString("HTML_OUTPUT")+"/search/search.idx");
+ }
+ else // write data for external search index
+ {
+ HtmlGenerator::writeExternalSearchPage();
+ QCString searchDataFile = Config_getString("SEARCHDATA_FILE");
+ if (searchDataFile.isEmpty())
+ {
+ searchDataFile="searchdata.xml";
+ }
+ if (!portable_isAbsolutePath(searchDataFile))
+ {
+ searchDataFile.prepend(Config_getString("OUTPUT_DIRECTORY")+"/");
+ }
+ Doxygen::searchIndex->write(searchDataFile);
+ }
+ g_s.end();
+ }
+
+ if (g_useOutputTemplate) generateOutputViaTemplate();
+
+ if (generateRtf)
+ {
+ g_s.begin("Combining RTF output...\n");
+ if (!RTFGenerator::preProcessFileInplace(Config_getString("RTF_OUTPUT"),"refman.rtf"))
+ {
+ err("An error occurred during post-processing the RTF files!\n");
+ }
+ g_s.end();
+ }
+
+ if (Config_getBool("HAVE_DOT"))
+ {
+ g_s.begin("Running dot...\n");
+ DotManager::instance()->run();
+ g_s.end();
+ }
+
+ if (generateHtml &&
+ Config_getBool("GENERATE_HTMLHELP") &&
+ !Config_getString("HHC_LOCATION").isEmpty())
+ {
+ g_s.begin("Running html help compiler...\n");
+ QString oldDir = QDir::currentDirPath();
+ QDir::setCurrent(Config_getString("HTML_OUTPUT"));
+ portable_sysTimerStart();
+ if (portable_system(Config_getString("HHC_LOCATION"), "index.hhp", FALSE))
+ {
+ err("failed to run html help compiler on index.hhp\n");
+ }
+ portable_sysTimerStop();
+ QDir::setCurrent(oldDir);
+ g_s.end();
+ }
+ if ( generateHtml &&
+ Config_getBool("GENERATE_QHP") &&
+ !Config_getString("QHG_LOCATION").isEmpty())
+ {
+ g_s.begin("Running qhelpgenerator...\n");
+ QCString const qhpFileName = Qhp::getQhpFileName();
+ QCString const qchFileName = getQchFileName();
+
+ QCString const args = QCString().sprintf("%s -o \"%s\"", qhpFileName.data(), qchFileName.data());
+ QString const oldDir = QDir::currentDirPath();
+ QDir::setCurrent(Config_getString("HTML_OUTPUT"));
+ portable_sysTimerStart();
+ if (portable_system(Config_getString("QHG_LOCATION"), args.data(), FALSE))
+ {
+ err("failed to run qhelpgenerator on index.qhp\n");
+ }
+ portable_sysTimerStop();
+ QDir::setCurrent(oldDir);
+ g_s.end();
+ }
+
+ int cacheParam;
+ msg("lookup cache used %d/%d hits=%d misses=%d\n",
+ Doxygen::lookupCache->count(),
+ Doxygen::lookupCache->size(),
+ Doxygen::lookupCache->hits(),
+ Doxygen::lookupCache->misses());
+ cacheParam = computeIdealCacheParam(Doxygen::lookupCache->misses()*2/3); // part of the cache is flushed, hence the 2/3 correction factor
+ if (cacheParam>Config_getInt("LOOKUP_CACHE_SIZE"))
+ {
+ msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is %d at the cost of higher memory usage.\n",cacheParam);
+ }
+
+ if (Debug::isFlagSet(Debug::Time))
+ {
+ msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n",
+ ((double)Doxygen::runningTime.elapsed())/1000.0,
+ portable_getSysElapsedTime()
+ );
+ g_s.print();
+ }
+ else
+ {
+ msg("finished...\n");
+ }
+
+
+ /**************************************************************************
+ * Start cleaning up *
+ **************************************************************************/
+
+ cleanUpDoxygen();
+
+ finializeSearchIndexer();
+ Doxygen::symbolStorage->close();
+ QDir thisDir;
+ thisDir.remove(Doxygen::objDBFileName);
+ Config::deleteInstance();
+ QTextCodec::deleteAllCodecs();
+ delete Doxygen::symbolMap;
+ delete Doxygen::clangUsrMap;
+ delete Doxygen::symbolStorage;
+ g_successfulRun=TRUE;
+}
+
diff --git a/src/doxygen.css b/src/doxygen.css
new file mode 100644
index 0000000..2f4bf70
--- /dev/null
+++ b/src/doxygen.css
@@ -0,0 +1,1440 @@
+/* The standard CSS for doxygen $doxygenversion */
+
+body, table, div, p, dl {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+ font-size: 150%;
+}
+
+.title {
+ font: 400 14px/28px Roboto,sans-serif;
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2.groupheader {
+ border-bottom: 1px solid ##99;
+ color: ##44;
+ font-size: 150%;
+ font-weight: normal;
+ margin-top: 1.75em;
+ padding-top: 8px;
+ padding-bottom: 4px;
+ width: 100%;
+}
+
+h3.groupheader {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+ margin-top: 2px;
+}
+
+p.starttd {
+ margin-top: 0px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: ##ee;
+ border: 1px solid ##b0;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: ##50;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: ##60;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: ##AA;
+ color: #ffffff;
+ border: 1px double ##98;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+ color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ background-color: ##FC;
+ border: 1px solid ##CC;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ min-height: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+div.line.glow {
+ background-color: cyan;
+ box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 12px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: ##ee;
+ font-weight: bold;
+ border: 1px solid ##cc;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: ##ee;
+ border: 1px solid ##cc;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: ##f0;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: ##F8;
+ border-left: 2px solid ##AA;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid ##b0;
+}
+
+th.dirtab {
+ background: ##ee;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid ##66;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+ background-color: cyan;
+ box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: ##FA;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memSeparator {
+ border-bottom: 1px solid #DEE4F0;
+ line-height: 1px;
+ margin: 0px;
+ padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: ##60;
+ white-space: nowrap;
+ font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: ##60;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: ##ee;
+ border: 1px solid ##b0;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+ display: table !important;
+ width: 100%;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memname td {
+ vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid ##B4;
+ border-left: 1px solid ##B4;
+ border-right: 1px solid ##B4;
+ padding: 6px 0px 6px 0px;
+ color: ##2b;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: ##E6;
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid ##B4;
+ border-left: 1px solid ##B4;
+ border-right: 1px solid ##B4;
+ padding: 6px 10px 2px 10px;
+ background-color: ##FC;
+ border-top-width: 0;
+ background-image:url('nav_g.png');
+ background-repeat:repeat-x;
+ background-color: #FFFFFF;
+ /* opera specific markup */
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+.paramname code {
+ line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+table.mlabels {
+ border-spacing: 0px;
+}
+
+td.mlabels-left {
+ width: 100%;
+ padding: 0px;
+}
+
+td.mlabels-right {
+ vertical-align: bottom;
+ padding: 0px;
+ white-space: nowrap;
+}
+
+span.mlabels {
+ margin-left: 8px;
+}
+
+span.mlabel {
+ background-color: ##88;
+ border-top:1px solid ##70;
+ border-left:1px solid ##70;
+ border-right:1px solid ##CC;
+ border-bottom:1px solid ##CC;
+ text-shadow: none;
+ color: white;
+ margin-right: 4px;
+ padding: 2px 3px;
+ border-radius: 3px;
+ font-size: 7pt;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+ margin: 10px 0px;
+ border-top: 1px solid ##AA;
+ border-bottom: 1px solid ##AA;
+ width: 100%;
+}
+
+.directory table {
+ border-collapse:collapse;
+}
+
+.directory td {
+ margin: 0px;
+ padding: 0px;
+ vertical-align: top;
+}
+
+.directory td.entry {
+ white-space: nowrap;
+ padding-right: 6px;
+ padding-top: 3px;
+}
+
+.directory td.entry a {
+ outline:none;
+}
+
+.directory td.entry a img {
+ border: none;
+}
+
+.directory td.desc {
+ width: 100%;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 3px;
+ border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+ padding-left: 6px;
+ background-color: ##F8;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+.directory .levels {
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ font-size: 9pt;
+}
+
+.directory .levels span {
+ cursor: pointer;
+ padding-left: 2px;
+ padding-right: 2px;
+ color: ##50;
+}
+
+.arrow {
+ color: ##AA;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ font-size: 80%;
+ display: inline-block;
+ width: 16px;
+ height: 22px;
+}
+
+.icon {
+ font-family: Arial, Helvetica;
+ font-weight: bold;
+ font-size: 12px;
+ height: 14px;
+ width: 16px;
+ display: inline-block;
+ background-color: ##88;
+ color: white;
+ text-align: center;
+ border-radius: 4px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+
+.icona {
+ width: 24px;
+ height: 22px;
+ display: inline-block;
+}
+
+.iconfopen {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2folderopen.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.iconfclosed {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2folderclosed.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.icondoc {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2doc.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+table.directory {
+ font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+address {
+ font-style: normal;
+ color: ##33;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid ##37;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: ##47;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+table.fieldtable {
+ /*width: 100%;*/
+ margin-bottom: 10px;
+ border: 1px solid ##B4;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid ##B4;
+ border-bottom: 1px solid ##B4;
+ vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+ padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid ##B4;
+ /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+ margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+ margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: ##E6;
+ font-size: 90%;
+ color: ##2B;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid ##B4;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ background-position: 0 -5px;
+ height:30px;
+ line-height:30px;
+ color:##9b;
+ border:solid 1px ##ca;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:##45;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+ color: ##30;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:##80;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:##45;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.ingroups
+{
+ font-size: 8pt;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: ##FA;
+ margin: 0px;
+ border-bottom: 1px solid ##CC;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+dl.note
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #505050;
+}
+
+dl.todo
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid ##70;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.diagraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid ##A0;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:##40;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: ##F6;
+ border: 1px solid ##DD;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 20px 10px 10px;
+ width: 200px;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ color: ##60;
+ border-bottom: 0 none;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+.inherit_header {
+ font-weight: bold;
+ color: gray;
+ cursor: pointer;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.inherit_header td {
+ padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+ display: none;
+}
+
+tr.heading h2 {
+ margin-top: 12px;
+ margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+ position: absolute;
+ display: none;
+}
+
+#powerTip {
+ cursor: default;
+ white-space: nowrap;
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 4px 4px 4px 4px;
+ box-shadow: 1px 1px 7px gray;
+ display: none;
+ font-size: smaller;
+ max-width: 80%;
+ opacity: 0.9;
+ padding: 1ex 1em 1em;
+ position: absolute;
+ z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+ color: grey;
+ font-style: italic;
+}
+
+#powerTip div.ttname a {
+ font-weight: bold;
+}
+
+#powerTip div.ttname {
+ font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+ color: #006318;
+}
+
+#powerTip div {
+ margin: 0px;
+ padding: 0px;
+ font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+ content: "";
+ position: absolute;
+ margin: 0px;
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.w:after, #powerTip.w:before,
+#powerTip.e:after, #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+}
+
+#powerTip.n:after, #powerTip.s:after,
+#powerTip.w:after, #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+ border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before, #powerTip.s:before,
+#powerTip.w:before, #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+ border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+ top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+ border-top-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+#powerTip.n:before {
+ border-top-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+ left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+ right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+ left: 14px;
+}
+
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+ border-bottom-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+ border-bottom-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+ left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+ right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+ left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+ left: 100%;
+}
+#powerTip.e:after {
+ border-left-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.e:before {
+ border-left-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+ right: 100%;
+}
+#powerTip.w:after {
+ border-right-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.w:before {
+ border-right-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+ at media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+}
+
diff --git a/src/doxygen.h b/src/doxygen.h
new file mode 100644
index 0000000..6f766c0
--- /dev/null
+++ b/src/doxygen.h
@@ -0,0 +1,195 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef DOXYGEN_H
+#define DOXYGEN_H
+
+#include <qdatetime.h>
+#include <qcache.h>
+#include <qstrlist.h>
+#include <qdict.h>
+#include <qintdict.h>
+
+#include "ftextstream.h"
+#include "sortdict.h"
+#include "membergroup.h"
+#include "dirdef.h"
+#include "memberlist.h"
+
+class RefList;
+class PageSList;
+class PageSDict;
+class PageDef;
+class SearchIndexIntf;
+class ParserManager;
+class ObjCache;
+class Store;
+class QFileInfo;
+class BufStr;
+class CiteDict;
+class MemberDef;
+class GroupDef;
+class GroupSDict;
+class FileDef;
+class ClassDef;
+class ClassSDict;
+class GenericsSDict;
+class MemberNameSDict;
+class FileNameDict;
+class FileNameList;
+class NamespaceSDict;
+class NamespaceDef;
+class DefinitionIntf;
+class DirSDict;
+class DirRelation;
+class IndexList;
+class FormulaList;
+class FormulaDict;
+class FormulaNameDict;
+class SectionDict;
+struct MemberGroupInfo;
+
+typedef QList<QCString> StringList;
+typedef QListIterator<QCString> StringListIterator;
+//typedef QDict<FileDef> FileDict;
+//typedef QDict<GroupDef> GroupDict;
+
+class StringDict : public QDict<QCString>
+{
+ public:
+ StringDict(uint size=17) : QDict<QCString>(size) {}
+ virtual ~StringDict() {}
+};
+
+struct LookupInfo
+{
+ LookupInfo() : classDef(0), typeDef(0) {}
+ LookupInfo(ClassDef *cd,MemberDef *td,QCString ts,QCString rt)
+ : classDef(cd), typeDef(td), templSpec(ts),resolvedType(rt) {}
+ ClassDef *classDef;
+ MemberDef *typeDef;
+ QCString templSpec;
+ QCString resolvedType;
+};
+
+extern QCString g_spaces;
+
+/*! \brief This class serves as a namespace for global variables used by doxygen.
+ *
+ * All fields in this class are public and static, so they can be used directly.
+ */
+class Doxygen
+{
+ public:
+ static ClassSDict *classSDict;
+ static ClassSDict *hiddenClasses;
+ static PageSDict *exampleSDict;
+ static PageSDict *pageSDict;
+ static PageDef *mainPage;
+ static bool insideMainPage;
+ static FileNameDict *includeNameDict;
+ static FileNameDict *exampleNameDict;
+ static QDict<void> inputPaths;
+ static FileNameDict *inputNameDict;
+ static FileNameList *inputNameList;
+ static FileNameDict *imageNameDict;
+ static FileNameDict *dotFileNameDict;
+ static FileNameDict *mscFileNameDict;
+ static FileNameDict *diaFileNameDict;
+ static QStrList tagfileList;
+ static MemberNameSDict *memberNameSDict;
+ static MemberNameSDict *functionNameSDict;
+ static FTextStream tagFile;
+ static SectionDict *sectionDict;
+ static StringDict namespaceAliasDict;
+ static GroupSDict *groupSDict;
+ static NamespaceSDict *namespaceSDict;
+ static FormulaList *formulaList;
+ static FormulaDict *formulaDict;
+ static FormulaDict *formulaNameDict;
+ static StringDict tagDestinationDict;
+ static StringDict aliasDict;
+ static QIntDict<MemberGroupInfo> memGrpInfoDict;
+ static QDict<void> expandAsDefinedDict;
+ static NamespaceDef *globalScope;
+ static QDict<RefList> *xrefLists; // array of xref lists: todo, test, bug, deprecated ...
+ static QCString htmlFileExtension;
+ static bool parseSourcesNeeded;
+ static QTime runningTime;
+ static SearchIndexIntf *searchIndex;
+ static QDict<DefinitionIntf> *symbolMap;
+ static QDict<Definition> *clangUsrMap;
+ static bool outputToWizard;
+ static QDict<int> *htmlDirMap;
+ static QCache<LookupInfo> *lookupCache;
+ static DirSDict *directories;
+ static SDict<DirRelation> dirRelations;
+ static ParserManager *parserManager;
+ static bool suppressDocWarnings;
+ static Store *symbolStorage;
+ static QCString objDBFileName;
+ static QCString entryDBFileName;
+ static CiteDict *citeDict;
+ static bool gatherDefines;
+ static bool userComments;
+ static IndexList *indexList;
+ static int subpageNestingLevel;
+ static QCString spaces;
+ static bool generatingXmlOutput;
+ static bool markdownSupport;
+ static GenericsSDict *genericsDict;
+};
+
+void initDoxygen();
+void readConfiguration(int argc, char **argv);
+void checkConfiguration();
+void adjustConfiguration();
+void searchInputFiles(StringList &inputFiles);
+void parseInput();
+void generateOutput();
+void readAliases();
+void readFormulaRepository();
+void cleanUpDoxygen();
+int readFileOrDirectory(const char *s,
+ FileNameList *fnList,
+ FileNameDict *fnDict,
+ StringDict *exclDict,
+ QStrList *patList,
+ QStrList *exclPatList,
+ StringList *resultList,
+ StringDict *resultDict,
+ bool recursive,
+ bool errorIfNotExist=TRUE,
+ QDict<void> *killDict = 0,
+ QDict<void> *paths = 0
+ );
+int readDir(QFileInfo *fi,
+ FileNameList *fnList,
+ FileNameDict *fnDict,
+ StringDict *exclDict,
+ QStrList *patList,
+ QStrList *exclPatList,
+ StringList *resultList,
+ StringDict *resultDict,
+ bool errorIfNotExist,
+ bool recursive,
+ QDict<void> *killDict
+ );
+void copyAndFilterFile(const char *fileName,BufStr &dest);
+
+#endif
diff --git a/src/doxygen.md b/src/doxygen.md
new file mode 100644
index 0000000..9a9d726
--- /dev/null
+++ b/src/doxygen.md
@@ -0,0 +1,227 @@
+Doxygen Internals {#mainpage}
+=================
+
+Introduction
+------------
+
+This page provides a high-level overview of the internals of doxygen, with
+links to the relevant parts of the code. This document is intended for
+developers who want to work on doxygen. Users of doxygen are referred to the
+[User Manual](http://www.doxygen.org/manual.html).
+
+The generic starting point of the application is of cource the main() function.
+
+Configuration options
+---------------------
+
+Configuration file data is stored in singleton class Config and can be
+accessed using wrapper macros
+Config_getString(), Config_getInt(), Config_getList(),
+Config_getEnum(), and Config_getBool() depending on the type of the
+option.
+
+The format of the configuration file (options and types) is defined
+by the file `config.xml`. As part of the build process,
+the python script `configgen.py` will create a file configoptions.cpp
+from this, which serves as the input for the configuration file parser
+that is invoked using Config::parse(). The script `configgen.py` will also
+create the documentation for the configuration items, creating the file
+`config.doc`.
+
+Gathering Input files
+---------------------
+
+After the configuration is known, the input files are searched using
+searchInputFiles() and any tag files are read using readTagFile()
+
+Parsing Input files
+-------------------
+
+The function parseFiles() takes care of parsing all files.
+It uses the ParserManager singleton factory to create a suitable parser object
+for each file. Each parser implements the abstract interface ParserInterface.
+
+If the parser indicates it needs preprocessing
+via ParserInterface::needsPreprocessing(), doxygen will call preprocessFile()
+on the file.
+
+A second step is to convert multiline C++-style comments into C style comments
+for easier processing later on. As side effect of this step also
+aliases (ALIASES option) are resolved. The function that performs these
+2 tasks is called convertCppComments().
+
+*Note:* Alias resolution should better be done in a separate step as it is
+now coupled to C/C++ code and does not work automatically for other languages!
+
+The third step is the actual language parsing and is done by calling
+ParserInterface::parseInput() on the parser interface returned by
+the ParserManager.
+
+The result of parsing is a tree of Entry objects.
+These Entry objects are wrapped in a EntryNav object and stored on disk using
+Entry::createNavigationIndex() on the root node of the tree.
+
+Each Entry object roughly contains the raw data for a symbol and is later
+converted into a Definition object.
+
+When a parser finds a special comment block in the input, it will do a first
+pass parsing via parseCommentBlock(). During this pass the comment block
+is split into multiple parts if needed. Some data that is later needed is
+extracted like section labels, xref items, and formulas.
+Also Markdown markup is processed using processMarkdown() during this pass.
+
+Resolving relations
+-------------------
+
+The Entry objects created and filled during parsing are stored on disk
+(to keep memory needs low). The name, parent/child relation, and
+location on disk of each Entry is stored as a tree of EntryNav nodes, which is
+kept in memory.
+
+Doxygen does a number of tree walks over the EntryNav nodes in the tree to
+build up the data structures needed to produce the output.
+
+The resulting data structures are all children of the generic base class
+called Definition which holds all non-specific data for a symbol definition.
+
+Definition is an abstract base class. Concrete subclasses are
+- ClassDef: for storing class/struct/union related data
+- NamespaceDef: for storing namespace related data
+- FileDef: for storing file related data
+- DirDef: for storing directory related data
+
+For doxygen specific concepts the following subclasses are available
+- GroupDef: for storing grouping related data
+- PageDef: for storing page related data
+
+Finally the data for members of classes, namespaces, and files is stored in
+the subclass MemberDef.
+
+Producing debug output
+----------------------
+
+Within doxygen there are a number of ways to obtain debug output. Besides the
+invasive method of putting print statements in the code there are a number of
+easy ways to get debug information.
+
+- Compilation of `.l` files<br>
+ This is also an invasive method but it will be automatically done by the
+ `flex / lex` command. The result is that of each input line the (lex) rule(s)
+ that are applied on it are shown.
+ - windows
+ - in the Visual C++ GUI
+ - find the required `.l` file
+ - select the `Properties` of this file
+ - set the item `Write used lex rules` to `Yes`
+ - see to it that the `.l` file is newer than the corresponding `.cpp` file
+ or remove the corresponding `.cpp` file
+ - unices
+ - global change<br>
+ In the chapter "Doxygen's internals" a `perl` script is given to toggle the
+ possibility of having the rules debug information.
+ - command line change<br>
+ It is possible to the option `LEX="flex -d"` with the `make` command on the
+ command line. In this case the `.l` that are converted to the corresponding
+ `.cpp` files during this `make` get the rules debug information.<br>
+ To undo the rules debug information output just recompile the file with
+ just `make`.<br>
+ Note this method applies for all the `.l` files that are rebuild to `.cpp`
+ files so be sure that only the `.l` files(s) of which you want to have the
+ rules debug information is (are) newer than the corresponding `.cpp`
+ file(s).
+- Running doxygen<br>
+ During a run of doxygen it is possible to specify the `-d` option with the
+ following possibilities (each option has to be preceded by `-d`):
+ - findmembers<br>
+ Gives of global, class, module members its scope, arguments and other relevant information.
+ - functions<br>
+ Gives of functions its scope, arguments and other relevant information.
+ - variables<br>
+ Gives of variables its scope and other relevant information.
+ - classes<br>
+ Gives of classes en modules its scope and other relevant information.
+ - preprocessor<br>
+ Shows the results of the preprocessing phase, i.e. results from include files,
+ <tt>\#define</tt> statements etc., definitions in the doxygen configuration file like:
+ `EXPAND_ONLY_PREDEF`, `PREDEFINED` and `MACRO_EXPANSION`.
+ - commentcnv<br>
+ Shows the results of the comment conversion, the comment conversion does the
+ following:
+ - It converts multi-line C++ style comment blocks (that are aligned)
+ to C style comment blocks (if `MULTILINE_CPP_IS_BRIEF` is set to `NO`).
+ - It replaces aliases with their definition (see `ALIASES`)
+ - It handles conditional sections (<tt>\\cond ... \\endcond</tt> blocks)
+ - commentscan<br>
+ Will print each comment block before and after the comment is interpreted by
+ the comment scanner.
+ - printtree<br>
+ Give the results in in pretty print way, i.e. in an XML like way with each
+ level indented by a `"."` (dot).
+ - time<br>
+ Provides information of the different stages of the doxygen process.
+ - extcmd<br>
+ Shows which external commands are executed and which pipes are opened.
+ - markdown<br>
+ Will print each comment block before and after Markdown processing.
+ - filteroutput<br>
+ Gives the output of the output as result of the filter command (when a filter
+ command is specified)
+ - validate<br>
+ Currently not used
+
+Producing output
+----------------
+
+TODO
+
+Topics TODO
+-----------
+- Grouping of files in Model / Parser / Generator categories
+- Index files based on IndexIntf
+ - HTML navigation
+ - HTML Help (chm)
+ - Documentation Sets (XCode)
+ - Qt Help (qhp)
+ - Eclipse Help
+- Search index
+ - Javascript based
+ - Server based
+ - External
+- Citations
+ - via bibtex
+- Various processing steps for a comment block
+ - comment conversion
+ - comment scanner
+ - markdown processor
+ - doc tokenizer
+ - doc parser
+ - doc visitors
+- Diagrams and Images
+ - builtin
+ - via Graphviz dot
+ - via mscgen
+ - PNG generation
+- Output formats: OutputGen, OutputList, and DocVisitor
+ - Html: HtmlGenerator and HtmlDocVisitor
+ - Latex: LatexGenerator and LatexDocVisitor
+ - RTF: RTFGenerator and RTFDocVisitor
+ - Man: ManGenerator and ManDocVisitor
+ - XML: generateXML() and XmlDocVisitor
+ - print: debugging via PrintDocVisitor
+ - text: TextDocVisitor for tooltips
+ - perlmod
+- i18n via Translator and language.cpp
+- Customizing the layout via LayoutDocManager
+- Parsers
+ - C Preprocessing
+ - const expression evaluation
+ - C link languages
+ - Python
+ - Fortran
+ - VHDL
+ - TCL
+ - Tag files
+- Marshaling to/from disk
+- Portability functions
+- Utility functions
+
diff --git a/src/doxygen.pro b/src/doxygen.pro
new file mode 100644
index 0000000..0dcff1b
--- /dev/null
+++ b/src/doxygen.pro
@@ -0,0 +1,47 @@
+#
+# This file was generated from doxygen.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = app.t
+CONFIG = console warn_on debug
+HEADERS = doxygen.h
+SOURCES = main.cpp
+unix:LIBS += -L../lib -ldoxygen -lvhdlparser -ldoxycfg -lqtools -lmd5 -lpthread
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../lib -ldoxygen -ldoxycfg -lvhdlparser -lqtools -lmd5 -lpthread -llibiconv -lole32
+win32-msvc:LIBS += qtools.lib md5.lib doxygen.lib doxycfg.lib vhdlparser.lib shell32.lib iconv.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\lib
+win32-borland:LIBS += qtools.lib md5.lib doxygen.lib doxycfg.lib vhdlparser.lib shell32.lib iconv.lib
+win32-borland:TMAKE_LFLAGS += -L..\lib -L$(BCB)\lib\psdk
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:LIBS = -L../lib -ldoxygen -ldoxycfg -lvhdlparser -lqtools -lmd5 -liconv -lpthread -Wl,--as-needed -lole32
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti
+DEPENDPATH += ../generated_src/doxygen
+INCLUDEPATH += ../qtools ../libmd5 . ../vhdlparser
+DESTDIR = ../bin
+TARGET = doxygen
+unix:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+win32:TARGETDEPS = ..\lib\doxygen.lib ..\lib\doxycfg.lib
+win32-g++:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+win32-mingw:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+OBJECTS_DIR = ../objects/doxygen
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in
new file mode 100644
index 0000000..4f05a35
--- /dev/null
+++ b/src/doxygen.pro.in
@@ -0,0 +1,40 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = app.t
+CONFIG = console warn_on $extraopts
+HEADERS = doxygen.h
+SOURCES = main.cpp
+unix:LIBS += -L../lib -ldoxygen -lvhdlparser -ldoxycfg -lqtools -lmd5 -lpthread %%SQLITE3_LIBS%% %%LIBCLANG_LIBS%%
+win32:INCLUDEPATH += .
+win32-mingw:LIBS += -L../lib -ldoxygen -ldoxycfg -lvhdlparser -lqtools -lmd5 -lpthread -llibiconv -lole32 %%SQLITE3_LIBS%% %%LIBCLANG_LIBS%%
+win32-msvc:LIBS += qtools.lib md5.lib doxygen.lib doxycfg.lib vhdlparser.lib shell32.lib iconv.lib
+win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\lib
+win32-borland:LIBS += qtools.lib md5.lib doxygen.lib doxycfg.lib vhdlparser.lib shell32.lib iconv.lib
+win32-borland:TMAKE_LFLAGS += -L..\lib -L$(BCB)\lib\psdk
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:LIBS = -L../lib -ldoxygen -ldoxycfg -lvhdlparser -lqtools -lmd5 -liconv -lpthread %%SQLITE3_LIBS%% %%LIBCLANG_LIBS%% -Wl,--as-needed -lole32
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti
+DEPENDPATH += ../generated_src/doxygen
+INCLUDEPATH += ../qtools ../libmd5 . ../vhdlparser
+DESTDIR = ../bin
+TARGET = doxygen
+unix:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+win32:TARGETDEPS = ..\lib\doxygen.lib ..\lib\doxycfg.lib
+win32-g++:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+win32-mingw:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a
+OBJECTS_DIR = ../objects/doxygen
+
diff --git a/src/doxygen.sty b/src/doxygen.sty
new file mode 100644
index 0000000..c423e12
--- /dev/null
+++ b/src/doxygen.sty
@@ -0,0 +1,478 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{doxygen}
+
+% Packages used by this style file
+\RequirePackage{alltt}
+\RequirePackage{array}
+\RequirePackage{calc}
+\RequirePackage{float}
+\RequirePackage{ifthen}
+\RequirePackage{verbatim}
+\RequirePackage[table]{xcolor}
+\RequirePackage{xtab}
+
+%---------- Internal commands used in this style file ----------------
+
+\newcommand{\ensurespace}[1]{%
+ \begingroup%
+ \setlength{\dimen@}{#1}%
+ \vskip\z@\@plus\dimen@%
+ \penalty -100\vskip\z@\@plus -\dimen@%
+ \vskip\dimen@%
+ \penalty 9999%
+ \vskip -\dimen@%
+ \vskip\z at skip% hide the previous |\vskip| from |\addvspace|
+ \endgroup%
+}
+
+\newcommand{\DoxyLabelFont}{}
+\newcommand{\entrylabel}[1]{%
+ {%
+ \parbox[b]{\labelwidth-4pt}{%
+ \makebox[0pt][l]{\DoxyLabelFont#1}%
+ \vspace{1.5\baselineskip}%
+ }%
+ }%
+}
+
+\newenvironment{DoxyDesc}[1]{%
+ \ensurespace{4\baselineskip}%
+ \begin{list}{}{%
+ \settowidth{\labelwidth}{20pt}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\itemsep}{0pt}%
+ \setlength{\leftmargin}{\labelwidth+\labelsep}%
+ \renewcommand{\makelabel}{\entrylabel}%
+ }%
+ \item[#1]%
+}{%
+ \end{list}%
+}
+
+\newsavebox{\xrefbox}
+\newlength{\xreflength}
+\newcommand{\xreflabel}[1]{%
+ \sbox{\xrefbox}{#1}%
+ \setlength{\xreflength}{\wd\xrefbox}%
+ \ifthenelse{\xreflength>\labelwidth}{%
+ \begin{minipage}{\textwidth}%
+ \setlength{\parindent}{0pt}%
+ \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}%
+ \end{minipage}%
+ }{%
+ \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}%
+ }%
+}
+
+%---------- Commands used by doxygen LaTeX output generator ----------
+
+% Used by <pre> ... </pre>
+\newenvironment{DoxyPre}{%
+ \small%
+ \begin{alltt}%
+}{%
+ \end{alltt}%
+ \normalsize%
+}
+
+% Used by @code ... @endcode
+\newenvironment{DoxyCode}{%
+ \par%
+ \scriptsize%
+ \begin{alltt}%
+}{%
+ \end{alltt}%
+ \normalsize%
+}
+
+% Used by @example, @include, @includelineno and @dontinclude
+\newenvironment{DoxyCodeInclude}{%
+ \DoxyCode%
+}{%
+ \endDoxyCode%
+}
+
+% Used by @verbatim ... @endverbatim
+\newenvironment{DoxyVerb}{%
+ \footnotesize%
+ \verbatim%
+}{%
+ \endverbatim%
+ \normalsize%
+}
+
+% Used by @verbinclude
+\newenvironment{DoxyVerbInclude}{%
+ \DoxyVerb%
+}{%
+ \endDoxyVerb%
+}
+
+% Used by numbered lists (using '-#' or <ol> ... </ol>)
+\newenvironment{DoxyEnumerate}{%
+ \enumerate%
+}{%
+ \endenumerate%
+}
+
+% Used by bullet lists (using '-', @li, @arg, or <ul> ... </ul>)
+\newenvironment{DoxyItemize}{%
+ \itemize%
+}{%
+ \enditemize%
+}
+
+% Used by description lists (using <dl> ... </dl>)
+\newenvironment{DoxyDescription}{%
+ \description%
+}{%
+ \enddescription%
+}
+
+% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
+% (only if caption is specified)
+\newenvironment{DoxyImage}{%
+ \begin{figure}[H]%
+ \begin{center}%
+}{%
+ \end{center}%
+ \end{figure}%
+}
+
+% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
+% (only if no caption is specified)
+\newenvironment{DoxyImageNoCaption}{%
+}{%
+}
+
+% Used by @attention
+\newenvironment{DoxyAttention}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @author and @authors
+\newenvironment{DoxyAuthor}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @date
+\newenvironment{DoxyDate}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @invariant
+\newenvironment{DoxyInvariant}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @note
+\newenvironment{DoxyNote}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @post
+\newenvironment{DoxyPostcond}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @pre
+\newenvironment{DoxyPrecond}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @copyright
+\newenvironment{DoxyCopyright}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @remark
+\newenvironment{DoxyRemark}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @return and @returns
+\newenvironment{DoxyReturn}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @since
+\newenvironment{DoxySince}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @see
+\newenvironment{DoxySeeAlso}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @version
+\newenvironment{DoxyVersion}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @warning
+\newenvironment{DoxyWarning}[1]{%
+ \begin{DoxyDesc}{#1}%
+}{%
+ \end{DoxyDesc}%
+}
+
+% Used by @internal
+\newenvironment{DoxyInternal}[1]{%
+ \paragraph*{#1}%
+}{%
+}
+
+% Used by @par and @paragraph
+\newenvironment{DoxyParagraph}[1]{%
+ \begin{list}{}{%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\itemsep}{-4pt}%
+ \renewcommand{\makelabel}{\entrylabel}%
+ }%
+ \item[#1]%
+}{%
+ \end{list}%
+}
+
+% Used by parameter lists
+\newenvironment{DoxyParams}[2][]{%
+ \par%
+ \tabletail{\hline}%
+ \tablelasttail{\hline}%
+ \tablefirsthead{}%
+ \tablehead{}%
+ \ifthenelse{\equal{#1}{}}%
+ {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}%
+ \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.805\textwidth}|}}%
+ {\ifthenelse{\equal{#1}{1}}%
+ {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}%
+ \begin{xtabular}{|>{\centering}p{0.10\textwidth}|%
+ >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.678\textwidth}|}}%
+ {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}%
+ \begin{xtabular}{|>{\centering}p{0.10\textwidth}|%
+ >{\centering\hspace{0pt}}p{0.15\textwidth}|%
+ >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.501\textwidth}|}}%
+ }\hline%
+}{%
+ \end{xtabular}%
+ \tablefirsthead{}%
+ \vspace{6pt}%
+}
+
+% Used for fields of simple structs
+\newenvironment{DoxyFields}[1]{%
+ \par%
+ \tabletail{\hline}%
+ \tablelasttail{\hline}%
+ \tablehead{}%
+ \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}%
+ \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|%
+ p{0.15\textwidth}|%
+ p{0.63\textwidth}|}%
+ \hline%
+}{%
+ \end{xtabular}%
+ \tablefirsthead{}%
+ \vspace{6pt}%
+}
+
+% Used for parameters within a detailed function description
+\newenvironment{DoxyParamCaption}{%
+ \renewcommand{\item}[2][]{##1 {\em ##2}}%
+}{%
+}
+
+% Used by return value lists
+\newenvironment{DoxyRetVals}[1]{%
+ \par%
+ \tabletail{\hline}%
+ \tablelasttail{\hline}%
+ \tablehead{}%
+ \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}%
+ \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.705\textwidth}|}%
+ \hline%
+}{%
+ \end{xtabular}%
+ \tablefirsthead{}%
+ \vspace{6pt}%
+}
+
+% Used by exception lists
+\newenvironment{DoxyExceptions}[1]{%
+ \par%
+ \tabletail{\hline}%
+ \tablelasttail{\hline}%
+ \tablehead{}%
+ \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}%
+ \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.705\textwidth}|}%
+ \hline%
+}{%
+ \end{xtabular}%
+ \tablefirsthead{}%
+ \vspace{6pt}%
+}
+
+% Used by template parameter lists
+\newenvironment{DoxyTemplParams}[1]{%
+ \par%
+ \tabletail{\hline}%
+ \tablelasttail{\hline}%
+ \tablehead{}%
+ \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}%
+ \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|%
+ p{0.705\textwidth}|}%
+ \hline%
+}{%
+ \end{xtabular}%
+ \tablefirsthead{}%
+ \vspace{6pt}%
+}
+
+% Used for member lists
+\newenvironment{DoxyCompactItemize}{%
+ \begin{itemize}%
+ \setlength{\itemsep}{-3pt}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\topsep}{0pt}%
+ \setlength{\partopsep}{0pt}%
+}{%
+ \end{itemize}%
+}
+
+% Used for member descriptions
+\newenvironment{DoxyCompactList}{%
+ \begin{list}{}{%
+ \setlength{\leftmargin}{0.5cm}%
+ \setlength{\itemsep}{0pt}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\topsep}{0pt}%
+ \renewcommand{\makelabel}{\hfill}%
+ }%
+}{%
+ \end{list}%
+}
+
+% Used for reference lists (@bug, @deprecated, @todo, etc.)
+\newenvironment{DoxyRefList}{%
+ \begin{list}{}{%
+ \setlength{\labelwidth}{10pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \addtolength{\leftmargin}{\labelsep}%
+ \renewcommand{\makelabel}{\xreflabel}%
+ }%
+}{%
+ \end{list}%
+}
+
+% Used by @bug, @deprecated, @todo, etc.
+\newenvironment{DoxyRefDesc}[1]{%
+ \begin{list}{}{%
+ \renewcommand\makelabel[1]{\textbf{##1}}%
+ \settowidth\labelwidth{\makelabel{#1}}%
+ \setlength\leftmargin{\labelwidth+\labelsep}%
+ }%
+}{%
+ \end{list}%
+}
+
+% Used by parameter lists and simple sections
+\newenvironment{Desc}
+{\begin{list}{}{%
+ \settowidth{\labelwidth}{40pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \setlength{\parsep}{0pt}%
+ \setlength{\itemsep}{-4pt}%
+ \renewcommand{\makelabel}{\entrylabel}%
+ }
+}{%
+ \end{list}%
+}
+
+% Used by tables
+\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}%
+\newlength{\tmplength}%
+\newenvironment{TabularC}[1]%
+{%
+\setlength{\tmplength}%
+ {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)}%
+ \par\begin{xtabular*}{\linewidth}%
+ {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|}%
+}%
+{\end{xtabular*}\par}%
+
+% Used by nested tables
+\newenvironment{TabularNC}[1]%
+{%
+\setlength{\tmplength}%
+ {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)}%
+ \par\begin{tabular*}{\linewidth}%
+ {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|}%
+}%
+{\end{tabular*}\par}%
+
+% Used for member group headers
+\newenvironment{Indent}{%
+ \begin{list}{}{%
+ \setlength{\leftmargin}{0.5cm}%
+ }%
+ \item[]\ignorespaces%
+}{%
+ \unskip%
+ \end{list}%
+}
+
+% Used when hyperlinks are turned off
+\newcommand{\doxyref}[3]{%
+ \textbf{#1} (\textnormal{#2}\,\pageref{#3})%
+}
+
+% Used by @addindex
+\newcommand{\lcurly}{\{}
+\newcommand{\rcurly}{\}}
+
+% Used for syntax highlighting
+\definecolor{comment}{rgb}{0.5,0.0,0.0}
+\definecolor{keyword}{rgb}{0.0,0.5,0.0}
+\definecolor{keywordtype}{rgb}{0.38,0.25,0.125}
+\definecolor{keywordflow}{rgb}{0.88,0.5,0.0}
+\definecolor{preprocessor}{rgb}{0.5,0.38,0.125}
+\definecolor{stringliteral}{rgb}{0.0,0.125,0.25}
+\definecolor{charliteral}{rgb}{0.0,0.5,0.5}
+\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0}
+\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43}
+\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0}
+\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0}
diff --git a/src/dynsections.js b/src/dynsections.js
new file mode 100644
index 0000000..85e1836
--- /dev/null
+++ b/src/dynsections.js
@@ -0,0 +1,97 @@
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+ content.hide();
+ summary.show();
+ $(linkObj).addClass('closed').removeClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ content.show();
+ summary.hide();
+ $(linkObj).removeClass('closed').addClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+ return false;
+}
+
+function updateStripes()
+{
+ $('table.directory tr').
+ removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+ $('table.directory tr').each(function() {
+ var l = this.id.split('_').length-1;
+ var i = $('#img'+this.id.substring(3));
+ var a = $('#arr'+this.id.substring(3));
+ if (l<level+1) {
+ i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+ a.html('▼');
+ $(this).show();
+ } else if (l==level+1) {
+ i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+ a.html('►');
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+ updateStripes();
+}
+
+function toggleFolder(id)
+{
+ // the clicked row
+ var currentRow = $('#row_'+id);
+
+ // all rows after the clicked row
+ var rows = currentRow.nextAll("tr");
+
+ var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+ // only match elements AFTER this one (can't hide elements before)
+ var childRows = rows.filter(function() { return this.id.match(re); });
+
+ // first row is visible we are HIDING
+ if (childRows.filter(':first').is(':visible')===true) {
+ // replace down arrow by right arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ currentRowSpans.filter(".arrow").html('►');
+ rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+ } else { // we are SHOWING
+ // replace right arrow by down arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+ currentRowSpans.filter(".arrow").html('▼');
+ // replace down arrows by right arrows for child rows
+ var childRowsSpans = childRows.find("span");
+ childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ childRowsSpans.filter(".arrow").html('►');
+ childRows.show(); //show all children
+ }
+ updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+ var rows = $('tr.inherit.'+id);
+ var img = $('tr.inherit_header.'+id+' img');
+ var src = $(img).attr('src');
+ if (rows.filter(':first').is(':visible')===true) {
+ rows.css('display','none');
+ $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ rows.css('display','table-row'); // using show() causes jump in firefox
+ $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+}
+
diff --git a/src/eclipsehelp.cpp b/src/eclipsehelp.cpp
new file mode 100644
index 0000000..6680aeb
--- /dev/null
+++ b/src/eclipsehelp.cpp
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#include "eclipsehelp.h"
+#include "util.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include <qfile.h>
+
+EclipseHelp::EclipseHelp() : m_depth(0), m_endtag(FALSE), m_openTags(0), m_tocfile(0)
+{
+}
+
+EclipseHelp::~EclipseHelp()
+{
+}
+
+void EclipseHelp::indent()
+{
+ int i;
+ for (i=0; i<m_depth; i++)
+ {
+ m_tocstream << " ";
+ }
+}
+
+void EclipseHelp::closedTag()
+{
+ if (m_endtag)
+ {
+ m_tocstream << "/>" << endl;
+ m_endtag = FALSE;
+ }
+}
+
+void EclipseHelp::openedTag()
+{
+ if (m_endtag)
+ {
+ m_tocstream << ">" << endl;
+ m_endtag = FALSE;
+ ++m_openTags;
+ }
+}
+
+/*!
+ * \brief Initialize the Eclipse generator
+ *
+ * This method opens the XML TOC file and writes headers of the files.
+ * \sa finalize()
+ */
+void EclipseHelp::initialize()
+{
+ // -- read path prefix from the configuration
+ //m_pathprefix = Config_getString("ECLIPSE_PATHPREFIX");
+ //if (m_pathprefix.isEmpty()) m_pathprefix = "html/";
+
+ // -- open the contents file
+ QCString name = Config_getString("HTML_OUTPUT") + "/toc.xml";
+ m_tocfile = new QFile(name);
+ if (!m_tocfile->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n", name.data());
+ exit(1);
+ }
+
+ // -- initialize its text stream
+ m_tocstream.setDevice(m_tocfile);
+ //m_tocstream.setEncoding(FTextStream::UnicodeUTF8);
+
+ // -- write the opening tag
+ QCString title = Config_getString("PROJECT_NAME");
+ if (title.isEmpty())
+ {
+ title = "Doxygen generated documentation";
+ }
+ m_tocstream << "<toc label=\"" << convertToXML(title)
+ << "\" topic=\"" << convertToXML(m_pathprefix)
+ << "index" << Doxygen::htmlFileExtension << "\">" << endl;
+ ++ m_depth;
+}
+
+/*!
+ * \brief Finish generation of the Eclipse specific help files
+ *
+ * This method writes footers of the files and closes them.
+ * \sa initialize()
+ */
+void EclipseHelp::finalize()
+{
+ closedTag(); // -- close previous tag
+
+ // -- write ending tag
+ --m_depth;
+ m_tocstream << "</toc>" << endl;
+
+ // -- close the content file
+ m_tocstream.unsetDevice();
+ m_tocfile->close();
+ delete m_tocfile; m_tocfile = 0;
+
+ QCString name = Config_getString("HTML_OUTPUT") + "/plugin.xml";
+ QFile pluginFile(name);
+ if (pluginFile.open(IO_WriteOnly))
+ {
+ QString docId = Config_getString("ECLIPSE_DOC_ID");
+ FTextStream t(&pluginFile);
+ t << "<plugin name=\"" << docId << "\" id=\"" << docId << "\"" << endl;
+ t << " version=\"1.0.0\" provider-name=\"Doxygen\">" << endl;
+ t << " <extension point=\"org.eclipse.help.toc\">" << endl;
+ t << " <toc file=\"toc.xml\" primary=\"true\" />" << endl;
+ t << " </extension>" << endl;
+ t << "</plugin>" << endl;
+ }
+}
+
+/*!
+ * \brief Increase the level of content hierarchy
+ */
+void EclipseHelp::incContentsDepth()
+{
+ openedTag();
+ ++m_depth;
+}
+
+/*!
+ * \brief Decrease the level of content hierarchy
+ *
+ * It closes currently opened topic tag.
+ */
+void EclipseHelp::decContentsDepth()
+{
+ // -- end of the opened topic
+ closedTag();
+ --m_depth;
+
+ if (m_openTags==m_depth)
+ {
+ --m_openTags;
+ indent();
+ m_tocstream << "</topic>" << endl;
+ }
+}
+
+/*!
+ * \brief Add an item to the content
+ *
+ * @param isDir Flag whether the argument \a file is a directory or a file entry
+ * @param name Name of the item
+ * @param ref URL of the item
+ * @param file Name of a file which the item is defined in (without extension)
+ * @param anchor Name of an anchor of the item.
+ * @param separateIndex not used.
+ * @param addToNavIndex not used.
+ * @param def not used.
+ */
+void EclipseHelp::addContentsItem(
+ bool /* isDir */,
+ const char *name,
+ const char * /* ref */,
+ const char *file,
+ const char *anchor,
+ bool /* separateIndex */,
+ bool /* addToNavIndex */,
+ Definition * /*def*/)
+{
+ // -- write the topic tag
+ closedTag();
+ if (file)
+ {
+ switch (file[0]) // check for special markers (user defined URLs)
+ {
+ case '^':
+ // URL not supported by eclipse toc.xml
+ break;
+
+ case '!':
+ indent();
+ m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
+ m_tocstream << " href=\"" << convertToXML(m_pathprefix) << &file[1] << "\"";
+ m_endtag = TRUE;
+ break;
+
+ default:
+ indent();
+ m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
+ m_tocstream << " href=\"" << convertToXML(m_pathprefix)
+ << file << Doxygen::htmlFileExtension;
+ if (anchor)
+ {
+ m_tocstream << "#" << anchor;
+ }
+ m_tocstream << "\"";
+ m_endtag = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ indent();
+ m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
+ m_endtag = TRUE;
+ }
+}
+
+void EclipseHelp::addIndexItem(
+ Definition * /* context */,
+ MemberDef * /* md */,
+ const char * /* sectionAnchor */,
+ const char * /* title */)
+{
+}
+
+void EclipseHelp::addIndexFile(const char * /* name */)
+{
+}
+
+void EclipseHelp::addImageFile(const char * /* name */)
+{
+}
+
+void EclipseHelp::addStyleSheetFile(const char * /* name */)
+{
+}
+
diff --git a/src/eclipsehelp.h b/src/eclipsehelp.h
new file mode 100644
index 0000000..f0ab78e
--- /dev/null
+++ b/src/eclipsehelp.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*
+ * eclipsehelp.h
+ *
+ * Created on: 7.11.2009
+ * Author: ondrej
+ */
+
+#ifndef ECLIPSEHELP_H
+#define ECLIPSEHELP_H
+
+#include "index.h"
+#include "ftextstream.h"
+
+/* -- forward declarations */
+class QFile;
+class Definition;
+
+/** Generator for Eclipse help files.
+ *
+ * This class generates the Eclipse specific help files.
+ * These files can be used to generate a help plugin readable
+ * by the Eclipse IDE.
+ */
+class EclipseHelp : public IndexIntf
+{
+ public:
+ EclipseHelp();
+ virtual ~EclipseHelp();
+
+ /* -- index interface */
+ virtual void initialize();
+ virtual void finalize();
+ virtual void incContentsDepth();
+ virtual void decContentsDepth();
+ virtual void addContentsItem(bool isDir, const char *name, const char *ref,
+ const char *file, const char *anchor,bool separateIndex,bool addToNavIndex,
+ Definition *def);
+ virtual void addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor,const char *title);
+ virtual void addIndexFile(const char *name);
+ virtual void addImageFile(const char *name);
+ virtual void addStyleSheetFile(const char *name);
+
+ private:
+ int m_depth;
+ bool m_endtag;
+ int m_openTags;
+
+ QFile * m_tocfile;
+ FTextStream m_tocstream;
+ QCString m_pathprefix;
+
+ /* -- avoid copying */
+ EclipseHelp(const EclipseHelp &);
+ EclipseHelp & operator = (const EclipseHelp &);
+
+ /* -- formatting helpers */
+ void indent();
+ void closedTag();
+ void openedTag();
+};
+
+#endif /* ECLIPSEHELP_H */
diff --git a/src/entry.cpp b/src/entry.cpp
new file mode 100644
index 0000000..ee3d0ae
--- /dev/null
+++ b/src/entry.cpp
@@ -0,0 +1,444 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+#include <qfile.h>
+#include "entry.h"
+#include "marshal.h"
+#include "util.h"
+#include "section.h"
+#include "doxygen.h"
+#include "filestorage.h"
+#include "arguments.h"
+
+//------------------------------------------------------------------
+
+#define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
+
+//------------------------------------------------------------------
+
+int Entry::num=0;
+
+Entry::Entry()
+{
+ //printf("Entry::Entry(%p)\n",this);
+ num++;
+ m_parent=0;
+ section = EMPTY_SEC;
+ m_sublist = new QList<Entry>;
+ m_sublist->setAutoDelete(TRUE);
+ extends = new QList<BaseInfo>;
+ extends->setAutoDelete(TRUE);
+ groups = new QList<Grouping>;
+ groups->setAutoDelete(TRUE);
+ anchors = new QList<SectionInfo>; // Doxygen::sectionDict takes ownership of the items!
+ argList = new ArgumentList;
+ argList->setAutoDelete(TRUE);
+ //printf("Entry::Entry() tArgList=0\n");
+ tArgLists = 0;
+ typeConstr = 0;
+ mGrpId = -1;
+ tagInfo = 0;
+ sli = 0;
+ relatesType = Simple;
+ hidden = FALSE;
+ groupDocType = GROUPDOC_NORMAL;
+ reset();
+}
+
+Entry::Entry(const Entry &e)
+{
+ //printf("Entry::Entry(%p):copy\n",this);
+ num++;
+ section = e.section;
+ type = e.type;
+ name = e.name;
+ tagInfo = e.tagInfo;
+ protection = e.protection;
+ mtype = e.mtype;
+ spec = e.spec;
+ initLines = e.initLines;
+ stat = e.stat;
+ explicitExternal = e.explicitExternal;
+ proto = e.proto;
+ subGrouping = e.subGrouping;
+ callGraph = e.callGraph;
+ callerGraph = e.callerGraph;
+ virt = e.virt;
+ args = e.args;
+ bitfields = e.bitfields;
+ argList = e.argList->deepCopy();
+ tArgLists = 0;
+ program = e.program;
+ initializer = e.initializer;
+ includeFile = e.includeFile;
+ includeName = e.includeName;
+ doc = e.doc;
+ docLine = e.docLine;
+ docFile = e.docFile;
+ brief = e.brief;
+ briefLine = e.briefLine;
+ briefFile = e.briefFile;
+ inbodyDocs = e.inbodyDocs;
+ inbodyLine = e.inbodyLine;
+ inbodyFile = e.inbodyFile;
+ relates = e.relates;
+ relatesType = e.relatesType;
+ read = e.read;
+ write = e.write;
+ inside = e.inside;
+ exception = e.exception;
+ typeConstr = 0;
+ bodyLine = e.bodyLine;
+ endBodyLine = e.endBodyLine;
+ mGrpId = e.mGrpId;
+ extends = new QList<BaseInfo>;
+ extends->setAutoDelete(TRUE);
+ groups = new QList<Grouping>;
+ groups->setAutoDelete(TRUE);
+ anchors = new QList<SectionInfo>;
+ fileName = e.fileName;
+ startLine = e.startLine;
+ startColumn = e.startColumn;
+ if (e.sli)
+ {
+ sli = new QList<ListItemInfo>;
+ sli->setAutoDelete(TRUE);
+ QListIterator<ListItemInfo> slii(*e.sli);
+ ListItemInfo *ili;
+ for (slii.toFirst();(ili=slii.current());++slii)
+ {
+ sli->append(new ListItemInfo(*ili));
+ }
+ }
+ else
+ {
+ sli=0;
+ }
+ lang = e.lang;
+ hidden = e.hidden;
+ artificial = e.artificial;
+ groupDocType = e.groupDocType;
+ id = e.id;
+
+ m_parent = e.m_parent;
+ m_sublist = new QList<Entry>;
+ m_sublist->setAutoDelete(TRUE);
+
+ // deep copy of the child entry list
+ QListIterator<Entry> eli(*e.m_sublist);
+ Entry *cur;
+ for (;(cur=eli.current());++eli)
+ {
+ m_sublist->append(new Entry(*cur));
+ }
+
+ // deep copy base class list
+ QListIterator<BaseInfo> bli(*e.extends);
+ BaseInfo *bi;
+ for (;(bi=bli.current());++bli)
+ {
+ extends->append(new BaseInfo(*bi));
+ }
+
+ // deep copy group list
+ QListIterator<Grouping> gli(*e.groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ groups->append(new Grouping(*g));
+ }
+
+ QListIterator<SectionInfo> sli2(*e.anchors);
+ SectionInfo *s;
+ for (;(s=sli2.current());++sli2)
+ {
+ anchors->append(new SectionInfo(*s));
+ }
+
+ // deep copy type contraint list
+ if (e.typeConstr)
+ {
+ typeConstr = e.typeConstr->deepCopy();
+ }
+
+ // deep copy template argument lists
+ if (e.tArgLists)
+ {
+ tArgLists = copyArgumentLists(e.tArgLists);
+ }
+
+}
+
+Entry::~Entry()
+{
+ //printf("Entry::~Entry(%p) num=%d\n",this,num);
+ //printf("Deleting entry %d name %s type %x children %d\n",
+ // num,name.data(),section,sublist->count());
+
+ delete m_sublist; // each element is now own by a EntryNav so we do no longer own
+ // our children.
+ delete extends;
+ delete groups;
+ delete anchors;
+ delete argList;
+ delete tArgLists;
+ delete tagInfo;
+ delete typeConstr;
+ delete sli;
+ num--;
+}
+
+void Entry::addSubEntry(Entry *current)
+{
+ //printf("Entry %d with name %s type 0x%x added to %s type 0x%x\n",
+ // current->num,current->name.data(),current->section,
+ // name.data(),section);
+ //printf("Entry::addSubEntry(%s:%p) to %s\n",current->name.data(),
+ // current,name.data());
+ current->m_parent=this;
+ m_sublist->append(current);
+}
+
+void Entry::reset()
+{
+ //printf("Entry::reset()\n");
+ name.resize(0);
+ type.resize(0);
+ args.resize(0);
+ bitfields.resize(0);
+ exception.resize(0);
+ program.resize(0);
+ includeFile.resize(0);
+ includeName.resize(0);
+ doc.resize(0);
+ docFile.resize(0);
+ docLine=-1;
+ relates.resize(0);
+ relatesType=Simple;
+ brief.resize(0);
+ briefFile.resize(0);
+ briefLine=-1;
+ inbodyDocs.resize(0);
+ inbodyFile.resize(0);
+ inbodyLine=-1;
+ inside.resize(0);
+ fileName.resize(0);
+ initializer.resize(0);
+ initLines = -1;
+ startLine = 1;
+ startColumn = 1;
+ bodyLine = -1;
+ endBodyLine = -1;
+ mGrpId = -1;
+ callGraph = FALSE;
+ callerGraph = FALSE;
+ section = EMPTY_SEC;
+ mtype = Method;
+ virt = Normal;
+ stat = FALSE;
+ proto = FALSE;
+ explicitExternal = FALSE;
+ spec = 0;
+ lang = SrcLangExt_Unknown;
+ hidden = FALSE;
+ artificial = FALSE;
+ subGrouping = TRUE;
+ protection = Public;
+ groupDocType = GROUPDOC_NORMAL;
+ id.resize(0);
+ m_sublist->clear();
+ extends->clear();
+ groups->clear();
+ anchors->clear();
+ argList->clear();
+ if (tagInfo) { delete tagInfo; tagInfo=0; }
+ if (tArgLists) { delete tArgLists; tArgLists=0; }
+ if (sli) { delete sli; sli=0; }
+ if (typeConstr) { delete typeConstr; typeConstr=0; }
+ //if (mtArgList) { delete mtArgList; mtArgList=0; }
+}
+
+
+int Entry::getSize()
+{
+ return sizeof(Entry);
+}
+
+void Entry::createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd)
+{
+ EntryNav *childNav = new EntryNav(nav,this);
+ nav->addChild(childNav);
+ childNav->setFileDef(fd);
+ childNav->saveEntry(this,storage);
+ if (m_sublist)
+ {
+ //printf("saveEntry: %d children\n",node->sublist->count());
+ QListIterator<Entry> eli(*m_sublist);
+ Entry *childNode;
+ for (eli.toFirst();(childNode=eli.current());++eli)
+ {
+ childNode->createSubtreeIndex(childNav,storage,fd);
+ }
+ //m_sublist->setAutoDelete(FALSE);
+ m_sublist->clear();
+ }
+}
+
+void Entry::createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd)
+{
+ //printf("createNavigationIndex(%p) sublist=%p\n",this,m_sublist);
+ if (m_sublist)
+ {
+ //printf("saveEntries: %d children\n",root->sublist->count());
+ // store all child entries of root, but keep the navigation info (=index)
+ QListIterator<Entry> eli(*m_sublist);
+ Entry *e;
+ for (eli.toFirst();(e=eli.current());++eli)
+ {
+ createSubtreeIndex(rootNav,storage,fd);
+ }
+ // remove all entries from root
+ //m_sublist->setAutoDelete(FALSE);
+ m_sublist->clear();
+ }
+}
+
+void Entry::addSpecialListItem(const char *listName,int itemId)
+{
+ if (sli==0)
+ {
+ sli = new QList<ListItemInfo>;
+ sli->setAutoDelete(TRUE);
+ }
+ ListItemInfo *ili=new ListItemInfo;
+ ili->type = listName;
+ ili->itemId = itemId;
+ sli->append(ili);
+}
+
+Entry *Entry::removeSubEntry(Entry *e)
+{
+ int i = m_sublist->find(e);
+ return i!=-1 ? m_sublist->take(i) : 0;
+}
+
+//------------------------------------------------------------------
+
+
+EntryNav::EntryNav(EntryNav *parent, Entry *e)
+ : m_parent(parent), m_subList(0), m_section(e->section), m_type(e->type),
+ m_name(e->name), m_fileDef(0), m_lang(e->lang),
+ m_info(0), m_offset(-1), m_noLoad(FALSE)
+{
+ if (e->tagInfo)
+ {
+ m_tagInfo = new TagInfo;
+ m_tagInfo->tagName = e->tagInfo->tagName;
+ m_tagInfo->fileName = e->tagInfo->fileName;
+ m_tagInfo->anchor = e->tagInfo->anchor;
+ if (e->tagInfo)
+ {
+ //printf("tagInfo %p: tagName=%s fileName=%s anchor=%s\n",
+ // e->tagInfo,
+ // e->tagInfo->tagName.data(),
+ // e->tagInfo->fileName.data(),
+ // e->tagInfo->anchor.data());
+ }
+ }
+ else
+ {
+ m_tagInfo = 0;
+ }
+}
+
+EntryNav::~EntryNav()
+{
+ delete m_subList;
+ delete m_info;
+ delete m_tagInfo;
+}
+
+void EntryNav::addChild(EntryNav *e)
+{
+ if (m_subList==0)
+ {
+ m_subList = new QList<EntryNav>;
+ m_subList->setAutoDelete(TRUE);
+ }
+ m_subList->append(e);
+}
+
+bool EntryNav::loadEntry(FileStorage *storage)
+{
+ if (m_noLoad)
+ {
+ return TRUE;
+ }
+ if (m_offset==-1)
+ {
+ //printf("offset not set!\n");
+ return FALSE;
+ }
+ //delete m_info;
+ //printf("EntryNav::loadEntry: new entry %p: %s\n",m_info,m_name.data());
+ //m_info->tagInfo = m_tagInfo;
+ //if (m_parent)
+ //{
+ // m_info->parent = m_parent->m_info;
+ //}
+ //m_info->parent = 0;
+ //printf("load entry: seek to %llx\n",m_offset);
+ if (!storage->seek(m_offset))
+ {
+ //printf("seek failed!\n");
+ return FALSE;
+ }
+ if (m_info) delete m_info;
+ m_info = unmarshalEntry(storage);
+ m_info->name = m_name;
+ m_info->type = m_type;
+ m_info->section = m_section;
+ return TRUE;
+}
+
+bool EntryNav::saveEntry(Entry *e,FileStorage *storage)
+{
+ m_offset = storage->pos();
+ //printf("EntryNav::saveEntry offset=%llx\n",m_offset);
+ marshalEntry(storage,e);
+ return TRUE;
+}
+
+void EntryNav::releaseEntry()
+{
+ if (!m_noLoad)
+ {
+ //printf("EntryNav::releaseEntry %p\n",m_info);
+ delete m_info;
+ m_info=0;
+ }
+}
+
+void EntryNav::setEntry(Entry *e)
+{
+ delete m_info;
+ m_info = e;
+ //printf("EntryNav::setEntry %p\n",e);
+ m_noLoad=TRUE;
+}
+
diff --git a/src/entry.h b/src/entry.h
new file mode 100644
index 0000000..2cc2827
--- /dev/null
+++ b/src/entry.h
@@ -0,0 +1,382 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include "types.h"
+
+#include <qlist.h>
+#include <qgstring.h>
+
+struct SectionInfo;
+class QFile;
+class EntryNav;
+class FileDef;
+class FileStorage;
+class StorageIntf;
+class ArgumentList;
+struct ListItemInfo;
+
+/** This class stores information about an inheritance relation
+ */
+struct BaseInfo
+{
+ /*! Creates an object representing an inheritance relation */
+ BaseInfo(const char *n,Protection p,Specifier v) :
+ name(n),prot(p),virt(v) {}
+ QCString name; //!< the name of the base class
+ Protection prot; //!< inheritance type
+ Specifier virt; //!< virtualness
+};
+
+/** This struct is used to capture the tag file information
+ * for an Entry.
+ */
+struct TagInfo
+{
+ QCString tagName;
+ QCString fileName;
+ QCString anchor;
+};
+
+/** Represents an unstructured piece of information, about an
+ * entity found in the sources.
+ *
+ * parseMain() in scanner.l will generate a tree of these
+ * entries.
+ */
+class Entry
+{
+ public:
+
+ /*! Kind of entries that are supported */
+ enum Sections {
+ CLASS_SEC = 0x00000001,
+ NAMESPACE_SEC = 0x00000010,
+ COMPOUND_MASK = CLASS_SEC,
+ SCOPE_MASK = COMPOUND_MASK | NAMESPACE_SEC,
+
+ CLASSDOC_SEC = 0x00000800,
+ STRUCTDOC_SEC = 0x00001000,
+ UNIONDOC_SEC = 0x00002000,
+ EXCEPTIONDOC_SEC = 0x00004000,
+ NAMESPACEDOC_SEC = 0x00008000,
+ INTERFACEDOC_SEC = 0x00010000,
+ PROTOCOLDOC_SEC = 0x00020000,
+ CATEGORYDOC_SEC = 0x00040000,
+ SERVICEDOC_SEC = 0x00080000,
+ SINGLETONDOC_SEC = 0x00100000,
+ COMPOUNDDOC_MASK = CLASSDOC_SEC | STRUCTDOC_SEC | UNIONDOC_SEC |
+ INTERFACEDOC_SEC | EXCEPTIONDOC_SEC | PROTOCOLDOC_SEC |
+ CATEGORYDOC_SEC | SERVICEDOC_SEC | SINGLETONDOC_SEC,
+
+ SOURCE_SEC = 0x00400000,
+ HEADER_SEC = 0x00800000,
+ FILE_MASK = SOURCE_SEC | HEADER_SEC,
+
+ ENUMDOC_SEC = 0x01000000,
+ ENUM_SEC = 0x02000000,
+ EMPTY_SEC = 0x03000000,
+ PAGEDOC_SEC = 0x04000000,
+ VARIABLE_SEC = 0x05000000,
+ FUNCTION_SEC = 0x06000000,
+ TYPEDEF_SEC = 0x07000000,
+ MEMBERDOC_SEC = 0x08000000,
+ OVERLOADDOC_SEC = 0x09000000,
+ EXAMPLE_SEC = 0x0a000000,
+ VARIABLEDOC_SEC = 0x0b000000,
+ FILEDOC_SEC = 0x0c000000,
+ DEFINEDOC_SEC = 0x0d000000,
+ INCLUDE_SEC = 0x0e000000,
+ DEFINE_SEC = 0x0f000000,
+ GROUPDOC_SEC = 0x10000000,
+ USINGDIR_SEC = 0x11000000,
+ MAINPAGEDOC_SEC = 0x12000000,
+ MEMBERGRP_SEC = 0x13000000,
+ USINGDECL_SEC = 0x14000000,
+ PACKAGE_SEC = 0x15000000,
+ PACKAGEDOC_SEC = 0x16000000,
+ OBJCIMPL_SEC = 0x17000000,
+ DIRDOC_SEC = 0x18000000
+ ,EXPORTED_INTERFACE_SEC = 0x19000000
+ ,INCLUDED_SERVICE_SEC = 0x1A000000
+ };
+
+ // class specifiers (add new items to the end)
+ static const uint64 Template = (1ULL<<0);
+ static const uint64 Generic = (1ULL<<1);
+ static const uint64 Ref = (1ULL<<2);
+ static const uint64 Value = (1ULL<<3);
+ static const uint64 Interface = (1ULL<<4);
+ static const uint64 Struct = (1ULL<<5);
+ static const uint64 Union = (1ULL<<6);
+ static const uint64 Exception = (1ULL<<7);
+ static const uint64 Protocol = (1ULL<<8);
+ static const uint64 Category = (1ULL<<9);
+ static const uint64 SealedClass = (1ULL<<10);
+ static const uint64 AbstractClass = (1ULL<<11);
+ static const uint64 Enum = (1ULL<<12); // for Java-style enums
+ static const uint64 Service = (1ULL<<13); // UNO IDL
+ static const uint64 Singleton = (1ULL<<14); // UNO IDL
+ static const uint64 ForwardDecl = (1ULL<<14); // forward declarad template classes
+
+ // member specifiers (add new items to the beginning)
+ static const uint64 PrivateGettable = (1ULL<<20); // C# private getter
+ static const uint64 ProtectedGettable = (1ULL<<21); // C# protected getter
+ static const uint64 PrivateSettable = (1ULL<<22); // C# private setter
+ static const uint64 ProtectedSettable = (1ULL<<23); // C# protected setter
+ static const uint64 Inline = (1ULL<<24);
+ static const uint64 Explicit = (1ULL<<25);
+ static const uint64 Mutable = (1ULL<<26);
+ static const uint64 Settable = (1ULL<<27);
+ static const uint64 Gettable = (1ULL<<28);
+ static const uint64 Readable = (1ULL<<29);
+ static const uint64 Writable = (1ULL<<30);
+ static const uint64 Final = (1ULL<<31);
+ static const uint64 Abstract = (1ULL<<32);
+ static const uint64 Addable = (1ULL<<33);
+ static const uint64 Removable = (1ULL<<34);
+ static const uint64 Raisable = (1ULL<<35);
+ static const uint64 Override = (1ULL<<36);
+ static const uint64 New = (1ULL<<37);
+ static const uint64 Sealed = (1ULL<<38);
+ static const uint64 Initonly = (1ULL<<39);
+ static const uint64 Optional = (1ULL<<40);
+ static const uint64 Required = (1ULL<<41);
+ static const uint64 NonAtomic = (1ULL<<42);
+ static const uint64 Copy = (1ULL<<43);
+ static const uint64 Retain = (1ULL<<44);
+ static const uint64 Assign = (1ULL<<45);
+ static const uint64 Strong = (1ULL<<46);
+ static const uint64 Weak = (1ULL<<47);
+ static const uint64 Unretained = (1ULL<<48);
+ static const uint64 Alias = (1ULL<<49);
+ static const uint64 ConstExp = (1ULL<<50);
+ static const uint64 Default = (1ULL<<51);
+ static const uint64 Delete = (1ULL<<52);
+ static const uint64 NoExcept = (1ULL<<53);
+ static const uint64 Attribute = (1ULL<<54); // UNO IDL attribute
+ static const uint64 Property = (1ULL<<55); // UNO IDL property
+ static const uint64 Readonly = (1ULL<<56); // on UNO IDL attribute or property
+ static const uint64 Bound = (1ULL<<57); // on UNO IDL attribute or property
+ static const uint64 Constrained = (1ULL<<58); // on UNO IDL property
+ static const uint64 Transient = (1ULL<<59); // on UNO IDL property
+ static const uint64 MaybeVoid = (1ULL<<60); // on UNO IDL property
+ static const uint64 MaybeDefault = (1ULL<<61); // on UNO IDL property
+ static const uint64 MaybeAmbiguous = (1ULL<<62); // on UNO IDL property
+ static const uint64 Published = (1ULL<<63); // UNO IDL keyword
+
+ enum GroupDocType
+ {
+ GROUPDOC_NORMAL, //!< defgroup
+ GROUPDOC_ADD, //!< addgroup
+ GROUPDOC_WEAK //!< weakgroup
+ }; //!< kind of group
+
+ Entry();
+ Entry(const Entry &);
+ ~Entry();
+
+ /*! Returns the static size of the Entry (so excluding any dynamic memory) */
+ int getSize();
+
+ void addSpecialListItem(const char *listName,int index);
+ void createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd);
+
+ // while parsing a file these function can be used to navigate/build the tree
+ void setParent(Entry *parent) { m_parent = parent; }
+
+ /*! Returns the parent for this Entry or 0 if this entry has no parent. */
+ Entry *parent() const { return m_parent; }
+
+ /*! Returns the list of children for this Entry
+ * @see addSubEntry() and removeSubEntry()
+ */
+ const QList<Entry> *children() const { return m_sublist; }
+
+ /*! Adds entry \a e as a child to this entry */
+ void addSubEntry (Entry* e) ;
+
+ /*! Removes entry \a e from the list of children.
+ * Returns a pointer to the entry or 0 if the entry was not a child.
+ * Note the entry will not be deleted.
+ */
+ Entry *removeSubEntry(Entry *e);
+
+ /*! Restore the state of this Entry to the default value it has
+ * at construction time.
+ */
+ void reset();
+
+ /*! Serialize this entry to a persistent storage stream. */
+ void marshall(StorageIntf *);
+
+ /*! Reinitialize this entry from a persistent storage stream. */
+ void unmarshall(StorageIntf *);
+
+ public:
+
+ // identification
+ int section; //!< entry type (see Sections);
+ QCString type; //!< member type
+ QCString name; //!< member name
+ TagInfo *tagInfo; //!< tag file info
+
+ // content
+ Protection protection; //!< class protection
+ MethodTypes mtype; //!< signal, slot, (dcop) method, or property?
+ uint64 spec; //!< class/member specifiers
+ int initLines; //!< define/variable initializer lines to show
+ bool stat; //!< static ?
+ bool explicitExternal; //!< explicitly defined as external?
+ bool proto; //!< prototype ?
+ bool subGrouping; //!< automatically group class members?
+ bool callGraph; //!< do we need to draw the call graph?
+ bool callerGraph; //!< do we need to draw the caller graph?
+ Specifier virt; //!< virtualness of the entry
+ QCString args; //!< member argument string
+ QCString bitfields; //!< member's bit fields
+ ArgumentList *argList; //!< member arguments as a list
+ QList<ArgumentList> *tArgLists; //!< template argument declarations
+ QGString program; //!< the program text
+ QGString initializer; //!< initial value (for variables)
+ QCString includeFile; //!< include file (2 arg of \\class, must be unique)
+ QCString includeName; //!< include name (3 arg of \\class)
+ QCString doc; //!< documentation block (partly parsed)
+ int docLine; //!< line number at which the documentation was found
+ QCString docFile; //!< file in which the documentation was found
+ QCString brief; //!< brief description (doc block)
+ int briefLine; //!< line number at which the brief desc. was found
+ QCString briefFile; //!< file in which the brief desc. was found
+ QCString inbodyDocs; //!< documentation inside the body of a function
+ int inbodyLine; //!< line number at which the body doc was found
+ QCString inbodyFile; //!< file in which the body doc was found
+ QCString relates; //!< related class (doc block)
+ RelatesType relatesType; //!< how relates is handled
+ QCString read; //!< property read accessor
+ QCString write; //!< property write accessor
+ QCString inside; //!< name of the class in which documents are found
+ QCString exception; //!< throw specification
+ ArgumentList *typeConstr; //!< where clause (C#) for type constraints
+ int bodyLine; //!< line number of the definition in the source
+ int endBodyLine; //!< line number where the definition ends
+ int mGrpId; //!< member group id
+ QList<BaseInfo> *extends; //!< list of base classes
+ QList<Grouping> *groups; //!< list of groups this entry belongs to
+ QList<SectionInfo> *anchors; //!< list of anchors defined in this entry
+ QCString fileName; //!< file this entry was extracted from
+ int startLine; //!< start line of entry in the source
+ int startColumn; //!< start column of entry in the source
+ QList<ListItemInfo> *sli; //!< special lists (test/todo/bug/deprecated/..) this entry is in
+ SrcLangExt lang; //!< programming language in which this entry was found
+ bool hidden; //!< does this represent an entity that is hidden from the output
+ bool artificial; //!< Artificially introduced item
+ GroupDocType groupDocType;
+ QCString id; //!< libclang id
+
+
+ static int num; //!< counts the total number of entries
+
+ /// return the command name used to define GROUPDOC_SEC
+ const char *groupDocCmd() const
+ {
+ switch( groupDocType )
+ {
+ case GROUPDOC_NORMAL: return "\\defgroup";
+ case GROUPDOC_ADD: return "\\addgroup";
+ case GROUPDOC_WEAK: return "\\weakgroup";
+ default: return "unknown group command";
+ }
+ }
+ Grouping::GroupPri_t groupingPri() const
+ {
+ if( section != GROUPDOC_SEC )
+ {
+ return Grouping::GROUPING_LOWEST;
+ }
+ switch( groupDocType )
+ {
+ case GROUPDOC_NORMAL: return Grouping::GROUPING_AUTO_DEF;
+ case GROUPDOC_ADD: return Grouping::GROUPING_AUTO_ADD;
+ case GROUPDOC_WEAK: return Grouping::GROUPING_AUTO_WEAK;
+ default: return Grouping::GROUPING_LOWEST;
+ }
+ }
+
+ private:
+ void createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd);
+ Entry *m_parent; //!< parent node in the tree
+ QList<Entry> *m_sublist; //!< entries that are children of this one
+ Entry &operator=(const Entry &);
+};
+
+/** Wrapper for a node in the Entry tree.
+ *
+ * Allows navigating through the Entry tree and load and storing Entry
+ * objects persistently to disk.
+ */
+class EntryNav
+{
+ public:
+ EntryNav(EntryNav *parent,Entry *e);
+ ~EntryNav();
+ void addChild(EntryNav *);
+ bool loadEntry(FileStorage *storage);
+ bool saveEntry(Entry *e,FileStorage *storage);
+ void setEntry(Entry *e);
+ void releaseEntry();
+ void changeSection(int section) { m_section = section; }
+ void setFileDef(FileDef *fd) { m_fileDef = fd; }
+
+ Entry *entry() const { return m_info; }
+ int section() const { return m_section; }
+ SrcLangExt lang() const { return m_lang; }
+ const QCString &type() const { return m_type; }
+ const QCString &name() const { return m_name; }
+ TagInfo *tagInfo() const { return m_tagInfo; }
+ const QList<EntryNav> *children() const { return m_subList; }
+ EntryNav *parent() const { return m_parent; }
+ FileDef *fileDef() const { return m_fileDef; }
+
+ private:
+
+ // navigation
+ EntryNav *m_parent; //!< parent node in the tree
+ QList<EntryNav> *m_subList; //!< entries that are children of this one
+
+ // identification
+ int m_section; //!< entry type (see Sections);
+ QCString m_type; //!< member type
+ QCString m_name; //!< member name
+ TagInfo *m_tagInfo; //!< tag file info
+ FileDef *m_fileDef;
+ SrcLangExt m_lang; //!< programming language in which this entry was found
+
+ Entry *m_info;
+ int64 m_offset;
+ bool m_noLoad;
+};
+
+
+typedef QList<Entry> EntryList;
+typedef QListIterator<Entry> EntryListIterator;
+
+typedef QList<EntryNav> EntryNavList;
+typedef QListIterator<EntryNav> EntryNavListIterator;
+
+#endif
diff --git a/src/example.h b/src/example.h
new file mode 100644
index 0000000..7c86554
--- /dev/null
+++ b/src/example.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
+
+#include <qcstring.h>
+#include "sortdict.h"
+
+class ClassDef;
+class MemberName;
+
+/** Data associated with an example. */
+struct Example
+{
+ QCString anchor;
+ QCString name;
+ QCString file;
+};
+
+/** A sorted dictionary of Example objects. */
+class ExampleSDict : public SDict<Example>
+{
+ public:
+ ExampleSDict(int size=17) : SDict<Example>(size) {}
+ ~ExampleSDict() {}
+ private:
+ int compareValues(const Example *item1,const Example *item2) const
+ {
+ return qstricmp(item1->name,item2->name);
+ }
+};
+
+#endif
diff --git a/src/extsearch.js b/src/extsearch.js
new file mode 100644
index 0000000..920c12b
--- /dev/null
+++ b/src/extsearch.js
@@ -0,0 +1,129 @@
+function SearchBox(name, resultsPath, inFrame, label)
+{
+ this.searchLabel = label;
+ this.DOMSearchField = function()
+ { return document.getElementById("MSearchField"); }
+ this.DOMSearchBox = function()
+ { return document.getElementById("MSearchBox"); }
+ this.OnSearchFieldFocus = function(isActive)
+ {
+ if (isActive)
+ {
+ this.DOMSearchBox().className = 'MSearchBoxActive';
+ var searchField = this.DOMSearchField();
+ if (searchField.value == this.searchLabel)
+ {
+ searchField.value = '';
+ }
+ }
+ else
+ {
+ this.DOMSearchBox().className = 'MSearchBoxInactive';
+ this.DOMSearchField().value = this.searchLabel;
+ }
+ }
+}
+
+function trim(s) {
+ return s?s.replace(/^\s\s*/, '').replace(/\s\s*$/, ''):'';
+}
+
+function getURLParameter(name) {
+ return decodeURIComponent((new RegExp('[?|&]'+name+
+ '='+'([^&;]+?)(&|#|;|$)').exec(location.search)
+ ||[,""])[1].replace(/\+/g, '%20'))||null;
+}
+
+var entityMap = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': '"',
+ "'": ''',
+ "/": '/'
+};
+
+function escapeHtml(s) {
+ return String(s).replace(/[&<>"'\/]/g, function (s) {
+ return entityMap[s];
+ });
+}
+
+function searchFor(query,page,count) {
+ $.getJSON(serverUrl+"?cb=?",
+ {
+ n:count,
+ p:page,
+ q:query
+ },
+ function(data) {
+ var results = $('#searchresults');
+ $('#MSearchField').val(query);
+ if (data.hits>0) {
+ if (data.hits==1) {
+ results.html('<p>'+searchResultsText[1]+'</p>');
+ } else {
+ results.html('<p>'+searchResultsText[2].replace(/\$num/,data.hits)+'</p>');
+ }
+ var r='<table>';
+ $.each(data.items, function(i,item){
+ var prefix = tagMap[item.tag];
+ if (prefix) prefix+='/'; else prefix='';
+ r+='<tr class="searchresult">'+
+ '<td align="right">'+(data.first+i+1)+'.</td>'+
+ '<td>'+escapeHtml(item.type)+' '+
+ '<a href="'+escapeHtml(prefix+item.url)+
+ '">'+escapeHtml(item.name)+'</a>';
+ if (item.type=="source") {
+ var l=item.url.match(/[1-9][0-9]*$/);
+ if (l) r+=' at line '+parseInt(l[0]);
+ }
+ r+='</td>';
+ for (var i=0;i<item.fragments.length;i++)
+ {
+ r+='<tr><td></td><td>'+item.fragments[i]+'</td></tr>';
+ }
+ r+='</tr>';
+ });
+ r+='</table>';
+ if (data.pages>1) // write multi page navigation bar
+ {
+ r+='<div class="searchpages">';
+ if (data.page>0)
+ {
+ r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+(page-1).toString()+','+count.toString()+')">«</a></span> ';
+ }
+ var firstPage = data.page-5;
+ var lastPage = data.page+5;
+ if (firstPage<0)
+ {
+ lastPage-=firstPage;
+ firstPage=0;
+ }
+ if (lastPage>data.pages)
+ {
+ lastPage=data.pages;
+ }
+ for(var i=firstPage;i<lastPage;i++)
+ {
+ if (i==data.page)
+ {
+ r+='<span class="pages"><b>'+(i+1).toString()+'</b></span> ';
+ }
+ else
+ {
+ r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+i.toString()+','+count.toString()+')">'+(i+1).toString()+'</a></span> ';
+ }
+ }
+ if (data.page+1<data.pages)
+ {
+ r+='<span class="pages"><a href="javascript:searchFor(\''+escapeHtml(query)+'\','+(page+1).toString()+','+count.toString()+')">»</a></span>';
+ }
+ r+='</div>';
+ }
+ results.append(r);
+ } else {
+ results.html('<p>'+searchResultsText[0]+'</p>');
+ }
+ });
+}
diff --git a/src/filedef.cpp b/src/filedef.cpp
new file mode 100644
index 0000000..9e8a61c
--- /dev/null
+++ b/src/filedef.cpp
@@ -0,0 +1,1821 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "memberlist.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "doxygen.h"
+#include "memberdef.h"
+#include "classdef.h"
+#include "namespacedef.h"
+#include "util.h"
+#include "language.h"
+#include "outputlist.h"
+#include "dot.h"
+#include "message.h"
+#include "docparser.h"
+#include "searchindex.h"
+#include "htags.h"
+#include "parserintf.h"
+#include "portable.h"
+#include "vhdldocgen.h"
+#include "debug.h"
+#include "layout.h"
+#include "entry.h"
+#include "groupdef.h"
+#include "filename.h"
+#include "membergroup.h"
+#include "dirdef.h"
+#include "config.h"
+#include "clangparser.h"
+#include "settings.h"
+
+//---------------------------------------------------------------------------
+
+/** Class implementing CodeOutputInterface by throwing away everything. */
+class DevNullCodeDocInterface : public CodeOutputInterface
+{
+ public:
+ virtual void codify(const char *) {}
+ virtual void writeCodeLink(const char *,const char *,
+ const char *,const char *,
+ const char *) {}
+ virtual void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ ) {}
+ virtual void writeLineNumber(const char *,const char *,
+ const char *,int) {}
+ virtual void startCodeLine(bool) {}
+ virtual void endCodeLine() {}
+ virtual void startFontClass(const char *) {}
+ virtual void endFontClass() {}
+ virtual void writeCodeAnchor(const char *) {}
+ virtual void linkableSymbol(int, const char *,Definition *,Definition *) {}
+ virtual void setCurrentDoc(Definition *,const char *,bool) {}
+ virtual void addWord(const char *,bool) {}
+};
+
+//---------------------------------------------------------------------------
+
+/*! create a new file definition, where \a p is the file path,
+ \a nm the file name, and \a lref is an HTML anchor name if the
+ file was read from a tag file or 0 otherwise
+*/
+FileDef::FileDef(const char *p,const char *nm,
+ const char *lref,const char *dn)
+ : Definition((QCString)p+nm,1,1,nm)
+{
+ m_path=p;
+ m_filePath=m_path+nm;
+ m_fileName=nm;
+ m_diskName=dn;
+ if (m_diskName.isEmpty()) m_diskName=nm;
+ setReference(lref);
+ m_classSDict = 0;
+ m_includeList = 0;
+ m_includeDict = 0;
+ m_includedByList = 0;
+ m_includedByDict = 0;
+ m_namespaceSDict = 0;
+ m_srcDefDict = 0;
+ m_srcMemberDict = 0;
+ m_usingDirList = 0;
+ m_usingDeclList = 0;
+ m_package = 0;
+ m_isSource = guessSection(nm)==Entry::SOURCE_SEC;
+ m_docname = nm;
+ m_dir = 0;
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ m_docname.prepend(stripFromPath(m_path.copy()));
+ }
+ setLanguage(getLanguageFromFileName(name()));
+ m_memberGroupSDict = 0;
+ acquireFileVersion();
+ m_subGrouping=Config_getBool("SUBGROUPING");
+}
+
+/*! destroy the file definition */
+FileDef::~FileDef()
+{
+ delete m_classSDict;
+ delete m_includeDict;
+ delete m_includeList;
+ delete m_includedByDict;
+ delete m_includedByList;
+ delete m_namespaceSDict;
+ delete m_srcDefDict;
+ delete m_srcMemberDict;
+ delete m_usingDirList;
+ delete m_usingDeclList;
+ delete m_memberGroupSDict;
+}
+
+/*! Compute the HTML anchor names for all members in the class */
+void FileDef::computeAnchors()
+{
+ MemberList *ml = getMemberList(MemberListType_allMembersList);
+ if (ml) setAnchors(ml);
+}
+
+void FileDef::distributeMemberGroupDocumentation()
+{
+ //printf("FileDef::distributeMemberGroupDocumentation()\n");
+ if (m_memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->distributeMemberGroupDocumentation();
+ }
+ }
+}
+
+void FileDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+ if (m_memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ }
+
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ml->findSectionsInDocumentation();
+ }
+ }
+}
+
+bool FileDef::hasDetailedDescription() const
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ return ((!briefDescription().isEmpty() && repeatBrief) ||
+ !documentation().stripWhiteSpace().isEmpty() || // avail empty section
+ (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef())
+ );
+}
+
+void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title)
+{
+ if (hasDetailedDescription())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,"details");
+ ol.popGeneratorState();
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ ol.startTextBlock();
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
+ // ol.newParagraph(); // FIXME:PARA
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.enable(OutputGenerator::Latex);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ }
+ //printf("Writing source ref for file %s\n",name().data());
+ if (Config_getBool("SOURCE_BROWSER"))
+ {
+ ol.startParagraph();
+ QCString refText = theTranslator->trDefinedInSourceFile();
+ int fileMarkerPos = refText.find("@0");
+ if (fileMarkerPos!=-1) // should always pass this.
+ {
+ ol.parseText(refText.left(fileMarkerPos)); //text left from marker 1
+ ol.writeObjectLink(0,getSourceFileBase(),
+ 0,name());
+ ol.parseText(refText.right(
+ refText.length()-fileMarkerPos-2)); // text right from marker 2
+ }
+ ol.endParagraph();
+ }
+ ol.endTextBlock();
+ }
+}
+
+void FileDef::writeBriefDescription(OutputList &ol)
+{
+ if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startParagraph();
+ ol.writeDoc(rootNode,this,0);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+
+ if (Config_getBool("REPEAT_BRIEF") ||
+ !documentation().isEmpty()
+ )
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startTextLink(0,"details");
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ }
+ ol.popGeneratorState();
+ ol.endParagraph();
+ }
+ delete rootNode;
+ }
+ ol.writeSynopsis();
+}
+
+void FileDef::writeIncludeFiles(OutputList &ol)
+{
+ if (m_includeList && m_includeList->count()>0)
+ {
+ ol.startTextBlock(TRUE);
+ QListIterator<IncludeInfo> ili(*m_includeList);
+ IncludeInfo *ii;
+ for (;(ii=ili.current());++ili)
+ {
+ if (!ii->indirect)
+ {
+ FileDef *fd=ii->fileDef;
+ bool isIDLorJava = FALSE;
+ if (fd)
+ {
+ SrcLangExt lang = fd->getLanguage();
+ isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ }
+ ol.startTypewriter();
+ if (isIDLorJava) // IDL/Java include
+ {
+ ol.docify("import ");
+ }
+ else if (ii->imported) // Objective-C include
+ {
+ ol.docify("#import ");
+ }
+ else // C/C++ include
+ {
+ ol.docify("#include ");
+ }
+ if (ii->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify("<");
+ ol.disable(OutputGenerator::Html);
+ ol.docify(ii->includeName);
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ // Here we use the include file name as it appears in the file.
+ // we could also we the name as it is used within doxygen,
+ // then we should have used fd->docName() instead of ii->includeName
+ if (fd && fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),
+ fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
+ 0,ii->includeName);
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fd->isReference())
+ {
+ const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no";
+ const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
+ Doxygen::tagFile << " <includes id=\""
+ << convertToXML(fd->getOutputFileBase()) << "\" "
+ << "name=\"" << convertToXML(fd->name()) << "\" "
+ << "local=\"" << locStr << "\" "
+ << "imported=\"" << impStr << "\">"
+ << convertToXML(ii->includeName)
+ << "</includes>"
+ << endl;
+ }
+ }
+ else
+ {
+ ol.docify(ii->includeName);
+ }
+
+ ol.enableAll();
+ if (ii->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify(">");
+ if (isIDLorJava)
+ ol.docify(";");
+ ol.endTypewriter();
+ ol.lineBreak();
+ }
+ }
+ ol.endTextBlock();
+ }
+}
+
+void FileDef::writeIncludeGraph(OutputList &ol)
+{
+ if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDE_GRAPH")*/)
+ {
+ //printf("Graph for file %s\n",name().data());
+ DotInclDepGraph incDepGraph(this,FALSE);
+ if (incDepGraph.isTooBig())
+ {
+ warn_uncond("Include graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",name().data());
+ }
+ else if (!incDepGraph.isTrivial())
+ {
+ ol.startTextBlock();
+ ol.disable(OutputGenerator::Man);
+ ol.startInclDepGraph();
+ ol.parseText(theTranslator->trInclDepGraph(name()));
+ ol.endInclDepGraph(incDepGraph);
+ ol.enableAll();
+ ol.endTextBlock(TRUE);
+ }
+ //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
+ }
+}
+
+void FileDef::writeIncludedByGraph(OutputList &ol)
+{
+ if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDED_BY_GRAPH")*/)
+ {
+ //printf("Graph for file %s\n",name().data());
+ DotInclDepGraph incDepGraph(this,TRUE);
+ if (incDepGraph.isTooBig())
+ {
+ warn_uncond("Included by graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",name().data());
+ }
+ else if (!incDepGraph.isTrivial())
+ {
+ ol.startTextBlock();
+ ol.disable(OutputGenerator::Man);
+ ol.startInclDepGraph();
+ ol.parseText(theTranslator->trInclByDepGraph());
+ ol.endInclDepGraph(incDepGraph);
+ ol.enableAll();
+ ol.endTextBlock(TRUE);
+ }
+ //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
+ }
+}
+
+
+void FileDef::writeSourceLink(OutputList &ol)
+{
+ //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile());
+ if (generateSourceFile())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startParagraph();
+ ol.startTextLink(includeName(),0);
+ ol.parseText(theTranslator->trGotoSourceCode());
+ ol.endTextLink();
+ ol.endParagraph();
+ ol.enableAll();
+ }
+}
+
+void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title,
+ bool const isConstantGroup)
+{
+ // write list of namespaces
+ if (m_namespaceSDict) m_namespaceSDict->writeDeclaration(ol,title,isConstantGroup);
+}
+
+void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title)
+{
+ // write list of classes
+ if (m_classSDict) m_classSDict->writeDeclaration(ol,0,title,FALSE);
+}
+
+void FileDef::writeInlineClasses(OutputList &ol)
+{
+ // temporarily undo the disbling could be done by startMemberDocumentation()
+ // as a result of setting SEPARATE_MEMBER_PAGES to YES; see bug730512
+ bool isEnabled = ol.isEnabled(OutputGenerator::Html);
+ ol.enable(OutputGenerator::Html);
+
+ if (m_classSDict) m_classSDict->writeDocumentation(ol,this);
+
+ // restore the initial state if needed
+ if (!isEnabled) ol.disable(OutputGenerator::Html);
+}
+
+void FileDef::startMemberDeclarations(OutputList &ol)
+{
+ ol.startMemberSections();
+}
+
+void FileDef::endMemberDeclarations(OutputList &ol)
+{
+ ol.endMemberSections();
+}
+
+void FileDef::startMemberDocumentation(OutputList &ol)
+{
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.disable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = TRUE;
+ }
+}
+
+void FileDef::endMemberDocumentation(OutputList &ol)
+{
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.enable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = FALSE;
+ }
+}
+
+void FileDef::writeMemberGroups(OutputList &ol)
+{
+ /* write user defined member groups */
+ if (m_memberGroupSDict)
+ {
+ m_memberGroupSDict->sort();
+ MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if ((!mg->allMembersInSameSection() || !m_subGrouping)
+ && mg->header()!="[NOHEADER]")
+ {
+ mg->writeDeclarations(ol,0,0,this,0);
+ }
+ }
+ }
+}
+
+void FileDef::writeAuthorSection(OutputList &ol)
+{
+ // write Author section (Man only)
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
+ ol.popGeneratorState();
+}
+
+void FileDef::writeSummaryLinks(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::File));
+ LayoutDocEntry *lde;
+ bool first=TRUE;
+ SrcLangExt lang=getLanguage();
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if ((lde->kind()==LayoutDocEntry::FileClasses &&
+ m_classSDict && m_classSDict->declVisible()) ||
+ (lde->kind()==LayoutDocEntry::FileNamespaces &&
+ m_namespaceSDict && m_namespaceSDict->declVisible())
+ )
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ QCString label = lde->kind()==LayoutDocEntry::FileClasses ? "nested-classes" : "namespaces";
+ ol.writeSummaryLink(0,label,ls->title(lang),first);
+ first=FALSE;
+ }
+ else if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList * ml = getMemberList(lmd->type);
+ if (ml && ml->declVisible())
+ {
+ ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
+ first=FALSE;
+ }
+ }
+ }
+ if (!first)
+ {
+ ol.writeString(" </div>\n");
+ }
+ ol.popGeneratorState();
+}
+
+/*! Write the documentation page for this file to the file of output
+ generators \a ol.
+*/
+void FileDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ //funcList->countDecMembers();
+
+ //QCString fn = name();
+ //if (Config_getBool("FULL_PATH_NAMES"))
+ //{
+ // fn.prepend(stripFromPath(getPath().copy()));
+ //}
+
+ //printf("WriteDocumentation diskname=%s\n",diskname.data());
+
+ QCString versionTitle;
+ if (!m_fileVersion.isEmpty())
+ {
+ versionTitle=("("+m_fileVersion+")");
+ }
+ QCString title = m_docname+versionTitle;
+ QCString pageTitle=theTranslator->trFileReference(m_docname);
+
+ if (getDirDef())
+ {
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
+ if (!generateTreeView)
+ {
+ getDirDef()->writeNavigationPath(ol);
+ ol.endQuickIndices();
+ }
+ QCString pageTitleShort=theTranslator->trFileReference(name());
+ startTitle(ol,getOutputFileBase(),this);
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.parseText(pageTitleShort); // Html only
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ ol.parseText(pageTitle); // other output formats
+ ol.popGeneratorState();
+ addGroupListToTitle(ol,this);
+ endTitle(ol,getOutputFileBase(),title);
+ }
+ else
+ {
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
+ if (!generateTreeView)
+ {
+ ol.endQuickIndices();
+ }
+ startTitle(ol,getOutputFileBase(),this);
+ ol.parseText(pageTitle);
+ addGroupListToTitle(ol,this);
+ endTitle(ol,getOutputFileBase(),title);
+ }
+
+ ol.startContents();
+
+ if (!m_fileVersion.isEmpty())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startProjectNumber();
+ ol.docify(versionTitle);
+ ol.endProjectNumber();
+ ol.enableAll();
+ }
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ }
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"file\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl;
+ Doxygen::tagFile << " <filename>"
+ << convertToXML(getOutputFileBase())
+ << "</filename>" << endl;
+ }
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang = getLanguage();
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::File));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::FileIncludes:
+ writeIncludeFiles(ol);
+ break;
+ case LayoutDocEntry::FileIncludeGraph:
+ writeIncludeGraph(ol);
+ break;
+ case LayoutDocEntry::FileIncludedByGraph:
+ writeIncludedByGraph(ol);
+ break;
+ case LayoutDocEntry::FileSourceLink:
+ writeSourceLink(ol);
+ break;
+ case LayoutDocEntry::FileClasses:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeClassDeclarations(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::FileNamespaces:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNamespaceDeclarations(ol,ls->title(lang),false);
+ }
+ break;
+ case LayoutDocEntry::FileConstantGroups:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNamespaceDeclarations(ol,ls->title(lang),true);
+ }
+ break;
+ case LayoutDocEntry::MemberGroups:
+ writeMemberGroups(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::FileInlineClasses:
+ writeInlineClasses(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ endMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ case LayoutDocEntry::ClassInheritanceGraph:
+ case LayoutDocEntry::ClassNestedClasses:
+ case LayoutDocEntry::ClassCollaborationGraph:
+ case LayoutDocEntry::ClassAllMembersLink:
+ case LayoutDocEntry::ClassUsedFiles:
+ case LayoutDocEntry::ClassInlineClasses:
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::File entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ //---------------------------------------- end flexible part -------------------------------
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+
+ ol.endContents();
+
+ endFileWithNavPath(this,ol);
+
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ MemberList *ml = getMemberList(MemberListType_allMembersList);
+ if (ml) ml->sort();
+ writeMemberPages(ol);
+ }
+}
+
+void FileDef::writeMemberPages(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->writeDocumentationPage(ol,name(),this);
+ }
+ }
+
+ ol.popGeneratorState();
+}
+
+void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
+{
+ static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
+
+ ol.writeString(" <div class=\"navtab\">\n");
+ ol.writeString(" <table>\n");
+
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList)
+ {
+ MemberListIterator mli(*allMemberList);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->getFileDef()==this && md->getNamespaceDef()==0 && md->isLinkable() && !md->isEnumValue())
+ {
+ ol.writeString(" <tr><td class=\"navtab\">");
+ if (md->isLinkableInProject())
+ {
+ if (md==currentMd) // selected item => highlight
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ ol.writeString("href=\"");
+ if (createSubDirs) ol.writeString("../../");
+ ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
+ ol.writeString("\">");
+ ol.writeString(convertToHtml(md->localName()));
+ ol.writeString("</a>");
+ }
+ ol.writeString("</td></tr>\n");
+ }
+ }
+ }
+
+ ol.writeString(" </table>\n");
+ ol.writeString(" </div>\n");
+}
+
+/*! Write a source listing of this file to the output */
+void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
+ static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
+ DevNullCodeDocInterface devNullIntf;
+ QCString title = m_docname;
+ if (!m_fileVersion.isEmpty())
+ {
+ title+=(" ("+m_fileVersion+")");
+ }
+ QCString pageTitle = theTranslator->trSourceFile(title);
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
+ if (!latexSourceCode) ol.disable(OutputGenerator::Latex);
+
+ bool isDocFile = isDocumentationFile();
+ bool genSourceFile = !isDocFile && generateSourceFile();
+ if (getDirDef())
+ {
+ startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,
+ !generateTreeView,
+ !isDocFile && genSourceFile ? QCString() : getOutputFileBase());
+ if (!generateTreeView)
+ {
+ getDirDef()->writeNavigationPath(ol);
+ ol.endQuickIndices();
+ }
+ startTitle(ol,getSourceFileBase());
+ ol.parseText(name());
+ endTitle(ol,getSourceFileBase(),title);
+ }
+ else
+ {
+ startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,FALSE,
+ !isDocFile && genSourceFile ? QCString() : getOutputFileBase());
+ startTitle(ol,getSourceFileBase());
+ ol.parseText(title);
+ endTitle(ol,getSourceFileBase(),0);
+ }
+
+ ol.startContents();
+
+ if (isLinkable())
+ {
+ if (latexSourceCode) ol.disable(OutputGenerator::Latex);
+ ol.startTextLink(getOutputFileBase(),0);
+ ol.parseText(theTranslator->trGotoDocumentation());
+ ol.endTextLink();
+ if (latexSourceCode) ol.enable(OutputGenerator::Latex);
+ }
+
+ (void)sameTu;
+ (void)filesInSameTu;
+#if USE_LIBCLANG
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (clangAssistedParsing &&
+ (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
+ {
+ ol.startCodeFragment();
+ if (!sameTu)
+ {
+ ClangParser::instance()->start(absFilePath(),filesInSameTu);
+ }
+ else
+ {
+ ClangParser::instance()->switchToFile(absFilePath());
+ }
+ ClangParser::instance()->writeSources(ol,this);
+ ol.endCodeFragment();
+ }
+ else
+#endif
+ {
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
+ pIntf->resetCodeParserState();
+ ol.startCodeFragment();
+ bool needs2PassParsing =
+ Doxygen::parseSourcesNeeded && // we need to parse (filtered) sources for cross-references
+ !filterSourceFiles && // but user wants to show sources as-is
+ !getFileFilter(absFilePath(),TRUE).isEmpty(); // and there is a filter used while parsing
+
+ if (needs2PassParsing)
+ {
+ // parse code for cross-references only (see bug707641)
+ pIntf->parseCode(devNullIntf,0,
+ fileToString(absFilePath(),TRUE,TRUE),
+ getLanguage(),
+ FALSE,0,this
+ );
+ }
+ pIntf->parseCode(ol,0,
+ fileToString(absFilePath(),filterSourceFiles,TRUE),
+ getLanguage(), // lang
+ FALSE, // isExampleBlock
+ 0, // exampleName
+ this, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inlineFragment
+ 0, // memberDef
+ TRUE, // showLineNumbers
+ 0, // searchCtx
+ !needs2PassParsing // collectXRefs
+ );
+ ol.endCodeFragment();
+ }
+ ol.endContents();
+ endFileWithNavPath(this,ol);
+ ol.enableAll();
+}
+
+void FileDef::parseSource(bool sameTu,QStrList &filesInSameTu)
+{
+ static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
+ DevNullCodeDocInterface devNullIntf;
+ (void)sameTu;
+ (void)filesInSameTu;
+#if USE_LIBCLANG
+ static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
+ if (clangAssistedParsing &&
+ (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
+ {
+ if (!sameTu)
+ {
+ ClangParser::instance()->start(absFilePath(),filesInSameTu);
+ }
+ else
+ {
+ ClangParser::instance()->switchToFile(absFilePath());
+ }
+ ClangParser::instance()->writeSources(devNullIntf,this);
+ }
+ else
+#endif
+ {
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
+ pIntf->resetCodeParserState();
+ pIntf->parseCode(
+ devNullIntf,0,
+ fileToString(absFilePath(),filterSourceFiles,TRUE),
+ getLanguage(),
+ FALSE,0,this
+ );
+ }
+}
+
+void FileDef::startParsing()
+{
+}
+
+void FileDef::finishParsing()
+{
+ ClangParser::instance()->finish();
+}
+
+void FileDef::addMembersToMemberGroup()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ::addMembersToMemberGroup(ml,&m_memberGroupSDict,this);
+ }
+ }
+
+ // add members inside sections to their groups
+ if (m_memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (mg->allMembersInSameSection() && m_subGrouping)
+ {
+ //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
+ mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+/*! Adds member definition \a md to the list of all members of this file */
+void FileDef::insertMember(MemberDef *md)
+{
+ if (md->isHidden()) return;
+ //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n",
+ // name().data(),md->name().data(),md,allMemberList.count());
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef!
+ {
+ return;
+ }
+
+ if (allMemberList==0)
+ {
+ allMemberList = new MemberList(MemberListType_allMembersList);
+ m_memberLists.append(allMemberList);
+ }
+ allMemberList->append(md);
+ //::addFileMemberNameToIndex(md);
+ switch (md->memberType())
+ {
+ case MemberType_Variable:
+ case MemberType_Property:
+ addMemberToList(MemberListType_decVarMembers,md);
+ addMemberToList(MemberListType_docVarMembers,md);
+ break;
+ case MemberType_Function:
+ addMemberToList(MemberListType_decFuncMembers,md);
+ addMemberToList(MemberListType_docFuncMembers,md);
+ break;
+ case MemberType_Typedef:
+ addMemberToList(MemberListType_decTypedefMembers,md);
+ addMemberToList(MemberListType_docTypedefMembers,md);
+ break;
+ case MemberType_Enumeration:
+ addMemberToList(MemberListType_decEnumMembers,md);
+ addMemberToList(MemberListType_docEnumMembers,md);
+ break;
+ case MemberType_EnumValue: // enum values are shown inside their enums
+ break;
+ case MemberType_Define:
+ addMemberToList(MemberListType_decDefineMembers,md);
+ addMemberToList(MemberListType_docDefineMembers,md);
+ break;
+ default:
+ err("FileDef::insertMembers(): "
+ "member `%s' with class scope `%s' inserted in file scope `%s'!\n",
+ md->name().data(),
+ md->getClassDef() ? md->getClassDef()->name().data() : "<global>",
+ name().data());
+ }
+ //addMemberToGroup(md,groupId);
+}
+
+/*! Adds compound definition \a cd to the list of all compounds of this file */
+void FileDef::insertClass(ClassDef *cd)
+{
+ if (cd->isHidden()) return;
+ if (m_classSDict==0)
+ {
+ m_classSDict = new ClassSDict(17);
+ }
+ if (Config_getBool("SORT_BRIEF_DOCS"))
+ {
+ m_classSDict->inSort(cd->name(),cd);
+ }
+ else
+ {
+ m_classSDict->append(cd->name(),cd);
+ }
+}
+
+/*! Adds namespace definition \a nd to the list of all compounds of this file */
+void FileDef::insertNamespace(NamespaceDef *nd)
+{
+ if (nd->isHidden()) return;
+ if (!nd->name().isEmpty() &&
+ (m_namespaceSDict==0 || m_namespaceSDict->find(nd->name())==0))
+ {
+ if (m_namespaceSDict==0)
+ {
+ m_namespaceSDict = new NamespaceSDict;
+ }
+ if (Config_getBool("SORT_BRIEF_DOCS"))
+ {
+ m_namespaceSDict->inSort(nd->name(),nd);
+ }
+ else
+ {
+ m_namespaceSDict->append(nd->name(),nd);
+ }
+ }
+}
+
+QCString FileDef::name() const
+{
+ if (Config_getBool("FULL_PATH_NAMES"))
+ return m_fileName;
+ else
+ return Definition::name();
+}
+
+void FileDef::addSourceRef(int line,Definition *d,MemberDef *md)
+{
+ //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md);
+ if (d)
+ {
+ if (m_srcDefDict==0) m_srcDefDict = new QIntDict<Definition>(257);
+ if (m_srcMemberDict==0) m_srcMemberDict = new QIntDict<MemberDef>(257);
+ m_srcDefDict->insert(line,d);
+ if (md) m_srcMemberDict->insert(line,md);
+ //printf("Adding member %s with anchor %s at line %d to file %s\n",
+ // md?md->name().data():"<none>",md?md->anchor().data():"<none>",line,name().data());
+ }
+}
+
+Definition *FileDef::getSourceDefinition(int lineNr) const
+{
+ Definition *result=0;
+ if (m_srcDefDict)
+ {
+ result = m_srcDefDict->find(lineNr);
+ }
+ //printf("%s::getSourceDefinition(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
+ return result;
+}
+
+MemberDef *FileDef::getSourceMember(int lineNr) const
+{
+ MemberDef *result=0;
+ if (m_srcMemberDict)
+ {
+ result = m_srcMemberDict->find(lineNr);
+ }
+ //printf("%s::getSourceMember(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
+ return result;
+}
+
+
+void FileDef::addUsingDirective(NamespaceDef *nd)
+{
+ if (m_usingDirList==0)
+ {
+ m_usingDirList = new NamespaceSDict;
+ }
+ if (m_usingDirList->find(nd->qualifiedName())==0)
+ {
+ m_usingDirList->append(nd->qualifiedName(),nd);
+ }
+ //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
+}
+
+NamespaceSDict *FileDef::getUsedNamespaces() const
+{
+ //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
+ return m_usingDirList;
+}
+
+void FileDef::addUsingDeclaration(Definition *d)
+{
+ if (m_usingDeclList==0)
+ {
+ m_usingDeclList = new SDict<Definition>(17);
+ }
+ if (m_usingDeclList->find(d->qualifiedName())==0)
+ {
+ m_usingDeclList->append(d->qualifiedName(),d);
+ }
+}
+
+void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local,
+ bool imported,bool indirect)
+{
+ //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local);
+ QCString iName = fd ? fd->absFilePath().data() : incName;
+ if (!iName.isEmpty() && (!m_includeDict || m_includeDict->find(iName)==0))
+ {
+ if (m_includeDict==0)
+ {
+ m_includeDict = new QDict<IncludeInfo>(61);
+ m_includeList = new QList<IncludeInfo>;
+ m_includeList->setAutoDelete(TRUE);
+ }
+ IncludeInfo *ii = new IncludeInfo;
+ ii->fileDef = fd;
+ ii->includeName = incName;
+ ii->local = local;
+ ii->imported = imported;
+ ii->indirect = indirect;
+ m_includeList->append(ii);
+ m_includeDict->insert(iName,ii);
+ }
+}
+
+void FileDef::addIncludedUsingDirectives()
+{
+ if (visited) return;
+ visited=TRUE;
+ //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data());
+
+ NamespaceList nl;
+ if (m_includeList) // file contains #includes
+ {
+ {
+ QListIterator<IncludeInfo> iii(*m_includeList);
+ IncludeInfo *ii;
+ for (iii.toFirst();(ii=iii.current());++iii) // foreach #include...
+ {
+ if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file
+ {
+ // recurse into this file
+ ii->fileDef->addIncludedUsingDirectives();
+ }
+ }
+ }
+ {
+ QListIterator<IncludeInfo> iii(*m_includeList);
+ IncludeInfo *ii;
+ // iterate through list from last to first
+ for (iii.toLast();(ii=iii.current());--iii)
+ {
+ if (ii->fileDef && ii->fileDef!=this)
+ {
+ // add using directives
+ NamespaceSDict *unl = ii->fileDef->m_usingDirList;
+ if (unl)
+ {
+ NamespaceSDict::Iterator nli(*unl);
+ NamespaceDef *nd;
+ for (nli.toLast();(nd=nli.current());--nli)
+ {
+ // append each using directive found in a #include file
+ if (m_usingDirList==0) m_usingDirList = new NamespaceSDict;
+ //printf("Prepending used namespace %s to the list of file %s\n",
+ // nd->name().data(),name().data());
+ if (m_usingDirList->find(nd->qualifiedName())==0) // not yet added
+ {
+ m_usingDirList->prepend(nd->qualifiedName(),nd);
+ }
+ }
+ }
+ // add using declarations
+ SDict<Definition> *udl = ii->fileDef->m_usingDeclList;
+ if (udl)
+ {
+ SDict<Definition>::Iterator udi(*udl);
+ Definition *d;
+ for (udi.toLast();(d=udi.current());--udi)
+ {
+ //printf("Adding using declaration %s\n",d->name().data());
+ if (m_usingDeclList==0)
+ {
+ m_usingDeclList = new SDict<Definition>(17);
+ }
+ if (m_usingDeclList->find(d->qualifiedName())==0)
+ {
+ m_usingDeclList->prepend(d->qualifiedName(),d);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data());
+}
+
+
+void FileDef::addIncludedByDependency(FileDef *fd,const char *incName,
+ bool local,bool imported)
+{
+ //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local);
+ QCString iName = fd ? fd->absFilePath().data() : incName;
+ if (!iName.isEmpty() && (m_includedByDict==0 || m_includedByDict->find(iName)==0))
+ {
+ if (m_includedByDict==0)
+ {
+ m_includedByDict = new QDict<IncludeInfo>(61);
+ m_includedByList = new QList<IncludeInfo>;
+ m_includedByList->setAutoDelete(TRUE);
+ }
+ IncludeInfo *ii = new IncludeInfo;
+ ii->fileDef = fd;
+ ii->includeName = incName;
+ ii->local = local;
+ ii->imported = imported;
+ ii->indirect = FALSE;
+ m_includedByList->append(ii);
+ m_includedByDict->insert(iName,ii);
+ }
+}
+
+bool FileDef::isIncluded(const QCString &name) const
+{
+ if (name.isEmpty()) return FALSE;
+ return m_includeDict!=0 && m_includeDict->find(name)!=0;
+}
+
+bool FileDef::generateSourceFile() const
+{
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ static bool verbatimHeaders = Config_getBool("VERBATIM_HEADERS");
+ QCString extension = name().right(4);
+ return !isReference() &&
+ (sourceBrowser ||
+ (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC)
+ ) &&
+ extension!=".doc" && extension!=".txt" && extension!=".dox" &&
+ extension!=".md" && name().right(9)!=".markdown";
+}
+
+
+void FileDef::addListReferences()
+{
+ {
+ QList<ListItemInfo> *xrefItems = xrefListItems();
+ addRefItem(xrefItems,
+ getOutputFileBase(),
+ theTranslator->trFile(TRUE,TRUE),
+ getOutputFileBase(),name(),
+ 0
+ );
+ }
+ if (m_memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(this);
+ }
+ }
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->addListReferences(this);
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+static int findMatchingPart(const QCString &path,const QCString dir)
+{
+ int si1;
+ int pos1=0,pos2=0;
+ while ((si1=path.find('/',pos1))!=-1)
+ {
+ int si2=dir.find('/',pos2);
+ //printf(" found slash at pos %d in path %d: %s<->%s\n",si1,si2,
+ // path.mid(pos1,si1-pos2).data(),dir.mid(pos2).data());
+ if (si2==-1 && path.mid(pos1,si1-pos2)==dir.mid(pos2)) // match at end
+ {
+ return dir.length();
+ }
+ if (si1!=si2 || path.mid(pos1,si1-pos2)!=dir.mid(pos2,si2-pos2)) // no match in middle
+ {
+ return QMAX(pos1-1,0);
+ }
+ pos1=si1+1;
+ pos2=si2+1;
+ }
+ return 0;
+}
+
+static Directory *findDirNode(Directory *root,const QCString &name)
+{
+ QListIterator<DirEntry> dli(root->children());
+ DirEntry *de;
+ for (dli.toFirst();(de=dli.current());++dli)
+ {
+ if (de->kind()==DirEntry::Dir)
+ {
+ Directory *dir = (Directory *)de;
+ QCString dirName=dir->name();
+ int sp=findMatchingPart(name,dirName);
+ //printf("findMatchingPart(%s,%s)=%d\n",name.data(),dirName.data(),sp);
+ if (sp>0) // match found
+ {
+ if ((uint)sp==dirName.length()) // whole directory matches
+ {
+ // recurse into the directory
+ return findDirNode(dir,name.mid(dirName.length()+1));
+ }
+ else // partial match => we need to split the path into three parts
+ {
+ QCString baseName =dirName.left(sp);
+ QCString oldBranchName=dirName.mid(sp+1);
+ QCString newBranchName=name.mid(sp+1);
+ // strip file name from path
+ int newIndex=newBranchName.findRev('/');
+ if (newIndex>0) newBranchName=newBranchName.left(newIndex);
+
+ //printf("Splitting off part in new branch \n"
+ // "base=%s old=%s new=%s\n",
+ // baseName.data(),
+ // oldBranchName.data(),
+ // newBranchName.data()
+ // );
+ Directory *base = new Directory(root,baseName);
+ Directory *newBranch = new Directory(base,newBranchName);
+ dir->reParent(base);
+ dir->rename(oldBranchName);
+ base->addChild(dir);
+ base->addChild(newBranch);
+ dir->setLast(FALSE);
+ // remove DirEntry container from list (without deleting it)
+ root->children().setAutoDelete(FALSE);
+ root->children().removeRef(dir);
+ root->children().setAutoDelete(TRUE);
+ // add new branch to the root
+ if (!root->children().isEmpty())
+ {
+ root->children().getLast()->setLast(FALSE);
+ }
+ root->addChild(base);
+ return newBranch;
+ }
+ }
+ }
+ }
+ int si=name.findRev('/');
+ if (si==-1) // no subdir
+ {
+ return root; // put the file under the root node.
+ }
+ else // need to create a subdir
+ {
+ QCString baseName = name.left(si);
+ //printf("new subdir %s\n",baseName.data());
+ Directory *newBranch = new Directory(root,baseName);
+ if (!root->children().isEmpty())
+ {
+ root->children().getLast()->setLast(FALSE);
+ }
+ root->addChild(newBranch);
+ return newBranch;
+ }
+}
+
+static void mergeFileDef(Directory *root,FileDef *fd)
+{
+ QCString rootPath = root->name();
+ QCString filePath = fd->absFilePath();
+ //printf("merging %s\n",filePath.data());
+ Directory *dirNode = findDirNode(root,filePath);
+ if (!dirNode->children().isEmpty())
+ {
+ dirNode->children().getLast()->setLast(FALSE);
+ }
+ DirEntry *e=new DirEntry(dirNode,fd);
+ dirNode->addChild(e);
+}
+
+#if 0
+static void generateIndent(QTextStream &t,DirEntry *de,int level)
+{
+ if (de->parent())
+ {
+ generateIndent(t,de->parent(),level+1);
+ }
+ // from the root up to node n do...
+ if (level==0) // item before a dir or document
+ {
+ if (de->isLast())
+ {
+ if (de->kind()==DirEntry::Dir)
+ {
+ t << "<img " << FTV_IMGATTRIBS(plastnode) << "/>";
+ }
+ else
+ {
+ t << "<img " << FTV_IMGATTRIBS(lastnode) << "/>";
+ }
+ }
+ else
+ {
+ if (de->kind()==DirEntry::Dir)
+ {
+ t << "<img " << FTV_IMGATTRIBS(pnode) << "/>";
+ }
+ else
+ {
+ t << "<img " << FTV_IMGATTRIBS(node) << "/>";
+ }
+ }
+ }
+ else // item at another level
+ {
+ if (de->isLast())
+ {
+ t << "<img " << FTV_IMGATTRIBS(blank) << "/>";
+ }
+ else
+ {
+ t << "<img " << FTV_IMGATTRIBS(vertline) << "/>";
+ }
+ }
+}
+
+static void writeDirTreeNode(QTextStream &t,Directory *root,int level)
+{
+ QCString indent;
+ indent.fill(' ',level*2);
+ QListIterator<DirEntry> dli(root->children());
+ DirEntry *de;
+ for (dli.toFirst();(de=dli.current());++dli)
+ {
+ t << indent << "<p>";
+ generateIndent(t,de,0);
+ if (de->kind()==DirEntry::Dir)
+ {
+ Directory *dir=(Directory *)de;
+ //printf("%s [dir]: %s (last=%d,dir=%d)\n",indent.data(),dir->name().data(),dir->isLast(),dir->kind()==DirEntry::Dir);
+ t << "<img " << FTV_IMGATTRIBS(folderclosed) << "/>";
+ t << dir->name();
+ t << "</p>\n";
+ t << indent << "<div>\n";
+ writeDirTreeNode(t,dir,level+1);
+ t << indent << "</div>\n";
+ }
+ else
+ {
+ //printf("%s [file]: %s (last=%d,dir=%d)\n",indent.data(),de->file()->name().data(),de->isLast(),de->kind()==DirEntry::Dir);
+ t << "<img " << FTV_IMGATTRIBS(doc) << "/>";
+ t << de->file()->name();
+ t << "</p>\n";
+ }
+ }
+}
+#endif
+
+static void addDirsAsGroups(Directory *root,GroupDef *parent,int level)
+{
+ GroupDef *gd=0;
+ if (root->kind()==DirEntry::Dir)
+ {
+ gd = new GroupDef("[generated]",
+ 1,
+ root->path(), // name
+ root->name() // title
+ );
+ if (parent)
+ {
+ parent->addGroup(gd);
+ gd->makePartOfGroup(parent);
+ }
+ else
+ {
+ Doxygen::groupSDict->append(root->path(),gd);
+ }
+ }
+ QListIterator<DirEntry> dli(root->children());
+ DirEntry *de;
+ for (dli.toFirst();(de=dli.current());++dli)
+ {
+ if (de->kind()==DirEntry::Dir)
+ {
+ addDirsAsGroups((Directory *)de,gd,level+1);
+ }
+ }
+}
+
+void generateFileTree()
+{
+ Directory *root=new Directory(0,"root");
+ root->setLast(TRUE);
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ mergeFileDef(root,fd);
+ }
+ }
+ //t << "<div class=\"directory\">\n";
+ //writeDirTreeNode(t,root,0);
+ //t << "</div>\n";
+ addDirsAsGroups(root,0,0);
+ delete root;
+}
+
+//-------------------------------------------------------------------
+
+void FileDef::combineUsingRelations()
+{
+ if (visited) return; // already done
+ visited=TRUE;
+ if (m_usingDirList)
+ {
+ NamespaceSDict::Iterator nli(*m_usingDirList);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ nd->combineUsingRelations();
+ }
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ // add used namespaces of namespace nd to this namespace
+ if (nd->getUsedNamespaces())
+ {
+ NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
+ NamespaceDef *und;
+ for (unli.toFirst();(und=unli.current());++unli)
+ {
+ //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
+ addUsingDirective(und);
+ }
+ }
+ // add used classes of namespace nd to this namespace
+ if (nd->getUsedClasses())
+ {
+ SDict<Definition>::Iterator cli(*nd->getUsedClasses());
+ Definition *ucd;
+ for (cli.toFirst();(ucd=cli.current());++cli)
+ {
+ //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
+ addUsingDeclaration(ucd);
+ }
+ }
+ }
+ }
+}
+
+bool FileDef::isDocumentationFile() const
+{
+ return name().right(4)==".doc" ||
+ name().right(4)==".txt" ||
+ name().right(4)==".dox" ||
+ name().right(3)==".md" ||
+ name().right(9)==".markdown";
+}
+
+void FileDef::acquireFileVersion()
+{
+ QCString vercmd = Config_getString("FILE_VERSION_FILTER");
+ if (!vercmd.isEmpty() && !m_filePath.isEmpty() && m_filePath!="generated")
+ {
+ msg("Version of %s : ",m_filePath.data());
+ QCString cmd = vercmd+" \""+m_filePath+"\"";
+ Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
+ FILE *f=portable_popen(cmd,"r");
+ if (!f)
+ {
+ err("could not execute %s\n",vercmd.data());
+ return;
+ }
+ const int bufSize=1024;
+ char buf[bufSize];
+ int numRead = (int)fread(buf,1,bufSize,f);
+ portable_pclose(f);
+ if (numRead>0 && !(m_fileVersion=QCString(buf,numRead).stripWhiteSpace()).isEmpty())
+ {
+ msg("%s\n",m_fileVersion.data());
+ }
+ else
+ {
+ msg("no version available\n");
+ }
+ }
+}
+
+
+QCString FileDef::getSourceFileBase() const
+{
+ if (Htags::useHtags)
+ {
+ return Htags::path2URL(m_filePath);
+ }
+ else
+ {
+ return convertNameToFile(m_diskName)+"_source";
+ }
+}
+
+/*! Returns the name of the verbatim copy of this file (if any). */
+QCString FileDef::includeName() const
+{
+ return getSourceFileBase();
+}
+
+MemberList *FileDef::createMemberList(MemberListType lt)
+{
+ m_memberLists.setAutoDelete(TRUE);
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ // not found, create a new member list
+ ml = new MemberList(lt);
+ m_memberLists.append(ml);
+ return ml;
+}
+
+void FileDef::addMemberToList(MemberListType lt,MemberDef *md)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
+ MemberList *ml = createMemberList(lt);
+ ml->setNeedsSorting(
+ ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
+ ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
+ ml->append(md);
+#if 0
+ if (ml->needsSorting())
+ ml->inSort(md);
+ else
+ ml->append(md);
+#endif
+ if (lt&MemberListType_documentationLists)
+ {
+ ml->setInFile(TRUE);
+ }
+ if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml);
+}
+
+void FileDef::sortMemberLists()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
+ }
+}
+
+MemberList *FileDef::getMemberList(MemberListType lt) const
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ return 0;
+}
+
+void FileDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ MemberList * ml = getMemberList(lt);
+ if (ml)
+ {
+ if (optVhdl) // use specific declarations function
+ {
+
+ VhdlDocGen::writeVhdlDeclarations(ml,ol,0,0,this,0);
+ }
+ else
+ {
+ ml->writeDeclarations(ol,0,0,this,0,title,0,definitionType());
+ }
+ }
+}
+
+void FileDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDocumentation(ol,name(),this,title);
+}
+
+bool FileDef::isLinkableInProject() const
+{
+ static bool showFiles = Config_getBool("SHOW_FILES");
+ return hasDocumentation() && !isReference() && showFiles;
+}
+
+static void getAllIncludeFilesRecursively(
+ QDict<void> *filesVisited,const FileDef *fd,QStrList &incFiles)
+{
+ if (fd->includeFileList())
+ {
+ QListIterator<IncludeInfo> iii(*fd->includeFileList());
+ IncludeInfo *ii;
+ for (iii.toFirst();(ii=iii.current());++iii)
+ {
+ if (ii->fileDef && !ii->fileDef->isReference() &&
+ !filesVisited->find(ii->fileDef->absFilePath()))
+ {
+ //printf("FileDef::addIncludeDependency(%s)\n",ii->fileDef->absFilePath().data());
+ incFiles.append(ii->fileDef->absFilePath());
+ filesVisited->insert(ii->fileDef->absFilePath(),(void*)0x8);
+ getAllIncludeFilesRecursively(filesVisited,ii->fileDef,incFiles);
+ }
+ }
+ }
+}
+
+void FileDef::getAllIncludeFilesRecursively(QStrList &incFiles) const
+{
+ QDict<void> includes(257);
+ ::getAllIncludeFilesRecursively(&includes,this,incFiles);
+}
+
+QCString FileDef::title() const
+{
+ return theTranslator->trFileReference(name());
+}
+
+QCString FileDef::fileVersion() const
+{
+ return m_fileVersion;
+}
diff --git a/src/filedef.h b/src/filedef.h
new file mode 100644
index 0000000..a95cd77
--- /dev/null
+++ b/src/filedef.h
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef FILEDEF_H
+#define FILEDEF_H
+
+#include "index.h"
+#include <qlist.h>
+#include <qintdict.h>
+#include <qdict.h>
+#include "definition.h"
+#include "sortdict.h"
+#include "memberlist.h"
+
+class MemberList;
+class FileDef;
+class FileList;
+class ClassSDict;
+class ClassDef;
+class ClassList;
+class MemberDef;
+class OutputList;
+class NamespaceDef;
+class NamespaceSDict;
+class MemberGroupSDict;
+class PackageDef;
+class DirDef;
+
+/** Class representing the data associated with a \#include statement. */
+struct IncludeInfo
+{
+ IncludeInfo() { fileDef=0; local=FALSE; indirect=FALSE; }
+ ~IncludeInfo() {}
+ FileDef *fileDef;
+ QCString includeName;
+ bool local;
+ bool imported;
+ bool indirect;
+};
+
+/** A model of a file symbol.
+ *
+ * An object of this class contains all file information that is gathered.
+ * This includes the members and compounds defined in the file.
+ *
+ * The member writeDocumentation() can be used to generate the page of
+ * documentation to HTML and LaTeX.
+ */
+class FileDef : public Definition
+{
+ friend class FileName;
+
+ public:
+ //enum FileType { Source, Header, Unknown };
+
+ FileDef(const char *p,const char *n,const char *ref=0,const char *dn=0);
+ ~FileDef();
+
+ // ----------------------------------------------------------------------
+
+ DefType definitionType() const { return TypeFile; }
+
+ /*! Returns the unique file name (this may include part of the path). */
+ QCString name() const;
+ QCString displayName(bool=TRUE) const { return name(); }
+ QCString fileName() const { return m_fileName; }
+
+ QCString getOutputFileBase() const
+ { return convertNameToFile(m_diskName); }
+
+ QCString anchor() const { return QCString(); }
+
+ QCString getFileBase() const { return m_diskName; }
+
+ QCString getSourceFileBase() const;
+
+ /*! Returns the name of the verbatim copy of this file (if any). */
+ QCString includeName() const;
+
+ /*! Returns the absolute path including the file name. */
+ QCString absFilePath() const { return m_filePath; }
+
+ /*! Returns the name as it is used in the documentation */
+ QCString docName() const { return m_docname; }
+
+ /*! Returns TRUE if this file is a source file. */
+ bool isSource() const { return m_isSource; }
+
+ bool isDocumentationFile() const;
+
+ Definition *getSourceDefinition(int lineNr) const;
+ MemberDef *getSourceMember(int lineNr) const;
+
+ /*! Returns the absolute path of this file. */
+ QCString getPath() const { return m_path; }
+
+ /*! Returns version of this file. */
+ QCString getVersion() const { return m_fileVersion; }
+
+ bool isLinkableInProject() const;
+
+ bool isLinkable() const { return isLinkableInProject() || isReference(); }
+ bool isIncluded(const QCString &name) const;
+
+ PackageDef *packageDef() const { return m_package; }
+ DirDef *getDirDef() const { return m_dir; }
+ NamespaceSDict *getUsedNamespaces() const;
+ SDict<Definition> *getUsedClasses() const { return m_usingDeclList; }
+ QList<IncludeInfo> *includeFileList() const { return m_includeList; }
+ QList<IncludeInfo> *includedByFileList() const { return m_includedByList; }
+ void getAllIncludeFilesRecursively(QStrList &incFiles) const;
+
+ MemberList *getMemberList(MemberListType lt) const;
+ const QList<MemberList> &getMemberLists() const { return m_memberLists; }
+
+ /* user defined member groups */
+ MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; }
+ NamespaceSDict *getNamespaceSDict() const { return m_namespaceSDict; }
+ ClassSDict *getClassSDict() const { return m_classSDict; }
+
+ QCString title() const;
+ bool hasDetailedDescription() const;
+ QCString fileVersion() const;
+
+ bool subGrouping() const { return m_subGrouping; }
+
+ //---------------------------------
+
+ void addSourceRef(int line,Definition *d,MemberDef *md);
+
+ void writeDocumentation(OutputList &ol);
+ void writeMemberPages(OutputList &ol);
+ void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const;
+ void writeSummaryLinks(OutputList &ol);
+
+ void startParsing();
+ void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu);
+ void parseSource(bool sameTu,QStrList &filesInSameTu);
+ void finishParsing();
+
+ friend void generatedFileNames();
+ void insertMember(MemberDef *md);
+ void insertClass(ClassDef *cd);
+ void insertNamespace(NamespaceDef *nd);
+ void computeAnchors();
+
+ void setPackageDef(PackageDef *pd) { m_package=pd; }
+ void setDirDef(DirDef *dd) { m_dir=dd; }
+
+ void addUsingDirective(NamespaceDef *nd);
+ void addUsingDeclaration(Definition *def);
+ void combineUsingRelations();
+
+ bool generateSourceFile() const;
+ void sortMemberLists();
+
+ void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect);
+ void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported);
+
+ void addMembersToMemberGroup();
+ void distributeMemberGroupDocumentation();
+ void findSectionsInDocumentation();
+ void addIncludedUsingDirectives();
+
+ void addListReferences();
+ //bool includes(FileDef *incFile,QDict<FileDef> *includedFiles) const;
+ //bool includesByName(const QCString &name) const;
+ bool visited;
+
+ protected:
+ /**
+ * Retrieves the file version from version control system.
+ */
+ void acquireFileVersion();
+
+ private:
+ MemberList *createMemberList(MemberListType lt);
+ void addMemberToList(MemberListType lt,MemberDef *md);
+ void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
+ void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
+ void writeIncludeFiles(OutputList &ol);
+ void writeIncludeGraph(OutputList &ol);
+ void writeIncludedByGraph(OutputList &ol);
+ void writeMemberGroups(OutputList &ol);
+ void writeAuthorSection(OutputList &ol);
+ void writeSourceLink(OutputList &ol);
+ void writeNamespaceDeclarations(OutputList &ol,const QCString &title,
+ bool isConstantGroup);
+ void writeClassDeclarations(OutputList &ol,const QCString &title);
+ void writeInlineClasses(OutputList &ol);
+ void startMemberDeclarations(OutputList &ol);
+ void endMemberDeclarations(OutputList &ol);
+ void startMemberDocumentation(OutputList &ol);
+ void endMemberDocumentation(OutputList &ol);
+ void writeDetailedDescription(OutputList &ol,const QCString &title);
+ void writeBriefDescription(OutputList &ol);
+
+ QDict<IncludeInfo> *m_includeDict;
+ QList<IncludeInfo> *m_includeList;
+ QDict<IncludeInfo> *m_includedByDict;
+ QList<IncludeInfo> *m_includedByList;
+ NamespaceSDict *m_usingDirList;
+ SDict<Definition> *m_usingDeclList;
+ QCString m_path;
+ QCString m_filePath;
+ QCString m_diskName;
+ QCString m_fileName;
+ QCString m_docname;
+ QIntDict<Definition> *m_srcDefDict;
+ QIntDict<MemberDef> *m_srcMemberDict;
+ bool m_isSource;
+ QCString m_fileVersion;
+ PackageDef *m_package;
+ DirDef *m_dir;
+ QList<MemberList> m_memberLists;
+ MemberGroupSDict *m_memberGroupSDict;
+ NamespaceSDict *m_namespaceSDict;
+ ClassSDict *m_classSDict;
+ bool m_subGrouping;
+};
+
+/** Class representing a list of FileDef objects. */
+class FileList : public QList<FileDef>
+{
+ public:
+ FileList() : m_pathName("tmp") {}
+ FileList(const char *path) : QList<FileDef>(), m_pathName(path) {}
+ ~FileList() {}
+ QCString path() const { return m_pathName; }
+ private:
+ int compareValues(const FileDef *md1,const FileDef *md2) const
+ {
+ return qstricmp(md1->name(),md2->name());
+ }
+ QCString m_pathName;
+};
+
+class OutputNameList : public QList<FileList>
+{
+ public:
+ OutputNameList() : QList<FileList>() {}
+ ~OutputNameList() {}
+ private:
+ int compareValues(const FileList *fl1,const FileList *fl2) const
+ {
+ return qstricmp(fl1->path(),fl2->path());
+ }
+};
+
+class OutputNameDict : public QDict<FileList>
+{
+ public:
+ OutputNameDict(int size) : QDict<FileList>(size) {}
+ ~OutputNameDict() {}
+};
+
+class Directory;
+
+/** Class representing an entry (file or sub directory) in a directory */
+class DirEntry
+{
+ public:
+ enum EntryKind { Dir, File };
+ DirEntry(DirEntry *parent,FileDef *fd)
+ : m_parent(parent), m_name(fd->name()), m_kind(File), m_fd(fd),
+ m_isLast(FALSE) { }
+ DirEntry(DirEntry *parent,QCString name)
+ : m_parent(parent), m_name(name), m_kind(Dir),
+ m_fd(0), m_isLast(FALSE) { }
+ virtual ~DirEntry() { }
+ EntryKind kind() const { return m_kind; }
+ FileDef *file() const { return m_fd; }
+ bool isLast() const { return m_isLast; }
+ void setLast(bool b) { m_isLast=b; }
+ DirEntry *parent() const { return m_parent; }
+ QCString name() const { return m_name; }
+ QCString path() const { return parent() ? parent()->path()+"/"+name() : name(); }
+
+ protected:
+ DirEntry *m_parent;
+ QCString m_name;
+
+ private:
+ EntryKind m_kind;
+ FileDef *m_fd;
+ bool m_isLast;
+};
+
+/** Class representing a directory tree of DirEntry objects. */
+class Directory : public DirEntry
+{
+ public:
+ Directory(Directory *parent,const QCString &name)
+ : DirEntry(parent,name)
+ { m_children.setAutoDelete(TRUE); }
+ virtual ~Directory() {}
+ void addChild(DirEntry *d) { m_children.append(d); d->setLast(TRUE); }
+ QList<DirEntry> &children() { return m_children; }
+ void rename(const QCString &name) { m_name=name; }
+ void reParent(Directory *parent) { m_parent=parent; }
+
+ private:
+ QList<DirEntry> m_children;
+};
+
+void generateFileTree();
+
+#endif
+
diff --git a/src/filename.cpp b/src/filename.cpp
new file mode 100644
index 0000000..35a1841
--- /dev/null
+++ b/src/filename.cpp
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "filename.h"
+#include "util.h"
+#include "config.h"
+
+FileName::FileName(const char *fn,const char *n) : FileList()
+{
+ setAutoDelete(TRUE);
+ fName=fn;
+ name=n;
+}
+
+FileName::~FileName()
+{
+}
+
+
+void FileName::generateDiskNames()
+{
+ //QCString commonPrefix;
+ QListIterator<FileDef> it(*this);
+ FileDef *fd;
+ int count=0;
+ for (;(fd=it.current());++it)
+ {
+ if (!fd->isReference()) count++;
+ }
+ if (count==1)
+ {
+ // skip references
+ for (it.toFirst();(fd=it.current()) && fd->isReference();++it) { }
+ // name if unique, so diskname is simply the name
+ //printf("!!!!!!!! Unique disk name=%s for fd=%s\n",name.data(),fd->diskname.data());
+ fd->m_diskName=name;
+ }
+ else if (count>1) // multiple occurrences of the same file name
+ {
+ //printf("Multiple occurrences of %s\n",name.data());
+ int i=0,j=0;
+ bool found=FALSE;
+ while (!found) // search for the common prefix of all paths
+ {
+ for (it.toFirst();(fd=it.current()) && fd->isReference();++it) { }
+ char c=fd->m_path.at(i);
+ if (c=='/') j=i; // remember last position of dirname
+ ++it;
+ while ((fd=it.current()) && !found)
+ {
+ if (!fd->isReference())
+ {
+ //printf("i=%d j=%d fd->path=`%s' fd->name=`%s'\n",i,j,fd->path.left(i).data(),fd->name().data());
+ if (i==(int)fd->m_path.length())
+ {
+ //warning("Input file %s found multiple times!\n"
+ // " The generated documentation for this file may not be correct!\n",fd->absFilePath().data());
+ found=TRUE;
+ }
+ else if (fd->m_path[i]!=c)
+ {
+ found=TRUE;
+ }
+ }
+ ++it;
+ }
+ i++;
+ }
+ for (it.toFirst();(fd=it.current());++it)
+ {
+ //printf("fd->setName(%s)\n",(fd->path.right(fd->path.length()-j-1)+name).data());
+ if (!fd->isReference())
+ {
+ QCString prefix = fd->m_path.right(fd->m_path.length()-j-1);
+ fd->setName(prefix+name);
+ //printf("!!!!!!!! non unique disk name=%s for fd=%s\n",(prefix+name).data(),fd->diskname.data());
+ fd->m_diskName=prefix+name;
+ }
+ }
+ }
+}
+
+int FileName::compareValues(const FileDef *f1, const FileDef *f2) const
+{
+ return qstricmp(f1->fileName(),f2->fileName());
+}
+
+FileNameIterator::FileNameIterator(const FileName &fname) :
+ QListIterator<FileDef>(fname)
+{
+}
+
+FileNameList::FileNameList() : QList<FileName>()
+{
+}
+
+FileNameList::~FileNameList()
+{
+}
+
+void FileNameList::generateDiskNames()
+{
+ FileNameListIterator it(*this);
+ FileName *fn;
+ for (;(fn=it.current());++it)
+ {
+ fn->generateDiskNames();
+ }
+}
+
+int FileNameList::compareValues(const FileName *f1, const FileName *f2) const
+{
+ return Config_getBool("FULL_PATH_NAMES") ?
+ qstricmp(f1->fullName(),f2->fullName()) :
+ qstricmp(f1->fileName(),f2->fileName());
+}
+
+FileNameListIterator::FileNameListIterator(const FileNameList &fnlist) :
+ QListIterator<FileName>(fnlist)
+{
+}
+
+static bool getCaseSenseNames()
+{
+ static bool caseSenseNames = Config_getBool("CASE_SENSE_NAMES");
+ return caseSenseNames;
+}
+
+FileNameDict::FileNameDict(uint size) : QDict<FileName>(size,getCaseSenseNames())
+{
+}
+
diff --git a/src/filename.h b/src/filename.h
new file mode 100644
index 0000000..ac7b164
--- /dev/null
+++ b/src/filename.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef FILENAME_H
+#define FILENAME_H
+
+#include <qdict.h>
+#include <qlist.h>
+#include "filedef.h"
+
+/** Class representing all files with a certain base name */
+class FileName : public FileList
+{
+ public:
+ FileName(const char *fn,const char *name);
+ ~FileName();
+ const char *fileName() const { return name; }
+ const char *fullName() const { return fName; }
+ void generateDiskNames();
+
+ private:
+ int compareValues(const FileDef *item1,const FileDef *item2) const;
+ QCString name;
+ QCString fName;
+};
+
+/** Iterator for FileDef objects in a FileName list. */
+class FileNameIterator : public QListIterator<FileDef>
+{
+ public:
+ FileNameIterator(const FileName &list);
+};
+
+/** Class representing a list of FileName objects. */
+class FileNameList : public QList<FileName>
+{
+ public:
+ FileNameList();
+ ~FileNameList();
+ void generateDiskNames();
+ private:
+ int compareValues(const FileName *item1,const FileName *item2) const;
+};
+
+/** Iterator for FileName objects in a FileNameList. */
+class FileNameListIterator : public QListIterator<FileName>
+{
+ public:
+ FileNameListIterator( const FileNameList &list );
+};
+
+/** Unsorted dictionary of FileName objects. */
+class FileNameDict : public QDict<FileName>
+{
+ public:
+ FileNameDict(uint size);
+ ~FileNameDict() {}
+};
+
+#endif
diff --git a/src/fileparser.cpp b/src/fileparser.cpp
new file mode 100644
index 0000000..1d78e1e
--- /dev/null
+++ b/src/fileparser.cpp
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "fileparser.h"
+#include "outputgen.h"
+
+void FileParser::parseCode(CodeOutputInterface &codeOutIntf,
+ const char *, // scopeName
+ const QCString & input,
+ SrcLangExt, // lang
+ bool, // isExampleBlock
+ const char *, // exampleName
+ FileDef *, // fileDef
+ int startLine,
+ int endLine,
+ bool, // inlineFragment
+ MemberDef *, // memberDef
+ bool showLineNumbers,
+ Definition *, // searchCtx,
+ bool // collectXRefs
+ )
+{
+ int lineNr = startLine!=-1 ? startLine : 1;
+ int length = input.length();
+ int i=0;
+ while (i<length && (endLine==-1 || lineNr<=endLine))
+ {
+ int j=i;
+ while (j<length && input[j]!='\n') j++;
+ QCString lineStr = input.mid(i,j-i);
+ codeOutIntf.startCodeLine(showLineNumbers);
+ if (showLineNumbers) codeOutIntf.writeLineNumber(0,0,0,lineNr);
+ if (!lineStr.isEmpty()) codeOutIntf.codify(lineStr);
+ codeOutIntf.endCodeLine();
+ lineNr++;
+ i=j+1;
+ }
+}
+
diff --git a/src/fileparser.h b/src/fileparser.h
new file mode 100644
index 0000000..f9a7c7b
--- /dev/null
+++ b/src/fileparser.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef FILEPARSER_H
+#define FILEPARSER_H
+
+#include "parserintf.h"
+
+/** @brief General file parser */
+class FileParser : public ParserInterface
+{
+ public:
+ virtual ~FileParser() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char *, const char *,Entry *, bool, QStrList &) {}
+ bool needsPreprocessing(const QCString &) { return FALSE; }
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState() {}
+ void parsePrototype(const char *) {}
+};
+
+
+#endif
diff --git a/src/filestorage.h b/src/filestorage.h
new file mode 100644
index 0000000..0d72923
--- /dev/null
+++ b/src/filestorage.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfile.h>
+#include <assert.h>
+#include "store.h"
+
+
+#ifndef FILESTORAGE_H
+#define FILESTORAGE_H
+
+/** @brief Store implementation based on a file.
+ Writing is linear, after that the file is re-opened for reading.
+ Reading is random (seek+read).
+ */
+class FileStorage : public StorageIntf
+{
+ public:
+ FileStorage() : m_readOnly(FALSE) {}
+ FileStorage( const QString &name) :
+ m_readOnly(FALSE) { m_file.setName(name); }
+ int read(char *buf,uint size) { return m_file.readBlock(buf,size); }
+ int write(const char *buf,uint size) { assert(m_readOnly==FALSE); return m_file.writeBlock(buf,size); }
+ bool open( int m ) { m_readOnly = m==IO_ReadOnly; return m_file.open(m); }
+ bool seek(int64 pos) { return m_file.seek(pos); }
+ int64 pos() const { return m_file.pos(); }
+ void close() { m_file.close(); }
+ void setName( const char *name ) { m_file.setName(name); }
+ private:
+ bool m_readOnly;
+ QFile m_file;
+};
+
+#if 0 // experimental version using mmap after opening the file as read only.
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+class FileStorage : public StorageIntf
+{
+ public:
+ FileStorage() : m_readOnly(FALSE), m_map(0), m_off(0), m_size(0) {}
+ FileStorage( const QString &name) :
+ m_readOnly(FALSE) { m_file.setName(name); }
+ void setName( const char *name ) { m_file.setName(name); }
+ bool open( int m )
+ {
+ if (m==IO_ReadOnly)
+ {
+ m_readOnly=TRUE;
+ QString name = m_file.name();
+ m_file.close();
+ m_fd = ::open(name.data(),O_RDONLY);
+ struct stat stat;
+ fstat(m_fd,&stat);
+ m_size = stat.st_size;
+ m_map = mmap(NULL,m_size,PROT_READ,MAP_SHARED,m_fd,0);
+ if (m_map==MAP_FAILED) perror("mmap failed");
+ assert(m_map!=MAP_FAILED);
+ m_off = 0;
+ return TRUE;
+ }
+ else
+ {
+ m_readOnly = FALSE;
+ return m_file.open(m);
+ }
+ }
+ int write(const char *buf,uint size)
+ {
+ assert(m_map==0);
+ return m_file.writeBlock(buf,size);
+ }
+ int read(char *buf,uint size)
+ {
+ assert(m_map!=0);
+ memcpy(buf,((char *)m_map)+m_off,size);
+ m_off+=size;
+ return size;
+ }
+ bool seek(int64 pos)
+ {
+ m_off=pos;
+ return TRUE;
+ }
+ int64 pos() const
+ {
+ if (m_readOnly)
+ {
+ return m_off;
+ }
+ else
+ {
+ return m_file.pos();
+ }
+ }
+ void close()
+ {
+ if (m_readOnly)
+ {
+ munmap(m_map,m_size);
+ ::close(m_fd);
+ exit(1);
+ }
+ else
+ {
+ m_file.close();
+ }
+ }
+ private:
+ bool m_readOnly;
+ QFile m_file;
+ int m_fd;
+ void *m_map;
+ off_t m_off;
+ off_t m_size;
+};
+#endif
+
+#endif
diff --git a/src/footer.html b/src/footer.html
new file mode 100644
index 0000000..d2aa9e6
--- /dev/null
+++ b/src/footer.html
@@ -0,0 +1,20 @@
+<!-- start footer part -->
+<!--BEGIN GENERATE_TREEVIEW-->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ $navpath
+ <li class="footer">$generatedby
+ <a href="http://www.doxygen.org/index.html">
+ <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
+ </ul>
+</div>
+<!--END GENERATE_TREEVIEW-->
+<!--BEGIN !GENERATE_TREEVIEW-->
+<hr class="footer"/><address class="footer"><small>
+$generatedby <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
+</a> $doxygenversion
+</small></address>
+<!--END !GENERATE_TREEVIEW-->
+</body>
+</html>
diff --git a/src/formula.cpp b/src/formula.cpp
new file mode 100644
index 0000000..9e835e1
--- /dev/null
+++ b/src/formula.cpp
@@ -0,0 +1,328 @@
+/******************************************************************************
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qdir.h>
+
+#include "formula.h"
+#include "image.h"
+#include "util.h"
+#include "message.h"
+#include "config.h"
+#include "portable.h"
+#include "index.h"
+#include "doxygen.h"
+#include "ftextstream.h"
+
+Formula::Formula(const char *text)
+{
+ static int count=0;
+ number = count++;
+ form=text;
+}
+
+Formula::~Formula()
+{
+}
+
+int Formula::getId()
+{
+ return number;
+}
+
+void FormulaList::generateBitmaps(const char *path)
+{
+ int x1,y1,x2,y2;
+ QDir d(path);
+ // store the original directory
+ if (!d.exists()) { err("Output dir %s does not exist!\n",path); exit(1); }
+ QCString oldDir = QDir::currentDirPath().utf8();
+ // go to the html output directory (i.e. path)
+ QDir::setCurrent(d.absPath());
+ QDir thisDir;
+ // generate a latex file containing one formula per page.
+ QCString texName="_formulas.tex";
+ QList<int> pagesToGenerate;
+ pagesToGenerate.setAutoDelete(TRUE);
+ FormulaListIterator fli(*this);
+ Formula *formula;
+ QFile f(texName);
+ bool formulaError=FALSE;
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ if (Config_getBool("LATEX_BATCHMODE")) t << "\\batchmode" << endl;
+ t << "\\documentclass{article}" << endl;
+ t << "\\usepackage{epsfig}" << endl; // for those who want to include images
+ const char *s=Config_getList("EXTRA_PACKAGES").first();
+ while (s)
+ {
+ t << "\\usepackage{" << s << "}\n";
+ s=Config_getList("EXTRA_PACKAGES").next();
+ }
+ t << "\\pagestyle{empty}" << endl;
+ t << "\\begin{document}" << endl;
+ int page=0;
+ for (fli.toFirst();(formula=fli.current());++fli)
+ {
+ QCString resultName;
+ resultName.sprintf("form_%d.png",formula->getId());
+ // only formulas for which no image exists are generated
+ QFileInfo fi(resultName);
+ if (!fi.exists())
+ {
+ // we force a pagebreak after each formula
+ t << formula->getFormulaText() << endl << "\\pagebreak\n\n";
+ pagesToGenerate.append(new int(page));
+ }
+ Doxygen::indexList->addImageFile(resultName);
+ page++;
+ }
+ t << "\\end{document}" << endl;
+ f.close();
+ }
+ if (pagesToGenerate.count()>0) // there are new formulas
+ {
+ //printf("Running latex...\n");
+ //system("latex _formulas.tex </dev/null >/dev/null");
+ QCString latexCmd = Config_getString("LATEX_CMD_NAME");
+ if (latexCmd.isEmpty()) latexCmd="latex";
+ portable_sysTimerStart();
+ if (portable_system(latexCmd,"_formulas.tex")!=0)
+ {
+ err("Problems running latex. Check your installation or look "
+ "for typos in _formulas.tex and check _formulas.log!\n");
+ formulaError=TRUE;
+ //return;
+ }
+ portable_sysTimerStop();
+ //printf("Running dvips...\n");
+ QListIterator<int> pli(pagesToGenerate);
+ int *pagePtr;
+ int pageIndex=1;
+ for (;(pagePtr=pli.current());++pli,++pageIndex)
+ {
+ int pageNum=*pagePtr;
+ msg("Generating image form_%d.png for formula\n",pageNum);
+ char dviArgs[4096];
+ QCString formBase;
+ formBase.sprintf("_form%d",pageNum);
+ // run dvips to convert the page with number pageIndex to an
+ // encapsulated postscript.
+ sprintf(dviArgs,"-q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi",
+ pageIndex,formBase.data());
+ portable_sysTimerStart();
+ if (portable_system("dvips",dviArgs)!=0)
+ {
+ err("Problems running dvips. Check your installation!\n");
+ portable_sysTimerStop();
+ return;
+ }
+ portable_sysTimerStop();
+ // now we read the generated postscript file to extract the bounding box
+ QFileInfo fi(formBase+".eps");
+ if (fi.exists())
+ {
+ QCString eps = fileToString(formBase+".eps");
+ int i=eps.find("%%BoundingBox:");
+ if (i!=-1)
+ {
+ sscanf(eps.data()+i,"%%%%BoundingBox:%d %d %d %d",&x1,&y1,&x2,&y2);
+ }
+ else
+ {
+ err("Couldn't extract bounding box!\n");
+ }
+ }
+ // next we generate a postscript file which contains the eps
+ // and displays it in the right colors and the right bounding box
+ f.setName(formBase+".ps");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << "1 1 1 setrgbcolor" << endl; // anti-alias to white background
+ t << "newpath" << endl;
+ t << "-1 -1 moveto" << endl;
+ t << (x2-x1+2) << " -1 lineto" << endl;
+ t << (x2-x1+2) << " " << (y2-y1+2) << " lineto" << endl;
+ t << "-1 " << (y2-y1+2) << " lineto" <<endl;
+ t << "closepath" << endl;
+ t << "fill" << endl;
+ t << -x1 << " " << -y1 << " translate" << endl;
+ t << "0 0 0 setrgbcolor" << endl;
+ t << "(" << formBase << ".eps) run" << endl;
+ f.close();
+ }
+ // scale the image so that it is four times larger than needed.
+ // and the sizes are a multiple of four.
+ double scaleFactor = 16.0/3.0;
+ int zoomFactor = Config_getInt("FORMULA_FONTSIZE");
+ if (zoomFactor<8 || zoomFactor>50) zoomFactor=10;
+ scaleFactor *= zoomFactor/10.0;
+ int gx = (((int)((x2-x1)*scaleFactor))+3)&~1;
+ int gy = (((int)((y2-y1)*scaleFactor))+3)&~1;
+ // Then we run ghostscript to convert the postscript to a pixmap
+ // The pixmap is a truecolor image, where only black and white are
+ // used.
+
+ char gsArgs[4096];
+ sprintf(gsArgs,"-q -g%dx%d -r%dx%dx -sDEVICE=ppmraw "
+ "-sOutputFile=%s.pnm -dNOPAUSE -dBATCH -- %s.ps",
+ gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72),
+ formBase.data(),formBase.data()
+ );
+ portable_sysTimerStart();
+ if (portable_system(portable_ghostScriptCommand(),gsArgs)!=0)
+ {
+ err("Problem running ghostscript %s %s. Check your installation!\n",portable_ghostScriptCommand(),gsArgs);
+ portable_sysTimerStop();
+ return;
+ }
+ portable_sysTimerStop();
+ f.setName(formBase+".pnm");
+ uint imageX=0,imageY=0;
+ // we read the generated image again, to obtain the pixel data.
+ if (f.open(IO_ReadOnly))
+ {
+ QTextStream t(&f);
+ QCString s;
+ if (!t.eof())
+ s=t.readLine().utf8();
+ if (s.length()<2 || s.left(2)!="P6")
+ err("ghostscript produced an illegal image format!");
+ else
+ {
+ // assume the size is after the first line that does not start with
+ // # excluding the first line of the file.
+ while (!t.eof() && (s=t.readLine().utf8()) && !s.isEmpty() && s.at(0)=='#') { }
+ sscanf(s,"%d %d",&imageX,&imageY);
+ }
+ if (imageX>0 && imageY>0)
+ {
+ //printf("Converting image...\n");
+ char *data = new char[imageX*imageY*3]; // rgb 8:8:8 format
+ uint i,x,y,ix,iy;
+ f.readBlock(data,imageX*imageY*3);
+ Image srcImage(imageX,imageY),
+ filteredImage(imageX,imageY),
+ dstImage(imageX/4,imageY/4);
+ uchar *ps=srcImage.getData();
+ // convert image to black (1) and white (0) index.
+ for (i=0;i<imageX*imageY;i++) *ps++= (data[i*3]==0 ? 1 : 0);
+ // apply a simple box filter to the image
+ static int filterMask[]={1,2,1,2,8,2,1,2,1};
+ for (y=0;y<srcImage.getHeight();y++)
+ {
+ for (x=0;x<srcImage.getWidth();x++)
+ {
+ int s=0;
+ for (iy=0;iy<2;iy++)
+ {
+ for (ix=0;ix<2;ix++)
+ {
+ s+=srcImage.getPixel(x+ix-1,y+iy-1)*filterMask[iy*3+ix];
+ }
+ }
+ filteredImage.setPixel(x,y,s);
+ }
+ }
+ // down-sample the image to 1/16th of the area using 16 gray scale
+ // colors.
+ // TODO: optimize this code.
+ for (y=0;y<dstImage.getHeight();y++)
+ {
+ for (x=0;x<dstImage.getWidth();x++)
+ {
+ int xp=x<<2;
+ int yp=y<<2;
+ int c=filteredImage.getPixel(xp+0,yp+0)+
+ filteredImage.getPixel(xp+1,yp+0)+
+ filteredImage.getPixel(xp+2,yp+0)+
+ filteredImage.getPixel(xp+3,yp+0)+
+ filteredImage.getPixel(xp+0,yp+1)+
+ filteredImage.getPixel(xp+1,yp+1)+
+ filteredImage.getPixel(xp+2,yp+1)+
+ filteredImage.getPixel(xp+3,yp+1)+
+ filteredImage.getPixel(xp+0,yp+2)+
+ filteredImage.getPixel(xp+1,yp+2)+
+ filteredImage.getPixel(xp+2,yp+2)+
+ filteredImage.getPixel(xp+3,yp+2)+
+ filteredImage.getPixel(xp+0,yp+3)+
+ filteredImage.getPixel(xp+1,yp+3)+
+ filteredImage.getPixel(xp+2,yp+3)+
+ filteredImage.getPixel(xp+3,yp+3);
+ // here we scale and clip the color value so the
+ // resulting image has a reasonable contrast
+ dstImage.setPixel(x,y,QMIN(15,(c*15)/(16*10)));
+ }
+ }
+ // save the result as a bitmap
+ QCString resultName;
+ resultName.sprintf("form_%d.png",pageNum);
+ // the option parameter 1 is used here as a temporary hack
+ // to select the right color palette!
+ dstImage.save(resultName,1);
+ delete[] data;
+ }
+ f.close();
+ }
+ // remove intermediate image files
+ thisDir.remove(formBase+".eps");
+ thisDir.remove(formBase+".pnm");
+ thisDir.remove(formBase+".ps");
+ }
+ // remove intermediate files produced by latex
+ thisDir.remove("_formulas.dvi");
+ if (!formulaError) thisDir.remove("_formulas.log"); // keep file in case of errors
+ thisDir.remove("_formulas.aux");
+ }
+ // remove the latex file itself
+ if (!formulaError) thisDir.remove("_formulas.tex");
+ // write/update the formula repository so we know what text the
+ // generated images represent (we use this next time to avoid regeneration
+ // of the images, and to avoid forcing the user to delete all images in order
+ // to let a browser refresh the images).
+ f.setName("formula.repository");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ for (fli.toFirst();(formula=fli.current());++fli)
+ {
+ t << "\\form#" << formula->getId() << ":" << formula->getFormulaText() << endl;
+ }
+ f.close();
+ }
+ // reset the directory to the original location.
+ QDir::setCurrent(oldDir);
+}
+
+
+#ifdef FORMULA_TEST
+int main()
+{
+ FormulaList fl;
+ fl.append(new Formula("$x^2$"));
+ fl.append(new Formula("$y^2$"));
+ fl.append(new Formula("$\\sqrt{x_0^2+x_1^2+x_2^2}$"));
+ fl.generateBitmaps("dest");
+ return 0;
+}
+#endif
diff --git a/src/formula.h b/src/formula.h
new file mode 100644
index 0000000..47f7d4b
--- /dev/null
+++ b/src/formula.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef FORMULA_H
+#define FORMULA_H
+
+#include <qlist.h>
+#include <qdict.h>
+
+/** Class representing a formula in the output. */
+class Formula
+{
+ public:
+ Formula(const char *text);
+ ~Formula();
+ int getId();
+ QCString getFormulaText() const { return form; }
+
+ private:
+ int number;
+ QCString form;
+};
+
+/** A list of Formula objects. */
+class FormulaList : public QList<Formula>
+{
+ public:
+ void generateBitmaps(const char *path);
+};
+
+/** Iterator for Formula objects in a FormulaList. */
+class FormulaListIterator : public QListIterator<Formula>
+{
+ public:
+ FormulaListIterator(const FormulaList &l) :
+ QListIterator<Formula>(l) {}
+};
+
+/** Unsorted dictionary of Formula objects. */
+class FormulaDict : public QDict<Formula>
+{
+ public:
+ FormulaDict(uint size) :
+ QDict<Formula>(size) {}
+ ~FormulaDict() {}
+};
+
+#endif
diff --git a/src/fortrancode.h b/src/fortrancode.h
new file mode 100644
index 0000000..b64ede7
--- /dev/null
+++ b/src/fortrancode.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef FORTRANCODE_H
+#define FORTRANCODE_H
+
+#include "types.h"
+
+class CodeOutputInterface;
+class FileDef;
+class MemberDef;
+class QCString;
+class Definition;
+
+void parseFortranCode(CodeOutputInterface &,const char *,const QCString &,
+ bool ,const char *,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
+ bool collectRefs, FortranFormat format);
+void resetFortranCodeParserState();
+void codeFreeScanner();
+
+#endif
diff --git a/src/fortrancode.l b/src/fortrancode.l
new file mode 100644
index 0000000..03baeed
--- /dev/null
+++ b/src/fortrancode.l
@@ -0,0 +1,1237 @@
+/******************************************************************************
+ *
+ * Parser for syntax hightlighting and references for Fortran90 F subset
+ *
+ * Copyright (C) by Anke Visser
+ * based on the work of Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/**
+ @todo - continutation lines not always recognized
+ - merging of use-statements with same module name and different only-names
+ - rename part of use-statement
+ - links to interface functions
+ - references to variables
+**/
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <qregexp.h>
+#include <qdir.h>
+#include <qstringlist.h>
+#include "entry.h"
+#include "doxygen.h"
+#include "message.h"
+#include "outputlist.h"
+#include "util.h"
+#include "membername.h"
+#include "searchindex.h"
+#include "defargs.h"
+#include "memberlist.h"
+#include "config.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "namespacedef.h"
+#include "tooltip.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_TOP_STATE 1
+#define YY_NO_INPUT 1
+
+/*
+ * For fixed formatted code position 6 is of importance (continuation character).
+ * The following variables and macros keep track of the column number
+ * YY_USER_ACTION is always called for each scan action
+ * YY_FTN_REST is used to handle end of lines and reset the column counter
+ * YY_FTN_REJECT resets the column counters when a pattern is rejected and thus rescanned.
+ */
+int yy_old_start = 0;
+int yy_my_start = 0;
+int yy_end = 1;
+#define YY_USER_ACTION {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += yyleng;}
+#define YY_FTN_RESET {yy_old_start = 0; yy_my_start = 0; yy_end = 1;}
+#define YY_FTN_REJECT {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;}
+
+//--------------------------------------------------------------------------------
+
+/**
+ data of an use-statement
+*/
+class UseEntry
+{
+ public:
+ QCString module; // just for debug
+ QStringList onlyNames; /* entries of the ONLY-part */
+};
+
+/**
+ module name -> list of ONLY/remote entries
+ (module name = name of the module, which can be accessed via use-directive)
+*/
+class UseSDict : public SDict<UseEntry>
+{
+ public:
+ UseSDict() : SDict<UseEntry>(17) {}
+};
+
+/**
+ Contains names of used modules and names of local variables.
+*/
+class Scope
+{
+ public:
+ QStringList useNames; //!< contains names of used modules
+ QDict<void> localVars; //!< contains names of local variables
+
+ Scope() : localVars(7, FALSE /*caseSensitive*/) {}
+};
+
+/*===================================================================*/
+/*
+ * statics
+ */
+
+static QCString docBlock; //!< contents of all lines of a documentation block
+static QCString currentModule=0; //!< name of the current enclosing module
+static UseSDict *useMembers= new UseSDict; //!< info about used modules
+static UseEntry *useEntry = 0; //!< current use statement info
+static QList<Scope> scopeStack;
+// static QStringList *currentUseNames= new QStringList; //! contains names of used modules of current program unit
+static QCString str=""; //!> contents of fortran string
+
+static CodeOutputInterface * g_code;
+
+// TODO: is this still needed? if so, make it work
+static QCString g_parmType;
+static QCString g_parmName;
+
+static const char * g_inputString; //!< the code fragment as text
+static int g_inputPosition; //!< read offset during parsing
+static int g_inputLines; //!< number of line in the code fragment
+static int g_yyLineNr; //!< current line number
+static bool g_needsTermination;
+static Definition *g_searchCtx;
+static bool g_collectXRefs;
+static bool g_isFixedForm;
+
+static bool g_insideBody; //!< inside subprog/program body? => create links
+static const char * g_currentFontClass;
+
+static bool g_exampleBlock;
+static QCString g_exampleName;
+static QCString g_exampleFile;
+
+static FileDef * g_sourceFileDef;
+static Definition * g_currentDefinition;
+static MemberDef * g_currentMemberDef;
+static bool g_includeCodeFragment;
+
+static char stringStartSymbol; // single or double quote
+// count in variable declaration to filter out
+// declared from referenced names
+static int bracketCount = 0;
+
+static bool g_endComment;
+
+// simplified way to know if this is fixed form
+// duplicate in fortranscanner.l
+static bool recognizeFixedForm(const char* contents, FortranFormat format)
+{
+ int column=0;
+ bool skipLine=FALSE;
+
+ if (format == FortranFormat_Fixed) return TRUE;
+ if (format == FortranFormat_Free) return FALSE;
+ for (int i=0;;i++)
+ {
+ column++;
+
+ switch(contents[i])
+ {
+ case '\n':
+ column=0;
+ skipLine=FALSE;
+ break;
+ case ' ':
+ break;
+ case '#':
+ skipLine=TRUE;
+ break;
+ case '\000':
+ return FALSE;
+ case 'C':
+ case 'c':
+ case '*':
+ if(column==1) return TRUE;
+ if(skipLine) break;
+ return FALSE;
+ case '!':
+ if(column>1 && column<7) return FALSE;
+ skipLine=TRUE;
+ break;
+ default:
+ if(skipLine) break;
+ if(column==7) return TRUE;
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+static void endFontClass()
+{
+ if (g_currentFontClass)
+ {
+ g_code->endFontClass();
+ g_currentFontClass=0;
+ }
+}
+
+static void startFontClass(const char *s)
+{
+ endFontClass();
+ g_code->startFontClass(s);
+ g_currentFontClass=s;
+}
+
+static void setCurrentDoc(const QCString &anchor)
+{
+ if (Doxygen::searchIndex)
+ {
+ if (g_searchCtx)
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
+ }
+ else
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
+ }
+ }
+}
+
+static void addToSearchIndex(const char *text)
+{
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->addWord(text,FALSE);
+ }
+}
+
+/*! start a new line of code, inserting a line number if g_sourceFileDef
+ * is TRUE. If a definition starts at the current line, then the line
+ * number is linked to the documentation of that definition.
+ */
+static void startCodeLine()
+{
+ if (g_sourceFileDef)
+ {
+ //QCString lineNumber,lineAnchor;
+ //lineNumber.sprintf("%05d",g_yyLineNr);
+ //lineAnchor.sprintf("l%05d",g_yyLineNr);
+
+ Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
+ //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
+ if (!g_includeCodeFragment && d)
+ {
+ g_currentDefinition = d;
+ g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
+ g_insideBody = FALSE;
+ g_endComment = FALSE;
+ g_parmType.resize(0);
+ g_parmName.resize(0);
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",g_yyLineNr);
+ if (g_currentMemberDef)
+ {
+ g_code->writeLineNumber(g_currentMemberDef->getReference(),
+ g_currentMemberDef->getOutputFileBase(),
+ g_currentMemberDef->anchor(),g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ else if (d->isLinkableInProject())
+ {
+ g_code->writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ 0,g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ }
+ else
+ {
+ g_code->writeLineNumber(0,0,0,g_yyLineNr);
+ }
+ }
+ g_code->startCodeLine(g_sourceFileDef);
+ if (g_currentFontClass)
+ {
+ g_code->startFontClass(g_currentFontClass);
+ }
+}
+
+
+static void endFontClass();
+static void endCodeLine()
+{
+ endFontClass();
+ g_code->endCodeLine();
+}
+
+/*! write a code fragment `text' that may span multiple lines, inserting
+ * line numbers for each line.
+ */
+static void codifyLines(char *text)
+{
+ //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
+ char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+ const char * tmp_currentFontClass = g_currentFontClass;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ g_code->codify(sp);
+ endCodeLine();
+ if (g_yyLineNr<g_inputLines)
+ {
+ startCodeLine();
+ }
+ if (tmp_currentFontClass)
+ {
+ startFontClass(tmp_currentFontClass);
+ }
+ }
+ else
+ {
+ g_code->codify(sp);
+ done=TRUE;
+ }
+ }
+}
+
+static void codifyLines(QCString str)
+{
+ char *tmp= (char *) malloc(str.length()+1);
+ strcpy(tmp, str);
+ codifyLines(tmp);
+ free(tmp);
+}
+
+/*! writes a link to a fragment \a text that may span multiple lines, inserting
+ * line numbers for each line. If \a text contains newlines, the link will be
+ * split into multiple links with the same destination, one for each line.
+ */
+static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ Definition *d,const char *text)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ TooltipManager::instance()->addTooltip(d);
+ QCString ref = d->getReference();
+ QCString file = d->getOutputFileBase();
+ QCString anchor = d->anchor();
+ QCString tooltip;
+ if (!sourceTooltips) // fall back to simple "title" tooltips
+ {
+ tooltip = d->briefDescriptionAsTooltip();
+ }
+ bool done=FALSE;
+ char *p=(char *)text;
+ while (!done)
+ {
+ char *sp=p;
+ char c;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ endCodeLine();
+ if (g_yyLineNr<g_inputLines)
+ {
+ startCodeLine();
+ }
+ }
+ else
+ {
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ done=TRUE;
+ }
+ }
+}
+
+
+//-------------------------------------------------------------------------------
+/**
+ searches for definition of a type
+ @param tname the name of the type
+ @param moduleName name of enclosing module or null, if global entry
+ @param cd the entry, if found or null
+ @param useDict dictionary of data of USE-statement
+ @returns true, if type is found
+*/
+static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName,
+ ClassDef *&cd, UseSDict *usedict=0)
+{
+ if (tname.isEmpty()) return FALSE; /* empty name => nothing to link */
+
+ //cout << "=== search for type: " << tname << endl;
+
+ // search for type
+ if ((cd=Doxygen::classSDict->find(tname)))
+ {
+ //cout << "=== type found in global module" << endl;
+ return TRUE;
+ }
+ else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname)))
+ {
+ //cout << "=== type found in local module" << endl;
+ return TRUE;
+ }
+ else
+ {
+ UseEntry *use;
+ for (UseSDict::Iterator di(*usedict); (use=di.current()); ++di)
+ {
+ if ((cd= Doxygen::classSDict->find(use->module+"::"+tname)))
+ {
+ //cout << "=== type found in used module" << endl;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ searches for definition of function memberName
+ @param memberName the name of the function/variable
+ @param moduleName name of enclosing module or null, if global entry
+ @param md the entry, if found or null
+ @param usedict array of data of USE-statement
+ @returns true, if found
+*/
+static bool getFortranDefs(const QCString &memberName, const QCString &moduleName,
+ MemberDef *&md, UseSDict *usedict=0)
+{
+ if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */
+
+ // look in local variables
+ QListIterator<Scope> it(scopeStack);
+ Scope *scope;
+ for (it.toLast();(scope=it.current());--it)
+ {
+ if (scope->localVars.find(memberName))
+ return FALSE;
+ }
+
+ // search for function
+ MemberName *mn = Doxygen::functionNameSDict->find(memberName);
+ if (!mn)
+ {
+ mn = Doxygen::memberNameSDict->find(memberName);
+ }
+
+ if (mn) // name is known
+ {
+ MemberListIterator mli(*mn);
+ for (mli.toFirst();(md=mli.current());++mli) // all found functions with given name
+ {
+ FileDef *fd=md->getFileDef();
+ GroupDef *gd=md->getGroupDef();
+
+ //cout << "found link with same name: " << fd->fileName() << " " << memberName;
+ //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl;
+
+ if ((gd && gd->isLinkable()) || (fd && fd->isLinkable()))
+ {
+ NamespaceDef *nspace= md->getNamespaceDef();
+
+ if (nspace == 0)
+ { // found function in global scope
+ return TRUE;
+ }
+ else if (moduleName == nspace->name())
+ { // found in local scope
+ return TRUE;
+ }
+ else
+ { // else search in used modules
+ QCString moduleName= nspace->name();
+ UseEntry *ue= usedict->find(moduleName);
+ if (ue)
+ {
+ // check if only-list exists and if current entry exists is this list
+ QStringList &only= ue->onlyNames;
+ if (only.isEmpty())
+ {
+ //cout << " found in module " << moduleName << " entry " << memberName << endl;
+ return TRUE; // whole module used
+ }
+ else
+ {
+ for ( QStringList::Iterator it = only.begin(); it != only.end(); ++it)
+ {
+ //cout << " search in only: " << moduleName << ":: " << memberName << "==" << (*it)<< endl;
+ if (memberName == (*it).utf8())
+ {
+ return TRUE; // found in ONLY-part of use list
+ }
+ }
+ }
+ }
+ }
+ } // if linkable
+ } // for
+ }
+ return FALSE;
+}
+
+/**
+ gets the link to a generic procedure which depends not on the name, but on the parameter list
+ @todo implementation
+*/
+static bool getGenericProcedureLink(const ClassDef *cd,
+ const char *memberText,
+ CodeOutputInterface &ol)
+{
+ (void)cd;
+ (void)memberText;
+ (void)ol;
+ return FALSE;
+}
+
+static bool getLink(UseSDict *usedict, // dictonary with used modules
+ const char *memberText, // exact member text
+ CodeOutputInterface &ol,
+ const char *text)
+{
+ MemberDef *md;
+ QCString memberName= removeRedundantWhiteSpace(memberText);
+
+ if (getFortranDefs(memberName, currentModule, md, usedict) && md->isLinkable())
+ {
+ //if (md->isVariable()) return FALSE; // variables aren't handled yet
+
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getBodyDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable())
+ {
+ if (g_currentDefinition && g_currentMemberDef &&
+ md!=g_currentMemberDef && g_insideBody && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ writeMultiLineCodeLink(ol,md,text ? text : memberText);
+ addToSearchIndex(text ? text : memberText);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static void generateLink(CodeOutputInterface &ol, char *lname)
+{
+ ClassDef *cd=0;
+ QCString tmp = lname;
+ tmp = removeRedundantWhiteSpace(tmp.lower());
+
+ // check if lowercase lname is a linkable type or interface
+ if ( (getFortranTypeDefs(tmp, currentModule, cd, useMembers)) && cd->isLinkable() )
+ {
+ if ( (cd->compoundType() == ClassDef::Class) && // was Entry::INTERFACE_SEC) &&
+ (getGenericProcedureLink(cd, tmp, ol)) )
+ {
+ //cout << "=== generic procedure resolved" << endl;
+ }
+ else
+ { // write type or interface link
+ writeMultiLineCodeLink(ol,cd,tmp);
+ addToSearchIndex(tmp.data());
+ }
+ }
+ // check for function/variable
+ else if (getLink(useMembers, tmp, ol, tmp))
+ {
+ //cout << "=== found link for lowercase " << lname << endl;
+ }
+ else
+ {
+ // nothing found, just write out the word
+ //startFontClass("charliteral"); //test
+ codifyLines(tmp);
+ //endFontClass(); //test
+ addToSearchIndex(tmp.data());
+ }
+}
+
+/*! counts the number of lines in the input */
+static int countLines()
+{
+ const char *p=g_inputString;
+ char c;
+ int count=1;
+ while ((c=*p))
+ {
+ p++ ;
+ if (c=='\n') count++;
+ }
+ if (p>g_inputString && *(p-1)!='\n')
+ { // last line does not end with a \n, so we add an extra
+ // line and explicitly terminate the line after parsing.
+ count++,
+ g_needsTermination=TRUE;
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+/** start scope */
+static void startScope()
+{
+ DBG_CTX((stderr, "===> startScope %s",yytext));
+ Scope *scope = new Scope;
+ scopeStack.append(scope);
+}
+
+/** end scope */
+static void endScope()
+{
+ DBG_CTX((stderr,"===> endScope %s",yytext));
+ if (scopeStack.isEmpty())
+ {
+ DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n"));
+ return;
+ }
+
+ Scope *scope = scopeStack.getLast();
+ scopeStack.removeLast();
+ for ( QStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it)
+ {
+ useMembers->remove((*it).utf8());
+ }
+ delete scope;
+}
+
+static void addUse(const QCString &moduleName)
+{
+ if (!scopeStack.isEmpty())
+ scopeStack.getLast()->useNames.append(moduleName);
+}
+
+static void addLocalVar(const QCString &varName)
+{
+ if (!scopeStack.isEmpty())
+ scopeStack.getLast()->localVars.insert(varName, (void*)1);
+}
+
+//----------------------------------------------------------------------------
+
+/* -----------------------------------------------------------------*/
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+IDSYM [a-z_A-Z0-9]
+ID [a-z_A-Z]+{IDSYM}*
+SUBPROG (subroutine|function)
+B [ \t]
+BS [ \t]*
+BS_ [ \t]+
+COMMA {BS},{BS}
+ARGS_L0 ("("[^)]*")")
+ARGS_L1a [^()]*"("[^)]*")"[^)]*
+ARGS_L1 ("("{ARGS_L1a}*")")
+ARGS_L2 "("({ARGS_L0}|[^()]|{ARGS_L1a}|{ARGS_L1})*")"
+ARGS {BS}({ARGS_L0}|{ARGS_L1}|{ARGS_L2})
+
+NUM_TYPE (complex|integer|logical|real)
+LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
+KIND {ARGS}
+CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE)
+
+INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
+ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED)
+ACCESS_SPEC (PROTECTED|PRIVATE|PUBLIC)
+/* Assume that attribute statements are almost the same as attributes. */
+ATTR_STMT {ATTR_SPEC}|DIMENSION
+FLOW (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|ELSEWHERE|ELSEIF|RETURN|CONTINUE|EXIT)
+COMMANDS (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON)
+IGNORE (CALL)
+PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+
+/* | */
+
+%option noyywrap
+%option stack
+%option caseless
+/*%option debug*/
+
+%x Start
+%x SubCall
+%x FuncDef
+%x ClassName
+%x ClassVar
+%x Subprog
+%x DocBlock
+%x Use
+%x UseOnly
+%x Import
+%x Declaration
+%x DeclContLine
+%x Parameterlist
+%x String
+%x Subprogend
+
+%%
+ /*==================================================================*/
+
+ /*-------- ignore ------------------------------------------------------------*/
+
+<Start>{IGNORE}/{BS}"("? { // do not search keywords, intrinsics... TODO: complete list
+ codifyLines(yytext);
+ }
+ /*-------- inner construct ---------------------------------------------------*/
+
+<Start>{COMMANDS}/{BS}[,( \t\n] { // highlight
+ /* font class is defined e.g. in doxygen.css */
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Start>{FLOW}/{BS}[,( \t\n] {
+ if (g_isFixedForm)
+ {
+ if ((yy_my_start == 1) && ((yytext[0] == 'c') || (yytext[0] == 'C'))) YY_FTN_REJECT;
+ }
+ /* font class is defined e.g. in doxygen.css */
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Start>{BS}(CASE|CLASS|TYPE){BS_}(IS|DEFAULT) {
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Start>"end"({BS}{FLOW})?/[ \t\n] { // list is a bit long as not all have possible end
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+ }
+
+<Start>"implicit"{BS}"none" {
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Start>^{BS}"namelist"/[//] { // Namelist specification
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ /*-------- use statement -------------------------------------------*/
+<Start>"use"{BS_} {
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(Use);
+ }
+<Use>{ID} {
+ QCString tmp = yytext;
+ tmp = tmp.lower();
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+
+ /* append module name to use dict */
+ useEntry = new UseEntry();
+ //useEntry->module = yytext;
+ //useMembers->append(yytext, useEntry);
+ //addUse(yytext);
+ useEntry->module = tmp;
+ useMembers->append(tmp, useEntry);
+ addUse(tmp);
+ }
+<Use>,{BS}"ONLY" { // TODO: rename
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(UseOnly);
+ }
+<UseOnly,Import>{BS},{BS} { codifyLines(yytext); }
+<UseOnly,Import>{BS}&{BS}"\n" { codifyLines(yytext); YY_FTN_RESET}
+<UseOnly>{ID} {
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+ useEntry->onlyNames.append(yytext);
+ }
+<Use,UseOnly,Import>"\n" {
+ unput(*yytext);
+ yy_pop_state();YY_FTN_RESET
+ }
+<Start>"import"{BS_} {
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(Import);
+ }
+<Import>{ID} {
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+ }
+ /*-------- fortran module -----------------------------------------*/
+<Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { //
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(ClassName);
+ if (!qstricmp(yytext,"module")) currentModule="module";
+ }
+<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { //
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(ClassName);
+ }
+<ClassName>{ID} {
+ if (currentModule == "module")
+ {
+ currentModule=yytext;
+ currentModule = currentModule.lower();
+ }
+ generateLink(*g_code,yytext);
+ yy_pop_state();
+ }
+<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable deklaration
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<ClassName>\n { // interface may be without name
+ yy_pop_state();
+ YY_FTN_REJECT;
+ }
+<Start>"end"({BS_}"module").* { // just reset currentModule, rest is done in following rule
+ currentModule=0;
+ YY_FTN_REJECT;
+ }
+ /*-------- subprog definition -------------------------------------*/
+<Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_} { // TYPE_SPEC is for old function style function result
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(Subprog);
+ }
+<Subprog>{ID} { // subroutine/function name
+ DBG_CTX((stderr, "===> start subprogram %s\n", yytext));
+ startScope();
+ generateLink(*g_code,yytext);
+ }
+<Subprog>"(".* { // ignore rest of line
+ codifyLines(yytext);
+ }
+<Subprog,Subprogend>"\n" { codifyLines(yytext);
+ yy_pop_state();
+ YY_FTN_RESET
+ }
+<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS} { // Fortran subroutine or function ends
+ //cout << "===> end function " << yytext << endl;
+ endScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(Subprogend);
+ }
+<Subprogend>{ID}/{BS}(\n|!) {
+ generateLink(*g_code,yytext);
+ yy_pop_state();
+ }
+<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends
+ //cout << "===> end function " << yytext << endl;
+ endScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
+ /*-------- variable declaration ----------------------------------*/
+<Start>{TYPE_SPEC}/[,:( ] {
+ yy_push_state(YY_START);
+ BEGIN(Declaration);
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<Start>{ATTR_SPEC} {
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable deklaration
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ }
+<Declaration>{ID} { // local var
+ if (g_currentMemberDef && g_currentMemberDef->isFunction() && bracketCount==0)
+ {
+ g_code->codify(yytext);
+ addLocalVar(yytext);
+ }
+ else
+ {
+ generateLink(*g_code, yytext);
+ }
+ }
+<Declaration>[(] { // start of array specification
+ bracketCount++;
+ g_code->codify(yytext);
+ }
+
+<Declaration>[)] { // end array specification
+ bracketCount--;
+ g_code->codify(yytext);
+ }
+
+<Declaration>"&" { // continuation line
+ g_code->codify(yytext);
+ yy_push_state(YY_START);
+ BEGIN(DeclContLine);
+ }
+<DeclContLine>"\n" { // declaration not yet finished
+ codifyLines(yytext);
+ bracketCount = 0;
+ yy_pop_state();
+ YY_FTN_RESET
+ }
+<Declaration>"\n" { // end declaration line
+ if (g_endComment)
+ {
+ g_endComment=FALSE;
+ }
+ else
+ {
+ codifyLines(yytext);
+ }
+ bracketCount = 0;
+ yy_pop_state();
+ YY_FTN_RESET
+ }
+
+ /*-------- subprog calls -----------------------------------------*/
+
+<Start>"call"{BS_} {
+ codifyLines(yytext);
+ yy_push_state(YY_START);
+ BEGIN(SubCall);
+ }
+<SubCall>{ID} { // subroutine call
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+ yy_pop_state();
+ }
+<Start>{ID}{BS}/"(" { // function call
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+ }
+
+ /*-------- comments ---------------------------------------------------*/
+<Start>\n?{BS}"!>"|"!<" { // start comment line or comment block
+ if (yytext[0] == '\n')
+ {
+ yy_old_start = 0;
+ yy_my_start = 1;
+ yy_end = yyleng;
+ }
+ // Actually we should see if ! on position 6, can be continuation
+ // but the chance is very unlikely, so no effort to solve it here
+ yy_push_state(YY_START);
+ BEGIN(DocBlock);
+ docBlock=yytext;
+ }
+<Declaration>{BS}"!<" { // start comment line or comment block
+ yy_push_state(YY_START);
+ BEGIN(DocBlock);
+ docBlock=yytext;
+ }
+
+<DocBlock>.* { // contents of current comment line
+ docBlock+=yytext;
+ }
+<DocBlock>"\n"{BS}("!>"|"!<"|"!!") { // comment block (next line is also comment line)
+ yy_old_start = 0;
+ yy_my_start = 1;
+ yy_end = yyleng;
+ // Actually we should see if ! on position 6, can be continuation
+ // but the chance is very unlikely, so no effort to solve it here
+ docBlock+=yytext;
+ }
+<DocBlock>"\n" { // comment block ends at the end of this line
+ // remove special comment (default config)
+ if (Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr+=((QCString)docBlock).contains('\n');
+ g_yyLineNr+=1;
+ endCodeLine();
+ if (g_yyLineNr<g_inputLines)
+ {
+ startCodeLine();
+ }
+ g_endComment=TRUE;
+ }
+ else // do not remove comment
+ {
+ startFontClass("comment");
+ codifyLines(docBlock);
+ endFontClass();
+ }
+ unput(*yytext);
+ yy_pop_state();
+ YY_FTN_RESET
+ }
+
+<*>"!"[^><\n].*|"!"$ { // normal comment
+ if(YY_START == String) YY_FTN_REJECT; // ignore in strings
+ if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+
+<*>^[Cc*].* { // normal comment
+ if(! g_isFixedForm) YY_FTN_REJECT;
+
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+
+ /*------ preprocessor --------------------------------------------*/
+<Start>"#".*\n {
+ if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
+ startFontClass("preprocessor");
+ codifyLines(yytext);
+ endFontClass();
+ YY_FTN_RESET
+ }
+ /*------ variable references? -------------------------------------*/
+
+<Start>"%"{BS}{ID} { // ignore references to elements
+ g_code->codify(yytext);
+ }
+<Start>{ID} {
+ g_insideBody=TRUE;
+ generateLink(*g_code, yytext);
+ g_insideBody=FALSE;
+ }
+ /*------ strings --------------------------------------------------*/
+<*>"\\\\" { str+=yytext; /* ignore \\ */}
+<*>"\\\""|\\\' { str+=yytext; /* ignore \" */}
+
+<String>\n { // string with \n inside
+ str+=yytext;
+ startFontClass("stringliteral");
+ codifyLines(str);
+ endFontClass();
+ str = "";
+ YY_FTN_RESET
+ }
+<String>\"|\' { // string ends with next quote without previous backspace
+ if(yytext[0]!=stringStartSymbol) YY_FTN_REJECT; // single vs double quote
+ str+=yytext;
+ startFontClass("stringliteral");
+ codifyLines(str);
+ endFontClass();
+ yy_pop_state();
+ }
+<String>. {str+=yytext;}
+
+<*>\"|\' { /* string starts */
+ /* if(YY_START == StrIgnore) YY_FTN_REJECT; // ignore in simple comments */
+ if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
+ yy_push_state(YY_START);
+ stringStartSymbol=yytext[0]; // single or double quote
+ BEGIN(String);
+ str=yytext;
+ }
+ /*-----------------------------------------------------------------------------*/
+
+<*>\n {
+ if (g_endComment)
+ {
+ g_endComment=FALSE;
+ }
+ else
+ {
+ codifyLines(yytext);
+ }
+ YY_FTN_RESET
+ }
+<*>^{BS}"type"{BS}"=" { g_code->codify(yytext); }
+
+<*>. {
+ g_code->codify(yytext);
+ }
+<*>{LOG_OPER} { // Fortran logical comparison keywords
+ g_code->codify(yytext);
+ }
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+/*===================================================================*/
+
+
+void resetFortranCodeParserState() {}
+
+void parseFortranCode(CodeOutputInterface &od,const char *className,const QCString &s,
+ bool exBlock, const char *exName,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool,Definition *searchCtx,
+ bool collectXRefs, FortranFormat format)
+{
+ //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
+
+ // used parameters
+ (void)memberDef;
+ (void)className;
+
+ if (s.isEmpty()) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
+ TooltipManager::instance()->clearTooltips();
+ g_code = &od;
+ g_inputString = s;
+ g_inputPosition = 0;
+ g_isFixedForm = recognizeFixedForm((const char*)s,format);
+ g_currentFontClass = 0;
+ g_needsTermination = FALSE;
+ g_searchCtx = searchCtx;
+ g_collectXRefs = collectXRefs;
+ if (endLine!=-1)
+ g_inputLines = endLine+1;
+ else
+ g_inputLines = countLines();
+
+ if (startLine!=-1)
+ g_yyLineNr = startLine;
+ else
+ g_yyLineNr = 1;
+
+ g_exampleBlock = exBlock;
+ g_exampleName = exName;
+ g_sourceFileDef = fd;
+ if (exBlock && fd==0)
+ {
+ // create a dummy filedef for the example
+ g_sourceFileDef = new FileDef("",exName);
+ }
+ if (g_sourceFileDef)
+ {
+ setCurrentDoc("l00001");
+ }
+ g_currentDefinition = 0;
+ g_currentMemberDef = 0;
+ if (!g_exampleName.isEmpty())
+ {
+ g_exampleFile = convertNameToFile(g_exampleName+"-example");
+ }
+ g_includeCodeFragment = inlineFragment;
+ startCodeLine();
+ g_parmName.resize(0);
+ g_parmType.resize(0);
+ fortrancodeYYrestart( fortrancodeYYin );
+ BEGIN( Start );
+ fortrancodeYYlex();
+ if (g_needsTermination)
+ {
+ endFontClass();
+ g_code->endCodeLine();
+ }
+ if (fd)
+ {
+ TooltipManager::instance()->writeTooltips(*g_code);
+ }
+ if (exBlock && g_sourceFileDef)
+ {
+ // delete the temporary file definition used for this example
+ delete g_sourceFileDef;
+ g_sourceFileDef=0;
+ }
+ printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
+ return;
+}
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void fortrancodeYYdummy() { yy_flex_realloc(0,0); }
+}
+#elif YY_FLEX_SUBMINOR_VERSION<33
+#error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
+#else
+extern "C" { // some bogus code to keep the compiler happy
+ void fortrancodeYYdummy() { yy_top_state(); }
+}
+#endif
+
diff --git a/src/fortranscanner.h b/src/fortranscanner.h
new file mode 100644
index 0000000..92a8669
--- /dev/null
+++ b/src/fortranscanner.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCANNER_FORTRAN_H
+#define SCANNER_FORTRAN_H
+
+#include "parserintf.h"
+
+/** \brief Fortran language parser using state-based lexical scanning.
+ *
+ * This is the Fortran language parser for doxygen.
+ */
+class FortranLanguageScanner : public ParserInterface
+{
+ public:
+ FortranLanguageScanner(FortranFormat format=FortranFormat_Unknown) : m_format(format) { }
+ virtual ~FortranLanguageScanner() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+ bool needsPreprocessing(const QCString &extension);
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState();
+ void parsePrototype(const char *text);
+
+ private:
+ FortranFormat m_format;
+};
+
+class FortranLanguageScannerFree : public FortranLanguageScanner
+{
+ public:
+ FortranLanguageScannerFree() : FortranLanguageScanner(FortranFormat_Free) { }
+};
+
+class FortranLanguageScannerFixed : public FortranLanguageScanner
+{
+ public:
+ FortranLanguageScannerFixed() : FortranLanguageScanner(FortranFormat_Fixed) { }
+};
+
+#endif
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
new file mode 100644
index 0000000..64a49ca
--- /dev/null
+++ b/src/fortranscanner.l
@@ -0,0 +1,2429 @@
+/* -*- mode: fundamental; indent-tabs-mode: 1; -*- */
+/*****************************************************************************
+ * Parser for Fortran90 F subset
+ *
+ * Copyright (C) by Anke Visser
+ * based on the work of Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/* Developer notes.
+ *
+ * - Consider using startScope(), endScope() functions with module, program,
+ * subroutine or any other scope in fortran program.
+ *
+ * - Symbol modifiers (attributes) are collected using SymbolModifiers |= operator during
+ * substructure parsing. When substructure ends all modifiers are applied to actual
+ * entries in applyModifiers() functions.
+ *
+ * - How case insensitiveness should be handled in code?
+ * On one side we have arg->name and entry->name, on another side modifierMap[name].
+ * In entries and arguments case is the same as in code, in modifier map case is lowered and
+ * then it is compared to lowered entry/argument names.
+ *
+ * - Do not like constructs like aa{BS} or {BS}bb. Should try to handle blank space
+ * with separate rule?: It seems it is often necessary, because we may parse something like
+ * "functionA" or "MyInterface". So constructs like `(^|[ \t])interface({BS_}{ID})?/[ \t\n]'
+ * are desired.
+ *
+ * - Must track yyLineNr when using REJECT, unput() or similar commands.
+ */
+
+%{
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <unistd.h>
+#include <qfile.h>
+#include <qmap.h>
+
+#include "fortranscanner.h"
+#include "entry.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "defargs.h"
+#include "language.h"
+#include "commentscan.h"
+#include "fortrancode.h"
+#include "pre.h"
+#include "arguments.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+enum ScanVar { V_IGNORE, V_VARIABLE, V_PARAMETER};
+enum InterfaceType { IF_NONE, IF_SPECIFIC, IF_GENERIC, IF_ABSTRACT };
+
+// {{{ ----- Helper structs -----
+//! Holds modifiers (ie attributes) for one symbol (variable, function, etc)
+struct SymbolModifiers {
+ enum Protection {NONE_P, PUBLIC, PRIVATE};
+ enum Direction {NONE_D, IN, OUT, INOUT};
+
+ //!< This is only used with function return value.
+ QCString type, returnName;
+ Protection protection;
+ Direction direction;
+ bool optional;
+ bool protect;
+ QCString dimension;
+ bool allocatable;
+ bool external;
+ bool intrinsic;
+ bool parameter;
+ bool pointer;
+ bool target;
+ bool save;
+ bool deferred;
+ bool nonoverridable;
+ bool nopass;
+ bool pass;
+ QCString passVar;
+
+ SymbolModifiers() : type(), returnName(), protection(NONE_P), direction(NONE_D),
+ optional(FALSE), protect(FALSE), dimension(), allocatable(FALSE),
+ external(FALSE), intrinsic(FALSE), parameter(FALSE),
+ pointer(FALSE), target(FALSE), save(FALSE), deferred(FALSE), nonoverridable(FALSE),
+ nopass(FALSE), pass(FALSE), passVar() {}
+
+ SymbolModifiers& operator|=(const SymbolModifiers &mdfs);
+ SymbolModifiers& operator|=(QCString mdfrString);
+};
+
+//ostream& operator<<(ostream& out, const SymbolModifiers& mdfs);
+
+static const char *directionStrs[] =
+{
+ "", "intent(in)", "intent(out)", "intent(inout)"
+};
+static const char *directionParam[] =
+{
+ "", "[in]", "[out]", "[in,out]"
+};
+
+// }}}
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+static ParserInterface *g_thisParser;
+static const char * inputString;
+static int inputPosition;
+static bool isFixedForm;
+static QCString inputStringPrepass; ///< Input string for prepass of line cont. '&'
+static QCString inputStringSemi; ///< Input string after command separetor ';'
+static unsigned int inputPositionPrepass;
+static int lineCountPrepass = 0;
+
+static QList<Entry> subrCurrent;
+
+struct CommentInPrepass {
+ int column;
+ QCString str;
+ CommentInPrepass(int column, QCString str) : column(column), str(str) {}
+};
+static QList<CommentInPrepass> comments;
+
+YY_BUFFER_STATE *include_stack = NULL;
+int include_stack_ptr = 0;
+int include_stack_cnt = 0;
+
+static QFile inputFile;
+static QCString yyFileName;
+static int yyLineNr = 1 ;
+static int yyColNr = 0 ;
+static Entry* current_root = 0 ;
+static Entry* global_root = 0 ;
+static Entry* file_root = 0 ;
+static Entry* current = 0 ;
+static Entry* last_entry = 0 ;
+static ScanVar v_type = V_IGNORE; // type of parsed variable
+static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved
+ // module procedures
+static QCString docBlock;
+static QCString docBlockName;
+static bool docBlockInBody = FALSE;
+static bool docBlockJavaStyle;
+
+static MethodTypes mtype;
+static bool gstat;
+static Specifier virt;
+
+static QCString debugStr;
+static QCString result; // function result
+static Argument *parameter; // element of parameter list
+static QCString argType; // fortran type of an argument of a parameter list
+static QCString argName; // last identifier name in variable list
+static QCString initializer; // initial value of a variable
+static int initializerArrayScope; // number if nested array scopes in initializer
+static int initializerScope; // number if nested function calls in initializer
+static QCString useModuleName; // name of module in the use statement
+static Protection defaultProtection;
+static Protection typeProtection;
+static int typeMode = false;
+static InterfaceType ifType = IF_NONE;
+static bool functionLine = FALSE;
+
+static char stringStartSymbol; // single or double quote
+static bool parsingPrototype = FALSE; // see parsePrototype()
+
+//! Accumulated modifiers of current statement, eg variable declaration.
+static SymbolModifiers currentModifiers;
+//! Holds program scope->symbol name->symbol modifiers.
+static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
+
+//-----------------------------------------------------------------------------
+
+static int yyread(char *buf,int max_size);
+static void startCommentBlock(bool);
+static void handleCommentBlock(const QCString &doc,bool brief);
+static void subrHandleCommentBlock(const QCString &doc,bool brief);
+static void addCurrentEntry(int case_insens);
+static void addModule(const char *name, bool isModule=FALSE);
+static void addSubprogram(const char *text);
+static void addInterface(QCString name, InterfaceType type);
+static Argument *getParameter(const QCString &name);
+static void scanner_abort();
+
+static void startScope(Entry *scope);
+static bool endScope(Entry *scope, bool isGlobalRoot=FALSE);
+//static bool isTypeName(QCString name);
+static void resolveModuleProcedures(QList<Entry> &moduleProcedures, Entry *current_root);
+static int getAmpersandAtTheStart(const char *buf, int length);
+static int getAmpOrExclAtTheEnd(const char *buf, int length);
+static void truncatePrepass(int index);
+static void pushBuffer(QCString &buffer);
+static void popBuffer();
+//static void extractPrefix(QCString& text);
+static QCString extractFromParens(const QCString name);
+static CommentInPrepass* locatePrepassComment(int from, int to);
+static void updateVariablePrepassComment(int from, int to);
+static void newLine();
+
+//-----------------------------------------------------------------------------
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+#define YY_USER_ACTION yyColNr+=(int)yyleng;
+//-----------------------------------------------------------------------------
+
+%}
+
+ //-----------------------------------------------------------------------------
+ //-----------------------------------------------------------------------------
+IDSYM [a-z_A-Z0-9]
+NOTIDSYM [^a-z_A-Z0-9]
+SEPARATE [:, \t]
+ID [a-z_A-Z%]+{IDSYM}*
+ID_ [a-z_A-Z%]*{IDSYM}*
+PP_ID {ID}
+LABELID [a-z_A-Z]+[a-z_A-Z0-9\-]*
+SUBPROG (subroutine|function)
+B [ \t]
+BS [ \t]*
+BS_ [ \t]+
+COMMA {BS},{BS}
+ARGS_L0 ("("[^)]*")")
+ARGS_L1a [^()]*"("[^)]*")"[^)]*
+ARGS_L1 ("("{ARGS_L1a}*")")
+ARGS_L2 "("({ARGS_L0}|[^()]|{ARGS_L1a}|{ARGS_L1})*")"
+ARGS {BS}({ARGS_L0}|{ARGS_L1}|{ARGS_L2})
+NOARGS {BS}"\n"
+
+NUM_TYPE (complex|integer|logical|real)
+LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
+KIND {ARGS}
+CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
+
+INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
+ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE)
+ACCESS_SPEC (PRIVATE|PUBLIC)
+LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")"
+/* Assume that attribute statements are almost the same as attributes. */
+ATTR_STMT {ATTR_SPEC}|DIMENSION|{ACCESS_SPEC}
+
+CONTAINS CONTAINS
+PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+SCOPENAME ({ID}{BS}"::"{BS})*
+
+%option noyywrap
+%option stack
+%option caseless
+/*%option debug */
+
+ //---------------------------------------------------------------------------------
+
+ /** fortran parsing states */
+%x Subprog
+%x SubprogPrefix
+%x Parameterlist
+%x SubprogBody
+%x SubprogBodyContains
+%x Start
+%x Comment
+%x Module
+%x Program
+%x ModuleBody
+%x ModuleBodyContains
+%x AttributeList
+%x Variable
+%x Initialization
+%x ArrayInitializer
+%x Typedef
+%x TypedefBody
+%x TypedefBodyContains
+%x InterfaceBody
+%x StrIgnore
+%x String
+%x Use
+%x UseOnly
+%x ModuleProcedure
+
+%x Prepass
+
+ /** comment parsing states */
+%x DocBlock
+%x DocBackLine
+%x EndDoc
+
+%x BlockData
+
+/** prototype parsing */
+%x Prototype
+%x PrototypeSubprog
+%x PrototypeArgs
+
+%%
+
+ /*-----------------------------------------------------------------------------------*/
+
+<*>^.*\n { // prepass: look for line continuations
+ functionLine = FALSE;
+
+ DBG_CTX((stderr, "---%s", yytext));
+
+ int indexStart = getAmpersandAtTheStart(yytext, (int)yyleng);
+ int indexEnd = getAmpOrExclAtTheEnd(yytext, (int)yyleng);
+ if (indexEnd>=0 && yytext[indexEnd]!='&') //we are only interested in amp
+ indexEnd=-1;
+
+ if(indexEnd<0){ // ----- no ampersand as line continuation
+ if(YY_START == Prepass) { // last line in "continuation"
+
+ // Only take input after initial ampersand
+ inputStringPrepass+=(const char*)(yytext+(indexStart+1));
+
+ //printf("BUFFER:%s\n", (const char*)inputStringPrepass);
+ pushBuffer(inputStringPrepass);
+ yyColNr = 0;
+ yy_pop_state();
+ } else { // simple line
+ yyColNr = 0;
+ REJECT;
+ }
+
+ } else { // ----- line with continuation
+ if(YY_START != Prepass) {
+ comments.setAutoDelete(TRUE);
+ comments.clear();
+ yy_push_state(Prepass);
+ }
+
+ int length = inputStringPrepass.length();
+
+ // Only take input after initial ampersand
+ inputStringPrepass+=(const char*)(yytext+(indexStart+1));
+ lineCountPrepass ++;
+
+ // cut off & and remove following comment if present
+ truncatePrepass(length+indexEnd-(indexStart+1));
+ }
+
+ }
+
+
+ /*------ ignore strings that are not initialization strings */
+<*>"\\\\" { if (yy_top_state() == Initialization
+ || yy_top_state() == ArrayInitializer)
+ initializer+=yytext;
+ }
+<*>"\\\""|\\\' { if (yy_top_state() == Initialization
+ || yy_top_state() == ArrayInitializer)
+ initializer+=yytext;
+ }
+<String>\"|\' { // string ends with next quote without previous backspace
+ if (yytext[0]!=stringStartSymbol) { yyColNr -= (int)yyleng; REJECT; } // single vs double quote
+ if (yy_top_state() == Initialization
+ || yy_top_state() == ArrayInitializer)
+ initializer+=yytext;
+ yy_pop_state();
+ }
+<String>. { if (yy_top_state() == Initialization
+ || yy_top_state() == ArrayInitializer)
+ initializer+=yytext;
+ }
+<*>\"|\' { /* string starts */
+ if (YY_START == StrIgnore) { yyColNr -= (int)yyleng; REJECT; }; // ignore in simple comments
+ yy_push_state(YY_START);
+ if (yy_top_state() == Initialization
+ || yy_top_state() == ArrayInitializer)
+ initializer+=yytext;
+ stringStartSymbol=yytext[0]; // single or double quote
+ BEGIN(String);
+ }
+
+ /*------ ignore simple comment (not documentation comments) */
+
+<*>"!"/[^<>\n] { if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings
+ // skip comment line (without docu comments "!>" "!<" )
+ /* ignore further "!" and ignore comments in Strings */
+ if ((YY_START != StrIgnore) && (YY_START != String))
+ {
+ yy_push_state(YY_START);
+ BEGIN(StrIgnore);
+ debugStr="*!";
+ DBG_CTX((stderr,"start comment %d\n",yyLineNr));
+ }
+ }
+<StrIgnore>.?/\n { yy_pop_state(); // comment ends with endline character
+ DBG_CTX((stderr,"end comment %d %s\n",yyLineNr,debugStr.data()));
+ } // comment line ends
+<StrIgnore>. { debugStr+=yytext; }
+
+
+ /*------ use handling ------------------------------------------------------------*/
+
+<Start,ModuleBody,SubprogBody>"use"{BS_} {
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+ yy_push_state(Use);
+ }
+<Use>{ID} {
+ DBG_CTX((stderr,"using dir %s\n",yytext));
+ current->name=yytext;
+ current->fileName = yyFileName;
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ current->lang = SrcLangExt_Fortran;
+ yy_pop_state();
+ }
+<Use>{ID}/, {
+ useModuleName=yytext;
+ }
+<Use>,{BS}"ONLY" { BEGIN(UseOnly);
+ }
+<UseOnly>{BS},{BS} {}
+<UseOnly>{ID} {
+ current->name= useModuleName+"::"+yytext;
+ current->fileName = yyFileName;
+ current->section=Entry::USINGDECL_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ current->lang = SrcLangExt_Fortran;
+ }
+<Use,UseOnly>"\n" {
+ yyColNr -= 1;
+ unput(*yytext);
+ yy_pop_state();
+ }
+
+ /* INTERFACE definitions */
+<Start,ModuleBody,SubprogBody>{
+^{BS}interface{IDSYM}+ { /* variable with interface prefix */ }
+^{BS}interface { ifType = IF_SPECIFIC;
+ yy_push_state(InterfaceBody);
+ // do not start a scope here, every
+ // interface body is a scope of its own
+ }
+
+^{BS}abstract{BS_}interface { ifType = IF_ABSTRACT;
+ yy_push_state(InterfaceBody);
+ // do not start a scope here, every
+ // interface body is a scope of its own
+ }
+
+^{BS}interface{BS_}{ID}{ARGS}? { ifType = IF_GENERIC;
+ yy_push_state(InterfaceBody);
+
+ // extract generic name
+ QCString name = QCString(yytext).stripWhiteSpace();
+ name = name.right(name.length() - 9).stripWhiteSpace().lower();
+ addInterface(name, ifType);
+ startScope(last_entry);
+ }
+}
+
+<InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? {
+ // end scope only if GENERIC interface
+ if (ifType == IF_GENERIC && !endScope(current_root))
+ yyterminate();
+
+ ifType = IF_NONE;
+ yy_pop_state();
+ }
+<InterfaceBody>module{BS}procedure { yy_push_state(YY_START);
+ BEGIN(ModuleProcedure);
+ }
+<ModuleProcedure>{ID} { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ {
+ addInterface(yytext, ifType);
+ startScope(last_entry);
+ }
+
+ current->section = Entry::FUNCTION_SEC ;
+ current->name = yytext;
+ moduleProcedures.append(current);
+ addCurrentEntry(1);
+ }
+<ModuleProcedure>"\n" { yyColNr -= 1;
+ unput(*yytext);
+ yy_pop_state();
+ }
+<InterfaceBody>. {}
+
+ /*-- Contains handling --*/
+<Start>^{BS}{CONTAINS}/({BS}|\n|!) {
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBodyContains); //anon program
+ }
+ }
+<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(ModuleBodyContains); }
+<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(SubprogBodyContains); }
+<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); }
+
+ /*------ module handling ------------------------------------------------------------*/
+<Start>block{BS}data{BS}{ID_} { //
+ v_type = V_IGNORE;
+ yy_push_state(BlockData);
+ defaultProtection = Public;
+ }
+<Start>module|program{BS_} { //
+ v_type = V_IGNORE;
+ if(yytext[0]=='m' || yytext[0]=='M')
+ yy_push_state(Module);
+ else
+ yy_push_state(Program);
+ defaultProtection = Public;
+ }
+<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!) { // end block data
+ //if (!endScope(current_root))
+ // yyterminate();
+ defaultProtection = Public;
+ yy_pop_state();
+ }
+<Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module
+ resolveModuleProcedures(moduleProcedures, current_root);
+ if (!endScope(current_root))
+ yyterminate();
+ defaultProtection = Public;
+ yy_pop_state();
+ }
+<Module>{ID} {
+ addModule(yytext, TRUE);
+ BEGIN(ModuleBody);
+ }
+
+<Program>{ID} {
+ addModule(yytext, FALSE);
+ BEGIN(ModuleBody);
+ }
+
+ /*------- access specification --------------------------------------------------------------------------*/
+
+<ModuleBody>private/{BS}(\n|"!") { defaultProtection = Private;
+ current->protection = defaultProtection ;
+ }
+<ModuleBody>public/{BS}(\n|"!") { defaultProtection = Public;
+ current->protection = defaultProtection ;
+ }
+
+ /*------- type definition -------------------------------------------------------------------------------*/
+
+<Start,ModuleBody>^{BS}type/[^a-z0-9_] {
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+
+ yy_push_state(Typedef);
+ current->protection = defaultProtection;
+ typeProtection = defaultProtection;
+ typeMode = true;
+ }
+<Typedef>{
+{COMMA} {}
+
+{BS}"::"{BS} {}
+
+abstract {
+ current->spec |= Entry::AbstractClass;
+ }
+extends{ARGS} {
+ QCString basename = extractFromParens(yytext);
+ current->extends->append(new BaseInfo(basename, Public, Normal));
+ }
+public {
+ current->protection = Public;
+ typeProtection = Public;
+ }
+private {
+ current->protection = Private;
+ typeProtection = Private;
+ }
+{LANGUAGE_BIND_SPEC} {
+ /* ignored for now */
+ }
+{ID} { /* type name found */
+ current->section = Entry::CLASS_SEC;
+ current->spec |= Entry::Struct;
+ current->name = yytext;
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr;
+
+ /* if type is part of a module, mod name is necessary for output */
+ if ((current_root) &&
+ (current_root->section == Entry::CLASS_SEC
+ || current_root->section == Entry::NAMESPACE_SEC))
+ {
+ current->name = current_root->name + "::" + current->name;
+ }
+
+ addCurrentEntry(1);
+ startScope(last_entry);
+ BEGIN(TypedefBody);
+ }
+}
+
+<TypedefBodyContains>{ /* Type Bound Procedures */
+^{BS}PROCEDURE{ARGS}? {
+ current->type = QCString(yytext).simplifyWhiteSpace();
+ }
+^{BS}final {
+ current->spec |= Entry::Final;
+ current->type = QCString(yytext).simplifyWhiteSpace();
+ }
+^{BS}generic {
+ current->type = QCString(yytext).simplifyWhiteSpace();
+ }
+{COMMA} {
+ }
+{ATTR_SPEC} {
+ currentModifiers |= QCString(yytext);
+ }
+{BS}"::"{BS} {
+ }
+{ID} {
+ QCString name = yytext;
+ modifiers[current_root][name.lower()] |= currentModifiers;
+ current->section = Entry::FUNCTION_SEC;
+ current->name = name;
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr;
+ addCurrentEntry(1);
+ }
+{BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */
+ last_entry->args = yytext;
+ }
+"\n" {
+ currentModifiers = SymbolModifiers();
+ newLine();
+ docBlock.resize(0);
+ }
+}
+
+
+<TypedefBody,TypedefBodyContains>{
+^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */
+ if (!endScope(current_root))
+ yyterminate();
+ typeMode = false;
+ yy_pop_state();
+ }
+}
+
+ /*------- module/global/typedef variable ---------------------------------------------------*/
+
+<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!) {
+ //
+ // ABSTRACT and specific interfaces are stored
+ // in a scope of their own, even if multiple
+ // are group in one INTERFACE/END INTERFACE block.
+ //
+ if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ endScope(current_root);
+
+ if (!endScope(current_root))
+ yyterminate();
+ subrCurrent.remove(0u);
+ yy_pop_state() ;
+ }
+<BlockData>{
+{ID} {
+ }
+}
+<Start,ModuleBody,TypedefBody,SubprogBody>{
+^{BS}{TYPE_SPEC}/{SEPARATE} {
+ /* variable declaration starts */
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+ argType = QCString(yytext).simplifyWhiteSpace().lower();
+ yy_push_state(AttributeList);
+ }
+ /* Dimitri: macro expansion should already be done during preprocessing not here!
+^{BS}{PP_ID}{KIND}? { // check for preprocessor symbol expand to type
+ QCString str = yytext;
+ str = str.stripWhiteSpace();
+ //DefineDict* defines = getGlobalDefineDict();
+ QCString name;
+ int index = str.find("(");
+ if (index != -1)
+ name = str.left(index).stripWhiteSpace();
+ else
+ name = str;
+
+ Define *define = 0; //(*defines)[name];
+ if (define != 0 && isTypeName(define->definition))
+ {
+ argType = str;
+ yy_push_state(AttributeList);
+ }
+ else
+ {
+ yyColNr -= (int)yyleng;
+ REJECT;
+ }
+ }
+ */
+{ATTR_STMT}/{BS_}{ID} |
+{ATTR_STMT}/{BS}"::" {
+ /* attribute statement starts */
+ DBG_CTX((stderr,"5=========> Attribute statement: %s\n", yytext));
+ QCString tmp = yytext;
+ currentModifiers |= tmp.stripWhiteSpace();
+ argType="";
+ yy_push_state(YY_START);
+ BEGIN( AttributeList ) ;
+ }
+{ID} {
+ }
+^{BS}"type"{BS_}"is"/{BS_} { }
+^{BS}"type"{BS}"=" { }
+}
+<AttributeList>{
+{COMMA} {}
+{BS} {}
+{ATTR_SPEC}. { /* update current modifierswhen it is an ATTR_SPEC and not a variable name */
+ /* bug_625519 */
+ QChar chr = yytext[(int)yyleng-1];
+ if (chr.isLetter() || chr.isDigit() || (chr == '_'))
+ {
+ yyColNr -= (int)yyleng;
+ REJECT;
+ }
+ else
+ {
+ QCString tmp = yytext;
+ tmp = tmp.left(tmp.length() - 1);
+ yyColNr -= 1;
+ unput(yytext[(int)yyleng-1]);
+ currentModifiers |= (tmp);
+ }
+ }
+"::" { /* end attribute list */
+ BEGIN( Variable );
+ }
+. { /* unknown attribute, consider variable name */
+ //cout<<"start variables, unput "<<*yytext<<endl;
+ yyColNr -= 1;
+ unput(*yytext);
+ BEGIN( Variable );
+ }
+}
+
+<Variable>{BS} { }
+<Variable>{ID} { /* parse variable declaration */
+ //cout << "5=========> got variable: " << argType << "::" << yytext << endl;
+ /* work around for bug in QCString.replace (QCString works) */
+ QCString name=yytext;
+ name = name.lower();
+ /* remember attributes for the symbol */
+ modifiers[current_root][name.lower()] |= currentModifiers;
+ argName= name;
+
+ v_type= V_IGNORE;
+ if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
+ { // new variable entry
+ v_type = V_VARIABLE;
+ current->section = Entry::VARIABLE_SEC;
+ current->name = argName;
+ current->type = argType;
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr; // used for source reference
+ addCurrentEntry(1);
+ }
+ else if (!argType.isEmpty())
+ { // declaration of parameter list: add type for corr. parameter
+ parameter = getParameter(argName);
+ if (parameter)
+ {
+ v_type= V_PARAMETER;
+ if (!argType.isNull()) parameter->type=argType.stripWhiteSpace();
+ if (!docBlock.isNull())
+ {
+ subrHandleCommentBlock(docBlock,TRUE);
+ }
+ }
+ // save, it may be function return type
+ if (parameter)
+ {
+ modifiers[current_root][name.lower()].type = argType;
+ }
+ else
+ {
+ if ((current_root->name.lower() == argName.lower()) ||
+ (modifiers[current_root->parent()][current_root->name.lower()].returnName.lower() == argName.lower()))
+ {
+ int strt = current_root->type.find("function");
+ QCString lft;
+ QCString rght;
+ if (strt != -1)
+ {
+ lft = "";
+ rght = "";
+ if (strt != 0) lft = current_root->type.left(strt).stripWhiteSpace();
+ if ((current_root->type.length() - strt - strlen("function"))!= 0)
+ {
+ rght = current_root->type.right(current_root->type.length() - strt - strlen("function")).stripWhiteSpace();
+ }
+ current_root->type = lft;
+ if (rght.length() > 0)
+ {
+ if (current_root->type.length() > 0) current_root->type += " ";
+ current_root->type += rght;
+ }
+ if (argType.stripWhiteSpace().length() > 0)
+ {
+ if (current_root->type.length() > 0) current_root->type += " ";
+ current_root->type += argType.stripWhiteSpace();
+ }
+ if (current_root->type.length() > 0) current_root->type += " ";
+ current_root->type += "function";
+ }
+ else
+ {
+ current_root->type += " " + argType.stripWhiteSpace();
+ }
+ current_root->type = current_root->type.stripWhiteSpace();
+ modifiers[current_root][name.lower()].type = current_root->type;
+ }
+ else
+ {
+ modifiers[current_root][name.lower()].type = argType;
+ }
+ }
+ // any accumulated doc for argument should be emptied,
+ // because it is handled other way and this doc can be
+ // unexpectedly passed to the next member.
+ current->doc.resize(0);
+ current->brief.resize(0);
+ }
+ }
+<Variable>{ARGS} { /* dimension of the previous entry. */
+ QCString name(argName);
+ QCString attr("dimension");
+ attr += yytext;
+ modifiers[current_root][name.lower()] |= attr;
+ }
+<Variable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyColNr-(int)yyleng, yyColNr);
+ // locate !< comment
+ updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
+ }
+<Variable>{BS}"=" { yy_push_state(YY_START);
+ initializer="=";
+ initializerScope = initializerArrayScope = 0;
+ BEGIN(Initialization);
+ }
+<Variable>"\n" { currentModifiers = SymbolModifiers();
+ yy_pop_state(); // end variable declaration list
+ newLine();
+ docBlock.resize(0);
+ }
+<Variable>";".*"\n" { currentModifiers = SymbolModifiers();
+ yy_pop_state(); // end variable declaration list
+ docBlock.resize(0);
+ inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
+ yyLineNr--;
+ pushBuffer(inputStringSemi);
+ }
+<*>";".*"\n" {
+ if (YY_START == Variable) REJECT; // Just be on the safe side
+ if (YY_START == String) REJECT; // ";" ignored in strings
+ if (YY_START == StrIgnore) REJECT; // ";" ignored in regular comments
+ inputStringSemi =(const char*)(QCString(" \n") + QCString(yytext+1)).data();
+ yyLineNr--;
+ pushBuffer(inputStringSemi);
+ }
+
+<Initialization,ArrayInitializer>"[" |
+<Initialization,ArrayInitializer>"(/" { initializer+=yytext;
+ initializerArrayScope++;
+ BEGIN(ArrayInitializer); // initializer may contain comma
+ }
+<ArrayInitializer>"]" |
+<ArrayInitializer>"/)" { initializer+=yytext;
+ initializerArrayScope--;
+ if(initializerArrayScope<=0)
+ {
+ initializerArrayScope = 0; // just in case
+ BEGIN(Initialization);
+ }
+ }
+<ArrayInitializer>. { initializer+=yytext; }
+<Initialization>"(" { initializerScope++;
+ initializer+=yytext;
+ }
+<Initialization>")" { initializerScope--;
+ initializer+=yytext;
+ }
+<Initialization>{COMMA} { if (initializerScope == 0)
+ {
+ updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
+ yy_pop_state(); // end initialization
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ }
+ else
+ initializer+=", ";
+ }
+<Initialization>"\n"|"!" { //|
+ yy_pop_state(); // end initialization
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ yyColNr -= 1;
+ unput(*yytext);
+ }
+<Initialization>. { initializer+=yytext; }
+
+ /*------ fortran subroutine/function handling ------------------------------------------------------------*/
+ /* Start is initial condition */
+
+<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}({PREFIX}{BS_})?/{SUBPROG}{BS_} {
+ if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ {
+ addInterface("$interface$", ifType);
+ startScope(last_entry);
+ }
+
+ // TYPE_SPEC is for old function style function result
+ result = QCString(yytext).stripWhiteSpace().lower();
+ current->type = result;
+ yy_push_state(SubprogPrefix);
+ }
+
+<SubprogPrefix>{BS}{SUBPROG}{BS_} {
+ // Fortran subroutine or function found
+ v_type = V_IGNORE;
+ result=yytext;
+ result=result.stripWhiteSpace();
+ addSubprogram(result);
+ BEGIN(Subprog);
+ }
+
+<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{SUBPROG}{BS_} {
+ // Fortran subroutine or function found
+ v_type = V_IGNORE;
+ if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ {
+ addInterface("$interface$", ifType);
+ startScope(last_entry);
+ }
+
+ result = QCString(yytext).stripWhiteSpace();
+ addSubprogram(result);
+ yy_push_state(Subprog);
+ }
+
+<Subprog>{BS} { /* ignore white space */ }
+<Subprog>{ID} { current->name = yytext;
+ //cout << "1a==========> got " << current->type << " " << yytext << " " << yyLineNr << endl;
+ modifiers[current_root][current->name.lower()].returnName = current->name.lower();
+
+ if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
+ {
+ current_root->name.replace(QRegExp("\\$interface\\$"), yytext);
+ }
+
+ BEGIN(Parameterlist);
+ }
+<Parameterlist>"(" { current->args = "("; }
+<Parameterlist>")" {
+ current->args += ")";
+ current->args = removeRedundantWhiteSpace(current->args);
+ addCurrentEntry(1);
+ startScope(last_entry);
+ BEGIN(SubprogBody);
+ }
+<Parameterlist>{COMMA}|{BS} { current->args += yytext;
+ CommentInPrepass *c = locatePrepassComment(yyColNr-(int)yyleng, yyColNr);
+ if (c!=NULL) {
+ if(current->argList->count()>0) {
+ current->argList->at(current->argList->count()-1)->docs = c->str;
+ }
+ }
+ }
+<Parameterlist>{ID} {
+ //current->type not yet available
+ QCString param = yytext;
+ // std::cout << "3=========> got parameter " << param << std::endl;
+ current->args += param;
+ Argument *arg = new Argument;
+ arg->name = param;
+ arg->type = "";
+ current->argList->append(arg);
+ }
+<Parameterlist>{NOARGS} {
+ newLine();
+ //printf("3=========> without parameterlist \n");
+ //current->argList = ;
+ addCurrentEntry(1);
+ startScope(last_entry);
+ BEGIN(SubprogBody);
+}
+<SubprogBody>result{BS}\({BS}{ID} {
+ if (functionLine)
+ {
+ result= yytext;
+ result= result.right(result.length()-result.find("(")-1);
+ result= result.stripWhiteSpace();
+ modifiers[current_root->parent()][current_root->name.lower()].returnName = result;
+ }
+ //cout << "=====> got result " << result << endl;
+ }
+
+ /*---- documentation comments --------------------------------------------------------------------*/
+
+<Variable,SubprogBody,ModuleBody,TypedefBody,TypedefBodyContains>"!<" { /* backward docu comment */
+ if (v_type != V_IGNORE) {
+ current->docLine = yyLineNr;
+ docBlockJavaStyle = FALSE;
+ docBlock.resize(0);
+ docBlockJavaStyle = Config_getBool("JAVADOC_AUTOBRIEF");
+ startCommentBlock(TRUE);
+ yy_push_state(DocBackLine);
+ }
+ else
+ {
+ /* handle out of place !< comment as a normal comment */
+ if (YY_START == String) { yyColNr -= (int)yyleng; REJECT; } // "!" is ignored in strings
+ // skip comment line (without docu comments "!>" "!<" )
+ /* ignore further "!" and ignore comments in Strings */
+ if ((YY_START != StrIgnore) && (YY_START != String))
+ {
+ yy_push_state(YY_START);
+ BEGIN(StrIgnore);
+ debugStr="*!";
+ //fprintf(stderr,"start comment %d\n",yyLineNr);
+ }
+ }
+ }
+<DocBackLine>.* { // contents of current comment line
+ docBlock+=yytext;
+ }
+<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line)
+ docBlock+="\n"; // \n is necessary for lists
+ newLine();
+ }
+<DocBackLine>"\n" { // comment block ends at the end of this line
+ //cout <<"3=========> comment block : "<< docBlock << endl;
+ yyColNr -= 1;
+ unput(*yytext);
+ if (v_type == V_VARIABLE)
+ {
+ Entry *tmp_entry = current;
+ current = last_entry; // temporarily switch to the previous entry
+ handleCommentBlock(docBlock,TRUE);
+ current=tmp_entry;
+ }
+ else if (v_type == V_PARAMETER)
+ {
+ subrHandleCommentBlock(docBlock,TRUE);
+ }
+ yy_pop_state();
+ docBlock.resize(0);
+ }
+
+<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>" {
+ yy_push_state(YY_START);
+ current->docLine = yyLineNr;
+ docBlockJavaStyle = FALSE;
+ if (YY_START==SubprogBody) docBlockInBody = TRUE;
+ docBlock.resize(0);
+ docBlockJavaStyle = Config_getBool("JAVADOC_AUTOBRIEF");
+ startCommentBlock(TRUE);
+ BEGIN(DocBlock);
+ //cout << "start DocBlock " << endl;
+ }
+
+<DocBlock>.* { // contents of current comment line
+ docBlock+=yytext;
+ }
+<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line)
+ docBlock+="\n"; // \n is necessary for lists
+ newLine();
+ }
+<DocBlock>"\n" { // comment block ends at the end of this line
+ //cout <<"3=========> comment block : "<< docBlock << endl;
+ yyColNr -= 1;
+ unput(*yytext);
+ handleCommentBlock(docBlock,TRUE);
+ yy_pop_state();
+ }
+
+ /*-----Prototype parsing -------------------------------------------------------------------------*/
+<Prototype>{BS}{SUBPROG}{BS_} {
+ BEGIN(PrototypeSubprog);
+ }
+<Prototype,PrototypeSubprog>{BS}{SCOPENAME}?{BS}{ID} {
+ current->name = QCString(yytext).lower();
+ current->name.stripWhiteSpace();
+ BEGIN(PrototypeArgs);
+ }
+<PrototypeArgs>{
+"("|")"|","|{BS_} { current->args += yytext; }
+{ID} { current->args += yytext;
+ Argument *a = new Argument;
+ a->name = QCString(yytext).lower();
+ current->argList->append(a);
+ }
+}
+
+ /*------------------------------------------------------------------------------------------------*/
+
+<*>"\n" {
+ newLine();
+ //if (debugStr.stripWhiteSpace().length() > 0) cout << "ignored text: " << debugStr << " state: " <<YY_START << endl;
+ debugStr="";
+ }
+
+
+ /*---- error: EOF in wrong state --------------------------------------------------------------------*/
+
+<*><<EOF>> {
+ if (parsingPrototype) {
+ yyterminate();
+
+ } else if ( include_stack_ptr <= 0 ) {
+ if (YY_START!=INITIAL && YY_START!=Start) {
+ DBG_CTX((stderr,"==== Error: EOF reached in wrong state (end missing)"));
+ scanner_abort();
+ }
+ yyterminate();
+ } else {
+ popBuffer();
+ }
+ }
+<*>{LOG_OPER} { // Fortran logical comparison keywords
+ }
+<*>. {
+ //debugStr+=yytext;
+ //printf("I:%c\n", *yytext);
+ } // ignore remaining text
+
+ /**********************************************************************************/
+ /**********************************************************************************/
+ /**********************************************************************************/
+%%
+//----------------------------------------------------------------------------
+
+#if 0
+static void extractPrefix(QCString &text)
+{
+ int prefixIndex = 0;
+ int curIndex = 0;
+ bool cont = TRUE;
+ const char* pre[] = {"RECURSIVE","IMPURE","PURE","ELEMENTAL"};
+ while(cont)
+ {
+ cont = FALSE;
+ for(unsigned int i=0; i<4; i++)
+ {
+ if((prefixIndex=text.find(pre[i], curIndex, FALSE))==0)
+ {
+ text.remove(0,strlen(pre[i]));
+ text.stripWhiteSpace();
+ cont = TRUE;
+ }
+ }
+ }
+}
+#endif
+
+static void newLine() {
+ yyLineNr++;
+ yyLineNr+=lineCountPrepass;
+ lineCountPrepass=0;
+ comments.clear();
+}
+
+static CommentInPrepass* locatePrepassComment(int from, int to) {
+ //printf("Locate %d-%d\n", from, to);
+ for(uint i=0; i<comments.count(); i++) { // todo: optimize
+ int c = comments.at(i)->column;
+ //printf("Candidate %d\n", c);
+ if (c>=from && c<=to) {
+ // comment for previous variable or parameter
+ return comments.at(i);
+ }
+ }
+ return NULL;
+}
+
+static void updateVariablePrepassComment(int from, int to) {
+ CommentInPrepass *c = locatePrepassComment(from, to);
+ if (c!=NULL && v_type == V_VARIABLE) {
+ last_entry->brief = c->str;
+ } else if (c!=NULL && v_type == V_PARAMETER) {
+ Argument *parameter = getParameter(argName);
+ if (parameter) parameter->docs = c->str;
+ }
+}
+
+static int getAmpersandAtTheStart(const char *buf, int length)
+{
+ for(int i=0; i<length; i++) {
+ switch(buf[i]) {
+ case ' ':
+ case '\t':
+ break;
+ case '&':
+ return i;
+ default:
+ return -1;
+ }
+ }
+ return -1;
+}
+
+/* Returns ampersand index, comment start index or -1 if neither exist.*/
+static int getAmpOrExclAtTheEnd(const char *buf, int length)
+{
+ // Avoid ampersands in string and comments
+ int parseState = Start;
+ char quoteSymbol = 0;
+ int ampIndex = -1;
+ int commentIndex = -1;
+
+ for(int i=0; i<length && parseState!=Comment; i++)
+ {
+ // When in string, skip backslashes
+ // Legacy code, not sure whether this is correct?
+ if(parseState==String)
+ {
+ if(buf[i]=='\\') i++;
+ }
+
+ switch(buf[i])
+ {
+ case '\'':
+ case '"':
+ // Close string, if quote symbol matches.
+ // Quote symbol is set iff parseState==String
+ if(buf[i]==quoteSymbol)
+ {
+ parseState = Start;
+ quoteSymbol = 0;
+ }
+ // Start new string, if not already in string or comment
+ else if(parseState==Start)
+ {
+ parseState = String;
+ quoteSymbol = buf[i];
+ }
+ ampIndex = -1; // invalidate prev ampersand
+ break;
+ case '!':
+ // When in string or comment, ignore exclamation mark
+ if(parseState==Start)
+ {
+ parseState = Comment;
+ commentIndex = i;
+ }
+ break;
+ case ' ': // ignore whitespace
+ case '\t':
+ case '\n': // this may be at the end of line
+ break;
+ case '&':
+ ampIndex = i;
+ break;
+ default:
+ ampIndex = -1; // invalidate prev ampersand
+ }
+ }
+
+ if (ampIndex>=0)
+ return ampIndex;
+ else
+ return commentIndex;
+}
+
+/* Although comments at the end of continuation line are grabbed by this function,
+* we still do not know how to use them later in parsing.
+*/
+void truncatePrepass(int index)
+{
+ int length = inputStringPrepass.length();
+ for (int i=index+1; i<length; i++) {
+ if (inputStringPrepass[i]=='!' && i<length-1 && inputStringPrepass[i+1]=='<') { // save comment
+ struct CommentInPrepass *c=new CommentInPrepass(index, inputStringPrepass.right(length-i-2));
+ comments.append(c);
+ }
+ }
+ inputStringPrepass.truncate(index);
+}
+
+// simplified way to know if this is fixed form
+// duplicate in fortrancode.l
+static bool recognizeFixedForm(const char* contents, FortranFormat format)
+{
+ int column=0;
+ bool skipLine=FALSE;
+
+ if (format == FortranFormat_Fixed) return TRUE;
+ if (format == FortranFormat_Free) return FALSE;
+
+ for(int i=0;;i++) {
+ column++;
+
+ switch(contents[i]) {
+ case '\n':
+ column=0;
+ skipLine=FALSE;
+ break;
+ case ' ':
+ break;
+ case '\000':
+ return FALSE;
+ case '#':
+ skipLine=TRUE;
+ break;
+ case 'C':
+ case 'c':
+ case '*':
+ if(column==1) return TRUE;
+ if(skipLine) break;
+ return FALSE;
+ case '!':
+ if(column>1 && column<7) return FALSE;
+ skipLine=TRUE;
+ break;
+ default:
+ if(skipLine) break;
+ if(column==7) return TRUE;
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+/* This function assumes that contents has at least size=length+1 */
+static void insertCharacter(char *contents, int length, int pos, char c)
+{
+ // shift tail by one character
+ for(int i=length; i>pos; i--)
+ contents[i]=contents[i-1];
+ // set the character
+ contents[pos] = c;
+}
+
+/* change comments and bring line continuation character to previous line */
+static const char* prepassFixedForm(const char* contents)
+{
+ int column=0;
+ int prevLineLength=0;
+ int prevLineAmpOrExclIndex=-1;
+ bool emptyLabel=TRUE;
+ int newContentsSize = strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation)
+ char* newContents = (char*)malloc(newContentsSize);
+
+ for(int i=0, j=0;;i++,j++) {
+ if(j>=newContentsSize-1) { // check for one spare character, which may be eventually used below (by &)
+ newContents = (char*)realloc(newContents, newContentsSize+1000);
+ newContentsSize = newContentsSize+1000;
+ }
+
+ column++;
+ char c = contents[i];
+ switch(c) {
+ case '\n':
+ prevLineLength=column;
+ prevLineAmpOrExclIndex=getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength);
+ column=0;
+ emptyLabel=TRUE;
+ newContents[j]=c;
+ break;
+ case ' ':
+ newContents[j]=c;
+ break;
+ case '\000':
+ newContents[j]='\000';
+ newContentsSize = strlen(newContents);
+ if (newContents[newContentsSize - 1] != '\n')
+ {
+ // to be on the safe side
+ newContents = (char*)realloc(newContents, newContentsSize+2);
+ newContents[newContentsSize] = '\n';
+ newContents[newContentsSize + 1] = '\000';
+ }
+ return newContents;
+ case 'C':
+ case 'c':
+ case '*':
+ if (column!=6)
+ {
+ emptyLabel=FALSE;
+ if(column==1)
+ newContents[j]='!';
+ else
+ newContents[j]=c;
+ break;
+ }
+ default:
+ if(column==6 && emptyLabel) { // continuation
+ if (c != '0') { // 0 not allowed as continuatioin character, see f95 standard paragraph 3.3.2.3
+ newContents[j]=' ';
+
+ if(prevLineAmpOrExclIndex==-1) { // add & just before end of previous line
+ insertCharacter(newContents, j+1, (j+1)-6-1, '&');
+ j++;
+ } else { // add & just before end of previous line comment
+ insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex, '&');
+ j++;
+ }
+ } else {
+ newContents[j]=c; // , just handle like space
+ }
+ } else {
+ newContents[j]=c;
+ emptyLabel=FALSE;
+ }
+ break;
+ }
+ }
+
+ newContentsSize = strlen(newContents);
+ if (newContents[newContentsSize - 1] != '\n')
+ {
+ // to be on the safe side
+ newContents = (char*)realloc(newContents, newContentsSize+2);
+ newContents[newContentsSize] = '\n';
+ newContents[newContentsSize + 1] = '\000';
+ }
+ return newContents;
+}
+
+static void pushBuffer(QCString& buffer)
+{
+ if (include_stack_cnt <= include_stack_ptr)
+ {
+ include_stack_cnt++;
+ include_stack = (YY_BUFFER_STATE *)realloc(include_stack, include_stack_cnt * sizeof(YY_BUFFER_STATE));
+ }
+ include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_scan_string(buffer));
+
+ DBG_CTX((stderr, "--PUSH--%s", (const char *)buffer));
+ buffer = NULL;
+}
+
+static void popBuffer() {
+ DBG_CTX((stderr, "--POP--"));
+ include_stack_ptr --;
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ yy_switch_to_buffer( include_stack[include_stack_ptr] );
+}
+
+/** used to copy entry to an interface module procedure */
+static void copyEntry(Entry *dest, Entry *src)
+{
+ dest->type = src->type;
+ dest->fileName = src->fileName;
+ dest->bodyLine = src->bodyLine;
+ dest->args = src->args;
+ dest->argList = new ArgumentList(*src->argList);
+ dest->doc = src->doc;
+ dest->brief = src->brief;
+}
+
+/** fill empty interface module procedures with info from
+ corresponding module subprogs
+ @TODO: handle procedures in used modules
+*/
+void resolveModuleProcedures(QList<Entry> &moduleProcedures, Entry *current_root)
+{
+ if (moduleProcedures.isEmpty()) return;
+
+ EntryListIterator eli1(moduleProcedures);
+ // for all module procedures
+ for (Entry *ce1; (ce1=eli1.current()); ++eli1)
+ {
+ // check all entries in this module
+ EntryListIterator eli2(*current_root->children());
+ for (Entry *ce2; (ce2=eli2.current()); ++eli2)
+ {
+ if (ce1->name == ce2->name)
+ {
+ copyEntry(ce1, ce2);
+ }
+ } // for procedures in current module
+ } // for all interface module procedures
+ moduleProcedures.clear();
+}
+
+#if 0
+static bool isTypeName(QCString name)
+{
+ name = name.lower();
+ return name=="integer" || name == "real" ||
+ name=="complex" || name == "logical";
+}
+#endif
+
+/*! Extracts string which resides within parentheses of provided string. */
+static QCString extractFromParens(const QCString name)
+{
+ QCString extracted = name;
+ int start = extracted.find("(");
+ if (start != -1)
+ {
+ extracted.remove(0, start+1);
+ }
+ int end = extracted.findRev(")");
+ if (end != -1)
+ {
+ int length = extracted.length();
+ extracted.remove(end, length);
+ }
+ extracted = extracted.stripWhiteSpace();
+
+ return extracted;
+}
+
+/*! Adds passed modifiers to these modifiers.*/
+SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs)
+{
+ if (mdfs.protection!=NONE_P) protection = mdfs.protection;
+ if (mdfs.direction!=NONE_D) direction = mdfs.direction;
+ optional |= mdfs.optional;
+ if (!mdfs.dimension.isNull()) dimension = mdfs.dimension;
+ allocatable |= mdfs.allocatable;
+ external |= mdfs.external;
+ intrinsic |= mdfs.intrinsic;
+ protect |= mdfs.protect;
+ parameter |= mdfs.parameter;
+ pointer |= mdfs.pointer;
+ target |= mdfs.target;
+ save |= mdfs.save;
+ deferred |= mdfs.deferred;
+ nonoverridable |= mdfs.nonoverridable;
+ nopass |= mdfs.nopass;
+ pass |= mdfs.pass;
+ passVar = mdfs.passVar;
+ return *this;
+}
+
+/*! Extracts and adds passed modifier to these modifiers.*/
+SymbolModifiers& SymbolModifiers::operator|=(QCString mdfString)
+{
+ mdfString = mdfString.lower();
+ SymbolModifiers newMdf;
+
+ if (mdfString.find("dimension")==0)
+ {
+ newMdf.dimension=mdfString;
+ }
+ else if (mdfString.contains("intent"))
+ {
+ QCString tmp = extractFromParens(mdfString);
+ bool isin = tmp.contains("in");
+ bool isout = tmp.contains("out");
+ if (isin && isout) newMdf.direction = SymbolModifiers::INOUT;
+ else if (isin) newMdf.direction = SymbolModifiers::IN;
+ else if (isout) newMdf.direction = SymbolModifiers::OUT;
+ }
+ else if (mdfString=="public")
+ {
+ newMdf.protection = SymbolModifiers::PUBLIC;
+ }
+ else if (mdfString=="private")
+ {
+ newMdf.protection = SymbolModifiers::PRIVATE;
+ }
+ else if (mdfString=="protected")
+ {
+ newMdf.protect = TRUE;
+ }
+ else if (mdfString=="optional")
+ {
+ newMdf.optional = TRUE;
+ }
+ else if (mdfString=="allocatable")
+ {
+ newMdf.allocatable = TRUE;
+ }
+ else if (mdfString=="external")
+ {
+ newMdf.external = TRUE;
+ }
+ else if (mdfString=="intrinsic")
+ {
+ newMdf.intrinsic = TRUE;
+ }
+ else if (mdfString=="parameter")
+ {
+ newMdf.parameter = TRUE;
+ }
+ else if (mdfString=="pointer")
+ {
+ newMdf.pointer = TRUE;
+ }
+ else if (mdfString=="target")
+ {
+ newMdf.target = TRUE;
+ }
+ else if (mdfString=="save")
+ {
+ newMdf.save = TRUE;
+ }
+ else if (mdfString=="nopass")
+ {
+ newMdf.nopass = TRUE;
+ }
+ else if (mdfString=="deferred")
+ {
+ newMdf.deferred = TRUE;
+ }
+ else if (mdfString=="non_overridable")
+ {
+ newMdf.nonoverridable = TRUE;
+ }
+ else if (mdfString.contains("pass"))
+ {
+ newMdf.pass = TRUE;
+ if (mdfString.contains("("))
+ newMdf.passVar = extractFromParens(mdfString);
+ else
+ newMdf.passVar = "";
+ }
+
+ (*this) |= newMdf;
+ return *this;
+}
+
+/*! For debugging purposes. */
+//ostream& operator<<(ostream& out, const SymbolModifiers& mdfs)
+//{
+// out<<mdfs.protection<<", "<<mdfs.direction<<", "<<mdfs.optional<<
+// ", "<<(mdfs.dimension.isNull() ? "" : mdfs.dimension.latin1())<<
+// ", "<<mdfs.allocatable<<", "<<mdfs.external<<", "<<mdfs.intrinsic;
+//
+// return out;
+//}
+
+/*! Find argument with given name in \a subprog entry. */
+static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = FALSE)
+{
+ QCString cname(name.lower());
+ for (unsigned int i=0; i<subprog->argList->count(); i++)
+ {
+ Argument *arg = subprog->argList->at(i);
+ if ((!byTypeName && arg->name.lower() == cname) ||
+ (byTypeName && arg->type.lower() == cname)
+ )
+ {
+ return arg;
+ }
+ }
+ return 0;
+}
+
+/*! Find function with given name in \a entry. */
+#if 0
+static Entry *findFunction(Entry* entry, QCString name)
+{
+ QCString cname(name.lower());
+
+ EntryListIterator eli(*entry->children());
+ Entry *ce;
+ for (;(ce=eli.current());++eli)
+ {
+ if (ce->section != Entry::FUNCTION_SEC)
+ continue;
+
+ if (ce->name.lower() == cname)
+ return ce;
+ }
+
+ return 0;
+}
+#endif
+
+/*! Apply modifiers stored in \a mdfs to the \a typeName string. */
+static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs)
+{
+ if (!mdfs.dimension.isNull())
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += mdfs.dimension;
+ }
+ if (mdfs.direction!=SymbolModifiers::NONE_D)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += directionStrs[mdfs.direction];
+ }
+ if (mdfs.optional)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "optional";
+ }
+ if (mdfs.allocatable)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "allocatable";
+ }
+ if (mdfs.external)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "external";
+ }
+ if (mdfs.intrinsic)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "intrinsic";
+ }
+ if (mdfs.parameter)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "parameter";
+ }
+ if (mdfs.pointer)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "pointer";
+ }
+ if (mdfs.target)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "target";
+ }
+ if (mdfs.save)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "save";
+ }
+ if (mdfs.deferred)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "deferred";
+ }
+ if (mdfs.nonoverridable)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "non_overridable";
+ }
+ if (mdfs.nopass)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "nopass";
+ }
+ if (mdfs.pass)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "pass";
+ if (!mdfs.passVar.isEmpty())
+ typeName += "(" + mdfs.passVar + ")";
+ }
+ if (mdfs.protection == SymbolModifiers::PUBLIC)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "public";
+ }
+ else if (mdfs.protection == SymbolModifiers::PRIVATE)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "private";
+ }
+ if (mdfs.protect)
+ {
+ if (!typeName.isEmpty()) typeName += ", ";
+ typeName += "protected";
+ }
+
+ return typeName;
+}
+
+/*! Apply modifiers stored in \a mdfs to the \a arg argument. */
+static void applyModifiers(Argument *arg, SymbolModifiers& mdfs)
+{
+ QCString tmp = arg->type;
+ arg->type = applyModifiers(tmp, mdfs);
+}
+
+/*! Apply modifiers stored in \a mdfs to the \a ent entry. */
+static void applyModifiers(Entry *ent, SymbolModifiers& mdfs)
+{
+ QCString tmp = ent->type;
+ ent->type = applyModifiers(tmp, mdfs);
+
+ if (mdfs.protection == SymbolModifiers::PUBLIC)
+ ent->protection = Public;
+ else if (mdfs.protection == SymbolModifiers::PRIVATE)
+ ent->protection = Private;
+}
+
+/*! Starts the new scope in fortran program. Consider using this function when
+ * starting module, interface, function or other program block.
+ * \see endScope()
+ */
+static void startScope(Entry *scope)
+{
+ //cout<<"start scope: "<<scope->name<<endl;
+ current_root= scope; /* start substructure */
+
+ QMap<QCString,SymbolModifiers> mdfMap;
+ modifiers.insert(scope, mdfMap);
+}
+
+/*! Ends scope in fortran program: may update subprogram arguments or module variable attributes.
+ * \see startScope()
+ */
+static bool endScope(Entry *scope, bool isGlobalRoot)
+{
+ //cout<<"end scope: "<<scope->name<<endl;
+ if (current_root->parent() || isGlobalRoot)
+ {
+ current_root= current_root->parent(); /* end substructure */
+ }
+ else
+ {
+ fprintf(stderr,"parse error in end <scopename>");
+ scanner_abort();
+ return FALSE;
+ }
+
+ // update variables or subprogram arguments with modifiers
+ QMap<QCString,SymbolModifiers>& mdfsMap = modifiers[scope];
+
+ if (scope->section == Entry::FUNCTION_SEC)
+ {
+ // iterate all symbol modifiers of the scope
+ for (QMap<QCString,SymbolModifiers>::Iterator it=mdfsMap.begin(); it!=mdfsMap.end(); it++)
+ {
+ //cout<<it.key()<<": "<<it.data()<<endl;
+ Argument *arg = findArgument(scope, it.key());
+
+ if (arg)
+ applyModifiers(arg, it.data());
+ }
+
+ // find return type for function
+ //cout<<"RETURN NAME "<<modifiers[current_root][scope->name.lower()].returnName<<endl;
+ QCString returnName = modifiers[current_root][scope->name.lower()].returnName.lower();
+ if (modifiers[scope].contains(returnName))
+ {
+ scope->type = modifiers[scope][returnName].type; // returning type works
+ applyModifiers(scope, modifiers[scope][returnName]); // returning array works
+ }
+
+ }
+ if (scope->section == Entry::CLASS_SEC)
+ { // was INTERFACE_SEC
+ if (scope->parent()->section == Entry::FUNCTION_SEC)
+ { // interface within function
+ // iterate functions of interface and
+ // try to find types for dummy(ie. argument) procedures.
+ //cout<<"Search in "<<scope->name<<endl;
+ EntryListIterator eli(*scope->children());
+ Entry *ce;
+ int count = 0;
+ int found = FALSE;
+ for (;(ce=eli.current());++eli)
+ {
+ count++;
+ if (ce->section != Entry::FUNCTION_SEC)
+ continue;
+
+ Argument *arg = findArgument(scope->parent(), ce->name, TRUE);
+ if (arg != 0)
+ {
+ // set type of dummy procedure argument to interface
+ arg->name = arg->type;
+ arg->type = scope->name;
+ }
+ if (ce->name.lower() == scope->name.lower()) found = TRUE;
+ }
+ if ((count == 1) && found)
+ {
+ // clear all modifiers of the scope
+ modifiers.remove(scope);
+ delete scope->parent()->removeSubEntry(scope);
+ scope = 0;
+ return TRUE;
+ }
+ }
+ }
+ if (scope->section!=Entry::FUNCTION_SEC)
+ { // not function section
+ // iterate variables: get and apply modifiers
+ EntryListIterator eli(*scope->children());
+ Entry *ce;
+ for (;(ce=eli.current());++eli)
+ {
+ if (ce->section != Entry::VARIABLE_SEC && ce->section != Entry::FUNCTION_SEC)
+ continue;
+
+ //cout<<ce->name<<", "<<mdfsMap.contains(ce->name.lower())<<mdfsMap.count()<<endl;
+ if (mdfsMap.contains(ce->name.lower()))
+ applyModifiers(ce, mdfsMap[ce->name.lower()]);
+ }
+ }
+
+ // clear all modifiers of the scope
+ modifiers.remove(scope);
+
+ return TRUE;
+}
+
+#if 0
+//! Return full name of the entry. Sometimes we must combine several names recursively.
+static QCString getFullName(Entry *e)
+{
+ QCString name = e->name;
+ if (e->section == Entry::CLASS_SEC // || e->section == Entry::INTERFACE_SEC
+ || !e->parent() || e->parent()->name.isEmpty())
+ return name;
+
+ return getFullName(e->parent())+"::"+name;
+}
+#endif
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+
+ while ( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+static void initParser()
+{
+ last_entry = 0;
+}
+
+static void initEntry()
+{
+ if (typeMode)
+ {
+ current->protection = typeProtection;
+ }
+ else
+ {
+ current->protection = defaultProtection;
+ }
+ current->mtype = mtype;
+ current->virt = virt;
+ current->stat = gstat;
+ current->lang = SrcLangExt_Fortran;
+ initGroupInfo(current);
+}
+
+/**
+ adds current entry to current_root and creates new current
+*/
+static void addCurrentEntry(int case_insens)
+{
+ if (case_insens) current->name = current->name.lower();
+ //printf("===Adding entry %s to %s\n", current->name.data(), current_root->name.data());
+ current_root->addSubEntry(current);
+ last_entry = current;
+ current = new Entry ;
+ initEntry();
+}
+
+static int max(int a, int b) {return a>b?a:b;}
+
+static void addModule(const char *name, bool isModule)
+{
+ DBG_CTX((stderr, "0=========> got module %s\n", name));
+
+ if (isModule)
+ current->section = Entry::CLASS_SEC;
+ else
+ current->section = Entry::FUNCTION_SEC;
+
+ if (name!=NULL)
+ {
+ current->name = name;
+ }
+ else
+ {
+ QCString fname = yyFileName;
+ int index = max(fname.findRev('/'), fname.findRev('\\'));
+ fname = fname.right(fname.length()-index-1);
+ fname = fname.prepend("__").append("__");
+ current->name = fname;
+ }
+ current->type = "program";
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr; // used for source reference
+ current->protection = Public ;
+ addCurrentEntry(1);
+ startScope(last_entry);
+}
+
+
+static void addSubprogram(const char *text)
+{
+ DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text));
+ subrCurrent.prepend(current);
+ current->section = Entry::FUNCTION_SEC ;
+ QCString subtype = text; subtype=subtype.lower().stripWhiteSpace();
+ functionLine = (subtype.find("function") != -1);
+ current->type += " " + subtype;
+ current->type = current->type.stripWhiteSpace();
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr; // used for source reference
+ current->startLine = -1; // ??? what is startLine for?
+ current->args.resize(0);
+ current->argList->clear();
+ docBlock.resize(0);
+}
+
+/*! Adds interface to the root entry.
+ * \note Code was brought to this procedure from the parser,
+ * because there was/is idea to use it in several parts of the parser.
+ */
+static void addInterface(QCString name, InterfaceType type)
+{
+ if (YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+
+ current->section = Entry::CLASS_SEC; // was Entry::INTERFACE_SEC;
+ current->spec = Entry::Interface;
+ current->name = name;
+
+ switch (type)
+ {
+ case IF_ABSTRACT:
+ current->type = "abstract";
+ break;
+
+ case IF_GENERIC:
+ current->type = "generic";
+ break;
+
+ case IF_SPECIFIC:
+ case IF_NONE:
+ default:
+ current->type = "";
+ }
+
+ /* if type is part of a module, mod name is necessary for output */
+ if ((current_root) &&
+ (current_root->section == Entry::CLASS_SEC ||
+ current_root->section == Entry::NAMESPACE_SEC))
+ {
+ current->name= current_root->name + "::" + current->name;
+ }
+
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr;
+ addCurrentEntry(1);
+}
+
+
+//-----------------------------------------------------------------------------
+
+/*! Get the argument \a name.
+ */
+static Argument* getParameter(const QCString &name)
+{
+ // std::cout<<"addFortranParameter(): "<<name<<" DOCS:"<<(docs.isNull()?QCString("null"):docs)<<std::endl;
+ Argument *ret = 0;
+ if (current_root->argList==0) return 0;
+ ArgumentListIterator ali(*current_root->argList);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (a->name.lower()==name.lower())
+ {
+ ret=a;
+ //printf("parameter found: %s\n",(const char*)name);
+ break;
+ }
+ } // for
+ return ret;
+}
+
+ //----------------------------------------------------------------------------
+static void startCommentBlock(bool brief)
+{
+ if (brief)
+ {
+ current->briefFile = yyFileName;
+ current->briefLine = yyLineNr;
+ }
+ else
+ {
+ current->docFile = yyFileName;
+ current->docLine = yyLineNr;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+ bool needsEntry = FALSE;
+ static bool hideInBodyDocs = Config_getBool("HIDE_IN_BODY_DOCS");
+ int position=0;
+ if (docBlockInBody && hideInBodyDocs)
+ {
+ docBlockInBody = FALSE;
+ return;
+ }
+ DBG_CTX((stderr,"call parseCommentBlock [%s]\n",doc.data()));
+ int lineNr = brief ? current->briefLine : current->docLine;
+ while (parseCommentBlock(
+ g_thisParser,
+ docBlockInBody ? subrCurrent.getFirst() : current,
+ doc, // text
+ yyFileName, // file
+ lineNr,
+ docBlockInBody ? FALSE : brief,
+ docBlockInBody ? FALSE : docBlockJavaStyle,
+ docBlockInBody,
+ defaultProtection,
+ position,
+ needsEntry
+ ))
+ {
+ DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
+ if (needsEntry) addCurrentEntry(0);
+ }
+ DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
+
+ if (needsEntry) addCurrentEntry(0);
+ docBlockInBody = FALSE;
+}
+
+//----------------------------------------------------------------------------
+
+static void subrHandleCommentBlock(const QCString &doc,bool brief)
+{
+ QCString loc_doc;
+ Entry *tmp_entry = current;
+ current = subrCurrent.getFirst(); // temporarily switch to the entry of the subroutine / function
+
+ // Still in the specification section so no inbodyDocs yet, but parameter documentation
+ current->inbodyDocs = "";
+
+ if (docBlock.stripWhiteSpace().find("\\param") == 0)
+ {
+ handleCommentBlock("\n\n"+doc,brief);
+ }
+ else if (docBlock.stripWhiteSpace().find("@param") == 0)
+ {
+ handleCommentBlock("\n\n"+doc,brief);
+ }
+ else
+ {
+ int dir1 = modifiers[current_root][argName.lower()].direction;
+ loc_doc = doc.stripWhiteSpace();
+ if (loc_doc.lower().find(directionParam[SymbolModifiers::IN]) == 0)
+ {
+ if ((directionParam[dir1] == directionParam[SymbolModifiers::NONE_D]) ||
+ (directionParam[dir1] == directionParam[SymbolModifiers::IN]))
+ {
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[SymbolModifiers::IN] + " " +
+ argName + " " + loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::IN])),brief);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr, "inconsistency between intent attribute and documentation for variable: "+argName);
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[dir1] + " " +
+ argName + " " + doc,brief);
+ }
+ }
+ else if (loc_doc.lower().find(directionParam[SymbolModifiers::OUT]) == 0)
+ {
+ if ((directionParam[dir1] == directionParam[SymbolModifiers::NONE_D]) ||
+ (directionParam[dir1] == directionParam[SymbolModifiers::OUT]))
+ {
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[SymbolModifiers::OUT] + " " +
+ argName + " " + loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::OUT])),brief);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr, "inconsistency between intent attribute and documentation for variable: "+argName);
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[dir1] + " " +
+ argName + " " + doc,brief);
+ }
+ }
+ else if (loc_doc.lower().find(directionParam[SymbolModifiers::INOUT]) == 0)
+ {
+ if ((directionParam[dir1] == directionParam[SymbolModifiers::NONE_D]) ||
+ (directionParam[dir1] == directionParam[SymbolModifiers::INOUT]))
+ {
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[SymbolModifiers::INOUT] + " " +
+ argName + " " + loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::INOUT])),brief);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr, "inconsistency between intent attribute and documentation for variable: "+argName);
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[dir1] + " " +
+ argName + " " + doc,brief);
+ }
+ }
+ else
+ {
+ handleCommentBlock(QCString("\n\n at param ") + directionParam[dir1] + " " +
+ argName + " " + doc,brief);
+ }
+ }
+ current=tmp_entry;
+}
+
+//----------------------------------------------------------------------------
+#if 0
+static int level=0;
+
+static void debugCompounds(Entry *rt) // print Entry structure (for debugging)
+{
+ level++;
+ printf("%d) debugCompounds(%s) line %d\n",level, rt->name.data(), rt->bodyLine);
+ EntryListIterator eli(*rt->children());
+ Entry *ce;
+ for (;(ce=eli.current());++eli)
+ {
+ debugCompounds(ce);
+ }
+level--;
+}
+#endif
+
+
+static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, FortranFormat format)
+{
+ char *tmpBuf = NULL;
+ initParser();
+
+ defaultProtection = Public;
+ inputString = fileBuf;
+ inputPosition = 0;
+ inputStringPrepass = NULL;
+ inputPositionPrepass = 0;
+
+ //anonCount = 0; // don't reset per file
+ mtype = Method;
+ gstat = FALSE;
+ virt = Normal;
+ current_root = rt;
+ global_root = rt;
+ inputFile.setName(fileName);
+ if (inputFile.open(IO_ReadOnly))
+ {
+ isFixedForm = recognizeFixedForm(fileBuf,format);
+
+ if (isFixedForm)
+ {
+ msg("Prepassing fixed form of %s\n", fileName);
+ //printf("---strlen=%d\n", strlen(fileBuf));
+ //clock_t start=clock();
+
+ inputString = prepassFixedForm(fileBuf);
+
+ //clock_t end=clock();
+ //printf("CPU time used=%f\n", ((double) (end-start))/CLOCKS_PER_SEC);
+ }
+ else if (inputString[strlen(fileBuf)-1] != '\n')
+ {
+ tmpBuf = (char *)malloc(strlen(fileBuf)+2);
+ strcpy(tmpBuf,fileBuf);
+ tmpBuf[strlen(fileBuf)]= '\n';
+ tmpBuf[strlen(fileBuf)+1]= '\000';
+ inputString = tmpBuf;
+ }
+
+ yyLineNr= 1 ;
+ yyFileName = fileName;
+ msg("Parsing file %s...\n",yyFileName.data());
+
+ startScope(rt); // implies current_root = rt
+ initParser();
+ groupEnterFile(yyFileName,yyLineNr);
+
+ current = new Entry;
+ current->lang = SrcLangExt_Fortran;
+ current->name = yyFileName;
+ current->section = Entry::SOURCE_SEC;
+ current_root->addSubEntry(current);
+ file_root = current;
+ current = new Entry;
+ current->lang = SrcLangExt_Fortran;
+
+ fortranscannerYYrestart( fortranscannerYYin );
+ {
+ BEGIN( Start );
+ }
+
+ fortranscannerYYlex();
+ groupLeaveFile(yyFileName,yyLineNr);
+
+ endScope(current_root, TRUE); // TRUE - global root
+
+ //debugCompounds(rt); //debug
+
+ rt->program.resize(0);
+ delete current; current=0;
+ moduleProcedures.clear();
+ if (tmpBuf) {
+ free((char*)tmpBuf);
+ inputString=NULL;
+ }
+ if (isFixedForm) {
+ free((char*)inputString);
+ inputString=NULL;
+ }
+
+ inputFile.close();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void FortranLanguageScanner::parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool /*sameTranslationUnit*/,
+ QStrList & /*filesInSameTranslationUnit*/)
+{
+ g_thisParser = this;
+
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+
+ ::parseMain(fileName,fileBuf,root,m_format);
+
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+void FortranLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
+ const char * scopeName,
+ const QCString & input,
+ SrcLangExt /*lang*/,
+ bool isExampleBlock,
+ const char * exampleName,
+ FileDef * fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ ::parseFortranCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
+ fileDef,startLine,endLine,inlineFragment,memberDef,
+ showLineNumbers,searchCtx,collectXRefs,m_format);
+}
+
+bool FortranLanguageScanner::needsPreprocessing(const QCString &extension)
+{
+ return extension!=extension.lower(); // use preprocessor only for upper case extensions
+}
+void FortranLanguageScanner::resetCodeParserState()
+{
+ ::resetFortranCodeParserState();
+}
+
+void FortranLanguageScanner::parsePrototype(const char *text)
+{
+ QCString buffer = QCString(text);
+ pushBuffer(buffer);
+ parsingPrototype = TRUE;
+ BEGIN(Prototype);
+ fortranscannerYYlex();
+ parsingPrototype = FALSE;
+ popBuffer();
+}
+
+static void scanner_abort()
+{
+ fprintf(stderr,"********************************************************************\n");
+ fprintf(stderr,"Error in file %s line: %d, state: %d\n",yyFileName.data(),yyLineNr,YY_START);
+ fprintf(stderr,"********************************************************************\n");
+
+ EntryListIterator eli(*global_root->children());
+ Entry *ce;
+ bool start=FALSE;
+
+ for (;(ce=eli.current());++eli)
+ {
+ if (ce == file_root) start=TRUE;
+ if (start) ce->reset();
+ }
+
+ // dummy call to avoid compiler warning
+ (void)yy_top_state();
+
+ return;
+ //exit(-1);
+}
+
+//----------------------------------------------------------------------------
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void fortranscannernerYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/ftextstream.cpp b/src/ftextstream.cpp
new file mode 100644
index 0000000..3038af3
--- /dev/null
+++ b/src/ftextstream.cpp
@@ -0,0 +1,260 @@
+#include "ftextstream.h"
+#include <qfile.h>
+
+//----------------------------------------------------------------------------
+
+class QGStringBuffer : public QIODevice
+{
+ public:
+ QGStringBuffer( QGString* str );
+ ~QGStringBuffer();
+ bool open( int m );
+ void close();
+ void flush();
+ uint size() const;
+ int at() const;
+ bool at( int pos );
+ int readBlock( char *, uint) { return -1; }
+ int writeBlock( const char *p, uint len );
+ int getch() { return -1; }
+ int putch( int ch );
+ int ungetch( int ) { return -1; }
+
+ protected:
+ QGString* m_str;
+
+ private: // Disabled copy constructor and operator=
+ QGStringBuffer( const QGStringBuffer & );
+ QGStringBuffer &operator=( const QGStringBuffer & );
+};
+
+QGStringBuffer::QGStringBuffer( QGString* str ) : m_str(str)
+{
+ //printf("QGStringBuffer::QGStringBuffer(%p)\n",str);
+}
+
+QGStringBuffer::~QGStringBuffer()
+{
+}
+
+bool QGStringBuffer::open( int m )
+{
+ if ( !m_str )
+ {
+#if defined(CHECK_STATE)
+ qWarning( "QGStringBuffer::open: No string" );
+#endif
+ return FALSE;
+ }
+ if ( isOpen() )
+ { // buffer already open
+#if defined(CHECK_STATE)
+ qWarning( "QGStringBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate )
+ { // truncate buffer
+ m_str->truncate( 0 );
+ }
+ if ( m & IO_Append )
+ { // append to end of buffer
+ ioIndex = m_str->length();
+ }
+ else
+ {
+ ioIndex = 0;
+ }
+ setState( IO_Open );
+ setStatus( 0 );
+ return TRUE;
+}
+
+void QGStringBuffer::close()
+{
+ if ( isOpen() )
+ {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ }
+}
+
+void QGStringBuffer::flush()
+{
+}
+
+uint QGStringBuffer::size() const
+{
+ return m_str ? m_str->length() : 0;
+}
+
+int QGStringBuffer::at() const
+{
+ return ioIndex;
+}
+
+bool QGStringBuffer::at( int pos )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() )
+ {
+ qWarning( "QGStringBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( (uint)pos >= m_str->length() )
+ {
+#if defined(CHECK_RANGE)
+ qWarning( "QGStringBuffer::at: Index %d out of range", pos );
+#endif
+ return FALSE;
+ }
+
+ ioIndex = pos;
+ return TRUE;
+}
+
+int QGStringBuffer::writeBlock( const char *p, uint len )
+{
+ //printf("QGStringBuffer::writeBlock(%p,%d) m_str=%p ioIndex=%d\n",p,len,
+ // m_str,ioIndex);
+ m_str->enlarge(ioIndex+len+1);
+ memcpy(m_str->data()+ioIndex,p,len);
+ ioIndex+=len;
+ m_str->data()[ioIndex]='\0';
+ m_str->setLen(ioIndex);
+ return len;
+}
+
+int QGStringBuffer::putch( int ch )
+{
+ //printf("QGStringBuffer::putch(%d) m_str=%p ioIndex=%d\n",
+ // ch,m_str,ioIndex);
+ m_str->enlarge(ioIndex+2);
+ m_str->data()[ioIndex] = (char)ch;
+ ioIndex++;
+ m_str->data()[ioIndex] = '\0';
+ m_str->setLen(ioIndex);
+ return ch;
+}
+
+
+//----------------------------------------------------------------------------
+
+FTextStream::FTextStream()
+{
+ m_dev = 0;
+ m_owndev = FALSE;
+}
+
+FTextStream::FTextStream( QIODevice *dev )
+{
+ m_dev = dev;
+ m_owndev = FALSE;
+}
+
+FTextStream::FTextStream( QGString *s )
+{
+ m_dev = new QGStringBuffer(s);
+ ((QGStringBuffer*)m_dev)->open( IO_WriteOnly );
+ m_owndev = TRUE;
+}
+
+FTextStream::FTextStream( FILE *fh )
+{
+ m_dev = new QFile;
+ ((QFile *)m_dev)->open( IO_WriteOnly, fh);
+ m_owndev = TRUE;
+}
+
+FTextStream::~FTextStream()
+{
+ if (m_owndev) delete m_dev;
+ m_dev = 0;
+}
+
+QIODevice *FTextStream::device() const
+{
+ return m_dev;
+}
+
+void FTextStream::setDevice( QIODevice *dev )
+{
+ if (m_owndev)
+ {
+ delete m_dev;
+ m_owndev = FALSE;
+ }
+ m_dev = dev;
+}
+
+void FTextStream::unsetDevice()
+{
+ setDevice(0);
+}
+
+FTextStream &FTextStream::output_int( ulong n, bool neg )
+{
+ char buf[20];
+ char *p = &buf[19];
+ *p = '\0';
+ if ( neg )
+ {
+ n = (ulong)(-(long)n);
+ }
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg ) *--p = '-';
+ return operator<<(p);
+}
+
+FTextStream &FTextStream::operator<<( signed short i )
+{
+ return output_int( i, i < 0 );
+}
+
+FTextStream &FTextStream::operator<<( unsigned short i )
+{
+ return output_int( i, FALSE );
+}
+
+FTextStream &FTextStream::operator<<( signed int i )
+{
+ return output_int( i, i < 0 );
+}
+
+FTextStream &FTextStream::operator<<( unsigned int i )
+{
+ return output_int( i, FALSE );
+}
+
+FTextStream &FTextStream::operator<<( signed long i )
+{
+ return output_int( i, i < 0 );
+}
+
+FTextStream &FTextStream::operator<<( unsigned long i )
+{
+ return output_int( i, FALSE );
+}
+
+FTextStream &FTextStream::operator<<( float f )
+{
+ return *this << (double)f;
+}
+
+FTextStream &FTextStream::operator<<( double d )
+{
+ char buf[64];
+ sprintf(buf,"%f",d);
+ return *this << buf;
+}
+
+
+
+
+
diff --git a/src/ftextstream.h b/src/ftextstream.h
new file mode 100644
index 0000000..d073f40
--- /dev/null
+++ b/src/ftextstream.h
@@ -0,0 +1,82 @@
+#ifndef FTEXTSTREAM_H
+#define FTEXTSTREAM_H
+
+#include <stdio.h>
+
+#include <qiodevice.h>
+#include <qstring.h>
+#include <qgstring.h>
+
+/** @brief Simplified and optimized version of QTextStream */
+class FTextStream
+{
+ public:
+ FTextStream();
+ FTextStream( QIODevice * );
+ FTextStream( QGString * );
+ FTextStream( FILE * );
+ virtual ~FTextStream();
+
+ QIODevice *device() const;
+ void setDevice( QIODevice * );
+ void unsetDevice();
+
+ FTextStream &operator<<( char );
+ FTextStream &operator<<( const char *);
+ FTextStream &operator<<( const QString & );
+ FTextStream &operator<<( const QCString & );
+ FTextStream &operator<<( signed short );
+ FTextStream &operator<<( unsigned short );
+ FTextStream &operator<<( signed int );
+ FTextStream &operator<<( unsigned int );
+ FTextStream &operator<<( signed long );
+ FTextStream &operator<<( unsigned long );
+ FTextStream &operator<<( float );
+ FTextStream &operator<<( double );
+
+ private:
+ QIODevice *m_dev;
+ bool m_owndev;
+ FTextStream &output_int( ulong n, bool neg );
+
+ private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ FTextStream( const FTextStream & );
+ FTextStream &operator=( const FTextStream & );
+#endif
+};
+
+inline FTextStream &FTextStream::operator<<( char c)
+{
+ if (m_dev) m_dev->putch(c);
+ return *this;
+}
+
+inline FTextStream &FTextStream::operator<<( const char* s)
+{
+ uint len = qstrlen( s );
+ if (m_dev) m_dev->writeBlock( s, len );
+ return *this;
+}
+
+inline FTextStream &FTextStream::operator<<( const QString & s)
+{
+ return operator<<(s.data());
+}
+
+inline FTextStream &FTextStream::operator<<( const QCString &s)
+{
+ return operator<<(s.data());
+}
+
+typedef FTextStream & (*FTSFUNC)(FTextStream &);// manipulator function
+
+inline FTextStream &operator<<( FTextStream &s, FTSFUNC f )
+{ return (*f)( s ); }
+
+inline FTextStream &endl( FTextStream & s)
+{
+ return s << '\n';
+}
+
+#endif // FTEXTSTREAM_H
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
new file mode 100644
index 0000000..4613a92
--- /dev/null
+++ b/src/ftvhelp.cpp
@@ -0,0 +1,1335 @@
+/******************************************************************************
+ * ftvhelp.cpp,v 1.0 2000/09/06 16:09:00
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Original version contributed by Kenney Wong <kwong at ea.com>
+ * Modified by Dimitri van Heesch
+ *
+ * Folder Tree View for offline help on browsers that do not support HTML Help.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <qlist.h>
+#include <qdict.h>
+#include <qfileinfo.h>
+
+#include "ftvhelp.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "language.h"
+#include "htmlgen.h"
+#include "layout.h"
+#include "pagedef.h"
+#include "docparser.h"
+#include "htmldocvisitor.h"
+#include "filedef.h"
+#include "util.h"
+
+#define MAX_INDENT 1024
+
+
+static const char navtree_script[]=
+#include "navtree.js.h"
+;
+
+static const char resize_script[]=
+#include "resize.js.h"
+;
+
+static const char navtree_css[]=
+#include "navtree.css.h"
+;
+
+static unsigned char blank_png[352] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static unsigned char folderopen_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,228,195,193,190,187,218,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,195,215,221,225,225,178,176,176,175,176,178,180,255,255,255,255,255,255,
+ 255,255,255,255,255,255,189,206,215,219,226,220,214,212,207,204,200,176,255,255,255,255,255,255,
+ 255,255,255,255,168,154,153,153,152,152,151,149,150,150,149,147,146,145,145,167,255,255,255,255,
+ 255,255,255,255,146,187,187,188,187,187,185,183,183,182,179,178,175,173,174,145,255,255,255,255,
+ 255,255,255,255,146,180,182,182,181,181,179,178,176,174,173,171,169,170,168,144,255,255,255,255,
+ 255,255,255,255,144,173,176,176,177,175,175,174,171,170,168,168,166,166,164,143,255,255,255,255,
+ 255,255,255,255,142,168,170,171,170,170,169,168,166,166,165,163,163,164,162,142,255,255,255,255,
+ 255,255,255,255,141,162,166,164,164,165,163,163,161,161,161,161,161,160,159,141,255,255,255,255,
+ 255,255,255,255,138,157,159,159,158,158,158,157,157,157,157,156,157,157,155,138,255,255,255,255,
+ 255,255,255,255,137,154,153,154,154,153,154,154,154,153,154,154,154,154,154,137,255,255,255,255,
+ 255,255,255,255,137,154,154,154,154,154,154,154,153,154,154,153,153,153,154,137,255,255,255,255,
+ 255,255,255,255,137,125,125,125,125,124,125,124,124,125,124,124,125,124,125,138,255,255,255,255,
+ 255,255,255,255,212,209,204,199,193,190,186,183,180,181,185,188,192,197,202,203,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char folderopen_a_png[528] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static unsigned char folderclosed_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,197,155,155,155,155,196,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,155,191,191,191,192,155,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,168,144,180,180,181,180,145,145,146,145,146,146,146,146,145,167,255,255,255,255,
+ 255,255,255,255,147,225,226,226,225,226,225,221,221,219,215,214,212,211,213,145,255,255,255,255,
+ 255,255,255,255,147,212,211,211,210,211,210,205,206,205,201,201,199,196,201,145,255,255,255,255,
+ 255,255,255,255,146,204,203,204,203,203,202,200,200,197,197,196,195,194,196,145,255,255,255,255,
+ 255,255,255,255,146,202,200,201,201,200,199,198,198,195,194,194,193,192,194,145,255,255,255,255,
+ 255,255,255,255,145,200,196,196,196,195,195,193,192,192,190,189,189,189,191,143,255,255,255,255,
+ 255,255,255,255,143,192,191,190,190,189,189,188,186,187,186,185,185,185,187,142,255,255,255,255,
+ 255,255,255,255,142,186,184,183,182,183,182,183,180,181,181,181,181,181,182,141,255,255,255,255,
+ 255,255,255,255,138,177,175,176,176,177,177,176,175,174,175,175,175,174,176,138,255,255,255,255,
+ 255,255,255,255,138,173,169,170,168,170,169,170,170,169,171,171,171,171,174,137,255,255,255,255,
+ 255,255,255,255,138,166,163,163,162,162,162,162,162,162,164,163,163,163,166,137,255,255,255,255,
+ 255,255,255,255,137,124,124,124,125,124,124,124,125,125,124,124,125,124,125,138,255,255,255,255,
+ 255,255,255,255,231,231,228,225,222,220,218,216,214,215,217,219,221,224,227,226,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char folderclosed_a_png[528] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static unsigned char doc_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,218,214,208,208,204,191,179,190,197,209,231,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,195,224,226,226,222,214,204,181,203,229,188,225,255,255,255,255,255,255,255,
+ 255,255,255,255,255,198,226,228,227,227,224,215,203,180,252,229,184,224,255,255,255,255,255,255,
+ 255,255,255,255,255,198,229,230,229,229,228,224,214,154,252,252,229,187,235,255,255,255,255,255,
+ 255,255,255,255,255,198,232,233,233,232,231,230,223,176,154,144,165,177,216,255,255,255,255,255,
+ 255,255,255,255,255,198,236,236,216,226,238,219,232,225,209,190,189,166,193,255,255,255,255,255,
+ 255,255,255,255,255,198,239,240,178,177,230,175,169,184,188,219,208,189,187,255,255,255,255,255,
+ 255,255,255,255,255,198,241,242,240,218,237,236,240,235,241,244,221,208,182,255,255,255,255,255,
+ 255,255,255,255,255,198,243,243,188,154,183,158,166,140,185,198,231,219,177,255,255,255,255,255,
+ 255,255,255,255,255,198,243,245,248,228,241,241,226,249,237,227,239,232,177,255,255,255,255,255,
+ 255,255,255,255,255,198,244,246,213,172,163,149,171,200,167,149,242,239,177,255,255,255,255,255,
+ 255,255,255,255,255,198,249,248,240,218,237,236,240,235,241,244,244,242,177,255,255,255,255,255,
+ 255,255,255,255,255,198,249,251,188,155,184,158,166,140,185,198,246,244,177,255,255,255,255,255,
+ 255,255,255,255,255,198,251,253,248,228,241,241,226,249,237,227,249,246,177,255,255,255,255,255,
+ 255,255,255,255,255,196,253,252,252,252,252,251,251,250,250,249,249,248,175,255,255,255,255,255,
+ 255,255,255,255,255,194, 64, 30, 37, 37, 37, 37, 37, 37, 37, 37, 30, 64,188,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char doc_a_png[528] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#if 0
+static unsigned char module_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,255,193,128,136,255,255,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,255,213,128,170,255,255,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,247,247,128,196,255,247,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,213,255,153,230,255,213,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,187,255,187,255,230,204,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,153,255,247,255,196,204,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,128,247,255,255,170,204,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,128,213,255,255,136,204,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,255,255,128,187,255,230,138,204,255,217,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char namespace_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,226,128,128,198,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,255,189,128,198,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,255,244,141,198,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,255,255,220,198,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,226,255,255,220,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,198,220,255,255,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,198,141,250,255,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,198,128,198,255,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,157,255,255,198,128,128,226,255,255,157,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char class_png[528] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,187,247,255,255,230,170,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,196,255,255,255,255,255,255,170,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,145,255,255,230,128,136,230,247,179,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,179,255,255,170,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,179,255,255,162,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,179,255,255,170,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,145,255,255,221,128,128,221,255,179,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,196,255,255,255,255,255,255,187,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,187,247,255,255,240,179,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,
+ 255,255,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+
+static unsigned char letter_a_png[528] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 60,156,204,204,204,204,204,204,204,204,156, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 78,255,255,255,255,255,255,255,255,255,255,255,252, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,210,255,255,255,255,255,255,255,255,255,255,255,255,207, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,240,255,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,222,255,255,255,255,255,255,255,255,255,255,255,255,219, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,111,255,255,255,255,255,255,255,255,255,255,255,255, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 99,198,204,204,204,204,204,204,204,204,195, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+#endif
+
+
+static unsigned char arrow_right_png[352] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,255,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,152,152,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,152,152,152,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,152,152,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,255,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char arrow_right_a_png[352] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,223, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,176, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,255,248,117, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,255,255,255,211, 60, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,255,255,255,255,255, 77, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,255,255,255,211, 60, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,255,248,117, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,255,255,176, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,223, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static unsigned char arrow_down_png[352] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,152,152,152,152,152,152,152,152,152,255,255,255,255,
+ 255,255,255,152,152,152,152,152,152,152,152,152,255,255,255,255,
+ 255,255,255,255,152,152,152,152,152,152,152,255,255,255,255,255,
+ 255,255,255,255,152,152,152,152,152,152,152,255,255,255,255,255,
+ 255,255,255,255,255,152,152,152,152,152,255,255,255,255,255,255,
+ 255,255,255,255,255,255,152,152,152,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,152,152,152,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,152,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+static unsigned char arrow_down_a_png[352] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,231,255,255,255,255,255,255,255,216, 0, 0, 0, 0,
+ 0, 0, 0, 87,255,255,255,255,255,255,255, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0,186,255,255,255,255,255,164, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 38,251,255,255,255,241, 25, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,127,255,255,255,107, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,221,255,204, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 72,253, 52, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#define SPLITBAR_LINE 170,242,224,202,183,170
+#define SPLITBAR_BLOCK2 SPLITBAR_LINE , SPLITBAR_LINE
+#define SPLITBAR_BLOCK4 SPLITBAR_BLOCK2 , SPLITBAR_BLOCK2
+#define SPLITBAR_BLOCK8 SPLITBAR_BLOCK4 , SPLITBAR_BLOCK4
+#define SPLITBAR_BLOCK16 SPLITBAR_BLOCK8 , SPLITBAR_BLOCK8
+#define SPLITBAR_BLOCK32 SPLITBAR_BLOCK16 , SPLITBAR_BLOCK16
+
+#define SPLITBAR_ALTLINE1 170,242,170,202,170,170
+#define SPLITBAR_ALTLINE2 170,243,224,255,183,255
+#define SPLITBAR_ALTBLOCK2 SPLITBAR_ALTLINE1 , SPLITBAR_ALTLINE2
+#define SPLITBAR_ALTBLOCK4 SPLITBAR_ALTBLOCK2 , SPLITBAR_ALTBLOCK2
+#define SPLITBAR_ALTBLOCK8 SPLITBAR_ALTBLOCK4 , SPLITBAR_ALTBLOCK4
+
+static unsigned char splitbar_png[32*32*6] =
+{
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK8,
+ SPLITBAR_BLOCK8,
+ SPLITBAR_ALTBLOCK8,
+ SPLITBAR_BLOCK8,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32,
+ SPLITBAR_BLOCK32
+};
+
+struct FTVImageInfo
+{
+ const char *alt;
+ const char *name;
+ const unsigned char *data;
+ //unsigned int len;
+ unsigned short width, height;
+};
+
+//extern FTVImageInfo image_info[];
+
+#if 0
+#define FTVIMG_blank 0
+#define FTVIMG_doc 1
+#define FTVIMG_folderclosed 2
+#define FTVIMG_folderopen 3
+#define FTVIMG_lastnode 4
+#define FTVIMG_link 5
+#define FTVIMG_mlastnode 6
+#define FTVIMG_mnode 7
+#define FTVIMG_node 8
+#define FTVIMG_plastnode 9
+#define FTVIMG_pnode 10
+#define FTVIMG_vertline 11
+#define FTVIMG_ns 12
+#define FTVIMG_cl 13
+#define FTVIMG_mo 14
+
+#define FTV_S(name) #name
+#define FTV_ICON_FILE(name) "ftv2" FTV_S(name) ".png"
+#define FTVIMG_INDEX(name) FTVIMG_ ## name
+#define FTV_INFO(name) ( image_info[FTVIMG_INDEX(name)] )
+#define FTV_IMGATTRIBS(name) \
+ "src=\"" FTV_ICON_FILE(name) "\" " \
+ "alt=\"" << FTV_INFO(name).alt << "\" " \
+ "width=\"" << FTV_INFO(name).width << "\" " \
+ "height=\"" << FTV_INFO(name).height << "\" "
+
+
+static FTVImageInfo image_info[] =
+{
+ { " ", "ftv2blank.png", 0 /*ftv2blank_png*/ /*,174*/,16,22 },
+ { "*", "ftv2doc.png", 0 /*ftv2doc_png*/ /*,255*/,24,22 },
+ { "+", "ftv2folderclosed.png", 0 /*ftv2folderclosed_png*/ /*,259*/,24,22 },
+ { "-", "ftv2folderopen.png", 0 /*ftv2folderopen_png*/ /*,261*/,24,22 },
+ { "\\", "ftv2lastnode.png", 0 /*ftv2lastnode_png*/ /*,233*/,16,22 },
+ { "-", "ftv2link.png", 0 /*ftv2link_png*/ /*,358*/,24,22 },
+ { "\\", "ftv2mlastnode.png", 0 /*ftv2mlastnode_png*/ /*,160*/,16,22 },
+ { "o", "ftv2mnode.png", 0 /*ftv2mnode_png*/ /*,194*/,16,22 },
+ { "o", "ftv2node.png", 0 /*ftv2node_png*/ /*,235*/,16,22 },
+ { "\\", "ftv2plastnode.png", 0 /*ftv2plastnode_png*/ /*,165*/,16,22 },
+ { "o", "ftv2pnode.png", 0 /*ftv2pnode_png*/ /*,200*/,16,22 },
+ { "|", "ftv2vertline.png", 0 /*ftv2vertline_png*/ /*,229*/,16,22 },
+ { "N", "ftv2ns.png", 0 /*ftv2vertline_png*/ /*,352*/,24,22 },
+ { "C", "ftv2cl.png", 0 /*ftv2vertline_png*/ /*,352*/,24,22 },
+ { "M", "ftv2mo.png", 0 /*ftv2vertline_png*/ /*,352*/,24,22 },
+ { 0, 0, 0 /*, 0*/, 0, 0 }
+};
+#endif
+
+static ColoredImgDataItem ftv_image_data[] =
+{
+ { "ftv2blank.png", 16, 22, blank_png, blank_png },
+ { "ftv2doc.png", 24, 22, doc_png, doc_a_png },
+ { "ftv2folderclosed.png", 24, 22, folderclosed_png, folderclosed_a_png },
+ { "ftv2folderopen.png", 24, 22, folderopen_png, folderopen_a_png },
+// { "ftv2ns.png", 24, 22, namespace_png, letter_a_png },
+// { "ftv2mo.png", 24, 22, module_png, letter_a_png },
+// { "ftv2cl.png", 24, 22, class_png, letter_a_png },
+ { "ftv2lastnode.png", 16, 22, blank_png, blank_png },
+ { "ftv2link.png", 24, 22, doc_png, doc_a_png },
+ { "ftv2mlastnode.png", 16, 22, arrow_down_png, arrow_down_a_png },
+ { "ftv2mnode.png", 16, 22, arrow_down_png, arrow_down_a_png },
+ { "ftv2node.png", 16, 22, blank_png, blank_png },
+ { "ftv2plastnode.png", 16, 22, arrow_right_png, arrow_right_a_png },
+ { "ftv2pnode.png", 16, 22, arrow_right_png, arrow_right_a_png },
+ { "ftv2vertline.png", 16, 22, blank_png, blank_png },
+ { "ftv2splitbar.png", 6,1024, splitbar_png, 0 },
+ { 0, 0, 0, 0, 0 }
+};
+
+static int folderId=1;
+
+struct FTVNode
+{
+ FTVNode(bool dir,const char *r,const char *f,const char *a,
+ const char *n,bool sepIndex,bool navIndex,Definition *df)
+ : isLast(TRUE), isDir(dir),ref(r),file(f),anchor(a),name(n), index(0),
+ parent(0), separateIndex(sepIndex), addToNavIndex(navIndex),
+ def(df) { children.setAutoDelete(TRUE); }
+ int computeTreeDepth(int level) const;
+ int numNodesAtLevel(int level,int maxLevel) const;
+ bool isLast;
+ bool isDir;
+ QCString ref;
+ QCString file;
+ QCString anchor;
+ QCString name;
+ int index;
+ QList<FTVNode> children;
+ FTVNode *parent;
+ bool separateIndex;
+ bool addToNavIndex;
+ Definition *def;
+};
+
+int FTVNode::computeTreeDepth(int level) const
+{
+ int maxDepth=level;
+ QListIterator<FTVNode> li(children);
+ FTVNode *n;
+ for (;(n=li.current());++li)
+ {
+ if (n->children.count()>0)
+ {
+ int d = n->computeTreeDepth(level+1);
+ if (d>maxDepth) maxDepth=d;
+ }
+ }
+ return maxDepth;
+}
+
+int FTVNode::numNodesAtLevel(int level,int maxLevel) const
+{
+ int num=0;
+ if (level<maxLevel)
+ {
+ num++; // this node
+ QListIterator<FTVNode> li(children);
+ FTVNode *n;
+ for (;(n=li.current());++li)
+ {
+ num+=n->numNodesAtLevel(level+1,maxLevel);
+ }
+ }
+ return num;
+}
+
+//----------------------------------------------------------------------------
+
+/*! Constructs an ftv help object.
+ * The object has to be \link initialize() initialized\endlink before it can
+ * be used.
+ */
+FTVHelp::FTVHelp(bool TLI)
+{
+ /* initial depth */
+ m_indentNodes = new QList<FTVNode>[MAX_INDENT];
+ m_indentNodes[0].setAutoDelete(TRUE);
+ m_indent=0;
+ m_topLevelIndex = TLI;
+}
+
+/*! Destroys the ftv help object. */
+FTVHelp::~FTVHelp()
+{
+ delete[] m_indentNodes;
+}
+
+/*! This will create a folder tree view table of contents file (tree.js).
+ * \sa finalize()
+ */
+void FTVHelp::initialize()
+{
+}
+
+/*! Finalizes the FTV help. This will finish and close the
+ * contents file (index.js).
+ * \sa initialize()
+ */
+void FTVHelp::finalize()
+{
+ generateTreeView();
+}
+
+/*! Increase the level of the contents hierarchy.
+ * This will start a new sublist in contents file.
+ * \sa decContentsDepth()
+ */
+void FTVHelp::incContentsDepth()
+{
+ //printf("incContentsDepth() indent=%d\n",m_indent);
+ m_indent++;
+ ASSERT(m_indent<MAX_INDENT);
+}
+
+/*! Decrease the level of the contents hierarchy.
+ * This will end the current sublist.
+ * \sa incContentsDepth()
+ */
+void FTVHelp::decContentsDepth()
+{
+ //printf("decContentsDepth() indent=%d\n",m_indent);
+ ASSERT(m_indent>0);
+ if (m_indent>0)
+ {
+ m_indent--;
+ QList<FTVNode> *nl = &m_indentNodes[m_indent];
+ FTVNode *parent = nl->getLast();
+ if (parent)
+ {
+ QList<FTVNode> *children = &m_indentNodes[m_indent+1];
+ while (!children->isEmpty())
+ {
+ parent->children.append(children->take(0));
+ }
+ }
+ }
+}
+
+/*! Add a list item to the contents file.
+ * \param isDir TRUE if the item is a directory, FALSE if it is a text
+ * \param ref the URL of to the item.
+ * \param file the file containing the definition of the item
+ * \param anchor the anchor within the file.
+ * \param name the name of the item.
+ * \param separateIndex put the entries in a separate index file
+ * \param addToNavIndex add this entry to the quick navigation index
+ * \param def Definition corresponding to this entry
+ */
+void FTVHelp::addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool separateIndex,
+ bool addToNavIndex,
+ Definition *def
+ )
+{
+ //printf("%p: m_indent=%d addContentsItem(%s,%s,%s,%s)\n",this,m_indent,name,ref,file,anchor);
+ QList<FTVNode> *nl = &m_indentNodes[m_indent];
+ FTVNode *newNode = new FTVNode(isDir,ref,file,anchor,name,separateIndex,addToNavIndex,def);
+ if (!nl->isEmpty())
+ {
+ nl->getLast()->isLast=FALSE;
+ }
+ nl->append(newNode);
+ newNode->index = nl->count()-1;
+ if (m_indent>0)
+ {
+ QList<FTVNode> *pnl = &m_indentNodes[m_indent-1];
+ newNode->parent = pnl->getLast();
+ }
+
+}
+
+static QCString node2URL(FTVNode *n,bool overruleFile=FALSE,bool srcLink=FALSE)
+{
+ QCString url = n->file;
+ if (!url.isEmpty() && url.at(0)=='!') // relative URL
+ {
+ // remove leading !
+ url = url.mid(1);
+ }
+ else if (!url.isEmpty() && url.at(0)=='^') // absolute URL
+ {
+ // skip, keep ^ in the output
+ }
+ else // local file (with optional anchor)
+ {
+ if (overruleFile && n->def && n->def->definitionType()==Definition::TypeFile)
+ {
+ FileDef *fd = (FileDef*)n->def;
+ if (srcLink)
+ {
+ url = fd->getSourceFileBase();
+ }
+ else
+ {
+ url = fd->getOutputFileBase();
+ }
+ }
+ url+=Doxygen::htmlFileExtension;
+ if (!n->anchor.isEmpty()) url+="#"+n->anchor;
+ }
+ return url;
+}
+
+QCString FTVHelp::generateIndentLabel(FTVNode *n,int level)
+{
+ QCString result;
+ if (n->parent)
+ {
+ result=generateIndentLabel(n->parent,level+1);
+ }
+ result+=QCString().setNum(n->index)+"_";
+ return result;
+}
+
+void FTVHelp::generateIndent(FTextStream &t, FTVNode *n,bool opened)
+{
+ int indent=0;
+ FTVNode *p = n->parent;
+ while (p) { indent++; p=p->parent; }
+ if (n->isDir)
+ {
+ QCString dir = opened ? "▼" : "►";
+ t << "<span style=\"width:" << (indent*16) << "px;display:inline-block;\"> </span>"
+ << "<span id=\"arr_" << generateIndentLabel(n,0) << "\" class=\"arrow\" ";
+ t << "onclick=\"toggleFolder('" << generateIndentLabel(n,0) << "')\"";
+ t << ">" << dir
+ << "</span>";
+ }
+ else
+ {
+ t << "<span style=\"width:" << ((indent+1)*16) << "px;display:inline-block;\"> </span>";
+ }
+}
+
+void FTVHelp::generateLink(FTextStream &t,FTVNode *n)
+{
+ //printf("FTVHelp::generateLink(ref=%s,file=%s,anchor=%s\n",
+ // n->ref.data(),n->file.data(),n->anchor.data());
+ if (n->file.isEmpty()) // no link
+ {
+ t << "<b>" << convertToHtml(n->name) << "</b>";
+ }
+ else // link into other frame
+ {
+ if (!n->ref.isEmpty()) // link to entity imported via tag file
+ {
+ t << "<a class=\"elRef\" ";
+ t << externalLinkTarget() << externalRef("",n->ref,FALSE);
+ }
+ else // local link
+ {
+ t << "<a class=\"el\" ";
+ }
+ t << "href=\"";
+ t << externalRef("",n->ref,TRUE);
+ t << node2URL(n);
+ if (m_topLevelIndex)
+ t << "\" target=\"basefrm\">";
+ else
+ t << "\" target=\"_self\">";
+ t << convertToHtml(n->name);
+ t << "</a>";
+ if (!n->ref.isEmpty())
+ {
+ t << " [external]";
+ }
+ }
+}
+
+static void generateBriefDoc(FTextStream &t,Definition *def)
+{
+ QCString brief = def->briefDescription(TRUE);
+ //printf("*** %p: generateBriefDoc(%s)='%s'\n",def,def->name().data(),brief.data());
+ if (!brief.isEmpty())
+ {
+ DocNode *root = validatingParseDoc(def->briefFile(),def->briefLine(),
+ def,0,brief,FALSE,FALSE,0,TRUE,TRUE);
+ QCString relPath = relativePathToRoot(def->getOutputFileBase());
+ HtmlCodeGenerator htmlGen(t,relPath);
+ HtmlDocVisitor *visitor = new HtmlDocVisitor(t,htmlGen,def);
+ root->accept(visitor);
+ delete visitor;
+ delete root;
+ }
+}
+
+void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,int maxLevel,int &index)
+{
+ QListIterator<FTVNode> nli(nl);
+ FTVNode *n;
+ for (nli.toFirst();(n=nli.current());++nli)
+ {
+ t << "<tr id=\"row_" << generateIndentLabel(n,0) << "\"";
+ if ((index&1)==0) // even row
+ t << " class=\"even\"";
+ if (level>=maxLevel) // item invisible by default
+ t << " style=\"display:none;\"";
+ else // item visible by default
+ index++;
+ t << "><td class=\"entry\">";
+ bool nodeOpened = level+1<maxLevel;
+ generateIndent(t,n,nodeOpened);
+ if (n->isDir)
+ {
+ if (n->def && n->def->definitionType()==Definition::TypeGroup)
+ {
+ // no icon
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypePage)
+ {
+ // no icon
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypeNamespace)
+ {
+ t << "<span class=\"icona\"><span class=\"icon\">N</span></span>";
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypeClass)
+ {
+ t << "<span class=\"icona\"><span class=\"icon\">C</span></span>";
+ }
+ else
+ {
+ t << "<span id=\"img_" << generateIndentLabel(n,0)
+ << "\" class=\"iconf"
+ << (nodeOpened?"open":"closed")
+ << "\" onclick=\"toggleFolder('" << generateIndentLabel(n,0)
+ << "')\"> </span>";
+ }
+ generateLink(t,n);
+ t << "</td><td class=\"desc\">";
+ if (n->def)
+ {
+ generateBriefDoc(t,n->def);
+ }
+ t << "</td></tr>" << endl;
+ folderId++;
+ generateTree(t,n->children,level+1,maxLevel,index);
+ }
+ else // leaf node
+ {
+ FileDef *srcRef=0;
+ if (n->def && n->def->definitionType()==Definition::TypeFile &&
+ ((FileDef*)n->def)->generateSourceFile())
+ {
+ srcRef = (FileDef*)n->def;
+ }
+ if (srcRef)
+ {
+ t << "<a href=\"" << srcRef->getSourceFileBase()
+ << Doxygen::htmlFileExtension
+ << "\">";
+ }
+ if (n->def && n->def->definitionType()==Definition::TypeGroup)
+ {
+ // no icon
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypePage)
+ {
+ // no icon
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypeNamespace)
+ {
+ t << "<span class=\"icona\"><span class=\"icon\">N</span></span>";
+ }
+ else if (n->def && n->def->definitionType()==Definition::TypeClass)
+ {
+ t << "<span class=\"icona\"><span class=\"icon\">C</span></span>";
+ }
+ else
+ {
+ t << "<span class=\"icondoc\"></span>";
+ }
+ if (srcRef)
+ {
+ t << "</a>";
+ }
+ generateLink(t,n);
+ t << "</td><td class=\"desc\">";
+ if (n->def)
+ {
+ generateBriefDoc(t,n->def);
+ }
+ t << "</td></tr>" << endl;
+ }
+ }
+}
+
+//-----------------------------------------------------------
+
+struct NavIndexEntry
+{
+ NavIndexEntry(const QCString &u,const QCString &p) : url(u), path(p) {}
+ QCString url;
+ QCString path;
+};
+
+class NavIndexEntryList : public QList<NavIndexEntry>
+{
+ public:
+ NavIndexEntryList() : QList<NavIndexEntry>() { setAutoDelete(TRUE); }
+ ~NavIndexEntryList() {}
+ private:
+ int compareValues(const NavIndexEntry *item1,const NavIndexEntry *item2) const
+ {
+ // sort list based on url
+ return qstrcmp(item1->url,item2->url);
+ }
+};
+
+static QCString pathToNode(FTVNode *leaf,FTVNode *n)
+{
+ QCString result;
+ if (n->parent)
+ {
+ result+=pathToNode(leaf,n->parent);
+ }
+ result+=QCString().setNum(n->index);
+ if (leaf!=n) result+=",";
+ return result;
+}
+
+static bool dupOfParent(const FTVNode *n)
+{
+ if (n->parent==0) return FALSE;
+ if (n->file==n->parent->file) return TRUE;
+ return FALSE;
+}
+
+static void generateJSLink(FTextStream &t,FTVNode *n)
+{
+ if (n->file.isEmpty()) // no link
+ {
+ t << "\"" << convertToJSString(n->name) << "\", null, ";
+ }
+ else // link into other page
+ {
+ t << "\"" << convertToJSString(n->name) << "\", \"";
+ t << externalRef("",n->ref,TRUE);
+ t << node2URL(n);
+ t << "\", ";
+ }
+}
+
+static QCString convertFileId2Var(const QCString &fileId)
+{
+ QCString varId = fileId;
+ int i=varId.findRev('/');
+ if (i>=0) varId = varId.mid(i+1);
+ return substitute(varId,"-","_");
+}
+
+static bool generateJSTree(NavIndexEntryList &navIndex,FTextStream &t,
+ const QList<FTVNode> &nl,int level,bool &first)
+{
+ static QCString htmlOutput = Config_getString("HTML_OUTPUT");
+ QCString indentStr;
+ indentStr.fill(' ',level*2);
+ bool found=FALSE;
+ QListIterator<FTVNode> nli(nl);
+ FTVNode *n;
+ for (nli.toFirst();(n=nli.current());++nli)
+ {
+ // terminate previous entry
+ if (!first) t << "," << endl;
+ first=FALSE;
+
+ // start entry
+ if (!found)
+ {
+ t << "[" << endl;
+ }
+ found=TRUE;
+
+ if (n->addToNavIndex) // add entry to the navigation index
+ {
+ if (n->def && n->def->definitionType()==Definition::TypeFile)
+ {
+ FileDef *fd = (FileDef*)n->def;
+ bool doc,src;
+ doc = fileVisibleInIndex(fd,src);
+ if (doc)
+ {
+ navIndex.append(new NavIndexEntry(node2URL(n,TRUE,FALSE),pathToNode(n,n)));
+ }
+ if (src)
+ {
+ navIndex.append(new NavIndexEntry(node2URL(n,TRUE,TRUE),pathToNode(n,n)));
+ }
+ }
+ else
+ {
+ navIndex.append(new NavIndexEntry(node2URL(n),pathToNode(n,n)));
+ }
+ }
+
+ if (n->separateIndex) // store items in a separate file for dynamic loading
+ {
+ bool firstChild=TRUE;
+ t << indentStr << " [ ";
+ generateJSLink(t,n);
+ if (n->children.count()>0) // write children to separate file for dynamic loading
+ {
+ QCString fileId = n->file;
+ if (n->anchor)
+ {
+ fileId+="_"+n->anchor;
+ }
+ if (dupOfParent(n))
+ {
+ fileId+="_dup";
+ }
+ QFile f(htmlOutput+"/"+fileId+".js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream tt(&f);
+ tt << "var " << convertFileId2Var(fileId) << " =" << endl;
+ generateJSTree(navIndex,tt,n->children,1,firstChild);
+ tt << endl << "];";
+ }
+ t << "\"" << fileId << "\" ]";
+ }
+ else // no children
+ {
+ t << "null ]";
+ }
+ }
+ else // show items in this file
+ {
+ bool firstChild=TRUE;
+ t << indentStr << " [ ";
+ generateJSLink(t,n);
+ bool emptySection = !generateJSTree(navIndex,t,n->children,level+1,firstChild);
+ if (emptySection)
+ t << "null ]";
+ else
+ t << endl << indentStr << " ] ]";
+ }
+ }
+ return found;
+}
+
+static void generateJSNavTree(const QList<FTVNode> &nodeList)
+{
+ QCString htmlOutput = Config_getString("HTML_OUTPUT");
+ QFile f(htmlOutput+"/navtree.js");
+ NavIndexEntryList navIndex;
+ if (f.open(IO_WriteOnly) /*&& fidx.open(IO_WriteOnly)*/)
+ {
+ //FTextStream tidx(&fidx);
+ //tidx << "var NAVTREEINDEX =" << endl;
+ //tidx << "{" << endl;
+ FTextStream t(&f);
+ t << "var NAVTREE =" << endl;
+ t << "[" << endl;
+ t << " [ ";
+ QCString &projName = Config_getString("PROJECT_NAME");
+ if (projName.isEmpty())
+ {
+ if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) // Use title of main page as root
+ {
+ t << "\"" << convertToJSString(Doxygen::mainPage->title()) << "\", ";
+ }
+ else // Use default section title as root
+ {
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::MainPage);
+ t << "\"" << convertToJSString(lne->title()) << "\", ";
+ }
+ }
+ else // use PROJECT_NAME as root tree element
+ {
+ t << "\"" << convertToJSString(projName) << "\", ";
+ }
+ t << "\"index" << Doxygen::htmlFileExtension << "\", ";
+
+ // add special entry for index page
+ navIndex.append(new NavIndexEntry("index"+Doxygen::htmlFileExtension,""));
+ // related page index is written as a child of index.html, so add this as well
+ navIndex.append(new NavIndexEntry("pages"+Doxygen::htmlFileExtension,""));
+
+ bool first=TRUE;
+ generateJSTree(navIndex,t,nodeList,1,first);
+
+ if (first)
+ t << "]" << endl;
+ else
+ t << endl << " ] ]" << endl;
+ t << "];" << endl << endl;
+
+ // write the navigation index (and sub-indices)
+ navIndex.sort();
+ int subIndex=0;
+ int elemCount=0;
+ const int maxElemCount=250;
+ //QFile fidx(htmlOutput+"/navtreeindex.js");
+ QFile fsidx(htmlOutput+"/navtreeindex0.js");
+ if (/*fidx.open(IO_WriteOnly) &&*/ fsidx.open(IO_WriteOnly))
+ {
+ //FTextStream tidx(&fidx);
+ FTextStream tsidx(&fsidx);
+ t << "var NAVTREEINDEX =" << endl;
+ t << "[" << endl;
+ tsidx << "var NAVTREEINDEX" << subIndex << " =" << endl;
+ tsidx << "{" << endl;
+ QListIterator<NavIndexEntry> li(navIndex);
+ NavIndexEntry *e;
+ bool first=TRUE;
+ for (li.toFirst();(e=li.current());) // for each entry
+ {
+ if (elemCount==0)
+ {
+ if (!first)
+ {
+ t << "," << endl;
+ }
+ else
+ {
+ first=FALSE;
+ }
+ t << "\"" << e->url << "\"";
+ }
+ tsidx << "\"" << e->url << "\":[" << e->path << "]";
+ ++li;
+ if (li.current() && elemCount<maxElemCount-1) tsidx << ","; // not last entry
+ tsidx << endl;
+
+ elemCount++;
+ if (li.current() && elemCount>=maxElemCount) // switch to new sub-index
+ {
+ tsidx << "};" << endl;
+ elemCount=0;
+ fsidx.close();
+ subIndex++;
+ fsidx.setName(htmlOutput+"/navtreeindex"+QCString().setNum(subIndex)+".js");
+ if (!fsidx.open(IO_WriteOnly)) break;
+ tsidx.setDevice(&fsidx);
+ tsidx << "var NAVTREEINDEX" << subIndex << " =" << endl;
+ tsidx << "{" << endl;
+ }
+ }
+ tsidx << "};" << endl;
+ t << endl << "];" << endl;
+ }
+ t << endl << "var SYNCONMSG = '" << theTranslator->trPanelSynchronisationTooltip(FALSE) << "';";
+ t << endl << "var SYNCOFFMSG = '" << theTranslator->trPanelSynchronisationTooltip(TRUE) << "';";
+ t << endl << navtree_script;
+ }
+}
+
+//-----------------------------------------------------------
+
+// new style images
+void FTVHelp::generateTreeViewImages()
+{
+ QCString dname=Config_getString("HTML_OUTPUT");
+ writeColoredImgData(dname,ftv_image_data);
+}
+
+// new style scripts
+void FTVHelp::generateTreeViewScripts()
+{
+ QCString htmlOutput = Config_getString("HTML_OUTPUT");
+
+ // generate navtree.js & navtreeindex.js
+ generateJSNavTree(m_indentNodes[0]);
+
+ // generate resize.js
+ {
+ QFile f(htmlOutput+"/resize.js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << resize_script;
+ }
+ }
+ // generate navtree.css
+ {
+ QFile f(htmlOutput+"/navtree.css");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << substitute(
+ replaceColorMarkers(navtree_css),
+ "$width",
+ QCString().setNum(Config_getInt("TREEVIEW_WIDTH"))+"px"
+ );
+ }
+ }
+}
+
+// write tree inside page
+void FTVHelp::generateTreeViewInline(FTextStream &t)
+{
+ int preferredNumEntries = Config_getInt("HTML_INDEX_NUM_ENTRIES");
+ t << "<div class=\"directory\">\n";
+ QListIterator<FTVNode> li(m_indentNodes[0]);
+ FTVNode *n;
+ int d=1, depth=1;
+ for (;(n=li.current());++li)
+ {
+ if (n->children.count()>0)
+ {
+ d = n->computeTreeDepth(2);
+ if (d>depth) depth=d;
+ }
+ }
+ int preferredDepth = depth;
+ // write level selector
+ if (depth>1)
+ {
+ t << "<div class=\"levels\">[";
+ t << theTranslator->trDetailLevel();
+ t << " ";
+ int i;
+ for (i=1;i<=depth;i++)
+ {
+ t << "<span onclick=\"javascript:toggleLevel(" << i << ");\">" << i << "</span>";
+ }
+ t << "]</div>";
+
+ if (preferredNumEntries>0)
+ {
+ preferredDepth=1;
+ for (int i=1;i<=depth;i++)
+ {
+ int num=0;
+ QListIterator<FTVNode> li(m_indentNodes[0]);
+ FTVNode *n;
+ for (;(n=li.current());++li)
+ {
+ num+=n->numNodesAtLevel(0,i);
+ }
+ if (num<=preferredNumEntries)
+ {
+ preferredDepth=i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ //printf("preferred depth=%d\n",preferredDepth);
+
+ t << "<table class=\"directory\">\n";
+ int index=0;
+ generateTree(t,m_indentNodes[0],0,preferredDepth,index);
+ t << "</table>\n";
+
+ t << "</div><!-- directory -->\n";
+}
+
+// write old style index.html and tree.html
+void FTVHelp::generateTreeView()
+{
+ generateTreeViewImages();
+ generateTreeViewScripts();
+}
+
diff --git a/src/ftvhelp.h b/src/ftvhelp.h
new file mode 100644
index 0000000..bddb2f0
--- /dev/null
+++ b/src/ftvhelp.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/******************************************************************************
+ * ftvhelp.h,v 1.0 2000/09/06 16:09:00
+ *
+ * Kenney Wong <kwong at ea.com>
+ *
+ * Folder Tree View for offline help on browsers that do not support HTML Help.
+ */
+
+#ifndef FTVHELP_H
+#define FTVHELP_H
+
+#include <qlist.h>
+#include "index.h"
+
+class QFile;
+class Definition;
+struct FTVNode;
+class FTextStream;
+
+/** A class that generates a dynamic tree view side panel.
+ */
+class FTVHelp : public IndexIntf
+{
+ public:
+ FTVHelp(bool LTI);
+ ~FTVHelp();
+ void initialize();
+ void finalize();
+ void incContentsDepth();
+ void decContentsDepth();
+ void addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool separateIndex,
+ bool addToNavIndex,
+ Definition *def);
+ void addIndexItem(Definition *,MemberDef *,const char *,const char *) {}
+ void addIndexFile(const char *) {}
+ void addImageFile(const char *) {}
+ void addStyleSheetFile(const char *) {}
+ void generateTreeView();
+ void generateTreeViewInline(FTextStream &t);
+ static void generateTreeViewImages();
+ void generateTreeViewScripts();
+ private:
+ void generateTree(FTextStream &t,const QList<FTVNode> &nl,int level,int maxLevel,int &index);
+ //bool generateJSTree(FTextStream &tidx,FTextStream &t,const QList<FTVNode> &nl,int level,bool &first);
+ //bool generateJSTreeTopLevel(FTextStream &tidx,FTextStream &t,const QList<FTVNode> &nl,int level,bool &first);
+ QCString generateIndentLabel(FTVNode *n,int level);
+ void generateIndent(FTextStream &t,FTVNode *n,bool opened);
+ void generateLink(FTextStream &t,FTVNode *n);
+ //void generateJSLink(FTextStream &t,FTVNode *n);
+ QList<FTVNode> *m_indentNodes;
+ int m_indent;
+ bool m_topLevelIndex;
+};
+
+
+#endif /* FTVHELP_H */
+
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
new file mode 100644
index 0000000..f1d1877
--- /dev/null
+++ b/src/groupdef.cpp
@@ -0,0 +1,1521 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <ctype.h>
+#include <qregexp.h>
+#include "groupdef.h"
+#include "classdef.h"
+#include "filedef.h"
+#include "classlist.h"
+#include "outputlist.h"
+#include "namespacedef.h"
+#include "language.h"
+#include "util.h"
+#include "memberlist.h"
+#include "message.h"
+#include "membergroup.h"
+#include "doxygen.h"
+#include "pagedef.h"
+#include "docparser.h"
+#include "searchindex.h"
+#include "dot.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "arguments.h"
+#include "entry.h"
+#include "membername.h"
+#include "dirdef.h"
+#include "config.h"
+
+//---------------------------------------------------------------------------
+
+GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t,
+ const char *refFileName) : Definition(df,dl,1,na)
+{
+ fileList = new FileList;
+ classSDict = new ClassSDict(17);
+ groupList = new GroupList;
+ namespaceSDict = new NamespaceSDict(17);
+ pageDict = new PageSDict(17);
+ exampleDict = new PageSDict(17);
+ dirList = new DirList;
+ allMemberNameInfoSDict = new MemberNameInfoSDict(17);
+ allMemberNameInfoSDict->setAutoDelete(TRUE);
+ if (refFileName)
+ {
+ fileName=stripExtension(refFileName);
+ }
+ else
+ {
+ fileName = (QCString)"group_"+na;
+ }
+ setGroupTitle( t );
+ memberGroupSDict = new MemberGroupSDict;
+ memberGroupSDict->setAutoDelete(TRUE);
+
+ allMemberList = new MemberList(MemberListType_allMembersList);
+
+ visited = 0;
+ groupScope = 0;
+ m_subGrouping=Config_getBool("SUBGROUPING");
+}
+
+GroupDef::~GroupDef()
+{
+ delete fileList;
+ delete classSDict;
+ delete groupList;
+ delete namespaceSDict;
+ delete pageDict;
+ delete exampleDict;
+ delete allMemberList;
+ delete allMemberNameInfoSDict;
+ delete memberGroupSDict;
+ delete dirList;
+}
+
+void GroupDef::setGroupTitle( const char *t )
+{
+ if ( t && qstrlen(t) )
+ {
+ title = t;
+ titleSet = TRUE;
+ }
+ else
+ {
+ title = name();
+ title.at(0)=toupper(title.at(0));
+ titleSet = FALSE;
+ }
+}
+
+
+void GroupDef::distributeMemberGroupDocumentation()
+{
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->distributeMemberGroupDocumentation();
+ }
+}
+
+void GroupDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ml->findSectionsInDocumentation();
+ }
+ }
+}
+
+void GroupDef::addFile(const FileDef *def)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ if (def->isHidden()) return;
+ updateLanguage(def);
+ if (sortBriefDocs)
+ fileList->inSort(def);
+ else
+ fileList->append(def);
+}
+
+bool GroupDef::addClass(const ClassDef *cd)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ if (cd->isHidden()) return FALSE;
+ updateLanguage(cd);
+ if (classSDict->find(cd->qualifiedName())==0)
+ {
+ QCString qn = cd->qualifiedName();
+ //printf("--- addClass %s sort=%d\n",qn.data(),sortBriefDocs);
+ if (sortBriefDocs)
+ {
+ classSDict->inSort(cd->qualifiedName(),cd);
+ }
+ else
+ {
+ int i=qn.findRev("::");
+ if (i==-1) i=qn.find('.');
+ bool found=FALSE;
+ //printf("i=%d\n",i);
+ if (i!=-1)
+ {
+ // add nested classes (e.g. A::B, A::C) after their parent (A) in
+ // order of insertion
+ QCString scope = qn.left(i);
+ int j=classSDict->findAt(scope);
+ if (j!=-1)
+ {
+ while (j<(int)classSDict->count() &&
+ classSDict->at(j)->qualifiedName().left(i)==scope)
+ {
+ //printf("skipping over %s\n",classSDict->at(j)->qualifiedName().data());
+ j++;
+ }
+ //printf("Found scope at index %d\n",j);
+ classSDict->insertAt(j,cd->qualifiedName(),cd);
+ found=TRUE;
+ }
+ }
+ if (!found) // no insertion point found -> just append
+ {
+ classSDict->append(cd->qualifiedName(),cd);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool GroupDef::addNamespace(const NamespaceDef *def)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ if (def->isHidden()) return FALSE;
+ updateLanguage(def);
+ if (namespaceSDict->find(def->name())==0)
+ {
+ if (sortBriefDocs)
+ namespaceSDict->inSort(def->name(),def);
+ else
+ namespaceSDict->append(def->name(),def);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void GroupDef::addDir(const DirDef *def)
+{
+ if (def->isHidden()) return;
+ if (Config_getBool("SORT_BRIEF_DOCS"))
+ dirList->inSort(def);
+ else
+ dirList->append(def);
+}
+
+void GroupDef::addPage(PageDef *def)
+{
+ if (def->isHidden()) return;
+ //printf("Making page %s part of a group\n",def->name.data());
+ pageDict->append(def->name(),def);
+ def->makePartOfGroup(this);
+}
+
+void GroupDef::addExample(const PageDef *def)
+{
+ if (def->isHidden()) return;
+ exampleDict->append(def->name(),def);
+}
+
+
+void GroupDef::addMembersToMemberGroup()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
+ }
+ }
+
+ //printf("GroupDef::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count());
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->setInGroup(TRUE);
+ }
+}
+
+
+bool GroupDef::insertMember(MemberDef *md,bool docOnly)
+{
+ if (md->isHidden()) return FALSE;
+ updateLanguage(md);
+ //printf("GroupDef(%s)::insertMember(%s)\n", title.data(), md->name().data());
+ MemberNameInfo *mni=0;
+ if ((mni=(*allMemberNameInfoSDict)[md->name()]))
+ { // member with this name already found
+ MemberNameInfoIterator srcMnii(*mni);
+ MemberInfo *srcMi;
+ for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
+ {
+ MemberDef *srcMd = srcMi->memberDef;
+ if (srcMd==md) return FALSE; // already added before!
+
+ bool sameScope = srcMd->getOuterScope()==md->getOuterScope() || // same class or namespace
+ // both inside a file => definition and declaration do not have to be in the same file
+ (srcMd->getOuterScope()->definitionType()==Definition::TypeFile &&
+ md->getOuterScope()->definitionType()==Definition::TypeFile);
+
+ ArgumentList *srcMdAl = srcMd->argumentList();
+ ArgumentList *mdAl = md->argumentList();
+ ArgumentList *tSrcMdAl = srcMd->templateArguments();
+ ArgumentList *tMdAl = md->templateArguments();
+
+ if (srcMd->isFunction() && md->isFunction() && // both are a function
+ ((tSrcMdAl==0 && tMdAl==0) ||
+ (tSrcMdAl!=0 && tMdAl!=0 && tSrcMdAl->count()==tMdAl->count())
+ ) && // same number of template arguments
+ matchArguments2(srcMd->getOuterScope(),srcMd->getFileDef(),srcMdAl,
+ md->getOuterScope(),md->getFileDef(),mdAl,
+ TRUE
+ ) && // matching parameters
+ sameScope // both are found in the same scope
+ )
+ {
+ if (srcMd->getGroupAlias()==0)
+ {
+ md->setGroupAlias(srcMd);
+ }
+ else if (md!=srcMd->getGroupAlias())
+ {
+ md->setGroupAlias(srcMd->getGroupAlias());
+ }
+ return FALSE; // member is the same as one that is already added
+ }
+ }
+ mni->append(new MemberInfo(md,md->protection(),md->virtualness(),FALSE));
+ }
+ else
+ {
+ mni = new MemberNameInfo(md->name());
+ mni->append(new MemberInfo(md,md->protection(),md->virtualness(),FALSE));
+ allMemberNameInfoSDict->append(mni->memberName(),mni);
+ }
+ //printf("Added member!\n");
+ allMemberList->append(md);
+ switch(md->memberType())
+ {
+ case MemberType_Variable:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decVarMembers,md);
+ }
+ addMemberToList(MemberListType_docVarMembers,md);
+ break;
+ case MemberType_Function:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decFuncMembers,md);
+ }
+ addMemberToList(MemberListType_docFuncMembers,md);
+ break;
+ case MemberType_Typedef:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decTypedefMembers,md);
+ }
+ addMemberToList(MemberListType_docTypedefMembers,md);
+ break;
+ case MemberType_Enumeration:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decEnumMembers,md);
+ }
+ addMemberToList(MemberListType_docEnumMembers,md);
+ break;
+ case MemberType_EnumValue:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decEnumValMembers,md);
+ }
+ addMemberToList(MemberListType_docEnumValMembers,md);
+ break;
+ case MemberType_Define:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decDefineMembers,md);
+ }
+ addMemberToList(MemberListType_docDefineMembers,md);
+ break;
+ case MemberType_Signal:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decSignalMembers,md);
+ }
+ addMemberToList(MemberListType_docSignalMembers,md);
+ break;
+ case MemberType_Slot:
+ if (md->protection()==Public)
+ {
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decPubSlotMembers,md);
+ }
+ addMemberToList(MemberListType_docPubSlotMembers,md);
+ }
+ else if (md->protection()==Protected)
+ {
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decProSlotMembers,md);
+ }
+ addMemberToList(MemberListType_docProSlotMembers,md);
+ }
+ else
+ {
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decPriSlotMembers,md);
+ }
+ addMemberToList(MemberListType_docPriSlotMembers,md);
+ }
+ break;
+ case MemberType_Event:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decEventMembers,md);
+ }
+ addMemberToList(MemberListType_docEventMembers,md);
+ break;
+ case MemberType_Property:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decPropMembers,md);
+ }
+ addMemberToList(MemberListType_docPropMembers,md);
+ break;
+ case MemberType_Friend:
+ if (!docOnly)
+ {
+ addMemberToList(MemberListType_decFriendMembers,md);
+ }
+ addMemberToList(MemberListType_docFriendMembers,md);
+ break;
+ default:
+ err("GroupDef::insertMembers(): "
+ "member `%s' (typeid=%d) with scope `%s' inserted in group scope `%s'!\n",
+ md->name().data(),md->memberType(),
+ md->getClassDef() ? md->getClassDef()->name().data() : "",
+ name().data());
+ }
+ return TRUE;
+}
+
+void GroupDef::removeMember(MemberDef *md)
+{
+ // fprintf(stderr, "GroupDef(%s)::removeMember( %s )\n", title.data(), md->name().data());
+ MemberNameInfo *mni = allMemberNameInfoSDict->find(md->name());
+ if (mni)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ while( mnii.current() )
+ {
+ if( mnii.current()->memberDef == md )
+ {
+ mni->remove(mnii.current());
+ break;
+ }
+ ++mnii;
+ }
+ if( mni->isEmpty() )
+ {
+ allMemberNameInfoSDict->remove(md->name());
+ }
+
+ removeMemberFromList(MemberListType_allMembersList,md);
+ switch(md->memberType())
+ {
+ case MemberType_Variable:
+ removeMemberFromList(MemberListType_decVarMembers,md);
+ removeMemberFromList(MemberListType_docVarMembers,md);
+ break;
+ case MemberType_Function:
+ removeMemberFromList(MemberListType_decFuncMembers,md);
+ removeMemberFromList(MemberListType_docFuncMembers,md);
+ break;
+ case MemberType_Typedef:
+ removeMemberFromList(MemberListType_decTypedefMembers,md);
+ removeMemberFromList(MemberListType_docTypedefMembers,md);
+ break;
+ case MemberType_Enumeration:
+ removeMemberFromList(MemberListType_decEnumMembers,md);
+ removeMemberFromList(MemberListType_docEnumMembers,md);
+ break;
+ case MemberType_EnumValue:
+ removeMemberFromList(MemberListType_decEnumValMembers,md);
+ removeMemberFromList(MemberListType_docEnumValMembers,md);
+ break;
+ case MemberType_Define:
+ removeMemberFromList(MemberListType_decDefineMembers,md);
+ removeMemberFromList(MemberListType_docDefineMembers,md);
+ break;
+ case MemberType_Signal:
+ removeMemberFromList(MemberListType_decSignalMembers,md);
+ removeMemberFromList(MemberListType_docSignalMembers,md);
+ break;
+ case MemberType_Slot:
+ if (md->protection()==Public)
+ {
+ removeMemberFromList(MemberListType_decPubSlotMembers,md);
+ removeMemberFromList(MemberListType_docPubSlotMembers,md);
+ }
+ else if (md->protection()==Protected)
+ {
+ removeMemberFromList(MemberListType_decProSlotMembers,md);
+ removeMemberFromList(MemberListType_docProSlotMembers,md);
+ }
+ else
+ {
+ removeMemberFromList(MemberListType_decPriSlotMembers,md);
+ removeMemberFromList(MemberListType_docPriSlotMembers,md);
+ }
+ break;
+ case MemberType_Event:
+ removeMemberFromList(MemberListType_decEventMembers,md);
+ removeMemberFromList(MemberListType_docEventMembers,md);
+ break;
+ case MemberType_Property:
+ removeMemberFromList(MemberListType_decPropMembers,md);
+ removeMemberFromList(MemberListType_docPropMembers,md);
+ break;
+ case MemberType_Friend:
+ removeMemberFromList(MemberListType_decFriendMembers,md);
+ removeMemberFromList(MemberListType_docFriendMembers,md);
+ break;
+ default:
+ err("GroupDef::removeMember(): unexpected member remove in file!\n");
+ }
+ }
+}
+
+bool GroupDef::containsGroup(const GroupDef *def)
+{
+ return this==def || groupList->find(def) >= 0;
+}
+
+void GroupDef::addGroup(const GroupDef *def)
+{
+ //printf("adding group `%s' to group `%s'\n",def->name().data(),name().data());
+ //if (Config_getBool("SORT_MEMBER_DOCS"))
+ // groupList->inSort(def);
+ //else
+ groupList->append(def);
+}
+
+bool GroupDef::isASubGroup() const
+{
+ GroupList *groups = partOfGroups();
+ return groups!=0 && groups->count()!=0;
+}
+
+int GroupDef::countMembers() const
+{
+ return fileList->count()+
+ classSDict->count()+
+ namespaceSDict->count()+
+ groupList->count()+
+ allMemberList->count()+
+ pageDict->count()+
+ exampleDict->count();
+}
+
+/*! Compute the HTML anchor names for all members in the group */
+void GroupDef::computeAnchors()
+{
+ //printf("GroupDef::computeAnchors()\n");
+ setAnchors(allMemberList);
+}
+
+void GroupDef::writeDetailedDescription(OutputList &ol,const QCString &title)
+{
+ if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
+ || !documentation().isEmpty() || !inbodyDocumentation().isEmpty()
+ )
+ {
+ if (pageDict->count()!=countMembers()) // not only pages -> classical layout
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,"details");
+ ol.popGeneratorState();
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+ }
+
+ // repeat brief description
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ // write separator between brief and details
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
+ // ol.newParagraph(); // FIXME:PARA
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.enable(OutputGenerator::Latex);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+
+ // write detailed documentation
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ }
+
+ // write inbody documentation
+ if (!inbodyDocumentation().isEmpty())
+ {
+ ol.generateDoc(inbodyFile(),inbodyLine(),this,0,inbodyDocumentation()+"\n",TRUE,FALSE);
+ }
+ }
+}
+
+void GroupDef::writeBriefDescription(OutputList &ol)
+{
+ if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startParagraph();
+ ol.writeDoc(rootNode,this,0);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+
+ if (Config_getBool("REPEAT_BRIEF") ||
+ !documentation().isEmpty()
+ )
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startTextLink(0,"details");
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ }
+ ol.popGeneratorState();
+ ol.endParagraph();
+ }
+ delete rootNode;
+ }
+}
+
+void GroupDef::writeGroupGraph(OutputList &ol)
+{
+ if (Config_getBool("HAVE_DOT") /*&& Config_getBool("GROUP_GRAPHS")*/ )
+ {
+ DotGroupCollaboration graph(this);
+ if (!graph.isTrivial())
+ {
+ msg("Generating dependency graph for group %s\n",qualifiedName().data());
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ //ol.startParagraph();
+ ol.startGroupCollaboration();
+ ol.parseText(theTranslator->trCollaborationDiagram(title));
+ ol.endGroupCollaboration(graph);
+ //ol.endParagraph();
+ ol.popGeneratorState();
+ }
+ }
+}
+
+void GroupDef::writeFiles(OutputList &ol,const QCString &title)
+{
+ // write list of files
+ if (fileList->count()>0)
+ {
+ ol.startMemberHeader("files");
+ ol.parseText(title);
+ ol.endMemberHeader();
+ ol.startMemberList();
+ QListIterator<FileDef> it(*fileList);
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ ol.startMemberDeclaration();
+ ol.startMemberItem(fd->getOutputFileBase(),0);
+ ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
+ ol.insertMemberAlign();
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl;
+ }
+ ol.endMemberItem();
+ if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(fd->getOutputFileBase());
+ ol.generateDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+ ol.endMemberList();
+ }
+}
+
+void GroupDef::writeNamespaces(OutputList &ol,const QCString &title)
+{
+ // write list of namespaces
+ namespaceSDict->writeDeclaration(ol,title);
+}
+
+void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title)
+{
+ // write list of groups
+ int count=0;
+ if (groupList->count()>0)
+ {
+ QListIterator<GroupDef> it(*groupList);
+ GroupDef *gd;
+ for (;(gd=it.current());++it)
+ {
+ if (gd->isVisible()) count++;
+ }
+ }
+ if (count>0)
+ {
+ ol.startMemberHeader("groups");
+ ol.parseText(title);
+ ol.endMemberHeader();
+ ol.startMemberList();
+ if (Config_getBool("SORT_GROUP_NAMES"))
+ {
+ groupList->sort();
+ }
+ QListIterator<GroupDef> it(*groupList);
+ GroupDef *gd;
+ for (;(gd=it.current());++it)
+ {
+ if (gd->isVisible())
+ {
+ ol.startMemberDeclaration();
+ ol.startMemberItem(gd->getOutputFileBase(),0);
+ //ol.docify(theTranslator->trGroup(FALSE,TRUE));
+ //ol.docify(" ");
+ ol.insertMemberAlign();
+ ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle());
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl;
+ }
+ ol.endMemberItem();
+ if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(gd->getOutputFileBase());
+ ol.generateDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+ }
+ ol.endMemberList();
+ }
+}
+
+void GroupDef::writeDirs(OutputList &ol,const QCString &title)
+{
+ // write list of directories
+ if (dirList->count()>0)
+ {
+ ol.startMemberHeader("dirs");
+ ol.parseText(title);
+ ol.endMemberHeader();
+ ol.startMemberList();
+ QListIterator<DirDef> it(*dirList);
+ DirDef *dd;
+ for (;(dd=it.current());++it)
+ {
+ ol.startMemberDeclaration();
+ ol.startMemberItem(dd->getOutputFileBase(),0);
+ ol.parseText(theTranslator->trDir(FALSE,TRUE));
+ ol.insertMemberAlign();
+ ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
+ ol.endMemberItem();
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <dir>" << convertToXML(dd->displayName()) << "</dir>" << endl;
+ }
+ if (!dd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(dd->getOutputFileBase());
+ ol.generateDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+
+ ol.endMemberList();
+ }
+}
+
+void GroupDef::writeClasses(OutputList &ol,const QCString &title)
+{
+ // write list of classes
+ classSDict->writeDeclaration(ol,0,title,FALSE);
+}
+
+void GroupDef::writeInlineClasses(OutputList &ol)
+{
+ classSDict->writeDocumentation(ol);
+}
+
+void GroupDef::writePageDocumentation(OutputList &ol)
+{
+ PageDef *pd=0;
+ PageSDict::Iterator pdi(*pageDict);
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (!pd->isReference())
+ {
+ QCString pageName = pd->getOutputFileBase();
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <page>" << convertToXML(pageName) << "</page>" << endl;
+ }
+
+ SectionInfo *si=0;
+ if (!pd->title().isEmpty() && !pd->name().isEmpty() &&
+ (si=Doxygen::sectionDict->find(pd->name()))!=0)
+ {
+ ol.startSection(si->label,si->title,SectionInfo::Subsection);
+ ol.docify(si->title);
+ ol.endSection(si->label,SectionInfo::Subsection);
+ }
+ ol.startTextBlock();
+ ol.generateDoc(pd->docFile(),pd->docLine(),pd,0,pd->documentation()+pd->inbodyDocumentation(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.endTextBlock();
+ }
+ }
+}
+
+void GroupDef::writeMemberGroups(OutputList &ol)
+{
+ /* write user defined member groups */
+ if (memberGroupSDict)
+ {
+ memberGroupSDict->sort();
+ /* write user defined member groups */
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->writeDeclarations(ol,0,0,0,this);
+ }
+ }
+}
+
+void GroupDef::startMemberDeclarations(OutputList &ol)
+{
+ ol.startMemberSections();
+}
+
+void GroupDef::endMemberDeclarations(OutputList &ol)
+{
+ ol.endMemberSections();
+}
+
+void GroupDef::startMemberDocumentation(OutputList &ol)
+{
+ //printf("** GroupDef::startMemberDocumentation()\n");
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = TRUE;
+ }
+}
+
+void GroupDef::endMemberDocumentation(OutputList &ol)
+{
+ //printf("** GroupDef::endMemberDocumentation()\n");
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.popGeneratorState();
+ Doxygen::suppressDocWarnings = FALSE;
+ }
+}
+
+void GroupDef::writeAuthorSection(OutputList &ol)
+{
+ // write Author section (Man only)
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
+ ol.popGeneratorState();
+}
+
+void GroupDef::writeSummaryLinks(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
+ LayoutDocEntry *lde;
+ bool first=TRUE;
+ SrcLangExt lang = getLanguage();
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if ((lde->kind()==LayoutDocEntry::GroupClasses && classSDict->declVisible()) ||
+ (lde->kind()==LayoutDocEntry::GroupNamespaces && namespaceSDict->declVisible()) ||
+ (lde->kind()==LayoutDocEntry::GroupFiles && fileList->count()>0) ||
+ (lde->kind()==LayoutDocEntry::GroupNestedGroups && groupList->count()>0) ||
+ (lde->kind()==LayoutDocEntry::GroupDirs && dirList->count()>0)
+ )
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ QCString label = lde->kind()==LayoutDocEntry::GroupClasses ? "nested-classes" :
+ lde->kind()==LayoutDocEntry::GroupNamespaces ? "namespaces" :
+ lde->kind()==LayoutDocEntry::GroupFiles ? "files" :
+ lde->kind()==LayoutDocEntry::GroupNestedGroups ? "groups" :
+ "dirs";
+ ol.writeSummaryLink(0,label,ls->title(lang),first);
+ first=FALSE;
+ }
+ else if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList * ml = getMemberList(lmd->type);
+ if (ml && ml->declVisible())
+ {
+ ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
+ first=FALSE;
+ }
+ }
+ }
+ if (!first)
+ {
+ ol.writeString(" </div>\n");
+ }
+ ol.popGeneratorState();
+}
+
+void GroupDef::writeDocumentation(OutputList &ol)
+{
+ //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ ol.pushGeneratorState();
+ startFile(ol,getOutputFileBase(),name(),title,HLI_None);
+
+ ol.startHeaderSection();
+ writeSummaryLinks(ol);
+ ol.startTitleHead(getOutputFileBase());
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.parseText(title);
+ ol.popGeneratorState();
+ addGroupListToTitle(ol,this);
+ ol.endTitleHead(getOutputFileBase(),title);
+ ol.endHeaderSection();
+ ol.startContents();
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ static QRegExp we("[a-zA-Z_][-a-zA-Z_0-9]*");
+ int i=0,p=0,l=0;
+ while ((i=we.match(title,p,&l))!=-1) // foreach word in the title
+ {
+ Doxygen::searchIndex->addWord(title.mid(i,l),TRUE);
+ p=i+l;
+ }
+ }
+
+ Doxygen::indexList->addIndexItem(this,0,0,title);
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"group\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <title>" << convertToXML(title) << "</title>" << endl;
+ Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
+ }
+
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang=getLanguage();
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::GroupClasses:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeClasses(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::GroupInlineClasses:
+ {
+ writeInlineClasses(ol);
+ }
+ break;
+ case LayoutDocEntry::GroupNamespaces:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNamespaces(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberGroups:
+ writeMemberGroups(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ endMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::GroupNestedGroups:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNestedGroups(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::GroupPageDocs:
+ writePageDocumentation(ol);
+ break;
+ case LayoutDocEntry::GroupDirs:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDirs(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::GroupFiles:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeFiles(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::GroupGraph:
+ writeGroupGraph(ol);
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ case LayoutDocEntry::ClassInheritanceGraph:
+ case LayoutDocEntry::ClassNestedClasses:
+ case LayoutDocEntry::ClassCollaborationGraph:
+ case LayoutDocEntry::ClassAllMembersLink:
+ case LayoutDocEntry::ClassUsedFiles:
+ case LayoutDocEntry::ClassInlineClasses:
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileConstantGroups:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Group entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ //---------------------------------------- end flexible part -------------------------------
+
+ endFile(ol);
+
+ ol.popGeneratorState();
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ allMemberList->sort();
+ writeMemberPages(ol);
+ }
+
+}
+
+void GroupDef::writeMemberPages(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->writeDocumentationPage(ol,name(),this);
+ }
+ }
+
+ ol.popGeneratorState();
+}
+
+void GroupDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
+{
+ static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
+
+ ol.writeString(" <div class=\"navtab\">\n");
+ ol.writeString(" <table>\n");
+
+ MemberListIterator mli(*allMemberList);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->getGroupDef()==this && md->isLinkable() && !md->isEnumValue())
+ {
+ ol.writeString(" <tr><td class=\"navtab\">");
+ if (md->isLinkableInProject())
+ {
+ if (md==currentMd) // selected item => highlight
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ ol.writeString("href=\"");
+ if (createSubDirs) ol.writeString("../../");
+ ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
+ ol.writeString("\">");
+ ol.writeString(convertToHtml(md->localName()));
+ ol.writeString("</a>");
+ }
+ ol.writeString("</td></tr>\n");
+ }
+ }
+
+ ol.writeString(" </table>\n");
+ ol.writeString(" </div>\n");
+}
+
+
+
+//---- helper functions ------------------------------------------------------
+
+void addClassToGroups(Entry *root,ClassDef *cd)
+{
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ {
+ if (gd->addClass(cd))
+ {
+ cd->makePartOfGroup(gd);
+ }
+ //printf("Compound %s: in group %s\n",cd->name().data(),gd->groupTitle());
+ }
+ }
+}
+
+void addNamespaceToGroups(Entry *root,NamespaceDef *nd)
+{
+ //printf("root->groups->count()=%d\n",root->groups->count());
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ //printf("group `%s'\n",s->data());
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ {
+ if (gd->addNamespace(nd)) nd->makePartOfGroup(gd);
+ //printf("Namespace %s: in group %s\n",nd->name().data(),s->data());
+ }
+ }
+}
+
+void addDirToGroups(Entry *root,DirDef *dd)
+{
+ //printf("*** root->groups->count()=%d\n",root->groups->count());
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ //printf("group `%s'\n",g->groupname.data());
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ {
+ gd->addDir(dd);
+ dd->makePartOfGroup(gd);
+ //printf("Dir %s: in group %s\n",dd->name().data(),g->groupname.data());
+ }
+ }
+}
+
+void addGroupToGroups(Entry *root,GroupDef *subGroup)
+{
+ //printf("addGroupToGroups for %s groups=%d\n",root->name.data(),
+ // root->groups?root->groups->count():-1);
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)) &&
+ !gd->containsGroup(subGroup) )
+ {
+ gd->addGroup(subGroup);
+ subGroup->makePartOfGroup(gd);
+ }
+ else if (gd==subGroup)
+ {
+ warn(root->fileName,root->startLine,"Trying to add group %s to itself!",
+ gd->name().data());
+ }
+ }
+}
+
+/*! Add a member to the group with the highest priority */
+void addMemberToGroups(Entry *root,MemberDef *md)
+{
+ //printf("addMemberToGroups: Root %p = %s, md %p=%s groups=%d\n",
+ // root, root->name.data(), md, md->name().data(), root->groups->count() );
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+
+ // Search entry's group list for group with highest pri.
+ Grouping::GroupPri_t pri = Grouping::GROUPING_LOWEST;
+ GroupDef *fgd=0;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() &&
+ (gd=Doxygen::groupSDict->find(g->groupname)) &&
+ g->pri >= pri)
+ {
+ if (fgd && gd!=fgd && g->pri==pri)
+ {
+ warn(root->fileName.data(), root->startLine,
+ "Member %s found in multiple %s groups! "
+ "The member will be put in group %s, and not in group %s",
+ md->name().data(), Grouping::getGroupPriName( pri ),
+ gd->name().data(), fgd->name().data()
+ );
+ }
+
+ fgd = gd;
+ pri = g->pri;
+ }
+ }
+ //printf("fgd=%p\n",fgd);
+
+ // put member into group defined by this entry?
+ if (fgd)
+ {
+ GroupDef *mgd = md->getGroupDef();
+ //printf("mgd=%p\n",mgd);
+ bool insertit = FALSE;
+ if (mgd==0)
+ {
+ insertit = TRUE;
+ }
+ else if (mgd!=fgd)
+ {
+ bool moveit = FALSE;
+
+ // move member from one group to another if
+ // - the new one has a higher priority
+ // - the new entry has the same priority, but with docs where the old one had no docs
+ if (md->getGroupPri()<pri)
+ {
+ moveit = TRUE;
+ }
+ else
+ {
+ if (md->getGroupPri()==pri)
+ {
+ if (!root->doc.isEmpty() && !md->getGroupHasDocs())
+ {
+ moveit = TRUE;
+ }
+ else if (!root->doc.isEmpty() && md->getGroupHasDocs())
+ {
+ warn(md->getGroupFileName(),md->getGroupStartLine(),
+ "Member documentation for %s found several times in %s groups!\n"
+ "%s:%d: The member will remain in group %s, and won't be put into group %s",
+ md->name().data(), Grouping::getGroupPriName( pri ),
+ root->fileName.data(), root->startLine,
+ mgd->name().data(),
+ fgd->name().data()
+ );
+ }
+ }
+ }
+
+ if (moveit)
+ {
+ //printf("removeMember\n");
+ mgd->removeMember(md);
+ insertit = TRUE;
+ }
+ }
+
+ if (insertit)
+ {
+ //printf("insertMember found at %s line %d: %s: related %s\n",
+ // md->getDefFileName().data(),md->getDefLine(),
+ // md->name().data(),root->relates.data());
+ bool success = fgd->insertMember(md);
+ if (success)
+ {
+ //printf("insertMember successful\n");
+ md->setGroupDef(fgd,pri,root->fileName,root->startLine,
+ !root->doc.isEmpty());
+ ClassDef *cd = md->getClassDefOfAnonymousType();
+ if (cd)
+ {
+ cd->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
+ }
+ }
+ }
+ }
+}
+
+
+void addExampleToGroups(Entry *root,PageDef *eg)
+{
+ QListIterator<Grouping> gli(*root->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ GroupDef *gd=0;
+ if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
+ {
+ gd->addExample(eg);
+ eg->makePartOfGroup(gd);
+ //printf("Example %s: in group %s\n",eg->name().data(),s->data());
+ }
+ }
+}
+
+QCString GroupDef::getOutputFileBase() const
+{
+ if (isReference())
+ {
+ return fileName;
+ }
+ else
+ {
+ return convertNameToFile(fileName);
+ }
+}
+
+void GroupDef::addListReferences()
+{
+ {
+ QList<ListItemInfo> *xrefItems = xrefListItems();
+ addRefItem(xrefItems,
+ getOutputFileBase(),
+ theTranslator->trGroup(TRUE,TRUE),
+ getOutputFileBase(),name(),
+ 0
+ );
+ }
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(this);
+ }
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->addListReferences(this);
+ }
+ }
+}
+
+MemberList *GroupDef::createMemberList(MemberListType lt)
+{
+ m_memberLists.setAutoDelete(TRUE);
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ // not found, create a new member list
+ ml = new MemberList(lt);
+ m_memberLists.append(ml);
+ ml->setInGroup(TRUE);
+ return ml;
+}
+
+void GroupDef::addMemberToList(MemberListType lt,MemberDef *md)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
+ MemberList *ml = createMemberList(lt);
+ ml->setNeedsSorting(
+ ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
+ ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
+ ml->append(md);
+}
+
+void GroupDef::sortMemberLists()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
+ }
+}
+
+MemberList *GroupDef::getMemberList(MemberListType lt) const
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (;(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ return 0;
+}
+
+void GroupDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+
+ MemberList * ml = getMemberList(lt);
+ if (optimizeVhdl && ml)
+ {
+ VhdlDocGen::writeVhdlDeclarations(ml,ol,this,0,0,0);
+ return;
+ }
+ if (ml)
+ {
+ ml->writeDeclarations(ol,0,0,0,this,title,0,definitionType());
+ }
+}
+
+void GroupDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDocumentation(ol,name(),this,title);
+}
+
+void GroupDef::removeMemberFromList(MemberListType lt,MemberDef *md)
+{
+ MemberList *ml = getMemberList(lt);
+ if (ml) ml->remove(md);
+}
+
+void GroupDef::sortSubGroups()
+{
+ groupList->sort();
+}
+
+bool GroupDef::isLinkableInProject() const
+{
+ return !isReference() && isLinkable();
+}
+
+bool GroupDef::isLinkable() const
+{
+ return hasUserDocumentation();
+}
+
+// let the "programming language" for a group depend on what is inserted into it.
+// First item that has an associated languages determines the language for the whole group.
+void GroupDef::updateLanguage(const Definition *d)
+{
+ if (getLanguage()==SrcLangExt_Unknown && d->getLanguage()!=SrcLangExt_Unknown)
+ {
+ setLanguage(d->getLanguage());
+ }
+}
+
+bool GroupDef::hasDetailedDescription() const
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ return ((!briefDescription().isEmpty() && repeatBrief) ||
+ !documentation().isEmpty());
+}
diff --git a/src/groupdef.h b/src/groupdef.h
new file mode 100644
index 0000000..bc956da
--- /dev/null
+++ b/src/groupdef.h
@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef GROUPDEF_H
+#define GROUPDEF_H
+
+#include "sortdict.h"
+#include "definition.h"
+
+class MemberList;
+class FileList;
+class ClassSDict;
+class FileDef;
+class ClassDef;
+class NamespaceDef;
+class GroupList;
+class OutputList;
+class NamespaceSDict;
+class MemberGroupSDict;
+class MemberNameInfoSDict;
+class PageSDict;
+class PageDef;
+class DirDef;
+class DirList;
+class FTVHelp;
+class Entry;
+class MemberDef;
+
+/** A model of a group of symbols. */
+class GroupDef : public Definition
+{
+ public:
+ GroupDef(const char *fileName,int line,const char *name,const char *title,const char *refFileName=0);
+ ~GroupDef();
+ DefType definitionType() const { return TypeGroup; }
+ QCString getOutputFileBase() const;
+ QCString anchor() const { return QCString(); }
+ QCString displayName(bool=TRUE) const { return hasGroupTitle() ? title : Definition::name(); }
+ const char *groupTitle() const { return title; }
+ void setGroupTitle( const char *newtitle );
+ bool hasGroupTitle( ) const { return titleSet; }
+ void addFile(const FileDef *def);
+ bool addClass(const ClassDef *def);
+ bool addNamespace(const NamespaceDef *def);
+ void addGroup(const GroupDef *def);
+ void addParentGroup(const GroupDef *def);
+ void addPage(PageDef *def);
+ void addExample(const PageDef *def);
+ void addDir(const DirDef *dd);
+ bool insertMember(MemberDef *def,bool docOnly=FALSE);
+ void removeMember(MemberDef *md);
+ bool containsGroup(const GroupDef *def); // true if def is already a subgroup
+ void writeDocumentation(OutputList &ol);
+ void writeMemberPages(OutputList &ol);
+ void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const;
+ int countMembers() const;
+ bool isLinkableInProject() const;
+ bool isLinkable() const;
+ bool isASubGroup() const;
+ void computeAnchors();
+
+ void addMembersToMemberGroup();
+ void distributeMemberGroupDocumentation();
+ void findSectionsInDocumentation();
+
+ void addListReferences();
+ void sortMemberLists();
+ bool subGrouping() const { return m_subGrouping; }
+
+ bool visited; // number of times accessed for output - KPW
+
+ //friend void writeGroupTreeNode(OutputList&, GroupDef*, int, FTVHelp*);
+ // make accessible for writing tree view of group in index.cpp - KPW
+
+ void setGroupScope(Definition *d) { groupScope = d; }
+ Definition *getGroupScope() const { return groupScope; }
+
+ MemberList *getMemberList(MemberListType lt) const;
+ const QList<MemberList> &getMemberLists() const { return m_memberLists; }
+
+ /* user defined member groups */
+ MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; }
+
+ FileList * getFiles() const { return fileList; }
+ ClassSDict * getClasses() const { return classSDict; }
+ NamespaceSDict * getNamespaces() const { return namespaceSDict; }
+ GroupList * getSubGroups() const { return groupList; }
+ PageSDict * getPages() const { return pageDict; }
+ DirList * getDirs() const { return dirList; }
+ PageSDict * getExamples() const { return exampleDict; }
+ bool hasDetailedDescription() const;
+ //MemberList* getMembers() const { return allMemberList; }
+ void sortSubGroups();
+
+ protected:
+ void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const);
+
+ private:
+ MemberList *createMemberList(MemberListType lt);
+ void addMemberToList(MemberListType lt,MemberDef *md);
+ void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
+ void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
+ void removeMemberFromList(MemberListType lt,MemberDef *md);
+ void writeGroupGraph(OutputList &ol);
+ void writeFiles(OutputList &ol,const QCString &title);
+ void writeNamespaces(OutputList &ol,const QCString &title);
+ void writeNestedGroups(OutputList &ol,const QCString &title);
+ void writeDirs(OutputList &ol,const QCString &title);
+ void writeClasses(OutputList &ol,const QCString &title);
+ void writeInlineClasses(OutputList &ol);
+ void writePageDocumentation(OutputList &ol);
+ void writeDetailedDescription(OutputList &ol,const QCString &title);
+ void writeBriefDescription(OutputList &ol);
+ void writeMemberGroups(OutputList &ol);
+ void startMemberDeclarations(OutputList &ol);
+ void endMemberDeclarations(OutputList &ol);
+ void startMemberDocumentation(OutputList &ol);
+ void endMemberDocumentation(OutputList &ol);
+ void writeAuthorSection(OutputList &ol);
+ void writeSummaryLinks(OutputList &ol);
+ void updateLanguage(const Definition *);
+
+ QCString title; // title of the group
+ bool titleSet; // true if title is not the same as the name
+ QCString fileName; // base name of the generated file
+ FileList *fileList; // list of files in the group
+ ClassSDict *classSDict; // list of classes in the group
+ NamespaceSDict *namespaceSDict; // list of namespaces in the group
+ GroupList *groupList; // list of sub groups.
+ PageSDict *pageDict; // list of pages in the group
+ PageSDict *exampleDict; // list of examples in the group
+ DirList *dirList; // list of directories in the group
+
+ MemberList *allMemberList;
+ MemberNameInfoSDict *allMemberNameInfoSDict;
+
+ Definition *groupScope;
+
+ QList<MemberList> m_memberLists;
+ MemberGroupSDict *memberGroupSDict;
+ bool m_subGrouping;
+
+};
+
+/** A sorted dictionary of GroupDef objects. */
+class GroupSDict : public SDict<GroupDef>
+{
+ public:
+ GroupSDict(uint size) : SDict<GroupDef>(size) {}
+ virtual ~GroupSDict() {}
+ private:
+ int compareValues(const GroupDef *item1,const GroupDef *item2) const
+ {
+ return qstrcmp(item1->groupTitle(),item2->groupTitle());
+ }
+};
+
+/** A list of GroupDef objects. */
+class GroupList : public QList<GroupDef>
+{
+ public:
+ int compareValues(const GroupDef *item1,const GroupDef *item2) const
+ {
+ return qstrcmp(item1->groupTitle(),item2->groupTitle());
+ }
+};
+
+/** An iterator for GroupDef objects in a GroupList. */
+class GroupListIterator : public QListIterator<GroupDef>
+{
+ public:
+ GroupListIterator(const GroupList &l) : QListIterator<GroupDef>(l) {}
+ virtual ~GroupListIterator() {}
+};
+
+void addClassToGroups(Entry *root,ClassDef *cd);
+void addNamespaceToGroups(Entry *root,NamespaceDef *nd);
+void addGroupToGroups(Entry *root,GroupDef *subGroup);
+void addMemberToGroups(Entry *root,MemberDef *md);
+void addPageToGroups(Entry *root,PageDef *pd);
+void addExampleToGroups(Entry *root,PageDef *eg);
+void addDirToGroups(Entry *root,DirDef *dd);
+
+#endif
+
diff --git a/src/growbuf.h b/src/growbuf.h
new file mode 100644
index 0000000..bc8e4b5
--- /dev/null
+++ b/src/growbuf.h
@@ -0,0 +1,47 @@
+#ifndef GROWBUF_H
+#define GROWBUF_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#define GROW_AMOUNT 1024
+
+/** Class representing a string buffer optimised for growing. */
+class GrowBuf
+{
+ public:
+ GrowBuf() : str(0), pos(0), len(0) {}
+ ~GrowBuf() { free(str); str=0; pos=0; len=0; }
+ void clear() { pos=0; }
+ void addChar(char c) { if (pos>=len) { len+=GROW_AMOUNT; str = (char*)realloc(str,len); }
+ str[pos++]=c;
+ }
+ void addStr(const char *s) {
+ if (s)
+ {
+ int l=strlen(s);
+ if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); }
+ strcpy(&str[pos],s);
+ pos+=l;
+ }
+ }
+ void addStr(const char *s,int n) {
+ if (s)
+ {
+ int l=strlen(s);
+ if (n<l) l=n;
+ if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); }
+ strncpy(&str[pos],s,n);
+ pos+=l;
+ }
+ }
+ const char *get() { return str; }
+ int getPos() const { return pos; }
+ char at(int i) const { return str[i]; }
+ private:
+ char *str;
+ int pos;
+ int len;
+};
+
+#endif
diff --git a/src/header.html b/src/header.html
new file mode 100644
index 0000000..70305df
--- /dev/null
+++ b/src/header.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <!--BEGIN PROJECT_LOGO-->
+ <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
+ <!--END PROJECT_LOGO-->
+ <!--BEGIN PROJECT_NAME-->
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">$projectname
+ <!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
+ </div>
+ <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
+ </td>
+ <!--END PROJECT_NAME-->
+ <!--BEGIN !PROJECT_NAME-->
+ <!--BEGIN PROJECT_BRIEF-->
+ <td style="padding-left: 0.5em;">
+ <div id="projectbrief">$projectbrief</div>
+ </td>
+ <!--END PROJECT_BRIEF-->
+ <!--END !PROJECT_NAME-->
+ <!--BEGIN DISABLE_INDEX-->
+ <!--BEGIN SEARCHENGINE-->
+ <td>$searchbox</td>
+ <!--END SEARCHENGINE-->
+ <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/src/htags.cpp b/src/htags.cpp
new file mode 100644
index 0000000..1e18ae1
--- /dev/null
+++ b/src/htags.cpp
@@ -0,0 +1,178 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+
+#include <qdir.h>
+#include <qdict.h>
+
+#include "htags.h"
+#include "util.h"
+#include "message.h"
+#include "config.h"
+#include "portable.h"
+
+
+bool Htags::useHtags = FALSE;
+
+static QDir g_inputDir;
+static QDict<QCString> g_symbolDict(10007);
+
+/*! constructs command line of htags(1) and executes it.
+ * \retval TRUE success
+ * \retval FALSE an error has occurred.
+ */
+bool Htags::execute(const QCString &htmldir)
+{
+ static QStrList &inputSource = Config_getList("INPUT");
+ static bool quiet = Config_getBool("QUIET");
+ static bool warnings = Config_getBool("WARNINGS");
+ static QCString htagsOptions = ""; //Config_getString("HTAGS_OPTIONS");
+ static QCString projectName = Config_getString("PROJECT_NAME");
+ static QCString projectNumber = Config_getString("PROJECT_NUMBER");
+
+ QCString cwd = QDir::currentDirPath().utf8();
+ if (inputSource.isEmpty())
+ {
+ g_inputDir.setPath(cwd);
+ }
+ else if (inputSource.count()==1)
+ {
+ g_inputDir.setPath(inputSource.first());
+ if (!g_inputDir.exists())
+ err("Cannot find directory %s. "
+ "Check the value of the INPUT tag in the configuration file.\n",
+ inputSource.first()
+ );
+ }
+ else
+ {
+ err("If you use USE_HTAGS then INPUT should specific a single directory. \n");
+ return FALSE;
+ }
+
+ /*
+ * Construct command line for htags(1).
+ */
+ QCString commandLine = " -g -s -a -n ";
+ if (!quiet) commandLine += "-v ";
+ if (warnings) commandLine += "-w ";
+ if (!htagsOptions.isEmpty())
+ {
+ commandLine += ' ';
+ commandLine += htagsOptions;
+ }
+ if (!projectName.isEmpty())
+ {
+ commandLine += "-t \"";
+ commandLine += projectName;
+ if (!projectNumber.isEmpty())
+ {
+ commandLine += '-';
+ commandLine += projectNumber;
+ }
+ commandLine += "\" ";
+ }
+ commandLine += " \"" + htmldir + "\"";
+ QCString oldDir = QDir::currentDirPath().utf8();
+ QDir::setCurrent(g_inputDir.absPath());
+ //printf("CommandLine=[%s]\n",commandLine.data());
+ portable_sysTimerStart();
+ bool result=portable_system("htags",commandLine,FALSE)==0;
+ portable_sysTimerStop();
+ QDir::setCurrent(oldDir);
+ return result;
+}
+
+
+/*! load filemap and make index.
+ * \param htmlDir of HTML directory generated by htags(1).
+ * \retval TRUE success
+ * \retval FALSE error
+ */
+bool Htags::loadFilemap(const QCString &htmlDir)
+{
+ QCString fileMapName = htmlDir+"/HTML/FILEMAP";
+ QCString fileMap;
+ QFileInfo fi(fileMapName);
+ /*
+ * Construct FILEMAP dictionary using QDict.
+ *
+ * In FILEMAP, URL includes 'html' suffix but we cut it off according
+ * to the method of FileDef class.
+ *
+ * FILEMAP format:
+ * <NAME>\t<HREF>.html\n
+ * QDICT:
+ * dict[<NAME>] = <HREF>
+ */
+ if (fi.exists() && fi.isReadable())
+ {
+ QFile f(fileMapName);
+ const int maxlen = 8192;
+ QCString line(maxlen+1);
+ line.at(maxlen)='\0';
+ if (f.open(IO_ReadOnly))
+ {
+ while (f.readLine(line.data(),maxlen)>0)
+ {
+ //printf("Read line: %s",line.data());
+ int sep = line.find('\t');
+ if (sep!=-1)
+ {
+ QCString key = line.left(sep).stripWhiteSpace();
+ QCString value = line.mid(sep+1).stripWhiteSpace();
+ int ext=value.findRev('.');
+ if (ext!=-1) value=value.left(ext); // strip extension
+ g_symbolDict.setAutoDelete(TRUE);
+ g_symbolDict.insert(key,new QCString(value));
+ //printf("Key/Value=(%s,%s)\n",key.data(),value.data());
+ }
+ }
+ return TRUE;
+ }
+ else
+ {
+ err("file %s cannot be opened\n",fileMapName.data());
+ }
+ }
+ return FALSE;
+}
+
+/*! convert path name into the url in the hypertext generated by htags.
+ * \param path path name
+ * \returns URL NULL: not found.
+ */
+QCString Htags::path2URL(const QCString &path)
+{
+ QCString url,symName=path;
+ QCString dir = g_inputDir.absPath().utf8();
+ int dl=dir.length();
+ if ((int)symName.length()>dl+1)
+ {
+ symName = symName.mid(dl+1);
+ }
+ if (!symName.isEmpty())
+ {
+ QCString *result = g_symbolDict[symName];
+ //printf("path2URL=%s symName=%s result=%p\n",path.data(),symName.data(),result);
+ if (result)
+ {
+ url = "HTML/" + *result;
+ }
+ }
+ return url;
+}
+
diff --git a/src/htags.h b/src/htags.h
new file mode 100644
index 0000000..5173b2b
--- /dev/null
+++ b/src/htags.h
@@ -0,0 +1,29 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#ifndef HTAGS_H
+#define HTAGS_H
+
+class QCString;
+
+/** This class is a namespace for HTAGS related functions */
+struct Htags
+{
+ static bool useHtags;
+ static bool loadFilemap(const QCString &htmldir);
+ static QCString path2URL(const QCString &path);
+ static bool execute(const QCString &htmldir);
+};
+
+#endif /* HTAGS_H */
diff --git a/src/htmlattrib.h b/src/htmlattrib.h
new file mode 100644
index 0000000..e7fd204
--- /dev/null
+++ b/src/htmlattrib.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef _HTMLATTRIB_H
+#define _HTMLATTRIB_H
+
+#include <qcstring.h>
+#include <qlist.h>
+
+/*! A Html option. A name, value pair */
+struct HtmlAttrib
+{
+ QCString name;
+ QCString value;
+};
+
+/*! @brief A list of Html attributes.
+ *
+ * The Html attributes are deeply copied into the list.
+ */
+class HtmlAttribList : public QList<HtmlAttrib>
+{
+ public:
+ HtmlAttribList() : QList<HtmlAttrib>() { setAutoDelete(TRUE); }
+ ~HtmlAttribList() { clear(); }
+ HtmlAttribList(const HtmlAttribList &l) : QList<HtmlAttrib>()
+ { operator=(l); }
+ HtmlAttribList &operator=(const HtmlAttribList &l)
+ { clear(); QList<HtmlAttrib>::operator=(l); return *this; }
+ QCString find(const QCString name) const
+ {
+ QListIterator<HtmlAttrib> it(*this);
+ QCString result;
+ HtmlAttrib *attr;
+ for (;(attr=it.current());++it)
+ {
+ if (attr->name==name) return attr->value;
+ }
+ return result;
+ }
+ QCString toString() const
+ {
+ QListIterator<HtmlAttrib> it(*this);
+ QCString result;
+ HtmlAttrib *attr;
+ for (;(attr=it.current());++it)
+ {
+ result+=" "+attr->name+"=\""+attr->value+"\"";
+ }
+ return result;
+ }
+ private:
+ HtmlAttrib *newValue( HtmlAttrib *v ) const
+ { return new HtmlAttrib(*v); }
+ void deleteValue(HtmlAttrib *v) const
+ { delete v; }
+};
+
+/*! @brief Html attribute list iterator */
+class HtmlAttribListIterator : public QListIterator<HtmlAttrib>
+{
+ public:
+ HtmlAttribListIterator(const HtmlAttribList &l) : QListIterator<HtmlAttrib>(l) {}
+};
+
+#endif
+
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
new file mode 100644
index 0000000..e319a1f
--- /dev/null
+++ b/src/htmldocvisitor.cpp
@@ -0,0 +1,2098 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qdir.h>
+#include "htmldocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "message.h"
+#include "config.h"
+#include "htmlgen.h"
+#include "parserintf.h"
+#include "msc.h"
+#include "dia.h"
+#include "util.h"
+#include "vhdldocgen.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "htmlentity.h"
+#include "plantuml.h"
+
+static const int NUM_HTML_LIST_TYPES = 4;
+static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"};
+
+static QCString convertIndexWordToAnchor(const QString &word)
+{
+ static char hex[] = "0123456789abcdef";
+ QCString result;
+ const char *str = word.data();
+ unsigned char c;
+ if (str)
+ {
+ while ((c = *str++))
+ {
+ if ((c >= 'a' && c <= 'z') || // ALPHA
+ (c >= 'A' && c <= 'A') || // ALPHA
+ (c >= '0' && c <= '9') || // DIGIT
+ c == '-' ||
+ c == '.' ||
+ c == '_' ||
+ c == '~'
+ )
+ {
+ result += c;
+ }
+ else
+ {
+ char enc[4];
+ enc[0] = '%';
+ enc[1] = hex[(c & 0xf0) >> 4];
+ enc[2] = hex[c & 0xf];
+ enc[3] = 0;
+ result += enc;
+ }
+ }
+ }
+ return result;
+}
+
+static bool mustBeOutsideParagraph(DocNode *n)
+{
+ switch (n->kind())
+ {
+ /* <ul> */
+ case DocNode::Kind_HtmlList:
+ case DocNode::Kind_SimpleList:
+ case DocNode::Kind_AutoList:
+ /* <dl> */
+ case DocNode::Kind_SimpleSect:
+ case DocNode::Kind_ParamSect:
+ case DocNode::Kind_HtmlDescList:
+ case DocNode::Kind_XRefItem:
+ /* <table> */
+ case DocNode::Kind_HtmlTable:
+ /* <h?> */
+ case DocNode::Kind_Section:
+ case DocNode::Kind_HtmlHeader:
+ /* \internal */
+ case DocNode::Kind_Internal:
+ /* <div> */
+ case DocNode::Kind_Include:
+ case DocNode::Kind_Image:
+ case DocNode::Kind_SecRefList:
+ /* <hr> */
+ case DocNode::Kind_HorRuler:
+ /* CopyDoc gets paragraph markers from the wrapping DocPara node,
+ * but needs to insert them for all documentation being copied to
+ * preserve formatting.
+ */
+ case DocNode::Kind_Copy:
+ /* <blockquote> */
+ case DocNode::Kind_HtmlBlockQuote:
+ /* \parblock */
+ case DocNode::Kind_ParBlock:
+ return TRUE;
+ case DocNode::Kind_Verbatim:
+ {
+ DocVerbatim *dv = (DocVerbatim*)n;
+ return dv->type()!=DocVerbatim::HtmlOnly || dv->isBlock();
+ }
+ case DocNode::Kind_StyleChange:
+ return ((DocStyleChange*)n)->style()==DocStyleChange::Preformatted ||
+ ((DocStyleChange*)n)->style()==DocStyleChange::Div ||
+ ((DocStyleChange*)n)->style()==DocStyleChange::Center;
+ case DocNode::Kind_Formula:
+ return !((DocFormula*)n)->isInline();
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static QString htmlAttribsToString(const HtmlAttribList &attribs)
+{
+ QString result;
+ HtmlAttribListIterator li(attribs);
+ HtmlAttrib *att;
+ for (li.toFirst();(att=li.current());++li)
+ {
+ if (!att->value.isEmpty()) // ignore attribute without values as they
+ // are not XHTML compliant
+ {
+ result+=" ";
+ result+=att->name;
+ result+="=\""+convertToXML(att->value)+"\"";
+ }
+ }
+ return result;
+}
+
+//-------------------------------------------------------------------------
+
+HtmlDocVisitor::HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci,
+ Definition *ctx)
+ : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_insidePre(FALSE),
+ m_hide(FALSE), m_ctx(ctx)
+{
+ if (ctx) m_langExt=ctx->getDefFileExtension();
+}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+void HtmlDocVisitor::visit(DocWord *w)
+{
+ //printf("word: %s\n",w->word().data());
+ if (m_hide) return;
+ filter(w->word());
+}
+
+void HtmlDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ //printf("linked word: %s\n",w->word().data());
+ startLink(w->ref(),w->file(),w->relPath(),w->anchor(),w->tooltip());
+ filter(w->word());
+ endLink();
+}
+
+void HtmlDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ }
+ else
+ {
+ m_t << " ";
+ }
+}
+
+void HtmlDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ const char *res = HtmlEntityMapper::instance()->html(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ err("HTML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+}
+
+void HtmlDocVisitor::writeObfuscatedMailAddress(const QCString &url)
+{
+ m_t << "<a href=\"#\" onclick=\"location.href='mai'+'lto:'";
+ uint i;
+ int size=3;
+ for (i=0;i<url.length();)
+ {
+ m_t << "+'" << url.mid(i,size) << "'";
+ i+=size;
+ if (size==3) size=2; else size=3;
+ }
+ m_t << "; return false;\">";
+}
+
+void HtmlDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ if (u->isEmail()) // mail address
+ {
+ QCString url = u->url();
+ writeObfuscatedMailAddress(url);
+ uint size=5,i;
+ for (i=0;i<url.length();)
+ {
+ filter(url.mid(i,size));
+ if (i<url.length()-size) m_t << "<span style=\"display: none;\">.nosp at m.</span>";
+ i+=size;
+ if (size==5) size=4; else size=5;
+ }
+ m_t << "</a>";
+ }
+ else // web address
+ {
+ m_t << "<a href=\"";
+ m_t << u->url() << "\">";
+ filter(u->url());
+ m_t << "</a>";
+ }
+}
+
+void HtmlDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ m_t << "<br />\n";
+}
+
+void HtmlDocVisitor::visit(DocHorRuler *hr)
+{
+ if (m_hide) return;
+ forceEndParagraph(hr);
+ m_t << "<hr/>\n";
+ forceStartParagraph(hr);
+}
+
+void HtmlDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "<b" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</b>";
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "<em" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</em>";
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "<code" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</code>";
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "<sub" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</sub>";
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "<sup" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</sup>";
+ break;
+ case DocStyleChange::Center:
+ if (s->enable())
+ {
+ forceEndParagraph(s);
+ m_t << "<center" << htmlAttribsToString(s->attribs()) << ">";
+ }
+ else
+ {
+ m_t << "</center>";
+ forceStartParagraph(s);
+ }
+ break;
+ case DocStyleChange::Small:
+ if (s->enable()) m_t << "<small" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</small>";
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ forceEndParagraph(s);
+ m_t << "<pre" << htmlAttribsToString(s->attribs()) << ">";
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_insidePre=FALSE;
+ m_t << "</pre>";
+ forceStartParagraph(s);
+ }
+ break;
+ case DocStyleChange::Div:
+ if (s->enable())
+ {
+ forceEndParagraph(s);
+ m_t << "<div" << htmlAttribsToString(s->attribs()) << ">";
+ }
+ else
+ {
+ m_t << "</div>";
+ forceStartParagraph(s);
+ }
+ break;
+ case DocStyleChange::Span:
+ if (s->enable()) m_t << "<span" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</span>";
+ break;
+
+ }
+}
+
+
+void HtmlDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ QCString lang = m_langExt;
+ if (!s->language().isEmpty()) // explicit language setting
+ {
+ lang = s->language();
+ }
+ SrcLangExt langExt = getLanguageFromFileName(lang);
+ switch(s->type())
+ {
+ case DocVerbatim::Code:
+ forceEndParagraph(s);
+ m_t << PREFRAG_START;
+ Doxygen::parserManager->getParser(lang)
+ ->parseCode(m_ci,
+ s->context(),
+ s->text(),
+ langExt,
+ s->isExample(),
+ s->exampleFile(),
+ 0, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inlineFragment
+ 0, // memberDef
+ TRUE, // show line numbers
+ m_ctx // search context
+ );
+ m_t << PREFRAG_END;
+ forceStartParagraph(s);
+ break;
+ case DocVerbatim::Verbatim:
+ forceEndParagraph(s);
+ m_t << /*PREFRAG_START <<*/ "<pre class=\"fragment\">";
+ filter(s->text());
+ m_t << "</pre>" /*<< PREFRAG_END*/;
+ forceStartParagraph(s);
+ break;
+ case DocVerbatim::HtmlOnly:
+ if (s->isBlock()) forceEndParagraph(s);
+ m_t << s->text();
+ if (s->isBlock()) forceStartParagraph(s);
+ break;
+ case DocVerbatim::ManOnly:
+ case DocVerbatim::LatexOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::RtfOnly:
+ case DocVerbatim::DocbookOnly:
+ /* nothing */
+ break;
+
+ case DocVerbatim::Dot:
+ {
+ static int dotindex = 1;
+ QCString fileName(4096);
+
+ fileName.sprintf("%s%d%s",
+ (Config_getString("HTML_OUTPUT")+"/inline_dotgraph_").data(),
+ dotindex++,
+ ".dot"
+ );
+ QFile file(fileName);
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ }
+ file.writeBlock( s->text(), s->text().length() );
+ file.close();
+
+ forceEndParagraph(s);
+ m_t << "<div align=\"center\">" << endl;
+ writeDotFile(fileName,s->relPath(),s->context());
+ m_t << "</div>" << endl;
+ forceStartParagraph(s);
+
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ }
+ break;
+ case DocVerbatim::Msc:
+ {
+ forceEndParagraph(s);
+
+ static int mscindex = 1;
+ QCString baseName(4096);
+
+ baseName.sprintf("%s%d",
+ (Config_getString("HTML_OUTPUT")+"/inline_mscgraph_").data(),
+ mscindex++
+ );
+ QFile file(baseName+".msc");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s.msc for writing\n",baseName.data());
+ }
+ QCString text = "msc {";
+ text+=s->text();
+ text+="}";
+
+ file.writeBlock( text, text.length() );
+ file.close();
+
+ m_t << "<div align=\"center\">" << endl;
+ writeMscFile(baseName+".msc",s->relPath(),s->context());
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ m_t << "</div>" << endl;
+ forceStartParagraph(s);
+ }
+ break;
+ case DocVerbatim::PlantUML:
+ {
+ forceEndParagraph(s);
+
+ static QCString htmlOutput = Config_getString("HTML_OUTPUT");
+ QCString baseName = writePlantUMLSource(htmlOutput,s->exampleFile(),s->text());
+ m_t << "<div align=\"center\">" << endl;
+ writePlantUMLFile(baseName,s->relPath(),s->context());
+ m_t << "</div>" << endl;
+ forceStartParagraph(s);
+ }
+ break;
+ }
+}
+
+void HtmlDocVisitor::visit(DocAnchor *anc)
+{
+ if (m_hide) return;
+ m_t << "<a class=\"anchor\" id=\"" << anc->anchor() << "\"></a>";
+}
+
+void HtmlDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ switch(inc->type())
+ {
+ case DocInclude::Include:
+ forceEndParagraph(inc);
+ m_t << PREFRAG_START;
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(),
+ 0, // fileDef
+ -1, // startLine
+ -1, // endLine
+ TRUE, // inlineFragment
+ 0, // memberDef
+ FALSE, // show line numbers
+ m_ctx // search context
+ );
+ m_t << PREFRAG_END;
+ forceStartParagraph(inc);
+ break;
+ case DocInclude::IncWithLines:
+ {
+ forceEndParagraph(inc);
+ m_t << PREFRAG_START;
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(),
+ &fd, // fileDef,
+ -1, // start line
+ -1, // end line
+ FALSE, // inline fragment
+ 0, // memberDef
+ TRUE, // show line numbers
+ m_ctx // search context
+ );
+ m_t << PREFRAG_END;
+ forceStartParagraph(inc);
+ }
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ m_t << inc->text();
+ break;
+ case DocInclude::LatexInclude:
+ break;
+ case DocInclude::VerbInclude:
+ forceEndParagraph(inc);
+ m_t << /*PREFRAG_START <<*/ "<pre class=\"fragment\">";
+ filter(inc->text());
+ m_t << "</pre>" /*<< PREFRAG_END*/;
+ forceStartParagraph(inc);
+ break;
+ case DocInclude::Snippet:
+ {
+ forceEndParagraph(inc);
+ m_t << PREFRAG_START;
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(),
+ 0,
+ -1, // startLine
+ -1, // endLine
+ TRUE, // inlineFragment
+ 0, // memberDef
+ TRUE, // show line number
+ m_ctx // search context
+ );
+ m_t << PREFRAG_END;
+ forceStartParagraph(inc);
+ }
+ break;
+ }
+}
+
+void HtmlDocVisitor::visit(DocIncOperator *op)
+{
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ if (op->isFirst())
+ {
+ if (!m_hide) m_t << PREFRAG_START;
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(
+ m_ci,
+ op->context(),
+ op->text(),
+ langExt,
+ op->isExample(),
+ op->exampleFile(),
+ 0, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inline fragment
+ 0, // memberDef
+ TRUE, // show line numbers
+ m_ctx // search context
+ );
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide) m_t << PREFRAG_END;
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ }
+}
+
+void HtmlDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ bool bDisplay = !f->isInline();
+ if (bDisplay)
+ {
+ forceEndParagraph(f);
+ m_t << "<p class=\"formulaDsp\">" << endl;
+ }
+
+ if (Config_getBool("USE_MATHJAX"))
+ {
+ QCString text = f->text();
+ bool closeInline = FALSE;
+ if (!bDisplay && !text.isEmpty() && text.at(0)=='$' &&
+ text.at(text.length()-1)=='$')
+ {
+ closeInline=TRUE;
+ text = text.mid(1,text.length()-2);
+ m_t << "\\(";
+ }
+ m_t << convertToHtml(text);
+ if (closeInline)
+ {
+ m_t << "\\)";
+ }
+ }
+ else
+ {
+ m_t << "<img class=\"formula"
+ << (bDisplay ? "Dsp" : "Inl");
+ m_t << "\" alt=\"";
+ filterQuotedCdataAttr(f->text());
+ m_t << "\"";
+ // TODO: cache image dimensions on formula generation and give height/width
+ // for faster preloading and better rendering of the page
+ m_t << " src=\"" << f->relPath() << f->name() << ".png\"/>";
+
+ }
+ if (bDisplay)
+ {
+ m_t << endl << "</p>" << endl;
+ forceStartParagraph(f);
+ }
+}
+
+void HtmlDocVisitor::visit(DocIndexEntry *e)
+{
+ QCString anchor = convertIndexWordToAnchor(e->entry());
+ if (e->member())
+ {
+ anchor.prepend(e->member()->anchor()+"_");
+ }
+ m_t << "<a name=\"" << anchor << "\"></a>";
+ //printf("*** DocIndexEntry: word='%s' scope='%s' member='%s'\n",
+ // e->entry().data(),
+ // e->scope() ? e->scope()->name().data() : "<null>",
+ // e->member() ? e->member()->name().data() : "<null>"
+ // );
+ Doxygen::indexList->addIndexItem(e->scope(),e->member(),anchor,e->entry());
+}
+
+void HtmlDocVisitor::visit(DocSimpleSectSep *)
+{
+ m_t << "</dd>" << endl;
+ m_t << "<dd>" << endl;
+}
+
+void HtmlDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ if (!cite->file().isEmpty())
+ {
+ startLink(cite->ref(),cite->file(),cite->relPath(),cite->anchor());
+ }
+ else
+ {
+ m_t << "<b>[";
+ }
+ filter(cite->text());
+ if (!cite->file().isEmpty())
+ {
+ endLink();
+ }
+ else
+ {
+ m_t << "]</b>";
+ }
+}
+
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+
+void HtmlDocVisitor::visitPre(DocAutoList *l)
+{
+ //printf("DocAutoList::visitPre\n");
+ if (m_hide) return;
+ forceEndParagraph(l);
+ if (l->isEnumList())
+ {
+ //
+ // Do list type based on depth:
+ // 1.
+ // a.
+ // i.
+ // A.
+ // 1. (repeat)...
+ //
+ m_t << "<ol type=\"" << types[l->depth() % NUM_HTML_LIST_TYPES] << "\">";
+ }
+ else
+ {
+ m_t << "<ul>";
+ }
+ if (!l->isPreformatted()) m_t << "\n";
+}
+
+void HtmlDocVisitor::visitPost(DocAutoList *l)
+{
+ //printf("DocAutoList::visitPost\n");
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "</ol>";
+ }
+ else
+ {
+ m_t << "</ul>";
+ }
+ if (!l->isPreformatted()) m_t << "\n";
+ forceStartParagraph(l);
+}
+
+void HtmlDocVisitor::visitPre(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "<li>";
+}
+
+void HtmlDocVisitor::visitPost(DocAutoListItem *li)
+{
+ if (m_hide) return;
+ m_t << "</li>";
+ if (!li->isPreformatted()) m_t << "\n";
+}
+
+template<class T>
+bool isFirstChildNode(T *parent, DocNode *node)
+{
+ return parent->children().getFirst()==node;
+}
+
+template<class T>
+bool isLastChildNode(T *parent, DocNode *node)
+{
+ return parent->children().getLast()==node;
+}
+
+bool isSeparatedParagraph(DocSimpleSect *parent,DocPara *par)
+{
+ QList<DocNode> nodes = parent->children();
+ int i = nodes.findRef(par);
+ if (i==-1) return FALSE;
+ int count = parent->children().count();
+ if (count>1 && i==0) // first node
+ {
+ if (nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep)
+ {
+ return TRUE;
+ }
+ }
+ else if (count>1 && i==count-1) // last node
+ {
+ if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep)
+ {
+ return TRUE;
+ }
+ }
+ else if (count>2 && i>0 && i<count-1) // intermediate node
+ {
+ if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep &&
+ nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast)
+{
+ int t=0;
+ isFirst=FALSE;
+ isLast=FALSE;
+ if (p && p->parent())
+ {
+ switch (p->parent()->kind())
+ {
+ case DocNode::Kind_ParBlock:
+ { // hierarchy: node N -> para -> parblock -> para
+ // adapt return value to kind of N
+ DocNode::Kind kind = DocNode::Kind_Para;
+ if ( p->parent()->parent() && p->parent()->parent()->parent() )
+ {
+ kind = p->parent()->parent()->parent()->kind();
+ }
+ isFirst=isFirstChildNode((DocParBlock*)p->parent(),p);
+ isLast =isLastChildNode ((DocParBlock*)p->parent(),p);
+ t=0;
+ if (isFirst)
+ {
+ if (kind==DocNode::Kind_HtmlListItem ||
+ kind==DocNode::Kind_SecRefItem)
+ {
+ t=1;
+ }
+ else if (kind==DocNode::Kind_HtmlDescData ||
+ kind==DocNode::Kind_XRefItem ||
+ kind==DocNode::Kind_SimpleSect)
+ {
+ t=2;
+ }
+ else if (kind==DocNode::Kind_HtmlCell ||
+ kind==DocNode::Kind_ParamList)
+ {
+ t=5;
+ }
+ }
+ if (isLast)
+ {
+ if (kind==DocNode::Kind_HtmlListItem ||
+ kind==DocNode::Kind_SecRefItem)
+ {
+ t=3;
+ }
+ else if (kind==DocNode::Kind_HtmlDescData ||
+ kind==DocNode::Kind_XRefItem ||
+ kind==DocNode::Kind_SimpleSect)
+ {
+ t=4;
+ }
+ else if (kind==DocNode::Kind_HtmlCell ||
+ kind==DocNode::Kind_ParamList)
+ {
+ t=6;
+ }
+ }
+ break;
+ }
+ case DocNode::Kind_AutoListItem:
+ isFirst=isFirstChildNode((DocAutoListItem*)p->parent(),p);
+ isLast =isLastChildNode ((DocAutoListItem*)p->parent(),p);
+ t=1; // not used
+ break;
+ case DocNode::Kind_SimpleListItem:
+ isFirst=TRUE;
+ isLast =TRUE;
+ t=1; // not used
+ break;
+ case DocNode::Kind_ParamList:
+ isFirst=TRUE;
+ isLast =TRUE;
+ t=1; // not used
+ break;
+ case DocNode::Kind_HtmlListItem:
+ isFirst=isFirstChildNode((DocHtmlListItem*)p->parent(),p);
+ isLast =isLastChildNode ((DocHtmlListItem*)p->parent(),p);
+ if (isFirst) t=1;
+ if (isLast) t=3;
+ break;
+ case DocNode::Kind_SecRefItem:
+ isFirst=isFirstChildNode((DocSecRefItem*)p->parent(),p);
+ isLast =isLastChildNode ((DocSecRefItem*)p->parent(),p);
+ if (isFirst) t=1;
+ if (isLast) t=3;
+ break;
+ case DocNode::Kind_HtmlDescData:
+ isFirst=isFirstChildNode((DocHtmlDescData*)p->parent(),p);
+ isLast =isLastChildNode ((DocHtmlDescData*)p->parent(),p);
+ if (isFirst) t=2;
+ if (isLast) t=4;
+ break;
+ case DocNode::Kind_XRefItem:
+ isFirst=isFirstChildNode((DocXRefItem*)p->parent(),p);
+ isLast =isLastChildNode ((DocXRefItem*)p->parent(),p);
+ if (isFirst) t=2;
+ if (isLast) t=4;
+ break;
+ case DocNode::Kind_SimpleSect:
+ isFirst=isFirstChildNode((DocSimpleSect*)p->parent(),p);
+ isLast =isLastChildNode ((DocSimpleSect*)p->parent(),p);
+ if (isFirst) t=2;
+ if (isLast) t=4;
+ if (isSeparatedParagraph((DocSimpleSect*)p->parent(),p))
+ // if the paragraph is enclosed with separators it will
+ // be included in <dd>..</dd> so avoid addition paragraph
+ // markers
+ {
+ isFirst=isLast=TRUE;
+ }
+ break;
+ case DocNode::Kind_HtmlCell:
+ isFirst=isFirstChildNode((DocHtmlCell*)p->parent(),p);
+ isLast =isLastChildNode ((DocHtmlCell*)p->parent(),p);
+ if (isFirst) t=5;
+ if (isLast) t=6;
+ break;
+ default:
+ break;
+ }
+ //printf("para=%p parent()->kind=%d isFirst=%d isLast=%d t=%d\n",
+ // p,p->parent()->kind(),isFirst,isLast,t);
+ }
+ return t;
+}
+
+void HtmlDocVisitor::visitPre(DocPara *p)
+{
+ if (m_hide) return;
+
+ //printf("DocPara::visitPre: parent of kind %d ",
+ // p->parent() ? p->parent()->kind() : -1);
+
+ bool needsTag = FALSE;
+ if (p && p->parent())
+ {
+ switch (p->parent()->kind())
+ {
+ case DocNode::Kind_Section:
+ case DocNode::Kind_Internal:
+ case DocNode::Kind_HtmlListItem:
+ case DocNode::Kind_HtmlDescData:
+ case DocNode::Kind_HtmlCell:
+ case DocNode::Kind_SimpleListItem:
+ case DocNode::Kind_AutoListItem:
+ case DocNode::Kind_SimpleSect:
+ case DocNode::Kind_XRefItem:
+ case DocNode::Kind_Copy:
+ case DocNode::Kind_HtmlBlockQuote:
+ case DocNode::Kind_ParBlock:
+ needsTag = TRUE;
+ break;
+ case DocNode::Kind_Root:
+ needsTag = !((DocRoot*)p->parent())->singleLine();
+ break;
+ default:
+ needsTag = FALSE;
+ }
+ }
+
+ // if the first element of a paragraph is something that should be outside of
+ // the paragraph (<ul>,<dl>,<table>,..) then that will already started the
+ // paragraph and we don't need to do it here
+ uint nodeIndex = 0;
+ if (p && nodeIndex<p->children().count())
+ {
+ while (nodeIndex<p->children().count() &&
+ p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace)
+ {
+ nodeIndex++;
+ }
+ if (nodeIndex<p->children().count())
+ {
+ DocNode *n = p->children().at(nodeIndex);
+ if (mustBeOutsideParagraph(n))
+ {
+ needsTag = FALSE;
+ }
+ }
+ }
+
+ // check if this paragraph is the first or last child of a <li> or <dd>.
+ // this allows us to mark the tag with a special class so we can
+ // fix the otherwise ugly spacing.
+ int t;
+ static const char *contexts[7] =
+ { "", // 0
+ " class=\"startli\"", // 1
+ " class=\"startdd\"", // 2
+ " class=\"endli\"", // 3
+ " class=\"enddd\"", // 4
+ " class=\"starttd\"", // 5
+ " class=\"endtd\"" // 6
+ };
+ bool isFirst;
+ bool isLast;
+ t = getParagraphContext(p,isFirst,isLast);
+ //printf("startPara first=%d last=%d\n",isFirst,isLast);
+ if (isFirst && isLast) needsTag=FALSE;
+
+ //printf(" needsTag=%d\n",needsTag);
+ // write the paragraph tag (if needed)
+ if (needsTag) m_t << "<p" << contexts[t] << ">";
+}
+
+void HtmlDocVisitor::visitPost(DocPara *p)
+{
+ bool needsTag = FALSE;
+ if (p && p->parent())
+ {
+ switch (p->parent()->kind())
+ {
+ case DocNode::Kind_Section:
+ case DocNode::Kind_Internal:
+ case DocNode::Kind_HtmlListItem:
+ case DocNode::Kind_HtmlDescData:
+ case DocNode::Kind_HtmlCell:
+ case DocNode::Kind_SimpleListItem:
+ case DocNode::Kind_AutoListItem:
+ case DocNode::Kind_SimpleSect:
+ case DocNode::Kind_XRefItem:
+ case DocNode::Kind_Copy:
+ case DocNode::Kind_HtmlBlockQuote:
+ case DocNode::Kind_ParBlock:
+ needsTag = TRUE;
+ break;
+ case DocNode::Kind_Root:
+ needsTag = !((DocRoot*)p->parent())->singleLine();
+ break;
+ default:
+ needsTag = FALSE;
+ }
+ }
+
+ QCString context;
+ // if the last element of a paragraph is something that should be outside of
+ // the paragraph (<ul>,<dl>,<table>) then that will already have ended the
+ // paragraph and we don't need to do it here
+ int nodeIndex = p->children().count()-1;
+ if (p && nodeIndex>=0)
+ {
+ while (nodeIndex>=0 && p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace)
+ {
+ nodeIndex--;
+ }
+ if (nodeIndex>=0)
+ {
+ DocNode *n = p->children().at(nodeIndex);
+ if (mustBeOutsideParagraph(n))
+ {
+ needsTag = FALSE;
+ }
+ }
+ }
+
+ bool isFirst;
+ bool isLast;
+ getParagraphContext(p,isFirst,isLast);
+ //printf("endPara first=%d last=%d\n",isFirst,isLast);
+ if (isFirst && isLast) needsTag=FALSE;
+
+ //printf("DocPara::visitPost needsTag=%d\n",needsTag);
+
+ if (needsTag) m_t << "</p>\n";
+
+}
+
+void HtmlDocVisitor::visitPre(DocRoot *)
+{
+}
+
+void HtmlDocVisitor::visitPost(DocRoot *)
+{
+}
+
+void HtmlDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ forceEndParagraph(s);
+ m_t << "<dl class=\"section " << s->typeString() << "\"><dt>";
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << theTranslator->trSeeAlso(); break;
+ case DocSimpleSect::Return:
+ m_t << theTranslator->trReturns(); break;
+ case DocSimpleSect::Author:
+ m_t << theTranslator->trAuthor(TRUE,TRUE); break;
+ case DocSimpleSect::Authors:
+ m_t << theTranslator->trAuthor(TRUE,FALSE); break;
+ case DocSimpleSect::Version:
+ m_t << theTranslator->trVersion(); break;
+ case DocSimpleSect::Since:
+ m_t << theTranslator->trSince(); break;
+ case DocSimpleSect::Date:
+ m_t << theTranslator->trDate(); break;
+ case DocSimpleSect::Note:
+ m_t << theTranslator->trNote(); break;
+ case DocSimpleSect::Warning:
+ m_t << theTranslator->trWarning(); break;
+ case DocSimpleSect::Pre:
+ m_t << theTranslator->trPrecondition(); break;
+ case DocSimpleSect::Post:
+ m_t << theTranslator->trPostcondition(); break;
+ case DocSimpleSect::Copyright:
+ m_t << theTranslator->trCopyright(); break;
+ case DocSimpleSect::Invar:
+ m_t << theTranslator->trInvariant(); break;
+ case DocSimpleSect::Remark:
+ m_t << theTranslator->trRemarks(); break;
+ case DocSimpleSect::Attention:
+ m_t << theTranslator->trAttention(); break;
+ case DocSimpleSect::User: break;
+ case DocSimpleSect::Rcs: break;
+ case DocSimpleSect::Unknown: break;
+ }
+
+ // special case 1: user defined title
+ if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
+ {
+ m_t << "</dt><dd>";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ m_t << "</dd></dl>\n";
+ forceStartParagraph(s);
+}
+
+void HtmlDocVisitor::visitPre(DocTitle *)
+{
+}
+
+void HtmlDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "</dt><dd>";
+}
+
+void HtmlDocVisitor::visitPre(DocSimpleList *sl)
+{
+ if (m_hide) return;
+ forceEndParagraph(sl);
+ m_t << "<ul>";
+ if (!sl->isPreformatted()) m_t << "\n";
+
+}
+
+void HtmlDocVisitor::visitPost(DocSimpleList *sl)
+{
+ if (m_hide) return;
+ m_t << "</ul>";
+ if (!sl->isPreformatted()) m_t << "\n";
+ forceStartParagraph(sl);
+}
+
+void HtmlDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "<li>";
+}
+
+void HtmlDocVisitor::visitPost(DocSimpleListItem *li)
+{
+ if (m_hide) return;
+ m_t << "</li>";
+ if (!li->isPreformatted()) m_t << "\n";
+}
+
+void HtmlDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ forceEndParagraph(s);
+ m_t << "<h" << s->level() << ">";
+ m_t << "<a class=\"anchor\" id=\"" << s->anchor();
+ m_t << "\"></a>" << endl;
+ filter(convertCharEntitiesToUTF8(s->title().data()));
+ m_t << "</h" << s->level() << ">\n";
+}
+
+void HtmlDocVisitor::visitPost(DocSection *s)
+{
+ forceStartParagraph(s);
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlList *s)
+{
+ if (m_hide) return;
+ forceEndParagraph(s);
+ if (s->type()==DocHtmlList::Ordered)
+ {
+ m_t << "<ol" << htmlAttribsToString(s->attribs()) << ">\n";
+ }
+ else
+ {
+ m_t << "<ul" << htmlAttribsToString(s->attribs()) << ">\n";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ {
+ m_t << "</ol>";
+ }
+ else
+ {
+ m_t << "</ul>";
+ }
+ if (!s->isPreformatted()) m_t << "\n";
+ forceStartParagraph(s);
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlListItem *i)
+{
+ if (m_hide) return;
+ m_t << "<li" << htmlAttribsToString(i->attribs()) << ">";
+ if (!i->isPreformatted()) m_t << "\n";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "</li>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlDescList *dl)
+{
+ if (m_hide) return;
+ forceEndParagraph(dl);
+ m_t << "<dl" << htmlAttribsToString(dl->attribs()) << ">\n";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlDescList *dl)
+{
+ if (m_hide) return;
+ m_t << "</dl>\n";
+ forceStartParagraph(dl);
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlDescTitle *dt)
+{
+ if (m_hide) return;
+ m_t << "<dt" << htmlAttribsToString(dt->attribs()) << ">";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "</dt>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlDescData *dd)
+{
+ if (m_hide) return;
+ m_t << "<dd" << htmlAttribsToString(dd->attribs()) << ">";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ m_t << "</dd>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlTable *t)
+{
+ if (m_hide) return;
+
+ forceEndParagraph(t);
+
+ QString attrs = htmlAttribsToString(t->attribs());
+ if (attrs.isEmpty())
+ {
+ m_t << "<table class=\"doxtable\">\n";
+ }
+ else
+ {
+ m_t << "<table " << htmlAttribsToString(t->attribs()) << ">\n";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlTable *t)
+{
+ if (m_hide) return;
+ m_t << "</table>\n";
+ forceStartParagraph(t);
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlRow *tr)
+{
+ if (m_hide) return;
+ m_t << "<tr" << htmlAttribsToString(tr->attribs()) << ">\n";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlRow *)
+{
+ if (m_hide) return;
+ m_t << "</tr>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlCell *c)
+{
+ if (m_hide) return;
+ if (c->isHeading())
+ {
+ m_t << "<th" << htmlAttribsToString(c->attribs()) << ">";
+ }
+ else
+ {
+ m_t << "<td" << htmlAttribsToString(c->attribs()) << ">";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlCell *c)
+{
+ if (m_hide) return;
+ if (c->isHeading()) m_t << "</th>"; else m_t << "</td>";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlCaption *c)
+{
+ if (m_hide) return;
+ bool hasAlign = FALSE;
+ HtmlAttribListIterator li(c->attribs());
+ HtmlAttrib *att;
+ for (li.toFirst();(att=li.current());++li)
+ {
+ if (att->name=="align") hasAlign=TRUE;
+ }
+ m_t << "<caption" << htmlAttribsToString(c->attribs());
+ if (!hasAlign) m_t << " align=\"bottom\"";
+ m_t << ">";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "</caption>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ //forceEndParagraph(i);
+ //m_t << "<p><b>" << theTranslator->trForInternalUseOnly() << "</b></p>" << endl;
+}
+
+void HtmlDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ //forceStartParagraph(i);
+}
+
+void HtmlDocVisitor::visitPre(DocHRef *href)
+{
+ if (m_hide) return;
+ if (href->url().left(7)=="mailto:")
+ {
+ writeObfuscatedMailAddress(href->url().mid(7));
+ }
+ else
+ {
+ QCString url = correctURL(href->url(),href->relPath());
+ m_t << "<a href=\"" << convertToXML(url) << "\""
+ << htmlAttribsToString(href->attribs()) << ">";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "</a>";
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ forceEndParagraph(header);
+ m_t << "<h" << header->level()
+ << htmlAttribsToString(header->attribs()) << ">";
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ m_t << "</h" << header->level() << ">\n";
+ forceStartParagraph(header);
+}
+
+void HtmlDocVisitor::visitPre(DocImage *img)
+{
+ if (img->type()==DocImage::Html)
+ {
+ forceEndParagraph(img);
+ if (m_hide) return;
+ QString baseName=img->name();
+ int i;
+ if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ m_t << "<div class=\"image\">" << endl;
+ QCString url = img->url();
+ if (url.isEmpty())
+ {
+ m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\""
+ << baseName << "\"" << htmlAttribsToString(img->attribs())
+ << "/>" << endl;
+ }
+ else
+ {
+ m_t << "<img src=\"" << correctURL(url,img->relPath()) << "\" "
+ << htmlAttribsToString(img->attribs())
+ << "/>" << endl;
+ }
+ if (img->hasCaption())
+ {
+ m_t << "<div class=\"caption\">" << endl;
+ }
+ }
+ else // other format -> skip
+ {
+ pushEnabled();
+ m_hide=TRUE;
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocImage *img)
+{
+ if (img->type()==DocImage::Html)
+ {
+ if (m_hide) return;
+ if (img->hasCaption())
+ {
+ m_t << "</div>";
+ }
+ m_t << "</div>" << endl;
+ forceStartParagraph(img);
+ }
+ else // other format
+ {
+ popEnabled();
+ }
+}
+
+void HtmlDocVisitor::visitPre(DocDotFile *df)
+{
+ if (m_hide) return;
+ m_t << "<div class=\"dotgraph\">" << endl;
+ writeDotFile(df->file(),df->relPath(),df->context());
+ if (df->hasCaption())
+ {
+ m_t << "<div class=\"caption\">" << endl;
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocDotFile *df)
+{
+ if (m_hide) return;
+ if (df->hasCaption())
+ {
+ m_t << "</div>" << endl;
+ }
+ m_t << "</div>" << endl;
+}
+
+void HtmlDocVisitor::visitPre(DocMscFile *df)
+{
+ if (m_hide) return;
+ m_t << "<div class=\"mscgraph\">" << endl;
+ writeMscFile(df->file(),df->relPath(),df->context());
+ if (df->hasCaption())
+ {
+ m_t << "<div class=\"caption\">" << endl;
+ }
+}
+void HtmlDocVisitor::visitPost(DocMscFile *df)
+{
+ if (m_hide) return;
+ if (df->hasCaption())
+ {
+ m_t << "</div>" << endl;
+ }
+ m_t << "</div>" << endl;
+}
+
+void HtmlDocVisitor::visitPre(DocDiaFile *df)
+{
+ if (m_hide) return;
+ m_t << "<div class=\"diagraph\">" << endl;
+ writeDiaFile(df->file(),df->relPath(),df->context());
+ if (df->hasCaption())
+ {
+ m_t << "<div class=\"caption\">" << endl;
+ }
+}
+void HtmlDocVisitor::visitPost(DocDiaFile *df)
+{
+ if (m_hide) return;
+ if (df->hasCaption())
+ {
+ m_t << "</div>" << endl;
+ }
+ m_t << "</div>" << endl;
+}
+
+void HtmlDocVisitor::visitPre(DocLink *lnk)
+{
+ if (m_hide) return;
+ startLink(lnk->ref(),lnk->file(),lnk->relPath(),lnk->anchor());
+}
+
+void HtmlDocVisitor::visitPost(DocLink *)
+{
+ if (m_hide) return;
+ endLink();
+}
+
+void HtmlDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty())
+ {
+ // when ref->isSubPage()==TRUE we use ref->file() for HTML and
+ // ref->anchor() for LaTeX/RTF
+ startLink(ref->ref(),ref->file(),ref->relPath(),ref->isSubPage() ? QCString() : ref->anchor());
+ }
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void HtmlDocVisitor::visitPost(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty()) endLink();
+ //m_t << " ";
+}
+
+void HtmlDocVisitor::visitPre(DocSecRefItem *ref)
+{
+ if (m_hide) return;
+ QString refName=ref->file();
+ if (refName.right(Doxygen::htmlFileExtension.length())!=
+ QString(Doxygen::htmlFileExtension))
+ {
+ refName+=Doxygen::htmlFileExtension;
+ }
+ m_t << "<li><a href=\"" << refName << "#" << ref->anchor() << "\">";
+
+}
+
+void HtmlDocVisitor::visitPost(DocSecRefItem *)
+{
+ if (m_hide) return;
+ m_t << "</a></li>\n";
+}
+
+void HtmlDocVisitor::visitPre(DocSecRefList *s)
+{
+ if (m_hide) return;
+ forceEndParagraph(s);
+ m_t << "<div class=\"multicol\">" << endl;
+ m_t << "<ul>" << endl;
+}
+
+void HtmlDocVisitor::visitPost(DocSecRefList *s)
+{
+ if (m_hide) return;
+ m_t << "</ul>" << endl;
+ m_t << "</div>" << endl;
+ forceStartParagraph(s);
+}
+
+//void HtmlDocVisitor::visitPre(DocLanguage *l)
+//{
+// QString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// pushEnabled();
+// m_hide = TRUE;
+// }
+//}
+//
+//void HtmlDocVisitor::visitPost(DocLanguage *l)
+//{
+// QString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// popEnabled();
+// }
+//}
+
+void HtmlDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ forceEndParagraph(s);
+ QCString className;
+ QCString heading;
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ heading=theTranslator->trParameters();
+ className="params";
+ break;
+ case DocParamSect::RetVal:
+ heading=theTranslator->trReturnValues();
+ className="retval";
+ break;
+ case DocParamSect::Exception:
+ heading=theTranslator->trExceptions();
+ className="exception";
+ break;
+ case DocParamSect::TemplateParam:
+ heading=theTranslator->trTemplateParameters();
+ className="tparams";
+ break;
+ default:
+ ASSERT(0);
+ }
+ m_t << "<dl class=\"" << className << "\"><dt>";
+ m_t << heading;
+ m_t << "</dt><dd>" << endl;
+ m_t << " <table class=\"" << className << "\">" << endl;
+}
+
+void HtmlDocVisitor::visitPost(DocParamSect *s)
+{
+ if (m_hide) return;
+ m_t << " </table>" << endl;
+ m_t << " </dd>" << endl;
+ m_t << "</dl>" << endl;
+ forceStartParagraph(s);
+}
+
+void HtmlDocVisitor::visitPre(DocParamList *pl)
+{
+ //printf("DocParamList::visitPre\n");
+ if (m_hide) return;
+ m_t << " <tr>";
+ DocParamSect *sect = 0;
+ if (pl->parent()->kind()==DocNode::Kind_ParamSect)
+ {
+ sect=(DocParamSect*)pl->parent();
+ }
+ if (sect && sect->hasInOutSpecifier())
+ {
+ m_t << "<td class=\"paramdir\">";
+ if (pl->direction()!=DocParamSect::Unspecified)
+ {
+ m_t << "[";
+ if (pl->direction()==DocParamSect::In)
+ {
+ m_t << "in";
+ }
+ else if (pl->direction()==DocParamSect::Out)
+ {
+ m_t << "out";
+ }
+ else if (pl->direction()==DocParamSect::InOut)
+ {
+ m_t << "in,out";
+ }
+ m_t << "]";
+ }
+ m_t << "</td>";
+ }
+ if (sect && sect->hasTypeSpecifier())
+ {
+ m_t << "<td class=\"paramtype\">";
+ QListIterator<DocNode> li(pl->paramTypes());
+ DocNode *type;
+ bool first=TRUE;
+ for (li.toFirst();(type=li.current());++li)
+ {
+ if (!first) m_t << " | "; else first=FALSE;
+ if (type->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)type);
+ }
+ else if (type->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)type);
+ }
+ }
+ m_t << "</td>";
+ }
+ m_t << "<td class=\"paramname\">";
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ bool first=TRUE;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (!first) m_t << ","; else first=FALSE;
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ }
+ m_t << "</td><td>";
+}
+
+void HtmlDocVisitor::visitPost(DocParamList *)
+{
+ //printf("DocParamList::visitPost\n");
+ if (m_hide) return;
+ m_t << "</td></tr>" << endl;
+}
+
+void HtmlDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+
+ forceEndParagraph(x);
+ bool anonymousEnum = x->file()=="@";
+ if (!anonymousEnum)
+ {
+ m_t << "<dl class=\"" << x->key() << "\"><dt><b><a class=\"el\" href=\""
+ << x->relPath() << x->file() << Doxygen::htmlFileExtension
+ << "#" << x->anchor() << "\">";
+ }
+ else
+ {
+ m_t << "<dl class=\"" << x->key() << "\"><dt><b>";
+ }
+ filter(x->title());
+ m_t << ":";
+ if (!anonymousEnum) m_t << "</a>";
+ m_t << "</b></dt><dd>";
+}
+
+void HtmlDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "</dd></dl>" << endl;
+ forceStartParagraph(x);
+}
+
+void HtmlDocVisitor::visitPre(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ startLink(0,ref->file(),ref->relPath(),ref->anchor());
+}
+
+void HtmlDocVisitor::visitPost(DocInternalRef *)
+{
+ if (m_hide) return;
+ endLink();
+ m_t << " ";
+}
+
+void HtmlDocVisitor::visitPre(DocCopy *)
+{
+}
+
+void HtmlDocVisitor::visitPost(DocCopy *)
+{
+}
+
+void HtmlDocVisitor::visitPre(DocText *)
+{
+}
+
+void HtmlDocVisitor::visitPost(DocText *)
+{
+}
+
+void HtmlDocVisitor::visitPre(DocHtmlBlockQuote *b)
+{
+ if (m_hide) return;
+ forceEndParagraph(b);
+
+ QString attrs = htmlAttribsToString(b->attribs());
+ if (attrs.isEmpty())
+ {
+ m_t << "<blockquote class=\"doxtable\">\n";
+ }
+ else
+ {
+ m_t << "<blockquote " << htmlAttribsToString(b->attribs()) << ">\n";
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocHtmlBlockQuote *b)
+{
+ if (m_hide) return;
+ m_t << "</blockquote>" << endl;
+ forceStartParagraph(b);
+}
+
+void HtmlDocVisitor::visitPre(DocVhdlFlow *vf)
+{
+ if (m_hide) return;
+ if (VhdlDocGen::getFlowMember()) // use VHDL flow chart creator
+ {
+ forceEndParagraph(vf);
+ QCString fname=FlowChart::convertNameToFileName();
+ m_t << "<p>";
+ m_t << "flowchart: " ; // TODO: translate me
+ m_t << "<a href=\"";
+ m_t << fname.data();
+ m_t << ".svg\">";
+ m_t << VhdlDocGen::getFlowMember()->name().data();
+ m_t << "</a>";
+ if (vf->hasCaption())
+ {
+ m_t << "<br />";
+ }
+ }
+}
+
+void HtmlDocVisitor::visitPost(DocVhdlFlow *vf)
+{
+ if (m_hide) return;
+ if (VhdlDocGen::getFlowMember()) // use VHDL flow chart creator
+ {
+ m_t << "</p>";
+ forceStartParagraph(vf);
+ }
+}
+
+void HtmlDocVisitor::visitPre(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+void HtmlDocVisitor::visitPost(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+
+
+void HtmlDocVisitor::filter(const char *str)
+{
+ if (str==0) return;
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '<': m_t << "<"; break;
+ case '>': m_t << ">"; break;
+ case '&': m_t << "&"; break;
+ default: m_t << c;
+ }
+ }
+}
+
+/// Escape basic entities to produce a valid CDATA attribute value,
+/// assume that the outer quoting will be using the double quote "
+void HtmlDocVisitor::filterQuotedCdataAttr(const char* str)
+{
+ if (str==0) return;
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '&': m_t << "&"; break;
+ case '"': m_t << """; break;
+ // For SGML compliance, and given the SGML declaration for HTML syntax,
+ // it's enough to replace these two, provided that the declaration
+ // for the HTML version we generate (and as supported by the browser)
+ // specifies that all the other symbols used in rawVal are
+ // within the right character class (i.e., they're not
+ // some multinational weird characters not in the BASESET).
+ // We assume that 1) the browser will support whatever is remaining
+ // in the formula and 2) the TeX formulae are generally governed
+ // by even stricter character restrictions so it should be enough.
+ //
+ // On some incompliant browsers, additional translation of
+ // '>' and '<' into ">" and "<", respectively, might be needed;
+ // but I'm unaware of particular modern (last 4 years) versions
+ // with such problems, so let's not do it for performance.
+ // Also, some brousers will (wrongly) not process the entity references
+ // inside the attribute value and show the &...; form instead,
+ // so we won't create entites unless necessary to minimize clutter there.
+ // --vassilii
+ default: m_t << c;
+ }
+ }
+}
+
+void HtmlDocVisitor::startLink(const QCString &ref,const QCString &file,
+ const QCString &relPath,const QCString &anchor,
+ const QCString &tooltip)
+{
+ //printf("HtmlDocVisitor: file=%s anchor=%s\n",file.data(),anchor.data());
+ if (!ref.isEmpty()) // link to entity imported via tag file
+ {
+ m_t << "<a class=\"elRef\" ";
+ m_t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
+ }
+ else // local link
+ {
+ m_t << "<a class=\"el\" ";
+ }
+ m_t << "href=\"";
+ m_t << externalRef(relPath,ref,TRUE);
+ if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
+ if (!anchor.isEmpty()) m_t << "#" << anchor;
+ m_t << "\"";
+ if (!tooltip.isEmpty()) m_t << " title=\"" << substitute(tooltip,"\"",""") << "\"";
+ m_t << ">";
+}
+
+void HtmlDocVisitor::endLink()
+{
+ m_t << "</a>";
+}
+
+void HtmlDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void HtmlDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
+void HtmlDocVisitor::writeDotFile(const QCString &fn,const QCString &relPath,
+ const QCString &context)
+{
+ QCString baseName=fn;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1) // strip extension
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("dot_");
+ QCString outDir = Config_getString("HTML_OUTPUT");
+ writeDotGraphFromFile(fn,outDir,baseName,GOF_BITMAP);
+ writeDotImageMapFromFile(m_t,fn,outDir,relPath,baseName,context);
+}
+
+void HtmlDocVisitor::writeMscFile(const QCString &fileName,
+ const QCString &relPath,
+ const QCString &context)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1) // strip path
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1) // strip extension
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("msc_");
+ QCString outDir = Config_getString("HTML_OUTPUT");
+ QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ MscOutputFormat mscFormat = MSC_BITMAP;
+ if ("svg" == imgExt)
+ mscFormat = MSC_SVG;
+ writeMscGraphFromFile(fileName,outDir,baseName,mscFormat);
+ writeMscImageMapFromFile(m_t,fileName,outDir,relPath,baseName,context,mscFormat);
+}
+
+void HtmlDocVisitor::writeDiaFile(const QCString &fileName,
+ const QCString &relPath,
+ const QCString &)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1) // strip path
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1) // strip extension
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("dia_");
+ QCString outDir = Config_getString("HTML_OUTPUT");
+ writeDiaGraphFromFile(fileName,outDir,baseName,DIA_BITMAP);
+
+ m_t << "<img src=\"" << relPath << baseName << ".png" << "\" />" << endl;
+}
+
+void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName,
+ const QCString &relPath,
+ const QCString &)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1) // strip path
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.findRev('.'))!=-1) // strip extension
+ {
+ baseName=baseName.left(i);
+ }
+ static QCString outDir = Config_getString("HTML_OUTPUT");
+ static QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
+ if (imgExt=="svg")
+ {
+ generatePlantUMLOutput(fileName,outDir,PUML_SVG);
+ //m_t << "<iframe scrolling=\"no\" frameborder=\"0\" src=\"" << relPath << baseName << ".svg" << "\" />" << endl;
+ //m_t << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
+ //m_t << "</iframe>" << endl;
+ m_t << "<object type=\"image/svg+xml\" data=\"" << relPath << baseName << ".svg\"></object>" << endl;
+ }
+ else
+ {
+ generatePlantUMLOutput(fileName,outDir,PUML_BITMAP);
+ m_t << "<img src=\"" << relPath << baseName << ".png" << "\" />" << endl;
+ }
+}
+
+/** Used for items found inside a paragraph, which due to XHTML restrictions
+ * have to be outside of the paragraph. This method will forcefully end
+ * the current paragraph and forceStartParagraph() will restart it.
+ */
+void HtmlDocVisitor::forceEndParagraph(DocNode *n)
+{
+ //printf("forceEndParagraph(%p) %d\n",n,n->kind());
+ if (n->parent() && n->parent()->kind()==DocNode::Kind_Para)
+ {
+ DocPara *para = (DocPara*)n->parent();
+ int nodeIndex = para->children().findRef(n);
+ nodeIndex--;
+ if (nodeIndex<0) return; // first node
+ while (nodeIndex>=0 &&
+ para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace
+ )
+ {
+ nodeIndex--;
+ }
+ if (nodeIndex>=0)
+ {
+ DocNode *n = para->children().at(nodeIndex);
+ //printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n));
+ if (mustBeOutsideParagraph(n)) return;
+ }
+
+ bool isFirst;
+ bool isLast;
+ getParagraphContext(para,isFirst,isLast);
+ //printf("forceEnd first=%d last=%d\n",isFirst,isLast);
+ if (isFirst && isLast) return;
+
+ m_t << "</p>";
+ }
+}
+
+/** Used for items found inside a paragraph, which due to XHTML restrictions
+ * have to be outside of the paragraph. This method will forcefully start
+ * the paragraph, that was previously ended by forceEndParagraph().
+ */
+void HtmlDocVisitor::forceStartParagraph(DocNode *n)
+{
+ //printf("forceStartParagraph(%p) %d\n",n,n->kind());
+ if (n->parent() && n->parent()->kind()==DocNode::Kind_Para) // if we are inside a paragraph
+ {
+ DocPara *para = (DocPara*)n->parent();
+ int nodeIndex = para->children().findRef(n);
+ int numNodes = para->children().count();
+ nodeIndex++;
+ if (nodeIndex==numNodes) return; // last node
+ while (nodeIndex<numNodes &&
+ para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace
+ )
+ {
+ nodeIndex++;
+ }
+ if (nodeIndex<numNodes)
+ {
+ DocNode *n = para->children().at(nodeIndex);
+ if (mustBeOutsideParagraph(n)) return;
+ }
+ else
+ {
+ return; // only whitespace at the end!
+ }
+
+ bool isFirst;
+ bool isLast;
+ getParagraphContext(para,isFirst,isLast);
+ //printf("forceStart first=%d last=%d\n",isFirst,isLast);
+ if (isFirst && isLast) return;
+
+ m_t << "<p>";
+ }
+}
+
diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h
new file mode 100644
index 0000000..00ae09e
--- /dev/null
+++ b/src/htmldocvisitor.h
@@ -0,0 +1,177 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _HTMLDOCVISITOR_H
+#define _HTMLDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+
+class Definition;
+class MemberDef;
+class DocNode;
+class FTextStream;
+class CodeOutputInterface;
+
+/*! @brief Concrete visitor implementation for HTML output. */
+class HtmlDocVisitor : public DocVisitor
+{
+ public:
+ HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci,Definition *ctx);
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *) ;
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *);
+ void visitPost(DocHtmlList *) ;
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *);
+ void visitPost(DocHtmlTable *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *);
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void writeObfuscatedMailAddress(const QCString &url);
+ void filter(const char *str);
+ void filterQuotedCdataAttr(const char* str);
+ void startLink(const QCString &ref,const QCString &file,
+ const QCString &relPath,const QCString &anchor,
+ const QCString &tooltip = "");
+ void endLink();
+ void writeDotFile(const QCString &fileName,const QCString &relPath,const QCString &context);
+ void writeMscFile(const QCString &fileName,const QCString &relPath,const QCString &context);
+ void writeDiaFile(const QCString &fileName,const QCString &relPath,const QCString &context);
+ void writePlantUMLFile(const QCString &fileName,const QCString &relPath,const QCString &context);
+
+ void pushEnabled();
+ void popEnabled();
+
+ void forceEndParagraph(DocNode *n);
+ void forceStartParagraph(DocNode *n);
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_hide;
+ QStack<bool> m_enabled;
+ Definition *m_ctx;
+ QCString m_langExt;
+};
+
+#endif
diff --git a/src/htmlentity.cpp b/src/htmlentity.cpp
new file mode 100644
index 0000000..216b65c
--- /dev/null
+++ b/src/htmlentity.cpp
@@ -0,0 +1,500 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "htmlentity.h"
+#include "message.h"
+#include "ftextstream.h"
+
+//! Number of doxygen commands mapped as if it were HTML entities
+static const int g_numberHtmlMappedCmds = 11;
+
+//! @brief Structure defining all HTML4 entities, doxygen extensions and doxygen commands representing special symbols.
+//! @details In case an entity does not exist a NULL is given for the entity. The first column contains the symbolic code
+//! for the entity, see also doxparser.h The second column contains the name of the enitity (without the starting \& and
+//! ending ;)
+static struct htmlEntityInfo
+{
+ DocSymbol::SymType symb;
+ const char *item;
+ const char *UTF8;
+ const char *html;
+ const char *xml;
+ const char *docbook;
+ const char *latex;
+ const char *man;
+ const char *rtf;
+ DocSymbol::PerlSymb perl;
+} g_htmlEntities[] =
+{
+#undef SYM
+// helper macro to force consistent entries for the symbol and item columns
+#define SYM(s) DocSymbol::Sym_##s,"&"#s";"
+ // HTML4 entities
+ // symb+item UTF-8 html xml docbook latex man rtf perl
+ { SYM(nbsp), "\xc2\xa0", " ", "<nonbreakablespace/>", " ", "~", " ", "\\~", { " ", DocSymbol::Perl_char }},
+ { SYM(iexcl), "\xc2\xa1", "¡", "<iexcl/>", "¡", "!`", NULL, "\\'A1", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(cent), "\xc2\xa2", "¢", "<cent/>", "¢", "\\textcent{}", NULL, "\\'A2", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(pound), "\xc2\xa3", "£", "<pound/>", "£", "{$\\pounds$}", NULL, "\\'A3", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(curren), "\xc2\xa4", "¤", "<curren/>", "¤", "\\textcurrency{}", NULL, "\\'A4", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(yen), "\xc2\xa5", "¥", "<yen/>", "¥", "{$\\yen$}", NULL, "\\'A5", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(brvbar), "\xc2\xa6", "¦", "<brvbar/>", "¦", "\\textbrokenbar{}", NULL, "\\'A6", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(sect), "\xc2\xa7", "§", "<sect/>", "<simplesect/>", "{$\\S$}", NULL, "\\'A7", { "sect", DocSymbol::Perl_symbol }},
+ { SYM(uml), "\xc2\xa8", "¨", "<umlaut/>", "¨", "\\textasciidieresis{}", " \\*(4", "\\'A8", { " ", DocSymbol::Perl_umlaut }},
+ { SYM(copy), "\xc2\xa9", "©", "<copy/>", "©", "\\copyright{}", "(C)", "\\'A9", { "copyright", DocSymbol::Perl_symbol }},
+ { SYM(ordf), "\xc2\xaa", "ª", "<ordf/>", "ª", "\\textordfeminine{}", NULL, "\\'AA", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(laquo), "\xc2\xab", "«", "<laquo/>", "«", "\\guillemotleft{}", NULL, "\\'AB", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(not), "\xc2\xac", "¬", "<not/>", "¬", "\\textlnot", NULL, "\\'AC", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(shy), "\xc2\xad", "", "<shy/>", "", "{$\\-$}", NULL, "\\-", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(reg), "\xc2\xae", "®", "<registered/>", "®", "\\textregistered{}", "(R)", "\\'AE", { "registered", DocSymbol::Perl_symbol }},
+ { SYM(macr), "\xc2\xaf", "¯", "<macr/>", "¯", "\\={}", NULL, "\\'AF", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(deg), "\xc2\xb0", "°", "<deg/>", "°", "\\textdegree", NULL, "\\'B0", { "deg", DocSymbol::Perl_symbol }},
+ { SYM(plusmn), "\xc2\xb1", "±", "<plusmn/>", "±", "{$\\pm$}", NULL, "\\'B1", { "+/-", DocSymbol::Perl_string }},
+ { SYM(sup2), "\xc2\xb2", "²", "<sup2/>", "²", "\\texttwosuperior{}", NULL, "\\'B2", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(sup3), "\xc2\xb3", "³", "<sup3/>", "³", "\\textthreesuperior{}", NULL, "\\'B3", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(acute), "\xc2\xb4", "´", "<acute/>", "´", "\\'{}", NULL, "\\'B4", { " ", DocSymbol::Perl_acute }},
+ { SYM(micro), "\xc2\xb5", "µ", "<micro/>", "µ", "{$\\mu$}", NULL, "\\'B5", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(para), "\xc2\xb6", "¶", "<para/>", "¶", "{$\\P$}", NULL, "\\'B6", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(middot), "\xc2\xb7", "·", "<middot/>", "·", "\\textperiodcentered{}", NULL, "\\'B7", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(cedil), "\xc2\xb8", "¸", "<cedil/>", "¸", "\\c{}", " \\*,", "\\'B8", { " ", DocSymbol::Perl_cedilla }},
+ { SYM(sup1), "\xc2\xb9", "¹", "<sup1/>", "¹", "\\textonesuperior{}", NULL, "\\'B9", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(ordm), "\xc2\xba", "º", "<ordm/>", "º", "\\textordmasculine{}", NULL, "\\'BA", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(raquo), "\xc2\xbb", "»", "<raquo/>", "»", "\\guillemotright{}", NULL, "\\'BB", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(frac14), "\xc2\xbc", "¼", "<frac14/>", "¼", "{$\\frac14$}", "1/4", "\\'BC", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(frac12), "\xc2\xbd", "½", "<frac12/>", "½", "{$\\frac12$}", "1/2", "\\'BD", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(frac34), "\xc2\xbe", "¾", "<frac34/>", "¾", "{$\\frac34$}", "3/4", "\\'BE", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(iquest), "\xc2\xbf", "¿", "<iquest/>", "¿", "?`", NULL, "\\'BF", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Agrave), "\xc3\x80", "À", "<Agrave/>", "À", "\\`{A}", "A\\*:", "\\'C0", { "A", DocSymbol::Perl_grave }},
+ { SYM(Aacute), "\xc3\x81", "Á", "<Aacute/>", "Á", "\\'{A}", "A\\*(`", "\\'C1", { "A", DocSymbol::Perl_acute }},
+ { SYM(Acirc), "\xc3\x82", "Â", "<Acirc/>", "Â", "\\^{A}", "A\\*^", "\\'C2", { "A", DocSymbol::Perl_circ }},
+ { SYM(Atilde), "\xc3\x83", "Ã", "<Atilde/>", "Ã", "\\~{A}", "A\\*~", "\\'C3", { "A", DocSymbol::Perl_tilde }},
+ { SYM(Auml), "\xc3\x84", "Ä", "<Aumlaut/>", "Ä", "\\\"{A}", "A\\*(4", "\\'C4", { "A", DocSymbol::Perl_umlaut }},
+ { SYM(Aring), "\xc3\x85", "Å", "<Aring/>", "Å", "\\AA", "A\\*o", "\\'C5", { "A", DocSymbol::Perl_ring }},
+ { SYM(AElig), "\xc3\x86", "Æ", "<AElig/>", "Æ", "{\\AE}", NULL, "\\'C6", { "AElig", DocSymbol::Perl_symbol }},
+ { SYM(Ccedil), "\xc3\x87", "Ç", "<Ccedil/>", "Ç", "\\c{C}", "C\\*,", "\\'C7", { "C", DocSymbol::Perl_cedilla }},
+ { SYM(Egrave), "\xc3\x88", "È", "<Egrave/>", "È", "\\`{E}", "E\\*:", "\\'C8", { "E", DocSymbol::Perl_grave }},
+ { SYM(Eacute), "\xc3\x89", "É", "<Eacute/>", "É", "\\'{E}", "E\\*(`", "\\'C9", { "E", DocSymbol::Perl_acute }},
+ { SYM(Ecirc), "\xc3\x8a", "Ê", "<Ecirc/>", "Ê", "\\^{E}", "E\\*^", "\\'CA", { "E", DocSymbol::Perl_circ }},
+ { SYM(Euml), "\xc3\x8b", "Ë", "<Eumlaut/>", "Ë", "\\\"{E}", "E\\*(4", "\\'CB", { "E", DocSymbol::Perl_umlaut }},
+ { SYM(Igrave), "\xc3\x8c", "Ì", "<Igrave/>", "Ì", "\\`{I}", "I\\*:", "\\'CC", { "I", DocSymbol::Perl_grave }},
+ { SYM(Iacute), "\xc3\x8d", "Í", "<Iacute/>", "Í", "\\'{I}", "I\\*(`", "\\'CD", { "I", DocSymbol::Perl_acute }},
+ { SYM(Icirc), "\xc3\x8e", "Î", "<Icirc/>", "Î", "\\^{I}", "I\\*^", "\\'CE", { "I", DocSymbol::Perl_circ }},
+ { SYM(Iuml), "\xc3\x8f", "Ï", "<Iumlaut/>", "Ï", "\\\"{I}", "I\\*(4", "\\'CF", { "I", DocSymbol::Perl_umlaut }},
+ { SYM(ETH), "\xc3\x90", "Ð", "<ETH/>", "Ð", "\\DH", NULL, "\\'D0", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Ntilde), "\xc3\x91", "Ñ", "<Ntilde/>", "Ñ", "\\~{N}", "N\\*~", "\\'D1", { "N", DocSymbol::Perl_tilde }},
+ { SYM(Ograve), "\xc3\x92", "Ò", "<Ograve/>", "Ò", "\\`{O}", "O\\*:", "\\'D2", { "O", DocSymbol::Perl_grave }},
+ { SYM(Oacute), "\xc3\x93", "Ó", "<Oacute/>", "Ó", "\\'{O}", "O\\*(`", "\\'D3", { "O", DocSymbol::Perl_acute }},
+ { SYM(Ocirc), "\xc3\x94", "Ô", "<Ocirc/>", "Ô", "\\^{O}", "O\\*^", "\\'D4", { "O", DocSymbol::Perl_circ }},
+ { SYM(Otilde), "\xc3\x95", "Õ", "<Otilde/>", "Õ", "\\~{O}", "O\\*~", "\\'D5", { "O", DocSymbol::Perl_tilde }},
+ { SYM(Ouml), "\xc3\x96", "Ö", "<Oumlaut/>", "Ö", "\\\"{O}", "O\\*(4", "\\'D6", { "O", DocSymbol::Perl_umlaut }},
+ { SYM(times), "\xc3\x97", "×", "<times/>", "×", "{$\\times$}", NULL, "\\'D7", { "*", DocSymbol::Perl_char }},
+ { SYM(Oslash), "\xc3\x98", "Ø", "<Oslash/>", "Ø", "{\\O}", "O\x08/", "\\'D8", { "O", DocSymbol::Perl_slash }},
+ { SYM(Ugrave), "\xc3\x99", "Ù", "<Ugrave/>", "Ù", "\\`{U}", "U\\*:", "\\'D9", { "U", DocSymbol::Perl_grave }},
+ { SYM(Uacute), "\xc3\x9a", "Ú", "<Uacute/>", "Ú", "\\'{U}", "U\\*(`", "\\'DA", { "U", DocSymbol::Perl_acute }},
+ { SYM(Ucirc), "\xc3\x9b", "Û", "<Ucirc/>", "Û", "\\^{U}", "U\\*^", "\\'DB", { "U", DocSymbol::Perl_circ }},
+ { SYM(Uuml), "\xc3\x9c", "Ü", "<Uumlaut/>", "Ü", "\\\"{U}", "U\\*(4", "\\'DC", { "U", DocSymbol::Perl_umlaut }},
+ { SYM(Yacute), "\xc3\x9d", "Ý", "<Yacute/>", "Ý", "\\'{Y}", "Y\\*(`", "\\'DD", { "Y", DocSymbol::Perl_acute }},
+ { SYM(THORN), "\xc3\x9e", "Þ", "<THORN/>", "Þ", "\\TH", NULL, "\\'DE", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(szlig), "\xc3\x9f", "ß", "<szlig/>", "ß", "{\\ss}", "s\\*:", "\\'DF", { "szlig", DocSymbol::Perl_symbol }},
+ { SYM(agrave), "\xc3\xa0", "à", "<agrave/>", "à", "\\`{a}", "a\\*:", "\\'E0", { "a", DocSymbol::Perl_grave }},
+ { SYM(aacute), "\xc3\xa1", "á", "<aacute/>", "á", "\\'{a}", "a\\*(`", "\\'E1", { "a", DocSymbol::Perl_acute }},
+ { SYM(acirc), "\xc3\xa2", "â", "<acirc/>", "â", "\\^{a}", "a\\*^", "\\'E2", { "a", DocSymbol::Perl_circ }},
+ { SYM(atilde), "\xc3\xa3", "ã", "<atilde/>", "ã", "\\~{a}", "a\\*~", "\\'E3", { "a", DocSymbol::Perl_tilde }},
+ { SYM(auml), "\xc3\xa4", "ä", "<aumlaut/>", "ä", "\\\"{a}", "a\\*(4", "\\'E4", { "a", DocSymbol::Perl_umlaut }},
+ { SYM(aring), "\xc3\xa5", "å", "<aring/>", "å", "\\aa", "a\\*o", "\\'E5", { "a", DocSymbol::Perl_ring }},
+ { SYM(aelig), "\xc3\xa6", "æ", "<aelig/>", "æ", "{\\ae}", NULL, "\\'E6", { "aelig", DocSymbol::Perl_symbol }},
+ { SYM(ccedil), "\xc3\xa7", "ç", "<ccedil/>", "ç", "\\c{c}", "c\\*,", "\\'E7", { "c", DocSymbol::Perl_cedilla }},
+ { SYM(egrave), "\xc3\xa8", "è", "<egrave/>", "è", "\\`{e}", "e\\*:", "\\'E8", { "e", DocSymbol::Perl_grave }},
+ { SYM(eacute), "\xc3\xa9", "é", "<eacute/>", "é", "\\'{e}", "e\\*(`", "\\'E9", { "e", DocSymbol::Perl_acute }},
+ { SYM(ecirc), "\xc3\xaa", "ê", "<ecirc/>", "ê", "\\^{e}", "e\\*^", "\\'EA", { "e", DocSymbol::Perl_circ }},
+ { SYM(euml), "\xc3\xab", "ë", "<eumlaut/>", "ë", "\\\"{e}", "e\\*(4", "\\'EB", { "e", DocSymbol::Perl_umlaut }},
+ { SYM(igrave), "\xc3\xac", "ì", "<igrave/>", "ì", "\\`{\\i}", "i\\*:", "\\'EC", { "i", DocSymbol::Perl_grave }},
+ { SYM(iacute), "\xc3\xad", "í", "<iacute/>", "í", "\\'{\\i}", "i\\*(`", "\\'ED", { "i", DocSymbol::Perl_acute }},
+ { SYM(icirc), "\xc3\xae", "î", "<icirc/>", "î", "\\^{\\i}", "i\\*^", "\\'EE", { "i", DocSymbol::Perl_circ }},
+ { SYM(iuml), "\xc3\xaf", "ï", "<iumlaut/>", "ï", "\\\"{\\i}", "i\\*(4", "\\'EF", { "i", DocSymbol::Perl_umlaut }},
+ { SYM(eth), "\xc3\xb0", "ð", "<eth/>", "ð", "\\dh", NULL, "\\'F0", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(ntilde), "\xc3\xb1", "ñ", "<ntilde/>", "ñ", "\\~{n}", "n\\*~", "\\'F1", { "n", DocSymbol::Perl_tilde }},
+ { SYM(ograve), "\xc3\xb2", "ò", "<ograve/>", "ò", "\\`{o}", "o\\*:", "\\'F2", { "o", DocSymbol::Perl_grave }},
+ { SYM(oacute), "\xc3\xb3", "ó", "<oacute/>", "ó", "\\'{o}", "o\\*(`", "\\'F3", { "o", DocSymbol::Perl_acute }},
+ { SYM(ocirc), "\xc3\xb4", "ô", "<ocirc/>", "ô", "\\^{o}", "o\\*^", "\\'F4", { "o", DocSymbol::Perl_circ }},
+ { SYM(otilde), "\xc3\xb5", "õ", "<otilde/>", "õ", "\\~{o}", "o\\*~", "\\'F5", { "o", DocSymbol::Perl_tilde }},
+ { SYM(ouml), "\xc3\xb6", "ö", "<oumlaut/>", "ö", "\\\"{o}", "o\\*(4", "\\'F6", { "o", DocSymbol::Perl_umlaut }},
+ { SYM(divide), "\xc3\xb7", "÷", "<divide/>", "÷", "{$\\div$}", NULL, "\\'F7", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(oslash), "\xc3\xb8", "ø", "<oslash/>", "ø", "{\\o}", "o\x08/", "\\'F8", { "o", DocSymbol::Perl_slash }},
+ { SYM(ugrave), "\xc3\xb9", "ù", "<ugrave/>", "ù", "\\`{u}", "u\\*:", "\\'F9", { "u", DocSymbol::Perl_grave }},
+ { SYM(uacute), "\xc3\xba", "ú", "<uacute/>", "ú", "\\'{u}", "u\\*(`", "\\'FA", { "u", DocSymbol::Perl_acute }},
+ { SYM(ucirc), "\xc3\xbb", "û", "<ucirc/>", "û", "\\^{u}", "u\\*^", "\\'FB", { "u", DocSymbol::Perl_circ }},
+ { SYM(uuml), "\xc3\xbc", "ü", "<uumlaut/>", "ü", "\\\"{u}", "u\\*(4", "\\'FC", { "u", DocSymbol::Perl_umlaut }},
+ { SYM(yacute), "\xc3\xbd", "ý", "<yacute/>", "ý", "\\'{y}", "y\\*(`", "\\'FD", { "y", DocSymbol::Perl_acute }},
+ { SYM(thorn), "\xc3\xbe", "þ", "<thorn/>", "þ", "\\th", NULL, "\\'FE", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(yuml), "\xc3\xbf", "ÿ", "<yumlaut/>", "ÿ", "\\\"{y}", "y\\*(4", "\\'FF", { "y", DocSymbol::Perl_umlaut }},
+ { SYM(fnof), "\xc6\x92", "ƒ", "<fnof/>", "ƒ", "\\textflorin", NULL, "\\'83", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Alpha), "\xce\x91", "Α", "<Alpha/>", "Α", "A", NULL, "\\u0913?", { "A", DocSymbol::Perl_char }},
+ { SYM(Beta), "\xce\x92", "Β", "<Beta/>", "Β", "B", NULL, "\\u0914?", { "B", DocSymbol::Perl_char }},
+ { SYM(Gamma), "\xce\x93", "Γ", "<Gamma/>", "Γ", "{$\\Gamma$}", NULL, "\\u0915?", { "Gamma", DocSymbol::Perl_symbol }},
+ { SYM(Delta), "\xce\x94", "Δ", "<Delta/>", "Δ", "{$\\Delta$}", NULL, "\\u0916?", { "Delta", DocSymbol::Perl_symbol }},
+ { SYM(Epsilon), "\xce\x95", "Ε", "<Epsilon/>", "Ε", "E", NULL, "\\u0917?", { "E", DocSymbol::Perl_char }},
+ { SYM(Zeta), "\xce\x96", "Ζ", "<Zeta/>", "Ζ", "Z", NULL, "\\u0918?", { "Z", DocSymbol::Perl_char }},
+ { SYM(Eta), "\xce\x97", "Η", "<Eta/>", "Η", "H", NULL, "\\u0919?", { "H", DocSymbol::Perl_char }},
+ { SYM(Theta), "\xce\x98", "Θ", "<Theta/>", "Θ", "{$\\Theta$}", NULL, "\\u0920?", { "Theta", DocSymbol::Perl_symbol }},
+ { SYM(Iota), "\xce\x99", "Ι", "<Iota/>", "Ι", "I", NULL, "\\u0921?", { "I", DocSymbol::Perl_char }},
+ { SYM(Kappa), "\xce\x9a", "Κ", "<Kappa/>", "Κ", "K", NULL, "\\u0922?", { "K", DocSymbol::Perl_char }},
+ { SYM(Lambda), "\xce\x9b", "Λ", "<Lambda/>", "Λ", "{$\\Lambda$}", NULL, "\\u0923?", { "Lambda", DocSymbol::Perl_symbol }},
+ { SYM(Mu), "\xce\x9c", "Μ", "<Mu/>", "Μ", "M", NULL, "\\u0924?", { "M", DocSymbol::Perl_char }},
+ { SYM(Nu), "\xce\x9d", "Ν", "<Nu/>", "Ν", "N", NULL, "\\u0925?", { "N", DocSymbol::Perl_char }},
+ { SYM(Xi), "\xce\x9e", "Ξ", "<Xi/>", "Ξ", "{$\\Xi$}", NULL, "\\u0926?", { "Xi", DocSymbol::Perl_symbol }},
+ { SYM(Omicron), "\xce\x9f", "Ο", "<Omicron/>", "Ο", "O", NULL, "\\u0927?", { "O", DocSymbol::Perl_char }},
+ { SYM(Pi), "\xce\xa0", "Π", "<Pi/>", "Π", "{$\\Pi$}", NULL, "\\u0928?", { "Pi", DocSymbol::Perl_symbol }},
+ { SYM(Rho), "\xce\xa1", "Ρ", "<Rho/>", "Ρ", "P", NULL, "\\u0929?", { "P", DocSymbol::Perl_char }},
+ { SYM(Sigma), "\xce\xa3", "Σ", "<Sigma/>", "Σ", "{$\\Sigma$}", NULL, "\\u0931?", { "Sigma", DocSymbol::Perl_symbol }},
+ { SYM(Tau), "\xce\xa4", "Τ", "<Tau/>", "Τ", "T", NULL, "\\u0932?", { "T", DocSymbol::Perl_char }},
+ { SYM(Upsilon), "\xce\xa5", "Υ", "<Upsilon/>", "Υ", "{$\\Upsilon$}", NULL, "\\u0933?", { "Upsilon", DocSymbol::Perl_symbol }},
+ { SYM(Phi), "\xce\xa6", "Φ", "<Phi/>", "Φ", "{$\\Phi$}", NULL, "\\u0934?", { "Phi", DocSymbol::Perl_symbol }},
+ { SYM(Chi), "\xce\xa7", "Χ", "<Chi/>", "Χ", "X", NULL, "\\u0935?", { "X", DocSymbol::Perl_char }},
+ { SYM(Psi), "\xce\xa8", "Ψ", "<Psi/>", "Ψ", "{$\\Psi$}", NULL, "\\u0936?", { "Psi", DocSymbol::Perl_symbol }},
+ { SYM(Omega), "\xce\xa9", "Ω", "<Omega/>", "Ω", "{$\\Omega$}", NULL, "\\u0937?", { "Omega", DocSymbol::Perl_symbol }},
+ { SYM(alpha), "\xce\xb1", "α", "<alpha/>", "α", "{$\\alpha$}", NULL, "\\u0945?", { "alpha", DocSymbol::Perl_symbol }},
+ { SYM(beta), "\xce\xb2", "β", "<beta/>", "β", "{$\\beta$}", NULL, "\\u0946?", { "beta", DocSymbol::Perl_symbol }},
+ { SYM(gamma), "\xce\xb3", "γ", "<gamma/>", "γ", "{$\\gamma$}", NULL, "\\u0947?", { "gamma", DocSymbol::Perl_symbol }},
+ { SYM(delta), "\xce\xb4", "δ", "<delta/>", "δ", "{$\\delta$}", NULL, "\\u0948?", { "delta", DocSymbol::Perl_symbol }},
+ { SYM(epsilon), "\xce\xb5", "ε", "<epsilon/>", "ε", "{$\\varepsilon$}", NULL, "\\u0949?", { "epsilon", DocSymbol::Perl_symbol }},
+ { SYM(zeta), "\xce\xb6", "ζ", "<zeta/>", "ζ", "{$\\zeta$}", NULL, "\\u0950?", { "zeta", DocSymbol::Perl_symbol }},
+ { SYM(eta), "\xce\xb7", "η", "<eta/>", "η", "{$\\eta$}", NULL, "\\u0951?", { "eta", DocSymbol::Perl_symbol }},
+ { SYM(theta), "\xce\xb8", "θ", "<theta/>", "θ", "{$\\theta$}", NULL, "\\u0952?", { "theta", DocSymbol::Perl_symbol }},
+ { SYM(iota), "\xce\xb9", "ι", "<iota/>", "ι", "{$\\iota$}", NULL, "\\u0953?", { "iota", DocSymbol::Perl_symbol }},
+ { SYM(kappa), "\xce\xba", "κ", "<kappa/>", "κ", "{$\\kappa$}", NULL, "\\u0954?", { "kappa", DocSymbol::Perl_symbol }},
+ { SYM(lambda), "\xce\xbb", "λ", "<lambda/>", "λ", "{$\\lambda$}", NULL, "\\u0955?", { "lambda", DocSymbol::Perl_symbol }},
+ { SYM(mu), "\xce\xbc", "μ", "<mu/>", "μ", "{$\\mu$}", NULL, "\\u0956?", { "mu", DocSymbol::Perl_symbol }},
+ { SYM(nu), "\xce\xbd", "ν", "<nu/>", "ν", "{$\\nu$}", NULL, "\\u0957?", { "nu", DocSymbol::Perl_symbol }},
+ { SYM(xi), "\xce\xbe", "ξ", "<xi/>", "ξ", "{$\\xi$}", NULL, "\\u0958?", { "xi", DocSymbol::Perl_symbol }},
+ { SYM(omicron), "\xce\xbf", "ο", "<omicron/>", "ο", "{$\\omicron$}", NULL, "\\u0959?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(pi), "\xcf\x80", "π", "<pi/>", "π", "{$\\pi$}", NULL, "\\u0960?", { "pi", DocSymbol::Perl_symbol }},
+ { SYM(rho), "\xcf\x81", "ρ", "<rho/>", "ρ", "{$\\rho$}", NULL, "\\u0961?", { "rho", DocSymbol::Perl_symbol }},
+ { SYM(sigmaf), "\xcf\x82", "ς", "<sigmaf/>", "ς", "{$\\varsigma$}", NULL, "\\u0962?", { "sigma", DocSymbol::Perl_symbol }},
+ { SYM(sigma), "\xcf\x83", "σ", "<sigma/>", "σ", "{$\\sigma$}", NULL, "\\u0963?", { "sigma", DocSymbol::Perl_symbol }},
+ { SYM(tau), "\xcf\x84", "τ", "<tau/>", "τ", "{$\\tau$}", NULL, "\\u0964?", { "tau", DocSymbol::Perl_symbol }},
+ { SYM(upsilon), "\xcf\x85", "υ", "<upsilon/>", "υ", "{$\\upsilon$}", NULL, "\\u0965?", { "upsilon", DocSymbol::Perl_symbol }},
+ { SYM(phi), "\xcf\x86", "φ", "<phi/>", "φ", "{$\\varphi$}", NULL, "\\u0966?", { "phi", DocSymbol::Perl_symbol }},
+ { SYM(chi), "\xcf\x87", "χ", "<chi/>", "χ", "{$\\chi$}", NULL, "\\u0967?", { "chi", DocSymbol::Perl_symbol }},
+ { SYM(psi), "\xcf\x88", "ψ", "<psi/>", "ψ", "{$\\psi$}", NULL, "\\u0968?", { "psi", DocSymbol::Perl_symbol }},
+ { SYM(omega), "\xcf\x89", "ω", "<omega/>", "ω", "{$\\omega$}", NULL, "\\u0969?", { "omega", DocSymbol::Perl_symbol }},
+ { SYM(thetasym), "\xcf\x91", "ϑ", "<thetasym/>", "ϑ", "{$\\vartheta$}", NULL, "\\u977?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(upsih), "\xcf\x92", "ϒ", "<upsih/>", "ϒ", "{$\\Upsilon$}", NULL, "\\u978?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(piv), "\xcf\x96", "ϖ", "<piv/>", "ϖ", "{$\\varpi$}", NULL, "\\u982?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(bull), "\xe2\x80\xa2", "•", "<bull/>", "•", "\\textbullet{}", NULL, "\\'95", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(hellip), "\xe2\x80\xa6", "…", "<hellip/>", "…", "{$\\cdots$}", NULL, "\\'85", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(prime), "\xe2\x80\xb2", "′", "<prime/>", "′", "'", NULL, "\\u8242?", { "\\\'", DocSymbol::Perl_string }},
+ { SYM(Prime), "\xe2\x80\xb3", "″", "<Prime/>", "″", "''", NULL, "\\u8243?", { "\"", DocSymbol::Perl_char }},
+ { SYM(oline), "\xe2\x80\xbe", "‾", "<oline/>", "‾", "{$\\overline{\\,}$}", NULL, "\\u8254?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(frasl), "\xe2\x81\x84", "⁄", "<frasl/>", "⁄", "/", NULL, "\\u8260?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(weierp), "\xe2\x84\x98", "℘", "<weierp/>", "℘", "{$\\wp$}", NULL, "\\u8472?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(image), "\xe2\x84\x91", "ℑ", "<image/>", "ℑ", "{$\\Im$}", NULL, "\\u8465?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(real), "\xe2\x84\x9c", "ℜ", "<real/>", "ℜ", "{$\\Re$}", NULL, "\\u8476?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(trade), "\xe2\x84\xa2", "™", "<trademark/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", DocSymbol::Perl_symbol }},
+ { SYM(alefsym), "\xe2\x85\xb5", "ℵ", "<alefsym/>", "ℵ", "{$\\aleph$}", NULL, "\\u8501?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(larr), "\xe2\x86\x90", "←", "<larr/>", "←", "{$\\leftarrow$}", NULL, "\\u8592?", { "<-", DocSymbol::Perl_string }},
+ { SYM(uarr), "\xe2\x86\x91", "↑", "<uarr/>", "↑", "{$\\uparrow$}", NULL, "\\u8593?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(rarr), "\xe2\x86\x92", "→", "<rarr/>", "→", "{$\\rightarrow$}", NULL, "\\u8594?", { "->", DocSymbol::Perl_string }},
+ { SYM(darr), "\xe2\x86\x93", "↓", "<darr/>", "↓", "{$\\downarrow$}", NULL, "\\u8595?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(harr), "\xe2\x86\x94", "↔", "<harr/>", "↔", "{$\\leftrightarrow$}", NULL, "\\u8596?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(crarr), "\xe2\x86\xb5", "↵", "<crarr/>", "↵", "{$\\hookleftarrow$}", NULL, "\\u8629?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(lArr), "\xe2\x87\x90", "⇐", "<lArr/>", "⇐", "{$\\Leftarrow$}", NULL, "\\u8656?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(uArr), "\xe2\x87\x91", "⇑", "<uArr/>", "⇑", "{$\\Uparrow$}", NULL, "\\u8657?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(rArr), "\xe2\x87\x92", "⇒", "<rArr/>", "⇒", "{$\\Rightarrow$}", NULL, "\\u8658?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(dArr), "\xe2\x87\x93", "⇓", "<dArr/>", "⇓", "{$\\Downarrow$}", NULL, "\\u8659?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(hArr), "\xe2\x87\x94", "⇔", "<hArr/>", "⇔", "{$\\Leftrightarrow$}", NULL, "\\u8660?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(forall), "\xe2\x88\x80", "∀", "<forall/>", "∀", "{$\\forall$}", NULL, "\\u8704?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(part), "\xe2\x88\x82", "∂", "<part/>", "∂", "{$\\partial$}", NULL, "\\u8706?", { "partial", DocSymbol::Perl_symbol }},
+ { SYM(exist), "\xe2\x88\x83", "∃", "<exist/>", "∃", "{$\\exists$}", NULL, "\\u8707?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(empty), "\xe2\x88\x85", "∅", "<empty/>", "∅", "{$\\emptyset$}", NULL, "\\u8709?", { "empty", DocSymbol::Perl_symbol }},
+ { SYM(nabla), "\xe2\x88\x87", "∇", "<nabla/>", "∇", "{$\\nabla$}", NULL, "\\u8711?", { "nabla", DocSymbol::Perl_symbol }},
+ { SYM(isin), "\xe2\x88\x88", "∈", "<isin/>", "∈", "{$\\in$}", NULL, "\\u8712?", { "in", DocSymbol::Perl_symbol }},
+ { SYM(notin), "\xe2\x88\x89", "∉", "<notin/>", "∉", "{$\\notin$}", NULL, "\\u8713?", { "notin", DocSymbol::Perl_symbol }},
+ { SYM(ni), "\xe2\x88\x8b", "∋", "<ni/>", "∋", "{$\\ni$}", NULL, "\\u8715?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(prod), "\xe2\x88\x8f", "∏", "<prod/>", "∏", "{$\\prod$}", NULL, "\\u8719?", { "prod", DocSymbol::Perl_symbol }},
+ { SYM(sum), "\xe2\x88\x91", "∑", "<sum/>", "∑", "{$\\sum$}", NULL, "\\u8721?", { "sum", DocSymbol::Perl_symbol }},
+ { SYM(minus), "\xe2\x88\x92", "−", "<minus/>", "−", "-", NULL, "\\u8722?", { "-", DocSymbol::Perl_char }},
+ { SYM(lowast), "\xe2\x88\x97", "∗", "<lowast/>", "∗", "{$\\ast$}", NULL, "\\u8727?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(radic), "\xe2\x88\x9a", "√", "<radic/>", "√", "{$\\surd$}", NULL, "\\u8730?", { "sqrt", DocSymbol::Perl_symbol }},
+ { SYM(prop), "\xe2\x88\x9d", "∝", "<prop/>", "∝", "{$\\propto$}", NULL, "\\u8733?", { "propto", DocSymbol::Perl_symbol }},
+ { SYM(infin), "\xe2\x88\x9e", "∞", "<infin/>", "∞", "{$\\infty$}", NULL, "\\u8734?", { "inf", DocSymbol::Perl_symbol }},
+ { SYM(ang), "\xe2\x88\xa0", "∠", "<ang/>", "∠", "{$\\angle$}", NULL, "\\u8736?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(and), "\xe2\x88\xa7", "∧", "<and/>", "∧", "{$\\wedge$}", NULL, "\\u8743?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(or), "\xe2\x88\xa8", "∨", "<or/>", "∨", "{$\\vee$}", NULL, "\\u8744?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(cap), "\xe2\x88\xa9", "∩", "<cap/>", "∩", "{$\\cap$}", NULL, "\\u8745?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(cup), "\xe2\x88\xaa", "∪", "<cup/>", "∪", "{$\\cup$}", NULL, "\\u8746?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(int), "\xe2\x88\xab", "∫", "<int/>", "∫", "{$\\int$}", NULL, "\\u8747?", { "int", DocSymbol::Perl_symbol }},
+ { SYM(there4), "\xe2\x88\xb4", "∴", "<there4/>", "∴", "{$\\therefore$}", NULL, "\\u8756?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(sim), "\xe2\x88\xbc", "∼", "<sim/>", "∼", "{$\\sim$}", NULL, "\\u8764?", { "~", DocSymbol::Perl_char }},
+ { SYM(cong), "\xe2\x89\x85", "≅", "<cong/>", "≅", "{$\\cong$}", NULL, "\\u8773?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(asymp), "\xe2\x89\x88", "≈", "<asymp/>", "≈", "{$\\approx$}", NULL, "\\u8776?", { "approx", DocSymbol::Perl_symbol }},
+ { SYM(ne), "\xe2\x89\xa0", "≠", "<ne/>", "≠", "{$\\ne$}", NULL, "\\u8800?", { "!=", DocSymbol::Perl_string }},
+ { SYM(equiv), "\xe2\x89\xa1", "≡", "<equiv/>", "≡", "{$\\equiv$}", NULL, "\\u8801?", { "equiv", DocSymbol::Perl_symbol }},
+ { SYM(le), "\xe2\x89\xa4", "≤", "<le/>", "≤", "{$\\le$}", NULL, "\\u8804?", { "<=", DocSymbol::Perl_string }},
+ { SYM(ge), "\xe2\x89\xa5", "≥", "<ge/>", "≥", "{$\\ge$}", NULL, "\\u8805?", { ">=", DocSymbol::Perl_string }},
+ { SYM(sub), "\xe2\x8a\x82", "⊂", "<sub/>", "⊂", "{$\\subset$}", NULL, "\\u8834?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(sup), "\xe2\x8a\x83", "⊃", "<sup/>", "⊃", "{$\\supset$}", NULL, "\\u8835?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(nsub), "\xe2\x8a\x84", "⊄", "<nsub/>", "⊄", "{$\\not\\subset$}", NULL, "\\u8836?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(sube), "\xe2\x8a\x86", "⊆", "<sube/>", "⊆", "{$\\subseteq$}", NULL, "\\u8838?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(supe), "\xe2\x8a\x87", "⊇", "<supe/>", "⊇", "{$\\supseteq$}", NULL, "\\u8839?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(oplus), "\xe2\x8a\x95", "⊕", "<oplus/>", "⊕", "{$\\oplus$}", NULL, "\\u8853?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(otimes), "\xe2\x8a\x97", "⊗", "<otimes/>", "⊗", "{$\\otimes$}", NULL, "\\u8855?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(perp), "\xe2\x8a\xa5", "⊥", "<perp/>", "⊥", "{$\\perp$}", NULL, "\\u8869?", { "perp", DocSymbol::Perl_symbol }},
+ { SYM(sdot), "\xe2\x8b\x85", "⋅", "<sdot/>", "⋅", "{$\\cdot$}", NULL, "\\u8901?", { ".", DocSymbol::Perl_char }},
+ { SYM(lceil), "\xe2\x8c\x88", "⌈", "<lceil/>", "⌈", "{$\\lceil$}", NULL, "\\u8968?", { "lceil", DocSymbol::Perl_symbol }},
+ { SYM(rceil), "\xe2\x8c\x89", "⌉", "<rceil/>", "⌉", "{$\\rceil$}", NULL, "\\u8969?", { "rceil", DocSymbol::Perl_symbol }},
+ { SYM(lfloor), "\xe2\x8c\x8a", "⌊", "<lfloor/>", "⌊", "{$\\lfloor$}", NULL, "\\u8970?", { "lfloor", DocSymbol::Perl_symbol }},
+ { SYM(rfloor), "\xe2\x8c\x8b", "⌋", "<rfloor/>", "⌋", "{$\\rfloor$}", NULL, "\\u8971?", { "rfloor", DocSymbol::Perl_symbol }},
+ { SYM(lang), "\xe2\x8c\xa9", "〈", "<lang/>", "〈", "{$\\langle$}", NULL, "\\u9001?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(rang), "\xe2\x8c\xaa", "〉", "<rang/>", "〉", "{$\\rangle$}", NULL, "\\u9002?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(loz), "\xe2\x97\x8a", "◊", "<loz/>", "◊", "{$\\lozenge$}", NULL, "\\u9674?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(spades), "\xe2\x99\xa0", "♠", "<spades/>", "♠", "{$\\spadesuit$}", NULL, "\\u9824?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(clubs), "\xe2\x99\xa3", "♣", "<clubs/>", "♣", "{$\\clubsuit$}", NULL, "\\u9827?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(hearts), "\xe2\x99\xa5", "♥", "<hearts/>", "♥", "{$\\heartsuit$}", NULL, "\\u9829?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(diams), "\xe2\x99\xa6", "♦", "<diams/>", "♦", "{$\\diamondsuit$}", NULL, "\\u9830?", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(quot), "\"", """, "\"", """, "\"", "\"", "\"", { "\"", DocSymbol::Perl_char }},
+ { SYM(amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", DocSymbol::Perl_char }},
+ { SYM(lt), "<", "<", "<", "<", "<", "<", "<", { "<", DocSymbol::Perl_char }},
+ { SYM(gt), ">", ">", ">", ">", ">", ">", ">", { ">", DocSymbol::Perl_char }},
+ { SYM(OElig), "\xc5\x92", "Œ", "<OElig/>", "Œ", "\\OE", NULL, "\\'8C", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(oelig), "\xc5\x93", "œ", "<oelig/>", "œ", "\\oe", NULL, "\\'9C", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Scaron), "\xc5\xa0", "Š", "<Scaron/>", "Š", "\\v{S}", NULL, "\\'8A", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(scaron), "\xc5\xa1", "š", "<scaron/>", "š", "\\v{s}", NULL, "\\'9A", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Yuml), "\xc5\xb8", "Ÿ", "<Yumlaut/>", "Ÿ", "\\\"{Y}", "Y\\*(4", "\\'9F", { "Y", DocSymbol::Perl_umlaut }},
+ { SYM(circ), "\xcb\x86", "ˆ", "<circ/>", "ˆ", "{$\\circ$}", NULL, "\\'88", { " ", DocSymbol::Perl_circ }},
+ { SYM(tilde), "\xcb\x9c", "˜", "<tilde/>", "˜", "\\~{}", "~", "\\'98", { " ", DocSymbol::Perl_tilde }},
+ { SYM(ensp), "\xe2\x80\x82", " ", "<ensp/>", " ", "\\enskip{}", NULL, "{\\enspace}", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(emsp), "\xe2\x80\x83", " ", "<emsp/>", " ", "\\quad{}", NULL, "{\\emspace}", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(thinsp), "\xe2\x80\x89", " ", "<thinsp/>", " ", "\\,", NULL, "{\\qmspace}", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(zwnj), "\xe2\x80\x8c", "", "<zwnj/>", "", "{}", NULL, "\\zwnj", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(zwj), "\xe2\x80\x8d", "", "<zwj/>", "", "", NULL, "\\zwj", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(lrm), "\xe2\x80\x8e", "", "<lrm/>", "", "", NULL, "\\ltrmark", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(rlm), "\xe2\x80\x8f", "", "<rlm/>", "", "", NULL, "\\rtlmark", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(ndash), "\xe2\x80\x93", "–", "<ndash/>", "–", "--", "--", "\\'96", { "-", DocSymbol::Perl_char }},
+ { SYM(mdash), "\xe2\x80\x94", "—", "<mdash/>", "—", "---", "---", "\\'97", { "--", DocSymbol::Perl_string }},
+ { SYM(lsquo), "\xe2\x80\x98", "‘", "<lsquo/>", "‘", "`", "`", "\\'91", { "\\\'", DocSymbol::Perl_string }},
+ { SYM(rsquo), "\xe2\x80\x99", "’", "<rsquo/>", "’", "'", "'", "\\'92", { "\\\'", DocSymbol::Perl_string }},
+ { SYM(sbquo), "\xe2\x80\x9a", "‚", "<sbquo/>", "‚", "\\quotesinglbase{}", NULL, "\\'82", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(ldquo), "\xe2\x80\x9c", "“", "<ldquo/>", "“", "``", "``", "\\'93", { "\"", DocSymbol::Perl_char }},
+ { SYM(rdquo), "\xe2\x80\x9d", "”", "<rdquo/>", "”", "''", "''", "\\'94", { "\"", DocSymbol::Perl_char }},
+ { SYM(bdquo), "\xe2\x80\x9e", "„", "<bdquo/>", "„", "\\quotedblbase{}", NULL, "\\'84", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(dagger), "\xe2\x80\xa0", "†", "<dagger/>", "†", "{$\\dagger$}", NULL, "\\'86", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(Dagger), "\xe2\x80\xa1", "‡", "<Dagger/>", "‡", "{$\\ddagger$}", NULL, "\\'87", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(permil), "\xe2\x80\xb0", "‰", "<permil/>", "‰", "{$\\permil{}$}", NULL, "\\'89", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(lsaquo), "\xe2\x80\xb9", "‹", "<lsaquo/>", "‹", "\\guilsinglleft{}", NULL, "\\'8B", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(rsaquo), "\xe2\x80\xba", "›", "<rsaquo/>", "›", "\\guilsinglright{}", NULL, "\\'9B", { NULL, DocSymbol::Perl_unknown }},
+ { SYM(euro), "\xe2\x82\xac", "€", "<euro/>", "€", "\\texteuro{}", NULL, "\\'80", { NULL, DocSymbol::Perl_unknown }},
+
+ // doxygen extension to the HTML4 table of HTML entities
+ { SYM(tm), "\xe2\x84\xa2", "™", "<trademark/>", "™", "\\texttrademark{}", "(TM)", "\\'99", { "trademark", DocSymbol::Perl_symbol }},
+ { SYM(apos), "'", "'", "'", "'", "'", "'", "'", { "\\\'", DocSymbol::Perl_string }},
+
+ // doxygen commands represented as HTML entities
+ { SYM(BSlash), "\\", "\\", "\\", "\\", "\\textbackslash{}", "\\\\", "\\\\", { "\\\\", DocSymbol::Perl_string }},
+ { SYM(At), "@", "@", "@", "@", "@", "@", "@", { "@", DocSymbol::Perl_char }},
+ { SYM(Less), "<", "<", "<", "<", "<", "<", "<", { "<", DocSymbol::Perl_char }},
+ { SYM(Greater), ">", ">", ">", ">", ">", ">", ">", { ">", DocSymbol::Perl_char }},
+ { SYM(Amp), "&", "&", "&", "&", "\\&", "&", "&", { "&", DocSymbol::Perl_char }},
+ { SYM(Dollar), "$", "$", "$", "$", "\\$", "$", "$", { "$", DocSymbol::Perl_char }},
+ { SYM(Hash), "#;", "#", "#", "#", "\\#", "#", "#", { "#", DocSymbol::Perl_char }},
+ { SYM(DoubleColon), "::", "::", "::", "::", "::", "::", "::", { "::", DocSymbol::Perl_string }},
+ { SYM(Percent), "%", "%", "%", "%", "\\%", "%", "%", { "%", DocSymbol::Perl_char }},
+ { SYM(Pipe), "|", "|", "|", "|", "$|$", "|", "|", { "|", DocSymbol::Perl_char }},
+ { SYM(Quot), "\"", "\"", "\"", """, "\"", "\"", "\"", { "\"", DocSymbol::Perl_char }},
+ { SYM(Minus), "-", "-", "-", "-", "-\\/", "-", "-", { "-", DocSymbol::Perl_char }}
+};
+
+static const int g_numHtmlEntities = (int)(sizeof(g_htmlEntities)/ sizeof(*g_htmlEntities));
+
+HtmlEntityMapper *HtmlEntityMapper::s_instance = 0;
+
+HtmlEntityMapper::HtmlEntityMapper()
+{
+ m_name2sym = new QDict<int>(1009);
+ m_name2sym->setAutoDelete(TRUE);
+ for (int i = 0; i < g_numHtmlEntities; i++)
+ {
+ m_name2sym->insert(g_htmlEntities[i].item,new int(g_htmlEntities[i].symb));
+ }
+ validate();
+}
+
+HtmlEntityMapper::~HtmlEntityMapper()
+{
+ delete m_name2sym;
+}
+
+/** Returns the one and only instance of the HTML entity mapper */
+HtmlEntityMapper *HtmlEntityMapper::instance()
+{
+ if (s_instance==0)
+ {
+ s_instance = new HtmlEntityMapper;
+ }
+ return s_instance;
+}
+
+/** Deletes the one and only instance of the HTML entity mapper */
+void HtmlEntityMapper::deleteInstance()
+{
+ delete s_instance;
+ s_instance=0;
+}
+
+
+/*! @brief Access routine to the UTF8 code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @param useInPrintf If TRUE the result will be escaped such that it can be
+ * used in a printf string pattern
+ * @return the UTF8 code of the HTML entity,
+ * in case the UTF code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::utf8(DocSymbol::SymType symb,bool useInPrintf) const
+{
+ if (useInPrintf && symb==DocSymbol::Sym_Percent)
+ {
+ return "%%"; // escape for printf
+ }
+ else
+ {
+ return g_htmlEntities[symb].UTF8;
+ }
+}
+
+/*! @brief Access routine to the html code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @param useInPrintf If TRUE the result will be escaped such that it can be
+ * used in a printf string pattern
+ * @return the html representation of the HTML entity,
+ * in case the html code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::html(DocSymbol::SymType symb,bool useInPrintf) const
+{
+ if (useInPrintf && symb==DocSymbol::Sym_Percent)
+ {
+ return "%%"; // escape for printf
+ }
+ else
+ {
+ return g_htmlEntities[symb].html;
+ }
+}
+
+/*! @brief Access routine to the XML code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the XML code of the HTML entity,
+ * in case the XML code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::xml(DocSymbol::SymType symb) const
+{
+ return g_htmlEntities[symb].xml;
+}
+
+/*! @brief Access routine to the docbook code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the docbook code of the HTML entity,
+ * in case the docbook code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::docbook(DocSymbol::SymType symb) const
+{
+ return g_htmlEntities[symb].docbook;
+}
+
+/*! @brief Access routine to the LaTeX code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the LaTeX code of the HTML entity,
+ * in case the LaTeX code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::latex(DocSymbol::SymType symb) const
+{
+ return g_htmlEntities[symb].latex;
+}
+
+/*! @brief Access routine to the man code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the man of the HTML entity,
+ * in case the man code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::man(DocSymbol::SymType symb) const
+{
+ return g_htmlEntities[symb].man;
+}
+
+/*! @brief Access routine to the RTF code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the RTF of the HTML entity,
+ * in case the RTF code is unknown \c NULL is returned.
+ */
+const char *HtmlEntityMapper::rtf(DocSymbol::SymType symb) const
+{
+ return g_htmlEntities[symb].rtf;
+}
+
+/*! @brief Access routine to the perl struct with the perl code of the HTML entity
+ *
+ * @param symb Code of the requested HTML entity
+ * @return the pointer to perl struct with the perl code of the HTML entity,
+ * in case the perl code does not exists the NULL pointer is entered in the
+ * \c symb field and in the `DocSymbol::Perl_unknown` in the \c type field.
+ */
+const DocSymbol::PerlSymb *HtmlEntityMapper::perl(DocSymbol::SymType symb) const
+{
+ return &g_htmlEntities[symb].perl;
+}
+
+/*!
+ * @brief Give code of the requested HTML entity name
+ * @param symName HTML entity name without \c & and \c ;
+ * @return the code for the requested HTML entity name,
+ * in case the requested HTML item does not exist `DocSymbol::Sym_unknown` is returned.
+ */
+DocSymbol::SymType HtmlEntityMapper::name2sym(const QCString &symName) const
+{
+ int *pSymb = m_name2sym->find(symName);
+ return pSymb ? ((DocSymbol::SymType)*pSymb) : DocSymbol::Sym_Unknown;
+}
+
+void HtmlEntityMapper::writeXMLSchema(FTextStream &t)
+{
+ for (int i=0;i<g_numHtmlEntities - g_numberHtmlMappedCmds;i++)
+ {
+ QCString bareName = g_htmlEntities[i].xml;
+ if (!bareName.isEmpty() && bareName.at(0)=='<' && bareName.right(2)=="/>")
+ {
+ bareName = bareName.mid(1,bareName.length()-3); // strip < and />
+ t << " <xsd:element name=\"" << bareName << "\" type=\"docEmptyType\" />\n";
+ }
+ }
+}
+
+/*! @brief Routine to check if the entries of the html_entities are numbered correctly
+ * @details in case of a mismatch a warning message is given.
+ */
+void HtmlEntityMapper::validate()
+{
+ for (int i = 0; i < g_numHtmlEntities; i++)
+ {
+ if (i != g_htmlEntities[i].symb)
+ {
+ warn_uncond("Internal inconsistency, htmlentries code %d (item=%s)\n",i,g_htmlEntities[i].item);
+ }
+ }
+}
diff --git a/src/htmlentity.h b/src/htmlentity.h
new file mode 100644
index 0000000..d3b268c
--- /dev/null
+++ b/src/htmlentity.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#ifndef HTMLENTITY_H
+#define HTMLENTITY_H
+
+#include <qdict.h>
+#include "docparser.h"
+
+class FTextStream;
+
+/** @brief Singleton helper class to map html entities to other formats */
+class HtmlEntityMapper
+{
+ public:
+ static HtmlEntityMapper *instance();
+ static void deleteInstance();
+ DocSymbol::SymType name2sym(const QCString &symName) const;
+ const char *utf8(DocSymbol::SymType symb,bool useInPrintf=FALSE) const;
+ const char *html(DocSymbol::SymType symb,bool useInPrintf=FALSE) const;
+ const char *xml(DocSymbol::SymType symb) const;
+ const char *docbook(DocSymbol::SymType symb) const;
+ const char *latex(DocSymbol::SymType symb) const;
+ const char *man(DocSymbol::SymType symb) const;
+ const char *rtf(DocSymbol::SymType symb) const;
+ const DocSymbol::PerlSymb *perl(DocSymbol::SymType symb) const;
+ void writeXMLSchema(FTextStream &t);
+ private:
+ void validate();
+ HtmlEntityMapper();
+ ~HtmlEntityMapper();
+ static HtmlEntityMapper *s_instance;
+ QDict<int> *m_name2sym;
+};
+
+#endif
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
new file mode 100644
index 0000000..62ae1c7
--- /dev/null
+++ b/src/htmlgen.cpp
@@ -0,0 +1,3479 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qregexp.h>
+#include "message.h"
+#include "htmlgen.h"
+#include "config.h"
+#include "util.h"
+#include "doxygen.h"
+#include "logos.h"
+#include "diagram.h"
+#include "version.h"
+#include "dot.h"
+#include "language.h"
+#include "htmlhelp.h"
+#include "docparser.h"
+#include "htmldocvisitor.h"
+#include "searchindex.h"
+#include "pagedef.h"
+#include "debug.h"
+#include "dirdef.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "image.h"
+#include "ftvhelp.h"
+#include "bufstr.h"
+
+
+//#define DBG_HTML(x) x;
+#define DBG_HTML(x)
+
+static const char defaultHtmlHeader[] =
+#include "header.html.h"
+;
+
+static const char defaultHtmlFooter[] =
+#include "footer.html.h"
+;
+
+static const char defaultStyleSheet[] =
+#include "doxygen.css.h"
+;
+
+static const char search_functions_script[]=
+#include "search_functions.php.h"
+;
+
+static const char search_opensearch_script[]=
+#include "search_opensearch.php.h"
+;
+
+static const char search_styleSheet[] =
+#include "search.css.h"
+;
+
+static const char search_jquery_script1[]=
+#include "jquery_p1.js.h"
+;
+
+static const char search_jquery_script2[]=
+#include "jquery_p2.js.h"
+;
+
+static const char search_jquery_script3[]=
+#include "jquery_p3.js.h"
+;
+
+static const char search_jquery_script4[]=
+#include "jquery_ui.js.h"
+;
+
+static const char search_jquery_script5[]=
+#include "jquery_fx.js.h"
+;
+
+static const char search_jquery_script6[]=
+#include "jquery_pt.js.h"
+;
+
+static const char svgpan_script[]=
+#include "svgpan.js.h"
+;
+
+static const char dynsections_script[]=
+#include "dynsections.js.h"
+;
+
+static const char extsearch_script[]=
+#include "extsearch.js.h"
+;
+
+static QCString g_header;
+static QCString g_footer;
+static QCString g_mathjax_code;
+
+//------------------------- Pictures for the Tabs ------------------------
+
+// active tab background luma
+static unsigned char tab_a_png[36] =
+{
+ 31, 42, 59, 69, 73, 74, 75, 77, 77,
+ 77, 79, 80, 80, 82, 81, 83, 84, 86,
+ 87, 88, 89, 90, 91, 91, 93, 94, 94,
+ 96, 96, 97, 98, 98, 99, 99, 99, 100
+};
+
+// normal tab background luma
+static unsigned char tab_b_png[36] =
+{
+ 218, 228, 235, 233, 230, 227, 225, 222, 221,
+ 218, 217, 215, 214, 213, 212, 211, 210, 209,
+ 209, 197, 198, 199, 200, 201, 202, 203, 204,
+ 205, 207, 209, 211, 213, 217, 219, 206, 188
+};
+
+// hovering tab background luma
+static unsigned char tab_h_png[36] =
+{
+ 181, 191, 198, 196, 193, 190, 188, 185, 184,
+ 181, 180, 178, 177, 176, 175, 174, 173, 172,
+ 172, 154, 155, 156, 157, 158, 159, 160, 161,
+ 162, 164, 166, 168, 170, 174, 176, 163, 145
+};
+
+// shadowed header
+static unsigned char header_png[12] =
+{
+ 255, 240, 241, 242, 243, 244,
+ 245, 246, 247, 248, 249, 250
+};
+
+// function header
+static unsigned char func_header_png[56] =
+{
+ 248, 247, 246, 245, 244, 243, 242, 241,
+ 240, 239, 238, 237, 236, 235, 234, 233,
+ 232, 231, 230, 229, 228, 223, 223, 223,
+ 223, 223, 223, 223, 223, 223, 223, 223,
+ 224, 224, 224, 224, 225, 225, 225, 225,
+ 225, 226, 226, 226, 227, 227, 227, 227,
+ 228, 228, 228, 229, 229, 229, 229, 229
+};
+
+// tab separator
+static unsigned char tab_s_png[36] =
+{
+ 187, 186, 185, 183, 182, 181, 180, 178, 176,
+ 174, 173, 171, 169, 167, 164, 163, 161, 158,
+ 156, 154, 152, 150, 148, 145, 143, 141, 140,
+ 138, 136, 134, 131, 131, 128, 126, 125, 124
+};
+
+// breadcrumbs luma
+static unsigned char bc_s_png[240] =
+{
+ 150,187,187,148,148,148,148,148,
+ 147,175,186,147,147,147,147,147,
+ 146,153,185,185,146,146,146,146,
+ 144,144,177,183,144,144,144,144,
+ 144,144,159,182,144,144,144,144,
+ 143,143,144,179,181,143,143,143,
+ 142,142,142,165,180,142,142,142,
+ 141,141,141,144,178,178,141,141,
+ 139,139,139,139,167,176,139,139,
+ 137,137,137,137,146,174,137,137,
+ 137,137,137,137,137,169,173,137,
+ 135,135,135,135,135,150,171,135,
+ 133,133,133,133,133,135,167,169,
+ 132,132,132,132,132,132,154,167,
+ 129,129,129,129,129,129,140,164,
+ 129,129,129,129,129,129,154,163,
+ 127,127,127,127,127,128,161,161,
+ 125,125,125,125,125,141,158,125,
+ 123,123,123,123,123,152,156,123,
+ 121,121,121,121,129,154,121,121,
+ 120,120,120,120,143,152,120,120,
+ 118,118,118,120,150,150,118,118,
+ 117,117,117,132,148,117,117,117,
+ 114,114,114,142,145,114,114,114,
+ 113,113,120,143,113,113,113,113,
+ 111,111,133,141,111,111,111,111,
+ 110,112,140,140,110,110,110,110,
+ 109,124,138,109,109,109,109,109,
+ 107,133,136,107,107,107,107,107,
+ 111,134,106,106,106,106,106,106
+};
+
+// breadcrumbs alpha map
+static unsigned char bc_s_a_png[240] =
+{
+ 241,241, 21, 0, 0, 0, 0, 0,
+ 162,205,117, 0, 0, 0, 0, 0,
+ 54,231,225, 3, 0, 0, 0, 0,
+ 0,198,215, 78, 0, 0, 0, 0,
+ 0, 93,211,186, 0, 0, 0, 0,
+ 0, 6,232,235, 42, 0, 0, 0,
+ 0, 0,132,203,147, 0, 0, 0,
+ 0, 0, 27,242,241, 15, 0, 0,
+ 0, 0, 0,168,205,108, 0, 0,
+ 0, 0, 0, 63,228,219, 0, 0,
+ 0, 0, 0, 0,207,221, 72, 0,
+ 0, 0, 0, 0,102,208,177, 0,
+ 0, 0, 0, 0, 9,238,240, 36,
+ 0, 0, 0, 0, 0,138,201,138,
+ 0, 0, 0, 0, 0, 77,187,158,
+ 0, 0, 0, 0, 0,159,204,120,
+ 0, 0, 0, 0, 15,241,241, 21,
+ 0, 0, 0, 0,111,208,171, 0,
+ 0, 0, 0, 0,210,222, 66, 0,
+ 0, 0, 0, 60,227,219, 0, 0,
+ 0, 0, 0,162,204,114, 0, 0,
+ 0, 0, 18,238,238, 21, 0, 0,
+ 0, 0,114,205,165, 0, 0, 0,
+ 0, 0,216,225, 60, 0, 0, 0,
+ 0, 66,226,216, 0, 0, 0, 0,
+ 0,165,204,111, 0, 0, 0, 0,
+ 21,241,241, 18, 0, 0, 0, 0,
+ 117,203,159, 0, 0, 0, 0, 0,
+ 219,227, 57, 0, 0, 0, 0, 0,
+ 211,201, 0, 0, 0, 0, 0, 0
+};
+
+// doxygen logo luma
+static unsigned char doxygen_png[3224] =
+{
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 91, 91, 91, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,253,253,253,253, 32, 32,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,251,251,251,251, 32, 32,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,255,255,255,255,255,255,255,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249,249, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249, 32, 32, 32, 32, 32,249, 32, 32, 32, 32, 32,255,255,255,
+ 32, 32, 32, 32, 46,132,190,190,147, 61,247,247,247,247, 32, 32,247,247, 32, 32,118,161,190,190,161,118, 32, 32,247, 32, 46, 89, 89, 89, 89, 46, 32,247,247, 32, 89, 89, 89, 89, 61, 89, 89, 89, 89, 46, 32,247, 32, 46, 89, 89, 89, 89, 32,247, 32, 32,118,175,190,161, 89, 61, 89, 89, 89, 61, 32,247,247,247, 32, 32,104,147,190,190,190,132, 89, 32, 32,247,247, 32, 46, 89, 89, 89, 75, 32, 89,161,190,161, 75, 32,255,255,
+ 32, 32, 32, 74,230,244,244,244,244,244,244,244,244,244, 32, 32,244, 32, 74,216,244,244,244,244,244,244,216, 74, 32,244, 32,187,244,244,244,159, 32,244, 32,117,244,244,244,230, 46,173,244,244,244,131, 32,244, 32,131,244,244,244,173, 32, 32, 46,173,244,244,244,244,244,230,244,244,244,131, 32,244,244, 32, 74,202,244,244,244,244,244,244,244,173, 46, 32,244, 32, 89,244,244,244,187,145,244,244,244,244,244, 89, 32,255,
+ 32, 32, 46,213,241,241,241,241,241,241,241,241,241,241, 32, 32, 32, 60,227,241,241,241,241,241,241,241,241,227, 60, 32, 32, 46,227,241,241,241,102, 32, 60,227,241,241,241, 88, 32,116,241,241,241,199, 32,241, 32,185,241,241,241,116, 32, 32,143,241,241,241,241,241,241,241,241,241,241,130, 32,241, 32, 74,227,241,241,241,199,185,241,241,241,241,171, 32,241, 32, 88,241,241,241,241,241,241,241,241,241,241,199, 32,255,
+ 32, 32,128,237,237,237,223,128, 87,128,237,237,237,237, 32, 32, 32,182,237,237,237,196,100,100,196,237,237,237,182, 32,237, 32,100,237,237,237,223, 59,196,237,237,237,141, 32, 32, 46,237,237,237,237, 59, 32, 46,237,237,237,237, 46, 32, 59,237,237,237,237,169, 87, 87,182,237,237,237,128, 32,237, 32,196,237,237,237, 87, 32, 32, 73,223,237,237,237, 73, 32, 32, 87,237,237,237,237,223,182,223,237,237,237,237, 46, 32,
+ 32, 32,207,234,234,234,113, 32, 32, 32,234,234,234,234, 32, 32, 59,234,234,234,221, 45, 32, 32, 45,221,234,234,234, 59, 32,234, 32,140,234,234,234,221,234,234,234,194, 32, 32,234, 32,167,234,234,234,126, 32, 99,234,234,234,167, 32, 32,126,234,234,234,180, 32, 32, 32,126,234,234,234,126, 32, 32, 99,234,234,234,167, 32, 32, 32, 32,153,234,234,234,126, 32, 32, 86,234,234,234,207, 45, 32, 45,234,234,234,234, 86, 32,
+ 32, 45,231,231,231,218, 32, 32, 32, 32,231,231,231,231, 32, 32, 98,231,231,231,165, 32,231,231, 32,165,231,231,231, 98, 32,231, 32, 45,191,231,231,231,231,231,218, 72, 32,231,231, 32, 98,231,231,231,165, 32,151,231,231,231,112, 32, 32,165,231,231,231,112, 32,231, 32,125,231,231,231,125, 32, 32,138,231,231,231,178,125,125,125,125,178,231,231,231,178, 32, 32, 85,231,231,231,178, 32,255, 32,191,231,231,231, 85, 32,
+ 32, 84,227,227,227,175, 32, 32, 32, 32,227,227,227,227, 32, 32,123,227,227,227,123, 32,227,227, 32,123,227,227,227,123, 32,227,227, 32, 71,227,227,227,227,227,123, 32,227,227,227,227, 32,214,227,227,227, 45,201,227,227,227, 45, 32, 32,175,227,227,227, 84, 32,227, 32,123,227,227,227,123, 32, 32,175,227,227,227,227,227,227,227,227,227,227,227,227,175, 32, 32, 84,227,227,227,175, 32,255, 32,175,227,227,227, 84, 32,
+ 32, 83,223,223,223,172, 32, 32, 32, 32,223,223,223,223, 32, 32,121,223,223,223,121, 32,223,223, 32,121,223,223,223,121, 32,223,223,223, 32,172,223,223,223,210, 45, 32,223,223,223,223, 32,147,223,223,223,134,223,223,223,147, 32,223, 32,172,223,223,223, 83, 32,223, 32,121,223,223,223,121, 32, 32,172,223,223,223,223,223,223,223,223,223,223,223,223,172, 32, 32, 83,223,223,223,172, 32,255, 32,172,223,223,223, 83, 32,
+ 32, 82,220,220,220,170, 32, 32, 32, 32,220,220,220,220, 32, 32,120,220,220,220,120, 32,220,220, 32,120,220,220,220,120, 32,220,220, 32, 95,220,220,220,220,220,132, 32,220,220,220,220, 32, 95,220,220,220,207,220,220,220, 95, 32,220, 32,170,220,220,220,107, 32,220, 32,120,220,220,220,120, 32, 32,170,220,220,220,132, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,220,220,220,170, 32,255, 32,170,220,220,220, 82, 32,
+ 32, 57,216,216,216,216, 32, 32, 32, 32,216,216,216,216, 32, 32, 81,216,216,216,167, 32,216,216, 32,155,216,216,216, 81, 32,216, 32, 57,204,216,216,216,216,216,216, 93, 32,216,216,216,216, 32,204,216,216,216,216,216,204, 32,216,216, 32,118,216,216,216,167, 32, 32, 32,130,216,216,216,118, 32, 32,118,216,216,216,191, 32, 32,216,216,216, 32, 32, 44, 57, 32, 32, 81,216,216,216,167, 32,255, 32,167,216,216,216, 81, 32,
+ 32, 32,189,213,213,213,116, 32, 32, 80,213,213,213,213, 32, 32, 44,201,213,213,213, 68, 32, 32, 68,213,213,213,213, 44, 32, 32, 32,165,213,213,213,165,213,213,213,201, 44, 32,213,213,213, 32,129,213,213,213,213,213,141, 32,213,213, 32, 80,213,213,213,213,165,116,153,213,213,213,213,116, 32, 32, 56,213,213,213,213,153, 56, 32, 32, 32, 44,104,189,116, 32, 32, 80,213,213,213,165, 32,255, 32,165,213,213,213, 80, 32,
+ 32, 32,139,210,210,210,210,174,174,210,210,210,210,210, 32, 32, 32,127,210,210,210,198,127,127,198,210,210,210,127, 32,210, 32,115,210,210,210,174, 44,139,210,210,210,163, 32, 32,210,210, 32, 68,210,210,210,210,210, 91, 32,210,210,210, 32,174,210,210,210,210,210,210,210,210,210,210,115, 32,210, 32,127,210,210,210,210,210,174,163,163,210,210,210,115, 32, 32, 79,210,210,210,163, 32,255, 32,163,210,210,210, 79, 32,
+ 32, 32, 55,194,206,206,206,206,206,194,206,206,206,206, 32, 32, 32, 44,171,206,206,206,206,206,206,206,206,171, 44, 32, 32, 67,206,206,206,206, 67, 32, 44,183,206,206,206,113, 32,206,206,206, 32,183,206,206,206,194, 32,206,206,206,206, 32, 67,194,206,206,206,206,206,171,206,206,206,113, 32,206, 32, 32,136,206,206,206,206,206,206,206,206,206,206,113, 32, 32, 78,206,206,206,160, 32,255, 32,160,206,206,206, 78, 32,
+ 32, 32, 32,100,192,203,203,203,157, 55,203,203,203,203, 32, 32,203, 32, 43,135,203,203,203,203,203,203,135, 43, 32, 32, 43,180,203,203,203,112, 32,203, 32, 66,203,203,203,203, 66, 32,203,203, 32,157,203,203,203,135, 32,203,203,203,203,203, 32, 43,112,157,157,123, 55,112,203,203,203,112, 32,203,203, 32, 32, 78,146,203,203,203,203,203,203,169,123, 55, 32, 32, 78,203,203,203,157, 32,255, 32,157,203,203,203, 78, 32,
+ 32, 32, 32, 32, 54,110,110, 88, 32, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 54, 99,110,110, 99, 54, 32, 32,200,200, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,200,200, 32, 54,200,200,200,200, 77, 32,200,200,200,200,200, 32, 32, 32, 32, 32, 32, 32,166,200,200,200, 88, 32,200,200,200,200, 32, 32, 32, 66, 77, 77, 77, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,255, 32, 32, 32, 32, 32, 32,255,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,198,198,198,198, 32, 32, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, 32,109,198,198,198,176, 32,198,198,198,198,198, 32, 98,121, 76, 32, 32, 54,109,198,198,198,198, 43, 32,198,198,198,198,198,198,198, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,255,255,255,255,255,255,255,255,
+ 32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 33,159,191,191,191,117, 36, 41, 41, 41, 41, 41, 34,108,191,191,191,191,191,191,191,191,191,117, 36, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
+ 32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 78, 38, 64,190,192,192,192, 66, 66, 41, 41, 85,128, 65, 34,107,190,192,192,192,192,192,192,192,139, 48, 39, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
+ 32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 96, 36, 95,147,148,148,139, 55, 41, 41, 85,121,128, 91, 38, 75,137,158,190,190,190,170,139, 97, 49, 37, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
+ 32, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41, 36, 45, 45, 45, 48, 38, 41, 41, 76, 76, 76, 76, 76, 37, 34, 42, 33, 33, 33, 39, 48, 59, 41, 41, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41,255,
+ 32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+// doxygen logo alpha map
+static unsigned char doxygen_a_png[3224] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,145,247,247,247,247,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,247,247,247,247,247,247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,247,247,247,247,247,247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,247,247,247,247,247,247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16,115,181,181,132,247,247,247,247,247,247, 0, 0, 0, 0, 0, 99,148,181,181,148, 99, 0, 0, 0, 0, 16, 66, 66, 66, 66, 16, 0, 0, 0, 0, 66, 66, 66, 66, 33, 66, 66, 66, 66, 16, 0, 0, 0, 16, 66, 66, 66, 66, 0, 0, 0, 0, 99,165,181,148, 66, 33, 66, 66, 66, 33, 0, 0, 0, 0, 0, 0, 82,132,181,181,181,115, 66, 0, 0, 0, 0, 0, 16, 66, 66, 66, 49, 0, 66,148,181,148, 49, 0, 0, 0,
+ 0, 0, 0,129,247,247,247,247,247,247,247,247,247,247,247, 0, 0, 0,112,214,247,247,247,247,247,247,214,112, 0, 16,247,247,247,247,247,247, 46, 0, 0,145,247,247,247,247,247,247,247,247,247,247, 16, 0, 16,247,247,247,247,247, 66, 0, 63,165,247,247,247,247,247,247,247,247,247,247, 33, 0, 0, 0, 96,198,247,247,247,247,247,247,247,165, 63, 0, 0, 16,247,247,247,247,247,145,247,247,247,247,247,145, 0, 0,
+ 0, 0,112,247,247,247,247,247,247,247,247,247,247,247,247, 0, 0,129,247,247,247,247,247,247,247,247,247,247,129, 0,181,247,247,247,247,247,148, 0,129,247,247,247,247,247,247,247,247,247,247,247,115, 0,115,247,247,247,247,247,165, 30,247,247,247,247,247,247,247,247,247,247,247,247,115, 0, 0,129,247,247,247,247,247,247,247,247,247,247,247, 63, 0, 66,247,247,247,247,247,247,247,247,247,247,247,247, 96, 0,
+ 0, 16,247,247,247,247,247,247,247,247,247,247,247,247,247, 0, 79,247,247,247,247,247,247,247,247,247,247,247,247, 79, 79,247,247,247,247,247,247,129,247,247,247,247,247,247,129,247,247,247,247,247,198, 0,181,247,247,247,247,247, 99,145,247,247,247,247,247,247,247,247,247,247,247,247,115, 0, 96,247,247,247,247,247,247,247,247,247,247,247,247,165, 0, 66,247,247,247,247,247,247,247,247,247,247,247,247,198, 0,
+ 0,115,247,247,247,247,247,247,247,247,247,247,247,247,247, 0,181,247,247,247,247,247,247,247,247,247,247,247,247,181, 0,129,247,247,247,247,247,247,247,247,247,247,247,145, 16,247,247,247,247,247,247, 33,247,247,247,247,247,247, 33,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 0,198,247,247,247,247,247,198,181,247,247,247,247,247,247, 49, 66,247,247,247,247,247,247,247,247,247,247,247,247,247, 16,
+ 0,214,247,247,247,247,247,129, 66,247,247,247,247,247,247, 33,247,247,247,247,247,247, 96, 96,247,247,247,247,247,247, 33, 0,145,247,247,247,247,247,247,247,247,247,198, 30, 0,165,247,247,247,247,247,115,247,247,247,247,247,165,115,247,247,247,247,247,181, 66,115,247,247,247,247,247,115, 82,247,247,247,247,247,165,115,115,148,247,247,247,247,247,115, 66,247,247,247,247,247,247,181,247,247,247,247,247,247, 66,
+ 16,247,247,247,247,247,231, 0, 0,247,247,247,247,247,247, 82,247,247,247,247,247,165, 0, 0,165,247,247,247,247,247, 82, 0, 30,247,247,247,247,247,247,247,247,247, 96, 0, 0, 82,247,247,247,247,247,165,247,247,247,247,247, 99,165,247,247,247,247,247, 99, 0,115,247,247,247,247,247,115,132,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181, 0,198,247,247,247,247,247, 66,
+ 66,247,247,247,247,247,181, 0, 0,247,247,247,247,247,247,115,247,247,247,247,247,115, 0, 0,115,247,247,247,247,247,115, 0, 0, 96,247,247,247,247,247,247,247,129, 0, 0, 0, 0,231,247,247,247,247,247,247,247,247,247,247, 16,181,247,247,247,247,247, 66, 0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 66,247,247,247,247,247,181, 0, 0,247,247,247,247,247,247,115,247,247,247,247,247,115, 0, 0,115,247,247,247,247,247,115, 0, 0, 0,181,247,247,247,247,247,247, 30, 0, 0, 0, 0,148,247,247,247,247,247,247,247,247,247,148, 0,181,247,247,247,247,247, 66, 0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 66,247,247,247,247,247,181, 0, 0,247,247,247,247,247,247,115,247,247,247,247,247,115, 0, 0,115,247,247,247,247,247,115, 0, 0,129,247,247,247,247,247,247,247,145, 0, 0, 0, 0, 82,247,247,247,247,247,247,247,247,247, 82, 0,181,247,247,247,247,247, 99, 0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 79, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 33,247,247,247,247,247,247, 14, 0,247,247,247,247,247,247, 66,247,247,247,247,247,181, 0, 0,165,247,247,247,247,247, 66, 0, 79,247,247,247,247,247,247,247,247,247,129, 0, 0, 0, 0,231,247,247,247,247,247,247,247,231, 0, 0,115,247,247,247,247,247,181,115,165,247,247,247,247,247,115,115,247,247,247,247,247,214, 63, 0, 0, 0, 16,112,247,247, 33, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 0,214,247,247,247,247,247,198,198,247,247,247,247,247,247, 16,247,247,247,247,247,247,132,132,247,247,247,247,247,247, 16, 14,181,247,247,247,247,247,247,247,247,247,247, 79, 0, 0, 0,132,247,247,247,247,247,247,247,148, 0, 0, 66,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 33,247,247,247,247,247,247,247,198,181,181,247,247,247,247,115, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 0,148,247,247,247,247,247,247,247,247,247,247,247,247,247, 0,132,247,247,247,247,247,247,247,247,247,247,247,247,145, 0,145,247,247,247,247,247,247,247,247,247,247,247,181, 14, 0, 0, 49,247,247,247,247,247,247,247, 82, 0, 0, 0,198,247,247,247,247,247,247,247,247,247,247,247,247,115, 0,145,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 0, 46,247,247,247,247,247,247,247,247,247,247,247,247,247, 0, 30,247,247,247,247,247,247,247,247,247,247,247,247, 30,112,247,247,247,247,247,247, 96,247,247,247,247,247,247,145, 0, 0, 0,214,247,247,247,247,247,231, 0, 0, 0, 0, 96,247,247,247,247,247,247,247,247,247,247,247,247,115, 0, 30,148,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 0, 0,129,247,247,247,247,247,247,247,247,247,247,247,247, 0, 0, 96,247,247,247,247,247,247,247,247,247,247, 96, 16,247,247,247,247,247,247,145, 0,112,247,247,247,247,247,247, 49, 0, 0,181,247,247,247,247,247,148, 0, 0, 0, 0, 0,129,247,247,247,247,247,247,247,247,247,247,247,115, 0, 0, 46,148,247,247,247,247,247,247,247,247,247,247,247, 33, 66,247,247,247,247,247,181, 0,181,247,247,247,247,247, 66,
+ 0, 0, 0,129,247,247,247,247,181,145,247,247,247,247,145, 0, 0, 0, 46,148,247,247,247,247,247,247,148, 46, 0, 0,112,214,247,247,247,145, 14, 0, 0,145,247,247,247,247,145, 0, 0, 33,247,247,247,247,247,247, 66, 0, 0, 0, 0, 0, 99,132,115,181,181,132,198,247,247,247,247,247, 82, 0, 0, 0, 0, 66,165,247,247,247,247,247,247,198,132, 33, 0, 0,145,247,247,247,181, 79, 0, 79,181,247,247,247,145, 0,
+ 0, 0, 0, 0, 33,115,115, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 99,115,115, 99, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115,247,247,247,247,247,214, 0, 0, 0, 0, 0, 99,247,247,247,247,247,247,247,247,247,247,247,247, 16, 0, 0, 0, 0, 0, 0, 0, 49, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,108,224,255,255,255,255,255,255,101,164,255,255,255,143,250,255,255,255,255,255,255,255,255,255,255,255, 98,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165, 0,
+ 0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,136,251,255,255,255,255,255,255,101,130,255,255,255,153,250,255,255,255,255,255,255,255,255,255,255,121, 98,189,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165, 0,
+ 0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,198,252,255,255,255,255,255,164,164,255,255,255,255,176,249,251,255,255,255,255,255,255,255,255,150, 86,192,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165, 0,
+ 0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,164,198,255,255,255,255,201,133,164,255,255,255,255,255,145,203,255,255,255,255,255,255,255,117, 79,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165, 0,
+ 0, 66,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 73, 73,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 47, 70,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 66, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+// magnifying glass icon (raw png)
+unsigned char mag_sel_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
+ 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
+ 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
+ 0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
+ 0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
+ 0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
+ 0x2a, 0xbd, 0x00, 0x00, 0x01, 0xb9, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
+ 0xe4, 0x94, 0xbb, 0x8a, 0x22, 0x41, 0x14, 0x86, 0xbf, 0xda, 0x16, 0x3a,
+ 0x10, 0xba, 0x03, 0x2f, 0x78, 0x03, 0x51, 0x11, 0x4c, 0xd4, 0x40, 0xd4,
+ 0x37, 0x30, 0x31, 0x30, 0xe9, 0x07, 0xf0, 0x15, 0x14, 0x7c, 0x1e, 0x31,
+ 0x37, 0x33, 0x11, 0x73, 0xe9, 0x56, 0x44, 0x84, 0x36, 0xe9, 0x40, 0x50,
+ 0x54, 0x14, 0xc4, 0xc0, 0xa8, 0x6d, 0x50, 0x6a, 0x92, 0x1d, 0xd9, 0x9d,
+ 0x99, 0x75, 0x0d, 0x26, 0x58, 0xd8, 0x3f, 0xaa, 0xe2, 0xfc, 0xf5, 0xd5,
+ 0x39, 0x9c, 0x53, 0x25, 0xa4, 0x94, 0x7c, 0xa7, 0x7e, 0xf0, 0xcd, 0xfa,
+ 0xf7, 0x81, 0xbe, 0xf7, 0xc5, 0xf9, 0x7c, 0x96, 0x93, 0xc9, 0x84, 0xe5,
+ 0x72, 0xc9, 0x66, 0xb3, 0x21, 0x99, 0x4c, 0x92, 0xcf, 0xe7, 0xa9, 0x54,
+ 0x2a, 0x04, 0x02, 0x01, 0xf1, 0x2a, 0x50, 0x48, 0x29, 0x39, 0x9d, 0x4e,
+ 0x72, 0x30, 0x18, 0x60, 0x59, 0xd6, 0x27, 0x43, 0xb5, 0x5a, 0xa5, 0xd1,
+ 0x68, 0x10, 0x0c, 0x06, 0xc5, 0xcb, 0x19, 0x4e, 0xa7, 0x53, 0x2c, 0xcb,
+ 0x22, 0x95, 0x4a, 0x51, 0x2a, 0x95, 0xc8, 0x64, 0x32, 0xac, 0x56, 0x2b,
+ 0x66, 0xb3, 0x19, 0x93, 0xc9, 0x84, 0x48, 0x24, 0x42, 0xbd, 0x5e, 0x7f,
+ 0xbd, 0x64, 0xdb, 0xb6, 0x01, 0x28, 0x97, 0xcb, 0x54, 0x2a, 0x15, 0x34,
+ 0x4d, 0x13, 0xa1, 0x50, 0x48, 0x2a, 0x8a, 0xc2, 0x7a, 0xbd, 0xc6, 0xb6,
+ 0x6d, 0xea, 0xf5, 0x3a, 0xa3, 0xd1, 0x48, 0xf6, 0xfb, 0xfd, 0xc7, 0x61,
+ 0xc3, 0x30, 0xa8, 0xd5, 0x6a, 0xe2, 0x53, 0x53, 0xb6, 0xdb, 0x2d, 0x00,
+ 0xc5, 0x62, 0x11, 0x4d, 0xd3, 0x04, 0x80, 0xa6, 0x69, 0xa2, 0x50, 0x28,
+ 0xf0, 0x6b, 0x1c, 0x10, 0x86, 0x61, 0x3c, 0x60, 0x80, 0xf8, 0xb2, 0xcb,
+ 0x89, 0x44, 0x02, 0x00, 0xc7, 0x71, 0x00, 0xde, 0x27, 0x5d, 0xfe, 0xdc,
+ 0x3f, 0xe2, 0x1f, 0xa0, 0xe2, 0x8f, 0x63, 0x93, 0xcb, 0xe5, 0x00, 0x18,
+ 0x8f, 0xc7, 0x98, 0xa6, 0x89, 0xeb, 0xba, 0xd2, 0x34, 0x4d, 0xc6, 0xe3,
+ 0x31, 0x00, 0xe9, 0x74, 0x1a, 0x80, 0x5a, 0xad, 0xf6, 0x80, 0x3e, 0xed,
+ 0xf2, 0x7a, 0xbd, 0x96, 0xc3, 0xe1, 0x90, 0xf9, 0x7c, 0xfe, 0xa5, 0x29,
+ 0x1c, 0x0e, 0xd3, 0xe9, 0x74, 0xd0, 0x75, 0x5d, 0x00, 0x8c, 0x46, 0xa3,
+ 0x8f, 0x17, 0xfc, 0x0e, 0xf4, 0x3c, 0x4f, 0xee, 0x76, 0x3b, 0x16, 0x8b,
+ 0x05, 0x8e, 0xe3, 0xb0, 0xdf, 0xef, 0x89, 0xc7, 0xe3, 0xa4, 0xd3, 0x69,
+ 0x6c, 0xdb, 0xe6, 0x74, 0x3a, 0x11, 0x8d, 0x46, 0x69, 0xb7, 0xdb, 0x0f,
+ 0xe8, 0xd3, 0x0c, 0x01, 0x3c, 0xcf, 0x93, 0xae, 0xeb, 0xe2, 0x79, 0x1e,
+ 0xb7, 0xdb, 0x0d, 0x9f, 0xcf, 0x87, 0xa2, 0x28, 0x5c, 0x2e, 0x17, 0x7a,
+ 0xbd, 0x1e, 0xc7, 0xe3, 0x91, 0x58, 0x2c, 0x46, 0xab, 0xd5, 0x7a, 0x0a,
+ 0x7d, 0xbc, 0x14, 0x55, 0x55, 0x85, 0xaa, 0xaa, 0x9f, 0x0c, 0x7e, 0xbf,
+ 0x5f, 0x36, 0x9b, 0x4d, 0xba, 0xdd, 0x2e, 0xd7, 0xeb, 0x95, 0xeb, 0xf5,
+ 0x8a, 0xae, 0xeb, 0x7f, 0xcf, 0xf0, 0x99, 0x5c, 0xd7, 0x95, 0x87, 0xc3,
+ 0x81, 0xfb, 0xfd, 0x4e, 0x36, 0x9b, 0x7d, 0xad, 0xe4, 0xff, 0xe7, 0xfb,
+ 0x7a, 0x1b, 0x00, 0x59, 0xa8, 0xba, 0x68, 0xca, 0x4f, 0xc5, 0xa7, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+unsigned int mag_sel_png_len = 563;
+
+unsigned char mag_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
+ 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
+ 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
+ 0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
+ 0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
+ 0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
+ 0x2a, 0xbd, 0x00, 0x00, 0x01, 0x92, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
+ 0xe4, 0x94, 0xbb, 0xaa, 0xea, 0x50, 0x10, 0x86, 0xbf, 0xec, 0x08, 0x29,
+ 0x36, 0x24, 0x85, 0x17, 0xbc, 0x81, 0x18, 0x11, 0x6c, 0xd4, 0x42, 0x8c,
+ 0x0f, 0x61, 0xe1, 0x2b, 0xf8, 0x0a, 0x0a, 0x3e, 0x8f, 0xf8, 0x0c, 0x36,
+ 0x62, 0x1f, 0x92, 0x88, 0x88, 0x10, 0x9b, 0x14, 0x42, 0x44, 0x45, 0x41,
+ 0x2c, 0xac, 0x92, 0x80, 0xb2, 0x4e, 0x73, 0x94, 0x03, 0xfb, 0xb0, 0x4d,
+ 0xb1, 0x8b, 0x03, 0xe7, 0xaf, 0xd6, 0x62, 0xfe, 0xf5, 0x31, 0xc3, 0xcc,
+ 0x1a, 0x49, 0x08, 0xc1, 0x4f, 0xea, 0x83, 0x1f, 0xd6, 0xbf, 0x0f, 0x4c,
+ 0x3c, 0x0f, 0xd7, 0xeb, 0x55, 0x38, 0x8e, 0xc3, 0x66, 0xb3, 0x61, 0xb7,
+ 0xdb, 0x51, 0x2a, 0x95, 0xa8, 0xd7, 0xeb, 0x18, 0x86, 0x41, 0x32, 0x99,
+ 0x94, 0xe2, 0x02, 0x25, 0x21, 0x04, 0x97, 0xcb, 0x45, 0x4c, 0xa7, 0x53,
+ 0x6c, 0xdb, 0xfe, 0x62, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x52, 0xa9,
+ 0x94, 0x14, 0x3b, 0xc3, 0xc5, 0x62, 0x81, 0x6d, 0xdb, 0x94, 0xcb, 0x65,
+ 0x5a, 0xad, 0x16, 0x95, 0x4a, 0x85, 0xed, 0x76, 0xcb, 0x72, 0xb9, 0xc4,
+ 0x71, 0x1c, 0xb2, 0xd9, 0x2c, 0xdd, 0x6e, 0x37, 0x7e, 0xc9, 0xae, 0xeb,
+ 0x02, 0xd0, 0x6e, 0xb7, 0x31, 0x0c, 0x03, 0x55, 0x55, 0xa5, 0x74, 0x3a,
+ 0x2d, 0x64, 0x59, 0xc6, 0xf7, 0x7d, 0x5c, 0xd7, 0x8d, 0x0d, 0xfc, 0x00,
+ 0xd8, 0xef, 0xf7, 0x00, 0x34, 0x9b, 0x4d, 0x54, 0x55, 0x95, 0x00, 0x54,
+ 0x55, 0x95, 0x1a, 0x8d, 0x06, 0x7f, 0xc6, 0x63, 0x03, 0x8b, 0xc5, 0x22,
+ 0x00, 0x9e, 0xe7, 0x01, 0x3c, 0x27, 0x5d, 0xfc, 0xbe, 0xbf, 0xe2, 0xb1,
+ 0x81, 0xb5, 0x5a, 0x0d, 0x00, 0xd3, 0x34, 0xb1, 0x2c, 0x8b, 0x20, 0x08,
+ 0x84, 0x65, 0x59, 0x98, 0xa6, 0x09, 0x80, 0xae, 0xeb, 0xaf, 0x07, 0xf3,
+ 0xf9, 0xfc, 0x7d, 0x97, 0x7d, 0xdf, 0x17, 0xb3, 0xd9, 0x8c, 0xd5, 0x6a,
+ 0xf5, 0x57, 0x53, 0x26, 0x93, 0x61, 0x34, 0x1a, 0xa1, 0x69, 0x9a, 0x14,
+ 0x6b, 0x6c, 0xa2, 0x28, 0x12, 0x87, 0xc3, 0x81, 0xf5, 0x7a, 0x8d, 0xe7,
+ 0x79, 0x1c, 0x8f, 0x47, 0x0a, 0x85, 0x02, 0xba, 0xae, 0xe3, 0xba, 0x2e,
+ 0x97, 0xcb, 0x85, 0x5c, 0x2e, 0xc7, 0x70, 0x38, 0x7c, 0x0b, 0x95, 0x9e,
+ 0xcb, 0x21, 0x8a, 0x22, 0x11, 0x04, 0x01, 0x51, 0x14, 0x71, 0xbf, 0xdf,
+ 0x49, 0x24, 0x12, 0xc8, 0xb2, 0xcc, 0xed, 0x76, 0x63, 0x32, 0x99, 0x70,
+ 0x3e, 0x9f, 0xc9, 0xe7, 0xf3, 0x0c, 0x06, 0x83, 0x6f, 0xa1, 0xaf, 0x9f,
+ 0xa2, 0x28, 0x8a, 0xa4, 0x28, 0xca, 0x17, 0xc3, 0xe7, 0xe7, 0xa7, 0xe8,
+ 0xf7, 0xfb, 0x8c, 0xc7, 0x63, 0xc2, 0x30, 0x24, 0x0c, 0x43, 0x34, 0x4d,
+ 0x7b, 0x9f, 0xe1, 0x77, 0x0a, 0x82, 0x40, 0x9c, 0x4e, 0x27, 0x1e, 0x8f,
+ 0x07, 0xd5, 0x6a, 0x35, 0x5e, 0xc9, 0xff, 0xcf, 0xfa, 0xfa, 0x35, 0x00,
+ 0x70, 0xf3, 0xae, 0xcb, 0x89, 0xcd, 0xd2, 0x46, 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+unsigned int mag_png_len = 524;
+
+unsigned char search_l_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
+ 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
+ 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
+ 0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
+ 0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
+ 0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
+ 0x2a, 0xbd, 0x00, 0x00, 0x01, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
+ 0xac, 0x54, 0x3d, 0xab, 0xda, 0x50, 0x18, 0x7e, 0xce, 0xc9, 0x39, 0x31,
+ 0x4d, 0xfc, 0x40, 0x30, 0x46, 0x14, 0xec, 0x50, 0x44, 0x17, 0x2f, 0x9d,
+ 0xba, 0x15, 0xda, 0xd1, 0xa1, 0x2e, 0xdd, 0x3b, 0x14, 0x4a, 0xa1, 0x7f,
+ 0xa6, 0x74, 0xbd, 0x43, 0xff, 0x84, 0xfd, 0x05, 0x82, 0xda, 0xa5, 0x83,
+ 0x1d, 0xdc, 0x8a, 0x88, 0xa0, 0x44, 0x83, 0xc6, 0x28, 0xad, 0x1f, 0x49,
+ 0xde, 0x2e, 0x8d, 0x78, 0x6f, 0xaf, 0x34, 0x68, 0x9f, 0xed, 0xbc, 0x70,
+ 0x1e, 0x9e, 0x8f, 0xf7, 0x1c, 0x46, 0x44, 0x38, 0x45, 0xaf, 0xd7, 0x63,
+ 0xb6, 0x6d, 0xe7, 0x6d, 0xdb, 0x6e, 0xba, 0xae, 0xfb, 0x6e, 0xb3, 0xd9,
+ 0xdc, 0x6c, 0xb7, 0xdb, 0x04, 0xe7, 0x1c, 0x8c, 0x31, 0xfc, 0x0b, 0x2c,
+ 0x22, 0xec, 0x76, 0xbb, 0xcc, 0xf3, 0xbc, 0xcc, 0x68, 0x34, 0x7a, 0xed,
+ 0xba, 0xee, 0x87, 0x6c, 0x36, 0x7b, 0x93, 0xcb, 0xe5, 0x44, 0x3a, 0x9d,
+ 0x86, 0xa6, 0x69, 0x50, 0x14, 0x25, 0x3e, 0x61, 0xa7, 0xd3, 0x61, 0xf3,
+ 0xf9, 0xfc, 0xc9, 0x78, 0x3c, 0xbe, 0xd5, 0x75, 0xfd, 0x79, 0xa5, 0x52,
+ 0x11, 0xa6, 0x69, 0x22, 0x95, 0x4a, 0x41, 0xd3, 0x34, 0x08, 0x21, 0xc0,
+ 0x18, 0x8b, 0x45, 0x28, 0x00, 0x60, 0xb5, 0x5a, 0xa5, 0x27, 0x93, 0xc9,
+ 0xa7, 0x62, 0xb1, 0xf8, 0xb2, 0x5a, 0xad, 0x22, 0x9f, 0xcf, 0xc3, 0x30,
+ 0x0c, 0x48, 0x29, 0xc1, 0x39, 0x47, 0x5c, 0xbb, 0x00, 0x20, 0xda, 0xed,
+ 0x36, 0x9f, 0x4e, 0xa7, 0xaf, 0x4c, 0xd3, 0x7c, 0x51, 0xaf, 0xd7, 0x61,
+ 0x59, 0x16, 0x74, 0x5d, 0x87, 0x94, 0x12, 0x97, 0x40, 0x2c, 0x16, 0x0b,
+ 0x93, 0x88, 0xde, 0xd6, 0x6a, 0x35, 0xdd, 0xb2, 0x2c, 0x18, 0x86, 0x01,
+ 0x21, 0x04, 0x2e, 0x05, 0xf7, 0x3c, 0xaf, 0x59, 0x2e, 0x97, 0x9f, 0x45,
+ 0xca, 0x38, 0xe7, 0xb8, 0x06, 0x3c, 0x08, 0x82, 0x46, 0xa1, 0x50, 0x78,
+ 0x74, 0xad, 0xb2, 0x23, 0xa1, 0x94, 0xf2, 0x69, 0x26, 0x93, 0xe1, 0x51,
+ 0x66, 0xf7, 0xf7, 0xd2, 0xf7, 0xfd, 0x07, 0x2f, 0x9e, 0x9b, 0x73, 0x55,
+ 0x55, 0xb3, 0x91, 0x55, 0xc6, 0x18, 0xc2, 0x30, 0xbc, 0x1b, 0xf2, 0x19,
+ 0xd5, 0xe7, 0xe6, 0x5c, 0x4a, 0x39, 0x06, 0x70, 0x5c, 0x8b, 0xb8, 0xeb,
+ 0x71, 0xd6, 0x32, 0x11, 0x75, 0xf6, 0xfb, 0xfd, 0xd1, 0xea, 0xd5, 0xa5,
+ 0x10, 0xd1, 0xb7, 0xf5, 0x7a, 0x1d, 0x84, 0x61, 0x08, 0x22, 0xba, 0x9e,
+ 0x50, 0x51, 0x94, 0xaf, 0x8e, 0xe3, 0xfc, 0xdc, 0xed, 0x76, 0xf8, 0x1f,
+ 0xe0, 0x89, 0x44, 0xe2, 0xc7, 0x72, 0xb9, 0xfc, 0xee, 0x38, 0x0e, 0x7c,
+ 0xdf, 0x3f, 0x5a, 0xbf, 0xdf, 0x76, 0x6c, 0xc2, 0x46, 0xa3, 0xf1, 0x2b,
+ 0x08, 0x82, 0xdb, 0xe1, 0x70, 0xe8, 0x2c, 0x16, 0x0b, 0x04, 0x41, 0x00,
+ 0x22, 0xba, 0xb8, 0x1c, 0xfe, 0x67, 0x05, 0xbe, 0x78, 0x9e, 0xf7, 0x79,
+ 0x30, 0x18, 0x8c, 0x67, 0xb3, 0x19, 0x45, 0x25, 0x9d, 0x53, 0x49, 0x44,
+ 0x38, 0x1c, 0x0e, 0x38, 0x2d, 0xf3, 0xce, 0x6f, 0x03, 0x60, 0x29, 0x84,
+ 0xf8, 0xe8, 0x79, 0x9e, 0xdb, 0xef, 0xf7, 0xdf, 0x97, 0x4a, 0xa5, 0xc7,
+ 0xd1, 0x53, 0x54, 0x55, 0x15, 0x52, 0xca, 0xbf, 0x14, 0x0b, 0x21, 0x1e,
+ 0x8c, 0x87, 0x9d, 0x1e, 0x5a, 0xad, 0x96, 0x00, 0x50, 0x27, 0xa2, 0x37,
+ 0xaa, 0xaa, 0x36, 0x0d, 0xc3, 0x28, 0x26, 0x93, 0x49, 0xa1, 0x69, 0x9a,
+ 0xc2, 0x39, 0x8f, 0x95, 0xc1, 0xef, 0x01, 0x00, 0x35, 0xe5, 0xd5, 0x5e,
+ 0xd0, 0xed, 0x0c, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
+ 0xae, 0x42, 0x60, 0x82
+};
+unsigned int search_l_png_len = 604;
+
+unsigned char search_m_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
+ 0x08, 0x02, 0x00, 0x00, 0x00, 0x35, 0x5e, 0x4b, 0x4d, 0x00, 0x00, 0x00,
+ 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58,
+ 0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66,
+ 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20,
+ 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9,
+ 0x65, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
+ 0x62, 0x2c, 0x2f, 0x2f, 0x67, 0x60, 0x60, 0x60, 0x3c, 0x7e, 0xfc, 0x38,
+ 0x88, 0xfa, 0xf8, 0xf1, 0x23, 0x88, 0xfa, 0xff, 0xff, 0x3f, 0x90, 0x62,
+ 0x62, 0x00, 0x03, 0x5a, 0x50, 0x2c, 0x10, 0x1b, 0x58, 0x6e, 0xdd, 0xba,
+ 0x05, 0xa4, 0x00, 0x02, 0x0c, 0x00, 0xa5, 0x07, 0x0f, 0x3c, 0x7e, 0xe1,
+ 0x45, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
+ 0x60, 0x82
+};
+unsigned int search_m_png_len = 158;
+
+unsigned char search_r_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x92, 0x5d, 0xf2, 0x00, 0x00, 0x00,
+ 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
+ 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
+ 0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
+ 0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
+ 0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
+ 0x2a, 0xbd, 0x00, 0x00, 0x01, 0xea, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
+ 0xa4, 0xd4, 0xbf, 0xaa, 0x1a, 0x41, 0x14, 0x06, 0xf0, 0x6f, 0xf6, 0x9f,
+ 0xb2, 0x0a, 0x6b, 0xa5, 0x56, 0x8b, 0xa4, 0x92, 0xd4, 0x69, 0x7c, 0x03,
+ 0xb1, 0x59, 0x49, 0x11, 0x52, 0xdf, 0xbc, 0x43, 0xcc, 0x2b, 0xa4, 0x4c,
+ 0x97, 0x67, 0x08, 0xa4, 0x11, 0x2c, 0x52, 0x5c, 0x42, 0x24, 0x60, 0x8a,
+ 0x34, 0x29, 0x42, 0x50, 0x41, 0x21, 0xa0, 0x97, 0xd5, 0x55, 0xb3, 0xbb,
+ 0xee, 0xb2, 0xce, 0xee, 0xcc, 0x49, 0x91, 0x28, 0xc2, 0x0d, 0xe6, 0xaa,
+ 0xa7, 0x9d, 0xc3, 0x8f, 0x73, 0x98, 0xf9, 0x86, 0x75, 0x3a, 0x1d, 0xc2,
+ 0x89, 0x12, 0x42, 0x24, 0xf9, 0x7c, 0x7e, 0x5a, 0x2c, 0x16, 0x3f, 0x96,
+ 0x4a, 0xa5, 0x5e, 0xb5, 0x5a, 0xfd, 0x52, 0x2e, 0x97, 0xfd, 0x46, 0xa3,
+ 0x21, 0x8e, 0xfb, 0xd8, 0x60, 0x30, 0x38, 0x09, 0x65, 0x59, 0x86, 0x24,
+ 0x49, 0x10, 0x04, 0x81, 0xf0, 0x3c, 0x6f, 0xb3, 0xd9, 0x6c, 0x7e, 0x58,
+ 0x96, 0x75, 0x5b, 0xab, 0xd5, 0xde, 0x34, 0x9b, 0xcd, 0x5f, 0x07, 0xc8,
+ 0xf7, 0xfd, 0x93, 0x90, 0x94, 0xf2, 0x80, 0x85, 0x61, 0x88, 0xe5, 0x72,
+ 0x49, 0xe3, 0xf1, 0x58, 0xc6, 0x71, 0xfc, 0xc1, 0xb6, 0xed, 0xe7, 0x8e,
+ 0xe3, 0x84, 0x00, 0xc0, 0xa4, 0x94, 0x27, 0x21, 0x22, 0x82, 0x94, 0x12,
+ 0x52, 0x4a, 0xa4, 0x69, 0x8a, 0x28, 0x8a, 0xb0, 0x58, 0x2c, 0x30, 0x1c,
+ 0x0e, 0x85, 0xeb, 0xba, 0xef, 0x6b, 0xb5, 0xda, 0x4d, 0xab, 0xd5, 0x8a,
+ 0x34, 0xc6, 0xd8, 0x29, 0x07, 0x8c, 0x31, 0x28, 0x8a, 0x02, 0x22, 0x82,
+ 0xae, 0xeb, 0x30, 0x0c, 0x03, 0xb9, 0x5c, 0x0e, 0x86, 0x61, 0xa8, 0x52,
+ 0xca, 0xa7, 0xf3, 0xf9, 0xfc, 0x67, 0xbf, 0xdf, 0x7f, 0xa5, 0xe0, 0x81,
+ 0xc5, 0x18, 0x03, 0x63, 0x0c, 0x9a, 0xa6, 0xa1, 0x50, 0x28, 0xa0, 0x52,
+ 0xa9, 0xa0, 0x5e, 0xaf, 0x6b, 0x00, 0x5e, 0xac, 0xd7, 0xeb, 0x47, 0x0f,
+ 0x86, 0x8e, 0x41, 0x55, 0x55, 0x61, 0x9a, 0x26, 0x2a, 0x95, 0x0a, 0x6c,
+ 0xdb, 0xb6, 0x82, 0x20, 0x78, 0x76, 0x36, 0xb4, 0xc7, 0xf6, 0x93, 0x55,
+ 0xab, 0x55, 0x26, 0x84, 0x78, 0xac, 0x1c, 0x5f, 0xf3, 0xb9, 0xa5, 0xeb,
+ 0x3a, 0x2c, 0xcb, 0x82, 0xae, 0xeb, 0xbb, 0x03, 0xa4, 0x69, 0xda, 0xd9,
+ 0x53, 0x29, 0x8a, 0x02, 0xd3, 0x34, 0x99, 0x61, 0x18, 0xcb, 0x8b, 0x56,
+ 0x3b, 0xc6, 0xfe, 0x4e, 0x76, 0x77, 0x15, 0x44, 0x44, 0xe0, 0x9c, 0x0b,
+ 0x22, 0xfa, 0xaa, 0x5c, 0x83, 0x48, 0x29, 0x11, 0x86, 0xe1, 0x86, 0x88,
+ 0xbe, 0x5f, 0x35, 0xd1, 0x6e, 0xb7, 0x83, 0xe7, 0x79, 0x3d, 0x55, 0x55,
+ 0x7d, 0xd0, 0x05, 0x25, 0xa5, 0x24, 0xce, 0x39, 0x4d, 0x26, 0x93, 0x45,
+ 0xb7, 0xdb, 0x7d, 0x42, 0x44, 0x50, 0x2e, 0x59, 0x49, 0x08, 0x81, 0xf5,
+ 0x7a, 0x9d, 0x4c, 0xa7, 0xd3, 0x77, 0x42, 0x88, 0x6f, 0x00, 0xa0, 0xed,
+ 0x0f, 0xb3, 0x2c, 0x3b, 0xe4, 0xe9, 0x5f, 0xf9, 0x23, 0xfa, 0x93, 0x6d,
+ 0xce, 0x39, 0x56, 0xab, 0x95, 0x18, 0x0e, 0x87, 0x9f, 0x82, 0x20, 0x78,
+ 0xdd, 0x6e, 0xb7, 0xd3, 0x7b, 0xe9, 0x27, 0xa2, 0x7b, 0x08, 0x11, 0x21,
+ 0x4d, 0x53, 0x70, 0xce, 0x11, 0xc7, 0xb1, 0x74, 0x5d, 0xd7, 0x9f, 0xcd,
+ 0x66, 0x3d, 0xce, 0xf9, 0x4b, 0xc7, 0x71, 0xee, 0x0e, 0xef, 0x70, 0x34,
+ 0x1a, 0xe1, 0x7f, 0xff, 0x51, 0x92, 0x24, 0xd8, 0x6e, 0xb7, 0x61, 0x14,
+ 0x45, 0x9f, 0x39, 0xe7, 0x6f, 0x19, 0x63, 0xb7, 0x8e, 0xe3, 0x44, 0xc7,
+ 0x7d, 0xbf, 0x07, 0x00, 0x5f, 0x77, 0x46, 0x8c, 0x30, 0x2c, 0xd8, 0x9d,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+unsigned int search_r_png_len = 612;
+
+static unsigned char close_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0xac, 0x77, 0x26, 0x00, 0x00, 0x00,
+ 0xd8, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x75, 0x51, 0xbd, 0x12, 0x46,
+ 0x40, 0x0c, 0xdc, 0x18, 0x15, 0x0a, 0x14, 0x14, 0x1a, 0x43, 0xeb, 0x35,
+ 0xbc, 0x7f, 0xa7, 0x43, 0x67, 0x06, 0x33, 0x28, 0xd0, 0xde, 0x77, 0x7b,
+ 0x23, 0x2a, 0xdf, 0x16, 0x97, 0x9f, 0xdb, 0xcb, 0x26, 0x39, 0xc1, 0x83,
+ 0x7d, 0xdf, 0xcd, 0xb2, 0x2c, 0xd8, 0xb6, 0x0d, 0xe7, 0x79, 0x22, 0x8a,
+ 0x22, 0xc4, 0x71, 0x8c, 0x3c, 0xcf, 0x91, 0xa6, 0xa9, 0x90, 0xe6, 0x8e,
+ 0x69, 0x9a, 0xcc, 0x38, 0x8e, 0xb8, 0xae, 0x4b, 0xdf, 0xbe, 0x36, 0x0c,
+ 0x43, 0x94, 0x65, 0x89, 0xa2, 0x28, 0xc4, 0x3b, 0x8e, 0xe3, 0x2f, 0x91,
+ 0x2f, 0xa8, 0xc2, 0x42, 0x56, 0xd1, 0x78, 0xf3, 0x3c, 0xbb, 0x04, 0x2f,
+ 0xda, 0xb6, 0x45, 0x55, 0x55, 0x74, 0x9d, 0x65, 0x2c, 0x22, 0xb8, 0xef,
+ 0x1b, 0xeb, 0xba, 0xc2, 0x67, 0x8f, 0x4c, 0x10, 0x7d, 0xdf, 0xa3, 0xae,
+ 0x6b, 0xe7, 0xd3, 0x32, 0x56, 0x90, 0xe7, 0x53, 0x46, 0x31, 0x0c, 0x83,
+ 0x73, 0x95, 0xa8, 0x31, 0x93, 0x9c, 0xc7, 0xe3, 0xd4, 0x0a, 0xb6, 0xa0,
+ 0x44, 0x5a, 0xc6, 0xc6, 0x18, 0x77, 0xcd, 0x41, 0xbd, 0x24, 0x49, 0x94,
+ 0xfb, 0x12, 0x59, 0x51, 0x5b, 0xd2, 0x16, 0xed, 0xfa, 0x20, 0xdc, 0x6f,
+ 0xd7, 0x75, 0x9f, 0x6b, 0xd3, 0x2a, 0x41, 0x10, 0xa0, 0x69, 0x1a, 0x57,
+ 0x59, 0x28, 0x47, 0x99, 0x2f, 0x30, 0xcf, 0x7b, 0xfb, 0x41, 0xcf, 0x1a,
+ 0x2c, 0xeb, 0xeb, 0x07, 0x29, 0x9d, 0x65, 0x19, 0x6c, 0xab, 0x6e, 0x5d,
+ 0x3f, 0x07, 0x0a, 0x79, 0x90, 0x0e, 0x11, 0x45, 0xc2, 0x00, 0x00, 0x00,
+ 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+static unsigned int close_png_len = 273;
+
+
+static unsigned char closed_png[81] =
+{
+ 0, 0, 0, 0,142, 0, 0, 0, 0,
+ 0, 0, 0, 0,142,142, 0, 0, 0,
+ 0, 0, 0, 0,142,142,142, 0, 0,
+ 0, 0, 0, 0,142,142,142,142, 0,
+ 0, 0, 0, 0,142,142,142,142,142,
+ 0, 0, 0, 0,142,142,142,142, 0,
+ 0, 0, 0, 0,142,142,142, 0, 0,
+ 0, 0, 0, 0,142,142, 0, 0, 0,
+ 0, 0, 0, 0,142, 0, 0, 0, 0
+};
+
+static unsigned char closed_a_png[81] =
+{
+ 0, 0, 0, 0,255, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255, 0, 0,
+ 0, 0, 0, 0,255,255,255,255, 0,
+ 0, 0, 0, 0,255,255,255,255,255,
+ 0, 0, 0, 0,255,255,255,255, 0,
+ 0, 0, 0, 0,255,255,255, 0, 0,
+ 0, 0, 0, 0,255,255, 0, 0, 0,
+ 0, 0, 0, 0,255, 0, 0, 0, 0
+};
+
+static unsigned char open_png[81] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 142,142,142,142,142,142,142,142,142,
+ 0,142,142,142,142,142,142,142, 0,
+ 0, 0,142,142,142,142,142, 0, 0,
+ 0, 0, 0,142,142,142, 0, 0, 0,
+ 0, 0, 0, 0,142, 0, 0, 0, 0
+};
+
+static unsigned char open_a_png[81] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 255,255,255,255,255,255,255,255,255,
+ 0,255,255,255,255,255,255,255, 0,
+ 0, 0,255,255,255,255,255, 0, 0,
+ 0, 0, 0,255,255,255, 0, 0, 0,
+ 0, 0, 0, 0,255, 0, 0, 0, 0
+};
+
+static unsigned char bdwn_png[7*8] =
+{
+ 0, 0, 0,142, 0, 0, 0,
+ 0, 0, 0,142, 0, 0, 0,
+ 0, 0, 0,142, 0, 0, 0,
+ 142, 0, 0,142, 0, 0,142,
+ 142,142, 0,142, 0,142,142,
+ 142,142,142,142,142,142,142,
+ 0,142,142,142,142,142, 0,
+ 0, 0,142,142,142, 0, 0,
+};
+
+static unsigned char bdwn_a_png[7*8] =
+{
+ 0, 0, 0,255, 0, 0, 0,
+ 0, 0, 0,255, 0, 0, 0,
+ 0, 0, 0,255, 0, 0, 0,
+ 128, 0, 0,255, 0, 0,128,
+ 255,128, 0,255, 0,128,255,
+ 128,255,128,255,128,255,128,
+ 0,128,255,255,255,128, 0,
+ 0, 0,128,255,128, 0, 0,
+};
+
+static unsigned char sync_on_png[576] =
+{
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,138,128,128,128,128,133,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,129,205,186,128,128,128,128,160,210,134,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,139,217,255,181,128,128,128,128,152,255,229,147,128,128,128,128,128,128,
+ 128,128,128,128,128,156,236,255,255,181,128,128,128,128,152,255,255,243,164,128,128,128,128,128,
+ 128,128,128,128,175,249,255,255,255,223,196,198,198,197,211,255,255,255,253,186,128,128,128,128,
+ 128,128,133,202,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,214,137,128,128,
+ 128,128,135,217,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,225,140,128,128,
+ 128,128,128,128,189,255,255,255,255,238,224,225,225,224,232,255,255,255,255,201,131,128,128,128,
+ 128,128,128,128,128,167,245,255,255,183,128,128,128,128,155,255,255,250,179,128,128,128,128,128,
+ 128,128,128,128,128,128,150,231,255,188,128,128,128,128,161,255,238,158,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,136,216,188,128,128,128,128,161,223,142,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,130,141,128,128,128,128,135,132,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
+};
+
+static unsigned char sync_off_png[576] =
+{
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,138,128,128,128,128,128,128,133,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,129,205,186,128,128,128,128,128,128,160,210,134,128,128,128,128,128,128,
+ 128,128,128,128,128,139,217,255,181,128,128,128,128,128,128,152,255,229,147,128,128,128,128,128,
+ 128,128,128,128,156,236,255,255,181,128,128,128,128,128,128,152,255,255,243,164,128,128,128,128,
+ 128,128,128,175,249,255,255,255,223,196,198,198,128,128,197,211,255,255,255,253,186,128,128,128,
+ 128,128,202,255,255,255,255,255,255,255,255,225,128,128,255,255,255,255,255,255,255,214,128,128,
+ 128,128,217,255,255,255,255,255,255,255,255,128,128,198,255,255,255,255,255,255,255,225,128,128,
+ 128,128,128,189,255,255,255,255,238,224,225,128,128,225,224,232,255,255,255,255,201,128,128,128,
+ 128,128,128,128,167,245,255,255,183,128,128,128,128,128,128,155,255,255,250,179,128,128,128,128,
+ 128,128,128,128,128,150,231,255,188,128,128,128,128,128,128,161,255,238,158,128,128,128,128,128,
+ 128,128,128,128,128,128,136,216,188,128,128,128,128,128,128,161,223,142,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,130,141,128,128,128,128,128,128,135,132,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
+};
+
+static unsigned char sync_a_png[576] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 29, 98,157,207,231,234,211,164,104, 38, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 21,143,234,255,255,255,255,255,255,255,255,244,155, 33, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 70,221,255,255,255,255,255,255,255,255,255,255,255,255,235, 93, 0, 0, 0, 0,
+ 0, 0, 0, 92,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,116, 0, 0, 0,
+ 0, 0, 68,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 96, 0, 0,
+ 0, 20,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243, 41, 0,
+ 0,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172, 1,
+ 28,238,255,255,255,255,255,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 42,
+ 99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,133,
+ 160,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,204,
+ 212,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,224,
+ 234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,237,255,236,
+ 235,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,230,255,236,
+ 216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,226,
+ 168,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,208,
+ 107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,147,
+ 39,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 53,
+ 0,159,255,255,255,255,255,255,251,255,255,255,255,255,255,255,255,255,255,255,255,255,190, 3,
+ 0, 31,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,249, 54, 0,
+ 0, 0, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,119, 0, 0,
+ 0, 0, 0,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145, 0, 0, 0,
+ 0, 0, 0, 0, 98,240,255,255,255,255,255,255,255,255,255,255,255,255,248,119, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 45,168,252,255,255,255,255,255,255,255,255,255,184, 58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 45,131,201,222,234,236,224,204,142, 54, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+//------------------------------------------------------------------------
+
+static const char tabs_css[] =
+".tabs, .tabs2, .tabs3 {\n"
+" background-image: url('tab_b.png');\n"
+" width: 100%;\n"
+" z-index: 101;\n"
+" font-size: 13px;\n"
+" font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n"
+"}\n"
+"\n"
+".tabs2 {\n"
+" font-size: 10px;\n"
+"}\n"
+".tabs3 {\n"
+" font-size: 9px;\n"
+"}\n"
+"\n"
+".tablist {\n"
+" margin: 0;\n"
+" padding: 0;\n"
+" display: table;\n"
+"}\n"
+"\n"
+".tablist li {\n"
+" float: left;\n"
+" display: table-cell;\n"
+" background-image: url('tab_b.png');\n"
+" line-height: 36px;\n"
+" list-style: none;\n"
+"}\n"
+"\n"
+".tablist a {\n"
+" display: block;\n"
+" padding: 0 20px;\n"
+" font-weight: bold;\n"
+" background-image:url('tab_s.png');\n"
+" background-repeat:no-repeat;\n"
+" background-position:right;\n"
+" color: ##30;\n"
+" text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n"
+" text-decoration: none;\n"
+" outline: none;\n"
+"}\n"
+"\n"
+".tabs3 .tablist a {\n"
+" padding: 0 10px;\n"
+"}\n"
+"\n"
+".tablist a:hover {\n"
+" background-image: url('tab_h.png');\n"
+" background-repeat:repeat-x;\n"
+" color: #fff;\n"
+" text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
+" text-decoration: none;\n"
+"}\n"
+"\n"
+".tablist li.current a {\n"
+" background-image: url('tab_a.png');\n"
+" background-repeat:repeat-x;\n"
+" color: #fff;\n"
+" text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
+"}\n"
+;
+
+struct img_data_item
+{
+ const char *name;
+ unsigned char *content;
+ unsigned int len;
+};
+
+
+static void writeImgData(const char *dir,img_data_item *data)
+{
+ while (data->name)
+ {
+ QCString fileName;
+ fileName=(QCString)dir+"/"+data->name;
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ f.writeBlock((char*)data->content,
+ data->len>0 ? data->len : qstrlen((char*)data->content));
+ }
+ else
+ {
+ fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
+ }
+ Doxygen::indexList->addImageFile(QCString("/search/")+data->name);
+ data++;
+ }
+}
+
+static ColoredImgDataItem colored_tab_data[] =
+{
+ // file_name W H luma_data alpha_data
+ { "tab_a.png", 1, 36, tab_a_png, 0 },
+ { "tab_b.png", 1, 36, tab_b_png, 0 },
+ { "tab_h.png", 1, 36, tab_h_png, 0 },
+ { "tab_s.png", 1, 36, tab_s_png, 0 },
+ { "nav_h.png", 1, 12, header_png, 0 },
+ { "nav_f.png", 1, 56, func_header_png, 0 },
+ { "bc_s.png", 8, 30, bc_s_png, bc_s_a_png },
+ { "doxygen.png", 104,31, doxygen_png, doxygen_a_png },
+ { "closed.png", 9, 9, closed_png, closed_a_png },
+ { "open.png", 9, 9, open_png, open_a_png },
+ { "bdwn.png", 7, 8, bdwn_png, bdwn_a_png },
+ { "sync_on.png", 24, 24, sync_on_png, sync_a_png },
+ { "sync_off.png",24, 24, sync_off_png, sync_a_png },
+ { 0, 0, 0, 0, 0 }
+};
+
+static img_data_item search_client_data[] =
+{
+ // file_name raw_data num bytes
+ { "mag_sel.png", mag_sel_png, mag_sel_png_len },
+ { "search_l.png", search_l_png, search_l_png_len },
+ { "search_m.png", search_m_png, search_m_png_len },
+ { "search_r.png", search_r_png, search_r_png_len },
+ { "close.png", close_png, close_png_len },
+ { 0, 0, 0 }
+};
+
+static img_data_item search_server_data[] =
+{
+ // file_name raw_data num bytes
+ { "mag.png", mag_png, mag_png_len },
+ { "search_l.png", search_l_png, search_l_png_len },
+ { "search_m.png", search_m_png, search_m_png_len },
+ { "search_r.png", search_r_png, search_r_png_len },
+ { 0, 0, 0 }
+};
+
+//------------------------------------------------------------------------
+
+static void writeClientSearchBox(FTextStream &t,const char *relPath)
+{
+ t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
+ t << " <span class=\"left\">\n";
+ t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
+ t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
+ t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
+ t << " alt=\"\"/>\n";
+ t << " <input type=\"text\" id=\"MSearchField\" value=\""
+ << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
+ t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
+ t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
+ t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
+ t << " </span><span class=\"right\">\n";
+ t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
+ << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
+ t << " </span>\n";
+ t << " </div>\n";
+}
+
+static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
+{
+ static bool externalSearch = Config_getBool("EXTERNAL_SEARCH");
+ t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
+ t << " <div class=\"left\">\n";
+ t << " <form id=\"FSearchBox\" action=\"" << relPath;
+ if (externalSearch)
+ {
+ t << "search" << Doxygen::htmlFileExtension;
+ }
+ else
+ {
+ t << "search.php";
+ }
+ t << "\" method=\"get\">\n";
+ t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
+ if (!highlightSearch)
+ {
+ t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
+ << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
+ t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
+ t << " onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
+ t << " </form>\n";
+ t << " </div><div class=\"right\"></div>\n";
+ t << " </div>\n";
+ }
+}
+
+//------------------------------------------------------------------------
+
+/// substitute all occurrences of \a src in \a s by \a dst
+QCString substitute(const char *s,const char *src,const char *dst)
+{
+ if (s==0 || src==0) return s;
+ const char *p, *q;
+ int srcLen = qstrlen(src);
+ int dstLen = dst ? qstrlen(dst) : 0;
+ int resLen;
+ if (srcLen!=dstLen)
+ {
+ int count;
+ for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
+ resLen = (int)(p-s)+qstrlen(p)+count*(dstLen-srcLen);
+ }
+ else // result has same size as s
+ {
+ resLen = qstrlen(s);
+ }
+ QCString result(resLen+1);
+ char *r;
+ for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
+ {
+ int l = (int)(q-p);
+ memcpy(r,p,l);
+ r+=l;
+ if (dst) memcpy(r,dst,dstLen);
+ r+=dstLen;
+ }
+ qstrcpy(r,p);
+ //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
+ return result;
+}
+//----------------------------------------------------------------------
+
+/// Clear a text block \a s from \a begin to \a end markers
+QCString clearBlock(const char *s,const char *begin,const char *end)
+{
+ if (s==0 || begin==0 || end==0) return s;
+ const char *p, *q;
+ int beginLen = qstrlen(begin);
+ int endLen = qstrlen(end);
+ int resLen = 0;
+ for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
+ {
+ resLen+=(int)(q-p);
+ p=q+beginLen;
+ if ((q=strstr(p,end))==0)
+ {
+ resLen+=beginLen;
+ break;
+ }
+ }
+ resLen+=qstrlen(p);
+ // resLen is the length of the string without the marked block
+
+ QCString result(resLen+1);
+ char *r;
+ for (r=result.data(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
+ {
+ int l = (int)(q-p);
+ memcpy(r,p,l);
+ r+=l;
+ p=q+beginLen;
+ if ((q=strstr(p,end))==0)
+ {
+ memcpy(r,begin,beginLen);
+ r+=beginLen;
+ break;
+ }
+ }
+ qstrcpy(r,p);
+ return result;
+}
+//----------------------------------------------------------------------
+
+QCString selectBlock(const QCString& s,const QCString &name,bool enable)
+{
+ const QCString begin = "<!--BEGIN " + name + "-->";
+ const QCString end = "<!--END " + name + "-->";
+ const QCString nobegin = "<!--BEGIN !" + name + "-->";
+ const QCString noend = "<!--END !" + name + "-->";
+
+ QCString result = s;
+ if (enable)
+ {
+ result = substitute(result, begin, "");
+ result = substitute(result, end, "");
+ result = clearBlock(result, nobegin, noend);
+ }
+ else
+ {
+ result = substitute(result, nobegin, "");
+ result = substitute(result, noend, "");
+ result = clearBlock(result, begin, end);
+ }
+
+ return result;
+}
+
+static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
+{
+ QGString result;
+ FTextStream t(&result);
+ if (serverSide) {
+ writeServerSearchBox(t, relPath, highlightSearch);
+ }
+ else {
+ writeClientSearchBox(t, relPath);
+ }
+ return QCString(result);
+}
+
+static QCString removeEmptyLines(const QCString &s)
+{
+ BufStr out(s.length()+1);
+ char *p=s.data();
+ if (p)
+ {
+ char c;
+ while ((c=*p++))
+ {
+ if (c=='\n')
+ {
+ char *e = p;
+ while (*e==' ' || *e=='\t') e++;
+ if (*e=='\n')
+ {
+ p=e;
+ }
+ else out.addChar(c);
+ }
+ else
+ {
+ out.addChar(c);
+ }
+ }
+ }
+ out.addChar('\0');
+ //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
+ return out.data();
+}
+
+static QCString substituteHtmlKeywords(const QCString &s,
+ const QCString &title,
+ const QCString &relPath,
+ const QCString &navPath=QCString())
+{
+ // Build CSS/Javascript tags depending on treeview, search engine settings
+ QCString cssFile;
+ QStrList extraCssFile;
+ QCString generatedBy;
+ QCString treeViewCssJs;
+ QCString searchCssJs;
+ QCString searchBox;
+ QCString mathJaxJs;
+ QCString extraCssText;
+
+ static QCString projectName = Config_getString("PROJECT_NAME");
+ static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
+ static bool treeView = Config_getBool("GENERATE_TREEVIEW");
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+ static bool mathJax = Config_getBool("USE_MATHJAX");
+ static QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT");
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+ static bool hasProjectName = !projectName.isEmpty();
+ static bool hasProjectNumber = !Config_getString("PROJECT_NUMBER").isEmpty();
+ static bool hasProjectBrief = !Config_getString("PROJECT_BRIEF").isEmpty();
+ static bool hasProjectLogo = !Config_getString("PROJECT_LOGO").isEmpty();
+ static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
+
+ cssFile = Config_getString("HTML_STYLESHEET");
+ if (cssFile.isEmpty())
+ {
+ cssFile = "doxygen.css";
+ }
+ else
+ {
+ QFileInfo cssfi(cssFile);
+ if (cssfi.exists())
+ {
+ cssFile = cssfi.fileName().utf8();
+ }
+ else
+ {
+ cssFile = "doxygen.css";
+ }
+ }
+
+ extraCssText = "";
+ extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
+ for (uint i=0; i<extraCssFile.count(); ++i)
+ {
+ QCString fileName(extraCssFile.at(i));
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fi(fileName);
+ if (fi.exists())
+ {
+ extraCssText += "<link href=\"$relpath^"+stripPath(fileName)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
+ }
+ }
+ }
+
+ if (timeStamp)
+ {
+ generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString("PROJECT_NAME")));
+ }
+ else
+ {
+ generatedBy = theTranslator->trGeneratedBy();
+ }
+
+ if (treeView)
+ {
+ treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
+ "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
+ "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
+ "<script type=\"text/javascript\">\n"
+ " $(document).ready(initResizable);\n"
+ " $(window).load(resizeHeight);\n"
+ "</script>";
+ }
+
+ if (searchEngine)
+ {
+ searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
+ searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
+
+ if (!serverBasedSearch)
+ {
+ searchCssJs += "<script type=\"text/javascript\">\n"
+ " $(document).ready(function() { searchBox.OnSelectItem(0); });\n"
+ "</script>";
+ }
+ else
+ {
+ searchCssJs += "<script type=\"text/javascript\">\n"
+ " $(document).ready(function() {\n"
+ " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
+ " });\n"
+ "</script>\n";
+
+ // OPENSEARCH_PROVIDER {
+ searchCssJs += "<link rel=\"search\" href=\"" + relPath +
+ "search-opensearch.php?v=opensearch.xml\" "
+ "type=\"application/opensearchdescription+xml\" title=\"" +
+ (hasProjectName ? projectName : QCString("Doxygen")) +
+ "\"/>";
+ // OPENSEARCH_PROVIDER }
+ }
+ searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
+ }
+
+ if (mathJax)
+ {
+ QCString path = Config_getString("MATHJAX_RELPATH");
+ if (!path.isEmpty() && path.at(path.length()-1)!='/')
+ {
+ path+="/";
+ }
+ if (path.isEmpty() || path.left(2)=="..") // relative path
+ {
+ path.prepend(relPath);
+ }
+ mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
+ " MathJax.Hub.Config({\n"
+ " extensions: [\"tex2jax.js\"";
+ QStrList &mathJaxExtensions = Config_getList("MATHJAX_EXTENSIONS");
+ const char *s = mathJaxExtensions.first();
+ while (s)
+ {
+ mathJaxJs+= ", \""+QCString(s)+".js\"";
+ s = mathJaxExtensions.next();
+ }
+ if (mathJaxFormat.isEmpty())
+ {
+ mathJaxFormat = "HTML-CSS";
+ }
+ mathJaxJs += "],\n"
+ " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
+ "});\n";
+ if (!g_mathjax_code.isEmpty())
+ {
+ mathJaxJs += g_mathjax_code;
+ mathJaxJs += "\n";
+ }
+ mathJaxJs += "</script>";
+ mathJaxJs += "<script src=\"" + path + "MathJax.js\"></script>\n";
+ }
+
+ // first substitute generic keywords
+ QCString result = substituteKeywords(s,title,
+ convertToHtml(Config_getString("PROJECT_NAME")),
+ convertToHtml(Config_getString("PROJECT_NUMBER")),
+ convertToHtml(Config_getString("PROJECT_BRIEF")));
+
+ // additional HTML only keywords
+ result = substitute(result,"$navpath",navPath);
+ result = substitute(result,"$stylesheet",cssFile);
+ result = substitute(result,"$treeview",treeViewCssJs);
+ result = substitute(result,"$searchbox",searchBox);
+ result = substitute(result,"$search",searchCssJs);
+ result = substitute(result,"$mathjax",mathJaxJs);
+ result = substitute(result,"$generatedby",generatedBy);
+ result = substitute(result,"$extrastylesheet",extraCssText);
+ result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
+ result = substitute(result,"$relpath^",relPath); //<-- must be last
+
+ // additional HTML only conditional blocks
+ result = selectBlock(result,"DISABLE_INDEX",disableIndex);
+ result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
+ result = selectBlock(result,"SEARCHENGINE",searchEngine);
+ result = selectBlock(result,"TITLEAREA",titleArea);
+ result = selectBlock(result,"PROJECT_NAME",hasProjectName);
+ result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
+ result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
+ result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);
+
+ result = removeEmptyLines(result);
+
+ return result;
+}
+
+//--------------------------------------------------------------------------
+
+HtmlCodeGenerator::HtmlCodeGenerator()
+ : m_streamSet(FALSE), m_col(0)
+{
+}
+
+HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath)
+ : m_col(0), m_relPath(relPath)
+{
+ setTextStream(t);
+}
+
+void HtmlCodeGenerator::setTextStream(FTextStream &t)
+{
+ m_streamSet = t.device()!=0;
+ m_t.setDevice(t.device());
+}
+
+void HtmlCodeGenerator::setRelativePath(const QCString &path)
+{
+ m_relPath = path;
+}
+
+void HtmlCodeGenerator::codify(const char *str)
+{
+ static int tabSize = Config_getInt("TAB_SIZE");
+ if (str && m_streamSet)
+ {
+ const char *p=str;
+ char c;
+ int spacesToNextTabStop;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '\t': spacesToNextTabStop =
+ tabSize - (m_col%tabSize);
+ m_t << Doxygen::spaces.left(spacesToNextTabStop);
+ m_col+=spacesToNextTabStop;
+ break;
+ case '\n': m_t << "\n"; m_col=0;
+ break;
+ case '\r': break;
+ case '<': m_t << "<"; m_col++;
+ break;
+ case '>': m_t << ">"; m_col++;
+ break;
+ case '&': m_t << "&"; m_col++;
+ break;
+ case '\'': m_t << "'"; m_col++; // ' is not valid XHTML
+ break;
+ case '"': m_t << """; m_col++;
+ break;
+ case '\\':
+ if (*p=='<')
+ { m_t << "<"; p++; }
+ else if (*p=='>')
+ { m_t << ">"; p++; }
+ else
+ m_t << "\\";
+ m_col++;
+ break;
+ default: p=writeUtf8Char(m_t,p-1);
+ m_col++;
+ break;
+ }
+ }
+ }
+}
+
+void HtmlCodeGenerator::docify(const char *str)
+{
+ if (str && m_streamSet)
+ {
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '<': m_t << "<"; break;
+ case '>': m_t << ">"; break;
+ case '&': m_t << "&"; break;
+ case '"': m_t << """; break;
+ case '\\':
+ if (*p=='<')
+ { m_t << "<"; p++; }
+ else if (*p=='>')
+ { m_t << ">"; p++; }
+ else
+ m_t << "\\";
+ break;
+ default: m_t << c;
+ }
+ }
+ }
+}
+
+void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
+ const char *anchor,int l)
+{
+ if (!m_streamSet) return;
+ QCString lineNumber,lineAnchor;
+ lineNumber.sprintf("%5d",l);
+ lineAnchor.sprintf("l%05d",l);
+
+ m_t << "<div class=\"line\">";
+ m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">";
+ if (filename)
+ {
+ _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
+ }
+ else
+ {
+ codify(lineNumber);
+ }
+ m_t << "</span>";
+ m_t << " ";
+}
+
+void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
+ const char *anchor, const char *name,
+ const char *tooltip)
+{
+ if (!m_streamSet) return;
+ //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
+ _writeCodeLink("code",ref,f,anchor,name,tooltip);
+}
+
+void HtmlCodeGenerator::_writeCodeLink(const char *className,
+ const char *ref,const char *f,
+ const char *anchor, const char *name,
+ const char *tooltip)
+{
+ if (ref)
+ {
+ m_t << "<a class=\"" << className << "Ref\" ";
+ m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
+ }
+ else
+ {
+ m_t << "<a class=\"" << className << "\" ";
+ }
+ m_t << "href=\"";
+ m_t << externalRef(m_relPath,ref,TRUE);
+ if (f) m_t << f << Doxygen::htmlFileExtension;
+ if (anchor) m_t << "#" << anchor;
+ m_t << "\"";
+ if (tooltip) m_t << " title=\"" << tooltip << "\"";
+ m_t << ">";
+ docify(name);
+ m_t << "</a>";
+ m_col+=qstrlen(name);
+}
+
+void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
+ const char *decl, const char *desc,
+ const SourceLinkInfo &defInfo,
+ const SourceLinkInfo &declInfo)
+{
+ m_t << "<div class=\"ttc\" id=\"" << id << "\">";
+ m_t << "<div class=\"ttname\">";
+ if (!docInfo.url.isEmpty())
+ {
+ m_t << "<a href=\"";
+ m_t << externalRef(m_relPath,docInfo.ref,TRUE);
+ m_t << docInfo.url << Doxygen::htmlFileExtension;
+ if (!docInfo.anchor.isEmpty())
+ {
+ m_t << "#" << docInfo.anchor;
+ }
+ m_t << "\">";
+ }
+ docify(docInfo.name);
+ if (!docInfo.url.isEmpty())
+ {
+ m_t << "</a>";
+ }
+ m_t << "</div>";
+ if (decl)
+ {
+ m_t << "<div class=\"ttdeci\">";
+ docify(decl);
+ m_t << "</div>";
+ }
+ if (desc)
+ {
+ m_t << "<div class=\"ttdoc\">";
+ m_t << desc; // desc is already HTML escaped
+ m_t << "</div>";
+ }
+ if (!defInfo.file.isEmpty())
+ {
+ m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
+ if (!defInfo.url.isEmpty())
+ {
+ m_t << "<a href=\"";
+ m_t << externalRef(m_relPath,defInfo.ref,TRUE);
+ m_t << defInfo.url << Doxygen::htmlFileExtension;
+ if (!defInfo.anchor.isEmpty())
+ {
+ m_t << "#" << defInfo.anchor;
+ }
+ m_t << "\">";
+ }
+ m_t << defInfo.file << ":" << defInfo.line;
+ if (!defInfo.url.isEmpty())
+ {
+ m_t << "</a>";
+ }
+ m_t << "</div>";
+ }
+ if (!declInfo.file.isEmpty())
+ {
+ m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
+ if (!declInfo.url.isEmpty())
+ {
+ m_t << "<a href=\"";
+ m_t << externalRef(m_relPath,declInfo.ref,TRUE);
+ m_t << declInfo.url << Doxygen::htmlFileExtension;
+ if (!declInfo.anchor.isEmpty())
+ {
+ m_t << "#" << declInfo.anchor;
+ }
+ m_t << "\">";
+ }
+ m_t << declInfo.file << ":" << declInfo.line;
+ if (!declInfo.url.isEmpty())
+ {
+ m_t << "</a>";
+ }
+ m_t << "</div>";
+ }
+ m_t << "</div>" << endl;
+}
+
+
+void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers)
+{
+ if (m_streamSet)
+ {
+ if (!hasLineNumbers) m_t << "<div class=\"line\">";
+ m_col=0;
+ }
+}
+
+void HtmlCodeGenerator::endCodeLine()
+{
+ if (m_streamSet) m_t << "</div>\n";
+}
+
+void HtmlCodeGenerator::startFontClass(const char *s)
+{
+ if (m_streamSet) m_t << "<span class=\"" << s << "\">";
+}
+
+void HtmlCodeGenerator::endFontClass()
+{
+ if (m_streamSet) m_t << "</span>";
+}
+
+void HtmlCodeGenerator::writeCodeAnchor(const char *anchor)
+{
+ if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>";
+}
+
+//--------------------------------------------------------------------------
+
+HtmlGenerator::HtmlGenerator() : OutputGenerator()
+{
+ dir=Config_getString("HTML_OUTPUT");
+ m_emptySection=FALSE;
+}
+
+HtmlGenerator::~HtmlGenerator()
+{
+ //printf("HtmlGenerator::~HtmlGenerator()\n");
+}
+
+void HtmlGenerator::init()
+{
+ QCString dname=Config_getString("HTML_OUTPUT");
+ QDir d(dname);
+ if (!d.exists() && !d.mkdir(dname))
+ {
+ err("Could not create output directory %s\n",dname.data());
+ exit(1);
+ }
+ //writeLogo(dname);
+ if (!Config_getString("HTML_HEADER").isEmpty())
+ {
+ g_header=fileToString(Config_getString("HTML_HEADER"));
+ //printf("g_header='%s'\n",g_header.data());
+ }
+ else
+ {
+ g_header = defaultHtmlHeader;
+ }
+
+ if (!Config_getString("HTML_FOOTER").isEmpty())
+ {
+ g_footer=fileToString(Config_getString("HTML_FOOTER"));
+ //printf("g_footer='%s'\n",g_footer.data());
+ }
+ else
+ {
+ g_footer = defaultHtmlFooter;
+ }
+
+ if (Config_getBool("USE_MATHJAX"))
+ {
+ if (!Config_getString("MATHJAX_CODEFILE").isEmpty())
+ {
+ g_mathjax_code=fileToString(Config_getString("MATHJAX_CODEFILE"));
+ //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
+ }
+ }
+ createSubDirs(d);
+
+ QCString fileName=dname+"/tabs.css";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << replaceColorMarkers(tabs_css);
+ }
+ else
+ {
+ fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
+ }
+
+ {
+ QFile f(dname+"/jquery.js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << search_jquery_script1 << search_jquery_script2 << search_jquery_script3;
+ if (Config_getBool("GENERATE_TREEVIEW"))
+ {
+ t << search_jquery_script4 << search_jquery_script5;
+ }
+ if (Config_getBool("SOURCE_BROWSER"))
+ {
+ t << search_jquery_script6;
+ }
+ }
+ }
+
+ if (Config_getBool("INTERACTIVE_SVG"))
+ {
+ QFile f(dname+"/svgpan.js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << svgpan_script;
+ }
+ }
+
+ {
+ QFile f(dname+"/dynsections.js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << dynsections_script;
+ if (Config_getBool("SOURCE_BROWSER") && Config_getBool("SOURCE_TOOLTIPS"))
+ {
+ t << endl <<
+ "$(document).ready(function() {\n"
+ " $('.code,.codeRef').each(function() {\n"
+ " $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
+ " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
+ " });\n"
+ "});\n";
+ }
+ }
+ }
+}
+
+/// Additional initialization after indices have been created
+void HtmlGenerator::writeTabData()
+{
+ Doxygen::indexList->addStyleSheetFile("tabs.css");
+ QCString dname=Config_getString("HTML_OUTPUT");
+ writeColoredImgData(dname,colored_tab_data);
+
+ {
+ unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
+ unsigned char shadow_alpha[6] = { 80, 60, 40, 20, 10, 0 };
+ ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
+ img.save(dname+"/nav_g.png");
+ }
+}
+
+void HtmlGenerator::writeSearchData(const char *dir)
+{
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+ writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
+ QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
+ QFile f(searchDirName+"/search.css");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ QCString searchCss = replaceColorMarkers(search_styleSheet);
+ searchCss = substitute(searchCss,"$doxygenversion",versionString);
+ if (Config_getBool("DISABLE_INDEX"))
+ {
+ // move up the search box if there are no tabs
+ searchCss = substitute(searchCss,"margin-top: 8px;","margin-top: 0px;");
+ }
+ t << searchCss;
+ }
+ Doxygen::indexList->addStyleSheetFile("search/search.css");
+}
+
+void HtmlGenerator::writeStyleSheetFile(QFile &file)
+{
+ FTextStream t(&file);
+ t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
+}
+
+void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
+{
+ FTextStream t(&file);
+ t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
+ QCString contents(defaultHtmlHeader);
+ t << contents;
+}
+
+void HtmlGenerator::writeFooterFile(QFile &file)
+{
+ FTextStream t(&file);
+ t << "<!-- HTML footer for doxygen " << versionString << "-->" << endl;
+ QCString contents(defaultHtmlFooter);
+ t << contents;
+}
+
+void HtmlGenerator::startFile(const char *name,const char *,
+ const char *title)
+{
+ //printf("HtmlGenerator::startFile(%s)\n",name);
+ QCString fileName=name;
+ lastTitle=title;
+ relPath = relativePathToRoot(fileName);
+
+ if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension)
+ {
+ fileName+=Doxygen::htmlFileExtension;
+ }
+ startPlainFile(fileName);
+ m_codeGen.setTextStream(t);
+ m_codeGen.setRelativePath(relPath);
+ Doxygen::indexList->addIndexFile(fileName);
+
+ lastFile = fileName;
+ t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);
+
+ t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
+ << versionString << " -->" << endl;
+ //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ if (searchEngine /*&& !generateTreeView*/)
+ {
+ t << "<script type=\"text/javascript\">\n";
+ t << "var searchBox = new SearchBox(\"searchBox\", \""
+ << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
+ t << "</script>\n";
+ }
+ //generateDynamicSections(t,relPath);
+ m_sectionCount=0;
+}
+
+void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
+{
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+ if (searchEngine && !serverBasedSearch)
+ {
+ (void)relPath;
+ t << "<!-- window showing the filter options -->\n";
+ t << "<div id=\"MSearchSelectWindow\"\n";
+ t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
+ t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
+ t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
+ writeSearchCategories(t);
+ t << "</div>\n";
+ t << "\n";
+ t << "<!-- iframe showing the search results (closed by default) -->\n";
+ t << "<div id=\"MSearchResultsWindow\">\n";
+ t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
+ t << " name=\"MSearchResults\" id=\"MSearchResults\">\n";
+ t << "</iframe>\n";
+ t << "</div>\n";
+ t << "\n";
+ }
+}
+
+void HtmlGenerator::writeSearchInfo()
+{
+ writeSearchInfo(t,relPath);
+}
+
+
+QCString HtmlGenerator::writeLogoAsString(const char *path)
+{
+ static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
+ QCString result;
+ if (timeStamp)
+ {
+ result += theTranslator->trGeneratedAt(
+ dateToString(TRUE),
+ Config_getString("PROJECT_NAME")
+ );
+ }
+ else
+ {
+ result += theTranslator->trGeneratedBy();
+ }
+ result += " \n<a href=\"http://www.doxygen.org/index.html\">\n"
+ "<img class=\"footer\" src=\"";
+ result += path;
+ result += "doxygen.png\" alt=\"doxygen\"/></a> ";
+ result += versionString;
+ result += " ";
+ return result;
+}
+
+void HtmlGenerator::writeLogo()
+{
+ t << writeLogoAsString(relPath);
+}
+
+void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
+ const QCString &relPath,const QCString &navPath)
+{
+ t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
+}
+
+void HtmlGenerator::writeFooter(const char *navPath)
+{
+ writePageFooter(t,lastTitle,relPath,navPath);
+}
+
+void HtmlGenerator::endFile()
+{
+ endPlainFile();
+}
+
+void HtmlGenerator::startProjectNumber()
+{
+ t << "<h3 class=\"version\">";
+}
+
+void HtmlGenerator::endProjectNumber()
+{
+ t << "</h3>";
+}
+
+void HtmlGenerator::writeStyleInfo(int part)
+{
+ //printf("writeStyleInfo(%d)\n",part);
+ if (part==0)
+ {
+ if (Config_getString("HTML_STYLESHEET").isEmpty()) // write default style sheet
+ {
+ //printf("write doxygen.css\n");
+ startPlainFile("doxygen.css");
+
+ // alternative, cooler looking titles
+ //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
+ //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;
+
+ t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
+ endPlainFile();
+ Doxygen::indexList->addStyleSheetFile("doxygen.css");
+ }
+ else // write user defined style sheet
+ {
+ QCString cssname=Config_getString("HTML_STYLESHEET");
+ QFileInfo cssfi(cssname);
+ if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
+ {
+ err("style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data());
+ }
+ else
+ {
+ // convert style sheet to string
+ QCString fileStr = fileToString(cssname);
+ // write the string into the output dir
+ startPlainFile(cssfi.fileName().utf8());
+ t << fileStr;
+ endPlainFile();
+ }
+ Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
+ }
+ static QStrList extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
+ for (uint i=0; i<extraCssFile.count(); ++i)
+ {
+ QCString fileName(extraCssFile.at(i));
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fi(fileName);
+ if (fi.exists())
+ {
+ Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
+ }
+ }
+ }
+ }
+}
+
+void HtmlGenerator::startDoxyAnchor(const char *,const char *,
+ const char *anchor, const char *,
+ const char *)
+{
+ t << "<a class=\"anchor\" id=\"" << anchor << "\"></a>";
+}
+
+void HtmlGenerator::endDoxyAnchor(const char *,const char *)
+{
+}
+
+//void HtmlGenerator::newParagraph()
+//{
+// t << endl << "<p>" << endl;
+//}
+
+void HtmlGenerator::startParagraph()
+{
+ t << endl << "<p>";
+}
+
+void HtmlGenerator::endParagraph()
+{
+ t << "</p>" << endl;
+}
+
+void HtmlGenerator::writeString(const char *text)
+{
+ t << text;
+}
+
+void HtmlGenerator::startIndexListItem()
+{
+ t << "<li>";
+}
+
+void HtmlGenerator::endIndexListItem()
+{
+ t << "</li>" << endl;
+}
+
+void HtmlGenerator::startIndexItem(const char *ref,const char *f)
+{
+ //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
+ if (ref || f)
+ {
+ if (ref)
+ {
+ t << "<a class=\"elRef\" ";
+ t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
+ }
+ else
+ {
+ t << "<a class=\"el\" ";
+ }
+ t << "href=\"";
+ t << externalRef(relPath,ref,TRUE);
+ if (f) t << f << Doxygen::htmlFileExtension << "\">";
+ }
+ else
+ {
+ t << "<b>";
+ }
+}
+
+void HtmlGenerator::endIndexItem(const char *ref,const char *f)
+{
+ //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
+ if (ref || f)
+ {
+ t << "</a>";
+ }
+ else
+ {
+ t << "</b>";
+ }
+}
+
+void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
+ const char *path,const char *name)
+{
+ t << "<li>";
+ if (path) docify(path);
+ t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
+ docify(name);
+ t << "</a> ";
+}
+
+void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
+ const char *anchor, const char *name)
+{
+ if (ref)
+ {
+ t << "<a class=\"elRef\" ";
+ t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
+ }
+ else
+ {
+ t << "<a class=\"el\" ";
+ }
+ t << "href=\"";
+ t << externalRef(relPath,ref,TRUE);
+ if (f) t << f << Doxygen::htmlFileExtension;
+ if (anchor) t << "#" << anchor;
+ t << "\">";
+ docify(name);
+ t << "</a>";
+}
+
+void HtmlGenerator::startTextLink(const char *f,const char *anchor)
+{
+ t << "<a href=\"";
+ if (f) t << relPath << f << Doxygen::htmlFileExtension;
+ if (anchor) t << "#" << anchor;
+ t << "\">";
+}
+
+void HtmlGenerator::endTextLink()
+{
+ t << "</a>";
+}
+
+void HtmlGenerator::startHtmlLink(const char *url)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ t << "<a ";
+ if (generateTreeView) t << "target=\"top\" ";
+ t << "href=\"";
+ if (url) t << url;
+ t << "\">";
+}
+
+void HtmlGenerator::endHtmlLink()
+{
+ t << "</a>";
+}
+
+void HtmlGenerator::startGroupHeader(int extraIndentLevel)
+{
+ if (extraIndentLevel==2)
+ {
+ t << "<h4 class=\"groupheader\">";
+ }
+ else if (extraIndentLevel==1)
+ {
+ t << "<h3 class=\"groupheader\">";
+ }
+ else // extraIndentLevel==0
+ {
+ t << "<h2 class=\"groupheader\">";
+ }
+}
+
+void HtmlGenerator::endGroupHeader(int extraIndentLevel)
+{
+ if (extraIndentLevel==2)
+ {
+ t << "</h4>" << endl;
+ }
+ else if (extraIndentLevel==1)
+ {
+ t << "</h3>" << endl;
+ }
+ else
+ {
+ t << "</h2>" << endl;
+ }
+}
+
+void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
+{
+ switch(type)
+ {
+ case SectionInfo::Page: t << "\n\n<h1>"; break;
+ case SectionInfo::Section: t << "\n\n<h2>"; break;
+ case SectionInfo::Subsection: t << "\n\n<h3>"; break;
+ case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
+ case SectionInfo::Paragraph: t << "\n\n<h5>"; break;
+ default: ASSERT(0); break;
+ }
+ t << "<a class=\"anchor\" id=\"" << lab << "\"></a>";
+}
+
+void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
+{
+ switch(type)
+ {
+ case SectionInfo::Page: t << "</h1>"; break;
+ case SectionInfo::Section: t << "</h2>"; break;
+ case SectionInfo::Subsection: t << "</h3>"; break;
+ case SectionInfo::Subsubsection: t << "</h4>"; break;
+ case SectionInfo::Paragraph: t << "</h5>"; break;
+ default: ASSERT(0); break;
+ }
+}
+
+void HtmlGenerator::docify(const char *str)
+{
+ docify(str,FALSE);
+}
+
+void HtmlGenerator::docify(const char *str,bool inHtmlComment)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '<': t << "<"; break;
+ case '>': t << ">"; break;
+ case '&': t << "&"; break;
+ case '"': t << """; break;
+ case '-': if (inHtmlComment) t << "-"; else t << "-"; break;
+ case '\\':
+ if (*p=='<')
+ { t << "<"; p++; }
+ else if (*p=='>')
+ { t << ">"; p++; }
+ else
+ t << "\\";
+ break;
+ default: t << c;
+ }
+ }
+ }
+}
+
+void HtmlGenerator::writeChar(char c)
+{
+ char cs[2];
+ cs[0]=c;
+ cs[1]=0;
+ docify(cs);
+}
+
+//--- helper function for dynamic sections -------------------------
+
+static void startSectionHeader(FTextStream &t,
+ const QCString &relPath,int sectionCount)
+{
+ //t << "<!-- startSectionHeader -->";
+ static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
+ if (dynamicSections)
+ {
+ t << "<div id=\"dynsection-" << sectionCount << "\" "
+ "onclick=\"return toggleVisibility(this)\" "
+ "class=\"dynheader closed\" "
+ "style=\"cursor:pointer;\">" << endl;
+ t << " <img id=\"dynsection-" << sectionCount << "-trigger\" src=\""
+ << relPath << "closed.png\" alt=\"+\"/> ";
+ }
+ else
+ {
+ t << "<div class=\"dynheader\">" << endl;
+ }
+}
+
+static void endSectionHeader(FTextStream &t)
+{
+ //t << "<!-- endSectionHeader -->";
+ t << "</div>" << endl;
+}
+
+static void startSectionSummary(FTextStream &t,int sectionCount)
+{
+ //t << "<!-- startSectionSummary -->";
+ static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
+ if (dynamicSections)
+ {
+ t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
+ "class=\"dynsummary\" "
+ "style=\"display:block;\">" << endl;
+ }
+}
+
+static void endSectionSummary(FTextStream &t)
+{
+ //t << "<!-- endSectionSummary -->";
+ static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
+ if (dynamicSections)
+ {
+ t << "</div>" << endl;
+ }
+}
+
+static void startSectionContent(FTextStream &t,int sectionCount)
+{
+ //t << "<!-- startSectionContent -->";
+ static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
+ if (dynamicSections)
+ {
+ t << "<div id=\"dynsection-" << sectionCount << "-content\" "
+ "class=\"dyncontent\" "
+ "style=\"display:none;\">" << endl;
+ }
+ else
+ {
+ t << "<div class=\"dyncontent\">" << endl;
+ }
+}
+
+static void endSectionContent(FTextStream &t)
+{
+ //t << "<!-- endSectionContent -->";
+ t << "</div>" << endl;
+}
+
+//----------------------------
+
+void HtmlGenerator::startClassDiagram()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
+ const char *fileName,const char *name)
+{
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+ t << " <div class=\"center\">" << endl;
+ t << " <img src=\"";
+ t << relPath << fileName << ".png\" usemap=\"#";
+ docify(name);
+ t << "_map\" alt=\"\"/>" << endl;
+ t << " <map id=\"";
+ docify(name);
+ t << "_map\" name=\"";
+ docify(name);
+ t << "_map\">" << endl;
+
+ d.writeImage(t,dir,relPath,fileName);
+ t << " </div>";
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+
+void HtmlGenerator::startMemberList()
+{
+ DBG_HTML(t << "<!-- startMemberList -->" << endl)
+}
+
+void HtmlGenerator::endMemberList()
+{
+ DBG_HTML(t << "<!-- endMemberList -->" << endl)
+}
+
+// anonymous type:
+// 0 = single column right aligned
+// 1 = double column left aligned
+// 2 = single column left aligned
+void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId)
+{
+ DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
+ if (m_emptySection)
+ {
+ t << "<table class=\"memberdecls\">" << endl;
+ m_emptySection=FALSE;
+ }
+ t << "<tr class=\"memitem:" << anchor;
+ if (inheritId)
+ {
+ t << " inherit " << inheritId;
+ }
+ t << "\">";
+ switch(annoType)
+ {
+ case 0: t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
+ case 1: t << "<td class=\"memItemLeft\" >"; break;
+ case 2: t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
+ default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
+ }
+}
+
+void HtmlGenerator::endMemberItem()
+{
+ t << "</td></tr>";
+ t << endl;
+}
+
+void HtmlGenerator::startMemberTemplateParams()
+{
+}
+
+void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
+{
+ t << "</td></tr>" << endl;
+ t << "<tr class=\"memitem:" << anchor;
+ if (inheritId)
+ {
+ t << " inherit " << inheritId;
+ }
+ t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
+}
+
+
+void HtmlGenerator::insertMemberAlign(bool templ)
+{
+ DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
+ QCString className = templ ? "memTemplItemRight" : "memItemRight";
+ t << " </td><td class=\"" << className << "\" valign=\"bottom\">";
+}
+
+void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId)
+{
+ DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
+ if (m_emptySection)
+ {
+ t << "<table class=\"memberdecls\">" << endl;
+ m_emptySection=FALSE;
+ }
+ t << "<tr class=\"memdesc:" << anchor;
+ if (inheritId)
+ {
+ t << " inherit " << inheritId;
+ }
+ t << "\"><td class=\"mdescLeft\"> </td><td class=\"mdescRight\">";
+}
+
+void HtmlGenerator::endMemberDescription()
+{
+ DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
+ t << "<br /></td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberSections()
+{
+ DBG_HTML(t << "<!-- startMemberSections -->" << endl)
+ m_emptySection=TRUE; // we postpone writing <table> until we actually
+ // write a row to prevent empty tables, which
+ // are not valid XHTML!
+}
+
+void HtmlGenerator::endMemberSections()
+{
+ DBG_HTML(t << "<!-- endMemberSections -->" << endl)
+ if (!m_emptySection)
+ {
+ t << "</table>" << endl;
+ }
+}
+
+void HtmlGenerator::startMemberHeader(const char *anchor)
+{
+ DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
+ if (!m_emptySection)
+ {
+ t << "</table>";
+ m_emptySection=TRUE;
+ }
+ if (m_emptySection)
+ {
+ t << "<table class=\"memberdecls\">" << endl;
+ m_emptySection=FALSE;
+ }
+ t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">";
+ if (anchor)
+ {
+ t << "<a name=\"" << anchor << "\"></a>" << endl;
+ }
+}
+
+void HtmlGenerator::endMemberHeader()
+{
+ DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
+ t << "</h2></td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberSubtitle()
+{
+ DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
+ t << "<tr><td class=\"ititle\" colspan=\"2\">";
+}
+
+void HtmlGenerator::endMemberSubtitle()
+{
+ DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
+ t << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::startIndexList()
+{
+ t << "<table>" << endl;
+}
+
+void HtmlGenerator::endIndexList()
+{
+ t << "</table>" << endl;
+}
+
+void HtmlGenerator::startIndexKey()
+{
+ // inserted 'class = ...', 02 jan 2002, jh
+ t << " <tr><td class=\"indexkey\">";
+}
+
+void HtmlGenerator::endIndexKey()
+{
+ t << "</td>";
+}
+
+void HtmlGenerator::startIndexValue(bool)
+{
+ // inserted 'class = ...', 02 jan 2002, jh
+ t << "<td class=\"indexvalue\">";
+}
+
+void HtmlGenerator::endIndexValue(const char *,bool)
+{
+ t << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberDocList()
+{
+ DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
+}
+
+void HtmlGenerator::endMemberDocList()
+{
+ DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
+}
+
+void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool)
+{
+ DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
+
+ t << "\n<div class=\"memitem\">" << endl;
+ t << "<div class=\"memproto\">" << endl;
+}
+
+void HtmlGenerator::startMemberDocPrefixItem()
+{
+ DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
+ t << "<div class=\"memtemplate\">" << endl;
+}
+
+void HtmlGenerator::endMemberDocPrefixItem()
+{
+ DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
+ t << "</div>" << endl;
+}
+
+void HtmlGenerator::startMemberDocName(bool /*align*/)
+{
+ DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)
+
+ t << " <table class=\"memname\">" << endl;
+
+ t << " <tr>" << endl;
+ t << " <td class=\"memname\">";
+}
+
+void HtmlGenerator::endMemberDocName()
+{
+ DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
+ t << "</td>" << endl;
+}
+
+void HtmlGenerator::startParameterList(bool openBracket)
+{
+ DBG_HTML(t << "<!-- startParameterList -->" << endl;)
+ t << " <td>";
+ if (openBracket) t << "(";
+ t << "</td>" << endl;
+}
+
+void HtmlGenerator::startParameterType(bool first,const char *key)
+{
+ if (first)
+ {
+ DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
+ t << " <td class=\"paramtype\">";
+ }
+ else
+ {
+ DBG_HTML(t << "<!-- startParameterType -->" << endl;)
+ t << " <tr>" << endl;
+ t << " <td class=\"paramkey\">";
+ if (key) t << key;
+ t << "</td>" << endl;
+ t << " <td></td>" << endl;
+ t << " <td class=\"paramtype\">";
+ }
+}
+
+void HtmlGenerator::endParameterType()
+{
+ DBG_HTML(t << "<!-- endParameterType -->" << endl;)
+ t << " </td>" << endl;
+}
+
+void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
+{
+ DBG_HTML(t << "<!-- startParameterName -->" << endl;)
+ t << " <td class=\"paramname\">";
+}
+
+void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
+{
+ DBG_HTML(t << "<!-- endParameterName -->" << endl;)
+ if (last)
+ {
+ if (emptyList)
+ {
+ if (closeBracket) t << "</td><td>)";
+ t << "</td>" << endl;
+ t << " <td>";
+ }
+ else
+ {
+ t << " </td>" << endl;
+ t << " </tr>" << endl;
+ t << " <tr>" << endl;
+ t << " <td></td>" << endl;
+ t << " <td>";
+ if (closeBracket) t << ")";
+ t << "</td>" << endl;
+ t << " <td></td><td>";
+ }
+ }
+ else
+ {
+ t << "</td>" << endl;
+ t << " </tr>" << endl;
+ }
+}
+
+void HtmlGenerator::endParameterList()
+{
+ DBG_HTML(t << "<!-- endParameterList -->" << endl;)
+ t << "</td>" << endl;
+ t << " </tr>" << endl;
+}
+
+void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
+{
+ DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
+ t << "</td>" << endl;
+ t << " </tr>" << endl;
+ t << " <tr>" << endl;
+ t << " <td align=\"right\">";
+ // colspan 2 so it gets both parameter type and parameter name columns
+ if (prefix)
+ t << prefix << "</td><td>(</td><td colspan=\"2\">";
+ else if (closeBracket)
+ t << "</td><td>)</td><td></td><td>";
+ else
+ t << "</td><td></td><td colspan=\"2\">";
+}
+
+void HtmlGenerator::endMemberDoc(bool hasArgs)
+{
+ DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
+ if (!hasArgs)
+ {
+ t << " </tr>" << endl;
+ }
+ t << " </table>" << endl;
+ // t << "</div>" << endl;
+}
+
+void HtmlGenerator::startDotGraph()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endDotGraph(const DotClassGraph &g)
+{
+ bool generateLegend = Config_getBool("GENERATE_LEGEND");
+ bool umlLook = Config_getBool("UML_LOOK");
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+
+ g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
+ if (generateLegend && !umlLook)
+ {
+ t << "<center><span class=\"legend\">[";
+ startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
+ t << theTranslator->trLegend();
+ endHtmlLink();
+ t << "]</span></center>";
+ }
+
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+void HtmlGenerator::startInclDepGraph()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
+{
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+
+ g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
+
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+void HtmlGenerator::startGroupCollaboration()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
+{
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+
+ g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
+
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+void HtmlGenerator::startCallGraph()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endCallGraph(const DotCallGraph &g)
+{
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+
+ g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
+
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+void HtmlGenerator::startDirDepGraph()
+{
+ startSectionHeader(t,relPath,m_sectionCount);
+}
+
+void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
+{
+ endSectionHeader(t);
+ startSectionSummary(t,m_sectionCount);
+ endSectionSummary(t);
+ startSectionContent(t,m_sectionCount);
+
+ g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
+
+ endSectionContent(t);
+ m_sectionCount++;
+}
+
+void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
+{
+ g.writeGraph(t,dir,fileName);
+}
+
+void HtmlGenerator::startMemberGroupHeader(bool)
+{
+ t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
+}
+
+void HtmlGenerator::endMemberGroupHeader()
+{
+ t << "</div></td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberGroupDocs()
+{
+ t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
+}
+
+void HtmlGenerator::endMemberGroupDocs()
+{
+ t << "</div></td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberGroup()
+{
+}
+
+void HtmlGenerator::endMemberGroup(bool)
+{
+}
+
+void HtmlGenerator::startIndent()
+{
+ DBG_HTML(t << "<!-- startIndent -->" << endl;)
+
+ t << "<div class=\"memdoc\">\n";
+}
+
+void HtmlGenerator::endIndent()
+{
+ DBG_HTML(t << "<!-- endIndent -->" << endl;)
+ t << endl << "</div>" << endl << "</div>" << endl;
+}
+
+void HtmlGenerator::addIndexItem(const char *,const char *)
+{
+}
+
+void HtmlGenerator::writeNonBreakableSpace(int n)
+{
+ int i;
+ for (i=0;i<n;i++)
+ {
+ t << " ";
+ }
+}
+
+void HtmlGenerator::startSimpleSect(SectionTypes,
+ const char *filename,const char *anchor,
+ const char *title)
+{
+ t << "<dl><dt><b>";
+ if (filename)
+ {
+ writeObjectLink(0,filename,anchor,title);
+ }
+ else
+ {
+ docify(title);
+ }
+ t << "</b></dt>";
+}
+
+void HtmlGenerator::endSimpleSect()
+{
+ t << "</dl>";
+}
+
+void HtmlGenerator::startParamList(ParamListTypes,
+ const char *title)
+{
+ t << "<dl><dt><b>";
+ docify(title);
+ t << "</b></dt>";
+}
+
+void HtmlGenerator::endParamList()
+{
+ t << "</dl>";
+}
+
+void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
+{
+ HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
+ n->accept(visitor);
+ delete visitor;
+}
+
+//---------------- helpers for index generation -----------------------------
+
+static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
+{
+ if (compact)
+ {
+ if (topLevel)
+ {
+ t << " <div id=\"navrow1\" class=\"tabs\">\n";
+ }
+ else
+ {
+ t << " <div id=\"navrow2\" class=\"tabs2\">\n";
+ }
+ t << " <ul class=\"tablist\">\n";
+ }
+ else
+ {
+ t << "<ul>";
+ }
+}
+
+static void endQuickIndexList(FTextStream &t,bool compact)
+{
+ if (compact)
+ {
+ t << " </ul>\n";
+ t << " </div>\n";
+ }
+ else
+ {
+ t << "</ul>\n";
+ }
+}
+
+static void startQuickIndexItem(FTextStream &t,const char *l,
+ bool hl,bool /*compact*/,
+ const QCString &relPath)
+{
+ t << " <li";
+ if (hl)
+ {
+ t << " class=\"current\"";
+ }
+ t << ">";
+ if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
+ t << "<span>";
+}
+
+static void endQuickIndexItem(FTextStream &t,const char *l)
+{
+ t << "</span>";
+ if (l) t << "</a>";
+ t << "</li>\n";
+}
+
+static QCString fixSpaces(const QCString &s)
+{
+ return substitute(s," "," ");
+}
+
+static bool quickLinkVisible(LayoutNavEntry::Kind kind)
+{
+ static bool showFiles = Config_getBool("SHOW_FILES");
+ static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
+ switch (kind)
+ {
+ case LayoutNavEntry::MainPage: return TRUE;
+ case LayoutNavEntry::User: return TRUE;
+ case LayoutNavEntry::UserGroup: return TRUE;
+ case LayoutNavEntry::Pages: return indexedPages>0;
+ case LayoutNavEntry::Modules: return documentedGroups>0;
+ case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces;
+ case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces;
+ case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
+ case LayoutNavEntry::Classes: return annotatedClasses>0;
+ case LayoutNavEntry::ClassList: return annotatedClasses>0;
+ case LayoutNavEntry::ClassIndex: return annotatedClasses>0;
+ case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0;
+ case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0;
+ case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles;
+ case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles;
+ case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0;
+ //case LayoutNavEntry::Dirs: return documentedDirs>0;
+ case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0;
+ }
+ return FALSE;
+}
+
+static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)
+
+{
+ QListIterator<LayoutNavEntry> li(root->children());
+ LayoutNavEntry *entry;
+ int count=0;
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible() && quickLinkVisible(entry->kind())) count++;
+ }
+ if (count>0) // at least one item is visible
+ {
+ startQuickIndexList(t,FALSE);
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible() && quickLinkVisible(entry->kind()))
+ {
+ QCString url = entry->url();
+ t << "<li><a href=\"" << relPath << url << "\"><span>";
+ t << fixSpaces(entry->title());
+ t << "</span></a>\n";
+ // recursive into child list
+ renderQuickLinksAsTree(t,relPath,entry);
+ t << "</li>";
+ }
+ }
+ endQuickIndexList(t,FALSE);
+ }
+}
+
+
+static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
+ LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
+ bool highlightParent,bool highlightSearch)
+{
+ if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
+ {
+ renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
+ }
+ if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
+ {
+ bool topLevel = hlEntry->parent()->parent()==0;
+ QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
+ LayoutNavEntry *entry;
+
+ int count=0;
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible() && quickLinkVisible(entry->kind())) count++;
+ }
+ if (count>0) // at least one item is visible
+ {
+ startQuickIndexList(t,TRUE,topLevel);
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible() && quickLinkVisible(entry->kind()))
+ {
+ QCString url = entry->url();
+ startQuickIndexItem(t,url,
+ entry==hlEntry &&
+ (entry->children().count()>0 ||
+ (entry->kind()==kind && !highlightParent)
+ ),
+ TRUE,relPath);
+ t << fixSpaces(entry->title());
+ endQuickIndexItem(t,url);
+ }
+ }
+ if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
+ {
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+ if (searchEngine)
+ {
+ t << " <li>\n";
+ if (!serverBasedSearch) // pure client side search
+ {
+ writeClientSearchBox(t,relPath);
+ t << " </li>\n";
+ }
+ else // server based search
+ {
+ writeServerSearchBox(t,relPath,highlightSearch);
+ if (!highlightSearch)
+ {
+ t << " </li>\n";
+ }
+ }
+ }
+ if (!highlightSearch) // on the search page the index will be ended by the
+ // page itself
+ {
+ endQuickIndexList(t,TRUE);
+ }
+ }
+ else // normal case for other rows than first one
+ {
+ endQuickIndexList(t,TRUE);
+ }
+ }
+ }
+}
+
+static void writeDefaultQuickLinks(FTextStream &t,bool compact,
+ HighlightedItem hli,
+ const char *file,
+ const QCString &relPath)
+{
+ LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
+ LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
+ LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
+ bool highlightParent=FALSE;
+ switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
+ {
+ case HLI_Main: kind = LayoutNavEntry::MainPage; break;
+ case HLI_Modules: kind = LayoutNavEntry::Modules; break;
+ //case HLI_Directories: kind = LayoutNavEntry::Dirs; break;
+ case HLI_Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break;
+ case HLI_Hierarchy: kind = LayoutNavEntry::ClassHierarchy; break;
+ case HLI_Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break;
+ case HLI_Annotated: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break;
+ case HLI_Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break;
+ case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
+ case HLI_Functions: kind = LayoutNavEntry::ClassMembers; break;
+ case HLI_Globals: kind = LayoutNavEntry::FileGlobals; break;
+ case HLI_Pages: kind = LayoutNavEntry::Pages; break;
+ case HLI_Examples: kind = LayoutNavEntry::Examples; break;
+ case HLI_UserGroup: kind = LayoutNavEntry::UserGroup; break;
+ case HLI_ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes;
+ highlightParent = TRUE; break;
+ case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces;
+ highlightParent = TRUE; break;
+ case HLI_FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files;
+ highlightParent = TRUE; break;
+ case HLI_None: break;
+ case HLI_Search: break;
+ }
+
+ if (compact)
+ {
+ // find highlighted index item
+ LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
+ if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
+ if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
+ {
+ highlightParent=TRUE;
+ hlEntry = root->children().getFirst();
+ if (hlEntry==0)
+ {
+ return; // argl, empty index!
+ }
+ }
+ if (kind==LayoutNavEntry::UserGroup)
+ {
+ LayoutNavEntry *e = hlEntry->children().getFirst();
+ if (e)
+ {
+ hlEntry = e;
+ }
+ }
+ renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
+ }
+ else
+ {
+ renderQuickLinksAsTree(t,relPath,root);
+ }
+}
+
+void HtmlGenerator::endQuickIndices()
+{
+ t << "</div><!-- top -->" << endl;
+}
+
+QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ QCString result;
+ // write split bar
+ if (generateTreeView)
+ {
+ result = QCString(
+ "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
+ " <div id=\"nav-tree\">\n"
+ " <div id=\"nav-tree-contents\">\n"
+ " <div id=\"nav-sync\" class=\"sync\"></div>\n"
+ " </div>\n"
+ " </div>\n"
+ " <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
+ " class=\"ui-resizable-handle\">\n"
+ " </div>\n"
+ "</div>\n"
+ "<script type=\"text/javascript\">\n"
+ "$(document).ready(function(){initNavTree('") +
+ QCString(name) + Doxygen::htmlFileExtension +
+ QCString("','") + relpath +
+ QCString("');});\n"
+ "</script>\n"
+ "<div id=\"doc-content\">\n");
+ }
+ return result;
+}
+
+void HtmlGenerator::writeSplitBar(const char *name)
+{
+ t << writeSplitBarAsString(name,relPath);
+}
+
+void HtmlGenerator::writeNavigationPath(const char *s)
+{
+ t << substitute(s,"$relpath^",relPath);
+}
+
+void HtmlGenerator::startContents()
+{
+ t << "<div class=\"contents\">" << endl;
+}
+
+void HtmlGenerator::endContents()
+{
+ t << "</div><!-- contents -->" << endl;
+}
+
+void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
+{
+ writeDefaultQuickLinks(t,compact,hli,file,relPath);
+}
+
+// PHP based search script
+void HtmlGenerator::writeSearchPage()
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+ static QCString projectName = Config_getString("PROJECT_NAME");
+
+ // OPENSEARCH_PROVIDER {
+ QCString configFileName = Config_getString("HTML_OUTPUT")+"/search-config.php";
+ QFile cf(configFileName);
+ if (cf.open(IO_WriteOnly))
+ {
+ FTextStream t(&cf);
+ t << "<script language=\"php\">\n\n";
+ t << "$config = array(\n";
+ t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
+ t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
+ t << " 'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
+ t << ");\n\n";
+ t << "$translator = array(\n";
+ t << " 'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
+ t << " 'search_results' => array(\n";
+ t << " 0 => \"" << theTranslator->trSearchResults(0) << "\",\n";
+ t << " 1 => \"" << theTranslator->trSearchResults(1) << "\",\n";
+ t << " 2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";
+ t << " ),\n";
+ t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
+ t << " 'search' => \"" << theTranslator->trSearch() << "\",\n";
+ t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
+ t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
+ t << ");\n\n";
+ t << "</script>\n";
+ }
+
+ QCString functionsFileName = Config_getString("HTML_OUTPUT")+"/search-functions.php";
+ QFile ff(functionsFileName);
+ if (ff.open(IO_WriteOnly))
+ {
+ FTextStream t(&ff);
+ // Write stuff from search_functions.php source file...
+ t << search_functions_script;
+ }
+
+ QCString opensearchFileName = Config_getString("HTML_OUTPUT")+"/search-opensearch.php";
+ QFile of(opensearchFileName);
+ if (of.open(IO_WriteOnly))
+ {
+ FTextStream t(&of);
+ // Write stuff from search_opensearch.php source file...
+ t << search_opensearch_script;
+ }
+ // OPENSEARCH_PROVIDER }
+
+ QCString fileName = Config_getString("HTML_OUTPUT")+"/search.php";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << substituteHtmlKeywords(g_header,"Search","");
+
+ t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
+ << versionString << " -->" << endl;
+ t << "<script type=\"text/javascript\">\n";
+ t << "var searchBox = new SearchBox(\"searchBox\", \""
+ << "search\",false,'" << theTranslator->trSearch() << "');\n";
+ t << "</script>\n";
+ if (!Config_getBool("DISABLE_INDEX"))
+ {
+ writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
+ }
+ else
+ {
+ t << "</div>" << endl;
+ }
+
+ t << "<script language=\"php\">\n";
+ t << "require_once \"search-functions.php\";\n";
+ t << "main();\n";
+ t << "</script>\n";
+
+ // Write empty navigation path, to make footer connect properly
+ if (generateTreeView)
+ {
+ t << "</div><!-- doc-contents -->\n";
+ //t << "<div id=\"nav-path\" class=\"navpath\">\n";
+ //t << " <ul>\n";
+ }
+
+ writePageFooter(t,"Search","","");
+ }
+ QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
+ QFile sf(scriptName);
+ if (sf.open(IO_WriteOnly))
+ {
+ FTextStream t(&sf);
+ t << extsearch_script;
+ }
+ else
+ {
+ err("Failed to open file '%s' for writing...\n",scriptName.data());
+ }
+}
+
+void HtmlGenerator::writeExternalSearchPage()
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension;
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << substituteHtmlKeywords(g_header,"Search","");
+
+ t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
+ << versionString << " -->" << endl;
+ t << "<script type=\"text/javascript\">\n";
+ t << "var searchBox = new SearchBox(\"searchBox\", \""
+ << "search\",false,'" << theTranslator->trSearch() << "');\n";
+ t << "</script>\n";
+ if (!Config_getBool("DISABLE_INDEX"))
+ {
+ writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
+ t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
+ t << " </form>\n";
+ t << " </div><div class=\"right\"></div>\n";
+ t << " </div>\n";
+ t << " </li>\n";
+ t << " </ul>\n";
+ t << " </div>\n";
+ t << "</div>\n";
+ }
+ else
+ {
+ t << "</div>" << endl;
+ }
+ t << writeSplitBarAsString("search","");
+ t << "<div class=\"header\">" << endl;
+ t << " <div class=\"headertitle\">" << endl;
+ t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
+ t << " </div>" << endl;
+ t << "</div>" << endl;
+ t << "<div class=\"contents\">" << endl;
+
+ t << "<div id=\"searchresults\"></div>" << endl;
+ t << "</div>" << endl;
+
+ if (generateTreeView)
+ {
+ t << "</div><!-- doc-contents -->" << endl;
+ }
+
+ writePageFooter(t,"Search","","");
+ }
+ QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
+ QFile sf(scriptName);
+ if (sf.open(IO_WriteOnly))
+ {
+ FTextStream t(&sf);
+ t << "var searchResultsText=["
+ << "\"" << theTranslator->trSearchResults(0) << "\","
+ << "\"" << theTranslator->trSearchResults(1) << "\","
+ << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
+ t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl;
+ t << "var tagMap = {" << endl;
+ bool first=TRUE;
+ // add search mappings
+ QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS");
+ char *ml=extraSearchMappings.first();
+ while (ml)
+ {
+ QCString mapLine = ml;
+ int eqPos = mapLine.find('=');
+ if (eqPos!=-1) // tag command contains a destination
+ {
+ QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
+ QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
+ if (!tagName.isEmpty())
+ {
+ if (!first) t << "," << endl;
+ t << " \"" << tagName << "\": \"" << destName << "\"";
+ first=FALSE;
+ }
+ }
+ ml=extraSearchMappings.next();
+ }
+ if (!first) t << endl;
+ t << "};" << endl << endl;
+ t << extsearch_script;
+ t << endl;
+ t << "$(document).ready(function() {" << endl;
+ t << " var query = trim(getURLParameter('query'));" << endl;
+ t << " if (query) {" << endl;
+ t << " searchFor(query,0,20);" << endl;
+ t << " } else {" << endl;
+ t << " var results = $('#results');" << endl;
+ t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
+ t << " }" << endl;
+ t << "});" << endl;
+ }
+ else
+ {
+ err("Failed to open file '%s' for writing...\n",scriptName.data());
+ }
+}
+
+void HtmlGenerator::startConstraintList(const char *header)
+{
+ t << "<div class=\"typeconstraint\">" << endl;
+ t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
+ t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
+}
+
+void HtmlGenerator::startConstraintParam()
+{
+ t << "<tr><td valign=\"top\"><em>";
+}
+
+void HtmlGenerator::endConstraintParam()
+{
+ t << "</em></td>";
+}
+
+void HtmlGenerator::startConstraintType()
+{
+ t << "<td> :</td><td valign=\"top\"><em>";
+}
+
+void HtmlGenerator::endConstraintType()
+{
+ t << "</em></td>";
+}
+
+void HtmlGenerator::startConstraintDocs()
+{
+ t << "<td> ";
+}
+
+void HtmlGenerator::endConstraintDocs()
+{
+ t << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::endConstraintList()
+{
+ t << "</table>" << endl;
+ t << "</dl>" << endl;
+ t << "</div>" << endl;
+}
+
+void HtmlGenerator::lineBreak(const char *style)
+{
+ if (style)
+ {
+ t << "<br class=\"" << style << "\" />" << endl;
+ }
+ else
+ {
+ t << "<br />" << endl;
+ }
+}
+
+void HtmlGenerator::startHeaderSection()
+{
+ t << "<div class=\"header\">" << endl;
+}
+
+void HtmlGenerator::startTitleHead(const char *)
+{
+ t << " <div class=\"headertitle\">" << endl;
+ startTitle();
+}
+
+void HtmlGenerator::endTitleHead(const char *,const char *)
+{
+ endTitle();
+ t << " </div>" << endl;
+}
+
+void HtmlGenerator::endHeaderSection()
+{
+ t << "</div><!--header-->" << endl;
+}
+
+void HtmlGenerator::startInlineHeader()
+{
+ if (m_emptySection)
+ {
+ t << "<table class=\"memberdecls\">" << endl;
+ m_emptySection=FALSE;
+ }
+ t << "<tr><td colspan=\"2\"><h3>";
+}
+
+void HtmlGenerator::endInlineHeader()
+{
+ t << "</h3></td></tr>" << endl;
+}
+
+void HtmlGenerator::startMemberDocSimple()
+{
+ DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
+ t << "<table class=\"fieldtable\">" << endl;
+ t << "<tr><th colspan=\"3\">" << theTranslator->trCompoundMembers() << "</th></tr>" << endl;
+}
+
+void HtmlGenerator::endMemberDocSimple()
+{
+ DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
+ t << "</table>" << endl;
+}
+
+void HtmlGenerator::startInlineMemberType()
+{
+ DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
+ t << "<tr><td class=\"fieldtype\">" << endl;
+}
+
+void HtmlGenerator::endInlineMemberType()
+{
+ DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
+ t << "</td>" << endl;
+}
+
+void HtmlGenerator::startInlineMemberName()
+{
+ DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
+ t << "<td class=\"fieldname\">" << endl;
+}
+
+void HtmlGenerator::endInlineMemberName()
+{
+ DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
+ t << "</td>" << endl;
+}
+
+void HtmlGenerator::startInlineMemberDoc()
+{
+ DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
+ t << "<td class=\"fielddoc\">" << endl;
+}
+
+void HtmlGenerator::endInlineMemberDoc()
+{
+ DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
+ t << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::startLabels()
+{
+ DBG_HTML(t << "<!-- startLabels -->" << endl;)
+ t << "<span class=\"mlabels\">";
+}
+
+void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
+{
+ DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
+ //t << "<tt>[" << l << "]</tt>";
+ //if (!isLast) t << ", ";
+ t << "<span class=\"mlabel\">" << l << "</span>";
+}
+
+void HtmlGenerator::endLabels()
+{
+ DBG_HTML(t << "<!-- endLabels -->" << endl;)
+ t << "</span>";
+}
+
+void HtmlGenerator::writeInheritedSectionTitle(
+ const char *id, const char *ref,
+ const char *file, const char *anchor,
+ const char *title, const char *name)
+{
+ DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
+ QCString a = anchor;
+ if (!a.isEmpty()) a.prepend("#");
+ QCString classLink = QCString("<a class=\"el\" href=\"");
+ if (ref)
+ {
+ classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE);
+ }
+ else
+ {
+ classLink+=relPath;
+ }
+ classLink+=file+Doxygen::htmlFileExtension+a;
+ classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
+ t << "<tr class=\"inherit_header " << id << "\">"
+ << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
+ << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/> "
+ << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
+ << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
+{
+ if (first)
+ {
+ t << " <div class=\"summary\">\n";
+ }
+ else
+ {
+ t << " |\n";
+ }
+ t << "<a href=\"";
+ if (file)
+ {
+ t << relPath << file;
+ t << Doxygen::htmlFileExtension;
+ }
+ else
+ {
+ t << "#";
+ t << anchor;
+ }
+ t << "\">";
+ t << title;
+ t << "</a>";
+}
+
+void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
+{
+ t << "<tr class=\"separator:" << anchor;
+ if (inheritId)
+ {
+ t << " inherit " << inheritId;
+ }
+ t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n";
+}
+
+void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
+{
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
+ }
+}
+
+void HtmlGenerator::addWord(const char *word,bool hiPriority)
+{
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->addWord(word,hiPriority);
+ }
+}
+
diff --git a/src/htmlgen.h b/src/htmlgen.h
new file mode 100644
index 0000000..7b63a6b
--- /dev/null
+++ b/src/htmlgen.h
@@ -0,0 +1,362 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef HTMLGEN_H
+#define HTMLGEN_H
+
+#include "outputgen.h"
+#include "ftextstream.h"
+
+//#define PREFRAG_START "<div class=\"fragment\"><pre class=\"fragment\">"
+//#define PREFRAG_END "</pre></div>"
+#define PREFRAG_START "<div class=\"fragment\">"
+#define PREFRAG_END "</div><!-- fragment -->"
+
+class QFile;
+
+class HtmlCodeGenerator : public CodeOutputInterface
+{
+ public:
+ HtmlCodeGenerator(FTextStream &t,const QCString &relPath);
+ HtmlCodeGenerator();
+ void setTextStream(FTextStream &t);
+ void setRelativePath(const QCString &path);
+ void codify(const char *text);
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void writeTooltip(const char *id,
+ const DocLinkInfo &docInfo,
+ const char *decl,
+ const char *desc,
+ const SourceLinkInfo &defInfo,
+ const SourceLinkInfo &declInfo
+ );
+ void writeLineNumber(const char *,const char *,const char *,int);
+ void startCodeLine(bool);
+ void endCodeLine();
+ void startFontClass(const char *s);
+ void endFontClass();
+ void writeCodeAnchor(const char *anchor);
+ void setCurrentDoc(Definition *,const char *,bool) {}
+ void addWord(const char *,bool) {}
+
+ private:
+ void _writeCodeLink(const char *className,
+ const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void docify(const char *str);
+ bool m_streamSet;
+ FTextStream m_t;
+ int m_col;
+ QCString m_relPath;
+};
+
+/** Generator for HTML output */
+class HtmlGenerator : public OutputGenerator
+{
+ public:
+ HtmlGenerator();
+ virtual ~HtmlGenerator();
+ static void init();
+ static void writeStyleSheetFile(QFile &f);
+ static void writeHeaderFile(QFile &f, const char *cssname);
+ static void writeFooterFile(QFile &f);
+ static void writeTabData();
+ static void writeSearchInfo(FTextStream &t,const QCString &relPath);
+ static void writeSearchData(const char *dir);
+ static void writeSearchPage();
+ static void writeExternalSearchPage();
+ static QCString writeLogoAsString(const char *path);
+ static QCString writeSplitBarAsString(const char *name,const char *relpath);
+
+ void enable()
+ { if (genStack->top()) active=*genStack->top(); else active=TRUE; }
+ void disable() { active=FALSE; }
+ void enableIf(OutputType o) { if (o==Html) enable(); }
+ void disableIf(OutputType o) { if (o==Html) disable(); }
+ void disableIfNot(OutputType o) { if (o!=Html) disable(); }
+ bool isEnabled(OutputType o) { return (o==Html && active); }
+ OutputGenerator *get(OutputType o) { return (o==Html) ? this : 0; }
+
+ // ---- CodeOutputInterface
+ void codify(const char *text)
+ { m_codeGen.codify(text); }
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip)
+ { m_codeGen.writeCodeLink(ref,file,anchor,name,tooltip); }
+ void writeLineNumber(const char *ref,const char *file,const char *anchor,int lineNumber)
+ { m_codeGen.writeLineNumber(ref,file,anchor,lineNumber); }
+ void writeTooltip(const char *id, const DocLinkInfo &docInfo, const char *decl,
+ const char *desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo
+ )
+ { m_codeGen.writeTooltip(id,docInfo,decl,desc,defInfo,declInfo); }
+ void startCodeLine(bool hasLineNumbers)
+ { m_codeGen.startCodeLine(hasLineNumbers); }
+ void endCodeLine()
+ { m_codeGen.endCodeLine(); }
+ void startFontClass(const char *s)
+ { m_codeGen.startFontClass(s); }
+ void endFontClass()
+ { m_codeGen.endFontClass(); }
+ void writeCodeAnchor(const char *anchor)
+ { m_codeGen.writeCodeAnchor(anchor); }
+ // ---------------------------
+
+ void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile);
+ void addWord(const char *word,bool hiPriority);
+ void writeDoc(DocNode *,Definition *,MemberDef *);
+
+ void startFile(const char *name,const char *manName,const char *title);
+ void writeFooter(const char *navPath);
+ void endFile();
+ void clearBuffer();
+ void writeSearchInfo();
+
+ void startIndexSection(IndexSections) {}
+ void endIndexSection(IndexSections) {}
+ void writePageLink(const char *,bool) {}
+ void startProjectNumber();
+ void endProjectNumber();
+ void writeStyleInfo(int part);
+ void startTitleHead(const char *);
+ void endTitleHead(const char *,const char *);
+ void startTitle() { t << "<div class=\"title\">"; }
+ void endTitle() { t << "</div>"; }
+
+ void startParagraph();
+ void endParagraph();
+ void writeString(const char *text);
+ void startIndexListItem();
+ void endIndexListItem();
+ void startIndexList();
+ void endIndexList();
+ void startIndexKey();
+ void endIndexKey();
+ void startIndexValue(bool);
+ void endIndexValue(const char *,bool);
+ void startItemList() { t << "<ul>" << endl; }
+ void endItemList() { t << "</ul>" << endl; }
+ void startIndexItem(const char *ref,const char *file);
+ void endIndexItem(const char *ref,const char *file);
+ void docify(const char *text);
+
+ void writeObjectLink(const char *ref,const char *file,
+ const char *anchor,const char *name);
+
+ void startTextLink(const char *file,const char *anchor);
+ void endTextLink();
+ void startHtmlLink(const char *url);
+ void endHtmlLink();
+ void startTypewriter() { t << "<code>"; }
+ void endTypewriter() { t << "</code>"; }
+ void startGroupHeader(int);
+ void endGroupHeader(int);
+ void startItemListItem() { t << "<li>"; }
+ void endItemListItem() { t << "</li>\n"; }
+
+ void startMemberSections();
+ void endMemberSections();
+ void startHeaderSection();
+ void endHeaderSection();
+ void startMemberHeader(const char *);
+ void endMemberHeader();
+ void startMemberSubtitle();
+ void endMemberSubtitle();
+ void startMemberDocList();
+ void endMemberDocList();
+ void startMemberList();
+ void endMemberList();
+ void startInlineHeader();
+ void endInlineHeader();
+ void startAnonTypeScope(int) {}
+ void endAnonTypeScope(int) {}
+ void startMemberItem(const char *anchor,int,const char *inheritId);
+ void endMemberItem();
+ void startMemberTemplateParams();
+ void endMemberTemplateParams(const char *anchor,const char *inheritId);
+
+ void startMemberGroupHeader(bool);
+ void endMemberGroupHeader();
+ void startMemberGroupDocs();
+ void endMemberGroupDocs();
+ void startMemberGroup();
+ void endMemberGroup(bool);
+
+ void insertMemberAlign(bool);
+ void startMemberDescription(const char *anchor,const char *inheritId);
+ void endMemberDescription();
+ void startMemberDeclaration() {}
+ void endMemberDeclaration(const char *anchor,const char *inheritId);
+ void writeInheritedSectionTitle(const char *id, const char *ref,
+ const char *file, const char *anchor,
+ const char *title,const char *name);
+
+ void writeRuler() { t << "<hr/>"; }
+ void writeAnchor(const char *,const char *name)
+ { t << "<a name=\"" << name <<"\" id=\"" << name << "\"></a>"; }
+ void startCodeFragment() { t << PREFRAG_START; }
+ void endCodeFragment() { t << PREFRAG_END; }
+ void startEmphasis() { t << "<em>"; }
+ void endEmphasis() { t << "</em>"; }
+ void startBold() { t << "<b>"; }
+ void endBold() { t << "</b>"; }
+ void startDescription() { t << endl << "<dl>" << endl; }
+ void endDescription() { t << endl << "</dl>\n" << endl; }
+ void startDescItem() { t << "<dt>"; }
+ void endDescItem() { t << "</dt>"; }
+ void startDescForItem() { t << "<dd>"; }
+ void endDescForItem() { t << "</dd>\n"; }
+ void lineBreak(const char *style);
+ void writeChar(char c);
+ void startMemberDoc(const char *,const char *,const char *,const char *,bool);
+ void endMemberDoc(bool);
+ void startDoxyAnchor(const char *fName,const char *manName,
+ const char *anchor,const char *name,
+ const char *args);
+ void endDoxyAnchor(const char *fName,const char *anchor);
+ void writeLatexSpacing() {}
+ void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name);
+ void writeEndAnnoItem(const char *) { t << endl; }
+ void startSubsection() { t << "<h2>"; }
+ void endSubsection() { t << "</h2>" << endl; }
+ void startSubsubsection() { t << "<h3>"; }
+ void endSubsubsection() { t << "</h3>" << endl; }
+ void startCenter() { t << "<center>" << endl; }
+ void endCenter() { t << "</center>" << endl; }
+ void startSmall() { t << "<small>" << endl; }
+ void endSmall() { t << "</small>" << endl; }
+ //void startDescList(SectionTypes) { t << "<dl compact><dt><b>" << endl; }
+ //void endDescList() { t << "</dl>"; }
+ void startSimpleSect(SectionTypes,const char *,const char *,const char *);
+ void endSimpleSect();
+ void startParamList(ParamListTypes,const char *);
+ void endParamList();
+ //void writeDescItem() { t << "<dd>" << endl; }
+ void startSection(const char *,const char *,SectionInfo::SectionType);
+ void endSection(const char *,SectionInfo::SectionType);
+ void addIndexItem(const char *,const char *);
+ void startIndent();
+ void endIndent();
+ void writeSynopsis() {}
+ void startClassDiagram();
+ void endClassDiagram(const ClassDiagram &,const char *,const char *);
+ void startPageRef() {}
+ void endPageRef(const char *,const char *) {}
+ void startQuickIndices() {}
+ void endQuickIndices();
+ void writeSplitBar(const char *name);
+ void writeNavigationPath(const char *s);
+ void writeLogo();
+ void writeQuickLinks(bool compact,HighlightedItem hli,const char *file);
+ void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first);
+ void startContents();
+ void endContents();
+ void writeNonBreakableSpace(int);
+
+ void startDescTable(const char *title)
+ //{ t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl; }
+ { t << "<table class=\"fieldtable\">" << endl
+ << "<tr><th colspan=\"2\">" << title << "</th></tr>";
+ }
+ void endDescTable()
+ { t << "</table>" << endl; }
+ void startDescTableTitle()
+ //{ t << "<tr><td valign=\"top\"><em>"; }
+ { t << "<tr><td class=\"fieldname\">"; }
+ void endDescTableTitle()
+ { t << " </td>"; }
+ void startDescTableData()
+ //{ t << "<td>" << endl; }
+ { t << "<td class=\"fielddoc\">" << endl; }
+ void endDescTableData()
+ { t << "</td></tr>" << endl; }
+
+ void startDotGraph();
+ void endDotGraph(const DotClassGraph &g);
+ void startInclDepGraph();
+ void endInclDepGraph(const DotInclDepGraph &g);
+ void startGroupCollaboration();
+ void endGroupCollaboration(const DotGroupCollaboration &g);
+ void startCallGraph();
+ void endCallGraph(const DotCallGraph &g);
+ void startDirDepGraph();
+ void endDirDepGraph(const DotDirDeps &g);
+ void writeGraphicalHierarchy(const DotGfxHierarchyTable &g);
+
+ void startTextBlock(bool)
+ { t << "<div class=\"textblock\">"; }
+ void endTextBlock(bool)
+ { t << "</div>"; }
+ void lastIndexPage() {}
+
+ void startMemberDocPrefixItem();
+ void endMemberDocPrefixItem();
+ void startMemberDocName(bool);
+ void endMemberDocName();
+ void startParameterType(bool first,const char *key);
+ void endParameterType();
+ void startParameterName(bool);
+ void endParameterName(bool last,bool emptyList,bool closeBracket);
+ void startParameterList(bool);
+ void endParameterList();
+ virtual void exceptionEntry(const char*,bool);
+
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
+ void startMemberDocSimple();
+ void endMemberDocSimple();
+ void startInlineMemberType();
+ void endInlineMemberType();
+ void startInlineMemberName();
+ void endInlineMemberName();
+ void startInlineMemberDoc();
+ void endInlineMemberDoc();
+
+ void startLabels();
+ void writeLabel(const char *l,bool isLast);
+ void endLabels();
+
+
+ //static void generateSectionImages();
+
+ private:
+ static void writePageFooter(FTextStream &t,const QCString &,const QCString &,const QCString &);
+ QCString lastTitle;
+ QCString lastFile;
+ QCString relPath;
+ void docify(const char *text,bool inHtmlComment);
+
+ HtmlGenerator &operator=(const HtmlGenerator &g);
+ HtmlGenerator(const HtmlGenerator &g);
+
+ int m_sectionCount;
+ bool m_emptySection;
+ HtmlCodeGenerator m_codeGen;
+};
+
+#endif
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
new file mode 100644
index 0000000..c1e535d
--- /dev/null
+++ b/src/htmlhelp.cpp
@@ -0,0 +1,714 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The original version of this file is largely based on a contribution from
+ * Harm van der Heijden.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <qlist.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <qfile.h>
+
+#include "qtextcodec.h"
+#include "sortdict.h"
+#include "htmlhelp.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "language.h"
+#include "portable.h"
+#include "groupdef.h"
+#include "memberdef.h"
+#include "filedef.h"
+#include "util.h"
+
+//----------------------------------------------------------------------------
+
+/** Class representing a field in the HTML help index. */
+struct IndexField
+{
+ QCString name;
+ QCString url;
+ QCString anchor;
+ bool link;
+ bool reversed;
+};
+
+/** Sorted dictionary of IndexField objects. */
+class IndexFieldSDict : public SDict<IndexField>
+{
+ public:
+ IndexFieldSDict() : SDict<IndexField>(17) {}
+ ~IndexFieldSDict() {}
+ private:
+ int compareValues(const IndexField *item1, const IndexField *item2) const
+ {
+ return qstricmp(item1->name,item2->name);
+ }
+};
+
+/** A helper class for HtmlHelp that manages a two level index in
+ * alphabetical order.
+ */
+class HtmlHelpIndex
+{
+ public:
+ HtmlHelpIndex(HtmlHelp *help);
+ ~HtmlHelpIndex();
+ void addItem(const char *first,const char *second,
+ const char *url, const char *anchor,
+ bool hasLink,bool reversed);
+ void writeFields(FTextStream &t);
+ private:
+ IndexFieldSDict *dict;
+ HtmlHelp *m_help;
+};
+
+/*! Constructs a new HtmlHelp index */
+HtmlHelpIndex::HtmlHelpIndex(HtmlHelp *help) : m_help(help)
+{
+ dict = new IndexFieldSDict;
+ dict->setAutoDelete(TRUE);
+}
+
+/*! Destroys the HtmlHelp index */
+HtmlHelpIndex::~HtmlHelpIndex()
+{
+ delete dict;
+}
+
+/*! Stores an item in the index if it is not already present.
+ * Items are stored in alphetical order, by sorting on the
+ * concatenation of \a level1 and \a level2 (if present).
+ *
+ * \param level1 the string at level 1 in the index.
+ * \param level2 the string at level 2 in the index (or 0 if not applicable).
+ * \param url the url of the documentation (without .html extension).
+ * \param anchor the anchor of the documentation within the page.
+ * \param hasLink if true, the url (without anchor) can be used in the
+ * level1 item, when writing the header of a list of level2 items.
+ * \param reversed TRUE if level1 is the member name and level2 the compound
+ * name.
+ */
+void HtmlHelpIndex::addItem(const char *level1,const char *level2,
+ const char *url,const char *anchor,bool hasLink,
+ bool reversed)
+{
+ QCString key = level1;
+ if (level2) key+= (QCString)"?" + level2;
+ if (key.find(QRegExp("@[0-9]+"))!=-1) // skip anonymous stuff
+ {
+ return;
+ }
+ if (dict->find(key)==0) // new key
+ {
+ //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n",
+ // level1,level2,url,anchor);
+ IndexField *f = new IndexField;
+ f->name = key;
+ f->url = url;
+ f->anchor = anchor;
+ f->link = hasLink;
+ f->reversed = reversed;
+ dict->append(key,f);
+ }
+}
+
+static QCString field2URL(const IndexField *f,bool checkReversed)
+{
+ QCString result = f->url + Doxygen::htmlFileExtension;
+ if (!f->anchor.isEmpty() && (!checkReversed || f->reversed))
+ {
+ result+="#"+f->anchor;
+ }
+ return result;
+}
+
+/*! Writes the sorted list of index items into a html like list.
+ *
+ * An list of calls with <code>name = level1,level2</code> as follows:
+ * <pre>
+ * a1,b1
+ * a1,b2
+ * a2,b1
+ * a2,b2
+ * a3
+ * a4,b1
+ * </pre>
+ *
+ * Will result in the following list:
+ *
+ * <pre>
+ * a1 -> link to url if hasLink==TRUE
+ * b1 -> link to url#anchor
+ * b2 -> link to url#anchor
+ * a2 -> link to url if hasLink==TRUE
+ * b1 -> link to url#anchor
+ * b2 -> link to url#anchor
+ * a3 -> link to url if hasLink==TRUE
+ * a4 -> link to url if hasLink==TRUE
+ * b1 -> link to url#anchor
+ * </pre>
+ */
+void HtmlHelpIndex::writeFields(FTextStream &t)
+{
+ dict->sort();
+ IndexFieldSDict::Iterator ifli(*dict);
+ IndexField *f;
+ QCString lastLevel1;
+ bool level2Started=FALSE;
+ for (;(f=ifli.current());++ifli)
+ {
+ QCString level1,level2;
+ int i;
+ if ((i=f->name.find('?'))!=-1)
+ {
+ level1 = f->name.left(i);
+ level2 = f->name.right(f->name.length()-i-1);
+ }
+ else
+ {
+ level1 = f->name.copy();
+ }
+
+ if (level1!=lastLevel1)
+ { // finish old list at level 2
+ if (level2Started) t << " </UL>" << endl;
+ level2Started=FALSE;
+
+ // <Antony>
+ // Added this code so that an item with only one subitem is written
+ // without any subitem.
+ // For example:
+ // a1, b1 -> will create only a1, not separate subitem for b1
+ // a2, b2
+ // a2, b3
+ QCString nextLevel1;
+ IndexField* fnext = ++ifli;
+ if (fnext)
+ {
+ nextLevel1 = fnext->name.left(fnext->name.find('?'));
+ --ifli;
+ }
+ if (level1 != nextLevel1)
+ {
+ level2 = "";
+ }
+ // </Antony>
+
+ if (level2.isEmpty())
+ {
+ t << " <LI><OBJECT type=\"text/sitemap\">";
+ t << "<param name=\"Local\" value=\"" << field2URL(f,TRUE);
+ t << "\">";
+ t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">"
+ "</OBJECT>\n";
+ }
+ else
+ {
+ if (f->link)
+ {
+ t << " <LI><OBJECT type=\"text/sitemap\">";
+ t << "<param name=\"Local\" value=\"" << field2URL(f,TRUE);
+ t << "\">";
+ t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">"
+ "</OBJECT>\n";
+ }
+ else
+ {
+ t << " <LI><OBJECT type=\"text/sitemap\">";
+ t << "<param name=\"See Also\" value=\"" << m_help->recode(level1) << "\">";
+ t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">"
+ "</OBJECT>\n";
+ }
+ }
+ }
+ if (!level2Started && !level2.isEmpty())
+ { // start new list at level 2
+ t << " <UL>" << endl;
+ level2Started=TRUE;
+ }
+ else if (level2Started && level2.isEmpty())
+ { // end list at level 2
+ t << " </UL>" << endl;
+ level2Started=FALSE;
+ }
+ if (level2Started)
+ {
+ t << " <LI><OBJECT type=\"text/sitemap\">";
+ t << "<param name=\"Local\" value=\"" << field2URL(f,FALSE);
+ t << "\">";
+ t << "<param name=\"Name\" value=\"" << m_help->recode(level2) << "\">"
+ "</OBJECT>\n";
+ }
+ lastLevel1 = level1.copy();
+ }
+ if (level2Started) t << " </UL>" << endl;
+}
+
+//----------------------------------------------------------------------------
+
+HtmlHelp *HtmlHelp::theInstance = 0;
+
+/*! Constructs an html object.
+ * The object has to be \link initialize() initialized\endlink before it can
+ * be used.
+ */
+HtmlHelp::HtmlHelp() : indexFileDict(1009)
+{
+ /* initial depth */
+ dc = 0;
+ cf = kf = 0;
+ index = new HtmlHelpIndex(this);
+ m_fromUtf8 = (void *)(-1);
+}
+
+HtmlHelp::~HtmlHelp()
+{
+ if (m_fromUtf8!=(void *)(-1)) portable_iconv_close(m_fromUtf8);
+}
+#if 0
+/*! return a reference to the one and only instance of this class.
+ */
+HtmlHelp *HtmlHelp::getInstance()
+{
+ if (theInstance==0) theInstance = new HtmlHelp;
+ return theInstance;
+}
+#endif
+
+static QDict<QCString> s_languageDict;
+
+/*! This will create a contents file (index.hhc) and a index file (index.hhk)
+ * and write the header of those files.
+ * It also creates a project file (index.hhp)
+ * \sa finalize()
+ */
+void HtmlHelp::initialize()
+{
+ const char *str = Config_getString("CHM_INDEX_ENCODING");
+ if (!str) str = "CP1250"; // use safe and likely default
+ m_fromUtf8 = portable_iconv_open(str,"UTF-8");
+ if (m_fromUtf8==(void *)(-1))
+ {
+ err("unsupported character conversion for CHM_INDEX_ENCODING: '%s'->'UTF-8'\n", str);
+ exit(1);
+ }
+
+ /* open the contents file */
+ QCString fName = Config_getString("HTML_OUTPUT") + "/index.hhc";
+ cf = new QFile(fName);
+ if (!cf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fName.data());
+ exit(1);
+ }
+ /* Write the header of the contents file */
+ cts.setDevice(cf);
+ cts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
+ "<HTML><HEAD></HEAD><BODY>\n"
+ "<OBJECT type=\"text/site properties\">\n"
+ "<param name=\"FrameName\" value=\"right\">\n"
+ "</OBJECT>\n"
+ "<UL>\n";
+
+ /* open the contents file */
+ fName = Config_getString("HTML_OUTPUT") + "/index.hhk";
+ kf = new QFile(fName);
+ if (!kf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fName.data());
+ exit(1);
+ }
+ /* Write the header of the contents file */
+ kts.setDevice(kf);
+ kts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
+ "<HTML><HEAD></HEAD><BODY>\n"
+ "<OBJECT type=\"text/site properties\">\n"
+ "<param name=\"FrameName\" value=\"right\">\n"
+ "</OBJECT>\n"
+ "<UL>\n";
+
+ /* language codes for Html help
+ 0x405 Czech
+ 0x406 Danish
+ 0x413 Dutch
+ 0xC09 English (Australia)
+ 0x809 English (Britain)
+ 0x1009 English (Canada)
+ 0x1809 English (Ireland)
+ 0x1409 English (New Zealand)
+ 0x1C09 English (South Africa)
+ 0x409 English (United States)
+ 0x40B Finnish
+ 0x40C French
+ 0x407 German
+ 0x408 Greece
+ 0x40E Hungarian
+ 0x410 Italian
+ 0x814 Norwegian
+ 0x415 Polish
+ 0x816 Portuguese(Portugal)
+ 0x416 Portuguese(Brazil)
+ 0x419 Russian
+ 0x80A Spanish(Mexico)
+ 0xC0A Spanish(Modern Sort)
+ 0x40A Spanish(Traditional Sort)
+ 0x41D Swedish
+ 0x41F Turkey
+ 0x411 Japanese
+ 0x412 Korean
+ 0x804 Chinese (PRC)
+ 0x404 Chinese (Taiwan)
+
+ New LCIDs:
+ 0x421 Indonesian
+ 0x41A Croatian
+ 0x418 Romanian
+ 0x424 Slovenian
+ 0x41B Slovak
+ 0x422 Ukrainian
+ 0x81A Serbian (Serbia, Latin)
+ 0x403 Catalan
+ 0x426 Latvian
+ 0x427 Lithuanian
+ 0x436 Afrikaans
+ 0x42A Vietnamese
+ 0x429 Persian (Iran)
+ 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h ,
+ so I have chosen Egypt at random
+
+ */
+ s_languageDict.setAutoDelete(TRUE);
+ s_languageDict.clear();
+ s_languageDict.insert("czech", new QCString("0x405 Czech"));
+ s_languageDict.insert("danish", new QCString("0x406 Danish"));
+ s_languageDict.insert("dutch", new QCString("0x413 Dutch"));
+ s_languageDict.insert("finnish", new QCString("0x40B Finnish"));
+ s_languageDict.insert("french", new QCString("0x40C French"));
+ s_languageDict.insert("german", new QCString("0x407 German"));
+ s_languageDict.insert("greek", new QCString("0x408 Greece"));
+ s_languageDict.insert("hungarian", new QCString("0x40E Hungarian"));
+ s_languageDict.insert("italian", new QCString("0x410 Italian"));
+ s_languageDict.insert("norwegian", new QCString("0x814 Norwegian"));
+ s_languageDict.insert("polish", new QCString("0x415 Polish"));
+ s_languageDict.insert("portuguese", new QCString("0x816 Portuguese(Portugal)"));
+ s_languageDict.insert("brazilian", new QCString("0x416 Portuguese(Brazil)"));
+ s_languageDict.insert("russian", new QCString("0x419 Russian"));
+ s_languageDict.insert("spanish", new QCString("0x40A Spanish(Traditional Sort)"));
+ s_languageDict.insert("swedish", new QCString("0x41D Swedish"));
+ s_languageDict.insert("turkish", new QCString("0x41F Turkey"));
+ s_languageDict.insert("japanese", new QCString("0x411 Japanese"));
+ s_languageDict.insert("japanese-en", new QCString("0x411 Japanese"));
+ s_languageDict.insert("korean", new QCString("0x412 Korean"));
+ s_languageDict.insert("korean-en", new QCString("0x412 Korean"));
+ s_languageDict.insert("chinese", new QCString("0x804 Chinese (PRC)"));
+ s_languageDict.insert("chinese-traditional", new QCString("0x404 Chinese (Taiwan)"));
+
+ // new LCIDs
+ s_languageDict.insert("indonesian", new QCString("0x412 Indonesian"));
+ s_languageDict.insert("croatian", new QCString("0x41A Croatian"));
+ s_languageDict.insert("romanian", new QCString("0x418 Romanian"));
+ s_languageDict.insert("slovene", new QCString("0x424 Slovenian"));
+ s_languageDict.insert("slovak", new QCString("0x41B Slovak"));
+ s_languageDict.insert("ukrainian", new QCString("0x422 Ukrainian"));
+ s_languageDict.insert("serbian", new QCString("0x81A Serbian (Serbia, Latin)"));
+ s_languageDict.insert("catalan", new QCString("0x403 Catalan"));
+ s_languageDict.insert("lithuanian", new QCString("0x427 Lithuanian"));
+ s_languageDict.insert("afrikaans", new QCString("0x436 Afrikaans"));
+ s_languageDict.insert("vietnamese", new QCString("0x42A Vietnamese"));
+ s_languageDict.insert("persian", new QCString("0x429 Persian (Iran)"));
+ s_languageDict.insert("arabic", new QCString("0xC01 Arabic (Egypt)"));
+ s_languageDict.insert("latvian", new QCString("0x426 Latvian"));
+ s_languageDict.insert("macedonian", new QCString("0x042f Macedonian (Former Yugoslav Republic of Macedonia)"));
+ s_languageDict.insert("armenian", new QCString("0x42b Armenian"));
+ //Code for Esperanto should be as shown below but the htmlhelp compiler 1.3 does not support this
+ // (and no newer version is available).
+ //So do a fallback to the default language (see getLanguageString())
+ //s_languageDict.insert("esperanto", new QCString("0x48f Esperanto"));
+ s_languageDict.insert("serbian-cyrillic", new QCString("0xC1A Serbian (Serbia, Cyrillic)"));
+}
+
+
+static QCString getLanguageString()
+{
+ if (!theTranslator->idLanguage().isEmpty())
+ {
+ QCString *s = s_languageDict[theTranslator->idLanguage()];
+ if (s)
+ {
+ return *s;
+ }
+ }
+ // default language
+ return "0x409 English (United States)";
+}
+
+
+
+void HtmlHelp::createProjectFile()
+{
+ /* Write the project file */
+ QCString fName = Config_getString("HTML_OUTPUT") + "/index.hhp";
+ QFile f(fName);
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+
+ QCString indexName="index"+Doxygen::htmlFileExtension;
+ t << "[OPTIONS]\n";
+ if (!Config_getString("CHM_FILE").isEmpty())
+ {
+ t << "Compiled file=" << Config_getString("CHM_FILE") << "\n";
+ }
+ t << "Compatibility=1.1\n"
+ "Full-text search=Yes\n"
+ "Contents file=index.hhc\n"
+ "Default Window=main\n"
+ "Default topic=" << indexName << "\n"
+ "Index file=index.hhk\n"
+ "Language=" << getLanguageString() << endl;
+ if (Config_getBool("BINARY_TOC")) t << "Binary TOC=YES\n";
+ if (Config_getBool("GENERATE_CHI")) t << "Create CHI file=YES\n";
+ t << "Title=" << recode(Config_getString("PROJECT_NAME")) << endl << endl;
+
+ t << "[WINDOWS]" << endl;
+
+ // NOTE: the 0x10387e number is a set of bits specifying the buttons
+ // which should appear in the CHM viewer; that specific value
+ // means "show all buttons including the font-size one";
+ // the font-size one is not normally settable by the HTML Help Workshop
+ // utility but the way to set it is described here:
+ // http://support.microsoft.com/?scid=kb%3Ben-us%3B240062&x=17&y=18
+ // NOTE: the 0x70387e number in addition to the above the Next and Prev button
+ // are shown. They can only be shown in case of a binary toc.
+ // dee http://www.mif2go.com/xhtml/htmlhelp_0016_943addingtabsandtoolbarbuttonstohtmlhelp.htm#Rz108x95873
+ // Value has been taken from htmlhelp.h file of the HTML Help Workshop
+ if (Config_getBool("BINARY_TOC"))
+ {
+ t << "main=\"" << recode(Config_getString("PROJECT_NAME")) << "\",\"index.hhc\","
+ "\"index.hhk\",\"" << indexName << "\",\"" <<
+ indexName << "\",,,,,0x23520,,0x70387e,,,,,,,,0" << endl << endl;
+ }
+ else
+ {
+ t << "main=\"" << recode(Config_getString("PROJECT_NAME")) << "\",\"index.hhc\","
+ "\"index.hhk\",\"" << indexName << "\",\"" <<
+ indexName << "\",,,,,0x23520,,0x10387e,,,,,,,,0" << endl << endl;
+ }
+
+ t << "[FILES]" << endl;
+ char *s = indexFiles.first();
+ while (s)
+ {
+ t << s << endl;
+ s = indexFiles.next();
+ }
+ uint i;
+ for (i=0;i<imageFiles.count();i++)
+ {
+ t << imageFiles.at(i) << endl;
+ }
+ f.close();
+ }
+ else
+ {
+ err("Could not open file %s for writing\n",fName.data());
+ }
+}
+
+void HtmlHelp::addIndexFile(const char *s)
+{
+ if (indexFileDict.find(s)==0)
+ {
+ indexFiles.append(s);
+ indexFileDict.insert(s,(void *)0x8);
+ }
+}
+
+/*! Finalizes the HTML help. This will finish and close the
+ * contents file (index.hhc) and the index file (index.hhk).
+ * \sa initialize()
+ */
+void HtmlHelp::finalize()
+{
+ // end the contents file
+ cts << "</UL>\n";
+ cts << "</BODY>\n";
+ cts << "</HTML>\n";
+ cts.unsetDevice();
+ cf->close();
+ delete cf;
+
+ index->writeFields(kts);
+
+ // end the index file
+ kts << "</UL>\n";
+ kts << "</BODY>\n";
+ kts << "</HTML>\n";
+ kts.unsetDevice();
+ kf->close();
+ delete kf;
+
+ createProjectFile();
+ s_languageDict.clear();
+}
+
+/*! Increase the level of the contents hierarchy.
+ * This will start a new unnumbered HTML list in contents file.
+ * \sa decContentsDepth()
+ */
+void HtmlHelp::incContentsDepth()
+{
+ int i; for (i=0;i<dc+1;i++) cts << " ";
+ cts << "<UL>\n";
+ ++dc;
+}
+
+/*! Decrease the level of the contents hierarchy.
+ * This will end the unnumber HTML list.
+ * \sa incContentsDepth()
+ */
+void HtmlHelp::decContentsDepth()
+{
+ int i; for (i=0;i<dc;i++) cts << " ";
+ cts << "</UL>\n";
+ --dc;
+}
+
+QCString HtmlHelp::recode(const QCString &s)
+{
+ int iSize = s.length();
+ int oSize = iSize*4+1;
+ QCString output(oSize);
+ size_t iLeft = iSize;
+ size_t oLeft = oSize;
+ char *iPtr = s.data();
+ char *oPtr = output.data();
+ if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft))
+ {
+ oSize -= (int)oLeft;
+ output.resize(oSize+1);
+ output.at(oSize)='\0';
+ return output;
+ }
+ else
+ {
+ return s;
+ }
+}
+
+/*! Add an list item to the contents file.
+ * \param isDir boolean indicating if this is a dir or file entry
+ * \param name the name of the item.
+ * \param ref the URL of to the item.
+ * \param file the file in which the item is defined.
+ * \param anchor the anchor of the item.
+ * \param separateIndex not used.
+ * \param addToNavIndex not used.
+ * \param def not used.
+ */
+void HtmlHelp::addContentsItem(bool isDir,
+ const char *name,
+ const char * /*ref*/,
+ const char *file,
+ const char *anchor,
+ bool /* separateIndex */,
+ bool /* addToNavIndex */,
+ Definition * /* def */)
+{
+ // If we're using a binary toc then folders cannot have links.
+ // Tried this and I didn't see any problems, when not using
+ // the resetting of file and anchor the TOC works better
+ // (prev / next button)
+ //if(Config_getBool("BINARY_TOC") && isDir)
+ //{
+ //file = 0;
+ //anchor = 0;
+ //}
+ int i; for (i=0;i<dc;i++) cts << " ";
+ cts << "<LI><OBJECT type=\"text/sitemap\">";
+ cts << "<param name=\"Name\" value=\"" << convertToHtml(recode(name),TRUE) << "\">";
+ if (file) // made file optional param - KPW
+ {
+ if (file && (file[0]=='!' || file[0]=='^')) // special markers for user defined URLs
+ {
+ cts << "<param name=\"";
+ if (file[0]=='^') cts << "URL"; else cts << "Local";
+ cts << "\" value=\"";
+ cts << &file[1];
+ }
+ else
+ {
+ cts << "<param name=\"Local\" value=\"";
+ cts << file << Doxygen::htmlFileExtension;
+ if (anchor) cts << "#" << anchor;
+ }
+ cts << "\">";
+ }
+ cts << "<param name=\"ImageNumber\" value=\"";
+ if (isDir) // added - KPW
+ {
+ cts << (int)BOOK_CLOSED ;
+ }
+ else
+ {
+ cts << (int)TEXT;
+ }
+ cts << "\">";
+ cts << "</OBJECT>\n";
+}
+
+
+void HtmlHelp::addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor,const char *word)
+{
+ if (md)
+ {
+ static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ if (context==0) // global member
+ {
+ if (md->getGroupDef())
+ context = md->getGroupDef();
+ else if (md->getFileDef())
+ context = md->getFileDef();
+ }
+ if (context==0) return; // should not happen
+
+ QCString cfname = md->getOutputFileBase();
+ QCString cfiname = context->getOutputFileBase();
+ QCString level1 = context->name();
+ QCString level2 = md->name();
+ QCString contRef = separateMemberPages ? cfname : cfiname;
+ QCString memRef = cfname;
+ QCString anchor = sectionAnchor ? QCString(sectionAnchor) : md->anchor();
+ index->addItem(level1,level2,contRef,anchor,TRUE,FALSE);
+ index->addItem(level2,level1,memRef,anchor,TRUE,TRUE);
+ }
+ else if (context)
+ {
+ QCString level1 = word ? QCString(word) : context->name();
+ index->addItem(level1,0,context->getOutputFileBase(),sectionAnchor,TRUE,FALSE);
+ }
+}
+
+void HtmlHelp::addImageFile(const char *fileName)
+{
+ if (!imageFiles.contains(fileName)) imageFiles.append(fileName);
+}
+
diff --git a/src/htmlhelp.h b/src/htmlhelp.h
new file mode 100644
index 0000000..574cec9
--- /dev/null
+++ b/src/htmlhelp.h
@@ -0,0 +1,105 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The code is this file is largely based on a contribution from
+ * Harm van der Heijden <H.v.d.Heijden at phys.tue.nl>
+ * Please send thanks to him and bug reports to me :-)
+ */
+
+#ifndef HTMLHELP_H
+#define HTMLHELP_H
+
+#include <qstrlist.h>
+#include <qdict.h>
+#include "index.h"
+#include "ftextstream.h"
+
+class QFile;
+class Definition;
+class HtmlHelpIndex;
+
+/** A class that generated the HTML Help specific files.
+ *
+ * These files can be used with the Microsoft HTML Help workshop
+ * to generate compressed HTML files (.chm).
+ */
+class HtmlHelp : public IndexIntf
+{
+ /*! used in imageNumber param of HTMLHelp::addContentsItem() function
+ to specify document icon in tree view.
+ Writes \<param name="ImageNumber" value="xx"\> in .HHC file. */
+ enum ImageNumber {
+ BOOK_CLOSED=1, BOOK_OPEN,
+ BOOK_CLOSED_NEW, BOOK_OPEN_NEW,
+ FOLDER_CLOSED, FOLDER_OPEN,
+ FOLDER_CLOSED_NEW,FOLDER_OPEN_NEW,
+ QUERY, QUERY_NEW,
+ TEXT, TEXT_NEW,
+ WEB_DOC, WEB_DOC_NEW,
+ WEB_LINK, WEB_LINK_NEW,
+ INFO, INFO_NEW,
+ LINK, LINK_NEW,
+ BOOKLET, BOOKLET_NEW,
+ EMAIL, EMAIL_NEW,
+ EMAIL2, EMAIL2_NEW,
+ IMAGE, IMAGE_NEW,
+ AUDIO, AUDIO_NEW,
+ MUSIC, MUSIC_NEW,
+ VIDEO, VIDEO_NEW,
+ INDEX, INDEX_NEW,
+ IDEA, IDEA_NEW,
+ NOTE, NOTE_NEW,
+ TOOL, TOOL_NEW
+ };
+ public:
+ //static HtmlHelp *getInstance();
+ HtmlHelp();
+ ~HtmlHelp();
+ void initialize();
+ void finalize();
+ void incContentsDepth();
+ void decContentsDepth();
+ void addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool separateIndex,
+ bool addToNavIndex,
+ Definition *def);
+ void addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor, const char *title);
+ void addIndexFile(const char *name);
+ void addImageFile(const char *);
+ void addStyleSheetFile(const char *) {}
+
+ private:
+ friend class HtmlHelpIndex;
+ void createProjectFile();
+
+ QFile *cf,*kf;
+ FTextStream cts,kts;
+ HtmlHelpIndex *index;
+ int dc;
+ QStrList indexFiles;
+ QStrList imageFiles;
+ QDict<void> indexFileDict;
+ static HtmlHelp *theInstance;
+ QCString recode(const QCString &s);
+ void *m_fromUtf8;
+};
+
+#endif /* HTMLHELP_H */
+
diff --git a/src/image.cpp b/src/image.cpp
new file mode 100644
index 0000000..3283754
--- /dev/null
+++ b/src/image.cpp
@@ -0,0 +1,540 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "image.h"
+#include <qfile.h>
+#include <math.h>
+#include "lodepng.h"
+#include "config.h"
+
+typedef unsigned char Byte;
+
+/** Helper struct representing a RGBA color */
+struct Color
+{
+ Byte red;
+ Byte green;
+ Byte blue;
+ Byte alpha;
+};
+
+const int charSetWidth=80;
+const int charHeight=12;
+const int numChars=96;
+
+unsigned short charPos[numChars] =
+ {
+ 0, 5, 8, 13, 20, 27, 38, 47,
+ 50, 54, 58, 65, 72, 76, 83, 87,
+ 91, 98,105,112,119,126,133,140,
+ 147,154,161,164,167,174,181,188,
+ 195,207,216,224,233,242,250,258,
+ 267,276,279,286,294,301,312,321,
+ 331,339,349,357,365,372,380,389,
+ 400,409,418,427,430,434,437,443,
+ 450,453,460,467,474,481,488,492,
+ 499,506,509,512,518,521,530,537,
+ 544,551,557,562,568,571,578,585,
+ 594,600,607,613,617,620,624,631
+ };
+
+unsigned char charWidth[numChars] =
+ {
+ 5, 3, 5, 7, 7,11, 9, 3,
+ 4, 4, 7, 7, 4, 7, 4, 4,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 3, 3, 7, 7, 7, 7,
+ 12, 9, 8, 9, 9, 8, 8, 9,
+ 9, 3, 7, 8, 7,11, 9,10,
+ 8,10, 8, 8, 7, 8, 9,11,
+ 9, 9, 9, 3, 4, 3, 6, 7,
+ 3, 7, 7, 7, 7, 7, 4, 7,
+ 7, 3, 3, 6, 3, 9, 7, 7,
+ 7, 6, 5, 6, 3, 7, 7, 9,
+ 6, 7, 6, 4, 3, 4, 7, 5
+ };
+
+unsigned char fontRaw[charSetWidth*charHeight] = {
+ 0x02, 0x50, 0x01, 0x06, 0x20, 0x60, 0xc6, 0x04, 0x00, 0x00, 0x00, 0x27,
+ 0x04, 0x1c, 0x38, 0x11, 0xf1, 0xc7, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x03,
+ 0x81, 0xf0, 0x10, 0x7c, 0x1e, 0x3e, 0x1f, 0x9f, 0x87, 0x88, 0x24, 0x09,
+ 0x09, 0x02, 0x02, 0x41, 0x0f, 0x0f, 0x83, 0xc3, 0xe1, 0xe7, 0xf4, 0x24,
+ 0x12, 0x22, 0x41, 0x20, 0x9f, 0xce, 0x30, 0x00, 0x10, 0x04, 0x00, 0x01,
+ 0x00, 0x30, 0x08, 0x12, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x02, 0x51, 0x43, 0x89,
+ 0x40, 0x90, 0x49, 0x15, 0x00, 0x00, 0x00, 0x28, 0x9c, 0x22, 0x44, 0x31,
+ 0x02, 0x20, 0x48, 0x91, 0x00, 0x00, 0x00, 0x04, 0x46, 0x08, 0x28, 0x42,
+ 0x21, 0x21, 0x10, 0x10, 0x08, 0x48, 0x24, 0x09, 0x11, 0x03, 0x06, 0x61,
+ 0x10, 0x88, 0x44, 0x22, 0x12, 0x10, 0x84, 0x24, 0x12, 0x22, 0x22, 0x20,
+ 0x80, 0x4a, 0x11, 0x00, 0x20, 0x04, 0x00, 0x01, 0x00, 0x40, 0x08, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x22, 0x00, 0x00, 0x02, 0x51, 0x45, 0x49, 0x40, 0x90, 0x89, 0x0a,
+ 0x00, 0x00, 0x00, 0x48, 0x84, 0x02, 0x04, 0x51, 0x02, 0x00, 0x88, 0x91,
+ 0x00, 0x00, 0x00, 0x04, 0x44, 0xd4, 0x28, 0x42, 0x40, 0x20, 0x90, 0x10,
+ 0x10, 0x08, 0x24, 0x09, 0x21, 0x03, 0x06, 0x51, 0x20, 0x48, 0x48, 0x12,
+ 0x12, 0x00, 0x84, 0x22, 0x22, 0x22, 0x22, 0x11, 0x00, 0x89, 0x12, 0x80,
+ 0x31, 0xc5, 0x87, 0x0d, 0x1c, 0xe3, 0x4b, 0x12, 0x49, 0x29, 0x16, 0x1c,
+ 0x58, 0x69, 0x4c, 0xe8, 0x91, 0x44, 0x61, 0x44, 0xf2, 0x22, 0x00, 0x00,
+ 0x02, 0x07, 0xe5, 0x06, 0x80, 0x60, 0x10, 0x95, 0x08, 0x00, 0x00, 0x48,
+ 0x84, 0x04, 0x18, 0x51, 0xe2, 0xc0, 0x87, 0x11, 0x24, 0x18, 0x03, 0x00,
+ 0x89, 0x24, 0x44, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x08, 0x24, 0x09,
+ 0x41, 0x02, 0x8a, 0x51, 0x20, 0x48, 0x48, 0x12, 0x11, 0x80, 0x84, 0x22,
+ 0x21, 0x24, 0x14, 0x11, 0x01, 0x09, 0x14, 0x40, 0x02, 0x26, 0x48, 0x93,
+ 0x22, 0x44, 0xcc, 0x92, 0x51, 0x36, 0x99, 0x22, 0x64, 0x99, 0x92, 0x48,
+ 0x91, 0x44, 0x52, 0x44, 0x12, 0x22, 0x00, 0x00, 0x02, 0x01, 0x43, 0x80,
+ 0x80, 0xa0, 0x10, 0x84, 0x08, 0x00, 0x00, 0x88, 0x84, 0x08, 0x04, 0x90,
+ 0x13, 0x21, 0x08, 0x8f, 0x00, 0x61, 0xf0, 0xc0, 0x8a, 0x24, 0x44, 0x7c,
+ 0x40, 0x20, 0x9f, 0x9f, 0x11, 0xcf, 0xe4, 0x09, 0xc1, 0x02, 0x8a, 0x49,
+ 0x20, 0x4f, 0x88, 0x13, 0xe0, 0x60, 0x84, 0x22, 0x21, 0x54, 0x08, 0x0a,
+ 0x02, 0x08, 0x90, 0x00, 0x00, 0x24, 0x48, 0x11, 0x22, 0x44, 0x48, 0x92,
+ 0x61, 0x24, 0x91, 0x22, 0x44, 0x89, 0x10, 0x48, 0x91, 0x24, 0x8c, 0x44,
+ 0x22, 0x22, 0x64, 0x00, 0x02, 0x07, 0xe1, 0x41, 0x31, 0x14, 0x10, 0x80,
+ 0x3e, 0x07, 0xc0, 0x88, 0x84, 0x10, 0x05, 0x10, 0x12, 0x21, 0x08, 0x81,
+ 0x01, 0x80, 0x00, 0x31, 0x0a, 0x24, 0x7c, 0x42, 0x40, 0x20, 0x90, 0x10,
+ 0x10, 0x48, 0x24, 0x09, 0x21, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x92,
+ 0x20, 0x10, 0x84, 0x21, 0x41, 0x54, 0x14, 0x04, 0x04, 0x08, 0x90, 0x00,
+ 0x01, 0xe4, 0x48, 0x11, 0x3e, 0x44, 0x48, 0x92, 0x61, 0x24, 0x91, 0x22,
+ 0x44, 0x89, 0x0c, 0x48, 0x8a, 0x24, 0x8c, 0x48, 0x44, 0x21, 0x98, 0x00,
+ 0x02, 0x02, 0x85, 0x41, 0x49, 0x08, 0x10, 0x80, 0x08, 0x00, 0x00, 0x88,
+ 0x84, 0x20, 0x45, 0xf9, 0x12, 0x21, 0x08, 0x81, 0x00, 0x61, 0xf0, 0xc1,
+ 0x0a, 0x68, 0x82, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x48, 0x24, 0x89,
+ 0x11, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x52, 0x12, 0x10, 0x84, 0x21,
+ 0x40, 0x88, 0x22, 0x04, 0x08, 0x08, 0x90, 0x00, 0x02, 0x24, 0x48, 0x11,
+ 0x20, 0x44, 0x48, 0x92, 0x51, 0x24, 0x91, 0x22, 0x44, 0x89, 0x02, 0x48,
+ 0x8a, 0x2a, 0x92, 0x28, 0x42, 0x22, 0x00, 0x00, 0x00, 0x02, 0x85, 0x41,
+ 0x49, 0x18, 0x10, 0x80, 0x08, 0x00, 0x01, 0x08, 0x84, 0x20, 0x44, 0x11,
+ 0x12, 0x22, 0x08, 0x91, 0x00, 0x18, 0x03, 0x00, 0x09, 0xb0, 0x82, 0x42,
+ 0x21, 0x21, 0x10, 0x10, 0x08, 0xc8, 0x24, 0x89, 0x09, 0x02, 0x22, 0x43,
+ 0x10, 0x88, 0x04, 0x22, 0x12, 0x10, 0x84, 0x20, 0x80, 0x88, 0x22, 0x04,
+ 0x10, 0x08, 0x50, 0x00, 0x02, 0x26, 0x48, 0x93, 0x22, 0x44, 0xc8, 0x92,
+ 0x49, 0x24, 0x91, 0x22, 0x64, 0x99, 0x12, 0x49, 0x84, 0x11, 0x21, 0x28,
+ 0x82, 0x22, 0x00, 0x00, 0x02, 0x02, 0x83, 0x82, 0x30, 0xe4, 0x10, 0x80,
+ 0x00, 0x20, 0x05, 0x07, 0x04, 0x3e, 0x38, 0x10, 0xe1, 0xc2, 0x07, 0x0e,
+ 0x24, 0x00, 0x00, 0x01, 0x04, 0x00, 0x82, 0x7c, 0x1e, 0x3e, 0x1f, 0x90,
+ 0x07, 0x48, 0x24, 0x71, 0x05, 0xf2, 0x22, 0x41, 0x0f, 0x08, 0x03, 0xd2,
+ 0x11, 0xe0, 0x83, 0xc0, 0x80, 0x88, 0x41, 0x04, 0x1f, 0xc8, 0x50, 0x00,
+ 0x01, 0xd5, 0x87, 0x0d, 0x1c, 0x43, 0x48, 0x92, 0x45, 0x24, 0x91, 0x1c,
+ 0x58, 0x69, 0x0c, 0x66, 0x84, 0x11, 0x21, 0x10, 0xf2, 0x22, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x10, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xac, 0x00, 0x00
+};
+
+static Color palette[] =
+{
+ { 0xff, 0xff, 0xff, 0x00 },
+ { 0x00, 0x00, 0x00, 0xff },
+ { 0xff, 0xff, 0xc0, 0xff },
+ { 0x9f, 0x9f, 0x60, 0xff },
+ { 0x90, 0x00, 0x00, 0xff },
+ { 0x00, 0x90, 0x00, 0xff },
+ { 0x00, 0x00, 0x90, 0xff },
+ { 0xc0, 0xc0, 0xc0, 0xff }
+};
+
+// for alpha we use x^(1/1.3)
+static Color palette2[] =
+{
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x2e },
+ { 0x00, 0x00, 0x00, 0x48 },
+ { 0x00, 0x00, 0x00, 0x5d },
+ { 0x00, 0x00, 0x00, 0x6f },
+ { 0x00, 0x00, 0x00, 0x80 },
+ { 0x00, 0x00, 0x00, 0x8f },
+ { 0x00, 0x00, 0x00, 0x9e },
+ { 0x00, 0x00, 0x00, 0xac },
+ { 0x00, 0x00, 0x00, 0xb9 },
+ { 0x00, 0x00, 0x00, 0xc5 },
+ { 0x00, 0x00, 0x00, 0xd2 },
+ { 0x00, 0x00, 0x00, 0xdd },
+ { 0x00, 0x00, 0x00, 0xe9 },
+ { 0x00, 0x00, 0x00, 0xf4 },
+ { 0x00, 0x00, 0x00, 0xff }
+};
+
+static Color palette3[] =
+{
+ { 0xff, 0xff, 0xff, 0xff },
+ { 0xe0, 0xe0, 0xe0, 0xff },
+ { 0xd0, 0xd0, 0xd0, 0xff },
+ { 0xc0, 0xc0, 0xc0, 0xff },
+ { 0xb0, 0xb0, 0xb0, 0xff },
+ { 0xa0, 0xa0, 0xa0, 0xff },
+ { 0x90, 0x90, 0x90, 0xff },
+ { 0x80, 0x80, 0x80, 0xff },
+ { 0x70, 0x70, 0x70, 0xff },
+ { 0x60, 0x60, 0x60, 0xff },
+ { 0x50, 0x50, 0x50, 0xff },
+ { 0x40, 0x40, 0x40, 0xff },
+ { 0x30, 0x30, 0x30, 0xff },
+ { 0x20, 0x20, 0x20, 0xff },
+ { 0x10, 0x10, 0x10, 0xff },
+ { 0x00, 0x00, 0x00, 0xff }
+};
+
+
+Image::Image(int w,int h)
+{
+ static int hue = Config_getInt("HTML_COLORSTYLE_HUE");
+ static int sat = Config_getInt("HTML_COLORSTYLE_SAT");
+ static int gamma = Config_getInt("HTML_COLORSTYLE_GAMMA");
+
+ double red1,green1,blue1;
+ double red2,green2,blue2;
+
+ ColoredImage::hsl2rgb(hue/360.0, // hue
+ sat/255.0, // saturation
+ pow(235/255.0,gamma/100.0), // luma (gamma corrected)
+ &red1,&green1,&blue1
+ );
+
+ ColoredImage::hsl2rgb(hue/360.0, // hue
+ sat/255.0, // saturation
+ pow(138/255.0,gamma/100.0), // luma (gamma corrected)
+ &red2,&green2,&blue2
+ );
+
+ palette[2].red = (int)(red1 * 255.0);
+ palette[2].green = (int)(green1 * 255.0);
+ palette[2].blue = (int)(blue1 * 255.0);
+
+ palette[3].red = (int)(red2 * 255.0);
+ palette[3].green = (int)(green2 * 255.0);
+ palette[3].blue = (int)(blue2 * 255.0);
+
+ data = new uchar[w*h];
+ memset(data,0,w*h);
+ width = w;
+ height = h;
+}
+
+Image::~Image()
+{
+ delete[] data;
+}
+
+void Image::setPixel(int x,int y,uchar val)
+{
+ if (x>=0 && x<width && y>=0 && y<height)
+ data[y*width+x] = val;
+}
+
+uchar Image::getPixel(int x,int y) const
+{
+ if (x>=0 && x<width && y>=0 && y<height)
+ return data[y*width+x];
+ else
+ return 0;
+}
+
+void Image::writeChar(int x,int y,char c,uchar fg)
+{
+ if (c>=' ')
+ {
+ int xf,yf,ci=c-' ';
+ int rowOffset=0;
+ int cw = charWidth[ci];
+ int cp = charPos[ci];
+ for (yf=0;yf<charHeight;yf++)
+ {
+ unsigned short bitPattern=0;
+ int bitsLeft=cw;
+ int byteOffset = rowOffset+(cp>>3);
+ int bitOffset = cp&7;
+ // get the bit pattern for row yf of the character from the font data
+ while (bitsLeft>0)
+ {
+ int bits=8-bitOffset;
+ if (bits>bitsLeft) bits=bitsLeft;
+ bitPattern<<=bits;
+ bitPattern|=((fontRaw[byteOffset]<<bitOffset)&0xff)>>(8-bits);
+ bitsLeft-=bits;
+ bitOffset=0;
+ byteOffset++;
+ }
+ int mask=1<<(cw-1);
+ // draw character row yf
+ for (xf=0;xf<cw;xf++)
+ {
+ setPixel(x+xf,y+yf,(bitPattern&mask) ? fg : getPixel(x+xf,y+yf));
+ mask>>=1;
+ }
+ rowOffset+=charSetWidth;
+ }
+ }
+}
+
+void Image::writeString(int x,int y,const char *s,uchar fg)
+{
+ if (s)
+ {
+ char c;
+ while ((c=*s++))
+ {
+ writeChar(x,y,c,fg);
+ x+=charWidth[c-' '];
+ }
+ }
+}
+
+uint Image::stringLength(const char *s)
+{
+ int w=0;
+ if (s)
+ {
+ char c;
+ while ((c=*s++)) w+=charWidth[c-' '];
+ }
+ return w;
+}
+
+void Image::drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask)
+{
+ int x,i=0,j=0;
+ for (x=xs;x<=xe;x++,j++)
+ {
+ if (j&1) i++;
+ if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
+ }
+}
+
+void Image::drawHorzArrow(int y,int xs,int xe,uchar colIndex,uint mask)
+{
+ drawHorzLine(y,xs,xe,colIndex,mask);
+ int i;
+ for (i=0;i<6;i++)
+ {
+ int h=i>>1;
+ drawVertLine(xe-i,y-h,y+h,colIndex,0xffffffff);
+ }
+}
+
+void Image::drawVertLine(int x,int ys,int ye,uchar colIndex,uint mask)
+{
+ int y,i=0;
+ for (y=ys;y<=ye;y++,i++)
+ {
+ if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
+ }
+}
+
+void Image::drawVertArrow(int x,int ys,int ye,uchar colIndex,uint mask)
+{
+ drawVertLine(x,ys,ye,colIndex,mask);
+ int i;
+ for (i=0;i<6;i++)
+ {
+ int h=i>>1;
+ drawHorzLine(ys+i,x-h,x+h,colIndex,0xffffffff);
+ }
+}
+
+void Image::drawRect(int x,int y,int w,int h,uchar colIndex,uint mask)
+{
+ drawHorzLine(y,x,x+w-1,colIndex,mask);
+ drawHorzLine(y+h-1,x,x+w-1,colIndex,mask);
+ drawVertLine(x,y,y+h-1,colIndex,mask);
+ drawVertLine(x+w-1,y,y+h-1,colIndex,mask);
+}
+
+void Image::fillRect(int x,int y,int lwidth,int lheight,uchar colIndex,uint mask)
+{
+ int xp,yp,xi,yi;
+ for (yp=y,yi=0;yp<y+lheight;yp++,yi++)
+ for (xp=x,xi=0;xp<x+lwidth;xp++,xi++)
+ if (mask&(1<<((xi+yi)&0x1f)))
+ setPixel(xp,yp,colIndex);
+}
+
+bool Image::save(const char *fileName,int mode)
+{
+#if 0
+ GifEncoder gifenc(data,
+ mode==0 ? palette : palette2,
+ width,height,
+ mode==0 ? 3 : 4,
+ 0);
+ QFile file(fileName);
+ if (file.open(IO_WriteOnly))
+ {
+ gifenc.writeGIF(file);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+#endif
+ static bool useTransparency = Config_getBool("FORMULA_TRANSPARENT");
+ uchar* buffer;
+ size_t bufferSize;
+ LodePNG_Encoder encoder;
+ LodePNG_Encoder_init(&encoder);
+ int numCols = mode==0 ? 8 : 16;
+ Color *pPal = mode==0 ? palette :
+ useTransparency ? palette2 :
+ palette3 ;
+ int i;
+ for (i=0;i<numCols;i++,pPal++)
+ {
+ LodePNG_InfoColor_addPalette(&encoder.infoPng.color,
+ pPal->red,pPal->green,pPal->blue,pPal->alpha);
+ }
+ encoder.infoPng.color.colorType = 3;
+ encoder.infoRaw.color.colorType = 3;
+ LodePNG_encode(&encoder, &buffer, &bufferSize, data, width, height);
+ LodePNG_saveFile(buffer, bufferSize, fileName);
+ free(buffer);
+ LodePNG_Encoder_cleanup(&encoder);
+ return TRUE;
+}
+
+//----------------------------------------------------------------
+
+void ColoredImage::hsl2rgb(double h,double s,double l,
+ double *pRed,double *pGreen,double *pBlue)
+{
+ double v;
+ double r,g,b;
+
+ r = l; // default to gray
+ g = l;
+ b = l;
+ v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
+ if (v > 0)
+ {
+ double m;
+ double sv;
+ int sextant;
+ double fract, vsf, mid1, mid2;
+
+ m = l + l - v;
+ sv = (v - m ) / v;
+ h *= 6.0;
+ sextant = (int)h;
+ fract = h - sextant;
+ vsf = v * sv * fract;
+ mid1 = m + vsf;
+ mid2 = v - vsf;
+ switch (sextant)
+ {
+ case 0:
+ r = v;
+ g = mid1;
+ b = m;
+ break;
+ case 1:
+ r = mid2;
+ g = v;
+ b = m;
+ break;
+ case 2:
+ r = m;
+ g = v;
+ b = mid1;
+ break;
+ case 3:
+ r = m;
+ g = mid2;
+ b = v;
+ break;
+ case 4:
+ r = mid1;
+ g = m;
+ b = v;
+ break;
+ case 5:
+ r = v;
+ g = m;
+ b = mid2;
+ break;
+ }
+ }
+ *pRed = r;
+ *pGreen = g;
+ *pBlue = b;
+}
+
+ColoredImage::ColoredImage(int width,int height,
+ const uchar *greyLevels,const uchar *alphaLevels,
+ int saturation,int hue,int gamma)
+{
+ m_hasAlpha = alphaLevels!=0;
+ m_width = width;
+ m_height = height;
+ m_data = (uchar*)malloc(width*height*4);
+ int i;
+ for (i=0;i<width*height;i++)
+ {
+ uchar r,g,b,a;
+ double red,green,blue;
+ hsl2rgb(hue/360.0, // hue
+ saturation/255.0, // saturation
+ pow(greyLevels[i]/255.0,gamma/100.0), // luma (gamma corrected)
+ &red,&green,&blue);
+ r = (int)(red *255.0);
+ g = (int)(green*255.0);
+ b = (int)(blue *255.0);
+ a = alphaLevels ? alphaLevels[i] : 255;
+ m_data[i*4+0]=r;
+ m_data[i*4+1]=g;
+ m_data[i*4+2]=b;
+ m_data[i*4+3]=a;
+ }
+}
+
+ColoredImage::~ColoredImage()
+{
+ free(m_data);
+}
+
+bool ColoredImage::save(const char *fileName)
+{
+ uchar *buffer;
+ size_t bufferSize;
+ LodePNG_Encoder encoder;
+ LodePNG_Encoder_init(&encoder);
+ encoder.infoPng.color.colorType = m_hasAlpha ? 6 : 2; // 2=RGB 24 bit, 6=RGBA 32 bit
+ encoder.infoRaw.color.colorType = 6; // 6=RGBA 32 bit
+ LodePNG_encode(&encoder, &buffer, &bufferSize, m_data, m_width, m_height);
+ LodePNG_saveFile(buffer, bufferSize, fileName);
+ LodePNG_Encoder_cleanup(&encoder);
+ free(buffer);
+ return TRUE;
+}
+
+
diff --git a/src/image.h b/src/image.h
new file mode 100644
index 0000000..ad11a64
--- /dev/null
+++ b/src/image.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _IMAGE_H
+#define _IMAGE_H
+#include <qglobal.h>
+
+/** Class representing a bitmap image generated by doxygen. */
+class Image
+{
+ public:
+ Image(int w,int h);
+ ~Image();
+
+ void setPixel(int x,int y,uchar val);
+ uchar getPixel(int x,int y) const;
+ void writeChar(int x,int y,char c,uchar fg);
+ void writeString(int x,int y,const char *s,uchar fg);
+ void drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask);
+ void drawHorzArrow(int y,int xs,int xe,uchar colIndex,uint mask);
+ void drawVertLine(int x,int ys,int ye,uchar colIndex,uint mask);
+ void drawVertArrow(int x,int ys,int ye,uchar colIndex,uint mask);
+ void drawRect(int x,int y,int width,int height,uchar colIndex,uint mask);
+ void fillRect(int x,int y,int width,int height,uchar colIndex,uint mask);
+ bool save(const char *fileName,int mode=0);
+ friend uint stringLength(const char *s);
+ uint getWidth() const { return width; }
+ uint getHeight() const { return height; }
+ uchar *getData() const { return data; }
+ static uint stringLength(const char *s);
+
+ private:
+ int width;
+ int height;
+ uchar *data;
+};
+
+/** Class representing a bitmap image colored based on hue/sat/gamma settings. */
+class ColoredImage
+{
+ public:
+ ColoredImage(int width,int height,
+ const uchar *greyLevels,const uchar *alphaLevels,
+ int saturation,int hue,int gamma);
+ ~ColoredImage();
+ bool save(const char *fileName);
+ static void hsl2rgb(double h,double s,double l,
+ double *pRed,double *pGreen,double *pBlue);
+ private:
+ int m_width;
+ int m_height;
+ uchar *m_data;
+ bool m_hasAlpha;
+};
+
+#endif
diff --git a/src/increasebuffer.py b/src/increasebuffer.py
new file mode 100755
index 0000000..e2b2d0c
--- /dev/null
+++ b/src/increasebuffer.py
@@ -0,0 +1,7 @@
+# Since the internal token buffer of a generated flex file is hardcoded
+# to 16K, this script is used to increase the buffer size of a flex
+# generated scanner to 256K.
+import sys
+sys.stdout.write(sys.stdin.read().
+ replace('YY_BUF_SIZE 16384','YY_BUF_SIZE 262144').
+ replace('YY_READ_BUF_SIZE 8192','YY_READ_BUF_SIZE 262144'))
diff --git a/src/index.cpp b/src/index.cpp
new file mode 100644
index 0000000..430f5af
--- /dev/null
+++ b/src/index.cpp
@@ -0,0 +1,4272 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/** @file
+ * @brief This file contains functions for the various index pages.
+ */
+
+#include <stdlib.h>
+
+#include <qtextstream.h>
+#include <qdatetime.h>
+#include <qdir.h>
+#include <qregexp.h>
+
+#include "message.h"
+#include "index.h"
+#include "doxygen.h"
+#include "config.h"
+#include "filedef.h"
+#include "outputlist.h"
+#include "util.h"
+#include "groupdef.h"
+#include "language.h"
+#include "htmlgen.h"
+#include "htmlhelp.h"
+#include "ftvhelp.h"
+#include "dot.h"
+#include "pagedef.h"
+#include "dirdef.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "memberlist.h"
+#include "classlist.h"
+#include "namespacedef.h"
+#include "filename.h"
+
+#define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
+#define MAX_ITEMS_BEFORE_QUICK_INDEX 30
+
+
+int annotatedClasses;
+int annotatedClassesPrinted;
+int hierarchyClasses;
+int documentedFiles;
+int documentedGroups;
+int documentedNamespaces;
+int indexedPages;
+int documentedClassMembers[CMHL_Total];
+int documentedFileMembers[FMHL_Total];
+int documentedNamespaceMembers[NMHL_Total];
+int documentedHtmlFiles;
+int documentedPages;
+int documentedDirs;
+
+static int countClassHierarchy();
+static void countFiles(int &htmlFiles,int &files);
+static int countGroups();
+static int countDirs();
+static int countNamespaces();
+static int countAnnotatedClasses(int *cp);
+static void countRelatedPages(int &docPages,int &indexPages);
+
+void countDataStructures()
+{
+ annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated"
+ hierarchyClasses = countClassHierarchy(); // "hierarchy"
+ countFiles(documentedHtmlFiles,documentedFiles); // "files"
+ countRelatedPages(documentedPages,indexedPages); // "pages"
+ documentedGroups = countGroups(); // "modules"
+ documentedNamespaces = countNamespaces(); // "namespaces"
+ documentedDirs = countDirs(); // "dirs"
+ // "globals"
+ // "namespacemembers"
+ // "functions"
+}
+
+static void startIndexHierarchy(OutputList &ol,int level)
+{
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Html);
+ if (level<6) ol.startIndexList();
+ ol.enableAll();
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ ol.startItemList();
+ ol.popGeneratorState();
+}
+
+static void endIndexHierarchy(OutputList &ol,int level)
+{
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Html);
+ if (level<6) ol.endIndexList();
+ ol.enableAll();
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ ol.endItemList();
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+
+class MemberIndexList : public QList<MemberDef>
+{
+ public:
+ typedef MemberDef ElementType;
+ MemberIndexList(uint letter) : QList<MemberDef>(), m_letter(letter) {}
+ ~MemberIndexList() {}
+ int compareValues(const MemberDef *md1, const MemberDef *md2) const
+ {
+ int result = qstricmp(md1->name(),md2->name());
+ if (result==0)
+ {
+ result = qstricmp(md1->qualifiedName(),md2->qualifiedName());
+ }
+ return result;
+ }
+ uint letter() const { return m_letter; }
+ private:
+ uint m_letter;
+};
+
+static LetterToIndexMap<MemberIndexList> g_memberIndexLetterUsed[CMHL_Total];
+static LetterToIndexMap<MemberIndexList> g_fileIndexLetterUsed[FMHL_Total];
+static LetterToIndexMap<MemberIndexList> g_namespaceIndexLetterUsed[NMHL_Total];
+
+const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
+
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+
+static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
+{
+ bool fancyTabs = TRUE;
+ if (fancyTabs)
+ {
+ if (letterTabs)
+ {
+ ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
+ }
+ else
+ {
+ ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
+ }
+ ol.writeString(" <ul class=\"tablist\">\n");
+ }
+ else
+ {
+ ol.writeString(" <div class=\"qindex\">");
+ }
+}
+
+static void endQuickIndexList(OutputList &ol)
+{
+ bool fancyTabs = TRUE;
+ if (fancyTabs)
+ {
+ ol.writeString(" </ul>\n");
+ }
+ ol.writeString(" </div>\n");
+}
+
+static void startQuickIndexItem(OutputList &ol,const char *l,
+ bool hl,bool compact,bool &first)
+{
+ bool fancyTabs = TRUE;
+ if (!first && compact && !fancyTabs) ol.writeString(" | ");
+ first=FALSE;
+ if (fancyTabs)
+ {
+ ol.writeString(" <li");
+ if (hl) ol.writeString(" class=\"current\"");
+ ol.writeString("><a ");
+ }
+ else
+ {
+ if (!compact) ol.writeString("<li>");
+ if (hl && compact)
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ }
+ ol.writeString("href=\"");
+ ol.writeString(l);
+ ol.writeString("\">");
+ if (fancyTabs)
+ {
+ ol.writeString("<span>");
+ }
+}
+
+static void endQuickIndexItem(OutputList &ol)
+{
+ bool fancyTabs=TRUE;
+ if (fancyTabs) ol.writeString("</span>");
+ ol.writeString("</a>");
+ if (fancyTabs) ol.writeString("</li>\n");
+}
+
+// don't make this static as it is called from a template function and some
+// old compilers don't support calls to static functions from a template.
+QCString fixSpaces(const QCString &s)
+{
+ return substitute(s," "," ");
+}
+
+void startTitle(OutputList &ol,const char *fileName,Definition *def)
+{
+ ol.startHeaderSection();
+ if (def) def->writeSummaryLinks(ol);
+ ol.startTitleHead(fileName);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+}
+
+void endTitle(OutputList &ol,const char *fileName,const char *name)
+{
+ ol.popGeneratorState();
+ ol.endTitleHead(fileName,name);
+ ol.endHeaderSection();
+}
+
+void startFile(OutputList &ol,const char *name,const char *manName,
+ const char *title,HighlightedItem hli,bool additionalIndices,
+ const char *altSidebarName)
+{
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+ ol.startFile(name,manName,title);
+ ol.startQuickIndices();
+ if (!disableIndex)
+ {
+ ol.writeQuickLinks(TRUE,hli,name);
+ }
+ if (!additionalIndices)
+ {
+ ol.endQuickIndices();
+ }
+ ol.writeSplitBar(altSidebarName ? altSidebarName : name);
+ ol.writeSearchInfo();
+}
+
+void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents,
+ const QCString &navPath)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ if (!skipNavIndex)
+ {
+ if (!skipEndContents) ol.endContents();
+ if (generateTreeView)
+ {
+ ol.writeString("</div><!-- doc-content -->\n");
+ }
+ }
+ ol.writeFooter(navPath); // write the footer
+ ol.popGeneratorState();
+ ol.endFile();
+}
+
+void endFileWithNavPath(Definition *d,OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ QCString navPath;
+ if (generateTreeView)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString("</div><!-- doc-content -->\n");
+ ol.popGeneratorState();
+ navPath = d->navigationPathAsString();
+ }
+ endFile(ol,generateTreeView,TRUE,navPath);
+}
+
+//----------------------------------------------------------------------
+template<class T>
+void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
+ const QCString &name,const QCString &anchor,
+ bool addToIndex=TRUE,bool preventSeparateIndex=FALSE)
+{
+ bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
+ Doxygen::indexList->addContentsItem(hasMembers,name,
+ def->getReference(),def->getOutputFileBase(),anchor,
+ hasMembers && !preventSeparateIndex,
+ addToIndex,
+ def);
+ int numClasses=0;
+ ClassSDict *classes = def->getClassSDict();
+ if (classes)
+ {
+ ClassDef *cd;
+ ClassSDict::Iterator it(*classes);
+ for (;(cd=it.current());++it)
+ {
+ if (cd->isLinkable()) numClasses++;
+ }
+ }
+ //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",def->name().data(),hasMembers,numClasses);
+ if (hasMembers || numClasses>0)
+ {
+ Doxygen::indexList->incContentsDepth();
+ QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(part));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDef)
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ MemberList *ml = def->getMemberList(lmd->type);
+ if (ml)
+ {
+ MemberListIterator mi(*ml);
+ MemberDef *md;
+ for (mi.toFirst();(md=mi.current());++mi)
+ {
+ MemberList *enumList = md->enumFieldList();
+ bool isDir = enumList!=0 && md->isEnumerate();
+ bool isAnonymous = md->name().find('@')!=-1;
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ if (!isAnonymous &&
+ (!hideUndocMembers || md->hasDocumentation()) &&
+ (!md->isStatic() || extractStatic)
+ )
+ {
+ if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope)
+ {
+ Doxygen::indexList->addContentsItem(isDir,
+ md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
+ }
+ else // inherited member
+ {
+ Doxygen::indexList->addContentsItem(isDir,
+ md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
+ }
+ }
+ if (isDir)
+ {
+ if (!isAnonymous)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ MemberListIterator emli(*enumList);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ if (!hideUndocMembers || emd->hasDocumentation())
+ {
+ if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
+ }
+ else // inherited member
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
+ }
+ }
+ }
+ if (!isAnonymous)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::NamespaceClasses ||
+ lde->kind()==LayoutDocEntry::FileClasses ||
+ lde->kind()==LayoutDocEntry::ClassNestedClasses
+ )
+ {
+ if (classes)
+ {
+ ClassDef *cd;
+ ClassSDict::Iterator it(*classes);
+ for (;(cd=it.current());++it)
+ {
+ if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup))
+ {
+ static bool inlineSimpleStructs = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ bool isNestedClass = def->definitionType()==Definition::TypeClass;
+ addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),
+ addToIndex && (isNestedClass || (cd->isSimple() && inlineSimpleStructs)),
+ preventSeparateIndex || cd->isEmbeddedInOuterScope());
+ }
+ }
+ }
+ }
+ }
+
+ Doxygen::indexList->decContentsDepth();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+/*! Generates HTML Help tree of classes */
+
+static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
+{
+ if (bcl==0) return;
+ BaseClassListIterator bcli(*bcl);
+ bool started=FALSE;
+ for ( ; bcli.current() ; ++bcli)
+ {
+ ClassDef *cd=bcli.current()->classDef;
+ if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
+ {
+ continue;
+ }
+
+ bool b;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ b=hasVisibleRoot(cd->subClasses());
+ }
+ else
+ {
+ b=hasVisibleRoot(cd->baseClasses());
+ }
+
+ if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
+ {
+ if (!started)
+ {
+ startIndexHierarchy(ol,level);
+ if (addToIndex)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->incContentsDepth();
+ }
+ started=TRUE;
+ }
+ ol.startIndexListItem();
+ //printf("Passed...\n");
+ bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
+ //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
+ if (cd->isLinkable())
+ {
+ //printf("Writing class %s\n",cd->displayName().data());
+ ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
+ ol.parseText(cd->displayName());
+ ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
+ if (cd->isReference())
+ {
+ ol.startTypewriter();
+ ol.docify(" [external]");
+ ol.endTypewriter();
+ }
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
+ }
+ if (ftv)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
+ }
+ else
+ {
+ ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
+ }
+ }
+ }
+ else
+ {
+ ol.startIndexItem(0,0);
+ ol.parseText(cd->name());
+ ol.endIndexItem(0,0);
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0);
+ }
+ if (ftv)
+ {
+ ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
+ }
+ }
+ if (hasChildren)
+ {
+ //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
+ bool wasVisited=cd->visited;
+ cd->visited=TRUE;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
+ }
+ else
+ {
+ writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex);
+ }
+ }
+ ol.endIndexListItem();
+ }
+ }
+ if (started)
+ {
+ endIndexHierarchy(ol,level);
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->decContentsDepth();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static bool dirHasVisibleChildren(DirDef *dd)
+{
+ if (dd->hasDocumentation()) return TRUE;
+
+ QListIterator<FileDef> fli(*dd->getFiles());
+ FileDef *fd;
+ for (fli.toFirst();(fd=fli.current());++fli)
+ {
+ bool genSourceFile;
+ if (fileVisibleInIndex(fd,genSourceFile))
+ {
+ return TRUE;
+ }
+ if (genSourceFile)
+ {
+ return TRUE;
+ }
+ }
+
+ QListIterator<DirDef> dli(dd->subDirs());
+ DirDef *subdd;
+ for (dli.toFirst();(subdd=dli.current());++dli)
+ {
+ if (dirHasVisibleChildren(subdd))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
+{
+ if (level>20)
+ {
+ warn(dd->getDefFileName(),dd->getDefLine(),
+ "maximum nesting level exceeded for directory %s: "
+ "check for possible recursive directory relation!\n",dd->name().data()
+ );
+ return;
+ }
+
+ if (!dirHasVisibleChildren(dd))
+ {
+ return;
+ }
+
+ static bool tocExpand = TRUE; //Config_getBool("TOC_EXPAND");
+ bool isDir = dd->subDirs().count()>0 || // there are subdirs
+ (tocExpand && // or toc expand and
+ dd->getFiles() && dd->getFiles()->count()>0 // there are files
+ );
+ //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),
+ dd->getOutputFileBase(),0,FALSE,TRUE,dd);
+ ftv->incContentsDepth();
+ }
+
+ ol.startIndexListItem();
+ ol.startIndexItem(dd->getReference(),dd->getOutputFileBase());
+ ol.parseText(dd->shortName());
+ ol.endIndexItem(dd->getReference(),dd->getOutputFileBase());
+ if (dd->isReference())
+ {
+ ol.startTypewriter();
+ ol.docify(" [external]");
+ ol.endTypewriter();
+ }
+
+ // write sub directories
+ if (dd->subDirs().count()>0)
+ {
+ startIndexHierarchy(ol,level+1);
+ QListIterator<DirDef> dli(dd->subDirs());
+ DirDef *subdd = 0;
+ for (dli.toFirst();(subdd=dli.current());++dli)
+ {
+ writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex);
+ }
+ endIndexHierarchy(ol,level+1);
+ }
+
+ FileList *fileList=dd->getFiles();
+ int fileCount=0;
+ if (fileList && fileList->count()>0)
+ {
+ QListIterator<FileDef> it(*fileList);
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ //static bool allExternals = Config_getBool("ALLEXTERNALS");
+ //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
+ //{
+ // fileCount++;
+ //}
+ bool genSourceFile;
+ if (fileVisibleInIndex(fd,genSourceFile))
+ {
+ fileCount++;
+ }
+ else if (genSourceFile)
+ {
+ fileCount++;
+ }
+ }
+ if (fileCount>0)
+ {
+ startIndexHierarchy(ol,level+1);
+ for (it.toFirst();(fd=it.current());++it)
+ {
+ bool doc,src;
+ doc = fileVisibleInIndex(fd,src);
+ QCString reference;
+ QCString outputBase;
+ if (doc)
+ {
+ reference = fd->getReference();
+ outputBase = fd->getOutputFileBase();
+ }
+ if (doc || src)
+ {
+ ol.startIndexListItem();
+ ol.startIndexItem(reference,outputBase);
+ ol.parseText(fd->displayName());
+ ol.endIndexItem(reference,outputBase);
+ ol.endIndexListItem();
+ if (ftv && (src || doc))
+ {
+ ftv->addContentsItem(FALSE,
+ fd->displayName(),
+ reference,outputBase,
+ 0,FALSE,FALSE,fd);
+ }
+ }
+ }
+ endIndexHierarchy(ol,level+1);
+ }
+ }
+
+ if (tocExpand && addToIndex)
+ {
+ // write files of this directory
+ if (fileCount>0)
+ {
+ QListIterator<FileDef> it(*fileList);
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ //static bool allExternals = Config_getBool("ALLEXTERNALS");
+ //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
+ bool doc,src;
+ doc = fileVisibleInIndex(fd,src);
+ if (doc)
+ {
+ addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
+ }
+ else if (src)
+ {
+ Doxygen::indexList->addContentsItem(
+ FALSE, convertToHtml(fd->name(),TRUE), 0,
+ fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
+ }
+ }
+ }
+ }
+ ol.endIndexListItem();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->decContentsDepth();
+ }
+}
+
+static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
+{
+ if (ftv)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ }
+ static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
+ startIndexHierarchy(ol,0);
+ if (fullPathNames)
+ {
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ for (dli.toFirst();(dd=dli.current());++dli)
+ {
+ if (dd->getOuterScope()==Doxygen::globalScope)
+ {
+ writeDirTreeNode(ol,dd,0,ftv,addToIndex);
+ }
+ }
+ }
+ if (ftv)
+ {
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
+ if (!fullPathNames || fd->getDirDef()==0) // top level file
+ {
+ bool doc,src;
+ doc = fileVisibleInIndex(fd,src);
+ QCString reference, outputBase;
+ if (doc)
+ {
+ reference = fd->getReference();
+ outputBase = fd->getOutputFileBase();
+ }
+ if (doc || src)
+ {
+ ftv->addContentsItem(FALSE,fd->displayName(),
+ reference, outputBase, 0,
+ FALSE,FALSE,fd);
+ }
+ if (addToIndex)
+ {
+ if (doc)
+ {
+ addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
+ }
+ else if (src)
+ {
+ Doxygen::indexList->addContentsItem(
+ FALSE, convertToHtml(fd->name(),TRUE), 0,
+ fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
+ }
+ }
+ }
+ }
+ }
+ }
+ endIndexHierarchy(ol,0);
+ if (ftv)
+ {
+ ol.popGeneratorState();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex)
+{
+ ClassSDict::Iterator cli(*cl);
+ for (;cli.current(); ++cli)
+ {
+ ClassDef *cd=cli.current();
+ //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
+ // cd->name().data(),
+ // hasVisibleRoot(cd->baseClasses()),
+ // cd->isVisibleInHierarchy()
+ // );
+ bool b;
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
+ {
+ continue;
+ }
+ b=!hasVisibleRoot(cd->subClasses());
+ }
+ else
+ {
+ b=!hasVisibleRoot(cd->baseClasses());
+ }
+
+ if (b) //filter on root classes
+ {
+ if (cd->isVisibleInHierarchy()) // should it be visible
+ {
+ if (!started)
+ {
+ startIndexHierarchy(ol,0);
+ if (addToIndex)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ started=TRUE;
+ }
+ ol.startIndexListItem();
+ bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
+ //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
+ if (cd->isLinkable())
+ {
+ //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
+ // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
+ ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
+ ol.parseText(cd->displayName());
+ ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
+ if (cd->isReference())
+ {
+ ol.startTypewriter();
+ ol.docify(" [external]");
+ ol.endTypewriter();
+ }
+ if (addToIndex)
+ {
+ if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List
+ Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
+ }
+ if (ftv)
+ {
+ ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
+ }
+ }
+ else
+ {
+ ol.startIndexItem(0,0);
+ ol.parseText(cd->displayName());
+ ol.endIndexItem(0,0);
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE);
+ }
+ if (ftv)
+ {
+ ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
+ }
+ }
+ if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
+ {
+ writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
+ cd->visited=TRUE;
+ }
+ else if (hasChildren)
+ {
+ writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex);
+ cd->visited=TRUE;
+ }
+ ol.endIndexListItem();
+ }
+ }
+ }
+}
+
+static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
+{
+ initClassHierarchy(Doxygen::classSDict);
+ initClassHierarchy(Doxygen::hiddenClasses);
+ if (ftv)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ }
+ bool started=FALSE;
+ writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex);
+ writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex);
+ if (started)
+ {
+ endIndexHierarchy(ol,0);
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ if (ftv)
+ {
+ ol.popGeneratorState();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static int countClassesInTreeList(const ClassSDict &cl)
+{
+ int count=0;
+ ClassSDict::Iterator cli(cl);
+ for (;cli.current(); ++cli)
+ {
+ ClassDef *cd=cli.current();
+ if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
+ {
+ if (cd->isVisibleInHierarchy()) // should it be visible
+ {
+ if (cd->subClasses()) // should have sub classes
+ {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+static int countClassHierarchy()
+{
+ int count=0;
+ initClassHierarchy(Doxygen::classSDict);
+ initClassHierarchy(Doxygen::hiddenClasses);
+ count+=countClassesInTreeList(*Doxygen::classSDict);
+ count+=countClassesInTreeList(*Doxygen::hiddenClasses);
+ return count;
+}
+
+//----------------------------------------------------------------------------
+
+static void writeHierarchicalIndex(OutputList &ol)
+{
+ if (hierarchyClasses==0) return;
+ ol.pushGeneratorState();
+ //1.{
+ ol.disable(OutputGenerator::Man);
+
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
+ QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
+ bool addToIndex = lne==0 || lne->visible();
+
+ startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+
+ if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
+ {
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ ol.startParagraph();
+ ol.startTextLink("inherits",0);
+ ol.parseText(theTranslator->trGotoGraphicalHierarchy());
+ ol.endTextLink();
+ ol.endParagraph();
+ ol.enable(OutputGenerator::Latex);
+ ol.enable(OutputGenerator::RTF);
+ }
+ ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription());
+ ol.endTextBlock();
+
+ // ---------------
+ // Static class hierarchy for Latex/RTF
+ // ---------------
+ ol.pushGeneratorState();
+ //2.{
+ ol.disable(OutputGenerator::Html);
+ Doxygen::indexList->disable();
+
+ writeClassHierarchy(ol,0,addToIndex);
+
+ Doxygen::indexList->enable();
+ ol.popGeneratorState();
+ //2.}
+
+ // ---------------
+ // Dynamic class hierarchical index for HTML
+ // ---------------
+ ol.pushGeneratorState();
+ //2.{
+ ol.disableAllBut(OutputGenerator::Html);
+
+ {
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE);
+ }
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ writeClassHierarchy(ol,ftv,addToIndex);
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString(outStr);
+ ol.popGeneratorState();
+ delete ftv;
+ }
+ ol.popGeneratorState();
+ //2.}
+ // ------
+
+ endFile(ol);
+ ol.popGeneratorState();
+ //1.}
+}
+
+//----------------------------------------------------------------------------
+
+static void writeGraphicalClassHierarchy(OutputList &ol)
+{
+ if (hierarchyClasses==0) return;
+ ol.disableAllBut(OutputGenerator::Html);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
+ QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
+ startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+ ol.startParagraph();
+ ol.startTextLink("hierarchy",0);
+ ol.parseText(theTranslator->trGotoTextualHierarchy());
+ ol.endTextLink();
+ ol.endParagraph();
+ ol.endTextBlock();
+ DotGfxHierarchyTable g;
+ ol.writeGraphicalHierarchy(g);
+ endFile(ol);
+ ol.enableAll();
+}
+
+//----------------------------------------------------------------------------
+
+static void countFiles(int &htmlFiles,int &files)
+{
+ htmlFiles=0;
+ files=0;
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ bool doc,src;
+ doc = fileVisibleInIndex(fd,src);
+ if (doc || src)
+ {
+ htmlFiles++;
+ }
+ if (doc)
+ {
+ files++;
+ }
+ }
+ }
+}
+
+static void writeSingleFileIndex(OutputList &ol,FileDef *fd)
+{
+ //printf("Found filedef %s\n",fd->name().data());
+ bool doc = fd->isLinkableInProject();
+ bool src = fd->generateSourceFile();
+ bool nameOk = !fd->isDocumentationFile();
+ if (nameOk && (doc || src) && !fd->isReference())
+ {
+ QCString path;
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ path=stripFromPath(fd->getPath().copy());
+ }
+ QCString fullName=fd->name();
+ if (!path.isEmpty())
+ {
+ if (path.at(path.length()-1)!='/') fullName.prepend("/");
+ fullName.prepend(path);
+ }
+
+ ol.startIndexKey();
+ ol.docify(path);
+ if (doc)
+ {
+ ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
+ //if (addToIndex)
+ //{
+ // addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString());
+ //}
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(fd->name());
+ ol.endBold();
+ //if (addToIndex)
+ //{
+ // Doxygen::indexList->addContentsItem(FALSE,fullName,0,0,0);
+ //}
+ }
+ if (src)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(fd->includeName(),0);
+ ol.docify("[");
+ ol.parseText(theTranslator->trCode());
+ ol.docify("]");
+ ol.endTextLink();
+ ol.popGeneratorState();
+ }
+ ol.endIndexKey();
+ bool hasBrief = !fd->briefDescription().isEmpty();
+ ol.startIndexValue(hasBrief);
+ if (hasBrief)
+ {
+ //ol.docify(" (");
+ ol.generateDoc(
+ fd->briefFile(),fd->briefLine(),
+ fd,0,
+ fd->briefDescription(TRUE),
+ FALSE, // index words
+ FALSE, // isExample
+ 0, // example name
+ TRUE, // single line
+ TRUE // link from index
+ );
+ //ol.docify(")");
+ }
+ ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
+ //ol.popGeneratorState();
+ // --------------------------------------------------------
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void writeFileIndex(OutputList &ol)
+{
+ if (documentedHtmlFiles==0) return;
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
+
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileList);
+ if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); // fall back
+ QCString title = lne ? lne->title() : theTranslator->trFileList();
+ bool addToIndex = lne==0 || lne->visible();
+
+ startFile(ol,"files",0,title,HLI_Files);
+ startTitle(ol,0);
+ //if (!Config_getString("PROJECT_NAME").isEmpty())
+ //{
+ // title.prepend(Config_getString("PROJECT_NAME")+" ");
+ //}
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+
+ ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
+ ol.endTextBlock();
+
+ // ---------------
+ // Flat file index
+ // ---------------
+
+ // 1. {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+
+ OutputNameDict outputNameDict(1009);
+ OutputNameList outputNameList;
+ outputNameList.setAutoDelete(TRUE);
+
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ // re-sort input files in (dir,file) output order instead of (file,dir) input order
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ QCString path=fd->getPath();
+ if (path.isEmpty()) path="[external]";
+ FileList *fl = outputNameDict.find(path);
+ if (fl)
+ {
+ fl->append(fd);
+ //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
+ }
+ else
+ {
+ //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
+ fl = new FileList(path);
+ fl->append(fd);
+ outputNameList.append(fl);
+ outputNameDict.insert(path,fl);
+ }
+ }
+ }
+ }
+
+ ol.startIndexList();
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ outputNameList.sort();
+ QListIterator<FileList> fnli(outputNameList);
+ FileList *fl;
+ for (fnli.toFirst();(fl=fnli.current());++fnli)
+ {
+ fl->sort();
+ QListIterator<FileDef> it(*fl);
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ writeSingleFileIndex(ol,fd);
+ }
+ }
+ }
+ else
+ {
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ writeSingleFileIndex(ol,fd);
+ }
+ }
+ }
+ ol.endIndexList();
+
+ // 1. }
+ ol.popGeneratorState();
+
+ // ---------------
+ // Hierarchical file index for HTML
+ // ---------------
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ writeDirHierarchy(ol,ftv,addToIndex);
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.writeString(outStr);
+ delete ftv;
+
+ ol.popGeneratorState();
+ // ------
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+static int countNamespaces()
+{
+ int count=0;
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (;(nd=nli.current());++nli)
+ {
+ if (nd->isLinkableInProject()) count++;
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+
+void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly)
+{
+ if (clDict)
+ {
+ ClassSDict::Iterator cli(*clDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS
+ )// no architecture
+ {
+ continue;
+ }
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
+ {
+ QCString n=cd->name();
+ cd->setClassName(n.data());
+ }
+ }
+
+ if (!globalOnly ||
+ cd->getOuterScope()==0 ||
+ cd->getOuterScope()==Doxygen::globalScope
+ )
+ {
+ int count=0;
+ if (cd->getClassSDict())
+ {
+ ClassSDict::Iterator ccit(*cd->getClassSDict());
+ ClassDef *ccd;
+ for (;(ccd=ccit.current());++ccit)
+ {
+ if (ccd->isLinkableInProject() && ccd->templateMaster()==0)
+ {
+ count++;
+ }
+ }
+ }
+ if (classVisibleInIndex(cd) && cd->templateMaster()==0)
+ {
+ ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(),
+ cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd);
+ if (addToIndex &&
+ /*cd->partOfGroups()==0 &&*/
+ (cd->getOuterScope()==0 ||
+ cd->getOuterScope()->definitionType()!=Definition::TypeClass
+ )
+ )
+ {
+ addMembersToIndex(cd,LayoutDocManager::Class,
+ cd->displayName(FALSE),
+ cd->anchor(),
+ cd->partOfGroups()==0 && !cd->isSimple());
+ }
+ if (count>0)
+ {
+ ftv->incContentsDepth();
+ writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE);
+ ftv->decContentsDepth();
+ }
+ }
+ }
+ }
+ }
+}
+
+static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv,
+ bool rootOnly,bool showClasses,bool addToIndex)
+{
+ if (nsDict)
+ {
+ NamespaceSDict::Iterator nli(*nsDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (nd->localName().find('@')==-1 &&
+ (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
+ {
+
+ bool hasChildren = namespaceHasVisibleChild(nd,showClasses);
+ bool isLinkable = nd->isLinkableInProject();
+
+ QCString ref;
+ QCString file;
+ if (isLinkable)
+ {
+ ref = nd->getReference();
+ file = nd->getOutputFileBase();
+ if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK
+ {
+ file=file.replace(0,qstrlen("namespace"),"class");
+ }
+ }
+
+ if ((isLinkable && !showClasses) || hasChildren)
+ {
+ ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd);
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(),
+ hasChildren && !file.isEmpty(),addToIndex);
+ }
+
+ //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n",
+ // count,addToIndex,showClasses,classCount);
+ if (hasChildren)
+ {
+ if (addToIndex) Doxygen::indexList->incContentsDepth();
+ ftv->incContentsDepth();
+ writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex);
+ if (showClasses)
+ {
+ writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE);
+ }
+ ftv->decContentsDepth();
+ if (addToIndex) Doxygen::indexList->decContentsDepth();
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static void writeNamespaceIndex(OutputList &ol)
+{
+ if (documentedNamespaces==0) return;
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceList);
+ if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back
+ QCString title = lne ? lne->title() : theTranslator->trNamespaceList();
+ bool addToIndex = lne==0 || lne->visible();
+ startFile(ol,"namespaces",0,title,HLI_Namespaces);
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool("EXTRACT_ALL")));
+ ol.endTextBlock();
+
+ bool first=TRUE;
+
+ // ---------------
+ // Linear namespace index for Latex/RTF
+ // ---------------
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ if (first)
+ {
+ ol.startIndexList();
+ first=FALSE;
+ }
+ //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
+ ol.startIndexKey();
+ if (nd->getLanguage()==SrcLangExt_VHDL)
+ {
+ ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,qstrlen("namespace"),"class"),0,nd->displayName());
+ }
+ else
+ {
+ ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
+ }
+ ol.endIndexKey();
+
+ bool hasBrief = !nd->briefDescription().isEmpty();
+ ol.startIndexValue(hasBrief);
+ if (hasBrief)
+ {
+ //ol.docify(" (");
+ ol.generateDoc(
+ nd->briefFile(),nd->briefLine(),
+ nd,0,
+ nd->briefDescription(TRUE),
+ FALSE, // index words
+ FALSE, // isExample
+ 0, // example name
+ TRUE, // single line
+ TRUE // link from index
+ );
+ //ol.docify(")");
+ }
+ ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
+
+ }
+ }
+ if (!first) ol.endIndexList();
+
+ ol.popGeneratorState();
+
+ // ---------------
+ // Hierarchical namespace index for HTML
+ // ---------------
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ {
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex);
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.writeString(outStr);
+ delete ftv;
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+
+ ol.popGeneratorState();
+ // ------
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+
+static int countAnnotatedClasses(int *cp)
+{
+ int count=0;
+ int countPrinted=0;
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ if (!cd->isEmbeddedInOuterScope())
+ {
+ countPrinted++;
+ }
+ count++;
+ }
+ }
+ *cp = countPrinted;
+ return count;
+}
+
+
+static void writeAnnotatedClassList(OutputList &ol)
+{
+ //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
+ //bool addToIndex = lne==0 || lne->visible();
+
+ ol.startIndexList();
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL &&
+ ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ ) // no architecture
+ {
+ continue;
+ }
+
+ ol.pushGeneratorState();
+ if (cd->isEmbeddedInOuterScope())
+ {
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ }
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ QCString type=cd->compoundTypeString();
+ ol.startIndexKey();
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection());
+ ol.docify(prot.data());
+ ol.writeString(" ");
+ }
+ ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
+ ol.endIndexKey();
+ bool hasBrief = !cd->briefDescription().isEmpty();
+ ol.startIndexValue(hasBrief);
+ if (hasBrief)
+ {
+ ol.generateDoc(
+ cd->briefFile(),cd->briefLine(),
+ cd,0,
+ cd->briefDescription(TRUE),
+ FALSE, // indexWords
+ FALSE, // isExample
+ 0, // example name
+ TRUE, // single line
+ TRUE // link from index
+ );
+ }
+ ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
+
+ //if (addToIndex)
+ //{
+ // addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor());
+ //}
+ }
+ ol.popGeneratorState();
+ }
+ ol.endIndexList();
+}
+
+static QCString letterToLabel(uint startLetter)
+{
+ char s[10];
+ if (startLetter>0x20 && startLetter<=0x7f) // printable ASCII character
+ {
+ s[0]=(char)startLetter;
+ s[1]=0;
+ }
+ else
+ {
+ const char hex[]="0123456789abcdef";
+ int i=0;
+ s[i++]='0';
+ s[i++]='x';
+ if (startLetter>(1<<24)) // 4 byte character
+ {
+ s[i++]=hex[(startLetter>>28)&0xf];
+ s[i++]=hex[(startLetter>>24)&0xf];
+ }
+ if (startLetter>(1<<16)) // 3 byte character
+ {
+ s[i++]=hex[(startLetter>>20)&0xf];
+ s[i++]=hex[(startLetter>>16)&0xf];
+ }
+ if (startLetter>(1<<8)) // 2 byte character
+ {
+ s[i++]=hex[(startLetter>>12)&0xf];
+ s[i++]=hex[(startLetter>>8)&0xf];
+ }
+ // one byte character
+ s[i++]=hex[(startLetter>>4)&0xf];
+ s[i++]=hex[(startLetter>>0)&0xf];
+ s[i++]=0;
+ }
+ return s;
+}
+
+//----------------------------------------------------------------------------
+
+/** Special class list where sorting takes IGNORE_PREFIX into account. */
+class PrefixIgnoreClassList : public ClassList
+{
+ public:
+ typedef ClassDef ElementType;
+ PrefixIgnoreClassList(uint letter) : m_letter(letter) {}
+ uint letter() const { return m_letter; }
+ private:
+ virtual int compareValue(const ClassDef *c1, const ClassDef *c2) const
+ {
+ QCString n1 = c1->className();
+ QCString n2 = c2->className();
+ return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
+ }
+ uint m_letter;
+};
+
+/** Class representing a cell in the alphabetical class index. */
+class AlphaIndexTableCell
+{
+ public:
+ AlphaIndexTableCell(int row,int col,uint letter,ClassDef *cd) :
+ m_letter(letter), m_class(cd), m_row(row), m_col(col)
+ { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
+ // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>");
+ }
+
+ ClassDef *classDef() const { return m_class; }
+ uint letter() const { return m_letter; }
+ int row() const { return m_row; }
+ int column() const { return m_col; }
+
+ private:
+ uint m_letter;
+ ClassDef *m_class;
+ int m_row;
+ int m_col;
+};
+
+/** Class representing a row in the alphabetical class index. */
+class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
+{
+ public:
+ AlphaIndexTableRows() { setAutoDelete(TRUE); }
+};
+
+/** Iterator for the cells in a row of the alphabetical class index. */
+class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
+{
+ public:
+ AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) :
+ QListIterator<AlphaIndexTableCell>(list) {}
+};
+
+/** Class representing the columns in the alphabetical class index. */
+class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
+{
+ public:
+ AlphaIndexTableColumns() { setAutoDelete(TRUE); }
+};
+
+class UsedIndexLetters : public SIntDict<uint>
+{
+ public:
+ UsedIndexLetters() : SIntDict<uint>(257) { setAutoDelete(TRUE); }
+ void add(uint letter)
+ {
+ uint *v = find(letter);
+ if (v==0)
+ {
+ append(letter,new uint(letter));
+ }
+ }
+ private:
+ int compareValues( const uint *p1, const uint *p2) const
+ {
+ return (int)*p1 - (int)*p2; // subtracting is done by int not uint.
+ }
+};
+
+// write an alphabetical index of all class with a header for each letter
+static void writeAlphabeticalClassList(OutputList &ol)
+{
+ // What starting letters are used
+ UsedIndexLetters indexLettersUsed;
+
+ // first count the number of headers
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ uint startLetter=0;
+ int headerItems=0;
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
+ continue;
+
+ int index = getPrefixIndex(cd->className());
+ //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
+ startLetter=getUtf8CodeToUpper(cd->className(),index);
+ indexLettersUsed.add(startLetter);
+ }
+ }
+ indexLettersUsed.sort();
+
+ // write quick link index (row of letters)
+ QCString alphaLinks = "<div class=\"qindex\">";
+ SIntDict<uint>::Iterator it(indexLettersUsed);
+ uint *pLetter;
+ for (it.toFirst();(pLetter=it.current());++it)
+ {
+ if (headerItems) alphaLinks += " | ";
+ headerItems++;
+ QCString li = letterToLabel(*pLetter);
+ QCString ls = QString(QChar(*pLetter)).utf8();
+ alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
+ li + "\">" +
+ ls + "</a>";
+ }
+ alphaLinks += "</div>\n";
+ ol.writeString(alphaLinks);
+
+
+ // the number of columns in the table
+ const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
+
+ int i,j;
+ int totalItems = headerItems*2 + annotatedClasses; // number of items in the table (headers span 2 items)
+ int rows = (totalItems + columns - 1)/columns; // number of rows in the table
+
+ //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
+ // headerItems,totalItems,columns,rows,itemsInLastRow);
+
+ // Keep a list of classes for each starting letter
+ LetterToIndexMap<PrefixIgnoreClassList> classesByLetter;
+ AlphaIndexTableColumns tableColumns;
+
+ // fill the columns with the class list (row elements in each column,
+ // expect for the columns with number >= itemsInLastRow, which get one
+ // item less.
+ //int icount=0;
+ startLetter=0;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
+ continue;
+
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ int index = getPrefixIndex(cd->className());
+ startLetter=getUtf8Code(cd->className(),index);
+ // Do some sorting again, since the classes are sorted by name with
+ // prefix, which should be ignored really.
+ if (cd->getLanguage()==SrcLangExt_VHDL)
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
+ {
+ classesByLetter.append(startLetter,cd);
+ }
+ }
+ else
+ {
+ classesByLetter.append(startLetter,cd);
+ }
+ }
+ }
+
+ #define NEXT_ROW() \
+ do \
+ { \
+ if (row>maxRows) maxRows=row; \
+ if (row>=rows && col<columns) \
+ { \
+ col++; \
+ row=0; \
+ tableRows = new AlphaIndexTableRows; \
+ tableColumns.append(tableRows); \
+ } \
+ } \
+ while(0) \
+
+ AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
+ tableColumns.append(tableRows);
+ int col=0,row=0,maxRows=0;
+ PrefixIgnoreClassList *cl;
+ SIntDict<PrefixIgnoreClassList>::Iterator lit(classesByLetter);
+ for (lit.toFirst();(cl=lit.current());++lit)
+ {
+ uint l = cl->letter();
+ // add special header cell
+ tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8));
+ row++;
+ tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
+ row++;
+ ClassListIterator cit(*cl);
+ cit.toFirst();
+ ClassDef *cd = cit.current();
+ ++cit;
+ tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
+ row++;
+ NEXT_ROW();
+ for (;(cd=cit.current()); ++cit)
+ {
+ // add normal cell
+ tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
+ row++;
+ NEXT_ROW();
+ }
+ }
+
+ // create row iterators for each column
+ AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
+ for (i=0;i<columns;i++)
+ {
+ if (i<(int)tableColumns.count())
+ {
+ colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
+ }
+ else // empty column
+ {
+ colIterators[i] = 0;
+ }
+ }
+
+ ol.writeString("<table style=\"margin: 10px; white-space: nowrap;\" align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
+ // generate table
+ for (i=0;i<=maxRows;i++) // foreach table row
+ {
+ //printf("writing row %d\n",i);
+ //ol.nextTableRow();
+ ol.writeString("<tr>");
+ // the last column may contain less items then the others
+ //int colsInRow = (i<rows-1) ? columns : itemsInLastRow;
+ //printf("row [%d]\n",i);
+ for (j=0;j<columns;j++) // foreach table column
+ {
+ if (colIterators[j])
+ {
+ AlphaIndexTableCell *cell = colIterators[j]->current();
+ if (cell)
+ {
+ if (cell->row()==i)
+ {
+ if (cell->letter()!=0)
+ {
+ QCString s = letterToLabel(cell->letter());
+ ol.writeString("<td rowspan=\"2\" valign=\"bottom\">");
+ ol.writeString("<a name=\"letter_");
+ ol.writeString(s);
+ ol.writeString("\"></a>");
+ ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+ "<tr>"
+ "<td><div class=\"ah\"> ");
+ ol.writeString(QString(QChar(cell->letter())).utf8());
+ ol.writeString( " </div>"
+ "</td>"
+ "</tr>"
+ "</table>\n");
+ }
+ else if (cell->classDef()!=(ClassDef*)0x8)
+ {
+ cd = cell->classDef();
+ ol.writeString("<td valign=\"top\">");
+ QCString namesp,cname;
+ //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
+ //QCString cname=cd->className();
+ extractNamespaceName(cd->name(),cname,namesp);
+ QCString nsDispName;
+ SrcLangExt lang = cd->getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ nsDispName=substitute(namesp,"::",sep);
+ cname=substitute(cname,"::",sep);
+ }
+ else
+ {
+ nsDispName=namesp;
+ }
+
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),cd->anchor(),cname);
+ if (!namesp.isEmpty())
+ {
+ ol.docify(" (");
+ NamespaceDef *nd = getResolvedNamespace(namesp);
+ if (nd && nd->isLinkable())
+ {
+ ol.writeObjectLink(nd->getReference(),
+ nd->getOutputFileBase(),0,nsDispName);
+ }
+ else
+ {
+ ol.docify(nsDispName);
+ }
+ ol.docify(")");
+ }
+ ol.writeNonBreakableSpace(3);
+ }
+ ++(*colIterators[j]);
+ if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8)
+ {
+ ol.writeString("</td>");
+ }
+ }
+ }
+ else
+ {
+ ol.writeString("<td></td>");
+ }
+ }
+ }
+ ol.writeString("</tr>\n");
+ }
+ ol.writeString("</table>\n");
+
+ ol.writeString(alphaLinks);
+
+ // release the temporary memory
+ for (i=0;i<columns;i++)
+ {
+ delete colIterators[i];
+ }
+ delete[] colIterators;
+}
+
+//----------------------------------------------------------------------------
+
+static void writeAlphabeticalIndex(OutputList &ol)
+{
+ if (annotatedClasses==0) return;
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassIndex);
+ QCString title = lne ? lne->title() : theTranslator->trCompoundIndex();
+ bool addToIndex = lne==0 || lne->visible();
+
+ startFile(ol,"classes",0,title,HLI_Classes);
+
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,title,0,"classes",0,FALSE,TRUE);
+ }
+
+ ol.startContents();
+ writeAlphabeticalClassList(ol);
+ endFile(ol); // contains ol.endContents()
+
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+
+static void writeAnnotatedIndex(OutputList &ol)
+{
+ //printf("writeAnnotatedIndex: count=%d printed=%d\n",
+ // annotatedClasses,annotatedClassesPrinted);
+ if (annotatedClasses==0) return;
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ if (annotatedClassesPrinted==0)
+ {
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ }
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
+ if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back
+ QCString title = lne ? lne->title() : theTranslator->trCompoundList();
+ bool addToIndex = lne==0 || lne->visible();
+
+
+ startFile(ol,"annotated",0,title,HLI_Annotated);
+
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+
+ ol.startContents();
+
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription());
+ ol.endTextBlock();
+
+ // ---------------
+ // Linear class index for Latex/RTF
+ // ---------------
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ Doxygen::indexList->disable();
+
+ writeAnnotatedClassList(ol);
+
+ Doxygen::indexList->enable();
+ ol.popGeneratorState();
+
+ // ---------------
+ // Hierarchical class index for HTML
+ // ---------------
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ {
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex);
+ writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE);
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.writeString(outStr);
+ delete ftv;
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+
+ ol.popGeneratorState();
+ // ------
+
+ endFile(ol); // contains ol.endContents()
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+ QCString &prevClassName)
+{
+ ClassDef *cd=md->getClassDef();
+ if ( cd && prevClassName!=cd->displayName())
+ {
+ ol.docify(separator);
+ ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
+ cd->displayName());
+ ol.writeString("\n");
+ prevClassName = cd->displayName();
+ }
+}
+
+static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+ QCString &prevFileName)
+{
+ FileDef *fd=md->getFileDef();
+ if (fd && prevFileName!=fd->name())
+ {
+ ol.docify(separator);
+ ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
+ fd->name());
+ ol.writeString("\n");
+ prevFileName = fd->name();
+ }
+}
+
+static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+ QCString &prevNamespaceName)
+{
+ NamespaceDef *nd=md->getNamespaceDef();
+ if (nd && prevNamespaceName!=nd->name())
+ {
+ ol.docify(separator);
+ ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
+ nd->name());
+ ol.writeString("\n");
+ prevNamespaceName = nd->name();
+ }
+}
+
+static void writeMemberList(OutputList &ol,bool useSections,int page,
+ const LetterToIndexMap<MemberIndexList> &memberLists,
+ DefinitionIntf::DefType type)
+{
+ ASSERT((int)type<3);
+
+ typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
+ QCString &prevNamespaceName);
+
+ // each index tab has its own write function
+ static writeLinkForMember_t writeLinkForMemberMap[3] =
+ {
+ &writeClassLinkForMember,
+ &writeFileLinkForMember,
+ &writeNamespaceLinkForMember
+ };
+ QCString prevName;
+ QCString prevDefName;
+ bool first=TRUE;
+ bool firstSection=TRUE;
+ bool firstItem=TRUE;
+ MemberIndexList *ml;
+ SIntDict<MemberIndexList>::Iterator it(memberLists);
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ if (page!=-1)
+ {
+ ml = memberLists[page];
+ it.toLast();
+ }
+ if (ml==0 || ml->count()==0) continue;
+ ml->sort();
+ QListIterator<MemberDef> mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ const char *sep;
+ bool isFunc=!md->isObjCMethod() &&
+ (md->isFunction() || md->isSlot() || md->isSignal());
+ QCString name=md->name();
+ int startIndex = getPrefixIndex(name);
+ if (QCString(name.data()+startIndex)!=prevName) // new entry
+ {
+ if ((prevName.isEmpty() ||
+ tolower(name.at(startIndex))!=tolower(prevName.at(0))) &&
+ useSections) // new section
+ {
+ if (!firstItem) ol.endItemListItem();
+ if (!firstSection) ol.endItemList();
+ QCString cs = letterToLabel(ml->letter());
+ QCString cl = QString(QChar(ml->letter())).utf8();
+ QCString anchor=(QCString)"index_"+cs;
+ QCString title=(QCString)"- "+cl+" -";
+ ol.startSection(anchor,title,SectionInfo::Subsection);
+ ol.docify(title);
+ ol.endSection(anchor,SectionInfo::Subsection);
+ ol.startItemList();
+ firstSection=FALSE;
+ firstItem=TRUE;
+ }
+ else if (!useSections && first)
+ {
+ ol.startItemList();
+ first=FALSE;
+ }
+
+ // member name
+ if (!firstItem) ol.endItemListItem();
+ ol.startItemListItem();
+ firstItem=FALSE;
+ ol.docify(name);
+ if (isFunc) ol.docify("()");
+ ol.writeString("\n");
+
+ // link to class
+ prevDefName="";
+ sep = ": ";
+ prevName = name.data()+startIndex;
+ }
+ else // same entry
+ {
+ sep = ", ";
+ // link to class for other members with the same name
+ }
+ // write the link for the specific list type
+ writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
+ }
+ }
+ if (!firstItem) ol.endItemListItem();
+ ol.endItemList();
+}
+
+//----------------------------------------------------------------------------
+
+void initClassMemberIndices()
+{
+ int j=0;
+ for (j=0;j<CMHL_Total;j++)
+ {
+ documentedClassMembers[j]=0;
+ g_memberIndexLetterUsed[j].clear();
+ }
+}
+
+void addClassMemberNameToIndex(MemberDef *md)
+{
+ static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
+ ClassDef *cd=0;
+
+
+
+ if (md->isLinkableInProject() &&
+ (cd=md->getClassDef()) &&
+ cd->isLinkableInProject() &&
+ cd->templateMaster()==0)
+ {
+ QCString n = md->name();
+ int index = getPrefixIndex(n);
+ uint letter = getUtf8CodeToLower(n,index);
+ if (!n.isEmpty())
+ {
+ bool isFriendToHide = hideFriendCompounds &&
+ (QCString(md->typeString())=="friend class" ||
+ QCString(md->typeString())=="friend struct" ||
+ QCString(md->typeString())=="friend union");
+ if (!(md->isFriend() && isFriendToHide) &&
+ (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
+ )
+ {
+ g_memberIndexLetterUsed[CMHL_All].append(letter,md);
+ documentedClassMembers[CMHL_All]++;
+ }
+ if (md->isFunction() || md->isSlot() || md->isSignal())
+ {
+ g_memberIndexLetterUsed[CMHL_Functions].append(letter,md);
+ documentedClassMembers[CMHL_Functions]++;
+ }
+ else if (md->isVariable())
+ {
+ g_memberIndexLetterUsed[CMHL_Variables].append(letter,md);
+ documentedClassMembers[CMHL_Variables]++;
+ }
+ else if (md->isTypedef())
+ {
+ g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md);
+ documentedClassMembers[CMHL_Typedefs]++;
+ }
+ else if (md->isEnumerate())
+ {
+ g_memberIndexLetterUsed[CMHL_Enums].append(letter,md);
+ documentedClassMembers[CMHL_Enums]++;
+ }
+ else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
+ {
+ g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md);
+ documentedClassMembers[CMHL_EnumValues]++;
+ }
+ else if (md->isProperty())
+ {
+ g_memberIndexLetterUsed[CMHL_Properties].append(letter,md);
+ documentedClassMembers[CMHL_Properties]++;
+ }
+ else if (md->isEvent())
+ {
+ g_memberIndexLetterUsed[CMHL_Events].append(letter,md);
+ documentedClassMembers[CMHL_Events]++;
+ }
+ else if (md->isRelated() || md->isForeign() ||
+ (md->isFriend() && !isFriendToHide))
+ {
+ g_memberIndexLetterUsed[CMHL_Related].append(letter,md);
+ documentedClassMembers[CMHL_Related]++;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void initNamespaceMemberIndices()
+{
+ int j=0;
+ for (j=0;j<NMHL_Total;j++)
+ {
+ documentedNamespaceMembers[j]=0;
+ g_namespaceIndexLetterUsed[j].clear();
+ }
+}
+
+void addNamespaceMemberNameToIndex(MemberDef *md)
+{
+ NamespaceDef *nd=md->getNamespaceDef();
+ if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
+ {
+ QCString n = md->name();
+ int index = getPrefixIndex(n);
+ uint letter = getUtf8CodeToLower(n,index);
+ if (!n.isEmpty())
+ {
+ if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
+ {
+ g_namespaceIndexLetterUsed[NMHL_All].append(letter,md);
+ documentedNamespaceMembers[NMHL_All]++;
+ }
+
+ if (md->isFunction())
+ {
+ g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md);
+ documentedNamespaceMembers[NMHL_Functions]++;
+ }
+ else if (md->isVariable())
+ {
+ g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md);
+ documentedNamespaceMembers[NMHL_Variables]++;
+ }
+ else if (md->isTypedef())
+ {
+ g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md);
+ documentedNamespaceMembers[NMHL_Typedefs]++;
+ }
+ else if (md->isEnumerate())
+ {
+ g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md);
+ documentedNamespaceMembers[NMHL_Enums]++;
+ }
+ else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
+ {
+ g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md);
+ documentedNamespaceMembers[NMHL_EnumValues]++;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void initFileMemberIndices()
+{
+ int j=0;
+ for (j=0;j<NMHL_Total;j++)
+ {
+ documentedFileMembers[j]=0;
+ g_fileIndexLetterUsed[j].clear();
+ }
+}
+
+void addFileMemberNameToIndex(MemberDef *md)
+{
+ FileDef *fd=md->getFileDef();
+ if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
+ {
+ QCString n = md->name();
+ int index = getPrefixIndex(n);
+ uint letter = getUtf8CodeToLower(n,index);
+ if (!n.isEmpty())
+ {
+ if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
+ {
+ g_fileIndexLetterUsed[FMHL_All].append(letter,md);
+ documentedFileMembers[FMHL_All]++;
+ }
+
+ if (md->isFunction())
+ {
+ g_fileIndexLetterUsed[FMHL_Functions].append(letter,md);
+ documentedFileMembers[FMHL_Functions]++;
+ }
+ else if (md->isVariable())
+ {
+ g_fileIndexLetterUsed[FMHL_Variables].append(letter,md);
+ documentedFileMembers[FMHL_Variables]++;
+ }
+ else if (md->isTypedef())
+ {
+ g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md);
+ documentedFileMembers[FMHL_Typedefs]++;
+ }
+ else if (md->isEnumerate())
+ {
+ g_fileIndexLetterUsed[FMHL_Enums].append(letter,md);
+ documentedFileMembers[FMHL_Enums]++;
+ }
+ else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
+ {
+ g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md);
+ documentedFileMembers[FMHL_EnumValues]++;
+ }
+ else if (md->isDefine())
+ {
+ g_fileIndexLetterUsed[FMHL_Defines].append(letter,md);
+ documentedFileMembers[FMHL_Defines]++;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void writeQuickMemberIndex(OutputList &ol,
+ const LetterToIndexMap<MemberIndexList> &charUsed,uint page,
+ QCString fullName,bool multiPage)
+{
+ bool first=TRUE;
+ startQuickIndexList(ol,TRUE);
+ SIntDict<MemberIndexList>::Iterator it(charUsed);
+ MemberIndexList *ml;
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ uint i = ml->letter();
+ QCString is = letterToLabel(i);
+ QCString ci = QString(QChar(i)).utf8();
+ QCString anchor;
+ QCString extension=Doxygen::htmlFileExtension;
+ if (!multiPage)
+ anchor="#index_";
+ else if (first)
+ anchor=fullName+extension+"#index_";
+ else
+ anchor=fullName+"_"+letterToLabel(i)+extension+"#index_";
+ startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
+ ol.writeString(is);
+ endQuickIndexItem(ol);
+ first=FALSE;
+ }
+ endQuickIndexList(ol);
+}
+
+//----------------------------------------------------------------------------
+
+/** Helper class representing a class member in the navigation menu. */
+struct CmhlInfo
+{
+ CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
+ const char *fname;
+ QCString title;
+};
+
+static const CmhlInfo *getCmhlInfo(int hl)
+{
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static CmhlInfo cmhlInfo[] =
+ {
+ CmhlInfo("functions", theTranslator->trAll()),
+ CmhlInfo("functions_func",
+ fortranOpt ? theTranslator->trSubprograms() :
+ vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
+ theTranslator->trFunctions()),
+ CmhlInfo("functions_vars",theTranslator->trVariables()),
+ CmhlInfo("functions_type",theTranslator->trTypedefs()),
+ CmhlInfo("functions_enum",theTranslator->trEnumerations()),
+ CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
+ CmhlInfo("functions_prop",theTranslator->trProperties()),
+ CmhlInfo("functions_evnt",theTranslator->trEvents()),
+ CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
+ };
+ return &cmhlInfo[hl];
+}
+
+static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
+{
+ if (documentedClassMembers[hl]==0) return;
+
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+
+ bool multiPageIndex=FALSE;
+ if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
+ {
+ multiPageIndex=TRUE;
+ }
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString extension=Doxygen::htmlFileExtension;
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
+ QCString title = lne ? lne->title() : theTranslator->trCompoundMembers();
+ if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
+ bool addToIndex = lne==0 || lne->visible();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0,
+ getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
+ if (multiPageIndex) Doxygen::indexList->incContentsDepth();
+ }
+
+ bool first=TRUE;
+ SIntDict<MemberIndexList>::Iterator it(g_memberIndexLetterUsed[hl]);
+ MemberIndexList *ml;
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ uint page = ml->letter();
+ QCString fileName = getCmhlInfo(hl)->fname;
+ if (multiPageIndex)
+ {
+ if (!first)
+ {
+ fileName+="_"+letterToLabel(page);
+ }
+ QCString cs = QString(QChar(page)).utf8();
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
+ }
+ }
+ bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
+
+ ol.startFile(fileName+extension,0,title);
+ ol.startQuickIndices();
+ if (!disableIndex)
+ {
+ ol.writeQuickLinks(TRUE,HLI_Functions,0);
+ startQuickIndexList(ol);
+
+ // index item for global member list
+ startQuickIndexItem(ol,
+ getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
+ ol.writeString(fixSpaces(getCmhlInfo(0)->title));
+ endQuickIndexItem(ol);
+
+ int i;
+ // index items per category member lists
+ for (i=1;i<CMHL_Total;i++)
+ {
+ if (documentedClassMembers[i]>0)
+ {
+ startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
+ ol.writeString(fixSpaces(getCmhlInfo(i)->title));
+ //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
+ // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data());
+ endQuickIndexItem(ol);
+ }
+ }
+
+ endQuickIndexList(ol);
+
+ // quick alphabetical index
+ if (quickIndex)
+ {
+ writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
+ getCmhlInfo(hl)->fname,multiPageIndex);
+ }
+ }
+ ol.endQuickIndices();
+ ol.writeSplitBar(fileName);
+ ol.writeSearchInfo();
+
+ ol.startContents();
+
+ if (hl==CMHL_All)
+ {
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL")));
+ ol.endTextBlock();
+ }
+ else
+ {
+ // hack to work around a mozilla bug, which refuses to switch to
+ // normal lists otherwise
+ ol.writeString(" ");
+ }
+
+ writeMemberList(ol,quickIndex,
+ multiPageIndex?page:-1,
+ g_memberIndexLetterUsed[hl],
+ Definition::TypeClass);
+ endFile(ol);
+ first=FALSE;
+ }
+
+ if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
+
+ ol.popGeneratorState();
+}
+
+static void writeClassMemberIndex(OutputList &ol)
+{
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
+ bool addToIndex = lne==0 || lne->visible();
+
+ if (documentedClassMembers[CMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0);
+ Doxygen::indexList->incContentsDepth();
+ }
+ writeClassMemberIndexFiltered(ol,CMHL_All);
+ writeClassMemberIndexFiltered(ol,CMHL_Functions);
+ writeClassMemberIndexFiltered(ol,CMHL_Variables);
+ writeClassMemberIndexFiltered(ol,CMHL_Typedefs);
+ writeClassMemberIndexFiltered(ol,CMHL_Enums);
+ writeClassMemberIndexFiltered(ol,CMHL_EnumValues);
+ writeClassMemberIndexFiltered(ol,CMHL_Properties);
+ writeClassMemberIndexFiltered(ol,CMHL_Events);
+ writeClassMemberIndexFiltered(ol,CMHL_Related);
+ if (documentedClassMembers[CMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+/** Helper class representing a file member in the navigation menu. */
+struct FmhlInfo
+{
+ FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
+ const char *fname;
+ QCString title;
+};
+
+static const FmhlInfo *getFmhlInfo(int hl)
+{
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static FmhlInfo fmhlInfo[] =
+ {
+ FmhlInfo("globals", theTranslator->trAll()),
+ FmhlInfo("globals_func",
+ fortranOpt ? theTranslator->trSubprograms() :
+ vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
+ theTranslator->trFunctions()),
+ FmhlInfo("globals_vars",theTranslator->trVariables()),
+ FmhlInfo("globals_type",theTranslator->trTypedefs()),
+ FmhlInfo("globals_enum",theTranslator->trEnumerations()),
+ FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
+ FmhlInfo("globals_defs",theTranslator->trDefines())
+ };
+ return &fmhlInfo[hl];
+}
+
+static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
+{
+ if (documentedFileMembers[hl]==0) return;
+
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+
+ bool multiPageIndex=FALSE;
+ if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
+ {
+ multiPageIndex=TRUE;
+ }
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString extension=Doxygen::htmlFileExtension;
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
+ QCString title = lne ? lne->title() : theTranslator->trFileMembers();
+ bool addToIndex = lne==0 || lne->visible();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0,
+ getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
+ if (multiPageIndex) Doxygen::indexList->incContentsDepth();
+ }
+
+ bool first=TRUE;
+ SIntDict<MemberIndexList>::Iterator it(g_fileIndexLetterUsed[hl]);
+ MemberIndexList *ml;
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ uint page = ml->letter();
+ QCString fileName = getFmhlInfo(hl)->fname;
+ if (multiPageIndex)
+ {
+ if (!first)
+ {
+ fileName+="_"+letterToLabel(page);
+ }
+ QCString cs = QString(QChar(page)).utf8();
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
+ }
+ }
+ bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
+
+ ol.startFile(fileName+extension,0,title);
+ ol.startQuickIndices();
+ if (!disableIndex)
+ {
+ ol.writeQuickLinks(TRUE,HLI_Globals,0);
+ startQuickIndexList(ol);
+
+ // index item for all file member lists
+ startQuickIndexItem(ol,
+ getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
+ ol.writeString(fixSpaces(getFmhlInfo(0)->title));
+ endQuickIndexItem(ol);
+
+ int i;
+ // index items for per category member lists
+ for (i=1;i<FMHL_Total;i++)
+ {
+ if (documentedFileMembers[i]>0)
+ {
+ startQuickIndexItem(ol,
+ getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
+ ol.writeString(fixSpaces(getFmhlInfo(i)->title));
+ endQuickIndexItem(ol);
+ }
+ }
+
+ endQuickIndexList(ol);
+
+ if (quickIndex)
+ {
+ writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
+ getFmhlInfo(hl)->fname,multiPageIndex);
+ }
+ }
+ ol.endQuickIndices();
+ ol.writeSplitBar(fileName);
+ ol.writeSearchInfo();
+
+ ol.startContents();
+
+ if (hl==FMHL_All)
+ {
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL")));
+ ol.endTextBlock();
+ }
+ else
+ {
+ // hack to work around a mozilla bug, which refuses to switch to
+ // normal lists otherwise
+ ol.writeString(" ");
+ }
+
+ writeMemberList(ol,quickIndex,
+ multiPageIndex?page:-1,
+ g_fileIndexLetterUsed[hl],
+ Definition::TypeFile);
+ endFile(ol);
+ first=FALSE;
+ }
+ if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
+ ol.popGeneratorState();
+}
+
+static void writeFileMemberIndex(OutputList &ol)
+{
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
+ bool addToIndex = lne==0 || lne->visible();
+ if (documentedFileMembers[FMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0);
+ Doxygen::indexList->incContentsDepth();
+ }
+ writeFileMemberIndexFiltered(ol,FMHL_All);
+ writeFileMemberIndexFiltered(ol,FMHL_Functions);
+ writeFileMemberIndexFiltered(ol,FMHL_Variables);
+ writeFileMemberIndexFiltered(ol,FMHL_Typedefs);
+ writeFileMemberIndexFiltered(ol,FMHL_Enums);
+ writeFileMemberIndexFiltered(ol,FMHL_EnumValues);
+ writeFileMemberIndexFiltered(ol,FMHL_Defines);
+ if (documentedFileMembers[FMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+/** Helper class representing a namespace member in the navigation menu. */
+struct NmhlInfo
+{
+ NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
+ const char *fname;
+ QCString title;
+};
+
+static const NmhlInfo *getNmhlInfo(int hl)
+{
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static NmhlInfo nmhlInfo[] =
+ {
+ NmhlInfo("namespacemembers", theTranslator->trAll()),
+ NmhlInfo("namespacemembers_func",
+ fortranOpt ? theTranslator->trSubprograms() :
+ vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
+ theTranslator->trFunctions()),
+ NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
+ NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
+ NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
+ NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
+ };
+ return &nmhlInfo[hl];
+}
+
+//----------------------------------------------------------------------------
+
+static void writeNamespaceMemberIndexFiltered(OutputList &ol,
+ NamespaceMemberHighlight hl)
+{
+ if (documentedNamespaceMembers[hl]==0) return;
+
+ static bool disableIndex = Config_getBool("DISABLE_INDEX");
+
+
+ bool multiPageIndex=FALSE;
+ if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
+ {
+ multiPageIndex=TRUE;
+ }
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString extension=Doxygen::htmlFileExtension;
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
+ QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers();
+ bool addToIndex = lne==0 || lne->visible();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0,
+ getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
+ if (multiPageIndex) Doxygen::indexList->incContentsDepth();
+ }
+
+ bool first=TRUE;
+ SIntDict<MemberIndexList>::Iterator it(g_namespaceIndexLetterUsed[hl]);
+ MemberIndexList *ml;
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ uint page = ml->letter();
+ QCString fileName = getNmhlInfo(hl)->fname;
+ if (multiPageIndex)
+ {
+ if (!first)
+ {
+ fileName+="_"+letterToLabel(page);
+ }
+ QCString cs = QString(QChar(page)).utf8();
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
+ }
+ }
+ bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
+
+ ol.startFile(fileName+extension,0,title);
+ ol.startQuickIndices();
+ if (!disableIndex)
+ {
+ ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0);
+ startQuickIndexList(ol);
+
+ // index item for all namespace member lists
+ startQuickIndexItem(ol,
+ getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
+ ol.writeString(fixSpaces(getNmhlInfo(0)->title));
+ endQuickIndexItem(ol);
+
+ int i;
+ // index items per category member lists
+ for (i=1;i<NMHL_Total;i++)
+ {
+ if (documentedNamespaceMembers[i]>0)
+ {
+ startQuickIndexItem(ol,
+ getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
+ ol.writeString(fixSpaces(getNmhlInfo(i)->title));
+ endQuickIndexItem(ol);
+ }
+ }
+
+ endQuickIndexList(ol);
+
+ if (quickIndex)
+ {
+ writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
+ getNmhlInfo(hl)->fname,multiPageIndex);
+ }
+
+ }
+ ol.endQuickIndices();
+ ol.writeSplitBar(fileName);
+ ol.writeSearchInfo();
+
+ ol.startContents();
+
+ if (hl==NMHL_All)
+ {
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL")));
+ ol.endTextBlock();
+ }
+ else
+ {
+ // hack to work around a mozilla bug, which refuses to switch to
+ // normal lists otherwise
+ ol.writeString(" ");
+ }
+
+ writeMemberList(ol,quickIndex,
+ multiPageIndex?page:-1,
+ g_namespaceIndexLetterUsed[hl],
+ Definition::TypeNamespace);
+ endFile(ol);
+ }
+ if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
+ ol.popGeneratorState();
+}
+
+static void writeNamespaceMemberIndex(OutputList &ol)
+{
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
+ bool addToIndex = lne==0 || lne->visible();
+ if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0);
+ Doxygen::indexList->incContentsDepth();
+ }
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ writeNamespaceMemberIndexFiltered(ol,NMHL_All);
+ writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
+ writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
+ writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
+ writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
+ writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
+ if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+
+static void writeExampleIndex(OutputList &ol)
+{
+ if (Doxygen::exampleSDict->count()==0) return;
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples);
+ QCString title = lne ? lne->title() : theTranslator->trExamples();
+ bool addToIndex = lne==0 || lne->visible();
+
+ startFile(ol,"examples",0,title,HLI_Examples);
+
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+
+ ol.startContents();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription());
+ ol.endTextBlock();
+
+ ol.startItemList();
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ ol.startItemListItem();
+ QCString n=pd->getOutputFileBase();
+ if (!pd->title().isEmpty())
+ {
+ ol.writeObjectLink(0,n,0,pd->title());
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE);
+ }
+ }
+ else
+ {
+ ol.writeObjectLink(0,n,0,pd->name());
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE);
+ }
+ }
+ ol.endItemListItem();
+ ol.writeString("\n");
+ }
+ ol.endItemList();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+
+//----------------------------------------------------------------------------
+
+static void countRelatedPages(int &docPages,int &indexPages)
+{
+ docPages=indexPages=0;
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if ( pd->visibleInIndex())
+ {
+ indexPages++;
+ }
+ if ( pd->documentedPage())
+ {
+ docPages++;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void writePages(PageDef *pd,FTVHelp *ftv)
+{
+ //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
+ bool addToIndex = lne==0 || lne->visible();
+ if (!addToIndex) return;
+
+ bool hasSubPages = pd->hasSubPages();
+ bool hasSections = pd->hasSections();
+
+ if (pd->visibleInIndex())
+ {
+ QCString pageTitle;
+
+ if (pd->title().isEmpty())
+ pageTitle=pd->name();
+ else
+ pageTitle=filterTitle(pd->title());
+
+ if (ftv)
+ {
+ //printf("*** adding %s\n",pageTitle.data());
+ ftv->addContentsItem(
+ hasSubPages,pageTitle,
+ pd->getReference(),pd->getOutputFileBase(),
+ 0,hasSubPages,TRUE,pd);
+ }
+ if (addToIndex && pd!=Doxygen::mainPage)
+ {
+ Doxygen::indexList->addContentsItem(
+ hasSubPages,pageTitle,
+ pd->getReference(),pd->getOutputFileBase(),
+ 0,hasSubPages,TRUE);
+ }
+ }
+ if (hasSubPages && ftv) ftv->incContentsDepth();
+ bool doIndent = (hasSections || hasSubPages) &&
+ (pd!=Doxygen::mainPage || mainPageHasTitle());
+ if (doIndent)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ if (hasSections)
+ {
+ pd->addSectionsToIndex();
+ }
+ PageSDict *subPages = pd->getSubPages();
+ if (subPages)
+ {
+ PageSDict::Iterator pi(*subPages);
+ PageDef *subPage;
+ for (pi.toFirst();(subPage=pi.current());++pi)
+ {
+ writePages(subPage,ftv);
+ }
+ }
+ if (hasSubPages && ftv) ftv->decContentsDepth();
+ if (doIndent)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ //printf("end writePages()=%s\n",pd->title().data());
+}
+
+//----------------------------------------------------------------------------
+
+static void writePageIndex(OutputList &ol)
+{
+ if (indexedPages==0) return;
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
+ QCString title = lne ? lne->title() : theTranslator->trRelatedPages();
+ startFile(ol,"pages",0,title,HLI_Pages);
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trRelatedPagesDescription());
+ ol.endTextBlock();
+
+ {
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if ((pd->getOuterScope()==0 ||
+ pd->getOuterScope()->definitionType()!=Definition::TypePage) && // not a sub page
+ !pd->isReference() // not an external page
+ )
+ {
+ writePages(pd,ftv);
+ }
+ }
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.writeString(outStr);
+ delete ftv;
+ }
+
+// ol.popGeneratorState();
+ // ------
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+//----------------------------------------------------------------------------
+
+static int countGroups()
+{
+ int count=0;
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (!gd->isReference())
+ {
+ gd->visited=FALSE;
+ count++;
+ }
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+
+static int countDirs()
+{
+ int count=0;
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ for (dli.toFirst();(dd=dli.current());++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ dd->visited=FALSE;
+ count++;
+ }
+ }
+ return count;
+}
+
+
+//----------------------------------------------------------------------------
+
+void writeGraphInfo(OutputList &ol)
+{
+ if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ generateGraphLegend(Config_getString("HTML_OUTPUT"));
+
+ bool &stripCommentsStateRef = Config_getBool("STRIP_CODE_COMMENTS");
+ bool oldStripCommentsState = stripCommentsStateRef;
+ bool &createSubdirs = Config_getBool("CREATE_SUBDIRS");
+ bool oldCreateSubdirs = createSubdirs;
+ // temporarily disable the stripping of comments for our own code example!
+ stripCommentsStateRef = FALSE;
+ // temporarily disable create subdirs for linking to our example
+ createSubdirs = FALSE;
+
+ startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
+ startTitle(ol,0);
+ ol.parseText(theTranslator->trLegendTitle());
+ endTitle(ol,0,0);
+ ol.startContents();
+ QCString legendDocs = theTranslator->trLegendDocs();
+ int s = legendDocs.find("<center>");
+ int e = legendDocs.find("</center>");
+ if (Config_getEnum("DOT_IMAGE_FORMAT")=="svg" && s!=-1 && e!=-1)
+ {
+ legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e);
+ //printf("legendDocs=%s\n",legendDocs.data());
+ }
+ FileDef fd("","graph_legend");
+ ol.generateDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE);
+
+ // restore config settings
+ stripCommentsStateRef = oldStripCommentsState;
+ createSubdirs = oldCreateSubdirs;
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+
+
+//----------------------------------------------------------------------------
+/*!
+ * write groups as hierarchical trees
+ */
+static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
+{
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (level>20)
+ {
+ warn(gd->getDefFileName(),gd->getDefLine(),
+ "maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
+ );
+ return;
+ }
+
+ /* Some groups should appear twice under different parent-groups.
+ * That is why we should not check if it was visited
+ */
+ if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) &&
+ gd->isVisible() &&
+ (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
+ )
+ {
+ //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
+ // write group info
+ bool hasSubGroups = gd->getSubGroups()->count()>0;
+ bool hasSubPages = gd->getPages()->count()>0;
+ int numSubItems = 0;
+ if (1 /*Config_getBool("TOC_EXPAND")*/)
+ {
+ QListIterator<MemberList> mli(gd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ numSubItems += ml->count();
+ }
+ }
+ numSubItems += gd->getNamespaces()->count();
+ numSubItems += gd->getClasses()->count();
+ numSubItems += gd->getFiles()->count();
+ numSubItems += gd->getDirs()->count();
+ numSubItems += gd->getPages()->count();
+ }
+
+ bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
+ //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->addContentsItem(hasSubGroups,gd->groupTitle(),
+ gd->getReference(),gd->getOutputFileBase(),0,
+ FALSE,FALSE,gd);
+ ftv->incContentsDepth();
+ }
+
+ //ol.writeListItem();
+ //ol.startTextLink(gd->getOutputFileBase(),0);
+ //parseText(ol,gd->groupTitle());
+ //ol.endTextLink();
+
+ ol.startIndexListItem();
+ ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
+ ol.parseText(gd->groupTitle());
+ ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
+ if (gd->isReference())
+ {
+ ol.startTypewriter();
+ ol.docify(" [external]");
+ ol.endTypewriter();
+ }
+
+ QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex)
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ MemberList *ml = gd->getMemberList(lmd->type);
+ if (ml)
+ {
+ MemberListIterator mi(*ml);
+ MemberDef *md;
+ for (mi.toFirst();(md=mi.current());++mi)
+ {
+ MemberList *enumList = md->enumFieldList();
+ bool isDir = enumList!=0 && md->isEnumerate();
+ if (md->isVisible() && md->name().find('@')==-1)
+ {
+ Doxygen::indexList->addContentsItem(isDir,
+ md->name(),md->getReference(),
+ md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
+ }
+ if (isDir)
+ {
+ Doxygen::indexList->incContentsDepth();
+ MemberListIterator emli(*enumList);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ if (emd->isVisible())
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ emd->name(),emd->getReference(),emd->getOutputFileBase(),
+ emd->anchor(),FALSE,addToIndex);
+ }
+ }
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex)
+ {
+ ClassSDict::Iterator it(*gd->getClasses());
+ ClassDef *cd;
+ for (;(cd=it.current());++it)
+ {
+ //bool nestedClassInSameGroup =
+ // cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass &&
+ // cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd);
+ //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup);
+ if (cd->isVisible() /*&& !nestedClassInSameGroup*/)
+ {
+ //if (cd->isEmbeddedInOuterScope())
+ //{
+ //printf("add class & members %d\n",addToIndex);
+ addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),addToIndex,TRUE);
+ //}
+ //else // only index the class, not its members
+ //{
+ // printf("%s: add class only\n",cd->name().data());
+ // Doxygen::indexList->addContentsItem(FALSE,
+ // cd->displayName(TRUE),cd->getReference(),
+ // cd->getOutputFileBase(),cd->anchor(),addToIndex,TRUE);
+ //}
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex)
+ {
+ NamespaceSDict::Iterator it(*gd->getNamespaces());
+ NamespaceDef *nd;
+ for (;(nd=it.current());++it)
+ {
+ if (nd->isVisible())
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ nd->localName(),nd->getReference(),
+ nd->getOutputFileBase(),0,FALSE,FALSE);
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex)
+ {
+ QListIterator<FileDef> it(*gd->getFiles());
+ FileDef *fd;
+ for (;(fd=it.current());++it)
+ {
+ if (fd->isVisible())
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ fd->displayName(),fd->getReference(),
+ fd->getOutputFileBase(),0,FALSE,FALSE);
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex)
+ {
+ QListIterator<DirDef> it(*gd->getDirs());
+ DirDef *dd;
+ for (;(dd=it.current());++it)
+ {
+ if (dd->isVisible())
+ {
+ Doxygen::indexList->addContentsItem(FALSE,
+ dd->shortName(),dd->getReference(),
+ dd->getOutputFileBase(),0,FALSE,FALSE);
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
+ {
+ SDict<PageDef>::Iterator it(*gd->getPages());
+ PageDef *pd;
+ for (;(pd=it.current());++it)
+ {
+ SectionInfo *si=0;
+ if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name());
+ bool hasSubPages = pd->hasSubPages();
+ bool hasSections = pd->hasSections();
+ Doxygen::indexList->addContentsItem(
+ hasSubPages || hasSections,
+ convertToHtml(pd->title(),TRUE),
+ gd->getReference(),
+ gd->getOutputFileBase(),
+ si ? si->label.data() : 0,
+ hasSubPages || hasSections,
+ TRUE); // addToNavIndex
+ if (hasSections || hasSubPages)
+ {
+ Doxygen::indexList->incContentsDepth();
+ }
+ if (hasSections)
+ {
+ pd->addSectionsToIndex();
+ }
+ writePages(pd,0);
+ if (hasSections || hasSubPages)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ }
+ else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
+ {
+ if (gd->getSubGroups()->count()>0)
+ {
+ startIndexHierarchy(ol,level+1);
+ QListIterator<GroupDef> gli(*gd->getSubGroups());
+ GroupDef *subgd = 0;
+ for (gli.toFirst();(subgd=gli.current());++gli)
+ {
+ writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex);
+ }
+ endIndexHierarchy(ol,level+1);
+ }
+ }
+ }
+
+ ol.endIndexListItem();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->decContentsDepth();
+ }
+ //gd->visited=TRUE;
+ }
+}
+
+static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
+{
+ if (ftv)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ }
+ startIndexHierarchy(ol,0);
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
+ }
+ endIndexHierarchy(ol,0);
+ if (ftv)
+ {
+ ol.popGeneratorState();
+ }
+}
+
+#if 0
+static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
+{
+ static bool externalGroups = Config_getBool("EXTERNAL_GROUPS");
+ /* Some groups should appear twice under different parent-groups.
+ * That is why we should not check if it was visited
+ */
+ if ((!gd->isASubGroup() || level>0) &&
+ gd->isVisible() &&
+ (!gd->isReference() || externalGroups) // hide external groups by default
+ )
+ {
+ if (ftv)
+ {
+ ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
+ ftv->incContentsDepth();
+ }
+ if (ftv)
+ {
+ ftv->decContentsDepth();
+ }
+ }
+}
+
+static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
+{
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ writeGroupTree(gd,ftv,0,addToIndex);
+ }
+}
+#endif
+
+//----------------------------------------------------------------------------
+
+static void writeGroupIndex(OutputList &ol)
+{
+ if (documentedGroups==0) return;
+ ol.pushGeneratorState();
+ // 1.{
+ ol.disable(OutputGenerator::Man);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules);
+ QCString title = lne ? lne->title() : theTranslator->trModules();
+ bool addToIndex = lne==0 || lne->visible();
+
+ startFile(ol,"modules",0,title,HLI_Modules);
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+ ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription());
+ ol.endTextBlock();
+
+ // ---------------
+ // Normal group index for Latex/RTF
+ // ---------------
+ // 2.{
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ Doxygen::indexList->disable();
+
+ writeGroupHierarchy(ol,0,FALSE);
+
+ Doxygen::indexList->enable();
+ ol.popGeneratorState();
+ // 2.}
+
+ // ---------------
+ // interactive group index for HTML
+ // ---------------
+ // 2.{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ {
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ FTVHelp* ftv = new FTVHelp(FALSE);
+ writeGroupHierarchy(ol,ftv,addToIndex);
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString(outStr);
+ delete ftv;
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ }
+ ol.popGeneratorState();
+ // 2.}
+
+ endFile(ol);
+ ol.popGeneratorState();
+ // 1.}
+}
+
+//----------------------------------------------------------------------------
+
+#if 0
+static void writeDirIndex(OutputList &ol)
+{
+ if (documentedDirs==0) return;
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
+ QCString title = lne ? lne->title() : theTranslator->trDirectories();
+ bool addToIndex=FALSE; //lne==0 || lne->visible();
+
+ startFile(ol,"dirs",0,title,HLI_Directories);
+ startTitle(ol,0);
+ ol.parseText(title);
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startTextBlock();
+
+ if (addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE);
+ Doxygen::indexList->incContentsDepth();
+ }
+ ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
+ ol.endTextBlock();
+
+ FTVHelp* ftv = 0;
+ bool treeView=Config_getBool("USE_INLINE_TREES");
+ if (treeView)
+ {
+ ftv = new FTVHelp(FALSE);
+ }
+
+ writeDirHierarchy(ol,ftv,addToIndex);
+
+ if (ftv)
+ {
+ QGString outStr;
+ FTextStream t(&outStr);
+ ftv->generateTreeViewInline(t);
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString(outStr);
+ ol.popGeneratorState();
+ delete ftv;
+ }
+ if (addToIndex)
+ {
+ Doxygen::indexList->decContentsDepth();
+ }
+ endFile(ol);
+ ol.popGeneratorState();
+}
+#endif
+
+//----------------------------------------------------------------------------
+
+static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne)
+{
+ if (lne->baseFile().left(9)=="usergroup")
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ startFile(ol,lne->baseFile(),0,lne->title(),HLI_UserGroup);
+ startTitle(ol,0);
+ ol.parseText(lne->title());
+ endTitle(ol,0,0);
+ ol.startContents();
+ QListIterator<LayoutNavEntry> li(lne->children());
+ LayoutNavEntry *entry;
+ int count=0;
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible()) count++;
+ }
+ if (count>0)
+ {
+ ol.writeString("<ul>\n");
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ if (entry->visible())
+ {
+ ol.writeString("<li><a href=\""+entry->url()+"\"><span>"+
+ fixSpaces(entry->title())+"</span></a></li>\n");
+ }
+ }
+ ol.writeString("</ul>\n");
+ }
+ endFile(ol);
+ ol.popGeneratorState();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+
+static void writeIndex(OutputList &ol)
+{
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static QCString projectName = Config_getString("PROJECT_NAME");
+ // save old generator state
+ ol.pushGeneratorState();
+
+ QCString projPrefix;
+ if (!projectName.isEmpty())
+ {
+ projPrefix=projectName+" ";
+ }
+
+ //--------------------------------------------------------------------
+ // write HTML index
+ //--------------------------------------------------------------------
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString defFileName =
+ Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]";
+ int defLine =
+ Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1;
+
+ QCString title;
+ if (!mainPageHasTitle())
+ {
+ title = theTranslator->trMainPage();
+ }
+ else
+ {
+ title = filterTitle(Doxygen::mainPage->title());
+ }
+
+ QCString indexName="index";
+ ol.startFile(indexName,0,title);
+
+ if (Doxygen::mainPage)
+ {
+ if (
+ (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0)
+ ) // to avoid duplicate entries in the treeview
+ {
+ Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE);
+ }
+ if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections())
+ {
+ writePages(Doxygen::mainPage,0);
+ }
+ }
+
+ ol.startQuickIndices();
+ if (!Config_getBool("DISABLE_INDEX"))
+ {
+ ol.writeQuickLinks(TRUE,HLI_Main,0);
+ }
+ ol.endQuickIndices();
+ ol.writeSplitBar(indexName);
+ ol.writeSearchInfo();
+ bool headerWritten=FALSE;
+ if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
+ {
+ if (Doxygen::mainPage->title().lower()!="notitle")
+ {
+ ol.startHeaderSection();
+ ol.startTitleHead(0);
+ ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
+ Doxygen::mainPage,0,Doxygen::mainPage->title(),
+ TRUE,FALSE,0,TRUE,FALSE);
+ headerWritten = TRUE;
+ }
+ }
+ else
+ {
+ if (!projectName.isEmpty())
+ {
+ ol.startHeaderSection();
+ ol.startTitleHead(0);
+ ol.parseText(projPrefix+theTranslator->trDocumentation());
+ headerWritten = TRUE;
+ }
+ }
+ if (headerWritten)
+ {
+ ol.endTitleHead(0,0);
+ ol.endHeaderSection();
+ }
+
+ ol.startContents();
+ if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0)
+ {
+ ol.writeQuickLinks(FALSE,HLI_Main,0);
+ }
+
+ if (Doxygen::mainPage)
+ {
+ Doxygen::insideMainPage=TRUE;
+ if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
+ {
+ Doxygen::mainPage->writeToc(ol);
+ }
+
+ ol.startTextBlock();
+ ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
+ Doxygen::mainPage->documentation(),TRUE,FALSE
+ /*,Doxygen::mainPage->sectionDict*/);
+ ol.endTextBlock();
+
+ Doxygen::insideMainPage=FALSE;
+ }
+
+ endFile(ol);
+ ol.disable(OutputGenerator::Html);
+
+ //--------------------------------------------------------------------
+ // write LaTeX/RTF index
+ //--------------------------------------------------------------------
+ ol.enable(OutputGenerator::Latex);
+ ol.enable(OutputGenerator::RTF);
+
+ ol.startFile("refman",0,0);
+ ol.startIndexSection(isTitlePageStart);
+ if (!Config_getString("LATEX_HEADER").isEmpty())
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+
+ if (projPrefix.isEmpty())
+ {
+ ol.parseText(theTranslator->trReferenceManual());
+ }
+ else
+ {
+ ol.parseText(projPrefix);
+ }
+
+ if (!Config_getString("PROJECT_NUMBER").isEmpty())
+ {
+ ol.startProjectNumber();
+ ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
+ ol.endProjectNumber();
+ }
+ ol.endIndexSection(isTitlePageStart);
+ ol.startIndexSection(isTitlePageAuthor);
+ ol.parseText(theTranslator->trGeneratedBy());
+ ol.endIndexSection(isTitlePageAuthor);
+ ol.enable(OutputGenerator::Latex);
+
+ ol.lastIndexPage();
+ if (Doxygen::mainPage)
+ {
+ ol.startIndexSection(isMainPage);
+ if (mainPageHasTitle())
+ {
+ ol.parseText(Doxygen::mainPage->title());
+ }
+ else
+ {
+ ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
+ }
+ ol.endIndexSection(isMainPage);
+ }
+ if (documentedPages>0)
+ {
+ //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
+ //ol.endIndexSection(isPageDocumentation);
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=pdi.toFirst();
+ bool first=Doxygen::mainPage==0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (!pd->getGroupDef() && !pd->isReference() &&
+ (!pd->hasParentPage() || // not inside other page
+ (Doxygen::mainPage==pd->getOuterScope())) // or inside main page
+ )
+ {
+ bool isCitationPage = pd->name()=="citelist";
+ if (isCitationPage)
+ {
+ // For LaTeX the bibliograph is already written by \bibliography
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Latex);
+ }
+ QCString title = pd->title();
+ if (title.isEmpty()) title=pd->name();
+
+ ol.startIndexSection(isPageDocumentation);
+ ol.parseText(title);
+ ol.endIndexSection(isPageDocumentation);
+
+ ol.pushGeneratorState(); // write TOC title (RTF only)
+ ol.disableAllBut(OutputGenerator::RTF);
+ ol.startIndexSection(isPageDocumentation2);
+ ol.parseText(title);
+ ol.endIndexSection(isPageDocumentation2);
+ ol.popGeneratorState();
+
+ ol.writeAnchor(0,pd->getOutputFileBase());
+
+ ol.writePageLink(pd->getOutputFileBase(),first);
+ first=FALSE;
+
+ if (isCitationPage)
+ {
+ ol.popGeneratorState();
+ }
+ }
+ }
+ }
+
+ if (!Config_getBool("LATEX_HIDE_INDICES"))
+ {
+ //if (indexedPages>0)
+ //{
+ // ol.startIndexSection(isPageIndex);
+ // ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
+ // ol.endIndexSection(isPageIndex);
+ //}
+ if (documentedGroups>0)
+ {
+ ol.startIndexSection(isModuleIndex);
+ ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
+ ol.endIndexSection(isModuleIndex);
+ }
+ if (documentedNamespaces>0)
+ {
+ ol.startIndexSection(isNamespaceIndex);
+ ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
+ ol.endIndexSection(isNamespaceIndex);
+ }
+ if (hierarchyClasses>0)
+ {
+ ol.startIndexSection(isClassHierarchyIndex);
+ ol.parseText(/*projPrefix+*/
+ (fortranOpt ? theTranslator->trCompoundIndexFortran() :
+ vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
+ theTranslator->trHierarchicalIndex()
+ ));
+ ol.endIndexSection(isClassHierarchyIndex);
+ }
+ if (annotatedClassesPrinted>0)
+ {
+ ol.startIndexSection(isCompoundIndex);
+ ol.parseText(/*projPrefix+*/
+ (fortranOpt ? theTranslator->trCompoundIndexFortran() :
+ vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
+ theTranslator->trCompoundIndex()
+ ));
+ ol.endIndexSection(isCompoundIndex);
+ }
+ if (documentedFiles>0)
+ {
+ ol.startIndexSection(isFileIndex);
+ ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
+ ol.endIndexSection(isFileIndex);
+ }
+ }
+ if (documentedGroups>0)
+ {
+ ol.startIndexSection(isModuleDocumentation);
+ ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
+ ol.endIndexSection(isModuleDocumentation);
+ }
+ if (documentedNamespaces>0)
+ {
+ ol.startIndexSection(isNamespaceDocumentation);
+ ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
+ ol.endIndexSection(isNamespaceDocumentation);
+ }
+ if (annotatedClassesPrinted>0)
+ {
+ ol.startIndexSection(isClassDocumentation);
+ ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
+ ol.endIndexSection(isClassDocumentation);
+ }
+ if (documentedFiles>0)
+ {
+ ol.startIndexSection(isFileDocumentation);
+ ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
+ ol.endIndexSection(isFileDocumentation);
+ }
+ if (Doxygen::exampleSDict->count()>0)
+ {
+ ol.startIndexSection(isExampleDocumentation);
+ ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
+ ol.endIndexSection(isExampleDocumentation);
+ }
+ ol.endIndexSection(isEndIndex);
+ endFile(ol);
+
+ if (Doxygen::mainPage)
+ {
+ Doxygen::insideMainPage=TRUE;
+ ol.disable(OutputGenerator::Man);
+ startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
+ ol.startContents();
+ ol.startTextBlock();
+ ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
+ Doxygen::mainPage->documentation(),FALSE,FALSE
+ );
+ ol.endTextBlock();
+ endFile(ol);
+ ol.enable(OutputGenerator::Man);
+ Doxygen::insideMainPage=FALSE;
+ }
+
+ ol.popGeneratorState();
+}
+
+static QArray<bool> indexWritten;
+
+static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry> &entries)
+{
+ QListIterator<LayoutNavEntry> li(entries);
+ LayoutNavEntry *lne;
+ for (li.toFirst();(lne=li.current());++li)
+ {
+ LayoutNavEntry::Kind kind = lne->kind();
+ uint index = (uint)kind;
+ if (index>=indexWritten.size())
+ {
+ uint i;
+ uint oldSize = indexWritten.size();
+ uint newSize = index+1;
+ indexWritten.resize(newSize);
+ for (i=oldSize;i<newSize;i++) indexWritten.at(i)=FALSE;
+ }
+ //printf("starting %s kind=%d\n",lne->title().data(),lne->kind());
+ bool addToIndex=lne==0 || lne->visible();
+ bool needsClosing=FALSE;
+ if (!indexWritten.at(index))
+ {
+ switch(kind)
+ {
+ case LayoutNavEntry::MainPage:
+ msg("Generating index page...\n");
+ writeIndex(ol);
+ break;
+ case LayoutNavEntry::Pages:
+ msg("Generating page index...\n");
+ writePageIndex(ol);
+ break;
+ case LayoutNavEntry::Modules:
+ msg("Generating module index...\n");
+ writeGroupIndex(ol);
+ break;
+ case LayoutNavEntry::Namespaces:
+ {
+ static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
+ if (showNamespaces)
+ {
+ if (documentedNamespaces>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0);
+ Doxygen::indexList->incContentsDepth();
+ needsClosing=TRUE;
+ }
+ if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file
+ {
+ msg("Generating namespace index...\n");
+ writeNamespaceIndex(ol);
+ }
+ }
+ }
+ break;
+ case LayoutNavEntry::NamespaceList:
+ {
+ static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
+ if (showNamespaces)
+ {
+ msg("Generating namespace index...\n");
+ writeNamespaceIndex(ol);
+ }
+ }
+ break;
+ case LayoutNavEntry::NamespaceMembers:
+ msg("Generating namespace member index...\n");
+ writeNamespaceMemberIndex(ol);
+ break;
+ case LayoutNavEntry::Classes:
+ if (annotatedClasses>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0);
+ Doxygen::indexList->incContentsDepth();
+ needsClosing=TRUE;
+ }
+ if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file
+ {
+ msg("Generating annotated compound index...\n");
+ writeAnnotatedIndex(ol);
+ }
+ break;
+ case LayoutNavEntry::ClassList:
+ msg("Generating annotated compound index...\n");
+ writeAnnotatedIndex(ol);
+ break;
+ case LayoutNavEntry::ClassIndex:
+ msg("Generating alphabetical compound index...\n");
+ writeAlphabeticalIndex(ol);
+ break;
+ case LayoutNavEntry::ClassHierarchy:
+ msg("Generating hierarchical class index...\n");
+ writeHierarchicalIndex(ol);
+ if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
+ {
+ msg("Generating graphical class hierarchy...\n");
+ writeGraphicalClassHierarchy(ol);
+ }
+ break;
+ case LayoutNavEntry::ClassMembers:
+ msg("Generating member index...\n");
+ writeClassMemberIndex(ol);
+ break;
+ case LayoutNavEntry::Files:
+ {
+ static bool showFiles = Config_getBool("SHOW_FILES");
+ if (showFiles)
+ {
+ if (documentedHtmlFiles>0 && addToIndex)
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0);
+ Doxygen::indexList->incContentsDepth();
+ needsClosing=TRUE;
+ }
+ if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file
+ {
+ msg("Generating file index...\n");
+ writeFileIndex(ol);
+ }
+ }
+ }
+ break;
+ case LayoutNavEntry::FileList:
+ {
+ static bool showFiles = Config_getBool("SHOW_FILES");
+ if (showFiles)
+ {
+ msg("Generating file index...\n");
+ writeFileIndex(ol);
+ }
+ }
+ break;
+ case LayoutNavEntry::FileGlobals:
+ msg("Generating file member index...\n");
+ writeFileMemberIndex(ol);
+ break;
+ case LayoutNavEntry::Examples:
+ msg("Generating example index...\n");
+ writeExampleIndex(ol);
+ break;
+ case LayoutNavEntry::User:
+ {
+ // prepend a ! or ^ marker to the URL to avoid tampering with it
+ QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
+ bool isRelative=url.at(0)=='!';
+ if (!url.isEmpty() && !isRelative) // absolute URL
+ {
+ url.prepend("^"); // prepend ^ to absolute URL
+ }
+ bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative);
+ }
+ break;
+ case LayoutNavEntry::UserGroup:
+ if (addToIndex)
+ {
+ QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
+ if (!url.isEmpty())
+ {
+ if (url=="![none]")
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0,FALSE,FALSE);
+ }
+ else
+ {
+ bool isRelative=url.at(0)=='!';
+ if (!isRelative) // absolute URL
+ {
+ url.prepend("^"); // prepend ^ to absolute URL
+ }
+ bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative);
+ }
+ }
+ else
+ {
+ Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE);
+ }
+ Doxygen::indexList->incContentsDepth();
+ needsClosing=TRUE;
+ }
+ writeUserGroupStubPage(ol,lne);
+ break;
+ }
+ if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times
+ {
+ indexWritten.at(index)=TRUE;
+ }
+ }
+ writeIndexHierarchyEntries(ol,lne->children());
+ if (needsClosing)
+ {
+ switch(kind)
+ {
+ case LayoutNavEntry::Namespaces:
+ case LayoutNavEntry::Classes:
+ case LayoutNavEntry::Files:
+ case LayoutNavEntry::UserGroup:
+ Doxygen::indexList->decContentsDepth();
+ break;
+ default:
+ break;
+ }
+ }
+ //printf("ending %s kind=%d\n",lne->title().data(),lne->kind());
+ }
+}
+
+void writeIndexHierarchy(OutputList &ol)
+{
+ LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry();
+ if (lne)
+ {
+ writeIndexHierarchyEntries(ol,lne->children());
+ }
+}
+
diff --git a/src/index.h b/src/index.h
new file mode 100644
index 0000000..6805655
--- /dev/null
+++ b/src/index.h
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef INDEX_H
+#define INDEX_H
+
+#include <qlist.h>
+#include <qcstring.h>
+
+class Definition;
+class MemberDef;
+class OutputList;
+class FTextStream;
+
+/** \brief Abstract interface for index generators. */
+class IndexIntf
+{
+ public:
+ virtual ~IndexIntf() {}
+ virtual void initialize() = 0;
+ virtual void finalize() = 0;
+ virtual void incContentsDepth() = 0;
+ virtual void decContentsDepth() = 0;
+ virtual void addContentsItem(bool isDir, const char *name, const char *ref,
+ const char *file, const char *anchor, bool separateIndex,
+ bool addToNavIndex,Definition *def) = 0;
+ virtual void addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor,const char *title) = 0;
+ virtual void addIndexFile(const char *name) = 0;
+ virtual void addImageFile(const char *name) = 0;
+ virtual void addStyleSheetFile(const char *name) = 0;
+};
+
+/** \brief A list of index interfaces.
+ *
+ * This class itself implements all methods of IndexIntf and
+ * just forwards the calls to all items in the list.
+ */
+class IndexList : public IndexIntf
+{
+ private:
+ QList<IndexIntf> m_intfs;
+
+ // --- foreach implementations for various number of arguments
+
+ void foreach(void (IndexIntf::*methodPtr)())
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)();
+ }
+
+ template<typename A1>
+ void foreach(void (IndexIntf::*methodPtr)(A1),A1 a1)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1);
+ }
+
+ template<typename A1,typename A2,typename A3>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3),A1 a1,A2 a2,A3 a3)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3);
+ }
+
+ template<typename A1,typename A2,typename A3,typename A4>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4),A1 a1,A2 a2,A3 a3,A4 a4)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4);
+ }
+
+ template<typename A1,typename A2,typename A3,typename A4,typename A5>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5);
+ }
+
+ template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6);
+ }
+
+ template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6,A7,A8),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6,a7,a8);
+ }
+
+ template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8,typename A9>
+ void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6,A7,A8,A9),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)
+ {
+ QListIterator<IndexIntf> li(m_intfs);
+ for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6,a7,a8,a9);
+ }
+
+ public:
+ /** Creates a list of indexes */
+ IndexList() { m_intfs.setAutoDelete(TRUE); m_enabled=TRUE; }
+ /** Add an index generator to the list */
+ void addIndex(IndexIntf *intf)
+ { m_intfs.append(intf); }
+ void disable()
+ { m_enabled = FALSE; }
+ void enable()
+ { m_enabled = TRUE; }
+ bool isEnabled() const
+ { return m_enabled; }
+
+ // IndexIntf implementation
+ void initialize()
+ { foreach(&IndexIntf::initialize); }
+ void finalize()
+ { foreach(&IndexIntf::finalize); }
+ void incContentsDepth()
+ { if (m_enabled) foreach(&IndexIntf::incContentsDepth); }
+ void decContentsDepth()
+ { if (m_enabled) foreach(&IndexIntf::decContentsDepth); }
+ void addContentsItem(bool isDir, const char *name, const char *ref,
+ const char *file, const char *anchor,bool separateIndex=FALSE,bool addToNavIndex=FALSE,
+ Definition *def=0)
+ { if (m_enabled) foreach<bool,const char *,const char *,const char *,const char*,bool,bool,Definition *>
+ (&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); }
+ void addIndexItem(Definition *context,MemberDef *md,const char *sectionAnchor=0,const char *title=0)
+ { if (m_enabled) foreach<Definition *,MemberDef *,const char *,const char *>
+ (&IndexIntf::addIndexItem,context,md,sectionAnchor,title); }
+ void addIndexFile(const char *name)
+ { if (m_enabled) foreach<const char *>(&IndexIntf::addIndexFile,name); }
+ void addImageFile(const char *name)
+ { if (m_enabled) foreach<const char *>(&IndexIntf::addImageFile,name); }
+ void addStyleSheetFile(const char *name)
+ { if (m_enabled) foreach<const char *>(&IndexIntf::addStyleSheetFile,name); }
+
+ private:
+ bool m_enabled;
+};
+
+
+enum IndexSections
+{
+ isTitlePageStart,
+ isTitlePageAuthor,
+ isMainPage,
+ isModuleIndex,
+ isDirIndex,
+ isNamespaceIndex,
+ isClassHierarchyIndex,
+ isCompoundIndex,
+ isFileIndex,
+ isPageIndex,
+ isModuleDocumentation,
+ isDirDocumentation,
+ isNamespaceDocumentation,
+ isClassDocumentation,
+ isFileDocumentation,
+ isExampleDocumentation,
+ isPageDocumentation,
+ isPageDocumentation2,
+ isEndIndex
+};
+
+enum HighlightedItem
+{
+ HLI_None=0,
+ HLI_Main,
+ HLI_Modules,
+ //HLI_Directories,
+ HLI_Namespaces,
+ HLI_Hierarchy,
+ HLI_Classes,
+ HLI_Annotated,
+ HLI_Files,
+ HLI_NamespaceMembers,
+ HLI_Functions,
+ HLI_Globals,
+ HLI_Pages,
+ HLI_Examples,
+ HLI_Search,
+ HLI_UserGroup,
+
+ HLI_ClassVisible,
+ HLI_NamespaceVisible,
+ HLI_FileVisible
+};
+
+enum ClassMemberHighlight
+{
+ CMHL_All = 0,
+ CMHL_Functions,
+ CMHL_Variables,
+ CMHL_Typedefs,
+ CMHL_Enums,
+ CMHL_EnumValues,
+ CMHL_Properties,
+ CMHL_Events,
+ CMHL_Related,
+ CMHL_Total = CMHL_Related+1
+};
+
+enum FileMemberHighlight
+{
+ FMHL_All = 0,
+ FMHL_Functions,
+ FMHL_Variables,
+ FMHL_Typedefs,
+ FMHL_Enums,
+ FMHL_EnumValues,
+ FMHL_Defines,
+ FMHL_Total = FMHL_Defines+1
+};
+
+enum NamespaceMemberHighlight
+{
+ NMHL_All = 0,
+ NMHL_Functions,
+ NMHL_Variables,
+ NMHL_Typedefs,
+ NMHL_Enums,
+ NMHL_EnumValues,
+ NMHL_Total = NMHL_EnumValues+1
+};
+
+enum ClassHighlight
+{
+ CHL_All = 0,
+ CHL_Classes,
+ CHL_Structs,
+ CHL_Unions,
+ CHL_Interfaces,
+ CHL_Protocols,
+ CHL_Categories,
+ CHL_Exceptions,
+ CHL_Total = CHL_Exceptions+1
+};
+
+void writeGraphInfo(OutputList &ol);
+void writeIndexHierarchy(OutputList &ol);
+
+void countDataStructures();
+
+extern int annotatedClasses;
+extern int hierarchyClasses;
+extern int documentedFiles;
+extern int documentedGroups;
+extern int documentedNamespaces;
+extern int indexedPages;
+extern int documentedClassMembers[CMHL_Total];
+extern int documentedFileMembers[FMHL_Total];
+extern int documentedNamespaceMembers[NMHL_Total];
+extern int documentedDirs;
+extern int documentedHtmlFiles;
+extern int documentedPages;
+
+void startTitle(OutputList &ol,const char *fileName,Definition *def=0);
+void endTitle(OutputList &ol,const char *fileName,const char *name);
+void startFile(OutputList &ol,const char *name,const char *manName,
+ const char *title,HighlightedItem hli=HLI_None,
+ bool additionalIndices=FALSE,const char *altSidebarName=0);
+void endFile(OutputList &ol,bool skipNavIndex=FALSE,bool skipEndContents=FALSE,
+ const QCString &navPath=QCString());
+void endFileWithNavPath(Definition *d,OutputList &ol);
+
+void initClassMemberIndices();
+void initFileMemberIndices();
+void initNamespaceMemberIndices();
+void addClassMemberNameToIndex(MemberDef *md);
+void addFileMemberNameToIndex(MemberDef *md);
+void addNamespaceMemberNameToIndex(MemberDef *md);
+
+#endif
diff --git a/src/index.xsd b/src/index.xsd
new file mode 100644
index 0000000..d7ab2a9
--- /dev/null
+++ b/src/index.xsd
@@ -0,0 +1,66 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="doxygenindex" type="DoxygenType"/>
+
+ <xsd:complexType name="DoxygenType">
+ <xsd:sequence>
+ <xsd:element name="compound" type="CompoundType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="version" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="CompoundType">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="refid" type="xsd:string" use="required"/>
+ <xsd:attribute name="kind" type="CompoundKind" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="MemberType">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute name="refid" type="xsd:string" use="required"/>
+ <xsd:attribute name="kind" type="MemberKind" use="required"/>
+ </xsd:complexType>
+
+ <xsd:simpleType name="CompoundKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="class"/>
+ <xsd:enumeration value="struct"/>
+ <xsd:enumeration value="union"/>
+ <xsd:enumeration value="interface"/>
+ <xsd:enumeration value="protocol"/>
+ <xsd:enumeration value="category"/>
+ <xsd:enumeration value="exception"/>
+ <xsd:enumeration value="file"/>
+ <xsd:enumeration value="namespace"/>
+ <xsd:enumeration value="group"/>
+ <xsd:enumeration value="page"/>
+ <xsd:enumeration value="example"/>
+ <xsd:enumeration value="dir"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="MemberKind">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="define"/>
+ <xsd:enumeration value="property"/>
+ <xsd:enumeration value="event"/>
+ <xsd:enumeration value="variable"/>
+ <xsd:enumeration value="typedef"/>
+ <xsd:enumeration value="enum"/>
+ <xsd:enumeration value="enumvalue"/>
+ <xsd:enumeration value="function"/>
+ <xsd:enumeration value="signal"/>
+ <xsd:enumeration value="prototype"/>
+ <xsd:enumeration value="friend"/>
+ <xsd:enumeration value="dcop"/>
+ <xsd:enumeration value="slot"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema>
+
diff --git a/src/jquery_fx.js b/src/jquery_fx.js
new file mode 100644
index 0000000..97e5843
--- /dev/null
+++ b/src/jquery_fx.js
@@ -0,0 +1 @@
+(function(c){var a=c.scrollTo=function(f,e,d){c(window).scrollTo(f,e,d)};a.defaults={axis:"xy",duration:parseFloat(c.fn.jquery)>=1.3?0:1};a.window=function(d){return c(window)._scrollable()};c.fn._scrollable=function(){return this.map(function(){var e=this,d=!e.nodeName||c.inArray(e.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!d){return e}var f=(e.contentWindow||e).document||e.ownerDocument||e;return c.browser.safari||f.compatMode=="BackCompat"?f.body:f.documentEl [...]
\ No newline at end of file
diff --git a/src/jquery_p1.js b/src/jquery_p1.js
new file mode 100644
index 0000000..06eb7e6
--- /dev/null
+++ b/src/jquery_p1.js
@@ -0,0 +1,18 @@
+/*!
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/ [...]
+}else{--bw}}if(!bw){bC.resolveWith(bC,bx)}}else{if(bC!==bA){bC.resolveWith(bC,e?[bA]:[])}}return bE}});b.support=(function(){var bJ,bI,bF,bG,bx,bE,bA,bD,bz,bK,bB,by,bw,bv=av.createElement("div"),bH=av.documentElement;bv.setAttribute("className","t");bv.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElemen [...]
+if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);re [...]
diff --git a/src/jquery_p2.js b/src/jquery_p2.js
new file mode 100644
index 0000000..bc16cf6
--- /dev/null
+++ b/src/jquery_p2.js
@@ -0,0 +1,10 @@
+}b.event.add(this,"click._submit keypress._submit",function(bx){var bw=bx.target,bv=b.nodeName(bw,"input")||b.nodeName(bw,"button")?bw.form:L;if(bv&&!bv._submit_attached){b.event.add(bv,"submit._submit",function(e){if(this.parentNode&&!e.isTrigger){b.event.simulate("submit",this.parentNode,e,true)}});bv._submit_attached=true}})},teardown:function(){if(b.nodeName(this,"form")){return false}b.event.remove(this,"._submit")}}}if(!b.support.changeBubbles){b.event.special.change={setup:functio [...]
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU [...]
+},lt:function(bS,bR,e){return bR<e[3]-0},gt:function(bS,bR,e){return bR>e[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV<bU;bV++){if(bT[bV]===bS){return false}}return true}else{by.error(e)}}}},CHILD: [...]
+ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div<div>","</div>"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this [...]
diff --git a/src/jquery_p3.js b/src/jquery_p3.js
new file mode 100644
index 0000000..c0f18ce
--- /dev/null
+++ b/src/jquery_p3.js
@@ -0,0 +1,3 @@
+if(bA>0){if(bv!=="border"){for(;bx<e;bx++){if(!bv){bA-=parseFloat(b.css(by,"padding"+bz[bx]))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[bx]))||0}else{bA-=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}}}return bA+"px"}bA=Z(by,bw,bw);if(bA<0||bA==null){bA=by.style[bw]||0}bA=parseFloat(bA)||0;if(bv){for(;bx<e;bx++){bA+=parseFloat(b.css(by,"padding"+bz[bx]))||0;if(bv!=="padding"){bA+=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[ [...]
+}}}}})}var Q={},a8,m,aB=/^(?:toggle|show|hide)$/,aT=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,a3,aH=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],a4;b.fn.extend({show:function(bx,bA,bz){var bw,by;if(bx||bx===0){return this.animate(a0("show",3),bx,bA,bz)}else{for(var bv=0,e=this.length;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(!b._data(bw,"olddisplay")&&by==="none"){by=bw.style.d [...]
+})}})(window);
\ No newline at end of file
diff --git a/src/jquery_pt.js b/src/jquery_pt.js
new file mode 100644
index 0000000..cbc428d
--- /dev/null
+++ b/src/jquery_pt.js
@@ -0,0 +1,8 @@
+/*!
+ PowerTip - v1.2.0 - 2013-04-03
+ http://stevenbenner.github.com/jquery-powertip/
+ Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouse [...]
\ No newline at end of file
diff --git a/src/jquery_ui.js b/src/jquery_ui.js
new file mode 100644
index 0000000..0ef321d
--- /dev/null
+++ b/src/jquery_ui.js
@@ -0,0 +1,40 @@
+/*!
+ * jQuery UI 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn [...]
+ * jQuery UI Widget 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Wid [...]
+ * jQuery UI Mouse 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseD [...]
+p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizab [...]
+ * jQuery hashchange event - v1.3 - 7/21/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function() [...]
\ No newline at end of file
diff --git a/src/lang_cfg.py b/src/lang_cfg.py
new file mode 100644
index 0000000..efed05f
--- /dev/null
+++ b/src/lang_cfg.py
@@ -0,0 +1,8 @@
+import sys
+
+if (len(sys.argv) > 1):
+ if (sys.argv[1] == "ENONLY"):
+ print("#define ENGLISH_ONLY")
+ else:
+ for x in range(1, len(sys.argv)):
+ print("#define LANG_%s"%(sys.argv[x]))
diff --git a/src/language.cpp b/src/language.cpp
new file mode 100644
index 0000000..3b57de1
--- /dev/null
+++ b/src/language.cpp
@@ -0,0 +1,422 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "language.h"
+#include "lang_cfg.h"
+#include "translator.h"
+#include "translator_en.h"
+#if !defined(ENGLISH_ONLY)
+#include "translator_adapter.h"
+#ifdef LANG_NL
+#include "translator_nl.h"
+#endif
+#ifdef LANG_AM
+#include "translator_am.h"
+#endif
+#ifdef LANG_SV
+#include "translator_sv.h"
+#endif
+#ifdef LANG_CZ
+#include "translator_cz.h"
+#endif
+#ifdef LANG_FR
+#include "translator_fr.h"
+#endif
+#ifdef LANG_ID
+#include "translator_id.h"
+#endif
+#ifdef LANG_IT
+#include "translator_it.h"
+#endif
+#ifdef LANG_DE
+#include "translator_de.h"
+#endif
+#ifdef LANG_JP
+#include "translator_jp.h"
+#endif
+#ifdef LANG_JE
+#include "translator_je.h"
+#endif
+#ifdef LANG_ES
+#include "translator_es.h"
+#endif
+#ifdef LANG_EO
+#include "translator_eo.h"
+#endif
+#ifdef LANG_FI
+#include "translator_fi.h"
+#endif
+#ifdef LANG_RU
+#include "translator_ru.h"
+#endif
+#ifdef LANG_HR
+#include "translator_hr.h"
+#endif
+#ifdef LANG_PL
+#include "translator_pl.h"
+#endif
+#ifdef LANG_PT
+#include "translator_pt.h"
+#endif
+#ifdef LANG_HU
+#include "translator_hu.h"
+#endif
+#ifdef LANG_KE
+#include "translator_ke.h"
+#endif
+#ifdef LANG_KR
+#include "translator_kr.h"
+#endif
+#ifdef LANG_RO
+#include "translator_ro.h"
+#endif
+#ifdef LANG_SI
+#include "translator_si.h"
+#endif
+#ifdef LANG_CN
+#include "translator_cn.h"
+#endif
+#ifdef LANG_TW
+#include "translator_tw.h"
+#endif
+#ifdef LANG_NO
+#include "translator_no.h"
+#endif
+#ifdef LANG_BR
+#include "translator_br.h"
+#endif
+#ifdef LANG_DK
+#include "translator_dk.h"
+#endif
+#ifdef LANG_SK
+#include "translator_sk.h"
+#endif
+#ifdef LANG_UA
+#include "translator_ua.h"
+#endif
+#ifdef LANG_GR
+#include "translator_gr.h"
+#endif
+#ifdef LANG_SR
+#include "translator_sr.h"
+#endif
+#ifdef LANG_CA
+#include "translator_ca.h"
+#endif
+//#ifdef LANG_JS
+//#include "translator_js.h"
+//#endif
+#ifdef LANG_LT
+#include "translator_lt.h"
+#endif
+#ifdef LANG_LV
+#include "translator_lv.h"
+#endif
+#ifdef LANG_ZA
+#include "translator_za.h"
+#endif
+#ifdef LANG_AR
+#include "translator_ar.h"
+#endif
+#ifdef LANG_FA
+#include "translator_fa.h"
+#endif
+#ifdef LANG_MK
+#include "translator_mk.h"
+#endif
+#ifdef LANG_SC
+#include "translator_sc.h"
+#endif
+#ifdef LANG_VI
+#include "translator_vi.h"
+#endif
+#ifdef LANG_TR
+#include "translator_tr.h"
+#endif
+#endif // !ENGLISH_ONLY
+
+#define L_EQUAL(a) !qstricmp(langName,a)
+
+Translator *theTranslator=0;
+
+bool setTranslator(const char *langName)
+{
+ if (L_EQUAL("english"))
+ {
+ theTranslator=new TranslatorEnglish;
+ }
+#if !defined(ENGLISH_ONLY)
+#ifdef LANG_NL
+ else if (L_EQUAL("dutch"))
+ {
+ theTranslator=new TranslatorDutch;
+ }
+#endif
+#ifdef LANG_AM
+ else if (L_EQUAL("armenian"))
+ {
+ theTranslator=new TranslatorArmenian;
+ }
+#endif
+#ifdef LANG_SV
+ else if (L_EQUAL("swedish"))
+ {
+ theTranslator=new TranslatorSwedish;
+ }
+#endif
+#ifdef LANG_CZ
+ else if (L_EQUAL("czech"))
+ {
+ theTranslator=new TranslatorCzech;
+ }
+#endif
+#ifdef LANG_FR
+ else if (L_EQUAL("french"))
+ {
+ theTranslator=new TranslatorFrench;
+ }
+#endif
+#ifdef LANG_ID
+ else if (L_EQUAL("indonesian"))
+ {
+ theTranslator=new TranslatorIndonesian;
+ }
+#endif
+#ifdef LANG_IT
+ else if (L_EQUAL("italian"))
+ {
+ theTranslator=new TranslatorItalian;
+ }
+#endif
+#ifdef LANG_DE
+ else if (L_EQUAL("german"))
+ {
+ theTranslator=new TranslatorGerman;
+ }
+#endif
+#ifdef LANG_JP
+ else if (L_EQUAL("japanese"))
+ {
+ theTranslator=new TranslatorJapanese;
+ }
+#endif
+#ifdef LANG_JE
+ else if (L_EQUAL("japanese-en"))
+ {
+ theTranslator=new TranslatorJapaneseEn;
+ }
+#endif
+#ifdef LANG_ES
+ else if (L_EQUAL("spanish"))
+ {
+ theTranslator=new TranslatorSpanish;
+ }
+#endif
+#ifdef LANG_FI
+ else if (L_EQUAL("finnish"))
+ {
+ theTranslator=new TranslatorFinnish;
+ }
+#endif
+#ifdef LANG_RU
+ else if (L_EQUAL("russian"))
+ {
+ theTranslator=new TranslatorRussian;
+ }
+#endif
+#ifdef LANG_HR
+ else if (L_EQUAL("croatian"))
+ {
+ theTranslator=new TranslatorCroatian;
+ }
+#endif
+#ifdef LANG_PL
+ else if (L_EQUAL("polish"))
+ {
+ theTranslator=new TranslatorPolish;
+ }
+#endif
+#ifdef LANG_PT
+ else if (L_EQUAL("portuguese"))
+ {
+ theTranslator=new TranslatorPortuguese;
+ }
+#endif
+#ifdef LANG_HU
+ else if (L_EQUAL("hungarian"))
+ {
+ theTranslator=new TranslatorHungarian;
+ }
+#endif
+#ifdef LANG_KR
+ else if (L_EQUAL("korean"))
+ {
+ theTranslator=new TranslatorKorean;
+ }
+#endif
+#ifdef LANG_KE
+ else if (L_EQUAL("korean-en"))
+ {
+ theTranslator=new TranslatorKoreanEn;
+ }
+#endif
+#ifdef LANG_RO
+ else if (L_EQUAL("romanian"))
+ {
+ theTranslator=new TranslatorRomanian;
+ }
+#endif
+#ifdef LANG_SI
+ else if (L_EQUAL("slovene"))
+ {
+ theTranslator=new TranslatorSlovene;
+ }
+#endif
+#ifdef LANG_CN
+ else if (L_EQUAL("chinese"))
+ {
+ theTranslator=new TranslatorChinese;
+ }
+#endif
+#ifdef LANG_TW
+ else if (L_EQUAL("chinese-traditional"))
+ {
+ theTranslator=new TranslatorChinesetraditional;
+ }
+#endif
+#ifdef LANG_NO
+ else if (L_EQUAL("norwegian"))
+ {
+ theTranslator=new TranslatorNorwegian;
+ }
+#endif
+#ifdef LANG_BR
+ else if (L_EQUAL("brazilian"))
+ {
+ theTranslator=new TranslatorBrazilian;
+ }
+#endif
+#ifdef LANG_DK
+ else if (L_EQUAL("danish"))
+ {
+ theTranslator=new TranslatorDanish;
+ }
+#endif
+#ifdef LANG_SK
+ else if (L_EQUAL("slovak"))
+ {
+ theTranslator=new TranslatorSlovak;
+ }
+#endif
+#ifdef LANG_UA
+ else if (L_EQUAL("ukrainian"))
+ {
+ theTranslator=new TranslatorUkrainian;
+ }
+#endif
+#ifdef LANG_GR
+ else if (L_EQUAL("greek"))
+ {
+ theTranslator=new TranslatorGreek;
+ }
+#endif
+#ifdef LANG_SR
+ else if (L_EQUAL("serbian"))
+ {
+ theTranslator=new TranslatorSerbian;
+ }
+#endif
+#ifdef LANG_SC
+ else if (L_EQUAL("serbian-cyrillic") || L_EQUAL("serbiancyr")) /* serbiancyr for consistency with older versions */
+ {
+ theTranslator=new TranslatorSerbianCyrillic;
+ }
+#endif
+#ifdef LANG_CA
+ else if (L_EQUAL("catalan"))
+ {
+ theTranslator=new TranslatorCatalan;
+ }
+#endif
+#ifdef LANG_LT
+ else if (L_EQUAL("lithuanian"))
+ {
+ theTranslator=new TranslatorLithuanian;
+ }
+#endif
+#ifdef LANG_LV
+ else if (L_EQUAL("latvian"))
+ {
+ theTranslator=new TranslatorLatvian;
+ }
+#endif
+#ifdef LANG_ZA
+ else if (L_EQUAL("afrikaans"))
+ {
+ theTranslator=new TranslatorAfrikaans;
+ }
+#endif
+#ifdef LANG_AR
+ else if (L_EQUAL("arabic"))
+ {
+ theTranslator=new TranslatorArabic;
+ }
+#endif
+#ifdef LANG_FA
+ else if (L_EQUAL("persian") || L_EQUAL("farsi"))
+ {
+ theTranslator=new TranslatorPersian;
+ }
+#endif
+#ifdef LANG_MK
+ else if (L_EQUAL("macedonian"))
+ {
+ theTranslator=new TranslatorMacedonian;
+ }
+#endif
+#ifdef LANG_VI
+ else if (L_EQUAL("vietnamese"))
+ {
+ theTranslator=new TranslatorVietnamese;
+ }
+#endif
+#ifdef LANG_TR
+ else if (L_EQUAL("turkish"))
+ {
+ theTranslator=new TranslatorTurkish;
+ }
+#endif
+#ifdef LANG_EO
+ else if (L_EQUAL("esperanto"))
+ {
+ theTranslator=new TranslatorEsperanto;
+ }
+#endif
+#endif // ENGLISH_ONLY
+ else // use the default language (i.e. english)
+ {
+ theTranslator=new TranslatorEnglish;
+ return FALSE;
+ }
+
+ QCString msg = theTranslator->updateNeededMessage();
+ if (!msg.isEmpty()) warn_uncond(msg);
+ return TRUE;
+}
diff --git a/src/language.h b/src/language.h
new file mode 100644
index 0000000..4780ab3
--- /dev/null
+++ b/src/language.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef LANGUAGE_H
+#define LANGUAGE_H
+
+#include "translator.h"
+
+extern Translator *theTranslator;
+extern bool setTranslator(const char *languageName);
+
+#endif
diff --git a/src/languages.py b/src/languages.py
new file mode 100755
index 0000000..2b02b3e
--- /dev/null
+++ b/src/languages.py
@@ -0,0 +1,106 @@
+#
+# This file is an aid to generated the Languages rules file.
+# usage:
+# python languages.py > ..\winbuild\Languages.rules
+#
+import os
+import re
+
+files = [f for f in os.listdir('.') if re.match(r'translator_[a-z][a-z]\.h', f)]
+new_list = []
+for f in files:
+ new_list.append([f,(os.path.splitext(f)[0]).replace("translator_","").upper()])
+
+#
+# generating file is lang_cfg.py
+# the rules file has to output lang_cfg.h
+#
+print("""\
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="languages"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Languages"
+ DisplayName="Settings"
+ CommandLine="python $(InputPath) [AllOptions] [AdditionalOptions] > $(InpDir)/$(InputName).h"
+ Outputs="$(IntDir)/$(InputName).h"
+ FileExtensions="*.py"
+ AdditionalDependencies=""
+ ExecutionDescription="Executing languages ..."
+ ShowOnlyRuleProperties="false"
+ >
+ <Properties>
+ <EnumProperty
+ Name="EnglishOnly"
+ DisplayName="Use English Only"
+ Description="Use English Only"
+ DefaultValue="0"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use English Only"
+ />
+ <EnumValue
+ Value="1"
+ Switch="ENONLY"
+ DisplayName="Use English Only"
+ />
+ </Values>
+ </EnumProperty>
+""")
+#
+# generate loop, English is mandatory (so cannot be chosen)
+#
+for f in new_list:
+ if (f[1] != "EN"):
+ # search for the language description
+ fil = open(f[0], 'r')
+ tmp = ""
+ for line in fil:
+ if "idLanguage" in line:
+ tmp = line
+ if "}" in line:
+ break
+ elif (tmp != ""):
+ tmp += line
+ if "}" in line:
+ break
+
+ tmp = tmp.replace("\n","")
+ l = re.sub('[^"]*"([^"]*)".*','\\1',tmp)
+ l1 = l.replace("-","")
+ # capatalize first letter
+ l = l.title()
+ print("""\
+ <EnumProperty
+ Name="%s"
+ DisplayName="Use %s"
+ Description="Use %s"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use %s"
+ />
+ <EnumValue
+ Value="1"
+ Switch="%s"
+ DisplayName="Use %s"
+ />
+ </Values>
+ </EnumProperty>
+ """ % (l1, l, l, l, f[1], l))
+
+print("""\
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
+""")
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
new file mode 100644
index 0000000..af1a5fd
--- /dev/null
+++ b/src/latexdocvisitor.cpp
@@ -0,0 +1,1865 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#include "htmlattrib.h"
+#include <qfileinfo.h>
+#include "latexdocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "util.h"
+#include "message.h"
+#include "parserintf.h"
+#include "msc.h"
+#include "dia.h"
+#include "cite.h"
+#include "filedef.h"
+#include "config.h"
+#include "htmlentity.h"
+#include "plantuml.h"
+
+static QCString escapeLabelName(const char *s)
+{
+ QCString result;
+ const char *p=s;
+ char c;
+ if (p)
+ {
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '%': result+="\\%"; break;
+ case '|': result+="\\texttt{\"|}"; break;
+ case '!': result+="\"!"; break;
+ case '{': result+="\\lcurly{}"; break;
+ case '}': result+="\\rcurly{}"; break;
+ case '~': result+="````~"; break; // to get it a bit better in index together with other special characters
+ default: result+=c;
+ }
+ }
+ }
+ return result;
+}
+
+const int maxLevels=5;
+static const char *secLabels[maxLevels] =
+ { "section","subsection","subsubsection","paragraph","subparagraph" };
+
+static const char *getSectionName(int level)
+{
+ static bool compactLatex = Config_getBool("COMPACT_LATEX");
+ int l = level;
+ if (compactLatex) l++;
+ if (Doxygen::insideMainPage) l--;
+ return secLabels[QMIN(maxLevels-1,l)];
+}
+
+QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
+{
+ QCString result;
+ const char *p=s;
+ char str[2]; str[1]=0;
+ char c;
+ if (p)
+ {
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '!': m_t << "\"!"; break;
+ case '"': m_t << "\"\""; break;
+ case '@': m_t << "\"@"; break;
+ case '|': m_t << "\\texttt{\"|}"; break;
+ case '[': m_t << "["; break;
+ case ']': m_t << "]"; break;
+ case '{': m_t << "\\lcurly{}"; break;
+ case '}': m_t << "\\rcurly{}"; break;
+ default: str[0]=c; filter(str); break;
+ }
+ }
+ }
+ return result;
+}
+
+
+LatexDocVisitor::LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci,
+ const char *langExt,bool insideTabbing)
+ : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE),
+ m_insideItem(FALSE), m_hide(FALSE), m_insideTabbing(insideTabbing),
+ m_insideTable(FALSE), m_langExt(langExt), m_currentColumn(0),
+ m_inRowspan(FALSE), m_inColspan(FALSE)
+{
+ m_rowSpans.setAutoDelete(TRUE);
+}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+void LatexDocVisitor::visit(DocWord *w)
+{
+ if (m_hide) return;
+ filter(w->word());
+}
+
+void LatexDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ startLink(w->ref(),w->file(),w->anchor());
+ filter(w->word());
+ endLink(w->ref(),w->file(),w->anchor());
+}
+
+void LatexDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ }
+ else
+ {
+ m_t << " ";
+ }
+}
+
+void LatexDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ const char *res = HtmlEntityMapper::instance()->latex(s->symbol());
+ if (res)
+ {
+ if (((s->symbol() == DocSymbol::Sym_lt) || (s->symbol() == DocSymbol::Sym_Less))&& (!m_insidePre))
+ {
+ m_t << "$<$";
+ }
+ else if (((s->symbol() == DocSymbol::Sym_gt) || (s->symbol() == DocSymbol::Sym_Greater)) && (!m_insidePre))
+ {
+ m_t << "$>$";
+ }
+ else
+ {
+ m_t << res;
+ }
+ }
+ else
+ {
+ err("LaTeX: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+}
+
+void LatexDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ if (Config_getBool("PDF_HYPERLINKS"))
+ {
+ m_t << "\\href{";
+ if (u->isEmail()) m_t << "mailto:";
+ m_t << u->url() << "}";
+ }
+ m_t << "{\\tt ";
+ filter(u->url());
+ m_t << "}";
+}
+
+void LatexDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ m_t << "~\\newline\n";
+}
+
+void LatexDocVisitor::visit(DocHorRuler *)
+{
+ if (m_hide) return;
+ m_t << "\n\n";
+}
+
+void LatexDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "{\\bfseries "; else m_t << "}";
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "{\\itshape "; else m_t << "}";
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "{\\ttfamily "; else m_t << "}";
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "\\textsubscript{"; else m_t << "}";
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "\\textsuperscript{"; else m_t << "}";
+ break;
+ case DocStyleChange::Center:
+ if (s->enable()) m_t << "\\begin{center}"; else m_t << "\\end{center} ";
+ break;
+ case DocStyleChange::Small:
+ if (s->enable()) m_t << "\n\\footnotesize "; else m_t << "\n\\normalsize ";
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ m_t << "\n\\begin{DoxyPre}";
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_insidePre=FALSE;
+ m_t << "\\end{DoxyPre}\n";
+ }
+ break;
+ case DocStyleChange::Div: /* HTML only */ break;
+ case DocStyleChange::Span: /* HTML only */ break;
+ }
+}
+
+void LatexDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ QCString lang = m_langExt;
+ if (!s->language().isEmpty()) // explicit language setting
+ {
+ lang = s->language();
+ }
+ SrcLangExt langExt = getLanguageFromFileName(lang);
+ switch(s->type())
+ {
+ case DocVerbatim::Code:
+ {
+ m_t << "\n\\begin{DoxyCode}\n";
+ Doxygen::parserManager->getParser(lang)
+ ->parseCode(m_ci,s->context(),s->text(),langExt,
+ s->isExample(),s->exampleFile());
+ m_t << "\\end{DoxyCode}\n";
+ }
+ break;
+ case DocVerbatim::Verbatim:
+ m_t << "\\begin{DoxyVerb}";
+ m_t << s->text();
+ m_t << "\\end{DoxyVerb}\n";
+ break;
+ case DocVerbatim::HtmlOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::ManOnly:
+ case DocVerbatim::RtfOnly:
+ case DocVerbatim::DocbookOnly:
+ /* nothing */
+ break;
+ case DocVerbatim::LatexOnly:
+ m_t << s->text();
+ break;
+ case DocVerbatim::Dot:
+ {
+ static int dotindex = 1;
+ QCString fileName(4096);
+
+ fileName.sprintf("%s%d%s",
+ (Config_getString("LATEX_OUTPUT")+"/inline_dotgraph_").data(),
+ dotindex++,
+ ".dot"
+ );
+ QFile file(fileName);
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ }
+ file.writeBlock( s->text(), s->text().length() );
+ file.close();
+
+ m_t << "\\begin{center}\n";
+ startDotFile(fileName,"","",FALSE);
+ endDotFile(FALSE);
+ m_t << "\\end{center}\n";
+
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ }
+ break;
+ case DocVerbatim::Msc:
+ {
+ static int mscindex = 1;
+ QCString baseName(4096);
+
+ baseName.sprintf("%s%d",
+ (Config_getString("LATEX_OUTPUT")+"/inline_mscgraph_").data(),
+ mscindex++
+ );
+ QFile file(baseName+".msc");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s.msc for writing\n",baseName.data());
+ }
+ QCString text = "msc {";
+ text+=s->text();
+ text+="}";
+ file.writeBlock( text, text.length() );
+ file.close();
+
+ m_t << "\\begin{center}\n";
+ writeMscFile(baseName);
+ m_t << "\\end{center}\n";
+
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ }
+ break;
+ case DocVerbatim::PlantUML:
+ {
+ QCString latexOutput = Config_getString("LATEX_OUTPUT");
+ QCString baseName = writePlantUMLSource(latexOutput,s->exampleFile(),s->text());
+
+ m_t << "\\begin{center}\n";
+ writePlantUMLFile(baseName);
+ m_t << "\\end{center}\n";
+ }
+ break;
+ }
+}
+
+void LatexDocVisitor::visit(DocAnchor *anc)
+{
+ if (m_hide) return;
+ m_t << "\\label{" << stripPath(anc->file()) << "_" << anc->anchor() << "}%" << endl;
+ if (!anc->file().isEmpty() && Config_getBool("PDF_HYPERLINKS"))
+ {
+ m_t << "\\hypertarget{" << stripPath(anc->file()) << "_" << anc->anchor()
+ << "}{}%" << endl;
+ }
+}
+
+void LatexDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ {
+ m_t << "\n\\begin{DoxyCodeInclude}\n";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(), &fd);
+ m_t << "\\end{DoxyCodeInclude}" << endl;
+ }
+ break;
+ case DocInclude::Include:
+ m_t << "\n\\begin{DoxyCodeInclude}\n";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),langExt,inc->isExample(),
+ inc->exampleFile());
+ m_t << "\\end{DoxyCodeInclude}\n";
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ break;
+ case DocInclude::LatexInclude:
+ m_t << inc->text();
+ break;
+ case DocInclude::VerbInclude:
+ m_t << "\n\\begin{DoxyVerbInclude}\n";
+ m_t << inc->text();
+ m_t << "\\end{DoxyVerbInclude}\n";
+ break;
+ case DocInclude::Snippet:
+ {
+ m_t << "\n\\begin{DoxyCodeInclude}\n";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile()
+ );
+ m_t << "\\end{DoxyCodeInclude}" << endl;
+ }
+ break;
+ }
+}
+
+void LatexDocVisitor::visit(DocIncOperator *op)
+{
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ if (op->isFirst())
+ {
+ if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}\n";
+ pushEnabled();
+ m_hide = TRUE;
+ }
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,op->context(),op->text(),langExt,
+ op->isExample(),op->exampleFile());
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide) m_t << "\n\\end{DoxyCodeInclude}\n";
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ }
+}
+
+void LatexDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ m_t << f->text();
+}
+
+void LatexDocVisitor::visit(DocIndexEntry *i)
+{
+ if (m_hide) return;
+ m_t << "\\index{" << escapeLabelName(i->entry()) << "@{";
+ escapeMakeIndexChars(i->entry());
+ m_t << "}}";
+}
+
+void LatexDocVisitor::visit(DocSimpleSectSep *)
+{
+}
+
+void LatexDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ if (!cite->file().isEmpty())
+ {
+ //startLink(cite->ref(),cite->file(),cite->anchor());
+ QCString anchor = cite->anchor();
+ anchor = anchor.mid(CiteConsts::anchorPrefix.length()); // strip prefix
+ m_t << "\\cite{" << anchor << "}";
+ }
+ else
+ {
+ m_t << "{\\bfseries [";
+ filter(cite->text());
+ m_t << "]}";
+ }
+}
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void LatexDocVisitor::visitPre(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "\n\\begin{DoxyEnumerate}";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyItemize}";
+ }
+}
+
+void LatexDocVisitor::visitPost(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "\n\\end{DoxyEnumerate}";
+ }
+ else
+ {
+ m_t << "\n\\end{DoxyItemize}";
+ }
+}
+
+void LatexDocVisitor::visitPre(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "\n\\item ";
+}
+
+void LatexDocVisitor::visitPost(DocAutoListItem *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocPara *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocPara *p)
+{
+ if (m_hide) return;
+ if (!p->isLast() && // omit <p> for last paragraph
+ !(p->parent() && // and for parameter sections
+ p->parent()->kind()==DocNode::Kind_ParamSect
+ )
+ ) m_t << endl << endl;
+}
+
+void LatexDocVisitor::visitPre(DocRoot *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocRoot *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << "\\begin{DoxySeeAlso}{";
+ filter(theTranslator->trSeeAlso());
+ break;
+ case DocSimpleSect::Return:
+ m_t << "\\begin{DoxyReturn}{";
+ filter(theTranslator->trReturns());
+ break;
+ case DocSimpleSect::Author:
+ m_t << "\\begin{DoxyAuthor}{";
+ filter(theTranslator->trAuthor(TRUE,TRUE));
+ break;
+ case DocSimpleSect::Authors:
+ m_t << "\\begin{DoxyAuthor}{";
+ filter(theTranslator->trAuthor(TRUE,FALSE));
+ break;
+ case DocSimpleSect::Version:
+ m_t << "\\begin{DoxyVersion}{";
+ filter(theTranslator->trVersion());
+ break;
+ case DocSimpleSect::Since:
+ m_t << "\\begin{DoxySince}{";
+ filter(theTranslator->trSince());
+ break;
+ case DocSimpleSect::Date:
+ m_t << "\\begin{DoxyDate}{";
+ filter(theTranslator->trDate());
+ break;
+ case DocSimpleSect::Note:
+ m_t << "\\begin{DoxyNote}{";
+ filter(theTranslator->trNote());
+ break;
+ case DocSimpleSect::Warning:
+ m_t << "\\begin{DoxyWarning}{";
+ filter(theTranslator->trWarning());
+ break;
+ case DocSimpleSect::Pre:
+ m_t << "\\begin{DoxyPrecond}{";
+ filter(theTranslator->trPrecondition());
+ break;
+ case DocSimpleSect::Post:
+ m_t << "\\begin{DoxyPostcond}{";
+ filter(theTranslator->trPostcondition());
+ break;
+ case DocSimpleSect::Copyright:
+ m_t << "\\begin{DoxyCopyright}{";
+ filter(theTranslator->trCopyright());
+ break;
+ case DocSimpleSect::Invar:
+ m_t << "\\begin{DoxyInvariant}{";
+ filter(theTranslator->trInvariant());
+ break;
+ case DocSimpleSect::Remark:
+ m_t << "\\begin{DoxyRemark}{";
+ filter(theTranslator->trRemarks());
+ break;
+ case DocSimpleSect::Attention:
+ m_t << "\\begin{DoxyAttention}{";
+ filter(theTranslator->trAttention());
+ break;
+ case DocSimpleSect::User:
+ m_t << "\\begin{DoxyParagraph}{";
+ break;
+ case DocSimpleSect::Rcs:
+ m_t << "\\begin{DoxyParagraph}{";
+ break;
+ case DocSimpleSect::Unknown: break;
+ }
+
+ // special case 1: user defined title
+ if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
+ {
+ m_t << "}\n";
+ }
+ else
+ {
+ m_insideItem=TRUE;
+ }
+}
+
+void LatexDocVisitor::visitPost(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << "\n\\end{DoxySeeAlso}\n";
+ break;
+ case DocSimpleSect::Return:
+ m_t << "\n\\end{DoxyReturn}\n";
+ break;
+ case DocSimpleSect::Author:
+ m_t << "\n\\end{DoxyAuthor}\n";
+ break;
+ case DocSimpleSect::Authors:
+ m_t << "\n\\end{DoxyAuthor}\n";
+ break;
+ case DocSimpleSect::Version:
+ m_t << "\n\\end{DoxyVersion}\n";
+ break;
+ case DocSimpleSect::Since:
+ m_t << "\n\\end{DoxySince}\n";
+ break;
+ case DocSimpleSect::Date:
+ m_t << "\n\\end{DoxyDate}\n";
+ break;
+ case DocSimpleSect::Note:
+ m_t << "\n\\end{DoxyNote}\n";
+ break;
+ case DocSimpleSect::Warning:
+ m_t << "\n\\end{DoxyWarning}\n";
+ break;
+ case DocSimpleSect::Pre:
+ m_t << "\n\\end{DoxyPrecond}\n";
+ break;
+ case DocSimpleSect::Post:
+ m_t << "\n\\end{DoxyPostcond}\n";
+ break;
+ case DocSimpleSect::Copyright:
+ m_t << "\n\\end{DoxyCopyright}\n";
+ break;
+ case DocSimpleSect::Invar:
+ m_t << "\n\\end{DoxyInvariant}\n";
+ break;
+ case DocSimpleSect::Remark:
+ m_t << "\n\\end{DoxyRemark}\n";
+ break;
+ case DocSimpleSect::Attention:
+ m_t << "\n\\end{DoxyAttention}\n";
+ break;
+ case DocSimpleSect::User:
+ m_t << "\n\\end{DoxyParagraph}\n";
+ break;
+ case DocSimpleSect::Rcs:
+ m_t << "\n\\end{DoxyParagraph}\n";
+ break;
+ default:
+ break;
+ }
+}
+
+void LatexDocVisitor::visitPre(DocTitle *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ m_insideItem=FALSE;
+ m_t << "}\n";
+}
+
+void LatexDocVisitor::visitPre(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "\\begin{DoxyItemize}" << endl;
+}
+
+void LatexDocVisitor::visitPost(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "\\end{DoxyItemize}" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "\\item ";
+}
+
+void LatexDocVisitor::visitPost(DocSimpleListItem *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ if (Config_getBool("PDF_HYPERLINKS"))
+ {
+ m_t << "\\hypertarget{" << stripPath(s->file()) << "_" << s->anchor() << "}{}";
+ }
+ m_t << "\\" << getSectionName(s->level()) << "{";
+ filter(convertCharEntitiesToUTF8(s->title().data()));
+ m_t << "}\\label{" << stripPath(s->file()) << "_" << s->anchor() << "}" << endl;
+}
+
+void LatexDocVisitor::visitPost(DocSection *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "\n\\begin{DoxyEnumerate}";
+ else
+ m_t << "\n\\begin{DoxyItemize}";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "\n\\end{DoxyEnumerate}";
+ else
+ m_t << "\n\\end{DoxyItemize}";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "\n\\item ";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlListItem *)
+{
+}
+
+//void LatexDocVisitor::visitPre(DocHtmlPre *)
+//{
+// m_t << "\\small\\begin{alltt}";
+// m_insidePre=TRUE;
+//}
+
+//void LatexDocVisitor::visitPost(DocHtmlPre *)
+//{
+// m_insidePre=FALSE;
+// m_t << "\\end{alltt}\\normalsize " << endl;
+//}
+
+void LatexDocVisitor::visitPre(DocHtmlDescList *dl)
+{
+ if (m_hide) return;
+ QCString val = dl->attribs().find("class");
+ if (val=="reflist")
+ {
+ m_t << "\n\\begin{DoxyRefList}";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyDescription}";
+ }
+}
+
+void LatexDocVisitor::visitPost(DocHtmlDescList *dl)
+{
+ if (m_hide) return;
+ QCString val = dl->attribs().find("class");
+ if (val=="reflist")
+ {
+ m_t << "\n\\end{DoxyRefList}";
+ }
+ else
+ {
+ m_t << "\n\\end{DoxyDescription}";
+ }
+}
+
+void LatexDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "\n\\item[";
+ m_insideItem=TRUE;
+}
+
+void LatexDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_insideItem=FALSE;
+ m_t << "]";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlDescData *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocHtmlDescData *)
+{
+}
+
+static const char *getTableName(const DocNode *n)
+{
+ bool isNested=FALSE;
+ while (n && !isNested)
+ {
+ isNested = n->kind()==DocNode::Kind_HtmlTable;
+ n = n->parent();
+ }
+ return isNested ? "TabularNC" : "TabularC";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlTable *t)
+{
+ m_rowSpans.clear();
+ m_insideTable=TRUE;
+ if (m_hide) return;
+ if (t->hasCaption())
+ {
+ m_t << "\\begin{table}[h]";
+ }
+ m_t << "\\begin{" << getTableName(t->parent()) << "}{" << t->numColumns() << "}\n";
+ m_numCols = t->numColumns();
+ m_t << "\\hline\n";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlTable *t)
+{
+ m_insideTable=FALSE;
+ if (m_hide) return;
+ if (t->hasCaption())
+ {
+ m_t << "\\end{table}\n";
+ }
+ else
+ {
+ m_t << "\\end{" << getTableName(t->parent()) << "}\n";
+ }
+}
+
+void LatexDocVisitor::visitPre(DocHtmlCaption *c)
+{
+ if (m_hide) return;
+ m_t << "\\end{" << getTableName(c->parent()) << "}\n\\centering\n\\caption{";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "}\n";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlRow *r)
+{
+ m_currentColumn = 0;
+ if (r->isHeading()) m_t << "\\rowcolor{lightgray}";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlRow *row)
+{
+ if (m_hide) return;
+
+ int c=m_currentColumn;
+ while (c<=m_numCols) // end of row while inside a row span?
+ {
+ uint i;
+ for (i=0;i<m_rowSpans.count();i++)
+ {
+ ActiveRowSpan *span = m_rowSpans.at(i);
+ //printf(" founc row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d\n",
+ // span->column, span->rowSpan,span->colSpan,row->rowIndex(),span->cell->rowIndex());
+ if (span->rowSpan>0 && span->column==c && // we are at a cell in a row span
+ row->rowIndex()>span->cell->rowIndex() // but not the row that started the span
+ )
+ {
+ m_t << "&";
+ if (span->colSpan>1) // row span is also part of a column span
+ {
+ m_t << "\\multicolumn{" << span->colSpan << "}{";
+ m_t << "p{(\\linewidth-\\tabcolsep*"
+ << m_numCols << "-\\arrayrulewidth*"
+ << row->visibleCells() << ")*"
+ << span->colSpan <<"/"<< m_numCols << "}|}{}";
+ }
+ else // solitary row span
+ {
+ m_t << "\\multicolumn{1}{c|}{}";
+ }
+ }
+ }
+ c++;
+ }
+
+ m_t << "\\\\";
+
+ int col = 1;
+ uint i;
+ for (i=0;i<m_rowSpans.count();i++)
+ {
+ ActiveRowSpan *span = m_rowSpans.at(i);
+ if (span->rowSpan>0) span->rowSpan--;
+ if (span->rowSpan<=0)
+ {
+ // inactive span
+ }
+ else if (span->column>col)
+ {
+ m_t << "\\cline{" << col << "-" << (span->column-1) << "}";
+ col = span->column+span->colSpan;
+ }
+ else
+ {
+ col = span->column+span->colSpan;
+ }
+ }
+
+ if (col <= m_numCols)
+ {
+ m_t << "\\cline{" << col << "-" << m_numCols << "}";
+ }
+
+ m_t << "\n";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlCell *c)
+{
+ if (m_hide) return;
+
+ DocHtmlRow *row = 0;
+ if (c->parent() && c->parent()->kind()==DocNode::Kind_HtmlRow)
+ {
+ row = (DocHtmlRow*)c->parent();
+ }
+
+ m_currentColumn++;
+
+ //Skip columns that span from above.
+ uint i;
+ for (i=0;i<m_rowSpans.count();i++)
+ {
+ ActiveRowSpan *span = m_rowSpans.at(i);
+ if (span->rowSpan>0 && span->column==m_currentColumn)
+ {
+ if (row && span->colSpan>1)
+ {
+ m_t << "\\multicolumn{" << span->colSpan << "}{";
+ if (m_currentColumn /*c->columnIndex()*/==1) // add extra | for first column
+ {
+ m_t << "|";
+ }
+ m_t << "p{(\\linewidth-\\tabcolsep*"
+ << m_numCols << "-\\arrayrulewidth*"
+ << row->visibleCells() << ")*"
+ << span->colSpan <<"/"<< m_numCols << "}|}{}";
+ m_currentColumn+=span->colSpan;
+ }
+ else
+ {
+ m_currentColumn++;
+ }
+ m_t << "&";
+ }
+ }
+
+#if 0
+ QMap<int, int>::Iterator it = m_rowspanIndices.find(m_currentColumn);
+ if (it!=m_rowspanIndices.end() && it.data()>0)
+ {
+ m_t << "&";
+ m_currentColumn++;
+ it++;
+ }
+#endif
+
+ int cs = c->colSpan();
+ if (cs>1 && row)
+ {
+ m_inColspan = TRUE;
+ m_t << "\\multicolumn{" << cs << "}{";
+ if (c->columnIndex()==1) // add extra | for first column
+ {
+ m_t << "|";
+ }
+ m_t << "p{(\\linewidth-\\tabcolsep*"
+ << m_numCols << "-\\arrayrulewidth*"
+ << row->visibleCells() << ")*"
+ << cs <<"/"<< m_numCols << "}|}{";
+ if (c->isHeading()) m_t << "\\cellcolor{lightgray}";
+ }
+ int rs = c->rowSpan();
+ if (rs>0)
+ {
+ m_inRowspan = TRUE;
+ //m_rowspanIndices[m_currentColumn] = rs;
+ m_rowSpans.append(new ActiveRowSpan(c,rs,cs,m_currentColumn));
+ m_t << "\\multirow{" << rs << "}{\\linewidth}{";
+ }
+ int a = c->alignment();
+ if (a==DocHtmlCell::Center)
+ {
+ m_t << "\\PBS\\centering ";
+ }
+ else if (a==DocHtmlCell::Right)
+ {
+ m_t << "\\PBS\\raggedleft ";
+ }
+ if (c->isHeading())
+ {
+ m_t << "{\\bf ";
+ }
+ if (cs>1)
+ {
+ m_currentColumn+=cs-1;
+ }
+}
+
+void LatexDocVisitor::visitPost(DocHtmlCell *c)
+{
+ if (m_hide) return;
+ if (c->isHeading())
+ {
+ m_t << "}";
+ }
+ if (m_inRowspan)
+ {
+ m_inRowspan = FALSE;
+ m_t << "}";
+ }
+ if (m_inColspan)
+ {
+ m_inColspan = FALSE;
+ m_t << "}";
+ }
+ if (!c->isLast()) m_t << "&";
+}
+
+void LatexDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ //m_t << "\\begin{DoxyInternal}{";
+ //filter(theTranslator->trForInternalUseOnly());
+ //m_t << "}\n";
+}
+
+void LatexDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ //m_t << "\\end{DoxyInternal}" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocHRef *href)
+{
+ if (m_hide) return;
+ if (Config_getBool("PDF_HYPERLINKS"))
+ {
+ m_t << "\\href{";
+ m_t << href->url();
+ m_t << "}";
+ }
+ m_t << "{\\tt ";
+}
+
+void LatexDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "}";
+}
+
+void LatexDocVisitor::visitPre(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ m_t << "\\" << getSectionName(header->level()) << "*{";
+}
+
+void LatexDocVisitor::visitPost(DocHtmlHeader *)
+{
+ if (m_hide) return;
+ m_t << "}";
+}
+
+void LatexDocVisitor::visitPre(DocImage *img)
+{
+ if (img->type()==DocImage::Latex)
+ {
+ if (m_hide) return;
+ if (img->hasCaption())
+ {
+ m_t << "\n\\begin{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyImageNoCaption}\n"
+ " \\mbox{";
+ }
+ QCString gfxName = img->name();
+ if (gfxName.right(4)==".eps" || gfxName.right(4)==".pdf")
+ {
+ gfxName=gfxName.left(gfxName.length()-4);
+ }
+ m_t << "\\includegraphics";
+ if (!img->width().isEmpty())
+ {
+ m_t << "[width=" << img->width() << "]";
+ }
+ else if (!img->height().isEmpty())
+ {
+ m_t << "[height=" << img->height() << "]";
+ }
+ m_t << "{" << gfxName << "}";
+ if (img->hasCaption())
+ {
+ m_t << "\n\\caption{";
+ }
+ }
+ else // other format -> skip
+ {
+ pushEnabled();
+ m_hide=TRUE;
+ }
+}
+
+void LatexDocVisitor::visitPost(DocImage *img)
+{
+ if (img->type()==DocImage::Latex)
+ {
+ if (m_hide) return;
+ m_t << "}\n"; // end mbox or caption
+ if (img->hasCaption())
+ {
+ m_t << "\\end{DoxyImage}\n";
+ }
+ else{
+ m_t << "\\end{DoxyImageNoCaption}\n";
+ }
+ }
+ else // other format
+ {
+ popEnabled();
+ }
+}
+
+void LatexDocVisitor::visitPre(DocDotFile *df)
+{
+ if (m_hide) return;
+ startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void LatexDocVisitor::visitPost(DocDotFile *df)
+{
+ if (m_hide) return;
+ endDotFile(df->hasCaption());
+}
+void LatexDocVisitor::visitPre(DocMscFile *df)
+{
+ if (m_hide) return;
+ startMscFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void LatexDocVisitor::visitPost(DocMscFile *df)
+{
+ if (m_hide) return;
+ endMscFile(df->hasCaption());
+}
+
+void LatexDocVisitor::visitPre(DocDiaFile *df)
+{
+ if (m_hide) return;
+ startDiaFile(df->file(),df->width(),df->height(),df->hasCaption());
+}
+
+void LatexDocVisitor::visitPost(DocDiaFile *df)
+{
+ if (m_hide) return;
+ endDiaFile(df->hasCaption());
+}
+void LatexDocVisitor::visitPre(DocLink *lnk)
+{
+ if (m_hide) return;
+ startLink(lnk->ref(),lnk->file(),lnk->anchor());
+}
+
+void LatexDocVisitor::visitPost(DocLink *lnk)
+{
+ if (m_hide) return;
+ endLink(lnk->ref(),lnk->file(),lnk->anchor());
+}
+
+void LatexDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ // when ref->isSubPage()==TRUE we use ref->file() for HTML and
+ // ref->anchor() for LaTeX/RTF
+ if (ref->isSubPage())
+ {
+ startLink(ref->ref(),0,ref->anchor());
+ }
+ else
+ {
+ if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
+ }
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void LatexDocVisitor::visitPost(DocRef *ref)
+{
+ if (m_hide) return;
+ if (ref->isSubPage())
+ {
+ endLink(ref->ref(),0,ref->anchor());
+ }
+ else
+ {
+ if (!ref->file().isEmpty()) endLink(ref->ref(),ref->file(),ref->anchor());
+ }
+}
+
+void LatexDocVisitor::visitPre(DocSecRefItem *ref)
+{
+ if (m_hide) return;
+ m_t << "\\item \\contentsline{section}{";
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ if (pdfHyperlinks)
+ {
+ m_t << "\\hyperlink{" << ref->file() << "_" << ref->anchor() << "}{" ;
+ }
+}
+
+void LatexDocVisitor::visitPost(DocSecRefItem *ref)
+{
+ if (m_hide) return;
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ if (pdfHyperlinks)
+ {
+ m_t << "}";
+ }
+ m_t << "}{\\ref{" << ref->file() << "_" << ref->anchor() << "}}{}" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "\\footnotesize" << endl;
+ m_t << "\\begin{multicols}{2}" << endl;
+ m_t << "\\begin{DoxyCompactList}" << endl;
+}
+
+void LatexDocVisitor::visitPost(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "\\end{DoxyCompactList}" << endl;
+ m_t << "\\end{multicols}" << endl;
+ m_t << "\\normalsize" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ bool hasInOutSpecs = s->hasInOutSpecifier();
+ bool hasTypeSpecs = s->hasTypeSpecifier();
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ m_t << "\n\\begin{DoxyParams}";
+ if (hasInOutSpecs && hasTypeSpecs) m_t << "[2]"; // 2 extra cols
+ else if (hasInOutSpecs || hasTypeSpecs) m_t << "[1]"; // 1 extra col
+ m_t << "{";
+ filter(theTranslator->trParameters());
+ break;
+ case DocParamSect::RetVal:
+ m_t << "\n\\begin{DoxyRetVals}{";
+ filter(theTranslator->trReturnValues());
+ break;
+ case DocParamSect::Exception:
+ m_t << "\n\\begin{DoxyExceptions}{";
+ filter(theTranslator->trExceptions());
+ break;
+ case DocParamSect::TemplateParam:
+ /* TODO: add this
+ filter(theTranslator->trTemplateParam()); break;
+ */
+ m_t << "\n\\begin{DoxyTemplParams}{";
+ filter("Template Parameters");
+ break;
+ default:
+ ASSERT(0);
+ }
+ m_t << "}\n";
+}
+
+void LatexDocVisitor::visitPost(DocParamSect *s)
+{
+ if (m_hide) return;
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ m_t << "\\end{DoxyParams}\n";
+ break;
+ case DocParamSect::RetVal:
+ m_t << "\\end{DoxyRetVals}\n";
+ break;
+ case DocParamSect::Exception:
+ m_t << "\\end{DoxyExceptions}\n";
+ break;
+ case DocParamSect::TemplateParam:
+ m_t << "\\end{DoxyTemplParams}\n";
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+
+void LatexDocVisitor::visitPre(DocParamList *pl)
+{
+ if (m_hide) return;
+ DocParamSect::Type parentType = DocParamSect::Unknown;
+ DocParamSect *sect = 0;
+ if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect)
+ {
+ parentType = ((DocParamSect*)pl->parent())->type();
+ sect=(DocParamSect*)pl->parent();
+ }
+ bool useTable = parentType==DocParamSect::Param ||
+ parentType==DocParamSect::RetVal ||
+ parentType==DocParamSect::Exception ||
+ parentType==DocParamSect::TemplateParam;
+ if (!useTable)
+ {
+ m_t << "\\item[";
+ }
+ if (sect && sect->hasInOutSpecifier())
+ {
+ if (pl->direction()!=DocParamSect::Unspecified)
+ {
+ m_t << "\\mbox{\\tt ";
+ if (pl->direction()==DocParamSect::In)
+ {
+ m_t << "in";
+ }
+ else if (pl->direction()==DocParamSect::Out)
+ {
+ m_t << "out";
+ }
+ else if (pl->direction()==DocParamSect::InOut)
+ {
+ m_t << "in,out";
+ }
+ m_t << "} ";
+ }
+ if (useTable) m_t << " & ";
+ }
+ if (sect && sect->hasTypeSpecifier())
+ {
+ QListIterator<DocNode> li(pl->paramTypes());
+ DocNode *type;
+ bool first=TRUE;
+ for (li.toFirst();(type=li.current());++li)
+ {
+ if (!first) m_t << " | "; else first=FALSE;
+ if (type->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)type);
+ }
+ else if (type->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)type);
+ }
+ }
+ if (useTable) m_t << " & ";
+ }
+ m_t << "{\\em ";
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ bool first=TRUE;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (!first) m_t << ","; else first=FALSE;
+ m_insideItem=TRUE;
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ m_insideItem=FALSE;
+ }
+ m_t << "}";
+ if (useTable)
+ {
+ m_t << " & ";
+ }
+ else
+ {
+ m_t << "]";
+ }
+}
+
+void LatexDocVisitor::visitPost(DocParamList *pl)
+{
+ if (m_hide) return;
+ DocParamSect::Type parentType = DocParamSect::Unknown;
+ if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect)
+ {
+ parentType = ((DocParamSect*)pl->parent())->type();
+ }
+ bool useTable = parentType==DocParamSect::Param ||
+ parentType==DocParamSect::RetVal ||
+ parentType==DocParamSect::Exception ||
+ parentType==DocParamSect::TemplateParam;
+ if (useTable)
+ {
+ m_t << "\\\\" << endl
+ << "\\hline" << endl;
+ }
+}
+
+void LatexDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "\\begin{DoxyRefDesc}{";
+ filter(x->title());
+ m_t << "}" << endl;
+ bool anonymousEnum = x->file()=="@";
+ m_t << "\\item[";
+ if (Config_getBool("PDF_HYPERLINKS") && !anonymousEnum)
+ {
+ m_t << "\\hyperlink{" << stripPath(x->file()) << "_" << x->anchor() << "}{";
+ }
+ else
+ {
+ m_t << "{\\bf ";
+ }
+ m_insideItem=TRUE;
+ filter(x->title());
+ m_insideItem=FALSE;
+ m_t << "}]";
+}
+
+void LatexDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "\\end{DoxyRefDesc}" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ startLink(0,ref->file(),ref->anchor());
+}
+
+void LatexDocVisitor::visitPost(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ endLink(0,ref->file(),ref->anchor());
+}
+
+void LatexDocVisitor::visitPre(DocCopy *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocCopy *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocText *)
+{
+}
+
+void LatexDocVisitor::visitPost(DocText *)
+{
+}
+
+void LatexDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "\\begin{quote}" << endl;
+}
+
+void LatexDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "\\end{quote}" << endl;
+}
+
+void LatexDocVisitor::visitPre(DocVhdlFlow *)
+{
+ if (m_hide) return;
+}
+
+void LatexDocVisitor::visitPost(DocVhdlFlow *)
+{
+ if (m_hide) return;
+}
+
+void LatexDocVisitor::visitPre(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+void LatexDocVisitor::visitPost(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+void LatexDocVisitor::filter(const char *str)
+{
+ filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem);
+}
+
+void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
+{
+ if (ref.isEmpty() && Config_getBool("PDF_HYPERLINKS")) // internal PDF link
+ {
+ if (ref.isEmpty()) {
+ m_t << "\\hyperlink{";
+ if (!file.isEmpty()) m_t << stripPath(file);
+ if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
+ if (!anchor.isEmpty()) m_t << anchor;
+ m_t << "}{";
+ }
+ else
+ {
+ QCString *dest;
+ m_t << "\\href{";
+ if ((dest=Doxygen::tagDestinationDict[ref])) m_t << *dest << "/";
+ if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
+ if (!anchor.isEmpty()) m_t << "#" << anchor;
+ m_t << "}{";
+ }
+ }
+ else if (ref.isEmpty()) // internal non-PDF link
+ {
+ m_t << "\\doxyref{";
+ }
+ else // external link
+ {
+ m_t << "{\\bf ";
+ }
+}
+
+void LatexDocVisitor::endLink(const QCString &ref,const QCString &file,const QCString &anchor)
+{
+ m_t << "}";
+ if (ref.isEmpty() && !Config_getBool("PDF_HYPERLINKS"))
+ {
+ m_t << "{";
+ filter(theTranslator->trPageAbbreviation());
+ m_t << "}{" << file;
+ if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
+ m_t << anchor << "}";
+ }
+}
+
+void LatexDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void LatexDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
+void LatexDocVisitor::startDotFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("dot_");
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ QCString name = fileName;
+ writeDotGraphFromFile(name,outDir,baseName,GOF_EPS);
+ if (hasCaption)
+ {
+ m_t << "\n\\begin{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyImageNoCaption}\n"
+ " \\mbox{";
+ }
+ m_t << "\\includegraphics";
+ if (!width.isEmpty())
+ {
+ m_t << "[width=" << width << "]";
+ }
+ else if (!height.isEmpty())
+ {
+ m_t << "[height=" << height << "]";
+ }
+ else
+ {
+ m_t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]";
+ }
+ m_t << "{" << baseName;
+ //if (Config_getBool("USE_PDFLATEX"))
+ //{
+ // m_t << ".pdf";
+ //}
+ //else
+ //{
+ // m_t << ".eps";
+ //}
+ m_t << "}";
+
+ if (hasCaption)
+ {
+ m_t << "\n\\caption{";
+ }
+}
+
+void LatexDocVisitor::endDotFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "}\n"; // end caption or mbox
+ if (hasCaption)
+ {
+ m_t << "\\end{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\\end{DoxyImageNoCaption}\n";
+ }
+}
+
+void LatexDocVisitor::startMscFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("msc_");
+
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ writeMscGraphFromFile(fileName,outDir,baseName,MSC_EPS);
+ if (hasCaption)
+ {
+ m_t << "\n\\begin{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyImageNoCaption}\n"
+ " \\mbox{";
+ }
+ m_t << "\\includegraphics";
+ if (!width.isEmpty())
+ {
+ m_t << "[width=" << width << "]";
+ }
+ else if (!height.isEmpty())
+ {
+ m_t << "[height=" << height << "]";
+ }
+ else
+ {
+ m_t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]";
+ }
+ m_t << "{" << baseName;
+ //if (Config_getBool("USE_PDFLATEX"))
+ //{
+ // m_t << ".pdf";
+ //}
+ //else
+ //{
+ // m_t << ".eps";
+ //}
+ m_t << "}";
+
+ if (hasCaption)
+ {
+ m_t << "\n\\caption{";
+ }
+}
+
+void LatexDocVisitor::endMscFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "}\n"; // end caption or mbox
+ if (hasCaption)
+ {
+ m_t << "\\end{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\\end{DoxyImageNoCaption}\n";
+ }
+}
+
+
+void LatexDocVisitor::writeMscFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_EPS);
+ m_t << "\n\\begin{DoxyImageNoCaption}"
+ " \\mbox{\\includegraphics";
+ m_t << "{" << shortName << "}";
+ m_t << "}\n"; // end mbox
+ m_t << "\\end{DoxyImageNoCaption}\n";
+}
+
+
+void LatexDocVisitor::startDiaFile(const QCString &fileName,
+ const QCString &width,
+ const QCString &height,
+ bool hasCaption
+ )
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ if ((i=baseName.find('.'))!=-1)
+ {
+ baseName=baseName.left(i);
+ }
+ baseName.prepend("dia_");
+
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ writeDiaGraphFromFile(fileName,outDir,baseName,DIA_EPS);
+ if (hasCaption)
+ {
+ m_t << "\n\\begin{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\n\\begin{DoxyImageNoCaption}\n"
+ " \\mbox{";
+ }
+ m_t << "\\includegraphics";
+ if (!width.isEmpty())
+ {
+ m_t << "[width=" << width << "]";
+ }
+ else if (!height.isEmpty())
+ {
+ m_t << "[height=" << height << "]";
+ }
+ else
+ {
+ m_t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]";
+ }
+ m_t << "{" << baseName;
+ //if (Config_getBool("USE_PDFLATEX"))
+ //{
+ // m_t << ".pdf";
+ //}
+ //else
+ //{
+ // m_t << ".eps";
+ //}
+ m_t << "}";
+
+ if (hasCaption)
+ {
+ m_t << "\n\\caption{";
+ }
+}
+
+void LatexDocVisitor::endDiaFile(bool hasCaption)
+{
+ if (m_hide) return;
+ m_t << "}\n"; // end caption or mbox
+ if (hasCaption)
+ {
+ m_t << "\\end{DoxyImage}\n";
+ }
+ else
+ {
+ m_t << "\\end{DoxyImageNoCaption}\n";
+ }
+}
+
+
+void LatexDocVisitor::writeDiaFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_EPS);
+ m_t << "\n\\begin{DoxyImageNoCaption}"
+ " \\mbox{\\includegraphics";
+ m_t << "{" << shortName << "}";
+ m_t << "}\n"; // end mbox
+ m_t << "\\end{DoxyImageNoCaption}\n";
+}
+
+void LatexDocVisitor::writePlantUMLFile(const QCString &baseName)
+{
+ QCString shortName = baseName;
+ int i;
+ if ((i=shortName.findRev('/'))!=-1)
+ {
+ shortName=shortName.right(shortName.length()-i-1);
+ }
+ QCString outDir = Config_getString("LATEX_OUTPUT");
+ generatePlantUMLOutput(baseName,outDir,PUML_EPS);
+ m_t << "\n\\begin{DoxyImageNoCaption}"
+ " \\mbox{\\includegraphics";
+ m_t << "{" << shortName << "}";
+ m_t << "}\n"; // end mbox
+ m_t << "\\end{DoxyImageNoCaption}\n";
+}
+
diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h
new file mode 100644
index 0000000..64560b9
--- /dev/null
+++ b/src/latexdocvisitor.h
@@ -0,0 +1,204 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _LATEXDOCVISITOR_H
+#define _LATEXDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+#include <qlist.h>
+//#include <qmap.h>
+
+class FTextStream;
+class CodeOutputInterface;
+
+/*! @brief Concrete visitor implementation for LaTeX output. */
+class LatexDocVisitor : public DocVisitor
+{
+ public:
+ LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci,
+ const char *langExt,bool insideTabbing);
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *);
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *s);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *s);
+ void visitPost(DocHtmlList *s);
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *t);
+ void visitPost(DocHtmlTable *t);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *) ;
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *lnk);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *ref);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+
+ struct ActiveRowSpan
+ {
+ ActiveRowSpan(DocHtmlCell *c,int rs,int cs,int col)
+ : cell(c), rowSpan(rs), colSpan(cs), column(col) {}
+ DocHtmlCell *cell;
+ int rowSpan;
+ int colSpan;
+ int column;
+ };
+
+ typedef QList<ActiveRowSpan> RowSpanList;
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void filter(const char *str);
+ void startLink(const QCString &ref,const QCString &file,
+ const QCString &anchor);
+ void endLink(const QCString &ref,const QCString &file,
+ const QCString &anchor);
+ QCString escapeMakeIndexChars(const char *s);
+ void startDotFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endDotFile(bool hasCaption);
+
+ void startMscFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endMscFile(bool hasCaption);
+ void writeMscFile(const QCString &fileName);
+
+ void startDiaFile(const QCString &fileName,const QCString &width,
+ const QCString &height, bool hasCaption);
+ void endDiaFile(bool hasCaption);
+ void writeDiaFile(const QCString &fileName);
+ void writePlantUMLFile(const QCString &fileName);
+
+ void pushEnabled();
+ void popEnabled();
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_insideItem;
+ bool m_hide;
+ bool m_insideTabbing;
+ bool m_insideTable;
+ int m_numCols;
+ QStack<bool> m_enabled;
+ QCString m_langExt;
+ RowSpanList m_rowSpans;
+ int m_currentColumn;
+ bool m_inRowspan;
+ bool m_inColspan;
+};
+
+#endif
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
new file mode 100644
index 0000000..086e012
--- /dev/null
+++ b/src/latexgen.cpp
@@ -0,0 +1,2231 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include "latexgen.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "util.h"
+#include "diagram.h"
+#include "language.h"
+#include "version.h"
+#include "dot.h"
+#include "pagedef.h"
+#include "docparser.h"
+#include "latexdocvisitor.h"
+#include "dirdef.h"
+#include "cite.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "namespacedef.h"
+#include "filename.h"
+
+static const char doxygenLatexStyle[] =
+#include "doxygen.sty.h"
+;
+
+//static QCString filterTitle(const char *s)
+//{
+// QCString tmp=s,result;
+// uint i;for (i=0;i<tmp.length();i++)
+// {
+// char c=tmp.at(i);
+// switch(c)
+// {
+// case '#': result+="\\#"; break;
+// case '"': result+="\\\""; break;
+// case '%': result+="\\%"; break;
+// case '[': result+="{"; break;
+// case ']': result+="}"; break;
+// default: result+=c; break;
+// }
+// }
+// return result;
+//}
+
+
+
+LatexGenerator::LatexGenerator() : OutputGenerator()
+{
+ dir=Config_getString("LATEX_OUTPUT");
+ col=0;
+ //printf("LatexGenerator::LatexGenerator() insideTabbing=FALSE\n");
+ insideTabbing=FALSE;
+ firstDescItem=TRUE;
+ disableLinks=FALSE;
+ m_indent=0;
+ templateMemberItem = FALSE;
+ m_prettyCode=Config_getBool("LATEX_SOURCE_CODE");
+}
+
+LatexGenerator::~LatexGenerator()
+{
+}
+
+static void writeLatexMakefile()
+{
+ bool generateBib = !Doxygen::citeDict->isEmpty();
+ QCString dir=Config_getString("LATEX_OUTPUT");
+ QCString fileName=dir+"/Makefile";
+ QFile file(fileName);
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ exit(1);
+ }
+ // inserted by KONNO Akihisa <konno at researchers.jp> 2002-03-05
+ QCString latex_command = Config_getString("LATEX_CMD_NAME");
+ QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME");
+ // end insertion by KONNO Akihisa <konno at researchers.jp> 2002-03-05
+ FTextStream t(&file);
+ if (!Config_getBool("USE_PDFLATEX")) // use plain old latex
+ {
+ t << "all: refman.dvi" << endl
+ << endl
+ << "ps: refman.ps" << endl
+ << endl
+ << "pdf: refman.pdf" << endl
+ << endl
+ << "ps_2on1: refman_2on1.ps" << endl
+ << endl
+ << "pdf_2on1: refman_2on1.pdf" << endl
+ << endl
+ << "refman.ps: refman.dvi" << endl
+ << "\tdvips -o refman.ps refman.dvi" << endl
+ << endl;
+ t << "refman.pdf: refman.ps" << endl;
+ t << "\tps2pdf refman.ps refman.pdf" << endl << endl;
+ t << "refman.dvi: clean refman.tex doxygen.sty" << endl
+ << "\techo \"Running latex...\"" << endl
+ << "\t" << latex_command << " refman.tex" << endl
+ << "\techo \"Running makeindex...\"" << endl
+ << "\t" << mkidx_command << " refman.idx" << endl;
+ if (generateBib)
+ {
+ t << "\techo \"Running bibtex...\"" << endl;
+ t << "\tbibtex refman" << endl;
+ t << "\techo \"Rerunning latex....\"" << endl;
+ t << "\t" << latex_command << " refman.tex" << endl;
+ }
+ t << "\techo \"Rerunning latex....\"" << endl
+ << "\t" << latex_command << " refman.tex" << endl
+ << "\tlatex_count=8 ; \\" << endl
+ << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
+ << "\t do \\" << endl
+ << "\t echo \"Rerunning latex....\" ;\\" << endl
+ << "\t " << latex_command << " refman.tex ;\\" << endl
+ << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
+ << "\t done" << endl
+ << "\t" << mkidx_command << " refman.idx" << endl
+ << "\t" << latex_command << " refman.tex" << endl << endl
+ << "refman_2on1.ps: refman.ps" << endl
+ << "\tpsnup -2 refman.ps >refman_2on1.ps" << endl
+ << endl
+ << "refman_2on1.pdf: refman_2on1.ps" << endl
+ << "\tps2pdf refman_2on1.ps refman_2on1.pdf" << endl;
+ }
+ else // use pdflatex for higher quality output
+ {
+ t << "all: refman.pdf" << endl << endl
+ << "pdf: refman.pdf" << endl << endl;
+ t << "refman.pdf: clean refman.tex" << endl;
+ t << "\tpdflatex refman" << endl;
+ t << "\t" << mkidx_command << " refman.idx" << endl;
+ if (generateBib)
+ {
+ t << "\tbibtex refman" << endl;
+ t << "\tpdflatex refman" << endl;
+ }
+ t << "\tpdflatex refman" << endl
+ << "\tlatex_count=8 ; \\" << endl
+ << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
+ << "\t do \\" << endl
+ << "\t echo \"Rerunning latex....\" ;\\" << endl
+ << "\t pdflatex refman ;\\" << endl
+ << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
+ << "\t done" << endl
+ << "\t" << mkidx_command << " refman.idx" << endl
+ << "\tpdflatex refman" << endl << endl;
+ }
+
+ t << endl
+ << "clean:" << endl
+ << "\trm -f "
+ << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl;
+}
+
+static void writeMakeBat()
+{
+#if defined(_MSC_VER)
+ QCString dir=Config_getString("LATEX_OUTPUT");
+ QCString fileName=dir+"/make.bat";
+ QCString latex_command = Config_getString("LATEX_CMD_NAME");
+ QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME");
+ QFile file(fileName);
+ bool generateBib = !Doxygen::citeDict->isEmpty();
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ exit(1);
+ }
+ FTextStream t(&file);
+ t << "set Dir_Old=%cd%\n";
+ t << "cd /D %~dp0\n\n";
+ t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n";
+ if (!Config_getBool("USE_PDFLATEX")) // use plain old latex
+ {
+ t << latex_command << " refman.tex\n";
+ t << "echo ----\n";
+ t << mkidx_command << " refman.idx\n";
+ if (generateBib)
+ {
+ t << "bibtex refman\n";
+ t << "echo ----\n";
+ t << latex_command << " refman.tex\n";
+ }
+ t << "setlocal enabledelayedexpansion\n";
+ t << "set count=8\n";
+ t << ":repeat\n";
+ t << "set content=X\n";
+ t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
+ t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
+ t << "if !content! == X goto :skip\n";
+ t << "set /a count-=1\n";
+ t << "if !count! EQU 0 goto :skip\n\n";
+ t << "echo ----\n";
+ t << latex_command << " refman.tex\n";
+ t << "goto :repeat\n";
+ t << ":skip\n";
+ t << "endlocal\n";
+ t << mkidx_command << " refman.idx\n";
+ t << latex_command << " refman.tex\n";
+ t << "dvips -o refman.ps refman.dvi\n";
+ t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
+ "-sOutputFile=refman.pdf -c save pop -f refman.ps\n";
+ }
+ else // use pdflatex
+ {
+ t << "pdflatex refman\n";
+ t << "echo ----\n";
+ t << mkidx_command << " refman.idx\n";
+ if (generateBib)
+ {
+ t << "bibtex refman" << endl;
+ t << "pdflatex refman" << endl;
+ }
+ t << "echo ----\n";
+ t << "pdflatex refman\n\n";
+ t << "setlocal enabledelayedexpansion\n";
+ t << "set count=8\n";
+ t << ":repeat\n";
+ t << "set content=X\n";
+ t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
+ t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
+ t << "if !content! == X goto :skip\n";
+ t << "set /a count-=1\n";
+ t << "if !count! EQU 0 goto :skip\n\n";
+ t << "echo ----\n";
+ t << "pdflatex refman\n";
+ t << "goto :repeat\n";
+ t << ":skip\n";
+ t << "endlocal\n";
+ t << mkidx_command << " refman.idx\n";
+ t << "pdflatex refman\n";
+ t << "cd /D %Dir_Old%\n";
+ t << "set Dir_Old=\n";
+ }
+#endif
+}
+
+void LatexGenerator::init()
+{
+
+ QCString dir=Config_getString("LATEX_OUTPUT");
+ QDir d(dir);
+ if (!d.exists() && !d.mkdir(dir))
+ {
+ err("Could not create output directory %s\n",dir.data());
+ exit(1);
+ }
+
+ writeLatexMakefile();
+ writeMakeBat();
+
+ createSubDirs(d);
+}
+
+static void writeDefaultHeaderPart1(FTextStream &t)
+{
+ // part 1
+
+ // Handle batch mode
+ if (Config_getBool("LATEX_BATCHMODE"))
+ t << "\\batchmode\n";
+
+ // Set document class depending on configuration
+ QCString documentClass;
+ if (Config_getBool("COMPACT_LATEX"))
+ documentClass = "article";
+ else
+ documentClass = "book";
+ t << "\\documentclass[twoside]{" << documentClass << "}\n"
+ "\n";
+
+ // Load required packages
+ t << "% Packages required by doxygen\n"
+ "\\usepackage{fixltx2e}\n" // for \textsubscript
+ "\\usepackage{calc}\n"
+ "\\usepackage{doxygen}\n"
+ "\\usepackage{graphicx}\n"
+ "\\usepackage[utf8]{inputenc}\n"
+ "\\usepackage{makeidx}\n"
+ "\\usepackage{multicol}\n"
+ "\\usepackage{multirow}\n"
+ "\\PassOptionsToPackage{warn}{textcomp}\n"
+ "\\usepackage{textcomp}\n"
+ "\\usepackage[nointegrals]{wasysym}\n"
+ "\\usepackage[table]{xcolor}\n"
+ "\n";
+
+ // Language support
+ QCString languageSupport = theTranslator->latexLanguageSupportCommand();
+ if (!languageSupport.isEmpty())
+ {
+ t << "% NLS support packages\n"
+ << languageSupport
+ << "\n";
+ }
+
+ // Define default fonts
+ t << "% Font selection\n"
+ "\\usepackage[T1]{fontenc}\n"
+ "\\usepackage{mathptmx}\n"
+ "\\usepackage[scaled=.90]{helvet}\n"
+ "\\usepackage{courier}\n"
+ "\\usepackage{amssymb}\n"
+ "\\usepackage{sectsty}\n"
+ "\\renewcommand{\\familydefault}{\\sfdefault}\n"
+ "\\allsectionsfont{%\n"
+ " \\fontseries{bc}\\selectfont%\n"
+ " \\color{darkgray}%\n"
+ "}\n"
+ "\\renewcommand{\\DoxyLabelFont}{%\n"
+ " \\fontseries{bc}\\selectfont%\n"
+ " \\color{darkgray}%\n"
+ "}\n"
+ "\\newcommand{\\+}{\\discretionary{\\mbox{\\scriptsize$\\hookleftarrow$}}{}{}}\n"
+ "\n";
+
+ // Define page & text layout
+ QCString paperName;
+ QCString &paperType=Config_getEnum("PAPER_TYPE");
+ // "a4wide" package is obsolete (see bug 563698)
+ if (paperType=="a4wide")
+ paperName="a4";
+ else
+ paperName=paperType;
+ t << "% Page & text layout\n"
+ "\\usepackage{geometry}\n"
+ "\\geometry{%\n"
+ " " << paperName << "paper,%\n"
+ " top=2.5cm,%\n"
+ " bottom=2.5cm,%\n"
+ " left=2.5cm,%\n"
+ " right=2.5cm%\n"
+ "}\n";
+ // \sloppy is obsolete (see bug 563698)
+ // Allow a bit of overflow to go unnoticed by other means
+ t << "\\tolerance=750\n"
+ "\\hfuzz=15pt\n"
+ "\\hbadness=750\n"
+ "\\setlength{\\emergencystretch}{15pt}\n"
+ "\\setlength{\\parindent}{0cm}\n"
+ "\\setlength{\\parskip}{0.2cm}\n";
+ // Redefine paragraph/subparagraph environments, using sectsty fonts
+ t << "\\makeatletter\n"
+ "\\renewcommand{\\paragraph}{%\n"
+ " \\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%\n"
+ " \\normalfont\\normalsize\\bfseries\\SS at parafont%\n"
+ " }%\n"
+ "}\n"
+ "\\renewcommand{\\subparagraph}{%\n"
+ " \\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%\n"
+ " \\normalfont\\normalsize\\bfseries\\SS at subparafont%\n"
+ " }%\n"
+ "}\n"
+ "\\makeatother\n"
+ "\n";
+
+ // Headers & footers
+ QGString genString;
+ FTextStream tg(&genString);
+ filterLatexString(tg,
+ theTranslator->trGeneratedAt(dateToString(TRUE),
+ Config_getString("PROJECT_NAME")),
+ FALSE,FALSE,FALSE);
+ t << "% Headers & footers\n"
+ "\\usepackage{fancyhdr}\n"
+ "\\pagestyle{fancyplain}\n"
+ "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n"
+ "\\fancyhead[CE]{\\fancyplain{}{}}\n"
+ "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n"
+ "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n"
+ "\\fancyhead[CO]{\\fancyplain{}{}}\n"
+ "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n"
+ "\\fancyfoot[LE]{\\fancyplain{}{}}\n"
+ "\\fancyfoot[CE]{\\fancyplain{}{}}\n"
+ "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
+ "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
+ "\\fancyfoot[CO]{\\fancyplain{}{}}\n"
+ "\\fancyfoot[RO]{\\fancyplain{}{}}\n"
+ "\\renewcommand{\\footrulewidth}{0.4pt}\n";
+ if (!Config_getBool("COMPACT_LATEX"))
+ {
+ t << "\\renewcommand{\\chaptermark}[1]{%\n"
+ " \\markboth{#1}{}%\n"
+ "}\n";
+ }
+ t << "\\renewcommand{\\sectionmark}[1]{%\n"
+ " \\markright{\\thesection\\ #1}%\n"
+ "}\n"
+ "\n";
+
+ // ToC, LoF, LoT, bibliography, and index
+ t << "% Indices & bibliography\n"
+ "\\usepackage{natbib}\n"
+ "\\usepackage[titles]{tocloft}\n"
+ "\\setcounter{tocdepth}{3}\n"
+ "\\setcounter{secnumdepth}{5}\n"
+ "\\makeindex\n"
+ "\n";
+
+ // User-specified packages
+ QStrList &extraPackages = Config_getList("EXTRA_PACKAGES");
+ if (!extraPackages.isEmpty()) {
+ t << "% Packages requested by user\n";
+ const char *pkgName=extraPackages.first();
+ while (pkgName)
+ {
+ t << "\\usepackage{" << pkgName << "}\n";
+ pkgName=extraPackages.next();
+ }
+ t << "\n";
+ }
+
+ // Hyperlinks
+ bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ if (pdfHyperlinks)
+ {
+ t << "% Hyperlinks (required, but should be loaded last)\n"
+ "\\usepackage{ifpdf}\n"
+ "\\ifpdf\n"
+ " \\usepackage[pdftex,pagebackref=true]{hyperref}\n"
+ "\\else\n"
+ " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n"
+ "\\fi\n"
+ "\\hypersetup{%\n"
+ " colorlinks=true,%\n"
+ " linkcolor=blue,%\n"
+ " citecolor=blue,%\n"
+ " unicode%\n"
+ "}\n"
+ "\n";
+ }
+
+ // Custom commands used by the header
+ t << "% Custom commands\n"
+ "\\newcommand{\\clearemptydoublepage}{%\n"
+ " \\newpage{\\pagestyle{empty}\\cleardoublepage}%\n"
+ "}\n"
+ "\n"
+ "\n";
+
+ // End of preamble, now comes the document contents
+ t << "%===== C O N T E N T S =====\n"
+ "\n"
+ "\\begin{document}\n";
+ if (theTranslator->idLanguage()=="greek")
+ t << "\\selectlanguage{greek}\n";
+ t << "\n";
+
+ // Front matter
+ t << "% Titlepage & ToC\n";
+ bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (pdfHyperlinks && usePDFLatex)
+ {
+ // To avoid duplicate page anchors due to reuse of same numbers for
+ // the index (be it as roman numbers)
+ t << "\\hypersetup{pageanchor=false,\n"
+ << " bookmarks=true,\n"
+ << " bookmarksnumbered=true,\n"
+ << " pdfencoding=unicode\n"
+ << " }\n";
+ }
+ t << "\\pagenumbering{roman}\n"
+ "\\begin{titlepage}\n"
+ "\\vspace*{7cm}\n"
+ "\\begin{center}%\n"
+ "{\\Large ";
+}
+
+static void writeDefaultHeaderPart2(FTextStream &t)
+{
+ // part 2
+ // Finalize project name
+ t << "}\\\\\n"
+ "\\vspace*{1cm}\n"
+ "{\\large ";
+}
+
+static void writeDefaultHeaderPart3(FTextStream &t)
+{
+ // part 3
+ // Finalize project number
+ t << " Doxygen " << versionString << "}\\\\\n"
+ "\\vspace*{0.5cm}\n"
+ "{\\small " << dateToString(TRUE) << "}\\\\\n"
+ "\\end{center}\n"
+ "\\end{titlepage}\n";
+ bool compactLatex = Config_getBool("COMPACT_LATEX");
+ if (!compactLatex)
+ t << "\\clearemptydoublepage\n";
+
+ // ToC
+ t << "\\tableofcontents\n";
+ if (!compactLatex)
+ t << "\\clearemptydoublepage\n";
+ t << "\\pagenumbering{arabic}\n";
+ bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (pdfHyperlinks && usePDFLatex)
+ {
+ // re-enable anchors again
+ t << "\\hypersetup{pageanchor=true}\n";
+ }
+ t << "\n"
+ "%--- Begin generated contents ---\n";
+}
+
+static void writeDefaultStyleSheet(FTextStream &t)
+{
+ t << doxygenLatexStyle;
+}
+
+static void writeDefaultFooter(FTextStream &t)
+{
+ t << "%--- End generated contents ---\n"
+ "\n";
+
+ // Bibliography
+ Doxygen::citeDict->writeLatexBibliography(t);
+
+ // Index
+ QCString unit;
+ if (Config_getBool("COMPACT_LATEX"))
+ unit = "section";
+ else
+ unit = "chapter";
+ t << "% Index\n"
+ "\\newpage\n"
+ "\\phantomsection\n"
+ "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trRTFGeneralIndex() << "}\n"
+ "\\printindex\n"
+ "\n"
+ "\\end{document}\n";
+}
+
+void LatexGenerator::writeHeaderFile(QFile &f)
+{
+ FTextStream t(&f);
+ t << "% Latex header for doxygen " << versionString << endl;
+ writeDefaultHeaderPart1(t);
+ t << "Your title here";
+ writeDefaultHeaderPart2(t);
+ t << "Generated by";
+ writeDefaultHeaderPart3(t);
+}
+
+void LatexGenerator::writeFooterFile(QFile &f)
+{
+ FTextStream t(&f);
+ t << "% Latex footer for doxygen " << versionString << endl;
+ writeDefaultFooter(t);
+}
+
+void LatexGenerator::writeStyleSheetFile(QFile &f)
+{
+ FTextStream t(&f);
+ t << "% stylesheet for doxygen " << versionString << endl;
+ writeDefaultStyleSheet(t);
+}
+
+void LatexGenerator::startFile(const char *name,const char *,const char *)
+{
+#if 0
+ setEncoding(Config_getString("LATEX_OUTPUT_ENCODING"));
+#endif
+ QCString fileName=name;
+ relPath = relativePathToRoot(fileName);
+ sourceFileName = stripPath(fileName);
+ if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex";
+ startPlainFile(fileName);
+}
+
+void LatexGenerator::endFile()
+{
+ endPlainFile();
+ sourceFileName.resize(0);
+}
+
+//void LatexGenerator::writeIndex()
+//{
+// startFile("refman.tex");
+//}
+
+void LatexGenerator::startProjectNumber()
+{
+ t << "\\\\[1ex]\\large ";
+}
+
+static QCString convertToLaTeX(const QCString &s)
+{
+ QGString result;
+ FTextStream t(&result);
+ filterLatexString(t,s,FALSE,FALSE,FALSE);
+ return result.data();
+}
+
+void LatexGenerator::startIndexSection(IndexSections is)
+{
+ bool &compactLatex = Config_getBool("COMPACT_LATEX");
+ QCString &latexHeader = Config_getString("LATEX_HEADER");
+ switch (is)
+ {
+ case isTitlePageStart:
+ {
+ if (latexHeader.isEmpty())
+ {
+ writeDefaultHeaderPart1(t);
+ }
+ else
+ {
+ QCString header = fileToString(latexHeader);
+ t << substituteKeywords(header,"",
+ convertToLaTeX(Config_getString("PROJECT_NAME")),
+ convertToLaTeX(Config_getString("PROJECT_NUMBER")),
+ convertToLaTeX(Config_getString("PROJECT_BRIEF")));
+ }
+ }
+ break;
+ case isTitlePageAuthor:
+ if (latexHeader.isEmpty())
+ {
+ writeDefaultHeaderPart2(t);
+ }
+ break;
+ case isMainPage:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Introduction}\n"
+ break;
+ //case isPackageIndex:
+ // if (compactLatex) t << "\\section"; else t << "\\chapter";
+ // t << "{"; //Package Index}\n"
+ // break;
+ case isModuleIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Module Index}\n"
+ break;
+ case isDirIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Directory Index}\n"
+ break;
+ case isNamespaceIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Namespace Index}\"
+ break;
+ case isClassHierarchyIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Hierarchical Index}\n"
+ break;
+ case isCompoundIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Annotated Compound Index}\n"
+ break;
+ case isFileIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Annotated File Index}\n"
+ break;
+ case isPageIndex:
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Annotated Page Index}\n"
+ break;
+ case isModuleDocumentation:
+ {
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ bool found=FALSE;
+ for (gli.toFirst();(gd=gli.current()) && !found;++gli)
+ {
+ if (!gd->isReference())
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Module Documentation}\n";
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isDirDocumentation:
+ {
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ bool found=FALSE;
+ for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Module Documentation}\n";
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isNamespaceDocumentation:
+ {
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ bool found=FALSE;
+ for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; // Namespace Documentation}\n":
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isClassDocumentation:
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ bool found=FALSE;
+ for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Compound Documentation}\n";
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isFileDocumentation:
+ {
+ bool isFirst=TRUE;
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->isLinkableInProject())
+ {
+ if (isFirst)
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //File Documentation}\n";
+ isFirst=FALSE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case isExampleDocumentation:
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Example Documentation}\n";
+ }
+ break;
+ case isPageDocumentation:
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{"; //Page Documentation}\n";
+ }
+ break;
+ case isPageDocumentation2:
+ break;
+ case isEndIndex:
+ break;
+ }
+}
+
+void LatexGenerator::endIndexSection(IndexSections is)
+{
+ //static bool compactLatex = Config_getBool("COMPACT_LATEX");
+ static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
+ static QCString latexHeader = Config_getString("LATEX_HEADER");
+ static QCString latexFooter = Config_getString("LATEX_FOOTER");
+ switch (is)
+ {
+ case isTitlePageStart:
+ break;
+ case isTitlePageAuthor:
+ if (latexHeader.isEmpty())
+ {
+ writeDefaultHeaderPart3(t);
+ }
+ break;
+ case isMainPage:
+ {
+ //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
+ QCString indexName="index";
+ t << "}\n\\label{index}";
+ if (Config_getBool("PDF_HYPERLINKS")) t << "\\hypertarget{index}{}";
+ t << "\\input{" << indexName << "}\n";
+ }
+ break;
+ case isModuleIndex:
+ t << "}\n\\input{modules}\n";
+ break;
+ case isDirIndex:
+ t << "}\n\\input{dirs}\n";
+ break;
+ case isNamespaceIndex:
+ t << "}\n\\input{namespaces}\n";
+ break;
+ case isClassHierarchyIndex:
+ t << "}\n\\input{hierarchy}\n";
+ break;
+ case isCompoundIndex:
+ t << "}\n\\input{annotated}\n";
+ break;
+ case isFileIndex:
+ t << "}\n\\input{files}\n";
+ break;
+ case isPageIndex:
+ t << "}\n\\input{pages}\n";
+ break;
+ case isModuleDocumentation:
+ {
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ bool found=FALSE;
+ for (gli.toFirst();(gd=gli.current()) && !found;++gli)
+ {
+ if (!gd->isReference())
+ {
+ t << "}\n\\input{" << gd->getOutputFileBase() << "}\n";
+ found=TRUE;
+ }
+ }
+ for (;(gd=gli.current());++gli)
+ {
+ if (!gd->isReference())
+ {
+ //if (compactLatex) t << "\\input"; else t << "\\include";
+ t << "\\include";
+ t << "{" << gd->getOutputFileBase() << "}\n";
+ }
+ }
+ }
+ break;
+ case isDirDocumentation:
+ {
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ bool found=FALSE;
+ for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ t << "}\n\\input{" << dd->getOutputFileBase() << "}\n";
+ found=TRUE;
+ }
+ }
+ for (;(dd=dli.current());++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ //if (compactLatex) t << "\\input"; else t << "\\include";
+ t << "\\input";
+ t << "{" << dd->getOutputFileBase() << "}\n";
+ }
+ }
+ }
+ break;
+ case isNamespaceDocumentation:
+ {
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ bool found=FALSE;
+ for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ t << "}\n\\input{" << nd->getOutputFileBase() << "}\n";
+ found=TRUE;
+ }
+ }
+ while ((nd=nli.current()))
+ {
+ if (nd->isLinkableInProject())
+ {
+ //if (compactLatex) t << "\\input"; else t << "\\include";
+ t << "\\input";
+ t << "{" << nd->getOutputFileBase() << "}\n";
+ }
+ ++nli;
+ }
+ }
+ break;
+ case isClassDocumentation:
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ bool found=FALSE;
+ for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ t << "}\n\\input{" << cd->getOutputFileBase() << "}\n";
+ found=TRUE;
+ }
+ }
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ //if (compactLatex) t << "\\input"; else t << "\\include";
+ t << "\\input";
+ t << "{" << cd->getOutputFileBase() << "}\n";
+ }
+ }
+ }
+ break;
+ case isFileDocumentation:
+ {
+ bool isFirst=TRUE;
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->isLinkableInProject())
+ {
+ if (isFirst)
+ {
+ t << "}\n\\input{" << fd->getOutputFileBase() << "}\n";
+ if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
+ {
+ //t << "\\include{" << fd->getSourceFileBase() << "}\n";
+ t << "\\input{" << fd->getSourceFileBase() << "}\n";
+ }
+ isFirst=FALSE;
+ }
+ else
+ {
+ //if (compactLatex) t << "\\input" ; else t << "\\include";
+ t << "\\input" ;
+ t << "{" << fd->getOutputFileBase() << "}\n";
+ if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
+ {
+ //t << "\\include{" << fd->getSourceFileBase() << "}\n";
+ t << "\\input{" << fd->getSourceFileBase() << "}\n";
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case isExampleDocumentation:
+ {
+ t << "}\n";
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=pdi.toFirst();
+ if (pd)
+ {
+ t << "\\input{" << pd->getOutputFileBase() << "}\n";
+ }
+ for (++pdi;(pd=pdi.current());++pdi)
+ {
+ //if (compactLatex) t << "\\input" ; else t << "\\include";
+ t << "\\input";
+ t << "{" << pd->getOutputFileBase() << "}\n";
+ }
+ }
+ break;
+ case isPageDocumentation:
+ {
+ t << "}\n";
+#if 0
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=pdi.toFirst();
+ bool first=TRUE;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (!pd->getGroupDef() && !pd->isReference())
+ {
+ if (compactLatex) t << "\\section"; else t << "\\chapter";
+ t << "{" << pd->title();
+ t << "}\n";
+
+ if (compactLatex || first) t << "\\input" ; else t << "\\include";
+ t << "{" << pd->getOutputFileBase() << "}\n";
+ first=FALSE;
+ }
+ }
+#endif
+ }
+ break;
+ case isPageDocumentation2:
+ break;
+ case isEndIndex:
+ if (latexFooter.isEmpty())
+ {
+ writeDefaultFooter(t);
+ }
+ else
+ {
+ QCString footer = fileToString(latexFooter);
+ t << substituteKeywords(footer,"",
+ convertToLaTeX(Config_getString("PROJECT_NAME")),
+ convertToLaTeX(Config_getString("PROJECT_NUMBER")),
+ convertToLaTeX(Config_getString("PROJECT_BRIEF")));
+ }
+ break;
+ }
+}
+
+void LatexGenerator::writePageLink(const char *name, bool /*first*/)
+{
+ //bool &compactLatex = Config_getBool("COMPACT_LATEX");
+ // next is remove for bug615957
+ //if (compactLatex || first) t << "\\input" ; else t << "\\include";
+ t << "\\input" ;
+ t << "{" << name << "}\n";
+}
+
+
+void LatexGenerator::writeStyleInfo(int part)
+{
+ if (part > 0)
+ return;
+
+ startPlainFile("doxygen.sty");
+ writeDefaultStyleSheet(t);
+ endPlainFile();
+}
+
+void LatexGenerator::newParagraph()
+{
+ t << endl << endl;
+}
+
+void LatexGenerator::startParagraph()
+{
+ t << endl << endl;
+}
+
+void LatexGenerator::endParagraph()
+{
+ t << endl << endl;
+}
+
+void LatexGenerator::writeString(const char *text)
+{
+ t << text;
+}
+
+void LatexGenerator::startIndexItem(const char *ref,const char *fn)
+{
+ t << "\\item ";
+ if (!ref && fn)
+ {
+ t << "\\contentsline{section}{";
+ }
+}
+
+void LatexGenerator::endIndexItem(const char *ref,const char *fn)
+{
+ if (!ref && fn)
+ {
+ t << "}{\\pageref{" << fn << "}}{}" << endl;
+ }
+}
+
+//void LatexGenerator::writeIndexFileItem(const char *,const char *text)
+//{
+// t << "\\item\\contentsline{section}{";
+// docify(text);
+// t << "}{\\pageref{" << text << "}}" << endl;
+//}
+
+
+void LatexGenerator::startHtmlLink(const char *url)
+{
+ if (Config_getBool("PDF_HYPERLINKS"))
+ {
+ t << "\\href{";
+ t << url;
+ t << "}";
+ }
+ t << "{\\tt ";
+}
+
+void LatexGenerator::endHtmlLink()
+{
+ t << "}";
+}
+
+//void LatexGenerator::writeMailLink(const char *url)
+//{
+// if (Config_getBool("PDF_HYPERLINKS"))
+// {
+// t << "\\href{mailto:";
+// t << url;
+// t << "}";
+// }
+// t << "{\\tt ";
+// docify(url);
+// t << "}";
+//}
+
+void LatexGenerator::writeStartAnnoItem(const char *,const char *,
+ const char *path,const char *name)
+{
+ t << "\\item\\contentsline{section}{\\bf ";
+ if (path) docify(path);
+ docify(name);
+ t << "} ";
+}
+
+void LatexGenerator::writeEndAnnoItem(const char *name)
+{
+ t << "}{\\pageref{" << name << "}}{}" << endl;
+}
+
+void LatexGenerator::startIndexKey()
+{
+ t << "\\item\\contentsline{section}{";
+}
+
+void LatexGenerator::endIndexKey()
+{
+}
+
+void LatexGenerator::startIndexValue(bool hasBrief)
+{
+ t << " ";
+ if (hasBrief) t << "\\\\*";
+}
+
+void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/)
+{
+ //if (hasBrief) t << ")";
+ t << "}{\\pageref{" << name << "}}{}" << endl;
+}
+
+//void LatexGenerator::writeClassLink(const char *,const char *,
+// const char *,const char *name)
+//{
+// t << "{\\bf ";
+// docify(name);
+// t << "}";
+//}
+
+void LatexGenerator::startTextLink(const char *f,const char *anchor)
+{
+ if (!disableLinks && Config_getBool("PDF_HYPERLINKS"))
+ {
+ t << "\\hyperlink{";
+ if (f) t << stripPath(f);
+ if (anchor) t << "_" << anchor;
+ t << "}{";
+ }
+ else
+ {
+ t << "{\\bf ";
+ }
+}
+
+void LatexGenerator::endTextLink()
+{
+ t << "}";
+}
+
+void LatexGenerator::writeObjectLink(const char *ref, const char *f,
+ const char *anchor, const char *text)
+{
+ if (!disableLinks && !ref && Config_getBool("PDF_HYPERLINKS"))
+ {
+ t << "\\hyperlink{";
+ if (f) t << stripPath(f);
+ if (f && anchor) t << "_";
+ if (anchor) t << anchor;
+ t << "}{";
+ docify(text);
+ t << "}";
+ }
+ else
+ {
+ t << "{\\bf ";
+ docify(text);
+ t << "}";
+ }
+}
+
+void LatexGenerator::startPageRef()
+{
+ t << " \\doxyref{}{";
+}
+
+void LatexGenerator::endPageRef(const char *clname, const char *anchor)
+{
+ t << "}{";
+ if (clname) t << clname;
+ if (anchor) t << "_" << anchor;
+ t << "}";
+}
+
+void LatexGenerator::writeCodeLink(const char *ref,const char *f,
+ const char *anchor,const char *name,
+ const char *)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ int l = qstrlen(name);
+ if (col+l>80)
+ {
+ t << "\n ";
+ col=0;
+ }
+ if (/*m_prettyCode &&*/ !disableLinks && !ref && usePDFLatex && pdfHyperlinks)
+ {
+ t << "\\hyperlink{";
+ if (f) t << stripPath(f);
+ if (f && anchor) t << "_";
+ if (anchor) t << anchor;
+ t << "}{";
+ codify(name);
+ t << "}";
+ }
+ else
+ {
+ t << name;
+ }
+ col+=l;
+}
+
+void LatexGenerator::startTitleHead(const char *fileName)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (usePDFLatex && pdfHyperlinks && fileName)
+ {
+ t << "\\hypertarget{" << stripPath(fileName) << "}{";
+ }
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ t << "\\subsection{";
+ }
+ else
+ {
+ t << "\\section{";
+ }
+}
+
+void LatexGenerator::endTitleHead(const char *fileName,const char *name)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ t << "}" << endl;
+ if (name)
+ {
+ t << "\\label{" << stripPath(fileName) << "}\\index{";
+ escapeLabelName(name);
+ t << "@{";
+ escapeMakeIndexChars(name);
+ t << "}}" << endl;
+ }
+ if (usePDFLatex && pdfHyperlinks && fileName)
+ {
+ t << "}" << endl;
+ }
+}
+
+void LatexGenerator::startTitle()
+{
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ t << "\\subsection{";
+ }
+ else
+ {
+ t << "\\section{";
+ }
+}
+
+void LatexGenerator::startGroupHeader(int extraIndentLevel)
+{
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ extraIndentLevel++;
+ }
+
+ if (extraIndentLevel==3)
+ {
+ t << "\\subparagraph*{";
+ }
+ else if (extraIndentLevel==2)
+ {
+ t << "\\paragraph{";
+ }
+ else if (extraIndentLevel==1)
+ {
+ t << "\\subsubsection{";
+ }
+ else // extraIndentLevel==0
+ {
+ t << "\\subsection{";
+ }
+ disableLinks=TRUE;
+}
+
+void LatexGenerator::endGroupHeader(int)
+{
+ disableLinks=FALSE;
+ t << "}" << endl;
+}
+
+void LatexGenerator::startMemberHeader(const char *)
+{
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ t << "\\subsubsection*{";
+ }
+ else
+ {
+ t << "\\subsection*{";
+ }
+ disableLinks=TRUE;
+}
+
+void LatexGenerator::endMemberHeader()
+{
+ disableLinks=FALSE;
+ t << "}" << endl;
+}
+
+void LatexGenerator::startMemberDoc(const char *clname,
+ const char *memname,
+ const char *,
+ const char *title,
+ bool showInline)
+{
+ if (memname && memname[0]!='@')
+ {
+ t << "\\index{";
+ if (clname)
+ {
+ escapeLabelName(clname);
+ t << "@{";
+ escapeMakeIndexChars(clname);
+ t << "}!";
+ }
+ escapeLabelName(memname);
+ t << "@{";
+ escapeMakeIndexChars(memname);
+ t << "}}" << endl;
+
+ t << "\\index{";
+ escapeLabelName(memname);
+ t << "@{";
+ escapeMakeIndexChars(memname);
+ t << "}";
+ if (clname)
+ {
+ t << "!";
+ escapeLabelName(clname);
+ t << "@{";
+ escapeMakeIndexChars(clname);
+ t << "}";
+ }
+ t << "}" << endl;
+ }
+ static const char *levelLab[] = { "subsubsection","paragraph","subparagraph", "subparagraph" };
+ static bool compactLatex = Config_getBool("COMPACT_LATEX");
+ int level=0;
+ if (showInline) level+=2;
+ if (compactLatex) level++;
+ t << "\\" << levelLab[level];
+
+ //if (Config_getBool("PDF_HYPERLINKS") && memname)
+ //{
+ // t << "[";
+ // escapeMakeIndexChars(this,t,memname);
+ // t << "]";
+ //}
+ t << "[{";
+ escapeMakeIndexChars(title);
+ t << "}]";
+ t << "{\\setlength{\\rightskip}{0pt plus 5cm}";
+ disableLinks=TRUE;
+}
+
+void LatexGenerator::endMemberDoc(bool)
+{
+ disableLinks=FALSE;
+ t << "}";
+ //if (Config_getBool("COMPACT_LATEX")) t << "\\hfill";
+}
+
+void LatexGenerator::startDoxyAnchor(const char *fName,const char *,
+ const char *anchor, const char *,
+ const char *)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (usePDFLatex && pdfHyperlinks)
+ {
+ t << "\\hypertarget{";
+ if (fName) t << stripPath(fName);
+ if (anchor) t << "_" << anchor;
+ t << "}{";
+ }
+}
+
+void LatexGenerator::endDoxyAnchor(const char *fName,const char *anchor)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (usePDFLatex && pdfHyperlinks)
+ {
+ t << "}";
+ }
+ t << "\\label{";
+ if (fName) t << stripPath(fName);
+ if (anchor) t << "_" << anchor;
+ t << "}" << endl;
+}
+
+void LatexGenerator::writeAnchor(const char *fName,const char *name)
+{
+ //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
+ t << "\\label{" << name << "}" << endl;
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (usePDFLatex && pdfHyperlinks)
+ {
+ if (fName)
+ {
+ t << "\\hypertarget{" << stripPath(fName) << "_" << name << "}{}" << endl;
+ }
+ else
+ {
+ t << "\\hypertarget{" << name << "}{}" << endl;
+ }
+ }
+}
+
+
+//void LatexGenerator::writeLatexLabel(const char *clName,const char *anchor)
+//{
+// writeDoxyAnchor(0,clName,anchor,0);
+//}
+
+void LatexGenerator::addIndexItem(const char *s1,const char *s2)
+{
+ if (s1)
+ {
+ t << "\\index{";
+ escapeLabelName(s1);
+ t << "@{";
+ escapeMakeIndexChars(s1);
+ t << "}";
+ if (s2)
+ {
+ t << "!";
+ escapeLabelName(s2);
+ t << "@{";
+ escapeMakeIndexChars(s2);
+ t << "}";
+ }
+ t << "}";
+ }
+}
+
+
+void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
+{
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ if (usePDFLatex && pdfHyperlinks)
+ {
+ t << "\\hypertarget{" << stripPath(lab) << "}{}";
+ }
+ t << "\\";
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ switch(type)
+ {
+ case SectionInfo::Page: t << "subsection"; break;
+ case SectionInfo::Section: t << "subsubsection"; break;
+ case SectionInfo::Subsection: t << "paragraph"; break;
+ case SectionInfo::Subsubsection: t << "subparagraph"; break;
+ case SectionInfo::Paragraph: t << "subparagraph"; break;
+ default: ASSERT(0); break;
+ }
+ t << "{";
+ }
+ else
+ {
+ switch(type)
+ {
+ case SectionInfo::Page: t << "section"; break;
+ case SectionInfo::Section: t << "subsection"; break;
+ case SectionInfo::Subsection: t << "subsubsection"; break;
+ case SectionInfo::Subsubsection: t << "paragraph"; break;
+ case SectionInfo::Paragraph: t << "subparagraph"; break;
+ default: ASSERT(0); break;
+ }
+ t << "{";
+ }
+}
+
+void LatexGenerator::endSection(const char *lab,SectionInfo::SectionType)
+{
+ t << "}\\label{" << lab << "}" << endl;
+}
+
+
+void LatexGenerator::docify(const char *str)
+{
+ filterLatexString(t,str,insideTabbing,FALSE,FALSE);
+}
+
+void LatexGenerator::codify(const char *str)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c;
+ //char cs[5];
+ int spacesToNextTabStop;
+ static int tabSize = Config_getInt("TAB_SIZE");
+ const int maxLineLen = 108;
+ QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars
+ int i;
+ while ((c=*p))
+ {
+ switch(c)
+ {
+ case 0x0c: p++; // remove ^L
+ break;
+ case '\t': spacesToNextTabStop =
+ tabSize - (col%tabSize);
+ t << Doxygen::spaces.left(spacesToNextTabStop);
+ col+=spacesToNextTabStop;
+ p++;
+ break;
+ case '\n': t << '\n'; col=0; p++;
+ break;
+ default:
+ i=0;
+
+#undef COPYCHAR
+// helper macro to copy a single utf8 character, dealing with multibyte chars.
+#define COPYCHAR() do { \
+ result[i++]=c; p++; \
+ if (c<0) /* multibyte utf-8 character */ \
+ { \
+ /* 1xxx.xxxx: >=2 byte character */ \
+ result[i++]=*p++; \
+ if (((uchar)c&0xE0)==0xE0) \
+ { \
+ /* 111x.xxxx: >=3 byte character */ \
+ result[i++]=*p++; \
+ } \
+ if (((uchar)c&0xF0)==0xF0) \
+ { \
+ /* 1111.xxxx: 4 byte character */ \
+ result[i++]=*p++; \
+ } \
+ } \
+ col++; \
+ } while(0)
+
+ // gather characters until we find whitespace or are at
+ // the end of a line
+ COPYCHAR();
+ if (col>=maxLineLen) // force line break
+ {
+ t << "\n ";
+ col=0;
+ }
+ else // copy more characters
+ {
+ while (col<maxLineLen && (c=*p) &&
+ c!=0x0c && c!='\t' && c!='\n' && c!=' '
+ )
+ {
+ COPYCHAR();
+ }
+ if (col>=maxLineLen) // force line break
+ {
+ t << "\n ";
+ col=0;
+ }
+ }
+ result[i]=0; // add terminator
+ //if (m_prettyCode)
+ //{
+ filterLatexString(t,result,insideTabbing,TRUE);
+ //}
+ //else
+ //{
+ // t << result;
+ //}
+ break;
+ }
+ }
+ }
+}
+
+void LatexGenerator::writeChar(char c)
+{
+ char cs[2];
+ cs[0]=c;
+ cs[1]=0;
+ docify(cs);
+}
+
+void LatexGenerator::startClassDiagram()
+{
+ //if (Config_getBool("COMPACT_LATEX")) t << "\\subsubsection"; else t << "\\subsection";
+ //t << "{";
+}
+
+void LatexGenerator::endClassDiagram(const ClassDiagram &d,
+ const char *fileName,const char *)
+{
+ d.writeFigure(t,dir,fileName);
+}
+
+
+void LatexGenerator::startAnonTypeScope(int indent)
+{
+ if (indent==0)
+ {
+ t << "\\begin{tabbing}" << endl;
+ t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill" << endl;
+ insideTabbing=TRUE;
+ }
+ m_indent=indent;
+}
+
+void LatexGenerator::endAnonTypeScope(int indent)
+{
+ if (indent==0)
+ {
+ t << endl << "\\end{tabbing}";
+ insideTabbing=FALSE;
+ }
+ m_indent=indent;
+}
+
+void LatexGenerator::startMemberTemplateParams()
+{
+ if (templateMemberItem)
+ {
+ t << "{\\footnotesize ";
+ }
+}
+
+void LatexGenerator::endMemberTemplateParams(const char *,const char *)
+{
+ if (templateMemberItem)
+ {
+ t << "}\\\\";
+ }
+}
+
+void LatexGenerator::startMemberItem(const char *,int annoType,const char *)
+{
+ //printf("LatexGenerator::startMemberItem(%d)\n",annType);
+ if (!insideTabbing)
+ {
+ t << "\\item " << endl;
+ templateMemberItem = (annoType == 3);
+ }
+}
+
+void LatexGenerator::endMemberItem()
+{
+ if (insideTabbing)
+ {
+ t << "\\\\";
+ }
+ templateMemberItem = FALSE;
+ t << endl;
+}
+
+void LatexGenerator::startMemberDescription(const char *,const char *)
+{
+ if (!insideTabbing)
+ {
+ t << "\\begin{DoxyCompactList}\\small\\item\\em ";
+ }
+ else
+ {
+ for (int i=0;i<m_indent+2;i++) t << "\\>";
+ t << "{\\em ";
+ }
+}
+
+void LatexGenerator::endMemberDescription()
+{
+ if (!insideTabbing)
+ {
+ //t << "\\item\\end{DoxyCompactList}";
+ t << "\\end{DoxyCompactList}";
+ }
+ else
+ {
+ t << "}\\\\\n";
+ }
+}
+
+
+void LatexGenerator::writeNonBreakableSpace(int)
+{
+ //printf("writeNonBreakbleSpace()\n");
+ if (insideTabbing)
+ {
+ t << "\\>";
+ }
+ else
+ {
+ t << "~";
+ }
+}
+
+void LatexGenerator::startMemberList()
+{
+ if (!insideTabbing)
+ {
+ t << "\\begin{DoxyCompactItemize}" << endl;
+ }
+}
+
+void LatexGenerator::endMemberList()
+{
+ //printf("LatexGenerator::endMemberList(%d)\n",insideTabbing);
+ if (!insideTabbing)
+ {
+ t << "\\end{DoxyCompactItemize}" << endl;
+ }
+}
+
+
+void LatexGenerator::startMemberGroupHeader(bool hasHeader)
+{
+ if (hasHeader) t << "\\begin{Indent}";
+ t << "{\\bf ";
+ // changed back to rev 756 due to bug 660501
+ //if (Config_getBool("COMPACT_LATEX"))
+ //{
+ // t << "\\subparagraph*{";
+ //}
+ //else
+ //{
+ // t << "\\paragraph*{";
+ //}
+}
+
+void LatexGenerator::endMemberGroupHeader()
+{
+ // changed back to rev 756 due to bug 660501
+ t << "}\\par" << endl;
+ //t << "}" << endl;
+}
+
+void LatexGenerator::startMemberGroupDocs()
+{
+ t << "{\\em ";
+}
+
+void LatexGenerator::endMemberGroupDocs()
+{
+ t << "}";
+}
+
+void LatexGenerator::startMemberGroup()
+{
+}
+
+void LatexGenerator::endMemberGroup(bool hasHeader)
+{
+ if (hasHeader)t << "\\end{Indent}";
+ t << endl;
+}
+
+void LatexGenerator::startDotGraph()
+{
+ newParagraph();
+}
+
+void LatexGenerator::endDotGraph(const DotClassGraph &g)
+{
+ g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString("LATEX_OUTPUT"),fileName,relPath);
+}
+
+void LatexGenerator::startInclDepGraph()
+{
+}
+
+void LatexGenerator::endInclDepGraph(const DotInclDepGraph &g)
+{
+ g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString("LATEX_OUTPUT"),fileName,relPath);
+}
+
+void LatexGenerator::startGroupCollaboration()
+{
+}
+
+void LatexGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
+{
+ g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString("LATEX_OUTPUT"),fileName,relPath);
+}
+
+void LatexGenerator::startCallGraph()
+{
+}
+
+void LatexGenerator::endCallGraph(const DotCallGraph &g)
+{
+ g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString("LATEX_OUTPUT"),fileName,relPath);
+}
+
+void LatexGenerator::startDirDepGraph()
+{
+}
+
+void LatexGenerator::endDirDepGraph(const DotDirDeps &g)
+{
+ g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString("LATEX_OUTPUT"),fileName,relPath);
+}
+
+void LatexGenerator::startDescription()
+{
+ t << "\\begin{description}" << endl;
+}
+
+void LatexGenerator::endDescription()
+{
+ t << "\\end{description}" << endl;
+ firstDescItem=TRUE;
+}
+
+void LatexGenerator::startDescItem()
+{
+ firstDescItem=TRUE;
+ t << "\\item[";
+}
+
+void LatexGenerator::endDescItem()
+{
+ if (firstDescItem)
+ {
+ t << "]" << endl;
+ firstDescItem=FALSE;
+ }
+ else
+ {
+ lineBreak();
+ }
+}
+
+void LatexGenerator::startSimpleSect(SectionTypes,const char *file,
+ const char *anchor,const char *title)
+{
+ t << "\\begin{Desc}\n\\item[";
+ if (file)
+ {
+ writeObjectLink(0,file,anchor,title);
+ }
+ else
+ {
+ docify(title);
+ }
+ t << "]";
+}
+
+void LatexGenerator::endSimpleSect()
+{
+ t << "\\end{Desc}" << endl;
+}
+
+void LatexGenerator::startParamList(ParamListTypes,const char *title)
+{
+ t << "\\begin{Desc}\n\\item[";
+ docify(title);
+ t << "]";
+}
+
+void LatexGenerator::endParamList()
+{
+ t << "\\end{Desc}" << endl;
+}
+
+void LatexGenerator::startParameterList(bool openBracket)
+{
+ /* start of ParameterType ParameterName list */
+ if (openBracket) t << "(";
+ t << endl << "\\begin{DoxyParamCaption}" << endl;
+}
+
+void LatexGenerator::endParameterList()
+{
+}
+
+void LatexGenerator::startParameterType(bool first,const char *key)
+{
+ t << "\\item[{";
+ if (!first && key) t << key;
+}
+
+void LatexGenerator::endParameterType()
+{
+ t << "}]";
+}
+
+void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
+{
+ t << "{";
+}
+
+void LatexGenerator::endParameterName(bool last,bool /* emptyList */,bool closeBracket)
+{
+ t << "}" << endl;
+
+ if (last)
+ {
+ t << "\\end{DoxyParamCaption}" << endl;
+ if (closeBracket) t << ")";
+ }
+}
+
+void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket)
+{
+ if (prefix)
+ t << " " << prefix;
+ else if (closeBracket)
+ t << ")";
+ t << " ";
+}
+
+void LatexGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
+{
+ LatexDocVisitor *visitor =
+ new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),insideTabbing);
+ n->accept(visitor);
+ delete visitor;
+}
+
+void LatexGenerator::startConstraintList(const char *header)
+{
+ t << "\\begin{Desc}\n\\item[";
+ docify(header);
+ t << "]";
+ t << "\\begin{description}" << endl;
+}
+
+void LatexGenerator::startConstraintParam()
+{
+ t << "\\item[{\\em ";
+}
+
+void LatexGenerator::endConstraintParam()
+{
+}
+
+void LatexGenerator::startConstraintType()
+{
+ t << "} : {\\em ";
+}
+
+void LatexGenerator::endConstraintType()
+{
+ t << "}]";
+}
+
+void LatexGenerator::startConstraintDocs()
+{
+}
+
+void LatexGenerator::endConstraintDocs()
+{
+}
+
+void LatexGenerator::endConstraintList()
+{
+ t << "\\end{description}" << endl;
+ t << "\\end{Desc}" << endl;
+}
+
+void LatexGenerator::escapeLabelName(const char *s)
+{
+ if (s==0) return;
+ const char *p=s;
+ char c;
+ QCString result(qstrlen(s)+1); // worst case allocation
+ int i;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '|': t << "\\texttt{\"|}"; break;
+ case '!': t << "\"!"; break;
+ case '%': t << "\\%"; break;
+ case '{': t << "\\lcurly{}"; break;
+ case '}': t << "\\rcurly{}"; break;
+ case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
+ // NOTE: adding a case here, means adding it to while below as well!
+ default:
+ i=0;
+ // collect as long string as possible, before handing it to docify
+ result[i++]=c;
+ while ((c=*p) && c!='|' && c!='!' && c!='%' && c!='{' && c!='}' && c!='~')
+ {
+ result[i++]=c;
+ p++;
+ }
+ result[i]=0;
+ docify(result);
+ break;
+ }
+ }
+}
+
+void LatexGenerator::escapeMakeIndexChars(const char *s)
+{
+ if (s==0) return;
+ const char *p=s;
+ char c;
+ QCString result(qstrlen(s)+1); // worst case allocation
+ int i;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '!': t << "\"!"; break;
+ case '"': t << "\"\""; break;
+ case '@': t << "\"@"; break;
+ case '|': t << "\\texttt{\"|}"; break;
+ case '[': t << "["; break;
+ case ']': t << "]"; break;
+ case '{': t << "\\lcurly{}"; break;
+ case '}': t << "\\rcurly{}"; break;
+ // NOTE: adding a case here, means adding it to while below as well!
+ default:
+ i=0;
+ // collect as long string as possible, before handing it to docify
+ result[i++]=c;
+ while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
+ {
+ result[i++]=c;
+ p++;
+ }
+ result[i]=0;
+ docify(result);
+ break;
+ }
+ }
+}
+
+void LatexGenerator::startCodeFragment()
+{
+ t << "\n\\begin{DoxyCode}\n";
+}
+
+void LatexGenerator::endCodeFragment()
+{
+ t << "\\end{DoxyCode}\n";
+}
+
+void LatexGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l)
+{
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ if (m_prettyCode)
+ {
+ QCString lineNumber;
+ lineNumber.sprintf("%05d",l);
+
+ if (fileName && !sourceFileName.isEmpty())
+ {
+ QCString lineAnchor;
+ lineAnchor.sprintf("_l%05d",l);
+ lineAnchor.prepend(sourceFileName);
+ //if (!m_prettyCode) return;
+ if (usePDFLatex && pdfHyperlinks)
+ {
+ t << "\\hypertarget{" << stripPath(lineAnchor) << "}{}";
+ }
+ writeCodeLink(ref,fileName,anchor,lineNumber,0);
+ }
+ else
+ {
+ codify(lineNumber);
+ }
+ t << " ";
+ }
+ else
+ {
+ t << l << " ";
+ }
+}
+
+void LatexGenerator::startCodeLine(bool)
+{
+ col=0;
+}
+
+void LatexGenerator::endCodeLine()
+{
+ codify("\n");
+}
+
+void LatexGenerator::startFontClass(const char *name)
+{
+ //if (!m_prettyCode) return;
+ t << "\\textcolor{" << name << "}{";
+}
+
+void LatexGenerator::endFontClass()
+{
+ //if (!m_prettyCode) return;
+ t << "}";
+}
+
+void LatexGenerator::startInlineHeader()
+{
+ if (Config_getBool("COMPACT_LATEX"))
+ {
+ t << "\\paragraph*{";
+ }
+ else
+ {
+ t << "\\subsubsection*{";
+ }
+}
+
+void LatexGenerator::endInlineHeader()
+{
+ t << "}" << endl;
+}
+
+void LatexGenerator::lineBreak(const char *)
+{
+ if (insideTabbing)
+ {
+ t << "\\\\\n";
+ }
+ else
+ {
+ t << "\\\\*\n";
+ }
+}
+
+void LatexGenerator::startMemberDocSimple()
+{
+ t << "\\begin{DoxyFields}{";
+ docify(theTranslator->trCompoundMembers());
+ t << "}" << endl;
+}
+
+void LatexGenerator::endMemberDocSimple()
+{
+ t << "\\end{DoxyFields}" << endl;
+}
+
+void LatexGenerator::startInlineMemberType()
+{
+}
+
+void LatexGenerator::endInlineMemberType()
+{
+ t << "&" << endl;
+}
+
+void LatexGenerator::startInlineMemberName()
+{
+}
+
+void LatexGenerator::endInlineMemberName()
+{
+ t << "&" << endl;
+}
+
+void LatexGenerator::startInlineMemberDoc()
+{
+}
+
+void LatexGenerator::endInlineMemberDoc()
+{
+ t << "\\\\\n\\hline\n" << endl;
+}
+
+void LatexGenerator::startLabels()
+{
+ t << "\\hspace{0.3cm}";
+}
+
+void LatexGenerator::writeLabel(const char *l,bool isLast)
+{
+ t << "{\\ttfamily [" << l << "]}";
+ if (!isLast) t << ", ";
+}
+
+void LatexGenerator::endLabels()
+{
+}
+
diff --git a/src/latexgen.h b/src/latexgen.h
new file mode 100644
index 0000000..f68612d
--- /dev/null
+++ b/src/latexgen.h
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef LATEXGEN_H
+#define LATEXGEN_H
+
+#include "outputgen.h"
+
+class QFile;
+
+/** Generator for LaTeX output. */
+class LatexGenerator : public OutputGenerator
+{
+ public:
+ LatexGenerator();
+ ~LatexGenerator();
+ static void init();
+ static void writeStyleSheetFile(QFile &f);
+ static void writeHeaderFile(QFile &f);
+ static void writeFooterFile(QFile &f);
+
+ //OutputGenerator *copy();
+ //OutputGenerator *clone() { return new LatexGenerator(*this); }
+ //void append(const OutputGenerator *o);
+ void enable()
+ { if (genStack->top()) active=*genStack->top(); else active=TRUE; }
+ void disable() { active=FALSE; }
+ void enableIf(OutputType o) { if (o==Latex) enable(); }
+ void disableIf(OutputType o) { if (o==Latex) disable(); }
+ void disableIfNot(OutputType o) { if (o!=Latex) disable(); }
+ bool isEnabled(OutputType o) { return (o==Latex && active); }
+ OutputGenerator *get(OutputType o) { return (o==Latex) ? this : 0; }
+
+ void writeDoc(DocNode *,Definition *ctx,MemberDef *);
+
+ void startFile(const char *name,const char *manName,const char *title);
+ void writeSearchInfo() {}
+ void writeFooter(const char *) {}
+ void endFile();
+ void clearBuffer();
+
+ void startIndexSection(IndexSections);
+ void endIndexSection(IndexSections);
+ void writePageLink(const char *,bool);
+ void startProjectNumber();
+ void endProjectNumber() {}
+ void writeStyleInfo(int part);
+ void startTitleHead(const char *);
+ void startTitle();
+ void endTitleHead(const char *,const char *name);
+ void endTitle() { t << "}"; }
+
+ void newParagraph();
+ void startParagraph();
+ void endParagraph();
+ void writeString(const char *text);
+ void startIndexListItem() {}
+ void endIndexListItem() {}
+ void startIndexList() { t << "\\begin{DoxyCompactList}" << endl; }
+ void endIndexList() { t << "\\end{DoxyCompactList}" << endl; }
+ void startIndexKey();
+ void endIndexKey();
+ void startIndexValue(bool);
+ void endIndexValue(const char *,bool);
+ void startItemList() { t << "\\begin{DoxyCompactItemize}" << endl; }
+ void endItemList() { t << "\\end{DoxyCompactItemize}" << endl; }
+ void startIndexItem(const char *ref,const char *file);
+ void endIndexItem(const char *ref,const char *file);
+ void docify(const char *text);
+ void codify(const char *text);
+ void writeObjectLink(const char *ref,const char *file,
+ const char *anchor,const char *name);
+ void writeCodeLink(const char *ref, const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ ) {}
+ void startTextLink(const char *,const char *);
+ void endTextLink();
+ void startHtmlLink(const char *url);
+ void endHtmlLink();
+ void startTypewriter() { t << "{\\ttfamily "; }
+ void endTypewriter() { t << "}"; }
+ void startGroupHeader(int);
+ void endGroupHeader(int);
+ void startItemListItem() { t << "\\item " << endl; }
+ void endItemListItem() {}
+
+ void startMemberSections() {}
+ void endMemberSections() {}
+ void startHeaderSection() {}
+ void endHeaderSection() {}
+ void startMemberHeader(const char *);
+ void endMemberHeader();
+ void startMemberSubtitle() {}
+ void endMemberSubtitle() {}
+ void startMemberDocList() {}
+ void endMemberDocList() {}
+ void startMemberList();
+ void endMemberList();
+ void startInlineHeader();
+ void endInlineHeader();
+ void startAnonTypeScope(int);
+ void endAnonTypeScope(int);
+ void startMemberItem(const char *,int,const char *);
+ void endMemberItem();
+ void startMemberTemplateParams();
+ void endMemberTemplateParams(const char *,const char *);
+
+ void startMemberGroupHeader(bool);
+ void endMemberGroupHeader();
+ void startMemberGroupDocs();
+ void endMemberGroupDocs();
+ void startMemberGroup();
+ void endMemberGroup(bool);
+
+ void insertMemberAlign(bool) {}
+
+ void writeRuler() { t << endl << endl; }
+ void writeAnchor(const char *fileName,const char *name);
+ void startCodeFragment();
+ void endCodeFragment();
+ void writeLineNumber(const char *,const char *,const char *,int l);
+ void startCodeLine(bool hasLineNumbers);
+ void endCodeLine();
+ void startEmphasis() { t << "{\\em "; }
+ void endEmphasis() { t << "}"; }
+ void startBold() { t << "{\\bfseries "; }
+ void endBold() { t << "}"; }
+ void startDescription();
+ void endDescription();
+ void startDescItem();
+ void endDescItem();
+ void lineBreak(const char *style=0);
+ void startMemberDoc(const char *,const char *,const char *,const char *,bool);
+ void endMemberDoc(bool);
+ void startDoxyAnchor(const char *,const char *,const char *,const char *,const char *);
+ void endDoxyAnchor(const char *,const char *);
+ void writeChar(char c);
+ void writeLatexSpacing() { t << "\\hspace{0.3cm}"; }
+ void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name);
+ void writeEndAnnoItem(const char *name);
+ void startSubsection() { t << "\\subsection*{"; }
+ void endSubsection() { t << "}" << endl; }
+ void startSubsubsection() { t << "\\subsubsection*{"; }
+ void endSubsubsection() { t << "}" << endl; }
+ void startCenter() { t << "\\begin{center}" << endl; }
+ void endCenter() { t << "\\end{center}" << endl; }
+ void startSmall() { t << "\\footnotesize "; }
+ void endSmall() { t << "\\normalsize "; }
+ void startMemberDescription(const char *,const char *);
+ void endMemberDescription();
+ void startMemberDeclaration() {}
+ void endMemberDeclaration(const char *,const char *) {}
+ void writeInheritedSectionTitle(const char *,const char *,const char *,
+ const char *,const char *,const char *) {}
+ void startDescList(SectionTypes) { t << "\\begin{Desc}\n\\item["; }
+ void endDescList() { t << "\\end{Desc}" << endl; }
+ void startSimpleSect(SectionTypes,const char *,const char *,const char *);
+ void endSimpleSect();
+ void startParamList(ParamListTypes,const char *title);
+ void endParamList();
+ void startDescForItem() { t << "\\par" << endl; }
+ void endDescForItem() {}
+ void startSection(const char *,const char *,SectionInfo::SectionType);
+ void endSection(const char *,SectionInfo::SectionType);
+ void addIndexItem(const char *,const char *);
+ void startIndent() {}
+ void endIndent() {}
+ void writeSynopsis() {}
+ void startClassDiagram();
+ void endClassDiagram(const ClassDiagram &,const char *,const char *);
+ void startPageRef();
+ void endPageRef(const char *,const char *);
+ void startQuickIndices() {}
+ void endQuickIndices() {}
+ void writeSplitBar(const char *) {}
+ void writeNavigationPath(const char *) {}
+ void writeLogo() {}
+ void writeQuickLinks(bool,HighlightedItem,const char*) {}
+ void writeSummaryLink(const char *,const char *,const char *,bool) {}
+ void startContents() {}
+ void endContents() {}
+ void writeNonBreakableSpace(int);
+
+ void startDescTable(const char *title)
+ { startSimpleSect(EnumValues,0,0,title);
+ startDescForItem();
+ t << "\\begin{description}" << endl; }
+ void endDescTable()
+ { t << "\\end{description}" << endl;
+ endDescForItem();
+ endSimpleSect();
+ }
+ void startDescTableTitle()
+ { t << "\\item[{\\em " << endl; }
+ void endDescTableTitle()
+ { t << "}]"; }
+ void startDescTableData() {}
+ void endDescTableData() {}
+ void lastIndexPage() {}
+
+ void startDotGraph();
+ void endDotGraph(const DotClassGraph &);
+ void startInclDepGraph();
+ void endInclDepGraph(const DotInclDepGraph &);
+ void startCallGraph();
+ void startGroupCollaboration();
+ void endGroupCollaboration(const DotGroupCollaboration &g);
+ void endCallGraph(const DotCallGraph &);
+ void startDirDepGraph();
+ void endDirDepGraph(const DotDirDeps &g);
+ void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {}
+
+ void startTextBlock(bool) {}
+ void endTextBlock(bool) {}
+
+ void startMemberDocPrefixItem() {}
+ void endMemberDocPrefixItem() {}
+ void startMemberDocName(bool) {}
+ void endMemberDocName() {}
+ void startParameterType(bool,const char *);
+ void endParameterType();
+ void startParameterName(bool);
+ void endParameterName(bool,bool,bool);
+ void startParameterList(bool);
+ void endParameterList();
+ void exceptionEntry(const char*,bool);
+
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
+ void startMemberDocSimple();
+ void endMemberDocSimple();
+ void startInlineMemberType();
+ void endInlineMemberType();
+ void startInlineMemberName();
+ void endInlineMemberName();
+ void startInlineMemberDoc();
+ void endInlineMemberDoc();
+
+ void startLabels();
+ void writeLabel(const char *l,bool isLast);
+ void endLabels();
+
+ void startFontClass(const char *); // {}
+ void endFontClass(); // {}
+
+ void writeCodeAnchor(const char *) {}
+ void setCurrentDoc(Definition *,const char *,bool) {}
+ void addWord(const char *,bool) {}
+
+
+ private:
+ LatexGenerator(const LatexGenerator &);
+ LatexGenerator &operator=(const LatexGenerator &);
+ void escapeLabelName(const char *s);
+ void escapeMakeIndexChars(const char *s);
+ int col;
+ bool insideTabbing;
+ bool firstDescItem;
+ bool disableLinks;
+ QCString relPath;
+ QCString sourceFileName;
+ int m_indent;
+ bool templateMemberItem;
+ bool m_prettyCode;
+};
+
+#endif
diff --git a/src/layout.cpp b/src/layout.cpp
new file mode 100644
index 0000000..739a2a3
--- /dev/null
+++ b/src/layout.cpp
@@ -0,0 +1,1464 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "layout.h"
+#include "message.h"
+#include "language.h"
+#include "vhdldocgen.h"
+#include "util.h"
+#include "doxygen.h"
+#include "version.h"
+#include "config.h"
+
+#include <assert.h>
+#include <qxml.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+
+static const char layout_default[] =
+#include "layout_default.xml.h"
+;
+
+#define ADD_OPTION(langId,text) "|"+QCString().setNum(langId)+"="+text
+
+#define COMPILE_FOR_1_OPTION(def,langId1,text1) \
+ def+ADD_OPTION(langId1,text1)
+
+#define COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2) \
+ COMPILE_FOR_1_OPTION(def,langId1,text1)+ADD_OPTION(langId2,text2)
+
+#define COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3) \
+ COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2)+ADD_OPTION(langId3,text3)
+
+#define COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4) \
+ COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3)+ADD_OPTION(langId4,text4)
+
+static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE)
+{
+ QCString visible = attrib.value("visible").utf8();
+ if (visible.isEmpty()) return defVal;
+ if (visible.at(0)=='$' && visible.length()>1)
+ {
+ QCString id = visible.mid(1);
+ ConfigOption *opt = Config::instance()->get(id);
+ if (opt && opt->kind()==ConfigOption::O_Bool)
+ {
+ return *((ConfigBool *)opt)->valueRef();
+ }
+ else if (!opt)
+ {
+ err("found unsupported value %s for visible attribute in layout file\n",
+ visible.data());
+ }
+ }
+ return visible!="no" && visible!="0";
+}
+
+//---------------------------------------------------------------------------------
+
+LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind,
+ const char *file) const
+{
+ LayoutNavEntry *result=0;
+ QListIterator<LayoutNavEntry> li(m_children);
+ LayoutNavEntry *entry;
+ for (li.toFirst();(entry=li.current());++li)
+ {
+ // depth first search, needed to find the entry furthest from the
+ // root in case an entry is in the tree twice
+ result = entry->find(kind,file);
+ if (result) return result;
+ if (entry->kind()==kind && (file==0 || entry->baseFile()==file))
+ {
+ return entry;
+ }
+ }
+ return result;
+}
+
+QCString LayoutNavEntry::url() const
+{
+ QCString url = baseFile().stripWhiteSpace();
+ if ((kind()!=LayoutNavEntry::User && kind()!=LayoutNavEntry::UserGroup) ||
+ (kind()==LayoutNavEntry::UserGroup && url.left(9)=="usergroup"))
+ {
+ url+=Doxygen::htmlFileExtension;
+ }
+ else if (url.left(5)=="@ref " || url.left(5)=="\\ref ")
+ {
+ Definition *d;
+ QCString anchor;
+ bool found=FALSE;
+ if (resolveLink(0,url.mid(5).stripWhiteSpace(),TRUE,&d,anchor))
+ {
+ if (d && d->isLinkable())
+ {
+ url=d->getOutputFileBase()+Doxygen::htmlFileExtension;
+ if (!anchor.isEmpty())
+ {
+ url+="#"+anchor;
+ }
+ found=TRUE;
+ }
+ }
+ if (!found)
+ {
+ msg("explicit link request to '%s' in layout file '%s' could not be resolved\n",qPrint(url.mid(5)),qPrint(Config_getString("LAYOUT_FILE")));
+ }
+ }
+ //printf("LayoutNavEntry::url()=%s\n",url.data());
+ return url;
+}
+
+//---------------------------------------------------------------------------------
+
+class LayoutParser : public QXmlDefaultHandler
+{
+ private:
+ class StartElementHandler
+ {
+ typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib);
+ public:
+ StartElementHandler(LayoutParser *parent, Handler h)
+ : m_parent(parent), m_handler(h) {}
+ virtual ~StartElementHandler() {}
+ virtual void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(attrib);
+ }
+ protected:
+ StartElementHandler() : m_parent(0), m_handler(0) {}
+ private:
+ LayoutParser *m_parent;
+ Handler m_handler;
+ };
+
+ class StartElementHandlerKind : public StartElementHandler
+ {
+ typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
+ const QXmlAttributes &attrib);
+ public:
+ StartElementHandlerKind(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h)
+ : m_parent(parent), m_kind(k), m_handler(h) {}
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib);
+ }
+ private:
+ LayoutParser *m_parent;
+ LayoutDocEntry::Kind m_kind;
+ Handler m_handler;
+ };
+
+ class StartElementHandlerSection : public StartElementHandler
+ {
+ typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
+ const QXmlAttributes &attrib,
+ const QCString &title);
+ public:
+ StartElementHandlerSection(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h,
+ const QCString &title)
+ : m_parent(parent), m_kind(k), m_handler(h), m_title(title) {}
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib,m_title);
+ }
+ private:
+ LayoutParser *m_parent;
+ LayoutDocEntry::Kind m_kind;
+ Handler m_handler;
+ QCString m_title;
+ };
+
+ class StartElementHandlerMember : public StartElementHandler
+ {
+ typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib,
+ MemberListType type,
+ const QCString &title,
+ const QCString &subtitle);
+ public:
+ StartElementHandlerMember(LayoutParser *parent,
+ Handler h,
+ MemberListType type,
+ const QCString &tl,
+ const QCString &ss = QCString()
+ )
+ : m_parent(parent), m_handler(h), m_type(type),
+ m_title(tl), m_subscript(ss) {}
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(attrib,m_type,m_title,m_subscript);
+ }
+ private:
+ LayoutParser *m_parent;
+ Handler m_handler;
+ MemberListType m_type;
+ QCString m_title;
+ QCString m_subscript;
+ };
+
+ class StartElementHandlerNavEntry : public StartElementHandler
+ {
+ typedef void (LayoutParser::*Handler)(LayoutNavEntry::Kind kind,
+ const QXmlAttributes &attrib,
+ const QCString &title);
+ public:
+ StartElementHandlerNavEntry(LayoutParser *parent,
+ LayoutNavEntry::Kind kind,
+ Handler h,
+ const QCString &tl
+ )
+ : m_parent(parent), m_kind(kind), m_handler(h), m_title(tl) {}
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib,m_title);
+ }
+ private:
+ LayoutParser *m_parent;
+ LayoutNavEntry::Kind m_kind;
+ Handler m_handler;
+ QCString m_title;
+ };
+
+ class EndElementHandler
+ {
+ typedef void (LayoutParser::*Handler)();
+ public:
+ EndElementHandler(LayoutParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
+ void operator()() { (m_parent->*m_handler)(); }
+ private:
+ LayoutParser *m_parent;
+ Handler m_handler;
+ };
+
+
+ public:
+ static LayoutParser &instance()
+ {
+ static LayoutParser *theInstance = new LayoutParser;
+ return *theInstance;
+ }
+ void init()
+ {
+ m_sHandler.setAutoDelete(TRUE);
+ m_eHandler.setAutoDelete(TRUE);
+ m_part = -1; // invalid
+ m_rootNav = 0;
+
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ //bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+
+ // start & end handlers
+ m_sHandler.insert("doxygenlayout",
+ new StartElementHandler(this,&LayoutParser::startLayout));
+ m_eHandler.insert("doxygenlayout",
+ new EndElementHandler(this,&LayoutParser::endLayout));
+
+ // class layout handlers
+ m_sHandler.insert("navindex",
+ new StartElementHandler(this,&LayoutParser::startNavIndex));
+ m_sHandler.insert("navindex/tab",
+ new StartElementHandler(this,&LayoutParser::startNavEntry));
+ m_eHandler.insert("navindex/tab",
+ new EndElementHandler(this,&LayoutParser::endNavEntry));
+ m_eHandler.insert("navindex",
+ new EndElementHandler(this,&LayoutParser::endNavIndex));
+
+ // class layout handlers
+ m_sHandler.insert("class",
+ new StartElementHandler(this,&LayoutParser::startClass));
+ m_sHandler.insert("class/briefdescription",
+ new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/detaileddescription",
+ new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
+ theTranslator->trDetailedDescription()));
+ m_sHandler.insert("class/authorsection",
+ new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/includes",
+ new StartElementHandlerKind(this,LayoutDocEntry::ClassIncludes,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/inheritancegraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::ClassInheritanceGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/collaborationgraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::ClassCollaborationGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/allmemberslink",
+ new StartElementHandlerKind(this,LayoutDocEntry::ClassAllMembersLink,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/usedfiles",
+ new StartElementHandlerKind(this,LayoutDocEntry::ClassUsedFiles,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/memberdecl",
+ new StartElementHandler(this,&LayoutParser::startMemberDecl));
+ m_sHandler.insert("class/memberdecl/membergroups",
+ new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("class/memberdecl/nestedclasses",
+ new StartElementHandlerSection(this,LayoutDocEntry::ClassNestedClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trCompounds(),
+ SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
+ SrcLangExt_Fortran,theTranslator->trDataTypes()
+ )));
+ m_sHandler.insert("class/memberdecl/services",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_services,theTranslator->trServices()));
+ m_sHandler.insert("class/memberdecl/interfaces",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_interfaces,theTranslator->trInterfaces()));
+ m_sHandler.insert("class/memberdecl/publictypes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubTypes,theTranslator->trPublicTypes()));
+ m_sHandler.insert("class/memberdecl/publicslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubSlots,theTranslator->trPublicSlots()));
+ m_sHandler.insert("class/memberdecl/signals",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_signals,theTranslator->trSignals()));
+ m_sHandler.insert("class/memberdecl/publicmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubMethods,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trPublicMembers(),
+ SrcLangExt_ObjC,theTranslator->trInstanceMethods()
+ )));
+ m_sHandler.insert("class/memberdecl/publicstaticmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubStaticMethods,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trStaticPublicMembers(),
+ SrcLangExt_ObjC,theTranslator->trClassMethods()
+ )));
+ m_sHandler.insert("class/memberdecl/publicattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubAttribs,theTranslator->trPublicAttribs()));
+ m_sHandler.insert("class/memberdecl/publicstaticattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()));
+ m_sHandler.insert("class/memberdecl/protectedtypes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proTypes,theTranslator->trProtectedTypes()));
+ m_sHandler.insert("class/memberdecl/protectedslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proSlots,theTranslator->trProtectedSlots()));
+ m_sHandler.insert("class/memberdecl/protectedmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proMethods,theTranslator->trProtectedMembers()));
+ m_sHandler.insert("class/memberdecl/protectedstaticmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()));
+ m_sHandler.insert("class/memberdecl/protectedattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proAttribs,theTranslator->trProtectedAttribs()));
+ m_sHandler.insert("class/memberdecl/protectedstaticattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()));
+ m_sHandler.insert("class/memberdecl/packagetypes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pacTypes,theTranslator->trPackageTypes()));
+ m_sHandler.insert("class/memberdecl/packagemethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pacMethods,theTranslator->trPackageMembers()));
+ m_sHandler.insert("class/memberdecl/packagestaticmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()));
+ m_sHandler.insert("class/memberdecl/packageattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pacAttribs,theTranslator->trPackageAttribs()));
+ m_sHandler.insert("class/memberdecl/packagestaticattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()));
+ m_sHandler.insert("class/memberdecl/properties",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_properties,theTranslator->trProperties()));
+ m_sHandler.insert("class/memberdecl/events",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_events,theTranslator->trEvents()));
+ m_sHandler.insert("class/memberdecl/privatetypes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priTypes,theTranslator->trPrivateTypes()));
+ m_sHandler.insert("class/memberdecl/privateslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priSlots,theTranslator->trPrivateSlots()));
+ m_sHandler.insert("class/memberdecl/privatemethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priMethods,theTranslator->trPrivateMembers()));
+ m_sHandler.insert("class/memberdecl/privatestaticmethods",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()));
+ m_sHandler.insert("class/memberdecl/privateattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priAttribs,theTranslator->trPrivateAttribs()));
+ m_sHandler.insert("class/memberdecl/privatestaticattributes",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()));
+ m_sHandler.insert("class/memberdecl/friends",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_friends,theTranslator->trFriends()));
+ m_sHandler.insert("class/memberdecl/related",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_related,theTranslator->trRelatedFunctions(),
+ theTranslator->trRelatedSubscript()));
+ m_eHandler.insert("class/memberdecl",
+ new EndElementHandler(this,&LayoutParser::endMemberDecl));
+ m_sHandler.insert("class/memberdef",
+ new StartElementHandler(this,&LayoutParser::startMemberDef));
+ m_sHandler.insert("class/memberdef/inlineclasses",
+ new StartElementHandlerSection(this,LayoutDocEntry::ClassInlineClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trClassDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
+ )));
+ m_sHandler.insert("class/memberdef/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation()));
+ m_sHandler.insert("class/memberdef/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation()));
+ m_sHandler.insert("class/memberdef/services",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_serviceMembers,theTranslator->trInterfaces()));
+ m_sHandler.insert("class/memberdef/interfaces",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_interfaceMembers,theTranslator->trInterfaces()));
+ m_sHandler.insert("class/memberdef/constructors",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_constructors,theTranslator->trConstructorDocumentation()));
+ m_sHandler.insert("class/memberdef/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_functionMembers,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trMemberFunctionDocumentation(),
+ SrcLangExt_ObjC,theTranslator->trMethodDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran()
+ )));
+ m_sHandler.insert("class/memberdef/related",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation()));
+ m_sHandler.insert("class/memberdef/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_variableMembers,theTranslator->trMemberDataDocumentation()));
+ m_sHandler.insert("class/memberdef/properties",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_propertyMembers,theTranslator->trPropertyDocumentation()));
+ m_sHandler.insert("class/memberdef/events",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_eventMembers,theTranslator->trEventDocumentation()));
+ m_eHandler.insert("class/memberdef",
+ new EndElementHandler(this,&LayoutParser::endMemberDef));
+ m_eHandler.insert("class",
+ new EndElementHandler(this,&LayoutParser::endClass));
+
+
+ // namespace layout handlers
+ m_sHandler.insert("namespace",
+ new StartElementHandler(this,&LayoutParser::startNamespace));
+ m_sHandler.insert("namespace/briefdescription",
+ new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("namespace/detaileddescription",
+ new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
+ theTranslator->trDetailedDescription()));
+ m_sHandler.insert("namespace/authorsection",
+ new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("namespace/memberdecl",
+ new StartElementHandler(this,&LayoutParser::startMemberDecl));
+ m_sHandler.insert("namespace/memberdecl/nestednamespaces",
+ new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedNamespaces,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_4_OPTIONS(
+ theTranslator->trNamespaces(),
+ SrcLangExt_Java,theTranslator->trPackages(),
+ SrcLangExt_VHDL,theTranslator->trPackages(),
+ SrcLangExt_IDL,theTranslator->trModules(),
+ SrcLangExt_Fortran,theTranslator->trModules()
+ )));
+ m_sHandler.insert("namespace/memberdecl/constantgroups",
+ new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedConstantGroups,&LayoutParser::startSectionEntry,
+ theTranslator->trConstantGroups()));
+ m_sHandler.insert("namespace/memberdecl/classes",
+ new StartElementHandlerSection(this,LayoutDocEntry::NamespaceClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trCompounds(),
+ SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
+ SrcLangExt_Fortran,theTranslator->trDataTypes()
+ )));
+ m_sHandler.insert("namespace/memberdecl/membergroups",
+ new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("namespace/memberdecl/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
+ m_sHandler.insert("namespace/memberdecl/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decEnumMembers,theTranslator->trEnumerations()));
+ m_sHandler.insert("namespace/memberdecl/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decFuncMembers,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trFunctions(),
+ SrcLangExt_Fortran,theTranslator->trSubprograms(),
+ SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
+ )));
+ m_sHandler.insert("namespace/memberdecl/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decVarMembers,theTranslator->trVariables()));
+ m_eHandler.insert("namespace/memberdecl",
+ new EndElementHandler(this,&LayoutParser::endMemberDecl));
+ m_sHandler.insert("namespace/memberdef",
+ new StartElementHandler(this,&LayoutParser::startMemberDef));
+ m_sHandler.insert("namespace/memberdef/inlineclasses",
+ new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInlineClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trClassDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
+ )));
+ m_sHandler.insert("namespace/memberdef/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
+ m_sHandler.insert("namespace/memberdef/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
+ m_sHandler.insert("namespace/memberdef/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docFuncMembers,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trFunctionDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
+ )));
+ m_sHandler.insert("namespace/memberdef/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
+ m_eHandler.insert("namespace/memberdef",
+ new EndElementHandler(this,&LayoutParser::endMemberDef));
+ m_eHandler.insert("namespace",
+ new EndElementHandler(this,&LayoutParser::endNamespace));
+
+ // file layout handlers
+ m_sHandler.insert("file",
+ new StartElementHandler(this,&LayoutParser::startFile));
+ m_sHandler.insert("file/briefdescription",
+ new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/detaileddescription",
+ new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
+ theTranslator->trDetailedDescription()));
+ m_sHandler.insert("file/authorsection",
+ new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/includes",
+ new StartElementHandlerKind(this,LayoutDocEntry::FileIncludes,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/includegraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::FileIncludeGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/includedbygraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::FileIncludedByGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/sourcelink",
+ new StartElementHandlerKind(this,LayoutDocEntry::FileSourceLink,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/memberdecl/membergroups",
+ new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("file/memberdecl",
+ new StartElementHandler(this,&LayoutParser::startMemberDecl));
+ m_sHandler.insert("file/memberdecl/classes",
+ new StartElementHandlerSection(this,LayoutDocEntry::FileClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trCompounds(),
+ SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
+ SrcLangExt_Fortran,theTranslator->trDataTypes()
+ )));
+ m_sHandler.insert("file/memberdecl/namespaces",
+ new StartElementHandlerSection(this,LayoutDocEntry::FileNamespaces,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_3_OPTIONS(
+ theTranslator->trNamespaces(),
+ SrcLangExt_Java,theTranslator->trPackages(),
+ SrcLangExt_IDL,theTranslator->trModules(),
+ SrcLangExt_Fortran,theTranslator->trModules()
+ )));
+ m_sHandler.insert("file/memberdecl/constantgroups",
+ new StartElementHandlerSection(this,LayoutDocEntry::FileConstantGroups,&LayoutParser::startSectionEntry,
+ theTranslator->trConstantGroups()));
+ m_sHandler.insert("file/memberdecl/defines",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decDefineMembers,theTranslator->trDefines()));
+ m_sHandler.insert("file/memberdecl/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
+ m_sHandler.insert("file/memberdecl/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decEnumMembers,theTranslator->trEnumerations()));
+ m_sHandler.insert("file/memberdecl/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decFuncMembers,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trFunctions(),
+ SrcLangExt_Fortran,theTranslator->trSubprograms(),
+ SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
+ )));
+ m_sHandler.insert("file/memberdecl/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decVarMembers,theTranslator->trVariables()));
+
+ m_eHandler.insert("file/memberdecl",
+ new EndElementHandler(this,&LayoutParser::endMemberDecl));
+ m_sHandler.insert("file/memberdef",
+ new StartElementHandler(this,&LayoutParser::startMemberDef));
+ m_sHandler.insert("file/memberdef/inlineclasses",
+ new StartElementHandlerSection(this,LayoutDocEntry::FileInlineClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trClassDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
+ )));
+ m_sHandler.insert("file/memberdef/defines",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
+ m_sHandler.insert("file/memberdef/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
+ m_sHandler.insert("file/memberdef/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docEnumMembers,
+ theTranslator->trEnumerationTypeDocumentation()));
+ m_sHandler.insert("file/memberdef/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docFuncMembers,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trFunctionDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
+ )));
+ m_sHandler.insert("file/memberdef/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
+ m_eHandler.insert("file/memberdef",
+ new EndElementHandler(this,&LayoutParser::endMemberDef));
+ m_eHandler.insert("file",
+ new EndElementHandler(this,&LayoutParser::endFile));
+
+ // group layout handlers
+ m_sHandler.insert("group",
+ new StartElementHandler(this,&LayoutParser::startGroup));
+ m_sHandler.insert("group/briefdescription",
+ new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("group/detaileddescription",
+ new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
+ theTranslator->trDetailedDescription()));
+ m_sHandler.insert("group/authorsection",
+ new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("group/groupgraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::GroupGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("group/memberdecl/membergroups",
+ new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("group/memberdecl",
+ new StartElementHandler(this,&LayoutParser::startMemberDecl));
+ m_sHandler.insert("group/memberdecl/classes",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trCompounds(),
+ SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
+ SrcLangExt_Fortran,theTranslator->trDataTypes()
+ )));
+ m_sHandler.insert("group/memberdecl/namespaces",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupNamespaces,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trNamespaces(),
+ SrcLangExt_Java,theTranslator->trPackages(),
+ SrcLangExt_Fortran,theTranslator->trModules()
+ )));
+ m_sHandler.insert("group/memberdecl/dirs",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupDirs,&LayoutParser::startSectionEntry,
+ theTranslator->trDirectories()
+ ));
+ m_sHandler.insert("group/memberdecl/nestedgroups",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupNestedGroups,&LayoutParser::startSectionEntry,
+ theTranslator->trModules()
+ ));
+ m_sHandler.insert("group/memberdecl/files",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupFiles,&LayoutParser::startSectionEntry,
+ theTranslator->trFile(TRUE,FALSE)
+ ));
+
+ m_sHandler.insert("group/memberdecl/defines",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decDefineMembers,theTranslator->trDefines()));
+ m_sHandler.insert("group/memberdecl/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
+ m_sHandler.insert("group/memberdecl/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decEnumMembers,theTranslator->trEnumerations()));
+ m_sHandler.insert("group/memberdecl/enumvalues",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decEnumValMembers,theTranslator->trEnumerationValues()));
+ m_sHandler.insert("group/memberdecl/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decFuncMembers,
+ COMPILE_FOR_2_OPTIONS(
+ theTranslator->trFunctions(),
+ SrcLangExt_Fortran,theTranslator->trSubprograms(),
+ SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
+ )));
+ m_sHandler.insert("group/memberdecl/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decVarMembers,theTranslator->trVariables()));
+ m_sHandler.insert("group/memberdecl/signals",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decSignalMembers,theTranslator->trSignals()));
+ m_sHandler.insert("group/memberdecl/publicslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decPubSlotMembers,theTranslator->trPublicSlots()));
+ m_sHandler.insert("group/memberdecl/protectedslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decProSlotMembers,theTranslator->trProtectedSlots()));
+ m_sHandler.insert("group/memberdecl/privateslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decPriSlotMembers,theTranslator->trPrivateSlots()));
+ m_sHandler.insert("group/memberdecl/events",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decEventMembers,theTranslator->trEvents()));
+ m_sHandler.insert("group/memberdecl/properties",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decPropMembers,theTranslator->trProperties()));
+ m_sHandler.insert("group/memberdecl/friends",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
+ MemberListType_decFriendMembers,theTranslator->trFriends()));
+ m_eHandler.insert("group/memberdecl",
+ new EndElementHandler(this,&LayoutParser::endMemberDecl));
+ m_sHandler.insert("group/memberdef",
+ new StartElementHandler(this,&LayoutParser::startMemberDef));
+ m_sHandler.insert("group/memberdef/pagedocs",
+ new StartElementHandlerKind(this,LayoutDocEntry::GroupPageDocs,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("group/memberdef/inlineclasses",
+ new StartElementHandlerSection(this,LayoutDocEntry::GroupInlineClasses,&LayoutParser::startSectionEntry,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trClassDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
+ )));
+ m_sHandler.insert("group/memberdef/defines",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
+ m_sHandler.insert("group/memberdef/typedefs",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
+ m_sHandler.insert("group/memberdef/enums",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
+ m_sHandler.insert("group/memberdef/enumvalues",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation()));
+ m_sHandler.insert("group/memberdef/functions",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docFuncMembers,
+ COMPILE_FOR_1_OPTION(
+ theTranslator->trFunctionDocumentation(),
+ SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
+ )));
+ m_sHandler.insert("group/memberdef/variables",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
+ m_sHandler.insert("group/memberdef/signals",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docSignalMembers,theTranslator->trSignals()));
+ m_sHandler.insert("group/memberdef/publicslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docPubSlotMembers,theTranslator->trPublicSlots()));
+ m_sHandler.insert("group/memberdef/protectedslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docProSlotMembers,theTranslator->trProtectedSlots()));
+ m_sHandler.insert("group/memberdef/privateslots",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots()));
+ m_sHandler.insert("group/memberdef/events",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docEventMembers,theTranslator->trEvents()));
+ m_sHandler.insert("group/memberdef/properties",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docPropMembers,theTranslator->trProperties()));
+ m_sHandler.insert("group/memberdef/friends",
+ new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
+ MemberListType_docFriendMembers,theTranslator->trFriends()));
+ m_eHandler.insert("group/memberdef",
+ new EndElementHandler(this,&LayoutParser::endMemberDef));
+ m_eHandler.insert("group",
+ new EndElementHandler(this,&LayoutParser::endGroup));
+
+ // directory layout handlers
+ m_sHandler.insert("directory",
+ new StartElementHandler(this,&LayoutParser::startDirectory));
+ m_sHandler.insert("directory/briefdescription",
+ new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("directory/detaileddescription",
+ new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
+ theTranslator->trDetailedDescription()));
+ m_sHandler.insert("directory/directorygraph",
+ new StartElementHandlerKind(this,LayoutDocEntry::DirGraph,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("directory/memberdecl",
+ new StartElementHandler(this,&LayoutParser::startMemberDecl));
+ m_sHandler.insert("directory/memberdecl/dirs",
+ new StartElementHandlerKind(this,LayoutDocEntry::DirSubDirs,&LayoutParser::startSimpleEntry));
+ m_sHandler.insert("directory/memberdecl/files",
+ new StartElementHandlerKind(this,LayoutDocEntry::DirFiles,&LayoutParser::startSimpleEntry));
+ m_eHandler.insert("directory/memberdecl",
+ new EndElementHandler(this,&LayoutParser::endMemberDecl));
+ m_eHandler.insert("directory",
+ new EndElementHandler(this,&LayoutParser::endDirectory));
+ }
+
+ void startSimpleEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib)
+ {
+ bool isVisible = elemIsVisible(attrib);
+ if (m_part!=-1 && isVisible)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySimple(k));
+ }
+ }
+
+ void startSectionEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib,
+ const QCString &title)
+ {
+ bool isVisible = elemIsVisible(attrib);
+ QCString userTitle = attrib.value("title").utf8();
+ //printf("startSectionEntry: title='%s' userTitle='%s'\n",
+ // title.data(),userTitle.data());
+ if (userTitle.isEmpty()) userTitle = title;
+ if (m_part!=-1 && isVisible)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySection(k,userTitle));
+ }
+ }
+
+
+ void startMemberDeclEntry(const QXmlAttributes &attrib,MemberListType type,
+ const QCString &title,const QCString &subscript)
+ {
+ //QCString visible = convertToQCString(attrib.value("visible"));
+ //bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0");
+ QCString userTitle = attrib.value("title").utf8();
+ QCString userSubscript = attrib.value("subtitle").utf8();
+ if (userTitle.isEmpty()) userTitle = title;
+ if (userSubscript.isEmpty()) userSubscript = subscript;
+ //printf("memberdecl: %s\n",userTitle.data());
+ if (m_part!=-1 /*&& isVisible*/)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntryMemberDecl(type,userTitle,userSubscript));
+ }
+ }
+
+ void startMemberDefEntry(const QXmlAttributes &attrib,MemberListType type,
+ const QCString &title,const QCString &)
+ {
+ QCString userTitle = attrib.value("title").utf8();
+ if (userTitle.isEmpty()) userTitle = title;
+ //printf("memberdef: %s\n",userTitle.data());
+ if (m_part!=-1 /*&& isVisible*/)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntryMemberDef(type,userTitle));
+ }
+ }
+
+ void startLayout(const QXmlAttributes &)
+ {
+ }
+
+ void endLayout()
+ {
+ }
+
+ void startNavIndex(const QXmlAttributes &)
+ {
+ m_scope="navindex/";
+ m_rootNav = LayoutDocManager::instance().rootNavEntry();
+ if (m_rootNav) m_rootNav->clear();
+ }
+
+ void endNavIndex()
+ {
+ m_scope="";
+ if (m_rootNav && !m_rootNav->find(LayoutNavEntry::MainPage))
+ {
+ // no MainPage node... add one as the first item of the root node...
+ new LayoutNavEntry(m_rootNav,LayoutNavEntry::MainPage, TRUE,
+ /*Config_getBool("GENERATE_TREEVIEW") ? "main" :*/ "index",
+ theTranslator->trMainPage(),TRUE);
+ }
+ }
+
+ void startNavEntry(const QXmlAttributes &attrib)
+ {
+ static bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static bool hasGraphicalHierarchy = Config_getBool("HAVE_DOT") &&
+ Config_getBool("GRAPHICAL_HIERARCHY");
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ static struct NavEntryMap
+ {
+ const char *typeStr; // type attribute name in the XML file
+ LayoutNavEntry::Kind kind; // corresponding enum name
+ QCString mainName; // default title for an item if it has children
+ QCString subName; // optional name for an item if it is rendered as a child
+ QCString intro; // introduction text to be put on the index page
+ QCString baseFile; // base name of the file containing the index page
+ } mapping[] =
+ {
+ { "mainpage",
+ LayoutNavEntry::MainPage,
+ theTranslator->trMainPage(),
+ QCString(),
+ QCString(),
+ "index"
+ },
+ { "pages",
+ LayoutNavEntry::Pages,
+ theTranslator->trRelatedPages(),
+ QCString(),
+ theTranslator->trRelatedPagesDescription(),
+ "pages"
+ },
+ { "modules",
+ LayoutNavEntry::Modules,
+ theTranslator->trModules(),
+ QCString(),
+ theTranslator->trModulesDescription(),
+ "modules"
+ },
+ { "namespaces",
+ LayoutNavEntry::Namespaces,
+ javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModules() : theTranslator->trNamespaces(),
+ javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
+ javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
+ "namespaces"
+ },
+ { "namespacelist",
+ LayoutNavEntry::NamespaceList,
+ javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
+ QCString(),
+ javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
+ "namespaces"
+ },
+ { "namespacemembers",
+ LayoutNavEntry::NamespaceMembers,
+ javaOpt || vhdlOpt ? theTranslator->trPackageMembers() : fortranOpt ? theTranslator->trModulesMembers() : theTranslator->trNamespaceMembers(),
+ QCString(),
+ fortranOpt ? theTranslator->trModulesMemberDescription(extractAll) : theTranslator->trNamespaceMemberDescription(extractAll),
+ "namespacemembers"
+ },
+ { "classindex",
+ LayoutNavEntry::ClassIndex,
+ fortranOpt ? theTranslator->trDataTypes() : vhdlOpt ? VhdlDocGen::trDesignUnits() : theTranslator->trCompoundIndex(),
+ QCString(),
+ QCString(),
+ "classes"
+ },
+ { "classes",
+ LayoutNavEntry::Classes,
+ fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trClasses(),
+ theTranslator->trCompoundList(),
+ fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(),
+ "annotated"
+ },
+ { "classlist",
+ LayoutNavEntry::ClassList,
+ fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trCompoundList(),
+ QCString(),
+ fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(),
+ "annotated"
+ },
+ { "hierarchy",
+ LayoutNavEntry::ClassHierarchy,
+ vhdlOpt ? VhdlDocGen::trDesignUnitHierarchy() : theTranslator->trClassHierarchy(),
+ QCString(),
+ theTranslator->trClassHierarchyDescription(),
+ hasGraphicalHierarchy ? "inherits" : "hierarchy"
+ },
+ { "classmembers",
+ LayoutNavEntry::ClassMembers,
+ fortranOpt ? theTranslator->trCompoundMembersFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitMembers() : theTranslator->trCompoundMembers(),
+ QCString(),
+ fortranOpt ? theTranslator->trCompoundMembersDescriptionFortran(extractAll) : theTranslator->trCompoundMembersDescription(extractAll),
+ "functions"
+ },
+ { "files",
+ LayoutNavEntry::Files,
+ theTranslator->trFile(TRUE,FALSE),
+ theTranslator->trFileList(),
+ theTranslator->trFileListDescription(extractAll),
+ "files"
+ },
+ { "filelist",
+ LayoutNavEntry::FileList,
+ theTranslator->trFileList(),
+ QCString(),
+ theTranslator->trFileListDescription(extractAll),
+ "files"
+ },
+ { "globals",
+ LayoutNavEntry::FileGlobals,
+ theTranslator->trFileMembers(),
+ QCString(),
+ theTranslator->trFileMembersDescription(extractAll),
+ "globals"
+ },
+ //{ "dirs",
+ // LayoutNavEntry::Dirs,
+ // theTranslator->trDirectories(),
+ // QCString(),
+ // theTranslator->trDirDescription(),
+ // "dirs"
+ //},
+ { "examples",
+ LayoutNavEntry::Examples,
+ theTranslator->trExamples(),
+ QCString(),
+ theTranslator->trExamplesDescription(),
+ "examples"
+ },
+ { "user",
+ LayoutNavEntry::User,
+ QCString(),
+ QCString(),
+ QCString(),
+ "user"
+ },
+ { "usergroup",
+ LayoutNavEntry::UserGroup,
+ QCString(),
+ QCString(),
+ QCString(),
+ "usergroup"
+ },
+ { 0, // end of list
+ (LayoutNavEntry::Kind)0,
+ QCString(),
+ QCString(),
+ QCString(),
+ QCString()
+ }
+ };
+ LayoutNavEntry::Kind kind;
+ // find type in the table
+ int i=0;
+ QString type = attrib.value("type");
+ while (mapping[i].typeStr)
+ {
+ if (mapping[i].typeStr==type)
+ {
+ kind = mapping[i].kind;
+ break;
+ }
+ i++;
+ }
+ if (mapping[i].typeStr==0)
+ {
+ if (type.isEmpty())
+ {
+ err("an entry tag within a navindex has no type attribute! Check your layout file!\n");
+ }
+ else
+ {
+ err("the type '%s' is not supported for the entry tag within a navindex! Check your layout file!\n",type.data());
+ }
+ m_invalidEntry=TRUE;
+ return;
+ }
+ QCString baseFile = mapping[i].baseFile;
+ QCString title = attrib.value("title").utf8();
+ bool isVisible = elemIsVisible(attrib);
+ if (title.isEmpty()) // use default title
+ {
+ title = mapping[i].mainName; // use title for main row
+ if (m_rootNav!=LayoutDocManager::instance().rootNavEntry() && !mapping[i].subName.isEmpty())
+ {
+ title = mapping[i].subName; // if this is a child of another row, use the subName if available
+ // this is mainly done to get compatible naming with older versions.
+ }
+ }
+ QCString intro = attrib.value("intro").utf8();
+ if (intro.isEmpty()) // use default intro text
+ {
+ intro = mapping[i].intro;
+ }
+ QCString url = attrib.value("url").utf8();
+ if (mapping[i].kind==LayoutNavEntry::User && !url.isEmpty())
+ {
+ baseFile=url;
+ }
+ else if (kind==LayoutNavEntry::UserGroup)
+ {
+ if (!url.isEmpty())
+ {
+ baseFile=url;
+ }
+ else
+ {
+ baseFile+=QCString().sprintf("%d",m_userGroupCount++);
+ }
+ }
+ // create new item and make it the new root
+ m_rootNav = new LayoutNavEntry(m_rootNav,kind,kind==LayoutNavEntry::MainPage?TRUE:isVisible,baseFile,title,intro);
+ }
+
+ void endNavEntry()
+ {
+ // set the root back to the parent
+ if (m_rootNav && !m_invalidEntry) m_rootNav = m_rootNav->parent();
+ m_invalidEntry=FALSE;
+ }
+
+ void startClass(const QXmlAttributes &)
+ {
+ LayoutDocManager::instance().clear(LayoutDocManager::Class);
+ m_scope="class/";
+ m_part = (int)LayoutDocManager::Class;
+ }
+
+ void endClass()
+ {
+ m_scope="";
+ m_part = -1;
+ }
+
+ void startNamespace(const QXmlAttributes &)
+ {
+ LayoutDocManager::instance().clear(LayoutDocManager::Namespace);
+ m_scope="namespace/";
+ m_part = (int)LayoutDocManager::Namespace;
+ }
+
+ void endNamespace()
+ {
+ m_scope="";
+ m_part = -1;
+ }
+
+ void startFile(const QXmlAttributes &)
+ {
+ LayoutDocManager::instance().clear(LayoutDocManager::File);
+ m_scope="file/";
+ m_part = (int)LayoutDocManager::File;
+ }
+
+ void endFile()
+ {
+ m_scope="";
+ m_part = -1;
+ }
+
+ void startGroup(const QXmlAttributes &)
+ {
+ LayoutDocManager::instance().clear(LayoutDocManager::Group);
+ m_scope="group/";
+ m_part = (int)LayoutDocManager::Group;
+ }
+
+ void endGroup()
+ {
+ m_scope="";
+ m_part = -1;
+ }
+
+ void startDirectory(const QXmlAttributes &)
+ {
+ LayoutDocManager::instance().clear(LayoutDocManager::Directory);
+ m_scope="directory/";
+ m_part = (int)LayoutDocManager::Directory;
+ }
+
+ void endDirectory()
+ {
+ m_scope="";
+ m_part = -1;
+ }
+
+ void startMemberDef(const QXmlAttributes &)
+ {
+ m_scope+="memberdef/";
+ if (m_part!=-1)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySimple(LayoutDocEntry::MemberDefStart));
+ }
+ }
+
+ void endMemberDef()
+ {
+ int i=m_scope.findRev("memberdef/");
+ if (i!=-1)
+ {
+ m_scope=m_scope.left(i);
+ if (m_part!=-1)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySimple(LayoutDocEntry::MemberDefEnd));
+ }
+ }
+ }
+
+ void startMemberDecl(const QXmlAttributes &)
+ {
+ m_scope+="memberdecl/";
+ if (m_part!=-1)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclStart));
+ }
+ }
+
+ void endMemberDecl()
+ {
+ int i=m_scope.findRev("memberdecl/");
+ if (i!=-1)
+ {
+ m_scope=m_scope.left(i);
+ if (m_part!=-1)
+ {
+ LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
+ new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclEnd));
+ }
+ }
+ }
+
+ // reimplemented from QXmlDefaultHandler
+ bool startElement( const QString&, const QString&,
+ const QString& name, const QXmlAttributes& attrib )
+ {
+ //printf("startElement [%s]::[%s]\n",m_scope.data(),name.data());
+ StartElementHandler *handler = m_sHandler[m_scope+name.utf8()];
+ if (handler)
+ {
+ (*handler)(attrib);
+ }
+ else
+ {
+ err("Unexpected start tag `%s' found in scope='%s'!\n",
+ name.data(),m_scope.data());
+ }
+ return TRUE;
+ }
+ bool endElement( const QString&, const QString&, const QString& name )
+ {
+ //printf("endElement [%s]::[%s]\n",m_scope.data(),name.data());
+ EndElementHandler *handler;
+ if (!m_scope.isEmpty() && m_scope.right(name.length()+1)==name.utf8()+"/")
+ { // element ends current scope
+ handler = m_eHandler[m_scope.left(m_scope.length()-1)];
+ }
+ else // continue with current scope
+ {
+ handler = m_eHandler[m_scope+name.utf8()];
+ }
+ if (handler)
+ {
+ (*handler)();
+ }
+ return TRUE;
+ }
+ bool startDocument()
+ {
+ return TRUE;
+ }
+
+ private:
+ LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE) { }
+
+ QDict<StartElementHandler> m_sHandler;
+ QDict<EndElementHandler> m_eHandler;
+ QCString m_scope;
+ int m_part;
+ LayoutNavEntry *m_rootNav;
+ bool m_invalidEntry;
+ static int m_userGroupCount;
+};
+
+int LayoutParser::m_userGroupCount=0;
+
+//---------------------------------------------------------------------------------
+
+class LayoutErrorHandler : public QXmlErrorHandler
+{
+ public:
+ LayoutErrorHandler(const char *fn) : fileName(fn) {}
+ bool warning( const QXmlParseException &exception )
+ {
+ warn_uncond("at line %d column %d of %s: %s\n",
+ exception.lineNumber(),exception.columnNumber(),fileName.data(),
+ exception.message().data());
+ return FALSE;
+ }
+ bool error( const QXmlParseException &exception )
+ {
+ err("at line %d column %d of %s: %s\n",
+ exception.lineNumber(),exception.columnNumber(),fileName.data(),
+ exception.message().data());
+ return FALSE;
+ }
+ bool fatalError( const QXmlParseException &exception )
+ {
+ err("fatal: at line %d column %d of %s: %s\n",
+ exception.lineNumber(),exception.columnNumber(),fileName.data(),
+ exception.message().data());
+ return FALSE;
+ }
+ QString errorString() { return ""; }
+
+ private:
+ QString errorMsg;
+ QString fileName;
+};
+
+//---------------------------------------------------------------------------------
+
+class LayoutDocManager::Private
+{
+ public:
+ QList<LayoutDocEntry> docEntries[LayoutDocManager::NrParts];
+ LayoutNavEntry *rootNav;
+};
+
+LayoutDocManager::LayoutDocManager()
+{
+ d = new Private;
+ int i;
+ for (i=0;i<LayoutDocManager::NrParts;i++)
+ {
+ d->docEntries[i].setAutoDelete(TRUE);
+ }
+ d->rootNav = new LayoutNavEntry;
+ LayoutParser::instance().init();
+}
+
+
+void LayoutDocManager::init()
+{
+ // parse the default layout
+ LayoutErrorHandler errorHandler( "layout_default.xml" );
+ QXmlInputSource source;
+ source.setData( layout_default );
+ QXmlSimpleReader reader;
+ reader.setContentHandler( &LayoutParser::instance() );
+ reader.setErrorHandler( &errorHandler );
+ reader.parse( source );
+}
+
+LayoutDocManager::~LayoutDocManager()
+{
+ delete d->rootNav;
+ delete d;
+}
+
+LayoutDocManager & LayoutDocManager::instance()
+{
+ static LayoutDocManager *theInstance = new LayoutDocManager;
+ return *theInstance;
+}
+
+const QList<LayoutDocEntry> &LayoutDocManager::docEntries(LayoutDocManager::LayoutPart part) const
+{
+ return d->docEntries[(int)part];
+}
+
+LayoutNavEntry* LayoutDocManager::rootNavEntry() const
+{
+ return d->rootNav;
+}
+
+void LayoutDocManager::addEntry(LayoutDocManager::LayoutPart p,LayoutDocEntry *e)
+{
+ d->docEntries[(int)p].append(e);
+}
+
+void LayoutDocManager::clear(LayoutDocManager::LayoutPart p)
+{
+ d->docEntries[(int)p].clear();
+}
+
+void LayoutDocManager::parse(QTextStream &t,const char *fileName)
+{
+ LayoutErrorHandler errorHandler(fileName);
+ QXmlInputSource source( t );
+ QXmlSimpleReader reader;
+ reader.setContentHandler( &LayoutParser::instance() );
+ reader.setErrorHandler( &errorHandler );
+ reader.parse( source );
+}
+
+//---------------------------------------------------------------------------------
+
+void writeDefaultLayoutFile(const char *fileName)
+{
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Failed to open file %s for writing!\n",fileName);
+ return;
+ }
+ QTextStream t(&f);
+ t << substitute(layout_default,"$doxygenversion",versionString);
+}
+
+//----------------------------------------------------------------------------------
+
+// Convert input to a title.
+// The format of input can be a simple title "A title" or in case there are different
+// titles for some programming languages they can take the following form:
+// "A title|16=Another title|8=Yet Another title"
+// where the number is a value of SrcLangExt in decimal notation (i.e. 16=Java, 8=IDL).
+QCString extractLanguageSpecificTitle(const QCString &input,SrcLangExt lang)
+{
+ int i,s=0,e=input.find('|');
+ if (e==-1) return input; // simple title case
+ int e1=e;
+ while (e!=-1) // look for 'number=title' pattern separated by '|'
+ {
+ s=e+1;
+ e=input.find('|',s);
+ i=input.find('=',s);
+ assert(i>s);
+ int key=input.mid(s,i-s).toInt();
+ if (key==(int)lang) // found matching key
+ {
+ if (e==-1) e=input.length();
+ return input.mid(i+1,e-i-1);
+ }
+ }
+ return input.left(e1); // fallback, no explicit language key found
+}
+
+//----------------------------------------------------------------------------------
+
+QCString LayoutDocEntrySection::title(SrcLangExt lang) const
+{
+ return extractLanguageSpecificTitle(m_title,lang);
+}
+
+//----------------------------------------------------------------------------------
+
+QCString LayoutDocEntryMemberDecl::title(SrcLangExt lang) const
+{
+ return extractLanguageSpecificTitle(m_title,lang);
+}
+
+QCString LayoutDocEntryMemberDecl::subtitle(SrcLangExt lang) const
+{
+ return extractLanguageSpecificTitle(m_subscript,lang);
+}
+
+//----------------------------------------------------------------------------------
+
+QCString LayoutDocEntryMemberDef::title(SrcLangExt lang) const
+{
+ return extractLanguageSpecificTitle(m_title,lang);
+}
+
+
+
+
diff --git a/src/layout.h b/src/layout.h
new file mode 100644
index 0000000..d50bc7c
--- /dev/null
+++ b/src/layout.h
@@ -0,0 +1,206 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef LAYOUT_H
+#define LAYOUT_H
+
+#include <qlist.h>
+#include "types.h"
+
+class LayoutParser;
+class MemberList;
+class QTextStream;
+
+/** @brief Base class representing a piece of a documentation page */
+struct LayoutDocEntry
+{
+ virtual ~LayoutDocEntry() {}
+ enum Kind {
+ // Generic items for all pages
+ MemberGroups,
+ MemberDeclStart, MemberDeclEnd, MemberDecl,
+ MemberDefStart, MemberDefEnd, MemberDef,
+ BriefDesc, DetailedDesc,
+ AuthorSection,
+
+ // Class specific items
+ ClassIncludes, ClassInlineClasses,
+ ClassInheritanceGraph, ClassNestedClasses,
+ ClassCollaborationGraph, ClassAllMembersLink,
+ ClassUsedFiles,
+
+ // Namespace specific items
+ NamespaceNestedNamespaces, NamespaceNestedConstantGroups,
+ NamespaceClasses, NamespaceInlineClasses,
+
+ // File specific items
+ FileClasses, FileNamespaces, FileConstantGroups,
+ FileIncludes, FileIncludeGraph,
+ FileIncludedByGraph, FileSourceLink,
+ FileInlineClasses,
+
+ // Group specific items
+ GroupClasses, GroupInlineClasses, GroupNamespaces,
+ GroupDirs, GroupNestedGroups, GroupFiles,
+ GroupGraph, GroupPageDocs,
+
+ // Directory specific items
+ DirSubDirs, DirFiles, DirGraph
+
+ };
+ virtual Kind kind() const = 0;
+};
+
+/** @brief Represents of a piece of a documentation page without configurable parts */
+struct LayoutDocEntrySimple : LayoutDocEntry
+{
+ public:
+ LayoutDocEntrySimple(Kind k) : m_kind(k) {}
+ Kind kind() const { return m_kind; }
+ private:
+ Kind m_kind;
+};
+
+struct LayoutDocEntrySection: public LayoutDocEntrySimple
+{
+ LayoutDocEntrySection(Kind k,const QCString &tl) :
+ LayoutDocEntrySimple(k), m_title(tl) {}
+ QCString title(SrcLangExt lang) const;
+private:
+ QCString m_title;
+};
+
+/** @brief Represents of a member declaration list with configurable title and subtitle. */
+struct LayoutDocEntryMemberDecl: public LayoutDocEntry
+{
+ LayoutDocEntryMemberDecl(MemberListType tp,
+ const QCString &tl,const QCString &ss)
+ : type(tp), m_title(tl), m_subscript(ss) {}
+
+ Kind kind() const { return MemberDecl; }
+ MemberListType type;
+ QCString title(SrcLangExt lang) const;
+ QCString subtitle(SrcLangExt lang) const;
+private:
+ QCString m_title;
+ QCString m_subscript;
+};
+
+/** @brief Represents of a member definition list with configurable title. */
+struct LayoutDocEntryMemberDef: public LayoutDocEntry
+{
+ LayoutDocEntryMemberDef(MemberListType tp,const QCString &tl)
+ : type(tp), m_title(tl) {}
+
+ Kind kind() const { return MemberDef; }
+ MemberListType type;
+ QCString title(SrcLangExt lang) const;
+private:
+ QCString m_title;
+};
+
+/** @brief Base class for the layout of a navigation item at the top of the HTML pages. */
+struct LayoutNavEntry
+{
+ public:
+ enum Kind {
+ MainPage,
+ Pages,
+ Modules,
+ Namespaces,
+ NamespaceList,
+ NamespaceMembers,
+ Classes,
+ ClassList,
+ ClassIndex,
+ ClassHierarchy,
+ ClassMembers,
+ Files,
+ FileList,
+ FileGlobals,
+ //Dirs,
+ Examples,
+ User,
+ UserGroup
+ };
+ LayoutNavEntry(LayoutNavEntry *parent,Kind k,bool vs,const QCString &bf,
+ const QCString &tl,const QCString &intro,bool prepend=FALSE)
+ : m_parent(parent), m_kind(k), m_visible(vs), m_baseFile(bf), m_title(tl), m_intro(intro)
+ { m_children.setAutoDelete(TRUE);
+ if (parent) { if (prepend) parent->prependChild(this); else parent->addChild(this); }
+ }
+ LayoutNavEntry *parent() const { return m_parent; }
+ Kind kind() const { return m_kind; }
+ QCString baseFile() const { return m_baseFile; }
+ QCString title() const { return m_title; }
+ QCString intro() const { return m_intro; }
+ QCString url() const;
+ bool visible() { return m_visible; }
+ void clear() { m_children.clear(); }
+ void addChild(LayoutNavEntry *e) { m_children.append(e); }
+ void prependChild(LayoutNavEntry *e) { m_children.prepend(e); }
+ const QList<LayoutNavEntry> &children() const { return m_children; }
+ LayoutNavEntry *find(LayoutNavEntry::Kind k,const char *file=0) const;
+
+ private:
+ LayoutNavEntry() : m_parent(0) {}
+ LayoutNavEntry *m_parent;
+ Kind m_kind;
+ bool m_visible;
+ QCString m_baseFile;
+ QCString m_title;
+ QCString m_intro;
+ QList<LayoutNavEntry> m_children;
+ friend class LayoutDocManager;
+};
+
+/** @brief Singleton providing access to the (user configurable) layout of the documentation */
+class LayoutDocManager
+{
+ class Private;
+ public:
+ enum LayoutPart
+ {
+ Class, Namespace, File, Group, Directory,
+ NrParts
+ };
+ /** Returns a reference to this singleton. */
+ static LayoutDocManager &instance();
+
+ /** Returns the list of LayoutDocEntry's in representation order for a given page identified by @a part. */
+ const QList<LayoutDocEntry> &docEntries(LayoutPart part) const;
+
+ /** returns the (invisible) root of the navigation tree. */
+ LayoutNavEntry *rootNavEntry() const;
+
+ /** Parses a user provided layout */
+ void parse(QTextStream &t,const char *fileName);
+ void init();
+ private:
+ void addEntry(LayoutPart p,LayoutDocEntry*e);
+ void clear(LayoutPart p);
+ LayoutDocManager();
+ ~LayoutDocManager();
+ Private *d;
+ friend class LayoutParser;
+};
+
+void writeDefaultLayoutFile(const char *fileName);
+
+#endif
+
diff --git a/src/layout_default.h b/src/layout_default.h
new file mode 100644
index 0000000..d775926
--- /dev/null
+++ b/src/layout_default.h
@@ -0,0 +1,194 @@
+"<doxygenlayout version=\"1.0\">\n"
+" <!-- Generated by doxygen $doxygenversion -->\n"
+" <!-- Navigation index tabs for HTML output -->\n"
+" <navindex>\n"
+" <tab type=\"mainpage\" visible=\"yes\" title=\"\"/>\n"
+" <tab type=\"pages\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"modules\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"namespaces\" visible=\"yes\" title=\"\">\n"
+" <tab type=\"namespacelist\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"namespacemembers\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" </tab>\n"
+" <tab type=\"classes\" visible=\"yes\" title=\"\">\n"
+" <tab type=\"classlist\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"classindex\" visible=\"$ALPHABETICAL_INDEX\" title=\"\"/> \n"
+" <tab type=\"hierarchy\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"classmembers\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" </tab>\n"
+" <tab type=\"files\" visible=\"yes\" title=\"\">\n"
+" <tab type=\"filelist\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" <tab type=\"globals\" visible=\"yes\" title=\"\" intro=\"\"/>\n"
+" </tab>\n"
+" <tab type=\"examples\" visible=\"yes\" title=\"\" intro=\"\"/> \n"
+" </navindex>\n"
+"\n"
+" <!-- Layout definition for a class page -->\n"
+" <class>\n"
+" <briefdescription visible=\"yes\"/>\n"
+" <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n"
+" <inheritancegraph visible=\"$CLASS_GRAPH\"/>\n"
+" <collaborationgraph visible=\"$COLLABORATION_GRAPH\"/>\n"
+" <memberdecl>\n"
+" <nestedclasses visible=\"yes\" title=\"\"/>\n"
+" <publictypes title=\"\"/>\n"
+" <services title=\"\"/>\n"
+" <interfaces title=\"\"/>\n"
+" <publicslots title=\"\"/>\n"
+" <signals title=\"\"/>\n"
+" <publicmethods title=\"\"/>\n"
+" <publicstaticmethods title=\"\"/>\n"
+" <publicattributes title=\"\"/>\n"
+" <publicstaticattributes title=\"\"/>\n"
+" <protectedtypes title=\"\"/>\n"
+" <protectedslots title=\"\"/>\n"
+" <protectedmethods title=\"\"/>\n"
+" <protectedstaticmethods title=\"\"/>\n"
+" <protectedattributes title=\"\"/>\n"
+" <protectedstaticattributes title=\"\"/>\n"
+" <packagetypes title=\"\"/>\n"
+" <packagemethods title=\"\"/>\n"
+" <packagestaticmethods title=\"\"/>\n"
+" <packageattributes title=\"\"/>\n"
+" <packagestaticattributes title=\"\"/>\n"
+" <properties title=\"\"/>\n"
+" <events title=\"\"/>\n"
+" <privatetypes title=\"\"/>\n"
+" <privateslots title=\"\"/>\n"
+" <privatemethods title=\"\"/>\n"
+" <privatestaticmethods title=\"\"/>\n"
+" <privateattributes title=\"\"/>\n"
+" <privatestaticattributes title=\"\"/>\n"
+" <friends title=\"\"/>\n"
+" <related title=\"\" subtitle=\"\"/>\n"
+" <membergroups visible=\"yes\"/>\n"
+" </memberdecl>\n"
+" <detaileddescription title=\"\"/>\n"
+" <memberdef>\n"
+" <inlineclasses title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <services title=\"\"/>\n"
+" <interfaces title=\"\"/>\n"
+" <constructors title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <related title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" <properties title=\"\"/>\n"
+" <events title=\"\"/>\n"
+" </memberdef>\n"
+" <allmemberslink visible=\"yes\"/>\n"
+" <usedfiles visible=\"$SHOW_USED_FILES\"/>\n"
+" <authorsection visible=\"yes\"/>\n"
+" </class>\n"
+"\n"
+" <!-- Layout definition for a namespace page -->\n"
+" <namespace>\n"
+" <briefdescription visible=\"yes\"/>\n"
+" <memberdecl>\n"
+" <nestednamespaces visible=\"yes\" title=\"\"/>\n"
+" <constantgroups visible=\"yes\" title=\"\"/>\n"
+" <classes visible=\"yes\" title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" <membergroups visible=\"yes\"/>\n"
+" </memberdecl>\n"
+" <detaileddescription title=\"\"/>\n"
+" <memberdef>\n"
+" <inlineclasses title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" </memberdef>\n"
+" <authorsection visible=\"yes\"/>\n"
+" </namespace>\n"
+"\n"
+" <!-- Layout definition for a file page -->\n"
+" <file>\n"
+" <briefdescription visible=\"yes\"/>\n"
+" <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n"
+" <includegraph visible=\"$INCLUDE_GRAPH\"/>\n"
+" <includedbygraph visible=\"$INCLUDED_BY_GRAPH\"/>\n"
+" <sourcelink visible=\"yes\"/>\n"
+" <memberdecl>\n"
+" <classes visible=\"yes\" title=\"\"/>\n"
+" <namespaces visible=\"yes\" title=\"\"/>\n"
+" <constantgroups visible=\"yes\" title=\"\"/>\n"
+" <defines title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" <membergroups visible=\"yes\"/>\n"
+" </memberdecl>\n"
+" <detaileddescription title=\"\"/>\n"
+" <memberdef>\n"
+" <inlineclasses title=\"\"/>\n"
+" <defines title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" </memberdef>\n"
+" <authorsection/>\n"
+" </file>\n"
+"\n"
+" <!-- Layout definition for a group page -->\n"
+" <group>\n"
+" <briefdescription visible=\"yes\"/>\n"
+" <groupgraph visible=\"$GROUP_GRAPHS\"/>\n"
+" <memberdecl>\n"
+" <nestedgroups visible=\"yes\" title=\"\"/>\n"
+" <dirs visible=\"yes\" title=\"\"/>\n"
+" <files visible=\"yes\" title=\"\"/>\n"
+" <namespaces visible=\"yes\" title=\"\"/>\n"
+" <classes visible=\"yes\" title=\"\"/>\n"
+" <defines title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <enumvalues title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" <signals title=\"\"/>\n"
+" <publicslots title=\"\"/>\n"
+" <protectedslots title=\"\"/>\n"
+" <privateslots title=\"\"/>\n"
+" <events title=\"\"/>\n"
+" <properties title=\"\"/>\n"
+" <friends title=\"\"/>\n"
+" <membergroups visible=\"yes\"/>\n"
+" </memberdecl>\n"
+" <detaileddescription title=\"\"/>\n"
+" <memberdef>\n"
+" <pagedocs/>\n"
+" <inlineclasses title=\"\"/>\n"
+" <defines title=\"\"/>\n"
+" <typedefs title=\"\"/>\n"
+" <enums title=\"\"/>\n"
+" <enumvalues title=\"\"/>\n"
+" <functions title=\"\"/>\n"
+" <variables title=\"\"/>\n"
+" <signals title=\"\"/>\n"
+" <publicslots title=\"\"/>\n"
+" <protectedslots title=\"\"/>\n"
+" <privateslots title=\"\"/>\n"
+" <events title=\"\"/>\n"
+" <properties title=\"\"/>\n"
+" <friends title=\"\"/>\n"
+" </memberdef>\n"
+" <authorsection visible=\"yes\"/>\n"
+" </group>\n"
+"\n"
+" <!-- Layout definition for a directory page -->\n"
+" <directory>\n"
+" <briefdescription visible=\"yes\"/>\n"
+" <directorygraph visible=\"yes\"/>\n"
+" <memberdecl>\n"
+" <dirs visible=\"yes\"/>\n"
+" <files visible=\"yes\"/>\n"
+" </memberdecl>\n"
+" <detaileddescription title=\"\"/>\n"
+" </directory>\n"
+"</doxygenlayout>\n"
diff --git a/src/layout_default.xml b/src/layout_default.xml
new file mode 100644
index 0000000..f087958
--- /dev/null
+++ b/src/layout_default.xml
@@ -0,0 +1,194 @@
+<doxygenlayout version="1.0">
+ <!-- Generated by doxygen $doxygenversion -->
+ <!-- Navigation index tabs for HTML output -->
+ <navindex>
+ <tab type="mainpage" visible="yes" title=""/>
+ <tab type="pages" visible="yes" title="" intro=""/>
+ <tab type="modules" visible="yes" title="" intro=""/>
+ <tab type="namespaces" visible="yes" title="">
+ <tab type="namespacelist" visible="yes" title="" intro=""/>
+ <tab type="namespacemembers" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="classes" visible="yes" title="">
+ <tab type="classlist" visible="yes" title="" intro=""/>
+ <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+ <tab type="hierarchy" visible="yes" title="" intro=""/>
+ <tab type="classmembers" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="files" visible="yes" title="">
+ <tab type="filelist" visible="yes" title="" intro=""/>
+ <tab type="globals" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="examples" visible="yes" title="" intro=""/>
+ </navindex>
+
+ <!-- Layout definition for a class page -->
+ <class>
+ <briefdescription visible="yes"/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <inheritancegraph visible="$CLASS_GRAPH"/>
+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+ <memberdecl>
+ <nestedclasses visible="yes" title=""/>
+ <publictypes title=""/>
+ <services title=""/>
+ <interfaces title=""/>
+ <publicslots title=""/>
+ <signals title=""/>
+ <publicmethods title=""/>
+ <publicstaticmethods title=""/>
+ <publicattributes title=""/>
+ <publicstaticattributes title=""/>
+ <protectedtypes title=""/>
+ <protectedslots title=""/>
+ <protectedmethods title=""/>
+ <protectedstaticmethods title=""/>
+ <protectedattributes title=""/>
+ <protectedstaticattributes title=""/>
+ <packagetypes title=""/>
+ <packagemethods title=""/>
+ <packagestaticmethods title=""/>
+ <packageattributes title=""/>
+ <packagestaticattributes title=""/>
+ <properties title=""/>
+ <events title=""/>
+ <privatetypes title=""/>
+ <privateslots title=""/>
+ <privatemethods title=""/>
+ <privatestaticmethods title=""/>
+ <privateattributes title=""/>
+ <privatestaticattributes title=""/>
+ <friends title=""/>
+ <related title="" subtitle=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <detaileddescription title=""/>
+ <memberdef>
+ <inlineclasses title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <services title=""/>
+ <interfaces title=""/>
+ <constructors title=""/>
+ <functions title=""/>
+ <related title=""/>
+ <variables title=""/>
+ <properties title=""/>
+ <events title=""/>
+ </memberdef>
+ <allmemberslink visible="yes"/>
+ <usedfiles visible="$SHOW_USED_FILES"/>
+ <authorsection visible="yes"/>
+ </class>
+
+ <!-- Layout definition for a namespace page -->
+ <namespace>
+ <briefdescription visible="yes"/>
+ <memberdecl>
+ <nestednamespaces visible="yes" title=""/>
+ <constantgroups visible="yes" title=""/>
+ <classes visible="yes" title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <detaileddescription title=""/>
+ <memberdef>
+ <inlineclasses title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </namespace>
+
+ <!-- Layout definition for a file page -->
+ <file>
+ <briefdescription visible="yes"/>
+ <includes visible="$SHOW_INCLUDE_FILES"/>
+ <includegraph visible="$INCLUDE_GRAPH"/>
+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+ <sourcelink visible="yes"/>
+ <memberdecl>
+ <classes visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+ <constantgroups visible="yes" title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <detaileddescription title=""/>
+ <memberdef>
+ <inlineclasses title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ </memberdef>
+ <authorsection/>
+ </file>
+
+ <!-- Layout definition for a group page -->
+ <group>
+ <briefdescription visible="yes"/>
+ <groupgraph visible="$GROUP_GRAPHS"/>
+ <memberdecl>
+ <nestedgroups visible="yes" title=""/>
+ <dirs visible="yes" title=""/>
+ <files visible="yes" title=""/>
+ <namespaces visible="yes" title=""/>
+ <classes visible="yes" title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <enumvalues title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+ <membergroups visible="yes"/>
+ </memberdecl>
+ <detaileddescription title=""/>
+ <memberdef>
+ <pagedocs/>
+ <inlineclasses title=""/>
+ <defines title=""/>
+ <typedefs title=""/>
+ <enums title=""/>
+ <enumvalues title=""/>
+ <functions title=""/>
+ <variables title=""/>
+ <signals title=""/>
+ <publicslots title=""/>
+ <protectedslots title=""/>
+ <privateslots title=""/>
+ <events title=""/>
+ <properties title=""/>
+ <friends title=""/>
+ </memberdef>
+ <authorsection visible="yes"/>
+ </group>
+
+ <!-- Layout definition for a directory page -->
+ <directory>
+ <briefdescription visible="yes"/>
+ <directorygraph visible="yes"/>
+ <memberdecl>
+ <dirs visible="yes"/>
+ <files visible="yes"/>
+ </memberdecl>
+ <detaileddescription title=""/>
+ </directory>
+</doxygenlayout>
diff --git a/src/libdoxycfg.pro b/src/libdoxycfg.pro
new file mode 100644
index 0000000..4379ef3
--- /dev/null
+++ b/src/libdoxycfg.pro
@@ -0,0 +1,34 @@
+#
+# This file was generated from libdoxycfg.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = libdoxycfg.t
+CONFIG = console warn_on staticlib debug
+HEADERS = config.h configoptions.h portable.h
+SOURCES = ../generated_src/doxygen/config.cpp ../generated_src/doxygen/configoptions.cpp portable.cpp portable_c.c
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti
+DEPENDPATH += ../generated_src/doxygen
+INCLUDEPATH += ../generated_src/doxygen . ../qtools
+DESTDIR = ../lib
+TARGET = doxycfg
+OBJECTS_DIR = ../objects/doxygen
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/src/libdoxycfg.pro.in b/src/libdoxycfg.pro.in
new file mode 100644
index 0000000..ab7c36c
--- /dev/null
+++ b/src/libdoxycfg.pro.in
@@ -0,0 +1,27 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = libdoxycfg.t
+CONFIG = console warn_on staticlib $extraopts
+HEADERS = config.h configoptions.h portable.h
+SOURCES = ../generated_src/doxygen/config.cpp ../generated_src/doxygen/configoptions.cpp portable.cpp portable_c.c
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti
+DEPENDPATH += ../generated_src/doxygen
+INCLUDEPATH += ../generated_src/doxygen . ../qtools
+DESTDIR = ../lib
+TARGET = doxycfg
+OBJECTS_DIR = ../objects/doxygen
diff --git a/src/libdoxycfg.t b/src/libdoxycfg.t
new file mode 100644
index 0000000..3a40b63
--- /dev/null
+++ b/src/libdoxycfg.t
@@ -0,0 +1,53 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#!
+#! doxygen.t: This is a custom template for building Doxygen
+#!
+#$ IncludeTemplate("lib.t");
+
+LEX = /usr/bin/flex
+YACC = /opt/local/bin/bison
+PYTHON = /opt/local/bin/python2
+
+#${
+sub GenerateDep {
+ my($obj,$src,$dep) = @_;
+ my(@objv,$srcv,$i,$s,$o,$d,$c);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ next if $s eq "";
+ $text .= $o . ": " . $s;
+ $text .= " ${linebreak}\n\t\t" . $dep if $dep ne "";
+ if ( $moc_output{$s} ne "" ) {
+ $text .= " ${linebreak}\n\t\t" . $moc_output{$s};
+ }
+ $d = &make_depend($s);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ $text .= "\n";
+ }
+ chop $text;
+}
+#$}
+
+####################
+
+#$ GenerateDep("../generated_src/doxygen/config.cpp","config.l");
+ $(LEX) -PconfigYY -t config.l >../generated_src/doxygen/config.cpp
+
+../generated_src/doxygen/configoptions.cpp: config.xml configgen.py
+ $(PYTHON) configgen.py -cpp config.xml >../generated_src/doxygen/configoptions.cpp
+
diff --git a/src/libdoxycfg.t.in b/src/libdoxycfg.t.in
new file mode 100644
index 0000000..89833f6
--- /dev/null
+++ b/src/libdoxycfg.t.in
@@ -0,0 +1,53 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#!
+#! doxygen.t: This is a custom template for building Doxygen
+#!
+#$ IncludeTemplate("lib.t");
+
+LEX = %%FLEX%%
+YACC = %%BISON%%
+PYTHON = %%PYTHON%%
+
+#${
+sub GenerateDep {
+ my($obj,$src,$dep) = @_;
+ my(@objv,$srcv,$i,$s,$o,$d,$c);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ next if $s eq "";
+ $text .= $o . ": " . $s;
+ $text .= " ${linebreak}\n\t\t" . $dep if $dep ne "";
+ if ( $moc_output{$s} ne "" ) {
+ $text .= " ${linebreak}\n\t\t" . $moc_output{$s};
+ }
+ $d = &make_depend($s);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ $text .= "\n";
+ }
+ chop $text;
+}
+#$}
+
+####################
+
+#$ GenerateDep("../generated_src/doxygen/config.cpp","config.l");
+ $(LEX) -PconfigYY -t config.l >../generated_src/doxygen/config.cpp
+
+../generated_src/doxygen/configoptions.cpp: config.xml configgen.py
+ $(PYTHON) configgen.py -cpp config.xml >../generated_src/doxygen/configoptions.cpp
+
diff --git a/src/libdoxygen.pro b/src/libdoxygen.pro
new file mode 100644
index 0000000..923c6ad
--- /dev/null
+++ b/src/libdoxygen.pro
@@ -0,0 +1,245 @@
+#
+# This file was generated from libdoxygen.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = libdoxygen.t
+CONFIG = console warn_on staticlib debug
+HEADERS = arguments.h \
+ bufstr.h \
+ cite.h \
+ clangparser.h \
+ classdef.h \
+ classlist.h \
+ cmdmapper.h \
+ code.h \
+ commentcnv.h \
+ commentscan.h \
+ condparser.h \
+ config.h \
+ context.h \
+ constexp.h \
+ cppvalue.h \
+ debug.h \
+ declinfo.h \
+ defargs.h \
+ defgen.h \
+ define.h \
+ definition.h \
+ diagram.h \
+ dirdef.h \
+ docparser.h \
+ docsets.h \
+ doctokenizer.h \
+ docvisitor.h \
+ dot.h \
+ doxygen.h \
+ eclipsehelp.h \
+ entry.h \
+ example.h \
+ filedef.h \
+ filename.h \
+ fileparser.h \
+ formula.h \
+ ftextstream.h \
+ ftvhelp.h \
+ groupdef.h \
+ htags.h \
+ htmlattrib.h \
+ htmldocvisitor.h \
+ htmlgen.h \
+ htmlhelp.h \
+ htmlentity.h \
+ image.h \
+ index.h \
+ language.h \
+ latexdocvisitor.h \
+ latexgen.h \
+ layout.h \
+ logos.h \
+ mandocvisitor.h \
+ mangen.h \
+ sqlite3gen.h \
+ markdown.h \
+ marshal.h \
+ memberdef.h \
+ membergroup.h \
+ memberlist.h \
+ membername.h \
+ message.h \
+ msc.h \
+ dia.h \
+ namespacedef.h \
+ objcache.h \
+ outputgen.h \
+ outputlist.h \
+ pagedef.h \
+ perlmodgen.h \
+ lodepng.h \
+ plantuml.h \
+ pre.h \
+ printdocvisitor.h \
+ pycode.h \
+ pyscanner.h \
+ fortrancode.h \
+ fortranscanner.h \
+ dbusxmlscanner.h \
+ qhp.h \
+ qhpxmlwriter.h \
+ reflist.h \
+ rtfdocvisitor.h \
+ rtfgen.h \
+ rtfstyle.h \
+ scanner.h \
+ searchindex.h \
+ section.h \
+ sortdict.h \
+ store.h \
+ tagreader.h \
+ tclscanner.h \
+ template.h \
+ textdocvisitor.h \
+ tooltip.h \
+ translator.h \
+ translator_adapter.h \
+ util.h \
+ version.h \
+ vhdlcode.h \
+ vhdldocgen.h \
+ xmldocvisitor.h \
+ xmlgen.h \
+ docbookvisitor.h \
+ docbookgen.h \
+ vhdljjparser.h
+
+
+SOURCES = arguments.cpp \
+ cite.cpp \
+ clangparser.cpp \
+ classdef.cpp \
+ classlist.cpp \
+ cmdmapper.cpp \
+ condparser.cpp \
+ context.cpp \
+ cppvalue.cpp \
+ dbusxmlscanner.cpp \
+ debug.cpp \
+ defgen.cpp \
+ define.cpp \
+ definition.cpp \
+ diagram.cpp \
+ dirdef.cpp \
+ docparser.cpp \
+ docsets.cpp \
+ dot.cpp \
+ doxygen.cpp \
+ eclipsehelp.cpp \
+ entry.cpp \
+ filedef.cpp \
+ filename.cpp \
+ fileparser.cpp \
+ formula.cpp \
+ ftextstream.cpp \
+ ftvhelp.cpp \
+ groupdef.cpp \
+ htags.cpp \
+ htmldocvisitor.cpp \
+ htmlgen.cpp \
+ htmlhelp.cpp \
+ htmlentity.cpp \
+ image.cpp \
+ index.cpp \
+ language.cpp \
+ latexdocvisitor.cpp \
+ latexgen.cpp \
+ layout.cpp \
+ lodepng.cpp \
+ logos.cpp \
+ plantuml.cpp \
+ mandocvisitor.cpp \
+ mangen.cpp \
+ sqlite3gen.cpp \
+ markdown.cpp \
+ marshal.cpp \
+ memberdef.cpp \
+ membergroup.cpp \
+ memberlist.cpp \
+ membername.cpp \
+ message.cpp \
+ msc.cpp \
+ dia.cpp \
+ namespacedef.cpp \
+ objcache.cpp \
+ outputgen.cpp \
+ outputlist.cpp \
+ pagedef.cpp \
+ perlmodgen.cpp \
+ qhp.cpp \
+ qhpxmlwriter.cpp \
+ reflist.cpp \
+ rtfdocvisitor.cpp \
+ rtfgen.cpp \
+ rtfstyle.cpp \
+ searchindex.cpp \
+ store.cpp \
+ tagreader.cpp \
+ template.cpp \
+ textdocvisitor.cpp \
+ tooltip.cpp \
+ util.cpp \
+ vhdldocgen.cpp \
+ xmldocvisitor.cpp \
+ xmlgen.cpp \
+ docbookvisitor.cpp \
+ docbookgen.cpp \
+ vhdljjparser.cpp \
+ ../generated_src/doxygen/ce_parse.cpp \
+ ../generated_src/doxygen/constexp.cpp \
+ ../generated_src/doxygen/vhdlcode.cpp \
+ ../generated_src/doxygen/code.cpp \
+ ../generated_src/doxygen/commentcnv.cpp \
+ ../generated_src/doxygen/commentscan.cpp \
+ ../generated_src/doxygen/declinfo.cpp \
+ ../generated_src/doxygen/defargs.cpp \
+ ../generated_src/doxygen/doctokenizer.cpp \
+ ../generated_src/doxygen/pre.cpp \
+ ../generated_src/doxygen/pycode.cpp \
+ ../generated_src/doxygen/pyscanner.cpp \
+ ../generated_src/doxygen/scanner.cpp \
+ ../generated_src/doxygen/tclscanner.cpp \
+ ../generated_src/doxygen/fortrancode.cpp \
+ ../generated_src/doxygen/fortranscanner.cpp \
+ ../generated_src/doxygen/version.cpp
+
+
+
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-msvc:TMAKE_CXXFLAGS += -Zm200
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions
+linux-g++:TMAKE_CXXFLAGS += -fno-exceptions
+INCLUDEPATH += ../generated_src/doxygen ../src ../qtools ../libmd5 ../vhdlparser
+INCLUDEPATH +=
+DEPENDPATH += ../generated_src/doxygen
+win32:INCLUDEPATH += .
+DESTDIR = ../lib
+TARGET = doxygen
+OBJECTS_DIR = ../objects/doxygen
+
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
new file mode 100644
index 0000000..703b885
--- /dev/null
+++ b/src/libdoxygen.pro.in
@@ -0,0 +1,238 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+# TMake project file for doxygen
+
+TEMPLATE = libdoxygen.t
+CONFIG = console warn_on staticlib $extraopts
+HEADERS = arguments.h \
+ bufstr.h \
+ cite.h \
+ clangparser.h \
+ classdef.h \
+ classlist.h \
+ cmdmapper.h \
+ code.h \
+ commentcnv.h \
+ commentscan.h \
+ condparser.h \
+ config.h \
+ context.h \
+ constexp.h \
+ cppvalue.h \
+ debug.h \
+ declinfo.h \
+ defargs.h \
+ defgen.h \
+ define.h \
+ definition.h \
+ diagram.h \
+ dirdef.h \
+ docparser.h \
+ docsets.h \
+ doctokenizer.h \
+ docvisitor.h \
+ dot.h \
+ doxygen.h \
+ eclipsehelp.h \
+ entry.h \
+ example.h \
+ filedef.h \
+ filename.h \
+ fileparser.h \
+ formula.h \
+ ftextstream.h \
+ ftvhelp.h \
+ groupdef.h \
+ htags.h \
+ htmlattrib.h \
+ htmldocvisitor.h \
+ htmlgen.h \
+ htmlhelp.h \
+ htmlentity.h \
+ image.h \
+ index.h \
+ language.h \
+ latexdocvisitor.h \
+ latexgen.h \
+ layout.h \
+ logos.h \
+ mandocvisitor.h \
+ mangen.h \
+ sqlite3gen.h \
+ markdown.h \
+ marshal.h \
+ memberdef.h \
+ membergroup.h \
+ memberlist.h \
+ membername.h \
+ message.h \
+ msc.h \
+ dia.h \
+ namespacedef.h \
+ objcache.h \
+ outputgen.h \
+ outputlist.h \
+ pagedef.h \
+ perlmodgen.h \
+ lodepng.h \
+ plantuml.h \
+ pre.h \
+ printdocvisitor.h \
+ pycode.h \
+ pyscanner.h \
+ fortrancode.h \
+ fortranscanner.h \
+ dbusxmlscanner.h \
+ qhp.h \
+ qhpxmlwriter.h \
+ reflist.h \
+ rtfdocvisitor.h \
+ rtfgen.h \
+ rtfstyle.h \
+ scanner.h \
+ searchindex.h \
+ section.h \
+ sortdict.h \
+ store.h \
+ tagreader.h \
+ tclscanner.h \
+ template.h \
+ textdocvisitor.h \
+ tooltip.h \
+ translator.h \
+ translator_adapter.h \
+ util.h \
+ version.h \
+ vhdlcode.h \
+ vhdldocgen.h \
+ xmldocvisitor.h \
+ xmlgen.h \
+ docbookvisitor.h \
+ docbookgen.h \
+ vhdljjparser.h
+
+
+SOURCES = arguments.cpp \
+ cite.cpp \
+ clangparser.cpp \
+ classdef.cpp \
+ classlist.cpp \
+ cmdmapper.cpp \
+ condparser.cpp \
+ context.cpp \
+ cppvalue.cpp \
+ dbusxmlscanner.cpp \
+ debug.cpp \
+ defgen.cpp \
+ define.cpp \
+ definition.cpp \
+ diagram.cpp \
+ dirdef.cpp \
+ docparser.cpp \
+ docsets.cpp \
+ dot.cpp \
+ doxygen.cpp \
+ eclipsehelp.cpp \
+ entry.cpp \
+ filedef.cpp \
+ filename.cpp \
+ fileparser.cpp \
+ formula.cpp \
+ ftextstream.cpp \
+ ftvhelp.cpp \
+ groupdef.cpp \
+ htags.cpp \
+ htmldocvisitor.cpp \
+ htmlgen.cpp \
+ htmlhelp.cpp \
+ htmlentity.cpp \
+ image.cpp \
+ index.cpp \
+ language.cpp \
+ latexdocvisitor.cpp \
+ latexgen.cpp \
+ layout.cpp \
+ lodepng.cpp \
+ logos.cpp \
+ plantuml.cpp \
+ mandocvisitor.cpp \
+ mangen.cpp \
+ sqlite3gen.cpp \
+ markdown.cpp \
+ marshal.cpp \
+ memberdef.cpp \
+ membergroup.cpp \
+ memberlist.cpp \
+ membername.cpp \
+ message.cpp \
+ msc.cpp \
+ dia.cpp \
+ namespacedef.cpp \
+ objcache.cpp \
+ outputgen.cpp \
+ outputlist.cpp \
+ pagedef.cpp \
+ perlmodgen.cpp \
+ qhp.cpp \
+ qhpxmlwriter.cpp \
+ reflist.cpp \
+ rtfdocvisitor.cpp \
+ rtfgen.cpp \
+ rtfstyle.cpp \
+ searchindex.cpp \
+ store.cpp \
+ tagreader.cpp \
+ template.cpp \
+ textdocvisitor.cpp \
+ tooltip.cpp \
+ util.cpp \
+ vhdldocgen.cpp \
+ xmldocvisitor.cpp \
+ xmlgen.cpp \
+ docbookvisitor.cpp \
+ docbookgen.cpp \
+ vhdljjparser.cpp \
+ ../generated_src/doxygen/ce_parse.cpp \
+ ../generated_src/doxygen/constexp.cpp \
+ ../generated_src/doxygen/vhdlcode.cpp \
+ ../generated_src/doxygen/code.cpp \
+ ../generated_src/doxygen/commentcnv.cpp \
+ ../generated_src/doxygen/commentscan.cpp \
+ ../generated_src/doxygen/declinfo.cpp \
+ ../generated_src/doxygen/defargs.cpp \
+ ../generated_src/doxygen/doctokenizer.cpp \
+ ../generated_src/doxygen/pre.cpp \
+ ../generated_src/doxygen/pycode.cpp \
+ ../generated_src/doxygen/pyscanner.cpp \
+ ../generated_src/doxygen/scanner.cpp \
+ ../generated_src/doxygen/tclscanner.cpp \
+ ../generated_src/doxygen/fortrancode.cpp \
+ ../generated_src/doxygen/fortranscanner.cpp \
+ ../generated_src/doxygen/version.cpp
+
+
+
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+win32-msvc:TMAKE_CXXFLAGS += -Zm200
+win32-g++:TMAKE_CXXFLAGS += -fno-exceptions
+linux-g++:TMAKE_CXXFLAGS += -fno-exceptions
+INCLUDEPATH += ../generated_src/doxygen ../src ../qtools ../libmd5 ../vhdlparser
+INCLUDEPATH += %%SQLITE3_INC%%
+DEPENDPATH += ../generated_src/doxygen
+win32:INCLUDEPATH += .
+DESTDIR = ../lib
+TARGET = doxygen
+OBJECTS_DIR = ../objects/doxygen
+
diff --git a/src/libdoxygen.t b/src/libdoxygen.t
new file mode 100644
index 0000000..0f496bd
--- /dev/null
+++ b/src/libdoxygen.t
@@ -0,0 +1,208 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#!
+#! doxygen.t: This is a custom template for building Doxygen
+#!
+#$ IncludeTemplate("lib.t");
+
+LEX = /usr/bin/flex
+YACC = /opt/local/bin/bison
+PYTHON = /opt/local/bin/python2
+PERL = %%PERL%%
+INCBUFSIZE = $(PYTHON) increasebuffer.py
+GENERATED_SRC = ../generated_src/doxygen
+GENERATED_OBJ = ../objects/doxygen
+
+#${
+sub GenerateDep {
+ my($obj,$src, at deps) = @_;
+ my(@objv,$srcv,$i,$s,$o,$d,$c);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ next if $s eq "";
+ $text .= $o . ": " . $s;
+ foreach my $dep (@deps) {
+ $text .= " ${linebreak}\n\t\t" . $dep if $dep ne "";
+ }
+ if ( $moc_output{$s} ne "" ) {
+ $text .= " ${linebreak}\n\t\t" . $moc_output{$s};
+ }
+ $d = &make_depend($s);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ $text .= "\n";
+ }
+ chop $text;
+}
+sub GenerateLex {
+ my($name,$caseOpt) = @_;
+ $text = "\t\$(LEX) ";
+ if ($caseOpt) {
+ $text .= "-i ";
+ }
+ $text .= "-P".$name."YY -t ".$name.".l | \$(INCBUFSIZE) > \$(GENERATED_SRC)/".$name.".cpp";
+}
+#$}
+
+####################
+
+#$ GenerateDep("\$(GENERATED_SRC)/scanner.cpp","scanner.l");
+#$ GenerateLex("scanner",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/code.cpp","code.l");
+#$ GenerateLex("code",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pyscanner.cpp","pyscanner.l");
+#$ GenerateLex("pyscanner",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pycode.cpp","pycode.l");
+#$ GenerateLex("pycode",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/fortranscanner.cpp","fortranscanner.l");
+#$ GenerateLex("fortranscanner",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/fortrancode.cpp","fortrancode.l");
+#$ GenerateLex("fortrancode",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/vhdlcode.cpp","vhdlcode.l");
+#$ GenerateLex("vhdlcode",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/tclscanner.cpp","tclscanner.l");
+#$ GenerateLex("tclscanner",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pre.cpp","pre.l");
+#$ GenerateLex("pre",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/declinfo.cpp","declinfo.l");
+#$ GenerateLex("declinfo",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/defargs.cpp","defargs.l");
+#$ GenerateLex("defargs",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/doctokenizer.cpp","doctokenizer.l");
+#$ GenerateLex("doctokenizer",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/commentcnv.cpp","commentcnv.l");
+#$ GenerateLex("commentcnv",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/commentscan.cpp","commentscan.l");
+#$ GenerateLex("commentscan",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/constexp.cpp","constexp.l","\$(GENERATED_SRC)/ce_parse.h");
+#$ GenerateLex("constexp",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/ce_parse.cpp","constexp.y");
+ $(YACC) -l -p constexpYY constexp.y -o \$(GENERATED_SRC)/ce_parse.cpp
+
+#$ GenerateDep("\$(GENERATED_SRC)/ce_parse.h","constexp.y");
+ $(YACC) -l -d -p ce_parsexpYY constexp.y -o \$(GENERATED_SRC)/ce_parse.c
+ -rm $(GENERATED_SRC)/ce_parse.c
+
+
+
+TO_C_CMD=$(PYTHON) to_c_cmd.py < $< > $@
+
+#$ GenerateDep("layout.cpp","\$(GENERATED_SRC)/layout_default.xml.h");
+
+#$ GenerateDep("cite.cpp","\$(GENERATED_SRC)/doxygen.bst.h","\$(GENERATED_SRC)/bib2xhtml.pl.h");
+
+#$ GenerateDep("ftvhelp.cpp","\$(GENERATED_SRC)/navtree.js.h","\$(GENERATED_SRC)/resize.js.h","\$(GENERATED_SRC)/navtree.css.h");
+
+#$ GenerateDep("htmlgen.cpp","\$(GENERATED_SRC)/header.html.h","\$(GENERATED_SRC)/footer.html.h","\$(GENERATED_SRC)/doxygen.css.h","\$(GENERATED_SRC)/search_functions.php.h","\$(GENERATED_SRC)/search_opensearch.php.h","\$(GENERATED_SRC)/search.css.h","\$(GENERATED_SRC)/jquery_p1.js.h","\$(GENERATED_SRC)/jquery_p2.js.h","\$(GENERATED_SRC)/jquery_p3.js.h","\$(GENERATED_SRC)/jquery_ui.js.h","\$(GENERATED_SRC)/jquery_fx.js.h","\$(GENERATED_SRC)/jquery_pt.js.h","\$(GENERATED_SRC)/svgpan.js.h" [...]
+
+#$ GenerateDep("xmlgen.cpp","\$(GENERATED_SRC)/index.xsd.h","\$(GENERATED_SRC)/compound.xsd.h");
+
+#$ GenerateDep("latexgen.cpp","\$(GENERATED_SRC)/doxygen.sty.h");
+
+#$ GenerateDep("searchindex.cpp","\$(GENERATED_SRC)/search.js.h");
+
+$(GENERATED_SRC)/index.xsd.h: index.xsd
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/compound.xsd.h: compound.xsd
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/layout_default.xml.h: layout_default.xml
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/header.html.h: header.html
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/footer.html.h: footer.html
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search_functions.php.h: search_functions.php
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search_opensearch.php.h: search_opensearch.php
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search.js.h: search.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search.css.h: search.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/extsearch.js.h: extsearch.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.css.h: doxygen.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.sty.h: doxygen.sty
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/navtree.js.h: navtree.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/resize.js.h: resize.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p1.js.h: jquery_p1.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p2.js.h: jquery_p2.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p3.js.h: jquery_p3.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_ui.js.h: jquery_ui.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_fx.js.h: jquery_fx.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_pt.js.h: jquery_pt.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/navtree.css.h: navtree.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/svgpan.js.h: svgpan.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/dynsections.js.h: dynsections.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.bst.h: doxygen.bst
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/bib2xhtml.pl.h: bib2xhtml.pl
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/version.cpp: ../configure
+ $(PYTHON) version.py $(GENERATED_SRC)
diff --git a/src/libdoxygen.t.in b/src/libdoxygen.t.in
new file mode 100644
index 0000000..314e94c
--- /dev/null
+++ b/src/libdoxygen.t.in
@@ -0,0 +1,208 @@
+#
+#
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#!
+#! doxygen.t: This is a custom template for building Doxygen
+#!
+#$ IncludeTemplate("lib.t");
+
+LEX = %%FLEX%%
+YACC = %%BISON%%
+PYTHON = %%PYTHON%%
+PERL = %%PERL%%
+INCBUFSIZE = $(PYTHON) increasebuffer.py
+GENERATED_SRC = ../generated_src/doxygen
+GENERATED_OBJ = ../objects/doxygen
+
+#${
+sub GenerateDep {
+ my($obj,$src, at deps) = @_;
+ my(@objv,$srcv,$i,$s,$o,$d,$c);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ next if $s eq "";
+ $text .= $o . ": " . $s;
+ foreach my $dep (@deps) {
+ $text .= " ${linebreak}\n\t\t" . $dep if $dep ne "";
+ }
+ if ( $moc_output{$s} ne "" ) {
+ $text .= " ${linebreak}\n\t\t" . $moc_output{$s};
+ }
+ $d = &make_depend($s);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ $text .= "\n";
+ }
+ chop $text;
+}
+sub GenerateLex {
+ my($name,$caseOpt) = @_;
+ $text = "\t\$(LEX) ";
+ if ($caseOpt) {
+ $text .= "-i ";
+ }
+ $text .= "-P".$name."YY -t ".$name.".l | \$(INCBUFSIZE) > \$(GENERATED_SRC)/".$name.".cpp";
+}
+#$}
+
+####################
+
+#$ GenerateDep("\$(GENERATED_SRC)/scanner.cpp","scanner.l");
+#$ GenerateLex("scanner",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/code.cpp","code.l");
+#$ GenerateLex("code",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pyscanner.cpp","pyscanner.l");
+#$ GenerateLex("pyscanner",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pycode.cpp","pycode.l");
+#$ GenerateLex("pycode",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/fortranscanner.cpp","fortranscanner.l");
+#$ GenerateLex("fortranscanner",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/fortrancode.cpp","fortrancode.l");
+#$ GenerateLex("fortrancode",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/vhdlcode.cpp","vhdlcode.l");
+#$ GenerateLex("vhdlcode",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/tclscanner.cpp","tclscanner.l");
+#$ GenerateLex("tclscanner",1);
+
+#$ GenerateDep("\$(GENERATED_SRC)/pre.cpp","pre.l");
+#$ GenerateLex("pre",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/declinfo.cpp","declinfo.l");
+#$ GenerateLex("declinfo",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/defargs.cpp","defargs.l");
+#$ GenerateLex("defargs",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/doctokenizer.cpp","doctokenizer.l");
+#$ GenerateLex("doctokenizer",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/commentcnv.cpp","commentcnv.l");
+#$ GenerateLex("commentcnv",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/commentscan.cpp","commentscan.l");
+#$ GenerateLex("commentscan",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/constexp.cpp","constexp.l","\$(GENERATED_SRC)/ce_parse.h");
+#$ GenerateLex("constexp",0);
+
+#$ GenerateDep("\$(GENERATED_SRC)/ce_parse.cpp","constexp.y");
+ $(YACC) -l -p constexpYY constexp.y -o \$(GENERATED_SRC)/ce_parse.cpp
+
+#$ GenerateDep("\$(GENERATED_SRC)/ce_parse.h","constexp.y");
+ $(YACC) -l -d -p ce_parsexpYY constexp.y -o \$(GENERATED_SRC)/ce_parse.c
+ -rm $(GENERATED_SRC)/ce_parse.c
+
+
+
+TO_C_CMD=$(PYTHON) to_c_cmd.py < $< > $@
+
+#$ GenerateDep("layout.cpp","\$(GENERATED_SRC)/layout_default.xml.h");
+
+#$ GenerateDep("cite.cpp","\$(GENERATED_SRC)/doxygen.bst.h","\$(GENERATED_SRC)/bib2xhtml.pl.h");
+
+#$ GenerateDep("ftvhelp.cpp","\$(GENERATED_SRC)/navtree.js.h","\$(GENERATED_SRC)/resize.js.h","\$(GENERATED_SRC)/navtree.css.h");
+
+#$ GenerateDep("htmlgen.cpp","\$(GENERATED_SRC)/header.html.h","\$(GENERATED_SRC)/footer.html.h","\$(GENERATED_SRC)/doxygen.css.h","\$(GENERATED_SRC)/search_functions.php.h","\$(GENERATED_SRC)/search_opensearch.php.h","\$(GENERATED_SRC)/search.css.h","\$(GENERATED_SRC)/jquery_p1.js.h","\$(GENERATED_SRC)/jquery_p2.js.h","\$(GENERATED_SRC)/jquery_p3.js.h","\$(GENERATED_SRC)/jquery_ui.js.h","\$(GENERATED_SRC)/jquery_fx.js.h","\$(GENERATED_SRC)/jquery_pt.js.h","\$(GENERATED_SRC)/svgpan.js.h" [...]
+
+#$ GenerateDep("xmlgen.cpp","\$(GENERATED_SRC)/index.xsd.h","\$(GENERATED_SRC)/compound.xsd.h");
+
+#$ GenerateDep("latexgen.cpp","\$(GENERATED_SRC)/doxygen.sty.h");
+
+#$ GenerateDep("searchindex.cpp","\$(GENERATED_SRC)/search.js.h");
+
+$(GENERATED_SRC)/index.xsd.h: index.xsd
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/compound.xsd.h: compound.xsd
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/layout_default.xml.h: layout_default.xml
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/header.html.h: header.html
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/footer.html.h: footer.html
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search_functions.php.h: search_functions.php
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search_opensearch.php.h: search_opensearch.php
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search.js.h: search.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/search.css.h: search.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/extsearch.js.h: extsearch.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.css.h: doxygen.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.sty.h: doxygen.sty
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/navtree.js.h: navtree.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/resize.js.h: resize.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p1.js.h: jquery_p1.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p2.js.h: jquery_p2.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_p3.js.h: jquery_p3.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_ui.js.h: jquery_ui.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_fx.js.h: jquery_fx.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/jquery_pt.js.h: jquery_pt.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/navtree.css.h: navtree.css
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/svgpan.js.h: svgpan.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/dynsections.js.h: dynsections.js
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/doxygen.bst.h: doxygen.bst
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/bib2xhtml.pl.h: bib2xhtml.pl
+ $(TO_C_CMD)
+
+$(GENERATED_SRC)/version.cpp: ../configure
+ $(PYTHON) version.py $(GENERATED_SRC)
diff --git a/src/lodepng.cpp b/src/lodepng.cpp
new file mode 100644
index 0000000..b237d5a
--- /dev/null
+++ b/src/lodepng.cpp
@@ -0,0 +1,4158 @@
+/*
+LodePNG version 20080927
+
+Copyright (c) 2005-2008 Lode Vandevenne
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+*/
+
+/*
+The manual and changelog can be found in the header file "lodepng.h"
+You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
+*/
+
+#include "lodepng.h"
+#include "portable.h"
+
+#define USE_BRUTE_FORCE_ENCODING 1
+
+#define VERSION_STRING "20080927"
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Tools For C / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*
+About these tools (vector, uivector, ucvector and string):
+-LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version.
+-The string tools are made to avoid problems with compilers that declare things like strncat as deprecated.
+-They're not used in the interface, only internally in this file, so all their functions are made static.
+*/
+
+#ifdef LODEPNG_COMPILE_ZLIB
+#ifdef LODEPNG_COMPILE_ENCODER
+
+typedef struct vector /*this one is used only by the deflate compressor*/
+{
+ void* data;
+ size_t size; /*in groups of bytes depending on type*/
+ size_t allocsize; /*in bytes*/
+ unsigned typesize; /*sizeof the type you store in data*/
+} vector;
+
+static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ if(size * p->typesize > p->allocsize)
+ {
+ size_t newsize = size * p->typesize * 2;
+ void* data = realloc(p->data, newsize);
+ if(data)
+ {
+ p->allocsize = newsize;
+ p->data = data;
+ p->size = size;
+ }
+ else return 0;
+ }
+ else p->size = size;
+ return 1;
+}
+
+static unsigned vector_resized(vector* p, size_t size, void dtor(void*)) /*resize and use destructor on elements if it gets smaller*/
+{
+ size_t i;
+ if(size < p->size) for(i = size; i < p->size; i++) dtor(&((char*)(p->data))[i * p->typesize]);
+ return vector_resize(p, size);
+}
+
+static void vector_cleanup(void* p)
+{
+ ((vector*)p)->size = ((vector*)p)->allocsize = 0;
+ free(((vector*)p)->data);
+ ((vector*)p)->data = NULL;
+}
+
+static void vector_cleanupd(vector* p, void dtor(void*)) /*clear and use destructor on elements*/
+{
+ vector_resized(p, 0, dtor);
+ vector_cleanup(p);
+}
+
+static void vector_init(vector* p, unsigned typesize)
+{
+ p->data = NULL;
+ p->size = p->allocsize = 0;
+ p->typesize = typesize;
+}
+
+static void vector_swap(vector* p, vector* q) /*they're supposed to have the same typesize*/
+{
+ size_t tmp;
+ void* tmpp;
+ tmp = p->size; p->size = q->size; q->size = tmp;
+ tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
+ tmpp = p->data; p->data = q->data; q->data = tmpp;
+}
+
+static void* vector_get(vector* p, size_t index)
+{
+ return &((char*)p->data)[index * p->typesize];
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+#endif /*LODEPNG_COMPILE_ZLIB*/
+
+/* /////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_ZLIB
+typedef struct uivector
+{
+ unsigned* data;
+ size_t size; /*size in number of unsigned longs*/
+ size_t allocsize; /*allocated size in bytes*/
+} uivector;
+
+static void uivector_cleanup(void* p)
+{
+ ((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
+ free(((uivector*)p)->data);
+ ((uivector*)p)->data = NULL;
+}
+
+static unsigned uivector_resize(uivector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ if(size * sizeof(unsigned) > p->allocsize)
+ {
+ size_t newsize = size * sizeof(unsigned) * 2;
+ void* data = realloc(p->data, newsize);
+ if(data)
+ {
+ p->allocsize = newsize;
+ p->data = (unsigned*)data;
+ p->size = size;
+ }
+ else return 0;
+ }
+ else p->size = size;
+ return 1;
+}
+
+static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) /*resize and give all new elements the value*/
+{
+ size_t oldsize = p->size, i;
+ if(!uivector_resize(p, size)) return 0;
+ for(i = oldsize; i < size; i++) p->data[i] = value;
+ return 1;
+}
+
+static void uivector_init(uivector* p)
+{
+ p->data = NULL;
+ p->size = p->allocsize = 0;
+}
+
+#ifdef LODEPNG_COMPILE_ENCODER
+static unsigned uivector_push_back(uivector* p, unsigned c) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ if(!uivector_resize(p, p->size + 1)) return 0;
+ p->data[p->size - 1] = c;
+ return 1;
+}
+
+static unsigned uivector_copy(uivector* p, const uivector* q) /*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/
+{
+ size_t i;
+ if(!uivector_resize(p, q->size)) return 0;
+ for(i = 0; i < q->size; i++) p->data[i] = q->data[i];
+ return 1;
+}
+
+static void uivector_swap(uivector* p, uivector* q)
+{
+ size_t tmp;
+ unsigned* tmpp;
+ tmp = p->size; p->size = q->size; q->size = tmp;
+ tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
+ tmpp = p->data; p->data = q->data; q->data = tmpp;
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+#endif /*LODEPNG_COMPILE_ZLIB*/
+
+/* /////////////////////////////////////////////////////////////////////////// */
+
+typedef struct ucvector
+{
+ unsigned char* data;
+ size_t size; /*used size*/
+ size_t allocsize; /*allocated size*/
+} ucvector;
+
+static void ucvector_cleanup(void* p)
+{
+ ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
+ free(((ucvector*)p)->data);
+ ((ucvector*)p)->data = NULL;
+}
+
+static unsigned ucvector_resize(ucvector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ if(size * sizeof(unsigned) > p->allocsize)
+ {
+ size_t newsize = size * sizeof(unsigned) * 2;
+ void* data = realloc(p->data, newsize);
+ if(data)
+ {
+ p->allocsize = newsize;
+ p->data = (unsigned char*)data;
+ p->size = size;
+ }
+ else return 0; /*error: not enough memory*/
+ }
+ else p->size = size;
+ return 1;
+}
+
+#ifdef LODEPNG_COMPILE_DECODER
+#ifdef LODEPNG_COMPILE_PNG
+static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) /*resize and give all new elements the value*/
+{
+ size_t oldsize = p->size, i;
+ if(!ucvector_resize(p, size)) return 0;
+ for(i = oldsize; i < size; i++) p->data[i] = value;
+ return 1;
+}
+#endif /*LODEPNG_COMPILE_PNG*/
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+static void ucvector_init(ucvector* p)
+{
+ p->data = NULL;
+ p->size = p->allocsize = 0;
+}
+
+#ifdef LODEPNG_COMPILE_ZLIB
+/*you can both convert from vector to buffer&size and vica versa*/
+static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size)
+{
+ p->data = buffer;
+ p->allocsize = p->size = size;
+}
+#endif /*LODEPNG_COMPILE_ZLIB*/
+
+static unsigned ucvector_push_back(ucvector* p, unsigned char c) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ if(!ucvector_resize(p, p->size + 1)) return 0;
+ p->data[p->size - 1] = c;
+ return 1;
+}
+
+/* /////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_PNG
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+static unsigned string_resize(char** out, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
+{
+ char* data = (char*)realloc(*out, size + 1);
+ if(data)
+ {
+ data[size] = 0; /*null termination char*/
+ *out = data;
+ }
+ return data != 0;
+}
+
+static void string_init(char** out) /*init a {char*, size_t} pair for use as string*/
+{
+ *out = NULL;
+ string_resize(out, 0);
+}
+
+static void string_cleanup(char** out) /*free the above pair again*/
+{
+ free(*out);
+ *out = NULL;
+}
+
+static void string_set(char** out, const char* in)
+{
+ size_t insize = strlen(in), i = 0;
+ if(string_resize(out, insize)) for(i = 0; i < insize; i++) (*out)[i] = in[i];
+}
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+#endif /*LODEPNG_COMPILE_PNG*/
+
+#ifdef LODEPNG_COMPILE_ZLIB
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Reading and writing single bits and bytes from/to stream for Deflate / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_ENCODER
+static void addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit)
+{
+ if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, 0); /*add a new byte at the end*/
+ (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
+ (*bitpointer)++;
+}
+
+static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
+{
+ size_t i;
+ for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1));
+}
+
+static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
+{
+ size_t i;
+ for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1));
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+#ifdef LODEPNG_COMPILE_DECODER
+static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream)
+{
+ unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> ((*bitpointer) & 0x7)) & 1);
+ (*bitpointer)++;
+ return result;
+}
+
+static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
+{
+ unsigned result = 0, i;
+ for(i = 0; i < nbits; i++) result += ((unsigned)readBitFromStream(bitpointer, bitstream)) << i;
+ return result;
+}
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Deflate - Huffman / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#define FIRST_LENGTH_CODE_INDEX 257
+#define LAST_LENGTH_CODE_INDEX 285
+#define NUM_DEFLATE_CODE_SYMBOLS 288 /*256 literals, the end code, some length codes, and 2 unused codes*/
+#define NUM_DISTANCE_SYMBOLS 32 /*the distance codes have their own symbols, 30 used, 2 unused*/
+#define NUM_CODE_LENGTH_CODES 19 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/
+
+static const unsigned LENGTHBASE[29] /*the base lengths represented by codes 257-285*/
+ = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
+static const unsigned LENGTHEXTRA[29] /*the extra bits used by codes 257-285 (added to base length)*/
+ = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+static const unsigned DISTANCEBASE[30] /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/
+ = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
+static const unsigned DISTANCEEXTRA[30] /*the extra bits of backwards distances (added to base)*/
+ = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+static const unsigned CLCL[NUM_CODE_LENGTH_CODES] /*the order in which "code length alphabet code lengths" are stored, out of this the huffman tree of the dynamic huffman tree lengths is generated*/
+ = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/* /////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_ENCODER
+/*terminology used for the package-merge algorithm and the coin collector's problem*/
+typedef struct Coin /*a coin can be multiple coins (when they're merged)*/
+{
+ uivector symbols;
+ float weight; /*the sum of all weights in this coin*/
+} Coin;
+
+static void Coin_init(Coin* c)
+{
+ uivector_init(&c->symbols);
+}
+
+static void Coin_cleanup(void* c) /*void* so that this dtor can be given as function pointer to the vector resize function*/
+{
+ uivector_cleanup(&((Coin*)c)->symbols);
+}
+
+static void Coin_copy(Coin* c1, const Coin* c2)
+{
+ c1->weight = c2->weight;
+ uivector_copy(&c1->symbols, &c2->symbols);
+}
+
+static void addCoins(Coin* c1, const Coin* c2)
+{
+ unsigned i;
+ for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]);
+ c1->weight += c2->weight;
+}
+
+static void Coin_sort(Coin* data, size_t amount) /*combsort*/
+{
+ size_t gap = amount;
+ unsigned char swapped = 0;
+ while(gap > 1 || swapped)
+ {
+ size_t i;
+ gap = (gap * 10) / 13; /*shrink factor 1.3*/
+ if(gap == 9 || gap == 10) gap = 11; /*combsort11*/
+ if(gap < 1) gap = 1;
+ swapped = 0;
+ for(i = 0; i < amount - gap; i++)
+ {
+ size_t j = i + gap;
+ if(data[j].weight < data[i].weight)
+ {
+ float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp;
+ uivector_swap(&data[i].symbols, &data[j].symbols);
+ swapped = 1;
+ }
+ }
+ }
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+typedef struct HuffmanTree
+{
+ uivector tree2d;
+ uivector tree1d;
+ uivector lengths; /*the lengths of the codes of the 1d-tree*/
+ unsigned maxbitlen; /*maximum number of bits a single code can get*/
+ unsigned numcodes; /*number of symbols in the alphabet = number of codes*/
+} HuffmanTree;
+
+/*function used for debug purposes*/
+/*#include <iostream>
+static void HuffmanTree_draw(HuffmanTree* tree)
+{
+ std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl;
+ for(size_t i = 0; i < tree->tree1d.size; i++)
+ {
+ if(tree->lengths.data[i])
+ std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl;
+ }
+ std::cout << std::endl;
+}*/
+
+static void HuffmanTree_init(HuffmanTree* tree)
+{
+ uivector_init(&tree->tree2d);
+ uivector_init(&tree->tree1d);
+ uivector_init(&tree->lengths);
+}
+
+static void HuffmanTree_cleanup(HuffmanTree* tree)
+{
+ uivector_cleanup(&tree->tree2d);
+ uivector_cleanup(&tree->tree1d);
+ uivector_cleanup(&tree->lengths);
+}
+
+/*the tree representation used by the decoder. return value is error*/
+static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
+{
+ unsigned nodefilled = 0; /*up to which node it is filled*/
+ unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/
+ unsigned n, i;
+
+ if(!uivector_resize(&tree->tree2d, tree->numcodes * 2)) return 9901; /*if failed return not enough memory error*/
+ /*convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1
+ a good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen*/
+ for(n = 0; n < tree->numcodes * 2; n++) tree->tree2d.data[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/
+
+ for(n = 0; n < tree->numcodes; n++) /*the codes*/
+ for(i = 0; i < tree->lengths.data[n]; i++) /*the bits for this code*/
+ {
+ unsigned char bit = (unsigned char)((tree->tree1d.data[n] >> (tree->lengths.data[n] - i - 1)) & 1);
+ if(treepos > tree->numcodes - 2) return 55; /*error 55: oversubscribed; see description in header*/
+ if(tree->tree2d.data[2 * treepos + bit] == 32767) /*not yet filled in*/
+ {
+ if(i + 1 == tree->lengths.data[n]) /*last bit*/
+ {
+ tree->tree2d.data[2 * treepos + bit] = n; /*put the current code in it*/
+ treepos = 0;
+ }
+ else /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/
+ {
+ nodefilled++;
+ tree->tree2d.data[2 * treepos + bit] = nodefilled + tree->numcodes; /*addresses encoded with numcodes added to it*/
+ treepos = nodefilled;
+ }
+ }
+ else treepos = tree->tree2d.data[2 * treepos + bit] - tree->numcodes;
+ }
+ for(n = 0; n < tree->numcodes * 2; n++) if(tree->tree2d.data[n] == 32767) tree->tree2d.data[n] = 0; /*remove possible remaining 32767's*/
+
+ return 0;
+}
+
+static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) /*given that numcodes, lengths and maxbitlen are already filled in correctly. return value is error.*/
+{
+ uivector blcount;
+ uivector nextcode;
+ unsigned bits, n, error = 0;
+
+ uivector_init(&blcount);
+ uivector_init(&nextcode);
+ if(!uivector_resize(&tree->tree1d, tree->numcodes)
+ || !uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
+ || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
+ error = 9902;
+
+ if(!error)
+ {
+ /*step 1: count number of instances of each code length*/
+ for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths.data[bits]]++;
+ /*step 2: generate the nextcode values*/
+ for(bits = 1; bits <= tree->maxbitlen; bits++) nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
+ /*step 3: generate all the codes*/
+ for(n = 0; n < tree->numcodes; n++) if(tree->lengths.data[n] != 0) tree->tree1d.data[n] = nextcode.data[tree->lengths.data[n]]++;
+ }
+
+ uivector_cleanup(&blcount);
+ uivector_cleanup(&nextcode);
+
+ if(!error) return HuffmanTree_make2DTree(tree);
+ else return error;
+}
+
+/*given the code lengths (as stored in the PNG file), generate the tree as defined by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error.*/
+static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen)
+{
+ unsigned i;
+ if(!uivector_resize(&tree->lengths, numcodes)) return 9903;
+ for(i = 0; i < numcodes; i++) tree->lengths.data[i] = bitlen[i];
+ tree->numcodes = (unsigned)numcodes; /*number of symbols*/
+ tree->maxbitlen = maxbitlen;
+ return HuffmanTree_makeFromLengths2(tree);
+}
+
+#ifdef LODEPNG_COMPILE_ENCODER
+static unsigned HuffmanTree_fillInCoins(vector* coins, const unsigned* frequencies, unsigned numcodes, size_t sum)
+{
+ unsigned i;
+ for(i = 0; i < numcodes; i++)
+ {
+ Coin* coin;
+ if(frequencies[i] == 0) continue; /*it's important to exclude symbols that aren't present*/
+ if(!vector_resize(coins, coins->size + 1)) { vector_cleanup(coins); return 9904; }
+ coin = (Coin*)(vector_get(coins, coins->size - 1));
+ Coin_init(coin);
+ coin->weight = frequencies[i] / (float)sum;
+ uivector_push_back(&coin->symbols, i);
+ }
+ if(coins->size) Coin_sort((Coin*)coins->data, coins->size);
+ return 0;
+}
+
+static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen)
+{
+ unsigned i, j;
+ size_t sum = 0, numpresent = 0;
+ unsigned error = 0;
+
+ vector prev_row; /*type Coin, the previous row of coins*/
+ vector coins; /*type Coin, the coins of the currently calculated row*/
+
+ tree->maxbitlen = maxbitlen;
+
+ for(i = 0; i < numcodes; i++)
+ {
+ if(frequencies[i] > 0)
+ {
+ numpresent++;
+ sum += frequencies[i];
+ }
+ }
+
+ if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
+ tree->numcodes = (unsigned)numcodes; /*number of symbols*/
+ uivector_resize(&tree->lengths, 0);
+ if(!uivector_resizev(&tree->lengths, tree->numcodes, 0)) return 9905;
+
+ if(numpresent == 0) /*there are no symbols at all, in that case add one symbol of value 0 to the tree (see RFC 1951 section 3.2.7) */
+ {
+ tree->lengths.data[0] = 1;
+ return HuffmanTree_makeFromLengths2(tree);
+ }
+ else if(numpresent == 1) /*the package merge algorithm gives wrong results if there's only one symbol (theoretically 0 bits would then suffice, but we need a proper symbol for zlib)*/
+ {
+ for(i = 0; i < numcodes; i++) if(frequencies[i]) tree->lengths.data[i] = 1;
+ return HuffmanTree_makeFromLengths2(tree);
+ }
+
+ vector_init(&coins, sizeof(Coin));
+ vector_init(&prev_row, sizeof(Coin));
+
+ /*Package-Merge algorithm represented by coin collector's problem
+ For every symbol, maxbitlen coins will be created*/
+
+ /*first row, lowest denominator*/
+ error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
+ if(!error)
+ {
+ for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/
+ {
+ vector_swap(&coins, &prev_row); /*swap instead of copying*/
+ if(!vector_resized(&coins, 0, Coin_cleanup)) { error = 9906; break; }
+
+ for(i = 0; i + 1 < prev_row.size; i += 2)
+ {
+ if(!vector_resize(&coins, coins.size + 1)) { error = 9907; break; }
+ Coin_init((Coin*)vector_get(&coins, coins.size - 1));
+ Coin_copy((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i));
+ addCoins((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i + 1)); /*merge the coins into packages*/
+ }
+ if(j < maxbitlen)
+ {
+ error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
+ }
+ }
+ }
+
+ if(!error)
+ {
+ /*keep the coins with lowest weight, so that they add up to the amount of symbols - 1*/
+ vector_resized(&coins, numpresent - 1, Coin_cleanup);
+
+ /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/
+ for(i = 0; i < coins.size; i++)
+ {
+ Coin* coin = (Coin*)vector_get(&coins, i);
+ for(j = 0; j < coin->symbols.size; j++) tree->lengths.data[coin->symbols.data[j]]++;
+ }
+
+ error = HuffmanTree_makeFromLengths2(tree);
+ }
+
+ vector_cleanupd(&coins, Coin_cleanup);
+ vector_cleanupd(&prev_row, Coin_cleanup);
+
+ return error;
+}
+
+static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { return tree->tree1d.data[index]; }
+static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { return tree->lengths.data[index]; }
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/
+static unsigned generateFixedTree(HuffmanTree* tree)
+{
+ unsigned i, error = 0;
+ uivector bitlen;
+ uivector_init(&bitlen);
+ if(!uivector_resize(&bitlen, NUM_DEFLATE_CODE_SYMBOLS)) error = 9909;
+
+ if(!error)
+ {
+ /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/
+ for(i = 0; i <= 143; i++) bitlen.data[i] = 8;
+ for(i = 144; i <= 255; i++) bitlen.data[i] = 9;
+ for(i = 256; i <= 279; i++) bitlen.data[i] = 7;
+ for(i = 280; i <= 287; i++) bitlen.data[i] = 8;
+
+ error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DEFLATE_CODE_SYMBOLS, 15);
+ }
+
+ uivector_cleanup(&bitlen);
+ return error;
+}
+
+static unsigned generateDistanceTree(HuffmanTree* tree)
+{
+ unsigned i, error = 0;
+ uivector bitlen;
+ uivector_init(&bitlen);
+ if(!uivector_resize(&bitlen, NUM_DISTANCE_SYMBOLS)) error = 9910;
+
+ /*there are 32 distance codes, but 30-31 are unused*/
+ if(!error)
+ {
+ for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen.data[i] = 5;
+ error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DISTANCE_SYMBOLS, 15);
+ }
+ uivector_cleanup(&bitlen);
+ return error;
+}
+
+#ifdef LODEPNG_COMPILE_DECODER
+/*Decodes a symbol from the tree
+if decoded is true, then result contains the symbol, otherwise it contains something unspecified (because the symbol isn't fully decoded yet)
+bit is the bit that was just read from the stream
+you have to decode a full symbol (let the decode function return true) before you can try to decode another one, otherwise the state isn't reset
+return value is error.*/
+static unsigned HuffmanTree_decode(const HuffmanTree* tree, unsigned* decoded, unsigned* result, unsigned* treepos, unsigned char bit)
+{
+ if((*treepos) >= tree->numcodes) return 11; /*error: it appeared outside the codetree*/
+
+ (*result) = tree->tree2d.data[2 * (*treepos) + bit];
+ (*decoded) = ((*result) < tree->numcodes);
+
+ if(*decoded) (*treepos) = 0;
+ else (*treepos) = (*result) - tree->numcodes;
+
+ return 0;
+}
+
+static unsigned huffmanDecodeSymbol(unsigned int* error, const unsigned char* in, size_t* bp, const HuffmanTree* codetree, size_t inlength)
+{
+ unsigned treepos = 0, decoded, ct;
+ for(;;)
+ {
+ unsigned char bit;
+ if(((*bp) & 0x07) == 0 && ((*bp) >> 3) > inlength) { *error = 10; return 0; } /*error: end of input memory reached without endcode*/
+ bit = readBitFromStream(bp, in);
+ *error = HuffmanTree_decode(codetree, &decoded, &ct, &treepos, bit);
+ if(*error) return 0; /*stop, an error happened*/
+ if(decoded) return ct;
+ }
+}
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_DECODER
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Inflator / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/
+static void getTreeInflateFixed(HuffmanTree* tree, HuffmanTree* treeD)
+{
+ /*error checking not done, this is fixed stuff, it works, it doesn't depend on the image*/
+ generateFixedTree(tree);
+ generateDistanceTree(treeD);
+}
+
+/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/
+static unsigned getTreeInflateDynamic(HuffmanTree* codetree, HuffmanTree* codetreeD, HuffmanTree* codelengthcodetree,
+ const unsigned char* in, size_t* bp, size_t inlength)
+{
+ /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/
+ /*C-code note: use no "return" between ctor and dtor of an uivector!*/
+ unsigned error = 0;
+ unsigned n, HLIT, HDIST, HCLEN, i;
+ uivector bitlen;
+ uivector bitlenD;
+ uivector codelengthcode;
+
+ if((*bp) >> 3 >= inlength - 2) { return 49; } /*the bit pointer is or will go past the memory*/
+
+ HLIT = readBitsFromStream(bp, in, 5) + 257; /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/
+ HDIST = readBitsFromStream(bp, in, 5) + 1; /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/
+ HCLEN = readBitsFromStream(bp, in, 4) + 4; /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/
+
+ /*read the code length codes out of 3 * (amount of code length codes) bits*/
+ uivector_init(&codelengthcode);
+ if(!uivector_resize(&codelengthcode, NUM_CODE_LENGTH_CODES)) error = 9911;
+
+ if(!error)
+ {
+ for(i = 0; i < NUM_CODE_LENGTH_CODES; i++)
+ {
+ if(i < HCLEN) codelengthcode.data[CLCL[i]] = readBitsFromStream(bp, in, 3);
+ else codelengthcode.data[CLCL[i]] = 0; /*if not, it must stay 0*/
+ }
+
+ error = HuffmanTree_makeFromLengths(codelengthcodetree, codelengthcode.data, codelengthcode.size, 7);
+ }
+
+ uivector_cleanup(&codelengthcode);
+ if(error) return error;
+
+ /*now we can use this tree to read the lengths for the tree that this function will return*/
+ uivector_init(&bitlen);
+ uivector_resizev(&bitlen, NUM_DEFLATE_CODE_SYMBOLS, 0);
+ uivector_init(&bitlenD);
+ uivector_resizev(&bitlenD, NUM_DISTANCE_SYMBOLS, 0);
+ i = 0;
+ if(!bitlen.data || !bitlenD.data) error = 9912;
+ else while(i < HLIT + HDIST) /*i is the current symbol we're reading in the part that contains the code lengths of lit/len codes and dist codes*/
+ {
+ unsigned code = huffmanDecodeSymbol(&error, in, bp, codelengthcodetree, inlength);
+ if(error) break;
+
+ if(code <= 15) /*a length code*/
+ {
+ if(i < HLIT) bitlen.data[i] = code;
+ else bitlenD.data[i - HLIT] = code;
+ i++;
+ }
+ else if(code == 16) /*repeat previous*/
+ {
+ unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/
+ unsigned value; /*set value to the previous code*/
+
+ if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
+
+ replength += readBitsFromStream(bp, in, 2);
+
+ if((i - 1) < HLIT) value = bitlen.data[i - 1];
+ else value = bitlenD.data[i - HLIT - 1];
+ /*repeat this value in the next lengths*/
+ for(n = 0; n < replength; n++)
+ {
+ if(i >= HLIT + HDIST) { error = 13; break; } /*error: i is larger than the amount of codes*/
+ if(i < HLIT) bitlen.data[i] = value;
+ else bitlenD.data[i - HLIT] = value;
+ i++;
+ }
+ }
+ else if(code == 17) /*repeat "0" 3-10 times*/
+ {
+ unsigned replength = 3; /*read in the bits that indicate repeat length*/
+ if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
+
+ replength += readBitsFromStream(bp, in, 3);
+
+ /*repeat this value in the next lengths*/
+ for(n = 0; n < replength; n++)
+ {
+ if(i >= HLIT + HDIST) { error = 14; break; } /*error: i is larger than the amount of codes*/
+ if(i < HLIT) bitlen.data[i] = 0;
+ else bitlenD.data[i - HLIT] = 0;
+ i++;
+ }
+ }
+ else if(code == 18) /*repeat "0" 11-138 times*/
+ {
+ unsigned replength = 11; /*read in the bits that indicate repeat length*/
+ if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
+ replength += readBitsFromStream(bp, in, 7);
+
+ /*repeat this value in the next lengths*/
+ for(n = 0; n < replength; n++)
+ {
+ if(i >= HLIT + HDIST) { error = 15; break; } /*error: i is larger than the amount of codes*/
+ if(i < HLIT) bitlen.data[i] = 0;
+ else bitlenD.data[i - HLIT] = 0;
+ i++;
+ }
+ }
+ else { error = 16; break; } /*error: somehow an unexisting code appeared. This can never happen.*/
+ }
+
+ if(!error && bitlen.data[256] == 0) { error = 64; } /*the length of the end code 256 must be larger than 0*/
+
+ /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/
+ if(!error) error = HuffmanTree_makeFromLengths(codetree, &bitlen.data[0], bitlen.size, 15);
+ if(!error) error = HuffmanTree_makeFromLengths(codetreeD, &bitlenD.data[0], bitlenD.size, 15);
+
+ uivector_cleanup(&bitlen);
+ uivector_cleanup(&bitlenD);
+
+ return error;
+}
+
+/*inflate a block with dynamic of fixed Huffman tree*/
+static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength, unsigned btype)
+{
+ unsigned endreached = 0, error = 0;
+ HuffmanTree codetree; /*287, the code tree for Huffman codes*/
+ HuffmanTree codetreeD; /*31, the code tree for distance codes*/
+
+ HuffmanTree_init(&codetree);
+ HuffmanTree_init(&codetreeD);
+
+ if(btype == 1) getTreeInflateFixed(&codetree, &codetreeD);
+ else if(btype == 2)
+ {
+ HuffmanTree codelengthcodetree; /*18, the code tree for code length codes*/
+ HuffmanTree_init(&codelengthcodetree);
+ error = getTreeInflateDynamic(&codetree, &codetreeD, &codelengthcodetree, in, bp, inlength);
+ HuffmanTree_cleanup(&codelengthcodetree);
+ }
+
+ while(!endreached && !error)
+ {
+ unsigned code = huffmanDecodeSymbol(&error, in, bp, &codetree, inlength);
+ if(error) break; /*some error happened in the above function*/
+ if(code == 256) endreached = 1; /*end code*/
+ else if(code <= 255) /*literal symbol*/
+ {
+ if((*pos) >= out->size) ucvector_resize(out, ((*pos) + 1) * 2); /*reserve more room at once*/
+ if((*pos) >= out->size) { error = 9913; break; } /*not enough memory*/
+ out->data[(*pos)] = (unsigned char)(code);
+ (*pos)++;
+ }
+ else if(code >= FIRST_LENGTH_CODE_INDEX && code <= LAST_LENGTH_CODE_INDEX) /*length code*/
+ {
+ /*part 1: get length base*/
+ size_t length = LENGTHBASE[code - FIRST_LENGTH_CODE_INDEX];
+ unsigned codeD, distance, numextrabitsD;
+ size_t start, forward, backward, numextrabits;
+
+ /*part 2: get extra bits and add the value of that to length*/
+ numextrabits = LENGTHEXTRA[code - FIRST_LENGTH_CODE_INDEX];
+ if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
+ length += readBitsFromStream(bp, in, numextrabits);
+
+ /*part 3: get distance code*/
+ codeD = huffmanDecodeSymbol(&error, in, bp, &codetreeD, inlength);
+ if(error) break;
+ if(codeD > 29) { error = 18; break; } /*error: invalid distance code (30-31 are never used)*/
+ distance = DISTANCEBASE[codeD];
+
+ /*part 4: get extra bits from distance*/
+ numextrabitsD = DISTANCEEXTRA[codeD];
+ if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
+ distance += readBitsFromStream(bp, in, numextrabitsD);
+
+ /*part 5: fill in all the out[n] values based on the length and dist*/
+ start = (*pos);
+ backward = start - distance;
+ if((*pos) + length >= out->size) ucvector_resize(out, ((*pos) + length) * 2); /*reserve more room at once*/
+ if((*pos) + length >= out->size) { error = 9914; break; } /*not enough memory*/
+
+ for(forward = 0; forward < length; forward++)
+ {
+ out->data[(*pos)] = out->data[backward];
+ (*pos)++;
+ backward++;
+ if(backward >= start) backward = start - distance;
+ }
+ }
+ }
+
+ HuffmanTree_cleanup(&codetree);
+ HuffmanTree_cleanup(&codetreeD);
+
+ return error;
+}
+
+static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength)
+{
+ /*go to first boundary of byte*/
+ size_t p;
+ unsigned LEN, NLEN, n, error = 0;
+ while(((*bp) & 0x7) != 0) (*bp)++;
+ p = (*bp) / 8; /*byte position*/
+
+ /*read LEN (2 bytes) and NLEN (2 bytes)*/
+ if(p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/
+ LEN = in[p] + 256 * in[p + 1]; p += 2;
+ NLEN = in[p] + 256 * in[p + 1]; p += 2;
+
+ /*check if 16-bit NLEN is really the one's complement of LEN*/
+ if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/
+
+ if((*pos) + LEN >= out->size) { if(!ucvector_resize(out, (*pos) + LEN)) return 9915; }
+
+ /*read the literal data: LEN bytes are now stored in the out buffer*/
+ if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/
+ for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++];
+
+ (*bp) = p * 8;
+
+ return error;
+}
+
+/*inflate the deflated data (cfr. deflate spec); return value is the error*/
+unsigned LodeFlate_inflate(ucvector* out, const unsigned char* in, size_t insize, size_t inpos)
+{
+ size_t bp = 0; /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/
+ unsigned BFINAL = 0;
+ size_t pos = 0; /*byte position in the out buffer*/
+
+ unsigned error = 0;
+
+ while(!BFINAL)
+ {
+ unsigned BTYPE;
+ if((bp >> 3) >= insize) return 52; /*error, bit pointer will jump past memory*/
+ BFINAL = readBitFromStream(&bp, &in[inpos]);
+ BTYPE = 1 * readBitFromStream(&bp, &in[inpos]); BTYPE += 2 * readBitFromStream(&bp, &in[inpos]);
+
+ if(BTYPE == 3) return 20; /*error: invalid BTYPE*/
+ else if(BTYPE == 0) error = inflateNoCompression(out, &in[inpos], &bp, &pos, insize); /*no compression*/
+ else error = inflateHuffmanBlock(out, &in[inpos], &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/
+ if(error) return error;
+ }
+
+ if(!ucvector_resize(out, pos)) error = 9916; /*Only now we know the true size of out, resize it to that*/
+
+ return error;
+}
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Deflator / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258;
+
+/*bitlen is the size in bits of the code*/
+static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen)
+{
+ addBitsToStreamReversed(bp, compressed, code, bitlen);
+}
+
+/*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/
+static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value)
+{
+ /*linear search implementation*/
+ /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1;
+ return array_size - 1;*/
+
+ /*binary search implementation (not that much faster) (precondition: array_size > 0)*/
+ size_t left = 1;
+ size_t right = array_size - 1;
+ while(left <= right)
+ {
+ size_t mid = (left + right) / 2;
+ if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/
+ else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/
+ else return mid - 1;
+ }
+ return array_size - 1;
+}
+
+static void addLengthDistance(uivector* values, size_t length, size_t distance)
+{
+ /*values in encoded vector are those used by deflate:
+ 0-255: literal bytes
+ 256: end
+ 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits)
+ 286-287: invalid*/
+
+ unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
+ unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
+ unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
+ unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
+
+ uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX);
+ uivector_push_back(values, extra_length);
+ uivector_push_back(values, dist_code);
+ uivector_push_back(values, extra_distance);
+}
+
+#if USE_BRUTE_FORCE_ENCODING
+#define encodeLZ77 encodeLZ77_brute
+/*the "brute force" version of the encodeLZ7 algorithm, not used anymore, kept here for reference*/
+static unsigned encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size, unsigned windowSize)
+{
+ size_t pos;
+ /*using pointer instead of vector for input makes it faster when NOT using optimization when compiling; no influence if optimization is used*/
+ for(pos = 0; pos < size; pos++)
+ {
+ /*Phase 1: doxygen images often have long runs of the same color, try to find them*/
+ const int minLength = 4; // Minimum length for a run to make sense
+
+ if(pos < size - minLength * 4)
+ {
+ size_t p, fp;
+ size_t current_length;
+
+ /*RGBA pixel run?*/
+ p = pos;
+ fp = pos + 4;
+ current_length = 0;
+
+ while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
+ {
+ ++p;
+ ++fp;
+ ++current_length;
+ }
+
+ if (current_length > (minLength - 1 ) * 4) /*worth using?*/
+ {
+ uivector_push_back(out, in[pos ]);
+ uivector_push_back(out, in[pos + 1]);
+ uivector_push_back(out, in[pos + 2]);
+ uivector_push_back(out, in[pos + 3]);
+ addLengthDistance(out, current_length, 4);
+
+ pos += current_length + 4 - 1; /*-1 for loop's pos++*/
+ continue;
+ }
+
+ /*RGB pixel run?*/
+ p = pos;
+ fp = pos + 3;
+ current_length = 0;
+
+ while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
+ {
+ ++p;
+ ++fp;
+ ++current_length;
+ }
+
+ if (current_length > (minLength - 1 ) * 3) /*worth using?*/
+ {
+ uivector_push_back(out, in[pos ]);
+ uivector_push_back(out, in[pos + 1]);
+ uivector_push_back(out, in[pos + 2]);
+ addLengthDistance(out, current_length, 3);
+
+ pos += current_length + 3 - 1; /*-1 for loop's pos++*/
+ continue;
+ }
+ }
+
+ size_t length = 0, offset = 0; /*the length and offset found for the current position*/
+ size_t max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/
+ size_t current_offset;
+
+ /**search for the longest string**/
+ for(current_offset = 1; current_offset < max_offset; current_offset++) /*search backwards through all possible distances (=offsets)*/
+ {
+ size_t backpos = pos - current_offset;
+ if(in[backpos] == in[pos])
+ {
+ /*test the next characters*/
+ size_t current_length = 1;
+ size_t backtest = backpos + 1;
+ size_t foretest = pos + 1;
+ while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum supporte length by deflate is max length*/
+ {
+ if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/
+ current_length++;
+ backtest++;
+ foretest++;
+ }
+ if(current_length > length)
+ {
+ length = current_length; /*the longest length*/
+ offset = current_offset; /*the offset that is related to this longest length*/
+ if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/
+ }
+ }
+ }
+
+ /**encode it as length/distance pair or literal value**/
+ if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
+ {
+ uivector_push_back(out, in[pos]);
+ }
+ else
+ {
+ addLengthDistance(out, length, offset);
+ pos += (length - 1);
+ }
+ } /*end of the loop through each character of input*/
+
+ return 0;
+}
+#endif
+
+/*
+static const unsigned HASH_NUM_VALUES = 65536;
+static const unsigned HASH_NUM_CHARACTERS = 6;
+static const unsigned HASH_SHIFT = 2;
+Good and fast values: HASH_NUM_VALUES=65536, HASH_NUM_CHARACTERS=6, HASH_SHIFT=2
+making HASH_NUM_CHARACTERS larger (like 8), makes the file size larger but is a bit faster
+making HASH_NUM_CHARACTERS smaller (like 3), makes the file size smaller but is slower
+*/
+
+#if !defined(USE_BRUTE_FORCE_ENCODING)
+static unsigned getHash(const unsigned char* data, size_t size, size_t pos)
+{
+ unsigned result = 0;
+ size_t amount, i;
+ if(pos >= size) return 0;
+ amount = HASH_NUM_CHARACTERS; if(pos + amount >= size) amount = size - pos;
+ for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
+ return result % HASH_NUM_VALUES;
+}
+
+/*LZ77-encode the data using a hash table technique to let it encode faster. Return value is error code*/
+static unsigned encodeLZ77(uivector* out, const unsigned char* in, size_t size, unsigned windowSize)
+{
+ /**generate hash table**/
+ vector table; /*HASH_NUM_VALUES uivectors; this represents what would be an std::vector<std::vector<unsigned> > in C++*/
+ uivector tablepos1, tablepos2;
+ unsigned pos, i, error = 0;
+
+ vector_init(&table, sizeof(uivector));
+ if(!vector_resize(&table, HASH_NUM_VALUES)) return 9917;
+ for(i = 0; i < HASH_NUM_VALUES; i++)
+ {
+ uivector* v = (uivector*)vector_get(&table, i);
+ uivector_init(v);
+ }
+
+ /*remember start and end positions in the tables to searching in*/
+ uivector_init(&tablepos1);
+ uivector_init(&tablepos2);
+ if(!uivector_resizev(&tablepos1, HASH_NUM_VALUES, 0)) error = 9918;
+ if(!uivector_resizev(&tablepos2, HASH_NUM_VALUES, 0)) error = 9919;
+
+ if(!error)
+ {
+ for(pos = 0; pos < size; pos++)
+ {
+ unsigned length = 0, offset = 0; /*the length and offset found for the current position*/
+ unsigned max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/
+ unsigned tablepos;
+
+ /*/search for the longest string*/
+ /*first find out where in the table to start (the first value that is in the range from "pos - max_offset" to "pos")*/
+ unsigned hash = getHash(in, size, pos);
+ if(!uivector_push_back((uivector*)vector_get(&table, hash), pos)) { error = 9920; break; }
+
+ while(((uivector*)vector_get(&table, hash))->data[tablepos1.data[hash]] < pos - max_offset) tablepos1.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos - max_offset*/
+ while(((uivector*)vector_get(&table, hash))->data[tablepos2.data[hash]] < pos) tablepos2.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos*/
+
+ for(tablepos = tablepos2.data[hash] - 1; tablepos >= tablepos1.data[hash] && tablepos < tablepos2.data[hash]; tablepos--)
+ {
+ unsigned backpos = ((uivector*)vector_get(&table, hash))->data[tablepos];
+ unsigned current_offset = pos - backpos;
+
+ /*test the next characters*/
+ unsigned current_length = 0;
+ unsigned backtest = backpos;
+ unsigned foretest = pos;
+ while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum supporte length by deflate is max length*/
+ {
+ if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/
+ current_length++;
+ backtest++;
+ foretest++;
+ }
+ if(current_length > length)
+ {
+ length = current_length; /*the longest length*/
+ offset = current_offset; /*the offset that is related to this longest length*/
+ if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/
+ }
+ }
+
+ /**encode it as length/distance pair or literal value**/
+ if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
+ {
+ if(!uivector_push_back(out, in[pos])) { error = 9921; break; }
+ }
+ else
+ {
+ unsigned j;
+ addLengthDistance(out, length, offset);
+ for(j = 0; j < length - 1; j++)
+ {
+ pos++;
+ if(!uivector_push_back((uivector*)vector_get(&table, getHash(in, size, pos)), pos)) { error = 9922; break; }
+ }
+ }
+ } /*end of the loop through each character of input*/
+ } /*end of "if(!error)"*/
+
+ /*cleanup*/
+ for(i = 0; i < table.size; i++)
+ {
+ uivector* v = (uivector*)vector_get(&table, i);
+ uivector_cleanup(v);
+ }
+ vector_cleanup(&table);
+ uivector_cleanup(&tablepos1);
+ uivector_cleanup(&tablepos2);
+ return error;
+}
+#endif
+
+/* /////////////////////////////////////////////////////////////////////////// */
+
+static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize)
+{
+ /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/
+
+ size_t i, j, numdeflateblocks = datasize / 65536 + 1;
+ unsigned datapos = 0;
+ for(i = 0; i < numdeflateblocks; i++)
+ {
+ unsigned BFINAL, BTYPE, LEN, NLEN;
+ unsigned char firstbyte;
+
+ BFINAL = (i == numdeflateblocks - 1);
+ BTYPE = 0;
+
+ firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
+ ucvector_push_back(out, firstbyte);
+
+ LEN = 65535;
+ if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos;
+ NLEN = 65535 - LEN;
+
+ ucvector_push_back(out, (unsigned char)(LEN % 256));
+ ucvector_push_back(out, (unsigned char)(LEN / 256));
+ ucvector_push_back(out, (unsigned char)(NLEN % 256));
+ ucvector_push_back(out, (unsigned char)(NLEN / 256));
+
+ /*Decompressed data*/
+ for(j = 0; j < 65535 && datapos < datasize; j++)
+ {
+ ucvector_push_back(out, data[datapos++]);
+ }
+ }
+
+ return 0;
+}
+
+/*write the encoded data, using lit/len as well as distance codes*/
+static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, const HuffmanTree* codes, const HuffmanTree* codesD)
+{
+ size_t i = 0;
+ for(i = 0; i < lz77_encoded->size; i++)
+ {
+ unsigned val = lz77_encoded->data[i];
+ addHuffmanSymbol(bp, out, HuffmanTree_getCode(codes, val), HuffmanTree_getLength(codes, val));
+ if(val > 256) /*for a length code, 3 more things have to be added*/
+ {
+ unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
+ unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
+ unsigned length_extra_bits = lz77_encoded->data[++i];
+
+ unsigned distance_code = lz77_encoded->data[++i];
+
+ unsigned distance_index = distance_code;
+ unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
+ unsigned distance_extra_bits = lz77_encoded->data[++i];
+
+ addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits);
+ addHuffmanSymbol(bp, out, HuffmanTree_getCode(codesD, distance_code), HuffmanTree_getLength(codesD, distance_code));
+ addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits);
+ }
+ }
+}
+
+static unsigned deflateDynamic(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
+{
+ /*
+ after the BFINAL and BTYPE, the dynamic block consists out of the following:
+ - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN
+ - (HCLEN+4)*3 bits code lengths of code length alphabet
+ - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
+ - HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
+ - compressed data
+ - 256 (end code)
+ */
+
+ unsigned error = 0;
+
+ uivector lz77_encoded;
+ HuffmanTree codes; /*tree for literal values and length codes*/
+ HuffmanTree codesD; /*tree for distance codes*/
+ HuffmanTree codelengthcodes;
+ uivector frequencies;
+ uivector frequenciesD;
+ uivector amounts; /*the amounts in the "normal" order*/
+ uivector lldl;
+ uivector lldll; /*lit/len & dist code lenghts*/
+ uivector clcls;
+
+ unsigned BFINAL = 1; /*make only one block... the first and final one*/
+ size_t numcodes, numcodesD, i, bp = 0; /*the bit pointer*/
+ unsigned HLIT, HDIST, HCLEN;
+
+ uivector_init(&lz77_encoded);
+ HuffmanTree_init(&codes);
+ HuffmanTree_init(&codesD);
+ HuffmanTree_init(&codelengthcodes);
+ uivector_init(&frequencies);
+ uivector_init(&frequenciesD);
+ uivector_init(&amounts);
+ uivector_init(&lldl);
+ uivector_init(&lldll);
+ uivector_init(&clcls);
+
+ while(!error) /*the goto-avoiding while construct: break out to go to the cleanup phase, a break at the end makes sure the while is never repeated*/
+ {
+ if(settings->useLZ77)
+ {
+ error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize); /*LZ77 encoded*/
+ if(error) break;
+ }
+ else
+ {
+ if(!uivector_resize(&lz77_encoded, datasize)) { error = 9923; break; }
+ for(i = 0; i < datasize; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/
+ }
+
+ if(!uivector_resizev(&frequencies, 286, 0)) { error = 9924; break; }
+ if(!uivector_resizev(&frequenciesD, 30, 0)) { error = 9925; break; }
+ for(i = 0; i < lz77_encoded.size; i++)
+ {
+ unsigned symbol = lz77_encoded.data[i];
+ frequencies.data[symbol]++;
+ if(symbol > 256)
+ {
+ unsigned dist = lz77_encoded.data[i + 2];
+ frequenciesD.data[dist]++;
+ i += 3;
+ }
+ }
+ frequencies.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/
+
+ error = HuffmanTree_makeFromFrequencies(&codes, frequencies.data, frequencies.size, 15);
+ if(error) break;
+ error = HuffmanTree_makeFromFrequencies(&codesD, frequenciesD.data, frequenciesD.size, 15);
+ if(error) break;
+
+ addBitToStream(&bp, out, BFINAL);
+ addBitToStream(&bp, out, 0); /*first bit of BTYPE "dynamic"*/
+ addBitToStream(&bp, out, 1); /*second bit of BTYPE "dynamic"*/
+
+ numcodes = codes.numcodes; if(numcodes > 286) numcodes = 286;
+ numcodesD = codesD.numcodes; if(numcodesD > 30) numcodesD = 30;
+ for(i = 0; i < numcodes; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codes, (unsigned)i));
+ for(i = 0; i < numcodesD; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codesD, (unsigned)i));
+
+ /*make lldl smaller by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/
+ for(i = 0; i < (unsigned)lldll.size; i++)
+ {
+ unsigned j = 0;
+ while(i + j + 1 < (unsigned)lldll.size && lldll.data[i + j + 1] == lldll.data[i]) j++;
+
+ if(lldll.data[i] == 0 && j >= 2)
+ {
+ j++; /*include the first zero*/
+ if(j <= 10) { uivector_push_back(&lldl, 17); uivector_push_back(&lldl, j - 3); }
+ else
+ {
+ if(j > 138) j = 138;
+ uivector_push_back(&lldl, 18); uivector_push_back(&lldl, j - 11);
+ }
+ i += (j - 1);
+ }
+ else if(j >= 3)
+ {
+ size_t k;
+ unsigned num = j / 6, rest = j % 6;
+ uivector_push_back(&lldl, lldll.data[i]);
+ for(k = 0; k < num; k++) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, 6 - 3); }
+ if(rest >= 3) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, rest - 3); }
+ else j -= rest;
+ i += j;
+ }
+ else uivector_push_back(&lldl, lldll.data[i]);
+ }
+
+ /*generate huffmantree for the length codes of lit/len and dist codes*/
+ if(!uivector_resizev(&amounts, 19, 0)) { error = 9926; break; } /*16 possible lengths (0-15) and 3 repeat codes (16, 17 and 18)*/
+ for(i = 0; i < lldl.size; i++)
+ {
+ amounts.data[lldl.data[i]]++;
+ if(lldl.data[i] >= 16) i++; /*after a repeat code come the bits that specify the amount, those don't need to be in the amounts calculation*/
+ }
+
+ error = HuffmanTree_makeFromFrequencies(&codelengthcodes, amounts.data, amounts.size, 7);
+ if(error) break;
+
+ if(!uivector_resize(&clcls, 19)) { error = 9927; break; }
+ for(i = 0; i < 19; i++) clcls.data[i] = HuffmanTree_getLength(&codelengthcodes, CLCL[i]); /*lenghts of code length tree is in the order as specified by deflate*/
+ while(clcls.data[clcls.size - 1] == 0 && clcls.size > 4)
+ {
+ if(!uivector_resize(&clcls, clcls.size - 1)) { error = 9928; break; } /*remove zeros at the end, but minimum size must be 4*/
+ }
+ if(error) break;
+
+ /*write the HLIT, HDIST and HCLEN values*/
+ HLIT = (unsigned)(numcodes - 257);
+ HDIST = (unsigned)(numcodesD - 1);
+ HCLEN = (unsigned)clcls.size - 4;
+ addBitsToStream(&bp, out, HLIT, 5);
+ addBitsToStream(&bp, out, HDIST, 5);
+ addBitsToStream(&bp, out, HCLEN, 4);
+
+ /*write the code lenghts of the code length alphabet*/
+ for(i = 0; i < HCLEN + 4; i++) addBitsToStream(&bp, out, clcls.data[i], 3);
+
+ /*write the lenghts of the lit/len AND the dist alphabet*/
+ for(i = 0; i < lldl.size; i++)
+ {
+ addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codelengthcodes, lldl.data[i]), HuffmanTree_getLength(&codelengthcodes, lldl.data[i]));
+ /*extra bits of repeat codes*/
+ if(lldl.data[i] == 16) addBitsToStream(&bp, out, lldl.data[++i], 2);
+ else if(lldl.data[i] == 17) addBitsToStream(&bp, out, lldl.data[++i], 3);
+ else if(lldl.data[i] == 18) addBitsToStream(&bp, out, lldl.data[++i], 7);
+ }
+
+ /*write the compressed data symbols*/
+ writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
+ if(HuffmanTree_getLength(&codes, 256) == 0) { error = 64; break; } /*the length of the end code 256 must be larger than 0*/
+ addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*end code*/
+
+ break; /*end of error-while*/
+ }
+
+ /*cleanup*/
+ uivector_cleanup(&lz77_encoded);
+ HuffmanTree_cleanup(&codes);
+ HuffmanTree_cleanup(&codesD);
+ HuffmanTree_cleanup(&codelengthcodes);
+ uivector_cleanup(&frequencies);
+ uivector_cleanup(&frequenciesD);
+ uivector_cleanup(&amounts);
+ uivector_cleanup(&lldl);
+ uivector_cleanup(&lldll);
+ uivector_cleanup(&clcls);
+
+ return error;
+}
+
+static unsigned deflateFixed(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
+{
+ HuffmanTree codes; /*tree for literal values and length codes*/
+ HuffmanTree codesD; /*tree for distance codes*/
+
+ unsigned BFINAL = 1; /*make only one block... the first and final one*/
+ unsigned error = 0;
+ size_t i, bp = 0; /*the bit pointer*/
+
+ HuffmanTree_init(&codes);
+ HuffmanTree_init(&codesD);
+
+ generateFixedTree(&codes);
+ generateDistanceTree(&codesD);
+
+ addBitToStream(&bp, out, BFINAL);
+ addBitToStream(&bp, out, 1); /*first bit of BTYPE*/
+ addBitToStream(&bp, out, 0); /*second bit of BTYPE*/
+
+ if(settings->useLZ77) /*LZ77 encoded*/
+ {
+ uivector lz77_encoded;
+ uivector_init(&lz77_encoded);
+ error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize);
+ if(!error) writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
+ uivector_cleanup(&lz77_encoded);
+ }
+ else /*no LZ77, but still will be Huffman compressed*/
+ {
+ for(i = 0; i < datasize; i++) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, data[i]), HuffmanTree_getLength(&codes, data[i]));
+ }
+ if(!error) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*"end" code*/
+
+ /*cleanup*/
+ HuffmanTree_cleanup(&codes);
+ HuffmanTree_cleanup(&codesD);
+
+ return error;
+}
+
+unsigned LodeFlate_deflate(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
+{
+ unsigned error = 0;
+ if(settings->btype == 0) error = deflateNoCompression(out, data, datasize);
+ else if(settings->btype == 1) error = deflateFixed(out, data, datasize, settings);
+ else if(settings->btype == 2) error = deflateDynamic(out, data, datasize, settings);
+ else error = 61;
+ return error;
+}
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Adler32 */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len)
+{
+ unsigned s1 = adler & 0xffff;
+ unsigned s2 = (adler >> 16) & 0xffff;
+
+ while(len > 0)
+ {
+ /*at least 5550 sums can be done before the sums overflow, saving us from a lot of module divisions*/
+ unsigned amount = len > 5550 ? 5550 : len;
+ len -= amount;
+ while(amount > 0)
+ {
+ s1 = (s1 + *data++);
+ s2 = (s2 + s1);
+ amount--;
+ }
+ s1 %= 65521;
+ s2 %= 65521;
+ }
+
+ return (s2 << 16) | s1;
+}
+
+/*Return the adler32 of the bytes data[0..len-1]*/
+static unsigned adler32(const unsigned char* data, unsigned len)
+{
+ return update_adler32(1L, data, len);
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Reading and writing single bits and bytes from/to stream for Zlib / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_ENCODER
+void LodeZlib_add32bitInt(ucvector* buffer, unsigned value)
+{
+ ucvector_push_back(buffer, (unsigned char)((value >> 24) & 0xff));
+ ucvector_push_back(buffer, (unsigned char)((value >> 16) & 0xff));
+ ucvector_push_back(buffer, (unsigned char)((value >> 8) & 0xff));
+ ucvector_push_back(buffer, (unsigned char)((value ) & 0xff));
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+unsigned LodeZlib_read32bitInt(const unsigned char* buffer)
+{
+ return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Zlib / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_DECODER
+
+unsigned LodeZlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DecompressSettings* settings)
+{
+ unsigned error = 0;
+ unsigned CM, CINFO, FDICT;
+ ucvector outv;
+
+ if(insize < 2) { error = 53; return error; } /*error, size of zlib data too small*/
+ /*read information from zlib header*/
+ if((in[0] * 256 + in[1]) % 31 != 0) { error = 24; return error; } /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/
+
+ CM = in[0] & 15;
+ CINFO = (in[0] >> 4) & 15;
+ /*FCHECK = in[1] & 31; //FCHECK is already tested above*/
+ FDICT = (in[1] >> 5) & 1;
+ /*FLEVEL = (in[1] >> 6) & 3; //not really important, all it does it to give a compiler warning about unused variable, we don't care what encoding setting the encoder used*/
+
+ if(CM != 8 || CINFO > 7) { error = 25; return error; } /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/
+ if(FDICT != 0) { error = 26; return error; } /*error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."*/
+
+ ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/
+ error = LodeFlate_inflate(&outv, in, insize, 2);
+ *out = outv.data;
+ *outsize = outv.size;
+ if(error) return error;
+
+ if(!settings->ignoreAdler32)
+ {
+ unsigned ADLER32 = LodeZlib_read32bitInt(&in[insize - 4]);
+ unsigned checksum = adler32(outv.data, (unsigned)outv.size);
+ if(checksum != ADLER32) { error = 58; return error; }
+ }
+
+ return error;
+}
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+
+unsigned LodeZlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings)
+{
+ /*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/
+ ucvector deflatedata, outv;
+ size_t i;
+ unsigned error;
+
+ unsigned ADLER32;
+ /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
+ unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
+ unsigned FLEVEL = 0;
+ unsigned FDICT = 0;
+ unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
+ unsigned FCHECK = 31 - CMFFLG % 31;
+ CMFFLG += FCHECK;
+
+ ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/
+
+ ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256));
+ ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256));
+
+ ucvector_init(&deflatedata);
+ error = LodeFlate_deflate(&deflatedata, in, insize, settings);
+
+ if(!error)
+ {
+ ADLER32 = adler32(in, (unsigned)insize);
+ for(i = 0; i < deflatedata.size; i++) ucvector_push_back(&outv, deflatedata.data[i]);
+ ucvector_cleanup(&deflatedata);
+ LodeZlib_add32bitInt(&outv, ADLER32);
+ }
+
+ *out = outv.data;
+ *outsize = outv.size;
+
+ return error;
+}
+
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+#endif /*LODEPNG_COMPILE_ZLIB*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_ENCODER
+
+void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings* settings)
+{
+ settings->btype = 2; /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/
+ settings->useLZ77 = 1;
+ settings->windowSize = 2048; /*this is a good tradeoff between speed and compression ratio*/
+}
+
+const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings = {2, 1, 2048};
+
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+#ifdef LODEPNG_COMPILE_DECODER
+
+void LodeZlib_DecompressSettings_init(LodeZlib_DecompressSettings* settings)
+{
+ settings->ignoreAdler32 = 0;
+}
+
+const LodeZlib_DecompressSettings LodeZlib_defaultDecompressSettings = {0};
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* // End of Zlib related code, now comes the PNG related code that uses it// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_PNG
+
+/*
+The two functions below (LodePNG_decompress and LodePNG_compress) directly call the
+LodeZlib_decompress and LodeZlib_compress functions. The only purpose of the functions
+below, is to provide the ability to let LodePNG use a different Zlib encoder by only
+changing the two functions below, instead of changing it inside the vareous places
+in the other LodePNG functions.
+
+*out must be NULL and *outsize must be 0 initially, and after the function is done,
+*out must point to the decompressed data, *outsize must be the size of it, and must
+be the size of the useful data in bytes, not the alloc size.
+*/
+
+#ifdef LODEPNG_COMPILE_DECODER
+static unsigned LodePNG_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DecompressSettings* settings)
+{
+ return LodeZlib_decompress(out, outsize, in, insize, settings);
+}
+#endif /*LODEPNG_COMPILE_DECODER*/
+#ifdef LODEPNG_COMPILE_ENCODER
+static unsigned LodePNG_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings)
+{
+ return LodeZlib_compress(out, outsize, in, insize, settings);
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / CRC32 / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+static unsigned Crc32_crc_table_computed = 0;
+static unsigned Crc32_crc_table[256];
+
+/*Make the table for a fast CRC.*/
+static void Crc32_make_crc_table(void)
+{
+ unsigned int c, k, n;
+ for(n = 0; n < 256; n++)
+ {
+ c = n;
+ for(k = 0; k < 8; k++)
+ {
+ if(c & 1) c = (unsigned int)(0xedb88320L ^ (c >> 1));
+ else c = c >> 1;
+ }
+ Crc32_crc_table[n] = c;
+ }
+ Crc32_crc_table_computed = 1;
+}
+
+/*Update a running CRC with the bytes buf[0..len-1]--the CRC should be
+initialized to all 1's, and the transmitted value is the 1's complement of the
+final running CRC (see the crc() routine below).*/
+static unsigned Crc32_update_crc(const unsigned char* buf, unsigned int crc, size_t len)
+{
+ unsigned int c = crc;
+ size_t n;
+
+ if(!Crc32_crc_table_computed) Crc32_make_crc_table();
+ for(n = 0; n < len; n++)
+ {
+ c = Crc32_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+ }
+ return c;
+}
+
+/*Return the CRC of the bytes buf[0..len-1].*/
+static unsigned Crc32_crc(const unsigned char* buf, size_t len)
+{
+ return Crc32_update_crc(buf, 0xffffffffu, len) ^ 0xffffffffu;
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Reading and writing single bits and bytes from/to stream for LodePNG / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream)
+{
+ unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
+ (*bitpointer)++;
+ return result;
+}
+
+static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
+{
+ unsigned result = 0;
+ size_t i;
+ for(i = nbits - 1; i < nbits; i--) result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i;
+ return result;
+}
+
+#ifdef LODEPNG_COMPILE_DECODER
+static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
+{
+ /*the current bit in bitstream must be 0 for this to work*/
+ if(bit) bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
+ (*bitpointer)++;
+}
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
+{
+ /*the current bit in bitstream may be 0 or 1 for this to work*/
+ if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
+ else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7)));
+ (*bitpointer)++;
+}
+
+static unsigned LodePNG_read32bitInt(const unsigned char* buffer)
+{
+ return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+}
+
+static void LodePNG_set32bitInt(unsigned char* buffer, unsigned value) /*buffer must have at least 4 allocated bytes available*/
+{
+ buffer[0] = (unsigned char)((value >> 24) & 0xff);
+ buffer[1] = (unsigned char)((value >> 16) & 0xff);
+ buffer[2] = (unsigned char)((value >> 8) & 0xff);
+ buffer[3] = (unsigned char)((value ) & 0xff);
+}
+
+#ifdef LODEPNG_COMPILE_ENCODER
+static void LodePNG_add32bitInt(ucvector* buffer, unsigned value)
+{
+ ucvector_resize(buffer, buffer->size + 4);
+ LodePNG_set32bitInt(&buffer->data[buffer->size - 4], value);
+}
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / PNG chunks / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+unsigned LodePNG_chunk_length(const unsigned char* chunk) /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/
+{
+ return LodePNG_read32bitInt(&chunk[0]);
+}
+
+void LodePNG_chunk_type(char type[5], const unsigned char* chunk) /*puts the 4-byte type in null terminated string*/
+{
+ unsigned i;
+ for(i = 0; i < 4; i++) type[i] = chunk[4 + i];
+ type[4] = 0; /*null termination char*/
+}
+
+unsigned char LodePNG_chunk_type_equals(const unsigned char* chunk, const char* type) /*check if the type is the given type*/
+{
+ if(strlen(type) != 4) return 0;
+ return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
+}
+
+/*properties of PNG chunks gotten from capitalization of chunk type name, as defined by the standard*/
+unsigned char LodePNG_chunk_critical(const unsigned char* chunk) /*0: ancillary chunk, 1: it's one of the critical chunk types*/
+{
+ return((chunk[4] & 32) == 0);
+}
+
+unsigned char LodePNG_chunk_private(const unsigned char* chunk) /*0: public, 1: private*/
+{
+ return((chunk[6] & 32) != 0);
+}
+
+unsigned char LodePNG_chunk_safetocopy(const unsigned char* chunk) /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy*/
+{
+ return((chunk[7] & 32) != 0);
+}
+
+unsigned char* LodePNG_chunk_data(unsigned char* chunk) /*get pointer to the data of the chunk*/
+{
+ return &chunk[8];
+}
+
+const unsigned char* LodePNG_chunk_data_const(const unsigned char* chunk) /*get pointer to the data of the chunk*/
+{
+ return &chunk[8];
+}
+
+unsigned LodePNG_chunk_check_crc(const unsigned char* chunk) /*returns 0 if the crc is correct, error code if it's incorrect*/
+{
+ unsigned length = LodePNG_chunk_length(chunk);
+ unsigned CRC = LodePNG_read32bitInt(&chunk[length + 8]);
+ unsigned checksum = Crc32_crc(&chunk[4], length + 4); /*the CRC is taken of the data and the 4 chunk type letters, not the length*/
+ if(CRC != checksum) return 1;
+ else return 0;
+}
+
+void LodePNG_chunk_generate_crc(unsigned char* chunk) /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
+{
+ unsigned length = LodePNG_chunk_length(chunk);
+ unsigned CRC = Crc32_crc(&chunk[4], length + 4);
+ LodePNG_set32bitInt(chunk + 8 + length, CRC);
+}
+
+unsigned char* LodePNG_chunk_next(unsigned char* chunk) /*don't use on IEND chunk, as there is no next chunk then*/
+{
+ unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
+ return &chunk[total_chunk_length];
+}
+
+const unsigned char* LodePNG_chunk_next_const(const unsigned char* chunk) /*don't use on IEND chunk, as there is no next chunk then*/
+{
+ unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
+ return &chunk[total_chunk_length];
+}
+
+unsigned LodePNG_append_chunk(unsigned char** out, size_t* outlength, const unsigned char* chunk) /*appends chunk that was already created, to the data. Returns error code.*/
+{
+ unsigned i;
+ unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
+ unsigned char *chunk_start, *new_buffer;
+ size_t new_length = (*outlength) + total_chunk_length;
+ if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/
+
+ new_buffer = (unsigned char*)realloc(*out, new_length);
+ if(!new_buffer) return 9929;
+ (*out) = new_buffer;
+ (*outlength) = new_length;
+ chunk_start = &(*out)[new_length - total_chunk_length];
+
+ for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i];
+
+ return 0;
+}
+
+unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data) /*appends new chunk to out. Returns error code; may change memory address of out buffer*/
+{
+ unsigned i;
+ unsigned char *chunk, *new_buffer;
+ size_t new_length = (*outlength) + length + 12;
+ if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/
+ new_buffer = (unsigned char*)realloc(*out, new_length);
+ if(!new_buffer) return 9930;
+ (*out) = new_buffer;
+ (*outlength) = new_length;
+ chunk = &(*out)[(*outlength) - length - 12];
+
+ /*1: length*/
+ LodePNG_set32bitInt(chunk, (unsigned)length);
+
+ /*2: chunk name (4 letters)*/
+ chunk[4] = type[0];
+ chunk[5] = type[1];
+ chunk[6] = type[2];
+ chunk[7] = type[3];
+
+ /*3: the data*/
+ for(i = 0; i < length; i++) chunk[8 + i] = data[i];
+
+ /*4: CRC (of the chunkname characters and the data)*/
+ LodePNG_chunk_generate_crc(chunk);
+
+ return 0;
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / Color types and such / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*return type is a LodePNG error code*/
+static unsigned checkColorValidity(unsigned colorType, unsigned bd) /*bd = bitDepth*/
+{
+ switch(colorType)
+ {
+ case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/
+ case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/
+ case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/
+ case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/
+ case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/
+ default: return 31;
+ }
+ return 0; /*allowed color type / bits combination*/
+}
+
+static unsigned getNumColorChannels(unsigned colorType)
+{
+ switch(colorType)
+ {
+ case 0: return 1; /*grey*/
+ case 2: return 3; /*RGB*/
+ case 3: return 1; /*palette*/
+ case 4: return 2; /*grey + alpha*/
+ case 6: return 4; /*RGBA*/
+ }
+ return 0; /*unexisting color type*/
+}
+
+static unsigned getBpp(unsigned colorType, unsigned bitDepth)
+{
+ return getNumColorChannels(colorType) * bitDepth; /*bits per pixel is amount of channels * bits per channel*/
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+void LodePNG_InfoColor_init(LodePNG_InfoColor* info)
+{
+ info->key_defined = 0;
+ info->key_r = info->key_g = info->key_b = 0;
+ info->colorType = 6;
+ info->bitDepth = 8;
+ info->palette = 0;
+ info->palettesize = 0;
+}
+
+void LodePNG_InfoColor_cleanup(LodePNG_InfoColor* info)
+{
+ LodePNG_InfoColor_clearPalette(info);
+}
+
+void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor* info)
+{
+ if(info->palette) free(info->palette);
+ info->palettesize = 0;
+}
+
+unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+ unsigned char* data;
+ /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/
+ if(!(info->palettesize & (info->palettesize - 1))) /*if palettesize is 0 or a power of two*/
+ {
+ /*allocated data must be at least 4* palettesize (for 4 color bytes)*/
+ size_t alloc_size = info->palettesize == 0 ? 4 : info->palettesize * 4 * 2;
+ data = (unsigned char*)realloc(info->palette, alloc_size);
+ if(!data) return 9931;
+ else info->palette = data;
+ }
+ info->palette[4 * info->palettesize + 0] = r;
+ info->palette[4 * info->palettesize + 1] = g;
+ info->palette[4 * info->palettesize + 2] = b;
+ info->palette[4 * info->palettesize + 3] = a;
+ info->palettesize++;
+ return 0;
+}
+
+unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor* info) { return getBpp(info->colorType, info->bitDepth); } /*calculate bits per pixel out of colorType and bitDepth*/
+unsigned LodePNG_InfoColor_getChannels(const LodePNG_InfoColor* info) { return getNumColorChannels(info->colorType); }
+unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor* info) { return info->colorType == 0 || info->colorType == 4; }
+unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor* info) { return (info->colorType & 4) != 0; }
+
+unsigned LodePNG_InfoColor_equal(const LodePNG_InfoColor* info1, const LodePNG_InfoColor* info2)
+{
+ return info1->colorType == info2->colorType
+ && info1->bitDepth == info2->bitDepth; /*palette and color key not compared*/
+}
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+
+void LodePNG_UnknownChunks_init(LodePNG_UnknownChunks* chunks)
+{
+ unsigned i;
+ for(i = 0; i < 3; i++) chunks->data[i] = 0;
+ for(i = 0; i < 3; i++) chunks->datasize[i] = 0;
+}
+
+void LodePNG_UnknownChunks_cleanup(LodePNG_UnknownChunks* chunks)
+{
+ unsigned i;
+ for(i = 0; i < 3; i++) free(chunks->data[i]);
+}
+
+unsigned LodePNG_UnknownChunks_copy(LodePNG_UnknownChunks* dest, const LodePNG_UnknownChunks* src)
+{
+ unsigned i;
+
+ LodePNG_UnknownChunks_cleanup(dest);
+
+ for(i = 0; i < 3; i++)
+ {
+ size_t j;
+ dest->datasize[i] = src->datasize[i];
+ dest->data[i] = (unsigned char*)malloc(src->datasize[i]);
+ if(!dest->data[i] && dest->datasize[i]) return 9932;
+ for(j = 0; j < src->datasize[i]; j++) dest->data[i][j] = src->data[i][j];
+ }
+
+ return 0;
+}
+
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+
+void LodePNG_Text_init(LodePNG_Text* text)
+{
+ text->num = 0;
+ text->keys = NULL;
+ text->strings = NULL;
+}
+
+void LodePNG_Text_cleanup(LodePNG_Text* text)
+{
+ LodePNG_Text_clear(text);
+}
+
+unsigned LodePNG_Text_copy(LodePNG_Text* dest, const LodePNG_Text* source)
+{
+ size_t i = 0;
+ dest->keys = 0;
+ dest->strings = 0;
+ dest->num = 0;
+ for(i = 0; i < source->num; i++)
+ {
+ unsigned error = LodePNG_Text_add(dest, source->keys[i], source->strings[i]);
+ if(error) return error;
+ }
+ return 0;
+}
+
+void LodePNG_Text_clear(LodePNG_Text* text)
+{
+ size_t i;
+ for(i = 0; i < text->num; i++)
+ {
+ string_cleanup(&text->keys[i]);
+ string_cleanup(&text->strings[i]);
+ }
+ free(text->keys);
+ free(text->strings);
+}
+
+unsigned LodePNG_Text_add(LodePNG_Text* text, const char* key, const char* str)
+{
+ char** new_keys = (char**)(realloc(text->keys, sizeof(char*) * (text->num + 1)));
+ char** new_strings = (char**)(realloc(text->strings, sizeof(char*) * (text->num + 1)));
+ if(!new_keys || !new_strings)
+ {
+ free(new_keys);
+ free(new_strings);
+ return 9933;
+ }
+
+ text->num++;
+ text->keys = new_keys;
+ text->strings = new_strings;
+
+ string_init(&text->keys[text->num - 1]);
+ string_set(&text->keys[text->num - 1], key);
+
+ string_init(&text->strings[text->num - 1]);
+ string_set(&text->strings[text->num - 1], str);
+
+ return 0;
+}
+
+/******************************************************************************/
+
+void LodePNG_IText_init(LodePNG_IText* text)
+{
+ text->num = 0;
+ text->keys = NULL;
+ text->langtags = NULL;
+ text->transkeys = NULL;
+ text->strings = NULL;
+}
+
+void LodePNG_IText_cleanup(LodePNG_IText* text)
+{
+ LodePNG_IText_clear(text);
+}
+
+unsigned LodePNG_IText_copy(LodePNG_IText* dest, const LodePNG_IText* source)
+{
+ size_t i = 0;
+ dest->keys = 0;
+ dest->langtags = 0;
+ dest->transkeys = 0;
+ dest->strings = 0;
+ dest->num = 0;
+ for(i = 0; i < source->num; i++)
+ {
+ unsigned error = LodePNG_IText_add(dest, source->keys[i], source->langtags[i], source->transkeys[i], source->strings[i]);
+ if(error) return error;
+ }
+ return 0;
+}
+
+void LodePNG_IText_clear(LodePNG_IText* text)
+{
+ size_t i;
+ for(i = 0; i < text->num; i++)
+ {
+ string_cleanup(&text->keys[i]);
+ string_cleanup(&text->langtags[i]);
+ string_cleanup(&text->transkeys[i]);
+ string_cleanup(&text->strings[i]);
+ }
+ free(text->keys);
+ free(text->langtags);
+ free(text->transkeys);
+ free(text->strings);
+}
+
+unsigned LodePNG_IText_add(LodePNG_IText* text, const char* key, const char* langtag, const char* transkey, const char* str)
+{
+ char** new_keys = (char**)(realloc(text->keys, sizeof(char*) * (text->num + 1)));
+ char** new_langtags = (char**)(realloc(text->langtags, sizeof(char*) * (text->num + 1)));
+ char** new_transkeys = (char**)(realloc(text->transkeys, sizeof(char*) * (text->num + 1)));
+ char** new_strings = (char**)(realloc(text->strings, sizeof(char*) * (text->num + 1)));
+ if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
+ {
+ free(new_keys);
+ free(new_langtags);
+ free(new_transkeys);
+ free(new_strings);
+ return 9934;
+ }
+
+ text->num++;
+ text->keys = new_keys;
+ text->langtags = new_langtags;
+ text->transkeys = new_transkeys;
+ text->strings = new_strings;
+
+ string_init(&text->keys[text->num - 1]);
+ string_set(&text->keys[text->num - 1], key);
+
+ string_init(&text->langtags[text->num - 1]);
+ string_set(&text->langtags[text->num - 1], langtag);
+
+ string_init(&text->transkeys[text->num - 1]);
+ string_set(&text->transkeys[text->num - 1], transkey);
+
+ string_init(&text->strings[text->num - 1]);
+ string_set(&text->strings[text->num - 1], str);
+
+ return 0;
+}
+
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+void LodePNG_InfoPng_init(LodePNG_InfoPng* info)
+{
+ info->width = info->height = 0;
+ LodePNG_InfoColor_init(&info->color);
+ info->interlaceMethod = 0;
+ info->compressionMethod = 0;
+ info->filterMethod = 0;
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ info->background_defined = 0;
+ info->background_r = info->background_g = info->background_b = 0;
+
+ LodePNG_Text_init(&info->text);
+ LodePNG_IText_init(&info->itext);
+
+ info->time_defined = 0;
+ info->phys_defined = 0;
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ LodePNG_UnknownChunks_init(&info->unknown_chunks);
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+}
+
+void LodePNG_InfoPng_cleanup(LodePNG_InfoPng* info)
+{
+ LodePNG_InfoColor_cleanup(&info->color);
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ LodePNG_Text_cleanup(&info->text);
+ LodePNG_IText_cleanup(&info->itext);
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ LodePNG_UnknownChunks_cleanup(&info->unknown_chunks);
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+}
+
+unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng* dest, const LodePNG_InfoPng* source)
+{
+ unsigned error = 0;
+ LodePNG_InfoPng_cleanup(dest);
+ *dest = *source;
+ LodePNG_InfoColor_init(&dest->color);
+ error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error;
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ error = LodePNG_Text_copy(&dest->text, &source->text); if(error) return error;
+ error = LodePNG_IText_copy(&dest->itext, &source->itext); if(error) return error;
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ LodePNG_UnknownChunks_init(&dest->unknown_chunks);
+ error = LodePNG_UnknownChunks_copy(&dest->unknown_chunks, &source->unknown_chunks); if(error) return error;
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ return error;
+}
+
+void LodePNG_InfoPng_swap(LodePNG_InfoPng* a, LodePNG_InfoPng* b)
+{
+ LodePNG_InfoPng temp = *a;
+ *a = *b;
+ *b = temp;
+}
+
+unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor* dest, const LodePNG_InfoColor* source)
+{
+ size_t i;
+ LodePNG_InfoColor_cleanup(dest);
+ *dest = *source;
+ dest->palette = (unsigned char*)malloc(source->palettesize * 4);
+ if(!dest->palette && source->palettesize) return 9935;
+ for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i];
+ return 0;
+}
+
+void LodePNG_InfoRaw_init(LodePNG_InfoRaw* info)
+{
+ LodePNG_InfoColor_init(&info->color);
+}
+
+void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw* info)
+{
+ LodePNG_InfoColor_cleanup(&info->color);
+}
+
+unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw* dest, const LodePNG_InfoRaw* source)
+{
+ unsigned error = 0;
+ LodePNG_InfoRaw_cleanup(dest);
+ *dest = *source;
+ LodePNG_InfoColor_init(&dest->color);
+ error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error;
+ return error;
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*
+converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code
+the out buffer must have (w * h * bpp + 7) / 8 bytes, where bpp is the bits per pixel of the output color type (LodePNG_InfoColor_getBpp)
+for < 8 bpp images, there may _not_ be padding bits at the end of scanlines.
+*/
+unsigned LodePNG_convert(unsigned char* out, const unsigned char* in, LodePNG_InfoColor* infoOut, LodePNG_InfoColor* infoIn, unsigned w, unsigned h)
+{
+ const size_t numpixels = w * h; /*amount of pixels*/
+ const unsigned OUT_BYTES = LodePNG_InfoColor_getBpp(infoOut) / 8; /*bytes per pixel in the output image*/
+ const unsigned OUT_ALPHA = LodePNG_InfoColor_isAlphaType(infoOut); /*use 8-bit alpha channel*/
+ size_t i, c, bp = 0; /*bitpointer, used by less-than-8-bit color types*/
+
+ /*cases where in and out already have the same format*/
+ if(LodePNG_InfoColor_equal(infoIn, infoOut))
+ {
+ size_t i, size = (w * h * LodePNG_InfoColor_getBpp(infoIn) + 7) / 8;
+ for(i = 0; i < size; i++) out[i] = in[i];
+ return 0;
+ }
+
+ if((infoOut->colorType == 2 || infoOut->colorType == 6) && infoOut->bitDepth == 8)
+ {
+ if(infoIn->bitDepth == 8)
+ {
+ switch(infoIn->colorType)
+ {
+ case 0: /*greyscale color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[i];
+ if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
+ }
+ break;
+ case 2: /*RGB color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[3 * i + c];
+ if(OUT_ALPHA && infoIn->key_defined == 1 && in[3 * i + 0] == infoIn->key_r && in[3 * i + 1] == infoIn->key_g && in[3 * i + 2] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
+ }
+ break;
+ case 3: /*indexed color (palette)*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ if(in[i] >= infoIn->palettesize) return 46;
+ for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * in[i] + c]; /*get rgb colors from the palette*/
+ }
+ break;
+ case 4: /*greyscale with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i + 0];
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[2 * i + 1];
+ }
+ break;
+ case 6: /*RGB with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[4 * i + c];
+ }
+ break;
+ default: break;
+ }
+ }
+ else if(infoIn->bitDepth == 16)
+ {
+ switch(infoIn->colorType)
+ {
+ case 0: /*greyscale color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i];
+ if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
+ }
+ break;
+ case 2: /*RGB color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[6 * i + 2 * c];
+ if(OUT_ALPHA && infoIn->key_defined && 256U * in[6 * i + 0] + in[6 * i + 1] == infoIn->key_r && 256U * in[6 * i + 2] + in[6 * i + 3] == infoIn->key_g && 256U * in[6 * i + 4] + in[6 * i + 5] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
+ }
+ break;
+ case 4: /*greyscale with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[4 * i]; /*most significant byte*/
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[4 * i + 2];
+ }
+ break;
+ case 6: /*RGB with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[8 * i + 2 * c];
+ }
+ break;
+ default: break;
+ }
+ }
+ else /*infoIn->bitDepth is less than 8 bit per channel*/
+ {
+ switch(infoIn->colorType)
+ {
+ case 0: /*greyscale color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 3] = 0;
+ value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
+ out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = (unsigned char)(value);
+ }
+ break;
+ case 3: /*indexed color (palette)*/
+ for(i = 0; i < numpixels; i++)
+ {
+ unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
+ if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
+ if(value >= infoIn->palettesize) return 47;
+ for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * value + c]; /*get rgb colors from the palette*/
+ }
+ break;
+ default: break;
+ }
+ }
+ }
+ else if(LodePNG_InfoColor_isGreyscaleType(infoOut) && infoOut->bitDepth == 8) /*conversion from greyscale to greyscale*/
+ {
+ if(!LodePNG_InfoColor_isGreyscaleType(infoIn)) return 62;
+ if(infoIn->bitDepth == 8)
+ {
+ switch(infoIn->colorType)
+ {
+ case 0: /*greyscale color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
+ out[OUT_BYTES * i] = in[i];
+ if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
+ }
+ break;
+ case 4: /*greyscale with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ out[OUT_BYTES * i + 0] = in[2 * i + 0];
+ if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[2 * i + 1];
+ }
+ break;
+ default: return 31;
+ }
+ }
+ else if(infoIn->bitDepth == 16)
+ {
+ switch(infoIn->colorType)
+ {
+ case 0: /*greyscale color*/
+ for(i = 0; i < numpixels; i++)
+ {
+ if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
+ out[OUT_BYTES * i] = in[2 * i];
+ if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
+ }
+ break;
+ case 4: /*greyscale with alpha*/
+ for(i = 0; i < numpixels; i++)
+ {
+ out[OUT_BYTES * i] = in[4 * i]; /*most significant byte*/
+ if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[4 * i + 2]; /*most significant byte*/
+ }
+ break;
+ default: return 31;
+ }
+ }
+ else /*infoIn->bitDepth is less than 8 bit per channel*/
+ {
+ if(infoIn->colorType != 0) return 31; /*colorType 0 is the only greyscale type with < 8 bits per channel*/
+ for(i = 0; i < numpixels; i++)
+ {
+ unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
+ if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
+ if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 1] = 0;
+ value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
+ out[OUT_BYTES * i] = (unsigned char)(value);
+ }
+ }
+ }
+ else return 59;
+
+ return 0;
+}
+
+/*Paeth predicter, used by PNG filter type 4*/
+static int paethPredictor(int a, int b, int c)
+{
+ int p = a + b - c;
+ int pa = p > a ? p - a : a - p;
+ int pb = p > b ? p - b : b - p;
+ int pc = p > c ? p - c : c - p;
+
+ if(pa <= pb && pa <= pc) return a;
+ else if(pb <= pc) return b;
+ else return c;
+}
+
+/*shared values used by multiple Adam7 related functions*/
+
+static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
+static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
+static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
+static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
+
+static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
+{
+ /*the passstart values have 8 values: the 8th one actually indicates the byte after the end of the 7th (= last) pass*/
+ unsigned i;
+
+ /*calculate width and height in pixels of each pass*/
+ for(i = 0; i < 7; i++)
+ {
+ passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
+ passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
+ if(passw[i] == 0) passh[i] = 0;
+ if(passh[i] == 0) passw[i] = 0;
+ }
+
+ filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
+ for(i = 0; i < 7; i++)
+ {
+ filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/
+ padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); /*bits padded if needed to fill full byte at end of each scanline*/
+ passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; /*only padded at end of reduced image*/
+ }
+}
+
+#ifdef LODEPNG_COMPILE_DECODER
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / PNG Decoder / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*read the information from the header and store it in the LodePNG_Info. return value is error*/
+void LodePNG_inspect(LodePNG_Decoder* decoder, const unsigned char* in, size_t inlength)
+{
+ if(inlength == 0 || in == 0) { decoder->error = 48; return; } /*the given data is empty*/
+ if(inlength < 29) { decoder->error = 27; return; } /*error: the data length is smaller than the length of the header*/
+
+ /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/
+ LodePNG_InfoPng_cleanup(&decoder->infoPng);
+ LodePNG_InfoPng_init(&decoder->infoPng);
+ decoder->error = 0;
+
+ if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { decoder->error = 28; return; } /*error: the first 8 bytes are not the correct PNG signature*/
+ if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { decoder->error = 29; return; } /*error: it doesn't start with a IHDR chunk!*/
+
+ /*read the values given in the header*/
+ decoder->infoPng.width = LodePNG_read32bitInt(&in[16]);
+ decoder->infoPng.height = LodePNG_read32bitInt(&in[20]);
+ decoder->infoPng.color.bitDepth = in[24];
+ decoder->infoPng.color.colorType = in[25];
+ decoder->infoPng.compressionMethod = in[26];
+ decoder->infoPng.filterMethod = in[27];
+ decoder->infoPng.interlaceMethod = in[28];
+
+ if(!decoder->settings.ignoreCrc)
+ {
+ unsigned CRC = LodePNG_read32bitInt(&in[29]);
+ unsigned checksum = Crc32_crc(&in[12], 17);
+ if(CRC != checksum) { decoder->error = 57; return; }
+ }
+
+ if(decoder->infoPng.compressionMethod != 0) { decoder->error = 32; return; } /*error: only compression method 0 is allowed in the specification*/
+ if(decoder->infoPng.filterMethod != 0) { decoder->error = 33; return; } /*error: only filter method 0 is allowed in the specification*/
+ if(decoder->infoPng.interlaceMethod > 1) { decoder->error = 34; return; } /*error: only interlace methods 0 and 1 exist in the specification*/
+
+ decoder->error = checkColorValidity(decoder->infoPng.color.colorType, decoder->infoPng.color.bitDepth);
+}
+
+static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, size_t bytewidth, unsigned char filterType, size_t length)
+{
+ /*
+ For PNG filter method 0
+ unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, the filter works byte per byte (bytewidth = 1)
+ precon is the previous unfiltered scanline, recon the result, scanline the current one
+ the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
+ recon and scanline MAY be the same memory address! precon must be disjoint.
+ */
+
+ size_t i;
+ switch(filterType)
+ {
+ case 0:
+ for(i = 0; i < length; i++) recon[i] = scanline[i];
+ break;
+ case 1:
+ for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth];
+ break;
+ case 2:
+ if(precon) for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i];
+ else for(i = 0; i < length; i++) recon[i] = scanline[i];
+ break;
+ case 3:
+ if(precon)
+ {
+ for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2;
+ for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
+ }
+ else
+ {
+ for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
+ }
+ break;
+ case 4:
+ if(precon)
+ {
+ for(i = 0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(0, precon[i], 0));
+ for(i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
+ }
+ else
+ {
+ for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], 0, 0));
+ }
+ break;
+ default: return 36; /*error: unexisting filter type given*/
+ }
+ return 0;
+}
+
+static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
+{
+ /*
+ For PNG filter method 0
+ this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 it's called 7 times)
+ out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline
+ w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel
+ in and out are allowed to be the same memory address!
+ */
+
+ unsigned y;
+ unsigned char* prevline = 0;
+
+ size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
+ size_t linebytes = (w * bpp + 7) / 8;
+
+ for(y = 0; y < h; y++)
+ {
+ size_t outindex = linebytes * y;
+ size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
+ unsigned char filterType = in[inindex];
+
+ unsigned error = unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes);
+ if(error) return error;
+
+ prevline = &out[outindex];
+ }
+
+ return 0;
+}
+
+static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
+{
+ /*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding
+ out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation (because that's likely a little bit faster)*/
+ unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
+ unsigned i;
+
+ Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
+
+ if(bpp >= 8)
+ {
+ for(i = 0; i < 7; i++)
+ {
+ unsigned x, y, b;
+ size_t bytewidth = bpp / 8;
+ for(y = 0; y < passh[i]; y++)
+ for(x = 0; x < passw[i]; x++)
+ {
+ size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth;
+ size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
+ for(b = 0; b < bytewidth; b++)
+ {
+ out[pixeloutstart + b] = in[pixelinstart + b];
+ }
+ }
+ }
+ }
+ else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
+ {
+ for(i = 0; i < 7; i++)
+ {
+ unsigned x, y, b;
+ unsigned ilinebits = bpp * passw[i];
+ unsigned olinebits = bpp * w;
+ size_t obp, ibp; /*bit pointers (for out and in buffer)*/
+ for(y = 0; y < passh[i]; y++)
+ for(x = 0; x < passw[i]; x++)
+ {
+ ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
+ obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
+ for(b = 0; b < bpp; b++)
+ {
+ unsigned char bit = readBitFromReversedStream(&ibp, in);
+ setBitOfReversedStream0(&obp, out, bit); /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/
+ }
+ }
+ }
+ }
+}
+
+static void removePaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h)
+{
+ /*
+ After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers for the Adam7 code, the color convert code and the output to the user.
+ in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits
+ also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7
+ only useful if (ilinebits - olinebits) is a value in the range 1..7
+ */
+ unsigned y;
+ size_t diff = ilinebits - olinebits;
+ size_t obp = 0, ibp = 0; /*bit pointers*/
+ for(y = 0; y < h; y++)
+ {
+ size_t x;
+ for(x = 0; x < olinebits; x++)
+ {
+ unsigned char bit = readBitFromReversedStream(&ibp, in);
+ setBitOfReversedStream(&obp, out, bit);
+ }
+ ibp += diff;
+ }
+}
+
+/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from the IDAT chunks*/
+static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, const LodePNG_InfoPng* infoPng) /*return value is error*/
+{
+ /*
+ This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. Steps:
+ *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8)
+ *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace
+ NOTE: the in buffer will be overwritten with intermediate data!
+ */
+ unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color);
+ unsigned w = infoPng->width;
+ unsigned h = infoPng->height;
+ unsigned error = 0;
+ if(bpp == 0) return 31; /*error: invalid colortype*/
+
+ if(infoPng->interlaceMethod == 0)
+ {
+ if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
+ {
+ error = unfilter(in, in, w, h, bpp);
+ if(error) return error;
+ removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h);
+ }
+ else error = unfilter(out, in, w, h, bpp); /*we can immediatly filter into the out buffer, no other steps needed*/
+ }
+ else /*interlaceMethod is 1 (Adam7)*/
+ {
+ unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
+ unsigned i;
+
+ Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
+
+ for(i = 0; i < 7; i++)
+ {
+ error = unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp);
+ if(error) return error;
+ if(bpp < 8) /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, move bytes instead of bits or move not at all*/
+ {
+ /*remove padding bits in scanlines; after this there still may be padding bits between the different reduced images: each reduced image still starts nicely at a byte*/
+ removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7) / 8) * 8, passh[i]);
+ }
+ }
+
+ Adam7_deinterlace(out, in, w, h, bpp);
+ }
+
+ return error;
+}
+
+/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/
+static void decodeGeneric(LodePNG_Decoder* decoder, unsigned char** out, size_t* outsize, const unsigned char* in, size_t size)
+{
+ unsigned char IEND = 0;
+ const unsigned char* chunk;
+ size_t i;
+ ucvector idat; /*the data from idat chunks*/
+
+ /*for unknown chunk order*/
+ unsigned unknown = 0;
+ unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/
+
+ /*provide some proper output values if error will happen*/
+ *out = 0;
+ *outsize = 0;
+
+ if(size == 0 || in == 0) { decoder->error = 48; return; } /*the given data is empty*/
+
+ LodePNG_inspect(decoder, in, size); /*reads header and resets other parameters in decoder->infoPng*/
+ if(decoder->error) return;
+
+ ucvector_init(&idat);
+
+ chunk = &in[33]; /*first byte of the first chunk after the header*/
+
+ while(!IEND) /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer*/
+ {
+ unsigned chunkLength;
+ const unsigned char* data; /*the data in the chunk*/
+
+ if((size_t)((chunk - in) + 12) > size || chunk < in) { decoder->error = 30; break; } /*error: size of the in buffer too small to contain next chunk*/
+ chunkLength = LodePNG_chunk_length(chunk); /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/
+ if(chunkLength > 2147483647) { decoder->error = 63; break; }
+ if((size_t)((chunk - in) + chunkLength + 12) > size || (chunk + chunkLength + 12) < in) { decoder->error = 35; break; } /*error: size of the in buffer too small to contain next chunk*/
+ data = LodePNG_chunk_data_const(chunk);
+
+ /*IDAT chunk, containing compressed image data*/
+ if(LodePNG_chunk_type_equals(chunk, "IDAT"))
+ {
+ size_t oldsize = idat.size;
+ if(!ucvector_resize(&idat, oldsize + chunkLength)) { decoder->error = 9936; break; }
+ for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i];
+ critical_pos = 3;
+ }
+ /*IEND chunk*/
+ else if(LodePNG_chunk_type_equals(chunk, "IEND"))
+ {
+ IEND = 1;
+ }
+ /*palette chunk (PLTE)*/
+ else if(LodePNG_chunk_type_equals(chunk, "PLTE"))
+ {
+ unsigned pos = 0;
+ if(decoder->infoPng.color.palette) free(decoder->infoPng.color.palette);
+ decoder->infoPng.color.palettesize = chunkLength / 3;
+ decoder->infoPng.color.palette = (unsigned char*)malloc(4 * decoder->infoPng.color.palettesize);
+ if(!decoder->infoPng.color.palette && decoder->infoPng.color.palettesize) { decoder->error = 9937; break; }
+ if(!decoder->infoPng.color.palette) decoder->infoPng.color.palettesize = 0; /*malloc failed...*/
+ if(decoder->infoPng.color.palettesize > 256) { decoder->error = 38; break; } /*error: palette too big*/
+ for(i = 0; i < decoder->infoPng.color.palettesize; i++)
+ {
+ decoder->infoPng.color.palette[4 * i + 0] = data[pos++]; /*R*/
+ decoder->infoPng.color.palette[4 * i + 1] = data[pos++]; /*G*/
+ decoder->infoPng.color.palette[4 * i + 2] = data[pos++]; /*B*/
+ decoder->infoPng.color.palette[4 * i + 3] = 255; /*alpha*/
+ }
+ critical_pos = 2;
+ }
+ /*palette transparency chunk (tRNS)*/
+ else if(LodePNG_chunk_type_equals(chunk, "tRNS"))
+ {
+ if(decoder->infoPng.color.colorType == 3)
+ {
+ if(chunkLength > decoder->infoPng.color.palettesize) { decoder->error = 39; break; } /*error: more alpha values given than there are palette entries*/
+ for(i = 0; i < chunkLength; i++) decoder->infoPng.color.palette[4 * i + 3] = data[i];
+ }
+ else if(decoder->infoPng.color.colorType == 0)
+ {
+ if(chunkLength != 2) { decoder->error = 40; break; } /*error: this chunk must be 2 bytes for greyscale image*/
+ decoder->infoPng.color.key_defined = 1;
+ decoder->infoPng.color.key_r = decoder->infoPng.color.key_g = decoder->infoPng.color.key_b = 256 * data[0] + data[1];
+ }
+ else if(decoder->infoPng.color.colorType == 2)
+ {
+ if(chunkLength != 6) { decoder->error = 41; break; } /*error: this chunk must be 6 bytes for RGB image*/
+ decoder->infoPng.color.key_defined = 1;
+ decoder->infoPng.color.key_r = 256 * data[0] + data[1];
+ decoder->infoPng.color.key_g = 256 * data[2] + data[3];
+ decoder->infoPng.color.key_b = 256 * data[4] + data[5];
+ }
+ else { decoder->error = 42; break; } /*error: tRNS chunk not allowed for other color models*/
+ }
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ /*background color chunk (bKGD)*/
+ else if(LodePNG_chunk_type_equals(chunk, "bKGD"))
+ {
+ if(decoder->infoPng.color.colorType == 3)
+ {
+ if(chunkLength != 1) { decoder->error = 43; break; } /*error: this chunk must be 1 byte for indexed color image*/
+ decoder->infoPng.background_defined = 1;
+ decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_g = data[0];
+ }
+ else if(decoder->infoPng.color.colorType == 0 || decoder->infoPng.color.colorType == 4)
+ {
+ if(chunkLength != 2) { decoder->error = 44; break; } /*error: this chunk must be 2 bytes for greyscale image*/
+ decoder->infoPng.background_defined = 1;
+ decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_b = 256 * data[0] + data[1];
+ }
+ else if(decoder->infoPng.color.colorType == 2 || decoder->infoPng.color.colorType == 6)
+ {
+ if(chunkLength != 6) { decoder->error = 45; break; } /*error: this chunk must be 6 bytes for greyscale image*/
+ decoder->infoPng.background_defined = 1;
+ decoder->infoPng.background_r = 256 * data[0] + data[1];
+ decoder->infoPng.background_g = 256 * data[2] + data[3];
+ decoder->infoPng.background_b = 256 * data[4] + data[5];
+ }
+ }
+ /*text chunk (tEXt)*/
+ else if(LodePNG_chunk_type_equals(chunk, "tEXt"))
+ {
+ if(decoder->settings.readTextChunks)
+ {
+ char *key = 0, *str = 0;
+
+ while(!decoder->error) /*not really a while loop, only used to break on error*/
+ {
+ unsigned length, string2_begin;
+
+ for(length = 0; length < chunkLength && data[length] != 0; length++) ;
+ if(length + 1 >= chunkLength) { decoder->error = 75; break; }
+ key = (char*)malloc(length + 1);
+ if(!key) { decoder->error = 9938; break; }
+ key[length] = 0;
+ for(i = 0; i < length; i++) key[i] = data[i];
+
+ string2_begin = length + 1;
+ if(string2_begin > chunkLength) { decoder->error = 75; break; }
+ length = chunkLength - string2_begin;
+ str = (char*)malloc(length + 1);
+ if(!str) { decoder->error = 9939; break; }
+ str[length] = 0;
+ for(i = 0; i < length; i++) str[i] = data[string2_begin + i];
+
+ decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, str);
+
+ break;
+ }
+
+ free(key);
+ free(str);
+ }
+ }
+ /*compressed text chunk (zTXt)*/
+ else if(LodePNG_chunk_type_equals(chunk, "zTXt"))
+ {
+ if(decoder->settings.readTextChunks)
+ {
+ unsigned length, string2_begin;
+ char *key = 0;
+ ucvector decoded;
+
+ ucvector_init(&decoded);
+
+ while(!decoder->error) /*not really a while loop, only used to break on error*/
+ {
+ for(length = 0; length < chunkLength && data[length] != 0; length++) ;
+ if(length + 2 >= chunkLength) { decoder->error = 75; break; }
+ key = (char*)malloc(length + 1);
+ if(!key) { decoder->error = 9940; break; }
+ key[length] = 0;
+ for(i = 0; i < length; i++) key[i] = data[i];
+
+ if(data[length + 1] != 0) { decoder->error = 72; break; } /*the 0 byte indicating compression must be 0*/
+
+ string2_begin = length + 2;
+ if(string2_begin > chunkLength) { decoder->error = 75; break; }
+ length = chunkLength - string2_begin;
+ decoder->error = LodePNG_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[string2_begin]), length, &decoder->settings.zlibsettings);
+ if(decoder->error) break;
+ ucvector_push_back(&decoded, 0);
+
+ decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, (char*)decoded.data);
+
+ break;
+ }
+
+ free(key);
+ ucvector_cleanup(&decoded);
+ if(decoder->error) break;
+ }
+ }
+ /*international text chunk (iTXt)*/
+ else if(LodePNG_chunk_type_equals(chunk, "iTXt"))
+ {
+ if(decoder->settings.readTextChunks)
+ {
+ unsigned length, begin, compressed;
+ char *key = 0, *langtag = 0, *transkey = 0;
+ ucvector decoded;
+ ucvector_init(&decoded);
+
+ while(!decoder->error) /*not really a while loop, only used to break on error*/
+ {
+ if(chunkLength < 5) { decoder->error = 76; break; }
+ for(length = 0; length < chunkLength && data[length] != 0; length++) ;
+ if(length + 2 >= chunkLength) { decoder->error = 75; break; }
+ key = (char*)malloc(length + 1);
+ if(!key) { decoder->error = 9941; break; }
+ key[length] = 0;
+ for(i = 0; i < length; i++) key[i] = data[i];
+
+ compressed = data[length + 1];
+ if(data[length + 2] != 0) { decoder->error = 72; break; } /*the 0 byte indicating compression must be 0*/
+
+ begin = length + 3;
+ length = 0;
+ for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
+ if(begin + length + 1 >= chunkLength) { decoder->error = 75; break; }
+ langtag = (char*)malloc(length + 1);
+ if(!langtag) { decoder->error = 9942; break; }
+ langtag[length] = 0;
+ for(i = 0; i < length; i++) langtag[i] = data[begin + i];
+
+ begin += length + 1;
+ length = 0;
+ for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
+ if(begin + length + 1 >= chunkLength) { decoder->error = 75; break; }
+ transkey = (char*)malloc(length + 1);
+ if(!transkey) { decoder->error = 9943; break; }
+ transkey[length] = 0;
+ for(i = 0; i < length; i++) transkey[i] = data[begin + i];
+
+ begin += length + 1;
+ if(begin > chunkLength) { decoder->error = 75; break; }
+ length = chunkLength - begin;
+
+ if(compressed)
+ {
+ decoder->error = LodePNG_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[begin]), length, &decoder->settings.zlibsettings);
+ if(decoder->error) break;
+ ucvector_push_back(&decoded, 0);
+ }
+ else
+ {
+ if(!ucvector_resize(&decoded, length + 1)) { decoder->error = 9944; break; }
+ decoded.data[length] = 0;
+ for(i = 0; i < length; i++) decoded.data[i] = data[begin + i];
+ }
+
+ decoder->error = LodePNG_IText_add(&decoder->infoPng.itext, key, langtag, transkey, (char*)decoded.data);
+
+ break;
+ }
+
+ free(key);
+ free(langtag);
+ free(transkey);
+ ucvector_cleanup(&decoded);
+ if(decoder->error) break;
+ }
+ }
+ else if(LodePNG_chunk_type_equals(chunk, "tIME"))
+ {
+ if(chunkLength != 7) { decoder->error = 73; break; }
+ decoder->infoPng.time_defined = 1;
+ decoder->infoPng.time.year = 256 * data[0] + data[+ 1];
+ decoder->infoPng.time.month = data[2];
+ decoder->infoPng.time.day = data[3];
+ decoder->infoPng.time.hour = data[4];
+ decoder->infoPng.time.minute = data[5];
+ decoder->infoPng.time.second = data[6];
+ }
+ else if(LodePNG_chunk_type_equals(chunk, "pHYs"))
+ {
+ if(chunkLength != 9) { decoder->error = 74; break; }
+ decoder->infoPng.phys_defined = 1;
+ decoder->infoPng.phys_x = 16777216 * data[0] + 65536 * data[1] + 256 * data[2] + data[3];
+ decoder->infoPng.phys_y = 16777216 * data[4] + 65536 * data[5] + 256 * data[6] + data[7];
+ decoder->infoPng.phys_unit = data[8];
+ }
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+ else /*it's not an implemented chunk type, so ignore it: skip over the data*/
+ {
+ if(LodePNG_chunk_critical(chunk)) { decoder->error = 69; break; } /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/
+ unknown = 1;
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ if(decoder->settings.rememberUnknownChunks)
+ {
+ LodePNG_UnknownChunks* unknown = &decoder->infoPng.unknown_chunks;
+ decoder->error = LodePNG_append_chunk(&unknown->data[critical_pos - 1], &unknown->datasize[critical_pos - 1], chunk);
+ if(decoder->error) break;
+ }
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ }
+
+ if(!decoder->settings.ignoreCrc && !unknown) /*check CRC if wanted, only on known chunk types*/
+ {
+ if(LodePNG_chunk_check_crc(chunk)) { decoder->error = 57; break; }
+ }
+
+ if(!IEND) chunk = LodePNG_chunk_next_const(chunk);
+ }
+
+ if(!decoder->error)
+ {
+ ucvector scanlines;
+ ucvector_init(&scanlines);
+ if(!ucvector_resize(&scanlines, ((decoder->infoPng.width * (decoder->infoPng.height * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7)) / 8) + decoder->infoPng.height)) decoder->error = 9945; /*maximum final image length is already reserved in the vector's length - this is not really necessary*/
+ if(!decoder->error) decoder->error = LodePNG_decompress(&scanlines.data, &scanlines.size, idat.data, idat.size, &decoder->settings.zlibsettings); /*decompress with the Zlib decompressor*/
+
+ if(!decoder->error)
+ {
+ ucvector outv;
+ ucvector_init(&outv);
+ if(!ucvector_resizev(&outv, (decoder->infoPng.height * decoder->infoPng.width * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8, 0)) decoder->error = 9946;
+ if(!decoder->error) decoder->error = postProcessScanlines(outv.data, scanlines.data, &decoder->infoPng);
+ *out = outv.data;
+ *outsize = outv.size;
+ }
+ ucvector_cleanup(&scanlines);
+ }
+
+ ucvector_cleanup(&idat);
+}
+
+void LodePNG_decode(LodePNG_Decoder* decoder, unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize)
+{
+ *out = 0;
+ *outsize = 0;
+ decodeGeneric(decoder, out, outsize, in, insize);
+ if(decoder->error) return;
+ if(!decoder->settings.color_convert || LodePNG_InfoColor_equal(&decoder->infoRaw.color, &decoder->infoPng.color))
+ {
+ /*same color type, no copying or converting of data needed*/
+ /*store the infoPng color settings on the infoRaw so that the infoRaw still reflects what colorType
+ the raw image has to the end user*/
+ if(!decoder->settings.color_convert)
+ {
+ decoder->error = LodePNG_InfoColor_copy(&decoder->infoRaw.color, &decoder->infoPng.color);
+ if(decoder->error) return;
+ }
+ }
+ else
+ {
+ /*color conversion needed; sort of copy of the data*/
+ unsigned char* data = *out;
+
+ /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/
+ if(!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56; return; }
+
+ *outsize = (decoder->infoPng.width * decoder->infoPng.height * LodePNG_InfoColor_getBpp(&decoder->infoRaw.color) + 7) / 8;
+ *out = (unsigned char*)malloc(*outsize);
+ if(!(*out))
+ {
+ decoder->error = 9947;
+ *outsize = 0;
+ }
+ else decoder->error = LodePNG_convert(*out, data, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height);
+ free(data);
+ }
+}
+
+unsigned LodePNG_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize)
+{
+ unsigned error;
+ size_t dummy_size;
+ LodePNG_Decoder decoder;
+ LodePNG_Decoder_init(&decoder);
+ LodePNG_decode(&decoder, out, &dummy_size, in, insize);
+ error = decoder.error;
+ *w = decoder.infoPng.width;
+ *h = decoder.infoPng.height;
+ LodePNG_Decoder_cleanup(&decoder);
+ return error;
+}
+
+#ifdef LODEPNG_COMPILE_DISK
+unsigned LodePNG_decode32f(unsigned char** out, unsigned* w, unsigned* h, const char* filename)
+{
+ unsigned char* buffer;
+ size_t buffersize;
+ unsigned error;
+ error = LodePNG_loadFile(&buffer, &buffersize, filename);
+ if(!error) error = LodePNG_decode32(out, w, h, buffer, buffersize);
+ free(buffer);
+ return error;
+}
+#endif /*LODEPNG_COMPILE_DISK*/
+
+void LodePNG_DecodeSettings_init(LodePNG_DecodeSettings* settings)
+{
+ settings->color_convert = 1;
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ settings->readTextChunks = 1;
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+ settings->ignoreCrc = 0;
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ settings->rememberUnknownChunks = 0;
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ LodeZlib_DecompressSettings_init(&settings->zlibsettings);
+}
+
+void LodePNG_Decoder_init(LodePNG_Decoder* decoder)
+{
+ LodePNG_DecodeSettings_init(&decoder->settings);
+ LodePNG_InfoRaw_init(&decoder->infoRaw);
+ LodePNG_InfoPng_init(&decoder->infoPng);
+ decoder->error = 1;
+}
+
+void LodePNG_Decoder_cleanup(LodePNG_Decoder* decoder)
+{
+ LodePNG_InfoRaw_cleanup(&decoder->infoRaw);
+ LodePNG_InfoPng_cleanup(&decoder->infoPng);
+}
+
+void LodePNG_Decoder_copy(LodePNG_Decoder* dest, const LodePNG_Decoder* source)
+{
+ LodePNG_Decoder_cleanup(dest);
+ *dest = *source;
+ LodePNG_InfoRaw_init(&dest->infoRaw);
+ LodePNG_InfoPng_init(&dest->infoPng);
+ dest->error = LodePNG_InfoRaw_copy(&dest->infoRaw, &source->infoRaw); if(dest->error) return;
+ dest->error = LodePNG_InfoPng_copy(&dest->infoPng, &source->infoPng); if(dest->error) return;
+}
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / PNG Encoder / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*chunkName must be string of 4 characters*/
+static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length)
+{
+ unsigned error = LodePNG_create_chunk(&out->data, &out->size, (unsigned)length, chunkName, data);
+ if(error) return error;
+ out->allocsize = out->size; /*fix the allocsize again*/
+ return 0;
+}
+
+static void writeSignature(ucvector* out)
+{
+ /*8 bytes PNG signature*/
+ ucvector_push_back(out, 137);
+ ucvector_push_back(out, 80);
+ ucvector_push_back(out, 78);
+ ucvector_push_back(out, 71);
+ ucvector_push_back(out, 13);
+ ucvector_push_back(out, 10);
+ ucvector_push_back(out, 26);
+ ucvector_push_back(out, 10);
+}
+
+static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, unsigned bitDepth, unsigned colorType, unsigned interlaceMethod)
+{
+ unsigned error = 0;
+ ucvector header;
+ ucvector_init(&header);
+
+ LodePNG_add32bitInt(&header, w); /*width*/
+ LodePNG_add32bitInt(&header, h); /*height*/
+ ucvector_push_back(&header, (unsigned char)bitDepth); /*bit depth*/
+ ucvector_push_back(&header, (unsigned char)colorType); /*color type*/
+ ucvector_push_back(&header, 0); /*compression method*/
+ ucvector_push_back(&header, 0); /*filter method*/
+ ucvector_push_back(&header, interlaceMethod); /*interlace method*/
+
+ error = addChunk(out, "IHDR", header.data, header.size);
+ ucvector_cleanup(&header);
+
+ return error;
+}
+
+static unsigned addChunk_PLTE(ucvector* out, const LodePNG_InfoColor* info)
+{
+ unsigned error = 0;
+ size_t i;
+ ucvector PLTE;
+ ucvector_init(&PLTE);
+ for(i = 0; i < info->palettesize * 4; i++) if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); /*add all channels except alpha channel*/
+ error = addChunk(out, "PLTE", PLTE.data, PLTE.size);
+ ucvector_cleanup(&PLTE);
+
+ return error;
+}
+
+static unsigned addChunk_tRNS(ucvector* out, const LodePNG_InfoColor* info)
+{
+ unsigned error = 0;
+ size_t i;
+ ucvector tRNS;
+ ucvector_init(&tRNS);
+ if(info->colorType == 3)
+ {
+ for(i = 0; i < info->palettesize; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); /*add only alpha channel*/
+ }
+ else if(info->colorType == 0)
+ {
+ if(info->key_defined)
+ {
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
+ }
+ }
+ else if(info->colorType == 2)
+ {
+ if(info->key_defined)
+ {
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256));
+ ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256));
+ }
+ }
+
+ error = addChunk(out, "tRNS", tRNS.data, tRNS.size);
+ ucvector_cleanup(&tRNS);
+
+ return error;
+}
+
+static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, LodeZlib_DeflateSettings* zlibsettings)
+{
+ ucvector zlibdata;
+ unsigned error = 0;
+
+ /*compress with the Zlib compressor*/
+ ucvector_init(&zlibdata);
+ error = LodePNG_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings);
+ if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size);
+ ucvector_cleanup(&zlibdata);
+
+ return error;
+}
+
+static unsigned addChunk_IEND(ucvector* out)
+{
+ unsigned error = 0;
+ error = addChunk(out, "IEND", 0, 0);
+ return error;
+}
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+
+static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) /*add text chunk*/
+{
+ unsigned error = 0;
+ size_t i;
+ ucvector text;
+ ucvector_init(&text);
+ for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]);
+ ucvector_push_back(&text, 0);
+ for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]);
+ error = addChunk(out, "tEXt", text.data, text.size);
+ ucvector_cleanup(&text);
+
+ return error;
+}
+
+static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, LodeZlib_DeflateSettings* zlibsettings)
+{
+ unsigned error = 0;
+ ucvector data, compressed;
+ size_t i, textsize = strlen(textstring);
+
+ ucvector_init(&data);
+ ucvector_init(&compressed);
+ for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
+ ucvector_push_back(&data, 0); /* 0 termination char*/
+ ucvector_push_back(&data, 0); /*compression method: 0*/
+
+ error = LodePNG_compress(&compressed.data, &compressed.size, (unsigned char*)textstring, textsize, zlibsettings);
+ if(!error)
+ {
+ for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]);
+ error = addChunk(out, "zTXt", data.data, data.size);
+ }
+
+ ucvector_cleanup(&compressed);
+ ucvector_cleanup(&data);
+ return error;
+}
+
+static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, const char* transkey, const char* textstring, LodeZlib_DeflateSettings* zlibsettings)
+{
+ unsigned error = 0;
+ ucvector data, compressed_data;
+ size_t i, textsize = strlen(textstring);
+
+ ucvector_init(&data);
+
+ for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
+ ucvector_push_back(&data, 0); /*null termination char*/
+ ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/
+ ucvector_push_back(&data, 0); /*compression method*/
+ for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]);
+ ucvector_push_back(&data, 0); /*null termination char*/
+ for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]);
+ ucvector_push_back(&data, 0); /*null termination char*/
+
+ if(compressed)
+ {
+ ucvector_init(&compressed_data);
+ error = LodePNG_compress(&compressed_data.data, &compressed_data.size, (unsigned char*)textstring, textsize, zlibsettings);
+ if(!error)
+ {
+ for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]);
+ for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]);
+ }
+ }
+ else /*not compressed*/
+ {
+ for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]);
+ }
+
+ if(!error) error = addChunk(out, "iTXt", data.data, data.size);
+ ucvector_cleanup(&data);
+ return error;
+}
+
+static unsigned addChunk_bKGD(ucvector* out, const LodePNG_InfoPng* info)
+{
+ unsigned error = 0;
+ ucvector bKGD;
+ ucvector_init(&bKGD);
+ if(info->color.colorType == 0 || info->color.colorType == 4)
+ {
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
+ }
+ else if(info->color.colorType == 2 || info->color.colorType == 6)
+ {
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256));
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256));
+ }
+ else if(info->color.colorType == 3)
+ {
+ ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/
+ }
+
+ error = addChunk(out, "bKGD", bKGD.data, bKGD.size);
+ ucvector_cleanup(&bKGD);
+
+ return error;
+}
+
+static unsigned addChunk_tIME(ucvector* out, const LodePNG_Time* time)
+{
+ unsigned error = 0;
+ unsigned char* data = (unsigned char*)malloc(7);
+ if(!data) return 9948;
+ data[0] = (unsigned char)(time->year / 256);
+ data[1] = (unsigned char)(time->year % 256);
+ data[2] = time->month;
+ data[3] = time->day;
+ data[4] = time->hour;
+ data[5] = time->minute;
+ data[6] = time->second;
+ error = addChunk(out, "tIME", data, 7);
+ free(data);
+ return error;
+}
+
+static unsigned addChunk_pHYs(ucvector* out, const LodePNG_InfoPng* info)
+{
+ unsigned error = 0;
+ ucvector data;
+ ucvector_init(&data);
+
+ LodePNG_add32bitInt(&data, info->phys_x);
+ LodePNG_add32bitInt(&data, info->phys_y);
+ ucvector_push_back(&data, info->phys_unit);
+
+ error = addChunk(out, "pHYs", data.data, data.size);
+ ucvector_cleanup(&data);
+
+ return error;
+}
+
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, size_t length, size_t bytewidth, unsigned char filterType)
+{
+ size_t i;
+ switch(filterType)
+ {
+ case 0:
+ if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i];
+ else for(i = 0; i < length; i++) out[i] = scanline[i];
+ break;
+ case 1:
+ if(prevline)
+ {
+ for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
+ for(i = bytewidth; i < length ; i++) out[i] = scanline[i] - scanline[i - bytewidth];
+ }
+ else
+ {
+ for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
+ }
+ break;
+ case 2:
+ if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i];
+ else for(i = 0; i < length; i++) out[i] = scanline[i];
+ break;
+ case 3:
+ if(prevline)
+ {
+ for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2;
+ for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
+ }
+ else
+ {
+ for(i = 0; i < length; i++) out[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
+ }
+ break;
+ case 4:
+ if(prevline)
+ {
+ for(i = 0; i < bytewidth; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(0, prevline[i], 0));
+ for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
+ }
+ else
+ {
+ for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
+ for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], 0, 0));
+ }
+ break;
+ default: return; /*unexisting filter type given*/
+ }
+}
+
+static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, const LodePNG_InfoColor* info)
+{
+ /*
+ For PNG filter method 0
+ out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline
+
+ There is a nice heuristic described here: http://www.cs.toronto.edu/~cosmin/pngtech/optipng.html. It says:
+ * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None).
+ * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row.
+
+ Here the above method is used mostly. Note though that it appears to be better to use the adaptive filtering on the plasma 8-bit palette example, but that image isn't the best reference for palette images in general.
+ */
+
+ unsigned bpp = LodePNG_InfoColor_getBpp(info);
+ size_t linebytes = (w * bpp + 7) / 8; /*the width of a scanline in bytes, not including the filter type*/
+ size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
+ const unsigned char* prevline = 0;
+ unsigned x, y;
+ unsigned heuristic;
+ unsigned error = 0;
+
+ if(bpp == 0) return 31; /*invalid color type*/
+
+ /*choose heuristic as described above*/
+ if(info->colorType == 3 || info->bitDepth < 8) heuristic = 0;
+ else heuristic = 1;
+
+ if(heuristic == 0) /*None filtertype for everything*/
+ {
+ for(y = 0; y < h; y++)
+ {
+ size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
+ size_t inindex = linebytes * y;
+ const unsigned TYPE = 0;
+ out[outindex] = TYPE; /*filter type byte*/
+ filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, TYPE);
+ prevline = &in[inindex];
+ }
+ }
+ else if(heuristic == 1) /*adaptive filtering*/
+ {
+ size_t sum[5];
+ ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
+ size_t smallest = 0;
+ unsigned type, bestType = 0;
+
+ for(type = 0; type < 5; type++) ucvector_init(&attempt[type]);
+ for(type = 0; type < 5; type++)
+ {
+ if(!ucvector_resize(&attempt[type], linebytes)) { error = 9949; break; }
+ }
+
+ if(!error)
+ {
+ for(y = 0; y < h; y++)
+ {
+ /*try the 5 filter types*/
+ for(type = 0; type < 5; type++)
+ {
+ filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
+
+ /*calculate the sum of the result*/
+ sum[type] = 0;
+ for(x = 0; x < attempt[type].size; x+=3) sum[type] += attempt[type].data[x]; /*note that not all pixels are checked to speed this up while still having probably the best choice*/
+
+ /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
+ if(type == 0 || sum[type] < smallest)
+ {
+ bestType = type;
+ smallest = sum[type];
+ }
+ }
+
+ prevline = &in[y * linebytes];
+
+ /*now fill the out values*/
+ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
+ for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
+ }
+ }
+
+ for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
+ }
+ #if 0 /*deflate the scanline with a fixed tree after every filter attempt to see which one deflates best. This is slow, and _does not work as expected_: the heuristic gives smaller result!*/
+ else if(heuristic == 2) /*adaptive filtering by using deflate*/
+ {
+ size_t size[5];
+ ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
+ size_t smallest;
+ unsigned type = 0, bestType = 0;
+ unsigned char* dummy;
+ LodeZlib_DeflateSettings deflatesettings = LodeZlib_defaultDeflateSettings;
+ deflatesettings.btype = 1; /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image*/
+ for(type = 0; type < 5; type++) { ucvector_init(&attempt[type]); ucvector_resize(&attempt[type], linebytes); }
+ for(y = 0; y < h; y++) /*try the 5 filter types*/
+ {
+ for(type = 0; type < 5; type++)
+ {
+ filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
+ size[type] = 0; dummy = 0;
+ LodePNG_compress(&dummy, &size[type], attempt[type].data, attempt[type].size, &deflatesettings);
+ free(dummy);
+ /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
+ if(type == 0 || size[type] < smallest) { bestType = type; smallest = size[type]; }
+ }
+ prevline = &in[y * linebytes];
+ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
+ for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
+ }
+ for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
+ }
+ #endif
+
+ return error;
+}
+
+static void addPaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h)
+{
+ /*The opposite of the removePaddingBits function
+ olinebits must be >= ilinebits*/
+ unsigned y;
+ size_t diff = olinebits - ilinebits;
+ size_t obp = 0, ibp = 0; /*bit pointers*/
+ for(y = 0; y < h; y++)
+ {
+ size_t x;
+ for(x = 0; x < ilinebits; x++)
+ {
+ unsigned char bit = readBitFromReversedStream(&ibp, in);
+ setBitOfReversedStream(&obp, out, bit);
+ }
+ /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/
+ for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0);
+ }
+}
+
+static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
+{
+ /*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding*/
+ unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
+ unsigned i;
+
+ Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
+
+ if(bpp >= 8)
+ {
+ for(i = 0; i < 7; i++)
+ {
+ unsigned x, y, b;
+ size_t bytewidth = bpp / 8;
+ for(y = 0; y < passh[i]; y++)
+ for(x = 0; x < passw[i]; x++)
+ {
+ size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
+ size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
+ for(b = 0; b < bytewidth; b++)
+ {
+ out[pixeloutstart + b] = in[pixelinstart + b];
+ }
+ }
+ }
+ }
+ else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
+ {
+ for(i = 0; i < 7; i++)
+ {
+ unsigned x, y, b;
+ unsigned ilinebits = bpp * passw[i];
+ unsigned olinebits = bpp * w;
+ size_t obp, ibp; /*bit pointers (for out and in buffer)*/
+ for(y = 0; y < passh[i]; y++)
+ for(x = 0; x < passw[i]; x++)
+ {
+ ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
+ obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
+ for(b = 0; b < bpp; b++)
+ {
+ unsigned char bit = readBitFromReversedStream(&ibp, in);
+ setBitOfReversedStream(&obp, out, bit);
+ }
+ }
+ }
+ }
+}
+
+/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image*/
+static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, const LodePNG_InfoPng* infoPng) /*return value is error*/
+{
+ /*
+ This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps:
+ *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter
+ *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter
+ */
+ unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color);
+ unsigned w = infoPng->width;
+ unsigned h = infoPng->height;
+ unsigned error = 0;
+
+ if(infoPng->interlaceMethod == 0)
+ {
+ *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/
+ *out = (unsigned char*)malloc(*outsize);
+ if(!(*out) && (*outsize)) error = 9950;
+
+ if(!error)
+ {
+ if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) /*non multiple of 8 bits per scanline, padding bits needed per scanline*/
+ {
+ ucvector padded;
+ ucvector_init(&padded);
+ if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9951;
+ if(!error)
+ {
+ addPaddingBits(padded.data, in, ((w * bpp + 7) / 8) * 8, w * bpp, h);
+ error = filter(*out, padded.data, w, h, &infoPng->color);
+ }
+ ucvector_cleanup(&padded);
+ }
+ else error = filter(*out, in, w, h, &infoPng->color); /*we can immediatly filter into the out buffer, no other steps needed*/
+ }
+ }
+ else /*interlaceMethod is 1 (Adam7)*/
+ {
+ unsigned char* adam7 = (unsigned char*)malloc((h * w * bpp + 7) / 8);
+ if(!adam7 && ((h * w * bpp + 7) / 8)) error = 9952; /*malloc failed*/
+
+ while(!error) /*not a real while loop, used to break out to cleanup to avoid a goto*/
+ {
+ unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
+ unsigned i;
+
+ Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
+
+ *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/
+ *out = (unsigned char*)malloc(*outsize);
+ if(!(*out) && (*outsize)) { error = 9953; break; }
+
+ Adam7_interlace(adam7, in, w, h, bpp);
+
+ for(i = 0; i < 7; i++)
+ {
+ if(bpp < 8)
+ {
+ ucvector padded;
+ ucvector_init(&padded);
+ if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9954;
+ if(!error)
+ {
+ addPaddingBits(&padded.data[padded_passstart[i]], &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
+ error = filter(&(*out)[filter_passstart[i]], &padded.data[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
+ }
+
+ ucvector_cleanup(&padded);
+ }
+ else
+ {
+ error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
+ }
+ }
+
+ break;
+ }
+
+ free(adam7);
+ }
+
+ return error;
+}
+
+/*palette must have 4 * palettesize bytes allocated*/
+static unsigned isPaletteFullyOpaque(const unsigned char* palette, size_t palettesize) /*palette given in format RGBARGBARGBARGBA...*/
+{
+ size_t i;
+ for(i = 0; i < palettesize; i++)
+ {
+ if(palette[4 * i + 3] != 255) return 0;
+ }
+ return 1;
+}
+
+/*this function checks if the input image given by the user has no transparent pixels*/
+static unsigned isFullyOpaque(const unsigned char* image, unsigned w, unsigned h, const LodePNG_InfoColor* info)
+{
+ /*TODO: When the user specified a color key for the input image, then this function must also check for pixels that are the same as the color key and treat those as transparent.*/
+
+ unsigned i, numpixels = w * h;
+ if(info->colorType == 6)
+ {
+ if(info->bitDepth == 8)
+ {
+ for(i = 0; i < numpixels; i++) if(image[i * 4 + 3] != 255) return 0;
+ }
+ else
+ {
+ for(i = 0; i < numpixels; i++) if(image[i * 8 + 6] != 255 || image[i * 8 + 7] != 255) return 0;
+ }
+ return 1; /*no single pixel with alpha channel other than 255 found*/
+ }
+ else if(info->colorType == 4)
+ {
+ if(info->bitDepth == 8)
+ {
+ for(i = 0; i < numpixels; i++) if(image[i * 2 + 1] != 255) return 0;
+ }
+ else
+ {
+ for(i = 0; i < numpixels; i++) if(image[i * 4 + 2] != 255 || image[i * 4 + 3] != 255) return 0;
+ }
+ return 1; /*no single pixel with alpha channel other than 255 found*/
+ }
+ else if(info->colorType == 3)
+ {
+ /*when there's a palette, we could check every pixel for translucency, but much quicker is to just check the palette*/
+ return(isPaletteFullyOpaque(info->palette, info->palettesize));
+ }
+
+ return 0; /*color type that isn't supported by this function yet, so assume there is transparency to be safe*/
+}
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize)
+{
+ unsigned char* inchunk = data;
+ while((size_t)(inchunk - data) < datasize)
+ {
+ unsigned error = LodePNG_append_chunk(&out->data, &out->size, inchunk);
+ if(error) return error; /*error: not enough memory*/
+ out->allocsize = out->size; /*fix the allocsize again*/
+ inchunk = LodePNG_chunk_next(inchunk);
+ }
+ return 0;
+}
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+
+void LodePNG_encode(LodePNG_Encoder* encoder, unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
+{
+ LodePNG_InfoPng info;
+ ucvector outv;
+ unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/
+ size_t datasize = 0;
+
+ /*provide some proper output values if error will happen*/
+ *out = 0;
+ *outsize = 0;
+ encoder->error = 0;
+
+ info = encoder->infoPng; /*UNSAFE copy to avoid having to cleanup! but we will only change primitive parameters, and not invoke the cleanup function nor touch the palette's buffer so we use it safely*/
+ info.width = w;
+ info.height = h;
+
+ if(encoder->settings.autoLeaveOutAlphaChannel && isFullyOpaque(image, w, h, &encoder->infoRaw.color))
+ {
+ /*go to a color type without alpha channel*/
+ if(info.color.colorType == 6) info.color.colorType = 2;
+ else if(info.color.colorType == 4) info.color.colorType = 0;
+ }
+
+ if(encoder->settings.zlibsettings.windowSize > 32768) { encoder->error = 60; return; } /*error: windowsize larger than allowed*/
+ if(encoder->settings.zlibsettings.btype > 2) { encoder->error = 61; return; } /*error: unexisting btype*/
+ if(encoder->infoPng.interlaceMethod > 1) { encoder->error = 71; return; } /*error: unexisting interlace mode*/
+ if((encoder->error = checkColorValidity(info.color.colorType, info.color.bitDepth))) return; /*error: unexisting color type given*/
+ if((encoder->error = checkColorValidity(encoder->infoRaw.color.colorType, encoder->infoRaw.color.bitDepth))) return; /*error: unexisting color type given*/
+
+ if(!LodePNG_InfoColor_equal(&encoder->infoRaw.color, &info.color))
+ {
+ unsigned char* converted;
+ size_t size = (w * h * LodePNG_InfoColor_getBpp(&info.color) + 7) / 8;
+
+ if((info.color.colorType != 6 && info.color.colorType != 2) || (info.color.bitDepth != 8)) { encoder->error = 59; return; } /*for the output image, only these types are supported*/
+ converted = (unsigned char*)malloc(size);
+ if(!converted && size) encoder->error = 9955; /*error: malloc failed*/
+ if(!encoder->error) encoder->error = LodePNG_convert(converted, image, &info.color, &encoder->infoRaw.color, w, h);
+ if(!encoder->error) preProcessScanlines(&data, &datasize, converted, &info);/*filter(data.data, converted.data, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
+ free(converted);
+ }
+ else preProcessScanlines(&data, &datasize, image, &info);/*filter(data.data, image, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
+
+ ucvector_init(&outv);
+ while(!encoder->error) /*not really a while loop, this is only used to break out if an error happens to avoid goto's to do the ucvector cleanup*/
+ {
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ size_t i;
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+ /*write signature and chunks*/
+ writeSignature(&outv);
+ /*IHDR*/
+ addChunk_IHDR(&outv, w, h, info.color.bitDepth, info.color.colorType, info.interlaceMethod);
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ /*unknown chunks between IHDR and PLTE*/
+ if(info.unknown_chunks.data[0]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[0], info.unknown_chunks.datasize[0]); if(encoder->error) break; }
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ /*PLTE*/
+ if(info.color.colorType == 3)
+ {
+ if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
+ addChunk_PLTE(&outv, &info.color);
+ }
+ if(encoder->settings.force_palette && (info.color.colorType == 2 || info.color.colorType == 6))
+ {
+ if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
+ addChunk_PLTE(&outv, &info.color);
+ }
+ /*tRNS*/
+ if(info.color.colorType == 3 && !isPaletteFullyOpaque(info.color.palette, info.color.palettesize)) addChunk_tRNS(&outv, &info.color);
+ if((info.color.colorType == 0 || info.color.colorType == 2) && info.color.key_defined) addChunk_tRNS(&outv, &info.color);
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ /*bKGD (must come between PLTE and the IDAt chunks*/
+ if(info.background_defined) addChunk_bKGD(&outv, &info);
+ /*pHYs (must come before the IDAT chunks)*/
+ if(info.phys_defined) addChunk_pHYs(&outv, &info);
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ /*unknown chunks between PLTE and IDAT*/
+ if(info.unknown_chunks.data[1]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[1], info.unknown_chunks.datasize[1]); if(encoder->error) break; }
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ /*IDAT (multiple IDAT chunks must be consecutive)*/
+ encoder->error = addChunk_IDAT(&outv, data, datasize, &encoder->settings.zlibsettings);
+ if(encoder->error) break;
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ /*tIME*/
+ if(info.time_defined) addChunk_tIME(&outv, &info.time);
+ /*tEXt and/or zTXt*/
+ for(i = 0; i < info.text.num; i++)
+ {
+ if(strlen(info.text.keys[i]) > 79) { encoder->error = 66; break; }
+ if(strlen(info.text.keys[i]) < 1) { encoder->error = 67; break; }
+ if(encoder->settings.text_compression)
+ addChunk_zTXt(&outv, info.text.keys[i], info.text.strings[i], &encoder->settings.zlibsettings);
+ else
+ addChunk_tEXt(&outv, info.text.keys[i], info.text.strings[i]);
+ }
+ /*LodePNG version id in text chunk*/
+ if(encoder->settings.add_id)
+ {
+ unsigned alread_added_id_text = 0;
+ for(i = 0; i < info.text.num; i++)
+ if(!strcmp(info.text.keys[i], "LodePNG")) { alread_added_id_text = 1; break; }
+ if(alread_added_id_text == 0)
+ addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
+ }
+ /*iTXt*/
+ for(i = 0; i < info.itext.num; i++)
+ {
+ if(strlen(info.itext.keys[i]) > 79) { encoder->error = 66; break; }
+ if(strlen(info.itext.keys[i]) < 1) { encoder->error = 67; break; }
+ addChunk_iTXt(&outv, encoder->settings.text_compression,
+ info.itext.keys[i], info.itext.langtags[i], info.itext.transkeys[i], info.itext.strings[i],
+ &encoder->settings.zlibsettings);
+ }
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ /*unknown chunks between IDAT and IEND*/
+ if(info.unknown_chunks.data[2]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[2], info.unknown_chunks.datasize[2]); if(encoder->error) break; }
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+ /*IEND*/
+ addChunk_IEND(&outv);
+
+ break; /*this isn't really a while loop; no error happened so break out now!*/
+ }
+
+ free(data);
+ /*instead of cleaning the vector up, give it to the output*/
+ *out = outv.data;
+ *outsize = outv.size;
+}
+
+unsigned LodePNG_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
+{
+ unsigned error;
+ LodePNG_Encoder encoder;
+ LodePNG_Encoder_init(&encoder);
+ LodePNG_encode(&encoder, out, outsize, image, w, h);
+ error = encoder.error;
+ LodePNG_Encoder_cleanup(&encoder);
+ return error;
+}
+
+#ifdef LODEPNG_COMPILE_DISK
+unsigned LodePNG_encode32f(const char* filename, const unsigned char* image, unsigned w, unsigned h)
+{
+ unsigned char* buffer;
+ size_t buffersize;
+ unsigned error = LodePNG_encode32(&buffer, &buffersize, image, w, h);
+ LodePNG_saveFile(buffer, buffersize, filename);
+ free(buffer);
+ return error;
+}
+#endif /*LODEPNG_COMPILE_DISK*/
+
+void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings* settings)
+{
+ LodeZlib_DeflateSettings_init(&settings->zlibsettings);
+ settings->autoLeaveOutAlphaChannel = 1;
+ settings->force_palette = 0;
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ settings->add_id = 1;
+ settings->text_compression = 0;
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+}
+
+void LodePNG_Encoder_init(LodePNG_Encoder* encoder)
+{
+ LodePNG_EncodeSettings_init(&encoder->settings);
+ LodePNG_InfoPng_init(&encoder->infoPng);
+ LodePNG_InfoRaw_init(&encoder->infoRaw);
+ encoder->error = 1;
+}
+
+void LodePNG_Encoder_cleanup(LodePNG_Encoder* encoder)
+{
+ LodePNG_InfoPng_cleanup(&encoder->infoPng);
+ LodePNG_InfoRaw_cleanup(&encoder->infoRaw);
+}
+
+void LodePNG_Encoder_copy(LodePNG_Encoder* dest, const LodePNG_Encoder* source)
+{
+ LodePNG_Encoder_cleanup(dest);
+ *dest = *source;
+ LodePNG_InfoPng_init(&dest->infoPng);
+ LodePNG_InfoRaw_init(&dest->infoRaw);
+ dest->error = LodePNG_InfoPng_copy(&dest->infoPng, &source->infoPng); if(dest->error) return;
+ dest->error = LodePNG_InfoRaw_copy(&dest->infoRaw, &source->infoRaw); if(dest->error) return;
+}
+
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+#endif /*LODEPNG_COMPILE_PNG*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* / File IO / */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_DISK
+
+unsigned LodePNG_loadFile(unsigned char** out, size_t* outsize, const char* filename) /*designed for loading files from hard disk in a dynamically allocated buffer*/
+{
+ FILE* file;
+ long size;
+
+ /*provide some proper output values if error will happen*/
+ *out = 0;
+ *outsize = 0;
+
+ file = portable_fopen(filename, "rb");
+ if(!file) return 78;
+
+ /*get filesize:*/
+ fseek(file , 0 , SEEK_END);
+ size = ftell(file);
+ rewind(file);
+
+ /*read contents of the file into the vector*/
+ *outsize = 0;
+ *out = (unsigned char*)malloc((size_t)size);
+ if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file);
+
+ fclose(file);
+ if(!(*out) && size) return 80; /*the above malloc failed*/
+ return 0;
+}
+
+/*write given buffer to the file, overwriting the file, it doesn't append to it.*/
+unsigned LodePNG_saveFile(const unsigned char* buffer, size_t buffersize, const char* filename)
+{
+ FILE* file;
+ file = portable_fopen(filename, "wb" );
+ if(!file) return 79;
+ fwrite((char*)buffer , 1 , buffersize, file);
+ fclose(file);
+ return 0;
+}
+
+#endif /*LODEPNG_COMPILE_DISK*/
+
diff --git a/src/lodepng.h b/src/lodepng.h
new file mode 100644
index 0000000..bbf40dc
--- /dev/null
+++ b/src/lodepng.h
@@ -0,0 +1,1575 @@
+/*
+LodePNG version 20080927
+
+Copyright (c) 2005-2008 Lode Vandevenne
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+*/
+
+#ifndef LODEPNG_H
+#define LODEPNG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* Code Sections */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*The following defines can be commented disable code sections. Gives potential faster compile and smaller binary.*/
+
+#define LODEPNG_COMPILE_ZLIB /*deflate&zlib encoder and deflate&zlib decoder*/
+#define LODEPNG_COMPILE_PNG /*png encoder and png decoder*/
+//#define LODEPNG_COMPILE_DECODER /*deflate&zlib decoder and png decoder*/
+#define LODEPNG_COMPILE_ENCODER /*deflate&zlib encoder and png encoder*/
+#define LODEPNG_COMPILE_DISK /*the optional built in harddisk file loading and saving functions*/
+//#define LODEPNG_COMPILE_ANCILLARY_CHUNKS /*any code or struct datamember related to chunks other than IHDR, IDAT, PLTE, tRNS, IEND*/
+//#define LODEPNG_COMPILE_UNKNOWN_CHUNKS /*handling of unknown chunks*/
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* LodeFlate & LodeZlib Setting structs */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_DECODER
+typedef struct LodeZlib_DecompressSettings
+{
+ unsigned ignoreAdler32;
+} LodeZlib_DecompressSettings;
+
+extern const LodeZlib_DecompressSettings LodeZlib_defaultDecompressSettings;
+void LodeZlib_DecompressSettings_init(LodeZlib_DecompressSettings* settings);
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+typedef struct LodeZlib_DeflateSettings /*deflate = compress*/
+{
+ /*LZ77 related settings*/
+ unsigned btype; /*the block type for LZ*/
+ unsigned useLZ77; /*whether or not to use LZ77*/
+ unsigned windowSize; /*the maximum is 32768*/
+} LodeZlib_DeflateSettings;
+
+extern const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings;
+void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings* settings);
+#endif /*LODEPNG_COMPILE_ENCODER*/
+
+#ifdef LODEPNG_COMPILE_ZLIB
+/* ////////////////////////////////////////////////////////////////////////// */
+/* LodeFlate & LodeZlib */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifdef LODEPNG_COMPILE_DECODER
+/*This function reallocates the out buffer and appends the data.
+Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes.*/
+unsigned LodeZlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DecompressSettings* settings);
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+/*This function reallocates the out buffer and appends the data.
+Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes.*/
+unsigned LodeZlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings);
+#endif /*LODEPNG_COMPILE_ENCODER*/
+#endif /*LODEPNG_COMPILE_ZLIB*/
+
+#ifdef LODEPNG_COMPILE_PNG
+
+/* ////////////////////////////////////////////////////////////////////////// */
+/* LodePNG */
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/*LodePNG_chunk functions: These functions need as input a large enough amount of allocated memory.*/
+
+unsigned LodePNG_chunk_length(const unsigned char* chunk); /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/
+
+void LodePNG_chunk_type(char type[5], const unsigned char* chunk); /*puts the 4-byte type in null terminated string*/
+unsigned char LodePNG_chunk_type_equals(const unsigned char* chunk, const char* type); /*check if the type is the given type*/
+
+/*properties of PNG chunks gotten from capitalization of chunk type name, as defined by the standard*/
+unsigned char LodePNG_chunk_critical(const unsigned char* chunk); /*0: ancillary chunk, 1: it's one of the critical chunk types*/
+unsigned char LodePNG_chunk_private(const unsigned char* chunk); /*0: public, 1: private*/
+unsigned char LodePNG_chunk_safetocopy(const unsigned char* chunk); /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy*/
+
+unsigned char* LodePNG_chunk_data(unsigned char* chunk); /*get pointer to the data of the chunk*/
+const unsigned char* LodePNG_chunk_data_const(const unsigned char* chunk); /*get pointer to the data of the chunk*/
+
+unsigned LodePNG_chunk_check_crc(const unsigned char* chunk); /*returns 0 if the crc is correct, 1 if it's incorrect*/
+void LodePNG_chunk_generate_crc(unsigned char* chunk); /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
+
+/*iterate to next chunks.*/
+unsigned char* LodePNG_chunk_next(unsigned char* chunk);
+const unsigned char* LodePNG_chunk_next_const(const unsigned char* chunk);
+
+/*add chunks to out buffer. It reallocs the buffer to append the data. returns error code*/
+unsigned LodePNG_append_chunk(unsigned char** out, size_t* outlength, const unsigned char* chunk); /*appends chunk that was already created, to the data. Returns pointer to start of appended chunk, or NULL if error happened*/
+unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data); /*appends new chunk to out. Returns pointer to start of appended chunk, or NULL if error happened; may change memory address of out buffer*/
+
+typedef struct LodePNG_InfoColor /*info about the color type of an image*/
+{
+ /*header (IHDR)*/
+ unsigned colorType; /*color type*/
+ unsigned bitDepth; /*bits per sample*/
+
+ /*palette (PLTE)*/
+ unsigned char* palette; /*palette in RGBARGBA... order*/
+ size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/
+
+ /*transparent color key (tRNS)*/
+ unsigned key_defined; /*is a transparent color key given?*/
+ unsigned key_r; /*red component of color key*/
+ unsigned key_g; /*green component of color key*/
+ unsigned key_b; /*blue component of color key*/
+} LodePNG_InfoColor;
+
+void LodePNG_InfoColor_init(LodePNG_InfoColor* info);
+void LodePNG_InfoColor_cleanup(LodePNG_InfoColor* info);
+unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor* dest, const LodePNG_InfoColor* source);
+
+/*Use these functions instead of allocating palette manually*/
+void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor* info);
+unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a); /*add 1 color to the palette*/
+
+/*additional color info*/
+unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor* info); /*bits per pixel*/
+unsigned LodePNG_InfoColor_getChannels(const LodePNG_InfoColor* info); /*amount of channels*/
+unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor* info); /*is it a greyscale type? (colorType 0 or 4)*/
+unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor* info); /*has it an alpha channel? (colorType 2 or 6)*/
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+typedef struct LodePNG_Time /*LodePNG's encoder does not generate the current time. To make it add a time chunk the correct time has to be provided*/
+{
+ unsigned year; /*2 bytes*/
+ unsigned char month; /*1-12*/
+ unsigned char day; /*1-31*/
+ unsigned char hour; /*0-23*/
+ unsigned char minute; /*0-59*/
+ unsigned char second; /*0-60 (to allow for leap seconds)*/
+} LodePNG_Time;
+
+typedef struct LodePNG_Text /*non-international text*/
+{
+ size_t num;
+ char** keys; /*the keyword of a text chunk (e.g. "Comment")*/
+ char** strings; /*the actual text*/
+} LodePNG_Text;
+
+void LodePNG_Text_init(LodePNG_Text* text);
+void LodePNG_Text_cleanup(LodePNG_Text* text);
+unsigned LodePNG_Text_copy(LodePNG_Text* dest, const LodePNG_Text* source);
+
+/*Use these functions instead of allocating the char**s manually*/
+void LodePNG_Text_clear(LodePNG_Text* text);
+unsigned LodePNG_Text_add(LodePNG_Text* text, const char* key, const char* str); /*push back both texts at once*/
+
+
+typedef struct LodePNG_IText /*international text*/
+{
+ size_t num;
+ char** keys; /*the English keyword of the text chunk (e.g. "Comment")*/
+ char** langtags; /*the language tag for this text's international language, ISO/IEC 646 string, e.g. ISO 639 language tag*/
+ char** transkeys; /*keyword translated to the international language - UTF-8 string*/
+ char** strings; /*the actual international text - UTF-8 string*/
+} LodePNG_IText;
+
+void LodePNG_IText_init(LodePNG_IText* text);
+void LodePNG_IText_cleanup(LodePNG_IText* text);
+unsigned LodePNG_IText_copy(LodePNG_IText* dest, const LodePNG_IText* source);
+
+/*Use these functions instead of allocating the char**s manually*/
+void LodePNG_IText_clear(LodePNG_IText* text);
+unsigned LodePNG_IText_add(LodePNG_IText* text, const char* key, const char* langtag, const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+typedef struct LodePNG_UnknownChunks /*unknown chunks read from the PNG, or extra chunks the user wants to have added in the encoded PNG*/
+{
+ /*There are 3 buffers, one for each position in the PNG where unknown chunks can appear
+ each buffer contains all unknown chunks for that position consecutively
+ The 3 buffers are the unknown chunks between certain critical chunks:
+ 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND*/
+ unsigned char* data[3];
+ size_t datasize[3]; /*size in bytes of the unknown chunks, given for protection*/
+
+} LodePNG_UnknownChunks;
+
+void LodePNG_UnknownChunks_init(LodePNG_UnknownChunks* chunks);
+void LodePNG_UnknownChunks_cleanup(LodePNG_UnknownChunks* chunks);
+unsigned LodePNG_UnknownChunks_copy(LodePNG_UnknownChunks* dest, const LodePNG_UnknownChunks* src);
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+
+typedef struct LodePNG_InfoPng /*information about the PNG image, except pixels and sometimes except width and height*/
+{
+ /*header (IHDR), palette (PLTE) and transparency (tRNS)*/
+ unsigned width; /*width of the image in pixels (ignored by encoder, but filled in by decoder)*/
+ unsigned height; /*height of the image in pixels (ignored by encoder, but filled in by decoder)*/
+ unsigned compressionMethod; /*compression method of the original file*/
+ unsigned filterMethod; /*filter method of the original file*/
+ unsigned interlaceMethod; /*interlace method of the original file*/
+ LodePNG_InfoColor color; /*color type and bits, palette, transparency*/
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+
+ /*suggested background color (bKGD)*/
+ unsigned background_defined; /*is a suggested background color given?*/
+ unsigned background_r; /*red component of suggested background color*/
+ unsigned background_g; /*green component of suggested background color*/
+ unsigned background_b; /*blue component of suggested background color*/
+
+ /*non-international text chunks (tEXt and zTXt)*/
+ LodePNG_Text text;
+
+ /*international text chunks (iTXt)*/
+ LodePNG_IText itext;
+
+ /*time chunk (tIME)*/
+ unsigned char time_defined; /*if 0, no tIME chunk was or will be generated in the PNG image*/
+ LodePNG_Time time;
+
+ /*phys chunk (pHYs)*/
+ unsigned phys_defined; /*is pHYs chunk defined?*/
+ unsigned phys_x;
+ unsigned phys_y;
+ unsigned char phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
+
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ /*unknown chunks*/
+ LodePNG_UnknownChunks unknown_chunks;
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+
+} LodePNG_InfoPng;
+
+void LodePNG_InfoPng_init(LodePNG_InfoPng* info);
+void LodePNG_InfoPng_cleanup(LodePNG_InfoPng* info);
+unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng* dest, const LodePNG_InfoPng* source);
+
+typedef struct LodePNG_InfoRaw /*contains user-chosen information about the raw image data, which is independent of the PNG image*/
+{
+ LodePNG_InfoColor color;
+} LodePNG_InfoRaw;
+
+void LodePNG_InfoRaw_init(LodePNG_InfoRaw* info);
+void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw* info);
+unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw* dest, const LodePNG_InfoRaw* source);
+
+/*
+LodePNG_convert: Converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code
+The out buffer must have (w * h * bpp + 7) / 8, where bpp is the bits per pixel of the output color type (LodePNG_InfoColor_getBpp)
+*/
+unsigned LodePNG_convert(unsigned char* out, const unsigned char* in, LodePNG_InfoColor* infoOut, LodePNG_InfoColor* infoIn, unsigned w, unsigned h);
+
+#ifdef LODEPNG_COMPILE_DECODER
+
+typedef struct LodePNG_DecodeSettings
+{
+ LodeZlib_DecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
+
+ unsigned ignoreCrc; /*ignore CRC checksums*/
+ unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
+
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ unsigned readTextChunks; /*if false but rememberUnknownChunks is true, they're stored in the unknown chunks*/
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+
+#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
+ unsigned rememberUnknownChunks; /*store all bytes from unknown chunks in the InfoPng (off by default, useful for a png editor)*/
+#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
+} LodePNG_DecodeSettings;
+
+void LodePNG_DecodeSettings_init(LodePNG_DecodeSettings* settings);
+
+typedef struct LodePNG_Decoder
+{
+ LodePNG_DecodeSettings settings;
+ LodePNG_InfoRaw infoRaw;
+ LodePNG_InfoPng infoPng; /*info of the PNG image obtained after decoding*/
+ unsigned error;
+} LodePNG_Decoder;
+
+void LodePNG_Decoder_init(LodePNG_Decoder* decoder);
+void LodePNG_Decoder_cleanup(LodePNG_Decoder* decoder);
+void LodePNG_Decoder_copy(LodePNG_Decoder* dest, const LodePNG_Decoder* source);
+
+/*decoding functions*/
+/*This function allocates the out buffer and stores the size in *outsize.*/
+void LodePNG_decode(LodePNG_Decoder* decoder, unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize);
+unsigned LodePNG_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize); /*return value is error*/
+#ifdef LODEPNG_COMPILE_DISK
+unsigned LodePNG_decode32f(unsigned char** out, unsigned* w, unsigned* h, const char* filename);
+#endif /*LODEPNG_COMPILE_DISK*/
+void LodePNG_inspect(LodePNG_Decoder* decoder, const unsigned char* in, size_t size); /*read the png header*/
+
+#endif /*LODEPNG_COMPILE_DECODER*/
+
+#ifdef LODEPNG_COMPILE_ENCODER
+
+typedef struct LodePNG_EncodeSettings
+{
+ LodeZlib_DeflateSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
+
+ unsigned autoLeaveOutAlphaChannel; /*automatically use color type without alpha instead of given one, if given image is opaque*/
+ unsigned force_palette; /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). If colortype is 3, PLTE is _always_ created.*/
+#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
+ unsigned add_id; /*add LodePNG version as text chunk*/
+ unsigned text_compression; /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/
+#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
+} LodePNG_EncodeSettings;
+
+void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings* settings);
+
+typedef struct LodePNG_Encoder
+{
+ LodePNG_EncodeSettings settings;
+ LodePNG_InfoPng infoPng; /*the info specified by the user may not be changed by the encoder. The encoder will try to generate a PNG close to the given info.*/
+ LodePNG_InfoRaw infoRaw; /*put the properties of the input raw image in here*/
+ unsigned error;
+} LodePNG_Encoder;
+
+void LodePNG_Encoder_init(LodePNG_Encoder* encoder);
+void LodePNG_Encoder_cleanup(LodePNG_Encoder* encoder);
+void LodePNG_Encoder_copy(LodePNG_Encoder* dest, const LodePNG_Encoder* source);
+
+/*This function allocates the out buffer and stores the size in *outsize.*/
+void LodePNG_encode(LodePNG_Encoder* encoder, unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h);
+unsigned LodePNG_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); /*return value is error*/
+#ifdef LODEPNG_COMPILE_DISK
+unsigned LodePNG_encode32f(const char* filename, const unsigned char* image, unsigned w, unsigned h);
+#endif /*LODEPNG_COMPILE_DISK*/
+#endif /*LODEPNG_COMPILE_ENCODER*/
+#endif /*LODEPNG_COMPILE_PNG*/
+
+#ifdef LODEPNG_COMPILE_DISK
+/*free functions allowing to load and save a file from/to harddisk*/
+/*This function allocates the out buffer and stores the size in *outsize.*/
+unsigned LodePNG_loadFile(unsigned char** out, size_t* outsize, const char* filename);
+unsigned LodePNG_saveFile(const unsigned char* buffer, size_t buffersize, const char* filename);
+#endif /*LODEPNG_COMPILE_DISK*/
+
+
+/*
+TODO:
+[ ] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
+[ ] LZ77 encoder more like the one described in zlib - to make sure it's patentfree
+[ ] converting color to 16-bit types
+[ ] read all public PNG chunk types (but never let the color profile and gamma ones ever touch RGB values, that is very annoying for textures as well as images in a browser)
+[ ] make sure encoder generates no chunks with size > (2^31)-1
+[ ] partial decoding (stream processing)
+[ ] let the "isFullyOpaque" function check color keys and transparent palettes too
+[ ] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
+[ ] check compatibility with vareous compilers - done but needs to be redone for every newer version
+[ ] don't stop decoding on errors like 69, 57, 58 (make warnings that the decoder stores in the error at the very end? and make some errors just let it stop with this one chunk but still do the next ones)
+[ ] make option to choose if the raw image with non multiple of 8 bits per scanline should have padding bits or not, if people like storing raw images that way
+*/
+
+#endif
+
+/*
+LodePNG Documentation
+---------------------
+
+0. table of contents
+--------------------
+
+ 1. about
+ 1.1. supported features
+ 1.2. features not supported
+ 2. C and C++ version
+ 3. A note about security!
+ 4. simple functions
+ 4.1 C Simple Functions
+ 4.2 C++ Simple Functions
+ 5. decoder
+ 6. encoder
+ 7. color conversions
+ 8. info values
+ 9. error values
+ 10. file IO
+ 11. chunks and PNG editing
+ 12. compiler support
+ 13. examples
+ 13.1. decoder example
+ 13.2. encoder example
+ 14. LodeZlib
+ 15. changes
+ 16. contact information
+
+
+1. about
+--------
+
+PNG is a file format to store raster images losslessly with good compression,
+supporting different color types. It can be implemented in a patent-free way.
+
+LodePNG is a PNG codec according to the Portable Network Graphics (PNG)
+Specification (Second Edition) - W3C Recommendation 10 November 2003.
+
+The specifications used are:
+
+*) Portable Network Graphics (PNG) Specification (Second Edition):
+ http://www.w3.org/TR/2003/REC-PNG-20031110
+*) RFC 1950 ZLIB Compressed Data Format version 3.3:
+ http://www.gzip.org/zlib/rfc-zlib.html
+*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3:
+ http://www.gzip.org/zlib/rfc-deflate.html
+
+The most recent version of LodePNG can currently be found at
+http://members.gamedev.net/lode/projects/LodePNG/
+
+LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds
+extra functionality.
+
+LodePNG exists out of two files:
+-lodepng.h: the header file for both C and C++
+-lodepng.c(pp): give it the name lodepng.c or lodepng.cpp depending on your usage
+
+If you want to start using LodePNG right away without reading this doc, get the
+files lodepng_examples.c or lodepng_examples.cpp to see how to use it in code,
+or check the (smaller) examples in chapter 13 here.
+
+LodePNG is simple but only supports the basic requirements. To achieve
+simplicity, the following design choices were made: There are no dependencies
+on any external library. To decode PNGs, there's a Decoder struct or class that
+can convert any PNG file data into an RGBA image buffer with a single function
+call. To encode PNGs, there's an Encoder struct or class that can convert image
+data into PNG file data with a single function call. To read and write files,
+there are simple functions to convert the files to/from buffers in memory.
+
+This all makes LodePNG suitable for loading textures in games, demoscene
+productions, saving a screenshot, images in programs that require them for simple
+usage, ... It's less suitable for full fledged image editors, loading PNGs
+over network (it requires all the image data to be available before decoding can
+begin), life-critical systems, ...
+LodePNG has a standards conformant decoder and encoder, and supports the ability
+to make a somewhat conformant editor.
+
+1.1. supported features
+-----------------------
+
+The following features are supported by the decoder:
+
+*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, or the same color type as the PNG
+*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image
+*) Adam7 interlace and deinterlace for any color type
+*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk
+*) support for alpha channels, including RGBA color model, translucent palettes and color keying
+*) zlib decompression (inflate)
+*) zlib compression (deflate)
+*) CRC32 and ADLER32 checksums
+*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks.
+*) the following chunks are supported (generated/interpreted) by both encoder and decoder:
+ IHDR: header information
+ PLTE: color palette
+ IDAT: pixel data
+ IEND: the final chunk
+ tRNS: transparency for palettized images
+ tEXt: textual information
+ zTXt: compressed textual information
+ iTXt: international textual information
+ bKGD: suggested background color
+ pHYs: physical dimensions
+ tIME: modification time
+
+1.2. features not supported
+---------------------------
+
+The following features are _not_ supported:
+
+*) some features needed to make a conformant PNG-Editor might be still missing.
+*) partial loading/stream processing. All data must be available and is processed in one call.
+*) The following public chunks are not supported but treated as unknown chunks by LodePNG
+ cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT
+
+
+2. C and C++ version
+--------------------
+
+The C version uses buffers allocated with alloc instead that you need to free()
+yourself. On top of that, you need to use init and cleanup functions for each
+struct whenever using a struct from the C version to avoid exploits and memory leaks.
+
+The C++ version has constructors and destructors that take care of these things,
+and uses std::vectors in the interface for storing data.
+
+Both the C and the C++ version are contained in this file! The C++ code depends on
+the C code, the C code works on its own.
+
+These files work without modification for both C and C++ compilers because all the
+additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers ignore
+it, and the C code is made to compile both with strict ISO C90 and C++.
+
+To use the C++ version, you need to rename the source file to lodepng.cpp (instead
+of lodepng.c), and compile it with a C++ compiler.
+
+To use the C version, you need to rename the source file to lodepng.c (instead
+of lodepng.cpp), and compile it with a C compiler.
+
+
+3. A note about security!
+-------------------------
+
+Despite being used already and having received bug fixes whenever bugs were reported,
+LodePNG may still contain possible exploits.
+
+If you discover a possible exploit, please let me know, and it will be eliminated.
+
+When using LodePNG, care has to be taken with the C version of LodePNG, as well as the C-style
+structs when working with C++. The following conventions are used for all C-style structs:
+
+-if a struct has a corresponding init function, always call the init function when making a new one, to avoid exploits
+-if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks
+-if a struct has a corresponding copy function, use the copy function instead of "=". The destination must be inited already!
+
+
+4. "Simple" Functions
+---------------------
+
+For the most simple usage cases of loading and saving a PNG image, there
+are some simple functions that do everything in 1 call (instead of you
+having to instantiate a struct or class).
+
+The simple versions always use 32-bit RGBA color for the raw image, but
+still support loading arbitrary-colortype PNG images.
+
+The later sections of this manual are devoted to the complex versions, where
+you can use other color types and conversions.
+
+4.1 C Simple Functions
+----------------------
+
+The C simple functions have a "32" or "32f" in their name, and don't take a struct as
+parameter, unlike the non-simple ones (see more down in the documentation).
+
+unsigned LodePNG_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize);
+
+Load PNG from given buffer.
+As input, give an unsigned char* buffer gotten by loading the .png file and its size.
+As output, you get a dynamically allocated buffer of large enough size, and the width and height of the image.
+The buffer's size is w * h * 4. The image is in RGBA format.
+The return value is the error (0 if ok).
+You need to do free(out) after usage to clean up the memory.
+
+unsigned LodePNG_decode32f(unsigned char** out, unsigned* w, unsigned* h, const char* filename);
+
+Load PNG from disk, from file with given name.
+Same as decode32, except you give a filename instead of an input buffer.
+
+unsigned LodePNG_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h);
+
+Encode PNG into buffer.
+As input, give a image buffer of size w * h * 4, in RGBA format.
+As output, you get a dynamically allocated buffer and its size, which is a PNG file that can
+directly be saved in this form to the harddisk.
+The return value is the error (0 if ok).
+You need to do free(out) after usage to clean up the memory.
+
+unsigned LodePNG_encode32f(const char* filename, const unsigned char* image, unsigned w, unsigned h);
+
+Encode PNG into file on disk with given name.
+If the file exists, it's overwritten without warning!
+Same parameters as encode2, except the result is stored in a file instead of a dynamic buffer.
+
+4.2 C++ Simple Functions
+------------------------
+
+For decoding a PNG there are:
+
+unsigned LodePNG::decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const unsigned char* in, unsigned size);
+unsigned LodePNG::decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const std::vector<unsigned char>& in);
+unsigned LodePNG::decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const std::string& filename);
+
+These store the pixel data as 32-bit RGBA color in the out vector, and the width
+and height of the image in w and h.
+The 3 functions each have a different input type: The first as unsigned char
+buffer, the second as std::vector buffer, and the third allows you to give the
+filename in case you want to load the PNG from disk instead of from a buffer.
+The return value is the error (0 if ok).
+
+For encoding a PNG there are:
+
+unsigned LodePNG::encode(std::vector<unsigned char>& out, const unsigned char* in, unsigned w, unsigned h);
+unsigned LodePNG::encode(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, unsigned w, unsigned h);
+unsigned LodePNG::encode(const std::string& filename, const std::vector<unsigned char>& in, unsigned w, unsigned h);
+unsigned LodePNG::encode(const std::string& filename, const unsigned char* in, unsigned w, unsigned h);
+
+Specify the width and height of the input image with w and h.
+You can choose to get the output in an std::vector or stored in a file, and
+the input can come from an std::vector or an unsigned char* buffer. The input
+buffer must be in RGBA format and the size must be w * h * 4 bytes.
+
+The first two functions append to the out buffer, they don't clear it, clear it
+first before encoding into a buffer that you expect to only contain this result.
+
+On the other hand, the functions that encode to a file will completely overwrite
+the original file without warning if it exists.
+
+The return value is the error (0 if ok).
+
+5. Decoder
+----------
+
+This is about the LodePNG_Decoder struct in the C version, and the
+LodePNG::Decoder class in the C++ version. The C++ version inherits
+from the C struct and adds functions in the interface.
+
+The Decoder class can be used to convert a PNG image to a raw image.
+
+Usage:
+
+-in C++:
+ declare a LodePNG::Decoder
+ call its decode member function with the parameters described below
+
+-in C more needs to be done due to the lack of constructors and destructors:
+ declare a LodePNG_Decoder struct
+ call LodePNG_Decoder_init with the struct as parameter
+ call LodePNG_Decode with the parameters described below
+ after usage, call LodePNG_Decoder_cleanup with the struct as parameter
+ after usage, free() the out buffer with image data that was created by the decode function
+
+The other parameters of the decode function are:
+*) out: this buffer will be filled with the raw image pixels
+*) in: pointer to the PNG image data or std::vector with the data
+*) size: the size of the PNG image data (not needed for std::vector version)
+
+After decoding you need to read the width and height of the image from the
+decoder, see further down in this manual to see how.
+
+There's also an optional function "inspect". It has the same parameters as decode except
+the "out" parameter. This function will read only the header chunk of the PNG
+image, and store the information from it in the LodePNG_InfoPng (see below).
+This allows knowing information about the image without decoding it. Only the
+header (IHDR) information is read by this, not text chunks, not the palette, ...
+
+During the decoding it's possible that an error can happen, for example if the
+PNG image was corrupted. To check if an error happened during the last decoding,
+check the value error, which is a member of the decoder struct.
+In the C++ version, use hasError() and getError() of the Decoder.
+The error codes are explained in another section.
+
+Now about colors and settings...
+
+The Decoder contains 3 components:
+*) LodePNG_InfoPng: it stores information about the PNG (the input) in an LodePNG_InfoPng struct, don't modify this one yourself
+*) Settings: you can specify a few other settings for the decoder to use
+*) LodePNG_InfoRaw: here you can say what type of raw image (the output) you want to get
+
+Some of the parameters described below may be inside the sub-struct "LodePNG_InfoColor color".
+In the C and C++ version, when using Info structs outside of the decoder or encoder, you need to use their
+init and cleanup functions, but normally you use the ones in the decoder that are already handled
+in the init and cleanup functions of the decoder itself.
+
+=LodePNG_InfoPng=
+
+This contains information such as the original color type of the PNG image, text
+comments, suggested background color, etc... More details about the LodePNG_InfoPng struct
+are in another section.
+
+Because the dimensions of the image are important, there are shortcuts to get them in the
+C++ version: use decoder.getWidth() and decoder.getHeight().
+In the C version, use decoder.infoPng.width and decoder.infoPng.height.
+
+=LodePNG_InfoRaw=
+
+In the LodePNG_InfoRaw struct of the Decoder, you can specify which color type you want
+the resulting raw image to be. If this is different from the colorType of the
+PNG, then the decoder will automatically convert the result to your LodePNG_InfoRaw
+settings. Currently the following options are supported to convert to:
+-colorType 6, bitDepth 8: 32-bit RGBA
+-colorType 2, bitDepth 8: 24-bit RGB
+-other color types if it's exactly the same as that in the PNG image
+
+Palette of LodePNG_InfoRaw isn't used by the Decoder, when converting from palette color
+to palette color, the values of the pixels are left untouched so that the colors
+will change if the palette is different. Color key of LodePNG_InfoRaw is not used by the
+Decoder. If setting color_convert is false then LodePNG_InfoRaw is completely ignored,
+but it will be modified to match the color type of the PNG so will be overwritten.
+
+By default, 32-bit color is used for the result.
+
+=Settings=
+
+The Settings can be used to ignore the errors created by invalid CRC and Adler32
+chunks, and to disable the decoding of tEXt chunks.
+
+There's also a setting color_convert, true by default. If false, no conversion
+is done, the resulting data will be as it was in the PNG (after decompression)
+and you'll have to puzzle the colors of the pixels together yourself using the
+color type information in the LodePNG_InfoPng.
+
+
+6. Encoder
+----------
+
+This is about the LodePNG_Encoder struct in the C version, and the
+LodePNG::Encoder class in the C++ version.
+
+The Encoder class can be used to convert raw image data into a PNG image.
+
+The PNG part of the encoder is working good, the zlib compression part is
+becoming quite fine but not as good as the official zlib yet, because it's not
+as fast and doesn't provide an as high compression ratio.
+
+Usage:
+
+-in C++:
+ declare a LodePNG::Encoder
+ call its encode member function with the parameters described below
+
+-in C more needs to be done due to the lack of constructors and destructors:
+ declare a LodePNG_Encoder struct
+ call LodePNG_Encoder_init with the struct as parameter
+ call LodePNG_Encode with the parameters described below
+ after usage, call LodePNG_Encoder_cleanup with the struct as parameter
+ after usage, free() the out buffer with PNG data that was created by the encode function
+
+The raw image given to the encoder is an unsigned char* buffer. You also have to
+specify the width and height of the raw image. The result is stored in a given
+buffer. These buffers can be unsigned char* pointers, std::vectors or dynamically
+allocated unsigned char* buffers that you have to free() yourself, depending on
+which you use.
+
+The parameters of the encode function are:
+*) out: in this buffer the PNG file data will be stored (it will be appended)
+*) in: vector of or pointer to a buffer containing the raw image
+*) w and h: the width and height of the raw image in pixels
+
+Make sure that the in buffer you provide, is big enough to contain w * h pixels
+of the color type specified by the LodePNG_InfoRaw.
+
+In the C version, you need to free() the out buffer after usage to avoid memory leaks.
+In the C version, you need to use the LodePNG_Encoder_init function before using the decoder,
+and the LodePNG_Encoder_cleanup function after using it.
+In the C++ version, you don't need to do this since RAII takes care of it.
+
+The encoder generates some errors but not for everything, because, unlike when
+decoding a PNG, when encoding one there aren't so much parameters of the input
+that can be corrupted. It's the responsibility of the user to make sure that all
+preconditions are satesfied, such as giving a correct window size, giving an
+existing btype, making sure the given buffer is large enough to contain an image
+with the given width and height and colortype, ... The encoder can generate
+some errors, see the section with the explanations of errors for those.
+
+Like the Decoder, the Encoder has 3 components:
+*) LodePNG_InfoRaw: here you say what color type of the raw image (the input) has
+*) Settings: you can specify a few settings for the encoder to use
+*) LodePNG_InfoPng: the same LodePNG_InfoPng struct as created by the Decoder. For the encoder,
+with this you specify how you want the PNG (the output) to be.
+
+Some of the parameters described below may be inside the sub-struct "LodePNG_InfoColor color".
+In the C and C++ version, when using Info structs outside of the decoder or encoder, you need to use their
+init and cleanup functions, but normally you use the ones in the encoder that are already handled
+in the init and cleanup functions of the decoder itself.
+
+=LodePNG_InfoPng=
+
+The Decoder class stores information about the PNG image in an LodePNG_InfoPng object. With
+the Encoder you can do the opposite: you give it an LodePNG_InfoPng object, and it'll try
+to match the LodePNG_InfoPng you give as close as possible in the PNG it encodes. For
+example in the LodePNG_InfoPng you can specify the color type you want to use, possible
+tEXt chunks you want the PNG to contain, etc... For an explanation of all the
+values in LodePNG_InfoPng see a further section. Not all PNG color types are supported
+by the Encoder.
+
+Note that the encoder will only TRY to match the LodePNG_InfoPng struct you give.
+Some things are ignored by the encoder. The width and height of LodePNG_InfoPng are
+ignored as well, because instead the width and height of the raw image you give
+in the input are used. In fact the encoder currently uses only the following
+settings from it:
+-colorType: the ones it supports
+-text chunks, that you can add to the LodePNG_InfoPng with "addText"
+-the color key, if applicable for the given color type
+-the palette, if you encode to a PNG with colorType 3
+-the background color: it'll add a bKGD chunk to the PNG if one is given
+-the interlaceMethod: None (0) or Adam7 (1)
+
+When encoding to a PNG with colorType 3, the encoder will generate a PLTE chunk.
+If the palette contains any colors for which the alpha channel is not 255 (so
+there are translucent colors in the palette), it'll add a tRNS chunk.
+
+=LodePNG_InfoRaw=
+
+You specify the color type of the raw image that you give to the input here,
+including a possible transparent color key and palette you happen to be using in
+your raw image data.
+
+By default, 32-bit color is assumed, meaning your input has to be in RGBA
+format with 4 bytes (unsigned chars) per pixel.
+
+=Settings=
+
+The following settings are supported (some are in sub-structs):
+*) autoLeaveOutAlphaChannel: when this option is enabled, when you specify a PNG
+color type with alpha channel (not to be confused with the color type of the raw
+image you specify!!), but the encoder detects that all pixels of the given image
+are opaque, then it'll automatically use the corresponding type without alpha
+channel, resulting in a smaller PNG image.
+*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, 2 = dynamic huffman tree (best compression)
+*) useLZ77: whether or not to use LZ77 for compressed block types
+*) windowSize: the window size used by the LZ77 encoder (1 - 32768)
+*) force_palette: if colorType is 2 or 6, you can make the encoder write a PLTE
+ chunk if force_palette is true. This can used as suggested palette to convert
+ to by viewers that don't support more than 256 colors (if those still exist)
+*) add_id: add text chunk "Encoder: LodePNG <version>" to the image.
+*) text_compression: default 0. If 1, it'll store texts as zTXt instead of tEXt chunks.
+ zTXt chunks use zlib compression on the text. This gives a smaller result on
+ large texts but a larger result on small texts (such as a single program name).
+ It's all tEXt or all zTXt though, there's no separate setting per text yet.
+
+
+7. color conversions
+--------------------
+
+For trickier usage of LodePNG, you need to understand about PNG color types and
+about how and when LodePNG uses the settings in LodePNG_InfoPng, LodePNG_InfoRaw and Settings.
+
+=PNG color types=
+
+A PNG image can have many color types, ranging from 1-bit color to 64-bit color,
+as well as palettized color modes. After the zlib decompression and unfiltering
+in the PNG image is done, the raw pixel data will have that color type and thus
+a certain amount of bits per pixel. If you want the output raw image after
+decoding to have another color type, a conversion is done by LodePNG.
+
+The PNG specification mentions the following color types:
+
+0: greyscale, bit depths 1, 2, 4, 8, 16
+2: RGB, bit depths 8 and 16
+3: palette, bit depths 1, 2, 4 and 8
+4: greyscale with alpha, bit depths 8 and 16
+6: RGBA, bit depths 8 and 16
+
+Bit depth is the amount of bits per color channel.
+
+=Default Behaviour of LodePNG=
+
+By default, the Decoder will convert the data from the PNG to 32-bit RGBA color,
+no matter what color type the PNG has, so that the result can be used directly
+as a texture in OpenGL etc... without worries about what color type the original
+image has.
+
+The Encoder assumes by default that the raw input you give it is a 32-bit RGBA
+buffer and will store the PNG as either 32 bit or 24 bit depending on whether
+or not any translucent pixels were detected in it.
+
+To get the default behaviour, don't change the values of LodePNG_InfoRaw and LodePNG_InfoPng of
+the encoder, and don't change the values of LodePNG_InfoRaw of the decoder.
+
+=Color Conversions=
+
+As explained in the sections about the Encoder and Decoder, you can specify
+color types and bit depths in LodePNG_InfoPng and LodePNG_InfoRaw, to change the default behaviour
+explained above. (for the Decoder you can only specify the LodePNG_InfoRaw, because the
+LodePNG_InfoPng contains what the PNG file has).
+
+To avoid some confusion:
+-the Decoder converts from PNG to raw image
+-the Encoder converts from raw image to PNG
+-the color type and bit depth in LodePNG_InfoRaw, are those of the raw image
+-the color type and bit depth in LodePNG_InfoPng, are those of the PNG
+-if the color type of the LodePNG_InfoRaw and PNG image aren't the same, a conversion
+between the color types is done if the color types are supported
+
+Supported color types:
+-It's possible to load PNGs from any colortype and to save PNGs of any colorType.
+-Both encoder and decoder use the same converter. So both encoder and decoder
+suport the same color types at the input and the output. So the decoder supports
+any type of PNG image and can convert it to certain types of raw image, while the
+encoder supports any type of raw data but only certain color types for the output PNG.
+-The converter can convert from _any_ input color type, to 24-bit RGB or 32-bit RGBA
+-The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha
+-If both color types are the same, conversion from anything to anything is possible
+-Color types that are invalid according to the PNG specification are not allowed
+-When converting from a type with alpha channel to one without, the alpha channel information is discarded
+-When converting from a type without alpha channel to one with, the result will be opaque except pixels that have the same color as the color key of the input if one was given
+-When converting from 16-bit bitDepth to 8-bit bitDepth, the 16-bit precision information is lost, only the most significant byte is kept
+-Converting from color to greyscale is not supported on purpose: choosing what kind of color to greyscale conversion to do is not a decision a PNG codec should make
+-Converting from/to a palette type, only keeps the indices, it ignores the colors defined in the palette
+
+No conversion needed...:
+-If the color type of the PNG image and raw image are the same, then no
+conversion is done, and all color types are supported.
+-In the encoder, you can make it save a PNG with any color by giving the
+LodePNG_InfoRaw and LodePNG_InfoPng the same color type.
+-In the decoder, you can make it store the pixel data in the same color type
+as the PNG has, by setting the color_convert setting to false. Settings in
+infoRaw are then ignored.
+
+The function LodePNG_convert does this, which is available in the interface but
+normally isn't needed since the encoder and decoder already call it.
+
+=More Notes=
+
+In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines
+have a bit amount that isn't a multiple of 8, then padding bits are used so that each
+scanline starts at a fresh byte.
+However: The input image you give to the encoder, and the output image you get from the decoder
+will NOT have these padding bits in that case, e.g. in the case of a 1-bit image with a width
+of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte,
+not the first bit of a new byte.
+
+8. info values
+--------------
+
+Both the encoder and decoder use a variable of type LodePNG_InfoPng and LodePNG_InfoRaw, which
+both also contain a LodePNG_InfoColor. Here's a list of each of the values stored in them:
+
+*) info from the PNG header (IHDR chunk):
+
+width: width of the image in pixels
+height: height of the image in pixels
+colorType: color type of the original PNG file
+bitDepth: bits per sample
+compressionMethod: compression method of the original file. Always 0.
+filterMethod: filter method of the original file. Always 0.
+interlaceMethod: interlace method of the original file. 0 is no interlace, 1 is adam7 interlace.
+
+Note: width and height are only used as information of a decoded PNG image. When encoding one, you don't have
+to specify width and height in an LodePNG_Info struct, but you give them as parameters of the encode function.
+The rest of the LodePNG_Info struct IS used by the encoder though!
+
+*) palette:
+
+This is a dynamically allocated unsigned char array with the colors of the palette. The value palettesize
+indicates the amount of colors in the palette. The allocated size of the buffer is 4 * palettesize bytes,
+because there are 4 values per color: R, G, B and A. Even if less color channels are used, the palette
+is always in RGBA format, in the order RGBARGBARGBA.....
+
+When encoding a PNG, to store your colors in the palette of the LodePNG_InfoRaw, first use
+LodePNG_InfoColor_clearPalette, then for each color use LodePNG_InfoColor_addPalette.
+In the C++ version the Encoder class also has the above functions available directly in its interface.
+
+Note that the palette information from the tRNS chunk is also already included in this palette vector.
+
+If you encode an image with palette, don't forget that you have to set the alpha channels (A) of the palette
+too, set them to 255 for an opaque palette. If you leave them at zero, the image will be encoded as
+fully invisible. This both for the palette in the infoRaw and the infoPng if the png is to have a palette.
+
+*) transparent color key
+
+key_defined: is a transparent color key given?
+key_r: red/greyscale component of color key
+key_g: green component of color key
+key_b: blue component of color key
+
+For greyscale PNGs, r, g and b will all 3 be set to the same.
+
+This color is 8-bit for 8-bit PNGs, 16-bit for 16-bit per channel PNGs.
+
+*) suggested background color
+
+background_defined: is a suggested background color given?
+background_r: red component of sugg. background color
+background_g: green component of sugg. background color
+background_b: blue component of sugg. background color
+
+This color is 8-bit for 8-bit PNGs, 16-bit for 16-bit PNGs
+
+For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
+the encoder writes the red one away.
+For palette PNGs: When decoding, the RGB value will be stored, no a palette
+index. But when encoding, specify the index of the palette in background_r,
+the other two are then ignored.
+
+The decoder pretty much ignores this background color, after all if you make a
+PNG translucent normally you intend it to be used against any background, on
+websites, as translucent textures in games, ... But you can get the color this
+way if needed.
+
+*) text and itext
+
+Non-international text:
+
+-text.keys: a char** buffer containing the keywords (see below)
+-text.strings: a char** buffer containing the texts (see below)
+-text.num: the amount of texts in the above char** buffers (there may be more texts in itext)
+-LodePNG_InfoText_clearText: use this to clear the texts again after you filled them in
+-LodePNG_InfoText_addText: this function is used to push back a keyword and text
+
+International text: This is stored in separate arrays! The sum text.num and itext.num is the real amount of texts.
+
+-itext.keys: keyword in English
+-itext.langtags: ISO 639 letter code for the language
+-itext.transkeys: keyword in this language
+-itext.strings: the text in this language, in UTF-8
+-itext.num: the amount of international texts in this PNG
+-LodePNG_InfoIText_clearText: use this to clear the itexts again after you filled them in
+-LodePNG_InfoIText_addText: this function is used to push back all 4 parts of an itext
+
+Don't allocate these text buffers yourself. Use the init/cleanup functions
+correctly and use addText and clearText.
+
+In the C++ version the Encoder class also has the above functions available directly in its interface.
+The char** buffers are used like the argv parameter of a main() function, and (i)text.num takes the role
+of argc.
+
+In a text, there must be as much keys as strings because they always form pairs. In an itext,
+there must always be as much keys, langtags, transkeys and strings.
+
+They keyword of text chunks gives a short description what the actual text
+represents. There are a few standard standard keywords recognised
+by many programs: Title, Author, Description, Copyright, Creation Time,
+Software, Disclaimer, Warning, Source, Comment. It's allowed to use other keys.
+
+The keyword is minimum 1 character and maximum 79 characters long. It's
+discouraged to use a single line length longer than 79 characters for texts.
+
+*) additional color info
+
+These functions are available with longer names in the C version, and directly
+in the Decoder's interface in the C++ version.
+
+getBpp(): bits per pixel of the PNG image
+getChannels(): amount of color channels of the PNG image
+isGreyscaleType(): its color type 0 or 4
+isAlphaType(): its color type 2 or 6
+
+These values are calculated out of color type and bit depth of InfoColor.
+
+The difference between bits per pixel and bit depth is that bit depth is the
+number of bits per color channel, while a pixel can have multiple channels.
+
+*) pHYs chunk (image dimensions)
+
+phys_defined: if 0, there is no pHYs chunk and the values are undefined, if 1 else there is one
+phys_x: pixels per unit in x direction
+phys_y: pixels per unit in y direction
+phys_unit: the unit, 0 is no unit (x and y only give the ratio), 1 is metre
+
+*) tIME chunk (modification time)
+
+time_defined: if 0, there is no tIME chunk and the values are undefined, if 1 there is one
+time: this struct contains year as a 2-byte number (0-65535), month, day, hour, minute,
+second as 1-byte numbers that must be in the correct range
+
+Note: to make the encoder add a time chunk, set time_defined to 1 and fill in
+the correct values in all the time parameters, LodePNG will not fill the current
+time in these values itself, all it does is copy them over into the chunk bytes.
+
+
+9. error values
+---------------
+
+The meanings of the LodePNG error values:
+
+*) 0: no error, everything went ok
+*) 1: the Encoder/Decoder has done nothing yet, so error checking makes no sense yet
+*) 10: while huffman decoding: end of input memory reached without endcode
+*) 11: while huffman decoding: error in code tree made it jump outside of tree
+*) 13: problem while processing dynamic deflate block
+*) 14: problem while processing dynamic deflate block
+*) 15: problem while processing dynamic deflate block
+*) 16: unexisting code while processing dynamic deflate block
+*) 17: while inflating: end of out buffer memory reached
+*) 18: while inflating: invalid distance code
+*) 19: while inflating: end of out buffer memory reached
+*) 20: invalid deflate block BTYPE encountered while decoding
+*) 21: NLEN is not ones complement of LEN in a deflate block
+*) 22: while inflating: end of out buffer memory reached.
+ This can happen if the inflated deflate data is longer than the amount of bytes required to fill up
+ all the pixels of the image, given the color depth and image dimensions. Something that doesn't
+ happen in a normal, well encoded, PNG image.
+*) 23: while inflating: end of in buffer memory reached
+*) 24: invalid FCHECK in zlib header
+*) 25: invalid compression method in zlib header
+*) 26: FDICT encountered in zlib header while it's not used for PNG
+*) 27: PNG file is smaller than a PNG header
+*) 28: incorrect PNG signature (the first 8 bytes of the PNG file)
+ Maybe it's not a PNG, or a PNG file that got corrupted so that the header indicates the corruption.
+*) 29: first chunk is not the header chunk
+*) 30: chunk length too large, chunk broken off at end of file
+*) 31: illegal PNG color type or bpp
+*) 32: illegal PNG compression method
+*) 33: illegal PNG filter method
+*) 34: illegal PNG interlace method
+*) 35: chunk length of a chunk is too large or the chunk too small
+*) 36: illegal PNG filter type encountered
+*) 37: illegal bit depth for this color type given
+*) 38: the palette is too big (more than 256 colors)
+*) 39: more palette alpha values given in tRNS, than there are colors in the palette
+*) 40: tRNS chunk has wrong size for greyscale image
+*) 41: tRNS chunk has wrong size for RGB image
+*) 42: tRNS chunk appeared while it was not allowed for this color type
+*) 43: bKGD chunk has wrong size for palette image
+*) 44: bKGD chunk has wrong size for greyscale image
+*) 45: bKGD chunk has wrong size for RGB image
+*) 46: value encountered in indexed image is larger than the palette size (bitdepth == 8). Is the palette too small?
+*) 47: value encountered in indexed image is larger than the palette size (bitdepth < 8). Is the palette too small?
+*) 48: the input data is empty. Maybe a PNG file you tried to load doesn't exist or is in the wrong path.
+*) 49: jumped past memory while generating dynamic huffman tree
+*) 50: jumped past memory while generating dynamic huffman tree
+*) 51: jumped past memory while inflating huffman block
+*) 52: jumped past memory while inflating
+*) 53: size of zlib data too small
+*) 55: jumped past tree while generating huffman tree, this could be when the
+ tree will have more leaves than symbols after generating it out of the
+ given lengths. They call this an oversubscribed dynamic bit lengths tree in zlib.
+*) 56: given output image colorType or bitDepth not supported for color conversion
+*) 57: invalid CRC encountered (checking CRC can be disabled)
+*) 58: invalid ADLER32 encountered (checking ADLER32 can be disabled)
+*) 59: conversion to unexisting or unsupported color type or bit depth requested by encoder or decoder
+*) 60: invalid window size given in the settings of the encoder (must be 0-32768)
+*) 61: invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)
+*) 62: conversion from non-greyscale color to greyscale color requested by encoder or decoder. LodePNG
+ leaves the choice of RGB to greyscale conversion formula to the user.
+*) 63: length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk (2^31-1)
+*) 64: the length of the "end" symbol 256 in the Huffman tree is 0, resulting in the inability of a deflated
+ block to ever contain an end code. It must be at least 1.
+*) 66: the length of a text chunk keyword given to the encoder is longer than the maximum 79 bytes.
+*) 67: the length of a text chunk keyword given to the encoder is smaller than the minimum 1 byte.
+*) 68: tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors
+*) 69: unknown chunk type with "critical" flag encountered by the decoder
+*) 71: unexisting interlace mode given to encoder (must be 0 or 1)
+*) 72: while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)
+*) 73: invalid tIME chunk size
+*) 74: invalid pHYs chunk size
+*) 75: no null termination char found while decoding any kind of text chunk, or wrong length
+*) 76: iTXt chunk too short to contain required bytes
+*) 77: integer overflow in buffer size happened somewhere
+*) 78: file doesn't exist or couldn't be opened for reading
+*) 79: file couldn't be opened for writing
+*) 80: tried creating a tree for 0 symbols
+*) 9900-9999: out of memory while allocating chunk of memory somewhere
+
+
+10. file IO
+-----------
+
+For cases where you want to load the PNG image from a file, you can use your own
+file loading code, or the file loading and saving functions provided with
+LodePNG. These use the same unsigned char format used by the Decoder and Encoder.
+
+The loadFile function fills the given buffer up with the file from harddisk
+with the given name.
+
+The saveFile function saves the contents of the given buffer to the file
+with given name. Warning: this overwrites the contents that were previously in
+the file if it already existed, without warning.
+
+Note that you don't have to decode a PNG image from a file, you can as well
+retrieve the buffer another way in your code, because the decode function takes
+a buffer as parameter, not a filename.
+
+Both C and C++ versions of the loadFile and saveFile functions are available.
+For the C version of loadFile, you need to free() the buffer after use. The
+C++ versions use std::vectors so they clean themselves automatically.
+
+
+11. chunks and PNG editing
+--------------------------
+
+If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG
+editor that should follow the rules about handling of unknown chunks, or if you
+program is able to read other types of chunks than the ones handled by LodePNG,
+then that's possible with the chunk functions of LodePNG.
+
+A PNG chunk has the following layout:
+
+4 bytes length
+4 bytes type name
+length bytes data
+4 bytes CRC
+
+
+11.1 iterating through chunks
+-----------------------------
+
+If you have a buffer containing the PNG image data, then the first chunk (the
+IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the
+signature of the PNG and are not part of a chunk. But if you start at byte 8
+then you have a chunk, and can check the following things of it.
+
+NOTE: none of these functions check for memory buffer boundaries. To avoid
+exploits, always make sure the buffer contains all the data of the chunks.
+When using LodePNG_chunk_next, make sure the returned value is within the
+allocated memory.
+
+unsigned LodePNG_chunk_length(const unsigned char* chunk):
+
+Get the length of the chunk's data. The total chunk length is this length + 12.
+
+void LodePNG_chunk_type(char type[5], const unsigned char* chunk):
+unsigned char LodePNG_chunk_type_equals(const unsigned char* chunk, const char* type):
+
+Get the type of the chunk or compare if it's a certain type
+
+unsigned char LodePNG_chunk_critical(const unsigned char* chunk):
+unsigned char LodePNG_chunk_private(const unsigned char* chunk):
+unsigned char LodePNG_chunk_safetocopy(const unsigned char* chunk):
+
+Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are).
+Check if the chunk is private (public chunks are part of the standard, private ones not).
+Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical
+chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your
+program doesn't handle that type of unknown chunk.
+
+unsigned char* LodePNG_chunk_data(unsigned char* chunk):
+const unsigned char* LodePNG_chunk_data_const(const unsigned char* chunk):
+
+Get a pointer to the start of the data of the chunk.
+
+unsigned LodePNG_chunk_check_crc(const unsigned char* chunk):
+void LodePNG_chunk_generate_crc(unsigned char* chunk):
+
+Check if the crc is correct or generate a correct one.
+
+unsigned char* LodePNG_chunk_next(unsigned char* chunk):
+const unsigned char* LodePNG_chunk_next_const(const unsigned char* chunk):
+
+Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these
+functions do no boundary checking of the allocated data whatsoever, so make sure there is enough
+data available in the buffer to be able to go to the next chunk.
+
+unsigned LodePNG_append_chunk(unsigned char** out, size_t* outlength, const unsigned char* chunk):
+unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data):
+
+These functions are used to create new chunks that are appended to the data in *out that has
+length *outlength. The append function appends an existing chunk to the new data. The create
+function creates a new chunk with the given parameters and appends it. Type is the 4-letter
+name of the chunk.
+
+
+11.2 chunks in infoPng
+----------------------
+
+The LodePNG_InfoPng struct contains a struct LodePNG_UnknownChunks in it. This
+struct has 3 buffers (each with size) to contain 3 types of unknown chunks:
+the ones that come before the PLTE chunk, the ones that come between the PLTE
+and the IDAT chunks, and the ones that come after the IDAT chunks.
+It's necessary to make the distionction between these 3 cases because the PNG
+standard forces to keep the ordering of unknown chunks compared to the critical
+chunks, but does not force any other ordering rules.
+
+infoPng.unknown_chunks.data[0] is the chunks before PLTE
+infoPng.unknown_chunks.data[1] is the chunks after PLTE, before IDAT
+infoPng.unknown_chunks.data[2] is the chunks after IDAT
+
+The chunks in these 3 buffers can be iterated through and read by using the same
+way described in the previous subchapter.
+
+When using the decoder to decode a PNG, you can make it store all unknown chunks
+if you set the option settings.rememberUnknownChunks to 1. By default, this option
+is off and is 0.
+
+The encoder will always encode unknown chunks that are stored in the infoPng. If
+you need it to add a particular chunk that isn't known by LodePNG, you can use
+LodePNG_append_chunk or LodePNG_create_chunk to the chunk data in
+infoPng.unknown_chunks.data[x].
+
+Chunks that are known by LodePNG should not be added in that way. E.g. to make
+LodePNG add a bKGD chunk, set background_defined to true and add the correct
+parameters there and LodePNG will generate the chunk.
+
+
+12. compiler support
+--------------------
+
+No libraries other than the current standard C library are needed to compile
+LodePNG. For the C++ version, only the standard C++ library is needed on top.
+Add the files lodepng.c(pp) and lodepng.h to your project, include
+lodepng.h where needed, and your program can read/write PNG files.
+
+Use optimization! For both the encoder and decoder, compiling with the best
+optimizations makes a large difference.
+
+Make sure that LodePNG is compiled with the same compiler of the same version
+and with the same settings as the rest of the program, or the interfaces with
+std::vectors and std::strings in C++ can be incompatible resulting in bad things.
+
+CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets.
+
+*) gcc and g++
+
+LodePNG is developed in gcc so this compiler is natively supported. It gives no
+warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++
+version 4.2.2 on Linux.
+
+*) Mingw and Bloodshed DevC++
+
+The Mingw compiler (a port of gcc) used by Bloodshed DevC++ for Windows is fully
+supported by LodePNG.
+
+*) Visual Studio 2005 and Visual C++ 2005 Express Edition
+
+Versions 20070604 up to 20080107 have been tested on VS2005 and work. There are no
+warnings, except two warnings about 'fopen' being deprecated. 'fopen' is a function
+required by the C standard, so this warning is the fault of VS2005, it's nice of
+them to enforce secure code, however the multiplatform LodePNG can't follow their
+non-standard extensions. LodePNG is fully ISO C90 compliant.
+
+If you're using LodePNG in VS2005 and don't want to see the deprecated warnings,
+put this on top of lodepng.h before the inclusions: #define _CRT_SECURE_NO_DEPRECATE
+
+*) Visual Studio 6.0
+
+The C++ version of LodePNG was not supported by Visual Studio 6.0 because Visual
+Studio 6.0 doesn't follow the C++ standard and implements it incorrectly.
+The current C version of LodePNG has not been tested in VS6 but may work now.
+
+*) Comeau C/C++
+
+Vesion 20070107 compiles without problems on the Comeau C/C++ Online Test Drive
+at http://www.comeaucomputing.com/tryitout in both C90 and C++ mode.
+
+*) Compilers on Macintosh
+
+I'd love to support Macintosh but don't have one available to test it on.
+If it doesn't work with your compiler, maybe it can be gotten to work with the
+gcc compiler for Macintosh. Someone reported that it doesn't work well at all
+for Macintosh. All information on attempts to get it to work on Mac is welcome.
+
+*) Other Compilers
+
+If you encounter problems on other compilers, I'm happy to help out make LodePNG
+support the compiler if it supports the ISO C90 and C++ standard well enough. If
+the required modification to support the compiler requires using non standard or
+lesser C/C++ code or headers, I won't support it.
+
+
+13. examples
+------------
+
+This decoder and encoder example show the most basic usage of LodePNG (using the
+classes, not the simple functions, which would be trivial)
+
+More complex examples can be found in:
+-lodepng_examples.c: 9 different examples in C, such as showing the image with SDL, ...
+-lodepng_examples.cpp: the exact same examples in C++ using the C++ wrapper of LodePNG
+
+
+13.1. decoder C++ example
+-------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+#include "lodepng.h"
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ const char* filename = argc > 1 ? argv[1] : "test.png";
+
+ //load and decode
+ std::vector<unsigned char> buffer, image;
+ LodePNG::loadFile(buffer, filename); //load the image file with given filename
+ LodePNG::Decoder decoder;
+ decoder.decode(image, buffer.size() ? &buffer[0] : 0, (unsigned)buffer.size()); //decode the png
+
+ //if there's an error, display it
+ if(decoder.hasError()) std::cout << "error: " << decoder.getError() << std::endl;
+
+ //the pixels are now in the vector "image", use it as texture, draw it, ...
+}
+
+//alternative version using the "simple" function
+int main(int argc, char *argv[])
+{
+ const char* filename = argc > 1 ? argv[1] : "test.png";
+
+ //load and decode
+ std::vector<unsigned char> image;
+ unsigned w, h;
+ unsigned error = LodePNG::decode(image, w, h, filename);
+
+ //if there's an error, display it
+ if(error != 0) std::cout << "error: " << error << std::endl;
+
+ //the pixels are now in the vector "image", use it as texture, draw it, ...
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+13.2 encoder C++ example
+------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+#include "lodepng.h"
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ //check if user gave a filename
+ if(argc <= 1)
+ {
+ std::cout << "please provide a filename to save to\n";
+ return 0;
+ }
+
+ //generate some image
+ std::vector<unsigned char> image;
+ image.resize(512 * 512 * 4);
+ for(unsigned y = 0; y < 512; y++)
+ for(unsigned x = 0; x < 512; x++)
+ {
+ image[4 * 512 * y + 4 * x + 0] = 255 * !(x & y);
+ image[4 * 512 * y + 4 * x + 1] = x ^ y;
+ image[4 * 512 * y + 4 * x + 2] = x | y;
+ image[4 * 512 * y + 4 * x + 3] = 255;
+ }
+
+ //encode and save
+ std::vector<unsigned char> buffer;
+ LodePNG::Encoder encoder;
+ encoder.encode(buffer, image, 512, 512);
+ LodePNG::saveFile(buffer, argv[1]);
+
+ //the same as the 4 lines of code above, but in 1 call:
+ //LodePNG::encode(argv[1], image, 512, 512);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+13.3 Decoder C example
+----------------------
+
+This example loads the PNG in 1 function call
+
+#include "lodepng.h"
+
+int main(int argc, char *argv[])
+{
+ unsigned error;
+ unsigned char* image;
+ size_t w, h;
+
+ if(argc <= 1) return 0;
+
+ error = LodePNG_decode3(&image, &w, &h, filename);
+
+ free(image);
+}
+
+
+14. LodeZlib
+------------
+
+Also available in the interface is LodeZlib. Both C and C++ versions of these
+functions are available. The interface is similar to that of the "simple" PNG
+encoding and decoding functions.
+
+LodeZlib can be used to zlib compress and decompress a buffer. It cannot be
+used to create gzip files however. Also, it only supports the part of zlib
+that is required for PNG, it does not support compression and decompression
+with dictionaries.
+
+
+15. changes
+-----------
+
+The version number of LodePNG is the date of the change given in the format
+yyyymmdd.
+
+Some changes aren't backwards compatible. Those are indicated with a (!)
+symbol.
+
+*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could
+ read by ignoring the problem but windows apps couldn't.
+*) 06 jun 2008: added more error checks for out of memory cases.
+*) 26 apr 2008: added a few more checks here and there to ensure more safety.
+*) 06 mar 2008: crash with encoding of strings fixed
+*) 02 feb 2008: support for international text chunks added (iTXt)
+*) 23 jan 2008: small cleanups, and #defines to divide code in sections
+*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor.
+*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder.
+*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added
+ Also vareous fixes, such as in the deflate and the padding bits code.
+*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved
+ filtering code of encoder.
+*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A
+ C++ wrapper around this provides an interface almost identical to before.
+ Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code
+ are together in these files but it works both for C and C++ compilers.
+*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks
+*) 30 aug 2007: bug fixed which makes this Borland C++ compatible
+*) 09 aug 2007: some VS2005 warnings removed again
+*) 21 jul 2007: deflate code placed in new namespace separate from zlib code
+*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images
+*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing
+ invalid std::vector element [0] fixed, and level 3 and 4 warnings removed
+*) 02 jun 2007: made the encoder add a tag with version by default
+*) 27 may 2007: zlib and png code separated (but still in the same file),
+ simple encoder/decoder functions added for more simple usage cases
+*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69),
+ moved some examples from here to lodepng_examples.cpp
+*) 12 may 2007: palette decoding bug fixed
+*) 24 apr 2007: changed the license from BSD to the zlib license
+*) 11 mar 2007: very simple addition: ability to encode bKGD chunks.
+*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding
+ palettized PNG images. Plus little interface change with palette and texts.
+*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes.
+ Fixed a bug where the end code of a block had length 0 in the Huffman tree.
+*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented
+ and supported by the encoder, resulting in smaller PNGs at the output.
+*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone.
+*) 24 jan 2007: gave encoder an error interface. Added color conversion from any
+ greyscale type to 8-bit greyscale with or without alpha.
+*) 21 jan 2007: (!) Totally changed the interface. It allows more color types
+ to convert to and is more uniform. See the manual for how it works now.
+*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days:
+ encode/decode custom tEXt chunks, separate classes for zlib & deflate, and
+ at last made the decoder give errors for incorrect Adler32 or Crc.
+*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel.
+*) 29 dec 2006: Added support for encoding images without alpha channel, and
+ cleaned out code as well as making certain parts faster.
+*) 28 dec 2006: Added "Settings" to the encoder.
+*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now.
+ Removed some code duplication in the decoder. Fixed little bug in an example.
+*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter.
+ Fixed a bug of the decoder with 16-bit per color.
+*) 15 okt 2006: Changed documentation structure
+*) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the
+ given image buffer, however for now it's not compressed.
+*) 08 sep 2006: (!) Changed to interface with a Decoder class
+*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different
+ way. Renamed decodePNG to decodePNGGeneric.
+*) 29 jul 2006: (!) Changed the interface: image info is now returned as a
+ struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy.
+*) 28 jul 2006: Cleaned the code and added new error checks.
+ Corrected terminology "deflate" into "inflate".
+*) 23 jun 2006: Added SDL example in the documentation in the header, this
+ example allows easy debugging by displaying the PNG and its transparency.
+*) 22 jun 2006: (!) Changed way to obtain error value. Added
+ loadFile function for convenience. Made decodePNG32 faster.
+*) 21 jun 2006: (!) Changed type of info vector to unsigned.
+ Changed position of palette in info vector. Fixed an important bug that
+ happened on PNGs with an uncompressed block.
+*) 16 jun 2006: Internally changed unsigned into unsigned where
+ needed, and performed some optimizations.
+*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them
+ in LodePNG namespace. Changed the order of the parameters. Rewrote the
+ documentation in the header. Renamed files to lodepng.cpp and lodepng.h
+*) 22 apr 2006: Optimized and improved some code
+*) 07 sep 2005: (!) Changed to std::vector interface
+*) 12 aug 2005: Initial release
+
+
+16. contact information
+-----------------------
+
+Feel free to contact me with suggestions, problems, comments, ... concerning
+LodePNG. If you encounter a PNG image that doesn't work properly with this
+decoder, feel free to send it and I'll use it to find and fix the problem.
+
+My email address is (puzzle the account and domain together with an @ symbol):
+Domain: gmail dot com.
+Account: lode dot vandevenne.
+
+
+Copyright (c) 2005-2008 Lode Vandevenne
+*/
diff --git a/src/logos.cpp b/src/logos.cpp
new file mode 100644
index 0000000..9a9e5db
--- /dev/null
+++ b/src/logos.cpp
@@ -0,0 +1,1985 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+
+#include <qfile.h>
+#include <qdir.h>
+
+// Stripped version of FreeSans.ttf part of FreeFonts package,
+// see http://www.nongnu.org/freefont for more info
+unsigned char FreeSans_ttf[] = {
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70,
+ 0x47, 0x44, 0x45, 0x46, 0x01, 0x0a, 0x00, 0xe3, 0x00, 0x00, 0x48, 0x28,
+ 0x00, 0x00, 0x00, 0x2a, 0x47, 0x50, 0x4f, 0x53, 0x9d, 0x1a, 0x99, 0x8a,
+ 0x00, 0x00, 0x49, 0x50, 0x00, 0x00, 0x10, 0x42, 0x47, 0x53, 0x55, 0x42,
+ 0xa8, 0x85, 0x92, 0x0c, 0x00, 0x00, 0x48, 0x54, 0x00, 0x00, 0x00, 0xfc,
+ 0x4f, 0x53, 0x2f, 0x32, 0x67, 0x3f, 0xcf, 0x10, 0x00, 0x00, 0x01, 0x78,
+ 0x00, 0x00, 0x00, 0x56, 0x63, 0x6d, 0x61, 0x70, 0xe6, 0xd7, 0x91, 0x3d,
+ 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x01, 0x8a, 0x63, 0x76, 0x74, 0x20,
+ 0x00, 0x21, 0x02, 0x79, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x04,
+ 0x67, 0x61, 0x73, 0x70, 0xff, 0xff, 0x00, 0x03, 0x00, 0x00, 0x48, 0x20,
+ 0x00, 0x00, 0x00, 0x08, 0x67, 0x6c, 0x79, 0x66, 0xb3, 0x58, 0xaf, 0x41,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x37, 0xca, 0x68, 0x65, 0x61, 0x64,
+ 0xe7, 0x18, 0xbe, 0xac, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x36,
+ 0x68, 0x68, 0x65, 0x61, 0x10, 0xbb, 0x06, 0xf2, 0x00, 0x00, 0x01, 0x34,
+ 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78, 0x55, 0x0d, 0x49, 0xe2,
+ 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x03, 0x1a, 0x6c, 0x6f, 0x63, 0x61,
+ 0x1f, 0xdd, 0x2c, 0xb6, 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x01, 0x94,
+ 0x6d, 0x61, 0x78, 0x70, 0x01, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x01, 0x58,
+ 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x85, 0x1f, 0xf3, 0x73,
+ 0x00, 0x00, 0x3f, 0xdc, 0x00, 0x00, 0x06, 0x69, 0x70, 0x6f, 0x73, 0x74,
+ 0x46, 0xf5, 0x10, 0xd8, 0x00, 0x00, 0x46, 0x48, 0x00, 0x00, 0x01, 0xd6,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xc2, 0x8f, 0x00, 0x8a, 0xba, 0xad,
+ 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x44, 0xd8, 0x89, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x44, 0xd8, 0x89,
+ 0xff, 0xd3, 0xfe, 0x3d, 0x07, 0x9c, 0x07, 0xd1, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x07, 0xd1, 0xfe, 0x3d, 0x01, 0x78, 0x08, 0x1e, 0xff, 0xd3, 0xff, 0xd2,
+ 0x07, 0x9c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0xc9, 0x00, 0x66, 0x00, 0x05, 0x00, 0x49, 0x00, 0x04, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x03, 0x87, 0x01, 0x90, 0x00, 0x05,
+ 0x00, 0x00, 0x05, 0x33, 0x05, 0x99, 0x00, 0x00, 0x03, 0xd7, 0x05, 0x33,
+ 0x05, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x02, 0x12, 0x00, 0x00,
+ 0x02, 0x0b, 0x05, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00,
+ 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x66, 0x45, 0x64, 0x00, 0x40, 0x00, 0x0d, 0x02, 0xdc,
+ 0x06, 0x66, 0xfe, 0x66, 0x00, 0x00, 0x07, 0xd1, 0x01, 0xc3, 0x80, 0x02,
+ 0x00, 0xbf, 0xdf, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x89,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00,
+ 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0xfe, 0x02, 0xd7, 0x00, 0x6a,
+ 0x04, 0x72, 0x00, 0x1d, 0x04, 0x72, 0x00, 0x44, 0x07, 0x1c, 0x00, 0x3b,
+ 0x05, 0x56, 0x00, 0x6a, 0x01, 0x87, 0x00, 0x62, 0x02, 0xa9, 0x00, 0x96,
+ 0x02, 0xa9, 0x00, 0x4e, 0x03, 0x1c, 0x00, 0x52, 0x04, 0xac, 0x00, 0x66,
+ 0x02, 0x39, 0x00, 0xb2, 0x02, 0xa9, 0x00, 0x5e, 0x02, 0x39, 0x00, 0xb2,
+ 0x02, 0x39, 0xff, 0xf0, 0x04, 0x72, 0x00, 0x58, 0x04, 0x72, 0x00, 0xd1,
+ 0x04, 0x72, 0x00, 0x46, 0x04, 0x72, 0x00, 0x42, 0x04, 0x72, 0x00, 0x39,
+ 0x04, 0x72, 0x00, 0x48, 0x04, 0x72, 0x00, 0x58, 0x04, 0x72, 0x00, 0x5e,
+ 0x04, 0x72, 0x00, 0x4c, 0x04, 0x72, 0x00, 0x4e, 0x02, 0x39, 0x00, 0xe1,
+ 0x02, 0x39, 0x00, 0xe1, 0x04, 0xac, 0x00, 0x5c, 0x04, 0xac, 0x00, 0x66,
+ 0x04, 0xac, 0x00, 0x66, 0x04, 0x72, 0x00, 0x9e, 0x08, 0x1e, 0x00, 0x46,
+ 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0xa2, 0x05, 0xc6, 0x00, 0x62,
+ 0x05, 0xc6, 0x00, 0xb6, 0x05, 0x56, 0x00, 0xb8, 0x04, 0xe3, 0x00, 0xb8,
+ 0x06, 0x39, 0x00, 0x5a, 0x05, 0xc6, 0x00, 0xaa, 0x02, 0x39, 0x00, 0xcd,
+ 0x04, 0x00, 0x00, 0x23, 0x05, 0x56, 0x00, 0xa2, 0x04, 0x72, 0x00, 0xa4,
+ 0x06, 0xa9, 0x00, 0x9a, 0x05, 0xc6, 0x00, 0x9c, 0x06, 0x39, 0x00, 0x4e,
+ 0x05, 0x56, 0x00, 0xba, 0x06, 0x39, 0x00, 0x4e, 0x05, 0xc6, 0x00, 0xbe,
+ 0x05, 0x56, 0x00, 0x62, 0x04, 0xe3, 0x00, 0x2b, 0x05, 0xc6, 0x00, 0xae,
+ 0x05, 0x56, 0x00, 0x3d, 0x07, 0x8d, 0x00, 0x2d, 0x05, 0x56, 0x00, 0x2d,
+ 0x05, 0x56, 0x00, 0x1b, 0x04, 0xe3, 0x00, 0x39, 0x02, 0x39, 0x00, 0x83,
+ 0x02, 0x39, 0xff, 0xf0, 0x02, 0x39, 0x00, 0x2f, 0x03, 0xc0, 0x00, 0x5a,
+ 0x04, 0x72, 0xff, 0xd3, 0x02, 0xa9, 0x00, 0x2d, 0x04, 0x72, 0x00, 0x56,
+ 0x04, 0x72, 0x00, 0x6f, 0x04, 0x00, 0x00, 0x3f, 0x04, 0x72, 0x00, 0x35,
+ 0x04, 0x72, 0x00, 0x52, 0x02, 0x39, 0x00, 0x25, 0x04, 0x72, 0x00, 0x3b,
+ 0x04, 0x72, 0x00, 0x8f, 0x01, 0xc6, 0x00, 0x87, 0x01, 0xc6, 0xff, 0xdb,
+ 0x04, 0x00, 0x00, 0x77, 0x01, 0xc6, 0x00, 0x8b, 0x06, 0xa9, 0x00, 0x8f,
+ 0x04, 0x72, 0x00, 0x8f, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x6f,
+ 0x04, 0x72, 0x00, 0x35, 0x02, 0xa9, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x46,
+ 0x02, 0x39, 0x00, 0x1d, 0x04, 0x72, 0x00, 0x85, 0x04, 0x00, 0x00, 0x14,
+ 0x05, 0xc6, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x23, 0x04, 0x00, 0x00, 0x29,
+ 0x04, 0x00, 0x00, 0x3f, 0x02, 0xac, 0x00, 0x58, 0x02, 0x14, 0x00, 0xcd,
+ 0x02, 0xac, 0x00, 0x3b, 0x04, 0xac, 0x00, 0x9a, 0x02, 0x39, 0x00, 0x00,
+ 0x02, 0x39, 0x00, 0xfa, 0x04, 0x72, 0x00, 0x6a, 0x04, 0x72, 0x00, 0x35,
+ 0x04, 0x72, 0x00, 0x89, 0x04, 0x72, 0x00, 0x17, 0x02, 0x14, 0x00, 0xcd,
+ 0x04, 0x72, 0x00, 0x58, 0x02, 0xa9, 0x00, 0x3d, 0x05, 0xe5, 0xff, 0xe5,
+ 0x02, 0xf5, 0x00, 0x4c, 0x04, 0x72, 0x00, 0xc9, 0x04, 0xac, 0x00, 0x52,
+ 0x02, 0xa9, 0x00, 0x5e, 0x05, 0xe5, 0xff, 0xe5, 0x02, 0xa9, 0x00, 0x39,
+ 0x04, 0xd9, 0x01, 0x35, 0x04, 0xac, 0x00, 0x66, 0x02, 0xce, 0x00, 0x27,
+ 0x02, 0xce, 0x00, 0x21, 0x02, 0xa9, 0x00, 0xbc, 0x04, 0x72, 0x00, 0x85,
+ 0x04, 0x4b, 0x00, 0x62, 0x02, 0x39, 0x00, 0xb2, 0x02, 0xa9, 0x00, 0x50,
+ 0x02, 0xce, 0x00, 0x7d, 0x02, 0xeb, 0x00, 0x52, 0x04, 0x72, 0x00, 0xc9,
+ 0x06, 0xf3, 0x00, 0x7d, 0x06, 0xf3, 0x00, 0x7d, 0x06, 0xf3, 0x00, 0x21,
+ 0x04, 0x72, 0x00, 0xc5, 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23,
+ 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23,
+ 0x05, 0x56, 0x00, 0x23, 0x08, 0x00, 0x00, 0x17, 0x05, 0xc6, 0x00, 0x62,
+ 0x05, 0x56, 0x00, 0xb8, 0x05, 0x56, 0x00, 0xb8, 0x05, 0x56, 0x00, 0xb8,
+ 0x05, 0x56, 0x00, 0xb8, 0x02, 0x39, 0x00, 0xcd, 0x02, 0x39, 0x00, 0xcd,
+ 0x02, 0x39, 0x00, 0xcd, 0x02, 0x39, 0x00, 0x1c, 0x05, 0xc6, 0x00, 0x29,
+ 0x05, 0xc6, 0x00, 0x9c, 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e,
+ 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e,
+ 0x04, 0xac, 0x00, 0xc3, 0x06, 0x39, 0x00, 0x3d, 0x05, 0xc6, 0x00, 0xae,
+ 0x05, 0xc6, 0x00, 0xae, 0x05, 0xc6, 0x00, 0xae, 0x05, 0xc6, 0x00, 0xae,
+ 0x05, 0x56, 0x00, 0x1b, 0x05, 0x53, 0x00, 0xba, 0x04, 0xe3, 0x00, 0x89,
+ 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56,
+ 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56,
+ 0x07, 0x1c, 0x00, 0x46, 0x04, 0x00, 0x00, 0x3f, 0x04, 0x72, 0x00, 0x52,
+ 0x04, 0x72, 0x00, 0x52, 0x04, 0x72, 0x00, 0x52, 0x04, 0x72, 0x00, 0x52,
+ 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00,
+ 0x02, 0x39, 0x00, 0x06, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x8f,
+ 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a,
+ 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a, 0x04, 0xac, 0x00, 0x66,
+ 0x04, 0xe3, 0x00, 0x25, 0x04, 0x72, 0x00, 0x85, 0x04, 0x72, 0x00, 0x85,
+ 0x04, 0x72, 0x00, 0x85, 0x04, 0x72, 0x00, 0x85, 0x04, 0x00, 0x00, 0x29,
+ 0x04, 0x70, 0x00, 0x6f, 0x04, 0x00, 0x00, 0x29, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x03, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x10, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e,
+ 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x02, 0xc6, 0x02, 0xcb, 0x02, 0xda,
+ 0x02, 0xdc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e,
+ 0x00, 0x20, 0x00, 0xa0, 0x01, 0x31, 0x02, 0xc6, 0x02, 0xca, 0x02, 0xda,
+ 0x02, 0xdc, 0xff, 0xff, 0x00, 0x01, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xe4,
+ 0xff, 0xc3, 0xff, 0x92, 0xfd, 0xfe, 0xfd, 0xfb, 0xfd, 0xed, 0xfd, 0xec,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x93, 0xb3, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0xc0, 0x02, 0x00, 0xa1, 0xc1, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x7f, 0x7c, 0x81, 0x76, 0x75, 0x69, 0x70, 0x9a,
+ 0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d,
+ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
+ 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
+ 0x62, 0x00, 0x87, 0x88, 0x8a, 0x8c, 0x94, 0x99, 0x9f, 0xa4, 0xa3, 0xa5,
+ 0xa7, 0xa6, 0xa8, 0xaa, 0xac, 0xab, 0xad, 0xae, 0xb0, 0xaf, 0xb1, 0xb2,
+ 0xb4, 0xb6, 0xb5, 0xb7, 0xb9, 0xb8, 0xbd, 0xbc, 0xbe, 0xbf, 0x00, 0x73,
+ 0x65, 0x66, 0x6a, 0x00, 0x79, 0xa2, 0x71, 0x6c, 0x00, 0x77, 0x6b, 0x00,
+ 0x89, 0x9b, 0x00, 0x74, 0x00, 0x00, 0x68, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x6d, 0x7d, 0x00, 0xa9, 0xbb, 0x82, 0x64, 0x6f, 0x00, 0x00, 0x00,
+ 0x00, 0x6e, 0x7e, 0x00, 0x63, 0x83, 0x86, 0x98, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x85, 0x8d, 0x84, 0x8e, 0x8b,
+ 0x90, 0x91, 0x92, 0x8f, 0x96, 0x97, 0x00, 0x95, 0x9d, 0x9e, 0x9c, 0x00,
+ 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x21, 0x02, 0x79, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+ 0x00, 0x16, 0x00, 0x16, 0x00, 0x2e, 0x00, 0x48, 0x00, 0x7f, 0x00, 0xe5,
+ 0x01, 0x5d, 0x01, 0xc9, 0x01, 0xd9, 0x01, 0xfd, 0x02, 0x20, 0x02, 0x3e,
+ 0x02, 0x56, 0x02, 0x6c, 0x02, 0x79, 0x02, 0x85, 0x02, 0x93, 0x02, 0xc3,
+ 0x02, 0xda, 0x03, 0x16, 0x03, 0x63, 0x03, 0x80, 0x03, 0xbe, 0x04, 0x0c,
+ 0x04, 0x2a, 0x04, 0x84, 0x04, 0xd4, 0x04, 0xe6, 0x05, 0x03, 0x05, 0x17,
+ 0x05, 0x2b, 0x05, 0x3f, 0x05, 0x7d, 0x06, 0x10, 0x06, 0x2c, 0x06, 0x6d,
+ 0x06, 0xaa, 0x06, 0xd3, 0x06, 0xec, 0x07, 0x02, 0x07, 0x50, 0x07, 0x68,
+ 0x07, 0x76, 0x07, 0x99, 0x07, 0xb5, 0x07, 0xc6, 0x07, 0xe2, 0x07, 0xfa,
+ 0x08, 0x47, 0x08, 0x72, 0x08, 0xc7, 0x09, 0x08, 0x09, 0x57, 0x09, 0x6a,
+ 0x09, 0x8f, 0x09, 0xa2, 0x09, 0xc1, 0x09, 0xe0, 0x09, 0xf7, 0x0a, 0x0e,
+ 0x0a, 0x20, 0x0a, 0x2f, 0x0a, 0x41, 0x0a, 0x54, 0x0a, 0x61, 0x0a, 0x70,
+ 0x0a, 0xd1, 0x0b, 0x0b, 0x0b, 0x3e, 0x0b, 0x79, 0x0b, 0xba, 0x0b, 0xdc,
+ 0x0c, 0x34, 0x0c, 0x5b, 0x0c, 0x6f, 0x0c, 0x91, 0x0c, 0xae, 0x0c, 0xbc,
+ 0x0c, 0xfb, 0x0d, 0x21, 0x0d, 0x55, 0x0d, 0x8c, 0x0d, 0xc6, 0x0d, 0xe3,
+ 0x0e, 0x2f, 0x0e, 0x55, 0x0e, 0x7b, 0x0e, 0x8e, 0x0e, 0xaa, 0x0e, 0xc9,
+ 0x0e, 0xec, 0x0f, 0x03, 0x0f, 0x43, 0x0f, 0x50, 0x0f, 0x8f, 0x0f, 0xc0,
+ 0x0f, 0xc8, 0x0f, 0xd2, 0x10, 0x13, 0x10, 0x73, 0x10, 0xbe, 0x10, 0xe8,
+ 0x10, 0xfb, 0x11, 0x77, 0x11, 0x89, 0x12, 0x03, 0x12, 0x5c, 0x12, 0x78,
+ 0x12, 0x88, 0x12, 0x95, 0x13, 0x17, 0x13, 0x24, 0x13, 0x55, 0x13, 0x74,
+ 0x13, 0xb1, 0x13, 0xf8, 0x14, 0x06, 0x14, 0x38, 0x14, 0x5a, 0x14, 0x68,
+ 0x14, 0x99, 0x14, 0xb1, 0x14, 0xea, 0x15, 0x07, 0x15, 0x3d, 0x15, 0x94,
+ 0x15, 0xf9, 0x16, 0x03, 0x16, 0x0f, 0x16, 0x1b, 0x16, 0x27, 0x16, 0x33,
+ 0x16, 0x3f, 0x16, 0x4b, 0x16, 0x72, 0x16, 0xdc, 0x16, 0xe8, 0x16, 0xf4,
+ 0x17, 0x00, 0x17, 0x0c, 0x17, 0x18, 0x17, 0x24, 0x17, 0x30, 0x17, 0x3c,
+ 0x17, 0x70, 0x17, 0x7c, 0x17, 0x88, 0x17, 0x94, 0x17, 0xa0, 0x17, 0xac,
+ 0x17, 0xb8, 0x17, 0xd9, 0x18, 0x2e, 0x18, 0x3a, 0x18, 0x46, 0x18, 0x52,
+ 0x18, 0x5e, 0x18, 0x6a, 0x18, 0x95, 0x18, 0xdf, 0x18, 0xeb, 0x18, 0xf7,
+ 0x19, 0x03, 0x19, 0x0f, 0x19, 0x1b, 0x19, 0x27, 0x19, 0xa9, 0x1a, 0x05,
+ 0x1a, 0x11, 0x1a, 0x1d, 0x1a, 0x29, 0x1a, 0x35, 0x1a, 0x40, 0x1a, 0x4b,
+ 0x1a, 0x56, 0x1a, 0x61, 0x1a, 0xb5, 0x1a, 0xc1, 0x1a, 0xcd, 0x1a, 0xd9,
+ 0x1a, 0xe5, 0x1a, 0xf1, 0x1a, 0xfd, 0x1b, 0x17, 0x1b, 0x60, 0x1b, 0x6c,
+ 0x1b, 0x78, 0x1b, 0x84, 0x1b, 0x90, 0x1b, 0x9c, 0x1b, 0xd7, 0x1b, 0xe3,
+ 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3,
+ 0x00, 0x02, 0x00, 0x89, 0x00, 0x00, 0x03, 0xbe, 0x07, 0xd1, 0x00, 0x03,
+ 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x05, 0x21, 0x11, 0x21,
+ 0x03, 0xbe, 0xfc, 0xcb, 0x02, 0xac, 0xfd, 0xdd, 0x02, 0x23, 0x07, 0xd1,
+ 0xf8, 0x2f, 0x07, 0xd1, 0x89, 0xf9, 0x41, 0x00, 0x00, 0x02, 0x00, 0xfe,
+ 0x00, 0x00, 0x01, 0xaa, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00,
+ 0x01, 0x11, 0x03, 0x23, 0x03, 0x11, 0x13, 0x15, 0x23, 0x35, 0x01, 0xaa,
+ 0x2d, 0x50, 0x2d, 0xaa, 0xac, 0x05, 0xd5, 0xfd, 0x4c, 0xfe, 0x37, 0x01,
+ 0xc9, 0x02, 0xb4, 0xfb, 0x00, 0xd5, 0xd5, 0x00, 0x00, 0x02, 0x00, 0x6a,
+ 0x03, 0xb6, 0x02, 0x71, 0x05, 0xac, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00,
+ 0x13, 0x33, 0x15, 0x03, 0x23, 0x03, 0x25, 0x33, 0x15, 0x03, 0x23, 0x03,
+ 0x6a, 0xbf, 0x37, 0x50, 0x38, 0x01, 0x48, 0xbf, 0x38, 0x50, 0x37, 0x05,
+ 0xac, 0xe3, 0xfe, 0xed, 0x01, 0x13, 0xe3, 0xe3, 0xfe, 0xed, 0x01, 0x13,
+ 0x00, 0x02, 0x00, 0x1d, 0xff, 0xd7, 0x04, 0x56, 0x05, 0x93, 0x00, 0x1b,
+ 0x00, 0x1f, 0x00, 0x00, 0x01, 0x03, 0x33, 0x15, 0x23, 0x03, 0x33, 0x15,
+ 0x23, 0x03, 0x23, 0x13, 0x23, 0x03, 0x23, 0x13, 0x23, 0x35, 0x33, 0x13,
+ 0x23, 0x35, 0x33, 0x13, 0x33, 0x03, 0x21, 0x13, 0x03, 0x23, 0x03, 0x21,
+ 0x03, 0xe1, 0x49, 0xbe, 0xd9, 0x40, 0xd7, 0xef, 0x50, 0x9c, 0x4e, 0xfe,
+ 0x50, 0x9b, 0x4e, 0xcf, 0xe9, 0x40, 0xde, 0xf8, 0x4a, 0x9c, 0x4a, 0x01,
+ 0x00, 0x48, 0x63, 0xfe, 0x41, 0x01, 0x00, 0x05, 0x93, 0xfe, 0x6f, 0x8b,
+ 0xfe, 0x9b, 0x8b, 0xfe, 0x50, 0x01, 0xb0, 0xfe, 0x50, 0x01, 0xb0, 0x8b,
+ 0x01, 0x65, 0x8b, 0x01, 0x91, 0xfe, 0x6f, 0x01, 0x91, 0xfd, 0xe4, 0xfe,
+ 0x9b, 0x00, 0x00, 0x03, 0x00, 0x44, 0xfe, 0xfe, 0x04, 0x25, 0x06, 0x29,
+ 0x00, 0x2f, 0x00, 0x38, 0x00, 0x41, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06,
+ 0x07, 0x15, 0x23, 0x35, 0x24, 0x27, 0x26, 0x3d, 0x01, 0x33, 0x16, 0x17,
+ 0x16, 0x17, 0x16, 0x17, 0x11, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34,
+ 0x37, 0x36, 0x37, 0x35, 0x33, 0x15, 0x16, 0x17, 0x16, 0x15, 0x23, 0x26,
+ 0x27, 0x26, 0x27, 0x11, 0x17, 0x16, 0x17, 0x16, 0x01, 0x11, 0x06, 0x07,
+ 0x06, 0x15, 0x14, 0x17, 0x16, 0x13, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27,
+ 0x26, 0x27, 0x04, 0x25, 0xb0, 0x6a, 0xa1, 0x78, 0xfe, 0xec, 0x66, 0x34,
+ 0xa1, 0x0b, 0x12, 0x2e, 0x9b, 0x13, 0x14, 0xab, 0x3e, 0x0c, 0x0d, 0x92,
+ 0xcc, 0x54, 0x74, 0x78, 0xdb, 0x69, 0x4a, 0xa2, 0x02, 0x59, 0x3c, 0x55,
+ 0x8a, 0xde, 0x3c, 0x17, 0xfd, 0xcd, 0xa9, 0x33, 0x12, 0xbe, 0x16, 0x92,
+ 0xbd, 0x3e, 0x18, 0x41, 0x3c, 0x96, 0x01, 0x8f, 0xf9, 0x74, 0x46, 0x0b,
+ 0xd3, 0xd3, 0x12, 0xbd, 0x61, 0x86, 0x23, 0x77, 0x31, 0x7d, 0x20, 0x04,
+ 0x03, 0x02, 0x2d, 0x33, 0x27, 0x08, 0x09, 0x68, 0xc3, 0xf8, 0x68, 0x2b,
+ 0x0e, 0x6f, 0x6f, 0x10, 0x8f, 0x64, 0x90, 0x85, 0x49, 0x32, 0x04, 0xfe,
+ 0x02, 0x27, 0x49, 0xa1, 0x3f, 0x01, 0x60, 0x01, 0xec, 0x17, 0x7a, 0x2d,
+ 0x36, 0xa6, 0x43, 0x08, 0xfd, 0x1a, 0x17, 0x89, 0x36, 0x43, 0x69, 0x39,
+ 0x33, 0x2d, 0x00, 0x05, 0x00, 0x3b, 0xff, 0xd7, 0x06, 0xdf, 0x05, 0xac,
+ 0x00, 0x15, 0x00, 0x25, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x4f, 0x00, 0x00,
+ 0x01, 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22,
+ 0x27, 0x26, 0x27, 0x34, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22,
+ 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x25, 0x33, 0x01, 0x23, 0x01, 0x32, 0x17, 0x16, 0x17, 0x14,
+ 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x34, 0x35, 0x34,
+ 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16,
+ 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0x98, 0x91, 0x65,
+ 0x65, 0x03, 0x60, 0x60, 0x87, 0x0b, 0x0a, 0x8d, 0x66, 0x65, 0x07, 0x62,
+ 0x60, 0x88, 0x0a, 0x09, 0x5e, 0x3e, 0x33, 0x48, 0x3b, 0x4e, 0x5c, 0x3f,
+ 0x33, 0x48, 0x3a, 0x02, 0xf9, 0x87, 0xfc, 0xd7, 0x87, 0x03, 0xcb, 0x93,
+ 0x65, 0x64, 0x02, 0x61, 0x5f, 0x85, 0x0b, 0x0c, 0x8c, 0x65, 0x65, 0x08,
+ 0x61, 0x60, 0x88, 0x0a, 0x09, 0x5e, 0x3e, 0x33, 0x48, 0x3b, 0x4e, 0x5d,
+ 0x3f, 0x33, 0x4a, 0x39, 0x05, 0x7b, 0x65, 0x6b, 0x92, 0x89, 0x65, 0x64,
+ 0x08, 0x01, 0x62, 0x61, 0x8a, 0x09, 0x09, 0x8b, 0x66, 0x65, 0x07, 0x01,
+ 0x8f, 0x47, 0x3b, 0x4d, 0x5d, 0x3f, 0x33, 0x46, 0x3a, 0x4d, 0x61, 0x3e,
+ 0x32, 0xc0, 0xfa, 0x2b, 0x02, 0xbc, 0x65, 0x69, 0x92, 0x88, 0x65, 0x63,
+ 0x09, 0x01, 0x62, 0x60, 0x89, 0x0a, 0x09, 0x8b, 0x65, 0x64, 0x07, 0x01,
+ 0x8f, 0x47, 0x3a, 0x4c, 0x5e, 0x3e, 0x33, 0x47, 0x39, 0x4b, 0x62, 0x3e,
+ 0x31, 0x00, 0x00, 0x03, 0x00, 0x6a, 0xff, 0xd1, 0x05, 0x19, 0x05, 0xac,
+ 0x00, 0x29, 0x00, 0x39, 0x00, 0x46, 0x00, 0x00, 0x25, 0x06, 0x07, 0x06,
+ 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26,
+ 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06,
+ 0x07, 0x01, 0x36, 0x37, 0x34, 0x3d, 0x01, 0x33, 0x14, 0x07, 0x06, 0x07,
+ 0x13, 0x23, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22,
+ 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x09, 0x01, 0x06, 0x07, 0x06, 0x15,
+ 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x03, 0xba, 0x4a, 0x27, 0x8e,
+ 0xad, 0xc8, 0x74, 0x68, 0x49, 0x46, 0xbd, 0x7c, 0x1c, 0x0e, 0x65, 0x66,
+ 0x94, 0x9c, 0x5e, 0x53, 0x4b, 0x3f, 0x90, 0x01, 0x10, 0x3a, 0x06, 0xa4,
+ 0x6d, 0x05, 0x05, 0xfa, 0xe0, 0xfe, 0x0f, 0x8f, 0x29, 0x1b, 0x46, 0x2f,
+ 0x3e, 0x67, 0x2f, 0x1a, 0x1f, 0x1b, 0x01, 0x66, 0xfe, 0xb8, 0xa9, 0x31,
+ 0x1f, 0x53, 0x4e, 0x6b, 0x75, 0x6e, 0x27, 0xa0, 0x49, 0x1d, 0x69, 0x7b,
+ 0x6e, 0xae, 0x8e, 0x5d, 0x5c, 0x6e, 0x9c, 0x56, 0x2b, 0x30, 0x86, 0x5d,
+ 0x5f, 0x65, 0x59, 0x84, 0x79, 0x53, 0x46, 0x52, 0xfe, 0xb2, 0x68, 0x73,
+ 0x09, 0x08, 0x08, 0xb4, 0xb3, 0x08, 0x08, 0xfe, 0xcb, 0x03, 0x73, 0x5a,
+ 0x40, 0x2b, 0x37, 0x5a, 0x32, 0x22, 0x4c, 0x2b, 0x39, 0x3a, 0x32, 0x2c,
+ 0xfd, 0x44, 0x01, 0x99, 0x6c, 0x57, 0x36, 0x42, 0x70, 0x4d, 0x49, 0x5b,
+ 0x1f, 0x00, 0x00, 0x01, 0x00, 0x62, 0x03, 0xb6, 0x01, 0x23, 0x05, 0xac,
+ 0x00, 0x05, 0x00, 0x00, 0x13, 0x33, 0x15, 0x03, 0x23, 0x03, 0x62, 0xc1,
+ 0x37, 0x52, 0x38, 0x05, 0xac, 0xe3, 0xfe, 0xed, 0x01, 0x13, 0x00, 0x01,
+ 0x00, 0x96, 0xfe, 0x4e, 0x02, 0x54, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00,
+ 0x01, 0x33, 0x02, 0x03, 0x06, 0x15, 0x10, 0x13, 0x16, 0x17, 0x23, 0x26,
+ 0x03, 0x26, 0x35, 0x10, 0x13, 0x36, 0x01, 0xe3, 0x71, 0xd3, 0x36, 0x10,
+ 0xb3, 0x2e, 0x38, 0x71, 0xbe, 0x58, 0x37, 0x89, 0x51, 0x05, 0xd5, 0xfe,
+ 0xab, 0xfe, 0x77, 0x74, 0x71, 0xfe, 0x76, 0xfe, 0x82, 0x61, 0x5b, 0xfa,
+ 0x01, 0x47, 0xc9, 0xba, 0x01, 0x31, 0x01, 0x3f, 0xbd, 0x00, 0x00, 0x01,
+ 0x00, 0x4e, 0xfe, 0x4e, 0x02, 0x0c, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00,
+ 0x13, 0x23, 0x12, 0x13, 0x36, 0x35, 0x10, 0x03, 0x26, 0x27, 0x33, 0x16,
+ 0x13, 0x16, 0x15, 0x10, 0x03, 0x06, 0xbe, 0x70, 0xd2, 0x36, 0x10, 0xb4,
+ 0x2d, 0x37, 0x70, 0xbf, 0x59, 0x36, 0x89, 0x52, 0xfe, 0x4e, 0x01, 0x53,
+ 0x01, 0x8a, 0x74, 0x71, 0x01, 0x8e, 0x01, 0x7e, 0x60, 0x59, 0xfa, 0xfe,
+ 0xb9, 0xca, 0xba, 0xfe, 0xd1, 0xfe, 0xc2, 0xbe, 0x00, 0x01, 0x00, 0x52,
+ 0x03, 0x87, 0x02, 0xbe, 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x33,
+ 0x07, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07, 0x27, 0x37, 0x27, 0x37,
+ 0x17, 0x01, 0x48, 0x81, 0x0b, 0xda, 0x26, 0xdd, 0x90, 0x69, 0x7f, 0x81,
+ 0x66, 0x8d, 0xdd, 0x27, 0xd9, 0x05, 0xd5, 0xe5, 0x4d, 0x78, 0x3e, 0xb6,
+ 0x4a, 0xbf, 0xbf, 0x4a, 0xb6, 0x3e, 0x78, 0x4d, 0x00, 0x01, 0x00, 0x66,
+ 0xff, 0xec, 0x04, 0x46, 0x03, 0xcb, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x15,
+ 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x04, 0x46,
+ 0xfe, 0x58, 0x90, 0xfe, 0x58, 0x01, 0xa8, 0x90, 0x02, 0x23, 0x90, 0xfe,
+ 0x59, 0x01, 0xa7, 0x90, 0x01, 0xa8, 0xfe, 0x58, 0x00, 0x01, 0x00, 0xb2,
+ 0xfe, 0xd3, 0x01, 0x89, 0x00, 0xd5, 0x00, 0x0b, 0x00, 0x00, 0x37, 0x33,
+ 0x15, 0x10, 0x23, 0x35, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x23, 0xb2, 0xd7,
+ 0xd7, 0x4c, 0x19, 0x16, 0x7b, 0xd5, 0xf6, 0xfe, 0xf4, 0x4e, 0x03, 0x2c,
+ 0x27, 0x64, 0x25, 0x00, 0x00, 0x01, 0x00, 0x5e, 0x01, 0xec, 0x02, 0x46,
+ 0x02, 0x7f, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x02, 0x46,
+ 0xfe, 0x18, 0x02, 0x7f, 0x93, 0x93, 0x00, 0x01, 0x00, 0xb2, 0x00, 0x00,
+ 0x01, 0x87, 0x00, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35,
+ 0x01, 0x87, 0xd5, 0xd5, 0xd5, 0xd5, 0x00, 0x01, 0xff, 0xf0, 0xff, 0xd7,
+ 0x02, 0x46, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, 0x01, 0x23,
+ 0x01, 0xd5, 0x71, 0xfe, 0x1a, 0x70, 0x05, 0xd5, 0xfa, 0x02, 0x00, 0x02,
+ 0x00, 0x58, 0xff, 0xd1, 0x04, 0x0e, 0x05, 0xac, 0x00, 0x0f, 0x00, 0x19,
+ 0x00, 0x00, 0x13, 0x10, 0x25, 0x36, 0x33, 0x20, 0x13, 0x16, 0x15, 0x10,
+ 0x07, 0x06, 0x23, 0x20, 0x03, 0x26, 0x01, 0x20, 0x11, 0x10, 0x21, 0x32,
+ 0x13, 0x36, 0x35, 0x10, 0x58, 0x01, 0x24, 0x52, 0x65, 0x01, 0x7d, 0x4c,
+ 0x12, 0xd1, 0x6c, 0x9e, 0xfe, 0xcf, 0x6f, 0x3b, 0x01, 0xdb, 0xfe, 0xdd,
+ 0x01, 0x1f, 0xc7, 0x3f, 0x21, 0x02, 0xbe, 0x02, 0x43, 0x86, 0x25, 0xfe,
+ 0x10, 0x77, 0x93, 0xfe, 0x27, 0xae, 0x5a, 0x01, 0x44, 0xab, 0x03, 0x4c,
+ 0xfd, 0xb0, 0xfd, 0xaa, 0x01, 0x06, 0x86, 0xd1, 0x02, 0x49, 0x00, 0x01,
+ 0x00, 0xd1, 0x00, 0x00, 0x02, 0xc7, 0x05, 0xac, 0x00, 0x0a, 0x00, 0x00,
+ 0x01, 0x21, 0x35, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x02,
+ 0x12, 0xfe, 0xbf, 0xb3, 0x7f, 0x24, 0x12, 0x17, 0x77, 0xb5, 0x04, 0x0a,
+ 0x81, 0x16, 0x43, 0x50, 0x29, 0x4f, 0xfa, 0x54, 0x00, 0x01, 0x00, 0x46,
+ 0x00, 0x00, 0x04, 0x17, 0x05, 0xac, 0x00, 0x23, 0x00, 0x00, 0x13, 0x12,
+ 0x21, 0x32, 0x17, 0x16, 0x15, 0x10, 0x05, 0x06, 0x0f, 0x01, 0x06, 0x07,
+ 0x06, 0x07, 0x21, 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01,
+ 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x20, 0x03, 0x06, 0x07, 0x66, 0x0f,
+ 0x01, 0xd1, 0xd0, 0x82, 0x7f, 0xfe, 0xec, 0x0f, 0x11, 0xcc, 0xa8, 0x37,
+ 0x1d, 0x0b, 0x02, 0xfc, 0xfc, 0x3a, 0x0b, 0x48, 0x45, 0xa7, 0x28, 0x30,
+ 0xbd, 0xc4, 0x5b, 0x51, 0x73, 0xfe, 0xfe, 0x1f, 0x02, 0x01, 0x03, 0xb4,
+ 0x01, 0xf8, 0x79, 0x76, 0xbb, 0xff, 0x00, 0xa4, 0x09, 0x09, 0x6f, 0x5a,
+ 0x5e, 0x31, 0x42, 0xb2, 0xe0, 0x7d, 0x78, 0x6b, 0x1a, 0x1b, 0x6a, 0x70,
+ 0xaf, 0x7c, 0x4f, 0x45, 0xfe, 0xcd, 0x12, 0x15, 0x00, 0x01, 0x00, 0x42,
+ 0xff, 0xd1, 0x04, 0x0c, 0x05, 0xac, 0x00, 0x32, 0x00, 0x00, 0x01, 0x22,
+ 0x07, 0x06, 0x07, 0x23, 0x12, 0x25, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15,
+ 0x14, 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x20, 0x03,
+ 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x23, 0x07, 0x23, 0x35, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27,
+ 0x26, 0x02, 0x29, 0xd2, 0x32, 0x0f, 0x02, 0xb4, 0x07, 0x01, 0x1a, 0x4a,
+ 0x5c, 0xf3, 0x75, 0x52, 0xca, 0xa3, 0x34, 0x1e, 0x8e, 0x85, 0xd8, 0xfe,
+ 0xa3, 0x5f, 0x1c, 0x07, 0xb4, 0x0d, 0xa0, 0x38, 0x4c, 0xb3, 0x4d, 0x2d,
+ 0xff, 0x16, 0x18, 0x4c, 0x16, 0xc4, 0x4b, 0x55, 0x6b, 0x3e, 0x05, 0x0e,
+ 0xb3, 0x36, 0x4e, 0x01, 0x70, 0x50, 0x15, 0x8f, 0x65, 0x9b, 0xde, 0x4f,
+ 0x38, 0x77, 0x45, 0x66, 0xd6, 0x7c, 0x73, 0x01, 0x18, 0x52, 0x6b, 0xea,
+ 0x38, 0x13, 0x77, 0x46, 0x65, 0xf3, 0x14, 0x02, 0x02, 0x99, 0x03, 0x2b,
+ 0x32, 0x84, 0x93, 0x40, 0x24, 0x00, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00,
+ 0x04, 0x29, 0x05, 0xac, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x21,
+ 0x35, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x19, 0x01, 0x01,
+ 0x02, 0x9e, 0xfd, 0x9b, 0x02, 0x94, 0x85, 0xd7, 0xd7, 0xb4, 0xfe, 0x39,
+ 0x01, 0x5c, 0xbf, 0x03, 0x91, 0xfc, 0x52, 0xa2, 0xfe, 0xa4, 0x01, 0xfe,
+ 0x02, 0x7b, 0xfd, 0x85, 0x00, 0x01, 0x00, 0x48, 0xff, 0xd1, 0x04, 0x1b,
+ 0x05, 0xac, 0x00, 0x26, 0x00, 0x00, 0x01, 0x15, 0x21, 0x03, 0x36, 0x37,
+ 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x20, 0x03,
+ 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x23, 0x13, 0x03, 0xcf, 0xfd,
+ 0xa4, 0x3a, 0x7c, 0x91, 0xcf, 0x82, 0x83, 0x01, 0x85, 0x82, 0xce, 0x0e,
+ 0x0f, 0xfe, 0x71, 0x4d, 0x02, 0x03, 0xb4, 0x3d, 0xd5, 0x0b, 0x0c, 0xb0,
+ 0x54, 0x39, 0x74, 0x51, 0x78, 0x71, 0x4d, 0x24, 0x28, 0xa6, 0x6c, 0x05,
+ 0xac, 0xb2, 0xfe, 0x6a, 0x56, 0x02, 0x84, 0x86, 0xd9, 0xe0, 0x91, 0x8c,
+ 0x0a, 0x01, 0x01, 0x7b, 0x06, 0x12, 0xe7, 0x0b, 0x01, 0x7c, 0x55, 0x7f,
+ 0xbe, 0x5d, 0x41, 0x3b, 0x1d, 0x2f, 0x03, 0x16, 0x00, 0x02, 0x00, 0x58,
+ 0xff, 0xd1, 0x04, 0x1b, 0x05, 0xac, 0x00, 0x22, 0x00, 0x32, 0x00, 0x00,
+ 0x13, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27,
+ 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17,
+ 0x14, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x20, 0x03, 0x26, 0x25,
+ 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x34, 0x27, 0x26, 0x58, 0x01, 0x17, 0x69, 0x88, 0xc8, 0x72, 0x4d, 0x15,
+ 0xb4, 0x20, 0x76, 0x2b, 0x33, 0xc2, 0x51, 0x30, 0x01, 0x76, 0xd8, 0xbf,
+ 0x7c, 0x7e, 0x04, 0x7d, 0x7b, 0xc1, 0x11, 0x12, 0xfe, 0x42, 0x26, 0x03,
+ 0x01, 0xf0, 0x93, 0x55, 0x45, 0x5d, 0x53, 0x77, 0x81, 0x53, 0x4c, 0x6f,
+ 0x46, 0x02, 0x96, 0x02, 0x33, 0xa5, 0x3e, 0x8d, 0x5f, 0x8f, 0x9b, 0x2f,
+ 0x11, 0xdb, 0x84, 0xc8, 0xa2, 0x7c, 0x7e, 0xc7, 0x06, 0x06, 0xcd, 0x89,
+ 0x86, 0x0c, 0x01, 0x02, 0x56, 0x35, 0x8b, 0x65, 0x52, 0x7a, 0x93, 0x5e,
+ 0x54, 0x60, 0x59, 0x82, 0xb4, 0x53, 0x34, 0x00, 0x00, 0x01, 0x00, 0x5e,
+ 0x00, 0x00, 0x04, 0x29, 0x05, 0xac, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x15,
+ 0x00, 0x03, 0x06, 0x07, 0x23, 0x12, 0x13, 0x12, 0x13, 0x21, 0x35, 0x04,
+ 0x29, 0xfe, 0xa5, 0x94, 0x3c, 0x23, 0xc0, 0x56, 0x8b, 0x7e, 0xf5, 0xfc,
+ 0xef, 0x05, 0xac, 0x98, 0xfe, 0x33, 0xfe, 0x3c, 0xba, 0xc9, 0x01, 0x7a,
+ 0x01, 0x20, 0x01, 0x03, 0x01, 0x5d, 0xb2, 0x00, 0x00, 0x03, 0x00, 0x4c,
+ 0xff, 0xd1, 0x04, 0x1b, 0x05, 0xac, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x3c,
+ 0x00, 0x00, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x22, 0x23, 0x22,
+ 0x27, 0x26, 0x27, 0x34, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x33,
+ 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x01, 0x22, 0x07, 0x06, 0x15,
+ 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x03,
+ 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x34, 0x27, 0x26, 0x03, 0x21, 0xfa, 0x83, 0x85, 0xd5, 0x05, 0x06, 0xd7,
+ 0x88, 0x85, 0x03, 0xf8, 0x7e, 0x29, 0x1e, 0xf4, 0xc0, 0xc8, 0x7a, 0x72,
+ 0x3e, 0x2c, 0xfe, 0xb6, 0x8b, 0x44, 0x2d, 0x5e, 0x41, 0x5d, 0x8b, 0x45,
+ 0x2c, 0x63, 0x3f, 0x5a, 0x99, 0x54, 0x42, 0x63, 0x51, 0x77, 0x9f, 0x55,
+ 0x3f, 0x66, 0x51, 0x02, 0xfc, 0x77, 0xf4, 0xc2, 0x7c, 0x7e, 0x04, 0x7d,
+ 0x83, 0xc2, 0xf1, 0x78, 0x4f, 0x4d, 0x3a, 0x57, 0xaa, 0xd9, 0x73, 0x6b,
+ 0xa5, 0x78, 0x49, 0x34, 0x01, 0xd8, 0x59, 0x3a, 0x52, 0x7a, 0x3e, 0x2b,
+ 0x58, 0x39, 0x50, 0x82, 0x3e, 0x27, 0xfd, 0xa0, 0x62, 0x4c, 0x6f, 0x8c,
+ 0x51, 0x41, 0x65, 0x4b, 0x6e, 0x8e, 0x50, 0x3f, 0x00, 0x02, 0x00, 0x4e,
+ 0xff, 0xd1, 0x04, 0x12, 0x05, 0xac, 0x00, 0x22, 0x00, 0x32, 0x00, 0x00,
+ 0x01, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x33, 0x16, 0x17,
+ 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27,
+ 0x26, 0x27, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x20, 0x13, 0x16, 0x01,
+ 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x34, 0x27, 0x26, 0x04, 0x12, 0xfe, 0xea, 0x6a, 0x8a, 0xc7, 0x72, 0x4d,
+ 0x15, 0xb4, 0x1e, 0x72, 0x2d, 0x36, 0xc2, 0x51, 0x30, 0x01, 0x6e, 0x8e,
+ 0x25, 0x2b, 0xc2, 0x7d, 0x7d, 0x02, 0x7d, 0x7a, 0xc1, 0x11, 0x12, 0x01,
+ 0x9e, 0x40, 0x0b, 0xfe, 0x15, 0x83, 0x53, 0x4b, 0x6e, 0x47, 0x66, 0x8f,
+ 0x55, 0x49, 0x5d, 0x53, 0x02, 0xe7, 0xfd, 0xd0, 0xa6, 0x40, 0x8c, 0x5f,
+ 0x90, 0x97, 0x31, 0x13, 0xdb, 0x84, 0xc8, 0x84, 0x18, 0x06, 0x7e, 0x86,
+ 0xc9, 0xcd, 0x89, 0x86, 0x0c, 0x01, 0xfe, 0x01, 0x5b, 0x01, 0xbc, 0x62,
+ 0x58, 0x83, 0xb3, 0x53, 0x35, 0x62, 0x53, 0x7c, 0x95, 0x5e, 0x54, 0x00,
+ 0x00, 0x02, 0x00, 0xe1, 0x00, 0x00, 0x01, 0xb6, 0x04, 0x31, 0x00, 0x03,
+ 0x00, 0x07, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35,
+ 0x01, 0xb6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0x03, 0x5c, 0xd5, 0xd5,
+ 0x00, 0x02, 0x00, 0xe1, 0xfe, 0xd3, 0x01, 0xb8, 0x04, 0x31, 0x00, 0x03,
+ 0x00, 0x0f, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x03, 0x33, 0x15, 0x10,
+ 0x23, 0x35, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x01, 0xb8, 0xd5, 0x02,
+ 0xd7, 0xd7, 0x4d, 0x18, 0x16, 0x7b, 0x04, 0x31, 0xd5, 0xd5, 0xfc, 0xa4,
+ 0xf6, 0xfe, 0xf4, 0x4e, 0x03, 0x2c, 0x27, 0x64, 0x25, 0x00, 0x00, 0x01,
+ 0x00, 0x5c, 0xff, 0xee, 0x04, 0x46, 0x03, 0xcb, 0x00, 0x06, 0x00, 0x00,
+ 0x13, 0x35, 0x01, 0x15, 0x09, 0x01, 0x15, 0x5c, 0x03, 0xea, 0xfc, 0xd9,
+ 0x03, 0x27, 0x01, 0x96, 0x8d, 0x01, 0xa8, 0xa2, 0xfe, 0xb6, 0xfe, 0xb0,
+ 0xa1, 0x00, 0x00, 0x02, 0x00, 0x66, 0x00, 0xe3, 0x04, 0x46, 0x02, 0xd3,
+ 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x01, 0x15,
+ 0x21, 0x35, 0x04, 0x46, 0xfc, 0x20, 0x03, 0xe0, 0xfc, 0x20, 0x02, 0xd3,
+ 0x8f, 0x8f, 0xfe, 0xa0, 0x90, 0x90, 0x00, 0x01, 0x00, 0x66, 0xff, 0xee,
+ 0x04, 0x50, 0x03, 0xcb, 0x00, 0x06, 0x00, 0x00, 0x01, 0x15, 0x01, 0x35,
+ 0x09, 0x01, 0x35, 0x04, 0x50, 0xfc, 0x16, 0x03, 0x27, 0xfc, 0xd9, 0x02,
+ 0x23, 0x8d, 0xfe, 0x58, 0xa1, 0x01, 0x4a, 0x01, 0x50, 0xa2, 0x00, 0x02,
+ 0x00, 0x9e, 0x00, 0x00, 0x04, 0x12, 0x05, 0xee, 0x00, 0x23, 0x00, 0x27,
+ 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x1d, 0x01,
+ 0x23, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27,
+ 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x23, 0x10, 0x25, 0x36, 0x33, 0x32,
+ 0x17, 0x16, 0x01, 0x15, 0x23, 0x35, 0x04, 0x12, 0x6e, 0x1a, 0x5b, 0x58,
+ 0x1c, 0x17, 0xb8, 0x66, 0x14, 0x5d, 0x61, 0x1f, 0x17, 0x5f, 0x44, 0x63,
+ 0xc4, 0x31, 0x13, 0xae, 0x01, 0x1f, 0x48, 0x59, 0xdc, 0x77, 0x61, 0xfe,
+ 0x92, 0xb8, 0x04, 0x64, 0x99, 0x7a, 0x1c, 0x51, 0x50, 0x3a, 0x2e, 0x34,
+ 0x60, 0x70, 0x78, 0x6f, 0x15, 0x58, 0x5a, 0x43, 0x33, 0x38, 0x7b, 0x41,
+ 0x2e, 0xa2, 0x3f, 0x5f, 0x01, 0x7c, 0x50, 0x14, 0x80, 0x68, 0xfb, 0xcf,
+ 0xd5, 0xd5, 0x00, 0x02, 0x00, 0x46, 0xfe, 0xdd, 0x07, 0x9c, 0x05, 0xee,
+ 0x00, 0x51, 0x00, 0x65, 0x00, 0x00, 0x01, 0x33, 0x03, 0x06, 0x15, 0x14,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26,
+ 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x17, 0x06, 0x23, 0x20, 0x27, 0x26, 0x27,
+ 0x26, 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x20, 0x17,
+ 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27,
+ 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37,
+ 0x36, 0x33, 0x32, 0x17, 0x01, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16,
+ 0x05, 0x52, 0xaa, 0xb8, 0x19, 0x2e, 0x1a, 0x1e, 0x6f, 0x62, 0x65, 0x1b,
+ 0x07, 0x92, 0x8c, 0xd9, 0x6a, 0x6f, 0xfd, 0xd4, 0xc1, 0x59, 0x3a, 0x9e,
+ 0x97, 0xf1, 0x69, 0x71, 0xa3, 0xe8, 0x39, 0xe6, 0xe9, 0xfe, 0xc9, 0xf6,
+ 0xd9, 0x60, 0x3d, 0x8d, 0x4c, 0x6a, 0xb6, 0xfc, 0x7e, 0x7a, 0x01, 0x1e,
+ 0xe9, 0xcd, 0x5b, 0x3a, 0x7b, 0x18, 0x1d, 0x9b, 0xe2, 0xc5, 0x1d, 0x75,
+ 0x7f, 0x17, 0x18, 0x8d, 0x5f, 0x61, 0x78, 0x6d, 0x9e, 0x45, 0x46, 0xac,
+ 0x4e, 0xfe, 0x7b, 0x79, 0x5f, 0x4e, 0x14, 0x05, 0x47, 0x33, 0x46, 0x72,
+ 0x5f, 0x61, 0x14, 0x04, 0x48, 0x39, 0x04, 0x02, 0xfd, 0xc3, 0x45, 0x22,
+ 0x2f, 0x1c, 0x0f, 0x6e, 0x72, 0x9f, 0x2c, 0x2c, 0xcf, 0xa9, 0xa1, 0x3e,
+ 0x1e, 0x9a, 0x8d, 0xd8, 0x8d, 0x95, 0xf3, 0xb9, 0xb0, 0x3d, 0x1b, 0x41,
+ 0x89, 0x56, 0xa1, 0x8e, 0xdf, 0x8c, 0x99, 0x01, 0x07, 0xee, 0x80, 0x60,
+ 0xa6, 0x42, 0x21, 0x99, 0x86, 0xce, 0x82, 0x8b, 0xcc, 0xb7, 0x25, 0x21,
+ 0xb6, 0x9d, 0x7f, 0x11, 0x03, 0x6a, 0x6c, 0xa1, 0xbc, 0x9f, 0x90, 0x35,
+ 0x17, 0xb2, 0xfd, 0x87, 0x99, 0x7e, 0x98, 0x23, 0x1e, 0x5b, 0x36, 0x27,
+ 0x6c, 0x6f, 0x9c, 0x20, 0x1f, 0x72, 0x48, 0x38, 0x00, 0x02, 0x00, 0x23,
+ 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00,
+ 0x01, 0x21, 0x03, 0x23, 0x01, 0x33, 0x01, 0x23, 0x0b, 0x02, 0x03, 0xcb,
+ 0xfd, 0xc0, 0x9d, 0xcb, 0x02, 0x14, 0xf6, 0x02, 0x0c, 0xd5, 0xce, 0xe6,
+ 0xf6, 0x01, 0xc1, 0xfe, 0x3f, 0x05, 0xd5, 0xfa, 0x2b, 0x02, 0x60, 0x02,
+ 0xa8, 0xfd, 0x58, 0x00, 0x00, 0x03, 0x00, 0xa2, 0x00, 0x00, 0x04, 0xfc,
+ 0x05, 0xd5, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x26, 0x00, 0x00, 0x01, 0x14,
+ 0x07, 0x06, 0x23, 0x21, 0x11, 0x21, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07,
+ 0x16, 0x17, 0x16, 0x01, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x21, 0x32,
+ 0x37, 0x36, 0x03, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x21,
+ 0x11, 0x04, 0xfc, 0x82, 0x77, 0xbf, 0xfd, 0x5e, 0x02, 0x5e, 0x01, 0x17,
+ 0x6d, 0x36, 0xce, 0xbd, 0x37, 0x1c, 0xff, 0x00, 0xd0, 0x29, 0x32, 0xfe,
+ 0x8f, 0x01, 0x71, 0xf7, 0x2b, 0x09, 0xcb, 0xb8, 0x3d, 0x17, 0x67, 0x42,
+ 0x63, 0xfe, 0x2f, 0x01, 0xaa, 0xc7, 0x76, 0x6d, 0x05, 0xd5, 0xb4, 0x59,
+ 0x6e, 0xe4, 0x62, 0x48, 0x85, 0x43, 0x02, 0x3b, 0xc9, 0x1f, 0x06, 0xfe,
+ 0x25, 0x9f, 0x23, 0xfc, 0x94, 0x8c, 0x35, 0x3f, 0x92, 0x44, 0x2c, 0xfd,
+ 0xfe, 0x00, 0x00, 0x01, 0x00, 0x62, 0xff, 0xd1, 0x05, 0x6a, 0x05, 0xee,
+ 0x00, 0x23, 0x00, 0x00, 0x13, 0x34, 0x37, 0x12, 0x25, 0x36, 0x33, 0x20,
+ 0x13, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x11,
+ 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x33, 0x02, 0x21, 0x20,
+ 0x03, 0x26, 0x03, 0x26, 0x62, 0x65, 0x92, 0x01, 0x3a, 0x3a, 0x3f, 0x01,
+ 0xa2, 0x7c, 0x15, 0x0d, 0xc3, 0x2f, 0xb2, 0x4c, 0x66, 0xde, 0x7e, 0x79,
+ 0x91, 0x81, 0xd3, 0xec, 0x66, 0x36, 0x18, 0xc4, 0x43, 0xfd, 0xdd, 0xfe,
+ 0x8f, 0xb1, 0x76, 0x09, 0x01, 0x02, 0xd9, 0xfc, 0xc5, 0x01, 0x1d, 0x2e,
+ 0x09, 0xfe, 0x9b, 0x3c, 0x47, 0xe6, 0x3f, 0x1b, 0xad, 0xa5, 0xfe, 0xe7,
+ 0xfe, 0xd9, 0xa6, 0x95, 0xb2, 0x5e, 0x98, 0xfd, 0xb0, 0x01, 0x1d, 0xbc,
+ 0x01, 0x08, 0x14, 0x00, 0x00, 0x02, 0x00, 0xb6, 0x00, 0x00, 0x05, 0x56,
+ 0x05, 0xd5, 0x00, 0x09, 0x00, 0x14, 0x00, 0x00, 0x33, 0x11, 0x21, 0x20,
+ 0x00, 0x11, 0x10, 0x07, 0x06, 0x21, 0x25, 0x21, 0x20, 0x13, 0x36, 0x35,
+ 0x10, 0x25, 0x26, 0x23, 0x21, 0xb6, 0x02, 0x40, 0x01, 0x1b, 0x01, 0x45,
+ 0xaf, 0xa2, 0xfe, 0xf1, 0xfe, 0x7f, 0x01, 0x60, 0x01, 0x2f, 0x65, 0x2f,
+ 0xff, 0x00, 0x55, 0x6e, 0xfe, 0xa0, 0x05, 0xd5, 0xfe, 0x72, 0xfe, 0xa5,
+ 0xfe, 0x95, 0xc9, 0xb8, 0xa8, 0x01, 0x10, 0x7d, 0xb4, 0x01, 0xaf, 0x70,
+ 0x25, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, 0x05, 0xd5,
+ 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15,
+ 0x21, 0x11, 0x21, 0x15, 0x01, 0x77, 0x03, 0x70, 0xfb, 0xd1, 0x04, 0x0b,
+ 0xfc, 0xb4, 0x03, 0x2d, 0x02, 0xa8, 0xfe, 0x00, 0xa8, 0x05, 0xd5, 0xa8,
+ 0xfe, 0x23, 0xa8, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xa2,
+ 0x05, 0xd5, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x21, 0x15,
+ 0x21, 0x11, 0x21, 0x15, 0x01, 0x77, 0xbf, 0x03, 0xea, 0xfc, 0xd5, 0x02,
+ 0xc8, 0x02, 0xa8, 0xfd, 0x58, 0x05, 0xd5, 0xa8, 0xfe, 0x23, 0xa8, 0x00,
+ 0x00, 0x01, 0x00, 0x5a, 0xff, 0xd1, 0x05, 0xac, 0x05, 0xee, 0x00, 0x31,
+ 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x05, 0x32, 0x33, 0x32, 0x37, 0x36,
+ 0x37, 0x36, 0x3d, 0x01, 0x21, 0x35, 0x21, 0x11, 0x23, 0x27, 0x06, 0x07,
+ 0x06, 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x34, 0x37, 0x12, 0x25,
+ 0x36, 0x33, 0x20, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22,
+ 0x07, 0x06, 0x03, 0x14, 0x01, 0x19, 0x58, 0x88, 0x01, 0x28, 0x07, 0x07,
+ 0xc6, 0x84, 0x81, 0x09, 0x01, 0xfe, 0x39, 0x02, 0x6f, 0x79, 0x2f, 0xbe,
+ 0xfb, 0x22, 0x23, 0xfe, 0xf7, 0xb7, 0xb4, 0x2c, 0x0c, 0x61, 0x8d, 0x01,
+ 0x30, 0x52, 0x5d, 0x01, 0x35, 0xaa, 0x72, 0x20, 0xc3, 0x24, 0x95, 0x6a,
+ 0x8d, 0xe5, 0x8f, 0x93, 0x05, 0x02, 0xe5, 0xd1, 0xa0, 0xf5, 0x06, 0x7b,
+ 0x79, 0xbc, 0x0e, 0x0d, 0x29, 0xa7, 0xfc, 0xe4, 0xc6, 0xd3, 0x17, 0x03,
+ 0xab, 0xa7, 0x01, 0x17, 0x4e, 0x53, 0xea, 0xc0, 0x01, 0x19, 0x3f, 0x11,
+ 0xb2, 0x76, 0xb6, 0xaa, 0x52, 0x3a, 0x9d, 0xa2, 0xfe, 0xef, 0x08, 0x00,
+ 0x00, 0x01, 0x00, 0xaa, 0x00, 0x00, 0x05, 0x27, 0x05, 0xd5, 0x00, 0x0b,
+ 0x00, 0x00, 0x01, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33,
+ 0x11, 0x23, 0x04, 0x68, 0xfd, 0x00, 0xbe, 0xbe, 0x03, 0x00, 0xbf, 0xbf,
+ 0x02, 0xa8, 0xfd, 0x58, 0x05, 0xd5, 0xfd, 0x7b, 0x02, 0x85, 0xfa, 0x2b,
+ 0x00, 0x01, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d, 0x05, 0xd5, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x8d, 0xc0, 0x05, 0xd5, 0xfa,
+ 0x2b, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x23, 0xff, 0xd1, 0x03, 0x68,
+ 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x25, 0x32, 0x37, 0x36, 0x35, 0x11,
+ 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x33,
+ 0x15, 0x14, 0x17, 0x16, 0x01, 0xc5, 0xa7, 0x2c, 0x12, 0xbe, 0x88, 0x6f,
+ 0xae, 0xd6, 0x71, 0x59, 0xc2, 0x80, 0x2a, 0x71, 0xa0, 0x42, 0x67, 0x04,
+ 0x1b, 0xfb, 0xa0, 0xd6, 0x72, 0x5c, 0x83, 0x67, 0xa1, 0x83, 0x60, 0xc6,
+ 0x36, 0x12, 0x00, 0x01, 0x00, 0xa2, 0x00, 0x00, 0x05, 0x44, 0x05, 0xd5,
+ 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x33, 0x11, 0x01, 0x33,
+ 0x09, 0x01, 0x23, 0x01, 0x01, 0x60, 0xbe, 0xbe, 0x02, 0xe8, 0xf5, 0xfd,
+ 0xa0, 0x02, 0x67, 0xe2, 0xfd, 0xf2, 0x02, 0x0a, 0xfd, 0xf6, 0x05, 0xd5,
+ 0xfd, 0x0c, 0x02, 0xf4, 0xfd, 0xa0, 0xfc, 0x8b, 0x02, 0xfe, 0x00, 0x01,
+ 0x00, 0xa4, 0x00, 0x00, 0x04, 0x44, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00,
+ 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0x62, 0x02, 0xe2, 0xfc, 0x60,
+ 0x05, 0xd5, 0xfa, 0xd3, 0xa8, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x9a,
+ 0x00, 0x00, 0x06, 0x17, 0x05, 0xd5, 0x00, 0x0c, 0x00, 0x00, 0x21, 0x23,
+ 0x01, 0x11, 0x23, 0x11, 0x21, 0x09, 0x01, 0x21, 0x11, 0x23, 0x11, 0x03,
+ 0xbe, 0xc8, 0xfe, 0x58, 0xb4, 0x01, 0x08, 0x01, 0xba, 0x01, 0xb2, 0x01,
+ 0x09, 0xb5, 0x04, 0xe3, 0xfb, 0x1d, 0x05, 0xd5, 0xfa, 0xec, 0x05, 0x14,
+ 0xfa, 0x2b, 0x04, 0xe3, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x05, 0x2b,
+ 0x05, 0xd5, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x23, 0x01, 0x11, 0x23,
+ 0x11, 0x33, 0x01, 0x11, 0x05, 0x2b, 0xd7, 0xfc, 0xfc, 0xb4, 0xce, 0x03,
+ 0x0d, 0x05, 0xd5, 0xfa, 0x2b, 0x04, 0xba, 0xfb, 0x46, 0x05, 0xd5, 0xfb,
+ 0x3b, 0x04, 0xc5, 0x00, 0x00, 0x02, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0,
+ 0x05, 0xee, 0x00, 0x16, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x10, 0x00, 0x07,
+ 0x06, 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x25,
+ 0x36, 0x33, 0x20, 0x17, 0x16, 0x13, 0x16, 0x01, 0x22, 0x07, 0x06, 0x03,
+ 0x06, 0x15, 0x10, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37,
+ 0x36, 0x35, 0x10, 0x27, 0x26, 0x05, 0xf0, 0xfe, 0xd4, 0xfc, 0x51, 0x58,
+ 0xfe, 0xe0, 0xc1, 0xbd, 0x29, 0x0a, 0xa8, 0x9d, 0x01, 0x03, 0x41, 0x46,
+ 0x01, 0x2d, 0xc2, 0xbf, 0x20, 0x05, 0xfd, 0x2d, 0xe2, 0x90, 0x94, 0x0a,
+ 0x01, 0x8f, 0x88, 0xdd, 0x0f, 0x10, 0xde, 0x91, 0x93, 0x0f, 0x01, 0x94,
+ 0x96, 0x02, 0xd3, 0xfe, 0xe0, 0xfe, 0x66, 0x36, 0x12, 0xb0, 0xac, 0x01,
+ 0x20, 0x47, 0x4b, 0x01, 0x3f, 0xd3, 0xc6, 0x2c, 0x0b, 0xb9, 0xb8, 0xfe,
+ 0xc7, 0x37, 0x02, 0x39, 0x9a, 0x9f, 0xfe, 0xf7, 0x12, 0x13, 0xfe, 0xf0,
+ 0xa9, 0xa1, 0x0b, 0x01, 0x97, 0x98, 0xfc, 0x19, 0x1a, 0x01, 0x1e, 0xab,
+ 0xa3, 0x00, 0x00, 0x02, 0x00, 0xba, 0x00, 0x00, 0x04, 0xf0, 0x05, 0xd5,
+ 0x00, 0x0c, 0x00, 0x17, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x23, 0x21,
+ 0x11, 0x23, 0x11, 0x21, 0x20, 0x17, 0x16, 0x01, 0x21, 0x32, 0x37, 0x36,
+ 0x35, 0x34, 0x27, 0x26, 0x23, 0x21, 0x04, 0xf0, 0x7e, 0x72, 0xb2, 0xfe,
+ 0x2b, 0xbf, 0x02, 0x69, 0x01, 0x17, 0x73, 0x43, 0xfc, 0x89, 0x01, 0x8d,
+ 0xb1, 0x4a, 0x28, 0x77, 0x46, 0x66, 0xfe, 0x73, 0x04, 0x1f, 0xc7, 0x75,
+ 0x6a, 0xfd, 0x87, 0x05, 0xd5, 0xb1, 0x69, 0xfe, 0x66, 0x71, 0x3e, 0x57,
+ 0x9b, 0x43, 0x28, 0x00, 0x00, 0x02, 0x00, 0x4e, 0xff, 0x87, 0x05, 0xf0,
+ 0x05, 0xee, 0x00, 0x18, 0x00, 0x33, 0x00, 0x00, 0x05, 0x07, 0x27, 0x06,
+ 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x25, 0x36,
+ 0x33, 0x20, 0x17, 0x16, 0x13, 0x16, 0x15, 0x10, 0x07, 0x01, 0x17, 0x36,
+ 0x11, 0x10, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x06,
+ 0x15, 0x10, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x27,
+ 0x05, 0xdd, 0x60, 0xd7, 0xb1, 0xd6, 0xfe, 0xe0, 0xc1, 0xbd, 0x29, 0x0a,
+ 0xa8, 0x9e, 0x01, 0x04, 0x41, 0x46, 0x01, 0x1f, 0xc2, 0xbb, 0x2a, 0x0b,
+ 0xd3, 0xfe, 0xbc, 0xb6, 0xa2, 0x8e, 0x87, 0xdc, 0x10, 0x11, 0xe4, 0x90,
+ 0x94, 0x0a, 0x01, 0x8f, 0x89, 0xdf, 0x0d, 0x0d, 0x75, 0x6f, 0x08, 0x09,
+ 0x97, 0x02, 0x77, 0xb2, 0x68, 0xb0, 0xac, 0x01, 0x20, 0x47, 0x4b, 0x01,
+ 0x3f, 0xd3, 0xc6, 0x2c, 0x0b, 0xaf, 0xaa, 0xfe, 0xe3, 0x48, 0x4d, 0xfe,
+ 0xa1, 0xe8, 0x01, 0x08, 0x96, 0xb6, 0x01, 0x1d, 0x01, 0x0f, 0xa8, 0xa1,
+ 0x0c, 0x01, 0x9b, 0x9f, 0xfe, 0xf6, 0x11, 0x12, 0xfe, 0xee, 0xa9, 0xa1,
+ 0x09, 0x01, 0x31, 0x04, 0x04, 0x7f, 0x00, 0x02, 0x00, 0xbe, 0x00, 0x00,
+ 0x05, 0x6f, 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x00, 0x01, 0x16,
+ 0x17, 0x16, 0x07, 0x06, 0x17, 0x16, 0x17, 0x15, 0x23, 0x26, 0x3d, 0x01,
+ 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x23, 0x11, 0x21, 0x20, 0x17, 0x16,
+ 0x15, 0x14, 0x07, 0x06, 0x03, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x21,
+ 0x32, 0x37, 0x36, 0x04, 0x4a, 0x9d, 0x23, 0x0e, 0x02, 0x02, 0x14, 0x15,
+ 0x32, 0xe8, 0x29, 0x7b, 0x32, 0x49, 0xfe, 0x15, 0xbf, 0x02, 0xb1, 0x01,
+ 0x28, 0x6a, 0x34, 0x67, 0x32, 0x2d, 0xa6, 0x35, 0x4a, 0xfe, 0x33, 0x01,
+ 0xcd, 0xdb, 0x36, 0x14, 0x02, 0xe1, 0x44, 0x91, 0x3d, 0x89, 0x81, 0x39,
+ 0x3a, 0x23, 0x2f, 0x60, 0x94, 0x85, 0xc3, 0x32, 0x15, 0xfd, 0x7d, 0x05,
+ 0xd5, 0xb6, 0x5a, 0x7f, 0xab, 0x62, 0x30, 0x01, 0x22, 0xc9, 0x2b, 0x0e,
+ 0xfd, 0xfe, 0x86, 0x32, 0x00, 0x01, 0x00, 0x62, 0xff, 0xd1, 0x04, 0xf8,
+ 0x05, 0xee, 0x00, 0x32, 0x00, 0x00, 0x25, 0x20, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x27, 0x25, 0x24, 0x11, 0x34, 0x37, 0x36, 0x33, 0x20, 0x17,
+ 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14,
+ 0x17, 0x16, 0x17, 0x05, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x21,
+ 0x20, 0x27, 0x26, 0x27, 0x33, 0x15, 0x14, 0x17, 0x16, 0x02, 0xbc, 0x01,
+ 0x22, 0x47, 0x14, 0xa5, 0x2f, 0x3e, 0xfe, 0x8d, 0xfe, 0xdb, 0x9e, 0x8d,
+ 0xe8, 0x01, 0x31, 0x8e, 0x63, 0x01, 0xb5, 0x02, 0xa5, 0x54, 0x79, 0xb2,
+ 0x5c, 0x40, 0x4b, 0x37, 0x74, 0x01, 0x76, 0xd2, 0x4a, 0x22, 0x62, 0x97,
+ 0xfe, 0xb1, 0xfe, 0xe4, 0x9c, 0x93, 0x03, 0xb5, 0x74, 0x6c, 0x79, 0xa8,
+ 0x2f, 0x37, 0x87, 0x47, 0x14, 0x10, 0x62, 0x4c, 0x01, 0x10, 0xd7, 0x76,
+ 0x6a, 0xa7, 0x74, 0xb4, 0xc1, 0x49, 0x25, 0x5e, 0x41, 0x5d, 0x62, 0x35,
+ 0x27, 0x1f, 0x65, 0x39, 0x9d, 0x49, 0x57, 0x9f, 0x75, 0xb5, 0x8d, 0x86,
+ 0xf7, 0x0a, 0xa7, 0x5c, 0x55, 0x00, 0x00, 0x01, 0x00, 0x2b, 0x00, 0x00,
+ 0x04, 0xbe, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11,
+ 0x21, 0x35, 0x21, 0x15, 0x02, 0xd5, 0xbe, 0xfe, 0x14, 0x04, 0x93, 0x05,
+ 0x2d, 0xfa, 0xd3, 0x05, 0x2d, 0xa8, 0xa8, 0x00, 0x00, 0x01, 0x00, 0xae,
+ 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x01, 0x33,
+ 0x11, 0x14, 0x07, 0x06, 0x21, 0x20, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11,
+ 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x04, 0x6a, 0xbf, 0x9d,
+ 0x9d, 0xfe, 0xfa, 0xfe, 0xe0, 0x9a, 0x81, 0xbf, 0xae, 0x56, 0x78, 0xd9,
+ 0x66, 0x42, 0x05, 0xd5, 0xfb, 0xe7, 0xe1, 0x86, 0x84, 0x9a, 0x81, 0xd0,
+ 0x04, 0x19, 0xfb, 0xe7, 0xd0, 0x4d, 0x26, 0x7b, 0x50, 0x78, 0x00, 0x01,
+ 0x00, 0x3d, 0x00, 0x00, 0x05, 0x29, 0x05, 0xd5, 0x00, 0x06, 0x00, 0x00,
+ 0x21, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33, 0x03, 0x23, 0xcd, 0xfd, 0xe7,
+ 0xcd, 0x01, 0xb7, 0x01, 0x9d, 0xcb, 0x05, 0xd5, 0xfb, 0x10, 0x04, 0xf0,
+ 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x07, 0x6f, 0x05, 0xd5, 0x00, 0x0c,
+ 0x00, 0x00, 0x21, 0x23, 0x09, 0x01, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33,
+ 0x09, 0x01, 0x33, 0x05, 0xf4, 0xd1, 0xfe, 0xa8, 0xfe, 0xb2, 0xd1, 0xfe,
+ 0x81, 0xd5, 0x01, 0x19, 0x01, 0x4b, 0xcd, 0x01, 0x54, 0x01, 0x13, 0xd5,
+ 0x04, 0xcb, 0xfb, 0x35, 0x05, 0xd5, 0xfb, 0x44, 0x04, 0xbc, 0xfb, 0x44,
+ 0x04, 0xbc, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x05, 0x31, 0x05, 0xd5,
+ 0x00, 0x0b, 0x00, 0x00, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, 0x09, 0x01,
+ 0x33, 0x09, 0x01, 0x33, 0x03, 0x21, 0x02, 0x10, 0xeb, 0xfe, 0x68, 0xfe,
+ 0x66, 0xe7, 0x02, 0x10, 0xfe, 0x11, 0xe7, 0x01, 0x7f, 0x01, 0x81, 0xe4,
+ 0x02, 0xfe, 0xfd, 0x02, 0x02, 0x6f, 0xfd, 0x91, 0x02, 0xfe, 0x02, 0xd7,
+ 0xfd, 0xb6, 0x02, 0x4a, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x05, 0x4a,
+ 0x05, 0xd5, 0x00, 0x08, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x33,
+ 0x09, 0x01, 0x33, 0x03, 0x19, 0xbf, 0xfd, 0xc1, 0xeb, 0x01, 0xb6, 0x01,
+ 0xaa, 0xe4, 0x02, 0x4a, 0xfd, 0xb6, 0x02, 0x4a, 0x03, 0x8b, 0xfd, 0x29,
+ 0x02, 0xd7, 0x00, 0x01, 0x00, 0x39, 0x00, 0x00, 0x04, 0xaa, 0x05, 0xd5,
+ 0x00, 0x09, 0x00, 0x00, 0x01, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01,
+ 0x21, 0x35, 0x04, 0xa6, 0xfc, 0x83, 0x03, 0x81, 0xfb, 0x8f, 0x03, 0x81,
+ 0xfc, 0xb9, 0x05, 0xd5, 0xac, 0xfb, 0x7f, 0xa8, 0xa8, 0x04, 0x85, 0xa8,
+ 0x00, 0x01, 0x00, 0x83, 0xfe, 0x4e, 0x02, 0x00, 0x05, 0xd5, 0x00, 0x07,
+ 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x11, 0x02, 0x00,
+ 0xd3, 0xd3, 0xfe, 0x83, 0x05, 0xd5, 0x93, 0xf9, 0x9f, 0x93, 0x07, 0x87,
+ 0x00, 0x01, 0xff, 0xf0, 0xff, 0xd7, 0x02, 0x46, 0x05, 0xd5, 0x00, 0x03,
+ 0x00, 0x00, 0x13, 0x01, 0x23, 0x01, 0x60, 0x01, 0xe6, 0x71, 0xfe, 0x1b,
+ 0x05, 0xd5, 0xfa, 0x02, 0x05, 0xfe, 0x00, 0x01, 0x00, 0x2f, 0xfe, 0x4e,
+ 0x01, 0xac, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x00, 0x13, 0x35, 0x33, 0x11,
+ 0x23, 0x35, 0x21, 0x11, 0x2f, 0xd3, 0xd3, 0x01, 0x7d, 0xfe, 0x4e, 0x93,
+ 0x06, 0x61, 0x93, 0xf8, 0x79, 0x00, 0x00, 0x01, 0x00, 0x5a, 0x02, 0xa2,
+ 0x03, 0x66, 0x05, 0xac, 0x00, 0x06, 0x00, 0x00, 0x01, 0x33, 0x01, 0x23,
+ 0x0b, 0x01, 0x23, 0x01, 0x93, 0x96, 0x01, 0x3d, 0x8d, 0xfa, 0xf8, 0x8d,
+ 0x05, 0xac, 0xfc, 0xf6, 0x02, 0x66, 0xfd, 0x9a, 0x00, 0x01, 0xff, 0xd3,
+ 0xfe, 0x98, 0x04, 0xa0, 0xfe, 0xfe, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15,
+ 0x21, 0x35, 0x04, 0xa0, 0xfb, 0x33, 0xfe, 0xfe, 0x66, 0x66, 0x00, 0x01,
+ 0x00, 0x2d, 0x04, 0xbc, 0x01, 0xd9, 0x05, 0xec, 0x00, 0x03, 0x00, 0x00,
+ 0x01, 0x13, 0x23, 0x01, 0x01, 0x14, 0xc5, 0x7b, 0xfe, 0xcf, 0x05, 0xec,
+ 0xfe, 0xd0, 0x01, 0x30, 0x00, 0x02, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48,
+ 0x04, 0x50, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00, 0x13, 0x12, 0x25, 0x36,
+ 0x33, 0x20, 0x17, 0x16, 0x15, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37,
+ 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22,
+ 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36,
+ 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x13, 0x32,
+ 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17,
+ 0x16, 0x85, 0x0a, 0x01, 0x43, 0x2e, 0x33, 0x01, 0x31, 0x4c, 0x17, 0x46,
+ 0x0a, 0x0c, 0x12, 0x13, 0x48, 0x2d, 0x7f, 0x23, 0x0a, 0x04, 0x90, 0x94,
+ 0x23, 0x26, 0xc0, 0x5e, 0x42, 0x77, 0x54, 0xc6, 0x25, 0x5e, 0x84, 0x20,
+ 0x0f, 0x82, 0x30, 0x3e, 0xb7, 0x31, 0x0f, 0x05, 0xaa, 0x9b, 0x61, 0x46,
+ 0x38, 0x98, 0x9c, 0x3c, 0x6d, 0x66, 0x2e, 0x02, 0xf4, 0x01, 0x30, 0x27,
+ 0x05, 0xae, 0x34, 0x43, 0xfd, 0x89, 0x48, 0x0a, 0x02, 0x04, 0x81, 0x12,
+ 0x5e, 0x1c, 0x24, 0x84, 0x15, 0x05, 0x74, 0x51, 0x78, 0xb0, 0x4c, 0x36,
+ 0x1d, 0x06, 0x0c, 0x10, 0x2d, 0x16, 0x23, 0x2d, 0x72, 0x22, 0x0c, 0x70,
+ 0x21, 0x2d, 0xfd, 0x72, 0x5d, 0x43, 0x4c, 0xc0, 0x19, 0x17, 0x17, 0x1b,
+ 0x31, 0x6d, 0x70, 0x29, 0x13, 0x00, 0x00, 0x02, 0x00, 0x6f, 0xff, 0xd1,
+ 0x04, 0x2f, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x24, 0x00, 0x00, 0x13, 0x33,
+ 0x11, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x10, 0x07, 0x06,
+ 0x23, 0x22, 0x27, 0x26, 0x27, 0x15, 0x23, 0x01, 0x22, 0x07, 0x06, 0x15,
+ 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x6f,
+ 0xaa, 0x68, 0xb6, 0x16, 0x17, 0xdd, 0x7c, 0x72, 0x8a, 0x7e, 0xcb, 0xd5,
+ 0x77, 0x04, 0x04, 0x99, 0x01, 0xd5, 0x91, 0x53, 0x47, 0x6b, 0x4d, 0x73,
+ 0x90, 0x57, 0x52, 0x6e, 0x51, 0x05, 0xd5, 0xfd, 0xcb, 0x9f, 0x0f, 0x02,
+ 0xa3, 0x96, 0xfa, 0xfe, 0xe8, 0xa1, 0x93, 0xac, 0x06, 0x06, 0x89, 0x03,
+ 0xb0, 0x81, 0x6f, 0xb0, 0xdb, 0x72, 0x52, 0x78, 0x71, 0xb0, 0xdd, 0x73,
+ 0x56, 0x00, 0x00, 0x01, 0x00, 0x3f, 0xff, 0xd1, 0x03, 0xd1, 0x04, 0x50,
+ 0x00, 0x1f, 0x00, 0x00, 0x01, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07,
+ 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x13, 0x33, 0x06, 0x07, 0x06,
+ 0x23, 0x22, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16,
+ 0x03, 0xc5, 0xac, 0x18, 0x83, 0x2c, 0x37, 0xa5, 0x4d, 0x37, 0x7a, 0x49,
+ 0x6a, 0xdb, 0x2b, 0xac, 0x13, 0xa3, 0x69, 0x97, 0xde, 0x81, 0x7d, 0x8b,
+ 0x82, 0xd1, 0xf3, 0x6d, 0x3d, 0x02, 0xc9, 0xa9, 0x30, 0x10, 0x99, 0x6c,
+ 0xa7, 0xf0, 0x69, 0x3e, 0x01, 0x02, 0xf0, 0x6b, 0x45, 0x9d, 0x99, 0x00,
+ 0xff, 0x01, 0x14, 0xa1, 0x95, 0xa5, 0x5c, 0x00, 0x00, 0x02, 0x00, 0x35,
+ 0xff, 0xd1, 0x03, 0xf6, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x24, 0x00, 0x00,
+ 0x01, 0x11, 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x11,
+ 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x11, 0x01, 0x22, 0x07,
+ 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27,
+ 0x26, 0x03, 0xf6, 0x98, 0x62, 0x85, 0x32, 0x3d, 0xe2, 0x7e, 0x73, 0x87,
+ 0x7d, 0xc9, 0xd4, 0x6e, 0x04, 0x04, 0xfe, 0xd3, 0x93, 0x57, 0x4e, 0x6b,
+ 0x53, 0x7c, 0x8f, 0x53, 0x49, 0x6e, 0x4d, 0x05, 0xd5, 0xfa, 0x2b, 0x8d,
+ 0x8e, 0x21, 0x0d, 0xaa, 0x9b, 0x01, 0x05, 0x01, 0x0a, 0x9c, 0x8f, 0x9a,
+ 0x06, 0x06, 0x02, 0x2b, 0xfd, 0xdb, 0x7d, 0x71, 0xb2, 0xd2, 0x73, 0x5a,
+ 0x7d, 0x6f, 0xaf, 0xe2, 0x72, 0x50, 0x00, 0x02, 0x00, 0x52, 0xff, 0xd1,
+ 0x04, 0x1b, 0x04, 0x50, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x00, 0x01, 0x21,
+ 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x33, 0x06,
+ 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32,
+ 0x17, 0x16, 0x17, 0x16, 0x05, 0x21, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23,
+ 0x22, 0x07, 0x06, 0x04, 0x1b, 0xfc, 0xe9, 0x02, 0x28, 0x07, 0x08, 0x4f,
+ 0x90, 0x11, 0x12, 0xd2, 0x47, 0xac, 0x27, 0xa3, 0x6d, 0x94, 0xec, 0x83,
+ 0x78, 0x8d, 0x85, 0xd9, 0xc5, 0x83, 0x46, 0x25, 0x2b, 0xfc, 0xed, 0x02,
+ 0x5a, 0x02, 0x5a, 0x55, 0x7a, 0x95, 0x56, 0x3e, 0x01, 0xdf, 0x84, 0x48,
+ 0x0d, 0x0c, 0x7b, 0x0e, 0x02, 0xd7, 0xd3, 0x61, 0x41, 0xa6, 0x97, 0xfc,
+ 0x01, 0x11, 0x9f, 0x96, 0x7c, 0x42, 0x5d, 0x73, 0x58, 0x05, 0x08, 0x88,
+ 0x5c, 0x57, 0x74, 0x55, 0x00, 0x01, 0x00, 0x25, 0x00, 0x00, 0x02, 0x10,
+ 0x05, 0xdb, 0x00, 0x15, 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11,
+ 0x23, 0x35, 0x33, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x15, 0x26,
+ 0x23, 0x22, 0x1d, 0x01, 0x02, 0x10, 0xb2, 0xaa, 0x8f, 0x8f, 0x72, 0x3a,
+ 0x50, 0x2f, 0x31, 0x27, 0x14, 0x77, 0x04, 0x31, 0x8b, 0xfc, 0x5a, 0x03,
+ 0xa6, 0x8b, 0xb6, 0x9a, 0x3c, 0x1e, 0x0a, 0x8d, 0x02, 0x6d, 0xa8, 0x00,
+ 0x00, 0x02, 0x00, 0x3b, 0xfe, 0x42, 0x03, 0xe9, 0x04, 0x50, 0x00, 0x2a,
+ 0x00, 0x3a, 0x00, 0x00, 0x05, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x10,
+ 0x37, 0x36, 0x37, 0x32, 0x33, 0x32, 0x17, 0x16, 0x17, 0x35, 0x33, 0x11,
+ 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x33, 0x16,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x03,
+ 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x10, 0x27, 0x26, 0x01, 0xf6, 0xac, 0x79, 0x89, 0x0c, 0x01, 0x80, 0x78,
+ 0xbf, 0x09, 0x09, 0xc4, 0x7e, 0x03, 0x03, 0x9d, 0x45, 0x5a, 0xf0, 0x26,
+ 0x2a, 0xf3, 0x70, 0x3f, 0x0a, 0xae, 0x18, 0xa2, 0x22, 0x28, 0xbe, 0x41,
+ 0x2c, 0x64, 0x73, 0x32, 0x1b, 0x99, 0x50, 0x40, 0x78, 0x49, 0x6a, 0x9b,
+ 0x4d, 0x3a, 0x80, 0x44, 0x2f, 0x81, 0x91, 0xf8, 0x15, 0x16, 0x01, 0x07,
+ 0xa3, 0x98, 0x08, 0xb1, 0x04, 0x05, 0x9b, 0xfc, 0x7f, 0xfe, 0xe3, 0x87,
+ 0xb0, 0x16, 0x04, 0x89, 0x4c, 0x6e, 0x92, 0x1c, 0x06, 0x82, 0x58, 0xaf,
+ 0x37, 0x8d, 0x24, 0x0f, 0x03, 0xe1, 0x89, 0x6d, 0xac, 0xf4, 0x6c, 0x41,
+ 0x8d, 0x69, 0xa5, 0x01, 0x09, 0x68, 0x37, 0x00, 0x00, 0x01, 0x00, 0x8f,
+ 0x00, 0x00, 0x03, 0xe3, 0x05, 0xd5, 0x00, 0x17, 0x00, 0x00, 0x01, 0x34,
+ 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x11,
+ 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x23, 0x03, 0x39,
+ 0x79, 0x2f, 0x35, 0x91, 0x50, 0x42, 0xaa, 0xaa, 0x5e, 0x67, 0x3e, 0x55,
+ 0xbe, 0x59, 0x3b, 0xaa, 0x02, 0xe7, 0x90, 0x30, 0x13, 0x75, 0x61, 0x94,
+ 0xfd, 0xb0, 0x05, 0xd5, 0xfd, 0xc9, 0x7a, 0x23, 0x15, 0x70, 0x4a, 0x6b,
+ 0xfc, 0xd5, 0x00, 0x02, 0x00, 0x87, 0x00, 0x00, 0x01, 0x33, 0x05, 0xd5,
+ 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x13, 0x11,
+ 0x23, 0x11, 0x01, 0x33, 0xac, 0xac, 0xa9, 0x05, 0xd5, 0xd7, 0xd7, 0xfe,
+ 0x5c, 0xfb, 0xcf, 0x04, 0x31, 0x00, 0x00, 0x02, 0xff, 0xdb, 0xfe, 0x42,
+ 0x01, 0x39, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x01, 0x15,
+ 0x23, 0x35, 0x11, 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x35,
+ 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x01, 0x39, 0xaa, 0xaa, 0xce, 0x28,
+ 0x2f, 0x1a, 0x1f, 0x23, 0x06, 0x5d, 0x1c, 0x12, 0x05, 0xd5, 0xd7, 0xd7,
+ 0xfe, 0x5c, 0xfa, 0xf0, 0xb9, 0x20, 0x06, 0x06, 0x91, 0x02, 0x2e, 0x1f,
+ 0x40, 0x00, 0x00, 0x01, 0x00, 0x77, 0x00, 0x00, 0x04, 0x04, 0x05, 0xd5,
+ 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x01,
+ 0x07, 0x11, 0x23, 0x11, 0x01, 0x21, 0x01, 0xc6, 0xdc, 0xfe, 0x8b, 0x01,
+ 0xb6, 0xd3, 0xfe, 0x96, 0xa6, 0xaa, 0x05, 0xd5, 0xfc, 0x95, 0x01, 0xc7,
+ 0xfe, 0x8d, 0xfd, 0x42, 0x02, 0x46, 0xa4, 0xfe, 0x5e, 0x05, 0xd5, 0x00,
+ 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x01, 0x37, 0x05, 0xd5, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x37, 0xac, 0x05, 0xd5, 0xfa,
+ 0x2b, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x8f, 0x00, 0x00, 0x06, 0x19,
+ 0x04, 0x50, 0x00, 0x2a, 0x00, 0x00, 0x13, 0x33, 0x15, 0x36, 0x37, 0x36,
+ 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16,
+ 0x15, 0x11, 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15,
+ 0x11, 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11,
+ 0x23, 0x8f, 0x9e, 0x5d, 0x72, 0x36, 0x45, 0x9d, 0x54, 0x1a, 0x16, 0x5e,
+ 0x62, 0x3a, 0x4f, 0xd4, 0x46, 0x1e, 0xac, 0x62, 0x2b, 0x3a, 0x6c, 0x4a,
+ 0x46, 0xac, 0x71, 0x25, 0x31, 0x6c, 0x4a, 0x46, 0xac, 0x04, 0x31, 0x97,
+ 0x83, 0x22, 0x11, 0x5e, 0x1e, 0x28, 0x71, 0x20, 0x13, 0x95, 0x40, 0x56,
+ 0xfc, 0xdb, 0x02, 0xe3, 0x8e, 0x32, 0x17, 0x56, 0x51, 0x71, 0xfd, 0x5e,
+ 0x02, 0xe3, 0x9c, 0x2c, 0x0f, 0x56, 0x51, 0x71, 0xfd, 0x5e, 0x00, 0x01,
+ 0x00, 0x8f, 0x00, 0x00, 0x03, 0xe5, 0x04, 0x50, 0x00, 0x17, 0x00, 0x00,
+ 0x13, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11,
+ 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23,
+ 0x8f, 0x9e, 0x5d, 0x7a, 0x3d, 0x50, 0xb6, 0x5d, 0x41, 0xaa, 0x5c, 0x35,
+ 0x4c, 0x91, 0x50, 0x42, 0xac, 0x04, 0x31, 0xb4, 0x94, 0x2a, 0x15, 0x6b,
+ 0x4b, 0x6f, 0xfc, 0xd5, 0x02, 0xe7, 0x7a, 0x38, 0x21, 0x75, 0x61, 0x94,
+ 0xfd, 0xb0, 0x00, 0x02, 0x00, 0x4a, 0xff, 0xd1, 0x04, 0x14, 0x04, 0x50,
+ 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x20, 0x17, 0x16, 0x15, 0x10,
+ 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x17, 0x22,
+ 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x02, 0x2d, 0x01, 0x08, 0x7f, 0x60, 0x9a, 0x7f, 0xcc, 0xf9,
+ 0x81, 0x6b, 0xa0, 0x7c, 0xc9, 0x9f, 0x53, 0x41, 0x77, 0x4c, 0x70, 0x9d,
+ 0x53, 0x43, 0x7e, 0x4a, 0x04, 0x50, 0xc3, 0x95, 0xf0, 0xfe, 0xde, 0x98,
+ 0x7d, 0xb4, 0x95, 0xf6, 0x01, 0x2f, 0x99, 0x78, 0x9e, 0x8a, 0x6d, 0xab,
+ 0xee, 0x6d, 0x46, 0x86, 0x6c, 0xa9, 0xfd, 0x6c, 0x3f, 0x00, 0x00, 0x02,
+ 0x00, 0x6f, 0xfe, 0x42, 0x04, 0x2f, 0x04, 0x50, 0x00, 0x11, 0x00, 0x21,
+ 0x00, 0x00, 0x13, 0x11, 0x33, 0x15, 0x36, 0x20, 0x17, 0x16, 0x11, 0x10,
+ 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x11, 0x01, 0x22, 0x07, 0x06,
+ 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26,
+ 0x6f, 0x9d, 0x7a, 0x01, 0xb8, 0x7d, 0x74, 0x88, 0x7c, 0xc7, 0xa9, 0x72,
+ 0x17, 0x17, 0x01, 0x2b, 0x91, 0x53, 0x47, 0x6b, 0x4d, 0x73, 0x91, 0x57,
+ 0x4f, 0x6d, 0x51, 0xfe, 0x42, 0x05, 0xef, 0xa2, 0xc1, 0xa7, 0x9d, 0xfe,
+ 0xfa, 0xfe, 0xf5, 0x9c, 0x8e, 0x6d, 0x17, 0x1c, 0xfd, 0xd1, 0x05, 0x6e,
+ 0x81, 0x6f, 0xb0, 0xdb, 0x72, 0x52, 0x7a, 0x70, 0xaf, 0xdc, 0x73, 0x57,
+ 0x00, 0x02, 0x00, 0x35, 0xfe, 0x42, 0x03, 0xf6, 0x04, 0x50, 0x00, 0x14,
+ 0x00, 0x24, 0x00, 0x00, 0x01, 0x23, 0x11, 0x06, 0x07, 0x06, 0x23, 0x22,
+ 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x35,
+ 0x33, 0x05, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37,
+ 0x36, 0x35, 0x34, 0x27, 0x26, 0x03, 0xf6, 0xaa, 0x60, 0x9d, 0x25, 0x2a,
+ 0xdd, 0x7c, 0x72, 0x89, 0x7f, 0xcb, 0xc3, 0x7a, 0x0d, 0x0c, 0x98, 0xfe,
+ 0x2b, 0x94, 0x57, 0x4f, 0x6b, 0x53, 0x7c, 0x8f, 0x53, 0x49, 0x6d, 0x4d,
+ 0xfe, 0x42, 0x02, 0x39, 0x8d, 0x17, 0x06, 0xa3, 0x96, 0xfa, 0x01, 0x15,
+ 0xa2, 0x95, 0x8e, 0x0f, 0x11, 0x8f, 0x81, 0x7d, 0x71, 0xb2, 0xd2, 0x73,
+ 0x5a, 0x7d, 0x6e, 0xae, 0xe3, 0x73, 0x50, 0x00, 0x00, 0x01, 0x00, 0x8d,
+ 0x00, 0x00, 0x02, 0x91, 0x04, 0x50, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x06,
+ 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33,
+ 0x32, 0x17, 0x02, 0x91, 0xb0, 0x4e, 0x5a, 0xac, 0x9e, 0x64, 0x5f, 0x2d,
+ 0x35, 0x17, 0x2a, 0x03, 0x9c, 0x03, 0x49, 0x55, 0xce, 0xfd, 0xd3, 0x04,
+ 0x31, 0xc2, 0xa2, 0x2b, 0x14, 0x06, 0x00, 0x01, 0x00, 0x46, 0xff, 0xd1,
+ 0x03, 0xac, 0x04, 0x50, 0x00, 0x32, 0x00, 0x00, 0x13, 0x1e, 0x01, 0x33,
+ 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x27, 0x26,
+ 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27,
+ 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x1f, 0x01, 0x16,
+ 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x20, 0x27, 0x26, 0x27, 0xfa,
+ 0x0f, 0x7e, 0x79, 0x93, 0x42, 0x25, 0x4f, 0x22, 0x35, 0xa0, 0xd4, 0x48,
+ 0x38, 0x80, 0x6f, 0xad, 0xfc, 0x5c, 0x2c, 0x01, 0xb4, 0x05, 0xa3, 0x16,
+ 0x19, 0x8f, 0x3a, 0x1b, 0x65, 0x28, 0x3a, 0xa4, 0xd1, 0x3e, 0x20, 0x88,
+ 0x76, 0xbc, 0xfe, 0xa4, 0x41, 0x0d, 0x02, 0x01, 0x3f, 0x72, 0x5e, 0x4a,
+ 0x28, 0x36, 0x50, 0x27, 0x11, 0x0d, 0x27, 0x33, 0x52, 0x41, 0x6f, 0xa1,
+ 0x5a, 0x4d, 0x9a, 0x49, 0x67, 0x96, 0x13, 0x03, 0x4d, 0x25, 0x30, 0x50,
+ 0x2b, 0x10, 0x0e, 0x27, 0x32, 0x6d, 0x3a, 0x52, 0xa6, 0x5d, 0x51, 0xfc,
+ 0x34, 0x3e, 0x00, 0x01, 0x00, 0x1d, 0xff, 0xd1, 0x02, 0x08, 0x05, 0x58,
+ 0x00, 0x17, 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x14, 0x17, 0x16, 0x33,
+ 0x32, 0x37, 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x23, 0x35,
+ 0x33, 0x11, 0x33, 0x11, 0x02, 0x08, 0xb0, 0x1f, 0x14, 0x2b, 0x36, 0x1c,
+ 0x50, 0x3b, 0x9e, 0x26, 0x0b, 0x91, 0x91, 0xaa, 0x04, 0x31, 0x8b, 0xfd,
+ 0x21, 0x45, 0x11, 0x0b, 0x09, 0x90, 0x0e, 0x69, 0x1d, 0x24, 0x03, 0x2b,
+ 0x8b, 0x01, 0x27, 0xfe, 0xd9, 0x00, 0x00, 0x01, 0x00, 0x85, 0xff, 0xd1,
+ 0x03, 0xdb, 0x04, 0x31, 0x00, 0x17, 0x00, 0x00, 0x21, 0x23, 0x35, 0x06,
+ 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17,
+ 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x03, 0xdb, 0x99, 0x60,
+ 0x71, 0x41, 0x55, 0xb9, 0x5c, 0x41, 0xaa, 0x5c, 0x35, 0x4c, 0x93, 0x50,
+ 0x42, 0xaa, 0x96, 0x87, 0x28, 0x16, 0x6c, 0x4b, 0x6e, 0x03, 0x3b, 0xfd,
+ 0x08, 0x7a, 0x38, 0x21, 0x76, 0x61, 0x94, 0x02, 0x60, 0x00, 0x00, 0x01,
+ 0x00, 0x14, 0x00, 0x00, 0x03, 0xe3, 0x04, 0x31, 0x00, 0x06, 0x00, 0x00,
+ 0x21, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33, 0x02, 0x48, 0xbb, 0xfe, 0x87,
+ 0xc1, 0x01, 0x1f, 0x01, 0x2f, 0xc0, 0x04, 0x31, 0xfc, 0x9a, 0x03, 0x66,
+ 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x05, 0xaa, 0x04, 0x31, 0x00, 0x0c,
+ 0x00, 0x00, 0x21, 0x23, 0x0b, 0x01, 0x23, 0x01, 0x33, 0x1b, 0x01, 0x33,
+ 0x1b, 0x01, 0x33, 0x04, 0x6f, 0xc3, 0xd9, 0xcf, 0xc0, 0xfe, 0xc8, 0xbd,
+ 0xdb, 0xcd, 0xd1, 0xd2, 0xd5, 0xc1, 0x03, 0x4a, 0xfc, 0xb6, 0x04, 0x31,
+ 0xfc, 0xbd, 0x03, 0x43, 0xfc, 0xbd, 0x03, 0x43, 0x00, 0x01, 0x00, 0x23,
+ 0x00, 0x00, 0x03, 0xc9, 0x04, 0x31, 0x00, 0x0b, 0x00, 0x00, 0x09, 0x01,
+ 0x23, 0x09, 0x01, 0x23, 0x09, 0x01, 0x33, 0x09, 0x01, 0x33, 0x02, 0x56,
+ 0x01, 0x73, 0xc7, 0xfe, 0xf4, 0xfe, 0xef, 0xc2, 0x01, 0x7b, 0xfe, 0x99,
+ 0xc3, 0x01, 0x02, 0x01, 0x02, 0xc0, 0x02, 0x2b, 0xfd, 0xd5, 0x01, 0x9c,
+ 0xfe, 0x64, 0x02, 0x23, 0x02, 0x0e, 0xfe, 0x7b, 0x01, 0x85, 0x00, 0x01,
+ 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x04, 0x31, 0x00, 0x11, 0x00, 0x00,
+ 0x01, 0x33, 0x01, 0x06, 0x23, 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37,
+ 0x36, 0x3f, 0x01, 0x01, 0x33, 0x01, 0x03, 0x1b, 0xb8, 0xfe, 0x23, 0x54,
+ 0xc1, 0x41, 0x31, 0x3b, 0x1f, 0x4c, 0x24, 0x0d, 0x0c, 0x41, 0xfe, 0x96,
+ 0xb6, 0x01, 0x13, 0x04, 0x31, 0xfa, 0xee, 0xdd, 0x1a, 0x9a, 0x0d, 0x36,
+ 0x15, 0x1e, 0xaa, 0x04, 0x35, 0xfc, 0xbd, 0x00, 0x00, 0x01, 0x00, 0x3f,
+ 0x00, 0x00, 0x03, 0xa8, 0x04, 0x31, 0x00, 0x09, 0x00, 0x00, 0x01, 0x15,
+ 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x35, 0x03, 0x8b, 0xfd, 0x83,
+ 0x02, 0x9a, 0xfc, 0x97, 0x02, 0x82, 0xfd, 0xa9, 0x04, 0x31, 0x97, 0xfc,
+ 0xfc, 0x96, 0x9a, 0x03, 0x02, 0x95, 0x00, 0x01, 0x00, 0x58, 0xfe, 0x4e,
+ 0x02, 0x35, 0x05, 0xd5, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x15, 0x23, 0x22,
+ 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15,
+ 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x35,
+ 0x11, 0x34, 0x27, 0x26, 0x27, 0x35, 0x36, 0x37, 0x36, 0x35, 0x11, 0x34,
+ 0x37, 0x36, 0x33, 0x02, 0x35, 0x1e, 0x55, 0x19, 0x13, 0x3d, 0x25, 0x46,
+ 0x8b, 0x18, 0x05, 0x25, 0x1b, 0x41, 0x1e, 0x5e, 0x8e, 0x36, 0x1b, 0x32,
+ 0x23, 0x4b, 0x5e, 0x22, 0x20, 0x6f, 0x30, 0x40, 0x05, 0xd5, 0x85, 0x26,
+ 0x1e, 0x45, 0xfe, 0x8d, 0xae, 0x4a, 0x2e, 0x1c, 0x41, 0xad, 0x27, 0x2e,
+ 0xfe, 0x8d, 0x5b, 0x1a, 0x14, 0x85, 0x7a, 0x3d, 0x55, 0x01, 0x56, 0xa6,
+ 0x3c, 0x2a, 0x0f, 0x8d, 0x13, 0x41, 0x3d, 0x8a, 0x01, 0x56, 0xb3, 0x3e,
+ 0x1b, 0x00, 0x00, 0x01, 0x00, 0xcd, 0xfe, 0x4e, 0x01, 0x48, 0x05, 0xd5,
+ 0x00, 0x03, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23, 0xcd, 0x7b, 0x7b, 0x05,
+ 0xd5, 0xf8, 0x79, 0x00, 0x00, 0x01, 0x00, 0x3b, 0xfe, 0x4e, 0x02, 0x19,
+ 0x05, 0xd5, 0x00, 0x2a, 0x00, 0x00, 0x13, 0x35, 0x33, 0x32, 0x37, 0x36,
+ 0x35, 0x11, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x11, 0x34,
+ 0x27, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x14,
+ 0x17, 0x16, 0x17, 0x15, 0x06, 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06,
+ 0x23, 0x3b, 0x21, 0x56, 0x1a, 0x13, 0x79, 0x15, 0x1a, 0x8f, 0x15, 0x04,
+ 0x25, 0x1c, 0x42, 0x21, 0x61, 0x92, 0x35, 0x1a, 0x33, 0x22, 0x47, 0x5d,
+ 0x21, 0x1e, 0x71, 0x30, 0x40, 0xfe, 0x4e, 0x85, 0x26, 0x1d, 0x46, 0x01,
+ 0x73, 0xd4, 0x53, 0x0f, 0x0b, 0x43, 0xb7, 0x22, 0x28, 0x01, 0x73, 0x5b,
+ 0x1a, 0x14, 0x85, 0x7d, 0x3c, 0x53, 0xfe, 0xaa, 0xa7, 0x3c, 0x29, 0x0f,
+ 0x8d, 0x14, 0x44, 0x3e, 0x85, 0xfe, 0xaa, 0xb4, 0x3e, 0x1a, 0x00, 0x01,
+ 0x00, 0x9a, 0x02, 0x25, 0x04, 0x10, 0x03, 0x81, 0x00, 0x1f, 0x00, 0x00,
+ 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1f,
+ 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, 0x07,
+ 0x06, 0x23, 0x22, 0x2f, 0x01, 0x26, 0x27, 0x26, 0x01, 0x73, 0x5e, 0x0e,
+ 0x01, 0x6c, 0x0c, 0x87, 0x22, 0x28, 0x39, 0x35, 0xf0, 0x39, 0x2d, 0x51,
+ 0x12, 0x06, 0x6c, 0x59, 0x35, 0x49, 0x4f, 0x57, 0xc8, 0x28, 0x28, 0x05,
+ 0x02, 0xf8, 0x95, 0x05, 0x06, 0xea, 0x32, 0x0d, 0x21, 0x8d, 0x23, 0x4d,
+ 0x1b, 0x27, 0x0b, 0x21, 0x96, 0x45, 0x29, 0x35, 0x81, 0x17, 0x05, 0x01,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06,
+ 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0xfa, 0xfe, 0x5c, 0x01, 0xa6,
+ 0x04, 0x31, 0x10, 0x0f, 0x00, 0x05, 0x02, 0xa4, 0x04, 0x31, 0xc0, 0x00,
+ 0x00, 0x02, 0x00, 0x6a, 0xff, 0x0a, 0x04, 0x14, 0x05, 0x06, 0x00, 0x1e,
+ 0x00, 0x27, 0x00, 0x00, 0x01, 0x11, 0x36, 0x37, 0x33, 0x06, 0x07, 0x06,
+ 0x07, 0x15, 0x23, 0x35, 0x26, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x37,
+ 0x35, 0x33, 0x15, 0x16, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x03,
+ 0x11, 0x06, 0x03, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0x7f, 0xc6, 0x23,
+ 0xac, 0x0c, 0x8f, 0x65, 0x95, 0x56, 0xe0, 0x78, 0x67, 0x96, 0x73, 0xb6,
+ 0x56, 0xef, 0x62, 0x32, 0x06, 0xac, 0x0f, 0x6b, 0x2c, 0x8d, 0xe7, 0x20,
+ 0x05, 0x80, 0x3b, 0x03, 0xb2, 0xfc, 0xbb, 0x15, 0xef, 0xd8, 0x71, 0x50,
+ 0x07, 0xc7, 0xc9, 0x14, 0xac, 0x93, 0xe0, 0x01, 0x1a, 0xa0, 0x7b, 0x13,
+ 0xb8, 0xb6, 0x11, 0xa9, 0x56, 0x77, 0x93, 0x3a, 0x18, 0xfc, 0xc3, 0x03,
+ 0x3f, 0x2b, 0xfe, 0xdf, 0x2c, 0x32, 0xef, 0x69, 0x31, 0x00, 0x00, 0x01,
+ 0x00, 0x35, 0xff, 0xd1, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x41, 0x00, 0x00,
+ 0x01, 0x14, 0x1f, 0x01, 0x16, 0x17, 0x21, 0x15, 0x21, 0x16, 0x15, 0x14,
+ 0x07, 0x06, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x33, 0x32, 0x37, 0x17,
+ 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07,
+ 0x27, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x23, 0x35, 0x33, 0x26, 0x27,
+ 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17,
+ 0x23, 0x02, 0x21, 0x22, 0x07, 0x06, 0x01, 0x2d, 0x34, 0x3e, 0x04, 0x03,
+ 0x01, 0x48, 0xfe, 0xe9, 0x1f, 0x4f, 0x35, 0x6e, 0x79, 0x81, 0x45, 0x72,
+ 0x60, 0x33, 0x4f, 0x5b, 0x56, 0x67, 0x7b, 0x15, 0x16, 0x58, 0x82, 0x75,
+ 0x36, 0x17, 0x16, 0x6d, 0x72, 0x62, 0xb3, 0x31, 0x1c, 0x31, 0xe2, 0xa6,
+ 0x54, 0x0f, 0x09, 0x7a, 0x7a, 0xba, 0x1c, 0x1d, 0xf8, 0x74, 0x54, 0x03,
+ 0xb5, 0x09, 0xfe, 0xf3, 0x9a, 0x50, 0x37, 0x04, 0x2f, 0x56, 0x5d, 0x6d,
+ 0x06, 0x07, 0x71, 0x57, 0x3a, 0x5f, 0x6c, 0x49, 0x6f, 0x50, 0x23, 0x1d,
+ 0x3e, 0x87, 0x65, 0x0c, 0x02, 0x2c, 0x29, 0x06, 0x03, 0x4c, 0x87, 0x9a,
+ 0x6e, 0x3d, 0x43, 0x4c, 0x53, 0x71, 0x8b, 0x3a, 0x24, 0x34, 0xac, 0x7b,
+ 0x7a, 0x12, 0x03, 0xa1, 0x76, 0xc4, 0x01, 0x3b, 0x61, 0x43, 0x00, 0x02,
+ 0x00, 0x89, 0x01, 0x10, 0x03, 0xe9, 0x04, 0x68, 0x00, 0x1f, 0x00, 0x2f,
+ 0x00, 0x00, 0x01, 0x07, 0x27, 0x06, 0x23, 0x22, 0x27, 0x07, 0x27, 0x37,
+ 0x26, 0x27, 0x34, 0x35, 0x34, 0x37, 0x36, 0x37, 0x27, 0x37, 0x17, 0x36,
+ 0x33, 0x32, 0x17, 0x37, 0x17, 0x07, 0x16, 0x17, 0x14, 0x07, 0x01, 0x22,
+ 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x03, 0xe1, 0x77, 0x6c, 0x52, 0x7b, 0x6e, 0x52, 0x69, 0x72,
+ 0x62, 0x3c, 0x06, 0x3f, 0x01, 0x02, 0x6f, 0x73, 0x71, 0x59, 0x6d, 0x77,
+ 0x52, 0x79, 0x74, 0x70, 0x32, 0x03, 0x3b, 0xfe, 0xbe, 0x62, 0x41, 0x36,
+ 0x4a, 0x3e, 0x53, 0x5e, 0x42, 0x39, 0x4b, 0x3d, 0x01, 0x85, 0x6e, 0x6c,
+ 0x3d, 0x33, 0x69, 0x75, 0x64, 0x52, 0x6e, 0x09, 0x08, 0x71, 0x5b, 0x03,
+ 0x02, 0x71, 0x6c, 0x70, 0x35, 0x39, 0x6c, 0x77, 0x70, 0x57, 0x68, 0x67,
+ 0x5f, 0x01, 0x9b, 0x49, 0x3d, 0x51, 0x5f, 0x40, 0x36, 0x47, 0x3d, 0x4f,
+ 0x64, 0x41, 0x34, 0x00, 0x00, 0x01, 0x00, 0x17, 0x00, 0x00, 0x04, 0x5c,
+ 0x05, 0xac, 0x00, 0x16, 0x00, 0x00, 0x01, 0x15, 0x21, 0x15, 0x21, 0x15,
+ 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x01,
+ 0x33, 0x09, 0x01, 0x33, 0x01, 0x03, 0xf6, 0xfe, 0xa4, 0x01, 0x5c, 0xfe,
+ 0xa4, 0xb5, 0xfe, 0xa0, 0x01, 0x60, 0xfe, 0xa0, 0x01, 0x35, 0xfe, 0x5d,
+ 0xae, 0x01, 0x7a, 0x01, 0x6f, 0xae, 0xfe, 0x65, 0x02, 0xd5, 0x68, 0x9e,
+ 0x69, 0xfe, 0x9a, 0x01, 0x66, 0x69, 0x9e, 0x68, 0x02, 0xd7, 0xfd, 0x6d,
+ 0x02, 0x93, 0xfd, 0x29, 0x00, 0x02, 0x00, 0xcd, 0xfe, 0x4e, 0x01, 0x48,
+ 0x05, 0xd5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23,
+ 0x11, 0x33, 0x11, 0x23, 0xcd, 0x7b, 0x7b, 0x7b, 0x7b, 0x05, 0xd5, 0xfc,
+ 0xcb, 0xfe, 0xe3, 0xfc, 0xcb, 0x00, 0x00, 0x02, 0x00, 0x58, 0xfe, 0x4c,
+ 0x04, 0x0c, 0x05, 0xd5, 0x00, 0x45, 0x00, 0x55, 0x00, 0x00, 0x05, 0x14,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x25,
+ 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35,
+ 0x34, 0x37, 0x36, 0x37, 0x32, 0x33, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x23,
+ 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16,
+ 0x17, 0x05, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x17, 0x16, 0x15,
+ 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x13, 0x05, 0x36, 0x37,
+ 0x36, 0x35, 0x34, 0x27, 0x25, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16,
+ 0x01, 0x4c, 0x92, 0x1d, 0x22, 0x6d, 0x36, 0x21, 0x54, 0x0d, 0x0f, 0xfe,
+ 0xa3, 0x91, 0x20, 0x0b, 0x71, 0x2a, 0x3c, 0x4d, 0x0a, 0x03, 0x68, 0x6b,
+ 0x9d, 0x06, 0x05, 0xac, 0x63, 0x57, 0xac, 0x54, 0x30, 0x42, 0x60, 0x34,
+ 0x23, 0x3b, 0x17, 0x23, 0x01, 0x2b, 0x90, 0x2e, 0x21, 0xdf, 0x56, 0x11,
+ 0x06, 0x6c, 0x6d, 0xa6, 0xc0, 0x64, 0x59, 0xe3, 0x01, 0x54, 0x7b, 0x16,
+ 0x04, 0x95, 0xfe, 0xb6, 0x6b, 0x1a, 0x0c, 0x27, 0x1c, 0x1d, 0xcc, 0x26,
+ 0x08, 0x49, 0x2c, 0x3c, 0x5b, 0x44, 0x0a, 0x0b, 0xef, 0x65, 0x7d, 0x2c,
+ 0x34, 0x93, 0x5e, 0x22, 0x20, 0x5a, 0x4f, 0x13, 0x15, 0x89, 0x61, 0x64,
+ 0x04, 0x71, 0x63, 0x97, 0x39, 0x35, 0x7a, 0x37, 0x20, 0x44, 0x2d, 0x3d,
+ 0x3e, 0x34, 0x14, 0x17, 0xc1, 0x5c, 0x5c, 0x41, 0x5d, 0xec, 0x53, 0x62,
+ 0x4e, 0x1e, 0x24, 0x92, 0x62, 0x64, 0x75, 0x68, 0xba, 0x01, 0xf2, 0xfc,
+ 0x41, 0x69, 0x13, 0x14, 0x7e, 0x67, 0xe0, 0x47, 0x42, 0x20, 0x26, 0x48,
+ 0x2f, 0x22, 0x00, 0x02, 0x00, 0x3d, 0x04, 0xe5, 0x02, 0x5e, 0x05, 0xb8,
+ 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x21, 0x15,
+ 0x23, 0x35, 0x01, 0x12, 0xd5, 0x02, 0x21, 0xd5, 0x05, 0xb8, 0xd3, 0xd3,
+ 0xd3, 0xd3, 0x00, 0x03, 0xff, 0xe5, 0xff, 0xd3, 0x06, 0x02, 0x05, 0xf0,
+ 0x00, 0x21, 0x00, 0x39, 0x00, 0x51, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06,
+ 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16,
+ 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17,
+ 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x03, 0x20, 0x17, 0x16, 0x17, 0x16,
+ 0x15, 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26,
+ 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, 0x07, 0x06,
+ 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36,
+ 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x04, 0x6a, 0x1c, 0x28, 0x5e, 0xc8,
+ 0xaf, 0x6f, 0x6f, 0x79, 0x6e, 0xac, 0xd7, 0x56, 0x18, 0x0f, 0x91, 0x24,
+ 0x4d, 0x24, 0x34, 0x84, 0x46, 0x36, 0x51, 0x46, 0x69, 0x96, 0x35, 0x08,
+ 0x06, 0xe5, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2c, 0x9f, 0x92, 0xe8, 0x7b,
+ 0x85, 0xf8, 0xcd, 0xbc, 0x52, 0x31, 0x9c, 0x8e, 0xe0, 0x7e, 0x87, 0xde,
+ 0xaf, 0xa4, 0x39, 0x19, 0x88, 0x7e, 0xc0, 0x58, 0x5d, 0xe7, 0xb1, 0xa6,
+ 0x37, 0x16, 0x8b, 0x80, 0xc5, 0x58, 0x02, 0x7f, 0x8a, 0x49, 0xaa, 0x83,
+ 0x84, 0xd2, 0xe2, 0x86, 0x79, 0xc4, 0x35, 0x44, 0x89, 0x24, 0x11, 0x78,
+ 0x5c, 0x8c, 0xa2, 0x64, 0x56, 0xbc, 0x1f, 0x23, 0x03, 0x71, 0x9c, 0x8e,
+ 0xdf, 0x7e, 0x86, 0xfe, 0xf6, 0xd1, 0xc0, 0x4c, 0x29, 0x99, 0x8c, 0xdb,
+ 0x83, 0x8b, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2d, 0x7f, 0x8d, 0x83, 0xcb,
+ 0x58, 0x5d, 0xdf, 0xb3, 0xa5, 0x3c, 0x1c, 0x8f, 0x86, 0xcf, 0x54, 0x59,
+ 0xe2, 0xb2, 0xa6, 0x3a, 0x1a, 0x00, 0x00, 0x03, 0x00, 0x4c, 0x02, 0x6d,
+ 0x02, 0xaa, 0x05, 0xf0, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x3c, 0x00, 0x00,
+ 0x01, 0x15, 0x21, 0x35, 0x25, 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27,
+ 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37,
+ 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x23,
+ 0x36, 0x37, 0x36, 0x33, 0x32, 0x15, 0x11, 0x14, 0x33, 0x32, 0x27, 0x06,
+ 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36,
+ 0x35, 0x02, 0x8f, 0xfd, 0xc9, 0x02, 0x52, 0x20, 0x22, 0x50, 0x17, 0x06,
+ 0x03, 0x65, 0x72, 0x81, 0x37, 0x1d, 0x4b, 0x4a, 0xac, 0x4f, 0x10, 0x06,
+ 0x54, 0x18, 0x1e, 0x53, 0x1d, 0x12, 0x09, 0x79, 0x05, 0xab, 0x29, 0x30,
+ 0xf9, 0x30, 0x09, 0xad, 0x25, 0x6a, 0x63, 0x20, 0x1d, 0x4e, 0x11, 0x15,
+ 0x5b, 0x39, 0x27, 0x02, 0xd5, 0x68, 0x68, 0xc3, 0x5b, 0x0c, 0x38, 0x0e,
+ 0x12, 0x58, 0x57, 0x2f, 0x3f, 0x6b, 0x30, 0x2f, 0x0d, 0x06, 0x1d, 0x0c,
+ 0x14, 0x1b, 0x44, 0x11, 0x05, 0x27, 0x19, 0x33, 0xb2, 0x24, 0x08, 0xc1,
+ 0xfe, 0x92, 0x30, 0xfa, 0x10, 0x0f, 0x0e, 0x1b, 0x1a, 0x2d, 0x4c, 0x10,
+ 0x04, 0x36, 0x25, 0x2c, 0x00, 0x02, 0x00, 0xc9, 0x00, 0xd9, 0x03, 0xa4,
+ 0x03, 0x81, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x35, 0x25, 0x15,
+ 0x07, 0x17, 0x15, 0x37, 0x35, 0x25, 0x15, 0x07, 0x17, 0x15, 0xc9, 0x01,
+ 0x37, 0xd9, 0xd9, 0x6d, 0x01, 0x37, 0xd9, 0xd9, 0x01, 0xd1, 0xb6, 0xfa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xf8, 0xb6, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00,
+ 0x00, 0x01, 0x00, 0x52, 0x00, 0xb0, 0x04, 0x5a, 0x03, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x13, 0x21, 0x11, 0x23, 0x11, 0x21, 0x52, 0x04, 0x08, 0x8f,
+ 0xfc, 0x87, 0x03, 0x00, 0xfd, 0xb0, 0x01, 0xc1, 0x00, 0x01, 0x00, 0x5e,
+ 0x01, 0xec, 0x02, 0x46, 0x02, 0x7f, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15,
+ 0x21, 0x35, 0x02, 0x46, 0xfe, 0x18, 0x02, 0x7f, 0x93, 0x93, 0x00, 0x04,
+ 0xff, 0xe5, 0xff, 0xd3, 0x06, 0x02, 0x05, 0xf0, 0x00, 0x1a, 0x00, 0x25,
+ 0x00, 0x3d, 0x00, 0x55, 0x00, 0x00, 0x01, 0x16, 0x1f, 0x01, 0x16, 0x17,
+ 0x15, 0x23, 0x26, 0x3f, 0x01, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x23,
+ 0x11, 0x21, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x25, 0x21, 0x32,
+ 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x21, 0x13, 0x20, 0x17, 0x16,
+ 0x17, 0x16, 0x15, 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26,
+ 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06,
+ 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36,
+ 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x03, 0xf6, 0x55, 0x07,
+ 0x01, 0x05, 0x29, 0xa2, 0x22, 0x04, 0x02, 0x45, 0x1a, 0x25, 0xfe, 0xee,
+ 0x8f, 0x01, 0xa6, 0x01, 0x07, 0x17, 0x02, 0x2b, 0x17, 0xfe, 0x0b, 0x01,
+ 0x08, 0x7f, 0x16, 0x05, 0x4d, 0x1f, 0x2e, 0xfe, 0xf8, 0xc7, 0x01, 0x04,
+ 0xd0, 0xbf, 0x4f, 0x2c, 0x9f, 0x92, 0xe8, 0x7b, 0x85, 0xf8, 0xcd, 0xbc,
+ 0x52, 0x31, 0x9c, 0x8e, 0xe0, 0x7e, 0x87, 0xde, 0xaf, 0xa4, 0x39, 0x19,
+ 0x88, 0x7e, 0xc0, 0x58, 0x5d, 0xe7, 0xb1, 0xa6, 0x37, 0x16, 0x8b, 0x80,
+ 0xc5, 0x58, 0x02, 0xe1, 0x37, 0x6c, 0x8d, 0x41, 0x1e, 0x33, 0x51, 0x4c,
+ 0x52, 0x6b, 0x18, 0x09, 0xfe, 0x85, 0x03, 0x8f, 0xd5, 0x15, 0x18, 0x5a,
+ 0x35, 0x1c, 0x1a, 0x59, 0x15, 0x1b, 0x66, 0x19, 0x0a, 0x01, 0xc3, 0x9c,
+ 0x8e, 0xdf, 0x7e, 0x86, 0xfe, 0xf6, 0xd1, 0xc0, 0x4c, 0x29, 0x99, 0x8c,
+ 0xdb, 0x83, 0x8b, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2d, 0x7f, 0x8d, 0x83,
+ 0xcb, 0x58, 0x5d, 0xdf, 0xb3, 0xa5, 0x3c, 0x1c, 0x8f, 0x86, 0xcf, 0x54,
+ 0x59, 0xe2, 0xb2, 0xa6, 0x3a, 0x1a, 0x00, 0x01, 0x00, 0x39, 0x05, 0x0c,
+ 0x02, 0x6a, 0x05, 0x9c, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35,
+ 0x02, 0x6a, 0xfd, 0xcf, 0x05, 0x9c, 0x90, 0x90, 0x00, 0x02, 0x01, 0x35,
+ 0x03, 0x10, 0x03, 0xa2, 0x05, 0x7d, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x00,
+ 0x01, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26,
+ 0x27, 0x34, 0x36, 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33,
+ 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x02, 0x6d, 0x80, 0x5b, 0x5a,
+ 0x5e, 0x5b, 0x81, 0x7c, 0x5a, 0x5b, 0x02, 0xb7, 0x81, 0x59, 0x3c, 0x2e,
+ 0x44, 0x36, 0x44, 0x5f, 0x3a, 0x2c, 0x45, 0x35, 0x05, 0x7d, 0x5b, 0x5b,
+ 0x7f, 0x84, 0x5b, 0x59, 0x5a, 0x60, 0x7e, 0x80, 0xb5, 0x75, 0x45, 0x36,
+ 0x45, 0x59, 0x3c, 0x2e, 0x47, 0x35, 0x47, 0x5a, 0x39, 0x2d, 0x00, 0x02,
+ 0x00, 0x66, 0xff, 0xe9, 0x04, 0x46, 0x04, 0xfc, 0x00, 0x0b, 0x00, 0x0f,
+ 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11,
+ 0x33, 0x11, 0x01, 0x15, 0x21, 0x35, 0x04, 0x46, 0xfe, 0x58, 0x90, 0xfe,
+ 0x58, 0x01, 0xa8, 0x90, 0x01, 0xa8, 0xfc, 0x20, 0x03, 0x54, 0x8f, 0xfe,
+ 0x58, 0x01, 0xa8, 0x8f, 0x01, 0xa8, 0xfe, 0x58, 0xfd, 0x25, 0x90, 0x90,
+ 0x00, 0x01, 0x00, 0x27, 0x02, 0x46, 0x02, 0x9c, 0x05, 0xac, 0x00, 0x25,
+ 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x07, 0x23, 0x36, 0x37, 0x36, 0x33,
+ 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06,
+ 0x07, 0x21, 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x36,
+ 0x35, 0x34, 0x27, 0x26, 0x01, 0x6d, 0x8b, 0x1e, 0x07, 0x03, 0x7f, 0x08,
+ 0xc6, 0x2e, 0x3a, 0x96, 0x55, 0x40, 0xaa, 0x0d, 0x0e, 0x81, 0x59, 0x21,
+ 0x10, 0x0b, 0x01, 0xd5, 0xfd, 0x91, 0x08, 0x35, 0x34, 0x8f, 0x02, 0x02,
+ 0x77, 0x79, 0x43, 0x2f, 0x05, 0x3f, 0x85, 0x1c, 0x29, 0xfe, 0x2e, 0x0b,
+ 0x5b, 0x44, 0x63, 0x9b, 0x5f, 0x07, 0x07, 0x42, 0x2f, 0x36, 0x1a, 0x25,
+ 0x76, 0x96, 0x4e, 0x4c, 0x4d, 0x01, 0x01, 0x3f, 0x41, 0x61, 0x4e, 0x2d,
+ 0x1e, 0x00, 0x00, 0x01, 0x00, 0x21, 0x02, 0x29, 0x02, 0x93, 0x05, 0xac,
+ 0x00, 0x30, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x12, 0x37,
+ 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x15, 0x14, 0x07,
+ 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32,
+ 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x35, 0x32, 0x37,
+ 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0x5a, 0x7e, 0x1d, 0x0b, 0x81, 0x06,
+ 0xf4, 0x16, 0x17, 0xa7, 0x4a, 0x2c, 0x75, 0x91, 0x6d, 0x53, 0x7d, 0xc8,
+ 0x49, 0x24, 0x7f, 0x07, 0x61, 0x22, 0x30, 0x7d, 0x2a, 0x11, 0x3f, 0x18,
+ 0x1f, 0x1f, 0x69, 0x99, 0x2b, 0x1e, 0x4d, 0x22, 0x05, 0x3f, 0x5d, 0x23,
+ 0x36, 0x01, 0x0b, 0x16, 0x02, 0x65, 0x3c, 0x55, 0x78, 0x36, 0x31, 0x9c,
+ 0x8d, 0x4b, 0x3a, 0x87, 0x41, 0x5b, 0x8b, 0x20, 0x0b, 0x56, 0x22, 0x2d,
+ 0x51, 0x29, 0x10, 0x06, 0x04, 0x68, 0x26, 0x1b, 0x3c, 0x5a, 0x22, 0x0f,
+ 0x00, 0x01, 0x00, 0xbc, 0x04, 0xbc, 0x02, 0x68, 0x05, 0xec, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x33, 0x01, 0x23, 0x01, 0x81, 0xe7, 0xfe, 0xcf, 0x7b,
+ 0x05, 0xec, 0xfe, 0xd0, 0x00, 0x01, 0x00, 0x85, 0xfe, 0x3d, 0x04, 0x5a,
+ 0x04, 0x31, 0x00, 0x20, 0x00, 0x00, 0x25, 0x15, 0x06, 0x23, 0x22, 0x27,
+ 0x26, 0x27, 0x06, 0x23, 0x22, 0x27, 0x11, 0x23, 0x11, 0x33, 0x11, 0x14,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17,
+ 0x16, 0x33, 0x32, 0x04, 0x5a, 0x44, 0x31, 0x8f, 0x1a, 0x06, 0x01, 0x78,
+ 0xd6, 0x6f, 0x49, 0xaa, 0xaa, 0x5a, 0x36, 0x4b, 0x93, 0x50, 0x42, 0xaa,
+ 0x4f, 0x06, 0x07, 0x11, 0x64, 0x81, 0x12, 0x74, 0x18, 0x1e, 0xaa, 0x35,
+ 0xfe, 0x37, 0x05, 0xf4, 0xfd, 0x08, 0x79, 0x39, 0x21, 0x76, 0x61, 0x94,
+ 0x02, 0x60, 0xfc, 0x83, 0x4d, 0x06, 0x01, 0x00, 0x00, 0x01, 0x00, 0x62,
+ 0xfe, 0x96, 0x04, 0x2d, 0x05, 0xd5, 0x00, 0x13, 0x00, 0x00, 0x01, 0x26,
+ 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x21, 0x15, 0x23,
+ 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x02, 0x0a, 0xd1, 0x75, 0x62, 0x75,
+ 0x6f, 0xa8, 0x1f, 0x20, 0x02, 0x00, 0x75, 0x83, 0xa8, 0x83, 0x02, 0x12,
+ 0x0b, 0x98, 0x7f, 0xb5, 0xc1, 0x8b, 0x84, 0x18, 0x04, 0x83, 0xf9, 0x44,
+ 0x06, 0xbc, 0xf9, 0x44, 0x00, 0x01, 0x00, 0xb2, 0x02, 0x6a, 0x01, 0xb0,
+ 0x03, 0x6a, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0xb0,
+ 0xfe, 0x03, 0x6a, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50,
+ 0xfe, 0x4a, 0x02, 0x4c, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x17,
+ 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07,
+ 0x27, 0x37, 0x33, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07,
+ 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x7b, 0x6e, 0x2e, 0x2d, 0x43, 0x1e,
+ 0x0d, 0x3c, 0x0f, 0x13, 0x1f, 0x21, 0x18, 0x56, 0x4e, 0x2f, 0x1a, 0x1f,
+ 0x7a, 0x1f, 0x09, 0x67, 0x3d, 0x58, 0x50, 0x58, 0x22, 0x36, 0xfe, 0xe1,
+ 0x32, 0x11, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11, 0x0f, 0xbc, 0x73,
+ 0x04, 0x54, 0x18, 0x1d, 0x6f, 0x31, 0x1e, 0x21, 0x0d, 0x17, 0x00, 0x01,
+ 0x00, 0x7d, 0x02, 0x46, 0x01, 0xc7, 0x05, 0xac, 0x00, 0x0b, 0x00, 0x00,
+ 0x01, 0x23, 0x35, 0x37, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23,
+ 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03, 0x02, 0x58, 0x7f, 0x04,
+ 0xa4, 0x5e, 0x02, 0x0a, 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x00, 0x03,
+ 0x00, 0x52, 0x02, 0x6d, 0x02, 0x98, 0x05, 0xf0, 0x00, 0x03, 0x00, 0x13,
+ 0x00, 0x23, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x01, 0x32, 0x17, 0x16,
+ 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36,
+ 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36,
+ 0x35, 0x34, 0x27, 0x26, 0x02, 0x83, 0xfd, 0xe5, 0x01, 0x0d, 0xbb, 0x45,
+ 0x23, 0x79, 0x46, 0x64, 0xb1, 0x49, 0x29, 0x82, 0x43, 0x5e, 0x68, 0x2c,
+ 0x18, 0x56, 0x25, 0x31, 0x65, 0x2d, 0x1a, 0x5b, 0x23, 0x02, 0xd5, 0x68,
+ 0x68, 0x03, 0x1b, 0xa1, 0x51, 0x73, 0xcf, 0x58, 0x33, 0x92, 0x54, 0x7a,
+ 0xde, 0x55, 0x2c, 0x6b, 0x68, 0x3a, 0x52, 0xa2, 0x3a, 0x19, 0x64, 0x3a,
+ 0x53, 0xaa, 0x38, 0x16, 0x00, 0x02, 0x00, 0xc9, 0x00, 0xd9, 0x03, 0x9c,
+ 0x03, 0x81, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x15, 0x05, 0x35,
+ 0x37, 0x27, 0x35, 0x05, 0x15, 0x05, 0x35, 0x37, 0x27, 0x35, 0x02, 0x04,
+ 0xfe, 0xc5, 0xdd, 0xdd, 0x02, 0xd3, 0xfe, 0xc4, 0xdd, 0xdd, 0x02, 0x89,
+ 0xb6, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0xf8, 0xb6, 0xfa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x00, 0x00, 0x04, 0x00, 0x7d, 0xff, 0xd7, 0x06, 0xcb, 0x05, 0xac,
+ 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x23,
+ 0x35, 0x37, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x01, 0x33,
+ 0x01, 0x23, 0x25, 0x21, 0x35, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15,
+ 0x23, 0x19, 0x01, 0x01, 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03,
+ 0x02, 0x58, 0x7f, 0x03, 0xdd, 0x77, 0xfc, 0x62, 0x77, 0x04, 0x3c, 0xfe,
+ 0x7f, 0x01, 0xa1, 0x5f, 0x89, 0x89, 0x7f, 0xfe, 0xf7, 0x04, 0xa4, 0x5e,
+ 0x02, 0x0a, 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x03, 0x66, 0xfa, 0x2b,
+ 0xf6, 0x79, 0x02, 0x20, 0xfd, 0xd3, 0x6c, 0xcd, 0x01, 0x39, 0x01, 0x5d,
+ 0xfe, 0xa3, 0x00, 0x03, 0x00, 0x7d, 0xff, 0xd7, 0x06, 0xc1, 0x05, 0xac,
+ 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x35, 0x00, 0x00, 0x01, 0x23, 0x35, 0x37,
+ 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x01, 0x33, 0x01, 0x23,
+ 0x01, 0x22, 0x07, 0x06, 0x07, 0x23, 0x12, 0x37, 0x36, 0x33, 0x32, 0x17,
+ 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x21,
+ 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x35, 0x34,
+ 0x27, 0x26, 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03, 0x02, 0x58,
+ 0x7f, 0x03, 0xac, 0x76, 0xfc, 0x63, 0x77, 0x04, 0x3b, 0x8f, 0x1c, 0x05,
+ 0x02, 0x7f, 0x07, 0xd3, 0x2a, 0x32, 0x96, 0x55, 0x40, 0xaa, 0x0d, 0x0e,
+ 0x81, 0x59, 0x21, 0x10, 0x0c, 0x01, 0xd5, 0xfd, 0x92, 0x08, 0x35, 0x34,
+ 0x8d, 0x03, 0x03, 0x77, 0x78, 0x43, 0x2e, 0x04, 0xa4, 0x5e, 0x02, 0x0a,
+ 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x03, 0x66, 0xfa, 0x2b, 0x03, 0x23,
+ 0x8e, 0x1a, 0x23, 0x01, 0x06, 0x29, 0x08, 0x5b, 0x44, 0x63, 0x9a, 0x60,
+ 0x07, 0x07, 0x41, 0x2f, 0x36, 0x1a, 0x25, 0x77, 0x97, 0x4d, 0x4d, 0x4b,
+ 0x01, 0x02, 0x3f, 0x40, 0x62, 0x4e, 0x2d, 0x1f, 0x00, 0x04, 0x00, 0x21,
+ 0xff, 0xd7, 0x06, 0xcb, 0x05, 0xac, 0x00, 0x30, 0x00, 0x34, 0x00, 0x3f,
+ 0x00, 0x42, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x12, 0x37,
+ 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x15, 0x14, 0x07,
+ 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32,
+ 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x35, 0x32, 0x37,
+ 0x36, 0x35, 0x34, 0x27, 0x26, 0x25, 0x33, 0x01, 0x23, 0x25, 0x21, 0x35,
+ 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, 0x23, 0x19, 0x01, 0x01, 0x01,
+ 0x5a, 0x7e, 0x1d, 0x0b, 0x81, 0x06, 0xf4, 0x16, 0x17, 0xa7, 0x4a, 0x2c,
+ 0x75, 0x91, 0x6d, 0x53, 0x7d, 0xc8, 0x49, 0x24, 0x7f, 0x07, 0x61, 0x22,
+ 0x30, 0x7d, 0x2a, 0x11, 0x3f, 0x18, 0x1f, 0x1f, 0x69, 0x99, 0x2b, 0x1e,
+ 0x4d, 0x22, 0x03, 0xb2, 0x77, 0xfc, 0x62, 0x76, 0x04, 0x27, 0xfe, 0x7f,
+ 0x01, 0xa1, 0x5f, 0x89, 0x89, 0x7f, 0xfe, 0xf7, 0x05, 0x3f, 0x5d, 0x23,
+ 0x36, 0x01, 0x0b, 0x16, 0x02, 0x65, 0x3c, 0x55, 0x78, 0x36, 0x31, 0x9c,
+ 0x8d, 0x4b, 0x3a, 0x87, 0x41, 0x5b, 0x8b, 0x20, 0x0b, 0x56, 0x22, 0x2d,
+ 0x51, 0x29, 0x10, 0x06, 0x04, 0x68, 0x26, 0x1b, 0x3c, 0x5a, 0x22, 0x0f,
+ 0x6d, 0xfa, 0x2b, 0xf6, 0x79, 0x02, 0x20, 0xfd, 0xd3, 0x6c, 0xcd, 0x01,
+ 0x39, 0x01, 0x5d, 0xfe, 0xa3, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x43,
+ 0x04, 0x39, 0x04, 0x31, 0x10, 0x0f, 0x00, 0x23, 0x04, 0xd7, 0x04, 0x31,
+ 0xc0, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5,
+ 0x10, 0x27, 0x00, 0xc6, 0x01, 0x58, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5,
+ 0x10, 0x27, 0x00, 0xc5, 0x01, 0x75, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5,
+ 0x10, 0x27, 0x00, 0xc4, 0x01, 0x60, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5,
+ 0x10, 0x27, 0x00, 0xc8, 0x01, 0x66, 0x01, 0x81, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x07, 0x3b,
+ 0x10, 0x27, 0x00, 0x6b, 0x01, 0x64, 0x01, 0x83, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5,
+ 0x10, 0x27, 0x00, 0xc7, 0x01, 0x58, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x00, 0x00, 0x07, 0x9a, 0x05, 0xd5,
+ 0x00, 0x0f, 0x00, 0x13, 0x00, 0x00, 0x01, 0x21, 0x03, 0x23, 0x01, 0x21,
+ 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x19, 0x01,
+ 0x23, 0x01, 0x03, 0xbe, 0xfd, 0xda, 0xaf, 0xd2, 0x02, 0x64, 0x04, 0xfa,
+ 0xfd, 0x08, 0x02, 0xd1, 0xfd, 0x2f, 0x03, 0x1d, 0xfc, 0x24, 0xcc, 0xfe,
+ 0xe5, 0x01, 0xb6, 0xfe, 0x4a, 0x05, 0xd5, 0xa8, 0xfe, 0x23, 0xa8, 0xfe,
+ 0x00, 0xa8, 0x02, 0x5e, 0x02, 0xcf, 0xfd, 0x31, 0x00, 0x01, 0x00, 0x62,
+ 0xfe, 0x4a, 0x05, 0x6a, 0x05, 0xee, 0x00, 0x46, 0x00, 0x00, 0x25, 0x32,
+ 0x37, 0x36, 0x37, 0x33, 0x02, 0x05, 0x06, 0x23, 0x07, 0x36, 0x33, 0x32,
+ 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x37,
+ 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22,
+ 0x07, 0x27, 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34,
+ 0x37, 0x12, 0x25, 0x36, 0x33, 0x20, 0x13, 0x16, 0x17, 0x23, 0x26, 0x27,
+ 0x26, 0x23, 0x22, 0x07, 0x06, 0x11, 0x10, 0x17, 0x16, 0x03, 0x06, 0xdf,
+ 0x66, 0x3f, 0x1c, 0xc4, 0x3f, 0xfe, 0x31, 0x29, 0x2b, 0x1a, 0x1a, 0x1f,
+ 0x7a, 0x1f, 0x09, 0x65, 0x3e, 0x59, 0x53, 0x5d, 0x21, 0x2f, 0x2b, 0x68,
+ 0x32, 0x2f, 0x43, 0x1e, 0x0d, 0x3c, 0x0f, 0x13, 0x1f, 0x21, 0x16, 0x3f,
+ 0x9a, 0x4f, 0x21, 0x27, 0xb7, 0x49, 0x27, 0x65, 0x92, 0x01, 0x3a, 0x3a,
+ 0x3f, 0x01, 0xa2, 0x7c, 0x15, 0x0d, 0xc3, 0x2d, 0xa3, 0x50, 0x71, 0xe0,
+ 0x7e, 0x79, 0x91, 0x82, 0x77, 0x9d, 0x61, 0xac, 0xfd, 0xe0, 0x2c, 0x04,
+ 0x44, 0x04, 0x54, 0x18, 0x1d, 0x6d, 0x32, 0x1f, 0x24, 0x0c, 0x15, 0x52,
+ 0x30, 0x13, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11, 0x0f, 0x8d, 0x16,
+ 0x28, 0x11, 0x1b, 0x84, 0xfc, 0x86, 0x98, 0xfc, 0xc5, 0x01, 0x1d, 0x2e,
+ 0x09, 0xfe, 0x9b, 0x3c, 0x47, 0xdd, 0x42, 0x21, 0xae, 0xa5, 0xfe, 0xe8,
+ 0xfe, 0xd6, 0xa6, 0x94, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0x01, 0x7b, 0x01, 0x98, 0x10, 0x06,
+ 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x6d, 0x01, 0x98, 0x10, 0x06,
+ 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0x01, 0x73, 0x01, 0x96, 0x10, 0x06,
+ 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7,
+ 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0x01, 0x71, 0x01, 0x83, 0x10, 0x06,
+ 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0xff, 0xd3, 0x01, 0x98, 0x10, 0x06,
+ 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0xff, 0xd5, 0x01, 0x98, 0x10, 0x06,
+ 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d,
+ 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0xff, 0xd5, 0x01, 0x98, 0x10, 0x06,
+ 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1c, 0x00, 0x00, 0x02, 0x3d,
+ 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0xff, 0xdf, 0x01, 0x83, 0x10, 0x06,
+ 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x05, 0x56,
+ 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x1d, 0x00, 0x00, 0x13, 0x23, 0x35, 0x33,
+ 0x11, 0x21, 0x20, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x29, 0x01, 0x13,
+ 0x11, 0x21, 0x20, 0x13, 0x36, 0x35, 0x10, 0x27, 0x26, 0x23, 0x21, 0x11,
+ 0x21, 0x15, 0xb6, 0x8d, 0x8d, 0x02, 0x42, 0x01, 0x19, 0xa2, 0xa3, 0xb0,
+ 0xa1, 0xfe, 0xf3, 0xfd, 0xbe, 0xbf, 0x01, 0x62, 0x01, 0x37, 0x61, 0x29,
+ 0xf2, 0x58, 0x77, 0xfe, 0x9e, 0x01, 0x5e, 0x02, 0xb6, 0x89, 0x02, 0x96,
+ 0xc6, 0xc7, 0xfe, 0xa4, 0xfe, 0x93, 0xc9, 0xb6, 0x02, 0xb6, 0xfd, 0xf2,
+ 0x01, 0x20, 0x7a, 0xaa, 0x01, 0xa0, 0x76, 0x2b, 0xfe, 0x12, 0x89, 0x00,
+ 0xff, 0xff, 0x00, 0x9c, 0x00, 0x00, 0x05, 0x2b, 0x05, 0xd5, 0x10, 0x27,
+ 0x00, 0xc8, 0x01, 0x98, 0x01, 0x81, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27,
+ 0x00, 0xc6, 0x01, 0xcb, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27,
+ 0x00, 0xc5, 0x01, 0xd5, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27,
+ 0x00, 0xc4, 0x01, 0xd1, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27,
+ 0x00, 0xc8, 0x01, 0xd1, 0x01, 0x81, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x07, 0x3b, 0x10, 0x27,
+ 0x00, 0x6b, 0x01, 0xcf, 0x01, 0x83, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0xc3, 0x00, 0x46, 0x03, 0xe7, 0x03, 0x6a, 0x00, 0x0b,
+ 0x00, 0x00, 0x01, 0x17, 0x09, 0x01, 0x07, 0x09, 0x01, 0x27, 0x09, 0x01,
+ 0x37, 0x01, 0x03, 0x81, 0x64, 0xfe, 0xd5, 0x01, 0x2d, 0x66, 0xfe, 0xd3,
+ 0xfe, 0xd5, 0x66, 0x01, 0x2d, 0xfe, 0xd5, 0x64, 0x01, 0x2b, 0x03, 0x6a,
+ 0x66, 0xfe, 0xd5, 0xfe, 0xd3, 0x66, 0x01, 0x2d, 0xfe, 0xd5, 0x64, 0x01,
+ 0x2d, 0x01, 0x2b, 0x64, 0xfe, 0xd7, 0x00, 0x03, 0x00, 0x3d, 0xff, 0xd1,
+ 0x05, 0xf4, 0x06, 0x0a, 0x00, 0x1b, 0x00, 0x26, 0x00, 0x31, 0x00, 0x00,
+ 0x3f, 0x01, 0x26, 0x11, 0x10, 0x37, 0x36, 0x25, 0x36, 0x33, 0x20, 0x17,
+ 0x37, 0x17, 0x07, 0x16, 0x13, 0x16, 0x15, 0x10, 0x07, 0x06, 0x05, 0x06,
+ 0x23, 0x20, 0x27, 0x07, 0x13, 0x01, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03,
+ 0x06, 0x15, 0x14, 0x09, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x13, 0x36,
+ 0x35, 0x34, 0x3d, 0xa6, 0x9b, 0xa8, 0x9e, 0x01, 0x05, 0x41, 0x45, 0x01,
+ 0x17, 0xc0, 0xb2, 0x52, 0xb7, 0x92, 0x16, 0x04, 0xa8, 0x9e, 0xfe, 0xfb,
+ 0x40, 0x45, 0xfe, 0xd9, 0xc7, 0x9e, 0xd7, 0x03, 0x13, 0x97, 0xc7, 0xe4,
+ 0x90, 0x94, 0x0a, 0x01, 0x03, 0xb8, 0xfc, 0xe8, 0x97, 0xdc, 0xe2, 0x91,
+ 0x93, 0x0b, 0x01, 0x27, 0xb6, 0xdb, 0x01, 0x29, 0x01, 0x3e, 0xd2, 0xc7,
+ 0x2b, 0x0b, 0xa6, 0xc2, 0x49, 0xc7, 0xb7, 0xfe, 0xf1, 0x2b, 0x2c, 0xfe,
+ 0xc2, 0xd2, 0xc6, 0x2b, 0x0b, 0xb8, 0xac, 0x01, 0x8b, 0x03, 0x5b, 0x83,
+ 0x9b, 0x9e, 0xfe, 0xf8, 0x12, 0x12, 0xd4, 0x02, 0x62, 0xfc, 0xa1, 0x97,
+ 0x9a, 0x9e, 0x01, 0x06, 0x13, 0x13, 0xea, 0x00, 0xff, 0xff, 0x00, 0xae,
+ 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0x01, 0x98,
+ 0x01, 0x98, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae,
+ 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x98,
+ 0x01, 0x98, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae,
+ 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0x01, 0x9e,
+ 0x01, 0x96, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae,
+ 0xff, 0xd1, 0x05, 0x29, 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0x01, 0x9e,
+ 0x01, 0x83, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1b,
+ 0x00, 0x00, 0x05, 0x4a, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x6a,
+ 0x01, 0x98, 0x10, 0x06, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x02, 0x00, 0xba,
+ 0x00, 0x00, 0x04, 0xee, 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x00,
+ 0x01, 0x11, 0x23, 0x11, 0x33, 0x15, 0x21, 0x32, 0x17, 0x16, 0x15, 0x14,
+ 0x07, 0x06, 0x23, 0x25, 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26,
+ 0x23, 0x21, 0x01, 0x79, 0xbf, 0xbf, 0x01, 0xaa, 0xf0, 0x7b, 0x60, 0x77,
+ 0x74, 0xb5, 0xfe, 0x2b, 0x01, 0x8d, 0xae, 0x47, 0x26, 0x77, 0x43, 0x61,
+ 0xfe, 0x73, 0x01, 0x83, 0xfe, 0x7d, 0x05, 0xd5, 0xf6, 0x90, 0x71, 0xb1,
+ 0xbd, 0x78, 0x75, 0xa8, 0x72, 0x3e, 0x56, 0x9e, 0x43, 0x25, 0x00, 0x01,
+ 0x00, 0x89, 0xff, 0xe1, 0x04, 0x91, 0x05, 0xd3, 0x00, 0x31, 0x00, 0x00,
+ 0x01, 0x20, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06,
+ 0x15, 0x11, 0x23, 0x11, 0x34, 0x37, 0x36, 0x33, 0x20, 0x17, 0x16, 0x15,
+ 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15, 0x10, 0x07, 0x06, 0x23,
+ 0x22, 0x27, 0x35, 0x16, 0x33, 0x20, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26,
+ 0x2b, 0x01, 0x02, 0x5a, 0x01, 0x0e, 0x29, 0x07, 0x71, 0x4e, 0x79, 0xd1,
+ 0x39, 0x19, 0xb4, 0x8b, 0x7d, 0xd1, 0x01, 0x00, 0x85, 0x65, 0x97, 0x03,
+ 0x0e, 0x71, 0x46, 0x36, 0xdf, 0x79, 0xac, 0x31, 0x3b, 0x2d, 0x2d, 0x01,
+ 0x23, 0x30, 0x09, 0xec, 0x32, 0x3e, 0x21, 0x03, 0x6a, 0xac, 0x1c, 0x20,
+ 0x7e, 0x3d, 0x2a, 0x87, 0x3c, 0x60, 0xfb, 0xec, 0x04, 0x42, 0xc2, 0x6d,
+ 0x62, 0x7e, 0x60, 0x93, 0xbe, 0x66, 0x02, 0x09, 0x1f, 0x7a, 0x5e, 0x5d,
+ 0xfe, 0xbf, 0x7b, 0x42, 0x0f, 0x99, 0x06, 0xda, 0x29, 0x30, 0xef, 0x27,
+ 0x09, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc6, 0x00, 0xec, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc5, 0x00, 0xec, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc4, 0x00, 0xe5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc8, 0x00, 0xe7, 0xff, 0xe3, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x05, 0x9d,
+ 0x10, 0x27, 0x00, 0x6b, 0x00, 0xe5, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc7, 0x00, 0xdd, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x46, 0xff, 0xd1, 0x06, 0xc3, 0x04, 0x50,
+ 0x00, 0x3c, 0x00, 0x4d, 0x00, 0x56, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16,
+ 0x33, 0x32, 0x37, 0x33, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x2f,
+ 0x01, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36,
+ 0x25, 0x36, 0x33, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23,
+ 0x22, 0x07, 0x06, 0x07, 0x23, 0x12, 0x25, 0x36, 0x33, 0x20, 0x17, 0x36,
+ 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x01, 0x32, 0x37,
+ 0x36, 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14,
+ 0x17, 0x16, 0x01, 0x21, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03,
+ 0xac, 0x05, 0xa7, 0x41, 0x4e, 0xd1, 0x4a, 0xac, 0x26, 0x9f, 0x6e, 0x96,
+ 0xb7, 0x77, 0x24, 0x1a, 0x21, 0xa2, 0x97, 0x3d, 0x44, 0xb3, 0x5e, 0x47,
+ 0x98, 0x70, 0x01, 0x02, 0x05, 0x05, 0x7e, 0x20, 0x14, 0xa4, 0x23, 0x2a,
+ 0xb7, 0x31, 0x0d, 0x05, 0xac, 0x0a, 0x01, 0x20, 0x3a, 0x46, 0x01, 0x07,
+ 0x5f, 0x51, 0x96, 0x3c, 0x3f, 0xc0, 0x83, 0x48, 0x26, 0x2b, 0xfb, 0x02,
+ 0x9e, 0x6a, 0x36, 0x08, 0x01, 0x43, 0x9f, 0x94, 0x37, 0x67, 0x5b, 0x30,
+ 0x02, 0x2d, 0x02, 0x5a, 0x63, 0x4f, 0x75, 0x93, 0x56, 0x41, 0x01, 0xdf,
+ 0xfe, 0x52, 0x20, 0xd7, 0xcf, 0x62, 0x44, 0x65, 0x1f, 0x26, 0x37, 0xa8,
+ 0x29, 0x10, 0x6e, 0x53, 0x7c, 0xbc, 0x50, 0x3b, 0x17, 0x01, 0x0b, 0x27,
+ 0x18, 0x2e, 0x2d, 0x82, 0x19, 0x05, 0x73, 0x20, 0x2b, 0x01, 0x1e, 0x34,
+ 0x0a, 0xa8, 0x72, 0x27, 0x0f, 0x79, 0x44, 0x5e, 0x73, 0xe3, 0xfe, 0x87,
+ 0x6f, 0x38, 0x2d, 0x05, 0x03, 0xce, 0x1d, 0x17, 0x16, 0x18, 0x2e, 0x6e,
+ 0x69, 0x2c, 0x17, 0x02, 0x04, 0xa2, 0x5c, 0x4a, 0x72, 0x55, 0x00, 0x01,
+ 0x00, 0x3f, 0xfe, 0x4a, 0x03, 0xd1, 0x04, 0x50, 0x00, 0x3e, 0x00, 0x00,
+ 0x05, 0x24, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16,
+ 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17,
+ 0x16, 0x33, 0x32, 0x13, 0x33, 0x06, 0x07, 0x06, 0x23, 0x07, 0x36, 0x33,
+ 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27,
+ 0x37, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23,
+ 0x22, 0x07, 0x27, 0x01, 0xcd, 0xfe, 0xf2, 0x59, 0x27, 0x8b, 0x82, 0xd1,
+ 0xf3, 0x6d, 0x3d, 0x0b, 0xac, 0x18, 0x83, 0x2c, 0x37, 0xa5, 0x4e, 0x36,
+ 0x7a, 0x49, 0x6a, 0xda, 0x2c, 0xac, 0x0c, 0x8b, 0x72, 0xab, 0x1b, 0x1d,
+ 0x1c, 0x77, 0x21, 0x0a, 0x67, 0x3d, 0x58, 0x4f, 0x53, 0x24, 0x3a, 0x2b,
+ 0x69, 0x31, 0x2f, 0x42, 0x1f, 0x0e, 0x3d, 0x0f, 0x13, 0x20, 0x1f, 0x19,
+ 0x2b, 0x32, 0x01, 0x05, 0x70, 0x8a, 0x01, 0x14, 0xa1, 0x95, 0xa5, 0x5c,
+ 0x86, 0xa9, 0x30, 0x10, 0x9b, 0x6c, 0xa7, 0xf0, 0x69, 0x3e, 0x01, 0x04,
+ 0xd3, 0x71, 0x5c, 0x44, 0x04, 0x51, 0x19, 0x1f, 0x6f, 0x31, 0x1e, 0x1e,
+ 0x0c, 0x19, 0x54, 0x30, 0x13, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11,
+ 0x0f, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc6, 0x00, 0xf2, 0x00, 0x00, 0x10, 0x06, 0x00, 0x49,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc5, 0x00, 0xf6, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x49,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50,
+ 0x10, 0x27, 0x00, 0xc4, 0x00, 0xfc, 0x00, 0x02, 0x10, 0x06, 0x00, 0x49,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x05, 0x9d,
+ 0x10, 0x27, 0x00, 0x6b, 0x00, 0xf0, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x49,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x26, 0x00, 0xc6, 0xcb, 0xfc, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26,
+ 0x00, 0xc5, 0xc9, 0xfe, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0xc4,
+ 0xc9, 0x00, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06,
+ 0x04, 0xca, 0x02, 0x27, 0x05, 0x9d, 0x10, 0x26, 0x00, 0x6b, 0xc9, 0xe5,
+ 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x05, 0xf2, 0x00, 0x24, 0x00, 0x34, 0x00, 0x00, 0x13, 0x10,
+ 0x37, 0x36, 0x33, 0x32, 0x17, 0x26, 0x27, 0x26, 0x27, 0x07, 0x27, 0x37,
+ 0x26, 0x27, 0x26, 0x27, 0x37, 0x16, 0x17, 0x16, 0x17, 0x37, 0x17, 0x07,
+ 0x16, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x23, 0x20, 0x27, 0x26, 0x01,
+ 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x34, 0x27, 0x26, 0x4a, 0xc7, 0x6d, 0x8a, 0x33, 0x4e, 0x48, 0x64, 0x0b,
+ 0x11, 0xc7, 0x4a, 0xae, 0x38, 0x64, 0x05, 0x07, 0x5a, 0x45, 0x5f, 0x19,
+ 0x27, 0xc6, 0x52, 0xb8, 0x99, 0x57, 0xd0, 0xb7, 0x77, 0xb7, 0xfe, 0xf3,
+ 0x7d, 0x5b, 0x01, 0xe5, 0x9f, 0x53, 0x41, 0x75, 0x4c, 0x72, 0x9d, 0x53,
+ 0x43, 0x7e, 0x4a, 0x02, 0x10, 0x01, 0x5d, 0x90, 0x4f, 0x1b, 0x4a, 0x54,
+ 0x09, 0x0f, 0x5c, 0x50, 0x52, 0x2b, 0x39, 0x03, 0x04, 0x5a, 0x1d, 0x3b,
+ 0x10, 0x19, 0x5c, 0x4c, 0x54, 0x75, 0x6a, 0xfb, 0xfe, 0xbf, 0xfe, 0xb1,
+ 0x92, 0x60, 0xc7, 0x91, 0x02, 0x89, 0x8a, 0x6d, 0xab, 0xea, 0x6e, 0x49,
+ 0x86, 0x6c, 0xa9, 0xfd, 0x6c, 0x3f, 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00,
+ 0x03, 0xe5, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc8, 0x00, 0xee, 0xff, 0xe3,
+ 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc6, 0x00, 0xdf, 0x00, 0x02,
+ 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc5, 0x00, 0xe1, 0x00, 0x00,
+ 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc4, 0x00, 0xe1, 0x00, 0x02,
+ 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc8, 0x00, 0xe1, 0xff, 0xe3,
+ 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1,
+ 0x04, 0x14, 0x05, 0x9d, 0x10, 0x27, 0x00, 0x6b, 0x00, 0xdf, 0xff, 0xe5,
+ 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0x00, 0x03, 0x00, 0x66, 0x00, 0x00,
+ 0x04, 0x46, 0x03, 0xc7, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00,
+ 0x01, 0x15, 0x21, 0x35, 0x01, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35,
+ 0x04, 0x46, 0xfc, 0x20, 0x02, 0x5b, 0xd5, 0xd5, 0xd5, 0x02, 0x2b, 0x8f,
+ 0x8f, 0xfe, 0xaa, 0xd5, 0xd5, 0x02, 0xf2, 0xd5, 0xd5, 0x00, 0x00, 0x03,
+ 0x00, 0x25, 0xff, 0xc3, 0x04, 0x3b, 0x04, 0x50, 0x00, 0x17, 0x00, 0x20,
+ 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x16, 0x15, 0x10, 0x07, 0x06, 0x23,
+ 0x22, 0x27, 0x07, 0x27, 0x37, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32,
+ 0x17, 0x16, 0x17, 0x37, 0x03, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35,
+ 0x34, 0x09, 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14,
+ 0x04, 0x3b, 0x81, 0x5a, 0xa1, 0x7c, 0xc6, 0xd2, 0x7c, 0x7d, 0x41, 0x87,
+ 0x62, 0xa1, 0x7d, 0xc7, 0xc6, 0x81, 0x07, 0x06, 0x77, 0xbd, 0xfe, 0x19,
+ 0x58, 0x81, 0xa3, 0x52, 0x3e, 0xfd, 0xc5, 0x01, 0xe9, 0x49, 0x79, 0x0f,
+ 0x10, 0x9f, 0x53, 0x41, 0x04, 0x17, 0x92, 0x94, 0xe1, 0xfe, 0xce, 0x98,
+ 0x75, 0x7f, 0x8d, 0x39, 0x97, 0x92, 0xeb, 0x01, 0x31, 0x98, 0x77, 0x78,
+ 0x07, 0x06, 0x85, 0xfe, 0xa8, 0xfd, 0xd9, 0x62, 0x8e, 0x6b, 0xa8, 0x89,
+ 0xfe, 0x88, 0x02, 0x27, 0x5c, 0x0c, 0x02, 0x8a, 0x6d, 0xab, 0x8c, 0x00,
+ 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27,
+ 0x00, 0xc6, 0x00, 0xdd, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27,
+ 0x00, 0xc5, 0x00, 0xdd, 0x00, 0x00, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27,
+ 0x00, 0xc4, 0x00, 0xe3, 0x00, 0x02, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x05, 0x9d, 0x10, 0x27,
+ 0x00, 0x6b, 0x00, 0xe1, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x04, 0x31, 0x10, 0x27,
+ 0x00, 0xc5, 0x00, 0xa6, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x6f, 0xfe, 0x42, 0x04, 0x2d, 0x05, 0xb6, 0x00, 0x14,
+ 0x00, 0x24, 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, 0x33,
+ 0x32, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27,
+ 0x11, 0x01, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37,
+ 0x36, 0x35, 0x34, 0x27, 0x26, 0x6f, 0xaa, 0x59, 0x9f, 0x27, 0x2a, 0xd0,
+ 0x7c, 0x7f, 0x88, 0x7c, 0xc7, 0xa9, 0x72, 0x17, 0x17, 0x01, 0x2b, 0x91,
+ 0x53, 0x47, 0x6b, 0x4d, 0x73, 0x91, 0x57, 0x4f, 0x6d, 0x51, 0xfe, 0x42,
+ 0x07, 0x74, 0xfd, 0xf6, 0x7f, 0x1e, 0x07, 0x9d, 0xa0, 0xfe, 0xf3, 0xfe,
+ 0xf5, 0x9c, 0x8e, 0x6d, 0x17, 0x1c, 0xfd, 0xd1, 0x05, 0x6e, 0x81, 0x6f,
+ 0xb0, 0xdb, 0x72, 0x52, 0x7a, 0x70, 0xaf, 0xdc, 0x73, 0x57, 0xff, 0xff,
+ 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x05, 0x9d, 0x10, 0x27, 0x00, 0x6b,
+ 0x00, 0xb0, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x01, 0x9e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x9c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0xb7, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4a, 0x00, 0xcc, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x01, 0x3e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x34, 0x01, 0x5c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x01, 0xad, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x8c, 0x01, 0xc8, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x48, 0x02, 0x9d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x58, 0x03, 0x0c, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x68, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0xae, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0xc5, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x25, 0x01, 0x18, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x01, 0x52, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x1a, 0x01, 0x92, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x01, 0xbf, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x46, 0x02, 0x56, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x24, 0x02, 0xe7, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2c, 0x03, 0x66, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x10, 0x00, 0x9c, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0c, 0x00, 0xb7, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x4a, 0x00, 0xcc, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x12, 0x01, 0x3e, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x34, 0x01, 0x5c, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x10, 0x01, 0xad, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x0d, 0x00, 0x8c, 0x01, 0xc8, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x0e, 0x00, 0x48, 0x02, 0x9d, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x13, 0x00, 0x58, 0x03, 0x0c, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x24, 0x00, 0x02, 0x00, 0x0e, 0x03, 0x93, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x24, 0x00, 0x0d, 0x00, 0x86, 0x03, 0xa3, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x24, 0x00, 0x0e, 0x00, 0x48, 0x04, 0x2b, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x24, 0x00, 0x13, 0x00, 0x54, 0x04, 0x75, 0x00, 0x43,
+ 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x66,
+ 0x00, 0x74, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32,
+ 0x00, 0x2c, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33,
+ 0x00, 0x2c, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x35,
+ 0x00, 0x20, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x20,
+ 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61,
+ 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x75,
+ 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f,
+ 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65,
+ 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x32, 0x2c, 0x20, 0x32, 0x30, 0x30,
+ 0x33, 0x2c, 0x20, 0x32, 0x30, 0x30, 0x35, 0x20, 0x46, 0x72, 0x65, 0x65,
+ 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x46, 0x6f,
+ 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x00, 0x00, 0x46,
+ 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e,
+ 0x00, 0x73, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6e, 0x73,
+ 0x00, 0x00, 0x4d, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x75, 0x00,
+ 0x6d, 0x00, 0x00, 0x4d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x00, 0x00, 0x46,
+ 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72,
+ 0x00, 0x67, 0x00, 0x65, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30,
+ 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65,
+ 0x00, 0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73,
+ 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x32, 0x00, 0x36, 0x00, 0x2d,
+ 0x00, 0x31, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x36,
+ 0x00, 0x00, 0x46, 0x6f, 0x6e, 0x74, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x20,
+ 0x31, 0x2e, 0x30, 0x20, 0x3a, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x53,
+ 0x61, 0x6e, 0x73, 0x20, 0x3a, 0x20, 0x32, 0x36, 0x2d, 0x31, 0x2d, 0x32,
+ 0x30, 0x30, 0x36, 0x00, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x00,
+ 0x46, 0x72, 0x65, 0x65, 0x20, 0x53, 0x61, 0x6e, 0x73, 0x00, 0x00, 0x56,
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e,
+ 0x00, 0x20, 0x00, 0x24, 0x00, 0x52, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69,
+ 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3a, 0x00, 0x20,
+ 0x00, 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x36, 0x00, 0x20, 0x00, 0x24,
+ 0x00, 0x20, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+ 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31,
+ 0x2e, 0x37, 0x36, 0x20, 0x24, 0x20, 0x00, 0x00, 0x46, 0x00, 0x72, 0x00,
+ 0x65, 0x00, 0x65, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00,
+ 0x00, 0x46, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6e, 0x73, 0x00, 0x00, 0x54,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68,
+ 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6e,
+ 0x00, 0x74, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x67,
+ 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64,
+ 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65,
+ 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20,
+ 0x00, 0x47, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65,
+ 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20,
+ 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63,
+ 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e,
+ 0x00, 0x73, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20,
+ 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
+ 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e,
+ 0x74, 0x65, 0x64, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20,
+ 0x74, 0x6f, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72,
+ 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69,
+ 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2e, 0x00, 0x00, 0x68, 0x00, 0x74, 0x00,
+ 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x77, 0x00,
+ 0x77, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x75, 0x00,
+ 0x2e, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x2f, 0x00, 0x63, 0x00,
+ 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x66, 0x00,
+ 0x74, 0x00, 0x2f, 0x00, 0x67, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x2e, 0x00,
+ 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6e, 0x75, 0x2e,
+ 0x6f, 0x72, 0x67, 0x2f, 0x63, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74,
+ 0x2f, 0x67, 0x70, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x00, 0x54,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x71, 0x00, 0x75, 0x00, 0x69,
+ 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x62, 0x00, 0x72, 0x00, 0x6f,
+ 0x00, 0x77, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x78,
+ 0x00, 0x20, 0x00, 0x6a, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x73,
+ 0x00, 0x20, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20,
+ 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x61,
+ 0x00, 0x7a, 0x00, 0x79, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x67,
+ 0x00, 0x2e, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63,
+ 0x6b, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f, 0x78, 0x20,
+ 0x6a, 0x75, 0x6d, 0x70, 0x73, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x6c, 0x61, 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67, 0x2e,
+ 0x00, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x76, 0x00, 0x61, 0x00, 0x64, 0x00,
+ 0x6e, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x76, 0x00,
+ 0x6f, 0x00, 0x6c, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00,
+ 0x20, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x20, 0x00, 0x75, 0x00, 0x70, 0x00,
+ 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x62, 0x00, 0x61, 0x00, 0x20, 0x00,
+ 0x76, 0x00, 0x20, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x61, 0x00,
+ 0x64, 0x00, 0x75, 0x00, 0x20, 0x00, 0x7a, 0x00, 0x20, 0x00, 0x6c, 0x00,
+ 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x6f, 0x00,
+ 0x20, 0x00, 0x47, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x20, 0x00, 0x47, 0x00,
+ 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6c, 0x00,
+ 0x20, 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00,
+ 0x63, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00,
+ 0x6e, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x68, 0x00,
+ 0x74, 0x00, 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00,
+ 0x77, 0x00, 0x77, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x67, 0x00, 0x6e, 0x00,
+ 0x75, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x2f, 0x00,
+ 0x63, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00,
+ 0x66, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x67, 0x00, 0x70, 0x00, 0x6c, 0x00,
+ 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x01,
+ 0x60, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x66, 0x00, 0x20, 0x00,
+ 0x62, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x7a, 0x00, 0x61, 0x00, 0x20, 0x00,
+ 0x76, 0x00, 0x61, 0x00, 0x6a, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x73, 0x00,
+ 0x70, 0x00, 0x65, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x75, 0x00,
+ 0x68, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00,
+ 0x6d, 0x00, 0x61, 0x01, 0x0d, 0x00, 0x65, 0x00, 0x20, 0x01, 0x7e, 0x00,
+ 0x67, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x2e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0xcb, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x03,
+ 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09,
+ 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f,
+ 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15,
+ 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b,
+ 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21,
+ 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27,
+ 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d,
+ 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33,
+ 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39,
+ 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f,
+ 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45,
+ 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b,
+ 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51,
+ 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
+ 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d,
+ 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0xac, 0x00, 0xa3,
+ 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, 0x00, 0x96, 0x00, 0xe8, 0x00, 0x86,
+ 0x00, 0x8e, 0x00, 0x8b, 0x00, 0x9d, 0x00, 0xa9, 0x00, 0xa4, 0x01, 0x03,
+ 0x00, 0x8a, 0x00, 0xda, 0x00, 0x83, 0x00, 0x93, 0x00, 0xf2, 0x00, 0xf3,
+ 0x00, 0x8d, 0x00, 0x97, 0x00, 0x88, 0x00, 0xc3, 0x00, 0xde, 0x00, 0xf1,
+ 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, 0x00, 0xf4, 0x00, 0xf6, 0x00, 0xa2,
+ 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, 0x00, 0xae, 0x00, 0x62, 0x00, 0x63,
+ 0x00, 0x90, 0x00, 0x64, 0x00, 0xcb, 0x00, 0x65, 0x00, 0xc8, 0x00, 0xca,
+ 0x00, 0xcf, 0x00, 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xe9, 0x00, 0x66,
+ 0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xaf, 0x00, 0x67, 0x00, 0xf0,
+ 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0x68, 0x00, 0xeb,
+ 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, 0x00, 0x69, 0x00, 0x6b, 0x00, 0x6d,
+ 0x00, 0x6c, 0x00, 0x6e, 0x00, 0xa0, 0x00, 0x6f, 0x00, 0x71, 0x00, 0x70,
+ 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x74, 0x00, 0x76, 0x00, 0x77,
+ 0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x7b, 0x00, 0x7d,
+ 0x00, 0x7c, 0x00, 0xb8, 0x00, 0xa1, 0x00, 0x7f, 0x00, 0x7e, 0x00, 0x80,
+ 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, 0x00, 0xba, 0x00, 0xd7, 0x00, 0xd8,
+ 0x01, 0x04, 0x01, 0x05, 0x00, 0xdd, 0x00, 0xd9, 0x06, 0x67, 0x6c, 0x79,
+ 0x70, 0x68, 0x33, 0x0a, 0x73, 0x6f, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68,
+ 0x65, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x41, 0x07, 0x75,
+ 0x6e, 0x69, 0x30, 0x32, 0x43, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xff, 0xff, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+ 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6a,
+ 0x00, 0x01, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x03, 0x00, 0x6c, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x8e, 0x00, 0x9c, 0x00, 0x08,
+ 0x44, 0x46, 0x4c, 0x54, 0x00, 0x32, 0x61, 0x72, 0x6d, 0x6e, 0x00, 0x3c,
+ 0x62, 0x65, 0x6e, 0x67, 0x00, 0x46, 0x64, 0x65, 0x76, 0x61, 0x00, 0x50,
+ 0x67, 0x75, 0x6a, 0x72, 0x00, 0x5a, 0x67, 0x75, 0x72, 0x75, 0x00, 0x64,
+ 0x68, 0x65, 0x62, 0x72, 0x00, 0x6e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x78,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x63, 0x63, 0x6d, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00, 0x02,
+ 0x00, 0x12, 0x00, 0x1a, 0x00, 0x22, 0x00, 0x22, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x4d, 0x00, 0x4e,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
+ 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x06, 0x00, 0x76, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4d,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x90, 0x00, 0xaa, 0x00, 0x08,
+ 0x44, 0x46, 0x4c, 0x54, 0x00, 0x32, 0x61, 0x72, 0x6d, 0x6e, 0x00, 0x3e,
+ 0x62, 0x65, 0x6e, 0x67, 0x00, 0x48, 0x64, 0x65, 0x76, 0x61, 0x00, 0x52,
+ 0x67, 0x75, 0x6a, 0x72, 0x00, 0x5c, 0x67, 0x75, 0x72, 0x75, 0x00, 0x66,
+ 0x68, 0x65, 0x62, 0x72, 0x00, 0x70, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x7a,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 0x6b, 0x65, 0x72, 0x6e, 0x00, 0x0e, 0x6b, 0x65, 0x72, 0x6e,
+ 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8e,
+ 0x00, 0x01, 0x00, 0x7a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12,
+ 0x00, 0x20, 0x00, 0x46, 0x00, 0x54, 0x00, 0x03, 0xff, 0xff, 0xff, 0x33,
+ 0xff, 0xff, 0xff, 0xac, 0xff, 0xff, 0xff, 0x9a, 0x00, 0x09, 0x00, 0x25,
+ 0xff, 0xf2, 0x00, 0x38, 0xff, 0x5c, 0x00, 0x3a, 0xff, 0xa2, 0x00, 0x3b,
+ 0xff, 0xd9, 0x00, 0x3d, 0xff, 0x44, 0x00, 0x84, 0xff, 0xf2, 0x00, 0x87,
+ 0xff, 0xf2, 0x00, 0x88, 0xff, 0xf2, 0x00, 0x89, 0xff, 0xe9, 0x00, 0x03,
+ 0xff, 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0xac, 0xff, 0xff, 0xff, 0x98,
+ 0x00, 0x09, 0x00, 0x25, 0xff, 0x9a, 0x00, 0x38, 0xfe, 0xfe, 0x00, 0x3a,
+ 0xff, 0x42, 0x00, 0x3b, 0xff, 0x79, 0x00, 0x3d, 0xfe, 0xf0, 0x00, 0x84,
+ 0xff, 0x9a, 0x00, 0x87, 0xff, 0x9a, 0x00, 0x88, 0xff, 0x9a, 0x00, 0x89,
+ 0xff, 0x91, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12,
+ 0x00, 0x7e, 0x00, 0x01, 0x0e, 0x92, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x9a, 0x01, 0x34, 0x01, 0x7a, 0x01, 0xa4, 0x01, 0xda, 0x02, 0x50,
+ 0x02, 0x82, 0x02, 0x94, 0x02, 0xe6, 0x03, 0x5c, 0x03, 0xae, 0x03, 0xd8,
+ 0x04, 0x2e, 0x04, 0xa4, 0x04, 0xce, 0x05, 0x8c, 0x05, 0xc2, 0x06, 0x5c,
+ 0x06, 0xee, 0x07, 0x18, 0x07, 0xaa, 0x07, 0xb4, 0x07, 0xca, 0x07, 0xd8,
+ 0x07, 0xe2, 0x07, 0xfc, 0x08, 0x42, 0x08, 0x5c, 0x08, 0x66, 0x08, 0x70,
+ 0x08, 0xae, 0x08, 0xb4, 0x08, 0xc6, 0x08, 0xe0, 0x08, 0xfe, 0x09, 0x08,
+ 0x09, 0x12, 0x09, 0xc0, 0x09, 0xca, 0x0a, 0x08, 0x0a, 0x0e, 0x0a, 0x78,
+ 0x0a, 0xde, 0x0a, 0xf8, 0x0b, 0x62, 0x0b, 0x90, 0x0c, 0x02, 0x0c, 0x30,
+ 0x0c, 0x5e, 0x0c, 0xd0, 0x0d, 0x46, 0x0d, 0x4c, 0x0d, 0x5a, 0x0d, 0x70,
+ 0x0d, 0x7e, 0x0d, 0x8c, 0x0d, 0xa6, 0x0d, 0xac, 0x0d, 0xb2, 0x0d, 0xd0,
+ 0x0d, 0xd6, 0x0d, 0xf8, 0x0e, 0x06, 0x0e, 0x14, 0x0e, 0x22, 0x0e, 0x30,
+ 0x0e, 0x3e, 0x0e, 0x4c, 0x0e, 0x5a, 0x0e, 0x68, 0x0e, 0x76, 0x0e, 0x7c,
+ 0x00, 0x26, 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff,
+ 0xff, 0x7b, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x10,
+ 0x00, 0x0a, 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27,
+ 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35,
+ 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a,
+ 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45,
+ 0xff, 0xf8, 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48,
+ 0xff, 0xf0, 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53,
+ 0xff, 0xe5, 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59,
+ 0xff, 0xe7, 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d,
+ 0xff, 0xba, 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x8a, 0xff, 0xb6, 0x00, 0x99,
+ 0xff, 0xbc, 0x00, 0x9c, 0xff, 0xb4, 0x00, 0x9d, 0xff, 0xb4, 0x00, 0x9e,
+ 0xff, 0xb4, 0x00, 0x9f, 0xff, 0xb4, 0x00, 0xaa, 0xff, 0xec, 0x00, 0x11,
+ 0xff, 0xff, 0xff, 0xf6, 0x00, 0x25, 0xff, 0xd5, 0x00, 0x33, 0xff, 0xf2,
+ 0x00, 0x3a, 0xff, 0xac, 0x00, 0x3b, 0xff, 0xcd, 0x00, 0x3d, 0xff, 0xa6,
+ 0x00, 0x84, 0xff, 0xd5, 0x00, 0x85, 0xff, 0xd5, 0x00, 0x86, 0xff, 0xd5,
+ 0x00, 0x87, 0xff, 0xd5, 0x00, 0x88, 0xff, 0xd5, 0x00, 0x89, 0xff, 0xd5,
+ 0x00, 0x95, 0xff, 0xf2, 0x00, 0x96, 0xff, 0xf2, 0x00, 0x97, 0xff, 0xf2,
+ 0x00, 0x99, 0xff, 0xf2, 0x00, 0x9b, 0xff, 0xfe, 0x00, 0x0a, 0x00, 0x25,
+ 0xff, 0xbe, 0x00, 0x2c, 0xff, 0xe7, 0x00, 0x2f, 0xff, 0xec, 0x00, 0x33,
+ 0xff, 0xf0, 0x00, 0x84, 0xff, 0xbe, 0x00, 0x87, 0xff, 0xbe, 0x00, 0x88,
+ 0xff, 0xbe, 0x00, 0x89, 0xff, 0xbc, 0x00, 0x96, 0xff, 0xf0, 0x00, 0x99,
+ 0xff, 0xf0, 0x00, 0x0d, 0x00, 0x25, 0xff, 0xaa, 0x00, 0x2e, 0xff, 0xf6,
+ 0x00, 0x38, 0xff, 0xa4, 0x00, 0x3a, 0xff, 0x98, 0x00, 0x3b, 0xff, 0xc5,
+ 0x00, 0x3c, 0xff, 0x93, 0x00, 0x3d, 0xff, 0x7f, 0x00, 0x83, 0xff, 0xaa,
+ 0x00, 0x84, 0xff, 0xaa, 0x00, 0x85, 0xff, 0xaa, 0x00, 0x86, 0xff, 0xaa,
+ 0x00, 0x87, 0xff, 0xaa, 0x00, 0x88, 0xff, 0xaa, 0x00, 0x1d, 0xff, 0xff,
+ 0xff, 0xd1, 0x00, 0x10, 0xff, 0x23, 0x00, 0x11, 0xff, 0xe3, 0x00, 0x12,
+ 0xff, 0x23, 0x00, 0x25, 0xff, 0x73, 0x00, 0x2e, 0xff, 0x98, 0x00, 0x33,
+ 0xff, 0xd3, 0x00, 0x45, 0xff, 0xbc, 0x00, 0x49, 0xff, 0xcf, 0x00, 0x4d,
+ 0xff, 0xec, 0x00, 0x4e, 0xff, 0xe7, 0x00, 0x53, 0xff, 0xd5, 0x00, 0x56,
+ 0xff, 0xb8, 0x00, 0x59, 0xff, 0xbc, 0x00, 0x83, 0xff, 0x73, 0x00, 0x84,
+ 0xff, 0x73, 0x00, 0x85, 0xff, 0x73, 0x00, 0x86, 0xff, 0x73, 0x00, 0x87,
+ 0xff, 0x73, 0x00, 0x88, 0xff, 0x73, 0x00, 0x99, 0xff, 0xd3, 0x00, 0xa4,
+ 0xff, 0xbc, 0x00, 0xa7, 0xff, 0xbc, 0x00, 0xa8, 0xff, 0xbc, 0x00, 0xa9,
+ 0xff, 0xc5, 0x00, 0xac, 0xff, 0xcf, 0x00, 0xb6, 0xff, 0xd5, 0x00, 0xb9,
+ 0xff, 0xd5, 0x00, 0xbb, 0xff, 0xd5, 0x00, 0x0c, 0x00, 0x25, 0xff, 0xf4,
+ 0x00, 0x38, 0xff, 0xa6, 0x00, 0x3a, 0xff, 0x9a, 0x00, 0x3b, 0xff, 0xc7,
+ 0x00, 0x3d, 0xff, 0x81, 0x00, 0x83, 0xff, 0xf4, 0x00, 0x84, 0xff, 0xf4,
+ 0x00, 0x85, 0xff, 0xf4, 0x00, 0x86, 0xff, 0xf4, 0x00, 0x87, 0xff, 0xf4,
+ 0x00, 0x88, 0xff, 0xf4, 0x00, 0x89, 0xff, 0xfa, 0x00, 0x04, 0x00, 0x25,
+ 0xff, 0xbe, 0x00, 0x87, 0xff, 0xbe, 0x00, 0x88, 0xff, 0xbe, 0x00, 0x89,
+ 0xff, 0xc1, 0x00, 0x14, 0xff, 0xff, 0xff, 0xa4, 0x00, 0x11, 0xff, 0xa0,
+ 0x00, 0x27, 0xff, 0x98, 0x00, 0x2b, 0xff, 0x98, 0x00, 0x33, 0xff, 0x9e,
+ 0x00, 0x37, 0xff, 0xb2, 0x00, 0x38, 0x00, 0x29, 0x00, 0x45, 0xff, 0xe9,
+ 0x00, 0x49, 0xff, 0xbe, 0x00, 0x53, 0xff, 0xc5, 0x00, 0x59, 0xff, 0xd9,
+ 0x00, 0x5d, 0xff, 0x81, 0x00, 0x96, 0xff, 0x9e, 0x00, 0x99, 0xff, 0x9e,
+ 0x00, 0xa7, 0xff, 0xe9, 0x00, 0xa8, 0xff, 0xe9, 0x00, 0xa9, 0xff, 0xf2,
+ 0x00, 0xb6, 0xff, 0xc5, 0x00, 0xb9, 0xff, 0xc5, 0x00, 0xbf, 0xff, 0xd9,
+ 0x00, 0x1d, 0xff, 0xff, 0xfe, 0xdf, 0xff, 0xff, 0xfe, 0xcf, 0xff, 0xff,
+ 0xff, 0xd9, 0xff, 0xff, 0xff, 0xac, 0x00, 0x11, 0xff, 0x00, 0x00, 0x25,
+ 0x00, 0x23, 0x00, 0x27, 0xff, 0xac, 0x00, 0x2b, 0xff, 0xaa, 0x00, 0x33,
+ 0xff, 0xac, 0x00, 0x37, 0xff, 0xd9, 0x00, 0x38, 0xff, 0x29, 0x00, 0x39,
+ 0xff, 0xb8, 0x00, 0x3a, 0xff, 0x29, 0x00, 0x3b, 0xff, 0x75, 0x00, 0x3d,
+ 0xff, 0x08, 0x00, 0x59, 0xff, 0xf2, 0x00, 0x5d, 0xff, 0x8d, 0x00, 0x84,
+ 0x00, 0x23, 0x00, 0x87, 0x00, 0x23, 0x00, 0x88, 0x00, 0x23, 0x00, 0x89,
+ 0x00, 0x29, 0x00, 0x8a, 0xff, 0xb4, 0x00, 0x95, 0xff, 0xac, 0x00, 0x96,
+ 0xff, 0xac, 0x00, 0x97, 0xff, 0xac, 0x00, 0x98, 0xff, 0xac, 0x00, 0x99,
+ 0xff, 0xac, 0x00, 0x9f, 0xff, 0xb8, 0x00, 0xbf, 0xff, 0xf2, 0x00, 0x14,
+ 0xff, 0xff, 0xff, 0xfa, 0x00, 0x10, 0xff, 0xf2, 0x00, 0x12, 0xff, 0xf2,
+ 0x00, 0x25, 0xff, 0xee, 0x00, 0x27, 0xff, 0xfa, 0x00, 0x2b, 0xff, 0xfc,
+ 0x00, 0x45, 0xff, 0xf6, 0x00, 0x53, 0x00, 0x04, 0x00, 0x84, 0xff, 0xee,
+ 0x00, 0x87, 0xff, 0xee, 0x00, 0x88, 0xff, 0xee, 0x00, 0x89, 0xff, 0xf4,
+ 0x00, 0x8a, 0xff, 0xfa, 0x00, 0xa4, 0xff, 0xf6, 0x00, 0xa7, 0xff, 0xf6,
+ 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9, 0xff, 0xfc, 0x00, 0xb6, 0x00, 0x04,
+ 0x00, 0xb9, 0x00, 0x04, 0x00, 0xbb, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x25,
+ 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3b,
+ 0xff, 0xd1, 0x00, 0x3c, 0xff, 0xa2, 0x00, 0x3d, 0xff, 0x87, 0x00, 0x84,
+ 0xff, 0xb8, 0x00, 0x87, 0xff, 0xb8, 0x00, 0x88, 0xff, 0xb8, 0x00, 0x89,
+ 0xff, 0xb0, 0x00, 0x15, 0xff, 0xff, 0xff, 0xc7, 0x00, 0x10, 0xfe, 0xec,
+ 0x00, 0x11, 0xff, 0xae, 0x00, 0x12, 0xfe, 0xec, 0x00, 0x25, 0xff, 0x60,
+ 0x00, 0x2e, 0xff, 0x60, 0x00, 0x45, 0xff, 0xc7, 0x00, 0x49, 0xff, 0xc1,
+ 0x00, 0x53, 0xff, 0xc9, 0x00, 0x84, 0xff, 0x60, 0x00, 0x87, 0xff, 0x60,
+ 0x00, 0x88, 0xff, 0x60, 0x00, 0x89, 0xff, 0x50, 0x00, 0xa4, 0xff, 0xc7,
+ 0x00, 0xa7, 0xff, 0xc7, 0x00, 0xa8, 0xff, 0xc7, 0x00, 0xa9, 0xff, 0xcf,
+ 0x00, 0xac, 0xff, 0xc1, 0x00, 0xb6, 0xff, 0xc9, 0x00, 0xb9, 0xff, 0xc9,
+ 0x00, 0xbb, 0xff, 0xc9, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff,
+ 0xff, 0xe9, 0x00, 0x11, 0xff, 0xfc, 0x00, 0x27, 0xff, 0xdf, 0x00, 0x2b,
+ 0xff, 0xe1, 0x00, 0x33, 0xff, 0xe5, 0x00, 0x38, 0xff, 0xd1, 0x00, 0x39,
+ 0xff, 0xdd, 0x00, 0x3a, 0xff, 0xb0, 0x00, 0x3b, 0xff, 0xc9, 0x00, 0x3d,
+ 0xff, 0xa8, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x49, 0xff, 0xe7, 0x00, 0x53,
+ 0xff, 0xee, 0x00, 0x59, 0xff, 0xee, 0x00, 0x5d, 0xff, 0xf0, 0x00, 0x8a,
+ 0xff, 0xdf, 0x00, 0x96, 0xff, 0xe5, 0x00, 0x99, 0xff, 0xe5, 0x00, 0x9f,
+ 0xff, 0xdd, 0x00, 0xa4, 0xff, 0xe1, 0x00, 0xa7, 0xff, 0xe1, 0x00, 0xa8,
+ 0xff, 0xe1, 0x00, 0xa9, 0xff, 0xe7, 0x00, 0xac, 0xff, 0xe7, 0x00, 0xb6,
+ 0xff, 0xee, 0x00, 0xb9, 0xff, 0xee, 0x00, 0xbd, 0xff, 0xee, 0x00, 0xbf,
+ 0xff, 0xee, 0x00, 0x0a, 0x00, 0x25, 0xff, 0xd3, 0x00, 0x38, 0xff, 0xc7,
+ 0x00, 0x3a, 0xff, 0xaa, 0x00, 0x3b, 0xff, 0xc7, 0x00, 0x3d, 0xff, 0x9e,
+ 0x00, 0x58, 0xff, 0xfa, 0x00, 0x84, 0xff, 0xd3, 0x00, 0x87, 0xff, 0xd3,
+ 0x00, 0x88, 0xff, 0xd3, 0x00, 0x89, 0xff, 0xd3, 0x00, 0x2f, 0xff, 0xff,
+ 0xff, 0x10, 0xff, 0xff, 0xff, 0x85, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff,
+ 0xff, 0xb8, 0x00, 0x10, 0xff, 0x33, 0x00, 0x11, 0xff, 0x62, 0x00, 0x12,
+ 0xff, 0x33, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x1f, 0xfe, 0xf8, 0x00, 0x25,
+ 0xff, 0x3d, 0x00, 0x27, 0xff, 0xa6, 0x00, 0x2b, 0xff, 0xa4, 0x00, 0x2e,
+ 0xff, 0x33, 0x00, 0x33, 0xff, 0xaa, 0x00, 0x37, 0xff, 0xcf, 0x00, 0x3a,
+ 0x00, 0x19, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x29, 0x00, 0x45,
+ 0xff, 0x33, 0x00, 0x47, 0xff, 0x48, 0x00, 0x49, 0xff, 0x3d, 0x00, 0x4b,
+ 0xff, 0x4a, 0x00, 0x4d, 0xff, 0xfa, 0x00, 0x4e, 0xff, 0xf6, 0x00, 0x53,
+ 0xff, 0x44, 0x00, 0x56, 0xff, 0x44, 0x00, 0x57, 0xff, 0x44, 0x00, 0x59,
+ 0xff, 0x46, 0x00, 0x5a, 0xff, 0x3d, 0x00, 0x5b, 0xff, 0x42, 0x00, 0x5d,
+ 0xff, 0x33, 0x00, 0x6e, 0xff, 0x08, 0x00, 0x83, 0xff, 0x3d, 0x00, 0x84,
+ 0xff, 0x3d, 0x00, 0x85, 0xff, 0x3d, 0x00, 0x86, 0xff, 0x3d, 0x00, 0x87,
+ 0xff, 0x3d, 0x00, 0x88, 0xff, 0x3d, 0x00, 0x89, 0xff, 0x39, 0x00, 0x95,
+ 0xff, 0xaa, 0x00, 0x96, 0xff, 0xaa, 0x00, 0x97, 0xff, 0xaa, 0x00, 0x98,
+ 0xff, 0xaa, 0x00, 0x99, 0xff, 0xaa, 0x00, 0x9b, 0xff, 0xac, 0x00, 0xa9,
+ 0xff, 0x39, 0x00, 0xbb, 0xff, 0x4e, 0x00, 0x0d, 0x00, 0x10, 0xff, 0xc9,
+ 0x00, 0x12, 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x51, 0xff, 0xf8,
+ 0x00, 0x52, 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56, 0xff, 0xf8,
+ 0x00, 0x84, 0xff, 0xb6, 0x00, 0x85, 0xff, 0xb6, 0x00, 0x86, 0xff, 0xb6,
+ 0x00, 0x87, 0xff, 0xb6, 0x00, 0x88, 0xff, 0xb6, 0x00, 0x89, 0xff, 0xb0,
+ 0x00, 0x26, 0xff, 0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0xb8, 0xff, 0xff,
+ 0xff, 0xa8, 0x00, 0x10, 0xff, 0x4a, 0x00, 0x11, 0xff, 0xb2, 0x00, 0x12,
+ 0xff, 0x4a, 0x00, 0x1e, 0xff, 0x79, 0x00, 0x1f, 0xff, 0x79, 0x00, 0x25,
+ 0xff, 0x6f, 0x00, 0x27, 0xff, 0xa8, 0x00, 0x2b, 0xff, 0xaa, 0x00, 0x33,
+ 0xff, 0xae, 0x00, 0x37, 0xff, 0xb8, 0x00, 0x38, 0x00, 0x1f, 0x00, 0x45,
+ 0xff, 0x87, 0x00, 0x49, 0xff, 0x8b, 0x00, 0x4b, 0xff, 0x9a, 0x00, 0x4d,
+ 0xff, 0xf6, 0x00, 0x53, 0xff, 0x91, 0x00, 0x56, 0xff, 0xaa, 0x00, 0x59,
+ 0xff, 0xac, 0x00, 0x5d, 0xff, 0xd7, 0x00, 0x6e, 0xff, 0x56, 0x00, 0x83,
+ 0xff, 0x6f, 0x00, 0x84, 0xff, 0x6f, 0x00, 0x85, 0xff, 0x6f, 0x00, 0x86,
+ 0xff, 0x6f, 0x00, 0x87, 0xff, 0x6f, 0x00, 0x88, 0xff, 0x6f, 0x00, 0x89,
+ 0xff, 0x60, 0x00, 0x95, 0xff, 0xae, 0x00, 0x96, 0xff, 0xae, 0x00, 0x97,
+ 0xff, 0xae, 0x00, 0x98, 0xff, 0xae, 0x00, 0x99, 0xff, 0xae, 0x00, 0x9b,
+ 0xff, 0xbc, 0x00, 0xa9, 0xff, 0x8f, 0x00, 0xbb, 0xff, 0x9a, 0x00, 0x24,
+ 0xff, 0xff, 0xff, 0x91, 0x00, 0x10, 0xff, 0x8d, 0x00, 0x11, 0xff, 0xe5,
+ 0x00, 0x12, 0xff, 0x8d, 0x00, 0x1e, 0xff, 0x96, 0x00, 0x1f, 0xff, 0x93,
+ 0x00, 0x25, 0xff, 0x9a, 0x00, 0x27, 0xff, 0xd1, 0x00, 0x2b, 0xff, 0xd3,
+ 0x00, 0x33, 0xff, 0xd7, 0x00, 0x37, 0xff, 0xcf, 0x00, 0x38, 0x00, 0x27,
+ 0x00, 0x45, 0xff, 0xb2, 0x00, 0x49, 0xff, 0xbe, 0x00, 0x4b, 0xff, 0xcd,
+ 0x00, 0x4d, 0xff, 0xfe, 0x00, 0x53, 0xff, 0xc5, 0x00, 0x56, 0xff, 0xc7,
+ 0x00, 0x59, 0xff, 0xc7, 0x00, 0x5d, 0xff, 0xf4, 0x00, 0x6e, 0xff, 0x89,
+ 0x00, 0x83, 0xff, 0x9a, 0x00, 0x84, 0xff, 0x9a, 0x00, 0x85, 0xff, 0x9a,
+ 0x00, 0x86, 0xff, 0x9a, 0x00, 0x87, 0xff, 0x9a, 0x00, 0x88, 0xff, 0x9a,
+ 0x00, 0x89, 0xff, 0x8d, 0x00, 0x95, 0xff, 0xd7, 0x00, 0x96, 0xff, 0xd7,
+ 0x00, 0x97, 0xff, 0xd7, 0x00, 0x98, 0xff, 0xd7, 0x00, 0x99, 0xff, 0xd7,
+ 0x00, 0x9b, 0xff, 0xe5, 0x00, 0xa9, 0xff, 0xba, 0x00, 0xbb, 0xff, 0xcd,
+ 0x00, 0x0a, 0x00, 0x11, 0xff, 0x98, 0x00, 0x27, 0xff, 0x9e, 0x00, 0x33,
+ 0xff, 0xa4, 0x00, 0x35, 0xff, 0xa6, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x49,
+ 0xff, 0xb6, 0x00, 0x53, 0xff, 0xbc, 0x00, 0x59, 0xff, 0xcf, 0x00, 0x5d,
+ 0xff, 0x83, 0x00, 0x99, 0xff, 0xa4, 0x00, 0x24, 0xff, 0xff, 0xff, 0x0c,
+ 0x00, 0x10, 0xff, 0x1d, 0x00, 0x11, 0xff, 0x54, 0x00, 0x12, 0xff, 0x1d,
+ 0x00, 0x1e, 0xff, 0x4e, 0x00, 0x1f, 0xff, 0x4c, 0x00, 0x25, 0xff, 0x3b,
+ 0x00, 0x27, 0xff, 0x89, 0x00, 0x2b, 0xff, 0x89, 0x00, 0x33, 0xff, 0x8d,
+ 0x00, 0x37, 0xff, 0xac, 0x00, 0x38, 0x00, 0x2f, 0x00, 0x45, 0xff, 0x4c,
+ 0x00, 0x49, 0xff, 0x4a, 0x00, 0x4b, 0xff, 0x56, 0x00, 0x4d, 0x00, 0x06,
+ 0x00, 0x53, 0xff, 0x50, 0x00, 0x54, 0xff, 0x91, 0x00, 0x59, 0xff, 0x7f,
+ 0x00, 0x5a, 0xff, 0xb6, 0x00, 0x6e, 0xff, 0x04, 0x00, 0x83, 0xff, 0x3b,
+ 0x00, 0x84, 0xff, 0x3b, 0x00, 0x85, 0xff, 0x3b, 0x00, 0x86, 0xff, 0x3b,
+ 0x00, 0x87, 0xff, 0x3b, 0x00, 0x88, 0xff, 0x3b, 0x00, 0x89, 0xff, 0x2d,
+ 0x00, 0x95, 0xff, 0x8d, 0x00, 0x96, 0xff, 0x8d, 0x00, 0x97, 0xff, 0x8d,
+ 0x00, 0x98, 0xff, 0x8d, 0x00, 0x99, 0xff, 0x8d, 0x00, 0x9b, 0xff, 0x91,
+ 0x00, 0xa9, 0xff, 0x54, 0x00, 0xbb, 0xff, 0x58, 0x00, 0x02, 0x00, 0x5a,
+ 0xff, 0xbc, 0x00, 0x5d, 0xff, 0xb2, 0x00, 0x05, 0xff, 0xff, 0xff, 0xd1,
+ 0x00, 0x4e, 0xff, 0xf8, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5,
+ 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe9, 0x00, 0x5b,
+ 0xff, 0xfa, 0x00, 0x5d, 0xff, 0xe1, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02,
+ 0x00, 0x4f, 0x00, 0x0e, 0x00, 0x06, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x58,
+ 0xff, 0xec, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee, 0x00, 0x5c,
+ 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd9, 0x00, 0x11, 0xff, 0xff, 0xff, 0xe7,
+ 0x00, 0x45, 0xff, 0xee, 0x00, 0x49, 0xff, 0xe1, 0x00, 0x4a, 0x00, 0x2d,
+ 0x00, 0x4d, 0xff, 0xfc, 0x00, 0x4e, 0xff, 0xf8, 0x00, 0x50, 0xff, 0xfa,
+ 0x00, 0x53, 0xff, 0xec, 0x00, 0x58, 0x00, 0x31, 0x00, 0xa4, 0xff, 0xee,
+ 0x00, 0xa7, 0xff, 0xee, 0x00, 0xa8, 0xff, 0xee, 0x00, 0xa9, 0xff, 0xf6,
+ 0x00, 0xac, 0xff, 0xe1, 0x00, 0xb6, 0xff, 0xec, 0x00, 0xb9, 0xff, 0xec,
+ 0x00, 0xbb, 0xff, 0xee, 0x00, 0x06, 0x00, 0x45, 0xff, 0xf6, 0x00, 0xa7,
+ 0xff, 0xf6, 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9, 0xff, 0xfe, 0x00, 0xb6,
+ 0x00, 0x06, 0x00, 0xb9, 0x00, 0x06, 0x00, 0x02, 0xff, 0xff, 0xff, 0xe1,
+ 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x02, 0x00, 0x38, 0xff, 0xf2, 0x00, 0x4e,
+ 0xff, 0xfa, 0x00, 0x0f, 0x00, 0x11, 0xff, 0xac, 0x00, 0x45, 0xff, 0xfc,
+ 0x00, 0x49, 0xff, 0xd5, 0x00, 0x4b, 0xff, 0xdf, 0x00, 0x53, 0xff, 0xd9,
+ 0x00, 0x57, 0xff, 0xfa, 0x00, 0x59, 0xff, 0xe9, 0x00, 0xa4, 0xff, 0xfc,
+ 0x00, 0xa7, 0xff, 0xfc, 0x00, 0xa8, 0xff, 0xfc, 0x00, 0xa9, 0x00, 0x04,
+ 0x00, 0xac, 0xff, 0xd5, 0x00, 0xb6, 0xff, 0xd9, 0x00, 0xb9, 0xff, 0xd9,
+ 0x00, 0xbf, 0xff, 0xf4, 0x00, 0x01, 0x00, 0x5d, 0xff, 0xf6, 0x00, 0x04,
+ 0x00, 0x54, 0x00, 0x0a, 0x00, 0x5a, 0xff, 0xe5, 0x00, 0x5b, 0xff, 0xf2,
+ 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x06, 0xff, 0xff, 0xff, 0xe3, 0x00, 0x38,
+ 0xff, 0x3b, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x5a, 0xff, 0xe5, 0x00, 0x5b,
+ 0xff, 0xf2, 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x07, 0xff, 0xff, 0xff, 0xd5,
+ 0x00, 0x38, 0xff, 0x35, 0x00, 0x58, 0xff, 0xec, 0x00, 0x5a, 0xff, 0xdb,
+ 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5c, 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd3,
+ 0x00, 0x02, 0x00, 0x58, 0xff, 0xf8, 0x00, 0x5d, 0xff, 0xdf, 0x00, 0x02,
+ 0x00, 0x47, 0x00, 0x10, 0x00, 0x59, 0x00, 0x08, 0x00, 0x2b, 0xff, 0xff,
+ 0x00, 0x02, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf4, 0x00, 0x10,
+ 0xff, 0x73, 0x00, 0x11, 0xff, 0xa0, 0x00, 0x12, 0xff, 0x73, 0x00, 0x1e,
+ 0xff, 0xd3, 0x00, 0x1f, 0xff, 0xd3, 0x00, 0x45, 0xff, 0xf6, 0x00, 0x47,
+ 0xff, 0xf4, 0x00, 0x48, 0xff, 0xfe, 0x00, 0x49, 0xff, 0xe9, 0x00, 0x4a,
+ 0x00, 0x35, 0x00, 0x4b, 0xff, 0xf8, 0x00, 0x4d, 0x00, 0x02, 0x00, 0x4f,
+ 0x00, 0x0c, 0x00, 0x50, 0x00, 0x02, 0x00, 0x53, 0xff, 0xf4, 0x00, 0x54,
+ 0x00, 0x10, 0x00, 0x55, 0xff, 0xfa, 0x00, 0x57, 0x00, 0x08, 0x00, 0x58,
+ 0x00, 0x39, 0x00, 0x59, 0x00, 0x04, 0x00, 0x5a, 0x00, 0x3b, 0x00, 0x5b,
+ 0x00, 0x3f, 0x00, 0x5c, 0x00, 0x29, 0x00, 0x5d, 0x00, 0x31, 0x00, 0x5e,
+ 0x00, 0x12, 0x00, 0xa3, 0xff, 0xf6, 0x00, 0xa4, 0xff, 0xf6, 0x00, 0xa5,
+ 0xff, 0xf6, 0x00, 0xa7, 0xff, 0xf6, 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9,
+ 0xff, 0xfe, 0x00, 0xaa, 0xff, 0xee, 0x00, 0xab, 0xff, 0xe9, 0x00, 0xac,
+ 0xff, 0xe9, 0x00, 0xad, 0xff, 0xe9, 0x00, 0xb5, 0xff, 0xf4, 0x00, 0xb6,
+ 0xff, 0xf4, 0x00, 0xb7, 0xff, 0xf4, 0x00, 0xb9, 0xff, 0xf4, 0x00, 0xbb,
+ 0xff, 0xf4, 0x00, 0x02, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x58, 0xff, 0xfa,
+ 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1e, 0xff, 0xc7, 0x00, 0x1f,
+ 0xff, 0xc7, 0x00, 0x37, 0xff, 0xf0, 0x00, 0x45, 0xff, 0xfe, 0x00, 0x49,
+ 0xff, 0xe3, 0x00, 0x4c, 0xff, 0xfa, 0x00, 0x53, 0xff, 0xe7, 0x00, 0xa4,
+ 0xff, 0xfe, 0x00, 0xa7, 0xff, 0xfe, 0x00, 0xa8, 0xff, 0xfe, 0x00, 0xa9,
+ 0x00, 0x04, 0x00, 0xac, 0xff, 0xe3, 0x00, 0xb6, 0xff, 0xe7, 0x00, 0xb9,
+ 0xff, 0xe7, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1a, 0xff, 0xff,
+ 0xff, 0xdf, 0x00, 0x10, 0xff, 0x73, 0x00, 0x11, 0xff, 0xe7, 0x00, 0x12,
+ 0xff, 0x73, 0x00, 0x1e, 0xff, 0xd1, 0x00, 0x1f, 0xff, 0xd1, 0x00, 0x45,
+ 0xff, 0xdb, 0x00, 0x47, 0xff, 0xdf, 0x00, 0x49, 0xff, 0xd5, 0x00, 0x4b,
+ 0xff, 0xe3, 0x00, 0x53, 0xff, 0xdd, 0x00, 0x57, 0xff, 0xee, 0x00, 0xa3,
+ 0xff, 0xdb, 0x00, 0xa4, 0xff, 0xdb, 0x00, 0xa5, 0xff, 0xdb, 0x00, 0xa6,
+ 0xff, 0xdb, 0x00, 0xa7, 0xff, 0xdb, 0x00, 0xa8, 0xff, 0xdb, 0x00, 0xa9,
+ 0xff, 0xe3, 0x00, 0xab, 0xff, 0xd5, 0x00, 0xac, 0xff, 0xd5, 0x00, 0xad,
+ 0xff, 0xd5, 0x00, 0xb5, 0xff, 0xdd, 0x00, 0xb6, 0xff, 0xdd, 0x00, 0xb9,
+ 0xff, 0xdd, 0x00, 0xbb, 0xff, 0xdd, 0x00, 0x19, 0x00, 0x10, 0xff, 0x9a,
+ 0x00, 0x11, 0xff, 0xfe, 0x00, 0x12, 0xff, 0x9a, 0x00, 0x1e, 0xff, 0xd1,
+ 0x00, 0x1f, 0xff, 0xd1, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x47, 0xff, 0xf2,
+ 0x00, 0x49, 0xff, 0xe7, 0x00, 0x4b, 0xff, 0xf4, 0x00, 0x53, 0xff, 0xee,
+ 0x00, 0x57, 0xff, 0xf6, 0x00, 0xa3, 0xff, 0xe1, 0x00, 0xa4, 0xff, 0xe1,
+ 0x00, 0xa5, 0xff, 0xe1, 0x00, 0xa6, 0xff, 0xe1, 0x00, 0xa7, 0xff, 0xe1,
+ 0x00, 0xa8, 0xff, 0xe1, 0x00, 0xa9, 0xff, 0xe9, 0x00, 0xab, 0xff, 0xe7,
+ 0x00, 0xac, 0xff, 0xe7, 0x00, 0xad, 0xff, 0xe7, 0x00, 0xb5, 0xff, 0xee,
+ 0x00, 0xb6, 0xff, 0xee, 0x00, 0xb9, 0xff, 0xee, 0x00, 0xbb, 0xff, 0xf4,
+ 0x00, 0x06, 0x00, 0x45, 0xff, 0xdd, 0x00, 0x47, 0xff, 0xd1, 0x00, 0x49,
+ 0xff, 0xc7, 0x00, 0x53, 0xff, 0xcd, 0x00, 0x55, 0xff, 0xd7, 0x00, 0xac,
+ 0xff, 0xc7, 0x00, 0x1a, 0x00, 0x10, 0xff, 0x71, 0x00, 0x11, 0xff, 0xe3,
+ 0x00, 0x12, 0xff, 0x71, 0x00, 0x1e, 0xff, 0xc9, 0x00, 0x1f, 0xff, 0xc9,
+ 0x00, 0x45, 0xff, 0xd3, 0x00, 0x47, 0xff, 0xd9, 0x00, 0x49, 0xff, 0xcf,
+ 0x00, 0x4b, 0xff, 0xdd, 0x00, 0x50, 0xff, 0xf8, 0x00, 0x53, 0xff, 0xd7,
+ 0x00, 0x57, 0xff, 0xe7, 0x00, 0xa3, 0xff, 0xd3, 0x00, 0xa4, 0xff, 0xd3,
+ 0x00, 0xa5, 0xff, 0xd3, 0x00, 0xa6, 0xff, 0xd3, 0x00, 0xa7, 0xff, 0xd3,
+ 0x00, 0xa8, 0xff, 0xd3, 0x00, 0xa9, 0xff, 0xdb, 0x00, 0xab, 0xff, 0xcf,
+ 0x00, 0xac, 0xff, 0xcf, 0x00, 0xad, 0xff, 0xcf, 0x00, 0xb5, 0xff, 0xd7,
+ 0x00, 0xb6, 0xff, 0xd7, 0x00, 0xb9, 0xff, 0xd7, 0x00, 0xbb, 0xff, 0xd9,
+ 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27,
+ 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35,
+ 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a,
+ 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x1c,
+ 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a,
+ 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6,
+ 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe,
+ 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66,
+ 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8,
+ 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0,
+ 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, 0xff, 0xe5,
+ 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, 0xff, 0xe7,
+ 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, 0xff, 0xba,
+ 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12,
+ 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33,
+ 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39,
+ 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d,
+ 0xff, 0x35, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0a,
+ 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc,
+ 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4,
+ 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35,
+ 0x00, 0x1c, 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff,
+ 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12,
+ 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33,
+ 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39,
+ 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d,
+ 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8, 0x00, 0x46, 0x00, 0x08, 0x00, 0x47,
+ 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53,
+ 0xff, 0xe5, 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59,
+ 0xff, 0xe7, 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d,
+ 0xff, 0xba, 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xae,
+ 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff, 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a,
+ 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6,
+ 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe,
+ 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66,
+ 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8,
+ 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0,
+ 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, 0xff, 0xe5,
+ 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, 0xff, 0xe7,
+ 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, 0xff, 0xba,
+ 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x01, 0x00, 0x25, 0xff, 0xc1, 0x00, 0x03,
+ 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d, 0xff, 0x87,
+ 0x00, 0x05, 0x00, 0x25, 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a,
+ 0xff, 0xa4, 0x00, 0x3b, 0xff, 0xd1, 0x00, 0x3d, 0xff, 0x87, 0x00, 0x03,
+ 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d, 0xff, 0x87,
+ 0x00, 0x03, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d,
+ 0xff, 0x87, 0x00, 0x06, 0x00, 0x25, 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa,
+ 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3b, 0xff, 0xd1, 0x00, 0x3c, 0xff, 0xa2,
+ 0x00, 0x3d, 0xff, 0x87, 0x00, 0x01, 0x00, 0x25, 0xff, 0xbc, 0x00, 0x01,
+ 0x00, 0x25, 0xff, 0xb6, 0x00, 0x07, 0x00, 0x10, 0xff, 0xc9, 0x00, 0x12,
+ 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x51, 0xff, 0xf8, 0x00, 0x52,
+ 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56, 0xff, 0xf8, 0x00, 0x01,
+ 0x00, 0x25, 0xff, 0xb6, 0x00, 0x08, 0x00, 0x10, 0xff, 0xc9, 0x00, 0x12,
+ 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x46, 0x00, 0x06, 0x00, 0x51,
+ 0xff, 0xf8, 0x00, 0x52, 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56,
+ 0xff, 0xf8, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5,
+ 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b,
+ 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5,
+ 0x00, 0x5b, 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a,
+ 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03,
+ 0x00, 0x5a, 0xff, 0xdf, 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd7,
+ 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee, 0x00, 0x5d,
+ 0xff, 0xd9, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee,
+ 0x00, 0x5d, 0xff, 0xd9, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xdb, 0x00, 0x5b,
+ 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd3, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xdb,
+ 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd3, 0x00, 0x01, 0x00, 0x58,
+ 0xff, 0xec, 0x00, 0x05, 0x00, 0x58, 0xff, 0xec, 0x00, 0x5a, 0xff, 0xdb,
+ 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5c, 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd3,
+ 0x00, 0x02, 0x00, 0x11, 0x00, 0x25, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x2b, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x06, 0x00, 0x32,
+ 0x00, 0x34, 0x00, 0x09, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x0c, 0x00, 0x45,
+ 0x00, 0x47, 0x00, 0x15, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x18, 0x00, 0x4f,
+ 0x00, 0x5d, 0x00, 0x1d, 0x00, 0x83, 0x00, 0x88, 0x00, 0x2c, 0x00, 0x8a,
+ 0x00, 0x8a, 0x00, 0x32, 0x00, 0x95, 0x00, 0x99, 0x00, 0x33, 0x00, 0x9b,
+ 0x00, 0x9f, 0x00, 0x38, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x3d, 0x00, 0xa7,
+ 0x00, 0xa9, 0x00, 0x3f, 0x00, 0xac, 0x00, 0xad, 0x00, 0x42, 0x00, 0xb5,
+ 0x00, 0xb7, 0x00, 0x44, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0x47, 0x00, 0x00
+};
+unsigned int FreeSans_ttf_len = 22932;
+
+#if 0
+void writeLogo(const char *dir)
+{
+ QCString fileName=(QCString)dir+"/doxygen.png";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ f.writeBlock((char *)doxygen_png_data,doxygen_png_len);
+ else
+ {
+ fprintf(stderr,"warning: Cannot open file %s for writing\n",fileName.data());
+ }
+ f.close();
+}
+
+void writeSearchButton(const char *dir)
+{
+ QCString fileName=(QCString)dir+"/search.png";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ f.writeBlock((char *)search_png,search_png_len);
+ else
+ {
+ fprintf(stderr,"warning: Cannot open file %s for writing\n",fileName.data());
+ }
+ f.close();
+}
+#endif
+
+void writeDoxFont(const char *dir)
+{
+ QCString fileName=(QCString)dir+"/FreeSans.ttf";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ f.writeBlock((char *)FreeSans_ttf,FreeSans_ttf_len);
+ else
+ {
+ fprintf(stderr,"error: Cannot open file %s for writing\n",fileName.data());
+ }
+ f.close();
+}
+
+void removeDoxFont(const char *dir)
+{
+ QDir d(dir);
+ d.remove("FreeSans.ttf");
+}
diff --git a/src/logos.h b/src/logos.h
new file mode 100644
index 0000000..083d772
--- /dev/null
+++ b/src/logos.h
@@ -0,0 +1,27 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef LOGOS_H
+#define LOGOS_H
+
+extern void writeLogo(const char *dir);
+//extern void writeNullImage(const char *dir);
+extern void writeSearchButton(const char *dir);
+extern void writeDoxFont(const char *dir);
+extern void removeDoxFont(const char *dir);
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..b64f700
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "doxygen.h"
+
+/*! \file
+ * \brief main entry point for doxygen
+ *
+ * This file contains main()
+ */
+
+/*! Default main. The idea of separating this from the rest of doxygen,
+ * is to make it possible to write your own main, with a different
+ * generateOutput() function for instance.
+ */
+int main(int argc,char **argv)
+{
+ initDoxygen();
+ readConfiguration(argc,argv);
+ checkConfiguration();
+ adjustConfiguration();
+ parseInput();
+ generateOutput();
+ return 0;
+}
+
diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp
new file mode 100644
index 0000000..1fe5409
--- /dev/null
+++ b/src/mandocvisitor.cpp
@@ -0,0 +1,1031 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfileinfo.h>
+
+#include "mandocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "code.h"
+#include "dot.h"
+#include "util.h"
+#include "message.h"
+#include "parserintf.h"
+#include "filedef.h"
+#include "htmlentity.h"
+
+ManDocVisitor::ManDocVisitor(FTextStream &t,CodeOutputInterface &ci,
+ const char *langExt)
+ : DocVisitor(DocVisitor_Man), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(FALSE),
+ m_indent(0), m_langExt(langExt)
+{
+}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+void ManDocVisitor::visit(DocWord *w)
+{
+ if (m_hide) return;
+ filter(w->word());
+ m_firstCol=FALSE;
+}
+
+void ManDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ m_t << "\\fB";
+ filter(w->word());
+ m_t << "\\fP";
+ m_firstCol=FALSE;
+}
+
+void ManDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ m_firstCol=w->chars().at(w->chars().length()-1)=='\n';
+ }
+ else
+ {
+ m_t << " ";
+ m_firstCol=FALSE;
+ }
+}
+
+void ManDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ const char *res = HtmlEntityMapper::instance()->man(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ // no error or warning to be supplied
+ // err("man: non supported HTML-entity found: &%s;\n",get_symbol_item(s->symbol()));
+ }
+ m_firstCol=FALSE;
+}
+
+void ManDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ m_t << u->url();
+ m_firstCol=FALSE;
+}
+
+void ManDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ m_t << endl << ".br" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visit(DocHorRuler *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "\\fB"; else m_t << "\\fP";
+ m_firstCol=FALSE;
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "\\fI"; else m_t << "\\fP";
+ m_firstCol=FALSE;
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "\\fC"; else m_t << "\\fP";
+ m_firstCol=FALSE;
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "\\*<"; else m_t << "\\*> ";
+ m_firstCol=FALSE;
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "\\*{"; else m_t << "\\*} ";
+ m_firstCol=FALSE;
+ break;
+ case DocStyleChange::Center:
+ /* not supported */
+ break;
+ case DocStyleChange::Small:
+ /* not supported */
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_insidePre=FALSE;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ }
+ break;
+ case DocStyleChange::Div: /* HTML only */ break;
+ case DocStyleChange::Span: /* HTML only */ break;
+ }
+}
+
+void ManDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ QCString lang = m_langExt;
+ if (!s->language().isEmpty()) // explicit language setting
+ {
+ lang = s->language();
+ }
+ SrcLangExt langExt = getLanguageFromFileName(lang);
+ switch (s->type())
+ {
+ case DocVerbatim::Code: // fall though
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ Doxygen::parserManager->getParser(lang)
+ ->parseCode(m_ci,s->context(),s->text(),
+ langExt,
+ s->isExample(),s->exampleFile());
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ break;
+ case DocVerbatim::Verbatim:
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ m_t << s->text();
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ break;
+ case DocVerbatim::ManOnly:
+ m_t << s->text();
+ break;
+ case DocVerbatim::HtmlOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::LatexOnly:
+ case DocVerbatim::RtfOnly:
+ case DocVerbatim::DocbookOnly:
+ case DocVerbatim::Dot:
+ case DocVerbatim::Msc:
+ case DocVerbatim::PlantUML:
+ /* nothing */
+ break;
+ }
+}
+
+void ManDocVisitor::visit(DocAnchor *)
+{
+ /* no support for anchors in man pages */
+}
+
+void ManDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(), &fd);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ }
+ break;
+ case DocInclude::Include:
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile());
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ break;
+ case DocInclude::LatexInclude:
+ break;
+ case DocInclude::VerbInclude:
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ m_t << inc->text();
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ break;
+ case DocInclude::Snippet:
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile()
+ );
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ break;
+ }
+}
+
+void ManDocVisitor::visit(DocIncOperator *op)
+{
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ if (op->isFirst())
+ {
+ if (!m_hide)
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ }
+ pushEnabled();
+ m_hide = TRUE;
+ }
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,op->context(),op->text(),langExt,
+ op->isExample(),op->exampleFile());
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".fi" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ }
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ }
+}
+
+void ManDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ m_t << f->text();
+}
+
+void ManDocVisitor::visit(DocIndexEntry *)
+{
+}
+
+void ManDocVisitor::visit(DocSimpleSectSep *)
+{
+}
+
+void ManDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ m_t << "\\fB";
+ if (cite->file().isEmpty()) m_t << "[";
+ filter(cite->text());
+ if (cite->file().isEmpty()) m_t << "]";
+ m_t << "\\fP";
+}
+
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void ManDocVisitor::visitPre(DocAutoList *)
+{
+ if (m_hide) return;
+ m_indent+=2;
+}
+
+void ManDocVisitor::visitPost(DocAutoList *)
+{
+ if (m_hide) return;
+ m_indent-=2;
+ m_t << ".PP" << endl;
+}
+
+void ManDocVisitor::visitPre(DocAutoListItem *li)
+{
+ if (m_hide) return;
+ QCString ws;
+ ws.fill(' ',m_indent-2);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".IP \"" << ws;
+ if (((DocAutoList *)li->parent())->isEnumList())
+ {
+ m_t << li->itemNumber() << ".\" " << m_indent+2;
+ }
+ else // bullet list
+ {
+ m_t << "\\(bu\" " << m_indent;
+ }
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPost(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocPara *)
+{
+}
+
+void ManDocVisitor::visitPost(DocPara *p)
+{
+ if (m_hide) return;
+ if (!p->isLast() && // omit <p> for last paragraph
+ !(p->parent() && // and for parameter sections
+ p->parent()->kind()==DocNode::Kind_ParamSect
+ )
+ )
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ }
+}
+
+void ManDocVisitor::visitPre(DocRoot *)
+{
+}
+
+void ManDocVisitor::visitPost(DocRoot *)
+{
+}
+
+void ManDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ if (!m_firstCol)
+ {
+ m_t << endl;
+ m_t << ".PP" << endl;
+ }
+ m_t << "\\fB";
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << theTranslator->trSeeAlso(); break;
+ case DocSimpleSect::Return:
+ m_t << theTranslator->trReturns(); break;
+ case DocSimpleSect::Author:
+ m_t << theTranslator->trAuthor(TRUE,TRUE); break;
+ case DocSimpleSect::Authors:
+ m_t << theTranslator->trAuthor(TRUE,FALSE); break;
+ case DocSimpleSect::Version:
+ m_t << theTranslator->trVersion(); break;
+ case DocSimpleSect::Since:
+ m_t << theTranslator->trSince(); break;
+ case DocSimpleSect::Date:
+ m_t << theTranslator->trDate(); break;
+ case DocSimpleSect::Note:
+ m_t << theTranslator->trNote(); break;
+ case DocSimpleSect::Warning:
+ m_t << theTranslator->trWarning(); break;
+ case DocSimpleSect::Pre:
+ m_t << theTranslator->trPrecondition(); break;
+ case DocSimpleSect::Post:
+ m_t << theTranslator->trPostcondition(); break;
+ case DocSimpleSect::Copyright:
+ m_t << theTranslator->trCopyright(); break;
+ case DocSimpleSect::Invar:
+ m_t << theTranslator->trInvariant(); break;
+ case DocSimpleSect::Remark:
+ m_t << theTranslator->trRemarks(); break;
+ case DocSimpleSect::Attention:
+ m_t << theTranslator->trAttention(); break;
+ case DocSimpleSect::User: break;
+ case DocSimpleSect::Rcs: break;
+ case DocSimpleSect::Unknown: break;
+ }
+
+ // special case 1: user defined title
+ if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
+ {
+ m_t << ":\\fP" << endl;
+ m_t << ".RS 4" << endl;
+ }
+}
+
+void ManDocVisitor::visitPost(DocSimpleSect *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".RE" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocTitle *)
+{
+}
+
+void ManDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "\\fP" << endl;
+ m_t << ".RS 4" << endl;
+}
+
+void ManDocVisitor::visitPre(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_indent+=2;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PD 0" << endl;
+}
+
+void ManDocVisitor::visitPost(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_indent-=2;
+ m_t << ".PP" << endl;
+}
+
+void ManDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ QCString ws;
+ ws.fill(' ',m_indent-2);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".IP \"" << ws << "\\(bu\" " << m_indent << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPost(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ if (s->level()==1) m_t << ".SH"; else m_t << ".SS";
+ m_t << " \"";
+ filter(s->title());
+ m_t << "\"" << endl;
+ if (s->level()==1) m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPost(DocSection *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlList *)
+{
+ if (m_hide) return;
+ m_indent+=2;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PD 0" << endl;
+}
+
+void ManDocVisitor::visitPost(DocHtmlList *)
+{
+ if (m_hide) return;
+ m_indent-=2;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+}
+
+void ManDocVisitor::visitPre(DocHtmlListItem *li)
+{
+ if (m_hide) return;
+ QCString ws;
+ ws.fill(' ',m_indent-2);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".IP \"" << ws;
+ if (((DocHtmlList *)li->parent())->type()==DocHtmlList::Ordered)
+ {
+ m_t << li->itemNumber() << ".\" " << m_indent+2;
+ }
+ else // bullet list
+ {
+ m_t << "\\(bu\" " << m_indent;
+ }
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPost(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+//void ManDocVisitor::visitPre(DocHtmlPre *)
+//{
+// if (!m_firstCol) m_t << endl;
+// m_t << ".PP" << endl;
+// m_t << ".nf" << endl;
+// m_insidePre=TRUE;
+//}
+//
+//void ManDocVisitor::visitPost(DocHtmlPre *)
+//{
+// m_insidePre=FALSE;
+// if (!m_firstCol) m_t << endl;
+// m_t << ".fi" << endl;
+// m_t << ".PP" << endl;
+// m_firstCol=TRUE;
+//}
+
+void ManDocVisitor::visitPre(DocHtmlDescList *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".IP \"\\fB";
+ m_firstCol=FALSE;
+}
+
+void ManDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "\\fP\" 1c" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocHtmlDescData *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlDescData *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlTable *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlTable *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlCaption *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlCaption *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlRow *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlRow *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlCell *)
+{
+}
+
+void ManDocVisitor::visitPost(DocHtmlCell *)
+{
+}
+
+void ManDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ //if (!m_firstCol) m_t << endl;
+ //m_t << ".PP" << endl;
+ //m_t << "\\fB" << theTranslator->trForInternalUseOnly() << "\\fP" << endl;
+ //m_t << ".RS 4" << endl;
+}
+
+void ManDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ //if (!m_firstCol) m_t << endl;
+ //m_t << ".RE" << endl;
+ //m_t << ".PP" << endl;
+ //m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "\\fC";
+}
+
+void ManDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "\\fP";
+}
+
+void ManDocVisitor::visitPre(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ if (header->level()==1) m_t << ".SH"; else m_t << ".SS";
+ m_t << " \"";
+}
+
+void ManDocVisitor::visitPost(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ m_t << "\"" << endl;
+ if (header->level()==1) m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocImage *)
+{
+}
+
+void ManDocVisitor::visitPost(DocImage *)
+{
+}
+
+void ManDocVisitor::visitPre(DocDotFile *)
+{
+}
+
+void ManDocVisitor::visitPost(DocDotFile *)
+{
+}
+void ManDocVisitor::visitPre(DocMscFile *)
+{
+}
+
+void ManDocVisitor::visitPost(DocMscFile *)
+{
+}
+
+void ManDocVisitor::visitPre(DocDiaFile *)
+{
+}
+
+void ManDocVisitor::visitPost(DocDiaFile *)
+{
+}
+
+void ManDocVisitor::visitPre(DocLink *)
+{
+ if (m_hide) return;
+ m_t << "\\fB";
+}
+
+void ManDocVisitor::visitPost(DocLink *)
+{
+ if (m_hide) return;
+ m_t << "\\fP";
+}
+
+void ManDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ m_t << "\\fB";
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void ManDocVisitor::visitPost(DocRef *)
+{
+ if (m_hide) return;
+ m_t << "\\fP";
+}
+
+void ManDocVisitor::visitPre(DocSecRefItem *)
+{
+ if (m_hide) return;
+ QCString ws;
+ ws.fill(' ',m_indent-2);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".IP \"" << ws << "\\(bu\" " << m_indent << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPost(DocSecRefItem *)
+{
+ if (m_hide) return;
+ m_t << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_indent+=2;
+}
+
+void ManDocVisitor::visitPost(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_indent-=2;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+}
+
+//void ManDocVisitor::visitPre(DocLanguage *l)
+//{
+// QString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// pushEnabled();
+// m_hide = TRUE;
+// }
+//}
+//
+//void ManDocVisitor::visitPost(DocLanguage *l)
+//{
+// QString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// popEnabled();
+// }
+//}
+
+void ManDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ if (!m_firstCol)
+ {
+ m_t << endl;
+ m_t << ".PP" << endl;
+ }
+ m_t << "\\fB";
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ m_t << theTranslator->trParameters(); break;
+ case DocParamSect::RetVal:
+ m_t << theTranslator->trReturnValues(); break;
+ case DocParamSect::Exception:
+ m_t << theTranslator->trExceptions(); break;
+ case DocParamSect::TemplateParam:
+ /* TODO: add this
+ m_t << theTranslator->trTemplateParam(); break;
+ */
+ m_t << "Template Parameters"; break;
+ default:
+ ASSERT(0);
+ }
+ m_t << ":\\fP" << endl;
+ m_t << ".RS 4" << endl;
+}
+
+void ManDocVisitor::visitPost(DocParamSect *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".RE" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocParamList *pl)
+{
+ if (m_hide) return;
+ m_t << "\\fI";
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ bool first=TRUE;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (!first) m_t << ","; else first=FALSE;
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ }
+ m_t << "\\fP ";
+}
+
+void ManDocVisitor::visitPost(DocParamList *pl)
+{
+ if (m_hide) return;
+ if (!pl->isLast())
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".br" << endl;
+ }
+}
+
+void ManDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ if (!m_firstCol)
+ {
+ m_t << endl;
+ m_t << ".PP" << endl;
+ }
+ m_t << "\\fB";
+ filter(x->title());
+ m_t << "\\fP" << endl;
+ m_t << ".RS 4" << endl;
+}
+
+void ManDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".RE" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocInternalRef *)
+{
+ if (m_hide) return;
+ m_t << "\\fB";
+}
+
+void ManDocVisitor::visitPost(DocInternalRef *)
+{
+ if (m_hide) return;
+ m_t << "\\fP";
+}
+
+void ManDocVisitor::visitPre(DocCopy *)
+{
+}
+
+void ManDocVisitor::visitPost(DocCopy *)
+{
+}
+
+void ManDocVisitor::visitPre(DocText *)
+{
+}
+
+void ManDocVisitor::visitPost(DocText *)
+{
+}
+
+void ManDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ if (!m_firstCol)
+ {
+ m_t << endl;
+ m_t << ".PP" << endl;
+ }
+ m_t << ".RS 4" << endl; // TODO: add support for nested block quotes
+}
+
+void ManDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ if (!m_firstCol) m_t << endl;
+ m_t << ".RE" << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+}
+
+void ManDocVisitor::visitPre(DocVhdlFlow *)
+{
+}
+
+void ManDocVisitor::visitPost(DocVhdlFlow *)
+{
+}
+
+void ManDocVisitor::visitPre(DocParBlock *)
+{
+}
+
+void ManDocVisitor::visitPost(DocParBlock *)
+{
+}
+
+
+void ManDocVisitor::filter(const char *str)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c=0;
+ while ((c=*p++))
+ {
+ switch(c)
+ {
+ case '.': m_t << "\\&."; break; // see bug652277
+ case '\\': m_t << "\\\\"; break;
+ case '"': c = '\''; // fall through
+ default: m_t << c; break;
+ }
+ }
+ }
+}
+
+void ManDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void ManDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h
new file mode 100644
index 0000000..a5906d0
--- /dev/null
+++ b/src/mandocvisitor.h
@@ -0,0 +1,166 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _MANDOCVISITOR_H
+#define _MANDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+
+class FTextStream;
+class CodeOutputInterface;
+
+/*! @brief Concrete visitor implementation for LaTeX output. */
+class ManDocVisitor : public DocVisitor
+{
+ public:
+ ManDocVisitor(FTextStream &t,CodeOutputInterface &ci,const char *langExt);
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *);
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *s);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *s);
+ void visitPost(DocHtmlList *s);
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *t);
+ void visitPost(DocHtmlTable *t);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *) ;
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *lnk);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *ref);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ //void visitPre(DocLanguage *);
+ //void visitPost(DocLanguage *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void filter(const char *str);
+
+ void pushEnabled();
+ void popEnabled();
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_hide;
+ bool m_firstCol;
+ int m_indent;
+ QStack<bool> m_enabled;
+ QCString m_langExt;
+};
+
+#endif
diff --git a/src/mangen.cpp b/src/mangen.cpp
new file mode 100644
index 0000000..352ef15
--- /dev/null
+++ b/src/mangen.cpp
@@ -0,0 +1,837 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/* http://www.cubic.org/source/archive/fileform/txt/man/ has some
+ nice introductions to groff and man pages. */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include "message.h"
+#include "mangen.h"
+#include "config.h"
+#include "util.h"
+#include "doxygen.h"
+#include <string.h>
+#include "docparser.h"
+#include "mandocvisitor.h"
+#include "language.h"
+
+static QCString getExtension()
+{
+ /*
+ * [.][nuber][rest]
+ * in case of . missing, just ignore it
+ * in case number missing, just place a 3 in front of it
+ */
+ QCString ext = Config_getString("MAN_EXTENSION");
+ if (ext.isEmpty())
+ {
+ ext = "3";
+ }
+ else
+ {
+ if (ext.at(0)=='.')
+ {
+ if (ext.length()==1)
+ {
+ ext = "3";
+ }
+ else // strip .
+ {
+ ext = ext.mid(1);
+ }
+ }
+ if (ext.at(0)<'0' || ext.at(0)>'9')
+ {
+ ext.prepend("3");
+ }
+ }
+ return ext;
+}
+
+static QCString getSubdir()
+{
+ QCString dir = Config_getString("MAN_SUBDIR");
+ if (dir.isEmpty())
+ {
+ dir = "man" + getExtension();
+ }
+ return dir;
+}
+
+ManGenerator::ManGenerator() : OutputGenerator()
+{
+ dir=Config_getString("MAN_OUTPUT") + "/" + getSubdir();
+ firstCol=TRUE;
+ paragraph=TRUE;
+ col=0;
+ upperCase=FALSE;
+ insideTabbing=FALSE;
+ inHeader=FALSE;
+}
+
+ManGenerator::~ManGenerator()
+{
+}
+
+//void ManGenerator::append(const OutputGenerator *g)
+//{
+// QCString r=g->getContents();
+// if (upperCase)
+// t << r.upper();
+// else
+// t << r;
+// if (!r.isEmpty())
+// firstCol = r.at(r.length()-1)=='\n';
+// else
+// firstCol = ((ManGenerator *)g)->firstCol;
+// col+=((ManGenerator *)g)->col;
+// inHeader=((ManGenerator *)g)->inHeader;
+// paragraph=FALSE;
+//}
+
+void ManGenerator::init()
+{
+ QCString ext = getExtension();
+ QCString &manOutput = Config_getString("MAN_OUTPUT");
+
+ QDir d(manOutput);
+ if (!d.exists() && !d.mkdir(manOutput))
+ {
+ err("Could not create output directory %s\n",manOutput.data());
+ exit(1);
+ }
+ d.setPath(manOutput + "/" + getSubdir());
+ if (!d.exists() && !d.mkdir(manOutput + "/" + getSubdir()))
+ {
+ err("Could not create output directory %s/%s\n",manOutput.data(), getSubdir().data());
+ exit(1);
+ }
+ createSubDirs(d);
+}
+
+static QCString buildFileName(const char *name)
+{
+ QCString fileName;
+ if (name==0) return "noname";
+
+ const char *p=name;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case ':':
+ fileName+="_";
+ if (*p==':') p++;
+ break;
+ case '<':
+ case '>':
+ case '&':
+ case '*':
+ case '!':
+ case '^':
+ case '~':
+ case '%':
+ case '+':
+ case '/':
+ fileName+="_";
+ break;
+ default:
+ fileName+=c;
+ }
+ }
+
+ QCString manExtension = "." + getExtension();
+ if (fileName.right(manExtension.length())!=manExtension)
+ {
+ fileName+=manExtension;
+ }
+
+ return fileName;
+}
+
+void ManGenerator::startFile(const char *,const char *manName,const char *)
+{
+ startPlainFile( buildFileName( manName ) );
+ firstCol=TRUE;
+}
+
+void ManGenerator::endFile()
+{
+ t << endl;
+ endPlainFile();
+}
+
+void ManGenerator::endTitleHead(const char *,const char *name)
+{
+ t << ".TH \"" << name << "\" " << getExtension() << " \""
+ << dateToString(FALSE) << "\" \"";
+ if (!Config_getString("PROJECT_NUMBER").isEmpty())
+ t << "Version " << Config_getString("PROJECT_NUMBER") << "\" \"";
+ if (Config_getString("PROJECT_NAME").isEmpty())
+ t << "Doxygen";
+ else
+ t << Config_getString("PROJECT_NAME");
+ t << "\" \\\" -*- nroff -*-" << endl;
+ t << ".ad l" << endl;
+ t << ".nh" << endl;
+ t << ".SH NAME" << endl;
+ t << name << " \\- ";
+ firstCol=FALSE;
+ inHeader=TRUE;
+}
+
+void ManGenerator::newParagraph()
+{
+ if (!paragraph)
+ {
+ if (!firstCol) t << endl;
+ t << ".PP" << endl;
+ firstCol=TRUE;
+ }
+ paragraph=TRUE;
+}
+
+void ManGenerator::startParagraph()
+{
+ if (!paragraph)
+ {
+ if (!firstCol) t << endl;
+ t << ".PP" << endl;
+ firstCol=TRUE;
+ }
+ paragraph=TRUE;
+}
+
+void ManGenerator::endParagraph()
+{
+}
+
+void ManGenerator::writeString(const char *text)
+{
+ docify(text);
+}
+
+void ManGenerator::startIndexItem(const char *,const char *)
+{
+}
+
+void ManGenerator::endIndexItem(const char *,const char *)
+{
+}
+
+void ManGenerator::writeStartAnnoItem(const char *,const char *,
+ const char *,const char *)
+{
+}
+
+void ManGenerator::writeObjectLink(const char *,const char *,
+ const char *, const char *name)
+{
+ startBold(); docify(name); endBold();
+}
+
+void ManGenerator::writeCodeLink(const char *,const char *,
+ const char *, const char *name,
+ const char *)
+{
+ docify(name);
+}
+
+void ManGenerator::startHtmlLink(const char *)
+{
+}
+
+void ManGenerator::endHtmlLink()
+{
+}
+
+//void ManGenerator::writeMailLink(const char *url)
+//{
+// docify(url);
+//}
+
+void ManGenerator::startGroupHeader(int)
+{
+ if (!firstCol) t << endl;
+ t << ".SH \"";
+ upperCase=TRUE;
+ firstCol=FALSE;
+}
+
+void ManGenerator::endGroupHeader(int)
+{
+ t << "\"\n.PP " << endl;
+ firstCol=TRUE;
+ paragraph=TRUE;
+ upperCase=FALSE;
+}
+
+void ManGenerator::startMemberHeader(const char *)
+{
+ if (!firstCol) t << endl;
+ t << ".SS \"";
+}
+
+void ManGenerator::endMemberHeader()
+{
+ t << "\"\n";
+ firstCol=TRUE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::docify(const char *str)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c=0;
+ while ((c=*p++))
+ {
+ switch(c)
+ {
+ case '.': t << "\\&."; break; // see bug652277
+ case '\\': t << "\\\\"; col++; break;
+ case '\n': t << "\n"; col=0; break;
+ case '\"': c = '\''; // no break!
+ default: t << c; col++; break;
+ }
+ }
+ firstCol=(c=='\n');
+ //printf("%s",str);fflush(stdout);
+ }
+ paragraph=FALSE;
+}
+
+void ManGenerator::codify(const char *str)
+{
+ //static char spaces[]=" ";
+ if (str)
+ {
+ const char *p=str;
+ char c;
+ int spacesToNextTabStop;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '.': t << "\\&."; break; // see bug652277
+ case '\t': spacesToNextTabStop =
+ Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
+ t << Doxygen::spaces.left(spacesToNextTabStop);
+ col+=spacesToNextTabStop;
+ break;
+ case '\n': t << "\n"; firstCol=TRUE; col=0; break;
+ case '\\': t << "\\"; col++; break;
+ case '\"': c = '\''; // no break!
+ default: p=writeUtf8Char(t,p-1); firstCol=FALSE; col++; break;
+ }
+ }
+ //printf("%s",str);fflush(stdout);
+ }
+ paragraph=FALSE;
+}
+
+void ManGenerator::writeChar(char c)
+{
+ firstCol=(c=='\n');
+ if (firstCol) col=0; else col++;
+ switch (c)
+ {
+ case '\\': t << "\\\\"; break;
+ case '\"': c = '\''; // no break!
+ default: t << c; break;
+ }
+ //printf("%c",c);fflush(stdout);
+ paragraph=FALSE;
+}
+
+void ManGenerator::startDescList(SectionTypes)
+{
+ if (!firstCol)
+ { t << endl << ".PP" << endl;
+ firstCol=TRUE; paragraph=TRUE;
+ col=0;
+ }
+ paragraph=FALSE;
+ startBold();
+}
+
+void ManGenerator::startTitle()
+{
+ if (!firstCol) t << endl;
+ t << ".SH \"";
+ firstCol=FALSE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::endTitle()
+{
+ t << "\"";
+}
+
+void ManGenerator::startItemListItem()
+{
+ if (!firstCol) t << endl;
+ t << ".TP" << endl;
+ firstCol=TRUE;
+ paragraph=FALSE;
+ col=0;
+}
+
+void ManGenerator::endItemListItem()
+{
+}
+
+void ManGenerator::startCodeFragment()
+{
+ newParagraph();
+ t << ".nf" << endl;
+ firstCol=TRUE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::endCodeFragment()
+{
+ if (!firstCol) t << endl;
+ t << ".fi" << endl;
+ firstCol=TRUE;
+ paragraph=FALSE;
+ col=0;
+}
+
+void ManGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool)
+{
+ if (!firstCol) t << endl;
+ t << ".SS \"";
+ firstCol=FALSE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::startDoxyAnchor(const char *,const char *manName,
+ const char *, const char *name,
+ const char *)
+{
+ // something to be done?
+ if( !Config_getBool("MAN_LINKS") )
+ {
+ return; // no
+ }
+
+ // the name of the link file is derived from the name of the anchor:
+ // - truncate after an (optional) ::
+ QCString baseName = name;
+ int i=baseName.findRev("::");
+ if (i!=-1) baseName=baseName.right(baseName.length()-i-2);
+
+ //printf("Converting man link '%s'->'%s'->'%s'\n",
+ // name,baseName.data(),buildFileName(baseName).data());
+
+ // - remove dangerous characters and append suffix, then add dir prefix
+ QCString fileName=dir+"/"+buildFileName( baseName );
+ QFile linkfile( fileName );
+ // - only create file if it doesn't exist already
+ if ( !linkfile.open( IO_ReadOnly ) )
+ {
+ if ( linkfile.open( IO_WriteOnly ) )
+ {
+ FTextStream linkstream;
+ linkstream.setDevice(&linkfile);
+ //linkstream.setEncoding(QTextStream::UnicodeUTF8);
+ linkstream << ".so " << getSubdir() << "/" << buildFileName( manName ) << endl;
+ }
+ }
+ linkfile.close();
+}
+
+void ManGenerator::endMemberDoc(bool)
+{
+ t << "\"\n";
+}
+
+void ManGenerator::startSubsection()
+{
+ if (!firstCol) t << endl;
+ t << ".SS \"";
+ firstCol=FALSE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::endSubsection()
+{
+ t << "\"";
+}
+
+
+void ManGenerator::startSubsubsection()
+{
+ if (!firstCol) t << endl;
+ t << "\n.SS \"";
+ firstCol=FALSE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::endSubsubsection()
+{
+ t << "\"";
+}
+
+void ManGenerator::writeSynopsis()
+{
+ if (!firstCol) t << endl;
+ t << ".SH SYNOPSIS\n.br\n.PP\n";
+ firstCol=TRUE;
+ paragraph=FALSE;
+}
+
+void ManGenerator::startDescItem()
+{
+ if (!firstCol) t << endl;
+ t << ".IP \"";
+ firstCol=FALSE;
+}
+
+//void ManGenerator::endDescTitle()
+//{
+// endBold();
+// paragraph=TRUE;
+//}
+
+void ManGenerator::startDescForItem()
+{
+ if (!firstCol) t << endl;
+ if (!paragraph) t << ".in -1c" << endl;
+ t << ".in +1c" << endl;
+ firstCol=TRUE;
+ paragraph=FALSE;
+ col=0;
+}
+
+void ManGenerator::endDescForItem()
+{
+}
+
+void ManGenerator::endDescItem()
+{
+ t << "\" 1c" << endl;
+ firstCol=TRUE;
+}
+
+void ManGenerator::startAnonTypeScope(int indentLevel)
+{
+ if (indentLevel==0)
+ {
+ insideTabbing=TRUE;
+ }
+}
+
+void ManGenerator::endAnonTypeScope(int indentLevel)
+{
+ if (indentLevel==0)
+ {
+ insideTabbing=FALSE;
+ }
+}
+
+
+void ManGenerator::startMemberItem(const char *,int,const char *)
+{
+ if (firstCol && !insideTabbing) t << ".in +1c\n";
+ t << "\n.ti -1c\n.RI \"";
+ firstCol=FALSE;
+}
+
+void ManGenerator::endMemberItem()
+{
+ t << "\"\n.br";
+}
+
+void ManGenerator::startMemberList()
+{
+ if (!insideTabbing)
+ {
+ t << "\n.in +1c"; firstCol=FALSE;
+ }
+}
+
+void ManGenerator::endMemberList()
+{
+ if (!insideTabbing)
+ {
+ t << "\n.in -1c"; firstCol=FALSE;
+ }
+}
+
+void ManGenerator::startMemberGroupHeader(bool)
+{
+ t << "\n.PP\n.RI \"\\fB";
+}
+
+void ManGenerator::endMemberGroupHeader()
+{
+ t << "\\fP\"\n.br\n";
+ firstCol=TRUE;
+}
+
+void ManGenerator::startMemberGroupDocs()
+{
+}
+
+void ManGenerator::endMemberGroupDocs()
+{
+ t << "\n.PP";
+}
+
+void ManGenerator::startMemberGroup()
+{
+ t << "\n.in +1c";
+}
+
+void ManGenerator::endMemberGroup(bool)
+{
+ t << "\n.in -1c";
+ firstCol=FALSE;
+}
+
+void ManGenerator::startSection(const char *,const char *,SectionInfo::SectionType type)
+{
+ if( !inHeader )
+ {
+ switch(type)
+ {
+ case SectionInfo::Page: startGroupHeader(FALSE); break;
+ case SectionInfo::Section: startGroupHeader(FALSE); break;
+ case SectionInfo::Subsection: startMemberHeader(0); break;
+ case SectionInfo::Subsubsection: startMemberHeader(0); break;
+ case SectionInfo::Paragraph: startMemberHeader(0); break;
+ default: ASSERT(0); break;
+ }
+ }
+}
+
+void ManGenerator::endSection(const char *,SectionInfo::SectionType type)
+{
+ if( !inHeader )
+ {
+ switch(type)
+ {
+ case SectionInfo::Page: endGroupHeader(0); break;
+ case SectionInfo::Section: endGroupHeader(0); break;
+ case SectionInfo::Subsection: endMemberHeader(); break;
+ case SectionInfo::Subsubsection: endMemberHeader(); break;
+ case SectionInfo::Paragraph: endMemberHeader(); break;
+ default: ASSERT(0); break;
+ }
+ }
+ else
+ {
+ t << "\n";
+ firstCol=TRUE;
+ paragraph=FALSE;
+ inHeader=FALSE;
+ }
+}
+
+void ManGenerator::startSimpleSect(SectionTypes,const char *,
+ const char *,const char *title)
+{
+ if (!firstCol)
+ { t << endl << ".PP" << endl;
+ firstCol=TRUE; paragraph=TRUE;
+ col=0;
+ }
+ paragraph=FALSE;
+ startBold();
+ docify(title);
+ endBold();
+ paragraph=TRUE;
+}
+
+void ManGenerator::endSimpleSect()
+{
+}
+
+void ManGenerator::startParamList(ParamListTypes,const char *title)
+{
+ if (!firstCol)
+ { t << endl << ".PP" << endl;
+ firstCol=TRUE; paragraph=TRUE;
+ col=0;
+ }
+ paragraph=FALSE;
+ startBold();
+ docify(title);
+ endBold();
+ paragraph=TRUE;
+}
+
+void ManGenerator::endParamList()
+{
+}
+
+void ManGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
+{
+ ManDocVisitor *visitor = new ManDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""));
+ n->accept(visitor);
+ delete visitor;
+ firstCol=FALSE;
+ paragraph = FALSE;
+}
+
+void ManGenerator::startConstraintList(const char *header)
+{
+ if (!firstCol)
+ { t << endl << ".PP" << endl;
+ firstCol=TRUE; paragraph=TRUE;
+ col=0;
+ }
+ paragraph=FALSE;
+ startBold();
+ docify(header);
+ endBold();
+ paragraph=TRUE;
+}
+
+void ManGenerator::startConstraintParam()
+{
+ startItemListItem();
+ startEmphasis();
+}
+
+void ManGenerator::endConstraintParam()
+{
+ endEmphasis();
+ endItemListItem();
+ t << " : ";
+}
+
+void ManGenerator::startConstraintType()
+{
+ startEmphasis();
+}
+
+void ManGenerator::endConstraintType()
+{
+ endEmphasis();
+}
+
+void ManGenerator::startConstraintDocs()
+{
+}
+
+void ManGenerator::endConstraintDocs()
+{
+ t << endl; firstCol=TRUE;
+}
+
+void ManGenerator::endConstraintList()
+{
+}
+
+
+void ManGenerator::startInlineHeader()
+{
+ if (!firstCol)
+ {
+ t << endl << ".PP" << endl << ".in -1c" << endl;
+ }
+ t << ".RI \"\\fB";
+}
+
+void ManGenerator::endInlineHeader()
+{
+ t << "\\fP\"" << endl << ".in +1c" << endl;
+ firstCol = FALSE;
+}
+
+void ManGenerator::startMemberDocSimple()
+{
+ if (!firstCol)
+ {
+ t << endl << ".PP" << endl;
+ }
+ t << "\\fB";
+ docify(theTranslator->trCompoundMembers());
+ t << ":\\fP" << endl;
+ t << ".RS 4" << endl;
+}
+
+void ManGenerator::endMemberDocSimple()
+{
+ if (!firstCol) t << endl;
+ t << ".RE" << endl;
+ t << ".PP" << endl;
+ firstCol=TRUE;
+}
+
+void ManGenerator::startInlineMemberType()
+{
+}
+
+void ManGenerator::endInlineMemberType()
+{
+ t << " ";
+}
+
+void ManGenerator::startInlineMemberName()
+{
+ t << "\\fI";
+}
+
+void ManGenerator::endInlineMemberName()
+{
+ t << "\\fP ";
+}
+
+void ManGenerator::startInlineMemberDoc()
+{
+}
+
+void ManGenerator::endInlineMemberDoc()
+{
+ if (!firstCol) t << endl;
+ t << ".br" << endl;
+ t << ".PP" << endl;
+ firstCol=TRUE;
+}
+
+void ManGenerator::startLabels()
+{
+}
+
+void ManGenerator::writeLabel(const char *l,bool isLast)
+{
+ t << "\\fC [" << l << "]\\fP";
+ if (!isLast) t << ", ";
+}
+
+void ManGenerator::endLabels()
+{
+}
+
+void ManGenerator::endHeaderSection()
+{
+ if (!firstCol)
+ {
+ t<< endl; firstCol=TRUE;
+ }
+}
+
+
diff --git a/src/mangen.h b/src/mangen.h
new file mode 100644
index 0000000..98ef959
--- /dev/null
+++ b/src/mangen.h
@@ -0,0 +1,276 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MANGEN_H
+#define MANGEN_H
+
+#include "outputgen.h"
+
+class QFile;
+
+/** Generator for Man page output. */
+class ManGenerator : public OutputGenerator
+{
+ public:
+ ManGenerator();
+ ~ManGenerator();
+
+ //OutputGenerator *copy() { return new ManGenerator; }
+ //OutputGenerator *clone() { return new ManGenerator(*this); }
+ //void append(const OutputGenerator *o);
+ void enable()
+ { if (genStack->top()) active=*genStack->top(); else active=TRUE; }
+ void disable() { active=FALSE; }
+ void enableIf(OutputType o) { if (o==Man) enable(); }
+ void disableIf(OutputType o) { if (o==Man) disable(); }
+ void disableIfNot(OutputType o) { if (o!=Man) disable(); }
+ bool isEnabled(OutputType o) { return (o==Man && active); }
+ OutputGenerator *get(OutputType o) { return (o==Man) ? this : 0; }
+
+ void writeDoc(DocNode *,Definition *,MemberDef *);
+
+ static void init();
+ void startFile(const char *name,const char *manName,const char *title);
+ void writeSearchInfo() {}
+ void writeFooter(const char *) {}
+ void endFile();
+ void clearBuffer();
+
+ void startIndexSection(IndexSections) {}
+ void endIndexSection(IndexSections) {}
+ void writePageLink(const char *,bool) {}
+ void startProjectNumber() {}
+ void endProjectNumber() {}
+ void writeStyleInfo(int) {}
+ void startTitleHead(const char *) {}
+ void endTitleHead(const char *,const char *);
+ void startTitle();
+ void endTitle();
+
+ void newParagraph();
+ void startParagraph();
+ void endParagraph();
+ void writeString(const char *text);
+ void startIndexListItem() {}
+ void endIndexListItem() {}
+ void startIndexList() {}
+ void endIndexList() { newParagraph(); }
+ void startIndexKey() {}
+ void endIndexKey() {}
+ void startIndexValue(bool) {}
+ void endIndexValue(const char *,bool) {}
+ void startItemList() {}
+ void endItemList() { newParagraph(); }
+ void startIndexItem(const char *ref,const char *file);
+ void endIndexItem(const char *ref,const char *file);
+ void docify(const char *text);
+ void codify(const char *text);
+ void writeObjectLink(const char *ref,const char *file,
+ const char *anchor,const char *name);
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ ) {}
+ void startTextLink(const char *,const char *) {}
+ void endTextLink() {}
+ void startHtmlLink(const char *url);
+ void endHtmlLink();
+ void startTypewriter() { t << "\\fC"; firstCol=FALSE; }
+ void endTypewriter() { t << "\\fP"; firstCol=FALSE; }
+ void startGroupHeader(int);
+ void endGroupHeader(int);
+ void startMemberSections() {}
+ void endMemberSections() {}
+ void startHeaderSection() {}
+ void endHeaderSection();
+ void startMemberHeader(const char *);
+ void endMemberHeader();
+ void insertMemberAlign(bool) {}
+ void startMemberSubtitle() {}
+ void endMemberSubtitle() {}
+ //void writeListItem();
+ void startItemListItem();
+ void endItemListItem();
+ void startMemberDocList() {}
+ void endMemberDocList() {}
+ void startMemberList();
+ void endMemberList();
+ void startInlineHeader();
+ void endInlineHeader();
+ void startAnonTypeScope(int);
+ void endAnonTypeScope(int);
+ void startMemberItem(const char *,int,const char *);
+ void endMemberItem();
+ void startMemberTemplateParams() {}
+ void endMemberTemplateParams(const char *,const char *) {}
+
+ void startMemberGroupHeader(bool);
+ void endMemberGroupHeader();
+ void startMemberGroupDocs();
+ void endMemberGroupDocs();
+ void startMemberGroup();
+ void endMemberGroup(bool);
+
+ void writeRuler() {}
+ void writeAnchor(const char *,const char *) {}
+ void startCodeFragment();
+ void endCodeFragment();
+ void writeLineNumber(const char *,const char *,const char *,int l) { t << l << " "; }
+ void startCodeLine(bool) {}
+ void endCodeLine() { codify("\n"); col=0; }
+ void startEmphasis() { t << "\\fI"; firstCol=FALSE; }
+ void endEmphasis() { t << "\\fP"; firstCol=FALSE; }
+ void startBold() { t << "\\fB"; firstCol=FALSE; }
+ void endBold() { t << "\\fP"; firstCol=FALSE; }
+ void startDescription() {}
+ void endDescription() {}
+ void startDescItem();
+ void endDescItem();
+ void lineBreak(const char *) { t << "\n.br" << endl; }
+ void writeChar(char c);
+ void startMemberDoc(const char *,const char *,const char *,const char *,bool);
+ void endMemberDoc(bool);
+ void startDoxyAnchor(const char *,const char *,const char *,const char *,const char *);
+ void endDoxyAnchor(const char *,const char *) {}
+ void writeLatexSpacing() {}
+ void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name);
+ void writeEndAnnoItem(const char *) { t << endl; firstCol=TRUE; }
+ void startSubsection();
+ void endSubsection();
+ void startSubsubsection();
+ void endSubsubsection();
+ void startCenter() {}
+ void endCenter() {}
+ void startSmall() {}
+ void endSmall() {}
+ void startMemberDescription(const char *,const char *) { t << "\n.RI \"\\fI"; firstCol=FALSE; }
+ void endMemberDescription() { t << "\\fP\""; firstCol=FALSE; }
+ void startMemberDeclaration() {}
+ void endMemberDeclaration(const char *,const char *) {}
+ void writeInheritedSectionTitle(const char *,const char *,const char *,
+ const char *,const char *,const char *) {}
+ void startDescList(SectionTypes);
+ void endDescList() {}
+ void startSimpleSect(SectionTypes,const char *,const char *,const char *);
+ void endSimpleSect();
+ void startParamList(ParamListTypes,const char *title);
+ void endParamList();
+ //void writeDescItem();
+ void startDescForItem();
+ void endDescForItem();
+ void startSection(const char *,const char *,SectionInfo::SectionType);
+ void endSection(const char *,SectionInfo::SectionType);
+ void addIndexItem(const char *,const char *) {}
+ void startIndent() {}
+ void endIndent() {}
+ void writeSynopsis();
+ void startClassDiagram() {}
+ void endClassDiagram(const ClassDiagram &,const char *,const char *) {}
+ void startPageRef() {}
+ void endPageRef(const char *,const char *) {}
+ void startQuickIndices() {}
+ void endQuickIndices() {}
+ void writeSplitBar(const char *) {}
+ void writeNavigationPath(const char *) {}
+ void writeLogo() {}
+ void writeQuickLinks(bool,HighlightedItem,const char *) {}
+ void writeSummaryLink(const char *,const char *,const char *,bool) {}
+ void startContents() {}
+ void endContents() {}
+ void writeNonBreakableSpace(int n) { int i; for (i=0;i<n;i++) t << " "; }
+
+ void startDescTable(const char *t)
+ { startSimpleSect(EnumValues,0,0,t); startDescForItem(); }
+ void endDescTable() { endDescForItem(); endSimpleSect(); }
+ void startDescTableTitle() { startItemListItem(); startBold(); startEmphasis(); endItemListItem(); }
+ void endDescTableTitle() { endEmphasis(); endBold(); }
+ void startDescTableData() { t << endl; firstCol=TRUE; }
+ void endDescTableData() {}
+
+ void startDotGraph() {}
+ void endDotGraph(const DotClassGraph &) {}
+ void startInclDepGraph() {}
+ void endInclDepGraph(const DotInclDepGraph &) {}
+ void startGroupCollaboration() {}
+ void endGroupCollaboration(const DotGroupCollaboration &) {}
+ void startCallGraph() {}
+ void endCallGraph(const DotCallGraph &) {}
+ void startDirDepGraph() {}
+ void endDirDepGraph(const DotDirDeps &) {}
+ void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {}
+
+ void startTextBlock(bool) {}
+ void endTextBlock(bool) {}
+ void lastIndexPage() {}
+
+ void startMemberDocPrefixItem() {}
+ void endMemberDocPrefixItem() {}
+ void startMemberDocName(bool) {}
+ void endMemberDocName() {}
+ void startParameterType(bool,const char *) {}
+ void endParameterType() {}
+ void startParameterName(bool) {}
+ void endParameterName(bool,bool,bool) {}
+ void startParameterList(bool) {}
+ void endParameterList() {}
+ void exceptionEntry(const char*,bool) {}
+
+ void startFontClass(const char *) {}
+ void endFontClass() {}
+
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
+ void startMemberDocSimple();
+ void endMemberDocSimple();
+ void startInlineMemberType();
+ void endInlineMemberType();
+ void startInlineMemberName();
+ void endInlineMemberName();
+ void startInlineMemberDoc();
+ void endInlineMemberDoc();
+
+ void startLabels();
+ void writeLabel(const char *l,bool isLast);
+ void endLabels();
+
+ void writeCodeAnchor(const char *) {}
+ void setCurrentDoc(Definition *,const char *,bool) {}
+ void addWord(const char *,bool) {}
+
+ private:
+ bool firstCol;
+ bool paragraph;
+ int col;
+ bool upperCase;
+ bool insideTabbing;
+ bool inHeader;
+
+ ManGenerator(const ManGenerator &g);
+ ManGenerator &operator=(const ManGenerator &g);
+};
+
+#endif
diff --git a/src/markdown.cpp b/src/markdown.cpp
new file mode 100644
index 0000000..cc86af4
--- /dev/null
+++ b/src/markdown.cpp
@@ -0,0 +1,2455 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/* Note: part of the code below is inspired by libupskirt written by
+ * Natacha Porté. Original copyright message follows:
+ *
+ * Copyright (c) 2008, Natacha Porté
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <qglobal.h>
+#include <qregexp.h>
+#include <qfileinfo.h>
+#include <qdict.h>
+
+#include "markdown.h"
+#include "growbuf.h"
+#include "debug.h"
+#include "util.h"
+#include "doxygen.h"
+#include "commentscan.h"
+#include "entry.h"
+#include "bufstr.h"
+#include "commentcnv.h"
+#include "config.h"
+#include "section.h"
+#include "message.h"
+
+//-----------
+
+// is character at position i in data part of an identifier?
+#define isIdChar(i) \
+ ((data[i]>='a' && data[i]<='z') || \
+ (data[i]>='A' && data[i]<='Z') || \
+ (data[i]>='0' && data[i]<='9')) \
+
+// is character at position i in data allowed before an emphasis section
+#define isOpenEmphChar(i) \
+ (data[i]=='\n' || data[i]==' ' || data[i]=='\'' || data[i]=='<' || \
+ data[i]=='{' || data[i]=='(' || data[i]=='[' || data[i]==',' || \
+ data[i]==':' || data[i]==';')
+
+// is character at position i in data an escape that prevents ending an emphasis section
+// so for example *bla (*.txt) is cool*
+#define ignoreCloseEmphChar(i) \
+ (data[i]=='(' || data[i]=='{' || data[i]=='[' || data[i]=='<' || \
+ data[i]=='=' || data[i]=='+' || data[i]=='-' || data[i]=='\\' || \
+ data[i]=='@')
+
+//----------
+
+struct LinkRef
+{
+ LinkRef(const QCString &l,const QCString &t) : link(l), title(t) {}
+ QCString link;
+ QCString title;
+};
+
+typedef int (*action_t)(GrowBuf &out,const char *data,int offset,int size);
+
+enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight };
+
+
+//----------
+
+static QDict<LinkRef> g_linkRefs(257);
+static action_t g_actions[256];
+static Entry *g_current;
+static QCString g_fileName;
+static int g_lineNr;
+
+// In case a markdown page starts with a level1 header, that header is used
+// as a title of the page, in effect making it a level0 header, so the
+// level of all other sections needs to be corrected as well.
+// This flag is TRUE if corrections are needed.
+//static bool g_correctSectionLevel;
+
+
+//----------
+
+const int codeBlockIndent = 4;
+
+static void processInline(GrowBuf &out,const char *data,int size);
+
+// escape characters that have a special meaning later on.
+static QCString escapeSpecialChars(const QCString &s)
+{
+ if (s.isEmpty()) return "";
+ GrowBuf growBuf;
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '<': growBuf.addStr("\\<"); break;
+ case '>': growBuf.addStr("\\>"); break;
+ case '\\': growBuf.addStr("\\\\"); break;
+ case '@': growBuf.addStr("\\@"); break;
+ default: growBuf.addChar(c); break;
+ }
+ }
+ growBuf.addChar(0);
+ return growBuf.get();
+}
+
+static void convertStringFragment(QCString &result,const char *data,int size)
+{
+ if (size<0) size=0;
+ result.resize(size+1);
+ memcpy(result.data(),data,size);
+ result.at(size)='\0';
+}
+
+/** helper function to convert presence of left and/or right alignment markers
+ * to a alignment value
+ */
+static Alignment markersToAlignment(bool leftMarker,bool rightMarker)
+{
+ //printf("markerToAlignment(%d,%d)\n",leftMarker,rightMarker);
+ if (leftMarker && rightMarker)
+ {
+ return AlignCenter;
+ }
+ else if (leftMarker)
+ {
+ return AlignLeft;
+ }
+ else if (rightMarker)
+ {
+ return AlignRight;
+ }
+ else
+ {
+ return AlignNone;
+ }
+}
+
+
+// Check if data contains a block command. If so returned the command
+// that ends the block. If not an empty string is returned.
+// Note When offset>0 character position -1 will be inspected.
+//
+// Checks for and skip the following block commands:
+// {@code .. { .. } .. }
+// \dot .. \enddot
+// \code .. \endcode
+// \msc .. \endmsc
+// \f$..\f$
+// \f[..\f]
+// \f{..\f}
+// \verbatim..\endverbatim
+// \latexonly..\endlatexonly
+// \htmlonly..\endhtmlonly
+// \xmlonly..\endxmlonly
+// \rtfonly..\endrtfonly
+// \manonly..\endmanonly
+static QCString isBlockCommand(const char *data,int offset,int size)
+{
+ bool openBracket = offset>0 && data[-1]=='{';
+ bool isEscaped = offset>0 && (data[-1]=='\\' || data[-1]=='@');
+ if (isEscaped) return QCString();
+
+ int end=1;
+ while (end<size && (data[end]>='a' && data[end]<='z')) end++;
+ if (end==1) return QCString();
+ QCString blockName;
+ convertStringFragment(blockName,data+1,end-1);
+ if (blockName=="code" && openBracket)
+ {
+ return "}";
+ }
+ else if (blockName=="dot" ||
+ blockName=="code" ||
+ blockName=="msc" ||
+ blockName=="verbatim" ||
+ blockName=="latexonly" ||
+ blockName=="htmlonly" ||
+ blockName=="xmlonly" ||
+ blockName=="rtfonly" ||
+ blockName=="manonly" ||
+ blockName=="docbookonly"
+ )
+ {
+ return "end"+blockName;
+ }
+ else if (blockName=="startuml")
+ {
+ return "enduml";
+ }
+ else if (blockName=="f" && end<size)
+ {
+ if (data[end]=='$')
+ {
+ return "f$";
+ }
+ else if (data[end]=='[')
+ {
+ return "f]";
+ }
+ else if (data[end]=='}')
+ {
+ return "f}";
+ }
+ }
+ return QCString();
+}
+
+/** looks for the next emph char, skipping other constructs, and
+ * stopping when either it is found, or we are at the end of a paragraph.
+ */
+static int findEmphasisChar(const char *data, int size, char c, int c_size)
+{
+ int i = 1;
+
+ while (i<size)
+ {
+ while (i<size && data[i]!=c && data[i]!='`' &&
+ data[i]!='\\' && data[i]!='@' &&
+ data[i]!='\n') i++;
+ //printf("findEmphasisChar: data=[%s] i=%d c=%c\n",data,i,data[i]);
+
+ // not counting escaped chars or characters that are unlikely
+ // to appear as the end of the emphasis char
+ if (i>0 && ignoreCloseEmphChar(i-1))
+ {
+ i++;
+ continue;
+ }
+ else
+ {
+ // get length of emphasis token
+ int len = 0;
+ while (i+len<size && data[i+len]==c)
+ {
+ len++;
+ }
+
+ if (len>0)
+ {
+ if (len!=c_size || (i<size-len && isIdChar(i+len))) // to prevent touching some_underscore_identifier
+ {
+ i=i+len;
+ continue;
+ }
+ return i; // found it
+ }
+ }
+
+ // skipping a code span
+ if (data[i]=='`')
+ {
+ int snb=0;
+ while (i<size && data[i]=='`') snb++,i++;
+
+ // find same pattern to end the span
+ int enb=0;
+ while (i<size && enb<snb)
+ {
+ if (data[i]=='`') enb++;
+ if (snb==1 && data[i]=='\'') break; // ` ended by '
+ i++;
+ }
+ }
+ else if (data[i]=='@' || data[i]=='\\')
+ { // skip over blocks that should not be processed
+ QCString endBlockName = isBlockCommand(data+i,i,size-i);
+ if (!endBlockName.isEmpty())
+ {
+ i++;
+ int l = endBlockName.length();
+ while (i<size-l)
+ {
+ if ((data[i]=='\\' || data[i]=='@') && // command
+ data[i-1]!='\\' && data[i-1]!='@') // not escaped
+ {
+ if (qstrncmp(&data[i+1],endBlockName,l)==0)
+ {
+ break;
+ }
+ }
+ i++;
+ }
+ }
+ else if (i<size-1 && isIdChar(i+1)) // @cmd, stop processing, see bug 690385
+ {
+ return 0;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ else if (data[i]=='\n') // end * or _ at paragraph boundary
+ {
+ i++;
+ while (i<size && data[i]==' ') i++;
+ if (i>=size || data[i]=='\n') return 0; // empty line -> paragraph
+ }
+ else // should not get here!
+ {
+ i++;
+ }
+
+ }
+ return 0;
+}
+
+/** process single emphasis */
+static int processEmphasis1(GrowBuf &out, const char *data, int size, char c)
+{
+ int i = 0, len;
+
+ /* skipping one symbol if coming from emph3 */
+ if (size>1 && data[0]==c && data[1]==c) { i=1; }
+
+ while (i<size)
+ {
+ len = findEmphasisChar(data+i, size-i, c, 1);
+ if (len==0) return 0;
+ i+=len;
+ if (i>=size) return 0;
+
+ if (i+1<size && data[i+1]==c)
+ {
+ i++;
+ continue;
+ }
+ if (data[i]==c && data[i-1]!=' ' && data[i-1]!='\n')
+ {
+ out.addStr("<em>");
+ processInline(out,data,i);
+ out.addStr("</em>");
+ return i+1;
+ }
+ }
+ return 0;
+}
+
+/** process double emphasis */
+static int processEmphasis2(GrowBuf &out, const char *data, int size, char c)
+{
+ int i = 0, len;
+
+ while (i<size)
+ {
+ len = findEmphasisChar(data+i, size-i, c, 2);
+ if (len==0)
+ {
+ return 0;
+ }
+ i += len;
+ if (i+1<size && data[i]==c && data[i+1]==c && i && data[i-1]!=' ' &&
+ data[i-1]!='\n'
+ )
+ {
+ out.addStr("<strong>");
+ processInline(out,data,i);
+ out.addStr("</strong>");
+ return i + 2;
+ }
+ i++;
+ }
+ return 0;
+}
+
+/** Parsing tripple emphasis.
+ * Finds the first closing tag, and delegates to the other emph
+ */
+static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
+{
+ int i = 0, len;
+
+ while (i<size)
+ {
+ len = findEmphasisChar(data+i, size-i, c, 3);
+ if (len==0)
+ {
+ return 0;
+ }
+ i+=len;
+
+ /* skip whitespace preceded symbols */
+ if (data[i]!=c || data[i-1]==' ' || data[i-1]=='\n')
+ {
+ continue;
+ }
+
+ if (i+2<size && data[i+1]==c && data[i+2]==c)
+ {
+ out.addStr("<em><strong>");
+ processInline(out,data,i);
+ out.addStr("</strong></em>");
+ return i+3;
+ }
+ else if (i+1<size && data[i+1]==c)
+ {
+ // double symbol found, handing over to emph1
+ len = processEmphasis1(out, data-2, size+2, c);
+ if (len==0)
+ {
+ return 0;
+ }
+ else
+ {
+ return len - 2;
+ }
+ }
+ else
+ {
+ // single symbol found, handing over to emph2
+ len = processEmphasis2(out, data-1, size+1, c);
+ if (len==0)
+ {
+ return 0;
+ }
+ else
+ {
+ return len - 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/** Process ndash and mdashes */
+static int processNmdash(GrowBuf &out,const char *data,int off,int size)
+{
+ // precondition: data[0]=='-'
+ int i=1;
+ int count=1;
+ if (i<size && data[i]=='-') // found --
+ {
+ count++,i++;
+ }
+ if (i<size && data[i]=='-') // found ---
+ {
+ count++,i++;
+ }
+ if (i<size && data[i]=='-') // found ----
+ {
+ count++;
+ }
+ if (count==2 && (off<8 || qstrncmp(data-8,"operator",8)!=0)) // -- => ndash
+ {
+ out.addStr("–");
+ return 2;
+ }
+ else if (count==3) // --- => ndash
+ {
+ out.addStr("—");
+ return 3;
+ }
+ // not an ndash or mdash
+ return 0;
+}
+
+/** Process quoted section "...", can contain one embedded newline */
+static int processQuoted(GrowBuf &out,const char *data,int,int size)
+{
+ int i=1;
+ int nl=0;
+ while (i<size && data[i]!='"' && nl<2)
+ {
+ if (data[i]=='\n') nl++;
+ i++;
+ }
+ if (i<size && data[i]=='"' && nl<2)
+ {
+ out.addStr(data,i+1);
+ return i+1;
+ }
+ // not a quoted section
+ return 0;
+}
+
+/** Process a HTML tag. Note that <pre>..</pre> are treated specially, in
+ * the sense that all code inside is written unprocessed
+ */
+static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size)
+{
+ if (offset>0 && data[-1]=='\\') return 0; // escaped <
+
+ // find the end of the html tag
+ int i=1;
+ int l=0;
+ // compute length of the tag name
+ while (i<size && isIdChar(i)) i++,l++;
+ QCString tagName;
+ convertStringFragment(tagName,data+1,i-1);
+ if (tagName.lower()=="pre") // found <pre> tag
+ {
+ bool insideStr=FALSE;
+ while (i<size-6)
+ {
+ char c=data[i];
+ if (!insideStr && c=='<') // potential start of html tag
+ {
+ if (data[i+1]=='/' &&
+ tolower(data[i+2])=='p' && tolower(data[i+3])=='r' &&
+ tolower(data[i+4])=='e' && tolower(data[i+5])=='>')
+ { // found </pre> tag, copy from start to end of tag
+ out.addStr(data,i+6);
+ //printf("found <pre>..</pre> [%d..%d]\n",0,i+6);
+ return i+6;
+ }
+ }
+ else if (insideStr && c=='"')
+ {
+ if (data[i-1]!='\\') insideStr=FALSE;
+ }
+ else if (c=='"')
+ {
+ insideStr=TRUE;
+ }
+ i++;
+ }
+ }
+ else // some other html tag
+ {
+ if (l>0 && i<size)
+ {
+ if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/>
+ {
+ //printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data());
+ out.addStr(data,i+2);
+ return i+2;
+ }
+ else if (data[i]=='>') // <bla>
+ {
+ //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
+ out.addStr(data,i+1);
+ return i+1;
+ }
+ else if (data[i]==' ') // <bla attr=...
+ {
+ i++;
+ bool insideAttr=FALSE;
+ while (i<size)
+ {
+ if (!insideAttr && data[i]=='"')
+ {
+ insideAttr=TRUE;
+ }
+ else if (data[i]=='"' && data[i-1]!='\\')
+ {
+ insideAttr=FALSE;
+ }
+ else if (!insideAttr && data[i]=='>') // found end of tag
+ {
+ //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
+ out.addStr(data,i+1);
+ return i+1;
+ }
+ i++;
+ }
+ }
+ }
+ }
+ //printf("Not a valid html tag\n");
+ return 0;
+}
+
+static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
+{
+ if ((offset>0 && !isOpenEmphChar(-1)) || // invalid char before * or _
+ (size>1 && data[0]!=data[1] && !isIdChar(1)) || // invalid char after * or _
+ (size>2 && data[0]==data[1] && !isIdChar(2))) // invalid char after ** or __
+ {
+ return 0;
+ }
+
+ char c = data[0];
+ int ret;
+ if (size>2 && data[1]!=c) // _bla or *bla
+ {
+ // whitespace cannot follow an opening emphasis
+ if (data[1]==' ' || data[1]=='\n' ||
+ (ret = processEmphasis1(out, data+1, size-1, c)) == 0)
+ {
+ return 0;
+ }
+ return ret+1;
+ }
+ if (size>3 && data[1]==c && data[2]!=c) // __bla or **bla
+ {
+ if (data[2]==' ' || data[2]=='\n' ||
+ (ret = processEmphasis2(out, data+2, size-2, c)) == 0)
+ {
+ return 0;
+ }
+ return ret+2;
+ }
+ if (size>4 && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla
+ {
+ if (data[3]==' ' || data[3]=='\n' ||
+ (ret = processEmphasis3(out, data+3, size-3, c)) == 0)
+ {
+ return 0;
+ }
+ return ret+3;
+ }
+ return 0;
+}
+
+static int processLink(GrowBuf &out,const char *data,int,int size)
+{
+ QCString content;
+ QCString link;
+ QCString title;
+ int contentStart,contentEnd,linkStart,titleStart,titleEnd;
+ bool isImageLink = FALSE;
+ bool isToc = FALSE;
+ int i=1;
+ if (data[0]=='!')
+ {
+ isImageLink = TRUE;
+ if (size<2 || data[1]!='[')
+ {
+ return 0;
+ }
+ i++;
+ }
+ contentStart=i;
+ int level=1;
+ int nl=0;
+ // find the matching ]
+ while (i<size)
+ {
+ if (data[i-1]=='\\') // skip escaped characters
+ {
+ }
+ else if (data[i]=='[')
+ {
+ level++;
+ }
+ else if (data[i]==']')
+ {
+ level--;
+ if (level<=0) break;
+ }
+ else if (data[i]=='\n')
+ {
+ nl++;
+ if (nl>1) return 0; // only allow one newline in the content
+ }
+ i++;
+ }
+ if (i>=size) return 0; // premature end of comment -> no link
+ contentEnd=i;
+ convertStringFragment(content,data+contentStart,contentEnd-contentStart);
+ //printf("processLink: content={%s}\n",content.data());
+ if (!isImageLink && content.isEmpty()) return 0; // no link text
+ i++; // skip over ]
+
+ // skip whitespace
+ while (i<size && data[i]==' ') i++;
+ if (i<size && data[i]=='\n') // one newline allowed here
+ {
+ i++;
+ // skip more whitespace
+ while (i<size && data[i]==' ') i++;
+ }
+
+ bool explicitTitle=FALSE;
+ if (i<size && data[i]=='(') // inline link
+ {
+ i++;
+ while (i<size && data[i]==' ') i++;
+ if (i<size && data[i]=='<') i++;
+ linkStart=i;
+ nl=0;
+ while (i<size && data[i]!='\'' && data[i]!='"' && data[i]!=')')
+ {
+ if (data[i]=='\n')
+ {
+ nl++;
+ if (nl>1) return 0;
+ }
+ i++;
+ }
+ if (i>=size || data[i]=='\n') return 0;
+ convertStringFragment(link,data+linkStart,i-linkStart);
+ link = link.stripWhiteSpace();
+ //printf("processLink: link={%s}\n",link.data());
+ if (link.isEmpty()) return 0;
+ if (link.at(link.length()-1)=='>') link=link.left(link.length()-1);
+
+ // optional title
+ if (data[i]=='\'' || data[i]=='"')
+ {
+ char c = data[i];
+ i++;
+ titleStart=i;
+ nl=0;
+ while (i<size && data[i]!=')')
+ {
+ if (data[i]=='\n')
+ {
+ if (nl>1) return 0;
+ nl++;
+ }
+ i++;
+ }
+ if (i>=size)
+ {
+ return 0;
+ }
+ titleEnd = i-1;
+ // search back for closing marker
+ while (titleEnd>titleStart && data[titleEnd]==' ') titleEnd--;
+ if (data[titleEnd]==c) // found it
+ {
+ convertStringFragment(title,data+titleStart,titleEnd-titleStart);
+ //printf("processLink: title={%s}\n",title.data());
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ i++;
+ }
+ else if (i<size && data[i]=='[') // reference link
+ {
+ i++;
+ linkStart=i;
+ nl=0;
+ // find matching ]
+ while (i<size && data[i]!=']')
+ {
+ if (data[i]=='\n')
+ {
+ nl++;
+ if (nl>1) return 0;
+ }
+ i++;
+ }
+ if (i>=size) return 0;
+ // extract link
+ convertStringFragment(link,data+linkStart,i-linkStart);
+ //printf("processLink: link={%s}\n",link.data());
+ link = link.stripWhiteSpace();
+ if (link.isEmpty()) // shortcut link
+ {
+ link=content;
+ }
+ // lookup reference
+ LinkRef *lr = g_linkRefs.find(link.lower());
+ if (lr) // found it
+ {
+ link = lr->link;
+ title = lr->title;
+ //printf("processLink: ref: link={%s} title={%s}\n",link.data(),title.data());
+ }
+ else // reference not found!
+ {
+ //printf("processLink: ref {%s} do not exist\n",link.lower().data());
+ return 0;
+ }
+ i++;
+ }
+ else if (i<size && data[i]!=':' && !content.isEmpty()) // minimal link ref notation [some id]
+ {
+ LinkRef *lr = g_linkRefs.find(content.lower());
+ //printf("processLink: minimal link {%s} lr=%p",content.data(),lr);
+ if (lr) // found it
+ {
+ link = lr->link;
+ title = lr->title;
+ explicitTitle=TRUE;
+ i=contentEnd;
+ }
+ else if (content=="TOC")
+ {
+ isToc=TRUE;
+ i=contentEnd;
+ }
+ else
+ {
+ return 0;
+ }
+ i++;
+ }
+ else
+ {
+ return 0;
+ }
+ static QRegExp re("^[@\\]ref ");
+ if (isToc) // special case for [TOC]
+ {
+ if (g_current) g_current->stat=TRUE;
+ }
+ else if (isImageLink)
+ {
+ bool ambig;
+ FileDef *fd=0;
+ if (link.find("@ref ")!=-1 || link.find("\\ref ")!=-1 ||
+ (fd=findFileDef(Doxygen::imageNameDict,link,ambig)))
+ // assume doxygen symbol link or local image link
+ {
+ out.addStr("@image html ");
+ out.addStr(link.mid(fd ? 0 : 5));
+ if (!explicitTitle && !content.isEmpty())
+ {
+ out.addStr(" \"");
+ out.addStr(content);
+ out.addStr("\"");
+ }
+ else if ((content.isEmpty() || explicitTitle) && !title.isEmpty())
+ {
+ out.addStr(" \"");
+ out.addStr(title);
+ out.addStr("\"");
+ }
+ }
+ else
+ {
+ out.addStr("<img src=\"");
+ out.addStr(link);
+ out.addStr("\" alt=\"");
+ out.addStr(content);
+ out.addStr("\"");
+ if (!title.isEmpty())
+ {
+ out.addStr(" title=\"");
+ out.addStr(substitute(title.simplifyWhiteSpace(),"\"","""));
+ out.addStr("\"");
+ }
+ out.addStr("/>");
+ }
+ }
+ else
+ {
+ SrcLangExt lang = getLanguageFromFileName(link);
+ int lp=-1;
+ if ((lp=link.find("@ref "))!=-1 || (lp=link.find("\\ref "))!=-1 || lang==SrcLangExt_Markdown)
+ // assume doxygen symbol link
+ {
+ if (lp==-1) // link to markdown page
+ {
+ out.addStr("@ref ");
+ }
+ out.addStr(link);
+ out.addStr(" \"");
+ if (explicitTitle && !title.isEmpty())
+ {
+ out.addStr(title);
+ }
+ else
+ {
+ out.addStr(content);
+ }
+ out.addStr("\"");
+ }
+ else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1)
+ { // file/url link
+ out.addStr("<a href=\"");
+ out.addStr(link);
+ out.addStr("\"");
+ if (!title.isEmpty())
+ {
+ out.addStr(" title=\"");
+ out.addStr(substitute(title.simplifyWhiteSpace(),"\"","""));
+ out.addStr("\"");
+ }
+ out.addStr(">");
+ out.addStr(content.simplifyWhiteSpace());
+ out.addStr("</a>");
+ }
+ else // avoid link to e.g. F[x](y)
+ {
+ //printf("no link for '%s'\n",link.data());
+ return 0;
+ }
+ }
+ return i;
+}
+
+/** '`' parsing a code span (assuming codespan != 0) */
+static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int size)
+{
+ int end, nb = 0, i, f_begin, f_end;
+
+ /* counting the number of backticks in the delimiter */
+ while (nb<size && data[nb]=='`')
+ {
+ nb++;
+ }
+
+ /* finding the next delimiter */
+ i = 0;
+ int nl=0;
+ for (end=nb; end<size && i<nb && nl<2; end++)
+ {
+ if (data[end]=='`')
+ {
+ i++;
+ }
+ else if (data[end]=='\n')
+ {
+ i=0;
+ nl++;
+ }
+ else
+ {
+ i=0;
+ }
+ }
+ if (i < nb && end >= size)
+ {
+ return 0; // no matching delimiter
+ }
+ if (nl==2) // too many newlines inside the span
+ {
+ return 0;
+ }
+
+ // trimming outside whitespaces
+ f_begin = nb;
+ while (f_begin < end && data[f_begin]==' ')
+ {
+ f_begin++;
+ }
+ f_end = end - nb;
+ while (f_end > nb && data[f_end-1]==' ')
+ {
+ f_end--;
+ }
+
+ if (nb==1) // check for closing ' followed by space within f_begin..f_end
+ {
+ i=f_begin;
+ while (i<f_end-1)
+ {
+ if (data[i]=='\'' && !isIdChar(i+1)) // reject `some word' and not `it's cool`
+ {
+ return 0;
+ }
+ i++;
+ }
+ }
+ //printf("found code span '%s'\n",QCString(data+f_begin).left(f_end-f_begin).data());
+
+ /* real code span */
+ if (f_begin < f_end)
+ {
+ QCString codeFragment;
+ convertStringFragment(codeFragment,data+f_begin,f_end-f_begin);
+ out.addStr("<tt>");
+ //out.addStr(convertToHtml(codeFragment,TRUE));
+ out.addStr(escapeSpecialChars(codeFragment));
+ out.addStr("</tt>");
+ }
+ return end;
+}
+
+
+static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int size)
+{
+ int i=1;
+ QCString endBlockName = isBlockCommand(data,offset,size);
+ if (!endBlockName.isEmpty())
+ {
+ int l = endBlockName.length();
+ while (i<size-l)
+ {
+ if ((data[i]=='\\' || data[i]=='@') && // command
+ data[i-1]!='\\' && data[i-1]!='@') // not escaped
+ {
+ if (qstrncmp(&data[i+1],endBlockName,l)==0)
+ {
+ //printf("found end at %d\n",i);
+ out.addStr(data,i+1+l);
+ return i+1+l;
+ }
+ }
+ i++;
+ }
+ }
+ if (size>1 && data[0]=='\\')
+ {
+ char c=data[1];
+ if (c=='[' || c==']' || c=='*' || c=='+' || c=='-' ||
+ c=='!' || c=='(' || c==')' || c=='.' || c=='`' || c=='_')
+ {
+ if (c=='-' && size>3 && data[2]=='-' && data[3]=='-') // \---
+ {
+ out.addStr(&data[1],3);
+ return 4;
+ }
+ else if (c=='-' && size>2 && data[2]=='-') // \--
+ {
+ out.addStr(&data[1],2);
+ return 3;
+ }
+ out.addStr(&data[1],1);
+ return 2;
+ }
+ }
+ return 0;
+}
+
+static void processInline(GrowBuf &out,const char *data,int size)
+{
+ int i=0, end=0;
+ action_t action = 0;
+ while (i<size)
+ {
+ while (end<size && ((action=g_actions[(uchar)data[end]])==0)) end++;
+ out.addStr(data+i,end-i);
+ if (end>=size) break;
+ i=end;
+ end = action(out,data+i,i,size-i);
+ if (!end)
+ {
+ end=i+1;
+ }
+ else
+ {
+ i+=end;
+ end=i;
+ }
+ }
+}
+
+/** returns whether the line is a setext-style hdr underline */
+static int isHeaderline(const char *data, int size)
+{
+ int i=0, c=0;
+ while (i<size && data[i]==' ') i++;
+
+ // test of level 1 header
+ if (data[i]=='=')
+ {
+ while (i<size && data[i]=='=') i++,c++;
+ while (i<size && data[i]==' ') i++;
+ return (c>1 && (i>=size || data[i]=='\n')) ? 1 : 0;
+ }
+ // test of level 2 header
+ if (data[i]=='-')
+ {
+ while (i<size && data[i]=='-') i++,c++;
+ while (i<size && data[i]==' ') i++;
+ return (c>1 && (i>=size || data[i]=='\n')) ? 2 : 0;
+ }
+ return 0;
+}
+
+/** returns TRUE if this line starts a block quote */
+static bool isBlockQuote(const char *data,int size,int indent)
+{
+ int i = 0;
+ while (i<size && data[i]==' ') i++;
+ if (i<indent+codeBlockIndent) // could be a quotation
+ {
+ // count >'s and skip spaces
+ int level=0;
+ while (i<size && (data[i]=='>' || data[i]==' '))
+ {
+ if (data[i]=='>') level++;
+ i++;
+ }
+ // last characters should be a space or newline,
+ // so a line starting with >= does not match
+ return level>0 && i<size && ((data[i-1]==' ') || data[i]=='\n');
+ }
+ else // too much indentation -> code block
+ {
+ return FALSE;
+ }
+ //return i<size && data[i]=='>' && i<indent+codeBlockIndent;
+}
+
+/** returns end of the link ref if this is indeed a link reference. */
+static int isLinkRef(const char *data,int size,
+ QCString &refid,QCString &link,QCString &title)
+{
+ //printf("isLinkRef data={%s}\n",data);
+ // format: start with [some text]:
+ int i = 0;
+ while (i<size && data[i]==' ') i++;
+ if (i>=size || data[i]!='[') return 0;
+ i++;
+ int refIdStart=i;
+ while (i<size && data[i]!='\n' && data[i]!=']') i++;
+ if (i>=size || data[i]!=']') return 0;
+ convertStringFragment(refid,data+refIdStart,i-refIdStart);
+ if (refid.isEmpty()) return 0;
+ //printf(" isLinkRef: found refid='%s'\n",refid.data());
+ i++;
+ if (i>=size || data[i]!=':') return 0;
+ i++;
+
+ // format: whitespace* \n? whitespace* (<url> | url)
+ while (i<size && data[i]==' ') i++;
+ if (i<size && data[i]=='\n')
+ {
+ i++;
+ while (i<size && data[i]==' ') i++;
+ }
+ if (i>=size) return 0;
+
+ if (i<size && data[i]=='<') i++;
+ int linkStart=i;
+ while (i<size && data[i]!=' ' && data[i]!='\n') i++;
+ int linkEnd=i;
+ if (i<size && data[i]=='>') i++;
+ if (linkStart==linkEnd) return 0; // empty link
+ convertStringFragment(link,data+linkStart,linkEnd-linkStart);
+ //printf(" isLinkRef: found link='%s'\n",link.data());
+ if (link=="@ref" || link=="\\ref")
+ {
+ int argStart=i;
+ while (i<size && data[i]!='\n' && data[i]!='"') i++;
+ QCString refArg;
+ convertStringFragment(refArg,data+argStart,i-argStart);
+ link+=refArg;
+ }
+
+ title.resize(0);
+
+ // format: (whitespace* \n? whitespace* ( 'title' | "title" | (title) ))?
+ int eol=0;
+ while (i<size && data[i]==' ') i++;
+ if (i<size && data[i]=='\n')
+ {
+ eol=i;
+ i++;
+ while (i<size && data[i]==' ') i++;
+ }
+ if (i>=size)
+ {
+ //printf("end of isLinkRef while looking for title! i=%d\n",i);
+ return i; // end of buffer while looking for the optional title
+ }
+
+ char c = data[i];
+ if (c=='\'' || c=='"' || c=='(') // optional title present?
+ {
+ //printf(" start of title found! char='%c'\n",c);
+ i++;
+ if (c=='(') c=')'; // replace c by end character
+ int titleStart=i;
+ // search for end of the line
+ while (i<size && data[i]!='\n') i++;
+ eol = i;
+
+ // search back to matching character
+ int end=i-1;
+ while (end>titleStart && data[end]!=c) end--;
+ if (end>titleStart)
+ {
+ convertStringFragment(title,data+titleStart,end-titleStart);
+ }
+ //printf(" title found: '%s'\n",title.data());
+ }
+ while (i<size && data[i]==' ') i++;
+ //printf("end of isLinkRef: i=%d size=%d data[i]='%c' eol=%d\n",
+ // i,size,data[i],eol);
+ if (i>=size) return i; // end of buffer while ref id was found
+ else if (eol) return eol; // end of line while ref id was found
+ return 0; // invalid link ref
+}
+
+static int isHRuler(const char *data,int size)
+{
+ int i=0;
+ if (size>0 && data[size-1]=='\n') size--; // ignore newline character
+ while (i<size && data[i]==' ') i++;
+ if (i>=size) return 0; // empty line
+ char c=data[i];
+ if (c!='*' && c!='-' && c!='_')
+ {
+ return 0; // not a hrule character
+ }
+ int n=0;
+ while (i<size)
+ {
+ if (data[i]==c)
+ {
+ n++; // count rule character
+ }
+ else if (data[i]!=' ')
+ {
+ return 0; // line contains non hruler characters
+ }
+ i++;
+ }
+ return n>=3; // at least 3 characters needed for a hruler
+}
+
+static QCString extractTitleId(QCString &title)
+{
+ //static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:");
+ static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}");
+ int l=0;
+ int i = r2.match(title,0,&l);
+ if (i!=-1 && title.mid(i+l).stripWhiteSpace().isEmpty()) // found {#id} style id
+ {
+ QCString id = title.mid(i+2,l-3);
+ title = title.left(i);
+ //printf("found id='%s' title='%s'\n",id.data(),title.data());
+ return id;
+ }
+ //printf("no id found in title '%s'\n",title.data());
+ return "";
+}
+
+
+static int isAtxHeader(const char *data,int size,
+ QCString &header,QCString &id)
+{
+ int i = 0, end;
+ int level = 0, blanks=0;
+
+ // find start of header text and determine heading level
+ while (i<size && data[i]==' ') i++;
+ if (i>=size || data[i]!='#')
+ {
+ return 0;
+ }
+ while (i<size && level<6 && data[i]=='#') i++,level++;
+ while (i<size && data[i]==' ') i++,blanks++;
+ if (level==1 && blanks==0)
+ {
+ return 0; // special case to prevent #someid seen as a header (see bug 671395)
+ }
+
+ // find end of header text
+ end=i;
+ while (end<size && data[end]!='\n') end++;
+ while (end>i && (data[end-1]=='#' || data[end-1]==' ')) end--;
+
+ // store result
+ convertStringFragment(header,data+i,end-i);
+ id = extractTitleId(header);
+ if (!id.isEmpty()) // strip #'s between title and id
+ {
+ i=header.length()-1;
+ while (i>=0 && (header.at(i)=='#' || header.at(i)==' ')) i--;
+ header=header.left(i+1);
+ }
+
+ return level;
+}
+
+static int isEmptyLine(const char *data,int size)
+{
+ int i=0;
+ while (i<size)
+ {
+ if (data[i]=='\n') return TRUE;
+ if (data[i]!=' ') return FALSE;
+ i++;
+ }
+ return TRUE;
+}
+
+#define isLiTag(i) \
+ (data[(i)]=='<' && \
+ (data[(i)+1]=='l' || data[(i)+1]=='L') && \
+ (data[(i)+2]=='i' || data[(i)+2]=='I') && \
+ (data[(i)+3]=='>'))
+
+// compute the indent from the start of the input, excluding list markers
+// such as -, -#, *, +, 1., and <li>
+static int computeIndentExcludingListMarkers(const char *data,int size)
+{
+ int i=0;
+ int indent=0;
+ bool isDigit=FALSE;
+ bool isLi=FALSE;
+ bool listMarkerSkipped=FALSE;
+ while (i<size &&
+ (data[i]==' ' || // space
+ (!listMarkerSkipped && // first list marker
+ (data[i]=='+' || data[i]=='-' || data[i]=='*' || // unordered list char
+ (data[i]=='#' && i>0 && data[i-1]=='-') || // -# item
+ (isDigit=(data[i]>='1' && data[i]<='9')) || // ordered list marker?
+ (isLi=(i<size-3 && isLiTag(i))) // <li> tag
+ )
+ )
+ )
+ )
+ {
+ if (isDigit) // skip over ordered list marker '10. '
+ {
+ int j=i+1;
+ while (j<size && ((data[j]>='0' && data[j]<='9') || data[j]=='.'))
+ {
+ if (data[j]=='.') // should be end of the list marker
+ {
+ if (j<size-1 && data[j+1]==' ') // valid list marker
+ {
+ listMarkerSkipped=TRUE;
+ indent+=j+1-i;
+ i=j+1;
+ break;
+ }
+ else // not a list marker
+ {
+ break;
+ }
+ }
+ j++;
+ }
+ }
+ else if (isLi)
+ {
+ i+=3; // skip over <li>
+ indent+=3;
+ listMarkerSkipped=TRUE;
+ }
+ else if (data[i]=='-' && i<size-2 && data[i+1]=='#' && data[i+2]==' ')
+ { // case "-# "
+ listMarkerSkipped=TRUE; // only a single list marker is accepted
+ i++; // skip over #
+ indent++;
+ }
+ else if (data[i]!=' ' && i<size-1 && data[i+1]==' ')
+ { // case "- " or "+ " or "* "
+ listMarkerSkipped=TRUE; // only a single list marker is accepted
+ }
+ if (data[i]!=' ' && !listMarkerSkipped)
+ { // end of indent
+ break;
+ }
+ indent++,i++;
+ }
+ //printf("{%s}->%d\n",QCString(data).left(size).data(),indent);
+ return indent;
+}
+
+static bool isFencedCodeBlock(const char *data,int size,int refIndent,
+ QCString &lang,int &start,int &end,int &offset)
+{
+ // rules: at least 3 ~~~, end of the block same amount of ~~~'s, otherwise
+ // return FALSE
+ int i=0;
+ int indent=0;
+ int startTildes=0;
+ while (i<size && data[i]==' ') indent++,i++;
+ if (indent>=refIndent+4) return FALSE; // part of code block
+ while (i<size && data[i]=='~') startTildes++,i++;
+ if (startTildes<3) return FALSE; // not enough tildes
+ if (i<size && data[i]=='{') i++; // skip over optional {
+ int startLang=i;
+ while (i<size && (data[i]!='\n' && data[i]!='}' && data[i]!=' ')) i++;
+ convertStringFragment(lang,data+startLang,i-startLang);
+ while (i<size && data[i]!='\n') i++; // proceed to the end of the line
+ start=i;
+ while (i<size)
+ {
+ if (data[i]=='~')
+ {
+ end=i-1;
+ int endTildes=0;
+ while (i<size && data[i]=='~') endTildes++,i++;
+ while (i<size && data[i]==' ') i++;
+ if (i==size || data[i]=='\n')
+ {
+ offset=i;
+ return endTildes==startTildes;
+ }
+ }
+ i++;
+ }
+ return FALSE;
+}
+
+static bool isCodeBlock(const char *data,int offset,int size,int &indent)
+{
+ //printf("<isCodeBlock(offset=%d,size=%d,indent=%d)\n",offset,size,indent);
+ // determine the indent of this line
+ int i=0;
+ int indent0=0;
+ while (i<size && data[i]==' ') indent0++,i++;
+
+ if (indent0<codeBlockIndent)
+ {
+ //printf(">isCodeBlock: line is not indented enough %d<4\n",indent0);
+ return FALSE;
+ }
+ if (indent0>=size || data[indent0]=='\n') // empty line does not start a code block
+ {
+ //printf("only spaces at the end of a comment block\n");
+ return FALSE;
+ }
+
+ i=offset;
+ int nl=0;
+ int nl_pos[3];
+ // search back 3 lines and remember the start of lines -1 and -2
+ while (i>0 && nl<3)
+ {
+ if (data[i-offset-1]=='\n') nl_pos[nl++]=i-offset;
+ i--;
+ }
+
+ // if there are only 2 preceding lines, then line -2 starts at -offset
+ if (i==0 && nl==2) nl_pos[nl++]=-offset;
+ //printf(" nl=%d\n",nl);
+
+ if (nl==3) // we have at least 2 preceding lines
+ {
+ //printf(" positions: nl_pos=[%d,%d,%d] line[-2]='%s' line[-1]='%s'\n",
+ // nl_pos[0],nl_pos[1],nl_pos[2],
+ // QCString(data+nl_pos[1]).left(nl_pos[0]-nl_pos[1]-1).data(),
+ // QCString(data+nl_pos[2]).left(nl_pos[1]-nl_pos[2]-1).data());
+
+ // check that line -1 is empty
+ if (!isEmptyLine(data+nl_pos[1],nl_pos[0]-nl_pos[1]-1))
+ {
+ return FALSE;
+ }
+
+ // determine the indent of line -2
+ indent=computeIndentExcludingListMarkers(data+nl_pos[2],nl_pos[1]-nl_pos[2]);
+
+ //printf(">isCodeBlock local_indent %d>=%d+4=%d\n",
+ // indent0,indent2,indent0>=indent2+4);
+ // if the difference is >4 spaces -> code block
+ return indent0>=indent+codeBlockIndent;
+ }
+ else // not enough lines to determine the relative indent, use global indent
+ {
+ // check that line -1 is empty
+ if (nl==1 && !isEmptyLine(data-offset,offset-1))
+ {
+ return FALSE;
+ }
+ //printf(">isCodeBlock global indent %d>=%d+4=%d nl=%d\n",
+ // indent0,indent,indent0>=indent+4,nl);
+ return indent0>=indent+codeBlockIndent;
+ }
+}
+
+/** Finds the location of the table's contains in the string \a data.
+ * Only one line will be inspected.
+ * @param[in] data pointer to the string buffer.
+ * @param[in] size the size of the buffer.
+ * @param[out] start offset of the first character of the table content
+ * @param[out] end offset of the last character of the table content
+ * @param[out] columns number of table columns found
+ * @returns The offset until the next line in the buffer.
+ */
+int findTableColumns(const char *data,int size,int &start,int &end,int &columns)
+{
+ int i=0,n=0;
+ int eol;
+ // find start character of the table line
+ while (i<size && data[i]==' ') i++;
+ if (i<size && data[i]=='|' && data[i]!='\n') i++,n++; // leading | does not count
+ start = i;
+
+ // find end character of the table line
+ while (i<size && data[i]!='\n') i++;
+ eol=i+1;
+ i--;
+ while (i>0 && data[i]==' ') i--;
+ if (i>0 && data[i-1]!='\\' && data[i]=='|') i--,n++; // trailing or escaped | does not count
+ end = i;
+
+ // count columns between start and end
+ columns=0;
+ if (end>start)
+ {
+ i=start;
+ while (i<=end) // look for more column markers
+ {
+ if (data[i]=='|' && (i==0 || data[i-1]!='\\')) columns++;
+ if (columns==1) columns++; // first | make a non-table into a two column table
+ i++;
+ }
+ }
+ if (n==2 && columns==0) // table row has | ... |
+ {
+ columns++;
+ }
+ //printf("findTableColumns(start=%d,end=%d,columns=%d) eol=%d\n",
+ // start,end,columns,eol);
+ return eol;
+}
+
+/** Returns TRUE iff data points to the start of a table block */
+static bool isTableBlock(const char *data,int size)
+{
+ int cc0,start,end;
+
+ // the first line should have at least two columns separated by '|'
+ int i = findTableColumns(data,size,start,end,cc0);
+ if (i>=size || cc0<1)
+ {
+ //printf("isTableBlock: no |'s in the header\n");
+ return FALSE;
+ }
+
+ int cc1;
+ int ret = findTableColumns(data+i,size-i,start,end,cc1);
+ int j=i+start;
+ // separator line should consist of |, - and : and spaces only
+ while (j<=end+i)
+ {
+ if (data[j]!=':' && data[j]!='-' && data[j]!='|' && data[j]!=' ')
+ {
+ //printf("isTableBlock: invalid character '%c'\n",data[j]);
+ return FALSE; // invalid characters in table separator
+ }
+ j++;
+ }
+ if (cc1!=cc0) // number of columns should be same as previous line
+ {
+ return FALSE;
+ }
+
+ i+=ret; // goto next line
+ int cc2;
+ ret = findTableColumns(data+i,size-i,start,end,cc2);
+
+ //printf("isTableBlock: %d\n",cc1==cc2);
+ return cc1==cc2;
+}
+
+static int writeTableBlock(GrowBuf &out,const char *data,int size)
+{
+ int i=0,j,k;
+ int columns,start,end,cc;
+
+ i = findTableColumns(data,size,start,end,columns);
+
+ out.addStr("<table>");
+
+ // write table header, in range [start..end]
+ out.addStr("<tr>");
+
+ int headerStart = start;
+ int headerEnd = end;
+
+ // read cell alignments
+ int ret = findTableColumns(data+i,size-i,start,end,cc);
+ k=0;
+ Alignment *columnAlignment = new Alignment[columns];
+
+ bool leftMarker=FALSE,rightMarker=FALSE;
+ bool startFound=FALSE;
+ j=start+i;
+ while (j<=end+i)
+ {
+ if (!startFound)
+ {
+ if (data[j]==':') { leftMarker=TRUE; startFound=TRUE; }
+ if (data[j]=='-') startFound=TRUE;
+ //printf(" data[%d]=%c startFound=%d\n",j,data[j],startFound);
+ }
+ if (data[j]=='-') rightMarker=FALSE;
+ else if (data[j]==':') rightMarker=TRUE;
+ if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\')))
+ {
+ if (k<columns)
+ {
+ columnAlignment[k] = markersToAlignment(leftMarker,rightMarker);
+ //printf("column[%d] alignment=%d\n",k,columnAlignment[k]);
+ leftMarker=FALSE;
+ rightMarker=FALSE;
+ startFound=FALSE;
+ }
+ k++;
+ }
+ j++;
+ }
+ if (k<columns)
+ {
+ columnAlignment[k] = markersToAlignment(leftMarker,rightMarker);
+ //printf("column[%d] alignment=%d\n",k,columnAlignment[k]);
+ }
+ // proceed to next line
+ i+=ret;
+
+ int m=headerStart;
+ for (k=0;k<columns;k++)
+ {
+ out.addStr("<th");
+ switch (columnAlignment[k])
+ {
+ case AlignLeft: out.addStr(" align=\"left\""); break;
+ case AlignRight: out.addStr(" align=\"right\""); break;
+ case AlignCenter: out.addStr(" align=\"center\""); break;
+ case AlignNone: break;
+ }
+ out.addStr(">");
+ while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\')))
+ {
+ out.addChar(data[m++]);
+ }
+ m++;
+ }
+ out.addStr("\n</th>\n");
+
+ // write table cells
+ while (i<size)
+ {
+ int ret = findTableColumns(data+i,size-i,start,end,cc);
+ //printf("findTableColumns cc=%d\n",cc);
+ if (cc!=columns) break; // end of table
+
+ out.addStr("<tr>");
+ j=start+i;
+ int columnStart=j;
+ k=0;
+ while (j<=end+i)
+ {
+ if (j==columnStart)
+ {
+ out.addStr("<td");
+ switch (columnAlignment[k])
+ {
+ case AlignLeft: out.addStr(" align=\"left\""); break;
+ case AlignRight: out.addStr(" align=\"right\""); break;
+ case AlignCenter: out.addStr(" align=\"center\""); break;
+ case AlignNone: break;
+ }
+ out.addStr(">");
+ }
+ if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\')))
+ {
+ columnStart=j+1;
+ k++;
+ }
+ else
+ {
+ out.addChar(data[j]);
+ }
+ j++;
+ }
+ out.addChar('\n');
+
+ // proceed to next line
+ i+=ret;
+ }
+
+ out.addStr("</table> ");
+
+ delete[] columnAlignment;
+ return i;
+}
+
+
+void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size)
+{
+ int level;
+ QCString header;
+ QCString id;
+ if (isHRuler(data,size))
+ {
+ out.addStr("<hr>\n");
+ }
+ else if ((level=isAtxHeader(data,size,header,id)))
+ {
+ //if (level==1) g_correctSectionLevel=FALSE;
+ //if (g_correctSectionLevel) level--;
+ QCString hTag;
+ if (level<5 && !id.isEmpty())
+ {
+ SectionInfo::SectionType type = SectionInfo::Anchor;
+ switch(level)
+ {
+ case 1: out.addStr("@section ");
+ type=SectionInfo::Section;
+ break;
+ case 2: out.addStr("@subsection ");
+ type=SectionInfo::Subsection;
+ break;
+ case 3: out.addStr("@subsubsection ");
+ type=SectionInfo::Subsubsection;
+ break;
+ default: out.addStr("@paragraph ");
+ type=SectionInfo::Paragraph;
+ break;
+ }
+ out.addStr(id);
+ out.addStr(" ");
+ out.addStr(header);
+ out.addStr("\n");
+ SectionInfo *si = Doxygen::sectionDict->find(id);
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",header.data(),si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s)",header.data(),si->fileName.data());
+ }
+ }
+ else
+ {
+ si = new SectionInfo(g_fileName,g_lineNr,id,header,type,level);
+ if (g_current)
+ {
+ g_current->anchors->append(si);
+ }
+ Doxygen::sectionDict->append(id,si);
+ }
+ }
+ else
+ {
+ if (!id.isEmpty())
+ {
+ out.addStr("\\anchor "+id+"\n");
+ }
+ hTag.sprintf("h%d",level);
+ out.addStr("<"+hTag+">");
+ out.addStr(header);
+ out.addStr("</"+hTag+">\n");
+ }
+ }
+ else // nothing interesting -> just output the line
+ {
+ out.addStr(data,size);
+ }
+}
+
+static int writeBlockQuote(GrowBuf &out,const char *data,int size)
+{
+ int l;
+ int i=0;
+ int curLevel=0;
+ int end=0;
+ while (i<size)
+ {
+ // find end of this line
+ end=i+1;
+ while (end<=size && data[end-1]!='\n') end++;
+ int j=i;
+ int level=0;
+ int indent=i;
+ // compute the quoting level
+ while (j<end && (data[j]==' ' || data[j]=='>'))
+ {
+ if (data[j]=='>') { level++; indent=j+1; }
+ else if (j>0 && data[j-1]=='>') indent=j+1;
+ j++;
+ }
+ if (j>0 && data[j-1]=='>' &&
+ !(j==size || data[j]=='\n')) // disqualify last > if not followed by space
+ {
+ indent--;
+ j--;
+ }
+ if (level>curLevel) // quote level increased => add start markers
+ {
+ for (l=curLevel;l<level;l++)
+ {
+ out.addStr("<blockquote>\n");
+ }
+ }
+ else if (level<curLevel) // quote level descreased => add end markers
+ {
+ for (l=level;l<curLevel;l++)
+ {
+ out.addStr("</blockquote>\n");
+ }
+ }
+ curLevel=level;
+ if (level==0) break; // end of quote block
+ // copy line without quotation marks
+ out.addStr(data+indent,end-indent);
+ // proceed with next line
+ i=end;
+ }
+ // end of comment within blockquote => add end markers
+ for (l=0;l<curLevel;l++)
+ {
+ out.addStr("</blockquote>\n");
+ }
+ return i;
+}
+
+static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
+{
+ int i=0,end;
+ //printf("writeCodeBlock: data={%s}\n",QCString(data).left(size).data());
+ out.addStr("@verbatim\n");
+ int emptyLines=0;
+ while (i<size)
+ {
+ // find end of this line
+ end=i+1;
+ while (end<=size && data[end-1]!='\n') end++;
+ int j=i;
+ int indent=0;
+ while (j<end && data[j]==' ') j++,indent++;
+ //printf("j=%d end=%d indent=%d refIndent=%d tabSize=%d data={%s}\n",
+ // j,end,indent,refIndent,Config_getInt("TAB_SIZE"),QCString(data+i).left(end-i-1).data());
+ if (j==end-1) // empty line
+ {
+ emptyLines++;
+ i=end;
+ }
+ else if (indent>=refIndent+codeBlockIndent) // enough indent to contine the code block
+ {
+ while (emptyLines>0) // write skipped empty lines
+ {
+ // add empty line
+ out.addStr("\n");
+ emptyLines--;
+ }
+ // add code line minus the indent
+ out.addStr(data+i+refIndent+codeBlockIndent,end-i-refIndent-codeBlockIndent);
+ i=end;
+ }
+ else // end of code block
+ {
+ break;
+ }
+ }
+ out.addStr("@endverbatim\n");
+ while (emptyLines>0) // write skipped empty lines
+ {
+ // add empty line
+ out.addStr("\n");
+ emptyLines--;
+ }
+ //printf("i=%d\n",i);
+ return i;
+}
+
+// start searching for the end of the line start at offset \a i
+// keeping track of possible blocks that need to to skipped.
+static void findEndOfLine(GrowBuf &out,const char *data,int size,
+ int &pi,int&i,int &end)
+{
+ // find end of the line
+ int nb=0;
+ end=i+1;
+ while (end<=size && data[end-1]!='\n')
+ {
+ // while looking for the end of the line we might encounter a block
+ // that needs to be passed unprocessed.
+ if ((data[end-1]=='\\' || data[end-1]=='@') && // command
+ (end<=1 || (data[end-2]!='\\' && data[end-2]!='@')) // not escaped
+ )
+ {
+ QCString endBlockName = isBlockCommand(data+end-1,end-1,size-(end-1));
+ end++;
+ if (!endBlockName.isEmpty())
+ {
+ int l = endBlockName.length();
+ for (;end<size-l-1;end++) // search for end of block marker
+ {
+ if ((data[end]=='\\' || data[end]=='@') &&
+ data[end-1]!='\\' && data[end-1]!='@'
+ )
+ {
+ if (qstrncmp(&data[end+1],endBlockName,l)==0)
+ {
+ if (pi!=-1) // output previous line if available
+ {
+ //printf("feol out={%s}\n",QCString(data+pi).left(i-pi).data());
+ out.addStr(data+pi,i-pi);
+ }
+ // found end marker, skip over this block
+ //printf("feol.block out={%s}\n",QCString(data+i).left(end+l+1-i).data());
+ out.addStr(data+i,end+l+1-i);
+ pi=-1;
+ i=end+l+1; // continue after block
+ end=i+1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (nb==0 && data[end-1]=='<' && end<size-6 &&
+ (end<=1 || (data[end-2]!='\\' && data[end-2]!='@'))
+ )
+ {
+ if (tolower(data[end])=='p' && tolower(data[end+1])=='r' &&
+ tolower(data[end+2])=='e' && data[end+3]=='>') // <pre> tag
+ {
+ if (pi!=-1) // output previous line if available
+ {
+ out.addStr(data+pi,i-pi);
+ }
+ // output part until <pre>
+ out.addStr(data+i,end-1-i);
+ // output part until </pre>
+ i = end-1 + processHtmlTag(out,data+end-1,end-1,size-end+1);
+ pi=-1;
+ end = i+1;
+ break;
+ }
+ else
+ {
+ end++;
+ }
+ }
+ else if (nb==0 && data[end-1]=='`')
+ {
+ while (end<=size && data[end-1]=='`') end++,nb++;
+ }
+ else if (nb>0 && data[end-1]=='`')
+ {
+ int enb=0;
+ while (end<=size && data[end-1]=='`') end++,enb++;
+ if (enb==nb) nb=0;
+ }
+ else
+ {
+ end++;
+ }
+ }
+ //printf("findEndOfLine pi=%d i=%d end=%d {%s}\n",pi,i,end,QCString(data+i).left(end-i).data());
+}
+
+static void writeFencedCodeBlock(GrowBuf &out,const char *data,const char *lng,
+ int blockStart,int blockEnd)
+{
+ QCString lang = lng;
+ if (!lang.isEmpty() && lang.at(0)=='.') lang=lang.mid(1);
+ out.addStr("@code");
+ if (!lang.isEmpty())
+ {
+ out.addStr("{"+lang+"}");
+ }
+ out.addStr(data+blockStart,blockEnd-blockStart);
+ out.addStr("\n");
+ out.addStr("@endcode");
+}
+
+static QCString processQuotations(const QCString &s,int refIndent)
+{
+ GrowBuf out;
+ const char *data = s.data();
+ int size = s.length();
+ int i=0,end=0,pi=-1;
+ int blockStart,blockEnd,blockOffset;
+ QCString lang;
+ while (i<size)
+ {
+ findEndOfLine(out,data,size,pi,i,end);
+ // line is now found at [i..end)
+
+ if (pi!=-1)
+ {
+ if (isFencedCodeBlock(data+pi,size-pi,refIndent,lang,blockStart,blockEnd,blockOffset))
+ {
+ writeFencedCodeBlock(out,data+pi,lang,blockStart,blockEnd);
+ i=pi+blockOffset;
+ pi=-1;
+ end=i+1;
+ continue;
+ }
+ else if (isBlockQuote(data+pi,i-pi,refIndent))
+ {
+ i = pi+writeBlockQuote(out,data+pi,size-pi);
+ pi=-1;
+ end=i+1;
+ continue;
+ }
+ else
+ {
+ //printf("quote out={%s}\n",QCString(data+pi).left(i-pi).data());
+ out.addStr(data+pi,i-pi);
+ }
+ }
+ pi=i;
+ i=end;
+ }
+ if (pi!=-1 && pi<size) // deal with the last line
+ {
+ if (isBlockQuote(data+pi,size-pi,refIndent))
+ {
+ writeBlockQuote(out,data+pi,size-pi);
+ }
+ else
+ {
+ out.addStr(data+pi,size-pi);
+ }
+ }
+ out.addChar(0);
+
+ //printf("Process quotations\n---- input ----\n%s\n---- output ----\n%s\n------------\n",
+ // s.data(),out.get());
+
+ return out.get();
+}
+
+static QCString processBlocks(const QCString &s,int indent)
+{
+ GrowBuf out;
+ const char *data = s.data();
+ int size = s.length();
+ int i=0,end=0,pi=-1,ref,level;
+ QCString id,link,title;
+ int blockIndent = indent;
+
+ // get indent for the first line
+ end = i+1;
+ int sp=0;
+ while (end<=size && data[end-1]!='\n')
+ {
+ if (data[end-1]==' ') sp++;
+ end++;
+ }
+
+#if 0 // commented out, since starting with a comment block is probably a usage error
+ // see also http://stackoverflow.com/q/20478611/784672
+
+ // special case when the documentation starts with a code block
+ // since the first line is skipped when looking for a code block later on.
+ if (end>codeBlockIndent && isCodeBlock(data,0,end,blockIndent))
+ {
+ i=writeCodeBlock(out,data,size,blockIndent);
+ end=i+1;
+ pi=-1;
+ }
+#endif
+
+ // process each line
+ while (i<size)
+ {
+ findEndOfLine(out,data,size,pi,i,end);
+ // line is now found at [i..end)
+
+ //printf("findEndOfLine: pi=%d i=%d end=%d\n",pi,i,end);
+
+ if (pi!=-1)
+ {
+ int blockStart,blockEnd,blockOffset;
+ QCString lang;
+ blockIndent = indent;
+ //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level);
+ if ((level=isHeaderline(data+i,size-i))>0)
+ {
+ //if (level==1) g_correctSectionLevel=FALSE;
+ //if (g_correctSectionLevel) level--;
+ //printf("Found header at %d-%d\n",i,end);
+ while (pi<size && data[pi]==' ') pi++;
+ QCString header,id;
+ convertStringFragment(header,data+pi,i-pi-1);
+ id = extractTitleId(header);
+ //printf("header='%s' is='%s'\n",header.data(),id.data());
+ if (!header.isEmpty())
+ {
+ if (!id.isEmpty())
+ {
+ out.addStr(level==1?"@section ":"@subsection ");
+ out.addStr(id);
+ out.addStr(" ");
+ out.addStr(header);
+ out.addStr("\n\n");
+ SectionInfo *si = Doxygen::sectionDict->find(id);
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",header.data(),si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s)",header.data(),si->fileName.data());
+ }
+ }
+ else
+ {
+ si = new SectionInfo(g_fileName,g_lineNr,id,header,
+ level==1 ? SectionInfo::Section : SectionInfo::Subsection,level);
+ if (g_current)
+ {
+ g_current->anchors->append(si);
+ }
+ Doxygen::sectionDict->append(id,si);
+ }
+ }
+ else
+ {
+ out.addStr(level==1?"<h1>":"<h2>");
+ out.addStr(header);
+ out.addStr(level==1?"\n</h1>\n":"\n</h2>\n");
+ }
+ }
+ else
+ {
+ out.addStr("<hr>\n");
+ }
+ pi=-1;
+ i=end;
+ end=i+1;
+ continue;
+ }
+ else if ((ref=isLinkRef(data+pi,size-pi,id,link,title)))
+ {
+ //printf("found link ref: id='%s' link='%s' title='%s'\n",
+ // id.data(),link.data(),title.data());
+ g_linkRefs.insert(id.lower(),new LinkRef(link,title));
+ i=ref+pi;
+ pi=-1;
+ end=i+1;
+ }
+ else if (isFencedCodeBlock(data+pi,size-pi,indent,lang,blockStart,blockEnd,blockOffset))
+ {
+ //printf("Found FencedCodeBlock lang='%s' start=%d end=%d code={%s}\n",
+ // lang.data(),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data());
+ writeFencedCodeBlock(out,data+pi,lang,blockStart,blockEnd);
+ i=pi+blockOffset;
+ pi=-1;
+ end=i+1;
+ continue;
+ }
+ else if (isCodeBlock(data+i,i,end-i,blockIndent))
+ {
+ // skip previous line (it is empty anyway)
+ i+=writeCodeBlock(out,data+i,size-i,blockIndent);
+ pi=-1;
+ end=i+1;
+ continue;
+ }
+ else if (isTableBlock(data+pi,size-pi))
+ {
+ i=pi+writeTableBlock(out,data+pi,size-pi);
+ pi=-1;
+ end=i+1;
+ continue;
+ }
+ else
+ {
+ writeOneLineHeaderOrRuler(out,data+pi,i-pi);
+ }
+ }
+ pi=i;
+ i=end;
+ }
+ //printf("last line %d size=%d\n",i,size);
+ if (pi!=-1 && pi<size) // deal with the last line
+ {
+ if (isLinkRef(data+pi,size-pi,id,link,title))
+ {
+ //printf("found link ref: id='%s' link='%s' title='%s'\n",
+ // id.data(),link.data(),title.data());
+ g_linkRefs.insert(id.lower(),new LinkRef(link,title));
+ }
+ else
+ {
+ writeOneLineHeaderOrRuler(out,data+pi,size-pi);
+ }
+ }
+
+ out.addChar(0);
+ return out.get();
+}
+
+static QCString extractPageTitle(QCString &docs,QCString &id)
+{
+ int ln=0;
+ // first first non-empty line
+ QCString title;
+ const char *data = docs.data();
+ int i=0;
+ int size=docs.size();
+ while (i<size && (data[i]==' ' || data[i]=='\n'))
+ {
+ if (data[i]=='\n') ln++;
+ i++;
+ }
+ if (i>=size) return "";
+ int end1=i+1;
+ while (end1<size && data[end1-1]!='\n') end1++;
+ //printf("i=%d end1=%d size=%d line='%s'\n",i,end1,size,docs.mid(i,end1-i).data());
+ // first line from i..end1
+ if (end1<size)
+ {
+ ln++;
+ // second line form end1..end2
+ int end2=end1+1;
+ while (end2<size && data[end2-1]!='\n') end2++;
+ if (isHeaderline(data+end1,size-end1))
+ {
+ convertStringFragment(title,data+i,end1-i-1);
+ QCString lns;
+ lns.fill('\n',ln);
+ docs=lns+docs.mid(end2);
+ id = extractTitleId(title);
+ //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data());
+ return title;
+ }
+ }
+ if (i<end1 && isAtxHeader(data+i,end1-i,title,id)>0)
+ {
+ docs=docs.mid(end1);
+ }
+ //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data());
+ return title;
+}
+
+static QCString detab(const QCString &s,int &refIndent)
+{
+ static int tabSize = Config_getInt("TAB_SIZE");
+ GrowBuf out;
+ int size = s.length();
+ const char *data = s.data();
+ int i=0;
+ int col=0;
+ const int maxIndent=1000000; // value representing infinity
+ int minIndent=maxIndent;
+ while (i<size)
+ {
+ char c = data[i++];
+ switch(c)
+ {
+ case '\t': // expand tab
+ {
+ int stop = tabSize - (col%tabSize);
+ //printf("expand at %d stop=%d\n",col,stop);
+ col+=stop;
+ while (stop--) out.addChar(' ');
+ }
+ break;
+ case '\n': // reset colomn counter
+ out.addChar(c);
+ col=0;
+ break;
+ case ' ': // increment column counter
+ out.addChar(c);
+ col++;
+ break;
+ default: // non-whitespace => update minIndent
+ out.addChar(c);
+ if (c<0 && i<size) // multibyte sequence
+ {
+ out.addChar(data[i++]); // >= 2 bytes
+ if (((uchar)c&0xE0)==0xE0 && i<size)
+ {
+ out.addChar(data[i++]); // 3 bytes
+ }
+ if (((uchar)c&0xF0)==0xF0 && i<size)
+ {
+ out.addChar(data[i++]); // 4 byres
+ }
+ }
+ if (col<minIndent) minIndent=col;
+ col++;
+ }
+ }
+ if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
+ out.addChar(0);
+ //printf("detab refIndent=%d\n",refIndent);
+ return out.get();
+}
+
+//---------------------------------------------------------------------------
+
+QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &input)
+{
+ static bool init=FALSE;
+ if (!init)
+ {
+ // setup callback table for special characters
+ g_actions[(unsigned int)'_']=processEmphasis;
+ g_actions[(unsigned int)'*']=processEmphasis;
+ g_actions[(unsigned int)'`']=processCodeSpan;
+ g_actions[(unsigned int)'\\']=processSpecialCommand;
+ g_actions[(unsigned int)'@']=processSpecialCommand;
+ g_actions[(unsigned int)'[']=processLink;
+ g_actions[(unsigned int)'!']=processLink;
+ g_actions[(unsigned int)'<']=processHtmlTag;
+ g_actions[(unsigned int)'-']=processNmdash;
+ g_actions[(unsigned int)'"']=processQuoted;
+ init=TRUE;
+ }
+
+ g_linkRefs.setAutoDelete(TRUE);
+ g_linkRefs.clear();
+ g_current = e;
+ g_fileName = fileName;
+ g_lineNr = lineNr;
+ static GrowBuf out;
+ if (input.isEmpty()) return input;
+ out.clear();
+ int refIndent;
+ // for replace tabs by spaces
+ QCString s = detab(input,refIndent);
+ //printf("======== DeTab =========\n---- output -----\n%s\n---------\n",s.data());
+ // then process quotation blocks (as these may contain other blocks)
+ s = processQuotations(s,refIndent);
+ //printf("======== Quotations =========\n---- output -----\n%s\n---------\n",s.data());
+ // then process block items (headers, rules, and code blocks, references)
+ s = processBlocks(s,refIndent);
+ //printf("======== Blocks =========\n---- output -----\n%s\n---------\n",s.data());
+ // finally process the inline markup (links, emphasis and code spans)
+ processInline(out,s,s.length());
+ out.addChar(0);
+ Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n---------\n",input.data(),out.get());
+ return out.get();
+}
+
+//---------------------------------------------------------------------------
+
+QCString markdownFileNameToId(const QCString &fileName)
+{
+ QCString baseFn = stripFromPath(QFileInfo(fileName).absFilePath().utf8());
+ int i = baseFn.findRev('.');
+ if (i!=-1) baseFn = baseFn.left(i);
+ QCString baseName = substitute(substitute(baseFn," ","_"),"/","_");
+ return "md_"+baseName;
+}
+
+void MarkdownFileParser::parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool /*sameTranslationUnit*/,
+ QStrList & /*filesInSameTranslationUnit*/)
+{
+ Entry *current = new Entry;
+ current->lang = SrcLangExt_Markdown;
+ current->fileName = fileName;
+ current->docFile = fileName;
+ current->docLine = 1;
+ QCString docs = fileBuf;
+ QCString id;
+ QCString title=extractPageTitle(docs,id).stripWhiteSpace();
+ QCString titleFn = QFileInfo(fileName).baseName().utf8();
+ QCString fn = QFileInfo(fileName).fileName().utf8();
+ static QCString mdfileAsMainPage = Config_getString("USE_MDFILE_AS_MAINPAGE");
+ if (id.isEmpty()) id = markdownFileNameToId(fileName);
+ if (title.isEmpty()) title = titleFn;
+ if (!mdfileAsMainPage.isEmpty() &&
+ (fn==mdfileAsMainPage || // name reference
+ QFileInfo(fileName).absFilePath()==
+ QFileInfo(mdfileAsMainPage).absFilePath()) // file reference with path
+ )
+ {
+ docs.prepend("@mainpage\n");
+ }
+ else if (id=="mainpage" || id=="index")
+ {
+ docs.prepend("@mainpage "+title+"\n");
+ }
+ else
+ {
+ docs.prepend("@page "+id+" "+title+"\n");
+ }
+ int lineNr=1;
+ int position=0;
+
+ // even without markdown support enabled, we still
+ // parse markdown files as such
+ bool markdownEnabled = Doxygen::markdownSupport;
+ Doxygen::markdownSupport = TRUE;
+
+ bool needsEntry;
+ Protection prot;
+ while (parseCommentBlock(
+ this,
+ current,
+ docs,
+ fileName,
+ lineNr,
+ FALSE, // isBrief
+ FALSE, // javadoc autobrief
+ FALSE, // inBodyDocs
+ prot, // protection
+ position,
+ needsEntry))
+ {
+ if (needsEntry)
+ {
+ QCString docFile = current->docFile;
+ root->addSubEntry(current);
+ current = new Entry;
+ current->lang = SrcLangExt_Markdown;
+ current->docFile = docFile;
+ current->docLine = lineNr;
+ }
+ }
+ if (needsEntry)
+ {
+ root->addSubEntry(current);
+ }
+
+ // restore setting
+ Doxygen::markdownSupport = markdownEnabled;
+ //g_correctSectionLevel = FALSE;
+}
+
+void MarkdownFileParser::parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName,
+ FileDef *fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp");
+ if (pIntf!=this)
+ {
+ pIntf->parseCode(
+ codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName,
+ fileDef,startLine,endLine,inlineFragment,memberDef,showLineNumbers,
+ searchCtx,collectXRefs);
+ }
+}
+
+void MarkdownFileParser::resetCodeParserState()
+{
+ ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp");
+ if (pIntf!=this)
+ {
+ pIntf->resetCodeParserState();
+ }
+}
+
+void MarkdownFileParser::parsePrototype(const char *text)
+{
+ ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp");
+ if (pIntf!=this)
+ {
+ pIntf->parsePrototype(text);
+ }
+}
+
diff --git a/src/markdown.h b/src/markdown.h
new file mode 100644
index 0000000..5e35259
--- /dev/null
+++ b/src/markdown.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MARKDOWN_H
+#define MARKDOWN_H
+
+#include <qcstring.h>
+#include "parserintf.h"
+
+class Entry;
+
+/** processes string \a s and converts markdown into doxygen/html commands. */
+QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &s);
+QCString markdownFileNameToId(const QCString &fileName);
+
+class MarkdownFileParser : public ParserInterface
+{
+ public:
+ virtual ~MarkdownFileParser() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+ bool needsPreprocessing(const QCString &) { return FALSE; }
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState();
+ void parsePrototype(const char *text);
+};
+
+
+
+
+#endif
diff --git a/src/marshal.cpp b/src/marshal.cpp
new file mode 100644
index 0000000..04f426d
--- /dev/null
+++ b/src/marshal.cpp
@@ -0,0 +1,801 @@
+#include <qfile.h>
+#include <assert.h>
+
+#include "sortdict.h"
+#include "marshal.h"
+#include "entry.h"
+#include "section.h"
+#include "memberlist.h"
+#include "definition.h"
+#include "groupdef.h"
+#include "example.h"
+#include "arguments.h"
+
+#define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
+
+void marshalInt(StorageIntf *s,int v)
+{
+ uchar b[4];
+ b[0]=((uint)v)>>24;
+ b[1]=(((uint)v)>>16)&0xff;
+ b[2]=(((uint)v)>>8)&0xff;
+ b[3]=v&0xff;
+ s->write((const char *)b,4);
+}
+
+void marshalUInt(StorageIntf *s,uint v)
+{
+ uchar b[4];
+ b[0]=v>>24;
+ b[1]=(v>>16)&0xff;
+ b[2]=(v>>8)&0xff;
+ b[3]=v&0xff;
+ s->write((const char *)b,4);
+}
+
+void marshalUInt64(StorageIntf *s,uint64 v)
+{
+ marshalUInt(s, uint(v>>32));
+ marshalUInt(s, uint(v&0xFFFFFFFF));
+}
+
+void marshalBool(StorageIntf *s,bool b)
+{
+ char c = b;
+ s->write(&c,sizeof(char));
+}
+
+void marshalQCString(StorageIntf *s,const QCString &str)
+{
+ uint l=str.length();
+ marshalUInt(s,l);
+ if (l>0) s->write(str.data(),l);
+}
+
+void marshalQGString(StorageIntf *s,const QGString &str)
+{
+ uint l=str.length();
+ marshalUInt(s,l);
+ if (l>0) s->write(str.data(),l);
+}
+
+void marshalArgumentList(StorageIntf *s,ArgumentList *argList)
+{
+ ArgumentList::marshal(s,argList);
+}
+
+void marshalArgumentLists(StorageIntf *s,QList<ArgumentList> *argLists)
+{
+ if (argLists==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,argLists->count());
+ QListIterator<ArgumentList> ali(*argLists);
+ ArgumentList *al;
+ for (ali.toFirst();(al=ali.current());++ali)
+ {
+ marshalArgumentList(s,al);
+ }
+ }
+}
+
+void marshalBaseInfoList(StorageIntf *s, QList<BaseInfo> *baseList)
+{
+ if (baseList==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,baseList->count());
+ QListIterator<BaseInfo> bli(*baseList);
+ BaseInfo *bi;
+ for (bli.toFirst();(bi=bli.current());++bli)
+ {
+ marshalQCString(s,bi->name);
+ marshalInt(s,(int)bi->prot);
+ marshalInt(s,(int)bi->virt);
+ }
+ }
+}
+
+void marshalGroupingList(StorageIntf *s, QList<Grouping> *groups)
+{
+ if (groups==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,groups->count());
+ QListIterator<Grouping> gli(*groups);
+ Grouping *g;
+ for (gli.toFirst();(g=gli.current());++gli)
+ {
+ marshalQCString(s,g->groupname);
+ marshalInt(s,(int)g->pri);
+ }
+ }
+}
+
+void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors)
+{
+ if (anchors==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,anchors->count());
+ QListIterator<SectionInfo> sli(*anchors);
+ SectionInfo *si;
+ for (sli.toFirst();(si=sli.current());++sli)
+ {
+ marshalQCString(s,si->label);
+ marshalQCString(s,si->title);
+ marshalQCString(s,si->ref);
+ marshalInt(s,(int)si->type);
+ marshalQCString(s,si->fileName);
+ marshalInt(s,si->lineNr);
+ marshalInt(s,si->level);
+ }
+ }
+}
+
+void marshalItemInfoList(StorageIntf *s, QList<ListItemInfo> *sli)
+{
+ if (sli==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,sli->count());
+ QListIterator<ListItemInfo> liii(*sli);
+ ListItemInfo *lii;
+ for (liii.toFirst();(lii=liii.current());++liii)
+ {
+ marshalQCString(s,lii->type);
+ marshalInt(s,lii->itemId);
+ }
+ }
+}
+
+void marshalObjPointer(StorageIntf *s,void *obj)
+{
+ char *b = (char *)&obj;
+ s->write(b,sizeof(void *));
+}
+
+void marshalSectionDict(StorageIntf *s,SectionDict *sections)
+{
+ if (sections==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,sections->count());
+ SDict<SectionInfo>::IteratorDict sli(*sections);
+ SectionInfo *si;
+ for (sli.toFirst();(si=sli.current());++sli)
+ {
+ marshalQCString(s,sli.currentKey());
+ marshalObjPointer(s,si);
+ }
+ }
+}
+
+void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict)
+{
+ if (memberSDict==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,memberSDict->count());
+ //printf(" marshalMemberSDict: items=%d\n",memberSDict->count());
+ SDict<MemberDef>::IteratorDict mdi(*memberSDict);
+ MemberDef *md;
+ int count=0;
+ for (mdi.toFirst();(md=mdi.current());++mdi)
+ {
+ //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
+ marshalQCString(s,mdi.currentKey());
+ marshalObjPointer(s,md);
+ count++;
+ }
+ assert(count==memberSDict->count());
+ }
+}
+
+void marshalDocInfo(StorageIntf *s,DocInfo *docInfo)
+{
+ if (docInfo==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,1);
+ marshalQCString(s,docInfo->doc);
+ marshalInt(s,docInfo->line);
+ marshalQCString(s,docInfo->file);
+ }
+}
+
+void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo)
+{
+ if (briefInfo==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,1);
+ marshalQCString(s,briefInfo->doc);
+ marshalQCString(s,briefInfo->tooltip);
+ marshalInt(s,briefInfo->line);
+ marshalQCString(s,briefInfo->file);
+ }
+}
+
+void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo)
+{
+ if (bodyInfo==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,1);
+ marshalInt(s,bodyInfo->startLine);
+ marshalInt(s,bodyInfo->endLine);
+ marshalObjPointer(s,bodyInfo->fileDef);
+ }
+}
+
+void marshalGroupList(StorageIntf *s,GroupList *groupList)
+{
+ if (groupList==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,groupList->count());
+ QListIterator<GroupDef> gli(*groupList);
+ GroupDef *gd=0;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ marshalObjPointer(s,gd);
+ }
+ }
+}
+
+void marshalMemberList(StorageIntf *s,MemberList *ml)
+{
+ if (ml==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,ml->count());
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ uint count=0;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ marshalObjPointer(s,md);
+ count++;
+ }
+ assert(count==ml->count());
+
+ ml->marshal(s);
+ }
+}
+
+void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed)
+{
+ if (ed==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,ed->count());
+ //printf(" marshalMemberSDict: items=%d\n",memberSDict->count());
+ SDict<Example>::IteratorDict edi(*ed);
+ Example *e;
+ for (edi.toFirst();(e=edi.current());++edi)
+ {
+ //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
+ marshalQCString(s,edi.currentKey());
+ marshalQCString(s,e->anchor);
+ marshalQCString(s,e->name);
+ marshalQCString(s,e->file);
+ }
+ }
+}
+
+void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls)
+{
+ if (mls==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,mls->count());
+ //printf(" marshalMemberSDict: items=%d\n",memberSDict->count());
+ SDict<MemberList>::IteratorDict mli(*mls);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md);
+ marshalQCString(s,mli.currentKey());
+ marshalObjPointer(s,ml); // assume we are not owner of the list
+ }
+ }
+}
+
+void marshalEntry(StorageIntf *s,Entry *e)
+{
+ marshalUInt(s,HEADER);
+ marshalQCString(s,e->name);
+ marshalQCString(s,e->type);
+ marshalInt(s,e->section);
+ marshalInt(s,(int)e->protection);
+ marshalInt(s,(int)e->mtype);
+ marshalUInt64(s,e->spec);
+ marshalInt(s,e->initLines);
+ marshalBool(s,e->stat);
+ marshalBool(s,e->explicitExternal);
+ marshalBool(s,e->proto);
+ marshalBool(s,e->subGrouping);
+ marshalBool(s,e->callGraph);
+ marshalBool(s,e->callerGraph);
+ marshalInt(s,(int)e->virt);
+ marshalQCString(s,e->args);
+ marshalQCString(s,e->bitfields);
+ marshalArgumentList(s,e->argList);
+ marshalArgumentLists(s,e->tArgLists);
+ marshalQGString(s,e->program);
+ marshalQGString(s,e->initializer);
+ marshalQCString(s,e->includeFile);
+ marshalQCString(s,e->includeName);
+ marshalQCString(s,e->doc);
+ marshalInt(s,e->docLine);
+ marshalQCString(s,e->docFile);
+ marshalQCString(s,e->brief);
+ marshalInt(s,e->briefLine);
+ marshalQCString(s,e->briefFile);
+ marshalQCString(s,e->inbodyDocs);
+ marshalInt(s,e->inbodyLine);
+ marshalQCString(s,e->inbodyFile);
+ marshalQCString(s,e->relates);
+ marshalInt(s,e->relatesType);
+ marshalQCString(s,e->read);
+ marshalQCString(s,e->write);
+ marshalQCString(s,e->inside);
+ marshalQCString(s,e->exception);
+ marshalArgumentList(s,e->typeConstr);
+ marshalInt(s,e->bodyLine);
+ marshalInt(s,e->endBodyLine);
+ marshalInt(s,e->mGrpId);
+ marshalBaseInfoList(s,e->extends);
+ marshalGroupingList(s,e->groups);
+ marshalSectionInfoList(s,e->anchors);
+ marshalQCString(s,e->fileName);
+ marshalInt(s,e->startLine);
+ marshalItemInfoList(s,e->sli);
+ marshalInt(s,(int)e->lang);
+ marshalBool(s,e->hidden);
+ marshalBool(s,e->artificial);
+ marshalInt(s,(int)e->groupDocType);
+ marshalQCString(s,e->id);
+}
+
+void marshalEntryTree(StorageIntf *s,Entry *e)
+{
+ marshalEntry(s,e);
+ marshalUInt(s,e->children()->count());
+ QListIterator<Entry> eli(*e->children());
+ Entry *child;
+ for (eli.toFirst();(child=eli.current());++eli)
+ {
+ marshalEntryTree(s,child);
+ }
+}
+
+//------------------------------------------------------------------
+
+int unmarshalInt(StorageIntf *s)
+{
+ uchar b[4];
+ s->read((char *)b,4);
+ int result=(int)((((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]);
+ //printf("unmarshalInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos());
+ return result;
+}
+
+uint unmarshalUInt(StorageIntf *s)
+{
+ uchar b[4];
+ s->read((char *)b,4);
+ uint result=(((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3];
+ //printf("unmarshalUInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos());
+ return result;
+}
+
+uint64 unmarshalUInt64(StorageIntf *s)
+{
+ uint64 result=uint64(unmarshalUInt(s))<<32;
+ result|=unmarshalUInt(s);
+ return result;
+}
+
+bool unmarshalBool(StorageIntf *s)
+{
+ char result;
+ s->read(&result,sizeof(result));
+ //printf("unmarshalBool: %x offset=%llx\n",result,f.pos());
+ return result;
+}
+
+QCString unmarshalQCString(StorageIntf *s)
+{
+ uint len = unmarshalUInt(s);
+ //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos());
+ QCString result(len+1);
+ result.at(len)='\0';
+ if (len>0)
+ {
+ s->read(result.data(),len);
+ }
+ //printf("unmarshalQCString: result=%s\n",result.data());
+ return result;
+}
+
+QGString unmarshalQGString(StorageIntf *s)
+{
+ uint len = unmarshalUInt(s);
+ //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos());
+ QGString result(len+1);
+ result.at(len)='\0';
+ if (len>0)
+ {
+ s->read(result.data(),len);
+ }
+ //printf("unmarshalQCString: result=%s\n",result.data());
+ return result;
+}
+
+ArgumentList *unmarshalArgumentList(StorageIntf *s)
+{
+ return ArgumentList::unmarshal(s);
+}
+
+QList<ArgumentList> *unmarshalArgumentLists(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ QList<ArgumentList> *result = new QList<ArgumentList>;
+ result->setAutoDelete(TRUE);
+ assert(count<1000000);
+ //printf("unmarshalArgumentLists: %d\n",count);
+ for (i=0;i<count;i++)
+ {
+ result->append(unmarshalArgumentList(s));
+ }
+ return result;
+}
+
+QList<BaseInfo> *unmarshalBaseInfoList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ QList<BaseInfo> *result = new QList<BaseInfo>;
+ result->setAutoDelete(TRUE);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString name = unmarshalQCString(s);
+ Protection prot = (Protection)unmarshalInt(s);
+ Specifier virt = (Specifier)unmarshalInt(s);
+ result->append(new BaseInfo(name,prot,virt));
+ }
+ return result;
+}
+
+QList<Grouping> *unmarshalGroupingList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ QList<Grouping> *result = new QList<Grouping>;
+ result->setAutoDelete(TRUE);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString name = unmarshalQCString(s);
+ Grouping::GroupPri_t prio = (Grouping::GroupPri_t)unmarshalInt(s);
+ result->append(new Grouping(name,prio));
+ }
+ return result;
+}
+
+QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ QList<SectionInfo> *result = new QList<SectionInfo>;
+ result->setAutoDelete(TRUE);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString label = unmarshalQCString(s);
+ QCString title = unmarshalQCString(s);
+ QCString ref = unmarshalQCString(s);
+ SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s);
+ QCString fileName = unmarshalQCString(s);
+ int lineNr = unmarshalInt(s);
+ int level = unmarshalInt(s);
+ result->append(new SectionInfo(fileName,lineNr,label,title,type,level,ref));
+ }
+ return result;
+}
+
+QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ QList<ListItemInfo> *result = new QList<ListItemInfo>;
+ result->setAutoDelete(TRUE);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ ListItemInfo *lii = new ListItemInfo;
+ lii->type = unmarshalQCString(s);
+ lii->itemId = unmarshalInt(s);
+ result->append(lii);
+ }
+ return result;
+}
+
+void *unmarshalObjPointer(StorageIntf *s)
+{
+ void *result;
+ s->read((char *)&result,sizeof(void*));
+ return result;
+}
+
+SectionDict *unmarshalSectionDict(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ //printf("unmarshalSectionDict count=%d\n",count);
+ if (count==NULL_LIST) return 0; // null list
+ SectionDict *result = new SectionDict(17);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString key = unmarshalQCString(s);
+ SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s);
+ //printf(" unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data());
+ result->append(key,si);
+ }
+ return result;
+}
+
+MemberSDict *unmarshalMemberSDict(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ //printf("--- unmarshalMemberSDict count=%d\n",count);
+ if (count==NULL_LIST)
+ {
+ //printf("--- end unmarshalMemberSDict\n");
+ return 0; // null list
+ }
+ MemberSDict *result = new MemberSDict;
+ assert(count<1000000);
+ //printf("Reading %d key-value pairs\n",count);
+ for (i=0;i<count;i++)
+ {
+ //printf(" unmarshaling pair %d\n",i);
+ QCString key = unmarshalQCString(s);
+ //printf(" unmarshaling key %s\n",key.data());
+ MemberDef *md = (MemberDef *)unmarshalObjPointer(s);
+ //printf(" unmarshalMemberSDict i=%d key=%s md=%p\n",i,key.data(),md);
+ result->append(key,md);
+ }
+
+ //printf("--- end unmarshalMemberSDict\n");
+ return result;
+}
+
+DocInfo *unmarshalDocInfo(StorageIntf *s)
+{
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ DocInfo *result = new DocInfo;
+ result->doc = unmarshalQCString(s);
+ result->line = unmarshalInt(s);
+ result->file = unmarshalQCString(s);
+ return result;
+}
+
+BriefInfo *unmarshalBriefInfo(StorageIntf *s)
+{
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ BriefInfo *result = new BriefInfo;
+ result->doc = unmarshalQCString(s);
+ result->tooltip = unmarshalQCString(s);
+ result->line = unmarshalInt(s);
+ result->file = unmarshalQCString(s);
+ return result;
+}
+
+BodyInfo *unmarshalBodyInfo(StorageIntf *s)
+{
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ BodyInfo *result = new BodyInfo;
+ result->startLine = unmarshalInt(s);
+ result->endLine = unmarshalInt(s);
+ result->fileDef = (FileDef*)unmarshalObjPointer(s);
+ return result;
+}
+
+GroupList *unmarshalGroupList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0; // null list
+ assert(count<1000000);
+ GroupList *result = new GroupList;
+ for (i=0;i<count;i++)
+ {
+ GroupDef *gd = (GroupDef *)unmarshalObjPointer(s);
+ result->append(gd);
+ }
+ return result;
+}
+
+MemberList *unmarshalMemberList(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ MemberList *result = new MemberList;
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ MemberDef *md = (MemberDef*)unmarshalObjPointer(s);
+ result->append(md);
+ }
+ result->unmarshal(s);
+ return result;
+}
+
+ExampleSDict *unmarshalExampleSDict(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ ExampleSDict *result = new ExampleSDict;
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString key = unmarshalQCString(s);
+ Example *e = new Example;
+ e->anchor = unmarshalQCString(s);
+ e->name = unmarshalQCString(s);
+ e->file = unmarshalQCString(s);
+ result->inSort(key,e);
+ }
+ return result;
+}
+
+SDict<MemberList> *unmarshalMemberLists(StorageIntf *s)
+{
+ uint i;
+ uint count = unmarshalUInt(s);
+ if (count==NULL_LIST) return 0;
+ SDict<MemberList> *result = new SDict<MemberList>(7);
+ assert(count<1000000);
+ for (i=0;i<count;i++)
+ {
+ QCString key = unmarshalQCString(s);
+ MemberList *ml = (MemberList *)unmarshalObjPointer(s);
+ result->append(key,ml);
+ }
+ return result;
+}
+
+Entry * unmarshalEntry(StorageIntf *s)
+{
+ Entry *e = new Entry;
+ uint header=unmarshalUInt(s);
+ ASSERT(header==HEADER);
+ e->name = unmarshalQCString(s);
+ e->type = unmarshalQCString(s);
+ e->section = unmarshalInt(s);
+ e->protection = (Protection)unmarshalInt(s);
+ e->mtype = (MethodTypes)unmarshalInt(s);
+ e->spec = unmarshalUInt64(s);
+ e->initLines = unmarshalInt(s);
+ e->stat = unmarshalBool(s);
+ e->explicitExternal = unmarshalBool(s);
+ e->proto = unmarshalBool(s);
+ e->subGrouping = unmarshalBool(s);
+ e->callGraph = unmarshalBool(s);
+ e->callerGraph = unmarshalBool(s);
+ e->virt = (Specifier)unmarshalInt(s);
+ e->args = unmarshalQCString(s);
+ e->bitfields = unmarshalQCString(s);
+ delete e->argList;
+ e->argList = unmarshalArgumentList(s);
+ e->tArgLists = unmarshalArgumentLists(s);
+ e->program = unmarshalQGString(s);
+ e->initializer = unmarshalQGString(s);
+ e->includeFile = unmarshalQCString(s);
+ e->includeName = unmarshalQCString(s);
+ e->doc = unmarshalQCString(s);
+ e->docLine = unmarshalInt(s);
+ e->docFile = unmarshalQCString(s);
+ e->brief = unmarshalQCString(s);
+ e->briefLine = unmarshalInt(s);
+ e->briefFile = unmarshalQCString(s);
+ e->inbodyDocs = unmarshalQCString(s);
+ e->inbodyLine = unmarshalInt(s);
+ e->inbodyFile = unmarshalQCString(s);
+ e->relates = unmarshalQCString(s);
+ e->relatesType = (RelatesType)unmarshalInt(s);
+ e->read = unmarshalQCString(s);
+ e->write = unmarshalQCString(s);
+ e->inside = unmarshalQCString(s);
+ e->exception = unmarshalQCString(s);
+ e->typeConstr = unmarshalArgumentList(s);
+ e->bodyLine = unmarshalInt(s);
+ e->endBodyLine = unmarshalInt(s);
+ e->mGrpId = unmarshalInt(s);
+ delete e->extends;
+ e->extends = unmarshalBaseInfoList(s);
+ delete e->groups;
+ e->groups = unmarshalGroupingList(s);
+ delete e->anchors;
+ e->anchors = unmarshalSectionInfoList(s);
+ e->fileName = unmarshalQCString(s);
+ e->startLine = unmarshalInt(s);
+ e->sli = unmarshalItemInfoList(s);
+ e->lang = (SrcLangExt)unmarshalInt(s);
+ e->hidden = unmarshalBool(s);
+ e->artificial = unmarshalBool(s);
+ e->groupDocType = (Entry::GroupDocType)unmarshalInt(s);
+ e->id = unmarshalQCString(s);
+ return e;
+}
+
+Entry * unmarshalEntryTree(StorageIntf *s)
+{
+ Entry *e = unmarshalEntry(s);
+ uint count = unmarshalUInt(s);
+ uint i;
+ for (i=0;i<count;i++)
+ {
+ e->addSubEntry(unmarshalEntryTree(s));
+ }
+ return e;
+}
diff --git a/src/marshal.h b/src/marshal.h
new file mode 100644
index 0000000..0c61276
--- /dev/null
+++ b/src/marshal.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MARSHAL_H
+#define MARSHAL_H
+
+#include <qlist.h>
+#include <qfile.h>
+#include "sortdict.h"
+#include "store.h"
+
+class ArgumentList;
+struct BaseInfo;
+struct Grouping;
+struct SectionInfo;
+struct ListItemInfo;
+class QCString;
+class QGString;
+class SectionDict;
+class MemberSDict;
+class GroupList;
+class MemberList;
+struct BodyInfo;
+struct DocInfo;
+struct BriefInfo;
+class ExampleSDict;
+class Entry;
+
+#define NULL_LIST 0xffffffff
+
+//----- marshaling function: datatype -> byte stream --------------------
+
+void marshalInt(StorageIntf *s,int v);
+void marshalUInt(StorageIntf *s,uint v);
+void marshalUInt64(StorageIntf *s,uint64 v);
+void marshalBool(StorageIntf *s,bool b);
+void marshalQCString(StorageIntf *s,const QCString &str);
+void marshalQGString(StorageIntf *s,const QGString &str);
+void marshalArgumentList(StorageIntf *s,ArgumentList *argList);
+void marshalArgumentLists(StorageIntf *s,QList<ArgumentList> *argLists);
+void marshalBaseInfoList(StorageIntf *s, QList<BaseInfo> *baseList);
+void marshalGroupingList(StorageIntf *s, QList<Grouping> *groups);
+void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors);
+void marshalItemInfoList(StorageIntf *s, QList<ListItemInfo> *sli);
+void marshalObjPointer(StorageIntf *s,void *obj);
+void marshalSectionDict(StorageIntf *s,SectionDict *sections);
+void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict);
+void marshalDocInfo(StorageIntf *s,DocInfo *docInfo);
+void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo);
+void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo);
+void marshalGroupList(StorageIntf *s,GroupList *groupList);
+void marshalMemberList(StorageIntf *s,MemberList *ml);
+void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed);
+void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls);
+void marshalEntry(StorageIntf *s,Entry *e);
+void marshalEntryTree(StorageIntf *s,Entry *e);
+
+//----- unmarshaling function: byte stream -> datatype ------------------
+
+int unmarshalInt(StorageIntf *s);
+uint unmarshalUInt(StorageIntf *s);
+uint64 unmarshalUInt64(StorageIntf *s);
+bool unmarshalBool(StorageIntf *s);
+QCString unmarshalQCString(StorageIntf *s);
+QGString unmarshalQGString(StorageIntf *s);
+ArgumentList * unmarshalArgumentList(StorageIntf *s);
+QList<ArgumentList> *unmarshalArgumentLists(StorageIntf *s);
+QList<BaseInfo> * unmarshalBaseInfoList(StorageIntf *s);
+QList<Grouping> * unmarshalGroupingList(StorageIntf *s);
+QList<SectionInfo> * unmarshalSectionInfoList(StorageIntf *s);
+QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s);
+void * unmarshalObjPointer(StorageIntf *s);
+SectionDict * unmarshalSectionDict(StorageIntf *s);
+MemberSDict * unmarshalMemberSDict(StorageIntf *s);
+DocInfo * unmarshalDocInfo(StorageIntf *s);
+BriefInfo * unmarshalBriefInfo(StorageIntf *s);
+BodyInfo * unmarshalBodyInfo(StorageIntf *s);
+GroupList * unmarshalGroupList(StorageIntf *s);
+MemberList * unmarshalMemberList(StorageIntf *s);
+ExampleSDict * unmarshalExampleSDict(StorageIntf *s);
+SDict<MemberList> * unmarshalMemberLists(StorageIntf *s);
+Entry * unmarshalEntry(StorageIntf *s);
+Entry * unmarshalEntryTree(StorageIntf *s);
+
+#endif
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
new file mode 100644
index 0000000..a25528a
--- /dev/null
+++ b/src/memberdef.cpp
@@ -0,0 +1,5098 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <qglobal.h>
+#include <qregexp.h>
+#include <assert.h>
+#include "md5.h"
+#include "memberdef.h"
+#include "membername.h"
+#include "doxygen.h"
+#include "util.h"
+#include "code.h"
+#include "message.h"
+#include "htmlhelp.h"
+#include "language.h"
+#include "outputlist.h"
+#include "example.h"
+#include "membergroup.h"
+#include "groupdef.h"
+#include "defargs.h"
+#include "docparser.h"
+#include "dot.h"
+#include "searchindex.h"
+#include "parserintf.h"
+#include "marshal.h"
+#include "objcache.h"
+
+#include "vhdldocgen.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "config.h"
+
+//-----------------------------------------------------------------------------
+
+int MemberDef::s_indentLevel = 0;
+
+//-----------------------------------------------------------------------------
+
+static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
+{
+ QCString result;
+ QCString clRealName=n;
+ int p=0,i;
+ if ((i=clRealName.find('<'))!=-1)
+ {
+ clRealName=clRealName.left(i); // strip template specialization
+ }
+ if ((i=clRealName.findRev("::"))!=-1)
+ {
+ clRealName=clRealName.right(clRealName.length()-i-2);
+ }
+ while ((i=s.find(clRealName,p))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ uint j=clRealName.length()+i;
+ if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
+ { // add template names
+ //printf("Adding %s+%s\n",clRealName.data(),t.data());
+ result+=clRealName+t;
+ }
+ else
+ { // template names already present
+ //printf("Adding %s\n",clRealName.data());
+ result+=clRealName;
+ }
+ p=i+clRealName.length();
+ }
+ result+=s.right(s.length()-p);
+ //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
+ return result;
+}
+
+// ol.startMemberDocName has already been done before this is called.
+// when this function returns TRUE, ol.endParameterList will be called.
+//
+// typical sequence:
+// ol.startMemberDoc
+// ol.startMemberDocName
+// --- enter writeDefArgumentList
+// ol.endMemberDocName
+// ol.startParameterList
+// ...
+// ol.startParameterType(first=TRUE)
+// ol.endParameterType
+// ol.startParameterName
+// ol.endParameterName(last==FALSE)
+// ...
+// ol.startParameterType(first=FALSE)
+// ol.endParamtereType
+// ol.startParameterName
+// ol.endParameterName(last==TRUE)
+// ...
+// --- leave writeDefArgumentList with return value TRUE
+// ol.endParameterList
+// ol.endMemberDoc(hasArgs=TRUE)
+//
+// For an empty list the function should return FALSE, the sequence is
+// ol.startMemberDoc
+// ol.startMemberDocName
+// --- enter writeDefArgumentList
+// --- leave writeDefArgumentList with return value FALSE
+// ol.endMemberDocName
+// ol.endMemberDoc(hasArgs=FALSE);
+//
+
+static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
+ const QCString & /*scopeName*/,MemberDef *md)
+{
+ ArgumentList *defArgList=(md->isDocsForDefinition()) ?
+ md->argumentList() : md->declArgumentList();
+ //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
+ if (defArgList==0 || md->isProperty())
+ {
+ return FALSE; // member has no function like argument list
+ }
+
+ // simple argument list for tcl
+ if (md->getLanguage()==SrcLangExt_Tcl)
+ {
+ if (defArgList->count()==0) return FALSE;
+ ArgumentListIterator ali(*defArgList);
+ Argument *a;
+ ol.endMemberDocName();
+ ol.startParameterList(FALSE);
+ ol.startParameterType(TRUE,0);
+ ol.endParameterType();
+ ol.startParameterName(FALSE);
+ for (;(a=ali.current());++ali)
+ {
+ if (a->defval.isEmpty())
+ {
+ ol.docify(a->name+" ");
+ }
+ else
+ {
+ ol.docify("?"+a->name+"? ");
+ }
+ }
+ ol.endParameterName(TRUE,FALSE,FALSE);
+ return TRUE;
+ }
+
+ if (!md->isDefine()) ol.docify(" ");
+
+ //printf("writeDefArgList(%d)\n",defArgList->count());
+ ol.pushGeneratorState();
+ //ol.disableAllBut(OutputGenerator::Html);
+ bool htmlOn = ol.isEnabled(OutputGenerator::Html);
+ bool latexOn = ol.isEnabled(OutputGenerator::Latex);
+ {
+ // html and latex
+ if (htmlOn) ol.enable(OutputGenerator::Html);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+
+ ol.endMemberDocName();
+ ol.startParameterList(!md->isObjCMethod());
+ }
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Latex);
+ {
+ // other formats
+ if (!md->isObjCMethod()) ol.docify("("); // start argument list
+ ol.endMemberDocName();
+ }
+ ol.popGeneratorState();
+ //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
+
+ QCString cName;
+ if (cd)
+ {
+ cName=cd->name();
+ int il=cName.find('<');
+ int ir=cName.findRev('>');
+ if (il!=-1 && ir!=-1 && ir>il)
+ {
+ cName=cName.mid(il,ir-il+1);
+ //printf("1. cName=%s\n",cName.data());
+ }
+ else if (cd->templateArguments())
+ {
+ cName=tempArgListToString(cd->templateArguments());
+ //printf("2. cName=%s\n",cName.data());
+ }
+ else // no template specifier
+ {
+ cName.resize(0);
+ }
+ }
+ //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
+
+ bool first=TRUE;
+ bool paramTypeStarted=FALSE;
+ bool isDefine = md->isDefine();
+ ArgumentListIterator ali(*defArgList);
+ Argument *a=ali.current();
+ while (a)
+ {
+ if (isDefine || first)
+ {
+ ol.startParameterType(first,0);
+ paramTypeStarted=TRUE;
+ if (isDefine)
+ {
+ ol.endParameterType();
+ ol.startParameterName(TRUE);
+ }
+ }
+ QRegExp re(")("),res("(.*\\*");
+ int vp=a->type.find(re);
+ int wp=a->type.find(res);
+
+ // use the following to put the function pointer type before the name
+ bool hasFuncPtrType=FALSE;
+
+ if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
+ {
+ ol.docify(a->attrib+" ");
+ }
+ if (hasFuncPtrType) // argument type is a function pointer
+ {
+ //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
+ QCString n=a->type.left(vp);
+ if (hasFuncPtrType) n=a->type.left(wp);
+ if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n);
+ }
+ else // non-function pointer type
+ {
+ QCString n=a->type;
+ if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
+ if (a->type!="...")
+ {
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n);
+ }
+ }
+ if (!isDefine)
+ {
+ if (paramTypeStarted)
+ {
+ ol.endParameterType();
+ paramTypeStarted=FALSE;
+ }
+ ol.startParameterName(defArgList->count()<2);
+ }
+ if (hasFuncPtrType)
+ {
+ ol.docify(a->type.mid(wp,vp-wp));
+ }
+ if (!a->name.isEmpty() || a->type=="...") // argument has a name
+ {
+ //if (!hasFuncPtrType)
+ //{
+ // ol.docify(" ");
+ //}
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.startEmphasis();
+ ol.enable(OutputGenerator::Man);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.endEmphasis();
+ ol.enable(OutputGenerator::Man);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ }
+ if (!a->array.isEmpty())
+ {
+ ol.docify(a->array);
+ }
+ if (hasFuncPtrType) // write the part of the argument type
+ // that comes after the name
+ {
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),
+ md,a->type.right(a->type.length()-vp));
+ }
+ if (!a->defval.isEmpty()) // write the default value
+ {
+ QCString n=a->defval;
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ ol.docify(" = ");
+
+ ol.startTypewriter();
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
+ ol.endTypewriter();
+
+ }
+ ++ali;
+ a=ali.current();
+ if (a)
+ {
+ if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
+ if (!isDefine)
+ {
+ QCString key;
+ if (md->isObjCMethod() && a->attrib.length()>=2)
+ {
+ //printf("Found parameter keyword %s\n",a->attrib.data());
+ // strip [ and ]
+ key=a->attrib.mid(1,a->attrib.length()-2);
+ if (key!=",") key+=":"; // for normal keywords add colon
+ }
+ ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
+ if (paramTypeStarted)
+ {
+ ol.endParameterType();
+ }
+ ol.startParameterType(FALSE,key);
+ paramTypeStarted=TRUE;
+ }
+ else // isDefine
+ {
+ ol.endParameterName(FALSE,FALSE,TRUE);
+ }
+ }
+ first=FALSE;
+ }
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Latex);
+ if (!md->isObjCMethod()) ol.docify(")"); // end argument list
+ ol.enableAll();
+ if (htmlOn) ol.enable(OutputGenerator::Html);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ if (first) ol.startParameterName(defArgList->count()<2);
+ ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
+ ol.popGeneratorState();
+ if (md->extraTypeChars())
+ {
+ ol.docify(md->extraTypeChars());
+ }
+ if (defArgList->constSpecifier)
+ {
+ ol.docify(" const");
+ }
+ if (defArgList->volatileSpecifier)
+ {
+ ol.docify(" volatile");
+ }
+ if (!defArgList->trailingReturnType.isEmpty())
+ {
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ cd, // scope
+ md->getBodyDef(), // fileScope
+ md, // self
+ defArgList->trailingReturnType, // text
+ FALSE // autoBreak
+ );
+
+ }
+ return TRUE;
+}
+
+static void writeExceptionListImpl(
+ OutputList &ol, ClassDef *cd, MemberDef *md, QCString const& exception)
+{
+ // this is ordinary exception spec - there must be a '('
+ //printf("exception='%s'\n",exception.data());
+ int index = exception.find('(');
+ if (index!=-1)
+ {
+ ol.exceptionEntry(exception.left(index),false);
+ ++index; // paren in second column so skip it here
+ for (int comma = exception.find(',', index); comma!=-1; )
+ {
+ ++comma; // include comma
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,
+ exception.mid(index,comma-index));
+ ol.exceptionEntry(0,false);
+ index=comma;
+ comma = exception.find(',', index);
+ }
+ int close = exception.find(')', index);
+ if (close!=-1)
+ {
+ QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,type);
+ ol.exceptionEntry(0,true);
+ }
+ else
+ {
+ warn(md->getDefFileName(),md->getDefLine(),
+ "missing ) in exception list on member %s",qPrint(md->name()));
+ }
+ }
+ else // Java Exception
+ {
+ ol.docify(" ");
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,exception);
+ }
+}
+
+static void writeExceptionList(OutputList &ol, ClassDef *cd, MemberDef *md)
+{
+ QCString exception(QCString(md->excpString()).stripWhiteSpace());
+ if ('{'==exception.at(0))
+ {
+ // this is an UNO IDL attribute - need special handling
+ int index = exception.find(';');
+ int oldIndex = 1;
+ while (-1 != index) // there should be no more than 2 (set / get)
+ {
+ // omit '{' and ';' -> "set raises (...)"
+ writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
+ oldIndex=index+1;
+ index = exception.find(';',oldIndex);
+ }
+ // the rest is now just '}' - omit that
+ }
+ else
+ {
+ writeExceptionListImpl(ol,cd,md,exception);
+ }
+}
+
+static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
+{
+ ol.docify("template<");
+ ArgumentListIterator ali(*al);
+ Argument *a = ali.current();
+ while (a)
+ {
+ ol.docify(a->type);
+ ol.docify(" ");
+ ol.docify(a->name);
+ if (a->defval.length()!=0)
+ {
+ ol.docify(" = ");
+ ol.docify(a->defval);
+ }
+ ++ali;
+ a=ali.current();
+ if (a) ol.docify(", ");
+ }
+ ol.docify("> ");
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+class MemberDefImpl
+{
+ public:
+ MemberDefImpl();
+ ~MemberDefImpl();
+ void init(Definition *def,const char *t,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,
+ MemberType mt,const ArgumentList *tal,
+ const ArgumentList *al
+ );
+
+ ClassDef *classDef; // member of or related to
+ FileDef *fileDef; // member of file definition
+ NamespaceDef *nspace; // the namespace this member is in.
+
+ MemberDef *enumScope; // the enclosing scope, if this is an enum field
+ bool livesInsideEnum;
+ MemberDef *annEnumType; // the anonymous enum that is the type of this member
+ MemberList *enumFields; // enumeration fields
+
+ MemberDef *redefines; // the members that this member redefines
+ MemberList *redefinedBy; // the list of members that redefine this one
+
+ MemberDef *memDef; // member definition for this declaration
+ MemberDef *memDec; // member declaration for this definition
+ ClassDef *relatedAlso; // points to class marked by relatedAlso
+
+ ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
+
+ QCString type; // return actual type
+ QCString accessorType; // return type that tell how to get to this member
+ ClassDef *accessorClass; // class that this member accesses (for anonymous types)
+ QCString args; // function arguments/variable array specifiers
+ QCString def; // member definition in code (fully qualified name)
+ QCString anc; // HTML anchor name
+ Specifier virt; // normal/virtual/pure virtual
+ Protection prot; // protection type [Public/Protected/Private]
+ QCString decl; // member declaration in class
+
+ QCString bitfields; // struct member bitfields
+ QCString read; // property read accessor
+ QCString write; // property write accessor
+ QCString exception; // exceptions that can be thrown
+ QCString initializer; // initializer
+ QCString extraTypeChars; // extra type info found after the argument list
+ QCString enumBaseType; // base type of the enum (C++11)
+ int initLines; // number of lines in the initializer
+
+ uint64 memSpec; // The specifiers present for this member
+ MemberType mtype; // returns the kind of member
+ int maxInitLines; // when the initializer will be displayed
+ int userInitLines; // result of explicit \hideinitializer or \showinitializer
+ MemberDef *annMemb;
+
+ ArgumentList *defArgList; // argument list of this member definition
+ ArgumentList *declArgList; // argument list of this member declaration
+
+ ArgumentList *tArgList; // template argument list of function template
+ ArgumentList *typeConstraints; // type constraints for template parameters
+ MemberDef *templateMaster;
+ QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
+ // (for template functions in nested template classes)
+
+ ClassDef *cachedAnonymousType; // if the member has an anonymous compound
+ // as its type then this is computed by
+ // getClassDefOfAnonymousType() and
+ // cached here.
+ SDict<MemberList> *classSectionSDict; // not accessible
+
+ MemberDef *groupAlias; // Member containing the definition
+ int grpId; // group id
+ MemberGroup *memberGroup; // group's member definition
+ GroupDef *group; // group in which this member is in
+ Grouping::GroupPri_t grouppri; // priority of this definition
+ QCString groupFileName; // file where this grouping was defined
+ int groupStartLine; // line " " " " "
+ MemberDef *groupMember;
+
+ bool isTypedefValCached;
+ ClassDef *cachedTypedefValue;
+ QCString cachedTypedefTemplSpec;
+ QCString cachedResolvedType;
+
+ // inbody documentation
+ //int inbodyLine;
+ //QCString inbodyFile;
+ //QCString inbodyDocs;
+
+ // documentation inheritance
+ MemberDef *docProvider;
+
+ // to store the output file base from tag files
+ QCString explicitOutputFileBase;
+
+ // objective-c
+ bool implOnly; // function found in implementation but not
+ // in the interface
+ bool hasDocumentedParams;
+ bool hasDocumentedReturnType;
+ bool isDMember;
+ Relationship related; // relationship of this to the class
+ bool stat; // is it a static function?
+ bool proto; // is it a prototype;
+ bool docEnumValues; // is an enum with documented enum values.
+ bool annScope; // member is part of an annoymous scope
+ bool annUsed;
+ bool hasCallGraph;
+ bool hasCallerGraph;
+ bool explExt; // member was explicitly declared external
+ bool tspec; // member is a template specialization
+ bool groupHasDocs; // true if the entry that caused the grouping was documented
+ bool docsForDefinition; // TRUE => documentation block is put before
+ // definition.
+ // FALSE => block is put before declaration.
+ ClassDef *category;
+ MemberDef *categoryRelation;
+
+ unsigned tagDataWritten;
+};
+
+MemberDefImpl::MemberDefImpl() :
+ enumFields(0),
+ redefinedBy(0),
+ exampleSDict(0),
+ defArgList(0),
+ declArgList(0),
+ tArgList(0),
+ typeConstraints(0),
+ defTmpArgLists(0),
+ classSectionSDict(0),
+ category(0),
+ categoryRelation(0)
+{
+}
+
+MemberDefImpl::~MemberDefImpl()
+{
+ delete redefinedBy;
+ delete exampleSDict;
+ delete enumFields;
+ delete defArgList;
+ delete tArgList;
+ delete typeConstraints;
+ delete defTmpArgLists;
+ delete classSectionSDict;
+ delete declArgList;
+}
+
+void MemberDefImpl::init(Definition *def,
+ const char *t,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,
+ MemberType mt,const ArgumentList *tal,
+ const ArgumentList *al
+ )
+{
+ classDef=0;
+ fileDef=0;
+ redefines=0;
+ relatedAlso=0;
+ redefinedBy=0;
+ accessorClass=0;
+ nspace=0;
+ memDef=0;
+ memDec=0;
+ group=0;
+ grpId=-1;
+ exampleSDict=0;
+ enumFields=0;
+ enumScope=0;
+ livesInsideEnum=FALSE;
+ defTmpArgLists=0;
+ hasCallGraph = FALSE;
+ hasCallerGraph = FALSE;
+ initLines=0;
+ type=t;
+ if (mt==MemberType_Typedef) type.stripPrefix("typedef ");
+ // type.stripPrefix("struct ");
+ // type.stripPrefix("class " );
+ // type.stripPrefix("union " );
+ type=removeRedundantWhiteSpace(type);
+ args=a;
+ args=removeRedundantWhiteSpace(args);
+ if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
+
+ memberGroup=0;
+ virt=v;
+ prot=p;
+ related=r;
+ stat=s;
+ mtype=mt;
+ exception=e;
+ proto=FALSE;
+ annScope=FALSE;
+ memSpec=0;
+ annMemb=0;
+ annUsed=FALSE;
+ annEnumType=0;
+ groupAlias=0;
+ explExt=FALSE;
+ tspec=FALSE;
+ cachedAnonymousType=0;
+ maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
+ userInitLines=-1;
+ docEnumValues=FALSE;
+ // copy function template arguments (if any)
+ if (tal)
+ {
+ tArgList = tal->deepCopy();
+ }
+ else
+ {
+ tArgList=0;
+ }
+ //printf("new member al=%p\n",al);
+ // copy function definition arguments (if any)
+ if (al)
+ {
+ defArgList = al->deepCopy();
+ }
+ else
+ {
+ defArgList=0;
+ }
+ // convert function declaration arguments (if any)
+ if (!args.isEmpty())
+ {
+ declArgList = new ArgumentList;
+ stringToArgumentList(args,declArgList,&extraTypeChars);
+ //printf("setDeclArgList %s to %s const=%d\n",args.data(),
+ // argListToString(declArgList).data(),declArgList->constSpecifier);
+ }
+ else
+ {
+ declArgList = 0;
+ }
+ templateMaster = 0;
+ classSectionSDict = 0;
+ docsForDefinition = TRUE;
+ isTypedefValCached = FALSE;
+ cachedTypedefValue = 0;
+ //inbodyLine = -1;
+ implOnly=FALSE;
+ groupMember = 0;
+ hasDocumentedParams = FALSE;
+ hasDocumentedReturnType = FALSE;
+ docProvider = 0;
+ isDMember = def->getDefFileName().right(2).lower()==".d";
+ tagDataWritten = 0; // save separate written status for file, group, class, etc.
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+/*! Creates a new member definition.
+ *
+ * \param df File containing the definition of this member.
+ * \param dl Line at which the member definition was found.
+ * \param dc Column at which the member definition was found.
+ * \param t A string representing the type of the member.
+ * \param na A string representing the name of the member.
+ * \param a A string representing the arguments of the member.
+ * \param e A string representing the throw clause of the members.
+ * \param p The protection context of the member, possible values are:
+ * \c Public, \c Protected, \c Private.
+ * \param v The degree of `virtualness' of the member, possible values are:
+ * \c Normal, \c Virtual, \c Pure.
+ * \param s A boolean that is true iff the member is static.
+ * \param r The relationship between the class and the member.
+ * \param mt The kind of member. See #MemberType for a list of
+ * all types.
+ * \param tal The template arguments of this member.
+ * \param al The arguments of this member. This is a structured form of
+ * the string past as argument \a a.
+ */
+
+MemberDef::MemberDef(const char *df,int dl,int dc,
+ const char *t,const char *na,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,MemberType mt,
+ const ArgumentList *tal,const ArgumentList *al
+ ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na))
+{
+ //printf("MemberDef::MemberDef(%s)\n",na);
+ m_impl = new MemberDefImpl;
+ m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ m_isDestructorCached = 0;
+}
+
+MemberDef::MemberDef(const MemberDef &md) : Definition(md)
+{
+ m_impl = new MemberDefImpl;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ m_isDestructorCached = 0;
+}
+
+MemberDef *MemberDef::deepCopy() const
+{
+ //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
+ MemberDef *result = new MemberDef(*this);
+ // first copy everything by reference
+ *result->m_impl = *m_impl;
+ // clear pointers owned by object
+ result->m_impl->redefinedBy= 0;
+ result->m_impl->exampleSDict=0;
+ result->m_impl->enumFields=0;
+ result->m_impl->defArgList=0;
+ result->m_impl->tArgList=0;
+ result->m_impl->typeConstraints=0;
+ result->m_impl->defTmpArgLists=0;
+ result->m_impl->classSectionSDict=0;
+ result->m_impl->declArgList=0;
+ // replace pointers owned by the object by deep copies
+ if (m_impl->redefinedBy)
+ {
+ MemberListIterator mli(*m_impl->redefinedBy);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ result->insertReimplementedBy(md);
+ }
+ }
+ if (m_impl->exampleSDict)
+ {
+ ExampleSDict::Iterator it(*m_impl->exampleSDict);
+ Example *e;
+ for (it.toFirst();(e=it.current());++it)
+ {
+ result->addExample(e->anchor,e->name,e->file);
+ }
+ }
+ if (m_impl->enumFields)
+ {
+ MemberListIterator mli(*m_impl->enumFields);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ result->insertEnumField(md);
+ }
+ }
+ if (m_impl->defArgList)
+ {
+ result->m_impl->defArgList = m_impl->defArgList->deepCopy();
+ }
+ if (m_impl->tArgList)
+ {
+ result->m_impl->tArgList = m_impl->tArgList->deepCopy();
+ }
+ if (m_impl->typeConstraints)
+ {
+ result->m_impl->typeConstraints = m_impl->typeConstraints->deepCopy();
+ }
+ result->setDefinitionTemplateParameterLists(m_impl->defTmpArgLists);
+ if (m_impl->classSectionSDict)
+ {
+ result->m_impl->classSectionSDict = new SDict<MemberList>(7);
+ SDict<MemberList>::IteratorDict it(*m_impl->classSectionSDict);
+ MemberList *ml;
+ for (it.toFirst();(ml=it.current());++it)
+ {
+ result->m_impl->classSectionSDict->append(it.currentKey(),ml);
+ }
+ }
+ if (m_impl->declArgList)
+ {
+ result->m_impl->declArgList = m_impl->declArgList->deepCopy();
+ }
+ return result;
+}
+
+void MemberDef::moveTo(Definition *scope)
+{
+ setOuterScope(scope);
+ if (scope->definitionType()==Definition::TypeClass)
+ {
+ m_impl->classDef = (ClassDef*)scope;
+ }
+ else if (scope->definitionType()==Definition::TypeFile)
+ {
+ m_impl->fileDef = (FileDef*)scope;
+ }
+ else if (scope->definitionType()==Definition::TypeNamespace)
+ {
+ m_impl->nspace = (NamespaceDef*)scope;
+ }
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+}
+
+
+/*! Destroys the member definition. */
+MemberDef::~MemberDef()
+{
+ delete m_impl;
+ //printf("%p: ~MemberDef()\n",this);
+ m_impl=0;
+}
+
+void MemberDef::setReimplements(MemberDef *md)
+{
+ m_impl->redefines = md;
+}
+
+void MemberDef::insertReimplementedBy(MemberDef *md)
+{
+ if (m_impl->templateMaster)
+ {
+ m_impl->templateMaster->insertReimplementedBy(md);
+ }
+ if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberListType_redefinedBy);
+ if (m_impl->redefinedBy->findRef(md)==-1)
+ {
+ m_impl->redefinedBy->inSort(md);
+ }
+}
+
+MemberDef *MemberDef::reimplements() const
+{
+ return m_impl->redefines;
+}
+
+MemberList *MemberDef::reimplementedBy() const
+{
+ return m_impl->redefinedBy;
+}
+
+bool MemberDef::isReimplementedBy(ClassDef *cd) const
+{
+ if (cd && m_impl->redefinedBy)
+ {
+ MemberListIterator mi(*m_impl->redefinedBy);
+ MemberDef *md;
+ for (mi.toFirst();(md=mi.current());++mi)
+ {
+ ClassDef *mcd = md->getClassDef();
+ if (mcd)
+ {
+ if (cd==mcd || cd->isBaseClass(mcd,TRUE))
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+void MemberDef::insertEnumField(MemberDef *md)
+{
+ if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberListType_enumFields);
+ m_impl->enumFields->append(md);
+}
+
+bool MemberDef::addExample(const char *anchor,const char *nameStr,
+ const char *file)
+{
+ //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
+ if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
+ if (m_impl->exampleSDict->find(nameStr)==0)
+ {
+ //printf("Add reference to example %s to member %s\n",nameStr,name.data());
+ Example *e=new Example;
+ e->anchor=anchor;
+ e->name=nameStr;
+ e->file=file;
+ m_impl->exampleSDict->inSort(nameStr,e);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool MemberDef::hasExamples()
+{
+ if (m_impl->exampleSDict==0)
+ return FALSE;
+ else
+ return m_impl->exampleSDict->count()>0;
+}
+
+QCString MemberDef::getOutputFileBase() const
+{
+ static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ QCString baseName;
+
+ //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
+ // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
+ // m_impl->nspace,m_impl->fileDef);
+ if (!m_impl->explicitOutputFileBase.isEmpty())
+ {
+ return m_impl->explicitOutputFileBase;
+ }
+ else if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (m_impl->group)
+ {
+ baseName=m_impl->group->getOutputFileBase();
+ }
+ else if (m_impl->classDef)
+ {
+ baseName=m_impl->classDef->getOutputFileBase();
+ if (inlineSimpleClasses && m_impl->classDef->isSimple())
+ {
+ return baseName;
+ }
+ }
+ else if (m_impl->nspace)
+ {
+ baseName=m_impl->nspace->getOutputFileBase();
+ }
+ else if (m_impl->fileDef)
+ {
+ baseName=m_impl->fileDef->getOutputFileBase();
+ }
+
+ if (baseName.isEmpty())
+ {
+ warn(getDefFileName(),getDefLine(),
+ "Internal inconsistency: member %s does not belong to any"
+ " container!",qPrint(name())
+ );
+ return "dummy";
+ }
+ else if (separateMemberPages && isDetailedSectionLinkable())
+ {
+ if (getEnumScope()) // enum value, which is part of enum's documentation
+ {
+ baseName+="_"+getEnumScope()->anchor();
+ }
+ else
+ {
+ baseName+="_"+anchor();
+ }
+ }
+ return baseName;
+}
+
+QCString MemberDef::getReference() const
+{
+ QCString ref = Definition::getReference();
+ if (!ref.isEmpty())
+ {
+ return ref;
+ }
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getReference();
+ }
+ else if (m_impl->group)
+ {
+ return m_impl->group->getReference();
+ }
+ else if (m_impl->classDef)
+ {
+ return m_impl->classDef->getReference();
+ }
+ else if (m_impl->nspace)
+ {
+ return m_impl->nspace->getReference();
+ }
+ else if (m_impl->fileDef)
+ {
+ return m_impl->fileDef->getReference();
+ }
+ return "";
+}
+
+QCString MemberDef::anchor() const
+{
+ QCString result=m_impl->anc;
+ if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
+ if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
+ if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
+ {
+ result.prepend(m_impl->enumScope->anchor());
+ }
+ if (m_impl->group)
+ {
+ if (m_impl->groupMember)
+ {
+ result=m_impl->groupMember->anchor();
+ }
+ else if (getReference().isEmpty())
+ {
+ result.prepend("g");
+ }
+ }
+ return result;
+}
+
+void MemberDef::_computeLinkableInProject()
+{
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ m_isLinkableCached = 2; // linkable
+ //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
+ if (isHidden())
+ {
+ //printf("is hidden\n");
+ m_isLinkableCached = 1;
+ return;
+ }
+ if (m_impl->templateMaster)
+ {
+ //printf("has template master\n");
+ m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1;
+ return;
+ }
+ if (name().isEmpty() || name().at(0)=='@')
+ {
+ //printf("name invalid\n");
+ m_isLinkableCached = 1; // not a valid or a dummy name
+ return;
+ }
+ if (!hasDocumentation() && !isReference())
+ {
+ //printf("no docs or reference\n");
+ m_isLinkableCached = 1; // no documentation
+ return;
+ }
+ if (m_impl->group && !m_impl->group->isLinkableInProject())
+ {
+ //printf("group but group not linkable!\n");
+ m_isLinkableCached = 1; // group but group not linkable
+ return;
+ }
+ if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject())
+ {
+ //printf("in a class but class not linkable!\n");
+ m_isLinkableCached = 1; // in class but class not linkable
+ return;
+ }
+ if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject())
+ {
+ //printf("in a namespace but namespace not linkable!\n");
+ m_isLinkableCached = 1; // in namespace but namespace not linkable
+ return;
+ }
+ if (!m_impl->group && !m_impl->nspace &&
+ !m_impl->related && !m_impl->classDef &&
+ m_impl->fileDef && !m_impl->fileDef->isLinkableInProject())
+ {
+ //printf("in a file but file not linkable!\n");
+ m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
+ return;
+ }
+ if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend)
+ {
+ //printf("private and invisible!\n");
+ m_isLinkableCached = 1; // hidden due to protection
+ return;
+ }
+ if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
+ {
+ //printf("static and invisible!\n");
+ m_isLinkableCached = 1; // hidden due to staticness
+ return;
+ }
+ //printf("linkable!\n");
+ return; // linkable!
+}
+
+void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
+{
+ Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
+{
+ Definition::setBriefDescription(b,briefFile,briefLine);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
+{
+ Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setHidden(bool b)
+{
+ Definition::setHidden(b);
+ m_isLinkableCached = 0;
+}
+
+bool MemberDef::isLinkableInProject() const
+{
+ if (m_isLinkableCached==0)
+ {
+ MemberDef *that = (MemberDef*)this;
+ that->_computeLinkableInProject();
+ }
+ ASSERT(m_isLinkableCached>0);
+ return m_isLinkableCached==2;
+}
+
+bool MemberDef::isLinkable() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkable();
+ }
+ else
+ {
+ return isLinkableInProject() || isReference();
+ }
+}
+
+
+void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
+{
+ if (lists)
+ {
+ if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
+ m_impl->defTmpArgLists = copyArgumentLists(lists);
+ }
+}
+
+void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
+ FileDef *fd,GroupDef *gd,bool onlyText)
+{
+ SrcLangExt lang = getLanguage();
+ static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ QCString n = name();
+ if (!hideScopeNames)
+ {
+ if (m_impl->enumScope && m_impl->livesInsideEnum)
+ {
+ n.prepend(m_impl->enumScope->displayName()+sep);
+ }
+ if (m_impl->classDef && gd && !isRelated())
+ {
+ n.prepend(m_impl->classDef->displayName()+sep);
+ }
+ else if (m_impl->nspace && (gd || fd))
+ {
+ n.prepend(m_impl->nspace->displayName()+sep);
+ }
+ }
+
+ if (isObjCMethod())
+ {
+ if (isStatic()) ol.docify("+ "); else ol.docify("- ");
+ }
+ if (!onlyText && isLinkable()) // write link
+ {
+ if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped
+ getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
+ {
+ GroupDef *enumValGroup = getEnumScope()->getGroupDef();
+ ol.writeObjectLink(enumValGroup->getReference(),
+ enumValGroup->getOutputFileBase(),
+ anchor(),n);
+ }
+ else
+ {
+ ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
+ }
+ }
+ else // write only text
+ {
+ ol.startBold();
+ ol.docify(n);
+ ol.endBold();
+ }
+}
+
+/*! If this member has an anonymous class/struct/union as its type, then
+ * this method will return the ClassDef that describes this return type.
+ */
+ClassDef *MemberDef::getClassDefOfAnonymousType()
+{
+ if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
+
+ QCString cname;
+ if (getClassDef()!=0)
+ {
+ cname=getClassDef()->name().copy();
+ }
+ else if (getNamespaceDef()!=0)
+ {
+ cname=getNamespaceDef()->name().copy();
+ }
+ QCString ltype(m_impl->type);
+ // strip `static' keyword from ltype
+ //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
+ // strip `friend' keyword from ltype
+ ltype.stripPrefix("friend ");
+ static QRegExp r("@[0-9]+");
+ int l,i=r.match(ltype,0,&l);
+ //printf("ltype=`%s' i=%d\n",ltype.data(),i);
+ // search for the last anonymous scope in the member type
+ ClassDef *annoClassDef=0;
+ if (i!=-1) // found anonymous scope in type
+ {
+ int il=i-1,ir=i+l;
+ // extract anonymous scope
+ while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
+ if (il>0) il++; else if (il<0) il=0;
+ while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
+
+ QCString annName = ltype.mid(il,ir-il);
+
+ // if inside a class or namespace try to prepend the scope name
+ if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
+ {
+ QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
+ annoClassDef=getClass(ts);
+ }
+ // if not found yet, try without scope name
+ if (annoClassDef==0)
+ {
+ QCString ts=stripAnonymousNamespaceScope(annName);
+ annoClassDef=getClass(ts);
+ }
+ }
+ m_impl->cachedAnonymousType = annoClassDef;
+ return annoClassDef;
+}
+
+/*! This methods returns TRUE iff the brief section (also known as
+ * declaration section) is visible in the documentation.
+ */
+bool MemberDef::isBriefSectionVisible() const
+{
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
+
+ //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
+ // name().data(),
+ // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
+ // "", //getFileDef()->name().data(),
+ // argsString());
+
+ MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
+ //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
+ //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
+ bool hasDocs = hasDocumentation() ||
+ // part of a documented member group
+ (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
+
+ // only include static members with file/namespace scope if
+ // explicitly enabled in the config file
+ bool visibleIfStatic = !(getClassDef()==0 &&
+ isStatic() &&
+ !extractStatic
+ );
+
+ // only include members is the are documented or
+ // HIDE_UNDOC_MEMBERS is NO in the config file
+ bool visibleIfDocumented = (!hideUndocMembers ||
+ hasDocs ||
+ isDocumentedFriendClass()
+ );
+
+ // hide members with no detailed description and brief descriptions
+ // explicitly disabled.
+ bool visibleIfEnabled = !(hideUndocMembers &&
+ documentation().isEmpty() &&
+ !briefMemberDesc &&
+ !repeatBrief
+ );
+
+ // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
+ bool visibleIfFriendCompound = !(hideFriendCompounds &&
+ isFriend() &&
+ (m_impl->type=="friend class" ||
+ m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"
+ )
+ );
+
+ // only include members that are non-private unless EXTRACT_PRIVATE is
+ // set to YES or the member is part of a group
+ bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
+ m_impl->mtype==MemberType_Friend
+ );
+
+ // hide member if it overrides a member in a superclass and has no
+ // documentation of its own
+ //bool visibleIfDocVirtual = !reimplements() ||
+ // !Config_getBool("INHERIT_DOCS") ||
+ // hasDocs;
+
+ // true if this member is a constructor or destructor
+ bool cOrDTor = isConstructor() || isDestructor();
+
+ // hide default constructors or destructors (no args) without
+ // documentation
+ bool visibleIfNotDefaultCDTor = !(cOrDTor &&
+ m_impl->defArgList &&
+ (m_impl->defArgList->isEmpty() ||
+ m_impl->defArgList->getFirst()->type == "void"
+ ) &&
+ !hasDocs
+ );
+
+
+ //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
+ // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
+ // "visibleIfFriendCompound=%d !annScope=%d\n",
+ // visibleIfStatic,visibleIfDocumented,
+ // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
+ // visibleIfFriendCompound,!m_impl->annScope);
+
+ bool visible = visibleIfStatic && visibleIfDocumented &&
+ visibleIfEnabled && visibleIfPrivate &&
+ /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
+ visibleIfFriendCompound &&
+ !m_impl->annScope && !isHidden();
+ //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
+ return visible;
+}
+
+QCString MemberDef::getDeclType() const
+{
+ QCString ltype(m_impl->type);
+ if (m_impl->mtype==MemberType_Typedef)
+ {
+ ltype.prepend("typedef ");
+ }
+ if (isAlias())
+ {
+ ltype="using";
+ }
+ // strip `friend' keyword from ltype
+ ltype.stripPrefix("friend ");
+ if (ltype=="@") // rename type from enum values
+ {
+ ltype="";
+ }
+ else
+ {
+ if (isObjCMethod())
+ {
+ ltype.prepend("(");
+ ltype.append(")");
+ }
+ }
+ return ltype;
+}
+
+void MemberDef::writeDeclaration(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool inGroup, const DefType compoundType,
+ ClassDef *inheritedFrom,const char *inheritId)
+{
+ //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup);
+
+ // hide enum value, since they appear already as part of the enum, unless they
+ // are explicitly grouped.
+ if (!inGroup && m_impl->mtype==MemberType_EnumValue) return;
+
+ Definition *d=0;
+ ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
+ if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
+
+ _writeTagData(compoundType);
+ _addToSearchIndex();
+
+ QCString cname = d->name();
+ QCString cdname = d->displayName();
+ QCString cfname = getOutputFileBase();
+
+ // search for the last anonymous scope in the member type
+ ClassDef *annoClassDef=getClassDefOfAnonymousType();
+
+ ol.startMemberDeclaration();
+
+ // start a new member declaration
+ bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
+ ///printf("startMemberItem for %s\n",name().data());
+ ol.startMemberItem(anchor(),
+ isAnonymous ? 1 : m_impl->tArgList ? 3 : 0,
+ inheritId
+ );
+
+ // If there is no detailed description we need to write the anchor here.
+ bool detailsVisible = isDetailedSectionLinkable();
+ if (!detailsVisible)
+ {
+ QCString doxyArgs=argsString();
+ if (!m_impl->annMemb)
+ {
+ QCString doxyName=name();
+ if (!cname.isEmpty())
+ {
+ doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
+ }
+ ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
+ }
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.docify("\n");
+ ol.popGeneratorState();
+ }
+
+ if (annoClassDef || m_impl->annMemb)
+ {
+ int j;
+ for (j=0;j<s_indentLevel;j++)
+ {
+ ol.writeNonBreakableSpace(3);
+ }
+ }
+
+ // *** write template lists
+ if (m_impl->tArgList && getLanguage()==SrcLangExt_Cpp)
+ {
+ if (!isAnonymous) ol.startMemberTemplateParams();
+ writeTemplatePrefix(ol,m_impl->tArgList);
+ if (!isAnonymous) ol.endMemberTemplateParams(anchor(),inheritId);
+ }
+
+ // *** write type
+ QCString ltype(m_impl->type);
+ if (m_impl->mtype==MemberType_Typedef) ltype.prepend("typedef ");
+ if (isAlias())
+ {
+ ltype="using";
+ }
+ // strip `friend' keyword from ltype
+ ltype.stripPrefix("friend ");
+ static QRegExp r("@[0-9]+");
+
+ bool endAnonScopeNeeded=FALSE;
+ int l,i=r.match(ltype,0,&l);
+ if (i!=-1) // member has an anonymous type
+ {
+ //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
+ // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
+
+ if (annoClassDef) // type is an anonymous compound
+ {
+ int ir=i+l;
+ //printf("<<<<<<<<<<<<<<\n");
+ ol.startAnonTypeScope(s_indentLevel++);
+ annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
+ //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
+ ol.startMemberItem(anchor(),2,inheritId);
+ int j;
+ for (j=0;j< s_indentLevel-1;j++)
+ {
+ ol.writeNonBreakableSpace(3);
+ }
+ QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
+ //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data());
+ ol.docify("}");
+ if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
+ {
+ ol.docify(";");
+ }
+ endAnonScopeNeeded=TRUE;
+ }
+ else
+ {
+ if (getAnonymousEnumType()) // type is an anonymous enum
+ {
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ this, // self
+ ltype.left(i), // text
+ TRUE // autoBreak
+ );
+ getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd,compoundType);
+ //ol+=*getAnonymousEnumType()->enumDecl();
+ linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE);
+ }
+ else
+ {
+ ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ this, // self
+ ltype, // text
+ TRUE // autoBreak
+ );
+ }
+ }
+ }
+ else if (ltype=="@") // rename type from enum values
+ {
+ ltype="";
+ }
+ else
+ {
+ if (isObjCMethod())
+ {
+ ltype.prepend("(");
+ ltype.append(")");
+ }
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ this, // self
+ ltype, // text
+ TRUE // autoBreak
+ );
+ }
+ bool htmlOn = ol.isEnabled(OutputGenerator::Html);
+ if (htmlOn && !ltype.isEmpty())
+ {
+ ol.disable(OutputGenerator::Html);
+ }
+ if (!ltype.isEmpty()) ol.docify(" ");
+ if (htmlOn)
+ {
+ ol.enable(OutputGenerator::Html);
+ }
+
+ if (m_impl->annMemb)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeNonBreakableSpace(3);
+ ol.popGeneratorState();
+ }
+ else
+ {
+ ol.insertMemberAlign(m_impl->tArgList!=0);
+ }
+
+ // *** write name
+ if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
+ {
+ //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
+ if (!(name().isEmpty() || name().at(0)=='@') && // name valid
+ (hasDocumentation() || isReference()) && // has docs
+ !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
+ !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness
+ )
+ {
+ if (m_impl->annMemb)
+ {
+ //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
+ m_impl->annMemb->writeLink(ol,
+ m_impl->annMemb->getClassDef(),
+ m_impl->annMemb->getNamespaceDef(),
+ m_impl->annMemb->getFileDef(),
+ m_impl->annMemb->getGroupDef()
+ );
+ m_impl->annMemb->setAnonymousUsed();
+ setAnonymousUsed();
+ }
+ else
+ {
+ //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
+ ClassDef *rcd = cd;
+ if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
+ writeLink(ol,rcd,nd,fd,gd);
+ }
+ }
+ else if (isDocumentedFriendClass())
+ // if the member is an undocumented friend declaration for some class,
+ // then maybe we can link to the class
+ {
+ writeLink(ol,getClass(name()),0,0,0);
+ }
+ else
+ // there is a brief member description and brief member
+ // descriptions are enabled or there is no detailed description.
+ {
+ if (m_impl->annMemb)
+ {
+ m_impl->annMemb->setAnonymousUsed();
+ setAnonymousUsed();
+ }
+ ClassDef *rcd = cd;
+ if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
+ writeLink(ol,rcd,nd,fd,gd,TRUE);
+ }
+ }
+
+ // add to index
+ if (isEnumerate() && name().at(0)=='@')
+ {
+ // don't add to index
+ }
+ else // index member
+ {
+ //static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ //QCString cfname = getOutputFileBase();
+ //QCString cfiname = d->getOutputFileBase();
+ //Doxygen::indexList->addIndexItem(
+ // cname, // level1
+ // name(), // level2
+ // separateMemPages ? cfname : cfiname, // contRef
+ // cfname, // memRef
+ // anchor(), // anchor
+ // this); // memberdef
+ Doxygen::indexList->addIndexItem(d,this);
+ }
+
+ // *** write arguments
+ if (argsString() && !isObjCMethod())
+ {
+ if (!isDefine()) ol.writeString(" ");
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ this, // self
+ argsString(), // text
+ m_impl->annMemb, // autoBreak
+ TRUE, // external
+ FALSE, // keepSpaces
+ s_indentLevel
+ );
+ }
+ // *** write exceptions
+ if (excpString())
+ {
+ ol.writeString(" ");
+ ol.docify(excpString());
+ }
+
+ // *** write bitfields
+ if (!m_impl->bitfields.isEmpty()) // add bitfields
+ {
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields);
+ }
+ else if (hasOneLineInitializer()
+ //!init.isEmpty() && initLines==0 && // one line initializer
+ //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
+ ) // add initializer
+ {
+ if (!isDefine())
+ {
+ //ol.writeString(" = ");
+ ol.writeString(" ");
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer.simplifyWhiteSpace());
+ }
+ else
+ {
+ ol.writeNonBreakableSpace(3);
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer);
+ }
+ }
+ else if (isAlias()) // using template alias
+ {
+ ol.writeString(" = ");
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->type);
+ }
+
+
+ if ((isObjCMethod() || isObjCProperty()) && isImplementation())
+ {
+ ol.startTypewriter();
+ ol.docify(" [implementation]");
+ ol.endTypewriter();
+ }
+
+ bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+
+ if (isProperty() && (isSettable() || isGettable() ||
+ isPrivateSettable() || isPrivateGettable() ||
+ isProtectedSettable() || isProtectedGettable()))
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+
+ if (isGettable()) sl.append("get");
+ if (isProtectedGettable()) sl.append("protected get");
+ if (isSettable()) sl.append("set");
+ if (isProtectedSettable()) sl.append("protected set");
+ if (extractPrivate)
+ {
+ if (isPrivateGettable()) sl.append("private get");
+ if (isPrivateSettable()) sl.append("private set");
+ }
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+
+ if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (isAddable()) sl.append("add");
+ if (isRemovable()) sl.append("remove");
+ if (isRaisable()) sl.append("raise");
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+
+ if (!detailsVisible && !m_impl->annMemb)
+ {
+ ol.endDoxyAnchor(cfname,anchor());
+ }
+
+ //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
+ // name().data(),annoClassDef,annEnumType);
+ ol.endMemberItem();
+ if (endAnonScopeNeeded)
+ {
+ ol.endAnonTypeScope(--s_indentLevel);
+ }
+
+ // write brief description
+ if (!briefDescription().isEmpty() &&
+ Config_getBool("BRIEF_MEMBER_DESC")
+ /* && !annMemb */
+ )
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():d,this,briefDescription(),
+ TRUE,FALSE,0,TRUE,FALSE);
+
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startMemberDescription(anchor(),inheritId);
+ ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this);
+ if (detailsVisible)
+ {
+ static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ //ol.endEmphasis();
+ ol.docify(" ");
+ if (separateMemberPages || (m_impl->group!=0 && gd==0)) // forward link to the page or group
+ {
+ ol.startTextLink(getOutputFileBase(),anchor());
+ }
+ else // local link
+ {
+ ol.startTextLink(0,anchor());
+ }
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ //ol.startEmphasis();
+ ol.popGeneratorState();
+ }
+ // for RTF we need to add an extra empty paragraph
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::RTF);
+ ol.startParagraph();
+ ol.endParagraph();
+ ol.popGeneratorState();
+ ol.endMemberDescription();
+ }
+ delete rootNode;
+ }
+
+ ol.endMemberDeclaration(anchor(),inheritId);
+
+ warnIfUndocumented();
+}
+
+bool MemberDef::isDetailedSectionLinkable() const
+{
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ static bool alwaysDetailedSec = Config_getBool("ALWAYS_DETAILED_SEC");
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+
+ // the member has details documentation for any of the following reasons
+ bool docFilter =
+ // treat everything as documented
+ extractAll ||
+ // has detailed docs
+ !documentation().isEmpty() ||
+ // has inbody docs
+ !inbodyDocumentation().isEmpty() ||
+ // is an enum with values that are documented
+ (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) ||
+ // is documented enum value
+ (m_impl->mtype==MemberType_EnumValue && !briefDescription().isEmpty()) ||
+ // has brief description that is part of the detailed description
+ (!briefDescription().isEmpty() && // has brief docs
+ (alwaysDetailedSec && // they are visible in
+ (repeatBrief || // detailed section or
+ !briefMemberDesc // they are explicitly not
+ ) // shown in brief section
+ )
+ ) ||
+ // has a multi-line initialization block
+ //(initLines>0 && initLines<maxInitLines) ||
+ (hasMultiLineInitializer() && !hideUndocMembers) ||
+ // has one or more documented arguments
+ (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
+ // is an attribute or property - need to display that tag
+ (m_impl->memSpec & (Entry::Attribute|Entry::Property)) ||
+ // has user comments
+ Doxygen::userComments
+ ;
+
+ // this is not a global static or global statics should be extracted
+ bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
+
+ // only include members that are non-private unless EXTRACT_PRIVATE is
+ // set to YES or the member is part of a group
+ bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend;
+
+ // member is part of an anonymous scope that is the type of
+ // another member in the list.
+ //
+ //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
+
+ // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
+ // is true
+ bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
+ isFriend() &&
+ (m_impl->type=="friend class" ||
+ m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"
+ )
+ );
+
+
+ bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
+ //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
+ return result;
+}
+
+bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
+{
+ static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ static bool inlineSimpleStructs = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
+ bool fileFilter = getNamespaceDef()==0 || !inFile;
+ bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs &&
+ getClassDef()!=0 && getClassDef()->isSimple();
+
+ bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
+ !isReference();
+ bool result = visible || simpleFilter;
+ //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
+ // name().data(),result,groupFilter,fileFilter);
+ return result;
+}
+
+void MemberDef::getLabels(QStrList &sl,Definition *container) const
+{
+ static bool inlineInfo = Config_getBool("INLINE_INFO");
+
+ Specifier lvirt=virtualness();
+ if ((!isObjCMethod() || isOptional() || isRequired()) &&
+ (protection()!=Public || lvirt!=Normal ||
+ isFriend() || isRelated() ||
+ (isInline() && inlineInfo) ||
+ isSignal() || isSlot() ||
+ isStatic() ||
+ (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
+ (m_impl->memSpec & ~Entry::Inline)!=0
+ )
+ )
+ {
+ // write the member specifier list
+ //ol.writeLatexSpacing();
+ //ol.startTypewriter();
+ //ol.docify(" [");
+ SrcLangExt lang = getLanguage();
+ bool optVhdl = lang==SrcLangExt_VHDL;
+ bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ if (optVhdl)
+ {
+ sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
+ }
+ else
+ {
+ if (isFriend()) sl.append("friend");
+ else if (isRelated()) sl.append("related");
+ else
+ {
+ if (Config_getBool("INLINE_INFO") && isInline()) sl.append("inline");
+ if (isExplicit()) sl.append("explicit");
+ if (isMutable()) sl.append("mutable");
+ if (isStatic()) sl.append("static");
+ if (isGettable()) sl.append("get");
+ if (isProtectedGettable()) sl.append("protected get");
+ if (isSettable()) sl.append("set");
+ if (isProtectedSettable()) sl.append("protected set");
+ if (extractPrivate)
+ {
+ if (isPrivateGettable()) sl.append("private get");
+ if (isPrivateSettable()) sl.append("private set");
+ }
+ if (isAddable()) sl.append("add");
+ if (!isUNOProperty() && isRemovable()) sl.append("remove");
+ if (isRaisable()) sl.append("raise");
+ if (isReadable()) sl.append("read");
+ if (isWritable()) sl.append("write");
+ if (isFinal()) sl.append("final");
+ if (isAbstract()) sl.append("abstract");
+ if (isOverride()) sl.append("override");
+ if (isInitonly()) sl.append("initonly");
+ if (isSealed()) sl.append("sealed");
+ if (isNew()) sl.append("new");
+ if (isOptional()) sl.append("optional");
+ if (isRequired()) sl.append("required");
+
+ if (isNonAtomic()) sl.append("nonatomic");
+ else if (isObjCProperty()) sl.append("atomic");
+
+ // mutual exclusive Objective 2.0 property attributes
+ if (isAssign()) sl.append("assign");
+ else if (isCopy()) sl.append("copy");
+ else if (isRetain()) sl.append("retain");
+ else if (isWeak()) sl.append("weak");
+ else if (isStrong()) sl.append("strong");
+ else if (isUnretained()) sl.append("unsafe_unretained");
+
+ if (!isObjCMethod())
+ {
+ if (protection()==Protected) sl.append("protected");
+ else if (protection()==Private) sl.append("private");
+ else if (protection()==Package) sl.append("package");
+
+ if (lvirt==Virtual) sl.append("virtual");
+ else if (lvirt==Pure) sl.append("pure virtual");
+ if (isSignal()) sl.append("signal");
+ if (isSlot()) sl.append("slot");
+ if (isDefault()) sl.append("default");
+ if (isDelete()) sl.append("delete");
+ if (isNoExcept()) sl.append("noexcept");
+ if (isAttribute()) sl.append("attribute");
+ if (isUNOProperty()) sl.append("property");
+ if (isReadonly()) sl.append("readonly");
+ if (isBound()) sl.append("bound");
+ if (isUNOProperty() && isRemovable()) sl.append("removable");
+ if (isConstrained()) sl.append("constrained");
+ if (isTransient()) sl.append("transient");
+ if (isMaybeVoid()) sl.append("maybevoid");
+ if (isMaybeDefault()) sl.append("maybedefault");
+ if (isMaybeAmbiguous()) sl.append("maybeambiguous");
+ if (isPublished()) sl.append("published"); // enum
+ }
+ if (isObjCProperty() && isImplementation())
+ {
+ sl.append("implementation");
+ }
+ }
+ if (m_impl->classDef &&
+ container->definitionType()==TypeClass &&
+ m_impl->classDef!=container &&
+ !isRelated()
+ )
+ {
+ sl.append("inherited");
+ }
+ }
+ }
+ else if (isObjCMethod() && isImplementation())
+ {
+ sl.append("implementation");
+ }
+}
+
+void MemberDef::_writeCallGraph(OutputList &ol)
+{
+ // write call graph
+ if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH"))
+ && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
+ )
+ {
+ DotCallGraph callGraph(this,FALSE);
+ if (callGraph.isTooBig())
+ {
+ warn_uncond("Call graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
+ }
+ else if (!callGraph.isTrivial())
+ {
+ msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
+ ol.disable(OutputGenerator::Man);
+ ol.startParagraph();
+ ol.startCallGraph();
+ ol.parseText(theTranslator->trCallGraph());
+ ol.endCallGraph(callGraph);
+ ol.endParagraph();
+ ol.enableAll();
+ }
+ }
+}
+
+void MemberDef::_writeCallerGraph(OutputList &ol)
+{
+ if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH"))
+ && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
+ )
+ {
+ DotCallGraph callerGraph(this, TRUE);
+ if (callerGraph.isTooBig())
+ {
+ warn_uncond("Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
+ }
+ else if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
+ {
+ msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
+ ol.disable(OutputGenerator::Man);
+ ol.startParagraph();
+ ol.startCallGraph();
+ ol.parseText(theTranslator->trCallerGraph());
+ ol.endCallGraph(callerGraph);
+ ol.endParagraph();
+ ol.enableAll();
+ }
+ }
+}
+
+void MemberDef::_writeReimplements(OutputList &ol)
+{
+ MemberDef *bmd=reimplements();
+ ClassDef *bcd=0;
+ if (bmd && (bcd=bmd->getClassDef()))
+ {
+ // write class that contains a member that is reimplemented by this one
+ if (bcd->isLinkable())
+ {
+ ol.startParagraph();
+ QCString reimplFromLine;
+ if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
+ {
+ reimplFromLine = theTranslator->trReimplementedFromList(1);
+ }
+ else
+ {
+ reimplFromLine = theTranslator->trImplementedFromList(1);
+ }
+ int markerPos = reimplFromLine.find("@0");
+ if (markerPos!=-1) // should always pass this.
+ {
+ ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
+ if (bmd->isLinkable()) // replace marker with link
+ {
+ //Definition *bd=bmd->group;
+ //if (bd==0) bd=bcd;
+ ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+ bmd->anchor(),bcd->displayName());
+
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ if ( bmd->isLinkableInProject() )
+ {
+ writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+ }
+ }
+ else
+ {
+ ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ 0,bcd->displayName());
+ if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
+ {
+ writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
+ }
+ }
+ ol.parseText(reimplFromLine.right(
+ reimplFromLine.length()-markerPos-2)); // text right from marker
+
+ }
+ else
+ {
+ err("translation error: no marker in trReimplementsFromList()\n");
+ }
+ ol.endParagraph();
+ }
+ }
+}
+
+void MemberDef::_writeReimplementedBy(OutputList &ol)
+{
+ MemberList *bml=reimplementedBy();
+ if (bml)
+ {
+ MemberListIterator mli(*bml);
+ MemberDef *bmd=0;
+ uint count=0;
+ ClassDef *bcd=0;
+ for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
+ {
+ // count the members that directly inherit from md and for
+ // which the member and class are visible in the docs.
+ if ( bmd->isLinkable() && bcd->isLinkable() )
+ {
+ count++;
+ }
+ }
+ if (count>0)
+ {
+ mli.toFirst();
+ // write the list of classes that overwrite this member
+ ol.startParagraph();
+
+ QCString reimplInLine;
+ if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
+ {
+ reimplInLine = theTranslator->trImplementedInList(count);
+ }
+ else
+ {
+ reimplInLine = theTranslator->trReimplementedInList(count);
+ }
+ static QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in reimplInLine with links to the classes
+ while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(reimplInLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ //bmd=bml->at(entryIndex);
+
+ count=0;
+ // find the entryIndex-th documented entry in the inheritance list.
+ for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
+ {
+ if ( bmd->isLinkable() && bcd->isLinkable())
+ {
+ if (count==entryIndex) break;
+ count++;
+ }
+ }
+
+ if (ok && bcd && bmd) // write link for marker
+ {
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+ bmd->anchor(),bcd->displayName());
+
+ if (bmd->isLinkableInProject() )
+ {
+ writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+ }
+ }
+ ++mli;
+ index=newIndex+matchLen;
+ }
+ ol.parseText(reimplInLine.right(reimplInLine.length()-index));
+ ol.endParagraph();
+ }
+ }
+}
+
+void MemberDef::_writeCategoryRelation(OutputList &ol)
+{
+ if (m_impl->classDef) // this should be a member of a class/category
+ {
+ //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
+ // name().data(),
+ // m_impl->category ? m_impl->category->name().data() : "<none>",
+ // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
+ // m_impl->classDef->name().data(),
+ // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
+ // );
+ QCString text;
+ QCString ref;
+ QCString file;
+ QCString anc;
+ QCString name;
+ int i=-1;
+ if (m_impl->categoryRelation && m_impl->categoryRelation->isLinkable())
+ {
+ if (m_impl->category)
+ {
+ // this member is in a normal class and implements method categoryRelation from category
+ // so link to method 'categoryRelation' with 'provided by category 'category' text.
+ text = theTranslator->trProvidedByCategory();
+ name = m_impl->category->displayName();
+ }
+ else if (m_impl->classDef->categoryOf())
+ {
+ // this member is part of a category so link to the corresponding class member of the class we extend
+ // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
+ text = theTranslator->trExtendsClass();
+ name = m_impl->classDef->categoryOf()->displayName();
+ }
+ i=text.find("@1");
+ if (i!=-1)
+ {
+ MemberDef *md = m_impl->categoryRelation;
+ ref = md->getReference();
+ file = md->getOutputFileBase();
+ anc = md->anchor();
+ }
+ }
+ if (i!=-1 && !name.isEmpty())
+ {
+ ol.startParagraph();
+ ol.parseText(text.left(i));
+ ol.writeObjectLink(ref,file,anc,name);
+ ol.parseText(text.mid(i+2));
+ ol.endParagraph();
+ }
+ }
+}
+
+void MemberDef::_writeExamples(OutputList &ol)
+{
+ // write the list of examples that use this member
+ if (hasExamples())
+ {
+ ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
+ ol.startDescForItem();
+ writeExample(ol,m_impl->exampleSDict);
+ ol.endDescForItem();
+ ol.endSimpleSect();
+ }
+}
+
+void MemberDef::_writeTypeConstraints(OutputList &ol)
+{
+ if (m_impl->typeConstraints)
+ {
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+ }
+}
+
+void MemberDef::_writeEnumValues(OutputList &ol,Definition *container,
+ const QCString &cfname,const QCString &ciname,
+ const QCString &cname)
+{
+ // For enum, we also write the documented enum values
+ if (isEnumerate())
+ {
+ bool first=TRUE;
+ MemberList *fmdl=enumFieldList();
+ //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
+ if (fmdl)
+ {
+ MemberListIterator it(*fmdl);
+ MemberDef *fmd;
+ for (;(fmd=it.current());++it)
+ {
+ //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
+ if (fmd->isLinkable())
+ {
+ if (first)
+ {
+ //ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
+ //ol.startDescForItem();
+ ol.startDescTable(theTranslator->trEnumerationValues());
+ }
+
+ ol.addIndexItem(fmd->name(),ciname);
+ ol.addIndexItem(ciname,fmd->name());
+
+ //Doxygen::indexList->addIndexItem(
+ // ciname, // level1
+ // fmd->name(), // level2
+ // separateMemPages ? cfname : cfiname, // contRef
+ // cfname, // memRef
+ // fmd->anchor(), // anchor
+ // fmd); // memberdef
+ Doxygen::indexList->addIndexItem(container,fmd);
+
+ //ol.writeListItem();
+ ol.startDescTableTitle();
+ ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
+ first=FALSE;
+ //ol.startEmphasis();
+ ol.docify(fmd->name());
+ //ol.endEmphasis();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.writeString(" ");
+ ol.enableAll();
+ ol.endDoxyAnchor(cfname,fmd->anchor());
+ ol.endDescTableTitle();
+ //ol.newParagraph();
+ ol.startDescTableData();
+
+ bool hasBrief = !fmd->briefDescription().isEmpty();
+ bool hasDetails = !fmd->documentation().isEmpty();
+
+ if (hasBrief)
+ {
+ ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
+ getOuterScope()?getOuterScope():container,
+ fmd,fmd->briefDescription(),TRUE,FALSE);
+ }
+ // FIXME:PARA
+ //if (!fmd->briefDescription().isEmpty() &&
+ // !fmd->documentation().isEmpty())
+ //{
+ // ol.newParagraph();
+ //}
+ if (hasDetails)
+ {
+ ol.generateDoc(fmd->docFile(),fmd->docLine(),
+ getOuterScope()?getOuterScope():container,
+ fmd,fmd->documentation()+"\n",TRUE,FALSE);
+ }
+ ol.endDescTableData();
+ }
+ }
+ }
+ if (!first)
+ {
+ //ol.endItemList();
+ ol.endDescTable();
+ //ol.endDescForItem();
+ //ol.endSimpleSect();
+ //ol.writeChar('\n');
+ }
+ }
+}
+
+QCString MemberDef::displayDefinition() const
+{
+ QCString ldef = definition();
+ QCString title = name();
+ if (isEnumerate())
+ {
+ if (title.at(0)=='@')
+ {
+ ldef = title = "anonymous enum";
+ if (!m_impl->enumBaseType.isEmpty())
+ {
+ ldef+=" : "+m_impl->enumBaseType;
+ }
+ }
+ else
+ {
+ ldef.prepend("enum ");
+ }
+ }
+ else if (isEnumValue())
+ {
+ if (ldef.at(0)=='@')
+ {
+ ldef=ldef.mid(2);
+ }
+ }
+ static QRegExp r("@[0-9]+");
+ int l,i=r.match(ldef,0,&l);
+ if (i!=-1) // replace anonymous parts with { ... }
+ {
+ int si=ldef.find(' '),pi,ei=i+l;
+ if (si==-1) si=0;
+ while ((pi=r.match(ldef,i+l,&l))!=-1)
+ {
+ i=pi;
+ ei=i+l;
+ }
+ int ni=ldef.find("::",si);
+ if (ni>=ei) ei=ni+2;
+ ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei);
+ }
+ ClassDef *cd=getClassDef();
+ if (cd && cd->isObjectiveC())
+ {
+ // strip scope name
+ int ep = ldef.find("::");
+ if (ep!=-1)
+ {
+ int sp=ldef.findRev(' ',ep);
+ if (sp!=-1)
+ {
+ ldef=ldef.left(sp+1)+ldef.mid(ep+2);
+ }
+ }
+ // strip keywords
+ int dp = ldef.find(':');
+ if (dp!=-1)
+ {
+ ldef=ldef.left(dp+1);
+ }
+ l=ldef.length();
+ //printf("start >%s<\n",ldef.data());
+ i=l-1;
+ while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
+ while (i>=0 && isspace((uchar)ldef.at(i))) i--;
+ if (i>0)
+ {
+ // insert braches around the type
+ QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
+ ldef=tmp;
+ }
+ //printf("end >%s< i=%d\n",ldef.data(),i);
+ if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
+ }
+ SrcLangExt lang = getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ return substitute(ldef,"::",sep);
+}
+
+void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup)
+{
+ // only write out the include file if this is not part of a class or file
+ // definition
+ static bool showGroupedMembInc = Config_getBool("SHOW_GROUPED_MEMB_INC");
+ FileDef *fd = getFileDef();
+ QCString nm;
+ if (fd) nm = getFileDef()->docName();
+ if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
+ {
+ ol.startParagraph();
+ ol.startTypewriter();
+ SrcLangExt lang = getLanguage();
+ bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ if (isIDLorJava)
+ {
+ ol.docify("import ");
+ }
+ else
+ {
+ ol.docify("#include ");
+ }
+
+ if (isIDLorJava) ol.docify("\""); else ol.docify("<");
+
+ if (fd && fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
+ }
+ else
+ {
+ ol.docify(nm);
+ }
+
+ if (isIDLorJava) ol.docify("\""); else ol.docify(">");
+
+ ol.endTypewriter();
+ ol.endParagraph();
+ }
+}
+
+/*! Writes the "detailed documentation" section of this member to
+ * all active output formats.
+ */
+void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
+ const char *scName,
+ Definition *container,
+ bool inGroup,
+ bool showEnumValues,
+ bool showInline
+ )
+{
+ // if this member is in a group find the real scope name.
+ bool hasParameterList = FALSE;
+ bool inFile = container->definitionType()==Definition::TypeFile;
+ bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
+
+ //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n",
+ // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable());
+
+ if ( !hasDocs ) return;
+ if (isEnumValue() && !showEnumValues) return;
+
+ SrcLangExt lang = getLanguage();
+ //printf("member=%s lang=%d\n",name().data(),lang);
+ bool optVhdl = lang==SrcLangExt_VHDL;
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+
+ QCString scopeName = scName;
+ QCString memAnchor = anchor();
+ QCString ciname = container->name();
+ if (container->definitionType()==TypeGroup)
+ {
+ if (getClassDef()) scopeName=getClassDef()->displayName();
+ else if (getNamespaceDef()) scopeName=getNamespaceDef()->displayName();
+ else if (getFileDef()) scopeName=getFileDef()->displayName();
+ ciname = ((GroupDef *)container)->groupTitle();
+ }
+ else if (container->definitionType()==TypeFile && getNamespaceDef())
+ { // member is in a namespace, but is written as part of the file documentation
+ // as well, so we need to make sure its label is unique.
+ memAnchor.prepend("file_");
+ }
+
+ QCString cname = container->name();
+ QCString cfname = getOutputFileBase();
+ QCString cfiname = container->getOutputFileBase();
+
+ // get member name
+ QCString doxyName=name();
+ // prepend scope if there is any. TODO: make this optional for C only docs
+ if (!scopeName.isEmpty())
+ {
+ doxyName.prepend(scopeName+sep);
+ }
+ QCString doxyArgs=argsString();
+
+ QCString ldef = definition();
+ QCString title = name();
+ //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
+ if (isEnumerate())
+ {
+ if (title.at(0)=='@')
+ {
+ ldef = title = "anonymous enum";
+ if (!m_impl->enumBaseType.isEmpty())
+ {
+ ldef+=" : "+m_impl->enumBaseType;
+ }
+ }
+ else
+ {
+ ldef.prepend("enum ");
+ }
+ }
+ else if (isEnumValue())
+ {
+ if (ldef.at(0)=='@')
+ {
+ ldef=ldef.mid(2);
+ }
+ }
+ int i=0,l;
+ static QRegExp r("@[0-9]+");
+
+ //----------------------------------------
+
+ ol.pushGeneratorState();
+
+ bool htmlEndLabelTable=FALSE;
+ QStrList sl;
+ getLabels(sl,container);
+
+ if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
+ {
+ // find enum type and insert it in the definition
+ QListIterator<MemberDef> vmli(*ml);
+ MemberDef *vmd;
+ bool found=FALSE;
+ for ( ; (vmd=vmli.current()) && !found ; ++vmli)
+ {
+ if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
+ {
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.left(i));
+ vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef(),definitionType());
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.right(ldef.length()-i-l));
+
+ found=TRUE;
+ }
+ }
+ if (!found) // anonymous compound
+ {
+ //printf("Anonymous compound `%s'\n",cname.data());
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
+ // search for the last anonymous compound name in the definition
+ int si=ldef.find(' '),pi,ei=i+l;
+ if (si==-1) si=0;
+ while ((pi=r.match(ldef,i+l,&l))!=-1)
+ {
+ i=pi;
+ ei=i+l;
+ }
+ // first si characters of ldef contain compound type name
+ ol.startMemberDocName(isObjCMethod());
+ ol.docify(ldef.left(si));
+ ol.docify(" { ... } ");
+ // last ei characters of ldef contain pointer/reference specifiers
+ int ni=ldef.find("::",si);
+ if (ni>=ei) ei=ni+2;
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.right(ldef.length()-ei));
+ }
+ }
+ else // not an enum value or anonymous compound
+ {
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,title,showInline);
+
+ ClassDef *cd=getClassDef();
+ if (!Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ bool first=TRUE;
+ SrcLangExt lang = getLanguage();
+ if (m_impl->defTmpArgLists && lang==SrcLangExt_Cpp)
+ // definition has explicit template parameter declarations
+ {
+ QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ if (!first) ol.docify(" ");
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,tal);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+ else // definition gets it template parameters from its class
+ // (since no definition was found)
+ {
+ if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
+ {
+ QList<ArgumentList> tempParamLists;
+ cd->getTemplateParameterLists(tempParamLists);
+ //printf("#tempParamLists=%d\n",tempParamLists.count());
+ QListIterator<ArgumentList> ali(tempParamLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ if (!first) ol.docify(" ");
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,tal);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+ if (m_impl->tArgList && lang==SrcLangExt_Cpp) // function template prefix
+ {
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,m_impl->tArgList);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+
+ if (sl.count()>0)
+ {
+ ol.pushGeneratorState();
+ ol.disableAll();
+ ol.enable(OutputGenerator::Html);
+ ol.writeString("<table class=\"mlabels\">\n");
+ ol.writeString(" <tr>\n");
+ ol.writeString(" <td class=\"mlabels-left\">\n");
+ ol.popGeneratorState();
+ htmlEndLabelTable=TRUE;
+ }
+
+ ol.startMemberDocName(isObjCMethod());
+ if (cd && cd->isObjectiveC())
+ {
+ // strip scope name
+ int ep = ldef.find("::");
+ if (ep!=-1)
+ {
+ int sp=ldef.findRev(' ',ep);
+ if (sp!=-1)
+ {
+ ldef=ldef.left(sp+1)+ldef.mid(ep+2);
+ } else {
+ ldef=ldef.mid(ep+2);
+ }
+ }
+ // strip keywords
+ int dp = ldef.find(':');
+ if (dp!=-1)
+ {
+ ldef=ldef.left(dp+1);
+ }
+ int l=ldef.length();
+ //printf("start >%s<\n",ldef.data());
+ int i=l-1;
+ while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
+ while (i>=0 && isspace((uchar)ldef.at(i))) i--;
+ if (i>0)
+ {
+ // insert braches around the type
+ QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
+ ldef=tmp;
+ }
+ //printf("end >%s< i=%d\n",ldef.data(),i);
+ if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
+ }
+
+ if (optVhdl)
+ {
+ hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,container,ol);
+ }
+ else
+ {
+ linkifyText(TextGeneratorOLImpl(ol),
+ container,
+ getBodyDef(),
+ this,
+ substitute(ldef,"::",sep)
+ );
+ hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
+ }
+
+ if (hasOneLineInitializer()) // add initializer
+ {
+ if (!isDefine())
+ {
+ //ol.docify(" = ");
+ ol.docify(" ");
+ QCString init = m_impl->initializer.simplifyWhiteSpace();
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,init);
+ }
+ else
+ {
+ ol.writeNonBreakableSpace(3);
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,m_impl->initializer);
+ }
+ }
+ if (excpString()) // add exception list
+ {
+ writeExceptionList(ol,cd,this);
+ hasParameterList=true; // call endParameterList below
+ }
+ }
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ if (sl.count()>0)
+ {
+ ol.startLabels();
+ const char *s=sl.first();
+ while (s)
+ {
+ const char *ns = sl.next();
+ ol.writeLabel(s,ns==0);
+ s=ns;
+ }
+ ol.endLabels();
+ }
+ ol.popGeneratorState();
+
+ if (hasParameterList)
+ {
+ ol.endParameterList();
+ ol.endMemberDoc(TRUE);
+ }
+ else
+ {
+ ol.endMemberDocName();
+ ol.endMemberDoc(FALSE);
+ }
+
+ // for HTML write the labels here
+ ol.pushGeneratorState();
+ ol.disableAll();
+ ol.enable(OutputGenerator::Html);
+ if (htmlEndLabelTable)
+ {
+ ol.writeString(" </td>\n");
+ ol.writeString(" <td class=\"mlabels-right\">\n");
+ ol.startLabels();
+ const char *s=sl.first();
+ while (s)
+ {
+ const char *ns = sl.next();
+ ol.writeLabel(s,ns==0);
+ s=ns;
+ }
+ ol.endLabels();
+ ol.writeString(" </td>\n");
+ ol.writeString(" </tr>\n");
+ ol.writeString("</table>\n");
+ }
+ ol.writeString("</div>");
+ ol.popGeneratorState();
+
+
+ ol.endDoxyAnchor(cfname,memAnchor);
+ ol.startIndent();
+
+ _writeGroupInclude(ol,inGroup);
+
+ /* write multi-line initializer (if any) */
+ if (hasMultiLineInitializer()
+ //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
+ // || initLines<userInitLines // explicitly enabled
+ // )
+ )
+ {
+ //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
+ ol.startBold();
+ if (m_impl->mtype==MemberType_Define)
+ ol.parseText(theTranslator->trDefineValue());
+ else
+ ol.parseText(theTranslator->trInitialValue());
+ ol.endBold();
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
+ pIntf->resetCodeParserState();
+ ol.startCodeFragment();
+ pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,getFileDef(),
+ -1,-1,TRUE,this,FALSE,this);
+ ol.endCodeFragment();
+ }
+
+ QCString brief = briefDescription();
+ QCString detailed = documentation();
+ ArgumentList *docArgList = m_impl->defArgList;
+ if (m_impl->templateMaster)
+ {
+ brief = m_impl->templateMaster->briefDescription();
+ detailed = m_impl->templateMaster->documentation();
+ docArgList = m_impl->templateMaster->argumentList();
+ }
+
+ /* write brief description */
+ if (!brief.isEmpty() &&
+ (Config_getBool("REPEAT_BRIEF") ||
+ !Config_getBool("BRIEF_MEMBER_DESC")
+ )
+ )
+ {
+ ol.startParagraph();
+ ol.generateDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():container,this,
+ brief,FALSE,FALSE,0,TRUE,FALSE);
+ ol.endParagraph();
+ }
+
+ /* write detailed description */
+ if (!detailed.isEmpty() ||
+ !inbodyDocumentation().isEmpty())
+ {
+ // write vhdl inline code with or without option INLINE_SOURCE
+ if (optVhdl && VhdlDocGen::isMisc(this))
+ {
+ VhdlDocGen::writeSource(this,ol,cname);
+ return;
+ }
+ else
+ {
+ ol.generateDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
+ }
+
+ if (!inbodyDocumentation().isEmpty())
+ {
+ ol.generateDoc(inbodyFile(),inbodyLine(),
+ getOuterScope()?getOuterScope():container,this,
+ inbodyDocumentation()+"\n",TRUE,FALSE);
+ }
+ }
+ else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
+ !Config_getBool("BRIEF_MEMBER_DESC")))
+ {
+ if (!inbodyDocumentation().isEmpty())
+ {
+ ol.generateDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,inbodyDocumentation()+"\n",TRUE,FALSE);
+ }
+ }
+
+
+ //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
+ // defArgList,
+ // defArgList?defArgList->hasDocumentation():-1);
+ if (docArgList!=0 && docArgList->hasDocumentation())
+ {
+ QCString paramDocs;
+ ArgumentListIterator ali(*docArgList);
+ Argument *a;
+ // convert the parameter documentation into a list of @param commands
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (a->hasDocumentation())
+ {
+ QCString direction = extractDirection(a->docs);
+ paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
+ }
+ }
+ // feed the result to the documentation parser
+ ol.generateDoc(
+ docFile(),docLine(),
+ getOuterScope()?getOuterScope():container,
+ this, // memberDef
+ paramDocs, // docStr
+ TRUE, // indexWords
+ FALSE // isExample
+ );
+
+ }
+
+ _writeEnumValues(ol,container,cfname,ciname,cname);
+ _writeReimplements(ol);
+ _writeReimplementedBy(ol);
+ _writeCategoryRelation(ol);
+ _writeExamples(ol);
+ _writeTypeConstraints(ol);
+ writeSourceDef(ol,cname);
+ writeSourceRefs(ol,cname);
+ writeSourceReffedBy(ol,cname);
+ writeInlineCode(ol,cname);
+ _writeCallGraph(ol);
+ _writeCallerGraph(ol);
+
+ if (Doxygen::userComments)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
+ "passthru(\"$root/doxynotes --lookup "+
+ getOutputFileBase()+":"+anchor()+"\") ?>";
+ ol.writeString(cmd);
+ ol.popGeneratorState();
+ }
+
+ ol.endIndent();
+
+ // enable LaTeX again
+ //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex);
+ ol.popGeneratorState();
+
+ //------------------------------------------------
+
+ if (!Config_getBool("EXTRACT_ALL") &&
+ Config_getBool("WARN_IF_UNDOCUMENTED") &&
+ Config_getBool("WARN_NO_PARAMDOC") &&
+ !Doxygen::suppressDocWarnings)
+ {
+ if (!hasDocumentedParams())
+ {
+ warn_doc_error(docFile(),docLine(),
+ "parameters of member %s are not (all) documented",
+ qPrint(qualifiedName()));
+ }
+ if (!hasDocumentedReturnType() && isFunction() && hasDocumentation())
+ {
+ warn_doc_error(docFile(),docLine(),
+ "return type of member %s is not documented",
+ qPrint(qualifiedName()));
+ }
+ }
+}
+
+// strip scope and field name from the type
+// example: "struct N::S.v.c" will become "struct v"
+static QCString simplifyTypeForTable(const QCString &s)
+{
+ QCString ts=removeAnonymousScopes(s);
+ if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
+ static QRegExp re("[A-Z_a-z0-9]+::");
+ int i,l;
+ while ((i=re.match(ts,0,&l))!=-1)
+ {
+ ts=ts.left(i)+ts.mid(i+l);
+ }
+ i=ts.findRev('.');
+ if (i!=-1) ts = ts.left(i);
+ i=ts.findRev('.');
+ if (i!=-1) ts = ts.right(ts.length()-i-1);
+ //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
+ return ts;
+}
+
+#if 0
+/** Returns the type definition corresponding to a member's return type.
+ * @param[in] scope The scope in which to search for the class definition.
+ * @param[in] type The string representing the member's return type.
+ * @param[in] lang The programming language in which the class is defined.
+ * @param[out] start The string position where the class definition name was found.
+ * @param[out] length The length of the class definition's name.
+ */
+static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
+{
+ int pos=0;
+ int i;
+ QCString name;
+ QCString templSpec;
+ while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
+ {
+ ClassDef *cd=0;
+ MemberDef *md=0;
+ int l = name.length()+templSpec.length();
+ if (!templSpec.isEmpty())
+ {
+ cd = getResolvedClass(scope,0,name+templSpec,&md);
+ }
+ cd = getResolvedClass(scope,0,name);
+ if (cd)
+ {
+ start=i;
+ length=l;
+ printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
+ return cd;
+ }
+ else if (md)
+ {
+ start=i;
+ length=l;
+ printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
+ return md;
+ }
+ pos=i+l;
+ }
+ return 0;
+}
+#endif
+
+QCString MemberDef::fieldType() const
+{
+ QCString type = m_impl->accessorType;
+ if (type.isEmpty())
+ {
+ type = m_impl->type;
+ }
+
+ if (isTypedef()) type.prepend("typedef ");
+ return simplifyTypeForTable(type);
+}
+
+void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
+{
+ Definition *scope = getOuterScope();
+ QCString doxyName = name();
+ QCString doxyArgs = argsString();
+ QCString memAnchor = anchor();
+ QCString cfname = getOutputFileBase();
+ QCString cname;
+ if (scope) cname = scope->name();
+ if (doxyName.at(0)=='@')
+ {
+ doxyName="__unnamed__";
+ }
+
+ ClassDef *cd = m_impl->accessorClass;
+ //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
+
+ ol.startInlineMemberType();
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+
+ QCString ts = fieldType();
+
+ if (cd) // cd points to an anonymous struct pointed to by this member
+ // so we add a link to it from the type column.
+ {
+ int i=0;
+ const char *prefixes[] = { "struct ","union ","class ", 0 };
+ const char **p = prefixes;
+ while (*p)
+ {
+ int l=qstrlen(*p);
+ if (ts.left(l)==*p)
+ {
+ ol.writeString(*p);
+ i=l;
+ }
+ p++;
+ }
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),ts.mid(i));
+ }
+ else // use standard auto linking
+ {
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ scope, // scope
+ getBodyDef(), // fileScope
+ this, // self
+ ts, // text
+ TRUE // autoBreak
+ );
+ }
+ ol.endDoxyAnchor(cfname,memAnchor);
+ ol.endInlineMemberType();
+
+ ol.startInlineMemberName();
+ ol.docify(doxyName);
+ if (isVariable() && argsString() && !isObjCMethod())
+ {
+ linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,argsString());
+ }
+ if (!m_impl->bitfields.isEmpty()) // add bitfields
+ {
+ linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields);
+ }
+ ol.endInlineMemberName();
+
+ ol.startInlineMemberDoc();
+
+ QCString brief = briefDescription();
+ QCString detailed = documentation();
+
+ /* write brief description */
+ if (!brief.isEmpty())
+ {
+ ol.generateDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():container,this,
+ brief,FALSE,FALSE,0,TRUE,FALSE);
+ }
+
+ /* write detailed description */
+ if (!detailed.isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),
+ getOuterScope()?getOuterScope():container,this,
+ detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
+
+ }
+
+ ol.endInlineMemberDoc();
+}
+
+QCString MemberDef::memberTypeName() const
+{
+ switch (m_impl->mtype)
+ {
+ case MemberType_Define: return "macro definition";
+ case MemberType_Function: return "function";
+ case MemberType_Variable: return "variable";
+ case MemberType_Typedef: return "typedef";
+ case MemberType_Enumeration: return "enumeration";
+ case MemberType_EnumValue: return "enumvalue";
+ case MemberType_Signal: return "signal";
+ case MemberType_Slot: return "slot";
+ case MemberType_Friend: return "friend";
+ case MemberType_DCOP: return "dcop";
+ case MemberType_Property: return "property";
+ case MemberType_Event: return "event";
+ case MemberType_Interface: return "interface";
+ case MemberType_Service: return "service";
+ default: return "unknown";
+ }
+}
+
+void MemberDef::warnIfUndocumented()
+{
+ if (m_impl->memberGroup) return;
+ ClassDef *cd = getClassDef();
+ NamespaceDef *nd = getNamespaceDef();
+ FileDef *fd = getFileDef();
+ GroupDef *gd = getGroupDef();
+ Definition *d=0;
+ const char *t=0;
+ if (cd)
+ t="class", d=cd;
+ else if (nd)
+ t="namespace", d=nd;
+ else if (gd)
+ t="group", d=gd;
+ else
+ t="file", d=fd;
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+
+ //printf("warnIfUndoc: d->isLinkable()=%d isLinkable()=%d "
+ // "isDocumentedFriendClass()=%d name()=%s prot=%d\n",
+ // d->isLinkable(),isLinkable(),isDocumentedFriendClass(),
+ // name().data(),prot);
+ if ((!hasUserDocumentation() && !extractAll) &&
+ !isFriendClass() &&
+ name().find('@')==-1 && d && d->name().find('@')==-1 &&
+ protectionLevelVisible(m_impl->prot) &&
+ !isReference()
+ )
+ {
+ warn_undoc(getDefFileName(),getDefLine(),"Member %s%s (%s) of %s %s is not documented.",
+ qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
+ }
+}
+
+
+
+bool MemberDef::isFriendClass() const
+{
+ return (isFriend() &&
+ (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"));
+}
+
+bool MemberDef::isDocumentedFriendClass() const
+{
+ ClassDef *fcd=0;
+ QCString baseName=name();
+ int i=baseName.find('<');
+ if (i!=-1) baseName=baseName.left(i);
+ return (isFriendClass() &&
+ (fcd=getClass(baseName)) && fcd->isLinkable());
+}
+
+bool MemberDef::hasDocumentation() const
+{
+ return Definition::hasDocumentation() ||
+ (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values
+ (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
+}
+
+#if 0
+bool MemberDef::hasUserDocumentation() const
+{
+ bool hasDocs = Definition::hasUserDocumentation();
+ return hasDocs;
+}
+#endif
+
+
+void MemberDef::setMemberGroup(MemberGroup *grp)
+{
+ m_impl->memberGroup = grp;
+}
+
+bool MemberDef::visibleMemberGroup(bool hideNoHeader)
+{
+ return m_impl->memberGroup!=0 &&
+ (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
+}
+
+QCString MemberDef::getScopeString() const
+{
+ QCString result;
+ if (getClassDef()) result=getClassDef()->displayName();
+ else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
+ return result;
+}
+
+#if 0
+static QCString escapeAnchor(const QCString &anchor)
+{
+ QCString result;
+ int l = anchor.length(),i;
+ for (i=0;i<l;i++)
+ {
+ char c = anchor.at(i);
+ if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
+ {
+ result+=c;
+ }
+ else
+ {
+ static char hexStr[]="0123456789ABCDEF";
+ char escChar[]={ '_', 0, 0, 0 };
+ escChar[1]=hexStr[c>>4];
+ escChar[2]=hexStr[c&0xf];
+ result+=escChar;
+ }
+ }
+ return result;
+}
+#endif
+
+void MemberDef::setAnchor()
+{
+ QCString memAnchor = name();
+ if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
+
+ memAnchor.prepend(definition()); // actually the method name is now included
+ // twice, which is silly, but we keep it this way for backward
+ // compatibility.
+
+ // include number of template arguments as well,
+ // to distinguish between two template
+ // specializations that only differ in the template parameters.
+ if (m_impl->tArgList)
+ {
+ char buf[20];
+ qsnprintf(buf,20,"%d:",m_impl->tArgList->count());
+ buf[19]='\0';
+ memAnchor.prepend(buf);
+ }
+
+ // convert to md5 hash
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
+ //printf("memAnchor=%s\n",memAnchor.data());
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ m_impl->anc = "a"+sigStr;
+}
+
+void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
+ const QCString &fileName,int startLine,
+ bool hasDocs,MemberDef *member)
+{
+ //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
+ m_impl->group=gd;
+ m_impl->grouppri=pri;
+ m_impl->groupFileName=fileName;
+ m_impl->groupStartLine=startLine;
+ m_impl->groupHasDocs=hasDocs;
+ m_impl->groupMember=member;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum)
+{
+ m_impl->enumScope=md;
+ m_impl->livesInsideEnum=livesInsideEnum;
+ if (md->getGroupDef())
+ {
+ m_impl->group=md->getGroupDef();
+ m_impl->grouppri=md->getGroupPri();
+ m_impl->groupFileName=md->getGroupFileName();
+ m_impl->groupStartLine=md->getGroupStartLine();
+ m_impl->groupHasDocs=md->getGroupHasDocs();
+ m_isLinkableCached = 0;
+ }
+}
+
+void MemberDef::setMemberClass(ClassDef *cd)
+{
+ m_impl->classDef=cd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ setOuterScope(cd);
+}
+
+void MemberDef::setNamespace(NamespaceDef *nd)
+{
+ m_impl->nspace=nd;
+ setOuterScope(nd);
+}
+
+MemberDef *MemberDef::createTemplateInstanceMember(
+ ArgumentList *formalArgs,ArgumentList *actualArgs)
+{
+ //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
+ ArgumentList *actualArgList = 0;
+ if (m_impl->defArgList)
+ {
+ actualArgList = m_impl->defArgList->deepCopy();
+
+ // replace formal arguments with actuals
+ ArgumentListIterator ali(*actualArgList);
+ Argument *arg;
+ for (;(arg=ali.current());++ali)
+ {
+ arg->type = substituteTemplateArgumentsInString(arg->type,formalArgs,actualArgs);
+ }
+ actualArgList->trailingReturnType =
+ substituteTemplateArgumentsInString(actualArgList->trailingReturnType,formalArgs,actualArgs);
+ }
+
+ QCString methodName=name();
+ if (methodName.left(9)=="operator ") // conversion operator
+ {
+ methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
+ }
+
+ MemberDef *imd = new MemberDef(
+ getDefFileName(),getDefLine(),getDefColumn(),
+ substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
+ methodName,
+ substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
+ m_impl->exception, m_impl->prot,
+ m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
+ );
+ imd->setArgumentList(actualArgList);
+ imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
+ imd->setBodyDef(getBodyDef());
+ imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
+ //imd->setBodyMember(this);
+
+ // TODO: init other member variables (if needed).
+ // TODO: reimplemented info
+ return imd;
+}
+
+bool MemberDef::hasOneLineInitializer() const
+{
+ //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
+ // name().data(),m_impl->initializer.data(),m_impl->initLines,
+ // m_impl->maxInitLines,m_impl->userInitLines);
+ return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
+ ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
+}
+
+bool MemberDef::hasMultiLineInitializer() const
+{
+ //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
+ // initLines,userInitLines,maxInitLines);
+ return m_impl->initLines>0 &&
+ ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
+ || m_impl->initLines<m_impl->userInitLines // explicitly enabled
+ );
+}
+
+void MemberDef::setInitializer(const char *initializer)
+{
+ m_impl->initializer=initializer;
+ int l=m_impl->initializer.length();
+ int p=l-1;
+ while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
+ m_impl->initializer=m_impl->initializer.left(p+1);
+ m_impl->initLines=m_impl->initializer.contains('\n');
+ //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
+}
+
+void MemberDef::addListReference(Definition *)
+{
+ static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ //static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ SrcLangExt lang = getLanguage();
+ visited=TRUE;
+ if (!isLinkableInProject()) return;
+ QCString memLabel;
+ if (optimizeOutputForC)
+ {
+ memLabel=theTranslator->trGlobal(TRUE,TRUE);
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ memLabel=theTranslator->trSubprogram(TRUE,TRUE);
+ }
+ else
+ {
+ memLabel=theTranslator->trMember(TRUE,TRUE);
+ }
+ QCString memName = name();
+ Definition *pd=getOuterScope();
+ QCString pdName = pd->definitionType()==Definition::TypeClass ?
+ ((ClassDef*)pd)->displayName() : pd->name();
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ QCString memArgs;
+ if (!isRelated()
+ /* && commented out as a result of bug 597016
+ (
+ (!hideScopeNames && // there is a scope
+ pd && pd!=Doxygen::globalScope) // and we can show it
+ ||
+ (pd=getClassDef()) // it's a class so we
+ // show the scope anyway
+ )
+ */
+ )
+ {
+ if (isObjCMethod())
+ {
+ memName = "[" + pd->name() + " " + name() + "]";
+ }
+ else
+ {
+ if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
+ memArgs = argsString();
+ }
+ }
+ QList<ListItemInfo> *xrefItems = xrefListItems();
+ if (xrefItems)
+ {
+ addRefItem(xrefItems,
+ qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
+ memLabel,
+ getOutputFileBase()+"#"+anchor(),memName,memArgs);
+ }
+}
+
+MemberList *MemberDef::getSectionList(Definition *d) const
+{
+ char key[20];
+ sprintf(key,"%p",d);
+ return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
+}
+
+void MemberDef::setSectionList(Definition *d, MemberList *sl)
+{
+ //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
+ char key[20];
+ sprintf(key,"%p",d);
+ if (m_impl->classSectionSDict==0)
+ {
+ m_impl->classSectionSDict = new SDict<MemberList>(7);
+ }
+ m_impl->classSectionSDict->append(key,sl);
+}
+
+Specifier MemberDef::virtualness(int count) const
+{
+ if (count>25)
+ {
+ warn(getDefFileName(),getDefLine(),
+ "Internal inconsistency: recursion detected in overload relation for member %s!"
+ ,qPrint(name())
+ );
+ return Normal;
+ }
+ Specifier v = m_impl->virt;
+ MemberDef *rmd = reimplements();
+ while (rmd && v==Normal)
+ {
+ v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
+ rmd = rmd->reimplements();
+ }
+ return v;
+}
+
+void MemberDef::_writeTagData(const DefType compoundType)
+{
+ unsigned typeMask = 1 << compoundType;
+ if ((m_impl->tagDataWritten) & typeMask) return; // member already written for this type
+ if (m_impl->mtype==MemberType_EnumValue && m_impl->enumScope &&
+ m_impl->enumScope->isStrong()) return; // enum value is part of enum
+ static bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty();
+ // write tag file information of this member
+ if (generateTagFile && isLinkableInProject())
+ {
+ Doxygen::tagFile << " <member kind=\"";
+ switch (m_impl->mtype)
+ {
+ case MemberType_Define: Doxygen::tagFile << "define"; break;
+ case MemberType_EnumValue: Doxygen::tagFile << "enumvalue"; break;
+ case MemberType_Property: Doxygen::tagFile << "property"; break;
+ case MemberType_Event: Doxygen::tagFile << "event"; break;
+ case MemberType_Variable: Doxygen::tagFile << "variable"; break;
+ case MemberType_Typedef: Doxygen::tagFile << "typedef"; break;
+ case MemberType_Enumeration: Doxygen::tagFile << "enumeration"; break;
+ case MemberType_Function: Doxygen::tagFile << "function"; break;
+ case MemberType_Signal: Doxygen::tagFile << "signal"; break;
+ case MemberType_Friend: Doxygen::tagFile << "friend"; break;
+ case MemberType_DCOP: Doxygen::tagFile << "dcop"; break;
+ case MemberType_Slot: Doxygen::tagFile << "slot"; break;
+ case MemberType_Interface: Doxygen::tagFile << "interface"; break;
+ case MemberType_Service: Doxygen::tagFile << "service"; break;
+ }
+ if (m_impl->prot!=Public)
+ {
+ Doxygen::tagFile << "\" protection=\"";
+ if (m_impl->prot==Protected) Doxygen::tagFile << "protected";
+ else if (m_impl->prot==Package) Doxygen::tagFile << "package";
+ else /* Private */ Doxygen::tagFile << "private";
+ }
+ if (m_impl->virt!=Normal)
+ {
+ Doxygen::tagFile << "\" virtualness=\"";
+ if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual";
+ else /* Pure */ Doxygen::tagFile << "pure";
+ }
+ if (isStatic())
+ {
+ Doxygen::tagFile << "\" static=\"yes";
+ }
+ Doxygen::tagFile << "\">" << endl;
+ Doxygen::tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
+ Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
+ QCString idStr = id();
+ if (!idStr.isEmpty())
+ {
+ Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
+ }
+ Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
+ if (isStrong())
+ {
+ MemberList *fmdl=m_impl->enumFields;
+ if (fmdl)
+ {
+ MemberListIterator mli(*fmdl);
+ MemberDef *fmd;
+ for (mli.toFirst();(fmd=mli.current());++mli)
+ {
+ if (!fmd->isReference())
+ {
+ Doxygen::tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension);
+ Doxygen::tagFile << "\" anchor=\"" << convertToXML(fmd->anchor());
+ QCString idStr = fmd->id();
+ if (!idStr.isEmpty())
+ {
+ Doxygen::tagFile << "\" clangid=\"" << convertToXML(idStr);
+ }
+ Doxygen::tagFile << "\">" << convertToXML(fmd->name()) << "</enumvalue>" << endl;
+ }
+ }
+ }
+ }
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </member>" << endl;
+ }
+ m_impl->tagDataWritten |= typeMask;
+}
+
+void MemberDef::_computeIsConstructor()
+{
+ m_isConstructorCached=1; // FALSE
+ if (m_impl->classDef)
+ {
+ if (m_impl->isDMember) // for D
+ {
+ m_isConstructorCached = name()=="this" ? 2 : 1;
+ return;
+ }
+ else if (getLanguage()==SrcLangExt_PHP) // for PHP
+ {
+ m_isConstructorCached = name()=="__construct" ? 2 : 1;
+ return;
+ }
+ else if (name()=="__init__" &&
+ getLanguage()==SrcLangExt_Python) // for Python
+ {
+ m_isConstructorCached = 2; // TRUE
+ return;
+ }
+ else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
+ {
+ m_isConstructorCached = name()=="constructor" ? 2 : 1;
+ return;
+ }
+ else // for other languages
+ {
+ QCString locName = m_impl->classDef->localName();
+ int i=locName.find('<');
+ if (i==-1) // not a template class
+ {
+ m_isConstructorCached = name()==locName ? 2 : 1;
+ }
+ else
+ {
+ m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
+ }
+ return;
+ }
+ }
+}
+
+bool MemberDef::isConstructor() const
+{
+ if (m_isConstructorCached==0)
+ {
+ MemberDef *that = (MemberDef*)this;
+ that->_computeIsConstructor();
+ }
+ ASSERT(m_isConstructorCached>0);
+ return m_isConstructorCached==2;
+
+}
+
+void MemberDef::_computeIsDestructor()
+{
+ bool isDestructor;
+ if (m_impl->isDMember) // for D
+ {
+ isDestructor = name()=="~this";
+ }
+ else if (getLanguage()==SrcLangExt_PHP) // for PHP
+ {
+ isDestructor = name()=="__destruct";
+ }
+ else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
+ {
+ isDestructor = name()=="destructor";
+ }
+ else if (name()=="__del__" &&
+ getLanguage()==SrcLangExt_Python) // for Python
+ {
+ isDestructor=TRUE;
+ }
+ else // other languages
+ {
+ isDestructor =
+ (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
+ && name().find("operator")==-1;
+ }
+ m_isDestructorCached = isDestructor ? 2 : 1;
+}
+
+bool MemberDef::isDestructor() const
+{
+ if (m_isDestructorCached==0)
+ {
+ MemberDef *that=(MemberDef*)this;
+ that->_computeIsDestructor();
+ }
+ ASSERT(m_isDestructorCached>0);
+ return m_isDestructorCached==2;
+}
+
+void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const DefType compoundType)
+{
+ int enumMemCount=0;
+
+ MemberList *fmdl=m_impl->enumFields;
+ uint numVisibleEnumValues=0;
+ if (fmdl)
+ {
+ MemberListIterator mli(*fmdl);
+ MemberDef *fmd;
+ for (mli.toFirst();(fmd=mli.current());++mli)
+ {
+ if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
+ }
+ }
+ if (numVisibleEnumValues==0 && !isBriefSectionVisible())
+ {
+ return;
+ }
+
+ QCString n = name();
+ int i=n.findRev("::");
+ if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
+ if (n[0]!='@') // not an anonymous enum
+ {
+ if (isLinkableInProject() || hasDocumentedEnumValues())
+ {
+ _writeTagData(compoundType);
+ _addToSearchIndex();
+ writeLink(typeDecl,cd,nd,fd,gd);
+ }
+ else
+ {
+ typeDecl.startBold();
+ typeDecl.docify(n);
+ typeDecl.endBold();
+ }
+ typeDecl.writeChar(' ');
+ }
+ if (!m_impl->enumBaseType.isEmpty())
+ {
+ typeDecl.writeChar(':');
+ typeDecl.writeChar(' ');
+ typeDecl.docify(m_impl->enumBaseType);
+ typeDecl.writeChar(' ');
+ }
+
+ uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE");
+ if (numVisibleEnumValues>0 && enumValuesPerLine>0)
+ {
+ typeDecl.docify("{ ");
+ if (fmdl)
+ {
+ MemberListIterator mli(*fmdl);
+ MemberDef *fmd=mli.current();
+ bool fmdVisible = fmd->isBriefSectionVisible();
+ while (fmd)
+ {
+ if (fmdVisible)
+ {
+ /* in html we start a new line after a number of items */
+ if (numVisibleEnumValues>enumValuesPerLine
+ && (enumMemCount%enumValuesPerLine)==0
+ )
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.enable(OutputGenerator::Latex);
+ typeDecl.lineBreak();
+ typeDecl.disable(OutputGenerator::Latex);
+ typeDecl.writeString(" ");
+ typeDecl.popGeneratorState();
+ }
+
+ if (fmd->hasDocumentation()) // enum value has docs
+ {
+ fmd->_writeTagData(compoundType);
+ fmd->_addToSearchIndex();
+ fmd->writeLink(typeDecl,cd,nd,fd,gd);
+ }
+ else // no docs for this enum value
+ {
+ typeDecl.startBold();
+ typeDecl.docify(fmd->name());
+ typeDecl.endBold();
+ }
+ if (fmd->hasOneLineInitializer()) // enum value has initializer
+ {
+ //typeDecl.writeString(" = ");
+ typeDecl.writeString(" ");
+ typeDecl.parseText(fmd->initializer());
+ }
+ }
+
+ bool prevVisible = fmdVisible;
+ ++mli;
+ fmd=mli.current();
+ if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
+ {
+ typeDecl.writeString(", ");
+ }
+ if (prevVisible)
+ {
+ typeDecl.disable(OutputGenerator::Man);
+ typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
+ typeDecl.enable(OutputGenerator::Man);
+ enumMemCount++;
+ }
+ }
+ if (numVisibleEnumValues>enumValuesPerLine)
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.lineBreak();
+ typeDecl.popGeneratorState();
+ }
+ }
+ typeDecl.docify(" }");
+ }
+}
+
+void MemberDef::setArgumentList(ArgumentList *al)
+{
+ if (m_impl->defArgList) delete m_impl->defArgList;
+ m_impl->defArgList = al;
+}
+
+void MemberDef::setDeclArgumentList(ArgumentList *al)
+{
+ if (m_impl->declArgList) delete m_impl->declArgList;
+ m_impl->declArgList = al;
+}
+
+void MemberDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ if (m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ m_impl->typeConstraints->setAutoDelete(TRUE);
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
+void MemberDef::setType(const char *t)
+{
+ m_impl->type = t;
+}
+
+void MemberDef::setAccessorType(ClassDef *cd,const char *t)
+{
+ m_impl->accessorClass = cd;
+ m_impl->accessorType = t;
+}
+
+ClassDef *MemberDef::accessorClass() const
+{
+ return m_impl->accessorClass;
+}
+
+void MemberDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+}
+
+void MemberDef::enableCallGraph(bool e)
+{
+ m_impl->hasCallGraph=e;
+ if (e) Doxygen::parseSourcesNeeded = TRUE;
+}
+
+void MemberDef::enableCallerGraph(bool e)
+{
+ m_impl->hasCallerGraph=e;
+ if (e) Doxygen::parseSourcesNeeded = TRUE;
+}
+
+#if 0
+bool MemberDef::protectionVisible() const
+{
+ return m_impl->prot==Public ||
+ (m_impl->prot==Private && Config_getBool("EXTRACT_PRIVATE")) ||
+ (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) ||
+ (m_impl->prot==Package && Config_getBool("EXTRACT_PACKAGE"));
+}
+#endif
+
+#if 0
+void MemberDef::setInbodyDocumentation(const char *docs,
+ const char *docFile,int docLine)
+{
+ m_impl->inbodyDocs = docs;
+ m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
+ m_impl->inbodyLine = docLine;
+ m_impl->inbodyFile = docFile;
+}
+#endif
+
+bool MemberDef::isObjCMethod() const
+{
+ if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
+ return FALSE;
+}
+
+bool MemberDef::isObjCProperty() const
+{
+ if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
+ return FALSE;
+}
+
+QCString MemberDef::qualifiedName() const
+{
+ if (isObjCMethod())
+ {
+ QCString qm;
+ if (isStatic()) qm="+"; else qm="-";
+ qm+="[";
+ qm+=m_impl->classDef->name()+" ";
+ qm+=name();
+ qm+="]";
+ return qm;
+ }
+ else if (m_impl->enumScope && m_impl->enumScope->isStrong())
+ {
+ return m_impl->enumScope->qualifiedName()+
+ getLanguageSpecificSeparator(getLanguage())+
+ localName();
+ }
+ else
+ {
+ return Definition::qualifiedName();
+ }
+}
+
+void MemberDef::setTagInfo(TagInfo *ti)
+{
+ if (ti)
+ {
+ //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
+ m_impl->anc=ti->anchor;
+ setReference(ti->tagName);
+ m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
+ }
+}
+
+QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
+{
+ QCString qm;
+ if (showStatic)
+ {
+ if (isStatic()) qm="+ "; else qm="- ";
+ }
+ qm+=name();
+ if (!localLink) // link to method of same class
+ {
+ qm+=" (";
+ qm+=m_impl->classDef->name();
+ qm+=")";
+ }
+ return qm;
+}
+
+const char *MemberDef::declaration() const
+{
+ return m_impl->decl;
+}
+
+const char *MemberDef::definition() const
+{
+ return m_impl->def;
+}
+
+const char *MemberDef::extraTypeChars() const
+{
+ return m_impl->extraTypeChars;
+}
+
+const char *MemberDef::typeString() const
+{
+ return m_impl->type;
+}
+
+const char *MemberDef::argsString() const
+{
+ return m_impl->args;
+}
+
+const char *MemberDef::excpString() const
+{
+ return m_impl->exception;
+}
+
+const char *MemberDef::bitfieldString() const
+{
+ return m_impl->bitfields;
+}
+
+const QCString &MemberDef::initializer() const
+{
+ return m_impl->initializer;
+}
+
+int MemberDef::initializerLines() const
+{
+ return m_impl->initLines;
+}
+
+uint64 MemberDef::getMemberSpecifiers() const
+{
+ return m_impl->memSpec;
+}
+
+ClassDef *MemberDef::getClassDef() const
+{
+ return m_impl->classDef;
+}
+
+FileDef *MemberDef::getFileDef() const
+{
+ return m_impl->fileDef;
+}
+
+NamespaceDef* MemberDef::getNamespaceDef() const
+{
+ return m_impl->nspace;
+}
+
+const char *MemberDef::getReadAccessor() const
+{
+ return m_impl->read;
+}
+
+const char *MemberDef::getWriteAccessor() const
+{
+ return m_impl->write;
+}
+
+GroupDef *MemberDef::getGroupDef() const
+{
+ return m_impl->group;
+}
+
+Grouping::GroupPri_t MemberDef::getGroupPri() const
+{
+ return m_impl->grouppri;
+}
+
+const char *MemberDef::getGroupFileName() const
+{
+ return m_impl->groupFileName;
+}
+
+int MemberDef::getGroupStartLine() const
+{
+ return m_impl->groupStartLine;
+}
+
+bool MemberDef::getGroupHasDocs() const
+{
+ return m_impl->groupHasDocs;
+}
+
+Protection MemberDef::protection() const
+{
+ return m_impl->prot;
+}
+
+MemberType MemberDef::memberType() const
+{
+ return m_impl->mtype;
+}
+
+bool MemberDef::isSignal() const
+{
+ return m_impl->mtype==MemberType_Signal;
+}
+
+bool MemberDef::isSlot() const
+{
+ return m_impl->mtype==MemberType_Slot;
+}
+
+bool MemberDef::isVariable() const
+{
+ return m_impl->mtype==MemberType_Variable;
+}
+
+bool MemberDef::isEnumerate() const
+{
+ return m_impl->mtype==MemberType_Enumeration;
+}
+
+bool MemberDef::isEnumValue() const
+{
+ return m_impl->mtype==MemberType_EnumValue;
+}
+
+bool MemberDef::isTypedef() const
+{
+ return m_impl->mtype==MemberType_Typedef;
+}
+
+bool MemberDef::isFunction() const
+{
+ return m_impl->mtype==MemberType_Function;
+}
+
+bool MemberDef::isFunctionPtr() const
+{
+ return m_impl->mtype==MemberType_Variable && QCString(argsString()).find(")(")!=-1;
+}
+
+bool MemberDef::isDefine() const
+{
+ return m_impl->mtype==MemberType_Define;
+}
+
+bool MemberDef::isFriend() const
+{
+ return m_impl->mtype==MemberType_Friend;
+}
+
+bool MemberDef::isDCOP() const
+{
+ return m_impl->mtype==MemberType_DCOP;
+}
+
+bool MemberDef::isProperty() const
+{
+ return m_impl->mtype==MemberType_Property;
+}
+
+bool MemberDef::isEvent() const
+{
+ return m_impl->mtype==MemberType_Event;
+}
+
+bool MemberDef::isRelated() const
+{
+ return m_impl->related == Related;
+}
+
+bool MemberDef::isForeign() const
+{
+ return m_impl->related == Foreign;
+}
+
+bool MemberDef::isStatic() const
+{
+ return m_impl->stat;
+}
+
+bool MemberDef::isInline() const
+{
+ return (m_impl->memSpec&Entry::Inline)!=0;
+}
+
+bool MemberDef::isExplicit() const
+{
+ return (m_impl->memSpec&Entry::Explicit)!=0;
+}
+
+bool MemberDef::isMutable() const
+{
+ return (m_impl->memSpec&Entry::Mutable)!=0;
+}
+
+bool MemberDef::isGettable() const
+{
+ return (m_impl->memSpec&Entry::Gettable)!=0;
+}
+
+bool MemberDef::isPrivateGettable() const
+{
+ return (m_impl->memSpec&Entry::PrivateGettable)!=0;
+}
+
+bool MemberDef::isProtectedGettable() const
+{
+ return (m_impl->memSpec&Entry::ProtectedGettable)!=0;
+}
+
+bool MemberDef::isSettable() const
+{
+ return (m_impl->memSpec&Entry::Settable)!=0;
+}
+
+bool MemberDef::isPrivateSettable() const
+{
+ return (m_impl->memSpec&Entry::PrivateSettable)!=0;
+}
+
+bool MemberDef::isProtectedSettable() const
+{
+ return (m_impl->memSpec&Entry::ProtectedSettable)!=0;
+}
+
+bool MemberDef::isAddable() const
+{
+ return (m_impl->memSpec&Entry::Addable)!=0;
+}
+
+bool MemberDef::isRemovable() const
+{
+ return (m_impl->memSpec&Entry::Removable)!=0;
+}
+
+bool MemberDef::isRaisable() const
+{
+ return (m_impl->memSpec&Entry::Raisable)!=0;
+}
+
+bool MemberDef::isReadable() const
+{
+ return (m_impl->memSpec&Entry::Readable)!=0;
+}
+
+bool MemberDef::isWritable() const
+{
+ return (m_impl->memSpec&Entry::Writable)!=0;
+}
+
+bool MemberDef::isFinal() const
+{
+ return (m_impl->memSpec&Entry::Final)!=0;
+}
+
+bool MemberDef::isNew() const
+{
+ return (m_impl->memSpec&Entry::New)!=0;
+}
+
+bool MemberDef::isSealed() const
+{
+ return (m_impl->memSpec&Entry::Sealed)!=0;
+}
+
+bool MemberDef::isOverride() const
+{
+ return (m_impl->memSpec&Entry::Override)!=0;
+}
+
+bool MemberDef::isInitonly() const
+{
+ return (m_impl->memSpec&Entry::Initonly)!=0;
+}
+
+bool MemberDef::isAbstract() const
+{
+ return (m_impl->memSpec&Entry::Abstract)!=0;
+}
+
+bool MemberDef::isOptional() const
+{
+ return (m_impl->memSpec&Entry::Optional)!=0;
+}
+
+bool MemberDef::isRequired() const
+{
+ return (m_impl->memSpec&Entry::Required)!=0;
+}
+
+bool MemberDef::isNonAtomic() const
+{
+ return (m_impl->memSpec&Entry::NonAtomic)!=0;
+}
+
+bool MemberDef::isCopy() const
+{
+ return (m_impl->memSpec&Entry::Copy)!=0;
+}
+
+bool MemberDef::isAssign() const
+{
+ return (m_impl->memSpec&Entry::Assign)!=0;
+}
+
+bool MemberDef::isRetain() const
+{
+ return (m_impl->memSpec&Entry::Retain)!=0;
+}
+
+bool MemberDef::isWeak() const
+{
+ return (m_impl->memSpec&Entry::Weak)!=0;
+}
+
+bool MemberDef::isStrong() const
+{
+ return (m_impl->memSpec&Entry::Strong)!=0;
+}
+
+bool MemberDef::isStrongEnumValue() const
+{
+ return m_impl->mtype==MemberType_EnumValue &&
+ m_impl->enumScope &&
+ m_impl->enumScope->isStrong();
+}
+
+bool MemberDef::isUnretained() const
+{
+ return (m_impl->memSpec&Entry::Unretained)!=0;
+}
+
+bool MemberDef::isAlias() const
+{
+ return (m_impl->memSpec&Entry::Alias)!=0;
+}
+
+bool MemberDef::isDefault() const
+{
+ return (m_impl->memSpec&Entry::Default)!=0;
+}
+
+bool MemberDef::isDelete() const
+{
+ return (m_impl->memSpec&Entry::Delete)!=0;
+}
+
+bool MemberDef::isNoExcept() const
+{
+ return (m_impl->memSpec&Entry::NoExcept)!=0;
+}
+
+bool MemberDef::isAttribute() const
+{
+ return (m_impl->memSpec&Entry::Attribute)!=0;
+}
+
+bool MemberDef::isUNOProperty() const
+{
+ return (m_impl->memSpec&Entry::Property)!=0;
+}
+
+bool MemberDef::isReadonly() const
+{
+ return (m_impl->memSpec&Entry::Readonly)!=0;
+}
+
+bool MemberDef::isBound() const
+{
+ return (m_impl->memSpec&Entry::Bound)!=0;
+}
+
+bool MemberDef::isConstrained() const
+{
+ return (m_impl->memSpec&Entry::Constrained)!=0;
+}
+
+bool MemberDef::isTransient() const
+{
+ return (m_impl->memSpec&Entry::Transient)!=0;
+}
+
+bool MemberDef::isMaybeVoid() const
+{
+ return (m_impl->memSpec&Entry::MaybeVoid)!=0;
+}
+
+bool MemberDef::isMaybeDefault() const
+{
+ return (m_impl->memSpec&Entry::MaybeDefault)!=0;
+}
+
+bool MemberDef::isMaybeAmbiguous() const
+{
+ return (m_impl->memSpec&Entry::MaybeAmbiguous)!=0;
+}
+
+bool MemberDef::isPublished() const
+{
+ return (m_impl->memSpec&Entry::Published)!=0;
+}
+
+
+bool MemberDef::isImplementation() const
+{
+ return m_impl->implOnly;
+}
+
+bool MemberDef::isExternal() const
+{
+ return m_impl->explExt;
+}
+
+bool MemberDef::isTemplateSpecialization() const
+{
+ return m_impl->tspec;
+}
+
+bool MemberDef::hasDocumentedParams() const
+{
+ return m_impl->hasDocumentedParams;
+}
+
+bool MemberDef::hasDocumentedReturnType() const
+{
+ return m_impl->hasDocumentedReturnType;
+}
+
+bool MemberDef::showInCallGraph() const
+{
+ return isFunction() ||
+ isSlot() ||
+ isConstructor() ||
+ isDestructor() ||
+ isObjCMethod();
+}
+
+ClassDef *MemberDef::relatedAlso() const
+{
+ return m_impl->relatedAlso;
+}
+
+bool MemberDef::hasDocumentedEnumValues() const
+{
+ return m_impl->docEnumValues;
+}
+
+MemberDef *MemberDef::getAnonymousEnumType() const
+{
+ return m_impl->annEnumType;
+}
+
+bool MemberDef::isDocsForDefinition() const
+{
+ return m_impl->docsForDefinition;
+}
+
+MemberDef *MemberDef::getEnumScope() const
+{
+ return m_impl->enumScope;
+}
+
+MemberList *MemberDef::enumFieldList() const
+{
+ return m_impl->enumFields;
+}
+
+ExampleSDict *MemberDef::getExamples() const
+{
+ return m_impl->exampleSDict;
+}
+
+bool MemberDef::isPrototype() const
+{
+ return m_impl->proto;
+}
+
+ArgumentList *MemberDef::argumentList() const
+{
+ return m_impl->defArgList;
+}
+
+ArgumentList *MemberDef::declArgumentList() const
+{
+ return m_impl->declArgList;
+}
+
+ArgumentList *MemberDef::templateArguments() const
+{
+ return m_impl->tArgList;
+}
+
+QList<ArgumentList> *MemberDef::definitionTemplateParameterLists() const
+{
+ return m_impl->defTmpArgLists;
+}
+
+int MemberDef::getMemberGroupId() const
+{
+ return m_impl->grpId;
+}
+
+MemberGroup *MemberDef::getMemberGroup() const
+{
+ return m_impl->memberGroup;
+}
+
+bool MemberDef::fromAnonymousScope() const
+{
+ return m_impl->annScope;
+}
+
+bool MemberDef::anonymousDeclShown() const
+{
+ return m_impl->annUsed;
+}
+
+void MemberDef::setAnonymousUsed()
+{
+ m_impl->annUsed = TRUE;
+}
+
+bool MemberDef::hasCallGraph() const
+{
+ return m_impl->hasCallGraph;
+}
+
+bool MemberDef::hasCallerGraph() const
+{
+ return m_impl->hasCallerGraph;
+}
+
+MemberDef *MemberDef::templateMaster() const
+{
+ return m_impl->templateMaster;
+}
+
+bool MemberDef::isTypedefValCached() const
+{
+ return m_impl->isTypedefValCached;
+}
+
+ClassDef *MemberDef::getCachedTypedefVal() const
+{
+ return m_impl->cachedTypedefValue;
+}
+
+QCString MemberDef::getCachedTypedefTemplSpec() const
+{
+ return m_impl->cachedTypedefTemplSpec;
+}
+
+QCString MemberDef::getCachedResolvedTypedef() const
+{
+ //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
+ return m_impl->cachedResolvedType;
+}
+
+MemberDef *MemberDef::memberDefinition() const
+{
+ return m_impl->memDef;
+}
+
+MemberDef *MemberDef::memberDeclaration() const
+{
+ return m_impl->memDec;
+}
+
+MemberDef *MemberDef::inheritsDocsFrom() const
+{
+ return m_impl->docProvider;
+}
+
+MemberDef *MemberDef::getGroupAlias() const
+{
+ return m_impl->groupAlias;
+}
+
+void MemberDef::setMemberType(MemberType t)
+{
+ m_impl->mtype=t;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setDefinition(const char *d)
+{
+ m_impl->def=d;
+}
+
+void MemberDef::setFileDef(FileDef *fd)
+{
+ m_impl->fileDef=fd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ m_isDestructorCached = 0;
+}
+
+void MemberDef::setProtection(Protection p)
+{
+ m_impl->prot=p;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setMemberSpecifiers(uint64 s)
+{
+ m_impl->memSpec=s;
+}
+
+void MemberDef::mergeMemberSpecifiers(uint64 s)
+{
+ m_impl->memSpec|=s;
+}
+
+void MemberDef::setBitfields(const char *s)
+{
+ m_impl->bitfields = QCString(s).simplifyWhiteSpace();
+}
+
+void MemberDef::setMaxInitLines(int lines)
+{
+ if (lines!=-1)
+ {
+ m_impl->userInitLines=lines;
+ }
+}
+
+void MemberDef::setExplicitExternal(bool b)
+{
+ m_impl->explExt=b;
+}
+
+void MemberDef::setReadAccessor(const char *r)
+{
+ m_impl->read=r;
+}
+
+void MemberDef::setWriteAccessor(const char *w)
+{
+ m_impl->write=w;
+}
+
+void MemberDef::setTemplateSpecialization(bool b)
+{
+ m_impl->tspec=b;
+}
+
+void MemberDef::makeRelated()
+{
+ m_impl->related = Related;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::makeForeign()
+{
+ m_impl->related = Foreign;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setHasDocumentedParams(bool b)
+{
+ m_impl->hasDocumentedParams = b;
+}
+
+void MemberDef::setHasDocumentedReturnType(bool b)
+{
+ m_impl->hasDocumentedReturnType = b;
+}
+
+void MemberDef::setInheritsDocsFrom(MemberDef *md)
+{
+ m_impl->docProvider = md;
+}
+
+void MemberDef::setArgsString(const char *as)
+{
+ m_impl->args = as;
+}
+
+void MemberDef::setRelatedAlso(ClassDef *cd)
+{
+ m_impl->relatedAlso=cd;
+}
+
+void MemberDef::setEnumClassScope(ClassDef *cd)
+{
+ m_impl->classDef = cd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+}
+
+void MemberDef::setDocumentedEnumValues(bool value)
+{
+ m_impl->docEnumValues=value;
+}
+
+void MemberDef::setAnonymousEnumType(MemberDef *md)
+{
+ m_impl->annEnumType = md;
+}
+
+void MemberDef::setPrototype(bool p)
+{
+ m_impl->proto=p;
+}
+
+void MemberDef::setMemberGroupId(int id)
+{
+ m_impl->grpId=id;
+}
+
+void MemberDef::makeImplementationDetail()
+{
+ m_impl->implOnly=TRUE;
+}
+
+void MemberDef::setFromAnonymousScope(bool b)
+{
+ m_impl->annScope=b;
+}
+
+void MemberDef::setFromAnonymousMember(MemberDef *m)
+{
+ m_impl->annMemb=m;
+}
+
+MemberDef *MemberDef::fromAnonymousMember() const
+{
+ return m_impl->annMemb;
+}
+
+void MemberDef::setTemplateMaster(MemberDef *mt)
+{
+ m_impl->templateMaster=mt;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setDocsForDefinition(bool b)
+{
+ m_impl->docsForDefinition = b;
+}
+
+void MemberDef::setGroupAlias(MemberDef *md)
+{
+ m_impl->groupAlias = md;
+}
+
+void MemberDef::invalidateTypedefValCache()
+{
+ m_impl->isTypedefValCached=FALSE;
+}
+
+void MemberDef::setMemberDefinition(MemberDef *md)
+{
+ m_impl->memDef=md;
+}
+
+void MemberDef::setMemberDeclaration(MemberDef *md)
+{
+ m_impl->memDec=md;
+}
+
+ClassDef *MemberDef::category() const
+{
+ return m_impl->category;
+}
+
+void MemberDef::setCategory(ClassDef *def)
+{
+ m_impl->category = def;
+}
+
+MemberDef *MemberDef::categoryRelation() const
+{
+ return m_impl->categoryRelation;
+}
+
+void MemberDef::setCategoryRelation(MemberDef *md)
+{
+ m_impl->categoryRelation = md;
+}
+
+void MemberDef::setEnumBaseType(const QCString &type)
+{
+ m_impl->enumBaseType = type;
+}
+
+QCString MemberDef::enumBaseType() const
+{
+ return m_impl->enumBaseType;
+}
+
+
+void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
+{
+ m_impl->isTypedefValCached=TRUE;
+ m_impl->cachedTypedefValue=val;
+ m_impl->cachedTypedefTemplSpec=templSpec;
+ m_impl->cachedResolvedType=resolvedType;
+ //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
+}
+
+void MemberDef::copyArgumentNames(MemberDef *bmd)
+{
+ {
+ ArgumentList *arguments = bmd->argumentList();
+ if (m_impl->defArgList && arguments)
+ {
+ ArgumentListIterator aliDst(*m_impl->defArgList);
+ ArgumentListIterator aliSrc(*arguments);
+ Argument *argDst, *argSrc;
+ for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+ {
+ argDst->name = argSrc->name;
+ }
+ }
+ }
+ {
+ ArgumentList *arguments = bmd->declArgumentList();
+ if (m_impl->declArgList && arguments)
+ {
+ ArgumentListIterator aliDst(*m_impl->declArgList);
+ ArgumentListIterator aliSrc(*arguments);
+ Argument *argDst, *argSrc;
+ for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+ {
+ argDst->name = argSrc->name;
+ }
+ }
+ }
+}
+
+static void invalidateCachedTypesInArgumentList(ArgumentList *al)
+{
+ if (al)
+ {
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ a->canType.resize(0);
+ }
+ }
+}
+
+void MemberDef::invalidateCachedArgumentTypes()
+{
+ invalidateCachedTypesInArgumentList(m_impl->defArgList);
+ invalidateCachedTypesInArgumentList(m_impl->declArgList);
+}
+
+//----------------
+
+QCString MemberDef::displayName(bool) const
+{
+ return Definition::name();
+}
+
+void MemberDef::_addToSearchIndex()
+{
+ // write search index info
+ if (Doxygen::searchIndex && isLinkableInProject())
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ QCString ln=localName(),qn=qualifiedName();
+ Doxygen::searchIndex->addWord(ln,TRUE);
+ if (ln!=qn)
+ {
+ Doxygen::searchIndex->addWord(qn,TRUE);
+ if (getClassDef())
+ {
+ Doxygen::searchIndex->addWord(getClassDef()->displayName(),TRUE);
+ }
+ else if (getNamespaceDef())
+ {
+ Doxygen::searchIndex->addWord(getNamespaceDef()->displayName(),TRUE);
+ }
+ }
+ }
+}
+
+
+
+//----------------
+
+static void transferArgumentDocumentation(ArgumentList *decAl,ArgumentList *defAl)
+{
+ if (decAl && defAl)
+ {
+ ArgumentListIterator decAli(*decAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *decA,*defA;
+ for (decAli.toFirst(),defAli.toFirst();
+ (decA=decAli.current()) && (defA=defAli.current());
+ ++decAli,++defAli)
+ {
+ //printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
+ // decA->name.data(),decA->docs.data(),
+ // defA->name.data(),defA->docs.data()
+ // );
+ if (decA->docs.isEmpty() && !defA->docs.isEmpty())
+ {
+ decA->docs = defA->docs.copy();
+ }
+ else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
+ {
+ defA->docs = decA->docs.copy();
+ }
+ }
+ }
+}
+
+void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
+{
+ //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
+ if (
+ (mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
+ (mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
+ )
+ {
+ //printf("mdef=(%p,%s) mdec=(%p,%s)\n",
+ // mdef, mdef ? mdef->name().data() : "",
+ // mdec, mdec ? mdec->name().data() : "");
+
+ ArgumentList *mdefAl = mdef->argumentList();
+ ArgumentList *mdecAl = mdec->argumentList();
+ if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
+ mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
+ TRUE
+ )
+ ) /* match found */
+ {
+ //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
+ // mn->memberName(),
+ // mdef->getFileDef()->name().data(),mdef->documentation().data(),
+ // mdec->getFileDef()->name().data(),mdec->documentation().data()
+ // );
+
+ // first merge argument documentation
+ transferArgumentDocumentation(mdecAl,mdefAl);
+
+ /* copy documentation between function definition and declaration */
+ if (!mdec->briefDescription().isEmpty())
+ {
+ mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
+ }
+ else if (!mdef->briefDescription().isEmpty())
+ {
+ mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
+ }
+ if (!mdef->documentation().isEmpty())
+ {
+ //printf("transferring docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
+ mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
+ mdec->setDocsForDefinition(mdef->isDocsForDefinition());
+ if (mdefAl!=0)
+ {
+ ArgumentList *mdefAlComb = new ArgumentList;
+ stringToArgumentList(mdef->argsString(),mdefAlComb);
+ transferArgumentDocumentation(mdefAl,mdefAlComb);
+ mdec->setArgumentList(mdefAlComb);
+ }
+ }
+ else if (!mdec->documentation().isEmpty())
+ {
+ //printf("transferring docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
+ mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
+ mdef->setDocsForDefinition(mdec->isDocsForDefinition());
+ if (mdecAl!=0)
+ {
+ ArgumentList *mdecAlComb = new ArgumentList;
+ stringToArgumentList(mdec->argsString(),mdecAlComb);
+ transferArgumentDocumentation(mdecAl,mdecAlComb);
+ mdef->setDeclArgumentList(mdecAlComb);
+ }
+ }
+ if (!mdef->inbodyDocumentation().isEmpty())
+ {
+ mdec->setInbodyDocumentation(mdef->inbodyDocumentation(),mdef->inbodyFile(),mdef->inbodyLine());
+ }
+ else if (!mdec->inbodyDocumentation().isEmpty())
+ {
+ mdef->setInbodyDocumentation(mdec->inbodyDocumentation(),mdec->inbodyFile(),mdec->inbodyLine());
+ }
+ if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
+ {
+ //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
+ mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
+ mdef->setBodyDef(mdec->getBodyDef());
+ //mdef->setBodyMember(mdec);
+ }
+ else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
+ {
+ //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
+ mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
+ mdec->setBodyDef(mdef->getBodyDef());
+ //mdec->setBodyMember(mdef);
+ }
+ mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
+ mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
+
+
+ // copy group info.
+ if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
+ {
+ mdec->setGroupDef(mdef->getGroupDef(),
+ mdef->getGroupPri(),
+ mdef->docFile(),
+ mdef->docLine(),
+ mdef->hasDocumentation(),
+ mdef
+ );
+ }
+ else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
+ {
+ mdef->setGroupDef(mdec->getGroupDef(),
+ mdec->getGroupPri(),
+ mdec->docFile(),
+ mdec->docLine(),
+ mdec->hasDocumentation(),
+ mdec
+ );
+ }
+
+
+ mdec->mergeRefItems(mdef);
+ mdef->mergeRefItems(mdec);
+
+ mdef->setMemberDeclaration(mdec);
+ mdec->setMemberDefinition(mdef);
+
+ mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
+ mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
+ mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
+ mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
+ }
+ }
+}
+
+QCString MemberDef::briefDescription(bool abbr) const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->briefDescription(abbr);
+ }
+ else
+ {
+ return Definition::briefDescription(abbr);
+ }
+}
+
+QCString MemberDef::documentation() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->documentation();
+ }
+ else
+ {
+ return Definition::documentation();
+ }
+}
+
+const ArgumentList *MemberDef::typeConstraints() const
+{
+ return m_impl->typeConstraints;
+}
+
+bool MemberDef::isFriendToHide() const
+{
+ static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
+ bool isFriendToHide = hideFriendCompounds &&
+ (m_impl->type=="friend class" ||
+ m_impl->type=="friend struct" ||
+ m_impl->type=="friend union");
+ return isFriendToHide;
+}
+
+bool MemberDef::isNotFriend() const
+{
+ return !(isFriend() && isFriendToHide());
+}
+
+bool MemberDef::isFunctionOrSignalSlot() const
+{
+ return isFunction() || isSlot() || isSignal();
+}
+
+bool MemberDef::isRelatedOrFriend() const
+{
+ return isRelated() || isForeign() || (isFriend() && !isFriendToHide());
+}
+
diff --git a/src/memberdef.h b/src/memberdef.h
new file mode 100644
index 0000000..4f6028a
--- /dev/null
+++ b/src/memberdef.h
@@ -0,0 +1,440 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MEMBERDEF_H
+#define MEMBERDEF_H
+
+#include <qlist.h>
+#include <sys/types.h>
+
+#include "types.h"
+#include "definition.h"
+
+class ClassDef;
+class NamespaceDef;
+class GroupDef;
+class FileDef;
+class MemberList;
+class MemberGroup;
+class ExampleSDict;
+class OutputList;
+class GroupDef;
+class QTextStream;
+class ArgumentList;
+class MemberDefImpl;
+class QStrList;
+struct TagInfo;
+
+/** A model of a class/file/namespace member symbol. */
+class MemberDef : public Definition
+{
+ public:
+
+ MemberDef(const char *defFileName,int defLine,int defColumn,
+ const char *type,const char *name,const char *args,
+ const char *excp,Protection prot,Specifier virt,bool stat,
+ Relationship related,MemberType t,const ArgumentList *tal,
+ const ArgumentList *al);
+ ~MemberDef();
+ DefType definitionType() const { return TypeMember; }
+ // move this member into a different scope
+ MemberDef *deepCopy() const;
+ void moveTo(Definition *);
+
+ //-----------------------------------------------------------------------------------
+ // ---- getters -----
+ //-----------------------------------------------------------------------------------
+
+ // link id
+ QCString getOutputFileBase() const;
+ QCString getReference() const;
+ QCString anchor() const;
+
+ const char *declaration() const;
+ const char *definition() const;
+ const char *typeString() const;
+ const char *argsString() const;
+ const char *excpString() const;
+ const char *bitfieldString() const;
+ const char *extraTypeChars() const;
+ const QCString &initializer() const;
+ int initializerLines() const;
+ uint64 getMemberSpecifiers() const;
+ MemberList *getSectionList(Definition *d) const;
+ QCString displayDefinition() const;
+
+ // scope query members
+ ClassDef *getClassDef() const;
+ FileDef *getFileDef() const;
+ NamespaceDef* getNamespaceDef() const;
+ ClassDef *accessorClass() const;
+
+ // grabbing the property read/write accessor names
+ const char *getReadAccessor() const;
+ const char *getWriteAccessor() const;
+
+ // querying the grouping definition
+ GroupDef *getGroupDef() const;
+ Grouping::GroupPri_t getGroupPri() const;
+ const char *getGroupFileName() const;
+ int getGroupStartLine() const;
+ bool getGroupHasDocs() const;
+ QCString qualifiedName() const;
+ QCString objCMethodName(bool localLink,bool showStatic) const;
+
+ // direct kind info
+ Protection protection() const;
+ Specifier virtualness(int count=0) const;
+ MemberType memberType() const;
+ QCString memberTypeName() const;
+
+ // getter methods
+ bool isSignal() const;
+ bool isSlot() const;
+ bool isVariable() const;
+ bool isEnumerate() const;
+ bool isEnumValue() const;
+ bool isTypedef() const;
+ bool isFunction() const;
+ bool isFunctionPtr() const;
+ bool isDefine() const;
+ bool isFriend() const;
+ bool isDCOP() const;
+ bool isProperty() const;
+ bool isEvent() const;
+ bool isRelated() const;
+ bool isForeign() const;
+ bool isStatic() const;
+ bool isInline() const;
+ bool isExplicit() const;
+ bool isMutable() const;
+ bool isGettable() const;
+ bool isPrivateGettable() const;
+ bool isProtectedGettable() const;
+ bool isSettable() const;
+ bool isPrivateSettable() const;
+ bool isProtectedSettable() const;
+ bool isReadable() const;
+ bool isWritable() const;
+ bool isAddable() const;
+ bool isRemovable() const;
+ bool isRaisable() const;
+ bool isFinal() const;
+ bool isAbstract() const;
+ bool isOverride() const;
+ bool isInitonly() const;
+ bool isOptional() const;
+ bool isRequired() const;
+ bool isNonAtomic() const;
+ bool isCopy() const;
+ bool isAssign() const;
+ bool isRetain() const;
+ bool isWeak() const;
+ bool isStrong() const;
+ bool isUnretained() const;
+ bool isNew() const;
+ bool isSealed() const;
+ bool isImplementation() const;
+ bool isExternal() const;
+ bool isAlias() const;
+ bool isDefault() const;
+ bool isDelete() const;
+ bool isNoExcept() const;
+ bool isAttribute() const; // UNO IDL attribute
+ bool isUNOProperty() const; // UNO IDL property
+ bool isReadonly() const;
+ bool isBound() const;
+ bool isConstrained() const;
+ bool isTransient() const;
+ bool isMaybeVoid() const;
+ bool isMaybeDefault() const;
+ bool isMaybeAmbiguous() const;
+ bool isPublished() const; // UNO IDL published
+ bool isTemplateSpecialization() const;
+ bool hasDocumentedParams() const;
+ bool hasDocumentedReturnType() const;
+ bool isObjCMethod() const;
+ bool isObjCProperty() const;
+ bool isConstructor() const;
+ bool isDestructor() const;
+ bool hasOneLineInitializer() const;
+ bool hasMultiLineInitializer() const;
+ bool protectionVisible() const;
+ bool showInCallGraph() const;
+ bool isStrongEnumValue() const;
+
+ // derived getters
+ bool isFriendToHide() const;
+ bool isNotFriend() const;
+ bool isFunctionOrSignalSlot() const;
+ bool isRelatedOrFriend() const;
+
+ // output info
+ bool isLinkableInProject() const;
+ bool isLinkable() const;
+ bool hasDocumentation() const; // overrides hasDocumentation in definition.h
+ //bool hasUserDocumentation() const; // overrides hasUserDocumentation
+ bool isBriefSectionVisible() const;
+ bool isDetailedSectionVisible(bool inGroup,bool inFile) const;
+ bool isDetailedSectionLinkable() const;
+ bool isFriendClass() const;
+ bool isDocumentedFriendClass() const;
+
+ MemberDef *reimplements() const;
+ MemberList *reimplementedBy() const;
+ bool isReimplementedBy(ClassDef *cd) const;
+
+ //int inbodyLine() const;
+ //QCString inbodyFile() const;
+ //const QCString &inbodyDocumentation() const;
+
+ ClassDef *relatedAlso() const;
+
+ bool hasDocumentedEnumValues() const;
+ MemberDef *getAnonymousEnumType() const;
+ bool isDocsForDefinition() const;
+ MemberDef *getEnumScope() const;
+ MemberList *enumFieldList() const;
+ void setEnumBaseType(const QCString &type);
+ QCString enumBaseType() const;
+
+ bool hasExamples();
+ ExampleSDict *getExamples() const;
+ bool isPrototype() const;
+
+ // argument related members
+ ArgumentList *argumentList() const;
+ ArgumentList *declArgumentList() const;
+ ArgumentList *templateArguments() const;
+ QList<ArgumentList> *definitionTemplateParameterLists() const;
+
+ // member group related members
+ int getMemberGroupId() const;
+ MemberGroup *getMemberGroup() const;
+
+ bool fromAnonymousScope() const;
+ bool anonymousDeclShown() const;
+ MemberDef *fromAnonymousMember() const;
+
+ // callgraph related members
+ bool hasCallGraph() const;
+ bool hasCallerGraph() const;
+ bool visibleMemberGroup(bool hideNoHeader);
+
+ MemberDef *templateMaster() const;
+ QCString getScopeString() const;
+ ClassDef *getClassDefOfAnonymousType();
+
+ // cached typedef functions
+ bool isTypedefValCached() const;
+ ClassDef *getCachedTypedefVal() const;
+ QCString getCachedTypedefTemplSpec() const;
+ QCString getCachedResolvedTypedef() const;
+
+ MemberDef *memberDefinition() const;
+ MemberDef *memberDeclaration() const;
+ MemberDef *inheritsDocsFrom() const;
+ MemberDef *getGroupAlias() const;
+
+ ClassDef *category() const;
+ MemberDef *categoryRelation() const;
+
+ QCString displayName(bool=TRUE) const;
+ QCString getDeclType() const;
+ void getLabels(QStrList &sl,Definition *container) const;
+
+ const ArgumentList *typeConstraints() const;
+
+ // overrules
+ QCString documentation() const;
+ QCString briefDescription(bool abbr=FALSE) const;
+ QCString fieldType() const;
+
+
+ //-----------------------------------------------------------------------------------
+ // ---- setters -----
+ //-----------------------------------------------------------------------------------
+
+ // set functions
+ void setMemberType(MemberType t);
+ void setDefinition(const char *d);
+ void setFileDef(FileDef *fd);
+ void setAnchor();
+ void setProtection(Protection p);
+ void setMemberSpecifiers(uint64 s);
+ void mergeMemberSpecifiers(uint64 s);
+ void setInitializer(const char *i);
+ void setBitfields(const char *s);
+ void setMaxInitLines(int lines);
+ void setMemberClass(ClassDef *cd);
+ void setSectionList(Definition *d,MemberList *sl);
+ void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
+ const QCString &fileName,int startLine,bool hasDocs,
+ MemberDef *member=0);
+ void setExplicitExternal(bool b);
+ void setReadAccessor(const char *r);
+ void setWriteAccessor(const char *w);
+ void setTemplateSpecialization(bool b);
+
+ void makeRelated();
+ void makeForeign();
+ void setHasDocumentedParams(bool b);
+ void setHasDocumentedReturnType(bool b);
+ void setInheritsDocsFrom(MemberDef *md);
+ void setTagInfo(TagInfo *i);
+ void setArgsString(const char *as);
+
+ // relation to other members
+ void setReimplements(MemberDef *md);
+ void insertReimplementedBy(MemberDef *md);
+
+ // in-body documentation
+ //void setInbodyDocumentation(const char *docs,const char *file,int line);
+
+ void setRelatedAlso(ClassDef *cd);
+
+ // enumeration specific members
+ void insertEnumField(MemberDef *md);
+ void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE);
+ void setEnumClassScope(ClassDef *cd);
+ void setDocumentedEnumValues(bool value);
+ void setAnonymousEnumType(MemberDef *md);
+
+ // example related members
+ bool addExample(const char *anchor,const char *name,const char *file);
+
+ // prototype related members
+ void setPrototype(bool p);
+
+ // argument related members
+ void setArgumentList(ArgumentList *al);
+ void setDeclArgumentList(ArgumentList *al);
+ void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists);
+ void setTypeConstraints(ArgumentList *al);
+ void setType(const char *t);
+ void setAccessorType(ClassDef *cd,const char *t);
+
+ // namespace related members
+ void setNamespace(NamespaceDef *nd);
+
+ // member group related members
+ void setMemberGroup(MemberGroup *grp);
+ void setMemberGroupId(int id);
+ void makeImplementationDetail();
+
+ // anonymous scope members
+ void setFromAnonymousScope(bool b);
+ void setFromAnonymousMember(MemberDef *m);
+
+ void enableCallGraph(bool e);
+ void enableCallerGraph(bool e);
+
+ void setTemplateMaster(MemberDef *mt);
+ void addListReference(Definition *d);
+ void setDocsForDefinition(bool b);
+ void setGroupAlias(MemberDef *md);
+
+ void cacheTypedefVal(ClassDef *val,const QCString &templSpec,const QCString &resolvedType);
+ void invalidateTypedefValCache();
+
+ void invalidateCachedArgumentTypes();
+
+ // declaration <-> definition relation
+ void setMemberDefinition(MemberDef *md);
+ void setMemberDeclaration(MemberDef *md);
+
+ void setAnonymousUsed();
+ void copyArgumentNames(MemberDef *bmd);
+
+ void setCategory(ClassDef *);
+ void setCategoryRelation(MemberDef *);
+
+ void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE);
+ void setBriefDescription(const char *b,const char *briefFile,int briefLine);
+ void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine);
+
+ void setHidden(bool b);
+
+ //-----------------------------------------------------------------------------------
+ // --- actions ----
+ //-----------------------------------------------------------------------------------
+
+ // output generation
+ void writeDeclaration(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool inGroup, const DefType compoundType,
+ ClassDef *inheritFrom=0,const char *inheritId=0);
+ void writeDocumentation(MemberList *ml,OutputList &ol,
+ const char *scopeName,Definition *container,
+ bool inGroup,bool showEnumValues=FALSE,bool
+ showInline=FALSE);
+ void writeMemberDocSimple(OutputList &ol,Definition *container);
+ void writeEnumDeclaration(OutputList &typeDecl,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const DefType compoundType);
+ void warnIfUndocumented();
+
+ MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs,
+ ArgumentList *actualArgs);
+
+ void findSectionsInDocumentation();
+
+ bool visited;
+
+ protected:
+ void flushToDisk() const;
+ void loadFromDisk() const;
+ private:
+ void lock() const;
+ void unlock() const;
+ void saveToDisk() const;
+ void makeResident() const;
+ void _computeLinkableInProject();
+ void _computeIsConstructor();
+ void _computeIsDestructor();
+ void _writeGroupInclude(OutputList &ol,bool inGroup);
+ void _writeCallGraph(OutputList &ol);
+ void _writeCallerGraph(OutputList &ol);
+ void _writeReimplements(OutputList &ol);
+ void _writeReimplementedBy(OutputList &ol);
+ void _writeExamples(OutputList &ol);
+ void _writeTypeConstraints(OutputList &ol);
+ void _writeEnumValues(OutputList &ol,Definition *container,
+ const QCString &cfname,const QCString &ciname,
+ const QCString &cname);
+ void _writeCategoryRelation(OutputList &ol);
+ void _writeTagData(const DefType);
+ void _addToSearchIndex();
+
+ static int s_indentLevel;
+ // disable copying of member defs
+ MemberDef(const MemberDef &);
+ MemberDef &operator=(const MemberDef &);
+
+ void writeLink(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool onlyText=FALSE);
+
+ MemberDefImpl *m_impl;
+ uchar m_isLinkableCached; // 0 = not cached, 1=FALSE, 2=TRUE
+ uchar m_isConstructorCached; // 0 = not cached, 1=FALSE, 2=TRUE
+ uchar m_isDestructorCached; // 0 = not cached, 1=FALSE, 2=TRUE
+};
+
+void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef);
+
+#endif
diff --git a/src/membergroup.cpp b/src/membergroup.cpp
new file mode 100644
index 0000000..84567e2
--- /dev/null
+++ b/src/membergroup.cpp
@@ -0,0 +1,407 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "membergroup.h"
+#include "memberlist.h"
+#include "outputlist.h"
+#include "util.h"
+#include "classdef.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "language.h"
+#include "groupdef.h"
+#include "doxygen.h"
+#include "docparser.h"
+#include "marshal.h"
+#include "entry.h"
+#include "md5.h"
+
+//static QCString idToName(int id)
+//{
+// QCString result;
+// result.sprintf("mgroup_%d",id);
+// return result;
+//}
+
+MemberGroup::MemberGroup()
+{
+}
+
+MemberGroup::MemberGroup(Definition *parent,
+ int id,const char *hdr,const char *d,const char *docFile)
+{
+ //printf("New member group id=%d header=%s desc=%s\n",id,hdr,d);
+ memberList = new MemberList(MemberListType_memberGroup);
+ grpId = id;
+ grpHeader = hdr;
+ doc = d;
+ scope = 0;
+ inSameSection = TRUE;
+ inDeclSection = 0;
+ m_numDecMembers = -1;
+ m_numDocMembers = -1;
+ m_parent = parent;
+ m_docFile = docFile;
+ m_xrefListItems = 0;
+ //printf("Member group docs=`%s'\n",doc.data());
+}
+
+MemberGroup::~MemberGroup()
+{
+ delete memberList;
+}
+
+void MemberGroup::insertMember(MemberDef *md)
+{
+ //printf("MemberGroup::insertMember m_parent=%s memberList=%p count=%d"
+ // " member section list: %p: md=%p:%s\n",
+ // m_parent ? m_parent->name().data() : "<null>",
+ // memberList->first() ? memberList->first()->getSectionList(m_parent) : 0,
+ // memberList->count(),
+ // md->getSectionList(m_parent),
+ // md,md->name().data());
+
+ MemberDef *firstMd = memberList->getFirst();
+ if (inSameSection && memberList->count()>0 &&
+ firstMd->getSectionList(m_parent)!=md->getSectionList(m_parent))
+ {
+ inSameSection=FALSE;
+ }
+ else if (inDeclSection==0)
+ {
+ inDeclSection = md->getSectionList(m_parent);
+ //printf("inDeclSection=%p type=%d\n",inDeclSection,inDeclSection->listType());
+ }
+ memberList->append(md);
+
+ // copy the group of the first member in the memberGroup
+ GroupDef *gd;
+ if (firstMd && (gd=firstMd->getGroupDef()))
+ {
+ md->setGroupDef(gd, firstMd->getGroupPri(),
+ firstMd->getGroupFileName(), firstMd->getGroupStartLine(),
+ firstMd->getGroupHasDocs());
+ gd->insertMember(md);
+ }
+}
+
+
+void MemberGroup::setAnchors()
+{
+ ::setAnchors(memberList);
+}
+
+void MemberGroup::writeDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool showInline)
+{
+ //printf("MemberGroup::writeDeclarations() %s\n",grpHeader.data());
+ QCString ldoc = doc;
+ if (!ldoc.isEmpty()) ldoc.prepend("<a name=\""+anchor()+"\" id=\""+anchor()+"\"></a>");
+ memberList->writeDeclarations(ol,cd,nd,fd,gd,grpHeader,ldoc,DefinitionIntf::TypeGroup,FALSE,showInline);
+}
+
+void MemberGroup::writePlainDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ ClassDef *inheritedFrom,const char *inheritId
+ )
+{
+ //printf("MemberGroup::writePlainDeclarations() memberList->count()=%d\n",memberList->count());
+ memberList->writePlainDeclarations(ol,cd,nd,fd,gd,DefinitionIntf::TypeGroup,inheritedFrom,inheritId);
+}
+
+void MemberGroup::writeDocumentation(OutputList &ol,const char *scopeName,
+ Definition *container,bool showEnumValues,bool showInline)
+{
+ memberList->writeDocumentation(ol,scopeName,container,0,showEnumValues,showInline);
+}
+
+void MemberGroup::writeDocumentationPage(OutputList &ol,const char *scopeName,
+ Definition *container)
+{
+ memberList->writeDocumentationPage(ol,scopeName,container);
+}
+
+void MemberGroup::addGroupedInheritedMembers(OutputList &ol,ClassDef *cd,
+ MemberListType lt,
+ ClassDef *inheritedFrom,const QCString &inheritId)
+{
+ //printf("** addGroupedInheritedMembers()\n");
+ MemberListIterator li(*memberList);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType());
+ if (lt==md->getSectionList(m_parent)->listType())
+ {
+ MemberList ml(lt);
+ ml.append(md);
+ ml.writePlainDeclarations(ol,cd,0,0,0,DefinitionIntf::TypeGroup,inheritedFrom,inheritId);
+ }
+ }
+}
+
+int MemberGroup::countGroupedInheritedMembers(MemberListType lt)
+{
+ //printf("** countGroupedInheritedMembers()\n");
+ int count=0;
+ MemberListIterator li(*memberList);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType());
+ if (lt==md->getSectionList(m_parent)->listType())
+ {
+ count++;
+ }
+ }
+ return count;
+}
+
+
+/*! Add this group as a subsection of the declaration section, instead
+ * of rendering it in its own section
+ */
+void MemberGroup::addToDeclarationSection()
+{
+ if (inDeclSection)
+ {
+ //printf("Adding group %p to list %p (type=%d)\n",this,
+ // inDeclSection,inDeclSection->listType());
+ inDeclSection->addMemberGroup(this);
+ }
+}
+
+int MemberGroup::countDecMembers(GroupDef *gd)
+{
+ if (m_numDecMembers==-1) /* number of member not cached */
+ {
+ memberList->countDecMembers(gd);
+ m_numDecMembers = memberList->numDecMembers();
+ }
+ return m_numDecMembers;
+}
+
+int MemberGroup::countDocMembers()
+{
+ if (m_numDocMembers==-1)
+ {
+ memberList->countDocMembers();
+ m_numDocMembers = memberList->numDocMembers();
+ }
+ return m_numDocMembers;
+}
+
+int MemberGroup::countInheritableMembers(ClassDef *inheritedFrom) const
+{
+ return memberList->countInheritableMembers(inheritedFrom);
+}
+
+
+void MemberGroup::distributeMemberGroupDocumentation()
+{
+ //printf("MemberGroup::distributeMemberGroupDocumentation() %s\n",grpHeader.data());
+ MemberListIterator li(*memberList);
+ MemberDef *md;
+ for (li.toFirst();(md=li.current());++li)
+ {
+ //printf("checking md=%s\n",md->name().data());
+ // find the first member of the group with documentation
+ if (!md->documentation().isEmpty() ||
+ !md->briefDescription().isEmpty() ||
+ !md->inbodyDocumentation().isEmpty()
+ )
+ {
+ //printf("found it!\n");
+ break;
+ }
+ }
+ if (md) // distribute docs of md to other members of the list
+ {
+ //printf("Member %s has documentation!\n",md->name().data());
+ MemberDef *omd;
+ for (li.toFirst();(omd=li.current());++li)
+ {
+ if (md!=omd && omd->documentation().isEmpty() &&
+ omd->briefDescription().isEmpty() &&
+ omd->inbodyDocumentation().isEmpty()
+ )
+ {
+ //printf("Copying documentation to member %s\n",omd->name().data());
+ omd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+ omd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+ omd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+ }
+ }
+ }
+}
+
+int MemberGroup::varCount() const
+{
+ return memberList->varCount();
+}
+
+int MemberGroup::funcCount() const
+{
+ return memberList->funcCount();
+}
+
+int MemberGroup::enumCount() const
+{
+ return memberList->enumCount();
+}
+
+int MemberGroup::enumValueCount() const
+{
+ return memberList->enumValueCount();
+}
+
+int MemberGroup::typedefCount() const
+{
+ return memberList->typedefCount();
+}
+
+int MemberGroup::protoCount() const
+{
+ return memberList->protoCount();
+}
+
+int MemberGroup::defineCount() const
+{
+ return memberList->defineCount();
+}
+
+int MemberGroup::friendCount() const
+{
+ return memberList->friendCount();
+}
+
+int MemberGroup::numDecMembers() const
+{
+ return memberList->numDecMembers();
+}
+
+int MemberGroup::numDocMembers() const
+{
+ return memberList->numDocMembers();
+}
+
+void MemberGroup::setInGroup(bool b)
+{
+ memberList->setInGroup(b);
+}
+
+QCString MemberGroup::anchor() const
+{
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ QCString locHeader = grpHeader;
+ if (locHeader.isEmpty()) locHeader="[NOHEADER]";
+ MD5Buffer((const unsigned char *)locHeader.data(),locHeader.length(),md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ return "amgrp"+sigStr;
+}
+
+void MemberGroup::addListReferences(Definition *def)
+{
+ memberList->addListReferences(def);
+ if (m_xrefListItems && def)
+ {
+ QCString name = def->getOutputFileBase()+"#"+anchor();
+ addRefItem(m_xrefListItems,
+ name,
+ theTranslator->trGroup(TRUE,TRUE),
+ name,
+ grpHeader,0);
+ }
+}
+
+void MemberGroup::findSectionsInDocumentation()
+{
+ docFindSections(doc,0,this,m_docFile);
+ memberList->findSectionsInDocumentation();
+}
+
+void MemberGroup::marshal(StorageIntf *s)
+{
+ marshalMemberList(s,memberList);
+ marshalObjPointer(s,inDeclSection); // reference only
+ marshalInt(s,grpId);
+ marshalQCString(s,grpHeader);
+ marshalQCString(s,fileName);
+ marshalObjPointer(s,scope);
+ marshalQCString(s,doc);
+ marshalBool(s,inSameSection);
+ marshalInt(s,m_numDecMembers);
+ marshalInt(s,m_numDocMembers);
+ marshalObjPointer(s,m_parent);
+ marshalQCString(s,m_docFile);
+ marshalItemInfoList (Doxygen::symbolStorage,m_xrefListItems);
+}
+
+void MemberGroup::unmarshal(StorageIntf *s)
+{
+ memberList = unmarshalMemberList(s);
+ inDeclSection = (MemberList *)unmarshalObjPointer(s);
+ grpId = unmarshalInt(s);
+ grpHeader = unmarshalQCString(s);
+ fileName = unmarshalQCString(s);
+ scope = (Definition *)unmarshalObjPointer(s);
+ doc = unmarshalQCString(s);
+ inSameSection = unmarshalBool(s);
+ m_numDecMembers = unmarshalInt(s);
+ m_numDocMembers = unmarshalInt(s);
+ m_parent = (Definition *)unmarshalObjPointer(s);
+ m_docFile = unmarshalQCString(s);
+ m_xrefListItems = unmarshalItemInfoList (Doxygen::symbolStorage);
+}
+
+void MemberGroup::setRefItems(const QList<ListItemInfo> *sli)
+{
+ if (sli)
+ {
+ // deep copy the list
+ if (m_xrefListItems==0)
+ {
+ m_xrefListItems=new QList<ListItemInfo>;
+ m_xrefListItems->setAutoDelete(TRUE);
+ }
+ QListIterator<ListItemInfo> slii(*sli);
+ ListItemInfo *lii;
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ m_xrefListItems->append(new ListItemInfo(*lii));
+ }
+ }
+}
+//--------------------------------------------------------------------------
+
+void MemberGroupInfo::setRefItems(const QList<ListItemInfo> *sli)
+{
+ if (!sli) return;
+ if (m_sli==0)
+ {
+ m_sli = new QList<ListItemInfo>;
+ m_sli->setAutoDelete(TRUE);
+ }
+ QListIterator<ListItemInfo> slii(*sli);
+ ListItemInfo *ili;
+ for (slii.toFirst();(ili=slii.current());++slii)
+ {
+ m_sli->append(new ListItemInfo(*ili));
+ }
+}
diff --git a/src/membergroup.h b/src/membergroup.h
new file mode 100644
index 0000000..42e60c5
--- /dev/null
+++ b/src/membergroup.h
@@ -0,0 +1,148 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MEMBERGROUP_H
+#define MEMBERGROUP_H
+
+#include <qlist.h>
+#include "sortdict.h"
+#include "types.h"
+
+#define DOX_NOGROUP -1
+
+class MemberList;
+class MemberDef;
+class ClassDef;
+class NamespaceDef;
+class FileDef;
+class GroupDef;
+class OutputList;
+class Definition;
+class StorageIntf;
+struct ListItemInfo;
+
+/** A class representing a group of members. */
+class MemberGroup
+{
+ public:
+ MemberGroup();
+ MemberGroup(Definition *parent,int id,const char *header,
+ const char *docs,const char *docFile);
+ ~MemberGroup();
+ QCString header() const { return grpHeader; }
+ int groupId() const { return grpId; }
+ void insertMember(MemberDef *md);
+ void setAnchors();
+ void writePlainDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ ClassDef *inheritedFrom,const char *inheritId);
+ void writeDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool showInline=FALSE);
+ void writeDocumentation(OutputList &ol,const char *scopeName,
+ Definition *container,bool showEnumValues,bool showInline);
+ void writeDocumentationPage(OutputList &ol,const char *scopeName,
+ Definition *container);
+ void addGroupedInheritedMembers(OutputList &ol,ClassDef *cd,
+ MemberListType lt,
+ ClassDef *inheritedFrom,const QCString &inheritId);
+
+ QCString documentation() const { return doc; }
+ bool allMembersInSameSection() const { return inSameSection; }
+ void addToDeclarationSection();
+ int countDecMembers(GroupDef *gd=0);
+ int countDocMembers();
+ int countGroupedInheritedMembers(MemberListType lt);
+ void distributeMemberGroupDocumentation();
+ void findSectionsInDocumentation();
+ int varCount() const;
+ int funcCount() const;
+ int enumCount() const;
+ int enumValueCount() const;
+ int typedefCount() const;
+ int protoCount() const;
+ int defineCount() const;
+ int friendCount() const;
+ int numDecMembers() const;
+ int numDocMembers() const;
+ int countInheritableMembers(ClassDef *inheritedFrom) const;
+ void setInGroup(bool b);
+ void addListReferences(Definition *d);
+ void setRefItems(const QList<ListItemInfo> *sli);
+ MemberList *members() const { return memberList; }
+ Definition *parent() const { return m_parent; }
+ QCString anchor() const;
+
+ void marshal(StorageIntf *s);
+ void unmarshal(StorageIntf *s);
+
+ private:
+ MemberList *memberList; // list of all members in the group
+ MemberList *inDeclSection;
+ int grpId;
+ QCString grpHeader;
+ QCString fileName; // base name of the generated file
+ Definition *scope;
+ QCString doc;
+ bool inSameSection;
+ int m_numDecMembers;
+ int m_numDocMembers;
+ Definition *m_parent;
+ QCString m_docFile;
+ QList<ListItemInfo> *m_xrefListItems;
+};
+
+/** A list of MemberGroup objects. */
+class MemberGroupList : public QList<MemberGroup>
+{
+};
+
+/** An iterator for MemberGroup objects in a MemberGroupList. */
+class MemberGroupListIterator : public QListIterator<MemberGroup>
+{
+ public:
+ MemberGroupListIterator(const MemberGroupList &l) :
+ QListIterator<MemberGroup>(l) {}
+};
+
+/** A sorted dictionary of MemberGroup objects. */
+class MemberGroupSDict : public SIntDict<MemberGroup>
+{
+ public:
+ MemberGroupSDict(int size=17) : SIntDict<MemberGroup>(size) {}
+ ~MemberGroupSDict() {}
+ private:
+ int compareValues(const MemberGroup *item1,const MemberGroup *item2) const
+ {
+ return item1->groupId() - item2->groupId();
+ }
+};
+
+/** Data collected for a member group */
+struct MemberGroupInfo
+{
+ MemberGroupInfo() : m_sli(0) {}
+ ~MemberGroupInfo() { delete m_sli; m_sli=0; }
+ void setRefItems(const QList<ListItemInfo> *sli);
+ QCString header;
+ QCString doc;
+ QCString docFile;
+ QCString compoundName;
+ QList<ListItemInfo> *m_sli;
+};
+
+#endif
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
new file mode 100644
index 0000000..28ed37e
--- /dev/null
+++ b/src/memberlist.cpp
@@ -0,0 +1,963 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qregexp.h>
+
+#include "memberlist.h"
+#include "classdef.h"
+#include "message.h"
+#include "util.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputlist.h"
+#include "groupdef.h"
+#include "marshal.h"
+#include "vhdldocgen.h"
+#include "namespacedef.h"
+#include "filedef.h"
+#include "membergroup.h"
+#include "config.h"
+#include "docparser.h"
+
+MemberList::MemberList()
+{
+ memberGroupList=0;
+ m_numDecMembers=-1; // special value indicating that value needs to be computed
+ m_numDocMembers=-1; // special value indicating that value needs to be computed
+}
+
+MemberList::MemberList(MemberListType lt) : m_listType(lt)
+{
+ memberGroupList=0;
+ m_numDecMembers=-1; // special value indicating that value needs to be computed
+ m_numDocMembers=-1; // special value indicating that value needs to be computed
+ m_inGroup=FALSE;
+ m_inFile=FALSE;
+ m_needsSorting=FALSE;
+}
+
+MemberList::~MemberList()
+{
+ delete memberGroupList;
+}
+
+int MemberList::compareValues(const MemberDef *c1, const MemberDef *c2) const
+{
+ static bool sortConstructorsFirst = Config_getBool("SORT_MEMBERS_CTORS_1ST");
+ if (sortConstructorsFirst) {
+ int ord1 = c1->isConstructor() ? 2 : (c1->isDestructor() ? 1 : 0);
+ int ord2 = c2->isConstructor() ? 2 : (c2->isDestructor() ? 1 : 0);
+ if (ord1 > ord2)
+ return -1;
+ else if (ord2 > ord1)
+ return 1;
+ }
+ int cmp = qstricmp(c1->name(),c2->name());
+ return cmp!=0 ? cmp : c1->getDefLine()-c2->getDefLine();
+}
+
+int MemberList::countInheritableMembers(ClassDef *inheritedFrom) const
+{
+ int count=0;
+ QListIterator<MemberDef> mli(*this);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->isBriefSectionVisible())
+ {
+ if (md->memberType()!=MemberType_Friend &&
+ md->memberType()!=MemberType_EnumValue)
+ {
+ //printf("member %s: isReimplementedBy(%s)=%d\n",md->name().data(),
+ // inheritedFrom->name().data(),
+ // md->isReimplementedBy(inheritedFrom));
+ if (md->memberType()==MemberType_Function)
+ {
+ if (!md->isReimplementedBy(inheritedFrom)) count++;
+ }
+ else
+ {
+ count++;
+ }
+ }
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ count+=mg->countInheritableMembers(inheritedFrom);
+ }
+ }
+ //printf("%s::countInheritableMembers(%s)=%d\n",
+ // listTypeAsString().data(),
+ // inheritedFrom->name().data(),count);
+ return count;
+}
+
+/*! Count the number of members in this list that are visible in
+ * the declaration part of a compound's documentation page.
+ */
+void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd)
+{
+ if (m_numDecMembers!=-1) return;
+
+ //printf("----- countDecMembers count=%d ----\n",count());
+ m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0;
+ m_typeCnt=m_protoCnt=m_defCnt=m_friendCnt=0;
+ m_numDecMembers=0;
+ QListIterator<MemberDef> mli(*this);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ //printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible());
+ if (md->isBriefSectionVisible())
+ {
+ switch(md->memberType())
+ {
+ case MemberType_Variable: // fall through
+ case MemberType_Event: // fall through
+ case MemberType_Property: m_varCnt++,m_numDecMembers++;
+ break;
+// apparently necessary to get this to show up in declarations section?
+ case MemberType_Interface: // fall through
+ case MemberType_Service: // fall through
+ case MemberType_Function: // fall through
+ case MemberType_Signal: // fall through
+ case MemberType_DCOP: // fall through
+ case MemberType_Slot: if (!md->isRelated() || md->getClassDef())
+ m_funcCnt++,m_numDecMembers++;
+ break;
+ case MemberType_Enumeration: m_enumCnt++,m_numDecMembers++; break;
+ case MemberType_EnumValue: if (countEnumValues)
+ m_enumValCnt++,m_numDecMembers++;
+ break;
+ case MemberType_Typedef: m_typeCnt++,m_numDecMembers++; break;
+ //case MemberType_Prototype: m_protoCnt++,m_numDecMembers++; break;
+ case MemberType_Define: if (Config_getBool("EXTRACT_ALL") ||
+ md->argsString() ||
+ !md->initializer().isEmpty() ||
+ md->hasDocumentation()
+ ) m_defCnt++,m_numDecMembers++;
+ break;
+ case MemberType_Friend: m_friendCnt++,m_numDecMembers++;
+ break;
+ default:
+ err("Unknown member type found for member `%s'\n!",md->name().data());
+ }
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->countDecMembers(gd);
+ m_varCnt+=mg->varCount();
+ m_funcCnt+=mg->funcCount();
+ m_enumCnt+=mg->enumCount();
+ m_enumValCnt+=mg->enumValueCount();
+ m_typeCnt+=mg->typedefCount();
+ m_protoCnt+=mg->protoCount();
+ m_defCnt+=mg->defineCount();
+ m_friendCnt+=mg->friendCount();
+ m_numDecMembers+=mg->numDecMembers();
+ }
+ }
+ //printf("----- end countDecMembers ----\n");
+
+ //printf("MemberList::countDecMembers()=%d\n",m_numDecMembers);
+}
+
+void MemberList::countDocMembers(bool countEnumValues)
+{
+ if (m_numDocMembers!=-1) return; // used cached value
+ m_numDocMembers=0;
+ QListIterator<MemberDef> mli(*this);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->isDetailedSectionVisible(m_inGroup,m_inFile))
+ {
+ // do not count enum values, since they do not produce entries of their own
+ if (countEnumValues || md->memberType()!=MemberType_EnumValue)
+ m_numDocMembers++;
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->countDocMembers();
+ m_numDocMembers+=mg->numDocMembers();
+ }
+ }
+ //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList);
+}
+
+bool MemberList::insert(uint index,const MemberDef *md)
+{
+ return QList<MemberDef>::insert(index,md);
+}
+
+void MemberList::inSort(const MemberDef *md)
+{
+ QList<MemberDef>::inSort(md);
+}
+
+void MemberList::append(const MemberDef *md)
+{
+ QList<MemberDef>::append(md);
+}
+
+MemberListIterator::MemberListIterator(const QList<MemberDef> &l) :
+ QListIterator<MemberDef>(l)
+{
+}
+
+bool MemberList::declVisible() const
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()); ++mli )
+ {
+ if (md->isBriefSectionVisible())
+ {
+ switch (md->memberType())
+ {
+ case MemberType_Define: // fall through
+ case MemberType_Typedef: // fall through
+ case MemberType_Variable: // fall through
+ case MemberType_Function: // fall through
+ case MemberType_Signal: // fall through
+ case MemberType_Slot: // fall through
+ case MemberType_DCOP: // fall through
+ case MemberType_Property: // fall through
+ case MemberType_Interface: // fall through
+ case MemberType_Service: // fall through
+ case MemberType_Event:
+ return TRUE;
+ case MemberType_Enumeration:
+ {
+ int enumVars=0;
+ MemberListIterator vmli(*this);
+ MemberDef *vmd;
+ QCString name(md->name());
+ int i=name.findRev("::");
+ if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?)
+ if (name[0]=='@') // anonymous enum => append variables
+ {
+ for ( ; (vmd=vmli.current()) ; ++vmli)
+ {
+ QCString vtype=vmd->typeString();
+ if ((vtype.find(name))!=-1)
+ {
+ enumVars++;
+ }
+ }
+ }
+ // if this is an anonymous enum and there are variables of this
+ // enum type (i.e. enumVars>0), then we do not show the enum here.
+ if (enumVars==0) // show enum here
+ {
+ return TRUE;
+ }
+ }
+ break;
+ case MemberType_Friend:
+ return TRUE;
+ case MemberType_EnumValue:
+ {
+ if (m_inGroup)
+ {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ }
+ return FALSE;
+}
+
+void MemberList::writePlainDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,
+ GroupDef *gd, const DefinitionIntf::DefType compoundType,
+ ClassDef *inheritedFrom,const char *inheritId
+ )
+{
+ //printf("----- writePlainDeclaration() ----\n");
+ countDecMembers();
+ if (numDecMembers()==0)
+ {
+ //printf(" --> no members!\n");
+ return; // no members in this list
+ }
+ //printf(" --> writePlainDeclaration() numDecMembers()=%d\n",
+ // numDecMembers());
+
+ ol.pushGeneratorState();
+
+ bool first=TRUE;
+ MemberDef *md;
+ MemberListIterator mli(*this);
+ for ( ; (md=mli.current()); ++mli )
+ {
+ //printf(">>> Member `%s' type=%d visible=%d\n",
+ // md->name().data(),md->memberType(),md->isBriefSectionVisible());
+ if ((inheritedFrom==0 || !md->isReimplementedBy(inheritedFrom)) &&
+ md->isBriefSectionVisible())
+ {
+ //printf(">>> rendering\n");
+ switch(md->memberType())
+ {
+ case MemberType_Define: // fall through
+ //case MemberType_Prototype: // fall through
+ case MemberType_Typedef: // fall through
+ case MemberType_Variable: // fall through
+ case MemberType_Function: // fall through
+ case MemberType_Signal: // fall through
+ case MemberType_Slot: // fall through
+ case MemberType_DCOP: // fall through
+ case MemberType_Property: // fall through
+ case MemberType_Interface: // fall through
+ case MemberType_Service: // fall through
+ case MemberType_Event:
+ {
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup,compoundType,inheritedFrom,inheritId);
+ break;
+ }
+ case MemberType_Enumeration:
+ {
+ int enumVars=0;
+ MemberListIterator vmli(*this);
+ MemberDef *vmd;
+ QCString name(md->name());
+ int i=name.findRev("::");
+ if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?)
+ if (name[0]=='@') // anonymous enum => append variables
+ {
+ for ( ; (vmd=vmli.current()) ; ++vmli)
+ {
+ QCString vtype=vmd->typeString();
+ if ((vtype.find(name))!=-1)
+ {
+ enumVars++;
+ vmd->setAnonymousEnumType(md);
+ }
+ }
+ }
+ // if this is an anonymous enum and there are variables of this
+ // enum type (i.e. enumVars>0), then we do not show the enum here.
+ if (enumVars==0) // show enum here
+ {
+ //printf("Enum!!\n");
+ if (first)
+ {
+ ol.startMemberList();
+ first=FALSE;
+ }
+ ol.startMemberDeclaration();
+ ol.startMemberItem(md->anchor(),0,inheritId);
+ bool detailsLinkable = md->isDetailedSectionLinkable();
+ if (!detailsLinkable)
+ {
+ ol.startDoxyAnchor(md->getOutputFileBase(),0,md->anchor(),md->name(),QCString());
+ }
+ ol.writeString("enum ");
+ ol.insertMemberAlign();
+ md->writeEnumDeclaration(ol,cd,nd,fd,gd,compoundType);
+ if (!detailsLinkable)
+ {
+ ol.endDoxyAnchor(md->getOutputFileBase(),md->anchor());
+ }
+ ol.endMemberItem();
+ if (!md->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ DocRoot *rootNode = validatingParseDoc(
+ md->briefFile(),md->briefLine(),
+ cd,md,
+ md->briefDescription(),
+ TRUE,FALSE,0,TRUE,FALSE
+ );
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startMemberDescription(md->anchor());
+ ol.writeDoc(rootNode,cd,md);
+ if (md->isDetailedSectionLinkable())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(md->getOutputFileBase(),
+ md->anchor());
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ ol.enableAll();
+ }
+ ol.endMemberDescription();
+ }
+ delete rootNode;
+ }
+ ol.endMemberDeclaration(md->anchor(),inheritId);
+ }
+ md->warnIfUndocumented();
+ break;
+ }
+ case MemberType_Friend:
+ if (inheritedFrom==0)
+ {
+ if (first)
+ {
+ ol.startMemberList();
+ first=FALSE;
+ }
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup,compoundType,inheritedFrom,inheritId);
+ break;
+ }
+ case MemberType_EnumValue:
+ {
+ if (m_inGroup)
+ {
+ //printf("EnumValue!\n");
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup,compoundType,inheritedFrom,inheritId);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // handle members that are inside anonymous compounds and for which
+ // no variables of the anonymous compound type exist.
+ if (cd)
+ {
+ MemberListIterator mli(*this);
+ for ( ; (md=mli.current()) ; ++mli )
+ {
+ if (md->fromAnonymousScope() && !md->anonymousDeclShown())
+ {
+ md->setFromAnonymousScope(FALSE);
+ //printf("anonymous compound members\n");
+ if (md->isBriefSectionVisible())
+ {
+ if (first)
+ {
+ ol.startMemberList();
+ first=FALSE;
+ }
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup,compoundType);
+ }
+ md->setFromAnonymousScope(TRUE);
+ }
+ }
+ }
+
+ if (!first)
+ {
+ ol.endMemberList();
+ }
+
+ ol.popGeneratorState();
+ //printf("----- end writePlainDeclaration() ----\n");
+}
+
+/** Writes the list of members to the output.
+ * @param ol Output list to write to
+ * @param cd non-null if this list is part of class documentation.
+ * @param nd non-null if this list is part of namespace documentation.
+ * @param fd non-null if this list is part of file documentation.
+ * @param gd non-null if this list is part of group documentation.
+ * @param title Title to use for the member list.
+ * @param subtitle Sub title to use for the member list.
+ * @param compoundType Container type for this member list.
+ * @param showEnumValues Obsolete, always set to FALSE.
+ * @param showInline if set to TRUE if title is rendered differently
+ * @param inheritedFrom if not 0, the list is shown inside the
+ * given class as inherited members, parameter cd points to the
+ * class containing the members.
+ * @param lt Type of list that is inherited from.
+ */
+void MemberList::writeDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const char *title,const char *subtitle,
+ const DefinitionIntf::DefType compoundType,bool showEnumValues,
+ bool showInline,ClassDef *inheritedFrom,MemberListType lt)
+{
+ (void)showEnumValues; // unused
+
+ //printf("----- writeDeclaration() this=%p ---- inheritedFrom=%p\n",this,inheritedFrom);
+ static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString inheritId;
+
+ countDecMembers(/*showEnumValues*/FALSE,gd); // count members shown in this section
+ Definition *ctx = cd;
+ if (ctx==0 && nd) ctx = nd;
+ if (ctx==0 && gd) ctx = gd;
+ if (ctx==0 && fd) ctx = fd;
+
+ //printf("%p: MemberList::writeDeclaration(title=`%s',subtitle=`%s')=%d inheritedFrom=%p\n",
+ // this,title,subtitle,numDecMembers(),inheritedFrom);
+
+ int num = numDecMembers();
+ if (inheritedFrom)
+ {
+ //if ( cd && !optimizeVhdl && countInheritableMembers(inheritedFrom)>0 )
+ if ( cd && !optimizeVhdl && cd->countMembersIncludingGrouped(
+ m_listType,inheritedFrom,TRUE)>0 )
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ inheritId = substitute(listTypeAsString(lt),"-","_")+"_"+
+ stripPath(cd->getOutputFileBase());
+ if (title)
+ {
+ ol.writeInheritedSectionTitle(inheritId,cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),title,cd->displayName());
+ }
+ ol.popGeneratorState();
+ }
+ }
+ else if (num>0)
+ {
+ if (title)
+ {
+ if (showInline)
+ {
+ ol.startInlineHeader();
+ }
+ else
+ {
+ ol.startMemberHeader(listTypeAsString(m_listType));
+ }
+ ol.parseText(title);
+ if (showInline)
+ {
+ ol.endInlineHeader();
+ }
+ else
+ {
+ ol.endMemberHeader();
+ }
+ }
+ if (subtitle)
+ {
+ QCString st=subtitle;
+ st = st.stripWhiteSpace();
+ if (!st.isEmpty())
+ {
+ ol.startMemberSubtitle();
+ ol.generateDoc("[generated]",-1,ctx,0,subtitle,FALSE,FALSE,0,FALSE,FALSE);
+ ol.endMemberSubtitle();
+ }
+ }
+ }
+ if (num>0)
+ {
+ // TODO: Two things need to be worked out for proper VHDL output:
+ // 1. Signals and types under the group need to be
+ // formatted to associate them with the group somehow
+ // indentation, or at the very least, extra space after
+ // the group is done
+ // 2. This might need to be repeated below for memberGroupLists
+ if (optimizeVhdl) // use specific declarations function
+ {
+ VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd,0,0);
+ }
+ else
+ {
+ writePlainDeclarations(ol,cd,nd,fd,gd,compoundType,inheritedFrom,inheritId);
+ }
+
+ //printf("memberGroupList=%p\n",memberGroupList);
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ while ((mg=mgli.current()))
+ {
+ bool hasHeader=!mg->header().isEmpty() && mg->header()!="[NOHEADER]";
+ if (inheritId.isEmpty())
+ {
+ //printf("mg->header=%s hasHeader=%d\n",mg->header().data(),hasHeader);
+ ol.startMemberGroupHeader(hasHeader);
+ if (hasHeader)
+ {
+ ol.parseText(mg->header());
+ }
+ ol.endMemberGroupHeader();
+ if (!mg->documentation().isEmpty())
+ {
+ //printf("Member group has docs!\n");
+ ol.startMemberGroupDocs();
+ ol.generateDoc("[generated]",-1,ctx,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.endMemberGroupDocs();
+ }
+ ol.startMemberGroup();
+ }
+ //printf("--- mg->writePlainDeclarations ---\n");
+ mg->writePlainDeclarations(ol,cd,nd,fd,gd,inheritedFrom,inheritId);
+ if (inheritId.isEmpty())
+ {
+ ol.endMemberGroup(hasHeader);
+ }
+ ++mgli;
+ }
+ }
+ }
+ if (inheritedFrom && cd)
+ {
+ // also add members that of this list type, that are grouped together
+ // in a separate list in class 'inheritedFrom'
+ cd->addGroupedInheritedMembers(ol,m_listType,inheritedFrom,inheritId);
+ }
+ //printf("----- end writeDeclaration() ----\n");
+}
+
+void MemberList::writeDocumentation(OutputList &ol,
+ const char *scopeName, Definition *container,
+ const char *title,bool showEnumValues,bool showInline)
+{
+ //printf("MemberList::writeDocumentation()\n");
+
+ countDocMembers(showEnumValues);
+ if (numDocMembers()==0) return;
+
+ if (title)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+ ol.startGroupHeader(showInline ? 2 : 0);
+ ol.parseText(title);
+ ol.endGroupHeader(showInline ? 2 : 0);
+ }
+ ol.startMemberDocList();
+
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ md->writeDocumentation(this,ol,scopeName,container,
+ m_inGroup,showEnumValues,showInline);
+ }
+ if (memberGroupList)
+ {
+ //printf("MemberList::writeDocumentation() -- member groups\n");
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->writeDocumentation(ol,scopeName,container,showEnumValues,showInline);
+ }
+ }
+ ol.endMemberDocList();
+}
+
+// members in a table
+void MemberList::writeSimpleDocumentation(OutputList &ol,
+ Definition *container)
+{
+ countDocMembers(FALSE);
+ //printf("MemberList count=%d\n",numDocMembers());
+ if (numDocMembers()==0) return;
+
+ ol.startMemberDocSimple();
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ md->writeMemberDocSimple(ol,container);
+ }
+ ol.endMemberDocSimple();
+}
+
+// separate member pages
+void MemberList::writeDocumentationPage(OutputList &ol,
+ const char *scopeName, Definition *container)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ if (md->isDetailedSectionLinkable())
+ {
+ QCString diskName=md->getOutputFileBase();
+ QCString title=md->qualifiedName();
+ startFile(ol,diskName,md->name(),title,HLI_None,!generateTreeView,diskName);
+ if (!generateTreeView)
+ {
+ container->writeNavigationPath(ol);
+ ol.endQuickIndices();
+ }
+ ol.startContents();
+
+ if (generateTreeView)
+ {
+ md->writeDocumentation(this,ol,scopeName,container,m_inGroup);
+ ol.endContents();
+ endFileWithNavPath(container,ol);
+ }
+ else
+ {
+ ol.writeString("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"
+ " <tr>\n"
+ " <td valign=\"top\">\n");
+
+ container->writeQuickMemberLinks(ol,md);
+
+ ol.writeString(" </td>\n");
+ ol.writeString(" <td valign=\"top\" class=\"mempage\">\n");
+
+ md->writeDocumentation(this,ol,scopeName,container,m_inGroup);
+
+ ol.writeString(" </td>\n");
+ ol.writeString(" </tr>\n");
+ ol.writeString("</table>\n");
+
+ endFile(ol);
+ }
+ }
+ if (memberGroupList)
+ {
+ //printf("MemberList::writeDocumentation() -- member groups\n");
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->writeDocumentationPage(ol,scopeName,container);
+ }
+ }
+ }
+}
+
+void MemberList::addMemberGroup(MemberGroup *mg)
+{
+ if (memberGroupList==0)
+ {
+ memberGroupList=new MemberGroupList;
+ }
+ //printf("addMemberGroup: this=%p mg=%p\n",this,mg);
+ memberGroupList->append(mg);
+}
+
+void MemberList::addListReferences(Definition *def)
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)
+ {
+ md->addListReference(def);
+ MemberList *enumFields = md->enumFieldList();
+ if (md->memberType()==MemberType_Enumeration && enumFields)
+ {
+ //printf(" Adding enum values!\n");
+ MemberListIterator vmli(*enumFields);
+ MemberDef *vmd;
+ for ( ; (vmd=vmli.current()) ; ++vmli)
+ {
+ //printf(" adding %s\n",vmd->name().data());
+ vmd->addListReference(def);
+ }
+ }
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(def);
+ }
+ }
+}
+
+void MemberList::findSectionsInDocumentation()
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ md->findSectionsInDocumentation();
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ }
+}
+
+void MemberList::marshal(StorageIntf *s)
+{
+ marshalInt(s,(int)m_listType);
+ marshalInt(s,m_varCnt);
+ marshalInt(s,m_funcCnt);
+ marshalInt(s,m_enumCnt);
+ marshalInt(s,m_enumValCnt);
+ marshalInt(s,m_typeCnt);
+ marshalInt(s,m_protoCnt);
+ marshalInt(s,m_defCnt);
+ marshalInt(s,m_friendCnt);
+ marshalInt(s,m_numDecMembers);
+ marshalInt(s,m_numDocMembers);
+ marshalBool(s,m_inGroup);
+ marshalBool(s,m_inFile);
+ marshalBool(s,m_needsSorting);
+ if (memberGroupList==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,memberGroupList->count());
+ QListIterator<MemberGroup> mgi(*memberGroupList);
+ MemberGroup *mg=0;
+ for (mgi.toFirst();(mg=mgi.current());++mgi)
+ {
+ mg->marshal(s);
+ }
+ }
+}
+
+void MemberList::unmarshal(StorageIntf *s)
+{
+ m_listType = (MemberListType)unmarshalInt(s);
+ m_varCnt = unmarshalInt(s);
+ m_funcCnt = unmarshalInt(s);
+ m_enumCnt = unmarshalInt(s);
+ m_enumValCnt = unmarshalInt(s);
+ m_typeCnt = unmarshalInt(s);
+ m_protoCnt = unmarshalInt(s);
+ m_defCnt = unmarshalInt(s);
+ m_friendCnt = unmarshalInt(s);
+ m_numDecMembers = unmarshalInt(s);
+ m_numDocMembers = unmarshalInt(s);
+ m_inGroup = unmarshalBool(s);
+ m_inFile = unmarshalBool(s);
+ m_needsSorting = unmarshalBool(s);
+ uint i,count = unmarshalUInt(s);
+ if (count==NULL_LIST) // empty list
+ {
+ memberGroupList = 0;
+ }
+ else // add member groups
+ {
+ memberGroupList = new MemberGroupList;
+ for (i=0;i<count;i++)
+ {
+ MemberGroup *mg = new MemberGroup;
+ mg->unmarshal(s);
+ memberGroupList->append(mg);
+ }
+ }
+}
+
+void MemberList::setNeedsSorting(bool b)
+{
+ m_needsSorting = b;
+}
+
+QCString MemberList::listTypeAsString(MemberListType type)
+{
+ switch(type)
+ {
+ case MemberListType_pubMethods: return "pub-methods";
+ case MemberListType_proMethods: return "pro-methods";
+ case MemberListType_pacMethods: return "pac-methods";
+ case MemberListType_priMethods: return "pri-methods";
+ case MemberListType_pubStaticMethods: return "pub-static-methods";
+ case MemberListType_proStaticMethods: return "pro-static-methods";
+ case MemberListType_pacStaticMethods: return "pac-static-methods";
+ case MemberListType_priStaticMethods: return "pri-static-methods";
+ case MemberListType_pubSlots: return "pub-slots";
+ case MemberListType_proSlots: return "pro-slots";
+ case MemberListType_priSlots: return "pri-slots";
+ case MemberListType_pubAttribs: return "pub-attribs";
+ case MemberListType_proAttribs: return "pro-attribs";
+ case MemberListType_pacAttribs: return "pac-attribs";
+ case MemberListType_priAttribs: return "pri-attribs";
+ case MemberListType_pubStaticAttribs: return "pub-static-attribs";
+ case MemberListType_proStaticAttribs: return "pro-static-attribs";
+ case MemberListType_pacStaticAttribs: return "pac-static-attribs";
+ case MemberListType_priStaticAttribs: return "pri-static-attribs";
+ case MemberListType_pubTypes: return "pub-types";
+ case MemberListType_proTypes: return "pro-types";
+ case MemberListType_pacTypes: return "pac-types";
+ case MemberListType_priTypes: return "pri-types";
+ case MemberListType_related: return "related";
+ case MemberListType_signals: return "signals";
+ case MemberListType_friends: return "friends";
+ case MemberListType_dcopMethods: return "dcop-methods";
+ case MemberListType_properties: return "properties";
+ case MemberListType_events: return "events";
+ case MemberListType_interfaces: return "interfaces";
+ case MemberListType_services: return "services";
+ case MemberListType_decDefineMembers: return "define-members";
+ case MemberListType_decProtoMembers: return "proto-members";
+ case MemberListType_decTypedefMembers: return "typedef-members";
+ case MemberListType_decEnumMembers: return "enum-members";
+ case MemberListType_decFuncMembers: return "func-members";
+ case MemberListType_decVarMembers: return "var-members";
+ case MemberListType_decEnumValMembers: return "enumval-members";
+ case MemberListType_decPubSlotMembers: return "pub-slot-members";
+ case MemberListType_decProSlotMembers: return "pro-slot-members";
+ case MemberListType_decPriSlotMembers: return "pri-slot-members";
+ case MemberListType_decSignalMembers: return "signal-members";
+ case MemberListType_decEventMembers: return "event-members";
+ case MemberListType_decFriendMembers: return "friend-members";
+ case MemberListType_decPropMembers: return "prop-members";
+ case MemberListType_enumFields: return "enum-fields";
+ case MemberListType_memberGroup: return "member-group";
+ default: break;
+ }
+ return "";
+}
+
+
+//--------------------------------------------------------------------------
+
+int MemberSDict::compareValues(const MemberDef *c1, const MemberDef *c2) const
+{
+ //printf("MemberSDict::compareValues(%s,%s)\n",c1->name().data(),c2->name().data());
+ int cmp = qstricmp(c1->name(),c2->name());
+ if (cmp)
+ {
+ return cmp;
+ }
+ else
+ {
+ return c1->getDefLine()-c2->getDefLine();
+ }
+}
+
+
diff --git a/src/memberlist.h b/src/memberlist.h
new file mode 100644
index 0000000..607eb01
--- /dev/null
+++ b/src/memberlist.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MEMBERLIST_H
+#define MEMBERLIST_H
+
+#include <qlist.h>
+#include "memberdef.h"
+#include "sortdict.h"
+#include "types.h"
+
+class GroupDef;
+class MemberGroup;
+class MemberGroupList;
+class StorageIntf;
+
+/** A list of MemberDef objects. */
+class MemberList : public QList<MemberDef>
+{
+ public:
+ MemberList();
+ MemberList(MemberListType lt);
+ ~MemberList();
+ MemberListType listType() const { return m_listType; }
+ static QCString listTypeAsString(MemberListType type);
+ bool insert(uint index,const MemberDef *md);
+ void inSort(const MemberDef *md);
+ void append(const MemberDef *md);
+ int varCount() const { ASSERT(m_numDecMembers!=-1); return m_varCnt; }
+ int funcCount() const { ASSERT(m_numDecMembers!=-1); return m_funcCnt; }
+ int enumCount() const { ASSERT(m_numDecMembers!=-1); return m_enumCnt; }
+ int enumValueCount() const { ASSERT(m_numDecMembers!=-1); return m_enumValCnt; }
+ int typedefCount() const { ASSERT(m_numDecMembers!=-1); return m_typeCnt; }
+ int protoCount() const { ASSERT(m_numDecMembers!=-1); return m_protoCnt; }
+ int defineCount() const { ASSERT(m_numDecMembers!=-1); return m_defCnt; }
+ int friendCount() const { ASSERT(m_numDecMembers!=-1); return m_friendCnt; }
+ int numDecMembers() const { ASSERT(m_numDecMembers!=-1); return m_numDecMembers; }
+ int numDocMembers() const { ASSERT(m_numDocMembers!=-1); return m_numDocMembers; }
+ bool needsSorting() const { return m_needsSorting; }
+ void countDecMembers(bool countEnumValues=FALSE,GroupDef *gd=0);
+ void countDocMembers(bool countEnumValues=FALSE);
+ int countInheritableMembers(ClassDef *inheritedFrom) const;
+ void writePlainDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,
+ GroupDef *gd,const DefinitionIntf::DefType compoundType,
+ ClassDef *inheritedFrom,const char *inheritId);
+ void writeDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const char *title,const char *subtitle,const DefinitionIntf::DefType compoundType,
+ bool showEnumValues=FALSE,bool showInline=FALSE,
+ ClassDef *inheritedFrom=0,MemberListType lt=MemberListType_pubMethods);
+ void writeDocumentation(OutputList &ol,const char *scopeName,
+ Definition *container,const char *title,bool showEnumValues=FALSE,bool showInline=FALSE);
+ void writeSimpleDocumentation(OutputList &ol,Definition *container);
+ void writeDocumentationPage(OutputList &ol,
+ const char *scopeName, Definition *container);
+ bool declVisible() const;
+ void addMemberGroup(MemberGroup *mg);
+ void setInGroup(bool inGroup) { m_inGroup=inGroup; }
+ void setInFile(bool inFile) { m_inFile=inFile; }
+ void addListReferences(Definition *def);
+ void findSectionsInDocumentation();
+ void setNeedsSorting(bool b);
+ MemberGroupList *getMemberGroupList() const { return memberGroupList; }
+
+ void marshal(StorageIntf *s);
+ void unmarshal(StorageIntf *s);
+
+ private:
+ int compareValues(const MemberDef *item1,const MemberDef *item2) const;
+ int m_varCnt;
+ int m_funcCnt;
+ int m_enumCnt;
+ int m_enumValCnt;
+ int m_typeCnt;
+ int m_protoCnt;
+ int m_defCnt;
+ int m_friendCnt;
+ int m_numDecMembers; // number of members in the brief part of the memberlist
+ int m_numDocMembers; // number of members in the detailed part of the memberlist
+ MemberGroupList *memberGroupList;
+ bool m_inGroup; // is this list part of a group definition
+ bool m_inFile; // is this list part of a file definition
+ MemberListType m_listType;
+ bool m_needsSorting;
+};
+
+/** An iterator for MemberDef objects in a MemberList. */
+class MemberListIterator : public QListIterator<MemberDef>
+{
+ public:
+ MemberListIterator(const QList<MemberDef> &list);
+ virtual ~MemberListIterator() {}
+};
+
+/** An unsorted dictionary of MemberDef objects. */
+class MemberDict : public QDict<MemberDef>
+{
+ public:
+ MemberDict(int size) : QDict<MemberDef>(size) {}
+ virtual ~MemberDict() {}
+};
+
+/** A sorted dictionary of MemberDef objects. */
+class MemberSDict : public SDict<MemberDef>
+{
+ public:
+ MemberSDict(int size=17) : SDict<MemberDef>(size) {}
+ virtual ~MemberSDict() {}
+ private:
+ int compareValues(const MemberDef *item1,const MemberDef *item2) const;
+};
+
+
+#endif
diff --git a/src/membername.cpp b/src/membername.cpp
new file mode 100644
index 0000000..a2f7296
--- /dev/null
+++ b/src/membername.cpp
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "membername.h"
+#include "classdef.h"
+#include "util.h"
+#include "filedef.h"
+
+MemberName::MemberName(const char *n) : QList<MemberDef>()
+{
+ name=n;
+ setAutoDelete(TRUE);
+}
+
+MemberName::~MemberName()
+{
+}
+
+int MemberName::compareValues(const MemberDef *m1, const MemberDef *m2) const
+{
+ ClassDef *c1=m1->getClassDef();
+ ClassDef *c2=m2->getClassDef();
+ FileDef *f1=m1->getFileDef();
+ FileDef *f2=m2->getFileDef();
+ if (c1 && c2)
+ return qstrcmp(c1->name(),c2->name());
+ else if (f1 && f2)
+ return qstrcmp(f1->name(),f2->name());
+ else
+ return 0;
+}
+
+MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>()
+{
+ name=n;
+ setAutoDelete(TRUE);
+}
+
+int MemberNameInfo::compareValues(const MemberInfo *m1,const MemberInfo *m2) const
+{
+ ClassDef *c1=m1->memberDef->getClassDef();
+ ClassDef *c2=m2->memberDef->getClassDef();
+ FileDef *f1=m1->memberDef->getFileDef();
+ FileDef *f2=m2->memberDef->getFileDef();
+ if (c1 && c2)
+ return qstrcmp(c1->name(),c2->name());
+ else if (f1 && f2)
+ return qstrcmp(f1->name(),f2->name());
+ else
+ return 0;
+}
+MemberNameIterator::MemberNameIterator(const MemberName &mnlist) :
+ QListIterator<MemberDef>(mnlist)
+{
+}
+
+int MemberNameSDict::compareValues(const MemberName *n1,const MemberName *n2) const
+{
+ return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()),
+ n2->memberName()+getPrefixIndex(n2->memberName())
+ );
+}
+
diff --git a/src/membername.h b/src/membername.h
new file mode 100644
index 0000000..7a2fdc5
--- /dev/null
+++ b/src/membername.h
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MEMBERNAME_H
+#define MEMBERNAME_H
+
+#include <qlist.h>
+#include "memberdef.h"
+#include "sortdict.h"
+
+/** Class representing all MemberDef objects with the same name */
+class MemberName : public QList<MemberDef>
+{
+ public:
+ MemberName(const char *name);
+ ~MemberName();
+ const char *memberName() const { return name; }
+
+ private:
+ int compareValues(const MemberDef *item1,const MemberDef *item2) const;
+ QCString name;
+};
+
+/** Iterator for MemberDef objects in a MemberName list. */
+class MemberNameIterator : public QListIterator<MemberDef>
+{
+ public:
+ MemberNameIterator( const MemberName &list);
+};
+
+/** Sorted dictionary of MemberName objects. */
+class MemberNameSDict : public SDict<MemberName>
+{
+ public:
+ MemberNameSDict(int size) : SDict<MemberName>(size) {}
+ ~MemberNameSDict() {}
+
+ private:
+ int compareValues(const MemberName *item1,const MemberName *item2) const;
+};
+
+/** Data associated with a MemberDef in an inheritance relation. */
+struct MemberInfo
+{
+ MemberInfo(MemberDef *md,Protection p,Specifier v,bool inh) :
+ memberDef(md), prot(p), virt(v), inherited(inh), ambigClass(0) {}
+ ~MemberInfo() {}
+ MemberDef *memberDef;
+ Protection prot;
+ Specifier virt;
+ bool inherited;
+ QCString scopePath;
+ QCString ambiguityResolutionScope;
+ ClassDef *ambigClass;
+};
+
+/** Class representing all MemberInfo objects with the same name */
+class MemberNameInfo : public QList<MemberInfo>
+{
+ public:
+ MemberNameInfo(const char *name);
+ ~MemberNameInfo() {}
+ const char *memberName() const { return name; }
+ private:
+ int compareValues(const MemberInfo *item1,const MemberInfo *item2) const;
+ QCString name;
+};
+
+/** Iterator for MemberInfo objects in a MemberNameInfo list. */
+class MemberNameInfoIterator : public QListIterator<MemberInfo>
+{
+ public:
+ MemberNameInfoIterator(const MemberNameInfo &mnii)
+ : QListIterator<MemberInfo>(mnii) {}
+};
+
+/** Sorted dictionary of MemberNameInfo objects. */
+class MemberNameInfoSDict : public SDict<MemberNameInfo>
+{
+ public:
+ MemberNameInfoSDict(int size) : SDict<MemberNameInfo>(size) {}
+ ~MemberNameInfoSDict() {}
+ private:
+ int compareValues(const MemberNameInfo *item1,const MemberNameInfo *item2) const
+ {
+ return qstricmp(item1->memberName(), item2->memberName());
+ }
+};
+
+#endif
diff --git a/src/message.cpp b/src/message.cpp
new file mode 100644
index 0000000..11b4502
--- /dev/null
+++ b/src/message.cpp
@@ -0,0 +1,243 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <qdatetime.h>
+#include "config.h"
+#include "util.h"
+#include "debug.h"
+#include "doxygen.h"
+#include "portable.h"
+#include "filedef.h"
+#include "message.h"
+
+static QCString outputFormat;
+static const char *warning_str = "warning: ";
+static const char *error_str = "error: ";
+//static int warnFormatOrder; // 1 = $file,$line,$text
+// // 2 = $text,$line,$file
+// // 3 = $line,$text,$file
+// // 4 = $file,$text,$line
+// // 5 = $text,$file,$line
+// // 6 = $line,$file,$text
+
+static FILE *warnFile = stderr;
+
+void initWarningFormat()
+{
+// int filePos = Config_getString("WARN_FORMAT").find("$file");
+// int linePos = Config_getString("WARN_FORMAT").find("$line");
+// int textPos = Config_getString("WARN_FORMAT").find("$text");
+//
+// // sort items on position (there are 6 cases)
+// warnFormatOrder = 1;
+// if (filePos>linePos && filePos>textPos)
+// {
+// if (linePos>textPos) // $text,$line,$file
+// {
+// warnFormatOrder = 2;
+// }
+// else // $line,$text,$file
+// {
+// warnFormatOrder = 3;
+// }
+// }
+// else if (filePos<linePos && filePos<textPos)
+// {
+// if (linePos>textPos) // $file,$text,$line
+// {
+// warnFormatOrder = 4;
+// }
+// }
+// else if (filePos<linePos && filePos>textPos) // $text,$file,$line
+// {
+// warnFormatOrder = 5;
+// }
+// else // $line,$file,$text
+// {
+// warnFormatOrder = 6;
+// }
+// outputFormat =
+// substitute(
+// substitute(
+// substitute(
+// Config_getString("WARN_FORMAT"),
+// "$file","%s"
+// ),
+// "$text","%s"
+// ),
+// "$line","%d"
+// )+'\n';
+
+ // replace(QRegExp("\\$file"),"%s").
+ // replace(QRegExp("\\$text"),"%s").
+ // replace(QRegExp("\\$line"),"%d")+
+ // '\n';
+
+ outputFormat = Config_getString("WARN_FORMAT");
+
+ if (!Config_getString("WARN_LOGFILE").isEmpty())
+ {
+ warnFile = portable_fopen(Config_getString("WARN_LOGFILE"),"w");
+ }
+ if (!warnFile) // point it to something valid, because warn() relies on it
+ {
+ warnFile = stderr;
+ }
+}
+
+
+void msg(const char *fmt, ...)
+{
+ if (!Config_getBool("QUIET"))
+ {
+ if (Debug::isFlagSet(Debug::Time))
+ {
+ printf("%.3f sec: ",((double)Doxygen::runningTime.elapsed())/1000.0);
+ }
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+}
+
+static void format_warn(const char *file,int line,const char *text)
+{
+ QCString fileSubst = file==0 ? "<unknown>" : file;
+ QCString lineSubst; lineSubst.setNum(line);
+ QCString textSubst = text;
+ QCString versionSubst;
+ if (file) // get version from file name
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
+ if (fd)
+ {
+ versionSubst = fd->getVersion();
+ }
+ }
+ // substitute markers by actual values
+ QCString msgText =
+ substitute(
+ substitute(
+ substitute(
+ substitute(
+ outputFormat,
+ "$file",fileSubst
+ ),
+ "$text",textSubst
+ ),
+ "$line",lineSubst
+ ),
+ "$version",versionSubst
+ )+'\n';
+
+ // print resulting message
+ fwrite(msgText.data(),1,msgText.length(),warnFile);
+}
+
+static void do_warn(const char *tag, const char *file, int line, const char *prefix, const char *fmt, va_list args)
+{
+ if (!Config_getBool(tag)) return; // warning type disabled
+ char text[40960];
+ int l=0;
+ if (prefix)
+ {
+ strcpy(text,prefix);
+ l=strlen(prefix);
+ }
+ vsnprintf(text+l, 40960-l, fmt, args);
+ text[40960-1]='\0';
+ format_warn(file,line,text);
+}
+
+void warn(const char *file,int line,const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ do_warn("WARNINGS", file, line, warning_str, fmt, args);
+ va_end(args);
+}
+
+void va_warn(const char *file,int line,const char *fmt,va_list args)
+{
+ do_warn("WARNINGS", file, line, warning_str, fmt, args);
+}
+
+void warn_simple(const char *file,int line,const char *text)
+{
+ if (!Config_getBool("WARNINGS")) return; // warning type disabled
+ format_warn(file,line,QCString(warning_str) + text);
+}
+
+void warn_undoc(const char *file,int line,const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ do_warn("WARN_IF_UNDOCUMENTED", file, line, warning_str, fmt, args);
+ va_end(args);
+}
+
+void warn_doc_error(const char *file,int line,const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ do_warn("WARN_IF_DOC_ERROR", file, line, warning_str, fmt, args);
+ va_end(args);
+}
+
+void warn_uncond(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(warnFile, (QCString(warning_str) + fmt).data(), args);
+ va_end(args);
+}
+
+void err(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(warnFile, (QCString(error_str) + fmt).data(), args);
+ va_end(args);
+}
+
+void printlex(int dbg, bool enter, const char *lexName, const char *fileName)
+{
+ const char *enter_txt = "entering";
+ const char *enter_txt_uc = "Entering";
+
+ if (!enter)
+ {
+ enter_txt = "finished";
+ enter_txt_uc = "Finished";
+ }
+
+ if (dbg)
+ {
+ if (fileName)
+ fprintf(stderr,"--%s lexical analyzer: %s (for: %s)\n",enter_txt, lexName, fileName);
+ else
+ fprintf(stderr,"--%s lexical analyzer: %s\n",enter_txt, lexName);
+ }
+ else
+ {
+ if (fileName)
+ Debug::print(Debug::Lex,0,"%s lexical analyzer: %s (for: %s)\n",enter_txt_uc, lexName, fileName);
+ else
+ Debug::print(Debug::Lex,0,"%s lexical analyzer: %s\n",enter_txt_uc, lexName);
+ }
+}
diff --git a/src/message.h b/src/message.h
new file mode 100644
index 0000000..481e8bf
--- /dev/null
+++ b/src/message.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef MESSAGE_H
+#define MESSAGE_H
+
+#include <stdio.h>
+#include <stdarg.h>
+
+extern void msg(const char *fmt, ...);
+extern void warn(const char *file,int line,const char *fmt, ...);
+extern void va_warn(const char *file,int line,const char *fmt, va_list args);
+extern void warn_simple(const char *file,int line,const char *text);
+extern void warn_undoc(const char *file,int line,const char *fmt, ...);
+extern void warn_doc_error(const char *file,int line,const char *fmt, ...);
+extern void warn_uncond(const char *fmt, ...);
+extern void err(const char *fmt, ...);
+void initWarningFormat();
+
+extern void printlex(int dbg, bool enter, const char *lexName, const char *fileName);
+#endif
diff --git a/src/msc.cpp b/src/msc.cpp
new file mode 100644
index 0000000..ebbba0f
--- /dev/null
+++ b/src/msc.cpp
@@ -0,0 +1,224 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "msc.h"
+#include "portable.h"
+#include "config.h"
+#include "message.h"
+#include "docparser.h"
+#include "doxygen.h"
+#include "util.h"
+#include "ftextstream.h"
+
+#include <qdir.h>
+
+static const int maxCmdLine = 40960;
+
+static bool convertMapFile(FTextStream &t,const char *mapName,const QCString relPath,
+ const QCString &context)
+{
+ QFile f(mapName);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("failed to open map file %s for inclusion in the docs!\n"
+ "If you installed Graphviz/dot after a previous failing run, \n"
+ "try deleting the output directory and rerun doxygen.\n",mapName);
+ return FALSE;
+ }
+ const int maxLineLen=1024;
+ char buf[maxLineLen];
+ char url[maxLineLen];
+ char ref[maxLineLen];
+ int x1,y1,x2,y2;
+ while (!f.atEnd())
+ {
+ bool isRef = FALSE;
+ int numBytes = f.readLine(buf,maxLineLen);
+ buf[numBytes-1]='\0';
+ //printf("ReadLine `%s'\n",buf);
+ if (qstrncmp(buf,"rect",4)==0)
+ {
+ // obtain the url and the coordinates in the order used by graphviz-1.5
+ sscanf(buf,"rect %s %d,%d %d,%d",url,&x1,&y1,&x2,&y2);
+
+ if (qstrcmp(url,"\\ref")==0 || qstrcmp(url,"@ref")==0)
+ {
+ isRef = TRUE;
+ sscanf(buf,"rect %s %s %d,%d %d,%d",ref,url,&x1,&y1,&x2,&y2);
+ }
+
+ // sanity checks
+ if (y2<y1) { int temp=y2; y2=y1; y1=temp; }
+ if (x2<x1) { int temp=x2; x2=x1; x1=temp; }
+
+ t << "<area href=\"";
+
+ if ( isRef )
+ {
+ // handle doxygen \ref tag URL reference
+ DocRef *df = new DocRef( (DocNode*) 0, url, context );
+ t << externalRef(relPath,df->ref(),TRUE);
+ if (!df->file().isEmpty()) t << df->file() << Doxygen::htmlFileExtension;
+ if (!df->anchor().isEmpty()) t << "#" << df->anchor();
+ }
+ else
+ {
+ t << url;
+ }
+ t << "\" shape=\"rect\" coords=\""
+ << x1 << "," << y1 << "," << x2 << "," << y2 << "\""
+ << " alt=\"\"/>" << endl;
+ }
+ }
+
+ return TRUE;
+}
+
+void writeMscGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,MscOutputFormat format)
+{
+ QCString absOutFile = outDir;
+ absOutFile+=portable_pathSeparator();
+ absOutFile+=outFile;
+
+ // chdir to the output dir, so dot can find the font file.
+ QCString oldDir = QDir::currentDirPath().utf8();
+ // go to the html output directory (i.e. path)
+ QDir::setCurrent(outDir);
+ //printf("Going to dir %s\n",QDir::currentDirPath().data());
+ QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension();
+ QCString mscArgs;
+ QCString extension;
+ switch (format)
+ {
+ case MSC_BITMAP:
+ mscArgs+="-T png";
+ extension=".png";
+ break;
+ case MSC_EPS:
+ mscArgs+="-T eps";
+ extension=".eps";
+ break;
+ case MSC_SVG:
+ mscArgs+="-T svg";
+ extension=".svg";
+ break;
+ default:
+ goto error; // I am not very fond of goto statements, but when in Rome...
+ }
+ mscArgs+=" -i \"";
+ mscArgs+=inFile;
+
+ mscArgs+="\" -o \"";
+ mscArgs+=outFile;
+ mscArgs+=extension+"\"";
+ int exitCode;
+// printf("*** running: %s %s outDir:%s %s\n",mscExe.data(),mscArgs.data(),outDir,outFile);
+ portable_sysTimerStart();
+ if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0)
+ {
+ portable_sysTimerStop();
+ goto error;
+ }
+ portable_sysTimerStop();
+ if ( (format==MSC_EPS) && (Config_getBool("USE_PDFLATEX")) )
+ {
+ QCString epstopdfArgs(maxCmdLine);
+ epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
+ outFile,outFile);
+ portable_sysTimerStart();
+ if (portable_system("epstopdf",epstopdfArgs)!=0)
+ {
+ err("Problems running epstopdf. Check your TeX installation!\n");
+ }
+ portable_sysTimerStop();
+ }
+
+error:
+ QDir::setCurrent(oldDir);
+}
+
+QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir,
+ const QCString& relPath,const QCString& context)
+{
+ QCString outFile = inFile + ".map";
+
+
+ //printf("*** running:getMscImageMapFromFile \n");
+ // chdir to the output dir, so dot can find the font file.
+ QCString oldDir = QDir::currentDirPath().utf8();
+ // go to the html output directory (i.e. path)
+ QDir::setCurrent(outDir);
+ //printf("Going to dir %s\n",QDir::currentDirPath().data());
+
+ QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension();
+ QCString mscArgs = "-T ismap -i \"";
+ mscArgs+=inFile;
+ QFileInfo fi(inFile);
+ mscArgs+="\" -o \"";
+ mscArgs+=outFile + "\"";
+
+ int exitCode;
+ portable_sysTimerStart();
+ if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0)
+ {
+ portable_sysTimerStop();
+ QDir::setCurrent(oldDir);
+ return "";
+ }
+ portable_sysTimerStop();
+
+ QGString result;
+ FTextStream tmpout(&result);
+ convertMapFile(tmpout, outFile, relPath, context);
+ QDir().remove(outFile);
+
+ QDir::setCurrent(oldDir);
+ return result.data();
+}
+
+void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile,
+ const QCString &outDir,
+ const QCString &relPath,
+ const QCString &baseName,
+ const QCString &context,
+ MscOutputFormat format
+ )
+{
+ QCString mapName = baseName+".map";
+ QCString mapFile = inFile+".map";
+ t << "<img src=\"" << relPath << baseName << ".";
+ switch (format)
+ {
+ case MSC_BITMAP:
+ t << "png";
+ break;
+ case MSC_EPS:
+ t << "eps";
+ break;
+ case MSC_SVG:
+ t << "svg";
+ break;
+ default:
+ t << "unknown";
+ }
+ t << "\" alt=\""
+ << baseName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl;
+ QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context);
+ t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">" << imap << "</map>" << endl;
+}
+
diff --git a/src/msc.h b/src/msc.h
new file mode 100644
index 0000000..5d71ebd
--- /dev/null
+++ b/src/msc.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _MSC_H
+#define _MSC_H
+
+class QCString;
+class FTextStream;
+
+enum MscOutputFormat { MSC_BITMAP , MSC_EPS, MSC_SVG };
+
+void writeMscGraphFromFile(const char *inFile,const char *outDir,
+ const char *outFile,MscOutputFormat format);
+
+QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir,
+ const QCString& relPath,const QCString& context);
+
+void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile,
+ const QCString &outDir, const QCString &relPath,
+ const QCString &baseName, const QCString &context,
+ MscOutputFormat format
+ );
+
+#endif
+
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
new file mode 100644
index 0000000..2aa5728
--- /dev/null
+++ b/src/namespacedef.cpp
@@ -0,0 +1,1135 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "namespacedef.h"
+#include "outputlist.h"
+#include "util.h"
+#include "language.h"
+#include "classdef.h"
+#include "classlist.h"
+#include "memberlist.h"
+#include "doxygen.h"
+#include "message.h"
+#include "docparser.h"
+#include "searchindex.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "membergroup.h"
+#include "config.h"
+
+//------------------------------------------------------------------
+
+NamespaceDef::NamespaceDef(const char *df,int dl,int dc,
+ const char *name,const char *lref,
+ const char *fName, const char*type,
+ bool isPublished) :
+ Definition(df,dl,dc,name)
+ ,m_isPublished(isPublished)
+{
+ if (fName)
+ {
+ fileName = stripExtension(fName);
+ }
+ else
+ {
+ fileName="namespace";
+ fileName+=name;
+ }
+ classSDict = new ClassSDict(17);
+ namespaceSDict = new NamespaceSDict(17);
+ m_innerCompounds = new SDict<Definition>(17);
+ usingDirList = 0;
+ usingDeclList = 0;
+ m_allMembersDict = 0;
+ setReference(lref);
+ memberGroupSDict = new MemberGroupSDict;
+ memberGroupSDict->setAutoDelete(TRUE);
+ visited=FALSE;
+ m_subGrouping=Config_getBool("SUBGROUPING");
+ if (type && !strcmp("module", type))
+ {
+ m_type = MODULE;
+ }
+ else if (type && !strcmp("constants", type))
+ {
+ m_type = CONSTANT_GROUP;
+ }
+ else if (type && !strcmp("library", type))
+ {
+ m_type = LIBRARY;
+ }
+ else
+ {
+ m_type = NAMESPACE;
+ }
+}
+
+NamespaceDef::~NamespaceDef()
+{
+ delete classSDict;
+ delete namespaceSDict;
+ delete m_innerCompounds;
+ delete usingDirList;
+ delete usingDeclList;
+ delete memberGroupSDict;
+ delete m_allMembersDict;
+}
+
+void NamespaceDef::distributeMemberGroupDocumentation()
+{
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->distributeMemberGroupDocumentation();
+ }
+}
+
+void NamespaceDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ml->findSectionsInDocumentation();
+ }
+ }
+}
+
+void NamespaceDef::insertUsedFile(FileDef *fd)
+{
+ if (fd==0) return;
+ if (files.find(fd)==-1)
+ {
+ if (Config_getBool("SORT_MEMBER_DOCS"))
+ files.inSort(fd);
+ else
+ files.append(fd);
+ }
+}
+
+void NamespaceDef::addInnerCompound(Definition *d)
+{
+ m_innerCompounds->append(d->localName(),d);
+ if (d->definitionType()==Definition::TypeNamespace)
+ {
+ insertNamespace((NamespaceDef *)d);
+ }
+ else if (d->definitionType()==Definition::TypeClass)
+ {
+ insertClass((ClassDef *)d);
+ }
+}
+
+void NamespaceDef::insertClass(ClassDef *cd)
+{
+ if (classSDict->find(cd->name())==0)
+ {
+ if (Config_getBool("SORT_BRIEF_DOCS"))
+ classSDict->inSort(cd->name(),cd);
+ else
+ classSDict->append(cd->name(),cd);
+ }
+}
+
+void NamespaceDef::insertNamespace(NamespaceDef *nd)
+{
+ if (namespaceSDict->find(nd->name())==0)
+ {
+ if (Config_getBool("SORT_MEMBER_DOCS"))
+ namespaceSDict->inSort(nd->name(),nd);
+ else
+ namespaceSDict->append(nd->name(),nd);
+ }
+}
+
+
+void NamespaceDef::addMembersToMemberGroup()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_declarationLists)
+ {
+ ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
+ }
+ }
+
+ // add members inside sections to their groups
+ if (memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (mg->allMembersInSameSection() && m_subGrouping)
+ {
+ //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
+ mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+void NamespaceDef::insertMember(MemberDef *md)
+{
+ if (md->isHidden()) return;
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList==0)
+ {
+ allMemberList = new MemberList(MemberListType_allMembersList);
+ m_memberLists.append(allMemberList);
+ }
+ allMemberList->append(md);
+ if (m_allMembersDict==0)
+ {
+ m_allMembersDict = new MemberSDict;
+ }
+ //printf("%s::m_allMembersDict->append(%s)\n",name().data(),md->localName().data());
+ m_allMembersDict->append(md->localName(),md);
+ //::addNamespaceMemberNameToIndex(md);
+ //static bool sortBriefDocs=Config_getBool("SORT_BRIEF_DOCS");
+ switch(md->memberType())
+ {
+ case MemberType_Variable:
+ addMemberToList(MemberListType_decVarMembers,md);
+ addMemberToList(MemberListType_docVarMembers,md);
+ break;
+ case MemberType_Function:
+ addMemberToList(MemberListType_decFuncMembers,md);
+ addMemberToList(MemberListType_docFuncMembers,md);
+ break;
+ case MemberType_Typedef:
+ addMemberToList(MemberListType_decTypedefMembers,md);
+ addMemberToList(MemberListType_docTypedefMembers,md);
+ break;
+ case MemberType_Enumeration:
+ addMemberToList(MemberListType_decEnumMembers,md);
+ addMemberToList(MemberListType_docEnumMembers,md);
+ break;
+ case MemberType_EnumValue:
+ break;
+ case MemberType_Define:
+ addMemberToList(MemberListType_decDefineMembers,md);
+ addMemberToList(MemberListType_docDefineMembers,md);
+ break;
+ default:
+ err("NamespaceDef::insertMembers(): "
+ "member `%s' with class scope `%s' inserted in namespace scope `%s'!\n",
+ md->name().data(),
+ md->getClassDef() ? md->getClassDef()->name().data() : "",
+ name().data());
+ }
+}
+
+void NamespaceDef::computeAnchors()
+{
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList) setAnchors(allMemberList);
+}
+
+bool NamespaceDef::hasDetailedDescription() const
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ return ((!briefDescription().isEmpty() && repeatBrief) ||
+ !documentation().isEmpty());
+}
+
+
+void NamespaceDef::writeDetailedDescription(OutputList &ol,const QCString &title)
+{
+ if (hasDetailedDescription())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,"details");
+ ol.popGeneratorState();
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ ol.startTextBlock();
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
+ //ol.newParagraph(); // FIXME:PARA
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.enable(OutputGenerator::Latex);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ }
+ ol.endTextBlock();
+ }
+}
+
+void NamespaceDef::writeBriefDescription(OutputList &ol)
+{
+ if (hasBriefDescription())
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startParagraph();
+ ol.writeDoc(rootNode,this,0);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+
+ if (hasDetailedDescription())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startTextLink(0,"details");
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ }
+ ol.popGeneratorState();
+ ol.endParagraph();
+ }
+ delete rootNode;
+
+ // FIXME:PARA
+ //ol.pushGeneratorState();
+ //ol.disable(OutputGenerator::RTF);
+ //ol.newParagraph();
+ //ol.popGeneratorState();
+ }
+ ol.writeSynopsis();
+}
+
+void NamespaceDef::startMemberDeclarations(OutputList &ol)
+{
+ ol.startMemberSections();
+}
+
+void NamespaceDef::endMemberDeclarations(OutputList &ol)
+{
+ ol.endMemberSections();
+}
+
+void NamespaceDef::startMemberDocumentation(OutputList &ol)
+{
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.disable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = TRUE;
+ }
+}
+
+void NamespaceDef::endMemberDocumentation(OutputList &ol)
+{
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.enable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = FALSE;
+ }
+}
+
+void NamespaceDef::writeClassDeclarations(OutputList &ol,const QCString &title)
+{
+ if (classSDict) classSDict->writeDeclaration(ol,0,title,TRUE);
+}
+
+void NamespaceDef::writeInlineClasses(OutputList &ol)
+{
+ if (classSDict) classSDict->writeDocumentation(ol,this);
+}
+
+void NamespaceDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title,
+ bool const isConstantGroup)
+{
+ if (namespaceSDict) namespaceSDict->writeDeclaration(ol,title,isConstantGroup,TRUE);
+}
+
+void NamespaceDef::writeMemberGroups(OutputList &ol)
+{
+ /* write user defined member groups */
+ if (memberGroupSDict)
+ {
+ memberGroupSDict->sort();
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if ((!mg->allMembersInSameSection() || !m_subGrouping)
+ && mg->header()!="[NOHEADER]")
+ {
+ mg->writeDeclarations(ol,0,this,0,0);
+ }
+ }
+ }
+}
+
+void NamespaceDef::writeAuthorSection(OutputList &ol)
+{
+ // write Author section (Man only)
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
+ ol.popGeneratorState();
+}
+
+void NamespaceDef::writeSummaryLinks(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace));
+ LayoutDocEntry *lde;
+ bool first=TRUE;
+ SrcLangExt lang = getLanguage();
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if ((lde->kind()==LayoutDocEntry::NamespaceClasses && classSDict && classSDict->declVisible()) ||
+ (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaceSDict && namespaceSDict->declVisible())
+ )
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ QCString label = lde->kind()==LayoutDocEntry::NamespaceClasses ? "nested-classes" : "namespaces";
+ ol.writeSummaryLink(0,label,ls->title(lang),first);
+ first=FALSE;
+ }
+ else if (lde->kind()== LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList * ml = getMemberList(lmd->type);
+ if (ml && ml->declVisible())
+ {
+ ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
+ first=FALSE;
+ }
+ }
+ }
+ if (!first)
+ {
+ ol.writeString(" </div>\n");
+ }
+ ol.popGeneratorState();
+}
+
+void NamespaceDef::addNamespaceAttributes(OutputList &ol)
+{
+ // UNO IDL constant groups may be published
+ if (getLanguage()==SrcLangExt_IDL && isConstantGroup() && m_isPublished)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startLabels();
+ ol.writeLabel("published",false);
+ ol.endLabels();
+ ol.popGeneratorState();
+ }
+}
+
+void NamespaceDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ //static bool outputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+
+ QCString pageTitle = title();
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible,!generateTreeView);
+
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+
+ startTitle(ol,getOutputFileBase(),this);
+ ol.parseText(pageTitle);
+ addGroupListToTitle(ol,this);
+ addNamespaceAttributes(ol);
+ endTitle(ol,getOutputFileBase(),displayName());
+ ol.startContents();
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ }
+
+ bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty();
+ if (generateTagFile)
+ {
+ Doxygen::tagFile << " <compound kind=\"namespace\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
+ QCString idStr = id();
+ if (!idStr.isEmpty())
+ {
+ Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
+ }
+ }
+
+ Doxygen::indexList->addIndexItem(this,0);
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang = getLanguage();
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::NamespaceClasses:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeClassDeclarations(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNamespaceDeclarations(ol,ls->title(lang),false);
+ }
+ break;
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNamespaceDeclarations(ol,ls->title(lang),true);
+ }
+ break;
+ case LayoutDocEntry::MemberGroups:
+ writeMemberGroups(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::NamespaceInlineClasses:
+ writeInlineClasses(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ endMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ case LayoutDocEntry::ClassInheritanceGraph:
+ case LayoutDocEntry::ClassNestedClasses:
+ case LayoutDocEntry::ClassCollaborationGraph:
+ case LayoutDocEntry::ClassAllMembersLink:
+ case LayoutDocEntry::ClassUsedFiles:
+ case LayoutDocEntry::ClassInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileConstantGroups:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Namespace entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ //---------------------------------------- end flexible part -------------------------------
+
+ ol.endContents();
+
+ endFileWithNavPath(this,ol);
+
+ if (generateTagFile)
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList) allMemberList->sort();
+ writeMemberPages(ol);
+ }
+}
+
+void NamespaceDef::writeMemberPages(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->writeDocumentationPage(ol,displayName(),this);
+ }
+ }
+ ol.popGeneratorState();
+}
+
+void NamespaceDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
+{
+ static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
+
+ ol.writeString(" <div class=\"navtab\">\n");
+ ol.writeString(" <table>\n");
+
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList)
+ {
+ MemberListIterator mli(*allMemberList);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->getNamespaceDef()==this && md->isLinkable() && !md->isEnumValue())
+ {
+ ol.writeString(" <tr><td class=\"navtab\">");
+ if (md->isLinkableInProject())
+ {
+ if (md==currentMd) // selected item => highlight
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ ol.writeString("href=\"");
+ if (createSubDirs) ol.writeString("../../");
+ ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
+ ol.writeString("\">");
+ ol.writeString(convertToHtml(md->localName()));
+ ol.writeString("</a>");
+ }
+ ol.writeString("</td></tr>\n");
+ }
+ }
+ }
+
+ ol.writeString(" </table>\n");
+ ol.writeString(" </div>\n");
+}
+
+int NamespaceDef::countMembers()
+{
+ MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
+ if (allMemberList) allMemberList->countDocMembers();
+ return (allMemberList ? allMemberList->numDocMembers() : 0)+classSDict->count();
+}
+
+void NamespaceDef::addUsingDirective(NamespaceDef *nd)
+{
+ if (usingDirList==0)
+ {
+ usingDirList = new NamespaceSDict;
+ }
+ if (usingDirList->find(nd->qualifiedName())==0)
+ {
+ usingDirList->append(nd->qualifiedName(),nd);
+ }
+ //printf("%p: NamespaceDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
+}
+
+NamespaceSDict *NamespaceDef::getUsedNamespaces() const
+{
+ //printf("%p: NamespaceDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
+ return usingDirList;
+}
+
+void NamespaceDef::addUsingDeclaration(Definition *d)
+{
+ if (usingDeclList==0)
+ {
+ usingDeclList = new SDict<Definition>(17);
+ }
+ if (usingDeclList->find(d->qualifiedName())==0)
+ {
+ usingDeclList->append(d->qualifiedName(),d);
+ }
+}
+
+QCString NamespaceDef::getOutputFileBase() const
+{
+ if (isReference())
+ {
+ return fileName;
+ }
+ else
+ {
+ return convertNameToFile(fileName);
+ }
+}
+
+Definition *NamespaceDef::findInnerCompound(const char *n)
+{
+ if (n==0) return 0;
+ Definition *d = m_innerCompounds->find(n);
+ if (d==0)
+ {
+ if (usingDirList)
+ {
+ d = usingDirList->find(n);
+ }
+ if (d==0 && usingDeclList)
+ {
+ d = usingDeclList->find(n);
+ }
+ }
+ return d;
+}
+
+void NamespaceDef::addListReferences()
+{
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ {
+ QList<ListItemInfo> *xrefItems = xrefListItems();
+ addRefItem(xrefItems,
+ qualifiedName(),
+ getLanguage()==SrcLangExt_Fortran ?
+ theTranslator->trModule(TRUE,TRUE) :
+ theTranslator->trNamespace(TRUE,TRUE),
+ getOutputFileBase(),displayName(),
+ 0
+ );
+ }
+ MemberGroupSDict::Iterator mgli(*memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(this);
+ }
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberListType_documentationLists)
+ {
+ ml->addListReferences(this);
+ }
+ }
+}
+
+QCString NamespaceDef::displayName(bool includeScope) const
+{
+ QCString result=includeScope ? name() : localName();
+ SrcLangExt lang = getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ result = substitute(result,"::",sep);
+ }
+ //printf("NamespaceDef::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang);
+ return result;
+}
+
+QCString NamespaceDef::localName() const
+{
+ QCString result=name();
+ int i=result.findRev("::");
+ if (i!=-1)
+ {
+ result=result.mid(i+2);
+ }
+ return result;
+}
+
+void NamespaceDef::combineUsingRelations()
+{
+ if (visited) return; // already done
+ visited=TRUE;
+ if (usingDirList)
+ {
+ NamespaceSDict::Iterator nli(*usingDirList);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ nd->combineUsingRelations();
+ }
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ // add used namespaces of namespace nd to this namespace
+ if (nd->getUsedNamespaces())
+ {
+ NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
+ NamespaceDef *und;
+ for (unli.toFirst();(und=unli.current());++unli)
+ {
+ //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
+ addUsingDirective(und);
+ }
+ }
+ // add used classes of namespace nd to this namespace
+ if (nd->getUsedClasses())
+ {
+ SDict<Definition>::Iterator cli(*nd->getUsedClasses());
+ Definition *ucd;
+ for (cli.toFirst();(ucd=cli.current());++cli)
+ {
+ //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
+ addUsingDeclaration(ucd);
+ }
+ }
+ }
+ }
+}
+
+bool NamespaceSDict::declVisible() const
+{
+ SDict<NamespaceDef>::Iterator ni(*this);
+ NamespaceDef *nd;
+ for (ni.toFirst();(nd=ni.current());++ni)
+ {
+ if (nd->isLinkable())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title,
+ bool const isConstantGroup,bool localName)
+{
+
+
+ if (count()==0) return; // no namespaces in the list
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_VHDL")) return;
+
+
+ SDict<NamespaceDef>::Iterator ni(*this);
+ NamespaceDef *nd;
+ bool found=FALSE;
+ for (ni.toFirst();(nd=ni.current()) && !found;++ni)
+ {
+ if (nd->isLinkable())
+ {
+ SrcLangExt lang = nd->getLanguage();
+ if (SrcLangExt_IDL==lang)
+ {
+ if (isConstantGroup == nd->isConstantGroup())
+ {
+ found=TRUE;
+ break;
+ }
+ }
+ else if (!isConstantGroup) // ensure we only get extra section in IDL
+ {
+ if (nd->isConstantGroup())
+ {
+ err("Internal inconsistency: constant group but not IDL?\n");
+ }
+ found=TRUE;
+ break;
+ }
+ }
+ }
+ if (!found) return; // no linkable namespaces in the list
+
+ // write list of namespaces
+ ol.startMemberHeader("namespaces");
+ //bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ ol.parseText(title);
+ ol.endMemberHeader();
+ ol.startMemberList();
+ for (ni.toFirst();(nd=ni.current());++ni)
+ {
+ if (nd->isLinkable())
+ {
+ SrcLangExt lang = nd->getLanguage();
+ if (lang==SrcLangExt_IDL && (isConstantGroup != nd->isConstantGroup()))
+ continue; // will be output in another pass, see layout_default.xml
+ ol.startMemberDeclaration();
+ ol.startMemberItem(nd->getOutputFileBase(),0);
+ QCString ct = nd->compoundTypeString();
+ ol.docify(ct);
+ ol.docify(" ");
+ ol.insertMemberAlign();
+ QCString name;
+ if (localName)
+ {
+ name = nd->localName();
+ }
+ else
+ {
+ name = nd->displayName();
+ }
+ ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,name);
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && nd->isLinkableInProject())
+ {
+ Doxygen::tagFile << " <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl;
+ }
+ ol.endMemberItem();
+ if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription(nd->getOutputFileBase());
+ ol.generateDoc(nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE,0,TRUE);
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(0,0);
+ }
+ }
+ ol.endMemberList();
+}
+
+MemberList *NamespaceDef::createMemberList(MemberListType lt)
+{
+ m_memberLists.setAutoDelete(TRUE);
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ // not found, create a new member list
+ ml = new MemberList(lt);
+ m_memberLists.append(ml);
+ return ml;
+}
+
+void NamespaceDef::addMemberToList(MemberListType lt,MemberDef *md)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
+ MemberList *ml = createMemberList(lt);
+ ml->setNeedsSorting(
+ ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
+ ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
+ ml->append(md);
+
+#if 0
+ if (ml->needsSorting())
+ ml->inSort(md);
+ else
+ ml->append(md);
+#endif
+
+ if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml);
+}
+
+void NamespaceDef::sortMemberLists()
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
+ }
+ if (classSDict)
+ {
+ classSDict->sort();
+ }
+ if (namespaceSDict)
+ {
+ namespaceSDict->sort();
+ }
+}
+
+
+
+MemberList *NamespaceDef::getMemberList(MemberListType lt) const
+{
+ QListIterator<MemberList> mli(m_memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ return 0;
+}
+
+void NamespaceDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDeclarations(ol,0,this,0,0,title,0,DefinitionIntf::TypeNamespace);
+}
+
+void NamespaceDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title)
+{
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDocumentation(ol,displayName(),this,title);
+}
+
+
+bool NamespaceDef::isLinkableInProject() const
+{
+ int i = name().findRev("::");
+ if (i==-1) i=0; else i+=2;
+ static bool extractAnonNs = Config_getBool("EXTRACT_ANON_NSPACES");
+ if (extractAnonNs && // extract anonymous ns
+ name().mid(i,20)=="anonymous_namespace{" // correct prefix
+ ) // not disabled by config
+ {
+ return TRUE;
+ }
+ return !name().isEmpty() && name().at(i)!='@' && // not anonymous
+ (hasDocumentation() || getLanguage()==SrcLangExt_CSharp) && // documented
+ !isReference() && // not an external reference
+ !isHidden() && // not hidden
+ !isArtificial(); // or artificial
+}
+
+bool NamespaceDef::isLinkable() const
+{
+ return isLinkableInProject() || isReference();
+}
+
+MemberDef * NamespaceDef::getMemberByName(const QCString &n) const
+{
+ MemberDef *md = 0;
+ if (m_allMembersDict && !n.isEmpty())
+ {
+ md = m_allMembersDict->find(n);
+ //printf("%s::m_allMembersDict->find(%s)=%p\n",name().data(),n.data(),md);
+ }
+ return md;
+}
+
+QCString NamespaceDef::title() const
+{
+ SrcLangExt lang = getLanguage();
+ QCString pageTitle;
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
+ {
+ pageTitle = theTranslator->trPackage(displayName());
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ pageTitle = theTranslator->trModuleReference(displayName());
+ }
+ else if (lang==SrcLangExt_IDL)
+ {
+ pageTitle = isConstantGroup()
+ ? theTranslator->trConstantGroupReference(displayName())
+ : theTranslator->trModuleReference(displayName());
+ }
+ else
+ {
+ pageTitle = theTranslator->trNamespaceReference(displayName());
+ }
+ return pageTitle;
+}
+
+QCString NamespaceDef::compoundTypeString() const
+{
+ SrcLangExt lang = getLanguage();
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
+ {
+ return "package";
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ return "module";
+ }
+ else if (lang==SrcLangExt_IDL)
+ {
+ if (isModule())
+ {
+ return "module";
+ }
+ else if (isConstantGroup())
+ {
+ return "constants";
+ }
+ else if (isLibrary())
+ {
+ return "library";
+ }
+ else
+ {
+ err("Internal inconsistency: namespace in IDL not module, library or constant group\n");
+ }
+ }
+ return "";
+}
+
diff --git a/src/namespacedef.h b/src/namespacedef.h
new file mode 100644
index 0000000..ceb3bd7
--- /dev/null
+++ b/src/namespacedef.h
@@ -0,0 +1,187 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef NAMESPACEDEF_H
+#define NAMESPACEDEF_H
+
+#include <qstrlist.h>
+#include <qdict.h>
+#include "sortdict.h"
+#include "definition.h"
+#include "filedef.h"
+
+class MemberList;
+class ClassDef;
+class ClassList;
+class OutputList;
+class ClassSDict;
+class MemberDef;
+class NamespaceList;
+class MemberGroupSDict;
+class NamespaceSDict;
+
+/** A model of a namespace symbol. */
+class NamespaceDef : public Definition
+{
+ public:
+ NamespaceDef(const char *defFileName,int defLine,int defColumn,
+ const char *name,const char *ref=0,
+ const char *refFile=0,const char*type=0,
+ bool isPublished=false);
+ ~NamespaceDef();
+ DefType definitionType() const { return TypeNamespace; }
+ QCString getOutputFileBase() const;
+ QCString anchor() const { return QCString(); }
+ void insertUsedFile(FileDef *fd);
+
+ void writeDocumentation(OutputList &ol);
+ void writeMemberPages(OutputList &ol);
+ void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const;
+
+ void insertClass(ClassDef *cd);
+ void insertNamespace(NamespaceDef *nd);
+ void insertMember(MemberDef *md);
+
+ void computeAnchors();
+ int countMembers();
+ void addUsingDirective(NamespaceDef *nd);
+ NamespaceSDict *getUsedNamespaces() const;
+ void addUsingDeclaration(Definition *def);
+ SDict<Definition> *getUsedClasses() const { return usingDeclList; }
+ void combineUsingRelations();
+ QCString displayName(bool=TRUE) const;
+ QCString localName() const;
+
+ bool isConstantGroup() const { return CONSTANT_GROUP == m_type; }
+ bool isModule() const { return MODULE == m_type; }
+ bool isLibrary() const { return LIBRARY == m_type; }
+
+ bool isLinkableInProject() const;
+ bool isLinkable() const;
+ bool hasDetailedDescription() const;
+ void addMembersToMemberGroup();
+ void distributeMemberGroupDocumentation();
+ void findSectionsInDocumentation();
+ void sortMemberLists();
+
+ virtual Definition *findInnerCompound(const char *name);
+ void addInnerCompound(Definition *d);
+ void addListReferences();
+
+ bool subGrouping() const { return m_subGrouping; }
+
+ MemberList *getMemberList(MemberListType lt) const;
+ const QList<MemberList> &getMemberLists() const { return m_memberLists; }
+ MemberDef *getMemberByName(const QCString &) const;
+
+ /*! Returns the user defined member groups */
+ MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; }
+
+ /*! Returns the classes contained in this namespace */
+ ClassSDict *getClassSDict() const { return classSDict; }
+
+ /*! Returns the namespaces contained in this namespace */
+ NamespaceSDict *getNamespaceSDict() const { return namespaceSDict; }
+
+ QCString title() const;
+ QCString compoundTypeString() const;
+
+ bool visited;
+
+ private:
+ MemberList *createMemberList(MemberListType lt);
+ void addMemberToList(MemberListType lt,MemberDef *md);
+ void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
+ void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
+ void writeDetailedDescription(OutputList &ol,const QCString &title);
+ void writeBriefDescription(OutputList &ol);
+ void startMemberDeclarations(OutputList &ol);
+ void endMemberDeclarations(OutputList &ol);
+ void writeClassDeclarations(OutputList &ol,const QCString &title);
+ void writeInlineClasses(OutputList &ol);
+ void writeNamespaceDeclarations(OutputList &ol,const QCString &title,
+ bool isConstantGroup=false);
+ void writeMemberGroups(OutputList &ol);
+ void writeAuthorSection(OutputList &ol);
+ void startMemberDocumentation(OutputList &ol);
+ void endMemberDocumentation(OutputList &ol);
+ void writeSummaryLinks(OutputList &ol);
+ void addNamespaceAttributes(OutputList &ol);
+
+ QCString fileName;
+ FileList files;
+
+ NamespaceSDict *usingDirList;
+ SDict<Definition> *usingDeclList;
+ SDict<Definition> *m_innerCompounds;
+
+ MemberSDict *m_allMembersDict;
+ QList<MemberList> m_memberLists;
+ MemberGroupSDict *memberGroupSDict;
+ ClassSDict *classSDict;
+ NamespaceSDict *namespaceSDict;
+ bool m_subGrouping;
+ enum { NAMESPACE, MODULE, CONSTANT_GROUP, LIBRARY } m_type;
+ bool m_isPublished;
+};
+
+/** A list of NamespaceDef objects. */
+class NamespaceList : public QList<NamespaceDef>
+{
+ public:
+ ~NamespaceList() {}
+ int compareValues(const NamespaceDef *nd1,const NamespaceDef *nd2) const
+ {
+ return qstricmp(nd1->name(), nd2->name());
+ }
+};
+
+/** An iterator for NamespaceDef objects in a NamespaceList. */
+class NamespaceListIterator : public QListIterator<NamespaceDef>
+{
+ public:
+ NamespaceListIterator(const NamespaceList &l) :
+ QListIterator<NamespaceDef>(l) {}
+};
+
+/** An unsorted dictionary of NamespaceDef objects. */
+class NamespaceDict : public QDict<NamespaceDef>
+{
+ public:
+ NamespaceDict(int size) : QDict<NamespaceDef>(size) {}
+ ~NamespaceDict() {}
+};
+
+/** A sorted dictionary of NamespaceDef objects. */
+class NamespaceSDict : public SDict<NamespaceDef>
+{
+ public:
+ NamespaceSDict(int size=17) : SDict<NamespaceDef>(size) {}
+ ~NamespaceSDict() {}
+ void writeDeclaration(OutputList &ol,const char *title,
+ bool isConstantGroup=false, bool localName=FALSE);
+ bool declVisible() const;
+ private:
+ int compareValues(const NamespaceDef *item1,const NamespaceDef *item2) const
+ {
+ return qstricmp(item1->name(),item2->name());
+ }
+};
+
+
+
+#endif
diff --git a/src/navtree.css b/src/navtree.css
new file mode 100644
index 0000000..a2ae30a
--- /dev/null
+++ b/src/navtree.css
@@ -0,0 +1,143 @@
+#nav-tree .children_ul {
+ margin:0;
+ padding:4px;
+}
+
+#nav-tree ul {
+ list-style:none outside none;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree li {
+ white-space:nowrap;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .plus {
+ margin:0px;
+}
+
+#nav-tree .selected {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+#nav-tree img {
+ margin:0px;
+ padding:0px;
+ border:0px;
+ vertical-align: middle;
+}
+
+#nav-tree a {
+ text-decoration:none;
+ padding:0px;
+ margin:0px;
+ outline:none;
+}
+
+#nav-tree .label {
+ margin:0px;
+ padding:0px;
+ font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+#nav-tree .label a {
+ padding:2px;
+}
+
+#nav-tree .selected a {
+ text-decoration:none;
+ color:#fff;
+}
+
+#nav-tree .children_ul {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .item {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree {
+ padding: 0px 0px;
+ background-color: #FAFAFF;
+ font-size:14px;
+ overflow:auto;
+}
+
+#doc-content {
+ overflow:auto;
+ display:block;
+ padding:0px;
+ margin:0px;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#side-nav {
+ padding:0 6px 0 0;
+ margin: 0px;
+ display:block;
+ position: absolute;
+ left: 0px;
+ width: $width;
+}
+
+.ui-resizable .ui-resizable-handle {
+ display:block;
+}
+
+.ui-resizable-e {
+ background:url("ftv2splitbar.png") repeat scroll right center transparent;
+ cursor:e-resize;
+ height:100%;
+ right:0;
+ top:0;
+ width:6px;
+}
+
+.ui-resizable-handle {
+ display:none;
+ font-size:0.1px;
+ position:absolute;
+ z-index:1;
+}
+
+#nav-tree-contents {
+ margin: 6px 0px 0px 0px;
+}
+
+#nav-tree {
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: ##FA;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#nav-sync {
+ position:absolute;
+ top:5px;
+ right:24px;
+ z-index:0;
+}
+
+#nav-sync img {
+ opacity:0.3;
+}
+
+#nav-sync img:hover {
+ opacity:0.9;
+}
+
+ at media print
+{
+ #nav-tree { display: none; }
+ div.ui-resizable-handle { display: none; position: relative; }
+}
+
diff --git a/src/navtree.js b/src/navtree.js
new file mode 100644
index 0000000..3914be8
--- /dev/null
+++ b/src/navtree.js
@@ -0,0 +1,527 @@
+var navTreeSubIndices = new Array();
+
+function getData(varName)
+{
+ var i = varName.lastIndexOf('/');
+ var n = i>=0 ? varName.substring(i+1) : varName;
+ return eval(n.replace(/\-/g,'_'));
+}
+
+function stripPath(uri)
+{
+ return uri.substring(uri.lastIndexOf('/')+1);
+}
+
+function stripPath2(uri)
+{
+ var i = uri.lastIndexOf('/');
+ var s = uri.substring(i+1);
+ var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
+ return m ? uri.substring(i-6) : s;
+}
+
+function hashValue()
+{
+ return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
+}
+
+function hashUrl()
+{
+ return '#'+hashValue();
+}
+
+function pathName()
+{
+ return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
+}
+
+function localStorageSupported()
+{
+ try {
+ return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
+ }
+ catch(e) {
+ return false;
+ }
+}
+
+
+function storeLink(link)
+{
+ if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
+ window.localStorage.setItem('navpath',link);
+ }
+}
+
+function deleteLink()
+{
+ if (localStorageSupported()) {
+ window.localStorage.setItem('navpath','');
+ }
+}
+
+function cachedLink()
+{
+ if (localStorageSupported()) {
+ return window.localStorage.getItem('navpath');
+ } else {
+ return '';
+ }
+}
+
+function getScript(scriptName,func,show)
+{
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement('script');
+ script.id = scriptName;
+ script.type = 'text/javascript';
+ script.onload = func;
+ script.src = scriptName+'.js';
+ if ($.browser.msie && $.browser.version<=8) {
+ // script.onload does not work with older versions of IE
+ script.onreadystatechange = function() {
+ if (script.readyState=='complete' || script.readyState=='loaded') {
+ func(); if (show) showRoot();
+ }
+ }
+ }
+ head.appendChild(script);
+}
+
+function createIndent(o,domNode,node,level)
+{
+ var level=-1;
+ var n = node;
+ while (n.parentNode) { level++; n=n.parentNode; }
+ if (node.childrenData) {
+ var imgNode = document.createElement("img");
+ imgNode.style.paddingLeft=(16*level).toString()+'px';
+ imgNode.width = 16;
+ imgNode.height = 22;
+ imgNode.border = 0;
+ node.plus_img = imgNode;
+ node.expandToggle = document.createElement("a");
+ node.expandToggle.href = "javascript:void(0)";
+ node.expandToggle.onclick = function() {
+ if (node.expanded) {
+ $(node.getChildrenUL()).slideUp("fast");
+ node.plus_img.src = node.relpath+"ftv2pnode.png";
+ node.expanded = false;
+ } else {
+ expandNode(o, node, false, false);
+ }
+ }
+ node.expandToggle.appendChild(imgNode);
+ domNode.appendChild(node.expandToggle);
+ imgNode.src = node.relpath+"ftv2pnode.png";
+ } else {
+ var span = document.createElement("span");
+ span.style.display = 'inline-block';
+ span.style.width = 16*(level+1)+'px';
+ span.style.height = '22px';
+ span.innerHTML = ' ';
+ domNode.appendChild(span);
+ }
+}
+
+var animationInProgress = false;
+
+function gotoAnchor(anchor,aname,updateLocation)
+{
+ var pos, docContent = $('#doc-content');
+ var ancParent = $(anchor.parent());
+ if (ancParent.hasClass('memItemLeft') ||
+ ancParent.hasClass('fieldname') ||
+ ancParent.hasClass('fieldtype') ||
+ ancParent.is(':header'))
+ {
+ pos = ancParent.position().top;
+ } else if (anchor.position()) {
+ pos = anchor.position().top;
+ }
+ if (pos) {
+ var dist = Math.abs(Math.min(
+ pos-docContent.offset().top,
+ docContent[0].scrollHeight-
+ docContent.height()-docContent.scrollTop()));
+ animationInProgress=true;
+ docContent.animate({
+ scrollTop: pos + docContent.scrollTop() - docContent.offset().top
+ },Math.max(50,Math.min(500,dist)),function(){
+ if (updateLocation) window.location.href=aname;
+ animationInProgress=false;
+ });
+ }
+}
+
+function newNode(o, po, text, link, childrenData, lastNode)
+{
+ var node = new Object();
+ node.children = Array();
+ node.childrenData = childrenData;
+ node.depth = po.depth + 1;
+ node.relpath = po.relpath;
+ node.isLast = lastNode;
+
+ node.li = document.createElement("li");
+ po.getChildrenUL().appendChild(node.li);
+ node.parentNode = po;
+
+ node.itemDiv = document.createElement("div");
+ node.itemDiv.className = "item";
+
+ node.labelSpan = document.createElement("span");
+ node.labelSpan.className = "label";
+
+ createIndent(o,node.itemDiv,node,0);
+ node.itemDiv.appendChild(node.labelSpan);
+ node.li.appendChild(node.itemDiv);
+
+ var a = document.createElement("a");
+ node.labelSpan.appendChild(a);
+ node.label = document.createTextNode(text);
+ node.expanded = false;
+ a.appendChild(node.label);
+ if (link) {
+ var url;
+ if (link.substring(0,1)=='^') {
+ url = link.substring(1);
+ link = url;
+ } else {
+ url = node.relpath+link;
+ }
+ a.className = stripPath(link.replace('#',':'));
+ if (link.indexOf('#')!=-1) {
+ var aname = '#'+link.split('#')[1];
+ var srcPage = stripPath(pathName());
+ var targetPage = stripPath(link.split('#')[0]);
+ a.href = srcPage!=targetPage ? url : "javascript:void(0)";
+ a.onclick = function(){
+ storeLink(link);
+ if (!$(a).parent().parent().hasClass('selected'))
+ {
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ $(a).parent().parent().addClass('selected');
+ $(a).parent().parent().attr('id','selected');
+ }
+ var anchor = $(aname);
+ gotoAnchor(anchor,aname,true);
+ };
+ } else {
+ a.href = url;
+ a.onclick = function() { storeLink(link); }
+ }
+ } else {
+ if (childrenData != null)
+ {
+ a.className = "nolink";
+ a.href = "javascript:void(0)";
+ a.onclick = node.expandToggle.onclick;
+ }
+ }
+
+ node.childrenUL = null;
+ node.getChildrenUL = function() {
+ if (!node.childrenUL) {
+ node.childrenUL = document.createElement("ul");
+ node.childrenUL.className = "children_ul";
+ node.childrenUL.style.display = "none";
+ node.li.appendChild(node.childrenUL);
+ }
+ return node.childrenUL;
+ };
+
+ return node;
+}
+
+function showRoot()
+{
+ var headerHeight = $("#top").height();
+ var footerHeight = $("#nav-path").height();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ (function (){ // retry until we can scroll to the selected item
+ try {
+ var navtree=$('#nav-tree');
+ navtree.scrollTo('#selected',0,{offset:-windowHeight/2});
+ } catch (err) {
+ setTimeout(arguments.callee, 0);
+ }
+ })();
+}
+
+function expandNode(o, node, imm, showRoot)
+{
+ if (node.childrenData && !node.expanded) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ expandNode(o, node, imm, showRoot);
+ }, showRoot);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ } if (imm || ($.browser.msie && $.browser.version>8)) {
+ // somehow slideDown jumps to the start of tree for IE9 :-(
+ $(node.getChildrenUL()).show();
+ } else {
+ $(node.getChildrenUL()).slideDown("fast");
+ }
+ if (node.isLast) {
+ node.plus_img.src = node.relpath+"ftv2mlastnode.png";
+ } else {
+ node.plus_img.src = node.relpath+"ftv2mnode.png";
+ }
+ node.expanded = true;
+ }
+ }
+}
+
+function glowEffect(n,duration)
+{
+ n.addClass('glow').delay(duration).queue(function(next){
+ $(this).removeClass('glow');next();
+ });
+}
+
+function highlightAnchor()
+{
+ var aname = hashUrl();
+ var anchor = $(aname);
+ if (anchor.parent().attr('class')=='memItemLeft'){
+ var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
+ glowEffect(rows.children(),300); // member without details
+ } else if (anchor.parent().attr('class')=='fieldname'){
+ glowEffect(anchor.parent().parent(),1000); // enum value
+ } else if (anchor.parent().attr('class')=='fieldtype'){
+ glowEffect(anchor.parent().parent(),1000); // struct field
+ } else if (anchor.parent().is(":header")) {
+ glowEffect(anchor.parent(),1000); // section header
+ } else {
+ glowEffect(anchor.next(),1000); // normal member
+ }
+ gotoAnchor(anchor,aname,false);
+}
+
+function selectAndHighlight(hash,n)
+{
+ var a;
+ if (hash) {
+ var link=stripPath(pathName())+':'+hash.substring(1);
+ a=$('.item a[class$="'+link+'"]');
+ }
+ if (a && a.length) {
+ a.parent().parent().addClass('selected');
+ a.parent().parent().attr('id','selected');
+ highlightAnchor();
+ } else if (n) {
+ $(n.itemDiv).addClass('selected');
+ $(n.itemDiv).attr('id','selected');
+ }
+ if ($('#nav-tree-contents .item:first').hasClass('selected')) {
+ $('#nav-sync').css('top','30px');
+ } else {
+ $('#nav-sync').css('top','5px');
+ }
+ showRoot();
+}
+
+function showNode(o, node, index, hash)
+{
+ if (node && node.childrenData) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ showNode(o,node,index,hash);
+ },true);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ }
+ $(node.getChildrenUL()).css({'display':'block'});
+ if (node.isLast) {
+ node.plus_img.src = node.relpath+"ftv2mlastnode.png";
+ } else {
+ node.plus_img.src = node.relpath+"ftv2mnode.png";
+ }
+ node.expanded = true;
+ var n = node.children[o.breadcrumbs[index]];
+ if (index+1<o.breadcrumbs.length) {
+ showNode(o,n,index+1,hash);
+ } else {
+ if (typeof(n.childrenData)==='string') {
+ var varName = n.childrenData;
+ getScript(n.relpath+varName,function(){
+ n.childrenData = getData(varName);
+ node.expanded=false;
+ showNode(o,node,index,hash); // retry with child node expanded
+ },true);
+ } else {
+ var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
+ if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
+ expandNode(o, n, true, true);
+ }
+ selectAndHighlight(hash,n);
+ }
+ }
+ }
+ } else {
+ selectAndHighlight(hash);
+ }
+}
+
+function removeToInsertLater(element) {
+ var parentNode = element.parentNode;
+ var nextSibling = element.nextSibling;
+ parentNode.removeChild(element);
+ return function() {
+ if (nextSibling) {
+ parentNode.insertBefore(element, nextSibling);
+ } else {
+ parentNode.appendChild(element);
+ }
+ };
+}
+
+function getNode(o, po)
+{
+ var insertFunction = removeToInsertLater(po.li);
+ po.childrenVisited = true;
+ var l = po.childrenData.length-1;
+ for (var i in po.childrenData) {
+ var nodeData = po.childrenData[i];
+ po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
+ i==l);
+ }
+ insertFunction();
+}
+
+function gotoNode(o,subIndex,root,hash,relpath)
+{
+ var nti = navTreeSubIndices[subIndex][root+hash];
+ o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
+ if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
+ navTo(o,NAVTREE[0][1],"",relpath);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ if (o.breadcrumbs) {
+ o.breadcrumbs.unshift(0); // add 0 for root node
+ showNode(o, o.node, 0, hash);
+ }
+}
+
+function navTo(o,root,hash,relpath)
+{
+ var link = cachedLink();
+ if (link) {
+ var parts = link.split('#');
+ root = parts[0];
+ if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
+ else hash='';
+ }
+ if (hash.match(/^#l\d+$/)) {
+ var anchor=$('a[name='+hash.substring(1)+']');
+ glowEffect(anchor.parent(),1000); // line number
+ hash=''; // strip line number anchors
+ }
+ var url=root+hash;
+ var i=-1;
+ while (NAVTREEINDEX[i+1]<=url) i++;
+ if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath)
+ } else {
+ getScript(relpath+'navtreeindex'+i,function(){
+ navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath);
+ }
+ },true);
+ }
+}
+
+function showSyncOff(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
+}
+
+function showSyncOn(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
+}
+
+function toggleSyncButton(relpath)
+{
+ var navSync = $('#nav-sync');
+ if (navSync.hasClass('sync')) {
+ navSync.removeClass('sync');
+ showSyncOff(navSync,relpath);
+ storeLink(stripPath2(pathName())+hashUrl());
+ } else {
+ navSync.addClass('sync');
+ showSyncOn(navSync,relpath);
+ deleteLink();
+ }
+}
+
+function initNavTree(toroot,relpath)
+{
+ var o = new Object();
+ o.toroot = toroot;
+ o.node = new Object();
+ o.node.li = document.getElementById("nav-tree-contents");
+ o.node.childrenData = NAVTREE;
+ o.node.children = new Array();
+ o.node.childrenUL = document.createElement("ul");
+ o.node.getChildrenUL = function() { return o.node.childrenUL; };
+ o.node.li.appendChild(o.node.childrenUL);
+ o.node.depth = 0;
+ o.node.relpath = relpath;
+ o.node.expanded = false;
+ o.node.isLast = true;
+ o.node.plus_img = document.createElement("img");
+ o.node.plus_img.src = relpath+"ftv2pnode.png";
+ o.node.plus_img.width = 16;
+ o.node.plus_img.height = 22;
+
+ if (localStorageSupported()) {
+ var navSync = $('#nav-sync');
+ if (cachedLink()) {
+ showSyncOff(navSync,relpath);
+ navSync.removeClass('sync');
+ } else {
+ showSyncOn(navSync,relpath);
+ }
+ navSync.click(function(){ toggleSyncButton(relpath); });
+ }
+
+ $(window).load(function(){
+ navTo(o,toroot,hashUrl(),relpath);
+ showRoot();
+ });
+
+ $(window).bind('hashchange', function(){
+ if (window.location.hash && window.location.hash.length>1){
+ var a;
+ if ($(location).attr('hash')){
+ var clslink=stripPath(pathName())+':'+hashValue();
+ a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
+ }
+ if (a==null || !$(a).parent().parent().hasClass('selected')){
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ var link=stripPath2(pathName());
+ navTo(o,link,hashUrl(),relpath);
+ } else if (!animationInProgress) {
+ $('#doc-content').scrollTop(0);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ navTo(o,toroot,hashUrl(),relpath);
+ }
+ })
+}
+
diff --git a/src/objcache.cpp b/src/objcache.cpp
new file mode 100644
index 0000000..a59c67b
--- /dev/null
+++ b/src/objcache.cpp
@@ -0,0 +1,329 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <qglobal.h>
+#include "objcache.h"
+#if !defined(_OS_WIN32_) || defined(__MINGW32__)
+#include <stdint.h>
+#endif
+
+//----------------------------------------------------------------------
+
+ObjCache::ObjCache(unsigned int logSize)
+ : m_head(-1), m_tail(-1), //m_numEntries(0),
+ m_size(1<<logSize), m_count(0), m_freeHashNodes(0), m_freeCacheNodes(0),
+ m_lastHandle(-1)
+{
+ int i;
+ m_cache = new CacheNode[m_size];
+ m_hash = new HashNode[m_size];
+ // add all items to list of free buckets
+ for (i=0;i<m_size-1;i++)
+ {
+ m_hash[i].nextHash = i+1;
+ m_cache[i].next = i+1;
+ }
+ m_misses = 0;
+ m_hits = 0;
+}
+
+ObjCache::~ObjCache()
+{
+ delete[] m_cache;
+ delete[] m_hash;
+}
+
+int ObjCache::add(void *obj,void **victim)
+{
+ *victim=0;
+
+ HashNode *hnode = hashFind(obj);
+ //printf("hnode=%p\n",hnode);
+ if (hnode) // move object to the front of the LRU list, since it is used
+ // most recently
+ {
+ //printf("moveToFront=%d\n",hnode->index);
+ moveToFront(hnode->index);
+ m_hits++;
+ }
+ else // object not in the cache.
+ {
+ void *lruObj=0;
+ if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache
+ {
+ // remove element from free list
+ int index = m_freeCacheNodes;
+ m_freeCacheNodes = m_cache[index].next;
+
+ // add to head of the list
+ if (m_tail==-1)
+ {
+ m_tail = index;
+ }
+ m_cache[index].prev = -1;
+ m_cache[index].next = m_head;
+ if (m_head!=-1)
+ {
+ m_cache[m_head].prev = index;
+ }
+ m_head = index;
+ m_count++;
+ }
+ else // cache full -> replace element in the cache
+ {
+ //printf("Cache full!\n");
+ lruObj = m_cache[m_tail].obj;
+ hashRemove(lruObj);
+ moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head
+ }
+ //printf("numEntries=%d size=%d\n",m_numEntries,m_size);
+ m_cache[m_head].obj = obj;
+ hnode = hashInsert(obj);
+ hnode->index = m_head;
+ *victim = lruObj;
+ m_misses++;
+ }
+ return m_head;
+}
+
+void ObjCache::del(int index)
+{
+ assert(index!=-1);
+ assert(m_cache[index].obj!=0);
+ hashRemove(m_cache[index].obj);
+ moveToFront(index);
+ m_head = m_cache[index].next;
+ if (m_head==-1)
+ m_tail=-1;
+ else
+ m_cache[m_head].prev=-1;
+ m_cache[index].obj=0;
+ m_cache[index].prev=-1;
+ m_cache[index].next = m_freeCacheNodes;
+ m_freeCacheNodes = index;
+ m_count--;
+}
+
+#ifdef CACHE_DEBUG
+#define cache_debug_printf printf
+void ObjCache::printLRU()
+{
+ cache_debug_printf("MRU->LRU: ");
+ int index = m_head;
+ while (index!=-1)
+ {
+ cache_debug_printf("%d=%p ",index,m_cache[index].obj);
+ index = m_cache[index].next;
+ }
+ cache_debug_printf("\n");
+
+ cache_debug_printf("LRU->MRU: ");
+ index = m_tail;
+ while (index!=-1)
+ {
+ cache_debug_printf("%d=%p ",index,m_cache[index].obj);
+ index = m_cache[index].prev;
+ }
+ cache_debug_printf("\n");
+}
+#endif
+
+#ifdef CACHE_STATS
+#define cache_stats_printf printf
+void ObjCache::printStats()
+{
+ cache_stats_printf("ObjCache: hits=%d misses=%d hit ratio=%f\n",m_hits,m_misses,m_hits*100.0/(m_hits+m_misses));
+}
+#endif
+
+void ObjCache::moveToFront(int index)
+{
+ int prev,next;
+ if (m_head!=index)
+ {
+ next = m_cache[index].next;
+ prev = m_cache[index].prev;
+
+ // de-chain node at index
+ m_cache[prev].next = next;
+ if (next!=-1) m_cache[next].prev = prev; else m_tail = prev;
+
+ // add to head
+ m_cache[index].prev = -1;
+ m_cache[index].next = m_head;
+ m_cache[m_head].prev = index;
+ m_head = index;
+ }
+}
+
+unsigned int ObjCache::hash(void *addr)
+{
+ static bool isPtr64 = sizeof(addr)==8;
+ if (isPtr64)
+ {
+ uint64 key = (uint64)addr;
+ // Thomas Wang's 64 bit Mix Function
+ key += ~(key << 32);
+ key ^= (key >> 22);
+ key += ~(key << 13);
+ key ^= (key >> 8);
+ key += (key << 3);
+ key ^= (key >> 15);
+ key += ~(key << 27);
+ key ^= (key >> 31);
+ return (unsigned int)(key & (m_size-1));
+ }
+ else
+ {
+ // Thomas Wang's 32 bit Mix Function
+ uintptr_t key = (uintptr_t)addr;
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+ return (unsigned int)(key & (m_size-1));
+ }
+}
+
+ObjCache::HashNode *ObjCache::hashFind(void *obj)
+{
+ HashNode *node = 0;
+ int index = m_hash[hash(obj)].head;
+ //printf("hashFind: obj=%p index=%d\n",obj,index);
+ while (index!=-1 &&
+ m_hash[index].obj!=obj
+ ) // search for right object in the list
+ {
+ index = m_hash[index].nextHash;
+ }
+ // found the obj at index, so it is in the cache!
+ if (index!=-1)
+ {
+ node = &m_hash[index];
+ }
+ return node;
+}
+
+ObjCache::HashNode *ObjCache::hashInsert(void *obj)
+{
+ int index = hash(obj);
+ //printf("Inserting %p index=%d\n",obj,index);
+
+ // remove element from empty list
+ int newElement = m_freeHashNodes;
+ assert(newElement!=-1);
+ m_freeHashNodes = m_hash[m_freeHashNodes].nextHash;
+
+ if (m_hash[index].head!=-1) // hash collision -> goto end of the list
+ {
+ index = m_hash[index].head;
+ while (m_hash[index].nextHash!=-1)
+ {
+ index = m_hash[index].nextHash;
+ }
+ // add to end of the list
+ m_hash[index].nextHash = newElement;
+ }
+ else // first element in the hash list
+ {
+ m_hash[index].head = newElement;
+ }
+ // add to the end of the list
+ m_hash[newElement].nextHash = -1;
+ m_hash[newElement].obj = obj;
+ return &m_hash[newElement];
+}
+
+void ObjCache::hashRemove(void *obj)
+{
+ int index = hash(obj);
+
+ // find element
+ int curIndex = m_hash[index].head;
+ int prevIndex=-1;
+ while (m_hash[curIndex].obj!=obj)
+ {
+ prevIndex = curIndex;
+ curIndex = m_hash[curIndex].nextHash;
+ }
+
+ if (prevIndex==-1) // remove from start
+ {
+ m_hash[index].head = m_hash[curIndex].nextHash;
+ }
+ else // remove in the middle
+ {
+ m_hash[prevIndex].nextHash = m_hash[curIndex].nextHash;
+ }
+
+ // add curIndex element to empty list
+ m_hash[curIndex].nextHash = m_freeHashNodes;
+ m_hash[curIndex].index = -1;
+ m_hash[curIndex].obj = 0;
+ m_freeHashNodes = curIndex;
+}
+
+#ifdef CACHE_TEST
+int main()
+{
+ int i;
+ struct obj
+ {
+ obj() : handle(-1) {}
+ int handle;
+ };
+ obj *objs = new obj[100];
+ ObjCache c(3);
+ for (i=0;i<32;i++)
+ {
+ int objId=(i%3)+(i>>2)*4;
+ printf("------- use(%d=%p)--------\n",objId,&objs[objId]);
+#ifdef CACHE_DEBUG
+ c.printLRU();
+#endif
+ obj *victim=0;
+ if (objs[objId].handle==-1)
+ {
+ objs[objId].handle = c.add(&objs[objId],(void**)&victim);
+ if (victim) victim->handle=-1;
+ }
+ else
+ {
+ c.use(objs[objId].handle);
+ }
+ printf("i=%d objId=%d using %p victim=%p\n",i,objId,&objs[objId],victim);
+ }
+ for (i=0;i<100;i++)
+ {
+ if (objs[i].handle!=-1)
+ {
+ printf("------ del objId=%d handle=%d ------\n",i,objs[i].handle);
+ c.del(objs[i].handle);
+ objs[i].handle=-1;
+#ifdef CACHE_DEBUG
+ c.printLRU();
+#endif
+ }
+ }
+ c.printStats();
+ return 0;
+}
+#endif
diff --git a/src/objcache.h b/src/objcache.h
new file mode 100644
index 0000000..6e6e95d
--- /dev/null
+++ b/src/objcache.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef OBJCACHE_H
+#define OBJCACHE_H
+
+//#define CACHE_TEST
+//#define CACHE_DEBUG
+#define CACHE_STATS
+
+/** @brief Cache for objects.
+ *
+ * This cache is used to decide which objects should remain in
+ * memory. It uses a least recently used policy (LRU) to decide
+ * which object should make room for a new object when the cache
+ * is full. An object should be added using add(), and then use()
+ * should be called when the object is used.
+ */
+class ObjCache
+{
+ private:
+ struct CacheNode
+ {
+ CacheNode() : next(-1), prev(-1), obj(0) {}
+ int next;
+ int prev;
+ void *obj;
+ };
+ struct HashNode
+ {
+ HashNode() : head(-1), nextHash(-1), index(-1), obj(0) {}
+ int head;
+ int nextHash;
+ int index;
+ void *obj;
+ };
+
+ public:
+ /*! Creates the cache. The number of elements in the cache is 2 to
+ * the power of \a logSize.
+ */
+ ObjCache(unsigned int logSize);
+
+ /*! Deletes the cache and free all internal data-structures used. */
+ ~ObjCache();
+
+ /*! Adds \a obj to the cache. When victim is not null, this object is
+ * removed from the cache to make room for \a obj.
+ * Returns a handle to the object, which can be used by the use()
+ * function, each time the object is used.
+ */
+ int add(void *obj,void **victim);
+
+ /*! Indicates that this object is used. This will move the object
+ * to the front of the internal LRU list to make sure it is removed last.
+ * The parameter \a handle is returned when called add().
+ */
+ void use(int handle)
+ {
+ if (handle==m_lastHandle) return;
+ m_lastHandle = handle;
+ m_hits++;
+ moveToFront(handle);
+ }
+
+ /*! Removes the item identified by \a handle from the cache.
+ * @see add()
+ */
+ void del(int handle);
+
+ /*! Debug function. Prints the LRU list */
+ void printLRU();
+ /*! Print miss/hits statistics */
+ void printStats();
+
+ /*! total size of the cache */
+ int size() const { return m_size; }
+
+ /*! number of elements in the cache */
+ int count() const { return m_count; }
+
+ int hits() const
+ {
+ return m_hits;
+ }
+ int misses() const
+ {
+ return m_misses;
+ }
+
+
+ private:
+ void moveToFront(int index);
+ unsigned int hash(void *addr);
+ HashNode *hashFind(void *obj);
+ HashNode *hashInsert(void *obj);
+ void hashRemove(void *obj);
+
+ CacheNode *m_cache;
+ HashNode *m_hash;
+ int m_head;
+ int m_tail;
+ int m_size;
+ int m_count;
+ int m_freeHashNodes;
+ int m_freeCacheNodes;
+ int m_lastHandle;
+ int m_misses;
+ int m_hits;
+};
+
+#endif // OBJCACHE_H
+
diff --git a/src/outputgen.cpp b/src/outputgen.cpp
new file mode 100644
index 0000000..ee9bc48
--- /dev/null
+++ b/src/outputgen.cpp
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qfile.h>
+
+#include "outputgen.h"
+#include "message.h"
+#include "portable.h"
+
+OutputGenerator::OutputGenerator()
+{
+ //printf("OutputGenerator::OutputGenerator()\n");
+ file=0;
+ active=TRUE;
+ genStack = new QStack<bool>;
+ genStack->setAutoDelete(TRUE);
+}
+
+OutputGenerator::~OutputGenerator()
+{
+ //printf("OutputGenerator::~OutputGenerator()\n");
+ delete file;
+ delete genStack;
+}
+
+void OutputGenerator::startPlainFile(const char *name)
+{
+ //printf("startPlainFile(%s)\n",name);
+ fileName=dir+"/"+name;
+ file = new QFile(fileName);
+ if (!file)
+ {
+ err("Could not create file object for %s\n",fileName.data());
+ exit(1);
+ }
+ if (!file->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ exit(1);
+ }
+ t.setDevice(file);
+}
+
+void OutputGenerator::endPlainFile()
+{
+ t.unsetDevice();
+ delete file;
+ file=0;
+ fileName.resize(0);
+}
+
+void OutputGenerator::pushGeneratorState()
+{
+ genStack->push(new bool(isEnabled()));
+ //printf("%p:pushGeneratorState(%d) enabled=%d\n",this,genStack->count(),isEnabled());
+}
+
+void OutputGenerator::popGeneratorState()
+{
+ //printf("%p:popGeneratorState(%d) enabled=%d\n",this,genStack->count(),isEnabled());
+ bool *lb = genStack->pop();
+ ASSERT(lb!=0);
+ if (lb==0) return; // for some robustness against superfluous \endhtmlonly commands.
+ if (*lb) enable(); else disable();
+ delete lb;
+}
+
diff --git a/src/outputgen.h b/src/outputgen.h
new file mode 100644
index 0000000..aaf1ba7
--- /dev/null
+++ b/src/outputgen.h
@@ -0,0 +1,557 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef OUTPUTGEN_H
+#define OUTPUTGEN_H
+
+#include <qstack.h>
+
+#include "index.h"
+#include "section.h"
+#include "ftextstream.h"
+
+class ClassDiagram;
+class DotClassGraph;
+class DotInclDepGraph;
+class DotCallGraph;
+class DotDirDeps;
+class DotGfxHierarchyTable;
+class DotGroupCollaboration;
+class DocNode;
+class MemberDef;
+class GroupDef;
+class Definition;
+class QFile;
+
+struct DocLinkInfo
+{
+ QCString name;
+ QCString ref;
+ QCString url;
+ QCString anchor;
+};
+
+struct SourceLinkInfo
+{
+ QCString file;
+ int line;
+ QCString ref;
+ QCString url;
+ QCString anchor;
+};
+
+/** Output interface for code parser.
+ */
+class CodeOutputInterface
+{
+ public:
+ virtual ~CodeOutputInterface() {}
+
+ /*! Writes an code fragment to the output. This function should keep
+ * spaces visible, should break lines at a newline and should convert
+ * tabs to the right number of spaces.
+ */
+ virtual void codify(const char *s) = 0;
+
+ /*! Writes a link to an object in a code fragment.
+ * \param ref If this is non-zero, the object is to be found in
+ * an external documentation file.
+ * \param file The file in which the object is located.
+ * \param anchor The anchor uniquely identifying the object within
+ * the file.
+ * \param name The text to display as a placeholder for the link.
+ * \param tooltip The tooltip to display when the mouse is on the link.
+ */
+ virtual void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip) = 0;
+
+ /*! Writes the line number of a source listing
+ * \param ref External reference (when imported from a tag file)
+ * \param file The file part of the URL pointing to the docs.
+ * \param anchor The anchor part of the URL pointing to the docs.
+ * \param lineNumber The line number to write
+ */
+ virtual void writeLineNumber(const char *ref,const char *file,
+ const char *anchor,int lineNumber) = 0;
+
+ /*! Writes a tool tip definition
+ * \param id unique identifier for the tooltip
+ * \param docInfo Info about the symbol's documentation.
+ * \param decl full declaration of the symbol (for functions)
+ * \param desc brief description for the symbol
+ * \param defInfo Info about the symbol's definition in the source code
+ * \param declInfo Info about the symbol's declaration in the source code
+ */
+ virtual void writeTooltip(const char *id,
+ const DocLinkInfo &docInfo,
+ const char *decl,
+ const char *desc,
+ const SourceLinkInfo &defInfo,
+ const SourceLinkInfo &declInfo
+ ) = 0;
+
+ virtual void startCodeLine(bool hasLineNumbers) = 0;
+
+ /*! Ends a line of code started with startCodeLine() */
+ virtual void endCodeLine() = 0;
+
+ /*! Starts a block with a certain meaning. Used for syntax highlighting,
+ * which elements of the same type are rendered using the same 'font class'.
+ * \param clsName The category name.
+ */
+ virtual void startFontClass(const char *clsName) = 0;
+
+ /*! Ends a block started with startFontClass() */
+ virtual void endFontClass() = 0;
+
+ /*! Write an anchor to a source listing.
+ * \param name The name of the anchor.
+ */
+ virtual void writeCodeAnchor(const char *name) = 0;
+
+ virtual void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) = 0;
+ virtual void addWord(const char *word,bool hiPriority) = 0;
+};
+
+/** Base Interface used for generating output outside of the
+ * comment blocks.
+ *
+ * This abstract class is used by output generation functions
+ * to generate the output for a specific format,
+ * or a list of formats (see OutputList). This interface
+ * contains functions that generate fragments of the output.
+ */
+class BaseOutputDocInterface : public CodeOutputInterface
+{
+ public:
+ virtual ~BaseOutputDocInterface() {}
+ enum ParamListTypes { Param, RetVal, Exception };
+ enum SectionTypes { /*See, Return, Author, Version,
+ Since, Date, Bug, Note,
+ Warning, Par, Deprecated, Pre,
+ Post, Invar, Remark, Attention,
+ Todo, Test, RCS, */ EnumValues,
+ Examples
+ };
+
+ virtual bool parseText(const QCString &s) { return s.isEmpty(); }
+
+ /*! Start of a bullet list: e.g. \c \<ul\> in html. startItemListItem() is
+ * Used for the bullet items.
+ */
+ virtual void startItemList() = 0;
+
+ /*! Writes a list item for a bullet or enumerated
+ * list: e.g. \c \<li\> in html
+ */
+ virtual void startItemListItem() = 0;
+
+ /*! Writes a list item for a bullet or enumerated
+ * list: e.g. \c \</li\> in html
+ */
+ virtual void endItemListItem() = 0;
+
+ /*! Ends a bullet list: e.g. \c \</ul\> in html */
+ virtual void endItemList() = 0;
+
+ /*! Writes an ASCII string to the output. Converts characters that have
+ * A special meaning, like \c & in html.
+ */
+ virtual void docify(const char *s) = 0;
+
+ /*! Writes a single ASCII character to the output. Converts characters
+ * that have a special meaning.
+ */
+ virtual void writeChar(char c) = 0;
+
+ /*! Writes an ASCII string to the output, \e without converting
+ * special characters.
+ */
+ virtual void writeString(const char *text) = 0;
+
+ /*! Starts a new paragraph */
+ //virtual void newParagraph() = 0;
+
+ /*! Starts a new paragraph */
+ virtual void startParagraph() = 0;
+ /*! Ends a paragraph */
+ virtual void endParagraph() = 0;
+
+ /*! Writes a link to an object in the documentation.
+ * \param ref If this is non-zero, the object is to be found in
+ * an external documentation file.
+ * \param file The file in which the object is located.
+ * \param anchor The anchor uniquely identifying the object within
+ * the file.
+ * \param name The text to display as a placeholder for the link.
+ */
+ virtual void writeObjectLink(const char *ref,const char *file,
+ const char *anchor, const char *name) = 0;
+
+
+ /*! Starts a (link to an) URL found in the documentation.
+ * \param url The URL to link to.
+ */
+ virtual void startHtmlLink(const char *url) = 0;
+
+ /*! Ends a link started by startHtmlLink().
+ */
+ virtual void endHtmlLink() = 0;
+
+
+ /*! Changes the text font to bold face. The bold section ends with
+ * endBold()
+ */
+ virtual void startBold() = 0;
+
+ /*! End a section of text displayed in bold face. */
+ virtual void endBold() = 0;
+
+ /*! Changes the text font to fixed size. The section ends with
+ * endTypewriter()
+ */
+ virtual void startTypewriter() = 0;
+
+ /*! End a section of text displayed in typewriter style. */
+ virtual void endTypewriter() = 0;
+
+ /*! Changes the text font to italic. The italic section ends with
+ * endEmphasis()
+ */
+ virtual void startEmphasis() = 0;
+
+ /*! Ends a section of text displayed in italic. */
+ virtual void endEmphasis() = 0;
+
+ /*! Starts a source code fragment. The fragment will be
+ * fed to the code parser (see code.h) for syntax highlighting
+ * and cross-referencing. The fragment ends by a call to
+ * endCodeFragment()
+ */
+ virtual void startCodeFragment() = 0;
+
+ /*! Ends a source code fragment
+ */
+ virtual void endCodeFragment() = 0;
+
+
+
+
+ /*! Writes a horizontal ruler to the output */
+ virtual void writeRuler() = 0;
+
+ /*! Starts a description list: e.g. \c \<dl\> in HTML
+ * Items are surrounded by startDescItem() and endDescItem()
+ */
+ virtual void startDescription() = 0;
+
+ /*! Ends a description list: e.g. \c \</dl\> in HTML */
+ virtual void endDescription() = 0;
+
+ /*! Starts an item of a description list: e.g. \c \<dt\> in HTML. */
+ virtual void startDescItem() = 0;
+
+ virtual void startDescForItem() = 0;
+ virtual void endDescForItem() = 0;
+
+ /*! Ends an item of a description list and starts the
+ * description itself: e.g. \c \</dt\> in HTML.
+ */
+ virtual void endDescItem() = 0;
+
+ virtual void startCenter() = 0;
+ virtual void endCenter() = 0;
+ virtual void startSmall() = 0;
+ virtual void endSmall() = 0;
+
+ virtual void startSimpleSect(SectionTypes t,const char *file,
+ const char *anchor,const char *title) = 0;
+ virtual void endSimpleSect() = 0;
+ virtual void startParamList(ParamListTypes t,const char *title) = 0;
+ virtual void endParamList() = 0;
+
+ //virtual void writeDescItem() = 0;
+ virtual void startTitle() = 0;
+ virtual void endTitle() = 0;
+
+ virtual void writeAnchor(const char *fileName,const char *name) = 0;
+ virtual void startSection(const char *,const char *,SectionInfo::SectionType) = 0;
+ virtual void endSection(const char *,SectionInfo::SectionType) = 0;
+
+ virtual void lineBreak(const char *style) = 0;
+ virtual void addIndexItem(const char *s1,const char *s2) = 0;
+
+ virtual void writeNonBreakableSpace(int) = 0;
+ virtual void startDescTable(const char *title) = 0;
+ virtual void endDescTable() = 0;
+ virtual void startDescTableTitle() = 0;
+ virtual void endDescTableTitle() = 0;
+ virtual void startDescTableData() = 0;
+ virtual void endDescTableData() = 0;
+ virtual void startTextLink(const char *file,const char *anchor) = 0;
+ virtual void endTextLink() = 0;
+ virtual void startPageRef() = 0;
+ virtual void endPageRef(const char *,const char *) = 0;
+ virtual void startSubsection() = 0;
+ virtual void endSubsection() = 0;
+ virtual void startSubsubsection() = 0;
+ virtual void endSubsubsection() = 0;
+};
+
+/** Abstract output generator.
+ *
+ * Subclass this class to add support for a new output format
+ */
+class OutputGenerator : public BaseOutputDocInterface
+{
+ public:
+ enum OutputType { Html, Latex, Man, RTF, XML, DEF, Perl };
+
+ OutputGenerator();
+ virtual ~OutputGenerator();
+
+ ///////////////////////////////////////////////////////////////
+ // generic generator methods
+ ///////////////////////////////////////////////////////////////
+ virtual void enable() = 0;
+ virtual void disable() = 0;
+ virtual void enableIf(OutputType o) = 0;
+ virtual void disableIf(OutputType o) = 0;
+ virtual void disableIfNot(OutputType o) = 0;
+ virtual bool isEnabled(OutputType o) = 0;
+ virtual OutputGenerator *get(OutputType o) = 0;
+ void startPlainFile(const char *name);
+ void endPlainFile();
+ //QCString getContents() const;
+ bool isEnabled() const { return active; }
+ void pushGeneratorState();
+ void popGeneratorState();
+ //void setEncoding(const QCString &enc) { encoding = enc; }
+ //virtual void postProcess(QByteArray &) { }
+
+ virtual void writeDoc(DocNode *,Definition *ctx,MemberDef *md) = 0;
+
+ ///////////////////////////////////////////////////////////////
+ // structural output interface
+ ///////////////////////////////////////////////////////////////
+ virtual void startFile(const char *name,const char *manName,
+ const char *title) = 0;
+ virtual void writeSearchInfo() = 0;
+ virtual void writeFooter(const char *navPath) = 0;
+ virtual void endFile() = 0;
+ virtual void startIndexSection(IndexSections) = 0;
+ virtual void endIndexSection(IndexSections) = 0;
+ virtual void writePageLink(const char *,bool) = 0;
+ virtual void startProjectNumber() = 0;
+ virtual void endProjectNumber() = 0;
+ virtual void writeStyleInfo(int part) = 0;
+ virtual void startTitleHead(const char *) = 0;
+ virtual void endTitleHead(const char *fileName,const char *name) = 0;
+ virtual void startIndexListItem() = 0;
+ virtual void endIndexListItem() = 0;
+ virtual void startIndexList() = 0;
+ virtual void endIndexList() = 0;
+ virtual void startIndexKey() = 0;
+ virtual void endIndexKey() = 0;
+ virtual void startIndexValue(bool) = 0;
+ virtual void endIndexValue(const char *,bool) = 0;
+ virtual void startIndexItem(const char *ref,const char *file) = 0;
+ virtual void endIndexItem(const char *ref,const char *file) = 0;
+ virtual void startGroupHeader(int) = 0;
+ virtual void endGroupHeader(int) = 0;
+ virtual void startMemberSections() = 0;
+ virtual void endMemberSections() = 0;
+ virtual void startHeaderSection() = 0;
+ virtual void endHeaderSection() = 0;
+ virtual void startMemberHeader(const char *anchor) = 0;
+ virtual void endMemberHeader() = 0;
+ virtual void startMemberSubtitle() = 0;
+ virtual void endMemberSubtitle() = 0;
+ virtual void startMemberDocList() = 0;
+ virtual void endMemberDocList() = 0;
+ virtual void startMemberList() = 0;
+ virtual void endMemberList() = 0;
+ virtual void startInlineHeader() = 0;
+ virtual void endInlineHeader() = 0;
+ virtual void startAnonTypeScope(int) = 0;
+ virtual void endAnonTypeScope(int) = 0;
+ virtual void startMemberItem(const char *,int,const char *) = 0;
+ virtual void endMemberItem() = 0;
+ virtual void startMemberTemplateParams() = 0;
+ virtual void endMemberTemplateParams(const char *,const char *) = 0;
+ virtual void startMemberGroupHeader(bool) = 0;
+ virtual void endMemberGroupHeader() = 0;
+ virtual void startMemberGroupDocs() = 0;
+ virtual void endMemberGroupDocs() = 0;
+ virtual void startMemberGroup() = 0;
+ virtual void endMemberGroup(bool) = 0;
+ virtual void insertMemberAlign(bool) = 0;
+ virtual void startMemberDoc(const char *,const char *,
+ const char *,const char *,bool) = 0;
+ virtual void endMemberDoc(bool) = 0;
+ virtual void startDoxyAnchor(const char *fName,const char *manName,
+ const char *anchor,const char *name,
+ const char *args) = 0;
+ virtual void endDoxyAnchor(const char *fileName,const char *anchor) = 0;
+ virtual void writeLatexSpacing() = 0;
+ virtual void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name) = 0;
+ virtual void writeEndAnnoItem(const char *name) = 0;
+ virtual void startMemberDescription(const char *anchor,const char *inheritId) = 0;
+ virtual void endMemberDescription() = 0;
+ virtual void startMemberDeclaration() = 0;
+ virtual void endMemberDeclaration(const char *anchor,const char *inheritId) = 0;
+ virtual void writeInheritedSectionTitle(const char *id,const char *ref,
+ const char *file,const char *anchor,
+ const char *title,const char *name) = 0;
+ virtual void startIndent() = 0;
+ virtual void endIndent() = 0;
+ virtual void writeSynopsis() = 0;
+ virtual void startClassDiagram() = 0;
+ virtual void endClassDiagram(const ClassDiagram &,const char *,const char *) = 0;
+ virtual void startDotGraph() = 0;
+ virtual void endDotGraph(const DotClassGraph &g) = 0;
+ virtual void startInclDepGraph() = 0;
+ virtual void endInclDepGraph(const DotInclDepGraph &g) = 0;
+ virtual void startGroupCollaboration() = 0;
+ virtual void endGroupCollaboration(const DotGroupCollaboration &g) = 0;
+ virtual void startCallGraph() = 0;
+ virtual void endCallGraph(const DotCallGraph &g) = 0;
+ virtual void startDirDepGraph() = 0;
+ virtual void endDirDepGraph(const DotDirDeps &g) = 0;
+ virtual void writeGraphicalHierarchy(const DotGfxHierarchyTable &g) = 0;
+ virtual void startQuickIndices() = 0;
+ virtual void endQuickIndices() = 0;
+ virtual void writeSplitBar(const char *) = 0;
+ virtual void writeNavigationPath(const char *) = 0;
+ virtual void writeLogo() = 0;
+ virtual void writeQuickLinks(bool compact,HighlightedItem hli,const char *file) = 0;
+ virtual void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first) = 0;
+ virtual void startContents() = 0;
+ virtual void endContents() = 0;
+ virtual void startTextBlock(bool) = 0;
+ virtual void endTextBlock(bool) = 0;
+ virtual void lastIndexPage() = 0;
+ virtual void startMemberDocPrefixItem() = 0;
+ virtual void endMemberDocPrefixItem() = 0;
+ virtual void startMemberDocName(bool) = 0;
+ virtual void endMemberDocName() = 0;
+ virtual void startParameterType(bool,const char *key) = 0;
+ virtual void endParameterType() = 0;
+ virtual void startParameterName(bool) = 0;
+ virtual void endParameterName(bool,bool,bool) = 0;
+ virtual void startParameterList(bool) = 0;
+ virtual void endParameterList() = 0;
+ virtual void exceptionEntry(const char*,bool) = 0;
+
+ virtual void startConstraintList(const char *) = 0;
+ virtual void startConstraintParam() = 0;
+ virtual void endConstraintParam() = 0;
+ virtual void startConstraintType() = 0;
+ virtual void endConstraintType() = 0;
+ virtual void startConstraintDocs() = 0;
+ virtual void endConstraintDocs() = 0;
+ virtual void endConstraintList() = 0;
+
+ virtual void startMemberDocSimple() = 0;
+ virtual void endMemberDocSimple() = 0;
+ virtual void startInlineMemberType() = 0;
+ virtual void endInlineMemberType() = 0;
+ virtual void startInlineMemberName() = 0;
+ virtual void endInlineMemberName() = 0;
+ virtual void startInlineMemberDoc() = 0;
+ virtual void endInlineMemberDoc() = 0;
+
+
+ virtual void startLabels() = 0;
+ virtual void writeLabel(const char *,bool) = 0;
+ virtual void endLabels() = 0;
+
+ protected:
+ FTextStream t;
+ QFile *file;
+ QCString fileName;
+ QCString dir;
+ bool active;
+ QStack<bool> *genStack;
+
+ private:
+ OutputGenerator(const OutputGenerator &o);
+ OutputGenerator &operator=(const OutputGenerator &o);
+};
+
+/** Interface used for generating documentation.
+ *
+ * This abstract class is used by several functions
+ * to generate the output for a specific format.
+ * This interface contains some state saving and changing
+ * functions for dealing with format specific output.
+ */
+class OutputDocInterface : public BaseOutputDocInterface
+{
+ public:
+ virtual ~OutputDocInterface() {}
+
+ /*! Create a new output generator. This can later by appended
+ * to the current one using append().
+ */
+ //virtual OutputDocInterface *clone() = 0;
+
+ /*! Disables all output formats except format \a o
+ * (useful for OutputList only)
+ */
+ virtual void disableAllBut(OutputGenerator::OutputType o) = 0;
+
+ /*! Enables all output formats as far as they have been enabled in
+ * the config file. (useful for OutputList only)
+ */
+ virtual void enableAll() = 0;
+
+ /*! Disables all output formats (useful for OutputList only) */
+ virtual void disableAll()= 0;
+
+ /*! Disables a specific output format (useful for OutputList only) */
+ virtual void disable(OutputGenerator::OutputType o) = 0;
+
+ /*! Enables a specific output format (useful for OutputList only) */
+ virtual void enable(OutputGenerator::OutputType o) = 0;
+
+ /*! Check whether a specific output format is currently enabled
+ * (useful for OutputList only)
+ */
+ virtual bool isEnabled(OutputGenerator::OutputType o) = 0;
+
+ /*! Appends the output generated by generator \a g to this
+ * generator.
+ */
+ //virtual void append(const OutputDocInterface *g) = 0;
+
+ /*! Pushes the state of the current generator (or list of
+ * generators) on a stack.
+ */
+ virtual void pushGeneratorState() = 0;
+
+ /*! Pops the state of the current generator (or list of
+ * generators) on a stack. Should be preceded by a call
+ * the pushGeneratorState().
+ */
+ virtual void popGeneratorState() = 0;
+};
+
+
+#endif
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
new file mode 100644
index 0000000..754ee7c
--- /dev/null
+++ b/src/outputlist.cpp
@@ -0,0 +1,358 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*! \file
+ * This class represents a list of output generators that work in "parallel".
+ * The class only knows about the abstract base class OutputGenerators.
+ * All output is produced by calling a method of this class, which forwards
+ * the call to all output generators.
+ */
+
+#include "outputlist.h"
+#include "outputgen.h"
+#include "config.h"
+#include "message.h"
+#include "definition.h"
+#include "docparser.h"
+#include "vhdldocgen.h"
+
+OutputList::OutputList(bool)
+{
+ //printf("OutputList::OutputList()\n");
+ m_outputs.setAutoDelete(TRUE);
+}
+
+OutputList::~OutputList()
+{
+ //printf("OutputList::~OutputList()\n");
+}
+
+void OutputList::add(const OutputGenerator *og)
+{
+ if (og) m_outputs.append(og);
+}
+
+void OutputList::disableAllBut(OutputGenerator::OutputType o)
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->disableIfNot(o);
+ }
+}
+
+void OutputList::enableAll()
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->enable();
+ }
+}
+
+void OutputList::disableAll()
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->disable();
+ }
+}
+
+void OutputList::disable(OutputGenerator::OutputType o)
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->disableIf(o);
+ }
+}
+
+void OutputList::enable(OutputGenerator::OutputType o)
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->enableIf(o);
+ }
+}
+
+bool OutputList::isEnabled(OutputGenerator::OutputType o)
+{
+ bool result=FALSE;
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ result=result || og->isEnabled(o);
+ }
+ return result;
+}
+
+void OutputList::pushGeneratorState()
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->pushGeneratorState();
+ }
+}
+
+void OutputList::popGeneratorState()
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ og->popGeneratorState();
+ }
+}
+
+bool OutputList::generateDoc(const char *fileName,int startLine,
+ Definition *ctx,MemberDef * md,
+ const QCString &docStr,bool indexWords,
+ bool isExample,const char *exampleName,
+ bool singleLine,bool linkFromIndex)
+{
+ int count=0;
+ if (docStr.isEmpty()) return TRUE;
+
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ if (og->isEnabled()) count++;
+ }
+ if (count==0) return TRUE; // no output formats enabled.
+
+ DocRoot *root=0;
+ root = validatingParseDoc(fileName,startLine,
+ ctx,md,docStr,indexWords,isExample,exampleName,
+ singleLine,linkFromIndex);
+
+ writeDoc(root,ctx,md);
+
+ bool isEmpty = root->isEmpty();
+
+ delete root;
+
+ return isEmpty;
+}
+
+void OutputList::writeDoc(DocRoot *root,Definition *ctx,MemberDef *md)
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ //printf("og->printDoc(extension=%s)\n",
+ // ctx?ctx->getDefFileExtension().data():"<null>");
+ if (og->isEnabled()) og->writeDoc(root,ctx,md);
+ }
+ VhdlDocGen::setFlowMember(0);
+}
+
+bool OutputList::parseText(const QCString &textStr)
+{
+ int count=0;
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ if (og->isEnabled()) count++;
+ }
+ if (count==0) return TRUE; // no output formats enabled.
+
+ DocText *root = validatingParseText(textStr);
+
+ for (it.toFirst();(og=it.current());++it)
+ {
+ if (og->isEnabled()) og->writeDoc(root,0,0);
+ }
+
+ bool isEmpty = root->isEmpty();
+
+ delete root;
+
+ return isEmpty;
+}
+
+
+//--------------------------------------------------------------------------
+// Create some overloaded definitions of the forall function.
+// Using template functions here would have made it a little less
+// portable (I guess).
+
+// zero arguments
+void OutputList::forall(void (OutputGenerator::*func)())
+{
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (it.toFirst();(og=it.current());++it)
+ {
+ if (og->isEnabled()) (og->*func)();
+ }
+}
+
+// one argument
+#define FORALL1(a1,p1) \
+void OutputList::forall(void (OutputGenerator::*func)(a1),a1) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1); \
+ } \
+}
+
+// two arguments
+#define FORALL2(a1,a2,p1,p2) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2),a1,a2) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2); \
+ } \
+}
+
+// three arguments
+#define FORALL3(a1,a2,a3,p1,p2,p3) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3),a1,a2,a3) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3); \
+ } \
+}
+
+// four arguments
+#define FORALL4(a1,a2,a3,a4,p1,p2,p3,p4) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4),a1,a2,a3,a4) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3,p4); \
+ } \
+}
+
+// five arguments
+#define FORALL5(a1,a2,a3,a4,a5,p1,p2,p3,p4,p5) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5),a1,a2,a3,a4,a5) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5); \
+ } \
+}
+
+// six arguments
+#define FORALL6(a1,a2,a3,a4,a5,a6,p1,p2,p3,p4,p5,p6) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6),a1,a2,a3,a4,a5,a6) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6); \
+ } \
+}
+
+// seven arguments
+#define FORALL7(a1,a2,a3,a4,a5,a6,a7,p1,p2,p3,p4,p5,p6,p7) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6,a7),a1,a2,a3,a4,a5,a6,a7) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6,p7); \
+ } \
+}
+
+
+// eight arguments
+#define FORALL8(a1,a2,a3,a4,a5,a6,a7,a8,p1,p2,p3,p4,p5,p6,p7,p8) \
+void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6,a7,a8),a1,a2,a3,a4,a5,a6,a7,a8) \
+{ \
+ QListIterator<OutputGenerator> it(m_outputs); \
+ OutputGenerator *og; \
+ for (it.toFirst();(og=it.current());++it) \
+ { \
+ if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6,p7,p8); \
+ } \
+}
+
+// now instantiate only the ones we need.
+
+FORALL1(const char *a1,a1)
+FORALL1(char a1,a1)
+FORALL1(int a1,a1)
+FORALL1(const DotClassGraph &a1,a1)
+FORALL1(const DotInclDepGraph &a1,a1)
+FORALL1(const DotCallGraph &a1,a1)
+FORALL1(const DotDirDeps &a1,a1)
+FORALL1(const DotGfxHierarchyTable &a1,a1)
+FORALL1(const DotGroupCollaboration &a1,a1)
+FORALL1(SectionTypes a1,a1)
+#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
+FORALL1(bool a1,a1)
+FORALL2(bool a1,int a2,a1,a2)
+FORALL2(bool a1,bool a2,a1,a2)
+FORALL2(const char *a1,bool a2,a1,a2)
+FORALL4(const char *a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4)
+#endif
+FORALL2(int a1,bool a2,a1,a2)
+FORALL2(bool a1,const char *a2,a1,a2)
+FORALL2(ParamListTypes a1,const char *a2,a1,a2)
+FORALL1(IndexSections a1,a1)
+FORALL2(const char *a1,const char *a2,a1,a2)
+FORALL2(const char *a1,int a2,a1,a2)
+FORALL2(const char *a1,SectionInfo::SectionType a2,a1,a2)
+FORALL3(bool a1,HighlightedItem a2,const char *a3,a1,a2,a3)
+FORALL3(bool a1,bool a2,bool a3,a1,a2,a3)
+FORALL3(const ClassDiagram &a1,const char *a2,const char *a3,a1,a2,a3)
+FORALL3(const char *a1,const char *a2,const char *a3,a1,a2,a3)
+FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3)
+FORALL3(const char *a1,int a2,const char *a3,a1,a2,a3)
+FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3)
+FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3)
+FORALL3(Definition *a1,const char *a2,bool a3,a1,a2,a3)
+FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
+FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
+FORALL4(const char *a1,const char *a2,const char *a3,int a4,a1,a2,a3,a4)
+FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,a1,a2,a3,a4,a5)
+FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,bool a5,a1,a2,a3,a4,a5)
+FORALL6(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,const char *a6,a1,a2,a3,a4,a5,a6)
+FORALL6(const char *a1,const DocLinkInfo &a2,const char *a3,const char *a4,const SourceLinkInfo &a5,const SourceLinkInfo &a6,a1,a2,a3,a4,a5,a6)
+
+
+//--------------------------------------------------------------------------
diff --git a/src/outputlist.h b/src/outputlist.h
new file mode 100644
index 0000000..f578d64
--- /dev/null
+++ b/src/outputlist.h
@@ -0,0 +1,554 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef OUTPUTLIST_H
+#define OUTPUTLIST_H
+
+#include <qlist.h>
+#include "index.h" // for IndexSections
+#include "outputgen.h"
+
+#define FORALLPROTO1(arg1) \
+ void forall(void (OutputGenerator::*func)(arg1),arg1)
+#define FORALLPROTO2(arg1,arg2) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2),arg1,arg2)
+#define FORALLPROTO3(arg1,arg2,arg3) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3),arg1,arg2,arg3)
+#define FORALLPROTO4(arg1,arg2,arg3,arg4) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4),arg1,arg2,arg3,arg4)
+#define FORALLPROTO5(arg1,arg2,arg3,arg4,arg5) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5),arg1,arg2,arg3,arg4,arg5)
+#define FORALLPROTO6(arg1,arg2,arg3,arg4,arg5,arg6) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6),arg1,arg2,arg3,arg4,arg5,arg6)
+#define FORALLPROTO7(arg1,arg2,arg3,arg4,arg5,arg6,arg7) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6,arg7),arg1,arg2,arg3,arg4,arg5,arg6,arg7)
+#define FORALLPROTO8(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \
+ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8),arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)
+
+class ClassDiagram;
+class DotClassGraph;
+class DotDirDeps;
+class DotInclDepGraph;
+class DotGfxHierarchyTable;
+class SectionDict;
+class DotGroupCollaboration;
+class DocRoot;
+
+/** Class representing a list of output generators that are written to
+ * in parallel.
+ */
+class OutputList : public OutputDocInterface
+{
+ public:
+ OutputList(bool);
+ virtual ~OutputList();
+
+ void add(const OutputGenerator *);
+ uint count() const { return m_outputs.count(); }
+
+ void disableAllBut(OutputGenerator::OutputType o);
+ void enableAll();
+ void disableAll();
+ void disable(OutputGenerator::OutputType o);
+ void enable(OutputGenerator::OutputType o);
+ bool isEnabled(OutputGenerator::OutputType o);
+ void pushGeneratorState();
+ void popGeneratorState();
+
+
+ //////////////////////////////////////////////////
+ // OutputDocInterface implementation
+ //////////////////////////////////////////////////
+
+ bool generateDoc(const char *fileName,int startLine,
+ Definition *ctx,MemberDef *md,const QCString &docStr,
+ bool indexWords,bool isExample,const char *exampleName=0,
+ bool singleLine=FALSE,bool linkFromIndex=FALSE);
+ void writeDoc(DocRoot *root,Definition *ctx,MemberDef *md);
+ bool parseText(const QCString &textStr);
+
+
+ void startIndexSection(IndexSections is)
+ { forall(&OutputGenerator::startIndexSection,is); }
+ void endIndexSection(IndexSections is)
+ { forall(&OutputGenerator::endIndexSection,is); }
+ void writePageLink(const char *name,bool first)
+ { forall(&OutputGenerator::writePageLink,name,first); }
+ void startProjectNumber()
+ { forall(&OutputGenerator::startProjectNumber); }
+ void endProjectNumber()
+ { forall(&OutputGenerator::endProjectNumber); }
+ void writeStyleInfo(int part)
+ { forall(&OutputGenerator::writeStyleInfo,part); }
+ void startFile(const char *name,const char *manName,const char *title)
+ { forall(&OutputGenerator::startFile,name,manName,title); }
+ void writeSearchInfo()
+ { forall(&OutputGenerator::writeSearchInfo); }
+ void writeFooter(const char *navPath)
+ { forall(&OutputGenerator::writeFooter,navPath); }
+ void endFile()
+ { forall(&OutputGenerator::endFile); }
+ void startTitleHead(const char *fileName)
+ { forall(&OutputGenerator::startTitleHead,fileName); }
+ void endTitleHead(const char *fileName,const char *name)
+ { forall(&OutputGenerator::endTitleHead,fileName,name); }
+ void startTitle()
+ { forall(&OutputGenerator::startTitle); }
+ void endTitle()
+ { forall(&OutputGenerator::endTitle); }
+ //void newParagraph()
+ //{ forall(&OutputGenerator::newParagraph); }
+ void startParagraph()
+ { forall(&OutputGenerator::startParagraph); }
+ void endParagraph()
+ { forall(&OutputGenerator::endParagraph); }
+ void writeString(const char *text)
+ { forall(&OutputGenerator::writeString,text); }
+ void startIndexListItem()
+ { forall(&OutputGenerator::startIndexListItem); }
+ void endIndexListItem()
+ { forall(&OutputGenerator::endIndexListItem); }
+ void startIndexList()
+ { forall(&OutputGenerator::startIndexList); }
+ void endIndexList()
+ { forall(&OutputGenerator::endIndexList); }
+ void startIndexKey()
+ { forall(&OutputGenerator::startIndexKey); }
+ void endIndexKey()
+ { forall(&OutputGenerator::endIndexKey); }
+ void startIndexValue(bool b)
+ { forall(&OutputGenerator::startIndexValue,b); }
+ void endIndexValue(const char *name,bool b)
+ { forall(&OutputGenerator::endIndexValue,name,b); }
+ void startItemList()
+ { forall(&OutputGenerator::startItemList); }
+ void endItemList()
+ { forall(&OutputGenerator::endItemList); }
+ void startIndexItem(const char *ref,const char *file)
+ { forall(&OutputGenerator::startIndexItem,ref,file); }
+ void endIndexItem(const char *ref,const char *file)
+ { forall(&OutputGenerator::endIndexItem,ref,file); }
+ void docify(const char *s)
+ { forall(&OutputGenerator::docify,s); }
+ void codify(const char *s)
+ { forall(&OutputGenerator::codify,s); }
+ void writeObjectLink(const char *ref,const char *file,
+ const char *anchor, const char *name)
+ { forall(&OutputGenerator::writeObjectLink,ref,file,anchor,name); }
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip)
+ { forall(&OutputGenerator::writeCodeLink,ref,file,anchor,name,tooltip); }
+ void writeTooltip(const char *id, const DocLinkInfo &docInfo, const char *decl,
+ const char *desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo)
+ { forall(&OutputGenerator::writeTooltip,id,docInfo,decl,desc,defInfo,declInfo); }
+ void startTextLink(const char *file,const char *anchor)
+ { forall(&OutputGenerator::startTextLink,file,anchor); }
+ void endTextLink()
+ { forall(&OutputGenerator::endTextLink); }
+ void startHtmlLink(const char *url)
+ { forall(&OutputGenerator::startHtmlLink,url); }
+ void endHtmlLink()
+ { forall(&OutputGenerator::endHtmlLink); }
+ void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name)
+ { forall(&OutputGenerator::writeStartAnnoItem,type,file,path,name); }
+ void writeEndAnnoItem(const char *name)
+ { forall(&OutputGenerator::writeEndAnnoItem,name); }
+ void startTypewriter()
+ { forall(&OutputGenerator::startTypewriter); }
+ void endTypewriter()
+ { forall(&OutputGenerator::endTypewriter); }
+ void startGroupHeader(int extraLevels=0)
+ { forall(&OutputGenerator::startGroupHeader,extraLevels); }
+ void endGroupHeader(int extraLevels=0)
+ { forall(&OutputGenerator::endGroupHeader,extraLevels); }
+ //void writeListItem()
+ //{ forall(&OutputGenerator::writeListItem); }
+ void startItemListItem()
+ { forall(&OutputGenerator::startItemListItem); }
+ void endItemListItem()
+ { forall(&OutputGenerator::endItemListItem); }
+ void startMemberSections()
+ { forall(&OutputGenerator::startMemberSections); }
+ void endMemberSections()
+ { forall(&OutputGenerator::endMemberSections); }
+ void startHeaderSection()
+ { forall(&OutputGenerator::startHeaderSection); }
+ void endHeaderSection()
+ { forall(&OutputGenerator::endHeaderSection); }
+ void startMemberHeader(const char *anchor)
+ { forall(&OutputGenerator::startMemberHeader,anchor); }
+ void endMemberHeader()
+ { forall(&OutputGenerator::endMemberHeader); }
+ void startMemberSubtitle()
+ { forall(&OutputGenerator::startMemberSubtitle); }
+ void endMemberSubtitle()
+ { forall(&OutputGenerator::endMemberSubtitle); }
+ void startMemberDocList()
+ { forall(&OutputGenerator::startMemberDocList); }
+ void endMemberDocList()
+ { forall(&OutputGenerator::endMemberDocList); }
+ void startMemberList()
+ { forall(&OutputGenerator::startMemberList); }
+ void endMemberList()
+ { forall(&OutputGenerator::endMemberList); }
+ void startInlineHeader()
+ { forall(&OutputGenerator::startInlineHeader); }
+ void endInlineHeader()
+ { forall(&OutputGenerator::endInlineHeader); }
+ void startAnonTypeScope(int i1)
+ { forall(&OutputGenerator::startAnonTypeScope,i1); }
+ void endAnonTypeScope(int i1)
+ { forall(&OutputGenerator::endAnonTypeScope,i1); }
+ void startMemberItem(const char *anchor,int i1,const char *id=0)
+ { forall(&OutputGenerator::startMemberItem,anchor,i1,id); }
+ void endMemberItem()
+ { forall(&OutputGenerator::endMemberItem); }
+ void startMemberTemplateParams()
+ { forall(&OutputGenerator::startMemberTemplateParams); }
+ void endMemberTemplateParams(const char *anchor,const char *inheritId)
+ { forall(&OutputGenerator::endMemberTemplateParams,anchor,inheritId); }
+ void startMemberGroupHeader(bool b)
+ { forall(&OutputGenerator::startMemberGroupHeader,b); }
+ void endMemberGroupHeader()
+ { forall(&OutputGenerator::endMemberGroupHeader); }
+ void startMemberGroupDocs()
+ { forall(&OutputGenerator::startMemberGroupDocs); }
+ void endMemberGroupDocs()
+ { forall(&OutputGenerator::endMemberGroupDocs); }
+ void startMemberGroup()
+ { forall(&OutputGenerator::startMemberGroup); }
+ void endMemberGroup(bool last)
+ { forall(&OutputGenerator::endMemberGroup,last); }
+ void insertMemberAlign(bool templ=FALSE)
+ { forall(&OutputGenerator::insertMemberAlign,templ); }
+ void writeRuler()
+ { forall(&OutputGenerator::writeRuler); }
+ void writeAnchor(const char *fileName,const char *name)
+ { forall(&OutputGenerator::writeAnchor,fileName,name); }
+ void startCodeFragment()
+ { forall(&OutputGenerator::startCodeFragment); }
+ void endCodeFragment()
+ { forall(&OutputGenerator::endCodeFragment); }
+ void startCodeLine(bool hasLineNumbers)
+ { forall(&OutputGenerator::startCodeLine,hasLineNumbers); }
+ void endCodeLine()
+ { forall(&OutputGenerator::endCodeLine); }
+ void writeLineNumber(const char *ref,const char *file,const char *anchor,
+ int lineNumber)
+ { forall(&OutputGenerator::writeLineNumber,ref,file,anchor,lineNumber); }
+ void startEmphasis()
+ { forall(&OutputGenerator::startEmphasis); }
+ void endEmphasis()
+ { forall(&OutputGenerator::endEmphasis); }
+ void writeChar(char c)
+ { forall(&OutputGenerator::writeChar,c); }
+ void startMemberDoc(const char *clName,const char *memName,
+ const char *anchor,const char *title,bool showInline)
+ { forall(&OutputGenerator::startMemberDoc,clName,memName,anchor,title,showInline); }
+ void endMemberDoc(bool hasArgs)
+ { forall(&OutputGenerator::endMemberDoc,hasArgs); }
+ void startDoxyAnchor(const char *fName,const char *manName,
+ const char *anchor, const char *name,
+ const char *args)
+ { forall(&OutputGenerator::startDoxyAnchor,fName,manName,anchor,name,args); }
+ void endDoxyAnchor(const char *fn,const char *anchor)
+ { forall(&OutputGenerator::endDoxyAnchor,fn,anchor); }
+ void writeLatexSpacing()
+ { forall(&OutputGenerator::writeLatexSpacing); }
+ void startDescription()
+ { forall(&OutputGenerator::startDescription); }
+ void endDescription()
+ { forall(&OutputGenerator::endDescription); }
+ void startDescItem()
+ { forall(&OutputGenerator::startDescItem); }
+ void endDescItem()
+ { forall(&OutputGenerator::endDescItem); }
+ void startDescForItem()
+ { forall(&OutputGenerator::startDescForItem); }
+ void endDescForItem()
+ { forall(&OutputGenerator::endDescForItem); }
+ void startSubsection()
+ { forall(&OutputGenerator::startSubsection); }
+ void endSubsection()
+ { forall(&OutputGenerator::endSubsection); }
+ void startSubsubsection()
+ { forall(&OutputGenerator::startSubsubsection); }
+ void endSubsubsection()
+ { forall(&OutputGenerator::endSubsubsection); }
+ void startCenter()
+ { forall(&OutputGenerator::startCenter); }
+ void endCenter()
+ { forall(&OutputGenerator::endCenter); }
+ void startSmall()
+ { forall(&OutputGenerator::startSmall); }
+ void endSmall()
+ { forall(&OutputGenerator::endSmall); }
+ void lineBreak(const char *style=0)
+ { forall(&OutputGenerator::lineBreak,style); }
+ void startBold()
+ { forall(&OutputGenerator::startBold); }
+ void endBold()
+ { forall(&OutputGenerator::endBold); }
+ void startMemberDescription(const char *anchor,const char *inheritId=0)
+ { forall(&OutputGenerator::startMemberDescription,anchor,inheritId); }
+ void endMemberDescription()
+ { forall(&OutputGenerator::endMemberDescription); }
+ void startMemberDeclaration()
+ { forall(&OutputGenerator::startMemberDeclaration); }
+ void endMemberDeclaration(const char *anchor,const char *inheritId)
+ { forall(&OutputGenerator::endMemberDeclaration,anchor,inheritId); }
+ void writeInheritedSectionTitle(const char *id, const char *ref,
+ const char *file, const char *anchor,
+ const char *title,const char *name)
+ { forall(&OutputGenerator::writeInheritedSectionTitle,id,ref,
+ file,anchor,title,name); }
+ void startSimpleSect(SectionTypes t,const char *file,const char *anchor,
+ const char *title)
+ { forall(&OutputGenerator::startSimpleSect,t,file,anchor,title); }
+ void endSimpleSect()
+ { forall(&OutputGenerator::endSimpleSect); }
+ void startParamList(ParamListTypes t,const char *title)
+ { forall(&OutputGenerator::startParamList,t,title); }
+ void endParamList()
+ { forall(&OutputGenerator::endParamList); }
+ void startIndent()
+ { forall(&OutputGenerator::startIndent); }
+ void endIndent()
+ { forall(&OutputGenerator::endIndent); }
+ void startSection(const char *lab,const char *title,SectionInfo::SectionType t)
+ { forall(&OutputGenerator::startSection,lab,title,t); }
+ void endSection(const char *lab,SectionInfo::SectionType t)
+ { forall(&OutputGenerator::endSection,lab,t); }
+ void addIndexItem(const char *s1,const char *s2)
+ { forall(&OutputGenerator::addIndexItem,s1,s2); }
+ void writeSynopsis()
+ { forall(&OutputGenerator::writeSynopsis); }
+ void startClassDiagram()
+ { forall(&OutputGenerator::startClassDiagram); }
+ void endClassDiagram(const ClassDiagram &d,const char *f,const char *n)
+ { forall(&OutputGenerator::endClassDiagram,d,f,n); }
+ void startPageRef()
+ { forall(&OutputGenerator::startPageRef); }
+ void endPageRef(const char *c,const char *a)
+ { forall(&OutputGenerator::endPageRef,c,a); }
+ void startQuickIndices()
+ { forall(&OutputGenerator::startQuickIndices); }
+ void endQuickIndices()
+ { forall(&OutputGenerator::endQuickIndices); }
+ void writeSplitBar(const char *name)
+ { forall(&OutputGenerator::writeSplitBar,name); }
+ void writeNavigationPath(const char *s)
+ { forall(&OutputGenerator::writeNavigationPath,s); }
+ void writeLogo()
+ { forall(&OutputGenerator::writeLogo); }
+ void writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
+ { forall(&OutputGenerator::writeQuickLinks,compact,hli,file); }
+ void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
+ { forall(&OutputGenerator::writeSummaryLink,file,anchor,title,first); }
+ void startContents()
+ { forall(&OutputGenerator::startContents); }
+ void endContents()
+ { forall(&OutputGenerator::endContents); }
+ void writeNonBreakableSpace(int num)
+ { forall(&OutputGenerator::writeNonBreakableSpace,num); }
+ void startDescTable(const char *title)
+ { forall(&OutputGenerator::startDescTable,title); }
+ void endDescTable()
+ { forall(&OutputGenerator::endDescTable); }
+ void startDescTableTitle()
+ { forall(&OutputGenerator::startDescTableTitle); }
+ void endDescTableTitle()
+ { forall(&OutputGenerator::endDescTableTitle); }
+ void startDescTableData()
+ { forall(&OutputGenerator::startDescTableData); }
+ void endDescTableData()
+ { forall(&OutputGenerator::endDescTableData); }
+ void startDotGraph()
+ { forall(&OutputGenerator::startDotGraph); }
+ void endDotGraph(const DotClassGraph &g)
+ { forall(&OutputGenerator::endDotGraph,g); }
+ void startInclDepGraph()
+ { forall(&OutputGenerator::startInclDepGraph); }
+ void endInclDepGraph(const DotInclDepGraph &g)
+ { forall(&OutputGenerator::endInclDepGraph,g); }
+ void startCallGraph()
+ { forall(&OutputGenerator::startCallGraph); }
+ void endCallGraph(const DotCallGraph &g)
+ { forall(&OutputGenerator::endCallGraph,g); }
+ void startDirDepGraph()
+ { forall(&OutputGenerator::startDirDepGraph); }
+ void endDirDepGraph(const DotDirDeps &g)
+ { forall(&OutputGenerator::endDirDepGraph,g); }
+ void startGroupCollaboration()
+ { forall(&OutputGenerator::startGroupCollaboration); }
+ void endGroupCollaboration(const DotGroupCollaboration &g)
+ { forall(&OutputGenerator::endGroupCollaboration,g); }
+ void writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
+ { forall(&OutputGenerator::writeGraphicalHierarchy,g); }
+ void startTextBlock(bool dense=FALSE)
+ { forall(&OutputGenerator::startTextBlock,dense); }
+ void endTextBlock(bool paraBreak=FALSE)
+ { forall(&OutputGenerator::endTextBlock,paraBreak); }
+ void lastIndexPage()
+ { forall(&OutputGenerator::lastIndexPage); }
+ void startMemberDocPrefixItem()
+ { forall(&OutputGenerator::startMemberDocPrefixItem); }
+ void endMemberDocPrefixItem()
+ { forall(&OutputGenerator::endMemberDocPrefixItem); }
+ void startMemberDocName(bool align)
+ { forall(&OutputGenerator::startMemberDocName,align); }
+ void endMemberDocName()
+ { forall(&OutputGenerator::endMemberDocName); }
+ void startParameterType(bool first,const char *key)
+ { forall(&OutputGenerator::startParameterType,first,key); }
+ void endParameterType()
+ { forall(&OutputGenerator::endParameterType); }
+ void startParameterName(bool one)
+ { forall(&OutputGenerator::startParameterName,one); }
+ void endParameterName(bool last,bool one,bool bracket)
+ { forall(&OutputGenerator::endParameterName,last,one,bracket); }
+ void startParameterList(bool openBracket)
+ { forall(&OutputGenerator::startParameterList,openBracket); }
+ void endParameterList()
+ { forall(&OutputGenerator::endParameterList); }
+ void exceptionEntry(const char* prefix,bool closeBracket)
+ { forall(&OutputGenerator::exceptionEntry,prefix,closeBracket); }
+
+ void startConstraintList(const char *header)
+ { forall(&OutputGenerator::startConstraintList,header); }
+ void startConstraintParam()
+ { forall(&OutputGenerator::startConstraintParam); }
+ void endConstraintParam()
+ { forall(&OutputGenerator::endConstraintParam); }
+ void startConstraintType()
+ { forall(&OutputGenerator::startConstraintType); }
+ void endConstraintType()
+ { forall(&OutputGenerator::endConstraintType); }
+ void startConstraintDocs()
+ { forall(&OutputGenerator::startConstraintDocs); }
+ void endConstraintDocs()
+ { forall(&OutputGenerator::endConstraintDocs); }
+ void endConstraintList()
+ { forall(&OutputGenerator::endConstraintList); }
+
+ void startMemberDocSimple()
+ { forall(&OutputGenerator::startMemberDocSimple); }
+ void endMemberDocSimple()
+ { forall(&OutputGenerator::endMemberDocSimple); }
+ void startInlineMemberType()
+ { forall(&OutputGenerator::startInlineMemberType); }
+ void endInlineMemberType()
+ { forall(&OutputGenerator::endInlineMemberType); }
+ void startInlineMemberName()
+ { forall(&OutputGenerator::startInlineMemberName); }
+ void endInlineMemberName()
+ { forall(&OutputGenerator::endInlineMemberName); }
+ void startInlineMemberDoc()
+ { forall(&OutputGenerator::startInlineMemberDoc); }
+ void endInlineMemberDoc()
+ { forall(&OutputGenerator::endInlineMemberDoc); }
+
+ void startLabels()
+ { forall(&OutputGenerator::startLabels); }
+ void writeLabel(const char *l,bool isLast)
+ { forall(&OutputGenerator::writeLabel,l,isLast); }
+ void endLabels()
+ { forall(&OutputGenerator::endLabels); }
+
+ void startFontClass(const char *c)
+ { forall(&OutputGenerator::startFontClass,c); }
+ void endFontClass()
+ { forall(&OutputGenerator::endFontClass); }
+ void writeCodeAnchor(const char *name)
+ { forall(&OutputGenerator::writeCodeAnchor,name); }
+ void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
+ { forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); }
+ void addWord(const char *word,bool hiPriority)
+ { forall(&OutputGenerator::addWord,word,hiPriority); }
+
+ void startPlainFile(const char *name)
+ {
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (;(og=it.current());++it)
+ {
+ if (og->isEnabled()) (og->startPlainFile)(name);
+ }
+ }
+ void endPlainFile()
+ {
+ QListIterator<OutputGenerator> it(m_outputs);
+ OutputGenerator *og;
+ for (;(og=it.current());++it)
+ {
+ if (og->isEnabled()) (og->endPlainFile)();
+ }
+ }
+
+ private:
+ void debug();
+ void clear();
+
+ void forall(void (OutputGenerator::*func)());
+ FORALLPROTO1(const char *);
+ FORALLPROTO1(char);
+ FORALLPROTO1(IndexSections);
+ FORALLPROTO1(int);
+ FORALLPROTO1(const DotClassGraph &);
+ FORALLPROTO1(const DotInclDepGraph &);
+ FORALLPROTO1(const DotCallGraph &);
+ FORALLPROTO1(const DotGroupCollaboration &);
+ FORALLPROTO1(const DotDirDeps &);
+ FORALLPROTO1(const DotGfxHierarchyTable &);
+ FORALLPROTO1(SectionTypes);
+#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
+ FORALLPROTO1(bool);
+ FORALLPROTO2(bool,int);
+ FORALLPROTO2(bool,bool);
+ FORALLPROTO2(const char *,bool);
+ FORALLPROTO4(const char *,const char *,const char *,int);
+#endif
+ FORALLPROTO2(int,bool);
+ FORALLPROTO2(bool,const char *);
+ FORALLPROTO2(ParamListTypes,const char *);
+ FORALLPROTO2(const char *,const char *);
+ FORALLPROTO2(const char *,int);
+ FORALLPROTO2(const char *,SectionInfo::SectionType);
+ FORALLPROTO3(bool,HighlightedItem,const char *);
+ FORALLPROTO3(bool,bool,bool);
+ FORALLPROTO3(const char *,const char *,bool);
+ FORALLPROTO3(const char *,int,const char *);
+ FORALLPROTO3(const char *,const char *,SectionInfo::SectionType);
+ FORALLPROTO3(uchar,uchar,uchar);
+ FORALLPROTO3(const char *,const char *,const char *);
+ FORALLPROTO3(const ClassDiagram &,const char *,const char *);
+ FORALLPROTO3(Definition*,const char *,bool);
+ FORALLPROTO4(SectionTypes,const char *,const char *,const char *);
+ FORALLPROTO4(const char *,const char *,const char *,const char *);
+ FORALLPROTO4(const char *,const char *,const char *,bool);
+ FORALLPROTO5(const char *,const char *,const char *,const char *,const char *);
+ FORALLPROTO5(const char *,const char *,const char *,const char *,bool);
+ FORALLPROTO6(const char *,const char *,const char *,const char *,const char *,const char *);
+ FORALLPROTO6(const char *,const DocLinkInfo &,const char *,const char *,const SourceLinkInfo &,const SourceLinkInfo &);
+
+ OutputList(const OutputList &ol);
+ QList<OutputGenerator> m_outputs;
+};
+
+#endif
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
new file mode 100644
index 0000000..e75327c
--- /dev/null
+++ b/src/pagedef.cpp
@@ -0,0 +1,321 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qregexp.h>
+
+#include "pagedef.h"
+#include "groupdef.h"
+#include "docparser.h"
+#include "config.h"
+#include "util.h"
+#include "outputlist.h"
+#include "doxygen.h"
+#include "language.h"
+#include "namespacedef.h"
+#include "reflist.h"
+
+PageDef::PageDef(const char *f,int l,const char *n,
+ const char *d,const char *t)
+ : Definition(f,l,1,n), m_title(t)
+{
+ setDocumentation(d,f,l);
+ m_subPageDict = new PageSDict(7);
+ m_pageScope = 0;
+ m_nestingLevel = 0;
+ m_showToc = FALSE;
+}
+
+PageDef::~PageDef()
+{
+ delete m_subPageDict;
+}
+
+void PageDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+}
+
+GroupDef *PageDef::getGroupDef() const
+{
+ GroupList *groups = partOfGroups();
+ return groups!=0 ? groups->getFirst() : 0;
+}
+
+QCString PageDef::getOutputFileBase() const
+{
+ if (getGroupDef())
+ return getGroupDef()->getOutputFileBase();
+ else
+ return m_fileName;
+}
+
+void PageDef::setFileName(const char *name,bool dontEscape)
+{
+ static bool shortNames = Config_getBool("SHORT_NAMES");
+ if (shortNames && !dontEscape)
+ {
+ m_fileName = convertNameToFile(name);
+ }
+ else
+ {
+ m_fileName = name;
+ }
+}
+
+
+void PageDef::addInnerCompound(Definition *def)
+{
+ if (def->definitionType()==Definition::TypePage)
+ {
+ PageDef *pd = (PageDef*)def;
+ m_subPageDict->append(pd->name(),pd);
+ def->setOuterScope(this);
+ if (this==Doxygen::mainPage)
+ {
+ pd->setNestingLevel(m_nestingLevel);
+ }
+ else
+ {
+ pd->setNestingLevel(m_nestingLevel+1);
+ }
+ }
+}
+
+bool PageDef::hasParentPage() const
+{
+ return getOuterScope() &&
+ getOuterScope()->definitionType()==Definition::TypePage;
+}
+
+void PageDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+
+ //outputList->disable(OutputGenerator::Man);
+ QCString pageName,manPageName;
+ pageName = escapeCharsInString(name(),FALSE,TRUE);
+ manPageName = escapeCharsInString(name(),TRUE,TRUE);
+
+ //printf("PageDef::writeDocumentation: %s\n",getOutputFileBase().data());
+
+ ol.pushGeneratorState();
+ //1.{
+
+ if (m_nestingLevel>0
+ //&& // a sub page
+ //(Doxygen::mainPage==0 || getOuterScope()!=Doxygen::mainPage) // and not a subpage of the mainpage
+ )
+ {
+ // do not generate sub page output for RTF and LaTeX, as these are
+ // part of their parent page
+ ol.disableAll();
+ ol.enable(OutputGenerator::Man);
+ ol.enable(OutputGenerator::Html);
+ }
+
+ ol.pushGeneratorState();
+ //2.{
+ ol.disableAllBut(OutputGenerator::Man);
+ startFile(ol,getOutputFileBase(),manPageName,title(),HLI_Pages,!generateTreeView);
+ ol.enableAll();
+ ol.disable(OutputGenerator::Man);
+ startFile(ol,getOutputFileBase(),pageName,title(),HLI_Pages,!generateTreeView);
+ ol.popGeneratorState();
+ //2.}
+
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX"))
+ {
+ getOuterScope()->writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+ SectionInfo *si=Doxygen::sectionDict->find(name());
+
+ // save old generator state and write title only to Man generator
+ ol.pushGeneratorState();
+ //2.{
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.startTitleHead(manPageName);
+ ol.endTitleHead(manPageName, manPageName);
+ if (si)
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE);
+ ol.endSection(si->label,si->type);
+ }
+ ol.popGeneratorState();
+ //2.}
+
+ // for Latex the section is already generated as a chapter in the index!
+ ol.pushGeneratorState();
+ //2.{
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+ if (!title().isEmpty() && !name().isEmpty() && si!=0)
+ {
+ //ol.startSection(si->label,si->title,si->type);
+ startTitle(ol,getOutputFileBase(),this);
+ ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE);
+ //stringToSearchIndex(getOutputFileBase(),
+ // theTranslator->trPage(TRUE,TRUE)+" "+si->title,
+ // si->title);
+ //ol.endSection(si->label,si->type);
+ endTitle(ol,getOutputFileBase(),name());
+ }
+ ol.startContents();
+ ol.popGeneratorState();
+ //2.}
+
+ if (m_showToc && hasSections())
+ {
+ writeToc(ol);
+ }
+
+ writePageDocumentation(ol);
+
+ if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX"))
+ {
+ ol.endContents();
+ endFileWithNavPath(getOuterScope(),ol);
+ }
+ else
+ {
+ endFile(ol);
+ }
+
+ ol.popGeneratorState();
+ //1.}
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ bool found = name()=="citelist";
+ QDictIterator<RefList> rli(*Doxygen::xrefLists);
+ RefList *rl;
+ for (rli.toFirst();(rl=rli.current()) && !found;++rli)
+ {
+ if (rl->listName()==name())
+ {
+ found=TRUE;
+ break;
+ }
+ }
+ if (!found) // not one of the generated related pages
+ {
+ Doxygen::tagFile << " <compound kind=\"page\">" << endl;
+ Doxygen::tagFile << " <name>" << name() << "</name>" << endl;
+ Doxygen::tagFile << " <title>" << convertToXML(title()) << "</title>" << endl;
+ Doxygen::tagFile << " <filename>" << getOutputFileBase() << "</filename>" << endl;
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+ }
+
+ Doxygen::indexList->addIndexItem(this,0,0,filterTitle(title()));
+}
+
+void PageDef::writePageDocumentation(OutputList &ol)
+{
+
+ bool markdownEnabled = Doxygen::markdownSupport;
+ if (getLanguage()==SrcLangExt_Markdown)
+ {
+ Doxygen::markdownSupport = TRUE;
+ }
+
+ ol.startTextBlock();
+ ol.generateDoc(
+ docFile(), // fileName
+ docLine(), // startLine
+ this, // context
+ 0, // memberdef
+ documentation()+inbodyDocumentation(), // docStr
+ TRUE, // index words
+ FALSE // not an example
+ );
+ ol.endTextBlock();
+
+ Doxygen::markdownSupport = markdownEnabled;
+
+ if (hasSubPages())
+ {
+ // for printed documentation we write subpages as section's of the
+ // parent page.
+ ol.pushGeneratorState();
+ ol.disableAll();
+ ol.enable(OutputGenerator::Latex);
+ ol.enable(OutputGenerator::RTF);
+
+ PageSDict::Iterator pdi(*m_subPageDict);
+ PageDef *subPage=pdi.toFirst();
+ for (pdi.toFirst();(subPage=pdi.current());++pdi)
+ {
+ SectionInfo::SectionType sectionType = SectionInfo::Paragraph;
+ switch (m_nestingLevel)
+ {
+ case 0: sectionType = SectionInfo::Page; break;
+ case 1: sectionType = SectionInfo::Section; break;
+ case 2: sectionType = SectionInfo::Subsection; break;
+ case 3: sectionType = SectionInfo::Subsubsection; break;
+ default: sectionType = SectionInfo::Paragraph; break;
+ }
+ QCString title = subPage->title();
+ if (title.isEmpty()) title = subPage->name();
+ ol.startSection(subPage->name(),title,sectionType);
+ ol.parseText(title);
+ ol.endSection(subPage->name(),sectionType);
+ Doxygen::subpageNestingLevel++;
+ subPage->writePageDocumentation(ol);
+ Doxygen::subpageNestingLevel--;
+ }
+
+ ol.popGeneratorState();
+ }
+}
+
+bool PageDef::visibleInIndex() const
+{
+ static bool externalPages = Config_getBool("EXTERNAL_PAGES");
+ return // not part of a group
+ !getGroupDef() &&
+ // not an externally defined page
+ (!isReference() || externalPages)
+ ;
+}
+
+bool PageDef::documentedPage() const
+{
+ return // not part of a group
+ !getGroupDef() &&
+ // not an externally defined page
+ !isReference();
+}
+
+bool PageDef::hasSubPages() const
+{
+ return m_subPageDict->count()>0;
+}
+
+void PageDef::setNestingLevel(int l)
+{
+ m_nestingLevel = l;
+}
+
+void PageDef::setShowToc(bool b)
+{
+ m_showToc = b;
+}
+
diff --git a/src/pagedef.h b/src/pagedef.h
new file mode 100644
index 0000000..890829e
--- /dev/null
+++ b/src/pagedef.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef PAGEDEF_H
+#define PAGEDEF_H
+
+#include "definition.h"
+#include "sortdict.h"
+
+class PageSDict;
+class OutputList;
+
+/** @brief A model of a page symbol. */
+class PageDef : public Definition
+{
+ public:
+ PageDef(const char *f,int l,const char *n,const char *d,const char *t);
+ ~PageDef();
+
+ // setters
+ void setFileName(const char *name,bool dontEscape);
+ void setShowToc(bool b);
+
+ // getters
+ DefType definitionType() const { return TypePage; }
+ bool isLinkableInProject() const
+ {
+ return /*hasDocumentation() &&*/ !isReference();
+ }
+ bool isLinkable() const
+ {
+ return isLinkableInProject() || isReference();
+ }
+
+ // functions to get a uniform interface with Definitions
+ QCString getOutputFileBase() const;
+ QCString anchor() const { return QCString(); }
+ void findSectionsInDocumentation();
+ QCString title() const { return m_title; }
+ GroupDef * getGroupDef() const;
+ PageSDict * getSubPages() const { return m_subPageDict; }
+ void addInnerCompound(Definition *d);
+ bool visibleInIndex() const;
+ bool documentedPage() const;
+ bool hasSubPages() const;
+ bool hasParentPage() const;
+ bool showToc() const { return m_showToc; }
+ void setPageScope(Definition *d){ m_pageScope = d; }
+ Definition *getPageScope() const { return m_pageScope; }
+ QCString displayName(bool=TRUE) const { return !m_title.isEmpty() ? m_title : Definition::name(); }
+
+ void writeDocumentation(OutputList &ol);
+
+ private:
+ void setNestingLevel(int l);
+ void writePageDocumentation(OutputList &ol);
+ QCString m_fileName;
+ QCString m_title;
+ PageSDict *m_subPageDict; // list of pages in the group
+ Definition *m_pageScope;
+ int m_nestingLevel;
+ bool m_showToc;
+};
+
+class PageSDict : public SDict<PageDef>
+{
+ public:
+ PageSDict(int size) : SDict<PageDef>(size) {}
+ virtual ~PageSDict() {}
+ private:
+ int compareValues(const PageDef *i1,const PageDef *i2) const
+ {
+ return qstricmp(i1->name(),i2->name());
+ }
+};
+
+#endif
+
diff --git a/src/parserintf.h b/src/parserintf.h
new file mode 100644
index 0000000..019b4a9
--- /dev/null
+++ b/src/parserintf.h
@@ -0,0 +1,205 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef PARSERINTF_H
+#define PARSERINTF_H
+
+#include <qdict.h>
+#include <qstrlist.h>
+
+#include "types.h"
+
+class Entry;
+class FileDef;
+class CodeOutputInterface;
+class MemberDef;
+class Definition;
+
+/** \brief Abstract interface for programming language parsers.
+ *
+ * By implementing the methods of this interface one can add
+ * a new language parser to doxygen. The parser can make use of the
+ * comment block parser to parse the contents of special comment blocks.
+ */
+class ParserInterface
+{
+ public:
+ virtual ~ParserInterface() {}
+
+ /** Starts processing a translation unit (source files + headers).
+ * After this call parseInput() is called with sameTranslationUnit
+ * set to FALSE. If parseInput() returns additional include files,
+ * these are also processed using parseInput() with
+ * sameTranslationUnit set to TRUE. After that
+ * finishTranslationUnit() is called.
+ */
+ virtual void startTranslationUnit(const char *fileName) = 0;
+
+ /** Called after all files in a translation unit have been
+ * processed.
+ */
+ virtual void finishTranslationUnit() = 0;
+
+ /** Parses a single input file with the goal to build an Entry tree.
+ * @param[in] fileName The full name of the file.
+ * @param[in] fileBuf The contents of the file (zero terminated).
+ * @param[in,out] root The root of the tree of Entry *nodes
+ * representing the information extracted from the file.
+ * @param[in] sameTranslationUnit TRUE if this file was found in the same
+ * translation unit (in the filesInSameTranslationUnit list
+ * returned for another file).
+ * @param[in,out] filesInSameTranslationUnit other files expected to be
+ * found in the same translation unit (used for libclang)
+ */
+ virtual void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit) = 0;
+
+ /** Returns TRUE if the language identified by \a extension needs
+ * the C preprocessor to be run before feed the result to the input
+ * parser.
+ * @see parseInput()
+ */
+ virtual bool needsPreprocessing(const QCString &extension) = 0;
+
+ /** Parses a source file or fragment with the goal to produce
+ * highlighted and cross-referenced output.
+ * @param[in] codeOutIntf Abstract interface for writing the result.
+ * @param[in] lang The programming language of the code fragment.
+ * @param[in] scopeName Name of scope to which the code belongs.
+ * @param[in] input Actual code in the form of a string
+ * @param[in] isExampleBlock TRUE iff the code is part of an example.
+ * @param[in] exampleName Name of the example.
+ * @param[in] fileDef File definition to which the code
+ * is associated.
+ * @param[in] startLine Starting line in case of a code fragment.
+ * @param[in] endLine Ending line of the code fragment.
+ * @param[in] inlineFragment Code fragment that is to be shown inline
+ * as part of the documentation.
+ * @param[in] memberDef Member definition to which the code
+ * is associated (non null in case of an inline fragment
+ * for a member).
+ * @param[in] showLineNumbers if set to TRUE and also fileDef is not 0,
+ * line numbers will be added to the source fragement
+ * @param[in] searchCtx context under which search data has to be stored.
+ * @param[in] collectXRefs collect cross-reference relations.
+ */
+ virtual void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ ) = 0;
+
+ /** Resets the state of the code parser.
+ * Since multiple code fragments can together form a single example, an
+ * explicit function is used to reset the code parser state.
+ * @see parseCode()
+ */
+ virtual void resetCodeParserState() = 0;
+
+ /** Callback function called by the comment block scanner.
+ * It provides a string \a text containing the prototype of a function
+ * or variable. The parser should parse this and store the information
+ * in the Entry node that corresponds with the node for which the
+ * comment block parser was invoked.
+ */
+ virtual void parsePrototype(const char *text) = 0;
+
+};
+
+//-----------------------------------------------------------------------------
+
+/** \brief Manages programming language parsers.
+ *
+ * This class manages the language parsers in the system. One can
+ * register parsers, and obtain a parser given a file extension.
+ */
+class ParserManager
+{
+ public:
+ /** Creates the parser manager object.
+ */
+ ParserManager()
+ : m_defaultParser(0) { m_parsers.setAutoDelete(TRUE); }
+
+ void registerDefaultParser(ParserInterface *parser)
+ {
+ m_defaultParser = parser;
+ }
+
+ /** Registers an additional parser.
+ * @param[in] name A symbolic name of the parser, i.e. "c",
+ * "python", "fortran", "vhdl", ...
+ * @param[in] parser The parser that is to be used for the
+ * given name.
+ */
+ void registerParser(const char *name,ParserInterface *parser)
+ {
+ m_parsers.insert(name,parser);
+ }
+
+ /** Registers a file \a extension with a parser with name \a parserName.
+ * Returns TRUE if the extension was successfully registered.
+ */
+ bool registerExtension(const char *extension, const char *parserName)
+ {
+ if (parserName==0 || extension==0) return FALSE;
+ ParserInterface *intf = m_parsers.find(parserName);
+ if (intf==0) return FALSE;
+ if (m_extensions.find(extension)!=0) // extension already exists
+ {
+ m_extensions.remove(extension); // remove it
+ }
+ m_extensions.insert(extension,intf); // add new mapping
+ return TRUE;
+ }
+
+ /** Gets the interface to the parser associated with given \a extension.
+ * If there is no parser explicitly registered for the supplied extension,
+ * the interface to the default parser will be returned.
+ */
+ ParserInterface *getParser(const char *extension)
+ {
+ QCString ext = QCString(extension).lower();
+ if (ext.isEmpty()) ext=".no_extension";
+ ParserInterface *intf = m_extensions.find(ext);
+ if (intf==0 && ext.length()>4)
+ {
+ intf = m_extensions.find(ext.left(4));
+ }
+ return intf ? intf : m_defaultParser;
+ }
+
+ private:
+ QDict<ParserInterface> m_parsers;
+ QDict<ParserInterface> m_extensions;
+ ParserInterface *m_defaultParser;
+};
+
+#endif
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
new file mode 100644
index 0000000..c636cdf
--- /dev/null
+++ b/src/perlmodgen.cpp
@@ -0,0 +1,2987 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ * Authors: Dimitri van Heesch, Miguel Lobo.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qstack.h>
+#include <qdict.h>
+#include <qfile.h>
+
+#include "perlmodgen.h"
+#include "docparser.h"
+#include "message.h"
+#include "doxygen.h"
+#include "pagedef.h"
+#include "memberlist.h"
+#include "ftextstream.h"
+#include "arguments.h"
+#include "config.h"
+#include "groupdef.h"
+#include "classdef.h"
+#include "classlist.h"
+#include "filename.h"
+#include "membername.h"
+#include "namespacedef.h"
+#include "membergroup.h"
+#include "section.h"
+#include "util.h"
+#include "htmlentity.h"
+
+#define PERLOUTPUT_MAX_INDENTATION 40
+
+class PerlModOutputStream
+{
+public:
+
+ QCString m_s;
+ FTextStream *m_t;
+
+ PerlModOutputStream(FTextStream *t = 0) : m_t(t) { }
+
+ void add(char c);
+ void add(const char *s);
+ void add(QCString &s);
+ void add(int n);
+ void add(unsigned int n);
+};
+
+void PerlModOutputStream::add(char c)
+{
+ if (m_t != 0)
+ (*m_t) << c;
+ else
+ m_s += c;
+}
+
+void PerlModOutputStream::add(const char *s)
+{
+ if (m_t != 0)
+ (*m_t) << s;
+ else
+ m_s += s;
+}
+
+void PerlModOutputStream::add(QCString &s)
+{
+ if (m_t != 0)
+ (*m_t) << s;
+ else
+ m_s += s;
+}
+
+void PerlModOutputStream::add(int n)
+{
+ if (m_t != 0)
+ (*m_t) << n;
+ else
+ m_s += n;
+}
+
+void PerlModOutputStream::add(unsigned int n)
+{
+ if (m_t != 0)
+ (*m_t) << n;
+ else
+ m_s += n;
+}
+
+class PerlModOutput
+{
+public:
+
+ bool m_pretty;
+
+ inline PerlModOutput(bool pretty)
+ : m_pretty(pretty), m_stream(0), m_indentation(false), m_blockstart(true)
+ {
+ m_spaces[0] = 0;
+ }
+
+ virtual ~PerlModOutput() { }
+
+ inline void setPerlModOutputStream(PerlModOutputStream *os) { m_stream = os; }
+
+ inline PerlModOutput &openSave() { iopenSave(); return *this; }
+ inline PerlModOutput &closeSave(QCString &s) { icloseSave(s); return *this; }
+
+ inline PerlModOutput &continueBlock()
+ {
+ if (m_blockstart)
+ m_blockstart = false;
+ else
+ m_stream->add(',');
+ indent();
+ return *this;
+ }
+
+ inline PerlModOutput &add(char c) { m_stream->add(c); return *this; }
+ inline PerlModOutput &add(const char *s) { m_stream->add(s); return *this; }
+ inline PerlModOutput &add(QCString &s) { m_stream->add(s); return *this; }
+ inline PerlModOutput &add(int n) { m_stream->add(n); return *this; }
+ inline PerlModOutput &add(unsigned int n) { m_stream->add(n); return *this; }
+
+ PerlModOutput &addQuoted(const char *s) { iaddQuoted(s); return *this; }
+
+ inline PerlModOutput &indent()
+ {
+ if (m_pretty) {
+ m_stream->add('\n');
+ m_stream->add(m_spaces);
+ }
+ return *this;
+ }
+
+ inline PerlModOutput &open(char c, const char *s = 0) { iopen(c, s); return *this; }
+ inline PerlModOutput &close(char c = 0) { iclose(c); return *this; }
+
+ inline PerlModOutput &addField(const char *s) { iaddField(s); return *this; }
+ inline PerlModOutput &addFieldQuotedChar(const char *field, char content)
+ {
+ iaddFieldQuotedChar(field, content); return *this;
+ }
+ inline PerlModOutput &addFieldQuotedString(const char *field, const char *content)
+ {
+ iaddFieldQuotedString(field, content); return *this;
+ }
+ inline PerlModOutput &addFieldBoolean(const char *field, bool content)
+ {
+ return addFieldQuotedString(field, content ? "yes" : "no");
+ }
+ inline PerlModOutput &openList(const char *s = 0) { open('[', s); return *this; }
+ inline PerlModOutput &closeList() { close(']'); return *this; }
+ inline PerlModOutput &openHash(const char *s = 0 ) { open('{', s); return *this; }
+ inline PerlModOutput &closeHash() { close('}'); return *this; }
+
+protected:
+
+ void iopenSave();
+ void icloseSave(QCString &);
+
+ void incIndent();
+ void decIndent();
+
+ void iaddQuoted(const char *);
+ void iaddFieldQuotedChar(const char *, char);
+ void iaddFieldQuotedString(const char *, const char *);
+ void iaddField(const char *);
+
+ void iopen(char, const char *);
+ void iclose(char);
+
+private:
+
+ PerlModOutputStream *m_stream;
+ int m_indentation;
+ bool m_blockstart;
+
+ QStack<PerlModOutputStream> m_saved;
+ char m_spaces[PERLOUTPUT_MAX_INDENTATION * 2 + 2];
+};
+
+void PerlModOutput::iopenSave()
+{
+ m_saved.push(m_stream);
+ m_stream = new PerlModOutputStream();
+}
+
+void PerlModOutput::icloseSave(QCString &s)
+{
+ s = m_stream->m_s;
+ delete m_stream;
+ m_stream = m_saved.pop();
+}
+
+void PerlModOutput::incIndent()
+{
+ if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
+ {
+ char *s = &m_spaces[m_indentation * 2];
+ *s++ = ' '; *s++ = ' '; *s = 0;
+ }
+ m_indentation++;
+}
+
+void PerlModOutput::decIndent()
+{
+ m_indentation--;
+ if (m_indentation < PERLOUTPUT_MAX_INDENTATION)
+ m_spaces[m_indentation * 2] = 0;
+}
+
+void PerlModOutput::iaddQuoted(const char *s)
+{
+ char c;
+ while ((c = *s++) != 0) {
+ if ((c == '\'') || (c == '\\'))
+ m_stream->add('\\');
+ m_stream->add(c);
+ }
+}
+
+void PerlModOutput::iaddField(const char *s)
+{
+ continueBlock();
+ m_stream->add(s);
+ m_stream->add(m_pretty ? " => " : "=>");
+}
+
+void PerlModOutput::iaddFieldQuotedChar(const char *field, char content)
+{
+ iaddField(field);
+ m_stream->add('\'');
+ if ((content == '\'') || (content == '\\'))
+ m_stream->add('\\');
+ m_stream->add(content);
+ m_stream->add('\'');
+}
+
+void PerlModOutput::iaddFieldQuotedString(const char *field, const char *content)
+{
+ if (content == 0)
+ return;
+ iaddField(field);
+ m_stream->add('\'');
+ iaddQuoted(content);
+ m_stream->add('\'');
+}
+
+void PerlModOutput::iopen(char c, const char *s)
+{
+ if (s != 0)
+ iaddField(s);
+ else
+ continueBlock();
+ m_stream->add(c);
+ incIndent();
+ m_blockstart = true;
+}
+
+void PerlModOutput::iclose(char c)
+{
+ decIndent();
+ indent();
+ if (c != 0)
+ m_stream->add(c);
+ m_blockstart = false;
+}
+
+/*! @brief Concrete visitor implementation for PerlMod output. */
+class PerlModDocVisitor : public DocVisitor
+{
+public:
+ PerlModDocVisitor(PerlModOutput &);
+ virtual ~PerlModDocVisitor() { }
+
+ void finish();
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *) ;
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *);
+ void visitPost(DocHtmlList *) ;
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *);
+ void visitPost(DocHtmlTable *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *);
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ //void visitPre(DocLanguage *);
+ //void visitPost(DocLanguage *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+private:
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void addLink(const QCString &ref, const QCString &file,
+ const QCString &anchor);
+
+ void enterText();
+ void leaveText();
+
+ void openItem(const char *);
+ void closeItem();
+ void singleItem(const char *);
+ void openSubBlock(const char * = 0);
+ void closeSubBlock();
+ void openOther();
+ void closeOther();
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ PerlModOutput &m_output;
+ bool m_textmode;
+ bool m_textblockstart;
+ QCString m_other;
+};
+
+PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output)
+ : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false)
+{
+ m_output.openList("doc");
+}
+
+void PerlModDocVisitor::finish()
+{
+ leaveText();
+ m_output.closeList()
+ .add(m_other);
+}
+
+void PerlModDocVisitor::addLink(const QCString &,const QCString &file,const QCString &anchor)
+{
+ QCString link = file;
+ if (!anchor.isEmpty())
+ (link += "_1") += anchor;
+ m_output.addFieldQuotedString("link", link);
+}
+
+void PerlModDocVisitor::openItem(const char *name)
+{
+ leaveText();
+ m_output.openHash().addFieldQuotedString("type", name);
+}
+
+void PerlModDocVisitor::closeItem()
+{
+ leaveText();
+ m_output.closeHash();
+}
+
+void PerlModDocVisitor::enterText()
+{
+ if (m_textmode)
+ return;
+ openItem("text");
+ m_output.addField("content").add('\'');
+ m_textmode = true;
+}
+
+void PerlModDocVisitor::leaveText()
+{
+ if (!m_textmode)
+ return;
+ m_textmode = false;
+ m_output
+ .add('\'')
+ .closeHash();
+}
+
+void PerlModDocVisitor::singleItem(const char *name)
+{
+ openItem(name);
+ closeItem();
+}
+
+void PerlModDocVisitor::openSubBlock(const char *s)
+{
+ leaveText();
+ m_output.openList(s);
+ m_textblockstart = true;
+}
+
+void PerlModDocVisitor::closeSubBlock()
+{
+ leaveText();
+ m_output.closeList();
+}
+
+void PerlModDocVisitor::openOther()
+{
+ // Using a secondary text stream will corrupt the perl file. Instead of
+ // printing doc => [ data => [] ], it will print doc => [] data => [].
+ /*
+ leaveText();
+ m_output.openSave();
+ */
+}
+
+void PerlModDocVisitor::closeOther()
+{
+ // Using a secondary text stream will corrupt the perl file. Instead of
+ // printing doc => [ data => [] ], it will print doc => [] data => [].
+ /*
+ QCString other;
+ leaveText();
+ m_output.closeSave(other);
+ m_other += other;
+ */
+}
+
+void PerlModDocVisitor::visit(DocWord *w)
+{
+ enterText();
+ m_output.addQuoted(w->word());
+}
+
+void PerlModDocVisitor::visit(DocLinkedWord *w)
+{
+ openItem("url");
+ addLink(w->ref(), w->file(), w->anchor());
+ m_output.addFieldQuotedString("content", w->word());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocWhiteSpace *)
+{
+ enterText();
+ m_output.add(' ');
+}
+
+void PerlModDocVisitor::visit(DocSymbol *sy)
+{
+ const DocSymbol::PerlSymb *res = HtmlEntityMapper::instance()->perl(sy->symbol());
+ const char *accent=0;
+ if (res-> symb)
+ {
+ switch (res->type)
+ {
+ case DocSymbol::Perl_string:
+ enterText();
+ m_output.add(res->symb);
+ break;
+ case DocSymbol::Perl_char:
+ enterText();
+ m_output.add(res->symb[0]);
+ break;
+ case DocSymbol::Perl_symbol:
+ leaveText();
+ openItem("symbol");
+ m_output.addFieldQuotedString("symbol", res->symb);
+ closeItem();
+ break;
+ default:
+ switch(res->type)
+ {
+ case DocSymbol::Perl_umlaut:
+ accent = "umlaut";
+ break;
+ case DocSymbol::Perl_acute:
+ accent = "acute";
+ break;
+ case DocSymbol::Perl_grave:
+ accent = "grave";
+ break;
+ case DocSymbol::Perl_circ:
+ accent = "circ";
+ break;
+ case DocSymbol::Perl_slash:
+ accent = "slash";
+ break;
+ case DocSymbol::Perl_tilde:
+ accent = "tilde";
+ break;
+ case DocSymbol::Perl_cedilla:
+ accent = "cedilla";
+ break;
+ case DocSymbol::Perl_ring:
+ accent = "ring";
+ break;
+ default:
+ break;
+ }
+ leaveText();
+ if (accent)
+ {
+ openItem("accent");
+ m_output
+ .addFieldQuotedString("accent", accent)
+ .addFieldQuotedChar("letter", res->symb[0]);
+ closeItem();
+ }
+ break;
+ }
+ }
+ else
+ {
+ err("perl: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(sy->symbol(),TRUE));
+ }
+}
+
+void PerlModDocVisitor::visit(DocURL *u)
+{
+ openItem("url");
+ m_output.addFieldQuotedString("content", u->url());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocLineBreak *) { singleItem("linebreak"); }
+void PerlModDocVisitor::visit(DocHorRuler *) { singleItem("hruler"); }
+
+void PerlModDocVisitor::visit(DocStyleChange *s)
+{
+ const char *style = 0;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold: style = "bold"; break;
+ case DocStyleChange::Italic: style = "italic"; break;
+ case DocStyleChange::Code: style = "code"; break;
+ case DocStyleChange::Subscript: style = "subscript"; break;
+ case DocStyleChange::Superscript: style = "superscript"; break;
+ case DocStyleChange::Center: style = "center"; break;
+ case DocStyleChange::Small: style = "small"; break;
+ case DocStyleChange::Preformatted: style = "preformatted"; break;
+ case DocStyleChange::Div: style = "div"; break;
+ case DocStyleChange::Span: style = "span"; break;
+
+ }
+ openItem("style");
+ m_output.addFieldQuotedString("style", style)
+ .addFieldBoolean("enable", s->enable());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocVerbatim *s)
+{
+ const char *type = 0;
+ switch (s->type())
+ {
+ case DocVerbatim::Code:
+#if 0
+ m_output.add("<programlisting>");
+ parseCode(m_ci,s->context(),s->text(),FALSE,0);
+ m_output.add("</programlisting>");
+#endif
+ return;
+ case DocVerbatim::Verbatim: type = "preformatted"; break;
+ case DocVerbatim::HtmlOnly: type = "htmlonly"; break;
+ case DocVerbatim::RtfOnly: type = "rtfonly"; break;
+ case DocVerbatim::ManOnly: type = "manonly"; break;
+ case DocVerbatim::LatexOnly: type = "latexonly"; break;
+ case DocVerbatim::XmlOnly: type = "xmlonly"; break;
+ case DocVerbatim::DocbookOnly: type = "docbookonly"; break;
+ case DocVerbatim::Dot: type = "dot"; break;
+ case DocVerbatim::Msc: type = "msc"; break;
+ case DocVerbatim::PlantUML: type = "plantuml"; break;
+ }
+ openItem(type);
+ m_output.addFieldQuotedString("content", s->text());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocAnchor *anc)
+{
+ QCString anchor = anc->file() + "_1" + anc->anchor();
+ openItem("anchor");
+ m_output.addFieldQuotedString("id", anchor);
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocInclude *inc)
+{
+ const char *type = 0;
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ #if 0
+ {
+ m_t << "<div class=\"fragment\"><pre>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "</pre></div>";
+ }
+ break;
+ #endif
+ return;
+ case DocInclude::Include:
+#if 0
+ m_output.add("<programlisting>");
+ parseCode(m_ci,inc->context(),inc->text(),FALSE,0);
+ m_output.add("</programlisting>");
+#endif
+ return;
+ case DocInclude::DontInclude: return;
+ case DocInclude::HtmlInclude: type = "htmlonly"; break;
+ case DocInclude::LatexInclude: type = "latexonly"; break;
+ case DocInclude::VerbInclude: type = "preformatted"; break;
+ case DocInclude::Snippet: return;
+ }
+ openItem(type);
+ m_output.addFieldQuotedString("content", inc->text());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocIncOperator *)
+{
+#if 0
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ if (op->isFirst())
+ {
+ m_output.add("<programlisting>");
+ }
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ parseCode(m_ci,op->context(),op->text(),FALSE,0);
+ }
+ if (op->isLast())
+ {
+ m_output.add("</programlisting>");
+ }
+ else
+ {
+ m_output.add('\n');
+ }
+#endif
+}
+
+void PerlModDocVisitor::visit(DocFormula *f)
+{
+ openItem("formula");
+ QCString id;
+ id += f->id();
+ m_output.addFieldQuotedString("id", id).addFieldQuotedString("content", f->text());
+ closeItem();
+}
+
+void PerlModDocVisitor::visit(DocIndexEntry *)
+{
+#if 0
+ m_output.add("<indexentry>"
+ "<primaryie>");
+ m_output.addQuoted(ie->entry());
+ m_output.add("</primaryie>"
+ "<secondaryie></secondaryie>"
+ "</indexentry>");
+#endif
+}
+
+void PerlModDocVisitor::visit(DocSimpleSectSep *)
+{
+}
+
+void PerlModDocVisitor::visit(DocCite *cite)
+{
+ openItem("cite");
+ m_output.addFieldQuotedString("text", cite->text());
+ closeItem();
+}
+
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void PerlModDocVisitor::visitPre(DocAutoList *l)
+{
+ openItem("list");
+ m_output.addFieldQuotedString("style", l->isEnumList() ? "ordered" : "itemized");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocAutoList *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocAutoListItem *)
+{
+ openSubBlock();
+}
+
+void PerlModDocVisitor::visitPost(DocAutoListItem *)
+{
+ closeSubBlock();
+}
+
+void PerlModDocVisitor::visitPre(DocPara *)
+{
+ if (m_textblockstart)
+ m_textblockstart = false;
+ else
+ singleItem("parbreak");
+ /*
+ openItem("para");
+ openSubBlock("content");
+ */
+}
+
+void PerlModDocVisitor::visitPost(DocPara *)
+{
+ /*
+ closeSubBlock();
+ closeItem();
+ */
+}
+
+void PerlModDocVisitor::visitPre(DocRoot *)
+{
+}
+
+void PerlModDocVisitor::visitPost(DocRoot *)
+{
+}
+
+void PerlModDocVisitor::visitPre(DocSimpleSect *s)
+{
+ const char *type = 0;
+ switch (s->type())
+ {
+ case DocSimpleSect::See: type = "see"; break;
+ case DocSimpleSect::Return: type = "return"; break;
+ case DocSimpleSect::Author: type = "author"; break;
+ case DocSimpleSect::Authors: type = "authors"; break;
+ case DocSimpleSect::Version: type = "version"; break;
+ case DocSimpleSect::Since: type = "since"; break;
+ case DocSimpleSect::Date: type = "date"; break;
+ case DocSimpleSect::Note: type = "note"; break;
+ case DocSimpleSect::Warning: type = "warning"; break;
+ case DocSimpleSect::Pre: type = "pre"; break;
+ case DocSimpleSect::Post: type = "post"; break;
+ case DocSimpleSect::Copyright: type = "copyright"; break;
+ case DocSimpleSect::Invar: type = "invariant"; break;
+ case DocSimpleSect::Remark: type = "remark"; break;
+ case DocSimpleSect::Attention: type = "attention"; break;
+ case DocSimpleSect::User: type = "par"; break;
+ case DocSimpleSect::Rcs: type = "rcs"; break;
+ case DocSimpleSect::Unknown:
+ err("unknown simple section found\n");
+ break;
+ }
+ leaveText();
+ m_output.openHash();
+ openOther();
+ openSubBlock(type);
+}
+
+void PerlModDocVisitor::visitPost(DocSimpleSect *)
+{
+ closeSubBlock();
+ closeOther();
+ m_output.closeHash();
+}
+
+void PerlModDocVisitor::visitPre(DocTitle *)
+{
+ openItem("title");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocTitle *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocSimpleList *)
+{
+ openItem("list");
+ m_output.addFieldQuotedString("style", "itemized");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocSimpleList *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocSimpleListItem *) { openSubBlock(); }
+void PerlModDocVisitor::visitPost(DocSimpleListItem *) { closeSubBlock(); }
+
+void PerlModDocVisitor::visitPre(DocSection *s)
+{
+ QCString sect = QCString().sprintf("sect%d",s->level());
+ openItem(sect);
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocSection *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlList *l)
+{
+ openItem("list");
+ m_output.addFieldQuotedString("style", (l->type() == DocHtmlList::Ordered) ? "ordered" : "itemized");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlList *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlListItem *) { openSubBlock(); }
+void PerlModDocVisitor::visitPost(DocHtmlListItem *) { closeSubBlock(); }
+
+//void PerlModDocVisitor::visitPre(DocHtmlPre *)
+//{
+// openItem("preformatted");
+// openSubBlock("content");
+// //m_insidePre=TRUE;
+//}
+
+//void PerlModDocVisitor::visitPost(DocHtmlPre *)
+//{
+// //m_insidePre=FALSE;
+// closeSubBlock();
+// closeItem();
+//}
+
+void PerlModDocVisitor::visitPre(DocHtmlDescList *)
+{
+#if 0
+ m_output.add("<variablelist>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlDescList *)
+{
+#if 0
+ m_output.add("</variablelist>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+#if 0
+ m_output.add("<varlistentry><term>");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+#if 0
+ m_output.add("</term></varlistentry>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlDescData *)
+{
+#if 0
+ m_output.add("<listitem>");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlDescData *)
+{
+#if 0
+ m_output.add("</listitem>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlTable *)
+{
+#if 0
+ m_output.add("<table rows=\""); m_output.add(t->numRows());
+ m_output.add("\" cols=\""); m_output.add(t->numCols()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlTable *)
+{
+#if 0
+ m_output.add("</table>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlRow *)
+{
+#if 0
+ m_output.add("<row>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlRow *)
+{
+#if 0
+ m_output.add("</row>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlCell *)
+{
+#if 0
+ if (c->isHeading()) m_output.add("<entry thead=\"yes\">"); else m_output.add("<entry thead=\"no\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlCell *)
+{
+#if 0
+ m_output.add("</entry>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlCaption *)
+{
+#if 0
+ m_output.add("<caption>");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlCaption *)
+{
+#if 0
+ m_output.add("</caption>\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocInternal *)
+{
+#if 0
+ m_output.add("<internal>");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocInternal *)
+{
+#if 0
+ m_output.add("</internal>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHRef *)
+{
+#if 0
+ m_output.add("<ulink url=\""); m_output.add(href->url()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHRef *)
+{
+#if 0
+ m_output.add("</ulink>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlHeader *)
+{
+#if 0
+ m_output.add("<sect"); m_output.add(header->level()); m_output.add(">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlHeader *)
+{
+#if 0
+ m_output.add("</sect"); m_output.add(header->level()); m_output.add(">\n");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocImage *)
+{
+#if 0
+ m_output.add("<image type=\"");
+ switch(img->type())
+ {
+ case DocImage::Html: m_output.add("html"); break;
+ case DocImage::Latex: m_output.add("latex"); break;
+ case DocImage::Rtf: m_output.add("rtf"); break;
+ }
+ m_output.add("\"");
+
+ QCString baseName=img->name();
+ int i;
+ if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ m_output.add(" name=\""); m_output.add(baseName); m_output.add("\"");
+ if (!img->width().isEmpty())
+ {
+ m_output.add(" width=\"");
+ m_output.addQuoted(img->width());
+ m_output.add("\"");
+ }
+ else if (!img->height().isEmpty())
+ {
+ m_output.add(" height=\"");
+ m_output.addQuoted(img->height());
+ m_output.add("\"");
+ }
+ m_output.add(">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocImage *)
+{
+#if 0
+ m_output.add("</image>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocDotFile *)
+{
+#if 0
+ m_output.add("<dotfile name=\""); m_output.add(df->file()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocDotFile *)
+{
+#if 0
+ m_output.add("</dotfile>");
+#endif
+}
+void PerlModDocVisitor::visitPre(DocMscFile *)
+{
+#if 0
+ m_output.add("<mscfile name=\""); m_output.add(df->file()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocMscFile *)
+{
+#if 0
+ m_output.add("<mscfile>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocDiaFile *)
+{
+#if 0
+ m_output.add("<diafile name=\""); m_output.add(df->file()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocDiaFile *)
+{
+#if 0
+ m_output.add("</diafile>");
+#endif
+}
+
+
+void PerlModDocVisitor::visitPre(DocLink *lnk)
+{
+ openItem("link");
+ addLink(lnk->ref(), lnk->file(), lnk->anchor());
+}
+
+void PerlModDocVisitor::visitPost(DocLink *)
+{
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocRef *ref)
+{
+ openItem("ref");
+ if (!ref->hasLinkText())
+ m_output.addFieldQuotedString("text", ref->targetTitle());
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocRef *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocSecRefItem *)
+{
+#if 0
+ m_output.add("<tocitem id=\""); m_output.add(ref->file()); m_output.add("_1"); m_output.add(ref->anchor()); m_output.add("\">");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocSecRefItem *)
+{
+#if 0
+ m_output.add("</tocitem>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocSecRefList *)
+{
+#if 0
+ m_output.add("<toclist>");
+#endif
+}
+
+void PerlModDocVisitor::visitPost(DocSecRefList *)
+{
+#if 0
+ m_output.add("</toclist>");
+#endif
+}
+
+//void PerlModDocVisitor::visitPre(DocLanguage *l)
+//{
+// openItem("language");
+// m_output.addFieldQuotedString("id", l->id());
+//}
+//
+//void PerlModDocVisitor::visitPost(DocLanguage *)
+//{
+// closeItem();
+//}
+
+void PerlModDocVisitor::visitPre(DocParamSect *s)
+{
+ leaveText();
+ const char *type = 0;
+ switch(s->type())
+ {
+ case DocParamSect::Param: type = "params"; break;
+ case DocParamSect::RetVal: type = "retvals"; break;
+ case DocParamSect::Exception: type = "exceptions"; break;
+ case DocParamSect::TemplateParam: type = "templateparam"; break;
+ case DocParamSect::Unknown:
+ err("unknown parameter section found\n");
+ break;
+ }
+ openOther();
+ openSubBlock(type);
+}
+
+void PerlModDocVisitor::visitPost(DocParamSect *)
+{
+ closeSubBlock();
+ closeOther();
+}
+
+void PerlModDocVisitor::visitPre(DocParamList *pl)
+{
+ leaveText();
+ m_output.openHash()
+ .openList("parameters");
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ QCString s;
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ s = ((DocWord*)param)->word();
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ s = ((DocLinkedWord*)param)->word();
+ }
+ m_output.openHash()
+ .addFieldQuotedString("name", s)
+ .closeHash();
+ }
+ m_output.closeList()
+ .openList("doc");
+}
+
+void PerlModDocVisitor::visitPost(DocParamList *)
+{
+ leaveText();
+ m_output.closeList()
+ .closeHash();
+}
+
+void PerlModDocVisitor::visitPre(DocXRefItem *x)
+{
+#if 0
+ m_output.add("<xrefsect id=\"");
+ m_output.add(x->file()); m_output.add("_1"); m_output.add(x->anchor());
+ m_output.add("\">");
+ m_output.add("<xreftitle>");
+ m_output.addQuoted(x->title());
+ m_output.add("</xreftitle>");
+ m_output.add("<xrefdescription>");
+#endif
+ if (x->title().isEmpty()) return;
+ openItem("xrefitem");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (x->title().isEmpty()) return;
+ closeSubBlock();
+ closeItem();
+#if 0
+ m_output.add("</xrefdescription>");
+ m_output.add("</xrefsect>");
+#endif
+}
+
+void PerlModDocVisitor::visitPre(DocInternalRef *ref)
+{
+ openItem("ref");
+ addLink(0,ref->file(),ref->anchor());
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocInternalRef *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocCopy *)
+{
+}
+
+void PerlModDocVisitor::visitPost(DocCopy *)
+{
+}
+
+void PerlModDocVisitor::visitPre(DocText *)
+{
+}
+
+void PerlModDocVisitor::visitPost(DocText *)
+{
+}
+
+void PerlModDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ openItem("blockquote");
+ openSubBlock("content");
+}
+
+void PerlModDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ closeSubBlock();
+ closeItem();
+}
+
+void PerlModDocVisitor::visitPre(DocVhdlFlow *)
+{
+}
+
+void PerlModDocVisitor::visitPost(DocVhdlFlow *)
+{
+}
+
+void PerlModDocVisitor::visitPre(DocParBlock *)
+{
+}
+
+void PerlModDocVisitor::visitPost(DocParBlock *)
+{
+}
+
+
+static void addTemplateArgumentList(ArgumentList *al,PerlModOutput &output,const char *)
+{
+ QCString indentStr;
+ if (!al)
+ return;
+ output.openList("template_parameters");
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ output.openHash();
+ if (!a->type.isEmpty())
+ output.addFieldQuotedString("type", a->type);
+ if (!a->name.isEmpty())
+ output.addFieldQuotedString("declaration_name", a->name)
+ .addFieldQuotedString("definition_name", a->name);
+ if (!a->defval.isEmpty())
+ output.addFieldQuotedString("default", a->defval);
+ output.closeHash();
+ }
+ output.closeList();
+}
+
+#if 0
+static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output)
+{
+ ClassDef *cd = md->getClassDef();
+ const char *cname = cd ? cd->name().data() : 0;
+ if (md->templateArguments()) // function template prefix
+ addTemplateArgumentList(md->templateArguments(),output,cname);
+}
+#endif
+
+static void addTemplateList(ClassDef *cd,PerlModOutput &output)
+{
+ addTemplateArgumentList(cd->templateArguments(),output,cd->name());
+}
+
+static void addPerlModDocBlock(PerlModOutput &output,
+ const char *name,
+ const QCString &fileName,
+ int lineNr,
+ Definition *scope,
+ MemberDef *md,
+ const QCString &text)
+{
+ QCString stext = text.stripWhiteSpace();
+ if (stext.isEmpty())
+ output.addField(name).add("{}");
+ else {
+ DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,0);
+ output.openHash(name);
+ PerlModDocVisitor *visitor = new PerlModDocVisitor(output);
+ root->accept(visitor);
+ visitor->finish();
+ output.closeHash();
+ delete visitor;
+ delete root;
+ }
+}
+
+static const char *getProtectionName(Protection prot)
+{
+ switch (prot)
+ {
+ case Public: return "public";
+ case Protected: return "protected";
+ case Private: return "private";
+ case Package: return "package";
+ }
+ return 0;
+}
+
+static const char *getVirtualnessName(Specifier virt)
+{
+ switch(virt)
+ {
+ case Normal: return "non_virtual";
+ case Virtual: return "virtual";
+ case Pure: return "pure_virtual";
+ }
+ return 0;
+}
+
+static QCString pathDoxyfile;
+static QCString pathDoxyExec;
+
+void setPerlModDoxyfile(const QCString &qs)
+{
+ pathDoxyfile = qs;
+ pathDoxyExec = QDir::currentDirPath().utf8();
+}
+
+class PerlModGenerator
+{
+public:
+
+ PerlModOutput m_output;
+
+ QCString pathDoxyStructurePM;
+ QCString pathDoxyDocsTex;
+ QCString pathDoxyFormatTex;
+ QCString pathDoxyLatexTex;
+ QCString pathDoxyLatexDVI;
+ QCString pathDoxyLatexPDF;
+ QCString pathDoxyStructureTex;
+ QCString pathDoxyDocsPM;
+ QCString pathDoxyLatexPL;
+ QCString pathDoxyLatexStructurePL;
+ QCString pathDoxyRules;
+ QCString pathMakefile;
+
+ inline PerlModGenerator(bool pretty) : m_output(pretty) { }
+
+ void generatePerlModForMember(MemberDef *md, Definition *);
+ void generatePerlModSection(Definition *d, MemberList *ml,
+ const char *name, const char *header=0);
+ void addListOfAllMembers(ClassDef *cd);
+ void generatePerlModForClass(ClassDef *cd);
+ void generatePerlModForNamespace(NamespaceDef *nd);
+ void generatePerlModForFile(FileDef *fd);
+ void generatePerlModForGroup(GroupDef *gd);
+ void generatePerlModForPage(PageDef *pi);
+
+ bool createOutputFile(QFile &f, const char *s);
+ bool createOutputDir(QDir &perlModDir);
+ bool generateDoxyLatexTex();
+ bool generateDoxyFormatTex();
+ bool generateDoxyStructurePM();
+ bool generateDoxyLatexPL();
+ bool generateDoxyLatexStructurePL();
+ bool generateDoxyRules();
+ bool generateMakefile();
+ bool generatePerlModOutput();
+
+ void generate();
+};
+
+void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *)
+{
+ // + declaration/definition arg lists
+ // + reimplements
+ // + reimplementedBy
+ // + exceptions
+ // + const/volatile specifiers
+ // - examples
+ // - source definition
+ // - source references
+ // - source referenced by
+ // - body code
+ // - template arguments
+ // (templateArguments(), definitionTemplateParameterLists())
+
+ QCString memType;
+ bool isFunc=FALSE;
+ switch (md->memberType())
+ {
+ case MemberType_Define: memType="define"; break;
+ case MemberType_EnumValue: memType="enumvalue"; break;
+ case MemberType_Property: memType="property"; break;
+ case MemberType_Variable: memType="variable"; break;
+ case MemberType_Typedef: memType="typedef"; break;
+ case MemberType_Enumeration: memType="enum"; break;
+ case MemberType_Function: memType="function"; isFunc=TRUE; break;
+ case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
+ //case MemberType_Prototype: memType="prototype"; isFunc=TRUE; break;
+ case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
+ case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
+ case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
+ case MemberType_Event: memType="event"; break;
+ case MemberType_Interface: memType="interface"; break;
+ case MemberType_Service: memType="service"; break;
+ }
+
+ m_output.openHash()
+ .addFieldQuotedString("kind", memType)
+ .addFieldQuotedString("name", md->name())
+ .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
+ .addFieldQuotedString("protection", getProtectionName(md->protection()))
+ .addFieldBoolean("static", md->isStatic());
+
+ addPerlModDocBlock(m_output,"brief",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->briefDescription());
+ addPerlModDocBlock(m_output,"detailed",md->getDefFileName(),md->getDefLine(),md->getOuterScope(),md,md->documentation());
+ if (md->memberType()!=MemberType_Define &&
+ md->memberType()!=MemberType_Enumeration)
+ m_output.addFieldQuotedString("type", md->typeString());
+
+ ArgumentList *al = md->argumentList();
+ if (isFunc) //function
+ {
+ m_output.addFieldBoolean("const", al!=0 && al->constSpecifier)
+ .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier);
+
+ m_output.openList("parameters");
+ ArgumentList *declAl = md->declArgumentList();
+ ArgumentList *defAl = md->argumentList();
+ if (declAl && declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ Argument *defArg = defAli.current();
+ m_output.openHash();
+
+ if (!a->name.isEmpty())
+ m_output.addFieldQuotedString("declaration_name", a->name);
+
+ if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
+ m_output.addFieldQuotedString("definition_name", defArg->name);
+
+ if (!a->type.isEmpty())
+ m_output.addFieldQuotedString("type", a->type);
+
+ if (!a->array.isEmpty())
+ m_output.addFieldQuotedString("array", a->array);
+
+ if (!a->defval.isEmpty())
+ m_output.addFieldQuotedString("default_value", a->defval);
+
+ if (!a->attrib.isEmpty())
+ m_output.addFieldQuotedString("attributes", a->attrib);
+
+ m_output.closeHash();
+ if (defArg) ++defAli;
+ }
+ }
+ m_output.closeList();
+ }
+ else if (md->memberType()==MemberType_Define &&
+ md->argsString()!=0) // define
+ {
+ m_output.openList("parameters");
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ m_output.openHash()
+ .addFieldQuotedString("name", a->type)
+ .closeHash();
+ }
+ m_output.closeList();
+ }
+ else if (md->argsString()!=0)
+ {
+ m_output.addFieldQuotedString("arguments", md->argsString());
+ }
+
+ if (!md->initializer().isEmpty())
+ m_output.addFieldQuotedString("initializer", md->initializer());
+
+ if (md->excpString())
+ m_output.addFieldQuotedString("exceptions", md->excpString());
+
+ if (md->memberType()==MemberType_Enumeration) // enum
+ {
+ MemberList *enumFields = md->enumFieldList();
+ if (enumFields)
+ {
+ m_output.openList("values");
+ MemberListIterator emli(*enumFields);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ m_output.openHash()
+ .addFieldQuotedString("name", emd->name());
+
+ if (!emd->initializer().isEmpty())
+ m_output.addFieldQuotedString("initializer", emd->initializer());
+
+ addPerlModDocBlock(m_output,"brief",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->briefDescription());
+
+ addPerlModDocBlock(m_output,"detailed",emd->getDefFileName(),emd->getDefLine(),emd->getOuterScope(),emd,emd->documentation());
+
+ m_output.closeHash();
+ }
+ m_output.closeList();
+ }
+ }
+
+ MemberDef *rmd = md->reimplements();
+ if (rmd)
+ m_output.openHash("reimplements")
+ .addFieldQuotedString("name", rmd->name())
+ .closeHash();
+
+ MemberList *rbml = md->reimplementedBy();
+ if (rbml)
+ {
+ MemberListIterator mli(*rbml);
+ m_output.openList("reimplemented_by");
+ for (mli.toFirst();(rmd=mli.current());++mli)
+ m_output.openHash()
+ .addFieldQuotedString("name", rmd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ m_output.closeHash();
+}
+
+void PerlModGenerator::generatePerlModSection(Definition *d,
+ MemberList *ml,const char *name,const char *header)
+{
+ if (ml==0) return; // empty list
+
+ m_output.openHash(name);
+
+ if (header)
+ m_output.addFieldQuotedString("header", header);
+
+ m_output.openList("members");
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ generatePerlModForMember(md,d);
+ }
+ m_output.closeList()
+ .closeHash();
+}
+
+void PerlModGenerator::addListOfAllMembers(ClassDef *cd)
+{
+ m_output.openList("all_members");
+ if (cd->memberNameInfoSDict())
+ {
+ MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberNameInfoIterator mii(*mni);
+ MemberInfo *mi;
+ for (mii.toFirst();(mi=mii.current());++mii)
+ {
+ MemberDef *md=mi->memberDef;
+ ClassDef *cd=md->getClassDef();
+ Definition *d=md->getGroupDef();
+ if (d==0) d = cd;
+
+ m_output.openHash()
+ .addFieldQuotedString("name", md->name())
+ .addFieldQuotedString("virtualness", getVirtualnessName(md->virtualness()))
+ .addFieldQuotedString("protection", getProtectionName(mi->prot));
+
+ if (!mi->ambiguityResolutionScope.isEmpty())
+ m_output.addFieldQuotedString("ambiguity_scope", mi->ambiguityResolutionScope);
+
+ m_output.addFieldQuotedString("scope", cd->name())
+ .closeHash();
+ }
+ }
+ }
+ m_output.closeList();
+}
+
+void PerlModGenerator::generatePerlModForClass(ClassDef *cd)
+{
+ // + brief description
+ // + detailed description
+ // + template argument list(s)
+ // - include file
+ // + member groups
+ // + inheritance diagram
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + list of inner classes
+ // + collaboration diagram
+ // + list of all members
+ // + user defined member sections
+ // + standard member sections
+ // + detailed member documentation
+ // - examples using the class
+
+ if (cd->isReference()) return; // skip external references.
+ if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
+ if (cd->templateMaster()!=0) return; // skip generated template instances.
+
+ m_output.openHash()
+ .addFieldQuotedString("name", cd->name());
+
+ if (cd->baseClasses())
+ {
+ m_output.openList("base");
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ m_output.openHash()
+ .addFieldQuotedString("name", bcd->classDef->displayName())
+ .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
+ .addFieldQuotedString("protection", getProtectionName(bcd->prot))
+ .closeHash();
+ m_output.closeList();
+ }
+
+ if (cd->subClasses())
+ {
+ m_output.openList("derived");
+ BaseClassListIterator bcli(*cd->subClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ m_output.openHash()
+ .addFieldQuotedString("name", bcd->classDef->displayName())
+ .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
+ .addFieldQuotedString("protection", getProtectionName(bcd->prot))
+ .closeHash();
+ m_output.closeList();
+ }
+
+ ClassSDict *cl = cd->getClassSDict();
+ if (cl)
+ {
+ m_output.openList("inner");
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ m_output.openHash()
+ .addFieldQuotedString("name", cd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ IncludeInfo *ii=cd->includeInfo();
+ if (ii)
+ {
+ QCString nm = ii->includeName;
+ if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
+ if (!nm.isEmpty())
+ {
+ m_output.openHash("includes");
+#if 0
+ if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
+ t << " id=\"" << ii->fileDef->getOutputFileBase() << "\"";
+#endif
+ m_output.addFieldBoolean("local", ii->local)
+ .addFieldQuotedString("name", nm)
+ .closeHash();
+ }
+ }
+
+ addTemplateList(cd,m_output);
+ addListOfAllMembers(cd);
+ if (cd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ generatePerlModSection(cd,mg->members(),"user_defined",mg->header());
+ }
+
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubTypes),"public_typedefs");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubMethods),"public_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubAttribs),"public_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubSlots),"public_slots");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_signals),"signals");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_dcopMethods),"dcop_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_properties),"properties");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubStaticMethods),"public_static_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_pubStaticAttribs),"public_static_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proTypes),"protected_typedefs");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proMethods),"protected_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proAttribs),"protected_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proSlots),"protected_slots");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proStaticMethods),"protected_static_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_proStaticAttribs),"protected_static_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priTypes),"private_typedefs");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priMethods),"private_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priAttribs),"private_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priSlots),"private_slots");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priStaticMethods),"private_static_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_priStaticAttribs),"private_static_members");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_friends),"friend_methods");
+ generatePerlModSection(cd,cd->getMemberList(MemberListType_related),"related_methods");
+
+ addPerlModDocBlock(m_output,"brief",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->briefDescription());
+ addPerlModDocBlock(m_output,"detailed",cd->getDefFileName(),cd->getDefLine(),cd,0,cd->documentation());
+
+#if 0
+ DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance);
+ if (!inheritanceGraph.isTrivial())
+ {
+ t << " <inheritancegraph>" << endl;
+ inheritanceGraph.writePerlMod(t);
+ t << " </inheritancegraph>" << endl;
+ }
+ DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation);
+ if (!collaborationGraph.isTrivial())
+ {
+ t << " <collaborationgraph>" << endl;
+ collaborationGraph.writePerlMod(t);
+ t << " </collaborationgraph>" << endl;
+ }
+ t << " <location file=\""
+ << cd->getDefFileName() << "\" line=\""
+ << cd->getDefLine() << "\"";
+ if (cd->getStartBodyLine()!=-1)
+ {
+ t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
+ << cd->getEndBodyLine() << "\"";
+ }
+ t << "/>" << endl;
+#endif
+
+ m_output.closeHash();
+}
+
+void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd)
+{
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // + location
+ // - files containing (parts of) the namespace definition
+
+ if (nd->isReference()) return; // skip external references
+
+ m_output.openHash()
+ .addFieldQuotedString("name", nd->name());
+
+ ClassSDict *cl = nd->getClassSDict();
+ if (cl)
+ {
+ m_output.openList("classes");
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ m_output.openHash()
+ .addFieldQuotedString("name", cd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ NamespaceSDict *nl = nd->getNamespaceSDict();
+ if (nl)
+ {
+ m_output.openList("namespaces");
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ m_output.openHash()
+ .addFieldQuotedString("name", nd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ if (nd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ generatePerlModSection(nd,mg->members(),"user-defined",mg->header());
+ }
+
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decDefineMembers),"defines");
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decProtoMembers),"prototypes");
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decTypedefMembers),"typedefs");
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decEnumMembers),"enums");
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decFuncMembers),"functions");
+ generatePerlModSection(nd,nd->getMemberList(MemberListType_decVarMembers),"variables");
+
+ addPerlModDocBlock(m_output,"brief",nd->getDefFileName(),nd->getDefLine(),0,0,nd->briefDescription());
+ addPerlModDocBlock(m_output,"detailed",nd->getDefFileName(),nd->getDefLine(),0,0,nd->documentation());
+
+ m_output.closeHash();
+}
+
+void PerlModGenerator::generatePerlModForFile(FileDef *fd)
+{
+ // + includes files
+ // + includedby files
+ // - include graph
+ // - included by graph
+ // - contained class definitions
+ // - contained namespace definitions
+ // - member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // - source code
+ // - location
+ // - number of lines
+
+ if (fd->isReference()) return;
+
+ m_output.openHash()
+ .addFieldQuotedString("name", fd->name());
+
+ IncludeInfo *inc;
+ m_output.openList("includes");
+ if (fd->includeFileList())
+ {
+ QListIterator<IncludeInfo> ili1(*fd->includeFileList());
+ for (ili1.toFirst();(inc=ili1.current());++ili1)
+ {
+ m_output.openHash()
+ .addFieldQuotedString("name", inc->includeName);
+ if (inc->fileDef && !inc->fileDef->isReference())
+ {
+ m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
+ }
+ m_output.closeHash();
+ }
+ }
+ m_output.closeList();
+
+ m_output.openList("included_by");
+ if (fd->includedByFileList())
+ {
+ QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
+ for (ili2.toFirst();(inc=ili2.current());++ili2)
+ {
+ m_output.openHash()
+ .addFieldQuotedString("name", inc->includeName);
+ if (inc->fileDef && !inc->fileDef->isReference())
+ {
+ m_output.addFieldQuotedString("ref", inc->fileDef->getOutputFileBase());
+ }
+ m_output.closeHash();
+ }
+ }
+ m_output.closeList();
+
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decDefineMembers),"defines");
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decProtoMembers),"prototypes");
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decTypedefMembers),"typedefs");
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decEnumMembers),"enums");
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decFuncMembers),"functions");
+ generatePerlModSection(fd,fd->getMemberList(MemberListType_decVarMembers),"variables");
+
+ addPerlModDocBlock(m_output,"brief",fd->getDefFileName(),fd->getDefLine(),0,0,fd->briefDescription());
+ addPerlModDocBlock(m_output,"detailed",fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation());
+
+ m_output.closeHash();
+}
+
+void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
+{
+ // + members
+ // + member groups
+ // + files
+ // + classes
+ // + namespaces
+ // - packages
+ // + pages
+ // + child groups
+ // - examples
+ // + brief description
+ // + detailed description
+
+ if (gd->isReference()) return; // skip external references
+
+ m_output.openHash()
+ .addFieldQuotedString("name", gd->name())
+ .addFieldQuotedString("title", gd->groupTitle());
+
+ FileList *fl = gd->getFiles();
+ if (fl)
+ {
+ m_output.openList("files");
+ QListIterator<FileDef> fli(*fl);
+ FileDef *fd;
+ for (fli.toFirst();(fd=fli.current());++fli)
+ m_output.openHash()
+ .addFieldQuotedString("name", fd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ ClassSDict *cl = gd->getClasses();
+ if (cl)
+ {
+ m_output.openList("classes");
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ m_output.openHash()
+ .addFieldQuotedString("name", cd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ NamespaceSDict *nl = gd->getNamespaces();
+ if (nl)
+ {
+ m_output.openList("namespaces");
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ m_output.openHash()
+ .addFieldQuotedString("name", nd->name())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ PageSDict *pl = gd->getPages();
+ if (pl)
+ {
+ m_output.openList("pages");
+ PageSDict::Iterator pli(*pl);
+ PageDef *pd;
+ for (pli.toFirst();(pd=pli.current());++pli)
+ m_output.openHash()
+ .addFieldQuotedString("title", pd->title())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ GroupList *gl = gd->getSubGroups();
+ if (gl)
+ {
+ m_output.openList("groups");
+ GroupListIterator gli(*gl);
+ GroupDef *sgd;
+ for (gli.toFirst();(sgd=gli.current());++gli)
+ m_output.openHash()
+ .addFieldQuotedString("title", sgd->groupTitle())
+ .closeHash();
+ m_output.closeList();
+ }
+
+ if (gd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ generatePerlModSection(gd,mg->members(),"user-defined",mg->header());
+ }
+
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decDefineMembers),"defines");
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decProtoMembers),"prototypes");
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decTypedefMembers),"typedefs");
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decEnumMembers),"enums");
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decFuncMembers),"functions");
+ generatePerlModSection(gd,gd->getMemberList(MemberListType_decVarMembers),"variables");
+
+ addPerlModDocBlock(m_output,"brief",gd->getDefFileName(),gd->getDefLine(),0,0,gd->briefDescription());
+ addPerlModDocBlock(m_output,"detailed",gd->getDefFileName(),gd->getDefLine(),0,0,gd->documentation());
+
+ m_output.closeHash();
+}
+
+void PerlModGenerator::generatePerlModForPage(PageDef *pd)
+{
+ // + name
+ // + title
+ // + documentation
+
+ if (pd->isReference()) return;
+
+ m_output.openHash()
+ .addFieldQuotedString("name", pd->name());
+
+ SectionInfo *si = Doxygen::sectionDict->find(pd->name());
+ if (si)
+ m_output.addFieldQuotedString("title4", filterTitle(si->title));
+
+ addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation());
+ m_output.closeHash();
+}
+
+bool PerlModGenerator::generatePerlModOutput()
+{
+ QFile outputFile;
+ if (!createOutputFile(outputFile, pathDoxyDocsPM))
+ return false;
+
+ FTextStream outputTextStream(&outputFile);
+ PerlModOutputStream outputStream(&outputTextStream);
+ m_output.setPerlModOutputStream(&outputStream);
+ m_output.add("$doxydocs=").openHash();
+
+ m_output.openList("classes");
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ generatePerlModForClass(cd);
+ m_output.closeList();
+
+ m_output.openList("namespaces");
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ generatePerlModForNamespace(nd);
+ m_output.closeList();
+
+ m_output.openList("files");
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ generatePerlModForFile(fd);
+ }
+ m_output.closeList();
+
+ m_output.openList("groups");
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (;(gd=gli.current());++gli)
+ {
+ generatePerlModForGroup(gd);
+ }
+ m_output.closeList();
+
+ m_output.openList("pages");
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ generatePerlModForPage(pd);
+ }
+ if (Doxygen::mainPage)
+ {
+ generatePerlModForPage(Doxygen::mainPage);
+ }
+ m_output.closeList();
+
+ m_output.closeHash().add(";\n1;\n");
+ return true;
+}
+
+bool PerlModGenerator::createOutputFile(QFile &f, const char *s)
+{
+ f.setName(s);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n", s);
+ return false;
+ }
+ return true;
+}
+
+bool PerlModGenerator::createOutputDir(QDir &perlModDir)
+{
+ QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
+ if (outputDirectory.isEmpty())
+ {
+ outputDirectory=QDir::currentDirPath().utf8();
+ }
+ else
+ {
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("tag OUTPUT_DIRECTORY: Output directory `%s' does not "
+ "exist and cannot be created\n",outputDirectory.data());
+ exit(1);
+ }
+ else
+ {
+ msg("Notice: Output directory `%s' does not exist. "
+ "I have created it for you.\n", outputDirectory.data());
+ }
+ dir.cd(outputDirectory);
+ }
+ outputDirectory=dir.absPath().utf8();
+ }
+
+ QDir dir(outputDirectory);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(outputDirectory))
+ {
+ err("Cannot create directory %s\n",outputDirectory.data());
+ return false;
+ }
+ }
+
+ perlModDir.setPath(outputDirectory+"/perlmod");
+ if (!perlModDir.exists() && !perlModDir.mkdir(outputDirectory+"/perlmod"))
+ {
+ err("Could not create perlmod directory in %s\n",outputDirectory.data());
+ return false;
+ }
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyStructurePM()
+{
+ QFile doxyModelPM;
+ if (!createOutputFile(doxyModelPM, pathDoxyStructurePM))
+ return false;
+
+ FTextStream doxyModelPMStream(&doxyModelPM);
+ doxyModelPMStream <<
+ "sub memberlist($) {\n"
+ " my $prefix = $_[0];\n"
+ " return\n"
+ "\t[ \"hash\", $prefix . \"s\",\n"
+ "\t {\n"
+ "\t members =>\n"
+ "\t [ \"list\", $prefix . \"List\",\n"
+ "\t\t[ \"hash\", $prefix,\n"
+ "\t\t {\n"
+ "\t\t kind => [ \"string\", $prefix . \"Kind\" ],\n"
+ "\t\t name => [ \"string\", $prefix . \"Name\" ],\n"
+ "\t\t static => [ \"string\", $prefix . \"Static\" ],\n"
+ "\t\t virtualness => [ \"string\", $prefix . \"Virtualness\" ],\n"
+ "\t\t protection => [ \"string\", $prefix . \"Protection\" ],\n"
+ "\t\t type => [ \"string\", $prefix . \"Type\" ],\n"
+ "\t\t parameters =>\n"
+ "\t\t [ \"list\", $prefix . \"Params\",\n"
+ "\t\t\t[ \"hash\", $prefix . \"Param\",\n"
+ "\t\t\t {\n"
+ "\t\t\t declaration_name => [ \"string\", $prefix . \"ParamName\" ],\n"
+ "\t\t\t type => [ \"string\", $prefix . \"ParamType\" ],\n"
+ "\t\t\t },\n"
+ "\t\t\t],\n"
+ "\t\t ],\n"
+ "\t\t detailed =>\n"
+ "\t\t [ \"hash\", $prefix . \"Detailed\",\n"
+ "\t\t\t{\n"
+ "\t\t\t doc => [ \"doc\", $prefix . \"DetailedDoc\" ],\n"
+ "\t\t\t return => [ \"doc\", $prefix . \"Return\" ],\n"
+ "\t\t\t see => [ \"doc\", $prefix . \"See\" ],\n"
+ "\t\t\t params =>\n"
+ "\t\t\t [ \"list\", $prefix . \"PDBlocks\",\n"
+ "\t\t\t [ \"hash\", $prefix . \"PDBlock\",\n"
+ "\t\t\t\t{\n"
+ "\t\t\t\t parameters =>\n"
+ "\t\t\t\t [ \"list\", $prefix . \"PDParams\",\n"
+ "\t\t\t\t [ \"hash\", $prefix . \"PDParam\",\n"
+ "\t\t\t\t\t{\n"
+ "\t\t\t\t\t name => [ \"string\", $prefix . \"PDParamName\" ],\n"
+ "\t\t\t\t\t},\n"
+ "\t\t\t\t ],\n"
+ "\t\t\t\t ],\n"
+ "\t\t\t\t doc => [ \"doc\", $prefix . \"PDDoc\" ],\n"
+ "\t\t\t\t},\n"
+ "\t\t\t ],\n"
+ "\t\t\t ],\n"
+ "\t\t\t},\n"
+ "\t\t ],\n"
+ "\t\t },\n"
+ "\t\t],\n"
+ "\t ],\n"
+ "\t },\n"
+ "\t];\n"
+ "}\n"
+ "\n"
+ "$doxystructure =\n"
+ " [ \"hash\", \"Root\",\n"
+ " {\n"
+ "\tfiles =>\n"
+ "\t [ \"list\", \"Files\",\n"
+ "\t [ \"hash\", \"File\",\n"
+ "\t {\n"
+ "\t\tname => [ \"string\", \"FileName\" ],\n"
+ "\t\ttypedefs => memberlist(\"FileTypedef\"),\n"
+ "\t\tvariables => memberlist(\"FileVariable\"),\n"
+ "\t\tfunctions => memberlist(\"FileFunction\"),\n"
+ "\t\tdetailed =>\n"
+ "\t\t [ \"hash\", \"FileDetailed\",\n"
+ "\t\t {\n"
+ "\t\t doc => [ \"doc\", \"FileDetailedDoc\" ],\n"
+ "\t\t },\n"
+ "\t\t ],\n"
+ "\t },\n"
+ "\t ],\n"
+ "\t ],\n"
+ "\tpages =>\n"
+ "\t [ \"list\", \"Pages\",\n"
+ "\t [ \"hash\", \"Page\",\n"
+ "\t {\n"
+ "\t\tname => [ \"string\", \"PageName\" ],\n"
+ "\t\tdetailed =>\n"
+ "\t\t [ \"hash\", \"PageDetailed\",\n"
+ "\t\t {\n"
+ "\t\t doc => [ \"doc\", \"PageDetailedDoc\" ],\n"
+ "\t\t },\n"
+ "\t\t ],\n"
+ "\t },\n"
+ "\t ],\n"
+ "\t ],\n"
+ "\tclasses =>\n"
+ "\t [ \"list\", \"Classes\",\n"
+ "\t [ \"hash\", \"Class\",\n"
+ "\t {\n"
+ "\t\tname => [ \"string\", \"ClassName\" ],\n"
+ "\t\tpublic_typedefs => memberlist(\"ClassPublicTypedef\"),\n"
+ "\t\tpublic_methods => memberlist(\"ClassPublicMethod\"),\n"
+ "\t\tpublic_members => memberlist(\"ClassPublicMember\"),\n"
+ "\t\tprotected_typedefs => memberlist(\"ClassProtectedTypedef\"),\n"
+ "\t\tprotected_methods => memberlist(\"ClassProtectedMethod\"),\n"
+ "\t\tprotected_members => memberlist(\"ClassProtectedMember\"),\n"
+ "\t\tprivate_typedefs => memberlist(\"ClassPrivateTypedef\"),\n"
+ "\t\tprivate_methods => memberlist(\"ClassPrivateMethod\"),\n"
+ "\t\tprivate_members => memberlist(\"ClassPrivateMember\"),\n"
+ "\t\tdetailed =>\n"
+ "\t\t [ \"hash\", \"ClassDetailed\",\n"
+ "\t\t {\n"
+ "\t\t doc => [ \"doc\", \"ClassDetailedDoc\" ],\n"
+ "\t\t },\n"
+ "\t\t ],\n"
+ "\t },\n"
+ "\t ],\n"
+ "\t ],\n"
+ "\tgroups =>\n"
+ "\t [ \"list\", \"Groups\",\n"
+ "\t [ \"hash\", \"Group\",\n"
+ "\t {\n"
+ "\t\tname => [ \"string\", \"GroupName\" ],\n"
+ "\t\ttitle => [ \"string\", \"GroupTitle\" ],\n"
+ "\t\tfiles =>\n"
+ "\t\t [ \"list\", \"Files\",\n"
+ "\t\t [ \"hash\", \"File\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"Filename\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tclasses =>\n"
+ "\t\t [ \"list\", \"Classes\",\n"
+ "\t\t [ \"hash\", \"Class\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"Classname\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tnamespaces =>\n"
+ "\t\t [ \"list\", \"Namespaces\",\n"
+ "\t\t [ \"hash\", \"Namespace\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"NamespaceName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tpages =>\n"
+ "\t\t [ \"list\", \"Pages\",\n"
+ "\t\t [ \"hash\", \"Page\","
+ "\t\t {\n"
+ "\t\t title => [ \"string\", \"PageName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tgroups =>\n"
+ "\t\t [ \"list\", \"Groups\",\n"
+ "\t\t [ \"hash\", \"Group\",\n"
+ "\t\t {\n"
+ "\t\t title => [ \"string\", \"GroupName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tfunctions => memberlist(\"GroupFunction\"),\n"
+ "\t\tdetailed =>\n"
+ "\t\t [ \"hash\", \"GroupDetailed\",\n"
+ "\t\t {\n"
+ "\t\t doc => [ \"doc\", \"GroupDetailedDoc\" ],\n"
+ "\t\t },\n"
+ "\t\t ],\n"
+ "\t }\n"
+ "\t ],\n"
+ "\t ],\n"
+ " },\n"
+ " ];\n"
+ "\n"
+ "1;\n";
+
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyRules()
+{
+ QFile doxyRules;
+ if (!createOutputFile(doxyRules, pathDoxyRules))
+ return false;
+
+ bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
+ QCString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
+
+ FTextStream doxyRulesStream(&doxyRules);
+ doxyRulesStream <<
+ prefix << "DOXY_EXEC_PATH = " << pathDoxyExec << "\n" <<
+ prefix << "DOXYFILE = " << pathDoxyfile << "\n" <<
+ prefix << "DOXYDOCS_PM = " << pathDoxyDocsPM << "\n" <<
+ prefix << "DOXYSTRUCTURE_PM = " << pathDoxyStructurePM << "\n" <<
+ prefix << "DOXYRULES = " << pathDoxyRules << "\n";
+ if (perlmodLatex)
+ doxyRulesStream <<
+ prefix << "DOXYLATEX_PL = " << pathDoxyLatexPL << "\n" <<
+ prefix << "DOXYLATEXSTRUCTURE_PL = " << pathDoxyLatexStructurePL << "\n" <<
+ prefix << "DOXYSTRUCTURE_TEX = " << pathDoxyStructureTex << "\n" <<
+ prefix << "DOXYDOCS_TEX = " << pathDoxyDocsTex << "\n" <<
+ prefix << "DOXYFORMAT_TEX = " << pathDoxyFormatTex << "\n" <<
+ prefix << "DOXYLATEX_TEX = " << pathDoxyLatexTex << "\n" <<
+ prefix << "DOXYLATEX_DVI = " << pathDoxyLatexDVI << "\n" <<
+ prefix << "DOXYLATEX_PDF = " << pathDoxyLatexPDF << "\n";
+
+ doxyRulesStream <<
+ "\n"
+ ".PHONY: clean-perlmod\n"
+ "clean-perlmod::\n"
+ "\trm -f $(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
+ "\t$(" << prefix << "DOXYDOCS_PM)";
+ if (perlmodLatex)
+ doxyRulesStream <<
+ " \\\n"
+ "\t$(" << prefix << "DOXYLATEX_PL) \\\n"
+ "\t$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
+ "\t$(" << prefix << "DOXYDOCS_TEX) \\\n"
+ "\t$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
+ "\t$(" << prefix << "DOXYFORMAT_TEX) \\\n"
+ "\t$(" << prefix << "DOXYLATEX_TEX) \\\n"
+ "\t$(" << prefix << "DOXYLATEX_PDF) \\\n"
+ "\t$(" << prefix << "DOXYLATEX_DVI) \\\n"
+ "\t$(addprefix $(" << prefix << "DOXYLATEX_TEX:tex=),out aux log)";
+ doxyRulesStream << "\n\n";
+
+ doxyRulesStream <<
+ "$(" << prefix << "DOXYRULES) \\\n"
+ "$(" << prefix << "DOXYMAKEFILE) \\\n"
+ "$(" << prefix << "DOXYSTRUCTURE_PM) \\\n"
+ "$(" << prefix << "DOXYDOCS_PM)";
+ if (perlmodLatex) {
+ doxyRulesStream <<
+ " \\\n"
+ "$(" << prefix << "DOXYLATEX_PL) \\\n"
+ "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
+ "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
+ "$(" << prefix << "DOXYLATEX_TEX)";
+ }
+ doxyRulesStream <<
+ ": \\\n"
+ "\t$(" << prefix << "DOXYFILE)\n"
+ "\tcd $(" << prefix << "DOXY_EXEC_PATH) ; doxygen \"$<\"\n";
+
+ if (perlmodLatex) {
+ doxyRulesStream <<
+ "\n"
+ "$(" << prefix << "DOXYDOCS_TEX): \\\n"
+ "$(" << prefix << "DOXYLATEX_PL) \\\n"
+ "$(" << prefix << "DOXYDOCS_PM)\n"
+ "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
+ "\n"
+ "$(" << prefix << "DOXYSTRUCTURE_TEX): \\\n"
+ "$(" << prefix << "DOXYLATEXSTRUCTURE_PL) \\\n"
+ "$(" << prefix << "DOXYSTRUCTURE_PM)\n"
+ "\tperl -I\"$(<D)\" \"$<\" >\"$@\"\n"
+ "\n"
+ "$(" << prefix << "DOXYLATEX_PDF) \\\n"
+ "$(" << prefix << "DOXYLATEX_DVI): \\\n"
+ "$(" << prefix << "DOXYLATEX_TEX) \\\n"
+ "$(" << prefix << "DOXYFORMAT_TEX) \\\n"
+ "$(" << prefix << "DOXYSTRUCTURE_TEX) \\\n"
+ "$(" << prefix << "DOXYDOCS_TEX)\n"
+ "\n"
+ "$(" << prefix << "DOXYLATEX_PDF): \\\n"
+ "$(" << prefix << "DOXYLATEX_TEX)\n"
+ "\tpdflatex -interaction=nonstopmode \"$<\"\n"
+ "\n"
+ "$(" << prefix << "DOXYLATEX_DVI): \\\n"
+ "$(" << prefix << "DOXYLATEX_TEX)\n"
+ "\tlatex -interaction=nonstopmode \"$<\"\n";
+ }
+
+ return true;
+}
+
+bool PerlModGenerator::generateMakefile()
+{
+ QFile makefile;
+ if (!createOutputFile(makefile, pathMakefile))
+ return false;
+
+ bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
+ QCString prefix = Config_getString("PERLMOD_MAKEVAR_PREFIX");
+
+ FTextStream makefileStream(&makefile);
+ makefileStream <<
+ ".PHONY: default clean" << (perlmodLatex ? " pdf" : "") << "\n"
+ "default: " << (perlmodLatex ? "pdf" : "clean") << "\n"
+ "\n"
+ "include " << pathDoxyRules << "\n"
+ "\n"
+ "clean: clean-perlmod\n";
+
+ if (perlmodLatex) {
+ makefileStream <<
+ "pdf: $(" << prefix << "DOXYLATEX_PDF)\n"
+ "dvi: $(" << prefix << "DOXYLATEX_DVI)\n";
+ }
+
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyLatexStructurePL()
+{
+ QFile doxyLatexStructurePL;
+ if (!createOutputFile(doxyLatexStructurePL, pathDoxyLatexStructurePL))
+ return false;
+
+ FTextStream doxyLatexStructurePLStream(&doxyLatexStructurePL);
+ doxyLatexStructurePLStream <<
+ "use DoxyStructure;\n"
+ "\n"
+ "sub process($) {\n"
+ "\tmy $node = $_[0];\n"
+ "\tmy ($type, $name) = @$node[0, 1];\n"
+ "\tmy $command;\n"
+ "\tif ($type eq \"string\") { $command = \"String\" }\n"
+ "\telsif ($type eq \"doc\") { $command = \"Doc\" }\n"
+ "\telsif ($type eq \"hash\") {\n"
+ "\t\t$command = \"Hash\";\n"
+ "\t\tfor my $subnode (values %{$$node[2]}) {\n"
+ "\t\t\tprocess($subnode);\n"
+ "\t\t}\n"
+ "\t}\n"
+ "\telsif ($type eq \"list\") {\n"
+ "\t\t$command = \"List\";\n"
+ "\t\tprocess($$node[2]);\n"
+ "\t}\n"
+ "\tprint \"\\\\\" . $command . \"Node{\" . $name . \"}%\\n\";\n"
+ "}\n"
+ "\n"
+ "process($doxystructure);\n";
+
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyLatexPL()
+{
+ QFile doxyLatexPL;
+ if (!createOutputFile(doxyLatexPL, pathDoxyLatexPL))
+ return false;
+
+ FTextStream doxyLatexPLStream(&doxyLatexPL);
+ doxyLatexPLStream <<
+ "use DoxyStructure;\n"
+ "use DoxyDocs;\n"
+ "\n"
+ "sub latex_quote($) {\n"
+ "\tmy $text = $_[0];\n"
+ "\t$text =~ s/\\\\/\\\\textbackslash /g;\n"
+ "\t$text =~ s/\\|/\\\\textbar /g;\n"
+ "\t$text =~ s/</\\\\textless /g;\n"
+ "\t$text =~ s/>/\\\\textgreater /g;\n"
+ "\t$text =~ s/~/\\\\textasciitilde /g;\n"
+ "\t$text =~ s/\\^/\\\\textasciicircum /g;\n"
+ "\t$text =~ s/[\\$&%#_{}]/\\\\$&/g;\n"
+ "\tprint $text;\n"
+ "}\n"
+ "\n"
+ "sub generate_doc($) {\n"
+ "\tmy $doc = $_[0];\n"
+ "\tfor my $item (@$doc) {\n"
+ "\t\tmy $type = $$item{type};\n"
+ "\t\tif ($type eq \"text\") {\n"
+ "\t\t\tlatex_quote($$item{content});\n"
+ "\t\t} elsif ($type eq \"parbreak\") {\n"
+ "\t\t\tprint \"\\n\\n\";\n"
+ "\t\t} elsif ($type eq \"style\") {\n"
+ "\t\t\tmy $style = $$item{style};\n"
+ "\t\t\tif ($$item{enable} eq \"yes\") {\n"
+ "\t\t\t\tif ($style eq \"bold\") { print '\\bfseries'; }\n"
+ "\t\t\t\tif ($style eq \"italic\") { print '\\itshape'; }\n"
+ "\t\t\t\tif ($style eq \"code\") { print '\\ttfamily'; }\n"
+ "\t\t\t} else {\n"
+ "\t\t\t\tif ($style eq \"bold\") { print '\\mdseries'; }\n"
+ "\t\t\t\tif ($style eq \"italic\") { print '\\upshape'; }\n"
+ "\t\t\t\tif ($style eq \"code\") { print '\\rmfamily'; }\n"
+ "\t\t\t}\n"
+ "\t\t\tprint '{}';\n"
+ "\t\t} elsif ($type eq \"symbol\") {\n"
+ "\t\t\tmy $symbol = $$item{symbol};\n"
+ "\t\t\tif ($symbol eq \"copyright\") { print '\\copyright'; }\n"
+ "\t\t\telsif ($symbol eq \"szlig\") { print '\\ss'; }\n"
+ "\t\t\tprint '{}';\n"
+ "\t\t} elsif ($type eq \"accent\") {\n"
+ "\t\t\tmy ($accent) = $$item{accent};\n"
+ "\t\t\tif ($accent eq \"umlaut\") { print '\\\"'; }\n"
+ "\t\t\telsif ($accent eq \"acute\") { print '\\\\\\''; }\n"
+ "\t\t\telsif ($accent eq \"grave\") { print '\\`'; }\n"
+ "\t\t\telsif ($accent eq \"circ\") { print '\\^'; }\n"
+ "\t\t\telsif ($accent eq \"tilde\") { print '\\~'; }\n"
+ "\t\t\telsif ($accent eq \"cedilla\") { print '\\c'; }\n"
+ "\t\t\telsif ($accent eq \"ring\") { print '\\r'; }\n"
+ "\t\t\tprint \"{\" . $$item{letter} . \"}\"; \n"
+ "\t\t} elsif ($type eq \"list\") {\n"
+ "\t\t\tmy $env = ($$item{style} eq \"ordered\") ? \"enumerate\" : \"itemize\";\n"
+ "\t\t\tprint \"\\n\\\\begin{\" . $env .\"}\";\n"
+ "\t\t \tfor my $subitem (@{$$item{content}}) {\n"
+ "\t\t\t\tprint \"\\n\\\\item \";\n"
+ "\t\t\t\tgenerate_doc($subitem);\n"
+ "\t\t \t}\n"
+ "\t\t\tprint \"\\n\\\\end{\" . $env .\"}\";\n"
+ "\t\t} elsif ($type eq \"url\") {\n"
+ "\t\t\tlatex_quote($$item{content});\n"
+ "\t\t}\n"
+ "\t}\n"
+ "}\n"
+ "\n"
+ "sub generate($$) {\n"
+ "\tmy ($item, $node) = @_;\n"
+ "\tmy ($type, $name) = @$node[0, 1];\n"
+ "\tif ($type eq \"string\") {\n"
+ "\t\tprint \"\\\\\" . $name . \"{\";\n"
+ "\t\tlatex_quote($item);\n"
+ "\t\tprint \"}\";\n"
+ "\t} elsif ($type eq \"doc\") {\n"
+ "\t\tif (@$item) {\n"
+ "\t\t\tprint \"\\\\\" . $name . \"{\";\n"
+ "\t\t\tgenerate_doc($item);\n"
+ "\t\t\tprint \"}%\\n\";\n"
+ "\t\t} else {\n"
+ "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
+ "\t\t}\n"
+ "\t} elsif ($type eq \"hash\") {\n"
+ "\t\tmy ($key, $value);\n"
+ "\t\twhile (($key, $subnode) = each %{$$node[2]}) {\n"
+ "\t\t\tmy $subname = $$subnode[1];\n"
+ "\t\t\tprint \"\\\\Defcs{field\" . $subname . \"}{\";\n"
+ "\t\t\tif ($$item{$key}) {\n"
+ "\t\t\t\tgenerate($$item{$key}, $subnode);\n"
+ "\t\t\t} else {\n"
+ "#\t\t\t\t\tprint \"\\\\\" . $subname . \"Empty%\\n\";\n"
+ "\t\t\t}\n"
+ "\t\t\tprint \"}%\\n\";\n"
+ "\t\t}\n"
+ "\t\tprint \"\\\\\" . $name . \"%\\n\";\n"
+ "\t} elsif ($type eq \"list\") {\n"
+ "\t\tmy $index = 0;\n"
+ "\t\tif (@$item) {\n"
+ "\t\t\tprint \"\\\\\" . $name . \"{%\\n\";\n"
+ "\t\t\tfor my $subitem (@$item) {\n"
+ "\t\t\t\tif ($index) {\n"
+ "\t\t\t\t\tprint \"\\\\\" . $name . \"Sep%\\n\";\n"
+ "\t\t\t\t}\n"
+ "\t\t\t\tgenerate($subitem, $$node[2]);\n"
+ "\t\t\t\t$index++;\n"
+ "\t\t\t}\n"
+ "\t\t\tprint \"}%\\n\";\n"
+ "\t\t} else {\n"
+ "#\t\t\tprint \"\\\\\" . $name . \"Empty%\\n\";\n"
+ "\t\t}\n"
+ "\t}\n"
+ "}\n"
+ "\n"
+ "generate($doxydocs, $doxystructure);\n";
+
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyFormatTex()
+{
+ QFile doxyFormatTex;
+ if (!createOutputFile(doxyFormatTex, pathDoxyFormatTex))
+ return false;
+
+ FTextStream doxyFormatTexStream(&doxyFormatTex);
+ doxyFormatTexStream <<
+ "\\def\\Defcs#1{\\long\\expandafter\\def\\csname#1\\endcsname}\n"
+ "\\Defcs{Empty}{}\n"
+ "\\def\\IfEmpty#1{\\expandafter\\ifx\\csname#1\\endcsname\\Empty}\n"
+ "\n"
+ "\\def\\StringNode#1{\\Defcs{#1}##1{##1}}\n"
+ "\\def\\DocNode#1{\\Defcs{#1}##1{##1}}\n"
+ "\\def\\ListNode#1{\\Defcs{#1}##1{##1}\\Defcs{#1Sep}{}}\n"
+ "\\def\\HashNode#1{\\Defcs{#1}{}}\n"
+ "\n"
+ "\\input{" << pathDoxyStructureTex << "}\n"
+ "\n"
+ "\\newbox\\BoxA\n"
+ "\\dimendef\\DimenA=151\\relax\n"
+ "\\dimendef\\DimenB=152\\relax\n"
+ "\\countdef\\ZoneDepth=151\\relax\n"
+ "\n"
+ "\\def\\Cs#1{\\csname#1\\endcsname}\n"
+ "\\def\\Letcs#1{\\expandafter\\let\\csname#1\\endcsname}\n"
+ "\\def\\Heading#1{\\vskip 4mm\\relax\\textbf{#1}}\n"
+ "\\def\\See#1{\\begin{flushleft}\\Heading{See also: }#1\\end{flushleft}}\n"
+ "\n"
+ "\\def\\Frame#1{\\vskip 3mm\\relax\\fbox{ \\vbox{\\hsize0.95\\hsize\\vskip 1mm\\relax\n"
+ "\\raggedright#1\\vskip 0.5mm\\relax} }}\n"
+ "\n"
+ "\\def\\Zone#1#2#3{%\n"
+ "\\Defcs{Test#1}{#2}%\n"
+ "\\Defcs{Emit#1}{#3}%\n"
+ "\\Defcs{#1}{%\n"
+ "\\advance\\ZoneDepth1\\relax\n"
+ "\\Letcs{Mode\\number\\ZoneDepth}0\\relax\n"
+ "\\Letcs{Present\\number\\ZoneDepth}0\\relax\n"
+ "\\Cs{Test#1}\n"
+ "\\expandafter\\if\\Cs{Present\\number\\ZoneDepth}1%\n"
+ "\\advance\\ZoneDepth-1\\relax\n"
+ "\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
+ "\\expandafter\\if\\Cs{Mode\\number\\ZoneDepth}1%\n"
+ "\\advance\\ZoneDepth1\\relax\n"
+ "\\Letcs{Mode\\number\\ZoneDepth}1\\relax\n"
+ "\\Cs{Emit#1}\n"
+ "\\advance\\ZoneDepth-1\\relax\\fi\n"
+ "\\advance\\ZoneDepth1\\relax\\fi\n"
+ "\\advance\\ZoneDepth-1\\relax}}\n"
+ "\n"
+ "\\def\\Member#1#2{%\n"
+ "\\Defcs{Test#1}{\\Cs{field#1Detailed}\n"
+ "\\IfEmpty{field#1DetailedDoc}\\else\\Letcs{Present#1}1\\fi}\n"
+ "\\Defcs{#1}{\\Letcs{Present#1}0\\relax\n"
+ "\\Cs{Test#1}\\if1\\Cs{Present#1}\\Letcs{Present\\number\\ZoneDepth}1\\relax\n"
+ "\\if1\\Cs{Mode\\number\\ZoneDepth}#2\\fi\\fi}}\n"
+ "\n"
+ "\\def\\TypedefMemberList#1#2{%\n"
+ "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
+ "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
+ "\\Defcs{#1See}##1{\\See{##1}}%\n"
+ "%\n"
+ "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
+ "\\Member{#1}{\\Frame{typedef \\Cs{field#1Type} \\Cs{field#1Name}}%\n"
+ "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
+ "\n"
+ "\\def\\VariableMemberList#1#2{%\n"
+ "\\Defcs{#1DetailedDoc}##1{\\vskip 5.5mm\\relax##1}%\n"
+ "\\Defcs{#1Name}##1{\\textbf{##1}}%\n"
+ "\\Defcs{#1See}##1{\\See{##1}}%\n"
+ "%\n"
+ "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
+ "\\Member{#1}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}}%\n"
+ "\\Cs{field#1DetailedDoc}\\Cs{field#1See}\\vskip 5mm\\relax}}%\n"
+ "\n"
+ "\\def\\FunctionMemberList#1#2{%\n"
+ "\\Defcs{#1PDParamName}##1{\\textit{##1}}%\n"
+ "\\Defcs{#1PDParam}{\\Cs{field#1PDParamName}}%\n"
+ "\\Defcs{#1PDParamsSep}{, }%\n"
+ "\\Defcs{#1PDBlocksSep}{\\vskip 2mm\\relax}%\n"
+ "%\n"
+ "\\Defcs{#1PDBlocks}##1{%\n"
+ "\\Heading{Parameters:}\\vskip 1.5mm\\relax\n"
+ "\\DimenA0pt\\relax\n"
+ "\\Defcs{#1PDBlock}{\\setbox\\BoxA\\hbox{\\Cs{field#1PDParams}}%\n"
+ "\\ifdim\\DimenA<\\wd\\BoxA\\DimenA\\wd\\BoxA\\fi}%\n"
+ "##1%\n"
+ "\\advance\\DimenA3mm\\relax\n"
+ "\\DimenB\\hsize\\advance\\DimenB-\\DimenA\\relax\n"
+ "\\Defcs{#1PDBlock}{\\hbox to\\hsize{\\vtop{\\hsize\\DimenA\\relax\n"
+ "\\Cs{field#1PDParams}}\\hfill\n"
+ "\\vtop{\\hsize\\DimenB\\relax\\Cs{field#1PDDoc}}}}%\n"
+ "##1}\n"
+ "\n"
+ "\\Defcs{#1ParamName}##1{\\textit{##1}}\n"
+ "\\Defcs{#1Param}{\\Cs{field#1ParamType}{} \\Cs{field#1ParamName}}\n"
+ "\\Defcs{#1ParamsSep}{, }\n"
+ "\n"
+ "\\Defcs{#1Name}##1{\\textbf{##1}}\n"
+ "\\Defcs{#1See}##1{\\See{##1}}\n"
+ "\\Defcs{#1Return}##1{\\Heading{Returns: }##1}\n"
+ "\\Defcs{field#1Title}{\\Frame{\\Cs{field#1Type}{} \\Cs{field#1Name}(\\Cs{field#1Params})}}%\n"
+ "%\n"
+ "\\Zone{#1s}{\\Cs{field#1List}}{\\subsubsection{#2}\\Cs{field#1List}}%\n"
+ "\\Member{#1}{%\n"
+ "\\Cs{field#1Title}\\vskip 6mm\\relax\\Cs{field#1DetailedDoc}\n"
+ "\\Cs{field#1Return}\\Cs{field#1PDBlocks}\\Cs{field#1See}\\vskip 5mm\\relax}}\n"
+ "\n"
+ "\\def\\FileDetailed{\\fieldFileDetailedDoc\\par}\n"
+ "\\def\\ClassDetailed{\\fieldClassDetailedDoc\\par}\n"
+ "\n"
+ "\\def\\FileSubzones{\\fieldFileTypedefs\\fieldFileVariables\\fieldFileFunctions}\n"
+ "\n"
+ "\\def\\ClassSubzones{%\n"
+ "\\fieldClassPublicTypedefs\\fieldClassPublicMembers\\fieldClassPublicMethods\n"
+ "\\fieldClassProtectedTypedefs\\fieldClassProtectedMembers\\fieldClassProtectedMethods\n"
+ "\\fieldClassPrivateTypedefs\\fieldClassPrivateMembers\\fieldClassPrivateMethods}\n"
+ "\n"
+ "\\Member{Page}{\\subsection{\\fieldPageName}\\fieldPageDetailedDoc}\n"
+ "\n"
+ "\\TypedefMemberList{FileTypedef}{Typedefs}\n"
+ "\\VariableMemberList{FileVariable}{Variables}\n"
+ "\\FunctionMemberList{FileFunction}{Functions}\n"
+ "\\Zone{File}{\\FileSubzones}{\\subsection{\\fieldFileName}\\fieldFileDetailed\\FileSubzones}\n"
+ "\n"
+ "\\TypedefMemberList{ClassPublicTypedef}{Public Typedefs}\n"
+ "\\TypedefMemberList{ClassProtectedTypedef}{Protected Typedefs}\n"
+ "\\TypedefMemberList{ClassPrivateTypedef}{Private Typedefs}\n"
+ "\\VariableMemberList{ClassPublicMember}{Public Members}\n"
+ "\\VariableMemberList{ClassProtectedMember}{Protected Members}\n"
+ "\\VariableMemberList{ClassPrivateMember}{Private Members}\n"
+ "\\FunctionMemberList{ClassPublicMethod}{Public Methods}\n"
+ "\\FunctionMemberList{ClassProtectedMethod}{Protected Methods}\n"
+ "\\FunctionMemberList{ClassPrivateMethod}{Private Methods}\n"
+ "\\Zone{Class}{\\ClassSubzones}{\\subsection{\\fieldClassName}\\fieldClassDetailed\\ClassSubzones}\n"
+ "\n"
+ "\\Zone{AllPages}{\\fieldPages}{\\section{Pages}\\fieldPages}\n"
+ "\\Zone{AllFiles}{\\fieldFiles}{\\section{Files}\\fieldFiles}\n"
+ "\\Zone{AllClasses}{\\fieldClasses}{\\section{Classes}\\fieldClasses}\n"
+ "\n"
+ "\\newlength{\\oldparskip}\n"
+ "\\newlength{\\oldparindent}\n"
+ "\\newlength{\\oldfboxrule}\n"
+ "\n"
+ "\\ZoneDepth0\\relax\n"
+ "\\Letcs{Mode0}1\\relax\n"
+ "\n"
+ "\\def\\EmitDoxyDocs{%\n"
+ "\\setlength{\\oldparskip}{\\parskip}\n"
+ "\\setlength{\\oldparindent}{\\parindent}\n"
+ "\\setlength{\\oldfboxrule}{\\fboxrule}\n"
+ "\\setlength{\\parskip}{0cm}\n"
+ "\\setlength{\\parindent}{0cm}\n"
+ "\\setlength{\\fboxrule}{1pt}\n"
+ "\\AllPages\\AllFiles\\AllClasses\n"
+ "\\setlength{\\parskip}{\\oldparskip}\n"
+ "\\setlength{\\parindent}{\\oldparindent}\n"
+ "\\setlength{\\fboxrule}{\\oldfboxrule}}\n";
+
+ return true;
+}
+
+bool PerlModGenerator::generateDoxyLatexTex()
+{
+ QFile doxyLatexTex;
+ if (!createOutputFile(doxyLatexTex, pathDoxyLatexTex))
+ return false;
+
+ FTextStream doxyLatexTexStream(&doxyLatexTex);
+ doxyLatexTexStream <<
+ "\\documentclass[a4paper,12pt]{article}\n"
+ "\\usepackage[latin1]{inputenc}\n"
+ "\\usepackage[none]{hyphenat}\n"
+ "\\usepackage[T1]{fontenc}\n"
+ "\\usepackage{hyperref}\n"
+ "\\usepackage{times}\n"
+ "\n"
+ "\\input{doxyformat}\n"
+ "\n"
+ "\\begin{document}\n"
+ "\\input{" << pathDoxyDocsTex << "}\n"
+ "\\sloppy\n"
+ "\\EmitDoxyDocs\n"
+ "\\end{document}\n";
+
+ return true;
+}
+
+void PerlModGenerator::generate()
+{
+ // + classes
+ // + namespaces
+ // + files
+ // - packages
+ // + groups
+ // + related pages
+ // - examples
+
+ QDir perlModDir;
+ if (!createOutputDir(perlModDir))
+ return;
+
+ bool perlmodLatex = Config_getBool("PERLMOD_LATEX");
+
+ QCString perlModAbsPath = perlModDir.absPath().utf8();
+ pathDoxyDocsPM = perlModAbsPath + "/DoxyDocs.pm";
+ pathDoxyStructurePM = perlModAbsPath + "/DoxyStructure.pm";
+ pathMakefile = perlModAbsPath + "/Makefile";
+ pathDoxyRules = perlModAbsPath + "/doxyrules.make";
+
+ if (perlmodLatex) {
+ pathDoxyStructureTex = perlModAbsPath + "/doxystructure.tex";
+ pathDoxyFormatTex = perlModAbsPath + "/doxyformat.tex";
+ pathDoxyLatexTex = perlModAbsPath + "/doxylatex.tex";
+ pathDoxyLatexDVI = perlModAbsPath + "/doxylatex.dvi";
+ pathDoxyLatexPDF = perlModAbsPath + "/doxylatex.pdf";
+ pathDoxyDocsTex = perlModAbsPath + "/doxydocs.tex";
+ pathDoxyLatexPL = perlModAbsPath + "/doxylatex.pl";
+ pathDoxyLatexStructurePL = perlModAbsPath + "/doxylatex-structure.pl";
+ }
+
+ if (!(generatePerlModOutput()
+ && generateDoxyStructurePM()
+ && generateMakefile()
+ && generateDoxyRules()))
+ return;
+
+ if (perlmodLatex) {
+ if (!(generateDoxyLatexStructurePL()
+ && generateDoxyLatexPL()
+ && generateDoxyLatexTex()
+ && generateDoxyFormatTex()))
+ return;
+ }
+}
+
+void generatePerlMod()
+{
+ PerlModGenerator pmg(Config_getBool("PERLMOD_PRETTY"));
+ pmg.generate();
+}
+
+// Local Variables:
+// c-basic-offset: 2
+// End:
+
+/* This elisp function for XEmacs makes Control-Z transform
+ the text in the region into a valid C string.
+
+ (global-set-key '(control z) (lambda () (interactive)
+ (save-excursion
+ (if (< (mark) (point)) (exchange-point-and-mark))
+ (let ((start (point)) (replacers
+ '(("\\\\" "\\\\\\\\")
+ ("\"" "\\\\\"")
+ ("\t" "\\\\t")
+ ("^.*$" "\"\\&\\\\n\""))))
+ (while replacers
+ (while (re-search-forward (caar replacers) (mark) t)
+ (replace-match (cadar replacers) t))
+ (goto-char start)
+ (setq replacers (cdr replacers)))))))
+*/
diff --git a/src/perlmodgen.h b/src/perlmodgen.h
new file mode 100644
index 0000000..f908959
--- /dev/null
+++ b/src/perlmodgen.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef PERLMODGEN_H
+#define PERLMODGEN_H
+
+class QCString;
+
+extern void setPerlModDoxyfile(const QCString &);
+extern void generatePerlMod();
+
+#endif
diff --git a/src/plantuml.cpp b/src/plantuml.cpp
new file mode 100644
index 0000000..18f028b
--- /dev/null
+++ b/src/plantuml.cpp
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "plantuml.h"
+#include "portable.h"
+#include "config.h"
+#include "message.h"
+
+#include <qdir.h>
+
+//static const int maxCmdLine = 40960;
+
+QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content)
+{
+ QCString baseName(4096);
+ static int umlindex=1;
+
+ if (fileName.isEmpty()) // generate name
+ {
+ baseName = outDir+"/inline_umlgraph_"+QCString().setNum(umlindex++);
+ }
+ else // user specified name
+ {
+ baseName = fileName;
+ int i=baseName.findRev('.');
+ if (i!=-1) baseName = baseName.left(i);
+ baseName.prepend(outDir+"/");
+ }
+ QFile file(baseName+".pu");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",baseName.data());
+ }
+ QCString text = "@startuml\n";
+ text+=content;
+ text+="@enduml\n";
+ file.writeBlock( text, text.length() );
+ file.close();
+ return baseName;
+}
+
+void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format)
+{
+ static QCString plantumlJarPath = Config_getString("PLANTUML_JAR_PATH");
+
+ QCString pumlExe = "java";
+ QCString pumlArgs = "-Djava.awt.headless=true -jar \""+plantumlJarPath+"plantuml.jar\" ";
+ pumlArgs+="-o \"";
+ pumlArgs+=outDir;
+ pumlArgs+="\" ";
+ QCString extension;
+ switch (format)
+ {
+ case PUML_BITMAP:
+ pumlArgs+="-tpng";
+ extension=".png";
+ break;
+ case PUML_EPS:
+ pumlArgs+="-teps";
+ extension=".eps";
+ break;
+ case PUML_SVG:
+ pumlArgs+="-tsvg";
+ extension=".svg";
+ break;
+ }
+ pumlArgs+=" \"";
+ pumlArgs+=baseName;
+ pumlArgs+=".pu\" ";
+ int exitCode;
+ //printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,outFile);
+ msg("Running PlantUML on generated file %s.pu\n",baseName);
+ portable_sysTimerStart();
+ if ((exitCode=portable_system(pumlExe,pumlArgs,FALSE))!=0)
+ {
+ err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line\n",
+ plantumlJarPath.data());
+ }
+ else if (Config_getBool("DOT_CLEANUP"))
+ {
+ QFile(QCString(baseName)+".pu").remove();
+ }
+ portable_sysTimerStop();
+}
+
diff --git a/src/plantuml.h b/src/plantuml.h
new file mode 100644
index 0000000..27626d1
--- /dev/null
+++ b/src/plantuml.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef PLANTUML_H
+#define PLANTUML_H
+
+class QCString;
+
+/** Plant UML output image formats */
+enum PlantUMLOutputFormat { PUML_BITMAP, PUML_EPS, PUML_SVG };
+
+/** Write a PlantUML compatible file.
+ * @param[in] outDir the output directory to write the file to.
+ * @param[in] fileName the name of the file. If empty a name will be chosen automatically.
+ * @param[in] content the contents of the PlantUML file.
+ * @returns The name of the generated file.
+ */
+QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content);
+
+/** Convert a PlantUML file to an image.
+ * @param[in] baseName the name of the generated file (as returned by writePlantUMLSource())
+ * @param[in] outDir the directory to write the resulting image into.
+ * @param[in] format the image format to generate.
+ */
+void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format);
+
+#endif
+
diff --git a/src/portable.cpp b/src/portable.cpp
new file mode 100644
index 0000000..258c50f
--- /dev/null
+++ b/src/portable.cpp
@@ -0,0 +1,442 @@
+#include <stdlib.h>
+#include <ctype.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef UNICODE
+#define _WIN32_DCOM
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+extern char **environ;
+#endif
+
+#include <qglobal.h>
+#include <qdatetime.h>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#include "portable.h"
+#ifndef NODEBUG
+#include "debug.h"
+#endif
+//#include "doxygen.h"
+
+static double g_sysElapsedTime;
+static QTime g_time;
+
+int portable_system(const char *command,const char *args,bool commandHasConsole)
+{
+
+ if (command==0) return 1;
+
+ QCString fullCmd=command;
+ fullCmd=fullCmd.stripWhiteSpace();
+ if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1)
+ {
+ // add quotes around command as it contains spaces and is not quoted already
+ fullCmd="\""+fullCmd+"\"";
+ }
+ fullCmd += " ";
+ fullCmd += args;
+#ifndef NODEBUG
+ Debug::print(Debug::ExtCmd,0,"Executing external command `%s`\n",fullCmd.data());
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ (void)commandHasConsole;
+ /*! taken from the system() manpage on my Linux box */
+ int pid,status=0;
+
+#ifdef _OS_SOLARIS // for Solaris we use vfork since it is more memory efficient
+
+ // on Solaris fork() duplicates the memory usage
+ // so we use vfork instead
+
+ // spawn shell
+ if ((pid=vfork())<0)
+ {
+ status=-1;
+ }
+ else if (pid==0)
+ {
+ execl("/bin/sh","sh","-c",fullCmd.data(),(char*)0);
+ _exit(127);
+ }
+ else
+ {
+ while (waitpid(pid,&status,0 )<0)
+ {
+ if (errno!=EINTR)
+ {
+ status=-1;
+ break;
+ }
+ }
+ }
+ return status;
+
+#else // Other Unices just use fork
+
+ pid = fork();
+ if (pid==-1)
+ {
+ perror("fork error");
+ return -1;
+ }
+ if (pid==0)
+ {
+ const char * argv[4];
+ argv[0] = "sh";
+ argv[1] = "-c";
+ argv[2] = fullCmd.data();
+ argv[3] = 0;
+ execve("/bin/sh",(char * const *)argv,environ);
+ exit(127);
+ }
+ for (;;)
+ {
+ if (waitpid(pid,&status,0)==-1)
+ {
+ if (errno!=EINTR) return -1;
+ }
+ else
+ {
+ if (WIFEXITED(status))
+ {
+ return WEXITSTATUS(status);
+ }
+ else
+ {
+ return status;
+ }
+ }
+ }
+#endif // !_OS_SOLARIS
+
+#else // Win32 specific
+ if (commandHasConsole)
+ {
+ return system(fullCmd);
+ }
+ else
+ {
+ // Because ShellExecuteEx can delegate execution to Shell extensions
+ // (data sources, context menu handlers, verb implementations) that
+ // are activated using Component Object Model (COM), COM should be
+ // initialized before ShellExecuteEx is called. Some Shell extensions
+ // require the COM single-threaded apartment (STA) type.
+ // For that case COM is initialized as follows
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+
+ QString commandw = QString::fromUtf8( command );
+ QString argsw = QString::fromUtf8( args );
+
+ // gswin32 is a GUI api which will pop up a window and run
+ // asynchronously. To prevent both, we use ShellExecuteEx and
+ // WaitForSingleObject (thanks to Robert Golias for the code)
+
+ SHELLEXECUTEINFOW sInfo = {
+ sizeof(SHELLEXECUTEINFOW), /* structure size */
+ SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI, /* tell us the process
+ * handle so we can wait till it's done |
+ * do not display msg box if error
+ */
+ NULL, /* window handle */
+ NULL, /* action to perform: open */
+ (LPCWSTR)commandw.ucs2(), /* file to execute */
+ (LPCWSTR)argsw.ucs2(), /* argument list */
+ NULL, /* use current working dir */
+ SW_HIDE, /* minimize on start-up */
+ 0, /* application instance handle */
+ NULL, /* ignored: id list */
+ NULL, /* ignored: class name */
+ NULL, /* ignored: key class */
+ 0, /* ignored: hot key */
+ NULL, /* ignored: icon */
+ NULL /* resulting application handle */
+ };
+
+ if (!ShellExecuteExW(&sInfo))
+ {
+ return -1;
+ }
+ else if (sInfo.hProcess) /* executable was launched, wait for it to finish */
+ {
+ WaitForSingleObject(sInfo.hProcess,INFINITE);
+ CloseHandle(sInfo.hProcess);
+ }
+ }
+ return 0;
+#endif
+
+}
+
+uint portable_pid()
+{
+ uint pid;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ pid = (uint)getpid();
+#else
+ pid = (uint)GetCurrentProcessId();
+#endif
+ return pid;
+}
+
+static char **last_environ;
+
+void portable_setenv(const char *name,const char *value)
+{
+ if (value==0) value="";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ SetEnvironmentVariable(name,value);
+#else
+ register char **ep = 0;
+ register size_t size;
+ const size_t namelen=qstrlen(name);
+ const size_t vallen=qstrlen(value) + 1;
+
+ size = 0;
+ if (environ!=0)
+ {
+ for (ep = environ; *ep; ++ep)
+ {
+ if (!qstrncmp (*ep, name, (uint)namelen) &&
+ (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+ }
+ }
+
+ if (environ==0 || *ep==0) /* add new string */
+ {
+ char **new_environ;
+ if (environ == last_environ && environ!=0)
+ {
+ // We allocated this space; we can extend it.
+ new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
+ }
+ else
+ {
+ new_environ = (char **) malloc ((size + 2) * sizeof (char *));
+ }
+
+ if (new_environ==0) // no more memory
+ {
+ return;
+ }
+
+ new_environ[size] = (char *)malloc (namelen + 1 + vallen);
+ if (new_environ[size]==0)
+ {
+ free (new_environ);
+ return;
+ }
+
+ if (environ != last_environ)
+ {
+ memcpy ((char *) new_environ, environ, size * sizeof (char *));
+ }
+
+ memcpy(new_environ[size], name, namelen);
+ new_environ[size][namelen] = '=';
+ memcpy(&new_environ[size][namelen + 1], value, vallen);
+ new_environ[size + 1] = 0;
+ last_environ = environ = new_environ;
+ }
+ else /* replace existing string */
+ {
+ size_t len = qstrlen (*ep);
+ if (len + 1 < namelen + 1 + vallen)
+ {
+ /* The existing string is too short; malloc a new one. */
+ char *newString = (char *)malloc(namelen + 1 + vallen);
+ if (newString==0)
+ {
+ return;
+ }
+ *ep = newString;
+ }
+ memcpy(*ep, name, namelen);
+ (*ep)[namelen] = '=';
+ memcpy(&(*ep)[namelen + 1], value, vallen);
+ }
+
+#endif
+}
+
+void portable_unsetenv(const char *variable)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ SetEnvironmentVariable(variable,0);
+#else
+ /* Some systems don't have unsetenv(), so we do it ourselves */
+ size_t len;
+ char **ep;
+
+ if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL)
+ {
+ return; // not properly formatted
+ }
+
+ len = qstrlen(variable);
+
+ ep = environ;
+ while (*ep != NULL)
+ {
+ if (!qstrncmp(*ep, variable, (uint)len) && (*ep)[len]=='=')
+ {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+ do dp[0] = dp[1]; while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+ else
+ {
+ ++ep;
+ }
+ }
+#endif
+}
+
+const char *portable_getenv(const char *variable)
+{
+ return getenv(variable);
+}
+
+portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
+{
+#if defined(__MINGW32__)
+ return fseeko64(f,offset,whence);
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ return _fseeki64(f,offset,whence);
+#else
+ return fseeko(f,offset,whence);
+#endif
+}
+
+portable_off_t portable_ftell(FILE *f)
+{
+#if defined(__MINGW32__)
+ return ftello64(f);
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ return _ftelli64(f);
+#else
+ return ftello(f);
+#endif
+}
+
+FILE *portable_fopen(const char *fileName,const char *mode)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ QString fn(fileName);
+ QString m(mode);
+ return _wfopen((wchar_t*)fn.ucs2(),(wchar_t*)m.ucs2());
+#else
+ return fopen(fileName,mode);
+#endif
+}
+
+char portable_pathSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return '\\';
+#else
+ return '/';
+#endif
+}
+
+char portable_pathListSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return ';';
+#else
+ return ':';
+#endif
+}
+
+const char *portable_ghostScriptCommand()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return "gswin32c.exe";
+#else
+ return "gs";
+#endif
+}
+
+const char *portable_commandExtension()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return ".exe";
+#else
+ return "";
+#endif
+}
+
+bool portable_fileSystemIsCaseSensitive()
+{
+#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__)
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+
+FILE * portable_popen(const char *name,const char *type)
+{
+ return popen(name,type);
+}
+
+int portable_pclose(FILE *stream)
+{
+ return pclose(stream);
+}
+
+void portable_sysTimerStart()
+{
+ g_time.start();
+}
+
+void portable_sysTimerStop()
+{
+ g_sysElapsedTime+=((double)g_time.elapsed())/1000.0;
+}
+
+double portable_getSysElapsedTime()
+{
+ return g_sysElapsedTime;
+}
+
+void portable_sleep(int ms)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(ms);
+#else
+ usleep(1000*ms);
+#endif
+}
+
+bool portable_isAbsolutePath(const char *fileName)
+{
+# ifdef _WIN32
+ if (isalpha (fileName [0]) && fileName[1] == ':')
+ fileName += 2;
+# endif
+ char const fst = fileName [0];
+ if (fst == '/') {
+ return true;
+ }
+# ifdef _WIN32
+ if (fst == '\\')
+ return true;
+# endif
+ return false;
+}
+
+
diff --git a/src/portable.h b/src/portable.h
new file mode 100644
index 0000000..1471ce1
--- /dev/null
+++ b/src/portable.h
@@ -0,0 +1,47 @@
+#ifndef PORTABLE_H
+#define PORTABLE_H
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <qglobal.h>
+
+#if defined(_WIN32)
+typedef __int64 portable_off_t;
+#else
+typedef off_t portable_off_t;
+#endif
+
+/** @file
+ * @brief Portable versions of functions that are platform dependent.
+ */
+
+int portable_system(const char *command,const char *args,bool commandHasConsole=TRUE);
+uint portable_pid();
+const char * portable_getenv(const char *variable);
+void portable_setenv(const char *variable,const char *value);
+void portable_unsetenv(const char *variable);
+portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence);
+portable_off_t portable_ftell(FILE *f);
+FILE * portable_fopen(const char *fileName,const char *mode);
+char portable_pathSeparator();
+char portable_pathListSeparator();
+const char * portable_ghostScriptCommand();
+const char * portable_commandExtension();
+bool portable_fileSystemIsCaseSensitive();
+FILE * portable_popen(const char *name,const char *type);
+int portable_pclose(FILE *stream);
+void portable_sysTimerStart();
+void portable_sysTimerStop();
+double portable_getSysElapsedTime();
+void portable_sleep(int ms);
+bool portable_isAbsolutePath(const char *fileName);
+
+extern "C" {
+ void * portable_iconv_open(const char* tocode, const char* fromcode);
+ size_t portable_iconv (void *cd, char** inbuf, size_t *inbytesleft,
+ char* * outbuf, size_t *outbytesleft);
+ int portable_iconv_close (void *cd);
+}
+
+#endif
+
diff --git a/src/portable_c.c b/src/portable_c.c
new file mode 100644
index 0000000..944c996
--- /dev/null
+++ b/src/portable_c.c
@@ -0,0 +1,30 @@
+#if (defined(__APPLE__) || defined(macintosh)) && !defined(DMG_BUILD)
+// define this before including iconv.h to avoid a mapping of
+// iconv_open and friends to libicon_open (done by mac ports),
+// while the symbols without 'lib' are linked from /usr/lib/libiconv
+#define LIBICONV_PLUG
+#endif
+#include <iconv.h>
+
+// These functions are implemented in a C file, because there are different
+// versions of the iconv() prototype, some with a const pointer and some
+// without. In C this is just a warning, but in C++ breaks the compilation.
+// Looking at the LIBICONV_VERSION is not enough, since for MACOSX the
+// const and non-const version exist with the same version of the file.
+
+void * portable_iconv_open(const char* tocode, const char* fromcode)
+{
+ return iconv_open(tocode,fromcode);
+}
+
+size_t portable_iconv (void *cd, char** inbuf, size_t *inbytesleft,
+ char** outbuf, size_t *outbytesleft)
+{
+ return iconv((iconv_t)cd,inbuf,inbytesleft,outbuf,outbytesleft);
+}
+
+int portable_iconv_close (void *cd)
+{
+ return iconv_close((iconv_t)cd);
+}
+
diff --git a/src/pre.h b/src/pre.h
new file mode 100644
index 0000000..b624be5
--- /dev/null
+++ b/src/pre.h
@@ -0,0 +1,29 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef PRE_H
+#define PRE_H
+
+class BufStr;
+
+void initPreprocessor();
+void cleanUpPreprocessor();
+void addSearchDir(const char *dir);
+void preprocessFile(const char *fileName,BufStr &input,BufStr &output);
+void preFreeScanner();
+
+#endif
diff --git a/src/pre.l b/src/pre.l
new file mode 100644
index 0000000..c3eeb2a
--- /dev/null
+++ b/src/pre.l
@@ -0,0 +1,3208 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <qarray.h>
+#include <qstack.h>
+#include <qfile.h>
+#include <qstrlist.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+
+#include "pre.h"
+#include "constexp.h"
+#include "define.h"
+#include "doxygen.h"
+#include "message.h"
+#include "util.h"
+#include "defargs.h"
+#include "debug.h"
+#include "bufstr.h"
+#include "portable.h"
+#include "bufstr.h"
+#include "arguments.h"
+#include "entry.h"
+#include "condparser.h"
+#include "config.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "membername.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+
+struct CondCtx
+{
+ CondCtx(int line,QCString id,bool b)
+ : lineNr(line),sectionId(id), skip(b) {}
+ int lineNr;
+ QCString sectionId;
+ bool skip;
+};
+
+struct FileState
+{
+ FileState(int size) : fileBuf(size),
+ oldFileBuf(0), oldFileBufPos(0) {}
+ int lineNr;
+ BufStr fileBuf;
+ BufStr *oldFileBuf;
+ int oldFileBufPos;
+ YY_BUFFER_STATE bufState;
+ QCString fileName;
+};
+
+/** @brief Singleton that manages the defines available while
+ * proprocessing files.
+ */
+class DefineManager
+{
+ /** Local class used to hold the defines for a single file */
+ class DefinesPerFile
+ {
+ public:
+ /** Creates an empty container for defines */
+ DefinesPerFile() : m_defines(257), m_includedFiles(17)
+ {
+ m_defines.setAutoDelete(TRUE);
+ }
+ /** Destroys the object */
+ virtual ~DefinesPerFile()
+ {
+ }
+ /** Adds a define in the context of a file. Will replace
+ * an existing define with the same name (redefinition)
+ * @param def The Define object to add.
+ */
+ void addDefine(Define *def)
+ {
+ Define *d = m_defines.find(def->name);
+ if (d!=0) // redefine
+ {
+ m_defines.remove(d->name);
+ }
+ m_defines.insert(def->name,def);
+ }
+ /** Adds an include file for this file
+ * @param fileName The name of the include file
+ */
+ void addInclude(const char *fileName)
+ {
+ m_includedFiles.insert(fileName,(void*)0x8);
+ }
+ void collectDefines(DefineDict *dict,QDict<void> &includeStack);
+ private:
+ DefineDict m_defines;
+ QDict<void> m_includedFiles;
+ };
+
+ public:
+ friend class DefinesPerFile;
+ /** Returns a reference to the singleton */
+ static DefineManager &instance()
+ {
+ if (theInstance==0) theInstance = new DefineManager;
+ return *theInstance;
+ }
+ /** Deletes the singleton */
+ static void deleteInstance()
+ {
+ delete theInstance;
+ theInstance = 0;
+ }
+ /** Starts a context in which defines are collected.
+ * Called at the start of a new file that is preprocessed.
+ * @param fileName the name of the file to process.
+ */
+ void startContext(const char *fileName)
+ {
+ //printf("DefineManager::startContext()\n");
+ m_contextDefines.clear();
+ if (fileName==0) return;
+ DefinesPerFile *dpf = m_fileMap.find(fileName);
+ if (dpf==0)
+ {
+ //printf("New file!\n");
+ dpf = new DefinesPerFile;
+ m_fileMap.insert(fileName,dpf);
+ }
+ }
+ /** Ends the context started with startContext() freeing any
+ * defines collected within in this context.
+ */
+ void endContext()
+ {
+ //printf("DefineManager::endContext()\n");
+ m_contextDefines.clear();
+ }
+ /** Add an included file to the current context.
+ * If the file has been pre-processed already, all defines are added
+ * to the context.
+ * @param fileName The name of the include file to add to the context.
+ */
+ void addFileToContext(const char *fileName)
+ {
+ if (fileName==0) return;
+ //printf("DefineManager::addFileToContext(%s)\n",fileName);
+ DefinesPerFile *dpf = m_fileMap.find(fileName);
+ if (dpf==0)
+ {
+ //printf("New file!\n");
+ dpf = new DefinesPerFile;
+ m_fileMap.insert(fileName,dpf);
+ }
+ else
+ {
+ //printf("existing file!\n");
+ QDict<void> includeStack(17);
+ dpf->collectDefines(&m_contextDefines,includeStack);
+ }
+ }
+
+ /** Add a define to the manager object.
+ * @param fileName The file in which the define was found
+ * @param def The Define object to add.
+ */
+ void addDefine(const char *fileName,Define *def)
+ {
+ if (fileName==0) return;
+ //printf("DefineManager::addDefine(%s,%s)\n",fileName,def->name.data());
+ Define *d = m_contextDefines.find(def->name);
+ if (d!=0) // redefine
+ {
+ m_contextDefines.remove(d->name);
+ }
+ m_contextDefines.insert(def->name,def);
+
+ DefinesPerFile *dpf = m_fileMap.find(fileName);
+ if (dpf==0)
+ {
+ dpf = new DefinesPerFile;
+ }
+ dpf->addDefine(def);
+ }
+
+ /** Add an include relation to the manager object.
+ * @param fromFileName file name in which the include was found.
+ * @param toFileName file name that is included.
+ */
+ void addInclude(const char *fromFileName,const char *toFileName)
+ {
+ //printf("DefineManager::addInclude(%s,%s)\n",fromFileName,toFileName);
+ if (fromFileName==0 || toFileName==0) return;
+ DefinesPerFile *dpf = m_fileMap.find(fromFileName);
+ if (dpf==0)
+ {
+ dpf = new DefinesPerFile;
+ }
+ dpf->addInclude(toFileName);
+ }
+ /** Returns a Define object given its name or 0 if the Define does
+ * not exist.
+ */
+ Define *isDefined(const char *name) const
+ {
+ Define *d = m_contextDefines.find(name);
+ if (d && d->undef) d=0;
+ //printf("isDefined(%s)=%p\n",name,d);
+ return d;
+ }
+ /** Returns a reference to the defines found in the current context. */
+ const DefineDict &defineContext() const
+ {
+ return m_contextDefines;
+ }
+ private:
+ static DefineManager *theInstance;
+
+ /** Helper function to collect all define for a given file */
+ void collectDefinesForFile(const char *fileName,DefineDict *dict)
+ {
+ if (fileName==0) return;
+ DefinesPerFile *dpf = m_fileMap.find(fileName);
+ if (dpf)
+ {
+ QDict<void> includeStack(17);
+ dpf->collectDefines(dict,includeStack);
+ }
+ }
+
+ /** Helper function to return the DefinesPerFile object for a given file name. */
+ DefinesPerFile *find(const char *fileName) const
+ {
+ if (fileName==0) return 0;
+ return m_fileMap.find(fileName);
+ }
+
+ /** Creates a new DefineManager object */
+ DefineManager() : m_fileMap(1009), m_contextDefines(1009)
+ {
+ m_fileMap.setAutoDelete(TRUE);
+ }
+
+ /** Destroys the object */
+ virtual ~DefineManager()
+ {
+ }
+
+ QDict<DefinesPerFile> m_fileMap;
+ DefineDict m_contextDefines;
+};
+
+/** Singleton instance */
+DefineManager *DefineManager::theInstance = 0;
+
+/** Collects all defines for a file and all files that the file includes.
+ * This function will recursively call itself for each file.
+ * @param dict The dictionary to fill with the defines. A redefine will
+ * replace a previous definition.
+ * @param includeStack The stack of includes, used to stop recursion in
+ * case there is a cyclic include dependency.
+ */
+void DefineManager::DefinesPerFile::collectDefines(
+ DefineDict *dict,QDict<void> &includeStack)
+{
+ //printf("DefinesPerFile::collectDefines #defines=%d\n",m_defines.count());
+ {
+ QDictIterator<void> di(m_includedFiles);
+ for (di.toFirst();(di.current());++di)
+ {
+ QCString incFile = di.currentKey();
+ DefinesPerFile *dpf = DefineManager::instance().find(incFile);
+ if (dpf && includeStack.find(incFile)==0)
+ {
+ //printf(" processing include %s\n",incFile.data());
+ includeStack.insert(incFile,(void*)0x8);
+ dpf->collectDefines(dict,includeStack);
+ }
+ }
+ }
+ {
+ QDictIterator<Define> di(m_defines);
+ Define *def;
+ for (di.toFirst();(def=di.current());++di)
+ {
+ Define *d = dict->find(def->name);
+ if (d!=0) // redefine
+ {
+ dict->remove(d->name);
+ }
+ dict->insert(def->name,def);
+ //printf(" adding define %s\n",def->name.data());
+ }
+ }
+}
+
+/* -----------------------------------------------------------------
+ *
+ * scanner's state
+ */
+
+static int g_yyLineNr = 1;
+static int g_yyMLines = 1;
+static int g_yyColNr = 1;
+static QCString g_yyFileName;
+static FileDef *g_yyFileDef;
+static FileDef *g_inputFileDef;
+static int g_ifcount = 0;
+static QStrList *g_pathList = 0;
+static QStack<FileState> g_includeStack;
+static QDict<int> *g_argDict;
+static int g_defArgs = -1;
+static QCString g_defName;
+static QCString g_defText;
+static QCString g_defLitText;
+static QCString g_defArgsStr;
+static QCString g_defExtraSpacing;
+static bool g_defVarArgs;
+static int g_level;
+static int g_lastCContext;
+static int g_lastCPPContext;
+static QArray<int> g_levelGuard;
+static BufStr *g_inputBuf;
+static int g_inputBufPos;
+static BufStr *g_outputBuf;
+static int g_roundCount;
+static bool g_quoteArg;
+static DefineDict *g_expandedDict;
+static int g_findDefArgContext;
+static bool g_expectGuard;
+static QCString g_guardName;
+static QCString g_lastGuardName;
+static QCString g_incName;
+static QCString g_guardExpr;
+static int g_curlyCount;
+static bool g_nospaces; // add extra spaces during macro expansion
+
+static bool g_macroExpansion; // from the configuration
+static bool g_expandOnlyPredef; // from the configuration
+static int g_commentCount;
+static bool g_insideComment;
+static bool g_isImported;
+static QCString g_blockName;
+static int g_condCtx;
+static bool g_skip;
+static QStack<CondCtx> g_condStack;
+static bool g_insideCS; // C# has simpler preprocessor
+static bool g_isSource;
+
+static bool g_lexInit = FALSE;
+static int g_fenceSize = 0;
+static bool g_ccomment;
+
+//DefineDict* getGlobalDefineDict()
+//{
+// return g_globalDefineDict;
+//}
+
+static void setFileName(const char *name)
+{
+ bool ambig;
+ QFileInfo fi(name);
+ g_yyFileName=fi.absFilePath().utf8();
+ g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig);
+ if (g_yyFileDef==0) // if this is not an input file check if it is an
+ // include file
+ {
+ g_yyFileDef=findFileDef(Doxygen::includeNameDict,g_yyFileName,ambig);
+ }
+ //printf("setFileName(%s) g_yyFileName=%s g_yyFileDef=%p\n",
+ // name,g_yyFileName.data(),g_yyFileDef);
+ if (g_yyFileDef && g_yyFileDef->isReference()) g_yyFileDef=0;
+ g_insideCS = getLanguageFromFileName(g_yyFileName)==SrcLangExt_CSharp;
+ g_isSource = guessSection(g_yyFileName);
+}
+
+static void incrLevel()
+{
+ g_level++;
+ g_levelGuard.resize(g_level);
+ g_levelGuard[g_level-1]=FALSE;
+ //printf("%s line %d: incrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level);
+}
+
+static void decrLevel()
+{
+ //printf("%s line %d: decrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level);
+ if (g_level > 0)
+ {
+ g_level--;
+ g_levelGuard.resize(g_level);
+ }
+ else
+ {
+ warn(g_yyFileName,g_yyLineNr,"More #endif's than #if's found.\n");
+ }
+}
+
+static bool otherCaseDone()
+{
+ if (g_level==0)
+ {
+ warn(g_yyFileName,g_yyLineNr,"Found an #else without a preceding #if.\n");
+ return TRUE;
+ }
+ else
+ {
+ return g_levelGuard[g_level-1];
+ }
+}
+
+static void setCaseDone(bool value)
+{
+ g_levelGuard[g_level-1]=value;
+}
+
+static QDict<void> g_allIncludes(10009);
+
+static FileState *checkAndOpenFile(const QCString &fileName,bool &alreadyIncluded)
+{
+ alreadyIncluded = FALSE;
+ FileState *fs = 0;
+ //printf("checkAndOpenFile(%s)\n",fileName.data());
+ QFileInfo fi(fileName);
+ if (fi.exists() && fi.isFile())
+ {
+ static QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS");
+ if (patternMatch(fi,&exclPatterns)) return 0;
+
+ QCString absName = fi.absFilePath().utf8();
+
+ // global guard
+ if (g_curlyCount==0) // not #include inside { ... }
+ {
+ if (g_allIncludes.find(absName)!=0)
+ {
+ alreadyIncluded = TRUE;
+ //printf(" already included 1\n");
+ return 0; // already done
+ }
+ g_allIncludes.insert(absName,(void *)0x8);
+ }
+ // check include stack for absName
+
+ QStack<FileState> tmpStack;
+ g_includeStack.setAutoDelete(FALSE);
+ while ((fs=g_includeStack.pop()))
+ {
+ if (fs->fileName==absName) alreadyIncluded=TRUE;
+ tmpStack.push(fs);
+ }
+ while ((fs=tmpStack.pop()))
+ {
+ g_includeStack.push(fs);
+ }
+ g_includeStack.setAutoDelete(TRUE);
+
+ if (alreadyIncluded)
+ {
+ //printf(" already included 2\n");
+ return 0;
+ }
+ //printf("#include %s\n",absName.data());
+
+ fs = new FileState(fi.size()+4096);
+ alreadyIncluded = FALSE;
+ if (!readInputFile(absName,fs->fileBuf))
+ { // error
+ //printf(" error reading\n");
+ delete fs;
+ fs=0;
+ }
+ else
+ {
+ fs->oldFileBuf = g_inputBuf;
+ fs->oldFileBufPos = g_inputBufPos;
+ }
+ }
+ return fs;
+}
+
+static FileState *findFile(const char *fileName,bool localInclude,bool &alreadyIncluded)
+{
+ //printf("** findFile(%s,%d) g_yyFileName=%s\n",fileName,localInclude,g_yyFileName.data());
+ if (portable_isAbsolutePath(fileName))
+ {
+ FileState *fs = checkAndOpenFile(fileName,alreadyIncluded);
+ if (fs)
+ {
+ setFileName(fileName);
+ g_yyLineNr=1;
+ return fs;
+ }
+ else if (alreadyIncluded)
+ {
+ return 0;
+ }
+ }
+ if (localInclude && !g_yyFileName.isEmpty())
+ {
+ QFileInfo fi(g_yyFileName);
+ if (fi.exists())
+ {
+ QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName;
+ FileState *fs = checkAndOpenFile(absName,alreadyIncluded);
+ if (fs)
+ {
+ setFileName(absName);
+ g_yyLineNr=1;
+ return fs;
+ }
+ else if (alreadyIncluded)
+ {
+ return 0;
+ }
+ }
+ }
+ if (g_pathList==0)
+ {
+ return 0;
+ }
+ char *s=g_pathList->first();
+ while (s)
+ {
+ QCString absName = (QCString)s+"/"+fileName;
+ //printf(" Looking for %s in %s\n",fileName,s);
+ FileState *fs = checkAndOpenFile(absName,alreadyIncluded);
+ if (fs)
+ {
+ setFileName(absName);
+ g_yyLineNr=1;
+ //printf(" -> found it\n");
+ return fs;
+ }
+ else if (alreadyIncluded)
+ {
+ return 0;
+ }
+
+ s=g_pathList->next();
+ }
+ return 0;
+}
+
+static QCString extractTrailingComment(const char *s)
+{
+ if (s==0) return "";
+ int i=strlen(s)-1;
+ while (i>=0)
+ {
+ char c=s[i];
+ switch (c)
+ {
+ case '/':
+ {
+ i--;
+ if (i>=0 && s[i]=='*') // end of a comment block
+ {
+ i--;
+ while (i>0 && !(s[i-1]=='/' && s[i]=='*')) i--;
+ if (i==0)
+ {
+ i++;
+ }
+ // only /*!< or /**< are treated as a comment for the macro name,
+ // otherwise the comment is treated as part of the macro definition
+ return ((s[i+1]=='*' || s[i+1]=='!') && s[i+2]=='<') ? &s[i-1] : "";
+ }
+ else
+ {
+ return "";
+ }
+ }
+ break;
+ // whitespace or line-continuation
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case '\\':
+ break;
+ default:
+ return "";
+ }
+ i--;
+ }
+ return "";
+}
+
+static int getNextChar(const QCString &expr,QCString *rest,uint &pos);
+static int getCurrentChar(const QCString &expr,QCString *rest,uint pos);
+static void unputChar(const QCString &expr,QCString *rest,uint &pos,char c);
+static void expandExpression(QCString &expr,QCString *rest,int pos);
+
+static QCString stringize(const QCString &s)
+{
+ QCString result;
+ uint i=0;
+ bool inString=FALSE;
+ bool inChar=FALSE;
+ char c,pc;
+ while (i<s.length())
+ {
+ if (!inString && !inChar)
+ {
+ while (i<s.length() && !inString && !inChar)
+ {
+ c=s.at(i++);
+ if (c=='"')
+ {
+ result+="\\\"";
+ inString=TRUE;
+ }
+ else if (c=='\'')
+ {
+ result+=c;
+ inChar=TRUE;
+ }
+ else
+ {
+ result+=c;
+ }
+ }
+ }
+ else if (inChar)
+ {
+ while (i<s.length() && inChar)
+ {
+ c=s.at(i++);
+ if (c=='\'')
+ {
+ result+='\'';
+ inChar=FALSE;
+ }
+ else if (c=='\\')
+ {
+ result+="\\\\";
+ }
+ else
+ {
+ result+=c;
+ }
+ }
+ }
+ else
+ {
+ pc=0;
+ while (i<s.length() && inString)
+ {
+ char c=s.at(i++);
+ if (c=='"')
+ {
+ result+="\\\"";
+ inString= pc=='\\';
+ }
+ else if (c=='\\')
+ result+="\\\\";
+ else
+ result+=c;
+ pc=c;
+ }
+ }
+ }
+ //printf("stringize `%s'->`%s'\n",s.data(),result.data());
+ return result;
+}
+
+/*! Execute all ## operators in expr.
+ * If the macro name before or after the operator contains a no-rescan
+ * marker (@-) then this is removed (before the concatenated macro name
+ * may be expanded again.
+ */
+static void processConcatOperators(QCString &expr)
+{
+ //printf("processConcatOperators: in=`%s'\n",expr.data());
+ QRegExp r("[ \\t\\n]*##[ \\t\\n]*");
+ int l,n,i=0;
+ if (expr.isEmpty()) return;
+ while ((n=r.match(expr,i,&l))!=-1)
+ {
+ //printf("Match: `%s'\n",expr.data()+i);
+ if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-')
+ {
+ // remove no-rescan marker after ID
+ l+=2;
+ }
+ //printf("found `%s'\n",expr.mid(n,l).data());
+ // remove the ## operator and the surrounding whitespace
+ expr=expr.left(n)+expr.right(expr.length()-n-l);
+ int k=n-1;
+ while (k>=0 && isId(expr.at(k))) k--;
+ if (k>0 && expr.at(k)=='-' && expr.at(k-1)=='@')
+ {
+ // remove no-rescan marker before ID
+ expr=expr.left(k-1)+expr.right(expr.length()-k-1);
+ n-=2;
+ }
+ i=n;
+ }
+ //printf("processConcatOperators: out=`%s'\n",expr.data());
+}
+
+static void yyunput (int c,char *buf_ptr );
+static void returnCharToStream(char c)
+{
+ unput(c);
+}
+
+static inline void addTillEndOfString(const QCString &expr,QCString *rest,
+ uint &pos,char term,QCString &arg)
+{
+ int cc;
+ while ((cc=getNextChar(expr,rest,pos))!=EOF && cc!=0)
+ {
+ if (cc=='\\') arg+=(char)cc,cc=getNextChar(expr,rest,pos);
+ else if (cc==term) return;
+ arg+=(char)cc;
+ }
+}
+
+/*! replaces the function macro \a def whose argument list starts at
+ * \a pos in expression \a expr.
+ * Notice that this routine may scan beyond the \a expr string if needed.
+ * In that case the characters will be read from the input file.
+ * The replacement string will be returned in \a result and the
+ * length of the (unexpanded) argument list is stored in \a len.
+ */
+static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result)
+{
+ //printf("replaceFunctionMacro(expr=%s,rest=%s,pos=%d,def=%s) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),g_level);
+ uint j=pos;
+ len=0;
+ result.resize(0);
+ int cc;
+ while ((cc=getCurrentChar(expr,rest,j))!=EOF && isspace(cc))
+ {
+ len++;
+ getNextChar(expr,rest,j);
+ }
+ if (cc!='(')
+ {
+ unputChar(expr,rest,j,' ');
+ return FALSE;
+ }
+ getNextChar(expr,rest,j); // eat the `(' character
+
+ QDict<QCString> argTable; // list of arguments
+ argTable.setAutoDelete(TRUE);
+ QCString arg;
+ int argCount=0;
+ bool done=FALSE;
+
+ // PHASE 1: read the macro arguments
+ if (def->nargs==0)
+ {
+ while ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0)
+ {
+ char c = (char)cc;
+ if (c==')') break;
+ }
+ }
+ else
+ {
+ while (!done && (argCount<def->nargs || def->varArgs) &&
+ ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0)
+ )
+ {
+ char c=(char)cc;
+ if (c=='(') // argument is a function => search for matching )
+ {
+ int level=1;
+ arg+=c;
+ //char term='\0';
+ while ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0)
+ {
+ char c=(char)cc;
+ //printf("processing %c: term=%c (%d)\n",c,term,term);
+ if (c=='\'' || c=='\"') // skip ('s and )'s inside strings
+ {
+ arg+=c;
+ addTillEndOfString(expr,rest,j,c,arg);
+ }
+ if (c==')')
+ {
+ level--;
+ arg+=c;
+ if (level==0) break;
+ }
+ else if (c=='(')
+ {
+ level++;
+ arg+=c;
+ }
+ else
+ arg+=c;
+ }
+ }
+ else if (c==')' || c==',') // last or next argument found
+ {
+ if (c==',' && argCount==def->nargs-1 && def->varArgs)
+ {
+ arg=arg.stripWhiteSpace();
+ arg+=',';
+ }
+ else
+ {
+ QCString argKey;
+ argKey.sprintf("@%d",argCount++); // key name
+ arg=arg.stripWhiteSpace();
+ // add argument to the lookup table
+ argTable.insert(argKey, new QCString(arg));
+ arg.resize(0);
+ if (c==')') // end of the argument list
+ {
+ done=TRUE;
+ }
+ }
+ }
+ else if (c=='\"') // append literal strings
+ {
+ arg+=c;
+ bool found=FALSE;
+ while (!found && (cc=getNextChar(expr,rest,j))!=EOF && cc!=0)
+ {
+ found = cc=='"';
+ if (cc=='\\')
+ {
+ c=(char)cc;
+ arg+=c;
+ if ((cc=getNextChar(expr,rest,j))==EOF || cc==0) break;
+ }
+ c=(char)cc;
+ arg+=c;
+ }
+ }
+ else if (c=='\'') // append literal characters
+ {
+ arg+=c;
+ bool found=FALSE;
+ while (!found && (cc=getNextChar(expr,rest,j))!=EOF && cc!=0)
+ {
+ found = cc=='\'';
+ if (cc=='\\')
+ {
+ c=(char)cc;
+ arg+=c;
+ if ((cc=getNextChar(expr,rest,j))==EOF || cc==0) break;
+ }
+ c=(char)cc;
+ arg+=c;
+ }
+ }
+ else // append other characters
+ {
+ arg+=c;
+ }
+ }
+ }
+
+ // PHASE 2: apply the macro function
+ if (argCount==def->nargs || // same number of arguments
+ (argCount>=def->nargs-1 && def->varArgs)) // variadic macro with at least as many
+ // params as the non-variadic part (see bug731985)
+ {
+ uint k=0;
+ // substitution of all formal arguments
+ QCString resExpr;
+ const QCString d=def->definition.stripWhiteSpace();
+ //printf("Macro definition: %s\n",d.data());
+ bool inString=FALSE;
+ while (k<d.length())
+ {
+ if (d.at(k)=='@') // maybe a marker, otherwise an escaped @
+ {
+ if (d.at(k+1)=='@') // escaped @ => copy it (is unescaped later)
+ {
+ k+=2;
+ resExpr+="@@"; // we unescape these later
+ }
+ else if (d.at(k+1)=='-') // no-rescan marker
+ {
+ k+=2;
+ resExpr+="@-";
+ }
+ else // argument marker => read the argument number
+ {
+ QCString key="@";
+ QCString *subst=0;
+ bool hash=FALSE;
+ int l=k-1;
+ // search for ## backward
+ if (l>=0 && d.at(l)=='"') l--;
+ while (l>=0 && d.at(l)==' ') l--;
+ if (l>0 && d.at(l)=='#' && d.at(l-1)=='#') hash=TRUE;
+ k++;
+ // scan the number
+ while (k<d.length() && d.at(k)>='0' && d.at(k)<='9') key+=d.at(k++);
+ if (!hash)
+ {
+ // search for ## forward
+ l=k;
+ if (l<(int)d.length() && d.at(l)=='"') l++;
+ while (l<(int)d.length() && d.at(l)==' ') l++;
+ if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE;
+ }
+ //printf("request key %s result %s\n",key.data(),argTable[key]->data());
+ if (key.length()>1 && (subst=argTable[key]))
+ {
+ QCString substArg=*subst;
+ //printf("substArg=`%s'\n",substArg.data());
+ // only if no ## operator is before or after the argument
+ // marker we do macro expansion.
+ if (!hash) expandExpression(substArg,0,0);
+ if (inString)
+ {
+ //printf("`%s'=stringize(`%s')\n",stringize(*subst).data(),subst->data());
+
+ // if the marker is inside a string (because a # was put
+ // before the macro name) we must escape " and \ characters
+ resExpr+=stringize(substArg);
+ }
+ else
+ {
+ if (hash && substArg.isEmpty())
+ {
+ resExpr+="@E"; // empty argument will be remove later on
+ }
+ else if (g_nospaces)
+ {
+ resExpr+=substArg;
+ }
+ else
+ {
+ resExpr+=" "+substArg+" ";
+ }
+ }
+ }
+ }
+ }
+ else // no marker, just copy
+ {
+ if (!inString && d.at(k)=='\"')
+ {
+ inString=TRUE; // entering a literal string
+ }
+ else if (inString && d.at(k)=='\"' && (d.at(k-1)!='\\' || d.at(k-2)=='\\'))
+ {
+ inString=FALSE; // leaving a literal string
+ }
+ resExpr+=d.at(k++);
+ }
+ }
+ len=j-pos;
+ result=resExpr;
+ //printf("result after substitution `%s' expr=`%s'\n",
+ // result.data(),expr.mid(pos,len).data());
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*! returns the next identifier in string \a expr by starting at position \a p.
+ * The position of the identifier is returned (or -1 if nothing is found)
+ * and \a l is its length. Any quoted strings are skipping during the search.
+ */
+static int getNextId(const QCString &expr,int p,int *l)
+{
+ int n;
+ while (p<(int)expr.length())
+ {
+ char c=expr.at(p++);
+ if (isdigit(c)) // skip number
+ {
+ while (p<(int)expr.length() && isId(expr.at(p))) p++;
+ }
+ else if (isalpha(c) || c=='_') // read id
+ {
+ n=p-1;
+ while (p<(int)expr.length() && isId(expr.at(p))) p++;
+ *l=p-n;
+ return n;
+ }
+ else if (c=='"') // skip string
+ {
+ char ppc=0,pc=c;
+ if (p<(int)expr.length()) c=expr.at(p);
+ while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\')))
+ // continue as long as no " is found, but ignoring \", but not \\"
+ {
+ ppc=pc;
+ pc=c;
+ c=expr.at(p);
+ p++;
+ }
+ if (p<(int)expr.length()) ++p; // skip closing quote
+ }
+ else if (c=='/') // skip C Comment
+ {
+ //printf("Found C comment at p=%d\n",p);
+ char pc=c;
+ if (p<(int)expr.length())
+ {
+ c=expr.at(p);
+ if (c=='*') // Start of C comment
+ {
+ p++;
+ while (p<(int)expr.length() && !(pc=='*' && c=='/'))
+ {
+ pc=c;
+ c=expr.at(p++);
+ }
+ }
+ }
+ //printf("Found end of C comment at p=%d\n",p);
+ }
+ }
+ return -1;
+}
+
+/*! preforms recursive macro expansion on the string \a expr
+ * starting at position \a pos.
+ * May read additional characters from the input while re-scanning!
+ * If \a expandAll is \c TRUE then all macros in the expression are
+ * expanded, otherwise only the first is expanded.
+ */
+static void expandExpression(QCString &expr,QCString *rest,int pos)
+{
+ //printf("expandExpression(%s,%s)\n",expr.data(),rest ? rest->data() : 0);
+ QCString macroName;
+ QCString expMacro;
+ bool definedTest=FALSE;
+ int i=pos,l,p,len;
+ while ((p=getNextId(expr,i,&l))!=-1) // search for an macro name
+ {
+ bool replaced=FALSE;
+ macroName=expr.mid(p,l);
+ //printf("macroName=%s\n",macroName.data());
+ if (p<2 || !(expr.at(p-2)=='@' && expr.at(p-1)=='-')) // no-rescan marker?
+ {
+ if (g_expandedDict->find(macroName)==0) // expand macro
+ {
+ Define *def=DefineManager::instance().isDefined(macroName);
+ if (definedTest) // macro name was found after defined
+ {
+ if (def) expMacro = " 1 "; else expMacro = " 0 ";
+ replaced=TRUE;
+ len=l;
+ definedTest=FALSE;
+ }
+ else if (def && def->nargs==-1) // simple macro
+ {
+ // substitute the definition of the macro
+ //printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data());
+ if (g_nospaces)
+ {
+ expMacro=def->definition.stripWhiteSpace();
+ }
+ else
+ {
+ expMacro=" "+def->definition.stripWhiteSpace()+" ";
+ }
+ //expMacro=def->definition.stripWhiteSpace();
+ replaced=TRUE;
+ len=l;
+ //printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data());
+ }
+ else if (def && def->nargs>=0) // function macro
+ {
+ replaced=replaceFunctionMacro(expr,rest,p+l,len,def,expMacro);
+ len+=l;
+ }
+ else if (macroName=="defined")
+ {
+ //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data());
+ definedTest=TRUE;
+ }
+
+ if (replaced) // expand the macro and rescan the expression
+ {
+
+ //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data());
+ QCString resultExpr=expMacro;
+ QCString restExpr=expr.right(expr.length()-len-p);
+ processConcatOperators(resultExpr);
+ if (def && !def->nonRecursive)
+ {
+ g_expandedDict->insert(macroName,def);
+ expandExpression(resultExpr,&restExpr,0);
+ g_expandedDict->remove(macroName);
+ }
+ expr=expr.left(p)+resultExpr+restExpr;
+ i=p;
+ //printf("new expression: %s\n",expr.data());
+ }
+ else // move to the next macro name
+ {
+ //printf("moving to the next macro old=%d new=%d\n",i,p+l);
+ i=p+l;
+ }
+ }
+ else // move to the next macro name
+ {
+ expr=expr.left(p)+"@-"+expr.right(expr.length()-p);
+ //printf("macro already expanded, moving to the next macro expr=%s\n",expr.data());
+ i=p+l+2;
+ //i=p+l;
+ }
+ }
+ else // no re-scan marker found, skip the macro name
+ {
+ //printf("skipping marked macro\n");
+ i=p+l;
+ }
+ }
+}
+
+/*! replaces all occurrences of @@@@ in \a s by @@
+ * and removes all occurrences of @@E.
+ * All identifiers found are replaced by 0L
+ */
+QCString removeIdsAndMarkers(const char *s)
+{
+ //printf("removeIdsAndMarkers(%s)\n",s);
+ const char *p=s;
+ char c;
+ bool inNum=FALSE;
+ QCString result;
+ if (p)
+ {
+ while ((c=*p))
+ {
+ if (c=='@') // replace @@ with @ and remove @E
+ {
+ if (*(p+1)=='@')
+ {
+ result+=c;
+ }
+ else if (*(p+1)=='E')
+ {
+ // skip
+ }
+ p+=2;
+ }
+ else if (isdigit(c)) // number
+ {
+ result+=c;
+ p++;
+ inNum=TRUE;
+ }
+ else if (c=='d' && !inNum) // identifier starting with a `d'
+ {
+ if (qstrncmp(p,"defined ",8)==0 || qstrncmp(p,"defined(",8)==0)
+ // defined keyword
+ {
+ p+=7; // skip defined
+ }
+ else
+ {
+ result+="0L";
+ p++;
+ while ((c=*p) && isId(c)) p++;
+ }
+ }
+ else if ((isalpha(c) || c=='_') && !inNum) // replace identifier with 0L
+ {
+ result+="0L";
+ p++;
+ while ((c=*p) && isId(c)) p++;
+ if (*p=='(') // undefined function macro
+ {
+ p++;
+ int count=1;
+ while ((c=*p++))
+ {
+ if (c=='(') count++;
+ else if (c==')')
+ {
+ count--;
+ if (count==0) break;
+ }
+ else if (c=='/')
+ {
+ char pc=c;
+ c=*++p;
+ if (c=='*') // start of C comment
+ {
+ while (*p && !(pc=='*' && c=='/')) // search end of comment
+ {
+ pc=c;
+ c=*++p;
+ }
+ p++;
+ }
+ }
+ }
+ }
+ }
+ else if (c=='/') // skip C comments
+ {
+ char pc=c;
+ c=*++p;
+ if (c=='*') // start of C comment
+ {
+ while (*p && !(pc=='*' && c=='/')) // search end of comment
+ {
+ pc=c;
+ c=*++p;
+ }
+ p++;
+ }
+ else // oops, not comment but division
+ {
+ result+=pc;
+ goto nextChar;
+ }
+ }
+ else
+ {
+nextChar:
+ result+=c;
+ char lc=tolower(c);
+ if (!isId(lc) && lc!='.' /*&& lc!='-' && lc!='+'*/) inNum=FALSE;
+ p++;
+ }
+ }
+ }
+ //printf("removeIdsAndMarkers(%s)=%s\n",s,result.data());
+ return result;
+}
+
+/*! replaces all occurrences of @@ in \a s by @
+ * \par assumption:
+ * \a s only contains pairs of @@'s
+ */
+QCString removeMarkers(const char *s)
+{
+ const char *p=s;
+ char c;
+ QCString result;
+ if (p)
+ {
+ while ((c=*p))
+ {
+ switch(c)
+ {
+ case '@': // replace @@ with @
+ {
+ if (*(p+1)=='@')
+ {
+ result+=c;
+ }
+ p+=2;
+ }
+ break;
+ case '/': // skip C comments
+ {
+ result+=c;
+ char pc=c;
+ c=*++p;
+ if (c=='*') // start of C comment
+ {
+ while (*p && !(pc=='*' && c=='/')) // search end of comment
+ {
+ if (*p=='@' && *(p+1)=='@')
+ result+=c,p++;
+ else
+ result+=c;
+ pc=c;
+ c=*++p;
+ }
+ if (*p) result+=c,p++;
+ }
+ }
+ break;
+ case '"': // skip string literals
+ {
+ result+=c;
+ char pc=c;
+ c=*++p;
+ while (*p && (c!='"' || pc=='\\')) // no end quote
+ {
+ result+=c;
+ c=*++p;
+ }
+ if (*p) result+=c,p++;
+ }
+ break;
+ case '\'': // skip char literals
+ {
+ result+=c;
+ char pc=c;
+ c=*++p;
+ while (*p && (c!='\'' || pc=='\\')) // no end quote
+ {
+ result+=c;
+ c=*++p;
+ }
+ if (*p) result+=c,p++;
+ }
+ break;
+ default:
+ {
+ result+=c;
+ p++;
+ }
+ break;
+ }
+ }
+ }
+ //printf("RemoveMarkers(%s)=%s\n",s,result.data());
+ return result;
+}
+
+/*! compute the value of the expression in string \a expr.
+ * If needed the function may read additional characters from the input.
+ */
+
+bool computeExpression(const QCString &expr)
+{
+ QCString e=expr;
+ expandExpression(e,0,0);
+ //printf("after expansion `%s'\n",e.data());
+ e = removeIdsAndMarkers(e);
+ if (e.isEmpty()) return FALSE;
+ //printf("parsing `%s'\n",e.data());
+ return parseconstexp(g_yyFileName,g_yyLineNr,e);
+}
+
+/*! expands the macro definition in \a name
+ * If needed the function may read additional characters from the input
+ */
+
+QCString expandMacro(const QCString &name)
+{
+ QCString n=name;
+ expandExpression(n,0,0);
+ n=removeMarkers(n);
+ //printf("expandMacro `%s'->`%s'\n",name.data(),n.data());
+ return n;
+}
+
+Define *newDefine()
+{
+ Define *def=new Define;
+ def->name = g_defName;
+ def->definition = g_defText.stripWhiteSpace();
+ def->nargs = g_defArgs;
+ def->fileName = g_yyFileName;
+ def->fileDef = g_yyFileDef;
+ def->lineNr = g_yyLineNr-g_yyMLines;
+ def->columnNr = g_yyColNr;
+ def->varArgs = g_defVarArgs;
+ //printf("newDefine: %s %s file: %s\n",def->name.data(),def->definition.data(),
+ // def->fileDef ? def->fileDef->name().data() : def->fileName.data());
+ //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data());
+ if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name])
+ {
+ def->isPredefined=TRUE;
+ }
+ return def;
+}
+
+void addDefine()
+{
+ if (g_skip) return; // do not add this define as it is inside a
+ // conditional section (cond command) that is disabled.
+ if (!Doxygen::gatherDefines) return;
+
+ //printf("addDefine %s %s\n",g_defName.data(),g_defArgsStr.data());
+ //ArgumentList *al = new ArgumentList;
+ //stringToArgumentList(g_defArgsStr,al);
+ MemberDef *md=new MemberDef(
+ g_yyFileName,g_yyLineNr-g_yyMLines,g_yyColNr,
+ "#define",g_defName,g_defArgsStr,0,
+ Public,Normal,FALSE,Member,MemberType_Define,0,0);
+ if (!g_defArgsStr.isEmpty())
+ {
+ ArgumentList *argList = new ArgumentList;
+ //printf("addDefine() g_defName=`%s' g_defArgsStr=`%s'\n",g_defName.data(),g_defArgsStr.data());
+ stringToArgumentList(g_defArgsStr,argList);
+ md->setArgumentList(argList);
+ }
+ //printf("Setting initializer for `%s' to `%s'\n",g_defName.data(),g_defText.data());
+ int l=g_defLitText.find('\n');
+ if (l>0 && g_defLitText.left(l).stripWhiteSpace()=="\\")
+ {
+ // strip first line if it only contains a slash
+ g_defLitText = g_defLitText.right(g_defLitText.length()-l-1);
+ }
+ else if (l>0)
+ {
+ // align the items on the first line with the items on the second line
+ int k=l+1;
+ const char *p=g_defLitText.data()+k;
+ char c;
+ while ((c=*p++) && (c==' ' || c=='\t')) k++;
+ g_defLitText=g_defLitText.mid(l+1,k-l-1)+g_defLitText.stripWhiteSpace();
+ }
+ md->setInitializer(g_defLitText.stripWhiteSpace());
+
+ //printf("pre.l: md->setFileDef(%p)\n",g_inputFileDef);
+ md->setFileDef(g_inputFileDef);
+ md->setDefinition("#define "+g_defName);
+
+ MemberName *mn=Doxygen::functionNameSDict->find(g_defName);
+ if (mn==0)
+ {
+ mn = new MemberName(g_defName);
+ Doxygen::functionNameSDict->append(g_defName,mn);
+ }
+ mn->append(md);
+ if (g_yyFileDef)
+ {
+ g_yyFileDef->insertMember(md);
+ }
+
+ //Define *d;
+ //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine());
+}
+
+static inline void outputChar(char c)
+{
+ if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addChar(c);
+}
+
+static inline void outputArray(const char *a,int len)
+{
+ if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addArray(a,len);
+}
+
+static void readIncludeFile(const QCString &inc)
+{
+ static bool searchIncludes = Config_getBool("SEARCH_INCLUDES");
+ uint i=0;
+
+ // find the start of the include file name
+ while (i<inc.length() &&
+ (inc.at(i)==' ' || inc.at(i)=='"' || inc.at(i)=='<')
+ ) i++;
+ uint s=i;
+
+ // was it a local include?
+ bool localInclude = s>0 && inc.at(s-1)=='"';
+
+ // find the end of the include file name
+ while (i<inc.length() && inc.at(i)!='"' && inc.at(i)!='>') i++;
+
+ if (s<inc.length() && i>s) // valid include file name found
+ {
+ // extract include path+name
+ QCString incFileName=inc.mid(s,i-s).stripWhiteSpace();
+
+ QCString dosExt = incFileName.right(4);
+ if (dosExt==".exe" || dosExt==".dll" || dosExt==".tlb")
+ {
+ // skip imported binary files (e.g. M$ type libraries)
+ return;
+ }
+
+ QCString oldFileName = g_yyFileName;
+ FileDef *oldFileDef = g_yyFileDef;
+ int oldLineNr = g_yyLineNr;
+ //printf("Searching for `%s'\n",incFileName.data());
+
+ // absIncFileName avoids difficulties for incFileName starting with "../" (bug 641336)
+ QCString absIncFileName = incFileName;
+ {
+ QFileInfo fi(g_yyFileName);
+ if (fi.exists())
+ {
+ QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName;
+ QFileInfo fi2(absName);
+ if (fi2.exists())
+ {
+ absIncFileName=fi2.absFilePath().utf8();
+ }
+ else if (searchIncludes) // search in INCLUDE_PATH as well
+ {
+ QStrList &includePath = Config_getList("INCLUDE_PATH");
+ char *s=includePath.first();
+ while (s)
+ {
+ QFileInfo fi(s);
+ if (fi.exists() && fi.isDir())
+ {
+ QCString absName = QCString(fi.absFilePath().utf8())+"/"+incFileName;
+ //printf("trying absName=%s\n",absName.data());
+ QFileInfo fi2(absName);
+ if (fi2.exists())
+ {
+ absIncFileName=fi2.absFilePath().utf8();
+ break;
+ }
+ //printf( "absIncFileName = %s\n", absIncFileName.data() );
+ }
+ s=includePath.next();
+ }
+ }
+ //printf( "absIncFileName = %s\n", absIncFileName.data() );
+ }
+ }
+ DefineManager::instance().addInclude(g_yyFileName,absIncFileName);
+ DefineManager::instance().addFileToContext(absIncFileName);
+
+ // findFile will overwrite g_yyFileDef if found
+ FileState *fs;
+ bool alreadyIncluded = FALSE;
+ //printf("calling findFile(%s)\n",incFileName.data());
+ if ((fs=findFile(incFileName,localInclude,alreadyIncluded))) // see if the include file can be found
+ {
+ //printf("Found include file!\n");
+ if (Debug::isFlagSet(Debug::Preprocessor))
+ {
+ for (i=0;i<g_includeStack.count();i++)
+ {
+ Debug::print(Debug::Preprocessor,0," ");
+ }
+ //msg("#include %s: parsing...\n",incFileName.data());
+ }
+ if (oldFileDef)
+ {
+ // add include dependency to the file in which the #include was found
+ bool ambig;
+ // change to absolute name for bug 641336
+ FileDef *incFd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig);
+ oldFileDef->addIncludeDependency(ambig ? 0 : incFd,incFileName,localInclude,g_isImported,FALSE);
+ // add included by dependency
+ if (g_yyFileDef)
+ {
+ //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data());
+ g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
+ }
+ }
+ else if (g_inputFileDef)
+ {
+ g_inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,g_isImported,TRUE);
+ }
+ fs->bufState = YY_CURRENT_BUFFER;
+ fs->lineNr = oldLineNr;
+ fs->fileName = oldFileName;
+ // push the state on the stack
+ g_includeStack.push(fs);
+ // set the scanner to the include file
+
+ // Deal with file changes due to
+ // #include's within { .. } blocks
+ QCString lineStr(g_yyFileName.length()+20);
+ lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data());
+ outputArray(lineStr.data(),lineStr.length());
+
+ DBG_CTX((stderr,"Switching to include file %s\n",incFileName.data()));
+ g_expectGuard=TRUE;
+ g_inputBuf = &fs->fileBuf;
+ g_inputBufPos=0;
+ yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE));
+ }
+ else
+ {
+ //printf(" calling findFile(%s) alreadyInc=%d\n",incFileName.data(),alreadyIncluded);
+ if (oldFileDef)
+ {
+ bool ambig;
+ //QCString absPath = incFileName;
+ //if (QDir::isRelativePath(incFileName))
+ //{
+ // absPath = QDir::cleanDirPath(oldFileDef->getPath()+"/"+incFileName);
+ // //printf("%s + %s -> resolved path %s\n",oldFileDef->getPath().data(),incFileName.data(),absPath.data());
+ //}
+
+ // change to absolute name for bug 641336
+ FileDef *fd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig);
+ //printf("%s::findFileDef(%s)=%p\n",oldFileDef->name().data(),incFileName.data(),fd);
+ // add include dependency to the file in which the #include was found
+ oldFileDef->addIncludeDependency(ambig ? 0 : fd,incFileName,localInclude,g_isImported,FALSE);
+ // add included by dependency
+ if (fd)
+ {
+ //printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig);
+ fd->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
+ }
+ }
+ else if (g_inputFileDef)
+ {
+ g_inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,g_isImported,TRUE);
+ }
+ if (Debug::isFlagSet(Debug::Preprocessor))
+ {
+ if (alreadyIncluded)
+ {
+ Debug::print(Debug::Preprocessor,0,"#include %s: already included! skipping...\n",incFileName.data());
+ }
+ else
+ {
+ Debug::print(Debug::Preprocessor,0,"#include %s: not found! skipping...\n",incFileName.data());
+ }
+ //printf("error: include file %s not found\n",yytext);
+ }
+ if (g_curlyCount>0 && !alreadyIncluded) // failed to find #include inside { ... }
+ {
+ warn(g_yyFileName,g_yyLineNr,"include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",incFileName.data());
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------- */
+
+static void startCondSection(const char *sectId)
+{
+ //printf("startCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
+ CondParser prs;
+ bool expResult = prs.parse(g_yyFileName,g_yyLineNr,sectId);
+ g_condStack.push(new CondCtx(g_yyLineNr,sectId,g_skip));
+ if (!expResult)
+ {
+ g_skip=TRUE;
+ }
+ //printf(" expResult=%d skip=%d\n",expResult,g_skip);
+}
+
+static void endCondSection()
+{
+ if (g_condStack.isEmpty())
+ {
+ g_skip=FALSE;
+ }
+ else
+ {
+ CondCtx *ctx = g_condStack.pop();
+ g_skip=ctx->skip;
+ }
+ //printf("endCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
+}
+
+static void forceEndCondSection()
+{
+ while (!g_condStack.isEmpty())
+ {
+ g_condStack.pop();
+ }
+ g_skip=FALSE;
+}
+
+static QCString escapeAt(const char *text)
+{
+ QCString result;
+ if (text)
+ {
+ char c;
+ const char *p=text;
+ while ((c=*p++))
+ {
+ if (c=='@') result+="@@"; else result+=c;
+ }
+ }
+ return result;
+}
+
+static char resolveTrigraph(char c)
+{
+ switch (c)
+ {
+ case '=': return '#';
+ case '/': return '\\';
+ case '\'': return '^';
+ case '(': return '[';
+ case ')': return ']';
+ case '!': return '|';
+ case '<': return '{';
+ case '>': return '}';
+ case '-': return '~';
+ }
+ return '?';
+}
+
+/* ----------------------------------------------------------------- */
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int bytesInBuf = g_inputBuf->curPos()-g_inputBufPos;
+ int bytesToCopy = QMIN(max_size,bytesInBuf);
+ memcpy(buf,g_inputBuf->data()+g_inputBufPos,bytesToCopy);
+ g_inputBufPos+=bytesToCopy;
+ return bytesToCopy;
+}
+
+/* ----------------------------------------------------------------- */
+
+%}
+
+ID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+B [ \t]
+BN [ \t\r\n]
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
+
+%option noyywrap
+
+%x Start
+%x Command
+%x SkipCommand
+%x SkipLine
+%x SkipString
+%x CopyLine
+%x CopyString
+%x Include
+%x IncludeID
+%x EndImport
+%x DefName
+%x DefineArg
+%x DefineText
+%x SkipCPPBlock
+%x Ifdef
+%x Ifndef
+%x SkipCComment
+%x ArgCopyCComment
+%x CopyCComment
+%x SkipVerbatim
+%x SkipCPPComment
+%x RemoveCComment
+%x RemoveCPPComment
+%x Guard
+%x DefinedExpr1
+%x DefinedExpr2
+%x SkipDoubleQuote
+%x SkipSingleQuote
+%x UndefName
+%x IgnoreLine
+%x FindDefineArgs
+%x ReadString
+%x CondLineC
+%x CondLineCpp
+%x SkipCond
+
+%%
+
+<*>\x06
+<*>\x00
+<*>\r
+<*>"??"[=/'()!<>-] { // Trigraph
+ unput(resolveTrigraph(yytext[2]));
+ }
+<Start>^{B}*"#" { BEGIN(Command); g_yyColNr+=yyleng; g_yyMLines=0;}
+<Start>^{B}*/[^#] {
+ outputArray(yytext,(int)yyleng);
+ BEGIN(CopyLine);
+ }
+<Start>^{B}*[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]+{B}*"("[^\)\n]*")"/{BN}{1,10}*[:{] { // constructors?
+ int i;
+ for (i=(int)yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ BEGIN(CopyLine);
+ }
+<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\(\)\n]*"("[^\)\n]*")"[^\)\n]*")"{B}*\n | // function list macro with one (...) argument, e.g. for K_GLOBAL_STATIC_WITH_ARGS
+<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\)\n]*")"{B}*\n { // function like macro
+ static bool skipFuncMacros = Config_getBool("SKIP_FUNCTION_MACROS");
+ QCString name(yytext);
+ name=name.left(name.find('(')).stripWhiteSpace();
+
+ Define *def=0;
+ if (skipFuncMacros &&
+ name!="Q_PROPERTY" &&
+ !(
+ (g_includeStack.isEmpty() || g_curlyCount>0) &&
+ g_macroExpansion &&
+ (def=DefineManager::instance().isDefined(name)) &&
+ /*macroIsAccessible(def) &&*/
+ (!g_expandOnlyPredef || def->isPredefined)
+ )
+ )
+ {
+ outputChar('\n');
+ g_yyLineNr++;
+ }
+ else // don't skip
+ {
+ int i;
+ for (i=(int)yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ BEGIN(CopyLine);
+ }
+ }
+<CopyLine>"extern"{BN}{0,80}"\"C\""*{BN}{0,80}"{" {
+ QCString text=yytext;
+ g_yyLineNr+=text.contains('\n');
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyLine>"{" { // count brackets inside the main file
+ if (g_includeStack.isEmpty())
+ {
+ g_curlyCount++;
+ }
+ outputChar(*yytext);
+ }
+<CopyLine>"}" { // count brackets inside the main file
+ if (g_includeStack.isEmpty() && g_curlyCount>0)
+ {
+ g_curlyCount--;
+ }
+ outputChar(*yytext);
+ }
+<CopyLine>"'"\\[0-7]{1,3}"'" {
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyLine>"'"\\."'" {
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyLine>"'"."'" {
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyLine>\" {
+ outputChar(*yytext);
+ BEGIN( CopyString );
+ }
+<CopyString>[^\"\\\r\n]+ {
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyString>\\. {
+ outputArray(yytext,(int)yyleng);
+ }
+<CopyString>\" {
+ outputChar(*yytext);
+ BEGIN( CopyLine );
+ }
+<CopyLine>{ID}/{BN}{0,80}"(" {
+ g_expectGuard = FALSE;
+ Define *def=0;
+ //def=g_globalDefineDict->find(yytext);
+ //def=DefineManager::instance().isDefined(yytext);
+ //printf("Search for define %s found=%d g_includeStack.isEmpty()=%d "
+ // "g_curlyCount=%d g_macroExpansion=%d g_expandOnlyPredef=%d "
+ // "isPreDefined=%d\n",yytext,def ? 1 : 0,
+ // g_includeStack.isEmpty(),g_curlyCount,g_macroExpansion,g_expandOnlyPredef,
+ // def ? def->isPredefined : -1
+ // );
+ if ((g_includeStack.isEmpty() || g_curlyCount>0) &&
+ g_macroExpansion &&
+ (def=DefineManager::instance().isDefined(yytext)) &&
+ /*(def->isPredefined || macroIsAccessible(def)) && */
+ (!g_expandOnlyPredef || def->isPredefined)
+ )
+ {
+ //printf("Found it! #args=%d\n",def->nargs);
+ g_roundCount=0;
+ g_defArgsStr=yytext;
+ if (def->nargs==-1) // no function macro
+ {
+ QCString result = def->isPredefined ? def->definition : expandMacro(g_defArgsStr);
+ outputArray(result,result.length());
+ }
+ else // zero or more arguments
+ {
+ g_findDefArgContext = CopyLine;
+ BEGIN(FindDefineArgs);
+ }
+ }
+ else
+ {
+ outputArray(yytext,(int)yyleng);
+ }
+ }
+<CopyLine>{ID} {
+ Define *def=0;
+ if ((g_includeStack.isEmpty() || g_curlyCount>0) &&
+ g_macroExpansion &&
+ (def=DefineManager::instance().isDefined(yytext)) &&
+ def->nargs==-1 &&
+ /*(def->isPredefined || macroIsAccessible(def)) &&*/
+ (!g_expandOnlyPredef || def->isPredefined)
+ )
+ {
+ QCString result=def->isPredefined ? def->definition : expandMacro(yytext);
+ outputArray(result,result.length());
+ }
+ else
+ {
+ outputArray(yytext,(int)yyleng);
+ }
+ }
+<CopyLine>"\\"\r?/\n { // strip line continuation characters
+ }
+<CopyLine>. {
+ outputChar(*yytext);
+ }
+<CopyLine>\n {
+ outputChar('\n');
+ BEGIN(Start);
+ g_yyLineNr++;
+ g_yyColNr=1;
+ }
+<FindDefineArgs>"(" {
+ g_defArgsStr+='(';
+ g_roundCount++;
+ }
+<FindDefineArgs>")" {
+ g_defArgsStr+=')';
+ g_roundCount--;
+ if (g_roundCount==0)
+ {
+ QCString result=expandMacro(g_defArgsStr);
+ //printf("g_defArgsStr=`%s'->`%s'\n",g_defArgsStr.data(),result.data());
+ if (g_findDefArgContext==CopyLine)
+ {
+ outputArray(result,result.length());
+ BEGIN(g_findDefArgContext);
+ }
+ else // g_findDefArgContext==IncludeID
+ {
+ readIncludeFile(result);
+ g_nospaces=FALSE;
+ BEGIN(Start);
+ }
+ }
+ }
+ /*
+<FindDefineArgs>")"{B}*"(" {
+ g_defArgsStr+=yytext;
+ }
+ */
+<FindDefineArgs>{CHARLIT} {
+ g_defArgsStr+=yytext;
+ }
+<FindDefineArgs>"/*"[*]? {
+ g_defArgsStr+=yytext;
+ BEGIN(ArgCopyCComment);
+ }
+<FindDefineArgs>\" {
+ g_defArgsStr+=*yytext;
+ BEGIN(ReadString);
+ }
+<FindDefineArgs>\n {
+ g_defArgsStr+=' ';
+ g_yyLineNr++;
+ outputChar('\n');
+ }
+<FindDefineArgs>"@" {
+ g_defArgsStr+="@@";
+ }
+<FindDefineArgs>. {
+ g_defArgsStr+=*yytext;
+ }
+<ArgCopyCComment>[^*\n]+ {
+ g_defArgsStr+=yytext;
+ }
+<ArgCopyCComment>"*/" {
+ g_defArgsStr+=yytext;
+ BEGIN(FindDefineArgs);
+ }
+<ArgCopyCComment>\n {
+ g_defArgsStr+=' ';
+ g_yyLineNr++;
+ outputChar('\n');
+ }
+<ArgCopyCComment>. {
+ g_defArgsStr+=yytext;
+ }
+<ReadString>"\"" {
+ g_defArgsStr+=*yytext;
+ BEGIN(FindDefineArgs);
+ }
+<ReadString>"//"|"/*" {
+ g_defArgsStr+=yytext;
+ }
+<ReadString>\\. {
+ g_defArgsStr+=yytext;
+ }
+<ReadString>. {
+ g_defArgsStr+=*yytext;
+ }
+<Command>("include"|"import"){B}+/{ID} {
+ g_isImported = yytext[1]=='m';
+ if (g_macroExpansion)
+ BEGIN(IncludeID);
+ }
+<Command>("include"|"import"){B}*[<"] {
+ g_isImported = yytext[1]=='m';
+ char c[2];
+ c[0]=yytext[yyleng-1];c[1]='\0';
+ g_incName=c;
+ BEGIN(Include);
+ }
+<Command>("cmake")?"define"{B}+ {
+ //printf("!!!DefName\n");
+ g_yyColNr+=yyleng;
+ BEGIN(DefName);
+ }
+<Command>"ifdef"/{B}*"(" {
+ incrLevel();
+ g_guardExpr.resize(0);
+ BEGIN(DefinedExpr2);
+ }
+<Command>"ifdef"/{B}+ {
+ //printf("Pre.l: ifdef\n");
+ incrLevel();
+ g_guardExpr.resize(0);
+ BEGIN(DefinedExpr1);
+ }
+<Command>"ifndef"/{B}*"(" {
+ incrLevel();
+ g_guardExpr="! ";
+ BEGIN(DefinedExpr2);
+ }
+<Command>"ifndef"/{B}+ {
+ incrLevel();
+ g_guardExpr="! ";
+ BEGIN(DefinedExpr1);
+ }
+<Command>"if"/[ \t(!] {
+ incrLevel();
+ g_guardExpr.resize(0);
+ BEGIN(Guard);
+ }
+<Command>("elif"|"else"{B}*"if")/[ \t(!] {
+ if (!otherCaseDone())
+ {
+ g_guardExpr.resize(0);
+ BEGIN(Guard);
+ }
+ else
+ {
+ g_ifcount=0;
+ BEGIN(SkipCPPBlock);
+ }
+ }
+<Command>"else"/[^a-z_A-Z0-9\x80-\xFF] {
+ //printf("else g_levelGuard[%d]=%d\n",g_level-1,g_levelGuard[g_level-1]);
+ if (otherCaseDone())
+ {
+ g_ifcount=0;
+ BEGIN(SkipCPPBlock);
+ }
+ else
+ {
+ setCaseDone(TRUE);
+ //g_levelGuard[g_level-1]=TRUE;
+ }
+ }
+<Command>"undef"{B}+ {
+ BEGIN(UndefName);
+ }
+<Command>("elif"|"else"{B}*"if")/[ \t(!] {
+ if (!otherCaseDone())
+ {
+ g_guardExpr.resize(0);
+ BEGIN(Guard);
+ }
+ }
+<Command>"endif"/[^a-z_A-Z0-9\x80-\xFF] {
+ //printf("Pre.l: #endif\n");
+ decrLevel();
+ }
+<Command,IgnoreLine>\n {
+ outputChar('\n');
+ BEGIN(Start);
+ g_yyLineNr++;
+ }
+<Command>"pragma"{B}+"once" {
+ g_expectGuard = FALSE;
+ }
+<Command>{ID} { // unknown directive
+ BEGIN(IgnoreLine);
+ }
+<IgnoreLine>\\[\r]?\n {
+ outputChar('\n');
+ g_yyLineNr++;
+ }
+<IgnoreLine>.
+<Command>. {g_yyColNr+=yyleng;}
+<UndefName>{ID} {
+ Define *def;
+ if ((def=DefineManager::instance().isDefined(yytext))
+ /*&& !def->isPredefined*/
+ && !def->nonRecursive
+ )
+ {
+ //printf("undefining %s\n",yytext);
+ def->undef=TRUE;
+ }
+ BEGIN(Start);
+ }
+<Guard>\\[\r]?\n {
+ outputChar('\n');
+ g_guardExpr+=' ';
+ g_yyLineNr++;
+ }
+<Guard>"defined"/{B}*"(" {
+ BEGIN(DefinedExpr2);
+ }
+<Guard>"defined"/{B}+ {
+ BEGIN(DefinedExpr1);
+ }
+<Guard>{ID} { g_guardExpr+=yytext; }
+<Guard>. { g_guardExpr+=*yytext; }
+<Guard>\n {
+ unput(*yytext);
+ //printf("Guard: `%s'\n",
+ // g_guardExpr.data());
+ bool guard=computeExpression(g_guardExpr);
+ setCaseDone(guard);
+ //printf("if g_levelGuard[%d]=%d\n",g_level-1,g_levelGuard[g_level-1]);
+ if (guard)
+ {
+ BEGIN(Start);
+ }
+ else
+ {
+ g_ifcount=0;
+ BEGIN(SkipCPPBlock);
+ }
+ }
+<DefinedExpr1,DefinedExpr2>\\\n { g_yyLineNr++; outputChar('\n'); }
+<DefinedExpr1>{ID} {
+ if (DefineManager::instance().isDefined(yytext) || g_guardName==yytext)
+ g_guardExpr+=" 1L ";
+ else
+ g_guardExpr+=" 0L ";
+ g_lastGuardName=yytext;
+ BEGIN(Guard);
+ }
+<DefinedExpr2>{ID} {
+ if (DefineManager::instance().isDefined(yytext) || g_guardName==yytext)
+ g_guardExpr+=" 1L ";
+ else
+ g_guardExpr+=" 0L ";
+ g_lastGuardName=yytext;
+ }
+<DefinedExpr1,DefinedExpr2>\n { // should not happen, handle anyway
+ g_yyLineNr++;
+ g_ifcount=0;
+ BEGIN(SkipCPPBlock);
+ }
+<DefinedExpr2>")" {
+ BEGIN(Guard);
+ }
+<DefinedExpr1,DefinedExpr2>.
+<SkipCPPBlock>^{B}*"#" { BEGIN(SkipCommand); }
+<SkipCPPBlock>^{B}*/[^#] { BEGIN(SkipLine); }
+<SkipCPPBlock>\n { g_yyLineNr++; outputChar('\n'); }
+<SkipCPPBlock>.
+<SkipCommand>"if"(("n")?("def"))?/[ \t(!] {
+ incrLevel();
+ g_ifcount++;
+ //printf("#if... depth=%d\n",g_ifcount);
+ }
+<SkipCommand>"else" {
+ //printf("Else! g_ifcount=%d otherCaseDone=%d\n",g_ifcount,otherCaseDone());
+ if (g_ifcount==0 && !otherCaseDone())
+ {
+ setCaseDone(TRUE);
+ //outputChar('\n');
+ BEGIN(Start);
+ }
+ }
+<SkipCommand>("elif"|"else"{B}*"if")/[ \t(!] {
+ if (g_ifcount==0)
+ {
+ if (!otherCaseDone())
+ {
+ g_guardExpr.resize(0);
+ g_lastGuardName.resize(0);
+ BEGIN(Guard);
+ }
+ else
+ {
+ BEGIN(SkipCPPBlock);
+ }
+ }
+ }
+<SkipCommand>"endif" {
+ g_expectGuard = FALSE;
+ decrLevel();
+ if (--g_ifcount<0)
+ {
+ //outputChar('\n');
+ BEGIN(Start);
+ }
+ }
+<SkipCommand>\n {
+ outputChar('\n');
+ g_yyLineNr++;
+ BEGIN(SkipCPPBlock);
+ }
+<SkipCommand>{ID} { // unknown directive
+ BEGIN(SkipLine);
+ }
+<SkipCommand>.
+<SkipLine>[^'"/\n]+
+<SkipLine>{CHARLIT} { }
+<SkipLine>\" {
+ BEGIN(SkipString);
+ }
+<SkipLine>.
+<SkipString>"//"/[^\n]* {
+ }
+<SkipLine,SkipCommand,SkipCPPBlock>"//"[^\n]* {
+ g_lastCPPContext=YY_START;
+ BEGIN(RemoveCPPComment);
+ }
+<SkipString>"/*"/[^\n]* {
+ }
+<SkipLine,SkipCommand,SkipCPPBlock>"/*"/[^\n]* {
+ g_lastCContext=YY_START;
+ BEGIN(RemoveCComment);
+ }
+<SkipLine>\n {
+ outputChar('\n');
+ g_yyLineNr++;
+ BEGIN(SkipCPPBlock);
+ }
+<SkipString>[^"\\\n]+ { }
+<SkipString>\\. { }
+<SkipString>\" {
+ BEGIN(SkipLine);
+ }
+<SkipString>. { }
+<IncludeID>{ID}{B}*/"(" {
+ g_nospaces=TRUE;
+ g_roundCount=0;
+ g_defArgsStr=yytext;
+ g_findDefArgContext = IncludeID;
+ BEGIN(FindDefineArgs);
+ }
+<IncludeID>{ID} {
+ g_nospaces=TRUE;
+ readIncludeFile(expandMacro(yytext));
+ BEGIN(Start);
+ }
+<Include>[^\">\n]+[\">] {
+ g_incName+=yytext;
+ readIncludeFile(g_incName);
+ if (g_isImported)
+ {
+ BEGIN(EndImport);
+ }
+ else
+ {
+ BEGIN(Start);
+ }
+ }
+<EndImport>[^\\\n]*/\n {
+ BEGIN(Start);
+ }
+<EndImport>\\[\r]?"\n" {
+ outputChar('\n');
+ g_yyLineNr++;
+ }
+<EndImport>. {
+ }
+<DefName>{ID}/("\\\n")*"(" { // define with argument
+ //printf("Define() `%s'\n",yytext);
+ g_argDict = new QDict<int>(31);
+ g_argDict->setAutoDelete(TRUE);
+ g_defArgs = 0;
+ g_defArgsStr.resize(0);
+ g_defText.resize(0);
+ g_defLitText.resize(0);
+ g_defName = yytext;
+ g_defVarArgs = FALSE;
+ g_defExtraSpacing.resize(0);
+ BEGIN(DefineArg);
+ }
+<DefName>{ID}{B}+"1"/[ \r\t\n] { // special case: define with 1 -> can be "guard"
+ //printf("Define `%s'\n",yytext);
+ g_argDict = 0;
+ g_defArgs = -1;
+ g_defArgsStr.resize(0);
+ g_defName = yytext;
+ g_defName = g_defName.left(g_defName.length()-1).stripWhiteSpace();
+ g_defVarArgs = FALSE;
+ //printf("Guard check: %s!=%s || %d\n",
+ // g_defName.data(),g_lastGuardName.data(),g_expectGuard);
+ if (g_curlyCount>0 || g_defName!=g_lastGuardName || !g_expectGuard)
+ { // define may appear in the output
+ QCString tmp=(QCString)"#define "+g_defName;
+ outputArray(tmp.data(),tmp.length());
+ g_quoteArg=FALSE;
+ g_insideComment=FALSE;
+ g_lastGuardName.resize(0);
+ g_defText="1";
+ g_defLitText="1";
+ BEGIN(DefineText);
+ }
+ else // define is a guard => hide
+ {
+ //printf("Found a guard %s\n",yytext);
+ g_defText.resize(0);
+ g_defLitText.resize(0);
+ BEGIN(Start);
+ }
+ g_expectGuard=FALSE;
+ }
+<DefName>{ID}/{B}*"\n" { // empty define
+ g_argDict = 0;
+ g_defArgs = -1;
+ g_defName = yytext;
+ g_defArgsStr.resize(0);
+ g_defText.resize(0);
+ g_defLitText.resize(0);
+ g_defVarArgs = FALSE;
+ //printf("Guard check: %s!=%s || %d\n",
+ // g_defName.data(),g_lastGuardName.data(),g_expectGuard);
+ if (g_curlyCount>0 || g_defName!=g_lastGuardName || !g_expectGuard)
+ { // define may appear in the output
+ QCString tmp=(QCString)"#define "+g_defName;
+ outputArray(tmp.data(),tmp.length());
+ g_quoteArg=FALSE;
+ g_insideComment=FALSE;
+ if (g_insideCS) g_defText="1"; // for C#, use "1" as define text
+ BEGIN(DefineText);
+ }
+ else // define is a guard => hide
+ {
+ //printf("Found a guard %s\n",yytext);
+ g_guardName = yytext;
+ g_lastGuardName.resize(0);
+ BEGIN(Start);
+ }
+ g_expectGuard=FALSE;
+ }
+<DefName>{ID}/{B}* { // define with content
+ //printf("Define `%s'\n",yytext);
+ g_argDict = 0;
+ g_defArgs = -1;
+ g_defArgsStr.resize(0);
+ g_defText.resize(0);
+ g_defLitText.resize(0);
+ g_defName = yytext;
+ g_defVarArgs = FALSE;
+ QCString tmp=(QCString)"#define "+g_defName+g_defArgsStr;
+ outputArray(tmp.data(),tmp.length());
+ g_quoteArg=FALSE;
+ g_insideComment=FALSE;
+ BEGIN(DefineText);
+ }
+<DefineArg>"\\\n" {
+ g_defExtraSpacing+="\n";
+ g_yyLineNr++;
+ }
+<DefineArg>","{B}* { g_defArgsStr+=yytext; }
+<DefineArg>"("{B}* { g_defArgsStr+=yytext; }
+<DefineArg>{B}*")"{B}* {
+ g_defArgsStr+=yytext;
+ QCString tmp=(QCString)"#define "+g_defName+g_defArgsStr+g_defExtraSpacing;
+ outputArray(tmp.data(),tmp.length());
+ g_quoteArg=FALSE;
+ g_insideComment=FALSE;
+ BEGIN(DefineText);
+ }
+<DefineArg>"..." { // Variadic macro
+ g_defVarArgs = TRUE;
+ g_defArgsStr+=yytext;
+ g_argDict->insert("__VA_ARGS__",new int(g_defArgs));
+ g_defArgs++;
+ }
+<DefineArg>{ID}{B}*("..."?) {
+ //printf("Define addArg(%s)\n",yytext);
+ QCString argName=yytext;
+ g_defVarArgs = yytext[yyleng-1]=='.';
+ if (g_defVarArgs) // strip ellipsis
+ {
+ argName=argName.left(argName.length()-3);
+ }
+ argName = argName.stripWhiteSpace();
+ g_defArgsStr+=yytext;
+ g_argDict->insert(argName,new int(g_defArgs));
+ g_defArgs++;
+ }
+ /*
+<DefineText>"/ **"|"/ *!" {
+ g_defText+=yytext;
+ g_defLitText+=yytext;
+ g_insideComment=TRUE;
+ }
+<DefineText>"* /" {
+ g_defText+=yytext;
+ g_defLitText+=yytext;
+ g_insideComment=FALSE;
+ }
+ */
+<DefineText>"/*"[!*]? {
+ g_defText+=yytext;
+ g_defLitText+=yytext;
+ g_lastCContext=YY_START;
+ g_commentCount=1;
+ BEGIN(CopyCComment);
+ }
+<DefineText>"//"[!/]? {
+ outputArray(yytext,(int)yyleng);
+ g_lastCPPContext=YY_START;
+ g_defLitText+=' ';
+ BEGIN(SkipCPPComment);
+ }
+<SkipCComment>[/]?"*/" {
+ if (yytext[0]=='/') outputChar('/');
+ outputChar('*');outputChar('/');
+ if (--g_commentCount<=0)
+ {
+ if (g_lastCContext==Start)
+ // small hack to make sure that ^... rule will
+ // match when going to Start... Example: "/*...*/ some stuff..."
+ {
+ YY_CURRENT_BUFFER->yy_at_bol=1;
+ }
+ BEGIN(g_lastCContext);
+ }
+ }
+<SkipCComment>"//"("/")* {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCComment>"/*" {
+ outputChar('/');outputChar('*');
+ //g_commentCount++;
+ }
+<SkipCComment>[\\@][\\@]("f{"|"f$"|"f[") {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCComment>"~~~"[~]* {
+ static bool markdownSupport = Config_getBool("MARKDOWN_SUPPORT");
+ if (!markdownSupport)
+ {
+ REJECT;
+ }
+ else
+ {
+ outputArray(yytext,(int)yyleng);
+ g_fenceSize=yyleng;
+ BEGIN(SkipVerbatim);
+ }
+ }
+<SkipCComment>[\\@][\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly"|"dot"|"code"("{"[^}]*"}")?){BN}+ {
+ outputArray(yytext,(int)yyleng);
+ g_yyLineNr+=QCString(yytext).contains('\n');
+ }
+<SkipCComment>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly"|"dot"|"code"("{"[^}]*"}")?){BN}+ {
+ outputArray(yytext,(int)yyleng);
+ g_yyLineNr+=QCString(yytext).contains('\n');
+ g_fenceSize=0;
+ if (yytext[1]=='f')
+ {
+ g_blockName="f";
+ }
+ else
+ {
+ QCString bn=&yytext[1];
+ int i = bn.find('{'); // for \code{.c}
+ if (i!=-1) bn=bn.left(i);
+ g_blockName=bn.stripWhiteSpace();
+ }
+ BEGIN(SkipVerbatim);
+ }
+<SkipCComment,SkipCPPComment>[\\@][\\@]"cond"[ \t]+ { // escaped @cond
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCPPComment>[\\@]"cond"[ \t]+ { // conditional section
+ g_ccomment=TRUE;
+ g_condCtx=YY_START;
+ BEGIN(CondLineCpp);
+ }
+<SkipCComment>[\\@]"cond"[ \t]+ { // conditional section
+ g_ccomment=FALSE;
+ g_condCtx=YY_START;
+ BEGIN(CondLineC);
+ }
+<CondLineC,CondLineCpp>[!()&| \ta-z_A-Z0-9\x80-\xFF.\-]+ {
+ startCondSection(yytext);
+ if (g_skip)
+ {
+ if (YY_START==CondLineC)
+ {
+ // end C comment
+ outputArray("*/",2);
+ g_ccomment=TRUE;
+ }
+ else
+ {
+ g_ccomment=FALSE;
+ }
+ BEGIN(SkipCond);
+ }
+ else
+ {
+ BEGIN(g_condCtx);
+ }
+ }
+<CondLineC,CondLineCpp>. { // non-guard character
+ unput(*yytext);
+ startCondSection(" ");
+ if (g_skip)
+ {
+ if (YY_START==CondLineC)
+ {
+ // end C comment
+ outputArray("*/",2);
+ g_ccomment=TRUE;
+ }
+ else
+ {
+ g_ccomment=FALSE;
+ }
+ BEGIN(SkipCond);
+ }
+ else
+ {
+ BEGIN(g_condCtx);
+ }
+ }
+<SkipCComment,SkipCPPComment>[\\@]"cond"[ \t\r]*/\n { // no guard
+ if (YY_START==SkipCComment)
+ {
+ g_ccomment=TRUE;
+ // end C comment
+ outputArray("*/",2);
+ }
+ else
+ {
+ g_ccomment=FALSE;
+ }
+ g_condCtx=YY_START;
+ startCondSection(" ");
+ BEGIN(SkipCond);
+ }
+<SkipCond>\n { g_yyLineNr++; outputChar('\n'); }
+<SkipCond>. { }
+<SkipCond>[^\/\!*\\@\n]+ { }
+<SkipCond>"//"[/!] { g_ccomment=FALSE; }
+<SkipCond>"/*"[*!] { g_ccomment=TRUE; }
+<SkipCond,SkipCComment,SkipCPPComment>[\\@][\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
+ if (!g_skip)
+ {
+ outputArray(yytext,(int)yyleng);
+ }
+ }
+<SkipCond>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
+ bool oldSkip = g_skip;
+ endCondSection();
+ if (oldSkip && !g_skip)
+ {
+ if (g_ccomment)
+ {
+ outputArray("/** ",4);
+ }
+ BEGIN(g_condCtx);
+ }
+ }
+<SkipCComment,SkipCPPComment>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
+ bool oldSkip = g_skip;
+ endCondSection();
+ if (oldSkip && !g_skip)
+ {
+ BEGIN(g_condCtx);
+ }
+ }
+<SkipVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}") { /* end of verbatim block */
+ outputArray(yytext,(int)yyleng);
+ if (yytext[1]=='f' && g_blockName=="f")
+ {
+ BEGIN(SkipCComment);
+ }
+ else if (&yytext[4]==g_blockName)
+ {
+ BEGIN(SkipCComment);
+ }
+ }
+<SkipVerbatim>"~~~"[~]* {
+ outputArray(yytext,(int)yyleng);
+ if (g_fenceSize==yyleng)
+ {
+ BEGIN(SkipCComment);
+ }
+ }
+<SkipVerbatim>"*/"|"/*" {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCComment,SkipVerbatim>[^*\\@\x06~\n\/]+ {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCComment,SkipVerbatim>\n {
+ g_yyLineNr++;
+ outputChar('\n');
+ }
+<SkipCComment,SkipVerbatim>. {
+ outputChar(*yytext);
+ }
+<CopyCComment>[^*a-z_A-Z\x80-\xFF\n]+ {
+ g_defLitText+=yytext;
+ g_defText+=escapeAt(yytext);
+ }
+<CopyCComment>"*/" {
+ g_defLitText+=yytext;
+ g_defText+=yytext;
+ BEGIN(g_lastCContext);
+ }
+<CopyCComment>\n {
+ g_yyLineNr++;
+ outputChar('\n');
+ g_defLitText+=yytext;
+ g_defText+=' ';
+ }
+<RemoveCComment>"*/"{B}*"#" { // see bug 594021 for a usecase for this rule
+ if (g_lastCContext==SkipCPPBlock)
+ {
+ BEGIN(SkipCommand);
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<RemoveCComment>"*/" { BEGIN(g_lastCContext); }
+<RemoveCComment>"//"
+<RemoveCComment>"/*"
+<RemoveCComment>[^*\x06\n]+
+<RemoveCComment>\n { g_yyLineNr++; outputChar('\n'); }
+<RemoveCComment>.
+<SkipCPPComment>[^\n\/\\@]+ {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCPPComment,RemoveCPPComment>\n {
+ unput(*yytext);
+ BEGIN(g_lastCPPContext);
+ }
+<SkipCPPComment>"/*" {
+ outputChar('/');outputChar('*');
+ }
+<SkipCPPComment>"//" {
+ outputChar('/');outputChar('/');
+ }
+<SkipCPPComment>[^\x06\@\\\n]+ {
+ outputArray(yytext,(int)yyleng);
+ }
+<SkipCPPComment>. {
+ outputChar(*yytext);
+ }
+<RemoveCPPComment>"/*"
+<RemoveCPPComment>"//"
+<RemoveCPPComment>[^\x06\n]+
+<RemoveCPPComment>.
+<DefineText>"#" {
+ g_quoteArg=TRUE;
+ g_defLitText+=yytext;
+ }
+<DefineText,CopyCComment>{ID} {
+ g_defLitText+=yytext;
+ if (g_quoteArg)
+ {
+ g_defText+="\"";
+ }
+ if (g_defArgs>0)
+ {
+ int *n;
+ if ((n=(*g_argDict)[yytext]))
+ {
+ //if (!g_quoteArg) g_defText+=' ';
+ g_defText+='@';
+ QCString numStr;
+ numStr.sprintf("%d",*n);
+ g_defText+=numStr;
+ //if (!g_quoteArg) g_defText+=' ';
+ }
+ else
+ {
+ g_defText+=yytext;
+ }
+ }
+ else
+ {
+ g_defText+=yytext;
+ }
+ if (g_quoteArg)
+ {
+ g_defText+="\"";
+ }
+ g_quoteArg=FALSE;
+ }
+<CopyCComment>. {
+ g_defLitText+=yytext;
+ g_defText+=yytext;
+ }
+<DefineText>\\[\r]?\n {
+ g_defLitText+=yytext;
+ outputChar('\n');
+ g_defText += ' ';
+ g_yyLineNr++;
+ g_yyMLines++;
+ }
+<DefineText>\n {
+ QCString comment=extractTrailingComment(g_defLitText);
+ g_defLitText+=yytext;
+ if (!comment.isEmpty())
+ {
+ outputArray(comment,comment.length());
+ g_defLitText=g_defLitText.left(g_defLitText.length()-comment.length()-1);
+ }
+ outputChar('\n');
+ Define *def=0;
+ //printf("Define name=`%s' text=`%s' litTexti=`%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data());
+ if (g_includeStack.isEmpty() || g_curlyCount>0)
+ {
+ addDefine();
+ }
+ def=DefineManager::instance().isDefined(g_defName);
+ if (def==0) // new define
+ {
+ //printf("new define '%s'!\n",g_defName.data());
+ Define *nd = newDefine();
+ DefineManager::instance().addDefine(g_yyFileName,nd);
+
+ // also add it to the local file list if it is a source file
+ //if (g_isSource && g_includeStack.isEmpty())
+ //{
+ // g_fileDefineDict->insert(g_defName,nd);
+ //}
+ }
+ else if (def /*&& macroIsAccessible(def)*/)
+ // name already exists
+ {
+ //printf("existing define!\n");
+ //printf("define found\n");
+ if (def->undef) // undefined name
+ {
+ def->undef = FALSE;
+ def->name = g_defName;
+ def->definition = g_defText.stripWhiteSpace();
+ def->nargs = g_defArgs;
+ def->fileName = g_yyFileName.copy();
+ def->lineNr = g_yyLineNr-g_yyMLines;
+ def->columnNr = g_yyColNr;
+ }
+ else
+ {
+ //printf("error: define %s is defined more than once!\n",g_defName.data());
+ }
+ }
+ delete g_argDict; g_argDict=0;
+ g_yyLineNr++;
+ g_yyColNr=1;
+ g_lastGuardName.resize(0);
+ BEGIN(Start);
+ }
+<DefineText>{B}* { g_defText += ' '; g_defLitText+=yytext; }
+<DefineText>{B}*"##"{B}* { g_defText += "##"; g_defLitText+=yytext; }
+<DefineText>"@" { g_defText += "@@"; g_defLitText+=yytext; }
+<DefineText>\" {
+ g_defText += *yytext;
+ g_defLitText+=yytext;
+ if (!g_insideComment)
+ {
+ BEGIN(SkipDoubleQuote);
+ }
+ }
+<DefineText>\' { g_defText += *yytext;
+ g_defLitText+=yytext;
+ if (!g_insideComment)
+ {
+ BEGIN(SkipSingleQuote);
+ }
+ }
+<SkipDoubleQuote>"//"[/]? { g_defText += yytext; g_defLitText+=yytext; }
+<SkipDoubleQuote>"/*" { g_defText += yytext; g_defLitText+=yytext; }
+<SkipDoubleQuote>\" {
+ g_defText += *yytext; g_defLitText+=yytext;
+ BEGIN(DefineText);
+ }
+<SkipSingleQuote,SkipDoubleQuote>\\. {
+ g_defText += yytext; g_defLitText+=yytext;
+ }
+<SkipSingleQuote>\' {
+ g_defText += *yytext; g_defLitText+=yytext;
+ BEGIN(DefineText);
+ }
+<SkipDoubleQuote>. { g_defText += *yytext; g_defLitText+=yytext; }
+<SkipSingleQuote>. { g_defText += *yytext; g_defLitText+=yytext; }
+<DefineText>. { g_defText += *yytext; g_defLitText+=yytext; }
+<<EOF>> {
+ DBG_CTX((stderr,"End of include file\n"));
+ //printf("Include stack depth=%d\n",g_includeStack.count());
+ if (g_includeStack.isEmpty())
+ {
+ DBG_CTX((stderr,"Terminating scanner!\n"));
+ yyterminate();
+ }
+ else
+ {
+ FileState *fs=g_includeStack.pop();
+ //fileDefineCache->merge(g_yyFileName,fs->fileName);
+ YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer( fs->bufState );
+ yy_delete_buffer( oldBuf );
+ g_yyLineNr = fs->lineNr;
+ //preYYin = fs->oldYYin;
+ g_inputBuf = fs->oldFileBuf;
+ g_inputBufPos = fs->oldFileBufPos;
+ setFileName(fs->fileName);
+ DBG_CTX((stderr,"######## FileName %s\n",g_yyFileName.data()));
+
+ // Deal with file changes due to
+ // #include's within { .. } blocks
+ QCString lineStr(15+g_yyFileName.length());
+ lineStr.sprintf("# %d \"%s\" 2",g_yyLineNr,g_yyFileName.data());
+ outputArray(lineStr.data(),lineStr.length());
+
+ delete fs; fs=0;
+ }
+ }
+<*>"/*"/"*/" |
+<*>"/*"[*]? {
+ if (YY_START==SkipVerbatim || YY_START==SkipCond)
+ {
+ REJECT;
+ }
+ else
+ {
+ outputArray(yytext,(int)yyleng);
+ g_lastCContext=YY_START;
+ g_commentCount=1;
+ if (yyleng==3) g_lastGuardName.resize(0); // reset guard in case the #define is documented!
+ BEGIN(SkipCComment);
+ }
+ }
+<*>"//"[/]? {
+ if (YY_START==SkipVerbatim || YY_START==SkipCond)
+ {
+ REJECT;
+ }
+ else
+ {
+ outputArray(yytext,(int)yyleng);
+ g_lastCPPContext=YY_START;
+ if (yyleng==3) g_lastGuardName.resize(0); // reset guard in case the #define is documented!
+ BEGIN(SkipCPPComment);
+ }
+ }
+<*>\n {
+ outputChar('\n');
+ g_yyLineNr++;
+ }
+<*>. {
+ g_expectGuard = FALSE;
+ outputChar(*yytext);
+ }
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+static int getNextChar(const QCString &expr,QCString *rest,uint &pos)
+{
+ //printf("getNextChar(%s,%s,%d)\n",expr.data(),rest ? rest->data() : 0,pos);
+ if (pos<expr.length())
+ {
+ //printf("%c=expr()\n",expr.at(pos));
+ return expr.at(pos++);
+ }
+ else if (rest && !rest->isEmpty())
+ {
+ int cc=rest->at(0);
+ *rest=rest->right(rest->length()-1);
+ //printf("%c=rest\n",cc);
+ return cc;
+ }
+ else
+ {
+ int cc=yyinput();
+ //printf("%d=yyinput() %d\n",cc,EOF);
+ return cc;
+ }
+}
+
+static int getCurrentChar(const QCString &expr,QCString *rest,uint pos)
+{
+ //printf("getCurrentChar(%s,%s,%d)\n",expr.data(),rest ? rest->data() : 0,pos);
+ if (pos<expr.length())
+ {
+ //printf("%c=expr()\n",expr.at(pos));
+ return expr.at(pos);
+ }
+ else if (rest && !rest->isEmpty())
+ {
+ int cc=rest->at(0);
+ //printf("%c=rest\n",cc);
+ return cc;
+ }
+ else
+ {
+ int cc=yyinput();
+ returnCharToStream(cc);
+ //unput((char)cc);
+ //printf("%c=yyinput()\n",cc);
+ return cc;
+ }
+}
+
+static void unputChar(const QCString &expr,QCString *rest,uint &pos,char c)
+{
+ //printf("unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c);
+ if (pos<expr.length())
+ {
+ pos++;
+ }
+ else if (rest)
+ {
+ //printf("Prepending to rest!\n");
+ char cs[2];cs[0]=c;cs[1]='\0';
+ rest->prepend(cs);
+ }
+ else
+ {
+ //unput(c);
+ returnCharToStream(c);
+ }
+ //printf("result: unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c);
+}
+
+void addSearchDir(const char *dir)
+{
+ QFileInfo fi(dir);
+ if (fi.isDir()) g_pathList->append(fi.absFilePath().utf8());
+}
+
+void initPreprocessor()
+{
+ g_pathList = new QStrList;
+ addSearchDir(".");
+ g_expandedDict = new DefineDict(17);
+}
+
+void cleanUpPreprocessor()
+{
+ delete g_expandedDict; g_expandedDict=0;
+ delete g_pathList; g_pathList=0;
+ DefineManager::deleteInstance();
+}
+
+
+void preprocessFile(const char *fileName,BufStr &input,BufStr &output)
+{
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+ uint orgOffset=output.curPos();
+ //printf("##########################\n%s\n####################\n",
+ // input.data());
+
+ g_macroExpansion = Config_getBool("MACRO_EXPANSION");
+ g_expandOnlyPredef = Config_getBool("EXPAND_ONLY_PREDEF");
+ g_skip=FALSE;
+ g_curlyCount=0;
+ g_nospaces=FALSE;
+ g_inputBuf=&input;
+ g_inputBufPos=0;
+ g_outputBuf=&output;
+ g_includeStack.setAutoDelete(TRUE);
+ g_includeStack.clear();
+ g_expandedDict->setAutoDelete(FALSE);
+ g_expandedDict->clear();
+ g_condStack.clear();
+ g_condStack.setAutoDelete(TRUE);
+ //g_fileDefineDict->clear();
+
+ setFileName(fileName);
+ g_inputFileDef = g_yyFileDef;
+ DefineManager::instance().startContext(g_yyFileName);
+
+ static bool firstTime=TRUE;
+ if (firstTime)
+ {
+ // add predefined macros
+ char *defStr;
+ QStrList &predefList = Config_getList("PREDEFINED");
+ QStrListIterator sli(predefList);
+ for (sli.toFirst();(defStr=sli.current());++sli)
+ {
+ QCString ds = defStr;
+ int i_equals=ds.find('=');
+ int i_obrace=ds.find('(');
+ int i_cbrace=ds.find(')');
+ bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':';
+
+ if (i_obrace==0) continue; // no define name
+
+ if (i_obrace<i_equals && i_cbrace<i_equals &&
+ i_obrace!=-1 && i_cbrace!=-1 &&
+ i_obrace<i_cbrace
+ ) // predefined function macro definition
+ {
+ //printf("predefined function macro '%s'\n",defStr);
+ QRegExp reId("[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*"); // regexp matching an id
+ QDict<int> argDict(17);
+ argDict.setAutoDelete(TRUE);
+ int i=i_obrace+1,p,l,count=0;
+ // gather the formal arguments in a dictionary
+ while (i<i_cbrace && (p=reId.match(ds,i,&l)))
+ {
+ if (l>0) // see bug375037
+ {
+ argDict.insert(ds.mid(p,l),new int(count++));
+ i=p+l;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ // strip definition part
+ QCString tmp=ds.right(ds.length()-i_equals-1);
+ QCString definition;
+ i=0;
+ // substitute all occurrences of formal arguments by their
+ // corresponding markers
+ while ((p=reId.match(tmp,i,&l))!=-1)
+ {
+ if (p>i) definition+=tmp.mid(i,p-i);
+ int *argIndex;
+ if ((argIndex=argDict[tmp.mid(p,l)])!=0)
+ {
+ QCString marker;
+ marker.sprintf(" @%d ",*argIndex);
+ definition+=marker;
+ }
+ else
+ {
+ definition+=tmp.mid(p,l);
+ }
+ i=p+l;
+ }
+ if (i<(int)tmp.length()) definition+=tmp.mid(i,tmp.length()-i);
+
+ // add define definition to the dictionary of defines for this file
+ QCString dname = ds.left(i_obrace);
+ if (!dname.isEmpty())
+ {
+ Define *def = new Define;
+ def->name = dname;
+ def->definition = definition;
+ def->nargs = count;
+ def->isPredefined = TRUE;
+ def->nonRecursive = nonRecursive;
+ def->fileDef = g_yyFileDef;
+ def->fileName = fileName;
+ DefineManager::instance().addDefine(g_yyFileName,def);
+ }
+
+ //printf("#define `%s' `%s' #nargs=%d\n",
+ // def->name.data(),def->definition.data(),def->nargs);
+ }
+ else if ((i_obrace==-1 || i_obrace>i_equals) &&
+ (i_cbrace==-1 || i_cbrace>i_equals) &&
+ !ds.isEmpty() && (int)ds.length()>i_equals
+ ) // predefined non-function macro definition
+ {
+ //printf("predefined normal macro '%s'\n",defStr);
+ Define *def = new Define;
+ if (i_equals==-1) // simple define without argument
+ {
+ def->name = ds;
+ def->definition = "1"; // substitute occurrences by 1 (true)
+ }
+ else // simple define with argument
+ {
+ int ine=i_equals - (nonRecursive ? 1 : 0);
+ def->name = ds.left(ine);
+ def->definition = ds.right(ds.length()-i_equals-1);
+ }
+ if (!def->name.isEmpty())
+ {
+ def->nargs = -1;
+ def->isPredefined = TRUE;
+ def->nonRecursive = nonRecursive;
+ def->fileDef = g_yyFileDef;
+ def->fileName = fileName;
+ DefineManager::instance().addDefine(g_yyFileName,def);
+ }
+ else
+ {
+ delete def;
+ }
+
+ //printf("#define `%s' `%s' #nargs=%d\n",
+ // def->name.data(),def->definition.data(),def->nargs);
+ }
+ }
+ //firstTime=FALSE;
+ }
+
+ g_yyLineNr = 1;
+ g_yyColNr = 1;
+ g_level = 0;
+ g_ifcount = 0;
+
+ BEGIN( Start );
+
+ g_expectGuard = guessSection(fileName)==Entry::HEADER_SEC;
+ g_guardName.resize(0);
+ g_lastGuardName.resize(0);
+ g_guardExpr.resize(0);
+
+ preYYlex();
+ g_lexInit=TRUE;
+
+ while (!g_condStack.isEmpty())
+ {
+ CondCtx *ctx = g_condStack.pop();
+ QCString sectionInfo = " ";
+ if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label %s ",ctx->sectionId.data());
+ warn(fileName,ctx->lineNr,"Conditional section%sdoes not have "
+ "a corresponding \\endcond command within this file.",sectionInfo.data());
+ }
+ // make sure we don't extend a \cond with missing \endcond over multiple files (see bug 624829)
+ forceEndCondSection();
+
+ // remove locally defined macros so they can be redefined in another source file
+ //if (g_fileDefineDict->count()>0)
+ //{
+ // QDictIterator<Define> di(*g_fileDefineDict);
+ // Define *d;
+ // for (di.toFirst();(d=di.current());++di)
+ // {
+ // g_globalDefineDict->remove(di.currentKey());
+ // }
+ // g_fileDefineDict->clear();
+ //}
+
+ if (Debug::isFlagSet(Debug::Preprocessor))
+ {
+ char *orgPos=output.data()+orgOffset;
+ char *newPos=output.data()+output.curPos();
+ Debug::print(Debug::Preprocessor,0,"Preprocessor output (size: %d bytes):\n",newPos-orgPos);
+ int line=1;
+ Debug::print(Debug::Preprocessor,0,"---------\n00001 ");
+ while (orgPos<newPos)
+ {
+ putchar(*orgPos);
+ if (*orgPos=='\n') Debug::print(Debug::Preprocessor,0,"%05d ",++line);
+ orgPos++;
+ }
+ Debug::print(Debug::Preprocessor,0,"\n---------\n");
+ if (DefineManager::instance().defineContext().count()>0)
+ {
+ Debug::print(Debug::Preprocessor,0,"Macros accessible in this file:\n");
+ Debug::print(Debug::Preprocessor,0,"---------\n");
+ QDictIterator<Define> di(DefineManager::instance().defineContext());
+ Define *def;
+ for (di.toFirst();(def=di.current());++di)
+ {
+ Debug::print(Debug::Preprocessor,0,"%s ",def->name.data());
+ }
+ Debug::print(Debug::Preprocessor,0,"\n---------\n");
+ }
+ else
+ {
+ Debug::print(Debug::Preprocessor,0,"No macros accessible in this file.\n");
+ }
+ }
+ DefineManager::instance().endContext();
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+void preFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+ if (g_lexInit)
+ {
+ preYYlex_destroy();
+ }
+#endif
+}
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+// int preYYwrap() { return 1 ; }
+ void preYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h
new file mode 100644
index 0000000..1d384b1
--- /dev/null
+++ b/src/printdocvisitor.h
@@ -0,0 +1,728 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _PRINTDOCVISITOR_H
+#define _PRINTDOCVISITOR_H
+
+#include <qglobal.h>
+#include "docvisitor.h"
+#include "htmlentity.h"
+
+/*! Concrete visitor implementation for pretty printing */
+class PrintDocVisitor : public DocVisitor
+{
+ public:
+ PrintDocVisitor() : DocVisitor(DocVisitor_Other), m_indent(0),
+ m_needsEnter(FALSE), m_insidePre(FALSE) {}
+
+ //--------------------------------------
+
+ void visit(DocWord *w)
+ {
+ indent_leaf();
+ printf("%s",w->word().data());
+ }
+ void visit(DocLinkedWord *w)
+ {
+ indent_leaf();
+ printf("%s",w->word().data());
+ }
+ void visit(DocWhiteSpace *w)
+ {
+ indent_leaf();
+ if (m_insidePre)
+ {
+ printf("%s",w->chars().data());
+ }
+ else
+ {
+ printf(" ");
+ }
+ }
+ void visit(DocSymbol *s)
+ {
+ indent_leaf();
+ const char *res = HtmlEntityMapper::instance()->utf8(s->symbol(),TRUE);
+ if (res)
+ {
+ printf("%s",res);
+ }
+ else
+ {
+ printf("print: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+ }
+ void visit(DocURL *u)
+ {
+ indent_leaf();
+ printf("%s",u->url().data());
+ }
+ void visit(DocLineBreak *)
+ {
+ indent_leaf();
+ printf("<br/>");
+ }
+ void visit(DocHorRuler *)
+ {
+ indent_leaf();
+ printf("<hr>");
+ }
+ void visit(DocStyleChange *s)
+ {
+ indent_leaf();
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) printf("<bold>"); else printf("</bold>");
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) printf("<italic>"); else printf("</italic>");
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) printf("<code>"); else printf("</code>");
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) printf("<sub>"); else printf("</sub>");
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) printf("<sup>"); else printf("</sup>");
+ break;
+ case DocStyleChange::Center:
+ if (s->enable()) printf("<center>"); else printf("</center>");
+ break;
+ case DocStyleChange::Small:
+ if (s->enable()) printf("<small>"); else printf("</small>");
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable()) printf("<pre>"); else printf("</pre>");
+ break;
+ case DocStyleChange::Div:
+ if (s->enable()) printf("<div>"); else printf("</div>");
+ break;
+ case DocStyleChange::Span:
+ if (s->enable()) printf("<span>"); else printf("</span>");
+ break;
+ }
+ }
+ void visit(DocVerbatim *s)
+ {
+ indent_leaf();
+ switch(s->type())
+ {
+ case DocVerbatim::Code: printf("<code>"); break;
+ case DocVerbatim::Verbatim: printf("<verbatim>"); break;
+ case DocVerbatim::HtmlOnly: printf("<htmlonly>"); break;
+ case DocVerbatim::RtfOnly: printf("<rtfonly>"); break;
+ case DocVerbatim::ManOnly: printf("<manonly>"); break;
+ case DocVerbatim::LatexOnly: printf("<latexonly>"); break;
+ case DocVerbatim::XmlOnly: printf("<xmlonly>"); break;
+ case DocVerbatim::DocbookOnly: printf("<docbookonly>"); break;
+ case DocVerbatim::Dot: printf("<dot>"); break;
+ case DocVerbatim::Msc: printf("<msc>"); break;
+ case DocVerbatim::PlantUML: printf("<plantuml>"); break;
+ }
+ printf("%s",s->text().data());
+ switch(s->type())
+ {
+ case DocVerbatim::Code: printf("</code>"); break;
+ case DocVerbatim::Verbatim: printf("</verbatim>"); break;
+ case DocVerbatim::HtmlOnly: printf("</htmlonly>"); break;
+ case DocVerbatim::RtfOnly: printf("</rtfonly>"); break;
+ case DocVerbatim::ManOnly: printf("</manonly>"); break;
+ case DocVerbatim::LatexOnly: printf("</latexonly>"); break;
+ case DocVerbatim::XmlOnly: printf("</xmlonly>"); break;
+ case DocVerbatim::DocbookOnly: printf("</docbookonly>"); break;
+ case DocVerbatim::Dot: printf("</dot>"); break;
+ case DocVerbatim::Msc: printf("</msc>"); break;
+ case DocVerbatim::PlantUML: printf("</plantuml>"); break;
+ }
+ }
+ void visit(DocAnchor *a)
+ {
+ indent_leaf();
+ printf("<anchor name=\"%s\"/>",a->anchor().data());
+ }
+ void visit(DocInclude *inc)
+ {
+ indent_leaf();
+ printf("<include file=\"%s\" type=\"",inc->file().data());
+ switch(inc->type())
+ {
+ case DocInclude::Include: printf("include"); break;
+ case DocInclude::IncWithLines: printf("incwithlines"); break;
+ case DocInclude::DontInclude: printf("dontinclude"); break;
+ case DocInclude::HtmlInclude: printf("htmlinclude"); break;
+ case DocInclude::LatexInclude: printf("latexinclude"); break;
+ case DocInclude::VerbInclude: printf("verbinclude"); break;
+ case DocInclude::Snippet: printf("snippet"); break;
+ }
+ printf("\"/>");
+ }
+ void visit(DocIncOperator *op)
+ {
+ indent_leaf();
+ printf("<incoperator pattern=\"%s\" type=\"",op->pattern().data());
+ switch(op->type())
+ {
+ case DocIncOperator::Line: printf("line"); break;
+ case DocIncOperator::Skip: printf("skip"); break;
+ case DocIncOperator::SkipLine: printf("skipline"); break;
+ case DocIncOperator::Until: printf("until"); break;
+ }
+ printf("\"/>");
+ }
+ void visit(DocFormula *f)
+ {
+ indent_leaf();
+ printf("<formula name=%s test=%s/>",f->name().data(),f->text().data());
+ }
+ void visit(DocIndexEntry *i)
+ {
+ indent_leaf();
+ printf("<indexentry>%s</indexentry\n",i->entry().data());
+ }
+ void visit(DocSimpleSectSep *)
+ {
+ indent_leaf();
+ printf("<simplesectsep/>");
+ }
+ void visit(DocCite *cite)
+ {
+ indent_leaf();
+ printf("<cite ref=\"%s\" file=\"%s\" "
+ "anchor=\"%s\" text=\"%s\""
+ "/>\n",
+ cite->ref().data(),cite->file().data(),cite->anchor().data(),
+ cite->text().data());
+ }
+
+ //--------------------------------------
+
+ void visitPre(DocAutoList *l)
+ {
+ indent_pre();
+ if (l->isEnumList())
+ {
+ printf("<ol>\n");
+ }
+ else
+ {
+ printf("<ul>\n");
+ }
+ }
+ void visitPost(DocAutoList *l)
+ {
+ indent_post();
+ if (l->isEnumList())
+ {
+ printf("</ol>\n");
+ }
+ else
+ {
+ printf("</ul>\n");
+ }
+ }
+ void visitPre(DocAutoListItem *)
+ {
+ indent_pre();
+ printf("<li>\n");
+ }
+ void visitPost(DocAutoListItem *)
+ {
+ indent_post();
+ printf("</li>\n");
+ }
+ void visitPre(DocPara *)
+ {
+ indent_pre();
+ printf("<para>\n");
+ }
+ void visitPost(DocPara *)
+ {
+ indent_post();
+ printf("</para>\n");
+ }
+ void visitPre(DocRoot *)
+ {
+ indent_pre();
+ printf("<root>\n");
+ }
+ void visitPost(DocRoot *)
+ {
+ indent_post();
+ printf("</root>\n");
+ }
+ void visitPre(DocSimpleSect *s)
+ {
+ indent_pre();
+ printf("<simplesect type=");
+ switch(s->type())
+ {
+ case DocSimpleSect::See: printf("see"); break;
+ case DocSimpleSect::Return: printf("return"); break;
+ case DocSimpleSect::Author: printf("author"); break;
+ case DocSimpleSect::Authors: printf("authors"); break;
+ case DocSimpleSect::Version: printf("version"); break;
+ case DocSimpleSect::Since: printf("since"); break;
+ case DocSimpleSect::Date: printf("date"); break;
+ case DocSimpleSect::Note: printf("note"); break;
+ case DocSimpleSect::Warning: printf("warning"); break;
+ case DocSimpleSect::Pre: printf("pre"); break;
+ case DocSimpleSect::Post: printf("post"); break;
+ case DocSimpleSect::Copyright: printf("copyright"); break;
+ case DocSimpleSect::Invar: printf("invar"); break;
+ case DocSimpleSect::Remark: printf("remark"); break;
+ case DocSimpleSect::Attention: printf("attention"); break;
+ case DocSimpleSect::User: printf("user"); break;
+ case DocSimpleSect::Rcs: printf("rcs"); break;
+ case DocSimpleSect::Unknown: printf("unknown"); break;
+ }
+ printf(">\n");
+ }
+ void visitPost(DocSimpleSect *)
+ {
+ indent_post();
+ printf("</simplesect>\n");
+ }
+ void visitPre(DocTitle *)
+ {
+ indent_pre();
+ printf("<title>\n");
+ }
+ void visitPost(DocTitle *)
+ {
+ indent_post();
+ printf("</title>\n");
+ }
+ void visitPre(DocSimpleList *)
+ {
+ indent_pre();
+ printf("<ul>\n");
+ }
+ void visitPost(DocSimpleList *)
+ {
+ indent_post();
+ printf("</ul>\n");
+ }
+ void visitPre(DocSimpleListItem *)
+ {
+ indent_pre();
+ printf("<li>\n");
+ }
+ void visitPost(DocSimpleListItem *)
+ {
+ indent_post();
+ printf("</li>\n");
+ }
+ void visitPre(DocSection *s)
+ {
+ indent_pre();
+ printf("<sect%d>\n",s->level());
+ }
+ void visitPost(DocSection *s)
+ {
+ indent_post();
+ printf("</sect%d>\n",s->level());
+ }
+ void visitPre(DocHtmlList *s)
+ {
+ indent_pre();
+ if (s->type()==DocHtmlList::Ordered) printf("<ol>\n"); else printf("<ul>\n");
+ }
+ void visitPost(DocHtmlList *s)
+ {
+ indent_post();
+ if (s->type()==DocHtmlList::Ordered) printf("</ol>\n"); else printf("</ul>\n");
+ }
+ void visitPre(DocHtmlListItem *)
+ {
+ indent_pre();
+ printf("<li>\n");
+ }
+ void visitPost(DocHtmlListItem *)
+ {
+ indent_post();
+ printf("</li>\n");
+ }
+ //void visitPre(DocHtmlPre *)
+ //{
+ // indent_pre();
+ // printf("<pre>\n");
+ // m_insidePre=TRUE;
+ //}
+ //void visitPost(DocHtmlPre *)
+ //{
+ // m_insidePre=FALSE;
+ // indent_post();
+ // printf("</pre>\n");
+ //}
+ void visitPre(DocHtmlDescList *)
+ {
+ indent_pre();
+ printf("<dl>\n");
+ }
+ void visitPost(DocHtmlDescList *)
+ {
+ indent_post();
+ printf("</dl>\n");
+ }
+ void visitPre(DocHtmlDescTitle *)
+ {
+ indent_pre();
+ printf("<dt>\n");
+ }
+ void visitPost(DocHtmlDescTitle *)
+ {
+ indent_post();
+ printf("</dt>\n");
+ }
+ void visitPre(DocHtmlDescData *)
+ {
+ indent_pre();
+ printf("<dd>\n");
+ }
+ void visitPost(DocHtmlDescData *)
+ {
+ indent_post();
+ printf("</dd>\n");
+ }
+ void visitPre(DocHtmlTable *t)
+ {
+ indent_pre();
+ printf("<table rows=\"%d\" cols=\"%d\">\n",
+ t->numRows(),t->numColumns());
+ }
+ void visitPost(DocHtmlTable *)
+ {
+ indent_post();
+ printf("</table>\n");
+ }
+ void visitPre(DocHtmlRow *)
+ {
+ indent_pre();
+ printf("<tr>\n");
+ }
+ void visitPost(DocHtmlRow *)
+ {
+ indent_post();
+ printf("</tr>\n");
+ }
+ void visitPre(DocHtmlCell *c)
+ {
+ indent_pre();
+ printf("<t%c>\n",c->isHeading()?'h':'d');
+ }
+ void visitPost(DocHtmlCell *c)
+ {
+ indent_post();
+ printf("</t%c>\n",c->isHeading()?'h':'d');
+ }
+ void visitPre(DocHtmlCaption *)
+ {
+ indent_pre();
+ printf("<caption>\n");
+ }
+ void visitPost(DocHtmlCaption *)
+ {
+ indent_post();
+ printf("</caption>\n");
+ }
+ void visitPre(DocInternal *)
+ {
+ indent_pre();
+ printf("<internal>\n");
+ }
+ void visitPost(DocInternal *)
+ {
+ indent_post();
+ printf("</internal>\n");
+ }
+ void visitPre(DocHRef *href)
+ {
+ indent_pre();
+ printf("<a url=\"%s\">\n",href->url().data());
+ }
+ void visitPost(DocHRef *)
+ {
+ indent_post();
+ printf("</a>\n");
+ }
+ void visitPre(DocHtmlHeader *header)
+ {
+ indent_pre();
+ printf("<h%d>\n",header->level());
+ }
+ void visitPost(DocHtmlHeader *header)
+ {
+ indent_post();
+ printf("</h%d>\n",header->level());
+ }
+ void visitPre(DocImage *img)
+ {
+ indent_pre();
+ printf("<image src=\"%s\" type=\"",img->name().data());
+ switch(img->type())
+ {
+ case DocImage::Html: printf("html"); break;
+ case DocImage::Latex: printf("latex"); break;
+ case DocImage::Rtf: printf("rtf"); break;
+ case DocImage::DocBook: printf("docbook"); break;
+ }
+ printf("\" width=%s height=%s>\n",img->width().data(),img->height().data());
+ }
+ void visitPost(DocImage *)
+ {
+ indent_post();
+ printf("</image>\n");
+ }
+ void visitPre(DocDotFile *df)
+ {
+ indent_pre();
+ printf("<dotfile src=\"%s\">\n",df->name().data());
+ }
+ void visitPost(DocDotFile *)
+ {
+ indent_post();
+ printf("</dotfile>\n");
+ }
+ void visitPre(DocMscFile *df)
+ {
+ indent_pre();
+ printf("<mscfile src=\"%s\">\n",df->name().data());
+ }
+ void visitPost(DocMscFile *)
+ {
+ indent_post();
+ printf("</mscfile>\n");
+ }
+ void visitPre(DocDiaFile *df)
+ {
+ indent_pre();
+ printf("<diafile src=\"%s\">\n",df->name().data());
+ }
+ void visitPost(DocDiaFile *)
+ {
+ indent_post();
+ printf("</diafile>\n");
+ }
+ void visitPre(DocLink *lnk)
+ {
+ indent_pre();
+ printf("<link ref=\"%s\" file=\"%s\" anchor=\"%s\">\n",
+ lnk->ref().data(),lnk->file().data(),lnk->anchor().data());
+ }
+ void visitPost(DocLink *)
+ {
+ indent_post();
+ printf("</link>\n");
+ }
+ void visitPre(DocRef *ref)
+ {
+ indent_pre();
+ printf("<ref ref=\"%s\" file=\"%s\" "
+ "anchor=\"%s\" targetTitle=\"%s\""
+ " hasLinkText=\"%s\" refToAnchor=\"%s\" refToSection=\"%s\">\n",
+ ref->ref().data(),ref->file().data(),ref->anchor().data(),
+ ref->targetTitle().data(),ref->hasLinkText()?"yes":"no",
+ ref->refToAnchor()?"yes":"no", ref->refToSection()?"yes":"no");
+ }
+ void visitPost(DocRef *)
+ {
+ indent_post();
+ printf("</ref>\n");
+ }
+ void visitPre(DocSecRefItem *ref)
+ {
+ indent_pre();
+ printf("<secrefitem target=\"%s\">\n",ref->target().data());
+ }
+ void visitPost(DocSecRefItem *)
+ {
+ indent_post();
+ printf("</secrefitem>\n");
+ }
+ void visitPre(DocSecRefList *)
+ {
+ indent_pre();
+ printf("<secreflist>\n");
+ }
+ void visitPost(DocSecRefList *)
+ {
+ indent_post();
+ printf("</secreflist>\n");
+ }
+ //void visitPre(DocLanguage *l)
+ //{
+ // indent_pre();
+ // printf("<language id=%s>\n",l->id().data());
+ //}
+ //void visitPost(DocLanguage *)
+ //{
+ // indent_post();
+ // printf("</language>\n");
+ //}
+ void visitPre(DocParamList *pl)
+ {
+ indent_pre();
+ //QStrListIterator sli(pl->parameters());
+ QListIterator<DocNode> sli(pl->parameters());
+ //const char *s;
+ DocNode *param;
+ printf("<parameters>");
+ for (sli.toFirst();(param=sli.current());++sli)
+ {
+ printf("<param>");
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ printf("</param>");
+ }
+ printf("\n");
+ }
+ void visitPost(DocParamList *)
+ {
+ indent_post();
+ printf("</parameters>\n");
+ }
+ void visitPre(DocParamSect *ps)
+ {
+ indent_pre();
+ printf("<paramsect type=");
+ switch (ps->type())
+ {
+ case DocParamSect::Param: printf("param"); break;
+ case DocParamSect::RetVal: printf("retval"); break;
+ case DocParamSect::Exception: printf("exception"); break;
+ case DocParamSect::TemplateParam: printf("templateparam"); break;
+ case DocParamSect::Unknown: printf("unknown"); break;
+ }
+ printf(">\n");
+ }
+ void visitPost(DocParamSect *)
+ {
+ indent_post();
+ printf("</paramsect>\n");
+ }
+ void visitPre(DocXRefItem *x)
+ {
+ indent_pre();
+ printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\"/>\n",
+ x->file().data(),x->anchor().data(),x->title().data());
+ }
+ void visitPost(DocXRefItem *)
+ {
+ indent_post();
+ printf("<xrefitem/>\n");
+ }
+ void visitPre(DocInternalRef *r)
+ {
+ indent_pre();
+ printf("<internalref file=%s anchor=%s>\n",r->file().data(),r->anchor().data());
+ }
+ void visitPost(DocInternalRef *)
+ {
+ indent_post();
+ printf("</internalref>\n");
+ }
+ void visitPre(DocCopy *c)
+ {
+ indent_pre();
+ printf("<copy link=\"%s\">\n",c->link().data());
+ }
+ void visitPost(DocCopy *)
+ {
+ indent_post();
+ printf("</copy>\n");
+ }
+ void visitPre(DocText *)
+ {
+ indent_pre();
+ printf("<text>\n");
+ }
+ void visitPost(DocText *)
+ {
+ indent_post();
+ printf("</text>\n");
+ }
+ void visitPre(DocHtmlBlockQuote *)
+ {
+ indent_pre();
+ printf("<blockquote>\n");
+ }
+ void visitPost(DocHtmlBlockQuote *)
+ {
+ indent_post();
+ printf("</blockquote>\n");
+ }
+ void visitPre(DocVhdlFlow *)
+ {
+ indent_pre();
+ printf("<vhdlflow>\n");
+ }
+ void visitPost(DocVhdlFlow *)
+ {
+ indent_post();
+ printf("</vhdlflow>\n");
+ }
+ void visitPre(DocParBlock *)
+ {
+ indent_pre();
+ printf("<parblock>\n");
+ }
+ void visitPost(DocParBlock *)
+ {
+ indent_post();
+ printf("</parblock>\n");
+ }
+
+ private:
+ // helper functions
+ void indent()
+ {
+ if (m_needsEnter) printf("\n");
+ for (int i=0;i<m_indent;i++) printf(".");
+ m_needsEnter=FALSE;
+ }
+ void indent_leaf()
+ {
+ if (!m_needsEnter) indent();
+ m_needsEnter=TRUE;
+ }
+ void indent_pre()
+ {
+ indent();
+ m_indent++;
+ }
+ void indent_post()
+ {
+ m_indent--;
+ indent();
+ }
+
+ // member variables
+ int m_indent;
+ bool m_needsEnter;
+ bool m_insidePre;
+};
+
+#endif
diff --git a/src/pycode.h b/src/pycode.h
new file mode 100644
index 0000000..9b0dacb
--- /dev/null
+++ b/src/pycode.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/* This code is based on the work done by the MoxyPyDoxy team
+ * (Linda Leong, Mike Rivera, Kim Truong, and Gabriel Estrada)
+ * in Spring 2005 as part of CS 179E: Compiler Design Project
+ * at the University of California, Riverside; the course was
+ * taught by Peter H. Froehlich <phf at acm.org>.
+ */
+
+
+#ifndef PYCODE_H
+#define PYCODE_H
+
+#include "types.h"
+
+class CodeOutputInterface;
+class FileDef;
+class MemberDef;
+class QCString;
+class Definition;
+
+extern void parsePythonCode(CodeOutputInterface &,const char *,const QCString &,
+ bool ,const char *,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
+ bool collectXRefs);
+extern void resetPythonCodeParserState();
+
+#endif
diff --git a/src/pycode.l b/src/pycode.l
new file mode 100644
index 0000000..585b587
--- /dev/null
+++ b/src/pycode.l
@@ -0,0 +1,1510 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/* This code is based on the work done by the MoxyPyDoxy team
+ * (Linda Leong, Mike Rivera, Kim Truong, and Gabriel Estrada)
+ * in Spring 2005 as part of CS 179E: Compiler Design Project
+ * at the University of California, Riverside; the course was
+ * taught by Peter H. Froehlich <phf at acm.org>.
+ */
+
+
+%{
+
+#include <stdio.h>
+#include <qvaluestack.h>
+
+#include "pycode.h"
+#include "message.h"
+
+#include "scanner.h"
+#include "entry.h"
+#include "doxygen.h"
+#include "outputlist.h"
+#include "util.h"
+#include "membername.h"
+#include "searchindex.h"
+#include "config.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "namespacedef.h"
+#include "tooltip.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+static ClassSDict g_codeClassSDict(17);
+static QCString g_curClassName;
+static QStrList g_curClassBases;
+
+
+static CodeOutputInterface * g_code;
+static const char * g_inputString; //!< the code fragment as text
+static int g_inputPosition; //!< read offset during parsing
+static const char * g_currentFontClass;
+static bool g_needsTermination;
+static Definition *g_searchCtx;
+static bool g_collectXRefs;
+static int g_inputLines; //!< number of line in the code fragment
+static int g_yyLineNr; //!< current line number
+static FileDef * g_sourceFileDef;
+static Definition * g_currentDefinition;
+static MemberDef * g_currentMemberDef;
+static bool g_includeCodeFragment;
+static QCString g_realScope;
+//static bool g_insideBody;
+static int g_bodyCurlyCount;
+static bool g_searchingForBody;
+static QCString g_classScope;
+static int g_paramParens;
+//static int g_anchorCount;
+
+static bool g_exampleBlock;
+static QCString g_exampleName;
+static QCString g_exampleFile;
+
+static QCString g_type;
+static QCString g_name;
+
+static bool g_doubleStringIsDoc;
+static bool g_doubleQuote;
+static bool g_noSuiteFound;
+static int g_stringContext;
+
+static QValueStack<uint> g_indents; //!< Tracks indentation levels for scoping in python
+
+static void endFontClass();
+static void adjustScopesAndSuites(unsigned indentLength);
+
+
+/*! Represents a stack of variable to class mappings as found in the
+ * code. Each scope is enclosed in pushScope() and popScope() calls.
+ * Variables are added by calling addVariables() and one can search
+ * for variable using findVariable().
+ */
+class PyVariableContext
+{
+ public:
+ static const ClassDef *dummyContext;
+ class Scope : public SDict<ClassDef>
+ {
+ public:
+ Scope() : SDict<ClassDef>(17) {}
+ };
+
+ PyVariableContext()
+ {
+ m_scopes.setAutoDelete(TRUE);
+ }
+
+ virtual ~PyVariableContext()
+ {
+ }
+
+ void pushScope()
+ {
+ m_scopes.append(new Scope);
+ }
+
+ void popScope()
+ {
+ if (m_scopes.count()>0)
+ {
+ m_scopes.remove(m_scopes.count()-1);
+ }
+ }
+
+ void clear()
+ {
+ m_scopes.clear();
+ m_globalScope.clear();
+ }
+
+ void clearExceptGlobal()
+ {
+ m_scopes.clear();
+ }
+
+ void addVariable(const QCString &type,const QCString &name);
+ ClassDef *findVariable(const QCString &name);
+
+ private:
+ Scope m_globalScope;
+ QList<Scope> m_scopes;
+};
+
+void PyVariableContext::addVariable(const QCString &type,const QCString &name)
+{
+ //printf("PyVariableContext::addVariable(%s,%s)\n",type.data(),name.data());
+ QCString ltype = type.simplifyWhiteSpace();
+ QCString lname = name.simplifyWhiteSpace();
+
+ Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
+ ClassDef *varType;
+ if (
+ (varType=g_codeClassSDict[ltype]) || // look for class definitions inside the code block
+ (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
+ )
+ {
+ scope->append(lname,varType); // add it to a list
+ }
+ else
+ {
+ if (m_scopes.count()>0) // for local variables add a dummy entry so the name
+ // is hidden to avoid FALSE links to global variables with the same name
+ // TODO: make this work for namespaces as well!
+ {
+ scope->append(lname,dummyContext);
+ }
+ }
+}
+
+ClassDef *PyVariableContext::findVariable(const QCString &name)
+{
+ if (name.isEmpty()) return 0;
+ ClassDef *result = 0;
+ QListIterator<Scope> sli(m_scopes);
+ Scope *scope;
+ // search from inner to outer scope
+ for (sli.toLast();(scope=sli.current());--sli)
+ {
+ result = scope->find(name);
+ if (result)
+ {
+ return result;
+ }
+ }
+ // nothing found -> also try the global scope
+ result=m_globalScope.find(name);
+ return result;
+}
+
+static PyVariableContext g_theVarContext;
+const ClassDef *PyVariableContext::dummyContext = (ClassDef*)0x8;
+
+class PyCallContext
+{
+ public:
+ struct Ctx
+ {
+ Ctx() : name(g_name), type(g_type), cd(0) {}
+ QCString name;
+ QCString type;
+ ClassDef *cd;
+ };
+
+ PyCallContext()
+ {
+ m_classList.append(new Ctx);
+ m_classList.setAutoDelete(TRUE);
+ }
+
+ virtual ~PyCallContext() {}
+
+ void setClass(ClassDef *cd)
+ {
+ Ctx *ctx = m_classList.getLast();
+ if (ctx)
+ {
+ ctx->cd=cd;
+ }
+ }
+ void pushScope()
+ {
+ m_classList.append(new Ctx);
+ }
+
+ void popScope()
+ {
+ if (m_classList.count()>1)
+ {
+ Ctx *ctx = m_classList.getLast();
+ if (ctx)
+ {
+ g_name = ctx->name;
+ g_type = ctx->type;
+ }
+ m_classList.removeLast();
+ }
+ else
+ {
+ }
+ }
+
+ void clear()
+ {
+ m_classList.clear();
+ m_classList.append(new Ctx);
+ }
+
+ ClassDef *getClass() const
+ {
+ Ctx *ctx = m_classList.getLast();
+
+ if (ctx)
+ return ctx->cd;
+ else
+ return 0;
+ }
+
+ private:
+ QList<Ctx> m_classList;
+};
+
+static PyCallContext g_theCallContext;
+
+
+/*! counts the number of lines in the input */
+static int countLines()
+{
+ const char *p=g_inputString;
+ char c;
+ int count=1;
+ while ((c=*p))
+ {
+ p++ ;
+ if (c=='\n') count++;
+ }
+ if (p>g_inputString && *(p-1)!='\n')
+ { // last line does not end with a \n, so we add an extra
+ // line and explicitly terminate the line after parsing.
+ count++,
+ g_needsTermination=TRUE;
+ }
+ return count;
+}
+
+static void setCurrentDoc(const QCString &anchor)
+{
+ if (Doxygen::searchIndex)
+ {
+ if (g_searchCtx)
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
+ }
+ else
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
+ }
+ }
+}
+
+static void addToSearchIndex(const char *text)
+{
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->addWord(text,FALSE);
+ }
+}
+
+
+static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition)
+{
+ int pos=0;
+ QCString type = s;
+ QCString className;
+ QCString templSpec;
+ while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
+ {
+ QCString clName=className+templSpec;
+
+ ClassDef *cd=0;
+ if (!g_classScope.isEmpty())
+ {
+ cd=getResolvedClass(d,g_sourceFileDef,g_classScope+"::"+clName);
+ }
+ if (cd==0)
+ {
+ cd=getResolvedClass(d,g_sourceFileDef,clName);
+ }
+ if (cd)
+ {
+ return cd;
+ }
+ }
+
+ return 0;
+}
+
+
+
+/*! start a new line of code, inserting a line number if g_sourceFileDef
+ * is TRUE. If a definition starts at the current line, then the line
+ * number is linked to the documentation of that definition.
+ */
+static void startCodeLine()
+{
+ //if (g_currentFontClass) { g_code->endFontClass(); }
+ if (g_sourceFileDef)
+ {
+ //QCString lineNumber,lineAnchor;
+ //lineNumber.sprintf("%05d",g_yyLineNr);
+ //lineAnchor.sprintf("l%05d",g_yyLineNr);
+
+ Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
+ //printf("startCodeLine %d d=%p\n",g_yyLineNr,d);
+ //g_code->startLineNumber();
+ if (!g_includeCodeFragment && d && d->isLinkableInProject())
+ {
+ g_currentDefinition = d;
+ g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
+ //g_insideBody = FALSE;
+ g_searchingForBody = TRUE;
+ g_realScope = d->name().copy();
+ g_classScope = d->name().copy();
+ //printf("Real scope: `%s'\n",g_realScope.data());
+ g_bodyCurlyCount = 0;
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",g_yyLineNr);
+ if (g_currentMemberDef)
+ {
+ g_code->writeLineNumber(g_currentMemberDef->getReference(),
+ g_currentMemberDef->getOutputFileBase(),
+ g_currentMemberDef->anchor(),g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ else
+ {
+ g_code->writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ 0,g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ }
+ else
+ {
+ //g_code->codify(lineNumber);
+ g_code->writeLineNumber(0,0,0,g_yyLineNr);
+ }
+ //g_code->endLineNumber();
+ }
+ g_code->startCodeLine(g_sourceFileDef);
+ if (g_currentFontClass)
+ {
+ g_code->startFontClass(g_currentFontClass);
+ }
+}
+
+static void codify(const char* text)
+{
+ g_code->codify(text);
+}
+
+static void endCodeLine()
+{
+ endFontClass();
+ g_code->endCodeLine();
+}
+
+static void nextCodeLine()
+{
+ const char *fc = g_currentFontClass;
+ endCodeLine();
+ if (g_yyLineNr<g_inputLines)
+ {
+ g_currentFontClass = fc;
+ startCodeLine();
+ }
+}
+
+
+/*! writes a link to a fragment \a text that may span multiple lines, inserting
+ * line numbers for each line. If \a text contains newlines, the link will be
+ * split into multiple links with the same destination, one for each line.
+ */
+static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ Definition *d,
+ const char *text)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ TooltipManager::instance()->addTooltip(d);
+ QCString ref = d->getReference();
+ QCString file = d->getOutputFileBase();
+ QCString anchor = d->anchor();
+ QCString tooltip;
+ if (!sourceTooltips) // fall back to simple "title" tooltips
+ {
+ tooltip = d->briefDescriptionAsTooltip();
+ }
+ bool done=FALSE;
+ char *p=(char *)text;
+ while (!done)
+ {
+ char *sp=p;
+ char c;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ nextCodeLine();
+ }
+ else
+ {
+ //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ done=TRUE;
+ }
+ }
+}
+
+
+static void codifyLines(char *text)
+{
+ //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
+ char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') { }
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ g_code->codify(sp);
+ nextCodeLine();
+ }
+ else
+ {
+ g_code->codify(sp);
+ done=TRUE;
+ }
+ }
+}
+
+
+static bool getLinkInScope(const QCString &c, // scope
+ const QCString &m, // member
+ const char *memberText, // exact text
+ CodeOutputInterface &ol,
+ const char *text
+ )
+{
+ MemberDef *md;
+ ClassDef *cd;
+ FileDef *fd;
+ NamespaceDef *nd;
+ GroupDef *gd;
+ //printf("Trying `%s'::`%s'\n",c.data(),m.data());
+ if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) &&
+ md->isLinkable())
+ {
+ //Definition *d=0;
+ //if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
+
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getBodyDef() : md->getOuterScope();
+ //printf("Found! d=%s\n",d?d->name().data():"<none>");
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable())
+ {
+ g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
+ //printf("g_currentDefinition=%p g_currentMemberDef=%p\n",
+ // g_currentDefinition,g_currentMemberDef);
+
+ if (g_currentDefinition && g_currentMemberDef &&
+ md!=g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ //printf("d->getReference()=`%s' d->getOutputBase()=`%s' name=`%s' member name=`%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data());
+
+ writeMultiLineCodeLink(ol,md, text ? text : memberText);
+ addToSearchIndex(text ? text : memberText);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool getLink(const char *className,
+ const char *memberName,
+ CodeOutputInterface &ol,
+ const char *text=0)
+{
+ QCString m=removeRedundantWhiteSpace(memberName);
+ QCString c=className;
+ if (!getLinkInScope(c,m,memberName,ol,text))
+ {
+ if (!g_curClassName.isEmpty())
+ {
+ if (!c.isEmpty()) c.prepend("::");
+ c.prepend(g_curClassName);
+ return getLinkInScope(c,m,memberName,ol,text);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ For a given string in the source code,
+ finds its class or global id and links to it.
+*/
+static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
+ bool typeOnly=FALSE)
+{
+ QCString className=clName;
+
+ // Don't do anything for empty text
+ if (className.isEmpty()) return;
+
+ DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",className.data()));
+
+ ClassDef *cd=0,*lcd=0; /** Class def that we may find */
+ MemberDef *md=0; /** Member def that we may find */
+ //bool isLocal=FALSE;
+
+ if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable
+ {
+ Definition *d = g_currentDefinition;
+ QCString scope = substitute(className,".","::");
+
+ cd = getResolvedClass(d,g_sourceFileDef,substitute(className,".","::"),&md);
+
+ DBG_CTX((stderr,"d=%s g_sourceFileDef=%s\n",
+ d?d->displayName().data():"<null>",
+ g_currentDefinition?g_currentDefinition->displayName().data():"<null>"));
+ DBG_CTX((stderr,"is found as a type %s\n",cd?cd->name().data():"<null>"));
+
+ if (cd==0 && md==0) // also see if it is variable or enum or enum value
+ {
+ NamespaceDef *nd = getResolvedNamespace(scope);
+ if (nd)
+ {
+ writeMultiLineCodeLink(ol,nd,clName);
+ addToSearchIndex(className);
+ return;
+ }
+ else if (getLink(g_classScope,clName,ol,clName))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ if (lcd!=PyVariableContext::dummyContext)
+ {
+ g_theCallContext.setClass(lcd);
+ }
+ //isLocal=TRUE;
+ DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
+ }
+
+ if (cd && cd->isLinkable()) // is it a linkable class
+ {
+ writeMultiLineCodeLink(ol,cd,clName);
+ addToSearchIndex(className);
+ if (md)
+ {
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getBodyDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable() && md->isLinkable() &&
+ g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ }
+ }
+ else // not a class, maybe a global member
+ {
+ int scopeEnd = className.findRev(".");
+ if (scopeEnd!=-1 && !typeOnly) // name with explicit scope
+ {
+ QCString scope = substitute(className.left(scopeEnd),".","::");
+ QCString locName = className.right(className.length()-scopeEnd-1);
+ ClassDef *mcd = getClass(scope);
+ DBG_CTX((stderr,"scope=%s locName=%s mcd=%p\n",scope.data(),locName.data(),mcd));
+ if (mcd)
+ {
+ MemberDef *md = mcd->getMemberByName(locName);
+ if (md)
+ {
+ g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
+ writeMultiLineCodeLink(ol,md,clName);
+ addToSearchIndex(className);
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getBodyDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable() && md->isLinkable() &&
+ g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ return;
+ }
+ }
+ else // check namespace as well
+ {
+ NamespaceDef *mnd = getResolvedNamespace(scope);
+ if (mnd)
+ {
+ MemberDef *md=mnd->getMemberByName(locName);
+ if (md)
+ {
+ //printf("name=%s scope=%s\n",locName.data(),scope.data());
+ g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
+ writeMultiLineCodeLink(ol,md,clName);
+ addToSearchIndex(className);
+ Definition *d = md->getOuterScope()==Doxygen::globalScope ?
+ md->getBodyDef() : md->getOuterScope();
+ if (md->getGroupDef()) d = md->getGroupDef();
+ if (d && d->isLinkable() && md->isLinkable() &&
+ g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,md);
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ // nothing found, just write out the word
+ codifyLines(clName);
+ addToSearchIndex(clName);
+ }
+}
+
+/*
+ As of June 1, this function seems to work
+ for file members, but scopes are not
+ being correctly tracked for classes
+ so it doesn't work for classes yet.
+
+*/
+static void generateFunctionLink(CodeOutputInterface &ol,char *funcName)
+{
+ //CodeClassDef *ccd=0;
+ ClassDef *ccd=0;
+ QCString locScope=g_classScope.copy();
+ QCString locFunc=removeRedundantWhiteSpace(funcName);
+ DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data()));
+ int i=locFunc.findRev("::");
+ if (i>0)
+ {
+ locScope=locFunc.left(i);
+ locFunc=locFunc.right(locFunc.length()-i-2).stripWhiteSpace();
+ }
+ //printf("generateFunctionLink(%s) classScope=`%s'\n",locFunc.data(),locScope.data());
+ if (!locScope.isEmpty() && (ccd=g_codeClassSDict[locScope]))
+ {
+ //printf("using classScope %s\n",g_classScope.data());
+ if (ccd->baseClasses())
+ {
+ BaseClassListIterator bcli(*ccd->baseClasses());
+ for ( ; bcli.current() ; ++bcli)
+ {
+ if (getLink(bcli.current()->classDef->name(),locFunc,ol,funcName))
+ {
+ return;
+ }
+ }
+ }
+ }
+ if (!getLink(locScope,locFunc,ol,funcName))
+ {
+ generateClassOrGlobalLink(ol,funcName);
+ }
+ return;
+}
+
+static bool findMemberLink(CodeOutputInterface &ol,Definition *sym,const char *symName)
+{
+ //printf("sym %s outerScope=%s equal=%d\n",
+ // sym->name().data(),sym->getOuterScope()->name().data(),
+ // sym->getOuterScope()==g_currentDefinition);
+
+ if (sym->getOuterScope() &&
+ sym->getOuterScope()->definitionType()==Definition::TypeClass &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd = (ClassDef*)sym->getOuterScope();
+ ClassDef *thisCd = (ClassDef *)g_currentDefinition;
+ if (sym->definitionType()==Definition::TypeMember)
+ {
+ if (g_currentMemberDef && g_collectXRefs)
+ {
+ addDocCrossReference(g_currentMemberDef,(MemberDef*)sym);
+ }
+ }
+ DBG_CTX((stderr,"cd=%s thisCd=%s\n",cd?cd->name().data():"<none>",thisCd?thisCd->name().data():"<none>"));
+
+ // TODO: find the nearest base class in case cd is a base class of
+ // thisCd
+ if (cd==thisCd || (thisCd && thisCd->isBaseClass(cd,TRUE)))
+ {
+ writeMultiLineCodeLink(ol,sym,symName);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void findMemberLink(CodeOutputInterface &ol,char *symName)
+{
+ //printf("Member reference: %s scope=%s member=%s\n",
+ // yytext,
+ // g_currentDefinition?g_currentDefinition->name().data():"<none>",
+ // g_currentMemberDef?g_currentMemberDef->name().data():"<none>"
+ // );
+ if (g_currentDefinition)
+ {
+ DefinitionIntf *di = Doxygen::symbolMap->find(symName);
+ if (di)
+ {
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multiple symbols
+ {
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *sym;
+ for (dli.toFirst();(sym=dli.current());++dli)
+ {
+ if (findMemberLink(ol,sym,symName)) return;
+ }
+ }
+ else // single symbol
+ {
+ if (findMemberLink(ol,(Definition*)di,symName)) return;
+ }
+ }
+ }
+ //printf("sym %s not found\n",&yytext[5]);
+ codify(symName);
+}
+
+static void startFontClass(const char *s)
+{
+ endFontClass();
+ g_code->startFontClass(s);
+ g_currentFontClass=s;
+}
+
+static void endFontClass()
+{
+ if (g_currentFontClass)
+ {
+ g_code->endFontClass();
+ g_currentFontClass=0;
+ }
+}
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+
+BB [ \t]+
+B [ \t]*
+NEWLINE \n
+
+DIGIT [0-9]
+LETTER [A-Za-z\x80-\xFF]
+NONEMPTY [A-Za-z0-9_\x80-\xFF]
+EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-]
+NONEMPTYEXP [^ \t\n:]
+PARAMNONEMPTY [^ \t\n():]
+IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")*
+BORDER ([^A-Za-z0-9])
+
+POUNDCOMMENT "#".*
+
+TRISINGLEQUOTE "'''"
+TRIDOUBLEQUOTE "\"\"\""
+LONGSTRINGCHAR [^\\"']
+ESCAPESEQ ("\\")(.)
+LONGSTRINGITEM ({LONGSTRINGCHAR}|{ESCAPESEQ})
+SMALLQUOTE ("\"\""|"\""|"'"|"''")
+LONGSTRINGBLOCK ({LONGSTRINGITEM}+|{SMALLQUOTE})
+
+SHORTSTRING ("'"{SHORTSTRINGITEM}*"'"|'"'{SHORTSTRINGITEM}*'"')
+SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ})
+SHORTSTRINGCHAR [^\\\n"]
+STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING})
+STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR")
+KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False")
+FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally")
+QUOTES ("\""[^"]*"\"")
+SINGLEQUOTES ("'"[^']*"'")
+
+LONGINTEGER {INTEGER}("l"|"L")
+INTEGER ({DECIMALINTEGER}|{OCTINTEGER}|{HEXINTEGER})
+DECIMALINTEGER ({NONZERODIGIT}{DIGIT}*|"0")
+OCTINTEGER "0"{OCTDIGIT}+
+HEXINTEGER "0"("x"|"X"){HEXDIGIT}+
+NONZERODIGIT [1-9]
+OCTDIGIT [0-7]
+HEXDIGIT ({DIGIT}|[a-f]|[A-F])
+FLOATNUMBER ({POINTFLOAT}|{EXPONENTFLOAT})
+POINTFLOAT ({INTPART}?{FRACTION}|{INTPART}".")
+EXPONENTFLOAT ({INTPART}|{POINTFLOAT}){EXPONENT}
+INTPART {DIGIT}+
+FRACTION "."{DIGIT}+
+EXPONENT ("e"|"E")("+"|"-")?{DIGIT}+
+IMAGNUMBER ({FLOATNUMBER}|{INTPART})("j"|"J")
+ATOM ({IDENTIFIER}|{LITERAL}|{ENCLOSURE})
+ENCLOSURE ({PARENTH_FORM}|{LIST_DISPLAY}|{DICT_DISPLAY}|{STRING_CONVERSION})
+LITERAL ({STRINGLITERAL}|{INTEGER}|{LONGINTEGER}|{FLOATNUMBER}|{IMAGNUMBER})
+PARENTH_FORM "("{EXPRESSION_LIST}?")"
+TEST ({AND_TEST}("or"{AND_TEST})*|{LAMBDA_FORM})
+TESTLIST {TEST}( ","{TEST})*","?
+LIST_DISPLAY "["{LISTMAKER}?"]"
+LISTMAKER {EXPRESSION}({LIST_FOR}|(","{EXPRESSION})*","?)
+LIST_ITER ({LIST_FOR}|{LIST_IF})
+LIST_FOR "for"{EXPRESSION_LIST}"in"{TESTLIST}{LIST_ITER}?
+LIST_IF "if"{TEST}{LIST_ITER}?
+DICT_DISPLAY "\{"{KEY_DATUM_LIST}?"\}"
+KEY_DATUM_LIST {KEY_DATUM}(","{KEY_DATUM})*","?
+KEY_DATUM {EXPRESSION}":"{EXPRESSION}
+STRING_CONVERSION "`"{EXPRESSION_LIST}"`"
+PRIMARY ({ATOM}|{ATTRIBUTEREF}|{SUBSCRIPTION}|{SLICING}|{CALL})
+ATTRIBUTEREF {PRIMARY}"."{IDENTIFIER}
+SUBSCRIPTION {PRIMARY}"["{EXPRESSION_LIST}"]"
+SLICING ({SIMPLE_SLICING}|{EXTENDED_SLICING})
+SIMPLE_SLICING {PRIMARY}"["{SHORT_SLICE}"]"
+EXTENDED_SLICING {PRIMARY}"["{SLICE_LIST}"]"
+SLICE_LIST {SLICE_ITEM}(","{SLICE_ITEM})*","?
+SLICE_ITEM ({EXPRESSION}|{PROPER_SLICE}|{ELLIPSIS})
+PROPER_SLICE ({SHORT_SLICE}|{LONG_SLICE})
+SHORT_SLICE {LOWER_BOUND}?":"{UPPER_BOUND}?
+LONG_SLICE {SHORT_SLICE}":"{STRIDE}?
+LOWER_BOUND {EXPRESSION}
+UPPER_BOUND {EXPRESSION}
+STRIDE {EXPRESSION}
+ELLIPSIS "..."
+CALL {PRIMARY}"("({ARGUMENT_LIST}","?)?")"
+ARGUMENT_LIST ({POSITIONAL_ARGUMENTS}(","{KEYWORD_ARGUMENTS})?(",""*"{EXPRESSION})?(",""**"{EXPRESSION})?|{KEYWORD_ARGUMENTS}(",""*"{EXPRESSION})?(",""**"{EXPRESSION})?|"*"{EXPRESSION}(",""**"{EXPRESSION})?|"**"{EXPRESSION})
+POSITIONAL_ARGUMENTS {EXPRESSION}(","{EXPRESSION})*
+KEYWORD_ARGUMENTS {KEYWORD_ITEM}(","{KEYWORD_ITEM})*
+KEYWORD_ITEM {IDENTIFIER}"="{EXPRESSION}
+POWER {PRIMARY}("**"{U_EXPR})?
+U_EXPR ({POWER}|"-"{U_EXPR}|"+"{U_EXPR}|"\~"{U_EXPR})
+M_EXPR ({U_EXPR}|{M_EXPR}"*"{U_EXPR}|{M_EXPR}"//"{U_EXPR}|{M_EXPR}"/"{U_EXPR}|{M_EXPR}"\%"{U_EXPR})
+A_EXPR ({M_EXPR}|{A_EXPR}"+"{M_EXPR}|{A_EXPR}"-"{M_EXPR}
+SHIFT_EXPR ({A_EXPR}|{SHIFT_EXPR}("<<"|">>"){A_EXPR})
+AND_EXPR ({SHIFT_EXPR}|{AND_EXPR}"\;SPMamp;"{SHIFT_EXPR}
+XOR_EXPR ({AND_EXPR}|{XOR_EXPR}"\textasciicircum"{AND_EXPR})
+OR_EXPR ({XOR_EXPR}|{OR_EXPR}"|"{ XOR_EXPR})
+
+COMPARISON {OR_EXPR}({COMP_OPERATOR}{OR_EXPR})*
+COMP_OPERATOR ("<"|">"|"=="|">="|"<="|"<>"|"!="|"is""not"?|"not"?"in")
+EXPRESSION ({OR_TEST}|{LAMBDA_FORM})
+OR_TEST ({AND_TEST}|{OR_TEST}"or"{AND_TEST})
+AND_TEST ({NOT_TEST}|{AND_TEST}"and"{NOT_TEST})
+NOT_TEST ({COMPARISON}|"not"{NOT_TEST})
+LAMBDA_FORM "lambda"{PARAMETER_LIST}?":"{EXPRESSION}
+EXPRESSION_LIST {EXPRESSION}(","{EXPRESSION})*","?
+SIMPLE_STMT ({EXPRESSION_STMT}|{ASSERT_STMT}|{ASSIGNMENT_STMT}|{AUGMENTED_ASSIGNMENT_STMT}|{PASS_STMT}|{DEL_STMT}|{PRINT_STMT}|{RETURN_STMT}|{YIELD_STMT}|{RAISE_STMT}|{BREAK_STMT}|{CONTINUE_STMT}|{IMPORT_STMT}|{GLOBAL_STMT}|{EXEC_STMT})
+EXPRESSION_STMT {EXPRESSION_LIST}
+ASSERT_STMT "assert"{EXPRESSION}(","{EXPRESSION})?
+ASSIGNMENT_STMT ({TARGET_LIST}"=")+{EXPRESSION_LIST}
+TARGET_LIST {TARGET}(","{TARGET})*","?
+TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUTEREF}|{SUBSCRIPTION}|{SLICING})
+
+
+%option noyywrap
+%option nounput
+
+%x Body
+
+%x FunctionDec
+%x FunctionParams
+
+%x ClassDec
+%x ClassInheritance
+
+%x Suite
+%x SuiteCaptureIndent
+%x SuiteStart
+%x SuiteMaintain
+%x SuiteContinuing
+
+%x LongString
+
+%x SingleQuoteString
+%x DoubleQuoteString
+%x TripleString
+
+%%
+
+<Body,Suite>{
+ "def"{BB} {
+ startFontClass("keyword");
+ codify(yytext);
+ endFontClass();
+ BEGIN( FunctionDec );
+ }
+
+ "class"{BB} {
+ startFontClass("keyword");
+ codify(yytext);
+ endFontClass();
+ BEGIN( ClassDec );
+ }
+ "None" {
+ startFontClass("keywordtype");
+ codify(yytext);
+ endFontClass();
+ }
+ "self."{IDENTIFIER}/"(" {
+ codify("self.");
+ findMemberLink(*g_code,&yytext[5]);
+ }
+ "self."{IDENTIFIER} {
+ codify("self.");
+ findMemberLink(*g_code,&yytext[5]);
+ }
+}
+
+<ClassDec>{IDENTIFIER} {
+
+ generateClassOrGlobalLink(*g_code,yytext);
+ // codify(yytext);
+ g_curClassName = yytext;
+ g_curClassBases.clear();
+ BEGIN( ClassInheritance );
+ }
+
+<ClassInheritance>{
+ ({BB}|[(,)]) {
+ codify(yytext);
+ }
+
+ ({IDENTIFIER}".")*{IDENTIFIER} {
+ // The parser
+ // is assuming
+ // that ALL identifiers
+ // in this state
+ // are base classes;
+ // it doesn't check to see
+ // that the first parenthesis
+ // has been seen.
+
+ // This is bad - it should
+ // probably be more strict
+ // about what to accept.
+
+ g_curClassBases.inSort(yytext);
+ generateClassOrGlobalLink(*g_code,yytext);
+ // codify(yytext);
+ }
+
+ ":" {
+ codify(yytext);
+
+ // Assume this will
+ // be a one-line suite;
+ // found counter-example
+ // in SuiteStart.
+
+ // Push a class scope
+
+ ClassDef *classDefToAdd = new ClassDef("<code>",1,1,g_curClassName,ClassDef::Class,0,0,FALSE);
+ g_codeClassSDict.append(g_curClassName,classDefToAdd);
+ char *s=g_curClassBases.first();
+ while (s)
+ {
+ ClassDef *baseDefToAdd;
+ baseDefToAdd=g_codeClassSDict[s];
+
+ // Try to find class in global
+ // scope
+ if (baseDefToAdd==0)
+ {
+ baseDefToAdd=getResolvedClass(g_currentDefinition,g_sourceFileDef,s);
+ }
+
+ if (baseDefToAdd && baseDefToAdd!=classDefToAdd)
+ {
+ classDefToAdd->insertBaseClass(baseDefToAdd,s,Public,Normal);
+ }
+
+ s=g_curClassBases.next();
+ }
+
+ // Reset class-parsing variables.
+ g_curClassName.resize(0);
+ g_curClassBases.clear();
+
+ g_noSuiteFound = TRUE;
+ BEGIN( SuiteStart );
+ }
+}
+
+
+<FunctionDec>{
+ {IDENTIFIER} {
+ generateFunctionLink(*g_code,yytext);
+ }
+
+ {B}"(" {
+ codify(yytext);
+ BEGIN( FunctionParams );
+ }
+}
+
+<FunctionParams>{
+ ({BB}|",") {
+ // Parses delimiters
+ codify(yytext);
+ }
+
+ ({IDENTIFIER}|{PARAMNONEMPTY}+) {
+ codify(yytext);
+ }
+
+ ")" {
+ codify(yytext);
+ }
+
+ ":" {
+ codify(yytext);
+
+ // Assume this will
+ // be a one-line suite;
+ // found counter-example
+ // in SuiteStart.
+ g_noSuiteFound = TRUE;
+ BEGIN( SuiteStart );
+ }
+}
+
+<Body,Suite>{
+
+ {KEYWORD} {
+ // Position-sensitive rules!
+ // Must come AFTER keyword-triggered rules
+ // Must come BEFORE identifier NONEMPTY-like rules
+ // to syntax highlight.
+
+ startFontClass("keyword");
+ codify(yytext);
+ endFontClass();
+ }
+
+ {FLOWKW} {
+ startFontClass("keywordflow");
+ codify(yytext);
+ endFontClass();
+ }
+ ({IDENTIFIER}".")*{IDENTIFIER}/"(" {
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+ ({IDENTIFIER}".")+{IDENTIFIER} {
+ generateClassOrGlobalLink(*g_code,yytext,TRUE);
+ }
+ {IDENTIFIER} { codify(yytext); }
+
+}
+
+
+
+<SuiteStart>{
+
+ {BB} {
+ codify(yytext);
+ }
+ "pass" {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ BEGIN(Body);
+ }
+ {KEYWORD} {
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+
+ // No indentation necessary
+ g_noSuiteFound = FALSE;
+ }
+
+ {FLOWKW} {
+ startFontClass("keywordflow");
+ codifyLines(yytext);
+ endFontClass();
+
+ // No indentation necessary
+ g_noSuiteFound = FALSE;
+ }
+ {IDENTIFIER} {
+ codify(yytext);
+ }
+
+
+ {POUNDCOMMENT} {
+ // This eats EVERYTHING
+ // except the newline
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+
+ {NEWLINE} {
+ codifyLines(yytext);
+ if ( g_noSuiteFound )
+ {
+ // printf("New suite to capture! [%d]\n", g_yyLineNr);
+ BEGIN ( SuiteCaptureIndent );
+ }
+ }
+}
+
+<SuiteCaptureIndent>{
+ "\n"|({BB}"\n") {
+ // Blankline - ignore, keep looking for indentation.
+ codifyLines(yytext);
+ }
+
+ {BB} {
+ // This state lasts momentarily,
+ // to check the indentation
+ // level that is about to be
+ // used.
+ codifyLines(yytext);
+ g_indents.push(yyleng);
+ // printf("Captured indent of %d [line %d]\n", yyleng, g_yyLineNr);
+ BEGIN( Suite );
+ }
+}
+
+<SuiteMaintain>{
+
+ {BB}/({NONEMPTY}|{EXPCHAR}) {
+ // This implements poor
+ // indendation-tracking;
+ // should be improved.
+ // (translate tabs to space, etc)
+ codifyLines(yytext);
+ adjustScopesAndSuites((int)yyleng);
+ }
+
+ "\n"|({BB}"\n") {
+ // If this ever succeeds,
+ // it means that this is
+ // a blank line, and
+ // can be ignored.
+ codifyLines(yytext);
+ }
+
+ ""/({NONEMPTY}|{EXPCHAR}) {
+ // Default rule; matches
+ // the empty string, assuming
+ // real text starts here.
+ // Just go straight to Body.
+ adjustScopesAndSuites(0);
+ }
+}
+
+
+<Suite>{NEWLINE} {
+ codifyLines(yytext);
+ BEGIN( SuiteMaintain );
+ }
+<Body>{IDENTIFIER} {
+ codify(yytext);
+ }
+<Body>{NEWLINE} {
+ codifyLines(yytext);
+ }
+
+<SingleQuoteString>{ // Single quoted string like 'That\'s a """nice""" string!'
+ \\{B}\n { // line continuation
+ codifyLines(yytext);
+ }
+ \\. { // espaced char
+ codify(yytext);
+ }
+ {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // tripple double quotes
+ codify(yytext);
+ }
+ "'" { // end of the string
+ codify(yytext);
+ endFontClass();
+ BEGIN(g_stringContext);
+ }
+ [^"'\n\\]+ { // normal chars
+ codify(yytext);
+ }
+ . { // normal char
+ codify(yytext);
+ }
+}
+
+<DoubleQuoteString>{ // Double quoted string like "That's \"a '''nice'''\" string!"
+ \\{B}\n { // line continuation
+ codifyLines(yytext);
+ }
+ \\. { // espaced char
+ codify(yytext);
+ }
+ {STRINGPREFIX}?{TRISINGLEQUOTE} { // tripple single quotes
+ codify(yytext);
+ }
+ "\"" { // end of the string
+ codify(yytext);
+ endFontClass();
+ BEGIN(g_stringContext);
+ }
+ [^"'\n\\]+ { // normal chars
+ codify(yytext);
+ }
+ . { // normal char
+ codify(yytext);
+ }
+}
+
+<TripleString>{
+ {TRIDOUBLEQUOTE} |
+ {TRISINGLEQUOTE} {
+ codify(yytext);
+ if (g_doubleQuote==(yytext[0]=='"'))
+ {
+ endFontClass();
+ BEGIN(g_stringContext);
+ }
+ }
+ {LONGSTRINGBLOCK} {
+ codifyLines(yytext);
+ }
+ \n {
+ codifyLines(yytext);
+ }
+ . {
+ codify(yytext);
+ }
+}
+
+ /*
+<*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time.
+ codify(yytext);
+ // printf("[pycode] '%s' [ state %d ] [line %d] no match\n",
+ // yytext, YY_START, g_yyLineNr);
+
+ //endFontClass();
+ BEGIN(Body);
+ }
+ */
+
+<*>{STRINGPREFIX}?{TRISINGLEQUOTE} |
+<*>{STRINGPREFIX}?{TRIDOUBLEQUOTE} {
+ startFontClass("stringliteral");
+ g_stringContext=YY_START;
+ g_doubleQuote=yytext[yyleng-1]=='"';
+ codify(yytext);
+ BEGIN(TripleString);
+ }
+<*>{STRINGPREFIX}?"'" { // single quoted string
+ startFontClass("stringliteral");
+ g_stringContext=YY_START;
+ codify(yytext);
+ BEGIN(SingleQuoteString);
+ }
+<*>{STRINGPREFIX}?"\"" { // double quoted string
+ startFontClass("stringliteral");
+ g_stringContext=YY_START;
+ codify(yytext);
+ BEGIN(DoubleQuoteString);
+ }
+<*>{POUNDCOMMENT} {
+ if (YY_START==SingleQuoteString ||
+ YY_START==DoubleQuoteString ||
+ YY_START==TripleString
+ )
+ {
+ REJECT;
+ }
+ // This eats EVERYTHING
+ // except the newline
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+<*>{NEWLINE} {
+ codifyLines(yytext);
+ //printf("[pycode] %d NEWLINE [line %d] no match\n",
+ // YY_START, g_yyLineNr);
+
+ //endFontClass();
+ BEGIN(Body);
+ }
+
+<*>[ \t]+ {
+ codify(yytext);
+ BEGIN(Body);
+ }
+<*>. {
+ codify(yytext);
+ // printf("[pycode] '%s' [ state %d ] [line %d] no match\n",
+ // yytext, YY_START, g_yyLineNr);
+
+ //endFontClass();
+ BEGIN(Body);
+ }
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+void resetPythonCodeParserState()
+{
+ g_currentDefinition = 0;
+ g_currentMemberDef = 0;
+ g_doubleStringIsDoc = FALSE;
+ g_paramParens = 0;
+ g_indents.clear();
+ BEGIN( Body );
+}
+
+/*!
+ Examines current stack of white-space indentations;
+ re-syncs the parser with the correct scope.
+*/
+static void adjustScopesAndSuites(unsigned indentLength)
+{
+ // States to pop
+ if (!g_indents.isEmpty() && indentLength < g_indents.top())
+ {
+ while (!g_indents.isEmpty() && indentLength < g_indents.top())
+ {
+ // printf("Exited scope indent of [%d]\n", g_indents.top());
+ g_indents.pop(); // Pop the old suite's indentation
+
+ g_currentMemberDef=0;
+ if (g_currentDefinition)
+ g_currentDefinition=g_currentDefinition->getOuterScope();
+ }
+ }
+
+ // Are there any remaining indentation levels for suites?
+ if (!g_indents.isEmpty())
+ {
+ BEGIN( Suite );
+ }
+ else
+ {
+ BEGIN( Body );
+ }
+}
+
+void parsePythonCode(CodeOutputInterface &od,const char * /*className*/,
+ const QCString &s,bool exBlock, const char *exName,
+ FileDef *fd,int startLine,int endLine,bool /*inlineFragment*/,
+ MemberDef *,bool,Definition *searchCtx,bool collectXRefs)
+{
+
+ //printf("***parseCode()\n");
+
+ //--------------------------------------
+ if (s.isEmpty()) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
+ TooltipManager::instance()->clearTooltips();
+ g_code = &od;
+ g_inputString = s;
+ g_inputPosition = 0;
+ g_currentFontClass = 0;
+ g_needsTermination = FALSE;
+ g_searchCtx=searchCtx;
+ g_collectXRefs=collectXRefs;
+ if (endLine!=-1)
+ g_inputLines = endLine+1;
+ else
+ g_inputLines = countLines();
+
+ if (startLine!=-1)
+ g_yyLineNr = startLine;
+ else
+ g_yyLineNr = 1;
+
+ g_exampleBlock = exBlock;
+ g_exampleName = exName;
+ g_sourceFileDef = fd;
+
+ bool cleanupSourceDef = FALSE;
+ if (fd==0)
+ {
+ // create a dummy filedef for the example
+ g_sourceFileDef = new FileDef("",(exName?exName:"generated"));
+ cleanupSourceDef = TRUE;
+ }
+ if (g_sourceFileDef)
+ {
+ setCurrentDoc("l00001");
+ }
+
+ // Starts line 1 on the output
+ startCodeLine();
+
+ pycodeYYrestart( pycodeYYin );
+
+ pycodeYYlex();
+
+ if (!g_indents.isEmpty())
+ {
+ // printf("Exited pysourceparser in inconsistent state!\n");
+ }
+
+ if (g_needsTermination)
+ {
+ endCodeLine();
+ }
+ if (fd)
+ {
+ TooltipManager::instance()->writeTooltips(*g_code);
+ }
+ if (cleanupSourceDef)
+ {
+ // delete the temporary file definition used for this example
+ delete g_sourceFileDef;
+ g_sourceFileDef=0;
+ }
+ printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
+ return;
+}
+
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void pycodeYYdummy() { yy_flex_realloc(0,0); }
+}
+#elif YY_FLEX_SUBMINOR_VERSION<33
+#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)."
+#endif
+
diff --git a/src/pyscanner.h b/src/pyscanner.h
new file mode 100644
index 0000000..e4e974f
--- /dev/null
+++ b/src/pyscanner.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/* This code is based on the work done by the MoxyPyDoxy team
+ * (Linda Leong, Mike Rivera, Kim Truong, and Gabriel Estrada)
+ * in Spring 2005 as part of CS 179E: Compiler Design Project
+ * at the University of California, Riverside; the course was
+ * taught by Peter H. Froehlich <phf at acm.org>.
+ */
+
+
+#ifndef PYSCANNER_H
+#define PYSCANNER_H
+
+#include "parserintf.h"
+
+/** \brief Python Language parser using state-based lexical scanning.
+ *
+ * This is the Python language parser for doxygen.
+ */
+class PythonLanguageScanner : public ParserInterface
+{
+ public:
+ virtual ~PythonLanguageScanner() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char * fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+ bool needsPreprocessing(const QCString &extension);
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXrefs=TRUE
+ );
+ void resetCodeParserState();
+ void parsePrototype(const char *text);
+};
+
+void pyscanFreeScanner();
+
+#endif
diff --git a/src/pyscanner.l b/src/pyscanner.l
new file mode 100644
index 0000000..c67875e
--- /dev/null
+++ b/src/pyscanner.l
@@ -0,0 +1,1744 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/* This code is based on the work done by the MoxyPyDoxy team
+ * (Linda Leong, Mike Rivera, Kim Truong, and Gabriel Estrada)
+ * in Spring 2005 as part of CS 179E: Compiler Design Project
+ * at the University of California, Riverside; the course was
+ * taught by Peter H. Froehlich <phf at acm.org>.
+ */
+
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <unistd.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
+#include "pyscanner.h"
+#include "entry.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "defargs.h"
+#include "language.h"
+#include "commentscan.h"
+#include "pycode.h"
+#include "arguments.h"
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+
+
+static ParserInterface *g_thisParser;
+static const char * inputString;
+static int inputPosition;
+static QFile inputFile;
+
+static Protection protection;
+
+static Entry* current_root = 0 ;
+static Entry* current = 0 ;
+static Entry* previous = 0 ;
+static Entry* bodyEntry = 0 ;
+static int yyLineNr = 1 ;
+static QCString yyFileName;
+static MethodTypes mtype;
+static bool gstat;
+static Specifier virt;
+
+static int docBlockContext;
+static QCString docBlock;
+static QCString docBlockName;
+static bool docBlockInBody;
+static bool docBlockJavaStyle;
+static bool docBrief;
+static bool docBlockSpecial;
+
+static bool g_doubleQuote;
+static bool g_specialBlock;
+static int g_stringContext;
+static QGString * g_copyString;
+static int g_indent = 0;
+static int g_curIndent = 0;
+
+static QDict<QCString> g_packageNameCache(257);
+static QCString g_packageScope;
+
+static char g_atomStart;
+static char g_atomEnd;
+static int g_atomCount;
+
+//static bool g_insideConstructor;
+
+static QCString g_moduleScope;
+static QCString g_packageName;
+
+//static bool g_hideClassDocs;
+
+static QCString g_defVal;
+static int g_braceCount;
+
+static bool g_lexInit = FALSE;
+static bool g_packageCommentAllowed;
+
+//-----------------------------------------------------------------------------
+
+
+static void initParser()
+{
+ protection = Public;
+ mtype = Method;
+ gstat = FALSE;
+ virt = Normal;
+ previous = 0;
+ g_packageCommentAllowed = TRUE;
+ g_packageNameCache.setAutoDelete(TRUE);
+}
+
+static void initEntry()
+{
+ //current->python = TRUE;
+ current->protection = protection ;
+ current->mtype = mtype;
+ current->virt = virt;
+ current->stat = gstat;
+ current->lang = SrcLangExt_Python;
+ current->setParent(current_root);
+ initGroupInfo(current);
+ gstat = FALSE;
+}
+
+static void newEntry()
+{
+ previous = current;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+}
+
+static void newVariable()
+{
+ if (!current->name.isEmpty() && current->name.at(0)=='_') // mark as private
+ {
+ current->protection=Private;
+ }
+ if (current_root->section&Entry::COMPOUND_MASK) // mark as class variable
+ {
+ current->stat = TRUE;
+ }
+ newEntry();
+}
+
+static void newFunction()
+{
+ if (current->name.left(2)=="__" && current->name.right(2)=="__")
+ {
+ // special method name, see
+ // http://docs.python.org/ref/specialnames.html
+ current->protection=Public;
+ }
+ else if (current->name.at(0)=='_')
+ {
+ current->protection=Private;
+ }
+}
+
+static inline int computeIndent(const char *s)
+{
+ int col=0;
+ static int tabSize=Config_getInt("TAB_SIZE");
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ if (c==' ') col++;
+ else if (c=='\t') col+=tabSize-(col%tabSize);
+ else break;
+ }
+ return col;
+}
+
+static QCString findPackageScopeFromPath(const QCString &path)
+{
+ QCString *pScope = g_packageNameCache.find(path);
+ if (pScope)
+ {
+ return *pScope;
+ }
+ QFileInfo pf(path+"/__init__.py"); // found package initialization file
+ if (pf.exists())
+ {
+ int i=path.findRev('/');
+ if (i!=-1)
+ {
+ QCString scope = findPackageScopeFromPath(path.left(i));
+ if (!scope.isEmpty())
+ {
+ scope+="::";
+ }
+ scope+=path.mid(i+1);
+ g_packageNameCache.insert(path,new QCString(scope));
+ return scope;
+ }
+ }
+ return "";
+}
+
+static QCString findPackageScope(const char *fileName)
+{
+ if (fileName==0) return "";
+ QFileInfo fi(fileName);
+ return findPackageScopeFromPath(fi.dirPath(TRUE).data());
+}
+
+//-----------------------------------------------------------------------------
+
+static void lineCount()
+{
+ DBG_CTX((stderr,"yyLineNr=%d\n",yyLineNr));
+ for (const char *p = yytext; *p; ++p)
+ {
+ yyLineNr += (*p == '\n') ;
+ }
+}
+
+static void incLineNr()
+{
+ DBG_CTX((stderr,"yyLineNr=%d\n",yyLineNr));
+ yyLineNr++;
+}
+
+#if 0
+// Appends the current-name to current-type;
+// Destroys current-name.
+// Destroys current->args and current->argList
+static void addType( Entry* current )
+{
+ uint tl=current->type.length();
+ if ( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.')
+ {
+ current->type += ' ' ;
+ }
+ current->type += current->name ;
+ current->name.resize(0) ;
+ tl=current->type.length();
+ if ( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.')
+ {
+ current->type += ' ' ;
+ }
+ current->type += current->args ;
+ current->args.resize(0) ;
+ current->argList->clear();
+}
+
+static QCString stripQuotes(const char *s)
+{
+ QCString name;
+ if (s==0 || *s==0) return name;
+ name=s;
+ if (name.at(0)=='"' && name.at(name.length()-1)=='"')
+ {
+ name=name.mid(1,name.length()-2);
+ }
+ return name;
+}
+#endif
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+static void startCommentBlock(bool brief)
+{
+ if (brief)
+ {
+ current->briefFile = yyFileName;
+ current->briefLine = yyLineNr;
+ }
+ else
+ {
+ current->docFile = yyFileName;
+ current->docLine = yyLineNr;
+ }
+}
+
+/*
+static void appendDocBlock() {
+ previous = current;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ initEntry();
+}
+*/
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+ //printf("handleCommentBlock(doc=[%s] brief=%d docBlockInBody=%d docBlockJavaStyle=%d\n",
+ // doc.data(),brief,docBlockInBody,docBlockJavaStyle);
+
+ // TODO: Fix me
+ docBlockInBody=FALSE;
+
+ if (docBlockInBody && previous && !previous->doc.isEmpty())
+ {
+ previous->doc=previous->doc.stripWhiteSpace()+"\n\n";
+ }
+
+ int position = 0;
+ bool needsEntry;
+ int lineNr = brief ? current->briefLine : current->docLine;
+ while (parseCommentBlock(
+ g_thisParser,
+ (docBlockInBody && previous) ? previous : current,
+ doc, // text
+ yyFileName, // file
+ lineNr,
+ docBlockInBody ? FALSE : brief,
+ docBlockJavaStyle, // javadoc style // or FALSE,
+ docBlockInBody,
+ protection,
+ position,
+ needsEntry)
+ ) // need to start a new entry
+ {
+ if (needsEntry)
+ {
+ newEntry();
+ }
+ }
+ if (needsEntry)
+ {
+ newEntry();
+ }
+
+}
+
+static void endOfDef(int correction=0)
+{
+ //printf("endOfDef at=%d\n",yyLineNr);
+ if (bodyEntry)
+ {
+ bodyEntry->endBodyLine = yyLineNr-correction;
+ bodyEntry = 0;
+ }
+ newEntry();
+ //g_insideConstructor = FALSE;
+}
+
+static inline void addToString(const char *s)
+{
+ if (g_copyString) (*g_copyString)+=s;
+}
+
+static void initTriDoubleQuoteBlock()
+{
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockJavaStyle = TRUE;
+ docBlockSpecial = yytext[3]=='!';
+ docBlock.resize(0);
+ g_doubleQuote = TRUE;
+ startCommentBlock(FALSE);
+}
+
+static void initTriSingleQuoteBlock()
+{
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockJavaStyle = TRUE;
+ docBlockSpecial = yytext[3]=='!';
+ docBlock.resize(0);
+ g_doubleQuote = FALSE;
+ startCommentBlock(FALSE);
+}
+
+static void initSpecialBlock()
+{
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockJavaStyle = TRUE;
+ docBrief = TRUE;
+ docBlock.resize(0);
+ startCommentBlock(TRUE);
+}
+
+static void searchFoundDef()
+{
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ current->section = Entry::FUNCTION_SEC;
+ current->protection = protection = Public;
+ current->lang = SrcLangExt_Python;
+ current->virt = Normal;
+ current->stat = gstat;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ g_packageCommentAllowed = FALSE;
+ gstat=FALSE;
+ //printf("searchFoundDef at=%d\n",yyLineNr);
+}
+
+static void searchFoundClass()
+{
+ current->section = Entry::CLASS_SEC;
+ current->argList->clear();
+ current->type += "class" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ g_packageCommentAllowed = FALSE;
+}
+
+//-----------------------------------------------------------------------------
+/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while ( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ //printf("%d (%c)\n",*buf,*buf);
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+ /* start command character */
+
+
+
+BB [ \t]+
+B [ \t]*
+NEWLINE \n
+BN [ \t\n]
+
+DIGIT [0-9]
+
+HEXNUMBER "0"[xX][0-9a-fA-F]+[lL]?
+OCTNUMBER "0"[0-7]+[lL]?
+NUMBER {DIGIT}+[lLjJ]?
+INTNUMBER {HEXNUMBER}|{OCTNUMBER}|{NUMBER}
+FLOATNUMBER {DIGIT}+"."{DIGIT}+([eE][+\-]?{DIGIT}+)?[jJ]?
+LETTER [A-Za-z\x80-\xFF]
+NONEMPTY [A-Za-z0-9_\x80-\xFF]
+EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-]
+NONEMPTYEXP [^ \t\n:]
+PARAMNONEMPTY [^ \t\n():]
+IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")*
+SCOPE {IDENTIFIER}("."{IDENTIFIER})*
+BORDER ([^A-Za-z0-9])
+
+TRISINGLEQUOTE "'''"(!)?
+TRIDOUBLEQUOTE "\"\"\""(!)?
+LONGSTRINGCHAR [^\\"']
+ESCAPESEQ ("\\")(.)
+LONGSTRINGITEM ({LONGSTRINGCHAR}|{ESCAPESEQ})
+SMALLQUOTE ("\"\""|"\""|"'"|"''")
+LONGSTRINGBLOCK ({LONGSTRINGITEM}+|{SMALLQUOTE})
+
+SHORTSTRING ("'"{SHORTSTRINGITEM}*"'"|'"'{SHORTSTRINGITEM}*'"')
+SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ})
+SHORTSTRINGCHAR [^\\\n"]
+STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING})
+STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR")
+KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False")
+FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally")
+POUNDCOMMENT "#"[^#\n][^\n]*
+
+STARTDOCSYMS "##"
+
+%option noyywrap
+
+ /* Main start state */
+
+%x Search
+%x SearchMemVars
+
+ /* Mid-comment states */
+
+ /* %x FuncDoubleComment */
+ /* %x ClassDoubleComment */
+%x TryClassDocString
+%x TripleComment
+%x SpecialComment
+
+ /* Function states */
+
+%x FunctionDec
+%x FunctionParams
+%x FunctionBody
+%x FunctionParamDefVal
+
+ /* Class states */
+
+%x ClassDec
+%x ClassInheritance
+%x ClassCaptureIndent
+%x ClassBody
+
+ /* Variable states */
+%x VariableDec
+%x VariableEnd
+%x VariableAtom
+
+ /* String states */
+
+%x SingleQuoteString
+%x DoubleQuoteString
+%x TripleString
+
+ /* import */
+%x FromMod
+%x FromModItem
+%x Import
+
+%%
+
+ /* ------------ Function recognition rules -------------- */
+
+<Search>{
+
+ ^{B}"def"{BB} { // start of a function/method definition with indent
+ DBG_CTX((stderr,"Found def at %d\n",yyLineNr));
+ g_indent=computeIndent(yytext);
+ searchFoundDef();
+ BEGIN( FunctionDec );
+ }
+ "def"{BB} { // start of a function/method definition
+ searchFoundDef();
+ BEGIN( FunctionDec );
+ }
+
+ ^{B}"class"{BB} { // start of a class definition with indent
+ DBG_CTX((stderr,"Found class at %d\n",yyLineNr));
+ g_indent=computeIndent(yytext);
+ searchFoundClass();
+ BEGIN( ClassDec ) ;
+ }
+ "class"{BB} { // start of a class definition
+ searchFoundClass();
+ BEGIN( ClassDec ) ;
+ }
+ ^{B}"from"{BB} |
+ "from"{BB} { // start of an from import
+ g_packageCommentAllowed = FALSE;
+ BEGIN( FromMod );
+ }
+
+ ^{B}"import"{BB} |
+ "import"{BB} { // start of an import statement
+ g_packageCommentAllowed = FALSE;
+ BEGIN( Import );
+ }
+ ^{B}{IDENTIFIER}/{B}"="{B}"property" { // property
+ current->section = Entry::VARIABLE_SEC;
+ current->mtype = Property;
+ current->name = QCString(yytext).stripWhiteSpace();
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ g_packageCommentAllowed = FALSE;
+ BEGIN(VariableDec);
+ }
+ ^{B}{IDENTIFIER}/{B}"="[^=] { // variable
+ g_indent=computeIndent(yytext);
+ current->section = Entry::VARIABLE_SEC;
+ current->name = QCString(yytext).stripWhiteSpace();
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ g_packageCommentAllowed = FALSE;
+ BEGIN(VariableDec);
+ }
+ "'" { // start of a single quoted string
+ g_stringContext=YY_START;
+ g_copyString=0;
+ g_packageCommentAllowed = FALSE;
+ BEGIN( SingleQuoteString );
+ }
+ "\"" { // start of a double quoted string
+ g_stringContext=YY_START;
+ g_copyString=0;
+ g_packageCommentAllowed = FALSE;
+ BEGIN( DoubleQuoteString );
+ }
+ "@staticmethod" {
+ gstat=TRUE;
+ }
+ {POUNDCOMMENT} { // normal comment
+ g_packageCommentAllowed = FALSE;
+ }
+ {IDENTIFIER} { // some other identifier
+ g_packageCommentAllowed = FALSE;
+ }
+ ^{BB} {
+ g_curIndent=computeIndent(yytext);
+ }
+
+ {NEWLINE}+ { // new line
+ lineCount();
+ }
+
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ initTriDoubleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ initTriSingleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {STARTDOCSYMS}/[^#] { // start of a special comment
+ g_curIndent=computeIndent(yytext);
+ g_packageCommentAllowed = FALSE;
+ initSpecialBlock();
+ BEGIN(SpecialComment);
+ }
+ [^\n] { // any other character...
+ // This is the major default
+ // that should catch everything
+ // else in Body.
+ }
+}
+
+<FromMod>{
+ "." { // python3 style imports
+ }
+ {IDENTIFIER}({B}"."{B}{IDENTIFIER})* { // from package import
+ g_packageName=yytext;
+ }
+ "import"{B} {
+ BEGIN(FromModItem);
+ }
+ \n {
+ incLineNr();
+ BEGIN(Search);
+ }
+ {B} {
+ }
+ . {
+ unput(*yytext);
+ BEGIN(Search);
+ }
+}
+
+<FromModItem>{
+ "*" { // import all
+ QCString item=g_packageName;
+ current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
+ current->fileName = yyFileName;
+ //printf("Adding using directive: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data());
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(Search);
+ }
+ {IDENTIFIER}/{B}","{B} {
+ QCString item=g_packageName+"."+yytext;
+ current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
+ current->fileName = yyFileName;
+ //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data());
+ current->section=Entry::USINGDECL_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ }
+ {IDENTIFIER} {
+ QCString item=g_packageName+"."+yytext;
+ current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
+ current->fileName = yyFileName;
+ //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data());
+ current->section=Entry::USINGDECL_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(Search);
+ }
+ \n {
+ incLineNr();
+ BEGIN(Search);
+ }
+ {B} {
+ }
+ "," {
+ }
+ . {
+ unput(*yytext);
+ BEGIN(Search);
+ }
+}
+
+<Import>{
+ {IDENTIFIER}({B}"."{B}{IDENTIFIER})* {
+ current->name=removeRedundantWhiteSpace(substitute(yytext,".","::"));
+ current->fileName = yyFileName;
+ //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data());
+ current->section=Entry::USINGDECL_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(Search);
+ }
+ \n {
+ incLineNr();
+ BEGIN(Search);
+ }
+ {B} {
+ }
+ . {
+ unput(*yytext);
+ BEGIN(Search);
+ }
+}
+
+<SearchMemVars>{
+ "self."{IDENTIFIER}/{B}"=" {
+ DBG_CTX((stderr,"Found member variable %s in %s at %d\n",&yytext[5],current_root->name.data(),yyLineNr));
+ current->name=&yytext[5];
+ current->section=Entry::VARIABLE_SEC;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ current->type.resize(0);
+ if (current->name.at(0)=='_') // mark as private
+ {
+ current->protection=Private;
+ }
+ else
+ {
+ current->protection=Public;
+ }
+ newEntry();
+ }
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ initTriDoubleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ initTriSingleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {STARTDOCSYMS}/[^#] { // start of a special comment
+ initSpecialBlock();
+ BEGIN(SpecialComment);
+ }
+ {POUNDCOMMENT} { // #
+ }
+ "'" { // start of a single quoted string
+ g_stringContext=YY_START;
+ g_copyString=0;
+ BEGIN( SingleQuoteString );
+ }
+ "\"" { // start of a double quoted string
+ g_stringContext=YY_START;
+ g_copyString=0;
+ BEGIN( DoubleQuoteString );
+ }
+ \n { incLineNr(); }
+ {IDENTIFIER} // identifiers
+ [^'"\.#a-z_A-Z\n]+ // other uninteresting stuff
+ . // anything else
+}
+
+<FunctionBody>{
+ \n{B}/{IDENTIFIER}{BB} {
+ DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),g_indent));
+ if (computeIndent(&yytext[1])<=g_indent)
+ {
+ int i;
+ for (i=(int)yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ endOfDef();
+ //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
+ BEGIN(Search);
+ }
+ else
+ {
+ incLineNr();
+ current->program+=yytext;
+ }
+ }
+ \n{B}/"##" {
+ if (computeIndent(&yytext[1])<=g_indent)
+ {
+ int i;
+ for (i=(int)yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ endOfDef();
+ //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
+ BEGIN(Search);
+ }
+ else
+ {
+ incLineNr();
+ current->program+=yytext;
+ }
+ }
+ <<EOF>> {
+ endOfDef();
+ yyterminate();
+ }
+ ^{BB}/\n { // skip empty line
+ current->program+=yytext;
+ }
+ ^{BB} { // something at indent >0
+ current->program+=yytext;
+ g_curIndent = computeIndent(yytext);
+ if (g_curIndent<=g_indent)
+ // jumped out of the function
+ {
+ endOfDef(1);
+ BEGIN(Search);
+ }
+ }
+ "'" { // start of a single quoted string
+ current->program+=yytext;
+ g_stringContext=YY_START;
+ g_specialBlock = FALSE;
+ g_copyString=¤t->program;
+ BEGIN( SingleQuoteString );
+ }
+ "\"" { // start of a double quoted string
+ current->program+=yytext;
+ g_stringContext=YY_START;
+ g_specialBlock = FALSE;
+ g_copyString=¤t->program;
+ BEGIN( DoubleQuoteString );
+ }
+ [^ \t\n#'".]+ { // non-special stuff
+ current->program+=yytext;
+ g_specialBlock = FALSE;
+ }
+ ^{POUNDCOMMENT} { // normal comment
+ current->program+=yytext;
+ }
+ "#".* { // comment half way
+ current->program+=yytext;
+ }
+ {NEWLINE} {
+ incLineNr();
+ current->program+=yytext;
+ }
+ . { // any character
+ current->program+=*yytext;
+ g_specialBlock = FALSE;
+ }
+
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ current->program+=yytext;
+ initTriDoubleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ current->program+=yytext;
+ initTriSingleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {STARTDOCSYMS}/[^#] { // start of a special comment
+ initSpecialBlock();
+ BEGIN(SpecialComment);
+ }
+
+}
+
+<FunctionDec>{
+
+ {IDENTIFIER} {
+ //found function name
+ if (current->type.isEmpty())
+ {
+ current->type = "def";
+ }
+ current->name = yytext;
+ current->name = current->name.stripWhiteSpace();
+ newFunction();
+ }
+ {B}":" { // function without arguments
+ g_specialBlock = TRUE; // expecting a docstring
+ bodyEntry = current;
+ current->bodyLine = yyLineNr;
+ BEGIN( FunctionBody );
+ }
+
+ {B}"(" {
+ BEGIN( FunctionParams );
+ }
+}
+
+<FunctionParams>{
+ ({BB}|",") {
+ }
+
+ {IDENTIFIER} { // Name of parameter
+ lineCount();
+ Argument *a = new Argument;
+ current->argList->append(a);
+ current->argList->getLast()->name = QCString(yytext).stripWhiteSpace();
+ current->argList->getLast()->type = "";
+ }
+ "=" { // default value
+ // TODO: this rule is too simple, need to be able to
+ // match things like =")" as well!
+ QCString defVal=&yytext[1];
+ g_defVal.resize(0);
+ g_braceCount=0;
+ BEGIN(FunctionParamDefVal);
+ }
+
+ ")" { // end of parameter list
+ }
+
+ ":"{B} {
+ g_specialBlock = TRUE; // expecting a docstring
+ bodyEntry = current;
+ current->bodyLine = yyLineNr;
+ BEGIN( FunctionBody );
+ }
+ {POUNDCOMMENT} { // a comment
+ }
+ {PARAMNONEMPTY} { // Default rule inside arguments.
+ }
+
+}
+
+<FunctionParamDefVal>{
+ "(" { // internal opening brace
+ g_braceCount++;
+ g_defVal+=*yytext;
+ }
+ "," |
+ ")" {
+ if (g_braceCount==0) // end of default argument
+ {
+ if (current->argList->getLast())
+ {
+ current->argList->getLast()->defval=g_defVal.stripWhiteSpace();
+ }
+ BEGIN(FunctionParams);
+ }
+ else // continue
+ {
+ g_braceCount--;
+ g_defVal+=*yytext;
+ }
+ }
+ . {
+ g_defVal+=*yytext;
+ }
+ \n {
+ g_defVal+=*yytext;
+ incLineNr();
+ }
+}
+
+
+<ClassBody>{
+ \n/{IDENTIFIER}{BB} { // new def at indent 0
+ incLineNr();
+ endOfDef();
+ //g_hideClassDocs = FALSE;
+ //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
+ BEGIN(Search);
+ }
+ \n/"##"[^#] { // start of a special comment at indent 0
+ incLineNr();
+ endOfDef();
+ //g_hideClassDocs = FALSE;
+ //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
+ BEGIN(Search);
+ }
+ ^{BB}/\n { // skip empty line
+ current->program+=yytext;
+ }
+ <<EOF>> {
+ endOfDef();
+ yyterminate();
+ }
+ ^{BB} { // something at indent >0
+ g_curIndent=computeIndent(yytext);
+ DBG_CTX((stderr,"g_curIndent=%d g_indent=%d\n",g_curIndent,g_indent));
+ if (g_curIndent<=g_indent)
+ // jumped out of the class/method
+ {
+ endOfDef(1);
+ g_indent=g_curIndent;
+ // make sure the next rule matches ^...
+ //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
+ //g_hideClassDocs = FALSE;
+ BEGIN(Search);
+ }
+ else
+ {
+ current->program+=yytext;
+ }
+ }
+ "'" { // start of a single quoted string
+ current->program+=*yytext;
+ g_stringContext=YY_START;
+ g_specialBlock = FALSE;
+ g_copyString=¤t->program;
+ BEGIN( SingleQuoteString );
+ }
+ "\"" { // start of a double quoted string
+ current->program+=*yytext;
+ g_stringContext=YY_START;
+ g_specialBlock = FALSE;
+ g_copyString=¤t->program;
+ BEGIN( DoubleQuoteString );
+ }
+ [^ \t\n#'"]+ { // non-special stuff
+ current->program+=yytext;
+ g_specialBlock = FALSE;
+ //g_hideClassDocs = FALSE;
+ }
+ {NEWLINE} {
+ current->program+=*yytext;
+ incLineNr();
+ }
+ {POUNDCOMMENT} { // normal comment
+ current->program+=yytext;
+ }
+ . { // any character
+ g_specialBlock = FALSE;
+ current->program+=*yytext;
+ }
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ //if (!g_hideClassDocs)
+ current->program+=yytext;
+ initTriDoubleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ //if (!g_hideClassDocs)
+ current->program+=yytext;
+ initTriSingleQuoteBlock();
+ BEGIN(TripleComment);
+ }
+}
+
+<ClassDec>{IDENTIFIER} {
+ if (current->type.isEmpty())
+ {
+ current->type = "class";
+ }
+
+ current->section = Entry::CLASS_SEC;
+ current->name = yytext;
+
+ // prepend scope in case of nested classes
+ if (current_root->section&Entry::SCOPE_MASK)
+ {
+ //printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data());
+ current->name.prepend(current_root->name+"::");
+ }
+
+ current->name = current->name.stripWhiteSpace();
+ current->fileName = yyFileName;
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockJavaStyle = FALSE;
+ docBlock.resize(0);
+
+ BEGIN(ClassInheritance);
+ }
+
+<ClassInheritance>{
+ ({BB}|[\(,\)]) { // syntactic sugar for the list
+ }
+
+ ":" { // begin of the class definition
+ g_specialBlock = TRUE; // expecting a docstring
+ current->bodyLine = yyLineNr;
+ current->program.resize(0);
+ BEGIN(ClassCaptureIndent);
+ }
+
+ {SCOPE} {
+ current->extends->append(
+ new BaseInfo(substitute(yytext,".","::"),Public,Normal)
+ );
+ //Has base class-do stuff
+ }
+}
+
+
+<ClassCaptureIndent>{
+ "\n"|({BB}"\n") {
+ // Blankline - ignore, keep looking for indentation.
+ lineCount();
+ current->program+=yytext;
+ }
+
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ initTriDoubleQuoteBlock();
+ current->program+=yytext;
+ BEGIN(TripleComment);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ initTriSingleQuoteBlock();
+ current->program+=yytext;
+ BEGIN(TripleComment);
+ }
+
+ ^{BB} {
+ current->program+=yytext;
+ //current->startLine = yyLineNr;
+ g_curIndent=computeIndent(yytext);
+ bodyEntry = current;
+ DBG_CTX((stderr,"setting indent %d\n",g_curIndent));
+ //printf("current->program=[%s]\n",current->program.data());
+ //g_hideClassDocs = TRUE;
+ BEGIN(ClassBody);
+ }
+
+ ""/({NONEMPTY}|{EXPCHAR}) {
+
+ // Just pushback an empty class, and
+ // resume parsing the body.
+ newEntry();
+ current->program+=yytext;
+
+ // printf("Failed to find indent - skipping!");
+ BEGIN( Search );
+ }
+}
+
+
+<VariableDec>{
+ "=" { // the assignment operator
+ //printf("====== VariableDec at line %d\n",yyLineNr);
+ current->initializer = yytext;
+ current->initializer += " ";
+ }
+ {B} { // spaces
+ }
+ {INTNUMBER} { // integer value
+ current->type = "int";
+ current->initializer += yytext;
+ BEGIN(VariableEnd);
+ }
+ {FLOATNUMBER} { // floating point value
+ current->type = "float";
+ current->initializer += yytext;
+ BEGIN(VariableEnd);
+ }
+ {STRINGPREFIX}?"'" { // string
+ current->type = "string";
+ current->initializer += yytext;
+ g_copyString=¤t->initializer;
+ g_stringContext=VariableEnd;
+ BEGIN( SingleQuoteString );
+ }
+ {STRINGPREFIX}?"\"" { // string
+ current->type = "string";
+ current->initializer += yytext;
+ g_copyString=¤t->initializer;
+ g_stringContext=VariableEnd;
+ BEGIN( DoubleQuoteString );
+ }
+ {TRIDOUBLEQUOTE} { // start of a comment block
+ current->type = "string";
+ current->initializer += yytext;
+ g_doubleQuote=TRUE;
+ g_copyString=¤t->initializer;
+ g_stringContext=VariableEnd;
+ BEGIN(TripleString);
+ }
+
+ {TRISINGLEQUOTE} { // start of a comment block
+ current->type = "string";
+ current->initializer += yytext;
+ g_doubleQuote=FALSE;
+ g_copyString=¤t->initializer;
+ g_stringContext=VariableEnd;
+ BEGIN(TripleString);
+ }
+ "(" { // tuple
+ if (current->mtype!=Property)
+ {
+ current->type = "tuple";
+ }
+ current->initializer+=*yytext;
+ g_atomStart='(';
+ g_atomEnd=')';
+ g_atomCount=1;
+ BEGIN( VariableAtom );
+ }
+ "[" { // list
+ current->type = "list";
+ current->initializer+=*yytext;
+ g_atomStart='[';
+ g_atomEnd=']';
+ g_atomCount=1;
+ BEGIN( VariableAtom );
+ }
+ "{" { // dictionary
+ current->type = "dictionary";
+ current->initializer+=*yytext;
+ g_atomStart='{';
+ g_atomEnd='}';
+ g_atomCount=1;
+ BEGIN( VariableAtom );
+ }
+ "#".* { // comment
+ BEGIN( VariableEnd );
+ }
+ {IDENTIFIER} {
+ current->initializer+=yytext;
+ }
+ . {
+ current->initializer+=*yytext;
+ }
+ \n {
+ unput('\n');
+ BEGIN( VariableEnd );
+ }
+}
+
+<VariableAtom>{
+ [\(\[\{] {
+ current->initializer+=*yytext;
+ if (g_atomStart==*yytext)
+ {
+ g_atomCount++;
+ }
+ }
+ [\)\]\}] {
+ current->initializer+=*yytext;
+ if (g_atomEnd==*yytext)
+ {
+ g_atomCount--;
+ }
+ if (g_atomCount==0)
+ {
+ BEGIN(VariableEnd);
+ }
+ }
+ "\"" {
+ g_stringContext=YY_START;
+ current->initializer+="\"";
+ g_copyString=¤t->initializer;
+ BEGIN( DoubleQuoteString );
+ }
+ {IDENTIFIER} {
+ current->initializer+=yytext;
+ }
+ . {
+ current->initializer+=*yytext;
+ }
+ \n {
+ current->initializer+=*yytext;
+ incLineNr();
+ }
+
+}
+
+<VariableEnd>{
+ \n {
+ incLineNr();
+ newVariable();
+ BEGIN(Search);
+ }
+ . {
+ unput(*yytext);
+ newVariable();
+ BEGIN(Search);
+ }
+ <<EOF>> { yyterminate();
+ newEntry();
+ }
+}
+
+<TripleComment>{
+ {TRIDOUBLEQUOTE} |
+ {TRISINGLEQUOTE} {
+ // printf("Expected module block %d special=%d\n",g_expectModuleDocs,g_specialBlock);
+ if (g_doubleQuote==(yytext[0]=='"'))
+ {
+ if (g_specialBlock) // expecting a docstring
+ {
+ QCString actualDoc=docBlock;
+ if (!docBlockSpecial) // legacy unformatted docstring
+ {
+ actualDoc.prepend("\\verbatim ");
+ actualDoc.append("\\endverbatim ");
+ }
+ //printf("-------> current=%p bodyEntry=%p\n",current,bodyEntry);
+ handleCommentBlock(actualDoc, FALSE);
+ }
+ else if (g_packageCommentAllowed) // expecting module docs
+ {
+ QCString actualDoc=docBlock;
+ if (!docBlockSpecial) // legacy unformatted docstring
+ {
+ actualDoc.prepend("\\verbatim ");
+ actualDoc.append("\\endverbatim ");
+ }
+ actualDoc.prepend("\\namespace "+g_moduleScope+"\\_linebr ");
+ handleCommentBlock(actualDoc, FALSE);
+ }
+ if ((docBlockContext==ClassBody /*&& !g_hideClassDocs*/) ||
+ docBlockContext==FunctionBody)
+ {
+ current->program+=docBlock;
+ current->program+=yytext;
+ }
+ //if (g_hideClassDocs)
+ //{
+ // current->startLine = yyLineNr;
+ //}
+ //g_hideClassDocs=FALSE;
+ BEGIN(docBlockContext);
+ }
+ else
+ {
+ docBlock += yytext;
+ }
+ g_packageCommentAllowed = FALSE;
+ }
+
+
+ ^{BB} { // leading whitespace
+ int indent = computeIndent(yytext);
+ if (indent>=g_curIndent)
+ { // strip g_curIndent amount of whitespace
+ int i;
+ for (i=0;i<indent-g_curIndent;i++) docBlock+=' ';
+ DBG_CTX((stderr,"stripping indent %d\n",g_curIndent));
+ }
+ else
+ {
+ DBG_CTX((stderr,"not stripping: %d<%d\n",indent,g_curIndent));
+ docBlock += yytext;
+ }
+ }
+ [^"'\n \t]+ {
+ docBlock += yytext;
+ }
+ \n {
+ incLineNr();
+ docBlock += yytext;
+ }
+ . {
+ docBlock += yytext;
+ }
+}
+
+<SpecialComment>{
+ ^{B}"#"("#")* { // skip leading hashes
+ }
+ \n/{B}"#" { // continuation of the comment on the next line
+ docBlock+='\n';
+ docBrief = FALSE;
+ startCommentBlock(FALSE);
+ incLineNr();
+ }
+ [^#\n]+ { // any other stuff
+ docBlock+=yytext;
+ }
+ \n { // new line that ends the comment
+ handleCommentBlock(docBlock, docBrief);
+ incLineNr();
+ BEGIN(docBlockContext);
+ }
+ . { // anything we missed
+ docBlock+=*yytext;
+ }
+}
+
+<SingleQuoteString>{
+ \\{B}\n { // line continuation
+ addToString(yytext);
+ incLineNr();
+ }
+ \\. { // espaced char
+ addToString(yytext);
+ }
+ "\"\"\"" { // tripple double quotes
+ addToString(yytext);
+ }
+ "'" { // end of the string
+ addToString(yytext);
+ BEGIN(g_stringContext);
+ }
+ [^"'\n\\]+ { // normal chars
+ addToString(yytext);
+ }
+ . { // normal char
+ addToString(yytext);
+ }
+}
+
+<DoubleQuoteString>{
+ \\{B}\n { // line continuation
+ addToString(yytext);
+ incLineNr();
+ }
+ \\. { // espaced char
+ addToString(yytext);
+ }
+ "'''" { // tripple single quotes
+ addToString(yytext);
+ }
+ "\"" { // end of the string
+ addToString(yytext);
+ BEGIN(g_stringContext);
+ }
+ [^"'\n\\]+ { // normal chars
+ addToString(yytext);
+ }
+ . { // normal char
+ addToString(yytext);
+ }
+}
+
+<TripleString>{
+ {TRIDOUBLEQUOTE} |
+ {TRISINGLEQUOTE} {
+ *g_copyString += yytext;
+ if (g_doubleQuote==(yytext[0]=='"'))
+ {
+ BEGIN(g_stringContext);
+ }
+ }
+
+
+ ({LONGSTRINGBLOCK}) {
+ lineCount();
+ *g_copyString += yytext;
+ }
+ \n {
+ incLineNr();
+ *g_copyString += yytext;
+ }
+ . {
+ *g_copyString += *yytext;
+ }
+}
+
+ /* ------------ End rules -------------- */
+
+ /*
+<*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time.
+ // printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
+ // yytext, YY_START, yyLineNr);
+
+ }
+ */
+
+<*>{NEWLINE} {
+ //printf("[pyscanner] %d NEWLINE [line %d] no match\n",
+ // YY_START, yyLineNr);
+
+ lineCount();
+ }
+
+<*>. {
+ //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
+ // yytext, YY_START, yyLineNr);
+
+ }
+
+
+%%
+
+//----------------------------------------------------------------------------
+
+static void parseCompounds(Entry *rt)
+{
+ //printf("parseCompounds(%s)\n",rt->name.data());
+ EntryListIterator eli(*rt->children());
+ Entry *ce;
+ for (;(ce=eli.current());++eli)
+ {
+ if (!ce->program.isEmpty())
+ {
+ //printf("-- %s ---------\n%s\n---------------\n",
+ // ce->name.data(),ce->program.data());
+ // init scanner state
+ inputString = ce->program;
+ inputPosition = 0;
+ pyscannerYYrestart( pyscannerYYin ) ;
+ if (ce->section&Entry::COMPOUND_MASK)
+ {
+ current_root = ce ;
+ BEGIN( Search );
+ }
+ else if (ce->parent())
+ {
+ current_root = ce->parent();
+ //printf("Searching for member variables in %s parent=%s\n",
+ // ce->name.data(),ce->parent->name.data());
+ BEGIN( SearchMemVars );
+ }
+ yyFileName = ce->fileName;
+ yyLineNr = ce->bodyLine ;
+ if (current) delete current;
+ current = new Entry;
+ initEntry();
+
+ groupEnterCompound(yyFileName,yyLineNr,ce->name);
+
+ pyscannerYYlex() ;
+ g_lexInit=TRUE;
+ delete current; current=0;
+ ce->program.resize(0);
+
+ groupLeaveCompound(yyFileName,yyLineNr,ce->name);
+
+ }
+ parseCompounds(ce);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+
+static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
+{
+ initParser();
+
+ inputString = fileBuf;
+ inputPosition = 0;
+
+ protection = Public;
+ mtype = Method;
+ gstat = FALSE;
+ virt = Normal;
+ current_root = rt;
+ g_specialBlock = FALSE;
+
+
+ inputFile.setName(fileName);
+ if (inputFile.open(IO_ReadOnly))
+ {
+ yyLineNr= 1 ;
+ yyFileName = fileName;
+ //setContext();
+ msg("Parsing file %s...\n",yyFileName.data());
+
+ QFileInfo fi(fileName);
+ g_moduleScope = findPackageScope(fileName);
+ QCString baseName=fi.baseName().utf8();
+ if (baseName!="__init__") // package initializer file is not a package itself
+ {
+ if (!g_moduleScope.isEmpty())
+ {
+ g_moduleScope+="::";
+ }
+ g_moduleScope+=baseName;
+ }
+
+ current = new Entry;
+ initEntry();
+ current->name = g_moduleScope;
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "namespace";
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+
+ rt->addSubEntry(current);
+
+ current_root = current ;
+ initParser();
+ current = new Entry;
+
+ groupEnterFile(yyFileName,yyLineNr);
+
+ current->reset();
+ initEntry();
+ pyscannerYYrestart( pyscannerYYin );
+ BEGIN( Search );
+ pyscannerYYlex();
+ g_lexInit=TRUE;
+
+ groupLeaveFile(yyFileName,yyLineNr);
+
+ current_root->program.resize(0);
+ delete current; current=0;
+
+ parseCompounds(current_root);
+
+ inputFile.close();
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+static void parsePrototype(const QCString &text)
+{
+ //printf("**** parsePrototype(%s) begin\n",text.data());
+ if (text.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Empty prototype found!");
+ return;
+ }
+
+ g_specialBlock = FALSE;
+ g_packageCommentAllowed = FALSE;
+
+ const char *orgInputString;
+ int orgInputPosition;
+ YY_BUFFER_STATE orgState;
+
+ // save scanner state
+ orgState = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(pyscannerYYin, YY_BUF_SIZE));
+ orgInputString = inputString;
+ orgInputPosition = inputPosition;
+
+ // set new string
+ inputString = text;
+ inputPosition = 0;
+ pyscannerYYrestart( pyscannerYYin );
+
+ BEGIN( FunctionDec );
+
+ pyscannerYYlex();
+ g_lexInit=TRUE;
+
+ current->name = current->name.stripWhiteSpace();
+ if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty())
+ current->section = Entry::VARIABLEDOC_SEC;
+
+ // restore original scanner state
+
+ YY_BUFFER_STATE tmpBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(orgState);
+ yy_delete_buffer(tmpBuf);
+
+ inputString = orgInputString;
+ inputPosition = orgInputPosition;
+
+ //printf("**** parsePrototype end\n");
+}
+
+void pyscanFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+ if (g_lexInit)
+ {
+ pyscannerYYlex_destroy();
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+
+void PythonLanguageScanner::parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool /*sameTranslationUnit*/,
+ QStrList & /*filesInSameTranslationUnit*/)
+{
+ g_thisParser = this;
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+ ::parseMain(fileName,fileBuf,root);
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+
+ // May print the AST for debugging purposes
+ // printAST(global_root);
+}
+
+bool PythonLanguageScanner::needsPreprocessing(const QCString &)
+{
+ return FALSE;
+}
+
+void PythonLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt /*lang*/,
+ bool isExampleBlock,
+ const char *exampleName,
+ FileDef *fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ ::parsePythonCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
+ fileDef,startLine,endLine,inlineFragment,memberDef,
+ showLineNumbers,searchCtx,collectXRefs);
+}
+
+void PythonLanguageScanner::parsePrototype(const char *text)
+{
+ ::parsePrototype(text);
+
+}
+
+void PythonLanguageScanner::resetCodeParserState()
+{
+ ::resetPythonCodeParserState();
+}
+
+//----------------------------------------------------------------------------
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void pyscannerYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/qhp.cpp b/src/qhp.cpp
new file mode 100644
index 0000000..9e6cc5d
--- /dev/null
+++ b/src/qhp.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2008 by Sebastian Pipping.
+ * Copyright (C) 2008 Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Sebastian Pipping <sebastian at pipping.org>
+ */
+
+#include "qhp.h"
+#include "qhpxmlwriter.h"
+#include "message.h"
+#include "config.h"
+#include "memberdef.h"
+#include "groupdef.h"
+#include "doxygen.h"
+#include "filedef.h"
+
+#include <qstringlist.h>
+#include <string.h>
+#include <qfile.h>
+
+static QCString makeFileName(const char * withoutExtension)
+{
+ QCString result=withoutExtension;
+ if (!result.isEmpty())
+ {
+ if (result.at(0)=='!') // relative URL -> strip marker
+ {
+ result=result.mid(1);
+ }
+ else // add specified HTML extension
+ {
+ result+=Doxygen::htmlFileExtension;
+ }
+ }
+ return result;
+}
+
+static QCString makeRef(const char * withoutExtension, const char * anchor)
+{
+ //printf("QHP::makeRef(%s,%s)\n",withoutExtension,anchor);
+ if (!withoutExtension) return QCString();
+ QCString result = makeFileName(withoutExtension);
+ if (!anchor) return result;
+ return result+"#"+anchor;
+}
+
+Qhp::Qhp() : m_prevSectionLevel(0), m_sectionLevel(0)
+{
+ m_doc.setIndentLevel(0);
+ m_toc.setIndentLevel(2);
+ m_index.setIndentLevel(2);
+ m_files.setIndentLevel(2);
+}
+
+Qhp::~Qhp()
+{
+ clearPrevSection();
+}
+
+void Qhp::initialize()
+{
+ /*
+ <QtHelpProject version="1.0">
+ <namespace>mycompany.com.myapplication.1_0</namespace>
+ <virtualFolder>doc</virtualFolder>
+ <customFilter name="My Application 1.0">
+ <filterAttribute>myapp</filterAttribute>
+ <filterAttribute>1.0</filterAttribute>
+ </customFilter>
+ <filterSection>
+ <filterAttribute>myapp</filterAttribute>
+ <filterAttribute>1.0</filterAttribute>
+ ..
+ */
+ QCString nameSpace = Config_getString("QHP_NAMESPACE");
+ QCString virtualFolder = Config_getString("QHP_VIRTUAL_FOLDER");
+
+ m_doc.declaration("1.0", "UTF-8");
+
+ const char * rootAttributes[] =
+ { "version", "1.0", 0 };
+
+ m_doc.open("QtHelpProject", rootAttributes);
+ m_doc.openCloseContent("namespace", nameSpace);
+ m_doc.openCloseContent("virtualFolder", virtualFolder);
+
+ // Add custom filter
+ QCString filterName = Config_getString("QHP_CUST_FILTER_NAME");
+ if (!filterName.isEmpty())
+ {
+ const char * tagAttributes[] =
+ { "name", filterName, 0 };
+ m_doc.open("customFilter", tagAttributes);
+
+ QStringList customFilterAttributes = QStringList::split(QChar(' '), Config_getString("QHP_CUST_FILTER_ATTRS"));
+ for (int i = 0; i < (int)customFilterAttributes.count(); i++)
+ {
+ m_doc.openCloseContent("filterAttribute", customFilterAttributes[i].utf8());
+ }
+ m_doc.close("customFilter");
+ }
+
+ m_doc.open("filterSection");
+
+ // Add section attributes
+ QStringList sectionFilterAttributes = QStringList::split(QChar(' '),
+ Config_getString("QHP_SECT_FILTER_ATTRS"));
+ if (!sectionFilterAttributes.contains(QString("doxygen")))
+ {
+ sectionFilterAttributes << "doxygen";
+ }
+ for (int i = 0; i < (int)sectionFilterAttributes.count(); i++)
+ {
+ m_doc.openCloseContent("filterAttribute", sectionFilterAttributes[i].utf8());
+ }
+
+ m_toc.open("toc");
+
+ // Add extra root node
+ QCString fullProjectname = getFullProjectName();
+ QCString indexFile = "index"+Doxygen::htmlFileExtension;
+ const char * const attributes[] =
+ { "title", fullProjectname,
+ "ref", indexFile,
+ NULL
+ };
+ m_toc.open("section", attributes);
+ m_prevSectionTitle = getFullProjectName();
+ m_prevSectionLevel = 1;
+ m_sectionLevel = 1;
+
+ m_index.open("keywords");
+ m_files.open("files");
+}
+
+void Qhp::finalize()
+{
+ // Finish TOC
+ handlePrevSection();
+ for (int i = m_prevSectionLevel; i > 0; i--)
+ {
+ m_toc.close("section");
+ }
+ m_toc.close("toc");
+ m_doc.insert(m_toc);
+
+ // Finish index
+ m_index.close("keywords");
+ m_doc.insert(m_index);
+
+ // Finish files
+ m_files.close("files");
+ m_doc.insert(m_files);
+
+ m_doc.close("filterSection");
+ m_doc.close("QtHelpProject");
+
+ QCString fileName = Config_getString("HTML_OUTPUT") + "/" + getQhpFileName();
+ QFile file(fileName);
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n", fileName.data());
+ exit(1);
+ }
+ m_doc.dumpTo(file);
+}
+
+void Qhp::incContentsDepth()
+{
+ m_sectionLevel++;
+ //printf("Qhp::incContentsDepth() %d->%d\n",m_sectionLevel-1,m_sectionLevel);
+}
+
+void Qhp::decContentsDepth()
+{
+ //printf("Qhp::decContentsDepth() %d->%d\n",m_sectionLevel,m_sectionLevel-1);
+ if (m_sectionLevel <= 0)
+ {
+ return;
+ }
+ m_sectionLevel--;
+}
+
+void Qhp::addContentsItem(bool /*isDir*/, const char * name,
+ const char * /*ref*/, const char * file,
+ const char *anchor, bool /* separateIndex */,
+ bool /* addToNavIndex */,
+ Definition * /*def*/)
+{
+ //printf("Qhp::addContentsItem(%s) %d\n",name,m_sectionLevel);
+ // Backup difference before modification
+
+ QCString f = file;
+ if (!f.isEmpty() && f.at(0)=='^') return; // absolute URL not supported
+
+ int diff = m_prevSectionLevel - m_sectionLevel;
+
+ handlePrevSection();
+ setPrevSection(name, f, anchor, m_sectionLevel);
+
+ // Close sections as needed
+ for (; diff > 0; diff--)
+ {
+ m_toc.close("section");
+ }
+}
+
+void Qhp::addIndexItem(Definition *context,MemberDef *md,
+ const char *sectionAnchor,const char *word)
+{
+ (void)word;
+ //printf("addIndexItem(%s %s %s\n",
+ // context?context->name().data():"<none>",
+ // md?md->name().data():"<none>",
+ // word);
+
+ if (md) // member
+ {
+ static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ if (context==0) // global member
+ {
+ if (md->getGroupDef())
+ context = md->getGroupDef();
+ else if (md->getFileDef())
+ context = md->getFileDef();
+ }
+ if (context==0) return; // should not happen
+ QCString cfname = md->getOutputFileBase();
+ QCString cfiname = context->getOutputFileBase();
+ QCString level1 = context->name();
+ QCString level2 = word ? QCString(word) : md->name();
+ QCString contRef = separateMemberPages ? cfname : cfiname;
+ QCString anchor = sectionAnchor ? QCString(sectionAnchor) : md->anchor();
+
+ QCString ref;
+
+ // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/>
+ ref = makeRef(contRef, anchor);
+ QCString id = level1+"::"+level2;
+ const char * attributes[] =
+ {
+ "name", level2,
+ "id", id,
+ "ref", ref,
+ 0
+ };
+ m_index.openClose("keyword", attributes);
+ }
+ else if (context) // container
+ {
+ // <keyword name="Foo" id="Foo" ref="doc.html#Foo"/>
+ QCString contRef = context->getOutputFileBase();
+ QCString level1 = word ? QCString(word) : context->name();
+ QCString ref = makeRef(contRef,sectionAnchor);
+ const char * attributes[] =
+ {
+ "name", level1,
+ "id", level1,
+ "ref", ref,
+ 0
+ };
+ m_index.openClose("keyword", attributes);
+ }
+}
+
+void Qhp::addIndexFile(const char * name)
+{
+ addFile(name);
+}
+
+QCString Qhp::getQhpFileName()
+{
+ return "index.qhp";
+}
+
+QCString Qhp::getFullProjectName()
+{
+ QCString projectName = Config_getString("PROJECT_NAME");
+ QCString versionText = Config_getString("PROJECT_NUMBER");
+ if (projectName.isEmpty()) projectName="Root";
+ return projectName + (versionText.isEmpty()
+ ? QCString("")
+ : QCString(" ") + versionText);
+}
+
+void Qhp::handlePrevSection()
+{
+ /*
+ <toc>
+ <section title="My Application Manual" ref="index.html">
+ <section title="Chapter 1" ref="doc.html#chapter1"/>
+ <section title="Chapter 2" ref="doc.html#chapter2"/>
+ <section title="Chapter 3" ref="doc.html#chapter3"/>
+ </section>
+ </toc>
+ */
+
+ if (m_prevSectionTitle.isNull())
+ {
+ m_prevSectionTitle=" "; // should not happen...
+ }
+
+ // We skip "Main Page" as our extra root is pointing to that
+ if (!((m_prevSectionLevel==1) && (m_prevSectionTitle==getFullProjectName())))
+ {
+ QCString finalRef = makeRef(m_prevSectionBaseName, m_prevSectionAnchor);
+
+ const char * const attributes[] =
+ { "title", m_prevSectionTitle,
+ "ref", finalRef,
+ NULL
+ };
+
+ if (m_prevSectionLevel < m_sectionLevel)
+ {
+ // Section with children
+ m_toc.open("section", attributes);
+ }
+ else
+ {
+ // Section without children
+ m_toc.openClose("section", attributes);
+ }
+ }
+
+ clearPrevSection();
+}
+
+void Qhp::setPrevSection(const char * title, const char * basename, const char * anchor, int level)
+{
+ m_prevSectionTitle = title;
+ m_prevSectionBaseName = basename;
+ m_prevSectionAnchor = anchor;
+ m_prevSectionLevel = level;
+}
+
+void Qhp::clearPrevSection()
+{
+ m_prevSectionTitle.resize(0);
+ m_prevSectionBaseName.resize(0);
+ m_prevSectionAnchor.resize(0);
+}
+
+void Qhp::addFile(const char * fileName)
+{
+ m_files.openCloseContent("file", fileName);
+}
+
+void Qhp::addImageFile(const char *fileName)
+{
+ addFile(fileName);
+}
+
+void Qhp::addStyleSheetFile(const char *fileName)
+{
+ addFile(fileName);
+}
+
diff --git a/src/qhp.h b/src/qhp.h
new file mode 100644
index 0000000..a428ac4
--- /dev/null
+++ b/src/qhp.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 by Sebastian Pipping.
+ * Copyright (C) 2008 Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Sebastian Pipping <sebastian at pipping.org>
+ */
+
+#ifndef DOXYGEN_QHP_H
+#define DOXYGEN_QHP_H
+
+#include "index.h"
+#include "qhpxmlwriter.h"
+
+class Qhp : public IndexIntf
+{
+ public:
+ Qhp();
+ ~Qhp();
+
+ // BEGIN IndexIntf
+ void initialize();
+ void finalize();
+ void incContentsDepth();
+ void decContentsDepth();
+ void addContentsItem(bool isDir, const char * name, const char * ref,
+ const char * file, const char * anchor,
+ bool separateIndex,bool addToNavIndex,
+ Definition *def);
+ void addIndexItem(Definition *context, MemberDef *md,
+ const char *sectionAnchor, const char *title);
+ void addIndexFile(const char * name);
+ void addImageFile(const char * name);
+ void addStyleSheetFile(const char * name);
+ // END IndexIntf
+
+ static QCString getQhpFileName();
+
+ private:
+ void handlePrevSection();
+ void clearPrevSection();
+ void setPrevSection(const char * title, const char * basename, const char * anchor, int level);
+ void addFile(const char * fileName);
+
+ static QCString getFullProjectName();
+
+ QhpXmlWriter m_doc;
+ QhpXmlWriter m_toc;
+ QhpXmlWriter m_index;
+ QhpXmlWriter m_files;
+
+ QCString m_prevSectionTitle;
+ QCString m_prevSectionBaseName;
+ QCString m_prevSectionAnchor;
+
+ int m_prevSectionLevel;
+ int m_sectionLevel;
+
+ //QCString m_prevIdName;
+ //QCString m_prevIdRef;
+};
+
+#endif // DOXYGEN_QHP_H
+
diff --git a/src/qhpxmlwriter.cpp b/src/qhpxmlwriter.cpp
new file mode 100644
index 0000000..edf9ae0
--- /dev/null
+++ b/src/qhpxmlwriter.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2008 by Sebastian Pipping.
+ * Copyright (C) 2008 Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Sebastian Pipping <sebastian at pipping.org>
+ */
+
+#include "qhpxmlwriter.h"
+#include "util.h"
+
+#include <qfile.h>
+
+QhpXmlWriter::QhpXmlWriter()
+ : m_out(&m_backend), m_indentLevel(0),
+ m_curLineIndented(false), m_compress(false)
+{
+}
+
+QhpXmlWriter::~QhpXmlWriter()
+{
+}
+
+void QhpXmlWriter::setIndentLevel(int level)
+{
+ m_indentLevel = level;
+}
+
+void QhpXmlWriter::setCompressionEnabled(bool enabled)
+{
+ m_compress = enabled;
+}
+
+void QhpXmlWriter::insert(QhpXmlWriter const & source)
+{
+ m_out << source.m_backend.data();
+}
+
+void QhpXmlWriter::dumpTo(QFile & file)
+{
+ file.writeBlock(m_backend.data(), m_backend.length());
+}
+
+void QhpXmlWriter::open(char const * elementName,
+ char const * const * attributes)
+{
+ indent();
+ openPure(elementName, attributes);
+ newLine();
+ m_indentLevel++;
+}
+
+void QhpXmlWriter::openClose(char const * elementName,
+ char const * const * attributes)
+{
+ indent();
+ openClosePure(elementName, attributes);
+ newLine();
+}
+
+void QhpXmlWriter::openCloseContent(char const * elementName,
+ char const * content)
+{
+ indent();
+ openPure(elementName);
+ m_out << convertToXML(content);
+ closePure(elementName);
+ newLine();
+}
+
+void QhpXmlWriter::close(char const * elementName)
+{
+ m_indentLevel--;
+ indent();
+ closePure(elementName);
+ newLine();
+}
+
+void QhpXmlWriter::declaration(char const * version, char const * encoding)
+{
+ m_out << "<?xml version=\"" << version << "\" encoding=\"" << encoding << "\"?>";
+ newLine();
+}
+
+void QhpXmlWriter::indent()
+{
+ if (m_curLineIndented)
+ {
+ return;
+ }
+ for (int i = 0; i < m_indentLevel; i++)
+ {
+ m_out << " ";
+ }
+ m_curLineIndented = true;
+}
+
+void QhpXmlWriter::newLine()
+{
+ if (!m_compress)
+ {
+ m_out << "\n";
+ m_curLineIndented = false;
+ }
+}
+
+void QhpXmlWriter::openPureHelper(char const * elementName,
+ char const * const * attributes, bool close)
+{
+ m_out << "<" << elementName;
+ if (attributes)
+ {
+ for (char const * const * walker = attributes;
+ walker[0]; walker += 2)
+ {
+ char const * const key = walker[0];
+ char const * const value = walker[1];
+ if (!value)
+ {
+ continue;
+ }
+ m_out << " " << key << "=\"" << convertToXML(value) << "\"";
+ }
+ }
+
+ if (close)
+ {
+ m_out << " /";
+ }
+ m_out << ">";
+}
+
+void QhpXmlWriter::openPure(char const * elementName,
+ char const * const * attributes)
+{
+ openPureHelper(elementName, attributes, false);
+}
+
+void QhpXmlWriter::openClosePure(char const * elementName,
+ char const * const * attributes)
+{
+ openPureHelper(elementName, attributes, true);
+}
+
+void QhpXmlWriter::closePure(char const * elementName)
+{
+ m_out << "</" << elementName << ">";
+}
+
diff --git a/src/qhpxmlwriter.h b/src/qhpxmlwriter.h
new file mode 100644
index 0000000..f75414b
--- /dev/null
+++ b/src/qhpxmlwriter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 by Sebastian Pipping.
+ * Copyright (C) 2008 Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Sebastian Pipping <sebastian at pipping.org>
+ */
+
+#ifndef QHPXMLWRITER_H
+#define QHPXMLWRITER_H
+
+#include <qstring.h>
+#include "ftextstream.h"
+
+class QFile;
+
+class QhpXmlWriter
+{
+ public:
+ QhpXmlWriter();
+ ~QhpXmlWriter();
+
+ void setIndentLevel(int level);
+ void setCompressionEnabled(bool enabled);
+ void insert(QhpXmlWriter const & source);
+ void dumpTo(QFile & file);
+ void open(char const * elementName,
+ char const * const * attributes = 0);
+ void openClose(char const * elementName,
+ char const * const * attributes = 0);
+ void openCloseContent(char const * elementName, char const * content);
+ void close(char const * elementName);
+ void declaration(char const * version, char const * encoding);
+
+ static char * dupEscaped(const char * source);
+
+ private:
+ void indent();
+ void newLine();
+ void openPureHelper(char const * elementName,
+ char const * const * attributes, bool close);
+ void openPure(char const * elementName,
+ char const * const * attributes = 0);
+ void openClosePure(char const * elementName,
+ char const * const * attributes = 0);
+ void closePure(char const * elementName);
+
+ QGString m_backend;
+ FTextStream m_out;
+ int m_indentLevel;
+ bool m_curLineIndented;
+ bool m_compress;
+
+};
+
+#endif // QHPXMLWRITER_H
diff --git a/src/qtbc.h b/src/qtbc.h
new file mode 100644
index 0000000..c9ff3ca
--- /dev/null
+++ b/src/qtbc.h
@@ -0,0 +1,21 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef QTBC_H
+#define QTBC_H
+
+#endif
diff --git a/src/reflist.cpp b/src/reflist.cpp
new file mode 100644
index 0000000..ee6ac91
--- /dev/null
+++ b/src/reflist.cpp
@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include "reflist.h"
+#include "util.h"
+#include "ftextstream.h"
+
+/*! Create a list of items that are cross referenced with documentation blocks
+ * @param listName String representing the name of the list.
+ * @param pageTitle String representing the title of the list page.
+ * @param secTitle String representing the title of the section.
+ */
+RefList::RefList(const char *listName,
+ const char *pageTitle,
+ const char *secTitle
+ )
+{
+ m_itemList = 0;
+ m_dict = 0;
+ m_dictIterator = 0;
+ m_id = 0;
+ m_listName = listName;
+ m_pageTitle = pageTitle;
+ m_secTitle = secTitle;
+}
+
+/*! Destroy the todo list. Currently not called! */
+RefList::~RefList()
+{
+ delete m_dictIterator;
+ delete m_dict;
+ delete m_itemList;
+}
+
+/*! Adds a new item to the list.
+ * \returns A unique id for this item.
+ */
+int RefList::addRefItem()
+{
+ if (m_dict==0)
+ {
+ m_dict = new QIntDict<RefItem>(1009);
+ m_dict->setAutoDelete(TRUE);
+ m_dictIterator = new QIntDictIterator<RefItem>(*m_dict);
+ }
+ RefItem *item = new RefItem;
+ m_id++;
+ m_dict->insert(m_id,item);
+ return m_id;
+}
+
+/*! Returns an item given it's id that is obtained with addRefItem()
+ * \param itemId item's identifier.
+ * \returns A pointer to the todo item's structure.
+ */
+RefItem *RefList::getRefItem(int itemId)
+{
+ return m_dict ? m_dict->find(itemId) : 0;
+}
+
+/*! Returns the first item in the dictionary or 0 if
+ * non is available.
+ * Items are not sorted.
+ */
+RefItem *RefList::getFirstRefItem()
+{
+ return m_dictIterator ? m_dictIterator->toFirst() : 0;
+}
+
+/*! Returns the next item in the dictionary or 0 if
+ * we are at the end of the list.
+ * Items are not sorted.
+ */
+RefItem *RefList::getNextRefItem()
+{
+ return m_dictIterator ? m_dictIterator->operator++() : 0;
+}
+
+/*! Returns the name of the list as set in the constructor. */
+QCString RefList::listName() const
+{
+ return m_listName;
+}
+
+QCString RefList::pageTitle() const
+{
+ return m_pageTitle;
+}
+
+QCString RefList::sectionTitle() const
+{
+ return m_secTitle;
+}
+
+void RefList::insertIntoList(const char *key,RefItem *item)
+{
+ if (m_itemList==0)
+ {
+ m_itemList = new SortedRefItems(1009);
+ }
+ RefItem *ri = m_itemList->find(key);
+ if (ri==0)
+ {
+ m_itemList->append(key,item);
+ }
+ else // item already added to the list (i.e. multiple item for the same
+ // entity)
+ {
+ if (ri!=item)
+ {
+ ri->extraItems.append(item);
+ }
+ }
+}
+
+
+void RefList::generatePage()
+{
+ if (m_itemList==0) return;
+ m_itemList->sort();
+ SDict<RefItem>::Iterator it(*m_itemList);
+ RefItem *item;
+ QCString doc;
+ doc += "<dl class=\"reflist\">";
+ for (it.toFirst();(item=it.current());++it)
+ {
+ doc += " <dt>";
+ doc += "\\anchor ";
+ doc += item->listAnchor;
+ doc += "\n";
+ doc += item->prefix;
+ doc += " \\_internalref ";
+ doc += item->name;
+ doc += " \"";
+ doc += item->title;
+ doc += "\" ";
+ // write declaration in case a function with arguments
+ if (!item->args.isEmpty())
+ {
+ doc += item->args;
+ }
+ doc += "</dt><dd> ";
+ doc += item->text;
+ QListIterator<RefItem> li(item->extraItems);
+ RefItem *extraItem;
+ for (li.toFirst();(extraItem=li.current());++li)
+ {
+ doc += "<p>" + extraItem->text;
+ }
+ doc += "</dd>";
+ }
+ doc += "</dl>\n";
+ addRelatedPage(m_listName,m_pageTitle,doc,0,m_listName,1,0,0,0);
+}
+
diff --git a/src/reflist.h b/src/reflist.h
new file mode 100644
index 0000000..97b1420
--- /dev/null
+++ b/src/reflist.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _REFLIST_H
+#define _REFLIST_H
+
+#include <qintdict.h>
+#include <qlist.h>
+#include "sortdict.h"
+
+/** This struct represents an item in the list of references. */
+struct RefItem
+{
+ RefItem() /*: written(FALSE)*/ {}
+ QCString text; //!< text of the item.
+ QCString listAnchor; //!< anchor in the list
+
+ QCString prefix; //!< type prefix for the name
+ QCString name; //!< name of the entity containing the reference
+ QCString title; //!< display name of the entity
+ QCString args; //!< optional arguments for the entity (if function)
+ //bool written;
+ QList<RefItem> extraItems; //!< more items belonging to the same entity
+};
+
+/** List of items sorted by title */
+class SortedRefItems : public SDict<RefItem>
+{
+ public:
+ SortedRefItems(int size=17) : SDict<RefItem>(size) {}
+ virtual ~SortedRefItems() {}
+ private:
+ int compareValues(const RefItem *r1,const RefItem *r2) const
+ {
+ return qstricmp(r1->title,r2->title);
+ }
+};
+
+/** List of cross-referenced items
+ *
+ * This class represents a list of items that are put
+ * at a certain point in the documentation by some special command
+ * and are collected in a list. The items cross-reference the
+ * documentation and the list.
+ *
+ * Examples are the todo list, the test list and the bug list,
+ * introduced by the \\todo, \\test, and \\bug commands respectively.
+ */
+class RefList
+{
+ public:
+ int addRefItem();
+ RefItem *getRefItem(int todoItemId);
+ RefItem *getFirstRefItem();
+ RefItem *getNextRefItem();
+ QCString listName() const;
+ QCString pageTitle() const;
+ QCString sectionTitle() const;
+
+ RefList(const char *listName,
+ const char *pageTitle,const char *secTitle
+ );
+ ~RefList();
+ void insertIntoList(const char *key,RefItem *item);
+ void generatePage();
+
+ private:
+ int m_id;
+ QCString m_listName;
+ QCString m_pageTitle;
+ QCString m_secTitle;
+ SortedRefItems *m_itemList;
+ QIntDict<RefItem> *m_dict;
+ QIntDictIterator<RefItem> *m_dictIterator;
+};
+
+#endif
diff --git a/src/resize.js b/src/resize.js
new file mode 100644
index 0000000..304fcb6
--- /dev/null
+++ b/src/resize.js
@@ -0,0 +1,97 @@
+var cookie_namespace = 'doxygen';
+var sidenav,navtree,content,header;
+
+function readCookie(cookie)
+{
+ var myCookie = cookie_namespace+"_"+cookie+"=";
+ if (document.cookie)
+ {
+ var index = document.cookie.indexOf(myCookie);
+ if (index != -1)
+ {
+ var valStart = index + myCookie.length;
+ var valEnd = document.cookie.indexOf(";", valStart);
+ if (valEnd == -1)
+ {
+ valEnd = document.cookie.length;
+ }
+ var val = document.cookie.substring(valStart, valEnd);
+ return val;
+ }
+ }
+ return 0;
+}
+
+function writeCookie(cookie, val, expiration)
+{
+ if (val==undefined) return;
+ if (expiration == null)
+ {
+ var date = new Date();
+ date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+ expiration = date.toGMTString();
+ }
+ document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/";
+}
+
+function resizeWidth()
+{
+ var windowWidth = $(window).width() + "px";
+ var sidenavWidth = $(sidenav).outerWidth();
+ content.css({marginLeft:parseInt(sidenavWidth)+"px"});
+ writeCookie('width',sidenavWidth, null);
+}
+
+function restoreWidth(navWidth)
+{
+ var windowWidth = $(window).width() + "px";
+ content.css({marginLeft:parseInt(navWidth)+6+"px"});
+ sidenav.css({width:navWidth + "px"});
+}
+
+function resizeHeight()
+{
+ var headerHeight = header.outerHeight();
+ var footerHeight = footer.outerHeight();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ content.css({height:windowHeight + "px"});
+ navtree.css({height:windowHeight + "px"});
+ sidenav.css({height:windowHeight + "px",top: headerHeight+"px"});
+}
+
+function initResizable()
+{
+ header = $("#top");
+ sidenav = $("#side-nav");
+ content = $("#doc-content");
+ navtree = $("#nav-tree");
+ footer = $("#nav-path");
+ $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
+ $(window).resize(function() { resizeHeight(); });
+ var width = readCookie('width');
+ if (width) { restoreWidth(width); } else { resizeWidth(); }
+ resizeHeight();
+ var url = location.href;
+ var i=url.indexOf("#");
+ if (i>=0) window.location.hash=url.substr(i);
+ var _preventDefault = function(evt) { evt.preventDefault(); };
+ $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
+ $(document).bind('touchmove',function(e){
+ var device = navigator.userAgent.toLowerCase();
+ var ios = device.match(/(iphone|ipod|ipad)/);
+ if (ios) {
+ try {
+ var target = e.target;
+ while (target) {
+ if ($(target).css('-webkit-overflow-scrolling')=='touch') return;
+ target = target.parentNode;
+ }
+ e.preventDefault();
+ } catch(err) {
+ e.preventDefault();
+ }
+ }
+ });
+}
+
+
diff --git a/src/resize_js.h b/src/resize_js.h
new file mode 100644
index 0000000..160b16c
--- /dev/null
+++ b/src/resize_js.h
@@ -0,0 +1,93 @@
+"var cookie_namespace = 'doxygen'; \n"
+"var sidenav,navtree,content,header;\n"
+"\n"
+"function readCookie(cookie) \n"
+"{\n"
+" var myCookie = cookie_namespace+\"_\"+cookie+\"=\";\n"
+" if (document.cookie) \n"
+" {\n"
+" var index = document.cookie.indexOf(myCookie);\n"
+" if (index != -1) \n"
+" {\n"
+" var valStart = index + myCookie.length;\n"
+" var valEnd = document.cookie.indexOf(\";\", valStart);\n"
+" if (valEnd == -1) \n"
+" {\n"
+" valEnd = document.cookie.length;\n"
+" }\n"
+" var val = document.cookie.substring(valStart, valEnd);\n"
+" return val;\n"
+" }\n"
+" }\n"
+" return 0;\n"
+"}\n"
+"\n"
+"function writeCookie(cookie, val, expiration) \n"
+"{\n"
+" if (val==undefined) return;\n"
+" if (expiration == null) \n"
+" {\n"
+" var date = new Date();\n"
+" date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week\n"
+" expiration = date.toGMTString();\n"
+" }\n"
+" document.cookie = cookie_namespace + \"_\" + cookie + \"=\" + val + \"; expires=\" + expiration+\"; path=/\";\n"
+"}\n"
+" \n"
+"function resizeWidth() \n"
+"{\n"
+" var windowWidth = $(window).width() + \"px\";\n"
+" var sidenavWidth = $(sidenav).outerWidth();\n"
+" content.css({marginLeft:parseInt(sidenavWidth)+\"px\"}); \n"
+" writeCookie('width',sidenavWidth, null);\n"
+"}\n"
+"\n"
+"function restoreWidth(navWidth)\n"
+"{\n"
+" var windowWidth = $(window).width() + \"px\";\n"
+" content.css({marginLeft:parseInt(navWidth)+6+\"px\"});\n"
+" sidenav.css({width:navWidth + \"px\"});\n"
+"}\n"
+"\n"
+"function resizeHeight() \n"
+"{\n"
+" var headerHeight = header.outerHeight();\n"
+" var footerHeight = footer.outerHeight();\n"
+" var windowHeight = $(window).height() - headerHeight - footerHeight;\n"
+" content.css({height:windowHeight + \"px\"});\n"
+" navtree.css({height:windowHeight + \"px\"});\n"
+" sidenav.css({height:windowHeight + \"px\",top: headerHeight+\"px\"});\n"
+"}\n"
+"\n"
+"function initResizable()\n"
+"{\n"
+" header = $(\"#top\");\n"
+" sidenav = $(\"#side-nav\");\n"
+" content = $(\"#doc-content\");\n"
+" navtree = $(\"#nav-tree\");\n"
+" footer = $(\"#nav-path\");\n"
+" $(\".side-nav-resizable\").resizable({resize: function(e, ui) { resizeWidth(); } });\n"
+" $(window).resize(function() { resizeHeight(); });\n"
+" var width = readCookie('width');\n"
+" if (width) { restoreWidth(width); } else { resizeWidth(); }\n"
+" resizeHeight();\n"
+" var url = location.href;\n"
+" var i=url.indexOf(\"#\");\n"
+" if (i>=0) window.location.hash=url.substr(i);\n"
+" var _preventDefault = function(evt) { evt.preventDefault(); };\n"
+" $(\"#splitbar\").bind(\"dragstart\", _preventDefault).bind(\"selectstart\", _preventDefault);\n"
+" $(document).bind('touchmove',function(e){\n"
+" try {\n"
+" var target = e.target;\n"
+" while (target) {\n"
+" if ($(target).css('-webkit-overflow-scrolling')=='touch') return;\n"
+" target = target.parentNode;\n"
+" }\n"
+" e.preventDefault();\n"
+" } catch(err) {\n"
+" e.preventDefault();\n"
+" }\n"
+" });\n"
+"}\n"
+"\n"
+"\n"
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
new file mode 100644
index 0000000..5e27137
--- /dev/null
+++ b/src/rtfdocvisitor.cpp
@@ -0,0 +1,1738 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfileinfo.h>
+
+#include "rtfdocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "msc.h"
+#include "util.h"
+#include "rtfstyle.h"
+#include "message.h"
+#include "parserintf.h"
+#include "msc.h"
+#include "dia.h"
+#include "filedef.h"
+#include "config.h"
+#include "htmlentity.h"
+#include "plantuml.h"
+
+//#define DBG_RTF(x) m_t << x
+#define DBG_RTF(x) do {} while(0)
+
+static QCString align(DocHtmlCell *cell)
+{
+ HtmlAttribList attrs = cell->attribs();
+ uint i;
+ for (i=0; i<attrs.count(); ++i)
+ {
+ if (attrs.at(i)->name.lower()=="align")
+ {
+ if (attrs.at(i)->value.lower()=="center")
+ return "\\qc ";
+ else if (attrs.at(i)->value.lower()=="right")
+ return "\\qr ";
+ else return "";
+ }
+ }
+ return "";
+}
+
+RTFDocVisitor::RTFDocVisitor(FTextStream &t,CodeOutputInterface &ci,
+ const char *langExt)
+ : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE),
+ m_hide(FALSE), m_indentLevel(0), m_lastIsPara(FALSE), m_langExt(langExt)
+{
+}
+
+QCString RTFDocVisitor::getStyle(const char *name)
+{
+ QCString n;
+ n.sprintf("%s%d",name,m_indentLevel);
+ StyleData *sd = rtf_Style[n];
+ ASSERT(sd!=0);
+ return sd->reference;
+}
+
+void RTFDocVisitor::incIndentLevel()
+{
+ if (m_indentLevel<rtf_maxIndentLevels-1) m_indentLevel++;
+}
+
+void RTFDocVisitor::decIndentLevel()
+{
+ if (m_indentLevel>0) m_indentLevel--;
+}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+void RTFDocVisitor::visit(DocWord *w)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocWord)}\n");
+ filter(w->word());
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocLinkedWord)}\n");
+ startLink(w->ref(),w->file(),w->anchor());
+ filter(w->word());
+ endLink(w->ref());
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocWhiteSpace)}\n");
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ }
+ else
+ {
+ m_t << " ";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocSymbol)}\n");
+ const char *res = HtmlEntityMapper::instance()->rtf(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ err("RTF: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocURL)}\n");
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ m_t << "{\\field "
+ "{\\*\\fldinst "
+ "{ HYPERLINK \"";
+ if (u->isEmail()) m_t << "mailto:";
+ m_t << u->url();
+ m_t << "\" }"
+ "{}";
+ m_t << "}"
+ "{\\fldrslt "
+ "{\\cs37\\ul\\cf2 ";
+ filter(u->url());
+ m_t << "}"
+ "}"
+ "}" << endl;
+ }
+ else
+ {
+ m_t << "{\\f2 ";
+ filter(u->url());
+ m_t << "}";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n");
+ m_t << "\\par" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visit(DocHorRuler *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocHorRuler)}\n");
+ m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ m_lastIsPara=FALSE;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocStyleChange)}\n");
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "{\\b "; else m_t << "} ";
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "{\\i "; else m_t << "} ";
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "{\\f2 "; else m_t << "} ";
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "{\\sub "; else m_t << "} ";
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "{\\super "; else m_t << "} ";
+ break;
+ case DocStyleChange::Center:
+ if (s->enable()) m_t << "{\\qc "; else m_t << "} ";
+ break;
+ case DocStyleChange::Small:
+ if (s->enable()) m_t << "{\\sub "; else m_t << "} ";
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_insidePre=FALSE;
+ m_t << "\\par";
+ m_t << "}" << endl;
+ }
+ m_lastIsPara=TRUE;
+ break;
+ case DocStyleChange::Div: /* HTML only */ break;
+ case DocStyleChange::Span: /* HTML only */ break;
+ }
+}
+
+void RTFDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n");
+ QCString lang = m_langExt;
+ if (!s->language().isEmpty()) // explicit language setting
+ {
+ lang = s->language();
+ }
+ SrcLangExt langExt = getLanguageFromFileName(lang);
+ switch(s->type())
+ {
+ case DocVerbatim::Code: // fall though
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ Doxygen::parserManager->getParser(lang)
+ ->parseCode(m_ci,s->context(),s->text(),langExt,
+ s->isExample(),s->exampleFile());
+ //m_t << "\\par" << endl;
+ m_t << "}" << endl;
+ break;
+ case DocVerbatim::Verbatim:
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ filter(s->text(),TRUE);
+ //m_t << "\\par" << endl;
+ m_t << "}" << endl;
+ break;
+ case DocVerbatim::RtfOnly:
+ m_t << s->text();
+ break;
+ case DocVerbatim::HtmlOnly:
+ case DocVerbatim::LatexOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::ManOnly:
+ case DocVerbatim::DocbookOnly:
+ /* nothing */
+ break;
+ case DocVerbatim::Dot:
+ {
+ static int dotindex = 1;
+ QCString fileName(4096);
+
+ fileName.sprintf("%s%d%s",
+ (Config_getString("RTF_OUTPUT")+"/inline_dotgraph_").data(),
+ dotindex++,
+ ".dot"
+ );
+ QFile file(fileName);
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",fileName.data());
+ }
+ file.writeBlock( s->text(), s->text().length() );
+ file.close();
+ m_t << "\\par{\\qc "; // center picture
+ writeDotFile(fileName);
+ m_t << "} ";
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ }
+ break;
+ case DocVerbatim::Msc:
+ {
+ static int mscindex = 1;
+ QCString baseName(4096);
+
+ baseName.sprintf("%s%d",
+ (Config_getString("RTF_OUTPUT")+"/inline_mscgraph_").data(),
+ mscindex++
+ );
+ QFile file(baseName+".msc");
+ if (!file.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",baseName.data());
+ }
+ QCString text = "msc {";
+ text+=s->text();
+ text+="}";
+ file.writeBlock( text, text.length() );
+ file.close();
+ m_t << "\\par{\\qc "; // center picture
+ writeMscFile(baseName);
+ m_t << "} ";
+ if (Config_getBool("DOT_CLEANUP")) file.remove();
+ }
+ break;
+ case DocVerbatim::PlantUML:
+ {
+ static QCString rtfOutput = Config_getString("RTF_OUTPUT");
+ QCString baseName = writePlantUMLSource(rtfOutput,s->exampleFile(),s->text());
+
+ m_t << "\\par{\\qc "; // center picture
+ writePlantUMLFile(baseName);
+ m_t << "} ";
+ }
+ break;
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocAnchor *anc)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocAnchor)}\n");
+ QCString anchor;
+ if (!anc->file().isEmpty())
+ {
+ anchor+=anc->file();
+ }
+ if (!anc->file().isEmpty() && !anc->anchor().isEmpty())
+ {
+ anchor+="_";
+ }
+ if (!anc->anchor().isEmpty())
+ {
+ anchor+=anc->anchor();
+ }
+ m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
+ m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocInclude)}\n");
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ {
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(), &fd);
+ m_t << "\\par";
+ m_t << "}" << endl;
+ }
+ break;
+ case DocInclude::Include:
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),langExt,inc->isExample(),
+ inc->exampleFile());
+ m_t << "\\par";
+ m_t << "}" << endl;
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ break;
+ case DocInclude::LatexInclude:
+ break;
+ case DocInclude::VerbInclude:
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ filter(inc->text());
+ m_t << "\\par";
+ m_t << "}" << endl;
+ break;
+ case DocInclude::Snippet:
+ m_t << "{" << endl;
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile()
+ );
+ m_t << "}";
+ break;
+ }
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visit(DocIncOperator *op)
+{
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocIncOperator)}\n");
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ if (op->isFirst())
+ {
+ if (!m_hide)
+ {
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ }
+ pushEnabled();
+ m_hide = TRUE;
+ }
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,op->context(),op->text(),langExt,
+ op->isExample(),op->exampleFile());
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ m_t << "\\par";
+ m_t << "}" << endl;
+ }
+ m_lastIsPara=TRUE;
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ m_lastIsPara=FALSE;
+ }
+}
+
+void RTFDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ // TODO: do something sensible here, like including a bitmap
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n");
+ m_t << f->text();
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocIndexEntry *i)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visit(DocIndexEntry)}\n");
+ m_t << "{\\xe \\v " << i->entry() << "}" << endl;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visit(DocSimpleSectSep *)
+{
+}
+
+void RTFDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCite)}\n");
+ if (!cite->file().isEmpty())
+ {
+ startLink(cite->ref(),cite->file(),cite->anchor());
+ }
+ else
+ {
+ m_t << "{\\b ";
+ }
+ filter(cite->text());
+ if (!cite->file().isEmpty())
+ {
+ endLink(cite->ref());
+ }
+ else
+ {
+ m_t << "}";
+ }
+}
+
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void RTFDocVisitor::visitPre(DocAutoList *l)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoList)}\n");
+ m_t << "{" << endl;
+ rtf_listItemInfo[m_indentLevel].isEnum = l->isEnumList();
+ rtf_listItemInfo[m_indentLevel].number = 1;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocAutoList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n");
+ m_t << "\\par";
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocAutoListItem *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoListItem)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset;
+ if (rtf_listItemInfo[m_indentLevel].isEnum)
+ {
+ m_t << getStyle("ListEnum") << endl;
+ m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
+ rtf_listItemInfo[m_indentLevel].number++;
+ }
+ else
+ {
+ m_t << getStyle("ListBullet") << endl;
+ }
+ incIndentLevel();
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocAutoListItem *)
+{
+ decIndentLevel();
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoListItem)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocPara *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocPara *p)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n");
+ if (!m_lastIsPara &&
+ !p->isLast() && // omit <p> for last paragraph
+ !(p->parent() && // and for parameters & sections
+ p->parent()->kind()==DocNode::Kind_ParamSect
+ )
+ )
+ {
+ m_t << "\\par" << endl;
+ m_lastIsPara=TRUE;
+ }
+}
+
+void RTFDocVisitor::visitPre(DocRoot *r)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRoot)}\n");
+ if (r->indent()) incIndentLevel();
+ m_t << "{" << rtf_Style["BodyText"]->reference << endl;
+}
+
+void RTFDocVisitor::visitPost(DocRoot *r)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRoot)}\n");
+ if (!m_lastIsPara && !r->singleLine()) m_t << "\\par" << endl;
+ m_t << "}";
+ m_lastIsPara=TRUE;
+ if (r->indent()) decIndentLevel();
+}
+
+void RTFDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{"; // start desc
+ //m_t << "{\\b "; // start bold
+ m_t << "{" << rtf_Style["Heading5"]->reference << endl;
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << theTranslator->trSeeAlso(); break;
+ case DocSimpleSect::Return:
+ m_t << theTranslator->trReturns(); break;
+ case DocSimpleSect::Author:
+ m_t << theTranslator->trAuthor(TRUE,TRUE); break;
+ case DocSimpleSect::Authors:
+ m_t << theTranslator->trAuthor(TRUE,FALSE); break;
+ case DocSimpleSect::Version:
+ m_t << theTranslator->trVersion(); break;
+ case DocSimpleSect::Since:
+ m_t << theTranslator->trSince(); break;
+ case DocSimpleSect::Date:
+ m_t << theTranslator->trDate(); break;
+ case DocSimpleSect::Note:
+ m_t << theTranslator->trNote(); break;
+ case DocSimpleSect::Warning:
+ m_t << theTranslator->trWarning(); break;
+ case DocSimpleSect::Pre:
+ m_t << theTranslator->trPrecondition(); break;
+ case DocSimpleSect::Post:
+ m_t << theTranslator->trPostcondition(); break;
+ case DocSimpleSect::Copyright:
+ m_t << theTranslator->trCopyright(); break;
+ case DocSimpleSect::Invar:
+ m_t << theTranslator->trInvariant(); break;
+ case DocSimpleSect::Remark:
+ m_t << theTranslator->trRemarks(); break;
+ case DocSimpleSect::Attention:
+ m_t << theTranslator->trAttention(); break;
+ case DocSimpleSect::User: break;
+ case DocSimpleSect::Rcs: break;
+ case DocSimpleSect::Unknown: break;
+ }
+
+ // special case 1: user defined title
+ if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
+ {
+ m_t << ":";
+ m_t << "\\par";
+ m_t << "}"; // end bold
+ incIndentLevel();
+ m_t << rtf_Style_Reset << getStyle("DescContinue");
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocSimpleSect *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ decIndentLevel();
+ m_t << "}"; // end desc
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocTitle *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocTitle)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocTitle)}\n");
+ m_t << "\\par" << endl;
+ m_t << "}"; // end bold
+ incIndentLevel();
+ m_t << rtf_Style_Reset << getStyle("DescContinue");
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPre(DocSimpleList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n");
+ m_t << "{" << endl;
+ rtf_listItemInfo[m_indentLevel].isEnum = FALSE;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocSimpleList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleListItem)}\n");
+ m_t << "\\par" << rtf_Style_Reset << getStyle("ListBullet") << endl;
+ m_lastIsPara=FALSE;
+ incIndentLevel();
+}
+
+void RTFDocVisitor::visitPost(DocSimpleListItem *)
+{
+ decIndentLevel();
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleListItem)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSection)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{\\bkmkstart " << rtfFormatBmkStr(s->file()+"_"+s->anchor()) << "}" << endl;
+ m_t << "{\\bkmkend " << rtfFormatBmkStr(s->file()+"_"+s->anchor()) << "}" << endl;
+ m_t << "{{" // start section
+ << rtf_Style_Reset;
+ QCString heading;
+ int level = QMIN(s->level()+1,4);
+ heading.sprintf("Heading%d",level);
+ // set style
+ m_t << rtf_Style[heading]->reference << endl;
+ // make table of contents entry
+ filter(s->title());
+ m_t << endl << "\\par" << "}" << endl;
+ m_t << "{\\tc\\tcl" << level << " \\v ";
+ filter(s->title());
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocSection *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSection)}\n");
+ m_t << "\\par}" << endl; // end section
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlList *l)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlList)}\n");
+ m_t << "{" << endl;
+ rtf_listItemInfo[m_indentLevel].isEnum = l->type()==DocHtmlList::Ordered;
+ rtf_listItemInfo[m_indentLevel].number = 1;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n");
+ m_t << "\\par" << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlListItem)}\n");
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset;
+ if (rtf_listItemInfo[m_indentLevel].isEnum)
+ {
+ m_t << getStyle("ListEnum") << endl;
+ m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
+ rtf_listItemInfo[m_indentLevel].number++;
+ }
+ else
+ {
+ m_t << getStyle("ListBullet") << endl;
+ }
+ incIndentLevel();
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlListItem *)
+{
+ decIndentLevel();
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlListItem)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescList)}\n");
+ //m_t << "{" << endl;
+ //m_t << rtf_Style_Reset << getStyle("ListContinue");
+ //m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescList)}\n");
+ //m_t << "}" << endl;
+ //m_t << "\\par" << endl;
+ //m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescTitle)}\n");
+ //m_t << "\\par" << endl;
+ //m_t << "{\\b ";
+ m_t << "{" << rtf_Style["Heading5"]->reference << endl;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescTitle)}\n");
+ m_t << "\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescData)}\n");
+ incIndentLevel();
+ m_t << "{" << rtf_Style_Reset << getStyle("DescContinue");
+}
+
+void RTFDocVisitor::visitPost(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n");
+ m_t << "\\par";
+ m_t << "}" << endl;
+ decIndentLevel();
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlTable *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlTable)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlTable *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlTable)}\n");
+ m_t << "\\pard\\plain" << endl;
+ m_t << "\\par" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlCaption *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCaption)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocHtmlCaption *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCaption)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocHtmlRow *r)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlRow)}\n");
+ uint i,columnWidth=r->numCells()>0 ? rtf_pageWidth/r->numCells() : 10;
+ m_t << "\\trowd \\trgaph108\\trleft-108"
+ "\\trbrdrt\\brdrs\\brdrw10 "
+ "\\trbrdrl\\brdrs\\brdrw10 "
+ "\\trbrdrb\\brdrs\\brdrw10 "
+ "\\trbrdrr\\brdrs\\brdrw10 "
+ "\\trbrdrh\\brdrs\\brdrw10 "
+ "\\trbrdrv\\brdrs\\brdrw10 "<< endl;
+ for (i=0;i<r->numCells();i++)
+ {
+ if (r->isHeading())
+ {
+ m_t << "\\clcbpat16"; // set cell shading to light grey (color 16 in the clut)
+ }
+ m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 "
+ "\\clbrdrl\\brdrs\\brdrw10 "
+ "\\clbrdrb\\brdrs\\brdrw10 "
+ "\\clbrdrr \\brdrs\\brdrw10 "
+ "\\cltxlrtb "
+ "\\cellx" << ((i+1)*columnWidth) << endl;
+ }
+ m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlRow *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlRow)}\n");
+ m_t << endl;
+ m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+ m_t << "{\\row }" << endl;
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlCell *c)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCell)}\n");
+ m_t << "{" << align(c);
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHtmlCell *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCell)}\n");
+ m_t << "\\cell }";
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ //DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternal)}\n");
+ //m_t << "{"; // start desc
+ //m_t << "{\\b "; // start bold
+ //m_t << theTranslator->trForInternalUseOnly();
+ //m_t << "}"; // end bold
+ //m_t << "\\par" << endl;
+ //incIndentLevel();
+ //m_t << rtf_Style_Reset << getStyle("DescContinue");
+ //m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ //DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n");
+ //m_t << "\\par";
+ //decIndentLevel();
+ //m_t << "}"; // end desc
+ //m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocHRef *href)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHRef)}\n");
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ m_t << "{\\field "
+ "{\\*\\fldinst "
+ "{ HYPERLINK \"" << href->url() << "\" "
+ "}{}"
+ "}"
+ "{\\fldrslt "
+ "{\\cs37\\ul\\cf2 ";
+
+ }
+ else
+ {
+ m_t << "{\\f2 ";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHRef)}\n");
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ m_t << "}"
+ "}"
+ "}";
+ }
+ else
+ {
+ m_t << "}";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPre(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlHeader)}\n");
+ m_t << "{" // start section
+ << rtf_Style_Reset;
+ QCString heading;
+ int level = QMIN(header->level()+2,4);
+ heading.sprintf("Heading%d",level);
+ // set style
+ m_t << rtf_Style[heading]->reference;
+ // make table of contents entry
+ m_t << "{\\tc\\tcl \\v " << level << "}";
+ m_lastIsPara=FALSE;
+
+}
+
+void RTFDocVisitor::visitPost(DocHtmlHeader *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n");
+ m_t << "\\par";
+ m_t << "}" << endl; // end section
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocImage *img)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocImage)}\n");
+ if (img->type()==DocImage::Rtf)
+ {
+ m_t << "\\par" << endl;
+ m_t << "{" << endl;
+ m_t << rtf_Style_Reset << endl;
+ m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ m_t << img->name();
+ m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+ }
+ else // other format -> skip
+ {
+ }
+ // hide caption since it is not supported at the moment
+ pushEnabled();
+ m_hide=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocImage *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocImage)}\n");
+ popEnabled();
+}
+
+void RTFDocVisitor::visitPre(DocDotFile *df)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocDotFile)}\n");
+ writeDotFile(df->file());
+
+ // hide caption since it is not supported at the moment
+ pushEnabled();
+ m_hide=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocDotFile *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDotFile)}\n");
+ popEnabled();
+}
+void RTFDocVisitor::visitPre(DocMscFile *df)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocMscFile)}\n");
+ writeMscFile(df->file());
+
+ // hide caption since it is not supported at the moment
+ pushEnabled();
+ m_hide=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocMscFile *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocMscFile)}\n");
+ popEnabled();
+}
+
+void RTFDocVisitor::visitPre(DocDiaFile *df)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocDiaFile)}\n");
+ writeDiaFile(df->file());
+
+ // hide caption since it is not supported at the moment
+ pushEnabled();
+ m_hide=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocDiaFile *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDiaFile)}\n");
+ popEnabled();
+}
+
+void RTFDocVisitor::visitPre(DocLink *lnk)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocLink)}\n");
+ startLink(lnk->ref(),lnk->file(),lnk->anchor());
+}
+
+void RTFDocVisitor::visitPost(DocLink *lnk)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLink)}\n");
+ endLink(lnk->ref());
+}
+
+void RTFDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRef)}\n");
+ // when ref->isSubPage()==TRUE we use ref->file() for HTML and
+ // ref->anchor() for LaTeX/RTF
+ if (ref->isSubPage())
+ {
+ startLink(ref->ref(),0,ref->anchor());
+ }
+ else
+ {
+ if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
+ }
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void RTFDocVisitor::visitPost(DocRef *ref)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRef)}\n");
+ if (!ref->file().isEmpty()) endLink(ref->ref());
+ //m_t << " ";
+}
+
+
+void RTFDocVisitor::visitPre(DocSecRefItem *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefItem)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocSecRefItem *)
+{
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefItem)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocSecRefList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefList)}\n");
+ m_t << "{" << endl;
+ incIndentLevel();
+ m_t << rtf_Style_Reset << getStyle("LatexTOC") << endl;
+ m_t << "\\par" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocSecRefList *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n");
+ decIndentLevel();
+ m_t << "\\par";
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+//void RTFDocVisitor::visitPre(DocLanguage *l)
+//{
+// DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocLanguage)}\n");
+// QCString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// pushEnabled();
+// m_hide = TRUE;
+// }
+//}
+//
+//void RTFDocVisitor::visitPost(DocLanguage *l)
+//{
+// DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLanguage)}\n");
+// QCString langId = Config_getEnum("OUTPUT_LANGUAGE");
+// if (l->id().lower()!=langId.lower())
+// {
+// popEnabled();
+// }
+//}
+
+void RTFDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamSect)}\n");
+ m_t << "{"; // start param list
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ //m_t << "{\\b "; // start bold
+ m_t << "{" << rtf_Style["Heading5"]->reference << endl;
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ m_t << theTranslator->trParameters(); break;
+ case DocParamSect::RetVal:
+ m_t << theTranslator->trReturnValues(); break;
+ case DocParamSect::Exception:
+ m_t << theTranslator->trExceptions(); break;
+ case DocParamSect::TemplateParam:
+ /* TODO: add this
+ m_t << theTranslator->trTemplateParam(); break;
+ */
+ m_t << "Template Parameters"; break;
+ default:
+ ASSERT(0);
+ }
+ m_t << ":";
+ m_t << "\\par";
+ m_t << "}" << endl;
+ bool useTable = s->type()==DocParamSect::Param ||
+ s->type()==DocParamSect::RetVal ||
+ s->type()==DocParamSect::Exception ||
+ s->type()==DocParamSect::TemplateParam;
+ if (!useTable)
+ {
+ incIndentLevel();
+ }
+ m_t << rtf_Style_Reset << getStyle("DescContinue");
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocParamSect *s)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamSect)}\n");
+ //m_t << "\\par" << endl;
+ bool useTable = s->type()==DocParamSect::Param ||
+ s->type()==DocParamSect::RetVal ||
+ s->type()==DocParamSect::Exception ||
+ s->type()==DocParamSect::TemplateParam;
+ if (!useTable)
+ {
+ decIndentLevel();
+ }
+ m_t << "}" << endl;
+}
+
+void RTFDocVisitor::visitPre(DocParamList *pl)
+{
+ static int columnPos[4][5] =
+ { { 2, 25, 100, 100, 100 }, // no inout, no type
+ { 3, 14, 35, 100, 100 }, // inout, no type
+ { 3, 25, 50, 100, 100 }, // no inout, type
+ { 4, 14, 35, 55, 100 }, // inout, type
+ };
+ int config=0;
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n");
+
+ DocParamSect::Type parentType = DocParamSect::Unknown;
+ DocParamSect *sect = 0;
+ if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect)
+ {
+ parentType = ((DocParamSect*)pl->parent())->type();
+ sect=(DocParamSect*)pl->parent();
+ }
+ bool useTable = parentType==DocParamSect::Param ||
+ parentType==DocParamSect::RetVal ||
+ parentType==DocParamSect::Exception ||
+ parentType==DocParamSect::TemplateParam;
+ if (sect && sect->hasInOutSpecifier()) config+=1;
+ if (sect && sect->hasTypeSpecifier()) config+=2;
+ if (useTable)
+ {
+ int i;
+ m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
+ "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
+ for (i=0;i<columnPos[config][0];i++)
+ {
+ m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
+ "\\cltxlrtb "
+ "\\cellx" << (rtf_pageWidth*columnPos[config][i+1]/100) << endl;
+ }
+ m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+ }
+
+ if (sect && sect->hasInOutSpecifier())
+ {
+ if (useTable)
+ {
+ m_t << "{";
+ }
+
+ // Put in the direction: in/out/in,out if specified.
+ if (pl->direction()!=DocParamSect::Unspecified)
+ {
+ if (pl->direction()==DocParamSect::In)
+ {
+ m_t << "in";
+ }
+ else if (pl->direction()==DocParamSect::Out)
+ {
+ m_t << "out";
+ }
+ else if (pl->direction()==DocParamSect::InOut)
+ {
+ m_t << "in,out";
+ }
+ }
+
+ if (useTable)
+ {
+ m_t << "\\cell }";
+ }
+ }
+
+ if (sect && sect->hasTypeSpecifier())
+ {
+ if (useTable)
+ {
+ m_t << "{";
+ }
+ QListIterator<DocNode> li(pl->paramTypes());
+ DocNode *type;
+ bool first=TRUE;
+ for (li.toFirst();(type=li.current());++li)
+ {
+ if (!first) m_t << " | "; else first=FALSE;
+ if (type->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)type);
+ }
+ else if (type->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)type);
+ }
+ }
+ if (useTable)
+ {
+ m_t << "\\cell }";
+ }
+ }
+
+
+ if (useTable)
+ {
+ m_t << "{";
+ }
+
+ m_t << "{\\i ";
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ bool first=TRUE;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (!first) m_t << ","; else first=FALSE;
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ }
+ m_t << "} ";
+
+ if (useTable)
+ {
+ m_t << "\\cell }{";
+ }
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPost(DocParamList *pl)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamList)}\n");
+
+ DocParamSect::Type parentType = DocParamSect::Unknown;
+ //DocParamSect *sect = 0;
+ if (pl->parent() && pl->parent()->kind()==DocNode::Kind_ParamSect)
+ {
+ parentType = ((DocParamSect*)pl->parent())->type();
+ //sect=(DocParamSect*)pl->parent();
+ }
+ bool useTable = parentType==DocParamSect::Param ||
+ parentType==DocParamSect::RetVal ||
+ parentType==DocParamSect::Exception ||
+ parentType==DocParamSect::TemplateParam;
+ if (useTable)
+ {
+ m_t << "\\cell }" << endl;
+ //m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+ m_t << "{\\row }" << endl;
+ }
+ else
+ {
+ m_t << "\\par" << endl;
+ }
+
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ bool anonymousEnum = x->file()=="@";
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocXRefItem)}\n");
+ m_t << "{"; // start param list
+ //m_t << "{\\b "; // start bold
+ m_t << "{" << rtf_Style["Heading5"]->reference << endl;
+ if (Config_getBool("RTF_HYPERLINKS") && !anonymousEnum)
+ {
+ QCString refName;
+ if (!x->file().isEmpty())
+ {
+ refName+=x->file();
+ }
+ if (!x->file().isEmpty() && !x->anchor().isEmpty())
+ {
+ refName+="_";
+ }
+ if (!x->anchor().isEmpty())
+ {
+ refName+=x->anchor();
+ }
+
+ m_t << "{\\field "
+ "{\\*\\fldinst "
+ "{ HYPERLINK \\\\l \"" << refName << "\" "
+ "}{}"
+ "}"
+ "{\\fldrslt "
+ "{\\cs37\\ul\\cf2 ";
+ filter(x->title());
+ m_t << "}"
+ "}"
+ "}";
+ }
+ else
+ {
+ filter(x->title());
+ }
+ m_t << ":";
+ m_t << "\\par";
+ m_t << "}"; // end bold
+ incIndentLevel();
+ m_t << rtf_Style_Reset << getStyle("DescContinue");
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocXRefItem)}\n");
+ m_t << "\\par" << endl;
+ decIndentLevel();
+ m_t << "}" << endl; // end xref item
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternalRef)}\n");
+ startLink("",ref->file(),ref->anchor());
+}
+
+void RTFDocVisitor::visitPost(DocInternalRef *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternalRef)}\n");
+ endLink("");
+ m_t << " ";
+}
+
+void RTFDocVisitor::visitPre(DocCopy *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCopy)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocCopy *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocCopy)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocText *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocText)}\n");
+}
+
+void RTFDocVisitor::visitPost(DocText *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocText)}\n");
+}
+
+void RTFDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlBlockQuote)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{"; // start desc
+ incIndentLevel();
+ m_t << rtf_Style_Reset << getStyle("DescContinue");
+}
+
+void RTFDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlBlockQuote)}\n");
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ decIndentLevel();
+ m_t << "}"; // end desc
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::visitPre(DocVhdlFlow *)
+{
+ if (m_hide) return;
+}
+
+void RTFDocVisitor::visitPost(DocVhdlFlow *)
+{
+ if (m_hide) return;
+}
+
+void RTFDocVisitor::visitPre(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+void RTFDocVisitor::visitPost(DocParBlock *)
+{
+ if (m_hide) return;
+}
+
+
+//static char* getMultiByte(int c)
+//{
+// static char s[10];
+// sprintf(s,"\\'%X",c);
+// return s;
+//}
+
+void RTFDocVisitor::filter(const char *str,bool verbatim)
+{
+ if (str)
+ {
+ const unsigned char *p=(const unsigned char *)str;
+ unsigned char c;
+ //unsigned char pc='\0';
+ while (*p)
+ {
+ //static bool MultiByte = FALSE;
+ c=*p++;
+
+ //if ( MultiByte )
+ //{
+ // m_t << getMultiByte( c );
+ // MultiByte = FALSE;
+ // continue;
+ //}
+ //if ( c >= 0x80 )
+ //{
+ // MultiByte = TRUE;
+ // m_t << getMultiByte( c );
+ // continue;
+ //}
+
+ switch (c)
+ {
+ case '{': m_t << "\\{"; break;
+ case '}': m_t << "\\}"; break;
+ case '\\': m_t << "\\\\"; break;
+ case '\n': if (verbatim)
+ {
+ m_t << "\\par" << endl;
+ }
+ else
+ {
+ m_t << '\n';
+ }
+ break;
+ default: m_t << (char)c;
+ }
+ //pc = c;
+ }
+ }
+}
+
+void RTFDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
+{
+ if (ref.isEmpty() && Config_getBool("RTF_HYPERLINKS"))
+ {
+ QCString refName;
+ if (!file.isEmpty())
+ {
+ refName+=file;
+ }
+ if (!file.isEmpty() && anchor)
+ {
+ refName+='_';
+ }
+ if (anchor)
+ {
+ refName+=anchor;
+ }
+
+ m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
+ m_t << rtfFormatBmkStr(refName);
+ m_t << "\" }{}";
+ m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+ }
+ else
+ {
+ m_t << "{\\b ";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::endLink(const QCString &ref)
+{
+ if (ref.isEmpty() && Config_getBool("RTF_HYPERLINKS"))
+ {
+ m_t << "}}}";
+ }
+ else
+ {
+ m_t << "}";
+ }
+ m_lastIsPara=FALSE;
+}
+
+void RTFDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void RTFDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
+void RTFDocVisitor::writeDotFile(const QCString &fileName)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ QCString outDir = Config_getString("RTF_OUTPUT");
+ writeDotGraphFromFile(fileName,outDir,baseName,GOF_BITMAP);
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{" << endl;
+ m_t << rtf_Style_Reset;
+ m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ m_t << baseName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+ m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::writeMscFile(const QCString &fileName)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ QCString outDir = Config_getString("RTF_OUTPUT");
+ writeMscGraphFromFile(fileName+".msc",outDir,baseName,MSC_BITMAP);
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{" << endl;
+ m_t << rtf_Style_Reset;
+ m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ m_t << baseName << ".png";
+ m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::writeDiaFile(const QCString &fileName)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ QCString outDir = Config_getString("RTF_OUTPUT");
+ writeDiaGraphFromFile(fileName+".dia",outDir,baseName,DIA_BITMAP);
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{" << endl;
+ m_t << rtf_Style_Reset;
+ m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ m_t << baseName << ".png";
+ m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
+void RTFDocVisitor::writePlantUMLFile(const QCString &fileName)
+{
+ QCString baseName=fileName;
+ int i;
+ if ((i=baseName.findRev('/'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ QCString outDir = Config_getString("RTF_OUTPUT");
+ generatePlantUMLOutput(fileName,outDir,PUML_BITMAP);
+ if (!m_lastIsPara) m_t << "\\par" << endl;
+ m_t << "{" << endl;
+ m_t << rtf_Style_Reset;
+ m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ m_t << baseName << ".png";
+ m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ m_t << "}" << endl;
+ m_lastIsPara=TRUE;
+}
+
diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h
new file mode 100644
index 0000000..c50802d
--- /dev/null
+++ b/src/rtfdocvisitor.h
@@ -0,0 +1,174 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _RTFDOCVISITOR_H
+#define _RTFDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+
+class FTextStream;
+class CodeOutputInterface;
+
+/*! @brief Concrete visitor implementation for RTF output. */
+class RTFDocVisitor : public DocVisitor
+{
+ public:
+ RTFDocVisitor(FTextStream &t,CodeOutputInterface &ci,const char *langExt);
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *);
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *s);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *s);
+ void visitPost(DocHtmlList *s);
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *t);
+ void visitPost(DocHtmlTable *t);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *) ;
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *ref);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void filter(const char *str,bool verbatim=FALSE);
+ void startLink(const QCString &ref,const QCString &file,
+ const QCString &anchor);
+ void endLink(const QCString &ref);
+ QCString getStyle(const char *name);
+ void incIndentLevel();
+ void decIndentLevel();
+
+ void pushEnabled();
+ void popEnabled();
+ void writeDotFile(const QCString &fileName);
+ void writeMscFile(const QCString &fileName);
+ void writeDiaFile(const QCString &fileName);
+ void writePlantUMLFile(const QCString &fileName);
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_hide;
+ int m_indentLevel;
+ QStack<bool> m_enabled;
+ bool m_lastIsPara;
+ QCString m_langExt;
+};
+
+#endif
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
new file mode 100644
index 0000000..ccdadcf
--- /dev/null
+++ b/src/rtfgen.cpp
@@ -0,0 +1,2949 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Parker Waechter & Dimitri van Heesch.
+ *
+ * Style sheet additions by Alexander Bartolich
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include "rtfgen.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "util.h"
+#include "diagram.h"
+#include "language.h"
+#include "dot.h"
+#include "version.h"
+#include "pagedef.h"
+#include "rtfstyle.h"
+#include "rtfdocvisitor.h"
+#include "docparser.h"
+#include "dirdef.h"
+#include "vhdldocgen.h"
+#include "portable.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filename.h"
+#include "namespacedef.h"
+
+//#define DBG_RTF(x) x;
+#define DBG_RTF(x)
+
+static QCString dateToRTFDateString()
+{
+ const QDateTime &d = QDateTime::currentDateTime();
+ QCString result;
+ result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
+ d.date().year(), d.date().month(), d.date().day(),
+ d.time().hour(),d.time().minute(),d.time().second());
+ return result;
+}
+
+RTFGenerator::RTFGenerator() : OutputGenerator()
+{
+ dir=Config_getString("RTF_OUTPUT");
+ col=0;
+ //insideTabbing=FALSE;
+ m_listLevel = 0;
+ m_bstartedBody = FALSE;
+ m_omitParagraph = FALSE;
+ m_numCols = 0;
+}
+
+RTFGenerator::~RTFGenerator()
+{
+}
+
+//void RTFGenerator::append(const OutputGenerator *g)
+//{
+// t << g->getContents();
+// col+=((RTFGenerator *)g)->col;
+// //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
+// m_listLevel=((RTFGenerator *)g)->m_listLevel;
+// m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
+// //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
+// // insideTabbing ? "TRUE" : "FALSE" );
+//}
+
+//OutputGenerator *RTFGenerator::copy()
+//{
+// RTFGenerator *result = new RTFGenerator;
+// //result->insideTabbing=insideTabbing;
+// result->m_listLevel=m_listLevel;
+// result->m_omitParagraph=m_omitParagraph;
+// return result;
+//}
+
+void RTFGenerator::writeStyleSheetFile(QFile &file)
+{
+ QTextStream t(&file);
+ t << "# Generated by doxygen " << versionString << "\n\n";
+ t << "# This file describes styles used for generating RTF output.\n";
+ t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
+ t << "# Remove a hash to activate a line.\n\n";
+
+ int i;
+ for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
+ {
+ t << "# " << rtf_Style_Default[i].name << " = "
+ << rtf_Style_Default[i].reference
+ << rtf_Style_Default[i].definition << endl;
+ }
+}
+
+void RTFGenerator::writeExtensionsFile(QFile &file)
+{
+ QTextStream t(&file);
+ t << "# Generated by doxygen " << versionString << "\n\n";
+ t << "# This file describes extensions used for generating RTF output.\n";
+ t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
+ t << "# Remove a hash to activate a line.\n\n";
+
+ t << "# Overrides the project title.\n";
+
+ t << "#Title = \n\n";
+
+ t << "# Name of the company that produced this document.\n";
+ t << "#Company = \n\n";
+
+ t << "# Filename of a company or project logo.\n";
+ t << "#LogoFilename = \n\n";
+
+ t << "# Author of the document.\n";
+ t << "#Author = \n\n";
+
+ t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
+ t << "#DocumentType = \n\n";
+
+ t << "# Document tracking number.\n";
+ t << "#DocumentId = \n\n";
+
+ t << "# Name of the author's manager.\n";
+ t << "# This field is not displayed in the document itself, but it is \n";
+ t << "# available in the information block of the rtf file. In Microsoft \n";
+ t << "# Word, it is available under File:Properties.\n";
+ t << "#Manager = \n\n";
+
+ t << "# Subject of the document.\n";
+ t << "# This field is not displayed in the document itself, but it is \n";
+ t << "# available in the information block of the rtf file. In Microsoft \n";
+ t << "# Word, it is available under File:Properties.\n";
+ t << "#Subject = \n\n";
+
+ t << "# Comments regarding the document.\n";
+ t << "# This field is not displayed in the document itself, but it is \n";
+ t << "# available in the information block of the rtf file. In Microsoft \n";
+ t << "# Word, it is available under File:Properties.\n";
+ t << "#Comments = \n\n";
+
+ t << "# Keywords associated with the document.\n";
+ t << "# This field is not displayed in the document itself, but it is \n";
+ t << "# available in the information block of the rtf file. In Microsoft \n";
+ t << "# Word, it is available under File:Properties.\n";
+ t << "#Keywords = \n\n";
+}
+
+
+void RTFGenerator::init()
+{
+ QCString dir=Config_getString("RTF_OUTPUT");
+ QDir d(dir);
+ if (!d.exists() && !d.mkdir(dir))
+ {
+ err("Could not create output directory %s\n",dir.data());
+ exit(1);
+ }
+ rtf_Style.setAutoDelete(TRUE);
+
+ // first duplicate strings of rtf_Style_Default
+ const struct Rtf_Style_Default* def = rtf_Style_Default;
+ while(def->reference != 0)
+ {
+ if (def->definition == 0)
+ err("Internal: rtf_Style_Default[%s] has no definition.\n", def->name);
+ StyleData* styleData = new StyleData(def->reference, def->definition);
+ rtf_Style.insert(def->name, styleData);
+ def++;
+ }
+
+ // overwrite some (or all) definitions from file
+ QCString &rtfStyleSheetFile = Config_getString("RTF_STYLESHEET_FILE");
+ if (!rtfStyleSheetFile.isEmpty())
+ {
+ loadStylesheet(rtfStyleSheetFile, rtf_Style);
+ }
+
+ // If user has defined an extension file, load its contents.
+ QCString &rtfExtensionsFile = Config_getString("RTF_EXTENSIONS_FILE");
+ if (!rtfExtensionsFile.isEmpty())
+ {
+ loadExtensions(rtfExtensionsFile);
+ }
+
+ createSubDirs(d);
+}
+
+static QCString makeIndexName(const char *s,int i)
+{
+ QCString result=s;
+ result+=(char)(i+'0');
+ return result;
+}
+
+void RTFGenerator::beginRTFDocument()
+{
+ /* all the included RTF files should begin with the
+ * same header
+ */
+ t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
+ t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
+
+ DBG_RTF(t <<"{\\comment Beginning font list}\n")
+ t <<"{\\fonttbl ";
+ t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
+ t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
+ t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
+ t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
+ t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
+ t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
+ t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
+ t <<"}\n";
+ DBG_RTF(t <<"{\\comment begin colors}\n")
+ t <<"{\\colortbl;";
+ t <<"\\red0\\green0\\blue0;";
+ t <<"\\red0\\green0\\blue255;";
+ t <<"\\red0\\green255\\blue255;";
+ t <<"\\red0\\green255\\blue0;";
+ t <<"\\red255\\green0\\blue255;";
+ t <<"\\red255\\green0\\blue0;";
+ t <<"\\red255\\green255\\blue0;";
+ t <<"\\red255\\green255\\blue255;";
+ t <<"\\red0\\green0\\blue128;";
+ t <<"\\red0\\green128\\blue128;";
+ t <<"\\red0\\green128\\blue0;";
+ t <<"\\red128\\green0\\blue128;";
+ t <<"\\red128\\green0\\blue0;";
+ t <<"\\red128\\green128\\blue0;";
+ t <<"\\red128\\green128\\blue128;";
+ t <<"\\red192\\green192\\blue192;}" << endl;
+
+ DBG_RTF(t <<"{\\comment Beginning style list}\n")
+ t <<"{\\stylesheet\n";
+ t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
+
+ // sort styles ascending by \s-number via an intermediate QArray
+ QArray<const StyleData*> array(128);
+ array.fill(0);
+ QDictIterator<StyleData> iter(rtf_Style);
+ const StyleData* style;
+ for(; (style = iter.current()); ++iter)
+ {
+ unsigned index = style->index;
+ unsigned size = array.size();
+ if (index >= size)
+ {
+ // +1 to add at least one element, then align up to multiple of 8
+ array.resize((index + 1 + 7) & ~7);
+ array.fill(0, size);
+ ASSERT(index < array.size());
+ }
+ if (array.at(index) != 0)
+ {
+ QCString key(iter.currentKey());
+ msg("Style '%s' redefines \\s%d.\n", key.data(), index);
+ }
+ array.at(index) = style;
+ }
+
+ // write array elements
+ unsigned size = array.size();
+ for(unsigned i = 0; i < size; i++)
+ {
+ const StyleData* style = array.at(i);
+ if (style != 0)
+ t <<"{" << style->reference << style->definition << ";}\n";
+ }
+
+ t <<"}" << endl;
+ // this comment is needed for postprocessing!
+ t <<"{\\comment begin body}" << endl;
+
+}
+
+void RTFGenerator::beginRTFChapter()
+{
+ t <<"\n";
+ DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
+ t << rtf_Style_Reset;
+
+ // if we are compact, no extra page breaks...
+ if (Config_getBool("COMPACT_RTF"))
+ {
+ // t <<"\\sect\\sectd\\sbknone\n";
+ t <<"\\sect\\sbknone\n";
+ rtfwriteRuler_thick();
+ }
+ else
+ t <<"\\sect\\sbkpage\n";
+ //t <<"\\sect\\sectd\\sbkpage\n";
+
+ t << rtf_Style["Heading1"]->reference << "\n";
+}
+
+void RTFGenerator::beginRTFSection()
+{
+ t <<"\n";
+ DBG_RTF(t << "{\\comment BeginRTFSection}\n")
+ t << rtf_Style_Reset;
+
+ // if we are compact, no extra page breaks...
+ if (Config_getBool("COMPACT_RTF"))
+ {
+ // t <<"\\sect\\sectd\\sbknone\n";
+ t <<"\\sect\\sbknone\n";
+ rtfwriteRuler_emboss();
+ }
+ else
+ t <<"\\sect\\sbkpage\n";
+ //t <<"\\sect\\sectd\\sbkpage\n";
+
+ t << rtf_Style["Heading2"]->reference << "\n";
+}
+
+void RTFGenerator::startFile(const char *name,const char *,const char *)
+{
+ //setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp()));
+ QCString fileName=name;
+ relPath = relativePathToRoot(fileName);
+
+ if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
+ startPlainFile(fileName);
+ beginRTFDocument();
+}
+
+void RTFGenerator::endFile()
+{
+ DBG_RTF(t << "{\\comment endFile}\n")
+ t << "}";
+
+ endPlainFile();
+}
+
+void RTFGenerator::startProjectNumber()
+{
+ DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
+ t << " ";
+}
+
+void RTFGenerator::endProjectNumber()
+{
+ DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
+}
+
+void RTFGenerator::startIndexSection(IndexSections is)
+{
+ //QCString paperName;
+
+ m_listLevel = 0;
+
+ switch (is)
+ {
+ case isTitlePageStart:
+ // basic RTFstart
+ // get readyfor author etc
+
+ t << "{\\info \n";
+ t << "{\\title {\\comment ";
+ break;
+ case isTitlePageAuthor:
+ t << "}\n";
+ if (rtf_subject) t << "{\\subject " << rtf_subject << "}\n";
+ if (rtf_comments) t << "{\\comment " << rtf_comments << "}\n";
+ if (rtf_company) t << "{\\company " << rtf_company << "}\n";
+ if (rtf_author) t << "{\\author " << rtf_author << "}\n";
+ if (rtf_manager) t << "{\\manager " << rtf_manager << "}\n";
+ if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
+ if (rtf_keywords) t << "{\\keywords " << rtf_keywords << "}\n";
+ t << "{\\comment ";
+ break;
+ case isMainPage:
+ //Introduction
+ beginRTFChapter();
+ break;
+ //case isPackageIndex:
+ // //Package Index
+ // beginRTFChapter();
+ // break;
+ case isModuleIndex:
+ //Module Index
+ beginRTFChapter();
+ break;
+ case isDirIndex:
+ //Directory Index
+ beginRTFChapter();
+ break;
+ case isNamespaceIndex:
+ //Namespace Index
+ beginRTFChapter();
+ break;
+ case isClassHierarchyIndex:
+ //Hierarchical Index
+ DBG_RTF(t << "{\\comment start classhierarchy}\n")
+ beginRTFChapter();
+ break;
+ case isCompoundIndex:
+ //Annotated Compound Index
+ beginRTFChapter();
+ break;
+ case isFileIndex:
+ //Annotated File Index
+ beginRTFChapter();
+ break;
+ case isPageIndex:
+ //Related Page Index
+ beginRTFChapter();
+ break;
+ case isModuleDocumentation:
+ {
+ //Module Documentation
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ bool found=FALSE;
+ for (gli.toFirst();(gd=gli.current()) && !found;++gli)
+ {
+ if (!gd->isReference())
+ {
+ beginRTFChapter();
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isDirDocumentation:
+ {
+ //Directory Documentation
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ bool found=FALSE;
+ for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ beginRTFChapter();
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isNamespaceDocumentation:
+ {
+ // Namespace Documentation
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ bool found=FALSE;
+ for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ beginRTFChapter();
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isClassDocumentation:
+ {
+ //Compound Documentation
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ bool found=FALSE;
+ for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ beginRTFChapter();
+ found=TRUE;
+ }
+ }
+ }
+ break;
+ case isFileDocumentation:
+ {
+ //File Documentation
+ bool isFirst=TRUE;
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->isLinkableInProject())
+ {
+ if (isFirst)
+ {
+ beginRTFChapter();
+ isFirst=FALSE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case isExampleDocumentation:
+ {
+ //Example Documentation
+ beginRTFChapter();
+ }
+ break;
+ case isPageDocumentation:
+ {
+ //Page Documentation
+ beginRTFChapter();
+ }
+ break;
+ case isPageDocumentation2:
+ {
+ t << "{\\tc \\v ";
+ }
+ break;
+ case isEndIndex:
+ break;
+ }
+}
+
+void RTFGenerator::endIndexSection(IndexSections is)
+{
+ bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ switch (is)
+ {
+ case isTitlePageStart:
+ if (rtf_title)
+ // User has overridden document title in extensions file
+ t << "}" << rtf_title;
+ else
+ t << "}" << Config_getString("PROJECT_NAME");
+ break;
+ case isTitlePageAuthor:
+ {
+ t << "Doxgyen. }\n";
+ t << "{\\creatim " << dateToRTFDateString() << "}\n}";
+ DBG_RTF(t << "{\\comment end of infoblock}\n");
+ // setup for this section
+ t << rtf_Style_Reset <<"\n";
+ t <<"\\sectd\\pgnlcrm\n";
+ t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
+ // the title entry
+ DBG_RTF(t << "{\\comment begin title page}\n")
+
+
+ t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
+
+ t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
+ if (rtf_logoFilename)
+ {
+ t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
+ t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
+ }
+ if (rtf_company)
+ {
+ t << rtf_company << "\\par\\par\n";
+ }
+
+ t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
+ t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt TITLE}}\\par" << endl;
+
+ t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
+ t << "\\par\n";
+ if (rtf_documentType)
+ {
+ t << rtf_documentType << "\\par\n";
+ }
+ if (rtf_documentId)
+ {
+ t << rtf_documentId << "\\par\n";
+ }
+ t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
+
+ t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
+ t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
+ t << "Version " << Config_getString("PROJECT_NUMBER") << "\\par";
+ t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
+ "{\\fldrslt CREATEDATE}}\\par"<<endl;
+ t << "\\page\\page";
+ DBG_RTF(t << "{\\comment End title page}" << endl)
+
+ // table of contents section
+ DBG_RTF(t << "{\\comment Table of contents}\n")
+ t << "\\vertalt\n";
+ t << rtf_Style_Reset << endl;
+ t << rtf_Style["Heading1"]->reference;
+ t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
+ t << rtf_Style_Reset << "\\par" << endl;
+ t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
+ t << rtf_Style_Reset << endl;
+ }
+ break;
+ case isMainPage:
+ t << "\\par " << rtf_Style_Reset << endl;
+ if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
+ {
+ t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
+ }
+ else
+ {
+ t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
+ }
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ //if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
+ t << "index";
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ //case isPackageIndex:
+ // t << "\\par " << rtf_Style_Reset << endl;
+ // t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
+ // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ // break;
+ case isModuleIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isDirIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isNamespaceIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ if (fortranOpt)
+ {
+ t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}" << endl;
+ }
+ else
+ {
+ t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}" << endl;
+ }
+
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isClassHierarchyIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isCompoundIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ if (fortranOpt)
+ {
+ t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
+ }
+ else if (vhdlOpt)
+ {
+ t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl;
+ }
+ else
+ {
+ t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
+ }
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isFileIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isPageIndex:
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ break;
+ case isModuleDocumentation:
+ {
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (!gd->isReference())
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << gd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ }
+ }
+ break;
+ case isDirDocumentation:
+ {
+ SDict<DirDef>::Iterator dli(*Doxygen::directories);
+ DirDef *dd;
+ t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
+ for (dli.toFirst();(dd=dli.current());++dli)
+ {
+ if (dd->isLinkableInProject())
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << dd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ }
+ }
+ break;
+ case isNamespaceDocumentation:
+ {
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ bool found=FALSE;
+ for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+ {
+ if (nd->isLinkableInProject())
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << nd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ found=TRUE;
+ }
+ }
+ while ((nd=nli.current()))
+ {
+ if (nd->isLinkableInProject())
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ beginRTFSection();
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << nd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ ++nli;
+ }
+ }
+ break;
+ case isClassDocumentation:
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd=0;
+ bool found=FALSE;
+ if (fortranOpt)
+ {
+ t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
+ }
+ else
+ {
+ t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
+ }
+ for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << cd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ found=TRUE;
+ }
+ }
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->isLinkableInProject() &&
+ cd->templateMaster()==0 &&
+ !cd->isEmbeddedInOuterScope()
+ )
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ beginRTFSection();
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << cd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ }
+ }
+ break;
+ case isFileDocumentation:
+ {
+ bool isFirst=TRUE;
+
+ t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (fnli.toFirst();(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ if (fd->isLinkableInProject())
+ {
+ if (isFirst)
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << fd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ isFirst=FALSE;
+ }
+ else
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ beginRTFSection();
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << fd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ }
+ }
+ }
+ }
+ break;
+ case isExampleDocumentation:
+ {
+ //t << "}\n";
+ t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=pdi.toFirst();
+ if (pd)
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << pd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ for (++pdi;(pd=pdi.current());++pdi)
+ {
+ t << "\\par " << rtf_Style_Reset << endl;
+ beginRTFSection();
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << pd->getOutputFileBase();
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ }
+ }
+ break;
+ case isPageDocumentation:
+ {
+//#error "fix me in the same way as the latex index..."
+ //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
+ //t << "}"<< endl;
+ //PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ //PageDef *pd=pdi.toFirst();
+ //bool first=TRUE;
+ //for (pdi.toFirst();(pd=pdi.current());++pdi)
+ //{
+ // if (!pd->getGroupDef() && !pd->isReference())
+ // {
+ // if (first) t << "\\par " << rtf_Style_Reset << endl;
+ // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ // t << pd->getOutputFileBase();
+ // t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ // first=FALSE;
+ // }
+ //}
+ }
+ break;
+ case isPageDocumentation2:
+ {
+ t << "}";
+ t << "\\par " << rtf_Style_Reset << endl;
+ }
+ break;
+ case isEndIndex:
+ beginRTFChapter();
+ t << rtf_Style["Heading1"]->reference;
+ t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
+ t << rtf_Style_Reset << endl;
+ t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
+ t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
+
+ break;
+ }
+}
+
+void RTFGenerator::writePageLink(const char *name,bool first)
+{
+ if (first) t << "\\par " << rtf_Style_Reset << endl;
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ t << name;
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+}
+
+void RTFGenerator::lastIndexPage()
+{
+ DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
+ // end page and setup for rest of document
+ t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
+ t <<"\\sect \\sectd \\sbknone\n";
+
+ // set new footer with arabic numbers
+ t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
+ //t << rtf_Style["Heading1"]->reference << "\n";
+
+}
+
+void RTFGenerator::writeStyleInfo(int)
+{
+}
+
+void RTFGenerator::lineBreak(const char *)
+{
+ DBG_RTF(t << "{\\comment (lineBreak)}" << endl)
+ t << "\\par" << endl;
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::writeString(const char *text)
+{
+ t << text;
+}
+
+void RTFGenerator::startIndexList()
+{
+ DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
+ t << "{" << endl;
+ t << "\\par" << endl;
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::endIndexList()
+{
+ DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
+ if (!m_omitParagraph)
+ {
+ t << "\\par";
+ m_omitParagraph = TRUE;
+ }
+ t << "}";
+ decrementIndentLevel();
+}
+
+/*! start bullet list */
+void RTFGenerator::startItemList()
+{
+ newParagraph();
+ DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
+ t << "{";
+ incrementIndentLevel();
+ rtf_listItemInfo[m_listLevel].isEnum = FALSE;
+}
+
+/*! end bullet list */
+void RTFGenerator::endItemList()
+{
+ newParagraph();
+ DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
+ t << "}";
+ decrementIndentLevel();
+ m_omitParagraph = TRUE;
+}
+
+///*! start enumeration list */
+//void RTFGenerator::startEnumList() // starts an enumeration list
+//{
+// DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
+// t << "{" << endl;
+// incrementIndentLevel();
+// rtf_listItemInfo[m_listLevel].isEnum = TRUE;
+// rtf_listItemInfo[m_listLevel].number = 1;
+//}
+//
+///*! end enumeration list */
+//void RTFGenerator::endEnumList()
+//{
+// newParagraph();
+// DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
+// t << "}";
+// decrementIndentLevel();
+// m_omitParagraph = TRUE;
+//}
+
+/*! write bullet or enum item */
+void RTFGenerator::startItemListItem()
+{
+ DBG_RTF(t << "{\\comment (startItemListItem)}" << endl)
+ newParagraph();
+ t << rtf_Style_Reset;
+ if (rtf_listItemInfo[m_listLevel].isEnum)
+ {
+ t << rtf_EList_DepthStyle() << endl;
+ t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
+ rtf_listItemInfo[m_listLevel].number++;
+ }
+ else
+ {
+ t << rtf_BList_DepthStyle() << endl;
+ }
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::endItemListItem()
+{
+ DBG_RTF(t << "{\\comment (endItemListItem)}" << endl)
+}
+
+void RTFGenerator::startIndexItem(const char *,const char *)
+{
+ DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
+
+ if (!m_omitParagraph)
+ {
+ t << "\\par" << endl;
+ m_omitParagraph = TRUE;
+ }
+}
+
+void RTFGenerator::endIndexItem(const char *ref,const char *fn)
+{
+ DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
+ if (!ref && fn)
+ {
+ t << "\\tab ";
+ writeRTFReference(fn);
+ t << endl;
+ }
+ else
+ {
+ t << endl;
+ }
+ m_omitParagraph = TRUE;
+}
+
+//void RTFGenerator::writeIndexFileItem(const char *,const char *text)
+//{
+// t << "\\item\\contentsline{section}{";
+// docify(text);
+// t << "}{\\pageref{" << text << "}}" << endl;
+//}
+
+void RTFGenerator::startHtmlLink(const char *url)
+{
+
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ t << "{\\field {\\*\\fldinst { HYPERLINK \"";
+ t << url;
+ t << "\" }{}";
+ t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+ }
+ else
+ {
+ startTypewriter();
+ }
+}
+
+void RTFGenerator::endHtmlLink()
+{
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ t << "}}}" << endl;
+ }
+ else
+ {
+ endTypewriter();
+ }
+}
+
+//void RTFGenerator::writeMailLink(const char *url)
+//{
+// startTypewriter();
+// docify(url);
+// endTypewriter();
+//}
+
+void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
+ const char *path,const char *name)
+{
+ DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
+ t << "{\\b ";
+ if (path) docify(path);
+ if (f && Config_getBool("RTF_HYPERLINKS"))
+ {
+ t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
+ t << rtfFormatBmkStr(f);
+ t << "\" }{}";
+ t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+ docify(name);
+
+ t << "}}}" << endl;
+ }
+ else
+ {
+ docify(name);
+ }
+ t << "} ";
+}
+
+void RTFGenerator::writeEndAnnoItem(const char *name)
+{
+ DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
+ if (name)
+ {
+ t << "\\tab ";
+ writeRTFReference(name);
+ t << endl;
+ }
+ else
+ {
+ t << endl;
+ }
+ newParagraph();
+}
+
+void RTFGenerator::startIndexKey()
+{
+ DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
+ t << "{\\b ";
+}
+
+void RTFGenerator::endIndexKey()
+{
+ DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
+}
+
+void RTFGenerator::startIndexValue(bool hasBrief)
+{
+ DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
+ t << " ";
+ if (hasBrief) t << "(";
+}
+
+void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
+{
+ DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
+ if (hasBrief) t << ")";
+ t << "} ";
+ if (name)
+ {
+ t << "\\tab ";
+ writeRTFReference(name);
+ t << endl;
+ }
+ else
+ {
+ t << endl;
+ }
+ m_omitParagraph=FALSE;
+ newParagraph();
+}
+
+void RTFGenerator::startSubsection()
+{
+ //beginRTFSubSection();
+ t <<"\n";
+ DBG_RTF(t << "{\\comment Begin SubSection}\n")
+ t << rtf_Style_Reset;
+ t << rtf_Style["Heading3"]->reference << "\n";
+}
+
+void RTFGenerator::endSubsection()
+{
+ newParagraph();
+ t << rtf_Style_Reset << endl;
+}
+
+void RTFGenerator::startSubsubsection()
+{
+ //beginRTFSubSubSection();
+ t << "\n";
+ DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
+ t << "{" << endl;
+ t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
+}
+
+void RTFGenerator::endSubsubsection()
+{
+ newParagraph();
+ t << "}" << endl;
+}
+
+
+//void RTFGenerator::writeClassLink(const char *,const char *,
+// const char *,const char *name)
+//{
+// t << "{\\bf ";
+// docify(name);
+// t << "}";
+//}
+
+//void RTFGenerator::startTable(bool,int colNumbers)
+//{
+// DBG_RTF(t << "{\\comment startTable}\n";)
+// m_numCols=colNumbers;
+// t << "\\par\n";
+//}
+//
+//void RTFGenerator::endTable(bool hasCaption)
+//{
+// DBG_RTF(t << "{\\comment endTable}\n";)
+// if (!hasCaption)
+// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
+// t << "\\pard\n" << endl;
+//}
+//
+//void RTFGenerator::startCaption()
+//{
+// DBG_RTF(t << "{\\comment startCaption}\n";)
+// endTableRow();
+// t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
+// t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 \\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb \\cellx"<<rtf_pageWidth<<"\\pard \\qc\\nowidctlpar\\widctlpar\\intbl\\adjustright " << endl;
+// nextTableColumn();
+//}
+//
+//void RTFGenerator::endCaption()
+//{
+// DBG_RTF(t << "{\\comment endCaption}\n";)
+// endTableColumn();
+// endTableRow();
+//}
+//
+//void RTFGenerator::nextTableRow()
+//{
+// DBG_RTF(t << "{\\comment nextTableRow}\n";)
+// ASSERT(m_numCols>0 && m_numCols<25);
+// uint columnWidth=rtf_pageWidth/m_numCols;
+// t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
+// "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
+// "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
+// "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
+// for (int i=0;i<m_numCols;i++)
+// {
+// t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
+// "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
+// "\\cellx" << (i*columnWidth) << endl;
+// }
+// t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
+//}
+//
+//void RTFGenerator::endTableRow()
+//{
+// DBG_RTF(t << "{\\comment endTableRow}\n";)
+// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
+//}
+//
+//void RTFGenerator::nextTableColumn()
+//{
+// DBG_RTF(t << "{\\comment nextTableColumn}\n";)
+// t << "{ ";
+//}
+//
+//void RTFGenerator::endTableColumn()
+//{
+// DBG_RTF(t << "{\\comment endTableColumn}\n";)
+// t << " \\cell }";
+//}
+//
+void RTFGenerator::startTextLink(const char *f,const char *anchor)
+{
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ QCString ref;
+ if (f)
+ {
+ ref+=f;
+ }
+ if (anchor)
+ {
+ ref+='_';
+ ref+=anchor;
+ }
+
+ t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
+ t << rtfFormatBmkStr(ref);
+ t << "\" }{}";
+ t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+ }
+}
+
+void RTFGenerator::endTextLink()
+{
+ if (Config_getBool("RTF_HYPERLINKS"))
+ {
+ t << "}}}" << endl;
+ }
+}
+
+void RTFGenerator::writeObjectLink(const char *ref, const char *f,
+ const char *anchor, const char *text)
+{
+ if (!ref && Config_getBool("RTF_HYPERLINKS"))
+ {
+ QCString refName;
+ if (f)
+ {
+ refName+=f;
+ }
+ if (anchor)
+ {
+ refName+='_';
+ refName+=anchor;
+ }
+
+ t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
+ t << rtfFormatBmkStr(refName);
+ t << "\" }{}";
+ t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+ docify(text);
+
+ t << "}}}" << endl;
+ }
+ else
+ {
+ startBold();
+ docify(text);
+ endBold();
+ }
+}
+
+void RTFGenerator::startPageRef()
+{
+ t << " (";
+ startEmphasis();
+}
+
+void RTFGenerator::endPageRef(const char *clname, const char *anchor)
+{
+ QCString ref;
+ if (clname)
+ {
+ ref+=clname;
+ }
+ if (anchor)
+ {
+ ref+='_';
+ ref+=anchor;
+ }
+ writeRTFReference(ref);
+ endEmphasis();
+ t << ")";
+}
+
+void RTFGenerator::writeCodeLink(const char *ref,const char *f,
+ const char *anchor,const char *name,
+ const char *)
+{
+ if (!ref && Config_getBool("RTF_HYPERLINKS"))
+ {
+ QCString refName;
+ if (f)
+ {
+ refName+=f;
+ }
+ if (anchor)
+ {
+ refName+='_';
+ refName+=anchor;
+ }
+
+ t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
+ t << rtfFormatBmkStr(refName);
+ t << "\" }{}";
+ t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+ codify(name);
+
+ t << "}}}" << endl;
+ }
+ else
+ {
+ codify(name);
+ }
+}
+
+void RTFGenerator::startTitleHead(const char *)
+{
+ DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
+
+ // beginRTFSection();
+ t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
+}
+
+void RTFGenerator::endTitleHead(const char *fileName,const char *name)
+{
+ DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
+ t << "\\par " << rtf_Style_Reset << endl;
+ if (name)
+ {
+ // make table of contents entry
+ t << "{\\tc\\tcl2 \\v ";
+ docify(name);
+ t << "}" << endl;
+
+ // make an index entry
+ addIndexItem(name,0);
+
+ //if (name)
+ //{
+ // writeAnchor(0,name);
+ //}
+ //
+ //if (Config_getBool("RTF_HYPERLINKS") && fileName)
+ //{
+ writeAnchor(fileName,0);
+ //}
+ }
+}
+
+void RTFGenerator::startTitle()
+{
+ DBG_RTF(t <<"{\\comment startTitle}" << endl)
+ if (Config_getBool("COMPACT_RTF"))
+ beginRTFSection();
+ else
+ beginRTFChapter();
+}
+
+void RTFGenerator::startGroupHeader(int extraIndent)
+{
+ DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
+ //newParagraph();
+ t << rtf_Style_Reset;
+ if (extraIndent==2)
+ {
+ t << rtf_Style["Heading5"]->reference;
+ }
+ else if (extraIndent==1)
+ {
+ t << rtf_Style["Heading4"]->reference;
+ }
+ else // extraIndent==0
+ {
+ t << rtf_Style["Heading3"]->reference;
+ }
+ t << endl;
+}
+
+void RTFGenerator::endGroupHeader(int)
+{
+ DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
+ t << "\\par" << endl;
+ t << rtf_Style_Reset << endl;
+}
+
+void RTFGenerator::startMemberDoc(const char *clname,
+ const char *memname,
+ const char *,
+ const char *,
+ bool showInline)
+{
+ DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
+ if (memname && memname[0]!='@')
+ {
+ addIndexItem(memname,clname);
+ addIndexItem(clname,memname);
+ }
+ t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference;
+ //styleStack.push(rtf_Style_Heading4);
+ t << "{" << endl;
+ //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
+ startBold();
+ t << endl;
+}
+
+void RTFGenerator::endMemberDoc(bool)
+{
+ DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
+ //const char *style = styleStack.pop();
+ //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
+ //ASSERT(style==rtf_Style["Heading4"]->reference);
+ endBold();
+ t << "}" << endl;
+ newParagraph();
+}
+
+void RTFGenerator::startDoxyAnchor(const char *,const char *,
+ const char *,const char *,
+ const char *
+ )
+{
+ DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
+}
+
+void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
+{
+ QCString ref;
+ if (fName)
+ {
+ ref+=fName;
+ }
+ if (anchor)
+ {
+ ref+='_';
+ ref+=anchor;
+ }
+
+ DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
+ t << "{\\bkmkstart ";
+ t << rtfFormatBmkStr(ref);
+ t << "}" << endl;
+ t << "{\\bkmkend ";
+ t << rtfFormatBmkStr(ref);
+ t << "}" << endl;
+}
+
+
+//void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
+//{
+// writeDoxyAnchor(0,clName,anchor,0);
+//}
+
+void RTFGenerator::addIndexItem(const char *s1,const char *s2)
+{
+ if (s1)
+ {
+ t << "{\\xe \\v ";
+ docify(s1);
+ if (s2)
+ {
+ t << "\\:";
+ docify(s2);
+ }
+ t << "}" << endl;
+ }
+}
+
+void RTFGenerator::startIndent()
+{
+ incrementIndentLevel();
+ DBG_RTF(t << "{\\comment (startIndent) }" << endl)
+ t << "{" << endl;
+ t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endIndent()
+{
+ t << "}" << endl;
+ decrementIndentLevel();
+}
+
+
+void RTFGenerator::startDescription()
+{
+ DBG_RTF(t << "{\\comment (startDescription)}" << endl)
+ t << "{" << endl;
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endDescription()
+{
+ DBG_RTF(t << "{\\comment (endDescription)}" << endl)
+ newParagraph();
+ t << "}";
+}
+
+void RTFGenerator::startDescItem()
+{
+ newParagraph();
+ DBG_RTF(t << "{\\comment (startDescItem)}" << endl)
+ t << "{\\b ";
+}
+
+void RTFGenerator::endDescItem()
+{
+ DBG_RTF(t << "{\\comment (endDescItem)}" << endl)
+ t << "}" << endl;
+ newParagraph();
+}
+
+void RTFGenerator::startMemberDescription(const char *,const char *)
+{
+ DBG_RTF(t << "{\\comment (startMemberDescription)}" << endl)
+ t << "{" << endl;
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_CList_DepthStyle();
+ startEmphasis();
+}
+
+void RTFGenerator::endMemberDescription()
+{
+ DBG_RTF(t << "{\\comment (endMemberDescription)}" << endl)
+ endEmphasis();
+ newParagraph();
+ decrementIndentLevel();
+ //t << "\\par";
+ t << "}" << endl;
+ //m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::startDescList(SectionTypes)
+{
+ DBG_RTF(t << "{\\comment (startDescList)}" << endl)
+ t << "{"; // ends at endDescList
+ t << "{"; // ends at endDescTitle
+ startBold();
+ newParagraph();
+}
+
+//void RTFGenerator::endDescTitle()
+//{
+// DBG_RTF(t << "{\\comment (endDescTitle) }" << endl)
+// endBold();
+// t << "}";
+// newParagraph();
+// incrementIndentLevel();
+// t << rtf_Style_Reset << rtf_DList_DepthStyle();
+//}
+
+void RTFGenerator::startDescForItem()
+{
+ DBG_RTF(t << "{\\comment (startDescForItem) }" << endl)
+}
+
+void RTFGenerator::endDescForItem()
+{
+ DBG_RTF(t << "{\\comment (endDescForItem) }" << endl)
+}
+
+//void RTFGenerator::endDescList()
+//{
+// DBG_RTF(t << "{\\comment (endDescList)}" << endl)
+// newParagraph();
+// decrementIndentLevel();
+// m_omitParagraph = TRUE;
+// t << "}";
+//}
+
+
+void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
+{
+ DBG_RTF(t << "{\\comment (startSection)}" << endl)
+ t << "{";
+ t<< rtf_Style_Reset;
+ int num=4;
+ switch(type)
+ {
+ case SectionInfo::Page: num=2; break;
+ case SectionInfo::Section: num=3; break;
+ case SectionInfo::Subsection: num=4; break;
+ case SectionInfo::Subsubsection: num=4; break;
+ case SectionInfo::Paragraph: num=4; break;
+ default: ASSERT(0); break;
+ }
+ QCString heading;
+ heading.sprintf("Heading%d",num);
+ // set style
+ t << rtf_Style[heading]->reference;
+ // make table of contents entry
+ t << "{\\tc\\tcl" << num << " \\v ";
+ docify(title);
+ t << "}" << endl;
+}
+
+void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
+{
+ DBG_RTF(t << "{\\comment (endSection)}" << endl)
+ // make bookmark
+ m_omitParagraph=FALSE;
+ newParagraph();
+ writeAnchor(0,lab);
+ t << "}";
+}
+
+//void RTFGenerator::writeSectionRef(const char *ref,const char *,
+// const char *lab,const char *title)
+//{
+// if (ref)
+// {
+// docify(title);
+// }
+// else
+// {
+// startBold();
+// docify(title);
+// endBold();
+// t << " (";
+// docify(theTranslator->trPageAbbreviation());
+// writeRTFReference(lab);
+// t << ")" << endl;
+// }
+//}
+//
+//void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
+// const char *title)
+//{
+// docify(title);
+// t << "\\tab";
+// writeRTFReference(lab);
+// t << endl;
+//}
+//
+//void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
+// const char *title)
+//{
+// writeSectionRef(name,lab,title);
+//}
+
+//char* RTFGenerator::getMultiByte(int c)
+//{
+// static char s[10];
+//
+// sprintf(s,"\\'%X",c);
+// return s;
+//}
+
+void RTFGenerator::docify(const char *str)
+{
+ if (str)
+ {
+ const unsigned char *p=(const unsigned char *)str;
+ unsigned char c;
+ //unsigned char pc='\0';
+ while (*p)
+ {
+ //static bool MultiByte = FALSE;
+ c=*p++;
+
+#if 0
+ if ( MultiByte )
+ {
+ t << getMultiByte( c );
+ MultiByte = FALSE;
+ continue;
+ }
+ if ( c >= 0x80 )
+ {
+ MultiByte = TRUE;
+ t << getMultiByte( c );
+ continue;
+ }
+#endif
+
+ switch (c)
+ {
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '\\': t << "\\\\"; break;
+ default:
+ {
+ // see if we can insert an hyphenation hint
+ //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
+ t << (char)c;
+ }
+ }
+ //pc = c;
+ m_omitParagraph = FALSE;
+ }
+ }
+}
+
+void RTFGenerator::codify(const char *str)
+{
+ // note that RTF does not have a "verbatim", so "\n" means
+ // nothing... add a "newParagraph()";
+ //static char spaces[]=" ";
+ if (str)
+ {
+ const unsigned char *p=(const unsigned char *)str;
+ unsigned char c;
+ int spacesToNextTabStop;
+
+ while (*p)
+ {
+ //static bool MultiByte = FALSE;
+
+ c=*p++;
+
+ switch(c)
+ {
+ case '\t': spacesToNextTabStop = Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
+ t << Doxygen::spaces.left(spacesToNextTabStop);
+ col+=spacesToNextTabStop;
+ break;
+ case '\n': newParagraph();
+ t << '\n'; col=0;
+ break;
+ case '{': t << "\\{"; col++; break;
+ case '}': t << "\\}"; col++; break;
+ case '\\': t << "\\\\"; col++; break;
+ default: p=(const unsigned char *)writeUtf8Char(t,(const char *)p-1); col++; break;
+ }
+ }
+ }
+}
+
+void RTFGenerator::writeChar(char c)
+{
+ char cs[2];
+ cs[0]=c;
+ cs[1]=0;
+ docify(cs);
+}
+
+void RTFGenerator::startClassDiagram()
+{
+ DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
+}
+
+void RTFGenerator::endClassDiagram(const ClassDiagram &d,
+ const char *fileName,const char *)
+{
+ newParagraph();
+
+ // create a png file
+ d.writeImage(t,dir,relPath,fileName,FALSE);
+
+ // display the file
+ t << "{" << endl;
+ t << rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ t << fileName << ".png\"";
+ t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
+}
+
+//void RTFGenerator::writeFormula(const char *,const char *text)
+//{
+// t << text;
+//}
+
+void RTFGenerator::startMemberItem(const char *,int,const char *)
+{
+ DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
+ t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to appropriate depth
+}
+
+void RTFGenerator::endMemberItem()
+{
+ DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
+ newParagraph();
+}
+
+void RTFGenerator::writeAnchor(const char *fileName,const char *name)
+{
+ QCString anchor;
+ if (fileName)
+ {
+ anchor+=fileName;
+ }
+ if (fileName && name)
+ {
+ anchor+='_';
+ }
+ if (name)
+ {
+ anchor+=name;
+ }
+
+ DBG_RTF(t <<"{\\comment writeAnchor (" << anchor << ")}" << endl)
+ t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
+ t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
+}
+
+void RTFGenerator::writeRTFReference(const char *label)
+{
+ t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
+ t << rtfFormatBmkStr(label);
+ t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
+}
+
+void RTFGenerator::startCodeFragment()
+{
+ DBG_RTF(t << "{\\comment (startCodeFragment) }" << endl)
+ t << "{" << endl;
+ //newParagraph();
+ t << rtf_Style_Reset << rtf_Code_DepthStyle();
+ //styleStack.push(rtf_Style_CodeExample);
+}
+
+void RTFGenerator::endCodeFragment()
+{
+ //newParagraph();
+ //styleStack.pop();
+ //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
+ //t << rtf_Style_Reset << styleStack.top() << endl;
+ DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl)
+ t << "}" << endl;
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::writeNonBreakableSpace(int)
+{
+ t << "\\~ ";
+}
+
+
+void RTFGenerator::startMemberList()
+{
+ t << endl;
+ DBG_RTF(t << "{\\comment (startMemberList) }" << endl)
+ t << "{" << endl;
+#ifdef DELETEDCODE
+ if (!insideTabbing)
+ t << "\\begin{CompactItemize}" << endl;
+#endif
+}
+
+void RTFGenerator::endMemberList()
+{
+ DBG_RTF(t << "{\\comment (endMemberList) }" << endl)
+ t << "}" << endl;
+#ifdef DELETEDCODE
+ if (!insideTabbing)
+ t << "\\end{CompactItemize}" << endl;
+#endif
+}
+
+//void RTFGenerator::startImage(const char *name,const char *,bool)
+//{
+// newParagraph();
+// t << "{" << endl;
+// t << rtf_Style_Reset << endl;
+// t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+// t << name;
+// t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+// t << "}" << endl;
+//}
+//
+//void RTFGenerator::endImage(bool)
+//{
+// // not yet implemented
+//}
+//
+//void RTFGenerator::startDotFile(const char *name,bool)
+//{
+// QCString baseName=name;
+// int i;
+// if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+// {
+// baseName=baseName.right(baseName.length()-i-1);
+// }
+// QCString outDir = Config_getString("RTF_OUTPUT");
+// writeDotGraphFromFile(name,outDir,baseName,BITMAP);
+// newParagraph();
+// t << "{" << endl;
+// t << rtf_Style_Reset << endl;
+// t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+// t << outDir << "\\" << baseName;
+// t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+// t << "}" << endl;
+//}
+//
+//void RTFGenerator::endDotFile(bool)
+//{
+// // not yet implemented
+//}
+//
+void RTFGenerator::startDescTable(const char *title)
+{
+ DBG_RTF(t << "{\\comment (startDescTable) }" << endl)
+ startSimpleSect(EnumValues,0,0,title);
+ startDescForItem();
+ //t << "{" << endl;
+ //incrementIndentLevel();
+ //t << rtf_Style_Reset << rtf_CList_DepthStyle();
+}
+
+void RTFGenerator::endDescTable()
+{
+ //decrementIndentLevel();
+ DBG_RTF(t << "{\\comment (endDescTable)}" << endl)
+ endDescForItem();
+ endSimpleSect();
+ //t << "}" << endl;
+ //t << rtf_Style_Reset << styleStack.top();
+}
+
+void RTFGenerator::startDescTableTitle()
+{
+ //t << rtf_BList_DepthStyle() << endl;
+ DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl)
+ startBold();
+ startEmphasis();
+}
+
+void RTFGenerator::endDescTableTitle()
+{
+ DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl)
+ endEmphasis();
+ endBold();
+ t << " ";
+}
+
+void RTFGenerator::startDescTableData()
+{
+ DBG_RTF(t << "{\\comment (startDescTableData) }" << endl)
+ m_omitParagraph = FALSE;
+}
+
+void RTFGenerator::endDescTableData()
+{
+ DBG_RTF(t << "{\\comment (endDescTableData) }" << endl)
+ newParagraph();
+ m_omitParagraph = TRUE;
+}
+
+// a style for list formatted as a "bulleted list"
+
+void RTFGenerator::incrementIndentLevel()
+{
+ m_listLevel++;
+ if (m_listLevel>rtf_maxIndentLevels-1)
+ {
+ err("Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
+ m_listLevel=rtf_maxIndentLevels-1;
+ }
+}
+
+void RTFGenerator::decrementIndentLevel()
+{
+ m_listLevel--;
+ if (m_listLevel<0)
+ {
+ err("Negative indent level while generating RTF output!\n");
+ m_listLevel=0;
+ }
+}
+
+// a style for list formatted with "list continue" style
+const char * RTFGenerator::rtf_CList_DepthStyle()
+{
+ QCString n=makeIndexName("ListContinue",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "latext style" table of contents
+const char * RTFGenerator::rtf_LCList_DepthStyle()
+{
+ QCString n=makeIndexName("LatexTOC",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "bullet" style
+const char * RTFGenerator::rtf_BList_DepthStyle()
+{
+ QCString n=makeIndexName("ListBullet",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "enumeration" style
+const char * RTFGenerator::rtf_EList_DepthStyle()
+{
+ QCString n=makeIndexName("ListEnum",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+const char * RTFGenerator::rtf_DList_DepthStyle()
+{
+ QCString n=makeIndexName("DescContinue",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+const char * RTFGenerator::rtf_Code_DepthStyle()
+{
+ QCString n=makeIndexName("CodeExample",m_listLevel);
+ return rtf_Style[n]->reference;
+}
+
+void RTFGenerator::startTextBlock(bool dense)
+{
+ DBG_RTF(t << "{\\comment startTextBlock}" << endl)
+ t << "{" << endl;
+ t << rtf_Style_Reset;
+ if (dense) // no spacing between "paragraphs"
+ {
+ t << rtf_Style["DenseText"]->reference;
+ }
+ else // some spacing
+ {
+ t << rtf_Style["BodyText"]->reference;
+ }
+}
+
+void RTFGenerator::endTextBlock(bool /*paraBreak*/)
+{
+ newParagraph();
+ DBG_RTF(t << "{\\comment endTextBlock}" << endl)
+ t << "}" << endl;
+ //m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::newParagraph()
+{
+ if (!m_omitParagraph)
+ {
+ DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
+ t << "\\par" << endl;
+ }
+ m_omitParagraph = FALSE;
+}
+
+void RTFGenerator::startParagraph()
+{
+ DBG_RTF(t << "{\\comment startParagraph}" << endl)
+ newParagraph();
+ t << "{" << endl;
+}
+
+void RTFGenerator::endParagraph()
+{
+ DBG_RTF(t << "{\\comment endParagraph}" << endl)
+ t << "}\\par" << endl;
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::startMemberSubtitle()
+{
+ DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
+ t << "{" << endl;
+ t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endMemberSubtitle()
+{
+ DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
+ newParagraph();
+ t << "}" << endl;
+}
+
+//void RTFGenerator::writeUmlaut(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\304'; break;
+// case 'E' : t << '\313'; break;
+// case 'I' : t << '\317'; break;
+// case 'O' : t << '\326'; break;
+// case 'U' : t << '\334'; break;
+// case 'Y' : t << 'Y'; break;
+// case 'a' : t << '\344'; break;
+// case 'e' : t << '\353'; break;
+// case 'i' : t << '\357'; break;
+// case 'o' : t << '\366'; break;
+// case 'u' : t << '\374'; break;
+// case 'y' : t << '\377'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeAcute(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\301'; break;
+// case 'E' : t << '\311'; break;
+// case 'I' : t << '\315'; break;
+// case 'O' : t << '\323'; break;
+// case 'U' : t << '\332'; break;
+// case 'Y' : t << '\335'; break;
+// case 'a' : t << '\341'; break;
+// case 'e' : t << '\351'; break;
+// case 'i' : t << '\355'; break;
+// case 'o' : t << '\363'; break;
+// case 'u' : t << '\372'; break;
+// case 'y' : t << '\375'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeGrave(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\300'; break;
+// case 'E' : t << '\310'; break;
+// case 'I' : t << '\314'; break;
+// case 'O' : t << '\322'; break;
+// case 'U' : t << '\331'; break;
+// case 'a' : t << '\340'; break;
+// case 'e' : t << '\350'; break;
+// case 'i' : t << '\354'; break;
+// case 'o' : t << '\362'; break;
+// case 'u' : t << '\371'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeCirc(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\302'; break;
+// case 'E' : t << '\312'; break;
+// case 'I' : t << '\316'; break;
+// case 'O' : t << '\324'; break;
+// case 'U' : t << '\333'; break;
+// case 'a' : t << '\342'; break;
+// case 'e' : t << '\352'; break;
+// case 'i' : t << '\356'; break;
+// case 'o' : t << '\364'; break;
+// case 'u' : t << '\373'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeTilde(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\303'; break;
+// case 'N' : t << '\321'; break;
+// case 'O' : t << '\325'; break;
+// case 'a' : t << '\343'; break;
+// case 'n' : t << '\361'; break;
+// case 'o' : t << '\365'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeRing(char c)
+//{
+// switch(c)
+// {
+// case 'A' : t << '\305'; break;
+// case 'a' : t << '\345'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+//void RTFGenerator::writeCCedil(char c)
+//{
+// switch(c)
+// {
+// case 'C' : t << '\307'; break;
+// case 'c' : t << '\347'; break;
+// default: t << '?'; break;
+// }
+//}
+//
+
+bool isLeadBytes(int c)
+{
+ bool result;
+
+ QCString codePage = theTranslator->trRTFansicp();
+
+ if (codePage == "932") // cp932 (Japanese Shift-JIS)
+ {
+ result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
+ }
+ else if (codePage == "936") // cp936 (Simplified Chinese GBK)
+ {
+ result = 0x81<=c && c<=0xFE;
+ }
+ else if (codePage == "949") // cp949 (Korean)
+ {
+ result = 0x81<=c && c<=0xFE;
+ }
+ else if (codePage == "950") // cp950 (Traditional Chinese Big5)
+ {
+ result = 0x81<=c && c<=0xFE;
+ }
+ else // for SBCS Codepages (cp1252,1251 etc...)
+ {
+ result = false;
+ }
+
+ return result;
+}
+
+
+// note: function is not reentrant!
+static void encodeForOutput(FTextStream &t,const QCString &s)
+{
+ QCString encoding;
+ bool converted=FALSE;
+ int l = s.length();
+ static QByteArray enc;
+ if (l*4>(int)enc.size()) enc.resize(l*4); // worst case
+ encoding.sprintf("CP%s",theTranslator->trRTFansicp().data());
+ if (!encoding.isEmpty())
+ {
+ // convert from UTF-8 back to the output encoding
+ void *cd = portable_iconv_open(encoding,"UTF-8");
+ if (cd!=(void *)(-1))
+ {
+ size_t iLeft=l;
+ size_t oLeft=enc.size();
+ char *inputPtr = s.data();
+ char *outputPtr = enc.data();
+ if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
+ {
+ enc.resize(enc.size()-(unsigned int)oLeft);
+ converted=TRUE;
+ }
+ portable_iconv_close(cd);
+ }
+ }
+ if (!converted) // if we did not convert anything, copy as is.
+ {
+ memcpy(enc.data(),s.data(),l);
+ enc.resize(l);
+ }
+ uint i;
+ bool multiByte = FALSE;
+
+ for (i=0;i<enc.size();i++)
+ {
+ uchar c = (uchar)enc.at(i);
+
+ if (c>=0x80 || multiByte)
+ {
+ char esc[10];
+ sprintf(esc,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
+ t << esc;
+
+ if (!multiByte)
+ {
+ multiByte = isLeadBytes(c); // It may be DBCS Codepages.
+ }
+ else
+ {
+ multiByte = FALSE; // end of Double Bytes Character.
+ }
+ }
+ else
+ {
+ t << (char)c;
+ }
+ }
+}
+
+/**
+ * VERY brittle routine inline RTF's included by other RTF's.
+ * it is recursive and ugly.
+ */
+static bool preProcessFile(QDir &d,QCString &infName, FTextStream &t, bool bIncludeHeader=TRUE)
+{
+ QFile f(infName);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("problems opening rtf file %s for reading\n",infName.data());
+ return FALSE;
+ }
+
+ const int maxLineLength = 10240;
+ static QCString lineBuf(maxLineLength);
+
+ // scan until find end of header
+ // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
+ // files because the first line before the body
+ // ALWAYS contains "{\comment begin body}"
+ do
+ {
+ if (f.readLine(lineBuf.data(),maxLineLength)==-1)
+ {
+ err("read error in %s before end of RTF header!\n",infName.data());
+ return FALSE;
+ }
+ if (bIncludeHeader) encodeForOutput(t,lineBuf);
+ } while (lineBuf.find("\\comment begin body")==-1);
+
+
+ while (f.readLine(lineBuf.data(),maxLineLength)!=-1)
+ {
+ int pos;
+ if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
+ {
+ int startNamePos = lineBuf.find('"',pos)+1;
+ int endNamePos = lineBuf.find('"',startNamePos);
+ QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
+ DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
+ if (!preProcessFile(d,fileName,t,FALSE)) return FALSE;
+ DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
+ }
+ else // no INCLUDETEXT on this line
+ {
+ // elaborate hoopla to skip the final "}" if we didn't include the
+ // headers
+ if (!f.atEnd() || bIncludeHeader)
+ {
+ encodeForOutput(t,lineBuf);
+ }
+ else // last line of included file
+ {
+ // null terminate at the last '}'
+ //char *str = strrchr(buffer,'}');
+ int pos = lineBuf.findRev('}');
+
+ if (pos != -1)
+ lineBuf.at(pos) = '\0';
+ else
+ err("Strange, the last char was not a '}'\n");
+ encodeForOutput(t,lineBuf);
+ }
+ }
+ }
+ f.close();
+ // remove temporary file
+ d.remove(infName);
+ return TRUE;
+}
+
+void RTFGenerator::startDotGraph()
+{
+ DBG_RTF(t << "{\\comment (startDotGraph)}" << endl)
+}
+
+void RTFGenerator::endDotGraph(const DotClassGraph &g)
+{
+ newParagraph();
+
+ QCString fn =
+ g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString("RTF_OUTPUT"),fileName,relPath,TRUE,FALSE);
+
+ // display the file
+ t << "{" << endl;
+ t << rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+ t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
+ newParagraph();
+ DBG_RTF(t << "{\\comment (endDotGraph)}" << endl)
+}
+
+void RTFGenerator::startInclDepGraph()
+{
+ DBG_RTF(t << "{\\comment (startInclDepGraph)}" << endl)
+}
+
+void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
+{
+ newParagraph();
+
+ QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString("RTF_OUTPUT"),
+ fileName,relPath,FALSE);
+
+ // display the file
+ t << "{" << endl;
+ t << rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+ t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
+ DBG_RTF(t << "{\\comment (endInclDepGraph)}" << endl)
+}
+
+void RTFGenerator::startGroupCollaboration()
+{
+}
+
+void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
+{
+}
+
+void RTFGenerator::startCallGraph()
+{
+ DBG_RTF(t << "{\\comment (startCallGraph)}" << endl)
+}
+
+void RTFGenerator::endCallGraph(const DotCallGraph &g)
+{
+ newParagraph();
+
+ QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString("RTF_OUTPUT"),
+ fileName,relPath,FALSE);
+
+ // display the file
+ t << "{" << endl;
+ t << rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+ t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
+ DBG_RTF(t << "{\\comment (endCallGraph)}" << endl)
+}
+
+void RTFGenerator::startDirDepGraph()
+{
+ DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl)
+}
+
+void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
+{
+ newParagraph();
+
+ QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString("RTF_OUTPUT"),
+ fileName,relPath,FALSE);
+
+ // display the file
+ t << "{" << endl;
+ t << rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+ t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+ t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
+ DBG_RTF(t << "{\\comment (endDirDepGraph)}" << endl)
+}
+
+/** Tests the integrity of the result by counting brackets.
+ *
+ */
+void testRTFOutput(const char *name)
+{
+ int bcount=0;
+ int line=1;
+ int c;
+ QFile f(name);
+ if (f.open(IO_ReadOnly))
+ {
+ while ((c=f.getch())!=-1)
+ {
+ if (c=='\\') // escape char
+ {
+ c=f.getch();
+ if (c==-1) break;
+ }
+ else if (c=='{') // open bracket
+ {
+ bcount++;
+ }
+ else if (c=='}') // close bracket
+ {
+ bcount--;
+ if (bcount<0)
+ {
+ goto err;
+ break;
+ }
+ }
+ else if (c=='\n') // newline
+ {
+ line++;
+ }
+ }
+ }
+ if (bcount==0) return; // file is OK.
+err:
+ err("RTF integrity test failed at line %d of %s due to a bracket mismatch.\n"
+ " Please try to create a small code example that produces this error \n"
+ " and send that to dimitri at stack.nl.\n",line,name);
+}
+
+/**
+ * This is an API to a VERY brittle RTF preprocessor that combines nested
+ * RTF files. This version replaces the infile with the new file
+ */
+bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
+{
+ QDir d(path);
+ // store the original directory
+ if (!d.exists())
+ {
+ err("Output dir %s does not exist!\n",path);
+ return FALSE;
+ }
+ QCString oldDir = QDir::currentDirPath().utf8();
+
+ // go to the html output directory (i.e. path)
+ QDir::setCurrent(d.absPath());
+ QDir thisDir;
+
+ QCString combinedName = (QCString)path+"/combined.rtf";
+ QCString mainRTFName = (QCString)path+"/"+name;
+
+ QFile outf(combinedName);
+ if (!outf.open(IO_WriteOnly))
+ {
+ err("Failed to open %s for writing!\n",combinedName.data());
+ return FALSE;
+ }
+ FTextStream outt(&outf);
+
+ if (!preProcessFile(thisDir,mainRTFName,outt))
+ {
+ // it failed, remove the temp file
+ outf.close();
+ thisDir.remove(combinedName);
+ QDir::setCurrent(oldDir);
+ return FALSE;
+ }
+
+ // everything worked, move the files
+ outf.close();
+ thisDir.remove(mainRTFName);
+ thisDir.rename(combinedName,mainRTFName);
+
+ testRTFOutput(mainRTFName);
+
+ QDir::setCurrent(oldDir);
+ return TRUE;
+}
+
+void RTFGenerator::startMemberGroupHeader(bool hasHeader)
+{
+ DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
+ t << "{" << endl;
+ if (hasHeader) incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
+}
+
+void RTFGenerator::endMemberGroupHeader()
+{
+ DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
+ newParagraph();
+ t << rtf_Style_Reset << rtf_CList_DepthStyle();
+}
+
+void RTFGenerator::startMemberGroupDocs()
+{
+ DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
+ startEmphasis();
+}
+
+void RTFGenerator::endMemberGroupDocs()
+{
+ DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
+ endEmphasis();
+ newParagraph();
+}
+
+void RTFGenerator::startMemberGroup()
+{
+ DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
+ t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endMemberGroup(bool hasHeader)
+{
+ DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
+ if (hasHeader) decrementIndentLevel();
+ t << "}";
+}
+
+void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title)
+{
+ DBG_RTF(t << "{\\comment (startSimpleSect)}" << endl)
+ t << "{"; // ends at endDescList
+ t << "{"; // ends at endDescTitle
+ startBold();
+ newParagraph();
+ if (file)
+ {
+ writeObjectLink(0,file,anchor,title);
+ }
+ else
+ {
+ docify(title);
+ }
+ endBold();
+ t << "}";
+ newParagraph();
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endSimpleSect()
+{
+ DBG_RTF(t << "{\\comment (endSimpleSect)}" << endl)
+ newParagraph();
+ decrementIndentLevel();
+ m_omitParagraph = TRUE;
+ t << "}";
+}
+
+void RTFGenerator::startParamList(ParamListTypes,const char *title)
+{
+ DBG_RTF(t << "{\\comment (startParamList)}" << endl)
+ t << "{"; // ends at endParamList
+ t << "{"; // ends at endDescTitle
+ startBold();
+ newParagraph();
+ docify(title);
+ endBold();
+ t << "}";
+ newParagraph();
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endParamList()
+{
+ DBG_RTF(t << "{\\comment (endParamList)}" << endl)
+ newParagraph();
+ decrementIndentLevel();
+ m_omitParagraph = TRUE;
+ t << "}";
+}
+
+void RTFGenerator::startParameterType(bool first,const char *key)
+{
+ DBG_RTF(t << "{\\comment (startParameterType)}" << endl)
+ if (!first && key)
+ {
+ t << " " << key << " ";
+ }
+}
+
+void RTFGenerator::endParameterType()
+{
+ DBG_RTF(t << "{\\comment (endParameterType)}" << endl)
+ t << " ";
+}
+
+void RTFGenerator::exceptionEntry(const char* prefix,bool closeBracket)
+{
+ DBG_RTF(t << "{\\comment (exceptionEntry)}" << endl)
+ if (prefix)
+ t << " " << prefix;
+ else if (closeBracket)
+ t << ")";
+ t << " ";
+}
+
+void RTFGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
+{
+ RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""));
+ n->accept(visitor);
+ delete visitor;
+ m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::rtfwriteRuler_doubleline()
+{
+ DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}" << endl)
+ t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
+}
+
+void RTFGenerator::rtfwriteRuler_emboss()
+{
+ DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}" << endl)
+ t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
+}
+
+void RTFGenerator::rtfwriteRuler_thick()
+{
+ DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}" << endl)
+ t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl;
+}
+
+void RTFGenerator::rtfwriteRuler_thin()
+{
+ DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}" << endl)
+ t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
+}
+
+#if 0
+void RTFGenerator::postProcess(QByteArray &a)
+{
+ QByteArray enc(a.size()*4); // worst case
+ int off=0;
+ uint i;
+ bool mbFlag=FALSE;
+ for (i=0;i<a.size();i++)
+ {
+ unsigned char c = (unsigned char)a.at(i);
+
+ // treat characters > 0x80 as multibyte characters, except when they
+ // are control characters
+ if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}'))
+ {
+ char s[10];
+ sprintf(s,"\\'%X",c);
+ qstrcpy(enc.data()+off,s);
+ off+=qstrlen(s);
+ mbFlag=c>0x80;
+ }
+ else
+ {
+ enc.at(off++)=c;
+ }
+ }
+ enc.resize(off);
+ a = enc;
+}
+#endif
+
+void RTFGenerator::startConstraintList(const char *header)
+{
+ DBG_RTF(t << "{\\comment (startConstraintList)}" << endl)
+ t << "{"; // ends at endConstraintList
+ t << "{";
+ startBold();
+ newParagraph();
+ docify(header);
+ endBold();
+ t << "}";
+ newParagraph();
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::startConstraintParam()
+{
+ DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl)
+ startEmphasis();
+}
+
+void RTFGenerator::endConstraintParam()
+{
+ DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl)
+ endEmphasis();
+ t << " : ";
+}
+
+void RTFGenerator::startConstraintType()
+{
+ DBG_RTF(t << "{\\comment (startConstraintType)}" << endl)
+ startEmphasis();
+}
+
+void RTFGenerator::endConstraintType()
+{
+ DBG_RTF(t << "{\\comment (endConstraintType)}" << endl)
+ endEmphasis();
+ t << " ";
+}
+
+void RTFGenerator::startConstraintDocs()
+{
+ DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl)
+}
+
+void RTFGenerator::endConstraintDocs()
+{
+ DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl)
+ newParagraph();
+}
+
+void RTFGenerator::endConstraintList()
+{
+ DBG_RTF(t << "{\\comment (endConstraintList)}" << endl)
+ newParagraph();
+ decrementIndentLevel();
+ m_omitParagraph = TRUE;
+ t << "}";
+}
+
+void RTFGenerator::startIndexListItem()
+{
+ DBG_RTF(t << "{\\comment (startIndexListItem)}" << endl)
+}
+
+void RTFGenerator::endIndexListItem()
+{
+ DBG_RTF(t << "{\\comment (endIndexListItem)}" << endl)
+ t << "\\par" << endl;
+}
+
+void RTFGenerator::startInlineHeader()
+{
+ DBG_RTF(t << "{\\comment (startInlineHeader)}" << endl)
+ t << "{" << endl;
+ t << rtf_Style_Reset << rtf_Style["Heading5"]->reference;
+ startBold();
+}
+
+void RTFGenerator::endInlineHeader()
+{
+ DBG_RTF(t << "{\\comment (endInlineHeader)}" << endl)
+ endBold();
+ t << "\\par";
+ t << "}" << endl;
+}
+
+void RTFGenerator::startMemberDocSimple()
+{
+ DBG_RTF(t << "{\\comment (startMemberDocSimple)}" << endl)
+ t << "{\\par" << endl;
+ t << "{" << rtf_Style["Heading5"]->reference << endl;
+ t << theTranslator->trCompoundMembers() << ":\\par}" << endl;
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+ t << "\\trowd \\trgaph108\\trleft426\\tblind426"
+ "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
+ "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
+ int i,columnPos[3] = { 25, 50, 100 };
+ for (i=0;i<3;i++)
+ {
+ t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
+ "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
+ "\\cltxlrtb "
+ "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << endl;
+ }
+ t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+}
+
+void RTFGenerator::endMemberDocSimple()
+{
+ DBG_RTF(t << "{\\comment (endMemberDocSimple)}" << endl)
+ t << "}" << endl;
+}
+
+void RTFGenerator::startInlineMemberType()
+{
+ DBG_RTF(t << "{\\comment (startInlineMemberType)}" << endl)
+ t << "{\\qr ";
+}
+
+void RTFGenerator::endInlineMemberType()
+{
+ DBG_RTF(t << "{\\comment (endInlineMemberType)}" << endl)
+ t << "\\cell }";
+}
+
+void RTFGenerator::startInlineMemberName()
+{
+ DBG_RTF(t << "{\\comment (startInlineMemberName)}" << endl)
+ t << "{";
+}
+
+void RTFGenerator::endInlineMemberName()
+{
+ DBG_RTF(t << "{\\comment (endInlineMemberName)}" << endl)
+ t << "\\cell }";
+}
+
+void RTFGenerator::startInlineMemberDoc()
+{
+ DBG_RTF(t << "{\\comment (startInlineMemberDoc)}" << endl)
+ t << "{";
+}
+
+void RTFGenerator::endInlineMemberDoc()
+{
+ DBG_RTF(t << "{\\comment (endInlineMemberDoc)}" << endl)
+ t << "\\cell }{\\row }" << endl;
+}
+
+void RTFGenerator::startLabels()
+{
+}
+
+void RTFGenerator::writeLabel(const char *l,bool isLast)
+{
+ t << "{\\f2 [" << l << "]}";
+ if (!isLast) t << ", ";
+}
+
+void RTFGenerator::endLabels()
+{
+}
+
+
+
diff --git a/src/rtfgen.h b/src/rtfgen.h
new file mode 100644
index 0000000..7b31673
--- /dev/null
+++ b/src/rtfgen.h
@@ -0,0 +1,298 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Parker Waechter & Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef RTFGEN_H
+#define RTFGEN_H
+
+#include "outputgen.h"
+
+class QFile;
+
+/** Generator for RTF output. */
+class RTFGenerator : public OutputGenerator
+{
+ public:
+ RTFGenerator();
+ ~RTFGenerator();
+ static void init();
+ static void writeStyleSheetFile(QFile &f);
+ static void writeExtensionsFile(QFile &file);
+
+ void enable()
+ { if (genStack->top()) active=*genStack->top(); else active=TRUE; }
+ void disable() { active=FALSE; }
+ void enableIf(OutputType o) { if (o==RTF) enable(); }
+ void disableIf(OutputType o) { if (o==RTF) disable(); }
+ void disableIfNot(OutputType o) { if (o!=RTF) disable(); }
+ bool isEnabled(OutputType o) { return (o==RTF && active); }
+ OutputGenerator *get(OutputType o) { return (o==RTF) ? this : 0; }
+
+ void writeDoc(DocNode *,Definition *,MemberDef *);
+
+ void startFile(const char *name,const char *manName,const char *title);
+ void writeSearchInfo() {}
+ void writeFooter(const char *) {}
+ void endFile();
+ void clearBuffer();
+ //void postProcess(QByteArray &);
+
+ void startIndexSection(IndexSections);
+ void endIndexSection(IndexSections);
+ void writePageLink(const char *,bool);
+ void startProjectNumber();
+ void endProjectNumber();
+ void writeStyleInfo(int part);
+ void startTitleHead(const char *);
+ void startTitle();
+ void endTitleHead(const char *,const char *name);
+ void endTitle() {}
+
+ void newParagraph();
+ void startParagraph();
+ void endParagraph();
+ void writeString(const char *text);
+ void startIndexListItem();
+ void endIndexListItem();
+ void startIndexList();
+ void endIndexList();
+ void startIndexKey();
+ void endIndexKey();
+ void startIndexValue(bool);
+ void endIndexValue(const char *,bool);
+ void startItemList();
+ void endItemList();
+ void startIndexItem(const char *ref,const char *file);
+ void endIndexItem(const char *ref,const char *file);
+ void docify(const char *text);
+ void codify(const char *text);
+ void writeObjectLink(const char *ref,const char *file,
+ const char *anchor,const char *name);
+ void writeCodeLink(const char *ref, const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ ) {}
+ void startTextLink(const char *f,const char *anchor);
+ void endTextLink();
+ void startHtmlLink(const char *url);
+ void endHtmlLink();
+ void startTypewriter() { t << "{\\f2 "; }
+ void endTypewriter() { t << "}"; }
+ void startGroupHeader(int);
+ void endGroupHeader(int);
+ //void writeListItem();
+ void startItemListItem();
+ void endItemListItem();
+
+ void startMemberSections() {}
+ void endMemberSections() {}
+ void startHeaderSection() {}
+ void endHeaderSection() {}
+ void startMemberHeader(const char *) { startGroupHeader(FALSE); }
+ void endMemberHeader() { endGroupHeader(FALSE); }
+ void startMemberSubtitle();
+ void endMemberSubtitle();
+ void startMemberDocList() {}
+ void endMemberDocList() {}
+ void startMemberList();
+ void endMemberList();
+ void startInlineHeader();
+ void endInlineHeader();
+ void startAnonTypeScope(int) {}
+ void endAnonTypeScope(int) {}
+ void startMemberItem(const char *,int,const char *);
+ void endMemberItem();
+ void startMemberTemplateParams() {}
+ void endMemberTemplateParams(const char *,const char *) {}
+ void insertMemberAlign(bool) {}
+
+ void writeRuler() { rtfwriteRuler_thin(); }
+
+ void writeAnchor(const char *fileName,const char *name);
+ void startCodeFragment();
+ void endCodeFragment();
+ void writeLineNumber(const char *,const char *,const char *,int l) { t << l << " "; }
+ void startCodeLine(bool) { col=0; }
+ void endCodeLine() { lineBreak(); }
+ void startEmphasis() { t << "{\\i "; }
+ void endEmphasis() { t << "}"; }
+ void startBold() { t << "{\\b "; }
+ void endBold() { t << "}"; }
+ void startDescription();
+ void endDescription();
+ void startDescItem();
+ void endDescItem();
+ void lineBreak(const char *style=0);
+ void startMemberDoc(const char *,const char *,const char *,const char *,bool);
+ void endMemberDoc(bool);
+ void startDoxyAnchor(const char *,const char *,const char *,const char *,const char *);
+ void endDoxyAnchor(const char *,const char *);
+ void writeChar(char c);
+ void writeLatexSpacing() {};//{ t << "\\hspace{0.3cm}"; }
+ void writeStartAnnoItem(const char *type,const char *file,
+ const char *path,const char *name);
+ void writeEndAnnoItem(const char *name);
+ void startSubsection();
+ void endSubsection();
+ void startSubsubsection();
+ void endSubsubsection();
+ void startCenter() { t << "{\\qc" << endl; }
+ void endCenter() { t << "}"; }
+ void startSmall() { t << "{\\sub "; }
+ void endSmall() { t << "}"; }
+
+ void startMemberDescription(const char *,const char *);
+ void endMemberDescription();
+ void startMemberDeclaration() {}
+ void endMemberDeclaration(const char *,const char *) {}
+ void writeInheritedSectionTitle(const char *,const char *,const char *,
+ const char *,const char *,const char *) {}
+ void startDescList(SectionTypes);
+ void startSimpleSect(SectionTypes,const char *,const char *,const char *);
+ void endSimpleSect();
+ void startParamList(ParamListTypes,const char *);
+ void endParamList();
+ //void writeDescItem();
+ void startDescForItem();
+ void endDescForItem();
+ void startSection(const char *,const char *,SectionInfo::SectionType);
+ void endSection(const char *,SectionInfo::SectionType);
+ void addIndexItem(const char *,const char *);
+ void startIndent();
+ void endIndent();
+ void writeSynopsis() {}
+ void startClassDiagram();
+ void endClassDiagram(const ClassDiagram &,const char *filename,const char *name);
+ void startPageRef();
+ void endPageRef(const char *,const char *);
+ void startQuickIndices() {}
+ void endQuickIndices() {}
+ void writeSplitBar(const char *) {}
+ void writeNavigationPath(const char *) {}
+ void writeLogo() {}
+ void writeQuickLinks(bool,HighlightedItem,const char *) {}
+ void writeSummaryLink(const char *,const char *,const char *,bool) {}
+ void startContents() {}
+ void endContents() {}
+ void writeNonBreakableSpace(int);
+
+ void startDescTable(const char *title);
+ void endDescTable();
+ void startDescTableTitle();
+ void endDescTableTitle();
+ void startDescTableData();
+ void endDescTableData();
+
+ void startDotGraph();
+ void endDotGraph(const DotClassGraph &);
+ void startInclDepGraph();
+ void endInclDepGraph(const DotInclDepGraph &);
+ void startGroupCollaboration();
+ void endGroupCollaboration(const DotGroupCollaboration &g);
+ void startCallGraph();
+ void endCallGraph(const DotCallGraph &);
+ void startDirDepGraph();
+ void endDirDepGraph(const DotDirDeps &g);
+ void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {}
+
+ void startMemberGroupHeader(bool);
+ void endMemberGroupHeader();
+ void startMemberGroupDocs();
+ void endMemberGroupDocs();
+ void startMemberGroup();
+ void endMemberGroup(bool);
+
+ void startTextBlock(bool dense);
+ void endTextBlock(bool);
+ void lastIndexPage();
+
+ void startMemberDocPrefixItem() {}
+ void endMemberDocPrefixItem() {}
+ void startMemberDocName(bool) {}
+ void endMemberDocName() {}
+ void startParameterType(bool,const char *);
+ void endParameterType();
+ void startParameterName(bool) {}
+ void endParameterName(bool,bool,bool) {}
+ void startParameterList(bool) {}
+ void endParameterList() {}
+ void exceptionEntry(const char*,bool);
+
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
+ void startMemberDocSimple();
+ void endMemberDocSimple();
+ void startInlineMemberType();
+ void endInlineMemberType();
+ void startInlineMemberName();
+ void endInlineMemberName();
+ void startInlineMemberDoc();
+ void endInlineMemberDoc();
+
+ void startLabels();
+ void writeLabel(const char *l,bool isLast);
+ void endLabels();
+
+ void startFontClass(const char *) {}
+ void endFontClass() {}
+
+ void writeCodeAnchor(const char *) {}
+ void setCurrentDoc(Definition *,const char *,bool) {}
+ void addWord(const char *,bool) {}
+
+ static bool preProcessFileInplace(const char *path,const char *name);
+
+ private:
+ RTFGenerator(const RTFGenerator &);
+ RTFGenerator &operator=(const RTFGenerator &);
+
+ const char *rtf_BList_DepthStyle();
+ const char *rtf_CList_DepthStyle();
+ const char *rtf_EList_DepthStyle();
+ const char *rtf_LCList_DepthStyle();
+ const char *rtf_DList_DepthStyle();
+ const char *rtf_Code_DepthStyle();
+ void incrementIndentLevel();
+ void decrementIndentLevel();
+ int col;
+
+ bool m_bstartedBody; // has startbody been called yet?
+ int m_listLevel; // // RTF does not really have a addative indent...manually set list level.
+ bool m_omitParagraph; // should a the next paragraph command be ignored?
+ int m_numCols; // number of columns in a table
+ QCString relPath;
+
+ void beginRTFDocument();
+ void beginRTFChapter();
+ void beginRTFSection();
+ void rtfwriteRuler_doubleline();
+ void rtfwriteRuler_emboss();
+ void rtfwriteRuler_thick();
+ void rtfwriteRuler_thin();
+ void writeRTFReference(const char *label);
+ //char *getMultiByte(int c);
+};
+
+#endif
diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp
new file mode 100644
index 0000000..f44951a
--- /dev/null
+++ b/src/rtfstyle.cpp
@@ -0,0 +1,518 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "rtfstyle.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <stdlib.h>
+
+#include "message.h"
+
+
+RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];
+
+QCString rtf_title;
+QCString rtf_subject;
+QCString rtf_comments;
+QCString rtf_company;
+QCString rtf_logoFilename;
+QCString rtf_author;
+QCString rtf_manager;
+QCString rtf_documentType;
+QCString rtf_documentId;
+QCString rtf_keywords;
+
+char rtf_Style_Reset[] = "\\pard\\plain ";
+
+Rtf_Style_Default rtf_Style_Default[] =
+{
+ { "Heading1",
+ "\\s1\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs36\\kerning36\\cgrid ",
+ "\\sbasedon0 \\snext0 heading 1"
+ },
+ { "Heading2",
+ "\\s2\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs28\\kerning28\\cgrid ",
+ "\\sbasedon0 \\snext0 heading 2"
+ },
+ { "Heading3",
+ "\\s3\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\cgrid ",
+ "\\sbasedon0 \\snext0 heading 3"
+ },
+ { "Heading4",
+ "\\s4\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext0 heading 4;}{\\*\\cs10 \\additive Default Paragraph Font"
+ },
+ { "Heading5",
+ "\\s5\\sb90\\sa30\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext0 heading 5;}{\\*\\cs10 \\additive Default Paragraph Font"
+ },
+ { "Title",
+ "\\s15\\qc\\sb240\\sa60\\widctlpar\\outlinelevel0\\adjustright \\b\\f1\\fs32\\kerning28\\cgrid ",
+ "\\sbasedon0 \\snext15 Title"
+ },
+ { "SubTitle",
+ "\\s16\\qc\\sa60\\widctlpar\\outlinelevel1\\adjustright \\f1\\cgrid ",
+ "\\sbasedon0 \\snext16 Subtitle"
+ },
+ { "BodyText",
+ "\\s17\\sa60\\sb30\\widctlpar\\qj \\fs22\\cgrid ",
+ "\\sbasedon0 \\snext17 BodyText"
+ },
+ { "DenseText",
+ "\\s18\\widctlpar\\fs22\\cgrid ",
+ "\\sbasedon0 \\snext18 DenseText"
+ },
+ { "Header",
+ "\\s28\\widctlpar\\tqc\\tx4320\\tqr\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext28 header"
+ },
+ { "Footer",
+ "\\s29\\widctlpar\\tqc\\tx4320\\tqr\\tx8640\\qr\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext29 footer"
+ },
+ { "GroupHeader",
+ "\\s30\\li360\\sa60\\sb120\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext30 GroupHeader"
+ },
+ { "CodeExample0",
+ "\\s40\\li0\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext41 Code Example 0"
+ },
+ { "CodeExample1",
+ "\\s41\\li360\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext42 Code Example 1"
+ },
+ { "CodeExample2",
+ "\\s42\\li720\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext43 Code Example 2"
+ },
+ { "CodeExample3",
+ "\\s43\\li1080\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext44 Code Example 3"
+ },
+ { "CodeExample4",
+ "\\s44\\li1440\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext45 Code Example 4"
+ },
+ { "CodeExample5",
+ "\\s45\\li1800\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext46 Code Example 5"
+ },
+ { "CodeExample6",
+ "\\s46\\li2160\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext47 Code Example 6"
+ },
+ { "CodeExample7",
+ "\\s47\\li2520\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext48 Code Example 7"
+ },
+ { "CodeExample8",
+ "\\s48\\li2880\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext49 Code Example 8"
+ },
+ { "CodeExample9",
+ "\\s49\\li3240\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ",
+ "\\sbasedon0 \\snext49 Code Example 9"
+ },
+ { "ListContinue0",
+ "\\s50\\li0\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext51 List Continue 0"
+ },
+ { "ListContinue1",
+ "\\s51\\li360\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext52 List Continue 1"
+ },
+ { "ListContinue2",
+ "\\s52\\li720\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext53 List Continue 2"
+ },
+ { "ListContinue3",
+ "\\s53\\li1080\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext54 List Continue 3"
+ },
+ { "ListContinue4",
+ "\\s54\\li1440\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext55 List Continue 4"
+ },
+ { "ListContinue5",
+ "\\s55\\li1800\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext56 List Continue 5"
+ },
+ { "ListContinue6",
+ "\\s56\\li2160\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext57 List Continue 6"
+ },
+ { "ListContinue7",
+ "\\s57\\li2520\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext58 List Continue 7"
+ },
+ { "ListContinue8",
+ "\\s58\\li2880\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext59 List Continue 8"
+ },
+ { "ListContinue9",
+ "\\s59\\li3240\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext59 List Continue 9"
+ },
+ { "DescContinue0",
+ "\\s60\\li0\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext61 DescContinue 0"
+ },
+ { "DescContinue1",
+ "\\s61\\li360\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext62 DescContinue 1"
+ },
+ { "DescContinue2",
+ "\\s62\\li720\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext63 DescContinue 2"
+ },
+ { "DescContinue3",
+ "\\s63\\li1080\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext64 DescContinue 3"
+ },
+ { "DescContinue4",
+ "\\s64\\li1440\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext65 DescContinue 4"
+ },
+ { "DescContinue5",
+ "\\s65\\li1800\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext66 DescContinue 5"
+ },
+ { "DescContinue6",
+ "\\s66\\li2160\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext67 DescContinue 6"
+ },
+ { "DescContinue7",
+ "\\s67\\li2520\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext68 DescContinue 7"
+ },
+ { "DescContinue8",
+ "\\s68\\li2880\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext69 DescContinue 8"
+ },
+ { "DescContinue9",
+ "\\s69\\li3240\\widctlpar\\ql\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext69 DescContinue 9"
+ },
+ { "LatexTOC0",
+ "\\s70\\li0\\sa30\\sb30\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext81 LatexTOC 0"
+ },
+ { "LatexTOC1",
+ "\\s71\\li360\\sa27\\sb27\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext82 LatexTOC 1"
+ },
+ { "LatexTOC2",
+ "\\s72\\li720\\sa24\\sb24\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext83 LatexTOC 2"
+ },
+ { "LatexTOC3",
+ "\\s73\\li1080\\sa21\\sb21\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext84 LatexTOC 3"
+ },
+ { "LatexTOC4",
+ "\\s74\\li1440\\sa18\\sb18\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext85 LatexTOC 4"
+ },
+ { "LatexTOC5",
+ "\\s75\\li1800\\sa15\\sb15\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext86 LatexTOC 5"
+ },
+ { "LatexTOC6",
+ "\\s76\\li2160\\sa12\\sb12\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext87 LatexTOC 6"
+ },
+ { "LatexTOC7",
+ "\\s77\\li2520\\sa9\\sb9\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext88 LatexTOC 7"
+ },
+ { "LatexTOC8",
+ "\\s78\\li2880\\sa6\\sb6\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext89 LatexTOC 8"
+ },
+ { "LatexTOC9",
+ "\\s79\\li3240\\sa3\\sb3\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext89 LatexTOC 9"
+ },
+ { "ListBullet0",
+ "\\s80\\fi-360\\li360\\widctlpar\\jclisttab\\tx360{\\*\\pn \\pnlvlbody\\ilvl0\\ls1\\pnrnot0\\pndec }\\ls1\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext81 \\sautoupd List Bullet 0"
+ },
+ { "ListBullet1",
+ "\\s81\\fi-360\\li720\\widctlpar\\jclisttab\\tx720{\\*\\pn \\pnlvlbody\\ilvl0\\ls2\\pnrnot0\\pndec }\\ls2\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext82 \\sautoupd List Bullet 1"
+ },
+ { "ListBullet2",
+ "\\s82\\fi-360\\li1080\\widctlpar\\jclisttab\\tx1080{\\*\\pn \\pnlvlbody\\ilvl0\\ls3\\pnrnot0\\pndec }\\ls3\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext83 \\sautoupd List Bullet 2"
+ },
+ { "ListBullet3",
+ "\\s83\\fi-360\\li1440\\widctlpar\\jclisttab\\tx1440{\\*\\pn \\pnlvlbody\\ilvl0\\ls4\\pnrnot0\\pndec }\\ls4\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext84 \\sautoupd List Bullet 3"
+ },
+ { "ListBullet4",
+ "\\s84\\fi-360\\li1800\\widctlpar\\jclisttab\\tx1800{\\*\\pn \\pnlvlbody\\ilvl0\\ls5\\pnrnot0\\pndec }\\ls5\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext85 \\sautoupd List Bullet 4"
+ },
+ { "ListBullet5",
+ "\\s85\\fi-360\\li2160\\widctlpar\\jclisttab\\tx2160{\\*\\pn \\pnlvlbody\\ilvl0\\ls6\\pnrnot0\\pndec }\\ls6\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext86 \\sautoupd List Bullet 5"
+ },
+ { "ListBullet6",
+ "\\s86\\fi-360\\li2520\\widctlpar\\jclisttab\\tx2520{\\*\\pn \\pnlvlbody\\ilvl0\\ls7\\pnrnot0\\pndec }\\ls7\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext87 \\sautoupd List Bullet 6"
+ },
+ { "ListBullet7",
+ "\\s87\\fi-360\\li2880\\widctlpar\\jclisttab\\tx2880{\\*\\pn \\pnlvlbody\\ilvl0\\ls8\\pnrnot0\\pndec }\\ls8\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext88 \\sautoupd List Bullet 7"
+ },
+ { "ListBullet8",
+ "\\s88\\fi-360\\li3240\\widctlpar\\jclisttab\\tx3240{\\*\\pn \\pnlvlbody\\ilvl0\\ls9\\pnrnot0\\pndec }\\ls9\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext89 \\sautoupd List Bullet 8"
+ },
+ { "ListBullet9",
+ "\\s89\\fi-360\\li3600\\widctlpar\\jclisttab\\tx3600{\\*\\pn \\pnlvlbody\\ilvl0\\ls10\\pnrnot0\\pndec }\\ls10\\adjustright \\fs20\\cgrid ",
+ "\\sbasedon0 \\snext89 \\sautoupd List Bullet 9"
+ },
+ { "ListEnum0",
+ "\\s90\\fi-360\\li360\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext91 \\sautoupd List Enum 0"
+ },
+ { "ListEnum1",
+ "\\s91\\fi-360\\li720\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext92 \\sautoupd List Enum 1"
+ },
+ { "ListEnum2",
+ "\\s92\\fi-360\\li1080\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext93 \\sautoupd List Enum 2"
+ },
+ { "ListEnum3",
+ "\\s93\\fi-360\\li1440\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext94 \\sautoupd List Enum 3"
+ },
+ { "ListEnum4",
+ "\\s94\\fi-360\\li1800\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext95 \\sautoupd List Enum 4"
+ },
+ { "ListEnum5",
+ "\\s95\\fi-360\\li2160\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext96 \\sautoupd List Enum 5"
+ },
+ { "ListEnum6",
+ "\\s96\\fi-360\\li2520\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext96 \\sautoupd List Enum 5"
+ },
+ { "ListEnum7",
+ "\\s97\\fi-360\\li2880\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext98 \\sautoupd List Enum 7"
+ },
+ { "ListEnum8",
+ "\\s98\\fi-360\\li3240\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext99 \\sautoupd List Enum 8"
+ },
+ { "ListEnum9",
+ "\\s99\\fi-360\\li3600\\widctlpar\\fs20\\cgrid ",
+ "\\sbasedon0 \\snext99 \\sautoupd List Enum 9"
+ },
+ { 0,
+ 0,
+ 0
+ }
+};
+
+const QRegExp StyleData::s_clause("\\\\s[0-9]+\\s*");
+
+StyleData::StyleData(const char* reference, const char* definition)
+{
+ int start = s_clause.match(reference); ASSERT(start >= 0);
+ reference += start;
+ index = (int)atol(reference + 2); ASSERT(index > 0);
+
+ ASSERT(reference != 0);
+ size_t size = 1 + strlen(reference);
+ memcpy(this->reference = new char[size], reference, size);
+
+ ASSERT(definition != 0);
+ size = 1 + strlen(definition);
+ memcpy(this->definition = new char[size], definition, size);
+}
+
+StyleData::~StyleData()
+{
+ delete[] reference;
+ delete[] definition;
+}
+
+bool StyleData::setStyle(const char* s, const char* styleName)
+{
+ static const QRegExp subgroup("^{[^}]*}\\s*");
+ static const QRegExp any_clause("^\\\\[a-z][a-z0-9-]*\\s*");
+
+ int len = 0; // length of a particular RTF formatting control
+ int ref_len = 0; // length of the whole formatting section of a style
+ int start = s_clause.match(s, 0, &len);
+ if (start < 0)
+ {
+ err("Style sheet '%s' contains no '\\s' clause.\n{%s}\n", styleName, s);
+ return FALSE;
+ }
+ s += start;
+ index = (int)atol(s + 2); ASSERT(index > 0);
+
+ // search for the end of pure formatting codes
+ const char* end = s + len;
+ ref_len = len;
+ bool haveNewDefinition = TRUE;
+ for(;;)
+ {
+ if (*end == '{')
+ {
+ // subgroups are used for \\additive
+ if (0 != subgroup.match(end, 0, &len))
+ break;
+ else
+ {
+ end += len;
+ ref_len += len;
+ }
+ }
+ else if (*end == '\\')
+ {
+ if (0 == qstrncmp(end, "\\snext", 6))
+ break;
+ if (0 == qstrncmp(end, "\\sbasedon", 9))
+ break;
+ if (0 != any_clause.match(end, 0, &len))
+ break;
+ end += len;
+ ref_len += len;
+ }
+ else if (*end == 0)
+ { // no style-definition part, keep default value
+ haveNewDefinition = FALSE;
+ break;
+ }
+ else // plain name without leading \\snext
+ break;
+ }
+ delete[] reference;
+ reference = new char[ref_len + 1];
+ memcpy(reference, s, ref_len);
+ reference[ref_len] = 0;
+ if (haveNewDefinition)
+ {
+ delete[] definition;
+ size_t size = 1 + strlen(end);
+ definition = new char[size];
+ memcpy(definition, end, size);
+ }
+ return TRUE;
+}
+
+void loadStylesheet(const char *name, QDict<StyleData>& dict)
+{
+ QFile file(name);
+ if (!file.open(IO_ReadOnly))
+ {
+ err("Can't open RTF style sheet file %s. Using defaults.\n",name);
+ return;
+ }
+ msg("Loading RTF style sheet %s...\n",name);
+
+ static const QRegExp separator("[ \t]*=[ \t]*");
+ uint lineNr=1;
+ QTextStream t(&file);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+
+ while (!t.eof())
+ {
+ QCString s(4096); // string buffer of max line length
+ s = t.readLine().stripWhiteSpace().utf8();
+ if (s.isEmpty() || s.at(0)=='#') continue; // skip blanks & comments
+ int sepLength;
+ int sepStart = separator.match(s,0,&sepLength);
+ if (sepStart<=0) // no valid assignment statement
+ {
+ warn(name,lineNr,"Assignment of style sheet name expected!\n");
+ continue;
+ }
+ QCString key=s.left(sepStart);
+ if (dict[key]==0) // not a valid style sheet name
+ {
+ warn(name,lineNr,"Invalid style sheet name %s ignored.\n",key.data());
+ continue;
+ }
+ StyleData* styleData = dict.find(key);
+ if (styleData == 0)
+ {
+ warn(name,lineNr,"Unknown style sheet name %s ignored.\n",key.data());
+ continue;
+ }
+ s+=" "; // add command separator
+ styleData->setStyle(s.data() + sepStart + sepLength, key.data());
+ lineNr++;
+ }
+}
+
+QDict<StyleData> rtf_Style(257);
+
+void loadExtensions(const char *name)
+{
+ QFile file(name);
+ if (!file.open(IO_ReadOnly))
+ {
+ err("Can't open RTF extensions file %s. Using defaults.\n",name);
+ return;
+ }
+ msg("Loading RTF extensions %s...\n",name);
+
+ static const QRegExp separator("[ \t]*=[ \t]*");
+ uint lineNr=1;
+ QTextStream t(&file);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+
+ while (!t.eof())
+ {
+ QCString s(4096); // string buffer of max line length
+ s = t.readLine().stripWhiteSpace().utf8();
+ if (s.length()==0 || s.at(0)=='#') continue; // skip blanks & comments
+ int sepLength;
+ int sepStart = separator.match(s,0,&sepLength);
+ if (sepStart<=0) // no valid assignment statement
+ {
+ warn(name,lineNr,"Assignment of extension field expected!\n");
+ continue;
+ }
+ QCString key=s.left(sepStart);
+ QCString data=s.data() + sepStart + sepLength;
+
+ if (key == "Title") rtf_title = data.data();
+ if (key == "Subject") rtf_subject = data.data();
+ if (key == "Comments") rtf_comments = data.data();
+ if (key == "Company") rtf_company = data.data();
+ if (key == "LogoFilename") rtf_logoFilename = data.data();
+ if (key == "Author") rtf_author = data.data();
+ if (key == "Manager") rtf_manager = data.data();
+ if (key == "DocumentType") rtf_documentType = data.data();
+ if (key == "DocumentId") rtf_documentId = data.data();
+ if (key == "Keywords") rtf_keywords = data.data();
+ lineNr++;
+ }
+}
+
diff --git a/src/rtfstyle.h b/src/rtfstyle.h
new file mode 100644
index 0000000..4f0a03f
--- /dev/null
+++ b/src/rtfstyle.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef RTFSTYLE_H
+#define RTFSTYLE_H
+
+#include <qregexp.h>
+#include <qdict.h>
+
+// used for table column width calculation
+const int rtf_pageWidth = 8748;
+
+extern QCString rtf_title;
+extern QCString rtf_subject;
+extern QCString rtf_comments;
+extern QCString rtf_company;
+extern QCString rtf_logoFilename;
+extern QCString rtf_author;
+extern QCString rtf_manager;
+extern QCString rtf_documentType;
+extern QCString rtf_documentId;
+extern QCString rtf_keywords;
+
+struct RTFListItemInfo
+{
+ bool isEnum;
+ int number;
+};
+
+const int rtf_maxIndentLevels = 10;
+
+extern RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];
+
+struct Rtf_Style_Default
+{
+ const char *name;
+ const char *reference;
+ const char *definition;
+};
+
+extern char rtf_Style_Reset[];
+extern Rtf_Style_Default rtf_Style_Default[];
+
+struct StyleData
+{
+ // elements of this type are stored in dictionary Rtf_Style
+ //
+ // to define a tag in the header reference + definition is required
+ // to use a tag in the body of the document only reference is required
+
+ unsigned index; // index in style-sheet, i.e. number in s-clause
+ char* reference; // everything required to apply the style
+ char* definition; // aditional tags like \snext and style name
+
+ StyleData(const char* reference, const char* definition);
+ ~StyleData();
+ bool setStyle(const char* s, const char* styleName);
+
+ static const QRegExp s_clause;
+};
+
+extern QDict<StyleData> rtf_Style;
+
+void loadExtensions(const char *name);
+void loadStylesheet(const char *name, QDict<StyleData>& dict);
+
+#endif
diff --git a/src/scanner.h b/src/scanner.h
new file mode 100644
index 0000000..8c8c3d9
--- /dev/null
+++ b/src/scanner.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCANNER_H
+#define SCANNER_H
+
+#include "parserintf.h"
+
+/** \brief C-like language parser using state-based lexical scanning.
+ *
+ * This is the language parser for doxygen. It is somewhat fuzzy and
+ * supports C++ and various languages that are closely related to C++,
+ * such as C, C#, Objective-C, Java, PHP, and IDL.
+ */
+class CLanguageScanner : public ParserInterface
+{
+ public:
+ virtual ~CLanguageScanner() {}
+ void startTranslationUnit(const char *fileName);
+ void finishTranslationUnit();
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+ bool needsPreprocessing(const QCString &extension);
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState();
+ void parsePrototype(const char *text);
+};
+
+void scanFreeScanner();
+
+#endif
diff --git a/src/scanner.l b/src/scanner.l
new file mode 100644
index 0000000..8370f13
--- /dev/null
+++ b/src/scanner.l
@@ -0,0 +1,7021 @@
+/*****************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <unistd.h>
+#include <qfile.h>
+
+#include "scanner.h"
+#include "entry.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "defargs.h"
+#include "language.h"
+#include "commentscan.h"
+#include "code.h"
+#include "arguments.h"
+
+#include "clangparser.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+static ParserInterface *g_thisParser;
+static const char * inputString;
+static int inputPosition;
+static QFile inputFile;
+static int lastContext;
+static int lastCContext;
+static int lastDocContext;
+static int lastCPPContext;
+static int lastSkipSharpContext;
+static int lastSkipRoundContext;
+static int lastStringContext;
+static int lastCurlyContext;
+static int lastRoundContext;
+static int lastSquareContext;
+static int lastInitializerContext;
+static int lastClassTemplSpecContext;
+static int lastPreLineCtrlContext;
+static int lastSkipVerbStringContext;
+static int lastCommentInArgContext;
+static int lastRawStringContext;
+static int lastCSConstraint;
+static int lastHereDocContext;
+static int lastDefineContext;
+static int lastAlignAsContext;
+static Protection protection;
+static Protection baseProt;
+static int sharpCount = 0 ;
+static int roundCount = 0 ;
+static int curlyCount = 0 ;
+static int squareCount = 0 ;
+static int padCount = 0 ;
+static QCString slString;
+static Entry* current_root = 0 ;
+static Entry* global_root = 0 ;
+static Entry* current = 0 ;
+static Entry* previous = 0 ;
+static Entry* tempEntry = 0 ;
+static Entry* firstTypedefEntry = 0 ;
+static Entry* memspecEntry = 0 ;
+static int yyLineNr = 1 ;
+static int yyBegLineNr = yyLineNr ;
+static int yyColNr = 1 ;
+static int yyBegColNr = yyColNr ;
+static int anonCount = 0 ;
+static int anonNSCount = 0 ;
+static QCString yyFileName;
+static MethodTypes mtype;
+static bool gstat;
+static bool removeSlashes;
+static Specifier virt;
+static Specifier baseVirt;
+static QCString msType,msName,msArgs;
+static bool isTypedef;
+static int tmpDocType;
+static QCString sectionLabel;
+static QCString sectionTitle;
+static QCString funcPtrType;
+static QCString templateStr;
+static QCString aliasName;
+static QCString baseName;
+static QCString* specName;
+static QCString formulaText;
+static QCString formulaEnd;
+static bool useOverrideCommands = FALSE;
+
+static SrcLangExt language;
+static bool insideIDL = FALSE; //!< processing IDL code?
+static bool insideJava = FALSE; //!< processing Java code?
+static bool insideCS = FALSE; //!< processing C# code?
+static bool insideD = FALSE; //!< processing D code?
+static bool insidePHP = FALSE; //!< processing PHP code?
+static bool insideObjC = FALSE; //!< processing Objective C code?
+static bool insideCli = FALSE; //!< processing C++/CLI code?
+static bool insideJS = FALSE; //!< processing JavaScript code?
+static bool insideCpp = TRUE; //!< processing C/C++ code
+
+static bool insideCppQuote = FALSE;
+static bool insideProtocolList = FALSE;
+
+static int argRoundCount;
+static int argSharpCount;
+static int currentArgumentContext;
+static int lastCopyArgStringContext;
+static int lastCopyArgContext;
+static QCString *copyArgString;
+static QCString fullArgString;
+
+static ArgumentList *currentArgumentList;
+static char lastCopyArgChar;
+
+static QCString *pCopyQuotedString;
+static QCString *pCopyRoundString;
+static QCString *pCopyCurlyString;
+static QCString *pCopyRawString;
+
+static QGString *pCopyCurlyGString;
+static QGString *pCopyRoundGString;
+static QGString *pCopyQuotedGString;
+static QGString *pCopyHereDocGString;
+static QGString *pCopyRawGString;
+static QGString *pSkipVerbString;
+static QStack<Grouping> autoGroupStack;
+
+static bool insideFormula;
+static bool insideTryBlock=FALSE;
+static bool insideCode;
+static bool needsSemi;
+
+//static int depthIf;
+static int initBracketCount;
+static QCString memberGroupRelates;
+static QCString memberGroupInside;
+static QCString xrefItemKey;
+static QCString xrefItemTitle;
+static QCString xrefListTitle;
+
+static QCString g_skipBlockName;
+static QCString oldStyleArgType;
+static QCString docBackup;
+static QCString briefBackup;
+
+static int docBlockContext;
+static QGString docBlock;
+static QCString docBlockName;
+static bool docBlockInBody;
+static bool docBlockAutoBrief;
+static char docBlockTerm;
+
+static QCString idlAttr;
+static QCString idlProp;
+
+static bool g_lexInit = FALSE;
+static bool externC;
+
+static QCString g_delimiter;
+
+static int g_column;
+
+static int g_fencedSize=0;
+static bool g_nestedComment=0;
+
+//-----------------------------------------------------------------------------
+
+// forward declarations
+//static void handleGroupStartCommand(const char *header);
+//static void handleGroupEndCommand();
+
+//-----------------------------------------------------------------------------
+
+static void initParser()
+{
+ sectionLabel.resize(0);
+ sectionTitle.resize(0);
+ baseName.resize(0);
+ formulaText.resize(0);
+ protection = Public;
+ baseProt = Public;
+ sharpCount = 0;
+ roundCount = 0;
+ curlyCount = 0;
+ mtype = Method;
+ gstat = FALSE;
+ virt = Normal;
+ baseVirt = Normal;
+ isTypedef = FALSE;
+ autoGroupStack.clear();
+ insideTryBlock = FALSE;
+ autoGroupStack.setAutoDelete(TRUE);
+ insideFormula = FALSE;
+ insideCode=FALSE;
+ insideCli=Config_getBool("CPP_CLI_SUPPORT");
+ previous = 0;
+ firstTypedefEntry = 0;
+ tempEntry = 0;
+ memspecEntry =0;
+}
+
+static void initEntry()
+{
+ if (insideJava)
+ {
+ protection = (current_root->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
+ }
+ current->protection = protection ;
+ current->mtype = mtype;
+ current->virt = virt;
+ current->stat = gstat;
+ current->lang = language;
+ //printf("*** initEntry() language=%d\n",language);
+ //if (!autoGroupStack.isEmpty())
+ //{
+ // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data());
+ // current->groups->append(new Grouping(*autoGroupStack.top()));
+ //}
+ initGroupInfo(current);
+ isTypedef=FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+
+///// remove any automatic grouping and add new one (if given)
+//static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri )
+//{
+// /* remove auto group name from current entry and discard it */
+// Grouping *g = current->groups->first();
+// int i=0;
+// while (g)
+// {
+// if (g->pri <= Grouping::GROUPING_AUTO_DEF)
+// {
+// current->groups->remove(i);
+// i--;
+// }
+// g=current->groups->next();
+// i++;
+// }
+//
+// /* use new group name instead? */
+// if ( newgroup )
+// {
+// current->groups->append(new Grouping(*newgroup, pri));
+// }
+//}
+//
+//static int newMemberGroupId()
+//{
+// static int curGroupId=0;
+// return curGroupId++;
+//}
+//
+// forward declarations
+//static void startGroupInDoc();
+//static void endGroup();
+
+//-----------------------------------------------------------------------------
+
+static void lineCount()
+{
+ static int tabSize = Config_getInt("TAB_SIZE");
+ const char *p;
+ for (p = yytext ; *p ; ++p )
+ {
+ if (*p=='\n')
+ {
+ yyLineNr++,g_column=0,yyColNr=1;
+ }
+ else if (*p=='\t')
+ {
+ g_column+=tabSize - (g_column%tabSize);
+ }
+ else
+ {
+ g_column++,yyColNr++;
+ }
+ }
+ //printf("lineCount()=%d\n",g_column);
+}
+
+static inline int computeIndent(const char *s,int startIndent)
+{
+ int col=startIndent;
+ static int tabSize=Config_getInt("TAB_SIZE");
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ if (c=='\t') col+=tabSize-(col%tabSize);
+ else if (c=='\n') col=0;
+ else col++;
+ }
+ return col;
+}
+
+static void addType( Entry* current )
+{
+ uint tl=current->type.length();
+ if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.')
+ {
+ current->type += ' ' ;
+ }
+ current->type += current->name ;
+ current->name.resize(0) ;
+ tl=current->type.length();
+ if( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.')
+ {
+ current->type += ' ' ;
+ }
+ current->type += current->args ;
+ current->args.resize(0) ;
+ current->argList->clear();
+}
+
+
+static QCString stripQuotes(const char *s)
+{
+ QCString name;
+ if (s==0 || *s==0) return name;
+ name=s;
+ if (name.at(0)=='"' && name.at(name.length()-1)=='"')
+ {
+ name=name.mid(1,name.length()-2);
+ }
+ return name;
+}
+
+//-----------------------------------------------------------------
+
+static void startCommentBlock(bool);
+static void handleCommentBlock(const QCString &doc,bool brief);
+static void handleParametersCommentBlocks(ArgumentList *al);
+
+//-----------------------------------------------------------------
+
+static bool nameIsOperator(QCString &name)
+{
+ int i=name.find("operator");
+ if (i==-1) return FALSE;
+ if (i==0 && !isId(name.at(8))) return TRUE; // case operator ::X
+ if (i>0 && !isId(name.at(i-1)) && !isId(name.at(i+8))) return TRUE; // case X::operator
+ return FALSE; // case TEXToperatorTEXT
+}
+
+//-----------------------------------------------------------------------------
+
+static void setContext()
+{
+ QCString fileName = yyFileName;
+ language = getLanguageFromFileName(fileName);
+ insideIDL = language==SrcLangExt_IDL;
+ insideJava = language==SrcLangExt_Java;
+ insideCS = language==SrcLangExt_CSharp;
+ insideD = language==SrcLangExt_D;
+ insidePHP = language==SrcLangExt_PHP;
+ insideObjC = language==SrcLangExt_ObjC;
+ insideJS = language==SrcLangExt_JS;
+ insideCpp = language==SrcLangExt_Cpp;
+ if ( insidePHP )
+ {
+ useOverrideCommands = TRUE;
+ }
+ //printf("setContext(%s) insideIDL=%d insideJava=%d insideCS=%d "
+ // "insideD=%d insidePHP=%d insideObjC=%d\n",
+ // yyFileName.data(),insideIDL,insideJava,insideCS,insideD,insidePHP,insideObjC
+ // );
+}
+
+//-----------------------------------------------------------------------------
+
+static void prependScope()
+{
+ if (current_root->section & Entry::SCOPE_MASK)
+ {
+ //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data());
+ current->name.prepend(current_root->name+"::");
+ if (current_root->tArgLists)
+ {
+ if (current->tArgLists==0)
+ {
+ current->tArgLists = new QList<ArgumentList>;
+ current->tArgLists->setAutoDelete(TRUE);
+ }
+ //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count());
+ QListIterator<ArgumentList> talsi(*current_root->tArgLists);
+ ArgumentList *srcAl=0;
+ for (talsi.toLast();(srcAl=talsi.current());--talsi)
+ {
+ ArgumentList *dstAl = new ArgumentList;
+ QListIterator<Argument> tali(*srcAl);
+ Argument *a;
+ for (;(a=tali.current());++tali)
+ {
+ dstAl->append(new Argument(*a));
+ //printf("appending argument %s %s\n",a->type.data(),a->name.data());
+ }
+ current->tArgLists->insert(0,dstAl);
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Returns TRUE iff the current entry could be a K&R style C function */
+static bool checkForKnRstyleC()
+{
+ if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file
+ if (!current->argList) return FALSE; // must have arguments
+ ArgumentListIterator ali(*current->argList);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ // in K&R style argument do not have a type, but doxygen expects a type
+ // so it will think the argument has no name
+ if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE;
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+
+static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
+{
+ int si = current->args.length();
+ if (oldStyleArgType.isEmpty()) // new argument
+ {
+ static QRegExp re("([^)]*)");
+ int bi1 = current->args.findRev(re);
+ int bi2 = bi1!=-1 ? current->args.findRev(re,bi1-1) : -1;
+ char c;
+ if (bi1!=-1 && bi2!=-1) // found something like "int (*func)(int arg)"
+ {
+ int s=bi2+1;
+ oldStyleArgType = current->args.left(s);
+ int i=s;
+ while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
+ oldStyleArgType += current->args.mid(s,i-s);
+ s=i;
+ while (i<si && isId(current->args.at(i))) i++;
+ oldStyleArgName = current->args.mid(s,i-s);
+ oldStyleArgType+=current->args.mid(i);
+ }
+ else if (bi1!=-1) // redundant braces like in "int (*var)"
+ {
+ int s=bi1;
+ oldStyleArgType = current->args.left(s);
+ s++;
+ int i=s+1;
+ while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
+ oldStyleArgType += current->args.mid(s,i-s);
+ s=i;
+ while (i<si && isId(current->args.at(i))) i++;
+ oldStyleArgName = current->args.mid(s,i-s);
+ }
+ else // normal "int *var"
+ {
+ int l=si,i=l-1,j;
+ char c;
+ // look for start of name in "type *name"
+ while (i>=0 && isId(current->args.at(i))) i--;
+ j=i+1;
+ // look for start of *'s
+ while (i>=0 && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i--;
+ i++;
+ if (i!=l)
+ {
+ oldStyleArgType=current->args.left(i);
+ oldStyleArgPtr=current->args.mid(i,j-i);
+ oldStyleArgName=current->args.mid(j).stripWhiteSpace();
+ }
+ else
+ {
+ oldStyleArgName=current->args.copy().stripWhiteSpace();
+ }
+ }
+ }
+ else // continuation like *arg2 in "int *args,*arg2"
+ {
+ int l=si,j=0;
+ char c;
+ while (j<l && ((c=current->args.at(j))=='*' || isspace((uchar)c))) j++;
+ if (j>0)
+ {
+ oldStyleArgPtr=current->args.left(j);
+ oldStyleArgName=current->args.mid(j).stripWhiteSpace();
+ }
+ else
+ {
+ oldStyleArgName=current->args.copy().stripWhiteSpace();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Update the argument \a name with additional \a type info. For K&R style
+ * function the type is found \e after the argument list, so this routine
+ * in needed to fix up.
+ */
+static void addKnRArgInfo(const QCString &type,const QCString &name,
+ const QCString &brief,const QCString &docs)
+{
+ if (current->argList==0) return;
+ ArgumentListIterator ali(*current->argList);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (a->type==name)
+ {
+ a->type=type.stripWhiteSpace();
+ if (a->type.left(9)=="register ") // strip keyword
+ {
+ a->type=a->type.mid(9);
+ }
+ a->name=name.stripWhiteSpace();
+ if (!brief.isEmpty() && !docs.isEmpty())
+ {
+ a->docs=brief+"\n\n"+docs;
+ }
+ else if (!brief.isEmpty())
+ {
+ a->docs=brief;
+ }
+ else
+ {
+ a->docs=docs;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+
+void fixArgumentListForJavaScript(ArgumentList *al)
+{
+ if (al==0) return;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (!a->type.isEmpty() && a->name.isEmpty())
+ { // a->type is actually the (typeless) parameter name, so move it
+ a->name=a->type;
+ a->type.resize(0);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ //printf("%d (%c)\n",*buf,*buf);
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+ /* start command character */
+CMD ("\\"|"@")
+SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"callgraph"|"callergraph"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"manonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">")
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
+ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
+SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
+PHPSCOPENAME ({ID}"\\")+{ID}
+TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")?
+CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
+PRE [pP][rR][eE]
+CODE [cC][oO][dD][eE]
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
+PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
+IDLATTR ("["[^\]]*"]"){BN}*
+TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
+RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
+RAWEND ")"[^ \t\(\)\\]{0,16}\"
+ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
+ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
+LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
+BITOP "&"|"|"|"^"|"<<"|">>"|"~"
+OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
+
+%option noyywrap
+
+ /* language parsing states */
+
+%x AlignAs
+%x AlignAsEnd
+%x Define
+%x DefineEnd
+%x CompoundName
+%x ClassVar
+%x CSConstraintName
+%x CSConstraintType
+%x CSIndexer
+%x ClassCategory
+%x ClassTemplSpec
+%x CliPropertyType
+%x CliPropertyIndex
+%x CliOverride
+%x Bases
+%x BasesProt
+%x NextSemi
+%x BitFields
+%x EnumBaseType
+%x FindMembers
+%x FindMembersPHP
+%x FindMemberName
+%x FindFields
+%x FindFieldArg
+%x Function
+%x FuncRound
+%x ExcpRound
+%x ExcpList
+%x FuncQual
+%x TrailingReturn
+%x Operator
+%x Array
+%x ReadBody
+%x ReadNSBody
+%x ReadBodyIntf
+%x Using
+%x UsingAlias
+%x UsingAliasEnd
+%x UsingDirective
+%x SkipCurly
+%x SkipCurlyCpp
+%x SkipCurlyEndDoc
+%x SkipString
+%x SkipPHPString
+%x SkipInits
+%x SkipCPP
+%x SkipCPPBlock
+%x SkipComment
+%x SkipCxxComment
+%x SkipCurlyBlock
+%x SkipRoundBlock
+%x Sharp
+%x SkipRound
+%x SkipSquare
+%x SkipRemainder
+%x StaticAssert
+%x DeclType
+%x TypedefName
+%x TryFunctionBlock
+%x TryFunctionBlockEnd
+%x Comment
+%x PackageName
+%x JavaImport
+%x PHPUse
+%x PHPUseAs
+%x CSAccessorDecl
+%x CSGeneric
+%x PreLineCtrl
+%x DefinePHP
+%x DefinePHPEnd
+%x OldStyleArgs
+%x SkipVerbString
+%x ObjCMethod
+%x ObjCReturnType
+%x ObjCParams
+%x ObjCParamType
+%x ObjCProtocolList
+%x ObjCPropAttr
+%x ObjCSkipStatement
+%x QtPropType
+%x QtPropName
+%x QtPropAttr
+%x QtPropRead
+%x QtPropWrite
+%x ReadInitializer
+%x UNOIDLAttributeBlock
+%x GetCallType
+%x CppQuote
+%x EndCppQuote
+%x MemberSpec
+%x MemberSpecSkip
+%x EndTemplate
+%x FuncPtr
+%x FuncPtrOperator
+%x EndFuncPtr
+%x ReadFuncArgType
+%x ReadTempArgs
+%x IDLUnionCase
+%x NSAliasName
+%x NSAliasArg
+%x CopyString
+%x CopyPHPString
+%x CopyGString
+%x CopyPHPGString
+%x CopyRound
+%x CopyCurly
+%x GCopyRound
+%x GCopyCurly
+%x SkipUnionSwitch
+%x Specialization
+%x FuncPtrInit
+%x FuncFunc
+%x FuncFuncEnd
+%x FuncFuncType
+%x FuncFuncArray
+%x CopyArgString
+%x CopyArgPHPString
+%x CopyArgRound
+%x CopyArgSharp
+%x CopyArgComment
+%x CopyArgCommentLine
+%x CopyArgVerbatim
+%x HereDoc
+%x HereDocEnd
+%x CopyHereDoc
+%x CopyHereDocEnd
+%x RawString
+%x RawGString
+
+%x IDLAttribute
+%x IDLProp
+%x IDLPropName
+
+ /** Prototype scanner states */
+
+%x Prototype
+%x PrototypePtr
+%x PrototypeQual
+%x PrototypeExc
+%x PrototypeSkipLine
+
+ /** comment parsing states */
+
+%x DocLine
+%x DocBlock
+%x DocCopyBlock
+
+%%
+
+<NextSemi>"{" {
+ curlyCount=0;
+ needsSemi = TRUE;
+ BEGIN(SkipCurlyBlock);
+ }
+<NextSemi>"(" {
+ roundCount=0;
+ BEGIN(SkipRoundBlock);
+ }
+<SkipRoundBlock>"(" {
+ ++roundCount;
+ }
+<SkipRoundBlock>")" {
+ if (roundCount )
+ --roundCount ;
+ else
+ BEGIN( NextSemi ) ;
+ }
+<SkipCurlyBlock>"{" {
+ ++curlyCount ;
+ }
+<SkipCurlyBlock>"}" {
+ if( curlyCount )
+ {
+ --curlyCount ;
+ }
+ else if (needsSemi)
+ {
+ BEGIN( NextSemi );
+ }
+ else
+ {
+ BEGIN( FindMembers );
+ }
+ }
+<NextSemi>\' {
+ if (insidePHP)
+ {
+ lastStringContext=NextSemi;
+ BEGIN(SkipPHPString);
+ }
+ }
+<NextSemi>{CHARLIT} { if (insidePHP) REJECT; }
+<NextSemi>\" {
+ lastStringContext=NextSemi;
+ BEGIN(SkipString);
+ }
+<NextSemi>[;,] {
+ unput(*yytext);
+ BEGIN( FindMembers );
+ }
+<BitFields>[;,] {
+ unput(*yytext);
+ BEGIN( FindMembers );
+ }
+<EnumBaseType>[{;,] {
+ current->args = current->args.simplifyWhiteSpace();
+ unput(*yytext);
+ BEGIN( ClassVar );
+ }
+<FindMembers>"<?php" { // PHP code with unsupported extension?
+ insidePHP = TRUE;
+ }
+<FindMembersPHP>"<?"("php"?) { // PHP code start
+ BEGIN( FindMembers );
+ }
+<FindMembersPHP>"<script"{BN}+"language"{BN}*"="{BN}*['"]?"php"['"]?{BN}*">" { // PHP code start
+ lineCount() ;
+ BEGIN( FindMembers );
+ }
+<FindMembersPHP>[^\n<]+ { // Non-PHP code text, ignore
+ }
+<FindMembersPHP>\n { // Non-PHP code text, ignore
+ lineCount();
+ }
+<FindMembersPHP>. { // Non-PHP code text, ignore
+ }
+<FindMembers>"?>"|"</script>" { // PHP code end
+ if (insidePHP)
+ BEGIN( FindMembersPHP );
+ else
+ REJECT;
+ }
+<FindMembers>{PHPKW} { if (insidePHP)
+ BEGIN( NextSemi );
+ else
+ REJECT;
+ }
+<FindMembers>"%{"[^\n]* { // Mozilla XPIDL lang-specific block
+ if (!insideIDL)
+ REJECT;
+ }
+<FindMembers>"%}" { // Mozilla XPIDL lang-specific block end
+ if (!insideIDL)
+ REJECT;
+ }
+<FindMembers>{B}*("properties"){BN}*":"{BN}* { // IDL or Borland C++ builder property
+ current->mtype = mtype = Property;
+ current->protection = protection = Public ;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+
+<FindMembers>{B}*"k_dcop"{BN}*":"{BN}* { current->mtype = mtype = DCOP;
+ current->protection = protection = Public ;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+
+<FindMembers>{B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { current->mtype = mtype = Signal;
+
+ current->protection = protection = Public ;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+
+<FindMembers>{B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
+ current->protection = protection = Public ;
+ current->mtype = mtype = Slot;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount();
+ }
+
+<FindMembers>{B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
+ current->protection = protection = Protected ;
+ current->mtype = mtype = Slot;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount();
+ }
+
+<FindMembers>{B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* {
+ current->protection = protection = Private ;
+ current->mtype = mtype = Slot;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount();
+ }
+<FindMembers>{B}*("public"|"methods"|"__published"){BN}*":"{BN}* {
+ current->protection = protection = Public ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>{B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package...
+ if (insideCli)
+ {
+ current->protection = protection = Package ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<FindMembers>{B}*"protected"{BN}*":"{BN}* {
+ current->protection = protection = Protected ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>{B}*"private"{BN}*":"{BN}* {
+ current->protection = protection = Private ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>{B}*"event"{BN}+ {
+ if (insideCli)
+ {
+ // C++/CLI event
+ lineCount() ;
+ current->mtype = mtype = Event;
+ current->bodyLine = yyLineNr;
+ curlyCount=0;
+ BEGIN( CliPropertyType );
+ }
+ else if (insideCS)
+ {
+ lineCount() ;
+ current->mtype = Event;
+ current->bodyLine = yyLineNr;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<FindMembers>{B}*"property"{BN}+ {
+ if (insideCli)
+ {
+ // C++/CLI property
+ lineCount() ;
+ current->mtype = mtype = Property;
+ current->bodyLine = yyLineNr;
+ curlyCount=0;
+ BEGIN( CliPropertyType );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<CliPropertyType>{ID} {
+ addType( current );
+ current->name = yytext;
+ }
+<CliPropertyType>"[" { // C++/CLI indexed property
+ current->name += yytext;
+ BEGIN( CliPropertyIndex );
+ }
+<CliPropertyType>"{" {
+ curlyCount=0;
+ //printf("event: '%s' '%s'\n",current->type.data(),current->name.data());
+ BEGIN( CSAccessorDecl );
+ }
+<CliPropertyType>";" {
+ unput(*yytext);
+ BEGIN( FindMembers );
+ }
+<CliPropertyType>\n {
+ lineCount();
+ }
+<CliPropertyType>{B}* {
+ }
+<CliPropertyType>. {
+ addType( current );
+ current->type += yytext;
+ }
+<CliPropertyIndex>"]" {
+ BEGIN( CliPropertyType );
+ current->name+=yytext;
+ }
+<CliPropertyIndex>. {
+ current->name+=yytext;
+ }
+ /*
+<FindMembers>{B}*"property"{BN}+ {
+ if (!current->type.isEmpty())
+ {
+ REJECT;
+ }
+ else
+ {
+ current->mtype = mtype = Property;
+ lineCount();
+ }
+ }
+ */
+<FindMembers>{B}*"@private"{BN}+ {
+ current->protection = protection = Private ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>{B}*"@protected"{BN}+ {
+ current->protection = protection = Protected ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>{B}*"@public"{BN}+ {
+ current->protection = protection = Public ;
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+<FindMembers>[\-+]{BN}* {
+ if (!insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ lineCount();
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ current->section = Entry::FUNCTION_SEC;
+ current->protection = protection = Public ;
+ language = current->lang = SrcLangExt_ObjC;
+ insideObjC = TRUE;
+ current->virt = Virtual;
+ current->stat=yytext[0]=='+';
+ current->mtype = mtype = Method;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ BEGIN( ObjCMethod );
+ }
+ }
+<ObjCMethod>"(" { // start of method's return type
+ BEGIN( ObjCReturnType );
+ }
+<ObjCMethod>{ID} { // found method name
+ if (current->type.isEmpty())
+ {
+ current->type = "id";
+ }
+ current->name = yytext;
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ }
+<ObjCMethod>":"{B}* { // start of parameter list
+ current->name += ':';
+ Argument *a = new Argument;
+ current->argList->append(a);
+ BEGIN( ObjCParams );
+ }
+<ObjCReturnType>[^)]* { // TODO: check if nested braches are possible.
+ current->type = yytext;
+ }
+<ObjCReturnType>")" {
+ BEGIN( ObjCMethod );
+ }
+<ObjCParams>({ID})?":" { // Keyword of parameter
+ QCString keyw = yytext;
+ keyw=keyw.left(keyw.length()-1); // strip :
+ if (keyw.isEmpty())
+ {
+ current->name += " :";
+ }
+ else
+ {
+ current->name += keyw+":";
+ }
+ if (current->argList->getLast()->type.isEmpty())
+ {
+ current->argList->getLast()->type="id";
+ }
+ Argument *a = new Argument;
+ a->attrib=(QCString)"["+keyw+"]";
+ current->argList->append(a);
+ }
+<ObjCParams>{ID}{BN}* { // name of parameter
+ lineCount();
+ current->argList->getLast()->name=QCString(yytext).stripWhiteSpace();
+ }
+<ObjCParams>","{BN}*"..." { // name of parameter
+ lineCount();
+ // do we want the comma as part of the name?
+ //current->name += ",";
+ Argument *a = new Argument;
+ a->attrib="[,]";
+ a->type="...";
+ current->argList->append(a);
+ }
+ /*
+<ObjCParams>":" {
+ current->name += ':';
+ }
+ */
+<ObjCParams>"(" {
+ roundCount=0;
+ current->argList->getLast()->type.resize(0);
+ BEGIN( ObjCParamType );
+ }
+<ObjCParamType>"(" {
+ roundCount++;
+ current->argList->getLast()->type+=yytext;
+ }
+<ObjCParamType>")"/{B}* {
+ if (roundCount<=0)
+ {
+ BEGIN( ObjCParams );
+ }
+ else
+ {
+ current->argList->getLast()->type+=yytext;
+ roundCount--;
+ }
+ }
+<ObjCParamType>[^()]* {
+ current->argList->getLast()->type+=QCString(yytext).stripWhiteSpace();
+ }
+<ObjCMethod,ObjCParams>";" { // end of method declaration
+ if (current->argList->getLast() && current->argList->getLast()->type.isEmpty())
+ {
+ current->argList->getLast()->type="id";
+ }
+ current->args = argListToString(current->argList);
+ //printf("argList=%s\n",current->args.data());
+ unput(';');
+ BEGIN( Function );
+ }
+<ObjCMethod,ObjCParams>(";"{BN}+)?"{" { // start of a method body
+ lineCount();
+ //printf("Type=%s Name=%s args=%s\n",
+ // current->type.data(),current->name.data(),argListToString(current->argList).data()
+ // );
+ if (current->argList->getLast() && current->argList->getLast()->type.isEmpty())
+ {
+ current->argList->getLast()->type="id";
+ }
+ current->args = argListToString(current->argList);
+ unput('{');
+ BEGIN( Function );
+ }
+<FindMembers>{BN}{1,80} {
+ lineCount();
+ }
+<FindMembers>"@"({ID}".")*{ID}{BN}*"(" {
+ if (insideJava) // Java annotation
+ {
+ lineCount();
+ lastSkipRoundContext = YY_START;
+ roundCount=1;
+ BEGIN( SkipRound );
+ }
+ else if (qstrncmp(yytext,"@property",9)==0) // ObjC 2.0 property
+ {
+ current->mtype = mtype = Property;
+ current->spec|=Entry::Readable | Entry::Writable | Entry::Assign;
+ current->protection = Public ;
+ unput('(');
+ BEGIN( ObjCPropAttr );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<ObjCPropAttr>"getter="{ID} {
+ current->read = yytext+7;
+ }
+<ObjCPropAttr>"setter="{ID} {
+ current->write = yytext+7;
+ }
+<ObjCPropAttr>"readonly" {
+ current->spec&=~Entry::Writable;
+ }
+<ObjCPropAttr>"readwrite" { // default
+ }
+<ObjCPropAttr>"assign" { // default
+ }
+<ObjCPropAttr>"unsafe_unretained" {
+ current->spec&=~Entry::Assign;
+ current->spec|=Entry::Unretained;
+ }
+<ObjCPropAttr>"retain" {
+ current->spec&=~Entry::Assign;
+ current->spec|=Entry::Retain;
+ }
+<ObjCPropAttr>"copy" {
+ current->spec&=~Entry::Assign;
+ current->spec|=Entry::Copy;
+ }
+<ObjCPropAttr>"weak" {
+ current->spec&=~Entry::Assign;
+ current->spec|=Entry::Weak;
+ }
+<ObjCPropAttr>"strong" {
+ current->spec&=~Entry::Assign;
+ current->spec|=Entry::Strong;
+ }
+<ObjCPropAttr>"nonatomic" {
+ current->spec|=Entry::NonAtomic;
+ }
+<ObjCPropAttr>")" {
+ BEGIN(FindMembers);
+ }
+<FindMembers>"@"{ID} {
+ if (insideJava) // Java annotation
+ {
+ // skip annotation
+ }
+ else if (qstrcmp(yytext,"@property")==0) // ObjC 2.0 property
+ {
+ current->mtype = mtype = Property;
+ current->spec|=Entry::Writable | Entry::Readable;
+ current->protection = Public ;
+ }
+ else if (qstrcmp(yytext,"@synthesize")==0)
+ {
+ BEGIN( ObjCSkipStatement );
+ }
+ else if (qstrcmp(yytext,"@dynamic")==0)
+ {
+ BEGIN( ObjCSkipStatement );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<ObjCSkipStatement>";" {
+ BEGIN(FindMembers);
+ }
+<PackageName>{ID}(("."|"\\"){ID})* {
+ isTypedef=FALSE;
+ //printf("Found namespace %s lang=%d\n",yytext,current->lang);
+ current->name = yytext;
+ current->name = substitute(current->name,".","::");
+ current->name = substitute(current->name,"\\","::");
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "namespace" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount();
+ }
+<PackageName>";" {
+ current_root->addSubEntry(current);
+ current_root = current ;
+ current = new Entry ;
+ initEntry();
+ BEGIN(FindMembers);
+ }
+<PackageName>"{" {
+ curlyCount=0;
+ BEGIN( ReadNSBody );
+ }
+<FindMembers>{B}*"initonly"{BN}+ {
+ current->type += " initonly ";
+ if (insideCli) current->spec |= Entry::Initonly;
+ lineCount();
+ }
+<FindMembers>{B}*"static"{BN}+ { current->type += " static ";
+ current->stat = TRUE;
+ lineCount();
+ }
+<FindMembers>{B}*"extern"{BN}+ {
+ current->stat = FALSE;
+ current->explicitExternal = TRUE;
+ lineCount();
+ }
+<FindMembers>{B}*"virtual"{BN}+ { current->type += " virtual ";
+ current->virt = Virtual;
+ lineCount();
+ }
+<FindMembers>{B}*"published"{BN}+ { // UNO IDL published keyword
+ if (insideIDL)
+ {
+ lineCount();
+ current->spec |= Entry::Published;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<FindMembers>{B}*"abstract"{BN}+ {
+ if (!insidePHP)
+ {
+ current->type += " abstract ";
+ if (!insideJava)
+ {
+ current->virt = Pure;
+ }
+ else
+ {
+ current->spec|=Entry::Abstract;
+ }
+ }
+ else
+ {
+ current->spec|=Entry::Abstract;
+ }
+ lineCount();
+ }
+<FindMembers>{B}*"inline"{BN}+ { current->spec|=Entry::Inline;
+ lineCount();
+ }
+<FindMembers>{B}*"mutable"{BN}+ { current->spec|=Entry::Mutable;
+ lineCount();
+ }
+<FindMembers>{B}*"explicit"{BN}+ { current->spec|=Entry::Explicit;
+ lineCount();
+ }
+<FindMembers>{B}*"@required"{BN}+ { // Objective C 2.0 protocol required section
+ current->spec=(current->spec & ~Entry::Optional) | Entry::Required;
+ lineCount();
+ }
+<FindMembers>{B}*"@optional"{BN}+ { // Objective C 2.0 protocol optional section
+ current->spec=(current->spec & ~Entry::Required) | Entry::Optional;
+ lineCount();
+ }
+ /*
+<FindMembers>{B}*"import"{BN}+ { // IDL import keyword
+ BEGIN( NextSemi );
+ }
+ */
+<FindMembers>{B}*"typename"{BN}+ { lineCount(); }
+<FindMembers>{B}*"namespace"{BN}*/[^a-z_A-Z0-9] {
+ isTypedef=FALSE;
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "namespace" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount();
+ if (insidePHP)
+ {
+ BEGIN( PackageName );
+ }
+ else
+ {
+ BEGIN( CompoundName );
+ }
+ }
+<FindMembers>{B}*"module"{BN}+ {
+ lineCount();
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "module" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else if (insideD)
+ {
+ lineCount();
+ BEGIN(PackageName);
+ }
+ else
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{B}*"library"{BN}+ {
+ lineCount();
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "library" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{B}*"constants"{BN}+ { // UNO IDL constant group
+ lineCount();
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::NAMESPACE_SEC;
+ current->type = "constants";
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{BN}*("service"){BN}+ { // UNO IDL service
+ lineCount();
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Service |
+ // preserve UNO IDL [optional] or published
+ (current->spec & (Entry::Optional|Entry::Published));
+ addType( current ) ;
+ current->type += " service " ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else // TODO is addType right? just copy/pasted
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{BN}*("singleton"){BN}+ { // UNO IDL singleton
+ lineCount();
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Singleton |
+ (current->spec & Entry::Published); // preserve
+ addType( current ) ;
+ current->type += " singleton " ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else // TODO is addType right? just copy/pasted
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{BN}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba/UNO IDL/Java interface
+ lineCount();
+ if (insideIDL || insideJava || insideCS || insideD || insidePHP)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Interface |
+ // preserve UNO IDL [optional] or published
+ (current->spec & (Entry::Optional|Entry::Published));
+ addType( current ) ;
+ current->type += " interface" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+ else
+ {
+ addType( current ) ;
+ current->name = QCString(yytext).stripWhiteSpace();
+ }
+ }
+<FindMembers>{B}*"@implementation"{BN}+ { // Objective-C class implementation
+ lineCount();
+ isTypedef=FALSE;
+ current->section = Entry::OBJCIMPL_SEC;
+ language = current->lang = SrcLangExt_ObjC;
+ insideObjC = TRUE;
+ current->protection = protection = Public ;
+ addType( current ) ;
+ current->type += " implementation" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+<FindMembers>{B}*"@interface"{BN}+ { // Objective-C class interface, or Java attribute
+ lineCount();
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Interface;
+ if (!insideJava)
+ {
+ language = current->lang = SrcLangExt_ObjC;
+ insideObjC = TRUE;
+ }
+ current->protection = protection = Public ;
+ addType( current ) ;
+ current->type += " interface" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+<FindMembers>{B}*"@protocol"{BN}+ { // Objective-C protocol definition
+ lineCount();
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Protocol;
+ language = current->lang = SrcLangExt_ObjC;
+ insideObjC = TRUE;
+ current->protection = protection = Public ;
+ addType( current ) ;
+ current->type += " protocol" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ BEGIN( CompoundName );
+ }
+<FindMembers>{B}*"exception"{BN}+ { // Corba IDL exception
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Exception |
+ (current->spec & Entry::Published); // preserve UNO IDL
+ addType( current ) ;
+ current->type += " exception" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount();
+ BEGIN( CompoundName );
+ }
+<FindMembers>"@class" | // for Objective C class declarations
+<FindMembers>{B}*{TYPEDEFPREFIX}"class{" |
+<FindMembers>{B}*{TYPEDEFPREFIX}"class"{BN}+ {
+ QCString decl = yytext;
+ isTypedef=decl.find("typedef")!=-1;
+ bool isConst=decl.find("const")!=-1;
+ bool isVolatile=decl.find("volatile")!=-1;
+ current->section = Entry::CLASS_SEC;
+ addType( current ) ;
+ if (isConst)
+ {
+ current->type += " const";
+ }
+ else if (isVolatile)
+ {
+ current->type += " volatile";
+ }
+ current->type += " class" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ if (yytext[0]=='@')
+ {
+ language = current->lang = SrcLangExt_ObjC;
+ insideObjC = TRUE;
+ }
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ if (insidePHP && current->spec&Entry::Abstract)
+ {
+ // convert Abstract to AbstractClass
+ current->spec=(current->spec&~Entry::Abstract)|Entry::AbstractClass;
+ }
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"value class{" | // C++/CLI extension
+<FindMembers>{B}*"value class"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Value;
+ addType( current ) ;
+ current->type += " value class" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"ref class{" | // C++/CLI extension
+<FindMembers>{B}*"ref class"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Ref;
+ addType( current ) ;
+ current->type += " ref class" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"interface class{" | // C++/CLI extension
+<FindMembers>{B}*"interface class"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Interface;
+ addType( current ) ;
+ current->type += " interface class" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"coclass"{BN}+ {
+ if (insideIDL)
+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ addType( current ) ;
+ current->type += " coclass" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ BEGIN( CompoundName ) ;
+ }
+ else
+ {
+ addType(current);
+ current->name = yytext;
+ current->name = current->name.stripWhiteSpace();
+ lineCount();
+ }
+ }
+<FindMembers>{B}*{TYPEDEFPREFIX}"struct{" |
+<FindMembers>{B}*{TYPEDEFPREFIX}"struct"/{BN}+ {
+ QCString decl = yytext;
+ isTypedef=decl.find("typedef")!=-1;
+ bool isConst=decl.find("const")!=-1;
+ bool isVolatile=decl.find("volatile")!=-1;
+ current->section = Entry::CLASS_SEC ;
+ current->spec = Entry::Struct |
+ (current->spec & Entry::Published); // preserve UNO IDL
+ // bug 582676: can be a struct nested in an interface so keep insideObjC state
+ //current->objc = insideObjC = FALSE;
+ addType( current ) ;
+ if (isConst)
+ {
+ current->type += " const";
+ }
+ else if (isVolatile)
+ {
+ current->type += " volatile";
+ }
+ current->type += " struct" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"value struct{" | // C++/CLI extension
+<FindMembers>{B}*"value struct"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Struct | Entry::Value;
+ addType( current ) ;
+ current->type += " value struct" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"ref struct{" | // C++/CLI extension
+<FindMembers>{B}*"ref struct"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Struct | Entry::Ref;
+ addType( current ) ;
+ current->type += " ref struct" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*"interface struct{" | // C++/CLI extension
+<FindMembers>{B}*"interface struct"{BN}+ {
+ isTypedef=FALSE;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Struct | Entry::Interface;
+ addType( current ) ;
+ current->type += " interface struct";
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*{TYPEDEFPREFIX}"union{" |
+<FindMembers>{B}*{TYPEDEFPREFIX}"union"{BN}+ {
+ QCString decl=yytext;
+ isTypedef=decl.find("typedef")!=-1;
+ bool isConst=decl.find("const")!=-1;
+ bool isVolatile=decl.find("volatile")!=-1;
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Union;
+ // bug 582676: can be a struct nested in an interface so keep insideObjC state
+ //current->objc = insideObjC = FALSE;
+ addType( current ) ;
+ if (isConst)
+ {
+ current->type += " const";
+ }
+ else if (isVolatile)
+ {
+ current->type += " volatile";
+ }
+ current->type += " union" ;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?"{" |
+<FindMembers>{B}*{TYPEDEFPREFIX}{IDLATTR}?"enum"({BN}+("class"|"struct"))?{BN}+ { // for IDL: typedef [something] enum
+ QCString text=yytext;
+ isTypedef = text.find("typedef")!=-1;
+ bool isStrongEnum = text.find("struct")!=-1 || text.find("class")!=-1;
+ if (insideJava)
+ {
+ current->section = Entry::CLASS_SEC;
+ current->spec = Entry::Enum;
+ }
+ else
+ {
+ current->section = Entry::ENUM_SEC ;
+ }
+ addType( current ) ;
+ current->type += " enum";
+ if (isStrongEnum)
+ {
+ current->spec |= Entry::Strong;
+ }
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->bodyLine = yyLineNr;
+ lineCount() ;
+ if (yytext[yyleng-1]=='{') unput('{');
+ BEGIN( CompoundName ) ;
+ }
+<Operator>"("{BN}*")"({BN}*"<"[^>]*">"){BN}*/"(" { // A::operator()<int>(int arg)
+ lineCount();
+ current->name += "()";
+ BEGIN( FindMembers );
+ }
+<Operator>"("{BN}*")"{BN}*/"(" {
+ lineCount();
+ current->name += yytext ;
+ current->name = current->name.simplifyWhiteSpace();
+ BEGIN( FindMembers ) ;
+ }
+<Operator>";" { // can occur when importing members
+ unput(';');
+ BEGIN( FindMembers ) ;
+ }
+<Operator>[^(] {
+ lineCount();
+ current->name += *yytext ;
+ }
+<Operator>"<>" { /* skip guided templ specifiers */ }
+<Operator>"(" {
+ current->name = current->name.simplifyWhiteSpace();
+ unput(*yytext);
+ BEGIN( FindMembers ) ;
+ }
+<FindMembers>("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension
+ lineCount();
+ if (current->tArgLists==0)
+ {
+ current->tArgLists = new QList<ArgumentList>;
+ current->tArgLists->setAutoDelete(TRUE);
+ }
+ ArgumentList *al = new ArgumentList;
+ //current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template;
+ current->tArgLists->append(al);
+ currentArgumentList = al;
+ templateStr="<";
+ fullArgString = templateStr;
+ copyArgString = &templateStr;
+ currentArgumentContext = FindMembers;
+ BEGIN( ReadTempArgs );
+ }
+<FindMembers>"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias
+ lineCount();
+ BEGIN( NSAliasName );
+ }
+<NSAliasName>{ID} {
+ aliasName = yytext;
+ BEGIN( NSAliasArg );
+ }
+<NSAliasArg>({ID}"::")*{ID} {
+ //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
+ //if (current_root->name.isEmpty())
+ //{
+ // TODO: namespace aliases are now treated as global entities
+ // while they should be aware of the scope they are in
+ Doxygen::namespaceAliasDict.insert(aliasName,new QCString(yytext));
+ //}
+ //else
+ //{
+ // Doxygen::namespaceAliasDict.insert(current_root->name+"::"+aliasName,
+ // new QCString(current_root->name+"::"+yytext));
+ //}
+ }
+<NSAliasArg>";" {
+ BEGIN( FindMembers );
+ }
+<PHPUse>({ID}{BN}*"\\"{BN}*)*{ID}/{BN}+"as" {
+ lineCount();
+ aliasName=yytext;
+ BEGIN(PHPUseAs);
+ }
+<PHPUse>({ID}{BN}*"\\"{BN}*)*{ID} {
+ lineCount();
+ current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::"));
+ //printf("PHP: adding use relation: %s\n",current->name.data());
+ current->fileName = yyFileName;
+ // add a using declaraton
+ current->section=Entry::USINGDECL_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry(*current);
+ // also add it as a using directive
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ aliasName.resize(0);
+ }
+<PHPUseAs>{BN}+"as"{BN}+ {
+ lineCount();
+ }
+<PHPUseAs>{ID} {
+ //printf("PHP: adding use as relation: %s->%s\n",yytext,aliasName.data());
+ Doxygen::namespaceAliasDict.insert(yytext,
+ new QCString(removeRedundantWhiteSpace(
+ substitute(aliasName,"\\","::"))));
+ aliasName.resize(0);
+ }
+<PHPUse,PHPUseAs>[,;] {
+ if (*yytext==',')
+ {
+ BEGIN(PHPUse);
+ }
+ else
+ {
+ BEGIN(FindMembers);
+ }
+ }
+<JavaImport>({ID}{BN}*"."{BN}*)+"*" { // package import => add as a using directive
+ lineCount();
+ QCString scope=yytext;
+ current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::"));
+ current->fileName = yyFileName;
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ initEntry();
+ BEGIN(Using);
+ }
+<JavaImport>({ID}{BN}*"."{BN}*)+{ID} { // class import => add as a using declaration
+ lineCount();
+ QCString scope=yytext;
+ current->name=removeRedundantWhiteSpace(substitute(scope,".","::"));
+ current->fileName = yyFileName;
+ if (insideD)
+ {
+ current->section=Entry::USINGDIR_SEC;
+ }
+ else
+ {
+ //printf("import name = %s -> %s\n",yytext,current->name.data());
+ current->section=Entry::USINGDECL_SEC;
+ }
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(Using);
+ }
+<FindMembers>"using"{BN}+ {
+ current->startLine=yyLineNr;
+ current->startColumn = yyColNr;
+ lineCount();
+ BEGIN(Using);
+ }
+<Using>"namespace"{BN}+ { lineCount(); BEGIN(UsingDirective); }
+<Using>({ID}{BN}*("::"|"."){BN}*)*({ID}|{OPERATOR}) {
+ lineCount();
+ current->name=yytext;
+ current->fileName = yyFileName;
+ current->section=Entry::USINGDECL_SEC;
+ current->startLine = yyLineNr;
+ current_root->addSubEntry(current);
+ previous = current;
+ current = new Entry ;
+ if (insideCS) /* Hack: in C# a using declaration and
+ directive have the same syntax, so we
+ also add it as a using directive here
+ */
+ {
+ current->name=yytext;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ }
+ initEntry();
+ BEGIN(Using);
+ }
+<Using>"=" { // C++11 style template alias?
+ BEGIN(UsingAlias);
+ }
+<UsingAlias>";" {
+ previous->section=Entry::VARIABLE_SEC;
+ previous->type = "typedef "+previous->args;
+ previous->type=previous->type.simplifyWhiteSpace();
+ previous->args.resize(0);
+ previous->name=previous->name.stripWhiteSpace();
+ previous->bodyLine = yyLineNr;
+ previous->spec |= Entry::Alias;
+ BEGIN(FindMembers);
+ }
+<UsingAlias>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
+ docBlockContext = UsingAliasEnd;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+ lineCount();
+
+ docBlockTerm = ';';
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+<UsingAlias>. {
+ previous->args+=yytext;
+ }
+<UsingAlias>\n {
+ previous->args+=yytext;
+ lineCount();
+ }
+<UsingAliasEnd>";" {
+ previous->doc = current->doc;
+ previous->brief = current->brief;
+ current->doc.resize(0);
+ current->brief.resize(0);
+ unput(';');
+ BEGIN(UsingAlias);
+ }
+<UsingDirective>{SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext);
+ current->fileName = yyFileName;
+ current->section=Entry::USINGDIR_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(Using);
+ }
+<Using>";" { BEGIN(FindMembers); }
+<FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl
+ QCString n=yytext;
+ addType( current );
+ current->name=n.left(n.length()-2);
+ }
+<FindMembers>{SCOPENAME}{BN}*/"<" { // Note: this could be a return type!
+ roundCount=0;
+ sharpCount=0;
+ lineCount();
+ addType( current );
+ current->name=yytext;
+ current->name=current->name.stripWhiteSpace();
+ //current->scopeSpec.resize(0);
+ // currentTemplateSpec = ¤t->scopeSpec;
+ if (nameIsOperator(current->name))
+ BEGIN( Operator );
+ else
+ BEGIN( EndTemplate );
+ }
+<FindMemberName>{SCOPENAME}{BN}*/"<" {
+ sharpCount=0;
+ roundCount=0;
+ lineCount();
+ current->name+=((QCString)yytext).stripWhiteSpace();
+ //current->memberSpec.resize(0);
+ // currentTemplateSpec = ¤t->memberSpec;
+ if (nameIsOperator(current->name))
+ BEGIN( Operator );
+ else
+ BEGIN( EndTemplate );
+ }
+<EndTemplate>"<<<" {
+ if (!insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ lastHereDocContext = YY_START;
+ BEGIN(HereDoc);
+ }
+ }
+<ClassTemplSpec,EndTemplate>"<<" {
+ current->name+=yytext;
+ // *currentTemplateSpec+=yytext;
+ }
+<EndTemplate>"<" {
+ if (roundCount==0)
+ {
+ // *currentTemplateSpec+='<';
+ sharpCount++;
+ }
+ current->name+=yytext;
+ }
+<ClassTemplSpec,EndTemplate>">>" {
+ if (insideJava || insideCS || insideCli || roundCount==0)
+ {
+ unput('>');
+ unput(' ');
+ unput('>');
+ }
+ else
+ {
+ current->name+=yytext;
+ }
+ // *currentTemplateSpec+=yytext;
+ }
+<EndTemplate>">" {
+ current->name+='>';
+ // *currentTemplateSpec+='>';
+ if (roundCount==0 && --sharpCount<=0)
+ {
+ //printf("Found %s\n",current->name.data());
+ BEGIN(FindMembers);
+ }
+ }
+<EndTemplate>">"{BN}*"(" {
+ lineCount();
+ current->name+='>';
+ // *currentTemplateSpec+='>';
+ if (roundCount==0 && --sharpCount<=0)
+ {
+ current->bodyLine = yyLineNr;
+ current->args = "(";
+ currentArgumentContext = FuncQual;
+ fullArgString = current->args.copy();
+ copyArgString = ¤t->args;
+ //printf("Found %s\n",current->name.data());
+ BEGIN( ReadFuncArgType ) ;
+ }
+ }
+<EndTemplate>">"{BN}*/"("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+ { // function pointer returning a template instance
+ lineCount();
+ current->name+='>';
+ if (roundCount==0)
+ {
+ BEGIN(FindMembers);
+ }
+ }
+<EndTemplate>">"{BN}*/"::" {
+ lineCount();
+ current->name+='>';
+ // *currentTemplateSpec+='>';
+ if (roundCount==0 && --sharpCount<=0)
+ {
+ BEGIN(FindMemberName);
+ }
+ }
+<ClassTemplSpec,EndTemplate>"(" { current->name+=*yytext;
+ roundCount++;
+ }
+<ClassTemplSpec,EndTemplate>")" { current->name+=*yytext;
+ if (roundCount>0) roundCount--;
+ }
+<EndTemplate>. {
+ current->name+=*yytext;
+ // *currentTemplateSpec+=*yytext;
+ }
+<FindMembers>"define"{BN}*"("{BN}*["'] {
+ if (insidePHP)
+ {
+ current->bodyLine = yyLineNr;
+ BEGIN( DefinePHP );
+ }
+ else
+ REJECT;
+ }
+<CopyHereDoc>{ID} { // PHP heredoc
+ g_delimiter = yytext;
+ *pCopyHereDocGString += yytext;
+ BEGIN(CopyHereDocEnd);
+ }
+<CopyHereDoc>"'"{ID}/"'" { // PHP nowdoc
+ g_delimiter = &yytext[1];
+ *pCopyHereDocGString += yytext;
+ BEGIN(CopyHereDocEnd);
+ }
+<HereDoc>{ID} { // PHP heredoc
+ g_delimiter = yytext;
+ BEGIN(HereDocEnd);
+ }
+<HereDoc>"'"{ID}/"'" { // PHP nowdoc
+ g_delimiter = &yytext[1];
+ BEGIN(HereDocEnd);
+ }
+<HereDocEnd>^{ID} { // id at start of the line could mark the end of the block
+ if (g_delimiter==yytext) // it is the end marker
+ {
+ BEGIN(lastHereDocContext);
+ }
+ }
+<HereDocEnd>. { }
+<CopyHereDocEnd>^{ID} { // id at start of the line could mark the end of the block
+ *pCopyHereDocGString += yytext;
+ if (g_delimiter==yytext) // it is the end marker
+ {
+ BEGIN(lastHereDocContext);
+ }
+ }
+<CopyHereDocEnd>\n {
+ *pCopyHereDocGString += yytext;
+ }
+<CopyHereDocEnd>. {
+ *pCopyHereDocGString += yytext;
+ }
+<FindMembers>"Q_OBJECT" { // Qt object macro
+ }
+<FindMembers>"Q_PROPERTY" { // Qt property declaration
+ //current->protection = protection = Public ; // see bug734245
+ current->mtype = mtype = Property;
+ current->type.resize(0);
+ BEGIN(QtPropType);
+ }
+<QtPropType>"(" { // start of property arguments
+ }
+<QtPropAttr>")" { // end of property arguments
+ unput(';');
+ BEGIN(FindMembers);
+ }
+<QtPropType>"const"|"volatile"|"unsigned"|"signed"|"long"|"short" {
+ current->type+=yytext;
+ }
+<QtPropType>{B}+ {
+ current->type+=yytext;
+ }
+<QtPropType>({TSCOPE}"::")*{TSCOPE} {
+ current->type+=yytext;
+ BEGIN(QtPropName);
+ }
+<QtPropName>{ID} {
+ current->name=yytext;
+ BEGIN(QtPropAttr);
+ }
+<QtPropAttr>"READ" {
+ current->spec |= Entry::Readable;
+ BEGIN(QtPropRead);
+ }
+<QtPropAttr>"WRITE" {
+ current->spec |= Entry::Writable;
+ BEGIN(QtPropWrite);
+ }
+<QtPropAttr>"RESET"{B}+{ID} { // reset method => not supported yet
+ }
+<QtPropAttr>"SCRIPTABLE"{B}+{ID} { // scriptable property => not supported yet
+ }
+<QtPropAttr>"DESIGNABLE"{B}+{ID} { // designable property => not supported yet
+ }
+<QtPropRead>{ID} {
+ current->read = yytext;
+ BEGIN(QtPropAttr);
+ }
+<QtPropWrite>{ID} {
+ current->write = yytext;
+ BEGIN(QtPropAttr);
+ }
+<FindMembers>"friend"{BN}+("class"|"union"|"struct"){BN}+ {
+ current->name=yytext;
+ BEGIN(FindMembers);
+ }
+<FindMembers,FindMemberName>{SCOPENAME} {
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ yyBegColNr=yyColNr;
+ yyBegLineNr=yyLineNr;
+ lineCount();
+ if (insideIDL && yyleng==9 && qstrcmp(yytext,"cpp_quote")==0)
+ {
+ BEGIN(CppQuote);
+ }
+ else if ((insideIDL || insideJava || insideD) && yyleng==6 && qstrcmp(yytext,"import")==0)
+ {
+ if (insideIDL)
+ BEGIN(NextSemi);
+ else // insideJava or insideD
+ BEGIN(JavaImport);
+ }
+ else if (insidePHP && qstrcmp(yytext,"use")==0)
+ {
+ BEGIN(PHPUse);
+ }
+ else if (insideJava && qstrcmp(yytext,"package")==0)
+ {
+ lineCount();
+ BEGIN(PackageName);
+ }
+ else if (insideIDL && qstrcmp(yytext,"case")==0)
+ {
+ BEGIN(IDLUnionCase);
+ }
+ else if (insideTryBlock && qstrcmp(yytext,"catch")==0)
+ {
+ insideTryBlock=FALSE;
+ BEGIN(TryFunctionBlock);
+ }
+ else if (insideCpp && qstrcmp(yytext,"alignas")==0)
+ {
+ lastAlignAsContext = YY_START;
+ BEGIN(AlignAs);
+ }
+ else if (insideJS && qstrcmp(yytext,"var")==0)
+ { // javascript variable
+ current->type="var";
+ }
+ else if (insideJS && qstrcmp(yytext,"function")==0)
+ { // javascript function
+ current->type="function";
+ }
+ else if (insideCS && qstrcmp(yytext,"this")==0)
+ {
+ // C# indexer
+ addType( current ) ;
+ current->name="this";
+ BEGIN(CSIndexer);
+ }
+ else if (insideCpp && qstrcmp(yytext,"static_assert")==0)
+ {
+ // C++11 static_assert
+ BEGIN(StaticAssert);
+ }
+ else if (insideCpp && qstrcmp(yytext,"decltype")==0)
+ {
+ // C++11 decltype(x)
+ current->type+=yytext;
+ BEGIN(DeclType);
+ }
+ else
+ {
+ if (YY_START==FindMembers)
+ {
+ addType( current ) ;
+ }
+ bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS;
+ if (javaLike && qstrcmp(yytext,"public")==0)
+ {
+ current->protection = Public;
+ }
+ else if (javaLike && qstrcmp(yytext,"protected")==0)
+ {
+ current->protection = Protected;
+ }
+ else if (javaLike && qstrcmp(yytext,"internal")==0)
+ {
+ current->protection = Package;
+ }
+ else if (javaLike && qstrcmp(yytext,"private")==0)
+ {
+ current->protection = Private;
+ }
+ else if (javaLike && qstrcmp(yytext,"static")==0)
+ {
+ if (YY_START==FindMembers)
+ current->name = yytext;
+ else
+ current->name += yytext;
+ current->stat = TRUE;
+ }
+ else
+ {
+ if (YY_START==FindMembers)
+ current->name = yytext;
+ else
+ current->name += yytext;
+ if (current->name.left(7)=="static ")
+ {
+ current->stat = TRUE;
+ current->name= current->name.mid(7);
+ }
+ else if (current->name.left(7)=="inline ")
+ {
+ if (current->type.isEmpty())
+ {
+ current->type="inline";
+ }
+ else
+ {
+ current->type+="inline ";
+ }
+ current->name= current->name.mid(7);
+ }
+ else if (current->name.left(6)=="const ")
+ {
+ if (current->type.isEmpty())
+ {
+ current->type="const";
+ }
+ else
+ {
+ current->type+="const ";
+ }
+ current->name=current->name.mid(6);
+ }
+ }
+ QCString tmp=yytext;
+ if (nameIsOperator(tmp))
+ {
+ BEGIN( Operator );
+ }
+ else
+ {
+ BEGIN(FindMembers);
+ }
+ }
+ }
+<StaticAssert>"(" {
+ lastSkipRoundContext = FindMembers;
+ roundCount=1;
+ BEGIN(SkipRound);
+ }
+<StaticAssert>{BN}+ { lineCount(); }
+<StaticAssert>. { // variable with static_assert as name?
+ unput(*yytext);
+ BEGIN(FindMembers);
+ }
+<DeclType>"(" {
+ current->type+=yytext;
+ lastRoundContext=FindMembers;
+ pCopyRoundString=¤t->type;
+ roundCount=0;
+ BEGIN(CopyRound);
+ }
+<DeclType>{BN}+ { lineCount(); }
+<DeclType>. {
+ unput(*yytext);
+ BEGIN(FindMembers);
+ }
+<CSIndexer>"["[^\n\]]*"]" {
+ current->name+=removeRedundantWhiteSpace(yytext);
+ BEGIN(FindMembers);
+ }
+<FindMembers>[0-9]{ID} { // some number where we did not expect one
+ }
+<FindMembers>"." {
+ if (insideJava || insideCS || insideD)
+ {
+ current->name+=".";
+ }
+ }
+<FindMembers>"::" {
+ current->name+=yytext;
+ }
+<CppQuote>"("{B}*"\"" {
+ insideCppQuote=TRUE;
+ BEGIN(FindMembers);
+ }
+<IDLUnionCase>"::"
+<IDLUnionCase>":" { BEGIN(FindMembers); }
+<IDLUnionCase>\n { lineCount(); }
+<IDLUnionCase>.
+<TryFunctionBlock>\n { lineCount(); }
+<TryFunctionBlock>"{" {
+ curlyCount=0;
+ lastCurlyContext = TryFunctionBlockEnd ;
+ BEGIN( SkipCurly );
+ }
+<TryFunctionBlock>.
+<TryFunctionBlockEnd>{BN}*"catch" { lineCount(); BEGIN(TryFunctionBlock); // {BN}* added to fix bug 611193
+ }
+<TryFunctionBlockEnd>\n { unput(*yytext); // rule added to fix bug id 601138
+ BEGIN( FindMembers );
+ }
+<TryFunctionBlockEnd>. { unput(*yytext);
+ BEGIN( FindMembers );
+ }
+<EndCppQuote>")" {
+ insideCppQuote=FALSE;
+ BEGIN(FindMembers);
+ }
+<FindMembers,FindFields>{B}*"#" { if (insidePHP)
+ REJECT;
+ lastCPPContext = YY_START;
+ BEGIN( SkipCPP ) ;
+ }
+<FindMembers,FindFields>{B}*"#"{B}*("cmake")?"define" {
+ if (insidePHP)
+ REJECT;
+ current->bodyLine = yyLineNr;
+ lastDefineContext = YY_START;
+ BEGIN( Define );
+ }
+<FindMembers,ReadBody,ReadNSBody,ReadBodyIntf,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
+ yyLineNr = atoi(&yytext[1]);
+ //printf("setting line number to %d\n",yyLineNr);
+ lastPreLineCtrlContext = YY_START;
+ if (YY_START==ReadBody ||
+ YY_START==ReadNSBody ||
+ YY_START==ReadBodyIntf)
+ {
+ current->program+=yytext;
+ }
+ BEGIN( PreLineCtrl );
+ }
+<PreLineCtrl>"\""[^\n\"]*"\"" {
+ yyFileName = stripQuotes(yytext);
+ if (lastPreLineCtrlContext==ReadBody ||
+ lastPreLineCtrlContext==ReadNSBody ||
+ lastPreLineCtrlContext==ReadBodyIntf)
+ {
+ current->program+=yytext;
+ }
+ }
+<PreLineCtrl>. {
+ if (lastPreLineCtrlContext==ReadBody ||
+ lastPreLineCtrlContext==ReadNSBody ||
+ lastPreLineCtrlContext==ReadBodyIntf)
+ {
+ current->program+=yytext;
+ }
+ }
+<PreLineCtrl>\n {
+ if (lastPreLineCtrlContext==ReadBody ||
+ lastPreLineCtrlContext==ReadNSBody ||
+ lastPreLineCtrlContext==ReadBodyIntf)
+ {
+ current->program+=yytext;
+ }
+ lineCount();
+ BEGIN( lastPreLineCtrlContext );
+ }
+<SkipCPP>.
+<SkipCPP>\\[\r]*"\n"[\r]* { lineCount(); }
+<SkipCPP>[\r]*\n[\r]* { lineCount();
+ BEGIN( lastCPPContext) ;
+ }
+<Define>{ID}{B}*"(" {
+ current->name = yytext;
+ current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
+ current->args = "(";
+ current->bodyLine = yyLineNr;
+ currentArgumentContext = DefineEnd;
+ fullArgString=current->args.copy();
+ copyArgString=¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ }
+ /*
+<DefineArg>")" {
+ //printf("Define with args\n");
+ current->args += ')';
+ BEGIN( DefineEnd );
+ }
+<DefineArg>. {
+ current->args += *yytext;
+ }
+ */
+<Define>{ID} {
+ //printf("Define `%s' without args\n",yytext);
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ current->bodyLine = yyLineNr;
+ current->name = yytext;
+ BEGIN(DefineEnd);
+ }
+<DefineEnd>\n {
+ //printf("End define: doc=%s docFile=%s docLine=%d\n",current->doc.data(),current->docFile.data(),current->docLine);
+ lineCount();
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->type.resize(0);
+ current->args = current->args.simplifyWhiteSpace();
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::DEFINE_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(lastDefineContext);
+ }
+<DefinePHPEnd>";" {
+ //printf("End define\n");
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->type.resize(0);
+ current->type = "const";
+ QCString init = current->initializer.data();
+ init = init.simplifyWhiteSpace();
+ init = init.left(init.length()-1);
+ current->initializer = init;
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::VARIABLE_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ BEGIN(FindMembers);
+ }
+<DefinePHPEnd>.
+<DefineEnd>\\[\r]?\n {
+ lineCount();
+ }
+<DefineEnd>\" {
+ if (insideIDL && insideCppQuote)
+ {
+ BEGIN(EndCppQuote);
+ }
+ else
+ {
+ lastStringContext=DefineEnd;
+ BEGIN(SkipString);
+ }
+ }
+<DefineEnd>.
+<DefinePHP>{ID}["']{BN}*","{BN}* {
+ current->name = yytext;
+ current->name = current->name.stripWhiteSpace();
+ current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
+ current->name = current->name.left(current->name.length()-1);
+ current->bodyLine = yyLineNr;
+ lastRoundContext = DefinePHPEnd;
+ pCopyRoundGString = ¤t->initializer;
+ roundCount = 0;
+ BEGIN( GCopyRound );
+ }
+
+<FindMembers>[\^%] { // ^ and % are C++/CLI extensions
+ if (insideCli)
+ {
+ addType( current );
+ current->name = yytext ;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<FindMembers>[*&]+ {
+ current->name += yytext ;
+ addType( current );
+ }
+<FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
+ if (current->bodyLine==-1)
+ {
+ current->bodyLine=yyLineNr;
+ }
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+ //printf("indent=%d\n",computeIndent(yytext+1,g_column));
+ lineCount();
+
+ docBlockTerm = ';';
+ if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC)
+ {
+ current->bitfields = ":"+current->args;
+ current->args.resize(0);
+ current->section=Entry::VARIABLE_SEC;
+ }
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+<MemberSpec,FindFields,FindMembers,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>","{BN}*("/**"|"//!"|"/*!"|"///")"<" {
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+ lineCount();
+
+ docBlockTerm = ',';
+ if (YY_START==EnumBaseType && current->section==Entry::ENUM_SEC)
+ {
+ current->bitfields = ":"+current->args;
+ current->args.resize(0);
+ current->section=Entry::VARIABLE_SEC;
+ }
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+<DefineEnd,FindFields,FindFieldArg,ReadInitializer,OldStyleArgs>{BN}*("/**"|"//!"|"/*!"|"///")"<" {
+ if (current->bodyLine==-1)
+ {
+ current->bodyLine=yyLineNr;
+ }
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+ lineCount();
+
+ docBlockTerm = 0;
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+
+<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") {
+ //handleGroupStartCommand(current->name);
+ if (previous && previous->section==Entry::GROUPDOC_SEC)
+ {
+ // link open command to the group defined in the previous entry
+ openGroup(previous,yyFileName,yyLineNr);
+ }
+ else
+ {
+ // link open command to the current entry
+ openGroup(current,yyFileName,yyLineNr);
+ }
+ //current = tmp;
+ initEntry();
+ if (yytext[1]=='/')
+ {
+ if (yytext[2]=='!' || yytext[2]=='/')
+ {
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = FALSE;
+ docBlock.resize(0);
+ docBlockTerm = 0;
+ startCommentBlock(TRUE);
+ BEGIN(DocLine);
+ }
+ else
+ {
+ lastCContext=YY_START;
+ BEGIN(SkipCxxComment);
+ }
+ }
+ else
+ {
+ if (yytext[2]=='!' || yytext[2]=='*')
+ {
+ docBlockContext = YY_START;
+ docBlockInBody = FALSE;
+ docBlock.resize(0);
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+ docBlockTerm = 0;
+ startCommentBlock(FALSE);
+ BEGIN(DocBlock);
+ }
+ else
+ {
+ lastCContext=YY_START;
+ BEGIN(SkipComment);
+ }
+ }
+ }
+<FindMembers,FindFields,ReadInitializer>"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}"[^*]*"*/" {
+ closeGroup(current,yyFileName,yyLineNr);
+ }
+<FindMembers>"=" { // in PHP code this could also be due to "<?="
+ current->bodyLine = yyLineNr;
+ current->initializer = yytext;
+ lastInitializerContext = YY_START;
+ initBracketCount=0;
+ BEGIN(ReadInitializer);
+ }
+<UNOIDLAttributeBlock>{BN}*[gs]"et"{BN}+"raises"{BN}*"("{BN}*{SCOPENAME}{BN}*(","{BN}*{SCOPENAME}{BN}*)*")"{BN}*";" {
+ lineCount();
+ current->exception += " ";
+ current->exception += removeRedundantWhiteSpace(yytext);
+ }
+<UNOIDLAttributeBlock>"}" {
+ current->exception += " }";
+ BEGIN(FindMembers);
+ }
+ /* Read initializer rules */
+<ReadInitializer>"(" {
+ lastRoundContext=YY_START;
+ pCopyRoundGString=¤t->initializer;
+ roundCount=0;
+ current->initializer+=*yytext;
+ BEGIN(GCopyRound);
+ }
+<ReadInitializer>"{" {
+ lastCurlyContext=YY_START;
+ pCopyCurlyGString=¤t->initializer;
+ curlyCount=0;
+ current->initializer+=*yytext;
+ BEGIN(GCopyCurly);
+ }
+<ReadInitializer>[;,] {
+ //printf(">> initializer `%s' <<\n",current->initializer.data());
+ if (*yytext==';' && (current_root->spec&Entry::Enum))
+ {
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->args = current->args.simplifyWhiteSpace();
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::VARIABLE_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ initEntry();
+ BEGIN(FindMembers);
+ }
+ else if (*yytext==';' || (lastInitializerContext==FindFields && initBracketCount==0)) // initBracketCount==0 was added for bug 665778
+ {
+ unput(*yytext);
+ BEGIN(lastInitializerContext);
+ }
+ else if (*yytext==',' && initBracketCount==0) // for "int a=0,b=0"
+ {
+ unput(*yytext);
+ BEGIN(lastInitializerContext);
+ }
+ else
+ {
+ current->initializer+=*yytext;
+ }
+ }
+<ReadInitializer>{RAWBEGIN} { // C++11 raw string
+ if (!insideCpp)
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString text=yytext;
+ current->initializer+=text;
+ int i=text.find('"');
+ g_delimiter = yytext+i+1;
+ g_delimiter=g_delimiter.left(g_delimiter.length()-1);
+ lastRawStringContext = YY_START;
+ pCopyRawGString = ¤t->initializer;
+ BEGIN(RawGString);
+ //printf("RawGString delimiter='%s'\n",delimiter.data());
+ }
+ }
+<RawGString>{RAWEND} {
+ *pCopyRawGString+=yytext;
+ QCString delimiter = yytext+1;
+ delimiter=delimiter.left(delimiter.length()-1);
+ if (delimiter==g_delimiter)
+ {
+ BEGIN(lastRawStringContext);
+ }
+ }
+<RawGString>[^)\n]+ {
+ *pCopyRawGString+=yytext;
+ }
+<RawGString>. {
+ *pCopyRawGString+=yytext;
+ }
+<RawGString>\n {
+ *pCopyRawGString+=yytext;
+ lineCount();
+ }
+<RawString>{RAWEND} {
+ *pCopyRawString+=yytext;
+ fullArgString+=yytext;
+ QCString delimiter = yytext+1;
+ delimiter=delimiter.left(delimiter.length()-1);
+ if (delimiter==g_delimiter)
+ {
+ BEGIN(lastRawStringContext);
+ }
+ }
+<RawString>[^)]+ {
+ *pCopyRawString+=yytext;
+ fullArgString+=yytext;
+ }
+<RawString>. {
+ *pCopyRawString+=yytext;
+ fullArgString+=yytext;
+ }
+<RawString>\n {
+ *pCopyRawString+=yytext;
+ fullArgString+=yytext;
+ lineCount();
+ }
+<ReadInitializer>\" {
+ if (insideIDL && insideCppQuote)
+ {
+ BEGIN(EndCppQuote);
+ }
+ else
+ {
+ lastStringContext=YY_START;
+ current->initializer+=yytext;
+ pCopyQuotedGString=¤t->initializer;
+ BEGIN(CopyGString);
+ }
+ }
+<ReadInitializer>"->" {
+ current->initializer+=yytext;
+ }
+<ReadInitializer>"<<" {
+ current->initializer+=yytext;
+ }
+<ReadInitializer>">>" {
+ current->initializer+=yytext;
+ }
+<ReadInitializer>[<\[{(] {
+ initBracketCount++;
+ current->initializer+=*yytext;
+ }
+<ReadInitializer>[>\]})] {
+ initBracketCount--;
+ current->initializer+=*yytext;
+ }
+<ReadInitializer>\' {
+ if (insidePHP)
+ {
+ current->initializer+=yytext;
+ pCopyQuotedGString = ¤t->initializer;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPGString);
+ }
+ else
+ {
+ current->initializer+=yytext;
+ }
+ }
+<ReadInitializer>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ current->initializer+=yytext;
+ }
+ }
+<ReadInitializer>\n {
+ current->initializer+=*yytext;
+ lineCount();
+ }
+<ReadInitializer>"@\"" {
+ //printf("insideCS=%d\n",insideCS);
+ current->initializer+=yytext;
+ if (!insideCS && !insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ // C#/ObjC verbatim string
+ lastSkipVerbStringContext=YY_START;
+ pSkipVerbString=¤t->initializer;
+ BEGIN(SkipVerbString);
+ }
+ }
+<SkipVerbString>[^\n"]+ {
+ *pSkipVerbString+=yytext;
+ }
+<SkipVerbString>"\"\"" { // quote escape
+ *pSkipVerbString+=yytext;
+ }
+<SkipVerbString>"\"" {
+ *pSkipVerbString+=*yytext;
+ BEGIN(lastSkipVerbStringContext);
+ }
+<SkipVerbString>\n {
+ *pSkipVerbString+=*yytext;
+ lineCount();
+ }
+<SkipVerbString>. {
+ *pSkipVerbString+=*yytext;
+ }
+<ReadInitializer>"?>" {
+ if (insidePHP)
+ BEGIN( FindMembersPHP );
+ else
+ current->initializer+=yytext;
+ }
+<ReadInitializer>. {
+ current->initializer+=*yytext;
+ }
+
+ /* generic quoted string copy rules */
+<CopyString,CopyPHPString>\\. {
+ *pCopyQuotedString+=yytext;
+ }
+<CopyString>\" {
+ *pCopyQuotedString+=*yytext;
+ BEGIN( lastStringContext );
+ }
+<CopyPHPString>\' {
+ *pCopyQuotedString+=*yytext;
+ BEGIN( lastStringContext );
+ }
+<CopyString,CopyPHPString>"/*"|"*/"|"//" {
+ *pCopyQuotedString+=yytext;
+ }
+<CopyString,CopyPHPString>\n {
+ *pCopyQuotedString+=*yytext;
+ lineCount();
+ }
+<CopyString,CopyPHPString>. {
+ *pCopyQuotedString+=*yytext;
+ }
+
+ /* generic quoted growable string copy rules */
+<CopyGString,CopyPHPGString>\\. {
+ *pCopyQuotedGString+=yytext;
+ }
+<CopyGString>\" {
+ *pCopyQuotedGString+=*yytext;
+ BEGIN( lastStringContext );
+ }
+<CopyPHPGString>\' {
+ *pCopyQuotedGString+=*yytext;
+ BEGIN( lastStringContext );
+ }
+<CopyGString,CopyPHPGString>"/*"|"*/"|"//" {
+ *pCopyQuotedGString+=yytext;
+ }
+<CopyGString,CopyPHPGString>\n {
+ *pCopyQuotedGString+=*yytext;
+ lineCount();
+ }
+<CopyGString,CopyPHPGString>. {
+ *pCopyQuotedGString+=*yytext;
+ }
+
+ /* generic round bracket list copy rules */
+<CopyRound>\" {
+ *pCopyRoundString+=*yytext;
+ pCopyQuotedString=pCopyRoundString;
+ lastStringContext=YY_START;
+ BEGIN(CopyString);
+ }
+<CopyRound>"(" {
+ *pCopyRoundString+=*yytext;
+ roundCount++;
+ }
+<CopyRound>")" {
+ *pCopyRoundString+=*yytext;
+ if (--roundCount<0)
+ BEGIN(lastRoundContext);
+ }
+<CopyRound>\n {
+ lineCount();
+ *pCopyRoundString+=*yytext;
+ }
+<CopyRound>\' {
+ if (insidePHP)
+ {
+ current->initializer+=yytext;
+ pCopyQuotedString = pCopyRoundString;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPString);
+ }
+ else
+ {
+ *pCopyRoundString+=yytext;
+ }
+ }
+<CopyRound>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ *pCopyRoundString+=yytext;
+ }
+ }
+<CopyRound>[^"'()\n]+ {
+ *pCopyRoundString+=yytext;
+ }
+<CopyRound>. {
+ *pCopyRoundString+=*yytext;
+ }
+
+ /* generic round bracket list copy rules for growable strings */
+<GCopyRound>\" {
+ *pCopyRoundGString+=*yytext;
+ pCopyQuotedGString=pCopyRoundGString;
+ lastStringContext=YY_START;
+ BEGIN(CopyGString);
+ }
+<GCopyRound>"(" {
+ *pCopyRoundGString+=*yytext;
+ roundCount++;
+ }
+<GCopyRound>")" {
+ *pCopyRoundGString+=*yytext;
+ if (--roundCount<0)
+ BEGIN(lastRoundContext);
+ }
+<GCopyRound>\n {
+ lineCount();
+ *pCopyRoundGString+=*yytext;
+ }
+<GCopyRound>\' {
+ if (insidePHP)
+ {
+ current->initializer+=yytext;
+ pCopyQuotedGString = pCopyRoundGString;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPGString);
+ }
+ else
+ {
+ *pCopyRoundGString+=yytext;
+ }
+ }
+<GCopyRound>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ *pCopyRoundGString+=yytext;
+ }
+ }
+<GCopyRound>[^"'()\n/]+ {
+ *pCopyRoundGString+=yytext;
+ }
+<GCopyRound>. {
+ *pCopyRoundGString+=*yytext;
+ }
+
+ /* generic curly bracket list copy rules */
+<CopyCurly>\" {
+ *pCopyCurlyString+=*yytext;
+ pCopyQuotedString=pCopyCurlyString;
+ lastStringContext=YY_START;
+ BEGIN(CopyString);
+ }
+<CopyCurly>\' {
+ *pCopyCurlyString+=*yytext;
+ if (insidePHP)
+ {
+ pCopyQuotedString=pCopyCurlyString;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPString);
+ }
+ }
+<CopyCurly>"{" {
+ *pCopyCurlyString+=*yytext;
+ curlyCount++;
+ }
+<CopyCurly>"}" {
+ *pCopyCurlyString+=*yytext;
+ if (--curlyCount<0)
+ BEGIN(lastCurlyContext);
+ }
+<CopyCurly>{CHARLIT} { if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ *pCopyCurlyString+=yytext;
+ }
+ }
+<CopyCurly>[^"'{}\/\n]+ {
+ *pCopyCurlyString+=yytext;
+ }
+<CopyCurly>"/" { *pCopyCurlyString+=yytext; }
+<CopyCurly>\n {
+ lineCount();
+ *pCopyCurlyString+=*yytext;
+ }
+<CopyCurly>. {
+ *pCopyCurlyString+=*yytext;
+ }
+
+ /* generic curly bracket list copy rules for growable strings */
+<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"1"{B}*\n? { // start of included file marker
+ }
+<GCopyCurly>^"#"{B}+[0-9]+{B}+"\""[^\"\n]+"\""{B}+"2"{B}*\n? { // end of included file marker
+ QCString line = QCString(yytext);
+ int s = line.find(' ');
+ int e = line.find('"',s);
+ yyLineNr = line.mid(s,e-s).toInt();
+ if (yytext[yyleng-1]=='\n')
+ {
+ lineCount();
+ g_column=0;
+ }
+ }
+<GCopyCurly>\" {
+ *pCopyCurlyGString+=*yytext;
+ pCopyQuotedGString=pCopyCurlyGString;
+ lastStringContext=YY_START;
+ BEGIN(CopyGString);
+ }
+<GCopyCurly>\' {
+ *pCopyCurlyGString+=*yytext;
+ if (insidePHP)
+ {
+ pCopyQuotedGString=pCopyCurlyGString;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPGString);
+ }
+ }
+<GCopyCurly>"{" {
+ *pCopyCurlyGString+=*yytext;
+ curlyCount++;
+ }
+<GCopyCurly>"}" {
+ *pCopyCurlyGString+=*yytext;
+ if (--curlyCount<0)
+ BEGIN(lastCurlyContext);
+ }
+<GCopyCurly>{CHARLIT} { if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ *pCopyCurlyGString+=yytext;
+ }
+ }
+<GCopyCurly>[^"'{}\/\n,]+ {
+ *pCopyCurlyGString+=yytext;
+ }
+<GCopyCurly>[,]+ {
+ *pCopyCurlyGString+=yytext;
+ }
+<GCopyCurly>"/" { *pCopyCurlyGString+=yytext; }
+<GCopyCurly>\n {
+ lineCount();
+ *pCopyCurlyGString+=*yytext;
+ }
+<GCopyCurly>. {
+ *pCopyCurlyGString+=*yytext;
+ }
+
+ /* ---------------------- */
+
+
+<FindMembers>":" {
+ if (current->type.isEmpty() &&
+ current->name=="enum") // see bug 69041, C++11 style anon enum: 'enum : unsigned int {...}'
+ {
+ current->section=Entry::ENUM_SEC;
+ current->name.resize(0);
+ current->args.resize(0);
+ BEGIN(EnumBaseType);
+ }
+ else
+ {
+ if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;"
+ {
+ addType(current);
+ current->name.sprintf("__pad%d__",padCount++);
+ }
+ BEGIN(BitFields);
+ current->bitfields+=":";
+ }
+ }
+<BitFields>. {
+ current->bitfields+=*yytext;
+ }
+<EnumBaseType>. {
+ current->args+=*yytext;
+ }
+<EnumBaseType>\n {
+ lineCount();
+ current->args+=' ';
+ }
+<FindMembers>[;,] {
+ QCString oldType = current->type;
+ if (current->bodyLine==-1)
+ {
+ current->bodyLine = yyLineNr;
+ }
+ if ( insidePHP && current->type.left(3) == "var" )
+ {
+ current->type = current->type.mid(3);
+ }
+ if (isTypedef && current->type.left(8)!="typedef ")
+ {
+ current->type.prepend("typedef ");
+ }
+ bool needNewCurrent=FALSE;
+ if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC)
+ {
+ current->type=current->type.simplifyWhiteSpace();
+ current->args=removeRedundantWhiteSpace(current->args);
+ current->name=current->name.stripWhiteSpace();
+ if (current->section==Entry::CLASS_SEC) // remove spec for "struct Bla bla;"
+ {
+ current->spec = 0;
+ }
+ current->section = Entry::VARIABLE_SEC ;
+ current->fileName = yyFileName;
+ current->startLine = yyBegLineNr;
+ current->startColumn = yyBegColNr;
+ current_root->addSubEntry( current ) ;
+ needNewCurrent=TRUE;
+ }
+ if ( *yytext == ',')
+ {
+ bool stat = current->stat;
+ if (needNewCurrent)
+ {
+ current = new Entry(*current);
+ initEntry();
+ }
+ current->stat = stat; // the static attribute holds for all variables
+ current->name.resize(0);
+ current->args.resize(0);
+ current->brief.resize(0);
+ current->doc.resize(0);
+ current->initializer.resize(0);
+ current->bitfields.resize(0);
+ int i=oldType.length();
+ while (i>0 && (oldType[i-1]=='*' || oldType[i-1]=='&' || oldType[i-1]==' ')) i--;
+ current->type = oldType.left(i);
+ }
+ else
+ {
+ mtype = Method;
+ virt = Normal;
+ if (needNewCurrent)
+ {
+ current = new Entry ;
+ }
+ else if (current->groups)
+ {
+ current->groups->clear();
+ }
+ initEntry();
+ }
+ }
+
+<FindMembers>"[" {
+ if (!insideCS &&
+ (current->name.isEmpty() ||
+ current->name=="typedef"
+ )
+ ) // IDL function property
+ {
+ squareCount=1;
+ lastSquareContext = YY_START;
+ idlAttr.resize(0);
+ idlProp.resize(0);
+ current->mtype = mtype;
+ BEGIN( IDLAttribute );
+ }
+ else if (insideCS &&
+ current->name.isEmpty())
+ {
+ squareCount=1;
+ lastSquareContext = YY_START;
+ // Skip the C# attribute
+ // for this member
+ current->args.resize(0);
+ BEGIN( SkipSquare );
+ }
+ else
+ {
+ current->args += yytext ;
+ squareCount=1;
+ BEGIN( Array ) ;
+ }
+ }
+<IDLAttribute>"]" {
+ // end of IDL function attribute
+ if (--squareCount<=0)
+ {
+ lineCount();
+ if (current->mtype == Property)
+ BEGIN( IDLPropName );
+ else
+ BEGIN( lastSquareContext );
+ }
+ }
+<IDLAttribute>"propput" {
+ if (Config_getBool("IDL_PROPERTY_SUPPORT"))
+ {
+ current->mtype = Property;
+ }
+ current->spec |= Entry::Settable;
+ }
+<IDLAttribute>"propget" {
+ if (Config_getBool("IDL_PROPERTY_SUPPORT"))
+ {
+ current->mtype = Property;
+ }
+ current->spec |= Entry::Gettable;
+ }
+<IDLAttribute>"property" { // UNO IDL property
+ current->spec |= Entry::Property;
+ }
+<IDLAttribute>"attribute" { // UNO IDL attribute
+ current->spec |= Entry::Attribute;
+ }
+<IDLAttribute>"optional" { // on UNO IDL interface/service/attribute/property
+ current->spec |= Entry::Optional;
+ }
+<IDLAttribute>"readonly" { // on UNO IDL attribute or property
+ current->spec |= Entry::Readonly;
+ }
+<IDLAttribute>"bound" { // on UNO IDL attribute or property
+ current->spec |= Entry::Bound;
+ }
+<IDLAttribute>"removable" { // on UNO IDL property
+ current->spec |= Entry::Removable;
+ }
+<IDLAttribute>"constrained" { // on UNO IDL property
+ current->spec |= Entry::Constrained;
+ }
+<IDLAttribute>"transient" { // on UNO IDL property
+ current->spec |= Entry::Transient;
+ }
+<IDLAttribute>"maybevoid" { // on UNO IDL property
+ current->spec |= Entry::MaybeVoid;
+ }
+<IDLAttribute>"maybedefault" { // on UNO IDL property
+ current->spec |= Entry::MaybeDefault;
+ }
+<IDLAttribute>"maybeambiguous" { // on UNO IDL property
+ current->spec |= Entry::MaybeAmbiguous;
+ }
+<IDLAttribute>. {
+ }
+<IDLPropName>{BN}*{ID}{BN}* {
+ // return type (probably HRESULT) - skip it
+ }
+<IDLPropName>{ID}{BN}*"(" {
+ current->name = yytext;
+ current->name = current->name.left(current->name.length()-1).stripWhiteSpace();
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ BEGIN( IDLProp );
+ }
+<IDLProp>{BN}*"["[^\]]*"]"{BN}* { // attribute of a parameter
+ idlAttr = yytext;
+ idlAttr=idlAttr.stripWhiteSpace();
+ }
+<IDLProp>{ID} { // property type
+ idlProp = yytext;
+ }
+<IDLProp>{BN}*{ID}{BN}*"," { // Rare: Another parameter ([propput] HRESULT Item(int index, [in] Type theRealProperty);)
+ if (!current->args)
+ current->args = "(";
+ else
+ current->args += ", ";
+ current->args += idlAttr;
+ current->args += " ";
+ current->args += idlProp; // prop was actually type of extra parameter
+ current->args += " ";
+ current->args += yytext;
+ current->args = current->args.left(current->args.length() - 1); // strip comma
+ idlProp.resize(0);
+ idlAttr.resize(0);
+ BEGIN( IDLProp );
+ }
+<IDLProp>{BN}*{ID}{BN}*")"{BN}* {
+ // the parameter name for the property - just skip.
+ }
+<IDLProp>";" {
+ current->fileName = yyFileName;
+ current->type = idlProp;
+ current->args = current->args.simplifyWhiteSpace();
+ if (current->args)
+ current->args += ")";
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::VARIABLE_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ initEntry();
+ BEGIN( FindMembers );
+ }
+<IDLProp>. { // spaces, *, or other stuff
+ //idlProp+=yytext;
+ }
+<Array>"]" { current->args += *yytext ;
+ if (--squareCount<=0)
+ BEGIN( FindMembers ) ;
+ }
+<FuncFuncArray>"]" { current->args += *yytext ;
+ if (--squareCount<=0)
+ BEGIN( Function ) ;
+ }
+<Array,FuncFuncArray>"[" { current->args += *yytext ;
+ squareCount++;
+ }
+<Array,FuncFuncArray>. { current->args += *yytext ; }
+<SkipSquare>"[" { squareCount++; }
+<SkipSquare>"]" {
+ if (--squareCount<=0)
+ BEGIN( lastSquareContext );
+ }
+<SkipSquare>\" {
+ lastStringContext=YY_START;
+ BEGIN( SkipString );
+ }
+<SkipSquare>[^\n\[\]\"]+
+<FindMembers>"<" { addType( current ) ;
+ current->type += yytext ;
+ BEGIN( Sharp ) ;
+ }
+<Sharp>">" { current->type += *yytext ;
+ if (--sharpCount<=0)
+ BEGIN( FindMembers ) ;
+ }
+<Sharp>"<" { current->type += *yytext ;
+ sharpCount++;
+ }
+<Sharp>{BN}+ {
+ lineCount();
+ }
+<Sharp>. { current->type += *yytext ; }
+<FindFields>{ID} {
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ current->bodyLine = yyLineNr;
+ current->name = yytext;
+ }
+<FindFields>"(" {
+ // Java enum initializer
+ unput('(');
+ lastInitializerContext = YY_START;
+ initBracketCount=0;
+ current->initializer = "=";
+ BEGIN(ReadInitializer);
+ }
+<FindFields>"=" {
+ lastInitializerContext = YY_START;
+ initBracketCount=0;
+ current->initializer = yytext;
+ BEGIN(ReadInitializer);
+ }
+<FindFields>";" {
+ if (insideJava) // last enum field in Java class
+ {
+ if (!current->name.isEmpty())
+ {
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ current->type = "@"; // enum marker
+ current->args = current->args.simplifyWhiteSpace();
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::VARIABLE_SEC;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ }
+
+ BEGIN( FindMembers );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<SkipRemainder>\n {
+ lineCount();
+ }
+<SkipRemainder>[^\n]*
+<FindFields>"," {
+ //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n",
+ // current->type.data(), current->name.data(),
+ // current->args.data(), current_root->name.data(),current->mGrpId);
+ if (!current->name.isEmpty())
+ {
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->startColumn = yyColNr;
+ if (!(current_root->spec&Entry::Enum))
+ {
+ current->type = "@"; // enum marker
+ }
+ current->args = current->args.simplifyWhiteSpace();
+ current->name = current->name.stripWhiteSpace();
+ current->section = Entry::VARIABLE_SEC;
+ // add to the scope of the enum
+ current_root->addSubEntry(current);
+ if (!insideCS && !insideJava &&
+ !(current_root->spec&Entry::Strong))
+ // for C# and Java 1.5+ enum values always have to be explicitly qualified,
+ // same for C++11 style enums (enum class Name {})
+ {
+ current = new Entry(*current);
+ // add to the scope surrounding the enum (copy!)
+ current_root->parent()->addSubEntry(current);
+ }
+ current = new Entry ;
+ initEntry();
+ }
+ else // probably a redundant ,
+ {
+ current->reset();
+ initEntry();
+ }
+ }
+<FindFields>"[" { // attribute list in IDL
+ squareCount=1;
+ lastSquareContext = YY_START;
+ BEGIN(SkipSquare);
+ }
+ /*
+<FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); }
+ */
+<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/<]* { current->program += yytext ; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"//".* { current->program += yytext ; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"#".* { if (!insidePHP)
+ REJECT;
+ // append PHP comment.
+ current->program += yytext ;
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>@\" { current->program += yytext ;
+ pSkipVerbString = ¤t->program;
+ lastSkipVerbStringContext=YY_START;
+ BEGIN( SkipVerbString );
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>"<<<" { if (insidePHP)
+ {
+ current->program += yytext ;
+ pCopyHereDocGString = ¤t->program;
+ lastHereDocContext=YY_START;
+ BEGIN( CopyHereDoc );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>\" { current->program += yytext ;
+ pCopyQuotedGString = ¤t->program;
+ lastStringContext=YY_START;
+ BEGIN( CopyGString );
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>"/*"{B}* { current->program += yytext ;
+ lastContext = YY_START ;
+ BEGIN( Comment ) ;
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>"/*"{BL} { current->program += yytext ;
+ ++yyLineNr ;
+ lastContext = YY_START ;
+ BEGIN( Comment ) ;
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>"'" {
+ if (!insidePHP)
+ {
+ current->program += yytext;
+ }
+ else
+ { // begin of single quoted string
+ current->program += yytext;
+ pCopyQuotedGString = ¤t->program;
+ lastStringContext=YY_START;
+ BEGIN(CopyPHPGString);
+ }
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT; // for PHP code single quotes
+ // are used for strings of arbitrary length
+ }
+ else
+ {
+ current->program += yytext;
+ }
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>"{" { current->program += yytext ;
+ ++curlyCount ;
+ }
+<ReadBodyIntf>"}" {
+ current->program += yytext ;
+ --curlyCount ;
+ }
+<ReadBody,ReadNSBody>"}" { //err("ReadBody count=%d\n",curlyCount);
+ if ( curlyCount>0 )
+ {
+ current->program += yytext ;
+ --curlyCount ;
+ }
+ else
+ {
+ current->endBodyLine = yyLineNr;
+ QCString &cn = current->name;
+ QCString rn = current_root->name.copy();
+ //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef);
+ if (!cn.isEmpty() && !rn.isEmpty())
+ {
+ prependScope();
+ }
+ if (isTypedef && cn.isEmpty())
+ {
+ //printf("Typedef Name\n");
+ BEGIN( TypedefName );
+ }
+ else
+ {
+ if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
+ {
+ current->program+=','; // add field terminator
+ }
+ // add compound definition to the tree
+ current->args=removeRedundantWhiteSpace(current->args);
+ // was: current->args.simplifyWhiteSpace();
+ current->type = current->type.simplifyWhiteSpace();
+ current->name = current->name.stripWhiteSpace();
+ //printf("adding `%s' `%s' `%s' brief=%s insideObjC=%d %x\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data(),insideObjC,current->section);
+ if (insideObjC &&
+ ((current->spec&Entry::Interface) || (current->spec==Entry::Category))
+ ) // method definition follows
+ {
+ BEGIN( ReadBodyIntf ) ;
+ }
+ else
+ {
+ current_root->addSubEntry( current ) ;
+ memspecEntry = current;
+ current = new Entry(*current);
+ if (current->section==Entry::NAMESPACE_SEC ||
+ (current->spec==Entry::Interface) ||
+ insideJava || insidePHP || insideCS || insideD || insideJS
+ )
+ { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
+ current->reset();
+ initEntry();
+ memspecEntry = 0;
+ BEGIN( FindMembers ) ;
+ }
+ else
+ {
+ static QRegExp re("@[0-9]+$");
+ if (!isTypedef && memspecEntry &&
+ memspecEntry->name.find(re)==-1) // not typedef or anonymous type (see bug691071)
+ {
+ // enabled the next two lines for bug 623424
+ current->doc.resize(0);
+ current->brief.resize(0);
+ }
+ BEGIN( MemberSpec ) ;
+ }
+ }
+ }
+ }
+ }
+<ReadBody>"}"{BN}+"typedef"{BN}+ { //err("ReadBody count=%d\n",curlyCount);
+ lineCount();
+ if ( curlyCount>0 )
+ {
+ current->program += yytext ;
+ --curlyCount ;
+ }
+ else
+ {
+ isTypedef = TRUE;
+ current->endBodyLine = yyLineNr;
+ QCString &cn = current->name;
+ QCString rn = current_root->name.copy();
+ if (!cn.isEmpty() && !rn.isEmpty())
+ {
+ prependScope();
+ }
+ BEGIN( TypedefName );
+ }
+ }
+<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
+ lineCount();
+ current->type.prepend(yytext);
+ }
+<TypedefName>{ID} {
+ if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
+ {
+ current->program+=","; // add field terminator
+ }
+ current->name=yytext;
+ prependScope();
+ current->args = current->args.simplifyWhiteSpace();
+ current->type = current->type.simplifyWhiteSpace();
+ //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data());
+ current_root->addSubEntry( current ) ;
+ if (!firstTypedefEntry)
+ {
+ firstTypedefEntry = current;
+ }
+ current = new Entry;
+ initEntry();
+ isTypedef=TRUE; // to undo reset by initEntry()
+ BEGIN(MemberSpecSkip);
+ }
+<TypedefName>";" { /* typedef of anonymous type */
+ current->name.sprintf("@%d",anonCount++);
+ if ((current->section == Entry::ENUM_SEC) || (current->spec&Entry::Enum))
+ {
+ current->program+=','; // add field terminator
+ }
+ // add compound definition to the tree
+ current->args = current->args.simplifyWhiteSpace();
+ current->type = current->type.simplifyWhiteSpace();
+ current_root->addSubEntry( current ) ;
+ memspecEntry = current;
+ current = new Entry(*current);
+ initEntry();
+ unput(';');
+ BEGIN( MemberSpec ) ;
+ }
+<MemberSpec>([*&]*{BN}*)*{ID}{BN}*("["[^\]\n]*"]")* { // the [] part could be improved.
+ lineCount();
+ int i=0,l=(int)yyleng,j;
+ while (i<l && (!isId(yytext[i]))) i++;
+ msName = QCString(yytext).right(l-i).stripWhiteSpace();
+ j=msName.find("[");
+ if (j!=-1)
+ {
+ msArgs=msName.right(msName.length()-j);
+ msName=msName.left(j);
+ }
+ msType=QCString(yytext).left(i);
+
+ // handle *pName in: typedef { ... } name, *pName;
+ if (firstTypedefEntry)
+ {
+ if (firstTypedefEntry->spec&Entry::Struct)
+ {
+ msType.prepend("struct "+firstTypedefEntry->name);
+ }
+ else if (firstTypedefEntry->spec&Entry::Union)
+ {
+ msType.prepend("union "+firstTypedefEntry->name);
+ }
+ else if (firstTypedefEntry->section==Entry::ENUM_SEC)
+ {
+ msType.prepend("enum "+firstTypedefEntry->name);
+ }
+ else
+ {
+ msType.prepend(firstTypedefEntry->name);
+ }
+ }
+ }
+<MemberSpec>"(" { // function with struct return type
+ addType(current);
+ current->name = msName;
+ current->spec = 0;
+ unput('(');
+ BEGIN(FindMembers);
+ }
+<MemberSpec>[,;] {
+ if (msName.isEmpty() && !current->name.isEmpty())
+ {
+ // see if the compound does not have a name or is inside another
+ // anonymous compound. If so we insert a
+ // special `anonymous' variable.
+ //Entry *p=current_root;
+ Entry *p=current;
+ while (p)
+ {
+ // only look for class scopes, not namespace scopes
+ if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty())
+ {
+ //printf("Trying scope `%s'\n",p->name.data());
+ int i=p->name.findRev("::");
+ int pi = (i==-1) ? 0 : i+2;
+ if (p->name.at(pi)=='@')
+ {
+ // anonymous compound inside -> insert dummy variable name
+ //printf("Adding anonymous variable for scope %s\n",p->name.data());
+ msName.sprintf("@%d",anonCount++);
+ break;
+ }
+ }
+ //p=p->parent;
+ if (p==current) p=current_root; else p=p->parent();
+ }
+ }
+ //printf("msName=%s current->name=%s\n",msName.data(),current->name.data());
+ if (!msName.isEmpty()
+ /*&& msName!=current->name*/) // skip typedef T {} T;, removed due to bug608493
+ {
+ static bool typedefHidesStruct = Config_getBool("TYPEDEF_HIDES_STRUCT");
+ // case 1: typedef struct _S { ... } S_t;
+ // -> omit typedef and use S_t as the struct name
+ if (typedefHidesStruct &&
+ isTypedef &&
+ ((current->spec&(Entry::Struct|Entry::Union)) ||
+ current->section==Entry::ENUM_SEC )&&
+ msType.stripWhiteSpace().isEmpty() &&
+ memspecEntry)
+ {
+ memspecEntry->name=msName;
+ }
+ else // case 2: create a typedef field
+ {
+ Entry *varEntry=new Entry;
+ varEntry->lang = language;
+ varEntry->protection = current->protection ;
+ varEntry->mtype = current->mtype;
+ varEntry->virt = current->virt;
+ varEntry->stat = current->stat;
+ varEntry->section = Entry::VARIABLE_SEC;
+ varEntry->name = msName.stripWhiteSpace();
+ varEntry->type = current->type.simplifyWhiteSpace()+" ";
+ varEntry->args = msArgs;
+ if (isTypedef)
+ {
+ varEntry->type.prepend("typedef ");
+ // //printf("current->name = %s %s\n",current->name.data(),msName.data());
+ }
+ if (typedefHidesStruct &&
+ isTypedef &&
+ (current->spec&(Entry::Struct|Entry::Union)) &&
+ memspecEntry
+ ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
+ {
+ varEntry->type+=memspecEntry->name+msType;
+ }
+ else // case 2: use _S as type for for pS_t
+ {
+ varEntry->type+=current->name+msType;
+ }
+ varEntry->fileName = yyFileName;
+ varEntry->startLine = yyLineNr;
+ varEntry->startColumn = yyColNr;
+ varEntry->doc = current->doc.copy();
+ varEntry->brief = current->brief.copy();
+ varEntry->mGrpId = current->mGrpId;
+ varEntry->initializer = current->initializer;
+
+ // deep copy group list
+ QListIterator<Grouping> gli(*current->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ varEntry->groups->append(new Grouping(*g));
+ }
+ if (current->sli) // copy special list items
+ {
+ QListIterator<ListItemInfo> li(*current->sli);
+ ListItemInfo *lii;
+ for (li.toFirst();(lii=li.current());++li)
+ {
+ varEntry->addSpecialListItem(lii->type,lii->itemId);
+ }
+ }
+
+ //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n",
+ // varEntry->type.data(),varEntry->name.data(),
+ // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data());
+ current_root->addSubEntry(varEntry);
+ }
+ }
+ if (*yytext==';') // end of a struct/class ...
+ {
+ if (!isTypedef && msName.isEmpty() && memspecEntry && (current->section&Entry::COMPOUND_MASK))
+ { // case where a class/struct has a doc block after it
+ if (!current->doc.isEmpty())
+ {
+ memspecEntry->doc += current->doc;
+ }
+ if (!current->brief.isEmpty())
+ {
+ memspecEntry->brief += current->brief;
+ }
+ }
+ msType.resize(0);
+ msName.resize(0);
+ msArgs.resize(0);
+ isTypedef=FALSE;
+ firstTypedefEntry=0;
+ memspecEntry=0;
+ current->reset();
+ initEntry();
+ BEGIN( FindMembers );
+ }
+ else
+ {
+ current->doc.resize(0);
+ current->brief.resize(0);
+ }
+
+ }
+<MemberSpec>"=" {
+ lastInitializerContext=YY_START;
+ initBracketCount=0;
+ current->initializer = yytext;
+ BEGIN(ReadInitializer);
+ /* BEGIN(MemberSpecSkip); */
+ }
+ /*
+<MemberSpecSkip>"{" {
+ curlyCount=0;
+ lastCurlyContext = MemberSpecSkip;
+ previous = current;
+ BEGIN(SkipCurly);
+ }
+ */
+<MemberSpecSkip>"," { BEGIN(MemberSpec); }
+<MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); }
+<ReadBody,ReadNSBody,ReadBodyIntf>{BN}{1,80} { current->program += yytext ;
+ lineCount() ;
+ }
+<ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block
+ current_root->addSubEntry( current ) ;
+ current=new Entry;
+ initEntry();
+ insideObjC=FALSE;
+ BEGIN( FindMembers );
+ }
+<ReadBody,ReadNSBody,ReadBodyIntf>. { current->program += yytext ; }
+
+<FindMembers>"("/{BN}*"::"*{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
+<FindMembers>("("({BN}*"::"*{BN}*{TSCOPE}{BN}*"::")*({BN}*[*&\^]{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) or int (*func(int))[], the ^ is for Obj-C blocks */
+ if (insidePHP) // reference parameter
+ {
+ REJECT
+ }
+ else
+ {
+ current->bodyLine = yyLineNr;
+ lineCount();
+ addType(current);
+ funcPtrType=yytext;
+ roundCount=0;
+ //current->type += yytext;
+ BEGIN( FuncPtr );
+ }
+ }
+<FuncPtr>{SCOPENAME} {
+ current->name = yytext;
+ if (nameIsOperator(current->name))
+ {
+ BEGIN( FuncPtrOperator );
+ }
+ else
+ {
+ if (current->name=="const" || current->name=="volatile")
+ {
+ funcPtrType += current->name;
+ }
+ else
+ {
+ BEGIN( EndFuncPtr );
+ }
+ }
+ }
+<FuncPtr>. {
+ //printf("error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName);
+ }
+<FuncPtrOperator>"("{BN}*")"{BN}*/"(" {
+ current->name += yytext;
+ current->name = current->name.simplifyWhiteSpace();
+ lineCount();
+ }
+<FuncPtrOperator>\n {
+ lineCount();
+ current->name += *yytext;
+ }
+<FuncPtrOperator>"(" {
+ unput(*yytext);
+ BEGIN( EndFuncPtr );
+ }
+<FuncPtrOperator>. {
+ current->name += *yytext;
+ }
+<EndFuncPtr>")"{BN}*/";" { // a variable with extra braces
+ lineCount();
+ current->type+=funcPtrType.data()+1;
+ BEGIN(FindMembers);
+ }
+<EndFuncPtr>")"{BN}*/"(" { // a function pointer
+ lineCount();
+ current->type+=funcPtrType+")";
+ BEGIN(FindMembers);
+ }
+<EndFuncPtr>")"{BN}*/"[" { // an array of variables
+ lineCount();
+ current->type+=funcPtrType.data();
+ current->args += ")";
+ BEGIN(FindMembers);
+ }
+<EndFuncPtr>"(" { // a function returning a function or
+ // a function returning a pointer to an array
+ current->args += *yytext ;
+ //roundCount=0;
+ //BEGIN( FuncFunc );
+ current->bodyLine = yyLineNr;
+ currentArgumentContext = FuncFuncEnd;
+ fullArgString=current->args.copy();
+ copyArgString=¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ }
+<EndFuncPtr>"["[^\n\]]*"]" {
+ funcPtrType+=yytext;
+ }
+<EndFuncPtr>")" {
+ BEGIN(FindMembers);
+ }
+<FuncFunc>"(" {
+ current->args += *yytext ;
+ ++roundCount;
+ }
+<FuncFunc>")" {
+ current->args += *yytext ;
+ if ( roundCount )
+ --roundCount;
+ else
+ {
+ BEGIN(FuncFuncEnd);
+ }
+ }
+<FuncFuncEnd>")"{BN}*"(" {
+ lineCount();
+ current->type+=funcPtrType+")(";
+ BEGIN(FuncFuncType);
+ }
+<FuncFuncEnd>")"{BN}*/[;{] {
+ lineCount();
+ current->type+=funcPtrType.data()+1;
+ BEGIN(Function);
+ }
+<FuncFuncEnd>")"{BN}*/"[" { // function returning a pointer to an array
+ lineCount();
+ current->type+=funcPtrType;
+ current->args+=")";
+ BEGIN(FuncFuncArray);
+ }
+<FuncFuncEnd>. {
+ current->args += *yytext;
+ }
+<FuncFuncType>"(" {
+ current->type += *yytext;
+ roundCount++;
+ }
+<FuncFuncType>")" {
+ current->type += *yytext;
+ if (roundCount)
+ --roundCount;
+ else
+ BEGIN(Function);
+ }
+<FuncFuncType>{BN}*","{BN}* { lineCount() ; current->type += ", " ; }
+<FuncFuncType>{BN}+ { lineCount() ; current->type += ' ' ; }
+<FuncFuncType>. {
+ current->type += *yytext;
+ }
+<FindMembers>"("/{BN}*{ID}{BN}*"*"{BN}*{ID}*")(" { // for catching typedef void (__stdcall *f)() like definitions
+ if (current->type.left(7)=="typedef" && current->bodyLine==-1)
+ // the bodyLine check is to prevent this guard to be true more than once
+ {
+ current->bodyLine = yyLineNr;
+ BEGIN( GetCallType );
+ }
+ else if (!current->name.isEmpty()) // normal function
+ {
+ current->args = yytext;
+ current->bodyLine = yyLineNr;
+ currentArgumentContext = FuncQual;
+ fullArgString=current->args.copy();
+ copyArgString=¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ //printf(">>> Read function arguments!\n");
+ }
+ }
+<GetCallType>{BN}*{ID}{BN}*"*" {
+ lineCount();
+ addType(current);
+ funcPtrType="(";
+ funcPtrType+=yytext;
+ roundCount=0;
+ BEGIN( FuncPtr );
+ }
+<FindMembers>"(" {
+ if (!current->name.isEmpty())
+ {
+ current->args = yytext;
+ current->bodyLine = yyLineNr;
+ currentArgumentContext = FuncQual;
+ fullArgString=current->args.copy();
+ copyArgString=¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ //printf(">>> Read function arguments current->argList->count()=%d\n",current->argList->count());
+ }
+ }
+ /*
+<FindMembers>"("{BN}*("void"{BN}*)?")" {
+ lineCount();
+ current->args = "()";
+ BEGIN( FuncQual );
+ }
+ */
+
+ /*- Function argument reading rules ---------------------------------------*/
+
+<ReadFuncArgType>[^ \/\r\t\n\)\(\"\'#]+ { *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+<CopyArgString,CopyArgPHPString>[^\n\\\"\']+ { *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+<CopyArgRound>[^\/\n\)\(\"\']+ {
+ *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+<ReadFuncArgType,ReadTempArgs>{BN}* {
+ *copyArgString+=" ";
+ fullArgString+=" ";
+ lineCount();
+ }
+<ReadFuncArgType,CopyArgRound,CopyArgSharp,ReadTempArgs>{RAWBEGIN} {
+ g_delimiter = yytext+2;
+ g_delimiter=g_delimiter.left(g_delimiter.length()-1);
+ lastRawStringContext = YY_START;
+ pCopyRawString = copyArgString;
+ *pCopyRawString+=yytext;
+ fullArgString+=yytext;
+ BEGIN(RawString);
+ }
+<ReadFuncArgType,CopyArgRound,CopyArgSharp,ReadTempArgs>\" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ lastCopyArgStringContext = YY_START;
+ BEGIN( CopyArgString );
+ }
+<ReadFuncArgType,ReadTempArgs>"(" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ argRoundCount=0;
+ lastCopyArgContext = YY_START;
+ BEGIN( CopyArgRound );
+ }
+<ReadFuncArgType>")" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ stringToArgumentList(fullArgString,current->argList);
+ if (insideJS)
+ {
+ fixArgumentListForJavaScript(current->argList);
+ }
+ handleParametersCommentBlocks(current->argList);
+
+ /* remember the current documentation block, since
+ we could overwrite it with the documentation of
+ a function argument, which we then have to correct later
+ on
+ */
+ docBackup = current->doc;
+ briefBackup = current->brief;
+
+ BEGIN( currentArgumentContext );
+ }
+ /* a special comment */
+<ReadFuncArgType,ReadTempArgs>("/*"[*!]|"//"[/!])("<"?) {
+ if (currentArgumentContext==DefineEnd)
+ {
+ // for defines we interpret a comment
+ // as documentation for the define
+ int i;for (i=(int)yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ stringToArgumentList(fullArgString,current->argList);
+ handleParametersCommentBlocks(current->argList);
+ BEGIN( currentArgumentContext );
+ }
+ else // not a define
+ {
+ // for functions we interpret a comment
+ // as documentation for the argument
+ fullArgString+=yytext;
+ lastCopyArgChar=0;
+ lastCommentInArgContext=YY_START;
+ if (yytext[1]=='/')
+ BEGIN( CopyArgCommentLine );
+ else
+ BEGIN( CopyArgComment );
+ }
+ }
+ /* a non-special comment */
+<ReadFuncArgType,ReadTempArgs>"/**/" { /* empty comment */ }
+<ReadFuncArgType,ReadTempArgs>"/*" {
+ lastCContext = YY_START;
+ BEGIN( SkipComment );
+ }
+<ReadFuncArgType,ReadTempArgs>"//" {
+ lastCContext = YY_START;
+ BEGIN( SkipCxxComment );
+ }
+ /*
+<ReadFuncArgType,ReadTempArgs>"'#" { if (insidePHP)
+ REJECT;
+ *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+<ReadFuncArgType,ReadTempArgs>"#" {
+ if (!insidePHP)
+ REJECT;
+ lastCContext = YY_START;
+ BEGIN( SkipCxxComment );
+ }
+ */
+ /* `)' followed by a special comment */
+<ReadFuncArgType>")"{BN}*("/*"[*!]|"//"[/!])"<" {
+ lineCount();
+ if (currentArgumentContext==DefineEnd)
+ {
+ // for defines we interpret a comment
+ // as documentation for the define
+ int i;for (i=(int)yyleng-1;i>0;i--)
+ {
+ unput(yytext[i]);
+ }
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ stringToArgumentList(fullArgString,current->argList);
+ handleParametersCommentBlocks(current->argList);
+ BEGIN( currentArgumentContext );
+ }
+ else
+ {
+ // for functions we interpret a comment
+ // as documentation for the last argument
+ lastCopyArgChar=*yytext;
+ QCString text=&yytext[1];
+ text=text.stripWhiteSpace();
+ lastCommentInArgContext=YY_START;
+ fullArgString+=text;
+ if (text.find("//")!=-1)
+ BEGIN( CopyArgCommentLine );
+ else
+ BEGIN( CopyArgComment );
+ }
+ }
+<CopyArgComment>^{B}*"*"+/{BN}+
+<CopyArgComment>[^\n\\\@\*]+ { fullArgString+=yytext; }
+<CopyArgComment>"*/" { fullArgString+=yytext;
+ if (lastCopyArgChar!=0)
+ unput(lastCopyArgChar);
+ BEGIN( lastCommentInArgContext );
+ }
+<CopyArgCommentLine>\n { fullArgString+=yytext;
+ lineCount();
+ if (lastCopyArgChar!=0)
+ unput(lastCopyArgChar);
+ BEGIN( lastCommentInArgContext );
+ }
+<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!)
+ docBlockName=&yytext[1];
+ fullArgString+=yytext;
+ BEGIN(CopyArgVerbatim);
+ }
+<CopyArgCommentLine>{CMD}("f$"|"f["|"f{") {
+ docBlockName=&yytext[1];
+ if (docBlockName.at(1)=='[')
+ {
+ docBlockName.at(1)='}';
+ }
+ if (docBlockName.at(1)=='{')
+ {
+ docBlockName.at(1)='}';
+ }
+ fullArgString+=yytext;
+ BEGIN(CopyArgVerbatim);
+ }
+<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9] { // end of verbatim block
+ fullArgString+=yytext;
+ if (yytext[1]=='f') // end of formula
+ {
+ BEGIN(CopyArgCommentLine);
+ }
+ if (&yytext[4]==docBlockName)
+ {
+ BEGIN(CopyArgCommentLine);
+ }
+ }
+<CopyArgCommentLine>[^\\\@\n]+ { fullArgString+=yytext; }
+<CopyArgCommentLine>. { fullArgString+=*yytext; }
+<CopyArgComment,CopyArgVerbatim>\n { fullArgString+=*yytext; lineCount(); }
+<CopyArgComment,CopyArgVerbatim>. { fullArgString+=*yytext; }
+<CopyArgComment>{CMD}("brief"|"short"){B}+ {
+ warn(yyFileName,yyLineNr,
+ "Ignoring %cbrief command inside argument documentation",*yytext
+ );
+ fullArgString+=' ';
+ }
+<ReadTempArgs>"<" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ argSharpCount=1;
+ BEGIN( CopyArgSharp );
+ }
+<ReadTempArgs>">" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ //printf("end template list %s\n",copyArgString->data());
+ stringToArgumentList(fullArgString,currentArgumentList);
+ BEGIN( currentArgumentContext );
+ }
+<CopyArgRound>"(" {
+ argRoundCount++;
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ }
+<CopyArgRound>")" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ if (argRoundCount>0)
+ argRoundCount--;
+ else
+ BEGIN( lastCopyArgContext );
+ }
+<CopyArgSharp>"(" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ argRoundCount=0;
+ lastCopyArgContext = YY_START;
+ BEGIN( CopyArgRound );
+ }
+<CopyArgSharp>"<" {
+ argSharpCount++;
+ //printf("argSharpCount++=%d copy\n",argSharpCount);
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ }
+<CopyArgSharp>">" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ argSharpCount--;
+ if (argSharpCount>0)
+ {
+ //printf("argSharpCount--=%d copy\n",argSharpCount);
+ }
+ else
+ {
+ BEGIN( ReadTempArgs );
+ //printf("end of argSharpCount\n");
+ }
+ }
+<CopyArgString,CopyArgPHPString>\\. {
+ *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+<CopyArgString>\" {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ BEGIN( lastCopyArgStringContext );
+ }
+<CopyArgPHPString>\' {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ BEGIN( lastCopyArgStringContext );
+ }
+<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ *copyArgString+=yytext;
+ fullArgString+=yytext;
+ }
+ }
+<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>\' {
+ *copyArgString+=yytext;
+ fullArgString+=yytext;
+ if (insidePHP)
+ {
+ lastCopyArgStringContext=YY_START;
+ BEGIN(CopyArgPHPString);
+ }
+ }
+<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSharp>\n {
+ lineCount();
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ }
+<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgPHPString,CopyArgRound,CopyArgSharp>. {
+ *copyArgString+=*yytext;
+ fullArgString+=*yytext;
+ }
+
+
+
+ /*------------------------------------------------------------------------*/
+
+
+<FuncRound>"(" { current->args += *yytext ;
+ ++roundCount ;
+ }
+<FuncRound>")" { current->args += *yytext ;
+ if ( roundCount )
+ --roundCount ;
+ else
+ BEGIN( FuncQual ) ;
+ }
+ /*
+<FuncQual>"#" { if (insidePHP)
+ REJECT;
+ lastCPPContext = YY_START;
+ BEGIN(SkipCPP);
+ }
+ */
+<FuncQual>[{:;,] {
+ if ( qstrcmp(yytext,";")==0 &&
+ insidePHP &&
+ !containsWord(current->type,"function") )
+ {
+ current->reset();
+ initEntry();
+ BEGIN( FindMembers );
+ }
+ else
+ {
+ unput(*yytext); BEGIN( Function );
+ }
+ }
+<FuncQual>{BN}*"abstract"{BN}* { // pure virtual member function
+ lineCount() ;
+ current->virt = Pure;
+ current->args += " override ";
+ }
+<FuncQual,TrailingReturn>{BN}*"override"{BN}* { // C++11 overridden virtual member function
+ lineCount() ;
+ current->spec |= Entry::Override;
+ current->args += " override ";
+ BEGIN(FuncQual);
+ }
+<FuncQual,TrailingReturn>{BN}*"final"{BN}* { // C++11 final method
+ lineCount() ;
+ current->spec |= Entry::Final;
+ current->args += " final ";
+ BEGIN(FuncQual);
+ }
+<FuncQual>{BN}*"sealed"{BN}* { // sealed member function
+ lineCount() ;
+ current->spec |= Entry::Sealed;
+ current->args += " sealed ";
+ }
+<FuncQual>{BN}*"new"{BN}* { // new member function
+ lineCount() ;
+ current->spec |= Entry::New;
+ current->args += " new ";
+ }
+<FuncQual>{BN}*"const"{BN}* { // const member function
+ lineCount() ;
+ current->args += " const ";
+ current->argList->constSpecifier=TRUE;
+ }
+<FuncQual>{BN}*"volatile"{BN}* { // volatile member function
+ lineCount() ;
+ current->args += " volatile ";
+ current->argList->volatileSpecifier=TRUE;
+ }
+<FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier
+ lineCount() ;
+ current->args += " noexcept ";
+ current->spec |= Entry::NoExcept;
+ }
+<FuncQual>{BN}*"noexcept"{BN}*"(" { // noexcept expression
+ lineCount() ;
+ current->args += " noexcept(";
+ current->spec |= Entry::NoExcept;
+ lastRoundContext=FuncQual;
+ pCopyRoundString=¤t->args;
+ roundCount=0;
+ BEGIN(CopyRound);
+ }
+<FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function
+ lineCount() ;
+ current->args += " = 0";
+ current->virt = Pure;
+ current->argList->pureSpecifier=TRUE;
+ BEGIN(FuncQual);
+ }
+<FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member
+ lineCount();
+ current->args += " = delete";
+ current->spec |= Entry::Delete;
+ BEGIN(FuncQual);
+ }
+<FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator
+ lineCount();
+ current->args += " = default";
+ current->spec |= Entry::Default;
+ BEGIN(FuncQual);
+ }
+<FuncQual>{BN}*"->"{BN}* {
+ lineCount();
+ current->argList->trailingReturnType = " -> ";
+ current->args += " -> ";
+ BEGIN(TrailingReturn);
+ }
+<TrailingReturn>[{;] {
+ unput(*yytext);
+ BEGIN(FuncQual);
+ }
+<TrailingReturn>. {
+ current->argList->trailingReturnType+=yytext;
+ current->args+=yytext;
+ }
+<TrailingReturn>\n {
+ lineCount();
+ current->argList->trailingReturnType+=yytext;
+ current->args+=' ';
+ }
+<FuncRound,FuncFunc>{BN}*","{BN}* {
+ lineCount() ;
+ current->args += ", " ;
+ }
+<FuncQual,FuncRound,FuncFunc>{BN}+ {
+ lineCount() ;
+ current->args += ' ' ;
+ }
+<Function,FuncQual,FuncRound,FuncFunc>"#" { if (insidePHP)
+ REJECT;
+ lastCPPContext = YY_START;
+ BEGIN(SkipCPP);
+ }
+<FuncQual>"=" {
+ if (insideCli &&
+ (current_root->section&Entry::COMPOUND_MASK)
+ )
+ {
+ BEGIN(CliOverride);
+ }
+ else
+ {
+ // typically an initialized function pointer
+ lastInitializerContext=YY_START;
+ initBracketCount=0;
+ current->initializer = yytext;
+ BEGIN(ReadInitializer);
+ }
+ }
+<CliOverride>{ID} {
+ }
+<CliOverride>"{" {
+ unput(*yytext);
+ BEGIN(FuncQual);
+ }
+<CliOverride>\n {
+ lineCount();
+ }
+<CliOverride>. {
+ }
+<FuncPtrInit>[{;] {
+ unput(*yytext);
+ BEGIN(FuncQual);
+ }
+<FuncPtrInit>\" {
+ current->args += *yytext;
+ pCopyQuotedString=¤t->args;
+ lastStringContext=FuncPtrInit;
+ BEGIN(CopyString);
+ }
+<FuncPtrInit>\' {
+ current->args += *yytext;
+ if (insidePHP)
+ {
+ pCopyQuotedString=¤t->args;
+ lastStringContext=FuncPtrInit;
+ BEGIN(CopyPHPString);
+ }
+ }
+<FuncPtrInit>{CHARLIT} {
+ if (insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ current->args += yytext;
+ }
+ }
+<FuncPtrInit>{ID} {
+ current->args += yytext;
+ }
+<FuncPtrInit>. {
+ current->args += *yytext;
+ }
+<FuncPtrInit>\n {
+ current->args += *yytext;
+ lineCount();
+ }
+<FuncQual>{ID} { // typically a K&R style C function
+ if (insideCS && qstrcmp(yytext,"where")==0)
+ {
+ // type contraint for a method
+ delete current->typeConstr;
+ current->typeConstr = new ArgumentList;
+ current->typeConstr->append(new Argument);
+ lastCSConstraint = YY_START;
+ BEGIN( CSConstraintName );
+ }
+ else if (checkForKnRstyleC())
+ {
+ current->args = yytext;
+ oldStyleArgType.resize(0);
+ BEGIN(OldStyleArgs);
+ }
+ else
+ {
+ current->args += yytext;
+ }
+ }
+<OldStyleArgs>[,;] {
+ QCString oldStyleArgPtr;
+ QCString oldStyleArgName;
+ splitKnRArg(oldStyleArgPtr,oldStyleArgName);
+ QCString doc,brief;
+ if (current->doc!=docBackup)
+ {
+ doc=current->doc.copy();
+ current->doc=docBackup;
+ }
+ if (current->brief!=briefBackup)
+ {
+ brief=current->brief.copy();
+ current->brief=briefBackup;
+ }
+ addKnRArgInfo(oldStyleArgType+oldStyleArgPtr,
+ oldStyleArgName,brief,doc);
+ current->args.resize(0);
+ if (*yytext==';') oldStyleArgType.resize(0);
+ }
+<OldStyleArgs>{ID} { current->args += yytext; }
+<OldStyleArgs>"{" {
+ current->args = argListToString(current->argList);
+ unput('{');
+ BEGIN(FuncQual);
+ }
+<OldStyleArgs>. { current->args += *yytext; }
+<FuncQual,FuncRound,FuncFunc>. { current->args += *yytext; }
+<FuncQual>{BN}*"try:" |
+<FuncQual>{BN}*"try"{BN}+ { /* try-function-block */
+ insideTryBlock=TRUE;
+ lineCount();
+ if (yytext[yyleng-1]==':')
+ {
+ unput(':');
+ BEGIN( Function );
+ }
+ }
+<FuncQual>{BN}*"throw"{BN}*"(" { // C++ style throw clause
+ current->exception = " throw (" ;
+ roundCount=0;
+ lineCount() ;
+ BEGIN( ExcpRound ) ;
+ }
+<FuncQual>{BN}*"raises"{BN}*"(" {
+ current->exception = " raises (" ;
+ lineCount() ;
+ roundCount=0;
+ BEGIN( ExcpRound ) ;
+ }
+<FuncQual>{BN}*"throws"{BN}+ { // Java style throw clause
+ current->exception = " throws " ;
+ lineCount() ;
+ BEGIN( ExcpList );
+ }
+<ExcpRound>"(" { current->exception += *yytext ;
+ ++roundCount ;
+ }
+<ExcpRound>")" { current->exception += *yytext ;
+ if ( roundCount )
+ --roundCount ;
+ else
+ BEGIN( FuncQual ) ;
+ }
+<ExcpRound>. {
+ current->exception += *yytext;
+ }
+<ExcpList>"{" {
+ unput('{'); BEGIN( FuncQual );
+ }
+<ExcpList>";" {
+ unput(';'); BEGIN( FuncQual );
+ }
+<ExcpList>"\n" {
+ current->exception += ' ';
+ lineCount();
+ }
+<ExcpList>. {
+ current->exception += *yytext;
+ }
+<Function>"(" { current->type += current->name ;
+ current->name = current->args ;
+ current->args = yytext ;
+ roundCount=0;
+ BEGIN( FuncRound ) ;
+ }
+<Function>":" {
+ if (!insidePHP) BEGIN(SkipInits);
+ }
+<Function>[;{,] {
+ current->name=current->name.simplifyWhiteSpace();
+ current->type=current->type.simplifyWhiteSpace();
+ current->args=removeRedundantWhiteSpace(current->args);
+ // was: current->args.simplifyWhiteSpace();
+ current->fileName = yyFileName;
+ current->startLine = yyBegLineNr;
+ current->startColumn = yyBegColNr;
+ static QRegExp re("([^)]*[*&][^)]*)"); // (...*...)
+ if (*yytext!=';' || (current_root->section&Entry::COMPOUND_MASK) )
+ {
+ int tempArg=current->name.find('<');
+ int ts=current->type.find('<');
+ int te=current->type.findRev('>');
+ int ti=current->type.find(re,0);
+
+ // bug677315: A<int(void *, char *)> get(); is not a function pointer
+ bool isFunction = ti==-1 || // not a (...*...) pattern
+ (ts!=-1 && ts<te && ts<ti && ti<te); // (...*...) is part of a template argument list
+
+ //printf("type=%s ts=%d te=%d ti=%d isFunction=%d\n",
+ // current->type.data(),ts,te,ti,isFunction);
+ QCString tempName;
+ if (tempArg==-1) tempName=current->name; else tempName=current->name.left(tempArg);
+ if (!current->type.isEmpty() &&
+ (!isFunction || current->type.left(8)=="typedef "))
+ {
+ //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data());
+ if (isTypedef && current->type.left(8)!="typedef ")
+ {
+ current->type.prepend("typedef ");
+ }
+ current->section = Entry::VARIABLE_SEC ;
+ }
+ else
+ {
+ //printf("Scanner.l: found in class function: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data());
+ current->section = Entry::FUNCTION_SEC ;
+ current->proto = *yytext==';';
+ }
+ }
+ else // a global function prototype or function variable
+ {
+ //printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data());
+ if (!current->type.isEmpty() &&
+ (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef "))
+ {
+ if (isTypedef && current->type.left(8)!="typedef ")
+ {
+ current->type.prepend("typedef ");
+ }
+ //printf("Scanner.l: found function variable!\n");
+ current->section = Entry::VARIABLE_SEC;
+ }
+ else
+ {
+ //printf("Scanner.l: found prototype\n");
+ current->section = Entry::FUNCTION_SEC;
+ current->proto = TRUE;
+ }
+ }
+ //printf("Adding entry `%s'\n",current->name.data());
+ if ( insidePHP)
+ {
+ if (findAndRemoveWord(current->type,"final"))
+ {
+ current->spec |= Entry::Final;
+ }
+ if (findAndRemoveWord(current->type,"abstract"))
+ {
+ current->spec |= Entry::Abstract;
+ }
+ }
+ if ( insidePHP && !containsWord(current->type,"function"))
+ {
+ initEntry();
+ if ( *yytext == '{' )
+ {
+ lastCurlyContext = FindMembers;
+ curlyCount=0;
+ BEGIN( SkipCurly );
+ }
+ else
+ {
+ BEGIN( FindMembers );
+ }
+ }
+ else
+ {
+ if ( insidePHP)
+ {
+ findAndRemoveWord(current->type,"function");
+ }
+ previous = current;
+ current_root->addSubEntry(current);
+ current = new Entry ;
+ initEntry();
+ // Objective C 2.0: Required/Optional section
+ if (previous->spec & (Entry::Optional | Entry::Required))
+ {
+ current->spec |= previous->spec & (Entry::Optional|Entry::Required);
+ }
+ lastCurlyContext = FindMembers;
+ if ( *yytext == ',' )
+ {
+ current->type = previous->type;
+ // we need to strip any trailing * and & (see bugs 623023 and 649103 for test cases)
+ int i=current->type.length();
+ while (i>0 && (current->type[i-1]=='*' || current->type[i-1]=='&' || current->type[i-1]==' ')) i--;
+ current->type = current->type.left(i);
+ }
+ if ( *yytext == '{' )
+ {
+ if ( !insidePHP && (current_root->section & Entry::COMPOUND_MASK) )
+ {
+ previous->spec |= Entry::Inline;
+ }
+ //addToBody(yytext);
+ curlyCount=0;
+ BEGIN( SkipCurly ) ;
+ }
+ else
+ {
+ if (previous->section!=Entry::VARIABLE_SEC)
+ previous->bodyLine=-1; // a function/member declaration
+ BEGIN( FindMembers ) ;
+ }
+ }
+ }
+<SkipInits>{ID}{BN}*"{" { // C++11 style initializer (see bug 688647)
+ lineCount();
+ ++curlyCount;
+ }
+<SkipInits>"{" { // C++11 style initializer
+ unput('{');
+ BEGIN( Function );
+ }
+<SkipCurly>"{" {
+ //addToBody(yytext);
+ ++curlyCount ;
+ }
+<SkipCurly>"}"/{BN}*("/*!"|"/**"|"//!"|"///")"<!--" | /* see bug710917 */
+<SkipCurly>"}" {
+ //addToBody(yytext);
+ if( curlyCount )
+ {
+ --curlyCount ;
+ }
+ else
+ {
+ if (current->sli && previous) // copy special list items
+ {
+ QListIterator<ListItemInfo> li(*current->sli);
+ ListItemInfo *lii;
+ for (li.toFirst();(lii=li.current());++li)
+ {
+ previous->addSpecialListItem(lii->type,lii->itemId);
+ }
+ delete current->sli;
+ current->sli = 0;
+ }
+ if (previous) previous->endBodyLine=yyLineNr;
+ BEGIN( lastCurlyContext ) ;
+ }
+ }
+<SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" {
+ lineCount();
+ if ( curlyCount )
+ {
+ //addToBody(yytext);
+ --curlyCount ;
+ }
+ else
+ {
+ current->endBodyLine=yyLineNr;
+
+ tempEntry = current; // temporarily switch to the previous entry
+ current = previous;
+ previous = 0;
+
+ docBlockContext = SkipCurlyEndDoc;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+ docBlock.resize(0);
+ docBlockTerm = '}';
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+ }
+<SkipCurlyEndDoc>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" { // desc is followed by another one
+ docBlockContext = SkipCurlyEndDoc;
+ docBlockInBody = FALSE;
+ docBlockAutoBrief = ( yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF") ) ||
+ ( yytext[yyleng-2]=='!' && Config_getBool("QT_AUTOBRIEF") );
+ docBlock.resize(0);
+ docBlockTerm = '}';
+ if (yytext[yyleng-3]=='/')
+ {
+ startCommentBlock(TRUE);
+ BEGIN( DocLine );
+ }
+ else
+ {
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+ }
+<SkipCurlyEndDoc>"}" {
+ //addToBody("}");
+ if (tempEntry) // we can only switch back to current if no new item was created
+ {
+ current = tempEntry;
+ tempEntry = 0;
+ }
+ BEGIN( lastCurlyContext );
+ }
+<SkipCurly>\" {
+ //addToBody(yytext);
+ lastStringContext=SkipCurly;
+ BEGIN( SkipString );
+ }
+<SkipCurly>^{B}*"#" {
+ if (insidePHP)
+ REJECT;
+ //addToBody(yytext);
+ BEGIN( SkipCurlyCpp );
+ }
+<SkipCurly,SkipInits>\n {
+ lineCount();
+ //addToBody(yytext);
+ }
+<SkipCurly,SkipCurlyCpp>"<<<" {
+ if (!insidePHP)
+ {
+ REJECT;
+ }
+ else
+ {
+ lastHereDocContext = YY_START;
+ BEGIN(HereDoc);
+ }
+ }
+<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}<]+ {
+ lineCount(); // for g_column updates
+ //addToBody(yytext);
+ }
+<SkipCurlyCpp>\n {
+ //addToBody(yytext);
+ lineCount();
+ lastCurlyContext = FindMembers;
+ BEGIN( SkipCurly );
+ }
+<SkipCurlyCpp>\\[\r]*"\n"[\r]* {
+ //addToBody(yytext);
+ lineCount();
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>"/*" {
+ //addToBody(yytext);
+ lastCContext = YY_START;
+ BEGIN(SkipComment);
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>"//" {
+ //addToBody(yytext);
+ lastCContext = YY_START;
+ BEGIN(SkipCxxComment);
+ }
+<SkipInits>"(" {
+ roundCount=0;
+ lastSkipRoundContext=YY_START;
+ BEGIN(SkipRound);
+ }
+<SkipInits>\" {
+ lastStringContext=YY_START;
+ BEGIN( SkipString );
+ }
+<SkipInits>; {
+ warn(yyFileName,yyLineNr,
+ "Found ';' while parsing initializer list! "
+ "(doxygen could be confused by a macro call without semicolon)"
+ );
+ BEGIN( FindMembers );
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>"#" {
+ if (!insidePHP)
+ REJECT;
+ //addToBody(yytext);
+ lastCContext = YY_START;
+ BEGIN(SkipCxxComment);
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>@\" {
+ if (!insideCS) REJECT;
+ // C# verbatim string
+ lastSkipVerbStringContext=YY_START;
+ pSkipVerbString=¤t->initializer;
+ BEGIN(SkipVerbString);
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>{CHARLIT} {
+ if (insidePHP) REJECT;
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>\' {
+ if (insidePHP)
+ {
+ lastStringContext=YY_START;
+ BEGIN(SkipPHPString);
+ }
+ }
+<SkipInits,SkipCurly,SkipCurlyCpp>. { }
+<SkipString,SkipPHPString>\\. { }
+<SkipString>\" {
+ BEGIN( lastStringContext );
+ }
+<SkipPHPString>\' {
+ BEGIN( lastStringContext );
+ }
+<SkipString,SkipPHPString>"/*"|"*/"|"//" { }
+<SkipString,SkipPHPString>\n {
+ lineCount();
+ }
+<SkipString,SkipPHPString>. { }
+<CompoundName>":" { // for "class : public base {} var;" construct, see bug 608359
+ unput(':');
+ BEGIN(ClassVar);
+ }
+<CompoundName>";" {
+ current->section = Entry::EMPTY_SEC ;
+ current->type.resize(0) ;
+ current->name.resize(0) ;
+ current->args.resize(0) ;
+ current->argList->clear();
+ BEGIN( FindMembers ) ;
+ }
+<Bases>";" {
+ if (insideIDL && (current->spec & (Entry::Singleton |
+ Entry::Service)))
+ {
+ // in UNO IDL a service or singleton may be defined
+ // completely like this: "service Foo : XFoo;"
+ if (!current->name.isEmpty() && !current_root->name.isEmpty())
+ {
+ prependScope();
+ }
+ current->name = current->name.stripWhiteSpace();
+ // there can be only one base class here
+ if (!baseName.isEmpty())
+ {
+ current->extends->append(
+ new BaseInfo(baseName,Public,Normal));
+ baseName.resize(0);
+ }
+ current_root->addSubEntry( current ) ;
+ current = new Entry;
+ }
+ else
+ {
+ current->section = Entry::EMPTY_SEC ;
+ current->type.resize(0) ;
+ current->name.resize(0) ;
+ current->args.resize(0) ;
+ current->argList->clear();
+ }
+ BEGIN( FindMembers ) ;
+ }
+<CompoundName>{SCOPENAME}{BN}*/"<" {
+ sharpCount = 0;
+ current->name = yytext ;
+ if (current->spec & Entry::Protocol)
+ {
+ current->name+="-p";
+ }
+ lineCount();
+ lastClassTemplSpecContext = ClassVar;
+ if (insideObjC) // protocol list
+ {
+ BEGIN( ObjCProtocolList );
+ }
+ else if (insideCS) // C# generic class
+ {
+ //current->name+="-g";
+ BEGIN( CSGeneric );
+ }
+ else // C++ template specialization
+ {
+ roundCount=0;
+ BEGIN( ClassTemplSpec );
+ }
+ }
+<CSGeneric>"<" {
+ if (current->tArgLists==0)
+ {
+ current->tArgLists = new QList<ArgumentList>;
+ current->tArgLists->setAutoDelete(TRUE);
+ }
+ ArgumentList *al = new ArgumentList;
+ // check bug 612858 before enabling the next line
+ //current->spec |= Entry::Template;
+ current->tArgLists->append(al);
+ currentArgumentList = al;
+ templateStr="<";
+ current->name += "<";
+ fullArgString = templateStr;
+ copyArgString = ¤t->name;
+ //copyArgString = &templateStr;
+ currentArgumentContext = ClassVar;
+ BEGIN( ReadTempArgs );
+ }
+<ObjCProtocolList>"<" {
+ insideProtocolList=TRUE;
+ BEGIN( Bases );
+ }
+<ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
+ current->name += yytext;
+ lineCount();
+ if (--sharpCount<=0)
+ {
+ current->name = removeRedundantWhiteSpace(current->name);
+ if (current->spec & Entry::Protocol)
+ { // Objective-C protocol
+ unput('{'); // fake start of body
+ BEGIN( ClassVar );
+ }
+ else
+ {
+ BEGIN( lastClassTemplSpecContext );
+ }
+ }
+ }
+<ClassTemplSpec>"<" {
+ current->name += yytext;
+ sharpCount++;
+ }
+<ClassTemplSpec>. {
+ current->name += yytext;
+ }
+<CompoundName>{SCOPENAME}{BN}*";" { // forward declaration
+ if (current->tArgLists && current->tArgLists->count()>0)
+ {
+ // found a forward template declaration, this has
+ // a purpose of its own
+ current->name = yytext;
+ current->name=current->name.left(current->name.length()-1).stripWhiteSpace();
+ //printf("template class declaration for %s!\n",current->name.data());
+ QCString rn = current_root->name.copy();
+ //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef);
+ if (!current->name.isEmpty() && !rn.isEmpty())
+ {
+ prependScope();
+ }
+ current->spec|=Entry::ForwardDecl;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ }
+ else if (insideIDL &&
+ (((current_root->spec & (Entry::Interface |
+ Entry::Service)) &&
+ (current->spec & Entry::Interface)) ||
+ ((current_root->spec & (Entry::Service |
+ Entry::Singleton)) &&
+ (current->spec & Entry::Service))))
+ {
+ // interface inside of UNO IDL service or interface
+ // service inside of UNO IDL service or singleton
+ // there may be documentation on the member,
+ // so do not throw it away...
+ current->name = yytext;
+ current->name=current->name.left(current->name.length()-1).stripWhiteSpace();
+ current->section = (current->spec & Entry::Interface)
+ ? Entry::EXPORTED_INTERFACE_SEC
+ : Entry::INCLUDED_SERVICE_SEC;
+// current->section = Entry::MEMBERDOC_SEC;
+ current->spec &= ~(Entry::Interface|Entry::Service); // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from different enums in this case... granted only Optional and Interface are actually valid in this context but urgh...
+ current_root->addSubEntry(current);
+ current = new Entry;
+ }
+
+ unput(';');
+ current->reset();
+ initEntry();
+ if (isTypedef) // typedef of a class, put typedef keyword back
+ {
+ current->type.prepend("typedef");
+ }
+ BEGIN( FindMembers );
+ }
+<CompoundName>{SCOPENAME}/{BN}*"(" {
+ current->name = yytext ;
+ lineCount();
+ if (insideCpp && current->name=="alignas") // C++11
+ {
+ lastAlignAsContext = YY_START;
+ BEGIN( AlignAs );
+ }
+ else
+ {
+ if (current->spec & Entry::Protocol)
+ {
+ current->name += "-p";
+ }
+ BEGIN( ClassVar );
+ }
+ }
+<AlignAs>"(" { roundCount=0;
+ BEGIN( AlignAsEnd );
+ }
+<AlignAs>\n { lineCount(); }
+<AlignAs>.
+<AlignAsEnd>"(" { roundCount++; }
+<AlignAsEnd>")" { if (--roundCount<0)
+ {
+ BEGIN( lastAlignAsContext );
+ }
+ }
+<AlignAsEnd>\n { lineCount(); }
+<AlignAsEnd>.
+<CompoundName>{SCOPENAME}/{BN}*"," { // multiple forward declarations on one line
+ // e.g. @protocol A,B;
+ current->reset();
+ initEntry();
+ }
+<CompoundName>{SCOPENAME} {
+ current->name = yytext ;
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ lineCount();
+ if (current->spec & Entry::Protocol)
+ {
+ current->name += "-p";
+ }
+ if ((current->spec & Entry::Protocol) ||
+ current->section == Entry::OBJCIMPL_SEC)
+ {
+ unput('{'); // fake start of body
+ }
+ BEGIN( ClassVar );
+ }
+<CompoundName>{CSSCOPENAME} { // C# style scope
+ current->name = substitute(yytext,".","::");
+ lineCount();
+ BEGIN( ClassVar );
+ }
+<ClassVar>{SCOPENAME}{BN}*/"(" {
+ if (insideIDL && qstrncmp(yytext,"switch",6)==0 && !isId(yytext[6]))
+ {
+ // Corba IDL style union
+ roundCount=0;
+ BEGIN(SkipUnionSwitch);
+ }
+ else
+ {
+ addType(current);
+ current->name = yytext;
+ current->name = current->name.stripWhiteSpace();
+ lineCount();
+ BEGIN( FindMembers );
+ }
+ }
+<ClassVar>"," {
+ if (isTypedef)
+ {
+ // multiple types in one typedef
+ unput(',');
+ current->type.prepend("typedef ");
+ BEGIN(FindMembers);
+ }
+ else
+ {
+ // Multiple class forward declaration
+ }
+ }
+<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
+ if (insideCli)
+ {
+ if (yytext[0]=='s') // sealed
+ current->spec |= Entry::SealedClass;
+ else // abstract
+ current->spec |= Entry::AbstractClass;
+ BEGIN( ClassVar );
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<ClassVar>{ID} {
+ if (insideCpp || insideObjC)
+ {
+ current->id = ClangParser::instance()->lookup(yyLineNr,yytext);
+ }
+ if (insideIDL && qstrcmp(yytext,"switch")==0)
+ {
+ // Corba IDL style union
+ roundCount=0;
+ BEGIN(SkipUnionSwitch);
+ }
+ else if ((insideJava || insidePHP || insideJS) && (qstrcmp(yytext,"implements")==0 || qstrcmp(yytext,"extends")==0))
+ {
+ current->type.resize(0);
+ baseProt=Public;
+ baseVirt=Normal;
+ baseName.resize(0);
+ BEGIN( BasesProt ) ;
+ }
+ else if (insideCS && qstrcmp(yytext,"where")==0) // C# type contraint
+ {
+ delete current->typeConstr;
+ current->typeConstr = new ArgumentList;
+ current->typeConstr->append(new Argument);
+ lastCSConstraint = YY_START;
+ BEGIN( CSConstraintName );
+ }
+ else if (insideCli && qstrcmp(yytext,"abstract")==0)
+ {
+ current->spec|=Entry::Abstract;
+ }
+ else if (insideCli && qstrcmp(yytext,"sealed")==0)
+ {
+ current->spec|=Entry::Sealed;
+ }
+ else if (qstrcmp(yytext,"final")==0)
+ {
+ current->spec|=Entry::Final;
+ }
+ else
+ {
+ if (current->section == Entry::ENUM_SEC)
+ { // found "enum a b" -> variable
+ current->section = Entry::VARIABLE_SEC ;
+ }
+ current->type += ' ' ;
+ current->type += current->name ;
+ current->name = yytext ;
+
+ if (nameIsOperator(current->name))
+ {
+ BEGIN( Operator );
+ }
+ }
+ }
+<ClassVar>[(\[] {
+ if (insideObjC && *yytext=='(') // class category
+ {
+ current->name+='(';
+ //if (current->section!=Entry::OBJCIMPL_SEC)
+ //{
+ current->spec|=Entry::Category;
+ //}
+ BEGIN( ClassCategory );
+ }
+ else
+ {
+ // probably a function anyway
+ unput(*yytext);
+ BEGIN( FindMembers );
+ }
+ }
+<CSConstraintType,CSConstraintName>"/**/" { /* empty comment */ }
+<CSConstraintType,CSConstraintName>("/*"[*!]|"//"[/!])("<"?) { // special comment
+ fullArgString.resize(0);
+ lastCopyArgChar='#'; // end marker
+ lastCommentInArgContext=YY_START;
+ if (yytext[1]=='/')
+ BEGIN( CopyArgCommentLine );
+ else
+ BEGIN( CopyArgComment );
+ }
+<CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block
+ current->typeConstr->getLast()->docs = fullArgString;
+ }
+<CSConstraintType>"{" { // end of type constraint reached
+ // parse documentation of the constraints
+ handleParametersCommentBlocks(current->typeConstr);
+ unput('{');
+ BEGIN( lastCSConstraint );
+ }
+<CSConstraintType,CSConstraintName>";" {
+ handleParametersCommentBlocks(current->typeConstr);
+ unput(';');
+ BEGIN( lastCSConstraint );
+ }
+<CSConstraintName>":" {
+ BEGIN( CSConstraintType );
+ }
+<CSConstraintName>{ID} {
+ // parameter name
+ current->typeConstr->getLast()->name=yytext;
+ }
+<CSConstraintType>"where" { // another constraint for a different param
+ current->typeConstr->append(new Argument);
+ BEGIN( CSConstraintName );
+ }
+<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
+ if (current->typeConstr->getLast()->type.isEmpty())
+ // first type constraint for this parameter
+ {
+ current->typeConstr->getLast()->type=yytext;
+ }
+ else // new type constraint for same parameter
+ {
+ QCString name = current->typeConstr->getLast()->name;
+ current->typeConstr->append(new Argument);
+ current->typeConstr->getLast()->name=name;
+ current->typeConstr->getLast()->type=yytext;
+ }
+ }
+<CSConstraintName,CSConstraintType>\n {
+ lineCount();
+ }
+<CSConstraintName,CSConstraintType>. {
+ }
+<ClassCategory>{ID} {
+ current->name+=yytext;
+ }
+<ClassCategory>")"/{BN}*"{" {
+ current->name+=')';
+ BEGIN( ClassVar );
+ }
+<ClassCategory>")"/{BN}*"<" {
+ current->name+=')';
+ BEGIN( ObjCProtocolList );
+ }
+<ClassCategory>")" {
+ current->name+=')';
+ if ((current->section & Entry::Protocol) ||
+ current->section == Entry::OBJCIMPL_SEC)
+ {
+ unput('{'); // fake start of body
+ }
+ else // category has no variables so push back an empty body
+ {
+ unput('}');
+ unput('{');
+ }
+ BEGIN( ClassVar );
+ }
+<ClassVar>":" {
+ if (current->section==Entry::ENUM_SEC) // enum E:2, see bug 313527,
+ // or C++11 style enum: 'E : unsigned int {...}'
+ {
+ current->args.resize(0);
+ BEGIN(EnumBaseType);
+ }
+ else
+ {
+ current->type.resize(0);
+ if ((current->spec & Entry::Interface) ||
+ (current->spec & Entry::Struct) ||
+ (current->spec & Entry::Ref) ||
+ (current->spec & Entry::Value) ||
+ insidePHP || insideCS || insideD || insideObjC || insideIDL
+ )
+ baseProt=Public;
+ else
+ baseProt=Private;
+ baseVirt=Normal;
+ baseName.resize(0);
+ BEGIN( BasesProt ) ;
+ }
+ }
+<ClassVar>[;=*&] {
+ unput(*yytext);
+ if (isTypedef) // typedef of a class, put typedef keyword back
+ {
+ current->type.prepend("typedef");
+ }
+ if ((yytext[0]=='*' || yytext[0]=='&') &&
+ current->section == Entry::ENUM_SEC)
+ { // found "enum a *b" -> variable
+ current->section = Entry::VARIABLE_SEC ;
+ }
+ BEGIN( FindMembers );
+ }
+<Bases,ClassVar>"///"/[^/] {
+ if (!insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ lineCount();
+ current->program+=yytext;
+ current->fileName = yyFileName ;
+ current->startLine = yyLineNr ;
+ current->startColumn = yyColNr;
+ curlyCount=0;
+ BEGIN( ReadBodyIntf );
+ }
+ }
+<Bases,ClassVar>("//"{B}*)?"/**"/[^/*] |
+<Bases,ClassVar>("//"{B}*)?"/*!" |
+<Bases,ClassVar>"//!" |
+<Bases,ClassVar>[\-+]{BN}* {
+ if (!insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ lineCount();
+ current->program+=yytext;
+ current->fileName = yyFileName ;
+ current->startLine = yyLineNr ;
+ current->startColumn = yyColNr;
+ curlyCount=0;
+ BEGIN( ReadBodyIntf );
+ }
+ }
+<CompoundName,ClassVar>{B}*"{"{B}* {
+ current->fileName = yyFileName ;
+ current->startLine = yyLineNr ;
+ current->startColumn = yyColNr;
+ current->name = removeRedundantWhiteSpace(current->name);
+ if (current->name.isEmpty() && !isTypedef) // anonymous compound
+ {
+ if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces
+ {
+ if (Config_getBool("EXTRACT_ANON_NSPACES")) // use visible name
+ {
+ current->name="anonymous_namespace{"+stripPath(current->fileName)+"}";
+ }
+ else // use invisible name
+ {
+ current->name.sprintf("@%d",anonNSCount);
+ }
+ }
+ else
+ {
+ current->name.sprintf("@%d",anonCount++);
+ }
+ }
+ curlyCount=0;
+ if (current_root && // not a nested struct inside an @interface section
+ !(current_root->spec & Entry::Interface) &&
+ ((current->spec & (Entry::Interface | Entry::Protocol | Entry::Category) ||
+ current->section==Entry::OBJCIMPL_SEC)
+ ) &&
+ insideObjC
+ )
+ { // ObjC body that ends with @end
+ BEGIN( ReadBodyIntf );
+ }
+ else if (current->section==Entry::NAMESPACE_SEC)
+ { // namespace body
+ BEGIN( ReadNSBody );
+ }
+ else
+ { // class body
+ BEGIN( ReadBody ) ;
+ }
+ }
+<BasesProt>"virtual"{BN}+ { lineCount(); baseVirt = Virtual; }
+<BasesProt>"public"{BN}+ { lineCount(); baseProt = Public; }
+<BasesProt>"protected"{BN}+ { lineCount(); baseProt = Protected; }
+<BasesProt>"internal"{BN}+ { lineCount(); baseProt = Package; }
+<BasesProt>"private"{BN}+ { lineCount(); baseProt = Private; }
+<BasesProt>{BN} { lineCount(); }
+<BasesProt>. { unput(*yytext); BEGIN(Bases); }
+<Bases>("\\")?({ID}"\\")*{ID} { // PHP namespace token, not sure if interspacing is allowed but it gives problems (see bug 640847)
+ if (!insidePHP)
+ {
+ REJECT;
+ }
+ else // PHP base class of the form \Ns\Cl or Ns\Cl
+ {
+ lineCount();
+ QCString bn=yytext;
+ bn = substitute(bn,"\\","::");
+ baseName += bn;
+ current->args += ' ';
+ current->args += yytext;
+ }
+ }
+<Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} {
+ lineCount();
+ QCString baseScope = yytext;
+ if (insideCS && baseScope.stripWhiteSpace()=="where")
+ {
+ // type contraint for a class
+ delete current->typeConstr;
+ current->typeConstr = new ArgumentList;
+ current->typeConstr->append(new Argument);
+ lastCSConstraint = YY_START;
+ BEGIN( CSConstraintName );
+ }
+ else
+ {
+ baseName+=yytext;
+ current->args += ' ';
+ current->args += yytext;
+ }
+ }
+<Bases>{BN}*{ID}("."{ID})* { // Java style class
+ QCString name = substitute(yytext,".","::");
+ baseName += name;
+ current->args += ' ';
+ current->args += name;
+ }
+<ClassVar,Bases>\n/{BN}*[^{, \t\n] {
+ if (!insideObjC)
+ {
+ REJECT;
+ }
+ else
+ {
+ lineCount();
+ unput('{');
+ }
+ }
+<ClassVar,Bases>"@end" { // empty ObjC interface
+ unput('d'); // insert fake body: {}@end
+ unput('n');
+ unput('e');
+ unput('@');
+ unput('}');
+ unput('{');
+ }
+<ClassVar>"<" { current->name += *yytext;
+ sharpCount=1;
+ roundCount=0;
+ lastSkipSharpContext = YY_START;
+ specName = ¤t->name;
+ BEGIN ( Specialization );
+ }
+<Bases>{BN}*"<" {
+ lineCount();
+ sharpCount=1;
+ roundCount=0;
+ lastSkipSharpContext = YY_START;
+ if (insideObjC) // start of protocol list
+ {
+ unput(',');
+ }
+ else // template specialization
+ {
+ //if (insideCS) // generic
+ //{
+ // baseName+="-g";
+ //}
+ templateStr = yytext;
+ specName = &templateStr;
+ BEGIN ( Specialization );
+ }
+ }
+<Specialization>"<" { *specName += *yytext;
+ if (roundCount==0) sharpCount++;
+ }
+<Specialization>">" {
+ *specName += *yytext;
+ if (roundCount==0 && --sharpCount<=0)
+ {
+ baseName+=removeRedundantWhiteSpace(*specName);
+ BEGIN(lastSkipSharpContext);
+ }
+ }
+<Specialization>{BN}+ { lineCount(); *specName +=' '; }
+<Specialization>"<<" { *specName += yytext; }
+<Specialization>">>"/{B}*"::" { // M$ C++ extension to allow >> to close a template...
+ unput('>');
+ unput(' ');
+ unput('>');
+ }
+<Specialization>">>" {
+ if (insideCS) // for C# >> ends a nested template
+ {
+ REJECT;
+ }
+ else // for C++ >> is a bitshift
+ // operator and > > would end
+ // a nested template.
+ // We require the bitshift to be enclosed in braces.
+ // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
+ {
+ if (roundCount>0)
+ {
+ *specName += yytext;
+ }
+ else
+ {
+ unput('>');
+ unput(' ');
+ unput('>');
+ }
+ }
+ }
+<Specialization>"typename"{BN}+ { lineCount(); }
+<Specialization>"(" { *specName += *yytext; roundCount++; }
+<Specialization>")" { *specName += *yytext; roundCount--; }
+<Specialization>. {
+ *specName += *yytext;
+ }
+<SkipRound>"(" { ++roundCount; }
+<SkipRound>")" { if (--roundCount<0)
+ BEGIN ( lastSkipRoundContext );
+ }
+<SkipRound>\" {
+ lastStringContext=SkipRound;
+ BEGIN(SkipString);
+ }
+<Bases>","|(">"({BN}*"{")?)|({BN}+"implements"{BN}*) { lineCount();
+ if (insideProtocolList)
+ {
+ baseName+="-p";
+ }
+ else
+ {
+ current->args += ',' ;
+ }
+ current->name = removeRedundantWhiteSpace(current->name);
+ if (!baseName.isEmpty())
+ {
+ current->extends->append(
+ new BaseInfo(baseName,baseProt,baseVirt)
+ );
+ }
+ if ((current->spec & (Entry::Interface|Entry::Struct)) ||
+ insideJava || insidePHP || insideCS ||
+ insideD || insideObjC || insideIDL)
+ {
+ baseProt=Public;
+ }
+ else
+ {
+ baseProt=Private;
+ }
+ baseVirt=Normal;
+ baseName.resize(0);
+ if (*yytext=='>')
+ { // end of a ObjC protocol list
+ insideProtocolList=FALSE;
+ if (yyleng==1)
+ {
+ unput('{'); // dummy start body
+ }
+ else
+ {
+ yyless(1);
+ }
+ }
+ else
+ {
+ if (*yytext==',' && insideObjC) // Begin of protocol list
+ {
+ insideProtocolList=TRUE;
+ }
+ BEGIN(BasesProt);
+ }
+ }
+<Bases>{B}*"{"{B}* { current->fileName = yyFileName ;
+ current->startLine = yyLineNr ;
+ current->startColumn = yyColNr;
+ current->name = removeRedundantWhiteSpace(current->name);
+ if (!baseName.isEmpty())
+ current->extends->append(
+ new BaseInfo(baseName,baseProt,baseVirt)
+ );
+ curlyCount=0;
+ if (insideObjC)
+ {
+ BEGIN( ReadBodyIntf );
+ }
+ else
+ {
+ BEGIN( ReadBody ) ;
+ }
+ }
+<SkipUnionSwitch>{B}*"(" {
+ roundCount++;
+ }
+<SkipUnionSwitch>")" {
+ if (--roundCount==0)
+ {
+ BEGIN(ClassVar);
+ }
+ }
+<SkipUnionSwitch>\n { lineCount(); }
+<SkipUnionSwitch>.
+<Comment>{BN}+ { current->program += yytext ;
+ lineCount() ;
+ }
+<Comment>"/*" { current->program += yytext ; }
+<Comment>"//" { current->program += yytext ; }
+<Comment>{CMD}("code"|"verbatim") {
+ insideCode=TRUE;
+ current->program += yytext ;
+ }
+<Comment>{CMD}("endcode"|"endverbatim") {
+ insideCode=FALSE;
+ current->program += yytext ;
+ }
+<Comment>[^ \.\t\r\n\/\*]+ { current->program += yytext ; }
+<Comment>"*/" { current->program += yytext ;
+ if (!insideCode) BEGIN( lastContext ) ;
+ }
+<Comment>. { current->program += *yytext ; }
+
+<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/*!" {
+ //printf("Start doc block at %d\n",yyLineNr);
+ removeSlashes=(yytext[1]=='/');
+ tmpDocType=-1;
+ if (!current->doc.isEmpty())
+ {
+ current->doc+="\n\n";
+ }
+ else
+ {
+ current->docLine = yyLineNr;
+ current->docFile = yyFileName;
+ }
+
+ lastDocContext = YY_START;
+ if (current_root->section & Entry::SCOPE_MASK)
+ {
+ current->inside = current_root->name+"::";
+ }
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockAutoBrief = Config_getBool("QT_AUTOBRIEF");
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+
+ if (docBlockAutoBrief)
+ {
+ current->briefLine = yyLineNr;
+ current->briefFile = yyFileName;
+ }
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/**"/[^/*] {
+ removeSlashes=(yytext[1]=='/');
+ lastDocContext = YY_START;
+
+ //printf("Found comment block at %s:%d\n",yyFileName,yyLineNr);
+ if (current_root->section & Entry::SCOPE_MASK)
+ {
+ current->inside = current_root->name+"::";
+ }
+ current->docLine = yyLineNr;
+ current->docFile = yyFileName;
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ static bool javadocAutoBrief = Config_getBool("JAVADOC_AUTOBRIEF");
+ docBlockAutoBrief = javadocAutoBrief;
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+
+ if (docBlockAutoBrief)
+ {
+ current->briefLine = yyLineNr;
+ current->briefFile = yyFileName;
+ }
+ startCommentBlock(FALSE);
+ BEGIN( DocBlock );
+ }
+<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" {
+ tmpDocType=-1;
+ lastDocContext = YY_START;
+ if (current_root->section & Entry::SCOPE_MASK)
+ {
+ current->inside = current_root->name+"::";
+ }
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockAutoBrief = FALSE;
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+
+ startCommentBlock(current->brief.isEmpty());
+ BEGIN( DocLine );
+ }
+<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] {
+ tmpDocType=-1;
+ lastDocContext = YY_START;
+ if (current_root->section & Entry::SCOPE_MASK)
+ {
+ current->inside = current_root->name+"::";
+ }
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockAutoBrief = FALSE;
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock=indent;
+ startCommentBlock(current->brief.isEmpty());
+ BEGIN( DocLine );
+ }
+<FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? {
+ lineCount();
+ externC=TRUE;
+ }
+<FindMembers>"{" {
+ if (externC)
+ {
+ externC=FALSE;
+ }
+ else if (insideCS &&
+ !current->name.isEmpty() &&
+ !current->type.isEmpty())
+ {
+ if (containsWord(current->type,"event")) // event
+ {
+ current->mtype = mtype = Event;
+ }
+ else // property
+ {
+ current->mtype = mtype = Property;
+ }
+ current->bodyLine = yyLineNr;
+ curlyCount=0;
+ BEGIN( CSAccessorDecl );
+ }
+ else if (insideIDL && (current->spec & Entry::Attribute))
+ {
+ // UNO IDL: attributes may have setter and getter
+ // exception specifications
+ current->exception = " {";
+ BEGIN(UNOIDLAttributeBlock);
+ }
+ else
+ {
+ if ((insideJava || insideCS || insideD) &&
+ current->name.isEmpty()
+ )
+ {
+ // static Java initializer
+ needsSemi = FALSE;
+ if (current->stat)
+ {
+ current->name="[static initializer]";
+ current->type.resize(0);
+ }
+ else
+ {
+ current->name="[instance initializer]";
+ }
+ unput(*yytext);
+ BEGIN( Function );
+ }
+ else
+ {
+ // pre C++11 code -> ignore the initializer
+ //needsSemi = TRUE;
+ //current->type.resize(0);
+ //current->name.resize(0);
+ //current->args.resize(0);
+ //current->argList->clear();
+ //curlyCount=0;
+ //BEGIN( SkipCurlyBlock );
+
+ // C++11 style initializer list
+ current->bodyLine = yyLineNr;
+ current->initializer = yytext;
+ lastInitializerContext = YY_START;
+ initBracketCount=1;
+ BEGIN(ReadInitializer);
+ }
+ }
+ }
+<CSAccessorDecl>"{" { curlyCount++; }
+<CSAccessorDecl>"}" {
+ if (curlyCount)
+ {
+ curlyCount--;
+ }
+ else
+ {
+ mtype = Method;
+ virt = Normal;
+ unput(';');
+ BEGIN(FindMembers);
+ }
+ }
+<CSAccessorDecl>"private "{BN}*"set" { if (curlyCount==0) current->spec |= Entry::PrivateSettable; }
+<CSAccessorDecl>"protected "{BN}*"set" { if (curlyCount==0) current->spec |= Entry::ProtectedSettable; }
+<CSAccessorDecl>"private "{BN}*"get" { if (curlyCount==0) current->spec |= Entry::PrivateGettable; }
+<CSAccessorDecl>"protected "{BN}*"get" { if (curlyCount==0) current->spec |= Entry::ProtectedGettable; }
+<CSAccessorDecl>"set" { if (curlyCount==0) current->spec |= Entry::Settable; }
+<CSAccessorDecl>"get" { if (curlyCount==0) current->spec |= Entry::Gettable; }
+<CSAccessorDecl>"add" { if (curlyCount==0) current->spec |= Entry::Addable; }
+<CSAccessorDecl>"remove" { if (curlyCount==0) current->spec |= Entry::Removable; }
+<CSAccessorDecl>"raise" { if (curlyCount==0) current->spec |= Entry::Raisable; }
+<CSAccessorDecl>. {}
+<CSAccessorDecl>\n { lineCount(); }
+
+
+
+
+ /**********************************************************************************/
+ /******************** Documentation block related rules ***************************/
+ /**********************************************************************************/
+
+ /* ---- Single line comments ------ */
+<DocLine>[^\n]*"\n"[ \t]*"//"[/!] { // continuation of multiline C++-style comment
+ docBlock+=yytext;
+ docBlock.resize(docBlock.length() - 3);
+ lineCount();
+ }
+<DocLine>{B}*"///"[/]+{B}*/"\n" { // ignore marker line (see bug700345)
+ handleCommentBlock(docBlock.data(),current->brief.isEmpty());
+ BEGIN( docBlockContext );
+ }
+<DocLine>[^\n]*/"\n" { // whole line
+ docBlock+=yytext;
+ handleCommentBlock(docBlock.data(),current->brief.isEmpty());
+ BEGIN( docBlockContext );
+ }
+
+ /* ---- Comments blocks ------ */
+
+<DocBlock>"*"*"*/" { // end of comment block
+ handleCommentBlock(docBlock.data(),FALSE);
+ BEGIN(docBlockContext);
+ }
+<DocBlock>^{B}*"*"+/[^/] {
+
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock+=indent;
+ }
+<DocBlock>^{B}*("//")?{B}*"*"+/[^//a-z_A-Z0-9*] { // start of a comment line
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,g_column));
+ docBlock+=indent;
+ }
+<DocBlock>^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line
+ }
+<DocBlock>"//" { // slashes in the middle of a comment block
+ docBlock+=yytext;
+ }
+<DocBlock>"/*" { // start of a new comment in the
+ // middle of a comment block
+ docBlock+=yytext;
+ }
+<DocBlock>("@@"|"\\\\"){ID}/[^a-z_A-Z0-9] { // escaped command
+ docBlock+=yytext;
+ }
+<DocBlock>{CMD}("f$"|"f["|"f{") {
+ docBlock+=yytext;
+ docBlockName=&yytext[1];
+ if (docBlockName.at(1)=='{')
+ {
+ docBlockName.at(1)='}';
+ }
+ g_fencedSize=0;
+ g_nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{B}*"<"{PRE}">" {
+ docBlock+=yytext;
+ docBlockName="<pre>";
+ g_fencedSize=0;
+ g_nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!)
+ docBlock+=yytext;
+ docBlockName=&yytext[1];
+ g_fencedSize=0;
+ g_nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>"~~~"[~]* {
+ docBlock+=yytext;
+ docBlockName="~~~";
+ g_fencedSize=yyleng;
+ g_nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>{B}*"<code>" {
+ if (insideCS)
+ {
+ docBlock+=yytext;
+ docBlockName="<code>";
+ g_nestedComment=FALSE;
+ BEGIN(DocCopyBlock);
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
+ docBlock+=yytext;
+ }
+<DocBlock>\n { // newline
+ lineCount();
+ docBlock+=*yytext;
+ }
+<DocBlock>. { // command block
+ docBlock+=*yytext;
+ }
+
+ /* ---- Copy verbatim sections ------ */
+
+<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
+ docBlock+=yytext;
+ if (docBlockName=="<pre>")
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
+ docBlock+=yytext;
+ if (docBlockName=="<code>")
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>[\\@]("f$"|"f]"|"f}") {
+ docBlock+=yytext;
+ BEGIN(DocBlock);
+ }
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+ docBlock+=yytext;
+ if (&yytext[4]==docBlockName)
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
+ if (docBlockName=="verbatim")
+ {
+ REJECT;
+ }
+ else if (docBlockName=="code")
+ {
+ REJECT;
+ }
+ else
+ {
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,0));
+ docBlock+=indent;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}+"*"{BN}* { // start of a comment line with two *'s
+ if (docBlockName=="code")
+ {
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,0));
+ docBlock+=indent;
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
+ if (docBlockName=="code")
+ {
+ QCString indent;
+ indent.fill(' ',computeIndent(yytext,-1));
+ docBlock+=indent+"*";
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
+ if (docBlockName=="code")
+ {
+ QCString indent;
+ if (g_nestedComment) // keep * it is part of the code
+ {
+ indent.fill(' ',computeIndent(yytext,-1));
+ docBlock+=indent+"*";
+ }
+ else // remove * it is part of the comment block
+ {
+ indent.fill(' ',computeIndent(yytext,0));
+ docBlock+=indent;
+ }
+ }
+ else
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>"~~~"[~]* {
+ docBlock+=yytext;
+ if (g_fencedSize==yyleng)
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>[^\<@/*\]~\$\\\n]+ { // any character that is not special
+ docBlock+=yytext;
+ }
+<DocCopyBlock>"/*"|"*/"|"//" {
+ if (yytext[1]=='*')
+ {
+ g_nestedComment=TRUE;
+ }
+ else if (yytext[0]=='*')
+ {
+ g_nestedComment=FALSE;
+ }
+ docBlock+=yytext;
+ }
+<DocCopyBlock>\n { // newline
+ docBlock+=*yytext;
+ lineCount();
+ }
+<DocCopyBlock>. { // any other character
+ docBlock+=*yytext;
+ }
+<DocCopyBlock><<EOF>> {
+ warn(yyFileName,yyLineNr,
+ "reached end of file while inside a %s block!\n"
+ "The command that should end the block seems to be missing!\n",
+ docBlockName.data());
+ yyterminate();
+ }
+
+
+ /* ------------- Prototype parser -------------- */
+
+<Prototype>"operator"{B}*"("{B}*")" {
+ current->name+=yytext;
+ }
+<Prototype>"(" {
+ current->args+=*yytext;
+ currentArgumentContext = PrototypeQual;
+ fullArgString = current->args.copy();
+ copyArgString = ¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ }
+<Prototype>"("({ID}"::")*({B}*[&*])+ {
+ current->type+=current->name+yytext;
+ current->name.resize(0);
+ BEGIN( PrototypePtr );
+ }
+<PrototypePtr>{SCOPENAME} {
+ current->name+=yytext;
+ }
+<PrototypePtr>"(" {
+ current->args+=*yytext;
+ currentArgumentContext = PrototypeQual;
+ fullArgString = current->args.copy();
+ copyArgString = ¤t->args;
+ BEGIN( ReadFuncArgType ) ;
+ }
+<PrototypePtr>")" {
+ current->type+=')';
+ BEGIN( Prototype );
+ }
+<PrototypePtr>. {
+ current->name+=yytext;
+ }
+<PrototypeQual>"{" {
+ BEGIN( PrototypeSkipLine);
+ }
+<PrototypeQual>{B}*"const"{B}* {
+ current->args += " const ";
+ current->argList->constSpecifier=TRUE;
+ }
+<PrototypeQual>{B}*"volatile"{B}* {
+ current->args += " volatile ";
+ current->argList->volatileSpecifier=TRUE;
+ }
+<PrototypeQual>{B}*"="{B}*"0"{B}* {
+ current->args += " = 0";
+ current->virt = Pure;
+ current->argList->pureSpecifier=TRUE;
+ }
+<PrototypeQual>"throw"{B}*"(" {
+ current->exception = "throw(";
+ BEGIN(PrototypeExc);
+ }
+<PrototypeExc>")" {
+ current->exception += ')';
+ BEGIN(PrototypeQual);
+ }
+<PrototypeExc>. {
+ current->exception += *yytext;
+ }
+<PrototypeQual>. {
+ current->args += *yytext;
+ }
+<Prototype>. {
+ current->name += *yytext;
+ }
+<PrototypeSkipLine>. {
+ }
+
+
+ /* ------------ Generic rules -------------- */
+
+
+<SkipCxxComment>.*"\\\n" { // line continuation
+ if (insideCS)
+ {
+ REJECT;
+ }
+ else
+ {
+ lineCount();
+ }
+ }
+<SkipCxxComment>.*/\n {
+ BEGIN( lastCContext ) ;
+ }
+<SkipComment>[^\*\n]+
+<*>\n { lineCount(); }
+<*>\" {
+ if (insideIDL && insideCppQuote)
+ {
+ BEGIN(EndCppQuote);
+ }
+ }
+<*>"#" {
+ if (!insidePHP)
+ REJECT;
+ lastCContext = YY_START ;
+ BEGIN( SkipCxxComment ) ;
+ }
+<*>\' {
+ if (insidePHP)
+ {
+ lastStringContext=YY_START;
+ BEGIN(SkipPHPString);
+ }
+ }
+<*>\" {
+ if (insidePHP)
+ {
+ lastStringContext=YY_START;
+ BEGIN(SkipString);
+ }
+ }
+<*>.
+<SkipComment>"//"|"/*"
+<*>"/*" { lastCContext = YY_START ;
+ BEGIN( SkipComment ) ;
+ }
+<SkipComment>{B}*"*/" { BEGIN( lastCContext ) ; }
+<*>"//" {
+ lastCContext = YY_START ;
+ BEGIN( SkipCxxComment ) ;
+ }
+%%
+
+//----------------------------------------------------------------------------
+
+static void startCommentBlock(bool brief)
+{
+ if (brief)
+ {
+ current->briefFile = yyFileName;
+ current->briefLine = yyLineNr;
+ }
+ else
+ {
+ current->docFile = yyFileName;
+ current->docLine = yyLineNr;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void newEntry()
+{
+ if (tempEntry==0) // if temp entry is not 0, it holds current,
+ // and current is actually replaced by previous which was
+ // already added to current_root, so we should not add it again
+ // (see bug723314)
+ {
+ current_root->addSubEntry(current);
+ }
+ tempEntry = 0;
+ previous = current;
+ current = new Entry ;
+ initEntry();
+}
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+ static bool hideInBodyDocs = Config_getBool("HIDE_IN_BODY_DOCS");
+ int position=0;
+ bool needsEntry=FALSE;
+ if (docBlockInBody && hideInBodyDocs) return;
+ //printf("parseCommentBlock [%s] brief=%d\n",doc.data(),brief);
+ int lineNr = brief ? current->briefLine : current->docLine; // line of block start
+
+ // fill in inbodyFile && inbodyLine the first time, see bug 633891
+ Entry *docEntry = docBlockInBody && previous ? previous : current;
+ if (docBlockInBody && docEntry && docEntry->inbodyLine==-1)
+ {
+ docEntry->inbodyFile = yyFileName;
+ docEntry->inbodyLine = lineNr;
+ }
+
+ while (parseCommentBlock(
+ g_thisParser,
+ docBlockInBody && previous ? previous : current,
+ stripIndentation(doc), // text
+ yyFileName, // file
+ lineNr, // line of block start
+ docBlockInBody ? FALSE : brief, // isBrief
+ docBlockInBody ? FALSE : docBlockAutoBrief, // isJavaDocStyle
+ docBlockInBody, // isInBody
+ protection,
+ position,
+ needsEntry
+ )
+ )
+ {
+ //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
+ if (needsEntry)
+ {
+ QCString docFile = current->docFile;
+ newEntry();
+ current->docFile = docFile;
+ current->docLine = lineNr;
+ }
+ }
+ if (needsEntry)
+ {
+ newEntry();
+ }
+
+ if (docBlockTerm)
+ {
+ unput(docBlockTerm);
+ docBlockTerm=0;
+ }
+}
+
+static void handleParametersCommentBlocks(ArgumentList *al)
+{
+ //printf(">>>>>>> handleParametersCommentBlocks()\n");
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ //printf(" Param %s docs=%s\n",a->name.data(),a->docs.data());
+ if (!a->docs.isEmpty())
+ {
+ int position=0;
+ bool needsEntry;
+
+ // save context
+ QCString orgDoc = current->doc;
+ QCString orgBrief = current->brief;
+ int orgDocLine = current->docLine;
+ int orgBriefLine = current->briefLine;
+
+ current->doc.resize(0);
+ current->brief.resize(0);
+
+ //printf("handleParametersCommentBlock [%s]\n",doc.data());
+ while (parseCommentBlock(
+ g_thisParser,
+ current,
+ a->docs, // text
+ yyFileName, // file
+ current->docLine, // line of block start
+ FALSE,
+ FALSE,
+ FALSE,
+ protection,
+ position,
+ needsEntry
+ )
+ )
+ {
+ //printf("handleParametersCommentBlock position=%d [%s]\n",position,doc.data()+position);
+ if (needsEntry) newEntry();
+ }
+ if (needsEntry)
+ {
+ newEntry();
+ }
+ a->docs = current->doc;
+
+ // restore context
+ current->doc = orgDoc;
+ current->brief = orgBrief;
+ current->docLine = orgDocLine;
+ current->briefLine = orgBriefLine;
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+static void parseCompounds(Entry *rt)
+{
+ //printf("parseCompounds(%s)\n",rt->name.data());
+ EntryListIterator eli(*rt->children());
+ Entry *ce;
+ for (;(ce=eli.current());++eli)
+ {
+ if (!ce->program.isEmpty())
+ {
+ //printf("-- %s ---------\n%s\n---------------\n",
+ // ce->name.data(),ce->program.data());
+ // init scanner state
+ padCount=0;
+ //depthIf = 0;
+ g_column=0;
+ inputString = ce->program;
+ inputPosition = 0;
+ scannerYYrestart( scannerYYin ) ;
+ if (ce->section==Entry::ENUM_SEC || (ce->spec&Entry::Enum))
+ BEGIN( FindFields ) ;
+ else
+ BEGIN( FindMembers ) ;
+ current_root = ce ;
+ yyFileName = ce->fileName;
+ //setContext();
+ yyLineNr = ce->startLine ;
+ yyColNr = ce->startColumn ;
+ insideObjC = ce->lang==SrcLangExt_ObjC;
+ //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC);
+ //current->reset();
+ if (current) delete current;
+ current = new Entry;
+ gstat = FALSE;
+ initEntry();
+
+ // deep copy group list from parent (see bug 727732)
+ if (rt->groups)
+ {
+ QListIterator<Grouping> gli(*rt->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ ce->groups->append(new Grouping(*g));
+ }
+ }
+
+ int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2;
+ // set default protection based on the compound type
+ if( ce->section==Entry::CLASS_SEC ) // class
+ {
+ if (insidePHP || insideD || insideJS || insideIDL)
+ {
+ current->protection = protection = Public ;
+ }
+ else if (insideJava)
+ {
+ current->protection = protection = (ce->spec & (Entry::Interface|Entry::Enum)) ? Public : Package;
+ }
+ else if (ce->spec&(Entry::Interface | Entry::Ref | Entry::Value | Entry::Struct | Entry::Union))
+ {
+ if (ce->lang==SrcLangExt_ObjC)
+ {
+ current->protection = protection = Protected ;
+ }
+ else
+ {
+ current->protection = protection = Public ;
+ }
+ }
+ else
+ {
+ current->protection = protection = Private ;
+ }
+ }
+ else if (ce->section == Entry::ENUM_SEC ) // enum
+ {
+ current->protection = protection = ce->protection;
+ }
+ else if (!ce->name.isEmpty() && ce->name.at(ni)=='@') // unnamed union or namespace
+ {
+ if (ce->section == Entry::NAMESPACE_SEC ) // unnamed namespace
+ {
+ current->stat = gstat = TRUE;
+ }
+ current->protection = protection = ce->protection;
+ }
+ else // named struct, union, protocol, category
+ {
+ current->protection = protection = Public ;
+ }
+ mtype = Method;
+ virt = Normal;
+ //printf("name=%s current->stat=%d gstat=%d\n",ce->name.data(),current->stat,gstat);
+
+ //memberGroupId = DOX_NOGROUP;
+ //memberGroupRelates.resize(0);
+ //memberGroupInside.resize(0);
+ groupEnterCompound(yyFileName,yyLineNr,ce->name);
+
+ scannerYYlex() ;
+ g_lexInit=TRUE;
+ //forceEndGroup();
+
+ groupLeaveCompound(yyFileName,yyLineNr,ce->name);
+
+ delete current; current=0;
+ ce->program.resize(0);
+
+
+ //if (depthIf>0)
+ //{
+ // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ //}
+ }
+ parseCompounds(ce);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void parseMain(const char *fileName,
+ const char *fileBuf,
+ Entry *rt,
+ bool sameTranslationUnit,
+ QStrList & filesInSameTranslationUnit)
+{
+ initParser();
+
+ inputString = fileBuf;
+ inputPosition = 0;
+ g_column = 0;
+
+ //anonCount = 0; // don't reset per file
+ //depthIf = 0;
+ protection = Public;
+ mtype = Method;
+ gstat = FALSE;
+ virt = Normal;
+ current_root = rt;
+ global_root = rt;
+ inputFile.setName(fileName);
+ if (inputFile.open(IO_ReadOnly))
+ {
+ yyLineNr= 1 ;
+ yyFileName = fileName;
+ setContext();
+ bool processWithClang = insideCpp || insideObjC;
+ if (processWithClang)
+ {
+ if (!sameTranslationUnit) // new file
+ {
+ ClangParser::instance()->start(fileName,filesInSameTranslationUnit);
+ }
+ else
+ {
+ ClangParser::instance()->switchToFile(fileName);
+ }
+ }
+ rt->lang = language;
+ msg("Parsing file %s...\n",yyFileName.data());
+
+ current_root = rt ;
+ initParser();
+ groupEnterFile(yyFileName,yyLineNr);
+ current = new Entry;
+ //printf("current=%p current_root=%p\n",current,current_root);
+ int sec=guessSection(yyFileName);
+ if (sec)
+ {
+ current->name = yyFileName;
+ current->section = sec;
+ current_root->addSubEntry(current);
+ current = new Entry;
+ }
+ current->reset();
+ initEntry();
+ scannerYYrestart( scannerYYin );
+ if ( insidePHP )
+ {
+ BEGIN( FindMembersPHP );
+ }
+ else
+ {
+ BEGIN( FindMembers );
+ }
+
+ scannerYYlex();
+ g_lexInit=TRUE;
+
+ if (YY_START==Comment)
+ {
+ warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?");
+ }
+
+ //forceEndGroup();
+ groupLeaveFile(yyFileName,yyLineNr);
+
+ //if (depthIf>0)
+ //{
+ // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ //}
+
+ rt->program.resize(0);
+ if (rt->children()->contains(current)==0)
+ // it could be that current is already added as a child to rt, so we
+ // only delete it if this is not the case. See bug 635317.
+ {
+ delete current; current=0;
+ }
+
+ parseCompounds(rt);
+
+ inputFile.close();
+
+ anonNSCount++;
+
+ }
+}
+
+//----------------------------------------------------------------------------
+
+static void parsePrototype(const QCString &text)
+{
+ //printf("**** parsePrototype(%s) begin\n",text.data());
+ if (text.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Empty prototype found!");
+ return;
+ }
+ if (!current) // nothing to store (see bug683516)
+ {
+ return;
+ }
+
+ const char *orgInputString;
+ int orgInputPosition;
+ YY_BUFFER_STATE orgState;
+
+ // save scanner state
+ orgState = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(scannerYYin, YY_BUF_SIZE));
+ orgInputString = inputString;
+ orgInputPosition = inputPosition;
+
+ // set new string
+ inputString = text;
+ inputPosition = 0;
+ g_column = 0;
+ scannerYYrestart( scannerYYin );
+ BEGIN(Prototype);
+ scannerYYlex();
+ g_lexInit=TRUE;
+
+ current->name = current->name.stripWhiteSpace();
+ if (current->section == Entry::MEMBERDOC_SEC && current->args.isEmpty())
+ current->section = Entry::VARIABLEDOC_SEC;
+
+ // restore original scanner state
+ YY_BUFFER_STATE tmpState = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(orgState);
+ yy_delete_buffer(tmpState);
+ inputString = orgInputString;
+ inputPosition = orgInputPosition;
+
+ //printf("**** parsePrototype end\n");
+}
+
+void scanFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+ if (g_lexInit)
+ {
+ scannerYYlex_destroy();
+ }
+#endif
+}
+
+//static void handleGroupStartCommand(const char *header)
+//{
+// memberGroupHeader=header;
+// startGroupInDoc();
+//}
+//
+//static void handleGroupEndCommand()
+//{
+// endGroup();
+// previous=0;
+//}
+
+//----------------------------------------------------------------------------
+
+void CLanguageScanner::startTranslationUnit(const char *)
+{
+}
+
+void CLanguageScanner::finishTranslationUnit()
+{
+ bool processWithClang = insideCpp || insideObjC;
+ if (processWithClang)
+ {
+ ClangParser::instance()->finish();
+ }
+}
+
+void CLanguageScanner::parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList & filesInSameTranslationUnit)
+{
+ g_thisParser = this;
+
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+
+ ::parseMain(fileName,fileBuf,root,
+ sameTranslationUnit,filesInSameTranslationUnit);
+
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
+ const char * scopeName,
+ const QCString & input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char * exampleName,
+ FileDef * fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ ::parseCCode(codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName,
+ fileDef,startLine,endLine,inlineFragment,memberDef,
+ showLineNumbers,searchCtx,collectXRefs);
+}
+
+bool CLanguageScanner::needsPreprocessing(const QCString &extension)
+{
+ QCString fe=extension.lower();
+ SrcLangExt lang = getLanguageFromFileName(extension);
+ return (SrcLangExt_Cpp == lang) ||
+ !( fe==".java" || fe==".as" || fe==".d" || fe==".php" ||
+ fe==".php4" || fe==".inc" || fe==".phtml"
+ );
+}
+
+void CLanguageScanner::resetCodeParserState()
+{
+ ::resetCCodeParserState();
+}
+
+void CLanguageScanner::parsePrototype(const char *text)
+{
+ ::parsePrototype(text);
+}
+
+//----------------------------------------------------------------------------
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void scannerYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/search.css b/src/search.css
new file mode 100644
index 0000000..a77ab21
--- /dev/null
+++ b/src/search.css
@@ -0,0 +1,271 @@
+/*---------------- Search Box */
+
+#FSearchBox {
+ float: left;
+}
+
+#MSearchBox {
+ white-space : nowrap;
+ position: absolute;
+ float: none;
+ display: inline;
+ margin-top: 8px;
+ right: 0px;
+ width: 170px;
+ z-index: 102;
+ background-color: white;
+}
+
+#MSearchBox .left
+{
+ display:block;
+ position:absolute;
+ left:10px;
+ width:20px;
+ height:19px;
+ background:url('search_l.png') no-repeat;
+ background-position:right;
+}
+
+#MSearchSelect {
+ display:block;
+ position:absolute;
+ width:20px;
+ height:19px;
+}
+
+.left #MSearchSelect {
+ left:4px;
+}
+
+.right #MSearchSelect {
+ right:5px;
+}
+
+#MSearchField {
+ display:block;
+ position:absolute;
+ height:19px;
+ background:url('search_m.png') repeat-x;
+ border:none;
+ width:111px;
+ margin-left:20px;
+ padding-left:4px;
+ color: #909090;
+ outline: none;
+ font: 9pt Arial, Verdana, sans-serif;
+}
+
+#FSearchBox #MSearchField {
+ margin-left:15px;
+}
+
+#MSearchBox .right {
+ display:block;
+ position:absolute;
+ right:10px;
+ top:0px;
+ width:20px;
+ height:19px;
+ background:url('search_r.png') no-repeat;
+ background-position:left;
+}
+
+#MSearchClose {
+ display: none;
+ position: absolute;
+ top: 4px;
+ background : none;
+ border: none;
+ margin: 0px 4px 0px 0px;
+ padding: 0px 0px;
+ outline: none;
+}
+
+.left #MSearchClose {
+ left: 6px;
+}
+
+.right #MSearchClose {
+ right: 2px;
+}
+
+.MSearchBoxActive #MSearchField {
+ color: #000000;
+}
+
+/*---------------- Search filter selection */
+
+#MSearchSelectWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid ##A0;
+ background-color: ##FA;
+ z-index: 1;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+.SelectItem {
+ font: 8pt Arial, Verdana, sans-serif;
+ padding-left: 2px;
+ padding-right: 12px;
+ border: 0px;
+}
+
+span.SelectionMark {
+ margin-right: 4px;
+ font-family: monospace;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem {
+ display: block;
+ outline-style: none;
+ color: #000000;
+ text-decoration: none;
+ padding-left: 6px;
+ padding-right: 12px;
+}
+
+a.SelectItem:focus,
+a.SelectItem:active {
+ color: #000000;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem:hover {
+ color: #FFFFFF;
+ background-color: ##50;
+ outline-style: none;
+ text-decoration: none;
+ cursor: pointer;
+ display: block;
+}
+
+/*---------------- Search results window */
+
+iframe#MSearchResults {
+ width: 60ex;
+ height: 15em;
+}
+
+#MSearchResultsWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid #000;
+ background-color: ##F0;
+}
+
+/* ----------------------------------- */
+
+
+#SRIndex {
+ clear:both;
+ padding-bottom: 15px;
+}
+
+.SREntry {
+ font-size: 10pt;
+ padding-left: 1ex;
+}
+
+.SRPage .SREntry {
+ font-size: 8pt;
+ padding: 1px 5px;
+}
+
+body.SRPage {
+ margin: 5px 2px;
+}
+
+.SRChildren {
+ padding-left: 3ex; padding-bottom: .5em
+}
+
+.SRPage .SRChildren {
+ display: none;
+}
+
+.SRSymbol {
+ font-weight: bold;
+ color: ##58;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRScope {
+ display: block;
+ color: ##58;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRSymbol:focus, a.SRSymbol:active,
+a.SRScope:focus, a.SRScope:active {
+ text-decoration: underline;
+}
+
+span.SRScope {
+ padding-left: 4px;
+}
+
+.SRPage .SRStatus {
+ padding: 2px 5px;
+ font-size: 8pt;
+ font-style: italic;
+}
+
+.SRResult {
+ display: none;
+}
+
+DIV.searchresults {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+/*---------------- External search page results */
+
+.searchresult {
+ background-color: ##F2;
+}
+
+.pages b {
+ color: white;
+ padding: 5px 5px 3px 5px;
+ background-image: url("../tab_a.png");
+ background-repeat: repeat-x;
+ text-shadow: 0 1px 1px #000000;
+}
+
+.pages {
+ line-height: 17px;
+ margin-left: 4px;
+ text-decoration: none;
+}
+
+.hl {
+ font-weight: bold;
+}
+
+#searchresults {
+ margin-bottom: 20px;
+}
+
+.searchpages {
+ margin-top: 10px;
+}
+
diff --git a/src/search.js b/src/search.js
new file mode 100644
index 0000000..10cee88
--- /dev/null
+++ b/src/search.js
@@ -0,0 +1,776 @@
+function convertToId(search)
+{
+ var result = '';
+ for (i=0;i<search.length;i++)
+ {
+ var c = search.charAt(i);
+ var cn = c.charCodeAt(0);
+ if (c.match(/[a-z0-9\u0080-\uFFFF]/))
+ {
+ result+=c;
+ }
+ else if (cn<16)
+ {
+ result+="_0"+cn.toString(16);
+ }
+ else
+ {
+ result+="_"+cn.toString(16);
+ }
+ }
+ return result;
+}
+
+function getXPos(item)
+{
+ var x = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ x += item.offsetLeft;
+ item = item.offsetParent;
+ }
+ }
+ return x;
+}
+
+function getYPos(item)
+{
+ var y = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ y += item.offsetTop;
+ item = item.offsetParent;
+ }
+ }
+ return y;
+}
+
+/* A class handling everything associated with the search panel.
+
+ Parameters:
+ name - The name of the global variable that will be
+ storing this instance. Is needed to be able to set timeouts.
+ resultPath - path to use for external files
+*/
+function SearchBox(name, resultsPath, inFrame, label)
+{
+ if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
+
+ // ---------- Instance variables
+ this.name = name;
+ this.resultsPath = resultsPath;
+ this.keyTimeout = 0;
+ this.keyTimeoutLength = 500;
+ this.closeSelectionTimeout = 300;
+ this.lastSearchValue = "";
+ this.lastResultsPage = "";
+ this.hideTimeout = 0;
+ this.searchIndex = 0;
+ this.searchActive = false;
+ this.insideFrame = inFrame;
+ this.searchLabel = label;
+
+ // ----------- DOM Elements
+
+ this.DOMSearchField = function()
+ { return document.getElementById("MSearchField"); }
+
+ this.DOMSearchSelect = function()
+ { return document.getElementById("MSearchSelect"); }
+
+ this.DOMSearchSelectWindow = function()
+ { return document.getElementById("MSearchSelectWindow"); }
+
+ this.DOMPopupSearchResults = function()
+ { return document.getElementById("MSearchResults"); }
+
+ this.DOMPopupSearchResultsWindow = function()
+ { return document.getElementById("MSearchResultsWindow"); }
+
+ this.DOMSearchClose = function()
+ { return document.getElementById("MSearchClose"); }
+
+ this.DOMSearchBox = function()
+ { return document.getElementById("MSearchBox"); }
+
+ // ------------ Event Handlers
+
+ // Called when focus is added or removed from the search field.
+ this.OnSearchFieldFocus = function(isActive)
+ {
+ this.Activate(isActive);
+ }
+
+ this.OnSearchSelectShow = function()
+ {
+ var searchSelectWindow = this.DOMSearchSelectWindow();
+ var searchField = this.DOMSearchSelect();
+
+ if (this.insideFrame)
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ left += searchField.offsetWidth + 6;
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ left -= searchSelectWindow.offsetWidth;
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+ else
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+
+ // stop selection hide timer
+ if (this.hideTimeout)
+ {
+ clearTimeout(this.hideTimeout);
+ this.hideTimeout=0;
+ }
+ return false; // to avoid "image drag" default event
+ }
+
+ this.OnSearchSelectHide = function()
+ {
+ this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
+ this.closeSelectionTimeout);
+ }
+
+ // Called when the content of the search field is changed.
+ this.OnSearchFieldChange = function(evt)
+ {
+ if (this.keyTimeout) // kill running timer
+ {
+ clearTimeout(this.keyTimeout);
+ this.keyTimeout = 0;
+ }
+
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 || e.keyCode==13)
+ {
+ if (e.shiftKey==1)
+ {
+ this.OnSearchSelectShow();
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ child.focus();
+ return;
+ }
+ }
+ return;
+ }
+ else if (window.frames.MSearchResults.searchResults)
+ {
+ var elem = window.frames.MSearchResults.searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+ }
+ else if (e.keyCode==27) // Escape out of the search field
+ {
+ this.DOMSearchField().blur();
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ this.Activate(false);
+ return;
+ }
+
+ // strip whitespaces
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+
+ if (searchValue != this.lastSearchValue) // search value has changed
+ {
+ if (searchValue != "") // non-empty search
+ {
+ // set timer for search update
+ this.keyTimeout = setTimeout(this.name + '.Search()',
+ this.keyTimeoutLength);
+ }
+ else // empty search field
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ }
+ }
+ }
+
+ this.SelectItemCount = function(id)
+ {
+ var count=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ this.SelectItemSet = function(id)
+ {
+ var i,j=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ var node = child.firstChild;
+ if (j==id)
+ {
+ node.innerHTML='•';
+ }
+ else
+ {
+ node.innerHTML=' ';
+ }
+ j++;
+ }
+ }
+ }
+
+ // Called when an search filter selection is made.
+ // set item with index id as the active item
+ this.OnSelectItem = function(id)
+ {
+ this.searchIndex = id;
+ this.SelectItemSet(id);
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+ if (searchValue!="" && this.searchActive) // something was found -> do a search
+ {
+ this.Search();
+ }
+ }
+
+ this.OnSearchSelectKey = function(evt)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
+ {
+ this.searchIndex++;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==38 && this.searchIndex>0) // Up
+ {
+ this.searchIndex--;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==13 || e.keyCode==27)
+ {
+ this.OnSelectItem(this.searchIndex);
+ this.CloseSelectionWindow();
+ this.DOMSearchField().focus();
+ }
+ return false;
+ }
+
+ // --------- Actions
+
+ // Closes the results window.
+ this.CloseResultsWindow = function()
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.Activate(false);
+ }
+
+ this.CloseSelectionWindow = function()
+ {
+ this.DOMSearchSelectWindow().style.display = 'none';
+ }
+
+ // Performs a search.
+ this.Search = function()
+ {
+ this.keyTimeout = 0;
+
+ // strip leading whitespace
+ var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
+
+ var code = searchValue.toLowerCase().charCodeAt(0);
+ var idxChar = searchValue.substr(0, 1).toLowerCase();
+ if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
+ {
+ idxChar = searchValue.substr(0, 2);
+ }
+
+ var resultsPage;
+ var resultsPageWithSearch;
+ var hasResultsPage;
+
+ var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
+ if (idx!=-1)
+ {
+ var hexCode=idx.toString(16);
+ resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
+ resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
+ hasResultsPage = true;
+ }
+ else // nothing available for this search term
+ {
+ resultsPage = this.resultsPath + '/nomatches.html';
+ resultsPageWithSearch = resultsPage;
+ hasResultsPage = false;
+ }
+
+ window.frames.MSearchResults.location = resultsPageWithSearch;
+ var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
+
+ if (domPopupSearchResultsWindow.style.display!='block')
+ {
+ var domSearchBox = this.DOMSearchBox();
+ this.DOMSearchClose().style.display = 'inline';
+ if (this.insideFrame)
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ domPopupSearchResultsWindow.style.position = 'relative';
+ domPopupSearchResultsWindow.style.display = 'block';
+ var width = document.body.clientWidth - 8; // the -8 is for IE :-(
+ domPopupSearchResultsWindow.style.width = width + 'px';
+ domPopupSearchResults.style.width = width + 'px';
+ }
+ else
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
+ var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
+ domPopupSearchResultsWindow.style.display = 'block';
+ left -= domPopupSearchResults.offsetWidth;
+ domPopupSearchResultsWindow.style.top = top + 'px';
+ domPopupSearchResultsWindow.style.left = left + 'px';
+ }
+ }
+
+ this.lastSearchValue = searchValue;
+ this.lastResultsPage = resultsPage;
+ }
+
+ // -------- Activation Functions
+
+ // Activates or deactivates the search panel, resetting things to
+ // their default values if necessary.
+ this.Activate = function(isActive)
+ {
+ if (isActive || // open it
+ this.DOMPopupSearchResultsWindow().style.display == 'block'
+ )
+ {
+ this.DOMSearchBox().className = 'MSearchBoxActive';
+
+ var searchField = this.DOMSearchField();
+
+ if (searchField.value == this.searchLabel) // clear "Search" term upon entry
+ {
+ searchField.value = '';
+ this.searchActive = true;
+ }
+ }
+ else if (!isActive) // directly remove the panel
+ {
+ this.DOMSearchBox().className = 'MSearchBoxInactive';
+ this.DOMSearchField().value = this.searchLabel;
+ this.searchActive = false;
+ this.lastSearchValue = ''
+ this.lastResultsPage = '';
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// The class that handles everything on the search results page.
+function SearchResults(name)
+{
+ // The number of matches from the last run of <Search()>.
+ this.lastMatchCount = 0;
+ this.lastKey = 0;
+ this.repeatOn = false;
+
+ // Toggles the visibility of the passed element ID.
+ this.FindChildElement = function(id)
+ {
+ var parentElement = document.getElementById(id);
+ var element = parentElement.firstChild;
+
+ while (element && element!=parentElement)
+ {
+ if (element.nodeName == 'DIV' && element.className == 'SRChildren')
+ {
+ return element;
+ }
+
+ if (element.nodeName == 'DIV' && element.hasChildNodes())
+ {
+ element = element.firstChild;
+ }
+ else if (element.nextSibling)
+ {
+ element = element.nextSibling;
+ }
+ else
+ {
+ do
+ {
+ element = element.parentNode;
+ }
+ while (element && element!=parentElement && !element.nextSibling);
+
+ if (element && element!=parentElement)
+ {
+ element = element.nextSibling;
+ }
+ }
+ }
+ }
+
+ this.Toggle = function(id)
+ {
+ var element = this.FindChildElement(id);
+ if (element)
+ {
+ if (element.style.display == 'block')
+ {
+ element.style.display = 'none';
+ }
+ else
+ {
+ element.style.display = 'block';
+ }
+ }
+ }
+
+ // Searches for the passed string. If there is no parameter,
+ // it takes it from the URL query.
+ //
+ // Always returns true, since other documents may try to call it
+ // and that may or may not be possible.
+ this.Search = function(search)
+ {
+ if (!search) // get search word from URL
+ {
+ search = window.location.search;
+ search = search.substring(1); // Remove the leading '?'
+ search = unescape(search);
+ }
+
+ search = search.replace(/^ +/, ""); // strip leading spaces
+ search = search.replace(/ +$/, ""); // strip trailing spaces
+ search = search.toLowerCase();
+ search = convertToId(search);
+
+ var resultRows = document.getElementsByTagName("div");
+ var matches = 0;
+
+ var i = 0;
+ while (i < resultRows.length)
+ {
+ var row = resultRows.item(i);
+ if (row.className == "SRResult")
+ {
+ var rowMatchName = row.id.toLowerCase();
+ rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
+
+ if (search.length<=rowMatchName.length &&
+ rowMatchName.substr(0, search.length)==search)
+ {
+ row.style.display = 'block';
+ matches++;
+ }
+ else
+ {
+ row.style.display = 'none';
+ }
+ }
+ i++;
+ }
+ document.getElementById("Searching").style.display='none';
+ if (matches == 0) // no results
+ {
+ document.getElementById("NoMatches").style.display='block';
+ }
+ else // at least one result
+ {
+ document.getElementById("NoMatches").style.display='none';
+ }
+ this.lastMatchCount = matches;
+ return true;
+ }
+
+ // return the first item with index index or higher that is visible
+ this.NavNext = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index++;
+ }
+ return focusItem;
+ }
+
+ this.NavPrev = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index--;
+ }
+ return focusItem;
+ }
+
+ this.ProcessKeys = function(e)
+ {
+ if (e.type == "keydown")
+ {
+ this.repeatOn = false;
+ this.lastKey = e.keyCode;
+ }
+ else if (e.type == "keypress")
+ {
+ if (!this.repeatOn)
+ {
+ if (this.lastKey) this.repeatOn = true;
+ return false; // ignore first keypress after keydown
+ }
+ }
+ else if (e.type == "keyup")
+ {
+ this.lastKey = 0;
+ this.repeatOn = false;
+ }
+ return this.lastKey!=0;
+ }
+
+ this.Nav = function(evt,itemIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ var newIndex = itemIndex-1;
+ var focusItem = this.NavPrev(newIndex);
+ if (focusItem)
+ {
+ var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
+ if (child && child.style.display == 'block') // children visible
+ {
+ var n=0;
+ var tmpElem;
+ while (1) // search for last child
+ {
+ tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
+ if (tmpElem)
+ {
+ focusItem = tmpElem;
+ }
+ else // found it!
+ {
+ break;
+ }
+ n++;
+ }
+ }
+ }
+ if (focusItem)
+ {
+ focusItem.focus();
+ }
+ else // return focus to search field
+ {
+ parent.document.getElementById("MSearchField").focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = itemIndex+1;
+ var focusItem;
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem && elem.style.display == 'block') // children visible
+ {
+ focusItem = document.getElementById('Item'+itemIndex+'_c0');
+ }
+ if (!focusItem) focusItem = this.NavNext(newIndex);
+ if (focusItem) focusItem.focus();
+ }
+ else if (this.lastKey==39) // Right
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'block';
+ }
+ else if (this.lastKey==37) // Left
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'none';
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+
+ this.NavChild = function(evt,itemIndex,childIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ if (childIndex>0)
+ {
+ var newIndex = childIndex-1;
+ document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
+ }
+ else // already at first child, jump to parent
+ {
+ document.getElementById('Item'+itemIndex).focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = childIndex+1;
+ var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
+ if (!elem) // last child, jump to parent next parent
+ {
+ elem = this.NavNext(itemIndex+1);
+ }
+ if (elem)
+ {
+ elem.focus();
+ }
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+}
+
+function setKeyActions(elem,action)
+{
+ elem.setAttribute('onkeydown',action);
+ elem.setAttribute('onkeypress',action);
+ elem.setAttribute('onkeyup',action);
+}
+
+function setClassAttr(elem,attr)
+{
+ elem.setAttribute('class',attr);
+ elem.setAttribute('className',attr);
+}
+
+function createResults()
+{
+ var results = document.getElementById("SRResults");
+ for (var e=0; e<searchData.length; e++)
+ {
+ var id = searchData[e][0];
+ var srResult = document.createElement('div');
+ srResult.setAttribute('id','SR_'+id);
+ setClassAttr(srResult,'SRResult');
+ var srEntry = document.createElement('div');
+ setClassAttr(srEntry,'SREntry');
+ var srLink = document.createElement('a');
+ srLink.setAttribute('id','Item'+e);
+ setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
+ setClassAttr(srLink,'SRSymbol');
+ srLink.innerHTML = searchData[e][1][0];
+ srEntry.appendChild(srLink);
+ if (searchData[e][1].length==2) // single result
+ {
+ srLink.setAttribute('href',searchData[e][1][1][0]);
+ if (searchData[e][1][1][1])
+ {
+ srLink.setAttribute('target','_parent');
+ }
+ var srScope = document.createElement('span');
+ setClassAttr(srScope,'SRScope');
+ srScope.innerHTML = searchData[e][1][1][2];
+ srEntry.appendChild(srScope);
+ }
+ else // multiple results
+ {
+ srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
+ var srChildren = document.createElement('div');
+ setClassAttr(srChildren,'SRChildren');
+ for (var c=0; c<searchData[e][1].length-1; c++)
+ {
+ var srChild = document.createElement('a');
+ srChild.setAttribute('id','Item'+e+'_c'+c);
+ setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
+ setClassAttr(srChild,'SRScope');
+ srChild.setAttribute('href',searchData[e][1][c+1][0]);
+ if (searchData[e][1][c+1][1])
+ {
+ srChild.setAttribute('target','_parent');
+ }
+ srChild.innerHTML = searchData[e][1][c+1][2];
+ srChildren.appendChild(srChild);
+ }
+ srEntry.appendChild(srChildren);
+ }
+ srResult.appendChild(srEntry);
+ results.appendChild(srResult);
+ }
+}
+
diff --git a/src/search_functions.php b/src/search_functions.php
new file mode 100644
index 0000000..5ad2e5d
--- /dev/null
+++ b/src/search_functions.php
@@ -0,0 +1,366 @@
+<script language="PHP">
+require_once "search-config.php";
+
+function end_form($value)
+{
+ global $config;
+ global $translator;
+ if ($config['DISABLE_INDEX'] == false)
+ {
+ echo " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"$value\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n </form>\n </div><div class=\"right\"></div>\n </div>\n </li>\n </ul>\n </div>\n</div>\n";
+ }
+ if ($config['GENERATE_TREEVIEW'])
+ {
+ echo $translator['split_bar'];
+ }
+}
+
+function end_page()
+{
+ echo "</body></html>";
+}
+
+function search_results()
+{
+ global $translator;
+ return $translator['search_results_title'];
+}
+
+function matches_text($num)
+{
+ global $translator;
+ $string = $translator['search_results'][($num>2)?2:$num];
+ // The eval is used so that translator strings can contain $num.
+ eval("\$result = \"$string\";");
+ return $result;
+}
+
+function report_matches()
+{
+ global $translator;
+ return $translator['search_matches'];
+}
+
+function readInt($file)
+{
+ $b1 = ord(fgetc($file)); $b2 = ord(fgetc($file));
+ $b3 = ord(fgetc($file)); $b4 = ord(fgetc($file));
+ return ($b1<<24)|($b2<<16)|($b3<<8)|$b4;
+}
+
+function readString($file)
+{
+ $result="";
+ while (ord($c=fgetc($file))) $result.=$c;
+ return $result;
+}
+
+function readHeader($file)
+{
+ $header =fgetc($file); $header.=fgetc($file);
+ $header.=fgetc($file); $header.=fgetc($file);
+ return $header;
+}
+
+function computeIndex($word)
+{
+ // Simple hashing that allows for substring search
+ if (strlen($word)<2) return -1;
+ // high char of the index
+ $hi = ord($word{0});
+ if ($hi==0) return -1;
+ // low char of the index
+ $lo = ord($word{1});
+ if ($lo==0) return -1;
+ // return index
+ return $hi*256+$lo;
+}
+
+function search($file,$word,&$statsList)
+{
+ $index = computeIndex($word);
+ if ($index!=-1) // found a valid index
+ {
+ fseek($file,$index*4+4); // 4 bytes per entry, skip header
+ $index = readInt($file);
+ if ($index) // found words matching the hash key
+ {
+ $start=sizeof($statsList);
+ $count=$start;
+ fseek($file,$index);
+ $w = readString($file);
+ while ($w)
+ {
+ $statIdx = readInt($file);
+ if ($word==substr($w,0,strlen($word)))
+ { // found word that matches (as substring)
+ $statsList[$count++]=array(
+ "word"=>$word,
+ "match"=>$w,
+ "index"=>$statIdx,
+ "full"=>strlen($w)==strlen($word),
+ "docs"=>array()
+ );
+ }
+ $w = readString($file);
+ }
+ $totalHi=0;
+ $totalFreqHi=0;
+ $totalFreqLo=0;
+ for ($count=$start;$count<sizeof($statsList);$count++)
+ {
+ $statInfo = &$statsList[$count];
+ $multiplier = 1;
+ // whole word matches have a double weight
+ if ($statInfo["full"]) $multiplier=2;
+ fseek($file,$statInfo["index"]);
+ $numDocs = readInt($file);
+ $docInfo = array();
+ // read docs info + occurrence frequency of the word
+ for ($i=0;$i<$numDocs;$i++)
+ {
+ $idx=readInt($file);
+ $freq=readInt($file);
+ $docInfo[$i]=array("idx" => $idx,
+ "freq" => $freq>>1,
+ "rank" => 0.0,
+ "hi" => $freq&1
+ );
+ if ($freq&1) // word occurs in high priority doc
+ {
+ $totalHi++;
+ $totalFreqHi+=$freq*$multiplier;
+ }
+ else // word occurs in low priority doc
+ {
+ $totalFreqLo+=$freq*$multiplier;
+ }
+ }
+ // read name and url info for the doc
+ for ($i=0;$i<$numDocs;$i++)
+ {
+ fseek($file,$docInfo[$i]["idx"]);
+ $docInfo[$i]["name"]=readString($file);
+ $docInfo[$i]["url"]=readString($file);
+ }
+ $statInfo["docs"]=$docInfo;
+ }
+ $totalFreq=($totalHi+1)*$totalFreqLo + $totalFreqHi;
+ for ($count=$start;$count<sizeof($statsList);$count++)
+ {
+ $statInfo = &$statsList[$count];
+ $multiplier = 1;
+ // whole word matches have a double weight
+ if ($statInfo["full"]) $multiplier=2;
+ for ($i=0;$i<sizeof($statInfo["docs"]);$i++)
+ {
+ $docInfo = &$statInfo["docs"];
+ // compute frequency rank of the word in each doc
+ $freq=$docInfo[$i]["freq"];
+ if ($docInfo[$i]["hi"])
+ {
+ $statInfo["docs"][$i]["rank"]=
+ (float)($freq*$multiplier+$totalFreqLo)/$totalFreq;
+ }
+ else
+ {
+ $statInfo["docs"][$i]["rank"]=
+ (float)($freq*$multiplier)/$totalFreq;
+ }
+ }
+ }
+ }
+ }
+ return $statsList;
+}
+
+function combine_results($results,&$docs)
+{
+ foreach ($results as $wordInfo)
+ {
+ $docsList = &$wordInfo["docs"];
+ foreach ($docsList as $di)
+ {
+ $key=$di["url"];
+ $rank=$di["rank"];
+ if (isset($docs[$key]))
+ {
+ $docs[$key]["rank"]+=$rank;
+ }
+ else
+ {
+ $docs[$key] = array("url"=>$key,
+ "name"=>$di["name"],
+ "rank"=>$rank
+ );
+ }
+ $docs[$key]["words"][] = array(
+ "word"=>$wordInfo["word"],
+ "match"=>$wordInfo["match"],
+ "freq"=>$di["freq"]
+ );
+ }
+ }
+ return $docs;
+}
+
+function filter_results($docs,&$requiredWords,&$forbiddenWords)
+{
+ $filteredDocs=array();
+ while (list ($key, $val) = each ($docs))
+ {
+ $words = &$docs[$key]["words"];
+ $copy=1; // copy entry by default
+ if (sizeof($requiredWords)>0)
+ {
+ foreach ($requiredWords as $reqWord)
+ {
+ $found=0;
+ foreach ($words as $wordInfo)
+ {
+ $found = $wordInfo["word"]==$reqWord;
+ if ($found) break;
+ }
+ if (!$found)
+ {
+ $copy=0; // document contains none of the required words
+ break;
+ }
+ }
+ }
+ if (sizeof($forbiddenWords)>0)
+ {
+ foreach ($words as $wordInfo)
+ {
+ if (in_array($wordInfo["word"],$forbiddenWords))
+ {
+ $copy=0; // document contains a forbidden word
+ break;
+ }
+ }
+ }
+ if ($copy) $filteredDocs[$key]=$docs[$key];
+ }
+ return $filteredDocs;
+}
+
+function compare_rank($a,$b)
+{
+ if ($a["rank"] == $b["rank"])
+ {
+ return 0;
+ }
+ return ($a["rank"]>$b["rank"]) ? -1 : 1;
+}
+
+function sort_results($docs,&$sorted)
+{
+ $sorted = $docs;
+ usort($sorted,"compare_rank");
+ return $sorted;
+}
+
+function report_results(&$docs)
+{
+ echo "<div class=\"header\">";
+ echo " <div class=\"headertitle\">\n";
+ echo " <h1>".search_results()."</h1>\n";
+ echo " </div>\n";
+ echo "</div>\n";
+ echo "<div class=\"searchresults\">\n";
+ echo "<table cellspacing=\"2\">\n";
+ $numDocs = sizeof($docs);
+ if ($numDocs==0)
+ {
+ echo " <tr>\n";
+ echo " <td colspan=\"2\">".matches_text(0)."</td>\n";
+ echo " </tr>\n";
+ }
+ else
+ {
+ echo " <tr>\n";
+ echo " <td colspan=\"2\">".matches_text($numDocs);
+ echo "\n";
+ echo " </td>\n";
+ echo " </tr>\n";
+ $num=1;
+ foreach ($docs as $doc)
+ {
+ echo " <tr>\n";
+ echo " <td align=\"right\">$num.</td>";
+ echo "<td><a class=\"el\" href=\"".$doc["url"]."\">".$doc["name"]."</a></td>\n";
+ echo " <tr>\n";
+ echo " <td></td><td class=\"tiny\">".report_matches()." ";
+ foreach ($doc["words"] as $wordInfo)
+ {
+ $word = $wordInfo["word"];
+ $matchRight = substr($wordInfo["match"],strlen($word));
+ echo "<b>$word</b>$matchRight(".$wordInfo["freq"].") ";
+ }
+ echo " </td>\n";
+ echo " </tr>\n";
+ $num++;
+ }
+ }
+ echo "</table>\n";
+ echo "</div>\n";
+}
+
+function run_query($query)
+{
+ if(strcmp('4.1.0', phpversion()) > 0)
+ {
+ die("Error: PHP version 4.1.0 or above required!");
+ }
+ if (!($file=fopen("search/search.idx","rb")))
+ {
+ die("Error: Search index file could NOT be opened!");
+ }
+ if (readHeader($file)!="DOXS")
+ {
+ die("Error: Header of index file is invalid!");
+ }
+ $results = array();
+ $requiredWords = array();
+ $forbiddenWords = array();
+ $foundWords = array();
+ $word=strtok($query," ");
+ while ($word) // for each word in the search query
+ {
+ if (($word{0}=='+')) { $word=substr($word,1); $requiredWords[]=$word; }
+ if (($word{0}=='-')) { $word=substr($word,1); $forbiddenWords[]=$word; }
+ if (!in_array($word,$foundWords))
+ {
+ $foundWords[]=$word;
+ search($file,strtolower($word),$results);
+ }
+ $word=strtok(" ");
+ }
+ fclose($file);
+ $docs = array();
+ combine_results($results,$docs);
+ // filter out documents with forbidden word or that do not contain
+ // required words
+ $filteredDocs = filter_results($docs,$requiredWords,$forbiddenWords);
+ // sort the results based on rank
+ $sorted = array();
+ sort_results($filteredDocs,$sorted);
+ return $sorted;
+}
+
+function main()
+{
+ $query = "";
+ if (array_key_exists("query", $_GET))
+ {
+ $query=$_GET["query"];
+ }
+ $sorted = run_query($query);
+ // Now output the HTML stuff...
+ // End the HTML form
+ end_form(preg_replace("/[^a-zA-Z0-9\-\_\.\x80-\xFF]/i", " ", $query ));
+ // report results to the user
+ report_results($sorted);
+ end_page();
+}
+</script>
diff --git a/src/search_opensearch.php b/src/search_opensearch.php
new file mode 100644
index 0000000..3b59516
--- /dev/null
+++ b/src/search_opensearch.php
@@ -0,0 +1,127 @@
+<script language="PHP">
+require "search-functions.php";
+
+$mode = array_key_exists('v', $_GET)?$_GET['v']:"";
+$query = array_key_exists('query', $_GET)?$_GET['query']:"";
+
+$query_results = run_query($query);
+
+switch ($mode)
+{
+ case "opensearch.xml":
+ opensearch_description();
+ break;
+ case "json":
+ opensearch_json_results($query, $query_results);
+ break;
+ case "xml":
+ opensearch_xml_results($query, $query_results);
+ break;
+ default:
+ invalid_format($query, $query_results);
+ break;
+}
+
+function opensearch_description()
+{
+ global $config;
+ global $translator;
+
+ $shortname = $translator['search']." ".$config['PROJECT_NAME'];
+ $link = "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['SCRIPT_NAME']);
+ header("Content-Type: application/xml");
+ echo <<<END_OPENSEARCH
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+<ShortName>$shortname</ShortName>
+<Description>Doxygen Search</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<!--
+<Image height="16" width="16" type="image/x-icon">
+http://dev.squello.com/doc/html/favicon.ico</Image>
+-->
+<Url type="text/html" method="GET"
+template="$link/search.php?query={searchTerms}" />
+<Url type="application/x-suggestions+json" method="GET"
+template="$link/search-opensearch.php?v=json&query={searchTerms}" />
+<Url type="application/x-suggestions+xml" method="GET"
+template="$link/search-opensearch.php?v=xml&query={searchTerms}" />
+</OpenSearchDescription>
+END_OPENSEARCH;
+}
+
+function opensearch_xml_results($query, array $results)
+{
+ // Much as I hate copy'n'paste code re-use, this is for testing;
+ // I expect a richer version to come soon.
+ // Although I hate that IE does this richer than FF more...
+ $qs_results = array();
+ foreach ($results as $i => $val)
+ {
+ foreach ($val['words'] as $j => $word)
+ {
+ if (array_key_exists($word, $qs_results))
+ $qs_results[$word['match']]++;
+ else
+ $qs_results[$word['match']] = 1;
+ }
+ }
+ $result = <<<END_FRAG
+<?xml version="1.0"?>
+<SearchSuggestion xmlns="http://schemas.microsoft.com/Search/2008/suggestions">
+<Query>$query</Query>
+<Section>
+END_FRAG;
+ foreach ($qs_results as $word => $count)
+ {
+ $result .= <<<END_FRAG
+<Item>
+<Text>$word</Text>
+<Description>$count results</Description>
+</Item>
+END_FRAG;
+ }
+ $result .= <<<END_FRAG
+</Section>
+</SearchSuggestion>
+END_FRAG;
+ echo $result;
+}
+
+function opensearch_json_results($query, array $results)
+{
+ $qs_results = array();
+ foreach ($results as $i => $val)
+ {
+ foreach ($val['words'] as $j => $word)
+ {
+ if (array_key_exists($word, $qs_results))
+ $qs_results[$word['match']]++;
+ else
+ $qs_results[$word['match']] = 1;
+ }
+ }
+ $result = '["'.$query.'", [';
+ $json_words = "";
+ $json_descriptions = "";
+ $i = 0;
+ foreach ($qs_results as $word => $count)
+ {
+ if ($i != 0)
+ {
+ $json_words .= ", ";
+ $json_descriptions .= ", ";
+ }
+ $json_words .= '"'.$word.'"';
+ $json_descriptions .= '"'.$count.' result'.($count==1?'':'s').'"';
+ $i++;
+ }
+ print "[\"$query\", [$json_words],[$json_descriptions]]";
+}
+
+function invalid_format($query, array $results)
+{
+ print "Search results for '$query':\n\n";
+ print_r($results);
+}
+</script>
diff --git a/src/searchindex.cpp b/src/searchindex.cpp
new file mode 100644
index 0000000..a550eb1
--- /dev/null
+++ b/src/searchindex.cpp
@@ -0,0 +1,1391 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <ctype.h>
+#include <assert.h>
+
+#include <qfile.h>
+#include <qregexp.h>
+
+#include "searchindex.h"
+#include "config.h"
+#include "util.h"
+#include "doxygen.h"
+#include "language.h"
+#include "pagedef.h"
+#include "growbuf.h"
+#include "message.h"
+#include "version.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "memberdef.h"
+#include "filename.h"
+#include "membername.h"
+
+// file format: (all multi-byte values are stored in big endian format)
+// 4 byte header
+// 256*256*4 byte index (4 bytes)
+// for each index entry: a zero terminated list of words
+// for each word: a \0 terminated string + 4 byte offset to the stats info
+// padding bytes to align at 4 byte boundary
+// for each word: the number of urls (4 bytes)
+// + for each url containing the word 8 bytes statistics
+// (4 bytes index to url string + 4 bytes frequency counter)
+// for each url: a \0 terminated string
+
+const int numIndexEntries = 256*256;
+
+//--------------------------------------------------------------------
+
+IndexWord::IndexWord(const char *word) : m_word(word), m_urls(17)
+{
+ m_urls.setAutoDelete(TRUE);
+ //printf("IndexWord::IndexWord(%s)\n",word);
+}
+
+void IndexWord::addUrlIndex(int idx,bool hiPriority)
+{
+ //printf("IndexWord::addUrlIndex(%d,%d)\n",idx,hiPriority);
+ URLInfo *ui = m_urls.find(idx);
+ if (ui==0)
+ {
+ //printf("URLInfo::URLInfo(%d)\n",idx);
+ ui=new URLInfo(idx,0);
+ m_urls.insert(idx,ui);
+ }
+ ui->freq+=2;
+ if (hiPriority) ui->freq|=1; // mark as high priority document
+}
+
+//--------------------------------------------------------------------
+
+SearchIndex::SearchIndex() : SearchIndexIntf(Internal),
+ m_words(328829), m_index(numIndexEntries), m_url2IdMap(10007), m_urls(10007), m_urlIndex(-1)
+{
+ int i;
+ m_words.setAutoDelete(TRUE);
+ m_url2IdMap.setAutoDelete(TRUE);
+ m_urls.setAutoDelete(TRUE);
+ m_index.setAutoDelete(TRUE);
+ for (i=0;i<numIndexEntries;i++) m_index.insert(i,new QList<IndexWord>);
+}
+
+void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile)
+{
+ if (ctx==0) return;
+ assert(!isSourceFile || ctx->definitionType()==Definition::TypeFile);
+ //printf("SearchIndex::setCurrentDoc(%s,%s,%s)\n",name,baseName,anchor);
+ QCString url=isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase();
+ url+=Config_getString("HTML_FILE_EXTENSION");
+ QCString baseUrl = url;
+ if (anchor) url+=QCString("#")+anchor;
+ if (!isSourceFile) baseUrl=url;
+ QCString name=ctx->qualifiedName();
+ if (ctx->definitionType()==Definition::TypeMember)
+ {
+ MemberDef *md = (MemberDef *)ctx;
+ name.prepend((md->getLanguage()==SrcLangExt_Fortran ?
+ theTranslator->trSubprogram(TRUE,TRUE) :
+ theTranslator->trMember(TRUE,TRUE))+" ");
+ }
+ else // compound type
+ {
+ SrcLangExt lang = ctx->getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ name = substitute(name,"::",sep);
+ }
+ switch (ctx->definitionType())
+ {
+ case Definition::TypePage:
+ {
+ PageDef *pd = (PageDef *)ctx;
+ if (!pd->title().isEmpty())
+ {
+ name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title();
+ }
+ else
+ {
+ name = theTranslator->trPage(TRUE,TRUE)+" "+pd->name();
+ }
+ }
+ break;
+ case Definition::TypeClass:
+ {
+ ClassDef *cd = (ClassDef *)ctx;
+ name.prepend(cd->compoundTypeString()+" ");
+ }
+ break;
+ case Definition::TypeNamespace:
+ {
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
+ {
+ name = theTranslator->trPackage(name);
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ name.prepend(theTranslator->trModule(TRUE,TRUE)+" ");
+ }
+ else
+ {
+ name.prepend(theTranslator->trNamespace(TRUE,TRUE)+" ");
+ }
+ }
+ break;
+ case Definition::TypeGroup:
+ {
+ GroupDef *gd = (GroupDef *)ctx;
+ if (gd->groupTitle())
+ {
+ name = theTranslator->trGroup(TRUE,TRUE)+" "+gd->groupTitle();
+ }
+ else
+ {
+ name.prepend(theTranslator->trGroup(TRUE,TRUE)+" ");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ int *pIndex = m_url2IdMap.find(baseUrl);
+ if (pIndex==0)
+ {
+ ++m_urlIndex;
+ m_url2IdMap.insert(baseUrl,new int(m_urlIndex));
+ m_urls.insert(m_urlIndex,new URL(name,url));
+ }
+ else
+ {
+ m_urls.insert(*pIndex,new URL(name,url));
+ }
+}
+
+static int charsToIndex(const char *word)
+{
+ if (word==0) return -1;
+
+ // Fast string hashing algorithm
+ //register ushort h=0;
+ //const char *k = word;
+ //ushort mask=0xfc00;
+ //while ( *k )
+ //{
+ // h = (h&mask)^(h<<6)^(*k++);
+ //}
+ //return h;
+
+ // Simple hashing that allows for substring searching
+ uint c1=((uchar *)word)[0];
+ if (c1==0) return -1;
+ uint c2=((uchar *)word)[1];
+ if (c2==0) return -1;
+ return c1*256+c2;
+}
+
+void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse)
+{
+ static QRegExp nextPart("[_a-z:][A-Z]");
+ if (word==0 || word[0]=='\0') return;
+ QCString wStr = QCString(word).lower();
+ //printf("SearchIndex::addWord(%s,%d) wStr=%s\n",word,hiPriority,wStr.data());
+ IndexWord *w = m_words[wStr];
+ if (w==0)
+ {
+ int idx=charsToIndex(wStr);
+ //fprintf(stderr,"addWord(%s) at index %d\n",word,idx);
+ if (idx<0) return;
+ w = new IndexWord(wStr);
+ m_index[idx]->append(w);
+ m_words.insert(wStr,w);
+ }
+ w->addUrlIndex(m_urlIndex,hiPriority);
+ int i;
+ bool found=FALSE;
+ if (!recurse) // the first time we check if we can strip the prefix
+ {
+ i=getPrefixIndex(word);
+ if (i>0)
+ {
+ addWord(word+i,hiPriority,TRUE);
+ found=TRUE;
+ }
+ }
+ if (!found) // no prefix stripped
+ {
+ if ((i=nextPart.match(word))>=1)
+ {
+ addWord(word+i+1,hiPriority,TRUE);
+ }
+ }
+}
+
+void SearchIndex::addWord(const char *word,bool hiPriority)
+{
+ addWord(word,hiPriority,FALSE);
+}
+
+static void writeInt(QFile &f,int index)
+{
+ f.putch(((uint)index)>>24);
+ f.putch((((uint)index)>>16)&0xff);
+ f.putch((((uint)index)>>8)&0xff);
+ f.putch(((uint)index)&0xff);
+}
+
+static void writeString(QFile &f,const char *s)
+{
+ const char *p = s;
+ while (*p) f.putch(*p++);
+ f.putch(0);
+}
+
+void SearchIndex::write(const char *fileName)
+{
+ int i;
+ int size=4; // for the header
+ size+=4*numIndexEntries; // for the index
+ int wordsOffset = size;
+ // first pass: compute the size of the wordlist
+ for (i=0;i<numIndexEntries;i++)
+ {
+ QList<IndexWord> *wlist = m_index[i];
+ if (!wlist->isEmpty())
+ {
+ QListIterator<IndexWord> iwi(*wlist);
+ IndexWord *iw;
+ for (iwi.toFirst();(iw=iwi.current());++iwi)
+ {
+ int ws = iw->word().length()+1;
+ size+=ws+4; // word + url info list offset
+ }
+ size+=1; // zero list terminator
+ }
+ }
+
+ // second pass: compute the offsets in the index
+ int indexOffsets[numIndexEntries];
+ int offset=wordsOffset;
+ for (i=0;i<numIndexEntries;i++)
+ {
+ QList<IndexWord> *wlist = m_index[i];
+ if (!wlist->isEmpty())
+ {
+ indexOffsets[i]=offset;
+ QListIterator<IndexWord> iwi(*wlist);
+ IndexWord *iw;
+ for (iwi.toFirst();(iw=iwi.current());++iwi)
+ {
+ offset+= iw->word().length()+1;
+ offset+=4; // word + offset to url info array
+ }
+ offset+=1; // zero list terminator
+ }
+ else
+ {
+ indexOffsets[i]=0;
+ }
+ }
+ int padding = size;
+ size = (size+3)&~3; // round up to 4 byte boundary
+ padding = size - padding;
+
+ //int statsOffset = size;
+ QDictIterator<IndexWord> wdi(m_words);
+ //IndexWord *iw;
+ int *wordStatOffsets = new int[m_words.count()];
+
+ int count=0;
+
+ // third pass: compute offset to stats info for each word
+ for (i=0;i<numIndexEntries;i++)
+ {
+ QList<IndexWord> *wlist = m_index[i];
+ if (!wlist->isEmpty())
+ {
+ QListIterator<IndexWord> iwi(*wlist);
+ IndexWord *iw;
+ for (iwi.toFirst();(iw=iwi.current());++iwi)
+ {
+ //printf("wordStatOffsets[%d]=%d\n",count,size);
+ wordStatOffsets[count++] = size;
+ size+=4+iw->urls().count()*8; // count + (url_index,freq) per url
+ }
+ }
+ }
+ int *urlOffsets = new int[m_urls.count()];
+ //int urlsOffset = size;
+ QIntDictIterator<URL> udi(m_urls);
+ URL *url;
+ for (udi.toFirst();(url=udi.current());++udi)
+ {
+ urlOffsets[udi.currentKey()]=size;
+ size+=url->name.length()+1+
+ url->url.length()+1;
+ }
+ //printf("Total size %x bytes (word=%x stats=%x urls=%x)\n",size,wordsOffset,statsOffset,urlsOffset);
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ // write header
+ f.putch('D'); f.putch('O'); f.putch('X'); f.putch('S');
+ // write index
+ for (i=0;i<numIndexEntries;i++)
+ {
+ writeInt(f,indexOffsets[i]);
+ }
+ // write word lists
+ count=0;
+ for (i=0;i<numIndexEntries;i++)
+ {
+ QList<IndexWord> *wlist = m_index[i];
+ if (!wlist->isEmpty())
+ {
+ QListIterator<IndexWord> iwi(*wlist);
+ IndexWord *iw;
+ for (iwi.toFirst();(iw=iwi.current());++iwi)
+ {
+ writeString(f,iw->word());
+ writeInt(f,wordStatOffsets[count++]);
+ }
+ f.putch(0);
+ }
+ }
+ // write extra padding bytes
+ for (i=0;i<padding;i++) f.putch(0);
+ // write word statistics
+ for (i=0;i<numIndexEntries;i++)
+ {
+ QList<IndexWord> *wlist = m_index[i];
+ if (!wlist->isEmpty())
+ {
+ QListIterator<IndexWord> iwi(*wlist);
+ IndexWord *iw;
+ for (iwi.toFirst();(iw=iwi.current());++iwi)
+ {
+ int numUrls = iw->urls().count();
+ writeInt(f,numUrls);
+ QIntDictIterator<URLInfo> uli(iw->urls());
+ URLInfo *ui;
+ for (uli.toFirst();(ui=uli.current());++uli)
+ {
+ writeInt(f,urlOffsets[ui->urlIdx]);
+ writeInt(f,ui->freq);
+ }
+ }
+ }
+ }
+ // write urls
+ QIntDictIterator<URL> udi(m_urls);
+ URL *url;
+ for (udi.toFirst();(url=udi.current());++udi)
+ {
+ writeString(f,url->name);
+ writeString(f,url->url);
+ }
+ }
+
+ delete[] urlOffsets;
+ delete[] wordStatOffsets;
+}
+
+
+//---------------------------------------------------------------------------
+// the following part is for writing an external search index
+
+struct SearchDocEntry
+{
+ QCString type;
+ QCString name;
+ QCString args;
+ QCString extId;
+ QCString url;
+ GrowBuf importantText;
+ GrowBuf normalText;
+};
+
+struct SearchIndexExternal::Private
+{
+ Private() : docEntries(12251) {}
+ SDict<SearchDocEntry> docEntries;
+ SearchDocEntry *current;
+};
+
+SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External)
+{
+ p = new SearchIndexExternal::Private;
+ p->docEntries.setAutoDelete(TRUE);
+ p->current=0;
+}
+
+SearchIndexExternal::~SearchIndexExternal()
+{
+ //printf("p->docEntries.count()=%d\n",p->docEntries.count());
+ delete p;
+}
+
+static QCString definitionToName(Definition *ctx)
+{
+ if (ctx->definitionType()==Definition::TypeMember)
+ {
+ MemberDef *md = (MemberDef*)ctx;
+ if (md->isFunction())
+ return "function";
+ else if (md->isSlot())
+ return "slot";
+ else if (md->isSignal())
+ return "signal";
+ else if (md->isVariable())
+ return "variable";
+ else if (md->isTypedef())
+ return "typedef";
+ else if (md->isEnumerate())
+ return "enum";
+ else if (md->isEnumValue())
+ return "enumvalue";
+ else if (md->isProperty())
+ return "property";
+ else if (md->isEvent())
+ return "event";
+ else if (md->isRelated() || md->isForeign())
+ return "related";
+ else if (md->isFriend())
+ return "friend";
+ else if (md->isDefine())
+ return "define";
+ }
+ else if (ctx)
+ {
+ switch(ctx->definitionType())
+ {
+ case Definition::TypeClass:
+ return ((ClassDef*)ctx)->compoundTypeString();
+ case Definition::TypeFile:
+ return "file";
+ case Definition::TypeNamespace:
+ return "namespace";
+ case Definition::TypeGroup:
+ return "group";
+ case Definition::TypePackage:
+ return "package";
+ case Definition::TypePage:
+ return "page";
+ case Definition::TypeDir:
+ return "dir";
+ default:
+ break;
+ }
+ }
+ return "unknown";
+}
+
+void SearchIndexExternal::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile)
+{
+ QCString extId = stripPath(Config_getString("EXTERNAL_SEARCH_ID"));
+ QCString baseName = isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase();
+ QCString url = baseName + Doxygen::htmlFileExtension;
+ if (anchor) url+=QCString("#")+anchor;
+ QCString key = extId+";"+url;
+
+ p->current = p->docEntries.find(key);
+ //printf("setCurrentDoc(url=%s,isSourceFile=%d) current=%p\n",url.data(),isSourceFile,p->current);
+ if (!p->current)
+ {
+ SearchDocEntry *e = new SearchDocEntry;
+ e->type = isSourceFile ? QCString("source") : definitionToName(ctx);
+ e->name = ctx->qualifiedName();
+ if (ctx->definitionType()==Definition::TypeMember)
+ {
+ e->args = ((MemberDef*)ctx)->argsString();
+ }
+ e->extId = extId;
+ e->url = url;
+ p->current = e;
+ p->docEntries.append(key,e);
+ //printf("searchIndexExt %s : %s\n",e->name.data(),e->url.data());
+ }
+}
+
+void SearchIndexExternal::addWord(const char *word,bool hiPriority)
+{
+ if (word==0 || !isId(*word) || p->current==0) return;
+ GrowBuf *pText = hiPriority ? &p->current->importantText : &p->current->normalText;
+ if (pText->getPos()>0) pText->addChar(' ');
+ pText->addStr(word);
+ //printf("addWord %s\n",word);
+}
+
+void SearchIndexExternal::write(const char *fileName)
+{
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ t << "<add>" << endl;
+ SDict<SearchDocEntry>::Iterator it(p->docEntries);
+ SearchDocEntry *doc;
+ for (it.toFirst();(doc=it.current());++it)
+ {
+ doc->normalText.addChar(0); // make sure buffer ends with a 0 terminator
+ doc->importantText.addChar(0); // make sure buffer ends with a 0 terminator
+ t << " <doc>" << endl;
+ t << " <field name=\"type\">" << doc->type << "</field>" << endl;
+ t << " <field name=\"name\">" << convertToXML(doc->name) << "</field>" << endl;
+ if (!doc->args.isEmpty())
+ {
+ t << " <field name=\"args\">" << convertToXML(doc->args) << "</field>" << endl;
+ }
+ if (!doc->extId.isEmpty())
+ {
+ t << " <field name=\"tag\">" << convertToXML(doc->extId) << "</field>" << endl;
+ }
+ t << " <field name=\"url\">" << convertToXML(doc->url) << "</field>" << endl;
+ t << " <field name=\"keywords\">" << convertToXML(doc->importantText.get()) << "</field>" << endl;
+ t << " <field name=\"text\">" << convertToXML(doc->normalText.get()) << "</field>" << endl;
+ t << " </doc>" << endl;
+ }
+ t << "</add>" << endl;
+ }
+ else
+ {
+ err("Failed to open file %s for writing!\n",fileName);
+ }
+}
+
+//---------------------------------------------------------------------------
+// the following part is for the javascript based search engine
+
+#include "memberdef.h"
+#include "namespacedef.h"
+#include "pagedef.h"
+#include "classdef.h"
+#include "filedef.h"
+#include "language.h"
+#include "doxygen.h"
+#include "message.h"
+
+static const char search_script[]=
+#include "search.js.h"
+;
+
+#define SEARCH_INDEX_ALL 0
+#define SEARCH_INDEX_CLASSES 1
+#define SEARCH_INDEX_NAMESPACES 2
+#define SEARCH_INDEX_FILES 3
+#define SEARCH_INDEX_FUNCTIONS 4
+#define SEARCH_INDEX_VARIABLES 5
+#define SEARCH_INDEX_TYPEDEFS 6
+#define SEARCH_INDEX_ENUMS 7
+#define SEARCH_INDEX_ENUMVALUES 8
+#define SEARCH_INDEX_PROPERTIES 9
+#define SEARCH_INDEX_EVENTS 10
+#define SEARCH_INDEX_RELATED 11
+#define SEARCH_INDEX_DEFINES 12
+#define SEARCH_INDEX_GROUPS 13
+#define SEARCH_INDEX_PAGES 14
+#define NUM_SEARCH_INDICES 15
+
+class SearchDefinitionList : public QList<Definition>
+{
+ public:
+ SearchDefinitionList(uint letter) : m_letter(letter) {}
+ uint letter() const { return m_letter; }
+ private:
+ uint m_letter;
+};
+
+class SearchIndexList : public SDict< SearchDefinitionList >
+{
+ public:
+ typedef Definition ElementType;
+ SearchIndexList(uint letter) : SDict<SearchDefinitionList>(17,FALSE), m_letter(letter)
+ {
+ setAutoDelete(TRUE);
+ }
+ ~SearchIndexList() {}
+ void append(Definition *d)
+ {
+ SearchDefinitionList *l = find(d->name());
+ if (l==0)
+ {
+ l=new SearchDefinitionList(m_letter);
+ SDict<SearchDefinitionList>::append(d->name(),l);
+ }
+ l->append(d);
+ }
+ uint letter() const { return m_letter; }
+ private:
+ int compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const
+ {
+ QCString n1 = md1->getFirst()->localName();
+ QCString n2 = md2->getFirst()->localName();
+ return qstricmp(n1.data(),n2.data());
+ }
+ uint m_letter;
+};
+
+static void addMemberToSearchIndex(
+ LetterToIndexMap<SearchIndexList> symbols[NUM_SEARCH_INDICES],
+ int symbolCount[NUM_SEARCH_INDICES],
+ MemberDef *md)
+{
+ static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
+ bool isLinkable = md->isLinkable();
+ ClassDef *cd=0;
+ NamespaceDef *nd=0;
+ FileDef *fd=0;
+ GroupDef *gd=0;
+ if (isLinkable &&
+ (
+ ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) ||
+ ((gd=md->getGroupDef()) && gd->isLinkable())
+ )
+ )
+ {
+ QCString n = md->name();
+ if (!n.isEmpty())
+ {
+ uint letter = getUtf8CodeToLower(n,0);
+ bool isFriendToHide = hideFriendCompounds &&
+ (QCString(md->typeString())=="friend class" ||
+ QCString(md->typeString())=="friend struct" ||
+ QCString(md->typeString())=="friend union");
+ if (!(md->isFriend() && isFriendToHide))
+ {
+ symbols[SEARCH_INDEX_ALL].append(letter,md);
+ symbolCount[SEARCH_INDEX_ALL]++;
+ }
+ if (md->isFunction() || md->isSlot() || md->isSignal())
+ {
+ symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md);
+ symbolCount[SEARCH_INDEX_FUNCTIONS]++;
+ }
+ else if (md->isVariable())
+ {
+ symbols[SEARCH_INDEX_VARIABLES].append(letter,md);
+ symbolCount[SEARCH_INDEX_VARIABLES]++;
+ }
+ else if (md->isTypedef())
+ {
+ symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md);
+ symbolCount[SEARCH_INDEX_TYPEDEFS]++;
+ }
+ else if (md->isEnumerate())
+ {
+ symbols[SEARCH_INDEX_ENUMS].append(letter,md);
+ symbolCount[SEARCH_INDEX_ENUMS]++;
+ }
+ else if (md->isEnumValue())
+ {
+ symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md);
+ symbolCount[SEARCH_INDEX_ENUMVALUES]++;
+ }
+ else if (md->isProperty())
+ {
+ symbols[SEARCH_INDEX_PROPERTIES].append(letter,md);
+ symbolCount[SEARCH_INDEX_PROPERTIES]++;
+ }
+ else if (md->isEvent())
+ {
+ symbols[SEARCH_INDEX_EVENTS].append(letter,md);
+ symbolCount[SEARCH_INDEX_EVENTS]++;
+ }
+ else if (md->isRelated() || md->isForeign() ||
+ (md->isFriend() && !isFriendToHide))
+ {
+ symbols[SEARCH_INDEX_RELATED].append(letter,md);
+ symbolCount[SEARCH_INDEX_RELATED]++;
+ }
+ }
+ }
+ else if (isLinkable &&
+ (((nd=md->getNamespaceDef()) && nd->isLinkable()) ||
+ ((fd=md->getFileDef()) && fd->isLinkable())
+ )
+ )
+ {
+ QCString n = md->name();
+ if (!n.isEmpty())
+ {
+ uint letter = getUtf8CodeToLower(n,0);
+ symbols[SEARCH_INDEX_ALL].append(letter,md);
+ symbolCount[SEARCH_INDEX_ALL]++;
+
+ if (md->isFunction())
+ {
+ symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md);
+ symbolCount[SEARCH_INDEX_FUNCTIONS]++;
+ }
+ else if (md->isVariable())
+ {
+ symbols[SEARCH_INDEX_VARIABLES].append(letter,md);
+ symbolCount[SEARCH_INDEX_VARIABLES]++;
+ }
+ else if (md->isTypedef())
+ {
+ symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md);
+ symbolCount[SEARCH_INDEX_TYPEDEFS]++;
+ }
+ else if (md->isEnumerate())
+ {
+ symbols[SEARCH_INDEX_ENUMS].append(letter,md);
+ symbolCount[SEARCH_INDEX_ENUMS]++;
+ }
+ else if (md->isEnumValue())
+ {
+ symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md);
+ symbolCount[SEARCH_INDEX_ENUMVALUES]++;
+ }
+ else if (md->isDefine())
+ {
+ symbols[SEARCH_INDEX_DEFINES].append(letter,md);
+ symbolCount[SEARCH_INDEX_DEFINES]++;
+ }
+ }
+ }
+}
+
+// see also function convertToId() in search.js, which should match in
+// behaviour
+static QCString searchId(const QCString &s)
+{
+ int c;
+ uint i;
+ QCString result;
+ for (i=0;i<s.length();i++)
+ {
+ c=s.at(i);
+ if (c>0x7f || c<0) // part of multibyte character
+ {
+ result+=(char)c;
+ }
+ else if (isalnum(c)) // simply alpha numerical character
+ {
+ result+=(char)tolower(c);
+ }
+ else // other 'unprintable' characters
+ {
+ char val[4];
+ sprintf(val,"_%02x",(uchar)c);
+ result+=val;
+ }
+ }
+ return result;
+}
+
+static int g_searchIndexCount[NUM_SEARCH_INDICES];
+static LetterToIndexMap<SearchIndexList> g_searchIndexSymbols[NUM_SEARCH_INDICES];
+static const char *g_searchIndexName[NUM_SEARCH_INDICES] =
+{
+ "all",
+ "classes",
+ "namespaces",
+ "files",
+ "functions",
+ "variables",
+ "typedefs",
+ "enums",
+ "enumvalues",
+ "properties",
+ "events",
+ "related",
+ "defines",
+ "groups",
+ "pages"
+};
+
+
+class SearchIndexCategoryMapping
+{
+ public:
+ SearchIndexCategoryMapping()
+ {
+ categoryLabel[SEARCH_INDEX_ALL] = theTranslator->trAll();
+ categoryLabel[SEARCH_INDEX_CLASSES] = theTranslator->trClasses();
+ categoryLabel[SEARCH_INDEX_NAMESPACES] = theTranslator->trNamespace(TRUE,FALSE);
+ categoryLabel[SEARCH_INDEX_FILES] = theTranslator->trFile(TRUE,FALSE);
+ categoryLabel[SEARCH_INDEX_FUNCTIONS] = theTranslator->trFunctions();
+ categoryLabel[SEARCH_INDEX_VARIABLES] = theTranslator->trVariables();
+ categoryLabel[SEARCH_INDEX_TYPEDEFS] = theTranslator->trTypedefs();
+ categoryLabel[SEARCH_INDEX_ENUMS] = theTranslator->trEnumerations();
+ categoryLabel[SEARCH_INDEX_ENUMVALUES] = theTranslator->trEnumerationValues();
+ categoryLabel[SEARCH_INDEX_PROPERTIES] = theTranslator->trProperties();
+ categoryLabel[SEARCH_INDEX_EVENTS] = theTranslator->trEvents();
+ categoryLabel[SEARCH_INDEX_RELATED] = theTranslator->trFriends();
+ categoryLabel[SEARCH_INDEX_DEFINES] = theTranslator->trDefines();
+ categoryLabel[SEARCH_INDEX_GROUPS] = theTranslator->trGroup(TRUE,FALSE);
+ categoryLabel[SEARCH_INDEX_PAGES] = theTranslator->trPage(TRUE,FALSE);
+ }
+ QCString categoryLabel[NUM_SEARCH_INDICES];
+};
+
+void writeJavascriptSearchIndex()
+{
+ if (!Config_getBool("GENERATE_HTML")) return;
+
+ // index classes
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ uint letter = getUtf8CodeToLower(cd->localName(),0);
+ if (cd->isLinkable() && isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,cd);
+ g_searchIndexSymbols[SEARCH_INDEX_CLASSES].append(letter,cd);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_CLASSES]++;
+ }
+ }
+
+ // index namespaces
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (;(nd=nli.current());++nli)
+ {
+ uint letter = getUtf8CodeToLower(nd->name(),0);
+ if (nd->isLinkable() && isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,nd);
+ g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES].append(letter,nd);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++;
+ }
+ }
+
+ // index files
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ uint letter = getUtf8CodeToLower(fd->name(),0);
+ if (fd->isLinkable() && isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,fd);
+ g_searchIndexSymbols[SEARCH_INDEX_FILES].append(letter,fd);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_FILES]++;
+ }
+ }
+ }
+
+ // index class members
+ {
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ MemberName *mn;
+ // for each member name
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md);
+ }
+ }
+ }
+
+ // index file/namespace members
+ {
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ MemberName *mn;
+ // for each member name
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md);
+ }
+ }
+ }
+
+ // index groups
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (gd->isLinkable())
+ {
+ QCString title = gd->groupTitle();
+ if (!title.isEmpty()) // TODO: able searching for all word in the title
+ {
+ uchar charCode = title.at(0);
+ uint letter = charCode<128 ? tolower(charCode) : charCode;
+ if (isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,gd);
+ g_searchIndexSymbols[SEARCH_INDEX_GROUPS].append(letter,gd);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_GROUPS]++;
+ }
+ }
+ }
+ }
+
+ // index pages
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ if (pd->isLinkable())
+ {
+ QCString title = pd->title();
+ if (!title.isEmpty())
+ {
+ uchar charCode = title.at(0);
+ uint letter = charCode<128 ? tolower(charCode) : charCode;
+ if (isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,pd);
+ g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,pd);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_PAGES]++;
+ }
+ }
+ }
+ }
+ if (Doxygen::mainPage)
+ {
+ QCString title = Doxygen::mainPage->title();
+ if (!title.isEmpty())
+ {
+ uchar charCode = title.at(0);
+ uint letter = charCode<128 ? tolower(charCode) : charCode;
+ if (isId(letter))
+ {
+ g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,Doxygen::mainPage);
+ g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,Doxygen::mainPage);
+ g_searchIndexCount[SEARCH_INDEX_ALL]++;
+ g_searchIndexCount[SEARCH_INDEX_PAGES]++;
+ }
+ }
+ }
+
+ // sort all lists
+ int i;
+ for (i=0;i<NUM_SEARCH_INDICES;i++)
+ {
+ SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
+ SearchIndexList *sl;
+ for (it.toFirst();(sl=it.current());++it)
+ {
+ sl->sort();
+ }
+ }
+
+ // write index files
+ QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
+
+ for (i=0;i<NUM_SEARCH_INDICES;i++) // for each index
+ {
+ SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
+ SearchIndexList *sl;
+ int p=0;
+ for (it.toFirst();(sl=it.current());++it,++p) // for each letter
+ {
+ QCString baseName;
+ baseName.sprintf("%s_%x",g_searchIndexName[i],p);
+
+ QCString fileName = searchDirName + "/"+baseName+".html";
+ QCString dataFileName = searchDirName + "/"+baseName+".js";
+
+ QFile outFile(fileName);
+ QFile dataOutFile(dataFileName);
+ if (outFile.open(IO_WriteOnly) && dataOutFile.open(IO_WriteOnly))
+ {
+ {
+ FTextStream t(&outFile);
+
+ t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\""
+ " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
+ t << "<html><head><title></title>" << endl;
+ t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
+ t << "<meta name=\"generator\" content=\"Doxygen " << versionString << "\"/>" << endl;
+ t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
+ t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>" << endl;
+ t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
+ t << "</head>" << endl;
+ t << "<body class=\"SRPage\">" << endl;
+ t << "<div id=\"SRIndex\">" << endl;
+ t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>" << endl;
+ t << "<div id=\"SRResults\"></div>" << endl; // here the results will be inserted
+ t << "<script type=\"text/javascript\"><!--" << endl;
+ t << "createResults();" << endl; // this function will insert the results
+ t << "--></script>" << endl;
+ t << "<div class=\"SRStatus\" id=\"Searching\">"
+ << theTranslator->trSearching() << "</div>" << endl;
+ t << "<div class=\"SRStatus\" id=\"NoMatches\">"
+ << theTranslator->trNoMatches() << "</div>" << endl;
+
+ t << "<script type=\"text/javascript\"><!--" << endl;
+ t << "document.getElementById(\"Loading\").style.display=\"none\";" << endl;
+ t << "document.getElementById(\"NoMatches\").style.display=\"none\";" << endl;
+ t << "var searchResults = new SearchResults(\"searchResults\");" << endl;
+ t << "searchResults.Search();" << endl;
+ t << "--></script>" << endl;
+ t << "</div>" << endl; // SRIndex
+ t << "</body>" << endl;
+ t << "</html>" << endl;
+ }
+ FTextStream ti(&dataOutFile);
+
+ ti << "var searchData=" << endl;
+ // format
+ // searchData[] = array of items
+ // searchData[x][0] = id
+ // searchData[x][1] = [ name + child1 + child2 + .. ]
+ // searchData[x][1][0] = name as shown
+ // searchData[x][1][y+1] = info for child y
+ // searchData[x][1][y+1][0] = url
+ // searchData[x][1][y+1][1] = 1 => target="_parent"
+ // searchData[x][1][y+1][2] = scope
+
+ ti << "[" << endl;
+ bool firstEntry=TRUE;
+
+ SDict<SearchDefinitionList>::Iterator li(*sl);
+ SearchDefinitionList *dl;
+ int itemCount=0;
+ for (li.toFirst();(dl=li.current());++li)
+ {
+ Definition *d = dl->getFirst();
+ QCString id = d->localName();
+
+ if (!firstEntry)
+ {
+ ti << "," << endl;
+ }
+ firstEntry=FALSE;
+
+ QCString dispName = d->localName();
+ if (d->definitionType()==Definition::TypeGroup)
+ {
+ dispName = ((GroupDef*)d)->groupTitle();
+ }
+ else if (d->definitionType()==Definition::TypePage)
+ {
+ dispName = ((PageDef*)d)->title();
+ }
+ ti << " ['" << searchId(dispName) << "',['"
+ << convertToXML(dispName) << "',[";
+
+ if (dl->count()==1) // item with a unique name
+ {
+ MemberDef *md = 0;
+ bool isMemberDef = d->definitionType()==Definition::TypeMember;
+ if (isMemberDef) md = (MemberDef*)d;
+ QCString anchor = d->anchor();
+
+ ti << "'" << externalRef("../",d->getReference(),TRUE)
+ << d->getOutputFileBase() << Doxygen::htmlFileExtension;
+ if (!anchor.isEmpty())
+ {
+ ti << "#" << anchor;
+ }
+ ti << "',";
+
+ static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW");
+ if (!extLinksInWindow || d->getReference().isEmpty())
+ {
+ ti << "1,";
+ }
+ else
+ {
+ ti << "0,";
+ }
+
+ if (d->getOuterScope()!=Doxygen::globalScope)
+ {
+ ti << "'" << convertToXML(d->getOuterScope()->name()) << "'";
+ }
+ else if (md)
+ {
+ FileDef *fd = md->getBodyDef();
+ if (fd==0) fd = md->getFileDef();
+ if (fd)
+ {
+ ti << "'" << convertToXML(fd->localName()) << "'";
+ }
+ }
+ else
+ {
+ ti << "''";
+ }
+ ti << "]]";
+ }
+ else // multiple items with the same name
+ {
+ QListIterator<Definition> di(*dl);
+ bool overloadedFunction = FALSE;
+ Definition *prevScope = 0;
+ int childCount=0;
+ for (di.toFirst();(d=di.current());)
+ {
+ ++di;
+ Definition *scope = d->getOuterScope();
+ Definition *next = di.current();
+ Definition *nextScope = 0;
+ MemberDef *md = 0;
+ bool isMemberDef = d->definitionType()==Definition::TypeMember;
+ if (isMemberDef) md = (MemberDef*)d;
+ if (next) nextScope = next->getOuterScope();
+ QCString anchor = d->anchor();
+
+ if (childCount>0)
+ {
+ ti << "],[";
+ }
+ ti << "'" << externalRef("../",d->getReference(),TRUE)
+ << d->getOutputFileBase() << Doxygen::htmlFileExtension;
+ if (!anchor.isEmpty())
+ {
+ ti << "#" << anchor;
+ }
+ ti << "',";
+
+ static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW");
+ if (!extLinksInWindow || d->getReference().isEmpty())
+ {
+ ti << "1,";
+ }
+ else
+ {
+ ti << "0,";
+ }
+ bool found=FALSE;
+ overloadedFunction = ((prevScope!=0 && scope==prevScope) ||
+ (scope && scope==nextScope)
+ ) && md &&
+ (md->isFunction() || md->isSlot());
+ QCString prefix;
+ if (md) prefix=convertToXML(md->localName());
+ if (overloadedFunction) // overloaded member function
+ {
+ prefix+=convertToXML(md->argsString());
+ // show argument list to disambiguate overloaded functions
+ }
+ else if (md) // unique member function
+ {
+ prefix+="()"; // only to show it is a function
+ }
+ QCString name;
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ name = convertToXML(((ClassDef*)d)->displayName());
+ found = TRUE;
+ }
+ else if (d->definitionType()==Definition::TypeNamespace)
+ {
+ name = convertToXML(((NamespaceDef*)d)->displayName());
+ found = TRUE;
+ }
+ else if (scope==0 || scope==Doxygen::globalScope) // in global scope
+ {
+ if (md)
+ {
+ FileDef *fd = md->getBodyDef();
+ if (fd==0) fd = md->getFileDef();
+ if (fd)
+ {
+ if (!prefix.isEmpty()) prefix+=": ";
+ name = prefix + convertToXML(fd->localName());
+ found = TRUE;
+ }
+ }
+ }
+ else if (md && (md->getClassDef() || md->getNamespaceDef()))
+ // member in class or namespace scope
+ {
+ SrcLangExt lang = md->getLanguage();
+ name = convertToXML(d->getOuterScope()->qualifiedName())
+ + getLanguageSpecificSeparator(lang) + prefix;
+ found = TRUE;
+ }
+ else if (scope) // some thing else? -> show scope
+ {
+ name = prefix + convertToXML(scope->name());
+ found = TRUE;
+ }
+ if (!found) // fallback
+ {
+ name = prefix + "("+theTranslator->trGlobalNamespace()+")";
+ }
+
+ ti << "'" << name << "'";
+
+ prevScope = scope;
+ childCount++;
+ }
+
+ ti << "]]";
+ }
+ ti << "]";
+ itemCount++;
+ }
+ if (!firstEntry)
+ {
+ ti << endl;
+ }
+
+ ti << "];" << endl;
+
+ }
+ else
+ {
+ err("Failed to open file '%s' for writing...\n",fileName.data());
+ }
+ }
+ }
+
+ {
+ QFile f(searchDirName+"/search.js");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << "// Search script generated by doxygen" << endl;
+ t << "// Copyright (C) 2009 by Dimitri van Heesch." << endl << endl;
+ t << "// The code in this file is loosly based on main.js, part of Natural Docs," << endl;
+ t << "// which is Copyright (C) 2003-2008 Greg Valure" << endl;
+ t << "// Natural Docs is licensed under the GPL." << endl << endl;
+ t << "var indexSectionsWithContent =" << endl;
+ t << "{" << endl;
+ bool first=TRUE;
+ int j=0;
+ for (i=0;i<NUM_SEARCH_INDICES;i++)
+ {
+ if (g_searchIndexCount[i]>0)
+ {
+ if (!first) t << "," << endl;
+ t << " " << j << ": \"";
+
+ SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
+ SearchIndexList *sl;
+ for (it.toFirst();(sl=it.current());++it) // for each letter
+ {
+ t << QString( QChar( sl->letter() ) ).utf8();
+ }
+ t << "\"";
+ first=FALSE;
+ j++;
+ }
+ }
+ if (!first) t << "\n";
+ t << "};" << endl << endl;
+ t << "var indexSectionNames =" << endl;
+ t << "{" << endl;
+ first=TRUE;
+ j=0;
+ for (i=0;i<NUM_SEARCH_INDICES;i++)
+ {
+ if (g_searchIndexCount[i]>0)
+ {
+ if (!first) t << "," << endl;
+ t << " " << j << ": \"" << g_searchIndexName[i] << "\"";
+ first=FALSE;
+ j++;
+ }
+ }
+ if (!first) t << "\n";
+ t << "};" << endl << endl;
+ t << search_script;
+ }
+ }
+ {
+ QFile f(searchDirName+"/nomatches.html");
+ if (f.open(IO_WriteOnly))
+ {
+ FTextStream t(&f);
+ t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
+ "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
+ t << "<html><head><title></title>" << endl;
+ t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
+ t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
+ t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
+ t << "</head>" << endl;
+ t << "<body class=\"SRPage\">" << endl;
+ t << "<div id=\"SRIndex\">" << endl;
+ t << "<div class=\"SRStatus\" id=\"NoMatches\">"
+ << theTranslator->trNoMatches() << "</div>" << endl;
+ t << "</div>" << endl;
+ t << "</body>" << endl;
+ t << "</html>" << endl;
+ }
+ }
+ Doxygen::indexList->addStyleSheetFile("search/search.js");
+}
+
+void writeSearchCategories(FTextStream &t)
+{
+ static SearchIndexCategoryMapping map;
+ int i,j=0;
+ for (i=0;i<NUM_SEARCH_INDICES;i++)
+ {
+ if (g_searchIndexCount[i]>0)
+ {
+ t << "<a class=\"SelectItem\" href=\"javascript:void(0)\" "
+ << "onclick=\"searchBox.OnSelectItem(" << j << ")\">"
+ << "<span class=\"SelectionMark\"> </span>"
+ << convertToXML(map.categoryLabel[i])
+ << "</a>";
+ j++;
+ }
+ }
+}
+
+//---------------------------------------------------------------------------------------------
+
+void initSearchIndexer()
+{
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
+ static bool externalSearch = Config_getBool("EXTERNAL_SEARCH");
+ if (searchEngine && serverBasedSearch)
+ {
+ if (externalSearch) // external tools produce search index and engine
+ {
+ Doxygen::searchIndex = new SearchIndexExternal;
+ }
+ else // doxygen produces search index and engine
+ {
+ Doxygen::searchIndex = new SearchIndex;
+ }
+ }
+ else // no search engine or pure javascript based search function
+ {
+ Doxygen::searchIndex = 0;
+ }
+}
+
+void finializeSearchIndexer()
+{
+ delete Doxygen::searchIndex;
+}
+
+
diff --git a/src/searchindex.h b/src/searchindex.h
new file mode 100644
index 0000000..872c0d3
--- /dev/null
+++ b/src/searchindex.h
@@ -0,0 +1,115 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _SEARCHINDEX_H
+#define _SEARCHINDEX_H
+
+#include <qintdict.h>
+#include <qlist.h>
+#include <qdict.h>
+#include <qintdict.h>
+#include <qvector.h>
+
+class FTextStream;
+class Definition;
+class MemberDef;
+
+/*! Initialize the search indexer */
+void initSearchIndexer();
+/*! Cleanup the search indexer */
+void finializeSearchIndexer();
+
+//------- server side search index ----------------------
+
+struct URL
+{
+ URL(const char *n,const char *u) : name(n), url(u) {}
+ QCString name;
+ QCString url;
+};
+
+
+struct URLInfo
+{
+ URLInfo(int idx,int f) : urlIdx(idx), freq(f) {}
+ int urlIdx;
+ int freq;
+};
+
+class IndexWord
+{
+ public:
+ IndexWord(const char *word);
+ void addUrlIndex(int,bool);
+ const QIntDict<URLInfo> &urls() const { return m_urls; }
+ QCString word() const { return m_word; }
+
+ private:
+ QCString m_word;
+ QIntDict<URLInfo> m_urls;
+};
+
+class SearchIndexIntf
+{
+ public:
+ enum Kind { Internal, External };
+ SearchIndexIntf(Kind k) : m_kind(k) {}
+ virtual ~SearchIndexIntf() {}
+ virtual void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile) = 0;
+ virtual void addWord(const char *word,bool hiPriority) = 0;
+ virtual void write(const char *file) = 0;
+ Kind kind() const { return m_kind; }
+ private:
+ Kind m_kind;
+};
+
+class SearchIndex : public SearchIndexIntf
+{
+ public:
+ SearchIndex();
+ void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile);
+ void addWord(const char *word,bool hiPriority);
+ void write(const char *file);
+ private:
+ void addWord(const char *word,bool hiPrio,bool recurse);
+ QDict<IndexWord> m_words;
+ QVector< QList<IndexWord> > m_index;
+ QDict<int> m_url2IdMap;
+ QIntDict<URL> m_urls;
+ int m_urlIndex;
+};
+
+
+class SearchIndexExternal : public SearchIndexIntf
+{
+ struct Private;
+ public:
+ SearchIndexExternal();
+ ~SearchIndexExternal();
+ void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile);
+ void addWord(const char *word,bool hiPriority);
+ void write(const char *file);
+ private:
+ Private *p;
+};
+
+//------- client side search index ----------------------
+
+void writeJavascriptSearchIndex();
+void writeSearchCategories(FTextStream &t);
+
+#endif
diff --git a/src/section.h b/src/section.h
new file mode 100644
index 0000000..a1f859e
--- /dev/null
+++ b/src/section.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SECTION_H
+#define SECTION_H
+
+#include "sortdict.h"
+
+class Definition;
+
+/** Class representing a section in a page */
+struct SectionInfo
+{
+ enum SectionType { Page = 0,
+ Section = 1,
+ Subsection = 2,
+ Subsubsection = 3,
+ Paragraph = 4,
+ Anchor = 5
+ };
+ SectionInfo(const char *f,const int lin,const char *l,const char *t,
+ SectionType st,int lev,const char *r=0) :
+ label(l), title(t), type(st), ref(r), definition(0),
+ fileName(f), lineNr(lin), generated(FALSE), level(lev)
+ {
+ }
+ SectionInfo(const SectionInfo &s)
+ {
+ label=s.label.copy();
+ title=s.title.copy();
+ type =s.type;
+ ref=s.ref.copy();
+ definition=s.definition;
+ fileName=s.fileName.copy();
+ lineNr=s.lineNr;
+ generated=s.generated;
+ level=s.level;
+ }
+ ~SectionInfo() {}
+ QCString label;
+ QCString title;
+ SectionType type;
+ QCString ref;
+ Definition *definition;
+ QCString fileName;
+ int lineNr;
+ bool generated;
+ int level;
+};
+
+/** Unsorted dictionary of SectionInfo objects. */
+class SectionDict : public SDict<SectionInfo>
+{
+ public:
+ SectionDict(int size) : SDict<SectionInfo>(size) {}
+ ~SectionDict() {}
+};
+
+#endif
diff --git a/src/settings.py b/src/settings.py
new file mode 100755
index 0000000..a9dfa13
--- /dev/null
+++ b/src/settings.py
@@ -0,0 +1,29 @@
+#
+
+import sys
+import os
+
+f_sqlite3 = sys.argv[1]
+f_libclang = sys.argv[2]
+
+f1 = open(os.path.join(sys.argv[3],'settings.h'),'w')
+f1.write("#ifndef SETTINGS_H\n")
+f1.write("#define SETTINGS_H\n")
+f1.write("\n")
+if (f_sqlite3 != "NO"):
+ f1.write("#define USE_SQLITE3 1\n")
+else:
+ f1.write("#define USE_SQLITE3 0\n")
+
+if (f_libclang != "NO"):
+ f1.write("#define USE_LIBCLANG 1\n")
+else:
+ f1.write("#define USE_LIBCLANG 0\n")
+
+f1.write("\n")
+f1.write("#define IS_SUPPORTED(x) \\\n")
+f1.write(" ((USE_SQLITE3 && strcmp(\"USE_SQLITE3\",(x))==0) || \\\n")
+f1.write(" (USE_LIBCLANG && strcmp(\"USE_LIBCLANG\",(x))==0) || \\\n")
+f1.write(" 0)\n")
+f1.write("\n")
+f1.write("#endif\n")
diff --git a/src/sortdict.h b/src/sortdict.h
new file mode 100644
index 0000000..f79a335
--- /dev/null
+++ b/src/sortdict.h
@@ -0,0 +1,734 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _SORTDICT_H
+#define _SORTDICT_H
+
+#include <qlist.h>
+#include <qdict.h>
+#include <qintdict.h>
+
+#define AUTORESIZE 1
+
+#if AUTORESIZE
+const uint SDict_primes[] =
+{
+ 17,
+ 29,
+ 47,
+ 71,
+ 113,
+ 179,
+ 293,
+ 457,
+ 733,
+ 1171,
+ 1871,
+ 2999,
+ 4787,
+ 7669,
+ 12251,
+ 19603,
+ 31379,
+ 50177,
+ 80287,
+ 128449,
+ 205519,
+ 328829,
+ 526139,
+ 841801,
+ 1346881,
+ 2155007,
+ 3448033,
+ 5516827,
+ 8826919,
+ 14123059,
+ 23538433,
+ 39230771,
+ 65384537,
+ 108974231,
+ 181623707,
+ 302706181,
+ 504510283,
+ 840850487,
+ 0xffffffff
+};
+#endif
+
+template<class T> class SDict;
+template<class T> class SIntDict;
+
+/** internal wrapper class that redirects compareValues() to the
+ * dictionary
+ */
+template<class T>
+class SList : public QList<T>
+{
+ public:
+ SList(SDict<T> *owner) : m_owner(owner) {}
+ virtual ~SList() {}
+ int compareValues(const T *item1,const T *item2) const
+ {
+ return m_owner->compareValues(item1,item2);
+ }
+ private:
+ SDict<T> *m_owner;
+};
+
+/** Ordered dictionary of elements of type T.
+ * Internally uses a QList<T> and a QDict<T>.
+ */
+template<class T>
+class SDict
+{
+ private:
+ SList<T> *m_list;
+ QDict<T> *m_dict;
+ int m_sizeIndex;
+
+ public:
+ /*! Create an ordered dictionary.
+ * \param size The size of the dictionary. Should be a prime number for
+ * best distribution of elements.
+ * \param caseSensitive indicated whether the keys should be sorted
+ * in a case sensitive way.
+ */
+ SDict(int size=17,bool caseSensitive=TRUE) : m_sizeIndex(0)
+ {
+ m_list = new SList<T>(this);
+#if AUTORESIZE
+ while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
+ m_dict = new QDict<T>(SDict_primes[m_sizeIndex],caseSensitive);
+#else
+ m_dict = new QDict<T>(size,caseSensitive);
+#endif
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~SDict()
+ {
+ delete m_list;
+ delete m_dict;
+ }
+
+ /*! Appends an element to the dictionary. The element is owned by the
+ * dictionary.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void append(const char *key,const T *d)
+ {
+ m_list->append(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Prepends an element to the dictionary. The element is owned by the
+ * dictionary.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void prepend(const char *key,const T *d)
+ {
+ m_list->prepend(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Remove an item from the dictionary */
+ bool remove(const char *key)
+ {
+ T *item = m_dict->take(key);
+ return item ? m_list->remove(item) : FALSE;
+ }
+
+ /*! Take an item out of the dictionary without deleting it */
+ T *take(const char *key)
+ {
+ T *item = m_dict->take(key);
+ if (item)
+ {
+ int i = m_list->find(item);
+ m_list->take(i);
+ }
+ return item;
+ }
+
+ /*! Sorts the members of the dictionary. First appending a number
+ * of members and then sorting them is faster (O(NlogN) than using
+ * inSort() for each member (O(N^2)).
+ */
+ void sort()
+ {
+ m_list->sort();
+ }
+ /*! Inserts a compound into the dictionary in a sorted way.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void inSort(const char *key,const T *d)
+ {
+ m_list->inSort(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ void insertAt(int i,const char *key,const T *d)
+ {
+ m_list->insert(i,d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Indicates whether or not the dictionary owns its elements */
+ void setAutoDelete(bool val)
+ {
+ m_list->setAutoDelete(val);
+ }
+
+ /*! Looks up a compound given its key.
+ * \param key The key to identify this element.
+ * \return The requested compound or zero if it cannot be found.
+ * \sa append()
+ */
+ T *find(const char *key)
+ {
+ return m_dict->find(key);
+ }
+ T *find(const QCString &key)
+ {
+ return m_dict->find(key);
+ }
+ T *find(const QString &key)
+ {
+ return m_dict->find(key);
+ }
+ int findAt(const QCString &key)
+ {
+ T *item = find(key);
+ if (item==0) return -1;
+ return m_list->find(item);
+ }
+
+ /*! Equavalent to find(). */
+ T *operator[](const char *key) const
+ {
+ return m_dict->find(key);
+ }
+
+ /*! Returns the item at position \a i in the sorted dictionary */
+ T *at(uint i)
+ {
+ return m_list->at(i);
+ }
+
+ /*! Function that is used to compare two items when sorting.
+ * Overload this to properly sort items.
+ * \sa inSort()
+ */
+ virtual int compareValues(const T *item1,const T *item2) const
+ {
+ return item1!=item2;
+ }
+
+ /*! Clears the dictionary. Will delete items if setAutoDelete() was
+ * set to \c TRUE.
+ * \sa setAutoDelete
+ */
+ void clear()
+ {
+ m_list->clear();
+ m_dict->clear();
+ }
+
+ /*! Returns the number of items stored in the dictionary
+ */
+ int count() const
+ {
+ return m_list->count();
+ }
+
+ class Iterator; // first forward declare
+ friend class Iterator; // then make it a friend
+ /*! Simple iterator for SDict. It iterates in the order in which the
+ * elements are stored.
+ */
+ class Iterator
+ {
+ public:
+ /*! Create an iterator given the dictionary. */
+ Iterator(const SDict<T> &dict)
+ {
+ m_li = new QListIterator<T>(*dict.m_list);
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~Iterator()
+ {
+ delete m_li;
+ }
+
+ /*! Set the iterator to the first element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toFirst() const
+ {
+ return m_li->toFirst();
+ }
+
+ /*! Set the iterator to the last element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toLast() const
+ {
+ return m_li->toLast();
+ }
+
+ /*! Returns the current compound */
+ T *current() const
+ {
+ return m_li->current();
+ }
+
+ /*! Moves the iterator to the next element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the last element.
+ */
+ T *operator++()
+ {
+ return m_li->operator++();
+ }
+
+ /*! Moves the iterator to the previous element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the first element.
+ */
+ T *operator--()
+ {
+ return m_li->operator--();
+ }
+
+ private:
+ QListIterator<T> *m_li;
+ };
+
+ class IteratorDict; // first forward declare
+ friend class IteratorDict; // then make it a friend
+ /*! Simple iterator for SDict. It iterates over the dictionary elements
+ * in an unsorted way, but does provide information about the element's key.
+ */
+ class IteratorDict
+ {
+ public:
+ /*! Create an iterator given the dictionary. */
+ IteratorDict(const SDict<T> &dict)
+ {
+ m_di = new QDictIterator<T>(*dict.m_dict);
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~IteratorDict()
+ {
+ delete m_di;
+ }
+
+ /*! Set the iterator to the first element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toFirst() const
+ {
+ return m_di->toFirst();
+ }
+
+ /*! Set the iterator to the last element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toLast() const
+ {
+ return m_di->toLast();
+ }
+
+ /*! Returns the current compound */
+ T *current() const
+ {
+ return m_di->current();
+ }
+
+ /*! Returns the current key */
+ QCString currentKey() const
+ {
+ return m_di->currentKey();
+ }
+
+ /*! Moves the iterator to the next element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the last element.
+ */
+ T *operator++()
+ {
+ return m_di->operator++();
+ }
+
+ /*! Moves the iterator to the previous element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the first element.
+ */
+ T *operator--()
+ {
+ return m_di->operator--();
+ }
+
+ private:
+ QDictIterator<T> *m_di;
+ };
+};
+
+/** internal wrapper class that redirects compareValues() to the
+ * dictionary
+ */
+template<class T>
+class SIntList : public QList<T>
+{
+ public:
+ SIntList(SIntDict<T> *owner) : m_owner(owner) {}
+ virtual ~SIntList() {}
+ private:
+ int compareValues(const T *item1,const T *item2) const
+ {
+ return m_owner->compareValues(item1,item2);
+ }
+ SIntDict<T> *m_owner;
+};
+
+/** Ordered dictionary of elements of type T.
+ * Internally uses a QList<T> and a QIntDict<T>.
+ */
+template<class T>
+class SIntDict
+{
+ private:
+ SIntList<T> *m_list;
+ QIntDict<T> *m_dict;
+ int m_sizeIndex;
+
+ public:
+ /*! Create an ordered dictionary.
+ * \param size The size of the dictionary. Should be a prime number for
+ * best distribution of elements.
+ */
+ SIntDict(int size=17) : m_sizeIndex(0)
+ {
+ m_list = new SIntList<T>(this);
+#if AUTORESIZE
+ while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
+ m_dict = new QIntDict<T>(SDict_primes[m_sizeIndex]);
+#else
+ m_dict = new QIntDict<T>(size);
+#endif
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~SIntDict()
+ {
+ delete m_list;
+ delete m_dict;
+ }
+
+ /*! Appends a compound to the dictionary. The element is owned by the
+ * dictionary.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void append(int key,const T *d)
+ {
+ m_list->append(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Prepend a compound to the dictionary. The element is owned by the
+ * dictionary.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void prepend(int key,const T *d)
+ {
+ m_list->prepend(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Remove an item from the dictionary */
+ bool remove(int key)
+ {
+ T *item = m_dict->take(key);
+ return item ? m_list->remove(item) : FALSE;
+ }
+
+ /*! Sorts the members of the dictionary. First appending a number
+ * of members and then sorting them is faster (O(NlogN) than using
+ * inSort() for each member (O(N^2)).
+ */
+ void sort()
+ {
+ m_list->sort();
+ }
+
+ /*! Inserts a compound into the dictionary in a sorted way.
+ * \param key The unique key to use to quicky find the item later on.
+ * \param d The compound to add.
+ * \sa find()
+ */
+ void inSort(int key,const T *d)
+ {
+ m_list->inSort(d);
+ m_dict->insert(key,d);
+#if AUTORESIZE
+ if (m_dict->size()>SDict_primes[m_sizeIndex])
+ {
+ m_dict->resize(SDict_primes[++m_sizeIndex]);
+ }
+#endif
+ }
+
+ /*! Indicates whether or not the dictionary owns its elements */
+ void setAutoDelete(bool val)
+ {
+ m_list->setAutoDelete(val);
+ }
+
+ /*! Looks up a compound given its key.
+ * \param key The key to identify this element.
+ * \return The requested compound or zero if it cannot be found.
+ * \sa append()
+ */
+ T *find(int key)
+ {
+ return m_dict->find(key);
+ }
+
+ /*! Equavalent to find(). */
+ T *operator[](int key) const
+ {
+ return m_dict->find(key);
+ }
+
+ /*! Returns the item at position \a i in the sorted dictionary */
+ T *at(uint i)
+ {
+ return m_list->at(i);
+ }
+
+ /*! Function that is used to compare two items when sorting.
+ * Overload this to properly sort items.
+ * \sa inSort()
+ */
+ virtual int compareValues(const T *item1,const T *item2) const
+ {
+ return item1!=item2;
+ }
+
+ /*! Clears the dictionary. Will delete items if setAutoDelete() was
+ * set to \c TRUE.
+ * \sa setAutoDelete
+ */
+ void clear()
+ {
+ m_list->clear();
+ m_dict->clear();
+ }
+
+ /*! Returns the number of items stored in the dictionary
+ */
+ int count()
+ {
+ return m_list->count();
+ }
+
+ class Iterator; // first forward declare
+ friend class Iterator; // then make it a friend
+ /*! Simple iterator for SDict. It iterates in the order in which the
+ * elements are stored.
+ */
+ class Iterator
+ {
+ public:
+ /*! Create an iterator given the dictionary. */
+ Iterator(const SIntDict<T> &dict)
+ {
+ m_li = new QListIterator<T>(*dict.m_list);
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~Iterator()
+ {
+ delete m_li;
+ }
+
+ /*! Set the iterator to the first element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toFirst() const
+ {
+ return m_li->toFirst();
+ }
+
+ /*! Set the iterator to the last element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toLast() const
+ {
+ return m_li->toLast();
+ }
+
+ /*! Returns the current compound */
+ T *current() const
+ {
+ return m_li->current();
+ }
+
+ /*! Moves the iterator to the next element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the last element.
+ */
+ T *operator++()
+ {
+ return m_li->operator++();
+ }
+
+ /*! Moves the iterator to the previous element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the first element.
+ */
+ T *operator--()
+ {
+ return m_li->operator--();
+ }
+
+ private:
+ QListIterator<T> *m_li;
+ };
+
+ class IteratorDict; // first forward declare
+ friend class IteratorDict; // then make it a friend
+ /*! Simple iterator for SDict. It iterates over the dictionary elements
+ * in an unsorted way, but does provide information about the element's key.
+ */
+ class IteratorDict
+ {
+ public:
+ /*! Create an iterator given the dictionary. */
+ IteratorDict(const SIntDict<T> &dict)
+ {
+ m_di = new QIntDictIterator<T>(*dict.m_dict);
+ }
+
+ /*! Destroys the dictionary */
+ virtual ~IteratorDict()
+ {
+ delete m_di;
+ }
+
+ /*! Set the iterator to the first element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toFirst() const
+ {
+ return m_di->toFirst();
+ }
+
+ /*! Set the iterator to the last element in the list.
+ * \return The first compound, or zero if the list was empty.
+ */
+ T *toLast() const
+ {
+ return m_di->toLast();
+ }
+
+ /*! Returns the current compound */
+ T *current() const
+ {
+ return m_di->current();
+ }
+
+ /*! Returns the current key */
+ int currentKey() const
+ {
+ return m_di->currentKey();
+ }
+
+ /*! Moves the iterator to the next element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the last element.
+ */
+ T *operator++()
+ {
+ return m_di->operator++();
+ }
+
+ /*! Moves the iterator to the previous element.
+ * \return the new "current" element, or zero if the iterator was
+ * already pointing at the first element.
+ */
+ T *operator--()
+ {
+ return m_di->operator--();
+ }
+
+ private:
+ QDictIterator<T> *m_di;
+ };
+
+};
+
+#endif
diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp
new file mode 100644
index 0000000..42a0307
--- /dev/null
+++ b/src/sqlite3gen.cpp
@@ -0,0 +1,1370 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "settings.h"
+#include "message.h"
+
+#if USE_SQLITE3
+
+#include "qtbc.h"
+#include "sqlite3gen.h"
+#include "doxygen.h"
+#include "config.h"
+#include "util.h"
+#include "docparser.h"
+#include "language.h"
+
+#include "dot.h"
+#include "arguments.h"
+#include "classlist.h"
+#include "filedef.h"
+#include "namespacedef.h"
+#include "filename.h"
+#include "groupdef.h"
+#include "pagedef.h"
+#include "dirdef.h"
+
+#include <qdir.h>
+#include <string.h>
+#include <sqlite3.h>
+
+//#define DBG_CTX(x) printf x
+#define DBG_CTX(x) do { } while(0)
+
+const char * schema_queries[][2] = {
+ { "includes",
+ "CREATE TABLE IF NOT EXISTS includes ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "local INTEGER NOT NULL,"
+ "id_src INTEGER NOT NULL,"
+ "id_dst INTEGER NOT NULL);"
+ "CREATE UNIQUE INDEX idx_includes ON includes "
+ "(local, id_src, id_dst);"
+ },
+ { "innerclass",
+ "CREATE TABLE IF NOT EXISTS innerclass ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "refid TEXT NOT NULL,"
+ "prot INTEGER NOT NULL,"
+ "name TEXT NOT NULL)"
+ },
+ { "files",
+ "CREATE TABLE IF NOT EXISTS files ("
+ "name TEXT PRIMARY KEY NOT NULL);"
+ },
+ { "refids",
+ "CREATE TABLE IF NOT EXISTS refids ("
+ "refid TEXT PRIMARY KEY NOT NULL);"
+ },
+ { "xrefs",
+ "CREATE TABLE IF NOT EXISTS xrefs ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "refid_src INTEGER NOT NULL, "
+ "refid_dst INTEGER NOT NULL, "
+ "id_file INTEGER NOT NULL, "
+ "line INTEGER NOT NULL, "
+ "column INTEGER NOT NULL);"
+ "CREATE UNIQUE INDEX idx_xrefs ON xrefs "
+ "(refid_src, refid_dst, id_file, line, column);"
+ },
+ { "memberdef",
+ "CREATE TABLE IF NOT EXISTS memberdef ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "id_file INTEGER NOT NULL,"
+ "line INTEGER NOT NULL,"
+ "column INTEGER NOT NULL,"
+ "refid TEXT NOT NULL,"
+ "name TEXT NOT NULL,"
+ "definition TEXT,"
+ "type TEXT,"
+ "argsstring TEXT,"
+ "scope TEXT,"
+ "initializer TEXT,"
+ "prot INTEGER,"
+ "const INTEGER,"
+ "virt INTEGER,"
+ "static INTEGER NOT NULL,"
+ "explicit INTEGER,"
+ "inline INTEGER,"
+ "final INTEGER,"
+ "sealed INTEGER,"
+ "new INTEGER,"
+ "optional INTEGER,"
+ "required INTEGER,"
+ "mutable INTEGER,"
+ "initonly INTEGER,"
+ "readable INTEGER,"
+ "writable INTEGER,"
+ "gettable INTEGER,"
+ "settable INTEGER,"
+ "accessor INTEGER,"
+ "addable INTEGER,"
+ "removable INTEGER,"
+ "raisable INTEGER,"
+ "kind INTEGER,"
+ "id_bodyfile INTEGER,"
+ "bodystart INTEGER,"
+ "bodyend INTEGER,"
+ "detaileddescription TEXT,"
+ "briefdescription TEXT,"
+ "inbodydescription TEXT"
+ ")"
+ },
+ { "compounddef",
+ "CREATE TABLE IF NOT EXISTS compounddef ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "name TEXT NOT NULL,"
+ "kind TEXT NOT NULL,"
+ "prot INTEGER NOT NULL,"
+ "refid TEXT NOT NULL,"
+ "id_file INTEGER NOT NULL,"
+ "line INTEGER NOT NULL,"
+ "column INTEGER NOT NULL)"
+ },
+ { "basecompoundref",
+ "CREATE TABLE IF NOT EXISTS basecompoundref ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "base TEXT NOT NULL,"
+ "derived TEXT NOT NULL,"
+ "refid TEXT NOT NULL,"
+ "prot INTEGER NOT NULL,"
+ "virt INTEGER NOT NULL)"
+ },
+ { "derivedcompoundref",
+ "CREATE TABLE IF NOT EXISTS derivedcompoundref ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "base TEXT NOT NULL,"
+ "derived TEXT NOT NULL,"
+ "refid TEXT NOT NULL,"
+ "prot INTEGER NOT NULL,"
+ "virt INTEGER NOT NULL)"
+ },
+ { "params",
+ "CREATE TABLE IF NOT EXISTS params ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "attributes TEXT,"
+ "type TEXT,"
+ "declname TEXT,"
+ "defnname TEXT,"
+ "array TEXT,"
+ "defval TEXT,"
+ "briefdescription TEXT)"
+ },
+ { "memberdef_params",
+ "CREATE TABLE IF NOT EXISTS memberdef_params ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "id_memberdef INTEGER NOT NULL,"
+ "id_param INTEGER NOT NULL)"
+ },
+ { "innernamespaces",
+ "CREATE TABLE IF NOT EXISTS innernamespaces ("
+ "rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "refid TEXT NOT NULL,"
+ "name TEXT NOT NULL)"
+ }
+};
+
+//////////////////////////////////////////////////////
+struct SqlStmt {
+ const char *query;
+ sqlite3_stmt *stmt;
+};
+//////////////////////////////////////////////////////
+SqlStmt incl_insert = { "INSERT INTO includes "
+ "( local, id_src, id_dst ) "
+ "VALUES "
+ "(:local,:id_src,:id_dst )"
+ ,NULL
+};
+SqlStmt incl_select = { "SELECT COUNT(*) FROM includes WHERE "
+ "local=:local AND id_src=:id_src AND id_dst=:id_dst"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt innerclass_insert={"INSERT INTO innerclass "
+ "( refid, prot, name )"
+ "VALUES "
+ "(:refid,:prot,:name )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt files_select = {"SELECT rowid FROM files WHERE name=:name"
+ ,NULL
+};
+SqlStmt files_insert = {"INSERT INTO files "
+ "( name )"
+ "VALUES "
+ "(:name )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt refids_select = {"SELECT rowid FROM refids WHERE "
+ "refid=:refid"
+ ,NULL
+};
+SqlStmt refids_insert = {"INSERT INTO refids "
+ "( refid )"
+ "VALUES "
+ "(:refid )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt xrefs_insert= {"INSERT INTO xrefs "
+ "( refid_src, refid_dst, id_file, line, column )"
+ "VALUES "
+ "(:refid_src,:refid_dst,:id_file,:line,:column )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt memberdef_insert={"INSERT INTO memberdef "
+ "( refid, prot, static, const, explicit, inline, final, sealed, new, optional, required, virt, mutable, initonly, readable, writable, gettable, settable, accessor, addable, removable, raisable, name, type, definition, argsstring, scope, initializer, kind, id_bodyfile, bodystart, bodyend, id_file, line, column, detaileddescription, briefdescription, inbodydescription)"
+ "VALUES "
+ "(:refid,:prot,:static,:const,:explicit,:inline,:final,:sealed,:new,:optional,:required,:virt,:mutable,:initonly,:readable,:writable,:gettable,:settable,:accessor,:addable,:removable,:raisable,:name,:type,:definition,:argsstring,:scope,:initializer,:kind,:id_bodyfile,:bodystart,:bodyend,:id_file,:line,:column,:detaileddescription,:briefdescription,:inbodydescription)"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt compounddef_insert={"INSERT INTO compounddef "
+ "( name, kind, prot, refid, id_file, line, column ) "
+ "VALUES "
+ "(:name,:kind,:prot,:refid,:id_file,:line,:column )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt basecompoundref_insert={"INSERT INTO basecompoundref "
+ "( base, derived, refid, prot, virt ) "
+ "VALUES "
+ "(:base,:derived,:refid,:prot,:virt )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt derivedcompoundref_insert={"INSERT INTO derivedcompoundref "
+ "( refid, prot, virt, base, derived ) "
+ "VALUES "
+ "(:refid,:prot,:virt,:base,:derived )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt params_select = { "SELECT rowid FROM params WHERE "
+ "(attributes IS NULL OR attributes=:attributes) AND "
+ "(type IS NULL OR type=:type) AND "
+ "(declname IS NULL OR declname=:declname) AND "
+ "(defnname IS NULL OR defnname=:defnname) AND "
+ "(array IS NULL OR array=:array) AND "
+ "(defval IS NULL OR defval=:defval) AND "
+ "(briefdescription IS NULL OR briefdescription=:briefdescription)"
+ ,NULL
+};
+SqlStmt params_insert = { "INSERT INTO params "
+ "( attributes, type, declname, defnname, array, defval, briefdescription ) "
+ "VALUES "
+ "(:attributes,:type,:declname,:defnname,:array,:defval,:briefdescription)"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt memberdef_params_insert={ "INSERT INTO memberdef_params "
+ "( id_memberdef, id_param)"
+ "VALUES "
+ "(:id_memberdef,:id_param)"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt innernamespace_insert={"INSERT INTO innernamespaces "
+ "( refid, name)"
+ "VALUES "
+ "(:refid,:name)",
+ NULL
+};
+
+
+class TextGeneratorSqlite3Impl : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorSqlite3Impl(StringList &l) : l(l) {
+ l.setAutoDelete(TRUE);
+ }
+ void writeString(const char * /*s*/,bool /*keepSpaces*/) const
+ {
+ }
+ void writeBreak(int) const
+ {
+ DBG_CTX(("writeBreak\n"));
+ }
+ void writeLink(const char * /*extRef*/,const char *file,
+ const char *anchor,const char * /*text*/
+ ) const
+ {
+ QCString *rs=new QCString(file);
+ if (anchor)
+ {
+ rs->append("_1").append(anchor);
+ }
+ l.append(rs);
+ }
+ private:
+ StringList &l;
+ // the list is filled by linkifyText and consumed by the caller
+};
+
+
+static void bindTextParameter(SqlStmt &s,const char *name,const char *value, bool _static=TRUE)
+{
+ int idx = sqlite3_bind_parameter_index(s.stmt, name);
+ sqlite3_bind_text(s.stmt, idx, value, -1, _static==TRUE?SQLITE_STATIC:SQLITE_TRANSIENT);
+}
+
+static void bindIntParameter(SqlStmt &s,const char *name,int value)
+{
+ int idx = sqlite3_bind_parameter_index(s.stmt, name);
+ sqlite3_bind_int(s.stmt, idx, value);
+}
+
+static int step(sqlite3 *db, SqlStmt &s,bool getRowId=FALSE, bool select=FALSE)
+{
+ int rowid=-1;
+ int rc = sqlite3_step(s.stmt);
+ if (rc!=SQLITE_DONE && rc!=SQLITE_ROW)
+ {
+ msg("sqlite3_step failed: %s\n", sqlite3_errmsg(db));
+ sqlite3_clear_bindings(s.stmt);
+ return -1;
+ }
+ if (getRowId && select) rowid = sqlite3_column_int(s.stmt, 0); // works on selects, doesnt on inserts
+ if (getRowId && !select) rowid = sqlite3_last_insert_rowid(db); //works on inserts, doesnt on selects
+ sqlite3_reset(s.stmt);
+ sqlite3_clear_bindings(s.stmt); // XXX When should this really be called
+ return rowid;
+}
+
+static int insertFile(sqlite3 *db, const char* name)
+{
+ int rowid=-1;
+ if (name==0) return rowid;
+
+ bindTextParameter(files_select,":name",name);
+ rowid=step(db,files_select,TRUE,TRUE);
+ if (rowid==0)
+ {
+ bindTextParameter(files_insert,":name",name);
+ rowid=step(db,files_insert,TRUE);
+ }
+ return rowid;
+}
+
+static int insertRefid(sqlite3 *db, const char *refid)
+{
+ int rowid=-1;
+ if (refid==0) return rowid;
+
+ bindTextParameter(refids_select,":refid",refid);
+ rowid=step(db,refids_select,TRUE,TRUE);
+ if (rowid==0)
+ {
+ bindTextParameter(refids_insert,":refid",refid);
+ rowid=step(db,refids_insert,TRUE);
+ }
+ return rowid;
+}
+
+
+static void insertMemberReference(sqlite3 *db, const char*src, const char*dst, const char *file, int line, int column)
+{
+ int id_file = insertFile(db,file);
+ int refid_src = insertRefid(db,src);
+ int refid_dst = insertRefid(db,dst);
+ if (id_file==-1||refid_src==-1||refid_dst==-1)
+ return;
+
+ bindIntParameter(xrefs_insert,":refid_src",refid_src);
+ bindIntParameter(xrefs_insert,":refid_dst",refid_dst);
+ bindIntParameter(xrefs_insert,":id_file",id_file);
+ bindIntParameter(xrefs_insert,":line",line);
+ bindIntParameter(xrefs_insert,":column",1);
+ step(db,xrefs_insert);
+}
+
+static void insertMemberReference(sqlite3 *db, MemberDef *src, MemberDef *dst, const char*floc)
+{
+ if (dst->getStartBodyLine()!=-1 && dst->getBodyDef())
+ {
+ static char file[4096];
+ int line=0,column=0;
+ if (floc)
+ {
+ int rv = sscanf(floc,"%[^:]:%d:%d",file,&line,&column);
+ if (rv!=3)
+ {
+ msg("unable to read file loc from[%s]\n",floc);
+ return;
+ }
+ }
+ insertMemberReference(db,src->anchor().data(),dst->anchor().data(),file,line,column);
+ }
+}
+
+static void insertMemberFunctionParams(sqlite3 *db,int id_memberdef,MemberDef *md,Definition *def)
+{
+ ArgumentList *declAl = md->declArgumentList();
+ ArgumentList *defAl = md->argumentList();
+ if (declAl!=0 && declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ Argument *defArg = defAli.current();
+
+ if (!a->attrib.isEmpty())
+ {
+ bindTextParameter(params_select,":attributes",a->attrib.data());
+ bindTextParameter(params_insert,":attributes",a->attrib.data());
+ }
+ if (!a->type.isEmpty())
+ {
+ StringList l;
+ linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->type);
+
+ StringListIterator li(l);
+ QCString *s;
+ while ((s=li.current()))
+ {
+ insertMemberReference(db,md->anchor().data(),s->data(),def->getDefFileName().data(),md->getDefLine(),1);
+ ++li;
+ }
+ bindTextParameter(params_select,":type",a->type.data());
+ bindTextParameter(params_insert,":type",a->type.data());
+ }
+ if (!a->name.isEmpty())
+ {
+ bindTextParameter(params_select,":declname",a->name.data());
+ bindTextParameter(params_insert,":declname",a->name.data());
+ }
+ if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
+ {
+ bindTextParameter(params_select,":defnname",defArg->name.data());
+ bindTextParameter(params_insert,":defnname",defArg->name.data());
+ }
+ if (!a->array.isEmpty())
+ {
+ bindTextParameter(params_select,":array",a->array.data());
+ bindTextParameter(params_insert,":array",a->array.data());
+ }
+ if (!a->defval.isEmpty())
+ {
+ StringList l;
+ linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->defval);
+ bindTextParameter(params_select,":defval",a->defval.data());
+ bindTextParameter(params_insert,":defval",a->defval.data());
+ }
+ if (defArg) ++defAli;
+
+ int id_param=step(db,params_select,TRUE,TRUE);
+ if (id_param==0) {
+ id_param=step(db,params_insert,TRUE);
+ }
+
+ bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
+ bindIntParameter(memberdef_params_insert,":id_param",id_param);
+ step(db,memberdef_params_insert);
+ }
+ }
+}
+
+static void insertMemberDefineParams(sqlite3 *db,int id_memberdef,MemberDef *md,Definition *def)
+{
+ if (md->argumentList()->count()==0) // special case for "foo()" to
+ // disguish it from "foo".
+ {
+ DBG_CTX(("no params\n"));
+ }
+ else
+ {
+ ArgumentListIterator ali(*md->argumentList());
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ bindTextParameter(params_insert,":defnname",a->type.data());
+ int id_param=step(db,params_insert,TRUE);
+
+ bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
+ bindIntParameter(memberdef_params_insert,":id_param",id_param);
+ step(db,memberdef_params_insert);
+ }
+ }
+}
+
+
+static void stripQualifiers(QCString &typeStr)
+{
+ bool done=FALSE;
+ while (!done)
+ {
+ if (typeStr.stripPrefix("static "));
+ else if (typeStr.stripPrefix("virtual "));
+ else if (typeStr.stripPrefix("volatile "));
+ else if (typeStr=="virtual") typeStr="";
+ else done=TRUE;
+ }
+}
+
+static int prepareStatement(sqlite3 *db, SqlStmt &s)
+{
+ int rc;
+ rc = sqlite3_prepare_v2(db,s.query,-1,&s.stmt,0);
+ if (rc!=SQLITE_OK)
+ {
+ msg("prepare failed for %s\n%s\n", s.query, sqlite3_errmsg(db));
+ return -1;
+ }
+ return rc;
+}
+
+static int prepareStatements(sqlite3 *db)
+{
+ if (
+ -1==prepareStatement(db, memberdef_insert) ||
+ -1==prepareStatement(db, files_insert) ||
+ -1==prepareStatement(db, files_select) ||
+ -1==prepareStatement(db, refids_insert) ||
+ -1==prepareStatement(db, refids_select) ||
+ -1==prepareStatement(db, incl_insert)||
+ -1==prepareStatement(db, incl_select)||
+ -1==prepareStatement(db, params_insert) ||
+ -1==prepareStatement(db, params_select) ||
+ -1==prepareStatement(db, xrefs_insert) ||
+ -1==prepareStatement(db, innerclass_insert) ||
+ -1==prepareStatement(db, compounddef_insert) ||
+ -1==prepareStatement(db, basecompoundref_insert) ||
+ -1==prepareStatement(db, derivedcompoundref_insert) ||
+ -1==prepareStatement(db, memberdef_params_insert)||
+ -1==prepareStatement(db, innernamespace_insert)
+ )
+ {
+ return -1;
+ }
+ return 0;
+}
+
+static void beginTransaction(sqlite3 *db)
+{
+ char * sErrMsg = 0;
+ sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
+}
+
+static void endTransaction(sqlite3 *db)
+{
+ char * sErrMsg = 0;
+ sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
+}
+
+static void pragmaTuning(sqlite3 *db)
+{
+ char * sErrMsg = 0;
+ sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &sErrMsg);
+ sqlite3_exec(db, "PRAGMA journal_mode = MEMORY", NULL, NULL, &sErrMsg);
+ sqlite3_exec(db, "PRAGMA temp_store = MEMORY;", NULL, NULL, &sErrMsg);
+}
+
+static int initializeSchema(sqlite3* db)
+{
+ int rc;
+ sqlite3_stmt *stmt = 0;
+
+ msg("Initializing DB schema...\n");
+ for (unsigned int k = 0; k < sizeof(schema_queries) / sizeof(schema_queries[0]); k++)
+ {
+ const char *q = schema_queries[k][1];
+ // create table
+ rc = sqlite3_prepare_v2(db, q, -1, &stmt, 0);
+ if (rc != SQLITE_OK)
+ {
+ msg("failed to prepare query: %s\n\t%s\n", q, sqlite3_errmsg(db));
+ return -1;
+ }
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE)
+ {
+ msg("failed to execute query: %s\n\t%s\n", q, sqlite3_errmsg(db));
+ return -1;
+ }
+ sqlite3_finalize(stmt);
+ }
+ return 0;
+}
+
+////////////////////////////////////////////
+static void writeInnerClasses(sqlite3*db,const ClassSDict *cl)
+{
+ if (!cl) return;
+
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
+ {
+ bindTextParameter(innerclass_insert,":refid",cd->getOutputFileBase(),FALSE);
+ bindIntParameter(innerclass_insert,":prot",cd->protection());
+ bindTextParameter(innerclass_insert,":name",cd->name());
+ step(db,innerclass_insert);
+ }
+ }
+}
+
+
+static void writeInnerNamespaces(sqlite3 *db,const NamespaceSDict *nl)
+{
+ if (nl)
+ {
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
+ {
+ bindTextParameter(innernamespace_insert,":refid",nd->getOutputFileBase(),FALSE);
+ bindTextParameter(innernamespace_insert,":name",nd->name(),FALSE);
+ step(db,innernamespace_insert);
+ }
+ }
+ }
+}
+
+
+static void writeTemplateArgumentList(sqlite3* db,
+ ArgumentList * al,
+ Definition * scope,
+ FileDef * fileScope)
+{
+ if (al)
+ {
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (!a->type.isEmpty())
+ {
+ #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
+ bindTextParameter(params_select,":type",a->type);
+ bindTextParameter(params_insert,":type",a->type);
+ }
+ if (!a->name.isEmpty())
+ {
+ bindTextParameter(params_select,":declname",a->name);
+ bindTextParameter(params_insert,":declname",a->name);
+ bindTextParameter(params_select,":defnname",a->name);
+ bindTextParameter(params_insert,":defnname",a->name);
+ }
+ if (!a->defval.isEmpty())
+ {
+ #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
+ bindTextParameter(params_select,":defval",a->defval);
+ bindTextParameter(params_insert,":defval",a->defval);
+ }
+ if (!step(db,params_select,TRUE,TRUE))
+ step(db,params_insert);
+ }
+ }
+}
+
+static void writeMemberTemplateLists(sqlite3* db,MemberDef *md)
+{
+ ArgumentList *templMd = md->templateArguments();
+ if (templMd) // function template prefix
+ {
+ writeTemplateArgumentList(db,templMd,md->getClassDef(),md->getFileDef());
+ }
+}
+static void writeTemplateList(sqlite3*db,ClassDef *cd)
+{
+ writeTemplateArgumentList(db,cd->templateArguments(),cd,0);
+}
+////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def)
+{
+ // + declaration/definition arg lists
+ // + reimplements
+ // + reimplementedBy
+ // + exceptions
+ // + const/volatile specifiers
+ // - examples
+ // + source definition
+ // + source references
+ // + source referenced by
+ // - body code
+ // + template arguments
+ // (templateArguments(), definitionTemplateParameterLists())
+ // - call graph
+
+ // enum values are written as part of the enum
+ if (md->memberType()==MemberType_EnumValue) return;
+ if (md->isHidden()) return;
+ //if (md->name().at(0)=='@') return; // anonymous member
+
+ // group members are only visible in their group
+ //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
+ QCString memType;
+ // memberdef
+ bindTextParameter(memberdef_insert,":refid",md->anchor().data(),FALSE);
+ bindIntParameter(memberdef_insert,":kind",md->memberType());
+ bindIntParameter(memberdef_insert,":prot",md->protection());
+
+ bindIntParameter(memberdef_insert,":static",md->isStatic());
+
+ bool isFunc=FALSE;
+ switch (md->memberType())
+ {
+ case MemberType_Function: // fall through
+ case MemberType_Signal: // fall through
+ case MemberType_Friend: // fall through
+ case MemberType_DCOP: // fall through
+ case MemberType_Slot:
+ isFunc=TRUE;
+ break;
+ default:
+ break;
+ }
+ if (isFunc)
+ {
+ ArgumentList *al = md->argumentList();
+ if (al!=0 && al->constSpecifier)
+ {
+ bindIntParameter(memberdef_insert,":const",al->constSpecifier);
+ }
+ bindIntParameter(memberdef_insert,":explicit",md->isExplicit());
+ bindIntParameter(memberdef_insert,":inline",md->isInline());
+ bindIntParameter(memberdef_insert,":final",md->isFinal());
+ bindIntParameter(memberdef_insert,":sealed",md->isSealed());
+ bindIntParameter(memberdef_insert,":new",md->isNew());
+ bindIntParameter(memberdef_insert,":optional",md->isOptional());
+ bindIntParameter(memberdef_insert,":required",md->isRequired());
+
+ bindIntParameter(memberdef_insert,":virt",md->virtualness());
+ }
+ // place in the arguments and linkify the arguments
+
+ if (md->memberType() == MemberType_Variable)
+ {
+ bindIntParameter(memberdef_insert,":mutable",md->isMutable());
+ bindIntParameter(memberdef_insert,":initonly",md->isInitonly());
+ }
+ else if (md->memberType() == MemberType_Property)
+ {
+ bindIntParameter(memberdef_insert,":readable",md->isReadable());
+ bindIntParameter(memberdef_insert,":writable",md->isWritable());
+ bindIntParameter(memberdef_insert,":gettable",md->isGettable());
+ bindIntParameter(memberdef_insert,":settable",md->isSettable());
+ if (md->isAssign() || md->isCopy() || md->isRetain())
+ {
+ int accessor = md->isAssign() ? md->isAssign() :
+ (md->isCopy() ? md->isCopy() : md->isRetain()) ;
+
+ bindIntParameter(memberdef_insert,":accessor",accessor);
+ }
+ }
+ else if (md->memberType() == MemberType_Event)
+ {
+ bindIntParameter(memberdef_insert,":addable",md->isAddable());
+ bindIntParameter(memberdef_insert,":removable",md->isRemovable());
+ bindIntParameter(memberdef_insert,":raisable",md->isRaisable());
+ }
+
+ // + declaration/definition arg lists
+ if (md->memberType()!=MemberType_Define &&
+ md->memberType()!=MemberType_Enumeration
+ )
+ {
+ if (md->memberType()!=MemberType_Typedef)
+ {
+ writeMemberTemplateLists(db,md);
+ }
+ QCString typeStr = md->typeString();
+ stripQualifiers(typeStr);
+ StringList l;
+ linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,typeStr);
+ if (typeStr.data())
+ {
+ bindTextParameter(memberdef_insert,":type",typeStr.data(),FALSE);
+ }
+
+ if (md->definition())
+ {
+ bindTextParameter(memberdef_insert,":definition",md->definition());
+ }
+
+ if (md->argsString())
+ {
+ bindTextParameter(memberdef_insert,":argsstring",md->argsString());
+ }
+ }
+
+ bindTextParameter(memberdef_insert,":name",md->name());
+
+ if (md->memberType() == MemberType_Property)
+ {
+ if (md->isReadable())
+ {
+ bindIntParameter(memberdef_insert,":readable",1);
+ }
+ if (md->isWritable())
+ {
+ bindIntParameter(memberdef_insert,":writable",1);
+ }
+ }
+
+
+ // Extract references from initializer
+ if (md->hasMultiLineInitializer() || md->hasOneLineInitializer())
+ {
+ bindTextParameter(memberdef_insert,":initializer",md->initializer().data());
+
+ StringList l;
+ linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,md->initializer());
+ StringListIterator li(l);
+ QCString *s;
+ while ((s=li.current()))
+ {
+ if (md->getBodyDef())
+ {
+ DBG_CTX(("initializer:%s %s %s %d\n",
+ md->anchor().data(),
+ s->data(),
+ md->getBodyDef()->getDefFileName().data(),
+ md->getStartBodyLine()));
+ insertMemberReference(db,md->anchor().data(),s->data(),md->getBodyDef()->getDefFileName().data(),md->getStartBodyLine(),1);
+ }
+ ++li;
+ }
+ }
+
+ if ( md->getScopeString() )
+ {
+ bindTextParameter(memberdef_insert,":scope",md->getScopeString().data(),FALSE);
+ }
+
+ // +Brief, detailed and inbody description
+ bindTextParameter(memberdef_insert,":briefdescription",md->briefDescription(),FALSE);
+ bindTextParameter(memberdef_insert,":detaileddescription",md->documentation(),FALSE);
+ bindTextParameter(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),FALSE);
+
+ // File location
+ if (md->getDefLine() != -1)
+ {
+ int id_file = insertFile(db,md->getDefFileName());
+ if (id_file!=-1)
+ {
+ bindIntParameter(memberdef_insert,":id_file",id_file);
+ bindIntParameter(memberdef_insert,":line",md->getDefLine());
+ bindIntParameter(memberdef_insert,":column",md->getDefColumn());
+
+ if (md->getStartBodyLine()!=-1)
+ {
+ int id_bodyfile = insertFile(db,md->getBodyDef()->absFilePath());
+ if (id_bodyfile == -1)
+ {
+ sqlite3_clear_bindings(memberdef_insert.stmt);
+ }
+ else
+ {
+ bindIntParameter(memberdef_insert,":id_bodyfile",id_bodyfile);
+ bindIntParameter(memberdef_insert,":bodystart",md->getStartBodyLine());
+ bindIntParameter(memberdef_insert,":bodyend",md->getEndBodyLine());
+ }
+ }
+ }
+ }
+
+ int id_memberdef=step(db,memberdef_insert,TRUE);
+
+ if (isFunc)
+ {
+ insertMemberFunctionParams(db,id_memberdef,md,def);
+ }
+ else if (md->memberType()==MemberType_Define &&
+ md->argsString())
+ {
+ insertMemberDefineParams(db,id_memberdef,md,def);
+ }
+
+ // + source references
+ // The cross-references in initializers only work when both the src and dst
+ // are defined.
+ MemberSDict *mdict = md->getReferencesMembers();
+ if (mdict!=0)
+ {
+ MemberSDict::IteratorDict mdi(*mdict);
+ MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ insertMemberReference(db,md,rmd,mdi.currentKey());
+ }
+ }
+ // + source referenced by
+ mdict = md->getReferencedByMembers();
+ if (mdict!=0)
+ {
+ MemberSDict::IteratorDict mdi(*mdict);
+ MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ insertMemberReference(db,rmd,md,mdi.currentKey());
+ }
+ }
+}
+
+static void generateSqlite3Section(sqlite3*db,
+ Definition *d,
+ MemberList *ml,const char * /*kind*/,const char * /*header*/=0,
+ const char * /*documentation*/=0)
+{
+ if (ml==0) return;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ int count=0;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the XML output, we filter those here.
+ if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ count++;
+ }
+ }
+ if (count==0) return; // empty list
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the XML output, we filter those here.
+ //if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ generateSqlite3ForMember(db,md,d);
+ }
+ }
+}
+
+
+static void generateSqlite3ForClass(sqlite3 *db, ClassDef *cd)
+{
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + include file
+ // + list of inner classes
+ // - template argument list(s)
+ // + member groups
+ // + list of all members
+ // - brief description
+ // - detailed description
+ // - inheritance DOT diagram
+ // - collaboration DOT diagram
+ // - user defined member sections
+ // - standard member sections
+ // - detailed member documentation
+ // - examples using the class
+
+ if (cd->isReference()) return; // skip external references.
+ if (cd->isHidden()) return; // skip hidden classes.
+ if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
+ if (cd->templateMaster()!=0) return; // skip generated template instances.
+
+ msg("Generating Sqlite3 output for class %s\n",cd->name().data());
+
+ bindTextParameter(compounddef_insert,":name",cd->name());
+ bindTextParameter(compounddef_insert,":kind",cd->compoundTypeString(),FALSE);
+ bindIntParameter(compounddef_insert,":prot",cd->protection());
+ bindTextParameter(compounddef_insert,":refid",cd->getOutputFileBase(),FALSE);
+
+ int id_file = insertFile(db,cd->getDefFileName().data());
+ bindIntParameter(compounddef_insert,":id_file",id_file);
+ bindIntParameter(compounddef_insert,":line",cd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",cd->getDefColumn());
+
+ step(db,compounddef_insert);
+
+ // + list of direct super classes
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ bindTextParameter(basecompoundref_insert,":refid",bcd->classDef->getOutputFileBase(),FALSE);
+ bindIntParameter(basecompoundref_insert,":prot",bcd->prot);
+ bindIntParameter(basecompoundref_insert,":virt",bcd->virt);
+
+ if (!bcd->templSpecifiers.isEmpty())
+ {
+ bindTextParameter(basecompoundref_insert,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
+ }
+ else
+ {
+ bindTextParameter(basecompoundref_insert,":base",bcd->classDef->displayName(),FALSE);
+ }
+ bindTextParameter(basecompoundref_insert,":derived",cd->displayName(),FALSE);
+ step(db,basecompoundref_insert);
+ }
+ }
+
+ // + list of direct sub classes
+ if (cd->subClasses())
+ {
+ BaseClassListIterator bcli(*cd->subClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ bindTextParameter(derivedcompoundref_insert,":base",cd->displayName());
+ bindTextParameter(derivedcompoundref_insert,":dervied",bcd->classDef->displayName());
+ bindTextParameter(derivedcompoundref_insert,":refid",bcd->classDef->getOutputFileBase());
+ bindIntParameter(derivedcompoundref_insert,":prot",bcd->prot);
+ bindIntParameter(derivedcompoundref_insert,":virt",bcd->virt);
+ step(db,derivedcompoundref_insert);
+ }
+ }
+
+ // + include file
+ IncludeInfo *ii=cd->includeInfo();
+ if (ii)
+ {
+ QCString nm = ii->includeName;
+ if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
+ if (!nm.isEmpty())
+ {
+ int id_dst=insertFile(db,nm);
+ if (id_dst!=-1) {
+ bindIntParameter(incl_select,":local",ii->local);
+ bindIntParameter(incl_select,":id_src",id_file);
+ bindIntParameter(incl_select,":id_dst",id_dst);
+ int count=step(db,incl_select,TRUE,TRUE);
+ if (count==0)
+ {
+ bindIntParameter(incl_insert,":local",ii->local);
+ bindIntParameter(incl_insert,":id_src",id_file);
+ bindIntParameter(incl_insert,":id_dst",id_dst);
+ step(db,incl_insert);
+ }
+ }
+ }
+ }
+ // + list of inner classes
+ writeInnerClasses(db,cd->getClassSDict());
+
+ // - template argument list(s)
+ writeTemplateList(db,cd);
+
+ // + member groups
+ if (cd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateSqlite3Section(db,cd,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ // + list of all members
+ QListIterator<MemberList> mli(cd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ generateSqlite3Section(db,cd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+}
+
+static void generateSqlite3ForNamespace(sqlite3 *db, NamespaceDef *nd)
+{
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // - brief desc
+ // - detailed desc
+ // - location
+ // - files containing (parts of) the namespace definition
+
+ if (nd->isReference() || nd->isHidden()) return; // skip external references
+
+ // + contained class definitions
+ writeInnerClasses(db,nd->getClassSDict());
+
+ // + contained namespace definitions
+ writeInnerNamespaces(db,nd->getNamespaceSDict());
+
+ // + member groups
+ if (nd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateSqlite3Section(db,nd,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ // + normal members
+ QListIterator<MemberList> mli(nd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateSqlite3Section(db,nd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+}
+
+static void generateSqlite3ForFile(sqlite3 *db, FileDef *fd)
+{
+ // + includes files
+ // + includedby files
+ // - include graph
+ // - included by graph
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // - brief desc
+ // - detailed desc
+ // - source code
+ // - location
+ // - number of lines
+
+ if (fd->isReference()) return; // skip external references
+
+ // + includes files
+ IncludeInfo *ii;
+ if (fd->includeFileList())
+ {
+ QListIterator<IncludeInfo> ili(*fd->includeFileList());
+ for (ili.toFirst();(ii=ili.current());++ili)
+ {
+ int id_src=insertFile(db,fd->absFilePath().data());
+ int id_dst=insertFile(db,ii->includeName.data());
+ bindIntParameter(incl_select,":local",ii->local);
+ bindIntParameter(incl_select,":id_src",id_src);
+ bindIntParameter(incl_select,":id_dst",id_dst);
+ if (step(db,incl_select,TRUE,TRUE)==0) {
+ bindIntParameter(incl_insert,":local",ii->local);
+ bindIntParameter(incl_insert,":id_src",id_src);
+ bindIntParameter(incl_insert,":id_dst",id_dst);
+ step(db,incl_insert);
+ }
+ }
+ }
+
+ // + includedby files
+ if (fd->includedByFileList())
+ {
+ QListIterator<IncludeInfo> ili(*fd->includedByFileList());
+ for (ili.toFirst();(ii=ili.current());++ili)
+ {
+ int id_src=insertFile(db,ii->includeName);
+ int id_dst=insertFile(db,fd->absFilePath());
+ bindIntParameter(incl_select,":local",ii->local);
+ bindIntParameter(incl_select,":id_src",id_src);
+ bindIntParameter(incl_select,":id_dst",id_dst);
+ if (step(db,incl_select,TRUE,TRUE)==0) {
+ bindIntParameter(incl_insert,":local",ii->local);
+ bindIntParameter(incl_insert,":id_src",id_src);
+ bindIntParameter(incl_insert,":id_dst",id_dst);
+ step(db,incl_insert);
+ }
+ }
+ }
+
+ // + contained class definitions
+ if (fd->getClassSDict())
+ {
+ writeInnerClasses(db,fd->getClassSDict());
+ }
+
+ // + contained namespace definitions
+ if (fd->getNamespaceSDict())
+ {
+ writeInnerNamespaces(db,fd->getNamespaceSDict());
+ }
+
+ // + member groups
+ if (fd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateSqlite3Section(db,fd,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ // + normal members
+ QListIterator<MemberList> mli(fd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateSqlite3Section(db,fd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+}
+
+static void generateSqlite3ForGroup(sqlite3*db,GroupDef *gd)
+{
+#warning WorkInProgress
+}
+
+static void generateSqlite3ForDir(sqlite3 *db,DirDef *dd)
+{
+#warning WorkInProgress
+}
+
+static void generateSqlite3ForPage(sqlite3 *db,PageDef *pd,bool isExample)
+{
+#warning WorkInProgress
+}
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void generateSqlite3()
+{
+ // + classes
+ // + namespaces
+ // + files
+ // + groups
+ // + related pages
+ // + examples
+ // + main page
+
+ QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
+ QDir sqlite3Dir(outputDirectory);
+ sqlite3 *db;
+ sqlite3_initialize();
+ int rc = sqlite3_open_v2(outputDirectory+"/doxygen_sqlite3.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
+ if (rc != SQLITE_OK)
+ {
+ sqlite3_close(db);
+ msg("database open failed: %s\n", "doxygen_sqlite3.db");
+ return;
+ }
+ beginTransaction(db);
+ pragmaTuning(db);
+
+ if (-1==initializeSchema(db))
+ return;
+
+ if ( -1 == prepareStatements(db) )
+ {
+ err("sqlite generator: prepareStatements failed!");
+ return;
+ }
+
+ // + classes
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ msg("Generating Sqlite3 output for class %s\n",cd->name().data());
+ generateSqlite3ForClass(db,cd);
+ }
+
+ // + namespaces
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ msg("Generating Sqlite3 output for namespace %s\n",nd->name().data());
+ generateSqlite3ForNamespace(db,nd);
+ }
+
+ // + files
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ msg("Generating Sqlite3 output for file %s\n",fd->name().data());
+ generateSqlite3ForFile(db,fd);
+ }
+ }
+
+ // + groups
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (;(gd=gli.current());++gli)
+ {
+ msg("Generating Sqlite3 output for group %s\n",gd->name().data());
+ generateSqlite3ForGroup(db,gd);
+ }
+
+ // + page
+ {
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating Sqlite3 output for page %s\n",pd->name().data());
+ generateSqlite3ForPage(db,pd,FALSE);
+ }
+ }
+
+ // + dirs
+ {
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ msg("Generating Sqlite3 output for dir %s\n",dir->name().data());
+ generateSqlite3ForDir(db,dir);
+ }
+ }
+
+ // + examples
+ {
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating Sqlite3 output for example %s\n",pd->name().data());
+ generateSqlite3ForPage(db,pd,TRUE);
+ }
+ }
+
+ // + main page
+ if (Doxygen::mainPage)
+ {
+ msg("Generating Sqlite3 output for the main page\n");
+ generateSqlite3ForPage(db,Doxygen::mainPage,FALSE);
+ }
+
+ endTransaction(db);
+}
+
+#else // USE_SQLITE3
+void generateSqlite3()
+{
+ err("sqlite3 support has not been compiled in!");
+}
+#endif
+// vim: noai:ts=2:sw=2:ss=2:expandtab
diff --git a/src/sqlite3gen.h b/src/sqlite3gen.h
new file mode 100644
index 0000000..59664dd
--- /dev/null
+++ b/src/sqlite3gen.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SQLITE3GEN_H
+#define SQLITE3GEN_H
+
+void generateSqlite3();
+
+#endif
diff --git a/src/store.cpp b/src/store.cpp
new file mode 100644
index 0000000..8916015
--- /dev/null
+++ b/src/store.cpp
@@ -0,0 +1,484 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "store.h"
+#include "portable.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+#define BLOCK_SIZE 512 // should be >8 and a power of 2
+#define BLOCK_POINTER_SIZE sizeof(portable_off_t)
+
+
+#define ASSERTS_ENABLED
+
+#ifdef ASSERTS_ENABLED
+#define STORE_ASSERT(x) assert(x)
+#else
+#define STORE_ASSERT(x)
+#endif
+
+// Decide to use ftell or keep track of the current file pointer ourselves.
+// Since valgrind shows that calling ftell has the unwanted side-effect of
+// writing some uninitialized bytes (!) it might be better (and faster) to keep track
+// of the current pointer ourselves.
+#define USE_FTELL 0
+
+//------------------------------------------------------------------------------------
+
+Store::Store()
+{
+ m_file = 0;
+ m_front = 0;
+ m_cur = 0;
+ m_head = 0;
+ m_state = Init;
+ m_reads = 0;
+ m_writes = 0;
+}
+
+Store::~Store()
+{
+ if (m_file) fclose(m_file);
+
+ // clean up free list
+ while (m_head)
+ {
+ Node *node = m_head;
+ m_head = node->next;
+ delete node;
+ }
+}
+
+int Store::open(const char *name)
+{
+ int i;
+ STORE_ASSERT(m_state==Init);
+ if (m_file) return 0; // already open
+ m_file = portable_fopen(name,"w+b");
+ if (m_file==0) return -1;
+
+ // first block serves as header, so offset=0 can be used as the end of the list.
+ for (i=0;i<BLOCK_SIZE/8;i++)
+ {
+ fputc('D',m_file);
+ fputc('O',m_file);
+ fputc('X',m_file);
+ fputc('Y',m_file);
+ fputc('G',m_file);
+ fputc('E',m_file);
+ fputc('N',m_file);
+ fputc(0,m_file);
+ }
+ m_front = BLOCK_SIZE;
+ m_cur = BLOCK_SIZE;
+ m_head = 0;
+ m_state = Reading;
+ return 0;
+}
+
+void Store::close()
+{
+ if (m_file) fclose(m_file);
+ m_file=0;
+ m_state = Init;
+}
+
+portable_off_t Store::alloc()
+{
+ STORE_ASSERT(m_state==Reading);
+ m_state=Writing;
+ portable_off_t pos;
+ if (m_head==0) // allocate new block
+ {
+ //printf("alloc: new block, pos=%lld\n",(long long)m_front);
+ if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file
+ {
+ fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno));
+ exit(1);
+ }
+#if USE_FTELL
+ pos = portable_ftell(m_file);
+ STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
+ m_front = pos + BLOCK_SIZE; // move front to end of this block
+#else
+ m_cur = m_front;
+ pos = m_cur;
+ STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
+ m_front = pos + BLOCK_SIZE;
+#endif
+ }
+ else // reuse freed block
+ {
+ //printf("alloc: reuse block: pos=%lld\n",(long long)m_head->pos);
+ Node *node = m_head;
+ pos = node->pos;
+ // point head to next free item
+ m_head = node->next;
+ delete node;
+ // move to start of the block
+ if (portable_fseek(m_file,pos,SEEK_SET)==-1)
+ {
+ fprintf(stderr,"Store::alloc: Error seeking to position %d: %s\n",
+ (int)pos,strerror(errno));
+ exit(1);
+ }
+ m_cur = pos;
+ STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
+ }
+ //printf("%x: Store::alloc\n",(int)pos);
+ return pos;
+}
+
+int Store::write(const char *buf,uint size)
+{
+ STORE_ASSERT(m_state==Writing);
+ //printf("%x: Store::write\n",(int)portable_ftell(m_file));
+ do
+ {
+#if USE_FTELL
+ portable_off_t curPos = portable_ftell(m_file);
+#else
+ portable_off_t curPos = m_cur;
+#endif
+ int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)));
+ int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0;
+ int numBytes = size - bytesLeft;
+ STORE_ASSERT(bytesInBlock>=0);
+ STORE_ASSERT(numBytes<=(int)(BLOCK_SIZE-BLOCK_POINTER_SIZE));
+ if (numBytes>0)
+ {
+ if ((int)fwrite(buf,1,numBytes,m_file)!=numBytes)
+ {
+ fprintf(stderr,"Error writing: %s\n",strerror(errno));
+ exit(1);
+ }
+ m_cur+=numBytes;
+ m_writes++;
+ }
+ if (bytesLeft>0) // still more bytes to write
+ {
+#if USE_FTELL
+ STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
+#else
+ STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
+#endif
+ // allocate new block
+ if (m_head==0) // no free blocks to reuse
+ {
+ //printf("%x: Store::write: new: pos=%x\n",(int)m_front,(int)portable_ftell(m_file));
+ // write pointer to next block
+ if (fwrite(&m_front,BLOCK_POINTER_SIZE,1,m_file)!=1)
+ {
+ fprintf(stderr,"Error writing to store: %s\n",strerror(errno));
+ exit(1);
+ }
+ m_cur+=BLOCK_POINTER_SIZE;
+#if USE_FTELL
+ STORE_ASSERT(portable_ftell(m_file)==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE);
+#else
+ STORE_ASSERT(m_cur==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE);
+#endif
+ // move to next block
+ if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file
+ {
+ fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno));
+ exit(1);
+ }
+ m_cur=m_front;
+#if USE_FTELL
+ STORE_ASSERT(portable_ftell(m_file)==m_front);
+#else
+ STORE_ASSERT(m_cur==m_front);
+#endif
+ // move front to the next of the block
+ m_front+=BLOCK_SIZE;
+ }
+ else // reuse block from the free list
+ {
+ // write pointer to next block
+ if (fwrite(&m_head->pos,BLOCK_POINTER_SIZE,1,m_file)!=1)
+ {
+ fprintf(stderr,"Error writing to store: %s\n",strerror(errno));
+ exit(1);
+ }
+ Node *node = m_head;
+ portable_off_t pos = node->pos;
+ // point head to next free item
+ m_head = node->next;
+ delete node;
+ // move to start of the block
+ if (portable_fseek(m_file,pos,SEEK_SET)==-1)
+ {
+ fprintf(stderr,"Store::write: Error seeking to position %d: %s\n",
+ (int)pos,strerror(errno));
+ exit(1);
+ }
+ m_cur = pos;
+ //printf("%x: Store::write: reuse\n",(int)pos);
+ }
+ }
+ size-=numBytes;
+ buf+=numBytes;
+ }
+ while (size>0);
+ return size;
+}
+
+void Store::end()
+{
+ STORE_ASSERT(m_state==Writing);
+#if USE_FTELL
+ portable_off_t curPos = portable_ftell(m_file);
+#else
+ portable_off_t curPos = m_cur;
+#endif
+ int bytesInBlock = (int)(BLOCK_SIZE - (curPos & (BLOCK_SIZE-1)));
+ //printf("%x: Store::end erasing %x bytes\n",(int)curPos&~(BLOCK_SIZE-1),bytesInBlock);
+ //printf("end: bytesInBlock=%x\n",bytesInBlock);
+ // zero out rest of the block
+ int i;
+ for (i=0;i<bytesInBlock;i++)
+ {
+ fputc(0,m_file);
+ }
+ m_state=Reading;
+}
+
+void Store::release(portable_off_t pos)
+{
+ STORE_ASSERT(m_state==Reading);
+ //printf("release: block pos=%lld\n",(long long)pos);
+ STORE_ASSERT(pos>0 && (pos & (BLOCK_SIZE-1))==0);
+ // goto end of the block
+ portable_off_t cur = pos, next;
+ while (1)
+ {
+ // add new node to the free list
+ Node *node = new Node;
+ node->next = m_head;
+ node->pos = cur;
+
+ m_head = node;
+ // goto the end of cur block
+ if (portable_fseek(m_file,cur+BLOCK_SIZE-BLOCK_POINTER_SIZE,SEEK_SET)==-1)
+ {
+ fprintf(stderr,"Store::release: Error seeking to position %d: %s\n",
+ (int)(cur+BLOCK_SIZE-BLOCK_POINTER_SIZE),strerror(errno));
+ exit(1);
+ }
+ // read pointer to next block
+ if (fread(&next,BLOCK_POINTER_SIZE,1,m_file)!=1)
+ {
+ fprintf(stderr,"Store::release: Error reading from store: %s\n",strerror(errno));
+ exit(1);
+ }
+ m_cur = cur+BLOCK_SIZE;
+ if (next==0) break; // found end of list -> cur is last element
+ STORE_ASSERT((next & (BLOCK_SIZE-1))==0);
+ cur = next;
+ //printf("%x: Store::release\n",(int)cur);
+ }
+}
+
+void Store::seek(portable_off_t pos)
+{
+ STORE_ASSERT(m_state==Reading);
+ //printf("%x: Store::seek\n",(int)pos);
+ if (portable_fseek(m_file,pos,SEEK_SET)==-1)
+ {
+ fprintf(stderr,"Store::seek: Error seeking to position %d: %s\n",
+ (int)pos,strerror(errno));
+ exit(1);
+ }
+ m_cur = pos;
+ STORE_ASSERT((pos&(BLOCK_SIZE-1))==0);
+}
+
+int Store::read(char *buf,uint size)
+{
+ STORE_ASSERT(m_state==Reading);
+ //printf("%x: Store::read total=%d\n",(int)portable_ftell(m_file),size);
+ do
+ {
+#if USE_FTELL
+ portable_off_t curPos = portable_ftell(m_file);
+#else
+ portable_off_t curPos = m_cur;
+#endif
+ int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)));
+ int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0;
+ int numBytes = size - bytesLeft;
+ //printf(" Store::read: pos=%x num=%d left=%d\n",(int)curPos,numBytes,bytesLeft);
+
+ if (numBytes>0)
+ {
+ //printf("%x: Store::read: %d out of %d bytes\n",(int)portable_ftell(m_file),numBytes,size);
+ if ((int)fread(buf,1,numBytes,m_file)!=numBytes)
+ {
+ fprintf(stderr,"Error reading from store: %s\n",strerror(errno));
+ exit(1);
+ }
+ m_cur+=numBytes;
+ m_reads++;
+ }
+ if (bytesLeft>0)
+ {
+ portable_off_t newPos;
+ // read offset of the next block
+#if USE_FTELL
+ STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
+#else
+ STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
+#endif
+ if (fread((char *)&newPos,BLOCK_POINTER_SIZE,1,m_file)!=1)
+ {
+ fprintf(stderr,"Error reading from store: %s\n",strerror(errno));
+ exit(1);
+ }
+ //printf("%x: Store::read: continue in next block, %d bytes to go\n",(int)newPos,bytesLeft);
+ //printf(" Store::read: next block=%x\n",(int)newPos);
+ STORE_ASSERT(newPos!=0);
+ STORE_ASSERT((newPos&(BLOCK_SIZE-1))==0);
+ curPos = newPos;
+ // move to next block
+ if (portable_fseek(m_file,curPos,SEEK_SET)==-1)
+ {
+ fprintf(stderr,"Store::read: Error seeking to position %d: %s\n",
+ (int)curPos,strerror(errno));
+ exit(1);
+ }
+ m_cur = curPos;
+ }
+
+ size-=numBytes;
+ buf+=numBytes;
+ }
+ while (size>0);
+ return size;
+}
+
+void Store::printFreeList()
+{
+ printf("FreeList: ");
+ portable_off_t pos = m_head->pos;
+ while (pos)
+ {
+ printf("%x ",(int)pos);
+ m_head = m_head->next;
+ }
+ printf("\n");
+}
+
+void Store::printStats()
+{
+ printf("ObjStore: block size %d bytes, total size %ld blocks, wrote %d blocks, read %d blocks\n",
+ BLOCK_SIZE,(long)(m_front/BLOCK_SIZE),m_reads,m_writes);
+}
+
+void Store::dumpBlock(portable_off_t s,portable_off_t e)
+{
+ portable_fseek(m_file,s,SEEK_SET);
+ int size = (int)(e-s);
+ uchar *buf = new uchar[size];
+ if (fread(buf,size,1,m_file)==(size_t)size)
+ {
+ int i,j;
+ for (i=0;i<size;i+=16)
+ {
+ printf("%08x: ",(int)s+i);
+ for (j=i;j<QMIN(size,i+16);j++)
+ {
+ printf("%02x ",buf[i+j]);
+ }
+ printf(" ");
+ for (j=i;j<QMIN(size,i+16);j++)
+ {
+ printf("%c",(buf[i+j]>=32 && buf[i+j]<128)?buf[i+j]:'.');
+ }
+ printf("\n");
+ }
+ }
+ delete[] buf;
+ portable_fseek(m_file,m_cur,SEEK_SET);
+}
+
+#ifdef STORE_TEST
+
+int main()
+{
+ printf("sizeof(portable_off_t)=%d\n",(int)sizeof(portable_off_t));
+ Store s;
+ if (s.open("test.db")==0)
+ {
+ const char *str1 = "This is a test message... ";
+ const char *str2 = "Another message. ";
+
+ int i,j;
+ for (j=0;j<5;j++)
+ {
+ char buf[100];
+
+ portable_off_t handle = s.alloc();
+ for (i=0;i<1000000000;i++)
+ {
+ s.write(str1,strlen(str1)+1);
+ }
+ s.end();
+ portable_off_t handle2 = s.alloc();
+ for (i=0;i<10;i++)
+ {
+ s.write(str2,strlen(str2)+1);
+ }
+ s.end();
+
+ s.seek(handle);
+ for (i=0;i<3;i++)
+ {
+ s.read(buf,strlen(str1)+1);
+ printf("i=%d Read: %s\n",i,buf);
+ }
+
+ s.release(handle);
+
+ s.seek(handle2);
+ for (i=0;i<3;i++)
+ {
+ s.read(buf,strlen(str2)+1);
+ printf("i=%d Read: %s\n",i,buf);
+ }
+
+ s.release(handle2);
+ }
+
+ s.close();
+ }
+ else
+ {
+ printf("Open failed! %s\n",strerror(errno));
+ }
+}
+
+#endif
+
diff --git a/src/store.h b/src/store.h
new file mode 100644
index 0000000..597ea63
--- /dev/null
+++ b/src/store.h
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef STORE_H
+#define STORE_H
+
+#include <qglobal.h>
+#include <stdio.h>
+
+#include "portable.h"
+
+/*! @brief Abstract interface for file based memory storage operations */
+class StorageIntf
+{
+ public:
+ /*! Required by gcc */
+ virtual ~StorageIntf() {}
+ /*! Read \a size bytes from the store into \a buf. */
+ virtual int read(char *buf,uint size) = 0;
+ /*! Write \a size bytes from \a buf into the store. */
+ virtual int write(const char *buf,uint size) = 0;
+};
+
+/*! @brief The Store is a file based memory manager.
+ *
+ * You can open the store using open(). Then obtain a handle via alloc()
+ * followed by a sequence of write() commands to store information,
+ * and finalize it using end().
+ *
+ * Later on you locate the information
+ * with seek() using the handle obtained with alloc(), and then use a
+ * sequence of read() calls to read the information back.
+ *
+ * If no longer needed the storage space can be freed using release().
+ *
+ * The store will dynamically grow the file on disk if needed.
+ */
+class Store : public StorageIntf
+{
+ public:
+ /*! Creates a store. */
+ Store();
+
+ /*! Releases the store object. Will close the underlying file if opened. */
+ ~Store();
+
+ /*! Opens the file underlying the store using \a name as the file name.
+ * Returns 0 upon success, or -1 otherwise.
+ */
+ int open(const char *name);
+
+ /*! Allocates a handle to write to and read from. */
+ portable_off_t alloc();
+
+ /*! Writes \a size bytes in array \a buf to the store.
+ * First alloc() has to be called.
+ * \note The information can only be read after end() has been called.
+ */
+ int write(const char *buf,uint size);
+
+ /*! Ends the sequence of writes.
+ * \note After this call, first alloc() has to be called
+ * before new writes can be done.
+ */
+ void end();
+
+ /*! Releases the memory corresponding to the handle returned with alloc() */
+ void release(portable_off_t handle);
+
+ /*! Closes the store */
+ void close();
+
+ /*! Goes to the start of information corresponding to handle \a pos */
+ void seek(portable_off_t handle);
+
+ /*! Reads \a size bytes from the store into the array pointed to be \a buf.
+ * \note Before reading seek() has to be called to set the right start of the store.
+ */
+ int read(char *buf,uint size);
+
+ void printStats();
+
+ portable_off_t pos() const { return m_cur; }
+
+ void dumpBlock(portable_off_t start,portable_off_t end);
+
+ private:
+ enum State
+ {
+ Init,
+ Reading,
+ Writing
+ };
+ struct Node
+ {
+ portable_off_t pos;
+ struct Node *next;
+ };
+ void printFreeList();
+ FILE *m_file;
+ portable_off_t m_front;
+ portable_off_t m_cur;
+ Node *m_head;
+ State m_state;
+ int m_reads;
+ int m_writes;
+};
+
+#endif
diff --git a/src/svgpan.js b/src/svgpan.js
new file mode 100644
index 0000000..4218e79
--- /dev/null
+++ b/src/svgpan.js
@@ -0,0 +1,319 @@
+/**
+ * The code below is based on SVGPan Library 1.2 and was modified for doxygen
+ * to support both zooming and panning via the mouse and via embedded bottons.
+ *
+ * This code is licensed under the following BSD license:
+ *
+ * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi at itcharm.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of Andrea Leofreddi.
+ */
+
+var root = document.documentElement;
+var state = 'none';
+var stateOrigin;
+var stateTf = root.createSVGMatrix();
+var cursorGrab = ' url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRFAAAA////////c3ilYwAAAAN0Uk5T//8A18oNQQAAAD1JREFUeNp0zlEKACAIA9Bt9z90bZBZkQj29qFBEuBOzQHSnWTTyckEfqUuZgFvslH4ch3qLCO/Kr8cAgwATw4Ax6XRCcoAAAAASUVORK5CYII="), move';
+var zoomSteps = 10;
+var zoomInFactor;
+var zoomOutFactor;
+var windowWidth;
+var windowHeight;
+var svgDoc;
+var minZoom;
+var maxZoom;
+if (!window) window=this;
+
+/**
+ * Show the graph in the middle of the view, scaled to fit
+ */
+function show()
+{
+ if (window.innerHeight) // Firefox
+ {
+ windowWidth = window.innerWidth;
+ windowHeight = window.innerHeight;
+ }
+ else if (document.documentElement.clientWidth) // Chrome/Safari
+ {
+ windowWidth = document.documentElement.clientWidth
+ windowHeight = document.documentElement.clientHeight
+ }
+ if (!windowWidth || !windowHeight) // failsafe
+ {
+ windowWidth = 800;
+ windowHeight = 600;
+ }
+ minZoom = Math.min(Math.min(viewHeight,windowHeight)/viewHeight,Math.min(viewWidth,windowWidth)/viewWidth);
+ maxZoom = minZoom+1.5;
+ zoomInFactor = Math.pow(maxZoom/minZoom,1.0/zoomSteps);
+ zoomOutFactor = 1.0/zoomInFactor;
+
+ var g = svgDoc.getElementById('viewport');
+ try
+ {
+ var bb = g.getBBox(); // this can throw an exception if css { display: none }
+ var tx = (windowWidth-viewWidth*minZoom+8)/(2*minZoom);
+ var ty = viewHeight+(windowHeight-viewHeight*minZoom)/(2*minZoom);
+ var a = 'scale('+minZoom+') rotate(0) translate('+tx+' '+ty+')';
+ g.setAttribute('transform',a);
+ }
+ catch(e) {}
+}
+
+/**
+ * Register handlers
+ */
+function init(evt)
+{
+ svgDoc = evt.target.ownerDocument;
+ if (top.window && top.window.registerShow) // register show function in html doc for dynamic sections
+ {
+ top.window.registerShow(sectionId,show);
+ }
+ show();
+
+ setAttributes(root, {
+ "onmousedown" : "handleMouseDown(evt)",
+ "onmousemove" : "handleMouseMove(evt)",
+ "onmouseup" : "handleMouseUp(evt)"
+ });
+
+ if (window.addEventListener)
+ {
+ if (navigator.userAgent.toLowerCase().indexOf('webkit') >= 0 ||
+ navigator.userAgent.toLowerCase().indexOf("opera") >= 0 ||
+ navigator.appVersion.indexOf("MSIE") != -1)
+ {
+ window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari/IE9
+ }
+ else
+ {
+ window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
+ }
+ }
+}
+
+window.onresize=function()
+{
+ if (svgDoc) { show(); }
+}
+
+/**
+ * Instance an SVGPoint object with given event coordinates.
+ */
+function getEventPoint(evt)
+{
+ var p = root.createSVGPoint();
+ p.x = evt.clientX;
+ p.y = evt.clientY;
+ return p;
+}
+
+/**
+ * Sets the current transform matrix of an element.
+ */
+function setCTM(element, matrix)
+{
+ var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
+ element.setAttribute("transform", s);
+}
+
+/**
+ * Sets attributes of an element.
+ */
+function setAttributes(element, attributes)
+{
+ for (i in attributes)
+ element.setAttributeNS(null, i, attributes[i]);
+}
+
+function doZoom(g,point,zoomFactor)
+{
+ var p = point.matrixTransform(g.getCTM().inverse());
+ var k = root.createSVGMatrix().translate(p.x, p.y).scale(zoomFactor).translate(-p.x, -p.y);
+ var n = g.getCTM().multiply(k);
+ var s = Math.max(n.a,n.d);
+ if (s>maxZoom) n=n.translate(p.x,p.y).scale(maxZoom/s).translate(-p.x,-p.y);
+ else if (s<minZoom) n=n.translate(p.x,p.y).scale(minZoom/s).translate(-p.x,-p.y);
+ setCTM(g, n);
+ stateTf = stateTf.multiply(n.inverse());
+}
+
+/**
+ * Handle mouse move event.
+ */
+function handleMouseWheel(evt)
+{
+ if (!evt) evt = window.evt;
+ if (!evt.shiftKey) return; // only zoom when shift is pressed
+ if (evt.preventDefault) evt.preventDefault();
+ evt.returnValue = false;
+
+ if (state!='pan')
+ {
+ var delta;
+ if (evt.wheelDelta)
+ {
+ delta = evt.wheelDelta / 7200; // Opera/Chrome/IE9/Safari
+ }
+ else
+ {
+ delta = evt.detail / -180; // Mozilla
+ }
+ var svgDoc = evt.target.ownerDocument;
+ var g = svgDoc.getElementById("viewport");
+ var p = getEventPoint(evt);
+ doZoom(g,p,1+delta);
+ }
+}
+
+/**
+ * Handle mouse move event.
+ */
+function handleMouseMove(evt)
+{
+ if(evt.preventDefault)
+ evt.preventDefault();
+
+ evt.returnValue = false;
+
+ var g = svgDoc.getElementById("viewport");
+
+ if (state == 'pan')
+ {
+ // Pan mode
+ var p = getEventPoint(evt).matrixTransform(stateTf);
+ setCTM(g,stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
+ }
+}
+
+/**
+ * Handle click event.
+ */
+function handleMouseDown(evt)
+{
+ if(evt.preventDefault)
+ evt.preventDefault();
+ evt.returnValue = false;
+ var g = svgDoc.getElementById("viewport");
+ state = 'pan';
+ stateTf = g.getCTM().inverse();
+ stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
+ g.style.cursor = cursorGrab;
+}
+
+/**
+ * Handle mouse button release event.
+ */
+function handleMouseUp(evt)
+{
+ if (evt.preventDefault) evt.preventDefault();
+ evt.returnValue = false;
+ var g = svgDoc.getElementById("viewport");
+ g.style.cursor = "default";
+ // Quit pan mode
+ state = '';
+}
+
+/**
+ * Dumps a matrix to a string (useful for debug).
+ */
+function dumpMatrix(matrix)
+{
+ var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n 0, 0, 1 ]";
+ return s;
+}
+
+/**
+ * Handler for pan buttons
+ */
+function handlePan(x,y)
+{
+ var g = svgDoc.getElementById("viewport");
+ setCTM(g,g.getCTM().translate(x*20/minZoom,y*20/minZoom));
+}
+
+/**
+ * Handle reset button
+ */
+function handleReset()
+{
+ show();
+}
+
+/**
+ * Handler for zoom buttons
+ */
+function handleZoom(evt,direction)
+{
+ var g = svgDoc.getElementById("viewport");
+ var factor = direction=='in' ? zoomInFactor : zoomOutFactor;
+ var m = g.getCTM();
+ var p = root.createSVGPoint();
+ p.x = windowWidth/2;
+ p.y = windowHeight/2;
+ doZoom(g,p,factor);
+}
+
+function serializeXmlNode(xmlNode)
+{
+ if (typeof window.XMLSerializer != "undefined") {
+ return (new window.XMLSerializer()).serializeToString(xmlNode);
+ } else if (typeof xmlNode.xml != "undefined") {
+ return xmlNode.xml;
+ }
+ return "";
+}
+
+/**
+ * Handler for print function
+ */
+function handlePrint(evt)
+{
+ evt.returnValue = false;
+ var g = svgDoc.getElementById("graph");
+ var xs = serializeXmlNode(g);
+ try {
+ var w = window.open('about:blank','_blank','width='+windowWidth+',height='+windowHeight+
+ ',toolbar=0,status=0,menubar=0,scrollbars=0,resizable=0,location=0,directories=0');
+ var d = w.document;
+ d.write('<html xmlns="http://www.w3.org/1999/xhtml" '+
+ 'xmlns:svg="http://www.w3.org/2000/svg" '+
+ 'xmlns:xlink="http://www.w3.org/1999/xlink">');
+ d.write('<head><title>Print SVG</title></head>');
+ d.write('<body style="margin: 0px; padding: 0px;" onload="window.print();">');
+ d.write('<div id="svg" style="width:'+windowWidth+'px; height:'+windowHeight+'px;">'+xs+'</div>');
+ d.write('</body>');
+ d.write('</html>');
+ d.close();
+ } catch(e) {
+ alert('Failed to open popup window needed for printing!\n'+e.message);
+ }
+}
+
+
+
+
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
new file mode 100644
index 0000000..23b8f13
--- /dev/null
+++ b/src/tagreader.cpp
@@ -0,0 +1,1512 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "tagreader.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <qxml.h>
+#include <qstack.h>
+#include <qdict.h>
+#include <qfileinfo.h>
+#include <qlist.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include "entry.h"
+#include "classdef.h"
+#include "doxygen.h"
+#include "util.h"
+#include "message.h"
+#include "defargs.h"
+#include "arguments.h"
+#include "filedef.h"
+#include "filename.h"
+#include "section.h"
+
+/** Information about an linkable anchor */
+class TagAnchorInfo
+{
+ public:
+ TagAnchorInfo(const QCString &f,
+ const QCString &l,
+ const QCString &t=QCString())
+ : label(l), fileName(f), title(t) {}
+ QCString label;
+ QCString fileName;
+ QCString title;
+};
+
+/** List of TagAnchorInfo objects. */
+class TagAnchorInfoList : public QList<TagAnchorInfo>
+{
+ public:
+ TagAnchorInfoList() : QList<TagAnchorInfo>() { setAutoDelete(TRUE); }
+ virtual ~TagAnchorInfoList() {}
+};
+
+/** Container for enum values that are scoped within an enum */
+class TagEnumValueInfo
+{
+ public:
+ QCString name;
+ QCString file;
+ QCString anchor;
+ QCString clangid;
+};
+
+/** Container for member specific info that can be read from a tagfile */
+class TagMemberInfo
+{
+ public:
+ TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE)
+ { enumValues.setAutoDelete(TRUE); }
+ QCString type;
+ QCString name;
+ QCString anchorFile;
+ QCString anchor;
+ QCString arglist;
+ QCString kind;
+ QCString clangId;
+ TagAnchorInfoList docAnchors;
+ Protection prot;
+ Specifier virt;
+ bool isStatic;
+ QList<TagEnumValueInfo> enumValues;
+};
+
+/** Container for class specific info that can be read from a tagfile */
+class TagClassInfo
+{
+ public:
+ enum Kind { Class, Struct, Union, Interface, Exception, Protocol, Category };
+ TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); isObjC=FALSE; }
+ ~TagClassInfo() { delete bases; delete templateArguments; }
+ QCString name;
+ QCString filename;
+ QCString clangId;
+ TagAnchorInfoList docAnchors;
+ QList<BaseInfo> *bases;
+ QList<TagMemberInfo> members;
+ QList<QCString> *templateArguments;
+ QStringList classList;
+ Kind kind;
+ bool isObjC;
+};
+
+/** Container for namespace specific info that can be read from a tagfile */
+class TagNamespaceInfo
+{
+ public:
+ TagNamespaceInfo() { members.setAutoDelete(TRUE); }
+ QCString name;
+ QCString filename;
+ QCString clangId;
+ QStringList classList;
+ QStringList namespaceList;
+ TagAnchorInfoList docAnchors;
+ QList<TagMemberInfo> members;
+};
+
+/** Container for package specific info that can be read from a tagfile */
+class TagPackageInfo
+{
+ public:
+ TagPackageInfo() { members.setAutoDelete(TRUE); }
+ QCString name;
+ QCString filename;
+ TagAnchorInfoList docAnchors;
+ QList<TagMemberInfo> members;
+ QStringList classList;
+};
+
+/** Container for include info that can be read from a tagfile */
+class TagIncludeInfo
+{
+ public:
+ QCString id;
+ QCString name;
+ QCString text;
+ bool isLocal;
+ bool isImported;
+};
+
+/** Container for file specific info that can be read from a tagfile */
+class TagFileInfo
+{
+ public:
+ TagFileInfo() { members.setAutoDelete(TRUE); includes.setAutoDelete(TRUE); }
+ QCString name;
+ QCString path;
+ QCString filename;
+ TagAnchorInfoList docAnchors;
+ QList<TagMemberInfo> members;
+ QStringList classList;
+ QStringList namespaceList;
+ QList<TagIncludeInfo> includes;
+};
+
+/** Container for group specific info that can be read from a tagfile */
+class TagGroupInfo
+{
+ public:
+ TagGroupInfo() { members.setAutoDelete(TRUE); }
+ QCString name;
+ QCString title;
+ QCString filename;
+ TagAnchorInfoList docAnchors;
+ QList<TagMemberInfo> members;
+ QStringList subgroupList;
+ QStringList classList;
+ QStringList namespaceList;
+ QStringList fileList;
+ QStringList pageList;
+ QStringList dirList;
+};
+
+/** Container for page specific info that can be read from a tagfile */
+class TagPageInfo
+{
+ public:
+ QCString name;
+ QCString title;
+ QCString filename;
+ TagAnchorInfoList docAnchors;
+};
+
+/** Container for directory specific info that can be read from a tagfile */
+class TagDirInfo
+{
+ public:
+ QCString name;
+ QCString filename;
+ QCString path;
+ QStringList subdirList;
+ QStringList fileList;
+ TagAnchorInfoList docAnchors;
+};
+
+/** Tag file parser.
+ *
+ * Reads an XML-structured tagfile and builds up the structure in
+ * memory. The method buildLists() is used to transfer/translate
+ * the structures to the doxygen engine.
+ */
+class TagFileParser : public QXmlDefaultHandler
+{
+ enum State { Invalid,
+ InClass,
+ InFile,
+ InNamespace,
+ InGroup,
+ InPage,
+ InMember,
+ InEnumValue,
+ InPackage,
+ InDir,
+ InTempArgList
+ };
+ class StartElementHandler
+ {
+ typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib);
+ public:
+ StartElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
+ void operator()(const QXmlAttributes &attrib) { (m_parent->*m_handler)(attrib); }
+ private:
+ TagFileParser *m_parent;
+ Handler m_handler;
+ };
+
+ class EndElementHandler
+ {
+ typedef void (TagFileParser::*Handler)();
+ public:
+ EndElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
+ void operator()() { (m_parent->*m_handler)(); }
+ private:
+ TagFileParser *m_parent;
+ Handler m_handler;
+ };
+
+ public:
+ TagFileParser(const char *tagName) : m_startElementHandlers(17),
+ m_endElementHandlers(17),
+ m_tagName(tagName)
+ {
+ m_startElementHandlers.setAutoDelete(TRUE);
+ m_endElementHandlers.setAutoDelete(TRUE);
+ }
+
+ void setDocumentLocator ( QXmlLocator * locator )
+ {
+ m_locator = locator;
+ }
+
+ void setFileName( const QString &fileName )
+ {
+ m_inputFileName = fileName.utf8();
+ }
+
+ void warn(const char *fmt)
+ {
+ ::warn(m_inputFileName,m_locator->lineNumber(),fmt);
+ }
+ void warn(const char *fmt,const char *s)
+ {
+ ::warn(m_inputFileName,m_locator->lineNumber(),fmt,s);
+ }
+
+ void startCompound( const QXmlAttributes& attrib )
+ {
+ m_curString = "";
+ QString kind = attrib.value("kind");
+ QString isObjC = attrib.value("objc");
+ if (kind=="class")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Class;
+ m_state = InClass;
+ }
+ else if (kind=="struct")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Struct;
+ m_state = InClass;
+ }
+ else if (kind=="union")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Union;
+ m_state = InClass;
+ }
+ else if (kind=="interface")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Interface;
+ m_state = InClass;
+ }
+ else if (kind=="exception")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Exception;
+ m_state = InClass;
+ }
+ else if (kind=="protocol")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Protocol;
+ m_state = InClass;
+ }
+ else if (kind=="category")
+ {
+ m_curClass = new TagClassInfo;
+ m_curClass->kind = TagClassInfo::Category;
+ m_state = InClass;
+ }
+ else if (kind=="file")
+ {
+ m_curFile = new TagFileInfo;
+ m_state = InFile;
+ }
+ else if (kind=="namespace")
+ {
+ m_curNamespace = new TagNamespaceInfo;
+ m_state = InNamespace;
+ }
+ else if (kind=="group")
+ {
+ m_curGroup = new TagGroupInfo;
+ m_state = InGroup;
+ }
+ else if (kind=="page")
+ {
+ m_curPage = new TagPageInfo;
+ m_state = InPage;
+ }
+ else if (kind=="package")
+ {
+ m_curPackage = new TagPackageInfo;
+ m_state = InPackage;
+ }
+ else if (kind=="dir")
+ {
+ m_curDir = new TagDirInfo;
+ m_state = InDir;
+ }
+ else
+ {
+ warn("Unknown compound attribute `%s' found!\n",kind.data());
+ m_state = Invalid;
+ }
+ if (isObjC=="yes" && m_curClass)
+ {
+ m_curClass->isObjC = TRUE;
+ }
+ }
+
+ void endCompound()
+ {
+ switch (m_state)
+ {
+ case InClass: m_tagFileClasses.append(m_curClass);
+ m_curClass=0; break;
+ case InFile: m_tagFileFiles.append(m_curFile);
+ m_curFile=0; break;
+ case InNamespace: m_tagFileNamespaces.append(m_curNamespace);
+ m_curNamespace=0; break;
+ case InGroup: m_tagFileGroups.append(m_curGroup);
+ m_curGroup=0; break;
+ case InPage: m_tagFilePages.append(m_curPage);
+ m_curPage=0; break;
+ case InDir: m_tagFileDirs.append(m_curDir);
+ m_curDir=0; break;
+ case InPackage: m_tagFilePackages.append(m_curPackage);
+ m_curPackage=0; break;
+ default:
+ warn("tag `compound' was not expected!\n");
+ }
+ }
+
+ void startMember( const QXmlAttributes& attrib)
+ {
+ m_curMember = new TagMemberInfo;
+ m_curMember->kind = attrib.value("kind").utf8();
+ QCString protStr = attrib.value("protection").utf8();
+ QCString virtStr = attrib.value("virtualness").utf8();
+ QCString staticStr = attrib.value("static").utf8();
+ if (protStr=="protected")
+ {
+ m_curMember->prot = Protected;
+ }
+ else if (protStr=="private")
+ {
+ m_curMember->prot = Private;
+ }
+ if (virtStr=="virtual")
+ {
+ m_curMember->virt = Virtual;
+ }
+ else if (virtStr=="pure")
+ {
+ m_curMember->virt = Pure;
+ }
+ if (staticStr=="yes")
+ {
+ m_curMember->isStatic = TRUE;
+ }
+ m_stateStack.push(new State(m_state));
+ m_state = InMember;
+ }
+
+ void endMember()
+ {
+ m_state = *m_stateStack.top();
+ m_stateStack.remove();
+ switch(m_state)
+ {
+ case InClass: m_curClass->members.append(m_curMember); break;
+ case InFile: m_curFile->members.append(m_curMember); break;
+ case InNamespace: m_curNamespace->members.append(m_curMember); break;
+ case InGroup: m_curGroup->members.append(m_curMember); break;
+ case InPackage: m_curPackage->members.append(m_curMember); break;
+ default: warn("Unexpected tag `member' found\n"); break;
+ }
+ }
+
+ void startEnumValue( const QXmlAttributes& attrib)
+ {
+ if (m_state==InMember)
+ {
+ m_curString = "";
+ m_curEnumValue = new TagEnumValueInfo;
+ m_curEnumValue->file = attrib.value("file").utf8();
+ m_curEnumValue->anchor = attrib.value("anchor").utf8();
+ m_curEnumValue->clangid = attrib.value("clangid").utf8();
+ m_stateStack.push(new State(m_state));
+ m_state = InEnumValue;
+ }
+ else
+ {
+ warn("Found enumvalue tag outside of member tag\n");
+ }
+ }
+
+ void endEnumValue()
+ {
+ m_curEnumValue->name = m_curString.stripWhiteSpace();
+ m_state = *m_stateStack.top();
+ m_stateStack.remove();
+ if (m_state==InMember)
+ {
+ m_curMember->enumValues.append(m_curEnumValue);
+ m_curEnumValue=0;
+ }
+ }
+
+ void endDocAnchor()
+ {
+ switch(m_state)
+ {
+ case InClass: m_curClass->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InFile: m_curFile->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InNamespace: m_curNamespace->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InGroup: m_curGroup->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InPage: m_curPage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
+ case InMember: m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InPackage: m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ case InDir: m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
+ default: warn("Unexpected tag `member' found\n"); break;
+ }
+ }
+
+ void endClass()
+ {
+ switch(m_state)
+ {
+ case InClass: m_curClass->classList.append(m_curString); break;
+ case InFile: m_curFile->classList.append(m_curString); break;
+ case InNamespace: m_curNamespace->classList.append(m_curString); break;
+ case InGroup: m_curGroup->classList.append(m_curString); break;
+ case InPackage: m_curPackage->classList.append(m_curString); break;
+ default: warn("Unexpected tag `class' found\n"); break;
+ }
+ }
+
+ void endNamespace()
+ {
+ switch(m_state)
+ {
+ case InNamespace: m_curNamespace->classList.append(m_curString); break;
+ case InFile: m_curFile->namespaceList.append(m_curString); break;
+ case InGroup: m_curGroup->namespaceList.append(m_curString); break;
+ default: warn("Unexpected tag `namespace' found\n"); break;
+ }
+ }
+
+ void endFile()
+ {
+ switch(m_state)
+ {
+ case InGroup: m_curGroup->fileList.append(m_curString); break;
+ case InDir: m_curDir->fileList.append(m_curString); break;
+ default: warn("Unexpected tag `file' found\n"); break;
+ }
+ }
+
+ void endPage()
+ {
+ switch(m_state)
+ {
+ case InGroup: m_curGroup->fileList.append(m_curString); break;
+ default: warn("Unexpected tag `page' found\n"); break;
+ }
+ }
+
+ void endDir()
+ {
+ switch(m_state)
+ {
+ case InDir: m_curDir->subdirList.append(m_curString); break;
+ default: warn("Unexpected tag `page' found\n"); break;
+ }
+ }
+
+ void startStringValue(const QXmlAttributes& )
+ {
+ m_curString = "";
+ }
+
+ void startDocAnchor(const QXmlAttributes& attrib )
+ {
+ m_fileName = attrib.value("file").utf8();
+ m_title = attrib.value("title").utf8();
+ m_curString = "";
+ }
+
+ void endType()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->type = m_curString;
+ }
+ else
+ {
+ warn("Unexpected tag `type' found\n");
+ }
+ }
+
+ void endName()
+ {
+ switch (m_state)
+ {
+ case InClass: m_curClass->name = m_curString; break;
+ case InFile: m_curFile->name = m_curString; break;
+ case InNamespace: m_curNamespace->name = m_curString; break;
+ case InGroup: m_curGroup->name = m_curString; break;
+ case InPage: m_curPage->name = m_curString; break;
+ case InDir: m_curDir->name = m_curString; break;
+ case InMember: m_curMember->name = m_curString; break;
+ case InPackage: m_curPackage->name = m_curString; break;
+ default: warn("Unexpected tag `name' found\n"); break;
+ }
+ }
+
+ void startBase(const QXmlAttributes& attrib )
+ {
+ m_curString="";
+ if (m_state==InClass && m_curClass)
+ {
+ QString protStr = attrib.value("protection");
+ QString virtStr = attrib.value("virtualness");
+ Protection prot = Public;
+ Specifier virt = Normal;
+ if (protStr=="protected")
+ {
+ prot = Protected;
+ }
+ else if (protStr=="private")
+ {
+ prot = Private;
+ }
+ if (virtStr=="virtual")
+ {
+ virt = Virtual;
+ }
+ if (m_curClass->bases==0)
+ {
+ m_curClass->bases = new QList<BaseInfo>;
+ m_curClass->bases->setAutoDelete(TRUE);
+ }
+ m_curClass->bases->append(new BaseInfo(m_curString,prot,virt));
+ }
+ else
+ {
+ warn("Unexpected tag `base' found\n");
+ }
+ }
+
+ void endBase()
+ {
+ if (m_state==InClass && m_curClass)
+ {
+ m_curClass->bases->getLast()->name = m_curString;
+ }
+ else
+ {
+ warn("Unexpected tag `base' found\n");
+ }
+ }
+
+ void startIncludes(const QXmlAttributes& attrib )
+ {
+ if (m_state==InFile && m_curFile)
+ {
+ m_curIncludes = new TagIncludeInfo;
+ m_curIncludes->id = attrib.value("id").utf8();
+ m_curIncludes->name = attrib.value("name").utf8();
+ m_curIncludes->isLocal = attrib.value("local").utf8()=="yes" ? TRUE : FALSE;
+ m_curIncludes->isImported = attrib.value("imported").utf8()=="yes" ? TRUE : FALSE;
+ m_curFile->includes.append(m_curIncludes);
+ }
+ else
+ {
+ warn("Unexpected tag `includes' found\n");
+ }
+ m_curString="";
+ }
+
+ void endIncludes()
+ {
+ m_curIncludes->text = m_curString;
+ }
+
+ void endTemplateArg()
+ {
+ if (m_state==InClass && m_curClass)
+ {
+ if (m_curClass->templateArguments==0)
+ {
+ m_curClass->templateArguments = new QList<QCString>;
+ m_curClass->templateArguments->setAutoDelete(TRUE);
+ }
+ m_curClass->templateArguments->append(new QCString(m_curString));
+ }
+ else
+ {
+ warn("Unexpected tag `templarg' found\n");
+ }
+ }
+
+ void endFilename()
+ {
+ switch (m_state)
+ {
+ case InClass: m_curClass->filename = m_curString; break;
+ case InNamespace: m_curNamespace->filename = m_curString; break;
+ case InFile: m_curFile->filename = m_curString; break;
+ case InGroup: m_curGroup->filename = m_curString; break;
+ case InPage: m_curPage->filename = m_curString; break;
+ case InPackage: m_curPackage->filename = m_curString; break;
+ case InDir: m_curDir->filename = m_curString; break;
+ default: warn("Unexpected tag `filename' found\n"); break;
+ }
+ }
+
+ void endPath()
+ {
+ switch (m_state)
+ {
+ case InFile: m_curFile->path = m_curString; break;
+ case InDir: m_curDir->path = m_curString; break;
+ default: warn("Unexpected tag `path' found\n"); break;
+ }
+ }
+
+ void endAnchor()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->anchor = m_curString;
+ }
+ else
+ {
+ warn("Unexpected tag `anchor' found\n");
+ }
+ }
+
+ void endClangId()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->clangId = m_curString;
+ }
+ else if (m_state==InClass)
+ {
+ m_curClass->clangId = m_curString;
+ }
+ else if (m_state==InNamespace)
+ {
+ m_curNamespace->clangId = m_curString;
+ }
+ else
+ {
+ warn("warning: Unexpected tag `anchor' found\n");
+ }
+ }
+
+
+
+ void endAnchorFile()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->anchorFile = m_curString;
+ }
+ else
+ {
+ warn("Unexpected tag `anchorfile' found\n");
+ }
+ }
+
+ void endArglist()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->arglist = m_curString;
+ }
+ else
+ {
+ warn("Unexpected tag `arglist' found\n");
+ }
+ }
+ void endTitle()
+ {
+ switch (m_state)
+ {
+ case InGroup: m_curGroup->title = m_curString; break;
+ case InPage: m_curPage->title = m_curString; break;
+ default: warn("Unexpected tag `title' found\n"); break;
+ }
+ }
+
+ void endSubgroup()
+ {
+ if (m_state==InGroup)
+ {
+ m_curGroup->subgroupList.append(m_curString);
+ }
+ else
+ {
+ warn("Unexpected tag `subgroup' found\n");
+ }
+ }
+
+ void startIgnoreElement(const QXmlAttributes& )
+ {
+ }
+
+ void endIgnoreElement()
+ {
+ }
+
+ bool startDocument()
+ {
+ m_state = Invalid;
+
+ m_curClass=0;
+ m_curNamespace=0;
+ m_curFile=0;
+ m_curGroup=0;
+ m_curPage=0;
+ m_curPackage=0;
+ m_curDir=0;
+
+ m_stateStack.setAutoDelete(TRUE);
+ m_tagFileClasses.setAutoDelete(TRUE);
+ m_tagFileFiles.setAutoDelete(TRUE);
+ m_tagFileNamespaces.setAutoDelete(TRUE);
+ m_tagFileGroups.setAutoDelete(TRUE);
+ m_tagFilePages.setAutoDelete(TRUE);
+ m_tagFilePackages.setAutoDelete(TRUE);
+ m_tagFileDirs.setAutoDelete(TRUE);
+
+ m_startElementHandlers.insert("compound", new StartElementHandler(this,&TagFileParser::startCompound));
+ m_startElementHandlers.insert("member", new StartElementHandler(this,&TagFileParser::startMember));
+ m_startElementHandlers.insert("enumvalue", new StartElementHandler(this,&TagFileParser::startEnumValue));
+ m_startElementHandlers.insert("name", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("base", new StartElementHandler(this,&TagFileParser::startBase));
+ m_startElementHandlers.insert("filename", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("includes", new StartElementHandler(this,&TagFileParser::startIncludes));
+ m_startElementHandlers.insert("path", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("anchorfile", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("anchor", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("clangid", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("arglist", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("title", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("subgroup", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("class", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("namespace", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("file", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("dir", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("page", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("docanchor", new StartElementHandler(this,&TagFileParser::startDocAnchor));
+ m_startElementHandlers.insert("tagfile", new StartElementHandler(this,&TagFileParser::startIgnoreElement));
+ m_startElementHandlers.insert("templarg", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("type", new StartElementHandler(this,&TagFileParser::startStringValue));
+
+ m_endElementHandlers.insert("compound", new EndElementHandler(this,&TagFileParser::endCompound));
+ m_endElementHandlers.insert("member", new EndElementHandler(this,&TagFileParser::endMember));
+ m_endElementHandlers.insert("enumvalue", new EndElementHandler(this,&TagFileParser::endEnumValue));
+ m_endElementHandlers.insert("name", new EndElementHandler(this,&TagFileParser::endName));
+ m_endElementHandlers.insert("base", new EndElementHandler(this,&TagFileParser::endBase));
+ m_endElementHandlers.insert("filename", new EndElementHandler(this,&TagFileParser::endFilename));
+ m_endElementHandlers.insert("includes", new EndElementHandler(this,&TagFileParser::endIncludes));
+ m_endElementHandlers.insert("path", new EndElementHandler(this,&TagFileParser::endPath));
+ m_endElementHandlers.insert("anchorfile", new EndElementHandler(this,&TagFileParser::endAnchorFile));
+ m_endElementHandlers.insert("anchor", new EndElementHandler(this,&TagFileParser::endAnchor));
+ m_endElementHandlers.insert("clangid", new EndElementHandler(this,&TagFileParser::endClangId));
+ m_endElementHandlers.insert("arglist", new EndElementHandler(this,&TagFileParser::endArglist));
+ m_endElementHandlers.insert("title", new EndElementHandler(this,&TagFileParser::endTitle));
+ m_endElementHandlers.insert("subgroup", new EndElementHandler(this,&TagFileParser::endSubgroup));
+ m_endElementHandlers.insert("class" , new EndElementHandler(this,&TagFileParser::endClass));
+ m_endElementHandlers.insert("namespace", new EndElementHandler(this,&TagFileParser::endNamespace));
+ m_endElementHandlers.insert("file", new EndElementHandler(this,&TagFileParser::endFile));
+ m_endElementHandlers.insert("dir", new EndElementHandler(this,&TagFileParser::endDir));
+ m_endElementHandlers.insert("page", new EndElementHandler(this,&TagFileParser::endPage));
+ m_endElementHandlers.insert("docanchor", new EndElementHandler(this,&TagFileParser::endDocAnchor));
+ m_endElementHandlers.insert("tagfile", new EndElementHandler(this,&TagFileParser::endIgnoreElement));
+ m_endElementHandlers.insert("templarg", new EndElementHandler(this,&TagFileParser::endTemplateArg));
+ m_endElementHandlers.insert("type", new EndElementHandler(this,&TagFileParser::endType));
+
+ return TRUE;
+ }
+
+ bool startElement( const QString&, const QString&,
+ const QString&name, const QXmlAttributes& attrib )
+ {
+ //printf("startElement `%s'\n",name.data());
+ StartElementHandler *handler = m_startElementHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)(attrib);
+ }
+ else
+ {
+ warn("Unknown tag `%s' found!\n",name.data());
+ }
+ return TRUE;
+ }
+
+ bool endElement( const QString&, const QString&, const QString& name )
+ {
+ //printf("endElement `%s'\n",name.data());
+ EndElementHandler *handler = m_endElementHandlers[name.utf8()];
+ if (handler)
+ {
+ (*handler)();
+ }
+ else
+ {
+ warn("Unknown tag `%s' found!\n",name.data());
+ }
+ return TRUE;
+ }
+
+ bool characters ( const QString & ch )
+ {
+ m_curString+=ch.utf8();
+ return TRUE;
+ }
+
+ void dump();
+ void buildLists(Entry *root);
+ void addIncludes();
+
+ private:
+ void buildMemberList(Entry *ce,QList<TagMemberInfo> &members);
+ void addDocAnchors(Entry *e,const TagAnchorInfoList &l);
+ QList<TagClassInfo> m_tagFileClasses;
+ QList<TagFileInfo> m_tagFileFiles;
+ QList<TagNamespaceInfo> m_tagFileNamespaces;
+ QList<TagGroupInfo> m_tagFileGroups;
+ QList<TagPageInfo> m_tagFilePages;
+ QList<TagPackageInfo> m_tagFilePackages;
+ QList<TagDirInfo> m_tagFileDirs;
+ QDict<StartElementHandler> m_startElementHandlers;
+ QDict<EndElementHandler> m_endElementHandlers;
+ TagClassInfo *m_curClass;
+ TagFileInfo *m_curFile;
+ TagNamespaceInfo *m_curNamespace;
+ TagPackageInfo *m_curPackage;
+ TagGroupInfo *m_curGroup;
+ TagPageInfo *m_curPage;
+ TagDirInfo *m_curDir;
+ TagMemberInfo *m_curMember;
+ TagEnumValueInfo *m_curEnumValue;
+ TagIncludeInfo *m_curIncludes;
+ QCString m_curString;
+ QCString m_tagName;
+ QCString m_fileName;
+ QCString m_title;
+ State m_state;
+ QStack<State> m_stateStack;
+ QXmlLocator *m_locator;
+ QCString m_inputFileName;
+};
+
+/** Error handler for the XML tag file parser.
+ *
+ * Basically dumps all fatal error to stderr using err().
+ */
+class TagFileErrorHandler : public QXmlErrorHandler
+{
+ public:
+ virtual ~TagFileErrorHandler() {}
+ bool warning( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool error( const QXmlParseException & )
+ {
+ return FALSE;
+ }
+ bool fatalError( const QXmlParseException &exception )
+ {
+ err("Fatal error at line %d column %d: %s\n",
+ exception.lineNumber(),exception.columnNumber(),
+ exception.message().data());
+ return FALSE;
+ }
+ QString errorString() { return ""; }
+
+ private:
+ QString errorMsg;
+};
+
+/*! Dumps the internal structures. For debugging only! */
+void TagFileParser::dump()
+{
+ msg("Result:\n");
+ QListIterator<TagClassInfo> lci(m_tagFileClasses);
+
+ //============== CLASSES
+ TagClassInfo *cd;
+ for (;(cd=lci.current());++lci)
+ {
+ msg("class `%s'\n",cd->name.data());
+ msg(" filename `%s'\n",cd->filename.data());
+ if (cd->bases)
+ {
+ QListIterator<BaseInfo> bii(*cd->bases);
+ BaseInfo *bi;
+ for ( bii.toFirst() ; (bi=bii.current()) ; ++bii)
+ {
+ msg( " base: %s \n", bi->name.data() );
+ }
+ }
+
+ QListIterator<TagMemberInfo> mci(cd->members);
+ TagMemberInfo *md;
+ for (;(md=mci.current());++mci)
+ {
+ msg(" member:\n");
+ msg(" kind: `%s'\n",md->kind.data());
+ msg(" name: `%s'\n",md->name.data());
+ msg(" anchor: `%s'\n",md->anchor.data());
+ msg(" arglist: `%s'\n",md->arglist.data());
+ }
+ }
+ //============== NAMESPACES
+ QListIterator<TagNamespaceInfo> lni(m_tagFileNamespaces);
+ TagNamespaceInfo *nd;
+ for (;(nd=lni.current());++lni)
+ {
+ msg("namespace `%s'\n",nd->name.data());
+ msg(" filename `%s'\n",nd->filename.data());
+ QStringList::Iterator it;
+ for ( it = nd->classList.begin();
+ it != nd->classList.end(); ++it )
+ {
+ msg( " class: %s \n", (*it).latin1() );
+ }
+
+ QListIterator<TagMemberInfo> mci(nd->members);
+ TagMemberInfo *md;
+ for (;(md=mci.current());++mci)
+ {
+ msg(" member:\n");
+ msg(" kind: `%s'\n",md->kind.data());
+ msg(" name: `%s'\n",md->name.data());
+ msg(" anchor: `%s'\n",md->anchor.data());
+ msg(" arglist: `%s'\n",md->arglist.data());
+ }
+ }
+ //============== FILES
+ QListIterator<TagFileInfo> lfi(m_tagFileFiles);
+ TagFileInfo *fd;
+ for (;(fd=lfi.current());++lfi)
+ {
+ msg("file `%s'\n",fd->name.data());
+ msg(" filename `%s'\n",fd->filename.data());
+ QStringList::Iterator it;
+ for ( it = fd->namespaceList.begin();
+ it != fd->namespaceList.end(); ++it )
+ {
+ msg( " namespace: %s \n", (*it).latin1() );
+ }
+ for ( it = fd->classList.begin();
+ it != fd->classList.end(); ++it )
+ {
+ msg( " class: %s \n", (*it).latin1() );
+ }
+
+ QListIterator<TagMemberInfo> mci(fd->members);
+ TagMemberInfo *md;
+ for (;(md=mci.current());++mci)
+ {
+ msg(" member:\n");
+ msg(" kind: `%s'\n",md->kind.data());
+ msg(" name: `%s'\n",md->name.data());
+ msg(" anchor: `%s'\n",md->anchor.data());
+ msg(" arglist: `%s'\n",md->arglist.data());
+ }
+
+ QListIterator<TagIncludeInfo> mii(fd->includes);
+ TagIncludeInfo *ii;
+ for (;(ii=mii.current());++mii)
+ {
+ msg(" includes id: %s name: %s\n",ii->id.data(),ii->name.data());
+ }
+ }
+
+ //============== GROUPS
+ QListIterator<TagGroupInfo> lgi(m_tagFileGroups);
+ TagGroupInfo *gd;
+ for (;(gd=lgi.current());++lgi)
+ {
+ msg("group `%s'\n",gd->name.data());
+ msg(" filename `%s'\n",gd->filename.data());
+ QStringList::Iterator it;
+ for ( it = gd->namespaceList.begin();
+ it != gd->namespaceList.end(); ++it )
+ {
+ msg( " namespace: %s \n", (*it).latin1() );
+ }
+ for ( it = gd->classList.begin();
+ it != gd->classList.end(); ++it )
+ {
+ msg( " class: %s \n", (*it).latin1() );
+ }
+ for ( it = gd->fileList.begin();
+ it != gd->fileList.end(); ++it )
+ {
+ msg( " file: %s \n", (*it).latin1() );
+ }
+ for ( it = gd->subgroupList.begin();
+ it != gd->subgroupList.end(); ++it )
+ {
+ msg( " subgroup: %s \n", (*it).latin1() );
+ }
+ for ( it = gd->pageList.begin();
+ it != gd->pageList.end(); ++it )
+ {
+ msg( " page: %s \n", (*it).latin1() );
+ }
+
+ QListIterator<TagMemberInfo> mci(gd->members);
+ TagMemberInfo *md;
+ for (;(md=mci.current());++mci)
+ {
+ msg(" member:\n");
+ msg(" kind: `%s'\n",md->kind.data());
+ msg(" name: `%s'\n",md->name.data());
+ msg(" anchor: `%s'\n",md->anchor.data());
+ msg(" arglist: `%s'\n",md->arglist.data());
+ }
+ }
+ //============== PAGES
+ QListIterator<TagPageInfo> lpi(m_tagFilePages);
+ TagPageInfo *pd;
+ for (;(pd=lpi.current());++lpi)
+ {
+ msg("page `%s'\n",pd->name.data());
+ msg(" title `%s'\n",pd->title.data());
+ msg(" filename `%s'\n",pd->filename.data());
+ }
+ //============== DIRS
+ QListIterator<TagDirInfo> ldi(m_tagFileDirs);
+ TagDirInfo *dd;
+ for (;(dd=ldi.current());++ldi)
+ {
+ msg("dir `%s'\n",dd->name.data());
+ msg(" path `%s'\n",dd->path.data());
+ QStringList::Iterator it;
+ for ( it = dd->fileList.begin();
+ it != dd->fileList.end(); ++it )
+ {
+ msg( " file: %s \n", (*it).latin1() );
+ }
+ for ( it = dd->subdirList.begin();
+ it != dd->subdirList.end(); ++it )
+ {
+ msg( " subdir: %s \n", (*it).latin1() );
+ }
+ }
+}
+
+void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l)
+{
+ QListIterator<TagAnchorInfo> tli(l);
+ TagAnchorInfo *ta;
+ for (tli.toFirst();(ta=tli.current());++tli)
+ {
+ if (Doxygen::sectionDict->find(ta->label)==0)
+ {
+ //printf("New sectionInfo file=%s anchor=%s\n",
+ // ta->fileName.data(),ta->label.data());
+ SectionInfo *si=new SectionInfo(ta->fileName,-1,ta->label,ta->title,
+ SectionInfo::Anchor,0,m_tagName);
+ Doxygen::sectionDict->append(ta->label,si);
+ e->anchors->append(si);
+ }
+ else
+ {
+ warn("Duplicate anchor %s found\n",ta->label.data());
+ }
+ }
+}
+
+void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
+{
+ QListIterator<TagMemberInfo> mii(members);
+ TagMemberInfo *tmi;
+ for (;(tmi=mii.current());++mii)
+ {
+ Entry *me = new Entry;
+ me->type = tmi->type;
+ me->name = tmi->name;
+ me->args = tmi->arglist;
+ if (!me->args.isEmpty())
+ {
+ delete me->argList;
+ me->argList = new ArgumentList;
+ stringToArgumentList(me->args,me->argList);
+ }
+ if (tmi->enumValues.count()>0)
+ {
+ me->spec |= Entry::Strong;
+ QListIterator<TagEnumValueInfo> evii(tmi->enumValues);
+ TagEnumValueInfo *evi;
+ for (evii.toFirst();(evi=evii.current());++evii)
+ {
+ Entry *ev = new Entry;
+ ev->type = "@";
+ ev->name = evi->name;
+ ev->id = evi->clangid;
+ ev->section = Entry::VARIABLE_SEC;
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->anchor = evi->anchor;
+ ti->fileName = evi->file;
+ ev->tagInfo = ti;
+ me->addSubEntry(ev);
+ }
+ }
+ me->protection = tmi->prot;
+ me->virt = tmi->virt;
+ me->stat = tmi->isStatic;
+ me->fileName = ce->fileName;
+ me->id = tmi->clangId;
+ if (ce->section == Entry::GROUPDOC_SEC)
+ {
+ me->groups->append(new Grouping(ce->name,Grouping::GROUPING_INGROUP));
+ }
+ addDocAnchors(me,tmi->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->anchor = tmi->anchor;
+ ti->fileName = tmi->anchorFile;
+ me->tagInfo = ti;
+ if (tmi->kind=="define")
+ {
+ me->type="#define";
+ me->section = Entry::DEFINE_SEC;
+ }
+ else if (tmi->kind=="enumvalue")
+ {
+ me->section = Entry::VARIABLE_SEC;
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="property")
+ {
+ me->section = Entry::VARIABLE_SEC;
+ me->mtype = Property;
+ }
+ else if (tmi->kind=="event")
+ {
+ me->section = Entry::VARIABLE_SEC;
+ me->mtype = Event;
+ }
+ else if (tmi->kind=="variable")
+ {
+ me->section = Entry::VARIABLE_SEC;
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="typedef")
+ {
+ me->section = Entry::VARIABLE_SEC; //Entry::TYPEDEF_SEC;
+ me->type.prepend("typedef ");
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="enumeration")
+ {
+ me->section = Entry::ENUM_SEC;
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="function")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="signal")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->mtype = Signal;
+ }
+ else if (tmi->kind=="prototype")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="friend")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->type.prepend("friend ");
+ me->mtype = Method;
+ }
+ else if (tmi->kind=="dcop")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->mtype = DCOP;
+ }
+ else if (tmi->kind=="slot")
+ {
+ me->section = Entry::FUNCTION_SEC;
+ me->mtype = Slot;
+ }
+ ce->addSubEntry(me);
+ }
+}
+
+static QCString stripPath(const QCString &s)
+{
+ int i=s.findRev('/');
+ if (i!=-1)
+ {
+ return s.right(s.length()-i-1);
+ }
+ else
+ {
+ return s;
+ }
+}
+
+/*! Injects the info gathered by the XML parser into the Entry tree.
+ * This tree contains the information extracted from the input in a
+ * "unrelated" form.
+ */
+void TagFileParser::buildLists(Entry *root)
+{
+ // build class list
+ QListIterator<TagClassInfo> cit(m_tagFileClasses);
+ TagClassInfo *tci;
+ for (cit.toFirst();(tci=cit.current());++cit)
+ {
+ Entry *ce = new Entry;
+ ce->section = Entry::CLASS_SEC;
+ switch (tci->kind)
+ {
+ case TagClassInfo::Class: break;
+ case TagClassInfo::Struct: ce->spec = Entry::Struct; break;
+ case TagClassInfo::Union: ce->spec = Entry::Union; break;
+ case TagClassInfo::Interface: ce->spec = Entry::Interface; break;
+ case TagClassInfo::Exception: ce->spec = Entry::Exception; break;
+ case TagClassInfo::Protocol: ce->spec = Entry::Protocol; break;
+ case TagClassInfo::Category: ce->spec = Entry::Category; break;
+ }
+ ce->name = tci->name;
+ if (tci->kind==TagClassInfo::Protocol)
+ {
+ ce->name+="-p";
+ }
+ addDocAnchors(ce,tci->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tci->filename;
+ ce->id = tci->clangId;
+ ce->tagInfo = ti;
+ ce->lang = tci->isObjC ? SrcLangExt_ObjC : SrcLangExt_Unknown;
+ // transfer base class list
+ if (tci->bases)
+ {
+ delete ce->extends;
+ ce->extends = tci->bases; tci->bases = 0;
+ }
+ if (tci->templateArguments)
+ {
+ if (ce->tArgLists==0)
+ {
+ ce->tArgLists = new QList<ArgumentList>;
+ ce->tArgLists->setAutoDelete(TRUE);
+ }
+ ArgumentList *al = new ArgumentList;
+ ce->tArgLists->append(al);
+
+ QListIterator<QCString> sli(*tci->templateArguments);
+ QCString *argName;
+ for (;(argName=sli.current());++sli)
+ {
+ Argument *a = new Argument;
+ a->type = "class";
+ a->name = *argName;
+ al->append(a);
+ }
+ }
+
+ buildMemberList(ce,tci->members);
+ root->addSubEntry(ce);
+ }
+
+ // build file list
+ QListIterator<TagFileInfo> fit(m_tagFileFiles);
+ TagFileInfo *tfi;
+ for (fit.toFirst();(tfi=fit.current());++fit)
+ {
+ Entry *fe = new Entry;
+ fe->section = guessSection(tfi->name);
+ fe->name = tfi->name;
+ addDocAnchors(fe,tfi->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tfi->filename;
+ fe->tagInfo = ti;
+
+ QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name);
+ fe->fileName = fullName;
+ //printf("new FileDef() filename=%s\n",tfi->filename.data());
+ FileDef *fd = new FileDef(m_tagName+":"+tfi->path,
+ tfi->name,m_tagName,
+ tfi->filename
+ );
+ FileName *mn;
+ if ((mn=Doxygen::inputNameDict->find(tfi->name)))
+ {
+ mn->append(fd);
+ }
+ else
+ {
+ mn = new FileName(fullName,tfi->name);
+ mn->append(fd);
+ Doxygen::inputNameList->inSort(mn);
+ Doxygen::inputNameDict->insert(tfi->name,mn);
+ }
+ buildMemberList(fe,tfi->members);
+ root->addSubEntry(fe);
+ }
+
+ // build namespace list
+ QListIterator<TagNamespaceInfo> nit(m_tagFileNamespaces);
+ TagNamespaceInfo *tni;
+ for (nit.toFirst();(tni=nit.current());++nit)
+ {
+ Entry *ne = new Entry;
+ ne->section = Entry::NAMESPACE_SEC;
+ ne->name = tni->name;
+ addDocAnchors(ne,tni->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tni->filename;
+ ne->id = tni->clangId;
+ ne->tagInfo = ti;
+
+ buildMemberList(ne,tni->members);
+ root->addSubEntry(ne);
+ }
+
+ // build package list
+ QListIterator<TagPackageInfo> pit(m_tagFilePackages);
+ TagPackageInfo *tpgi;
+ for (pit.toFirst();(tpgi=pit.current());++pit)
+ {
+ Entry *pe = new Entry;
+ pe->section = Entry::PACKAGE_SEC;
+ pe->name = tpgi->name;
+ addDocAnchors(pe,tpgi->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tpgi->filename;
+ pe->tagInfo = ti;
+
+ buildMemberList(pe,tpgi->members);
+ root->addSubEntry(pe);
+ }
+
+ // build group list
+ QListIterator<TagGroupInfo> git(m_tagFileGroups);
+ TagGroupInfo *tgi;
+ for (git.toFirst();(tgi=git.current());++git)
+ {
+ Entry *ge = new Entry;
+ ge->section = Entry::GROUPDOC_SEC;
+ ge->name = tgi->name;
+ ge->type = tgi->title;
+ addDocAnchors(ge,tgi->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tgi->filename;
+ ge->tagInfo = ti;
+
+ buildMemberList(ge,tgi->members);
+ root->addSubEntry(ge);
+ }
+
+ // build page list
+ QListIterator<TagPageInfo> pgit(m_tagFilePages);
+ TagPageInfo *tpi;
+ for (pgit.toFirst();(tpi=pgit.current());++pgit)
+ {
+ Entry *pe = new Entry;
+ pe->section = tpi->filename=="index" ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC;
+ pe->name = tpi->name;
+ pe->args = tpi->title;
+ addDocAnchors(pe,tpi->docAnchors);
+ TagInfo *ti = new TagInfo;
+ ti->tagName = m_tagName;
+ ti->fileName = tpi->filename;
+ pe->tagInfo = ti;
+ root->addSubEntry(pe);
+ }
+}
+
+void TagFileParser::addIncludes()
+{
+ QListIterator<TagFileInfo> fit(m_tagFileFiles);
+ TagFileInfo *tfi;
+ for (fit.toFirst();(tfi=fit.current());++fit)
+ {
+ //printf("tag file tagName=%s path=%s name=%s\n",m_tagName.data(),tfi->path.data(),tfi->name.data());
+ FileName *fn = Doxygen::inputNameDict->find(tfi->name);
+ if (fn)
+ {
+ //printf("found\n");
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ //printf("input file path=%s name=%s\n",fd->getPath().data(),fd->name().data());
+ if (fd->getPath()==QCString(m_tagName+":"+tfi->path))
+ {
+ //printf("found\n");
+ QListIterator<TagIncludeInfo> mii(tfi->includes);
+ TagIncludeInfo *ii;
+ for (;(ii=mii.current());++mii)
+ {
+ //printf("ii->name=`%s'\n",ii->name.data());
+ FileName *ifn = Doxygen::inputNameDict->find(ii->name);
+ ASSERT(ifn!=0);
+ if (ifn)
+ {
+ FileNameIterator ifni(*ifn);
+ FileDef *ifd;
+ for (;(ifd=ifni.current());++ifni)
+ {
+ //printf("ifd->getOutputFileBase()=%s ii->id=%s\n",
+ // ifd->getOutputFileBase().data(),ii->id.data());
+ if (ifd->getOutputFileBase()==QCString(ii->id))
+ {
+ fd->addIncludeDependency(ifd,ii->text,ii->isLocal,ii->isImported,FALSE);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void parseTagFile(Entry *root,const char *fullName)
+{
+ QFileInfo fi(fullName);
+ if (!fi.exists()) return;
+ TagFileParser handler( fullName ); // tagName
+ handler.setFileName(fullName);
+ TagFileErrorHandler errorHandler;
+ QFile xmlFile( fullName );
+ QXmlInputSource source( xmlFile );
+ QXmlSimpleReader reader;
+ reader.setContentHandler( &handler );
+ reader.setErrorHandler( &errorHandler );
+ reader.parse( source );
+ handler.buildLists(root);
+ handler.addIncludes();
+ //handler.dump();
+}
+
+
diff --git a/src/tagreader.h b/src/tagreader.h
new file mode 100644
index 0000000..1b5f7e3
--- /dev/null
+++ b/src/tagreader.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TAGREADER_H
+#define TAGREADER_H
+
+class Entry;
+
+void parseTagFile(Entry *root,const char *fullPathName);
+
+#endif
diff --git a/src/tclscanner.h b/src/tclscanner.h
new file mode 100644
index 0000000..baa8e84
--- /dev/null
+++ b/src/tclscanner.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ * Copyright (C) 2010-2011 by Rene Zaumseil
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCANNER_TCL_H
+#define SCANNER_TCL_H
+
+#include "parserintf.h"
+
+/** \brief Tcl language parser using state-based lexical scanning.
+ *
+ * This is the Tcl language parser for doxygen.
+ */
+class TclLanguageScanner : public ParserInterface
+{
+ public:
+ virtual ~TclLanguageScanner() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char *fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+ bool needsPreprocessing(const QCString &extension);
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ void resetCodeParserState();
+ void parsePrototype(const char *text);
+};
+
+#endif
diff --git a/src/tclscanner.l b/src/tclscanner.l
new file mode 100644
index 0000000..88e3d1d
--- /dev/null
+++ b/src/tclscanner.l
@@ -0,0 +1,3095 @@
+/*****************************************************************************
+ * Parser for Tcl subset
+ *
+ * Copyright (C) 2010 by Rene Zaumseil
+ * based on the work of Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qlist.h>
+#include <qmap.h>
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <qfile.h>
+#include <qdict.h>
+
+#include "entry.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "defargs.h"
+#include "language.h"
+#include "commentscan.h"
+#include "pre.h"
+#include "tclscanner.h"
+#include "outputlist.h"
+#include "membername.h"
+#include "searchindex.h"
+#include "commentcnv.h"
+#include "bufstr.h"
+#include "portable.h"
+#include "arguments.h"
+#include "namespacedef.h"
+#include "filedef.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+#define MAX_INCLUDE_DEPTH 10
+
+//! Application error.
+#define tcl_err \
+ printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \
+ yy_push_state(ERROR); \
+ yyless(0); \
+ printf
+
+//! Application warning.
+#define tcl_war \
+ printf("Warning %d %s() at line %d: ",__LINE__,tcl.file_name.data(),yylineno); \
+ printf
+
+//! Application message.
+#define tcl_inf \
+ if (0) printf("--- %.4d %d@%d: ",__LINE__,yylineno,yy_start_stack_ptr) && printf
+
+//! Debug message.
+#define D\
+ if (0) printf("--- %.4d %d@%d: %s\n",__LINE__,yylineno,yy_start_stack_ptr,yytext);
+
+// BEGIN of copy from tclUtil.c
+// - Tcl_Interp removed
+// - changes are marked with RZ
+// #define's to adapt the code:
+#define CONST const
+#define UCHAR (unsigned char)
+#define TCL_ERROR 1
+#define TCL_OK 0
+#define ckalloc malloc
+#define ckfree free
+#define TclCopyAndCollapse(size,src,dest) memcpy(dest,src,size); *(dest+size)=0
+int TclFindElement(
+ CONST char *list, /* Points to the first byte of a string
+ * containing a Tcl list with zero or more
+ * elements (possibly in braces). */
+ int listLength, /* Number of bytes in the list's string. */
+ CONST char **elementPtr, /* Where to put address of first significant
+ * character in first element of list. */
+ CONST char **nextPtr, /* Fill in with location of character just
+ * after all white space following end of
+ * argument (next arg or end of list). */
+ int *sizePtr, /* If non-zero, fill in with size of
+ * element. */
+ int *bracePtr) /* If non-zero, fill in with non-zero/zero to
+ * indicate that arg was/wasn't in braces. */
+{
+ CONST char *p = list;
+ CONST char *elemStart; /* Points to first byte of first element. */
+ CONST char *limit; /* Points just after list's last byte. */
+ int openBraces = 0; /* Brace nesting level during parse. */
+ int inQuotes = 0;
+ int size = 0; /* lint. */
+ //RZ int numChars;
+
+ /*
+ * Skim off leading white space and check for an opening brace or quote.
+ * We treat embedded NULLs in the list as bytes belonging to a list
+ * element.
+ */
+
+ limit = (list + listLength);
+ while ((p < limit) && (isspace(UCHAR(*p))))
+ { /* INTL: ISO space. */
+ p++;
+ }
+ if (p == limit)
+ { /* no element found */
+ elemStart = limit;
+ goto done;
+ }
+
+ if (*p == '{') /* } to keep vi happy */
+ {
+ openBraces = 1;
+ p++;
+ }
+ else if (*p == '"')
+ {
+ inQuotes = 1;
+ p++;
+ }
+ elemStart = p;
+ if (bracePtr != 0)
+ {
+ *bracePtr = openBraces;
+ }
+
+ /*
+ * Find element's end (a space, close brace, or the end of the string).
+ */
+
+ while (p < limit)
+ {
+ switch (*p)
+ {
+ /*
+ * Open brace: don't treat specially unless the element is in
+ * braces. In this case, keep a nesting count.
+ */
+
+ case '{':
+ if (openBraces != 0)
+ {
+ openBraces++;
+ }
+ break;
+
+ /*
+ * Close brace: if element is in braces, keep nesting count and
+ * quit when the last close brace is seen.
+ */
+
+ case '}':
+ if (openBraces > 1)
+ {
+ openBraces--;
+ }
+ else if (openBraces == 1)
+ {
+ size = (int)(p - elemStart);
+ p++;
+ if ((p >= limit) || isspace(UCHAR(*p)))
+ { /* INTL: ISO space. */
+ goto done;
+ }
+
+ /*
+ * Garbage after the closing brace; return an error.
+ */
+
+ return TCL_ERROR;
+ }
+ break;
+
+ /*
+ * Backslash: skip over everything up to the end of the backslash
+ * sequence.
+ */
+
+ case '\\':
+ //RZ Tcl_UtfBackslash(p, &numChars, NULL);
+ //RZ p += (numChars - 1);
+ p++; //RZ
+ break;
+
+ /*
+ * Space: ignore if element is in braces or quotes; otherwise
+ * terminate element.
+ */
+
+ case ' ':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ if ((openBraces == 0) && !inQuotes)
+ {
+ size = (int)(p - elemStart);
+ goto done;
+ }
+ break;
+
+ /*
+ * Double-quote: if element is in quotes then terminate it.
+ */
+
+ case '"':
+ if (inQuotes)
+ {
+ size = (int)(p - elemStart);
+ p++;
+ if ((p >= limit) || isspace(UCHAR(*p)))
+ { /* INTL: ISO space */
+ goto done;
+ }
+
+ /*
+ * Garbage after the closing quote; return an error.
+ */
+ return TCL_ERROR;
+ }
+ break;
+ }
+ p++;
+ }
+
+ /*
+ * End of list: terminate element.
+ */
+
+ if (p == limit)
+ {
+ if (openBraces != 0)
+ {
+ return TCL_ERROR;
+ }
+ else if (inQuotes)
+ {
+ return TCL_ERROR;
+ }
+ size = (int)(p - elemStart);
+ }
+
+done:
+ while ((p < limit) && (isspace(UCHAR(*p))))
+ { /* INTL: ISO space. */
+ p++;
+ }
+ *elementPtr = elemStart;
+ *nextPtr = p;
+ if (sizePtr != 0)
+ {
+ *sizePtr = size;
+ }
+ return TCL_OK;
+}
+
+int Tcl_SplitList(
+ CONST char *list, /* Pointer to string with list structure. */
+ int *argcPtr, /* Pointer to location to fill in with the
+ * number of elements in the list. */
+ CONST char ***argvPtr) /* Pointer to place to store pointer to array
+ * of pointers to list elements. */
+{
+ CONST char **argv, *l, *element;
+ char *p;
+ int length, size, i, result, elSize, brace;
+
+ /*
+ * Figure out how much space to allocate. There must be enough space for
+ * both the array of pointers and also for a copy of the list. To estimate
+ * the number of pointers needed, count the number of space characters in
+ * the list.
+ */
+
+ for (size = 2, l = list; *l != 0; l++)
+ {
+ if (isspace(UCHAR(*l)))
+ { /* INTL: ISO space. */
+ size++;
+
+ /*
+ * Consecutive space can only count as a single list delimiter.
+ */
+
+ while (1)
+ {
+ char next = *(l + 1);
+
+ if (next == '\0')
+ {
+ break;
+ }
+ ++l;
+ if (isspace(UCHAR(next)))
+ { /* INTL: ISO space. */
+ continue;
+ }
+ break;
+ }
+ }
+ }
+ length = (int)(l - list);
+ argv = (CONST char **) ckalloc((unsigned)
+ ((size * sizeof(char *)) + length + 1));
+ for (i = 0, p = ((char *) argv) + size*sizeof(char *);
+ *list != 0; i++)
+ {
+ CONST char *prevList = list;
+
+ result = TclFindElement(list, length, &element, &list,
+ &elSize, &brace);
+ length -= (int)(list - prevList);
+ if (result != TCL_OK)
+ {
+ ckfree((char *) argv);
+ return result;
+ }
+ if (*element == 0)
+ {
+ break;
+ }
+ if (i >= size)
+ {
+ ckfree((char *) argv);
+ return TCL_ERROR;
+ }
+ argv[i] = p;
+ if (brace)
+ {
+ memcpy(p, element, (size_t) elSize);
+ p += elSize;
+ *p = 0;
+ p++;
+ }
+ else
+ {
+ TclCopyAndCollapse(elSize, element, p);
+ p += elSize+1;
+ }
+ }
+
+ argv[i] = NULL;
+ *argvPtr = argv;
+ *argcPtr = i;
+ return TCL_OK;
+}
+// END of tclUtil.c
+
+void tcl_split_list(QString &str, QStringList &list)
+{
+ int argc;
+ const char **argv;
+
+ list.clear();
+ if (str.left(1)=="{" && str.right(1)=="}")
+ {
+ str=str.mid(1,str.length()-2);
+ }
+ else if (str.left(1)=="\"" && str.right(1)=="\"")
+ {
+ str=str.mid(1,str.length()-2);
+ }
+ if (Tcl_SplitList(str.ascii(),&argc,&argv) != TCL_OK)
+ {
+ list.append(str);
+ }
+ else
+ {
+ for (int i = 0; i < argc; i++)
+ {
+ list.append(argv[i]);
+ }
+ ckfree((char *) argv);
+ }
+}
+
+//! Structure containing information about current scan context.
+typedef struct
+{
+ char type[2]; // type of scan context: "\"" "{" "[" "?" " "
+ int line0; // start line of scan context
+ int line1; // end line of scan context
+ YY_BUFFER_STATE buffer_state; // value of scan context
+ QCString ns; // current namespace
+ Entry *entry_fn; // if set contains the current proc/method/constructor/destructor
+ Entry *entry_cl; // if set contain the current class
+ Entry *entry_scan; // current scan entry
+ Protection protection; // current protections state
+ QStringList after; // option/value list (options: NULL comment keyword script)
+} tcl_scan;
+
+//* Structure containing all internal global variables.
+static struct
+{
+ CodeOutputInterface * code; // if set then we are codifying the file
+ int code_line; // current line of code
+ int code_linenumbers; // if true create line numbers in code
+ const char *code_font; // used font to codify
+ bool config_autobrief; // value of configuration option
+ QMap<QString,QString> config_subst; // map of configuration option values
+ QCString input_string; // file contents
+ int input_position; // position in file
+ QCString file_name; // name of used file
+ ParserInterface *this_parser; // myself
+ int command; // true if command was found
+ int comment; // set true if comment was scaned
+ int brace_level; // bookkeeping of braces
+ int bracket_level; // bookkeeping of brackets
+ int bracket_quote; // bookkeeping of quotes (toggles)
+ char word_is; // type of current word: "\"" "{" "[" "?" " "
+ int line_comment; // line number of comment
+ int line_commentline; // line number of comment after command
+ int line_command; // line number of command
+ int line_body0; // start line of body
+ int line_body1; // end line of body
+ QCString string_command; // contain current command
+ QCString string_commentline; // contain current comment after command
+ QCString string_commentcodify; // current comment string used in codifying
+ QCString string_comment; // contain current comment
+ QCString string_last; // contain last read word or part of word
+ QCString string; // temporary string value
+ Entry* entry_main; // top level entry
+ Entry* entry_file; // entry of current file
+ Entry* entry_current; // currently used entry
+ Entry* entry_inside; // contain entry of current scan context
+ QStringList list_commandwords; // list of command words
+ QList<tcl_scan> scan; // stack of scan contexts
+ QAsciiDict<Entry> ns; // all read namespace entries
+ QAsciiDict<Entry> cl; // all read class entries
+ QAsciiDict<Entry> fn; // all read function entries
+ QList<Entry> entry; // list of all created entries, will be deleted after codifying
+ Protection protection; // current protections state
+ MemberDef *memberdef; // contain current MemberDef when codifying
+ bool collectXRefs;
+} tcl;
+
+// scanner functions
+static int yyread(char *buf,int max_size);
+static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cls, Entry *entry_fn);
+static void tcl_scan_end();
+static void tcl_comment(int what,const char *text);
+static void tcl_word(int what,const char *text);
+static void tcl_command(int what,const char *text);
+
+// helper functions
+
+//! Create new entry.
+// @return new initialised entry
+Entry* tcl_entry_new()
+{
+ Entry *myEntry = new Entry;
+ myEntry->section = Entry::EMPTY_SEC;
+ myEntry->name = "";
+// myEntry->type = "";
+ myEntry->brief = "";
+// myEntry->doc = "";
+ myEntry->protection = Public;
+// myEntry->mtype = Method;
+// myEntry->virt = Normal;
+// myEntry->stat = FALSE;
+ myEntry->fileName = tcl.file_name;
+ myEntry->lang = SrcLangExt_Tcl;
+ initGroupInfo(myEntry);
+ // collect entries
+ if (!tcl.code)
+ {
+ tcl.entry.insert(0,myEntry);
+ }
+ return myEntry;
+}
+
+//! Set protection level.
+void tcl_protection(Entry *entry)
+{
+ if (entry->protection!=Public&&entry->protection!=Protected&&entry->protection!=Private)
+ {
+ entry->protection = tcl.protection;
+ }
+ if (entry->protection!=Protected&&entry->protection!=Private)
+ {
+ entry->protection = Public;
+ }
+}
+
+//! Check name.
+// @return 'ns' and 'name' of given current 'ns0' and 'name0'
+static void tcl_name(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
+{
+ QCString myNm;
+ int myStart;
+
+ if (qstrncmp(name0.data(),"::",2)==0)
+ {
+ myNm = name0.mid(2);
+ }
+ else if (ns0.length() && ns0 != " ")
+ {
+ myNm = ns0 + "::" + name0;
+ }
+ else
+ {
+ myNm = name0;
+ }
+ myStart = myNm.findRev("::");
+ if (myStart == -1)
+ {
+ ns = "";
+ name = myNm;
+ }
+ else
+ {
+ ns = myNm.mid(0,myStart);
+ name = myNm.mid(myStart+2);
+ }
+}
+
+//! Check name. Strip namespace qualifiers from name0 if inside inlined code segment.
+// @return 'ns' and 'name' of given current 'ns0' and 'name0'
+static void tcl_name_SnippetAware(const QCString &ns0, const QCString &name0, QCString &ns, QCString &name)
+{
+ // If we are inside an inlined code snippet then ns0
+ // already containes the complete namespace path.
+ // Any namespace qualifiers in name0 are redundant.
+ int i = name0.findRev("::");
+ if (i>=0 && tcl.memberdef)
+ {
+ tcl_name(ns0, name0.mid(i+2), ns, name);
+ }
+ else
+ {
+ tcl_name(ns0, name0, ns, name);
+ }
+}
+
+// Check and return namespace entry.
+// @return namespace entry
+Entry* tcl_entry_namespace(const QCString ns)
+{
+ Entry *myEntry;
+ if (ns.length())
+ {
+ myEntry = tcl.ns.find(ns);
+ }
+ else
+ {
+ myEntry = tcl.ns.find("::");
+ }
+ if (myEntry == NULL)
+ {
+ myEntry = tcl_entry_new();
+ myEntry->section = Entry::NAMESPACE_SEC;
+ myEntry->name = ns;
+ tcl.entry_main->addSubEntry(myEntry);
+ tcl.ns.insert(ns,myEntry);
+ }
+ return myEntry;
+}
+
+// Check and return class entry.
+// @return class entry
+Entry* tcl_entry_class(const QCString cl)
+{
+ Entry *myEntry;
+ if (!cl.length()) return(NULL);
+
+ myEntry = tcl.cl.find(cl);
+ if (myEntry == NULL)
+ {
+ myEntry = tcl_entry_new();
+ myEntry->section = Entry::CLASS_SEC;
+ myEntry->name = cl;
+ tcl.entry_main->addSubEntry(myEntry);
+ tcl.cl.insert(cl,myEntry);
+ }
+ return myEntry;
+}
+
+//! Check for keywords.
+// @return 1 if keyword and 0 otherwise
+static int tcl_keyword(QCString str)
+{
+ static QStringList myList;
+ static int myInit=1;
+ if (myInit)
+ {
+ // tcl keywords
+ myList <<"append"<<"apply"<<"array"<<"auto_execok"<<"auto_import"<<"auto_load"<<"auto_mkindex"<<"auto_qualify"<<"auto_reset";
+ myList <<"binary";
+ myList <<"catch"<<"cd"<<"close"<<"clock"<<"concat";
+ myList <<"eof"<<"eval"<<"exec"<<"exit"<<"expr";
+ myList <<"fblocked"<<"fconfigure"<<"file"<<"fileevent"<<"flush"<<"for"<<"foreach"<<"format";
+ myList <<"gets"<<"global";
+ myList <<"http";
+ myList <<"if"<<"incr"<<"info"<<"interp";
+ myList <<"join";
+ myList <<"lappend"<<"lassign"<<"lindex"<<"linsert"<<"llength"<<"load"<<"lrange"<<"lrepeat"<<"lreplace"<<"lreverse"<<"lset";
+ myList <<"namespace";
+ myList <<"package"<<"parray"<<"pid"<<"pkg_mkIndex"<<"proc"<<"puts"<<"pwd";
+ myList <<"registry"<<"rename"<<"return";
+ myList <<"scan"<<"set"<<"split"<<"string"<<"switch";
+ myList <<"tclLog"<<"tcl_endOfWord"<<"tcl_findLibrary"<<"tcl_startOfNextWord"<<"tcl_startOfPreviousWord"<<"tcl_wordBreakAfter"<<"tcl_wordBreakBefore"<<"tell"<<"time";
+ myList <<"unknown"<<"upvar";
+ myList <<"variable"<<"vwait";
+// tk keywords
+ myList <<"bell"<<"bind"<<"bindtags";
+ myList <<"clipboard"<<"console"<<"consoleinterp";
+ myList <<"destroy";
+ myList <<"event";
+ myList <<"focus";
+ myList <<"grid";
+ myList <<"lower";
+ myList <<"option";
+ myList <<"pack"<<"place";
+ myList <<"raise";
+ myList <<"send";
+ myList <<"tkerror"<<"tkwait"<<"tk_bisque"<<"tk_focusNext"<<"tk_focusPrev"<<"tk_focusFollowsMouse"<<"tk_popup"<<"tk_setPalette"<<"tk_textCut"<<"tk_TextCopy"<<"tk_textPaste"<<"chooseColor"<<"tk_chooseColor"<<"tk_chooseDirectory"<<"tk_dialog"<<"tk_getOpenFile"<<"tkDialog"<<"tk_getSaveFile"<<"tk_messageBox";
+ myList <<"winfo"<<"wm";
+ myList <<"button"<<"canvas"<<"checkbutton"<<"entry"<<"frame"<<"image"<<"label"<<"labelframe"<<"listbox"<<"menu"<<"menubutton"<<"message"<<"panedwindow"<<"radiobutton"<<"scale"<<"scrollbar"<<"spinbox"<<"toplevel";
+ myList.sort();
+ myInit=0;
+ }
+ str=str.stripWhiteSpace();
+ if (str.left(2)=="::") {str=str.mid(2);}
+ if (myList.findIndex(str) != -1) return(1);
+ return 0;
+}
+
+//! End codifying with special font class.
+static void tcl_font_end()
+{
+ if (!tcl.code) return;
+ if (tcl.code_font)
+ {
+ tcl.code->endFontClass();
+ tcl.code_font=NULL;
+ }
+}
+
+//! Codify 'str' with special font class 's'.
+static void tcl_codify(const char *s,char *str)
+{
+ if (!tcl.code || !str) return;
+ if (s && qstrcmp(s,"NULL")!=0)
+ {
+ tcl_font_end();
+ tcl.code->startFontClass(s);
+ tcl.code_font=s;
+ }
+ char *p=str,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') {}
+ if (c=='\n')
+ {
+ tcl.code_line++;
+ *(p-1)='\0';
+ tcl.code->codify(sp);
+ if (tcl.code_font)
+ {
+ tcl.code->endFontClass();
+ }
+ tcl.code->endCodeLine();
+ tcl.code->startCodeLine(tcl.code_linenumbers);
+ if (tcl.code_linenumbers)
+ {
+ tcl.code->writeLineNumber(0,0,0,tcl.code_line);
+ }
+ if (tcl.code_font)
+ {
+ tcl.code->startFontClass(tcl.code_font);
+ }
+ }
+ else
+ {
+ tcl.code->codify(sp);
+ done=TRUE;
+ }
+ }
+ tcl_font_end();
+}
+
+#if 0
+//! Codify 'str' with special font class 's'.
+static void tcl_codify(const char *s,const char *str)
+{
+ if (tcl.code==NULL) return;
+ char *tmp= (char *) malloc(strlen(str)+1);
+ strcpy(tmp, str);
+ tcl_codify(s,tmp);
+ free(tmp);
+}
+
+//! Codify 'str' with special font class 's'.
+static void tcl_codify(const char *s,const QString &str)
+{
+ if (tcl.code==NULL) return;
+ tcl_codify(s,str.utf8());
+}
+#endif
+
+//! Codify 'str' with special font class 's'.
+static void tcl_codify(const char *s,const QCString &str)
+{
+ if (!tcl.code) return;
+ tcl_codify(s,str.data());
+}
+
+static void tcl_codify_cmd(const char *s,int i)
+{
+ tcl_codify(s,(*tcl.list_commandwords.at(i)).utf8());
+}
+//! codify a string token
+//
+// codifies string according to type.
+// Starts a new scan context if needed (*myScan==0 and type == "script").
+// Returns NULL or the created scan context.
+//
+static tcl_scan *tcl_codify_token(tcl_scan *myScan, const QCString type, const QCString string)
+{
+ if (myScan != NULL)
+ {
+ if (type != NULL)
+ {
+ myScan->after << type << string;
+ }
+ else
+ {
+ myScan->after << "NULL" << string;
+ }
+ }
+ else
+ {
+ if (qstrcmp(type, "script") == 0)
+ {
+ myScan = tcl.scan.at(0);
+ myScan = tcl_scan_start('?', string,
+ myScan->ns, myScan->entry_cl, myScan->entry_fn);
+ }
+ else
+ {
+ tcl_codify((const char*)type, string);
+ }
+ }
+ return myScan;
+}
+
+//-----------------------------------------------------------------------------
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+//-----------------------------------------------------------------------------
+%}
+ws ([ \t]|\\\n)
+
+%option yylineno
+%option noyywrap
+%option stack
+
+%x ERROR
+%x TOP
+%x COMMAND
+%x WORD
+%x COMMENT
+%x COMMENT_NL
+%x COMMENT_CODE
+%x COMMENT_VERB
+%x COMMENTLINE
+%x COMMENTLINE_NL
+%%
+<ERROR>. {
+D
+ yyterminate();
+}
+<<EOF>> {
+D
+ if (tcl.scan.count()<1)
+ {// error
+D
+ tcl_err("Tcl parser stack empty! Parser error in file '%s'.\n",tcl.file_name.data());
+ yyterminate();
+ }
+ else if (tcl.scan.count()==1)
+ {// exit, check on input?
+D
+ yyterminate();
+ }
+ else
+ {// continue
+D
+ tcl_command(-1,"");
+ tcl_scan_end();
+ }
+}
+<TOP>"#" {
+D
+ yyless(0);
+ tcl.line_comment=yylineno;
+ tcl_comment(0,"");
+}
+<TOP>({ws}|[\;\n])+ {
+D
+ tcl_codify(NULL,yytext);
+}
+<TOP>. {
+D
+ yyless(0);
+ tcl.line_command=yylineno;
+ tcl_command(0,"");
+}
+
+<COMMENT>[ \t]* {
+D
+ tcl_codify("comment",yytext);
+}
+<COMMENT>"###".*\n {
+D
+ tcl_codify("comment",yytext);
+ tcl_comment(2,yytext+1);
+}
+<COMMENT>"##".*\\\n {
+D
+ tcl_codify("comment",yytext);
+ QCString t=yytext;
+ t = t.mid(2,t.length()-3);
+ t.append("\n");
+ tcl_comment(1,t.data());
+ yy_push_state(COMMENT_NL);
+}
+<COMMENT>"##".*\n {
+D
+ tcl_codify("comment",yytext);
+ tcl_comment(1,yytext+2);
+}
+<COMMENT>"#"[@\\]"code"\n[ \t]*[^#] {
+D
+ QCString t=yytext;
+ tcl_codify("comment",t.left(7));
+ tcl_comment(2,"\n at code\n");
+ yyless(7);
+ yy_push_state(COMMENT_CODE);
+}
+<COMMENT>"#"[@\\]"verbatim"\n[ \t]*[^#] {
+D
+ QCString t=yytext;
+ tcl_codify("comment",t.left(11));
+ tcl_comment(2,"\n at verbatim\n");
+ yyless(11);
+ yy_push_state(COMMENT_VERB);
+}
+<COMMENT>"#".*\\\n {
+D
+ tcl_codify("comment",yytext);
+ QCString t=yytext;
+ t = t.mid(1,t.length()-3);
+ t.append("\n");
+ tcl_comment(2,t.data());
+ yy_push_state(COMMENT_NL);
+}
+<COMMENT>"#".*\n {
+D
+ tcl_codify("comment",yytext);
+ tcl_comment(2,yytext+1);
+}
+<COMMENT>"#".*\x1A {
+D
+ QCString t=yytext;
+ t = t.mid(0,t.length()-1);
+ tcl_codify("comment",t.data());
+ t = t.mid(1,t.length());
+ tcl_comment(-2,t.data());
+ unput(0x1A);
+}
+<COMMENT>\x1A {
+D
+ tcl_comment(-2,"");
+ unput(0x1A);
+}
+<COMMENT>.|\n {
+D
+ tcl_comment(-2,yytext);
+ yyless(0);
+}
+
+<COMMENT_CODE>"#"[@\\]"endcode"\n {
+D
+ QCString t=yytext;
+ t = t.left(t.length()-10);
+ tcl_comment(2,t.data());
+ tcl_comment(2,"\n at endcode\n");
+ yy_pop_state();
+ yyless(0);
+}
+<COMMENT_CODE>.*\n {
+D
+ yymore();
+}
+<COMMENT_CODE>.*\x1A {
+D
+ yy_pop_state();
+ yyless(0);
+}
+
+<COMMENT_VERB>"#"[@\\]"endverbatim"\n {
+D
+ QCString t=yytext;
+ t = t.left(t.length()-14);
+ tcl_comment(2,t.data());
+ tcl_comment(2,"\n at endverbatim\n");
+ yy_pop_state();
+ yyless(0);
+}
+<COMMENT_VERB>.*\n {
+D
+ yymore();
+}
+<COMMENT_VERB>.*\x1A {
+D
+ yy_pop_state();
+ yyless(0);
+}
+
+<COMMENT_NL>.*\\\n {
+D
+ tcl_codify("comment",yytext);
+ tcl_comment(2,yytext);
+}
+<COMMENT_NL>.*\n {
+D
+ tcl_codify("comment",yytext);
+ tcl_comment(2,yytext);
+ yy_pop_state();
+}
+<COMMENT_NL>.*\x1A {
+D
+ yy_pop_state();
+ yyless(0);
+}
+
+<COMMENTLINE>.*\x1A {
+D
+ yy_pop_state();
+ yyless(0);
+}
+<COMMENTLINE>[ \t]* {
+D
+ tcl.string_commentcodify += yytext;
+}
+<COMMENTLINE>"#<".*\\\n {
+D
+ tcl.string_commentcodify += yytext;
+ QCString t=yytext;
+ t = t.mid(2,t.length()-4);
+ t.append("\n");
+ tcl.string_commentline += t;
+ yy_push_state(COMMENTLINE_NL);
+}
+<COMMENTLINE>"#<".*\n {
+D
+ tcl.string_commentcodify += yytext;
+ tcl.string_commentline += (yytext+2);
+}
+<COMMENTLINE>.|\n {
+D
+ yy_pop_state();
+ if (tcl.string_commentline.length())
+ {
+ tcl.entry_current->brief = tcl.string_commentline;
+ tcl.entry_current->briefLine = tcl.line_commentline;
+ tcl.entry_current->briefFile = tcl.file_name;
+ }
+ yyless(0);
+ tcl_command(-1,tcl.string_commentcodify.data());
+ tcl.string_commentline="";
+ tcl.string_commentcodify="";
+}
+
+<COMMENTLINE_NL>.*\\\n {
+D
+ tcl.string_commentcodify += yytext;
+ QCString t=yytext;
+ t = t.left(t.length()-3);
+ t.append("\n");
+ tcl.string_commentline += t;
+}
+<COMMENTLINE_NL>.*\n {
+D
+ tcl.string_commentcodify += yytext;
+ tcl.string_commentline += yytext;
+ yy_pop_state();
+}
+<COMMENTLINE_NL>.*\x1A {
+D
+ QCString t=yytext;
+ t = t.left(t.length()-1);
+ tcl.string_commentcodify += t;
+ tcl.string_commentline += t;
+ yy_pop_state();
+ unput(0x1A);
+}
+
+<COMMAND>{ws}*[\;]{ws}*"#<" {
+D
+ tcl.string_commentcodify = yytext;
+ tcl.string_commentcodify = tcl.string_commentcodify.left(tcl.string_commentcodify.length()-2);
+ tcl.string_commentline = "";
+ tcl.line_commentline = yylineno;
+ tcl.line_body1=yylineno;
+ unput('<');
+ unput('#');
+ yy_push_state(COMMENTLINE);
+}
+<COMMAND>{ws}*\x1A {
+D
+ tcl.string_commentcodify = "";
+ tcl.string_commentline = "";
+ tcl.line_body1=yylineno;
+ tcl_command(-1,"");
+}
+<COMMAND>{ws}*; {
+D
+ tcl.string_commentcodify = "";
+ tcl.string_commentline = "";
+ tcl.line_body1=yylineno;
+ tcl_command(-1,yytext);
+}
+<COMMAND>{ws}*\n {
+D
+ tcl.string_commentcodify = "";
+ tcl.string_commentline = "";
+ tcl.line_body1=yylineno-1;
+ tcl_command(-1,yytext);
+}
+<COMMAND>{ws}+ {
+D
+ tcl_command(1,yytext);
+}
+<COMMAND>"{*}". {
+D
+ tcl.word_is = ' ';
+ tcl.string_last = "{*}";
+ tcl_word(0,&yytext[3]);
+}
+<COMMAND>"\\"[\{\}\[\]\;\" \t] {
+D
+ tcl.word_is=' ';
+ tcl.string_last = "";
+ tcl_word(0,yytext);
+}
+<COMMAND>. {
+D
+ tcl.word_is=' ';
+ if (yytext[0]=='{'||yytext[0]=='['||yytext[0]=='"') tcl.word_is = yytext[0];
+ tcl.string_last = "";
+ tcl_word(0,yytext);
+}
+
+<WORD>"\\\\" |
+<WORD>"\\"[\{\}\[\]\;\" \t] {
+ tcl_word(1,yytext);
+}
+<WORD>"\\\n" {
+ tcl_word(2,yytext);
+}
+<WORD>"{" {
+ tcl_word(3,yytext);
+}
+<WORD>"}" {
+ tcl_word(4,yytext);
+}
+<WORD>"[" {
+ tcl_word(5,yytext);
+}
+<WORD>"]" {
+ tcl_word(6,yytext);
+}
+<WORD>"\"" {
+ tcl_word(7,yytext);
+}
+<WORD>" " {
+ tcl_word(8,yytext);
+}
+<WORD>"\t" {
+ tcl_word(9,yytext);
+}
+<WORD>";" {
+ tcl_word(10,yytext);
+}
+<WORD>"\n" {
+ tcl_word(11,yytext);
+}
+<WORD>\x1A {
+ tcl_word(12,yytext);
+}
+<WORD>. {
+ tcl_word(1,yytext);
+}
+%%
+
+//! Start new scan context for given 'content'.
+// @return created new scan context.
+static tcl_scan *tcl_scan_start(char type, QString content, QCString ns, Entry *entry_cl, Entry *entry_fn)
+{
+ tcl_scan *myScan=tcl.scan.at(0);
+ QCString myName;
+tcl_inf("line=%d type=%d '%s'\n",tcl.line_body0,type,content.ascii());
+
+ myScan->line1=yylineno;
+ yy_push_state(TOP);
+
+ myScan=new tcl_scan;
+ myScan->type[0] =' ';
+ myScan->type[1] = '\0';
+ switch (type) {
+ case '"':
+ case '{':
+ case '[':
+ myScan->type[0] = type;
+ break;
+ case '?':
+ if (content[0]=='"' && content[content.length()-1]=='"') myScan->type[0]='"';
+ if (content[0]=='{' && content[content.length()-1]=='}') myScan->type[0]='{';
+ if (content[0]=='[' && content[content.length()-1]==']') myScan->type[0]='[';
+ }
+ if (myScan->type[0]!=' ')
+ {
+ tcl_codify(NULL,&myScan->type[0]);
+ content = content.mid(1,content.length()-2);
+ }
+ content += (char)0x1A;// for detection end of scan context
+ myScan->ns = ns;
+ myScan->entry_cl = entry_cl;
+ myScan->entry_fn = entry_fn;
+ myScan->entry_scan = tcl.entry_current;
+ myScan->buffer_state=yy_scan_string(content.ascii());
+ myScan->line0=tcl.line_body0;
+ myScan->line1=tcl.line_body1;
+ myScan->after.clear();
+ yylineno=myScan->line0;
+ myScan->protection = tcl.protection;
+
+ tcl.entry_inside = myScan->entry_scan;
+ tcl.entry_current = tcl_entry_new();
+ tcl.scan.insert(0,myScan);
+ yy_switch_to_buffer(myScan->buffer_state);
+ return (myScan);
+}
+
+//! Close current scan context.
+static void tcl_scan_end()
+{
+ tcl_scan *myScan=tcl.scan.at(0);
+ tcl_scan *myScan1=tcl.scan.at(1);
+tcl_inf("line=%d\n",myScan->line1);
+
+ if (myScan->type[0]=='{') myScan->type[0]='}';
+ if (myScan->type[0]=='[') myScan->type[0]=']';
+ if (myScan->type[0]!=' ') tcl_codify(NULL,&myScan->type[0]);
+ int myStart=-1;
+ for (unsigned int i=0;i<myScan->after.count();i=i+2)
+ {
+ if (myScan->after[i]=="script") {
+ myStart=i;
+ break;
+ }
+ tcl_codify(myScan->after[i].utf8(),myScan->after[i+1].utf8());
+ }
+ yy_delete_buffer(myScan->buffer_state);
+ yy_pop_state();
+ tcl.entry_inside = myScan1->entry_scan;
+ yy_switch_to_buffer(myScan1->buffer_state);
+ yylineno=myScan1->line1;
+ tcl.protection = myScan1->protection;
+ if (myStart>=0)
+ {
+ myScan1 = tcl_scan_start('?', myScan->after[myStart+1], myScan->ns, myScan->entry_cl, myScan->entry_fn);
+ for (unsigned int i=myStart+2;i<myScan->after.count();i++)
+ {
+ myScan1->after.append(myScan->after[i]);
+ }
+ tcl.scan.remove(1);
+ }
+ else
+ {
+ tcl.scan.removeFirst();
+ }
+}
+
+//! Handling of word parsing.
+static void tcl_word(int what,const char *text)
+{
+ static char myList[1024]="";// nesting level list
+ static int myLevel=0;// number of current nesting level
+ static int myWhite=0;// set true when next char should be whitespace
+ static char myWord;// internal state
+
+ switch (what)
+ {
+ case 0:// start
+ yy_push_state(WORD);
+ switch (text[0])
+ {
+ case '{':
+ case '[':
+ case '"': myWord = text[0]; break;
+ default: myWord = '.';
+ }
+ myList[0]=myWord;
+ myLevel=1;
+ myWhite=0;
+ break;
+ case 1:// all other chars
+ if (myWhite)
+ {// {x}y "x"y
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ if (myLevel==0)
+ {
+ myWord='.';
+ myList[0]=myWord;
+ myLevel=1;
+ }
+ break;
+ case 2:// \\\n
+ if (myLevel==0)
+ {
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ case '[':
+ case '"':
+ break;
+ case '.':
+ if (myLevel==1)
+ {
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(\\\n) ?%s?\n",tcl.string_last.data());
+ return;
+ }
+ break;
+ }
+ myWhite=0;
+ break;
+ case 3:// {
+ if (myWhite)
+ {// {x}{ "x"{
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ case '[':
+ myList[myLevel++]='{';
+ break;
+ case '"':
+ case '.':
+ break;
+ }
+ myWhite=0;
+ break;
+ case 4:// }
+ if (myWhite)
+ {// {x}{ "x"{
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':// {{x}}
+ myLevel--;
+ if (myLevel==0 && !tcl.code)
+ {
+ myWhite=1;
+ }
+ break;
+ case '[':
+ case '"':
+ case '.':
+ break;
+ }
+ break;
+ case 5:// [
+ if (myWhite)
+ {// {x}[
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ break;
+ case '[':
+ case '"':
+ case '.':
+ myList[myLevel++]='[';
+ break;
+ }
+ myWhite=0;
+ break;
+ case 6:// ]
+ if (myWhite)
+ {// {x}]
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ break;
+ case '[':
+ myLevel--;
+ break;
+ case '"':
+ case '.':
+ break;
+ }
+ myWhite=0;
+ break;
+ case 7:// "
+ if (myWhite)
+ {// {x}"
+ tcl_err("expected word separator: %s\n",text);
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ break;
+ case '[':
+ myList[myLevel++]='"';
+ break;
+ case '"':
+ myLevel--;
+ case '.':
+ break;
+ }
+ break;
+ case 8:// ' '
+ case 9:// \t
+ case 10:// ;
+ case 11:// \n
+ if (myLevel==0)
+ {
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
+ return;
+ }
+ switch (myList[myLevel-1])
+ {
+ case '{':
+ case '[':
+ case '"':
+ break;
+ case '.':
+ if (myLevel==1)
+ {
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
+ return;
+ }
+ else
+ {
+ myLevel--;
+ }
+ break;
+ }
+ myWhite=0;
+ break;
+ case 12:// \x1A
+ if (myLevel==0)
+ {
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(%d) ?%s?\n",what,tcl.string_last.data());
+ return;
+ }
+ if (myLevel!=1 || myList[0] != '.')
+ {
+ tcl_war("level=%d expected=%c\n",myLevel,myList[myLevel-1]);
+ }
+ myWord=' ';
+ yy_pop_state();
+ yyless(0);
+tcl_inf("(.%d) ?%s?\n",what,tcl.string_last.data());
+ return;
+ myWhite=0;
+ break;
+ default:
+ tcl_err("wrong state: %d\n",what);
+ return;
+ }
+ tcl.string_last += text;
+}
+
+//! Handling of comment parsing.
+static void tcl_comment(int what,const char *text)
+{
+ if (what==0)
+ { // begin of comment
+ if (tcl.comment)
+ {
+ tcl_err("comment in comment\n");
+ return;
+ }
+ yy_push_state(COMMENT);
+tcl_inf("<- %s\n",text);
+ tcl.string_comment="";
+ tcl.comment=0;
+ }
+ else if (what==1)
+ { // start new comment
+ if (tcl.comment)
+ {
+ tcl_comment(99,""); // inbody
+ }
+ tcl.string_comment=text;
+ tcl.comment=1;
+ }
+ else if (what==2)
+ { // add to comment
+ if (tcl.comment)
+ {
+ tcl.string_comment+=text;
+ }
+ }
+ else if (what==-1 || what == -2)
+ { // end of comment without/with command
+ if (tcl.comment)
+ {
+ tcl.string_last=tcl.string_comment;
+ tcl_comment(100+what,"");
+ }
+ else
+ {
+ tcl.string_last = "";
+tcl_inf("-> %s\n",(const char *)tcl.string_comment);
+ }
+ yy_pop_state();
+ tcl.string_comment="";
+ tcl.comment=0;
+ }
+ else if (what==98 || what==99)
+ { // 98=new 99=inbody
+ if (tcl.this_parser && tcl.string_comment.length())
+ {
+tcl_inf("-> %s\n",(const char *)tcl.string_comment);
+ int myPos=0;
+ bool myNew=0;
+ int myLine=tcl.line_comment;
+ BufStr myI(1024);
+ BufStr myO(1024);
+ Protection myProt=tcl.protection;
+
+ // resolve ALIASES
+ myI.addArray("/*!",3);
+ myI.addArray(tcl.string_comment.data(),tcl.string_comment.length());
+ myI.addArray("*/",2);
+ convertCppComments(&myI,&myO,tcl.file_name);
+ myO.dropFromStart(3);
+ myO.shrink(myO.curPos()-2);
+ myO.addChar('\0');
+ QCString myDoc = myO.data();
+ if (what==99)
+ { // inbody comment file or namespace or class or proc/method
+ int myPos0;
+ int myLine0;
+ Entry myEntry0; // used to test parsing
+ Entry *myEntry;
+
+ Entry *myEntry1=NULL;
+ if (tcl.scan.at(0)->entry_fn)
+ {
+ myEntry1=tcl.scan.at(0)->entry_fn;
+ }
+ else if (tcl.scan.at(0)->entry_cl)
+ {
+ myEntry1=tcl.scan.at(0)->entry_cl;
+ }
+
+ myPos0=myPos;
+ myLine0=myLine;
+ while (parseCommentBlock(tcl.this_parser, &myEntry0, myDoc, tcl.file_name,
+ myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew))
+ {
+ if (myNew)
+ { // we need a new entry in this case
+ myNew=0;
+ myEntry = tcl_entry_new();
+ parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
+ myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
+ tcl.entry_inside->addSubEntry(myEntry);
+ }
+ else
+ { // we can add to current entry in this case
+ if (!myEntry1)
+ {
+ myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
+ }
+ parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
+ myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
+ }
+ myPos0=myPos;
+ myLine0=myLine;
+ }
+ if (myNew)
+ { // we need a new entry
+ myNew=0;
+ myEntry = tcl_entry_new();
+ parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name,
+ myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
+ tcl.entry_inside->addSubEntry(myEntry);
+ }
+ else
+ { // we can add to current entry
+ if (!myEntry1)
+ {
+ myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns);
+ }
+ parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name,
+ myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew);
+ }
+ }
+ else
+ { // new entry
+ tcl.entry_current = tcl_entry_new();
+ while (parseCommentBlock(tcl.this_parser, tcl.entry_current, myDoc,
+ tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE,
+ myProt, myPos, myNew))
+ {
+ if (myNew)
+ {
+ tcl.entry_inside->addSubEntry(tcl.entry_current);
+ tcl.entry_current = tcl_entry_new();
+ }
+ else
+ {
+ tcl.entry_current->section = tcl.entry_inside->section;
+ tcl.entry_current->name = tcl.entry_inside->name;
+ }
+ }
+ if (myNew)
+ {
+ tcl.entry_inside->addSubEntry(tcl.entry_current);
+ tcl.entry_current = tcl_entry_new();
+ }
+ else
+ {
+ tcl.entry_current->section = tcl.entry_inside->section;
+ tcl.entry_current->name = tcl.entry_inside->name;
+ }
+ }
+ if (tcl.protection != myProt)
+ {
+ tcl.scan.at(0)->protection = tcl.protection = myProt;
+ }
+ }
+ }
+ else
+ {
+ tcl_err("what %d\n",what);
+ return;
+ }
+}
+
+//! Parse given \c arglist .
+static void tcl_command_ARGLIST(QString &arglist)
+{
+D
+ Argument *myArg;
+ QStringList myArgs;
+ QString myArglist="";
+
+ if (!tcl.entry_current->argList)
+ {
+ tcl.entry_current->argList=new ArgumentList;
+ }
+ tcl_split_list(arglist,myArgs);
+ for (uint i=0;i<myArgs.count();i++)
+ {
+ QStringList myArgs1;
+ myArg=new Argument;
+
+ tcl_split_list(*myArgs.at(i),myArgs1);
+ if (myArgs1.count()==2)
+ {
+ myArg->name= (*myArgs1.at(0)).utf8();
+ myArg->defval= (*myArgs1.at(1)).utf8();
+ if (myArg->defval.isEmpty())
+ {
+ myArg->defval = " ";
+ }
+ myArglist += "?" + QCString(myArg->name) + "? ";
+ }
+ else
+ {
+ myArg->name= (*myArgs.at(i)).utf8();
+ myArglist += QString(myArg->name) + " ";
+ }
+ tcl.entry_current->argList->append(myArg);
+ }
+ arglist = myArglist;
+ tcl.entry_current->args = arglist.utf8();
+}
+
+//! Create link.
+static void tcl_codify_link(QCString name)
+{
+ if (tcl.code == NULL || name.isEmpty()) return;
+ static int init=0;
+ static QAsciiDict<MemberDef> fn;
+ if (init==0)
+ {
+ init=1;
+ MemberNameSDict::Iterator mni(*Doxygen::memberNameSDict);
+ MemberNameSDict::Iterator fni(*Doxygen::functionNameSDict);
+ MemberName *mn=0;
+ MemberDef *md;
+ for (mni.toFirst();(mn=mni.current());++mni)
+ {
+ MemberNameIterator mi(*mn);
+ for (mi.toFirst();(md=mi.current());++mi)
+ {
+ fn.insert(md->qualifiedName(),md);
+ }
+ }
+ for (fni.toFirst();(mn=fni.current());++fni)
+ {
+ MemberNameIterator fi(*mn);
+ for (fi.toFirst();(md=fi.current());++fi)
+ {
+ fn.insert(md->qualifiedName(),md);
+ }
+ }
+ }
+ MemberDef *myDef;
+ QCString myName=name;
+ if (name.mid(0,2)=="::") // fully qualified global command
+ {
+ myName = myName.mid(2);
+ myDef = fn.find(myName);
+ }
+ else // not qualified name
+ {
+ QCString myName1=myName;
+ myDef = NULL;
+ myName1 = tcl.scan.at(0)->ns;
+ if (myName1 == " " || myName1 == "")
+ {
+ myName1 = myName;
+ }
+ else
+ {
+ myName1 = myName1 + "::" + myName;
+ }
+ myDef = fn.find(myName1); // search namespace command
+ if (myDef == NULL)
+ {
+ myDef = fn.find(myName); // search global command
+ }
+ }
+ if (myDef != NULL) // documented command
+ {
+ tcl.code->writeCodeLink(myDef->getReference().data(),
+ myDef->getOutputFileBase().data(),
+ myDef->anchor().data(),
+ name,
+ myDef->qualifiedName().data());
+ if (tcl.memberdef)
+ {
+ myDef->addSourceReferencedBy(tcl.memberdef);
+ tcl.memberdef->addSourceReferences(myDef);
+ } else {
+ Entry* callerEntry;
+ unsigned int i;
+ // walk the stack of scan contexts and find the enclosing method or proc
+ for (i=0;i<tcl.scan.count();i++)
+ {
+ callerEntry=tcl.scan.at(i)->entry_scan;
+ if (callerEntry->mtype==Method && !callerEntry->name.isEmpty())
+ {
+ break;
+ }
+ }
+ if (i<tcl.scan.count())
+ {
+ // enclosing method found
+ QCString callerName = callerEntry->name;
+ if (callerName.mid(0,2)=="::") // fully qualified global command
+ {
+ callerName = callerName.mid(2);
+ }
+ else
+ {
+ if (!(tcl.scan.at(0)->ns.stripWhiteSpace().isEmpty()))
+ {
+ callerName = tcl.scan.at(0)->ns + "::" + callerEntry->name;
+ }
+ }
+ MemberDef *callerDef=NULL;
+ callerDef = fn.find(callerName);
+ if (callerDef!=NULL && myDef!= NULL && tcl.collectXRefs)
+ {
+ addDocCrossReference(callerDef,myDef);
+ }
+ }
+ }
+ }
+ else if (tcl_keyword(myName)) // check keyword
+ {
+ tcl_codify("keyword",name);
+ }
+ else
+ {
+ tcl_codify(NULL,name); // something else
+ }
+
+}
+
+//! scan general argument for brackets
+//
+// parses (*tcl.list_commandwords.at(i)).utf8() and checks for brackets.
+// Starts a new scan context if needed (*myScan==0 and brackets found).
+// Returns NULL or the created scan context.
+//
+static tcl_scan *tcl_command_ARG(tcl_scan *myScan, unsigned int i, bool ignoreOutermostBraces)
+{
+ QCString myName;
+ bool insideQuotes=false;
+ unsigned int insideBrackets=0;
+ unsigned int insideBraces=0;
+ myName = (*tcl.list_commandwords.at(i)).utf8();
+ if (i%2 != 0)
+ {
+ // handle white space
+ myScan = tcl_codify_token(myScan, "NULL", myName);
+ }
+ else
+ {
+ QCString myStr = "";
+ unsigned int j;
+ for (j=0;j<myName.length();j++)
+ {
+ QChar c = myName[j];
+ bool backslashed = false;
+ if (j>0)
+ {
+ backslashed = myName[j-1]=='\\';
+ }
+ // this is a state machine
+ // input is c
+ // internal state is myScan and insideXXX
+ // these are the transitions:
+ if (c=='[' && !backslashed && insideBraces==0)
+ {
+ insideBrackets++;
+ }
+ if (c==']' && !backslashed && insideBraces==0 && insideBrackets>0)
+ {
+ insideBrackets--;
+ }
+ if (c=='{' && !backslashed && !insideQuotes && !(ignoreOutermostBraces && j==0))
+ {
+ insideBraces++;
+ }
+ if (c=='}' && !backslashed && !insideQuotes && insideBraces>0)
+ {
+ insideBraces--;
+ }
+ if (c=='"' && !backslashed && insideBraces==0)
+ {
+ insideQuotes=!insideQuotes;
+ }
+ // all output, depending on state and input
+ if (c=='[' && !backslashed && insideBrackets==1 && insideBraces==0)
+ {
+ // the first opening bracket, output what we have so far
+ myStr+=c;
+ myScan = tcl_codify_token(myScan, "NULL", myStr);
+ myStr="";
+ }
+ else if (c==']' && !backslashed && insideBrackets==0 && insideBraces==0)
+ {
+ // the last closing bracket, start recursion, switch to deferred
+ myScan = tcl_codify_token(myScan, "script", myStr);
+ myStr="";
+ myStr+=c;
+ }
+ else
+ {
+ myStr+=c;
+ }
+ }
+ if (i == 0 && myScan == NULL)
+ {
+ tcl_codify_link(myStr);
+ }
+ else
+ {
+ myScan = tcl_codify_token(myScan, "NULL", myStr);
+ }
+ }
+ return (myScan);
+}
+
+//! Handle internal tcl commands.
+// "eval arg ?arg ...?"
+static void tcl_command_EVAL()
+{
+D
+ tcl_codify_cmd("keyword", 0);
+ tcl_scan *myScan = tcl.scan.at(0);
+ QCString myString = "";
+ // we simply rescan the line without the eval
+ // we include leading whitespace because tcl_scan_start will examine
+ // the first char. If it finds a bracket it will assume one expression in brackets.
+ // Example: eval [list set] [list NotInvoked] [Invoked NotInvoked]
+ for (unsigned int i = 1; i < tcl.list_commandwords.count(); i++)
+ {
+ myString += (*tcl.list_commandwords.at(i)).utf8();
+ }
+ myScan = tcl_scan_start('?', myString,
+ myScan->ns, myScan->entry_cl, myScan->entry_fn);
+}
+
+//! Handle internal tcl commands.
+// switch ?options? string pattern body ?pattern body ...?
+// switch ?options? string {pattern body ?pattern body ...?}
+static void tcl_command_SWITCH()
+{
+D
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_scan *myScan=NULL;
+ unsigned int i;
+ QCString token;
+ // first: find the last option token
+ unsigned int lastOptionIndex = 0;
+ for (i = 2; i<tcl.list_commandwords.count(); i += 2)
+ {
+ token = (*tcl.list_commandwords.at(i)).utf8();
+ if (token == "--")
+ {
+ lastOptionIndex = i;
+ break;
+ }
+ if (token[0] == '-' && i - lastOptionIndex == 2)
+ {
+ // options start with dash and should form a continuous chain
+ lastOptionIndex = i;
+ }
+ }
+ // second: eat up options
+ for (i = 2; i <= lastOptionIndex; i++)
+ {
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+ // third: how many tokens are left?
+ if (tcl.list_commandwords.count() - lastOptionIndex == 5)
+ {
+ //printf("syntax: switch ?options? string {pattern body ?pattern body ...?}\n");
+ myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
+ myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
+ myScan = tcl_command_ARG(myScan, lastOptionIndex + 3, false);
+ // walk trough the list step by step
+ // this way we can preserve whitespace
+ bool inBraces = false;
+ bool nextIsPattern = true;
+ int size;
+ const char *elem;
+ const char *next;
+ token = (*tcl.list_commandwords.at(lastOptionIndex + 4)).utf8();
+ if (token[0] == '{')
+ {
+ inBraces = true;
+ token = token.mid(1, token.length() - 2);
+ myScan = tcl_codify_token(myScan, "NULL", QCString("{"));
+ }
+ // ToDo: check if multibyte chars are handled correctly
+ while (token.length() > 0)
+ {
+ TclFindElement((const char*)token, token.length(), &elem, &next, &size, NULL);
+ //printf("%s\nstart=%d, elem=%d, next=%d, size=%d, brace=%d\n",
+ // (const char*) token, (const char*) token, elem, next, size, brace);
+ //
+ // handle leading whitespace/opening brace/double quotes
+ if (elem - token > 0)
+ {
+ myScan = tcl_codify_token(myScan, "NULL", token.left(elem - token));
+ }
+ // handle actual element without braces/double quotes
+ if (nextIsPattern)
+ {
+ myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token,size));
+ //printf("pattern=%s\n",(const char*) token.mid(elem - token, size));
+ }
+ else {
+ myScan = tcl_codify_token(myScan, "script", token.mid(elem - token, size));
+ //printf("script =%s\n", (const char*) token.mid(elem - token, size));
+ }
+ // handle trailing whitespace/closing brace/double quotes
+ if (next - elem - size > 0)
+ {
+ myScan = tcl_codify_token(myScan, "NULL", token.mid(elem - token + size, next - elem - size));
+ }
+ nextIsPattern = !nextIsPattern;
+ token = token.mid(next - token);
+ }
+ if (inBraces)
+ {
+ myScan = tcl_codify_token(myScan, "NULL", QCString("}"));
+ }
+ if (!nextIsPattern)
+ {
+ tcl_war("Invalid switch syntax: last token is not a list of even elements.\n");
+ //tcl_war("%s\n", tcl.list_commandwords.join(" ").ascii());
+ }
+ }
+ else if ((tcl.list_commandwords.count() - lastOptionIndex > 6) &&
+ ((tcl.list_commandwords.count() - lastOptionIndex-3) % 4 == 0))
+ {
+ //printf("detected: switch ?options? string pattern body ?pattern body ...?\n");
+ myScan = tcl_command_ARG(myScan, lastOptionIndex + 1, false);
+ myScan = tcl_command_ARG(myScan, lastOptionIndex + 2, false);
+ //printf("value=%s\n",(const char*) (*tcl.list_commandwords.at(lastOptionIndex + 2)).utf8());
+ for (i = lastOptionIndex + 3; i < tcl.list_commandwords.count(); i += 4)
+ {
+ myScan = tcl_command_ARG(myScan, i + 0, false); // whitespace
+ myScan = tcl_command_ARG(myScan, i + 1, false); // pattern
+ myScan = tcl_command_ARG(myScan, i + 2, false); // whitespace
+ myScan = tcl_codify_token(myScan, "script", (*tcl.list_commandwords.at(i+3)).utf8()); // script
+ //printf("pattern=%s\n",(const char*) (*tcl.list_commandwords.at(i+1)).utf8());
+ //printf("script=%s\n",(const char*) (*tcl.list_commandwords.at(i+3)).utf8());
+ }
+ }
+ else
+ {
+ // not properly detected syntax
+ tcl_war("Invalid switch syntax: %d options followed by %d tokens.\n",
+ lastOptionIndex / 2, (tcl.list_commandwords.count() - 1) / 2 - lastOptionIndex / 2);
+ for (i = lastOptionIndex + 1; i <= tcl.list_commandwords.count(); i++)
+ {
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+ }
+}
+
+//! Handle internal tcl commands.
+// "catch script ?resultVarName? ?optionsVarName?"
+static void tcl_command_CATCH()
+{
+D
+ tcl_codify_cmd("keyword", 0);
+ tcl_codify_cmd(NULL, 1);
+ tcl_scan *myScan = tcl.scan.at(0);
+ myScan = tcl_scan_start('?', *tcl.list_commandwords.at(2),
+ myScan->ns, myScan->entry_cl, myScan->entry_fn);
+ for (unsigned int i = 3; i < tcl.list_commandwords.count(); i++)
+ {
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+}
+
+//! Handle internal tcl commands.
+// "if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?"
+static void tcl_command_IF(QStringList type)
+{
+D
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_scan *myScan = NULL;
+ myScan = tcl_command_ARG(myScan, 2, true);
+ for (unsigned int i = 3;i<tcl.list_commandwords.count();i++)
+ {
+ if (type[i] == "expr")
+ {
+ myScan = tcl_command_ARG(myScan, i, true);
+ }
+ else
+ {
+ if (myScan!=0)
+ {
+ myScan->after << type[i] << tcl.list_commandwords[i];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(i),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ }
+ }
+ }
+}
+//! Handle internal tcl commands.
+// "for start test next body"
+static void tcl_command_FOR()
+{
+D
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_scan *myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(2),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ myScan->after << "NULL" << tcl.list_commandwords[3];
+ myScan = tcl_command_ARG(myScan, 4, true);
+ myScan->after << "NULL" << tcl.list_commandwords[5];
+ myScan->after << "script" << tcl.list_commandwords[6];
+ myScan->after << "NULL" << tcl.list_commandwords[7];
+ myScan->after << "script" << tcl.list_commandwords[8];
+}
+
+///! Handle internal tcl commands.
+// "foreach varname list body" and
+// "foreach varlist1 list1 ?varlist2 list2 ...? body"
+static void tcl_command_FOREACH()
+{
+D
+ unsigned int i;
+ tcl_scan *myScan=NULL;
+ tcl_codify_cmd("keyword",0);
+ for (i = 1;i<tcl.list_commandwords.count()-1;i++)
+ {
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+ if (myScan!=0)
+ {
+ myScan->after << "script" << tcl.list_commandwords[tcl.list_commandwords.count()-1];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(tcl.list_commandwords.count()-1),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ }
+}
+
+///! Handle internal tcl commands.
+// "while test body"
+static void tcl_command_WHILE()
+{
+D
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_scan *myScan = NULL;
+ myScan = tcl_command_ARG(myScan, 2, true);
+ myScan = tcl_command_ARG(myScan, 3, false);
+ if (myScan!=0)
+ {
+ myScan->after << "script" << tcl.list_commandwords[4];
+ }
+ else
+ {
+ myScan=tcl.scan.at(0);
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(4),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ }
+}
+
+//! Handle all other commands.
+// Create links of first command word or first command word inside [].
+static void tcl_command_OTHER()
+{
+ tcl_scan *myScan=NULL;
+ for (unsigned int i=0; i< tcl.list_commandwords.count(); i++)
+ {
+ myScan = tcl_command_ARG(myScan, i, false);
+ }
+}
+
+//! Handle \c proc statements.
+static void tcl_command_PROC()
+{
+D
+ QCString myNs, myName;
+ Entry *myEntryNs;
+ Entry *myEntry;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd(NULL,2);
+ tcl_codify_cmd(NULL,3);
+ tcl_codify_cmd(NULL,4);
+ tcl_codify_cmd(NULL,5);
+ tcl_name_SnippetAware(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myEntryNs = tcl_entry_namespace(myNs);
+ }
+ else
+ {
+ myEntryNs = tcl_entry_namespace(myScan->ns);
+ }
+ //why not needed here? tcl.fn.remove(myName);
+ tcl.entry_current->section = Entry::FUNCTION_SEC;
+ tcl.entry_current->mtype = Method;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
+ myEntryNs->addSubEntry(tcl.entry_current);
+ myEntry = tcl.entry_current;
+ tcl.fn.insert(myName,myEntry);
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
+ myEntryNs->name,NULL,myEntry);
+}
+
+//! Handle \c itcl::body statements and \c oo::define method and method inside \c itcl::class statements.
+static void tcl_command_METHOD()
+{
+D
+ QCString myNs, myName;
+ Entry *myEntryCl, *myEntry;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd(NULL,2);
+ tcl_codify_cmd(NULL,3);
+ tcl_codify_cmd(NULL,4);
+ tcl_codify_cmd(NULL,5);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myEntryCl = tcl_entry_class(myNs);
+ }
+ else
+ {
+ myNs = myScan->ns;
+ myEntryCl = myScan->entry_cl;
+ }
+ // needed in case of more then one definition p.e. itcl::method and itcl::body
+ // see also bug #
+ tcl.fn.remove(myName);
+ tcl.entry_current->section = Entry::FUNCTION_SEC;
+ tcl.entry_current->mtype = Method;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ tcl_command_ARGLIST(*tcl.list_commandwords.at(4));
+ myEntryCl->addSubEntry(tcl.entry_current);
+ tcl.fn.insert(myName,tcl.entry_current);
+ myEntry = tcl.entry_current;
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
+ myNs, myEntryCl, myEntry);
+}
+
+//! Handle \c constructor statements inside class definitions.
+static void tcl_command_CONSTRUCTOR()
+{
+D
+ QCString myNs, myName;
+ Entry *myEntryCl, *myEntry;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd(NULL,2);
+ tcl_codify_cmd(NULL,3);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myEntryCl = tcl_entry_class(myNs);
+ }
+ else
+ {
+ myNs = myScan->ns;
+ myEntryCl = myScan->entry_cl;
+ }
+ tcl.entry_current->section = Entry::FUNCTION_SEC;
+ tcl.entry_current->mtype = Method;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ tcl_command_ARGLIST(*tcl.list_commandwords.at(2));
+ if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
+ myEntry = tcl.entry_current;
+ tcl.fn.insert(myName,myEntry);
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
+ myNs, myEntryCl, myEntry);
+}
+
+//! Handle \c destructor statements inside class definitions.
+static void tcl_command_DESTRUCTOR()
+{
+D
+ QCString myNs, myName;
+ Entry *myEntryCl, *myEntry;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(0)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myEntryCl = tcl_entry_class(myNs);
+ }
+ else
+ {
+ myNs = myScan->ns;
+ myEntryCl = myScan->entry_cl;
+ }
+ tcl.entry_current->section = Entry::FUNCTION_SEC;
+ tcl.entry_current->mtype = Method;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ myEntryCl->addSubEntry(tcl.entry_current);
+ myEntry = tcl.entry_current;
+ tcl.fn.insert(myName,myEntry);
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2),
+ myNs, myEntryCl, myEntry);
+}
+
+//! Handle \c namespace statements.
+static void tcl_command_NAMESPACE()
+{
+D
+ QCString myNs, myName, myStr;
+ //Entry *myEntryNs=NULL;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd("keyword",2);
+ tcl_codify_cmd(NULL,3);
+ tcl_codify_cmd(NULL,4);
+ tcl_codify_cmd(NULL,5);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myName = myNs+"::"+myName;
+ }
+ tcl.entry_current->section = Entry::NAMESPACE_SEC;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl.entry_main->addSubEntry(tcl.entry_current);
+ tcl.ns.insert(myName,tcl.entry_current);
+ //myEntryNs = tcl.entry_current;
+ myStr = (*tcl.list_commandwords.at(6)).utf8();
+ if (tcl.list_commandwords.count() > 7)
+ {
+ for (uint i=7;i<tcl.list_commandwords.count();i++)
+ {
+ myStr.append((*tcl.list_commandwords.at(i)).utf8());
+ }
+ tcl.word_is=' ';
+ }
+ myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL);
+}
+
+//! Handle \c itcl::class statements.
+static void tcl_command_ITCL_CLASS()
+{
+D
+ QCString myNs, myName, myStr;
+ Entry *myEntryCl;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd("NULL",2);
+ tcl_codify_cmd("NULL",3);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myName = myNs+"::"+myName;
+ }
+ tcl.entry_current->section = Entry::CLASS_SEC;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl.entry_main->addSubEntry(tcl.entry_current);
+ tcl.cl.insert(myName,tcl.entry_current);
+ myEntryCl = tcl.entry_current;
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4),
+ myName, myEntryCl, NULL);
+}
+
+//! Handle \c oo::class statements.
+static void tcl_command_OO_CLASS()
+{
+D
+ QCString myNs, myName, myStr;
+ //Entry *myEntryNs;
+ Entry *myEntryCl;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd("NULL",2);
+ tcl_codify_cmd("NULL",3);
+ tcl_codify_cmd("NULL",4);
+ tcl_codify_cmd("NULL",5);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myName = myNs+"::"+myName;
+ }
+ tcl.entry_current->section = Entry::CLASS_SEC;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl.entry_main->addSubEntry(tcl.entry_current);
+ //myEntryNs = tcl_entry_namespace(myName);
+ tcl.cl.insert(myName,tcl.entry_current);
+ myEntryCl = tcl.entry_current;
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6),
+ myName, myEntryCl, NULL);
+}
+
+//! Handle \c oo::define statements.
+static void tcl_command_OO_DEFINE()
+{
+D
+ QCString myNs, myName, myStr;
+ Entry *myEntryCl;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl_codify_cmd("NULL",2);
+ tcl_codify_cmd("NULL",3);
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
+ if (myNs.length())
+ {
+ myName = myNs+"::"+myName;
+ }
+ myEntryCl = tcl_entry_class(myName);
+ myStr = (*tcl.list_commandwords.at(4)).utf8();
+ //
+ // special cases first
+ // oo::define classname method methodname args script
+ // oo::define classname constructor argList bodyScript
+ // oo::define classname destructor bodyScript
+ unsigned int n =tcl.list_commandwords.count();
+ if ((myStr == "method" && n == 11) ||
+ (myStr == "constructor" && n == 9) ||
+ (myStr == "destructor" && n == 7))
+ {
+ for (unsigned int i = 4; i < n-1; i++)
+ {
+ tcl_codify_cmd("NULL",i);
+ }
+ Entry *myEntry;
+ QCString myMethod;
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(n==11?6:4)).utf8(),myNs,myMethod);
+ // code snippet taken from tcl_command_METHOD()/tcl_command_CONSTRUCTOR
+ tcl.fn.remove(myMethod);
+ tcl.entry_current->section = Entry::FUNCTION_SEC;
+ tcl.entry_current->mtype = Method;
+ tcl.entry_current->name = myMethod;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ if (n==11)
+ {
+ tcl_command_ARGLIST(*tcl.list_commandwords.at(8));
+ }
+ else if (n==9)
+ {
+ tcl_command_ARGLIST(*tcl.list_commandwords.at(6));
+ }
+ if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current);
+ tcl.fn.insert(myMethod,tcl.entry_current);
+ myEntry = tcl.entry_current;
+ myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1),
+ myNs, myEntryCl, myEntry);
+ }
+ else
+ {
+ // The general case
+ // Simply concat all arguments into a script.
+ // Note: all documentation collected just before the
+ // oo::define command is lost
+ if (tcl.list_commandwords.count() > 5)
+ {
+ for (uint i=5;i<tcl.list_commandwords.count();i++)
+ {
+ myStr.append((*tcl.list_commandwords.at(i)).utf8());
+ }
+ tcl.word_is=' ';
+ }
+ myScan = tcl_scan_start(tcl.word_is,myStr,myName,myEntryCl,NULL);
+ }
+}
+
+//! Handle \c variable statements.
+static void tcl_command_VARIABLE(int inclass)
+{
+D
+ QCString myNs, myName;
+ Entry *myEntry;
+ tcl_scan *myScan = tcl.scan.at(0);
+
+ tcl_codify_cmd("keyword",0);
+ for (unsigned int i=1; i< tcl.list_commandwords.count(); i++)
+ {
+ tcl_codify_cmd(NULL,i);
+ }
+ tcl_name(myScan->ns,(*tcl.list_commandwords.at(2)).utf8(),myNs,myName);
+ if (myNs.length())
+ {// qualified variables go into namespace
+ myEntry = tcl_entry_namespace(myNs);
+ tcl.entry_current->stat = true;
+ }
+ else
+ {
+ if (inclass)
+ {
+ myEntry = myScan->entry_cl;
+ tcl.entry_current->stat = false;
+ }
+ else
+ {
+ myEntry = tcl_entry_namespace(myScan->ns);
+ tcl.entry_current->stat = true;
+ }
+ }
+ tcl.entry_current->section = Entry::VARIABLE_SEC;
+ tcl.entry_current->name = myName;
+ tcl.entry_current->startLine = tcl.line_command;
+ tcl.entry_current->bodyLine = tcl.line_body0;
+ tcl.entry_current->endBodyLine = tcl.line_body1;
+ tcl_protection(tcl.entry_current);
+ myEntry->addSubEntry(tcl.entry_current);
+ tcl.entry_current = tcl_entry_new();
+}
+
+//! Handling of command parsing.
+//! what=0 -> ...
+//! what=1 -> ...
+//! what=-1 -> ...
+static void tcl_command(int what,const char *text)
+{
+ int myLine=0;
+ if (what==0)
+ {
+ tcl.scan.at(0)->line1=yylineno;// current line in scan context
+ tcl.line_body0=yylineno;// start line of command
+tcl_inf("<- %s\n",text);
+ yy_push_state(COMMAND);
+ tcl.list_commandwords.clear();
+ tcl.string_command="";
+ tcl.string_last="";
+ tcl.command=1;
+ return;
+ }
+ else if (what==1)
+ {
+ if (tcl.string_last.length())
+ {
+ tcl.list_commandwords.append(tcl.string_last);
+ tcl.string_last="";
+ }
+ if (text)
+ {
+ tcl.list_commandwords.append(text);
+ }
+ return;
+ }
+ else if (what!=-1)
+ {// should not happen
+ tcl_err("what %d\n",what);
+ return;
+ }
+ QCString myText = text;
+tcl_inf("->\n");
+ if (tcl.command==0)
+ {
+ return; //TODO check on inside comment
+ }
+ if (tcl.string_last != "")
+ {// get last word
+ tcl.list_commandwords.append(tcl.string_last);
+ tcl.string_last="";
+ }
+ yy_pop_state();
+
+ // check command
+ QCString myStr = (*tcl.list_commandwords.at(0)).utf8();
+ tcl_scan *myScanBackup=tcl.scan.at(0);
+ int myLevel = 0;
+ Protection myProt = tcl.protection;
+
+ if (tcl.list_commandwords.count() < 3)
+ {
+ tcl_command_OTHER();
+ goto command_end;
+ }
+ // remove leading "::" and apply TCL_SUBST
+ if (myStr.left(2)=="::") myStr = myStr.mid(2);
+ if (tcl.config_subst.contains(myStr))
+ {
+ myStr=tcl.config_subst[myStr].utf8();
+ }
+ if (myStr=="private")
+ {
+ tcl.protection = Private;
+ myLevel = 1;
+ }
+ else if (myStr=="protected")
+ {
+ tcl.protection = Protected;
+ myLevel = 1;
+ }
+ else if (myStr=="public")
+ {
+ tcl.protection = Public;
+ myLevel = 1;
+ }
+ if (myLevel)
+ {
+ tcl_codify_cmd("keyword",0);
+ tcl_codify_cmd(NULL,1);
+ tcl.list_commandwords.remove(tcl.list_commandwords.at(1));
+ tcl.list_commandwords.remove(tcl.list_commandwords.at(0));
+ if (tcl.list_commandwords.count()==1)
+ {
+ tcl_scan *myScan = tcl.scan.at(0);
+ myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(0),
+ myScan->ns,myScan->entry_cl,myScan->entry_fn);
+ myProt = tcl.protection;
+ goto command_end;
+ }
+ myStr = (*tcl.list_commandwords.at(0)).utf8();
+ // remove leading "::" and apply TCL_SUBST
+ if (myStr.left(2)=="::") myStr = myStr.mid(2);
+ if (tcl.config_subst.contains(myStr))
+ {
+ myStr=tcl.config_subst[myStr].utf8();
+ }
+ }
+ if (myStr=="proc")
+ {
+ if (tcl.list_commandwords.count() == 5)
+ {// itcl::proc
+ tcl.list_commandwords.append("");
+ tcl.list_commandwords.append("");
+ }
+ if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
+ tcl_command_PROC();
+ goto command_end;
+ }
+ if (myStr=="method")
+ {
+ if (tcl.list_commandwords.count() == 5)
+ {// itcl::method
+ tcl.list_commandwords.append("");
+ tcl.list_commandwords.append("");
+ }
+ if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
+ tcl_command_METHOD();
+ goto command_end;
+ }
+ if (myStr=="constructor")
+ {
+ if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
+ tcl_command_CONSTRUCTOR();
+ goto command_end;
+ }
+ if (myStr=="destructor")
+ {
+ if (tcl.list_commandwords.count() != 3) {myLine=__LINE__;goto command_warn;}
+ tcl_command_DESTRUCTOR();
+ goto command_end;
+ }
+ if (myStr=="namespace")
+ {
+ if ((*tcl.list_commandwords.at(2)).utf8()=="eval")
+ {
+ if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;}
+ tcl_command_NAMESPACE();
+ goto command_end;
+ }
+ tcl_command_OTHER();
+ goto command_end;
+ }
+ if (myStr=="itcl::class")
+ {
+ if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
+ tcl_command_ITCL_CLASS();
+ goto command_end;
+ }
+ if (myStr=="itcl::body")
+ {
+ if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
+ tcl_command_METHOD();
+ goto command_end;
+ }
+ if (myStr=="oo::class")
+ {
+ if ((*tcl.list_commandwords.at(2)).utf8()=="create")
+ {
+ if (tcl.list_commandwords.count() != 7) {myLine=__LINE__;goto command_warn;}
+ tcl_command_OO_CLASS();
+ goto command_end;
+ }
+ tcl_command_OTHER();
+ goto command_end;
+ }
+ if (myStr=="oo::define")
+ {
+ if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
+ tcl_command_OO_DEFINE();
+ goto command_end;
+ }
+ if (myStr=="variable")
+ {
+ if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
+ if (tcl.scan.at(0)->entry_fn == NULL)
+ {// only parsed outside functions
+ tcl_command_VARIABLE(tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="");
+ goto command_end;
+ }
+ }
+ if (myStr=="common")
+ {
+ if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
+ if (tcl.scan.at(0)->entry_fn == NULL)
+ {// only parsed outside functions
+ tcl_command_VARIABLE(0);
+ goto command_end;
+ }
+ }
+ if (myStr=="inherit" || myStr=="superclass")
+ {
+ if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
+ if (tcl.scan.at(0)->entry_cl && tcl.scan.at(0)->entry_cl->name!="")
+ {
+ for (unsigned int i = 2; i < tcl.list_commandwords.count(); i = i + 2)
+ {
+ tcl.scan.at(0)->entry_cl->extends->append(new BaseInfo((*tcl.list_commandwords.at(i)).utf8(),Public,Normal));
+ }
+ }
+ goto command_end;
+ }
+ /*
+ * Start of internal tcl keywords
+ * Ready: switch, eval, catch, if, for, foreach, while
+ */
+ if (myStr=="switch")
+ {
+ if (tcl.list_commandwords.count() < 5) {myLine=__LINE__;goto command_warn;}
+ tcl_command_SWITCH();
+ goto command_end;
+ }
+ if (myStr=="eval")
+ {
+ if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
+ tcl_command_EVAL();
+ goto command_end;
+ }
+ if (myStr=="catch")
+ {
+ if (tcl.list_commandwords.count() < 3) {myLine=__LINE__;goto command_warn;}
+ tcl_command_CATCH();
+ goto command_end;
+ }
+ if (myStr=="for")
+ {
+ if (tcl.list_commandwords.count() != 9) {myLine=__LINE__;goto command_warn;}
+ tcl_command_FOR();
+ goto command_end;
+ }
+ if (myStr=="foreach")
+ {
+ if (tcl.list_commandwords.count() < 7 || tcl.list_commandwords.count()%2==0) {myLine=__LINE__;goto command_warn;}
+ tcl_command_FOREACH();
+ goto command_end;
+ }
+ /*
+if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
+ */
+ if (myStr=="if" && tcl.list_commandwords.count() > 4)
+ {
+ QStringList myType;
+ myType << "keyword" << "NULL" << "expr" << "NULL";
+ char myState='x';// last word: e'x'pr 't'hen 'b'ody 'e'lse else'i'f..
+ for (unsigned int i = 4; i < tcl.list_commandwords.count(); i = i + 2)
+ {
+ QCString myStr=(*tcl.list_commandwords.at(i)).utf8();
+ if (myState=='x')
+ {
+ if (myStr=="then")
+ {
+ myState='t';
+ myType << "keyword" << "NULL";
+ }
+ else
+ {
+ myState='b';
+ myType << "script" << "NULL";
+ }
+ }
+ else if (myState=='t')
+ {
+ myState='b';
+ myType << "script" << "NULL";
+ }
+ else if (myState=='b')
+ {
+ if (myStr=="elseif") {
+ myState='i';
+ myType << "keyword" << "NULL";
+ }
+ else if (myStr=="else" && i==tcl.list_commandwords.count()-3)
+ {
+ myState = 'b';
+ myType << "keyword" << "NULL" << "script";
+ i = tcl.list_commandwords.count();
+ }
+ else if (i==tcl.list_commandwords.count()-1)
+ {
+ myState = 'b';
+ myType << "script";
+ i = tcl.list_commandwords.count();
+ }
+ else
+ {
+ myLine=__LINE__;goto command_warn;
+ }
+ }
+ else if (myState=='i')
+ {
+ myState='x';
+ myType << "expr" << "NULL";
+ }
+ }
+ if (myState != 'b') {myLine=__LINE__;goto command_warn;}
+ tcl_command_IF(myType);
+ goto command_end;
+ }
+ if (myStr=="while")
+ {
+ if (tcl.list_commandwords.count() != 5) {myLine=__LINE__;goto command_warn;}
+ tcl_command_WHILE();
+ goto command_end;
+ }
+ tcl_command_OTHER();
+ goto command_end;
+ command_warn:// print warning message because of wrong used syntax
+ tcl_war("%d count=%d: %s\n",myLine,tcl.list_commandwords.count(),tcl.list_commandwords.join(" ").ascii());
+ tcl_command_OTHER();
+ command_end:// add remaining text to current context
+ if (!myText.isEmpty())
+ {
+ if(myScanBackup==tcl.scan.at(0))
+ {
+ tcl_codify("comment",myText);
+ }
+ else
+ {
+ tcl.scan.at(0)->after << "comment" << myText;
+ }
+ }
+ tcl.list_commandwords.clear();
+ tcl.command = 0;
+ tcl.protection = myProt;
+}
+
+//----------------------------------------------------------------------------
+//! Common initializations.
+static void tcl_init()
+{
+ // Get values from option TCL_SUBST
+ tcl.config_subst.clear();
+ if (Config::instance()->get("TCL_SUBST"))
+ {
+ QStrList myStrList = Config_getList("TCL_SUBST");
+ const char *s=myStrList.first();
+ while (s)
+ {
+ QCString myStr=s;
+ int i=myStr.find('=');
+ if (i>0)
+ {
+ QCString myName=myStr.left(i).stripWhiteSpace();
+ QCString myValue=myStr.right(myStr.length()-i-1).stripWhiteSpace();
+ if (!myName.isEmpty() && !myValue.isEmpty())
+tcl_inf("TCL_SUBST: use '%s'\n",s);
+ tcl.config_subst[myName] = myValue;
+ }
+ s = myStrList.next();
+ }
+ }
+
+ if (tcl.input_string.at(tcl.input_string.length()-1) == '\n')
+ {
+ tcl.input_string[tcl.input_string.length()-1] = 0x1A;
+ }
+ else
+ {
+ tcl.input_string += 0x1A;
+ }
+ tcl.code = NULL;
+ tcl.code_font=NULL;
+ tcl.code_line=1;
+ tcl.code_linenumbers=1;
+ tcl.config_autobrief = Config_getBool("JAVADOC_AUTOBRIEF");
+ tcl.input_position = 0;
+ tcl.file_name = NULL;
+ tcl.this_parser = NULL;
+ tcl.command=0;
+ tcl.comment=0;
+ tcl.brace_level=0;
+ tcl.bracket_level=0;
+ tcl.bracket_quote=0;
+ tcl.word_is=' ';
+ tcl.string_command="";
+ tcl.string_commentline="";
+ tcl.string_commentcodify="";
+ tcl.string_comment = "";
+ tcl.string_last = "";
+ tcl.entry_main = NULL;
+ tcl.entry_file = NULL;
+ tcl.entry_current = NULL;
+ tcl.entry_inside = NULL;
+ tcl.list_commandwords.clear();
+ tcl.scan.clear();
+ tcl.ns.clear();
+ tcl.cl.clear();
+ tcl.fn.clear();
+ yylineno = 1;
+ tcl.protection = Public;
+ tcl.memberdef = NULL;
+}
+
+//! Start parsing.
+static void tcl_parse(const QCString ns, const QCString cls)
+{
+ tcl_scan *myScan;
+
+ tcl.entry_file = tcl_entry_new();
+ tcl.entry_file->name = tcl.file_name;
+ tcl.entry_file->section = Entry::SOURCE_SEC;
+ tcl.entry_file->protection = Public;
+ tcl.entry_main->addSubEntry(tcl.entry_file);
+ Entry *myEntry=tcl_entry_new();
+ myEntry->name="";
+ tcl.entry_main->addSubEntry(myEntry);
+ tcl.ns.insert("::",myEntry);
+ tcl.entry_current = tcl_entry_new();
+
+ tclscannerYYrestart( tclscannerYYin );
+ BEGIN( TOP );
+ yylineno=1;
+ myScan = new tcl_scan;
+ myScan->type[0]=' ';myScan->type[1]='\n';
+ myScan->after.clear();
+ myScan->line0=yylineno;
+ myScan->line1=yylineno;
+ myScan->buffer_state=YY_CURRENT_BUFFER;
+ myScan->ns=ns;
+ myScan->entry_cl=tcl_entry_class(cls);
+ myScan->entry_fn=NULL;
+ tcl.entry_inside = tcl.entry_file;
+ myScan->entry_scan = tcl.entry_inside;
+ tcl.scan.insert(0,myScan);
+ tclscannerYYlex();
+ tcl.scan.clear();
+ tcl.ns.clear();
+ tcl.cl.clear();
+ tcl.fn.clear();
+ tcl.entry.clear();
+}
+
+//! Parse text file and build up entry tree.
+void TclLanguageScanner::parseInput(const char *fileName,
+ const char *input,
+ Entry *root,
+ bool /*sameTranslationUnit*/,
+ QStrList & /*filesInSameTranslationUnit*/)
+{
+ QFile myFile;
+tcl_inf("%s\n",fileName);
+ myFile.setName(fileName);
+ if (!myFile.open(IO_ReadOnly)) return;
+ if (strlen(input)<1) return;
+
+ tcl.input_string = input;
+ if (tcl.input_string.length()<1) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fileName);
+
+ msg("Parsing %s...\n",fileName);
+ groupEnterFile(fileName,yylineno);
+
+ tcl_init();
+ tcl.code = NULL;
+ tcl.file_name = fileName;
+ tcl.this_parser = this;
+ tcl.entry_main = root; /* toplevel entry */
+ tcl_parse("","");
+ groupLeaveFile(tcl.file_name,yylineno);
+ root->program.resize(0);
+ myFile.close();
+ printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+}
+
+//! Parse file and codify.
+void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
+ const char * scopeName,
+ const QCString & input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char * exampleName,
+ FileDef * fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+ (void)scopeName;
+ (void)lang;
+ (void)exampleName;
+ (void)fileDef;
+ (void)endLine;
+ (void)inlineFragment;
+ (void)searchCtx;
+ (void)collectXRefs;
+
+ if (input.length()<1) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
+ tcl.input_string = input;
+
+ QCString myNs="";
+ QCString myCls="";
+ if (memberDef)
+ {
+ if (memberDef->getClassDef())
+ {
+ myCls = memberDef->getClassDef()->displayName();
+ myNs = myCls;
+ }
+ else if (memberDef->getNamespaceDef())
+ {
+ myNs = memberDef->getNamespaceDef()->displayName();
+ }
+ }
+
+ QString myStr="Codifying..";
+ if (scopeName)
+ {
+ myStr +=" scope=";
+ myStr+=scopeName;
+ }
+ if (exampleName)
+ {
+ myStr+=" example=";
+ myStr+=exampleName;
+ }
+ if (memberDef)
+ {
+ myStr+=" member=";
+ myStr+=memberDef->memberTypeName();
+ myStr+=" ";
+ myStr+=memberDef->qualifiedName();
+ }
+ if (fileDef)
+ {
+ myStr+=" file=";
+ myStr+=fileDef->fileName();
+ }
+tcl_inf("%s (%d,%d) %d %d\n",myStr.ascii(),startLine,endLine,isExampleBlock,inlineFragment);
+//tcl_inf("%s\n"input.data());
+ if (isExampleBlock)
+ {
+ tcl_codify(NULL,input);
+ return;
+ }
+ tcl_init();
+ tcl.collectXRefs = collectXRefs;
+ tcl.memberdef = memberDef;
+ tcl.code = &codeOutIntf;
+ if (startLine<0)
+ {
+ startLine=1;
+ }
+ yylineno=startLine;
+ tcl.code_linenumbers = showLineNumbers;
+ tcl.code_line=yylineno;
+ tcl.code->startCodeLine(tcl.code_linenumbers);
+ if (tcl.code_linenumbers)
+ {
+ tcl.code->writeLineNumber(0,0,0,tcl.code_line);
+ }
+ tcl.file_name = "";
+ tcl.this_parser = NULL;
+ tcl.entry_main = tcl_entry_new();
+ tcl_parse(myNs,myCls);
+ tcl.code->endCodeLine();
+ tcl.scan.clear();
+ tcl.ns.clear();
+ tcl.cl.clear();
+ tcl.fn.clear();
+ tcl.entry.clear();
+ printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL);
+}
+
+bool TclLanguageScanner::needsPreprocessing(const QCString &extension)
+{
+ (void)extension;
+ return FALSE;
+}
+
+void TclLanguageScanner::resetCodeParserState()
+{
+}
+
+void TclLanguageScanner::parsePrototype(const char *text)
+{
+ (void)text;
+}
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+
+ *buf = '\0';
+ while ( c < max_size && tcl.input_string.at(tcl.input_position) )
+ {
+ *buf = tcl.input_string.at(tcl.input_position++) ;
+ c++; buf++;
+ }
+ //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c);
+ return c;
+}
+
+//----------------------------------------------------------------------------
+
+// to avoid a warning
+void tclDummy()
+{
+ yy_top_state();
+}
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void tclscannerYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+
diff --git a/src/template.cpp b/src/template.cpp
new file mode 100644
index 0000000..ec8554b
--- /dev/null
+++ b/src/template.cpp
@@ -0,0 +1,4799 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "template.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <qlist.h>
+#include <qarray.h>
+#include <qdict.h>
+#include <qstrlist.h>
+#include <qvaluelist.h>
+#include <qstack.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qcstring.h>
+#include <qdir.h>
+
+#include "sortdict.h"
+#include "ftextstream.h"
+#include "message.h"
+#include "util.h"
+
+#define ENABLE_TRACING 0
+
+#if ENABLE_TRACING
+#define TRACE(x) printf x
+#else
+#define TRACE(x)
+#endif
+
+class TemplateToken;
+
+//-------------------------------------------------------------------
+
+static QValueList<QCString> split(const QCString &str,const QCString &sep,
+ bool allowEmptyEntries=FALSE,bool cleanup=TRUE)
+{
+ QValueList<QCString> lst;
+
+ int j = 0;
+ int i = str.find( sep, j );
+
+ while (i!=-1)
+ {
+ if ( str.mid(j,i-j).length() > 0 )
+ {
+ if (cleanup)
+ {
+ lst.append(str.mid(j,i-j).stripWhiteSpace());
+ }
+ else
+ {
+ lst.append(str.mid(j,i-j));
+ }
+ }
+ else if (allowEmptyEntries)
+ {
+ lst.append("");
+ }
+ j = i + sep.length();
+ i = str.find(sep,j);
+ }
+
+ int l = str.length() - 1;
+ if (str.mid(j,l-j+1).length()>0)
+ {
+ if (cleanup)
+ {
+ lst.append(str.mid(j,l-j+1).stripWhiteSpace());
+ }
+ else
+ {
+ lst.append(str.mid(j,l-j+1));
+ }
+ }
+ else if (allowEmptyEntries)
+ {
+ lst.append("");
+ }
+
+ return lst;
+}
+
+//----------------------------------------------------------------------------
+
+#if ENABLE_TRACING
+static QCString replace(const char *s,char csrc,char cdst)
+{
+ QCString result = s;
+ for (char *p=result.data();*p;p++)
+ {
+ if (*p==csrc) *p=cdst;
+ }
+ return result;
+}
+#endif
+
+//- TemplateVariant implementation -------------------------------------------
+
+/** @brief Private data of a template variant object */
+class TemplateVariant::Private
+{
+ public:
+ Private() : raw(FALSE) {}
+ Type type;
+ int intVal;
+ QCString strVal;
+ bool boolVal;
+ TemplateStructIntf *strukt;
+ TemplateListIntf *list;
+ Delegate delegate;
+ bool raw;
+};
+
+TemplateVariant::TemplateVariant()
+{
+ p = new Private;
+ p->type=None;
+}
+
+TemplateVariant::TemplateVariant(bool b)
+{
+ p = new Private;
+ p->type = Bool;
+ p->boolVal = b;
+}
+
+TemplateVariant::TemplateVariant(int v)
+{
+ p = new Private;
+ p->type = Integer;
+ p->intVal = v;
+}
+
+TemplateVariant::TemplateVariant(const char *s,bool raw)
+{
+ p = new Private;
+ p->type = String;
+ p->strVal = s;
+ p->raw = raw;
+}
+
+TemplateVariant::TemplateVariant(const QCString &s,bool raw)
+{
+ p = new Private;
+ p->type = String;
+ p->strVal = s;
+ p->raw = raw;
+}
+
+TemplateVariant::TemplateVariant(TemplateStructIntf *s)
+{
+ p = new Private;
+ p->type = Struct;
+ p->strukt = s;
+ p->strukt->addRef();
+}
+
+TemplateVariant::TemplateVariant(TemplateListIntf *l)
+{
+ p = new Private;
+ p->type = List;
+ p->list = l;
+ p->list->addRef();
+}
+
+TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)
+{
+ p = new Private;
+ p->type = Function;
+ p->delegate = delegate;
+}
+
+TemplateVariant::~TemplateVariant()
+{
+ if (p->type==Struct) p->strukt->release();
+ else if (p->type==List) p->list->release();
+ delete p;
+}
+
+TemplateVariant::TemplateVariant(const TemplateVariant &v)
+{
+ p = new Private;
+ p->type = v.p->type;
+ p->raw = v.p->raw;
+ switch (p->type)
+ {
+ case None: break;
+ case Bool: p->boolVal = v.p->boolVal; break;
+ case Integer: p->intVal = v.p->intVal; break;
+ case String: p->strVal = v.p->strVal; break;
+ case Struct: p->strukt = v.p->strukt; p->strukt->addRef(); break;
+ case List: p->list = v.p->list; p->list->addRef(); break;
+ case Function: p->delegate= v.p->delegate;break;
+ }
+}
+
+TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
+{
+ // assignment can change the type of the variable, so we have to be
+ // careful with reference counted content.
+ TemplateStructIntf *tmpStruct = p->type==Struct ? p->strukt : 0;
+ TemplateListIntf *tmpList = p->type==List ? p->list : 0;
+ Type tmpType = p->type;
+
+ p->type = v.p->type;
+ p->raw = v.p->raw;
+ switch (p->type)
+ {
+ case None: break;
+ case Bool: p->boolVal = v.p->boolVal; break;
+ case Integer: p->intVal = v.p->intVal; break;
+ case String: p->strVal = v.p->strVal; break;
+ case Struct: p->strukt = v.p->strukt; p->strukt->addRef(); break;
+ case List: p->list = v.p->list; p->list->addRef(); break;
+ case Function: p->delegate= v.p->delegate;break;
+ }
+
+ // release overwritten reference counted values
+ if (tmpType==Struct && tmpStruct) tmpStruct->release();
+ else if (tmpType==List && tmpList ) tmpList->release();
+ return *this;
+}
+
+QCString TemplateVariant::toString() const
+{
+ QCString result;
+ switch (p->type)
+ {
+ case None:
+ break;
+ case Bool:
+ result=p->boolVal ? "true" : "false";
+ break;
+ case Integer:
+ result=QCString().setNum(p->intVal);
+ break;
+ case String:
+ result=p->strVal;
+ break;
+ case Struct:
+ result="[struct]";
+ break;
+ case List:
+ result="[list]";
+ break;
+ case Function:
+ result="[function]";
+ break;
+ }
+ return result;
+}
+
+bool TemplateVariant::toBool() const
+{
+ bool result=FALSE;
+ switch (p->type)
+ {
+ case None:
+ break;
+ case Bool:
+ result = p->boolVal;
+ break;
+ case Integer:
+ result = p->intVal!=0;
+ break;
+ case String:
+ result = !p->strVal.isEmpty(); // && p->strVal!="false" && p->strVal!="0";
+ break;
+ case Struct:
+ result = TRUE;
+ break;
+ case List:
+ result = p->list->count()!=0;
+ break;
+ case Function:
+ result = FALSE;
+ break;
+ }
+ return result;
+}
+
+int TemplateVariant::toInt() const
+{
+ int result=0;
+ switch (p->type)
+ {
+ case None:
+ break;
+ case Bool:
+ result = p->boolVal ? 1 : 0;
+ break;
+ case Integer:
+ result = p->intVal;
+ break;
+ case String:
+ result = p->strVal.toInt();
+ break;
+ case Struct:
+ break;
+ case List:
+ result = p->list->count();
+ break;
+ case Function:
+ result = 0;
+ break;
+ }
+ return result;
+}
+
+TemplateStructIntf *TemplateVariant::toStruct() const
+{
+ return p->type==Struct ? p->strukt : 0;
+}
+
+TemplateListIntf *TemplateVariant::toList() const
+{
+ return p->type==List ? p->list : 0;
+}
+
+TemplateVariant TemplateVariant::call(const QValueList<TemplateVariant> &args)
+{
+ if (p->type==Function) return p->delegate(args);
+ return TemplateVariant();
+}
+
+bool TemplateVariant::operator==(TemplateVariant &other)
+{
+ if (p->type==None)
+ {
+ return FALSE;
+ }
+ if (p->type==TemplateVariant::List && other.p->type==TemplateVariant::List)
+ {
+ return p->list==other.p->list; // TODO: improve me
+ }
+ else if (p->type==TemplateVariant::Struct && other.p->type==TemplateVariant::Struct)
+ {
+ return p->strukt==other.p->strukt; // TODO: improve me
+ }
+ else
+ {
+ return toString()==other.toString();
+ }
+}
+
+TemplateVariant::Type TemplateVariant::type() const
+{
+ return p->type;
+}
+
+QCString TemplateVariant::typeAsString() const
+{
+ switch (p->type)
+ {
+ case None: return "none";
+ case Bool: return "bool";
+ case Integer: return "integer";
+ case String: return "string";
+ case Struct: return "struct";
+ case List: return "list";
+ case Function: return "function";
+ }
+ return "invalid";
+}
+
+bool TemplateVariant::isValid() const
+{
+ return p->type!=None;
+}
+
+void TemplateVariant::setRaw(bool b)
+{
+ p->raw = b;
+}
+
+bool TemplateVariant::raw() const
+{
+ return p->raw;
+}
+
+//- Template struct implementation --------------------------------------------
+
+
+/** @brief Private data of a template struct object */
+class TemplateStruct::Private
+{
+ public:
+ Private() : fields(17), refCount(0)
+ { fields.setAutoDelete(TRUE); }
+ QDict<TemplateVariant> fields;
+ int refCount;
+};
+
+TemplateStruct::TemplateStruct()
+{
+ p = new Private;
+}
+
+TemplateStruct::~TemplateStruct()
+{
+ delete p;
+}
+
+int TemplateStruct::addRef()
+{
+ return ++p->refCount;
+}
+
+int TemplateStruct::release()
+{
+ int count = --p->refCount;
+ if (count<=0)
+ {
+ delete this;
+ }
+ return count;
+}
+
+void TemplateStruct::set(const char *name,const TemplateVariant &v)
+{
+ TemplateVariant *pv = p->fields.find(name);
+ if (pv) // change existing field
+ {
+ *pv = v;
+ }
+ else // insert new field
+ {
+ p->fields.insert(name,new TemplateVariant(v));
+ }
+}
+
+TemplateVariant TemplateStruct::get(const char *name) const
+{
+ TemplateVariant *v = p->fields.find(name);
+ return v ? *v : TemplateVariant();
+}
+
+TemplateStruct *TemplateStruct::alloc()
+{
+ return new TemplateStruct;
+}
+
+//- Template list implementation ----------------------------------------------
+
+
+/** @brief Private data of a template list object */
+class TemplateList::Private
+{
+ public:
+ Private() : index(-1), refCount(0) {}
+ QValueList<TemplateVariant> elems;
+ int index;
+ int refCount;
+};
+
+
+TemplateList::TemplateList()
+{
+ p = new Private;
+}
+
+TemplateList::~TemplateList()
+{
+ delete p;
+}
+
+int TemplateList::addRef()
+{
+ return ++p->refCount;
+}
+
+int TemplateList::release()
+{
+ int count = --p->refCount;
+ if (count<=0)
+ {
+ delete this;
+ }
+ return count;
+}
+
+int TemplateList::count() const
+{
+ return p->elems.count();
+}
+
+void TemplateList::append(const TemplateVariant &v)
+{
+ p->elems.append(v);
+}
+
+// iterator support
+class TemplateListConstIterator : public TemplateListIntf::ConstIterator
+{
+ public:
+ TemplateListConstIterator(const TemplateList &l) : m_list(l) { m_index=-1; }
+ virtual ~TemplateListConstIterator() {}
+ virtual void toFirst()
+ {
+ m_it = m_list.p->elems.begin();
+ m_index=0;
+ }
+ virtual void toLast()
+ {
+ m_it = m_list.p->elems.fromLast();
+ m_index=m_list.count()-1;
+ }
+ virtual void toNext()
+ {
+ if (m_it!=m_list.p->elems.end())
+ {
+ ++m_it;
+ ++m_index;
+ }
+ }
+ virtual void toPrev()
+ {
+ if (m_index>0)
+ {
+ --m_it;
+ --m_index;
+ }
+ else
+ {
+ m_index=-1;
+ }
+ }
+ virtual bool current(TemplateVariant &v) const
+ {
+ if (m_index<0 || m_it==m_list.p->elems.end())
+ {
+ v = TemplateVariant();
+ return FALSE;
+ }
+ else
+ {
+ v = *m_it;
+ return TRUE;
+ }
+ }
+ private:
+ const TemplateList &m_list;
+ QValueList<TemplateVariant>::ConstIterator m_it;
+ int m_index;
+};
+
+TemplateListIntf::ConstIterator *TemplateList::createIterator() const
+{
+ return new TemplateListConstIterator(*this);
+}
+
+TemplateVariant TemplateList::at(int index) const
+{
+ if (index>=0 && index<(int)p->elems.count())
+ {
+ return p->elems[index];
+ }
+ else
+ {
+ return TemplateVariant();
+ }
+}
+
+TemplateList *TemplateList::alloc()
+{
+ return new TemplateList;
+}
+
+//- Operator types ------------------------------------------------------------
+
+/** @brief Class representing operators that can appear in template expressions */
+class Operator
+{
+ public:
+ /* Operator precedence (low to high)
+ or
+ and
+ not
+ in
+ ==, !=, <, >, <=, >=
+ +, -
+ *, /, %
+ |
+ :
+ ,
+ */
+ enum Type
+ {
+ Or, And, Not, In, Equal, NotEqual, Less, Greater, LessEqual,
+ GreaterEqual, Plus, Minus, Multiply, Divide, Modulo, Filter, Colon, Comma,
+ LeftParen, RightParen,
+ Last
+ };
+
+ static const char *toString(Type op)
+ {
+ switch(op)
+ {
+ case Or: return "or";
+ case And: return "and";
+ case Not: return "not";
+ case In: return "in";
+ case Equal: return "==";
+ case NotEqual: return "!=";
+ case Less: return "<";
+ case Greater: return ">";
+ case LessEqual: return "<=";
+ case GreaterEqual: return ">=";
+ case Plus: return "+";
+ case Minus: return "-";
+ case Multiply: return "*";
+ case Divide: return "/";
+ case Modulo: return "%";
+ case Filter: return "|";
+ case Colon: return ":";
+ case Comma: return ",";
+ case LeftParen: return "(";
+ case RightParen: return ")";
+ case Last: return "?";
+ }
+ return "?";
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+class TemplateNodeBlock;
+
+/** @brief Class holding stacks of blocks available in the context */
+class TemplateBlockContext
+{
+ public:
+ TemplateBlockContext();
+ TemplateNodeBlock *get(const QCString &name) const;
+ TemplateNodeBlock *pop(const QCString &name) const;
+ void add(TemplateNodeBlock *block);
+ void add(TemplateBlockContext *ctx);
+ void push(TemplateNodeBlock *block);
+ void clear();
+ private:
+ QDict< QList<TemplateNodeBlock> > m_blocks;
+};
+
+/** @brief A container to store a key-value pair */
+struct TemplateKeyValue
+{
+ TemplateKeyValue() {}
+ TemplateKeyValue(const QCString &k,const TemplateVariant &v) : key(k), value(v) {}
+ QCString key;
+ TemplateVariant value;
+};
+
+/** @brief Internal class representing the implementation of a template
+ * context */
+class TemplateContextImpl : public TemplateContext
+{
+ public:
+ TemplateContextImpl(const TemplateEngine *e);
+ virtual ~TemplateContextImpl();
+
+ // TemplateContext methods
+ void push();
+ void pop();
+ void set(const char *name,const TemplateVariant &v);
+ TemplateVariant get(const QCString &name) const;
+ const TemplateVariant *getRef(const QCString &name) const;
+ void setOutputDirectory(const QCString &dir)
+ { m_outputDir = dir; }
+ void setEscapeIntf(const QCString &ext,TemplateEscapeIntf *intf)
+ {
+ int i=(!ext.isEmpty() && ext.at(0)=='.') ? 1 : 0;
+ m_escapeIntfDict.insert(ext.mid(i),new TemplateEscapeIntf*(intf));
+ }
+ void selectEscapeIntf(const QCString &ext)
+ { TemplateEscapeIntf **ppIntf = m_escapeIntfDict.find(ext);
+ m_activeEscapeIntf = ppIntf ? *ppIntf : 0;
+ }
+ void setActiveEscapeIntf(TemplateEscapeIntf *intf) { m_activeEscapeIntf = intf; }
+ void setSpacelessIntf(TemplateSpacelessIntf *intf) { m_spacelessIntf = intf; }
+
+ // internal methods
+ TemplateBlockContext *blockContext();
+ TemplateVariant getPrimary(const QCString &name) const;
+ void setLocation(const QCString &templateName,int line)
+ { m_templateName=templateName; m_line=line; }
+ QCString templateName() const { return m_templateName; }
+ int line() const { return m_line; }
+ QCString outputDirectory() const { return m_outputDir; }
+ TemplateEscapeIntf *escapeIntf() const { return m_activeEscapeIntf; }
+ TemplateSpacelessIntf *spacelessIntf() const { return m_spacelessIntf; }
+ void enableSpaceless(bool b) { if (b && !m_spacelessEnabled) m_spacelessIntf->reset();
+ m_spacelessEnabled=b;
+ }
+ bool spacelessEnabled() const { return m_spacelessEnabled && m_spacelessIntf; }
+ void warn(const char *fileName,int line,const char *fmt,...) const;
+
+ // index related functions
+ void openSubIndex(const QCString &indexName);
+ void closeSubIndex(const QCString &indexName);
+ void addIndexEntry(const QCString &indexName,const QValueList<TemplateKeyValue> &arguments);
+
+ private:
+ const TemplateEngine *m_engine;
+ QCString m_templateName;
+ int m_line;
+ QCString m_outputDir;
+ QList< QDict<TemplateVariant> > m_contextStack;
+ TemplateBlockContext m_blockContext;
+ QDict<TemplateEscapeIntf*> m_escapeIntfDict;
+ TemplateEscapeIntf *m_activeEscapeIntf;
+ TemplateSpacelessIntf *m_spacelessIntf;
+ bool m_spacelessEnabled;
+ TemplateAutoRef<TemplateStruct> m_indices;
+ QDict< QStack<TemplateVariant> > m_indexStacks;
+};
+
+//-----------------------------------------------------------------------------
+
+/** @brief The implementation of the "add" filter */
+class FilterAdd
+{
+ public:
+ static int variantIntValue(const TemplateVariant &v,bool &isInt)
+ {
+ isInt = v.type()==TemplateVariant::Integer;
+ if (!isInt && v.type()==TemplateVariant::String)
+ {
+ return v.toString().toInt(&isInt);
+ }
+ return isInt ? v.toInt() : 0;
+ }
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
+ {
+ if (!v.isValid())
+ {
+ return arg;
+ }
+ bool lhsIsInt;
+ int lhsValue = variantIntValue(v,lhsIsInt);
+ bool rhsIsInt;
+ int rhsValue = variantIntValue(arg,rhsIsInt);
+ if (lhsIsInt && rhsIsInt)
+ {
+ return lhsValue+rhsValue;
+ }
+ else if (v.type()==TemplateVariant::String && arg.type()==TemplateVariant::String)
+ {
+ return TemplateVariant(v.toString() + arg.toString());
+ }
+ else
+ {
+ return v;
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+/** @brief The implementation of the "get" filter */
+class FilterGet
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
+ {
+ if (v.isValid() && v.type()==TemplateVariant::Struct && arg.type()==TemplateVariant::String)
+ {
+ TemplateVariant result = v.toStruct()->get(arg.toString());
+ //printf("\nok[%s]=%d\n",arg.toString().data(),result.type());
+ return result;
+ }
+ else
+ {
+ //printf("\nnok[%s]\n",arg.toString().data());
+ return FALSE;
+ }
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+
+/** @brief The implementation of the "append" filter */
+class FilterAppend
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
+ {
+ if ((v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer) &&
+ arg.type()==TemplateVariant::String)
+ {
+ return TemplateVariant(v.toString() + arg.toString());
+ }
+ else
+ {
+ return v;
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+/** @brief The implementation of the "prepend" filter */
+class FilterPrepend
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
+ {
+ if ((v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer) &&
+ arg.type()==TemplateVariant::String)
+ {
+ return TemplateVariant(arg.toString() + v.toString());
+ }
+ else
+ {
+ return v;
+ }
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "length" filter */
+class FilterLength
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (!v.isValid())
+ {
+ return TemplateVariant();
+ }
+ if (v.type()==TemplateVariant::List)
+ {
+ return TemplateVariant(v.toList()->count());
+ }
+ else if (v.type()==TemplateVariant::String)
+ {
+ return TemplateVariant((int)v.toString().length());
+ }
+ else
+ {
+ return TemplateVariant();
+ }
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "default" filter */
+class FilterDefault
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg)
+ {
+ if (!v.isValid())
+ {
+ return arg;
+ }
+ else if (v.type()==TemplateVariant::String && v.toString().isEmpty())
+ {
+ return arg;
+ }
+ else
+ {
+ return v;
+ }
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "flatten" filter */
+class FilterFlatten
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (!v.isValid() || v.type()!=TemplateVariant::List)
+ {
+ return v;
+ }
+ else
+ {
+ TemplateList *list = TemplateList::alloc();
+ flatten(v.toList(),list);
+ return TemplateVariant(list);
+ }
+ }
+
+ private:
+ static void flatten(TemplateListIntf *tree,TemplateList *list)
+ {
+ TemplateListIntf::ConstIterator *it = tree->createIterator();
+ TemplateVariant item;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ TemplateStructIntf *s = item.toStruct();
+ if (s)
+ {
+ list->append(item);
+ // if s has "children" then recurse into the children
+ TemplateVariant children = s->get("children");
+ if (children.isValid() && children.type()==TemplateVariant::List)
+ {
+ flatten(children.toList(),list);
+ }
+ }
+ else
+ {
+ list->append(item);
+ }
+ }
+ delete it;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "listsort" filter */
+class FilterListSort
+{
+ struct ListElem
+ {
+ ListElem(const QCString &k,const TemplateVariant &v) : key(k), value(v) {}
+ QCString key;
+ TemplateVariant value;
+ };
+ class SortList : public QList<ListElem>
+ {
+ public:
+ SortList() { setAutoDelete(TRUE); }
+ private:
+ int compareValues(const ListElem *item1,const ListElem *item2) const
+ {
+ return qstrcmp(item1->key,item2->key);
+ }
+ };
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
+ {
+ if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ {
+ //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
+
+ TemplateVariant item;
+ TemplateList *result = TemplateList::alloc();
+
+ // create list of items based on v using the data in args as a sort key
+ SortList sortList;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ TemplateStructIntf *s = item.toStruct();
+ if (s)
+ {
+ QCString sortKey = determineSortKey(s,args.toString());
+ sortList.append(new ListElem(sortKey,item));
+ //printf("sortKey=%s\n",sortKey.data());
+ }
+ }
+ delete it;
+
+ // sort the list
+ sortList.sort();
+
+ // add sorted items to the result list
+ QListIterator<ListElem> sit(sortList);
+ ListElem *elem;
+ for (sit.toFirst();(elem=sit.current());++sit)
+ {
+ result->append(elem->value);
+ }
+ return result;
+ }
+ return v;
+ }
+
+ private:
+ static QCString determineSortKey(TemplateStructIntf *s,const QCString &arg)
+ {
+ int i,p=0;
+ QCString result;
+ while ((i=arg.find("{{",p))!=-1)
+ {
+ result+=arg.mid(p,i-p);
+ int j=arg.find("}}",i+2);
+ if (j!=-1)
+ {
+ QCString var = arg.mid(i+2,j-i-2);
+ TemplateVariant val=s->get(var);
+ //printf("found argument %s value=%s\n",var.data(),val.toString().data());
+ result+=val.toString();
+ p=j+2;
+ }
+ else
+ {
+ p=i+1;
+ }
+ }
+ result+=arg.right(arg.length()-p);
+ return result;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "groupBy" filter */
+class FilterGroupBy
+{
+ struct ListElem
+ {
+ ListElem(const QCString &k,const TemplateVariant &v) : key(k), value(v) {}
+ QCString key;
+ TemplateVariant value;
+ };
+ class SortList : public QList<ListElem>
+ {
+ public:
+ SortList() { setAutoDelete(TRUE); }
+ private:
+ int compareValues(const ListElem *item1,const ListElem *item2) const
+ {
+ return qstrcmp(item1->key,item2->key);
+ }
+ };
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
+ {
+ if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ {
+ //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
+
+ TemplateVariant item;
+ TemplateList *result = TemplateList::alloc();
+
+ // create list of items based on v using the data in args as a sort key
+ SortList sortList;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ TemplateStructIntf *s = item.toStruct();
+ if (s)
+ {
+ QCString sortKey = determineSortKey(s,args.toString());
+ sortList.append(new ListElem(sortKey,item));
+ //printf("sortKey=%s\n",sortKey.data());
+ }
+ }
+ delete it;
+
+ // sort the list
+ sortList.sort();
+
+ // add sorted items to the result list
+ QListIterator<ListElem> sit(sortList);
+ ListElem *elem;
+ TemplateList *groupList=0;
+ QCString prevKey;
+ for (sit.toFirst();(elem=sit.current());++sit)
+ {
+ if (groupList==0 || elem->key!=prevKey)
+ {
+ groupList = TemplateList::alloc();
+ result->append(groupList);
+ prevKey = elem->key;
+ }
+ groupList->append(elem->value);
+ }
+ return result;
+ }
+ return v;
+ }
+
+ private:
+ static QCString determineSortKey(TemplateStructIntf *s,const QCString &attribName)
+ {
+ TemplateVariant v = s->get(attribName);
+ return v.toString();
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "paginate" filter */
+class FilterPaginate
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
+ {
+ if (v.isValid() && v.type()==TemplateVariant::List &&
+ args.isValid() && args.type()==TemplateVariant::Integer)
+ {
+ int pageSize = args.toInt();
+ TemplateListIntf *list = v.toList();
+ TemplateList *result = TemplateList::alloc();
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ TemplateVariant item;
+ TemplateList *pageList=0;
+ int i = 0;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ if (pageList==0)
+ {
+ pageList = TemplateList::alloc();
+ result->append(pageList);
+ }
+ pageList->append(item);
+ i++;
+ if (i==pageSize) // page is full start a new one
+ {
+ pageList=0;
+ i=0;
+ }
+ }
+ delete it;
+ return result;
+ }
+ else // wrong arguments
+ {
+ return v;
+ }
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "alphaIndex" filter */
+class FilterAlphaIndex
+{
+ private:
+ struct ListElem
+ {
+ ListElem(uint k,const TemplateVariant &v) : key(k), value(v) {}
+ uint key;
+ TemplateVariant value;
+ };
+ class SortList : public QList<ListElem>
+ {
+ public:
+ SortList() { setAutoDelete(TRUE); }
+ private:
+ int compareValues(const ListElem *item1,const ListElem *item2) const
+ {
+ return item1->key-item2->key;
+ }
+ };
+ static QCString keyToLetter(uint startLetter)
+ {
+ return QString(QChar(startLetter)).utf8();
+ }
+ static QCString keyToLabel(uint startLetter)
+ {
+ char s[10];
+ if (startLetter>0x20 && startLetter<=0x7f) // printable ASCII character
+ {
+ s[0]=tolower((char)startLetter);
+ s[1]=0;
+ }
+ else
+ {
+ const char hex[]="0123456789abcdef";
+ int i=0;
+ s[i++]='0';
+ s[i++]='x';
+ if (startLetter>(1<<24)) // 4 byte character
+ {
+ s[i++]=hex[(startLetter>>28)&0xf];
+ s[i++]=hex[(startLetter>>24)&0xf];
+ }
+ if (startLetter>(1<<16)) // 3 byte character
+ {
+ s[i++]=hex[(startLetter>>20)&0xf];
+ s[i++]=hex[(startLetter>>16)&0xf];
+ }
+ if (startLetter>(1<<8)) // 2 byte character
+ {
+ s[i++]=hex[(startLetter>>12)&0xf];
+ s[i++]=hex[(startLetter>>8)&0xf];
+ }
+ // one byte character
+ s[i++]=hex[(startLetter>>4)&0xf];
+ s[i++]=hex[(startLetter>>0)&0xf];
+ s[i++]=0;
+ }
+ return s;
+ }
+ static uint determineSortKey(TemplateStructIntf *s,const QCString &attribName)
+ {
+ TemplateVariant v = s->get(attribName);
+ int index = getPrefixIndex(v.toString());
+ return getUtf8CodeToUpper(v.toString(),index);
+ }
+
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args)
+ {
+ if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String)
+ {
+ //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data());
+ TemplateListIntf::ConstIterator *it = v.toList()->createIterator();
+
+ TemplateVariant item;
+ TemplateList *result = TemplateList::alloc();
+
+ // create list of items based on v using the data in args as a sort key
+ SortList sortList;
+ for (it->toFirst();(it->current(item));it->toNext())
+ {
+ TemplateStructIntf *s = item.toStruct();
+ if (s)
+ {
+ uint sortKey = determineSortKey(s,args.toString());
+ sortList.append(new ListElem(sortKey,item));
+ //printf("sortKey=%s\n",sortKey.data());
+ }
+ }
+ delete it;
+
+ // sort the list
+ sortList.sort();
+
+ // create an index from the sorted list
+ uint letter=0;
+ QListIterator<ListElem> sit(sortList);
+ ListElem *elem;
+ TemplateStruct *indexNode = 0;
+ TemplateList *indexList = 0;
+ for (sit.toFirst();(elem=sit.current());++sit)
+ {
+ if (letter!=elem->key || indexNode==0)
+ {
+ // create new indexNode
+ indexNode = TemplateStruct::alloc();
+ indexList = TemplateList::alloc();
+ indexNode->set("letter", keyToLetter(elem->key));
+ indexNode->set("label", keyToLabel(elem->key));
+ indexNode->set("items",indexList);
+ result->append(indexNode);
+ letter=elem->key;
+ }
+ indexList->append(elem->value);
+ }
+ return result;
+ }
+ return v;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "default" filter */
+class FilterStripPath
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (!v.isValid() || v.type()!=TemplateVariant::String)
+ {
+ return v;
+ }
+ QCString result = v.toString();
+ int i=result.findRev('/');
+ if (i!=-1)
+ {
+ result=result.mid(i+1);
+ }
+ i=result.findRev('\\');
+ if (i!=-1)
+ {
+ result=result.mid(i+1);
+ }
+ return result;
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "default" filter */
+class FilterNoWrap
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &)
+ {
+ if (!v.isValid() || v.type()!=TemplateVariant::String)
+ {
+ return v;
+ }
+ QCString s = v.toString();
+ return substitute(s," "," ");
+ }
+};
+
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "divisibleby" filter */
+class FilterDivisibleBy
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &n)
+ {
+ if (!v.isValid() || !n.isValid())
+ {
+ return TemplateVariant();
+ }
+ if (v.type()==TemplateVariant::Integer && n.type()==TemplateVariant::Integer)
+ {
+ return TemplateVariant((v.toInt()%n.toInt())==0);
+ }
+ else
+ {
+ return TemplateVariant();
+ }
+ }
+};
+
+
+//--------------------------------------------------------------------
+
+/** @brief Factory singleton for registering and creating filters */
+class TemplateFilterFactory
+{
+ public:
+ typedef TemplateVariant (FilterFunction)(const TemplateVariant &v,const TemplateVariant &arg);
+
+ static TemplateFilterFactory *instance()
+ {
+ static TemplateFilterFactory *instance = 0;
+ if (instance==0) instance = new TemplateFilterFactory;
+ return instance;
+ }
+
+ TemplateVariant apply(const QCString &name,const TemplateVariant &v,const TemplateVariant &arg, bool &ok)
+ {
+ FilterFunction *func = (FilterFunction*)m_registry.find(name);
+ if (func)
+ {
+ ok=TRUE;
+ return (*func)(v,arg);
+ }
+ else
+ {
+ ok=FALSE;
+ return v;
+ }
+ }
+
+ void registerFilter(const QCString &name,FilterFunction *func)
+ {
+ m_registry.insert(name,(void*)func);
+ }
+
+ /** @brief Helper class for registering a filter function */
+ template<class T> class AutoRegister
+ {
+ public:
+ AutoRegister<T>(const QCString &key)
+ {
+ TemplateFilterFactory::instance()->registerFilter(key,&T::apply);
+ }
+ };
+
+ private:
+ QDict<void> m_registry;
+};
+
+// register a handlers for each filter we support
+static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add");
+static TemplateFilterFactory::AutoRegister<FilterGet> fGet("get");
+static TemplateFilterFactory::AutoRegister<FilterAppend> fAppend("append");
+static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length");
+static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap");
+static TemplateFilterFactory::AutoRegister<FilterFlatten> fFlatten("flatten");
+static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default");
+static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend");
+static TemplateFilterFactory::AutoRegister<FilterGroupBy> fGroupBy("groupBy");
+static TemplateFilterFactory::AutoRegister<FilterListSort> fListSort("listsort");
+static TemplateFilterFactory::AutoRegister<FilterPaginate> fPaginate("paginate");
+static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("stripPath");
+static TemplateFilterFactory::AutoRegister<FilterAlphaIndex> fAlphaIndex("alphaIndex");
+static TemplateFilterFactory::AutoRegister<FilterDivisibleBy> fDivisibleBy("divisibleby");
+
+//--------------------------------------------------------------------
+
+/** @brief Base class for all nodes in the abstract syntax tree of an
+ * expression.
+ */
+class ExprAst
+{
+ public:
+ virtual ~ExprAst() {}
+ virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(); }
+};
+
+/** @brief Class representing a number in the AST */
+class ExprAstNumber : public ExprAst
+{
+ public:
+ ExprAstNumber(int num) : m_number(num)
+ { TRACE(("ExprAstNumber(%d)\n",num)); }
+ int number() const { return m_number; }
+ virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(m_number); }
+ private:
+ int m_number;
+};
+
+/** @brief Class representing a variable in the AST */
+class ExprAstVariable : public ExprAst
+{
+ public:
+ ExprAstVariable(const char *name) : m_name(name)
+ { TRACE(("ExprAstVariable(%s)\n",name)); }
+ const QCString &name() const { return m_name; }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ TemplateVariant v = c->get(m_name);
+ if (!v.isValid())
+ {
+ ci->warn(ci->templateName(),ci->line(),"undefined variable '%s' in expression",m_name.data());
+ }
+ return v;
+ }
+ private:
+ QCString m_name;
+};
+
+class ExprAstFunctionVariable : public ExprAst
+{
+ public:
+ ExprAstFunctionVariable(ExprAst *var,const QList<ExprAst> &args)
+ : m_var(var), m_args(args)
+ { TRACE(("ExprAstFunctionVariable()\n"));
+ m_args.setAutoDelete(TRUE);
+ }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ {
+ QValueList<TemplateVariant> args;
+ for (uint i=0;i<m_args.count();i++)
+ {
+ TemplateVariant v = m_args.at(i)->resolve(c);
+ args.append(v);
+ }
+ TemplateVariant v = m_var->resolve(c);
+ if (v.type()==TemplateVariant::Function)
+ {
+ v = v.call(args);
+ }
+ return v;
+ }
+ private:
+ ExprAst *m_var;
+ QList<ExprAst> m_args;
+};
+
+/** @brief Class representing a filter in the AST */
+class ExprAstFilter : public ExprAst
+{
+ public:
+ ExprAstFilter(const char *name,ExprAst *arg) : m_name(name), m_arg(arg)
+ { TRACE(("ExprAstFilter(%s)\n",name)); }
+ ~ExprAstFilter() { delete m_arg; }
+ const QCString &name() const { return m_name; }
+ TemplateVariant apply(const TemplateVariant &v,TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ TRACE(("Applying filter '%s' to '%s' (type=%d)\n",m_name.data(),v.toString().data(),v.type()));
+ TemplateVariant arg;
+ if (m_arg) arg = m_arg->resolve(c);
+ bool ok;
+ TemplateVariant result = TemplateFilterFactory::instance()->apply(m_name,v,arg,ok);
+ if (!ok)
+ {
+ ci->warn(ci->templateName(),ci->line(),"unknown filter '%s'",m_name.data());
+ }
+ return result;
+ }
+ private:
+ QCString m_name;
+ ExprAst *m_arg;
+};
+
+/** @brief Class representing a filter applied to an expression in the AST */
+class ExprAstFilterAppl : public ExprAst
+{
+ public:
+ ExprAstFilterAppl(ExprAst *expr,ExprAstFilter *filter)
+ : m_expr(expr), m_filter(filter)
+ { TRACE(("ExprAstFilterAppl\n")); }
+ ~ExprAstFilterAppl() { delete m_expr; delete m_filter; }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ {
+ return m_filter->apply(m_expr->resolve(c),c);
+ }
+ private:
+ ExprAst *m_expr;
+ ExprAstFilter *m_filter;
+};
+
+/** @brief Class representing a string literal in the AST */
+class ExprAstLiteral : public ExprAst
+{
+ public:
+ ExprAstLiteral(const char *lit) : m_literal(lit)
+ { TRACE(("ExprAstLiteral(%s)\n",lit)); }
+ const QCString &literal() const { return m_literal; }
+ virtual TemplateVariant resolve(TemplateContext *) { return TemplateVariant(m_literal); }
+ private:
+ QCString m_literal;
+};
+
+/** @brief Class representing a negation (not) operator in the AST */
+class ExprAstNegate : public ExprAst
+{
+ public:
+ ExprAstNegate(ExprAst *expr) : m_expr(expr)
+ { TRACE(("ExprAstNegate\n")); }
+ ~ExprAstNegate() { delete m_expr; }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ { return TemplateVariant(!m_expr->resolve(c).toBool()); }
+ private:
+ ExprAst *m_expr;
+};
+
+class ExprAstUnary : public ExprAst
+{
+ public:
+ ExprAstUnary(Operator::Type op,ExprAst *exp) : m_operator(op), m_exp(exp)
+ { TRACE(("ExprAstUnary %s\n",Operator::toString(op))); }
+ ~ExprAstUnary() { delete m_exp; }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ {
+ TemplateVariant exp = m_exp->resolve(c);
+ switch (m_operator)
+ {
+ case Operator::Minus:
+ return -exp.toInt();
+ default:
+ return TemplateVariant();
+ }
+ }
+ private:
+ Operator::Type m_operator;
+ ExprAst *m_exp;
+};
+
+/** @brief Class representing a binary operator in the AST */
+class ExprAstBinary : public ExprAst
+{
+ public:
+ ExprAstBinary(Operator::Type op,ExprAst *lhs,ExprAst *rhs)
+ : m_operator(op), m_lhs(lhs), m_rhs(rhs)
+ { TRACE(("ExprAstBinary %s\n",Operator::toString(op))); }
+ ~ExprAstBinary() { delete m_lhs; delete m_rhs; }
+ virtual TemplateVariant resolve(TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ TemplateVariant lhs = m_lhs->resolve(c);
+ TemplateVariant rhs = m_rhs ? m_rhs->resolve(c) : TemplateVariant();
+ switch(m_operator)
+ {
+ case Operator::Or:
+ return TemplateVariant(lhs.toBool() || rhs.toBool());
+ case Operator::And:
+ return TemplateVariant(lhs.toBool() && rhs.toBool());
+ case Operator::Equal:
+ return TemplateVariant(lhs == rhs);
+ case Operator::NotEqual:
+ return TemplateVariant(!(lhs == rhs));
+ case Operator::Less:
+ if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ {
+ return lhs.toString()<rhs.toString();
+ }
+ else
+ {
+ return lhs.toInt()<rhs.toInt();
+ }
+ case Operator::Greater:
+ if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ {
+ return !(lhs.toString()<rhs.toString());
+ }
+ else
+ {
+ return lhs.toInt()>rhs.toInt();
+ }
+ case Operator::LessEqual:
+ if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ {
+ return lhs.toString()==rhs.toString() || lhs.toString()<rhs.toString();
+ }
+ else
+ {
+ return lhs.toInt()<=rhs.toInt();
+ }
+ case Operator::GreaterEqual:
+ if (lhs.type()==TemplateVariant::String && rhs.type()==TemplateVariant::String)
+ {
+ return lhs.toString()==rhs.toString() || !(lhs.toString()<rhs.toString());
+ }
+ else
+ {
+ return lhs.toInt()>=rhs.toInt();
+ }
+ case Operator::Plus:
+ {
+ return TemplateVariant(lhs.toInt() + rhs.toInt());
+ }
+ case Operator::Minus:
+ {
+ return TemplateVariant(lhs.toInt() - rhs.toInt());
+ }
+ case Operator::Multiply:
+ {
+ return TemplateVariant(lhs.toInt() * rhs.toInt());
+ }
+ case Operator::Divide:
+ {
+ int denom = rhs.toInt();
+ if (denom!=0)
+ {
+ return TemplateVariant(lhs.toInt() / denom);
+ }
+ else // divide by zero
+ {
+ ci->warn(ci->templateName(),ci->line(),"division by zero while evaluating expression is undefined");
+ return 0;
+ }
+ }
+ case Operator::Modulo:
+ {
+ int denom = rhs.toInt();
+ if (denom!=0)
+ {
+ return TemplateVariant(lhs.toInt() % denom);
+ }
+ else // module zero
+ {
+ ci->warn(ci->templateName(),ci->line(),"modulo zero while evaluating expression is undefined");
+ return 0;
+ }
+ }
+ default:
+ return TemplateVariant();
+ }
+ }
+ private:
+ Operator::Type m_operator;
+ ExprAst *m_lhs;
+ ExprAst *m_rhs;
+};
+
+//----------------------------------------------------------
+
+/** @brief Base class of all nodes in a template's AST */
+class TemplateNode
+{
+ public:
+ TemplateNode(TemplateNode *parent) : m_parent(parent) {}
+ virtual ~TemplateNode() {}
+
+ virtual void render(FTextStream &ts, TemplateContext *c) = 0;
+
+ TemplateNode *parent() { return m_parent; }
+
+ private:
+ TemplateNode *m_parent;
+};
+
+//----------------------------------------------------------
+
+/** @brief Parser for templates */
+class TemplateParser
+{
+ public:
+ TemplateParser(const TemplateEngine *engine,
+ const QCString &templateName,QList<TemplateToken> &tokens);
+ void parse(TemplateNode *parent,int line,const QStrList &stopAt,
+ QList<TemplateNode> &nodes);
+ bool hasNextToken() const;
+ TemplateToken *takeNextToken();
+ void removeNextToken();
+ void prependToken(const TemplateToken *token);
+ const TemplateToken *currentToken() const;
+ QCString templateName() const { return m_templateName; }
+ void warn(const char *fileName,int line,const char *fmt,...) const;
+ private:
+ const TemplateEngine *m_engine;
+ QCString m_templateName;
+ QList<TemplateToken> &m_tokens;
+};
+
+//--------------------------------------------------------------------
+
+/** @brief Recursive decent parser for Django style template expressions.
+ */
+class ExpressionParser
+{
+ public:
+ ExpressionParser(const TemplateParser *parser,int line)
+ : m_parser(parser), m_line(line), m_tokenStream(0)
+ {
+ }
+ virtual ~ExpressionParser()
+ {
+ }
+
+ ExprAst *parse(const char *expr)
+ {
+ if (expr==0) return 0;
+ m_tokenStream = expr;
+ getNextToken();
+ return parseExpression();
+ }
+
+ private:
+
+ /** @brief Class representing a token within an expression. */
+ class ExprToken
+ {
+ public:
+ ExprToken() : type(Unknown), num(-1), op(Operator::Or)
+ {
+ }
+ enum Type
+ {
+ Unknown, Operator, Number, Identifier, Literal
+ };
+
+ Type type;
+ int num;
+ QCString id;
+ Operator::Type op;
+ };
+
+ ExprAst *parseExpression()
+ {
+ TRACE(("{parseExpression(%s)\n",m_tokenStream));
+ ExprAst *result = parseOrExpression();
+ TRACE(("}parseExpression(%s)\n",m_tokenStream));
+ return result;
+ }
+
+ ExprAst *parseOrExpression()
+ {
+ TRACE(("{parseOrExpression(%s)\n",m_tokenStream));
+ ExprAst *lhs = parseAndExpression();
+ if (lhs)
+ {
+ while (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Or)
+ {
+ getNextToken();
+ ExprAst *rhs = parseAndExpression();
+ lhs = new ExprAstBinary(Operator::Or,lhs,rhs);
+ }
+ }
+ TRACE(("}parseOrExpression(%s)\n",m_tokenStream));
+ return lhs;
+ }
+
+ ExprAst *parseAndExpression()
+ {
+ TRACE(("{parseAndExpression(%s)\n",m_tokenStream));
+ ExprAst *lhs = parseNotExpression();
+ if (lhs)
+ {
+ while (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::And)
+ {
+ getNextToken();
+ ExprAst *rhs = parseNotExpression();
+ lhs = new ExprAstBinary(Operator::And,lhs,rhs);
+ }
+ }
+ TRACE(("}parseAndExpression(%s)\n",m_tokenStream));
+ return lhs;
+ }
+
+ ExprAst *parseNotExpression()
+ {
+ TRACE(("{parseNotExpression(%s)\n",m_tokenStream));
+ ExprAst *result=0;
+ if (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Not)
+ {
+ getNextToken();
+ ExprAst *expr = parseCompareExpression();
+ if (expr==0)
+ {
+ warn(m_parser->templateName(),m_line,"argument missing for not operator");
+ return 0;
+ }
+ result = new ExprAstNegate(expr);
+ }
+ else
+ {
+ result = parseCompareExpression();
+ }
+ TRACE(("}parseNotExpression(%s)\n",m_tokenStream));
+ return result;
+ }
+
+ ExprAst *parseCompareExpression()
+ {
+ TRACE(("{parseCompareExpression(%s)\n",m_tokenStream));
+ ExprAst *lhs = parseAdditiveExpression();
+ if (lhs)
+ {
+ Operator::Type op = m_curToken.op;
+ if (m_curToken.type==ExprToken::Operator &&
+ (op==Operator::Less ||
+ op==Operator::Greater ||
+ op==Operator::Equal ||
+ op==Operator::NotEqual ||
+ op==Operator::LessEqual ||
+ op==Operator::GreaterEqual
+ )
+ )
+ {
+ getNextToken();
+ ExprAst *rhs = parseNotExpression();
+ lhs = new ExprAstBinary(op,lhs,rhs);
+ }
+ }
+ TRACE(("}parseCompareExpression(%s)\n",m_tokenStream));
+ return lhs;
+ }
+
+ ExprAst *parseAdditiveExpression()
+ {
+ TRACE(("{parseAdditiveExpression(%s)\n",m_tokenStream));
+ ExprAst *lhs = parseMultiplicativeExpression();
+ if (lhs)
+ {
+ while (m_curToken.type==ExprToken::Operator &&
+ (m_curToken.op==Operator::Plus || m_curToken.op==Operator::Minus))
+ {
+ Operator::Type op = m_curToken.op;
+ getNextToken();
+ ExprAst *rhs = parseMultiplicativeExpression();
+ lhs = new ExprAstBinary(op,lhs,rhs);
+ }
+ }
+ TRACE(("}parseAdditiveExpression(%s)\n",m_tokenStream));
+ return lhs;
+ }
+
+ ExprAst *parseMultiplicativeExpression()
+ {
+ TRACE(("{parseMultiplicativeExpression(%s)\n",m_tokenStream));
+ ExprAst *lhs = parseUnaryExpression();
+ if (lhs)
+ {
+ while (m_curToken.type==ExprToken::Operator &&
+ (m_curToken.op==Operator::Multiply || m_curToken.op==Operator::Divide || m_curToken.op==Operator::Modulo))
+ {
+ Operator::Type op = m_curToken.op;
+ getNextToken();
+ ExprAst *rhs = parseUnaryExpression();
+ lhs = new ExprAstBinary(op,lhs,rhs);
+ }
+ }
+ TRACE(("}parseMultiplicativeExpression(%s)\n",m_tokenStream));
+ return lhs;
+ }
+
+ ExprAst *parseUnaryExpression()
+ {
+ TRACE(("{parseUnaryExpression(%s)\n",m_tokenStream));
+ ExprAst *result=0;
+ if (m_curToken.type==ExprToken::Operator)
+ {
+ if (m_curToken.op==Operator::Plus)
+ {
+ getNextToken();
+ result = parsePrimaryExpression();
+ }
+ else if (m_curToken.op==Operator::Minus)
+ {
+ getNextToken();
+ ExprAst *rhs = parsePrimaryExpression();
+ result = new ExprAstUnary(m_curToken.op,rhs);
+ }
+ else
+ {
+ result = parsePrimaryExpression();
+ }
+ }
+ else
+ {
+ result = parsePrimaryExpression();
+ }
+ TRACE(("}parseUnaryExpression(%s)\n",m_tokenStream));
+ return result;
+ }
+
+ ExprAst *parsePrimaryExpression()
+ {
+ TRACE(("{parsePrimary(%s)\n",m_tokenStream));
+ ExprAst *result=0;
+ switch (m_curToken.type)
+ {
+ case ExprToken::Number:
+ result = parseNumber();
+ break;
+ case ExprToken::Identifier:
+ result = parseFilteredVariable();
+ break;
+ case ExprToken::Literal:
+ result = parseLiteral();
+ break;
+ case ExprToken::Operator:
+ if (m_curToken.op==Operator::LeftParen)
+ {
+ getNextToken(); // skip over opening bracket
+ result = parseExpression();
+ if (m_curToken.type!=ExprToken::Operator ||
+ m_curToken.op!=Operator::RightParen)
+ {
+ warn(m_parser->templateName(),m_line,"missing closing parenthesis");
+ }
+ else
+ {
+ getNextToken(); // skip over closing bracket
+ }
+ }
+ else
+ {
+ warn(m_parser->templateName(),m_line,"unexpected operator '%s' in expression",
+ Operator::toString(m_curToken.op));
+ }
+ break;
+ default:
+ warn(m_parser->templateName(),m_line,"unexpected token in expression");
+ }
+ TRACE(("}parsePrimary(%s)\n",m_tokenStream));
+ return result;
+ }
+
+ ExprAst *parseNumber()
+ {
+ TRACE(("{parseNumber(%d)\n",m_curToken.num));
+ ExprAst *num = new ExprAstNumber(m_curToken.num);
+ getNextToken();
+ TRACE(("}parseNumber()\n"));
+ return num;
+ }
+
+ ExprAst *parseIdentifier()
+ {
+ TRACE(("{parseIdentifier(%s)\n",m_curToken.id.data()));
+ ExprAst *id = new ExprAstVariable(m_curToken.id);
+ getNextToken();
+ TRACE(("}parseIdentifier()\n"));
+ return id;
+ }
+
+ ExprAst *parseLiteral()
+ {
+ TRACE(("{parseLiteral(%s)\n",m_curToken.id.data()));
+ ExprAst *lit = new ExprAstLiteral(m_curToken.id);
+ getNextToken();
+ TRACE(("}parseLiteral()\n"));
+ return lit;
+ }
+
+ ExprAst *parseIdentifierOptionalArgs()
+ {
+ TRACE(("{parseIdentifierOptionalArgs(%s)\n",m_curToken.id.data()));
+ ExprAst *expr = parseIdentifier();
+ if (expr)
+ {
+ if (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Colon)
+ {
+ getNextToken();
+ ExprAst *argExpr = parsePrimaryExpression();
+ QList<ExprAst> args;
+ args.append(argExpr);
+ while (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Comma)
+ {
+ getNextToken();
+ argExpr = parsePrimaryExpression();
+ args.append(argExpr);
+ }
+ expr = new ExprAstFunctionVariable(expr,args);
+ }
+ }
+ TRACE(("}parseIdentifierOptionalArgs()\n"));
+ return expr;
+ }
+
+ ExprAst *parseFilteredVariable()
+ {
+ TRACE(("{parseFilteredVariable()\n"));
+ ExprAst *expr = parseIdentifierOptionalArgs();
+ if (expr)
+ {
+ while (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Filter)
+ {
+ getNextToken();
+ ExprAstFilter *filter = parseFilter();
+ if (!filter) break;
+ expr = new ExprAstFilterAppl(expr,filter);
+ }
+ }
+ TRACE(("}parseFilteredVariable()\n"));
+ return expr;
+ }
+
+ ExprAstFilter *parseFilter()
+ {
+ TRACE(("{parseFilter(%s)\n",m_curToken.id.data()));
+ QCString filterName = m_curToken.id;
+ getNextToken();
+ ExprAst *argExpr=0;
+ if (m_curToken.type==ExprToken::Operator &&
+ m_curToken.op==Operator::Colon)
+ {
+ getNextToken();
+ argExpr = parsePrimaryExpression();
+ }
+ ExprAstFilter *filter = new ExprAstFilter(filterName,argExpr);
+ TRACE(("}parseFilter()\n"));
+ return filter;
+ }
+
+
+ bool getNextToken()
+ {
+ const char *p = m_tokenStream;
+ char s[2];
+ s[1]=0;
+ if (p==0 || *p=='\0') return FALSE;
+ while (*p==' ') p++; // skip over spaces
+ char c=*p;
+ const char *q = p;
+ switch (c)
+ {
+ case '=':
+ if (c=='=' && *(p+1)=='=') // equal
+ {
+ m_curToken.op = Operator::Equal;
+ p+=2;
+ }
+ break;
+ case '!':
+ if (c=='!' && *(p+1)=='=') // not equal
+ {
+ m_curToken.op = Operator::NotEqual;
+ p+=2;
+ }
+ break;
+ case '<':
+ if (c=='<' && *(p+1)=='=') // less or equal
+ {
+ m_curToken.op = Operator::LessEqual;
+ p+=2;
+ }
+ else // less
+ {
+ m_curToken.op = Operator::Less;
+ p++;
+ }
+ break;
+ case '>':
+ if (c=='>' && *(p+1)=='=') // greater or equal
+ {
+ m_curToken.op = Operator::GreaterEqual;
+ p+=2;
+ }
+ else // greater
+ {
+ m_curToken.op = Operator::Greater;
+ p++;
+ }
+ break;
+ case '(':
+ m_curToken.op = Operator::LeftParen;
+ p++;
+ break;
+ case ')':
+ m_curToken.op = Operator::RightParen;
+ p++;
+ break;
+ case '|':
+ m_curToken.op = Operator::Filter;
+ p++;
+ break;
+ case '+':
+ m_curToken.op = Operator::Plus;
+ p++;
+ break;
+ case '-':
+ m_curToken.op = Operator::Minus;
+ p++;
+ break;
+ case '*':
+ m_curToken.op = Operator::Multiply;
+ p++;
+ break;
+ case '/':
+ m_curToken.op = Operator::Divide;
+ p++;
+ break;
+ case '%':
+ m_curToken.op = Operator::Modulo;
+ p++;
+ break;
+ case ':':
+ m_curToken.op = Operator::Colon;
+ p++;
+ break;
+ case ',':
+ m_curToken.op = Operator::Comma;
+ p++;
+ break;
+ case 'n':
+ if (strncmp(p,"not ",4)==0)
+ {
+ m_curToken.op = Operator::Not;
+ p+=4;
+ }
+ break;
+ case 'a':
+ if (strncmp(p,"and ",4)==0)
+ {
+ m_curToken.op = Operator::And;
+ p+=4;
+ }
+ break;
+ case 'o':
+ if (strncmp(p,"or ",3)==0)
+ {
+ m_curToken.op = Operator::Or;
+ p+=3;
+ }
+ break;
+ default:
+ break;
+ }
+ if (p!=q) // found an operator
+ {
+ m_curToken.type = ExprToken::Operator;
+ }
+ else // no token found yet
+ {
+ if (c>='0' && c<='9') // number?
+ {
+ m_curToken.type = ExprToken::Number;
+ const char *np = p;
+ m_curToken.num = 0;
+ while (*np>='0' && *np<='9')
+ {
+ m_curToken.num*=10;
+ m_curToken.num+=*np-'0';
+ np++;
+ }
+ p=np;
+ }
+ else if (c=='_' || (c>='a' && c<='z') || (c>='A' && c<='Z')) // identifier?
+ {
+ m_curToken.type = ExprToken::Identifier;
+ s[0]=c;
+ m_curToken.id = s;
+ p++;
+ while ((c=*p) &&
+ (c=='_' || c=='.' ||
+ (c>='a' && c<='z') ||
+ (c>='A' && c<='Z') ||
+ (c>='0' && c<='9'))
+ )
+ {
+ s[0]=c;
+ m_curToken.id+=s;
+ p++;
+ }
+ if (m_curToken.id=="True") // treat true literal as numerical 1
+ {
+ m_curToken.type = ExprToken::Number;
+ m_curToken.num = 1;
+ }
+ else if (m_curToken.id=="False") // treat false literal as numerical 0
+ {
+ m_curToken.type = ExprToken::Number;
+ m_curToken.num = 0;
+ }
+ }
+ else if (c=='"' || c=='\'') // string literal
+ {
+ m_curToken.type = ExprToken::Literal;
+ m_curToken.id.resize(0);
+ p++;
+ char tokenChar = c;
+ char cp=0;
+ while ((c=*p) && (c!=tokenChar || (c==tokenChar && cp=='\\')))
+ {
+ s[0]=c;
+ if (c!='\\' || cp=='\\') // don't add escapes
+ {
+ m_curToken.id+=s;
+ }
+ cp=c;
+ p++;
+ }
+ if (*p==tokenChar) p++;
+ }
+ }
+ if (p==q) // still no valid token found -> error
+ {
+ m_curToken.type = ExprToken::Unknown;
+ char s[2];
+ s[0]=c;
+ s[1]=0;
+ warn(m_parser->templateName(),m_line,"Found unknown token %s while parsing %s",s,m_tokenStream);
+ m_curToken.id = s;
+ p++;
+ }
+ //TRACE(("token type=%d op=%d num=%d id=%s\n",
+ // m_curToken.type,m_curToken.op,m_curToken.num,m_curToken.id.data()));
+
+ m_tokenStream = p;
+ return TRUE;
+ }
+
+ const TemplateParser *m_parser;
+ ExprToken m_curToken;
+ int m_line;
+ const char *m_tokenStream;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a lexical token in a template */
+class TemplateToken
+{
+ public:
+ enum Type { Text, Variable, Block };
+ TemplateToken(Type t,const char *d,int l) : type(t), data(d), line(l) {}
+ Type type;
+ QCString data;
+ int line;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a list of AST nodes in a template */
+class TemplateNodeList : public QList<TemplateNode>
+{
+ public:
+ TemplateNodeList()
+ {
+ setAutoDelete(TRUE);
+ }
+ void render(FTextStream &ts,TemplateContext *c)
+ {
+ TRACE(("{TemplateNodeList::render\n"));
+ QListIterator<TemplateNode> it(*this);
+ TemplateNode *tn=0;
+ for (it.toFirst();(tn=it.current());++it)
+ {
+ tn->render(ts,c);
+ }
+ TRACE(("}TemplateNodeList::render\n"));
+ }
+};
+
+//----------------------------------------------------------
+
+/** @brief Internal class representing the implementation of a template */
+class TemplateImpl : public TemplateNode, public Template
+{
+ public:
+ TemplateImpl(TemplateEngine *e,const QCString &name,const QCString &data);
+ void render(FTextStream &ts, TemplateContext *c);
+
+ TemplateEngine *engine() const { return m_engine; }
+ TemplateBlockContext *blockContext() { return &m_blockContext; }
+
+ private:
+ TemplateEngine *m_engine;
+ QCString m_name;
+ TemplateNodeList m_nodes;
+ TemplateBlockContext m_blockContext;
+};
+
+//----------------------------------------------------------
+
+
+TemplateContextImpl::TemplateContextImpl(const TemplateEngine *e)
+ : m_engine(e), m_templateName("<unknown>"), m_line(1), m_activeEscapeIntf(0),
+ m_spacelessIntf(0), m_spacelessEnabled(FALSE), m_indices(TemplateStruct::alloc())
+{
+ m_indexStacks.setAutoDelete(TRUE);
+ m_contextStack.setAutoDelete(TRUE);
+ m_escapeIntfDict.setAutoDelete(TRUE);
+ push();
+ set("index",m_indices.get());
+}
+
+TemplateContextImpl::~TemplateContextImpl()
+{
+ pop();
+}
+
+void TemplateContextImpl::set(const char *name,const TemplateVariant &v)
+{
+ TemplateVariant *pv = m_contextStack.getFirst()->find(name);
+ if (pv)
+ {
+ m_contextStack.getFirst()->remove(name);
+ }
+ m_contextStack.getFirst()->insert(name,new TemplateVariant(v));
+}
+
+TemplateVariant TemplateContextImpl::get(const QCString &name) const
+{
+ int i=name.find('.');
+ if (i==-1) // simple name
+ {
+ return getPrimary(name);
+ }
+ else // obj.prop
+ {
+ TemplateVariant v;
+ QCString objName = name.left(i);
+ v = getPrimary(objName);
+ QCString propName = name.mid(i+1);
+ while (!propName.isEmpty())
+ {
+ //printf("getPrimary(%s) type=%d:%s\n",objName.data(),v.type(),v.toString().data());
+ if (v.type()==TemplateVariant::Struct)
+ {
+ i = propName.find(".");
+ int l = i==-1 ? propName.length() : i;
+ v = v.toStruct()->get(propName.left(l));
+ if (!v.isValid())
+ {
+ warn(m_templateName,m_line,"requesting non-existing property '%s' for object '%s'",propName.left(l).data(),objName.data());
+ }
+ if (i!=-1)
+ {
+ objName = propName.left(i);
+ propName = propName.mid(i+1);
+ }
+ else
+ {
+ propName.resize(0);
+ }
+ }
+ else if (v.type()==TemplateVariant::List)
+ {
+ i = propName.find(".");
+ int l = i==-1 ? propName.length() : i;
+ bool b;
+ int index = propName.left(l).toInt(&b);
+ if (b)
+ {
+ v = v.toList()->at(index);
+ }
+ else
+ {
+ warn(m_templateName,m_line,"list index '%s' is not valid",propName.data());
+ break;
+ }
+ if (i!=-1)
+ {
+ propName = propName.mid(i+1);
+ }
+ else
+ {
+ propName.resize(0);
+ }
+ }
+ else
+ {
+ warn(m_templateName,m_line,"using . on an object '%s' is not an struct or list",objName.data());
+ return TemplateVariant();
+ }
+ } while (i!=-1);
+ return v;
+ }
+}
+
+const TemplateVariant *TemplateContextImpl::getRef(const QCString &name) const
+{
+ QListIterator< QDict<TemplateVariant> > it(m_contextStack);
+ QDict<TemplateVariant> *dict;
+ for (it.toFirst();(dict=it.current());++it)
+ {
+ TemplateVariant *v = dict->find(name);
+ if (v) return v;
+ }
+ return 0; // not found
+}
+
+TemplateVariant TemplateContextImpl::getPrimary(const QCString &name) const
+{
+ const TemplateVariant *v = getRef(name);
+ return v ? *v : TemplateVariant();
+}
+
+void TemplateContextImpl::push()
+{
+ QDict<TemplateVariant> *dict = new QDict<TemplateVariant>;
+ dict->setAutoDelete(TRUE);
+ m_contextStack.prepend(dict);
+}
+
+void TemplateContextImpl::pop()
+{
+ if (!m_contextStack.removeFirst())
+ {
+ warn(m_templateName,m_line,"pop() called on empty context stack!\n");
+ }
+}
+
+TemplateBlockContext *TemplateContextImpl::blockContext()
+{
+ return &m_blockContext;
+}
+
+void TemplateContextImpl::warn(const char *fileName,int line,const char *fmt,...) const
+{
+ va_list args;
+ va_start(args,fmt);
+ va_warn(fileName,line,fmt,args);
+ va_end(args);
+ m_engine->printIncludeContext(fileName,line);
+}
+
+void TemplateContextImpl::openSubIndex(const QCString &indexName)
+{
+ //printf("TemplateContextImpl::openSubIndex(%s)\n",indexName.data());
+ QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
+ if (!stack || stack->isEmpty() || stack->top()->type()==TemplateVariant::List) // error: no stack yet or no entry
+ {
+ warn(m_templateName,m_line,"opensubindex for index %s without preceding indexentry",indexName.data());
+ return;
+ }
+ // get the parent entry to add the list to
+ TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack->top()->toStruct());
+ if (entry)
+ {
+ // add new list to the stack
+ TemplateList *list = TemplateList::alloc();
+ stack->push(new TemplateVariant(list));
+ entry->set("children",list);
+ entry->set("is_leaf_node",false);
+ }
+}
+
+void TemplateContextImpl::closeSubIndex(const QCString &indexName)
+{
+ //printf("TemplateContextImpl::closeSubIndex(%s)\n",indexName.data());
+ QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
+ if (!stack || stack->count()<3)
+ {
+ warn(m_templateName,m_line,"closesubindex for index %s without matching open",indexName.data());
+ }
+ else // stack->count()>=2
+ {
+ if (stack->top()->type()==TemplateVariant::Struct)
+ {
+ delete stack->pop(); // pop struct
+ delete stack->pop(); // pop list
+ }
+ else // empty list! correct "is_left_node" attribute of the parent entry
+ {
+ delete stack->pop(); // pop list
+ TemplateStruct *entry = dynamic_cast<TemplateStruct*>(stack->top()->toStruct());
+ if (entry)
+ {
+ entry->set("is_leaf_node",true);
+ }
+ }
+ }
+}
+
+static void getPathListFunc(TemplateStructIntf *entry,TemplateList *list)
+{
+ TemplateVariant parent = entry->get("parent");
+ if (parent.type()==TemplateVariant::Struct)
+ {
+ getPathListFunc(parent.toStruct(),list);
+ }
+ list->append(entry);
+}
+
+static TemplateVariant getPathFunc(const void *ctx, const QValueList<TemplateVariant> &)
+{
+ TemplateStruct *entry = (TemplateStruct*)ctx;
+ TemplateList *result = TemplateList::alloc();
+ getPathListFunc(entry,result);
+ return result;
+}
+
+void TemplateContextImpl::addIndexEntry(const QCString &indexName,const QValueList<TemplateKeyValue> &arguments)
+{
+ QValueListConstIterator<TemplateKeyValue> it = arguments.begin();
+ //printf("TemplateContextImpl::addIndexEntry(%s)\n",indexName.data());
+ //while (it!=arguments.end())
+ //{
+ // printf(" key=%s value=%s\n",(*it).key.data(),(*it).value.toString().data());
+ // ++it;
+ //}
+ TemplateVariant parent(FALSE);
+ QStack<TemplateVariant> *stack = m_indexStacks.find(indexName);
+ if (!stack) // no stack yet, create it!
+ {
+ stack = new QStack<TemplateVariant>;
+ stack->setAutoDelete(TRUE);
+ m_indexStacks.insert(indexName,stack);
+ }
+ TemplateList *list = 0;
+ if (stack->isEmpty()) // first item, create empty list and add it to the index
+ {
+ list = TemplateList::alloc();
+ stack->push(new TemplateVariant(list));
+ m_indices->set(indexName,list); // make list available under index
+ }
+ else // stack not empty
+ {
+ if (stack->top()->type()==TemplateVariant::Struct) // already an entry in the list
+ {
+ // remove current entry from the stack
+ delete stack->pop();
+ }
+ else // first entry after opensubindex
+ {
+ ASSERT(stack->top()->type()==TemplateVariant::List);
+ }
+ if (stack->count()>1)
+ {
+ TemplateVariant *tmp = stack->pop();
+ parent = *stack->top();
+ stack->push(tmp);
+ ASSERT(parent.type()==TemplateVariant::Struct);
+ }
+ // get list to add new item
+ list = dynamic_cast<TemplateList*>(stack->top()->toList());
+ }
+ TemplateStruct *entry = TemplateStruct::alloc();
+ // add user specified fields to the entry
+ for (it=arguments.begin();it!=arguments.end();++it)
+ {
+ entry->set((*it).key,(*it).value);
+ }
+ if (list->count()>0)
+ {
+ TemplateStruct *lastEntry = dynamic_cast<TemplateStruct*>(list->at(list->count()-1).toStruct());
+ lastEntry->set("last",false);
+ }
+ entry->set("is_leaf_node",true);
+ entry->set("first",list->count()==0);
+ entry->set("index",list->count());
+ entry->set("parent",parent);
+ entry->set("path",TemplateVariant::Delegate::fromFunction(entry,getPathFunc));
+ entry->set("last",true);
+ stack->push(new TemplateVariant(entry));
+ list->append(entry);
+}
+
+//----------------------------------------------------------
+
+/** @brief Class representing a piece of plain text in a template */
+class TemplateNodeText : public TemplateNode
+{
+ public:
+ TemplateNodeText(TemplateParser *,TemplateNode *parent,int,const QCString &data)
+ : TemplateNode(parent), m_data(data)
+ {
+ TRACE(("TemplateNodeText('%s')\n",replace(data,'\n',' ').data()));
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ //printf("TemplateNodeText::render(%s)\n",m_data.data());
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ if (ci->spacelessEnabled())
+ {
+ ts << ci->spacelessIntf()->remove(m_data);
+ }
+ else
+ {
+ ts << m_data;
+ }
+ }
+ private:
+ QCString m_data;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a variable in a template */
+class TemplateNodeVariable : public TemplateNode
+{
+ public:
+ TemplateNodeVariable(TemplateParser *parser,TemplateNode *parent,int line,const QCString &var)
+ : TemplateNode(parent), m_templateName(parser->templateName()), m_line(line)
+ {
+ TRACE(("TemplateNodeVariable(%s)\n",var.data()));
+ ExpressionParser expParser(parser,line);
+ m_var = expParser.parse(var);
+ if (m_var==0)
+ {
+ parser->warn(m_templateName,line,"invalid expression '%s' for variable",var.data());
+ }
+ }
+ ~TemplateNodeVariable()
+ {
+ delete m_var;
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_var)
+ {
+ TemplateVariant v = m_var->resolve(c);
+ if (v.type()==TemplateVariant::Function)
+ {
+ v = v.call(QValueList<TemplateVariant>());
+ }
+ //printf("TemplateNodeVariable::render(%s) raw=%d\n",value.data(),v.raw());
+ if (ci->escapeIntf() && !v.raw())
+ {
+ ts << ci->escapeIntf()->escape(v.toString());
+ }
+ else
+ {
+ ts << v.toString();
+ }
+ }
+ }
+
+ private:
+ QCString m_templateName;
+ int m_line;
+ ExprAst *m_var;
+ QList<ExprAst> m_args;
+};
+
+//----------------------------------------------------------
+
+/** @brief Helper class for creating template AST tag nodes and returning
+ * the template for a given node.
+ */
+template<class T> class TemplateNodeCreator : public TemplateNode
+{
+ public:
+ TemplateNodeCreator(TemplateParser *parser,TemplateNode *parent,int line)
+ : TemplateNode(parent), m_templateName(parser->templateName()), m_line(line) {}
+ static TemplateNode *createInstance(TemplateParser *parser,
+ TemplateNode *parent,
+ int line,
+ const QCString &data)
+ {
+ return new T(parser,parent,line,data);
+ }
+ TemplateImpl *getTemplate()
+ {
+ TemplateNode *root = this;
+ while (root && root->parent())
+ {
+ root = root->parent();
+ }
+ return dynamic_cast<TemplateImpl*>(root);
+ }
+ protected:
+ QCString m_templateName;
+ int m_line;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'if' tag in a template */
+class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
+{
+ public:
+ TemplateNodeIf(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data) :
+ TemplateNodeCreator<TemplateNodeIf>(parser,parent,line)
+ {
+ m_ifGuardedNodes.setAutoDelete(TRUE);
+ TRACE(("{TemplateNodeIf(%s)\n",data.data()));
+ if (data.isEmpty())
+ {
+ parser->warn(m_templateName,line,"missing argument for if tag");
+ }
+ QStrList stopAt;
+ stopAt.append("endif");
+ stopAt.append("elif");
+ stopAt.append("else");
+
+ // if 'nodes'
+ GuardedNodes *guardedNodes = new GuardedNodes;
+ ExpressionParser ex(parser,line);
+ guardedNodes->line = line;
+ guardedNodes->guardAst = ex.parse(data);
+ parser->parse(this,line,stopAt,guardedNodes->trueNodes);
+ m_ifGuardedNodes.append(guardedNodes);
+ TemplateToken *tok = parser->takeNextToken();
+
+ // elif 'nodes'
+ while (tok && tok->data.left(5)=="elif ")
+ {
+ ExpressionParser ex(parser,line);
+ guardedNodes = new GuardedNodes;
+ guardedNodes->line = tok->line;
+ guardedNodes->guardAst = ex.parse(tok->data.mid(5));
+ parser->parse(this,tok->line,stopAt,guardedNodes->trueNodes);
+ m_ifGuardedNodes.append(guardedNodes);
+ // proceed to the next token
+ delete tok;
+ tok = parser->takeNextToken();
+ }
+
+ // else 'nodes'
+ if (tok && tok->data=="else")
+ {
+ stopAt.removeLast(); // remove "else"
+ stopAt.removeLast(); // remove "elif"
+ parser->parse(this,line,stopAt,m_falseNodes);
+ parser->removeNextToken(); // skip over endif
+ }
+ delete tok;
+ TRACE(("}TemplateNodeIf(%s)\n",data.data()));
+ }
+ ~TemplateNodeIf()
+ {
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ //printf("TemplateNodeIf::render #trueNodes=%d #falseNodes=%d\n",m_trueNodes.count(),m_falseNodes.count());
+ bool processed=FALSE;
+ QListIterator<GuardedNodes> li(m_ifGuardedNodes);
+ GuardedNodes *nodes;
+ for (li.toFirst();(nodes=li.current()) && !processed;++li)
+ {
+ if (nodes->guardAst)
+ {
+ TemplateVariant guardValue = nodes->guardAst->resolve(c);
+ if (guardValue.toBool()) // render nodes for the first guard that evaluated to 'true'
+ {
+ nodes->trueNodes.render(ts,c);
+ processed=TRUE;
+ }
+ }
+ else
+ {
+ ci->warn(m_templateName,nodes->line,"invalid expression for if/elif");
+ }
+ }
+ if (!processed)
+ {
+ // all guards are false, render 'else' nodes
+ m_falseNodes.render(ts,c);
+ }
+ }
+ private:
+ struct GuardedNodes
+ {
+ GuardedNodes() : guardAst(0) {}
+ ~GuardedNodes() { delete guardAst; }
+ int line;
+ ExprAst *guardAst;
+ TemplateNodeList trueNodes;
+ };
+ QList<GuardedNodes> m_ifGuardedNodes;
+ TemplateNodeList m_falseNodes;
+};
+
+//----------------------------------------------------------
+/** @brief Class representing a 'for' tag in a template */
+class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
+{
+ public:
+ TemplateNodeRepeat(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeRepeat>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeRepeat(%s)\n",data.data()));
+ ExpressionParser expParser(parser,line);
+ m_expr = expParser.parse(data);
+ QStrList stopAt;
+ stopAt.append("endrepeat");
+ parser->parse(this,line,stopAt,m_repeatNodes);
+ parser->removeNextToken(); // skip over endrepeat
+ TRACE(("}TemplateNodeRepeat(%s)\n",data.data()));
+ }
+ ~TemplateNodeRepeat()
+ {
+ delete m_expr;
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ TemplateVariant v;
+ if (m_expr && (v=m_expr->resolve(c)).type()==TemplateVariant::Integer)
+ {
+ int i, n = v.toInt();
+ for (i=0;i<n;i++)
+ {
+ TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
+ s->set("counter0", (int)i);
+ s->set("counter", (int)(i+1));
+ s->set("revcounter", (int)(n-i));
+ s->set("revcounter0", (int)(n-i-1));
+ s->set("first",i==0);
+ s->set("last", i==n-1);
+ c->set("repeatloop",s.get());
+ // render all items for this iteration of the loop
+ m_repeatNodes.render(ts,c);
+ }
+ }
+ else // simple type...
+ {
+ ci->warn(m_templateName,m_line,"for requires a variable of list type!");
+ }
+ }
+ private:
+ TemplateNodeList m_repeatNodes;
+ ExprAst *m_expr;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a 'range' tag in a template */
+class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
+{
+ public:
+ TemplateNodeRange(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeRange>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeRange(%s)\n",data.data()));
+ QCString start,end;
+ int i1 = data.find(" from ");
+ int i2 = data.find(" to ");
+ int i3 = data.find(" downto ");
+ if (i1==-1)
+ {
+ if (data.right(5)==" from")
+ {
+ parser->warn(m_templateName,line,"range missing after 'from' keyword");
+ }
+ else if (data=="from")
+ {
+ parser->warn(m_templateName,line,"range needs an iterator variable and a range");
+ }
+ else
+ {
+ parser->warn(m_templateName,line,"range is missing 'from' keyword");
+ }
+ }
+ else if (i2==-1 && i3==-1)
+ {
+ if (data.right(3)==" to")
+ {
+ parser->warn(m_templateName,line,"range is missing end value after 'to' keyword");
+ }
+ else if (data.right(7)==" downto")
+ {
+ parser->warn(m_templateName,line,"range is missing end value after 'downto' keyword");
+ }
+ else
+ {
+ parser->warn(m_templateName,line,"range is missing 'to' or 'downto' keyword");
+ }
+ }
+ else
+ {
+ m_var = data.left(i1).stripWhiteSpace();
+ if (m_var.isEmpty())
+ {
+ parser->warn(m_templateName,line,"range needs an iterator variable");
+ }
+ start = data.mid(i1+6,i2-i1-6).stripWhiteSpace();
+ if (i2!=-1)
+ {
+ end = data.right(data.length()-i2-4).stripWhiteSpace();
+ m_down = FALSE;
+ }
+ else if (i3!=-1)
+ {
+ end = data.right(data.length()-i3-8).stripWhiteSpace();
+ m_down = TRUE;
+ }
+ }
+ ExpressionParser expParser(parser,line);
+ m_startExpr = expParser.parse(start);
+ m_endExpr = expParser.parse(end);
+
+ QStrList stopAt;
+ stopAt.append("endrange");
+ parser->parse(this,line,stopAt,m_loopNodes);
+ parser->removeNextToken(); // skip over endrange
+ TRACE(("}TemplateNodeRange(%s)\n",data.data()));
+ }
+
+ ~TemplateNodeRange()
+ {
+ delete m_startExpr;
+ delete m_endExpr;
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ //printf("TemplateNodeRange::render #loopNodes=%d\n",
+ // m_loopNodes.count());
+ if (m_startExpr && m_endExpr)
+ {
+ TemplateVariant vs = m_startExpr->resolve(c);
+ TemplateVariant ve = m_endExpr->resolve(c);
+ if (vs.type()==TemplateVariant::Integer && ve.type()==TemplateVariant::Integer)
+ {
+ int s = vs.toInt();
+ int e = ve.toInt();
+ int l = m_down ? s-e+1 : e-s+1;
+ if (l>0)
+ {
+ c->push();
+ //int index = m_reversed ? list.count() : 0;
+ TemplateVariant v;
+ const TemplateVariant *parentLoop = c->getRef("forloop");
+ uint index = 0;
+ int i = m_down ? e : s;
+ bool done=false;
+ while (!done)
+ {
+ // set the forloop meta-data variable
+ TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
+ s->set("counter0", (int)index);
+ s->set("counter", (int)(index+1));
+ s->set("revcounter", (int)(l-index));
+ s->set("revcounter0", (int)(l-index-1));
+ s->set("first",index==0);
+ s->set("last", (int)index==l-1);
+ s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
+ c->set("forloop",s.get());
+
+ // set the iterator variable
+ c->set(m_var,i);
+
+ // render all items for this iteration of the loop
+ m_loopNodes.render(ts,c);
+
+ index++;
+ if (m_down)
+ {
+ i--;
+ done = i<e;
+ }
+ else
+ {
+ i++;
+ done = i>e;
+ }
+ }
+ c->pop();
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"range %d %s %d is empty!",
+ s,m_down?"downto":"to",e);
+ }
+ }
+ else if (vs.type()!=TemplateVariant::Integer)
+ {
+ ci->warn(m_templateName,m_line,"range requires a start value of integer type!");
+ }
+ else if (ve.type()!=TemplateVariant::Integer)
+ {
+ ci->warn(m_templateName,m_line,"range requires an end value of integer type!");
+ }
+ }
+ else if (!m_startExpr)
+ {
+ ci->warn(m_templateName,m_line,"range has empty start value");
+ }
+ else if (!m_endExpr)
+ {
+ ci->warn(m_templateName,m_line,"range has empty end value");
+ }
+ }
+
+ private:
+ bool m_down;
+ ExprAst *m_startExpr;
+ ExprAst *m_endExpr;
+ QCString m_var;
+ TemplateNodeList m_loopNodes;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a 'for' tag in a template */
+class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
+{
+ public:
+ TemplateNodeFor(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeFor>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeFor(%s)\n",data.data()));
+ QCString exprStr;
+ int i = data.find(" in ");
+ if (i==-1)
+ {
+ if (data.right(3)==" in")
+ {
+ parser->warn(m_templateName,line,"for is missing container after 'in' keyword");
+ }
+ else if (data=="in")
+ {
+ parser->warn(m_templateName,line,"for needs at least one iterator variable");
+ }
+ else
+ {
+ parser->warn(m_templateName,line,"for is missing 'in' keyword");
+ }
+ }
+ else
+ {
+ m_vars = split(data.left(i),",");
+ if (m_vars.count()==0)
+ {
+ parser->warn(m_templateName,line,"for needs at least one iterator variable");
+ }
+
+ int j = data.find(" reversed",i);
+ m_reversed = (j!=-1);
+
+ if (j==-1) j=data.length();
+ if (j>i+4)
+ {
+ exprStr = data.mid(i+4,j-i-4); // skip over " in " part
+ }
+ if (exprStr.isEmpty())
+ {
+ parser->warn(m_templateName,line,"for is missing container after 'in' keyword");
+ }
+ }
+ ExpressionParser expParser(parser,line);
+ m_expr = expParser.parse(exprStr);
+
+ QStrList stopAt;
+ stopAt.append("endfor");
+ stopAt.append("empty");
+ parser->parse(this,line,stopAt,m_loopNodes);
+ TemplateToken *tok = parser->takeNextToken();
+ if (tok && tok->data=="empty")
+ {
+ stopAt.removeLast();
+ parser->parse(this,line,stopAt,m_emptyNodes);
+ parser->removeNextToken(); // skip over endfor
+ }
+ delete tok;
+ TRACE(("}TemplateNodeFor(%s)\n",data.data()));
+ }
+
+ ~TemplateNodeFor()
+ {
+ delete m_expr;
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ //printf("TemplateNodeFor::render #loopNodes=%d #emptyNodes=%d\n",
+ // m_loopNodes.count(),m_emptyNodes.count());
+ if (m_expr)
+ {
+ TemplateVariant v = m_expr->resolve(c);
+ if (v.type()==TemplateVariant::Function)
+ {
+ v = v.call(QValueList<TemplateVariant>());
+ }
+ const TemplateListIntf *list = v.toList();
+ if (list)
+ {
+ uint listSize = list->count();
+ if (listSize==0) // empty for loop
+ {
+ m_emptyNodes.render(ts,c);
+ return;
+ }
+ c->push();
+ //int index = m_reversed ? list.count() : 0;
+ TemplateVariant v;
+ const TemplateVariant *parentLoop = c->getRef("forloop");
+ uint index = m_reversed ? listSize-1 : 0;
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ for (m_reversed ? it->toLast() : it->toFirst();
+ (it->current(v));
+ m_reversed ? it->toPrev() : it->toNext())
+ {
+ TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
+ s->set("counter0", (int)index);
+ s->set("counter", (int)(index+1));
+ s->set("revcounter", (int)(listSize-index));
+ s->set("revcounter0", (int)(listSize-index-1));
+ s->set("first",index==0);
+ s->set("last", index==listSize-1);
+ s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
+ c->set("forloop",s.get());
+
+ // add variables for this loop to the context
+ //obj->addVariableToContext(index,m_vars,c);
+ uint vi=0;
+ if (m_vars.count()==1) // loop variable represents an item
+ {
+ c->set(m_vars[vi++],v);
+ }
+ else if (m_vars.count()>1 && v.type()==TemplateVariant::Struct)
+ // loop variables represent elements in a list item
+ {
+ for (uint i=0;i<m_vars.count();i++,vi++)
+ {
+ c->set(m_vars[vi],v.toStruct()->get(m_vars[vi]));
+ }
+ }
+ for (;vi<m_vars.count();vi++)
+ {
+ c->set(m_vars[vi],TemplateVariant());
+ }
+
+ // render all items for this iteration of the loop
+ m_loopNodes.render(ts,c);
+
+ if (m_reversed) index--; else index++;
+ }
+ c->pop();
+ delete it;
+ }
+ else // simple type...
+ {
+ ci->warn(m_templateName,m_line,"for requires a variable of list type, got type '%s'!",v.typeAsString().data());
+ }
+ }
+ }
+
+ private:
+ bool m_reversed;
+ ExprAst *m_expr;
+ QValueList<QCString> m_vars;
+ TemplateNodeList m_loopNodes;
+ TemplateNodeList m_emptyNodes;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'markers' tag in a template */
+class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
+{
+ public:
+ TemplateNodeMsg(TemplateParser *parser,TemplateNode *parent,int line,const QCString &)
+ : TemplateNodeCreator<TemplateNodeMsg>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeMsg()\n"));
+ QStrList stopAt;
+ stopAt.append("endmsg");
+ parser->parse(this,line,stopAt,m_nodes);
+ parser->removeNextToken(); // skip over endmarkers
+ TRACE(("}TemplateNodeMsg()\n"));
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ TemplateEscapeIntf *escIntf = ci->escapeIntf();
+ ci->setActiveEscapeIntf(0); // avoid escaping things we send to standard out
+ bool enable = ci->spacelessEnabled();
+ ci->enableSpaceless(FALSE);
+ FTextStream ts(stdout);
+ m_nodes.render(ts,c);
+ ts << endl;
+ ci->setActiveEscapeIntf(escIntf);
+ ci->enableSpaceless(enable);
+ }
+ private:
+ TemplateNodeList m_nodes;
+};
+
+
+//----------------------------------------------------------
+
+/** @brief Class representing a 'block' tag in a template */
+class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
+{
+ public:
+ TemplateNodeBlock(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeBlock>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeBlock(%s)\n",data.data()));
+ m_blockName = data;
+ if (m_blockName.isEmpty())
+ {
+ parser->warn(parser->templateName(),line,"block tag without name");
+ }
+ QStrList stopAt;
+ stopAt.append("endblock");
+ parser->parse(this,line,stopAt,m_nodes);
+ parser->removeNextToken(); // skip over endblock
+ TRACE(("}TemplateNodeBlock(%s)\n",data.data()));
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ TemplateImpl *t = getTemplate();
+ if (t)
+ {
+ // remove block from the context, so block.super can work
+ TemplateNodeBlock *nb = ci->blockContext()->pop(m_blockName);
+ if (nb) // block is overruled
+ {
+ ci->push();
+ QGString super;
+ FTextStream ss(&super);
+ // get super block of block nb
+ TemplateNodeBlock *sb = ci->blockContext()->get(m_blockName);
+ if (sb && sb!=nb && sb!=this) // nb and sb both overrule this block
+ {
+ sb->render(ss,c); // render parent of nb to string
+ }
+ else if (nb!=this) // only nb overrules this block
+ {
+ m_nodes.render(ss,c); // render parent of nb to string
+ }
+ // add 'block.super' variable to allow access to parent block content
+ TemplateAutoRef<TemplateStruct> superBlock(TemplateStruct::alloc());
+ superBlock->set("super",TemplateVariant(super.data(),TRUE));
+ ci->set("block",superBlock.get());
+ // render the overruled block contents
+ t->engine()->enterBlock(nb->m_templateName,nb->m_blockName,nb->m_line);
+ nb->m_nodes.render(ts,c);
+ t->engine()->leaveBlock();
+ ci->pop();
+ // re-add block to the context
+ ci->blockContext()->push(nb);
+ }
+ else // block has no overrule
+ {
+ t->engine()->enterBlock(m_templateName,m_blockName,m_line);
+ m_nodes.render(ts,c);
+ t->engine()->leaveBlock();
+ }
+ }
+ }
+
+ QCString name() const
+ {
+ return m_blockName;
+ }
+
+ private:
+ QCString m_blockName;
+ TemplateNodeList m_nodes;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing a 'extend' tag in a template */
+class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
+{
+ public:
+ TemplateNodeExtend(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeExtend>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeExtend(%s)\n",data.data()));
+ ExpressionParser ep(parser,line);
+ if (data.isEmpty())
+ {
+ parser->warn(m_templateName,line,"extend tag is missing template file argument");
+ }
+ m_extendExpr = ep.parse(data);
+ QStrList stopAt;
+ parser->parse(this,line,stopAt,m_nodes);
+ TRACE(("}TemplateNodeExtend(%s)\n",data.data()));
+ }
+ ~TemplateNodeExtend()
+ {
+ delete m_extendExpr;
+ }
+
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_extendExpr==0) return;
+
+ QCString extendFile = m_extendExpr->resolve(c).toString();
+ if (extendFile.isEmpty())
+ {
+ ci->warn(m_templateName,m_line,"invalid parameter for extend command");
+ }
+
+ // goto root of tree (template node)
+ TemplateImpl *t = getTemplate();
+ if (t)
+ {
+ Template *bt = t->engine()->loadByName(extendFile,m_line);
+ TemplateImpl *baseTemplate = bt ? dynamic_cast<TemplateImpl*>(bt) : 0;
+ if (baseTemplate)
+ {
+ // fill block context
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ TemplateBlockContext *bc = ci->blockContext();
+
+ // add overruling blocks to the context
+ QListIterator<TemplateNode> li(m_nodes);
+ TemplateNode *n;
+ for (li.toFirst();(n=li.current());++li)
+ {
+ TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n);
+ if (nb)
+ {
+ bc->add(nb);
+ }
+ TemplateNodeMsg *msg = dynamic_cast<TemplateNodeMsg*>(n);
+ if (msg)
+ {
+ msg->render(ts,c);
+ }
+ }
+
+ // render the base template with the given context
+ baseTemplate->render(ts,c);
+
+ // clean up
+ bc->clear();
+ t->engine()->unload(t);
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"failed to load template %s for extend",extendFile.data());
+ }
+ }
+ }
+
+ private:
+ ExprAst *m_extendExpr;
+ TemplateNodeList m_nodes;
+};
+
+/** @brief Class representing an 'include' tag in a template */
+class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
+{
+ public:
+ TemplateNodeInclude(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeInclude>(parser,parent,line)
+ {
+ TRACE(("TemplateNodeInclude(%s)\n",data.data()));
+ ExpressionParser ep(parser,line);
+ if (data.isEmpty())
+ {
+ parser->warn(m_templateName,line,"include tag is missing template file argument");
+ }
+ m_includeExpr = ep.parse(data);
+ }
+ ~TemplateNodeInclude()
+ {
+ delete m_includeExpr;
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_includeExpr)
+ {
+ QCString includeFile = m_includeExpr->resolve(c).toString();
+ if (includeFile.isEmpty())
+ {
+ ci->warn(m_templateName,m_line,"invalid parameter for include command\n");
+ }
+ else
+ {
+ TemplateImpl *t = getTemplate();
+ if (t)
+ {
+ Template *it = t->engine()->loadByName(includeFile,m_line);
+ TemplateImpl *incTemplate = it ? dynamic_cast<TemplateImpl*>(it) : 0;
+ if (incTemplate)
+ {
+ incTemplate->render(ts,c);
+ t->engine()->unload(t);
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"failed to load template '%s' for include",includeFile.data()?includeFile.data():"");
+ }
+ }
+ }
+ }
+ }
+
+ private:
+ ExprAst *m_includeExpr;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'create' tag in a template */
+class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
+{
+ public:
+ TemplateNodeCreate(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeCreate>(parser,parent,line)
+ {
+ TRACE(("TemplateNodeCreate(%s)\n",data.data()));
+ ExpressionParser ep(parser,line);
+ if (data.isEmpty())
+ {
+ parser->warn(m_templateName,line,"create tag is missing arguments");
+ }
+ int i = data.find(" from ");
+ if (i==-1)
+ {
+ if (data.right(3)==" from")
+ {
+ parser->warn(m_templateName,line,"create is missing template name after 'from' keyword");
+ }
+ else if (data=="from")
+ {
+ parser->warn(m_templateName,line,"create needs a file name and a template name");
+ }
+ else
+ {
+ parser->warn(m_templateName,line,"create is missing 'from' keyword");
+ }
+ }
+ else
+ {
+ ExpressionParser ep(parser,line);
+ m_fileExpr = ep.parse(data.left(i).stripWhiteSpace());
+ m_templateExpr = ep.parse(data.mid(i+6).stripWhiteSpace());
+ }
+ }
+ ~TemplateNodeCreate()
+ {
+ delete m_templateExpr;
+ delete m_fileExpr;
+ }
+ void mkpath(TemplateContextImpl *ci,const QCString &fileName)
+ {
+ int i=fileName.find('/');
+ QCString outputDir = ci->outputDirectory();
+ QDir d(outputDir);
+ int j=0;
+ while (i!=-1) // fileName contains path part
+ {
+ if (d.exists())
+ {
+ bool ok = d.mkdir(fileName.mid(j,i-j));
+ if (!ok) break;
+ QCString dirName = outputDir+'/'+fileName.left(i);
+ d = QDir(dirName);
+ j = i+1;
+ }
+ i=fileName.find('/',i+1);
+ }
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_templateExpr && m_fileExpr)
+ {
+ QCString templateFile = m_templateExpr->resolve(c).toString();
+ QCString outputFile = m_fileExpr->resolve(c).toString();
+ if (templateFile.isEmpty())
+ {
+ ci->warn(m_templateName,m_line,"empty template name parameter for create command\n");
+ }
+ else if (outputFile.isEmpty())
+ {
+ ci->warn(m_templateName,m_line,"empty file name parameter for create command\n");
+ }
+ else
+ {
+ TemplateImpl *t = getTemplate();
+ if (t)
+ {
+ Template *ct = t->engine()->loadByName(templateFile,m_line);
+ TemplateImpl *createTemplate = ct ? dynamic_cast<TemplateImpl*>(ct) : 0;
+ if (createTemplate)
+ {
+ //mkpath(ci,outputFile);
+ QCString extension=outputFile;
+ int i=extension.findRev('.');
+ if (i!=-1)
+ {
+ extension=extension.right(extension.length()-i-1);
+ }
+ if (!ci->outputDirectory().isEmpty())
+ {
+ outputFile.prepend(ci->outputDirectory()+"/");
+ }
+ QFile f(outputFile);
+ if (f.open(IO_WriteOnly))
+ {
+ TemplateEscapeIntf *escIntf = ci->escapeIntf();
+ ci->selectEscapeIntf(extension);
+ FTextStream ts(&f);
+ createTemplate->render(ts,c);
+ t->engine()->unload(t);
+ ci->setActiveEscapeIntf(escIntf);
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"failed to open output file '%s' for create command",outputFile.data());
+ }
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"failed to load template '%s' for include",templateFile.data());
+ }
+ }
+ }
+ }
+ }
+
+ private:
+ ExprAst *m_templateExpr;
+ ExprAst *m_fileExpr;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'tree' tag in a template */
+class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
+{
+ struct TreeContext
+ {
+ TreeContext(TemplateNodeTree *o,const TemplateListIntf *l,TemplateContext *c)
+ : object(o), list(l), templateCtx(c) {}
+ TemplateNodeTree *object;
+ const TemplateListIntf *list;
+ TemplateContext *templateCtx;
+ };
+ public:
+ TemplateNodeTree(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeTree>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeTree(%s)\n",data.data()));
+ ExpressionParser ep(parser,line);
+ if (data.isEmpty())
+ {
+ parser->warn(m_templateName,line,"recursetree tag is missing data argument");
+ }
+ m_treeExpr = ep.parse(data);
+ QStrList stopAt;
+ stopAt.append("endrecursetree");
+ parser->parse(this,line,stopAt,m_treeNodes);
+ parser->removeNextToken(); // skip over endrecursetree
+ TRACE(("}TemplateNodeTree(%s)\n",data.data()));
+ }
+ ~TemplateNodeTree()
+ {
+ delete m_treeExpr;
+ }
+ static TemplateVariant renderChildrenStub(const void *ctx, const QValueList<TemplateVariant> &)
+ {
+ return TemplateVariant(((TreeContext*)ctx)->object->
+ renderChildren((const TreeContext*)ctx),TRUE);
+ }
+ QCString renderChildren(const TreeContext *ctx)
+ {
+ //printf("TemplateNodeTree::renderChildren(%d)\n",ctx->list->count());
+ // render all children of node to a string and return it
+ QGString result;
+ FTextStream ss(&result);
+ TemplateContext *c = ctx->templateCtx;
+ c->push();
+ TemplateVariant node;
+ TemplateListIntf::ConstIterator *it = ctx->list->createIterator();
+ for (it->toFirst();(it->current(node));it->toNext())
+ {
+ c->set("node",node);
+ bool hasChildren=FALSE;
+ const TemplateStructIntf *ns = node.toStruct();
+ if (ns) // node is a struct
+ {
+ TemplateVariant v = ns->get("children");
+ if (v.isValid()) // with a field 'children'
+ {
+ const TemplateListIntf *list = v.toList();
+ if (list && list->count()>0) // non-empty list
+ {
+ TreeContext childCtx(this,list,ctx->templateCtx);
+// TemplateVariant children(&childCtx,renderChildrenStub);
+ TemplateVariant children(TemplateVariant::Delegate::fromFunction(&childCtx,renderChildrenStub));
+ children.setRaw(TRUE);
+ c->set("children",children);
+ m_treeNodes.render(ss,c);
+ hasChildren=TRUE;
+ }
+ }
+ }
+ if (!hasChildren)
+ {
+ c->set("children",TemplateVariant("")); // provide default
+ m_treeNodes.render(ss,c);
+ }
+ }
+ c->pop();
+ return result.data();
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ //printf("TemplateNodeTree::render()\n");
+ TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ TemplateVariant v = m_treeExpr->resolve(c);
+ const TemplateListIntf *list = v.toList();
+ if (list)
+ {
+ TreeContext ctx(this,list,c);
+ ts << renderChildren(&ctx);
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"recursetree's argument should be a list type");
+ }
+ }
+
+ private:
+ ExprAst *m_treeExpr;
+ TemplateNodeList m_treeNodes;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'indexentry' tag in a template */
+class TemplateNodeIndexEntry : public TemplateNodeCreator<TemplateNodeIndexEntry>
+{
+ struct Mapping
+ {
+ Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
+ ~Mapping() { delete value; }
+ QCString name;
+ ExprAst *value;
+ };
+ public:
+ TemplateNodeIndexEntry(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeIndexEntry>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeIndexEntry(%s)\n",data.data()));
+ m_args.setAutoDelete(TRUE);
+ ExpressionParser expParser(parser,line);
+ QValueList<QCString> args = split(data," ");
+ QValueListIterator<QCString> it = args.begin();
+ if (it==args.end() || (*it).find('=')!=-1)
+ {
+ parser->warn(parser->templateName(),line,"Missing name for indexentry tag");
+ }
+ else
+ {
+ m_name = *it;
+ ++it;
+ while (it!=args.end())
+ {
+ QCString arg = *it;
+ int j=arg.find('=');
+ if (j>0)
+ {
+ ExprAst *expr = expParser.parse(arg.mid(j+1));
+ if (expr)
+ {
+ m_args.append(new Mapping(arg.left(j),expr));
+ }
+ }
+ else
+ {
+ parser->warn(parser->templateName(),line,"invalid argument '%s' for indexentry tag",arg.data());
+ }
+ ++it;
+ }
+ }
+ TRACE(("}TemplateNodeIndexEntry(%s)\n",data.data()));
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ if (!m_name.isEmpty())
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ QListIterator<Mapping> it(m_args);
+ Mapping *mapping;
+ QValueList<TemplateKeyValue> list;
+ for (it.toFirst();(mapping=it.current());++it)
+ {
+ list.append(TemplateKeyValue(mapping->name,mapping->value->resolve(c)));
+ }
+ ci->addIndexEntry(m_name,list);
+ }
+ }
+ private:
+ QCString m_name;
+ QList<Mapping> m_args;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'opensubindex' tag in a template */
+class TemplateNodeOpenSubIndex : public TemplateNodeCreator<TemplateNodeOpenSubIndex>
+{
+ public:
+ TemplateNodeOpenSubIndex(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeOpenSubIndex>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeOpenSubIndex(%s)\n",data.data()));
+ m_name = data.stripWhiteSpace();
+ if (m_name.isEmpty())
+ {
+ parser->warn(parser->templateName(),line,"Missing argument for opensubindex tag");
+ }
+ else if (m_name.find(' ')!=-1)
+ {
+ parser->warn(parser->templateName(),line,"Expected single argument for opensubindex tag got '%s'",data.data());
+ m_name="";
+ }
+ TRACE(("}TemplateNodeOpenSubIndex(%s)\n",data.data()));
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ if (!m_name.isEmpty())
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ ci->openSubIndex(m_name);
+ }
+ }
+ private:
+ QCString m_name;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'closesubindex' tag in a template */
+class TemplateNodeCloseSubIndex : public TemplateNodeCreator<TemplateNodeCloseSubIndex>
+{
+ public:
+ TemplateNodeCloseSubIndex(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeCloseSubIndex>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeCloseSubIndex(%s)\n",data.data()));
+ m_name = data.stripWhiteSpace();
+ if (m_name.isEmpty())
+ {
+ parser->warn(parser->templateName(),line,"Missing argument for closesubindex tag");
+ }
+ else if (m_name.find(' ')!=-1 || m_name.isEmpty())
+ {
+ parser->warn(parser->templateName(),line,"Expected single argument for closesubindex tag got '%s'",data.data());
+ m_name="";
+ }
+ TRACE(("}TemplateNodeCloseSubIndex(%s)\n",data.data()));
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ if (!m_name.isEmpty())
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ ci->closeSubIndex(m_name);
+ }
+ }
+ private:
+ QCString m_name;
+};
+
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'with' tag in a template */
+class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
+{
+ struct Mapping
+ {
+ Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
+ ~Mapping() { delete value; }
+ QCString name;
+ ExprAst *value;
+ };
+ public:
+ TemplateNodeWith(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeWith>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeWith(%s)\n",data.data()));
+ m_args.setAutoDelete(TRUE);
+ ExpressionParser expParser(parser,line);
+ QValueList<QCString> args = split(data," ");
+ QValueListIterator<QCString> it = args.begin();
+ while (it!=args.end())
+ {
+ QCString arg = *it;
+ int j=arg.find('=');
+ if (j>0)
+ {
+ ExprAst *expr = expParser.parse(arg.mid(j+1));
+ if (expr)
+ {
+ m_args.append(new Mapping(arg.left(j),expr));
+ }
+ }
+ else
+ {
+ parser->warn(parser->templateName(),line,"invalid argument '%s' for 'with' tag",arg.data());
+ }
+ ++it;
+ }
+ QStrList stopAt;
+ stopAt.append("endwith");
+ parser->parse(this,line,stopAt,m_nodes);
+ parser->removeNextToken(); // skip over endwith
+ TRACE(("}TemplateNodeWith(%s)\n",data.data()));
+ }
+ ~TemplateNodeWith()
+ {
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ c->push();
+ QListIterator<Mapping> it(m_args);
+ Mapping *mapping;
+ for (it.toFirst();(mapping=it.current());++it)
+ {
+ TemplateVariant value = mapping->value->resolve(c);
+ ci->set(mapping->name,value);
+ }
+ m_nodes.render(ts,c);
+ c->pop();
+ }
+ private:
+ TemplateNodeList m_nodes;
+ QList<Mapping> m_args;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'set' tag in a template */
+class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
+{
+ public:
+ TemplateNodeCycle(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeCycle>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeCycle(%s)\n",data.data()));
+ m_args.setAutoDelete(TRUE);
+ m_index=0;
+ ExpressionParser expParser(parser,line);
+ QValueList<QCString> args = split(data," ");
+ QValueListIterator<QCString> it = args.begin();
+ while (it!=args.end())
+ {
+ ExprAst *expr = expParser.parse(*it);
+ if (expr)
+ {
+ m_args.append(expr);
+ }
+ ++it;
+ }
+ if (m_args.count()<2)
+ {
+ parser->warn(parser->templateName(),line,"expected at least two arguments for cycle command, got %d",m_args.count());
+ }
+ TRACE(("}TemplateNodeCycle(%s)\n",data.data()));
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_index<m_args.count())
+ {
+ TemplateVariant v = m_args.at(m_index)->resolve(c);
+ if (v.type()==TemplateVariant::Function)
+ {
+ v = v.call(QValueList<TemplateVariant>());
+ }
+ if (ci->escapeIntf() && !v.raw())
+ {
+ ts << ci->escapeIntf()->escape(v.toString());
+ }
+ else
+ {
+ ts << v.toString();
+ }
+ }
+ if (++m_index==m_args.count()) // wrap around
+ {
+ m_index=0;
+ }
+ }
+ private:
+ uint m_index;
+ QList<ExprAst> m_args;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'set' tag in a template */
+class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
+{
+ struct Mapping
+ {
+ Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
+ ~Mapping() { delete value; }
+ QCString name;
+ ExprAst *value;
+ };
+ public:
+ TemplateNodeSet(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeSet>(parser,parent,line), m_mapping(0)
+ {
+ TRACE(("{TemplateNodeSet(%s)\n",data.data()));
+ ExpressionParser expParser(parser,line);
+ // data format: name=expression
+ int j=data.find('=');
+ ExprAst *expr = 0;
+ if (j>0 && (expr = expParser.parse(data.mid(j+1))))
+ {
+ m_mapping = new Mapping(data.left(j),expr);
+ }
+ TRACE(("}TemplateNodeSet(%s)\n",data.data()));
+ }
+ ~TemplateNodeSet()
+ {
+ delete m_mapping;
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (m_mapping)
+ {
+ TemplateVariant value = m_mapping->value->resolve(c);
+ ci->set(m_mapping->name,value);
+ }
+ }
+ private:
+ Mapping *m_mapping;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'spaceless' tag in a template */
+class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
+{
+ public:
+ TemplateNodeSpaceless(TemplateParser *parser,TemplateNode *parent,int line,const QCString &)
+ : TemplateNodeCreator<TemplateNodeSpaceless>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeSpaceless()\n"));
+ QStrList stopAt;
+ stopAt.append("endspaceless");
+ parser->parse(this,line,stopAt,m_nodes);
+ parser->removeNextToken(); // skip over endwith
+ TRACE(("}TemplateNodeSpaceless()\n"));
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ bool wasSpaceless = ci->spacelessEnabled();
+ ci->enableSpaceless(TRUE);
+ m_nodes.render(ts,c);
+ ci->enableSpaceless(wasSpaceless);
+ }
+ private:
+ TemplateNodeList m_nodes;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'markers' tag in a template */
+class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
+{
+ public:
+ TemplateNodeMarkers(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeMarkers>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeMarkers(%s)\n",data.data()));
+ int i = data.find(" in ");
+ int w = data.find(" with ");
+ if (i==-1 || w==-1 || w<i)
+ {
+ parser->warn(m_templateName,line,"markers tag as wrong format. Expected: markers <var> in <list> with <string_with_markers>");
+ }
+ else
+ {
+ ExpressionParser expParser(parser,line);
+ m_var = data.left(i);
+ m_listExpr = expParser.parse(data.mid(i+4,w-i-4));
+ m_patternExpr = expParser.parse(data.right(data.length()-w-6));
+ }
+ QStrList stopAt;
+ stopAt.append("endmarkers");
+ parser->parse(this,line,stopAt,m_nodes);
+ parser->removeNextToken(); // skip over endmarkers
+ TRACE(("}TemplateNodeMarkers(%s)\n",data.data()));
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ ci->setLocation(m_templateName,m_line);
+ if (!m_var.isEmpty() && m_listExpr && m_patternExpr)
+ {
+ TemplateVariant v = m_listExpr->resolve(c);
+ const TemplateListIntf *list = v.toList();
+ TemplateVariant patternStr = m_patternExpr->resolve(c);
+ if (list)
+ {
+ if (patternStr.type()==TemplateVariant::String)
+ {
+ TemplateListIntf::ConstIterator *it = list->createIterator();
+ c->push();
+ QCString str = patternStr.toString();
+ QRegExp marker("@[0-9]+"); // pattern for a marker, i.e. @0, @1 ... @12, etc
+ int index=0,newIndex,matchLen;
+ while ((newIndex=marker.match(str,index,&matchLen))!=-1)
+ {
+ ts << str.mid(index,newIndex-index); // write text before marker
+ bool ok;
+ uint entryIndex = str.mid(newIndex+1,matchLen-1).toUInt(&ok); // get marker id
+ TemplateVariant var;
+ uint i=0;
+ // search for list element at position id
+ for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {}
+ if (ok && i==entryIndex) // found element
+ {
+ TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
+ s->set("id",(int)i);
+ c->set("markers",s.get());
+ c->set(m_var,var); // define local variable to hold element of list type
+ bool wasSpaceless = ci->spacelessEnabled();
+ ci->enableSpaceless(TRUE);
+ m_nodes.render(ts,c);
+ ci->enableSpaceless(wasSpaceless);
+ }
+ else if (!ok)
+ {
+ ci->warn(m_templateName,m_line,"markers pattern string has invalid markers '%s'",str.data());
+ }
+ else if (i<entryIndex)
+ {
+ ci->warn(m_templateName,m_line,"markers list does not an element for marker position %d",i);
+ }
+ index=newIndex+matchLen; // set index just after marker
+ }
+ ts << str.right(str.length()-index); // write text after last marker
+ c->pop();
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"markers requires a parameter of string type after 'with'!");
+ }
+ }
+ else
+ {
+ ci->warn(m_templateName,m_line,"markers requires a parameter of list type after 'in'!");
+ }
+ }
+ }
+ private:
+ TemplateNodeList m_nodes;
+ QCString m_var;
+ ExprAst *m_listExpr;
+ ExprAst *m_patternExpr;
+};
+
+//----------------------------------------------------------
+
+/** @brief Factory class for creating tag AST nodes found in a template */
+class TemplateNodeFactory
+{
+ public:
+ typedef TemplateNode *(*CreateFunc)(TemplateParser *parser,
+ TemplateNode *parent,
+ int line,
+ const QCString &data);
+
+ static TemplateNodeFactory *instance()
+ {
+ static TemplateNodeFactory *instance = 0;
+ if (instance==0) instance = new TemplateNodeFactory;
+ return instance;
+ }
+
+ TemplateNode *create(const QCString &name,
+ TemplateParser *parser,
+ TemplateNode *parent,
+ int line,
+ const QCString &data)
+ {
+ if (m_registry.find(name)==0) return 0;
+ return ((CreateFunc)m_registry[name])(parser,parent,line,data);
+ }
+
+ void registerTemplateNode(const QCString &name,CreateFunc func)
+ {
+ m_registry.insert(name,(void*)func);
+ }
+
+ /** @brief Helper class for registering a template AST node */
+ template<class T> class AutoRegister
+ {
+ public:
+ AutoRegister<T>(const QCString &key)
+ {
+ TemplateNodeFactory::instance()->registerTemplateNode(key,T::createInstance);
+ }
+ };
+
+ private:
+ QDict<void> m_registry;
+};
+
+// register a handler for each start tag we support
+static TemplateNodeFactory::AutoRegister<TemplateNodeIf> autoRefIf("if");
+static TemplateNodeFactory::AutoRegister<TemplateNodeFor> autoRefFor("for");
+static TemplateNodeFactory::AutoRegister<TemplateNodeMsg> autoRefMsg("msg");
+static TemplateNodeFactory::AutoRegister<TemplateNodeSet> autoRefSet("set");
+static TemplateNodeFactory::AutoRegister<TemplateNodeTree> autoRefTree("recursetree");
+static TemplateNodeFactory::AutoRegister<TemplateNodeWith> autoRefWith("with");
+static TemplateNodeFactory::AutoRegister<TemplateNodeBlock> autoRefBlock("block");
+static TemplateNodeFactory::AutoRegister<TemplateNodeCycle> autoRefCycle("cycle");
+static TemplateNodeFactory::AutoRegister<TemplateNodeRange> autoRefRange("range");
+static TemplateNodeFactory::AutoRegister<TemplateNodeExtend> autoRefExtend("extend");
+static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreate("create");
+static TemplateNodeFactory::AutoRegister<TemplateNodeRepeat> autoRefRepeat("repeat");
+static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include");
+static TemplateNodeFactory::AutoRegister<TemplateNodeMarkers> autoRefMarkers("markers");
+static TemplateNodeFactory::AutoRegister<TemplateNodeSpaceless> autoRefSpaceless("spaceless");
+static TemplateNodeFactory::AutoRegister<TemplateNodeIndexEntry> autoRefIndexEntry("indexentry");
+static TemplateNodeFactory::AutoRegister<TemplateNodeOpenSubIndex> autoRefOpenSubIndex("opensubindex");
+static TemplateNodeFactory::AutoRegister<TemplateNodeCloseSubIndex> autoRefCloseSubIndex("closesubindex");
+
+//----------------------------------------------------------
+
+TemplateBlockContext::TemplateBlockContext() : m_blocks(257)
+{
+ m_blocks.setAutoDelete(TRUE);
+}
+
+TemplateNodeBlock *TemplateBlockContext::get(const QCString &name) const
+{
+ QList<TemplateNodeBlock> *list = m_blocks.find(name);
+ if (list==0 || list->count()==0)
+ {
+ return 0;
+ }
+ else
+ {
+ return list->getLast();
+ }
+}
+
+TemplateNodeBlock *TemplateBlockContext::pop(const QCString &name) const
+{
+ QList<TemplateNodeBlock> *list = m_blocks.find(name);
+ if (list==0 || list->count()==0)
+ {
+ return 0;
+ }
+ else
+ {
+ return list->take(list->count()-1);
+ }
+}
+
+void TemplateBlockContext::add(TemplateNodeBlock *block)
+{
+ QList<TemplateNodeBlock> *list = m_blocks.find(block->name());
+ if (list==0)
+ {
+ list = new QList<TemplateNodeBlock>;
+ m_blocks.insert(block->name(),list);
+ }
+ list->prepend(block);
+}
+
+void TemplateBlockContext::add(TemplateBlockContext *ctx)
+{
+ QDictIterator< QList<TemplateNodeBlock> > di(ctx->m_blocks);
+ QList<TemplateNodeBlock> *list;
+ for (di.toFirst();(list=di.current());++di)
+ {
+ QListIterator<TemplateNodeBlock> li(*list);
+ TemplateNodeBlock *nb;
+ for (li.toFirst();(nb=li.current());++li)
+ {
+ add(nb);
+ }
+ }
+}
+
+void TemplateBlockContext::clear()
+{
+ m_blocks.clear();
+}
+
+void TemplateBlockContext::push(TemplateNodeBlock *block)
+{
+ QList<TemplateNodeBlock> *list = m_blocks.find(block->name());
+ if (list==0)
+ {
+ list = new QList<TemplateNodeBlock>;
+ m_blocks.insert(block->name(),list);
+ }
+ list->append(block);
+}
+
+
+//----------------------------------------------------------
+
+/** @brief Lexer class for turning a template into a list of tokens */
+class TemplateLexer
+{
+ public:
+ TemplateLexer(const TemplateEngine *engine,const QCString &fileName,const QCString &data);
+ void tokenize(QList<TemplateToken> &tokens);
+ private:
+ void addToken(QList<TemplateToken> &tokens,
+ const char *data,int line,int startPos,int endPos,
+ TemplateToken::Type type);
+ void reset();
+ const TemplateEngine *m_engine;
+ QCString m_fileName;
+ QCString m_data;
+};
+
+TemplateLexer::TemplateLexer(const TemplateEngine *engine,const QCString &fileName,const QCString &data) :
+ m_engine(engine), m_fileName(fileName), m_data(data)
+{
+}
+
+void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
+{
+ enum LexerStates
+ {
+ StateText,
+ StateBeginTemplate,
+ StateTag,
+ StateEndTag,
+ StateComment,
+ StateEndComment,
+ StateMaybeVar,
+ StateVariable,
+ StateEndVariable
+ };
+
+ const char *p=m_data.data();
+ int state=StateText;
+ int pos=0;
+ int lastTokenPos=0;
+ int startLinePos=0;
+ bool emptyOutputLine=TRUE;
+ int line=1;
+ char c;
+ int markStartPos=-1;
+ for (;(c=*p);p++,pos++)
+ {
+ switch (state)
+ {
+ case StateText:
+ if (c=='{') // {{ or {% or {# or something else
+ {
+ state=StateBeginTemplate;
+ }
+ else if (c!=' ' && c!='\t' && c!='\n') // non-whitepace text
+ {
+ emptyOutputLine=FALSE;
+ }
+ break;
+ case StateBeginTemplate:
+ switch (c)
+ {
+ case '%': // {%
+ state=StateTag;
+ markStartPos=pos-1;
+ break;
+ case '#': // {#
+ state=StateComment;
+ markStartPos=pos-1;
+ break;
+ case '{': // {{
+ state=StateMaybeVar;
+ markStartPos=pos-1;
+ break;
+ default:
+ state=StateText;
+ emptyOutputLine=FALSE;
+ break;
+ }
+ break;
+ case StateTag:
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {%%...%%} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ else if (c=='%') // %} or something else
+ {
+ state=StateEndTag;
+ }
+ break;
+ case StateEndTag:
+ if (c=='}') // %}
+ {
+ // found tag!
+ state=StateText;
+ addToken(tokens,m_data.data(),line,lastTokenPos,
+ emptyOutputLine ? startLinePos : markStartPos,
+ TemplateToken::Text);
+ addToken(tokens,m_data.data(),line,markStartPos+2,
+ pos-1,TemplateToken::Block);
+ lastTokenPos = pos+1;
+ }
+ else // something else
+ {
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {%%...%%} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ state=StateTag;
+ }
+ break;
+ case StateComment:
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {#...#} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ else if (c=='#') // #} or something else
+ {
+ state=StateEndComment;
+ }
+ break;
+ case StateEndComment:
+ if (c=='}') // #}
+ {
+ // found comment tag!
+ state=StateText;
+ addToken(tokens,m_data.data(),line,lastTokenPos,
+ emptyOutputLine ? startLinePos : markStartPos,
+ TemplateToken::Text);
+ lastTokenPos = pos+1;
+ }
+ else // something else
+ {
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {#...#} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ state=StateComment;
+ }
+ break;
+ case StateMaybeVar:
+ switch (c)
+ {
+ case '#': // {{#
+ state=StateComment;
+ markStartPos=pos-1;
+ break;
+ case '%': // {{%
+ state=StateTag;
+ markStartPos=pos-1;
+ break;
+ default: // {{
+ state=StateVariable;
+ break;
+ }
+ break;
+ case StateVariable:
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {{...}} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ else if (c=='}') // }} or something else
+ {
+ state=StateEndVariable;
+ }
+ break;
+ case StateEndVariable:
+ if (c=='}') // }}
+ {
+ // found variable tag!
+ state=StateText;
+ addToken(tokens,m_data.data(),line,lastTokenPos,
+ emptyOutputLine ? startLinePos : markStartPos,
+ TemplateToken::Text);
+ addToken(tokens,m_data.data(),line,markStartPos+2,
+ pos-1,TemplateToken::Variable);
+ lastTokenPos = pos+1;
+ }
+ else // something else
+ {
+ if (c=='\n')
+ {
+ warn(m_fileName,line,"unexpected new line inside {{...}} block");
+ m_engine->printIncludeContext(m_fileName,line);
+ }
+ state=StateVariable;
+ }
+ break;
+ }
+ if (c=='\n') // new line
+ {
+ state=StateText;
+ startLinePos=pos+1;
+ // if the current line only contain commands and whitespace,
+ // then skip it in the output by moving lastTokenPos
+ if (markStartPos!=-1 && emptyOutputLine) lastTokenPos = startLinePos;
+ // reset markers
+ markStartPos=-1;
+ line++;
+ emptyOutputLine=TRUE;
+ }
+ }
+ if (lastTokenPos<pos)
+ {
+ addToken(tokens,m_data.data(),line,
+ lastTokenPos,pos,
+ TemplateToken::Text);
+ }
+}
+
+void TemplateLexer::addToken(QList<TemplateToken> &tokens,
+ const char *data,int line,
+ int startPos,int endPos,
+ TemplateToken::Type type)
+{
+ if (startPos<endPos)
+ {
+ int len = endPos-startPos+1;
+ QCString text(len+1);
+ qstrncpy(text.data(),data+startPos,len);
+ text[len]='\0';
+ if (type!=TemplateToken::Text) text = text.stripWhiteSpace();
+ tokens.append(new TemplateToken(type,text,line));
+ }
+}
+
+//----------------------------------------------------------
+
+TemplateParser::TemplateParser(const TemplateEngine *engine,
+ const QCString &templateName,
+ QList<TemplateToken> &tokens) :
+ m_engine(engine), m_templateName(templateName), m_tokens(tokens)
+{
+}
+
+void TemplateParser::parse(
+ TemplateNode *parent,int line,const QStrList &stopAt,
+ QList<TemplateNode> &nodes)
+{
+ TRACE(("{TemplateParser::parse\n"));
+ // process the tokens. Build node list
+ while (hasNextToken())
+ {
+ TemplateToken *tok = takeNextToken();
+ //printf("%p:Token type=%d data='%s' line=%d\n",
+ // parent,tok->type,tok->data.data(),tok->line);
+ switch(tok->type)
+ {
+ case TemplateToken::Text:
+ nodes.append(new TemplateNodeText(this,parent,tok->line,tok->data));
+ break;
+ case TemplateToken::Variable: // {{ var }}
+ nodes.append(new TemplateNodeVariable(this,parent,tok->line,tok->data));
+ break;
+ case TemplateToken::Block: // {% tag %}
+ {
+ QCString command = tok->data;
+ int sep = command.find(' ');
+ if (sep!=-1)
+ {
+ command=command.left(sep);
+ }
+ if (stopAt.contains(command))
+ {
+ prependToken(tok);
+ TRACE(("}TemplateParser::parse: stop\n"));
+ return;
+ }
+ QCString arg;
+ if (sep!=-1)
+ {
+ arg = tok->data.mid(sep+1);
+ }
+ TemplateNode *node = TemplateNodeFactory::instance()->
+ create(command,this,parent,tok->line,arg);
+ if (node)
+ {
+ nodes.append(node);
+ }
+ else if (command=="empty" || command=="else" ||
+ command=="endif" || command=="endfor" ||
+ command=="endblock" || command=="endwith" ||
+ command=="endrecursetree" || command=="endspaceless" ||
+ command=="endmarkers" || command=="endmsg" ||
+ command=="endrepeat" || command=="elif" ||
+ command=="endrange")
+ {
+ warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data());
+ }
+ else
+ {
+ warn(m_templateName,tok->line,"Unknown tag '%s'",command.data());
+ }
+ }
+ break;
+ }
+ delete tok;
+ }
+ if (!stopAt.isEmpty())
+ {
+ QStrListIterator it(stopAt);
+ const char *s;
+ QCString options;
+ for (it.toFirst();(s=it.current());++it)
+ {
+ if (!options.isEmpty()) options+=", ";
+ options+=s;
+ }
+ warn(m_templateName,line,"Unclosed tag in template, expected one of: %s",
+ options.data());
+ }
+ TRACE(("}TemplateParser::parse: last token\n"));
+}
+
+bool TemplateParser::hasNextToken() const
+{
+ return !m_tokens.isEmpty();
+}
+
+TemplateToken *TemplateParser::takeNextToken()
+{
+ return m_tokens.take(0);
+}
+
+const TemplateToken *TemplateParser::currentToken() const
+{
+ return m_tokens.getFirst();
+};
+
+void TemplateParser::removeNextToken()
+{
+ m_tokens.removeFirst();
+}
+
+void TemplateParser::prependToken(const TemplateToken *token)
+{
+ m_tokens.prepend(token);
+}
+
+void TemplateParser::warn(const char *fileName,int line,const char *fmt,...) const
+{
+ va_list args;
+ va_start(args,fmt);
+ va_warn(fileName,line,fmt,args);
+ va_end(args);
+ m_engine->printIncludeContext(fileName,line);
+}
+
+
+
+//----------------------------------------------------------
+
+
+TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const QCString &data)
+ : TemplateNode(0)
+{
+ m_name = name;
+ m_engine = engine;
+ TemplateLexer lexer(engine,name,data);
+ QList<TemplateToken> tokens;
+ tokens.setAutoDelete(TRUE);
+ lexer.tokenize(tokens);
+ TemplateParser parser(engine,name,tokens);
+ parser.parse(this,1,QStrList(),m_nodes);
+}
+
+void TemplateImpl::render(FTextStream &ts, TemplateContext *c)
+{
+ if (!m_nodes.isEmpty())
+ {
+ TemplateNodeExtend *ne = dynamic_cast<TemplateNodeExtend*>(m_nodes.getFirst());
+ if (ne==0) // normal template, add blocks to block context
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ TemplateBlockContext *bc = ci->blockContext();
+ QListIterator<TemplateNode> li(m_nodes);
+ TemplateNode *n;
+ for (li.toFirst();(n=li.current());++li)
+ {
+ TemplateNodeBlock *nb = dynamic_cast<TemplateNodeBlock*>(n);
+ if (nb)
+ {
+ bc->add(nb);
+ }
+ }
+ }
+ m_nodes.render(ts,c);
+ }
+}
+
+//----------------------------------------------------------
+
+/** @brief Private data of the template engine */
+class TemplateEngine::Private
+{
+ class IncludeEntry
+ {
+ public:
+ enum Type { Template, Block };
+ IncludeEntry(Type type,const QCString &fileName,const QCString &blockName,int line)
+ : m_type(type), m_fileName(fileName), m_blockName(blockName), m_line(line) {}
+ Type type() const { return m_type; }
+ QCString fileName() const { return m_fileName; }
+ QCString blockName() const { return m_blockName; }
+ int line() const { return m_line; }
+
+ private:
+ Type m_type;
+ QCString m_fileName;
+ QCString m_blockName;
+ int m_line;
+ };
+ public:
+ Private(TemplateEngine *engine) : m_templateCache(17) /*, m_indent(0)*/, m_engine(engine)
+ {
+ m_templateCache.setAutoDelete(TRUE);
+ m_includeStack.setAutoDelete(TRUE);
+ }
+ Template *loadByName(const QCString &fileName,int line)
+ {
+ //for (int i=0;i<m_indent;i++) printf(" ");
+ //m_indent++;
+ //printf("loadByName(%s,%d) {\n",fileName.data(),line);
+ m_includeStack.append(new IncludeEntry(IncludeEntry::Template,fileName,QCString(),line));
+ Template *templ = m_templateCache.find(fileName);
+ if (templ==0)
+ {
+ QFile f(fileName);
+ if (f.open(IO_ReadOnly))
+ {
+ uint size=f.size();
+ char *data = new char[size+1];
+ if (data)
+ {
+ data[size]=0;
+ if (f.readBlock(data,f.size()))
+ {
+ templ = new TemplateImpl(m_engine,fileName,data);
+ m_templateCache.insert(fileName,templ);
+ }
+ delete[] data;
+ }
+ }
+ else
+ {
+ err("Cound not open template file %s\n",fileName.data());
+ }
+ }
+ return templ;
+ }
+ void unload(Template * /*t*/)
+ {
+ //(void)t;
+ //m_indent--;
+ //for (int i=0;i<m_indent;i++) printf(" ");
+ //printf("}\n");
+ m_includeStack.removeLast();
+ }
+
+ void enterBlock(const QCString &fileName,const QCString &blockName,int line)
+ {
+ //for (int i=0;i<m_indent;i++) printf(" ");
+ //m_indent++;
+ //printf("enterBlock(%s,%s,%d) {\n",fileName.data(),blockName.data(),line);
+ m_includeStack.append(new IncludeEntry(IncludeEntry::Block,fileName,blockName,line));
+ }
+
+ void leaveBlock()
+ {
+ //m_indent--;
+ //for (int i=0;i<m_indent;i++) printf(" ");
+ //printf("}\n");
+ m_includeStack.removeLast();
+ }
+
+ void printIncludeContext(const char *fileName,int line) const
+ {
+ QListIterator<IncludeEntry> li(m_includeStack);
+ li.toLast();
+ IncludeEntry *ie=li.current();
+ while ((ie=li.current()))
+ {
+ --li;
+ IncludeEntry *next=li.current();
+ if (ie->type()==IncludeEntry::Template)
+ {
+ if (next)
+ {
+ warn(fileName,line," inside template '%s' included from template '%s' at line %d",ie->fileName().data(),next->fileName().data(),ie->line());
+ }
+ }
+ else // ie->type()==IncludeEntry::Block
+ {
+ warn(fileName,line," included by block '%s' inside template '%s' at line %d",ie->blockName().data(),
+ ie->fileName().data(),ie->line());
+ }
+ }
+ }
+
+ private:
+ QDict<Template> m_templateCache;
+ //mutable int m_indent;
+ TemplateEngine *m_engine;
+ QList<IncludeEntry> m_includeStack;
+};
+
+TemplateEngine::TemplateEngine()
+{
+ p = new Private(this);
+}
+
+TemplateEngine::~TemplateEngine()
+{
+ delete p;
+}
+
+TemplateContext *TemplateEngine::createContext() const
+{
+ return new TemplateContextImpl(this);
+}
+
+void TemplateEngine::destroyContext(TemplateContext *ctx)
+{
+ delete ctx;
+}
+
+Template *TemplateEngine::loadByName(const QCString &fileName,int line)
+{
+ return p->loadByName(fileName,line);
+}
+
+void TemplateEngine::unload(Template *t)
+{
+ p->unload(t);
+}
+
+void TemplateEngine::enterBlock(const QCString &fileName,const QCString &blockName,int line)
+{
+ p->enterBlock(fileName,blockName,line);
+}
+
+void TemplateEngine::leaveBlock()
+{
+ p->leaveBlock();
+}
+
+void TemplateEngine::printIncludeContext(const char *fileName,int line) const
+{
+ p->printIncludeContext(fileName,line);
+}
+
diff --git a/src/template.h b/src/template.h
new file mode 100644
index 0000000..ef9792c
--- /dev/null
+++ b/src/template.h
@@ -0,0 +1,539 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TEMPLATE_H
+#define TEMPLATE_H
+
+#include <qcstring.h>
+#include <qvaluelist.h>
+
+class FTextStream;
+
+class TemplateListIntf;
+class TemplateStructIntf;
+class TemplateEngine;
+
+/** @defgroup template_api Template API
+ *
+ * This is the API for a
+ * <a href="https://docs.djangoproject.com/en/1.6/topics/templates/">Django</a>
+ * compatible template system written in C++.
+ * It is somewhat inspired by Stephen Kelly's
+ * <a href="http://www.gitorious.org/grantlee/pages/Home">Grantlee</a>.
+ *
+ * A template is simply a text file.
+ * A template contains \b variables, which get replaced with values when the
+ * template is evaluated, and \b tags, which control the logic of the template.
+ *
+ * Variables look like this: `{{ variable }}`
+ * When the template engine encounters a variable, it evaluates that variable and
+ * replaces it with the result. Variable names consist of any combination of
+ * alphanumeric characters and the underscore ("_").
+ * Use a dot (.) to access attributes of a structured variable.
+ *
+ * One can modify variables for display by using \b filters, for example:
+ * `{{ value|default:"nothing" }}`
+ *
+ * Tags look like this: `{% tag %}`. Tags are more complex than variables:
+ * Some create text in the output, some control flow by performing loops or logic,
+ * and some load external information into the template to be used by later variables.
+ *
+ * To comment-out part of a line in a template, use the comment syntax:
+ * `{# comment text #}`.
+ *
+ * Supported Django tags:
+ * - `for ... empty ... endfor`
+ * - `if ... else ... endif`
+ * - `block ... endblock`
+ * - `extend`
+ * - `include`
+ * - `with ... endwith`
+ * - `spaceless ... endspaceless`
+ * - `cycle`
+ *
+ * Extension tags:
+ * - `create` which instantiates a template and writes the result to a file.
+ * The syntax is `{% create 'filename' from 'template' %}`.
+ * - `recursetree`
+ * - `markers`
+ * - `msg` ... `endmsg`
+ * - `set`
+ *
+ * Supported Django filters:
+ * - `default`
+ * - `length`
+ * - `add`
+ * - `divisibleby`
+ *
+ * Extension filters:
+ * - `stripPath`
+ * - `nowrap`
+ * - `prepend`
+ * - `append`
+ *
+ * @{
+ */
+
+/** @brief Variant type which can hold one value of a fixed set of types. */
+class TemplateVariant
+{
+ public:
+ /** @brief Helper class to create a delegate that can store a function/method call. */
+ class Delegate
+ {
+ public:
+ /** Callback type to use when creating a delegate from a function. */
+ typedef TemplateVariant (*StubType)(const void *obj, const QValueList<TemplateVariant> &args);
+
+ Delegate() : m_objectPtr(0) , m_stubPtr(0) {}
+
+ /** Creates a delegate given an object. The method to call is passed as a template parameter */
+ template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
+ static Delegate fromMethod(const T* objectPtr)
+ {
+ Delegate d;
+ d.m_objectPtr = objectPtr;
+ d.m_stubPtr = &methodStub<T, TMethod>;
+ return d;
+ }
+ /** Creates a delegate given an object, and a plain function. */
+ static Delegate fromFunction(const void *obj,StubType func)
+ {
+ Delegate d;
+ d.m_objectPtr = obj;
+ d.m_stubPtr = func;
+ return d;
+ }
+
+ /** Invokes the function/method stored in the delegate */
+ TemplateVariant operator()(const QValueList<TemplateVariant> &args) const
+ {
+ return (*m_stubPtr)(m_objectPtr, args);
+ }
+
+ private:
+ const void* m_objectPtr;
+ StubType m_stubPtr;
+
+ template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
+ static TemplateVariant methodStub(const void* objectPtr, const QValueList<TemplateVariant> &args)
+ {
+ T* p = (T*)(objectPtr);
+ return (p->*TMethod)(args);
+ }
+ };
+
+ /** Types of data that can be stored in a TemplateVariant */
+ enum Type { None, Bool, Integer, String, Struct, List, Function };
+
+ /** Returns the type of the value stored in the variant */
+ Type type() const;
+
+ /** Return a string representation of the type of the value stored in the variant */
+ QCString typeAsString() const;
+
+ /** Returns TRUE if the variant holds a valid value, or FALSE otherwise */
+ bool isValid() const;
+
+ /** Constructs an invalid variant. */
+ TemplateVariant();
+
+ /** Constructs a new variant with a boolean value \a b. */
+ explicit TemplateVariant(bool b);
+
+ /** Constructs a new variant with a integer value \a v. */
+ TemplateVariant(int v);
+
+ /** Constructs a new variant with a string value \a s. */
+ TemplateVariant(const char *s,bool raw=FALSE);
+
+ /** Constructs a new variant with a string value \a s. */
+ TemplateVariant(const QCString &s,bool raw=FALSE);
+
+ /** Constructs a new variant with a struct value \a s.
+ * @note. The variant will hold a reference to the object.
+ */
+ TemplateVariant(TemplateStructIntf *s);
+
+ /** Constructs a new variant with a list value \a l.
+ * @note. The variant will hold a reference to the object.
+ */
+ TemplateVariant(TemplateListIntf *l);
+
+ /** Constructs a new variant which represents a method call
+ * @param[in] delegate Delegate object to invoke when
+ * calling call() on this variant.
+ * @note Use TemplateVariant::Delegate::fromMethod() and
+ * TemplateVariant::Delegate::fromFunction() to create
+ * Delegate objects.
+ */
+ TemplateVariant(const Delegate &delegate);
+
+ /** Destroys the Variant object */
+ ~TemplateVariant();
+
+ /** Constructs a copy of the variant, \a v,
+ * passed as the argument to this constructor.
+ */
+ TemplateVariant(const TemplateVariant &v);
+
+ /** Assigns the value of the variant \a v to this variant. */
+ TemplateVariant &operator=(const TemplateVariant &v);
+
+ /** Compares this QVariant with v and returns true if they are equal;
+ * otherwise returns false.
+ */
+ bool operator==(TemplateVariant &other);
+
+ /** Returns the variant as a string. */
+ QCString toString() const;
+
+ /** Returns the variant as a boolean. */
+ bool toBool() const;
+
+ /** Returns the variant as an integer. */
+ int toInt() const;
+
+ /** Returns the pointer to list referenced by this variant
+ * or 0 if this variant does not have list type.
+ */
+ TemplateListIntf *toList() const;
+
+ /** Returns the pointer to struct referenced by this variant
+ * or 0 if this variant does not have struct type.
+ */
+ TemplateStructIntf *toStruct() const;
+
+ /** Return the result of apply this function with \a args.
+ * Returns an empty string if the variant type is not a function.
+ */
+ TemplateVariant call(const QValueList<TemplateVariant> &args);
+
+ /** Sets whether or not the value of the Variant should be
+ * escaped or written as-is (raw).
+ * @param[in] b TRUE means write as-is, FALSE means apply escaping.
+ */
+ void setRaw(bool b);
+
+ /** Returns whether or not the value of the Value is raw.
+ * @see setRaw()
+ */
+ bool raw() const;
+
+ private:
+ class Private;
+ Private *p;
+};
+
+//------------------------------------------------------------------------
+
+template<class T> class TemplateAutoRef
+{
+ public:
+ TemplateAutoRef(T *obj) : m_obj(obj)
+ {
+ m_obj->addRef();
+ }
+ ~TemplateAutoRef()
+ {
+ m_obj->release();
+ }
+ T &operator*() const { return *m_obj; }
+ T *operator->() const { return m_obj; }
+ T *get() const { return m_obj; }
+
+ private:
+ T *m_obj;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Abstract read-only interface for a context value of type list.
+ * @note The values of the list are TemplateVariants.
+ */
+class TemplateListIntf
+{
+ public:
+ /** @brief Abstract interface for a iterator of a list. */
+ class ConstIterator
+ {
+ public:
+ /** Destructor for the iterator */
+ virtual ~ConstIterator() {}
+ /** Moves iterator to the first element in the list */
+ virtual void toFirst() = 0;
+ /** Moves iterator to the last element in the list */
+ virtual void toLast() = 0;
+ /** Moves iterator to the next element in the list */
+ virtual void toNext() = 0;
+ /** Moves iterator to the previous element in the list */
+ virtual void toPrev() = 0;
+ /* Returns TRUE if the iterator points to a valid element
+ * in the list, or FALSE otherwise.
+ * If TRUE is returned, the value pointed to be the
+ * iterator is assigned to \a v.
+ */
+ virtual bool current(TemplateVariant &v) const = 0;
+ };
+
+ /** Destroys the list */
+ virtual ~TemplateListIntf() {}
+
+ /** Returns the number of elements in the list */
+ virtual int count() const = 0;
+
+ /** Returns the element at index position \a index. */
+ virtual TemplateVariant at(int index) const = 0;
+
+ /** Creates a new iterator for this list.
+ * @note the user should call delete on the returned pointer.
+ */
+ virtual TemplateListIntf::ConstIterator *createIterator() const = 0;
+
+ /** Increase object's reference count */
+ virtual int addRef() = 0;
+
+ /** Decreases object's referenc count, destroy object if 0 */
+ virtual int release() = 0;
+};
+
+/** @brief Default implementation of a context value of type list. */
+class TemplateList : public TemplateListIntf
+{
+ public:
+ // TemplateListIntf methods
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+ virtual int addRef();
+ virtual int release();
+
+ /** Creates an instance with ref count set to 0 */
+ static TemplateList *alloc();
+
+ /** Appends element \a v to the end of the list */
+ virtual void append(const TemplateVariant &v);
+
+ private:
+ /** Creates a list */
+ TemplateList();
+ /** Destroys the list */
+ ~TemplateList();
+
+ friend class TemplateListConstIterator;
+ class Private;
+ Private *p;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Abstract interface for a context value of type struct. */
+class TemplateStructIntf
+{
+ public:
+ /** Destroys the struct */
+ virtual ~TemplateStructIntf() {}
+
+ /** Gets the value for a field name.
+ * @param[in] name The name of the field.
+ */
+ virtual TemplateVariant get(const char *name) const = 0;
+
+ /** Increase object's reference count */
+ virtual int addRef() = 0;
+
+ /** Decreases object's referenc count, destroy object if 0 */
+ virtual int release() = 0;
+};
+
+
+/** @brief Default implementation of a context value of type struct. */
+class TemplateStruct : public TemplateStructIntf
+{
+ public:
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+ virtual int addRef();
+ virtual int release();
+
+ /** Creates an instance with ref count set to 0. */
+ static TemplateStruct *alloc();
+
+ /** Sets the value the field of a struct
+ * @param[in] name The name of the field.
+ * @param[in] v The value to set.
+ */
+ virtual void set(const char *name,const TemplateVariant &v);
+
+
+ private:
+ /** Creates a struct */
+ TemplateStruct();
+ /** Destroys the struct */
+ virtual ~TemplateStruct();
+
+ class Private;
+ Private *p;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Interface used to escape characters in a string */
+class TemplateEscapeIntf
+{
+ public:
+ /** Returns the \a input after escaping certain characters */
+ virtual QCString escape(const QCString &input) = 0;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Interface used to remove redundant spaces inside a spaceless block */
+class TemplateSpacelessIntf
+{
+ public:
+ /** Returns the \a input after removing redundant whitespace */
+ virtual QCString remove(const QCString &input) = 0;
+ /** Reset filter state */
+ virtual void reset() = 0;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Abstract interface for a template context.
+ *
+ * A Context consists of a stack of dictionaries.
+ * A dictionary consists of a mapping of string keys onto TemplateVariant values.
+ * A key is searched starting with the dictionary at the top of the stack
+ * and searching downwards until it is found. The stack is used to create
+ * local scopes.
+ * @note This object must be created by TemplateEngine::createContext()
+ */
+class TemplateContext
+{
+ public:
+ virtual ~TemplateContext() {}
+
+ /** Push a new scope on the stack. */
+ virtual void push() = 0;
+
+ /** Pop the current scope from the stack. */
+ virtual void pop() = 0;
+
+ /** Sets a value in the current scope.
+ * @param[in] name The name of the value; the key in the dictionary.
+ * @param[in] v The value associated with the key.
+ * @note When a given key is already present,
+ * its value will be replaced by \a v
+ */
+ virtual void set(const char *name,const TemplateVariant &v) = 0;
+
+ /** Gets the value for a given key
+ * @param[in] name The name of key.
+ * @returns The value, which can be an invalid variant in case the
+ * key was not found.
+ */
+ virtual TemplateVariant get(const QCString &name) const = 0;
+
+ /** Returns a pointer to the value corresponding to a given key.
+ * @param[in] name The name of key.
+ * @returns A pointer to the value, or 0 in case the key was not found.
+ */
+ virtual const TemplateVariant *getRef(const QCString &name) const = 0;
+
+ /** When files are create (i.e. by {% create ... %}) they written
+ * to the directory \a dir.
+ */
+ virtual void setOutputDirectory(const QCString &dir) = 0;
+
+ /** Sets the interface that will be used for escaping the result
+ * of variable expansion before writing it to the output.
+ */
+ virtual void setEscapeIntf(const QCString &extension, TemplateEscapeIntf *intf) = 0;
+
+ /** Sets the interface that will be used inside a spaceless block
+ * to remove any redundant whitespace.
+ */
+ virtual void setSpacelessIntf(TemplateSpacelessIntf *intf) = 0;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Abstract interface for a template.
+ * @note Must be created and is deleted by the TemplateEngine
+ */
+class Template
+{
+ public:
+ /** Destructor */
+ virtual ~Template() {}
+
+ /** Renders a template instance to a stream.
+ * @param[in] ts The text stream to write the results to.
+ * @param[in] c The context containing data that can be used
+ * when instantiating the template.
+ */
+ virtual void render(FTextStream &ts,TemplateContext *c) = 0;
+};
+
+//------------------------------------------------------------------------
+
+/** @brief Engine to create templates and template contexts. */
+class TemplateEngine
+{
+ public:
+ /** Create a template engine. */
+ TemplateEngine();
+
+ /** Destroys the template engine. */
+ ~TemplateEngine();
+
+ /** Creates a new context that can be using to render a template.
+ * @see Template::render()
+ */
+ TemplateContext *createContext() const;
+
+ /** Destroys a context created via createContext().
+ * @param[in] ctx The context.
+ */
+ void destroyContext(TemplateContext *ctx);
+
+ /** Creates a new template whole contents are in a file.
+ * @param[in] fileName The name of the file containing the
+ * template data
+ * @param[in] fromLine The line number of the statement that triggered the load
+ * @return the new template, the caller will be the owner.
+ */
+ Template *loadByName(const QCString &fileName,int fromLine);
+
+ /** Indicates that template \a t is no longer needed. The engine
+ * may decide to delete it.
+ */
+ void unload(Template *t);
+
+ void printIncludeContext(const char *fileName,int line) const;
+
+ private:
+ friend class TemplateNodeBlock;
+ void enterBlock(const QCString &fileName,const QCString &blockName,int line);
+ void leaveBlock();
+
+ class Private;
+ Private *p;
+};
+
+/** @} */
+
+#endif
diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp
new file mode 100644
index 0000000..6f3151f
--- /dev/null
+++ b/src/textdocvisitor.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qdir.h>
+#include "textdocvisitor.h"
+#include "message.h"
+#include "util.h"
+#include "htmlentity.h"
+
+//-------------------------------------------------------------------------
+
+void TextDocVisitor::visit(DocSymbol *s)
+{
+ const char *res = HtmlEntityMapper::instance()->html(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ err("text: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+}
+
+
+void TextDocVisitor::filter(const char *str)
+{
+ if (str==0) return;
+ //printf("TextDocVisitor::filter(%s)\n",str);
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '\n': m_t << " "; break;
+ case '"': m_t << """; break;
+ case '\'': m_t << "'"; break;
+ case '<': m_t << "<"; break;
+ case '>': m_t << ">"; break;
+ case '&': m_t << "&"; break;
+ default: m_t << c;
+ }
+ }
+}
+
diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h
new file mode 100644
index 0000000..b17065d
--- /dev/null
+++ b/src/textdocvisitor.h
@@ -0,0 +1,145 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _TEXTDOCVISITOR_H
+#define _TEXTDOCVISITOR_H
+
+#include "docvisitor.h"
+#include "docparser.h"
+#include <qstack.h>
+#include <qcstring.h>
+#include "ftextstream.h"
+
+
+/*! @brief Concrete visitor implementation for TEXT output. */
+class TextDocVisitor : public DocVisitor
+{
+ public:
+ TextDocVisitor(FTextStream &t) : DocVisitor(DocVisitor_Text), m_t(t) {}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *w) { filter(w->word()); }
+ void visit(DocLinkedWord *w) { filter(w->word()); }
+ void visit(DocWhiteSpace *) { m_t << " "; }
+ void visit(DocSymbol *);
+ void visit(DocURL *u) { filter(u->url()); }
+ void visit(DocLineBreak *) { m_t << " "; }
+ void visit(DocHorRuler *) {}
+ void visit(DocStyleChange *) {}
+ void visit(DocVerbatim *s) { filter(s->text()); }
+ void visit(DocAnchor *) {}
+ void visit(DocInclude *) {}
+ void visit(DocIncOperator *) {}
+ void visit(DocFormula *) {}
+ void visit(DocIndexEntry *) {}
+ void visit(DocSimpleSectSep *){}
+ void visit(DocCite *) {}
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *) {}
+ void visitPost(DocAutoList *) {}
+ void visitPre(DocAutoListItem *) {}
+ void visitPost(DocAutoListItem *) {}
+ void visitPre(DocPara *) {}
+ void visitPost(DocPara *) {}
+ void visitPre(DocRoot *) {}
+ void visitPost(DocRoot *) {}
+ void visitPre(DocSimpleSect *) {}
+ void visitPost(DocSimpleSect *) {}
+ void visitPre(DocTitle *) {}
+ void visitPost(DocTitle *) {}
+ void visitPre(DocSimpleList *) {}
+ void visitPost(DocSimpleList *) {}
+ void visitPre(DocSimpleListItem *) {}
+ void visitPost(DocSimpleListItem *) {}
+ void visitPre(DocSection *) {}
+ void visitPost(DocSection *) {}
+ void visitPre(DocHtmlList *) {}
+ void visitPost(DocHtmlList *) {}
+ void visitPre(DocHtmlListItem *) {}
+ void visitPost(DocHtmlListItem *) {}
+ void visitPre(DocHtmlDescList *) {}
+ void visitPost(DocHtmlDescList *) {}
+ void visitPre(DocHtmlDescTitle *) {}
+ void visitPost(DocHtmlDescTitle *) {}
+ void visitPre(DocHtmlDescData *) {}
+ void visitPost(DocHtmlDescData *) {}
+ void visitPre(DocHtmlTable *) {}
+ void visitPost(DocHtmlTable *) {}
+ void visitPre(DocHtmlRow *) {}
+ void visitPost(DocHtmlRow *) {}
+ void visitPre(DocHtmlCell *) {}
+ void visitPost(DocHtmlCell *) {}
+ void visitPre(DocHtmlCaption *) {}
+ void visitPost(DocHtmlCaption *) {}
+ void visitPre(DocInternal *) {}
+ void visitPost(DocInternal *) {}
+ void visitPre(DocHRef *) {}
+ void visitPost(DocHRef *) {}
+ void visitPre(DocHtmlHeader *) {}
+ void visitPost(DocHtmlHeader *) {}
+ void visitPre(DocImage *) {}
+ void visitPost(DocImage *) {}
+ void visitPre(DocDotFile *) {}
+ void visitPost(DocDotFile *) {}
+
+ void visitPre(DocMscFile *) {}
+ void visitPost(DocMscFile *) {}
+ void visitPre(DocDiaFile *) {}
+ void visitPost(DocDiaFile *) {}
+ void visitPre(DocLink *) {}
+ void visitPost(DocLink *) {}
+ void visitPre(DocRef *) {}
+ void visitPost(DocRef *) {}
+ void visitPre(DocSecRefItem *) {}
+ void visitPost(DocSecRefItem *) {}
+ void visitPre(DocSecRefList *) {}
+ void visitPost(DocSecRefList *) {}
+ void visitPre(DocParamSect *) {}
+ void visitPost(DocParamSect *) {}
+ void visitPre(DocParamList *) {}
+ void visitPost(DocParamList *) {}
+ void visitPre(DocXRefItem *) {}
+ void visitPost(DocXRefItem *) {}
+ void visitPre(DocInternalRef *) {}
+ void visitPost(DocInternalRef *) {}
+ void visitPre(DocCopy *) {}
+ void visitPost(DocCopy *) {}
+ void visitPre(DocText *) {}
+ void visitPost(DocText *) {}
+ void visitPre(DocHtmlBlockQuote *) {}
+ void visitPost(DocHtmlBlockQuote *) {}
+ void visitPre(DocVhdlFlow *) {}
+ void visitPost(DocVhdlFlow *) {}
+ void visitPre(DocParBlock *) {}
+ void visitPost(DocParBlock *) {}
+
+ private:
+
+ void filter(const char *str);
+
+ FTextStream &m_t;
+};
+
+#endif
diff --git a/src/to_c_cmd.py b/src/to_c_cmd.py
new file mode 100755
index 0000000..52785f1
--- /dev/null
+++ b/src/to_c_cmd.py
@@ -0,0 +1,8 @@
+# place " at begin of each line
+# escape existing '\' and '"'
+# remove \n at the end of the line (sometimes the last line does not have a \n
+# so we cannot do a replacement with some other text)
+# place an escaped \n and " at the end of each line
+import sys
+for line in sys.stdin:
+ sys.stdout.write('"' + line.replace('\\','\\\\').replace('"','\\"').replace('\n','') + '\\n"\n')
diff --git a/src/tooltip.cpp b/src/tooltip.cpp
new file mode 100644
index 0000000..8085bff
--- /dev/null
+++ b/src/tooltip.cpp
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qdict.h>
+
+#include "tooltip.h"
+#include "definition.h"
+#include "outputgen.h"
+#include "util.h"
+#include "filedef.h"
+#include "doxygen.h"
+#include "config.h"
+
+class TooltipManager::Private
+{
+ public:
+ Private() : tooltipInfo(10007) {}
+ QDict<Definition> tooltipInfo;
+};
+
+TooltipManager *TooltipManager::s_theInstance = 0;
+
+TooltipManager::TooltipManager()
+{
+ p = new Private;
+}
+
+TooltipManager::~TooltipManager()
+{
+ delete p;
+}
+
+TooltipManager *TooltipManager::instance()
+{
+ if (!s_theInstance)
+ {
+ s_theInstance = new TooltipManager;
+ }
+ return s_theInstance;
+}
+
+void TooltipManager::clearTooltips()
+{
+ p->tooltipInfo.clear();
+}
+
+static QCString escapeId(const char *s)
+{
+ QCString res=s;
+ char *p=res.data();
+ while (*p)
+ {
+ if (!isId(*p)) *p='_';
+ p++;
+ }
+ return res;
+}
+
+void TooltipManager::addTooltip(Definition *d)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ if (!sourceTooltips) return;
+ QCString id = d->getOutputFileBase();
+ int i=id.findRev('/');
+ if (i!=-1)
+ {
+ id = id.right(id.length()-i-1); // strip path (for CREATE_SUBDIRS=YES)
+ }
+ id+=escapeId(Doxygen::htmlFileExtension);
+ QCString anc = d->anchor();
+ if (!anc.isEmpty())
+ {
+ id+="_"+anc;
+ }
+ if (p->tooltipInfo.find(id)==0)
+ {
+ p->tooltipInfo.insert(id,d);
+ }
+}
+
+void TooltipManager::writeTooltips(CodeOutputInterface &ol)
+{
+ QDictIterator<Definition> di(p->tooltipInfo);
+ Definition *d;
+ for (di.toFirst();(d=di.current());++di)
+ {
+ DocLinkInfo docInfo;
+ docInfo.name = d->qualifiedName();
+ docInfo.ref = d->getReference();
+ docInfo.url = d->getOutputFileBase();
+ docInfo.anchor = d->anchor();
+ SourceLinkInfo defInfo;
+ if (d->getBodyDef() && d->getStartBodyLine()!=-1)
+ {
+ defInfo.file = d->getBodyDef()->name();
+ defInfo.line = d->getStartBodyLine();
+ defInfo.url = d->getSourceFileBase();
+ defInfo.anchor = d->getSourceAnchor();
+ }
+ SourceLinkInfo declInfo; // TODO: fill in...
+ QCString decl;
+ if (d->definitionType()==Definition::TypeMember)
+ {
+ MemberDef *md = (MemberDef*)d;
+ decl = md->declaration();
+ if (!decl.isEmpty() && decl.at(0)=='@') // hide enum values
+ {
+ decl.resize(0);
+ }
+ }
+ ol.writeTooltip(di.currentKey(), // id
+ docInfo, // symName
+ decl, // decl
+ d->briefDescriptionAsTooltip(), // desc
+ defInfo,
+ declInfo
+ );
+ }
+}
+
diff --git a/src/tooltip.h b/src/tooltip.h
new file mode 100644
index 0000000..ea8948d
--- /dev/null
+++ b/src/tooltip.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+#ifndef TOOLTIP_H
+#define TOOLTIP_H
+
+class Definition;
+class CodeOutputInterface;
+
+class TooltipManager
+{
+ public:
+ static TooltipManager *instance();
+ void clearTooltips();
+ void addTooltip(Definition *d);
+ void writeTooltips(CodeOutputInterface &ol);
+
+ private:
+ class Private;
+ Private *p;
+ TooltipManager();
+ ~TooltipManager();
+ static TooltipManager *s_theInstance;
+};
+
+#endif
diff --git a/src/translator.h b/src/translator.h
new file mode 100644
index 0000000..32eaf09
--- /dev/null
+++ b/src/translator.h
@@ -0,0 +1,575 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_H
+#define TRANSLATOR_H
+
+#include "classdef.h"
+
+/** Abstract base class for all translatable text fragments. */
+class Translator
+{
+ public:
+
+ /*! This method is used to provide warning message that is displayed
+ * if the user chooses a language whose translation is not up to date.
+ * It is implemented by the adapter classes.
+ */
+ virtual QCString updateNeededMessage() { return ""; }
+ virtual ~Translator() {}
+
+ // Please, have a look at comments inside the translator_en.h file
+ // to learn the meaning of the following methods. The translator_en.h
+ // file contains the TranslatorEnglish implementation, which is
+ // always up-to-date (by definition).
+
+ // --- Language control methods -------------------
+
+ virtual QCString idLanguage() = 0;
+ virtual QCString latexLanguageSupportCommand() = 0;
+
+ // --- Language translation methods -------------------
+
+ virtual QCString trRelatedFunctions() = 0;
+ virtual QCString trRelatedSubscript() = 0;
+ virtual QCString trDetailedDescription() = 0;
+ virtual QCString trMemberTypedefDocumentation() = 0;
+ virtual QCString trMemberEnumerationDocumentation() = 0;
+ virtual QCString trMemberFunctionDocumentation() = 0;
+ virtual QCString trMemberDataDocumentation() = 0;
+ virtual QCString trMore() = 0;
+ virtual QCString trListOfAllMembers() = 0;
+ virtual QCString trMemberList() = 0;
+ virtual QCString trThisIsTheListOfAllMembers() = 0;
+ virtual QCString trIncludingInheritedMembers() = 0;
+ virtual QCString trGeneratedAutomatically(const char *s) = 0;
+ virtual QCString trEnumName() = 0;
+ virtual QCString trEnumValue() = 0;
+ virtual QCString trDefinedIn() = 0;
+
+ // quick reference sections
+
+ virtual QCString trModules() = 0;
+ virtual QCString trClassHierarchy() = 0;
+ virtual QCString trCompoundList() = 0;
+ virtual QCString trFileList() = 0;
+ //virtual QCString trHeaderFiles() = 0;
+ virtual QCString trCompoundMembers() = 0;
+ virtual QCString trFileMembers() = 0;
+ virtual QCString trRelatedPages() = 0;
+ virtual QCString trExamples() = 0;
+ virtual QCString trSearch() = 0;
+ virtual QCString trClassHierarchyDescription() = 0;
+ virtual QCString trFileListDescription(bool extractAll) = 0;
+ virtual QCString trCompoundListDescription() = 0;
+ virtual QCString trCompoundMembersDescription(bool extractAll) = 0;
+ virtual QCString trFileMembersDescription(bool extractAll) = 0;
+ //virtual QCString trHeaderFilesDescription() = 0;
+ virtual QCString trExamplesDescription() = 0;
+ virtual QCString trRelatedPagesDescription() = 0;
+ virtual QCString trModulesDescription() = 0;
+ //virtual QCString trNoDescriptionAvailable() = 0;
+
+ // index titles (the project name is prepended for these)
+
+ virtual QCString trDocumentation() = 0;
+ virtual QCString trModuleIndex() = 0;
+ virtual QCString trHierarchicalIndex() = 0;
+ virtual QCString trCompoundIndex() = 0;
+ virtual QCString trFileIndex() = 0;
+ virtual QCString trModuleDocumentation() = 0;
+ virtual QCString trClassDocumentation() = 0;
+ virtual QCString trFileDocumentation() = 0;
+ virtual QCString trExampleDocumentation() = 0;
+ virtual QCString trPageDocumentation() = 0;
+ virtual QCString trReferenceManual() = 0;
+ virtual QCString trDefines() = 0;
+ //virtual QCString trFuncProtos() = 0;
+ virtual QCString trTypedefs() = 0;
+ virtual QCString trEnumerations() = 0;
+ virtual QCString trFunctions() = 0;
+ virtual QCString trVariables() = 0;
+ virtual QCString trEnumerationValues() = 0;
+ virtual QCString trDefineDocumentation() = 0;
+ //virtual QCString trFunctionPrototypeDocumentation() = 0;
+ virtual QCString trTypedefDocumentation() = 0;
+ virtual QCString trEnumerationTypeDocumentation() = 0;
+ virtual QCString trFunctionDocumentation() = 0;
+ virtual QCString trVariableDocumentation() = 0;
+ virtual QCString trCompounds() = 0;
+ virtual QCString trGeneratedAt(const char *date,const char *projName) = 0;
+ //virtual QCString trWrittenBy() = 0;
+ virtual QCString trClassDiagram(const char *clName) = 0;
+ virtual QCString trForInternalUseOnly() = 0;
+ //virtual QCString trReimplementedForInternalReasons() = 0;
+ virtual QCString trWarning() = 0;
+ //virtual QCString trBugsAndLimitations() = 0;
+ virtual QCString trVersion() = 0;
+ virtual QCString trDate() = 0;
+ virtual QCString trReturns() = 0;
+ virtual QCString trSeeAlso() = 0;
+ virtual QCString trParameters() = 0;
+ virtual QCString trExceptions() = 0;
+ virtual QCString trGeneratedBy() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNamespaceList() = 0;
+ virtual QCString trNamespaceListDescription(bool extractAll) = 0;
+ virtual QCString trFriends() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trRelatedFunctionDocumentation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate) = 0;
+
+ virtual QCString trFileReference(const char *fileName) = 0;
+ virtual QCString trNamespaceReference(const char *namespaceName) = 0;
+
+ virtual QCString trPublicMembers() = 0;
+ virtual QCString trPublicSlots() = 0;
+ virtual QCString trSignals() = 0;
+ virtual QCString trStaticPublicMembers() = 0;
+ virtual QCString trProtectedMembers() = 0;
+ virtual QCString trProtectedSlots() = 0;
+ virtual QCString trStaticProtectedMembers() = 0;
+ virtual QCString trPrivateMembers() = 0;
+ virtual QCString trPrivateSlots() = 0;
+ virtual QCString trStaticPrivateMembers() = 0;
+ virtual QCString trWriteList(int numEntries) = 0;
+ virtual QCString trInheritsList(int numEntries) = 0;
+ virtual QCString trInheritedByList(int numEntries) = 0;
+ virtual QCString trReimplementedFromList(int numEntries) = 0;
+ virtual QCString trReimplementedInList(int numEntries) = 0;
+ virtual QCString trNamespaceMembers() = 0;
+ virtual QCString trNamespaceMemberDescription(bool extractAll) = 0;
+ virtual QCString trNamespaceIndex() = 0;
+ virtual QCString trNamespaceDocumentation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNamespaces() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single) = 0;
+ //virtual QCString trAlphabeticalList() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReturnValues() = 0;
+ virtual QCString trMainPage() = 0;
+ virtual QCString trPageAbbreviation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ //virtual QCString trSources() = 0;
+ virtual QCString trDefinedAtLineInSourceFile() = 0;
+ virtual QCString trDefinedInSourceFile() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCollaborationDiagram(const char *clName) = 0;
+ virtual QCString trInclDepGraph(const char *fName) = 0;
+ virtual QCString trConstructorDocumentation() = 0;
+ virtual QCString trGotoSourceCode() = 0;
+ virtual QCString trGotoDocumentation() = 0;
+ virtual QCString trPrecondition() = 0;
+ virtual QCString trPostcondition() = 0;
+ virtual QCString trInvariant() = 0;
+ virtual QCString trInitialValue() = 0;
+ virtual QCString trCode() = 0;
+
+ virtual QCString trGraphicalHierarchy() = 0;
+ virtual QCString trGotoGraphicalHierarchy() = 0;
+ virtual QCString trGotoTextualHierarchy() = 0;
+ virtual QCString trPageIndex() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote() = 0;
+ virtual QCString trPublicTypes() = 0;
+ virtual QCString trPublicAttribs() = 0;
+ virtual QCString trStaticPublicAttribs() = 0;
+ virtual QCString trProtectedTypes() = 0;
+ virtual QCString trProtectedAttribs() = 0;
+ virtual QCString trStaticProtectedAttribs() = 0;
+ virtual QCString trPrivateTypes() = 0;
+ virtual QCString trPrivateAttribs() = 0;
+ virtual QCString trStaticPrivateAttribs() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trTodo() = 0;
+ virtual QCString trTodoList() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy() = 0;
+ virtual QCString trRemarks() = 0;
+ virtual QCString trAttention() = 0;
+ virtual QCString trInclByDepGraph() = 0;
+ virtual QCString trSince() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trLegendTitle() = 0;
+ virtual QCString trLegendDocs() = 0;
+ virtual QCString trLegend() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trTest() = 0;
+ virtual QCString trTestList() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.1
+//////////////////////////////////////////////////////////////////////////
+
+ //virtual QCString trDCOPMethods() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trProperties() = 0;
+ virtual QCString trPropertyDocumentation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ //virtual QCString trInterfaces() = 0;
+ virtual QCString trClasses() = 0;
+ virtual QCString trPackage(const char *name) = 0;
+ virtual QCString trPackageList() = 0;
+ virtual QCString trPackageListDescription() = 0;
+ virtual QCString trPackages() = 0;
+ //virtual QCString trPackageDocumentation() = 0;
+ virtual QCString trDefineValue() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trBug() = 0;
+ virtual QCString trBugList() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp() = 0;
+
+ /*! Character sets
+ * <pre>
+ * 0 — ANSI
+ * 1 — Default
+ * 2 — Symbol
+ * 3 — Invalid
+ * 77 — Mac
+ * 128 — Shift Jis
+ * 129 — Hangul
+ * 130 — Johab
+ * 134 — GB2312
+ * 136 — Big5
+ * 161 — Greek
+ * 162 — Turkish
+ * 163 — Vietnamese
+ * 177 — Hebrew
+ * 178 — Arabic
+ * 179 — Arabic Traditional
+ * 180 — Arabic user
+ * 181 — Hebrew user
+ * 186 — Baltic
+ * 204 — Russian
+ * 222 — Thai
+ * 238 — Eastern European
+ * 254 — PC 437
+ * 255 — OEM
+ * </pre>
+ */
+ virtual QCString trRTFCharSet() = 0;
+ virtual QCString trRTFGeneralIndex() = 0;
+
+ // Translation of the word
+
+ virtual QCString trClass(bool first_capital, bool singular) = 0;
+ virtual QCString trFile(bool first_capital, bool singular) = 0;
+ virtual QCString trNamespace(bool first_capital, bool singular) = 0;
+ virtual QCString trGroup(bool first_capital, bool singular) = 0;
+ virtual QCString trPage(bool first_capital, bool singular) = 0;
+ virtual QCString trMember(bool first_capital, bool singular) = 0;
+ //virtual QCString trField(bool first_capital, bool singular) = 0;
+ virtual QCString trGlobal(bool first_capital, bool singular) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trAuthor(bool first_capital, bool singular) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferences() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trImplementedFromList(int numEntries) = 0;
+ virtual QCString trImplementedInList(int numEntries) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trRTFTableOfContents() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecatedList() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trEvents() = 0;
+ virtual QCString trEventDocumentation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trPackageTypes() = 0;
+ virtual QCString trPackageMembers() = 0;
+ virtual QCString trStaticPackageMembers() = 0;
+ virtual QCString trPackageAttribs() = 0;
+ virtual QCString trStaticPackageAttribs() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trAll() = 0;
+ virtual QCString trCallGraph() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ //virtual QCString trSearchForIndex() = 0;
+ virtual QCString trSearchResultsTitle() = 0;
+ virtual QCString trSearchResults(int numDocuments) = 0;
+ virtual QCString trSearchMatches() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trSourceFile(QCString& filename) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDirIndex() = 0;
+ virtual QCString trDirDocumentation() = 0;
+ virtual QCString trDirectories() = 0;
+ virtual QCString trDirDescription() = 0;
+ virtual QCString trDirReference(const char *dirName) = 0;
+ virtual QCString trDir(bool first_capital, bool singular) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trOverloadText() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCallerGraph() = 0;
+ virtual QCString trEnumerationValueDocumentation() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trMemberFunctionDocumentationFortran() = 0;
+ virtual QCString trCompoundListFortran() = 0;
+ virtual QCString trCompoundMembersFortran() = 0;
+ virtual QCString trCompoundListDescriptionFortran() = 0;
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll) = 0;
+ virtual QCString trCompoundIndexFortran() = 0;
+ virtual QCString trTypeDocumentation() = 0;
+ virtual QCString trSubprograms() = 0;
+ virtual QCString trSubprogramDocumentation() = 0;
+ virtual QCString trDataTypes() = 0;
+ virtual QCString trModulesList() = 0;
+ virtual QCString trModulesListDescription(bool extractAll) = 0;
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate) = 0;
+ virtual QCString trModuleReference(const char *namespaceName) = 0;
+ virtual QCString trModulesMembers() = 0;
+ virtual QCString trModulesMemberDescription(bool extractAll) = 0;
+ virtual QCString trModulesIndex() = 0;
+ virtual QCString trModule(bool first_capital, bool singular) = 0;
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single) = 0;
+ virtual QCString trType(bool first_capital, bool singular) = 0;
+ virtual QCString trSubprogram(bool first_capital, bool singular) = 0;
+ virtual QCString trTypeConstraints() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDirRelation(const char *name) = 0;
+ virtual QCString trLoading() = 0;
+ virtual QCString trGlobalNamespace() = 0;
+ virtual QCString trSearching() = 0;
+ virtual QCString trNoMatches() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3
+//////////////////////////////////////////////////////////////////////////
+
+ //virtual QCString trDirDependency(const char *name) = 0;
+ virtual QCString trFileIn(const char *name) = 0;
+ virtual QCString trIncludesFileIn(const char *name) = 0;
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCiteReferences() = 0;
+ virtual QCString trCopyright() = 0;
+ virtual QCString trDirDepGraph(const char *name) = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDetailLevel() = 0;
+ virtual QCString trTemplateParameters() = 0;
+ virtual QCString trAndMore(const QCString &number) = 0;
+ virtual QCString trEnumGeneratedFromFiles(bool single) = 0;
+ virtual QCString trEnumReference(const char *name) = 0;
+ virtual QCString trInheritedFrom(const char *members,const char *what) = 0;
+ virtual QCString trAdditionalInheritedMembers() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trPanelSynchronisationTooltip(bool enable) = 0;
+ virtual QCString trProvidedByCategory() = 0;
+ virtual QCString trExtendsClass() = 0;
+ virtual QCString trClassMethods() = 0;
+ virtual QCString trInstanceMethods() = 0;
+ virtual QCString trMethodDocumentation() = 0;
+ virtual QCString trDesignOverview() = 0;
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trInterfaces() = 0;
+ virtual QCString trServices() = 0;
+ virtual QCString trConstantGroups() = 0;
+ virtual QCString trConstantGroupReference(const char *namespaceName) = 0;
+ virtual QCString trServiceReference(const char *sName) = 0;
+ virtual QCString trSingletonReference(const char *sName) = 0;
+ virtual QCString trServiceGeneratedFromFiles(bool single) = 0;
+ virtual QCString trSingletonGeneratedFromFiles(bool single) = 0;
+};
+
+#endif
diff --git a/src/translator_adapter.h b/src/translator_adapter.h
new file mode 100644
index 0000000..254876a
--- /dev/null
+++ b/src/translator_adapter.h
@@ -0,0 +1,298 @@
+#ifndef TRANSLATOR_ADAPTER_H
+#define TRANSLATOR_ADAPTER_H
+
+#include "version.h"
+#include "translator.h"
+
+/** Base of the translator adapter tree.
+ *
+ * This abstract class provides access to the english
+ * translations, to be used as a substitute for not implemented
+ * local translations.
+ */
+class TranslatorAdapterBase : public Translator
+{
+ protected:
+ virtual ~TranslatorAdapterBase() {}
+ TranslatorEnglish english;
+
+ /*! An auxiliary inline method used by the updateNeededMessage()
+ * for building a warning message.
+ */
+ inline QCString createUpdateNeededMessage(const QCString & languageName,
+ const QCString & versionString)
+ {
+ return QCString("The selected output language \"")
+ + languageName
+ + "\" has not been updated\nsince "
+ + versionString
+ + ". As a result some sentences may appear in English.\n\n";
+ }
+
+ public:
+ /*! This method is used to generate a warning message to signal
+ * the user that the translation of his/her language of choice
+ * needs updating. It must be implemented by the translator
+ * adapter class (pure virtual).
+ *
+ * \sa createUpdateNeededMessage()
+ */
+ virtual QCString updateNeededMessage() = 0;
+
+};
+
+class TranslatorAdapter_1_8_4 : public TranslatorAdapterBase
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.8.4"); }
+
+ virtual QCString trInterfaces()
+ { return english.trInterfaces(); }
+
+ virtual QCString trServices()
+ { return english.trServices(); }
+
+ virtual QCString trConstantGroups()
+ { return english.trConstantGroups(); }
+
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ { return english.trConstantGroupReference(namespaceName); }
+
+ virtual QCString trServiceReference(const char *sName)
+ { return english.trServiceReference(sName); }
+
+ virtual QCString trSingletonReference(const char *sName)
+ { return english.trSingletonReference(sName); }
+
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ { return english.trServiceGeneratedFromFiles(single); }
+
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ { return english.trSingletonGeneratedFromFiles(single); }
+};
+
+class TranslatorAdapter_1_8_2 : public TranslatorAdapter_1_8_4
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.8.2"); }
+
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ { return english.trPanelSynchronisationTooltip(enable); }
+
+ virtual QCString trProvidedByCategory()
+ { return english.trProvidedByCategory(); }
+
+ virtual QCString trExtendsClass()
+ { return english.trExtendsClass(); }
+
+ virtual QCString trClassMethods()
+ { return english.trClassMethods(); }
+
+ virtual QCString trInstanceMethods()
+ { return english.trInstanceMethods(); }
+
+ virtual QCString trMethodDocumentation()
+ { return english.trMethodDocumentation(); }
+
+ virtual QCString trDesignOverview()
+ { return english.trDesignOverview(); }
+};
+
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.8.0.
+ */
+class TranslatorAdapter_1_8_0 : public TranslatorAdapter_1_8_2
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.8.0"); }
+
+ virtual QCString trDetailLevel()
+ { return english.trDetailLevel(); }
+
+ virtual QCString trTemplateParameters()
+ { return english.trTemplateParameters(); }
+
+ virtual QCString trAndMore(const QCString &number)
+ { return english.trAndMore(number); }
+
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { return english.trEnumGeneratedFromFiles(single); }
+
+ virtual QCString trEnumReference(const char *name)
+ { return english.trEnumReference(name); }
+
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return english.trInheritedFrom(members,what); }
+
+ virtual QCString trAdditionalInheritedMembers()
+ { return english.trAdditionalInheritedMembers(); }
+
+};
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.7.5.
+ */
+class TranslatorAdapter_1_7_5 : public TranslatorAdapter_1_8_0
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.7.5"); }
+
+ virtual QCString trCiteReferences()
+ { return english.trCiteReferences(); }
+
+ virtual QCString trCopyright()
+ { return english.trCopyright(); }
+
+ virtual QCString trDirDepGraph(const char *name)
+ { return english.trDirDepGraph(name); }
+};
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.6.3.
+ */
+class TranslatorAdapter_1_6_3 : public TranslatorAdapter_1_7_5
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.6.3"); }
+
+ virtual QCString trFileIn(const char *name)
+ { return english.trFileIn(name); }
+ virtual QCString trIncludesFileIn(const char *name)
+ { return english.trIncludesFileIn(name); }
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ { return english.trDateTime(year,month,day,dayOfWeek,hour,minutes,seconds,includeTime); }
+};
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.6.0.
+ */
+class TranslatorAdapter_1_6_0 : public TranslatorAdapter_1_6_3
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.6.0"); }
+
+ virtual QCString trDirRelation(const char *name)
+ { return english.trDirRelation(name); }
+
+ virtual QCString trLoading()
+ { return english.trLoading(); }
+
+ virtual QCString trGlobalNamespace()
+ { return english.trGlobalNamespace(); }
+
+ virtual QCString trSearching()
+ { return english.trSearching(); }
+
+ virtual QCString trNoMatches()
+ { return english.trNoMatches(); }
+};
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.5.4
+ */
+class TranslatorAdapter_1_5_4 : public TranslatorAdapter_1_6_0
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.5.4"); }
+
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return english.trMemberFunctionDocumentationFortran(); }
+
+ virtual QCString trCompoundListFortran()
+ { return english.trCompoundListFortran(); }
+
+ virtual QCString trCompoundMembersFortran()
+ { return english.trCompoundMembersFortran(); }
+
+ virtual QCString trCompoundListDescriptionFortran()
+ { return english.trCompoundListDescriptionFortran(); }
+
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ { return english.trCompoundMembersDescriptionFortran(extractAll); }
+
+ virtual QCString trCompoundIndexFortran()
+ { return english.trCompoundIndexFortran(); }
+
+ virtual QCString trTypeDocumentation()
+ { return english.trTypeDocumentation(); }
+
+ virtual QCString trSubprograms()
+ { return english.trSubprograms(); }
+
+ virtual QCString trSubprogramDocumentation()
+ { return english.trSubprogramDocumentation(); }
+
+ virtual QCString trDataTypes()
+ { return english.trDataTypes(); }
+
+ virtual QCString trModulesList()
+ { return english.trModulesList(); }
+
+ virtual QCString trModulesListDescription(bool extractAll)
+ { return english.trModulesListDescription(extractAll); }
+
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ { return english.trCompoundReferenceFortran(clName,compType,isTemplate); }
+
+ virtual QCString trModuleReference(const char *namespaceName)
+ { return english.trModuleReference(namespaceName); }
+
+ virtual QCString trModulesMembers()
+ { return english.trModulesMembers(); }
+
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ { return english.trModulesMemberDescription(extractAll); }
+
+ virtual QCString trModulesIndex()
+ { return english.trModulesIndex(); }
+
+ virtual QCString trModule(bool first_capital, bool singular)
+ { return english.trModule(first_capital,singular); }
+
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { return english.trGeneratedFromFilesFortran(compType,single); }
+
+ virtual QCString trType(bool first_capital, bool singular)
+ { return english.trType(first_capital,singular); }
+
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ { return english.trSubprogram(first_capital,singular); }
+
+ virtual QCString trTypeConstraints()
+ { return english.trTypeConstraints(); }
+};
+
+/** Adapter class for languages that only contain translations up to
+ * version 1.4.6
+ */
+class TranslatorAdapter_1_4_6 : public TranslatorAdapter_1_5_4
+{
+ public:
+ virtual QCString updateNeededMessage()
+ { return createUpdateNeededMessage(idLanguage(),"release 1.4.6"); }
+
+ virtual QCString trCallerGraph()
+ {
+ return english.trCallerGraph();
+ }
+ virtual QCString trEnumerationValueDocumentation()
+ {
+ return english.trEnumerationValueDocumentation();
+ }
+};
+
+#endif
+
diff --git a/src/translator_am.h b/src/translator_am.h
new file mode 100644
index 0000000..9eaba0e
--- /dev/null
+++ b/src/translator_am.h
@@ -0,0 +1,1804 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ */
+
+/*
+ * Translation by
+ * Armen Tangamyan <armen.tangamyan at anu.edu.au>
+ */
+
+#ifndef TRANSLATOR_AM_H
+#define TRANSLATOR_AM_H
+
+class TranslatorArmenian : public TranslatorAdapter_1_8_0
+{
+ public:
+ /*! Used for identification of the language. */
+ virtual QCString idLanguage()
+ { return "armenian"; }
+
+ /* Used to get the command(s) for the language support. */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "<pre>\\usepackage[latin]{armtex}\n"
+ "\\usepackage[armscii8]{inputenc}\n</pre>";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Դասին վերաբերվող ֆունկցիաներ"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Հաշվի առեք, որ սրանք անդամ ֆունկցիաներ չեն)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Մանրամասն նկարագրություն"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Անդամ տիպի սահմանումներ (typedef)"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Անդամ hամարակալումներ"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Անդամ ֆունկցիաներ"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Դաշտեր";
+ }
+ else
+ {
+ return "Անդամ տվյալներ";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Մանրամասն..."; }
+
+ /*! put in the class documentation */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trListOfAllMembers()
+ {
+ return "Բոլոր անդամների ցուցակը";
+ }
+
+ /*! used as the title of the "list of all members" page of a class */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trMemberList()
+ {
+ return "Անդամների ցուցակ";
+ }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Սա դասի անդամների ամբողջական ցուցակն է "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", ներառյալ բոլոր ժառանգված անդամները"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Ավտոմատ ստեղծված է ելքային կոդից, Doxygen-ի միջոցով, ";
+ if (s) result+=s+(QCString)" համար:";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "համարակալման անուն"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "համարակալման արժեք"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "սահմանված"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Մոդուլներ"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Դասերի հիերարխա"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածք";
+ }
+ else
+ {
+ return "Դասերի ցուցակ";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Ֆայլերի ցուցակ"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների դաշտեր";
+ }
+ else
+ {
+ return "Դասի անդամներ";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ /*??*/
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Գլոբալներ";
+ }
+ else
+ {
+ return "Ֆայլի անդամներ";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Նմանատիպ էջեր"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Օրինակներ"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Որոնում"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Այս ժառանգման ցուցակը կոպտորեն է տեսակավորված, "
+ "բայց ոչ ամբողջապես, այբբենական կարգով.";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if (!extractAll) result+="փաստագրված ";
+ result+="ֆայլերի մի ցուցակ` կարճ բացատրություններով:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածքը` կարճ բացատրություններով.";
+ }
+ else
+ {
+ return "Դասերը, կառուցվածքները, միավորումները "
+ "և ինտերֆեյսները` կարճ բացատրություններով.";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if(!extractAll) result+="փաստագրված ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="կառուցվածքների և միավորումների դաշտերի ";
+ else
+ result+="դասի անդամների ";
+ result+="ցուցակը`";
+ result+=" հղումներով դեպի ";
+ if(!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="կառուցվածք/միավորում փաստագրությունները բոլոր անդամների համար.";
+ else
+ result+="դասի փաստագրությունը բոլոր անդամների համար.";
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result += "կառուցվածքները/միավորումները, որոնց նրանք պատկանում են.";
+ else
+ result += "դասերը, որոնց նրանք պատկանում են.";
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if (!extractAll) result+="փաստագրված ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="ֆունկցիաների, փոփոխականների, մակրո-հայտարարությունների, "
+ "համարակալումների և տիպի սահմանումների (typedef)";
+ }
+ else
+ {
+ result+="ֆայլի անդամների ";
+ }
+ result+="ցուցակը`";
+ result+=" հղումներով դեպի ";
+ if (extractAll)
+ result+="ֆայլերը, որոնց նրանք պատկանում են.";
+ else
+ result+="փաստագրությունը.";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Բոլոր օրինակների ցուցակը."; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Բոլոր նմանատիպ փաստագրության էջերի ցուցակը."; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Բոլոր մոդուլների ցուցակը."; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return " - Փաստագրություն"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Մոդուլներ"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Դասակարգումներ"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածք";
+ }
+ else
+ {
+ return "Դասեր";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Ֆայլեր"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Մոդուլներ"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածքներ";
+ }
+ else
+ {
+ return "Դասեր";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Ֆայլեր"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Օրինակներ"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Էջեր"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Հղումների ձեռնարկ"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Մակրոսներ"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Տիպի սահմանումներ (typedef)"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Համարակալումներ"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Ֆունկցիաներ"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Փոփոխականներ"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Հաշվիչ"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Մակրոսներ"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Տիպի սահմանումներ (typedef)"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Համարակալման տիպեր"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Ֆունկցիաներ"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Փոփոխականներ"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածք";
+ }
+ else
+ {
+ return "Դասեր";
+ }
+ }
+
+ /*! This is used in the documentation of a group before the list of
+ * links to documented files
+ */
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Ստեղծվել է "+date;
+ if (projName) result+=projName+QCString(" -ի համար,");
+ result+=(QCString)" հետևյալ համակարգով.";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return clName+QCString(" -ի ժառանգման գծագիրը.");
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Միայն ներքին օգտագործման համար"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Զգուշացում"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Տարբերակ"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Տարեթիվ"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Վերադարձնում է"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Տեսեք նաև"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Պարամետրեր"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Բացառություններ"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Ստեղծված է հետևյալ համակարգի կողմից"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Անունների տարածությունների ցուցակ"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if (!extractAll) result+="փաստագրված ";
+ result+="անունների տարածությունների ցուցակը` կարճ բացատրություններով.";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Ընկերներ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Դասի ընկերներ և կապված ֆունկցիաներ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate)
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Դասի"; break;
+ case ClassDef::Struct: result+=" Կառուցվածքի"; break;
+ case ClassDef::Union: result+=" Միավորման"; break;
+ case ClassDef::Interface: result+=" Ինտերֆեյսի"; break;
+ case ClassDef::Protocol: result+=" Արձանագրության"; break;
+ case ClassDef::Category: result+=" Դասակարգման"; break;
+ case ClassDef::Exception: result+=" Բացառության"; break;
+ default: break;
+ }
+ result+=" Ձևանմուշներ";
+ }
+ else
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Դաս"; break;
+ case ClassDef::Struct: result+=" Կառուցվածք"; break;
+ case ClassDef::Union: result+=" Միավորում"; break;
+ case ClassDef::Interface: result+=" Ինտերֆեյս"; break;
+ case ClassDef::Protocol: result+=" Արձանագրություն"; break;
+ case ClassDef::Category: result+=" Դասակարգում"; break;
+ case ClassDef::Exception: result+=" Բացառություն"; break;
+ default: break;
+ }
+ }
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ return fileName+QCString(" ֆայլեր");
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" անունների տարածություններ";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Բաց անդամ ֆունկցիաներ"; }
+ virtual QCString trPublicSlots()
+ { return "Բաց սլոթեր"; }
+ virtual QCString trSignals()
+ { return "Ազդանշաններ"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Բաց ստատիկ անդամ ֆունկցիաներ"; }
+ virtual QCString trProtectedMembers()
+ { return "Պաշտպանված անդամ ֆունկցիաներ"; }
+ virtual QCString trProtectedSlots()
+ { return "Պաշտպանված սլոթեր"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Պաշտպանված ստատիկ անդամ ֆունկցիաներ"; }
+ virtual QCString trPrivateMembers()
+ { return "Փակ ֆունկցիաներ"; }
+ virtual QCString trPrivateSlots()
+ { return "Փակ սլոթեր"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Փակ ստատիկ անդամ ֆունկցիաներ"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" և ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Հենքային դասեր - "+trWriteList(numEntries)+":";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Ժառանգորդ դասեր - "+trWriteList(numEntries)+":";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Վերասահմանված ֆունկցիաներ - "+trWriteList(numEntries)+":";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Վերասահմանված է "+trWriteList(numEntries)+" ում:";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Անունների տարածության անդամներ"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if (!extractAll) result+="փաստագրված ";
+ result+="անունների տարածության անդամների ցուցակը` "
+ "հղումներով դեպի ";
+ if (extractAll)
+ result+="բոլոր անդամների անունների տարածության փաստագրությունը.";
+ else
+ result+="անունների տարածությունը, որին նրանք պատկանում են.";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Անունների տարածություններ"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Անունների տարածություն"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Անունների տարածություններ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ {
+ QCString result = (QCString)"Այս ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="դասի"; break;
+ case ClassDef::Struct: result+="կառուցվածքի"; break;
+ case ClassDef::Union: result+="միավորման"; break;
+ case ClassDef::Interface: result+="ինտերֆեյսի"; break;
+ case ClassDef::Protocol: result+="արձանագրության"; break;
+ case ClassDef::Category: result+="դասակարգման"; break;
+ case ClassDef::Exception: result+="բացառության"; break;
+ default: break;
+ }
+ result+=" փաստագրությունը ստեղծվել է հետևյալ ֆայլ";
+ if (single) result+="ից."; else result+="երից.";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Վերադարձվող արժեքներ"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Գլխավոր էջ"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "էջ:"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Սահմանումը @1 ֆայլի @0 տողում է:";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Սահմանումը @0 ֆայլում է:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Հնացած է";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)clName+"-ի համագործակցությունների գծագիր.";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)fName+"-ի ներառումների կախվածությունների գծագիր.";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Կառուցիչներ";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Տե'ս այս ֆայլի ելքային կոդը";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Տե'ս այս ֆայլի փաստագրությունը:";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Նախապայման";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Հետպայման";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Անփոփոխ";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Նախնական արժեք";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "Ելքային կոդ";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Գրաֆիկական դասերի հիերարխիա:";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Տե'ս դասերի գրաֆիկական հիերարխիան:";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Տե'ս դասերի տեքստային հիերարխիան:";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "էջեր";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Նշում";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Բաց տիպեր";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների դաշտեր";
+ }
+ else
+ {
+ return "Բաց ատրիբուտներ";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Բաց ստատիկ ատրիբուտներ";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Պաշտպանված տիպեր";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Պաշտպանված ատրիբուտներ";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Պաշտպանված ստատիկ ատրիբուտներ";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Փակ տիպեր";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Փակ ատրիբուտներ";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Փակ ստատիկ ատրիբուտներ";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ /*??*/
+ {
+ return "Կատարման ենթակա";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ /*??*/
+ {
+ return "Խնդիրների ցուցակ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Օգտագործվում է հետևյալում - ";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Դիտողություններ";
+ }
+ virtual QCString trAttention()
+ {
+ return "Ուշադրություն";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Այս գրաֆը ցույց է տալիս, թե որ ֆայլերն են "
+ "ուղղակի կամ անուղղակի ներառում տվյալ ֆայլը.";
+ }
+ virtual QCString trSince()
+ /*??*/
+ {
+ return "Սկսած";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Լեգենդ";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Այս էջը նկարագրում է, թե ինչպես մեկնաբանել doxygen-ի ստեղծած գրաֆները:<p>\n"
+ "Դիտարկենք հետևյալ օրինակը.\n"
+ "\\code\n"
+ "/*! Կրճատման հետևանքով անտեսանելի դաս */\n"
+ "class Invisible { };\n\n"
+ "/*! Կրճատված դաս, ժառանգությունների հարաբերությունը փակ է */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Չփաստագրված դաս */\n"
+ "class Undocumented { };\n\n"
+ "/*! Բաց ժառանգում */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Դասի ձևաչափ */\n"
+ "template<class T> class Templ {};\n\n"
+ "/*! Պաշտպանված ժառանգում */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Փակ ժառանգում */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Դաս, որը օգտագործվում է Inherited դասի կողմից */\n"
+ "class Used { };\n\n"
+ "/*! Դաս, որը ժառանգում է մի շարք այլ դասերից */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Սրանով կստանանք հետևյալ գրաֆը."
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Այս գրաֆի ուղղանկյունները ունեն հետևյալ իմաստը.\n"
+ "<ul>\n"
+ "<li>%A լցոնվաց մոխրագույն ուղղանկյունը ներկայացնում է այն դասը կամ կառուցվածքը, "
+ "որի համար ստեղծվել է տվյալ գրաֆը:</li>\n"
+ "<li>%A սև եզրերով ուղղանկյունը նշանակում է փաստագրված դաս կամ կարուցվածք:</li>\n"
+ "<li>%A մոխրագույն եզրերով ուղղանկյունը նշանակում է չփաստագրված դաս կամ կառուցվածք:</li>\n"
+ "<li>%A կարմիր եզրերով ուղղանկյունը նշանակում է դաս կամ կառուցվածք, որի համար\n"
+ " ոչ բոլոր ժառանգում/պարունակում կապերն են ցուցադրված: Գրաֆը կրճատված է, "
+ "եթե այն չի տեղավորվում նշված սահմաններում:</li>\n"
+ "</ul>\n"
+ "Սլաքները ունեն հետևյալ իմաստը.\n"
+ "<ul>\n"
+ "<li>%A մուգ կապույտ սլաքը օգտագործվում է երկու դասերի միջև բաց ժառանգում "
+ "կապը ցուցադրելու համար:</li>\n"
+ "<li>%A մուգ կանաչ սլաքը օգտագործվում է պաշտպանված ժառանգման համար:</li>\n"
+ "<li>%A մուգ կարմիր սլաքը օգտագործվում է փակ ժառանգման համար:</li>\n"
+ "<li>%A մանուշակագույն կետագիծ սլաքը օգտագորշվում է, եթե դասը պարունակվում է"
+ "այլ դասում կամ օգտագորշվում է այլ դասի կողմից: Սլաքը պիտակավորվաշ է"
+ "փոփոխական(ներ)ով, որի միջոցով մատնանշված դասը կամ կառուցվածքը հասանելի է:</li>\n"
+ "<li>Դեզին կետագիծ սլաքը ցույց է տալիս ձևանմուշի օրինակի կապը այն ձևանմուշի հետ, "
+ "որից այն իրականցվել է. Սլաքը պիտակավորված է օրինակի ձևանմուշային պարամետրերով:</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "լեգենդ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Թեստ";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Թեստերի ցուցակ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Հատկություններ";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Հատկություններ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Տվյալների կառուցվածք";
+ }
+ else
+ {
+ return "Դասեր";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Փաթեթ "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Փաթեթների ցուցակ";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Բոլոր փաթեթները` կարճ բացատրություններով (եթե հասանելի են).";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Փաթեթներ";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Արժեքներ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Սխալ";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Սխալների ցուցակ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "armscii-8";
+ }
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Ցուցիչ";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ QCString result((first_capital ? "Տվյալների կառուցվածք" : "տվյալների կառուցվածք"));
+ return result;
+ }
+ else
+ {
+ QCString result((first_capital ? "Դաս" : "դաս"));
+ if(!singular) result+="եր";
+ return result;
+ }
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ֆայլ" : "ֆայլ"));
+ if (!singular) result+="եր";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Անունների տարածություն" : "անունների տարածություն"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Խ" : "խ"));
+ result+=(singular ? "ումբ" : "մբեր");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Էջ" : "էջ"));
+ if (!singular) result+="եր";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Անդամ" : "անդամ"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Գլոբալ" : "գլոբալ"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Հեղինակ" : "հեղինակ"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Հղումներ - ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Իրագործում է հետևյալ դաս(եր)ի ֆունկցիաները - "+trWriteList(numEntries)+":";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Իրագործվում է հետևյալում - "+trWriteList(numEntries)+":";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Բովանդակություն";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Հնացած սահմանումների ցուցակը";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Պատահարներ";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Պատահարների ցուցակը";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Փաթեթի տիպեր";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Փաթեթի ֆունկցիաներ";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Փաթեթի ստատիկ ֆունկցիաներ";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Փաթեթի ատրիբուտներ";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Փաթեթի ստատիկ ատրիբուտներ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Բոլոր";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Այս ֆունկցիայի կանչերի գրաֆը.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Որոնման արդյունքները";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Ներեցեք, բայց Ձեր որոնումը արդյունք չտվեց:";
+ }
+ else if( numDocuments == 1 )
+ {
+ return "Հայտնաբերվել է 1 փաստաթուղթ:";
+ }
+ else
+ {
+ return "Հայտնաբերվել է <b>$num</b> փաստաթուղթ:"
+ "Փաստաթղթերը դասակարգված են ըստ համապասխանության";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Որոնման արդյունքներ:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Ելակետային ֆայլ " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Ֆայլադարանների հիերարխիա"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Ֆայլադարաններ"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Ֆայլադրաններ"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Այս ֆայլադարանների հիերարխիան կարգավորված է կոպտորեն, "
+ "բայց ոչ ամբողջապես, այբբենական կարգով.";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Ֆայլադարան"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ֆայլադարան" : "ֆայլադարան"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Սա վերաբեռնված ֆունկցիա է` տրամադրված հարմարության համար: "
+ "Այն տարբերվում է նախնականից միայն արգումնետներով:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Այս ֆունկցիայի կանչերի գրաֆը.";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Համարակալումներ"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Անդամ ֆունցիաներ/ենթածրագրեր"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Տվյալների տիպերի ցուցակը"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Տվյալների դաշտեր"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Տվյալների տիպերը` կարճ բացատրություններով."; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Բոլոր ";
+ if (!extractAll)
+ {
+ result+="փաստագրված ";
+ }
+ result+="տվյալների տիպերի անդամների ցուցակը` հղումներով դեպի ";
+ if (!extractAll)
+ {
+ result+="բոլոր անդամների տվյալների կառուցվածքի փաստագրությունը";
+ }
+ else
+ {
+ result+="տվյալների տիպերը, որոնց նրանք պատկանում են";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Տվյալների տիպեր"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Տվյալների տիպեր"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Ֆունկցիաներ/ենթածրագրեր"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Ֆունկցիաներ/ենթածրագրեր"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Տվյալների տիպեր"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Մոդուլների ցուցակ"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Բոլոր";
+ if (!extractAll) result+="փաստագրված ";
+ result+="մոդուլների ցուցակը` կարճ բացատրություններով.";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (!isTemplate)
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Մոդուլ"; break;
+ case ClassDef::Struct: result+=" Տիպ"; break;
+ case ClassDef::Union: result+=" Միավորում"; break;
+ case ClassDef::Interface: result+=" Ինտերֆեյս"; break;
+ case ClassDef::Protocol: result+=" Արձանագրություն"; break;
+ case ClassDef::Category: result+=" Դասակարգում"; break;
+ case ClassDef::Exception: result+=" Բացառություն"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Մոդուլի"; break;
+ case ClassDef::Struct: result+=" Տիպի"; break;
+ case ClassDef::Union: result+=" Միավորման"; break;
+ case ClassDef::Interface: result+=" Ինտերֆեյսի"; break;
+ case ClassDef::Protocol: result+=" Արձանագրության"; break;
+ case ClassDef::Category: result+=" Դասակարգման"; break;
+ case ClassDef::Exception: result+=" Բացառության"; break;
+ default: break;
+ }
+ result+=" Ձևանմուշ";
+ }
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ return QCString("Մոդուլ ") + namespaceName;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Մոդուլի անդամներ"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Մոդուլի բոլոր ";
+ if (!extractAll) result+="փաստագրված ";
+ result+="անդամների ցուցակը` հղումներով դեպի ";
+ if (extractAll)
+ {
+ result+="բոլոր անդամների փաստագրությունները.";
+ }
+ else
+ {
+ result+="մոդուլները, որոնց նրանք պատկանում են.";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Մոդուլներ"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Մոդուլ" : "մոդուլ"));
+ if (!singular) result+="ներ";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Այս ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="մոդուլի"; break;
+ case ClassDef::Struct: result+="տիպի"; break;
+ case ClassDef::Union: result+="միավորման"; break;
+ case ClassDef::Interface: result+="ինտերֆեյսի"; break;
+ case ClassDef::Protocol: result+="արձանագրության"; break;
+ case ClassDef::Category: result+="դասակարգման"; break;
+ case ClassDef::Exception: result+="բացառության"; break;
+ default: break;
+ }
+ result+=" փաստագրությունը ստեղծվել է հետևալ ֆայլ";
+ if (single) result+="ից."; else result+="երից.";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Տիպ" : "տիպ"));
+ if (!singular) result+="եր";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ե" : "ե"));
+ if (singular) result+="նթածրագիր"; else result+="նթածրագրեր";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Տիպերի Սահմանափակումներ";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Կապ";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Բեռնում...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Գլոբալ անունների տարածություն";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Որոնում...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Անարդյունք";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Ֆայլը " + name + " ում";
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Ներառում է ֆայլը " + name + " ում";
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Երկուշաբթի,","Երեքշաբթի,","Չորեքշաբթի,","Հինգշաբթի,",
+ "Ուրբաթ,","Շաբաթ,","Կիրակի," };
+ static const char *months[] = { "Հունիսի","Փետրվարի","Մարտի","Ապրրիլի","Մայիսի","Հունիսի",
+ "Հուլիսի","Օգոստոսի","Սեպտեմբերի","Հոկտեբմերի","Նոյեմբերի","Դեկտեմբերի" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d ",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Գրականություն"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Հեղինակային իրավունք"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return name + QCString("-ի ֆայլադարանների կախվածությունների գծագիր:"); }
+
+};
+
+#endif
diff --git a/src/translator_ar.h b/src/translator_ar.h
new file mode 100644
index 0000000..5d37b69
--- /dev/null
+++ b/src/translator_ar.h
@@ -0,0 +1,1569 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*
+ * Arabic translation for Doxygen
+ *
+ * Please send your comments on this translation to moazreyad at yahoo.com
+ *
+ * Note : consider this file as Beta version for testing Arabic output with Doxygen.
+ *
+ * Revision history :
+ *
+ * 6/2006 : Created initial version of Arabic translation.
+ */
+
+#ifndef TRANSLATOR_AR_H
+#define TRANSLATOR_AR_H
+
+class TranslatorArabic : public TranslatorAdapter_1_4_6
+{
+ protected:
+ friend class TranslatorAdapterBase;
+ virtual ~TranslatorArabic() {}
+
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "arabic"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "دوال ذات صلة"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(لاحظ أن هذه الدوال ليست أعضاء)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "وصف تفصيلي"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "توثيق تعريفات النوع الأعضاء"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "توثيق العدديات الأعضاء"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "توثيق الدوال الأعضاء"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "توثيق الحقل";
+ }
+ else
+ {
+ return "توثيق البيان العضو";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "المزيد ..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "اعرض كل الأعضاء"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "قائمة الأعضاء"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "هذه فائمة بكل الأعضاء في "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", متضمنة كل الأعضاء الموروثة"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="تم تكوينها آليا بواسطة Doxygen";
+ if (s) result+=(QCString)" لـ "+s;
+ result+=" من ملفات المصدر.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "الإسم العددي"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "القيمة العددية"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "معرف في"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "مكونات"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "الشكل الهرمي للفئة"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "هياكل البيانات";
+ }
+ else
+ {
+ return "قائمة الفئات";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "قائمة الملفات"; }
+
+ /*! This is put above each page as a link to the list of all verbatim headers */
+ virtual QCString trHeaderFiles()
+ { return "الملفات الرأسية"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "حقول البيانات";
+ }
+ else
+ {
+ return "أعضاء الفئة";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "العوام";
+ }
+ else
+ {
+ return "أعضاء الملف";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "صفحات ذات صلة"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "أمثلة"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "بحث"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "قائمة التوارث هذه تم ترتيبها أبجديا بصورة تقريبية ، "
+ "ولكن ليس بصورة تامة:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="هذه قائمة بكل الملفات";
+ if (!extractAll) result+="الموثقة ";
+ result+="مع وصف مختصر :";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "هذه هي هياكل البيانات مع وصف مختصر:";
+ }
+ else
+ {
+ return "هذه هي الفئات ، البناءات ،"
+ "الإتحادات والواجهات مع وصف مختصر:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="هذه قائمة بكل ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="حقول البناءات والإتحادات";
+ }
+ else
+ {
+ result+="أعضاء الفئة";
+ }
+ if (!extractAll)
+ {
+ result+=" الموثقة ";
+ }
+ result+=" مع وصلات إلى ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="توثيق البناء/الإتحاد لكل حقل:";
+ }
+ else
+ {
+ result+="توثيق الفئة لكل عضو:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="البناءات/الإتحادات التي ينتمون إليها:";
+ }
+ else
+ {
+ result+="الفئات التي ينتمون إليها:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="functions, variables, defines, enums, and typedefs";
+ }
+ else
+ {
+ result+="file members";
+ }
+ result+=" with links to ";
+ if (extractAll)
+ result+="the files they belong to:";
+ else
+ result+="the documentation:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all header files. */
+ virtual QCString trHeaderFilesDescription()
+ { return "Here are the header files that make up the API:"; }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "هذه قائمة بكل الأمثلة:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "هذه قائمة بكل صفحات التوثيق ذات الصلة:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "هذه قائمة بكل المكونات:"; }
+
+ /*! This sentences is used in the annotated class/file lists if no brief
+ * description is given.
+ */
+ virtual QCString trNoDescriptionAvailable()
+ { return "لا يوجد وصف متاح"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "التوثيق"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "فهرس المكونات"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "الفهرس الهرمي"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "فهرس هيكل البيانات";
+ }
+ else
+ {
+ return "فهرس الفئة";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "فهرس الملفات"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "توثيق المكون"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "فهرس هيكل البيانات";
+ }
+ else
+ {
+ return "فهرس الفئة";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "توثيق الملفات"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "توثيق الأمثلة"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "توثيق الصفحات"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "الكتيب المرجعي"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "التعريفات"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefs"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "العدديات"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "الدوال"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "المتغيرات"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumerator"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Define Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumeration Type Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerator Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "توثيق الدالة"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "توثيق المتغير"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "هياكل البيانات";
+ }
+ else
+ {
+ return "الفئات";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generated on "+date;
+ if (projName) result+=(QCString)" for "+projName;
+ result+=(QCString)" by";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Inheritance diagram for "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "للاستخدام الداخلي فقط."; }
+
+ /*! this text is generated when the \\reimp command is used. */
+ virtual QCString trReimplementedForInternalReasons()
+ { return "Reimplemented for internal reasons; the API is not affected."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "تنبيه"; }
+
+ /*! this text is generated when the \\bug command is used. */
+ virtual QCString trBugsAndLimitations()
+ { return "Bugs and limitations"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "إصدارة"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "تاريخ"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Returns"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "انظر أيضا"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parameters"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "استثناءات"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "انتجت بواسطة"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "قائمة مجالات الأسماء"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="namespaces with brief descriptions:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Friends And Related Function Documentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Class"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" File Reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Reference";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Public Member Functions"; }
+ virtual QCString trPublicSlots()
+ { return "Public Slots"; }
+ virtual QCString trSignals()
+ { return "Signals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Static Public Member Functions"; }
+ virtual QCString trProtectedMembers()
+ { return "Protected Member Functions"; }
+ virtual QCString trProtectedSlots()
+ { return "Protected Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Static Protected Member Functions"; }
+ virtual QCString trPrivateMembers()
+ { return "Private Member Functions"; }
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Static Private Member Functions"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", and ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Inherits "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Inherited by "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplemented from "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplemented in "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Namespace Members"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="namespace members with links to ";
+ if (extractAll)
+ result+="the namespace documentation for each member:";
+ else
+ result+="the namespaces they belong to:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "فهرس مجالات الأسماء"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "توثيق مجالات الأسماء"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "مجالات الأسماء"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"توثيق ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="هذه الفئة"; break;
+ case ClassDef::Struct: result+="هذا البناء"; break;
+ case ClassDef::Union: result+="هذا الإتحاد"; break;
+ case ClassDef::Interface: result+="هذه الواجهة"; break;
+ case ClassDef::Protocol: result+="هذا البروتوكول"; break;
+ case ClassDef::Category: result+="هذا التصنيف"; break;
+ case ClassDef::Exception: result+="هذا الإستثناء"; break;
+ default: break;
+ }
+ result+=" تم تكوينه من ";
+ if (single) result+="هذا الملف:"; else result+="هذه الملفات:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "قيم العودة"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "الصفحة الرئيسية"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "ص."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trSources()
+ {
+ return "مصادر";
+ }
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definition at line @0 of file @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definition in file @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Deprecated";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"رسم التعاون لـ "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"رسم اعتمادية التضمين لـ "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "توثيق دوال البناء والهدم";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "اذهب إلى الكود الخاص بهذا الملف.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "اذهب إلى توثيق هذا الملف.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "شرط سابق";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "شرط لاحق";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "ثابت";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "قيمة مبدئية:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "كود";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "الشكل الرسومي للفئات";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "اذهب إلى الشكل الهرمي الرسومي للفئات";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "اذهب إلى الشكل الهرمي النصي للفئات";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "فهرس الصفحات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "ملاحظات";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "أنواع عامة";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "حقول بيانات";
+ }
+ else
+ {
+ return "صفات عامة";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "صفات ساكنة عامة";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "أنواع محمية";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "صفات محمية";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "صفات ساكنة محمية";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "أنواع خاصة";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "صفات خاصة";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "صفات ساكنة خاصة";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "مهام";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "قائمة المهام";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "ذكر بواسطة";
+ }
+ virtual QCString trRemarks()
+ {
+ return "تعليقات";
+ }
+ virtual QCString trAttention()
+ {
+ return "انتبه";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "هذا الرسم يوضح الملفات التي ضمنت هذا الملف"
+ "بصورة مباشرة أو غير مباشرة:";
+ }
+ virtual QCString trSince()
+ {
+ return "منذ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Graph Legend";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "This page explains how to interpret the graphs that are generated "
+ "by doxygen.<p>\n"
+ "Consider the following example:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "If the \\c MAX_DOT_GRAPH_HEIGHT tag in the configuration file "
+ "is set to 240 this will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A filled black box represents the struct or class for which the "
+ "graph is generated.\n"
+ "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>%A box with a red border denotes a documented struct or class for"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries.\n"
+ "</ul>\n"
+ "The arrows have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.\n"
+ "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible.\n"
+ "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "the template class it was instantiated from. The arrow is labeled with "
+ "the template parameters of the instance.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legend";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "اختبار";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "قائمة الإختبارات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "خصائص";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "توثيق الخاصية";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java interfaces in the summary section of Java packages */
+ virtual QCString trInterfaces()
+ {
+ return "واجهات";
+ }
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "هياكل البيانات";
+ }
+ else
+ {
+ return "فئات";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"حزمة "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "قائمة الحزم";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "هذه هي الحزم مع وصف مختصر لكل منها )إن وجد( :";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "حزم";
+ }
+ /*! Used as a chapter title for Latex & RTF output */
+ virtual QCString trPackageDocumentation()
+ {
+ return "توثيق الحزم";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "القيمة:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "ثغرة";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "قائمة الثغرات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1256";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "178";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "فهرس";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool /*first_capital*/, bool singular)
+ {
+ QCString result("فئة");
+ if (!singular) result="فئات";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool /*first_capital*/, bool singular)
+ {
+ QCString result("ملف");
+ if (!singular) result="ملفات";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool /*first_capital*/, bool singular)
+ {
+ QCString result("مجال أسماء");
+ if (!singular) result="مجالات أسماء";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool /*first_capital*/, bool singular)
+ {
+ QCString result("مجموعة");
+ if (!singular) result="مجموعات";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool /*first_capital*/, bool singular)
+ {
+ QCString result("صفحة");
+ if (!singular) result="صفحات";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool /*first_capital*/, bool singular)
+ {
+ QCString result("عضو");
+ if (!singular) result="أعضاء";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trField(bool /*first_capital*/, bool singular)
+ {
+ QCString result("حقل");
+ if (!singular) result="حقول";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool /*first_capital*/, bool singular)
+ {
+ QCString result("عام");
+ if (!singular) result="عوام";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool /*first_capital*/, bool singular)
+ {
+ QCString result("المؤلف");
+ if (!singular) result="المؤلفون";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "مرجعيات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implements "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implemented in "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "جدول المحتويات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Deprecated List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "الأحداث";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "توثيق الأحداث";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "أنواع الحزمة";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "دوال الحزمة";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "دوال ساكنة للحزمة";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "خصائص الحزمة";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "خصائص ساكنة للحزمة";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "الكل";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "هذا هو رسم الاستدعاء لهذه الدالة:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "نتائج البحث";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "عفوا ، لا يوجد توثيق ملائم لما بحثت عنه.";
+ }
+ else if (numDocuments==1)
+ {
+ return "وثيقة مناسبة لما بحثت عنه. <b>1</b> تم العثور على.";
+ }
+ else
+ {
+ return "وثيقة مطابقة لما بحثت عنه <b>$num</b> تم إيجاد ."
+ "وتم ترتيبهم بحيث يكون الأقرب لنتيجة البحث أولا.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "يتطابق مع:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return " ملف المصدر" + filename ;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "شكل هرمي للأدلة"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "توثيق الأدلة"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "الأدلة"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "هذا الشكل الهرمي للأدلة تم ترتيبه أبجديا بصورة تقريبية، "
+ "وليس ترتيبا أبجديا كاملا:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=" مرجع الدليل"; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Director" : "director"));
+ if (singular) result+="y"; else result+="ies";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "هذه دالة عضو زائدة التحميل ،"
+ "وجد أنها ملائمة. إنها تختلف عن الدالة أعلاه"
+ "فقط في نوعية ال argument(s) التي تقبلها.";
+ }
+};
+
+#endif
diff --git a/src/translator_br.h b/src/translator_br.h
new file mode 100644
index 0000000..b381495
--- /dev/null
+++ b/src/translator_br.h
@@ -0,0 +1,1838 @@
+/******************************************************************************
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative workns derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Brazilian Portuguese translation version 20100531
+ * Maintainer: Fabio "FJTC" Jun Takada Chino <jun-chino at uol.com.br>
+ * Thanks to Jorge Ramos, Fernando Carijo and others for their contributions.
+ *
+ * History:
+ * 20110628:
+ * - Updated to 1.7.5;
+ * 20100531:
+ * - Updated to 1.6.3;
+ * 20091218:
+ * - Updated to 1.6.1;
+ * - Copyright year updated;
+ * - Translation updates suggested by Fernando Carijó added;
+ * 20080709:
+ * - References to MAX_DOT_GRAPH_HEIGHT removed from trLegendDocs().
+ * 20080206:
+ * - Method trTypeContraints() renamed to trTypeConstraints().
+ * 20071216:
+ * - New methods since 1.5.4 updated.
+ * Previous history removed from this version.
+ */
+#ifndef TRANSLATOR_BR_H
+#define TRANSLATOR_BR_H
+
+class TranslatorBrazilian : public TranslatorAdapter_1_8_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. May resemble
+ * the string returned by latexBabelPackage(), but it is not used
+ * for the same purpose. The identification should not be translated.
+ * It should be replaced by the name of the language in English
+ * (e.g. Czech, Japanese, Russian, etc.). It should be equal to
+ * the identification in language.h.
+ */
+ virtual QCString idLanguage()
+ {
+ return "brazilian";
+ }
+
+ /*! Used to get the command(s) for the language support. This method
+ * was designed for languages which do not prefer babel package.
+ * If this methods returns empty string, then the latexBabelPackage()
+ * method is used to generate the command for using the babel package.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[brazil]{babel}";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Funções Relacionadas"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Note que estas não são funções membros.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Descrição Detalhada"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Definições de Tipos"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Enumerações"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Métodos"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos";
+ }
+ else
+ {
+ return "Atributos";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Mais..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Lista de todos os Membros"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Lista dos Membros"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Esta é a lista de todos os membros de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", incluindo os membros herdados."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Gerado automaticamente por Doxygen";
+ if (s) result+=(QCString)" para "+s;
+ result+=" a partir de seu código-fonte.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "[Enumeração]"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "[Valor enumerado]"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definido(a) em"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Módulos"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hierarquia de Classes"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de Dados";
+ }
+ else
+ {
+ return "Lista de Componentes";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Lista de Arquivos"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de Dados";
+ }
+ else
+ {
+ return "Componentes Membros";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globais";
+ }
+ else
+ {
+ return "Arquivos Membros";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Páginas relacionadas"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Exemplos"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Busca"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Esta lista de hierarquias está parcialmente ordenada (ordem alfabética):"; }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os arquivos ";
+ if (!extractAll) result+="documentados ";
+ result+="e suas respectivas descrições:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Aqui estão as estruturas de dados, uniões e suas respectivas descrições:";
+ }
+ else
+ {
+ return "Aqui estão as classes, estruturas, uniões e interfaces e suas respectivas descrições:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="todas as estruturas e campos de uniões ";
+ if (!extractAll)
+ {
+ result+="documentas";
+ }
+ }
+ else
+ {
+ result+="todos os membros de classes ";
+ if (!extractAll)
+ {
+ result+="documentos";
+ }
+ }
+ result+=" com referências para ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="a documentação da estrutura/união de cada campo:";
+ }
+ else
+ {
+ result+="a documentação da classe de cada membro:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="a estrutura/união a que pertencem:";
+ }
+ else
+ {
+ result+="a classe a que pertencem:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="todas as funções, variáveis, definições, enumerações e definições de tipos ";
+ if (!extractAll) result+="documentadas ";
+ }
+ else
+ {
+ result+="todos os membros dos arquivos ";
+ if (!extractAll) result+="documentados ";
+ }
+ result+="com referências para ";
+ if (extractAll)
+ result+="seus respectivos arquivos:";
+ else
+ result+="suas respectivas documentações:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Esta é a lista com todos os exemplos:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Esta é a lista com toda a documentação relacionadas:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Esta é a lista com todos os módulos:"; }
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "\nDocumentação"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Índice dos Módulos"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Índice Hierárquico"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Índice das Estruturas de Dados";
+ }
+ else
+ {
+ return "Índice dos Componentes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Índice dos Arquivos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Módulos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Arquivos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Exemplos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Documentação Relacionada"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Guia de Referência"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definições e Macros"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definições de Tipos"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerações"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funções"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variáveis"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Valores enumerados"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Definições e macros"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Definições dos tipos"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumerações"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funções"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variáveis"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de Dados";
+ }
+ else
+ {
+ return "Componentes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Gerado em "+date;
+ if (projName) result+=(QCString)" para "+projName;
+ result+=(QCString)" por";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de Hierarquia para "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Apenas para uso interno."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Aviso"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versão"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Retorna"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Veja também"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parâmetros"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Exceções"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Gerado por"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Lista de Namespaces"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os Namespaces ";
+ if (!extractAll) result+="documentados ";
+ result+="com suas respectivas descrições:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Amigas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Amigas e Funções Relacionadas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referência da";
+ if (isTemplate) result+=" Template de";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Classe "; break;
+ case ClassDef::Struct: result+=" Estrutura "; break;
+ case ClassDef::Union: result+=" União "; break;
+ case ClassDef::Interface: result+=" Interface "; break;
+ case ClassDef::Protocol: result+=" Protocolo "; break;
+ case ClassDef::Category: result+=" Categoria "; break;
+ case ClassDef::Exception: result+=" Exceção "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result = "Referência do Arquivo ";
+ result += fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result ="Refência do Namespace ";
+ result += namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Métodos Públicos"; }
+ virtual QCString trPublicSlots()
+ { return "Slots Públicos"; }
+ virtual QCString trSignals()
+ { return "Sinais"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Métodos Públicos Estáticos"; }
+ virtual QCString trProtectedMembers()
+ { return "Métodos Protegidos"; }
+ virtual QCString trProtectedSlots()
+ { return "Slots Protegidos"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Métodos Protegidos Estáticos"; }
+ virtual QCString trPrivateMembers()
+ { return "Métodos Privados"; }
+ virtual QCString trPrivateSlots()
+ { return "Slots Privados"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Métodos Privados Estáticos"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" e ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Herdeiro de " + trWriteList(numEntries) + ".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Superclasse de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementação de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementado por "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Membros do Namespace"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista com todos os membros do Namespace ";
+ if (!extractAll) result+="documentados ";
+ result+="com referências para ";
+ if (extractAll)
+ result+="a documentação de seus respectivos Namespaces:";
+ else
+ result+="os seus respectivos namespaces:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespaces"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"A documentação para esta ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="classe "; break;
+ case ClassDef::Struct: result+="estrutura "; break;
+ case ClassDef::Union: result+="união "; break;
+ case ClassDef::Interface: result+="interface "; break;
+ case ClassDef::Protocol: result+="protocolo "; break;
+ case ClassDef::Category: result+="categoria "; break;
+ case ClassDef::Exception: result+="exceção "; break;
+ default: break;
+ }
+ result+=" foi gerada a partir ";
+ if (single) result+="do seguinte arquivo:"; else result+="dos seguintes arquivos:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valores Retornados"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Página Principal"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "pag."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definição na linha @0 do arquivo @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definição no arquivo @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ /*
+ * This note is for brazilians only.
+ * Esta é uma boa tradução para "deprecated"?
+ */
+ return "Descontinuado(a)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de colaboração para "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Gráfico de dependência de inclusões para "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Construtores & Destrutores";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Vá para o código-fonte deste arquivo.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Vá para a documentação deste arquivo.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Pré-Condição";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Pós-Condição";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariante";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valor Inicial:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "código";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Gráfico de Hierarquia de Classes";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Vá para o Gráfico de Hierarquia de Classes";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Vá para a Hierarquia de Classes (texto)";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Índice da Página";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Observação";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Tipos Públicos";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de Dados";
+ }
+ else
+ {
+ return "Atributos Públicos";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atributos Estáticos Públicos";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipos Protegidos";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atributos Protegidos";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atributos Estáticos Protegidos";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipos Privados";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atributos Privados";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atributos Privados Estáticos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Futuras Atividades";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Lista de Futuras Atividades";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenciado por";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Anotações";
+ }
+ virtual QCString trAttention()
+ {
+ return "Atenção";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Este grafo mostra quais arquivos estão direta ou indiretamente relacionados com este arquivo:";
+ }
+ virtual QCString trSince()
+ {
+ return "Desde";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda do Grafo";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Esta página explica como interpretar os grafos gerados pelo doxygen.<p>\n"
+ "Considere o seguinte exemplo:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Isto irá gerar o seguinte gráfo:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "As caixas no grafo acima tem as seguintes interpretações:\n"
+ "<ul>\n"
+ "<li>Uma caixa inteiramente preta representa a estrutura ou a classe para qual "
+ "o grafo foi gerado.\n"
+ "<li>Uma caixa com bordas pretas denota uma estrutura ou classe documentada.\n"
+ "<li>Uma caixa com bordas cinzas denota uma estrutura ou classe não documentada.\n"
+
+ "<li>Uma caixa com bordas vermelhas denota uma estrutura ou classe documentada para\n"
+ "a qual nem todas as heranças ou componentes são mostradas no grafo. Um grafo é "
+ "truncado quando este é maior que o tamanho especificado."
+ "</ul>\n"
+ "As setas tem os seguintes significados:\n"
+ "<ul>\n"
+ "<li>Uma seta azul escura é utilizada para denotar uma relação de herança "
+ "pública entre duas classes.\n"
+ "<li>Uma seta verde escura é utilizada para denotar uma herança protegida.\n"
+ "<li>Uma seta vermelho escura é utilizada para denotar uma herança privada.\n"
+ "<li>Uma seta púrpura pontilhada é usada se uma classe está contida ou é utilizada"
+ "por outra classe. A seta é marcada com a(s) variável(eis) "
+ "através das quais a classe ou estrutura apontada está acessível. \n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Teste";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Lista de Testes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propriedades";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Propriedades";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de Dados";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pacote "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista de Pacotes";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Esta é a lista com os pacotes e suas respectivas descrições (se disponíveis):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pacotes";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valor:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Problema";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista de Problemas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Índice";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Classe" : "classe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Arquivo": "arquivo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupo" : "grupo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Página" : "página"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membro" : "membro"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globa" : "globa"));
+ if (!singular){
+ result+="is";
+ }else{
+ result+="l";
+ }
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referências";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementado por "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Conteúdo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista de Descontinuados(as)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Eventos";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Eventos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipos do Pacote";
+ }
+
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funções do Pacote";
+ }
+
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funções Estáticas do Pacote";
+ }
+
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributos do Pacote";
+ }
+
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Atributos Estáticos do Pacote";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Todos";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Este é o diagrama das funções utilizadas por esta função:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Resultado da Busca";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Nenhum documento foi encontrado.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Apenas <b>1</b> documento foi encontrado.";
+ }
+ else
+ {
+ return "<b>$num</b> documentos encontrados. "
+ "Os melhores resultados vem primeiro.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Resultados:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Código-Fonte de " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarquia de Diretórios"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentação do Directório"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Diretórios"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Esta Hierarquia de Diretórios está parcialmente ordenada (ordem alfabética)"; }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result = "Referência do diretório ";
+ result += dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Diretório" : "diretório"));
+ if (!singular) result+="s";
+ return result;
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Este é um método provido por conveniência. "
+ "Ele difere do método acima apenas na lista de "
+ "argumentos que devem ser utilizados.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Este é o diagrama das funções que utilizam esta função:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentação da enumeração"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentação de Função Membro/Subrotina"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista de Tipos de Dados"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Campos de Dados"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Aqui estão os tipos de dados com descrições resumidas:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os membros ";
+ if (!extractAll) result+="documentados ";
+ result+="dos tipos de dados com links para ";
+ if (extractAll)
+ {
+ result+="a documentação dos tipos de dados para cada membro:";
+ }
+ else
+ {
+ result+="os tipos de dados a que pertencem:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Índice de Tipos de Dados"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentação dos Tipos de Dados"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funções/Subrotinas"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentação da Função/Subrotina"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipos de Dados"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Lista de Módulos"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os módulos ";
+ if (!extractAll) result+="documentados ";
+ result+="com descrições resumidas:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result = (QCString)"Referência ";
+
+ if (isTemplate) result+="da Template ";
+
+ switch(compType)
+ {
+ case ClassDef::Class: result+="do Modulo "; break;
+ case ClassDef::Struct: result+="do Tipo "; break;
+ case ClassDef::Union: result+="da União "; break;
+ case ClassDef::Interface: result+="da Interface "; break;
+ case ClassDef::Protocol: result+="do Protocolo "; break;
+ case ClassDef::Category: result+="da Categoria "; break;
+ case ClassDef::Exception: result+="da Exceção "; break;
+ default: break;
+ }
+ result += clName;
+
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result = "Referência do Módulo ";
+ result += namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membros do Módulo"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os membros ";
+ if (!extractAll) result+="documentados ";
+ result+="dos módulos com links para ";
+ if (extractAll)
+ {
+ result+="a documentação dos módulos para cada membro:";
+ }
+ else
+ {
+ result+="os módulos a que pertencem:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Índice dos Módulos"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modulo" : "modulo"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"A documentação para ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="este modulo "; break;
+ case ClassDef::Struct: result+="este tipo "; break;
+ case ClassDef::Union: result+="esta união "; break;
+ case ClassDef::Interface: result+="esta interface "; break;
+ case ClassDef::Protocol: result+="esto protocolo "; break;
+ case ClassDef::Category: result+="esta categoria "; break;
+ case ClassDef::Exception: result+="esta exceção "; break;
+ default: break;
+ }
+
+ result+=" foi gerada a partir do";
+ if (single)
+ result+=" seguinte arquivo:";
+ else
+ result+="s seguintes arquivos:";
+
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipo" : "tipo"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprograma" : "subprograma"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Restrições do Tipo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name
+ */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relação " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Carregando...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Procurando...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nenhuma entrada encontrada";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Arquivo em "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inclui arquivo em "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Segunda","Terça","Quarta","Quinta","Sexta","Sábado","Domingo" };
+ static const char *months[] = { "Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" };
+ QCString sdate;
+ sdate.sprintf("%s, %d de %s de %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Referências Bibliográficas"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ {
+ // Note: I will left it as is because "Direitos autorais" may not fit
+ // in the text.
+ return "Copyright";
+ }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Grafo de dependências do diretório ")+name+":"; }
+};
+#endif
diff --git a/src/translator_ca.h b/src/translator_ca.h
new file mode 100644
index 0000000..5c3e595
--- /dev/null
+++ b/src/translator_ca.h
@@ -0,0 +1,1843 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_CA_H
+#define TRANSLATOR_CA_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorCatalan : public TranslatorAdapter_1_8_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "catalan"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ //return "\\usepackage[catalan]{babel}\n\\usepackage[latin1]{inputenc}";
+ return "\\usepackage[catalan]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Funcions Associades"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Remarcar que aquestes funcions no són funcions membre.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Descripció Detallada"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Documentació de les Definicions de Tipus Membre"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Documentació de les Enumeracions Membre"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Documentació de les Funcions Membre"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentació dels Camps";
+ }
+ else
+ {
+ return "Documentació de les Dades Membre";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Més..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Llista de tots els membres"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Llista dels Membres"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Aquesta és la llista complerta dels membres de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", incloent tots els membres heretats."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generat automàticament per Doxygen";
+ if (s) result+=(QCString)" per a "+s;
+ result+=" a partir del codi font.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "nom de la enum"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "valors de la enum"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definit a"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Mòduls"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Jerarquia de Classes"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructures de Dades";
+ }
+ else
+ {
+ return "Llista de Classes";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Llista dels Fitxers"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Camps de Dades";
+ }
+ else
+ {
+ return "Membres de Classes";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globals";
+ }
+ else
+ {
+ return "Membres de Fitxers";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Pàgines Relacionades"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Exemples"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Cerca"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Aquesta llista d'herència està ordenada toscament, "
+ "però no completa, de forma alfabètica:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els fitxers ";
+ if (!extractAll) result+="documentats ";
+ result+="acompanyats amb breus descripcions:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Aquestes són les estructures de dades acompanyades amb breus descripcions:";
+ }
+ else
+ {
+ return "Aquestes són les classes, estructures, "
+ "unions i interfícies acompanyades amb breus descripcions:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="camps d'estructures i unions";
+ }
+ else
+ {
+ result+="membres de classe";
+ }
+ if (!extractAll)
+ {
+ result+=" documentats";
+ }
+ result+=" amb enllaços a ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="la documentació de l'estructura/unió per a cada camp:";
+ }
+ else
+ {
+ result+="la documentació de la classe per a cada membre:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="les estructures/unions a que pertanyen:";
+ }
+ else
+ {
+ result+="les classes a que pertanyen:";
+ }
+ }
+ return result;
+ }
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="totes les funcions, variables, definicions, enumeracions, i definicions de tipus";
+ if (!extractAll) result+=" documentades";
+ }
+ else
+ {
+ result+="tots els membres de fitxers";
+ if (!extractAll) result+=" documentats";
+ }
+ result+=" amb enllaços ";
+ if (extractAll)
+ result+="als fitxers als quals corresponen:";
+ else
+ result+="a la documentació:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Aquesta és la llista de tots els exemples:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Aquesta és la llista de totes les pàgines de documentació associades:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Aquesta és la llista de mòduls:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return ": Documentació"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Índex de Mòduls"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Índex Jeràrquic"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Índex d'Estructures de Dades";
+ }
+ else
+ {
+ return "Índex de Classes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Índex de Fitxers"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Documentació dels Mòduls"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentació de les Estructures de Dades";
+ }
+ else
+ {
+ return "Documentació de les Classes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Documentació dels Fitxers"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Documentació dels Exemples"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Documentació de les Pàgines"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Manual de Referència"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definicions"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definicions de Tipus"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumeracions"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funcions"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variables"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Valors de les Enumeracions"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Documentació de les Definicions"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Documentació de les Definicions de Tipus"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Documentació dels Tipus de les Enumeracions"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Documentació de les Funcions"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Documentació de les Variables"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructures de Dades";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generat a "+date;
+ if (projName) result+=(QCString)" per a "+projName;
+ result+=(QCString)" per";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama d'Herència per a "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Tan sols per a ús intern."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Atenció"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versió"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Retorna"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Mireu també"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Paràmetres"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Excepcions"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generat per"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Llista dels Espais de Noms"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Aquests són tots els espais de noms ";
+ if (!extractAll) result+="documentats ";
+ result+="amb breus descripcions:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Classes Amigues"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Documentació de funcions amigues i relacionades"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referència de";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" la Classe "; break;
+ case ClassDef::Struct: result+=" l'Estructura "; break;
+ case ClassDef::Union: result+=" la Unió "; break;
+ case ClassDef::Interface: result+=" la Interfície "; break;
+ case ClassDef::Protocol: result+="l Protocol "; break;
+ case ClassDef::Category: result+=" la Categoria "; break;
+ case ClassDef::Exception: result+=" l'Excepció "; break;
+ default: break;
+ }
+ if (isTemplate) result+="Template ";
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result="Referència del Fitxer ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Referència de l'Espai de Noms ";
+ result+=namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Mètodes públics"; }
+ virtual QCString trPublicSlots()
+ { return "Slots públics"; }
+ virtual QCString trSignals()
+ { return "Senyals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Mètodes Públics Estàtics"; }
+ virtual QCString trProtectedMembers()
+ { return "Mètodes Protegits"; }
+ virtual QCString trProtectedSlots()
+ { return "Slots Protegits"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Mètodes Protegits Estàtics"; }
+ virtual QCString trPrivateMembers()
+ { return "Mètodes Privats"; }
+ virtual QCString trPrivateSlots()
+ { return "Slots Privats"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Mètodes Privats Estàtics"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" i ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Hereta de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Heretat per "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementat de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementat a "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Membres de l'Espai de Noms"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els membres de l'espai de noms ";
+ if (!extractAll) result+="documentats ";
+ result+="amb enllaços a ";
+ if (extractAll)
+ result+="la documentació de l'espai de noms de cada membre:";
+ else
+ result+="l'espai de noms al qual corresponen:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Índex d'Espais de Noms"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Documentació de l'Espai de Noms"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Espais de Noms"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentació d'aquest";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="a classe"; break;
+ case ClassDef::Struct: result+="a estructura"; break;
+ case ClassDef::Union: result+="a unió"; break;
+ case ClassDef::Interface: result+="a interfície"; break;
+ case ClassDef::Protocol: result+=" protocol"; break;
+ case ClassDef::Category: result+="a categoria"; break;
+ case ClassDef::Exception: result+="a excepció"; break;
+ default: break;
+ }
+ result+=" es va generar a partir del";
+ if (!single) result+="s";
+ result+=" següent";
+ if (!single) result+="s";
+ result+=" fitxer";
+ if (!single) result+="s:"; else result+=":";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valors de retorn"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Pàgina principal"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definició a la línia @0 del fitxer @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definició al fitxer @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Antiquat";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de col·laboració per a "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Inclou el graf de dependències per a "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Documentació del Constructor i el Destructor";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Veure el codi d'aquest fitxer.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Veure la documentació d'aquest fitxer.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondició";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondició";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valor inicial:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "codi";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Jerarquia Gràfica de la Classe";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Veure la jerarquia gràfica de la classe";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Veure la jerarquia textual de la classe";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Índex de Pàgines";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Nota";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Tipus Públics";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Camps de Dades";
+ }
+ else
+ {
+ return "Atributs Públics";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atributs Públics Estàtics";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipus Protegits";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atributs Protegits";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atributs Protegits Estàtics";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipus Privats";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atributs Privats";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atributs Privats Estàtics";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Per fer";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Llista de coses per fer";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenciat a";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Remarca";
+ }
+ virtual QCString trAttention()
+ {
+ return "Atenció";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Aquest gràfic mostra quins fitxers inclouen, "
+ "de forma directa o indirecta, aquest fitxer:";
+ }
+ virtual QCString trSince()
+ {
+ return "Des de";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Llegenda del Gràfic";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Aquesta pàgina explica com s'interpreten els gràfics generats per doxygen.<p>\n"
+ "Considera aquest exemple:\n"
+ "\\code\n"
+ "/*! Classe invisible per culpa del retall */\n"
+ "class Invisible { };\n\n"
+ "/*! Classe truncada, l'herència està amagada */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Classe no documentada amb comentaris doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Classe heredada amb herència pública */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Una classe Template */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Classe heredada utilitzant herència protegida */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Classe heredada utiltzant herència privada */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Classe usada per la classe heretada */\n"
+ "class Used { };\n\n"
+ "/*! Super classe que hereda una quantitat de classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Resultarà el gràfic següent:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Les caixes del gràfic superior tenen aquesta interpretació:\n"
+ "<ul>\n"
+ "<li>Una caixa negra plena represent l'estructura o classe per la qual el gràfic s'ha generat.\n"
+ "<li>Una caixa de vora negra representa una estructura o classe documentada.\n"
+ "<li>Una caixa de vora verda representa una estructura o classe indocumentada.\n"
+ "<li>Una caixa de vora vermalla representa una estructura o classe documentada de la qual "
+ "no es mostren totes les relacions d'herència/inclusió. Un gràfic és truncat si no s'ajusta als límits.\n"
+ "</ul>\n"
+ "Les sagetes tenen aquest significat:\n"
+ "<ul>\n"
+ "<li>Una sageta blau fosc remarca una relació d'herència de tipus pública entre dues classes.\n"
+ "<li>Una sageta verd fosc remarca una relació d'herència de tipus protegida entre dues classes.\n"
+ "<li>Una sageta roig fosc remarca una relació d'herència de tipus privada entre dues classes.\n"
+ "<li>Una sageta puntejada de color porpra indica que una classe és continguda o usada per una altra classe."
+ " La sageta s'etiqueta amb la variable o variables a través de les quals la classe o estructura apuntada és accessible.\n"
+ "<li>Una sageta puntejada de color groc indica la relació entre una instància template i la classe template de què ha set instanciada."
+ " La sageta s'etiqueta amb els paràmetres template de la instància.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "llegenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Prova";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Llista de proves";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propietats";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentació de les Propietats";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructures de Dades";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paquet "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Llista de Paquets";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Aquesta és la llista de paquets, amb una breu descripció (si se'n disposa):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paquets";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valor:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Error";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Llista d'Errors";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Índex";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Classe" : "classe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fitxer" : "fitxer"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grup" : "grup"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Pàgin" : "pàgin"));
+ if (!singular) result+="es"; else result+="a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membre" : "membre"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referències";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementat a "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Taula de Continguts";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Llista d'Antiquats";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Esdeveniments";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentació dels Esdeveniments";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipus de paquets";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funcions de Paquet";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funcions Estàtiques de Paquet";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributs de Paquet";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Atributs Estàtics de Paquet";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tot";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Gràfic de crides d'aquesta funció:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Resultats de la Búsqueda";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "No s'ha trobat cap document.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Trobat <b>1</b> document.";
+ }
+ else
+ {
+ return "Trobats <b>$num</b> documents. "
+ "Mostrant els millors resultats primer.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Resultats:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Fitxer de Codi " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Jerarquia de Directoris"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentació dels Directoris"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directoris"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Aquesta jerarquia de directoris està ordenada toscament, "
+ "però no completa, de forma alfabètica:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Referència del Directori "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Directori" : "directori"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Aquesta és una funció membre sobrecarregada, "
+ "proveïda per conveniència. Es diferencia de la funció "
+ "anterior només en els arguments que accepta.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Gràfic de crides a aquesta funció:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentació de les Enumeracions"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentació de les Funcions/Subrutines Membre"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Llista de Tipus de Dades"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Camps de Dades"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Aquests són els tipus de dades acompanyats amb breus descripcions:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els membres de tipus de dades";
+ if (!extractAll)
+ {
+ result+=" documentats";
+ }
+ result+=" amb enllaços a ";
+ if (!extractAll)
+ {
+ result+="la documentació del tipus de dades per a cada membre:";
+ }
+ else
+ {
+ result+="els tipus de dades a que pertanyen:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Índex de Tipus de Dades"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentació dels Tipus de Dades"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funcions/Subrutines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentació de les Funcions/Subrutines"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipus de Dades"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Llista de Mòduls"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els mòduls ";
+ if (!extractAll) result+="documentats ";
+ result+="amb breus descripcions:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referència de";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" el Mòdul "; break;
+ case ClassDef::Struct: result+=" el Tipus "; break;
+ case ClassDef::Union: result+=" la Unió "; break;
+ case ClassDef::Interface: result+=" la Interfície "; break;
+ case ClassDef::Protocol: result+="l Protocol "; break;
+ case ClassDef::Category: result+=" la Categoria "; break;
+ case ClassDef::Exception: result+=" l'Excepció "; break;
+ default: break;
+ }
+ if (isTemplate) result+="Template ";
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Referència del Mòdul ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membres del Mòdul"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Aquesta és la llista de tots els membres del mòdul";
+ if (!extractAll)
+ {
+ result+=" documentats";
+ }
+ result+=" amb enllaços a ";
+ if (!extractAll)
+ {
+ result+="la documentació del mòdul per a cada membre:";
+ }
+ else
+ {
+ result+="els mòduls a que pertanyen:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Índex de Mòduls"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Mòdul" : "mòdul"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentació d'aquest";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" mòdul"; break;
+ case ClassDef::Struct: result+=" tipus"; break;
+ case ClassDef::Union: result+="a unió"; break;
+ case ClassDef::Interface: result+="a interfície"; break;
+ case ClassDef::Protocol: result+=" protocol"; break;
+ case ClassDef::Category: result+="a categoria"; break;
+ case ClassDef::Exception: result+="a excepció"; break;
+ default: break;
+ }
+ result+=" es va generar a partir del";
+ if (!single) result+="s";
+ result+=" següent";
+ if (!single) result+="s";
+ result+=" fitxer";
+ if (!single) result+="s:"; else result+=":";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Tipus" : "tipus"));
+ //if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (!singular) result+="es";
+ else result+="a";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Restriccions de Tipus";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relació";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Carregant...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Espai de Noms Global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Cercant...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Cap coincidència";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Fitxer a "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inclou fitxer a "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Dl","Dt","Dc","Dj","Dv","Ds","Dg" };
+ static const char *months[] = { "Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Sep","Oct","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Referències Bibliogràfiques"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Graf de dependència de directoris per a ")+name+":"; }
+
+};
+
+#endif
diff --git a/src/translator_cn.h b/src/translator_cn.h
new file mode 100644
index 0000000..fc01ce0
--- /dev/null
+++ b/src/translator_cn.h
@@ -0,0 +1,1800 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_CN_H
+#define TRANSLATOR_CN_H
+
+/*!
+ If you want insert a space whenever Chinese meets English characters, set
+ CN_SPC to " ", else null.
+*/
+#define CN_SPC " "
+
+class TranslatorChinese : public TranslatorAdapter_1_8_2
+{
+ public:
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in the language.cpp.
+ */
+
+ virtual QCString idLanguage()
+ { return "chinese"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ /*! used in the compound documentation before a list of related functions.
+ */
+ virtual QCString trRelatedFunctions()
+ { return "相关函数"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(请注意: 这些不是成员函数.)"; }
+
+ /*! header that is put before the detailed description of files,
+ * classes and namespaces.
+ */
+ virtual QCString trDetailedDescription()
+ { return "详细描述"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "成员类型定义说明"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "成员枚举类型说明"; }
+
+ /*! header that is put before the list of member function. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "成员函数说明"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "结构体成员变量说明";
+ }
+ else
+ {
+ return "类成员变量说明";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "更多..."; }
+
+ /*! put in the class documention */
+ virtual QCString trListOfAllMembers()
+ { return "所有成员列表"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "成员列表"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "成员的完整列表,这些成员属于"CN_SPC; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ",包括所有继承而来的类成员"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result;
+ result = "由"CN_SPC"Doyxgen"CN_SPC"通过分析"CN_SPC;
+ if (s) result += ((QCString)s+CN_SPC"的"CN_SPC);
+ result+= "源代码自动生成.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "枚举名称"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "枚举值"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "定义于"CN_SPC; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "模块"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "类继承关系"; }
+
+ /*! This is put above each page as a link to the list of annotated class */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "结构体";
+ }
+ else {
+ return "类列表";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "文件列表"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "成员变量";
+ }
+ else {
+ return "类成员";
+ }
+ }
+
+ /*! This is put above each page as a link to all member of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "全局定义";
+ } else {
+ return "文件成员";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "相关页面"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "示例"; }
+
+ virtual QCString trSearch()
+ { return "搜索"; }
+
+ virtual QCString trClassHierarchyDescription()
+ { return "此继承关系列表按字典顺序粗略的排序:"CN_SPC; }
+
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll) result+="文档化的";
+ result+="文件,并附带简要说明:";
+ return result;
+ }
+
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "这里列出了所有结构体,并附带简要说明:";
+ }
+ else
+ {
+ return "这里列出了所有类、结构、联合以及接口定义等,并附带简要说明:";
+ }
+ }
+
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll) {
+ result+="文档化的";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="结构体和联合体的成员变量,并附带";
+ }
+ else {
+ result+="类成员,并附带";
+ }
+ //result+=" with links to ";
+ if (extractAll) {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="结构体或联合的详细说明:";
+ }
+ else {
+ result+="类的详细说明:";
+ }
+ }
+ else {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="结构或联合所属的文件:";
+ }
+ else {
+ result+="类所属的文件:";
+ }
+ }
+ return result;
+ }
+
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll)
+ result +="文档化的";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result +="函数,变量,宏,枚举和类型定义等,并附带";
+ }
+ else {
+ result +="文件成员,并附带";
+ }
+
+ if (extractAll)
+ result+="其所属的文件:";
+ else
+ result+="其详细说明:";
+ return result;
+ }
+
+ virtual QCString trExamplesDescription()
+ { return "这里列出了所有示例:"; }
+
+ virtual QCString trRelatedPagesDescription()
+ { return "这里列出了所有相关页面:"; }
+
+ virtual QCString trModulesDescription()
+ { return "这里列出了所有模块:"; }
+
+ virtual QCString trDocumentation()
+ { return "文档"; }
+
+ virtual QCString trModuleIndex()
+ { return "模块索引"; }
+
+ virtual QCString trHierarchicalIndex()
+ { return "继承关系索引"; }
+
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "结构体索引";
+ }
+ else {
+ return "类索引";
+ }
+ }
+
+ virtual QCString trFileIndex()
+ { return "文件索引"; }
+
+ virtual QCString trModuleDocumentation()
+ { return "模块说明"; }
+
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "结构体说明";
+ }
+ else {
+ return "类说明";
+ }
+ }
+
+ virtual QCString trFileDocumentation()
+ { return "文件说明"; }
+
+ virtual QCString trExampleDocumentation()
+ { return "示例说明"; }
+
+ virtual QCString trPageDocumentation()
+ { return "页面说明"; }
+
+ virtual QCString trReferenceManual()
+ { return "参考手册"; }
+
+ virtual QCString trDefines()
+ { return "宏定义"; }
+
+ virtual QCString trTypedefs()
+ { return "类型定义"; }
+
+ virtual QCString trEnumerations()
+ { return "枚举"; }
+
+ virtual QCString trFunctions()
+ { return "函数"; }
+
+ virtual QCString trVariables()
+ { return "变量"; }
+
+ virtual QCString trEnumerationValues()
+ { return "枚举值"; }
+
+
+ virtual QCString trDefineDocumentation()
+ { return "宏定义说明"; }
+
+ virtual QCString trTypedefDocumentation()
+ { return "类型定义说明"; }
+
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "枚举类型说明"; }
+
+ virtual QCString trFunctionDocumentation()
+ { return "函数说明"; }
+
+ virtual QCString trVariableDocumentation()
+ { return "变量说明"; }
+
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "结构体";
+ }
+ else {
+ return "类";
+ }
+ }
+
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ { QCString result=(QCString)"生成于"CN_SPC+date;
+ if (projName) result+=(QCString)CN_SPC", 为"CN_SPC+projName;
+ result+=(QCString)"使用"CN_SPC;
+ return result;
+ }
+
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"类"CN_SPC+clName+CN_SPC"继承关系图:";
+ }
+
+ virtual QCString trForInternalUseOnly()
+ { return "仅限内部使用."; }
+
+ virtual QCString trWarning()
+ { return "警告"; }
+
+ virtual QCString trVersion()
+ { return "版本"; }
+
+ virtual QCString trDate()
+ { return "日期"; }
+
+ virtual QCString trReturns()
+ { return "返回"; }
+
+ virtual QCString trSeeAlso()
+ { return "参见"; }
+
+ virtual QCString trParameters()
+ { return "参数"; }
+
+ virtual QCString trExceptions()
+ { return "异常"; }
+
+ virtual QCString trGeneratedBy()
+ { return "制作者"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNamespaceList()
+ { return "命名空间列表"; }
+
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll) result+="文档化的";
+ result+="命名空间定义,附带简要说明:";
+ return result;
+ }
+
+ virtual QCString trFriends()
+ { return "友元"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "友元及相关函数文档"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ // used as the title of the HTML page of a class/struct/union
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate) result+=CN_SPC"模板";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="类"; break;
+ case ClassDef::Struct: result+="结构体"; break;
+ case ClassDef::Union: result+="联合体"; break;
+ case ClassDef::Interface: result+="接口"; break;
+ case ClassDef::Protocol: result+="协议"; break;
+ case ClassDef::Category: result+="分类"; break;
+ case ClassDef::Exception: result+="异常"; break;
+ default: break;
+ }
+ result+=CN_SPC"参考";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=CN_SPC"文件参考";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ { QCString result=namespaceName;
+ result+=CN_SPC"命名空间参考";
+ return result;
+ }
+
+ // these are for the member sections of a class, struct or union
+ virtual QCString trPublicMembers()
+ { return "Public 成员函数"; }
+
+ virtual QCString trPublicSlots()
+ { return "Public 槽"; }
+
+ virtual QCString trSignals()
+ { return "信号"; }
+
+ virtual QCString trStaticPublicMembers()
+ { return "静态 Public 成员函数"; }
+
+ virtual QCString trProtectedMembers()
+ { return "Protected 成员函数"; }
+
+ virtual QCString trProtectedSlots()
+ { return "Protected 槽"; }
+
+ virtual QCString trStaticProtectedMembers()
+ { return "静态 Protected 成员函数"; }
+
+ virtual QCString trPrivateMembers()
+ { return "Private 成员函数"; }
+
+ virtual QCString trPrivateSlots()
+ { return "Private 槽"; }
+
+ virtual QCString trStaticPrivateMembers()
+ { return "静态 Private 成员函数"; }
+
+ // end of member sections
+ virtual QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=","CN_SPC;
+ else // the fore last entry
+ result+=CN_SPC", 以及"CN_SPC;
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ { return "继承自"CN_SPC+trWriteList(numEntries)+CN_SPC"."; }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "被"CN_SPC+trWriteList(numEntries)+CN_SPC"继承.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "重载"CN_SPC+trWriteList(numEntries)+CN_SPC".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "被"CN_SPC+trWriteList(numEntries)+CN_SPC"重载.";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "命名空间成员"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll) result+="文档化的";
+ result+="命名空间成员,并附带";
+ if (extractAll)
+ result+="其说明文档:";
+ else
+ result+="其所属的文件:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "命名空间索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "命名空间文档"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ {
+ return "命名空间";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"该";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="类"; break;
+ case ClassDef::Struct: result+="结构体"; break;
+ case ClassDef::Union: result+="联合体"; break;
+ case ClassDef::Interface: result+="接口"; break;
+ case ClassDef::Protocol: result+="协议"; break;
+ case ClassDef::Category: result+="分类"; break;
+ case ClassDef::Exception: result+="异常"; break;
+ default: break;
+ }
+ result+="的文档由以下文件生成:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "返回值"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "首页"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "在文件"CN_SPC"@1"CN_SPC"第"CN_SPC"@0"CN_SPC"行定义.";
+ }
+
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "在文件"CN_SPC"@0"CN_SPC"中定义.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "弃用";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)clName+CN_SPC"的协作图:";
+ }
+
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)fName+CN_SPC"的引用(Include)关系图:";
+ }
+
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "构造及析构函数说明";
+ }
+
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "浏览源代码.";
+ }
+
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "浏览该文件的文档.";
+ }
+
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "前置条件";
+ }
+
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "后置条件";
+ }
+
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "不变性";
+ }
+
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "初始值:";
+ }
+
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "代码";
+ }
+
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "类继承关系图";
+ }
+
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "浏览类继承关系图";
+ }
+
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "浏览类继承关系表";
+ }
+
+ virtual QCString trPageIndex()
+ {
+ return "页面索引";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "注解";
+ }
+
+ virtual QCString trPublicTypes()
+ {
+ return "Public 类型";
+ }
+
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "成员变量";
+ }
+ else {
+ return "Public 属性";
+ }
+ }
+
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "静态 Public 属性";
+ }
+
+ virtual QCString trProtectedTypes()
+ {
+ return "Protected 类型";
+ }
+
+ virtual QCString trProtectedAttribs()
+ {
+ return "Protected 属性";
+ }
+
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "静态 Protected 属性";
+ }
+
+ virtual QCString trPrivateTypes()
+ {
+ return "Private 类型";
+ }
+
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private 属性";
+ }
+
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "静态 Private 属性";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "待办事项";
+ }
+
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "待办事项列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "参考自";
+ }
+
+ virtual QCString trRemarks()
+ {
+ return "备注";
+ }
+
+ virtual QCString trAttention()
+ {
+ return "注意";
+ }
+
+ virtual QCString trInclByDepGraph()
+ {
+ return "此图展示该文件直接或间接的被哪些文件引用了:";
+ }
+
+ virtual QCString trSince()
+ {
+ return "自从";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "图例";
+ }
+
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return "本页将向您解释如何理解由"CN_SPC"doxygen"CN_SPC"生成的图.<p>\n"
+ "考虑如下例子:\n"
+ "\\code\n"
+ "/*! 由于截断而使 Invisible 不可见 */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated 的继承关系将被隐藏 */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* 没有被doxygen文档化的类 */\n"
+ "class Undocumented { };\n\n"
+ "/*! public 继承关系的类 */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! 一个模板类 */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! protected 继承关系的类 */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! private 继承关系的类 */\n"
+ "class PrivateBase { };\n\n"
+ "/*! 被 Inherited 使用的类 */\n"
+ "class Used { };\n\n"
+ "/*! 继承自其它若干类的超级类 */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "结果将会生成以下图:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "上图中的矩形有如下意义:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%灰色填充的矩形 表示上图是由该结构体或类生成.</li>\n"
+ "<li>%黑色边框的矩形 表示已经被文档化的结构体或类.</li>\n"
+ "<li>%灰色边框的矩形 表示未被文档化的结构体或类.</li>\n"
+ "<li>%红色边框的矩形 表示该结构体或类的关系没有被完全显示."
+ "%如果生成的图不能调整到制定的尺寸,有一些关系就会被截断而不显示出来.</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "箭头有如下意义:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%深蓝色的箭头被用于展示 public 的继承关系.</li>\n"
+ "<li>%深绿色的箭头表示 protected 的继承关系.</li>\n"
+ "<li>%深红色的箭头说明了是 privated 的继承关系.</li>\n"
+ "<li>%紫色虚线箭头用来表示两个类之间的聚合关系. 被箭头指向的类的类型的变量,可以通过箭头旁标明的变量去访问.</li>\n"
+ "<li>%黄色虚线箭头表示模板类实例和模板类之间的关系. 箭头旁边标明了模板类实例化的参数.</li>\n"
+ "</ul>\n";
+ }
+
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "图例";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "测试";
+ }
+
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "测试列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+//// new since 1.2.2
+////////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "属性";
+ }
+
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "属性说明";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "结构体";
+ }
+ else
+ {
+ return "类";
+ }
+ }
+
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"包"CN_SPC+name;
+ }
+
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "包列表";
+ }
+
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "这里列出所有的包,附带简要说明(如果有的话):";
+ }
+
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "包";
+ }
+
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "值:";
+ }
+
+////////////////////////////////////////////////////////////////////////////
+//// new since 1.2.6
+////////////////////////////////////////////////////////////////////////////
+ virtual QCString trBug ()
+ {
+ return "Bug";
+ }
+
+ virtual QCString trBugList ()
+ {
+ return "Bug"CN_SPC"列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "936";
+ }
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "134";
+ }
+
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "索引";
+ }
+
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Class" : "class"));
+ if (!singular) result+="es";
+ return result;
+ */
+ return "类";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "File" : "file"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "文件";
+
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "命名空间";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Group" : "group"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "组";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Page" : "page"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "页";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Member" : "member"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "成员";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "全局";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool /*first_capital*/, bool /*singular*/)
+ {
+ /*
+ QCString result((first_capital ? "Author" : "author"));
+ if (!singular) result+="s";
+ return result;
+ */
+ return "作者";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "参考";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ /* return "Implements "+trWriteList(numEntries)+"."; */
+ return "实现了"CN_SPC+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ /* return "Implemented in "+trWriteList(numEntries)+"."; */
+ return "在"CN_SPC+trWriteList(numEntries)+CN_SPC"内被实现.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ /* return "Table of Contents"; */
+ return "目录";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "弃用列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "事件";
+ }
+
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "事件说明";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "包类型";
+ }
+
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "包函数";
+ }
+
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "静态包函数";
+ }
+
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "包属性";
+ }
+
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "静态包属性";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "全部";
+ }
+
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "函数调用图:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "搜索结果";
+ }
+
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "抱歉,未找到与您查询相符的文档.";
+ }
+ else if (numDocuments==1)
+ {
+ return "找到<b>1</b>篇与您查询相符的文档.";
+ }
+ else
+ {
+ return "找到<b>$num</b>篇与您查询相符的文档."
+ "优先显示最符合的文档.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "符合的结果:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ /* return filename + " Source File"; */
+ return filename + CN_SPC"源文件";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ {
+ return "目录结构";
+ }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ {
+ return "目录说明";
+ }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "目录"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ {
+ return "此继承关系列表按字典顺序粗略的排序:"CN_SPC;
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result=dirName;
+ result+=CN_SPC"目录参考";
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "目录";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "这是为便于使用而提供的一个重载成员函数."
+ "与上面的函数相比,它接受不同类型的参数.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "这是这个函数的调用关系图:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ {
+ return "枚举变量说明";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "成员函数/子程序说明"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "数据类型列表"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "数据项"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "带简要描述的数据类型列表:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll)
+ {
+ result+="文档化的";
+ }
+ result+="数据类型成员,并附带";
+ //result+=" with links to ";
+ if (!extractAll)
+ {
+ result+="其说明文档:";
+ }
+ else
+ {
+ result+="其所属的文件:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "数据类型索引"; }
+
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "数据类型文档"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "函数/子程序"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "函数/子程序说明"; }
+
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "数据类型"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "模块列表"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="这里列出了所有";
+ if (!extractAll) result+="文档化的";
+ result+="模块,并附带简要说明:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=CN_SPC"模块"; break;
+ case ClassDef::Struct: result+=CN_SPC"类型"; break;
+ case ClassDef::Union: result+=CN_SPC"联合体"; break;
+ case ClassDef::Interface: result+=CN_SPC"接口"; break;
+ case ClassDef::Protocol: result+=CN_SPC"协议"; break;
+ case ClassDef::Category: result+=CN_SPC"目录"; break;
+ case ClassDef::Exception: result+=CN_SPC"异常"; break;
+ default: break;
+ }
+ if (isTemplate) result+="模板"CN_SPC;
+ result+="参考手册";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result += CN_SPC"模块参考手册";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "模块成员"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ // QCString result="Here is a list of all ";
+ // if (!extractAll) result+="documented ";
+ // result+="module members with links to ";
+ // if (extractAll)
+ // {
+ // result+="the module documentation for each member:";
+ // }
+ // else
+ // {
+ // result+="the modules they belong to:";
+ // }
+ // return result;
+ if(!extractAll) {
+ return "这里是有文档的模块成员列表,含有到每个成员所在模块的文档的链接:";
+ } else {
+ return "这里是模块成员列表,含有到成员所属的模块的链接:";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ // { return "Modules Index"; }
+ { return "模块索引"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool, bool)
+ {
+ // QCString result((first_capital ? "Module" : "module"));
+ // if (!singular) result+="s";
+ // return result;
+ return "模块";
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool)
+ {
+ QCString result="该";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=CN_SPC"模块"; break;
+ case ClassDef::Struct: result+=CN_SPC"结构体"; break;
+ case ClassDef::Union: result+=CN_SPC"联合体"; break;
+ case ClassDef::Interface: result+=CN_SPC"接口"; break;
+ case ClassDef::Protocol: result+=CN_SPC"协议"; break;
+ case ClassDef::Category: result+=CN_SPC"目录"; break;
+ case ClassDef::Exception: result+=CN_SPC"异常"; break;
+ default: break;
+ }
+ result+=CN_SPC"的文档由以下文件生成:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool, bool)
+ {
+ return "类型";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool, bool)
+ {
+ return "子程序";
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "类型限制";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0
+//////////////////////////////////////////////////////////////////////////
+ virtual QCString trDirRelation(const char *name)
+ {
+ // return QCString(name)+" Relation";
+ // unsure
+ return QCString(name)+CN_SPC"关系";
+ }
+
+ virtual QCString trLoading()
+ {
+ return "载入中...";
+ }
+
+ virtual QCString trGlobalNamespace()
+ {
+ return "全局命名空间";
+ }
+
+ virtual QCString trSearching()
+ {
+ return "搜索中...";
+ }
+
+ virtual QCString trNoMatches()
+ {
+ return "未找到";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"文件在"+CN_SPC+name;
+ }
+
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"在"CN_SPC+name+CN_SPC"中引用";
+ }
+
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "一","二","三","四","五","六","日" };
+ static const char *months[] = { "一","二","三","四","五","六","七","八","九","十","十一","十二" };
+
+ QCString sdate;
+
+ sdate.sprintf("%d年"CN_SPC"%s月"CN_SPC"%d日"CN_SPC"星期%s",year, months[month-1], day, days[dayOfWeek-1]);
+
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "参考书目"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "版权所有"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ {
+ return QCString(name)+CN_SPC"的目录依赖关系图";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "详情级别"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "模板参数"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "和"CN_SPC+number+CN_SPC"更多..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool /*single*/)
+ { return "枚举说明文档从下列文件生成:"; }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+CN_SPC"枚举类型参考"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+CN_SPC"继承自"CN_SPC+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "额外继承的成员函数"; }
+
+//////////////////////////////////////////////////////////////////////////
+};
+
+#endif
+
diff --git a/src/translator_cz.h b/src/translator_cz.h
new file mode 100644
index 0000000..b83eb92
--- /dev/null
+++ b/src/translator_cz.h
@@ -0,0 +1,2042 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_CZ_H
+#define TRANSLATOR_CZ_H
+
+// Updates:
+// --------
+// 2013/04/11 - Updates for "new since 1.8.4".
+// 2012/07/31 - Updates for "new since 1.8.2".
+// 2012/04/10 - Updates for "new since 1.8.0".
+// 2011/07/28 - Updates for "new since 1.7.5".
+// 2010/06/01 - typo
+// 2010/04/28 - Updates for "new since 1.6.3".
+// 2009/09/02 - Updates for "new since 1.6.0 (mainly for the new search engine)".
+// 2008/06/09 - Corrections in trLegendDocs().
+// 2007/11/13 - Update for "new since 1.5.4 (mainly for Fortran)".
+// 2007/03/20 - removing decode(), conversion of literals to UTF-8.
+// 2006/06/13 - translation of the trEnumerationValueDocumentation().
+// and clear in the Czech language.
+// modified trCallGraph() to make the meaning unambiguous
+// 2006/05/10 - Update for "new since 1.4.6" -- trCallerGraph(),
+// 2005/03/08 - Update for "new since 1.4.1" (trOverloadText())
+// 2005/02/11 - The "never used" methods removed.
+// 2004/09/14 - The new methods "since 1.3.9" implemented.
+// 2004/06/16 - The new method "since 1.3.8" implemented.
+// 2004/02/27 - Text inside the trCallGraph() corrected.
+// 2004/02/26 - trLegendDocs() updated.
+// 2003/08/13 - Four new methods "since 1.3.3" implemented.
+// 2003/06/10 - Two new methods "since 1.3.1" implemented.
+// 2003/04/28 - Five new methods "since 1.3" implemented.
+// 2002/10/15 - The new trEvents() and trEventDocumentation() implemented.
+// 2002/07/29 - The new trDeprecatedList() implemented.
+// 2002/07/08 - The new trRTFTableOfContents() implemented. (my birthday! ;)
+// 2002/03/05 - ... forgot to replace TranslatorAdapter... by Translator.
+// 2002/01/23 - Two new methods "since 1.2.13" implemented.
+// 2001/11/06 - trReferences() implemented.
+// 2001/07/16 - trClassDocumentation() updated as in the English translator.
+// 2001/05/25 - Corrections.
+// 2001/05/18 - Updates, corrections.
+// 2001/05/02 - Decode() inline changed to decode(); cleaning.
+// level as other translators.
+// class Translator. The English translator is now on the same
+// introducing TranslatorAdapter class and the abstract base
+// 2001/04/20 - Update for "new since 1.2.6-20010422". Experimental version
+// 2001/04/10 - Updates (1.2.6-20010408), cleaning.
+// 2001/03/12 - Minor correction of comments (synchronous with translator.h).
+// 2001/02/26 - Update for "new since 1.2.5" version (trBug(), trBugList()).
+// 2001/02/15 - trMore() now returns only "..." (ellipsis).
+// 2001/01/09 - Update for "new since 1.2.4" version.
+// 2000/10/17 - Update for "new since 1.2.2" version.
+// 2000/09/11 - Update for "new since 1.2.1" version.
+// 2000/09/06 - Reimplementation of trInheritsList().
+// 2000/08/31 - ISOToWin() and WinToISO() moved to the base class.
+// 2000/08/30 - Macro DECODE replaced by the inline (thanks to Boris Bralo).
+// 2000/08/24 - Corrections, updates.
+// 2000/08/02 - Updated for 1.2.0
+// 2000/07/19 - Updates for "new since 1.1.5"; encoding conversion separated.
+// 2000/07/10 - Update to 1.1.5; conditionally decoding to iso-8859-2 for UNIX.
+// 2000/06/20 - Prototype: with diacritics; based on ver. 1.1.4 (from scratch).
+//
+// The first translation from English to Czech was started by
+// Vlastimil Havran (1999--2000). The prototype version of Czech strings
+// with diacritics was implemented by Petr Prikryl (prikrylp at skil.cz),
+// 2000/06/20. Vlastimil agreed that Petr be the new maintainer.
+
+// Todo
+// ----
+// - The trReimplementedFromList() should pass the kind of the
+// reimplemented element. It can be method, typedef or possibly
+// something else. It is difficult to find the general translation
+// for all kinds in the Czech language.
+
+class TranslatorCzech : public Translator
+{
+ public:
+ // --- Language control methods -------------------
+
+ virtual QCString idLanguage()
+ { return "czech"; }
+
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[T2A]{fontenc}\n"
+ "\\usepackage[czech]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Související funkce"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Uvedené funkce nejsou členskými funkcemi.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detailní popis"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentace k členským typům"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentace k členským výčtům"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentace k metodám"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentace k položkám";
+ }
+ else
+ {
+ return "Dokumentace k datovým členům";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Seznam všech členů"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Seznam členů třídy"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Zde naleznete úplný seznam členů třídy "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", včetně všech zděděných členů."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result("Generováno automaticky programem Doxygen "
+ "ze zdrojových textů");
+ if (s) result += QCString(" projektu ") + s;
+ result += ".";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "jméno výčtu"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "hodnota výčtu"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definován v"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduly"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hierarchie tříd"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datové struktury";
+ }
+ else
+ {
+ return "Seznam tříd";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Seznam souborů"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datové položky";
+ }
+ else
+ {
+ return "Seznam členů tříd";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globální symboly";
+ }
+ else
+ {
+ return "Symboly v souborech";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Ostatní stránky"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Příklady"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Hledat"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Zde naleznete seznam, vyjadřující vztah dědičnosti tříd. "
+ "Je seřazen přibližně (ale ne úplně) podle abecedy:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Zde naleznete seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="souborů se stručnými popisy:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Následující seznam obsahuje identifikace datových "
+ "struktur a jejich stručné popisy:";
+ }
+ else
+ {
+ return "Následující seznam obsahuje především identifikace "
+ "tříd, ale nacházejí se zde i další netriviální prvky, "
+ "jako jsou struktury (struct), unie (union) a rozhraní "
+ "(interface). V seznamu jsou uvedeny jejich stručné "
+ "popisy:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result= "Zde naleznete seznam všech ";
+ if (!extractAll)
+ {
+ result += "dokumentovaných ";
+ }
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result += "položek struktur (struct) a unií (union) ";
+ }
+ else
+ {
+ result += "členů tříd ";
+ }
+
+ result += "s odkazy na ";
+
+ if (extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result += "dokumentaci struktur/unií, ke kterým příslušejí:";
+ }
+ else
+ {
+ result += "dokumentaci tříd, ke kterým příslušejí:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktury/unie, ke kterým příslušejí:";
+ }
+ else
+ {
+ result+="třídy, ke kterým příslušejí:";
+ }
+ }
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Zde naleznete seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcí, proměnných, maker, výčtů a definic typů (typedef) "
+ "s odkazy na ";
+ }
+ else
+ {
+ result+="symbolů, které jsou definovány na úrovni svých souborů. "
+ "Pro každý symbol je uveden odkaz na ";
+ }
+
+ if (extractAll)
+ result+="soubory, ke kterým příslušejí:";
+ else
+ result+="dokumentaci:";
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Zde naleznete seznam všech příkladů:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Následující seznam odkazuje na další stránky projektu:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Zde naleznete seznam všech modulů:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentace"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Rejstřík modulů"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Rejstřík hierarchie tříd"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Rejstřík datových struktur";
+ }
+ else
+ {
+ return "Rejstřík tříd";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Rejstřík souborů"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Dokumentace modulů"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentace datových struktur";
+ }
+ else
+ {
+ return "Dokumentace tříd";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dokumentace souborů"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentace příkladů"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Dokumentace souvisejících stránek"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referenční příručka"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definice maker"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definice typů"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Výčty"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkce"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Proměnné"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Hodnoty výčtu"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Dokumentace k definicím maker"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentace definic typů"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentace výčtových typů"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentace funkcí"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Dokumentace proměnných"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datové struktry";
+ }
+ else
+ {
+ return "Třídy";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result("Generováno ");
+ result += date;
+ if (projName)
+ result += QCString(" pro projekt ") + projName;
+ result += " programem";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return QCString("Diagram dědičnosti pro třídu ") + clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Pouze pro vnitřní použití."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Pozor"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Verze"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Datum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Návratová hodnota"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Viz také"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametry"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Výjimky"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generováno programem"; }
+
+ // new since 0.49-990307
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Seznam prostorů jmen"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Zde naleznete seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="prostorů jmen se stručným popisem:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentace k friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result("Dokumentace ");
+ if (isTemplate) result += "šablony ";
+ switch(compType)
+ {
+ case ClassDef::Class: result += "třídy "; break;
+ case ClassDef::Struct: result += "struktury "; break;
+ case ClassDef::Union: result += "unie "; break;
+ case ClassDef::Interface: result += "rozhraní "; break;
+ case ClassDef::Protocol: result += "protokolu "; break;
+ case ClassDef::Category: result += "kategorie "; break;
+ case ClassDef::Exception: result += "výjimky "; break;
+ default: break;
+ }
+ result += clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result("Dokumentace souboru ");
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result("Dokumentace prostoru jmen ");
+ result+=namespaceName;
+ return result;
+ }
+
+ /*
+ * these are for the member sections of a class, struct or union
+ */
+ virtual QCString trPublicMembers()
+ { return "Veřejné metody"; }
+ virtual QCString trPublicSlots()
+ { return "Veřejné sloty"; }
+ virtual QCString trSignals()
+ { return "Signály"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statické veřejné metody"; }
+ virtual QCString trProtectedMembers()
+ { return "Chráněné metody"; }
+ virtual QCString trProtectedSlots()
+ { return "Chráněné sloty"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statické chráněné metody"; }
+ virtual QCString trPrivateMembers()
+ { return "Privátní metody"; }
+ virtual QCString trPrivateSlots()
+ { return "Privátní sloty"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statické privátní metody"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" a ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ QCString result("Dědí z ");
+ result += (numEntries == 1) ? "bázové třídy " : "bázových tříd ";
+ result += trWriteList(numEntries) + ".";
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ QCString result("Zděděna ");
+ result += (numEntries == 1) ? "třídou " : "třídami ";
+ result += trWriteList(numEntries) + ".";
+ return result;
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ QCString result("Reimplementuje stejnojmenný prvek z ");
+ result += trWriteList(numEntries) + ".";
+ return result;
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ QCString result("Reimplementováno v ");
+ result += trWriteList(numEntries) + ".";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Symboly v prostorech jmen"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Zde naleznete seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="symbolů, které jsou definovány ve svých prostorech jmen. "
+ "U každého je uveden odkaz na ";
+ if (extractAll)
+ result+="dokumentaci příslušného prostoru jmen:";
+ else
+ result+="příslušný prostor jmen:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Rejstřík prostorů jmen"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Dokumentace prostorů jmen"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Prostory jmen"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentace pro ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="tuto třídu"; break;
+ case ClassDef::Struct: result+="tuto strukturu (struct)"; break;
+ case ClassDef::Union: result+="tuto unii (union)"; break;
+ case ClassDef::Interface: result+="toto rozhraní"; break;
+ case ClassDef::Protocol: result+="tento protokol "; break;
+ case ClassDef::Category: result+="tuto kategorii "; break;
+ case ClassDef::Exception: result+="tuto výjimku"; break;
+ default: break;
+ }
+ result+=" byla generována z ";
+ if (single) result+="následujícího souboru:";
+ else result+="následujících souborů:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Vracené hodnoty"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hlavní stránka"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definice je uvedena na řádku @0 v souboru @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definice v souboru @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Zastaralé";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagram tříd pro "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graf závislostí na vkládaných souborech "
+ "pro "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentace konstruktoru a destruktoru";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Zobrazit zdrojový text tohoto souboru.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Zobrazit dokumentaci tohoto souboru.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondition";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondition";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Initializer:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "zdrojový text";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafické zobrazení hierarchie tříd";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Zobrazit grafickou podobu hierarchie tříd";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Zobrazit textovou podobu hierarchie tříd";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Rejstřík stránek";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Poznámka";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Veřejné typy";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datové položky";
+ }
+ else
+ {
+ return "Veřejné atributy";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statické veřejné atributy";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Chráněné typy";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Chráněné atributy";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statické chráněné atributy";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privátní typy";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privátní atributy";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statické privátní atributy";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Plánované úpravy";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Seznam plánovaných úprav";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Používá se v";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Poznámky"; // ??? not checked in a context
+ }
+ virtual QCString trAttention()
+ {
+ return "Upozornění"; // ??? not checked in a context
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Následující graf ukazuje, které soubory přímo nebo "
+ "nepřímo vkládají tento soubor:";
+ }
+ virtual QCString trSince()
+ {
+ return "Od"; // ??? not checked in a context
+ }
+
+////////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Vysvětlivky ke grafu";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Zde naleznete vysvětlení, jak mají být interpretovány grafy, "
+ "které byly generovány programem doxygen.<p>\n"
+ "Uvažujte následující příklad:\n"
+ "\\code\n"
+ "/*! Neviditelná třída, která se v grafu nezobrazuje, protože "
+ "došlo k ořezání grafu. */\n"
+ "class Invisible { };\n\n"
+ "/*! Třída, u které došlo k ořezání grafu. Vztah dědičnosti "
+ "je skryt. */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Třída, která není dokumentována komentáři programu doxygen. */\n"
+ "class Undocumented { };\n\n"
+ "/*! Bázová třída děděná veřejně (public inheritance). */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Šablona třídy. */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Bázová třída, použitá pro chráněné dědění "
+ "(protected inheritance). */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Bázová třída, využitá pro privátní dědění "
+ "(private inheritance). */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Třída, která je využívána třídou Inherited. */\n"
+ "class Used { };\n\n"
+ "/*! Odvozená třída, která dědí z více tříd. */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "K výše uvedenému bude vygenerován následující graf:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Bloky (tj. uzly) v uvedeném grafu mají následující význam:\n"
+ "<ul>\n"
+ "<li>Šedě vyplněný obdélník reprezentuje strukturu nebo třídu, "
+ "pro kterou byl graf generován.\n"
+ "<li>Obdélník s černým obrysem označuje dokumentovanou "
+ "strukturu nebo třídu.\n"
+ "<li>Obdélník s šedým obrysem označuje nedokumentovanou "
+ "strukturu nebo třídu.\n"
+ "<li>Obdélník s červeným obrysem označuje dokumentovanou "
+ "strukturu nebo třídu, pro kterou\n"
+ "nejsou zobrazeny všechny vztahy dědičnosti nebo obsažení. "
+ "Graf je ořezán v případě, kdy jej\n"
+ "není možné umístit do vymezeného prostoru.\n"
+ "</ul>\n"
+ "Šipky (tj. hrany grafu) mají následující význam:\n"
+ "<ul>\n"
+ "<li>Tmavě modrá šipka se používá pro označení vztahu veřejné "
+ "dědičnosti (public) mezi dvěma třídami.\n"
+ "<li>Tmavě zelená šipka označuje vztah chráněné dědičnosti "
+ "(protected).\n"
+ "<li>Tmavě červená šipka označuje vztah privátní dědičnosti "
+ "(private).\n"
+ "<li>Purpurová šipka kreslená čárkovaně se používá v případě, "
+ "kdy je třída obsažena v jiné třídě,\n"
+ "nebo kdy je používána jinou třídou. Je označena identifikátorem "
+ "jedné nebo více proměných, přes které\n"
+ "je třída nebo struktura zpřístupněna.\n"
+ "<li>Žlutá šipka kreslená čárkovaně vyjadřuje vztah mezi instancí šablony "
+ "a šablonou třídy, na základě které byla\n"
+ "instance šablony vytvořena. V popisu šipky jsou uvedeny příslušné"
+ " parametry šablony.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "vysvětlivky";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Seznam testů";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Vlastnosti";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentace k vlastnosti";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ return "Třídy";
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return QCString("Balík ") + name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Seznam balíků";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Zde naleznete seznam balíků se stručným popisem "
+ "(pokud byl uveden):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Balíky";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Hodnota:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Chyba";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Seznam chyb";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6-20010422
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1250";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Rejstřík";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tříd" : "tříd"));
+ result += singular ? "a" : "y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Soubor" : "soubor"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Prostor" : "prostor"));
+ if (!singular) result+="y";
+ result+=" jmen";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Skupin" : "skupin"));
+ result += singular ? "a" : "y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stránk" : "stránk"));
+ result += singular ? "a" : "y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Člen" : "člen"));
+ if (!singular)
+ result += "y";
+ return result;
+ }
+
+ /*! ??? Jak to prelozit? Bylo by dobre, kdyby se ozval nekdo,
+ * kdo to pouziva.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auto" : "auto"));
+ result += (singular) ? "r" : "ři";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Odkazuje se na";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementuje "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementováno v "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Obsah";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Seznam zastaralých prvků";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Události";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentace událostí";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Typy v balíku";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkce v balíku";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statické funkce v balíku";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributy balíku";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statické atributy balíku";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Vše";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Tato funkce volá...";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Výsledky vyhledávání";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Lituji. Vašemu dotazu neodpovídá žádný dokument.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Nalezen jediný dokument, který vyhovuje vašemu dotazu.";
+ }
+ else
+ {
+ return "Nalezeno <b>$num</b> dokumentů, které vyhovují vašemu "
+ "dotazu. Nejlépe odpovídající dokumenty jsou zobrazeny "
+ "jako první.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Nalezená slova:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return QCString("Zdrojový soubor ") + filename;
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarchie adresářů"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentace k adresářům"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Adresáře"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ {
+ return "Následující hierarchie adresářů je zhruba, "
+ "ale ne úplně, řazena podle abecedy:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result = "Reference k adresáři ";
+ result += dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Adresář" : "adresář"));
+ if ( ! singular)
+ result += "e";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Jde o přetíženou (overloaded) metodu, "
+ "která má usnadnit používání. Od výše uvedené metody se liší "
+ "pouze jinak zadávanými argumenty.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCallerGraph()
+ {
+ return "Tuto funkci volají...";
+ }
+
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ {
+ return "Dokumentace výčtových hodnot";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentace členských funkcí/podprogramů"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Seznam datových typů"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Datová pole"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Datové typy se stručnými popisy:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+
+ QCString result="Následuje seznam všech ";
+ if (!extractAll)
+ {
+ result+="dokumentovaných ";
+ }
+ result+="složek datových typů";
+ result+=" s odkazy na ";
+ if (!extractAll)
+ {
+ result+="dokumentaci datové struktury pro každou složku:";
+ }
+ else
+ {
+ result+="příslušné datové typy:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Rejstřík datových typů"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentace k datovým typům"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkce/podprogramy"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Dokumentace funkce/podprogramu"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datové typy"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Seznam modulů"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Následuje seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="modulů se stručnými popisy:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result("Dokumentace ");
+ if (isTemplate) result += "šablony ";
+ switch(compType)
+ {
+ case ClassDef::Class: result += "třídy "; break;
+ case ClassDef::Struct: result += "typu "; break;
+ case ClassDef::Union: result += "unie "; break;
+ case ClassDef::Interface: result += "rozhraní "; break;
+ case ClassDef::Protocol: result += "protokolu "; break;
+ case ClassDef::Category: result += "kategorie "; break;
+ case ClassDef::Exception: result += "výjimky "; break;
+ default: break;
+ }
+ result += clName;
+ return result;
+
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Dokumentace modulu ";
+ result += namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Části modulu"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Následuje seznam všech ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="částí modulů s odkazy ";
+ if (extractAll)
+ {
+ result+="na dokumentaci modulu pro danou část:";
+ }
+ else
+ {
+ result+="na moduly, ke kterým část patří:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Rejstřík modulů"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentace ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="k tomuto modulu"; break;
+ case ClassDef::Struct: result+="k tomuto typu"; break;
+ case ClassDef::Union: result+="k této unii"; break;
+ case ClassDef::Interface: result+="k tomuto rozhraní"; break;
+ case ClassDef::Protocol: result+="k tomuto protokolu"; break;
+ case ClassDef::Category: result+="k této kategorii"; break;
+ case ClassDef::Exception: result+="k této výjimce"; break;
+ default: break;
+ }
+ result+=" byla vygenerována z ";
+ if (single) result+="následujícího souboru:";
+ else result+="následujících souborů:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Typ" : "typ"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Podprogram" : "podprogram"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Omezení typů (Type Constraints)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relace " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Načítám...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globální prostor jmen";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Vyhledávám...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nic se nenašlo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Soubor v "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Vkládá (include) soubor z "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "po","út","st","čt","pá","so","ne" };
+ static const char *months[] = { "led","úno","bře","dub","kvě","čer","čec","srp","zář","říj","lis","pro" };
+ QCString sdate;
+ sdate.sprintf("%s %d. %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d.%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Odkazy na literaturu"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Graf závislosti na adresářích pro ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "úroveň detailů"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametry šablon"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "a "+number+" další(ch)..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumentace pro tento výčet byla generována z ";
+ if (single)
+ result += "následujícího souboru:";
+ else
+ result += "následujících souborů:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return "Reference k výčtu "+QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" dědí se z "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Další zděděné členy"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "povolit" : "zakázat";
+ return opt + " synchronizaci panelů";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Deklarováno v kategorii @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Rozšiřuje třídu @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Metody třídy";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Metody instance";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Dokumentace metody";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Návrhové schéma";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Exportovaná rozhraní"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Začleněné služby"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Konstantní skupiny"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result="Konstantní skupiny z ";
+ result += namespaceName;
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result="Popis služby ";
+ result += sName;
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result="Popis singletonu ";
+ result += sName;
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result="Dokumentace k této službě byla generována ";
+ if (single) result+="z následujícího souboru:";
+ else result+="z následujících souborů:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result="Dokumentace k tomuto singletonu byla generována ";
+ if (single) result+="z následujícího souboru:";
+ else result+="z následujících souborů:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif // TRANSLATOR_CZ_H
diff --git a/src/translator_de.h b/src/translator_de.h
new file mode 100644
index 0000000..d936bf1
--- /dev/null
+++ b/src/translator_de.h
@@ -0,0 +1,2045 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The translation into German was provided by
+ * Jens Seidel (jensseidel at users.sf.net)
+ * based on work from
+ * Jens Breitenstein (Jens.Breitenstein at tlc.de)
+ */
+
+// Updates:
+// --------
+// RK (who are you?)
+// - Update for "new since 1.1.3" version
+//
+// 2001/03/23 Jens Seidel (jensseidel at users.sourceforge.net)
+// - fixed typos
+// - changed trPageDocumentation() "Seitenbeschreibung" to
+// "Zusätzliche Informationen"
+// - removed old trGeneratedFrom()
+// - changed "/*!" to "/*" (documentation is inherited from translator_en.h
+// (INHERIT_DOCS = YES), there's no need to make changes twice)
+// - Update for "new since 1.2.4" version
+//
+// 2001/04/17 Jens Seidel (jensseidel at users.sourceforge.net)
+// - fixed typos ("Vererbunsbeziehung", "geschützter")
+// - use umlauts instead of html code ("ä",...)
+// this makes it easier to read and fixes three problems (two in
+// \code segment)
+//
+// 2001/04/23 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Update for "new since 1.2.6-20010422" version
+//
+// 2001/05/06 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Update for "new since 1.2.7" version
+// - Removed implementation of latexBabelPackage(), trVerbatimText(),
+// trFiles(), added latexLanguageSupportCommand().
+//
+// 2001/05/25 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Update for "new since 1.2.7-20010524" version:
+// removed trAuthors(), trAuthor(), added trAuthor(bool, bool)
+//
+// 2001/07/24 Jens Seidel (jensseidel at users.sourceforge.net)
+// - trClassDocumentation() updated as in the English translator.
+//
+// 2001/11/30 Oliver Brandt (o.brandt at tu-bs.de) and
+// Jens Seidel (jensseidel at users.sourceforge.net)
+// - trReferences() implemented.
+// - trCompoundReference(), trLegendDocs() updated
+// - Removed some TODO's
+//
+// 2001/02/13 Oliver Brandt (o.brandt at tu-bs.de)
+// - Updated for "new since 1.2.13" version
+// - Removed some TODO's
+//
+// 2002/07/08 Oliver Brandt (o.brandt at tu-bs.de)
+// - Updated for "new since 1.2.16" version
+//
+// 2002/11/25 Jens Seidel (jensseidel at users.sourceforge.net)
+// - sync with english version 1.3
+// - TranslatorGerman doesn't inherit from TranslatorEnglish anymore,
+// so I changed "/* " back to "/*! " as in the English file
+// - use ngerman instead of german package in LaTeX
+// - changed "Datenelemente" to "Methoden" in
+// tr{,Static}{Public,Protected,Private}Members
+//
+// 2003/04/28 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.3" version
+// - translated Java package to Paket
+//
+// 2003/09/11 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.3.1" version
+//
+// 2003/09/24 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated a few strings which changed in CVS revision 1.22
+// ("compound" vs. "class")
+//
+// 2004/08/01 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.3.8" version
+//
+// 2004/09/19 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.3.9" version
+//
+// 2004/09/25 Jens Seidel (jensseidel at users.sourceforge.net)
+// - changed "Typendefinitionen" to "Typdefinitionen" in
+// trFileMembersDescription() and trTypedefs()
+// - added a dash after (file, ...) names and in front of description
+// - changed "Eigenschaften" to "Propertys" (yeah, not ..."ies")
+//
+// 2005/03/20 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.4.1" version
+//
+// 2005/04/09 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Changed Todo list translation as suggested in
+// http://bugzilla.gnome.org/show_bug.cgi?id=172818
+//
+// 2005/05/09 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.4.3" version (removed unused methods)
+//
+// 2006/06/12 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.4.6" version
+//
+// 2008/02/04 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.5.4" version
+//
+// 2009/01/09 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Resynced the trLegendDocs() method
+//
+// 2010/03/17 Jens Seidel (jensseidel at users.sourceforge.net)
+// - Updated for "new since 1.6.0" version
+// - Resynced the trLegendDocs() method (added closing HTML tags)
+// - Changed file encoding to utf-8, adapted idLanguageCharset()
+// - New German orthography (ngerman) is now default in LaTeX
+//
+// 2012/04/11 Peter Grotrian
+// - Updated for "new since 1.8.0" version
+// - Some small corrections
+//
+// Todo:
+// - see FIXME
+
+#ifndef TRANSLATOR_DE_H
+#define TRANSLATOR_DE_H
+
+class TranslatorGerman : public TranslatorAdapter_1_8_4
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "german"; }
+
+ /*! Used to get the LaTeX command(s) for the language support. This method
+ * was designed for languages which do wish to use a babel package.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[ngerman]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Verwandte Funktionen"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Es handelt sich hierbei nicht um Elementfunktionen.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Ausführliche Beschreibung"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentation der benutzerdefinierten Datentypen"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentation der Aufzählungstypen"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentation der Elementfunktionen"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ { /* No difference if "OPTIMIZE_OUTPUT_FOR_C" is set! */
+ return "Dokumentation der Datenelemente";
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Mehr ..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Aufstellung aller Elemente"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Elementverzeichnis"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Vollständige Aufstellung aller Elemente für "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return " einschließlich aller geerbten Elemente."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automatisch erzeugt von Doxygen";
+ if (s) result+=(QCString)" für "+s;
+ result+=" aus dem Quellcode.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum-Bezeichner"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum-Wert"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "Definiert in"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Module"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klassenhierarchie"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datenstrukturen";
+ }
+ else
+ {
+ return "Auflistung der Klassen";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Auflistung der Dateien"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datenstruktur-Elemente";
+ }
+ else
+ {
+ return "Klassen-Elemente";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ /* No difference if "OPTIMIZE_OUTPUT_FOR_C" is set! */
+ { return "Datei-Elemente"; }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Zusätzliche Informationen"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Beispiele"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Suchen"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Die Liste der Ableitungen ist -mit Einschränkungen- "
+ "alphabetisch sortiert:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Hier folgt die Aufzählung aller ";
+ if (!extractAll) result+="dokumentierten ";
+ result+="Dateien mit einer Kurzbeschreibung:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Hier folgt die Aufzählung aller Datenstrukturen "
+ "mit einer Kurzbeschreibung:";
+ }
+ else
+ {
+ return "Hier folgt die Aufzählung aller Klassen, Strukturen, "
+ "Varianten und Schnittstellen mit einer Kurzbeschreibung:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Hier folgt die Aufzählung aller ";
+ if (!extractAll)
+ {
+ result+="dokumentierten ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="Strukturen und Varianten";
+ }
+ else
+ {
+ result+="Klassenelemente";
+ }
+ result+=" mit Verweisen auf ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="die Dokumentation zu jedem Element:";
+ }
+ else
+ {
+ result+="die Klassendokumentation zu jedem Element:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="die zugehörigen Elemente:";
+ }
+ else
+ {
+ result+="die zugehörigen Klassen:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Hier folgt die Aufzählung aller ";
+ if (!extractAll) result+="dokumentierten ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="Funktionen, Variablen, Makros, Aufzählungen und Typdefinitionen";
+ }
+ else
+ {
+ result+="Dateielemente";
+ }
+ result+=" mit Verweisen auf ";
+ if (extractAll)
+ result+="die Dokumentation zu jedem Element:";
+ else
+ result+="die zugehörigen Dateien:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Hier folgt eine Liste mit allen Beispielen:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Hier folgt eine Liste mit zusammengehörigen Themengebieten:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Hier folgt die Aufzählung aller Module:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modul-Verzeichnis"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarchie-Verzeichnis"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ return "Datenstruktur-Verzeichnis";
+ else
+ return "Klassen-Verzeichnis";
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Datei-Verzeichnis"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modul-Dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datenstruktur-Dokumentation";
+ }
+ else
+ {
+ return "Klassen-Dokumentation";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Datei-Dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentation der Beispiele"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Zusätzliche Informationen"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Nachschlagewerk"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makrodefinitionen"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typdefinitionen"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Aufzählungen"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funktionen"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variablen"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Aufzählungswerte"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Makro-Dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentation der benutzerdefinierten Typen"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentation der Aufzählungstypen"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentation der Funktionen"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variablen-Dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datenstrukturen";
+ }
+ else
+ {
+ return "Klassen";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Erzeugt am "+date;
+ if (projName) result+=(QCString)" für "+projName;
+ result+=(QCString)" von";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Klassendiagramm für "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Nur für den internen Gebrauch."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Warnung"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Version"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Datum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Rückgabe"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Siehe auch"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parameter"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Ausnahmebehandlung"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Erzeugt von"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Liste aller Namensbereiche"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Liste aller ";
+ if (!extractAll) result+="dokumentierten ";
+ result+="Namensbereiche mit Kurzbeschreibung:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Freundbeziehungen"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Freundbeziehungen und Funktionsdokumentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName+" ";
+ if (isTemplate) result+="Template-";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Klassen"; break;
+ case ClassDef::Struct: result+="Struktur"; break;
+ case ClassDef::Union: result+="Varianten"; break;
+ case ClassDef::Interface: result+="Schnittstellen"; break;
+ case ClassDef::Protocol: result+="Protokoll"; break;
+ case ClassDef::Category: result+="Kategorie"; break;
+ case ClassDef::Exception: result+="Ausnahmen"; break;
+ default: break;
+ }
+ result+="referenz";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+="-Dateireferenz";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+="-Namensbereichsreferenz";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Öffentliche Methoden"; }
+
+ virtual QCString trPublicSlots()
+ { return "Öffentliche Slots"; }
+
+ virtual QCString trSignals()
+ { return "Signale"; }
+
+ virtual QCString trStaticPublicMembers()
+ { return "Öffentliche, statische Methoden"; }
+
+ virtual QCString trProtectedMembers()
+ { return "Geschützte Methoden"; }
+
+ virtual QCString trProtectedSlots()
+ { return "Geschützte Slots"; }
+
+ virtual QCString trStaticProtectedMembers()
+ { return "Geschützte, statische Methoden"; }
+
+ virtual QCString trPrivateMembers()
+ { return "Private Methoden"; }
+
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+
+ virtual QCString trStaticPrivateMembers()
+ { return "Private, statische Methoden"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" und ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Abgeleitet von "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Basisklasse für "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Erneute Implementation von "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Erneute Implementation in "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Elemente eines Namensbereiches"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Hier folgt die Aufzählung aller ";
+ if (!extractAll) result+="dokumentierten ";
+ result+="Namensbereichselemente mit Verweisen auf ";
+ if (extractAll)
+ result+="die Namensbereichsdokumentation für jedes Element:";
+ else
+ result+="die zugehörigen Dateien:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Verzeichnis der Namensbereiche"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Dokumentation der Namensbereiche"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namensbereiche"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // single is true implies a single file
+ QCString result=(QCString)"Die Dokumentation für diese";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Klasse"; break;
+ case ClassDef::Struct: result+=" Struktur"; break;
+ case ClassDef::Union: result+=" Variante"; break;
+ case ClassDef::Interface: result+=" Schnittstelle"; break;
+ case ClassDef::Protocol: result+="s Protokoll"; break;
+ case ClassDef::Category: result+=" Kategorie"; break;
+ case ClassDef::Exception: result+=" Ausnahme"; break;
+ default: break;
+ }
+ result+=" wurde erzeugt aufgrund der Datei";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Rückgabewerte"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hauptseite"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "S."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definiert in Zeile @0 der Datei @1.";
+ }
+
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definiert in Datei @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Veraltet";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Zusammengehörigkeiten von "+clName+":";
+ }
+
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Include-Abhängigkeitsdiagramm für "+fName+":";
+ }
+
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Beschreibung der Konstruktoren und Destruktoren";
+ }
+
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "gehe zum Quellcode dieser Datei";
+ }
+
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "gehe zur Dokumentation dieser Datei";
+ }
+
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Vorbedingung";
+ }
+
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Nachbedingung";
+ }
+
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariante";
+ }
+
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Initialisierung:";
+ }
+
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "code";
+ }
+
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafische Darstellung der Klassenhierarchie";
+ }
+
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "gehe zur grafischen Darstellung der Klassenhierarchie";
+ }
+
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "gehe zur textbasierten Darstellung der Klassenhierarchie";
+ }
+
+ virtual QCString trPageIndex()
+ {
+ return "Seitenindex";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ //RK: had to change here because of the new command \remark
+ virtual QCString trNote()
+ {
+ return "Zu beachten";
+ }
+
+ virtual QCString trPublicTypes()
+ {
+ return "Öffentliche Typen";
+ }
+
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datenfelder";
+ }
+ else
+ {
+ return "Öffentliche Attribute";
+ }
+ }
+
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statische öffentliche Attribute";
+ }
+
+ virtual QCString trProtectedTypes()
+ {
+ return "Geschützte Typen";
+ }
+
+ virtual QCString trProtectedAttribs()
+ {
+ return "Geschützte Attribute";
+ }
+
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statische, geschützte Attribute";
+ }
+
+ virtual QCString trPrivateTypes()
+ {
+ return "Private Typen";
+ }
+
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private Attribute";
+ }
+
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statische, private Attribute";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Noch zu erledigen";
+ }
+
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Ausstehende Aufgaben";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Wird benutzt von";
+ }
+
+ virtual QCString trRemarks()
+ {
+ return "Bemerkungen";
+ }
+
+ virtual QCString trAttention()
+ {
+ return "Achtung";
+ }
+
+ virtual QCString trInclByDepGraph()
+ {
+ return "Dieser Graph zeigt, welche Datei direkt oder "
+ "indirekt diese Datei enthält:";
+ }
+
+ virtual QCString trSince()
+ {
+ return "Seit";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Erklärung des Graphen";
+ }
+
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Diese Seite erklärt die Interpretation der von doxygen "
+ "erzeugten Graphen.<p>\n"
+ "Beispiel:\n"
+ "\\code\n"
+ "/*! Wegen Verkürzung unsichtbare Klasse */\n"
+ "class Invisible { };\n\n"
+ "/*! Klasse verkürzt dargestellt, Vererbungsbeziehung ist versteckt */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Nicht mit doxygen-Kommentaren dokumentierte Klasse */\n"
+ "class Undocumented { };\n\n"
+ "/*! Mithilfe öffentlicher Vererbung vererbte Klasse */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Eine Template-Klasse */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Mithilfe geschützter Vererbung vererbte Klasse */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Mithilfe privater Vererbung vererbte Klasse */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Von der Klasse Inherited benutzte Klasse */\n"
+ "class Used { };\n\n"
+ "/*! Superklasse, die von mehreren anderen Klassen erbt */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Dies liefert den folgenden Graphen:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "Die Rechtecke in obigem Graphen bedeuten:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Ein grau gefülltes Rechteck stellt die Struktur oder "
+ "Klasse dar, für die der Graph erzeugt wurde.</li>\n"
+ "<li>Ein Rechteck mit schwarzem Rahmen kennzeichnet eine dokumentierte "
+ "Struktur oder Klasse.</li>\n"
+ "<li>Ein Rechteck mit grauem Rahmen kennzeichnet eine undokumentierte "
+ "Struktur oder Klasse.</li>\n"
+ "<li>Ein Rechteck mit rotem Rahmen kennzeichnet eine dokumentierte "
+ "Struktur oder Klasse, für die nicht alle Vererbungs-/"
+ "Enthaltenseinsbeziehungen dargestellt werden. Ein Graph wird gekürzt, "
+ "wenn er nicht in die angegebenen Schranken passt.</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "Die Pfeile bedeuten:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Ein dunkelblauer Pfeil stellt eine öffentliche Vererbungsbeziehung "
+ "zwischen zwei Klassen dar.</li>\n"
+ "<li>Ein dunkelgrüner Pfeil stellt geschützte Vererbung dar.</li>\n"
+ "<li>Ein dunkelroter Pfeil stellt private Vererbung dar.</li>\n"
+ "<li>Ein gestrichelter violetter Pfeil bedeutet, dass eine Klasse in "
+ "einer anderen enthalten ist oder von einer anderen benutzt wird. Am "
+ "Pfeil stehen die Variable(n), mit deren Hilfe auf die Struktur oder "
+ "Klasse an der Pfeilspitze zugegriffen werden kann.</li>\n"
+ "<li>Ein gestrichelter gelber Pfeil kennzeichnet eine Verknüpfung "
+ "zwischen einer Template-Instanz und der Template-Klasse von welcher "
+ "es abstammt. Neben dem Pfeil sind die Template-Parameter aufgeführt.</li>\n"
+ "</ul>\n";
+ }
+
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Legende";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test-Liste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propertys";
+ }
+
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentation der Propertys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ return "Datenstrukturen";
+ else
+ return "Klassen";
+ }
+
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Paketliste";
+ }
+
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Hier folgen die Pakete mit einer Kurzbeschreibung (wenn verfügbar):";
+ }
+
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakete";
+ }
+
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Wert:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Fehler";
+ }
+
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Liste der bekannten Fehler";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6-20010422
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file. See translator_en.h for details. */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool, bool singular)
+ {
+ QCString result("Klasse");
+ if (!singular) result+="n";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool, bool singular)
+ {
+ QCString result("Datei");
+ if (!singular) result+="en";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool, bool singular)
+ {
+ QCString result("Namensbereich");
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool, bool singular)
+ {
+ QCString result("Gruppe");
+ if (!singular) result+="n";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool, bool singular)
+ {
+ QCString result("Seite");
+ if (!singular) result+="n";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool, bool singular)
+ {
+ QCString result("Element");
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global")); // FIXME
+ if (!singular) result+="";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7-20010524
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages.
+ */
+ virtual QCString trAuthor(bool, bool singular)
+ {
+ QCString result("Autor");
+ if (!singular) result+="en";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Benutzt";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementiert " + trWriteList(numEntries) + ".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementiert in " + trWriteList(numEntries) + ".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Inhaltsverzeichnis";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Veraltete Elemente";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Ereignisse";
+ }
+
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Ereignisdokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Pakettypen";
+ }
+
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Paketfunktionen";
+ }
+
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statische Paketfunktionen";
+ }
+
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Paketattribute";
+ }
+
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statische Paketattribute";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alle";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Hier ist ein Graph, der zeigt, was diese Funktion aufruft:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Suchergebnisse";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Es wurden keine Dokumente zu Ihrer Suchanfrage gefunden.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Es wurde <b>1</b> Dokument zu Ihrer Suchanfrage gefunden.";
+ }
+ else
+ {
+ return "Es wurden <b>$num</b> Dokumente zu Ihrer Suchanfrage "
+ "gefunden. Die besten Treffer werden zuerst angezeigt.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Treffer:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Quellcode";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Verzeichnishierarchie"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Verzeichnisdokumentation"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Verzeichnisse"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Diese Verzeichnishierarchie ist -mit Einschränkungen- "
+ "alphabetisch sortiert:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+="-Verzeichnisreferenz"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool, bool singular)
+ {
+ QCString result("Verzeichnis");
+ if (!singular) result+="se";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Dies ist eine überladene Methode, die der Bequemlichkeit "
+ "wegen bereitgestellt wird. Sie unterscheidet sich von der "
+ "obigen Funktion nur in den Argumenten die sie unterstützt.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentation der Aufzählungswerte"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Elementfunktionen/Unterroutinen-Dokumentation"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Datentyp-Liste"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Datenfelder"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Hier folgen die Datentypen mit Kurzbeschreibungen:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Hier folgt eine Liste aller ";
+ if (!extractAll)
+ {
+ result+="dokumentierten ";
+ }
+ result+="Datentypelemente";
+ result+=" mit Links ";
+ if (!extractAll)
+ {
+ result+="zur Datenstruktur-Dokumentation für jedes Element";
+ }
+ else
+ {
+ result+="zu den Datentypen, zu denen sie gehören:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Datentyp-Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Datentyp-Dokumentation"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funktionen/Unterroutinen"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funktionen/Unterroutinen-Dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datentypen"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modulliste"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Hier folgt eine Liste aller ";
+ if (!extractAll) result+="dokumentierten ";
+ result+="Module mit ihren Kurzbeschreibungen:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ result += "-";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Modul"; break;
+ case ClassDef::Struct: result+="Typ"; break;
+ case ClassDef::Union: result+="Union"; break;
+ case ClassDef::Interface: result+="Interface"; break;
+ case ClassDef::Protocol: result+="Protokoll"; break;
+ case ClassDef::Category: result+="Kategorie"; break;
+ case ClassDef::Exception: result+="Ausnahmen"; break;
+ default: break;
+ }
+ if (isTemplate) result+="-Template";
+ result+="-Referenz";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+="-Modul-Referenz";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Modul-Elemente"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Hier folgt eine Liste aller ";
+ if (!extractAll) result+="dokumentierten ";
+ result+="Modulelemente mit Links ";
+ if (extractAll)
+ {
+ result+="zur Moduldokumentation für jedes Element:";
+ }
+ else
+ {
+ result+="zu den Modulen, zu denen sie gehören:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modul-Index"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool /*first_capital*/, bool singular)
+ {
+ QCString result("Modul");
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Die Dokumentation für ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="dieses Modul"; break;
+ case ClassDef::Struct: result+="diesen Typ"; break;
+ case ClassDef::Union: result+="diese Union"; break;
+ case ClassDef::Interface: result+="dieses Interface"; break;
+ case ClassDef::Protocol: result+="dieses Protokoll"; break;
+ case ClassDef::Category: result+="diese Kategorie"; break;
+ case ClassDef::Exception: result+="diese Ausnahme"; break;
+ default: break;
+ }
+ if (single)
+ result+=" wurde aus der folgenden Datei erzeugt:";
+ else
+ result+=" wurde aus den folgenden Dateien erzeugt:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool /*first_capital*/, bool singular)
+ {
+ QCString result("Typ");
+ if (!singular) result+="en";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool /*first_capital*/, bool singular)
+ {
+ QCString result("Unterprogramm");
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Type Constraints";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Bezug " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Lade ...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globaler Namensbereich";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Suche ...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Keine Treffer";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Datei in "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Include-Dateien in "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Mon","Die","Mit","Don","Fre","Sam","Son" };
+ static const char *months[] = { "Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Literaturverzeichnis"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Diagramm der Verzeichnisabhängigkeiten für ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "Detailebene"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Template-Parameter"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "und "+number+" mehr ..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Die Dokumentation für diesen enum wurde aus ";
+ if (single)
+ result += "der folgenden Datei";
+ else
+ result += "den folgenden Dateien";
+ result+=" generiert:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum-Referenz"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" geerbt von "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Weitere Geerbte Elemente"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button thatappears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "einzuschalten" : "auszuschalten";
+ return "Klicken um Panelsynchronisation "+opt;
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Bestandteil der Kategorie @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Erweitert Klasse @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Klassenmethoden";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Instanzmethoden";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Methodendokumentation";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Übersicht";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_dk.h b/src/translator_dk.h
new file mode 100644
index 0000000..74b07f4
--- /dev/null
+++ b/src/translator_dk.h
@@ -0,0 +1,1785 @@
+/*-*- c-basic-offset: 2; tab-width: 8 -*-*/
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+ /*! @file
+ * @brief Danish translation
+ */
+
+/*
+ * Danish translation by
+ * Erik Søe Sørensen <eriksoe at daimi.au.dk>
+ *
+ * First version (not complete) for Doxygen 1.2.7
+ * Extended and revised for Doxygen 1.3
+ * Extended and revised for Doxygen 1.3.4
+ * Extended and revised for Doxygen 1.3.8
+ */
+
+/* Translator's notes:
+
+ Oversættelseskonventioner:
+ (Konventioner for konventioner:
+ '?' angiver oversættelser, jeg har været i tvivl om
+ '??' angiver tvivlsomme oversættelser
+ '..?' angiver ord, der endnu ikke er fundet en oversættelse til
+ '(do.)' angiver ord, der med vilje ikke er oversat, idet jeg selv
+ overvejende bruger det engelske udtryk
+ '(-> _)' angiver ord, der er fundet en oversættelse til, men som jeg
+ vægrer mig ved at oversætte.
+ 'KLID:_' angiver ord, hvor jeg med overlæg har rettet mig efter
+ KLID.dk's oversættelsesguide (enig eller ej).
+ )
+ bug -> 'kendt fejl'
+ class -> klasse
+ compound -> 'sammensat type'
+ constructor -> konstruktør ?
+ destructor -> destruktør ?
+ directory -> KLID:katalog (kunne også være 'bibliotek','mappe','folder')
+ event -> begivenhed ?
+ exception (-> undtagelse ?)
+ friend ..?
+ interface -> grænseflade ?
+ member -> medlem (TODO)
+ namespace -> (do.)
+ overloaded -> KLID:overdefineret
+ private -> privat
+ property -> egenskab?
+ protected -> beskyttet ??
+ public -> offentlig
+ reference(vb) -> "indeholde referencer til" (?)
+ slot ..?
+ source code -> kildekode
+ struct -> datastruktur
+ template (-> skabelon ?)
+ typedef -> typedefinition (?)
+ todo -> (do.)
+ union ..?
+
+ Specielle forbindelser:
+ 'Inheritance diagram' -> Stamtræ (selvom Nedarvningsdiagram også gik an)
+
+
+ -----
+
+ (Konstruktivt) input modtages med glæde!
+ -- Erik Søe Sørensen <eriksoe at daimi.au.dk>
+
+
+ links -> (links.)
+ -- Poul-Erik Hansen
+
+ */
+
+#ifndef TRANSLATOR_DK_H
+#define TRANSLATOR_DK_H
+
+class TranslatorDanish : public TranslatorAdapter_1_8_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "danish"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return
+ "\\usepackage[danish]{babel}\n"
+ "\\usepackage[T1]{fontenc}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Relaterede funktioner"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Bemærk at disse ikke er medlems-funktioner.)"; }
+
+ /*! header that is put before the detailed description of files,
+ * classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detaljeret beskrivelse"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentation af medlems-typedefinitioner"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentation af medlems-enumerationer"; }
+ // medlems-enumerationer -> 'indeholdte enumerationer'
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentation af medlemsfunktioner"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Felt-dokumentation";
+ } else {
+ return "Dokumentation af feltvariable";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Mere..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Liste over alle medlemmer"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Liste over medlemmer"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Dette er den komplette liste over medlemmer i "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", inklusive alle nedarvede medlemmer."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automatisk genereret af Doxygen";
+ if (s) result+=(QCString)" for "+s;
+ result+=" ud fra kildekoden.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enumerationsnavn"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enumerationsværdi"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "defineret i"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduler"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klassehierarki"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Datastrukturer";
+ } else {
+ return "Oversigt over sammensatte typer";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Filoversigt"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Data-felter";
+ } else {
+ return "Felter i sammensatte typer";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Globale symboler";
+ } else {
+ return "Placering i filer"; // Fil-medlemmer"; //TODO
+ //"Globale definitioner" ?
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Relaterede sider"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Eksempler"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Søg"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Denne nedarvningsliste er sorteret næsten - "
+ "men ikke nødvendigvis helt - alfabetisk:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterede ";
+ result+="filer med korte beskrivelser:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Her er datastrukturerne med korte beskrivelser:";
+ } else {
+ return "Her er klasserne, datastrukturerne, "
+ "unionerne og grænsefladerne med korte beskrivelser:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) {
+ result+="dokumenterede ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="felter i datastrukturer og unioner";
+ } else {
+ result+="klassemedlemmer";
+ }
+ result+=" med links til ";
+ if (!extractAll) {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="datastruktur/unions-dokumentationen for hvert felt:";
+ } else {
+ result+="klassedokumentationen for hvert medlem:";
+ }
+ } else {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="de datastrukturer/unioner, de hører til:";
+ } else {
+ result+="de klasser, de hører til:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterede ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ result+="funktioner, variable, #defines, enumerationer "
+ "og typedefinitioner";
+ } else {
+ result+="fil-medlemmer";
+ }
+ result+=", med links til ";
+ if (extractAll)
+ result+="de filer, de tilhører:";
+ else
+ result+="deres dokumentation:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Her er en liste over alle eksempler:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Her er en liste over alle relaterede dokumentationssider:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Her er en liste over alle moduler:"; }
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modul-indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarkisk indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Indeks over datastrukturer";
+ } else {
+ return "Indeks over sammensatte typer";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Fil-indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modul-dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Datastruktur-documentation";
+ } else {
+ return "Klasse-dokumentation";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Fil-dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Eksempel-dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Side-dokumentation"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referencemanual"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "#Defines"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefinitioner"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerationer"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funktioner"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variable"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumerationsværdier"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "#Define-dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentation af typedefinitioner"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentation af enumerations-typer"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentation af enumerations-værdier"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funktions-dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variabel-dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Datastrukturer";
+ } else {
+ return "Sammensatte typer";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Genereret "+date;
+ if (projName) result+=(QCString)" for "+projName;
+ result+=(QCString)" af";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Stamtræ for "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Kun til intern brug."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Advarsel"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Version"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Dato"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Returnerer"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Se også"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametre"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Undtagelser"; } // "Exceptions"
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Genereret af"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Oversigt over namespaces"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterede ";
+ result+="namespaces med korte beskrivelser:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentation af friends og af relaterede funktioner"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName+" ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Klasse-"; break;
+ case ClassDef::Struct: result+=" Datastruktur-"; break;
+ case ClassDef::Union: result+=" Union-"; break;
+ case ClassDef::Interface: result+=" Grænseflade-"; break;
+ case ClassDef::Protocol: result+=" Protokol-"; break;
+ case ClassDef::Category: result+=" Kategori-"; break; // " Category-"
+ case ClassDef::Exception: result+=" Undtagelse-"; break; // " Exception"
+ default: break;
+ }
+ if (isTemplate) result+="skabelon-"; // "template-"
+ result+="reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" filreference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" namespace-reference";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Offentlige metoder"; }
+ virtual QCString trPublicSlots()
+ { return "Offentlige slots"; }
+ virtual QCString trSignals()
+ { return "Signaler"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiske, offentlige metoder"; }
+ virtual QCString trProtectedMembers()
+ { return "Beskyttede metoder"; }
+ virtual QCString trProtectedSlots()
+ { return "Beskyttede slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiske, beskyttede metoder"; }
+ virtual QCString trPrivateMembers()
+ { return "Private metoder"; }
+ virtual QCString trPrivateSlots()
+ { return "Private slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiske, private metoder"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++) {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) { // not the last entry, so we need a separator
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" og ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Nedarver "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Nedarvet af "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Overskriver metode fra "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementeret i "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Namespace-medlemmer"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterede ";
+ result+="namespace-medlemmer med links til ";
+ if (extractAll)
+ result+="namespace-dokumentationen for hvert medlem:";
+ else
+ result+="det namespace, de hører til:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespace-indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Namespace-dokumentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentationen for denne ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klasse"; break;
+ case ClassDef::Struct: result+="datastruktur"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="grænseflade"; break;
+ case ClassDef::Protocol: result+="protokol"; break; // "protocol"
+ case ClassDef::Category: result+="kategori"; break; // "category"
+ case ClassDef::Exception: result+="undtagelse"; break; // "exception"
+ default: break;
+ }
+ result+=" blev genereret ud fra fil";
+ if (single) result+="en:"; else result+="erne:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Returværdier"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hovedside"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Defineret på linje @0 i filen @1.";
+ }
+
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Defineret i filen @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Frarådes - fortidslevn"; // ?? - What is the context?
+ // "Ugleset" :)
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Samarbejdsdiagram for "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Inklusions-afhængighedsgraf for "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentation af konstruktører og destruktører";
+ // "Constructor & Destructor dokumentation";
+ }
+
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ { return "Hop til denne fils kildekode."; }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ { return "Hop til denne fils dokumentation."; }
+
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ { return "Forudsætninger (precondition)"; }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ { return "Resultat (postcondition)"; }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ { return "Invariant"; }
+
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ { return "Startværdi:"; }
+
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ { return "kildekode"; }
+ virtual QCString trGraphicalHierarchy()
+ { return "Grafisk klassehierarki"; }
+ virtual QCString trGotoGraphicalHierarchy()
+ { return "Hop til det grafiske klassehierarki"; }
+ virtual QCString trGotoTextualHierarchy()
+ { return "Hop til det tekstuelle klassehierarki"; }
+ virtual QCString trPageIndex()
+ { return "Sideindeks"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ { return "Note"; }
+ virtual QCString trPublicTypes()
+ { return "Offentlige typer"; }
+
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Datafelter";
+ } else {
+ return "Offentlige attributter";
+ }
+ }
+
+ virtual QCString trStaticPublicAttribs()
+ { return "Statiske, offentlige attributter"; }
+ virtual QCString trProtectedTypes()
+ { return "Beskyttede typer"; }
+ virtual QCString trProtectedAttribs()
+ { return "Beskyttede attributter"; }
+ virtual QCString trStaticProtectedAttribs()
+ { return "Statiske, beskyttede attributter"; }
+ virtual QCString trPrivateTypes()
+ { return "Private typer"; }
+ virtual QCString trPrivateAttribs()
+ { return "Private attributter"; }
+ virtual QCString trStaticPrivateAttribs()
+ { return "Statiske, private attributter"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Todo";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Todo-liste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Refereret til af";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Bemærkninger";
+ }
+ virtual QCString trAttention()
+ {
+ return "OBS";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return
+ "Denne graf viser, hvilke filer der direkte eller "
+ "indirekte inkluderer denne fil:";
+ }
+ virtual QCString trSince()
+ {
+ return "Siden";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Graf-forklaring";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs() //TODO
+ {
+ return
+ "Denne side forklarer, hvordan man skal fortolke de grafer, "
+ "der genereres af doxygen.<p>\n"
+ "Tag følgende eksempel:\n"
+ "\\code\n"
+ "/*! Klasse der er usynlig pg.a. beskæring */\n"
+ "class Invisible { };\n\n"
+ "/*! Beskåret klasse: nedarvningsrelation er skjult */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klasse der ikke er dokumenteret med doxygen-kommentarer */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klasse der nedarves fra offentligt */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! En template-klasse */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasse der nedarves fra beskyttet */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klasse der nedarves fra privat */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klasse der bruges af Inherited-klassen */\n"
+ "class Used { };\n\n"
+ "/*! Klasse der nedarver en masse andre klasser */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Hvis \\c MAX_DOT_GRAPH_HEIGHT i konfigurationsfilen "
+ "er sat til 240, vil dette resultere i følgende graf:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "De forskellige slags kasser i ovenstående graf har følgende "
+ "betydninger:\n"
+ "<ul>\n"
+ "<li>%En udfyldt sort kasse repræsenterer den datastruktur eller "
+ "klasse, grafen er genereret for.\n"
+ "<li>%En kasse med sort kant betegner en dokumenteret datastruktur "
+ " eller klasse.\n"
+ "<li>%En kasse med grå kant betegner en udokumenteret datastruktur "
+ " eller klasse.\n"
+ "<li>%En kasse med rød kant betegner en dokumenteret datastruktur "
+ " eller klasse, for hvilken ikke alle "
+ "nedarvnings- og indeholdelses-relationer er vist. "
+ "%Grafer beskæres, hvis de fylder mere end de specificerede dimensioner.\n "
+ "</ul>\n"
+ "Pilene har følgende betydninger:\n"
+ "<ul>\n"
+ "<li>%En mørkeblå pil viser en offentlig nedarvningsrelation "
+ "mellem to klasser.\n"
+ "<li>%En mørkegrøn pil viser en beskyttet nedarvningsrelation.\n"
+ "<li>%En mørkerød pil viser en privat nedarvningsrelation.\n"
+ "<li>%En lilla, stiplet pil bruges, når en klasse er indeholdt i "
+ "eller benyttes af en anden klasse. "
+ "Ved pilen står navnet på den eller de variable, gennem hvilke(n) "
+ "den klasse, pilen peger på, er tilgængelig.\n"
+ "<li>%En gul, stiplet pil viser forholdet mellem en template-instans "
+ "og den template-klasse, den er instantieret fra."
+ "Ved pilen står template-parametrene brugt ved instantieringen.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "forklaring til graf";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testliste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Egenskaber";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Egenskabsdokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Datastrukturer";
+ } else {
+ return "Klasser";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pakke "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakkeoversigt";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return
+ "Her er en liste over pakkerne, med korte beskrivelser "
+ "(hvor en sådan findes):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakker";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Værdi:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Kendte fejl";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Liste over kendte fejl";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ * (used table extract:)
+ * <pre>
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * ANSI_CHARSET 0 (x00) 1252
+ * </pre>
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "klasse", "r");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "fil", "er");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "namespace", "s");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "gruppe", "r");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "side", "r");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "medlem", "mer");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "global", "e");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "forfatter", "e");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Indeholder referencer til";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementerer "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementeret i "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Indholdsfortegnelse";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Liste over fortidslevn, hvis brug frarådes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Begivenheder";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Begivenhedsdokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /* Java: Entities with package scope... */
+ virtual QCString trPackageTypes()
+ { return "Typer med pakke-scope"; }
+ virtual QCString trPackageMembers()
+ { return "Metoder med pakke-scope"; }
+ virtual QCString trStaticPackageMembers()
+ { return "Statiske metoder med pakke-scope"; }
+ virtual QCString trPackageAttribs()
+ { return "Attributter med pakke-scope"; }
+ virtual QCString trStaticPackageAttribs()
+ { return "Statiske attributter med pakke-scope"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alle";
+ }
+
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Her er kald-grafen for denne funktion:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Søgeresultater";
+ }
+
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0) {
+ return "Beklager - ingen dokumenter passede til din forespørgsel.";
+ } else if (numDocuments==1) {
+ return "Fandt <b>1</b> dokument, der passer til din forespørgsel.";
+ } else {
+ return
+ "Fandt <b>$num</b> dokumenter, der passer til din forespørgsel. "
+ "De, der passer bedst, vises først.";
+ }
+ }
+
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Fundne ord:"; //translation?
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for
+ * file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Kildefilen " + filename;
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Katalogstruktur"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Katalog-dokumentation"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Kataloger"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Denne katalogstruktur er sorteret næsten - "
+ "men ikke nødvendigvis helt - alfabetisk:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Indhold af kataloget "; result+=dirName; return result;}
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "katalog", "er");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Dette er en overdefineret medlemsfunktion, "
+ "defineret af bekvemmelighedshensyn. "
+ "Den adskiller sig kun fra den ovenstående funktion i, "
+ "hvilke argumenter den tager.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Her er kalder-grafen for denne funktion:";
+ }
+
+ // None translated yet PEH 2010-11-27
+ // Subroutine
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Medlem Funktion/Subroutine Dokumentation"; } // "Member Function/Subroutine Documentation"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ /*
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerator-dokumentation"; } //TODO?
+*/
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Data Type Liste"; } // "Data Types List"
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Data felter"; } // "Data Fields"
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Her er de datatyper med kort beskrivelse:"; } // "Here are the data types with brief descriptions:"
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Her er en liste af alle "; // "Here is a list of all "
+ if (!extractAll)
+ {
+ result+="dokumenteret "; // "documented "
+ }
+ result+="datatype medlemmer"; // "data types members"
+ result+=" med links til "; // " with links to "
+ if (!extractAll)
+ {
+ result+="data strukturer dokumenteret for hver medlem"; // "the data structure documentation for each member"
+ }
+ else
+ {
+ result+="de datatyper som de tilhører:"; // "the data types they belong to:"
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Datatype indeks"; } // "Data Type Index"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Datatype dokumentation"; } // "Data Type Documentation"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funktioner/Subroutiner"; } // "Functions/Subroutines"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funktion/Subroutine dokumentation"; } // "Function/Subroutine Documentation"
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datatyper"; } // "Data Types"
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modulliste"; } // "Modules List"
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle "; // "Here is a list of all "
+ if (!extractAll) result+="dokumenteret "; // "documented "
+ result+="moduler med kort beskrivelse:"; // "modules with brief descriptions:"
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Modul"; break; // " Module"
+ case ClassDef::Struct: result+=" Type"; break; // " Type"
+ case ClassDef::Union: result+=" Union"; break; // " Union"
+ case ClassDef::Interface: result+=" Grænseflade"; break; // " Interface"
+ case ClassDef::Protocol: result+=" Protocol"; break; // " Protocol"
+ case ClassDef::Category: result+=" Kategori"; break; // " Category"
+ case ClassDef::Exception: result+=" Undtagelse"; break; // " Exception"
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Modulreference"; // " Module Reference"
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Modulmedlemmer"; } // "Module Members"
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Her er en list over alle "; // "Here is a list of all "
+ if (!extractAll) result+="Dokumentet "; // "documented "
+ result+="modulmemlemmer med link til "; // "module members with links to "
+ if (extractAll)
+ {
+ result+="dokumentation for hvert model medlem:"; // "the module documentation for each member:"
+ }
+ else
+ {
+ result+="moduler de tilhøre:"; // "the modules they belong to:"
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modulindekser"; } // "Modules Index"
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul")); // "Module" : "module"));
+ if (!singular) result+="er"; // "s";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modul"; break; // "module"
+ case ClassDef::Struct: result+="type"; break; // "type"
+ case ClassDef::Union: result+="union"; break; // "union"
+ case ClassDef::Interface: result+="grænseflade"; break; // "interface"
+ case ClassDef::Protocol: result+="protokol"; break; // "protocol"
+ case ClassDef::Category: result+="kategori"; break; // "category"
+ case ClassDef::Exception: result+="undtagelse"; break; // "exception"
+ default: break;
+ }
+ result+=" var lavet udfra følgende file"; // " was generated from the following file"
+ if (single) result+=":"; else result+="r:"; // ":" / "s:"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Type" : "type")); // "Type" : "type"
+ if (!singular) result+="r"; // "s"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram")); // "Subprogram" : "subprogram"
+ if (!singular) result+="er"; // "s"
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "typebegrænsninger"; // "Type Constraints"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relation"; // " Relation"
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Indlæser..."; // "Loading..."
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globalt Namespace"; // "Global Namespace"
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Søger..."; // "Searching..."
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Ingen fund"; // "No Matches"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"File i "+name; // "File in "
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inkluderer file i "+name; // "Includes file in "
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Man","Tir","Ons","Tor","Fre","Lør","Søn" }; // { "Mon","Tue","Wed","Thu","Fri","Sat","Sun" };
+ static const char *months[] = { "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec" }; // { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCiteReferences()
+ {
+ return "Bibliografiske referencer";
+ }
+
+ virtual QCString trCopyright()
+ {
+ return "Copyright";
+ }
+
+ virtual QCString trDirDepGraph(const char *name)
+ {
+ return QCString("Afhængighedsgraf for katalog ")+name+":";
+ }
+
+
+/*---------- For internal use: ----------------------------------------*/
+ protected:
+ /*! For easy flexible-noun implementation.
+ * \internal
+ */
+ QCString createNoun(bool first_capital, bool singular,
+ const char* base, const char* plurSuffix)
+ {
+ QCString result(base);
+ if (first_capital) result.at(0) = toupper(result.at(0));
+ if (!singular) result+=plurSuffix;
+ return result;
+ }
+};
+
+#endif
diff --git a/src/translator_en.h b/src/translator_en.h
new file mode 100644
index 0000000..5937ed3
--- /dev/null
+++ b/src/translator_en.h
@@ -0,0 +1,1999 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_EN_H
+#define TRANSLATOR_EN_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorEnglish : public Translator
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "english"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Related Functions"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Note that these are not member functions.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detailed Description"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Member Typedef Documentation"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Member Enumeration Documentation"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Member Function Documentation"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Field Documentation";
+ }
+ else
+ {
+ return "Member Data Documentation";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "More..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "List of all members"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Member List"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "This is the complete list of members for "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", including all inherited members."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generated automatically by Doxygen";
+ if (s) result+=(QCString)" for "+s;
+ result+=" from the source code.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum name"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum value"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "defined in"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modules"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Class Hierarchy"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structures";
+ }
+ else
+ {
+ return "Class List";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "File List"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Fields";
+ }
+ else
+ {
+ return "Class Members";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globals";
+ }
+ else
+ {
+ return "File Members";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Related Pages"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Examples"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Search"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "This inheritance list is sorted roughly, "
+ "but not completely, alphabetically:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="files with brief descriptions:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Here are the data structures with brief descriptions:";
+ }
+ else
+ {
+ return "Here are the classes, structs, "
+ "unions and interfaces with brief descriptions:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll)
+ {
+ result+="documented ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct and union fields";
+ }
+ else
+ {
+ result+="class members";
+ }
+ result+=" with links to ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="the struct/union documentation for each field:";
+ }
+ else
+ {
+ result+="the class documentation for each member:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="the structures/unions they belong to:";
+ }
+ else
+ {
+ result+="the classes they belong to:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="functions, variables, defines, enums, and typedefs";
+ }
+ else
+ {
+ result+="file members";
+ }
+ result+=" with links to ";
+ if (extractAll)
+ result+="the files they belong to:";
+ else
+ result+="the documentation:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Here is a list of all examples:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Here is a list of all related documentation pages:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Here is a list of all modules:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Documentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Module Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarchical Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structure Index";
+ }
+ else
+ {
+ return "Class Index";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "File Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Module Documentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structure Documentation";
+ }
+ else
+ {
+ return "Class Documentation";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "File Documentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Example Documentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Page Documentation"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Reference Manual"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Macros"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefs"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerations"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Functions"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variables"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumerator"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Macro Definition Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumeration Type Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Function Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variable Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structures";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generated on "+date;
+ if (projName) result+=(QCString)" for "+projName;
+ result+=(QCString)" by";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Inheritance diagram for "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "For internal use only."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Warning"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Version"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Date"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Returns"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "See also"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parameters"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Exceptions"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generated by"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Namespace List"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="namespaces with brief descriptions:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Friends And Related Function Documentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Class"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" File Reference";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Reference";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Public Member Functions"; }
+ virtual QCString trPublicSlots()
+ { return "Public Slots"; }
+ virtual QCString trSignals()
+ { return "Signals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Static Public Member Functions"; }
+ virtual QCString trProtectedMembers()
+ { return "Protected Member Functions"; }
+ virtual QCString trProtectedSlots()
+ { return "Protected Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Static Protected Member Functions"; }
+ virtual QCString trPrivateMembers()
+ { return "Private Member Functions"; }
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Static Private Member Functions"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", and ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Inherits "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Inherited by "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplemented from "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplemented in "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Namespace Members"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="namespace members with links to ";
+ if (extractAll)
+ result+="the namespace documentation for each member:";
+ else
+ result+="the namespaces they belong to:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespace Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Namespace Documentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // single is true implies a single file
+ QCString result=(QCString)"The documentation for this ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="class"; break;
+ case ClassDef::Struct: result+="struct"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" was generated from the following file";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Return values"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Main Page"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definition at line @0 of file @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definition in file @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Deprecated";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Collaboration diagram for "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Include dependency graph for "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Constructor & Destructor Documentation";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Go to the source code of this file.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Go to the documentation of this file.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondition";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondition";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Initial value:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "code";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Graphical Class Hierarchy";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Go to the graphical class hierarchy";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Go to the textual class hierarchy";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Page Index";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Note";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Public Types";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Fields";
+ }
+ else
+ {
+ return "Public Attributes";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Static Public Attributes";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Protected Types";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Protected Attributes";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Static Protected Attributes";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Private Types";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private Attributes";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Static Private Attributes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Todo";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Todo List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenced by";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Remarks";
+ }
+ virtual QCString trAttention()
+ {
+ return "Attention";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "This graph shows which files directly or "
+ "indirectly include this file:";
+ }
+ virtual QCString trSince()
+ {
+ return "Since";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Graph Legend";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "This page explains how to interpret the graphs that are generated "
+ "by doxygen.<p>\n"
+ "Consider the following example:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "This will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%A filled gray box represents the struct or class for which the "
+ "graph is generated.</li>\n"
+ "<li>%A box with a black border denotes a documented struct or class.</li>\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.</li>\n"
+ "<li>%A box with a red border denotes a documented struct or class for"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries.</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "The arrows have the following meaning:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.</li>\n"
+ "<li>%A dark green arrow is used for protected inheritance.</li>\n"
+ "<li>%A dark red arrow is used for private inheritance.</li>\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible.</li>\n"
+ "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "the template class it was instantiated from. The arrow is labeled with "
+ "the template parameters of the instance.</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legend";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Properties";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Property Documentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structures";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Package List";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Here are the packages with brief descriptions (if available):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Packages";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Value:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Bug List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Class" : "class"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "File" : "file"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Page" : "page"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Member" : "member"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Author" : "author"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "References";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implements "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implemented in "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Table of Contents";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Deprecated List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Events";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Event Documentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Package Types";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Package Functions";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Static Package Functions";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Package Attributes";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Static Package Attributes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "All";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Here is the call graph for this function:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Search Results";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Sorry, no documents matching your query.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Found <b>1</b> document matching your query.";
+ }
+ else
+ {
+ return "Found <b>$num</b> documents matching your query. "
+ "Showing best matches first.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Matches:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Source File";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Directory Hierarchy"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Directory Documentation"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directories"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "This directory hierarchy is sorted roughly, "
+ "but not completely, alphabetically:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Directory Reference"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Director" : "director"));
+ if (singular) result+="y"; else result+="ies";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "This is an overloaded member function, "
+ "provided for convenience. It differs from the above "
+ "function only in what argument(s) it accepts.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Here is the caller graph for this function:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerator Documentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Member Function/Subroutine Documentation"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Data Types List"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Data Fields"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Here are the data types with brief descriptions:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll)
+ {
+ result+="documented ";
+ }
+ result+="data types members";
+ result+=" with links to ";
+ if (!extractAll)
+ {
+ result+="the data structure documentation for each member";
+ }
+ else
+ {
+ result+="the data types they belong to:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Data Type Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Data Type Documentation"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Functions/Subroutines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Function/Subroutine Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Data Types"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modules List"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="modules with brief descriptions:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Module"; break;
+ case ClassDef::Struct: result+=" Type"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Reference";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Module Reference";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Module Members"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Here is a list of all ";
+ if (!extractAll) result+="documented ";
+ result+="module members with links to ";
+ if (extractAll)
+ {
+ result+="the module documentation for each member:";
+ }
+ else
+ {
+ result+="the modules they belong to:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modules Index"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="module"; break;
+ case ClassDef::Struct: result+="type"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" was generated from the following file";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Type" : "type"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Type Constraints";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relation";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Loading...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Global Namespace";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Searching...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "No Matches";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"File in "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Includes file in "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Mon","Tue","Wed","Thu","Fri","Sat","Sun" };
+ static const char *months[] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliography"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Directory dependency graph for ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detail level"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Template Parameters"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "and "+number+" more..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "The documentation for this enum was generated from the following file";
+ if (!single) result += "s";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum Reference"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" inherited from "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Additional Inherited Members"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "enable" : "disable";
+ return "click to "+opt+" panel synchronisation";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Provided by category @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Extends class @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Class Methods";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Instance Methods";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Method Documentation";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Design Overview";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Exported Interfaces"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Included Services"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Constant Groups"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Constant Group Reference";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Service Reference";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Singleton Reference";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this service "
+ "was generated from the following file";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this singleton "
+ "was generated from the following file";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_eo.h b/src/translator_eo.h
new file mode 100644
index 0000000..e1513cb
--- /dev/null
+++ b/src/translator_eo.h
@@ -0,0 +1,1948 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+ /* Tradukita kaj ĝisdatigata de Ander Martinez. */
+
+#ifndef TRANSLATOR_EO_H
+#define TRANSLATOR_EO_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorEsperanto : public TranslatorAdapter_1_8_4
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "esperanto"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[esperanto]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Rilataj Funkcioj"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Atentu ke tiuj ĉi ne estas membraj funkcioj.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detala Priskribo"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentado de la Membraj Tipodifinoj"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentado de la Membraj Enumeracioj"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentado de la Membraj Funkcioj"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Kampa Dokumentado";
+ }
+ else
+ {
+ return "Dokumentado de la Membraj Datumoj";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Pli..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Listo de ĉiuj membroj"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Membra Listo"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Tiu ĉi estas la kompleta membraro de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", inkluzive ĉiujn hereditajn membrojn."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generita aŭtomate de Doxygen";
+ if (s) result+=(QCString)" por "+s;
+ result+=" el la fontkodo.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum nomo"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum valoro"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "difinita en"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduloj"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klasa Hierarkio"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumstruktoroj";
+ }
+ else
+ {
+ return "Klasaro";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Dosieraro"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumkampoj";
+ }
+ else
+ {
+ return "Klasaj membroj";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Mallokalaĵoj";
+ }
+ else
+ {
+ return "Dosieraj Membroj";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Rilataj Paĝoj"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Ekzemploj"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Serĉi"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Tiu ĉi heredada listo estas plimalpli, "
+ "sed ne tute, ordigita alfabete:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+ result+="dosieroj kun mallongaj priskriboj:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Jen datumstrukturoj kun mallongaj priskriboj:";
+ }
+ else
+ {
+ return "Jen la klasoj, strukturoj, kunigoj kaj interfacoj "
+ "kun mallongaj priskriboj:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll)
+ {
+ result+="dokumentitaj ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="strukturaj kaj kunigaj kampoj";
+ }
+ else
+ {
+ result+="klasaj membroj";
+ }
+ result+=" kun ligiloj al ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="la struktura/kuniga dokumentado por ĉiu kampo:";
+ }
+ else
+ {
+ result+="la klasa dokumentado por ĉiu membro:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="la strukturoj/kunigoj al kiuj ili apartenas:";
+ }
+ else
+ {
+ result+="la klasoj al kiuj ili apartenas:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcioj, variabloj, difinoj, enumeracioj kaj tipodifinoj";
+ }
+ else
+ {
+ result+="dosieraj membroj";
+ }
+ result+=" kun ligiloj al ";
+ if (extractAll)
+ result+="la dosieroj al kiuj ili apartenas:";
+ else
+ result+="la dokumentado:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Jen listo de ĉiuj la ekzemploj:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Jen listo de ĉiuj rilataj dokumentadaj paĝoj:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Jen listo de ĉiuj la moduloj:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentado"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modula Indekso"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarkia Indekso"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumstruktura Indekso";
+ }
+ else
+ {
+ return "Klasa Indekso";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Dosiera Indekso"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modula Dokumentado"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumstruktura Dokumentado";
+ }
+ else
+ {
+ return "Klasa Dokumentado";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dosiera Dokumentado"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Ekzempla Dokumentado"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Paĝa Dokumentado"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referenca Manlibro"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Difinoj"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Tipdifinoj"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumeracioj"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkcioj"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variabloj"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumeraciilo"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Difina Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Tipdifina Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumeracitipa Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funkcia Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variabla Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumstrukturoj";
+ }
+ else
+ {
+ return "Klasoj";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generita la "+date;
+ if (projName) result+=(QCString)" por "+projName;
+ result+=(QCString)" de";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Heredada diagramo por "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Nur por ena uzado."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Averto"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versio"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Dato"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Liveras"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Vido ankaŭ"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametroj"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Esceptoj"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generita de"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Nomspacaro"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+ result+="nomspacoj kun mallongaj priskriboj:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Amikoj"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentado pri amikoj kaj rilatitaj funkcioj"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referenco de la ";
+ if (isTemplate) result+=" ŝablono de la ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klaso "; break;
+ case ClassDef::Struct: result+="strukturo "; break;
+ case ClassDef::Union: result+="kunigo "; break;
+ case ClassDef::Interface: result+="interfaco "; break;
+ case ClassDef::Protocol: result+="protokolo "; break;
+ case ClassDef::Category: result+="kategorio "; break;
+ case ClassDef::Exception: result+="escepto "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" Dosiera referenco";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Nomspaca referenco";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Publikaj Membraj Funkcioj"; }
+ virtual QCString trPublicSlots()
+ { return "Pubikaj Ingoj"; }
+ virtual QCString trSignals()
+ { return "Signaloj"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statikaj Publikaj Membraj Funkcioj"; }
+ virtual QCString trProtectedMembers()
+ { return "Protektitaj Membraj Funkcioj"; }
+ virtual QCString trProtectedSlots()
+ { return "Protektitaj Ingoj"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statikaj Protektitaj Membraj Funkcioj"; }
+ virtual QCString trPrivateMembers()
+ { return "Privataj Membraj Funkcioj"; }
+ virtual QCString trPrivateSlots()
+ { return "Privataj Ingoj"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statikaj Privataj Membraj Funkcioj"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", kaj ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Heredas de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Heredita de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Rerealigita el "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Rerealigita en "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Nomspacaj Membroj"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+ result+="nomspacaj membroj kun ligiloj al ";
+ if (extractAll)
+ result+="la nomspaca dokumentado de ĉiu membro:";
+ else
+ result+="la nomspacoj al kiuj ili apartenas:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Nomspaca Indekso"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Nomspaca Dokumentado"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Nomspacoj"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // single is true implies a single file
+ QCString result=(QCString)"La dokumentado por tiu ĉi ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klaso"; break;
+ case ClassDef::Struct: result+="strukturo"; break;
+ case ClassDef::Union: result+="kunigo"; break;
+ case ClassDef::Interface: result+="interfaco"; break;
+ case ClassDef::Protocol: result+="protokolo"; break;
+ case ClassDef::Category: result+="kategorio"; break;
+ case ClassDef::Exception: result+="escepto"; break;
+ default: break;
+ }
+ result+=" generitas el la ";
+ if (single) result+="sekva dosiero:";
+ else result+="sekvaj dosieroj:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Liveraĵoj"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Ĉefa Paĝo"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Difinita sur la lineo @0 de la dosiero @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Difinita en la dosiero @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Evitinda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Kunlaborada diagramo por "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Inkluzivaĵa dependeca diagramo por "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruila kaj Detruila Dokumentado";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Iri al la fontkodo de tiu ĉi dosiero.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Iri al la dokumentado de tiu ĉi dosiero.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Antaŭkondiĉo";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postkondiĉo";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Malvariaĵo";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Komenca valoro:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "kodo";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafika Klasa Hierarkio";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Iri al la grafika klasa hierarkio";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Iri al la teksta klasa hierarkio";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Paĝa Indekso";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Noto";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Publikaj Tipoj";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumkampoj";
+ }
+ else
+ {
+ return "Publikaj Atributoj";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statikaj Publikaj Atributoj";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Protektitaj Tipoj";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Protektitaj Atributoj";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statikaj Protektitaj Atributoj";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privataj Tipoj";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privataj Atributoj";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statikaj Privataj Atributoj";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Farendaĵo";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Farendaĵaro";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referencita de";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Rimarkoj";
+ }
+ virtual QCString trAttention()
+ {
+ return "Atentu";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Tiu ĉi diagramo montras kiuj dosieroj rekte aŭ malrekte "
+ "inkluzivas tiun ĉi dosieron:";
+ }
+ virtual QCString trSince()
+ {
+ return "De";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Diagrama Klarigeto";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Tiu ĉi paĝo klarigas kiel interpreti la diagramojn generitajn "
+ "de doxygen.<p>\n"
+ "Konsideru la sekvan ekzemplon:\n"
+ "\\code\n"
+ "/*! Nevidebla klaso pro trunkado */\n"
+ "class Invisible { };\n\n"
+ "/*! Trunkita klaso, hereda rilato kaŝiĝas */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klaso ne dokumentita per komentoj de doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klaso de kiu herediĝas per publika heredado */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Ŝablona klaso */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klaso de kiu herediĝas per protektita heredado */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klaso de kiu herediĝas per privata heredado */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klaso uzata de la klaso Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Supra klaso kiu heredas de kelkaj aliaj klasoj */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Tio ĉi liveros la sekvan diagramon:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "La skatoloj de la supra diagramo havas la sekvajn signifojn:\n"
+ "<ul>\n"
+ "<li>%Plene griza skatolo reprezentas la strukturon aŭ klason "
+ "kies diagramo generiĝis.\n"
+ "<li>%Skatolo kun nigra bordero montras dokumentitan strukturon aŭ klason.\n"
+ "<li>%Skatolo kun griza bordero montras nedokumentitan strukturon aŭ klason.\n"
+ "<li>%Skatolo kun ruĝa bordero montras dokumentitan strukturon aŭ klason por "
+ "kiu ne ĉiuj heredadoj/enhavoj montriĝas. %Diagramo estas trunkota "
+ "se ĝi ne adaptiĝas en la donitajn limojn.\n"
+ "</ul>\n"
+ "La sagoj havas la sekvajn signifojn:\n"
+ "<ul>\n"
+ "<li>%Malhelblua sago uzatas por montri publika heredado "
+ "inter du klasoj.\n"
+ "<li>%Malhelverda sago uzatas por protektita heredado.\n"
+ "<li>%Malhelruĝa sago uzatas por privata heredado.\n"
+ "<li>%Purpura streka sago uzatas se klaso enhavatas aŭ uzatas "
+ "de alia klaso. La sago estas etikedatas kun la variablo(j) "
+ "tra kiu la montrita klaso aŭ strukturo estas alirebla.\n"
+ "<li>%Flava streka sago montras rilato inter ŝablona apero kaj "
+ "la ŝablona klaso el kiu ĝi realigitas. La sago etikeditas kun "
+ "la parametroj de la ŝablona apero.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "klarigeto";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Testo";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testa Listo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Atributoj";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Atributa Dokumentado";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datumstrukturoj";
+ }
+ else
+ {
+ return "Klasoj";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pakaĵo "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakaĵa Listo";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Jen listo de pakaĵoj kun mallongaj priskriboj (se ekzistas):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakaĵoj";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valoro:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Cimo";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Cima Listo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "1";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indekso";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klaso" : "klaso"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Dosiero" : "dosiero"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Nomspaco" : "nomspaco"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupo" : "grupo"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Paĝo" : "paĝo"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membro" : "membro"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Mallokalaĵo" : "mallokalaĵo"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Aŭtoro" : "aŭtoro"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referencoj";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Realigas "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Realigita en "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Enhava Tabelo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Evitindaĵa Listo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Eventoj";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Eventa Dokumentado";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Pakaĵaj Tipoj";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Pakaĵaj Funkcioj";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statikaj Pakaĵaj Funkcioj";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Pakaĵaj Atributoj";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statikaj Pakaĵaj Atributoj";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Ĉiuj";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Jen la vokdiagramo por tiu ĉi funkcio:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Serĉaj Rezultoj";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Pardonu, nenio dokumento kongruas vian peton.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Trafita <b>unu</b> dokumenton kongruantan vian peton.";
+ }
+ else
+ {
+ return "Trafitaj <b>$num</b> dokumentojn kongruantajn vian peton. "
+ "Montriĝos plej bonaj kongruoj unue.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Kongruoj:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Fonta Dosiero";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Dosieruja Hierarkio"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dosieruja Dokumentado"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Dosierujoj"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Tiu ĉi dosieruja hierarkio estas plimalpli, "
+ "sed ne tute, ordigita alfabete:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Dosieruja Referenco"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Dosierujo" : "dosierujo"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Tiu ĉi estas superŝarĝita membra funkcio, "
+ "donita por faciligo. Ĝi nur malsamas de la supra "
+ "funkcio nur pro la argumento(j) kiujn ili akceptas.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Jen la vokdiagramo por tiu ĉi funkcio:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumeraciila Dokumentado"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentado de Membraj Funkcioj/Subrutinoj"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Datumtipa Listo"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Datumkampoj"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Jen la datumtipoj kun mallongaj priskriboj:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll)
+ {
+ result+="dokumentitaj ";
+ }
+ result+="datumtipaj membroj";
+ result+=" kun ligiloj al ";
+ if (!extractAll)
+ {
+ result+="la datumstruktura dokumentado de ĉiu membro";
+ }
+ else
+ {
+ result+="la datumtipoj al kiuj ili apartenas:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Datumtipa Indekso"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Datumtipa Dokumentado"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcioj/Subrutinoj"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funkcia/Subrutina Dokumentado"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datumtipoj"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modula Listo"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+ result+="moduloj kun mallongaj priskriboj:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referenco de la ";
+ if (isTemplate) result+=" ŝablono de la ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modulo "; break;
+ case ClassDef::Struct: result+="tipo "; break;
+ case ClassDef::Union: result+="kunigo "; break;
+ case ClassDef::Interface: result+="interfaco "; break;
+ case ClassDef::Protocol: result+="protokolo "; break;
+ case ClassDef::Category: result+="kategorio "; break;
+ case ClassDef::Exception: result+="escepto "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Modula Referenco";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Modulaj Membroj"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Jen listo de ĉiuj ";
+ if (!extractAll) result+="dokumentitaj ";
+ result+="modulaj membroj kun ligiloj al la ";
+ if (extractAll)
+ {
+ result+="modula dokumentado de ĉiu membro:";
+ }
+ else
+ {
+ result+="moduloj al kiuj ili apartenas:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Indekso de Moduloj"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modulo" : "modulo"));
+ if (!singular) result+="j";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La dokumentado por tiu ĉi ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modulo"; break;
+ case ClassDef::Struct: result+="tipo"; break;
+ case ClassDef::Union: result+="kunigo"; break;
+ case ClassDef::Interface: result+="interfaco"; break;
+ case ClassDef::Protocol: result+="protokolo"; break;
+ case ClassDef::Category: result+="kategorio"; break;
+ case ClassDef::Exception: result+="escepto"; break;
+ default: break;
+ }
+ result+=" kreiĝis el la ";
+ if (single) result+="sekva dosiero:"; else result+="sekvaj dosieroj:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipo" : "tipo"));
+ if (!singular) result+="j";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogramo" : "subprogramo"));
+ if (!singular) result+="j";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Tipaj Limigoj";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Rilato";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Ŝarĝante...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Malloka Nomspaco";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Serĉante...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nenia kongruo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Dosiero en "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inkluzivas dosieron en "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "lundo","mardo","merkredo",
+ "ĵaŭdo","vendredo","sabato",
+ "dimanĉo" };
+
+ static const char *months[] = { "Januaro", "Februaro", "Marto",
+ "Aprilo", "Majo", "Junio",
+ "Julio", "Aŭgusto", "Septembro",
+ "Oktobro", "Novembro",
+ "Decembro"
+ };
+ QCString sdate;
+ sdate.sprintf("%s, %d-a de %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliografiaj Referencoj"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Kopirajto"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Dosieruja dependa diagramo por ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detala nivelo"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametroj de ŝablonoj"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "kaj "+number+" pli..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "La dokumentaro por tiu ĉi enum estis generita el la sekva dosiero";
+ if (!single) result += "s";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum Referenco"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" heredita el "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Kromaj Hereditaj Membroj"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "aktivigi" : "malaktivigi";
+ return "klaku por "+opt+" panelan sinkronigon";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Provizita de kategorio @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Etendi klason @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Klasaj Metodoj";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Aperaj Metodoj";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Dokumentaro de la Metodo";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Fasona Superrigardo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_es.h b/src/translator_es.h
new file mode 100644
index 0000000..ba6e823
--- /dev/null
+++ b/src/translator_es.h
@@ -0,0 +1,2063 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_ES_H
+#define TRANSLATOR_ES_H
+
+/*!
+ * translator_es.h modified by Lucas Cruz (7-julio-2000)
+ * Some notes:
+ * - It's posible that some sentences haven't got meaning because
+ * some words haven't got translate in spanish.
+ * Updated from 1.3.8 to 1.4.6 by Guillermo Ballester Valor (May-05-2006)
+ * Updated to 1.5.1 by Bartomeu Creus Navarro (22-enero-2007)
+ * Updated to 1.5.5 by Bartomeu Creus Navarro (5-febrero-2008)
+ * Updated to 1.5.8 by Bartomeu Creus Navarro (10-abril-2009)
+ * Updated to 1.6.3 by Bartomeu Creus Navarro (3-marzo-2010)
+ * Updated to 1.6.4 by Bartomeu Creus Navarro (26-mayo-2010) [(16-jun-2010) grabado en UTF-8]
+ * Updated to 1.8.0 by Bartomeu Creus Navarro (11-abril-2012)
+ * Updated to 1.8.2 by Bartomeu Creus Navarro (01-julio-2012)
+ * Updated to 1.8.4 by Bartomeu Creus Navarro (17-julio-2013)
+ */
+
+class TranslatorSpanish : public Translator
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "spanish"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[spanish]{babel}";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Funciones relacionadas"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Observar que estas no son funciones miembro.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Descripción detallada"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Documentación de los 'Typedef' miembros de la clase"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Documentación de las enumeraciones miembro de la clase"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Documentación de las funciones miembro"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentación de los campos";
+ }
+ else
+ {
+ return "Documentación de los datos miembro";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Más..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Lista de todos los miembros"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Lista de los miembros"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Lista completa de los miembros de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", incluyendo todos los heredados:"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generado automáticamente por Doxygen";
+ if (s) result+=(QCString)" para "+s;
+ result+=" del código fuente.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "nombre de la enumeración"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "valor enumerado"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definido en"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Módulos"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Jerarquía de la clase"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructura de datos";
+ }
+ else
+ {
+ return "Lista de clases";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Lista de archivos"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de datos";
+ }
+ else
+ {
+ return "Miembros de las clases";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globales";
+ }
+ else
+ {
+ return "Miembros de los ficheros";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Páginas relacionadas"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Ejemplos"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Buscar"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Esta lista de herencias esta ordenada "
+ "aproximadamente por orden alfabético:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Lista de todos los archivos ";
+ if (!extractAll) result+="documentados y ";
+ result+="con descripciones breves:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Lista de estructuras con una breve descripción:";
+ }
+ else
+ {
+ return "Lista de las clases, estructuras, "
+ "uniones e interfaces con una breve descripción:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Lista de todos los ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="campos de estructuras y uniones";
+ }
+ else
+ {
+ result+="campos de clases";
+ }
+ if (!extractAll)
+ {
+ result+=" documentados";
+ }
+ result+=" con enlaces a ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="la documentación de la estructura/unión para cada campo:";
+ }
+ else
+ {
+ result+="la documentación de la clase para cada miembro:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="las estructuras/uniones a que pertenecen:";
+ }
+ else
+ {
+ result+="las classes a que pertenecen:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Lista de ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="todas las funciones, variables, 'defines', enumeraciones y 'typedefs'";
+ }
+ else
+ {
+ result+="todos los mienbros de los ficheros";
+ }
+ if (!extractAll) result+=" documentados";
+ result+=" con enlaces ";
+ if (extractAll)
+ result+="a los ficheros a los que corresponden:";
+ else
+ result+="a la documentación:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Lista de todos los ejemplos:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Lista de toda la documentación relacionada:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Lista de todos los módulos:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Documentación"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Indice de módulos"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Indice jerárquico"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Índice de estructura de datos";
+ }
+ else
+ {
+ return "Índice de clases";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Indice de archivos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Documentación de módulos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentación de las estructuras de datos";
+ }
+ else
+ {
+ return "Documentación de las clases";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Documentación de archivos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Documentación de ejemplos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Documentación de páginas"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Manual de referencia"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "'defines'"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "'typedefs'"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumeraciones"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funciones"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variables"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Valores de enumeraciones"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Documentación de los 'defines'"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Documentación de los 'typedefs'"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Documentación de las enumeraciones"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Documentación de las funciones"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Documentación de las variables"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructuras de datos";
+ }
+ else
+ {
+ return "Clases";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generado el "+date;
+ if (projName) result+=(QCString)" para "+projName;
+ result+=(QCString)" por";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de herencias de "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Sólo para uso interno."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Atención"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versión"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Fecha"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Devuelve"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Ver también"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parámetros"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Excepciones"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generado por"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Lista de 'namespaces'"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Lista de ";
+ if (!extractAll) result+="toda la documentación de ";
+ result+="los 'namespaces', con una breve descripción:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Amigas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Documentación de las funciones relacionadas y clases amigas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referencia de";
+ if (isTemplate) result+=" la plantilla de";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" la Clase "; break;
+ case ClassDef::Struct: result+=" la Estructura "; break;
+ case ClassDef::Union: result+=" la Unión "; break;
+ case ClassDef::Interface: result+=" la Interfaz "; break;
+ case ClassDef::Protocol: result+="l Protocolo "; break;
+ case ClassDef::Category: result+=" la Categoria "; break;
+ case ClassDef::Exception: result+=" la Excepción "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result="Referencia del Archivo ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Referencia del Namespace ";
+ result+=namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Métodos públicos"; }
+
+ virtual QCString trPublicSlots()
+ { return "Slots públicos"; }
+
+ virtual QCString trSignals()
+ { return "Señales"; }
+
+ virtual QCString trStaticPublicMembers()
+ { return "Métodos públicos estáticos"; }
+
+ virtual QCString trProtectedMembers()
+ { return "Métodos protegidos"; }
+
+ virtual QCString trProtectedSlots()
+ { return "Slots protegidos"; }
+
+ virtual QCString trStaticProtectedMembers()
+ { return "Métodos protegidos estáticos"; }
+
+ virtual QCString trPrivateMembers()
+ { return "Métodos privados"; }
+
+ virtual QCString trPrivateSlots()
+ { return "Slots privados"; }
+
+ virtual QCString trStaticPrivateMembers()
+ { return "Métodos privados estáticos"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" y ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Herencias "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Heredado por "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementado de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementado en "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Miembros del Namespace "; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Lista de ";
+ if (!extractAll) result+="toda la documentación de ";
+ result+="los miembros del namespace con enlace a ";
+ if (extractAll)
+ result+="los namespace de cada miembro:";
+ else
+ result+="la documentación de los namespaces pertenecientes a:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Indice de namespaces"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Documentación de namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentación para est";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="a clase"; break;
+ case ClassDef::Struct: result+="a estructura"; break;
+ case ClassDef::Union: result+="a unión"; break;
+ case ClassDef::Interface: result+="e interfaz"; break;
+ case ClassDef::Protocol: result+="e protocolo"; break;
+ case ClassDef::Category: result+="a categoría"; break;
+ case ClassDef::Exception: result+="a excepción"; break;
+ default: break;
+ }
+ result+=" fue generada a partir de";
+ if (single) result+="l siguiente fichero:";
+ else result+=" los siguientes ficheros:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valores devueltos"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Página principal"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definición en la línea @0 del archivo @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definición en el archivo @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Obsoleto";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de colaboración para "+clName+":";
+ }
+
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Dependencia gráfica adjunta para "+fName+":";
+ }
+
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Documentación del constructor y destructor";
+ }
+
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Ir al código fuente de este archivo.";
+ }
+
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Ir a la documentación de este archivo.";
+ }
+
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondición";
+ }
+
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondición";
+ }
+
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariante";
+ }
+
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valor inicial:";
+ }
+
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "código";
+ }
+
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Representación gráfica de la clase";
+ }
+
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Ir a la representación gráfica de la jerarquía de la clase";
+ }
+
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Ir a la jerarquía textual de la clase";
+ }
+
+ virtual QCString trPageIndex()
+ {
+ return "Página indice";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Nota";
+ }
+
+ virtual QCString trPublicTypes()
+ {
+ return "Tipos públicos";
+ }
+
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de datos";
+ }
+ else
+ {
+ return "Atributos públicos";
+ }
+ }
+
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atributos públicos estáticos";
+ }
+
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipos protegidos";
+ }
+
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atributos protegidos";
+ }
+
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atributos protegidos estáticos";
+ }
+
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipos privados";
+ }
+
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atributos privados";
+ }
+
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atributos privados estáticos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Tareas pendientes";
+ }
+
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Lista de tareas pendientes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenciado por";
+ }
+
+ virtual QCString trRemarks()
+ {
+ return "Comentarios";
+ }
+
+ virtual QCString trAttention()
+ {
+ return "Atención";
+ }
+
+ virtual QCString trInclByDepGraph()
+ {
+ return "Gráfico de los archivos que directa o "
+ "indirectamente incluyen a este archivo:";
+ }
+
+ virtual QCString trSince()
+ {
+ return "Desde";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ QCString trLegendTitle()
+ {
+ return "Colores y flechas del Gráfico";
+ }
+
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Esta página explica como interpretar los gráficos que son generados "
+ "por doxygen.<p>\n"
+ "Considere el siguiente ejemplo:\n"
+ "\\code\n"
+ "/*! Clase invisible por truncamiento */\n"
+ "class Invisible { };\n\n"
+ "/*! Clase truncada, relación de herencia escondida */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Clase no documentada con comentarios de doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Clase que es heredera usando herencia publica */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Clase plantilla */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Clase que es heredera usando herencia protegida */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Clase que es heredera usando herencia privada */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Clase que es usada por la clase heredada */\n"
+ "class Used { };\n\n"
+ "/*! Super-Clase que hereda de varias otras clases */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Dará como resultado el siguiente gráfico:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "Las cajas en el gráfico arriba tienen el siguiente significado:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Una caja llena gris representa la estructura o clase para la cuál"
+ "se generó el gráfico.\n"
+ "<li>Una caja con borde negro señala una estructura o clase documentada.\n"
+ "<li>Una caja con borde griz señala una estructura o clase no documentada.\n"
+ "<li>una caja con borde rojo señala una estructura o clase documentada"
+ " de la cuál no toda las relaciones de jerarquía/contenido son "
+ "mostradas. El gráfico sera truncado si este no calza dentro de los "
+ "límites especificados."
+ "</ul>\n"
+ "<p>\n"
+ "Las flechas tienen el siguiente significado:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Una flecha azul oscuro es usada para visualizar una relación herencia publica entre dos clases.\n"
+ "<li>Una flecha verde oscuro es usada para herencia protegida.\n"
+ "<li>Una flecha rojo oscuro es usada para herencia privada.\n"
+ "<li>Una flecha segmentada púrpura se usa si la clase es contenida o "
+ "usada por otra clase. La flecha está etiquetada por la variable "
+ "con que se accede a la clase o estructura apuntada. \n"
+ "<li>Una flecha segmentada amarilla indica la relación entre una instancia template y la clase template de la que se ha instanciado."
+ " La flecha se etiqueta con los parámetros con que se llama al template.\n"
+ "</ul>\n";
+ }
+
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "significado de colores y flechas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Prueba";
+ }
+
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Lista de pruebas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propiedades";
+ }
+
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentación de propiedades";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estructuras de Datos";
+ }
+ else
+ {
+ return "Clases";
+ }
+ }
+
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paquetes "+name;
+ }
+
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista de Paquetes ";
+ }
+
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Aquí van los paquetes con una breve descripción (si etá disponible):";
+ }
+
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paquetes";
+ }
+
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valor:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista de bugs";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Índice";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Clase" : "clase"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Archivo" : "archivo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupo" : "grupo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Página" : "página"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Miembro" : "miembro"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Hace referencia a";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementado en "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Tabla de contenidos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista de obsoletos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Eventos";
+ }
+
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentación de los eventos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipos del 'package'";
+ }
+
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funciones del 'package'";
+ }
+
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funciones estáticas del 'package'";
+ }
+
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributos del 'package'";
+ }
+
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Atributos Estáticos del 'package'";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Todo";
+ }
+
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Gráfico de llamadas para esta función:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Resultados de la Búsqueda";
+ }
+
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Disculpe, no se encontraron documentos que coincidan con su búsqueda.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Se encontró <b>1</b> documento que coincide con su búsqueda.";
+ }
+ else
+ {
+ return "Se encontraron <b>$num</b> documentos que coinciden con su búsqueda. "
+ "Se muestran los mejores resultados primero.";
+ }
+ }
+
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Coincidencias:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Fichero Fuente " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Jerarquía de directorios"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentación de directorios"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directorios"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "La jeraquía de este directorio está ordenada"
+ " alfabéticamente, de manera aproximada:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result="Referencia del directorio ";
+ result+=dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Directorio" : "directorio"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Esta es una función miembro sobrecargada que se "
+ "suministra por conveniencia. Difiere de la anterior "
+ "función solamente en los argumentos que acepta.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Gráfico de llamadas a esta función:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentación de los valores de la enumeración"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+ // De parte de Bartomeu:
+ // No conozco el Fortran, salvo un par de ejercicios en la universidad
+ // hace muchos años. Por lo tanto, las traducciones son del inglés
+ // al español, no de un usuario de Fortran que puede que haya cosas que no
+ // traduzca o traduzca de otra forma. Que los usuarios de Fortran disculpen
+ // y espero se animen a mejorar mi traducción.
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documetación de miembros Function/Subroutine"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista de tipos de datos"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Etiquetas de datos"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Aquí están los tipos de datos con una breve descripción:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Aquí está una lista de todos ";
+ result+="los miembros de los tipos de datos ";
+ if (!extractAll)
+ {
+ result+="documentados ";
+ }
+ result+="con enlaces a ";
+ if (!extractAll)
+ {
+ result+="la documentación de la estructura de datos para cada miembro";
+ }
+ else
+ {
+ result+="los tipos de dato a que pertenece:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Índice de tipos de datos"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentación de tipos de datos"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funciones/Subprogramas"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentación de Funciones/Subprogramas"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipos de datos"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Lista de módulos"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Lista de todos los módulos ";
+ if (!extractAll) result+="documentados ";
+ result+="con una breve descripción:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referencia de";
+ if (isTemplate) result+=" la plantilla de";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="l módulo"; break;
+ case ClassDef::Struct: result+="l tipo"; break;
+ case ClassDef::Union: result+=" la unión"; break;
+ case ClassDef::Interface: result+=" la interfaz"; break;
+ case ClassDef::Protocol: result+="l protocolo"; break;
+ case ClassDef::Category: result+=" la categoría"; break;
+ case ClassDef::Exception: result+=" la excepción"; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Referencia módulo ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Miembros módulo"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Lista de todos los miembros del módulo ";
+ if (!extractAll) result+="documentados ";
+ result+="con enlaces ";
+ if (extractAll)
+ {
+ result+="a la documentación del módulo para cada uno:";
+ }
+ else
+ {
+ result+="al módulo al que pertenecen:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Índice de módulos"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Módulo" : "módulo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentación para est";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="e módulo"; break;
+ case ClassDef::Struct: result+="e tipo"; break;
+ case ClassDef::Union: result+="a unión"; break;
+ case ClassDef::Interface: result+="e interfaz"; break;
+ case ClassDef::Protocol: result+="e protocolo"; break;
+ case ClassDef::Category: result+="a categoría"; break;
+ case ClassDef::Exception: result+="a excepción"; break;
+ default: break;
+ }
+ result+=" fue generada de";
+ if (single) result+="l siguiente fichero:";
+ else result+=" los siguientes ficheros:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipo" : "tipo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprograma" : "subprograma"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Restriciones de tipo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" relación";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Cargando...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Buscando...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nada coincide";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Fichero en "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Incluye ficheros en "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Lunes","Martes","Miércoles","Jueves",
+ "Viernes","Sábado","Domingo" };
+ static const char *months[] = { "Enero","Febrero","Marzo","Abril",
+ "Mayo","Junio","Julio","Agosto",
+ "Septiembre","Octubre","Noviembre","Diciembre" };
+ QCString sdate;
+ sdate.sprintf("%s, %d de %s de %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Referencias bibliográficas"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Gráfico de dependencias de directorios para ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detalle nivel"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parámetros del template"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "y "+number+" más..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "La documentación para este enum ha sido generada a partir de";
+ if (single)
+ result += "l siguiente fichero:";
+ else
+ result += " los siguientes ficheros:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString("Referencia del enum ") + QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" heredados desde "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Otros miembros heredados"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "habilitar" : "deshabilitar";
+ return "click en "+opt+" sincronización";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Proporcionado por categoría @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Extiende la clase @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Métodos de la clase";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Métodos de instancia";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Método de documentación";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Diseño información general";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Interface exportada"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Servicios incluidos"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Grupos constantes"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" referencia de grupos constantes";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Referencia servicio";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" referencia Singleton";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La documentacion para este servicio "
+ "se ha generado desde ";
+ if (single) result+="el siguiente fichero:"; else result+="los siguientes ficheros:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La documentación para este singleton "
+ "se ha generado desde ";
+ if (single) result+="el siguiente fichero:"; else result+="los siguientes ficheros:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_fa.h b/src/translator_fa.h
new file mode 100644
index 0000000..7b6f9d7
--- /dev/null
+++ b/src/translator_fa.h
@@ -0,0 +1,1784 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ *
+ * Description : Doxygen Persian (Farsi) Translator
+ * Author : Ali Nadalizadeh < nadalizadeh at gmail dot com >
+ *
+ * ChangeLog :
+ * Thu 06 Jul 2006 11:54:09 PM IRDT <nadalizadeh at gmail dot com>
+ * >> First version of persian language support has been completed.
+ *
+ * Mon 04 Feb 2008 11:52:09 AM IRDT <nadalizadeh at gmail dot com>
+ * >> Obsolete methods removed. Translated more string(s) to persian. Upgraded to 1_5_4 adapter.
+ *
+ * Fri 04 Jun 2010 04:05:24 PM IRDT <nadalizadeh at gmail dot com>
+ * >> Implement missing new methods since 1.6.0.
+ * >> Add English to Persian digit convertor. (for date/time digits)
+ *
+ * Translation feedbacks are really appreciated.
+ */
+
+#ifndef TRANSLATOR_FA_H
+#define TRANSLATOR_FA_H
+
+#define HtmlRightToLeft QCString("<div dir=\"rtl\">")
+#define HtmlLeftToRight QCString("<div dir=\"ltr\">")
+#define HtmlDivEnd QCString("</div>")
+
+
+class TranslatorPersian : public TranslatorAdapter_1_7_5
+{
+ private:
+ /** Converts english digits of an input string to persian equivalents.
+ */
+ QCString convertDigitsToFarsi(QCString str)
+ {
+ QCString output;
+ const char * PersianDigits[] = { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };
+ for(unsigned i=0; i<str.length(); i++)
+ {
+ if (str.at(i) >= '0' && str.at(i) <= '9')
+ output += PersianDigits[ str.at(i) - '0' ];
+ else
+ output += str.at(i);
+ }
+
+ return output;
+ }
+
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in Persian using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "persian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The Persian LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "توابع مربوط"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(لازم به ذکر است که اينها توابع عضو نيستند)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "توضيحات جزئی"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "مستندات تعریف گونه ها"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "های عضو Enumeration مستندات"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "توضيحات توابع عضو"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Field مستندات";
+ }
+ else
+ {
+ return "مستندات متغيير های عضو";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "بيشتر..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "ليست تمام اعضاء "; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "ليست اعضاء"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "اين ليستی کامل از همه اعضای "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return "شامل همه ی اعضای به ارث برده شده می باشد."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="تولید شده توسط نرم افزار دی اکسیژن ";
+ if (s) result+=(QCString)" برای "+s;
+ result+=" از کد برنامه ";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum نام"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum مقدار"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "تعریف شده در"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modules"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "سلسله مراتب کلاس ها"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "ساختار های داده ";
+ }
+ else
+ {
+ return "ليست کلاس ها ";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "ليست فايل ها"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "فضاهای داده ها";
+ }
+ else
+ {
+ return "اعضاء کلاس ها";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globals";
+ }
+ else
+ {
+ return "اعضاء پرونده";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "صفحات مربوط"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "مثال ها"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "جستجو"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "ليست و سلسله مراتب درختی کلاس ها به صورت مرتب شده :";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="ليست همه ي پرونده های ";
+ if (!extractAll) result+="(مستند شده) ";
+ result+=" :";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "ليست ساختارهای داده به همراه توضيحی کوتاه :";
+ }
+ else
+ {
+ return "ليست کلاس ها ، ساختارهای داده و ... به همراه توضيحات مختصر راجع به آنها :";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result=" در ذيل ليست ";
+ if (!extractAll)
+ {
+ result+="آن اعضايي که مستند شده اند ";
+ }
+ else
+ {
+ result+="همه ی اعضاء ";
+ }
+ result+=" به همراه ارتباطشان با ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="ساختارهای داده ";
+ }
+ else
+ {
+ result+="كلاس ها ";
+ }
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="و مستندات ساختار داده برای هر عضو ";
+ }
+ else
+ {
+ result+="و مستندات کلاس برای هر عضو ";
+ }
+ result+="را مشاهده ميکنيد :";
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="ليست همه ی توابع ، متغيير ها، تعاريف و ... ";
+ if (!extractAll) result+="(مستند شده) ";
+
+ result+=" به همراه ارتباط آنها ";
+ result+="با پرونده هايی که به آن مربوط اند :";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "ليست همه ی مثال ها :"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "لیست تمام صفحات و مستندات مربوطه :"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "لیست تمام ماژول ها:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "مستندات"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "فهرست ماژول ها"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "فهرست سلسله مراتب"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "فهرست ساختار داده ها";
+ }
+ else
+ {
+ return "فهرست کلاس های";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "فهرست پرونده ها"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "مستندات ماژول"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "مستندات ساختار داده ها";
+ }
+ else
+ {
+ return "مستندات کلاس ها";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "مستندات فایل"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "مستندات مثال"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "مستندات صفحه"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "راهنمای مرجع"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "تعاريف"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "تعریف گونه ها"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "تعاريف"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "توابع"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "متغيير ها"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "معرف ها"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Define Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "مستندات تعريف"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "مستندات معرف"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "توضيح تابع"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "توضيح متغير"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "ساختارهای داده";
+ }
+ else
+ {
+ return "کلاس ها";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result = HtmlDivEnd + HtmlRightToLeft + QCString("توليد شده در ") +date ;
+ if (projName) result+=(QCString)" برای "+projName;
+ result+=(QCString)" توسط";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)""+clName+" نمودار وراثت برای :";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return ".فقط برای استعمال داخلی"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "اخطار"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "نسخه"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "تاريخ"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "خروجی"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "See also"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "پارامترها"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "استثناء ها"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "توليد شده توسط"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "ليست فضاهای نام"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="در ذيل ليستی از همه ی فضاهای نام ";
+ if (!extractAll) result+="(مستند سازی شده) ";
+ result+="به همراه توضيح کوتاه آنها مشاهده می کنيد :";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "کلاس های دوست"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "مستندات توابع مربوط و دوست"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result;
+ switch(compType)
+ {
+ case ClassDef::Class: result=" کلاس"; break;
+ case ClassDef::Struct: result=" ساختار داده"; break;
+ case ClassDef::Union: result=" Union"; break;
+ case ClassDef::Interface: result=" Interface"; break;
+ case ClassDef::Protocol: result=" Protocol"; break;
+ case ClassDef::Category: result=" Category"; break;
+ case ClassDef::Exception: result=" استثناء"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" قالب";
+ result=QCString(clName) + " مرجع" +result ;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" مرجع پرونده";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" مرجع فضای نام";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "توابع عمومی عضو کلاس"; }
+ virtual QCString trPublicSlots()
+ { return "های عمومی Slot"; }
+ virtual QCString trSignals()
+ { return "سيگنال ها"; }
+ virtual QCString trStaticPublicMembers()
+ { return "توابع ثابت عمومی عضو کلاس"; }
+ virtual QCString trProtectedMembers()
+ { return "توابع خصوصی عضو کلاس"; }
+ virtual QCString trProtectedSlots()
+ { return "های محافظت شده Slot"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "توابع ثابت محافظت شده عضو کلاس"; }
+ virtual QCString trPrivateMembers()
+ { return "توابع خصوصی عضو کلاس"; }
+ virtual QCString trPrivateSlots()
+ { return "های خصوصی Slot"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "توابع خصوصی ثابت عضو کلاس"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" و ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return ".را به ارث می برد "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return ".اين کلاس را به ارث برده است "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplemented from "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "تعریف شده است "+trWriteList(numEntries)+"دوباره در ";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "اعضای فضاهای نام"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="ليست همه اعضای فضای نام ";
+ if (!extractAll) result+="(مستند شده) ";
+ result+=" با ارتباطشان با";
+ result+="فضاهای نامی که به آن مربوط اند را مشاهده ميکنيد :";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "فهرست فضاهای نام"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "توضيحات فضای نام"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "فضاهای نام"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"مستندات اين ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="کلاس"; break;
+ case ClassDef::Struct: result+="ساختار داده"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" از روی پرونده ";
+ if (single) result+=""; else result+="های ";
+ result+="زير توليد شده است :";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "مقادير بازگشتی"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "صفحه ی اصلی"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "ص."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return ".در خط @0 از پرونده @1 تعريف شده است";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return ".در فايل @0 تعريف شده است";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "منسوخ شده";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Collaboration diagram for "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"نمودار شامل شدن ها برای "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "مستندات توباع آغازین و پایانی";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "کد منبع اين پرونده.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "توضيحات اين پرونده.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "پیش شرط";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "پس شرط";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "مقدار اوليه :";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "کد";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "سلسله مراتب گرافيکی کلاس";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "نمایش نمودار درختی گرافیکی کلاس";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "نمایش نمودار درختی متنی کلاس";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "فهرست صفحات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "نکته";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "های عمومی Type";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "فضاهای داده ها";
+ }
+ else
+ {
+ return "خواص (متغييرهای) عمومی";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "خواص (متغييرهای) عمومی ثابت";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "های حفاظت شده Type";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "خواص (متغييرهای) حفاظت شده";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "خواص (متغييرهای) حفاظت شده ثابت";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "های خصوصی Type";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "خواص (متغييرهای) خصوصی";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "خواص (متغييرهای) خصوصی ثابت";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "برای انجام";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "ليست کارهاي آينده";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return " استفاده شده توسط ";
+ }
+ virtual QCString trRemarks()
+ {
+ return "ملاحظات";
+ }
+ virtual QCString trAttention()
+ {
+ return "توجه";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "این نمودار فایل هایی را که این فایل را به طور مستقیم یا غیر مستقیم استفاده کرده اند نشان می دهد";
+ }
+ virtual QCString trSince()
+ {
+ return "از";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "راهنمای نمودار";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "This page explains how to interpret the graphs that are generated "
+ "by doxygen.<p>\n"
+ "Consider the following example:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "If the \\c MAX_DOT_GRAPH_HEIGHT tag in the configuration file "
+ "is set to 240 this will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A filled black box represents the struct or class for which the "
+ "graph is generated.\n"
+ "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>%A box with a red border denotes a documented struct or class for"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries.\n"
+ "</ul>\n"
+ "The arrows have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.\n"
+ "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible.\n"
+ "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "the template class it was instantiated from. The arrow is labeled with "
+ "the template parameters of the instance.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "راهنما";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "تست";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "خاصیت ها";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "مستندات خاصیت";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "ساختار های داده";
+ }
+ else
+ {
+ return "كلاس ها";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "لیست بسته ها";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "لیست بسته ها به همراه توضیح مختر در صورت وجود :";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "بسته ها";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "مقدار:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "اشکال";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "ليست اشکالات";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1256";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "178";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "فهرست";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "کلاس" : "کلاس"));
+ if (!singular) result+="ها";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool /*first_capital*/, bool singular)
+ {
+ QCString result("پرونده");
+ if (!singular) result=result+" ها";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "فضای نام " : "فضای نام "));
+ if (!singular) result+="ها";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Group" : "group"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "صفحه" : "صفحه"));
+ if (!singular) result+=" ها ";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "عضو" : "عضو"));
+ if (!singular) result+="ها";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Author" : "author"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "را استفاده ميکند ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "را تکميل می کند "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return ".تکميل شده است "+trWriteList(numEntries)+" در";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "فهرست";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "لیست آیتم های از رده خارج";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "رویداد ها";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "مستندات رویداد";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "انواع بسته ها";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "توابع بسته ها";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Static Package Functions";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "خواص بسته ها";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Static Package Attributes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "همه";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "نمودار صدا زدن برای این تابع :";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "نتايج جستجو";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "متاسفانه هیچ صفحه ای برای جستجو ی شما یافت نشد.";
+ }
+ else if (numDocuments==1)
+ {
+ return "یک سند برای این مورد یافت شد.";
+ }
+ else
+ {
+ return "Found <b>$num</b> documents matching your query. "
+ "Showing best matches first.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Matches:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " کد و پرونده منبع";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "ساختار و سلسله مراتب شاخه ها"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "مستندات دايرکتوری"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "شاخه ها"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "در ذيل ساختار شاخه ها و دايرکتوری ها را نسبتا مرتب شده می بينيد :";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" مرجع شاخه ی"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool /*first_capital*/, bool singular)
+ {
+ QCString result("شاخه");
+ if (singular) result+=" ها "+result;
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "This is an overloaded member function, "
+ "provided for convenience. It differs from the above "
+ "function only in what argument(s) it accepts.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "نمودار صدا زننده های این تابع:";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "مستندات توابع عضو"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "لیست ساختار های داده"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "فیلدهای اطلاعات"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "ساختارهای داده به همراه توضیح کوتاه :"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool)
+ {
+ return "توضیحات اعضا ساختارها به همراه مستندات ساختار داده ی مربوطه";
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Data Type Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Data Type Documentation"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "توابع و زیربرنامه ها"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "مستندات توابع و زیربرنامه ها"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "ساختار های داده"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "لیست ماژول ها"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool)
+ {
+ QCString result="لیست ماژول ها به همراه توضیحات کوتاه";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Module"; break;
+ case ClassDef::Struct: result+=" Type"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Reference";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Module Reference";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "اعضاء ماژول"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool)
+ {
+ QCString result="لیست اعضاء ماژول ها به همراه مستندات ماژول مربوطه";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modules Index"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool, bool singular)
+ {
+ QCString result("ماژول");
+ if (!singular) result+=" ها";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="module"; break;
+ case ClassDef::Struct: result+="type"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" was generated from the following file";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Type" : "type"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool, bool singular)
+ {
+ QCString result("زیربرنامه");
+ if (!singular) result+=" ها ";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Type Constraints";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name) + " Relation";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "در حال بارگذاری...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "فضای نام جهانی";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "در حال جستجو...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "یافت نشد";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"پرونده ای در "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Includes file in "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "دوشنبه","سهشنبه","چهارشنبه","پنجشنبه","جمعه","شنبه","یکشنبه" };
+ static const char *months[] = { "ژانویه","فوریه","مارس","آوریل","می","جون","جولای","آگوست","سپتامبر","اکتبر","نوامبر","دسامبر" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return convertDigitsToFarsi(sdate);
+ }
+
+};
+
+#endif
diff --git a/src/translator_fi.h b/src/translator_fi.h
new file mode 100644
index 0000000..eeeb9a5
--- /dev/null
+++ b/src/translator_fi.h
@@ -0,0 +1,1859 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/*
+==================================================================================
+Suomenkielinen käännös:
+Olli Korhonen ( -> 0.49-990425) <olli.korhonen at ccc.fi>
+Antti Laine (0.49-990425 -> ) <antti.a.laine at tut.fi>
+==================================================================================
+1999/10/19
+* Alustava käännös valmis.
+
+* Huom: Kaikille termeille on keksitty käännösvastine, mikä ei ehkä ole
+ kaikissa tapauksissa hyvä ratkaisu, ja parempikin termi voi
+ olla vakiintuneessa käytössä.
+
+2008-04-08
+* Käännetty versioon 1.5.5 asti.
+2008-08-26
+* MAX_DOT_GRAPH_HEIGHT poistettu, versio 1.5.6
+* Tekstit muutettu UTF-8:ksi
+2009-01-17
+* versio 1.5.8
+* Kantaluokka vaihdettu TranslatorEnglishistä Translatoriksi
+* Enumeraatio -> luettelotyyppi
+* Paranneltu kieltä ja poistettu kirjoitusvirheitä
+
+* Tehtävää:
+ - Termien kokoaminen listaksi ja suomennosten järkevyyden tarkastelu. (lista on jo melko kattava)
+ Author = Tekijä
+ Class = Luokka
+ Compound = Kooste
+ Data = Data
+ Documentation = Dokumentaatio
+ Defines = Määrittelyt
+ Description = Selite
+ Detailed = Yksityiskohtainen
+ Diagram = Kaavio
+ Enum = Luettelotyyppi
+ Exceptions = Poikkeukset
+ File = Tiedosto
+ Friends = Ystävät
+ Functions = Funktiot
+ Hierarchical = Hierarkinen
+ Index = Indeksi
+ Inherits = Perii
+ Member = Jäsen
+ Module = Moduli
+ Namespace = Nimiavaruus
+ Parameters = Parametrit
+ Private = Yksityinen
+ Protected = Suojattu
+ Prototypes = Prototyypit
+ Public = Julkinen
+ Reference Manual= Käsikirja
+ Reimplemented = Uudelleen toteutettu
+ Related = Liittyvä
+ Signals = Signaalit
+ Slots = Vastineet
+ Static = Staattinen
+ Struct = Tietue
+ Typedef = Tyyppimäärittely
+ Union = Yhdiste
+ Variables = Muuttujat
+ - Taivutusmuotojen virheettömyyden tarkastelu prepositioiden korvauskohdissa.
+ - Sanasta sanaan käännöskohtien mielekkyyden tarkastelu valmiista dokumentista.
+ - umlaut vastineiden käyttö scandien kohdalla.
+
+positiiviset kommentit otetaan ilolla vastaan.
+===================================================================================
+*/
+
+#ifndef TRANSLATOR_FI_H
+#define TRANSLATOR_FI_H
+
+class TranslatorFinnish : public TranslatorAdapter_1_6_0
+{
+ public:
+ /*! This method is used to generate a warning message to signal
+ * the user that the translation of his/her language of choice
+ * needs updating.
+ */
+ /*virtual QCString updateNeededMessage()
+ {
+ return "The Finnish translator is really obsolete.\n"
+ "It was not updated since version 1.0.0. As a result,\n"
+ "some sentences may appear in English.\n\n";
+ }*/
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "finnish"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[finnish]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Liittyvät funktiot"; } // "Related Functions";
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Huomaa, että nämä eivät ole jäsenfunktioita.)"; } // "(Note that these are not member functions.)"
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Yksityiskohtainen selite"; } // "Detailed Description"
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ // header that is put before the list of typedefs.
+ { return "Jäsentyyppimäärittelyiden dokumentaatio"; } // "Member Typedef Documentation"
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Jäsenluettelotyyppien dokumentaatio"; } // "Member Enumeration Documentation"
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Jäsenfunktioiden dokumentaatio"; } // "Member Function Documentation"
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Kenttien dokumentaatio"; // "Field Documentation";
+ }
+ else
+ {
+ return "Jäsendatan dokumentaatio"; // "Member Data Documentation"
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Lisää..."; } // "More..."
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Lista kaikista jäsenistä"; } // "List of all members."
+ virtual QCString trMemberList()
+
+ /*! used as the title of the "list of all members" page of a class */
+ { return "Jäsenlista"; } // "Member List"
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Tämä on lista kaikista jäsenistä luokassa "; } // "This is the complete list of members for "
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", sisältäen kaikki perityt jäsenet."; } // ", including all inherited members."
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result=(QCString)"Automaattisesti luotu Doxygenilla "
+ "lähdekoodista projektille "+s; // "Generated automatically by Doxygen" ... "for" ... "from the sourcecode"
+ //if (s) result+=(QCString)" voor "+s;
+ // tässä on ongelma, kuinka taivuttaa parametria, esim. "Jcad"+"in"; "IFC2VRML konversio"+"n"
+ // mutta ratkaistaan ongelma kätevästi kaksoispisteellä -> "Jcad:n" / "IFC2VRML konversio:n"
+ // lopputulos on vähemmän kökkö ja täysin luettava, mutta ei kuitenkaan täydellinen.
+ //
+ // kierretään ongelma taivuttamalla sanaa projekti :)
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "luettelotyypin nimi"; } // "enum name"
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "luettelotyypin arvo"; } // "enum value"
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "määritelty"; } // "defined in"
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduulit"; } // "Modules"
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Luokkahierarkia"; } // "Class Hierarchy"
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueet"; // "Data Structures"
+ }
+ else
+ {
+ return "Luokkalista"; // "Class List"
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Tiedostolista"; } // "File List"
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueen kentät"; // "Data Fields"
+ }
+ else
+ {
+ return "Luokan jäsenet"; // "Class Members"
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globaalit"; // "Globals"
+ }
+ else
+ {
+ return "Tiedoston jäsenet"; // "File Members"
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Liittyvät sivut"; } // "Related Pages"
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Esimerkit"; } // "Examples"
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Etsi"; } // "Search"
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Tämä periytymislista on päätasoltaan aakkostettu " // "This inheritance list is sorted roughly, "
+ "mutta alijäsenet on aakkostettu itsenäisesti:"; // "but not completely, alphabetically:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista ";
+ if (!extractAll) result+="dokumentoiduista "; // "documented "
+ result+="tiedostoista lyhyen selitteen kanssa:"; // "files with brief descriptions:"
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tässä ovat tietueet lyhyen selitteen kanssa:"; // "Here are the data structures with brief descriptions:"
+ }
+ else
+ {
+ return "Tässä ovat luokat, tietueet ja " // "Here are the classes, structs and "
+ "yhdisteet lyhyen selitteen kanssa:"; // "unions with brief descriptions:"
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll)
+ {
+ result+="dokumentoiduista "; // "documented "
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="tietuiden ja yhdisteiden kentistä"; // "struct and union fields"
+ }
+ else
+ {
+ result+="luokkien jäsenistä"; // "class members"
+ }
+ result+=" linkitettyinä "; // " with links to "
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="jokaisen kentän tietueen/yhdisteen dokumentaatioon:"; // "the struct/union documentation for each field:"
+ }
+ else
+ {
+ result+="jokaisen jäsenen luokkadokumentaatioon:"; // "the class documentation for each member:"
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+= "tietueisiin/yhdisteisiin, joihin ne kuuluvat:"; // "the structures/unions they belong to:"
+ }
+ else
+ {
+ result+="luokkiin, joihin ne kuuluvat"; //"the classes they belong to:"
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll) result+="dokumentoiduista "; // "documented "
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funktioista, muuttujista, määrittelyistä, luettelotyypeistä ja tyyppimäärittelyistä"; // "functions, variables, defines, enums, and typedefs"
+ }
+ else
+ {
+ result+="tiedoston jäsenistä"; // "file members"
+ }
+ result+=" linkitettyinä "; // " with links to "
+ if (extractAll)
+ result+="tiedostoihin, joihin ne kuuluvat:"; // "the files they belong to:"
+ else
+ result+="dokumentaatioon:"; // "the documentation:"
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Tässä on lista kaikista esimerkeistä:"; } // "Here is a list of all examples:"
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Tässä on lista kaikista liittyvistä dokumentaatiosivuista:"; } // "Here is a list of all related documentation pages:"
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Tässä on lista kaikista moduleista:"; } // "Here is a list of all modules:"
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentaatio"; } // "Documentation"
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Moduuliluettelo"; } // "Module Index"
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarkinen luettelo"; } // "Hierarchical Index"
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueluettelo"; // "Data Structure Index"
+ }
+ else
+ {
+ return "Luokkaluettelo"; // "Class Index"
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Tiedostoluettelo"; } // "File Index"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Moduulien dokumentaatio"; } // "Module Documentation"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueiden dokumentaatio"; // "Data Structure Documentation"
+ }
+ else
+ {
+ return "Luokkien dokumentaatio"; // "Class Documentation"
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Tiedostojen dokumentaatio"; } // "File Documentation"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Esimerkkien dokumentaatio"; } // "Example Documentation"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Sivujen dokumentaatio"; } // "Page Documentation"
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Käsikirja"; } // "Reference Manual"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Määrittelyt"; } // "Defines"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Tyyppimäärittelyt"; } // "Typedefs"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Luettelotyypit"; } // "Enumerations"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funktiot"; } // "Functions"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Muuttujat"; } // "Variables"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Luettelotyyppien arvot"; } // "Enumerator"
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Määritysten dokumentointi"; } // "Define Documentation"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Tyyppimääritysten dokumentaatio"; } // "Typedef Documentation"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Luettelotyyppien dokumentaatio"; } // "Enumeration Type Documentation"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funktioiden dokumentaatio"; } // "Function Documentation"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Muuttujien dokumentaatio"; } // "Variable Documentation"
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueet"; // "Data Structures"
+ }
+ else
+ {
+ return "Luokat"; // "Classes"
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ // funktio on hiukan vaikea kääntää prepositioihin sidotun rakenteen vuoksi.
+ // Muutetaan siis lauserakennetta suomalaisemmaksi
+ // Generated on $date for $project by:
+ // -> Generated for $project on $date by:
+ QCString result=(QCString)"Generoinut ";
+ if (projName) result+=(QCString)"projektille "+projName+" ";
+ result+=(QCString)date+" ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return "Luokan "+(QCString)clName+" luokkakaavio"; // "Inheritance diagram for "
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Vain sisäiseen käyttöön."; } // "For internal use only."
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Varoitus"; } // "Warning"
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versio"; } // "Version"
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Päiväys"; } // "Date"
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Palauttaa"; } // "Returns"
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Katso myös"; } // "See also"
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametrit"; } // "Parameters"
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Poikkeukset"; } // "Exceptions"
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generoinut"; } // "Generated by"
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Nimiavaruus Lista"; } // "Namespace List"
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll) result+="dokumentoiduista "; // "documented "
+ result+="nimiavaruuksista lyhyen selitteen kanssa:"; // "namespaces with brief descriptions:"
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Ystävät"; } // "Friends"
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Ystävät ja niihin liittyvien funktioiden dokumentaatio"; } // "Friends And Related Function Documentation"
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" luokka"; break; // " Class"
+ case ClassDef::Struct: result+=" tietue"; break; // " Struct"
+ case ClassDef::Union: result+=" yhdiste"; break; // " Union"
+ case ClassDef::Interface: result+=" rajapinta"; break; // " Interface"
+ case ClassDef::Protocol: result+=" protokolla"; break; // " Protocol"
+ case ClassDef::Category: result+=" kategoria"; break; // " Category"
+ case ClassDef::Exception: result+=" poikkeus"; break; // " Exception"
+ default: break;
+ }
+ if (isTemplate) result+="malli"; // " Template"
+ result+="referenssi"; // " Reference"
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" tiedostoreferenssi"; // " File Reference"
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" nimiavaruusreferenssi"; // " Namespace Reference"
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Julkiset jäsenfunktiot"; } // "Public Member Functions"
+ virtual QCString trPublicSlots()
+ { return "Julkiset vastineet"; } // "Public Slots"
+ virtual QCString trSignals()
+ { return "Signaalit"; } // "Signals"
+ virtual QCString trStaticPublicMembers()
+ { return "Staattiset julkiset jäsenfunktiot"; } // "Static Public Member Functions"
+ virtual QCString trProtectedMembers()
+ { return "Suojatut jäsenfunktiot"; } // "Protected Member Functions"
+ virtual QCString trProtectedSlots()
+ { return "Suojatut vastineet"; } // "Protected Slots"
+ virtual QCString trStaticProtectedMembers()
+ { return "Staattiset suojatut jäsenfunktiot"; } // "Static Protected Member Functions"
+ virtual QCString trPrivateMembers()
+ { return "Yksityiset jäsenfunktiot"; } // "Private Member Functions"
+ virtual QCString trPrivateSlots()
+ { return "Yksityiset vastineet"; } // "Private Slots"
+ virtual QCString trStaticPrivateMembers()
+ { return "Staattiset yksityiset jäsenfunktiot"; } // "Static Private Member Functions"
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" ja "; // ", and "
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return (QCString)"Periytyy "+(numEntries > 1 ? "luokista " : "luokasta ")+trWriteList(numEntries)+"."; // "Inherits "
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return (QCString)"Periytetään "+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Inherited by "
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return (QCString)"Uudelleentoteuttaa "+(numEntries > 1 ? "luokat " : "luokan ")+trWriteList(numEntries)+"."; // "Reimplemented from "
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return (QCString)"Uudelleentoteutetaan "+(numEntries > 1 ? "luokissa " : "luokassa ")+trWriteList(numEntries)+"."; // "Reimplemented in "
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Nimiavaruuden jäsenet"; } // "Namespace Members"
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll) result+="dokumentoiduista "; // "documented "
+ result+="nimiavaruuden jäsenistä linkitettynä "; // "namespace members with links to "
+ if (extractAll)
+ result+="nimiavaruuden dokumentaatioon johon ne kuuluvat:"; // "the namespace documentation for each member:";
+ else
+ result+="nimiavaruuksiin joihin ne kuuluvat:"; // "the namespaces they belong to:"
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Nimiavaruuksien luettelo"; } // "Namespace Index"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Nimiavaruuden dokumentaatio"; } // "Namespace Documentation"
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Nimiavaruudet"; } // "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentaatio tälle "; // "The documentation for this "
+ switch(compType)
+ {
+ case ClassDef::Class: result+="luokalle"; break; // "class"
+ case ClassDef::Struct: result+="tietueelle"; break; // "struct"
+ case ClassDef::Union: result+="yhdisteelle"; break; // "union"
+ case ClassDef::Interface: result+="rajapinnalle"; break; // "interface"
+ case ClassDef::Protocol: result+="protokollalle"; break; // "protocol"
+ case ClassDef::Category: result+="kategorialle"; break; // "category"
+ case ClassDef::Exception: result+="poikkeukselle"; break; // "exception"
+ default: break;
+ }
+ if (single) result+=" luotiin seuraavasta tiedostosta:"; // " was generated from the following file"
+ else result+=" luotiin seuraavista tiedostoista:"; // ":" or "s:"
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Paluuarvot"; } // "Return values"
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Pääsivu"; } // "Main Page"
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; } // "p."
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Määrittely tiedoston @1 rivillä @0."; // "Definition at line @0 of file @1."
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Määrittely tiedostossa @0."; // "Definition in file @0."
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Vanhentunut"; // "Deprecated"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Yhteistyökaavio luokalle "+clName+":"; // "Collaboration diagram for "+clName+":"
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Sisällytysriippuvuuskaavio tiedostolle "+fName+":"; // "Include dependency graph for "+fName+":"
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Rakentajien & purkajien dokumentaatio"; // "Constructor & Destructor Documentation";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Siirry tämän tiedoston lähdekoodiin."; // "Go to the source code of this file."
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Siirry tämän tiedoston dokumentaatioon."; // "Go to the documentation of this file."
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Esiehto"; //"Precondition"
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Jälkiehto"; // "Postcondition"
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariantti"; // vai "Pysyväisväittämä"? "Invariant"
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Alkuarvo:"; // "Initial value:"
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "koodi"; // "code"
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Graafinen luokkahierarkia"; // "Graphical Class Hierarchy"
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Siirry graafiseen luokkahierarkiaan"; // "Go to the graphical class hierarchy"
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Siirry tekstimuotoiseen luokkahierarkiaan"; // "Go to the textual class hierarchy"
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Sivuhakemisto"; // "Page Index"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ // FIXME: Missähän merkityksessä tätä käytetään?
+ return "Huomautus"; // "Note"
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Julkiset tyypit"; // "Public Types"
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueen kentät"; // "Data Fields"
+ }
+ else
+ {
+ return "Julkiset attribuutit"; // "Public Attributes"
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Staattiset julkiset attribuutit"; // "Static Public Attributes"
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Suojellut tyypit"; // "Protected Types"
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Suojellut attribuutit"; // "Protected Attributes"
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Staattiset suojellut attribuutit"; // "Static Protected Attributes"
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Yksityiset tyypit"; // "Private Types"
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Yksityiset attribuutit"; // "Private Attributes"
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Staattiset yksityiset attribuutit"; // "Static Private Attributes"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Vielä tehtävänä"; // "Todo"
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Tehtävälista"; // "Todo List"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Viitattu"; // "Referenced by"
+ }
+ virtual QCString trRemarks()
+ {
+ return "Huomioita"; // "Remarks"
+ }
+ virtual QCString trAttention()
+ {
+ return "Huomio"; // "Attention"
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Tämä kaavio näyttää, mitkä tiedostot suorasti "
+ "tai epäsuorasti sisällyttävät tämän tiedoston";
+ // "This graph shows which files directly or "
+ // "indirectly include this file:"
+ }
+ virtual QCString trSince()
+ {
+ // FIXME: Missä merkityksessä tätä käytetään?
+ return "Lähtien"; // "Since"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Kaavion selite"; // "Graph Legend"
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Tämä sivu selittää, kuinka doxygenin luomia kaavioita tulkitaan.<p>\n"
+ // "This page explains how to interpret the graphs that are generated "
+ // "by doxygen.<p>\n"
+ "Ajattele seuraavaa esimerkkiä:\n"
+ // "Consider the following example:\n"
+ "\\code\n"
+ "/*! Näkymätön luokka katkaisun vuoksi */\n"
+ // "/*! Invisible class because of truncation */\n"
+ "class Nakymaton { };\n\n"
+ // "class Invisible { };\n\n"
+ "/*! Katkaistu luokka, periytymissuhde on piilotettu */\n"
+ // "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Katkaistu : public Nakymaton { };\n\n"
+ // "class Truncated : public Invisible { };\n\n"
+ "/* Luokkaa ei ole dokumentoitu doxygen-kommenteilla */\n"
+ // "/* Class not documented with doxygen comments */\n"
+ "class Dokumentoimaton { };\n\n"
+ // "class Undocumented { };\n\n"
+ "/*! Julkista periyttämistä käyttäen periytetty luokka */\n"
+ // "/*! Class that is inherited using public inheritance */\n"
+ "class JulkinenKanta : public Katkaistu { };\n\n"
+ // "class PublicBase : public Truncated { };\n\n"
+ "/*! Malliluokka */\n"
+ // "/*! A template class */\n"
+ "template<class T> class Malli { };\n\n"
+ // "template<class T> class Templ { };\n\n"
+ "/*! Suojeltua periytymistä käyttäen periytetty luokka */\n"
+ // "/*! Class that is inherited using protected inheritance */\n"
+ "class SuojeltuKanta { };\n\n"
+ // "class ProtectedBase { };\n\n"
+ "/*! Yksityistä periytymistä käyttäen periytetty luokka */\n"
+ // "/*! Class that is inherited using private inheritance */\n"
+ "class YksityisKanta { };\n\n"
+ // "class PrivateBase { };\n\n"
+ "/*! Luokka jota periytetty luokka käyttää */\n"
+ // "/*! Class that is used by the Inherited class */\n"
+ "class Kaytetty { };\n\n"
+ // "class Used { };\n\n"
+ "/*! Kantaluokka joka periytyy useasta muusta luokasta */\n"
+ // "/*! Super class that inherits a number of other classes */\n"
+ "class Periytetty : public JulkinenKanta,\n"
+ " : protected SuojeltuKanta,\n"
+ " : private YksityisKanta,\n"
+ " : public Dokumentoimaton,\n"
+ " : public Malli<int>\n"
+ "{\n"
+ " private:\n"
+ " Kaytetty *m_kaytettyLuokka;\n"
+ "}\n";
+ // "class Inherited : public PublicBase,\n"
+ // " protected ProtectedBase,\n"
+ // " private PrivateBase,\n"
+ // " public Undocumented,\n"
+ // " public Templ<int>\n"
+ // "{\n"
+ // " private:\n"
+ // " Used *m_usedClass;\n"
+ // "};\n"
+ "\\endcode\n"
+ "Tuloksena on seuraavanlainen kaavio:"
+ //"This will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Ylläolevassa kaaviossa laatikoilla on seuraavat merkitykset\n:"
+ // "The boxes in the above graph have the following meaning:\n"
+ "<ul>\n"
+ "<li>Täytetty harmaa laatikko esittää tietuetta tai luokkaa, jolle "
+ // "<li>%A filled gray box represents the struct or class for which the "
+ "kaavio on luotu.\n"
+ // "graph is generated.\n"
+ "<li>Mustareunainen laatikko merkitsee dokumentoitua tietuetta tai luokkaa.\n"
+ // "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>Harmaareunainen laatikko merkitsee dokumentoimatonta tietuetta tai luokkaa.\n"
+ // "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>Punareunainen laatikko merkistee dokumentoitua luokkaa tai structia "
+ // "<li>%A box with a red border denotes a documented struct or class for"
+ "jolle ei näytetä kaikkia periytymis-/sisällyssuhteita. Kaavio "
+ // "which not all inheritance/containment relations are shown. %A graph is "
+ "katkaistaan, jos se ei mahdu määriteltyjen rajojen sisään.\n"
+ // "truncated if it does not fit within the specified boundaries.\n"
+ "</ul>\n"
+ "Nuolilla on seuraavat merkitykset:\n"
+ // "The arrows have the following meaning:\n"
+ "<ul>\n"
+ "<li>Tummansinistä nuolta käytetään osoittamaan julkista periytymis"
+ // "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "suhdetta kahden luokan välillä.\n"
+ // "relation between two classes.\n"
+ "<li>Tummanvihreää nuolta käytetään suojellussa periytymisessä.\n"
+ // "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>Tummanpunaista nuolta käytetään yksityisessä periytymisessä.\n"
+ // "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>Purppuranväristä katkoviivaa käytetään, jos luokka sisältyy tai "
+ // "<li>%A purple dashed arrow is used if a class is contained or used "
+ "on toisen luokan käyttämä. Nuoli nimetään sillä muuttujalla/muuttujilla "
+ // "by another class. The arrow is labeled with the variable(s) "
+ "jonka läpi osoitettua luokkaa tai tietuetta käytetään.\n"
+ // "through which the pointed class or struct is accessible.\n"
+ "<li>Keltainen katkoviivalla piirretty nuoli merkitsee suhdetta mallin esiintymän ja "
+ // "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "malliluokan välillä. Nuoli nimetään "
+ // "the template class it was instantiated from. The arrow is labeled with "
+ "mallin esiintymän malliparametrilla.\n"
+ // "the template parameters of the instance.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "selite"; // "legend"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Testi"; // "Test"
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testilista"; // "Test List"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Ominaisuudet"; // "Properties"
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Ominaisuuksien dokumentaatio"; // "Property Documentation"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tietueet"; // "Data Structures"
+ }
+ else
+ {
+ return "Luokat"; // "Classes"
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paketti "+name; // "Package "
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakettilista"; // "Package List"
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Tässä ovat paketit lyhyiden selitysten kanssa (jos saatavilla):"; // "Here are the packages with brief descriptions (if available):"
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paketit"; // "Packages"
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Arvo:"; // "Value:"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bugi"; // "Bug"
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Bugilista"; // "Bug List"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Hakemisto"; // "Index"
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Luokka" : "luokka")); // "Class" / "class"
+ if (!singular) result=(first_capital ? "Luokat" : "luokat"); // "+es" -> "Classes" / "classes"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tiedosto" : "tiedosto")); // "File" / "file"
+ if (!singular) result+="t"; // "+s" -> "Files" / "files"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Nimiavaruus" : "nimiavaruus")); // "Namespace" / "namespace"
+ if (!singular) result=(first_capital ? "Nimiavaruudet" : "nimiavaruudet"); // "+s"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ryhmä" : "ryhmä")); // "Group" / "group"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sivu" : "sivu")); // "Page" / "page"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Jäsen" : "jäsen")); // "Member" / "member"
+ if (!singular) result+="et"; // "+s"
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globaali" : "globaali")); // "Global" / "global"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tekijä" : "tekijä")); // "Author" / "author"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Viittaukset"; // "References"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Toteuttaa luokan "+trWriteList(numEntries)+"."; // "Implements "
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Toteutettu luokassa "+trWriteList(numEntries)+"."; // "Implemented in "
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Sisällysluettelo"; // "Table of Contents"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Vanhentuneiden lista"; // "Deprecated List"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Tapahtumat"; // "Events"
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Tapahtumien dokumentaatio"; // "Event Documentation"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Paketin tyypit"; // "Package Types"
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Paketin funktiot"; // "Package Functions"
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Paketin staattiset funktiot"; // "Static Package Functions"
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Paketin attribuutit"; // "Package Attributes"
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Paketin staattiset attribuutit"; // "Static Package Attributes"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Kaikki"; // "All"
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Tässä on kutsukaavio tälle funktiolle:"; // "Here is the call graph for this function:"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Hakutulokset"; // "Search Results"
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Valitettavasti yksikään dokumentti ei vastannut hakuasi."; // "Sorry, no documents matching your query."
+ }
+ else if (numDocuments==1)
+ {
+ return "Löytyi <b>1</b> dokumentti, joka vastasi hakuasi."; // "Found <b>1</b> document matching your query.";
+ }
+ else
+ {
+ return "Löytyi <b>$num</b> dokumenttia, jotka vastasivat hakuasi. " // "Found <b>$num</b> documents matching your query. "
+ "Parhaat tulokset näytetään ensin."; // "Showing best matches first."
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Osumat:"; // "Matches:"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " lähdekooditiedosto"; // " Source File"
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hakemistohierarkia"; } // "Directory Hierarchy"
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Hakemistojen dokumentaatio"; } // "Directory Documentation"
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Hakemistot"; } // "Directories"
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Tämä hakemistohierarkia on järjestetty aakkosellisesti tasoittain:";
+ //This directory hierarchy is sorted roughly, "
+ // "but not completely, alphabetically:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" hakemistoreferenssi"; return result; }
+ // " Directory Reference"
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Hakemisto" : "hakemisto")); // "Director" / "director"
+ if (singular) result+=""; else result+="t"; // "+y" / "+ies"
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Tämä on ylikuormitettu jäsenfunktio, ja se tarjotaan "
+ "käytön helpottamiseksi. Se eroaa ylläolevasta "
+ "funktiosta ainoastaan hyväksymiltään parametreilta.";
+ // "This is an overloaded member function, "
+ // "provided for convenience. It differs from the above "
+ // "function only in what argument(s) it accepts."
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Tässä on kutsukaavio tälle funktiolle:"; // "Here is the caller graph for this function:"
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Luettelotyypin dokumentaatio"; } // "Enumerator Documentation"
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Jäsenfunktioiden/aliohjelmien dokumentaatio"; } // "Member Function/Subroutine Documentation"
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Tietotyyppien lista"; } // "Data Types List"
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Kentät"; } // "Data Fields";
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Tässä ovat tietotyypit lyhyiden selitysten kanssa:"; } // "Here are the data types with brief descriptions:"
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll)
+ {
+ result+="dokumentoiduista "; // "documented "
+ }
+ result+="tietotyyppien jäsenistä"; // "data types members"
+ result+=", sekä linkit "; // " with links to "
+ if (!extractAll)
+ {
+ result+="tietueen dokumentaatioon jokaiselle jäsenelle"; // "the data structure documentation for each member"
+ }
+ else
+ {
+ result+="tietotyyppeihin, joihin ne kuuluvat:"; // "the data types they belong to:"
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Tietotyyppien hakemisto"; } // "Data Type Index"
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Tietotyyppien dokumentaatio"; } // "Data Type Documentation"
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funktiot/aliohjelmat"; } // "Functions/Subroutines"
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funktioiden/aliohjelmien dokumentaatio"; } // "Function/Subroutine Documentation"
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tietotyypit"; } // "Data Types"
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Moduulilista"; } // "Modules List"
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista kaikista "; // "Here is a list of all "
+ if (!extractAll) result+="dokumentoiduista "; // "documented "
+ result+="moduuleista lyhyiden selitysten kanssa:"; // "modules with brief descriptions:"
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" moduuli"; break; // " Module"
+ case ClassDef::Struct: result+=" tyyppi"; break; // " Type"
+ case ClassDef::Union: result+=" yhdiste"; break; // " Union"
+ case ClassDef::Interface: result+=" rajapinta"; break; // " Interface"
+ case ClassDef::Protocol: result+=" protokolla"; break; // " Protocol"
+ case ClassDef::Category: result+=" kategoria"; break; // " Category"
+ case ClassDef::Exception: result+=" poikkeus"; break; // " Exception"
+ default: break;
+ }
+ if (isTemplate) result+="malli"; // " Template"
+ result+="referenssi"; // " Reference"
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" moduulin referenssi"; // " Module Reference"
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Moduulin jäsenet"; } // "Module Members"
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Tässä on lista moduulin kaikista "; // "Here is a list of all "
+ if (!extractAll) result+="dokumentoiduista"; // "documented "
+ result+="jäsenistä, sekä linkit "; // "module members with links to "
+ if (extractAll)
+ {
+ result+="moduulin dokumentaatioon jokaiselle jäsenelle:"; // "the module documentation for each member:"
+ }
+ else
+ {
+ result+="moduuleihin, joihin ne kuuluvat:"; // "the modules they belong to:"
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Moduulien hakemisto"; } // "Modules Index"
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Moduuli" : "moduuli")); // "Module" / "module"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentaatio tälle "; // "The documentation for this "
+ switch(compType)
+ {
+ case ClassDef::Class: result+="moduulille"; break; // "module"
+ case ClassDef::Struct: result+="tyypille"; break; // "type"
+ case ClassDef::Union: result+="yhdisteelle"; break; // "union"
+ case ClassDef::Interface: result+="rajapinnalle"; break; // "interface"
+ case ClassDef::Protocol: result+="protokollalle"; break; // "protocol"
+ case ClassDef::Category: result+="kategorialle"; break; // "category"
+ case ClassDef::Exception: result+="poikkeukselle"; break; // "exception"
+ default: break;
+ }
+ result+=" luotiin "; // " was generated from the following file"
+ if (single) result+="seuraavasta tiedostosta:"; else result+="seuraavista tiedostoista:"; // ":" / "s:"
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tyyppi" : "tyyppi")); // "Type" / "type"
+ if (!singular) result=(first_capital ? "Tyypit" : "tyypit"); // "+s"
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Aliohjelma" : "aliohjelma")); // "Subprogram" / "subprogram"
+ if (!singular) result+="t"; // "+s"
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Tyyppien rajoitteet"; // "Type Constraints"
+ }
+
+};
+
+#endif
diff --git a/src/translator_fr.h b/src/translator_fr.h
new file mode 100644
index 0000000..2c548c2
--- /dev/null
+++ b/src/translator_fr.h
@@ -0,0 +1,2060 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The translation into French was provided by
+ * Christophe Bordeux (bordeux at lig.di.epfl.ch)
+ * and after version 1.2.0 by Xavier Outhier (xouthier at yahoo.fr)
+ * member of the non for profit association D2SET (http://d2set.free.fr).
+ * Benoît BROSSE (Benoit dot BROSSE at ingenico dot com) was added
+ * after the 1.8.4 release.
+ */
+
+/******************************************************************************
+ * History of content
+ *
+ * Date | Description
+ * ============+=============================================================
+ * 2001-11-22 | Removed obsolet methods:
+ * | QCString latexBabelPackage()
+ * | QCString trAuthor()
+ * | QCString trAuthors()
+ * | QCString trFiles()
+ * | QCString trIncludeFile()
+ * | QCString trVerbatimText(const char *f)
+ * -------------+------------------------------------------------------------
+ * 2002-01-23 | Update for new since 1.2.13
+ * -------------+------------------------------------------------------------
+ * 2002-07-11 | Update for new since 1.2.16
+ * -------------+------------------------------------------------------------
+ * 2002-09-24 | Update for new since 1.2.17
+ * -------------+------------------------------------------------------------
+ * 2002-10-22 | Update for new since 1.2.18
+ * -------------+------------------------------------------------------------
+ * 2003-02-04 | Corrected typo. Thanks to Bertrand M. :)
+ * -------------+------------------------------------------------------------
+ * 2003-03-29 | Update for new since 1.3
+ * -------------+------------------------------------------------------------
+ * 2003-03-29 | Changed fonction into méthode.
+ * -------------+------------------------------------------------------------
+ * 2003-06-06 | Fixed code page problem appeared between 1.42 and 1.43 in CVS
+ * -------------+------------------------------------------------------------
+ * 2003-06-10 | Update for new since 1.3.1
+ * -------------+------------------------------------------------------------
+ * 2003-09-12 | Update for new since 1.3.3
+ * -------------+------------------------------------------------------------
+ * 2004-04-30 | Updates by Jacques Bouchard <jacques.bouchard at noos.fr>:
+ * | - spaces between ':' removed (should be added by the renderer)
+ * | - missing spaces added
+ * | - missing tests for OPTIMIZE_OUTPUT_FOR_C added
+ * | - translations corrected
+ * | - translator_fr.h now conforms exactly to translator_en.h
+ * | (try: gvim -d translator_en.h translator_fr.h)
+ * -------------+------------------------------------------------------------
+ * 2005-07-12 | Update for new since 1.4.1
+ * -------------+------------------------------------------------------------
+ * 2005-10-09 | Update for new since 1.4.6
+ * | Added virtual QCString trCallerGraph()
+ * | Removed virtual QCString trHeaderFilesDescription()
+ * | Removed virtual QCString trField(bool first_capital, bool singular)
+ * | Removed virtual QCString trPackageDocumentation()
+ * | Removed virtual QCString trSources()
+ * | Removed virtual QCString trReimplementedForInternalReasons()
+ * | Removed virtual QCString trInterfaces()
+ * | Removed virtual QCString trHeaderFiles()
+ * | Removed virtual QCString trBugsAndLimitations()
+ * | Removed virtual QCString trNoDescriptionAvailable()
+ * | Corrected some misspelling thanx to Christophe C.
+ * -------------+------------------------------------------------------------
+ */
+
+#ifndef TRANSLATOR_FR_H
+#define TRANSLATOR_FR_H
+
+// When defining a translator class for the new language, follow
+// the description in the documentation. One of the steps says
+// that you should copy the translator_en.h (this) file to your
+// translator_xx.h new file. Your new language should use the
+// Translator class as the base class. This means that you need to
+// implement exactly the same (pure virtual) methods as the
+// TranslatorEnglish does. Because of this, it is a good idea to
+// start with the copy of TranslatorEnglish and replace the strings
+// one by one.
+//
+// It is not necessary to include "translator.h" or
+// "translator_adapter.h" here. The files are included in the
+// language.cpp correctly. Not including any of the mentioned
+// files frees the maintainer from thinking about whether the
+// first, the second, or both files should be included or not, and
+// why. This holds namely for localized translators because their
+// base class is changed occasionaly to adapter classes when the
+// Translator class changes the interface, or back to the
+// Translator class (by the local maintainer) when the localized
+// translator is made up-to-date again.
+
+class TranslatorFrench : public Translator
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "french"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[french]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Fonctions associées"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Notez que ce ne sont pas des fonctions membres)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Description détaillée"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Documentation des définitions de type membres"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Documentation des énumérations membres"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Documentation des fonctions membres"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentation des champs";
+ }
+ else
+ {
+ return "Documentation des données membres";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Plus de détails..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Liste de tous les membres"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Liste des membres"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Liste complète des membres de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", y compris les membres hérités :"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Généré automatiquement par Doxygen";
+ if (s) result+=(QCString)" pour "+s;
+ result+=" à partir du code source.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "énumération"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "valeur énumérée"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "défini dans"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modules"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hiérarchie des classes"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structures de données";
+ }
+ else
+ {
+ return "Liste des classes";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Liste des fichiers"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Champs de donnée";
+ }
+ else
+ {
+ return "Membres de classe";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Variables globale";
+ }
+ else
+ {
+ return "Membres de fichier";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Pages associées"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Exemples"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Recherche"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Cette liste d'héritage est classée "
+ "approximativement par ordre alphabétique :";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les fichiers ";
+ if (!extractAll) result+="documentés ";
+ result+="avec une brève description :";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Liste des structures de données avec une brève description :";
+ }
+ else
+ {
+ return "Liste des classes, structures, "
+ "unions et interfaces avec une brève description :";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="champs de structure et d'union ";
+ }
+ else
+ {
+ result+="membres de classe ";
+ }
+ if (!extractAll)
+ {
+ result+="documentés ";
+ }
+ result+="avec des liens vers ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="la documentation de structure/union de chaque champ :";
+ }
+ else
+ {
+ result+="la documentation de classe de chaque membre :";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="les structures/unions auxquelles ils appartiennent :";
+ }
+ else
+ {
+ result+="les classes auxquelles ils appartiennent :";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Liste ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="de toutes les fonctions, variables, macros, enumérations, et définitions de type ";
+ }
+ else
+ {
+ result+="de tous les membres de fichier ";
+ }
+ if (!extractAll) result+="documentés ";
+ result+="avec des liens vers ";
+ if (extractAll)
+ result+="les fichiers auxquels ils appartiennent :";
+ else
+ result+="la documentation :";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Liste de tous les exemples :"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Liste de toutes les pages de documentation associées :"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Liste de tous les modules :"; }
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Documentation"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Index des modules"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Index hiérarchique"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Index des structures de données";
+ }
+ else
+ {
+ return "Index des classes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Index des fichiers"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Documentation des modules"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentation des structures de données";
+ }
+ else
+ {
+ return "Documentation des classes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Documentation des fichiers"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Documentation des exemples"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Documentation des pages associées"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Manuel de référence"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Macros"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Définitions de type"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Énumérations"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Fonctions"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variables"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Valeurs énumérées"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Documentation des macros"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Documentation des définitions de type"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Documentation du type de l'énumération"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Documentation des fonctions"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Documentation des variables"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structures de données";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Généré le "+date;
+ if (projName) result+=(QCString)" pour "+projName;
+ result+=(QCString)" par";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Graphe d'héritage de "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Pour un usage interne uniquement."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Avertissement"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Version"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Date"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Renvoie"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Voir également"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Paramètres"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Exceptions"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Généré par"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990307
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Liste des espaces de nommage"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les espaces de nommage ";
+ if (!extractAll) result+="documentés ";
+ result+="avec une brève description:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Amis"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990405
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Documentation des fonctions amies et associées"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990425
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Référence ";
+ if (isTemplate) result+="du modèle ";
+ result+="de ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="la classe "; break;
+ case ClassDef::Struct: result+="la structure "; break;
+ case ClassDef::Union: result+="l'union "; break;
+ case ClassDef::Interface: result+="l'interface "; break;
+ case ClassDef::Protocol: result+="le protocol "; break;
+ case ClassDef::Category: result+="la catégorie "; break;
+ case ClassDef::Exception: result+="l'exception "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result= "Référence du fichier ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result= "Référence de l'espace de nommage ";
+ result+=namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Fonctions membres publiques"; }
+ virtual QCString trPublicSlots()
+ { return "Connecteurs publics"; }
+ virtual QCString trSignals()
+ { return "Signaux"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Fonctions membres publiques statiques"; }
+ virtual QCString trProtectedMembers()
+ { return "Fonctions membres protégées"; }
+ virtual QCString trProtectedSlots()
+ { return "Connecteurs protégés"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Fonctions membres protégées statiques"; }
+ virtual QCString trPrivateMembers()
+ { return "Fonctions membres privées"; }
+ virtual QCString trPrivateSlots()
+ { return "Connecteurs privés"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Fonctions membres privées statiques"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", et ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Est dérivée de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Dérivée par "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Réimplémentée à partir de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Réimplémentée dans "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Membres de l'espace de nommage"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les membres des espaces de nommage ";
+ if (!extractAll) result+="documentés ";
+ result+="avec des liens vers ";
+ if (extractAll)
+ result+="la documentation de namespace de chaque membre :";
+ else
+ result+="les espaces de nommage auxquels ils appartiennent :";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Index des espaces de nommage"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Documentation des espaces de nommage"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990522
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Espaces de nommage"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990728
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ bool female = true;
+ QCString result=(QCString)"La documentation de ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="cette classe"; break;
+ case ClassDef::Struct: result+="cette structure"; break;
+ case ClassDef::Union: result+="cette union"; break;
+ case ClassDef::Interface: result+="cette interface"; break;
+ case ClassDef::Protocol: result+="ce protocol"; female = false; break;
+ case ClassDef::Category: result+="cette catégorie"; break;
+ case ClassDef::Exception: result+="cette exception"; break;
+ default: break;
+ }
+ if (female) result+= " a été générée à partir ";
+ else result+=" a été généré à partir ";
+ if (single) result+="du fichier suivant :";
+ else result+="des fichiers suivants :";
+ return result;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-990901
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valeurs retournées"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Page principale"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-991003
+ //////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Définition à la ligne @0 du fichier @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Définition dans le fichier @0.";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 0.49-991205
+ //////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Obsolète";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.0.0
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Graphe de collaboration de "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graphe des dépendances par inclusion de "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Documentation des constructeurs et destructeur";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Aller au code source de ce fichier.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Aller à la documentation de ce fichier.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Précondition";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondition";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valeur initiale :";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "code";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Graphe hiérarchique des classes";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Aller au graphe hiérarchique des classes";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Aller à la hiérarchie des classes en mode texte";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Index des pages";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.1.0
+ //////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Note";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Types publics";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Champs de données";
+ }
+ else
+ {
+ return "Attributs publics";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Attributs publics statiques";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Types protégés";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Attributs protégés";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Attributs protégés statiques";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Types privés";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Attributs privés";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Attributs privés statiques";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.1.3
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "A faire";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Liste des choses à faire";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.1.4
+ //////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Référencé par";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Remarques";
+ }
+ virtual QCString trAttention()
+ {
+ return "Attention";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Ce graphe montre quels fichiers incluent directement "
+ "ou indirectement ce fichier :";
+ }
+ virtual QCString trSince()
+ {
+ return "Depuis";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.1.5
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Légende du graphe";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Cette page explique comment interpréter les graphes générés "
+ "par doxygen.<p>\n"
+ "Considérez l'exemple suivant :\n"
+ "\\code\n"
+ "/*! Classe invisible à cause d'une troncature */\n"
+ "class Invisible { };\n\n"
+ "/*! Classe tronquée, la relation d'héritage est masquée */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/*! Classe non documentée avec des commentaires Doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Classe dérivée par héritage public */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Un modèle de classe */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Classe dérivée par héritage protégé */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Classe dérivée par héritage privé */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Classe utilisée par la classe dérivée */\n"
+ "class Used { };\n\n"
+ "/*! Super-classe qui hérite de plusieurs autres classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Cela aboutira au graphe suivant :"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "Les rectangles du graphe ci-dessus ont la signification suivante :\n"
+ "<ul>\n"
+ "<li>Un rectangle plein noir représente la structure ou la classe pour laquelle "
+ "le graphe est généré.\n"
+ "<li>Un rectangle avec un bord noir indique une classe ou une structure documentée.\n"
+ "<li>Un rectangle avec un bord gris indique une classe ou une structure non documentée.\n"
+ "<li>Un rectangle avec un bord rouge indique une structure ou une classe documentée\n"
+ "pour laquelle des relations d'héritage ou de collaboration manquent. Un graphe est "
+ "tronqué s'il n'entre pas dans les limites spécifiées."
+ "</ul>\n"
+ "Les flèches ont la signification suivante :\n"
+ "<ul>\n"
+ "<li>Une flèche bleu foncé est utilisée pour visualiser une relation d'héritage publique "
+ "entre deux classes.\n"
+ "<li>Une flèche vert foncé est utilisée pour une relation d'héritage protégée.\n"
+ "<li>Une flèche rouge foncé est utilisée pour une relation d'héritage privée.\n"
+ "<li>Une flèche violette en pointillés est utilisée si une classe est contenue ou "
+ "utilisée par une autre classe. La flèche est étiquetée avec la ou les variable(s) "
+ "qui permettent d'accéder à la classe ou structure pointée. \n"
+ "<li>Une flèche jaune en pointillés indique une relation entre un modèle d'instance et "
+ "le modèle de classe duquel il est instancié. La flèche est étiquetée avec "
+ "les paramètres de modèle de l'instance.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "légende";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.0
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Liste des tests";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.2
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propriétés";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentation des propriétés";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.4
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structures de données";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paquetage "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Liste des paquetages";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Liste des paquetages avec une brève description (si disponible) :";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paquetages";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valeur :";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.5
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bogue";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Liste des bogues";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.6
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Classe" : "classe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fichier" : "fichier"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Espace" : "espace"));
+ if (!singular) result+="s";
+ result+=" de nommage";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Groupe" : "groupe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Page" : "page"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membre" : "membre"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globa" : "globa"));
+ if (!singular) result+="ux(ales)"; else result+="l(e)";
+ return result;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.7
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auteur" : "auteur"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.11
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Références";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.13
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implémente "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implémenté dans "+trWriteList(numEntries)+".";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.16
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Table des matières";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.17
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Liste des éléments obsolètes";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.2.18
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Événements";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentation des événements";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Types de paquetage";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Fonctions de paquetage";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Fonctions statiques de paquetage";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Attributs de paquetage";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Attributs statiques de paquetage";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.1
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tout";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Voici le graphe d'appel pour cette fonction :";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.3
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Résultats de la recherche";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Désolé, aucun document ne correspond à votre requête.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Trouvé <b>1</b> document correspondant à votre requête.";
+ }
+ else
+ {
+ return "Trouvé <b>$num</b> documents correspondant à votre requête. "
+ "Classé par ordre de pertinence décroissant.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Correspondances :";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.8
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return " Fichier source de " + filename;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.9
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hiérarchie de répertoires"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentation des répertoires"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Répertoires"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Cette hiérarchie de répertoire est triée approximativement, "
+ "mais pas complètement, par ordre alphabétique :";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Répertoire de référence de "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Répertoire" : "répertoire"));
+ if (singular) result+=""; else result+="s";
+ return result;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.4.1
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ceci est une fonction membre surchargée, "
+ "proposée par commodité. Elle diffère de la fonction "
+ "ci-dessus uniquement par le(s) argument(s) qu'elle accepte.";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.4.6
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Voici le graphe des appelants de cette fonction :";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentation des énumérations"; }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.5.4 (mainly for Fortran)
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentation des fonctions/subroutines membres"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Liste des types de données"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Champs de données"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Liste des types de données avec une brève description :"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Liste de tous les membres de types de données ";
+ if (!extractAll)
+ {
+ result+="documentés ";
+ }
+ result+="avec des liens vers ";
+ if (!extractAll)
+ {
+ result+="la documentation de la structure des données de chaque membre :";
+ }
+ else
+ {
+ result+="les types des données auxquels ils appartiennent :";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Index du type de données"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentation du type de données"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Fonctions/Subroutines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentation de la fonction/subroutine"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Les types de données"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Liste des modules"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les modules ";
+ if (!extractAll) result+="documentés ";
+ result+="avec une brève description :";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Réference ";
+ if (isTemplate) result+="du modèle ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="du module "; break;
+ case ClassDef::Struct: result+="du type "; break;
+ case ClassDef::Union: result+="de l'union "; break;
+ case ClassDef::Interface: result+="de l'interface "; break;
+ case ClassDef::Protocol: result+="du protocole "; break;
+ case ClassDef::Category: result+="de la catégorie "; break;
+ case ClassDef::Exception: result+="de l'exception "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Référence du module ";
+ result+= namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membres du module"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Liste de tous les membres ";
+ if (!extractAll) result+="documentés ";
+ result+="du module avec des liens vers ";
+ if (extractAll)
+ {
+ result+="la documentation du module de chaque membre :";
+ }
+ else
+ {
+ result+="les modules auxquels ils appartiennent :";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Index des modules"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La documentation de ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="ce module"; break;
+ case ClassDef::Struct: result+="ce type"; break;
+ case ClassDef::Union: result+="cette union"; break;
+ case ClassDef::Interface: result+="cette interface"; break;
+ case ClassDef::Protocol: result+="ce protocole"; break;
+ case ClassDef::Category: result+="cette catégorie"; break;
+ case ClassDef::Exception: result+="cette exception"; break;
+ default: break;
+ }
+ result+=" a été générée à partir ";
+ if (single) result+="du fichier suivant :"; else result+="des fichiers suivants :";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Type" : "type"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sous-programme" : "sous-programme"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Contraintes de type";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relation " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Chargement...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Espace de nommage global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Recherche...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Aucune correspondance";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Fichier dans "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inclut le fichier dans "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche" };
+ static const char *months[] = { "Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Références bibliographiques"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Graphe des dépendances de répertoires pour ")+name+":"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "Niveau de détails"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Paramètres du template"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "et "+number+" de plus..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "La documentation pour cette énumération a été générée à partir ";
+ if (!single) result += "du fichier suivant"; else result += "des fichiers suivants";
+ result+=" :";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Référence de l'énumération"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" hérités de "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Membres hérités additionnels"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "activer" : "désactiver";
+ return "cliquez pour "+opt+" la synchronisation du panel";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Déclarée dans la catégorie @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Dérive la classe @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Méthodes de classe";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Méthodes d'instance";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Documentation des méthodes";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Vue d'ensemble";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Interfaces exportées"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Services inclus"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Groupes constants"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result="Référence du groupe constant ";
+ result+=namespaceName;
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result="Référence du service ";
+ result+=(QCString)sName;
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result="Référence du singleton ";
+ result+=(QCString)sName;
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La documentation pour ce service "
+ "a été générée par ";
+ if (single) result+="le fichier suivant :"; else result+="les fichiers suivants :";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"La documentation pour ce singleton "
+ "a été générée par ";
+ if (single) result+="le fichier suivant :"; else result+="les fichiers suivants :";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
\ No newline at end of file
diff --git a/src/translator_gr.h b/src/translator_gr.h
new file mode 100644
index 0000000..fa7a682
--- /dev/null
+++ b/src/translator_gr.h
@@ -0,0 +1,1922 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*
+ * 15 Dec 2001 : Translation to greek by
+ * Harry Kalogirou <no email>
+ *
+ * 01 Jan 2009 : Greek maintenance by
+ * Paul Gessos <gessos.paul at yahoo.gr>
+ */
+
+#ifndef TRANSLATOR_GR_H
+#define TRANSLATOR_GR_H
+
+class TranslatorGreek : public TranslatorAdapter_1_8_4
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "greek"; }
+
+ virtual QCString latexLanguageSupportCommand()
+ {
+ //return "\\usepackage[greek,english]{babel}\n\\usepackage[iso-8859-7]{inputenc}\n";
+ return "\\usepackage[greek,english]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Σχετικές συναρτήσεις"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Σημειώστε ότι αυτές δεν είναι συναρτήσεις μέλη.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Λεπτομερής Περιγραφή"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Τεκμηρίωση Μελών Typedef"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Τεκμηρίωση Απαριθμήσεων Μελών"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Τεκμηρίωση Συναρτήσεων Μελών"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Τεκμηρίωση Πεδίων";
+ }
+ else
+ {
+ return "Τεκμηρίωση Δεδομένων Μελών";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Περισσότερα..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Λίστα όλων των μελών"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Λίστα μελών"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Ακολουθεί η πλήρης λίστα των μελών της"; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", περιλαμβανομένων όλων των κληρονομημένων μελών."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Δημιουργήθηκε αυτόματα από το Doxygen";
+ if (s) result+=(QCString)" για "+s;
+ result+=" από τον πηγαίο κώδικα.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "όνομα απαρύθμισης"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "τιμή απαρίθμησης"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "ορισμένο στο "; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Κομμάτια"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Ιεραρχία Κλάσεων"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Δομές Δεδομένων";
+ }
+ else
+ {
+ return "Λίστα Κλάσεων";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Λίστα Αρχείων"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Μέλη Δομών Δεδομένων";
+ }
+ else
+ {
+ return "Μέλη Κλάσεων";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Καθολικοί ορισμοί";
+ }
+ else
+ {
+ return "Μέλη Αρχείων";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Σχετικές Σελίδες"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Παραδείγματα"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Αναζήτηση"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Αυτή η λίστα κληρονομικότητας είναι μερικώς ταξινομημένη αλφαβητικά:"; }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Ακολουθεί μια λίστα όλων των ";
+ if (!extractAll) result+="τεκμηριωμένων ";
+ result+="αρχείων με σύντομες περιγραφές:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Ακολουθούνε οι δομές δεδομένων με σύντομες περιγραφές:";
+ }
+ else
+ {
+ return "Ακολουθούνε οι κλάσεις, δομές, "
+ "ενώσεις και οι διασυνδέσεις με σύντομες περιγραφές:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Ακολουθεί η λίστα όλων των ";
+ if (!extractAll)
+ {
+ result+="τεκμηριωμένων ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="μελών δομών δεδομένων και ενώσεων ";
+ }
+ else
+ {
+ result+="κλάσεων";
+ }
+ result+=" με συνδέσμους ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="στην τεκμηρίωση των δομών/ενώσεων για κάθε πεδίο:";
+ }
+ else
+ {
+ result+="στην τεκμηρίωση των κλάσεων για κάθε πεδίο:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="στις δομές/ενώσεις που ανήκουν:";
+ }
+ else
+ {
+ result+="στις κλάσεις που ανήκουν:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Ακολουθεί η λίστα όλων των ";
+ if (!extractAll) result+="τεκμηριωμένων ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="συναρτήσεων, μεταβλητών, ορισμών, απαριθμήσεων, και ορισμών τύπων";
+ }
+ else
+ {
+ result+="μελών αρχείων";
+ }
+ result+=" με συνδέσμους ";
+ if (extractAll)
+ result+="στα αρχεία που ανήκουν:";
+ else
+ result+="στην τεκμηρίωση:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Ακολουθεί η λίστα με τα παραδείγματα:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Ακολουθεί η λίστα όλων των σχετικών σελίδων τεκμηρίωσης:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Ακολουθεί η λίστα όλων των μονάδων:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Τεκμηρίωση"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Ευρετήριο μονάδων"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Ιεραρχικό Ευρετήριο"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Ευρετήριο δομών δεδομένων";
+ }
+ else
+ {
+ return "Συμπαγές Ευρετήριο";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Ευρετήτιο Αρχείων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Τεκμηρίωση Μονάδων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Τεκμηρίωση Δομών Δεδομένων";
+ }
+ else
+ {
+ return "Τεκμηρίωση Κλάσεων";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Τεκμηρίωση Αρχείων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Τεκμηρίωση Παραδειγμάτων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Τεκμηρίωση Σελίδων"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Εγχειρίδιο Αναφοράς"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Ορισμοί"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Ορισμοί Τύπων"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Απαριθμήσεις"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Συναρτήσεις"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Μεταβλητές"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Τιμές Απαριθμήσεων"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Τεκμηρίωση Ορισμών"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Τεκμηρίωση Ορισμών Τύπων"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Τεκμηρίωση Απαριθμήσεων"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Τεκμηρίωση Συναρτήσεων"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Τεκμηρίωση Μεταβλητών"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Δομές Δεδομένων";
+ }
+ else
+ {
+ return "Κλάσεις";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Δημιουργήθηκε στις "+date;
+ if (projName) result+=(QCString)" για "+projName;
+ result+=(QCString)" από";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Διάγραμμα κληρονομικότητας για την "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Μόνο για εσωτερική χρήση."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Προειδοποίηση"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Έκδοση"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Ημ/νια"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Επιστρέφει"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Κοιτάξτε επίσης "; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Παράμετροι"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Εξαίρεση"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Δημιουργήθηκε από "; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Λίστα Χώρων Ονομάτων"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Ακολουθέι η λίστα όλων των ";
+ if (!extractAll) result+="τεκμηριωμένων ";
+ result+="Χώρων Ονομάτων με σύντομες περιγραφές:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Φίλοι"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Τεκμηρίωση Φιλικών και Συσχετιζόμενων Συναρτήσεων"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)"Αναφορά";
+ if (isTemplate) result+=" Προτύπου";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Κλάσης "; break;
+ case ClassDef::Struct: result+=" Δομής "; break;
+ case ClassDef::Union: result+=" Ένωσης "; break;
+ case ClassDef::Interface: result+=" Διασύνδεσης "; break;
+ case ClassDef::Protocol: result+=" Πρωτοκόλλου "; break;
+ case ClassDef::Category: result+=" Κατηγορίας "; break;
+ case ClassDef::Exception: result+=" Εξαίρεσης "; break;
+ default: break;
+ }
+ result+=clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result="Αναφορά Αρχείου ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Αναφορά Χώρου Ονομάτων ";
+ result+=namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Δημόσιες Μέθοδοι"; }
+ virtual QCString trPublicSlots()
+ { return "Δημόσια Slots"; }
+ virtual QCString trSignals()
+ { return "Σήματα"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Στατικές Δημόσιες Μέδοδοι"; }
+ virtual QCString trProtectedMembers()
+ { return "Προστατευμένες Μέδοδοι"; }
+ virtual QCString trProtectedSlots()
+ { return "Προστατευμένα Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Στατικές Προστατευμένες Μέδοδοι"; }
+ virtual QCString trPrivateMembers()
+ { return "Ιδιωτικές Μέθοδοι"; }
+ virtual QCString trPrivateSlots()
+ { return "Ιδιοτικά Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Στατικές Ιδιωτικές Μέθοδοι"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", και ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Κληρονομεί "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Κληρονομείται από "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Επαναϋλοποιείται από "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Επαναϋλοποιείται στην "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Μέλη Χώρου Ονομάτων"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Ακολουθεί η λίστα όλων των ";
+ if (!extractAll) result+="τεκμηριωμένων ";
+ result+="μελών χώρων ονομάτων με συνδέσμους ";
+ if (extractAll)
+ result+="στην τεκμηρίωση του χώρου ονομάτων για κάθε μέλος:";
+ else
+ result+="στους χώρους ονομάτων που ανήκουν:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Ευρετήριο Χώρων Ονομάτων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Τεκμηρίωση Χώρων Ονομάτων"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Χώροι Ονομάτων"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Η τεκμηρίωση για ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="αυτή την κλάση"; break;
+ case ClassDef::Struct: result+="αυτή τη δομή"; break;
+ case ClassDef::Union: result+="αυτή την ένωση"; break;
+ case ClassDef::Interface: result+="αυτή τη διασύνδεση"; break;
+ case ClassDef::Protocol: result+="αυτό το πρωτόκολλο"; break;
+ case ClassDef::Category: result+="αυτή την κατηγορία"; break;
+ case ClassDef::Exception: result+="αυτή την εξαίρεση"; break;
+ default: break;
+ }
+ result+=" δημιουργήθηκε απο τ";
+ if (single) result+="ο ακόλουθο αρχείο:"; else result+="α ακόλουθα αρχεία:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Τιμές Επιστροφής"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Κύρια Σελίδα"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "σελ."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Ορισμός στη γραμμή @0 του αρχείου @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Ορισμός στο αρχείο @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Αποσυρμένο";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Δίαγραμμα Συνεργασίας για την κλάση "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Διάγραμμα εξάρτησης αρχείου συμπερίληψης για το "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Τεκμηρίωση Constructor & Destructor";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Πήγαινε στον πηγαίο κώδικα του αρχείου.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Πήγαινε στην τεκμηρίωση του αρχείου.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Προϋποθέσεις";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Μεταϋποθέσεις";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Αμετάβλητα";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Αρχική τιμή:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "κώδικας";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Γραφική Αναπαράσταση Της Ιεραρχίας Των Κλάσεων";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Πήγαινε στην γραφική αναπαράσταση της ιεραρχίας των κλάσεων";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Πήγαινε στην με κείμενο αναπαράσταση της ιεραρχίας των κλάσεων";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Ευρετήριο Σελίδων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Σημείωση";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Δημόσιοι Τυποι";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Πεδία Δεδομένων";
+ }
+ else
+ {
+ return "Δημόσια Χαρακτηριστικά";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Στατικά Δημόσια Χαρακτηριστικά";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Προστατευμένοι Τύποι";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Προστατευμένα Χαρακτηριστικά";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Στατικά Προστατευμένα Χαρακτηριστικά";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Ιδιωτικοί Τύποι";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Ιδιωτικα Χαρακτηριστικά";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Στατικά Ιδιωτικα Χαρακτηριστικά";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Προς Υλοποίηση";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Λίστα των Προς Υλοποίηση";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Αναφορά από";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Παρατήρηση";
+ }
+ virtual QCString trAttention()
+ {
+ return "Προσοχή";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Το διάγραμμα αυτό παρουσιάζει ποιά αρχεία άμεσα ή "
+ "έμμεσα περιλαμβάνουν αυτό το αρχείο:";
+ }
+ virtual QCString trSince()
+ {
+ return "Από";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Υπόμνημα Διαγραμμάτων";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Αυτή η σελίδα εξηγεί το πως ερμηνεύονται τα διαγράμματα που δημιουργούνται "
+ "από το doxygen.<p>\n"
+ "Θεωρείστε το παρακάτω παράδειγμα:"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Αυτό οδηγεί στο επόμενο διάγραμμα:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "Τα κουτιά στο παραπάνω διάγραμμα έχουν την ακόλουθη σημασία:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Ένα γεμισμένο μαύρο κουτί αναπαριστά τη δομή ή την κλάση για την οποία"
+ "αφορά το διάγραμμα.\n"
+ "<li>Ένα κουτί με μαύρο περίγραμμα αναπαριστά μία τεκμηριωμένη δομή ή κλάση.\n"
+ "<li>Ένα κουτί με γκρίζο περίγραμμα αναπαριστά μία μη τεκμηριωμένη δομή ή κλάση.\n"
+ "<li>Ένα κουτί με κόκκινο περίγραμμα αναπαριστά μία τεκμηριωμένη δομή ή κλάση για "
+ "την οποία δεν παρουσιάζονται όλες οι σχέσεις κληρονομικότητας και περιεχομένου. %Ένα "
+ "διάγραμμα μειώνεται αν δεν χωράει στις ορισμένες διαστάσεις."
+ "</ul>\n"
+ "<p>\n"
+ "Τα βέλη έχουν τις ακόλουθες σημασίες:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Ένα βαθύ μπλε βέλος χρησιμοποιείται για να παρουσιάσει μία δημόσια σχέση κληρονομικότητας "
+ "μεταξύ δύο κλάσεων.</li>\n"
+ "<li>Ένα βαθύ πράσινο βέλος χρησιμοποιείται για προστατευμένη κληρονομικότητα.</li>\n"
+ "<li>Ένα βαθύ κόκκινο βέλος χρησιμοποιείται για ιδιωτική κληρονομικότητα.</li>\n"
+ "<li>Ένα μωβ διακεκομένο βέλος χρησιμοποιείται αν μία κλάση περιέχεται ή χρησιμοποιείται "
+ "από μία άλλη κλάση. Το βέλος ονομάζεται από το όνομα της μεταβλητής(ων) "
+ "μέσω της οποίας η κλάση ή δομή είναι προσβάσιμη.</li>\n"
+ "<li>Ένα κίτρινο διακεκομμένο βέλος χρησιμοποιείται για μια σχέση μεταξύ ενός template αντικειμένου και "
+ "της template κλάσης από την οποία δημιουργήθηκε. Το βέλος ονομάζεται με τις παραμέτρους του template "
+ "του αντικειμένου.</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "υπόμνημα";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Δοκιμαστικό";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Λίστα Δοκιμαστικών";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Ιδιότητες";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Τεκμηρίωση Ιδιοτήτων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Δομές Δεδομένων";
+ }
+ else
+ {
+ return "Κλάσεις";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Πακέτο "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Λίστα Πακέτων";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Ακολουθεί η λίστα των πακέτων με σύντομη περιγραφή (αν υπάρχει):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Πακέτα";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Τιμή:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Πρόβλημα";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Λίστα Προβλημάτων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1253";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "161";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Ευρετήριο";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Κλάση" : "κλάση"));
+ if (!singular) result+="";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Αρχεί" : "αρχεί"));
+ if (!singular) result+="α"; else result+="ο";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ομάδ" : "ομάδ"));
+ if (!singular) result+="ες"; else result+="α";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Σελίδ" : "σελίδ"));
+ if (!singular) result+="ες"; else result+="α";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Μέλ" : "μέλ"));
+ if (!singular) result+="η"; else result+="ος";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Καθολικ" : "καθολικ"));
+ if (!singular) result+="ές"; else result+="ή";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Συγραφ" : "συγραφ"));
+ if (!singular) result+=""; else result+="έας";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Αναφορές";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Υλοποιεί "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Υλοποιείται από "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Πίνακας Περιεχομένων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Λίστα Καταργημένων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Συμβάντα";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Τεκμηρίωση Συμβάντων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Τύποι Πακέτων";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Συναρτήσεις Πακέτου";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Στατικές Συναρτήσεις Πακέτου";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Μεταβλητές Πακέτου";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Στατικές Μεταβλητές Πακέτου";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Όλα";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Το διάγραμμα δείχνει ποιές συναρτήσεις καλούνται από αυτή:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Αποτελέσματα Αναζήτησης";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Συγγνώμη, δεν υπάρχει κείμενο που να ταιριάζει με την αίτησή σας.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Βρέθηκε <b>1</b> κείμενο που ταιριάζει με την αίτησή σας.";
+ }
+ else
+ {
+ return "Βρέθηκαν <b>$num</b> κείμενα που ταιριάζουν με την αίτησή σας. "
+ "Πρώτα εμφανίζονται τα κείμενα που ταιριάζουν πιο πολύ.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Ταίριαξαν:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Αρχείο κώδικα " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Ιεραρχία Καταλόγου"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Τεκμηρίωση Καταλόγου"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Κατάλογοι"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ {
+ return "Η ιεραρχία καταλόγων ταξινομήθηκε αλφαβητικά, αλλά όχι πολύ αυστηρά:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=QCString("Αναφορά του Καταλόγου ") + dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Κατάλογο" : "κατάλογο"));
+ if (singular) result+="ς"; else result+="ι";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Αυτή είναι μια υπερφορτωμένη συνάρτηση-μέλος, "
+ "που παρέχεται για ευκολία. Διαφέρει από την παραπάνω "
+ "συνάρτηση μόνο στον τύπο των παραμέτρων που δέχεται.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Το διάγραμμα δείχνει από ποιές συναρτήσεις καλείται αυτή η συνάρτηση:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerator Documentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Τεκμηρίωση Συνάρτησης/Υπορουτίνας Μέλους"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Λίστα Τύπων Δεδομένων"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Πεδία Δεδομένων"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Εδώ είναι οι τύποι δεδομένων με σύντομη περιγραφή:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Εδώ είναι η λίστα όλων των ";
+ if (!extractAll)
+ {
+ result+="τεκμηριωμένων ";
+ }
+ result+="μελών τύπων δεδομένων";
+ result+=" με συνδέσεις ";
+ if (!extractAll)
+ {
+ result+="στην τεκμηρίωση της δομής δεδομένων για κάθε μέλος";
+ }
+ else
+ {
+ result+="στους τύπους δεδομένων που ανήκουν:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Περιεχόμενα Τύπων Δεδομένων"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Τεκμηρίωση Τύπων Δεδομένων"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Συναρτήσεις/Υπορουτίνες"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Τεκμηρίωση Συνάρτησης/Υπορουτίνας"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Τύποι Δεδομένων"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Λίστα Υπομονάδων"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Εδώ είναι μια λίστα με όλες τις ";
+ if (!extractAll) result+="τεκμηριωμένες ";
+ result+="υπομονάδες με σύντομή περιγραφή:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Υπομονάδα"; break;
+ case ClassDef::Struct: result+=" Τύπος"; break;
+ case ClassDef::Union: result+=" Ένωση"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Πρωτόκολλο"; break;
+ case ClassDef::Category: result+=" Κατηγορία"; break;
+ case ClassDef::Exception: result+=" Εξαίρεση"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Πρότυπο";
+ result+=" Δήλωση";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Δηλώσεις Υπομονάδων";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Υπομονάδες Μέλη"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Εδώ είναι μια λίστα με όλες τις ";
+ if (!extractAll) result+="τεκμηριωμένες ";
+ result+="μέλη υπομονάδες με συνδέσεις ";
+ if (extractAll)
+ {
+ result+="στην τεκμηρίωση της υπομονάδας για κάθε μέλος:";
+ }
+ else
+ {
+ result+="στις υπομονάδες που ανήκουν:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Περιεχόμενα Υπομονάδων"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Υπομονάδ" : "υπομονάδ"));
+ if (!singular) result+="ες"; else result+="α";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Η τεκμηρίωση για ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="αυτή την υπομονάδα"; break;
+ case ClassDef::Struct: result+="αυτό τον τύπο δεδομένων"; break;
+ case ClassDef::Union: result+="αυτή την ένωση"; break;
+ case ClassDef::Interface: result+="αυτό το interface"; break;
+ case ClassDef::Protocol: result+="αυτό το πρωτόκολλο"; break;
+ case ClassDef::Category: result+="αυτή την κατηγορία"; break;
+ case ClassDef::Exception: result+="αυτή την εξαίρεση"; break;
+ default: break;
+ }
+ result+=" δημιουργήθηκε από ";
+ if (single) result+="το παρακάτω αρχείο:"; else result+="τα παρακάτω αρχεία:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Τύπο" : "τύπο"));
+ if (!singular) result+="ι"; else result+="ος";
+ result+= first_capital ? " Δεδομένων" : " δεδομένων";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Υποπρ" : "υποπρ"));
+ if (!singular) result+="ογράμματα"; else result+="όγραμμα";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Περιορισμοί Τύπων Δεδομένων";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Σχέση του "+QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Φόρτωση...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Γενικός χώρος ονομάτων";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Αναζήτηση...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Δεν βρέθηκαν αποτελέσματα αναζήτησης";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Αρχείο σε "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Εσωκλείει το αρχείο στο "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ","Κυρ" };
+ static const char *months[] = { "Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ" };
+ QCString sdate;
+ sdate.sprintf("%s %.2d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Αναφορές Βιβλιογραφίας"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Διάγραμμα εξάρτησης φακέλων για ")+name+":"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "Επίπεδο λεπτομέρειας"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Παράμετροι Προτύπου"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "και "+number+" ακόμη..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Η τεκμηρίωση αυτής της απαρίθμησης δημιουργήθηκε από ";
+ if (single) result += "τo αρχείo"; else result += "τα αρχεία";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString("Αναφορά Απαρίθμησης ") + QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" κληρονόμησαν από "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Επιπρόσθετες Κληρονομημένες Μέθοδοι"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "ενεργοποιήσετε" : "απενεργοποιήσετε";
+ return "Κάντε κλικ για να "+opt+" το συγχρονισμό του παραθύρου";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Παρέχεται από την κατηγορία @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Κληρονομει την κλάση @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Μέθοδοι Κλάσης";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Μέθοδοι Αντικειμένου";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Τεκμηρίωση Μεθόδου";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Επισκόπηση σχεδίασης";
+ }
+
+
+/* Future strategy of changes
+ Many words have more clear meaning in English and not in Greek:
+ template -> πρότυπο
+ instance -> αντικείμενο? (μπορεί να μιλάμε για template instantiation ή class instantiation)
+ interface -> διασύνδεση
+*/
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_hr.h b/src/translator_hr.h
new file mode 100644
index 0000000..70dba21
--- /dev/null
+++ b/src/translator_hr.h
@@ -0,0 +1,1576 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+*/
+// translation by Boris Bralo <boris.bralo at gmail.com>
+// Updates:
+// --------
+// 2000/08/20
+// - Better handling of ISO-8859-2/ WIN 1250 stuff based on (actually stolen from :-)) Czech translations
+// implemented by Petr Prikryl (prikrylp at skil.cz).
+// As opposed to Czech translation this one assumes that Doxygen strings are written in Linux ( it's true,
+// I don't have QT pro licence ) , and uses ISOToWin function when built in WIN32
+//
+// 2000/09/18
+// - Added strings from 1.2.1
+// - Removed unneeeded decode() calls
+// - Changed some CS terminology
+//
+// 2001/01/22
+// - Added strings from 1.2.4
+//
+// 2001/05/25
+// - Added strings and up to and including 1.2.7_20010524
+// - Removed obsolete method trFiles()
+// - Removed obsolete method trAuthor()
+// - Removed obsolete method trAuthor()
+// - Removed obsolete method trVerbatimHeadert()
+// - Method latexBabelPackage() removed, ude latexLanguageSupportCommand
+//
+// 2001/11/13
+// - inherits from Translator
+// - Added strings for 1.2.11
+// - better output for C documentation (trCompoundMembersDescription(), trClassDocumentation())
+//
+// 2001/11/13
+// - Added strings for 1.2.13
+//
+// 2003/02/26
+// - Added strings for 1.2.18
+//
+// 2003/04/29
+// - Added strings for 1.3.0
+//
+// 2004/06/21
+// - Added strings for 1.3.8
+//
+// 2004/09/15
+// - Added strings for 1.3.9
+//
+// 2005/02/28
+// - Removed obsolete (unused) methods
+//
+// 2005/03/21
+// - Added strings for 1.4.1
+//
+// 2006/06/11
+// - Added strings for 1.4.6
+//
+// 2009/01/09
+// - Updated trLegendDocs
+//
+// 2010/03/04
+// - Updates for "new since 1.6.0 (mainly for the new search engine)".
+// - UTF-8
+// - removed decode()
+//
+// 2010/05/27
+// - Updates for 1.6.3
+// 2012/04/12
+// - Updates for 1.8.0
+#ifndef TRANSLATOR_HR_H
+#define TRANSLATOR_HR_H
+
+class TranslatorCroatian : public TranslatorAdapter_1_8_2
+{
+ private:
+
+ public:
+ QCString idLanguage()
+ { return "croatian"; }
+ QCString latexLanguageSupportCommand()
+ { return "\\usepackage[croatian]{babel}\n"; }
+ QCString trRelatedFunctions()
+ { return "Povezane funkcije"; }
+ QCString trRelatedSubscript()
+ { return "(To nisu member funkcije.)"; }
+ QCString trDetailedDescription()
+ { return "Detaljno objašnjenje"; }
+ QCString trMemberTypedefDocumentation()
+ { return "Dokumentacija typedef članova"; }
+ QCString trMemberEnumerationDocumentation()
+ { return "Dokumentacija enumeracijskih članova"; }
+ QCString trMemberFunctionDocumentation()
+ { return "Dokumentacija funkcija"; }
+ QCString trMemberDataDocumentation()
+ { return "Documentacija varijabli"; }
+ QCString trMore()
+ { return "Opširnije..."; }
+ QCString trListOfAllMembers()
+ { return "Popis svih članova"; }
+ QCString trMemberList()
+ { return "Popis članova."; }
+ QCString trThisIsTheListOfAllMembers()
+ { return "Ovo je popis svih članova"; }
+ QCString trIncludingInheritedMembers()
+ { return ", uključujući naslijeđene članove."; }
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result="napravljeno automatski Doxygen-om";
+ if (s) result+=(QCString)" za "+s;
+ result+=" iz programskog koda.";
+ return result;
+ }
+ QCString trEnumName()
+ { return "enum ime"; }
+ QCString trEnumValue()
+ { return "enum vrijednost"; }
+ QCString trDefinedIn()
+ { return "definirano u"; }
+ QCString trModules()
+ { return "Moduli"; }
+ QCString trClassHierarchy()
+ { return "Stablo klasa"; }
+ QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Sve strukture";
+ }
+ else
+ {
+ return "Sve klase";
+ }
+ }
+ QCString trFileList()
+ { return "Popis datoteka"; }
+ QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ return "Svi članovi struktura";
+ else
+ return "Svi članovi klasa";
+ }
+ QCString trFileMembers()
+ { return "članovi klasa u datoteci"; }
+ QCString trRelatedPages()
+ { return "Stranice povezane s ovom"; }
+ QCString trExamples()
+ { return "Primjeri"; }
+ QCString trSearch()
+ { return "Traži"; }
+ QCString trClassHierarchyDescription()
+ { return "Stablo naslijeđivanja je složeno "
+ "približno po abecedi:";
+ }
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Popis svih ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="datoteka, s kratkim opisom:";
+ return result;
+ }
+ QCString trCompoundListDescription()
+ { return "Popis svih klasa, unija i struktura "
+ "s kratkim opisom :";
+ }
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Popis svih ";
+ if (!extractAll)
+ result+="dokumentiranih ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="članova klasa s linkovima na ";
+ else
+ result+="članova struktura s linkovima na ";
+
+ if (!extractAll)
+ {
+ result+="dokumentaciju svakog člana:";
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="dokumentaciju klase :";
+ else
+ result +="dokumentaciju strukture";
+ }
+ return result;
+ }
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Popis svih ";
+ if (!extractAll)
+ result+="dokumentiranih ";
+ result+="članova s linkovima na ";
+ if (extractAll)
+ result+="dokumentaciju datoteke u kojima se nalaze:";
+ else
+ result+="datoteke u kojima se nalaze:";
+ return result;
+ }
+ QCString trExamplesDescription()
+ { return "Popis primjera :"; }
+ QCString trRelatedPagesDescription()
+ { return "Popis povezanih stranica:"; }
+ QCString trModulesDescription()
+ { return "Popis svih modula:"; }
+
+ QCString trDocumentation()
+ { return "Dokumentacija"; }
+ QCString trModuleIndex()
+ { return "Kazalo modula"; }
+ QCString trHierarchicalIndex()
+ { return "Hijerarhijsko kazalo"; }
+ QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Kazalo struktura podataka";
+ }
+ else
+ {
+ return "Skupno kazalo ";
+ }
+ }
+ QCString trFileIndex()
+ { return "Kazalo datoteka"; }
+ QCString trModuleDocumentation()
+ { return "Dokumentacija modula"; }
+ QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentacija struktura podataka";
+ }
+ else
+ {
+ return "Dokumentacija klasa";
+ }
+ }
+ QCString trFileDocumentation()
+ { return "Dokumentacija datoteka"; }
+ QCString trExampleDocumentation()
+ { return "Dokumentacija primjera"; }
+ QCString trPageDocumentation()
+ { return "Dokumentacija vezane stranice"; }
+ QCString trReferenceManual()
+ { return "Priručnik"; }
+
+ QCString trDefines()
+ { return "Definicije"; }
+ QCString trTypedefs()
+ { return "Typedef-ovi"; }
+ QCString trEnumerations()
+ { return "Enumeracije"; }
+ QCString trFunctions()
+ { return "Funkcije"; }
+ QCString trVariables()
+ { return "Varijable"; }
+ QCString trEnumerationValues()
+ { return "Vrijednosti enumeracija"; }
+ QCString trDefineDocumentation()
+ { return "Dokumentacija definicija"; }
+ QCString trTypedefDocumentation()
+ { return "Dokumentacija typedef-a"; }
+ QCString trEnumerationTypeDocumentation()
+ { return "Dokumentacija enumeracijskog tipa"; }
+ QCString trFunctionDocumentation()
+ { return "Dokumentacije funkcija"; }
+ QCString trVariableDocumentation()
+ { return "Dokumentacija varijable"; }
+ QCString trCompounds()
+ { return "Strukture"; }
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Napravljeno "+date;
+ if (projName) result+=(QCString)" projekt: "+projName;
+ result+=" generator: ";
+ return result;
+ }
+ QCString trClassDiagram(const char *clName)
+ {
+ return QCString("Dijagram klasa za ")+clName;
+ }
+ QCString trForInternalUseOnly()
+ { return "Isključivo za internu uporabu."; }
+ QCString trWarning()
+ { return "Upozorenje"; }
+ QCString trVersion()
+ { return "Verzija"; }
+ QCString trDate()
+ { return "Datum"; }
+ QCString trReturns()
+ { return "Povratne vrijednosti"; }
+ QCString trSeeAlso()
+ { return "Vidi također"; }
+ QCString trParameters()
+ { return "Parametri"; }
+ QCString trExceptions()
+ { return "Iznimke"; }
+ QCString trGeneratedBy()
+ { return "Generirao"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNamespaceList()
+ { return "Popis imenika"; }
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Popis svih ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="imenika s kratkim opisom:";
+ return result;
+ }
+ QCString trFriends()
+ { return "Friend-ovi "; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trRelatedFunctionDocumentation()
+ { return "Dokumentacija povezanih funkcija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool /*isTemplate*/)
+ // used as the title of the HTML page of a class/struct/union
+ {
+ QCString result="Opis ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" klase "; break;
+ case ClassDef::Struct: result+=" strukture "; break;
+ case ClassDef::Union: result+=" unije "; break;
+ case ClassDef::Interface: result+=" sučelja (interface) "; break;
+ case ClassDef::Protocol: result+=" protokola "; break;
+ case ClassDef::Category: result+=" kategorije "; break;
+ case ClassDef::Exception: result+=" iznimke (exception) "; break;
+ default: break;
+ }
+ result += clName;
+ return result;
+ }
+ QCString trFileReference(const char *fileName)
+ // used as the title of the HTML page of a file
+ {
+ QCString result="Opis datoteke ";
+ result+=fileName;
+ return result;
+ }
+ QCString trNamespaceReference(const char *namespaceName)
+ // used as the title of the HTML page of a namespace
+ {
+ QCString result ="Opis imenika ";
+ result+=namespaceName;
+
+ return result;
+ }
+
+ // these are for the member sections of a class, struct or union
+ QCString trPublicMembers()
+ { return "Public članovi"; }
+ QCString trPublicSlots()
+ { return "Public slotovi"; }
+ QCString trSignals()
+ { return "Signali"; }
+ QCString trStaticPublicMembers()
+ { return "Static public članovi"; }
+ QCString trProtectedMembers()
+ { return "Protected članovi"; }
+ QCString trProtectedSlots()
+ { return "Protected slotovi"; }
+ QCString trStaticProtectedMembers()
+ { return "Static protected članovi"; }
+ QCString trPrivateMembers()
+ { return "Privatni članovi"; }
+ QCString trPrivateSlots()
+ { return "Privatni slotovi"; }
+ QCString trStaticPrivateMembers()
+ { return "Statični privatni članovi"; }
+ // end of member sections
+
+ QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+="";
+ }
+ }
+ return result;
+ }
+
+ QCString trInheritsList(int numEntries)
+ // used in class documentation to produce a list of base classes,
+ // if class diagrams are disabled.
+ {
+ return "Naslijeđuje od "+trWriteList(numEntries)+".";
+ }
+ QCString trInheritedByList(int numEntries)
+ // used in class documentation to produce a list of super classes,
+ // if class diagrams are disabled.
+ {
+ return "Naslijeđena u "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedFromList(int numEntries)
+ // used in member documentation blocks to produce a list of
+ // members that are hidden by this one.
+ {
+ return "Reimplementirano od "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedInList(int numEntries)
+ {
+ // used in member documentation blocks to produce a list of
+ // all member that overwrite the implementation of this member.
+ return "Reimplementacija u "+trWriteList(numEntries)+".";
+ }
+
+ QCString trNamespaceMembers()
+ // This is put above each page as a link to all members of namespaces.
+ { return "članovi imenika"; }
+ QCString trNamespaceMemberDescription(bool extractAll)
+ // This is an introduction to the page with all namespace members
+ {
+ QCString result="Lista svih ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="članova imenika s linkovima na ";
+ if (extractAll)
+ result+="imeničku dokumentaciju svakog člana:";
+ else
+ result+="imenike kojima pripadaju:";
+ return result;
+ }
+ QCString trNamespaceIndex()
+ // This is used in LaTeX as the title of the chapter with the
+ // index of all namespaces.
+ { return "Kazalo imenika"; }
+ QCString trNamespaceDocumentation()
+ // This is used in LaTeX as the title of the chapter containing
+ // the documentation of all namespaces.
+ { return "Dokumentacija namespace-a"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ QCString trNamespaces()
+ {
+ return "Imenici";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result="Dokumentacija ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klase"; break;
+ case ClassDef::Struct: result+="strukture"; break;
+ case ClassDef::Union: result+="unije"; break;
+ case ClassDef::Interface: result+="sučelja (interface)"; break;
+ case ClassDef::Protocol: result+="protokola"; break;
+ case ClassDef::Category: result+="kategorije"; break;
+ case ClassDef::Exception: result+="iznimke (exception)"; break;
+ default: break;
+ }
+ result+=" je napravljena iz " + trFile(FALSE, single) + ": ";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "Povratna vrijednost"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "Glavna stranica"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "str."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definirano u liniji @0 datoteke @1.";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "Definirano u datoteci @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Zastarjelo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Kolaboracijski dijagram za "+clName+ ":";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graf include međuovisnosti za "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "Dokumentacija konstruktora i destruktora ";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "Izvorni kod";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "Dokumenacija za ovu datoteku.";
+ }
+ /*! Text for the \\pre command */
+ QCString trPrecondition()
+ {
+ return "Preduvjeti";
+ }
+ /*! Text for the \\post command */
+ QCString trPostcondition()
+ {
+ return "Postuvjeti";
+ }
+ /*! Text for the \\invariant command */
+ QCString trInvariant()
+ {
+ return "Invarijanta";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "Početna vrijednost:";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "kod";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Grafičko stablo klasa";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "Grafičko stablo klasa";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "Tekstualno stablo klasa";
+ }
+ QCString trPageIndex()
+ {
+ return "Indeks stranice";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "Primjedba";
+ }
+ QCString trPublicTypes()
+ {
+ return "Public tipovi";
+ }
+ QCString trPublicAttribs()
+ {
+ return "Public atributi";
+ }
+ QCString trStaticPublicAttribs()
+ {
+ return "Static public atributi";
+ }
+ QCString trProtectedTypes()
+ {
+ return "Protected tipovi";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "Protected atributi";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "Static protected atributi";
+ }
+ QCString trPrivateTypes()
+ {
+ return "Private tipovi";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "Private atributi";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "Static private atributi";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Za uraditi";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Ostalo za uraditi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referencirano od";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Napomene";
+ }
+ virtual QCString trAttention()
+ {
+ return "Pažnja";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Ovaj graf pokazuje koje datoteke izravno "
+ "ili neizravno uključuju ovu datoteku:";
+ }
+ virtual QCString trSince()
+ {
+ return "Od";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Ova stranica objašnjava kako interpretirati grafikone koje je generirao "
+ "doxygen.<p>\n"
+ "Na primjer:\n"
+ "\\code\n"
+ "/*! Nevidljiva klasa (neće stati na graf date visine) */\n"
+ "class Invisible { };\n\n"
+ "/*! Odrezana klasa, inheritance je skriven (klase se vidi na grafu, ali ne i sve bazne klase) */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Nedokumentirana klasa */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klasa koja je naslijeđena public */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasa koje je naslijeđena protected */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klasa koje je naslijeđena private */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klasa koja se koristi agregacijom */\n"
+ "class Used { };\n\n"
+ "/*! Super klasa koja naslijeđuje/koristi ostale */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "To će rezultirati grafikonom:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Pravokutnici imaju slijedeće značenje:\n"
+ "<ul>\n"
+ "<li>Puni crni predstavlja klasu za koji je napravljen graf.\n"
+ "<li>Pravokutnik s crnim rubom predstavlja dokumentiranu klasu.\n"
+ "<li>Pravokutnik s sivim rubom predstavlja nedokumentiranu klasu.\n"
+ "<li>Pravokutnik s crvenim rubom predstavlja dokumentiranu klasu\n"
+ "Za koju nije prikazan graf naslijeđivanja. Graf je odrezan "
+ "ako ne stane unutar određenih granica."
+ "</ul>\n"
+ "Strelice imaju slijedeće značenje:\n"
+ "<ul>\n"
+ "<li>Tamnoplava strelica označava public naslijeđivanje.\n"
+ "<li>Tamnozelena strelica označava protected naslijeđivanje.\n"
+ "<li>Tamnocrvena strelica označava private naslijeđivanje.\n"
+ "<li>Ljubičasta isprekidana strelica se koristi ako je klasa dio "
+ "druge klase ili ako se klasa koristi u drugoj klasi. Natpis na "
+ "strelici je ime varijable u drugoj klasi\n"
+ "Strelica je označena imenom varijable.\n"
+ "<li>Žuta isprekidana strelica označava relaciju između template instance "
+ "i template klase. Označena je imenom template parametra\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test lista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Svojstva (property)";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentacija svojstava";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ return "Klase";
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista paketa";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Paketi s kratkim opisom (ukoliko postoji):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paketi";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Vrijednost:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Greška";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Popis grešaka";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Sadržaj";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klas" : "klas"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Datotek" : "datotek"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result;
+ if (singular)
+ result = ((first_capital ? "Imenik" : "imenik"));
+ else
+ result = ((first_capital ? "Imenici" : "imenici"));
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grup" : "grup"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stranic" : "stranic"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "član" : "član"));
+ if (!singular) result+="ovi";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "G" : "g"));
+ if( singular )
+ result += "lobalna varijabla";
+ else
+ result += "lobalne varijable";
+
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Reference";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementira "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementirano u "+trWriteList(numEntries)+".";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Sadržaj";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Popis zastarjelih metoda";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Događaji";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentacija događaja";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipovi u paketu";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkcije u paketu";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statičke funkcije u paketu";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributi u paketu";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statički atributi u paketu";
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.1
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Sve";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Ovo je dijagram poziva za ovu funkciju:";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.3.3
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Rezultati pretrage";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Nema dokumenta koji odgovaraju vašem upitu";
+ }
+ else if (numDocuments==1)
+ {
+ return "Nađen <b>1</b> dokument koji odgovara vašem upitu.";
+ }
+ else if (numDocuments<5)
+ {
+ // Croatian (AFAIK all Slavic languages except Macedonian and Bulgarian)
+ // have different plural form for 2,3,4.
+ return "Nađena <b>$num</b> dokumenta koji odgovaraju vašem upitu."
+ "Najbolji su prikazani prvi.";
+ }
+ else
+ {
+ return "Nađeno <b>$num</b> dokumenata koji odgovaraju vašem upitu."
+ "Najbolji su prikazani prvi.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Pronađeno:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Izvorni kod datoteke " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Stablo direktorija"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentacija direktorija"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Direktoriji"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Stablo direktorija sortirano abecednim redom:"; }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result= "Opis direktorija "; result += dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Direktorij" : "direktorij"));
+ if (!singular) result+="i";
+ return result;
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ovo je preopterećena funkcija (overload). "
+ "Razlikuje se od navedene metode "
+ "samo po vrsti argumenata koje prihvaća.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Ovo je graf funkcija koje pozivaju ovu funkciju:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentacija enumeracija"; }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentacija member funkcija/subrutina"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista tipova podataka"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Polja"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Tipovi podataka s kratkim opisom:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Lista svih ";
+ if (!extractAll)
+ {
+ result+="dokumentiranih ";
+ }
+ result+="polja";
+ result+=" s linkovima na ";
+ if (!extractAll)
+ {
+ result+="dokumentaciju struktura podataka za svako polje";
+ }
+ else
+ {
+ result+="strukture kojima pripadaju:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Kazalo data tipova"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentacija tipova podataka"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcije/Subrutine"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentacija funkcija/subrutina"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipovi podataka"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Popis modula"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Lista svih ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="modula s kratkim opisom:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Modul"; break;
+ case ClassDef::Struct: result+=" Tip"; break;
+ case ClassDef::Union: result+=" Unija"; break;
+ case ClassDef::Interface: result+=" Sučelje"; break;
+ case ClassDef::Protocol: result+=" Protokol"; break;
+ case ClassDef::Category: result+=" Kategorija"; break;
+ case ClassDef::Exception: result+=" Iznimka"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Predložak";
+ result+=" Referenca";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" - Sadržaj modula";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "članovi modula"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Lista svih ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="članova modula s linkovima na ";
+ if (extractAll)
+ {
+ result+="dokumentaciju modula za svaki član:";
+ }
+ else
+ {
+ result+="modul kojem pripadaju:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Kazalo modula"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (!singular) result+="i";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacija ovog ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modula"; break;
+ case ClassDef::Struct: result+="tipa"; break;
+ case ClassDef::Union: result+="unije"; break;
+ case ClassDef::Interface: result+="sučelja"; break;
+ case ClassDef::Protocol: result+="protokola"; break;
+ case ClassDef::Category: result+="kategorije"; break;
+ case ClassDef::Exception: result+="iznimke"; break;
+ default: break;
+ }
+ result+=" je napravljena iz :";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (!singular) result+="ovi";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Ograničenja tipova (Type Constraints)";
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.6.0 (mainly for the new search engine)
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString("Relacije ") + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Učitavam...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globalni namespace";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Tražim...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nema traženih podataka";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Datoteka u "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Uključuje datotake u "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Pon","Uto","Sri","Čet","Pet","Sub","Ned" };
+ static const char *months[] = { "Sje","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliografija"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Direktoriji o kojima ovisi ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "razina detalja"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametri predloška"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "i još "+number+" ..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumatacija za ovu enumeraciju je generirana iz ";
+ if (!single) result += "datoteka:";
+ else result += "datoteke:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return "Opis enumeracije " + QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" naslijeđeni od "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Dodatni naslijeđeni članovi"; }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
+
+
diff --git a/src/translator_hu.h b/src/translator_hu.h
new file mode 100644
index 0000000..610af8e
--- /dev/null
+++ b/src/translator_hu.h
@@ -0,0 +1,1498 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+ /*
+ * Original Hungarian translation by
+ * György Földvári <foldvari at diatronltd.com>
+ *
+ * Extended, revised and updated by
+ * Ákos Kiss <akiss at users.sourceforge.net>
+ *
+ * Further extended, revised and updated by
+ * Tamási Ferenc <tf551 at hszk.bme.hu>
+ */
+
+#ifndef TRANSLATOR_HU_H
+#define TRANSLATOR_HU_H
+
+class TranslatorHungarian : public TranslatorAdapter_1_4_6
+{
+ private:
+ const char * zed(char c)
+ {
+ switch (c & ~('a' ^ 'A')) {
+ case 'B': case 'C': case 'D': case 'F': case 'G':
+ case 'H': case 'J': case 'K': case 'L': case 'M':
+ case 'N': case 'P': case 'Q': case 'R': case 'S':
+ case 'T': case 'V': case 'W': case 'X': case 'Z':
+ return " ";
+ default:
+ return "z ";
+ }
+ }
+ public:
+
+ // --- Language control methods -------------------
+ virtual QCString idLanguage()
+ { return "hungarian"; }
+ /*! Used to get the command(s) for the language support. This method
+ * was designed for languages which do not prefer babel package.
+ * If this methods returns empty string, then the latexBabelPackage()
+ * method is used to generate the command for using the babel package.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[T2A]{fontenc}\n"
+ "\\usepackage[magyar]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Kapcsolódó függvények"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Figyelem! Ezek a függvények nem tagjai az osztálynak!)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Részletes leírás"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Típusdefiníció-tagok dokumentációja"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Enumeráció-tagok dokumentációja"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Tagfüggvények dokumentációja"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatmezők dokumentációja";
+ }
+ else
+ {
+ return "Adattagok dokumentációja";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Részletek..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "A tagok teljes listája"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Taglista"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "A(z) "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return " osztály tagjainak teljes listája, az örökölt tagokkal együtt."; }
+
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Ezt a dokumentációt a Doxygen készítette ";
+ if (s) result+=(QCString)" a" + zed(s[0])+s+(QCString)" projekthez";
+ result+=" a forráskódból.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum-érték"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definiálja:"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modulok"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Osztályhierarchia"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatszerkezetek";
+ }
+ else
+ {
+ return "Osztálylista";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Fájllista"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatmezők";
+ }
+ else
+ {
+ return "Osztálytagok";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globális elemek";
+ }
+ else
+ {
+ return "Fájlelemek";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Kapcsolódó lapok"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Példák"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Keresés"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Majdnem (de nem teljesen) betűrendbe szedett "
+ "leszármazási lista:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Az összes ";
+ if (!extractAll) result+="dokumentált ";
+ result+="fájl listája rövid leírásokkal:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Az összes adatszerkezet listája rövid leírásokkal:";
+ }
+ else
+ {
+ return "Az összes osztály, struktúra, unió és interfész "
+ "listája rövid leírásokkal:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Az összes ";
+ if (!extractAll)
+ {
+ result+="dokumentált ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktúra- és úniómező";
+ }
+ else
+ {
+ result+="osztálytag";
+ }
+ result+=" listája, valamint hivatkozás ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="a megfelelő struktúra-/úniódokumentációra minden mezőnél:";
+ }
+ else
+ {
+ result+="a megfelelő osztálydokumentációra minden tagnál:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="a struktúrákra/úniókra, amikhez tartoznak:";
+ }
+ else
+ {
+ result+="az osztályokra, amikhez tartoznak:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Az összes ";
+ if (!extractAll) result+="dokumentált ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="függvény, változó, makródefiníció, enumeráció és típusdefiníció";
+ }
+ else
+ {
+ result+="fájlelem";
+ }
+ result+=" listája, valamint hivatkozás ";
+ if (extractAll)
+ result+="a fájlokra, amikhez tartoznak:";
+ else
+ result+="a dokumentációra:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "A példák listája:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "A kapcsolódó dokumentációk listája:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "A modulok listája:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentáció"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modulmutató"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarchikus mutató"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatszerkezet-mutató";
+ }
+ else
+ {
+ return "Osztálymutató";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Fájlmutató"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modulok dokumentációja"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatszerkezetek dokumentációja";
+ }
+ else
+ {
+ return "Osztályok dokumentációja";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Fájlok dokumentációja"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Példák dokumentációja"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Kapcsolódó dokumentációk"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referencia kézikönyv"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makródefiníciók"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Típusdefiníciók"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerációk"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Függvények"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Változók"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumeráció-értékek"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Makródefiníciók dokumentációja"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Típusdefiníciók dokumentációja"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumerációk dokumentációja"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Függvények dokumentációja"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Változók dokumentációja"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatszerkezetek";
+ }
+ else
+ {
+ return "Osztályok";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"";
+ if (projName) result+=(QCString)"Projekt: "+projName;
+ result+=(QCString)" Készült: "+date+" Készítette: ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"A"+zed(clName[0])+clName+" osztály származási diagramja:";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "CSAK BELSŐ HASZNÁLATRA!"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Figyelmeztetés"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Verzió"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Dátum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Visszatérési érték"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Lásd még"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Paraméterek"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Kivételek"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Készítette"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Névtérlista"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Az összes ";
+ if (!extractAll) result+="dokumentált ";
+ result+="névtér listája rövid leírásokkal:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Barátok"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Barát és kapcsolódó függvények dokumentációja"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" osztály"; break;
+ case ClassDef::Struct: result+=" struktúra"; break;
+ case ClassDef::Union: result+=" unió"; break;
+ case ClassDef::Interface: result+=" interfész"; break;
+ case ClassDef::Protocol: result+=" protocol"; break; // translate me!
+ case ClassDef::Category: result+=" category"; break; // translate me!
+ case ClassDef::Exception: result+=" kivétel"; break;
+ default: break;
+ }
+ if (isTemplate) result+="sablon-";
+ result+="referencia";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" fájlreferencia";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" névtér-referencia";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Publikus tagfüggvények"; }
+ virtual QCString trPublicSlots()
+ { return "Publikus rések"; }
+ virtual QCString trSignals()
+ { return "Szignálok"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statikus publikus tagfüggvények"; }
+ virtual QCString trProtectedMembers()
+ { return "Védett tagfüggvények"; }
+ virtual QCString trProtectedSlots()
+ { return "Védett rések"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statikus védett tagfüggvények"; }
+ virtual QCString trPrivateMembers()
+ { return "Privát tagfüggvények"; }
+ virtual QCString trPrivateSlots()
+ { return "Privát rések"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statikus privát tagfüggvények"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" és ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Ősök: "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Leszármazottak: "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Újraimplementált ősök: "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Újraimplementáló leszármazottak: "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Névtértagok"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Az összes ";
+ if (!extractAll) result+="dokumentált ";
+ result+="névtér tagjainak listája, valamint hivatkozás ";
+ if (extractAll)
+ result+=" a megfelelő névtér dokumentációra minden tagnál:";
+ else
+ result+=" a névterekre, amelynek tagjai:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Névtérmutató"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Névterek dokumentációja"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Névterek"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Ez a dokumentáció ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="az osztályról"; break;
+ case ClassDef::Struct: result+="a struktúráról"; break;
+ case ClassDef::Union: result+="az unióról"; break;
+ case ClassDef::Interface: result+="az interfészről"; break;
+ case ClassDef::Protocol: result+="protocol"; break; // translate me!
+ case ClassDef::Category: result+="category"; break; // translate me!
+ case ClassDef::Exception: result+="a kivételről"; break;
+ default: break;
+ }
+ result+=" a következő fájl";
+ if (!single) result+="ok";
+ result+=" alapján készült:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Visszatérési értékek"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Főoldal"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "o."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definíció a(z) @1 fájl @0. sorában.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definíció a(z) @0 fájlban.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Ellenjavallt";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"A"+zed(clName[0])+clName+" osztály együttműködési diagramja:";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"A"+zed(fName[0])+fName+" definíciós fájl függési gráfja:";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruktorok és destruktorok dokumentációja";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Ugrás a fájl forráskódjához.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Ugrás a fájl dokumentációjához.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Előfeltétel";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Utófeltétel";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariáns";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Kezdő érték:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "forráskód";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Osztályhierarchia-ábra";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Ugrás az osztályhierarchia-ábrához";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Ugrás az szöveges osztályhierarchiához";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Oldalmutató";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Megjegyzés";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Publikus típusok";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatmezők";
+ }
+ else
+ {
+ return "Publikus attribútumok";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statikus publikus attribútumok";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Védett típusok";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Védett attribútumok";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statikus védett attribútumok";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privát típusok";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privát attribútumok";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statikus privát attribútumok";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Tennivaló";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Tennivalók listája";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Hivatkozások:";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Megjegyzések";
+ }
+ virtual QCString trAttention()
+ {
+ return "Figyelem";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Ez az ábra azt mutatja, hogy mely fájlok ágyazzák be "
+ "közvetve vagy közvetlenül ezt a fájlt:";
+ }
+ virtual QCString trSince()
+ {
+ return "Először bevezetve";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Jelmagyarázat";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Ez az oldal elmagyarázza hogyan kell értelmezni a "
+ "doxygen által készített ábrákat.<p>\n"
+ "Vegyük a következő példát:\n"
+ "\\code\n"
+ "/*! Vágás miatt nem látható osztály */\n"
+ "class Invisible { };\n\n"
+ "/*! Levágott osztály, származása rejtett */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Doxygen kommentekkel nem dokumentált osztály */\n"
+ "class Undocumented { };\n\n"
+ "/*! Publikus származtatásal levezetett osztály */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Egy sablonosztály */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Védett származtatásal levezetett osztály */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Privát származtatásal levezetett osztály */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Osztály, melyet a származtatott osztály használ */\n"
+ "class Used { };\n\n"
+ "/*! Osztály, mely több másiknak leszármazottja */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Ha a konfigurációs fájl \\c MAX_DOT_GRAPH_HEIGHT elemének értékét "
+ "240-re állítjuk, az eredmény a következő ábra lesz:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Az ábrán levő dobozok jelentése:\n"
+ "<ul>\n"
+ "<li>Kitöltött fekete doboz jelzi azt az osztályt vagy struktúrát,"
+ "amelyről az ábra szól.\n"
+ "<li>Fekete keret jelzi a dokumentált osztályokat és struktúrákat.\n"
+ "<li>Szürke keret jelzi a nem dokumentált osztályokat és struktúrákat.\n"
+ "<li>Piros keret jelzi azokat az osztályokat és struktúrákat, amelyeknél vágás miatt nem látható "
+ "az összes leszármaztatási kapcsolat. Egy ábra vágásra kerül, ha nem fér bele "
+ "a megadott tartományba."
+ "</ul>\n"
+ "A nyilak jelentése:\n"
+ "<ul>\n"
+ "<li>Sötétkék nyíl jelzi a publikus származtatást.\n"
+ "<li>Sötétzöld nyíl jelzi a védett származtatást.\n"
+ "<li>Sötétvörös nyíl jelzi a privát származtatást.\n"
+ "<li>Lila szaggatott nyíl jelzi, ha az osztály egy másikat használ vagy tartalmaz. "
+ "A nyíl felirata jelzi a változó(k) nevét, amelyeken keresztül a másik osztály kapcsolódik.\n"
+ "<li>Sárga szaggatott nyíl jelzi a kapcsolatot a sablonpéldány és a példányosított "
+ "osztálysablon között. A nyíl felirata jelzi a pélány sablonparamétereit.\n"
+ "</ul>\n";
+
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Jelmagyarázat";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Teszt";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Tesztlista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Tulajdonságok";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Tulajdonságok dokumentációjka";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Adatszerkezetek";
+ }
+ else
+ {
+ return "Osztályok";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return name+(QCString)" csomag";
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Csomaglista";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "A csomagok rövid leírásai (amennyiben léteznek):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Csomagok";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Érték:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Hiba";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Hiba lista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1250";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Tárgymutató";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Osztály" : "osztály"));
+ //if (!singular) result+="es";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Fájl" : "fájl"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Névtér" : "névtér"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Csoport" : "csoport"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Oldal" : "oldal"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Tag" : "tag"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Globális elem" : "globális elem"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Szerző" : "szerző"));
+ if (!singular) result+="k";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Hivatkozások";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Megvalósítja a következőket: "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Megvalósítják a következők: "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Tartalomjegyzék";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Ellenjavallt elemek listája";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Események";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Események dokumentációja";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Csomag típusok";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Csomag függvények";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statikus csomag függvények";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Csomag attribútumok";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statikus csomag attribútumok";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Összes";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "A függvény hívási gráfja:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "A keresés eredménye";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Sajnos egy dokumentum sem felelt meg a keresési feltételeknek.";
+ }
+ else if (numDocuments==1)
+ {
+ return "<b>1</b> dokumentum felelt meg a keresési feltételeknek.";
+ }
+ else
+ {
+ return "<b>$num</b> dokumentum felelt meg a keresési feltételeknek."
+ "Elsőnek a legjobb találatok vannak feltüntetve.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Találatok:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Forrásfájl";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Könyvtárhierarchia"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Könyvtárak dokumentációja"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Könyvtárak"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Majdnem (de nem teljesen) betűrendbe szedett "
+ "könyvtárhierarchia:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" könyvtárreferencia"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Könyvtár" : "könyvtár"));
+ //if (singular) result+="y"; else result+="ies";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ez egy túlterhelt tagfüggvény."
+ "A fenti függvénytől csak argumentumaiban különbözik.";
+ }
+};
+
+#endif
diff --git a/src/translator_id.h b/src/translator_id.h
new file mode 100644
index 0000000..5647bc0
--- /dev/null
+++ b/src/translator_id.h
@@ -0,0 +1,1817 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_ID_H
+#define TRANSLATOR_ID_H
+
+/*
+ * Translasi berikut didasarkan pada versi translator_en.h dalam
+ * Doxygen 1.7.5.1.
+ *
+ * Penterjemah: Adhi Hargo <cadmus_sw at yahoo.com>
+ */
+class TranslatorIndonesian : public TranslatorAdapter_1_8_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "indonesian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[bahasa]{babel}";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Fungsi-fungsi Terkait"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Perhatikan bahwa fungsi-fungsi tersebut bukan fungsi anggota.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Keterangan Lengkap"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentasi Anggota: Tipe"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentasi Anggota: Enumerasi"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentasi Anggota: Fungsi"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentasi Variabel";
+ }
+ else
+ {
+ return "Dokumentasi Anggota: Data";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Selengkapnya..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Daftar semua anggota"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Daftar anggota"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Berikut ini daftar lengkap anggota untuk "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", termasuk semua anggota yang diwariskan."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Dibangkitkan secara otomatis oleh Doxygen";
+ if (s) result+=(QCString)" untuk "+s;
+ result+=" dari kode sumber.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "nama enumerasi"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "nilai enumerasi"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "didefinisikan di"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modul"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hierarki Kelas"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktur Data";
+ }
+ else
+ {
+ return "Daftar Kelas";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Daftar File"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Variabel Data";
+ }
+ else
+ {
+ return "Daftar Anggota Kelas";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Daftar Definisi Global";
+ }
+ else
+ {
+ return "Daftar Anggota File";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Halaman Terkait"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Contoh"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Cari"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Hierarki kelas ini diurutkan kurang-lebih"
+ " berdasarkan abjad:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Berikut ini daftar seluruh file";
+ if (!extractAll) result+=" yang didokumentasikan";
+ result += ", dengan penjelasan singkat:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Berikut ini daftar struktur data, dengan penjelasan singkat:";
+ }
+ else
+ {
+ return "Berikut ini daftar kelas, struct, union, dan interface, dengan penjelasan singkat:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Berikut ini daftar seluruh ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="variabel anggota struct dan union";
+ }
+ else
+ {
+ result+="kelas";
+ }
+ if (!extractAll)
+ {
+ result+=" yang didokumentasikan";
+ }
+ result+=", dengan tautan ke ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="dokumentasi struct/union untuk setiap variabel:";
+ }
+ else
+ {
+ result+="dokumentasi kelas untuk setiap anggota:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct/union yang memuatnya:";
+ }
+ else
+ {
+ result+="kelas yang memuatnya:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Berikut ini daftar ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="fungsi, variabel, makro definisi, enumerasi, dan tipe";
+ }
+ else
+ {
+ result+="file";
+ }
+ if (!extractAll) result+=" yang didokumentasikan";
+ result+=", dengan tautan ke ";
+ if (extractAll)
+ result+="file yang memuatnya:";
+ else
+ result+="dokumentasinya:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Berikut ini daftar semua contoh:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Berikut ini daftar semua halaman dokumentasi yang terkait:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Berikut ini daftar semua modul:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentasi"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Indeks Modul"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Indeks Hierarki Kelas"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Indeks Struktur Data";
+ }
+ else
+ {
+ return "Indeks Kelas";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Indeks File"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Dokumentasi Modul"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentasi Struktur Data";
+ }
+ else
+ {
+ return "Dokumentasi Kelas";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dokumentasi File"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentasi Contoh"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Dokumentasi Halaman"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Dokumen Referensi"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makro Definisi"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definisi Tipe"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerasi"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Fungsi"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variabel"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Nilai enumerasi"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Dokumentasi Makro Definisi"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentasi Definisi Tipe"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentasi Tipe Enumerasi"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentasi Fungsi"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Dokumentasi Variabel"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktur Data";
+ }
+ else
+ {
+ return "Kelas";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Dibangkitkan pada tanggal "+date;
+ if (projName) result+=(QCString)" untuk "+projName;
+ result+=(QCString)" oleh";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagram hierarki kelas untuk "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Hanya untuk digunakan secara internal."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Peringatan"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versi"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Tanggal"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Mengembalikan"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Lihat juga"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parameter"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Eksepsi"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Dibangkitkan oleh"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Daftar Namespace"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Berikut ini daftar namespace";
+ if (!extractAll) result+=" yang didokumentasikan";
+ result+=", dengan keterangan singkat:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friend"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentasi Friend Dan Fungsi Terkait"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referensi";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Kelas "; break;
+ case ClassDef::Struct: result+=" Struct "; break;
+ case ClassDef::Union: result+=" Union "; break;
+ case ClassDef::Interface: result+=" Interface "; break;
+ case ClassDef::Protocol: result+=" Protokol "; break;
+ case ClassDef::Category: result+=" Kategori "; break;
+ case ClassDef::Exception: result+=" Eksepsi "; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template ";
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result="Referensi File ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Referensi Namespace ";
+ result+=namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Fungsi Anggota Publik"; }
+ virtual QCString trPublicSlots()
+ { return "Slot Publik"; }
+ virtual QCString trSignals()
+ { return "Signal"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Fungsi Anggota Publik Statis"; }
+ virtual QCString trProtectedMembers()
+ { return "Fungsi Anggota Diproteksi"; }
+ virtual QCString trProtectedSlots()
+ { return "Slot Diproteksi"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Fungsi Anggota Diproteksi Statis"; }
+ virtual QCString trPrivateMembers()
+ { return "Fungsi Anggota Privat"; }
+ virtual QCString trPrivateSlots()
+ { return "Slot Privat"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Fungsi Anggota Privat Statis"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", dan ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Mewarisi "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Diwariskan ke "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Di-reimplementasikan dari "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Diimplementasikan ulang di "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Anggota Namespace"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Berikut ini daftar anggota namespace";
+ if (!extractAll) result+=" yang didokumentasikan";
+ result+=", dengan tautan ke ";
+ if (extractAll)
+ result+="dokumentasi namespace untuk setiap anggota:";
+ else
+ result+="namespace yang memuatnya:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Indeks Namespace"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Dokumentasi Namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Daftar Namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentasi untuk ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="kelas"; break;
+ case ClassDef::Struct: result+="struct"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategori"; break;
+ case ClassDef::Exception: result+="eksepsi"; break;
+ default: break;
+ }
+ result+=" ini dibangkitkan dari file";
+ result+=single ? "" : "-file";
+ result+=" berikut:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Nilai kembali"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Halaman Utama"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "hal."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definisi pada baris @0 dalam file @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definisi dalam file @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Kadaluarsa";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagram kolaborasi untuk "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Bagan kebergantungan pemuatan untuk "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentasi Konstruktor & Destruktor";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Ke kode sumber file ini.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Ke dokumentasi file ini.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Kondisi Awal";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Kondisi Akhir";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invarian";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Nilai awal:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "kode";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Hierarki Kelas Secara Grafis";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Ke bagan grafis hierarki kelas";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Ke bagan tekstual hierarki kelas";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Indeks Halaman";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Catatan";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Tipe Publik";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Variabel Data";
+ }
+ else
+ {
+ return "Atribut Publik";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atribut Publik Statis";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipe Diproteksi";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atribut Diproteksi";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atribut Diproteksi Statis";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipe Privat";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atribut Privat";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atribut Privat Statis";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Tugas";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Daftar Tugas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Direferensikan oleh";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Keterangan";
+ }
+ virtual QCString trAttention()
+ {
+ return "Perhatian";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Bagan ini menunjukkan file-file yang memuat"
+ " atau menggunakan file ini baik secara langsung maupun"
+ " tidak langsung:";
+ }
+ virtual QCString trSince()
+ {
+ return "Sejak";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Keterangan Bagan";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Halaman ini berisi keterangan cara membaca bagan yang dibangkitkan "
+ "oleh doxygen.<p>\n"
+ "Contoh:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Apabila tag \\c MAX_DOT_GRAPH_HEIGHT di file konfigurasi "
+ "diset ke 240 kode di atas akan menghasilkan bagan berikut:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Kotak-kotak pada bagan di atas mempunyai arti sebagai berikut:\n"
+ "<ul>\n"
+ "<li>%Kotak hitam merupakan struct atau kelas yang bersangkutan.\n"
+ "<li>%Kotak berbingkai hitam adalah struct atau kelas yang mempunyai dokumentasi.\n"
+ "<li>%Kotak dengan bingkai abu-abu adalah struct atau kelas tanpa dokumentasi.\n"
+ "<li>%Kotak dengan bingkai merah merupakan struct atau kelas yang didokumentasikan tetapi"
+ "tidak semua relasinya ditampilkan. %Sebuah bagan "
+ "akan terpotong apabila lebih besar daripada ukuran yang ditentukan.\n"
+ "</ul>\n"
+ "Arti dari tanda-tanda panah adalah sebagai berikut:\n"
+ "<ul>\n"
+ "<li>%Panah biru tua menandakan pewarisan publik.\n"
+ "<li>%Panah hijau tua untuk pewarisan diproteksi.\n"
+ "<li>%Panah merah tua untuk pewarisan privat.\n"
+ "<li>%Panah ungu putus-putus menandakan kelas tersebut berhubungan dengan kelas lain. "
+ "Panah tersebut diberi judul sesuai dengan kelas atau struct tujuan.\n"
+ "<li>%Panah kuning putus-putus menandakan hubungan antara sebuah template kelas dan "
+ "instance dari template tersebut. Panah tersebut diberi judul sesuai dengan "
+ "parameter template yang digunakan.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "keterangan";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Tes";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Daftar Tes";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Daftar Property";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentasi Property";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktur Data";
+ }
+ else
+ {
+ return "Daftar Kelas";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Daftar Paket";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Berikut ini daftar paket, dengan keterangan singkat (apabila tersedia):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Daftar Paket";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Nilai:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Daftar Bug";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Kelas" : "kelas"));
+ if (!singular) result+="-kelas";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "File" : "file"));
+ if (!singular) result+="-file";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Kelompok" : "kelompok"));
+ if (!singular) result+="-kelompok";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Halaman" : "halaman"));
+ if (!singular) result+="-halaman";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Anggota" : "anggota"));
+ if (!singular) result+="-anggota";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Definisi" : "definisi"));
+ if (!singular) result+="-definisi";
+ result += " global";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Penulis" : "penulis"));
+ //if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referensi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Mengimplementasikan "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Diimplementasikan di "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Daftar Isi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Daftar Kadaluarsa";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Event";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentasi Event";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Jenis Paket";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Daftar Fungsi Paket";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Daftar Fungsi Statis Paket";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Daftar Atribut Paket";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Daftar Atribut Statis Paket";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Semua";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Berikut ini bagan fungsi-terpanggil untuk fungsi ini:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Hasil Pencarian";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Maaf, tidak ada dokumen yang cocok.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Ditemukan <b>1</b> dokumen yang cocok.";
+ }
+ else
+ {
+ return "Ditemukan <b>$num</b> documents yang cocok. "
+ "Menampilkan hasil terbaik lebih awal.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Kecocokan:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Kode Sumber:" + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarki Direktori"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentasi Direktori"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Daftar Direktori"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Struktur direktori ini diurutkan hampir berdasarkan abjad:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Referensi Direktori "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Direktori" : "direktori"));
+ //if (singular) result+="y"; else result+="ies";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ini adalah fungsi anggota yang di-overload"
+ " untuk kemudahan. Perbedaannya dengan fungsi di atas"
+ " hanya pada parameter-parameter yang diterima.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Berikut ini bagan fungsi-pemanggil untuk fungsi ini:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentasi Nilai Enumerasi"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentasi Fungsi/Subrutin Anggota"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Daftar Tipe Data"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Variabel Data"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Berikut daftar tipe data, dengan penjelasan singkat:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Berikut daftar semua anggota tipe data ";
+ if (!extractAll)
+ {
+ result+="terdokumentasi ";
+ }
+ result+=" dengan tautan ke ";
+ if (!extractAll)
+ {
+ result+="dokumentasi struktur data untuk setiap anggota:";
+ }
+ else
+ {
+ result+="tipe data yang memuatnya:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Indeks Tipe Data"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentasi Tipe Data"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Fungsi/Subrutin"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Dokumentasi Fungsi/Subrutin"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipe Data"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modules List"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Berikut daftar semua modul";
+ if (!extractAll) result+=" terdokumentasi";
+ result+=", dengan penjelasan singkat:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referensi ";
+ if (isTemplate) result+="Template ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Modul "; break;
+ case ClassDef::Struct: result+="Tipe "; break;
+ case ClassDef::Union: result+="Union "; break;
+ case ClassDef::Interface: result+="Antarmuka "; break;
+ case ClassDef::Protocol: result+="Protokol "; break;
+ case ClassDef::Category: result+="Kategori "; break;
+ case ClassDef::Exception: result+="Eksepsi "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Referensi Modul ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Anggota Modul"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Berikut daftar semua anggota modul ";
+ if (!extractAll) result+="terdokumentasi ";
+ result+="dengan tautan ke ";
+ if (extractAll)
+ {
+ result+="dokumentasi modul untuk setiap anggota:";
+ }
+ else
+ {
+ result+="modul yang memuatnya:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Indeks Modul"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (!singular) result+="-modul";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentasi untuk ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="module"; break;
+ case ClassDef::Struct: result+="type"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" ini dibangkitkan dari file";
+ if (!single) result+="-file ";
+ result+="berikut:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipe" : "tipe"));
+ if (!singular) result+="-tipe";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (!singular) result+="-subprogram";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Batasan Tipe";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relasi "+QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Memuat...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace Global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Mencari...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Tidak Ditemukan";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"File dimuat dalam "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Memuat file dalam "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Senin","Selasa","Rabu","Kamis","Jumat","Sabtu","Minggu" };
+ static const char *months[] = { "Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Daftar Pustaka"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Hak Cipta"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Bagan dependensi directori untuk ")+name+":"; }
+
+};
+
+#endif
diff --git a/src/translator_it.h b/src/translator_it.h
new file mode 100644
index 0000000..59799a3
--- /dev/null
+++ b/src/translator_it.h
@@ -0,0 +1,1860 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/******************************************************************************
+ *
+ * Revision history
+ *
+ * 2012/04: updated translation of new items used since version 1.7.5 and 1.8.0
+ * 2010/08: updated translation of new items used since version 1.6.0 and 1.6.3
+ * completely reviewed the translation in the trLegendDocs() function
+ * corrected some typos all around
+ * reviewed some translations all around
+ * 2007/11: updated translation of new items used since version 1.5.4
+ * 2007/10: Included corrections provided by Arialdo Martini <arialdomartini at bebox.it>, updated some strings marked with 'translate me' comment
+ * 2006/10: made class to derive directly from Translator class (reported in Petr Prikryl October 9 translator report)
+ * 2006/06: updated translation of new items used since version 1.4.6
+ * 2006/05: translated new items used since version 1.4.6
+ * corrected typo in trPackageMembers method
+ * 2005/03: translated new items used since version 1.4.1
+ * removed unused methods listed in Petr Prikryl February 28 translator report
+ * 2004/09: translated new items used since version 1.3.9
+ * 2004/06: translated new items used since version 1.3.8
+ * 2003/11: translated new items used since version 1.3.3
+ * 2003/06: translated new items used since version 1.3.1
+ * 2003/04: translated new items used since version 1.3
+ * 2002/11: translated new items used since version 1.2.18
+ * 2002/08: translated new items used since version 1.2.17
+ * 2002/07: translated new items used since version 1.2.16
+ * 2002/06: modified trRelatedPagesDescription() method
+ * corrected typo in trInclByDepGraph() method
+ * 2002/01: translated new items used since version 1.2.13
+ * updated e-mail address
+ * 2001/11: corrected the translation fixing the issues reported by the translator.pl script
+ * translated new items used since version 1.2.11
+ * 2001/08: corrected the translation fixing the issues reported by the translator.pl script
+ * translated new items used since version 1.2.7
+ * 2001/05: adopted new translation mechanism (trough adapters),
+ * translated new items used since version 1.2.5 and 1.2.6,
+ * revised those function returning strings in OPTIMIZE_OTPUT_FOR_C case,
+ * corrections regarding the plurals of some english terms maintained in the translation,
+ * changed some terms to better suit the sense
+ * 2001/02: translated new items used since version 1.2.4
+ * 2000/11: modified slightly the translation in trLegendDocs() function,
+ * translated new items used since version 1.2.1 and 1.2.2
+ * 2000/08: translated new items used since version 1.1.3, 1.1.4, 1.1.5 and 1.2.0
+ * 2000/03: translated new items used since version 1.0 and 1.1.0
+ * 1999/19: entirely rewritten the translation to correct small variations due
+ * to feature additions and to conform to the layout of the latest
+ * commented translator.h for the english language
+ * 1999/09: corrected some small typos in the "new since 0.49-990425" section
+ * added the "new since 0.49-990728" section
+ * 1999/06: revised and completed by Alessandro Falappa (current mantainer)
+ * 1999/??: initial italian translation by Ahmed Aldo Faisal
+ */
+
+/******************************************************************************
+ *
+ * Note sui criteri adottati per la traduzione
+ *
+ * Nella traduzione non si sono tradotti alcuni termini inglesi ormai entrati
+ * a far parte del "gergo" informatico (per es. file o namespace)
+ *
+ * Il plurale dei termini inglesi non tradotti è stato reso con il singolare
+ * della parola inglese secondo una convenzione spesso ritrovata nella documentazione
+ * tecnica (ad es. "lista dei file" e non "lista dei files")
+ *
+ * Se avete suggerimenti sulla traduzione di alcuni termini o volete segnalare
+ * eventuali sviste potete scrivermi all'indirizzo: alessandro at falappa.net
+ */
+
+#ifndef TRANSLATOR_IT_H
+#define TRANSLATOR_IT_H
+
+class TranslatorItalian : public TranslatorAdapter_1_8_2
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "italian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support. This method
+ * was designed for languages which do wish to use a babel package.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[italian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ QCString trRelatedFunctions()
+ { return "Funzioni collegate"; }
+
+ /*! subscript for the related functions. */
+ QCString trRelatedSubscript()
+ { return "(Si noti che queste non sono funzioni membro.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ QCString trDetailedDescription()
+ { return "Descrizione dettagliata"; }
+
+ /*! header that is put before the list of typedefs. */
+ QCString trMemberTypedefDocumentation()
+ { return "Documentazione delle ridefinizioni dei tipi (typedef)"; }
+
+ /*! header that is put before the list of enumerations. */
+ QCString trMemberEnumerationDocumentation()
+ { return "Documentazione dei tipi enumerati (enum)"; }
+
+ /*! header that is put before the list of member functions. */
+ QCString trMemberFunctionDocumentation()
+ { return "Documentazione delle funzioni membro"; }
+
+ /*! header that is put before the list of member attributes. */
+ QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentazione dei campi";
+ }
+ else
+ {
+ return "Documentazione dei membri dato";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ QCString trMore()
+ { return "Continua..."; }
+
+ /*! put in the class documentation */
+ QCString trListOfAllMembers()
+ { return "Elenco di tutti i membri"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ QCString trMemberList()
+ { return "Elenco dei membri"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ QCString trThisIsTheListOfAllMembers()
+ { return "Questo è l'elenco completo di tutti i membri di "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ QCString trIncludingInheritedMembers()
+ { return ", inclusi tutti i membri ereditati."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ QCString trGeneratedAutomatically(const char *s)
+ {
+ QCString result="Generato automaticamente da Doxygen";
+ if (s) result+=(QCString)" per "+s;
+ result+=" a partire dal codice sorgente.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ QCString trEnumName()
+ { return "nome di tipo enumerato"; }
+
+ /*! put after an enum value in the list of all members */
+ QCString trEnumValue()
+ { return "valore di tipo enumerato"; }
+
+ /*! put after an undocumented member in the list of all members */
+ QCString trDefinedIn()
+ { return "definito in"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ QCString trModules()
+ { return "Moduli"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ QCString trClassHierarchy()
+ { return "Gerarchia delle classi"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Strutture dati";
+ }
+ else
+ {
+ return "Elenco dei tipi composti";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ QCString trFileList()
+ { return "Elenco dei file"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campi dei dati";
+ }
+ else
+ {
+ return "Membri dei composti";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Elementi globali";
+ }
+ else
+ {
+ return "Elementi dei file";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ QCString trRelatedPages()
+ { return "Pagine collegate"; }
+
+ /*! This is put above each page as a link to all examples. */
+ QCString trExamples()
+ { return "Esempi"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ QCString trSearch()
+ { return "Cerca"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ QCString trClassHierarchyDescription()
+ {
+ return "Questo elenco di ereditarietà è ordinato "
+ "approssimativamente, ma non completamente, in ordine alfabetico:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Questo è un elenco ";
+ if (!extractAll) result+="dei file documentati ";
+ else result+="di tutti i file ";
+ result+="con una loro breve descrizione:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Queste sono le strutture dati con una loro breve descrizione:";
+ }
+ else
+ {
+ return "Queste sono le classi, le struct, le union e le interfacce con una loro breve descrizione:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Questo è un elenco ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ if (!extractAll) result+="delle struct e delle union documentate ";
+ else result+="di tutte le struct e le union ";
+ }
+ else
+ {
+ if (!extractAll) result+="dei membri documentati ";
+ else result+="di tutti i membri ";
+ }
+ result+="con collegamenti alla documentazione ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ if (extractAll) result+="della struct/union per ciascun campo:";
+ else result+="delle struct/union a cui appartengono:";
+ }
+ else
+ {
+ if (extractAll) result+="della classe a cui appartengono:";
+ else result+="delle classi a cui appartengono:";
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Questo è un elenco ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ if (!extractAll) result+="delle funzioni, delle variabili, delle define, dei tipi enumerati e delle ridefinizioni dei tipi (typedef) documentate ";
+ else result+="di tutte le funzioni, variabili, define, tipi enumerati, e ridefinizioni dei tipi (typedef) ";
+ }
+ else
+ {
+ if (!extractAll) result+="degli elementi documentati dei file ";
+ else result+="di tutti gli elementi dei file ";
+ }
+ result+="con collegamenti alla documentazione";
+ if (extractAll) result+=" del file a cui appartengono:";
+ else result+=":";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ QCString trExamplesDescription()
+ { return "Questo è l'elenco di tutti gli esempi:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ QCString trRelatedPagesDescription()
+ { return "Questo è l'elenco di tutte le pagine di documentazione collegate:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ QCString trModulesDescription()
+ { return "Questo è l'elenco di tutti i moduli:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ QCString trDocumentation()
+ { return "Documentazione"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ QCString trModuleIndex()
+ { return "Indice dei moduli"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ QCString trHierarchicalIndex()
+ { return "Indice della gerarchia"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Indice delle strutture dati";
+ }
+ else
+ {
+ return "Indice dei tipi composti";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ QCString trFileIndex()
+ { return "Indice dei file"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ QCString trModuleDocumentation()
+ { return "Documentazione dei moduli"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ QCString trClassDocumentation()
+ { return "Documentazione delle classi"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ QCString trFileDocumentation()
+ { return "Documentazione dei file"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ QCString trExampleDocumentation()
+ { return "Documentazione degli esempi"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ QCString trPageDocumentation()
+ { return "Documentazione delle pagine tra loro collegate "; }
+
+ /*! This is used in LaTeX as the title of the document */
+ QCString trReferenceManual()
+ { return "Manuale di riferimento"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ QCString trDefines()
+ { return "Definizioni"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ QCString trTypedefs()
+ { return "Ridefinizioni di tipo (typedef)"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ QCString trEnumerations()
+ { return "Tipi enumerati (enum)"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ QCString trFunctions()
+ { return "Funzioni"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trVariables()
+ { return "Variabili"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trEnumerationValues()
+ { return "Valori del tipo enumerato"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ QCString trDefineDocumentation()
+ { return "Documentazione delle definizioni"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ QCString trTypedefDocumentation()
+ { return "Documentazione delle ridefinizioni di tipo (typedef)"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ QCString trEnumerationTypeDocumentation()
+ { return "Documentazione dei tipi enumerati"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ QCString trFunctionDocumentation()
+ { return "Documentazione delle funzioni"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ QCString trVariableDocumentation()
+ { return "Documentazione delle variabili"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Strutture dati";
+ }
+ else
+ {
+ return "Composti";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generato "+date;
+ if (projName) result+=(QCString)" per "+projName;
+ result+=(QCString)" da";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagramma delle classi per "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ QCString trForInternalUseOnly()
+ { return "Solo per uso interno."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ QCString trWarning()
+ { return "Avvertimento"; }
+
+ /*! this text is generated when the \\version command is used. */
+ QCString trVersion()
+ { return "Versione"; }
+
+ /*! this text is generated when the \\date command is used. */
+ QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ QCString trReturns()
+ { return "Restituisce"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ QCString trSeeAlso()
+ { return "Si veda anche"; }
+
+ /*! this text is generated when the \\param command is used. */
+ QCString trParameters()
+ { return "Parametri"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ QCString trExceptions()
+ { return "Eccezioni"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ QCString trGeneratedBy()
+ { return "Generato da"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ QCString trNamespaceList()
+ { return "Lista dei namespace"; }
+
+ /*! used as an introduction to the namespace list */
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Questa è l'elenco ";
+ if (!extractAll) result+="dei namespace documentati, ";
+ else result+="di tutti i namespace ";
+ result+="con una loro breve descrizione:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ QCString trFriends()
+ { return "Friend"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ QCString trRelatedFunctionDocumentation()
+ { return "Documentazione dei friend e delle funzioni collegate"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Riferimenti per ";
+ if (isTemplate) result="Template per ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="la classe "; break;
+ case ClassDef::Struct: result+="la struct "; break;
+ case ClassDef::Union: result+="la union "; break;
+ case ClassDef::Interface: result+="l'interfaccia "; break;
+ case ClassDef::Protocol: result+="il protocollo "; break;
+ case ClassDef::Category: result+="la categoria "; break;
+ case ClassDef::Exception: result+="l'eccezione "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+
+ }
+
+ /*! used as the title of the HTML page of a file */
+ QCString trFileReference(const char *fileName)
+ {
+ QCString result="Riferimenti per il file ";
+ result+=(QCString)fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Riferimenti per il namespace ";
+ result+=(QCString)namespaceName;
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ QCString trPublicMembers()
+ { return "Membri pubblici"; }
+ QCString trPublicSlots()
+ { return "Slot pubblici"; }
+ QCString trSignals()
+ { return "Signal"; }
+ QCString trStaticPublicMembers()
+ { return "Membri pubblici statici"; }
+ QCString trProtectedMembers()
+ { return "Membri protetti"; }
+ QCString trProtectedSlots()
+ { return "Slot protetti"; }
+ QCString trStaticProtectedMembers()
+ { return "Membri protetti statici"; }
+ QCString trPrivateMembers()
+ { return "Membri privati"; }
+ QCString trPrivateSlots()
+ { return "Slot privati"; }
+ QCString trStaticPrivateMembers()
+ { return "Membri privati statici"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", e ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ QCString trInheritsList(int numEntries)
+ {
+ return "Eredita da "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ QCString trInheritedByList(int numEntries)
+ {
+ return "Base per "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementata in "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ QCString trNamespaceMembers()
+ { return "Membri dei namespace"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Questa è la lista ";
+ if (!extractAll) result+="dei membri documentati del namespace, ";
+ else result+="di tutti i membri del namespace ";
+ result+="con collegamenti ";
+ if (extractAll)
+ result+="alla documentazione del namespace per ciascun membro:";
+ else
+ result+="ai namespace a cui appartengono:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ QCString trNamespaceIndex()
+ { return "Indice dei namespace"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ QCString trNamespaceDocumentation()
+ { return "Documentazione dei namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ QCString trNamespaces()
+ { return "Namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentazione per quest";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="a classe"; break;
+ case ClassDef::Struct: result+="a struct"; break;
+ case ClassDef::Union: result+="a union"; break;
+ case ClassDef::Interface: result+="a interfaccia"; break;
+ case ClassDef::Protocol: result+="o protocollo"; break;
+ case ClassDef::Category: result+="a categoria"; break;
+ case ClassDef::Exception: result+="a eccezione"; break;
+ default: break;
+ }
+ result+=" è stata generata a partire ";
+ if (single) result+="dal seguente file:";
+ else result+="dai seguenti file:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "Valori di ritorno"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "Pagina Principale"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "pag."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definizione alla linea @0 del file @1.";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "Definizione nel file @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Deprecato";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagramma di collaborazione per "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Grafo delle dipendenze di inclusione per "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "Documentazione dei costruttori e dei distruttori";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "Vai al codice sorgente di questo file.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "Vai alla documentazione di questo file.";
+ }
+ /*! Text for the \\pre command */
+ QCString trPrecondition()
+ {
+ return "Precondizione";
+ }
+ /*! Text for the \\post command */
+ QCString trPostcondition()
+ {
+ return "Postcondizione";
+ }
+ /*! Text for the \\invariant command */
+ QCString trInvariant()
+ {
+ return "Invariante";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "Valore iniziale:";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "codice";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Grafico della gerarchia delle classi";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "Vai al grafico della gerarchia delle classi";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "Vai alla gerarchia delle classi (testuale)";
+ }
+ QCString trPageIndex()
+ {
+ return "Indice delle pagine";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "Nota";
+ }
+ QCString trPublicTypes()
+ {
+ return "Tipi pubblici";
+ }
+ QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campi";
+ }
+ else
+ {
+ return "Attributi pubblici";
+ }
+ }
+
+ QCString trStaticPublicAttribs()
+ {
+ return "Attributi pubblici statici";
+ }
+ QCString trProtectedTypes()
+ {
+ return "Tipi protetti";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "Attributi protetti";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "Attributi protetti statici";
+ }
+ QCString trPrivateTypes()
+ {
+ return "Tipi privati";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "Attributi privati";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "Attributi privati statici";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Da fare";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Elenco delle cose da fare";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenziato da";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Osservazioni";
+ }
+ virtual QCString trAttention()
+ {
+ return "Attenzione";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Questo grafo mostra quali altri file includono direttamente o indirettamente questo file:";
+ }
+ virtual QCString trSince()
+ {
+ return "A partire da";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda del grafo";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Questa pagina spiega come interpretare i grafi generati da doxygen.<p>\n"
+ "Si consideri l'esempio seguente:\n"
+ "\\code\n"
+ "/*! Classe invisibile per troncamento */\n"
+ "class Invisible { };\n\n"
+ "/*! Classe tronca, la relazione di ereditarietà è nascosta */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Classe non documentata con i commenti speciali di doxygen*/\n"
+ "class Undocumented { };\n\n"
+ "/*! Classe estesa mediante ereditarietà pubblica */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Classe templatizzata */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Classe estesa mediante ereditarietà protetta*/\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Classe estesa mediante ereditarietà privata*/\n"
+ "class PrivateBase { };\n\n"
+ "/*! Classe utilizzata dalla classe Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Classe che eredita da varie classi*/\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Verrà prodotto il grafo seguente:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "I riquadri nel grafo qui sopra hanno il seguente significato:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Il riquadro grigio pieno rappresenta la struct o la classe per la quale il grafo è stato generato.</li>\n"
+ "<li>Un riquadro con un bordo nero denota una struct o una classe documentata.</li>\n"
+ "<li>Un riquadro con un bordo grigio indica una struct o una classe non documentata.</li>\n"
+ "<li>Un riquadro con un bordo rosso indica una struct o una classe per la quale non sono mostrate tutte le relazioni di ereditarietà/contenimento (un grafo viene troncato se non rientra nei limiti prestabiliti).</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "Le frecce hanno il seguente significato:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Una freccia blu scuro indica una relazione di ereditarietà pubblica tra due classi.</li>\n"
+ "<li>Una freccia verde indica un'ereditarietà protetta.</li>\n"
+ "<li>Una freccia rossa indica un'ereditarietà privata.</li>\n"
+ "<li>Una freccia viola tratteggiata indica che una classe è contenuta o usata da un'altra classe."
+ " La freccia viene etichettata con la o le variabili attraverso cui la struct o la classe puntata dalla freccia è accessibile.</li>\n"
+ "<li>Una freccia gialla tratteggiata indica la relazione tra una istanza di un template e la classe templatizzata da cui è stata istanziata."
+ " La freccia viene etichettata con i parametri di template dell'istanza.</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Lista dei test";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Proprietà";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentazione delle proprietà";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Strutture dati";
+ }
+ else
+ {
+ return "Classi";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista dei package";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Questi sono i package e una loro breve descrizione (se disponibile):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Package";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valore:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista dei bug";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indice";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Class" : "class"));
+ result+=(singular ? "e" : "i");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "File" : "file"));
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupp" : "grupp"));
+ result+=(singular ? "o" : "i");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Pagin" : "pagin"));
+ result+=(singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membr" : "membr"));
+ result+=(singular ? "o" : "i");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ result+=(singular ? "e" : "i");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ result+=(singular ? "e" : "i");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referenzia";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementato in "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Sommario";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista degli elementi deprecati";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Eventi";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentazione degli eventi";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipi con visibilità di package";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funzioni con visibilità di package";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funzioni statiche con visibilità di package";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Attributi con visibilità di package";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Attributi statici con visibilità di package";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tutto";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Questo è il grafo delle chiamate per questa funzione:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Risultati della ricerca";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Nessun documento soddisfa la tua richiesta.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Trovato <b>1</b> documento che soddisfa la tua richiesta.";
+ }
+ else
+ {
+ return "Trovati <b>$num</b> documenti che soddisfano la tua richiesta. "
+ "Le corrispondenze migliori sono in testa.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Corrispondenze:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return " File sorgente " + filename ;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Gerarchia delle directory"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentazione delle directory"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directory"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Questa gerarchia di directory è approssimativamente, "
+ "ma non completamente, ordinata in ordine alfabetico:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Riferimenti per la directory "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool)
+ {
+ QCString result((first_capital ? "Directory" : "directory"));
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Questa è una funzione membro sovraccaricata (overloaded), "
+ "fornita per comodità. Differisce dalla funzione di cui sopra "
+ "unicamente per gli argomenti passati.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Questo è il grafo dei chiamanti di questa funzione:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentazione dei tipi enumerati"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentazione delle funzioni membro/subroutine"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Elenco dei tipi di dato"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Membri dei tipi di dato"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Questi sono i tipi dato con una loro breve descrizione:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Questa è una lista di tutti i membri ";
+ if (!extractAll)
+ {
+ result+="documentati ";
+ }
+ result+="dei tipi di dato con collegamenti ";
+ if (!extractAll)
+ {
+ result+="alla documentazione della struttura dati per ciascun membro:";
+ }
+ else
+ {
+ result+="ai tipi dato a cui appartengono:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Indice dei tipi dati"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentazione dei tipi dato"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funzioni/Subroutine"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentazione funzioni/subroutine"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipi di dato"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Elenco dei moduli"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Questa è una lista di tutti i moduli ";
+ if (!extractAll) result+="documentati ";
+ result+="con una loro breve descrizione:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Riferimenti per ";
+ if (isTemplate) result="Template per ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" il modulo"; break;
+ case ClassDef::Struct: result+=" il tipo dato"; break;
+ case ClassDef::Union: result+=" l'union"; break;
+ case ClassDef::Interface: result+=" l'nterfaccia"; break;
+ case ClassDef::Protocol: result+=" il protocollo"; break;
+ case ClassDef::Category: result+=" la categoria"; break;
+ case ClassDef::Exception: result+=" l'eccezione"; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Riferimenti per il modulo ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membri del modulo"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Questo è un elenco di tutti i membri dei moduli ";
+ if (!extractAll) result+="documentati ";
+ result+="con collegamenti ";
+ if (extractAll)
+ {
+ result+="alla documentazione del modulo per ciascun membro:";
+ }
+ else
+ {
+ result+="al modulo a cui appartengono:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Indice dei moduli"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (singular) result+="o";
+ else result+="i";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"La documentazione per quest";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="o modulo"; break;
+ case ClassDef::Struct: result+="o tipo"; break;
+ case ClassDef::Union: result+="a union"; break;
+ case ClassDef::Interface: result+="a interfaccia"; break;
+ case ClassDef::Protocol: result+="o protocollo"; break;
+ case ClassDef::Category: result+="a categoria"; break;
+ case ClassDef::Exception: result+="a eccezione"; break;
+ default: break;
+ }
+ result+=" è stata generata a partire ";
+ if (single) result+="dal seguente file:"; else result+="dai seguenti file:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (singular) result+="o";
+ else result+="i";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sottoprogramm" : "sottoprogramm"));
+ if (singular) result+="a";
+ else result+="i";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Vincoli dei tipi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relazione per "+QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Caricamento in corso...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace globale";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Ricerca in corso...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nessun risultato";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"File in "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Include il file in "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Lun","Mar","Mer","Gio","Ven","Sab","Dom" };
+ static const char *months[] = { "Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Riferimenti bibliografici"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Grafo di dipendenza delle directory per ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "livello di dettaglio"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametri dei template"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "e altri "+number+" ..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "La documentazione per questo tipo enumerato è stata generata";
+ if (!single) result += " dai seguenti";
+ else result += " dal seguente";
+ result+=" file:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString("Riferimenti per il tipo enumerato ") + QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" ereditati da "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Altri membri ereditati"; }
+
+};
+
+#endif
+
+
diff --git a/src/translator_je.h b/src/translator_je.h
new file mode 100644
index 0000000..4dbcb4e
--- /dev/null
+++ b/src/translator_je.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*
+ * translator_jp.h
+ *
+ * 1.2.5)
+ * First Translation
+ * by Kenji Nagamatsu
+ * 1.2.12)
+ * Update and Shift-Jis(_WIN32)
+ * by Ryunosuke Sato (30-Dec-2001)
+ */
+
+#ifndef TRANSLATOR_JE_H
+#define TRANSLATOR_JE_H
+
+class TranslatorJapaneseEn : public TranslatorEnglish
+{
+ public:
+ virtual QCString idLanguage()
+ { return "japanese-en"; }
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "platex";
+ }
+ virtual QCString trRTFansicp()
+ {
+ return "932";
+ }
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "128";
+ }
+};
+
+#endif
diff --git a/src/translator_jp.h b/src/translator_jp.h
new file mode 100644
index 0000000..ae3605a
--- /dev/null
+++ b/src/translator_jp.h
@@ -0,0 +1,1980 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*
+ * translator_jp.h
+ * Updates:
+ * 1.2.5)
+ * First Translation
+ * by Kenji Nagamatsu
+ * 1.2.12)
+ * Update and Shift-Jis(_WIN32) -> converted UTF-8 at version 1.8.5
+ * by Ryunosuke Sato (30-Dec-2001)
+ * 1.5.8)
+ * Translation for 1.5.8.
+ * by Hiroki Iseri (18-Feb-2009)
+ * 1.8.5)
+ * Translation Added for 1.8.4 and revised
+ * by Suzumizaki-Kimitaka (30-Aug-2013)
+ */
+/*
+Messages for translators written in Japanese:
+1.8.5 への追加にあたって過去の翻訳者三名への連絡を試みたところ、
+井芹さん(Hiroki Iseri)さんからメールのお返事をいただけました。
+その際教えていただいた過去の経緯によりますと当時連絡可能だった方々は
+揃って従来訳から改変追加して構わない旨を表明されていたとのことです。
+Doxygen の開発の方でもそれはそれでいーんじゃん?みたいな感じだったようで。
+
+井芹さんも同様の見解で、私(鈴見咲=Suzumizaki-Kimitaka)も
+今後この翻訳に関わり続けられるかは非常に怪しいところですので
+将来の追加訳・既存訳改良は臆することなく進めていってよいのでは
+ないかと思います。無論作業の衝突があるのは不経済ですので現在進行形で
+活発に更新している方がいないかの簡単な確認(MLとかGitとか)をやるのも
+いいでしょうし、それでも偶然衝突したら不運を諦めて相互に調整しましょう。
+
+当面なさそうですが訳語の選択で喧嘩になることもあるかもしれません。
+そのときは gettext を利用するようなパッチを作って doxygen の開発に
+適用を求めるのが一番ではないかなと思います。
+
+1.6.0以前の既存の訳についても多少弄りました。
+特に structure を構造体ではなく構成としていたのはあんまりでしたので。
+ほか、C++ での利用前提で改変したところもありますが、それが他の言語で
+問題のようでしたらお手数掛けて申し訳ないですが相応に再修正しちゃって
+構いません。
+
+その際 doc/maintainers.txt を修正してから python doc/translator.py を
+実行する点にご注意下さい。私のところに search 鈴見咲君高 と書いたのは
+同姓同名がまず考えられないというのが大前提ですのでこちらもご注意。
+
+"詳解"の語が厳しすぎると思う向きはありましょうが、その程度には書けと。
+明記されてないけど使われてる動作や戻り値が想定内なのか想定外なのか
+わからんのはメンテで困るじゃないですか。
+
+(2013-08-30, 鈴見咲君高)
+*/
+#ifndef TRANSLATOR_JP_H
+#define TRANSLATOR_JP_H
+
+class TranslatorJapanese : public Translator
+{
+ public:
+ virtual QCString idLanguage()
+ { return "japanese"; }
+
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "関連関数"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(これらはメソッドではありません)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "詳解"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "型定義メンバ詳解"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "列挙型メンバ詳解"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ {
+ if( Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
+ {
+ return "メソッド詳解";
+ }
+ else
+ {
+ return "関数詳解";
+ }
+ }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if( Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "フィールド詳解";
+ }
+ else
+ {
+ return "メンバ詳解";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "[詳解]"; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "全メンバ一覧"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "メンバ一覧"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "継承メンバを含む "; }
+ /* trIncludingInheritedMembers に続くように定義すること */
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return " の全メンバ一覧です。"; }
+ /* trThisIsTheListOfAllMembers から続くように定義すること */
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result = "Doxygen により";
+ if (s) result=(QCString)" "+s+"の";
+ result+="ソースコードから抽出しました。";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "列挙名"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "列挙値"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "定義場所: "; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "モジュール"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "クラス階層"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造";
+ }
+ else
+ {
+ return "クラス一覧";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "ファイル一覧"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データフィールド";
+ }
+ else
+ {
+ return "クラスメンバ";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "大域各種";
+ }
+ else
+ {
+ return "ファイルメンバ";
+ }
+ }
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "諸情報"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "各種例"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "検索"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ {
+ return "クラス階層一覧です。大雑把に文字符号順で並べられています。";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ /* 概要がついているのは見ればわかるので省略 */
+ /* extractAll こと EXTRACT_ALL はすべての詳解が存在することを
+ 実際の有無を度外視してユーザーが保証する設定なので
+ 詳解がなければこの関数が返す文字列は当然に矛盾を起こす。
+ */
+ if (extractAll)
+ {
+ return "ファイル一覧です。";
+ }
+ return "詳解が付けられているファイルの一覧です。";
+ }
+
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ /* 概要がついているのは見ればわかるので省略 */
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造一覧です。";
+ }
+ else
+ {
+ return "クラス・構造体・共用体・インターフェースの一覧です。";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ const bool forC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ QCString result;
+ if (forC)
+ {
+ result = "構造体・共用体の";
+ }
+ if (extractAll)
+ {
+ result += "全";
+ }
+ else
+ {
+ result += "詳解あり";
+ }
+ if (forC)
+ {
+ result += "フィールド";
+ }
+ else
+ {
+ result += "クラスメンバ";
+ }
+ if (!extractAll && !forC)
+ {
+ result += "の";
+ }
+ result += "一覧です。";
+ if (!extractAll)
+ {
+ if (forC)
+ {
+ result+="各フィールド詳解";
+ }
+ else
+ {
+ result+="各クラスメンバ詳解";
+ }
+ }
+ else
+ {
+ if (forC)
+ {
+ result+="各フィールドが属する構造体・共用体";
+ }
+ else
+ {
+ result+="各メンバが属するクラス";
+ }
+ }
+ result += "へのリンクがあります。";
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool /*extractAll*/)
+ {
+ QCString result;
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="関数・変数・マクロ・列挙・型定義";
+ }
+ else
+ {
+ result+="ファイル直下のメンバ";
+ }
+ result+="一覧です。各々詳解があればそこへリンクしています。";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "各種例の一覧です。"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "諸情報の一覧です。"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "全モジュールの一覧です。"; }
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "詳解"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "モジュール索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "階層索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造索引";
+ }
+ else
+ {
+ return "クラス索引";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "ファイル索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "モジュール詳解"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造詳解";
+ }
+ else
+ {
+ return "クラス詳解";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "ファイル詳解"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "各例詳解"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "ページ詳解"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "リファレンスマニュアル"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "マクロ定義"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "型定義"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "列挙型"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "関数"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "変数"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "列挙値"; }
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "マクロ定義詳解"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "型定義詳解"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "列挙型詳解"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "関数詳解"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "変数詳解"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造";
+ }
+ else
+ {
+ return "クラス";
+ }
+ }
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result = (QCString)date+"作成";
+ if (projName) result+=(QCString)" - " + projName;
+ result+=" / 構成: ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)clName+" の継承関係図";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "内部処理用です。"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "警告"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "バージョン"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "日付"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "戻り値"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "参照"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "引数"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "例外"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "構築:"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "名前空間一覧"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ if (extractAll)
+ {
+ return "全名前空間の一覧です。";
+ }
+ return "詳解が付いた名前空間の一覧です。";
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "フレンド"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "フレンドと関連関数の詳解"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName+" ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="クラス"; break;
+ case ClassDef::Struct: result+="構造体"; break;
+ case ClassDef::Union: result+="共用体"; break;
+ case ClassDef::Interface: result+="インタフェース"; break;
+ case ClassDef::Protocol: result+="プロトコル"; break;
+ case ClassDef::Category: result+="カテゴリ"; break;
+ case ClassDef::Exception: result+="例外"; break;
+ default: break;
+ }
+ if (isTemplate) result+="テンプレート";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=(QCString)fileName+" ファイル";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=(QCString)namespaceName+" 名前空間";
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ virtual QCString trPublicMembers()
+ { return "公開メンバ関数"; }
+ virtual QCString trPublicSlots()
+ { return "公開スロット"; }
+ virtual QCString trSignals()
+ { return "シグナル"; }
+ virtual QCString trStaticPublicMembers()
+ { return "静的公開メンバ関数"; }
+ virtual QCString trProtectedMembers()
+ { return "限定公開メンバ関数"; }
+ virtual QCString trProtectedSlots()
+ { return "限定公開スロット"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "静的限定公開メンバ関数"; }
+ virtual QCString trPrivateMembers()
+ { return "非公開メンバ関数"; }
+ virtual QCString trPrivateSlots()
+ { return "非公開スロット"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "静的非公開メンバ関数"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ result+=", ";
+ }
+ }
+ if ( result.length() > 60 )
+ {
+ QCString countStr;
+ countStr.sprintf(" (計%d項目)", numEntries);
+ result += countStr;
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return trWriteList(numEntries)+"を継承しています。";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return trWriteList(numEntries)+"に継承されています。";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return trWriteList(numEntries)+"を再実装しています。";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return trWriteList(numEntries)+"で再実装されています。";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "名前空間メンバ"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="これは";
+ result+="名前空間の一覧です。それぞれ";
+ if (extractAll)
+ {
+ result+="の名前空間";
+ }
+ else
+ {
+ result+="が属している名前空間";
+ }
+ result+="へリンクしています。";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "名前空間索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "名前空間詳解"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "名前空間"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool /*single*/)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"この";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="クラス"; break;
+ case ClassDef::Struct: result+="構造体"; break;
+ case ClassDef::Union: result+="共用体"; break;
+ case ClassDef::Interface: result+="インタフェース"; break;
+ case ClassDef::Protocol: result+="プロトコル"; break;
+ case ClassDef::Category: result+="カテゴリ"; break;
+ case ClassDef::Exception: result+="例外"; break;
+ default: break;
+ }
+ result+="詳解は次のファイルから抽出されました:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "戻り値"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "総合概要"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return " @1 の @0 行目に定義があります。";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return " @0 に定義があります。";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "非推奨";
+ }
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)clName+" 連携図";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)fName+" の依存先関係図:";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "構築子と解体子";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "[ソースコード]";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "[詳解]";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "事前条件";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "事後条件";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "不変";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "初期値:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "コード";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "クラス階層図";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "[クラス階層図]";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "[クラス階層表]";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "ページ索引";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "覚え書き";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "公開型";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "フィールド";
+ }
+ else
+ {
+ return "公開変数類";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "静的公開変数類";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "限定公開型";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "限定公開変数類";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "静的限定公開変数類";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "非公開型";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "非公開変数類";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "静的非公開変数類";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "todo";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "todo一覧";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "参照元";
+ }
+ virtual QCString trRemarks()
+ {
+ return "注釈";
+ }
+ virtual QCString trAttention()
+ {
+ return "注意";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "被依存関係図:";
+ }
+ virtual QCString trSince()
+ {
+ return "から";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "グラフの凡例";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Doxygen が生成したグラフを読み方について。<p>\n"
+ "次のコード例をご覧ください。\n"
+ "\\code\n"
+ "/*! 全体の大きさの関係で見えなくなるクラスです。 */\n"
+ "class Invisible { };\n\n"
+ "/*! 表示を切り捨てられたクラス(Invisibleクラスの分が見えません) */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Doxygen 用のコメントコードがないクラス */\n"
+ "class Undocumented { };\n\n"
+ "/*! 公開継承されているクラス */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! 限定公開で継承されているクラス */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! 非公開継承されているクラス */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Inherited クラス内で使われているクラス */\n"
+ "class Used { };\n\n"
+ "/*! 複数のクラスを継承している上位クラス */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "\\c MAX_DOT_GRAPH_" /* わざわざちょん切っているのは doc/translator.py の検出回避のため */
+ "HEIGHT タグに 200 を与えた設定ファイル"
+ "を使うと、次のようなグラフとなります。"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "グラフ内の矩形は構造体やクラスを表しています。色の意味は次の通りです。\n"
+ "<ul>\n"
+ "<li>中を黒く塗られた四角は、図が注目している起点です。</li>\n"
+ "<li>黒枠は詳解があることを示しています。</li>\n"
+ "<li>灰色枠で示されたクラス等には詳解がありません。</li>\n"
+ "<li>赤枠で示されたものは詳解を持つクラスですが、"
+ "指定された大きさに収まらないことから一部の継承・包含関係が"
+ "省略されていることを表します。</li>\n"
+ "</ul>\n"
+ "<p>矢印の意味は次の通りです。</p>\n"
+ "<ul>\n"
+ "<li>青い矢印は二つのクラス間の公開継承関係を示します。</li>\n"
+ "<li>緑の矢印は限定公開の継承関係を示します。</li>\n"
+ "<li>赤の矢印は非公開の継承関係を示します。</li>\n"
+ "<li>紫の破線矢印は、そのクラスが他のクラスに含まれているか、"
+ "利用されていることを示します。また、矢印のラベルは矢の先にあるクラス等を"
+ "アクセスしている矢の根本のメンバを表しています。</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "凡例";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "テスト";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "テスト一覧";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "プロパティ";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "プロパティ詳解";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "データ構造";
+ }
+ else
+ {
+ return "クラス";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)name+" パッケージ";
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "パッケージ一覧";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "パッケージ一覧です。";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "パッケージ";
+ }
+
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "値:";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "バグ";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "バグ一覧";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "932";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "128";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "索引";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "クラス";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "ファイル";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "名前空間";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "グループ";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "ページ";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "メンバ";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "大域各種";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "著者";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "参照先";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return trWriteList(numEntries)+"を実装しています。";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return trWriteList(numEntries)+"で実装されています。";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "目次";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "非推奨一覧";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "イベント";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "イベント詳解";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "パッケージ内の型定義";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "関数";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "静的関数";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "変数";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "静的変数";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "全て";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "呼び出し関係図:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "検索結果";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "入力条件を満たす文書がありません。";
+ }
+ else if (numDocuments==1)
+ {
+ return "入力条件を満たす文書が <b>1</b> 件ありました.";
+ }
+ else
+ {
+ return "入力条件を満たす文書が <b>$num</b> 件ありました. "
+ "一致度の高いものから表示されます.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "照合語:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " ソースファイル";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "ディレクトリ索引"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "ディレクトリ詳解"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "ディレクトリ"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "このディレクトリ一覧はおおまかにはソートされていますが、"
+ "完全にアルファベット順でソートされてはいません。";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" ディレクトリリファレンス"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool, bool)
+ {
+ return "ディレクトリ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "これはオーバーロードされたメンバ関数です。"
+ "利便性のために用意されています。"
+ "元の関数との違いは引き数のみです。";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "被呼び出し関係図:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "列挙型詳解"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "メンバ関数/サブルーチン詳解"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "データ型一覧"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "データフィールド"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "これはデータ型の一覧です:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="これは";
+ result+="フィールドの一覧です。それぞれ";
+ if (extractAll)
+ {
+ result+="が属しているデータ型";
+ }
+ result+="の詳解へリンクしています。";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "データ型索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "データ型詳解"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "関数/サブルーチン"; }
+
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "関数/サブルーチン詳解"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "データ型"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "モジュール一覧"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result;
+ if (!extractAll)
+ {
+ result+="詳解が記されている";
+ }
+ else
+ {
+ result+="全";
+ }
+ result+="モジュールの一覧です";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="モジュール "; break;
+ case ClassDef::Struct: result+="TYPE "; break;
+ case ClassDef::Union: result+="共用体 "; break;
+ case ClassDef::Interface: result+="インターフェース "; break;
+ case ClassDef::Protocol: result+="プロトコル "; break;
+ case ClassDef::Category: result+="カテゴリ "; break;
+ case ClassDef::Exception: result+="例外 "; break;
+ default: break;
+ }
+ if (isTemplate) result += "テンプレート ";
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+="モジュール";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "モジュールメンバ"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="これはモジュールメンバ一覧です。それぞれ ";
+ if (extractAll)
+ {
+ result+="属しているモジュール";
+ }
+ result+="の詳解へリンクしています。";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "モジュール索引"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool /*first_capital*/, bool /*singular*/)
+ {
+ return "モジュール";
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool /*single*/)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result="次のファイルから";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="モジュール"; break;
+ case ClassDef::Struct: result+="型"; break;
+ case ClassDef::Union: result+="共用体"; break;
+ case ClassDef::Interface: result+="インターフェース"; break;
+ case ClassDef::Protocol: result+="プロトコル"; break;
+ case ClassDef::Category: result+="カテゴリ"; break;
+ case ClassDef::Exception: result+="例外"; break;
+ default: break;
+ }
+ result+="の詳解が抽出されました:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool /*first_capital*/, bool /*singular*/)
+ {
+ QCString result = "型";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool /*first_capital*/, bool /*singular*/)
+ {
+ QCString result = "サブプログラム";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "型制約";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" 関係";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "読み取り中…";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "大域名前空間";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "検索中…";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "一致する文字列を見つけられません";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)name+"にあるファイル";
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)name+"にあるファイルを include している";
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "月", "火", "水", "木", "金", "土", "日" };
+ QCString sdate;
+ sdate.sprintf("%.4d年%.2d月%.2d日(%s)",year,month,day,days[dayOfWeek-1]);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d時%.2d分%.2d秒",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "書誌参照"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "著作権所有"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString(name)+" のディレクトリ依存関係図"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "表示階層"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "テンプレート引数"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "ほか "+number+" 件…"; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool)
+ {
+ return "次のファイルからこの列挙についての詳解を抽出しました:";
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString("列挙 ")+name+" 詳解"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString("基底クラス ")+what+" に属する継承"+members; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "その他の継承メンバ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+
+ QCString opt = enable ? "有効" : "無効";
+ return "クリックで同期表示が"+opt+"になります";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "@1 カテゴリーから提供されています。";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "@1 を拡張しています。";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "クラスメソッド";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "実体メソッド";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "メソッド詳解";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "デザイン概観";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "実装されたインターフォース"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "継承されたサービス"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "定数グループ"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" 定数グループ詳解";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" サービス詳解";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Singleton 詳解";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool /*single*/)
+ {
+ // single is true implies a single file
+ return "次のファイルからこのサービスについて"
+ "の詳解を抽出しました:";
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool /*single*/)
+ {
+ // single is true implies a single file
+ return "次のファイルからこの Singleton について"
+ "の詳解を抽出しました:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_ke.h b/src/translator_ke.h
new file mode 100644
index 0000000..56a70b3
--- /dev/null
+++ b/src/translator_ke.h
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+//
+// Update:
+//
+// 2004.12.22 (SooYoung Jung: jung5000 at gmail.com)
+// - LaTex and RTF were not generated correctly.
+// Corrected trRTFansicp and trRTFCharSet.
+// It was wrong.
+//
+//
+
+#ifndef TRANSLATOR_KE_H
+#define TRANSLATOR_KE_H
+
+class TranslatorKoreanEn : public TranslatorEnglish
+{
+ public:
+ virtual QCString idLanguage()
+ { return "korean-en"; }
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage{hfont}\n";
+ }
+ virtual QCString trRTFansicp()
+ {
+ return "949";
+ }
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "129";
+ }
+};
+
+#endif
diff --git a/src/translator_kr.h b/src/translator_kr.h
new file mode 100644
index 0000000..6919763
--- /dev/null
+++ b/src/translator_kr.h
@@ -0,0 +1,2009 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_KR_H
+#define TRANSLATOR_KR_H
+
+
+/* Korean translators
+ * doxygen-svn
+ * * fly1004 at gmail.com
+ * doxygen-1.5.3
+ * * Astromaker(http://ngps.net/)
+ * * gpgiki(http://www.gpgstudy.com/gpgiki/)
+ * doxygen-1.2.11
+ * * ryk */
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorKorean : public Translator
+{
+ protected:
+ friend class TranslatorAdapterBase;
+ virtual ~TranslatorKorean() {}
+
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "korean"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ // I'm not sure what this should be.
+ // When I figure it out, I'll update this.
+ // see http://www.ktug.or.kr/jsboard/read.php?table=operate&no=4422&page=1
+ return "\\usepackage{hfont}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "관련된 함수들"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(다음은 멤버 함수들이 아닙니다. 주의하십시오.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "상세한 설명"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "멤버 타입정의 문서화"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "멤버 열거형 문서화"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "멤버 함수 문서화"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "필드 문서화";
+ }
+ else
+ {
+ return "멤버 데이타 문서화";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "더 자세히 ..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "모든 멤버 목록"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "멤버 목록"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "다음에 대한 모든 멤버의 목록입니다 : "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return " (모든 상속된 멤버들도 포함합니다.)"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="소스 코드로부터 ";
+ if (s) result+=s+(QCString)"를 위해 ";
+ result+="Doxygen에 의해 자동으로 생성됨.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "열거형 이름"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "열거형 값"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "다음에서 정의됨 :"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "모듈"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "클래스 계통도"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 구조";
+ }
+ else
+ {
+ return "클래스 목록";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "파일 목록"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 필드";
+ }
+ else
+ {
+ return "클래스 멤버";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "전역";
+ }
+ else
+ {
+ return "파일 멤버";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "관련된 페이지"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "예제"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "검색"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "이 상속 목록은 완전하진 않지만 알파벳순으로 대략적으로 정렬되어있습니다.:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+ result+="모든 파일에 대한 목록입니다. (간략한 설명만을 보여줍니다) :";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "다음은 데이타 구조들입니다. (간략한 설명만을 보여줍니다) :";
+ }
+ else
+ {
+ return "다음은 클래스, 구조체, 공용체 그리고 인터페이스들입니다. "
+ "(간략한 설명만을 보여줍니다) :";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll)
+ {
+ result+="문서화된 ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="모든 구조체와 공용체의 필드들";
+ }
+ else
+ {
+ result+="모든 클래스 멤버들";
+ }
+ result+="의 목록입니다. ";
+
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="각 필드들은 해당 필드에 대한 구조체와 공용체의 "
+ "문서화 페이지의 링크를 가지고 있습니다. :";
+ }
+ else
+ {
+ result+="각 멤버들은 해당 멤버에 대한 클래스의 문서화 페이지의 "
+ "링크를 가지고 있습니다. :";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="각 필드들은 해당 필드가 속해 있는 구조체와 공용체에 "
+ "대한 링크를 가지고 있습니다. :";
+ }
+ else
+ {
+ result+="각 멤버들은 해당 멤버가 속해 있는 클래스에 대한 "
+ "링크를 가지고 있습니다. :";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="모든 함수, 변수, 매크로, 열거형, 타입정의들";
+ }
+ else
+ {
+ result+="파일 멤버들";
+ }
+ result+="의 목록입니다. ";
+
+ result+="각 항목은 ";
+ if (extractAll)
+ result+="그들이 속한 파일 페이지의 링크를 가지고 있습니다. :";
+ else
+ result+="그들에 대한 문서화 페이지의 링크를 가지고 있습니다. :";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "다음은 모든 예제들의 목록입니다.:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "다음은 관련된 모든 문서화 페이지들의 목록입니다.:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "다음은 모든 모듈들의 목록입니다.:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "문서화"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "모듈 색인"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "계통도 색인"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 구조 색인";
+ }
+ else
+ {
+ return "클래스 색인";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "파일 색인"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "모듈 문서화"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 구조 문서화";
+ }
+ else
+ {
+ return "클래스 문서화";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "파일 문서화"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "예제 문서화"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "페이지 문서화"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "참조 매뉴얼"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "매크로"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "타입정의"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "열거형 타입"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "함수"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "변수"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "열거형 멤버"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "매크로 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "타입정의 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "열거형 타입 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "함수 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "변수 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 구조";
+ }
+ else
+ {
+ return "클래스";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"생성시간 : "+date;
+ if (projName) result+=(QCString)", 프로젝트명 : "+projName;
+ result+=(QCString)", 생성자 : ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)clName+"에 대한 상속 다이어그램 : ";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "내부적적으로만 사용하기 위해."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "경고"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "버전"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "날짜"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "반환값"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "참고"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "매개변수"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "예외"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "다음에 의해 생성됨 : "; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "네임스페이스 목록"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+ result+="모든 네임스페이스에 대한 목록입니다. (간략한 설명만을 보여줍니다) :";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Friend, 그리고 관련된 함수 문서화"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" 클래스"; break;
+ case ClassDef::Struct: result+=" 구조체"; break;
+ case ClassDef::Union: result+=" 공용체"; break;
+ case ClassDef::Interface: result+=" 인터페이스"; break;
+ case ClassDef::Protocol: result+=" 프로토콜"; break;
+ case ClassDef::Category: result+=" 카테고리"; break;
+ case ClassDef::Exception: result+=" 예외"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" 템플릿";
+ result+=" 참조";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" 파일 참조";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" 네임스페이스 참조";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Public 멤버 함수"; }
+ virtual QCString trPublicSlots()
+ { return "Public Slots"; }
+ virtual QCString trSignals()
+ { return "Signals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "정적 Public 멤버 함수"; }
+ virtual QCString trProtectedMembers()
+ { return "Protected 멤버 함수"; }
+ virtual QCString trProtectedSlots()
+ { return "Protected Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "정적 Protected 멤버 함수"; }
+ virtual QCString trPrivateMembers()
+ { return "Private 멤버 함수"; }
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "정적 Private 멤버 함수"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return trWriteList(numEntries)+"를(을) 상속했습니다.";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return trWriteList(numEntries)+"에 의해 상속되었습니다.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return trWriteList(numEntries)+"(으)로부터 재구현되었습니다.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return trWriteList(numEntries)+"에서 재구현되었습니다.";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "네임스페이스 멤버"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+ result+="모든 네임스페이스 멤버들의 목록입니다. ";
+ if (extractAll)
+ result+="각 멤버들은 해당 멤버의 네임스페이스 문서화 페이지의 링크를 가지고 있습니다. :";
+ else
+ result+="각 멤버들은 해당 멤버가 속한 네임스페이스 페이지의 링크를 가지고 있습니다. :";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "네임스페이스 색인"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "네임스페이스 문서화"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "네임스페이스"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"이 ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="클래스"; break;
+ case ClassDef::Struct: result+="구조체"; break;
+ case ClassDef::Union: result+="공용체"; break;
+ case ClassDef::Interface: result+="인터페이스"; break;
+ case ClassDef::Protocol: result+="프로토콜"; break;
+ case ClassDef::Category: result+="카테고리"; break;
+ case ClassDef::Exception: result+="예외"; break;
+ default: break;
+ }
+ result+="에 대한 문서화 페이지는 다음의 파일";
+ if (!single) result+="들";
+ result+="로부터 생성되었습니다.:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "반환값"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "메인 페이지"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "페이지"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "@1 파일의 @0 번째 라인에서 정의되었습니다.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "@0 파일에서 정의되었습니다.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "잘못된 코드";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)clName+"에 대한 협력 다이어그램:";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)fName+"에 대한 include 의존 그래프";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "생성자 & 소멸자 문서화";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "이 파일의 소스 코드 페이지로 가기";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "이 파일의 문서화 페이지로 가기";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "전제조건";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "후미조건";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "변하지 않는";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "초기값:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "코드";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "그래픽컬한 클래스 계통도";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "그래픽컬한 클래스 계통도 페이지로 가기";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "텍스트 형식의 클래스 계통도 페이지로 가기";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "페이지 색인";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "주의";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Public 타입";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 필드";
+ }
+ else
+ {
+ return "Public 속성";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "정적 Public 속성";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Protected 타입";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Protected 속성";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "정적 Protected 속성";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Private 타입";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private 속성";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "정적 Private 속성";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "할일";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "할일 목록";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "다음에 의해서 참조됨 : ";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Remarks";
+ }
+ virtual QCString trAttention()
+ {
+ return "주의";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "이 그래프는 이 파일을 직/간접적으로 include 하는 파일들을 보여줍니다.:";
+ }
+ virtual QCString trSince()
+ {
+ return "Since";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "그래프 범례";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "이 페이지는 doxygen에 의해 생성된 그래프들을 이해하는 방법을 설명합니다.<p>\n"
+ "다음의 예제를 참고하십시오.:\n"
+ "\\code\n"
+ "/*! 생략되었기 때문에 보이지 않는 클래스 */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated 클래스, 상속관계가 숨겨짐 */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* doxygen 주석에 의해서 문서화되지 않는 클래스 */\n"
+ "class Undocumented { };\n\n"
+ "/*! public 상속을 통해서 상속된 클래스 */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! 템플릿 클래스 */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! protected 상속을 통해서 상속된 클래스 */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! private 상속을 통해서 상속된 클래스 */\n"
+ "class PrivateBase { };\n\n"
+ "/*! 상속되어진 클래스에 의해 (멤버로) 사용되어지는 클래스 */\n"
+ "class Used { };\n\n"
+ "/*! 다른 클래스들을 상속하는 슈퍼 클래스 */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "다음과 같은 그래프가 출력될 것입니다. :"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "위 그래프의 박스들은 다음과 같은 의미를 가집니다. :\n"
+ "<ul>\n"
+ "<li>%A 회색으로 채워진 박스는 이 그래프를 생성해 낸 구조체나 클래스를 의미합니다.\n"
+ "<li>%A 검은색 테두리의 박스는 문서화된 구조체나 클래스를 의미합니다.\n"
+ "<li>%A 회색 테두리의 박스는 문서화되지 않은 구조체나 클래스를 의미합니다.\n"
+ "<li>%A 빨간색 테두리의 박스는 모든 상속이나 포함관계가 보여지지 않는 "
+ "구조체나 클래스를 의미합니다."
+ "%A 만약 그래프가 지정된 경계내에 맞지 않으면, 그래프가 잘려집니다.\n"
+ "</ul>\n"
+ "화살표들은 다음과 같은 의미를 가집니다. :\n"
+ "<ul>\n"
+ "<li>%A 어두운 파랑색 화살표는 두 클래스들 간에 public 상속이 있음을 의미합니다.\n"
+ "<li>%A 어두운 연두색 화살표는 protected 상속이 있음을 의미합니다.\n"
+ "<li>%A 어두운 빨간색 화살표는 private 상속이 있음을 의미합니다.\n"
+ "<li>%A 보라색 점선 화살표는 다른 클래스에 의해 포함되거나 사용되어짐을 의미합니다. "
+ "화살표의 라벨은 화살표가 가리키는 클래스나 구조체로 접근하는 변수명(들)으로 붙습니다.\n"
+ "<li>%A 노란색 점선 화살표는 템플릿 인스턴스와 템프릿 클래스에 대한 관계를 의미합니다. "
+ "화살표의 라벨은 인스턴스의 템플릿 파라메터로 붙습니다.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "범례";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "테스트";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "테스트 목록";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "속성";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "속성 문서화";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "데이타 구조";
+ }
+ else
+ {
+ return "클래스";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return name+(QCString)" 패키지";
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "패키지 목록";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "다음은 패키지들입니다. (가능한한 간략한 설명만을 보여줍니다) :";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "패키지";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "값:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "버그";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "버그 목록";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "949";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "129";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "색인";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "클래스" : "클래스"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "파일" : "파일"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "네임스페이스" : "네임스페이스"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "그룹" : "그룹"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "페이지" : "페이지"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "멤버" : "멤버"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "전역" : "전역"));
+ if (!singular) result+="";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "작성자" : "작성자"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "다음을 참조함 : ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return trWriteList(numEntries)+"를 구현.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return trWriteList(numEntries)+"에서 구현되었습니다.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "목차";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "잘못된 코드 목록";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "이벤트";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "이벤트 문서화";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "패키지 타입";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "패키지 함수";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "정적 패키지 함수";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "패키지 속성";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "정적 패키지 속성";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "모두";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "검색 결과";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "죄송합니다. 질의에 일치하는 문서가 없습니다.";
+ }
+ else if (numDocuments==1)
+ {
+ return "질의에 일치하는 <b>1</b> 개의 문서를 찾았습니다.";
+ }
+ else
+ {
+ return "질의에 일치하는 <b>$num</b> 개의 문서를 찾았습니다. "
+ "가장 많이 일치하는 문서를 가장 먼저 보여줍니다.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "결과:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " 소스 파일";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "디렉토리 계통도"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "디렉토리 문서화"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "디렉토리"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "이 디렉토리 목록은 완전하진 않지만, (대략적으로) 알파벳순으로 정렬되어있습니다.:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" 디렉토리 참조"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "디렉토리" : "디렉토리"));
+ if (singular) result+=""; else result+="들";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "이 함수는 편의를 제공하기 위해 오버로드된 멤버 함수입니다. "
+ "위의 함수와 틀린 점은 단지 받아들이는 아규먼트(argument)가 다르다는 것입니다.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "이 함수를 호출하는 함수들에 대한 그래프입니다.:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "열거형 문서화"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "멤버 함수/서브루틴 문서화"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "데이타 타입 목록"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "데이타 필드"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "대략적인 설명과 함께 데이타 타입들의 목록입니다.:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll)
+ {
+ result+="문서화된 ";
+ }
+ result+="모든 데이타 타입 멤버들의 목록입니다. ";
+
+ result+="각 항목은 ";
+ if (!extractAll)
+ {
+ result+="각 멤버에 대한 데이타 구조 문서화 페이지의 링크를 가지고 있습니다.";
+ }
+ else
+ {
+ result+="그들이 속한 데이타 타입의 링크를 가지고 있습니다. :";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "데이타 타입 색인"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "데이타 타입 문서화"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "함수/서브루틴"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "함수/서브루틴 문서화"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "데이타 타입들"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "모듈 목록"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+ result+="모든 모듈에 대한 목록입니다. (간략한 설명만을 보여줍니다) :";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" 모듈"; break;
+ case ClassDef::Struct: result+=" 타입"; break;
+ case ClassDef::Union: result+=" 공용체"; break;
+ case ClassDef::Interface: result+=" 인터페이스"; break;
+ case ClassDef::Protocol: result+=" 프로토콜"; break;
+ case ClassDef::Category: result+=" 카테고리"; break;
+ case ClassDef::Exception: result+=" 예외"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" 템플릿";
+ result+=" 참조";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" 모듈 참조";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "모듈 멤버들"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="다음은 ";
+ if (!extractAll) result+="문서화된 ";
+ result+="모든 모듈 멤버의 목록입니다. ";
+ if (extractAll)
+ {
+ result+="각 항목은 각 멤버의 모듈 문서화 페이지의 링크를 가지고 있습니다. :";
+ }
+ else
+ {
+ result+="각 항목은 그들이 속한 모듈의 링크를 가지고 있습니다. :";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "모듈 색인"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "모듈" : "모듈"));
+ if (!singular) result+="들";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"다음 파일";
+ if (single) result+=""; else result+="들";
+ result+="로부터 생성된 ";
+ result+="이 ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="모듈"; break;
+ case ClassDef::Struct: result+="타입"; break;
+ case ClassDef::Union: result+="공용체"; break;
+ case ClassDef::Interface: result+="인터페이스"; break;
+ case ClassDef::Protocol: result+="프로토콜"; break;
+ case ClassDef::Category: result+="카테고리"; break;
+ case ClassDef::Exception: result+="예외"; break;
+ default: break;
+ }
+ result+="의 문서화 페이지:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "타입" : "타입"));
+ if (!singular) result+="들";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "서브프로그램" : "서브프로그램"));
+ if (!singular) result+="들";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "타입 한정자들";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" 관계";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "로딩중...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "전역 이름공간";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "검색중...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "일치하는것 없음";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return QCString(name) + "의 파일";
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return QCString(name) + "의 파일 포함";
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "월","화","수","목","금","토","일" };
+ static const char *months[] = { "1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "참고 문헌"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString(name) + QCString("에 대한 디렉토리 의존성 그래프:"); }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "상세 단계"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "템플릿 파라메터"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return QCString("그리고 ")+number+"개 더..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool /*single*/)
+ { QCString result = "이 열거형에 대한 문서가 다음 파일(들)로부터 생성되었습니다.:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum Reference"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(what) + QCString("(으)로부터 상속된 ") + QCString(members); }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "추가로 상속된 멤버들"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "활성화" : "비활성화";
+ return "패널 동기화를 "+opt+"하기 위해 클릭하십시오";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "카테고리 @1에 의해 제공됨.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "클래스 @1 확장.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "클래스 메소드들";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "인스턴스 메소드들";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "메소드 문서화";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "디자인 개요";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "익스포트된 인터페이스들"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "포함된 서비스들"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "상수 그룹들"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" 상수 그룹 레퍼런스";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" 서비스 레퍼런스";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" 싱글톤 레퍼런스";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"이 서비스에 대한 문서화는 다음의 파일";
+ if (!single) result+="들";
+ result+="로부터 생성되었습니다.:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"이 싱글톤에 대한 문서화는 다음의 파일";
+ if (!single) result+="들";
+ result+="로부터 생성되었습니다.:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_lt.h b/src/translator_lt.h
new file mode 100644
index 0000000..000dc6e
--- /dev/null
+++ b/src/translator_lt.h
@@ -0,0 +1,1515 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/* Translation from English to Lithanian by Tomas Simonaitis, Mindaugas Radzius and Aidas Berukstis
+ * (haden at homelan.lt/mindaugasradzius at takas.lt/aidasber at takas.lt)
+ * We tried to keep meaning close to original,
+ * if you have any suggestions drop us an email
+ * -------------------------------------------
+ * Project start :13.May.2k4
+ * Last Doxygen version covered : 1.4.3
+ *
+ * Revisions:
+ * Updated to 1.3.9 25.Oct.2k4
+ *
+*/
+
+#ifndef TRANSLATOR_LT_H
+#define TRANSLATOR_LT_H
+
+
+class TranslatorLithuanian : public TranslatorAdapter_1_4_6
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "lithuanian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[T2A]{fontenc}\n"
+ "\\usepackage[lithuanian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Susiję Funkcijos"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "Atkreipkite dėmesį, čią ne metodai"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Smulkus aprašymas"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Tipo Aprašymo Dokumentacija"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Išvardinimo Dokumentacija"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Metodų Dokumentacija"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Lauko aprašymas";
+ }
+ else
+ {
+ return "Atributų Dokumentacija";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Daugiau..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Visų narių sąrašas"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Narių sąrašas"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Tai galutinis narių sąrašas "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", įtraukiant visus paveldėtus narius."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automatiškai sugeneruota Doxygen įrankiu";
+ if (s) result+=(QCString)" "+s;
+ result+=" iš programos kodo.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "išvardinimo vardas"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "išvardinimo reikšmė"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "apibrėžta"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduliai"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klasių hierarchija"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Struktūros";
+ }
+ else
+ {
+ return "Klasės";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Failai"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Laukai";
+ }
+ else
+ {
+ return "Klasių Nariai";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globalūs Nariai";
+ }
+ else
+ {
+ return "Globalūs Nariai";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Susiję Puslapiai"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Pavyzdžiai"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Paieška"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Šis paveldėjimo sąrašas yra beveik surikiuotas "
+ "abėcėlės tvarka:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Visų ";
+ if (!extractAll) result+="dokumentuotų ";
+ result+="failų sąrašas su trumpais aprašymais:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų struktūros su trumpais aprašymais:";
+ }
+ else
+ {
+ return "Klasės, struktūros, "
+ "sąjungos ir sąsajos su trumpais aprašymais:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Visų ";
+ if (!extractAll)
+ {
+ result+="dokumentuotų ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūrų ir sąjungų laukų sąrašas";
+ }
+ else
+ {
+ result+="klasių nariai";
+ }
+ result+=" su ryšiais į ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūrų/sąjungų kiekvieno lauko dokumentaciją:";
+ }
+ else
+ {
+ result+="klasės dokumentacija kiekvienam nariui:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūros/sąjungos, kurios priklauso:";
+ }
+ else
+ {
+ result+="klasės, kurios priklauso:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Sąrašas visų ";
+ if (!extractAll) result+="dokumentuotų ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcijų, kintamųjų, apibrėžimų, išvardinimų, ir tipų apibrėžimų";
+ }
+ else
+ {
+ result+="globalių narių";
+ }
+ result+=" su ryšiais į ";
+ if (extractAll)
+ result+="failus, kuriems jie priklauso:";
+ else
+ result+="dokumentacija:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Visų pavyzdžių sąrašas:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Visų susijusių dokumentacijos puslapių sąrašas:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Visų modulių sąrašas:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modulio Indeksas"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarchijos Indeksas"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Struktūros Indeksas";
+ }
+ else
+ {
+ return "Klasės Indeksas";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Failo Indeksas"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modulio Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Struktūros Dokumentacija";
+ }
+ else
+ {
+ return "Klasės Dokumentacija";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Failo Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Pavyzdžio Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Puslapio Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Informacinis Vadovas"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Apibrėžimai"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Tipų apibrėžimai"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Išvardinimai"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkcijos"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Kintamieji"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Išvardinimų reikšmės"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Apibrėžimų Dokumentacija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Tipų apibrėžimų Dokumentacija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Išvardinimo Tipo Dokumentacija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funkcijos Dokumentacija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Kintamojo Dokumentacija"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų struktųros";
+ }
+ else
+ {
+ return "Klasės";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Sugeneruota "+date;/*FIXME*/
+ if (projName) result+=(QCString)" "+projName;/*FIXME*/
+ result+=(QCString)" ";/*FIXME*/
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Paveldimumo diagrama "+clName+":"; /*FIXME*/
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Tiktai vidiniam naudojimui."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Įspėjimas"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versija"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Gražina"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Taip pat žiūrėti"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametrai"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Išimtys"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Sugeneruota"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Varų Srities Sąrašas"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Sąrašas visų ";
+ if (!extractAll) result+="dokumentuotų ";
+ result+="vardų sričių su trumpais aprašymais:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Draugai"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Draugiškų Ir Susijusių Funkcijų Dokumentacija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Klasė"; break;
+ case ClassDef::Struct: result+=" Struktūra"; break;
+ case ClassDef::Union: result+=" Sąjunga"; break;
+ case ClassDef::Interface: result+=" Sąsaja"; break;
+ case ClassDef::Protocol: result+=" Protokolas"; break;
+ case ClassDef::Category: result+=" Kategorija"; break;
+ case ClassDef::Exception: result+=" Išimtis"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Šablonas";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" Failo Nuoroda";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Vardų Srities Nuoroda";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Vieši Metodai"; }
+ virtual QCString trPublicSlots()
+ { return "Vieši Slotai"; } /*FIXME*/
+ virtual QCString trSignals()
+ { return "Signalai"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiniai Vieši Metodai"; }
+ virtual QCString trProtectedMembers()
+ { return "Apsaugoti Metodai"; }
+ virtual QCString trProtectedSlots()
+ { return "Apsaugoti Slotai"; }/*FIXME*/
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiniai Apsaugoti Metodai"; }
+ virtual QCString trPrivateMembers()
+ { return "Privatatūs Metodai"; }
+ virtual QCString trPrivateSlots()
+ { return "Privatūs Slotai"; }/*FIXME*/
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiniai Privatūs Metodai"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", ir ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Paveldi "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Paveldėta "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Perkrauna metodą iš "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Metodas perkraunamas "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Vardų Srities Nariai"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Sąrašas visų ";
+ if (!extractAll) result+="dokumentuotų ";
+ result+="vardų srities narių su nuorodomis į ";
+ if (extractAll)
+ result+="vardų srities dokumentaciją kiekvienam nariui:";
+ else
+ result+="vardų sritis, kurioms jos priklauso:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Vardų Srities Indeksas"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Vardų Srities Dokumentacija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Vardų Sritys"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacija ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="šiai klasei"; break;
+ case ClassDef::Struct: result+="šiai struktūrai"; break;
+ case ClassDef::Union: result+="šiai sąjungai"; break;
+ case ClassDef::Interface: result+="šiai sąsajai"; break;
+ case ClassDef::Protocol: result+="šiam protocolui"; break;
+ case ClassDef::Category: result+="šiai kategorijai"; break;
+ case ClassDef::Exception: result+="šiai išimčiai"; break;
+ default: break;
+ }
+ result+=" sugeneruota iš ";
+ if (single) result+="šio failo:"; else result+="šių failų:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Gražinamos reikšmės"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Pagrindinis Puslapis"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "psl."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Apibrėžimas failo @1 eilutėje @0.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Apibrėžimas faile @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Smerktina";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Bendradarbiavimo diagrama "+clName+":";/*FIXME*/
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Įtraukimo priklausomybių diagrama "+fName+":";/*FIXME*/
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruktoriaus ir Destruktoriaus Dokumentacija";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Eiti į šio failo programos kodą.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Eiti į šio failo dokumentaciją.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Išakstinė sąlyga";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondition";/*FIXME*/
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Pastovus";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Pradinė reikšmė:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "tekstas";/*FIXME*/
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafinė Klasės Hierarchija";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Eiti į grafinę klasės hierarchiją";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Eiti į tekstinę klasės hierarchiją";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Puslapio Indeksas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Pastaba";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Vieši Tipai";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Laukai";
+ }
+ else
+ {
+ return "Vieši Atributai";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statiniai Vieši Atributai";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Apsaugoti Tipai";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Apsaugoti Atributai";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statiniai Apsaugoti Atributai";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privatūs Tipai";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privatūs Atributai";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statiniai Privatūs Atributai";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Daryti";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Tolimesni Darbai";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Naudojamas";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Pastabos";
+ }
+ virtual QCString trAttention()
+ {
+ return "Attention";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Šis grafas rodo, kuris failas tiesiogiai ar "
+ "netiesiogiai įtraukia šį failą:";
+ }
+ virtual QCString trSince()
+ {
+ return "Nuo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Grafo Legenda";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Šis puslapis paaiškina, kaip interpretuoti sugeneruotus grafus "
+ "su Doxygen įrankiu.<p>\n"
+ "Panagrinėkite pavyzdį:\n"
+ "\\kodo pradžia\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "If the \\c MAX_DOT_GRAPH_HEIGHT tag in the configuration file "
+ "is set to 240 this will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A filled black box represents the struct or class for which the "
+ "graph is generated.\n"
+ "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>%A box with a red border denotes a documented struct or class for"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries.\n"
+ "</ul>\n"
+ "The arrows have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.\n"
+ "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible.\n"
+ "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "the template class it was instantiated from. The arrow is labeled with "
+ "the template parameters of the instance.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Testas";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testo Sąrašas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Savybės";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Savybės Dokumentacija";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Duomenų Struktūros";
+ }
+ else
+ {
+ return "Klasės";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paketas "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Paketo Sąrašas";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Paketai su trumpu aprašymu:";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paketai";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Reikšmė:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Klaida";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Klaidų Sąrašas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1257";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "186";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeksas";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klasė" : "klasė"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Faila" : "faila"));
+ if (!singular) result+="i";
+ else result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Vardų srit" : "vardų srit"));
+ if (!singular) result+="ys";
+ else result+="is";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupė" : "grupė"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Puslapi" : "puslapi"));
+ if (!singular) result+="ai";
+ else result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Nar" : "nar"));
+ if (!singular) result+="iai";
+ else result+="ys";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="ūs";
+ else result+="us";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autori" : "autori"));
+ if (!singular) result+="ai";
+ else result+="us";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Ryšiai";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Realizuoja "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Realizuota "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Turinys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Smerktinumų Sąrašas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Įvykiai";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Įvykio Dokumentacija";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Paketo Tipai";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Paketo Funkcijos";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statinės Paketo Funkcijos";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Paketo Atributai";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statiniai Paketo Atributai";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Visi";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Funkcijos kvietimo grafas:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Paieškos Rezultatai";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Atsiprašome, jokių dokumentų nerasta pagal Jūsų užklausą.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Surasta <b>1</b> dokumentas, atitinkantis Jūsų užklausą.";
+ }
+ else
+ {
+ return "Surasta <b>$num</b> dokumentų, atitinkančių Jūsų užklausą. "
+ "Pirmiausiai rodomi labiausiai tenkinantys užklausą.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Atitikmenys:";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " išeities tekstas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Direktorijų hierarchija"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Direktorijų dokumentacija"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Direktorijos"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Ši direktorjų strūktūra grubiai surikiuota abėcėlės tvarka:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Directorijos aprašas"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Direktorij" : "direktorij"));
+ if (singular) result+="a"; else result+="os";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Perkraunamas metodas sukurtas patogumui. "
+ "Jis skiriasi nuo aukščiau minėto tik argumetais.";
+ }
+
+
+};
+
+#endif
diff --git a/src/translator_lv.h b/src/translator_lv.h
new file mode 100644
index 0000000..135cd11
--- /dev/null
+++ b/src/translator_lv.h
@@ -0,0 +1,1951 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_LV_H
+#define TRANSLATOR_LV_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+
+/* Translation from English to Latvian by Lauris Bukšis-Haberkorns
+ * (lauris at nix.lv)
+ * -------------------------------------------
+ * Project start : 24.Sept.2012
+ * Last Doxygen version covered : 1.8.2
+ */
+
+class TranslatorLatvian : public TranslatorAdapter_1_8_4
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "latvian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[LV]{fontenc}\n"
+ "\\usepackage[latvian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Saistītās funkcijas"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Šīs nav elementu funkcijas.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detalizēts apraksts"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Elementa Typedef dokumentācija"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Elementa uzskaitījumliterāļa dokumentācija"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Elementa funkcijas dokumentācija"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Lauka dokumentācija";
+ }
+ else
+ {
+ return "Elementa datu dokumentācija";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "vairāk..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Visu elementu saraksts"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Elementu saraksts"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Šis ir pilns elementu saraksts klasei "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", ieskaitot mantotos elementus."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automātiski ģenerēts izmantojot Doxygen";
+ if (s) result+=(QCString)" priekš "+s;
+ result+=" no pirmkoda.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "uzskaitījuma nosaukums"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "uzskaitījuma vērtība"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definēts"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduļi"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klašu hierarhija"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu struktūras";
+ }
+ else
+ {
+ return "Klašu saraksts";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Failu saraksts"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu lauki";
+ }
+ else
+ {
+ return "Klases elementi";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globālie";
+ }
+ else
+ {
+ return "Faila elementi";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Saistītās lapas"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Piemēri"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Meklēt"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Šis mantojamības saraksts ir sakārtots aptuveni, "
+ "bet ne pilnībā, alfabēta secībā:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll) result+="dokumentēto ";
+ result+="failu saraksts ar īsu aprakstu:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Šeit ir visas datu struktūras ar īsu aprakstu:";
+ }
+ else
+ {
+ return "Šeit ir visas klases, struktūras, "
+ "apvienojumi un interfeisi ar īsu aprakstu:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll)
+ {
+ result+="dokumentēto ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūru un apvienojumu lauku";
+ }
+ else
+ {
+ result+="klases elementu";
+ }
+ result+=" saraksts ar saitēm uz ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūru/apvienojumu dokumentāciju katram laukam:";
+ }
+ else
+ {
+ result+="klases dokumentāciju katram elementam:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktūrām/apvienojumiem, kam tie pieder:";
+ }
+ else
+ {
+ result+="klasēm, kam tie pieder:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll) result+="dokumentēto ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkciju, mainīgo, definīciju, uzskaitījumliterāļu un typedefs";
+ }
+ else
+ {
+ result+="faila elementu";
+ }
+ result+=" saraksts ar saitēm uz ";
+ if (extractAll)
+ result+="failiem, kam tie pieder:";
+ else
+ result+="dokumentāciju:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Šeit ir visu piemēru saraksts:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Here is a list of all related documentation pages:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Šeit ir visu moduļu saraksts:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentācija"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Moduļu indekss"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarhijas indekss"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu struktūru indess";
+ }
+ else
+ {
+ return "Klašu indekss";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Failu indekss"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Moduļa dokumentācija"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu struktūras dokomentācija";
+ }
+ else
+ {
+ return "Klases dokumentācija";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Faila dokumentācija"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Piemēri"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Lapas dokumentācija"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Rokasgrāmata"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makro"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefs"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Uzskaitījumi"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkcijas"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Mainīgie"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Uzskaitījumliterāļi"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Makro definīcijas dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Uzskaitījumliterāļa tipa dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funkcijas dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Mainīgo dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu struktūras";
+ }
+ else
+ {
+ return "Klases";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Ģenerēts "+date;
+ if (projName) result+=(QCString)" projektam "+projName;
+ result+=(QCString)" ar";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Mantojamības diagramma klasei "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Tikai iekšējai lietošanai."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Brīdinājums"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versija"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Datums"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Atgriež"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Skatīties arī"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametri"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Izņēmumi"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Ģenerēts ar"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Nosaukumvietu saraksts"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visas ";
+ if (!extractAll) result+="dokumentētās ";
+ result+="nosaukumvietas ar īsu aprakstu:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Draugi"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Draugu un saistīto funkciju dokumentācija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" klases"; break;
+ case ClassDef::Struct: result+=" struktūras"; break;
+ case ClassDef::Union: result+=" apvienojuma"; break;
+ case ClassDef::Interface: result+=" interfeisa"; break;
+ case ClassDef::Protocol: result+=" protokola"; break;
+ case ClassDef::Category: result+=" kategorijas"; break;
+ case ClassDef::Exception: result+=" izņēmuma"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" veidnes";
+ result+=" apraksts";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" faila apraksts";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" nosaukumvietas apraksts";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Publiskās elementa funkcijas"; }
+ virtual QCString trPublicSlots()
+ { return "Publiskās spraugas"; }
+ virtual QCString trSignals()
+ { return "Signāli"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiskās publiskās elementa funkcijas"; }
+ virtual QCString trProtectedMembers()
+ { return "Aizsargātās elementa funkcijas"; }
+ virtual QCString trProtectedSlots()
+ { return "Aizsargātās spraugas"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiskās aizsargātās elementa funkcijas"; }
+ virtual QCString trPrivateMembers()
+ { return "Privātās elementa funkcijas"; }
+ virtual QCString trPrivateSlots()
+ { return "Privātās spraugas"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiskās privātās elementa funkcijas"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", un ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Manto no "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Tiek mantots "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Pārimplementēts no "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Pārimplementēts "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Nosaukumvietas elementi"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visi ";
+ if (!extractAll) result+="dokumentētie ";
+ result+="nosaukumvietas elementi ar saitēm uz ";
+ if (extractAll)
+ result+="nosaukumvieta dokumentāciju katram elementam:";
+ else
+ result+="nosaukumvietu, kam tie pieder:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Nosaukumvietu indekss"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Nosaukumvietas dokumentācija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Nosaukumvietas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // single is true implies a single file
+ QCString result=(QCString)"Šī";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="s klases"; break;
+ case ClassDef::Struct: result+="s struktūras"; break;
+ case ClassDef::Union: result+=" apvienojuma"; break;
+ case ClassDef::Interface: result+=" interfeisa"; break;
+ case ClassDef::Protocol: result+=" protokola"; break;
+ case ClassDef::Category: result+="s kategorijas"; break;
+ case ClassDef::Exception: result+=" izņēmuma"; break;
+ default: break;
+ }
+ result+=" dokumentācijas tika ģenerēta no šāda fail";
+ if (single) result+="a:"; else result+="iem:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Atgriežamās vērtības"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Sākumlapa"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "lpp."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definēts līnijā @0 failā @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definēts failā @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Novecojusi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Sadarbības diagramma klasei "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Include dependency graph for "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruktora un destruktora dokumentācija";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Iet uz šī faila pirmkodu.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Ietu uz šī faila dokumentāciju.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Pirmsnosacījums";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Pēcnosacījums";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariants";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Sākotnējā vērtība:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "pirmkods";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafiska klases hierarhija";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Iet uz grafisku klases hierarhiju";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Iet uz tekstuālu klases hierarhiju";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Lapas indekss";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Piezīme";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Publiskie tipi";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu lauki";
+ }
+ else
+ {
+ return "Publiskie atribūti";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statiskie publiskie atribūti";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Aizsargātie tipi";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Aizsargātie atribūti";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statiskie aizsargātie atribūti";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privātie tipi";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privātie atribūti";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statiskie privātie atribūti";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Jāizdara";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Darāmo darbu saraksts";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Atsauces no";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Piebildes";
+ }
+ virtual QCString trAttention()
+ {
+ return "Uzmanību";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Šis grafs rāda kuri faili tieši vai "
+ "netieši iekļauj šo failu:";
+ }
+ virtual QCString trSince()
+ {
+ return "Kopš";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Grafika leģenda";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "This page explains how to interpret the graphs that are generated "
+ "by doxygen.<p>\n"
+ "Consider the following example:\n"
+ "\\code\n"
+ "/*! Invisible class because of truncation */\n"
+ "class Invisible { };\n\n"
+ "/*! Truncated class, inheritance relation is hidden */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Class not documented with doxygen comments */\n"
+ "class Undocumented { };\n\n"
+ "/*! Class that is inherited using public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class that is inherited using protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class that is inherited using private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class that is used by the Inherited class */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "This will result in the following graph:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%A filled gray box represents the struct or class for which the "
+ "graph is generated.</li>\n"
+ "<li>%A box with a black border denotes a documented struct or class.</li>\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.</li>\n"
+ "<li>%A box with a red border denotes a documented struct or class for"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries.</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "The arrows have the following meaning:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.</li>\n"
+ "<li>%A dark green arrow is used for protected inheritance.</li>\n"
+ "<li>%A dark red arrow is used for private inheritance.</li>\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible.</li>\n"
+ "<li>%A yellow dashed arrow denotes a relation between a template instance and "
+ "the template class it was instantiated from. The arrow is labeled with "
+ "the template parameters of the instance.</li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "leģenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Testi";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testu saraksts";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Rekvizīti";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Rekvizītu dokumentācija";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datu struktūras";
+ }
+ else
+ {
+ return "Klases";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pakotne "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakotņu saraksts";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Here are the packages with brief descriptions (if available):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakotnes";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Vērtība:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Kļūda";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Kļūdu saraksts";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1257";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "186";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indekss";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klase" : "klase"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fail" : "fail"));
+ if (singular) result+="s"; else result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Nosaukumvieta" : "nosaukumvieta"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupa" : "grupa"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Lapa" : "lapa"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Element" : "element"));
+ if (singular) result+="s"; else result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globāl" : "globāl"));
+ if (singular) result+="ais"; else result+="ie";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (singular) result+="s"; else result+="i";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Atsauces";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Īsteno "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Īstenots "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Satura rādītājs";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Novecojušo saraksts";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Notikumi";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Notikumu dokumentācija";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Pakas tipi";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Pakas funkcijas";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statiskās pakas funkcijas";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Pakas atribūti";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statiskie pakas atribūti";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Visi";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Šeit ir visu funkciju izsaugumu grafs:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Meklēšanas rezultāti";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Netika atrasts neviens dokuments.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Atrasts <b>1</b> dokuments.";
+ }
+ else
+ {
+ return "Atrasti <b>$num</b> Dokumenti. "
+ "Sākumā attēlo tos, kas atbilst visprecīzāk.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Atbilst meklētajam:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " pirmkoda fails";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Direktoriju struktūra"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Direktorijas dokumentācija"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Direktorijas"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Šī direktoriju hierarhija ir aptuveni, "
+ "bet ne pilnībā, alfabēta secībā:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Direktorijas "; result+=dirName; result+=" atsauce"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Direktorija" : "direktorija"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Šī ir elementa pārslogota funkcija, kas "
+ "parādīta tikai informātīvo nolūkos. Tā atšķiras no iepriekšapraksītās "
+ "funkcijas tikai ar parametriem, ko tā saņem.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Šeit ir šīs funkcijas izsaukuma grafs:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Uzskaitījumliterāļa dokumentācija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Elementa funckijas/apakšrutīnas dokumentācija"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Datu tipu saraksts"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Datu lauki"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Šeit ir visu datu tipu saraksts ar īsu aprakstu:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll)
+ {
+ result+="dokumentēto ";
+ }
+ result+="datu tipu saraksts";
+ result+=" ar saitēm uz ";
+ if (!extractAll)
+ {
+ result+="datu struktūras dokumentāciju katram elementam:";
+ }
+ else
+ {
+ result+="datu tipiem, kam tie pieder:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Datu tipu indekss"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Datu tipa dokumentācija"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcijas/Apakšrutīnas"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funkcijas/Apakšrutīnas dokumentācija"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datu tipi"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Moduļu saraksts"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll) result+="dokumentēto ";
+ result+="moduļu saraksts ar īsu aprakstu:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" moduļa"; break;
+ case ClassDef::Struct: result+=" tipa"; break;
+ case ClassDef::Union: result+=" apvienojuma"; break;
+ case ClassDef::Interface: result+=" interfeisa"; break;
+ case ClassDef::Protocol: result+=" protokola"; break;
+ case ClassDef::Category: result+=" kategorijas"; break;
+ case ClassDef::Exception: result+=" izņēmuma"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" sagataves";
+ result+=" atsauce";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" moduļu atsauce";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Moduļa elementi"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Šeit ir visu ";
+ if (!extractAll) result+="dokumentēto ";
+ result+="moduļa elementu saraksts ar saitēm uz ";
+ if (extractAll)
+ {
+ result+="moduļa dokumentāciju katram elementam:";
+ }
+ else
+ {
+ result+="moduļiem, kuriem tie pieder:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Moduļu indekss"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modu" : "modu"));
+ if (singular) result+="lis"; else result+="ļi";
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentācija š";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="im modulim"; break;
+ case ClassDef::Struct: result+="im tipam"; break;
+ case ClassDef::Union: result+="im apvienojumam"; break;
+ case ClassDef::Interface: result+="im interfeisam"; break;
+ case ClassDef::Protocol: result+="im protokolam"; break;
+ case ClassDef::Category: result+="ai kategorijai"; break;
+ case ClassDef::Exception: result+="im izņēmumam"; break;
+ default: break;
+ }
+ result+=" tika ģenerēta no fail";
+ if (single) result+="a:"; else result+="iem:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (singular) result+="s"; else result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Apakšprogramma" : "apakšprogramma"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Tipa ierobežojumi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" relācija";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Tiek veikta ielāde...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Global Namespace";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Meklē...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nav atbilstību";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"File in "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Includes file in "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Pirm","Otr","Tr","Cet","Piekt","Sest","Sv" };
+ static const char *months[] = { "Jan","Feb","Mar","Apr","Mai","Jūn","Jūl","Aug","Sept","Okt","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliogrāfiskās atsauces"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Autortiesības"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Atkarību grafs direktorijai ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detalizācijas līmenis"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Sagataves parametri"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "un vēl "+number+"..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumentācija šim uzskaitījumliterālim tika ģenerēta no sekojoš";
+ if (single) result+="a"; else result += "iem";
+ result+=" fail";
+ if (single) result+="a"; else result += "iem";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" uzskaitījumliterāļa atsauce"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" manto no "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Papildus mantotie elementi"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "iespējotu" : "atspējotu";
+ return "uzklikšķināt, lai "+opt+" paneļu sinhronizāciju";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Nodrošina kategorija @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Paplašina klasi @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Klases metodes";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Instances metodes";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Metožu dokumentācija";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Dizaina pārskats";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_mk.h b/src/translator_mk.h
new file mode 100644
index 0000000..510561e
--- /dev/null
+++ b/src/translator_mk.h
@@ -0,0 +1,1723 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+// Тranslated by Slave Jovanovski <slavejovanovski at yahoo.com>
+//
+// The cyrillic strings were entered using Macedonian language support in
+// Windows. The editor used was Eclipse 3.2. The file was saved in UTF-8.
+//
+// Updates:
+// --------
+// 2007/12/09
+// - Initial translation to Macedonian.
+//
+// 2008/05/22
+// - Translation for 1.5.4.
+//
+//
+
+#ifndef TRANSLATOR_MK_H
+#define TRANSLATOR_MK_H
+
+class TranslatorMacedonian : public TranslatorAdapter_1_6_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "macedonian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[macedonian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Поврзани Функции"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Овие функции не се членови.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Детален опис"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Документација на членови дефиниции на тип"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Документација на набројани членови"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Документација на функции членови"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ //if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Документација на членови";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Повеќе..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Список на сите членови"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Список на членови"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Ова е целосниот список на членови на "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", вклучувајќи ги сите наследени членови."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Автоматски создадено од Doxygen";
+ if (s) result+=(QCString)" за "+s;
+ result+=" изворниот код.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "име на набројан член"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "вредност на набројан член"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "дефиниран во"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Модули"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Стебло на класи"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Список на Структури";
+ }
+ else
+ {
+ return "Список на Класи";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Список на Датотеки"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Членови";
+ }
+ else
+ {
+ return "Членови на Класата";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Глобални Членови";
+ }
+ else
+ {
+ return "Членови на Датотеката";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Страници Поврзани со Оваа"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Примери"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Пребарај"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Овој список на наследување е приближно азбучно подреден:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+ result+="членови со кратки описи:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Список на структури со кратки описи:";
+ }
+ else
+ {
+ return "Список на класи, структури, унии и интерфејси "
+ "со кратки описи:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll)
+ {
+ result+="документирани ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="структури и унии";
+ }
+ else
+ {
+ result+="членови на класата";
+ }
+ result+=" со врски до ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="документацијата за секој член на структурата/унијата:";
+ }
+ else
+ {
+ result+="документацијата на секој член на класата:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="структурите/униите на кои што припаѓаат:";
+ }
+ else
+ {
+ result+="класите на кои што припаѓаат:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="функции, променливи, дефиниции, набројувања и дефиниции на тип";
+ }
+ else
+ {
+ result+="членови на датотеки";
+ }
+ result+=" со врски до ";
+ if (extractAll)
+ result+="датотеките на кои што припаѓаат:";
+ else
+ result+="документацијата:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Список на сите примери:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Список на сите страници поврзани со оваа и нивна документација:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Список на сите модули:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Документација"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Попис на Модули"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Попис на Стебло"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Попис на Структури";
+ }
+ else
+ {
+ return "Попис на Класи";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Попис на Датотеки"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Попис на Документација"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Документација на Структури";
+ }
+ else
+ {
+ return "Документација на Класи";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Документија на Датотеки"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Документаија на Примери"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Документација на Страници"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Прирачник"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Дефинирања"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Дефиниции на Тип"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Набројувања"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Функции"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Променливи"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Вредности на Набројувањата"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Документција на Дефиниции"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Документација на Дефиниции на Тип"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Документација на Набројувања"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Документација на Функции"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Документација на Променливи"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури";
+ }
+ else
+ {
+ return "Класи";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Создадено на "+date;
+ if (projName) result+=(QCString)" за "+projName;
+ result+=(QCString)" од";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Диаграм на наследување за "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Само за интерна употреба."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Предупредување"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Верзија"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Дата"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Враќа"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Истотака погледнете"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Параметри"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Исклучоци"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Создадено од"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Список на Имиња на Простор"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+ result+="имиња на простор со кратки описи:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Пријатели"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Документација на Пријатели и Поврзани Функции"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Класа"; break;
+ case ClassDef::Struct: result+=" Структура"; break;
+ case ClassDef::Union: result+=" Унија"; break;
+ case ClassDef::Interface: result+=" Интерфејс"; break;
+ case ClassDef::Protocol: result+=" Протокол"; break;
+ case ClassDef::Category: result+=" Категорија"; break;
+ case ClassDef::Exception: result+=" Исклучок"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Образец";
+ result+=" Повикување";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result = "Опис на Датотекaта ";
+ result += fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result = "Опис на Имeто на Простор ";
+ result += namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Јавни Функции Членови"; }
+ virtual QCString trPublicSlots()
+ { return "Јавни Слотови"; }
+ virtual QCString trSignals()
+ { return "Сигнали"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Статични Јавни Функции Членови"; }
+ virtual QCString trProtectedMembers()
+ { return "Заштитени Функции Членови"; }
+ virtual QCString trProtectedSlots()
+ { return "Заштитени Слотови"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Статични Заштитени Функции Членови"; }
+ virtual QCString trPrivateMembers()
+ { return "Приватни Функции Членови"; }
+ virtual QCString trPrivateSlots()
+ { return "Приватни Слотови"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Статични Приватни Функции Членови"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" и ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Наследува "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Наследено од "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Преприменето од "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Преприменето во "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Членови на Име на Простор"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+ result+="членови на името на простор со врски до ";
+ if (extractAll)
+ result+="документацијата на секој член:";
+ else
+ result+="името на простор на кое што му припаѓаат:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Попис на Имиња на Простор"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Документација на Имиња на Простор"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Имиња на Простор"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документацијата за ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="оваа класа"; break;
+ case ClassDef::Struct: result+="оваа структура"; break;
+ case ClassDef::Union: result+="оваа унија"; break;
+ case ClassDef::Interface: result+="овој интерфејс"; break;
+ case ClassDef::Protocol: result+="овој протокол"; break;
+ case ClassDef::Category: result+="оваа категорија"; break;
+ case ClassDef::Exception: result+="овој исклучок"; break;
+ default: break;
+ }
+ result+=" беше создадена од ";
+ if (single) result+="следнава датотека:"; else result+="следниве датотеки:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Вратена Вредност"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Главна Страна"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "стр."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Дефиницијата е на линија @0 во датотека @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Дефинијата е во датотека @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Застарено";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Диаграм на соработка за "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Вклучен дијаграм на зависност за "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Документација на Конструктор и Деструктор";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Оди до изворниот код на оваа датотека.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Оди до документацијата на оваа датотека.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Предуслов";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Постуслов";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Инваријанта";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Основна вредност:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "код";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Графичко Стебло на Класи";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Оди до графичкото стебло на класи";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Оди до текстуалното стебло на класи";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Попис на Страници";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Забелешка";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Јавни Типови";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Членови";
+ }
+ else
+ {
+ return "Јавни Членови";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Статични Јавни Членови";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Заштитени Типови";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Заштитени Членови";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Статични Заштитени Типови";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Приватни Типови";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Приватни Членови";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Статични Приватни Членови";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Незавршено";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Список на Незавршени";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Повикано од";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Забелешки";
+ }
+ virtual QCString trAttention()
+ {
+ return "Внимание";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Овој дијаграм покажува кои датотеки се "
+ "директно или индеректно вклучени во оваа датотека:";
+ }
+ virtual QCString trSince()
+ {
+ return "Од";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Легенда на Дијаграмот";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Оваа страна објаснува како да ги толкувате дијаграмите создадени"
+ " од doxygen.<p>\n"
+ "На пример:\n"
+ "\\code\n"
+ "/*! Невидлива класа заради ограничувања на дијаграмот */\n"
+ "class Invisible { };\n\n"
+ "/*! Одсечена класа, врската на наследување е скриена */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Класата не е документирана со doxygen коментари */\n"
+ "class Undocumented { };\n\n"
+ "/*! Класа која е наследена со јавно наследување */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Класа Образец */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Класа која е наследена со заштитено наследување */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Класа која е наследена со приватно наследување */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Класа која е користена од страна на наследената класа */\n"
+ "class Used { };\n\n"
+ "/*! Класа која наследува од повеќе други класи */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Ако вредноста на \\c MAX_DOT_GRAPH_HEIGHT во конфигурациската датотека "
+ "е 240 тогаш примерот ќе го создаде следниов дијаграм:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Правоаголниците во дијаграмот погоре го имаат следново значење:\n"
+ "<ul>\n"
+ "<li>Полн сив правоаголник ја означува структурата или класата за "
+ "којадијаграмот е создаден.\n"
+ "<li>Правоаголник со црна граница означува документирана структура или класа.\n"
+ "<li>Правоаголник со сива граница означува недокументирана структура или класа.\n"
+ "<li>Правоаголник со црвена граница означува документирана структура или класа "
+ "за која не сите врски на наследување се прикажани. Дијаграмот е одсечен доколку "
+ "не го собира во зададените граници..\n"
+ "</ul>\n"
+ "Стрелките го имаат следново значење:\n"
+ "<ul>\n"
+ "<li>Сина стрелка означува врска на јавно наследување помеѓу две класи.\n"
+ "<li>Зелена стрелка означува заштитено наследување.\n"
+ "<li>Црвена стрелка означува приватно наследување.\n"
+ "<li>Виолетова испрекината линија означува класа која е користена или вклучена "
+ "во друга класа. Стрелаката е означена со името на променливата преку "
+ "која класата е достапна.\n"
+ "<li>Жолта испрекината линија означува врска меѓу примерок од образец класа "
+ "и класата образец од која е создадена. Стрелката е означена со имињата на "
+ "параметрите на класата.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Легенда";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Тест";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Листа на Тестови";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Особини";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Документација на Особини";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури";
+ }
+ else
+ {
+ return "Класи";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Пакет "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Список на Пакети";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Пакети со краток опис (доколку достапен):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Пакети";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Вредност:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Дефект";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Листа на Дефекти";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1251";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "204";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Попис";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Клас" : "клас"));
+ result += (singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Датотек" : "датотек"));
+ result += (singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Им" : "им"));
+ result += (singular ? "е на простор" : "иња на простори");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Груп" : "груп"));
+ result += (singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Стран" : "стран"));
+ result += (singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Член" : "член"));
+ if (!singular) result+="ови";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Глобал" : "глобал"));
+ result += (singular ? "ен" : "ни");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Автор" : "автор"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Повикувања";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Применува "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Применето во "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Содржина";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Список на Застарени";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Настани";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Документација на Настани";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Типови во Пакетот";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Функции во Пакетот";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Статични Функции во Пакетот";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Членови во Пакетот";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Статични Членови во Пакетот";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Сите";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Дијаграм на повикувања за оваа функција:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Резултати од Пребарувањето";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Нема документи кои се поклопуваат со вашето барање.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Пронајден <b>1</b> документ кој се поклопува со вашето барање.";
+ }
+ else
+ {
+ return "Пронајдени <b>$num</b> документи кои се поклопуваат со вашето барање."
+ "Најдобро поклопените документи се прикажани први.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Пронајдени:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Изворен код на датотеката " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Стебло на Именикот"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Документација на Именикот"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Именици"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Ова стебло на именици е приближно азбучно подреден:";}
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result= "Опис на Именикот "; result += dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Имени" : "имени"));
+ if (singular) result+="к"; else result+="ци";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Оваа е преоптоварена фунција. Се разликува по "
+ "типот и бројот на аргументи што ги прифаќа.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Ова е графот на повикување за оваа фунција:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Документија на Набројувања"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Документација на функции/процедури членови"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Список на Типови"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Членови"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Список на типови со кратки описи:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll)
+ {
+ result+="документирани ";
+ }
+ result+="членови на типови";
+ result+=" со врски до ";
+ if (!extractAll)
+ {
+ result+="документацијата за секој член:";
+ }
+ else
+ {
+ result+="типовите на кои што припаѓаат:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Попис на Типови"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Документација на Типови"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Функции/Процедури"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Документација на Функции/Процедури"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Типови"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Попис на Модули"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+ result+="модули со кратки описи:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName + " - Повикување на";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Класа"; break;
+ case ClassDef::Struct: result+=" Тип"; break;
+ case ClassDef::Union: result+=" Унија"; break;
+ case ClassDef::Interface: result+=" Интерфејс"; break;
+ case ClassDef::Protocol: result+=" Протокол"; break;
+ case ClassDef::Category: result+=" Категорија"; break;
+ case ClassDef::Exception: result+=" Исклучок"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Образец";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" - Содржина на Модул";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Членови на Модул"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Список на сите ";
+ if (!extractAll) result+="документирани ";
+ result+="членови на модулот со врски до ";
+ if (extractAll)
+ {
+ result+="документацијата за секој член:";
+ }
+ else
+ {
+ result+="модулите на кои што припаѓаат:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Попис на Модули"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Модул" : "модул"));
+ if (!singular) result+="и";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документацијата за ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="оваа класа"; break;
+ case ClassDef::Struct: result+="овој тип"; break;
+ case ClassDef::Union: result+="оваа унија"; break;
+ case ClassDef::Interface: result+="овој интерфејс"; break;
+ case ClassDef::Protocol: result+="овој протокол"; break;
+ case ClassDef::Category: result+="оваа категорија"; break;
+ case ClassDef::Exception: result+="овој исклучок"; break;
+ default: break;
+ }
+ result+=" беше создадена од ";
+ if (single) result+="следнава датотека:"; else result+="следниве датотеки:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Тип" : "тип"));
+ if (!singular) result+="ови";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Потпрограм" : "потпрограм"));
+ if (singular){
+ result+="а";
+ }else{
+ result+="и";
+ }
+
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Ограничувања на Тип";
+ }
+};
+
+#endif
diff --git a/src/translator_nl.h b/src/translator_nl.h
new file mode 100644
index 0000000..2ffacb6
--- /dev/null
+++ b/src/translator_nl.h
@@ -0,0 +1,1591 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_NL_H
+#define TRANSLATOR_NL_H
+
+class TranslatorDutch : public Translator
+{
+ public:
+ QCString idLanguage()
+ { return "dutch"; }
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ */
+ QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[dutch]{babel}\n";
+ }
+ QCString trRelatedFunctions()
+ { return "Gerelateerde functies"; }
+ QCString trRelatedSubscript()
+ { return "(Merk op dat dit geen member functies zijn.)"; }
+ QCString trDetailedDescription()
+ { return "Gedetailleerde Beschrijving"; }
+ QCString trMemberTypedefDocumentation()
+ { return "Documentatie van type definitie members"; }
+ QCString trMemberEnumerationDocumentation()
+ { return "Documentatie van enumeratie members"; }
+ QCString trMemberFunctionDocumentation()
+ { return "Documentatie van functie members"; }
+ QCString trMemberDataDocumentation()
+ { return "Documentatie van data members"; }
+ QCString trMore()
+ { return "Meer..."; }
+ QCString trListOfAllMembers()
+ { return "Lijst van alle members"; }
+ QCString trMemberList()
+ { return "Member Lijst"; }
+ QCString trThisIsTheListOfAllMembers()
+ { return "Dit is de complete lijst van alle members voor"; }
+ QCString trIncludingInheritedMembers()
+ { return ", inclusief alle overgeërfde members."; }
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automatisch gegenereerd door Doxygen";
+ if (s) result+=(QCString)" voor "+s;
+ result+=" uit de programmatekst.";
+ return result;
+ }
+ QCString trEnumName()
+ { return "enum naam"; }
+ QCString trEnumValue()
+ { return "enum waarde"; }
+ QCString trDefinedIn()
+ { return "gedefinieerd in"; }
+ QCString trModules()
+ { return "Modules"; }
+ QCString trClassHierarchy()
+ { return "Klasse Hiërarchie"; }
+ QCString trCompoundList()
+ { return "Klasse Lijst"; }
+ QCString trFileList()
+ { return "Bestandslijst"; }
+ QCString trCompoundMembers()
+ { return "Klasse Members"; }
+ QCString trFileMembers()
+ { return "Bestand members"; }
+ QCString trRelatedPages()
+ { return "Gerelateerde pagina's"; }
+ QCString trExamples()
+ { return "Voorbeelden"; }
+ QCString trSearch()
+ { return "Zoeken"; }
+ QCString trClassHierarchyDescription()
+ { return "Deze inheritance lijst is min of meer alfabetisch "
+ "gesorteerd:";
+ }
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Hieronder volgt de lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="bestanden, elk met een korte beschrijving:";
+ return result;
+ }
+ QCString trCompoundListDescription()
+ { return "Hieronder volgen de klassen, structs en "
+ "unions met voor elk een korte beschrijving:";
+ }
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Hieronder volgt de lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="klasse members met links naar ";
+ if (!extractAll) result+="de klasse documentatie voor elke member:";
+ else result+="de klassen waartoe ze behoren:";
+ return result;
+ }
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Hieronder volgt de lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="bestand members met links naar ";
+ if (extractAll) result+="de bestand's documentatie voor elke member:";
+ else result+="de bestanden waartoe ze behoren:";
+ return result;
+ }
+ QCString trExamplesDescription()
+ { return "Hieronder volgt de lijst met alle voorbeelden:"; }
+ QCString trRelatedPagesDescription()
+ { return "Hieronder volgt de lijst met alle pagina's die gerelateerde documentatie bevatten:"; }
+ QCString trModulesDescription()
+ { return "Hieronder volgt de lijst met alle modules:"; }
+
+ QCString trDocumentation()
+ { return "Documentatie"; }
+ QCString trModuleIndex()
+ { return "Module Index"; }
+ QCString trHierarchicalIndex()
+ { return "Hiërarchische Index"; }
+ QCString trCompoundIndex()
+ { return "Klasse Index"; }
+ QCString trFileIndex()
+ { return "Bestand Index"; }
+ QCString trModuleDocumentation()
+ { return "Module Documentatie"; }
+ QCString trClassDocumentation()
+ { return "Klassen Documentatie"; }
+ QCString trFileDocumentation()
+ { return "Bestand Documentatie"; }
+ QCString trExampleDocumentation()
+ { return "Documentatie van voorbeelden"; }
+ QCString trPageDocumentation()
+ { return "Documentatie van gerelateerde pagina's"; }
+ QCString trReferenceManual()
+ { return "Naslagwerk"; }
+
+ QCString trDefines()
+ { return "Macros"; }
+ QCString trTypedefs()
+ { return "Typedefs"; }
+ QCString trEnumerations()
+ { return "Enumeraties"; }
+ QCString trFunctions()
+ { return "Functies"; }
+ QCString trVariables()
+ { return "Variabelen"; }
+ QCString trEnumerationValues()
+ { return "Enumeratie waarden"; }
+ QCString trDefineDocumentation()
+ { return "Documentatie van macro's"; }
+ QCString trTypedefDocumentation()
+ { return "Documentatie van typedefs"; }
+ QCString trEnumerationTypeDocumentation()
+ { return "Documentatie van enumeratie types"; }
+ QCString trEnumerationValueDocumentation()
+ { return "Documentatie van enumeratie waarden"; }
+ QCString trFunctionDocumentation()
+ { return "Documentatie van functies"; }
+ QCString trVariableDocumentation()
+ { return "Documentatie van variabelen"; }
+ QCString trCompounds()
+ { return "Klassen"; }
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Gegenereerd op "+date;
+ if (projName) result+=(QCString)" voor "+projName;
+ result+=(QCString)" door";
+ return result;
+ }
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Klasse diagram voor "+clName;
+ }
+ QCString trForInternalUseOnly()
+ { return "Alleen voor intern gebruik."; }
+ QCString trWarning()
+ { return "Waarschuwing"; }
+ QCString trVersion()
+ { return "Versie"; }
+ QCString trDate()
+ { return "Datum"; }
+ QCString trReturns()
+ { return "Retourneert"; }
+ QCString trSeeAlso()
+ { return "Zie ook"; }
+ QCString trParameters()
+ { return "Parameters"; }
+ QCString trExceptions()
+ { return "Excepties"; }
+ QCString trGeneratedBy()
+ { return "Gegenereerd door"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNamespaceList()
+ { return "Namespace Lijst"; }
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Hier is een lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="namespaces met voor elk een korte beschrijving:";
+ return result;
+ }
+ QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trRelatedFunctionDocumentation()
+ { return "Documentatie van friends en gerelateerde functies"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ // used as the title of the HTML page of a class/struct/union
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate) result+=" Template";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Class"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ result+=" Referentie";
+ return result;
+ }
+ QCString trFileReference(const char *fileName)
+ // used as the title of the HTML page of a file
+ {
+ QCString result=fileName;
+ result+=" Bestand Referentie";
+ return result;
+ }
+ QCString trNamespaceReference(const char *namespaceName)
+ // used as the title of the HTML page of a namespace
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Referentie";
+ return result;
+ }
+
+ // these are for the member sections of a class, struct or union
+ QCString trPublicMembers()
+ { return "Public Members"; }
+ QCString trPublicSlots()
+ { return "Public Slots"; }
+ QCString trSignals()
+ { return "Signals"; }
+ QCString trStaticPublicMembers()
+ { return "Static Public Members"; }
+ QCString trProtectedMembers()
+ { return "Protected Members"; }
+ QCString trProtectedSlots()
+ { return "Protected Slots"; }
+ QCString trStaticProtectedMembers()
+ { return "Static Protected Members"; }
+ QCString trPrivateMembers()
+ { return "Private Members"; }
+ QCString trPrivateSlots()
+ { return "Private Slots"; }
+ QCString trStaticPrivateMembers()
+ { return "Static Private Members"; }
+ // end of member sections
+
+ QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" en ";
+ }
+ }
+ return result;
+ }
+
+ QCString trInheritsList(int numEntries)
+ // used in class documentation to produce a list of base classes,
+ // if class diagrams are disabled.
+ {
+ return "Erft over van "+trWriteList(numEntries)+".";
+ }
+ QCString trInheritedByList(int numEntries)
+ // used in class documentation to produce a list of super classes,
+ // if class diagrams are disabled.
+ {
+ return "Wordt overgeërfd door "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedFromList(int numEntries)
+ // used in member documentation blocks to produce a list of
+ // members that are hidden by this one.
+ {
+ return "Nieuwe implementatie van "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedInList(int numEntries)
+ {
+ // used in member documentation blocks to produce a list of
+ // all member that overwrite the implementation of this member.
+ return "Opnieuw geïmplementeerd in "+trWriteList(numEntries)+".";
+ }
+
+ QCString trNamespaceMembers()
+ // This is put above each page as a link to all members of namespaces.
+ { return "Namespace Members"; }
+ QCString trNamespaceMemberDescription(bool extractAll)
+ // This is an introduction to the page with all namespace members
+ {
+ QCString result="Hier is een lijst van alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="namespace members met links naar ";
+ if (extractAll)
+ result+="de namespace documentatie voor iedere member:";
+ else
+ result+="de namespaces waartoe ze behoren:";
+ return result;
+ }
+ QCString trNamespaceIndex()
+ // This is used in LaTeX as the title of the chapter with the
+ // index of all namespaces.
+ { return "Namespace Index"; }
+ QCString trNamespaceDocumentation()
+ // This is used in LaTeX as the title of the chapter containing
+ // the documentation of all namespaces.
+ { return "Namespace Documentatie"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ QCString trNamespaces()
+ {
+ return "Namespaces";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"De documentatie voor ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="deze klasse"; break;
+ case ClassDef::Struct: result+="deze struct"; break;
+ case ClassDef::Union: result+="deze union"; break;
+ case ClassDef::Interface: result+="dit interface"; break;
+ case ClassDef::Protocol: result+="dit protocol"; break;
+ case ClassDef::Category: result+="deze categorie"; break;
+ case ClassDef::Exception: result+="deze exceptie"; break;
+ default: break;
+ }
+ result+=" is gegenereerd op grond van ";
+ if (single) result+="het"; else result+="de";
+ result+=" volgende bestand";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "Retour waarden"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "Hoofd Pagina"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "De definitie bevindt zich op regel @0 in het bestand @1.";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "De definitie bevindt zich in het bestand @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Verouderd";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Collaboratie diagram voor "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Include afhankelijkheidsgraaf voor "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "Constructor & Destructor Documentatie";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "Ga naar de broncode van dit bestand.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "Ga naar de documentatie van dit bestand.";
+ }
+ /*! Text for the \\pre command */
+ QCString trPrecondition()
+ {
+ return "Preconditie";
+ }
+ /*! Text for the \\post command */
+ QCString trPostcondition()
+ {
+ return "Postconditie";
+ }
+ /*! Text for the \\invariant command */
+ QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "Initiële waarde:";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "code";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Grafische Klasse Hiërarchie";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "Ga naar de grafische klasse hiërarchie";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "Ga naar de tekstuele klasse hiërarchie";
+ }
+ QCString trPageIndex()
+ {
+ return "Pagina Index";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "Noot";
+ }
+ QCString trPublicTypes()
+ {
+ return "Public Typen";
+ }
+ QCString trPublicAttribs()
+ {
+ return "Public Attributen";
+ }
+ QCString trStaticPublicAttribs()
+ {
+ return "Static Public Attributen";
+ }
+ QCString trProtectedTypes()
+ {
+ return "Protected Typen";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "Protected Attributen";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "Static Protected Attributen";
+ }
+ QCString trPrivateTypes()
+ {
+ return "Private Typen";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "Private Attributen";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "Static Private Attributen";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ QCString trTodo()
+ {
+ return "Todo";
+ }
+ /*! Used as the header of the todo list */
+ QCString trTodoList()
+ {
+ return "Todo Lijst";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trReferencedBy()
+ {
+ return "Wordt aangeroepen door";
+ }
+ QCString trRemarks()
+ {
+ return "Opmerkingen";
+ }
+ QCString trAttention()
+ {
+ return "Attentie";
+ }
+ QCString trInclByDepGraph()
+ {
+ return "Deze graaf geeft aan welke bestanden direct of "
+ "indirect afhankelijk zijn van dit bestand:";
+ }
+ QCString trSince()
+ {
+ return "Sinds";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ QCString trLegendTitle()
+ {
+ return "Graaf Legenda";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ QCString trLegendDocs()
+ {
+ return
+ "Deze pagina legt uit hoe de grafen die gegenereerd worden door doxygen "
+ "geïnterpreteerd dienen te worden.<p>\n"
+ "Beschouw het volgende voorbeeld:\n"
+ "\\code\n"
+ "/*! Onzichtbare klasse vanwege afkappen van de graaf */\n"
+ "class Invisible { };\n\n"
+ "/*! Afgekapte klasse, overervingsrelatie is verborgen */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klasse is niet gedocumenteerd met doxygen commentaar */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klasse met public inheritance */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasse met protected inheritance */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klasse met private inheritance */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klasse die wordt gebruikt door de klasse Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Super klasse die overerft van een aantal andere klassen */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Dit voorbeeld zal resulteren in de volgende graaf:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "De rechthoeken in the bovenstaande graaf hebben de volgende betekenis:\n"
+ "<ul>\n"
+ "<li>Een gevulde grijze rechthoek representeert de structure of klasse waarvoor "
+ "de graaf is gegenereerd.\n"
+ "<li>Een rechthoek met een zwarte rand representeert een gedocumenteerde structure of klasse.\n"
+ "<li>Een rechthoek met een grijze rand representeert een ongedocumenteerde structure of klasse.\n"
+ "<li>Een rechthoek met een rode rand representeert een gedocumenteerde structure or klasse waarvoor\n"
+ "niet alle overervings- of gebruiksrelaties konden worden getoond. Een graaf wordt "
+ "afgekapt als hij niet past binnen de gespecificeerde grenzen."
+ "</ul>\n"
+ "De pijlen hebben de volgende betekenis:\n"
+ "<ul>\n"
+ "<li>Een donkerblauwe pijl visualizeert een public inheritance "
+ "relatie tussen twee klassen.\n"
+ "<li>Een donkergroene pijl wordt gebruikt voor protected inheritance.\n"
+ "<li>Een donkerrode pijl wordt gebruikt voor private inheritance.\n"
+ "<li>Een paars gestippelde pijl wordt gebruikt indien een klasse bevat is of gebruikt wordt "
+ "door een andere klasse. De pijl is gelabeled met de variable(n) "
+ "die toegang geven tot de aangewezen klasse of structure. \n"
+ "<li>Een geel gestippelde pijl wordt gebruikt om een relatie tussen een \n"
+ "template instantie en een template klasse aan te geven. De pijl is gelabeld met \n"
+ "template parameters van de instantie.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ QCString trTestList()
+ {
+ return "Test Lijst";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ QCString trProperties()
+ {
+ return "Properties";
+ }
+ /*! Used as a section header for IDL property documentation */
+ QCString trPropertyDocumentation()
+ {
+ return "Property Documentatie";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ QCString trClasses()
+ {
+ return "Klassen";
+ }
+ /*! Used as the title of a Java package */
+ QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ QCString trPackageList()
+ {
+ return "Package Lijst";
+ }
+ /*! The description of the package index page */
+ QCString trPackageListDescription()
+ {
+ return "Hier volgen de packages, elk met een korte beschrijving (indien aanwezig):";
+ }
+ /*! The link name in the Quick links header for each page */
+ QCString trPackages()
+ {
+ return "Packages";
+ }
+ /*! Text shown before a multi-line define */
+ QCString trDefineValue()
+ {
+ return "Waarde:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ QCString trBugList()
+ {
+ return "Bug Lijst";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klasse" : "klass"));
+ if (!singular) result+="n";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Bestand" : "bestand"));
+ if (!singular) result+="en";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Groep" : "groep"));
+ if (!singular) result+="en";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Pagina" : "pagina"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Member" : "member"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globale member" : "globale member"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auteur" : "auteur"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Gebruikt";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementeert "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Wordt geïmplementeerd door "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trRTFTableOfContents()
+ { return "Inhoudsopgave"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Deprecated Lijst";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for a section of events found in a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Events";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Event Documentatie";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Package Types";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Package Functies";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statische Package Functies";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Package Attributen";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statische Package Attributen";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alle";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Hier is de call graaf voor deze functie:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Zoek Resultaten";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Helaas, er zijn geen documenten gevonden die aan de zoekopdracht voldoen.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Er is <b>1</b> document gevonden dat aan de zoekopdracht voldoet.";
+ }
+ else
+ {
+ return "Er zijn <b>$num</b> documenten gevonden die aan de zoekopdracht voldoen. "
+ "De beste resultaten worden eerst getoond.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Gevonden:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Bron Bestand";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Folder Hiërarchie"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Folder Documentatie"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Folders"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Deze folder hiërarchie is min of meer alfabetisch "
+ "gesorteerd:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Folder Referentie"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Folder" : "folder"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Deze functie is overloaded en is beschikbaar gemaakt om het "
+ "gebruik te vergemakkelijken. Ze verschilt alleen van de "
+ "bovenstaande functie wat betreft de parameterlijst.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallerGraph()
+ {
+ return "Hier is de caller graaf voor deze functie:";
+ }
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Member Functie/Subroutine Documentatie"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lijst met data types"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Data velden"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Hieronder volgen de data types elk een korte beschrijving:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Hieronder volgt de lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="data types met links naar ";
+ if (!extractAll) result+="de klasse documentatie voor elke member:";
+ else result+="de klassen waartoe ze behoren:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Data Type Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Data Type Documentatie"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Functies/Subroutines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Functie/Subroutine Documentatie"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Data Types"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Module Lijst"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Hieronder volgt de lijst met alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="modulen, elk met een korte beschrijving:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Module"; break;
+ case ClassDef::Struct: result+=" Type"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Referentie";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Module Referentie";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Module Members"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Hier is een lijst van alle ";
+ if (!extractAll) result+="gedocumenteerde ";
+ result+="module members met links naar ";
+ if (extractAll)
+ result+="de module documentatie voor iedere member:";
+ else
+ result+="de module waartoe ze behoren:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Module Index"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="n";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"De documentatie voor ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="deze module"; break;
+ case ClassDef::Struct: result+="dit type"; break;
+ case ClassDef::Union: result+="deze union"; break;
+ case ClassDef::Interface: result+="dit interface"; break;
+ case ClassDef::Protocol: result+="dit protocol"; break;
+ case ClassDef::Category: result+="deze category"; break;
+ case ClassDef::Exception: result+="deze exception"; break;
+ default: break;
+ }
+ result+=" is gegenereerd op grond van ";
+ if (single) result+="het"; else result+="de";
+ result+=" volgende bestand";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Type" : "type"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogramma" : "subprogramma"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Type Beperkingen";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relatie";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Laden...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globale Namespace";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Zoeken...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Niets gevonden";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Bestand in "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Includeert bestand in "+name;
+ }
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Ma","Di","Wo","Do","Vr","Za","Zo" };
+ static const char *months[] = { "Jan","Feb","Maa","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliografie"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Folder afhankelijkheidsgraaf voor ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detail niveau"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Template Parameters"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "en "+number+ " anderen..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "De documentatie voor deze enum is gegenereerd op grond van ";
+ if (single) result+="het"; else result+="de";
+ result+=" volgende bestand";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum Referentie"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" overgeërfd van "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Additionele Overgeërfde Members"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "in" : "uit";
+ return "klik hier de paneel synchronisatie "+opt+" the schakelen";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Wordt aangeboden door category @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Uitbereiding van klasse @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Klasse Methoden";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Instantie Methoden";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Methode Documentatie";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Ontwerp Overzicht";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Geëporteerde Interfaces"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Geïncludeerde Services"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Konstanten Groepen"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Konstanten Groepen Referentie";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Service Referentie";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Singleton Referentie";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ { QCString result = "De documentatie voor deze service is gegenereerd op grond van ";
+ if (single) result+="het"; else result+="de";
+ result+=" volgende bestand";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ { QCString result = "De documentatie voor deze singleton is gegenereerd op grond van ";
+ if (single) result+="het"; else result+="de";
+ result+=" volgende bestand";
+ if (single) result+=":"; else result+="en:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+};
+
+#endif
diff --git a/src/translator_no.h b/src/translator_no.h
new file mode 100644
index 0000000..2662e47
--- /dev/null
+++ b/src/translator_no.h
@@ -0,0 +1,1569 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/******************************************************************************
+ * Norwegian translation by Lars Erik Jordet <lejordet at gmail.com>, parts by Frode Nilsen
+ *
+ * This is a new translation made from scratch, not based on my older Norwegian translation (for 1.2.2)
+ *
+ * Translation notes (in Norwegian)
+ *
+ * Jeg har stort sett brukt ord som ligger ganske nær de engelske ekvivalentene,
+ * for eksempel "enumeration" -> "enumerasjon", og i enkelte tilfeller det engelske
+ * ordet direkte, der jeg finner det mer naturlig enn å prøve å stable en setning
+ * på beina på norsk, eller jeg selv foretrekker det engelske ordet (eks: "Header-fil").
+ * Om noen ikke skulle like disse valgene, kontakt meg på mailadressen over.
+ *
+ * Doxygen har mange strings som består av sammensatte ord ("Member function description", for eksempel),
+ * som ikke alltid ser like ryddig ut på norsk. Jeg har brukt bindestrek for å få
+ * det til å se presentabelt ut, men om noen har en bedre idé, send til mailadressen over.
+ *
+ * 2006-03-06:
+ * Jeg bruker ikke doxygen selv lenger, så det går nok litt i lengste laget mellom oppdateringer...
+ *
+ * Changelog
+ *
+ * 2003-12-18: Initial translation
+ * 2004-07-19: Fixup to prepare for 1.3.8 (I had forgotten some functions)
+ * 2006-03-06: Added a .diff from Frode Nilsen, now compatible with 1.4.6.
+ */
+
+#ifndef TRANSLATOR_NO_H
+#define TRANSLATOR_NO_H
+
+class TranslatorNorwegian : public TranslatorAdapter_1_4_6
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "norwegian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return
+ "\\usepackage[norwegian]{babel}\n"
+ "\\usepackage[T1]{fontenc}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Relaterte funksjoner"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Merk at disse ikke er medlemsfunksjoner.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detaljert beskrivelse"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Medlemstypedef-dokumentasjon"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Medlemsenumerasjon-dokumentasjon"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Medlemsfunksjon-dokumentasjon"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Feltdokumentasjon";
+ }
+ else
+ {
+ return "Medlemsdata-dokumentasjon";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Mer..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Liste over alle medlemmer"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Medlemsliste"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Dette er den fullstendige listen over medlemmer for "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", alle arvede medlemmer inkludert."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generert automatisk av Doxygen";
+ if (s) result+=(QCString)" for "+s;
+ result+=" fra kildekoden.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum-navn"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum-verdi"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definert i"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduler"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klassehierarki"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Klasseliste";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Fil-liste"; }
+
+ /*! This is put above each page as a link to the list of all verbatim headers */
+ virtual QCString trHeaderFiles()
+ { return "Header-filer"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datafelt";
+ }
+ else
+ {
+ return "Klassemedlemmer";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globale";
+ }
+ else
+ {
+ return "Filmedlemmer";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Relaterte sider"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Eksempler"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Søk"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Denne arvelisten er grovsortert alfabetisk "
+ "(ikke nødvendigvis korrekt):";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterte ";
+ result+="filer med korte beskrivelser:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Her er datastrukturene med korte beskrivelser:";
+ }
+ else
+ {
+ return "Her er klasser, struct'er, "
+ "unioner og interface'er med korte beskrivelser:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll)
+ {
+ result+="dokumenterte ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct- og unionfelter";
+ }
+ else
+ {
+ result+="klassemedlemmer";
+ }
+ result+=" med koblinger til ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct/union dokumentasjon for hvert felt:";
+ }
+ else
+ {
+ result+="klassedokumentasjonen for hvert medlem:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct'ene/unionene de hører til:";
+ }
+ else
+ {
+ result+="klassene de hører til:";
+ }
+ }
+ return result;
+ }
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterte ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funksjoner, variabler, definisjoner, enum'er, og typedef'er";
+ }
+ else
+ {
+ result+="filmedlemmer";
+ }
+ result+=" med koblinger til ";
+ if (extractAll)
+ result+="filene de hører til:";
+ else
+ result+="dokumentasjonen:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all header files. */
+ virtual QCString trHeaderFilesDescription()
+ { return "Her er alle header-filene som utgjør API'et:"; }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Her er en liste over alle eksemplene:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Her er en liste over alle relaterte dokumentasjonssider:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Her er en liste over alle moduler:"; }
+
+ /*! This sentences is used in the annotated class/file lists if no brief
+ * description is given.
+ */
+ virtual QCString trNoDescriptionAvailable()
+ { return "Ingen beskrivelse tilgjengelig"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentasjon"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modulindeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarkisk indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturindeks";
+ }
+ else
+ {
+ return "Klasseindeks";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Filindeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Moduldokumentasjon"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturdokumentasjon";
+ }
+ else
+ {
+ return "Klassedokumentasjon";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Fildokumentasjon"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Eksempeldokumentasjon"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Sidedokumentasjon"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referansemanual"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definisjoner"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedef'er"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerasjoner"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funksjoner"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variabler"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumerasjonsverdier"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Define-dokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef-dokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumerasjontype dokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerasjonsverdi dokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funksjonsdokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Variabeldokumentasjon"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Klasser";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generert "+date;
+ if (projName) result+=(QCString)" for "+projName;
+ result+=(QCString)" av";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Arvediagram for "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Kun for intern bruk."; }
+
+ /*! this text is generated when the \\reimp command is used. */
+ virtual QCString trReimplementedForInternalReasons()
+ { return "Reimplementert av interne grunner; API er ikke påvirket."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Advarsel"; }
+
+ /*! this text is generated when the \\bug command is used. */
+ virtual QCString trBugsAndLimitations()
+ { return "Feil og begrensninger"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versjon"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Dato"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Returnerer"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Se også"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametre"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Unntak"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generert av"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Navneromsliste"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterte ";
+ result+="navnerom med korte beskrivelser:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Venner"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Venner og relatert funksjonsdokumentasjon"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Klasse"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Grensesnitt"; break;
+ case ClassDef::Exception: result+=" Unntak"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Mal";
+ result+=" Referanse";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" filreferanse";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" navneromsreferanse";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Public medlemsfunksjoner"; }
+ virtual QCString trPublicSlots()
+ { return "Public slots"; }
+ virtual QCString trSignals()
+ { return "Signaler"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiske public medlemsfunksjoner"; }
+ virtual QCString trProtectedMembers()
+ { return "Protected memdlemsfunksjoner"; }
+ virtual QCString trProtectedSlots()
+ { return "Protected slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiske protected medlemsfunksjoner"; }
+ virtual QCString trPrivateMembers()
+ { return "Private medlemsfunksjoner"; }
+ virtual QCString trPrivateSlots()
+ { return "Private slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiske private medlemsfunksjoner"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", og ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Arver "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Arvet av "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementert fra "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementert i "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Navneromsmedlemmer"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Her er en liste over alle ";
+ if (!extractAll) result+="dokumenterte ";
+ result+="navneromsmedlemmer med koblinger til ";
+ if (extractAll)
+ result+="navneromsdokumentasjonen for hvert medlem:";
+ else
+ result+="navnerommet de hører til:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Navneromsindeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Navneromsdokumentasjon"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Navnerom"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentasjonen for ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="denne klasse"; break;
+ case ClassDef::Struct: result+="denne struct"; break;
+ case ClassDef::Union: result+="denne union"; break;
+ case ClassDef::Interface: result+="dette interface"; break;
+ case ClassDef::Exception: result+="dette unntak"; break;
+ case ClassDef::Protocol: result+="denne protocol"; break;
+ case ClassDef::Category: result+="denne category"; break;
+ default: break;
+ }
+ result+=" ble generert fra følgende fil";
+ if (single) result+=":"; else result+="er:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Returverdier"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hovedside"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trSources()
+ {
+ return "Kilder";
+ }
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definisjon på linje @0 i filen @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definisjon i filen @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Foreldet";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Samarbeidsdiagram for "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Avhengighetsgraf for "+fName+":";
+ }
+
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruktør- & destruktør-dokumentasjon";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Gå til kildekoden til denne filen.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Gå til dokumentasjonen til denne filen.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Forhåndsbetingelse";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Etterbetingelse";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Startverdi:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "kode";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafisk klassehierarki";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Gå til det grafiske klasse hierarkiet";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Gå til tekst-klassehierarki";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Innhold";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Notat";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Public typer";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datafelt";
+ }
+ else
+ {
+ return "Public attributter";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statiske public attributter";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Protected typer";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Protected attributter";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statiske protected attributter";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Private typer";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private attributter";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statiske private attributter";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Todo";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Todo-liste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referert av";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Merknader";
+ }
+ virtual QCString trAttention()
+ {
+ return "Viktig";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Denne grafen viser hvilke filer som direkte eller "
+ "indirekte inkluderer denne filen:";
+ }
+ virtual QCString trSince()
+ {
+ return "Siden";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Symbolforklaring";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Denne siden forklarer hvordan man tolker grafene doxygen genererer.<p>\n"
+ "Vi baserer oss på følgende eksempel:\n"
+ "\\code\n"
+ "/*! Usynlig klasse pga. trunkasjon */\n"
+ "class Invisible { };\n\n"
+ "/*! Trunkert klasse, arve-relasjon er skjult */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klasse som ikke er dokumentert med doxygen-kommentarer */"
+ "class Undocumented { };\n\n"
+ "/*! Klasse med public-arv */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasse med protected-arv */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klasse med private-arv */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klasse som blir brukt av klassen Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Super-klasse som arver flere andre klasser */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Hvis \\c MAX_DOT_GRAPH_HEIGHT er satt til 200 i "
+ "konfigurasjonsfila vil dette resultere i følgende graf:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Boksene i grafen over betyr følgende:\n"
+ "<ul>\n"
+ "<li>En fylt svart boks representerer klassen grafen "
+ "er generert for.\n"
+ "<li>En boks med svart ramme angir en dokumentert struct eller klasse.\n"
+ "<li>En boks med grå ramme angir en udokumentert struct eller klasse.\n"
+ "<li>En boks med rød ramme angir en dokumentert struct eller klasse "
+ "der ikke alle relasjoner er vist. En graf blir trunkert om den ikke "
+ "passer innenfor de spesifiserte rammene.\n"
+ "</ul>\n"
+ "Pilene i grafen har følgende betydning:\n"
+ "</ul>\n"
+ "<li>En mørk blå pil brukes til å visualisere public-arv mellom to klasser.\n"
+ "<li>En mørk grønn pil brukes for protected-arv.\n"
+ "<li>En mørk rød pil angir private-arv.\n"
+ "<li>En stiplet lilla pil angir at en klasse er inkludert eller brukt "
+ "i en annen klasse. Pilen er merket med variablen(e) klassen "
+ "er tilgjengelig gjennom.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "symbolforklaring";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test-liste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Egenskaper";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Egenskaps-dokumentasjon";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java interfaces in the summary section of Java packages */
+ virtual QCString trInterfaces()
+ {
+ return "Grensesnitt";
+ }
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Klasser";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakke-liste";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Her er pakkene med korte beskrivelser (om tilgjengelig):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakker";
+ }
+ /*! Used as a chapter title for Latex & RTF output */
+ virtual QCString trPackageDocumentation()
+ {
+ return "Pakke-dokumentasjon";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Verdi:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Feil";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Feil-liste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klasse" : "klasse"));
+ if (!singular) result+="r";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fil" : "fil"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Navnerom" : "navnerom"));
+ if (!singular) result+="";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Gruppe" : "gruppe"));
+ if (!singular) result+="r";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Side" : "side"));
+ if (!singular) result+="r";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Medlem" : "medlem"));
+ if (!singular) result+="mer";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trField(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Felt" : "felt"));
+ if (!singular) result+="";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="e";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Forfatter" : "forfatter"));
+ if (!singular) result+="e";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referanser";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementerer "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementert i "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Innholdsfortegnelse";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Liste over foreldede enheter";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Hendelser";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Hendelsesdokumentasjon";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Pakketyper";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Pakkefunksjoner";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statiske Pakkefunksjoner";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Pakkeattributter";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statiske Pakkeattributter";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alle";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Her er kall-grafen for denne funksjonen:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Søkeresultater";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Beklager, men ingen dokumenter ble funnet.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Fant <b>ett</b> dokument som passet ditt søk.";
+ }
+ else
+ {
+ return "Fant <b>$num</b> dokumenter som passet ditt søk. "
+ "Viser beste treff først.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Treff:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Kildefil " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Katalog hierarki"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Katalogdokumentasjon"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Kataloger"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Denne katalogen er grovsortert alfabetisk "
+ "(ikke nødvendigvis korrekt).";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Katalog referanse"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Katalog" : "katalog"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Dette er en overloaded medlemsfunksjon, "
+ "generert for deg. Den skiller seg ut fra "
+ "funksjonen ovenfor i argument(ene) den aksepterer.";
+ }
+};
+
+#endif
diff --git a/src/translator_pl.h b/src/translator_pl.h
new file mode 100644
index 0000000..6f2e14c
--- /dev/null
+++ b/src/translator_pl.h
@@ -0,0 +1,1867 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Polish translation was updated to version 1.3.9 by
+ * Piotr Kaminski (Piotr.Kaminski at ctm.gdynia.pl)
+ * Polish translation was updated since version 1.4.6 by
+ * Krzysztof Kral (krzysztof.kral at gmail.com)
+ */
+
+#ifndef TRANSLATOR_PL_H
+#define TRANSLATOR_PL_H
+
+class TranslatorPolish : public TranslatorAdapter_1_8_2
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. May resemble
+ * the string returned by latexBabelPackage(), but it is not used
+ * for the same purpose. The identification should not be translated.
+ * It should be replaced by the name of the language in English
+ * (e.g. Czech, Japanese, Russian, etc.). It should be equal to
+ * the identification in language.h.
+ */
+ QCString idLanguage()
+ { return "polish"; }
+ /*! Used to get the command(s) for the language support. This method
+ * was designed for languages which do not prefer babel package.
+ * If this methods returns empty string, then the latexBabelPackage()
+ * method is used to generate the command for using the babel package.
+ */
+ QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage{polski}\n"
+ "\\usepackage[T1]{fontenc}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ QCString trRelatedFunctions()
+ { return "Funkcje powiązane"; }
+
+ /*! subscript for the related functions. */
+ QCString trRelatedSubscript()
+ { return "(Zauważ, że to nie są metody klas.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ QCString trDetailedDescription()
+ { return "Opis szczegółowy"; }
+
+ /*! header that is put before the list of typedefs. */
+ QCString trMemberTypedefDocumentation()
+ { return "Dokumentacja składowych definicji typu"; }
+
+ /*! header that is put before the list of enumerations. */
+ QCString trMemberEnumerationDocumentation()
+ { return "Dokumentacja składowych wyliczanych"; }
+
+ /*! header that is put before the list of member functions. */
+ QCString trMemberFunctionDocumentation()
+ { return "Dokumentacja funkcji składowych"; }
+
+ /*! header that is put before the list of member attributes. */
+ QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentacja pól";
+ }
+ else
+ {
+ return "Dokumentacja atrybutów składowych";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ QCString trMore()
+ { return "Więcej..."; }
+
+ /*! put in the class documentation */
+ QCString trListOfAllMembers()
+ { return "Lista wszystkich składowych"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ QCString trMemberList()
+ { return "Lista składowych"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ QCString trThisIsTheListOfAllMembers()
+ { return "To jest kompletna lista składowych dla "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ QCString trIncludingInheritedMembers()
+ { return ", uwzględniająca wszystkie dziedziczone składowe."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Wygenerowano automatycznie z kodu źródłowego programem Doxygen";
+ if (s) result+=(QCString)" dla "+s;
+ result+=".";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ QCString trEnumName()
+ { return "nazwa wyliczenia"; }
+
+ /*! put after an enum value in the list of all members */
+ QCString trEnumValue()
+ { return "wartość wyliczenia"; }
+
+ /*! put after an undocumented member in the list of all members */
+ QCString trDefinedIn()
+ { return "zdefiniowana w"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ QCString trModules()
+ { return "Moduły"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ QCString trClassHierarchy()
+ { return "Hierarchia klas"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktury danych";
+ }
+ else
+ {
+ return "Lista klas";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ QCString trFileList()
+ { return "Lista plików"; }
+
+ /*! This is put above each page as a link to the list of all verbatim headers */
+ QCString trHeaderFiles()
+ { return "Pliki nagłówkowe"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Pola danych";
+ }
+ else
+ {
+ return "Składowe klas";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globalne";
+ }
+ else
+ {
+ return "Składowe plików";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ QCString trRelatedPages()
+ { return "Dodatkowe strony"; }
+
+ /*! This is put above each page as a link to all examples. */
+ QCString trExamples()
+ { return "Przykłady"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ QCString trSearch()
+ { return "Szukaj"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ QCString trClassHierarchyDescription()
+ { return "Ta lista dziedziczenia posortowana jest z grubsza, "
+ "choć nie całkowicie, alfabetycznie:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll) result+="udokumentowanych ";
+ result+="plików z ich krótkimi opisami:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Tutaj znajdują się struktury danych wraz z ich krótkimi opisami:";
+ }
+ else
+ {
+ return "Tutaj znajdują się klasy, struktury, "
+ "unie i interfejsy wraz z ich krótkimi opisami:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll)
+ {
+ result+="udokumentowanych ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="pól struktur i unii";
+ }
+ else
+ {
+ result+="składowych";
+ }
+ result+=" wraz z odnośnikami do ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="dokumentacji struktur/unii dla każdego pola:";
+ }
+ else
+ {
+ result+="dokumentacji klas dla każdej składowej:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktur/unii, do których dane pole należy:";
+ }
+ else
+ {
+ result+="klas, do których dana składowa należy:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll) result+="udokumentowanych ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcji, zmiennych, makr, wyliczeń i definicji typów";
+ }
+ else
+ {
+ result+="składowych plików";
+ }
+ result+=" wraz z odnośnikami do ";
+ if (extractAll)
+ result+="plików, do których one należą:";
+ else
+ result+="dokumentacji:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all header files. */
+ QCString trHeaderFilesDescription()
+ { return "Tutaj znajdują się pliki nagłówkowe tworzące API:"; }
+
+ /*! This is an introduction to the page with the list of all examples */
+ QCString trExamplesDescription()
+ { return "Tutaj znajduje się lista wszystkich przykładów:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ QCString trRelatedPagesDescription()
+ { return "Tutaj znajduje się lista wszystkich stron dokumentacji:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ QCString trModulesDescription()
+ { return "Tutaj znajduje się lista wszystkich grup:"; }
+
+ /*! This sentences is used in the annotated class/file lists if no brief
+ * description is given.
+ */
+ QCString trNoDescriptionAvailable()
+ { return "Brak opisu"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ QCString trDocumentation()
+ { return "Dokumentacja"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ QCString trModuleIndex()
+ { return "Indeks grup"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ QCString trHierarchicalIndex()
+ { return "Indeks hierarchiczny"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Indeks struktur danych";
+ }
+ else
+ {
+ return "Indeks klas";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ QCString trFileIndex()
+ { return "Indeks plików"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ QCString trModuleDocumentation()
+ { return "Dokumentacja grup"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentacja struktur danych";
+ }
+ else
+ {
+ return "Dokumentacja klas";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ QCString trFileDocumentation()
+ { return "Dokumentacja plików"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ QCString trExampleDocumentation()
+ { return "Dokumentacja przykładów"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ QCString trPageDocumentation()
+ { return "Dokumentacja stron"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ QCString trReferenceManual()
+ { return "Podręcznik"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ QCString trDefines()
+ { return "Definicje"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ QCString trTypedefs()
+ { return "Definicje typów"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ QCString trEnumerations()
+ { return "Wyliczenia"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ QCString trFunctions()
+ { return "Funkcje"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trVariables()
+ { return "Zmienne"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trEnumerationValues()
+ { return "Wartości wyliczeń"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ QCString trDefineDocumentation()
+ { return "Dokumentacja definicji"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ QCString trTypedefDocumentation()
+ { return "Dokumentacja definicji typów"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ QCString trEnumerationTypeDocumentation()
+ { return "Dokumentacja typów wyliczanych"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ QCString trFunctionDocumentation()
+ { return "Dokumentacja funkcji"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ QCString trVariableDocumentation()
+ { return "Dokumentacja zmiennych"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktury danych";
+ }
+ else
+ {
+ return "Komponenty";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Wygenerowano "+date;
+ if (projName) result+=(QCString)" dla "+projName;
+ result+=(QCString)" programem";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagram dziedziczenia dla "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ QCString trForInternalUseOnly()
+ { return "Tylko do użytku wewnętrznego."; }
+
+ /*! this text is generated when the \\reimp command is used. */
+ QCString trReimplementedForInternalReasons()
+ { return "Reimplementowana z wewnętrzych przyczyn; nie dotyczy API."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ QCString trWarning()
+ { return "Ostrzeżenie"; }
+
+ /*! this text is generated when the \\bug command is used. */
+ QCString trBugsAndLimitations()
+ { return "Błędy i ograniczenia"; }
+
+ /*! this text is generated when the \\version command is used. */
+ QCString trVersion()
+ { return "Wersja"; }
+
+ /*! this text is generated when the \\date command is used. */
+ QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ QCString trReturns()
+ { return "Zwraca"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ QCString trSeeAlso()
+ { return "Zobacz również"; }
+
+ /*! this text is generated when the \\param command is used. */
+ QCString trParameters()
+ { return "Parametry"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ QCString trExceptions()
+ { return "Wyjątki"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ QCString trGeneratedBy()
+ { return "Wygenerowano przez"; }
+
+ // new since 0.49-990307
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ QCString trNamespaceList()
+ { return "Lista przestrzeni nazw"; }
+
+ /*! used as an introduction to the namespace list */
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajdują się wszystkie ";
+ if (!extractAll) result+="udokumentowane ";
+ result+="przestrzenie nazw wraz z ich krótkimi opisami:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ QCString trFriends()
+ { return "Przyjaciele"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ QCString trRelatedFunctionDocumentation()
+ { return "Dokumentacja przyjaciół i funkcji związanych"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Dokumentacja";
+ if (isTemplate) result+=" szablonu";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" klasy "; break;
+ case ClassDef::Struct: result+=" struktury "; break;
+ case ClassDef::Union: result+=" unii "; break;
+ case ClassDef::Interface: result+=" interfejsu "; break;
+ case ClassDef::Protocol: result+=" protokołu "; break;
+ case ClassDef::Category: result+=" kategorii "; break;
+ case ClassDef::Exception: result+=" wyjątku "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ QCString trFileReference(const char *fileName)
+ {
+ QCString result="Dokumentacja pliku ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Dokumentacja przestrzeni nazw ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ QCString trPublicMembers()
+ { return "Metody publiczne"; }
+ QCString trPublicSlots()
+ { return "Sloty publiczne"; }
+ QCString trSignals()
+ { return "Sygnały"; }
+ QCString trStaticPublicMembers()
+ { return "Statyczne metody publiczne"; }
+ QCString trProtectedMembers()
+ { return "Metody chronione"; }
+ QCString trProtectedSlots()
+ { return "Sloty chronione"; }
+ QCString trStaticProtectedMembers()
+ { return "Statyczne metody chronione"; }
+ QCString trPrivateMembers()
+ { return "Metody prywatne"; }
+ QCString trPrivateSlots()
+ { return "Sloty prywatne"; }
+ QCString trStaticPrivateMembers()
+ { return "Statyczne metody prywatne"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" i ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ QCString trInheritsList(int numEntries)
+ {
+ return "Dziedziczy "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ QCString trInheritedByList(int numEntries)
+ {
+ return "Dziedziczona przez "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementowana z "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementowana w "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ QCString trNamespaceMembers()
+ { return "Składowe przestrzeni nazw"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll) result+="udokumentowanych ";
+ result+="składowych wraz z odnośnikami do ";
+ if (extractAll)
+ result+="dokumentacji przestrzeni nazw dla każdej składowej:";
+ else
+ result+="przestrzeni nazw do których składowe te należą:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ QCString trNamespaceIndex()
+ { return "Indeks przestrzeni nazw"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ QCString trNamespaceDocumentation()
+ { return "Dokumentacja przestrzeni nazw"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ QCString trNamespaces()
+ { return "Przestrzenie nazw"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacja dla te";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="j klasy"; break;
+ case ClassDef::Struct: result+="j struktury"; break;
+ case ClassDef::Union: result+="j unii"; break;
+ case ClassDef::Interface: result+="go interfejsu"; break;
+ case ClassDef::Protocol: result+="go protokołu"; break;
+ case ClassDef::Category: result+="j kategorii"; break;
+ case ClassDef::Exception: result+="go wyjątku"; break;
+ default: break;
+ }
+ result+=" została wygenerowana z plik";
+ if (single) result+="u:"; else result+="ów:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "Zwracane wartości"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "Strona główna"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "str."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trSources()
+ {
+ return "Źródła";
+ }
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definicja w linii @0 pliku @1.";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "Definicja w pliku @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Do wycofania";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagram współpracy dla "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Wykres zależności załączania dla "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "Dokumentacja konstruktora i destruktora";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "Idź do kodu źródłowego tego pliku.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "Idź do dokumentacji tego pliku.";
+ }
+ /*! Text for the \\pre command */
+ QCString trPrecondition()
+ {
+ return "Warunek wstępny";
+ }
+ /*! Text for the \\post command */
+ QCString trPostcondition()
+ {
+ return "Warunek końcowy";
+ }
+ /*! Text for the \\invariant command */
+ QCString trInvariant()
+ {
+ return "Niezmiennik";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "Wartość początkowa:";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "kod źródłowy";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Graficzna hierarchia klas";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "Idź do graficznej hierarchi klas";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "Idź do tekstowej hierarchi klas";
+ }
+ QCString trPageIndex()
+ {
+ return "Indeks stron";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "Nota";
+ }
+ QCString trPublicTypes()
+ {
+ return "Typy publiczne";
+ }
+ QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Pola danych";
+ }
+ else
+ {
+ return "Atrybuty publiczne";
+ }
+ }
+ QCString trStaticPublicAttribs()
+ {
+ return "Statyczne atrybuty publiczne";
+ }
+ QCString trProtectedTypes()
+ {
+ return "Typy chronione";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "Atrybuty chronione";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "Statyczne atrybuty chronione";
+ }
+ QCString trPrivateTypes()
+ {
+ return "Typy prywatne";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "Atrybuty prywatne";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "Statyczne atrybuty prywatne";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ QCString trTodo()
+ {
+ return "Do zrobienia";
+ }
+ /*! Used as the header of the todo list */
+ QCString trTodoList()
+ {
+ return "Lista rzeczy do zrobienia";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trReferencedBy()
+ {
+ return "Odwołania w";
+ }
+ QCString trRemarks()
+ {
+ return "Spostrzeżenia";
+ }
+ QCString trAttention()
+ {
+ return "Uwaga";
+ }
+ QCString trInclByDepGraph()
+ {
+ return "Ten wykres pokazuje, które pliki bezpośrednio lub "
+ "pośrednio załączają ten plik:";
+ }
+ QCString trSince()
+ {
+ return "Od";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ QCString trLegendTitle()
+ {
+ return "Legenda wykresu";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ QCString trLegendDocs()
+ {
+ return
+ "Ta strona wyjaśnia jak interpretować wykresy, które są wygenerowane "
+ "przez doxygen.<p>\n"
+ "Rozważ następujący przykład:\n"
+ "\\code\n"
+ "/*! Klasa Niewidzialna z powodu okrojenia */\n"
+ "class Niewidzialna { };\n\n"
+ "/*! Klasa Okrojona, relacja dziedziczenia jest ukryta */\n"
+ "class Okrojona : public Niewidzialna { };\n\n"
+ "/* Klasa nie udokumentowana komentarzami doxygen */\n"
+ "class Nieudokumentowana { };\n\n"
+ "/*! Klasa, która jest dziedziczona publicznie */\n"
+ "class PublicznaBaza : public Okrojona { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasa, która jest dziedziczona przy użyciu dziedziczenia chronionego */\n"
+ "class ChronionaBaza { };\n\n"
+ "/*! Klasa, która jest dziedziczona prywatnie */\n"
+ "class PrywatnaBaza { };\n\n"
+ "/*! Klasa, która jest użyta przez klasę Dziedziczona */\n"
+ "class Uzyta { };\n\n"
+ "/*! Superklasa, która dziedziczy kilka innych klas */\n"
+ "class Dziedziczona : public PublicznaBaza,\n"
+ " protected ChronionaBaza,\n"
+ " private PrywatnaBaza,\n"
+ " public Nieudokumentowana,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Uzyta *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Rezultat na następującym wykresie:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center></p>\n"
+ "<p>\n"
+ "Prostokąty w powyższym wykresie mają następujące znaczenie:\n"
+ "</p>\n"
+ "<ul>\n"
+ "<li>Wypełniony czarny prostokąt reprezentuje strukturę lub klasę dla "
+ "której został wygenerowany wykres.</li>\n"
+ "<li>Prostokąt z czarną obwolutą oznacza udokumentowaną strukturę lub klasę.</li>\n"
+ "<li>Prostokąt z szarą obwolutą oznacza nieudokumentowaną strukturę lub klasę.</li>\n"
+ "<li>Prostokąt z czerwoną obwolutą oznacza udokumentowaną strukturę lub klasę dla\n"
+ "której nie są pokazane wszystkie relacje dziedziczenia/zawierania. Wykres jest "
+ "okrojony, jeśli nie mieści się w określonych brzegach.</li>\n"
+ "</ul>\n"
+ "<p>\n"
+ "Strzałki mają następujące znaczenie:\n"
+ "<p>\n"
+ "<ul>\n"
+ "<li>Ciemno niebieska strzałka jest używana do wizualizacji relacji "
+ "dziedziczenia publicznego pomiędzy dwiema klasami.</li>\n"
+ "<li>Ciemno zielona strzałka jest używana dla dziedziczenia chronionego.</li>\n"
+ "<li>Ciemno czerwona strzałka jest używana dla dziedziczenia prywatnego.</li>\n"
+ "<li>Fioletowa przerywana strzałka jest używana jeśli klasa jest zawarta "
+ "lub użyta przez inną klasę. Strzałka jest podpisana zmienną(ymi) "
+ "przez które wskazywana klasa lub struktura jest dostępna. </li>\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ QCString trTestList()
+ {
+ return "Lista testu";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Właściwości";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentacja właściwości";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java interfaces in the summary section of Java packages */
+ virtual QCString trInterfaces()
+ {
+ return "Interfejsy";
+ }
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Struktury Danych";
+ }
+ else
+ {
+ return "Klasy";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pakiet "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista Pakietów";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Oto lista pakietów wraz z krótkim opisem (o ile jest dostępny):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakiety";
+ }
+ /*! Used as a chapter title for Latex & RTF output */
+ virtual QCString trPackageDocumentation()
+ {
+ return "Dokumentacja Pakietu";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Wartość:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Błąd";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista błędów";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6-20010422
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1250";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klas" : "klas"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Plik" : "plik"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Przestrze" : "przestrze"));
+ result+=(singular ? "ń" : "nie");
+ result+=" nazw";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupa" : "grupa"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stron" : "stron"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Składow" : "składow"));
+ result+=(singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trField(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Pol" : "pol"));
+ result+=(singular ? "e" : "a");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ result+=(singular ? "ny" : "ne");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auto" : "auto"));
+ result += (singular) ? "r" : "rzy";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Odwołuje się do";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementuje "+trWriteList(numEntries)+".";
+ }
+
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementowany w "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Spis treści";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista elementów do wycofania";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Zdarzenia";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentacja zdarzeń";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Typy pakietu";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkcje pakietu";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statyczne funkcje pakietu";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atrybuty pakietu";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statyczne atrybuty pakietu";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "All";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Oto graf wywołań dla tej funkcji:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Wyniki szukania";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Niestety żaden dokument nie pasuje do twojego zapytania.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Znaleziono <b>1</b> dokument pasujący do twojego zapytania.";
+ }
+ int count = numDocuments % 10;
+ if ((count>=2) && (count<=4))
+ {
+ return "Znaleziono <b>$num</b> dokumenty pasujące do twojego zapytania. "
+ "Najlepiej pasujące dokumenty wyświetlane są na początku listy.";
+ }
+ else
+ {
+ return "Znaleziono <b>$num</b> dokumentów pasujących do twojego zapytania. "
+ "Najlepiej pasujące dokumenty wyświetlane są na początku listy.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Pasujące słowa:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Plik źródłowy " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Struktura katalogów"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentacja katalogów"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Katalogi"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ {
+ return "Ta struktura katalogów jest posortowana jest z grubsza, "
+ "choć nie całkowicie, alfabetycznie:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Dokumentacja katalogu "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Katalog" : "katalog"));
+ if (! singular) result+="i";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "To jest metoda przeciążona, udostępniona dla wygody. "
+ "Różni się od powyższej metody tylko zestawem akceptowanych argumentów.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Oto graf wywoływań tej funkcji:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentacja wyliczeń"; } //TODO check if it is correct translation
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentacja składowej funkcji/podprogramu"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista typów danych"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Pola danych"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Tutaj znajdują się typy danych z ich krótkimi opisami:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll)
+ {
+ result+="udokumentowanych ";
+ }
+ result+="składowych typów danych";
+ result+=" wraz z odnośnikami do ";
+ if (!extractAll)
+ {
+ result+="dokumentacji struktury danych dla każdej składowej";
+ }
+ else
+ {
+ result+="typów danych, do których dana składowa należy:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Indeks typów danych"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentacja typów danych"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcje/podprogramy"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Dokumentacja funkcji/podprogramu"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Typy danych"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Lista modułów"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll) result+="udokumentowanych ";
+ result+="modułów z ich krótkimi opisami:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Dokumentacja";
+ if (isTemplate) result+=" szablonu";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" modułu "; break;
+ case ClassDef::Struct: result+=" typu "; break;
+ case ClassDef::Union: result+=" unii "; break;
+ case ClassDef::Interface: result+=" interfejsu "; break;
+ case ClassDef::Protocol: result+=" protokołu "; break;
+ case ClassDef::Category: result+=" kategorii "; break;
+ case ClassDef::Exception: result+=" wyjątku "; break;
+ default: break;
+ }
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Dokumentacja modułu ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Składowe modułu"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Tutaj znajduje się lista wszystkich ";
+ if (!extractAll) result+="udokumentowanych ";
+ result+="składowych modułów wraz z odnośnikami do ";
+ if (extractAll)
+ {
+ result+="dokumentacji modułu dla każdej składowej:";
+ }
+ else
+ {
+ result+="modułów do których składowe te należą:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Indeks modułu"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Moduł" : "moduł"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacja dla te";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="go modułu"; break;
+ case ClassDef::Struct: result+="go typu"; break;
+ case ClassDef::Union: result+="j unii"; break;
+ case ClassDef::Interface: result+="go interfejsu"; break;
+ case ClassDef::Protocol: result+="go protokołu"; break;
+ case ClassDef::Category: result+="j kategorii"; break;
+ case ClassDef::Exception: result+="go wyjątku"; break;
+ default: break;
+ }
+ result+=" została wygenerowana z plik";
+ if (single) result+="u:"; else result+="ów:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Typ" : "typ"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Podprogram" : "podprogram"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Więzy typów"; //TODO check if it is correct translation
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relcja "+ QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Wczytywanie...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globalna przestrzeń nazw";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Szukanie...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Brak dopasowań";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Plik w "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Zawiera plik w "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Pn","Wt","Śr","Cz","Pt","So","N" };
+ static const char *months[] = { "sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru" };
+ QCString sdate;
+ sdate.sprintf("%s, %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Odwołania do literatury"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Wykres zależności katalogu dla ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "poziom szczegółów"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametry Szablonu"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "i "+number+" więcej..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumentacja dla tego wyliczenia została wygenerowana z plik";
+ if (single) result+="u:"; else result+="ów:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { QCString result="Dokumentacja wyliczenia "; result+=name; return result; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" dziedziczone z "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Dodatkowe Dziedziczone Składowe"; }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_pt.h b/src/translator_pt.h
new file mode 100644
index 0000000..95a62b0
--- /dev/null
+++ b/src/translator_pt.h
@@ -0,0 +1,1840 @@
+/******************************************************************************
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Portuguese translation version 20110428
+ * Maintainer (from 04/28/2011):
+ * Fabio "FJTC" Jun Takada Chino <jun-chino at uol.com.br>
+ * Maintainer (until 04/28/2011):
+ * Rui Godinho Lopes <rui at ruilopes.com>
+ *
+ * Notes about this translation:
+ * Since I'm Brazilian, this translation may be odd or even incorect for
+ * Portuguese (from Portugal) speakers. If you find any errors, feel free
+ * to contact me.
+ *
+ * VERSION HISTORY
+ * ---------------
+ * History:
+ * 20110628:
+ * - Updated to 1.7.5;
+ * - All obsolete methods have been removed;
+ * 20110428
+ * - Updated to doxygen 1.6.3 using the Brazilian Portuguese as the base.
+ * Requires revision by a Portuguese (Portugal native speaker);
+ * 007 09 june 2003
+ * ! Updated for doxygen v1.3.1
+ * 006 30 july 2002
+ * ! Updated for doxygen v1.2.17
+ * 005 10 july 2002
+ * ! Updated for doxygen v1.2.16
+ * 004 03 march 2002
+ * ! Updated for doxygen v1.2.14
+ * 003 23 november 2001
+ * - Removed some obsolete methods (latexBabelPackage, trAuthor, trAuthors and trFiles)
+ * 002 19 november 2001
+ * ! Updated for doxygen v1.2.12
+ * 001 20 july 2001
+ * ! Updated for doxygen v1.2.8.1
+ * 000 ?
+ * + Initial translation for doxygen v1.1.5
+ */
+
+#ifndef TRANSLATOR_PT_H
+#define TRANSLATOR_PT_H
+
+
+class TranslatorPortuguese : public TranslatorAdapter_1_8_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ QCString idLanguage()
+ { return "portuguese"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ { return "Portuguese"; }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ QCString trRelatedFunctions()
+ { return "Funções associadas"; }
+
+ /*! subscript for the related functions. */
+ QCString trRelatedSubscript()
+ { return "(Note que não são funções membro)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ QCString trDetailedDescription()
+ { return "Descrição detalhada"; }
+
+ /*! header that is put before the list of typedefs. */
+ QCString trMemberTypedefDocumentation()
+ { return "Documentação das definições de tipo"; }
+
+ /*! header that is put before the list of enumerations. */
+ QCString trMemberEnumerationDocumentation()
+ { return "Documentação das enumerações"; }
+
+ /*! header that is put before the list of member functions. */
+ QCString trMemberFunctionDocumentation()
+ { return "Documentação dos métodos"; }
+
+ /*! header that is put before the list of member attributes. */
+ QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentação dos campos e atributos";
+ }
+ else
+ {
+ return "Documentação dos dados membro";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ QCString trMore()
+ { return "Mais..."; }
+
+ /*! put in the class documentation */
+ QCString trListOfAllMembers()
+ { return "Mostrar lista completa dos membros"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ QCString trMemberList()
+ { return "Lista dos membros"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ QCString trThisIsTheListOfAllMembers()
+ { return "Lista completa de todos os membros de "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ QCString trIncludingInheritedMembers()
+ { return ", incluindo todos os membros herdados."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Gerado automaticamente por Doxygen";
+ if (s) result+=(QCString)" para "+s;
+ result+=" a partir do código fonte.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ QCString trEnumName()
+ { return "enumeração"; }
+
+ /*! put after an enum value in the list of all members */
+ QCString trEnumValue()
+ { return "valor enumerado"; }
+
+ /*! put after an undocumented member in the list of all members */
+ QCString trDefinedIn()
+ { return "definido em"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ QCString trModules()
+ { return "Módulos"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ QCString trClassHierarchy()
+ { return "Hierarquia de classes"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de dados";
+ }
+ else
+ {
+ return "Lista de componentes";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ QCString trFileList()
+ { return "Lista de ficheiros"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de dados";
+ }
+ else
+ {
+ return "Componentes membro";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globais";
+ }
+ else
+ {
+ return "Ficheiros membro";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ QCString trRelatedPages()
+ { return "Páginas relacionadas"; }
+
+ /*! This is put above each page as a link to all examples. */
+ QCString trExamples()
+ { return "Exemplos"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ QCString trSearch()
+ { return "Localizar"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ QCString trClassHierarchyDescription()
+ { return "Esta lista de heranças está organizada, dentro do possível, por ordem alfabética:"; }
+
+ /*! This is an introduction to the list with all files. */
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Lista de todos os ficheiros ";
+ if (!extractAll) result+="documentados ";
+ result+="com uma breve descrição:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Lista das estruturas de dados com uma breve descrição:";
+ }
+ else
+ {
+ return "Lista de classes, estruturas, uniões e interfaces com uma breve descrição:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Lista de todas as";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+=" estruturas e campos de uniões";
+ }
+ else
+ {
+ result+=" classes membro";
+ }
+ if (!extractAll)
+ {
+ result+=" documentadas";
+ }
+ result+=" com referência para ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="a respectiva documentação:";
+ }
+ else
+ {
+ result+="a documentação de cada membro:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="as estruturas/uniões a que pertencem:";
+ }
+ else
+ {
+ result+="as classes a que pertencem:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Lista de ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="todas as funções, variáveis, definições, enumerações e definições de tipo ";
+ if (!extractAll) result+="documentadas ";
+ }
+ else
+ {
+ result+="todos os ficheiros membro ";
+ if (!extractAll) result+="documentados ";
+ }
+ result+="com referência para ";
+ if (extractAll)
+ result+="o ficheiro a que pertecem:";
+ else
+ result+="a respectiva documentação:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ QCString trExamplesDescription()
+ { return "Lista de todos os exemplos:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ QCString trRelatedPagesDescription()
+ { return "Lista de documentação relacionada:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ QCString trModulesDescription()
+ { return "Lista de todos os módulos:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ QCString trDocumentation()
+ { return "Documentação"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ QCString trModuleIndex()
+ { return "Índice dos módulos"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ QCString trHierarchicalIndex()
+ { return "Índice da hierarquia"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Índice das estruturas de dados";
+ }
+ else
+ {
+ return "Índice dos componentes";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ QCString trFileIndex()
+ { return "Índice dos ficheiros"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ QCString trModuleDocumentation()
+ { return "Documentação do módulo"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ QCString trClassDocumentation()
+ { return "Documentação da classe"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ QCString trFileDocumentation()
+ { return "Documentação do ficheiro"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ QCString trExampleDocumentation()
+ { return "Documentação do exemplo"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ QCString trPageDocumentation()
+ { return "Documentação da página"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ QCString trReferenceManual()
+ { return "Manual de referência"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ QCString trDefines()
+ { return "Macros"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ QCString trTypedefs()
+ { return "Definições de tipos"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ QCString trEnumerations()
+ { return "Enumerações"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ QCString trFunctions()
+ { return "Funções"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trVariables()
+ { return "Variáveis"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ QCString trEnumerationValues()
+ { return "Valores da enumeração"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ QCString trDefineDocumentation()
+ { return "Documentação das macros"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ QCString trTypedefDocumentation()
+ { return "Documentação dos tipos"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ QCString trEnumerationTypeDocumentation()
+ { return "Documentação dos valores da enumeração"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ QCString trFunctionDocumentation()
+ { return "Documentação das funções"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ QCString trVariableDocumentation()
+ { return "Documentação das variáveis"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de Dados";
+ }
+ else
+ {
+ return "Componentes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Gerado em "+date;
+ if (projName) result+=(QCString)" para "+projName;
+ result+=(QCString)" por";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de heranças da classe "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ QCString trForInternalUseOnly()
+ { return "Apenas para uso interno."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ QCString trWarning()
+ { return "Aviso"; }
+
+ /*! this text is generated when the \\version command is used. */
+ QCString trVersion()
+ { return "Versão"; }
+
+ /*! this text is generated when the \\date command is used. */
+ QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ QCString trReturns()
+ { return "Retorna"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ QCString trSeeAlso()
+ { return "Veja também"; }
+
+ /*! this text is generated when the \\param command is used. */
+ QCString trParameters()
+ { return "Parâmetros"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ QCString trExceptions()
+ { return "Excepções"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ QCString trGeneratedBy()
+ { return "Gerado por"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Lista de namespaces"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Lista ";
+ if (!extractAll) result+="de toda a documentação ";
+ result+="dos namespaces com uma breve descrição:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Amigos"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Documentação das classes amigas e funções relacionadas"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referência ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="à classe "; break;
+ case ClassDef::Struct: result+="à estrutura "; break;
+ case ClassDef::Union: result+="à união "; break;
+ case ClassDef::Interface: result+="ao interface "; break;
+ case ClassDef::Protocol: result+="ao protocolo "; break;
+ case ClassDef::Category: result+="à categoria "; break;
+ case ClassDef::Exception: result+="à excepção "; break;
+ default: break;
+ }
+ if (isTemplate) result+="Template ";
+ result+=(QCString)clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result= "Referência ao ficheiro ";
+ result += fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result= "Referência ao namespace ";
+ result += namespaceName;
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ virtual QCString trPublicMembers()
+ { return "Membros públicos"; }
+ virtual QCString trPublicSlots()
+ { return "Slots públicos"; }
+ virtual QCString trSignals()
+ { return "Sinais"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Membros públicos estáticos"; }
+ virtual QCString trProtectedMembers()
+ { return "Membros protegidos"; }
+ virtual QCString trProtectedSlots()
+ { return "Slots protegidos"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Membros protegidos estáticos"; }
+ virtual QCString trPrivateMembers()
+ { return "Membros privados"; }
+ virtual QCString trPrivateSlots()
+ { return "Slots privados"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Membros privados estáticos"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" e ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Derivada de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Herdado por "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementado de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementado em "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Membros do namespace"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Lista ";
+ if (extractAll) result+="de todos os ";
+ else result+="de toda a documentação dos ";
+ result+="membros do namespace com referência para ";
+ if (extractAll)
+ result+="a documentação de cada membro:";
+ else
+ result+="o namespace correspondente:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Índice dos namespaces"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Documentação dos namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"A documentação para ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="esta classe"; break;
+ case ClassDef::Struct: result+="esta estrutura"; break;
+ case ClassDef::Union: result+="esta união"; break;
+ case ClassDef::Interface: result+="este interface"; break;
+ case ClassDef::Protocol: result+="este protocolo"; break;
+ case ClassDef::Category: result+="esta categoria"; break;
+ case ClassDef::Exception: result+="esta excepção"; break;
+ default: break;
+ }
+ result+=" foi gerada a partir ";
+ if (single) result+=" do seguinte ficheiro:";
+ else result+="dos seguintes ficheiros:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valores retornados"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Página principal"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p. "; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definido na linha @0 do ficheiro @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definido no ficheiro @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Desaprovado";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de colaboração para "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Diagrama de dependências de inclusão para "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Documentação dos Construtores & Destrutor";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Ir para o código fonte deste ficheiro.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Ir para a documentação deste ficheiro.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondição";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Poscondição";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariante";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valor inicial:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "código";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Representação gráfica da hiearquia da classe";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Ir para a representação gráfica da hierarquia da classe";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Ir para a representação textual da hierarquia da classe";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Índice da página";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Nota";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Tipos Públicos";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Campos de Dados";
+ }
+ else
+ {
+ return "Atributos Públicos";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atributos Públicos Estáticos";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipos Protegidos";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atributos Protegidos";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atributos Protegidos Estáticos";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipos Privados";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atributos Privados";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atributos Privados Estáticos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Tarefa";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Lista de tarefas";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referenciado por";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Observações";
+ }
+ virtual QCString trAttention()
+ {
+ return "Atenção";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Este grafo mostra quais são os ficheiros que incluem directamente ou indirectamente este ficheiro:";
+ }
+ virtual QCString trSince()
+ {
+ return "Desde";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda do grafo";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Esta página explica como interpretar os grafos gerados pelo doxygen.<p>\n"
+ "Considere o seguinte exemplo:\n"
+ "\\code\n"
+ "/*! Esta classe vai estar escondida devido à truncação */\n"
+ "class Invisible { };\n\n"
+ "/*! Esta classe tem a relação de herança escondida */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Classe não documentada por comentários doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Classe derivada usando derivação pública */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Classe derivada usando derivação protegida */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Classe derivada usando derivação privada */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Classe usada pela classe Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Super classe que deriva de várias classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Isto irá gerar o seguinte gráfo:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "As caixas no grafo anterior têm as seguintes interpretações:\n"
+ "<ul>\n"
+ "<li>Uma caixa inteiramente preta representa a estrutura ou a classe para "
+ "a qual o grafo foi gerado.\n"
+ "<li>Uma caixa com borda preta representa uma estrutura ou classe documentada.\n"
+ "<li>Uma caixa com borda cinzenta representa uma estrutura ou classe não documentada.\n"
+ "<li>Uma caixa com borda vermelha representa uma estrutura ou classe documentada onde "
+ "nem todas as relações de herança/encapsulamento são exibidas. Um grafo é truncado "
+ "quando não cabe na sua área predefinida.\n"
+ "</ul>\n"
+ "As setas têm a seguinte interpretação:\n"
+ "<ul>\n"
+ "<li>Uma seta azul escura representa uma relação de herança pública entre duas classes.\n"
+ "<li>Uma seta verde escura representa uma relação de herança protegida.\n"
+ "<li>Uma seta vermelha escura representa uma relação de herança privada.\n"
+ "<li>Uma seta rocha em tracejado representa uma relação de encapsulamento ou uso por "
+ "parte de outra classe. A legenda da seta contém o nome da variável ou variáveis da "
+ "relação. A seta aponta da classe que estabelece a relação para a classe ou estrutura que "
+ "é acessível.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Teste";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Lista de teste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propriedades";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentação das propriedades";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Estruturas de dados";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pacote "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista de pacotes";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Lista de pacotes com uma breve descrição (se disponível):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pacotes";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valor:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista de Bugs";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Índice";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Classe" : "classe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Ficheiro" : "ficheiro"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupo" : "grupo"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Página" : "página"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membro" : "membro"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globa" : "globa"));
+ result+= singular? "l" : "ais";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referências";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementado em "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Índice";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista de Deprecados";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Eventos";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentação dos eventos";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipos do Pacote";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funções do Pacote";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funções Estáticas do Pacote";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributos do Pacote";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Atributos Estáticos do Pacote";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tudo";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Grafo de chamadas desta função:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3 - Based on the Brazilian Portuguese Translation
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Resultado da Busca";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Nenhum documento foi encontrado.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Apenas <b>1</b> documento foi encontrado.";
+ }
+ else
+ {
+ return "<b>$num</b> documentos encontrados. "
+ "Os melhores resultados vem primeiro.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Resultados:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Código-Fonte de " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarquia de Diretórios"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentação do Directório"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Diretórios"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Esta Hierarquia de Diretórios está parcialmente ordenada (ordem alfabética)"; }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result = "Referência do diretório ";
+ result += dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Diretório" : "diretório"));
+ if (!singular) result+="s";
+ return result;
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Este é um método provido por conveniência. "
+ "Ele difere do método acima apenas na lista de "
+ "argumentos que devem ser utilizados.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Este é o diagrama das funções que utilizam esta função:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentação da enumeração"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentação de Função Membro/Subrotina"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista de Tipos de Dados"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Campos de Dados"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Aqui estão os tipos de dados com descrições resumidas:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os membros ";
+ if (!extractAll) result+="documentados ";
+ result+="dos tipos de dados com links para ";
+ if (extractAll)
+ {
+ result+="a documentação dos tipos de dados para cada membro:";
+ }
+ else
+ {
+ result+="os tipos de dados a que pertencem:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Índice de Tipos de Dados"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentação dos Tipos de Dados"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funções/Subrotinas"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentação da Função/Subrotina"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipos de Dados"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Lista de Módulos"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os módulos ";
+ if (!extractAll) result+="documentados ";
+ result+="com descrições resumidas:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result = (QCString)"Referência ";
+
+ if (isTemplate) result+="da Template ";
+
+ switch(compType)
+ {
+ case ClassDef::Class: result+="do Modulo "; break;
+ case ClassDef::Struct: result+="do Tipo "; break;
+ case ClassDef::Union: result+="da União "; break;
+ case ClassDef::Interface: result+="da Interface "; break;
+ case ClassDef::Protocol: result+="do Protocolo "; break;
+ case ClassDef::Category: result+="da Categoria "; break;
+ case ClassDef::Exception: result+="da Exceção "; break;
+ default: break;
+ }
+ result += clName;
+
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result = "Referência do Módulo ";
+ result += namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membros do Módulo"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Esta é a lista de todos os membros ";
+ if (!extractAll) result+="documentados ";
+ result+="dos módulos com links para ";
+ if (extractAll)
+ {
+ result+="a documentação dos módulos para cada membro:";
+ }
+ else
+ {
+ result+="os módulos a que pertencem:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Índice dos Módulos"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modulo" : "modulo"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"A documentação para ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="este modulo "; break;
+ case ClassDef::Struct: result+="este tipo "; break;
+ case ClassDef::Union: result+="esta união "; break;
+ case ClassDef::Interface: result+="esta interface "; break;
+ case ClassDef::Protocol: result+="esto protocolo "; break;
+ case ClassDef::Category: result+="esta categoria "; break;
+ case ClassDef::Exception: result+="esta exceção "; break;
+ default: break;
+ }
+
+ result+=" foi gerada a partir do";
+ if (single)
+ result+=" seguinte ficheiro:";
+ else
+ result+="s seguintes ficheiros:";
+
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipo" : "tipo"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprograma" : "subprograma"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Restrições do Tipo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name
+ */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relação " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Carregando...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Procurando...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nenhuma entrada encontrada";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Ficheiro em "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inclui ficheiro em "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Segunda","Terça","Quarta","Quinta","Sexta","Sábado","Domingo" };
+ static const char *months[] = { "Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" };
+ QCString sdate;
+ sdate.sprintf("%s, %d de %s de %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Referências Bibliográficas"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ {
+ // Note: I will left it as is because "Direitos de autor" may not fit
+ // in the text.
+ return "Copyright";
+ }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Grafo de dependências do directório ")+name+":"; }
+};
+
+#endif
diff --git a/src/translator_ro.h b/src/translator_ro.h
new file mode 100644
index 0000000..ea0988d
--- /dev/null
+++ b/src/translator_ro.h
@@ -0,0 +1,2020 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/* Original translation from English to Romanian by Alexandru Iosup [aiosup at yahoo.com].
+ * Updated by Ionuţ Dumitraşcu [reddumy at yahoo.com]
+ *
+ * -------------------------------------------
+ * Project start : 20.09.2000
+ * Last Doxygen version covered : 1.8.4
+ * Last revision : 17.05.2013
+ * -------------------------------------------
+ *
+ * Revision history
+ * ----------------
+ * 17.05.2013 - Updated translation to cover Doxygen 1.8.4 (Ionuț Dumitrașcu)
+ * 15.01.2009 - Updated Romanian translation to Doxygen 1.5.8 and modified strings to UTF-8, as well as some other changes (Ionuţ Dumitraşcu)
+ * 28.07.2008 - Updated version - covering Doxygen 1.5.6 - and some minor changes (Ionuţ Dumitraşcu)
+ *
+ * 01.Mar.2k5 Third revision, covering Doxygen 1.4.1
+ *
+ * 07.Mar.2k2 Second revision, covering Doxygen 1.2.14
+ * - fixed some bugs
+ *
+ * 20.Sep.2k First version, covering Doxygen 1.2.1
+ *
+ */
+#ifndef TRANSLATOR_RO_H
+#define TRANSLATOR_RO_H
+
+
+class TranslatorRomanian : public Translator
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "romanian"; }
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[romanian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Funcţii înrudite"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Atenţie: acestea nu sunt funcţii membre.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Descriere Detaliată"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Documentaţia Definiţiilor de Tipuri (typedef) Membre"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Documentaţia Enumerărilor Membre"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Documentaţia Funcţiilor Membre"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentaţia Câmpurilor";
+ }
+ else
+ {
+ return "Documentaţia Datelor Membre";
+ }
+
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Mai mult..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Lista tuturor membrilor"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Lista Membrilor"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Lista completă a membrilor din "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", inclusiv a tuturor membrilor moşteniţi."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Generat automat de Doxygen";
+ if (s) result+=(QCString)" pentru "+s;
+ result+=" din codul sursă.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "nume enumerare"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "valoare enumerare"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definit în"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Module"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Ierarhia Claselor"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structuri de Date";
+ }
+ else
+ {
+ return "Lista Claselor";
+ }
+
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Lista fişierelor"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Câmpurile de Date";
+ }
+ else
+ {
+ return "Membrii Componenţi"; //cu articol hotarat
+ }
+
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globale";
+ }
+ else
+ {
+ return "Membrii din Fişier"; //cu articol hotarat
+ }
+
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Pagini înrudite"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Exemple"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Caută"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Această listă de moşteniri este sortată în general, "
+ "dar nu complet, în ordine alfabetică:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor ";
+ result+="fişierelor";
+ if (!extractAll) result+=" documentate";
+ result+=", cu scurte descrieri:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Lista structurilor de date, cu scurte descrieri:";
+ }
+ else
+ {
+ return "Lista claselor, structurilor, uniunilor şi interfeţelor"
+ ", cu scurte descrieri:";
+ }
+
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="câmpurilor ";
+ if (!extractAll) result+=" documentate ";
+ result+="din structuri si uniuni ";
+ }
+ else
+ {
+ result+="membrilor ";
+ if (!extractAll) result+="documentaţi ";
+ result+="din toate clasele ";
+ }
+ result+=", cu legături către ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="documentaţia structurii/uniunii pentru fiecare câmp în parte:";
+ }
+ else
+ {
+ result+="documentaţia clasei pentru fiecare membru în parte:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="structurile/uniunile de care aparţin:";
+ }
+ else
+ {
+ result+="clasele de care aparţin:";
+ }
+ }
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funcţiilor, variabilelor, definiţiilor, enumerărilor şi definiţiilor de tip";
+ if (!extractAll) result+=" documentate";
+ }
+ else
+ {
+ result+="membrilor ";
+ if (!extractAll) result+="documentaţi ";
+ result+="din toate fişierele";
+ }
+ result+=", cu legături către ";
+ if (extractAll)
+ result+="fişierele de care aparţin:";
+ else
+ result+="documentaţia aferentă:";
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Lista tuturor exemplelor:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Lista tuturor documentaţiilor înrudite:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Lista tuturor modulelor:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Documentaţie"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Indexul Modulelor"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Index Ierarhic"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Indexul Structurilor de Date";
+ }
+ else
+ {
+ return "Indexul Claselor";
+ }
+
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Indexul Fişierelor"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Documentaţia Modulelor"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Documentaţia Structurilor de Date";
+ }
+ else
+ {
+ return "Documentaţia Claselor";
+ }
+
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Documentaţia Fişierelor"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Documentaţia Exemplelor"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Documentaţii înrudite"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Manual de utilizare"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definiţii"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definiţii de tipuri"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerări"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funcţii"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Variabile"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Valori de enumerări"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Documentaţia definiţiilor"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Documentaţia definiţiilor de tipuri"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Documentaţia enumerărilor"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Documentaţia funcţiilor"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Documentaţia variabilelor"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structuri de Date";
+ }
+ else
+ {
+ return "Membri";
+ }
+
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generat "+date;
+ if (projName) result+=(QCString)" pentru "+projName;
+ result+=(QCString)" de către";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de relaţii pentru "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Doar pentru uz intern."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Atenţie"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Versiunea"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Data"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Întoarce"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Vezi şi"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametri"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Excepţii"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generat de"; }
+
+ // new since 0.49-990307
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Lista de Namespace-uri"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor ";
+ result+="namespace-urilor ";
+ if (!extractAll) result+="documentate ";
+ result+=", cu scurte descrieri:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Prieteni"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Documentaţia funcţiilor prietene sau înrudite"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referinţă la ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="clasa "; break;
+ case ClassDef::Struct: result+="structura "; break;
+ case ClassDef::Union: result+="uniunea "; break;
+ case ClassDef::Interface: result+="interfaţa "; break;
+ case ClassDef::Protocol: result+="protocolul "; break;
+ case ClassDef::Category: result+="categoria "; break;
+ case ClassDef::Exception: result+="excepţia "; break;
+ default: break;
+ }
+ if (isTemplate) result+=" (Template) ";
+ result+=(QCString)clName;
+
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result="Referinţă la fişierul ";
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Referinţă la Namespace-ul ";
+ result+=namespaceName;
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ virtual QCString trPublicMembers()
+ { return "Metode Publice"; }
+ virtual QCString trPublicSlots()
+ { return "Conectori (slots) Publici"; }
+ virtual QCString trSignals()
+ { return "Semnale"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Metode Statice Publice"; }
+ virtual QCString trProtectedMembers()
+ { return "Metode Protejate"; }
+ virtual QCString trProtectedSlots()
+ { return "Conectori (slots) Protejaţi"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Metode Statice Protejate"; }
+ virtual QCString trPrivateMembers()
+ { return "Metode Private"; }
+ virtual QCString trPrivateSlots()
+ { return "Conectori (slots) Privaţi"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Metode Statice Private"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" şi ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Moşteneşte "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Moştenit de "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Reimplementat din "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Reimplementat în "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Membrii Namespace-ului"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor membrilor ";
+ if (!extractAll) result+="documentaţi ";
+ result+="din toate namespace-urile, cu legături către ";
+
+ if (extractAll)
+ result+="documentaţia namespace-ului pentru fiecare membru în parte:";
+ else
+ result+="namespace-urile de care aparţin:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Indexul Namespace-ului"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Documentaţia Namespace-ului"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespace-uri"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Documentaţia pentru această ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="clasă"; break;
+ case ClassDef::Struct: result+="structură"; break;
+ case ClassDef::Union: result+="uniune"; break;
+ case ClassDef::Interface: result+="interfaţă"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="categorie"; break;
+ case ClassDef::Exception: result+="excepţie"; break;
+ default: break;
+ }
+ result+=" a fost generată din fişier";
+ if (single) result+="ul:"; else result+="ele:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Valori returnate"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Pagina principală"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "pg."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definiţia în linia @0 a fişierului @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definiţia în fişierul @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Învechită(Deprecated)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagrama de relaţii pentru "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graful dependenţelor prin incluziune pentru "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Documentaţia pentru Constructori şi Destructori";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Vezi sursele.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Vezi documentaţia.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Precondiţie";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postcondiţie";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Valoarea iniţială:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "cod";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Ierarhia Claselor în mod grafic";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Vezi ierarhia claselor în mod grafic";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Vezi ierarhia claselor în mod text";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Indexul Paginilor";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Notă";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Tipuri Publice";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Câmpuri de Date";
+ }
+ else
+ {
+ return "Atribute Publice";
+ }
+
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Atribute Statice Publice";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Tipuri Protejate";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Atribute Protejate";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Atribute Statice Protejate";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Tipuri Private";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Atribute Private";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Atribute Statice Private";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "De făcut";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Lista lucrurilor de făcut";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Semnalat de";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Observaţii";
+ }
+ virtual QCString trAttention()
+ {
+ return "Atenţie";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Acest graf arată care fişiere includ, "
+ "direct sau indirect, acest fişier:";
+ }
+ virtual QCString trSince()
+ {
+ return "Din";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda grafului";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Această pagină arată modul în care trebuie să interpretaţi "
+ "grafurile generate de doxygen.<p>\n"
+ "Consideraţi următorul exemplu:\n"
+ "\\code\n"
+ "/*! Clasă invizibilă, tăiată din cauza depăşirii spaţiului */\n"
+ "class Invisible { };\n\n"
+ "/*! Altă clasă tăiată, relaţia de moştenire este ascunsă */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Clasă necomentată în stil doxygen */\n"
+ "class Undocumented { };\n\n"
+ "/*! Clasă care este moştenită în mod public */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Clasă template */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Clasă care este moştenită în mod protejat */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Clasă care este moştenită în mod privat */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Clasă care este folosită de clasa Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Superclasă care moşteneşte un număr de alte clase */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Dacă tagul \\c MAX_DOT_GRAPH_HEIGHT din fişierul de configurare "
+ "este setat la 200, acesta este graful rezultat:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Căsuţele din partea de sus au următoarea semnificaţie:\n"
+ "<ul>\n"
+ "<li>O căsuţă neagră reprezintă structura sau clasa pentru care "
+ "graful este generat.\n"
+ "<li>O căsuţă cu marginea neagră reprezintă o structură sau o clasă documentate.\n"
+ "<li>O căsuţă cu marginea gri reprezintă o structură sau o clasă nedocumentate.\n"
+ "<li>O căsuţă cu marginea roşie reprezintă o structură sau o clasă documentate, pentru\n"
+ "care nu toate relaţiile de moştenire/incluziune sunt arătate. Un graf este "
+ "tăiat dacă nu încape în marginile specificate."
+ "</ul>\n"
+ "Săgeţile au următoarea semnificaţie:\n"
+ "<ul>\n"
+ "<li>O săgeată de un albastru închis este folosită când avem o relaţie de "
+ "moştenire publică între două clase.\n"
+ "<li>O săgeată de un verde închis este folosită când avem o moştenire protejată.\n"
+ "<li>O săgeată de un roşu închis este folosită când avem o moştenire privată.\n"
+ "<li>O săgeată violetă punctată este folosită pentru o clasă conţinută sau folosită "
+ "de o altă clasă. Săgeata este marcată cu variabila(e) "
+ "prin care este accesibilă clasa sau structura spre care este îndreptată. \n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Listă de teste";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Proprietăţi";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentaţia Proprietăţilor";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structuri de Date";
+ }
+ else
+ {
+ return "Clase";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pachet "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Lista Pachetelor";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Lista pachetelor, însoţită de scurte explicaţii, acolo unde acestea există:";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pachete";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valoare:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Problema (Bug)";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Lista de Probleme (Bugs)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1250"; //EASTEUROPE_CHARSET
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Clas" : "clas"));
+ result+= singular ? "a":"ele";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fişier" : "fişier"));
+ result+= singular ? "ul":"ele";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ result+= singular ? "-ul":"-urile";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupu" : "grupu"));
+ result+= singular ? "l":"rile";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Pagin" : "pagin"));
+ result+= singular ? "a":"ile";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membr" : "membr"));
+ result+= singular ? "ul":"ii";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="e";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ result+= singular ? "ul":"ii";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referinţe";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementează "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementat în "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Cuprins";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista elementelor învechite (deprecated)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Evenimente";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Documentaţia aferentă evenimentelor";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipuri în pachet";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funcţii în pachet";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Funcţii statice în pachet";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atribute în pachet";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Atribute statice în pachet";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Toate";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Graful de apel al acestei funcţii:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Rezultatele căutarii";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Din păcate nu am găsit nici un document care să corespundă cererii.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Am găsit <b>1</b> document corespunzând cererii.";
+ }
+ else
+ {
+ return "Am găsit <b>$num</b> documente corespunzând cererii. "
+ "Lista documentelor găsite, sortate după relevanţă.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Găsite:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return " Fişierul sursă " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Ierarhia directoarelor"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Documentaţia directoarelor"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directoare"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Această ierarhie de directoare este sortată în general, "
+ "dar nu complet, în ordine alfabetică:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result="Director-referinţă "; result+=dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Directo" : "directo"));
+ if (singular) result+="r"; else result="are";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Aceasta este o funcţie membră suprascrisă. "
+ "Diferă de funcţia de mai sus "
+ "doar prin argumentele acceptate.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Graful de apeluri pentru această funcţie:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Documentaţia Enumeratorilor"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Documentaţia Funcţiei Membre/Subrutinei"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Lista Tipurilor de Date"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Câmpuri de date"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Tipurile de date, cu scurte descrieri:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Lista tuturor tipurilor de date ";
+ if (!extractAll)
+ {
+ result+="documentate ";
+ }
+ result+=" cu legături către ";
+ if (!extractAll)
+ {
+ result+="documentaţia structurii de date pentru fiecare membru";
+ }
+ else
+ {
+ result+="tipurile de date de care aparţin:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Indexul Tipurilor de Date"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Documentaţia Tipurilor de Date"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funcţii/Subrutine"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Documentaţia Funcţiilor/Subrutinelor"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Tipuri de Date"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Lista Modulelor"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor modulelor ";
+ if (!extractAll) result+="documentate ";
+ result+="cu scurte descrieri:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result="Referinţă la ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Modulul "; break;
+ case ClassDef::Struct: result+="Tipul "; break;
+ case ClassDef::Union: result+="Uniunea "; break;
+ case ClassDef::Interface: result+="Interfaţa "; break;
+ case ClassDef::Protocol: result+="Protocolul "; break;
+ case ClassDef::Category: result+="Categoria "; break;
+ case ClassDef::Exception: result+="Excepţia "; break;
+ default: break;
+ }
+ if (isTemplate) result+="(Template) ";
+ result+=(QCString)clName;
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Referinţă la Modulul ";
+ result += namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Membrii Modulului"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Lista tuturor membrilor ";
+ if (!extractAll) result+="documentaţi ai ";
+ result+="modulului cu legături către ";
+ if (extractAll)
+ {
+ result+="documentaţia modulului pentru fiecare membru:";
+ }
+ else
+ {
+ result+="modulele de care aparţin:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Indexul Modulelor"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (singular) result+="ul";
+ else result += "ele";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Documentaţia ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modulului"; break;
+ case ClassDef::Struct: result+="tipului"; break;
+ case ClassDef::Union: result+="uniunii"; break;
+ case ClassDef::Interface: result+="interfeţei"; break;
+ case ClassDef::Protocol: result+="protocolului"; break;
+ case ClassDef::Category: result+="categoriei"; break;
+ case ClassDef::Exception: result+="excepţiei"; break;
+ default: break;
+ }
+ result+=" a fost generată din următo";
+ if (single) result+="rul fişier:"; else result+="arele fişiere:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (singular) result+="ul";
+ else result += "urile";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (singular) result+="ul";
+ else result += "ele";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Constrângerile de Tip";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relație";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Se încarcă...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Namespace Global";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Căutare...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Niciun rezultat";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Fișierul din "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Include fișierul din "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Luni","Marți","Miercuri","Joi","Vineri","Sâmbătă","Duminică" };
+ static const char *months[] = { "Ian","Feb","Mar","Apr","Mai","Iun","Iul","Aug","Sep","Oct","Noi","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Referințe Bibliografice"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Grafic de dependență a directoarelor pentru ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "nivel de detaliu"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametri Template"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "și încă " + number; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Documentația pentru acest enum a fost generată din ";
+ if (single)
+ result += "următorul fișier:";
+ else
+ result += "următoarele fișiere:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Referință Enum"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" moștenit(e) din "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Membri Moșteniți Adiționali"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "activa" : "dezactiva";
+ return "apasă click pentru a "+opt+" sincronizarea panourilor";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Furnizat de categoria @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Extinde clasa @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Metodele Clasei";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Metodele Instanței";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Documentația Metodelor";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Vedere de Ansamblu a Designului";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Interfețe exportate"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Servicii Incluse"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Grupuri Constante"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Referință Grup Constant";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Referință Serviciu";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Referință Singleton";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Documentația pentru acest serviciu "
+ "a fost generată din ";
+ if (single)
+ result += "următorul fișier:";
+ else
+ result += "următoarele fișiere:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Documentația pentru acest singleton "
+ "a fost generată din ";
+ if (single)
+ result += "următorul fișier:";
+ else
+ result += "următoarele fișiere:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_ru.h b/src/translator_ru.h
new file mode 100644
index 0000000..54174d7
--- /dev/null
+++ b/src/translator_ru.h
@@ -0,0 +1,1974 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ */
+
+/*
+ *
+ * Nickolay Semyonov
+ * Andrey V. Stolyarov released Feb 14, 2001
+ * Alexandr V. Chelpanov <cav at cryptopro.ru> released Sep 25, 2004
+ * Благодарности: Vitaly A. Repin <vitaly at radio.hop.stu.neva.ru>,
+ * Михаил Глушенков <bbman at mail.ru>
+ */
+
+#ifndef TRANSLATOR_RU_H
+#define TRANSLATOR_RU_H
+
+class TranslatorRussian : public Translator
+{
+ public:
+ /*! Used for identification of the language. */
+ virtual QCString idLanguage()
+ { return "russian"; }
+
+ /* Used to get the command(s) for the language support. */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[T2A]{fontenc}\n\\usepackage[russian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Относящиеся к классу функции"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(не члены класса)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Подробное описание"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Определения типов"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Перечисления"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Методы"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля";
+ }
+ else
+ {
+ return "Данные класса";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Подробнее..."; }
+
+ /*! put in the class documentation */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trListOfAllMembers()
+ {
+ return "Полный список членов класса";
+ }
+
+ /*! used as the title of the "list of all members" page of a class */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trMemberList()
+ {
+ return "Cписок членов класса";
+ }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Полный список членов класса "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", включая наследуемые из базового класса"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Автоматически создано Doxygen";
+ if (s) result+=QCString(" для ")+s;
+ result+=" из исходного текста.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "перечисление"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "элементы перечисления"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "определено в"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Группы"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Иерархия классов"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуры данных";
+ }
+ else
+ {
+ return "Классы";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Файлы"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля структур";
+ }
+ else
+ {
+ return "Члены классов";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ /*??*/
+ virtual QCString trFileMembers()
+ {
+ return "Список членов всех файлов";
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ /* ?? Вариант перевода "См. также: " более удачный, но не в заголовке,
+ как в данном случае. */
+ { return "Описания"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Примеры"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Поиск"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Иерархия классов."; }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Полный список ";
+ if (!extractAll) result+="документированных ";
+ result+="файлов.";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуры данных с их кратким описанием.";
+ }
+ else
+ {
+ return "Классы с их кратким описанием.";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Список всех ";
+ if(!extractAll) result+="документированных ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="членов структур данных со ссылками на ";
+ else
+ result+="членов классов со ссылками на ";
+ if(!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="документацию по структуре для каждого члена.";
+ else
+ result+="документацию по классу для каждого члена.";
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result += "структуры";
+ else
+ result += "классы";
+ result+=", к которым они принадлежат.";
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Список всех ";
+ if (!extractAll) result+="документированных ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="функций, переменных, макроопределений, "
+ "перечислений и определений типов";
+ }
+ else
+ {
+ result+="членов файлов ";
+ }
+ result+=" со ссылками на ";
+ if (extractAll)
+ result+="файлы, к которым они принадлежат.";
+ else
+ result+="документацию.";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Полный список примеров."; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Полный список дополнительных описаний."; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Полный список групп."; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Документация"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Алфавитный указатель групп"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Иерархический список классов"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Алфавитный указатель структур данных";
+ }
+ else
+ {
+ return "Алфавитный указатель классов";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Список файлов"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Группы"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуры данных";
+ }
+ else
+ {
+ return "Классы";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Файлы"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Примеры"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Тематические описания"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Оглавление"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Макросы"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Определения типов"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Перечисления"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Функции"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Переменные"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Элементы перечислений"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Макросы"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Типы"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Перечисления"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Функции"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Переменные"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуры данных";
+ }
+ else
+ {
+ return "Классы";
+ }
+
+ }
+
+ /*! This is used in the documentation of a group before the list of
+ * links to documented files
+ */
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result="Документация ";
+ if (projName) result+=QCString("по ")+projName;
+ result+=QCString(". Последние изменения: ")+date;
+ result+=". Создано системой";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return QCString("Граф наследования:")+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Только для внутреннего использования"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Предупреждения"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Версия"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Дата"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Возвращает"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "См. также"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Аргументы"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Исключения"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Создано системой"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Пространства имен"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Полный список ";
+ if (!extractAll) result+="документированных ";
+ result+="пространств имен.";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Друзья"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Документация по друзьям класса и функциям, относящимся"
+ " к классу"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result;
+ if (isTemplate)
+ {
+ result="Шаблон ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="класса"; break;
+ case ClassDef::Struct: result+="структуры"; break;
+ case ClassDef::Union: result+="объединения"; break;
+ case ClassDef::Interface: result+="интерфейса"; break;
+ case ClassDef::Protocol: result+="протокола"; break;
+ case ClassDef::Category: result+="категории"; break;
+ case ClassDef::Exception: result+="исключения"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Класс"; break;
+ case ClassDef::Struct: result+="Структура"; break;
+ case ClassDef::Union: result+="Объединение"; break;
+ case ClassDef::Interface: result+="Интерфейс"; break;
+ case ClassDef::Protocol: result+="Протокол"; break;
+ case ClassDef::Category: result+="Категория"; break;
+ case ClassDef::Exception: result+="Исключение"; break;
+ default: break;
+ }
+ }
+ result+=" ";
+ return result+clName;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ return QCString("Файл ")+fileName;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ return QCString("Пространство имен ")+namespaceName;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Открытые члены"; }
+ virtual QCString trPublicSlots()
+ { return "Открытые слоты"; }
+ virtual QCString trSignals()
+ { return "Сигналы"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Открытые статические члены"; }
+ virtual QCString trProtectedMembers()
+ { return "Защищенные члены"; }
+ virtual QCString trProtectedSlots()
+ { return "Защищенные слоты"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Защищенные статические члены"; }
+ virtual QCString trPrivateMembers()
+ { return "Закрытые члены"; }
+ virtual QCString trPrivateSlots()
+ { return "Закрытые слоты"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Закрытые статические члены"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" и ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Базовые классы:"+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Производные классы:"+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ QCString result="Переопределяет метод";
+ if(numEntries>1)
+ result+="ы предков";
+ else
+ result+=" предка";
+ return result+" "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Переопределяется в "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Члены пространств имен"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Полный список ";
+ if (!extractAll) result+="документированных ";
+ result+="членов простанств имен.";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Алфавитный указатель пространств имен"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Пространства имен"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Пространства имен"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=QCString("Объявления и описания членов ");
+ switch(compType)
+ {
+ case ClassDef::Class: result+="класс";
+ if (single) result+="а"; else result+="ов";
+ break;
+ case ClassDef::Struct: result+="структур";
+ if (single) result+="ы";
+ break;
+ case ClassDef::Union: result+="объединени";
+ if (single) result+="я"; else result+="й";
+ break;
+ case ClassDef::Interface: result+="интерфейс";
+ if (single) result+="а"; else result+="ов";
+ break;
+ case ClassDef::Protocol: result+="протокол";
+ if (single) result+="а"; else result+="ов";
+ break;
+ case ClassDef::Category: result+="категори";
+ if (single) result+="и"; else result+="й";
+ break;
+ case ClassDef::Exception: result+="исключени";
+ if (single) result+="я"; else result+="й";
+ break;
+ default:
+ break;
+ }
+ result+=" находятся в файл";
+ if (single) result+="е:"; else result+="ах:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Возвращаемые значения"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Титульная страница"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "стр."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "См. определение в файле @1 строка @0";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "См. определение в файле @0";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Уст.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Граф связей класса "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Граф включаемых заголовочных файлов для "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Конструктор(ы)";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "См. исходные тексты.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "См. документацию.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Предусловие";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Постусловие";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Инвариант";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Инициализатор";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "Исходные тексты";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Иерархия классов. Графический вид.";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "см. графический вид.";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "см. текстовый вид.";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Алфавитный указатель тематических описаний";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Заметки";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Открытые типы";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля данных";
+ }
+ else
+ {
+ return "Открытые атрибуты";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Статические открытые данные";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Защищенные типы";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Защищенные данные";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Статические защищенные данные";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Закрытые типы";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Закрытые данные";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Закрытые статические данные";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ /*??*/
+ {
+ return "Необходимо сделать";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ /*??*/
+ {
+ return "Список задач";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Используется в";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Прим.";
+ }
+ virtual QCString trAttention()
+ {
+ return "Внимание";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Граф файлов, в которые включается этот файл:";
+ }
+ virtual QCString trSince()
+ /*??*/
+ {
+ return "Начиная с";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Легенда";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Обозначения, используемые в графах.<p>\n"
+ "Рассмотрим следующий пример:\n"
+ "\\code\n"
+ "/*! Невидимый класс из-за усечения */\n"
+ "class Invisible { };\n\n"
+ "/*! Усеченный класс, отношение наследования скрыто */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Недокументированный класс */\n"
+ "class Undocumented { };\n\n"
+ "/*! Открытое наследование */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Шаблон класса */\n"
+ "template<class T> class Templ {};\n\n"
+ "/*! Защищенное наследование */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Закрытое наследование */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Класс, используемый классом Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Класс, порожденный от других классов */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Если \\c MAX_DOT_GRAPH_HEIGHT в конфигурационном файле "
+ "установлен в 240, получится следующий граф:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Прямоугольники в этом графе имеют следующее значение:\n"
+ "<ul>\n"
+ "<li>Заполненный черный прямоугольник представляет структуру или класс, "
+ "для которого создан граф.\n"
+ "<li>Прямоугольник с черной границей обозначает документированную структуру или класс.\n"
+ "<li>Прямоугольник с серой границей обозначает недокументированную структуру или класс.\n"
+ "<li>Прямоугольник с красной границей обозначает документированную структуру или класс, для которого\n"
+ " не все отношения наследования/содержания показаны. Граф усечен, "
+ "если он не поместился в указанных границах.\n"
+ "</ul>\n"
+ "Стрелки имеют следующее значение:\n"
+ "<ul>\n"
+ "<li>Темно-синяя стрелка используется для изображения отношения открытого наследования "
+ "между двумя классами.\n"
+ "<li>Темно-зеленая стрелка используется при защищенном наследовании.\n"
+ "<li>Темно-красная стрелка используется при закрытом наследовании.\n"
+ "<li>Фиолетовая стрелка используется, если класс содержится в"
+ "другом класе или используется другим классом."
+ "Со стрелкой указывается переменная, "
+ "через которую доступен указываемый класс или структура. \n"
+ "<li>Желтая стрелка используется для связи подстановки шаблона и "
+ "шаблона, на основе которого эта подстановка выполнена. С шаблоном"
+ "указывается параметр подстановки.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "см. легенду";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Тест";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Список тестов";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Свойства";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Полный список свойств";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуры данных";
+ }
+ else
+ {
+ return "Классы";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return QCString("Пакет ")+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Полный список пакетов ";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Полный список документированных пакетов.";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Пакеты";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Макроопределение:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Ошибка";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Ошибки";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1251";
+ }
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "204";
+ }
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Алфавитный указатель";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ QCString result((first_capital ? "Структуры данных" : "структуры данных"));
+ return result;
+ }
+ else
+ {
+ QCString result((first_capital ? "Класс" : "класс"));
+ if(!singular) result+="ы";
+ return result;
+ }
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Файл" : "файл"));
+ if (!singular) result+="ы";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Пространств" : "пространств"));
+ result+=(singular?"о имен":"а имен");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Групп" : "групп"));
+ result+=(singular ? "а" : "ы");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Страниц" : "страниц"));
+ result+=(singular ? "а" : "ы");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Член" : "член"));
+ if (!singular) result+="ы";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Глобальны" : "глобальны"));
+ result+=(singular ? "й" : "е");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Автор" : "автор"));
+ if (!singular) result+="ы";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Перекрестные ссылки";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Замещает "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implementation this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Замещается в "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Оглавление";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Список устаревших определений и описаний";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "События";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Cобытия";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Типы с областью видимости пакета";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Функции с областью видимости пакета";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Статические функции с областью видимости пакета";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Переменные с областью видимости пакета";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Статические переменные с областью видимости пакета";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Указатель";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Граф вызовов:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Результаты поиска";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "К сожалению, по Вашему запросу ничего не найдено.";
+ }
+ else if( numDocuments == 1 )
+ {
+ return "Найден 1 документ.";
+ }
+ else
+ {
+ return "Найден(о) <b>$num</b> документ(ов). "
+ "Документы отсортированы по релевантности.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Найдено:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Исходный файл " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Дерево директорий"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Директории"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Алфавитный указатель директорий"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Дерево директорий"; }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=QCString("Содержание директории ")+ dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Директори" : "директори"));
+ if (singular) result+="я"; else result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Эта функция перегружена и предоставляется исключительно "
+ "для удобства использования. Она отличается от вышеупомянутой "
+ "только фактическими аргументами.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Граф вызова функции:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Элементы перечислений"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+ // Простите переводчика, уже лет 20 не писал на фортране...
+ // Любые замечания приму с благодарностью.
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Функции/подпрограммы"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Типы данных"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Поля данных"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Аннотированный список типов данных:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Список всех ";
+ if (!extractAll)
+ {
+ result+="документированных ";
+ }
+ result+="членов типа со ссылками ";
+ if (!extractAll)
+ {
+ result+="на документацию для каждого члена:";
+ }
+ else
+ {
+ result+="на содержащую структуру:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Типы данных"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Оглавление типов данных"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Функции/подпрограммы"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Функции/подпрограммы"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Типы данных"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Указатель модулей"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Аннотированный список";
+ if (!extractAll) result+="документированных ";
+ result+="модулей:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate)
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Модуль"; break;
+ case ClassDef::Struct: result+=" Тип"; break;
+ case ClassDef::Union: result+=" Объединение"; break;
+ case ClassDef::Interface: result+=" Интерфейс"; break;
+ case ClassDef::Protocol: result+=" Протокол"; break;
+ case ClassDef::Category: result+=" Категория"; break;
+ case ClassDef::Exception: result+=" Исключение"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ if (isTemplate) result+=" Шаблон ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="модуля"; break;
+ case ClassDef::Struct: result+="типа"; break;
+ case ClassDef::Union: result+="объединения"; break;
+ case ClassDef::Interface: result+="интерфейса"; break;
+ case ClassDef::Protocol: result+="протокола"; break;
+ case ClassDef::Category: result+="категории"; break;
+ case ClassDef::Exception: result+="исключения"; break;
+ default: break;
+ }
+ }
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ return QCString("Модуль ") + namespaceName;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Члены модуля"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Список всех ";
+ if (!extractAll) result+="документированных ";
+ result+="модулей со ссылками ";
+ if (extractAll)
+ {
+ result+="на документацию для каждого члена:";
+ }
+ else
+ {
+ result+="на модули, их содержащие:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Указатель модулей"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Модул" : "модул"));
+ if (singular) result+="ь"; else result+="и";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документация по ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="модулю"; break;
+ case ClassDef::Struct: result+="типу"; break;
+ case ClassDef::Union: result+="объединению"; break;
+ case ClassDef::Interface: result+="интерфейсу"; break;
+ case ClassDef::Protocol: result+="протоколу"; break;
+ case ClassDef::Category: result+="категории"; break;
+ case ClassDef::Exception: result+="исключению"; break;
+ default: break;
+ }
+ result+=" сгенерирована на основе следующ";
+ if (single) result+="его файла:"; else result+="их файлов:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Тип" : "тип"));
+ if (!singular) result+="ы";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Подпрограмм" : "подпрограмм"));
+ if (singular) result+="а"; else result+="ы";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Согласование типов";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Связь";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Загрузка...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Глобальное пространство имён";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Поиск...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Не найдено";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Файл в "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Включает файл в "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Пн","Вт","Ср","Чт","Пт","Сб","Вс" };
+ static const char *months[] = { "Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+///////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+///////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Библиографические ссылки"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Авторство"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Директория графа зависимостей ")+name+":"; }
+
+///////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+///////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "уровень детализации"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Параметры шаблона"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "и "+number+" больше..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Документация для этого перечисления сгенерерирована из файл";
+ if (!single) result += "ов";
+ result+="а:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Ссылки на перечисление"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" унаследованные от "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Дополнительные унаследованные члены"; }
+
+///////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+///////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "включить" : "выключить";
+ return "нажмите на "+opt+" для синхронизации панелей";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "По группам @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Расширяет класс @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Методы класса";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Методы экземпляра";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Документация метода";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Обзор дизайна";
+ }
+
+///////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+///////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Экспортируемые интерфейсы"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Включённые сервисы"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Постоянные группы"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Ссылка на постоянную группу";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Ссылка на сервис";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Ссылка на одиночку";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Документация для этого сервиса "
+ "сгенерирована из следующего файл";
+ if (single) result+="а:"; else result+="ов:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Документация по этому одиночке "
+ "сгенерирована из следующего файл";
+ if (single) result+="а:"; else result+="ов:";
+ return result;
+ }
+
+///////////////////////////////////////////////////////////////////////
+};
+
+#endif
diff --git a/src/translator_sc.h b/src/translator_sc.h
new file mode 100644
index 0000000..84e8756
--- /dev/null
+++ b/src/translator_sc.h
@@ -0,0 +1,1765 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_SC_H
+#define TRANSLATOR_SC_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "serbian-cyrillic"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Повезане функције"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Напомињемо да ово нису функције чланице.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Опширније"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Документација дефиниције типа"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Документација члана набрајања"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Документација функције чланице"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Документација поља";
+ }
+ else
+ {
+ return "Документација атрибута";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Још..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Списак свих чланова"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Списак чланова"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Ово је списак свих чланова од "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", укључујући све наслеђене чланове."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Аутоматски направљено помоћу Doxygen-а";
+ if (s) result+=(QCString)" за "+s;
+ result+=" из изворног кода.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "назив набрајања"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "вредност набрајања"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "дефинисано у"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Модули"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Хијерархија класа"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуре";
+ }
+ else
+ {
+ return "Списак класа";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Списак датотека"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поља";
+ }
+ else
+ {
+ return "Чланови класе";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Глобално";
+ }
+ else
+ {
+ return "Чланови датотеке";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Повезане странице"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Примери"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Тражи"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Овај списак наслеђивања је уређен "
+ "скоро по абецеди:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+ result+="датотека са кратким описима:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Овде су структуре са кратким описима:";
+ }
+ else
+ {
+ return "Овде су класе, структуре, "
+ "уније и интерфејси са кратким описима:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll)
+ {
+ result+="документованих ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="поља структура и унија";
+ }
+ else
+ {
+ result+="чланова класа";
+ }
+ result+=" са везама ка ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="документацији структуре/уније за свако поље:";
+ }
+ else
+ {
+ result+="документацији класе за сваки члан:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="структури/унији којој припадају:";
+ }
+ else
+ {
+ result+="класи којој припадају:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="фрункција, променљивих, макро замена, набрајања, и дефиниција типова";
+ }
+ else
+ {
+ result+="чланова датотеке";
+ }
+ result+=" са везама ка ";
+ if (extractAll)
+ result+="датотекама којима припадају:";
+ else
+ result+="документацији:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Овде је списак свих примера:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Овде је списак свих повезаних страница документације:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Овде је списак свих модула:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Документација"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Индекс модула"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Хијерархијски индекс"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Индекс структура";
+ }
+ else
+ {
+ return "Индекс класа";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Индекс датотека"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Документација модула"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Документација структуре";
+ }
+ else
+ {
+ return "Документација класе";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Документација датотеке"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Документација примера"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Документација странице"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Приручник"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Дефиниције"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Дефиниције типова"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Набрајања"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Функције"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Променљиве"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Вредности набрајања"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Документација дефиниције"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Документација дефиниције типа"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Документација набрајања"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Документација функције"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Документација променљиве"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуре";
+ }
+ else
+ {
+ return "Класе";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Направљено "+date;
+ if (projName) result+=(QCString)" за "+projName;
+ result+=(QCString)" помоћу";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Дијаграм наслеђивања за "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Само за унутрашњу употребу."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Упозорење"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Верзија"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Датум"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Враћа"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Види"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Параметри"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Изизеци"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Направљено помоћу"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Списак простора имена"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+ result+="простора имена са кратким описима:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Пријатељи"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Документација за пријатеље и повезане функције"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate)
+ {
+ result+=" Шаблон";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="ска класа"; break;
+ case ClassDef::Struct: result+="ска структура"; break;
+ case ClassDef::Union: result+="ска унија"; break;
+ case ClassDef::Interface: result+="ски интерфејс"; break;
+ case ClassDef::Protocol: result+="ски протокол"; break;
+ case ClassDef::Category: result+="ска категорија"; break;
+ case ClassDef::Exception: result+="ски изузетак"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ result+=" Референца";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" класе"; break;
+ case ClassDef::Struct: result+=" структуре"; break;
+ case ClassDef::Union: result+=" уније"; break;
+ case ClassDef::Interface: result+=" интерфејса"; break;
+ case ClassDef::Protocol: result+=" протокола"; break;
+ case ClassDef::Category: result+=" категорије"; break;
+ case ClassDef::Exception: result+=" изузетка"; break;
+ default: break;
+ }
+ }
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" Референца датотеке";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Референца простора имена";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Јавне функције чланице"; }
+ virtual QCString trPublicSlots()
+ { return "Јавни слотови"; }
+ virtual QCString trSignals()
+ { return "Сигнали"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Статичке јавне функције чланице"; }
+ virtual QCString trProtectedMembers()
+ { return "Заштићене функције чланице"; }
+ virtual QCString trProtectedSlots()
+ { return "Заштићени слотови"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Статичке заштићене функције чланице"; }
+ virtual QCString trPrivateMembers()
+ { return "Приватне функције чланице"; }
+ virtual QCString trPrivateSlots()
+ { return "Приватни слотови"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Статичке приватне функције чланице"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" и ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Наслеђује "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Наслеђују "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Поново имплементирано од "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Поново имплементирано у "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Чланови простора имена"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+ result+="чланова простора имена са везама ка ";
+ if (extractAll)
+ result+="документацији простора имена за сваки члан:";
+ else
+ result+="просторима имена којима припадају:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Индекс простора имена"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Документација простора имена"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Простори имена"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документација за ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="ову класу"; break;
+ case ClassDef::Struct: result+="ову структуру"; break;
+ case ClassDef::Union: result+="ову унију"; break;
+ case ClassDef::Interface: result+="овај интерфејс"; break;
+ case ClassDef::Protocol: result+="овај протокол"; break;
+ case ClassDef::Category: result+="ову категорију"; break;
+ case ClassDef::Exception: result+="овај изузетак"; break;
+ default: break;
+ }
+ result+=" је произведена из";
+ if (single) result+="следеће датотеке:"; else result+="следећих датотека:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Враћене вредности"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Главна страница"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "стр."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Дефиниција у линији @0 датотеке @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Дефиниција у датотеци @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Застарело";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Дијаграм сарадње за "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Дијаграм зависности укључивања за "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Документација конструктора и деструктора";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Иди на изворни код овог фајла.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Иди на документацију овог фајла.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Услов пре";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Услов после";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Инваријанта";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Почетна вредност:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "код";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Графичка хијерархија класа";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Иди на графичку хијерархију класа";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Иди на текстуалну хијерархију класа";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Индекс страна";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Напомена";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Јавни типови";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поља";
+ }
+ else
+ {
+ return "Јавни атрибути";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Статички јавни атрибути";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Заштићени типови";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Заштићени атрибути";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Статички заштићени атрибути";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Приватни типови";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Приватни атрибути";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Статички приватни атрибути";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Урадити";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Подсетник шта још урадити";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Референцирано од";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Напомене";
+ }
+ virtual QCString trAttention()
+ {
+ return "Пажња";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Овај граф показује које датотеке директно или "
+ "или индиректно укључују овај фајл:";
+ }
+ virtual QCString trSince()
+ {
+ return "Од";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Легенда графова";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Ова страница објашњава како тумачити графове који су направљени "
+ "doxygen-ом.<p>\n"
+ "Размотримо следећи пример:\n"
+ "\\code\n"
+ "/*! Невидљива класа због одсецања */\n"
+ "class Invisible { };\n\n"
+ "/*! Одсечена класа, веза наслеђивања је скривена */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Класа која није документована doxygen коментарима */\n"
+ "class Undocumented { };\n\n"
+ "/*! Класа која је наслеђена јавним наслеђивањем */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Шаблонска класа */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Класа која је наслеђена заштићеним наслеђивањем */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Класа која је наслеђена јавним наслеђивањем */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Класа коју користи наслеђена класа */\n"
+ "class Used { };\n\n"
+ "/*! Надкласа која наслеђује неки број других класа */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Ако је \\c MAX_DOT_GRAPH_HEIGHT таг у конфигурационој датотеци "
+ "подешен на 240, то ће резултовати на следећи начин:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Правоугаоници имају следеће значење:\n"
+ "<ul>\n"
+ "<li>%Пуни сиви правоугаоник представља структуру или класу за коју је "
+ "граф направљен.\n"
+ "<li>%Правоугаоник са црним оквиром означава документовану структуру или класу.\n"
+ "<li>%Правоугаоник са сивим оквиром означава недокументовану структуру или класу.\n"
+ "<li>%Правоугаоник са црвеним оквиром означава документовану структуру или класу за"
+ "за коју нису све релације наслеђивања/садржавања приказане. %Граф је "
+ "одсечен ако излази из специфицираних оквира.\n"
+ "</ul>\n"
+ "Стрелице имају следећа значења:\n"
+ "<ul>\n"
+ "<li>%Тамноплава стрелица се користи да прикаже релацију јавног извођења "
+ "између двеју класа.\n"
+ "<li>%Тамнозелена стрелица се користи за заштићено наслеђивање.\n"
+ "<li>%Тамноцрвена стрелица се користи за приватно наслеђивање.\n"
+ "<li>%Љубичаста испрекидана стрелица се користи ако класа садржи или користи "
+ "друга класа. Стрелица је означена променљивом/променљивама "
+ "кроз које је показивана класа или структура доступна.\n"
+ "<li>%Жута испрекидана стрелица означава везу између примерка шаблона и "
+ "и шаблонске класе из које је инстанцирана. Стрелица је означена "
+ "параметрима примерка шаблона.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "легенда";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Тест";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Списак тестова";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Своства";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Документација свосјтва";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структуре";
+ }
+ else
+ {
+ return "Класе";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Пакет "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Списак пакета";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Овде су пакети са кратким описима (ако су доступни):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Пакети";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Вредност:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Грешка";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Списак грешака";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1251";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "204";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Индекс";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Клас" : "клас"));
+ if (!singular) result+="e"; else result+="a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Датотек" : "датотек"));
+ if (!singular) result+="e"; else result+="a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Простор" : "простор"));
+ if (!singular) result+="и имена"; else result+=" имена";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Груп" : "груп"));
+ if (!singular) result+="е"; else result+="a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Страниц" : "страниц"));
+ if (!singular) result+="е"; else result += "a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Члан" : "члан"));
+ if (!singular) result+="ови";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Глобалн" : "глобалн"));
+ if (!singular) result+="а"; else result+="о";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Аутор" : "аутор"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Референце";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Имплементира "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Имплементирано у "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Садржај";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Списак застарелог";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Догађаји";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Документација догажаја";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Типови пакета";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Функције пакета";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Статичке функције пакета";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Атрибути пакета";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Статички атрибути пакета";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Све";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Овде је граф позивања за ову функцију:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Резултати претраге";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Жао ми је, али нема докумената који одговарају упиту.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Пронађен <b>1</b> документ који одговара упиту.";
+ }
+ else if (numDocuments==2)
+ {
+ return "Пронађена <b>а</b> документа која одговарају упиту.";
+ }
+ else if (numDocuments==3)
+ {
+ return "Пронађена <b>3</b> документа која одговарају упиту.";
+ }
+ else if (numDocuments==4)
+ {
+ return "Пронађена <b>4</b> документа која одговарају упиту.";
+ }
+ else
+ {
+ return "Пронађено <b>$num</b> докумената који одговарају упиту. "
+ "Приказују се прво најбољи поготци.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Поготци:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Изворна датотека";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Хијерархија директоријума"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Документација директоријума"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Директоријуми"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Ова хијерархија директоријума је уређена "
+ "приближно по абецеди:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Референца директоријума"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Директоријум" : "директоријум"));
+ if (singular) result+=""; else result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ово је преоптерећена функција чланица. "
+ "Разликује се од наведене само по врсти аргумената кое прихвата";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Ово је граф функција које позивају ову функцију:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Документација вредности набрајања"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Документацијаr функције чланице, односно потпрограма члана"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Списак типова података"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Поља"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Овде су типови података са кратким описима:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll)
+ {
+ result+="документованих ";
+ }
+ result+="чланова типова података";
+ result+=" са везама ка ";
+ if (!extractAll)
+ {
+ result+="документацији структуре података за сваки члан";
+ }
+ else
+ {
+ result+="типовима података којима припадају:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Индекс типова података"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Документација типова података"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Функције/потпрограми"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Документација функције/потпрограма"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Типови података"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Списак модула"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+ result+="модула са кратким описима:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate) result+=" Шаблон";
+ result+=" Референца";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" модула"; break;
+ case ClassDef::Struct: result+=" типа"; break;
+ case ClassDef::Union: result+=" уније"; break;
+ case ClassDef::Interface: result+=" интерфејса"; break;
+ case ClassDef::Protocol: result+=" протокола"; break;
+ case ClassDef::Category: result+=" категорије"; break;
+ case ClassDef::Exception: result+=" изузетка"; break;
+ default: break;
+ }
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Референца модула";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Чланови модула"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Овде је списак свих ";
+ if (!extractAll) result+="документованих ";
+ result+="чланова модула са везама ка ";
+ if (extractAll)
+ {
+ result+="документацији модула за сваки члан:";
+ }
+ else
+ {
+ result+="модулима којима припадају:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Индекс модула"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Модул" : "модул"));
+ if (!singular) result+="и";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документација за ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="овај модул"; break;
+ case ClassDef::Struct: result+="овај тип"; break;
+ case ClassDef::Union: result+="ову унију"; break;
+ case ClassDef::Interface: result+="овај интерфејс"; break;
+ case ClassDef::Protocol: result+="овај протокол"; break;
+ case ClassDef::Category: result+="ову категорију"; break;
+ case ClassDef::Exception: result+="овај изузетак"; break;
+ default: break;
+ }
+ result+=" је направљен из следећ";
+ if (single) result+="е датотеке:"; else result+="их датотека:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Тип" : "тип"));
+ if (!singular) result+="ови";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Потпрограм" : "потпрограм"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Ограничења типова";
+ }
+
+};
+
+#endif
diff --git a/src/translator_si.h b/src/translator_si.h
new file mode 100644
index 0000000..33bc27a
--- /dev/null
+++ b/src/translator_si.h
@@ -0,0 +1,1212 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+// translation by Matjaz Ostroversnik <matjaz.ostroversnik at zrs-tk.si>
+
+#ifndef TRANSLATOR_SI_H
+#define TRANSLATOR_SI_H
+
+
+class TranslatorSlovene : public TranslatorAdapter_1_4_6
+{
+ protected:
+ friend class TranslatorAdapterBase;
+ virtual ~TranslatorSlovene() {}
+ public:
+ QCString idLanguage()
+ { return "slovene"; }
+ /*! Used to get the command(s) for the language support. This method
+ * was designed for languages which do not prefer babel package.
+ * If this methods returns empty string, then the latexBabelPackage()
+ * method is used to generate the command for using the babel package.
+ */
+ QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[slovene]{babel}\n\\usepackage[T1]{fontenc}\n";
+ }
+ QCString trRelatedFunctions()
+ { return "Povezane funkcije"; }
+ QCString trRelatedSubscript()
+ { return "(To niso metode.)"; }
+ QCString trDetailedDescription()
+ { return "Podroben opis"; }
+ QCString trMemberTypedefDocumentation()
+ { return "Opis uporabniško definiranih tipov"; }
+ QCString trMemberEnumerationDocumentation()
+ { return "Opis komponent naštevnih tipov"; }
+/* QCString trEnumerationValueDocumentation() */
+/* { return "Opis vrednosti naštevnih tipov (enum) "; } */
+ QCString trMemberFunctionDocumentation()
+ { return "Opis metod"; }
+ QCString trMemberDataDocumentation()
+ { return "Opis atributov"; }
+ QCString trMore()
+ { return "..."; }
+ QCString trListOfAllMembers()
+ { return "Seznam vseh metod / atributov"; }
+ QCString trMemberList()
+ { return " - seznam metod in atributov."; }
+ QCString trThisIsTheListOfAllMembers()
+ { return "Seznam metod razreda "; }
+ QCString trIncludingInheritedMembers()
+ { return ", vključujoč dedovane metode in atribute."; }
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result="zgenerirano z Doxygen-om";
+ if (s) result+=(QCString)" za "+s;
+ result+=" iz izvorne kode.";
+ return result;
+ }
+ QCString trEnumName()
+ { return "naštevno ime"; }
+ QCString trEnumValue()
+ { return "naštevna vrednost"; }
+ QCString trDefinedIn()
+ { return "definirano v"; }
+ QCString trModules()
+ { return "moduli"; }
+ QCString trClassHierarchy()
+ { return "dedovalna hierarhija"; }
+ QCString trCompoundList()
+ { return "kratek opis razredov"; }
+ QCString trFileList()
+ { return "seznam datotek"; }
+/* QCString trHeaderFiles() */
+/* { return "'Header' datoteka"; } */
+ QCString trCompoundMembers()
+ { return "metode in atributi"; }
+ QCString trFileMembers()
+ { return "komponente v datotekah"; }
+ QCString trRelatedPages()
+ { return "dodatni opisi"; }
+ QCString trExamples()
+ { return "Primeri"; }
+ QCString trSearch()
+ { return "Išči"; }
+ QCString trClassHierarchyDescription()
+ { return "Hierarhično drevo je (okvirno) sortirano po abecedi. ";
+ }
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Seznam vseh ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="datotek s kratkim opisom:";
+ return result;
+ }
+ QCString trCompoundListDescription()
+ { return "Seznam razredov, množic in struktur "
+ "s kratkim opisom :";
+ }
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Seznam vseh ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="metod in atributov s povezavami na ";
+ if (extractAll) result+="opis posamezne metode in/ali atributa:";
+ else result+="opis razreda :";
+ return result;
+ }
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Seznam ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="entitet v datotekah ";
+ if (extractAll) result+="skupaj z opisom datoteke v kateri se nahajajo:";
+ else result+="s povezavami na datoteke v katerih se nahajajo:";
+ return result;
+ }
+/* QCString trHeaderFilesDescription() */
+/* { return "Seznam header datotek, ki tvorijo aplikacijski vmesnik (API) :"; } */
+ QCString trExamplesDescription()
+ { return "Seznam primerov :"; }
+ QCString trRelatedPagesDescription()
+ { return "Seznam strani z dodatnimi opisi:"; }
+ QCString trModulesDescription()
+ { return "Seznam modulov:"; }
+/* QCString trNoDescriptionAvailable() */
+/* { return "Opis ni dostopen"; } */
+
+ QCString trDocumentation()
+ { return "Dokumentacija"; }
+ QCString trModuleIndex()
+ { return "seznam modulov"; }
+ QCString trHierarchicalIndex()
+ { return "Hierarhični indeks"; }
+ QCString trCompoundIndex()
+ { return "abecedni seznam"; }
+ QCString trFileIndex()
+ { return "seznam datotek"; }
+ QCString trModuleDocumentation()
+ { return "Dokumentacija modulov"; }
+ QCString trClassDocumentation()
+ { return "Opis razreda"; }
+ QCString trFileDocumentation()
+ { return "Opis datoteke"; }
+ QCString trExampleDocumentation()
+ { return "Opis primera"; }
+ QCString trPageDocumentation()
+ { return "Opis povezanih strani"; }
+ QCString trReferenceManual()
+ { return "Priročnik"; }
+
+ QCString trDefines()
+ { return "Makro deklaracije"; }
+ QCString trTypedefs()
+ { return "Uporabniško definirani tipi"; }
+ QCString trEnumerations()
+ { return "Naštevni tipi"; }
+ QCString trFunctions()
+ { return "Funkcije"; }
+ QCString trVariables()
+ { return "Spremenljivke"; }
+ QCString trEnumerationValues()
+ { return "Vrednosti naštevnih tipov"; }
+ QCString trDefineDocumentation()
+ { return "Opis makro definicije"; }
+ QCString trTypedefDocumentation()
+ { return "Opis uporabniško definiranega tipa"; }
+ QCString trEnumerationTypeDocumentation()
+ { return "Opis naštevnega (enum) tipa"; }
+ QCString trFunctionDocumentation()
+ { return "Opis funkcije"; }
+ QCString trVariableDocumentation()
+ { return "Opis spremenljivke"; }
+ QCString trCompounds()
+ { return "Strukture"; }
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generirano "+date;
+ if (projName) result+=(QCString)" projekt: "+projName;
+ result+=(QCString)" generator: ";
+ return result;
+ }
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagram razredov za "+clName;
+ }
+ QCString trForInternalUseOnly()
+ { return "Samo za interno uporabo."; }
+/* QCString trReimplementedForInternalReasons() */
+/* { return "Ponovno implementirano zaradi internih razlogov. " */
+/* "Nima vpliva na API."; */
+/* } */
+ QCString trWarning()
+ { return "Opozorilo"; }
+/* QCString trBugsAndLimitations() */
+/* { return "Napake in omejtive"; } */
+ QCString trVersion()
+ { return "Verzija"; }
+ QCString trDate()
+ { return "Datum"; }
+ QCString trReturns()
+ { return "Rezultat(i)"; }
+ QCString trSeeAlso()
+ { return "Glej"; }
+ QCString trParameters()
+ { return "Parametri"; }
+ QCString trExceptions()
+ { return "Prekinitve"; }
+ QCString trGeneratedBy()
+ { return "Izdelano s pomočjo"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNamespaceList()
+ { return "imenski prostori"; }
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Seznam ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="imenskih prostorov z opisom:";
+ return result;
+ }
+ QCString trFriends()
+ { return "Prijatelji (Friends) "; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trRelatedFunctionDocumentation()
+ { return "Podatki o poveznih funkcijah"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool /*isTemplate*/)
+ // used as the title of the HTML page of a class/struct/union
+ {
+ QCString result="";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Razred "; break;
+ case ClassDef::Struct: result+=" Struktura "; break;
+ case ClassDef::Union: result+=" Množica "; break;
+ case ClassDef::Interface: result+=" IDL vmesnik "; break;
+ case ClassDef::Protocol: result+=" protocol "; break; // translate me!
+ case ClassDef::Category: result+=" category "; break; // translate me!
+ case ClassDef::Exception: result+=" IDL prekinitev "; break;
+ default: break;
+ }
+ result += (QCString)clName;
+
+ return result;
+ }
+ QCString trFileReference(const char *fileName)
+ // used as the title of the HTML page of a file
+ {
+ QCString result="Datoteka ";
+ result+=fileName;
+ return result;
+ }
+ QCString trNamespaceReference(const char *namespaceName)
+ // used as the title of the HTML page of a namespace
+ {
+ QCString result ="Imenski prostor ";
+ result+=namespaceName;
+
+ return result;
+ }
+
+ // these are for the member sections of a class, struct or union
+ QCString trPublicMembers()
+ { return "Javne metode"; }
+ QCString trPublicSlots()
+ { return "Public slotovi"; }
+ QCString trSignals()
+ { return "Programske prekinitve"; }
+ QCString trStaticPublicMembers()
+ { return "Statične javne metode in atributi"; }
+ QCString trProtectedMembers()
+ { return "Zaščitene metode in atributi"; }
+ QCString trProtectedSlots()
+ { return "Zaščiteni sloti"; }
+ QCString trStaticProtectedMembers()
+ { return "Statične zaščitene metode in atributi"; }
+ QCString trPrivateMembers()
+ { return "Skrite metode in atributi"; }
+ QCString trPrivateSlots()
+ { return "Skriti slotovi"; }
+ QCString trStaticPrivateMembers()
+ { return "Statične skrite metode in atributi"; }
+ // end of member sections
+
+ QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" in ";
+ }
+ }
+ return result;
+ }
+
+ QCString trInheritsList(int numEntries)
+ // used in class documentation to produce a list of base classes,
+ // if class diagrams are disabled.
+ {
+ return "Deduje od "+trWriteList(numEntries)+".";
+ }
+ QCString trInheritedByList(int numEntries)
+ // used in class documentation to produce a list of super classes,
+ // if class diagrams are disabled.
+ {
+ return "Naslijeðena u "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedFromList(int numEntries)
+ // used in member documentation blocks to produce a list of
+ // members that are hidden by this one.
+ {
+ return "Skrije implementacijo iz "+trWriteList(numEntries)+".";
+ }
+ QCString trReimplementedInList(int numEntries)
+ {
+ // used in member documentation blocks to produce a list of
+ // all member that overwrite the implementation of this member.
+ return "Metodo skrijejo implementacije v razredih "+trWriteList(numEntries)+".";
+ }
+
+ QCString trNamespaceMembers()
+ // This is put above each page as a link to all members of namespaces.
+ { return "elementi imenskega prostora"; }
+ QCString trNamespaceMemberDescription(bool extractAll)
+ // This is an introduction to the page with all namespace members
+ {
+ QCString result="Seznam vseh ";
+ if (!extractAll) result+="dokumentiranih ";
+ result+="elementov imenskega prostora s povezavami na ";
+ if (extractAll)
+ result+="opis vsakega elementa:";
+ else
+ result+="imenski prostor, ki mu pripadajo:";
+ return result;
+ }
+ QCString trNamespaceIndex()
+ // This is used in LaTeX as the title of the chapter with the
+ // index of all namespaces.
+ { return "Indeks imenskih prostorov"; }
+ QCString trNamespaceDocumentation()
+ // This is used in LaTeX as the title of the chapter containing
+ // the documentation of all namespaces.
+ { return "Podatki o imenskih prostorih"; }
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Imenski prostori"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Opis ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="razreda"; break;
+ case ClassDef::Struct: result+="strukture"; break;
+ case ClassDef::Union: result+="unije"; break;
+ case ClassDef::Interface: result+="vmesnika (interface)"; break;
+ case ClassDef::Protocol: result+="protocol"; break; // translate me!
+ case ClassDef::Category: result+="category"; break; // translate me!
+ case ClassDef::Exception: result+="prekinitve (exception)"; break;
+ default: break;
+ }
+ result+=" je zgrajen na podlagi naslednj";
+ if (single) result+="e "; else result+="ih";
+ result+=" datotek";
+ if (single) result+="e :"; else result+=" :";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "Povratna vrednost"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "prva stran"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "str."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+/* QCString trSources() */
+/* { */
+/* return "Izvorne datoteke"; */
+/* } */
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definirano v @0 vrstici datoteke @1.";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "Definirano v datoteki @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Zastarelo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Kolaboracijski diagram razreda "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graf prikazuje seznam datotek, "
+ "ki jih datoteka \""+fName+"\" "
+ "direktno ali indirektno vključuje. Pravokotniki ponazarjajo datoteke, puščice "
+ "predstavljajo relacije med njimi. "
+ "črn pravokotnik ponazarja datoteko "+fName+". Puščice A->B ponazarjajo "
+ "usmerjeno relacijo \"A vključuje B\"."
+;
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "Opis konstruktorjev in destruktorjev ";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "izvorna koda";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "dokumenacija tekoče datoteke.";
+ }
+ /*! Text for the \pre command */
+ QCString trPrecondition()
+ {
+ return "Predpogoji (preconditions)";
+ }
+ /*! Text for the \post command */
+ QCString trPostcondition()
+ {
+ return "Naknadni pogoji (posconditions)";
+ }
+ /*! Text for the \invariant command */
+ QCString trInvariant()
+ {
+ return "Invarianta";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "Začetna vrednost / definicija :";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "koda";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Hierarhija razredov v grafični obliki";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "Dedovalna hierarhija v grafični obliki";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "Dedovalna hierarhija v tekstovni obliki";
+ }
+ QCString trPageIndex()
+ {
+ return "Indeks strani";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "Opomba";
+ }
+ QCString trPublicTypes()
+ {
+ return "Javni tipi";
+ }
+ QCString trPublicAttribs()
+ {
+ return "Javni atributi";
+ }
+ QCString trStaticPublicAttribs()
+ {
+ return "Statični javni atributi";
+ }
+ QCString trProtectedTypes()
+ {
+ return "Zaščiteni tipi";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "Zaščiteni atributi";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "Statični zaščiteni tipi";
+ }
+ QCString trPrivateTypes()
+ {
+ return "Skriti tipi";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "Skriti atributi";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "Statični skriti atributi";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "TODO";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Seznam nedokončanih opravil";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Uporabniki entitete: ";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Opomba";
+ }
+ virtual QCString trAttention()
+ {
+ return "Pozor";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Graf prikazuje datoteke, ki posredno ali neposredno "
+ "vključujejo tekočo datoteko. Pravokotniki simbolizirajo datoteke, "
+ "puščice pa relacije med datotekami. Tekoča datoteka je prikazana "
+ "kot pravokotnik s črno podlago, ostale pa kot pravokotnik brez podlage. "
+ "Smer puščice A->B definira relacijo \"A vključuje B\". "
+ "Vse datoteke, ki torej mejijo na tekočo (t.j. obstaja povezava med črnim in "
+ "praznim pravokotnikom), jo direktno vključujejo, medtem, ko jo ostale vključujejo "
+ "le posredno. "
+ ;
+ }
+ virtual QCString trSince()
+ {
+ return "Od";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Legenda grafa";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Tekoča stran pojasnjuje način interpretacije grafov, ki jih izriše "
+ "doxygen.<p>\n"
+ "Poglejmo si naslednji primer:\n"
+ "\\code\n"
+ "/*! Nevide razred zaradi rezanja */\n"
+ "class Invisible { };\n\n"
+ "/*! Odrezan razred, dedovalna relacija je skrita */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* razred, ki ni opisan z doxygen komentarji */\n"
+ "class Undocumented { };\n\n"
+ "/*! Razred, ki ga dedujemo s pomočjo javnega dedovanja */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Razred, ki ga dedujemo s pomočjo zaščitenega dedovanja */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Razred, ki ga dedujemo s pomočjo skritega dedovanja */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Razred, ki ga uporablja dedovani razred */\n"
+ "class Used { };\n\n"
+ "/*! Super class that inherits a number of other classes */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "If the \\c MAX_DOT_GRAPH_HEIGHT tag in the configuration file "
+ "is set to 200 this will result in the following graph:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "The boxes in the above graph have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A filled black box represents the struct or class for which the "
+ "graph is generated.\n"
+ "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>%A box with a red border denotes a documented struct or class for\n"
+ "which not all inheritance/containment relations are shown. %A graph is "
+ "truncated if it does not fit within the specified boundaries."
+ "</ul>\n"
+ "The arrows have the following meaning:\n"
+ "<ul>\n"
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
+ "relation between two classes.\n"
+ "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
+ "by another class. The arrow is labeled with the variable(s) "
+ "through which the pointed class or struct is accessible. \n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "legenda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test List";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "IDL Lastnosti";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Opis IDL lastnosti";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java interfaces in the summary section of Java packages */
+/* virtual QCString trInterfaces() */
+/* { */
+/* return "Vmesniki"; */
+/* } */
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Podatkovne strukture";
+ }
+ else
+ {
+ return "Razredi";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"JAVA paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Seznam JAVA paketov";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Seznam JAVA paketov in njihovih kratkih opisov v primeru, da obstajajo:";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "JAVA paketi";
+ }
+ /*! Used as a chapter title for Latex & RTF output */
+/* virtual QCString trPackageDocumentation() */
+/* { */
+/* return "Opisi JAVA paketov"; */
+/* } */
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Vrednost:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Programska napaka";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Seznam programskih napak";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1250";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Razred" : "razred"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Datotek" : "datotek"));
+ if (!singular) result+="e";
+ else result += "a";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Imenski prostor" : "imenski prostor"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Skupina" : "skupina"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stran" : "stran"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Element" : "element"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+/* virtual QCString trField(bool first_capital, bool singular) */
+/* { */
+/* QCString result((first_capital ? "Polj" : "polj")); */
+/* if (!singular) result+="a"; */
+/* else result += "e"; */
+/* return result; */
+/* } */
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Avtor" : "avtor"));
+ if (!singular) result+="ji";
+ return result;
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Reference";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementira "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementirano v "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Vsebina";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Seznam opuščenih";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Dogodki";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Opisi dogodkov";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipi paketov";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkcije paketa"; /* don't know the context */
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statične funkcije paketa";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributi paketa";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statični atributi paketa";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Vse";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Graf klicev tekoče funkcije:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Rezultat(i) iskanja";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Oprostite, noben dokument ne ustreza vašemu povpraševanju.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Našel sem <b>1</b> dokument, ki ustreza vašemu povpraševanju.";
+ }
+ else if (numDocuments==2)
+ {
+ return "Našel sem <b>2</b> dokumenta, ki ustrezata vašemu povpraševanju.";
+ }
+ else
+ {
+ return "Našel sem <b>$num</b> dokumentov, ki ustrezajo vašemu povpraševanju. "
+ "Dokumenti z najboljšo stopnjo ujemanja se nahajajo na začetku.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Zadetki:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " izvorna koda";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarhija imenikov"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Opisi imenikov"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Imeniki"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Imeniška hierarhija je urejena v glavnem, toda ne popolnoma, po abecedi, ";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName;
+ result+=" imeniške reference"; /* not sure for context */
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Imenik" : "imenik"));
+ if (singular) result+="i"; else result+="";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "To je ponovno definirana metoda, " /* don't know Slovene expresion for overloaded */
+ "podana je zaradi priročnosti. Metoda se od predhodnje razlikuje "
+ "samo v številu in/ali tipu formalnih argumentov.";
+ }
+};
+
+#endif
diff --git a/src/translator_sk.h b/src/translator_sk.h
new file mode 100644
index 0000000..0fc826b
--- /dev/null
+++ b/src/translator_sk.h
@@ -0,0 +1,1971 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * ----------------------------------------------------------------------------*/
+
+// Updates:
+// --------
+// 2013/05/14 - Updates for "new since 1.8.4".
+// 2012/08/02 - Updates for "new since 1.8.2".
+// 2012/04/18 - Updates for "new since 1.8.0".
+// 2011/07/28 - Updates for "new since 1.7.5".
+// 2010/06/04 - big leap from 1.2.18 to 1.6.3+
+//
+// Slovak translation started by Stanislav Kudlac (skudlac at pobox dot sk).
+// He resigned in March 2008 (thanks for the work). Until a "native Slovak"
+// maintainer is found, the TranslatorSlovak is maintained by Petr Prikryl with
+// Slovak speaking Kali and Laco Švec.
+// ----------------------------------------------------------------------------
+
+#ifndef TRANSLATOR_SK_H
+#define TRANSLATOR_SK_H
+
+class TranslatorSlovak : public Translator
+{
+ public:
+ // --- Language control methods -------------------
+
+ virtual QCString idLanguage()
+ { return "slovak"; }
+
+ virtual QCString latexLanguageSupportCommand()
+ { return "\\usepackage[slovak]{babel}\n"; }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Súvisiace funkcie"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Uvedené funkcie niesú členskými funkciami.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detailný popis"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentácia k členským typom"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentácia k členským enumeráciám"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentácia k metódam"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentácia k položkám";
+ }
+ else
+ {
+ return "Dokumentácia k dátovým členom";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Zoznam všetkých členov"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Zoznam členov triedy"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Tu nájdete úplný zoznam členov triedy "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", vrátane všetkých zdedených členov."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result("Generované automaticky programom Doxygen "
+ "zo zdrojových textov");
+ if (s)
+ result+=(QCString)" projektu "+s;
+ result+=".";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "meno enumerácie"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "hodnota enumerácie"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definovaný v"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduly"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hierarchia tried"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dátové štruktúry";
+ }
+ else
+ {
+ return "Zoznam tried";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Zoznam súborov"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dátové položky";
+ }
+ else
+ {
+ return "Zoznam členov tried";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globálne symboly";
+ }
+ else
+ {
+ return "Symboly v súboroch";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Ostatné stránky"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Príklady"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Hľadať"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Tu nájdete zoznam, vyjadrujúci vzťah dedičnosti tried. "
+ "Je zoradený približne (ale nie úplne) podľa abecedy:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result("Tu nájdete zoznam všetkých ");
+ if (!extractAll) result+="dokumentovaných ";
+ result+="súborov so stručnými popismi:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Nasledujúci zoznam obsahuje identifikáciu dátových "
+ "štruktúr a ich stručné popisy:";
+ }
+ else
+ {
+ return "Nasledujúci zoznam obsahuje predovšetkým identifikáciu "
+ "tried, ale nachádzajú sa tu i ďalšie netriviálne prvky, "
+ "ako sú štruktúry (struct), uniony (union) a rozhrania "
+ "(interface). V zozname sú uvedené ich stručné "
+ "popisy:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result= "Tu nájdete zoznam všetkých ";
+ if (!extractAll)
+ {
+ result += "dokumentovaných ";
+ }
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result += "položiek štruktúr (struct) a unionov (union) ";
+ }
+ else
+ {
+ result += "členov tried ";
+ }
+
+ result += "s odkazmi na ";
+
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result += "dokumentáciu štruktúr/unionov, ku ktorým prislúchajú:";
+ }
+ else
+ {
+ result += "dokumentáciu tried, ku ktorým prislúchajú:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="štruktúry/uniony, ku ktorým prislúchajú:";
+ }
+ else
+ {
+ result+="triedy, ku ktorým prislúchajú:";
+ }
+ }
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Tu nájdete zoznam všetkých ";
+ if (!extractAll) result+="dokumentovaných ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcií, premenných, makier, enumerácií a definícií typov (typedef) "
+ "s odkazmi na ";
+ }
+ else
+ {
+ result+="symbolov, ktoré sú definované na úrovni svojich súborov. "
+ "Pre každý symbol je uvedený odkaz na ";
+ }
+
+ if (extractAll)
+ result+="súbory, ku ktorým prislúchajú:";
+ else
+ result+="dokumentáciu:";
+
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Tu nájdete zoznam všetkých príkladov:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Nasledujúci zoznam odkazuje na ďalšie stránky projektu, "
+ "ktoré majú charakter usporiadaných zoznamov informácií, "
+ "pozbieraných z rôznych miest v zdrojových súboroch:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Tu nájdete zoznam všetkých modulov:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentácia"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Register modulov"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Register hierarchie tried"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Register dátových štruktúr";
+ }
+ else
+ {
+ return "Register tried";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Register súborov"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Dokumentácia modulov"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ { return "Dokumentácia tried"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dokumentácia súborov"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentácia príkladov"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Dokumentácia súvisiacich stránok"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referenčná príručka"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definícia makier"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definícia typov"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerácie"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkcie"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Premenné"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Hodnoty enumerácií"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Dokumentácia k definíciám makier"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentácia definícií typov"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentácia enumeračných typov"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentácia funkcií"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Dokumentácia premenných"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dátové štruktúry";
+ }
+ else
+ {
+ return "Triedy";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generované "+date;
+ if (projName) result+=(QCString)" pre projekt "+projName;
+ result+=(QCString)" programom";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Diagram dedičnosti pre triedu "+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Iba pre interné použitie."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Pozor"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Verzia"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Dátum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Návratová hodnota"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Viz tiež"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametre"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Výnimky"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Generované programom"; }
+
+ // new since 0.49-990307
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Zoznam priestorov mien"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Tu nájdete zoznam všetkých ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="priestorov mien so stručným popisom:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Priatelia (friends)"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentácia k priateľom (friends)"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result("Dokumentácia ");
+ if (isTemplate) result+="šablóny ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="triedy "; break;
+ case ClassDef::Struct: result+="štruktúry "; break;
+ case ClassDef::Union: result+="unionu "; break;
+ case ClassDef::Interface: result+="rozhrania "; break;
+ case ClassDef::Protocol: result+="protokol "; break;
+ case ClassDef::Category: result+="kategória "; break;
+ case ClassDef::Exception: result+="výnimky "; break;
+ default: break;
+ }
+ result+=clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result("Dokumentácia súboru ");
+ result+=fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result("Dokumentácia priestoru mien ");
+ result+=namespaceName;
+ return result;
+ }
+
+ /* these are for the member sections of a class, struct or union */
+ virtual QCString trPublicMembers()
+ { return "Verejné metódy"; }
+ virtual QCString trPublicSlots()
+ { return "Verejné sloty"; }
+ virtual QCString trSignals()
+ { return "Signály"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statické verejné metódy"; }
+ virtual QCString trProtectedMembers()
+ { return "Chránené metódy"; }
+ virtual QCString trProtectedSlots()
+ { return "Chránené sloty"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statické chránené metódy"; }
+ virtual QCString trPrivateMembers()
+ { return "Privátne metódy"; }
+ virtual QCString trPrivateSlots()
+ { return "Privátne sloty"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statické privátne metódy"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" a ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ QCString result("Dedí od ");
+ result += (numEntries == 1) ? "bázovej triedy " : "bázových tried ";
+ result += trWriteList(numEntries)+".";
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ QCString result("Zdedená ");
+ result += (numEntries == 1) ? "triedou " : "triedami ";
+ result += trWriteList(numEntries)+".";
+ return result;
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ QCString result("Reimplementuje ");
+ result += (numEntries == 1) ? "metódu triedy " : "metódy tried ";
+ result += trWriteList(numEntries)+".";
+ return result;
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ QCString result("Reimplementované ");
+ result += (numEntries == 1) ? "triedou " : "triedami ";
+ result += trWriteList(numEntries)+".";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Symboly v priestoroch mien"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Tu nájdete zoznam všetkých ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="symbolov, ktoré sú definované vo svojich priestoroch mien. "
+ "U každého je uvedený odkaz na ";
+ if (extractAll)
+ result+="dokumentáciu príslušného priestoru mien:";
+ else
+ result+="príslušný priestor mien:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Register priestorov mien"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Dokumentácia priestorov mien"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Priestory mien"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentácia pre ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="túto triedu"; break;
+ case ClassDef::Struct: result+="túto štruktúru (struct)"; break;
+ case ClassDef::Union: result+="tento union"; break;
+ case ClassDef::Interface: result+="toto rozhranie"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategória"; break;
+ case ClassDef::Exception: result+="túto výnimku"; break;
+ default: break;
+ }
+ result+=" bola generovaná z ";
+ if (single) result+="nasledujúceho súboru:";
+ else result+="nasledujúcich súborov:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Návratové hodnoty"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hlavná stránka"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definícia je uvedená na riadku @0 v súbore @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definícia v súbore @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Zastaralé";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Diagram tried pre "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graf závislostí na vkladaných súboroch "
+ "pre "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentácia konštruktoru a deštruktoru";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Zobraziť zdrojový text tohoto súboru.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Zobraziť dokumentáciu tohoto súboru.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Prepodmienka";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postpodmienka";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Inicializátor:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "zdrojový text";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafické zobrazenie hierarchie tried";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Zobraziť grafickú podobu hierarchie tried";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Zobraziť textovú podobu hierarchie tried";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Register stránok";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Poznámka";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Verejné typy";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dátové položky";
+ }
+ else
+ {
+ return "Verejné atribúty";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statické verejné atribúty";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Chránené typy";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Chránené atribúty";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statické chránené atribúty";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privátne typy";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privátne atribúty";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statické privátne atribúty";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Plánované úpravy";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Zoznam plánovaných úprav";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Používa sa v";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Poznámky";
+ }
+ virtual QCString trAttention()
+ {
+ return "Upozornenie";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Nasledujúci graf ukazuje, ktoré súbory priamo alebo "
+ "nepriamo vkladajú tento súbor:";
+ }
+ virtual QCString trSince()
+ {
+ return "Od";
+ }
+
+////////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Vysvetlivky ku grafu";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Tu nájdete vysvetlenie, ako majú byť interpretované grafy, "
+ "ktoré boli generované programom doxygen.<p>\n"
+ "Uvažujte nasledujúci príklad:\n"
+ "\\code\n"
+ "/*! Neviditelná trieda, ktorá sa v grafe nezobrazuje, pretože "
+ "došlo k orezaniu grafu. */\n"
+ "class Invisible { };\n\n"
+ "/*! Trieda, u ktorej došlo k orezaniu grafu. Vzťah dedičnosti "
+ "je skrytý. */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Trieda, ktorá nieje dokumentovaná komentármi programu doxygen. */\n"
+ "class Undocumented { };\n\n"
+ "/*! Odvodená trieda s verejným (public) dedením bázovej triedy. */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Šablóna triedy. */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Odvodená trieda s chráneným (protected) dedením bázovej triedy. */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Odvodená trieda s privátnym dedením bázovej triedy. */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Trieda, ktorá je využívaná triedou Inherited. */\n"
+ "class Used { };\n\n"
+ "/*! Odvodená trieda, ktorá rôznym spôsobom dedí od viacerých bázových "
+ "tried. */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "K vyššie uvedenému bude vygenerovaný nasledujúci graf:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Bloky (tj. uzly) v uvedenom grafe majú nasledujúci význam:\n"
+ "<ul>\n"
+ "<li>Čierne vyplnený obdĺžnik reprezentuje štruktúru alebo triedu, "
+ "pre ktorú bol graf generovaný.\n"
+ "<li>Obdĺžnik s čiernym obrysom označuje dokumentovanú "
+ "štruktúru alebo triedu.\n"
+ "<li>Obdĺžnik so šedým obrysom označuje nedokumentovanú "
+ "štruktúru alebo triedu.\n"
+ "<li>Obdĺžnik s červeným obrysom označuje dokumentovanú "
+ "štruktúru alebo triedu, pre ktorú\n"
+ "niesú zobrazené všetky vzťahy dedičnosti alebo obsiahnutia. "
+ "Graf je orezaný v prípade, kedy ho\n"
+ "nieje možné umiestniť do vymedzených hraníc.\n"
+ "</ul>\n"
+ "Šípky (tj. hrany grafu) majú nasledujúcí význam:\n"
+ "<ul>\n"
+ "<li>Tmavo modrá šípka sa používa pre označenie vzťahu verejnej "
+ "dedičnosti medzi dvoma triedami.\n"
+ "<li>Tmavo zelená šípka označuje vzťah chránenej dedičnosti "
+ "(protected).\n"
+ "<li>Tmavo červená šípka označuje vzťah privátnej dedičnosti.\n"
+ "<li>Purpurová šípka kreslená čiarkovane sa používa v prípade, "
+ "ak je trieda obsiahnutá v inej triede,\n"
+ "alebo ak je používaná inou triedou. Je označená identifikátorom "
+ "jednej alebo viacerých premenných (objektov), cez ktoré\n"
+ "je trieda alebo štruktúra zprístupnena.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "vysvetlivky";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Zoznam testov";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Vlastnosti";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentácia k vlastnosti";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ return "Triedy";
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Balík "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Zoznam balíkov";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Tu nájdete zoznam balíkov so stručným popisom "
+ "(pokiaľ bol uvedený):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Balíky";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Hodnota:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Chyba";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Zoznam chýb";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6-20010422
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1250";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tried" : "tried"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Súbor" : "súbor"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Priestor" : "priestor"));
+ if (!singular) result+="y";
+ result+=" mien";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Skupin" : "skupin"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stránk" : "stránk"));
+ result+=(singular ? "a" : "y");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Člen" : "člen"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globáln" : "globáln"));
+ result+=(singular ? "y" : "e");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auto" : "auto"));
+ result += (singular) ? "r" : "ri";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Odkazuje sa na";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementuje " + trWriteList(numEntries) + ".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementované v " + trWriteList(numEntries) + ".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Obsah";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Zastarané metódy";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Udalosti";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentácia udalostí";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Typy v balíku";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkcie v balíku";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statické funkcie v balíku";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atribúty balíku";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statické atribúty balíku";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Všetko";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Táto funkcia volá...";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Výsledky vyhľadávania";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Ľutujem. Vášmu dotazu neodpovedá žiadny dokument.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Bol nájdený jediný dokument, ktorý vyhovuje vášmu dotazu.";
+ }
+ else
+ {
+ return "Bolo nájdených <b>$num</b> dokumentov, ktoré vyhovujú vášmu "
+ "dotazu. Najviac odpovedajúce dokumenty sú ako prvé.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Nájdené slová:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return QCString("Zdrojový súbor ") + filename;
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hierarchia adresárov"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentácia k adresárom"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Adresáre"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ {
+ return "Následujúca hierarchia adresárov je zhruba, "
+ "ale nie úplne, zoradená podľa abecedy:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ {
+ QCString result = "Referencia k adresáru ";
+ result += dirName;
+ return result;
+ }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Adresár" : "adresár"));
+ if ( ! singular)
+ result += "e";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ide o preťaženú (overloaded) metódu, "
+ "ktorá má uľahčiť používanie. Od vyššie uvedenej metódy sa odlišuje "
+ "iba inak zadávanými argumentami.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCallerGraph()
+ { return "Túto funkciu volajú..."; }
+
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentácia enumeračných hodnôt"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentácia členských funkcií/podprogramov"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Zoznam dátových typov"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Dátové polia"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Dátové typy so stručnými popismi:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+
+ QCString result="Nasleduje zoznam všetkých ";
+ if (!extractAll)
+ {
+ result+="dokumentovaných ";
+ }
+ result+="zložiek dátových typov";
+ result+=" s odkazmi na ";
+ if (!extractAll)
+ {
+ result+="dokumentáciu dátovej štruktúry pre každú zložku:";
+ }
+ else
+ {
+ result+="příslušné dátové typy:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Register dátových typov"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentácia k dátovým typom"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcie/podprogramy"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Dokumentácia funkcie/podprogramu"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Dátové typy"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Zoznam modulov"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Nasleduje zoznam všetkých ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="modulov so stručnými popismi:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result("Dokumentácia ");
+ if (isTemplate) result += "šablóny ";
+ switch(compType)
+ {
+ case ClassDef::Class: result += "triedy "; break;
+ case ClassDef::Struct: result += "typu "; break;
+ case ClassDef::Union: result += "únie "; break;
+ case ClassDef::Interface: result += "rozhrania "; break;
+ case ClassDef::Protocol: result += "protokolu "; break;
+ case ClassDef::Category: result += "kategórie "; break;
+ case ClassDef::Exception: result += "výnimky "; break;
+ default: break;
+ }
+ result += clName;
+ return result;
+
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result="Dokumentácia modulu ";
+ result += namespaceName;
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Časti modulu"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Nasleduje zoznam všetkých ";
+ if (!extractAll) result+="dokumentovaných ";
+ result+="častí modulov s odkazmi ";
+ if (extractAll)
+ {
+ result+="na dokumentáciu modulov pre danú časť:";
+ }
+ else
+ {
+ result+="na moduly, ku ktorým časť patrí:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Register modulov"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentácia ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="k tomuto modulu"; break;
+ case ClassDef::Struct: result+="k tomuto typu"; break;
+ case ClassDef::Union: result+="k tejto únii"; break;
+ case ClassDef::Interface: result+="k tomuto rozhraniu"; break;
+ case ClassDef::Protocol: result+="k tomuto protokolu"; break;
+ case ClassDef::Category: result+="k tejto kategórii"; break;
+ case ClassDef::Exception: result+="k tejto výnimke"; break;
+ default: break;
+ }
+ result+=" bola vygenerovaná z ";
+ if (single) result+="nasledujúceho súboru:";
+ else result+="nasledujúcich súborov:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Typ" : "typ"));
+ if (!singular) result+="y";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Podprogram" : "podprogram"));
+ if (!singular) result+="y";
+ return result;
+ }
+
+ /*! C# Type Contraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Obmedzenie typov (Type Constraints)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Relácia " + QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Načítam...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globálny priestor mien";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Vyhľadávam...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Nič sa nenašlo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Súbor v "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Vkladá (include) súbor z "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "po","ut","st","št","pi","so","ne" };
+ static const char *months[] = { "jan","feb","mar","apr","máj","jún","júl","aug","sep","okt","nov","dec" };
+ QCString sdate;
+ sdate.sprintf("%s %d. %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d.%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Odkazy na literatúru"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Graf závislosti na priečinkoch pre ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "úroveň detailov"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Parametry šablón"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ {
+ QCString result("a " + number + " ďaľší");
+ if (atoi(number) >= 5)
+ result += "ch";
+ return result + "...";
+ }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumentácia pre tuto enumeráciu bola generovaná z ";
+ if (single)
+ result += "nasledujúceho súboru:";
+ else
+ result += "nasledujúcich súborov:";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return "Referencia k enumerácii "+QCString(name); }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" dedí sa z "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Ďaľšie zdedené členy"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "povoliť" : "zakázať";
+ return opt + " synchronizáciu panelov";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Deklarované v kategórii @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Rozširuje triedu @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Metódy triedy";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Metódy inštancie";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Dokumentácia metódy";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Návrhová schéma";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Exportované rozhrania"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Začlenené služby"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Konštantné skupiny"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result="Konštantné skupiny z ";
+ result += namespaceName;
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result="Popis služby ";
+ result += sName;
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result="Popis singletonu ";
+ result += sName;
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result="Dokumentácia k tejto službe bola vygenerovaná ";
+ if (single) result+="z nasledujúceho súboru:";
+ else result+="z nasledujúcich súborov:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result="Dokumentácia k tomuto singletonu bola vygenerovaná ";
+ if (single) result+="z nasledujúceho súboru:";
+ else result+="z nasledujúcich súborov:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+};
+
+#endif // TRANSLATOR_SK_H
diff --git a/src/translator_sr.h b/src/translator_sr.h
new file mode 100644
index 0000000..f58ac13
--- /dev/null
+++ b/src/translator_sr.h
@@ -0,0 +1,1774 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_SR_H
+#define TRANSLATOR_SR_H
+
+// translation by Dejan D. M. Milosavljevic <dmilos at email.com>;<dmilosx at ptt.yu>;<office at ddmrm.com>
+// // 10x 2 Ivana Miletic for grammatical consultation.
+
+// UTF-8 patch by Nenad Bulatovic <buletina at gmail.com>
+// translation update by Andrija M. Bosnjakovic <andrija at etf.bg.ac.yu>
+
+class TranslatorSerbian : public TranslatorAdapter_1_6_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "serbian"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ QCString result="\\usepackage[serbian]{babel}\n";
+ return result;
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ //! Čini se da je ovako manje loše nego "Povezane funkcije",
+ //! što uopšte ne izgleda dobro jer ta kartica sadrži prijatelje i globalne funkcije
+ { return "Relevantne funkcije"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(To nisu funkcije članice.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Opširniji opis"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentacija unutrašnjih definicija tipa"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ //! Ovo je u skladu sa "unutrašnja klasa" što se može videti u knjizi.
+ { return "Dokumentacija unutrašnjih nabrajanja"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentacija funkcija članica"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentacija polja";
+ }
+ else
+ {
+ return "Dokumentacija atributa";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Još..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Spisak svih članova"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Spisak članova"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Ovo je spisak svih članova "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", uključujući nasleđene članove."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Napravljeno automatski korišćenjem alata Doxygen";
+ if( s ) result+=(QCString)" za projekat " + s;
+ result+=" od izvornog koda.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "ime nabrajanja "; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "vrednost nabrojane konstante"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "definicija u"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Moduli"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Hijerarhija klasa"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Spisak struktura";
+ }
+ else
+ {
+ return "Spisak klasa";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Spisak datoteka"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Sva polja struktura";
+ }
+ else
+ {
+ return "Svi članovi klasa";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Članovi datoteke";
+ }
+ else
+ {
+ return "Članovi datoteke";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Stranice koje imaju veze sa ovom stranicom"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Primeri"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Traži"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Hijerahija klasa uređena približno po abecedi:"; }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+ result+="datoteka, sa kratkim opisima:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Spisak struktura sa kratkim opisima:";
+ }
+ else
+ {
+ return "Spisak klasa, struktura, unija i interfejsa sa kratkim opisima:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll)
+ {
+ result+="dokumentovanih ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="članova struktura/unija";
+ }
+ else
+ {
+ result+="članova klasa";
+ }
+ result+=" sa vezama ka ";
+ if (extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="dokumentaciji svakog polja strukture/unije:";
+ }
+ else
+ {
+ result+="dokumentaciji svakog člana klase:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="strukturama/unijama kojima pripadaju:";
+ }
+ else
+ {
+ result+="klasama kojima pripadaju:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funkcija, promenljivih, makro zamena, nabrajanja i definicija tipa";
+ }
+ else
+ {
+ result+="članova";
+ }
+ result+=" sa vezama ka ";
+ if (extractAll)
+ result+="datotekama u kojima se nalaze:";
+ else
+ result+="dokumentaciji:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Spisak svih primera:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Spisak stranica koje imaju veze sa ovom stranicom:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Spisak svih modula:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentacija"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Indeks modula"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hijerarhijski sadržaj"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Spisak struktura/unija";
+ }
+ else
+ {
+ return "Spisak klasa";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Indeks datoteka"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Dokumentacija modula"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentacija stuktura/unija";
+ }
+ else
+ {
+ return "Dokumentacija klasa";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dokumentacija datoteke"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentacija primera"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Dokumentacija stranice"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Priručnik"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makro zamene"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Definicije tipa"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Nabrajanja"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funkcije"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Promenljive"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Vrednosti nabrojanih konstanti"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Dokumentacija makro zamene"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentacija definicije tipa"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentacija nabrajanja"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentacija funkcije"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Dokumentacija promenljive"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Strukture i unije";
+ }
+ else
+ {
+ return "Klase, strukture i unije";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"[" + date + "] Napravljeno automatski ";
+ if ( projName ) result+=(QCString)" za projekat " + projName;
+ result+=(QCString)" upotrebom ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return QCString("Dijagram nasleđivanja za klasu ") + clName + ":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Samo za unutrašnju upotrebu."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Upozorenje"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Verzija"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Datum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Vrednost funkcije"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Takođe pogledati"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametri"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Izuzeci"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Napravio"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Spisak prostora imena"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+ result+="prostora imena sa kratkim opisom:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Prijatelji"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Dokumentacija prijatelja i relevantnih funkcija"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result( "Dokumentacija " );
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klase "; break;
+ case ClassDef::Struct: result+="strukture "; break;
+ case ClassDef::Union: result+="unije "; break;
+ case ClassDef::Interface: result+="interfejsa "; break;
+ case ClassDef::Protocol: result+="protokola "; break;
+ case ClassDef::Category: result+="kategorije "; break;
+ case ClassDef::Exception: result+="izuzetka "; break;
+ default: break;
+ }
+ if (isTemplate) result += "šablona ";
+ result += clName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result = "Opis datoteke ";
+ result += fileName;
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result="Opis prostora imena ";
+ result += namespaceName;
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Javni članovi"; }
+ virtual QCString trPublicSlots()
+ { return "Javni slotovi"; }
+ virtual QCString trSignals()
+ { return "Signali"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Zajednički javni članovi"; }
+ virtual QCString trProtectedMembers()
+ { return "Zaštićeni članovi"; }
+ virtual QCString trProtectedSlots()
+ { return "Zaštićeni slotovi"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Zajednički zaštićeni članovi"; }
+ virtual QCString trPrivateMembers()
+ { return "Privatni članovi"; }
+ virtual QCString trPrivateSlots()
+ { return "Privatni slotovi"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Zajednički privatni članovi"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" i ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int /*numEntries*/)
+ {
+ return "Spisak osnovnih klasa: ";
+ }
+
+ /*! used in class documentation to produce a list of derived classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int /*numEntries*/)
+ {
+ return "Spisak izvedenih klasa: ";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Menja definiciju iz "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ { //! Ako već ne možemo jednu reč (redefinicija), da uskladimo sa prethodnim i izbacimo upotrebu roda
+ return "Definicija je izmenjena u "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Članovi prostora imena"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+ result+="članova prostora imena sa vezama prema ";
+ if (extractAll)
+ result+="dokumentaciji svakog člana prostora imena: ";
+ else
+ result+="prostorima imena kojima pripadaju: ";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Indeks prostora imena"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Dokumentacija prostora imena"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Prostori imena"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacija ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="ove klase"; break;
+ case ClassDef::Struct: result+="ove strukture"; break;
+ case ClassDef::Union: result+="ove unije"; break;
+ case ClassDef::Interface: result+="ovog interfejsa"; break;
+ case ClassDef::Protocol: result+="ovog protokola"; break;
+ case ClassDef::Category: result+="ove kategorije"; break;
+ case ClassDef::Exception: result+="ovog izuzetka"; break;
+ default: break;
+ }
+ result+=" je napravljena na osnovu ";
+ if (single) result+="datoteke "; else result+="sledećih datoteka:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Karakteristične vrednosti funkcije"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Glavna strana"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "str."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ { //! Izbacujemo rod
+ return "Definicija je u redu @0 datoteke @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ { //! Izbacujemo rod
+ return "Definicija je u datoteci @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Zastarelo";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Klasni dijagram za "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Graf zavisnosti datoteka za "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentacija konstruktora i destruktora";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Izvorni kod.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Dokumentacija.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Preduslovi";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Stanje po izvršenju";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invarijanta";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Početna vrednost:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "programski kod";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Hijerarhija klasa u obliku grafa";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Prikaz hijerarhije klasa u obliku grafa";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Prikaz hijerarhije klasa u obliku nazubljenog teksta";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Indeks stranice";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Beleška";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Javni tipovi";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Polja";
+ }
+ else
+ {
+ return "Javni članovi";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Zajednički javni članovi";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Zaštićeni tipovi";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Zaštićeni članovi";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Zajednički zaštićeni članovi";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privatni tipovi";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privatni članovi";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Zajednički privatni članovi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Uraditi";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Spisak stvari koje treba uraditi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ { //! Izbegavanje roda. Uskladjivanje sa trReferences
+ return "Korisnici: ";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Napomene";
+ }
+ virtual QCString trAttention()
+ {
+ return "Pažnja";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Ovaj graf pokazuje koje datoteke direktno "
+ "ili indirektno uključuju ovu datoteku: ";
+ }
+ virtual QCString trSince()
+ {
+ return "Od";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Objašnjenje korišćenih simbola";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Ova stranica objašnjava kako tumačiti grafikone koje je napravio "
+ "doxygen.<p>\n"
+ "Na primer:\n"
+ "\\code\n"
+ "/*! Klasa nevidljiva zbog trenutnih ograničenja */\n"
+ "class Invisible { };\n\n"
+ "/*! Klasa kojoj se ne vidi način izvođenja */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klasa bez doxygen komentara */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klasa izvedena iz osnovne klase javnim izvođenjem */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Šablonska klasa */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klasa izvedena iz osnovne klase zaštićenim izvođenjem */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klasa izvedena iz osnovne klase privatnim izvođenjem */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klasa korišćena u nekoj/nekim od drugih klasa */\n"
+ "class Used { };\n\n"
+ "/*! Klasa izvedena iz više osnovnih klasa */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Ako je \\c MAX_DOT_GRAPH_HEIGHT tag u konfiguracionoj datoteci "
+ "postavljen na \\c 200 graf izvođenja će izgledati ovako:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "Graf će biti odsečen ako ne stane unutar zadatih granica.\n"
+ "<p>\n"
+ "Pravougaonici imaju sledeća značenja:\n"
+ "<ul>\n"
+ "<li>Puni sivi predstavlja strukturu ili klasu za koju je graf napravljen.\n"
+ "<li>Sa crnom ivicom predstavlja dokumentovanu strukturu ili klasu.\n"
+ "<li>Sa sivom ivicom predstavlja strukturu ili klasu bez doxygen komentara.\n"
+ "<li>Sa crvenom ivicom predstavlja dokumentovanu strukturu ili klasu\n"
+ "za koju nisu prikazani svi relevantni grafovi.\n"
+ "</ul>"
+ "Strelice imaju sledeća značenja:\n"
+ "<ul>\n"
+ "<li>Tamnoplava strelica označava javno izvođenje.\n"
+ "<li>Tamnozelena strelica označava zaštićeno izvođenje.\n"
+ "<li>Tamnocrvena strelica označava privatno izvođenje.\n"
+ "<li>Ljubičasta isprekidana strelica označava da je klasa sadržana "
+ "ili korišćena u drugoj klasi. Strelica je označena imenom atributa "
+ "preko koga se pristupa klasi/strukturi na koju pokazuje.\n"
+ "<li>Žuta isprekidana strelica označava vezu između primerka šablona i"
+ " šablona klase od kojeg je primerak napravljen. "
+ "Strelica je označena stvarnim argumentima šablona.\n"
+ "</ul>\n"
+ ;
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Objašnjenje korišćenih simbola";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Spisak testova";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Osobine";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Dokumentacija osobina";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Strukture i unije";
+ }
+ else
+ {
+ return "Klase";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Spisak paketa";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Paketi s kratkim opisom (ukoliko postoji):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paketi";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Vrednost:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Greška";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Spisak grešaka";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "238";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Sadržaj";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result( (first_capital ? "Klas" : "klas") );
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Datotek" : "datotek"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Prostor" : "prostor"));
+ result += (singular ? "" : "i");
+ result += " imena";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grup" : "grup"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Stran" : "stran"));
+ result+= (singular ? "a" : "e");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Član" : "član"));
+ result+= (singular ? "" : "ovi");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Globalni " : "globalni "));
+ result+= (singular ? "podatak" : "podaci");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Autor" : "autor"));
+ result+= (singular ? "" : "i");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Koristi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int /*numEntries*/)
+ { //! "Definiše" je previše kratko, ispada sa de definišu same apstraktne klase
+ return "Definiše apstraktnu funkciju deklarisanu u ";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int /*numEntries*/)
+ { //! Izbegavanje roda
+ return "Definicija u ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Sadržaj";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Spisak zastarelih stvari";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Događaji";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Dokumentacija događaja";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Tipovi u paketu";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Funkcije u paketu";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statičke funkcije u paketu"; // Zajednicke funkcije u paketu
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Atributi u paketu"; // Clanovi u paketu
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statički atributi u paketu"; // Zajednicki clanovi u paketu
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Sve";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Graf poziva iz ove funkcije:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Rezultati pretraživanja";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Nema dokumenata koji odgovaraju Vašem upitu.";
+ }
+ else if (numDocuments==1)
+ { return "Nađen je <b>1</b> dokument koji odgovara vašem upitu."; }
+ else if (numDocuments<5)
+ { return "Nađena su <b>$num</b> dokumenta koji odgovaraju vašem upitu."
+ " Najbolji su prikazani prvi."; }
+ else
+ { return "Nađeno je <b>$num</b> dokumenata koji odgovaraju vašem upitu."
+ " Najbolji su prikazani prvi.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Pronađeno:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Izvorni kod datoteke " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Hijerarhija direktorijuma"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dokumentacija direktorijuma"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Direktorijumi"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Hijerarhija direktorijuma uređena približno po abecedi:"; }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+="Opis direktorijuma"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Direktorijum" : "direktorijum"));
+ if (!singular) result+="i";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Ovo je funkcija prekopljenog imena, razlikuje se "
+ "od gore navedene samo po argumentima koje prihvata.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ { //! Možda je bolje "Graf pozivalaca ove funkcije"
+ return "Graf funkcija koje pozivaju ovu funkciju:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Dokumentacija enum vrednosti"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Dokumentacija funkcija i procedura"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ /* TODO: Koji je prevod za Compound u Fortran kontekstu */
+ virtual QCString trCompoundListFortran()
+ { return "Složeni tipovi podataka"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Polja u složenim tipovima podataka"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Spisak složenih tipova podataka sa kratkim opisima:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result=" Spisak svih ";
+ if (!extractAll)
+ {
+ result+="dokumentovanih ";
+ }
+ result+="polja složenih tipova podataka";
+ result+=" sa vezama ka ";
+ if (!extractAll)
+ {
+ result+="dokumentaciji strukture podataka za svakog člana";
+ }
+ else
+ {
+ result+="složenim tipovima podataka kojima pripadaju:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Sadržaj složenog tipa podataka"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dokumentacija tipova podataka"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funkcije i procedure"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Dokumentacija funkcija i procedura"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Složeni tipovi podataka"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Spisak modula"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+ result+="modula sa kratkim opisima:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Modul"; break;
+ case ClassDef::Struct: result+=" Tip"; break;
+ case ClassDef::Union: result+=" Unija"; break;
+ case ClassDef::Interface: result+=" Interfejs"; break;
+ case ClassDef::Protocol: result+=" Protokol"; break;
+ case ClassDef::Category: result+=" Kategorija"; break;
+ case ClassDef::Exception: result+=" Izuzetak"; break;
+ default: break;
+ }
+ result+=" - sažet pregled";
+ if (isTemplate) result+=" šablona";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" - sažet pregled modula";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Članovi modula"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Spisak svih ";
+ if (!extractAll) result+="dokumentovanih ";
+ result+="članova modula sa vezama ka ";
+ if (extractAll)
+ {
+ result+="dokumentaciji za svakog člana modula:";
+ }
+ else
+ {
+ result+="modulima kojima pripadaju:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Spisak modula"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modul" : "modul"));
+ if (!singular) result+="i";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentacija za ovaj ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modul"; break;
+ case ClassDef::Struct: result+="tip"; break;
+ case ClassDef::Union: result+="uniju"; break;
+ case ClassDef::Interface: result+="interfejs"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategoriju"; break;
+ case ClassDef::Exception: result+="izuzetak"; break;
+ default: break;
+ }
+ result+=" napravljena je automatski od sledeć";
+ if (single) result+="e datoteke:"; else result+="ih datoteka:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (!singular) result+="ovi";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Procedura" : "procedura"));
+ if (!singular) result = (first_capital ? "Procedure" : "procedure");
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Ograničenja tipova";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// following methods have no corresponding entry in translator_en.h
+//////////////////////////////////////////////////////////////////////////
+
+// /*! This is put above each page as a link to the list of all verbatim headers */
+// virtual QCString trHeaderFiles()
+// { return "Zaglavlja"; }
+//
+// /*! This is an introduction to the page with the list of all header files. */
+// virtual QCString trHeaderFilesDescription()
+// { return "Zaglavlja koje izgraduju API:"; }
+//
+// /*! This sentences is used in the annotated class/file lists if no brief
+// * description is given.
+// */
+// virtual QCString trNoDescriptionAvailable()
+// { return "Opis nije dostupan"; }
+//
+// /*! this text is generated when the \\reimp command is used. */
+// virtual QCString trReimplementedForInternalReasons()
+// { return decode("Preuradeno zbog unutrasnjih razloga; Nema uticaja na API." ); }
+//
+// /*! this text is generated when the \\bug command is used. */
+// virtual QCString trBugsAndLimitations()
+// { return "Greske i ogranicenja"; }
+//
+// virtual QCString trSources()
+// {
+// return decode("Izvorne datoteke" );
+// }
+//
+// /*! Used for Java interfaces in the summary section of Java packages */
+// virtual QCString trInterfaces()
+// {
+// return "Interfejsi"; //!< Radna okruzenja. Ali to je dve reci.
+// }
+//
+// /*! Used as a chapter title for Latex & RTF output */
+// virtual QCString trPackageDocumentation()
+// {
+// return "Dokumentacija paketa";
+// }
+//
+// /*! This is used for translation of the word that will possibly
+// * be followed by a single name or by a list of names
+// * of the category.
+// */
+// virtual QCString trField(bool first_capital, bool singular)
+// {
+// QCString result((first_capital ? "Polj" : "polj"));
+// result+= (singular ? "e" : "a");
+// return result;
+// }
+
+};
+
+#endif
diff --git a/src/translator_sv.h b/src/translator_sv.h
new file mode 100644
index 0000000..f4d0a35
--- /dev/null
+++ b/src/translator_sv.h
@@ -0,0 +1,1882 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+/*
+==================================================================================
+Svensk översättning av:
+Samuel Hägglund <sahag96 at ite.mh.se>
+Xet Erixon <xet at xeqt.com>
+Mikael Hallin <mikaelhallin at yahoo.se> 2003-07-28
+Björn Palmqvist <bjorn at aidium.se> 2014-02-01
+==================================================================================
+Uppdateringar.
+1999/04/29
+* Omskrivningar av en hel del ordval, t.ex.
+ ENG INNAN EFTER
+ compound inhängnad sammansatt
+ structs structs strukter
+ unions unions unioner
+
+ osv...
+
+* Alla översättnings-strängar returnerar i alla fall en något så när vettig
+ förklaring...
+
+1999/05/27
+* Det verkade som vi glömt en del mellanslag i vissa strängar vilket resulterade
+ i att en del ord blev ihopskrivna.
+
+* Bytt en del ordval igen...
+ ENG INNAN EFTER
+ reference manual Uppslagsbok referensmanual
+
+* Skrivit ihop en del ord som innan hade bindestreck
+* En del nya översättningar är tillagda.
+* Gamla översättningar borttagna
+
+===================================================================================
+Problem!
+ Slot: nån hygglig svensk översättning???
+
+ Skicka gärna synpunkter.
+===================================================================================
+1999/09/01
+* Det verkar som om "namnrymd" är en hyggligt vedertagen svensk översättning
+ av "namespace", så jag kör med det från och med nu.
+* "interface" heter numera "gränssnitt"
+
+2003/07/28
+* Jag har updaterat översättningen efter ett par års träda..
+Problem!
+ Deprecated: nån hygglig svensk översättning???
+
+ Skicka gärna synpunkter.
+*/
+
+#ifndef TRANSLATOR_SE_H
+#define TRANSLATOR_SE_H
+
+class TranslatorSwedish : public Translator
+{
+ public:
+
+ virtual QCString idLanguage()
+ { return "swedish"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[swedish]{babel}\n";
+ }
+
+ virtual QCString trRelatedFunctions()
+ { return "Besläktade funktioner"; }
+
+ virtual QCString trRelatedSubscript()
+ { return "(Observera att dessa inte är medlemsfunktioner)"; }
+
+ virtual QCString trDetailedDescription()
+ { return "Detaljerad beskrivning"; }
+
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Dokumentation av typdefinierade medlemmar"; }
+
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Dokumentation av egenuppräknande medlemmar"; }
+
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Dokumentation av medlemsfunktioner"; }
+
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Fält dokumentation";
+ }
+ else
+ {
+ return "Dokumentation av datamedlemmar";
+ }
+ }
+
+ virtual QCString trMore()
+ { return "Mer..."; }
+
+ virtual QCString trListOfAllMembers()
+ { return "Lista över alla medlemmar"; }
+
+ virtual QCString trMemberList()
+ { return "Medlemslista"; }
+
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Det här är en fullständig lista över medlemmar för "; }
+
+ virtual QCString trIncludingInheritedMembers()
+ { return " med alla ärvda medlemmar."; }
+
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automatiskt skapad av Doxygen";
+ if (s) result+=(QCString)" för "+s;
+ result+=" från källkoden.";
+ return result;
+ }
+
+ virtual QCString trEnumName()
+ { return "enum namn"; }
+
+ virtual QCString trEnumValue()
+ { return "enum värde"; }
+
+ virtual QCString trDefinedIn()
+ { return "definierad i"; }
+
+/*
+ QCString trVerbatimText(const char *f)
+ { return (QCString)"Detta är den ordagranna texten från inkluderingsfilen "+f; }
+*/
+ virtual QCString trModules()
+ { return "Moduler"; }
+
+ virtual QCString trClassHierarchy()
+ { return "Klasshierarki"; }
+
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Sammansatt klasslista";
+ }
+ }
+
+ virtual QCString trFileList()
+ { return "Fillista"; }
+
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data fält";
+ }
+ else
+ {
+ return "Sammansatta klassmedlemmar";
+ }
+ }
+
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globala symboler";
+ }
+ else
+ {
+ return "Filmedlemmar";
+ }
+ }
+
+ virtual QCString trRelatedPages()
+ { return "Besläktade sidor"; }
+
+ virtual QCString trExamples()
+ { return "Exempel"; }
+
+ virtual QCString trSearch()
+ { return "Sök"; }
+
+ virtual QCString trClassHierarchyDescription()
+ { return "Denna lista över arv är grovt, men inte helt, "
+ "sorterad i alfabetisk ordning:";
+ }
+
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Här följer en lista över alla ";
+ if (!extractAll) result+="dokumenterade ";
+ result+="filer, med en kort beskrivning:";
+ return result;
+ }
+
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Här följer datastrukturerna med korta beskrivningar:";
+ }
+ else
+ {
+ return "Här följer klasserna, strukterna, unionerna och "
+ "gränssnitten med korta beskrivningar:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Här är en lista över alla ";
+ if (!extractAll)
+ {
+ result+="dokumenterade ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktur- och unions-fält";
+ }
+ else
+ {
+ result+="klassmedlemmar";
+ }
+ result+=" med länkar till ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struktur/unions-dokumentationen för varje fält:";
+ }
+ else
+ {
+ result+="klassdokumentationen för varje medlem:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+=" strukturerna/unionerna de tillhör:";
+ }
+ else
+ {
+ result+="klasserna de tillhör:";
+ }
+ }
+ return result;
+ }
+
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Här följer en lista över alla ";
+ if (!extractAll) result+="dokumenterade ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funktioner, variabler, definitioner, enumerationer "
+ "och typdefinitioner";
+ }
+ else
+ {
+ result+= "filmedlemmar";
+ }
+ result+= " med länkar till ";
+ if (extractAll)
+ result+= "filerna som de tillhör:";
+ else
+ result+= "dokumentationen:";
+ return result;
+ }
+
+ virtual QCString trExamplesDescription()
+ { return "Här följer en lista med alla exempel:"; }
+
+ virtual QCString trRelatedPagesDescription()
+ { return "Här följer en lista över alla besläktade dokumentationssidor:";}
+
+ virtual QCString trModulesDescription()
+ { return "Här följer en lista över alla moduler:"; }
+
+ virtual QCString trDocumentation()
+ { return "Dokumentation"; }
+
+ virtual QCString trModuleIndex()
+ { return "Modulindex"; }
+
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarkiskt Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) {
+ return "Index över datastrukturer";
+ } else {
+ return "Index över sammensatta typer";
+ }
+ }
+
+ virtual QCString trFileIndex()
+ { return "Filindex"; }
+
+ virtual QCString trModuleDocumentation()
+ { return "Dokumentation över moduler"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Dokumentation över datastrukturer";
+ }
+ else
+ {
+ return "Documentation över klasser";
+ }
+ }
+
+ virtual QCString trFileDocumentation()
+ { return "Dokumentation över filer"; }
+
+ virtual QCString trExampleDocumentation()
+ { return "Dokumentation över exempel"; }
+
+ virtual QCString trPageDocumentation()
+ { return "Dokumentation av sidor"; }
+
+ virtual QCString trReferenceManual()
+ { return "Referensmanual"; }
+
+ virtual QCString trDefines()
+ { return "Definitioner"; }
+ virtual QCString trTypedefs()
+ { return "Typdefinitioner"; }
+ virtual QCString trEnumerations()
+ { return "Egenuppräknande typer"; }
+ virtual QCString trFunctions()
+ { return "Funktioner"; }
+ virtual QCString trVariables()
+ { return "Variabler"; }
+
+ virtual QCString trEnumerationValues()
+ { return "Egenuppräknade typers värden"; }
+
+ virtual QCString trDefineDocumentation()
+ { return "Dokumentation över definitioner"; }
+
+ virtual QCString trTypedefDocumentation()
+ { return "Dokumentation över typdefinitioner"; }
+
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Dokumentation över egenuppräknande typer"; ; }
+
+ virtual QCString trFunctionDocumentation()
+ { return "Dokumentation över funktioner"; }
+
+ virtual QCString trVariableDocumentation()
+ { return "Dokumentation över variabler"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Sammansättning";
+ }
+ }
+
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Skapad "+date;
+ if (projName) result+=(QCString)" för "+projName;
+ result+=(QCString)" av";
+ return result;
+ }
+
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Klassdiagram för "+clName;
+ }
+
+ virtual QCString trForInternalUseOnly()
+ { return "Endast för internt bruk."; }
+
+ virtual QCString trWarning()
+ { return "Varning"; }
+
+ virtual QCString trVersion()
+ { return "Version"; }
+
+ virtual QCString trDate()
+ { return "Datum"; }
+
+ virtual QCString trReturns()
+ { return "Returnerar"; }
+
+ virtual QCString trSeeAlso()
+ { return "Se även"; }
+
+ virtual QCString trParameters()
+ { return "Parametrar"; }
+
+ virtual QCString trExceptions()
+ { return "Undantag"; }
+
+ virtual QCString trGeneratedBy()
+ { return "Skapad av"; }
+
+// new since 0.49-990307
+
+ virtual QCString trNamespaceList()
+ { return "Namnrymdslista"; }
+
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Här är en lista över alla ";
+ if (!extractAll) result+="dokumenterade ";
+ result+="namnrymder med en kort beskrivning:";
+ return result;
+ }
+
+ virtual QCString trFriends()
+ { return "Vänner"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Vänners och besläktade funktioners dokumentation"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName+" ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" klass"; break;
+ case ClassDef::Struct: result+=" strukt"; break;
+ case ClassDef::Union: result+=" union"; break;
+ case ClassDef::Interface: result+=" gränssnitt"; break;
+ case ClassDef::Protocol: result+=" protocol"; break; // translate me!
+ case ClassDef::Category: result+=" category"; break; // translate me!
+ case ClassDef::Exception: result+=" undantag"; break;
+ default: break;
+ }
+ if (isTemplate) result+="template";
+ result+="referens";
+ return result;
+ }
+
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" filreferens";
+ return result;
+ }
+
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" namnrymdreferens";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Publika medlemmar"; }
+ virtual QCString trPublicSlots()
+ { return "Publika slots"; }
+ virtual QCString trSignals()
+ { return "Signaler"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiska publika medlemmar"; }
+ virtual QCString trProtectedMembers()
+ { return "Skyddade medlemmar"; }
+ virtual QCString trProtectedSlots()
+ { return "Skyddade slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiska skyddade medlemmar"; }
+ virtual QCString trPrivateMembers()
+ { return "Privata medlemmar"; }
+ virtual QCString trPrivateSlots()
+ { return "Privata slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiska privata medlemmar"; }
+ // end of member sections
+
+ virtual QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", och ";
+ }
+ }
+ return result;
+ }
+
+ virtual QCString trInheritsList(int numEntries)
+ // used in class documentation to produce a list of base classes,
+ // if class diagrams are disabled.
+ {
+ return "Ärver "+trWriteList(numEntries)+".";
+ }
+ virtual QCString trInheritedByList(int numEntries)
+ // used in class documentation to produce a list of super classes,
+ // if class diagrams are disabled.
+ {
+ return "Ärvd av "+trWriteList(numEntries)+".";
+ }
+ virtual QCString trReimplementedFromList(int numEntries)
+ // used in member documentation blocks to produce a list of
+ // members that are hidden by this one.
+ {
+ return "Återskapad från "+trWriteList(numEntries)+".";
+ }
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ // used in member documentation blocks to produce a list of
+ // all member that overwrite the implementation of this member.
+ return "Återskapad i "+trWriteList(numEntries)+".";
+ }
+
+ virtual QCString trNamespaceMembers()
+ { return "Namnrymdsmedlemmar"; }
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Här är en lista över alla ";
+ if (!extractAll) result+="dokumenterade ";
+ result+="namnrymdsmedlemmar med länkar till ";
+ if (extractAll)
+ result+=" namnrymd-dokumentationen för varje medlem:";
+ else
+ result+="de namnrymder de tillhör:";
+ return result;
+ }
+
+ virtual QCString trNamespaceIndex()
+ { return "Namnrymdsindex"; }
+
+ virtual QCString trNamespaceDocumentation()
+ { return "Namnrymd-dokumentation"; }
+ //////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namnrymder"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentationen för ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="denna klass "; break;
+ case ClassDef::Struct: result+="denna strukt "; break;
+ case ClassDef::Union: result+="denna union "; break;
+ case ClassDef::Interface: result+="detta gränssnitt "; break;
+ case ClassDef::Protocol: result+="protocol"; break; // translate me!
+ case ClassDef::Category: result+="category"; break; // translate me!
+ case ClassDef::Exception: result+="detta undantag "; break;
+ default: break;
+ }
+ result+="var genererad från följande fil";
+ if (single) result+=":"; else result+="er:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Returvärden"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Huvudsida"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "s."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Definition på rad @0 i filen @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definition i filen @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Föråldrad";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Samarbetsdiagram för "+clName+":";
+ }
+
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Include-beroendediagram för "+fName+":";
+ }
+
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Dokumentation av konstruktorer och destruktorer";
+ }
+
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Gå till denna fils källkod.";
+ }
+
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Gå till denna fils dokumentation.";
+ }
+
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Förhandsvillkor";
+ }
+
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Resultat"; //"Postcondition";
+ }
+
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Begynnelsevärde:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "källkod";
+ }
+
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafisk klasshierarki";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Gå till den grafiska klasshierarkin";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Gå till den textbaserade klasshierarkin";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Sidindex";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Notera";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Publika typer";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datafält";
+ }
+ else
+ {
+ return "Publika attribut";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statiska publika attribut";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Skyddade typer";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Skyddade attribut";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statiska skyddade attribut";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Privata typer";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Privata attribut";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statiska privata attribut";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Att-göra";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Att-göra lista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Refererad av";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Lägg märke till";
+ }
+ virtual QCString trAttention()
+ {
+ return "Observera";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Den här grafen visar vilka filer som direkt eller "
+ "indirekt inkluderar denna filen.";
+ }
+ virtual QCString trSince()
+ {
+ return "Sedan";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Grafförklaring";
+ }
+
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Den här sidan förklarar hur man ska tolka de grafer som doxygen "
+ "genererar.<p>\n"
+ "Tag följande exempel:\n"
+ "\\code\n"
+ "/*! Osynlig klass på grund av stympning */\n"
+ "class Invisible { };\n\n"
+ "/*! Stympad klass, ärvningsrelationen är dold */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Klass utan doxygen-kommentarer */\n"
+ "class Undocumented { };\n\n"
+ "/*! Klass som ärvs med publikt arv */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! En template-klass */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Klass som ärvs med skyddat arv */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Klass som ärvs med privat arv */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Klass som används av Inherited klassen */\n"
+ "class Used { };\n\n"
+ "/*! Super klassen som ärver ett antal andra klasser */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Om \\c MAX_DOT_GRAPH_HEIGHT är satt till 240 i konfigurationsfilen, "
+ "kommer följande graf att generas:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Rektanglarna i den ovanstående grafen har följande betydelser:\n"
+ "<ul>\n"
+ "<li>%En fylld svart rektangel representerar den strukt eller klass "
+ "som har genererat grafen.\n"
+ "<li>%En rektangel med svart kant symboliserar en dokumenterad "
+ "strukt eller klass.\n"
+ "<li>%En rektangel med grå kant symboliserar en odokumenterad strukt "
+ "eller klass.\n"
+ "<li>%En klass med röd kant symboliserar en strukt eller klass där "
+ "alla dess relationer inte visas. %En graf stympas om den inte får "
+ "plats inom de givna gränserna.\n"
+ "</ul>\n"
+ "Pilarna har följande betydelser:\n"
+ "<ul>\n"
+ "<li>%En mörkblå pil används för att visualisera en publik arvrelation "
+ "mellan två klasser.\n"
+ "<li>%En mörkgrön pil används för en skyddad arvsrelation.\n"
+ "<li>%En mörkröd pil används för en privat arvsrelation.\n"
+ "<li>%En sträckad lila pil används om en klass är innesluten eller "
+ "använd av en annan klass. Vid pilen står namnet på den eller de "
+ "variabler som klassen pilen pekar på kommer åt.\n"
+ "<li>%En sträckad gul pil symboliserar förhållandet mellan en "
+ "template-instans och template-klassen, som den instantierades från.\n"
+ "Vid pilen står instansens template-parametrar.\n"
+ "</ul>\n";
+ }
+
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "förklaring";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Testlista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Egenskaper";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Egenskapsdokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Datastrukturer";
+ }
+ else
+ {
+ return "Klasser";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Paketlista";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Här är en lista över paketen med en kort beskrivning "
+ "(om sådan finns):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paket";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Värde:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bugg";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Bugglista";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ * (used table extract:)
+ * <pre>
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * ANSI_CHARSET 0 (x00) 1252
+ * </pre>
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klass" : "klass"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fil" : "fil"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namnrymd" : "namnrymd"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grupp" : "grupp"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sid" : "sid"));
+ if (singular)
+ result+="a";
+ else
+ result+="or";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Medlem" : "medlem"));
+ if (!singular) result+="mar";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Författare" : "författare"));
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referenser";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implementerar "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Implementerad i "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Innehållsförteckning";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Lista över föråldrade";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Händelser";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Händelse Dokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Paket typer";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Paket funktioner";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statiska paket funktioner";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Paket attribut";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statiska paket attribut";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alla";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Här är anropnings diagrammet för den här funktionen:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Sökresultat";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Tyvärr finns det inga dokument som matchar din sökning.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Hittade <b>1</b> dokument som matchar din sökning.";
+ }
+ else
+ {
+ return "Hittade <b>$num</b> dokument som matchar din sökning. "
+ "Visar de bästa träffarna först.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Träffar:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Källkodsfilen " + filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Katalogstruktur"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Katalogdokumentation"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Kataloger"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Den här katalogen är grovt sorterad, "
+ "men inte helt, i alfabetisk ordning:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Katalogreferens"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Katalog" : "katalog"));
+ if (!singular) result+="er";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Det här är en överlagrad medlemsfunktion "
+ "tillhandahållen för bekvämlighet. Den enda som "
+ "skiljer sig från ovanstående funktion är vilka "
+ "argument den tar emot.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Här är katalog-grafen för denna funktion:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ {
+ return "Uppräknings-dokumentation";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Memlems-function/Subroutins Dokumentation"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Datatyplista"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Data fält"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Här är datatyperna med en kort beskrivning:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Här är en lista av alla ";
+ if (!extractAll)
+ {
+ result+="dokumenterade ";
+ }
+ result+="datatyps medlemmar";
+ result+=" med länkar till ";
+ if (!extractAll)
+ {
+ result+="datastrukturs documentation för varje medlem";
+ }
+ else
+ {
+ result+="klasserna de hör till:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Datatyps Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Dataryps Dokumentation"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funktions/Subroutins"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funktion/Subroutin Dokumentation"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Datatyper"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modullista"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Här är en lista på alla ";
+ if (!extractAll) result+="dokumenterade ";
+ result+="moduler med en kort beskrivning:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Modul"; break;
+ case ClassDef::Struct: result+=" Typ"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Gränssnitt"; break;
+ case ClassDef::Protocol: result+=" Protokoll"; break;
+ case ClassDef::Category: result+=" Kategori"; break;
+ case ClassDef::Exception: result+=" Undantag"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Mall";
+ result+=" Referens";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Modul Referens";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Modul Medlemmar"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Här är en lista på alla ";
+ if (!extractAll) result+="documented ";
+ result+="modul medlemmar med länkar till ";
+ if (extractAll)
+ {
+ result+="modul dokumentationen för varje medlem:";
+ }
+ else
+ {
+ result+="modulerna de hör till:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modul Index"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "modul", "er");
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentationen för denna ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modul"; break;
+ case ClassDef::Struct: result+="typ"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="gränssnitt"; break;
+ case ClassDef::Protocol: result+="protokoll"; break;
+ case ClassDef::Category: result+="kategori"; break;
+ case ClassDef::Exception: result+="undantag"; break;
+ default: break;
+ }
+ result+=" genererades från följade fil";
+ if (single) result+=":"; else result+="er:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ return createNoun(first_capital, singular, "typ", "er");
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool /*singular*/)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Typbegränsningar";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" Relation";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Laddar...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Globalnamnrymd";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Söker...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Inga träffar";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Fil i "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Inkluderar fil i "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Mån","Tis","Ons","Tor","Fre","Lör","Sön" };
+ static const char *months[] = { "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
+ QCString sdate;
+ sdate.sprintf("%s %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Bibliografiska Referenser"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Copyright"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Katalogberoendegraf för ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "detaljnivå"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Mall Parametrar"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "och "+number+" mera..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Dokumentationen för denna enum var genererad från föjlande fil";
+ if (!single) result += "er";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Enum Referens"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" ärvd ifrån "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Ytterliga Ärvda Medlemmar"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "aktivera" : "inaktivera";
+ return "klicka för att "+opt+" panel synkronisering";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Tillhandahålls av kategori @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Utökar klass @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Klassmetoder";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Instansmetoder";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Metoddokumentation";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Designöversikt";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "Exporterade Interface"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "Inkuderade Tjänster"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "Konstant Grupper"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Konstant Grupp Referens";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Tjänstereferens";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+=" Singleton Referens";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentationen för denna tjänst "
+ "genererades från följande fil";
+ if (single) result+=":"; else result+="er:";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Dokumentationen för denna singleton"
+ "genererades från följande fil";
+ if (single) result+=":"; else result+="er:";
+ return result;
+ }
+
+/*---------- For internal use: ----------------------------------------*/
+ protected:
+ /*! For easy flexible-noun implementation.
+ * \internal
+ */
+ QCString createNoun(bool first_capital, bool singular,
+ const char* base, const char* plurSuffix)
+ {
+ QCString result(base);
+ if (first_capital) result.at(0) = toupper(result.at(0));
+ if (!singular) result+=plurSuffix;
+ return result;
+ }
+
+
+};
+
+#endif
diff --git a/src/translator_tr.h b/src/translator_tr.h
new file mode 100644
index 0000000..56b4a19
--- /dev/null
+++ b/src/translator_tr.h
@@ -0,0 +1,1822 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_TR_H
+#define TRANSLATOR_TR_H
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorTurkish : public TranslatorAdapter_1_7_5
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "turkish"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related fonksiyonlar. */
+ virtual QCString trRelatedFunctions()
+ { return "İlgili Fonksiyonlar"; }
+
+ /*! subscript for the related fonksiyonlar. */
+ virtual QCString trRelatedSubscript()
+ { return "(Not: Bu fonksiyonlar üye fonksiyon değildir.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Ayrıntılı tanımlama"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Üye Typedef Dokümantasyonu"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Üye Enümerasyon Dokümantasyonu"; }
+
+ /*! header that is put before the list of member fonksiyonlar. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Üye Fonksiyon Dokümantasyonu"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Alan Dokümantasyonu";
+ }
+ else
+ {
+ return "Üye Veri Dokümantasyonu";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Ayrıntılar..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Tüm üyelerin listesi"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Üye Listesi"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Şu sınıfın tüm üyelerinin listesidir: "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return " (kalıtımla gelen üyeleri de içerir)."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Doxygen tarafından";
+ if (s) result+=s+(QCString)" için ";
+ result+=" kaynak koddan otomatik üretilmiştir.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum adı"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum değeri"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "tanımlandığı yer"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modüller"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Sınıf Hiyerarşisi"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Yapıları";
+ }
+ else
+ {
+ return "Sınıf Listesi";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Dosya Listesi"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Alanları";
+ }
+ else
+ {
+ return "Sınıf Üyeleri";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globaller";
+ }
+ else
+ {
+ return "Dosya Üyeleri";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "İlgili Sayfalar"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Örnekler"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Ara"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Bu kalıtım listesi tamamen olmasa da yaklaşık "
+ "olarak alfabetik sıraya konulmuştur:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+ result+="dosyaları kısa açıklamalarıyla göstermektedir:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Kısa tanımlarıyla birlikte veri yapıları:";
+ }
+ else
+ {
+ return "Kısa tanımlarıyla sınıflar, yapılar (struct), "
+ "birleşimler(union) ve arayüzler:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll)
+ {
+ result+="dokümante edilmiş ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="yapı(struct) ve birleşim(union) yapılarını içerir";
+ }
+ else
+ {
+ result+="sınıf üyelerini içerir";
+ }
+ result+=" ve ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="her alanı yapı(struct)/birleşim(union) dokümantasyonuna bağlar:";
+ }
+ else
+ {
+ result+="her üye için sınıf dokümantasyonuna bağlar:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="ait olduğu yapı(struct)/birleşime(union) bağlar:";
+ }
+ else
+ {
+ result+="ait olduğu sınıfa bağlar:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="fonksiyonları, değişkenleri, makroları, enümerasyonları ve typedef\'leri içerir";
+ }
+ else
+ {
+ result+="dosya üyelerini içerir";
+ }
+ result+=" ve ";
+ if (extractAll)
+ result+="ait olduğu dosyalar bağlar:";
+ else
+ result+="dokümantasyona bağlar:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Tüm örneklerin listesi aşağıdadır:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "İlgili tüm dokümantasyon sayfalarının listesi aşağıdadır:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Tüm modüllerin listesi aşağıdadır:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokümantasyonu"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Modül İndeksi"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hiyerarşik İndeksi"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Yapıları İndeksi";
+ }
+ else
+ {
+ return "Sınıf İndeksi";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Dosya İndeksi"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Modül Dokümantasyonu"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Yapıları Dokümantasyonu";
+ }
+ else
+ {
+ return "Sınıf Dokümantasyonu";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Dosya Dokümantasyonu"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Örnek Dokümantasyonu"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Sayfa Dokümantasyonu"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Referans Kitabı"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Makrolar"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedef\'ler"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enümerasyonlar"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Fonksiyonlar"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Değişkenler"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enümeratör"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Makro Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enümerasyon Tipi Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Fonksiyon Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Değişken Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Yapıları";
+ }
+ else
+ {
+ return "Sınıflar";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=projName+(QCString)" için "+date;
+ if (projName) result+=(QCString)" tarihinde ";
+ result+=(QCString)" üreten: ";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return clName+(QCString)" için kalıtım şeması:";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "İç kullanıma ayrılmıştır."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Uyarı"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Sürüm"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Tarih"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Döndürdüğü değer"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Ayrıca Bakınız"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parametreler"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "İstisnalar"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Oluşturan"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Namespace Listesi"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+ result+="namespace\'lerin kısa tanımlarıyla listesi aşağıdadır:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Arkadaşları"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Arkadaş Ve İlgili Fonksiyon Dokümantasyonu"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Sınıf"; break;
+ case ClassDef::Struct: result+=" Yapı(Struct)"; break;
+ case ClassDef::Union: result+=" Birleşim(Union)"; break;
+ case ClassDef::Interface: result+=" Arayüz(Interface)"; break;
+ case ClassDef::Protocol: result+=" Protokol"; break;
+ case ClassDef::Category: result+=" Kategori"; break;
+ case ClassDef::Exception: result+=" İstisna"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Şablon";
+ result+=" Referans";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" Dosya Referansı";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Referansı";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Public Üye Fonksiyonlar"; }
+ virtual QCString trPublicSlots()
+ { return "Public Slotlar"; }
+ virtual QCString trSignals()
+ { return "Sinyaller"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statik Public Üye Fonksiyonlar"; }
+ virtual QCString trProtectedMembers()
+ { return "Korumalı Üye Fonksiyonlar"; }
+ virtual QCString trProtectedSlots()
+ { return "Korumalı Slotlar"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statik Korumalı Üye Fonksiyonlar"; }
+ virtual QCString trPrivateMembers()
+ { return "Özel Üye Fonksiyonlar"; }
+ virtual QCString trPrivateSlots()
+ { return "Özel Slotlar"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statik Özel Üye Fonksiyonlar"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=" ve ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Şu sınıflardan türemiştir : "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Şu sınıfların atasıdır : "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Şu üyeleri yeniden tanımlar : "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Şu üyeler tarafından yeniden tanımlanmıştır : "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Namespace Üyeleri"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+ result+="namespace üyelerini listeler ve ";
+ if (extractAll)
+ result+="her üye için üye dokümantasyonuna bağlar:";
+ else
+ result+="ait olduğu namespace\'lere bağlar:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespace İndeksi"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Namespace Dokümantasyonu"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespace\'ler"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Bu ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="sınıf"; break;
+ case ClassDef::Struct: result+="yapı(struct)"; break;
+ case ClassDef::Union: result+="birleşim(union)"; break;
+ case ClassDef::Interface: result+="arayüz(interface)"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategori"; break;
+ case ClassDef::Exception: result+="istisna"; break;
+ default: break;
+ }
+ result+=" için dokümantasyon aşağıdaki dosya";
+ if (single) result+=""; else result+="lar";
+ result+="dan üretilmiştir:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Döndürdüğü değerler"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Ana Sayfa"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "sf."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "@1 dosyasının @0 numaralı satırında tanımlanmıştır.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "@0 dosyasında tanımlanmıştır.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Kullanımdan kalkmıştır";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return clName+(QCString)" için işbirliği (collaboration) şeması:";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return fName+(QCString)" için içerme bağımlılık grafiği:";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Constructor & Destructor Dokümantasyonu";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Bu dosyanın kaynak koduna git.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Bu dosyanın dokümantasyonuna git.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Ön şart";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Son şart (Postcondition)";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Değişmez(Invariant)";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "İlk değer:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "kod";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafiksel Sınıf Hiyerarşisi";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Grafiksel sınıf hiyerarşisine git";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Metinsel sınıf hiyerarşisine git";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Sayfa İndeksi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Not";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Public Tipler";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Alanları";
+ }
+ else
+ {
+ return "Public Özellikler(attribute)";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statik Public Özellikler(attribute)";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Korumalı Tipler";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Korumalı Özellikler(attribute)";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statik Korumalı Attributes";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Özel Tipler";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Özel Özellikler(attribute)";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statik Özel Özellikler(attribute)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Yapılacak";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Yapılacaklar Listesi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Referans veren";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Dipnotlar";
+ }
+ virtual QCString trAttention()
+ {
+ return "Dikkat";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Bu şekil hangi dosyaların doğrudan ya da "
+ "dolaylı olarak bu dosyayı içerdiğini gösterir:";
+ }
+ virtual QCString trSince()
+ {
+ return "Şu zamandan beri";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Şekil Lejantı";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Bu dosya doxygen tarafından üretilen grafiklerin nasıl anlaşılacağını "
+ "açıklar.<p>\n"
+ "Aşağıdaki örneğe bakalım:\n"
+ "\\code\n"
+ "/*! Sadeleşme yüzünden görünmeyen sınıf */\n"
+ "class Invisible { };\n\n"
+ "/*! Sadeleşmiş sınıf, kalıtım ilişkisi gizli */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Doxygen yorumlarıyla dokümante edilmemiş sınıf */\n"
+ "class Undocumented { };\n\n"
+ "/*! Public kalıtımla türetilen sınıf */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Bir şablon sınıfı */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Korumalı kalıtımla türetilen sınıf */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Özel kalıtımla türetilen sınıf */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Türetilen sınıf tarafından kullanılan sınıf */\n"
+ "class Used { };\n\n"
+ "/*! Pekçok sınıftan türeyen bir sınıf */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Bu kod aşağıdaki şemayı oluşturur:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Yukarıdaki şemadaki kutular aşağıda açıklanmıştır:\n"
+ "<ul>\n"
+ "<li>Dolu gri kutu şemanın ait olduğu yapı(struct) ya da sınıfı "
+ "gösterir.\n"
+ "<li>Siyah çerçeveli bir kutu dokümante edilmiş bir yapı(struct) ya da sınıfı gösterir.\n"
+ "<li>Gri çerçeveli bir kutu dokümante edilmemiş bir yapı(struct) ya da sınıfı gösterir.\n"
+ "<li>Kırmızı çerçeveli bir kutu tüm kalıtım/içerme ilişkileri gösterilmemiş ve dokümante "
+ "edilmiş bir yapı(struct) ya da sınıfı gösterir. %A şema belirlenen sınırlara "
+ "sığmıyorsa sadeleştirilir.\n"
+ "</ul>\n"
+ "Okların anlamı aşağıdaki gibidir:\n"
+ "<ul>\n"
+ "<li>Koyu mavi ok iki sınıf arasındaki public kalıtım ilişkisini "
+ "göstermekte kullanılır.\n"
+ "<li>Koyu yeşil ok korumalı kalıtımı gösterir.\n"
+ "<li>Koyu kırmızı ok özel kalıtımı gösterir.\n"
+ "<li>Mor kesikli çizgi bir sınıfın diğeri tarafından içeriliyor ya da kullanılıyor "
+ "olduğunu gösterir. Ok işaret edilen sınıfın hangi değişken(ler) tarafından erişildiğini "
+ "gösteren etiketle işaretleniştir.\n"
+ "<li>Sarı kesikli çizgi şablondan üretilen bir sınıf ve ilgili şablon sınıfı "
+ "arasındaki ilişkiyi gösterir. Ok türeyen sınıfın şablon parametreleriyle "
+ "etiketlenmiştir.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "lejant";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Test Listesi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Özellikler";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Özellik Dokümantasyonu";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veri Yapıları";
+ }
+ else
+ {
+ return "Sınıflar";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Paket Listesi";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Paketler ve kısa tanımları (var ise):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paketler";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Değer:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Hata";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Hata Listesi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1254";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "162";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "İndeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sınıf" : "sınıf"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Dosya" : "dosya"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="\'ler";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Grup" : "grup"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Sayfa" : "sayfa"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Üye" : "üye"));
+ if (!singular) result+="ler";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global değişken" : "global değişken"));
+ if (!singular) result+="ler";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Yazar" : "yazar"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Referanslar";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Şu üyeleri gerçekler: "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Şu üyelerce gerçeklenir: "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "İçindekiler";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Kullanımdan Kalkanlar Listesl";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Olaylar";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Olay Dokümantasyonu";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Paket Tipleri";
+ }
+ /*! Used as a heading for a list of Java class fonksiyonlar with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Paket Fonksiyonlar";
+ }
+ /*! Used as a heading for a list of static Java class fonksiyonlar with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Static Pakat Fonksiyonları";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Packet Özellikleri(attribute)";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statik Packet Özellikleri(attribute)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tümü";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Bu fonksiyon için çağırılma şeması:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Arama sonuçları";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Üzgünüm, sorgunuzla eşleşen doküman bulunamadı.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Sorgunuzla eşleşen <b>1</b> doküman bulundu.";
+ }
+ else
+ {
+ return "Sorgunuzla eşleşen <b>$num</b> doküman bulundu. "
+ "Önce en iyi eşleşmeler gösteriliyor.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Eşleşme:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Kaynak Dosyası";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Dizin Hiyerarşisi"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Dizin Dokümantasyonu"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Dizinler"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Bu dizin hiyerarşisi tamamen olmasa da yaklaşık "
+ "olarak alfabetik sıraya konulmuştur:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Dizin Referansı"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Dizin" : "dizin"));
+ if (!singular) result+="ler";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Bu çok anlamlı (overloaded) bir üye fonksiyondur, "
+ "tamamlık açısından burada verilmektedir. Yukarıdaki fonksiyondan "
+ "sadece aldığı argüman(lar) açısından farklıdır.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Bu fonksiyon için çağırılma şeması:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enümerasyon Dokümantasyonu"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Üye Fonksiyon/Subroutine Dokümantasyonu"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Veri Tipleri Listesi"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Veri Alanları"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Kısa tanımlarıyla veri tipleri:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll)
+ {
+ result+="dokümante edilmiş ";
+ }
+ result+="veri tiplerini içerir ve ";
+ if (!extractAll)
+ {
+ result+="her üyeyi veri yapısı dokümantasyonuna bağlar:";
+ }
+ else
+ {
+ result+="ait oldukları veri tiplerine bağlar:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Veri Tipi İndeksi"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Veri Tipi Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Fonksiyonlar/Subroutine\'ler"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Fonksiyon/Subroutine Dokümantasyonu"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Veri Tipleri"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modüller Listesi"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+ result+="modülleri kısa tanımlarıya içerir:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Modül"; break;
+ case ClassDef::Struct: result+=" Tip"; break;
+ case ClassDef::Union: result+=" Birleşim(Union)"; break;
+ case ClassDef::Interface: result+=" Arayüz"; break;
+ case ClassDef::Protocol: result+=" Protokol"; break;
+ case ClassDef::Category: result+=" Kategori"; break;
+ case ClassDef::Exception: result+=" İstisna"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Şablon";
+ result+=" Referans";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Modül Referansı";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Modül Üyeleri"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Bu liste tüm ";
+ if (!extractAll) result+="dokümante edilmiş ";
+ result+="modül üyelerini içerir ve ";
+ if (extractAll)
+ {
+ result+="her üyeyi modül dokümantasyonuna bağlar:";
+ }
+ else
+ {
+ result+="ait oldukları modüllere bağlar:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modüller Indeksi"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Modül" : "modül"));
+ if (!singular) result+="ler";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Bu ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="modül"; break;
+ case ClassDef::Struct: result+="tip"; break;
+ case ClassDef::Union: result+="birleşim(union)"; break;
+ case ClassDef::Interface: result+="arayüz"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategori"; break;
+ case ClassDef::Exception: result+="istisna"; break;
+ default: break;
+ }
+ result+=" için dokümantasyon aşağıdaki dosya";
+ if (single) result+=":"; else result+="lar";
+ result="dan üretilmiştir:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tip" : "tip"));
+ if (!singular) result+="ler";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Alt program" : "alt program"));
+ if (!singular) result+="lar";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Tip Sınırlamaları";
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.6.0 (mainly for the new search engine)
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" İlişkisi";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Yüklüyor...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "En Üst Seviye";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Arıyor...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Eşleşme Yok";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // new since 1.6.3 (missing items for the directory pages)
+ //////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)(name) + (QCString)" dizinindeki dosya";
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)(name) + (QCString)" dizinindeki dosyayı kapsıyor";
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Pzt","Sal","Çar","Per","Cma","Cmt","Pzr" };
+ static const char *months[] = { "Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Ekm","Kas","Ara" };
+ QCString sdate;
+ sdate.sprintf("%s %s %d %d",days[dayOfWeek-1],months[month-1],day,year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+
+};
+
+#endif
diff --git a/src/translator_tw.h b/src/translator_tw.h
new file mode 100644
index 0000000..581d7fe
--- /dev/null
+++ b/src/translator_tw.h
@@ -0,0 +1,1973 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The translation into Chinesetraditional was provided by
+ * Daniel YC Lin (dlin.tw <at> gmail.com) since v1.2.16-v1.5.5
+ */
+
+#ifndef TRANSLATOR_TW_H
+#define TRANSLATOR_TW_H
+
+// When defining a translator class for the new language, follow
+// the description in the documentation. One of the steps says
+// that you should copy the translator_en.h (this) file to your
+// translator_xx.h new file. Your new language should use the
+// Translator class as the base class. This means that you need to
+// implement exactly the same (pure virtual) methods as the
+// TranslatorEnglish does. Because of this, it is a good idea to
+// start with the copy of TranslatorEnglish and replace the strings
+// one by one.
+//
+// It is not necessary to include "translator.h" or
+// "translator_adapter.h" here. The files are included in the
+// language.cpp correctly. Not including any of the mentioned
+// files frees the maintainer from thinking about whether the
+// first, the second, or both files should be included or not, and
+// why. This holds namely for localized translators because their
+// base class is changed occasionaly to adapter classes when the
+// Translator class changes the interface, or back to the
+// Translator class (by the local maintainer) when the localized
+// translator is made up-to-date again.
+
+class TranslatorChinesetraditional : public Translator
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "chinese-traditional"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "相關函式"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(註:這些不是成員函式)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "詳細描述"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "型態定義成員說明文件"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "列舉型態成員說明文件"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "函式成員說明文件"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "欄位說明文件";
+ }
+ else
+ {
+ return "資料成員說明文件";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "更多..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "全部成員列表"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "成員列表"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "完整成員列表,類別為"; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", 包含所有繼承的成員"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="本文件由Doxygen";
+ if (s) result+=(QCString)" 自 "+s;
+ result+=" 的原始碼中自動產生.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "列舉型態名稱"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "列舉值"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "被定義於"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "模組"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "類別階層"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料結構";
+ }
+ else
+ {
+ return "複合列表";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "檔案列表"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料欄位";
+ }
+ else
+ {
+ return "複合成員";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "全域資料";
+ }
+ else
+ {
+ return "檔案成員";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "相關頁面"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "範例"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "搜尋"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "這個繼承列表經過簡略的字母排序: ";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="這是附帶簡略說明";
+ if (!extractAll) result+="且經過文件化";
+ result+="的檔案列表:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "這是附帶簡略說明的資料結構:";
+ }
+ else
+ {
+ return "這是附帶簡略說明的類別,結構,"
+ "聯合型態(unions)及介面(interfaces):";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="這是全部";
+ if (!extractAll)
+ {
+ result+="文件化過";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="結構及聯合型態欄位";
+ }
+ else
+ {
+ result+="類別成員";
+ }
+ result+=", 並且帶有連結至";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="每個欄位的結構/聯合型態說明文件:";
+ }
+ else
+ {
+ result+="每個成員的類別說明文件:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="這些結構/聯合型態所屬:";
+ }
+ else
+ {
+ result+="這些類別所屬:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="這是全部";
+ if (!extractAll) result+="文件化的";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="函式,變數,定義,列舉,及型態定義";
+ }
+ else
+ {
+ result+="檔案成員";
+ }
+ result+=",並且帶有連結至";
+ if (extractAll)
+ result+="這些檔案所屬:";
+ else
+ result+="說明文件:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "所有範例列表:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "所有相關文件頁面列表:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "所有模組列表:"; }
+
+ // index titles (the project name is prepended for these)
+
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "說明文件"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "模組索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "階層索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料結構索引";
+ }
+ else
+ {
+ return "複合索引";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "檔案索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "模組說明文件"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料結構說明文件";
+ }
+ else
+ {
+ return "類別說明文件";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "檔案說明文件"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "範例說明文件"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "頁面說明文件"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "參考手冊"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "定義"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "型態定義"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "列舉型態"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "函式"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "變數"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "列舉值"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "定義巨集說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "型態定義說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "列舉型態說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "列舉值說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "函式說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "變數說明文件"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料結構";
+ }
+ else
+ {
+ return "複合項目";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"產生日期:"+date;
+ if (projName) result+=(QCString)", 專案:"+projName;
+ result+=(QCString)", 產生器:";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"類別"+clName+"的繼承圖:";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "僅供內部使用."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "警告"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "版本"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "日期"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "傳回值"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "參閱"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "參數"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "例外"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "產生者:"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "命名空間(name space)列表"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="這是所有附帶簡略說明的";
+ if (!extractAll) result+="文件化的";
+ result+="命名空間(namespaces):";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "類別朋友(Friends)"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "類別朋友及相關函式說明文件"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName+" ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" 類別"; break;
+ case ClassDef::Struct: result+=" 結構"; break;
+ case ClassDef::Union: result+=" 聯合"; break;
+ case ClassDef::Interface: result+=" 介面"; break;
+ case ClassDef::Protocol: result+=" 協定"; break;
+ case ClassDef::Category: result+=" 分類"; break;
+ case ClassDef::Exception: result+=" 例外"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" 樣版";
+ result+=" 參考文件";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" 檔案參考文件";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" 命名空間(Namespace)參考文件";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "公開方法(Public Methods)"; }
+ virtual QCString trPublicSlots()
+ { return "公開插槽(Public Slots)"; }
+ virtual QCString trSignals()
+ { return "訊號(Signals)"; }
+ virtual QCString trStaticPublicMembers()
+ { return "靜態公開方法(Static Public Methods)"; }
+ virtual QCString trProtectedMembers()
+ { return "保護方法(Protected Methods)"; }
+ virtual QCString trProtectedSlots()
+ { return "保護插槽(Protected Slots)"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "靜態保護方法(Static Protected Methods)"; }
+ virtual QCString trPrivateMembers()
+ { return "私有方法(Private Methods)"; }
+ virtual QCString trPrivateSlots()
+ { return "私有插槽(Private Slots)"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "靜態私有方法(Static Private Methods)"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", 及 ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "繼承自 "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "被 "+trWriteList(numEntries)+"繼承.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "依據"+trWriteList(numEntries)+"重新實作.";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "在"+trWriteList(numEntries)+"重新實作.";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "命名空間(Namespace)成員"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="此處列表為所有 ";
+ if (!extractAll) result+="文件化的 ";
+ result+="命名空間(namespace)成員,並且附帶連結至 ";
+ if (extractAll)
+ result+="每個成員的說明文件:";
+ else
+ result+="該命名空間所屬之處:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "命名空間(Namespace)索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "命名空間(Namespace)說明文件"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "命名空間(Namespaces)"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"此";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="類別(class)"; break;
+ case ClassDef::Struct: result+="結構(structure)"; break;
+ case ClassDef::Union: result+="聯合(union)"; break;
+ case ClassDef::Interface: result+="介面(interface)"; break;
+ case ClassDef::Protocol: result+="協定(protocol)"; break;
+ case ClassDef::Category: result+="分類(category)"; break;
+ case ClassDef::Exception: result+="例外(exception)"; break;
+ default: break;
+ }
+ result+=" 文件是由下列檔案中產生";
+ if (single) result+=":"; else result+=":";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "傳回值"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "主頁面"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "定義在 @1 檔案之第 @0 行.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "定義在 @0 檔.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "過時";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)""+clName+"的合作圖:";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)""+fName+"的包含相依圖:";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "建構子與解構子說明文件";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "查看本檔案的原始碼.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "查看本檔案說明文件.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "前置條件";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "後置條件";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "常數";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "初值:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "程式碼";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "圖形化之類別階層";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "查看圖形化之類別階層";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "查看文字化之類別階層";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "頁面索引";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "註";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "公開型態";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料欄位";
+ }
+ else
+ {
+ return "公開屬性";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "靜態公開屬性";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "保護型態";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "保護屬性";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "靜態保護屬性";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "私有型態";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "私有屬性";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "靜態私有屬性";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "待辦事項";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "待辦事項列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "被參考於";
+ }
+ virtual QCString trRemarks()
+ {
+ return "備註";
+ }
+ virtual QCString trAttention()
+ {
+ return "注意";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "本圖顯示出哪些檔案直接或間接include本檔 "
+ ":";
+ }
+ virtual QCString trSince()
+ {
+ return "自";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "圖示";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "本頁解釋如何解譯這些由doxygen所產生的圖示 "
+ ".<p>\n"
+ "請看下面範例:\n"
+ "\\code\n"
+ "/*! 因為截斷的不可見類別 */\n"
+ "class Invisible { };\n\n"
+ "/*! 截斷的類別, 繼承關係被隱藏 */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* 未經過doxygen註解處理過的類別 */\n"
+ "class Undocumented { };\n\n"
+ "/*! 經過公開(Public)繼承的類別 */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! 一個樣版類別 */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! 使用保護(Protected)繼承的類別 */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! 使用私有(Private)繼承的類別 */\n"
+ "class PrivateBase { };\n\n"
+ "/*! 由被繼承類別所使用的類別 */\n"
+ "class Used { };\n\n"
+ "/*! 由數個其他類別所繼承來的超類別(Super Class) */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "若在組態檔中的 \\c MAX_DOT_GRAPH_HEIGHT tag "
+ "設為 240,將會產生下列的圖示:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "上圖中的各區塊意義如下:\n"
+ "<ul>\n"
+ "<li>%A 填滿黑色的區塊代表產生這個圖示的類別或結構 "
+ ".\n"
+ "<li>%A 黑邊的區塊代表文件化過的結構或類別.\n"
+ "<li>%A 灰邊的區塊代表未經文件化的結構或是類別.\n"
+ "<li>%A 紅邊的區塊代表文件化的結構或是類別,"
+ "這些結構或類別的繼承或包含關係不會全部顯示. %A 圖示 "
+ "若無法塞入指定的邊界中將會被截斷.\n"
+ "</ul>\n"
+ "箭頭具有下面的意義:\n"
+ "<ul>\n"
+ "<li>%A 深藍色箭頭用來代表兩個類別間的公開繼承 "
+ "關係.\n"
+ "<li>%A 深綠色箭頭代表保護繼承.\n"
+ "<li>%A 深紅色箭頭代表私有繼承.\n"
+ "<li>%A 紫色箭頭用來表示類別被另一個包含或是使用."
+ "箭頭上標示著可存取該類別或是結構的對應變數"
+ ".\n"
+ "<li>%A 黃色箭頭代表樣版實體與樣版類別之間的關係。"
+ "箭頭上標記著樣版實體上的參數"
+ ".\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "圖示";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "測試項目";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "測試項目列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "屬性(properties)";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "屬性(property)說明文件";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "資料結構";
+ }
+ else
+ {
+ return "類別";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Package "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Package列表";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "此處為Package的概略說明(如果有的話):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Packages";
+ }
+
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "巨集內容:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "臭蟲";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "臭蟲列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "950";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "136";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "索引";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("類別");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("檔案");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("命名空間");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("群組");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("頁面");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("成員");
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("全域");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("作者");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "參考";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "實作 "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "實作於 "+trWriteList(numEntries)+".";
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "目錄";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "過時項目(Deprecated) 列表";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Events";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Event 文件";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Package 型別";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Package 函數列表";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "靜態 Package 函數列表";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Package 屬性";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "靜態 Package 屬性";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "全部";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "這是此函數的引用函數圖:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "搜尋結果";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "找不到符合的資料.";
+ }
+ else if (numDocuments==1)
+ {
+ return "找到 <b>1</b> 筆符合的資料.";
+ }
+ else
+ {
+ return "找到 <b>$num</b> 筆符合的資料. "
+ "越符合的結果顯示在越前面.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "符合:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " 原始程式檔";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "目錄階層"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "目錄說明文件"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "目錄"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "這個目錄階層經過簡略的字母排序: ";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" 目錄參考文件"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool /*first_capital*/, bool /*singular*/)
+ {
+ return QCString("目錄");
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "這是一個為了便利性所提供 overload 成員函數,"
+ "只有在接受的參數上,與前一個函數不同.";
+ }
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "呼叫此函數的函數列表:";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "成員函數/子程序 文件"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "資料型態列表"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "資料欄位"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "資料型態簡短說明列表:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="此處列出所有";
+ if (!extractAll)
+ {
+ result+="有文件的";
+ }
+ result+="資料型別成員函數";
+ result+=" 附帶連結到 ";
+ if (!extractAll)
+ {
+ result+="每個成員函數的資料結構文件";
+ }
+ else
+ {
+ result+="他們屬於的資料型別";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "資料型別索引"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "資料型別文件"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "函數/子程序"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "函數/子程序 文件"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "資料型別"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "模組列表"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="此處列出所有";
+ if (!extractAll) result+="有文件的";
+ result+="模組附帶簡短說明:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+="模組"; break;
+ case ClassDef::Struct: result+="型態"; break;
+ case ClassDef::Union: result+="聯合"; break;
+ case ClassDef::Interface: result+="介面"; break;
+ case ClassDef::Protocol: result+="協議"; break;
+ case ClassDef::Category: result+="分類"; break;
+ case ClassDef::Exception: result+="例外"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+="參考文件";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+="模組參考文件";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "模組成員"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="此處列出所有";
+ if (!extractAll) result+="有文件的";
+ result+="模組成員附帶連結到";
+ if (extractAll)
+ {
+ result+="每個函數的模組文件:";
+ }
+ else
+ {
+ result+="他們所屬的模組:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "模組索引"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool /* first_capital */, bool /* singular */)
+ {
+ QCString result("模組");
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool /* single */)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"這個";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="模組"; break;
+ case ClassDef::Struct: result+="型態"; break;
+ case ClassDef::Union: result+="聯合"; break;
+ case ClassDef::Interface: result+="介面"; break;
+ case ClassDef::Protocol: result+="協議"; break;
+ case ClassDef::Category: result+="分類"; break;
+ case ClassDef::Exception: result+="例外"; break;
+ default: break;
+ }
+ result+="文件由下列檔案產生";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool /* first_capital */, bool /* singular */)
+ {
+ QCString result("型別");
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool /* first_capital */, bool /* singular */)
+ {
+ QCString result("子程式");
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "型別限制條件";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return QCString(name)+" 關連";
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "載入中...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "全域命名空間";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "搜尋中...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "無符合項目";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"檔案在"+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"含入檔案在"+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "星期一","星期二","星期三","星期四","星期五","星期六","星期日" };
+ static const char *months[] = { "1","2","3","4","5","6","7","8","9","10","11","12" };
+ QCString sdate;
+ sdate.sprintf("%d年%s月%d日 %s",year,months[month-1],day,days[dayOfWeek-1]);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "參考文獻資料"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "版權聲明"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString(name)+"的目錄關連圖"+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "詳細程度"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "樣版參數"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "及 "+number+" 個更多..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "此列舉型態的文件是由下列檔案所產生";
+ if (!single) result += "";
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" 列舉型態參考"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" 繼承自 "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "額外的繼承成員"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "啟用" : "停用";
+ return "點擊 "+opt+" 面板進行同步";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "由 @1 分類所提供.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "延伸 @1 類別 .";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "類別方法";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "實體方法";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "方法文件";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "設計概述";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.4
+//////////////////////////////////////////////////////////////////////////
+
+ /** old style UNO IDL services: implemented interfaces */
+ virtual QCString trInterfaces()
+ { return "導出介面"; }
+
+ /** old style UNO IDL services: inherited services */
+ virtual QCString trServices()
+ { return "引入的服務"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroups()
+ { return "常數群組"; }
+
+ /** UNO IDL constant groups */
+ virtual QCString trConstantGroupReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+="常數群組參考";
+ return result;
+ }
+ /** UNO IDL service page title */
+ virtual QCString trServiceReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+="服務參考";
+ return result;
+ }
+ /** UNO IDL singleton page title */
+ virtual QCString trSingletonReference(const char *sName)
+ {
+ QCString result=(QCString)sName;
+ result+="Singleton參考";
+ return result;
+ }
+ /** UNO IDL service page */
+ virtual QCString trServiceGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"本服務的文件由以下的檔案"
+ "所產生";
+ if (single) result+=":"; else result+=":";
+ return result;
+ }
+ /** UNO IDL singleton page */
+ virtual QCString trSingletonGeneratedFromFiles(bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"本singleton的文件由下面的檔案"
+ "所產生";
+ if (single) result+=":"; else result+=":";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
diff --git a/src/translator_ua.h b/src/translator_ua.h
new file mode 100644
index 0000000..b7ca86a
--- /dev/null
+++ b/src/translator_ua.h
@@ -0,0 +1,1917 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * The translation into Ukrainian was provided by
+ * Olexij Tkatchenko (olexij.tkatchenko at parcs.de)
+ * Petro Yermolenko (python at i.ua)
+ */
+
+#ifndef TRANSLATOR_UA_H
+#define TRANSLATOR_UA_H
+
+class TranslatorUkrainian : public TranslatorAdapter_1_8_4
+{
+ public:
+ /*! Used for identification of the language. */
+ virtual QCString idLanguage()
+ { return "ukrainian"; }
+
+ /* Used to get the command(s) for the language support. */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[T2A]{fontenc}\n\\usepackage[ukrainian]{babel}\n";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Споріднені фукції"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(не методи компонент)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Детальний опис"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Опис типів користувача"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Опис переліків користувача"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Опис методів компонент"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля" ;
+ }
+ else
+ {
+ return "Компонентні дані" ;
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Детальніше..."; }
+
+ /*! put in the class documentation */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trListOfAllMembers()
+ {
+ return "Список всіх елементів" ;
+ }
+
+ /*! used as the title of the "list of all members" page of a class */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trMemberList()
+ {
+ return "Cписок елементів" ;
+ }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Повний список елементів"; }
+
+ /*! this is the remainder of the sentence after the class name */
+ /* Dosn't use when optimization for C is on. */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", включаючи всі успадковані елементи"; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Автоматично створено за допомогою Doxygen";
+ if (s) result+=QCString(" для ")+s;
+ result+=" з тексту програми.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "Перелік"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "Елемент переліку"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "визначено в "; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Програмні модулі"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Ієрархія класів"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури даних" ;
+ }
+ else
+ {
+ return "Класи" ;
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Файли"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля структур" ;
+ }
+ else
+ {
+ return "Елементи класів" ;
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ /*??*/
+ virtual QCString trFileMembers()
+ {
+ return "Елементи файлу" ;
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ /* ?? Вариант перевода "См. также: " более удачный, но не в заголовке,
+ как в данном случае. */
+ { return "Додаткова інформація"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Приклади"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Пошук"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Список успадкувань впорядковано наближено до алфавіту"; }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Повний список ";
+ if (!extractAll) result+="документованих ";
+ result+="файлів.";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури даних з коротким описом." ;
+ }
+ else
+ {
+ return "Класи, структури, об'єднання та інтерфейси з коротким описом." ;
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Список всіх ";
+ if(!extractAll) result+="документоаних ";
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="елементів структур даних з посиланням на ";
+ else
+ result+="елементів класів даних з посиланням на ";
+ if(extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result+="документацію по структурі/об'єднанню кожного елементу.";
+ else
+ result+="документацію по класу кожного елементу.";
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ result += "відповідні структури";
+ else
+ result += "відповідні класи";
+ result+=", до яких вони належать.";
+ }
+ return result ;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Список всіх ";
+ if (!extractAll) result+="документованих ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="функцій, змінних, макровизначень, "
+ "переліків і визначень типів";
+ }
+ else
+ {
+ result+="елементів файлів ";
+ }
+ result+=" з посиланям на ";
+ if (extractAll)
+ result+="файли, до яких вони належать.";
+ else
+ result+="документацію.";
+ return result ;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Повний список прикладів."; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Повний список додаткових описів."; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Повний список модулів."; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Документація"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Алфавітний покажчик модулів"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Ієрархічний покажчик класів"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Алфавітний покажчик структур даних" ;
+ }
+ else
+ {
+ return "Алфавітний покажчик класів" ;
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Покажчик файлв" ; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Програмні Модулі"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури даних" ;
+ }
+ else
+ {
+ return "Класи" ;
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Файли"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Приклади"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Документація по темі"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Довідковий посібник"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Макровизначення"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Визначення типів"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Переліки"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Функції"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Змінні"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Елементи переліків"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Опис макровизначень"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Опис визначень типів"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Опис переліків"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Опис функцій"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Опис змінних"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури даних" ;
+ }
+ else
+ {
+ return "Класи" ;
+ }
+
+ }
+
+ /*! This is used in the documentation of a group before the list of
+ * links to documented files
+ */
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result="Документація ";
+ if (projName) result+=QCString("до ")+projName;
+ result+=QCString(" створена ")+date;
+ result+=" системою";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return QCString("Схема успадкувань для ")+clName;
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Тільки для внутрішнього користування"; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Застереження"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Версія"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Дата"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Повертає"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Див. також"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Аргументи"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Обробка виняткових ситуацій"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Створено системою"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Простір імен"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Повний список ";
+ if (!extractAll) result+="документованих ";
+ result+="просторів імен.";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Дружні класи"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Документация до дружніх класів та відповідних функцій"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result;
+ if (isTemplate)
+ {
+ result="Шаблон ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="класу"; break;
+ case ClassDef::Struct: result+="структури"; break;
+ case ClassDef::Union: result+="об'єднання"; break;
+ case ClassDef::Interface: result+="інтерфейсу"; break;
+ case ClassDef::Protocol: result+="протоколу"; break;
+ case ClassDef::Category: result+="категорії"; break;
+ case ClassDef::Exception: result+="Виняток"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Клас"; break;
+ case ClassDef::Struct: result+="Структура"; break;
+ case ClassDef::Union: result+="Об'єднання"; break;
+ case ClassDef::Interface: result+="Інтерфейс"; break;
+ case ClassDef::Protocol: result+="Протокол"; break;
+ case ClassDef::Category: result+="Категорія"; break;
+ case ClassDef::Exception: result+="Виняток"; break;
+ default: break;
+ }
+ }
+ result+=" ";
+ return result+clName;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ return QCString("Файл ")+fileName;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ return QCString("Простір імен ")+namespaceName;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Загальнодоступні елементи"; }
+ virtual QCString trPublicSlots()
+ { return "Загальнодоступні слоти"; }
+ virtual QCString trSignals()
+ { return "Сигнали"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Загальнодоступні статичні елементи"; }
+ virtual QCString trProtectedMembers()
+ { return "Захищені елементи"; }
+ virtual QCString trProtectedSlots()
+ { return "Захищені слоти"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Захищені статичні елементи"; }
+ virtual QCString trPrivateMembers()
+ { return "Приватні елементи"; }
+ virtual QCString trPrivateSlots()
+ { return "Приватні слоти"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Приватні статичні елементи"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+= " і " ;
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Успадковує клас "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Успадковано класами "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Переозначення з "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Переозначається в "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Елементи простору імен"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Повний список ";
+ if (!extractAll) result+="документованих ";
+ result+="елеметів простору імен з посиланням ";
+ if (extractAll)
+ result+="на документацію для кожного елементу:";
+ else
+ result+="на простір імен до якого вони належать:";
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Алфавітний покажчик простору імен"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Опис простору імен"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Простори імен" ; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Документація ";
+ switch(compType)
+ {
+ case ClassDef::Class:
+ if (single) result+="цього класу"; else result+="цих класів";
+ break;
+ case ClassDef::Struct:
+ if (single) result+="цієї структури"; else result+="цих структур";
+ break;
+ case ClassDef::Union:
+ if (single) result+="цього об'єднання"; else result+="цих об'єднань";
+ break;
+ case ClassDef::Interface:
+ if (single) result+="цього інтерфейсу"; else result+="цих інтерфейсів";
+ break;
+ case ClassDef::Protocol:
+ if (single) result+="цього протоколу"; else result+="цих протоколів";
+ break;
+ case ClassDef::Category:
+ if (single) result+="цієї категорії"; else result+="цих категорій";
+ break;
+ case ClassDef::Exception:
+ if (single) result+="цього винятку"; else result+="цих винятків";
+ break;
+ default:
+ break;
+ }
+ result+=" була створена з файл";
+ if (single) result+="у:"; else result+="ів:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Значення, що повертаються"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Титульна сторінка"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "стор."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Див. визначення в файлі @1, рядок @0";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Див. визначення в файлі @0";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Не рекомендовано";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Діаграма зв'язків класу "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return QCString("Діаграма включених заголовочних файлів для ")+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Конструктор(и)";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Див. вихідні тексти.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Див. документацію.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Передумови";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Післяумови";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Інваріант";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Початкові значення";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "Вихідні тексти";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Графічна ієрархія класів";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "див. графічну ієрархію";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "див. текстову ієрархію";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Алфавітний покажчик тематичних описів";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Нотатки";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Загальнодоступні типи";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Поля даних" ;
+ }
+ else
+ {
+ return "Загальнодоступні атрибути" ;
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Статичні загальнодоступні данні";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Захищені типи";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Захищені дані";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Статичні захищені дані";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Приватні типи";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Приватні дані";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Приватні статичні дані";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ /*??*/
+ {
+ return "Необхідно зробити";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ /*??*/
+ {
+ return "Список завдань";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Вживається в";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Прим.";
+ }
+ virtual QCString trAttention()
+ {
+ return "Увага";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Граф файлів, які включають цей файл:";
+ }
+ virtual QCString trSince()
+ /*??*/
+ {
+ return "Починаючи з";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Легенда";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Позначення, що використовуються у графах.<p>\n"
+ "Розглянемо наступний приклад:\n"
+ "\\code\n"
+ "/*! Невидимий клас через зрізання */\n"
+ "class Invisible { };\n\n"
+ "/*! Обмежений клас, відношення успадкування приховане */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Недокументований клас */\n"
+ "class Undocumented { };\n\n"
+ "/*! Загальнодоступне успадкування */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! A template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Захищене успадкування */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Приватне успадкування */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Клас, що використовується класом Inherited */\n"
+ "class Used { };\n\n"
+ "/*! Клас, що успадковує інші класи */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Таким чином, отримуємо наступний граф:"
+ "<p><center><img src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Прямокутники в цьому графі мають наступний зміст:\n"
+ "<ul>\n"
+ "<li>Заповнений чорний прямокутник відображає структуру або клас, "
+ "для якого створено граф.\n"
+ "<li>Прямокутник з чорною межею відображає документовану структуру або клас.\n"
+ "<li>Прямокутник з сірою межею відображає недокументовану структуру або клас.\n"
+ "<li>Прямокутник з червоною межею відображає документовану структуру або клас, для яких\n"
+ " не всі співвідношення успадкування/змісту показані. Граф зрізаниЙ, "
+ "якщо він не вміщається у вказані межі."
+ "</ul>\n"
+ "Стрілки мають наступний зміст:\n"
+ "<ul>\n"
+ "<li>Темносиня стрілка відображає відношення загальнодоступного успадкування "
+ "між двома класами.\n"
+ "<li>Темнозелена стрілка використовується при захищеному успадкуванні.\n"
+ "<li>Темночервона стрілка використовується при приватному успадкуванні.\n"
+ "<li>Пурпурна стрілка використовується, якщо клас міститься в"
+ "іншому класі або ним використовується."
+ "Стрілка етикетується змінною, "
+ "через яку відбувається доступ до вказаної структури або класу. \n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "див. легенду";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Тест";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Список тестів";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Властивості";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Повний список властивостей";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Структури даних" ;
+ }
+ else
+ {
+ return "Класи" ;
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return QCString("Пакет ")+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Повний список пакетів";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Повний список документованих пакетів.";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Пакети";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Макровизначення:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Дефект";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Список дефектів";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+ /*! Used as ansicpg for RTF file */
+ virtual QCString trRTFansicp()
+ {
+ return "1251";
+ }
+ /*! Used as ansicpg for RTF fcharset */
+ virtual QCString trRTFCharSet()
+ {
+ return "204";
+ }
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Предметний покажчик";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ QCString result((first_capital ? "Структури даних" : "структури даних"));
+ return result;
+ }
+ else
+ {
+ QCString result((first_capital ? "Клас" : "клас"));
+ if(!singular) result+="и";
+ return result;
+ }
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Файл" : "файл"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Прост" : "прост"));
+ result+=(singular?"ір імен":"ори імен");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Груп" : "груп"));
+ result+=(singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Сторінк" : "сторінк"));
+ result+=(singular ? "а" : "и");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Елемент" : "елемент"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Глобальн" : "глобальн"));
+ result+=(singular ? "ий" : "і");
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Автор" : "автор"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Використовує";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Реалізує " + trWriteList(numEntries) + ".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Реалізує в " + trWriteList(numEntries) + ".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Зміст";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Застарілі елементи";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Події";
+ }
+
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Документація подій";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Типи пакетів";
+ }
+
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Функції пакетів";
+ }
+
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Статичні функцію пакетів";
+ }
+
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Атрибути пакетів";
+ }
+
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Статичні атрибути пакетів";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Всі";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Граф всіх викликів цієї функції:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Результати пошуку";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Не знайдено документів відповідно до вашого запиту.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Було знайдено <b>1</b> документ відповідно до вашого запиту.";
+ }
+ else
+ {
+ return "Було знайдено <b>$num</b> документів відповідно до вашого запиту. "
+ "Найкращі відповідності показано спочатку.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Відповідність:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return "Текст програми "+filename;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Дерево каталогів"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Документація каталогів"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Каталоги"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Дерево каталогів впорядковано наближено "
+ "до алфавіту:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result="Довідник каталогу "; result+=dirName; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool, bool singular)
+ {
+ QCString result("Каталог");
+ if (!singular) result+="и";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Це перезавантажуваний метод, "
+ "ввкдкний для зручності. Він відрізняється від "
+ "описаної вище функції лише списком аргуметнів.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Граф викликів для цієї функції:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Документація переліку"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Документація функції/підпрограми"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Список типів даних"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Поля даних"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Типи даних з коротким описом:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Список усіх ";
+ if (!extractAll)
+ {
+ result+="задокументованих ";
+ }
+ result+="елементів типів даних";
+ result+=" з посиланнями на ";
+ if (!extractAll)
+ {
+ result+="документацію структури даних кожного елемента";
+ }
+ else
+ {
+ result+="типи даних, до яких вони належать:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Список типів даних"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Документація типів даних"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Функції/підпрограми"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Документація функцій/підпрограм"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Типи даних"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Список модулів"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Список усіх ";
+ if (!extractAll) result+="задокументованих ";
+ result+="модулів з коротким описом:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate)
+ {
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Модуль"; break;
+ case ClassDef::Struct: result+=" Тип"; break;
+ case ClassDef::Union: result+=" Об'єднання"; break;
+ case ClassDef::Interface: result+=" Інтерфейс"; break;
+ case ClassDef::Protocol: result+=" Протокол"; break;
+ case ClassDef::Category: result+=" Категорія"; break;
+ case ClassDef::Exception: result+=" Виняток"; break;
+ default: break;
+ }
+ }
+ else
+ {
+ if (isTemplate) result+=" Шаблон ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="модуля"; break;
+ case ClassDef::Struct: result+="типу"; break;
+ case ClassDef::Union: result+="об'єднання"; break;
+ case ClassDef::Interface: result+="інтерфейсу"; break;
+ case ClassDef::Protocol: result+="протоколу"; break;
+ case ClassDef::Category: result+="категорії"; break;
+ case ClassDef::Exception: result+="винятка"; break;
+ default: break;
+ }
+ }
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Модуль";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Елементи модуля"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Список усіх ";
+ if (!extractAll) result+="задокументованих ";
+ result+="елементів модулів з посиланнями на ";
+ if (extractAll)
+ {
+ result+="документацію модуля для кожного елемента:";
+ }
+ else
+ {
+ result+="модулі, до яких вони належать:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Алфавітний покажчик модулів"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Модул" : "модул"));
+ result+=(singular? "ь": "і");
+ return result;
+ }
+
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"Документацію для ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="цього модуля"; break;
+ case ClassDef::Struct: result+="цього типу"; break;
+ case ClassDef::Union: result+="цього об'єднання"; break;
+ case ClassDef::Interface: result+="цього інтерфейсу"; break;
+ case ClassDef::Protocol: result+="цього протоколу"; break;
+ case ClassDef::Category: result+="цієї категорії"; break;
+ case ClassDef::Exception: result+="цього винятку"; break;
+ default: break;
+ }
+ result+=" було згенеровано з ";
+ if (single) result+="наступного файлу:"; else result+="наступних файлів:";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Тип" : "тип"));
+ if (!singular) result+="и";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Підпрограм" : "підпрограм"));
+ result+= (singular? "а": "и");
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Обмеження типу";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.0 (mainly for the new search engine)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! directory relation for \a name */
+ virtual QCString trDirRelation(const char *name)
+ {
+ return "Зв'язок з "+QCString(name);
+ }
+
+ /*! Loading message shown when loading search results */
+ virtual QCString trLoading()
+ {
+ return "Завантаження...";
+ }
+
+ /*! Label used for search results in the global namespace */
+ virtual QCString trGlobalNamespace()
+ {
+ return "Глобальний простір імен";
+ }
+
+ /*! Message shown while searching */
+ virtual QCString trSearching()
+ {
+ return "Пошук...";
+ }
+
+ /*! Text shown when no search results are found */
+ virtual QCString trNoMatches()
+ {
+ return "Нічого не знайдено";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.6.3 (missing items for the directory pages)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the first column mentions the
+ * source file that has a relation to another file.
+ */
+ virtual QCString trFileIn(const char *name)
+ {
+ return (QCString)"Файл у "+name;
+ }
+
+ /*! when clicking a directory dependency label, a page with a
+ * table is shown. The heading for the second column mentions the
+ * destination file that is included.
+ */
+ virtual QCString trIncludesFileIn(const char *name)
+ {
+ return (QCString)"Включає файли в "+name;
+ }
+
+ /** Compiles a date string.
+ * @param year Year in 4 digits
+ * @param month Month of the year: 1=January
+ * @param day Day of the Month: 1..31
+ * @param dayOfWeek Day of the week: 1=Monday..7=Sunday
+ * @param hour Hour of the day: 0..23
+ * @param minutes Minutes in the hour: 0..59
+ * @param seconds Seconds within the minute: 0..59
+ * @param includeTime Include time in the result string?
+ */
+ virtual QCString trDateTime(int year,int month,int day,int dayOfWeek,
+ int hour,int minutes,int seconds,
+ bool includeTime)
+ {
+ static const char *days[] = { "Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота","Неділя" };
+ static const char *months[] = { "січня","лютого","березня","квітня","травня","червня","липня","серпня","вересня","жотня","листопада","грудня" };
+ QCString sdate;
+ sdate.sprintf("%s, %d %s %d",days[dayOfWeek-1],day,months[month-1],year);
+ if (includeTime)
+ {
+ QCString stime;
+ stime.sprintf(" %.2d:%.2d:%.2d",hour,minutes,seconds);
+ sdate+=stime;
+ }
+ return sdate;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.7.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Header for the page with bibliographic citations */
+ virtual QCString trCiteReferences()
+ { return "Бібліографічні посилання"; }
+
+ /*! Text for copyright paragraph */
+ virtual QCString trCopyright()
+ { return "Копірайт"; }
+
+ /*! Header for the graph showing the directory dependencies */
+ virtual QCString trDirDepGraph(const char *name)
+ { return QCString("Граф залежностей каталогу для ")+name+":"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Detail level selector shown for hierarchical indices */
+ virtual QCString trDetailLevel()
+ { return "рівень елемента"; }
+
+ /*! Section header for list of template parameters */
+ virtual QCString trTemplateParameters()
+ { return "Параметри шаблона"; }
+
+ /*! Used in dot graph when UML_LOOK is enabled and there are many fields */
+ virtual QCString trAndMore(const QCString &number)
+ { return "і ще "+number+"..."; }
+
+ /*! Used file list for a Java enum */
+ virtual QCString trEnumGeneratedFromFiles(bool single)
+ { QCString result = "Документацію для цього переліку булозгенеровано з ";
+ result += (single? "наступного файла": "наступних файлів");
+ result+=":";
+ return result;
+ }
+
+ /*! Header of a Java enum page (Java enums are represented as classes). */
+ virtual QCString trEnumReference(const char *name)
+ { return QCString(name)+" Перелік"; }
+
+ /*! Used for a section containing inherited members */
+ virtual QCString trInheritedFrom(const char *members,const char *what)
+ { return QCString(members)+" успадковано з "+what; }
+
+ /*! Header of the sections with inherited members specific for the
+ * base class(es)
+ */
+ virtual QCString trAdditionalInheritedMembers()
+ { return "Додаткові успадковані елементи"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.8.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a tooltip for the toggle button that appears in the
+ * navigation tree in the HTML output when GENERATE_TREEVIEW is
+ * enabled. This tooltip explains the meaning of the button.
+ */
+ virtual QCString trPanelSynchronisationTooltip(bool enable)
+ {
+ QCString opt = enable ? "дозволити" : "заборонити";
+ return "клацніть мишкою, щоб "+opt+" синхронізацію панелі";
+ }
+
+ /*! Used in a method of an Objective-C class that is declared in a
+ * a category. Note that the @1 marker is required and is replaced
+ * by a link.
+ */
+ virtual QCString trProvidedByCategory()
+ {
+ return "Забезпечено категорією @1.";
+ }
+
+ /*! Used in a method of an Objective-C category that extends a class.
+ * Note that the @1 marker is required and is replaced by a link to
+ * the class method.
+ */
+ virtual QCString trExtendsClass()
+ {
+ return "Розширює клас @1.";
+ }
+
+ /*! Used as the header of a list of class methods in Objective-C.
+ * These are similar to static public member functions in C++.
+ */
+ virtual QCString trClassMethods()
+ {
+ return "Методи класу";
+ }
+
+ /*! Used as the header of a list of instance methods in Objective-C.
+ * These are similar to public member functions in C++.
+ */
+ virtual QCString trInstanceMethods()
+ {
+ return "Методи об'єкта";
+ }
+
+ /*! Used as the header of the member functions of an Objective-C class.
+ */
+ virtual QCString trMethodDocumentation()
+ {
+ return "Документація метода";
+ }
+
+ /*! Used as the title of the design overview picture created for the
+ * VHDL output.
+ */
+ virtual QCString trDesignOverview()
+ {
+ return "Огляд дизайну проекту";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+
+};
+
+#endif
+
diff --git a/src/translator_vi.h b/src/translator_vi.h
new file mode 100644
index 0000000..54c68b8
--- /dev/null
+++ b/src/translator_vi.h
@@ -0,0 +1,1743 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_VI_H
+#define TRANSLATOR_VI_H
+
+/*
+ * 17 Oct 2008 : Translation to Vietnamese by
+ * Đặng Minh Tuấn <tuanvietkey at gmail.com>
+ *
+ */
+
+
+/*!
+ When defining a translator class for the new language, follow
+ the description in the documentation. One of the steps says
+ that you should copy the translator_en.h (this) file to your
+ translator_xx.h new file. Your new language should use the
+ Translator class as the base class. This means that you need to
+ implement exactly the same (pure virtual) methods as the
+ TranslatorEnglish does. Because of this, it is a good idea to
+ start with the copy of TranslatorEnglish and replace the strings
+ one by one.
+
+ It is not necessary to include "translator.h" or
+ "translator_adapter.h" here. The files are included in the
+ language.cpp correctly. Not including any of the mentioned
+ files frees the maintainer from thinking about whether the
+ first, the second, or both files should be included or not, and
+ why. This holds namely for localized translators because their
+ base class is changed occasionaly to adapter classes when the
+ Translator class changes the interface, or back to the
+ Translator class (by the local maintainer) when the localized
+ translator is made up-to-date again.
+*/
+class TranslatorVietnamese : public TranslatorAdapter_1_6_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "vietnamese"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The English LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Những hàm liên quan"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Chú ý những hàm này không phải là hàm thành viên.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Mô tả chi tiết"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Thông tin về Member Typedef"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Thông tin về Member Enumeration"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Thông tin về hàm thành viên"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Thông tin về trường";
+ }
+ else
+ {
+ return "Thông tin về Member Data";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Tiếp..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Liệt kê tất cả các thành viên"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Danh sách thành viên"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Danh sách các thành viên đầy đủ cho "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", cùng với tất cả các thành viên kế thừa."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Được tạo ra bởi Doxygen";
+ if (s) result+=(QCString)" cho "+s;
+ result+=" từ mã nguồn.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "tên enum"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "giá trị enum"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "được định nghĩa trong"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Các Modules"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Kiến trúc Class"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Cấu trúc cơ sở dữ liệu (Data Structures)";
+ }
+ else
+ {
+ return "Danh mục các Class";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Danh mục File"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Các trường dữ liệu";
+ }
+ else
+ {
+ return "Các thành viên của Class";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Toàn cục";
+ }
+ else
+ {
+ return "File thành viên";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Các trang liên quan"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Các ví dụ"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Tìm kiếm"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ { return "Danh sách kế thừa đã được sắp xếp theo ABC, "
+ "nhưng chưa đầy đủ:";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Danh mục đầy đủ tất cả các ";
+ if (!extractAll) result+="(đã được biên soạn) ";
+ result+="files cùng với các mô tả tóm tắt:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Đây là cấu trúc cơ sở dữ liệu với mô tả tóm tắt:";
+ }
+ else
+ {
+ return "Đây là các classes, structs, "
+ "unions và interfaces với các mô tả tóm tắt:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="Danh mục tất cả các ";
+ if (!extractAll)
+ {
+ result+="(đã được mô tả) ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct và union fields";
+ }
+ else
+ {
+ result+="class members";
+ }
+ result+=" cùng với các các liên kết đến ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="Thông tin về struct/union cho từng trường:";
+ }
+ else
+ {
+ result+="Thông tin về class cho từng thành viên:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="các structures/unions thuộc:";
+ }
+ else
+ {
+ result+="các lớp thuộc:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="Danh sách tất cả các ";
+ if (!extractAll) result+="(đã được mô tat) ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="functions, variables, defines, enums, và typedefs";
+ }
+ else
+ {
+ result+="các file thành viên";
+ }
+ result+=" cùng với links tới ";
+ if (extractAll)
+ result+="các files thuộc:";
+ else
+ result+="tài liệu:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "Danh sách tất cả các ví dụ:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "Danh sách tất cả các trang Thông tin có liên quan:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "Danh sách tất cả các thành viên:"; }
+
+ // index titles (the project name is prepended for these)
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Thông tin"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Chỉ mục (Index) Module"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierarchical Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Index cấu trúc cơ sở dữ liệu";
+ }
+ else
+ {
+ return "Class Index";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "File Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Thông tin về các Module"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Thông tin về cấu trúc cơ sở dữ liệu";
+ }
+ else
+ {
+ return "Thông tin về Class";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Thông tin về File"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Thông tin về các ví dụ"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Trang Thông tin"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Thông tin tham chiếu"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Định nghĩa"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefs"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerations"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Các hàm"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Các biến"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumerator"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Thông tin về định nghĩa"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Thông tin về Typedef"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Thông tin về Enumeration Type"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Thông tin về hàm"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Thông tin về các biến"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Cấu trúc cơ sở dữ liệu";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Được biên soạn vào "+date;
+ if (projName) result+=(QCString)" cho mã nguồn dự án "+projName;
+ result+=(QCString)" bởi";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Sơ đồ kế thừa cho "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Chỉ cho sử dụng nội bộ."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Lưu ý"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Phiên bản"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Ngày"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Giá trị trả về"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Xem thêm"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Các tham số"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Exceptions"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Được biên soạn bởi"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Danh sách Namespace"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="Danh sách tất cả các ";
+ if (!extractAll) result+="(đã được biên tập) ";
+ result+="namespaces với mô tả tóm tắt:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Thông tin về Friends và các hàm liên quan"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Class"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Tham chiếu";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" File Tham chiếu";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Tham chiếu";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Các hàm thành viên Public"; }
+ virtual QCString trPublicSlots()
+ { return "Public Slots"; }
+ virtual QCString trSignals()
+ { return "Signals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Các hàm Static Public"; }
+ virtual QCString trProtectedMembers()
+ { return "Các hàm thành viên Protected"; }
+ virtual QCString trProtectedSlots()
+ { return "Protected Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Các hàm thành viên Static Protected"; }
+ virtual QCString trPrivateMembers()
+ { return "Các hàm thành viên Private"; }
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Các hàm thành viên Static Private"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", và ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Kế thừa "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Được kế thừa bởi "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Được thực thi lại từ "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Được thực thi lại trong "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Thành viên Namespace"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="Danh sách tất cả các ";
+ if (!extractAll) result+="(đã được biên soạn) ";
+ result+="các thành viên namespace cùng với link tới ";
+ if (extractAll)
+ result+="Thông tin namespace cho từng thành viên:";
+ else
+ result+=" namespaces mà phụ thuộc bởi:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespace Index"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Thông tin về Namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Thông tin cho ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="class"; break;
+ case ClassDef::Struct: result+="struct"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" được biên soạn từ các file sau đây";
+ if (single) result+=":"; else result+=":";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Các giá trị trả về"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Tranh chính"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "tr."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Định nghĩa tại dòng @0 trong file @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Định nghĩa trong file @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Không tán thành";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Sơ đồ liên kết cho "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Kèm theo graph phụ thuộc cho "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Thông tin về Constructor và Destructor";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Tới mã nguồn của file này.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Tới Thông tin của file này.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Điều kiện trước";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Điều kiện sau";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Bất biến";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Giá trị khởi tạo:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "mã nguồn";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Kiến trúc đồ họa của Class";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Tới kiến trúc đồ họa của Class";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Tới kiến trúc text của Class";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Chỉ mục trang";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Ghi chú";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Public Types";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "các trường đữ liệu";
+ }
+ else
+ {
+ return "Các thuộc tính Public";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Các thuộc tính Static Public";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Các kiểu Protected";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "các thuộc tính Protected";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Các thuộc tính Static Protected";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Các kiểu Private";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Các thuộc tính Private";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Các thuộc tính Static Private";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Mục tiêu";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Danh sách hàng mục cần thực hiện";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Tham chiếu bởi";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Ghi chú";
+ }
+ virtual QCString trAttention()
+ {
+ return "Chú ý";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Đồ thị này biểu thị những file nào trực tiếp hoặc"
+ "không trực tiếp bao gồm file này:";
+ }
+ virtual QCString trSince()
+ {
+ return "Từ";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Chú giải Graph";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Trang này giải nghĩa các biểu đồ được biên soạn bởi "
+ " doxygen.<p>\n"
+ "Hãy xem xét các ví dụ sau:\n"
+ "\\code\n"
+ "/*! Các lướp không thấy được bởi sự cắt ngắn */\n"
+ "Lớp không nhìn thấy class { };\n\n"
+ "/*! class bị cắt, quan hệ kế thừa bị ẩn */\n"
+ "class bị cắt : bị ẩn toàn cục { };\n\n"
+ "/* Class không được mô tả với các chú giải doxygen */\n"
+ "class không được mô tả { };\n\n"
+ "/*! Class được kế thừa sử dụng các kế thừa public */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! template class */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! Class được kế thừa sử dụng kế thừa protected */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Class được kế thừa sử dụng kế thừa protected private */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Class được sử dụng bởi các class kế thừa */\n"
+ "class được sử dụng { };\n\n"
+ "/*! Super class kế thừa một số các class khác */\n"
+ "class được kế thừa : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Kết quả trong biểu đồ sau đây:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Các hộp trong biểu đồ trên có ý nghĩa như sau:\n"
+ "<ul>\n"
+ "<li>%Hộp màu xám biểu thị cấu trúc clas cho "
+ "biểu đồ được thể hiện.\n"
+ "<li>%Hộp có khung mầu đen biểu thị struct hoặc class được mô tả.\n"
+ "<li>%Hộp có khung mầu xám biểu thị struct hoặc class chưa được mô tả.\n"
+ "<li>%Hộp có khung mầu đỏ biểu thị struct hoặc class được mổ tả "
+ "khi mà không phải tất cả các quan hệ kế thừa/containment được biển diễn.. %Biểu đồ bị "
+ "cắt nếu nó không nằm trọn trong các biên được cho trước..\n"
+ "</ul>\n"
+ "Các mũi tên có ý nghĩa như sau::\n"
+ "<ul>\n"
+ "<li>%Mũi tên mầu xanh đậm biểu thị các quan hệ kế thừa công khai "
+ "giữa 2 class.\n"
+ "<li>%Mũi tên màu xanh lá cây đậm biểu thị kế thừa được bảo về (protected).\n"
+ "<li>%Mũi tên đỏ đậm biểu thị kế thừa dạng private.\n"
+ "<li>%Mũi tên màu hồng đứt quảng biểu thị class được sử dụng "
+ "bởi class khác. Mũi tên được gán nhãn với các giá trị "
+ "mà các calsss hoặc struct được truy cập tới.\n"
+ "<li>%Mũi tên vàng đắt quãng được thị quan hệ giữa template instance và "
+ "template class được dẫn xuất từ đó. Mũi tên được gán nhãn với "
+ "tham số của template.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Chú giải";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Danh sách Test";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Thuộc tính";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Thông tin thuộc tính (Property)";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Cấu trúc dữ liệu";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Gói "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Danh sách gói";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Danh sách các gói cùng với mô tả tóm tắt (khi có thể có):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Các gói";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Giá trị:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Lỗi";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Danh sách lỗi";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1258";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "163";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Chỉ số";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Class" : "class"));
+ if (!singular) result+="es";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "File" : "file"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Group" : "group"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Trang" : "trang"));
+ if (!singular) result+="";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Member" : "member"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tác giả" : "tác giả"));
+ if (!singular) result+="";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Tham chiếu";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Thực hiện "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Được thực hiện trong "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Mục lục";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Danh sách Deprecated";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Sự kiện";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Thông tin về sự kiện";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Kiểu gói";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Các hàm Package";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Các hàm Static Package";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Các thuộc tính Package";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Các thuộc tính Static Package";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Tất cả";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "Biểu đồ các lời gọi cho hàm này:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Kết quả tìm kiếm";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Không có tài liệu nào thỏa mãn các truy vấn của bạn.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Tìm thấy <b>1</b> tài liệu thỏa mã truy vấn của bạn.";
+ }
+ else
+ {
+ return "Tìm thấy tất cả <b>$num</b> tài liệu thỏa mã truy vấn của bạn. "
+ "Hiển thị những thỏa mãn tốt nhất trước.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Các kết quả thỏa mãn đk:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " File nguồn";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Cấu trúc thư mục"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Thông tin về thư mục"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of an HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Các thư mục"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Thư mục đã được sắp xếp theo al-pha-bê, "
+ "nhưng chưa đầy đủ:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Tham chiếu thư mục"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Thư mục" : "thư mục"));
+ if (singular) result+=""; else result+="";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Hàm thành viên dạng overloaded, "
+ "được chỉ ra cho việc tra cứu dễ dàng. Nó khác với hàm ở trên"
+ "chỉ ở chỗ những tham số nào nó chấp nhận.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Biểu đồ các lời gọi cho hàm này:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Thông tin Enumerator"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Thông tin về các hàm và các thủ tục thành viên"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Danh sách kiêu dữ liệu"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Trường dữ liệu"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Kiểu dữ liệu với các mô tả tóm tắt:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Danh sách tất cả ";
+ if (!extractAll)
+ {
+ result+="(đã được mô tả) ";
+ }
+ result+="các kiểu dữ liệu thành viên";
+ result+=" cùng với liên kết với ";
+ if (!extractAll)
+ {
+ result+="Thông tin cấu trúc dữ liệu cho từng thành viên";
+ }
+ else
+ {
+ result+=" các kiểu dữ liệu thuộc:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Chỉ mục kiểu dữ liệu"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Thông tin về kiểu dữ liệu"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Functions/Subroutines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Thông tin về Function/Subroutine"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Kiểu dữ liệu"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Danh sách Modules"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Danh sách tất cả ";
+ if (!extractAll) result+="(đã được mô tả) ";
+ result+="các module với mô tả tóm tắt:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Module"; break;
+ case ClassDef::Struct: result+=" Type"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Interface"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Category"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Tham chiếu";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Tham chiếu Module";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Thành viên Module"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Danh sách tất cả ";
+ if (!extractAll) result+="(đã được mô tả) ";
+ result+="các module thành viên cùng với liên kết tới ";
+ if (extractAll)
+ {
+ result+="Thông tin module cho từng thành viên:";
+ }
+ else
+ {
+ result+="các module thuộc:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Chỉ mục các Module"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Module", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Thông tin cho ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="module"; break;
+ case ClassDef::Struct: result+="type"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="interface"; break;
+ case ClassDef::Protocol: result+="protocol"; break;
+ case ClassDef::Category: result+="category"; break;
+ case ClassDef::Exception: result+="exception"; break;
+ default: break;
+ }
+ result+=" được biên soạn từ các file sau đây";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Kiểu" : "kiểu"));
+ if (!singular) result+="";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Chương trình con" : "chương trình con"));
+ if (!singular) result+="";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Ràng buộc của kiểu (Type)";
+ }
+
+};
+
+#endif
diff --git a/src/translator_za.h b/src/translator_za.h
new file mode 100644
index 0000000..f47052e
--- /dev/null
+++ b/src/translator_za.h
@@ -0,0 +1,1723 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+ /*
+ * Bronne vir hierdie vertaling (Sources for this translation):
+ * Die Stigting vir Afrikaans se rekenaartermelys:
+ * - http://www.afrikaans.com/rekenaarterme.html
+ * Werkgroep vir Afrikaanse IT-terme:
+ * - http://www.vertaal.org/index.html
+ */
+
+#ifndef TRANSLATOR_ZA_H
+#define TRANSLATOR_ZA_H
+
+class TranslatorAfrikaans : public TranslatorAdapter_1_6_0
+{
+ public:
+
+ // --- Language control methods -------------------
+
+ /*! Used for identification of the language. The identification
+ * should not be translated. It should be replaced by the name
+ * of the language in English using lower-case characters only
+ * (e.g. "czech", "japanese", "russian", etc.). It should be equal to
+ * the identification used in language.cpp.
+ */
+ virtual QCString idLanguage()
+ { return "afrikaans"; }
+
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The Afrikaans LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ virtual QCString latexLanguageSupportCommand()
+ {
+ //should we use return "\\usepackage[afrikaans]{babel}\n";
+ // not sure - for now return an empty string
+ return "";
+ }
+
+ // --- Language translation methods -------------------
+
+ /*! used in the compound documentation before a list of related functions. */
+ virtual QCString trRelatedFunctions()
+ { return "Verwante Funksies"; }
+
+ /*! subscript for the related functions. */
+ virtual QCString trRelatedSubscript()
+ { return "(Let daarop dat hierdie nie lede funksies is nie.)"; }
+
+ /*! header that is put before the detailed description of files, classes and namespaces. */
+ virtual QCString trDetailedDescription()
+ { return "Detail Beskrywing"; }
+
+ /*! header that is put before the list of typedefs. */
+ virtual QCString trMemberTypedefDocumentation()
+ { return "Lede Typedef Dokumentasie"; }
+
+ /*! header that is put before the list of enumerations. */
+ virtual QCString trMemberEnumerationDocumentation()
+ { return "Lede Enumerasie Dokumentasie"; }
+
+ /*! header that is put before the list of member functions. */
+ virtual QCString trMemberFunctionDocumentation()
+ { return "Lede Funksie Dokumentasie"; }
+
+ /*! header that is put before the list of member attributes. */
+ virtual QCString trMemberDataDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Veld Dokumentasie";
+ }
+ else
+ {
+ return "Lede Data Dokumentasie";
+ }
+ }
+
+ /*! this is the text of a link put after brief descriptions. */
+ virtual QCString trMore()
+ { return "Meer detail..."; }
+
+ /*! put in the class documentation */
+ virtual QCString trListOfAllMembers()
+ { return "Lys van alle lede"; }
+
+ /*! used as the title of the "list of all members" page of a class */
+ virtual QCString trMemberList()
+ { return "Lede Lys"; }
+
+ /*! this is the first part of a sentence that is followed by a class name */
+ virtual QCString trThisIsTheListOfAllMembers()
+ { return "Hierdie is 'n volledige lys van lede vir "; }
+
+ /*! this is the remainder of the sentence after the class name */
+ virtual QCString trIncludingInheritedMembers()
+ { return ", insluitend alle afgeleide lede."; }
+
+ /*! this is put at the author sections at the bottom of man pages.
+ * parameter s is name of the project name.
+ */
+ virtual QCString trGeneratedAutomatically(const char *s)
+ { QCString result="Automaties gegenereer deur Doxygen";
+ if (s) result+=(QCString)" vir "+s;
+ result+=" van die bron kode af.";
+ return result;
+ }
+
+ /*! put after an enum name in the list of all members */
+ virtual QCString trEnumName()
+ { return "enum naam"; }
+
+ /*! put after an enum value in the list of all members */
+ virtual QCString trEnumValue()
+ { return "enum waarde"; }
+
+ /*! put after an undocumented member in the list of all members */
+ virtual QCString trDefinedIn()
+ { return "gedefinieër in"; }
+
+ // quick reference sections
+
+ /*! This is put above each page as a link to the list of all groups of
+ * compounds or files (see the \\group command).
+ */
+ virtual QCString trModules()
+ { return "Modules"; }
+
+ /*! This is put above each page as a link to the class hierarchy */
+ virtual QCString trClassHierarchy()
+ { return "Klas Hierargie"; }
+
+ /*! This is put above each page as a link to the list of annotated classes */
+ virtual QCString trCompoundList()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Strukture";
+ }
+ else
+ {
+ return "Klas Lys";
+ }
+ }
+
+ /*! This is put above each page as a link to the list of documented files */
+ virtual QCString trFileList()
+ { return "Leër Lys"; }
+
+ /*! This is put above each page as a link to all members of compounds. */
+ virtual QCString trCompoundMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Velde";
+ }
+ else
+ {
+ return "Klas Lede";
+ }
+ }
+
+ /*! This is put above each page as a link to all members of files. */
+ virtual QCString trFileMembers()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Globals";
+ }
+ else
+ {
+ return "Leër Lede";
+ }
+ }
+
+ /*! This is put above each page as a link to all related pages. */
+ virtual QCString trRelatedPages()
+ { return "Verwante Bladsye"; }
+
+ /*! This is put above each page as a link to all examples. */
+ virtual QCString trExamples()
+ { return "Voorbeelde"; }
+
+ /*! This is put above each page as a link to the search engine. */
+ virtual QCString trSearch()
+ { return "Soek"; }
+
+ /*! This is an introduction to the class hierarchy. */
+ virtual QCString trClassHierarchyDescription()
+ {
+ return "Hierdie afgeleide lys word rofweg gesorteer: ";
+ }
+
+ /*! This is an introduction to the list with all files. */
+ virtual QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="Hier is 'n lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+ result+="leërs met kort beskrywings:";
+ return result;
+ }
+
+ /*! This is an introduction to the annotated compound list. */
+ virtual QCString trCompoundListDescription()
+ {
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return " Data strukture met kort beskrywings:";
+ }
+ else
+ {
+ return "Klasse, structs, "
+ "unions en intervlakke met kort beskrywings:";
+ }
+ }
+
+ /*! This is an introduction to the page with all class members. */
+ virtual QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="'n Lys van alle ";
+ if (!extractAll)
+ {
+ result+="gedokumenteerde ";
+ }
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="struct en union velde";
+ }
+ else
+ {
+ result+="klas lede";
+ }
+ result+=" met skakels na ";
+ if (!extractAll)
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="die struct/union dokumentasie vir elke veld:";
+ }
+ else
+ {
+ result+="die klas dokumentasie vir elke lid:";
+ }
+ }
+ else
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="die structures/unions waaraan hulle behoort:";
+ }
+ else
+ {
+ result+="die klasse waaraan hulle behoort:";
+ }
+ }
+ return result;
+ }
+
+ /*! This is an introduction to the page with all file members. */
+ virtual QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="'n Lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ result+="funksies, veranderlikes, defines, enums, en typedefs";
+ }
+ else
+ {
+ result+="leër lede";
+ }
+ result+=" met skakels na ";
+ if (extractAll)
+ result+="die leërs waaraan hulle behoort:";
+ else
+ result+="die dokumentasie:";
+ return result;
+ }
+
+ /*! This is an introduction to the page with the list of all examples */
+ virtual QCString trExamplesDescription()
+ { return "'n Lys van alle voorbeelde:"; }
+
+ /*! This is an introduction to the page with the list of related pages */
+ virtual QCString trRelatedPagesDescription()
+ { return "'n Lys van alle verwante dokumentasie:"; }
+
+ /*! This is an introduction to the page with the list of class/file groups */
+ virtual QCString trModulesDescription()
+ { return "'n Lys van alle modules:"; }
+
+ /*! This is used in HTML as the title of index.html. */
+ virtual QCString trDocumentation()
+ { return "Dokumentasie"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all groups.
+ */
+ virtual QCString trModuleIndex()
+ { return "Module Indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * class hierarchy.
+ */
+ virtual QCString trHierarchicalIndex()
+ { return "Hierargiese Indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index.
+ */
+ virtual QCString trCompoundIndex()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Strukture Indeks";
+ }
+ else
+ {
+ return "Klas Indeks";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * list of all files.
+ */
+ virtual QCString trFileIndex()
+ { return "Leër Indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all groups.
+ */
+ virtual QCString trModuleDocumentation()
+ { return "Module Dokumentasie"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all classes, structs and unions.
+ */
+ virtual QCString trClassDocumentation()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Strukture Dokumentasie";
+ }
+ else
+ {
+ return "Klas Dokumentasie";
+ }
+ }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all files.
+ */
+ virtual QCString trFileDocumentation()
+ { return "Leër Dokumentasie"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all examples.
+ */
+ virtual QCString trExampleDocumentation()
+ { return "Voorbeeld Dokumentasie"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all related pages.
+ */
+ virtual QCString trPageDocumentation()
+ { return "Bladsy Dokumentasie"; }
+
+ /*! This is used in LaTeX as the title of the document */
+ virtual QCString trReferenceManual()
+ { return "Verwysings Handleiding"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of defines
+ */
+ virtual QCString trDefines()
+ { return "Definiesies"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of typedefs
+ */
+ virtual QCString trTypedefs()
+ { return "Typedefs"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of enumerations
+ */
+ virtual QCString trEnumerations()
+ { return "Enumerations"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) functions
+ */
+ virtual QCString trFunctions()
+ { return "Funksies"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trVariables()
+ { return "Veranderlikes"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) variables
+ */
+ virtual QCString trEnumerationValues()
+ { return "Enumeration waardes"; }
+
+ /*! This is used in the documentation of a file before the list of
+ * documentation blocks for defines
+ */
+ virtual QCString trDefineDocumentation()
+ { return "Define Documentation"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for typedefs
+ */
+ virtual QCString trTypedefDocumentation()
+ { return "Typedef Dokumentasie"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration types
+ */
+ virtual QCString trEnumerationTypeDocumentation()
+ { return "Enumeration Type Dokumentasie"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for functions
+ */
+ virtual QCString trFunctionDocumentation()
+ { return "Funksie Dokumentasie"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for variables
+ */
+ virtual QCString trVariableDocumentation()
+ { return "Veranderlike Dokumentasie"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds
+ */
+ virtual QCString trCompounds()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Strukture";
+ }
+ else
+ {
+ return "Klasse";
+ }
+ }
+
+ /*! This is used in the standard footer of each page and indicates when
+ * the page was generated
+ */
+ virtual QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Gegenereer op "+date;
+ if (projName) result+=(QCString)" vir "+projName;
+ result+=(QCString)" deur";
+ return result;
+ }
+
+ /*! this text is put before a class diagram */
+ virtual QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"Afleidings diagram vir "+clName+":";
+ }
+
+ /*! this text is generated when the \\internal command is used. */
+ virtual QCString trForInternalUseOnly()
+ { return "Slegs vir interne gebruik."; }
+
+ /*! this text is generated when the \\warning command is used. */
+ virtual QCString trWarning()
+ { return "Waarskuwing"; }
+
+ /*! this text is generated when the \\version command is used. */
+ virtual QCString trVersion()
+ { return "Weergawe"; }
+
+ /*! this text is generated when the \\date command is used. */
+ virtual QCString trDate()
+ { return "Datum"; }
+
+ /*! this text is generated when the \\return command is used. */
+ virtual QCString trReturns()
+ { return "Returns"; }
+
+ /*! this text is generated when the \\sa command is used. */
+ virtual QCString trSeeAlso()
+ { return "Sien ook"; }
+
+ /*! this text is generated when the \\param command is used. */
+ virtual QCString trParameters()
+ { return "Parameters"; }
+
+ /*! this text is generated when the \\exception command is used. */
+ virtual QCString trExceptions()
+ { return "Exceptions"; }
+
+ /*! this text is used in the title page of a LaTeX document. */
+ virtual QCString trGeneratedBy()
+ { return "Gegenereer deur"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of page containing all the index of all namespaces. */
+ virtual QCString trNamespaceList()
+ { return "Namespace Lys"; }
+
+ /*! used as an introduction to the namespace list */
+ virtual QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="'n Lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+ result+="namespaces met kort beskrywings:";
+ return result;
+ }
+
+ /*! used in the class documentation as a header before the list of all
+ * friends of a class
+ */
+ virtual QCString trFriends()
+ { return "Friends"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in the class documentation as a header before the list of all
+ * related classes
+ */
+ virtual QCString trRelatedFunctionDocumentation()
+ { return "Friends En Verwante Funksie Dokumentasie"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used as the title of the HTML page of a class/struct/union */
+ virtual QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" klas"; break;
+ case ClassDef::Struct: result+=" Struct"; break;
+ case ClassDef::Union: result+=" Union"; break;
+ case ClassDef::Interface: result+=" Intervlak"; break;
+ case ClassDef::Protocol: result+=" Protocol"; break;
+ case ClassDef::Category: result+=" Kategorie"; break;
+ case ClassDef::Exception: result+=" Exception"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Verwysing";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a file */
+ virtual QCString trFileReference(const char *fileName)
+ {
+ QCString result=fileName;
+ result+=" Leër Verwysing";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a namespace */
+ virtual QCString trNamespaceReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Namespace Verwysing";
+ return result;
+ }
+
+ virtual QCString trPublicMembers()
+ { return "Publieke Lede Funksies"; }
+ virtual QCString trPublicSlots()
+ { return "Publieke Slots"; }
+ virtual QCString trSignals()
+ { return "Signals"; }
+ virtual QCString trStaticPublicMembers()
+ { return "Statiese Publieke Lede Funksies"; }
+ virtual QCString trProtectedMembers()
+ { return "Beskermde Lede Funksies"; }
+ virtual QCString trProtectedSlots()
+ { return "Beskermde Slots"; }
+ virtual QCString trStaticProtectedMembers()
+ { return "Statiese Beskermde Lede Funksies"; }
+ virtual QCString trPrivateMembers()
+ { return "Private Lede Funksies"; }
+ virtual QCString trPrivateSlots()
+ { return "Private Slots"; }
+ virtual QCString trStaticPrivateMembers()
+ { return "Statiese Private Lede Funksies"; }
+
+ /*! this function is used to produce a comma-separated list of items.
+ * use generateMarker(i) to indicate where item i should be put.
+ */
+ virtual QCString trWriteList(int numEntries)
+ {
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+=", ";
+ else // the fore last entry
+ result+=", en ";
+ }
+ }
+ return result;
+ }
+
+ /*! used in class documentation to produce a list of base classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritsList(int numEntries)
+ {
+ return "Afgelei van"+trWriteList(numEntries)+".";
+ }
+
+ /*! used in class documentation to produce a list of super classes,
+ * if class diagrams are disabled.
+ */
+ virtual QCString trInheritedByList(int numEntries)
+ {
+ return "Afgelei van"+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are hidden by this one.
+ */
+ virtual QCString trReimplementedFromList(int numEntries)
+ {
+ return "Hergeimplimenteer van "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all member that overwrite the implementation of this member.
+ */
+ virtual QCString trReimplementedInList(int numEntries)
+ {
+ return "Hergeimplimenter in "+trWriteList(numEntries)+".";
+ }
+
+ /*! This is put above each page as a link to all members of namespaces. */
+ virtual QCString trNamespaceMembers()
+ { return "Namespace Lede"; }
+
+ /*! This is an introduction to the page with all namespace members */
+ virtual QCString trNamespaceMemberDescription(bool extractAll)
+ {
+ QCString result="'n Lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+ result+="namespace lede met skakels na ";
+ if (extractAll)
+ result+="die namespace dokumentasie vir elke lid:";
+ else
+ result+="die namespaces waaraan hulle behoort:";
+ return result;
+ }
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all namespaces.
+ */
+ virtual QCString trNamespaceIndex()
+ { return "Namespace Indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all namespaces.
+ */
+ virtual QCString trNamespaceDocumentation()
+ { return "Namespace Dokumentasie"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in the documentation before the list of all
+ * namespaces in a file.
+ */
+ virtual QCString trNamespaces()
+ { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool single)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"Die dokumentasie vir hierdie ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="klas"; break;
+ case ClassDef::Struct: result+="struct"; break;
+ case ClassDef::Union: result+="union"; break;
+ case ClassDef::Interface: result+="intervlak"; break;
+ case ClassDef::Protocol: result+="protokol"; break;
+ case ClassDef::Category: result+="kategorie"; break;
+ case ClassDef::Exception: result+="eksepsie"; break;
+ default: break;
+ }
+ result+=" is gegenereer vanaf die volgende leër";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ virtual QCString trReturnValues()
+ { return "Return waardes"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ virtual QCString trMainPage()
+ { return "Hoof Bladsy"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ virtual QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDefinedAtLineInSourceFile()
+ {
+ return "Gedefinieër by lyn @0 van leër @1.";
+ }
+ virtual QCString trDefinedInSourceFile()
+ {
+ return "Definisie in leër @0.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trDeprecated()
+ {
+ return "Verouderd";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ virtual QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)"Samewerkings diagram vir "+clName+":";
+ }
+ /*! this text is put before an include dependency graph */
+ virtual QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)"Insluitings afhanklikheid diagram vir "+fName+":";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ virtual QCString trConstructorDocumentation()
+ {
+ return "Konstruktor & Destruktor Dokumentasie";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ virtual QCString trGotoSourceCode()
+ {
+ return "Skakel na die bron kode van hierdie leër.";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ virtual QCString trGotoDocumentation()
+ {
+ return "Skakel na die dokumentasie van hierdie leër.";
+ }
+ /*! Text for the \\pre command */
+ virtual QCString trPrecondition()
+ {
+ return "Prekondisie";
+ }
+ /*! Text for the \\post command */
+ virtual QCString trPostcondition()
+ {
+ return "Postkondisie";
+ }
+ /*! Text for the \\invariant command */
+ virtual QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ virtual QCString trInitialValue()
+ {
+ return "Oorspronklike waarde:";
+ }
+ /*! Text used the source code in the file index */
+ virtual QCString trCode()
+ {
+ return "kode";
+ }
+ virtual QCString trGraphicalHierarchy()
+ {
+ return "Grafiese Klasse Hierargie";
+ }
+ virtual QCString trGotoGraphicalHierarchy()
+ {
+ return "Skakel na die grafiese klasse hierargie";
+ }
+ virtual QCString trGotoTextualHierarchy()
+ {
+ return "Skakel na die teks klasse hierargie";
+ }
+ virtual QCString trPageIndex()
+ {
+ return "Bladsy Indeks";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trNote()
+ {
+ return "Nota";
+ }
+ virtual QCString trPublicTypes()
+ {
+ return "Publieke Tipes";
+ }
+ virtual QCString trPublicAttribs()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Velde";
+ }
+ else
+ {
+ return "Publieke Public Attributes";
+ }
+ }
+ virtual QCString trStaticPublicAttribs()
+ {
+ return "Statiese Publieke Attribute";
+ }
+ virtual QCString trProtectedTypes()
+ {
+ return "Beskermde Tipes";
+ }
+ virtual QCString trProtectedAttribs()
+ {
+ return "Beskermde Attribute";
+ }
+ virtual QCString trStaticProtectedAttribs()
+ {
+ return "Statiese Beskermde Attribute";
+ }
+ virtual QCString trPrivateTypes()
+ {
+ return "Private Tipes";
+ }
+ virtual QCString trPrivateAttribs()
+ {
+ return "Private Attribute";
+ }
+ virtual QCString trStaticPrivateAttribs()
+ {
+ return "Statiese Private Attribute";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\todo item */
+ virtual QCString trTodo()
+ {
+ return "Aksies";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Aksie Lys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Verwysing van";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Opmerkings";
+ }
+ virtual QCString trAttention()
+ {
+ return "Aandag";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Hierdie diagram verduidelik watter leërs direk of"
+ "indirek hierdie leër insluit:";
+ }
+ virtual QCString trSince()
+ {
+ return "Sederd";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Diagram beskrywing";
+ }
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Hierdie bladsy beskryf die diagram konvensies wat gebruik word "
+ "deur doxygen.<p>\n"
+ "in hierdie voorbeeld:\n"
+ "\\code\n"
+ "/*! Onsigbare klas weens afkorting */\n"
+ "class Invisible { };\n\n"
+ "/*! Afgekorte klas, afgeleide verwantskap word versteek */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Ongedokumenteerde Klas, geen doxygen kommentaar nie */\n"
+ "class Undocumented{ };\n\n"
+ "/*! 'n Klas wat afgelei is met 'n publieke verwantskap */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! 'n template klas */\n"
+ "template<class T> class Templ { };\n\n"
+ "/*! 'n Klas wat afgelei is met 'n beskermde verwantskap */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! 'n Klas wat afgelei is met 'n private verwantskap */\n"
+ "class PrivateBase { };\n\n"
+ "/*! 'n Klas wat gebrui word deur die Afgeleide klas */\n"
+ "class GebruikMy { };\n\n"
+ "/*! 'n Super klas wat afgelei word van 'n aantal basis klasse */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Ongedokumenteer,\n"
+ " public Templ<int>\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "As die \\c MAX_DOT_GRAPH_HEIGHT merker in die konfigurasie leër "
+ "aan 240 gelyk gestel is, word die volgende diagram geproduseer:"
+ "<p><center><img alt=\"\" src=\"graph_legend."+Config_getEnum("DOT_IMAGE_FORMAT")+"\"></center>\n"
+ "<p>\n"
+ "Die reghoeke in die diagram het die volgende betekenis:\n"
+ "<ul>\n"
+ "<li>%'n Soliede swart reghoek verteenwoordig die klas waarvoor "
+ "die diagram gegenereer is.\n"
+ "<li>%'n Reghoek met 'n swart omlyning verteenwoordig 'n gedokumenteerde klas.\n"
+ "<li>%'n Reghoek met 'n grys omlyning verteenwoordig 'n ongedokumenteerde klas.\n"
+ "<li>%'n Reghoek met 'n rooi omlyning verteenwoordig 'n gedokumenteerde klas waarvoor"
+ "alle verwante klasse (afgeleide of gebruik) nie getoon word nie. %'n Diagram word "
+ "op hierie manier afgekort as dit nie in die gespesifiseerde raam pas nie.\n"
+ "</ul>\n"
+ "Die pyltjies het die volgende betekenis:\n"
+ "<ul>\n"
+ "<li>%'n Donker blou pyltjie verteenwoordig 'n publieke afgeleide "
+ "verwantskap tussen twee klasse.\n"
+ "<li>%'n Donker groen pyltjie word gebruik vir 'n beskermde verwantskap.\n"
+ "<li>%'n Donker rooi pyltjie verteenwoordig private verwantskappe.\n"
+ "<li>%'n Pers pyltjie word gebruik as 'n klas gebruik of bevat word "
+ "deur 'n ander klas. Die pyltjie word gemerk met die veranderlike(s) waar deur "
+ "die verwysde klass verkrygbaar is.\n"
+ "<li>%'n Geel stippel pyl verteenwoordig die verwantslap tussen 'n template instansie en "
+ "die template waarvan die klas vervaardig is. Die pyltjie word gemerk met die "
+ "template parameters van die instansie.\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "beskrywing";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Toets";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Toets Lys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Eienskappe";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Eienskap Dokumentasie";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Strukture";
+ }
+ else
+ {
+ return "Klasse";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Pakket "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Pakket Lys";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Die pakkette met kort beskrywings (indien beskikbaar):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Pakkette";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Waarde:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bug";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Bug Lys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Indeks";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Klas" : "klas"));
+ if (!singular) result+="se";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Leër" : "leër"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Groep" : "groep"));
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Bladsy" : "bladsy"));
+ if (!singular) result+="e";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Lid" : "lid"));
+ if (!singular) result = (first_capital ? "Lede" : "lede");
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global" : "global"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Outeur" : "outeur"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.11
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is put before the list of members referenced by a member
+ */
+ virtual QCString trReferences()
+ {
+ return "Verwysings";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.13
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in member documentation blocks to produce a list of
+ * members that are implemented by this one.
+ */
+ virtual QCString trImplementedFromList(int numEntries)
+ {
+ return "Implimenteer "+trWriteList(numEntries)+".";
+ }
+
+ /*! used in member documentation blocks to produce a list of
+ * all members that implement this abstract member.
+ */
+ virtual QCString trImplementedInList(int numEntries)
+ {
+ return "Geimplimenteer in "+trWriteList(numEntries)+".";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.16
+//////////////////////////////////////////////////////////////////////////
+
+ /*! used in RTF documentation as a heading for the Table
+ * of Contents.
+ */
+ virtual QCString trRTFTableOfContents()
+ {
+ return "Inhoudsopgawe";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.17
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as the header of the list of item that have been
+ * flagged deprecated
+ */
+ virtual QCString trDeprecatedList()
+ {
+ return "Verouderde Lys";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.18
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a header for declaration section of the events found in
+ * a C# program
+ */
+ virtual QCString trEvents()
+ {
+ return "Events";
+ }
+ /*! Header used for the documentation section of a class' events. */
+ virtual QCString trEventDocumentation()
+ {
+ return "Event Dokumentasie";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a heading for a list of Java class types with package scope.
+ */
+ virtual QCString trPackageTypes()
+ {
+ return "Pakket Tipes";
+ }
+ /*! Used as a heading for a list of Java class functions with package
+ * scope.
+ */
+ virtual QCString trPackageMembers()
+ {
+ return "Pakket Funksies";
+ }
+ /*! Used as a heading for a list of static Java class functions with
+ * package scope.
+ */
+ virtual QCString trStaticPackageMembers()
+ {
+ return "Statiese Pakket Funksies";
+ }
+ /*! Used as a heading for a list of Java class variables with package
+ * scope.
+ */
+ virtual QCString trPackageAttribs()
+ {
+ return "Pakket Eienskappe";
+ }
+ /*! Used as a heading for a list of static Java class variables with
+ * package scope.
+ */
+ virtual QCString trStaticPackageAttribs()
+ {
+ return "Statiese Pakket Eienskappe";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used in the quick index of a class/file/namespace member list page
+ * to link to the unfiltered list of all members.
+ */
+ virtual QCString trAll()
+ {
+ return "Alle Lede";
+ }
+ /*! Put in front of the call graph for a function. */
+ virtual QCString trCallGraph()
+ {
+ return "'n gebruiks diagram vir hierdie funksie:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This string is used as the title for the page listing the search
+ * results.
+ */
+ virtual QCString trSearchResultsTitle()
+ {
+ return "Soektog Resultate";
+ }
+ /*! This string is put just before listing the search results. The
+ * text can be different depending on the number of documents found.
+ * Inside the text you can put the special marker $num to insert
+ * the number representing the actual number of search results.
+ * The @a numDocuments parameter can be either 0, 1 or 2, where the
+ * value 2 represents 2 or more matches. HTML markup is allowed inside
+ * the returned string.
+ */
+ virtual QCString trSearchResults(int numDocuments)
+ {
+ if (numDocuments==0)
+ {
+ return "Geen dokumente na gelang van jou navraag nie.";
+ }
+ else if (numDocuments==1)
+ {
+ return "Die soektog het <b>1</b> dokument gevind na gelang van jou navraag.";
+ }
+ else
+ {
+ return "Die soektog het <b>$num</b> dokumente gevind na gelang van jou navraag. "
+ "Beste resultate eerste.";
+ }
+ }
+ /*! This string is put before the list of matched words, for each search
+ * result. What follows is the list of words that matched the query.
+ */
+ virtual QCString trSearchMatches()
+ {
+ return "Teikens:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.8
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used in HTML as the title of page with source code for file filename
+ */
+ virtual QCString trSourceFile(QCString& filename)
+ {
+ return filename + " Bron kode Leër";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.9
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the name of the chapter containing the directory
+ * hierarchy.
+ */
+ virtual QCString trDirIndex()
+ { return "Directory Hiërargie"; }
+
+ /*! This is used as the name of the chapter containing the documentation
+ * of the directories.
+ */
+ virtual QCString trDirDocumentation()
+ { return "Directory Documentasie"; }
+
+ /*! This is used as the title of the directory index and also in the
+ * Quick links of a HTML page, to link to the directory hierarchy.
+ */
+ virtual QCString trDirectories()
+ { return "Directories"; }
+
+ /*! This returns a sentences that introduces the directory hierarchy.
+ * and the fact that it is sorted alphabetically per level
+ */
+ virtual QCString trDirDescription()
+ { return "Hierdie directory hiërargie is min of meer alfabeties "
+ "gesorteer:";
+ }
+
+ /*! This returns the title of a directory page. The name of the
+ * directory is passed via \a dirName.
+ */
+ virtual QCString trDirReference(const char *dirName)
+ { QCString result=dirName; result+=" Directory Verwysing"; return result; }
+
+ /*! This returns the word directory with or without starting capital
+ * (\a first_capital) and in sigular or plural form (\a singular).
+ */
+ virtual QCString trDir(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Director" : "director"));
+ if (singular) result+="y"; else result+="ies";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is added to the documentation when the \\overload command
+ * is used for a overloaded function.
+ */
+ virtual QCString trOverloadText()
+ {
+ return "Hierdie is 'n oorlaaide lede funksie, "
+ "vertoon vir volledigheid. Dit verskil slegs van die bogegewe "
+ "funksie in die argument(e) wat dit aanvaar.";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.4.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used to introduce a caller (or called-by) graph */
+ virtual QCString trCallerGraph()
+ {
+ return "Hier is die roep skema vir die funksie:";
+ }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for enumeration values
+ */
+ virtual QCString trEnumerationValueDocumentation()
+ { return "Enumerator Dokumentasie"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.5.4 (mainly for Fortran)
+//////////////////////////////////////////////////////////////////////////
+
+ /*! header that is put before the list of member subprograms (Fortran). */
+ virtual QCString trMemberFunctionDocumentationFortran()
+ { return "Lede Funksie/Subroetine Dokumentasie"; }
+
+ /*! This is put above each page as a link to the list of annotated data types (Fortran). */
+ virtual QCString trCompoundListFortran()
+ { return "Data Tipes Lys"; }
+
+ /*! This is put above each page as a link to all members of compounds (Fortran). */
+ virtual QCString trCompoundMembersFortran()
+ { return "Data Velde"; }
+
+ /*! This is an introduction to the annotated compound list (Fortran). */
+ virtual QCString trCompoundListDescriptionFortran()
+ { return "Hier is die data tipes met kort beskrywings:"; }
+
+ /*! This is an introduction to the page with all data types (Fortran). */
+ virtual QCString trCompoundMembersDescriptionFortran(bool extractAll)
+ {
+ QCString result="Hier is 'n lys van alle ";
+ if (!extractAll)
+ {
+ result+="gedokumenteerde ";
+ }
+ result+="data tipe lede";
+ result+=" met skakels na ";
+ if (!extractAll)
+ {
+ result+="die data strukture dokumentasie vir elke lid";
+ }
+ else
+ {
+ result+="die data tipes waaraan hulle behoort:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * annotated compound index (Fortran).
+ */
+ virtual QCString trCompoundIndexFortran()
+ { return "Data Tipe Indeks"; }
+
+ /*! This is used in LaTeX as the title of the chapter containing
+ * the documentation of all data types (Fortran).
+ */
+ virtual QCString trTypeDocumentation()
+ { return "Data Tipe Dokumentasie"; }
+
+ /*! This is used in the documentation of a file as a header before the
+ * list of (global) subprograms (Fortran).
+ */
+ virtual QCString trSubprograms()
+ { return "Funksies/Subroetines"; }
+
+ /*! This is used in the documentation of a file/namespace before the list
+ * of documentation blocks for subprograms (Fortran)
+ */
+ virtual QCString trSubprogramDocumentation()
+ { return "Funksies/Subroetine Dokumentasie"; }
+
+ /*! This is used in the documentation of a file/namespace/group before
+ * the list of links to documented compounds (Fortran)
+ */
+ virtual QCString trDataTypes()
+ { return "Data Tipes"; }
+
+ /*! used as the title of page containing all the index of all modules (Fortran). */
+ virtual QCString trModulesList()
+ { return "Modules Lys"; }
+
+ /*! used as an introduction to the modules list (Fortran) */
+ virtual QCString trModulesListDescription(bool extractAll)
+ {
+ QCString result="Hier is 'n lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+ result+="modules met kort beskrywings:";
+ return result;
+ }
+
+ /*! used as the title of the HTML page of a module/type (Fortran) */
+ virtual QCString trCompoundReferenceFortran(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ {
+ QCString result=(QCString)clName;
+ switch(compType)
+ {
+ case ClassDef::Class: result+=" Module"; break;
+ case ClassDef::Struct: result+=" Tipe"; break;
+ case ClassDef::Union: result+=" Unie"; break;
+ case ClassDef::Interface: result+=" Interflak"; break;
+ case ClassDef::Protocol: result+=" Protokol"; break;
+ case ClassDef::Category: result+=" Kategorie"; break;
+ case ClassDef::Exception: result+=" Eksepsie"; break;
+ default: break;
+ }
+ if (isTemplate) result+=" Template";
+ result+=" Bron";
+ return result;
+ }
+ /*! used as the title of the HTML page of a module (Fortran) */
+ virtual QCString trModuleReference(const char *namespaceName)
+ {
+ QCString result=namespaceName;
+ result+=" Module Bron";
+ return result;
+ }
+
+ /*! This is put above each page as a link to all members of modules. (Fortran) */
+ virtual QCString trModulesMembers()
+ { return "Module Lede"; }
+
+ /*! This is an introduction to the page with all modules members (Fortran) */
+ virtual QCString trModulesMemberDescription(bool extractAll)
+ {
+ QCString result="Hier is 'n lys van alle ";
+ if (!extractAll) result+="gedokumenteerde ";
+ result+="module lede met skakels na ";
+ if (extractAll)
+ {
+ result+="die module dokumentasie vir elke lid:";
+ }
+ else
+ {
+ result+="die modules waaraan hulle behoort:";
+ }
+ return result;
+ }
+
+ /*! This is used in LaTeX as the title of the chapter with the
+ * index of all modules (Fortran).
+ */
+ virtual QCString trModulesIndex()
+ { return "Modules Indeks"; }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trModule(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Module" : "module"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is put at the bottom of a module documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType,
+ bool single)
+ {
+ // single is true implies a single file
+ QCString result=(QCString)"The documentation for this ";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="module"; break;
+ case ClassDef::Struct: result+="tipe"; break;
+ case ClassDef::Union: result+="unie"; break;
+ case ClassDef::Interface: result+="Interflak"; break;
+ case ClassDef::Protocol: result+="protokcol"; break;
+ case ClassDef::Category: result+="kategorie"; break;
+ case ClassDef::Exception: result+="eksepsie"; break;
+ default: break;
+ }
+ result+=" is gegenereer vanaf die foldende leer";
+ if (single) result+=":"; else result+="s:";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trType(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Tipe" : "tipe"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trSubprogram(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Subprogram" : "subprogram"));
+ if (!singular) result+="me";
+ return result;
+ }
+
+ /*! C# Type Constraint list */
+ virtual QCString trTypeConstraints()
+ {
+ return "Tipe Limiete";
+ }
+
+};
+
+#endif
diff --git a/src/types.h b/src/types.h
new file mode 100644
index 0000000..688d664
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TYPES_H
+#define TYPES_H
+
+#include <qcstring.h>
+
+/** @file
+ * @brief This file contains a number of basic enums and types.
+ */
+
+/** Protection level of members */
+enum Protection { Public, Protected, Private, Package } ;
+
+/** Virtualness of a member. */
+enum Specifier { Normal, Virtual, Pure } ;
+
+/** Kind of method */
+enum MethodTypes { Method, Signal, Slot, DCOP, Property, Event };
+
+/** Type of member relation */
+enum RelatesType { Simple, Duplicate, MemberOf };
+
+/** Kind of member relationship */
+enum Relationship { Member, Related, Foreign };
+
+/** Language as given by extension */
+enum SrcLangExt
+{
+ SrcLangExt_Unknown = 0x00000,
+ SrcLangExt_IDL = 0x00008,
+ SrcLangExt_Java = 0x00010,
+ SrcLangExt_CSharp = 0x00020,
+ SrcLangExt_D = 0x00040,
+ SrcLangExt_PHP = 0x00080,
+ SrcLangExt_ObjC = 0x00100,
+ SrcLangExt_Cpp = 0x00200,
+ SrcLangExt_JS = 0x00400,
+ SrcLangExt_Python = 0x00800,
+ SrcLangExt_Fortran = 0x01000,
+ SrcLangExt_VHDL = 0x02000,
+ SrcLangExt_XML = 0x04000,
+ SrcLangExt_Tcl = 0x08000,
+ SrcLangExt_Markdown = 0x10000
+};
+
+/** Grouping info */
+struct Grouping
+{
+ /** Grouping priority */
+ enum GroupPri_t
+ {
+ GROUPING_LOWEST,
+ GROUPING_AUTO_WEAK = GROUPING_LOWEST, //!< membership in group was defined via \@weakgroup
+ GROUPING_AUTO_ADD, //!< membership in group was defined via \@add[to]group
+ GROUPING_AUTO_DEF, //!< membership in group was defined via \@defgroup
+ GROUPING_AUTO_HIGHEST = GROUPING_AUTO_DEF,
+ GROUPING_INGROUP, //!< membership in group was defined by \@ingroup
+ GROUPING_HIGHEST = GROUPING_INGROUP
+ };
+
+ static const char *getGroupPriName( GroupPri_t priority )
+ {
+ switch( priority )
+ {
+ case GROUPING_AUTO_WEAK:
+ return "@weakgroup";
+ case GROUPING_AUTO_ADD:
+ return "@addtogroup";
+ case GROUPING_AUTO_DEF:
+ return "@defgroup";
+ case GROUPING_INGROUP:
+ return "@ingroup";
+ }
+ return "???";
+ }
+
+ Grouping( const char *gn, GroupPri_t p ) : groupname(gn), pri(p) {}
+ Grouping( const Grouping &g ) : groupname(g.groupname), pri(g.pri) {}
+ QCString groupname; //!< name of the group
+ GroupPri_t pri; //!< priority of this definition
+
+};
+
+struct ListItemInfo
+{
+ QCString type;
+ int itemId;
+};
+
+enum MemberListType
+{
+ MemberListType_privateLists = 0x0800,
+ MemberListType_detailedLists = 0x1000,
+ MemberListType_declarationLists = 0x2000,
+ MemberListType_documentationLists = 0x4000,
+
+ MemberListType_pubMethods = 0,
+ MemberListType_proMethods = 1,
+ MemberListType_pacMethods = 2,
+ MemberListType_priMethods = 3 + MemberListType_privateLists,
+ MemberListType_pubStaticMethods = 4,
+ MemberListType_proStaticMethods = 5,
+ MemberListType_pacStaticMethods = 6,
+ MemberListType_priStaticMethods = 7 + MemberListType_privateLists,
+ MemberListType_pubSlots = 8,
+ MemberListType_proSlots = 9,
+ MemberListType_priSlots = 10 + MemberListType_privateLists,
+ MemberListType_pubAttribs = 11,
+ MemberListType_proAttribs = 12,
+ MemberListType_pacAttribs = 13,
+ MemberListType_priAttribs = 14 + MemberListType_privateLists,
+ MemberListType_pubStaticAttribs = 15,
+ MemberListType_proStaticAttribs = 16,
+ MemberListType_pacStaticAttribs = 17,
+ MemberListType_priStaticAttribs = 18 + MemberListType_privateLists,
+ MemberListType_pubTypes = 19,
+ MemberListType_proTypes = 20,
+ MemberListType_pacTypes = 21,
+ MemberListType_priTypes = 22 + MemberListType_privateLists,
+ MemberListType_related = 23,
+ MemberListType_signals = 24,
+ MemberListType_friends = 25,
+ MemberListType_dcopMethods = 26,
+ MemberListType_properties = 27,
+ MemberListType_events = 28,
+
+ MemberListType_typedefMembers = 29 + MemberListType_detailedLists,
+ MemberListType_enumMembers = 30 + MemberListType_detailedLists,
+ MemberListType_enumValMembers = 31 + MemberListType_detailedLists,
+ MemberListType_functionMembers = 32 + MemberListType_detailedLists,
+ MemberListType_relatedMembers = 33 + MemberListType_detailedLists,
+ MemberListType_variableMembers = 34 + MemberListType_detailedLists,
+ MemberListType_propertyMembers = 35 + MemberListType_detailedLists,
+ MemberListType_eventMembers = 36 + MemberListType_detailedLists,
+ MemberListType_constructors = 37 + MemberListType_detailedLists,
+
+ MemberListType_allMembersList = 38,
+
+ MemberListType_decDefineMembers = 39 + MemberListType_declarationLists,
+ MemberListType_decProtoMembers = 40 + MemberListType_declarationLists,
+ MemberListType_decTypedefMembers = 41 + MemberListType_declarationLists,
+ MemberListType_decEnumMembers = 42 + MemberListType_declarationLists,
+ MemberListType_decFuncMembers = 43 + MemberListType_declarationLists,
+ MemberListType_decVarMembers = 44 + MemberListType_declarationLists,
+ MemberListType_decEnumValMembers = 45 + MemberListType_declarationLists,
+ MemberListType_decPubSlotMembers = 46 + MemberListType_declarationLists,
+ MemberListType_decProSlotMembers = 47 + MemberListType_declarationLists,
+ MemberListType_decPriSlotMembers = 48 + MemberListType_declarationLists,
+ MemberListType_decSignalMembers = 49 + MemberListType_declarationLists,
+ MemberListType_decEventMembers = 50 + MemberListType_declarationLists,
+ MemberListType_decFriendMembers = 51 + MemberListType_declarationLists,
+ MemberListType_decPropMembers = 52 + MemberListType_declarationLists,
+
+ MemberListType_docDefineMembers = 53 + MemberListType_documentationLists,
+ MemberListType_docProtoMembers = 54 + MemberListType_documentationLists,
+ MemberListType_docTypedefMembers = 55 + MemberListType_documentationLists,
+ MemberListType_docEnumMembers = 56 + MemberListType_documentationLists,
+ MemberListType_docFuncMembers = 57 + MemberListType_documentationLists,
+ MemberListType_docVarMembers = 58 + MemberListType_documentationLists,
+ MemberListType_docEnumValMembers = 59 + MemberListType_documentationLists,
+ MemberListType_docPubSlotMembers = 60 + MemberListType_documentationLists,
+ MemberListType_docProSlotMembers = 61 + MemberListType_documentationLists,
+ MemberListType_docPriSlotMembers = 62 + MemberListType_documentationLists,
+ MemberListType_docSignalMembers = 63 + MemberListType_documentationLists,
+ MemberListType_docEventMembers = 64 + MemberListType_documentationLists,
+ MemberListType_docFriendMembers = 65 + MemberListType_documentationLists,
+ MemberListType_docPropMembers = 66 + MemberListType_documentationLists,
+
+ MemberListType_redefinedBy = 67,
+ MemberListType_enumFields = 68,
+ MemberListType_memberGroup = 69,
+
+ // this one is for the summary section on the class page
+ MemberListType_interfaces = 70,
+ // this one is for the detailed section on the class page
+ MemberListType_interfaceMembers = 71 + MemberListType_detailedLists,
+ MemberListType_services = 72,
+ MemberListType_serviceMembers = 73 + MemberListType_detailedLists,
+};
+
+enum MemberType
+{
+ MemberType_Define,
+ MemberType_Function,
+ MemberType_Variable,
+ MemberType_Typedef,
+ MemberType_Enumeration,
+ MemberType_EnumValue,
+ MemberType_Signal,
+ MemberType_Slot,
+ MemberType_Friend,
+ MemberType_DCOP,
+ MemberType_Property,
+ MemberType_Event,
+ MemberType_Interface,
+ MemberType_Service,
+};
+
+enum FortranFormat
+{
+ FortranFormat_Unknown,
+ FortranFormat_Free,
+ FortranFormat_Fixed
+};
+
+#endif
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000..a524922
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,8279 @@
+/*****************************************************************************
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+
+#include "md5.h"
+
+#include <qregexp.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qdatetime.h>
+#include <qcache.h>
+
+#include "util.h"
+#include "message.h"
+#include "classdef.h"
+#include "filedef.h"
+#include "doxygen.h"
+#include "outputlist.h"
+#include "defargs.h"
+#include "language.h"
+#include "config.h"
+#include "htmlhelp.h"
+#include "example.h"
+#include "version.h"
+#include "groupdef.h"
+#include "reflist.h"
+#include "pagedef.h"
+#include "debug.h"
+#include "searchindex.h"
+#include "doxygen.h"
+#include "textdocvisitor.h"
+#include "portable.h"
+#include "parserintf.h"
+#include "bufstr.h"
+#include "image.h"
+#include "growbuf.h"
+#include "entry.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "classlist.h"
+#include "namespacedef.h"
+#include "membername.h"
+#include "filename.h"
+#include "membergroup.h"
+#include "dirdef.h"
+#include "htmlentity.h"
+
+#define ENABLE_TRACINGSUPPORT 0
+
+#if defined(_OS_MAC_) && ENABLE_TRACINGSUPPORT
+#define TRACINGSUPPORT
+#endif
+
+#ifdef TRACINGSUPPORT
+#include <execinfo.h>
+#include <unistd.h>
+#endif
+
+
+//------------------------------------------------------------------------
+
+// selects one of the name to sub-dir mapping algorithms that is used
+// to select a sub directory when CREATE_SUBDIRS is set to YES.
+
+#define ALGO_COUNT 1
+#define ALGO_CRC16 2
+#define ALGO_MD5 3
+
+//#define MAP_ALGO ALGO_COUNT
+//#define MAP_ALGO ALGO_CRC16
+#define MAP_ALGO ALGO_MD5
+
+#define REL_PATH_TO_ROOT "../../"
+
+//------------------------------------------------------------------------
+// TextGeneratorOLImpl implementation
+//------------------------------------------------------------------------
+
+TextGeneratorOLImpl::TextGeneratorOLImpl(OutputDocInterface &od) : m_od(od)
+{
+}
+
+void TextGeneratorOLImpl::writeString(const char *s,bool keepSpaces) const
+{
+ if (s==0) return;
+ //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
+ if (keepSpaces)
+ {
+ const char *p=s;
+ if (p)
+ {
+ char cs[2];
+ char c;
+ cs[1]='\0';
+ while ((c=*p++))
+ {
+ if (c==' ') m_od.writeNonBreakableSpace(1);
+ else cs[0]=c,m_od.docify(cs);
+ }
+ }
+ }
+ else
+ {
+ m_od.docify(s);
+ }
+}
+
+void TextGeneratorOLImpl::writeBreak(int indent) const
+{
+ m_od.lineBreak("typebreak");
+ int i;
+ for (i=0;i<indent;i++)
+ {
+ m_od.writeNonBreakableSpace(3);
+ }
+}
+
+void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const
+{
+ //printf("TextGeneratorOlImpl::writeLink('%s')\n",text);
+ m_od.writeObjectLink(extRef,file,anchor,text);
+}
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+
+// an inheritance tree of depth of 100000 should be enough for everyone :-)
+const int maxInheritanceDepth = 100000;
+
+/*!
+ Removes all anonymous scopes from string s
+ Possible examples:
+\verbatim
+ "bla::@10::blep" => "bla::blep"
+ "bla::@10::@11::blep" => "bla::blep"
+ "@10::blep" => "blep"
+ " @10::blep" => "blep"
+ "@9::@10::blep" => "blep"
+ "bla::@1" => "bla"
+ "bla::@1::@2" => "bla"
+ "bla @1" => "bla"
+\endverbatim
+ */
+QCString removeAnonymousScopes(const QCString &s)
+{
+ QCString result;
+ if (s.isEmpty()) return result;
+ static QRegExp re("[ :]*@[0-9]+[: ]*");
+ int i,l,sl=s.length();
+ int p=0;
+ while ((i=re.match(s,p,&l))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ int c=i;
+ bool b1=FALSE,b2=FALSE;
+ while (c<i+l && s.at(c)!='@') if (s.at(c++)==':') b1=TRUE;
+ c=i+l-1;
+ while (c>=i && s.at(c)!='@') if (s.at(c--)==':') b2=TRUE;
+ if (b1 && b2)
+ {
+ result+="::";
+ }
+ p=i+l;
+ }
+ result+=s.right(sl-p);
+ //printf("removeAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
+ return result;
+}
+
+// replace anonymous scopes with __anonymous__ or replacement if provided
+QCString replaceAnonymousScopes(const QCString &s,const char *replacement)
+{
+ QCString result;
+ if (s.isEmpty()) return result;
+ static QRegExp re("@[0-9]+");
+ int i,l,sl=s.length();
+ int p=0;
+ while ((i=re.match(s,p,&l))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ if (replacement)
+ {
+ result+=replacement;
+ }
+ else
+ {
+ result+="__anonymous__";
+ }
+ p=i+l;
+ }
+ result+=s.right(sl-p);
+ //printf("replaceAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
+ return result;
+}
+
+
+// strip anonymous left hand side part of the scope
+QCString stripAnonymousNamespaceScope(const QCString &s)
+{
+ int i,p=0,l;
+ QCString newScope;
+ int sl = s.length();
+ while ((i=getScopeFragment(s,p,&l))!=-1)
+ {
+ //printf("Scope fragment %s\n",s.mid(i,l).data());
+ if (Doxygen::namespaceSDict->find(s.left(i+l))!=0)
+ {
+ if (s.at(i)!='@')
+ {
+ if (!newScope.isEmpty()) newScope+="::";
+ newScope+=s.mid(i,l);
+ }
+ }
+ else if (i<sl)
+ {
+ if (!newScope.isEmpty()) newScope+="::";
+ newScope+=s.right(sl-i);
+ goto done;
+ }
+ p=i+l;
+ }
+done:
+ //printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),newScope.data());
+ return newScope;
+}
+
+void writePageRef(OutputDocInterface &od,const char *cn,const char *mn)
+{
+ od.pushGeneratorState();
+
+ od.disable(OutputGenerator::Html);
+ od.disable(OutputGenerator::Man);
+ if (Config_getBool("PDF_HYPERLINKS")) od.disable(OutputGenerator::Latex);
+ if (Config_getBool("RTF_HYPERLINKS")) od.disable(OutputGenerator::RTF);
+ od.startPageRef();
+ od.docify(theTranslator->trPageAbbreviation());
+ od.endPageRef(cn,mn);
+
+ od.popGeneratorState();
+}
+
+/*! Generate a place holder for a position in a list. Used for
+ * translators to be able to specify different elements orders
+ * depending on whether text flows from left to right or visa versa.
+ */
+QCString generateMarker(int id)
+{
+ QCString result;
+ result.sprintf("@%d",id);
+ return result;
+}
+
+static QCString stripFromPath(const QCString &path,QStrList &l)
+{
+ // look at all the strings in the list and strip the longest match
+ const char *s=l.first();
+ QCString potential;
+ unsigned int length = 0;
+ while (s)
+ {
+ QCString prefix = s;
+ if (prefix.length() > length &&
+ qstricmp(path.left(prefix.length()),prefix)==0) // case insensitive compare
+ {
+ length = prefix.length();
+ potential = path.right(path.length()-prefix.length());
+ }
+ s = l.next();
+ }
+ if (length) return potential;
+ return path;
+}
+
+/*! strip part of \a path if it matches
+ * one of the paths in the Config_getList("STRIP_FROM_PATH") list
+ */
+QCString stripFromPath(const QCString &path)
+{
+ return stripFromPath(path,Config_getList("STRIP_FROM_PATH"));
+}
+
+/*! strip part of \a path if it matches
+ * one of the paths in the Config_getList("INCLUDE_PATH") list
+ */
+QCString stripFromIncludePath(const QCString &path)
+{
+ return stripFromPath(path,Config_getList("STRIP_FROM_INC_PATH"));
+}
+
+/*! try to determine if \a name is a source or a header file name by looking
+ * at the extension. A number of variations is allowed in both upper and
+ * lower case) If anyone knows or uses another extension please let me know :-)
+ */
+int guessSection(const char *name)
+{
+ QCString n=((QCString)name).lower();
+ if (n.right(2)==".c" || // source
+ n.right(3)==".cc" ||
+ n.right(4)==".cxx" ||
+ n.right(4)==".cpp" ||
+ n.right(4)==".c++" ||
+ n.right(5)==".java" ||
+ n.right(2)==".m" ||
+ n.right(2)==".M" ||
+ n.right(3)==".mm" ||
+ n.right(3)==".ii" || // inline
+ n.right(4)==".ixx" ||
+ n.right(4)==".ipp" ||
+ n.right(4)==".i++" ||
+ n.right(4)==".inl" ||
+ n.right(4)==".xml"
+ ) return Entry::SOURCE_SEC;
+ if (n.right(2)==".h" || // header
+ n.right(3)==".hh" ||
+ n.right(4)==".hxx" ||
+ n.right(4)==".hpp" ||
+ n.right(4)==".h++" ||
+ n.right(4)==".idl" ||
+ n.right(4)==".ddl" ||
+ n.right(5)==".pidl"
+ ) return Entry::HEADER_SEC;
+ return 0;
+}
+
+QCString resolveTypeDef(Definition *context,const QCString &qualifiedName,
+ Definition **typedefContext)
+{
+ //printf("<<resolveTypeDef(%s,%s)\n",
+ // context ? context->name().data() : "<none>",qualifiedName.data());
+ QCString result;
+ if (qualifiedName.isEmpty())
+ {
+ //printf(" qualified name empty!\n");
+ return result;
+ }
+
+ Definition *mContext=context;
+ if (typedefContext) *typedefContext=context;
+
+ // see if the qualified name has a scope part
+ int scopeIndex = qualifiedName.findRev("::");
+ QCString resName=qualifiedName;
+ if (scopeIndex!=-1) // strip scope part for the name
+ {
+ resName=qualifiedName.right(qualifiedName.length()-scopeIndex-2);
+ if (resName.isEmpty())
+ {
+ // qualifiedName was of form A:: !
+ //printf(" qualified name of form A::!\n");
+ return result;
+ }
+ }
+ MemberDef *md=0;
+ while (mContext && md==0)
+ {
+ // step 1: get the right scope
+ Definition *resScope=mContext;
+ if (scopeIndex!=-1)
+ {
+ // split-off scope part
+ QCString resScopeName = qualifiedName.left(scopeIndex);
+ //printf("resScopeName=`%s'\n",resScopeName.data());
+
+ // look-up scope in context
+ int is,ps=0;
+ int l;
+ while ((is=getScopeFragment(resScopeName,ps,&l))!=-1)
+ {
+ QCString qualScopePart = resScopeName.mid(is,l);
+ QCString tmp = resolveTypeDef(mContext,qualScopePart);
+ if (!tmp.isEmpty()) qualScopePart=tmp;
+ resScope = resScope->findInnerCompound(qualScopePart);
+ //printf("qualScopePart=`%s' resScope=%p\n",qualScopePart.data(),resScope);
+ if (resScope==0) break;
+ ps=is+l;
+ }
+ }
+ //printf("resScope=%s\n",resScope?resScope->name().data():"<none>");
+
+ // step 2: get the member
+ if (resScope) // no scope or scope found in the current context
+ {
+ //printf("scope found: %s, look for typedef %s\n",
+ // resScope->qualifiedName().data(),resName.data());
+ MemberNameSDict *mnd=0;
+ if (resScope->definitionType()==Definition::TypeClass)
+ {
+ mnd=Doxygen::memberNameSDict;
+ }
+ else
+ {
+ mnd=Doxygen::functionNameSDict;
+ }
+ MemberName *mn=mnd->find(resName);
+ if (mn)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *tmd=0;
+ int minDist=-1;
+ for (;(tmd=mni.current());++mni)
+ {
+ //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n",
+ // tmd->name().data(), resScope->name().data(),
+ // tmd->getOuterScope()->name().data(), mContext);
+ if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/)
+ {
+ int dist=isAccessibleFrom(resScope,0,tmd);
+ if (dist!=-1 && (md==0 || dist<minDist))
+ {
+ md = tmd;
+ minDist = dist;
+ }
+ }
+ }
+ }
+ }
+ mContext=mContext->getOuterScope();
+ }
+
+ // step 3: get the member's type
+ if (md)
+ {
+ //printf(">>resolveTypeDef: Found typedef name `%s' in scope `%s' value=`%s' args='%s'\n",
+ // qualifiedName.data(),context->name().data(),md->typeString(),md->argsString()
+ // );
+ result=md->typeString();
+ QCString args = md->argsString();
+ if (args.find(")(")!=-1) // typedef of a function/member pointer
+ {
+ result+=args;
+ }
+ else if (args.find('[')!=-1) // typedef of an array
+ {
+ result+=args;
+ }
+ if (typedefContext) *typedefContext=md->getOuterScope();
+ }
+ else
+ {
+ //printf(">>resolveTypeDef: Typedef `%s' not found in scope `%s'!\n",
+ // qualifiedName.data(),context ? context->name().data() : "<global>");
+ }
+ return result;
+
+}
+
+
+/*! Get a class definition given its name.
+ * Returns 0 if the class is not found.
+ */
+ClassDef *getClass(const char *n)
+{
+ if (n==0 || n[0]=='\0') return 0;
+ QCString name=n;
+ ClassDef *result = Doxygen::classSDict->find(name);
+ //if (result==0 && !exact) // also try generic and protocol versions
+ //{
+ // result = Doxygen::classSDict->find(name+"-g");
+ // if (result==0)
+ // {
+ // result = Doxygen::classSDict->find(name+"-p");
+ // }
+ //}
+ //printf("getClass(%s)=%s\n",n,result?result->name().data():"<none>");
+ return result;
+}
+
+NamespaceDef *getResolvedNamespace(const char *name)
+{
+ if (name==0 || name[0]=='\0') return 0;
+ QCString *subst = Doxygen::namespaceAliasDict[name];
+ if (subst)
+ {
+ int count=0; // recursion detection guard
+ QCString *newSubst;
+ while ((newSubst=Doxygen::namespaceAliasDict[*subst]) && count<10)
+ {
+ subst=newSubst;
+ count++;
+ }
+ if (count==10)
+ {
+ warn_uncond("possible recursive namespace alias detected for %s!\n",name);
+ }
+ return Doxygen::namespaceSDict->find(subst->data());
+ }
+ else
+ {
+ return Doxygen::namespaceSDict->find(name);
+ }
+}
+
+static QDict<MemberDef> g_resolvedTypedefs;
+static QDict<Definition> g_visitedNamespaces;
+
+// forward declaration
+static ClassDef *getResolvedClassRec(Definition *scope,
+ FileDef *fileScope,
+ const char *n,
+ MemberDef **pTypeDef,
+ QCString *pTemplSpec,
+ QCString *pResolvedType
+ );
+int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item,
+ const QCString &explicitScopePart);
+
+/*! Returns the class representing the value of the typedef represented by \a md
+ * within file \a fileScope.
+ *
+ * Example: typedef A T; will return the class representing A if it is a class.
+ *
+ * Example: typedef int T; will return 0, since "int" is not a class.
+ */
+ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md,
+ MemberDef **pMemType,QCString *pTemplSpec,
+ QCString *pResolvedType,
+ ArgumentList *actTemplParams)
+{
+ //printf("newResolveTypedef(md=%p,cachedVal=%p)\n",md,md->getCachedTypedefVal());
+ bool isCached = md->isTypedefValCached(); // value already cached
+ if (isCached)
+ {
+ //printf("Already cached %s->%s [%s]\n",
+ // md->name().data(),
+ // md->getCachedTypedefVal()?md->getCachedTypedefVal()->name().data():"<none>",
+ // md->getCachedResolvedTypedef()?md->getCachedResolvedTypedef().data():"<none>");
+
+ if (pTemplSpec) *pTemplSpec = md->getCachedTypedefTemplSpec();
+ if (pResolvedType) *pResolvedType = md->getCachedResolvedTypedef();
+ return md->getCachedTypedefVal();
+ }
+ //printf("new typedef\n");
+ QCString qname = md->qualifiedName();
+ if (g_resolvedTypedefs.find(qname)) return 0; // typedef already done
+
+ g_resolvedTypedefs.insert(qname,md); // put on the trace list
+
+ ClassDef *typeClass = md->getClassDef();
+ QCString type = md->typeString(); // get the "value" of the typedef
+ if (typeClass && typeClass->isTemplate() &&
+ actTemplParams && actTemplParams->count()>0)
+ {
+ type = substituteTemplateArgumentsInString(type,
+ typeClass->templateArguments(),actTemplParams);
+ }
+ QCString typedefValue = type;
+ int tl=type.length();
+ int ip=tl-1; // remove * and & at the end
+ while (ip>=0 && (type.at(ip)=='*' || type.at(ip)=='&' || type.at(ip)==' '))
+ {
+ ip--;
+ }
+ type=type.left(ip+1);
+ type.stripPrefix("const "); // strip leading "const"
+ type.stripPrefix("struct "); // strip leading "struct"
+ type.stripPrefix("union "); // strip leading "union"
+ int sp=0;
+ tl=type.length(); // length may have been changed
+ while (sp<tl && type.at(sp)==' ') sp++;
+ MemberDef *memTypeDef = 0;
+ ClassDef *result = getResolvedClassRec(md->getOuterScope(),
+ fileScope,type,&memTypeDef,0,pResolvedType);
+ // if type is a typedef then return what it resolves to.
+ if (memTypeDef && memTypeDef->isTypedef())
+ {
+ result=newResolveTypedef(fileScope,memTypeDef,pMemType,pTemplSpec);
+ goto done;
+ }
+ else if (memTypeDef && memTypeDef->isEnumerate() && pMemType)
+ {
+ *pMemType = memTypeDef;
+ }
+
+ //printf("type=%s result=%p\n",type.data(),result);
+ if (result==0)
+ {
+ // try unspecialized version if type is template
+ int si=type.findRev("::");
+ int i=type.find('<');
+ if (si==-1 && i!=-1) // typedef of a template => try the unspecialized version
+ {
+ if (pTemplSpec) *pTemplSpec = type.mid(i);
+ result = getResolvedClassRec(md->getOuterScope(),fileScope,
+ type.left(i),0,0,pResolvedType);
+ //printf("result=%p pRresolvedType=%s sp=%d ip=%d tl=%d\n",
+ // result,pResolvedType?pResolvedType->data():"<none>",sp,ip,tl);
+ }
+ else if (si!=-1) // A::B
+ {
+ i=type.find('<',si);
+ if (i==-1) // Something like A<T>::B => lookup A::B
+ {
+ i=type.length();
+ }
+ else // Something like A<T>::B<S> => lookup A::B, spec=<S>
+ {
+ if (pTemplSpec) *pTemplSpec = type.mid(i);
+ }
+ result = getResolvedClassRec(md->getOuterScope(),fileScope,
+ stripTemplateSpecifiersFromScope(type.left(i),FALSE),0,0,
+ pResolvedType);
+ }
+
+ //if (result) ip=si+sp+1;
+ }
+
+done:
+ if (pResolvedType)
+ {
+ if (result)
+ {
+ *pResolvedType=result->qualifiedName();
+ //printf("*pResolvedType=%s\n",pResolvedType->data());
+ if (sp>0) pResolvedType->prepend(typedefValue.left(sp));
+ if (ip<tl-1) pResolvedType->append(typedefValue.right(tl-ip-1));
+ }
+ else
+ {
+ *pResolvedType=typedefValue;
+ }
+ }
+
+ // remember computed value for next time
+ if (result && result->getDefFileName()!="<code>")
+ // this check is needed to prevent that temporary classes that are
+ // introduced while parsing code fragments are being cached here.
+ {
+ //printf("setting cached typedef %p in result %p\n",md,result);
+ //printf("==> %s (%s,%d)\n",result->name().data(),result->getDefFileName().data(),result->getDefLine());
+ //printf("*pResolvedType=%s\n",pResolvedType?pResolvedType->data():"<none>");
+ md->cacheTypedefVal(result,
+ pTemplSpec ? *pTemplSpec : QCString(),
+ pResolvedType ? *pResolvedType : QCString()
+ );
+ }
+
+ g_resolvedTypedefs.remove(qname); // remove from the trace list
+
+ return result;
+}
+
+/*! Substitutes a simple unqualified \a name within \a scope. Returns the
+ * value of the typedef or \a name if no typedef was found.
+ */
+static QCString substTypedef(Definition *scope,FileDef *fileScope,const QCString &name,
+ MemberDef **pTypeDef=0)
+{
+ QCString result=name;
+ if (name.isEmpty()) return result;
+
+ // lookup scope fragment in the symbol map
+ DefinitionIntf *di = Doxygen::symbolMap->find(name);
+ if (di==0) return result; // no matches
+
+ MemberDef *bestMatch=0;
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multi symbols
+ {
+ // search for the best match
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *d;
+ int minDistance=10000; // init at "infinite"
+ for (dli.toFirst();(d=dli.current());++dli) // foreach definition
+ {
+ // only look at members
+ if (d->definitionType()==Definition::TypeMember)
+ {
+ // that are also typedefs
+ MemberDef *md = (MemberDef *)d;
+ if (md->isTypedef()) // d is a typedef
+ {
+ // test accessibility of typedef within scope.
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
+ if (distance!=-1 && distance<minDistance)
+ // definition is accessible and a better match
+ {
+ minDistance=distance;
+ bestMatch = md;
+ }
+ }
+ }
+ }
+ }
+ else if (di->definitionType()==DefinitionIntf::TypeMember) // single symbol
+ {
+ Definition *d = (Definition*)di;
+ // that are also typedefs
+ MemberDef *md = (MemberDef *)di;
+ if (md->isTypedef()) // d is a typedef
+ {
+ // test accessibility of typedef within scope.
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
+ if (distance!=-1) // definition is accessible
+ {
+ bestMatch = md;
+ }
+ }
+ }
+ if (bestMatch)
+ {
+ result = bestMatch->typeString();
+ if (pTypeDef) *pTypeDef=bestMatch;
+ }
+
+ //printf("substTypedef(%s,%s)=%s\n",scope?scope->name().data():"<global>",
+ // name.data(),result.data());
+ return result;
+}
+
+static Definition *endOfPathIsUsedClass(SDict<Definition> *cl,const QCString &localName)
+{
+ if (cl)
+ {
+ SDict<Definition>::Iterator cli(*cl);
+ Definition *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (cd->localName()==localName)
+ {
+ return cd;
+ }
+ }
+ }
+ return 0;
+}
+
+/*! Starting with scope \a start, the string \a path is interpreted as
+ * a part of a qualified scope name (e.g. A::B::C), and the scope is
+ * searched. If found the scope definition is returned, otherwise 0
+ * is returned.
+ */
+static Definition *followPath(Definition *start,FileDef *fileScope,const QCString &path)
+{
+ int is,ps;
+ int l;
+ Definition *current=start;
+ ps=0;
+ //printf("followPath: start='%s' path='%s'\n",start?start->name().data():"<none>",path.data());
+ // for each part of the explicit scope
+ while ((is=getScopeFragment(path,ps,&l))!=-1)
+ {
+ // try to resolve the part if it is a typedef
+ MemberDef *typeDef=0;
+ QCString qualScopePart = substTypedef(current,fileScope,path.mid(is,l),&typeDef);
+ //printf(" qualScopePart=%s\n",qualScopePart.data());
+ if (typeDef)
+ {
+ ClassDef *type = newResolveTypedef(fileScope,typeDef);
+ if (type)
+ {
+ //printf("Found type %s\n",type->name().data());
+ return type;
+ }
+ }
+ Definition *next = current->findInnerCompound(qualScopePart);
+ //printf("++ Looking for %s inside %s result %s\n",
+ // qualScopePart.data(),
+ // current->name().data(),
+ // next?next->name().data():"<null>");
+ if (next==0) // failed to follow the path
+ {
+ //printf("==> next==0!\n");
+ if (current->definitionType()==Definition::TypeNamespace)
+ {
+ next = endOfPathIsUsedClass(
+ ((NamespaceDef *)current)->getUsedClasses(),qualScopePart);
+ }
+ else if (current->definitionType()==Definition::TypeFile)
+ {
+ next = endOfPathIsUsedClass(
+ ((FileDef *)current)->getUsedClasses(),qualScopePart);
+ }
+ current = next;
+ if (current==0) break;
+ }
+ else // continue to follow scope
+ {
+ current = next;
+ //printf("==> current = %p\n",current);
+ }
+ ps=is+l;
+ }
+ //printf("followPath(start=%s,path=%s) result=%s\n",
+ // start->name().data(),path.data(),current?current->name().data():"<null>");
+ return current; // path could be followed
+}
+
+bool accessibleViaUsingClass(const SDict<Definition> *cl,
+ FileDef *fileScope,
+ Definition *item,
+ const QCString &explicitScopePart=""
+ )
+{
+ //printf("accessibleViaUsingClass(%p)\n",cl);
+ if (cl) // see if the class was imported via a using statement
+ {
+ SDict<Definition>::Iterator cli(*cl);
+ Definition *ucd;
+ bool explicitScopePartEmpty = explicitScopePart.isEmpty();
+ for (cli.toFirst();(ucd=cli.current());++cli)
+ {
+ //printf("Trying via used class %s\n",ucd->name().data());
+ Definition *sc = explicitScopePartEmpty ? ucd : followPath(ucd,fileScope,explicitScopePart);
+ if (sc && sc==item) return TRUE;
+ //printf("Try via used class done\n");
+ }
+ }
+ return FALSE;
+}
+
+bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
+ FileDef *fileScope,
+ Definition *item,
+ const QCString &explicitScopePart="")
+{
+ static QDict<void> visitedDict;
+ if (nl) // check used namespaces for the class
+ {
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *und;
+ int count=0;
+ for (nli.toFirst();(und=nli.current());++nli,count++)
+ {
+ //printf("[Trying via used namespace %s: count=%d/%d\n",und->name().data(),
+ // count,nl->count());
+ Definition *sc = explicitScopePart.isEmpty() ? und : followPath(und,fileScope,explicitScopePart);
+ if (sc && item->getOuterScope()==sc)
+ {
+ //printf("] found it\n");
+ return TRUE;
+ }
+ QCString key=und->name();
+ if (und->getUsedNamespaces() && visitedDict.find(key)==0)
+ {
+ visitedDict.insert(key,(void *)0x08);
+
+ if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart))
+ {
+ //printf("] found it via recursion\n");
+ return TRUE;
+ }
+
+ visitedDict.remove(key);
+ }
+ //printf("] Try via used namespace done\n");
+ }
+ }
+ return FALSE;
+}
+
+const int MAX_STACK_SIZE = 1000;
+
+/** Helper class representing the stack of items considered while resolving
+ * the scope.
+ */
+class AccessStack
+{
+ public:
+ AccessStack() : m_index(0) {}
+ void push(Definition *scope,FileDef *fileScope,Definition *item)
+ {
+ if (m_index<MAX_STACK_SIZE)
+ {
+ m_elements[m_index].scope = scope;
+ m_elements[m_index].fileScope = fileScope;
+ m_elements[m_index].item = item;
+ m_index++;
+ }
+ }
+ void push(Definition *scope,FileDef *fileScope,Definition *item,const QCString &expScope)
+ {
+ if (m_index<MAX_STACK_SIZE)
+ {
+ m_elements[m_index].scope = scope;
+ m_elements[m_index].fileScope = fileScope;
+ m_elements[m_index].item = item;
+ m_elements[m_index].expScope = expScope;
+ m_index++;
+ }
+ }
+ void pop()
+ {
+ if (m_index>0) m_index--;
+ }
+ bool find(Definition *scope,FileDef *fileScope, Definition *item)
+ {
+ int i=0;
+ for (i=0;i<m_index;i++)
+ {
+ AccessElem *e = &m_elements[i];
+ if (e->scope==scope && e->fileScope==fileScope && e->item==item)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ bool find(Definition *scope,FileDef *fileScope, Definition *item,const QCString &expScope)
+ {
+ int i=0;
+ for (i=0;i<m_index;i++)
+ {
+ AccessElem *e = &m_elements[i];
+ if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ private:
+ /** Element in the stack. */
+ struct AccessElem
+ {
+ Definition *scope;
+ FileDef *fileScope;
+ Definition *item;
+ QCString expScope;
+ };
+ int m_index;
+ AccessElem m_elements[MAX_STACK_SIZE];
+};
+
+/* Returns the "distance" (=number of levels up) from item to scope, or -1
+ * if item in not inside scope.
+ */
+int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
+{
+ //printf("<isAccesibleFrom(scope=%s,item=%s itemScope=%s)\n",
+ // scope->name().data(),item->name().data(),item->getOuterScope()->name().data());
+
+ static AccessStack accessStack;
+ if (accessStack.find(scope,fileScope,item))
+ {
+ return -1;
+ }
+ accessStack.push(scope,fileScope,item);
+
+ int result=0; // assume we found it
+ int i;
+
+ Definition *itemScope=item->getOuterScope();
+ bool memberAccessibleFromScope =
+ (item->definitionType()==Definition::TypeMember && // a member
+ itemScope && itemScope->definitionType()==Definition::TypeClass && // of a class
+ scope->definitionType()==Definition::TypeClass && // accessible
+ ((ClassDef*)scope)->isAccessibleMember((MemberDef *)item) // from scope
+ );
+ bool nestedClassInsideBaseClass =
+ (item->definitionType()==Definition::TypeClass && // a nested class
+ itemScope && itemScope->definitionType()==Definition::TypeClass && // inside a base
+ scope->definitionType()==Definition::TypeClass && // class of scope
+ ((ClassDef*)scope)->isBaseClass((ClassDef*)itemScope,TRUE)
+ );
+
+ if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass)
+ {
+ //printf("> found it\n");
+ if (nestedClassInsideBaseClass) result++; // penalty for base class to prevent
+ // this is preferred over nested class in this class
+ // see bug 686956
+ }
+ else if (scope==Doxygen::globalScope)
+ {
+ if (fileScope)
+ {
+ SDict<Definition> *cl = fileScope->getUsedClasses();
+ if (accessibleViaUsingClass(cl,fileScope,item))
+ {
+ //printf("> found via used class\n");
+ goto done;
+ }
+ NamespaceSDict *nl = fileScope->getUsedNamespaces();
+ if (accessibleViaUsingNamespace(nl,fileScope,item))
+ {
+ //printf("> found via used namespace\n");
+ goto done;
+ }
+ }
+ //printf("> reached global scope\n");
+ result=-1; // not found in path to globalScope
+ }
+ else // keep searching
+ {
+ // check if scope is a namespace, which is using other classes and namespaces
+ if (scope->definitionType()==Definition::TypeNamespace)
+ {
+ NamespaceDef *nscope = (NamespaceDef*)scope;
+ //printf(" %s is namespace with %d used classes\n",nscope->name().data(),nscope->getUsedClasses());
+ SDict<Definition> *cl = nscope->getUsedClasses();
+ if (accessibleViaUsingClass(cl,fileScope,item))
+ {
+ //printf("> found via used class\n");
+ goto done;
+ }
+ NamespaceSDict *nl = nscope->getUsedNamespaces();
+ if (accessibleViaUsingNamespace(nl,fileScope,item))
+ {
+ //printf("> found via used namespace\n");
+ goto done;
+ }
+ }
+ // repeat for the parent scope
+ i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
+ //printf("> result=%d\n",i);
+ result= (i==-1) ? -1 : i+2;
+ }
+done:
+ accessStack.pop();
+ //Doxygen::lookupCache.insert(key,new int(result));
+ return result;
+}
+
+
+/* Returns the "distance" (=number of levels up) from item to scope, or -1
+ * if item in not in this scope. The explicitScopePart limits the search
+ * to scopes that match \a scope (or its parent scope(s)) plus the explicit part.
+ * Example:
+ *
+ * class A { public: class I {}; };
+ * class B { public: class J {}; };
+ *
+ * - Looking for item=='J' inside scope=='B' will return 0.
+ * - Looking for item=='I' inside scope=='B' will return -1
+ * (as it is not found in B nor in the global scope).
+ * - Looking for item=='A::I' inside scope=='B', first the match B::A::I is tried but
+ * not found and then A::I is searched in the global scope, which matches and
+ * thus the result is 1.
+ */
+int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,
+ Definition *item,const QCString &explicitScopePart)
+{
+ if (explicitScopePart.isEmpty())
+ {
+ // handle degenerate case where there is no explicit scope.
+ return isAccessibleFrom(scope,fileScope,item);
+ }
+
+ static AccessStack accessStack;
+ if (accessStack.find(scope,fileScope,item,explicitScopePart))
+ {
+ return -1;
+ }
+ accessStack.push(scope,fileScope,item,explicitScopePart);
+
+
+ //printf(" <isAccessibleFromWithExpScope(%s,%s,%s)\n",scope?scope->name().data():"<global>",
+ // item?item->name().data():"<none>",
+ // explicitScopePart.data());
+ int result=0; // assume we found it
+ Definition *newScope = followPath(scope,fileScope,explicitScopePart);
+ if (newScope) // explicitScope is inside scope => newScope is the result
+ {
+ Definition *itemScope = item->getOuterScope();
+ //printf(" scope traversal successful %s<->%s!\n",itemScope->name().data(),newScope->name().data());
+ //if (newScope && newScope->definitionType()==Definition::TypeClass)
+ //{
+ // ClassDef *cd = (ClassDef *)newScope;
+ // printf("---> Class %s: bases=%p\n",cd->name().data(),cd->baseClasses());
+ //}
+ if (itemScope==newScope) // exact match of scopes => distance==0
+ {
+ //printf("> found it\n");
+ }
+ else if (itemScope && newScope &&
+ itemScope->definitionType()==Definition::TypeClass &&
+ newScope->definitionType()==Definition::TypeClass &&
+ ((ClassDef*)newScope)->isBaseClass((ClassDef*)itemScope,TRUE,0)
+ )
+ {
+ // inheritance is also ok. Example: looking for B::I, where
+ // class A { public: class I {} };
+ // class B : public A {}
+ // but looking for B::I, where
+ // class A { public: class I {} };
+ // class B { public: class I {} };
+ // will find A::I, so we still prefer a direct match and give this one a distance of 1
+ result=1;
+
+ //printf("scope(%s) is base class of newScope(%s)\n",
+ // scope->name().data(),newScope->name().data());
+ }
+ else
+ {
+ int i=-1;
+ if (newScope->definitionType()==Definition::TypeNamespace)
+ {
+ g_visitedNamespaces.insert(newScope->name(),newScope);
+ // this part deals with the case where item is a class
+ // A::B::C but is explicit referenced as A::C, where B is imported
+ // in A via a using directive.
+ //printf("newScope is a namespace: %s!\n",newScope->name().data());
+ NamespaceDef *nscope = (NamespaceDef*)newScope;
+ SDict<Definition> *cl = nscope->getUsedClasses();
+ if (cl)
+ {
+ SDict<Definition>::Iterator cli(*cl);
+ Definition *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ //printf("Trying for class %s\n",cd->name().data());
+ if (cd==item)
+ {
+ //printf("> class is used in this scope\n");
+ goto done;
+ }
+ }
+ }
+ NamespaceSDict *nl = nscope->getUsedNamespaces();
+ if (nl)
+ {
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (g_visitedNamespaces.find(nd->name())==0)
+ {
+ //printf("Trying for namespace %s\n",nd->name().data());
+ i = isAccessibleFromWithExpScope(scope,fileScope,item,nd->name());
+ if (i!=-1)
+ {
+ //printf("> found via explicit scope of used namespace\n");
+ goto done;
+ }
+ }
+ }
+ }
+ }
+ // repeat for the parent scope
+ if (scope!=Doxygen::globalScope)
+ {
+ i = isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope,
+ item,explicitScopePart);
+ }
+ //printf(" | result=%d\n",i);
+ result = (i==-1) ? -1 : i+2;
+ }
+ }
+ else // failed to resolve explicitScope
+ {
+ //printf(" failed to resolve: scope=%s\n",scope->name().data());
+ if (scope->definitionType()==Definition::TypeNamespace)
+ {
+ NamespaceDef *nscope = (NamespaceDef*)scope;
+ NamespaceSDict *nl = nscope->getUsedNamespaces();
+ if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
+ {
+ //printf("> found in used namespace\n");
+ goto done;
+ }
+ }
+ if (scope==Doxygen::globalScope)
+ {
+ if (fileScope)
+ {
+ NamespaceSDict *nl = fileScope->getUsedNamespaces();
+ if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
+ {
+ //printf("> found in used namespace\n");
+ goto done;
+ }
+ }
+ //printf("> not found\n");
+ result=-1;
+ }
+ else // continue by looking into the parent scope
+ {
+ int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope,
+ item,explicitScopePart);
+ //printf("> result=%d\n",i);
+ result= (i==-1) ? -1 : i+2;
+ }
+ }
+
+done:
+ //printf(" > result=%d\n",result);
+ accessStack.pop();
+ //Doxygen::lookupCache.insert(key,new int(result));
+ return result;
+}
+
+int computeQualifiedIndex(const QCString &name)
+{
+ int i = name.find('<');
+ return name.findRev("::",i==-1 ? name.length() : i);
+}
+
+static void getResolvedSymbol(Definition *scope,
+ FileDef *fileScope,
+ Definition *d,
+ const QCString &explicitScopePart,
+ ArgumentList *actTemplParams,
+ int &minDistance,
+ ClassDef *&bestMatch,
+ MemberDef *&bestTypedef,
+ QCString &bestTemplSpec,
+ QCString &bestResolvedType
+ )
+{
+ //printf(" => found type %x name=%s d=%p\n",
+ // d->definitionType(),d->name().data(),d);
+
+ // only look at classes and members that are enums or typedefs
+ if (d->definitionType()==Definition::TypeClass ||
+ (d->definitionType()==Definition::TypeMember &&
+ (((MemberDef*)d)->isTypedef() || ((MemberDef*)d)->isEnumerate())
+ )
+ )
+ {
+ g_visitedNamespaces.clear();
+ // test accessibility of definition within scope.
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ //printf(" %s; distance %s (%p) is %d\n",scope->name().data(),d->name().data(),d,distance);
+ if (distance!=-1) // definition is accessible
+ {
+ // see if we are dealing with a class or a typedef
+ if (d->definitionType()==Definition::TypeClass) // d is a class
+ {
+ ClassDef *cd = (ClassDef *)d;
+ //printf("cd=%s\n",cd->name().data());
+ if (!cd->isTemplateArgument()) // skip classes that
+ // are only there to
+ // represent a template
+ // argument
+ {
+ //printf("is not a templ arg\n");
+ if (distance<minDistance) // found a definition that is "closer"
+ {
+ minDistance=distance;
+ bestMatch = cd;
+ bestTypedef = 0;
+ bestTemplSpec.resize(0);
+ bestResolvedType = cd->qualifiedName();
+ }
+ else if (distance==minDistance &&
+ fileScope && bestMatch &&
+ fileScope->getUsedNamespaces() &&
+ d->getOuterScope()->definitionType()==Definition::TypeNamespace &&
+ bestMatch->getOuterScope()==Doxygen::globalScope
+ )
+ {
+ // in case the distance is equal it could be that a class X
+ // is defined in a namespace and in the global scope. When searched
+ // in the global scope the distance is 0 in both cases. We have
+ // to choose one of the definitions: we choose the one in the
+ // namespace if the fileScope imports namespaces and the definition
+ // found was in a namespace while the best match so far isn't.
+ // Just a non-perfect heuristic but it could help in some situations
+ // (kdecore code is an example).
+ minDistance=distance;
+ bestMatch = cd;
+ bestTypedef = 0;
+ bestTemplSpec.resize(0);
+ bestResolvedType = cd->qualifiedName();
+ }
+ }
+ else
+ {
+ //printf(" is a template argument!\n");
+ }
+ }
+ else if (d->definitionType()==Definition::TypeMember)
+ {
+ MemberDef *md = (MemberDef *)d;
+ //printf(" member isTypedef()=%d\n",md->isTypedef());
+ if (md->isTypedef()) // d is a typedef
+ {
+ QCString args=md->argsString();
+ if (args.isEmpty()) // do not expand "typedef t a[4];"
+ {
+ //printf(" found typedef!\n");
+
+ // we found a symbol at this distance, but if it didn't
+ // resolve to a class, we still have to make sure that
+ // something at a greater distance does not match, since
+ // that symbol is hidden by this one.
+ if (distance<minDistance)
+ {
+ QCString spec;
+ QCString type;
+ minDistance=distance;
+ MemberDef *enumType = 0;
+ ClassDef *cd = newResolveTypedef(fileScope,md,&enumType,&spec,&type,actTemplParams);
+ if (cd) // type resolves to a class
+ {
+ //printf(" bestTypeDef=%p spec=%s type=%s\n",md,spec.data(),type.data());
+ bestMatch = cd;
+ bestTypedef = md;
+ bestTemplSpec = spec;
+ bestResolvedType = type;
+ }
+ else if (enumType) // type resolves to a enum
+ {
+ //printf(" is enum\n");
+ bestMatch = 0;
+ bestTypedef = enumType;
+ bestTemplSpec = "";
+ bestResolvedType = enumType->qualifiedName();
+ }
+ else if (md->isReference()) // external reference
+ {
+ bestMatch = 0;
+ bestTypedef = md;
+ bestTemplSpec = spec;
+ bestResolvedType = type;
+ }
+ else
+ {
+ bestMatch = 0;
+ bestTypedef = md;
+ bestTemplSpec.resize(0);
+ bestResolvedType.resize(0);
+ //printf(" no match\n");
+ }
+ }
+ else
+ {
+ //printf(" not the best match %d min=%d\n",distance,minDistance);
+ }
+ }
+ else
+ {
+ //printf(" not a simple typedef\n")
+ }
+ }
+ else if (md->isEnumerate())
+ {
+ if (distance<minDistance)
+ {
+ minDistance=distance;
+ bestMatch = 0;
+ bestTypedef = md;
+ bestTemplSpec = "";
+ bestResolvedType = md->qualifiedName();
+ }
+ }
+ }
+ } // if definition accessible
+ else
+ {
+ //printf(" Not accessible!\n");
+ }
+ } // if definition is a class or member
+ //printf(" bestMatch=%p bestResolvedType=%s\n",bestMatch,bestResolvedType.data());
+}
+
+/* Find the fully qualified class name referred to by the input class
+ * or typedef name against the input scope.
+ * Loops through scope and each of its parent scopes looking for a
+ * match against the input name. Can recursively call itself when
+ * resolving typedefs.
+ */
+static ClassDef *getResolvedClassRec(Definition *scope,
+ FileDef *fileScope,
+ const char *n,
+ MemberDef **pTypeDef,
+ QCString *pTemplSpec,
+ QCString *pResolvedType
+ )
+{
+ //printf("[getResolvedClassRec(%s,%s)\n",scope?scope->name().data():"<global>",n);
+ QCString name;
+ QCString explicitScopePart;
+ QCString strippedTemplateParams;
+ name=stripTemplateSpecifiersFromScope
+ (removeRedundantWhiteSpace(n),TRUE,
+ &strippedTemplateParams);
+ ArgumentList actTemplParams;
+ if (!strippedTemplateParams.isEmpty()) // template part that was stripped
+ {
+ stringToArgumentList(strippedTemplateParams,&actTemplParams);
+ }
+
+ int qualifierIndex = computeQualifiedIndex(name);
+ //printf("name=%s qualifierIndex=%d\n",name.data(),qualifierIndex);
+ if (qualifierIndex!=-1) // qualified name
+ {
+ // split off the explicit scope part
+ explicitScopePart=name.left(qualifierIndex);
+ // todo: improve namespace alias substitution
+ replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
+ name=name.mid(qualifierIndex+2);
+ }
+
+ if (name.isEmpty())
+ {
+ //printf("] empty name\n");
+ return 0; // empty name
+ }
+
+ //printf("Looking for symbol %s\n",name.data());
+ DefinitionIntf *di = Doxygen::symbolMap->find(name);
+ // the -g (for C# generics) and -p (for ObjC protocols) are now already
+ // stripped from the key used in the symbolMap, so that is not needed here.
+ if (di==0)
+ {
+ //di = Doxygen::symbolMap->find(name+"-g");
+ //if (di==0)
+ //{
+ di = Doxygen::symbolMap->find(name+"-p");
+ if (di==0)
+ {
+ //printf("no such symbol!\n");
+ return 0;
+ }
+ //}
+ }
+ //printf("found symbol!\n");
+
+ bool hasUsingStatements =
+ (fileScope && ((fileScope->getUsedNamespaces() &&
+ fileScope->getUsedNamespaces()->count()>0) ||
+ (fileScope->getUsedClasses() &&
+ fileScope->getUsedClasses()->count()>0))
+ );
+ //printf("hasUsingStatements=%d\n",hasUsingStatements);
+ // Since it is often the case that the same name is searched in the same
+ // scope over an over again (especially for the linked source code generation)
+ // we use a cache to collect previous results. This is possible since the
+ // result of a lookup is deterministic. As the key we use the concatenated
+ // scope, the name to search for and the explicit scope prefix. The speedup
+ // achieved by this simple cache can be enormous.
+ int scopeNameLen = scope->name().length()+1;
+ int nameLen = name.length()+1;
+ int explicitPartLen = explicitScopePart.length();
+ int fileScopeLen = hasUsingStatements ? 1+fileScope->absFilePath().length() : 0;
+
+ // below is a more efficient coding of
+ // QCString key=scope->name()+"+"+name+"+"+explicitScopePart;
+ QCString key(scopeNameLen+nameLen+explicitPartLen+fileScopeLen+1);
+ char *p=key.data();
+ qstrcpy(p,scope->name()); *(p+scopeNameLen-1)='+';
+ p+=scopeNameLen;
+ qstrcpy(p,name); *(p+nameLen-1)='+';
+ p+=nameLen;
+ qstrcpy(p,explicitScopePart);
+ p+=explicitPartLen;
+
+ // if a file scope is given and it contains using statements we should
+ // also use the file part in the key (as a class name can be in
+ // two different namespaces and a using statement in a file can select
+ // one of them).
+ if (hasUsingStatements)
+ {
+ // below is a more efficient coding of
+ // key+="+"+fileScope->name();
+ *p++='+';
+ qstrcpy(p,fileScope->absFilePath());
+ p+=fileScopeLen-1;
+ }
+ *p='\0';
+
+ LookupInfo *pval=Doxygen::lookupCache->find(key);
+ //printf("Searching for %s result=%p\n",key.data(),pval);
+ if (pval)
+ {
+ //printf("LookupInfo %p %p '%s' %p\n",
+ // pval->classDef, pval->typeDef, pval->templSpec.data(),
+ // pval->resolvedType.data());
+ if (pTemplSpec) *pTemplSpec=pval->templSpec;
+ if (pTypeDef) *pTypeDef=pval->typeDef;
+ if (pResolvedType) *pResolvedType=pval->resolvedType;
+ //printf("] cachedMatch=%s\n",
+ // pval->classDef?pval->classDef->name().data():"<none>");
+ //if (pTemplSpec)
+ // printf("templSpec=%s\n",pTemplSpec->data());
+ return pval->classDef;
+ }
+ else // not found yet; we already add a 0 to avoid the possibility of
+ // endless recursion.
+ {
+ Doxygen::lookupCache->insert(key,new LookupInfo);
+ }
+
+ ClassDef *bestMatch=0;
+ MemberDef *bestTypedef=0;
+ QCString bestTemplSpec;
+ QCString bestResolvedType;
+ int minDistance=10000; // init at "infinite"
+
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name
+ {
+ //printf(" name is not unique\n");
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *d;
+ int count=0;
+ for (dli.toFirst();(d=dli.current());++dli,++count) // foreach definition
+ {
+ getResolvedSymbol(scope,fileScope,d,explicitScopePart,&actTemplParams,
+ minDistance,bestMatch,bestTypedef,bestTemplSpec,
+ bestResolvedType);
+ }
+ }
+ else // unique name
+ {
+ //printf(" name is unique\n");
+ Definition *d = (Definition *)di;
+ getResolvedSymbol(scope,fileScope,d,explicitScopePart,&actTemplParams,
+ minDistance,bestMatch,bestTypedef,bestTemplSpec,
+ bestResolvedType);
+ }
+
+ if (pTypeDef)
+ {
+ *pTypeDef = bestTypedef;
+ }
+ if (pTemplSpec)
+ {
+ *pTemplSpec = bestTemplSpec;
+ }
+ if (pResolvedType)
+ {
+ *pResolvedType = bestResolvedType;
+ }
+ //printf("getResolvedClassRec: bestMatch=%p pval->resolvedType=%s\n",
+ // bestMatch,bestResolvedType.data());
+
+ pval=Doxygen::lookupCache->find(key);
+ if (pval)
+ {
+ pval->classDef = bestMatch;
+ pval->typeDef = bestTypedef;
+ pval->templSpec = bestTemplSpec;
+ pval->resolvedType = bestResolvedType;
+ }
+ else
+ {
+ Doxygen::lookupCache->insert(key,new LookupInfo(bestMatch,bestTypedef,bestTemplSpec,bestResolvedType));
+ }
+ //printf("] bestMatch=%s distance=%d\n",
+ // bestMatch?bestMatch->name().data():"<none>",minDistance);
+ //if (pTemplSpec)
+ // printf("templSpec=%s\n",pTemplSpec->data());
+ return bestMatch;
+}
+
+/* Find the fully qualified class name referred to by the input class
+ * or typedef name against the input scope.
+ * Loops through scope and each of its parent scopes looking for a
+ * match against the input name.
+ */
+ClassDef *getResolvedClass(Definition *scope,
+ FileDef *fileScope,
+ const char *n,
+ MemberDef **pTypeDef,
+ QCString *pTemplSpec,
+ bool mayBeUnlinkable,
+ bool mayBeHidden,
+ QCString *pResolvedType
+ )
+{
+ static bool optimizeOutputVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ g_resolvedTypedefs.clear();
+ if (scope==0 ||
+ (scope->definitionType()!=Definition::TypeClass &&
+ scope->definitionType()!=Definition::TypeNamespace
+ ) ||
+ (scope->getLanguage()==SrcLangExt_Java && QCString(n).find("::")!=-1)
+ )
+ {
+ scope=Doxygen::globalScope;
+ }
+ //printf("------------ getResolvedClass(scope=%s,file=%s,name=%s,mayUnlinkable=%d)\n",
+ // scope?scope->name().data():"<global>",
+ // fileScope?fileScope->name().data():"<none>",
+ // n,
+ // mayBeUnlinkable
+ // );
+ ClassDef *result;
+ if (optimizeOutputVhdl)
+ {
+ result = getClass(n);
+ }
+ else
+ {
+ result = getResolvedClassRec(scope,fileScope,n,pTypeDef,pTemplSpec,pResolvedType);
+ }
+ if (result==0) // for nested classes imported via tag files, the scope may not
+ // present, so we check the class name directly as well.
+ // See also bug701314
+ {
+ result = getClass(n);
+ }
+ if (!mayBeUnlinkable && result && !result->isLinkable())
+ {
+ if (!mayBeHidden || !result->isHidden())
+ {
+ //printf("result was %s\n",result?result->name().data():"<none>");
+ result=0; // don't link to artificial/hidden classes unless explicitly allowed
+ }
+ }
+ //printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"<global>",
+ // n,result?result->name().data():"<none>");
+ return result;
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+static bool findOperator(const QCString &s,int i)
+{
+ int b = s.findRev("operator",i);
+ if (b==-1) return FALSE; // not found
+ b+=8;
+ while (b<i) // check if there are only spaces in between
+ // the operator and the >
+ {
+ if (!isspace((uchar)s.at(b))) return FALSE;
+ b++;
+ }
+ return TRUE;
+}
+
+static bool findOperator2(const QCString &s,int i)
+{
+ int b = s.findRev("operator",i);
+ if (b==-1) return FALSE; // not found
+ b+=8;
+ while (b<i) // check if there are only non-ascii
+ // characters in front of the operator
+ {
+ if (isId((uchar)s.at(b))) return FALSE;
+ b++;
+ }
+ return TRUE;
+}
+
+static const char constScope[] = { 'c', 'o', 'n', 's', 't', ':' };
+static const char virtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' };
+
+// Note: this function is not reentrant due to the use of static buffer!
+QCString removeRedundantWhiteSpace(const QCString &s)
+{
+ static bool cliSupport = Config_getBool("CPP_CLI_SUPPORT");
+ static bool vhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+
+ if (s.isEmpty() || vhdl) return s;
+ static GrowBuf growBuf;
+ //int resultLen = 1024;
+ //int resultPos = 0;
+ //QCString result(resultLen);
+ // we use growBuf.addChar(c) instead of result+=c to
+ // improve the performance of this function
+ growBuf.clear();
+ uint i;
+ uint l=s.length();
+ uint csp=0;
+ uint vsp=0;
+ char c;
+ for (i=0;i<l;i++)
+ {
+nextChar:
+ c=s.at(i);
+
+ // search for "const"
+ if (csp<6 && c==constScope[csp] && // character matches substring "const"
+ (csp>0 || // if it is the first character
+ i==0 || // the previous may not be a digit
+ !isId(s.at(i-1))
+ )
+ )
+ csp++;
+ else // reset counter
+ csp=0;
+
+ // search for "virtual"
+ if (vsp<8 && c==virtualScope[vsp] && // character matches substring "virtual"
+ (vsp>0 || // if it is the first character
+ i==0 || // the previous may not be a digit
+ !isId(s.at(i-1))
+ )
+ )
+ vsp++;
+ else // reset counter
+ vsp=0;
+
+ if (c=='"') // quoted string
+ {
+ i++;
+ growBuf.addChar(c);
+ while (i<l)
+ {
+ char cc=s.at(i);
+ growBuf.addChar(cc);
+ if (cc=='\\') // escaped character
+ {
+ growBuf.addChar(s.at(i+1));
+ i+=2;
+ }
+ else if (cc=='"') // end of string
+ { i++; goto nextChar; }
+ else // any other character
+ { i++; }
+ }
+ }
+ else if (i<l-2 && c=='<' && // current char is a <
+ (isId(s.at(i+1)) || isspace((uchar)s.at(i+1))) && // next char is an id char or space
+ (i<8 || !findOperator(s,i)) // string in front is not "operator"
+ )
+ {
+ growBuf.addChar('<');
+ growBuf.addChar(' ');
+ }
+ else if (i>0 && c=='>' && // current char is a >
+ (isId(s.at(i-1)) || isspace((uchar)s.at(i-1)) || s.at(i-1)=='*' || s.at(i-1)=='&') && // prev char is an id char or space
+ (i<8 || !findOperator(s,i)) // string in front is not "operator"
+ )
+ {
+ growBuf.addChar(' ');
+ growBuf.addChar('>');
+ }
+ else if (i>0 && c==',' && !isspace((uchar)s.at(i-1))
+ && ((i<l-1 && (isId(s.at(i+1)) || s.at(i+1)=='[')) // the [ is for attributes (see bug702170)
+ || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2))) // for PHP
+ || (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3))))) // for PHP
+ {
+ growBuf.addChar(',');
+ growBuf.addChar(' ');
+ }
+ else if (i>0 &&
+ (
+ (s.at(i-1)==')' && isId(c))
+ ||
+ (c=='\'' && s.at(i-1)==' ')
+ )
+ )
+ {
+ growBuf.addChar(' ');
+ growBuf.addChar(c);
+ }
+ else if (c=='t' && csp==5 /*&& (i<5 || !isId(s.at(i-5)))*/ &&
+ !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ ||
+ s.at(i+1)==')' ||
+ s.at(i+1)==',' ||
+ s.at(i+1)=='\0'
+ )
+ )
+ // prevent const ::A from being converted to const::A
+ {
+ growBuf.addChar('t');
+ growBuf.addChar(' ');
+ if (s.at(i+1)==' ') i++;
+ csp=0;
+ }
+ else if (c==':' && csp==6 /*&& (i<6 || !isId(s.at(i-6)))*/)
+ // replace const::A by const ::A
+ {
+ growBuf.addChar(' ');
+ growBuf.addChar(':');
+ csp=0;
+ }
+ else if (c=='l' && vsp==7 /*&& (i<7 || !isId(s.at(i-7)))*/ &&
+ !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ ||
+ s.at(i+1)==')' ||
+ s.at(i+1)==',' ||
+ s.at(i+1)=='\0'
+ )
+ )
+ // prevent virtual ::A from being converted to virtual::A
+ {
+ growBuf.addChar('l');
+ growBuf.addChar(' ');
+ if (s.at(i+1)==' ') i++;
+ vsp=0;
+ }
+ else if (c==':' && vsp==8 /*&& (i<8 || !isId(s.at(i-8)))*/)
+ // replace virtual::A by virtual ::A
+ {
+ growBuf.addChar(' ');
+ growBuf.addChar(':');
+ vsp=0;
+ }
+ else if (!isspace((uchar)c) || // not a space
+ ( i>0 && i<l-1 && // internal character
+ (isId(s.at(i-1)) || s.at(i-1)==')' || s.at(i-1)==',' || s.at(i-1)=='>' || s.at(i-1)==']') &&
+ (isId(s.at(i+1)) ||
+ (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2))) ||
+ (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3)))
+ )
+ )
+ )
+ {
+ if (c=='\t') c=' ';
+ if (c=='*' || c=='&' || c=='@' || c=='$')
+ {
+ //uint rl=result.length();
+ uint rl=growBuf.getPos();
+ if ((rl>0 && (isId(growBuf.at(rl-1)) || growBuf.at(rl-1)=='>')) &&
+ ((c!='*' && c!='&') || !findOperator2(s,i)) // avoid splitting operator* and operator->* and operator&
+ )
+ {
+ growBuf.addChar(' ');
+ }
+ }
+ else if (c=='-')
+ {
+ uint rl=growBuf.getPos();
+ if (rl>0 && growBuf.at(rl-1)==')' && i<l-1 && s.at(i+1)=='>') // trailing return type ')->' => ') ->'
+ {
+ growBuf.addChar(' ');
+ }
+ }
+ growBuf.addChar(c);
+ if (cliSupport &&
+ (c=='^' || c=='%') && i>1 && isId(s.at(i-1)) &&
+ !findOperator(s,i)
+ )
+ {
+ growBuf.addChar(' '); // C++/CLI: Type^ name and Type% name
+ }
+ }
+ }
+ growBuf.addChar(0);
+ //printf("removeRedundantWhiteSpace(`%s')=`%s'\n",s.data(),growBuf.get());
+ //result.resize(resultPos);
+ return growBuf.get();
+}
+
+/**
+ * Returns the position in the string where a function parameter list
+ * begins, or -1 if one is not found.
+ */
+int findParameterList(const QCString &name)
+{
+ int pos=-1;
+ int templateDepth=0;
+ do
+ {
+ if (templateDepth > 0)
+ {
+ int nextOpenPos=name.findRev('>', pos);
+ int nextClosePos=name.findRev('<', pos);
+ if (nextOpenPos!=-1 && nextOpenPos>nextClosePos)
+ {
+ ++templateDepth;
+ pos=nextOpenPos-1;
+ }
+ else if (nextClosePos!=-1)
+ {
+ --templateDepth;
+ pos=nextClosePos-1;
+ }
+ else // more >'s than <'s, see bug701295
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ int lastAnglePos=name.findRev('>', pos);
+ int bracePos=name.findRev('(', pos);
+ if (lastAnglePos!=-1 && lastAnglePos>bracePos)
+ {
+ ++templateDepth;
+ pos=lastAnglePos-1;
+ }
+ else
+ {
+ int bp = bracePos>0 ? name.findRev('(',bracePos-1) : -1;
+ // bp test is to allow foo(int(&)[10]), but we need to make an exception for operator()
+ return bp==-1 || (bp>=8 && name.mid(bp-8,10)=="operator()") ? bracePos : bp;
+ }
+ }
+ } while (pos!=-1);
+ return -1;
+}
+
+bool rightScopeMatch(const QCString &scope, const QCString &name)
+{
+ int sl=scope.length();
+ int nl=name.length();
+ return (name==scope || // equal
+ (scope.right(nl)==name && // substring
+ sl-nl>1 && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
+ )
+ );
+}
+
+bool leftScopeMatch(const QCString &scope, const QCString &name)
+{
+ int sl=scope.length();
+ int nl=name.length();
+ return (name==scope || // equal
+ (scope.left(nl)==name && // substring
+ sl>nl+1 && scope.at(nl)==':' && scope.at(nl+1)==':' // scope
+ )
+ );
+}
+
+
+void linkifyText(const TextGeneratorIntf &out,Definition *scope,
+ FileDef *fileScope,Definition *self,
+ const char *text, bool autoBreak,bool external,
+ bool keepSpaces,int indentLevel)
+{
+ //printf("linkify=`%s'\n",text);
+ static QRegExp regExp("[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9$\\\\.:\\x80-\\xFF]*");
+ static QRegExp regExpSplit("(?!:),");
+ QCString txtStr=text;
+ int strLen = txtStr.length();
+ //printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%d external=%d\n",
+ // scope?scope->name().data():"<none>",
+ // fileScope?fileScope->name().data():"<none>",
+ // txtStr.data(),strLen,external);
+ int matchLen;
+ int index=0;
+ int newIndex;
+ int skipIndex=0;
+ int floatingIndex=0;
+ if (strLen==0) return;
+ // read a word from the text string
+ while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1 &&
+ (newIndex==0 || !(txtStr.at(newIndex-1)>='0' && txtStr.at(newIndex-1)<='9')) // avoid matching part of hex numbers
+ )
+ {
+ // add non-word part to the result
+ floatingIndex+=newIndex-skipIndex+matchLen;
+ bool insideString=FALSE;
+ int i;
+ for (i=index;i<newIndex;i++)
+ {
+ if (txtStr.at(i)=='"') insideString=!insideString;
+ }
+
+ //printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak);
+ if (strLen>35 && floatingIndex>30 && autoBreak) // try to insert a split point
+ {
+ QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex);
+ int splitLength = splitText.length();
+ int offset=1;
+ i=splitText.find(regExpSplit,0);
+ if (i==-1) { i=splitText.find('<'); if (i!=-1) offset=0; }
+ if (i==-1) i=splitText.find('>');
+ if (i==-1) i=splitText.find(' ');
+ //printf("splitText=[%s] len=%d i=%d offset=%d\n",splitText.data(),splitLength,i,offset);
+ if (i!=-1) // add a link-break at i in case of Html output
+ {
+ out.writeString(splitText.left(i+offset),keepSpaces);
+ out.writeBreak(indentLevel==0 ? 0 : indentLevel+1);
+ out.writeString(splitText.right(splitLength-i-offset),keepSpaces);
+ floatingIndex=splitLength-i-offset+matchLen;
+ }
+ else
+ {
+ out.writeString(splitText,keepSpaces);
+ }
+ }
+ else
+ {
+ //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
+ out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex),keepSpaces);
+ }
+ // get word from string
+ QCString word=txtStr.mid(newIndex,matchLen);
+ QCString matchWord = substitute(substitute(word,"\\","::"),".","::");
+ //printf("linkifyText word=%s matchWord=%s scope=%s\n",
+ // word.data(),matchWord.data(),scope?scope->name().data():"<none>");
+ bool found=FALSE;
+ if (!insideString)
+ {
+ ClassDef *cd=0;
+ FileDef *fd=0;
+ MemberDef *md=0;
+ NamespaceDef *nd=0;
+ GroupDef *gd=0;
+ //printf("** Match word '%s'\n",matchWord.data());
+
+ MemberDef *typeDef=0;
+ cd=getResolvedClass(scope,fileScope,matchWord,&typeDef);
+ if (typeDef) // First look at typedef then class, see bug 584184.
+ {
+ //printf("Found typedef %s\n",typeDef->name().data());
+ if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject())
+ {
+ if (typeDef->getOuterScope()!=self)
+ {
+ out.writeLink(typeDef->getReference(),
+ typeDef->getOutputFileBase(),
+ typeDef->anchor(),
+ word);
+ found=TRUE;
+ }
+ }
+ }
+ if (!found && (cd || (cd=getClass(matchWord))))
+ {
+ //printf("Found class %s\n",cd->name().data());
+ // add link to the result
+ if (external ? cd->isLinkable() : cd->isLinkableInProject())
+ {
+ if (cd!=self)
+ {
+ out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
+ found=TRUE;
+ }
+ }
+ }
+ else if ((cd=getClass(matchWord+"-p"))) // search for Obj-C protocols as well
+ {
+ // add link to the result
+ if (external ? cd->isLinkable() : cd->isLinkableInProject())
+ {
+ if (cd!=self)
+ {
+ out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
+ found=TRUE;
+ }
+ }
+ }
+// else if ((cd=getClass(matchWord+"-g"))) // C# generic as well
+// {
+// // add link to the result
+// if (external ? cd->isLinkable() : cd->isLinkableInProject())
+// {
+// if (cd!=self)
+// {
+// out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
+// found=TRUE;
+// }
+// }
+// }
+ else
+ {
+ //printf(" -> nothing\n");
+ }
+
+ int m = matchWord.findRev("::");
+ QCString scopeName;
+ if (scope &&
+ (scope->definitionType()==Definition::TypeClass ||
+ scope->definitionType()==Definition::TypeNamespace
+ )
+ )
+ {
+ scopeName=scope->name();
+ }
+ else if (m!=-1)
+ {
+ scopeName = matchWord.left(m);
+ matchWord = matchWord.mid(m+2);
+ }
+
+ //printf("ScopeName=%s\n",scopeName.data());
+ //if (!found) printf("Trying to link %s in %s\n",word.data(),scopeName.data());
+ if (!found &&
+ getDefs(scopeName,matchWord,0,md,cd,fd,nd,gd) &&
+ //(md->isTypedef() || md->isEnumerate() ||
+ // md->isReference() || md->isVariable()
+ //) &&
+ (external ? md->isLinkable() : md->isLinkableInProject())
+ )
+ {
+ //printf("Found ref scope=%s\n",d?d->name().data():"<global>");
+ //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
+ // md->anchor(),word);
+ if (md!=self && (self==0 || md->name()!=self->name()))
+ // name check is needed for overloaded members, where getDefs just returns one
+ {
+ out.writeLink(md->getReference(),md->getOutputFileBase(),
+ md->anchor(),word);
+ //printf("found symbol %s\n",matchWord.data());
+ found=TRUE;
+ }
+ }
+ }
+
+ if (!found) // add word to the result
+ {
+ out.writeString(word,keepSpaces);
+ }
+ // set next start point in the string
+ //printf("index=%d/%d\n",index,txtStr.length());
+ skipIndex=index=newIndex+matchLen;
+ }
+ // add last part of the string to the result.
+ //ol.docify(txtStr.right(txtStr.length()-skipIndex));
+ out.writeString(txtStr.right(txtStr.length()-skipIndex),keepSpaces);
+}
+
+
+void writeExample(OutputList &ol,ExampleSDict *ed)
+{
+ QCString exampleLine=theTranslator->trWriteList(ed->count());
+
+ //bool latexEnabled = ol.isEnabled(OutputGenerator::Latex);
+ //bool manEnabled = ol.isEnabled(OutputGenerator::Man);
+ //bool htmlEnabled = ol.isEnabled(OutputGenerator::Html);
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(exampleLine,index,&matchLen))!=-1)
+ {
+ bool ok;
+ ol.parseText(exampleLine.mid(index,newIndex-index));
+ uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ Example *e=ed->at(entryIndex);
+ if (ok && e)
+ {
+ ol.pushGeneratorState();
+ //if (latexEnabled) ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::RTF);
+ // link for Html / man
+ //printf("writeObjectLink(file=%s)\n",e->file.data());
+ ol.writeObjectLink(0,e->file,e->anchor,e->name);
+ ol.popGeneratorState();
+
+ ol.pushGeneratorState();
+ //if (latexEnabled) ol.enable(OutputGenerator::Latex);
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Html);
+ // link for Latex / pdf with anchor because the sources
+ // are not hyperlinked (not possible with a verbatim environment).
+ ol.writeObjectLink(0,e->file,0,e->name);
+ //if (manEnabled) ol.enable(OutputGenerator::Man);
+ //if (htmlEnabled) ol.enable(OutputGenerator::Html);
+ ol.popGeneratorState();
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(exampleLine.right(exampleLine.length()-index));
+ ol.writeString(".");
+}
+
+
+QCString argListToString(ArgumentList *al,bool useCanonicalType,bool showDefVals)
+{
+ QCString result;
+ if (al==0) return result;
+ ArgumentListIterator ali(*al);
+ Argument *a=ali.current();
+ result+="(";
+ while (a)
+ {
+ QCString type1 = useCanonicalType && !a->canType.isEmpty() ?
+ a->canType : a->type;
+ QCString type2;
+ int i=type1.find(")("); // hack to deal with function pointers
+ if (i!=-1)
+ {
+ type2=type1.mid(i);
+ type1=type1.left(i);
+ }
+ if (!a->attrib.isEmpty())
+ {
+ result+=a->attrib+" ";
+ }
+ if (!a->name.isEmpty() || !a->array.isEmpty())
+ {
+ result+= type1+" "+a->name+type2+a->array;
+ }
+ else
+ {
+ result+= type1+type2;
+ }
+ if (!a->defval.isEmpty() && showDefVals)
+ {
+ result+="="+a->defval;
+ }
+ ++ali;
+ a = ali.current();
+ if (a) result+=", ";
+ }
+ result+=")";
+ if (al->constSpecifier) result+=" const";
+ if (al->volatileSpecifier) result+=" volatile";
+ if (!al->trailingReturnType.isEmpty()) result+=" -> "+al->trailingReturnType;
+ if (al->pureSpecifier) result+=" =0";
+ return removeRedundantWhiteSpace(result);
+}
+
+QCString tempArgListToString(ArgumentList *al)
+{
+ QCString result;
+ if (al==0) return result;
+ result="<";
+ ArgumentListIterator ali(*al);
+ Argument *a=ali.current();
+ while (a)
+ {
+ if (!a->name.isEmpty()) // add template argument name
+ {
+ if (a->type.left(4)=="out") // C# covariance
+ {
+ result+="out ";
+ }
+ else if (a->type.left(3)=="in") // C# contravariance
+ {
+ result+="in ";
+ }
+ result+=a->name;
+ }
+ else // extract name from type
+ {
+ int i=a->type.length()-1;
+ while (i>=0 && isId(a->type.at(i))) i--;
+ if (i>0)
+ {
+ result+=a->type.right(a->type.length()-i-1);
+ }
+ else // nothing found -> take whole name
+ {
+ result+=a->type;
+ }
+ }
+ ++ali;
+ a=ali.current();
+ if (a) result+=", ";
+ }
+ result+=">";
+ return removeRedundantWhiteSpace(result);
+}
+
+
+// compute the HTML anchors for a list of members
+void setAnchors(MemberList *ml)
+{
+ //int count=0;
+ if (ml==0) return;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (;(md=mli.current());++mli)
+ {
+ if (!md->isReference())
+ {
+ //QCString anchor;
+ //if (groupId==-1)
+ // anchor.sprintf("%c%d",id,count++);
+ //else
+ // anchor.sprintf("%c%d_%d",id,groupId,count++);
+ //if (cd) anchor.prepend(escapeCharsInString(cd->name(),FALSE));
+ md->setAnchor();
+ //printf("setAnchors(): Member %s outputFileBase=%s anchor %s result %s\n",
+ // md->name().data(),md->getOutputFileBase().data(),anchor.data(),md->anchor().data());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+/*! takes the \a buf of the given length \a len and converts CR LF (DOS)
+ * or CR (MAC) line ending to LF (Unix). Returns the length of the
+ * converted content (i.e. the same as \a len (Unix, MAC) or
+ * smaller (DOS).
+ */
+int filterCRLF(char *buf,int len)
+{
+ int src = 0; // source index
+ int dest = 0; // destination index
+ char c; // current character
+
+ while (src<len)
+ {
+ c = buf[src++]; // Remember the processed character.
+ if (c == '\r') // CR to be solved (MAC, DOS)
+ {
+ c = '\n'; // each CR to LF
+ if (src<len && buf[src] == '\n')
+ ++src; // skip LF just after CR (DOS)
+ }
+ else if ( c == '\0' && src<len-1) // filter out internal \0 characters, as it will confuse the parser
+ {
+ c = ' '; // turn into a space
+ }
+ buf[dest++] = c; // copy the (modified) character to dest
+ }
+ return dest; // length of the valid part of the buf
+}
+
+static QCString getFilterFromList(const char *name,const QStrList &filterList,bool &found)
+{
+ found=FALSE;
+ // compare the file name to the filter pattern list
+ QStrListIterator sli(filterList);
+ char* filterStr;
+ for (sli.toFirst(); (filterStr = sli.current()); ++sli)
+ {
+ QCString fs = filterStr;
+ int i_equals=fs.find('=');
+ if (i_equals!=-1)
+ {
+ QCString filterPattern = fs.left(i_equals);
+ QRegExp fpat(filterPattern,portable_fileSystemIsCaseSensitive(),TRUE);
+ if (fpat.match(name)!=-1)
+ {
+ // found a match!
+ QCString filterName = fs.mid(i_equals+1);
+ if (filterName.find(' ')!=-1)
+ { // add quotes if the name has spaces
+ filterName="\""+filterName+"\"";
+ }
+ found=TRUE;
+ return filterName;
+ }
+ }
+ }
+
+ // no match
+ return "";
+}
+
+/*! looks for a filter for the file \a name. Returns the name of the filter
+ * if there is a match for the file name, otherwise an empty string.
+ * In case \a inSourceCode is TRUE then first the source filter list is
+ * considered.
+ */
+QCString getFileFilter(const char* name,bool isSourceCode)
+{
+ // sanity check
+ if (name==0) return "";
+
+ QStrList& filterSrcList = Config_getList("FILTER_SOURCE_PATTERNS");
+ QStrList& filterList = Config_getList("FILTER_PATTERNS");
+
+ QCString filterName;
+ bool found=FALSE;
+ if (isSourceCode && !filterSrcList.isEmpty())
+ { // first look for source filter pattern list
+ filterName = getFilterFromList(name,filterSrcList,found);
+ }
+ if (!found && filterName.isEmpty())
+ { // then look for filter pattern list
+ filterName = getFilterFromList(name,filterList,found);
+ }
+ if (!found)
+ { // then use the generic input filter
+ return Config_getString("INPUT_FILTER");
+ }
+ else
+ {
+ return filterName;
+ }
+}
+
+
+QCString transcodeCharacterStringToUTF8(const QCString &input)
+{
+ bool error=FALSE;
+ static QCString inputEncoding = Config_getString("INPUT_ENCODING");
+ const char *outputEncoding = "UTF-8";
+ if (inputEncoding.isEmpty() || qstricmp(inputEncoding,outputEncoding)==0) return input;
+ int inputSize=input.length();
+ int outputSize=inputSize*4+1;
+ QCString output(outputSize);
+ void *cd = portable_iconv_open(outputEncoding,inputEncoding);
+ if (cd==(void *)(-1))
+ {
+ err("unsupported character conversion: '%s'->'%s'\n",
+ inputEncoding.data(),outputEncoding);
+ error=TRUE;
+ }
+ if (!error)
+ {
+ size_t iLeft=inputSize;
+ size_t oLeft=outputSize;
+ char *inputPtr = input.data();
+ char *outputPtr = output.data();
+ if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
+ {
+ outputSize-=(int)oLeft;
+ output.resize(outputSize+1);
+ output.at(outputSize)='\0';
+ //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,srcBuf.data());
+ }
+ else
+ {
+ err("failed to translate characters from %s to %s: check INPUT_ENCODING\ninput=[%s]\n",
+ inputEncoding.data(),outputEncoding,input.data());
+ error=TRUE;
+ }
+ }
+ portable_iconv_close(cd);
+ return error ? input : output;
+}
+
+/*! reads a file with name \a name and returns it as a string. If \a filter
+ * is TRUE the file will be filtered by any user specified input filter.
+ * If \a name is "-" the string will be read from standard input.
+ */
+QCString fileToString(const char *name,bool filter,bool isSourceCode)
+{
+ if (name==0 || name[0]==0) return 0;
+ QFile f;
+
+ bool fileOpened=FALSE;
+ if (name[0]=='-' && name[1]==0) // read from stdin
+ {
+ fileOpened=f.open(IO_ReadOnly,stdin);
+ if (fileOpened)
+ {
+ const int bSize=4096;
+ QCString contents(bSize);
+ int totalSize=0;
+ int size;
+ while ((size=f.readBlock(contents.data()+totalSize,bSize))==bSize)
+ {
+ totalSize+=bSize;
+ contents.resize(totalSize+bSize);
+ }
+ totalSize = filterCRLF(contents.data(),totalSize+size)+2;
+ contents.resize(totalSize);
+ contents.at(totalSize-2)='\n'; // to help the scanner
+ contents.at(totalSize-1)='\0';
+ return contents;
+ }
+ }
+ else // read from file
+ {
+ QFileInfo fi(name);
+ if (!fi.exists() || !fi.isFile())
+ {
+ err("file `%s' not found\n",name);
+ return "";
+ }
+ BufStr buf(fi.size());
+ fileOpened=readInputFile(name,buf,filter,isSourceCode);
+ if (fileOpened)
+ {
+ int s = buf.size();
+ if (s>1 && buf.at(s-2)!='\n')
+ {
+ buf.at(s-1)='\n';
+ buf.addChar(0);
+ }
+ return buf.data();
+ }
+ }
+ if (!fileOpened)
+ {
+ err("cannot open file `%s' for reading\n",name);
+ }
+ return "";
+}
+
+QCString dateToString(bool includeTime)
+{
+ QDateTime current = QDateTime::currentDateTime();
+ return theTranslator->trDateTime(current.date().year(),
+ current.date().month(),
+ current.date().day(),
+ current.date().dayOfWeek(),
+ current.time().hour(),
+ current.time().minute(),
+ current.time().second(),
+ includeTime);
+}
+
+QCString yearToString()
+{
+ const QDate &d=QDate::currentDate();
+ QCString result;
+ result.sprintf("%d", d.year());
+ return result;
+}
+
+//----------------------------------------------------------------------
+// recursive function that returns the number of branches in the
+// inheritance tree that the base class `bcd' is below the class `cd'
+
+int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level)
+{
+ if (bcd->categoryOf()) // use class that is being extended in case of
+ // an Objective-C category
+ {
+ bcd=bcd->categoryOf();
+ }
+ if (cd==bcd) return level;
+ if (level==256)
+ {
+ warn_uncond("class %s seem to have a recursive "
+ "inheritance relation!\n",cd->name().data());
+ return -1;
+ }
+ int m=maxInheritanceDepth;
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcdi;
+ for (;(bcdi=bcli.current());++bcli)
+ {
+ int mc=minClassDistance(bcdi->classDef,bcd,level+1);
+ if (mc<m) m=mc;
+ if (m<0) break;
+ }
+ }
+ return m;
+}
+
+Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection prot,int level)
+{
+ if (bcd->categoryOf()) // use class that is being extended in case of
+ // an Objective-C category
+ {
+ bcd=bcd->categoryOf();
+ }
+ if (cd==bcd)
+ {
+ goto exit;
+ }
+ if (level==256)
+ {
+ err("Internal inconsistency: found class %s seem to have a recursive "
+ "inheritance relation! Please send a bug report to dimitri at stack.nl\n",cd->name().data());
+ }
+ else if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcdi;
+ for (;(bcdi=bcli.current()) && prot!=Private;++bcli)
+ {
+ Protection baseProt = classInheritedProtectionLevel(bcdi->classDef,bcd,bcdi->prot,level+1);
+ if (baseProt==Private) prot=Private;
+ else if (baseProt==Protected) prot=Protected;
+ }
+ }
+exit:
+ //printf("classInheritedProtectionLevel(%s,%s)=%d\n",cd->name().data(),bcd->name().data(),prot);
+ return prot;
+}
+
+//static void printArgList(ArgumentList *al)
+//{
+// if (al==0) return;
+// ArgumentListIterator ali(*al);
+// Argument *a;
+// printf("(");
+// for (;(a=ali.current());++ali)
+// {
+// printf("t=`%s' n=`%s' v=`%s' ",a->type.data(),!a->name.isEmpty()>0?a->name.data():"",!a->defval.isEmpty()>0?a->defval.data():"");
+// }
+// printf(")");
+//}
+
+#ifndef NEWMATCH
+// strip any template specifiers that follow className in string s
+static QCString trimTemplateSpecifiers(
+ const QCString &namespaceName,
+ const QCString &className,
+ const QCString &s
+ )
+{
+ //printf("trimTemplateSpecifiers(%s,%s,%s)\n",namespaceName.data(),className.data(),s.data());
+ QCString scopeName=mergeScopes(namespaceName,className);
+ ClassDef *cd=getClass(scopeName);
+ if (cd==0) return s; // should not happen, but guard anyway.
+
+ QCString result=s;
+
+ int i=className.length()-1;
+ if (i>=0 && className.at(i)=='>') // template specialization
+ {
+ // replace unspecialized occurrences in s, with their specialized versions.
+ int count=1;
+ int cl=i+1;
+ while (i>=0)
+ {
+ char c=className.at(i);
+ if (c=='>') count++,i--;
+ else if (c=='<') { count--; if (count==0) break; }
+ else i--;
+ }
+ QCString unspecClassName=className.left(i);
+ int l=i;
+ int p=0;
+ while ((i=result.find(unspecClassName,p))!=-1)
+ {
+ if (result.at(i+l)!='<') // unspecialized version
+ {
+ result=result.left(i)+className+result.right(result.length()-i-l);
+ l=cl;
+ }
+ p=i+l;
+ }
+ }
+
+ //printf("result after specialization: %s\n",result.data());
+
+ QCString qualName=cd->qualifiedNameWithTemplateParameters();
+ //printf("QualifiedName = %s\n",qualName.data());
+ // We strip the template arguments following className (if any)
+ if (!qualName.isEmpty()) // there is a class name
+ {
+ int is,ps=0;
+ int p=0,l,i;
+
+ while ((is=getScopeFragment(qualName,ps,&l))!=-1)
+ {
+ QCString qualNamePart = qualName.right(qualName.length()-is);
+ //printf("qualNamePart=%s\n",qualNamePart.data());
+ while ((i=result.find(qualNamePart,p))!=-1)
+ {
+ int ql=qualNamePart.length();
+ result=result.left(i)+cd->name()+result.right(result.length()-i-ql);
+ p=i+cd->name().length();
+ }
+ ps=is+l;
+ }
+ }
+ //printf("result=%s\n",result.data());
+
+ return result.stripWhiteSpace();
+}
+
+/*!
+ * @param pattern pattern to look for
+ * @param s string to search in
+ * @param p position to start
+ * @param len resulting pattern length
+ * @returns position on which string is found, or -1 if not found
+ */
+static int findScopePattern(const QCString &pattern,const QCString &s,
+ int p,int *len)
+{
+ int sl=s.length();
+ int pl=pattern.length();
+ int sp=0;
+ *len=0;
+ while (p<sl)
+ {
+ sp=p; // start of match
+ int pp=0; // pattern position
+ while (p<sl && pp<pl)
+ {
+ if (s.at(p)=='<') // skip template arguments while matching
+ {
+ int bc=1;
+ //printf("skipping pos=%d c=%c\n",p,s.at(p));
+ p++;
+ while (p<sl)
+ {
+ if (s.at(p)=='<') bc++;
+ else if (s.at(p)=='>')
+ {
+ bc--;
+ if (bc==0)
+ {
+ p++;
+ break;
+ }
+ }
+ //printf("skipping pos=%d c=%c\n",p,s.at(p));
+ p++;
+ }
+ }
+ else if (s.at(p)==pattern.at(pp))
+ {
+ //printf("match at position p=%d pp=%d c=%c\n",p,pp,s.at(p));
+ p++;
+ pp++;
+ }
+ else // no match
+ {
+ //printf("restarting at %d c=%c pat=%s\n",p,s.at(p),pattern.data());
+ p=sp+1;
+ break;
+ }
+ }
+ if (pp==pl) // whole pattern matches
+ {
+ *len=p-sp;
+ return sp;
+ }
+ }
+ return -1;
+}
+
+static QCString trimScope(const QCString &name,const QCString &s)
+{
+ int scopeOffset=name.length();
+ QCString result=s;
+ do // for each scope
+ {
+ QCString tmp;
+ QCString scope=name.left(scopeOffset)+"::";
+ //printf("Trying with scope=`%s'\n",scope.data());
+
+ int i,p=0,l;
+ while ((i=findScopePattern(scope,result,p,&l))!=-1) // for each occurrence
+ {
+ tmp+=result.mid(p,i-p); // add part before pattern
+ p=i+l;
+ }
+ tmp+=result.right(result.length()-p); // add trailing part
+
+ scopeOffset=name.findRev("::",scopeOffset-1);
+ result = tmp;
+ } while (scopeOffset>0);
+ //printf("trimScope(name=%s,scope=%s)=%s\n",name.data(),s.data(),result.data());
+ return result;
+}
+#endif
+
+void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0)
+{
+ //printf("trimBaseClassScope level=%d `%s'\n",level,s.data());
+ BaseClassListIterator bcli(*bcl);
+ BaseClassDef *bcd;
+ for (;(bcd=bcli.current());++bcli)
+ {
+ ClassDef *cd=bcd->classDef;
+ //printf("Trying class %s\n",cd->name().data());
+ int spos=s.find(cd->name()+"::");
+ if (spos!=-1)
+ {
+ s = s.left(spos)+s.right(
+ s.length()-spos-cd->name().length()-2
+ );
+ }
+ //printf("base class `%s'\n",cd->name().data());
+ if (cd->baseClasses())
+ trimBaseClassScope(cd->baseClasses(),s,level+1);
+ }
+}
+
+#if 0
+/*! if either t1 or t2 contains a namespace scope, then remove that
+ * scope. If neither or both have a namespace scope, t1 and t2 remain
+ * unchanged.
+ */
+static void trimNamespaceScope(QCString &t1,QCString &t2,const QCString &nsName)
+{
+ int p1=t1.length();
+ int p2=t2.length();
+ for (;;)
+ {
+ int i1=p1==0 ? -1 : t1.findRev("::",p1);
+ int i2=p2==0 ? -1 : t2.findRev("::",p2);
+ if (i1==-1 && i2==-1)
+ {
+ return;
+ }
+ if (i1!=-1 && i2==-1) // only t1 has a scope
+ {
+ QCString scope=t1.left(i1);
+ replaceNamespaceAliases(scope,i1);
+
+ int so=nsName.length();
+ do
+ {
+ QCString fullScope=nsName.left(so);
+ if (!fullScope.isEmpty() && !scope.isEmpty()) fullScope+="::";
+ fullScope+=scope;
+ if (!fullScope.isEmpty() && Doxygen::namespaceSDict[fullScope]!=0) // scope is a namespace
+ {
+ t1 = t1.right(t1.length()-i1-2);
+ return;
+ }
+ if (so==0)
+ {
+ so=-1;
+ }
+ else if ((so=nsName.findRev("::",so-1))==-1)
+ {
+ so=0;
+ }
+ }
+ while (so>=0);
+ }
+ else if (i1==-1 && i2!=-1) // only t2 has a scope
+ {
+ QCString scope=t2.left(i2);
+ replaceNamespaceAliases(scope,i2);
+
+ int so=nsName.length();
+ do
+ {
+ QCString fullScope=nsName.left(so);
+ if (!fullScope.isEmpty() && !scope.isEmpty()) fullScope+="::";
+ fullScope+=scope;
+ if (!fullScope.isEmpty() && Doxygen::namespaceSDict[fullScope]!=0) // scope is a namespace
+ {
+ t2 = t2.right(t2.length()-i2-2);
+ return;
+ }
+ if (so==0)
+ {
+ so=-1;
+ }
+ else if ((so=nsName.findRev("::",so-1))==-1)
+ {
+ so=0;
+ }
+ }
+ while (so>=0);
+ }
+ p1 = QMAX(i1-2,0);
+ p2 = QMAX(i2-2,0);
+ }
+}
+#endif
+
+static void stripIrrelevantString(QCString &target,const QCString &str)
+{
+ if (target==str) { target.resize(0); return; }
+ int i,p=0;
+ int l=str.length();
+ bool changed=FALSE;
+ while ((i=target.find(str,p))!=-1)
+ {
+ bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
+ (i+l==(int)target.length() || !isId(target.at(i+l))); // not a character after str
+ if (isMatch)
+ {
+ int i1=target.find('*',i+l);
+ int i2=target.find('&',i+l);
+ if (i1==-1 && i2==-1)
+ {
+ // strip str from target at index i
+ target=target.left(i)+target.right(target.length()-i-l);
+ changed=TRUE;
+ i-=l;
+ }
+ else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
+ {
+ // move str to front
+ target=str+" "+target.left(i)+target.right(target.length()-i-l);
+ changed=TRUE;
+ i++;
+ }
+ }
+ p = i+l;
+ }
+ if (changed) target=target.stripWhiteSpace();
+}
+
+/*! According to the C++ spec and Ivan Vecerina:
+
+ Parameter declarations that differ only in the presence or absence
+ of const and/or volatile are equivalent.
+
+ So the following example, show what is stripped by this routine
+ for const. The same is done for volatile.
+
+ \code
+ const T param -> T param // not relevant
+ const T& param -> const T& param // const needed
+ T* const param -> T* param // not relevant
+ const T* param -> const T* param // const needed
+ \endcode
+ */
+void stripIrrelevantConstVolatile(QCString &s)
+{
+ //printf("stripIrrelevantConstVolatile(%s)=",s.data());
+ stripIrrelevantString(s,"const");
+ stripIrrelevantString(s,"volatile");
+ //printf("%s\n",s.data());
+}
+
+
+// a bit of debug support for matchArguments
+#define MATCH
+#define NOMATCH
+//#define MATCH printf("Match at line %d\n",__LINE__);
+//#define NOMATCH printf("Nomatch at line %d\n",__LINE__);
+
+#ifndef NEWMATCH
+static bool matchArgument(const Argument *srcA,const Argument *dstA,
+ const QCString &className,
+ const QCString &namespaceName,
+ NamespaceSDict *usingNamespaces,
+ SDict<Definition> *usingClasses)
+{
+ //printf("match argument start `%s|%s' <-> `%s|%s' using nsp=%p class=%p\n",
+ // srcA->type.data(),srcA->name.data(),
+ // dstA->type.data(),dstA->name.data(),
+ // usingNamespaces,
+ // usingClasses);
+
+ // TODO: resolve any typedefs names that are part of srcA->type
+ // before matching. This should use className and namespaceName
+ // and usingNamespaces and usingClass to determine which typedefs
+ // are in-scope, so it will not be very efficient :-(
+
+ QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type);
+ QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type);
+ QCString srcAName=srcA->name.stripWhiteSpace();
+ QCString dstAName=dstA->name.stripWhiteSpace();
+ srcAType.stripPrefix("class ");
+ dstAType.stripPrefix("class ");
+
+ // allow distinguishing "const A" from "const B" even though
+ // from a syntactic point of view they would be two names of the same
+ // type "const". This is not fool prove of course, but should at least
+ // catch the most common cases.
+ if ((srcAType=="const" || srcAType=="volatile") && !srcAName.isEmpty())
+ {
+ srcAType+=" ";
+ srcAType+=srcAName;
+ }
+ if ((dstAType=="const" || dstAType=="volatile") && !dstAName.isEmpty())
+ {
+ dstAType+=" ";
+ dstAType+=dstAName;
+ }
+ if (srcAName=="const" || srcAName=="volatile")
+ {
+ srcAType+=srcAName;
+ srcAName.resize(0);
+ }
+ else if (dstA->name=="const" || dstA->name=="volatile")
+ {
+ dstAType+=dstA->name;
+ dstAName.resize(0);
+ }
+
+ stripIrrelevantConstVolatile(srcAType);
+ stripIrrelevantConstVolatile(dstAType);
+
+ // strip typename keyword
+ if (qstrncmp(srcAType,"typename ",9)==0)
+ {
+ srcAType = srcAType.right(srcAType.length()-9);
+ }
+ if (qstrncmp(dstAType,"typename ",9)==0)
+ {
+ dstAType = dstAType.right(dstAType.length()-9);
+ }
+
+ srcAType = removeRedundantWhiteSpace(srcAType);
+ dstAType = removeRedundantWhiteSpace(dstAType);
+
+ //srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE);
+ //dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE);
+
+ //printf("srcA=`%s|%s' dstA=`%s|%s'\n",srcAType.data(),srcAName.data(),
+ // dstAType.data(),dstAName.data());
+
+ if (srcA->array!=dstA->array) // nomatch for char[] against char
+ {
+ NOMATCH
+ return FALSE;
+ }
+ if (srcAType!=dstAType) // check if the argument only differs on name
+ {
+
+ // remove a namespace scope that is only in one type
+ // (assuming a using statement was used)
+ //printf("Trimming %s<->%s: %s\n",srcAType.data(),dstAType.data(),namespaceName.data());
+ //trimNamespaceScope(srcAType,dstAType,namespaceName);
+ //printf("After Trimming %s<->%s\n",srcAType.data(),dstAType.data());
+
+ //QCString srcScope;
+ //QCString dstScope;
+
+ // strip redundant scope specifiers
+ if (!className.isEmpty())
+ {
+ srcAType=trimScope(className,srcAType);
+ dstAType=trimScope(className,dstAType);
+ //printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ ClassDef *cd;
+ if (!namespaceName.isEmpty())
+ cd=getClass(namespaceName+"::"+className);
+ else
+ cd=getClass(className);
+ if (cd && cd->baseClasses())
+ {
+ trimBaseClassScope(cd->baseClasses(),srcAType);
+ trimBaseClassScope(cd->baseClasses(),dstAType);
+ }
+ //printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ }
+ if (!namespaceName.isEmpty())
+ {
+ srcAType=trimScope(namespaceName,srcAType);
+ dstAType=trimScope(namespaceName,dstAType);
+ }
+ //printf("#usingNamespace=%d\n",usingNamespaces->count());
+ if (usingNamespaces && usingNamespaces->count()>0)
+ {
+ NamespaceSDict::Iterator nli(*usingNamespaces);
+ NamespaceDef *nd;
+ for (;(nd=nli.current());++nli)
+ {
+ srcAType=trimScope(nd->name(),srcAType);
+ dstAType=trimScope(nd->name(),dstAType);
+ }
+ }
+ //printf("#usingClasses=%d\n",usingClasses->count());
+ if (usingClasses && usingClasses->count()>0)
+ {
+ SDict<Definition>::Iterator cli(*usingClasses);
+ Definition *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ srcAType=trimScope(cd->name(),srcAType);
+ dstAType=trimScope(cd->name(),dstAType);
+ }
+ }
+
+ //printf("2. srcA=%s|%s dstA=%s|%s\n",srcAType.data(),srcAName.data(),
+ // dstAType.data(),dstAName.data());
+
+ if (!srcAName.isEmpty() && !dstA->type.isEmpty() &&
+ (srcAType+" "+srcAName)==dstAType)
+ {
+ MATCH
+ return TRUE;
+ }
+ else if (!dstAName.isEmpty() && !srcA->type.isEmpty() &&
+ (dstAType+" "+dstAName)==srcAType)
+ {
+ MATCH
+ return TRUE;
+ }
+
+
+ uint srcPos=0,dstPos=0;
+ bool equal=TRUE;
+ while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
+ {
+ equal=srcAType.at(srcPos)==dstAType.at(dstPos);
+ if (equal) srcPos++,dstPos++;
+ }
+ uint srcATypeLen=srcAType.length();
+ uint dstATypeLen=dstAType.length();
+ if (srcPos<srcATypeLen && dstPos<dstATypeLen)
+ {
+ // if nothing matches or the match ends in the middle or at the
+ // end of a string then there is no match
+ if (srcPos==0 || dstPos==0)
+ {
+ NOMATCH
+ return FALSE;
+ }
+ if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos)))
+ {
+ //printf("partial match srcPos=%d dstPos=%d!\n",srcPos,dstPos);
+ // check if a name if already found -> if no then there is no match
+ if (!srcAName.isEmpty() || !dstAName.isEmpty())
+ {
+ NOMATCH
+ return FALSE;
+ }
+ // types only
+ while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++;
+ while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++;
+ if (srcPos<srcATypeLen ||
+ dstPos<dstATypeLen ||
+ (srcPos==srcATypeLen && dstPos==dstATypeLen)
+ )
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ else
+ {
+ // otherwise we assume that a name starts at the current position.
+ while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++;
+ while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++;
+
+ // if nothing more follows for both types then we assume we have
+ // found a match. Note that now `signed int' and `signed' match, but
+ // seeing that int is not a name can only be done by looking at the
+ // semantics.
+
+ if (srcPos!=srcATypeLen || dstPos!=dstATypeLen)
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ }
+ else if (dstPos<dstAType.length())
+ {
+ if (!isspace((uchar)dstAType.at(dstPos))) // maybe the names differ
+ {
+ if (!dstAName.isEmpty()) // dst has its name separated from its type
+ {
+ NOMATCH
+ return FALSE;
+ }
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ if (dstPos!=dstAType.length())
+ {
+ NOMATCH
+ return FALSE; // more than a difference in name -> no match
+ }
+ }
+ else // maybe dst has a name while src has not
+ {
+ dstPos++;
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ if (dstPos!=dstAType.length() || !srcAName.isEmpty())
+ {
+ NOMATCH
+ return FALSE; // nope not a name -> no match
+ }
+ }
+ }
+ else if (srcPos<srcAType.length())
+ {
+ if (!isspace((uchar)srcAType.at(srcPos))) // maybe the names differ
+ {
+ if (!srcAName.isEmpty()) // src has its name separated from its type
+ {
+ NOMATCH
+ return FALSE;
+ }
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ if (srcPos!=srcAType.length())
+ {
+ NOMATCH
+ return FALSE; // more than a difference in name -> no match
+ }
+ }
+ else // maybe src has a name while dst has not
+ {
+ srcPos++;
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ if (srcPos!=srcAType.length() || !dstAName.isEmpty())
+ {
+ NOMATCH
+ return FALSE; // nope not a name -> no match
+ }
+ }
+ }
+ }
+ MATCH
+ return TRUE;
+}
+
+
+/*!
+ * Matches the arguments list srcAl with the argument list dstAl
+ * Returns TRUE if the argument lists are equal. Two argument list are
+ * considered equal if the number of arguments is equal and the types of all
+ * arguments are equal. Furthermore the const and volatile specifiers
+ * stored in the list should be equal.
+ */
+bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
+ const char *cl,const char *ns,bool checkCV,
+ NamespaceSDict *usingNamespaces,
+ SDict<Definition> *usingClasses)
+{
+ QCString className=cl;
+ QCString namespaceName=ns;
+
+ // strip template specialization from class name if present
+ //int til=className.find('<'),tir=className.find('>');
+ //if (til!=-1 && tir!=-1 && tir>til)
+ //{
+ // className=className.left(til)+className.right(className.length()-tir-1);
+ //}
+
+ //printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d usingNamespaces=%d usingClasses=%d\n",
+ // srcAl ? argListToString(srcAl).data() : "",
+ // dstAl ? argListToString(dstAl).data() : "",
+ // cl,ns,checkCV,
+ // usingNamespaces?usingNamespaces->count():0,
+ // usingClasses?usingClasses->count():0
+ // );
+
+ if (srcAl==0 || dstAl==0)
+ {
+ bool match = srcAl==dstAl; // at least one of the members is not a function
+ if (match)
+ {
+ MATCH
+ return TRUE;
+ }
+ else
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+
+ // handle special case with void argument
+ if ( srcAl->count()==0 && dstAl->count()==1 &&
+ dstAl->getFirst()->type=="void" )
+ { // special case for finding match between func() and func(void)
+ Argument *a=new Argument;
+ a->type = "void";
+ srcAl->append(a);
+ MATCH
+ return TRUE;
+ }
+ if ( dstAl->count()==0 && srcAl->count()==1 &&
+ srcAl->getFirst()->type=="void" )
+ { // special case for finding match between func(void) and func()
+ Argument *a=new Argument;
+ a->type = "void";
+ dstAl->append(a);
+ MATCH
+ return TRUE;
+ }
+
+ if (srcAl->count() != dstAl->count())
+ {
+ NOMATCH
+ return FALSE; // different number of arguments -> no match
+ }
+
+ if (checkCV)
+ {
+ if (srcAl->constSpecifier != dstAl->constSpecifier)
+ {
+ NOMATCH
+ return FALSE; // one member is const, the other not -> no match
+ }
+ if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
+ {
+ NOMATCH
+ return FALSE; // one member is volatile, the other not -> no match
+ }
+ }
+
+ // so far the argument list could match, so we need to compare the types of
+ // all arguments.
+ ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
+ Argument *srcA,*dstA;
+ for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli)
+ {
+ if (!matchArgument(srcA,dstA,className,namespaceName,
+ usingNamespaces,usingClasses))
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ MATCH
+ return TRUE; // all arguments match
+}
+
+#endif
+
+#if 0
+static QCString resolveSymbolName(FileDef *fs,Definition *symbol,QCString &templSpec)
+{
+ ASSERT(symbol!=0);
+ if (symbol->definitionType()==Definition::TypeMember &&
+ ((MemberDef*)symbol)->isTypedef()) // if symbol is a typedef then try
+ // to resolve it
+ {
+ MemberDef *md = 0;
+ ClassDef *cd = newResolveTypedef(fs,(MemberDef*)symbol,&md,&templSpec);
+ if (cd)
+ {
+ return cd->qualifiedName()+templSpec;
+ }
+ else if (md)
+ {
+ return md->qualifiedName();
+ }
+ }
+ return symbol->qualifiedName();
+}
+#endif
+
+static QCString stripDeclKeywords(const QCString &s)
+{
+ int i=s.find(" class ");
+ if (i!=-1) return s.left(i)+s.mid(i+6);
+ i=s.find(" typename ");
+ if (i!=-1) return s.left(i)+s.mid(i+9);
+ i=s.find(" union ");
+ if (i!=-1) return s.left(i)+s.mid(i+6);
+ i=s.find(" struct ");
+ if (i!=-1) return s.left(i)+s.mid(i+7);
+ return s;
+}
+
+// forward decl for circular dependencies
+static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type);
+
+QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec)
+{
+
+ QCString templSpec = spec.stripWhiteSpace();
+ // this part had been commented out before... but it is needed to match for instance
+ // std::list<std::string> against list<string> so it is now back again!
+ if (!templSpec.isEmpty() && templSpec.at(0) == '<')
+ {
+ templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace());
+ }
+ QCString resolvedType = resolveTypeDef(d,templSpec);
+ if (!resolvedType.isEmpty()) // not known as a typedef either
+ {
+ templSpec = resolvedType;
+ }
+ //printf("getCanonicalTemplateSpec(%s)=%s\n",spec.data(),templSpec.data());
+ return templSpec;
+}
+
+
+static QCString getCanonicalTypeForIdentifier(
+ Definition *d,FileDef *fs,const QCString &word,
+ QCString *tSpec,int count=0)
+{
+ if (count>10) return word; // oops recursion
+
+ QCString symName,scope,result,templSpec,tmpName;
+ //DefinitionList *defList=0;
+ if (tSpec && !tSpec->isEmpty())
+ templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec));
+
+ if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty())
+ {
+ symName=tmpName; // name without scope
+ }
+ else
+ {
+ symName=word;
+ }
+ //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n",
+ // word.data(),tSpec?tSpec->data():"<none>",templSpec.data());
+
+ ClassDef *cd = 0;
+ MemberDef *mType = 0;
+ QCString ts;
+ QCString resolvedType;
+
+ // lookup class / class template instance
+ cd = getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE,TRUE,&resolvedType);
+ bool isTemplInst = cd && !templSpec.isEmpty();
+ if (!cd && !templSpec.isEmpty())
+ {
+ // class template specialization not known, look up class template
+ cd = getResolvedClass(d,fs,word,&mType,&ts,TRUE,TRUE,&resolvedType);
+ }
+ if (cd && cd->isUsedOnly()) cd=0; // ignore types introduced by usage relations
+
+ //printf("cd=%p mtype=%p\n",cd,mType);
+ //printf(" getCanonicalTypeForIdentifer: symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n",
+ // symName.data(),
+ // word.data(),
+ // cd?cd->name().data():"<none>",
+ // d?d->name().data():"<none>",
+ // fs?fs->name().data():"<none>",
+ // cd?cd->isTemplate():-1
+ // );
+
+ //printf(" >>>> word '%s' => '%s' templSpec=%s ts=%s tSpec=%s isTemplate=%d resolvedType=%s\n",
+ // (word+templSpec).data(),
+ // cd?cd->qualifiedName().data():"<none>",
+ // templSpec.data(),ts.data(),
+ // tSpec?tSpec->data():"<null>",
+ // cd?cd->isTemplate():FALSE,
+ // resolvedType.data());
+
+ //printf(" mtype=%s\n",mType?mType->name().data():"<none>");
+
+ if (cd) // resolves to a known class type
+ {
+ if (cd==d && tSpec) *tSpec="";
+
+ if (mType && mType->isTypedef()) // but via a typedef
+ {
+ result = resolvedType+ts; // the +ts was added for bug 685125
+ }
+ else
+ {
+ if (isTemplInst)
+ {
+ // spec is already part of class type
+ templSpec="";
+ if (tSpec) *tSpec="";
+ }
+ else if (!ts.isEmpty() && templSpec.isEmpty())
+ {
+ // use formal template args for spec
+ templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,ts));
+ }
+
+ result = removeRedundantWhiteSpace(cd->qualifiedName() + templSpec);
+
+ if (cd->isTemplate() && tSpec) //
+ {
+ if (!templSpec.isEmpty()) // specific instance
+ {
+ result=cd->name()+templSpec;
+ }
+ else // use template type
+ {
+ result=cd->qualifiedNameWithTemplateParameters();
+ }
+ // template class, so remove the template part (it is part of the class name)
+ *tSpec="";
+ }
+ else if (ts.isEmpty() && !templSpec.isEmpty() && cd && !cd->isTemplate() && tSpec)
+ {
+ // obscure case, where a class is used as a template, but doxygen think it is
+ // not (could happen when loading the class from a tag file).
+ *tSpec="";
+ }
+ }
+ }
+ else if (mType && mType->isEnumerate()) // an enum
+ {
+ result = mType->qualifiedName();
+ }
+ else if (mType && mType->isTypedef()) // a typedef
+ {
+ //result = mType->qualifiedName(); // changed after 1.7.2
+ //result = mType->typeString();
+ //printf("word=%s typeString=%s\n",word.data(),mType->typeString());
+ if (word!=mType->typeString())
+ {
+ result = getCanonicalTypeForIdentifier(d,fs,mType->typeString(),tSpec,count+1);
+ }
+ else
+ {
+ result = mType->typeString();
+ }
+ }
+ else // fallback
+ {
+ resolvedType = resolveTypeDef(d,word);
+ //printf("typedef [%s]->[%s]\n",word.data(),resolvedType.data());
+ if (resolvedType.isEmpty()) // not known as a typedef either
+ {
+ result = word;
+ }
+ else
+ {
+ result = resolvedType;
+ }
+ }
+ //printf("getCanonicalTypeForIdentifier [%s]->[%s]\n",word.data(),result.data());
+ return result;
+}
+
+static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type)
+{
+ type = type.stripWhiteSpace();
+
+ // strip const and volatile keywords that are not relevant for the type
+ stripIrrelevantConstVolatile(type);
+
+ // strip leading keywords
+ type.stripPrefix("class ");
+ type.stripPrefix("struct ");
+ type.stripPrefix("union ");
+ type.stripPrefix("enum ");
+ type.stripPrefix("typename ");
+
+ type = removeRedundantWhiteSpace(type);
+ //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(),
+ // d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>");
+
+ //static QRegExp id("[a-z_A-Z\\x80-\\xFF][:a-z_A-Z0-9\\x80-\\xFF]*");
+
+ QCString canType;
+ QCString templSpec,word;
+ int i,p=0,pp=0;
+ while ((i=extractClassNameFromType(type,p,word,templSpec))!=-1)
+ // foreach identifier in the type
+ {
+ //printf(" i=%d p=%d\n",i,p);
+ if (i>pp) canType += type.mid(pp,i-pp);
+
+
+ QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec);
+
+ // in case the ct is empty it means that "word" represents scope "d"
+ // and this does not need to be added to the canonical
+ // type (it is redundant), so/ we skip it. This solves problem 589616.
+ if (ct.isEmpty() && type.mid(p,2)=="::")
+ {
+ p+=2;
+ }
+ else
+ {
+ canType += ct;
+ }
+ //printf(" word=%s templSpec=%s canType=%s ct=%s\n",
+ // word.data(),templSpec.data(),canType.data(),ct.data());
+ if (!templSpec.isEmpty()) // if we didn't use up the templSpec already
+ // (i.e. type is not a template specialization)
+ // then resolve any identifiers inside.
+ {
+ static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
+ int tp=0,tl,ti;
+ // for each identifier template specifier
+ //printf("adding resolved %s to %s\n",templSpec.data(),canType.data());
+ while ((ti=re.match(templSpec,tp,&tl))!=-1)
+ {
+ canType += templSpec.mid(tp,ti-tp);
+ canType += getCanonicalTypeForIdentifier(d,fs,templSpec.mid(ti,tl),0);
+ tp=ti+tl;
+ }
+ canType+=templSpec.right(templSpec.length()-tp);
+ }
+
+ pp=p;
+ }
+ canType += type.right(type.length()-pp);
+ //printf("extractCanonicalType = '%s'->'%s'\n",type.data(),canType.data());
+
+ return removeRedundantWhiteSpace(canType);
+}
+
+static QCString extractCanonicalArgType(Definition *d,FileDef *fs,const Argument *arg)
+{
+ QCString type = arg->type.stripWhiteSpace();
+ QCString name = arg->name;
+ //printf("----- extractCanonicalArgType(type=%s,name=%s)\n",type.data(),name.data());
+ if ((type=="const" || type=="volatile") && !name.isEmpty())
+ { // name is part of type => correct
+ type+=" ";
+ type+=name;
+ }
+ if (name=="const" || name=="volatile")
+ { // name is part of type => correct
+ if (!type.isEmpty()) type+=" ";
+ type+=name;
+ }
+ if (!arg->array.isEmpty())
+ {
+ type+=arg->array;
+ }
+
+ return extractCanonicalType(d,fs,type);
+}
+
+static bool matchArgument2(
+ Definition *srcScope,FileDef *srcFileScope,Argument *srcA,
+ Definition *dstScope,FileDef *dstFileScope,Argument *dstA
+ )
+{
+ //printf(">> match argument: %s::`%s|%s' (%s) <-> %s::`%s|%s' (%s)\n",
+ // srcScope ? srcScope->name().data() : "",
+ // srcA->type.data(),srcA->name.data(),srcA->canType.data(),
+ // dstScope ? dstScope->name().data() : "",
+ // dstA->type.data(),dstA->name.data(),dstA->canType.data());
+
+ //if (srcA->array!=dstA->array) // nomatch for char[] against char
+ //{
+ // NOMATCH
+ // return FALSE;
+ //}
+ QCString sSrcName = " "+srcA->name;
+ QCString sDstName = " "+dstA->name;
+ QCString srcType = srcA->type;
+ QCString dstType = dstA->type;
+ stripIrrelevantConstVolatile(srcType);
+ stripIrrelevantConstVolatile(dstType);
+ //printf("'%s'<->'%s'\n",sSrcName.data(),dstType.right(sSrcName.length()).data());
+ //printf("'%s'<->'%s'\n",sDstName.data(),srcType.right(sDstName.length()).data());
+ if (sSrcName==dstType.right(sSrcName.length()))
+ { // case "unsigned int" <-> "unsigned int i"
+ srcA->type+=sSrcName;
+ srcA->name="";
+ srcA->canType=""; // invalidate cached type value
+ }
+ else if (sDstName==srcType.right(sDstName.length()))
+ { // case "unsigned int i" <-> "unsigned int"
+ dstA->type+=sDstName;
+ dstA->name="";
+ dstA->canType=""; // invalidate cached type value
+ }
+
+ if (srcA->canType.isEmpty())
+ {
+ srcA->canType = extractCanonicalArgType(srcScope,srcFileScope,srcA);
+ }
+ if (dstA->canType.isEmpty())
+ {
+ dstA->canType = extractCanonicalArgType(dstScope,dstFileScope,dstA);
+ }
+
+ if (srcA->canType==dstA->canType)
+ {
+ MATCH
+ return TRUE;
+ }
+ else
+ {
+ //printf(" Canonical types do not match [%s]<->[%s]\n",
+ // srcA->canType.data(),dstA->canType.data());
+ NOMATCH
+ return FALSE;
+ }
+}
+
+
+// new algorithm for argument matching
+bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
+ Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
+ bool checkCV
+ )
+{
+ //printf("*** matchArguments2\n");
+ ASSERT(srcScope!=0 && dstScope!=0);
+
+ if (srcAl==0 || dstAl==0)
+ {
+ bool match = srcAl==dstAl; // at least one of the members is not a function
+ if (match)
+ {
+ MATCH
+ return TRUE;
+ }
+ else
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+
+ // handle special case with void argument
+ if ( srcAl->count()==0 && dstAl->count()==1 &&
+ dstAl->getFirst()->type=="void" )
+ { // special case for finding match between func() and func(void)
+ Argument *a=new Argument;
+ a->type = "void";
+ srcAl->append(a);
+ MATCH
+ return TRUE;
+ }
+ if ( dstAl->count()==0 && srcAl->count()==1 &&
+ srcAl->getFirst()->type=="void" )
+ { // special case for finding match between func(void) and func()
+ Argument *a=new Argument;
+ a->type = "void";
+ dstAl->append(a);
+ MATCH
+ return TRUE;
+ }
+
+ if (srcAl->count() != dstAl->count())
+ {
+ NOMATCH
+ return FALSE; // different number of arguments -> no match
+ }
+
+ if (checkCV)
+ {
+ if (srcAl->constSpecifier != dstAl->constSpecifier)
+ {
+ NOMATCH
+ return FALSE; // one member is const, the other not -> no match
+ }
+ if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
+ {
+ NOMATCH
+ return FALSE; // one member is volatile, the other not -> no match
+ }
+ }
+
+ // so far the argument list could match, so we need to compare the types of
+ // all arguments.
+ ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
+ Argument *srcA,*dstA;
+ for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli)
+ {
+ if (!matchArgument2(srcScope,srcFileScope,srcA,
+ dstScope,dstFileScope,dstA)
+ )
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ MATCH
+ return TRUE; // all arguments match
+}
+
+
+
+// merges the initializer of two argument lists
+// pre: the types of the arguments in the list should match.
+void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwrite)
+{
+ //printf("mergeArguments `%s', `%s'\n",
+ // argListToString(srcAl).data(),argListToString(dstAl).data());
+
+ if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count())
+ {
+ return; // invalid argument lists -> do not merge
+ }
+
+ ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
+ Argument *srcA,*dstA;
+ for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli)
+ {
+ if (srcA->defval.isEmpty() && !dstA->defval.isEmpty())
+ {
+ //printf("Defval changing `%s'->`%s'\n",srcA->defval.data(),dstA->defval.data());
+ srcA->defval=dstA->defval.copy();
+ }
+ else if (!srcA->defval.isEmpty() && dstA->defval.isEmpty())
+ {
+ //printf("Defval changing `%s'->`%s'\n",dstA->defval.data(),srcA->defval.data());
+ dstA->defval=srcA->defval.copy();
+ }
+
+ // fix wrongly detected const or volatile specifiers before merging.
+ // example: "const A *const" is detected as type="const A *" name="const"
+ if (srcA->name=="const" || srcA->name=="volatile")
+ {
+ srcA->type+=" "+srcA->name;
+ srcA->name.resize(0);
+ }
+ if (dstA->name=="const" || dstA->name=="volatile")
+ {
+ dstA->type+=" "+dstA->name;
+ dstA->name.resize(0);
+ }
+
+ if (srcA->type==dstA->type)
+ {
+ //printf("1. merging %s:%s <-> %s:%s\n",srcA->type.data(),srcA->name.data(),dstA->type.data(),dstA->name.data());
+ if (srcA->name.isEmpty() && !dstA->name.isEmpty())
+ {
+ //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data());
+ //printf("name: `%s':=`%s'\n",srcA->name.data(),dstA->name.data());
+ srcA->type = dstA->type.copy();
+ srcA->name = dstA->name.copy();
+ }
+ else if (!srcA->name.isEmpty() && dstA->name.isEmpty())
+ {
+ //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data());
+ //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
+ dstA->type = srcA->type.copy();
+ dstA->name = dstA->name.copy();
+ }
+ else if (!srcA->name.isEmpty() && !dstA->name.isEmpty())
+ {
+ //printf("srcA->name=%s dstA->name=%s\n",srcA->name.data(),dstA->name.data());
+ if (forceNameOverwrite)
+ {
+ srcA->name = dstA->name;
+ }
+ else
+ {
+ if (srcA->docs.isEmpty() && !dstA->docs.isEmpty())
+ {
+ srcA->name = dstA->name;
+ }
+ else if (!srcA->docs.isEmpty() && dstA->docs.isEmpty())
+ {
+ dstA->name = srcA->name;
+ }
+ }
+ }
+ }
+ else
+ {
+ //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",srcA->type.data(),srcA->name.data(),dstA->type.data(),dstA->name.data());
+ srcA->type=srcA->type.stripWhiteSpace();
+ dstA->type=dstA->type.stripWhiteSpace();
+ if (srcA->type+" "+srcA->name==dstA->type) // "unsigned long:int" <-> "unsigned long int:bla"
+ {
+ srcA->type+=" "+srcA->name;
+ srcA->name=dstA->name;
+ }
+ else if (dstA->type+" "+dstA->name==srcA->type) // "unsigned long int bla" <-> "unsigned long int"
+ {
+ dstA->type+=" "+dstA->name;
+ dstA->name=srcA->name;
+ }
+ else if (srcA->name.isEmpty() && !dstA->name.isEmpty())
+ {
+ srcA->name = dstA->name;
+ }
+ else if (dstA->name.isEmpty() && !srcA->name.isEmpty())
+ {
+ dstA->name = srcA->name;
+ }
+ }
+ int i1=srcA->type.find("::"),
+ i2=dstA->type.find("::"),
+ j1=srcA->type.length()-i1-2,
+ j2=dstA->type.length()-i2-2;
+ if (i1!=-1 && i2==-1 && srcA->type.right(j1)==dstA->type)
+ {
+ //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data());
+ //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
+ dstA->type = srcA->type.left(i1+2)+dstA->type;
+ dstA->name = dstA->name.copy();
+ }
+ else if (i1==-1 && i2!=-1 && dstA->type.right(j2)==srcA->type)
+ {
+ //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data());
+ //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
+ srcA->type = dstA->type.left(i2+2)+srcA->type;
+ srcA->name = dstA->name.copy();
+ }
+ if (srcA->docs.isEmpty() && !dstA->docs.isEmpty())
+ {
+ srcA->docs = dstA->docs.copy();
+ }
+ else if (dstA->docs.isEmpty() && !srcA->docs.isEmpty())
+ {
+ dstA->docs = srcA->docs.copy();
+ }
+ //printf("Merge argument `%s|%s' `%s|%s'\n",
+ // srcA->type.data(),srcA->name.data(),
+ // dstA->type.data(),dstA->name.data());
+ }
+}
+
+static void findMembersWithSpecificName(MemberName *mn,
+ const char *args,
+ bool checkStatics,
+ FileDef *currentFile,
+ bool checkCV,
+ const char *forceTagFile,
+ QList<MemberDef> &members)
+{
+ //printf(" Function with global scope name `%s' args=`%s'\n",
+ // mn->memberName(),args);
+ MemberListIterator mli(*mn);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ FileDef *fd=md->getFileDef();
+ GroupDef *gd=md->getGroupDef();
+ //printf(" md->name()=`%s' md->args=`%s' fd=%p gd=%p current=%p ref=%s\n",
+ // md->name().data(),args,fd,gd,currentFile,md->getReference().data());
+ if (
+ ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) &&
+ md->getNamespaceDef()==0 && md->isLinkable() &&
+ (!checkStatics || (!md->isStatic() && !md->isDefine()) ||
+ currentFile==0 || fd==currentFile) // statics must appear in the same file
+ )
+ {
+ bool match=TRUE;
+ ArgumentList *argList=0;
+ if (args && !md->isDefine() && qstrcmp(args,"()")!=0)
+ {
+ argList=new ArgumentList;
+ ArgumentList *mdAl = md->argumentList();
+ stringToArgumentList(args,argList);
+ match=matchArguments2(
+ md->getOuterScope(),fd,mdAl,
+ Doxygen::globalScope,fd,argList,
+ checkCV);
+ delete argList; argList=0;
+ }
+ if (match && (forceTagFile==0 || md->getReference()==forceTagFile))
+ {
+ //printf("Found match!\n");
+ members.append(md);
+ }
+ }
+ }
+}
+
+/*!
+ * Searches for a member definition given its name `memberName' as a string.
+ * memberName may also include a (partial) scope to indicate the scope
+ * in which the member is located.
+ *
+ * The parameter `scName' is a string representing the name of the scope in
+ * which the link was found.
+ *
+ * In case of a function args contains a string representation of the
+ * argument list. Passing 0 means the member has no arguments.
+ * Passing "()" means any argument list will do, but "()" is preferred.
+ *
+ * The function returns TRUE if the member is known and documented or
+ * FALSE if it is not.
+ * If TRUE is returned parameter `md' contains a pointer to the member
+ * definition. Furthermore exactly one of the parameter `cd', `nd', or `fd'
+ * will be non-zero:
+ * - if `cd' is non zero, the member was found in a class pointed to by cd.
+ * - if `nd' is non zero, the member was found in a namespace pointed to by nd.
+ * - if `fd' is non zero, the member was found in the global namespace of
+ * file fd.
+ */
+bool getDefs(const QCString &scName,
+ const QCString &mbName,
+ const char *args,
+ MemberDef *&md,
+ ClassDef *&cd,
+ FileDef *&fd,
+ NamespaceDef *&nd,
+ GroupDef *&gd,
+ bool forceEmptyScope,
+ FileDef *currentFile,
+ bool checkCV,
+ const char *forceTagFile
+ )
+{
+ fd=0, md=0, cd=0, nd=0, gd=0;
+ if (mbName.isEmpty()) return FALSE; /* empty name => nothing to link */
+
+ QCString scopeName=scName;
+ QCString memberName=mbName;
+ scopeName = substitute(scopeName,"\\","::"); // for PHP
+ memberName = substitute(memberName,"\\","::"); // for PHP
+ //printf("Search for name=%s args=%s in scope=%s forceEmpty=%d\n",
+ // memberName.data(),args,scopeName.data(),forceEmptyScope);
+
+ int is,im=0,pm=0;
+ // strip common part of the scope from the scopeName
+ while ((is=scopeName.findRev("::"))!=-1 &&
+ (im=memberName.find("::",pm))!=-1 &&
+ (scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm))
+ )
+ {
+ scopeName=scopeName.left(is);
+ pm=im+2;
+ }
+ //printf("result after scope corrections scope=%s name=%s\n",
+ // scopeName.data(),memberName.data());
+
+ QCString mName=memberName;
+ QCString mScope;
+ if (memberName.left(9)!="operator " && // treat operator conversion methods
+ // as a special case
+ (im=memberName.findRev("::"))!=-1 &&
+ im<(int)memberName.length()-2 // not A::
+ )
+ {
+ mScope=memberName.left(im);
+ mName=memberName.right(memberName.length()-im-2);
+ }
+
+ // handle special the case where both scope name and member scope are equal
+ if (mScope==scopeName) scopeName.resize(0);
+
+ //printf("mScope=`%s' mName=`%s'\n",mScope.data(),mName.data());
+
+ MemberName *mn = Doxygen::memberNameSDict->find(mName);
+ //printf("mName=%s mn=%p\n",mName.data(),mn);
+
+ if ((!forceEmptyScope || scopeName.isEmpty()) && // this was changed for bug638856, forceEmptyScope => empty scopeName
+ mn && !(scopeName.isEmpty() && mScope.isEmpty()))
+ {
+ //printf(" >member name '%s' found\n",mName.data());
+ int scopeOffset=scopeName.length();
+ do
+ {
+ QCString className = scopeName.left(scopeOffset);
+ if (!className.isEmpty() && !mScope.isEmpty())
+ {
+ className+="::"+mScope;
+ }
+ else if (!mScope.isEmpty())
+ {
+ className=mScope;
+ }
+
+ MemberDef *tmd=0;
+ ClassDef *fcd=getResolvedClass(Doxygen::globalScope,0,className,&tmd);
+ //printf("Trying class scope %s: fcd=%p tmd=%p\n",className.data(),fcd,tmd);
+ // todo: fill in correct fileScope!
+ if (fcd && // is it a documented class
+ fcd->isLinkable()
+ )
+ {
+ //printf(" Found fcd=%p\n",fcd);
+ MemberListIterator mmli(*mn);
+ MemberDef *mmd;
+ int mdist=maxInheritanceDepth;
+ ArgumentList *argList=0;
+ if (args)
+ {
+ argList=new ArgumentList;
+ stringToArgumentList(args,argList);
+ }
+ for (mmli.toFirst();(mmd=mmli.current());++mmli)
+ {
+ if (!mmd->isStrongEnumValue())
+ {
+ ArgumentList *mmdAl = mmd->argumentList();
+ bool match=args==0 ||
+ matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
+ fcd,fcd->getFileDef(),argList,
+ checkCV
+ );
+ //printf("match=%d\n",match);
+ if (match)
+ {
+ ClassDef *mcd=mmd->getClassDef();
+ if (mcd)
+ {
+ int m=minClassDistance(fcd,mcd);
+ if (m<mdist && mcd->isLinkable())
+ {
+ mdist=m;
+ cd=mcd;
+ md=mmd;
+ }
+ }
+ }
+ }
+ }
+ if (argList)
+ {
+ delete argList; argList=0;
+ }
+ if (mdist==maxInheritanceDepth && args && qstrcmp(args,"()")==0)
+ // no exact match found, but if args="()" an arbitrary member will do
+ {
+ //printf(" >Searching for arbitrary member\n");
+ for (mmli.toFirst();(mmd=mmli.current());++mmli)
+ {
+ //if (mmd->isLinkable())
+ //{
+ ClassDef *mcd=mmd->getClassDef();
+ //printf(" >Class %s found\n",mcd->name().data());
+ if (mcd)
+ {
+ int m=minClassDistance(fcd,mcd);
+ if (m<mdist /* && mcd->isLinkable()*/ )
+ {
+ //printf("Class distance %d\n",m);
+ mdist=m;
+ cd=mcd;
+ md=mmd;
+ }
+ }
+ //}
+ }
+ }
+ //printf(" >Succes=%d\n",mdist<maxInheritanceDepth);
+ if (mdist<maxInheritanceDepth)
+ {
+ if (!md->isLinkable() || md->isStrongEnumValue())
+ {
+ md=0; // avoid returning things we cannot link to
+ cd=0;
+ return FALSE; // match found, but was not linkable
+ }
+ else
+ {
+ gd=md->getGroupDef();
+ if (gd) cd=0;
+ return TRUE; /* found match */
+ }
+ }
+ }
+ if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum
+ {
+ //printf("Found scoped enum!\n");
+ MemberList *tml = tmd->enumFieldList();
+ if (tml)
+ {
+ MemberListIterator tmi(*tml);
+ MemberDef *emd;
+ for (;(emd=tmi.current());++tmi)
+ {
+ if (emd->localName()==mName)
+ {
+ if (emd->isLinkable())
+ {
+ cd=tmd->getClassDef();
+ md=emd;
+ return TRUE;
+ }
+ else
+ {
+ cd=0;
+ md=0;
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ /* go to the parent scope */
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
+ {
+ scopeOffset=0;
+ }
+ } while (scopeOffset>=0);
+
+ }
+ if (mn && scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function?
+ {
+ //printf("Global symbol\n");
+ MemberListIterator mmli(*mn);
+ MemberDef *mmd, *fuzzy_mmd = 0;
+ ArgumentList *argList = 0;
+ bool hasEmptyArgs = args && qstrcmp(args, "()") == 0;
+
+ if (args)
+ stringToArgumentList(args, argList = new ArgumentList);
+
+ for (mmli.toFirst(); (mmd = mmli.current()); ++mmli)
+ {
+ if (!mmd->isLinkable() || (!mmd->isRelated() && !mmd->isForeign()) ||
+ !mmd->getClassDef())
+ continue;
+
+ if (!args) break;
+
+ QCString className = mmd->getClassDef()->name();
+
+ ArgumentList *mmdAl = mmd->argumentList();
+ if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
+ Doxygen::globalScope,mmd->getFileDef(),argList,
+ checkCV
+ )
+ ) break;
+
+ if (!fuzzy_mmd && hasEmptyArgs)
+ fuzzy_mmd = mmd;
+ }
+
+ if (argList) delete argList, argList = 0;
+
+ mmd = mmd ? mmd : fuzzy_mmd;
+
+ if (mmd && !mmd->isStrongEnumValue())
+ {
+ md = mmd;
+ cd = mmd->getClassDef();
+ return TRUE;
+ }
+ }
+
+
+ // maybe an namespace, file or group member ?
+ //printf("Testing for global symbol scopeName=`%s' mScope=`%s' :: mName=`%s'\n",
+ // scopeName.data(),mScope.data(),mName.data());
+ if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known
+ {
+ //printf(" >symbol name found\n");
+ NamespaceDef *fnd=0;
+ int scopeOffset=scopeName.length();
+ do
+ {
+ QCString namespaceName = scopeName.left(scopeOffset);
+ if (!namespaceName.isEmpty() && !mScope.isEmpty())
+ {
+ namespaceName+="::"+mScope;
+ }
+ else if (!mScope.isEmpty())
+ {
+ namespaceName=mScope.copy();
+ }
+ //printf("Trying namespace %s\n",namespaceName.data());
+ if (!namespaceName.isEmpty() &&
+ (fnd=Doxygen::namespaceSDict->find(namespaceName)) &&
+ fnd->isLinkable()
+ )
+ {
+ //printf("Symbol inside existing namespace `%s' count=%d\n",
+ // namespaceName.data(),mn->count());
+ bool found=FALSE;
+ MemberListIterator mmli(*mn);
+ MemberDef *mmd;
+ for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
+ {
+ //printf("mmd->getNamespaceDef()=%p fnd=%p\n",
+ // mmd->getNamespaceDef(),fnd);
+ MemberDef *emd = mmd->getEnumScope();
+ if (emd && emd->isStrong())
+ {
+ //printf("yes match %s<->%s!\n",mScope.data(),emd->localName().data());
+ if (emd->getNamespaceDef()==fnd &&
+ rightScopeMatch(mScope,emd->localName()))
+ {
+ //printf("found it!\n");
+ nd=fnd;
+ md=mmd;
+ found=TRUE;
+ }
+ else
+ {
+ md=0;
+ cd=0;
+ return FALSE;
+ }
+ }
+ else if (mmd->getNamespaceDef()==fnd /* && mmd->isLinkable() */ )
+ { // namespace is found
+ bool match=TRUE;
+ ArgumentList *argList=0;
+ if (args && qstrcmp(args,"()")!=0)
+ {
+ argList=new ArgumentList;
+ ArgumentList *mmdAl = mmd->argumentList();
+ stringToArgumentList(args,argList);
+ match=matchArguments2(
+ mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
+ fnd,mmd->getFileDef(),argList,
+ checkCV);
+ }
+ if (match)
+ {
+ nd=fnd;
+ md=mmd;
+ found=TRUE;
+ }
+ if (args)
+ {
+ delete argList; argList=0;
+ }
+ }
+ }
+ if (!found && args && !qstrcmp(args,"()"))
+ // no exact match found, but if args="()" an arbitrary
+ // member will do
+ {
+ for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
+ {
+ if (mmd->getNamespaceDef()==fnd /*&& mmd->isLinkable() */ )
+ {
+ nd=fnd;
+ md=mmd;
+ found=TRUE;
+ }
+ }
+ }
+ if (found)
+ {
+ if (!md->isLinkable())
+ {
+ md=0; // avoid returning things we cannot link to
+ nd=0;
+ return FALSE; // match found but not linkable
+ }
+ else
+ {
+ gd=md->getGroupDef();
+ if (gd && gd->isLinkable()) nd=0; else gd=0;
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ //printf("not a namespace\n");
+ bool found=FALSE;
+ MemberListIterator mmli(*mn);
+ MemberDef *mmd;
+ for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
+ {
+ MemberDef *tmd = mmd->getEnumScope();
+ //printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>");
+ int ni=namespaceName.findRev("::");
+ //printf("namespaceName=%s ni=%d\n",namespaceName.data(),ni);
+ bool notInNS = tmd && ni==-1 && tmd->getNamespaceDef()==0 && (mScope.isEmpty() || mScope==tmd->name());
+ bool sameNS = tmd && tmd->getNamespaceDef() && namespaceName.left(ni)==tmd->getNamespaceDef()->name();
+ //printf("notInNS=%d sameNS=%d\n",notInNS,sameNS);
+ if (tmd && tmd->isStrong() && // C++11 enum class
+ (notInNS || sameNS) &&
+ namespaceName.length()>0 // enum is part of namespace so this should not be empty
+ )
+ {
+ md=mmd;
+ fd=mmd->getFileDef();
+ gd=mmd->getGroupDef();
+ if (gd && gd->isLinkable()) fd=0; else gd=0;
+ //printf("Found scoped enum %s fd=%p gd=%p\n",
+ // mmd->name().data(),fd,gd);
+ return TRUE;
+ }
+ }
+ }
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
+ {
+ scopeOffset=0;
+ }
+ } while (scopeOffset>=0);
+
+ //else // no scope => global function
+ {
+ QList<MemberDef> members;
+ // search for matches with strict static checking
+ findMembersWithSpecificName(mn,args,TRUE,currentFile,checkCV,forceTagFile,members);
+ if (members.count()==0) // nothing found
+ {
+ // search again without strict static checking
+ findMembersWithSpecificName(mn,args,FALSE,currentFile,checkCV,forceTagFile,members);
+ }
+ //printf("found %d members\n",members.count());
+ if (members.count()!=1 && args && !qstrcmp(args,"()"))
+ {
+ // no exact match found, but if args="()" an arbitrary
+ // member will do
+ MemberListIterator mni(*mn);
+ for (mni.toLast();(md=mni.current());--mni)
+ {
+ //printf("Found member `%s'\n",md->name().data());
+ //printf("member is linkable md->name()=`%s'\n",md->name().data());
+ fd=md->getFileDef();
+ gd=md->getGroupDef();
+ MemberDef *tmd = md->getEnumScope();
+ if (
+ (gd && gd->isLinkable()) || (fd && fd->isLinkable()) ||
+ (tmd && tmd->isStrong())
+ )
+ {
+ members.append(md);
+ }
+ }
+ }
+ //printf("found %d candidate members\n",members.count());
+ if (members.count()>0) // at least one match
+ {
+ if (currentFile)
+ {
+ //printf("multiple results; pick one from file:%s\n", currentFile->name().data());
+ QListIterator<MemberDef> mit(members);
+ for (mit.toFirst();(md=mit.current());++mit)
+ {
+ if (md->getFileDef() && md->getFileDef()->name() == currentFile->name())
+ {
+ break; // found match in the current file
+ }
+ }
+ if (!md) // member not in the current file
+ {
+ md=members.getLast();
+ }
+ }
+ else
+ {
+ md=members.getLast();
+ }
+ }
+ if (md && (md->getEnumScope()==0 || !md->getEnumScope()->isStrong()))
+ // found a matching global member, that is not a scoped enum value (or uniquely matches)
+ {
+ fd=md->getFileDef();
+ gd=md->getGroupDef();
+ //printf("fd=%p gd=%p gd->isLinkable()=%d\n",fd,gd,gd->isLinkable());
+ if (gd && gd->isLinkable()) fd=0; else gd=0;
+ return TRUE;
+ }
+ }
+ }
+
+ // no nothing found
+ return FALSE;
+}
+
+/*!
+ * Searches for a scope definition given its name as a string via parameter
+ * `scope`.
+ *
+ * The parameter `docScope` is a string representing the name of the scope in
+ * which the `scope` string was found.
+ *
+ * The function returns TRUE if the scope is known and documented or
+ * FALSE if it is not.
+ * If TRUE is returned exactly one of the parameter `cd`, `nd`
+ * will be non-zero:
+ * - if `cd` is non zero, the scope was a class pointed to by cd.
+ * - if `nd` is non zero, the scope was a namespace pointed to by nd.
+ */
+static bool getScopeDefs(const char *docScope,const char *scope,
+ ClassDef *&cd, NamespaceDef *&nd)
+{
+ cd=0;nd=0;
+
+ QCString scopeName=scope;
+ //printf("getScopeDefs: docScope=`%s' scope=`%s'\n",docScope,scope);
+ if (scopeName.isEmpty()) return FALSE;
+
+ bool explicitGlobalScope=FALSE;
+ if (scopeName.at(0)==':' && scopeName.at(1)==':')
+ {
+ scopeName=scopeName.right(scopeName.length()-2);
+ explicitGlobalScope=TRUE;
+ }
+
+ QCString docScopeName=docScope;
+ int scopeOffset=explicitGlobalScope ? 0 : docScopeName.length();
+
+ do // for each possible docScope (from largest to and including empty)
+ {
+ QCString fullName=scopeName.copy();
+ if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
+
+ if (((cd=getClass(fullName)) || // normal class
+ (cd=getClass(fullName+"-p")) //|| // ObjC protocol
+ //(cd=getClass(fullName+"-g")) // C# generic
+ ) && cd->isLinkable())
+ {
+ return TRUE; // class link written => quit
+ }
+ else if ((nd=Doxygen::namespaceSDict->find(fullName)) && nd->isLinkable())
+ {
+ return TRUE; // namespace link written => quit
+ }
+ if (scopeOffset==0)
+ {
+ scopeOffset=-1;
+ }
+ else if ((scopeOffset=docScopeName.findRev("::",scopeOffset-1))==-1)
+ {
+ scopeOffset=0;
+ }
+ } while (scopeOffset>=0);
+
+ return FALSE;
+}
+
+static bool isLowerCase(QCString &s)
+{
+ uchar *p=(uchar*)s.data();
+ if (p==0) return TRUE;
+ int c;
+ while ((c=*p++)) if (!islower(c)) return FALSE;
+ return TRUE;
+}
+
+/*! Returns an object to reference to given its name and context
+ * @post return value TRUE implies *resContext!=0 or *resMember!=0
+ */
+bool resolveRef(/* in */ const char *scName,
+ /* in */ const char *name,
+ /* in */ bool inSeeBlock,
+ /* out */ Definition **resContext,
+ /* out */ MemberDef **resMember,
+ bool lookForSpecialization,
+ FileDef *currentFile,
+ bool checkScope
+ )
+{
+ //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",scName,name,inSeeBlock);
+ QCString tsName = name;
+ //bool memberScopeFirst = tsName.find('#')!=-1;
+ QCString fullName = substitute(tsName,"#","::");
+ if (fullName.find("anonymous_namespace{")==-1)
+ {
+ fullName = removeRedundantWhiteSpace(substitute(fullName,".","::"));
+ }
+ else
+ {
+ fullName = removeRedundantWhiteSpace(fullName);
+ }
+
+ int bracePos=findParameterList(fullName);
+ int endNamePos=bracePos!=-1 ? bracePos : fullName.length();
+ int scopePos=fullName.findRev("::",endNamePos);
+ bool explicitScope = fullName.left(2)=="::" && // ::scope or #scope
+ (scopePos>2 || // ::N::A
+ tsName.left(2)=="::" || // ::foo in local scope
+ scName==0 // #foo in global scope
+ );
+
+ // default result values
+ *resContext=0;
+ *resMember=0;
+
+ if (bracePos==-1) // simple name
+ {
+ ClassDef *cd=0;
+ NamespaceDef *nd=0;
+
+ // the following if() was commented out for releases in the range
+ // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
+ if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
+ { // link to lower case only name => do not try to autolink
+ return FALSE;
+ }
+
+ //printf("scName=%s fullName=%s\n",scName,fullName.data());
+
+ // check if this is a class or namespace reference
+ if (scName!=fullName && getScopeDefs(scName,fullName,cd,nd))
+ {
+ if (cd) // scope matches that of a class
+ {
+ *resContext = cd;
+ }
+ else // scope matches that of a namespace
+ {
+ ASSERT(nd!=0);
+ *resContext = nd;
+ }
+ return TRUE;
+ }
+ else if (scName==fullName || (!inSeeBlock && scopePos==-1))
+ // nothing to link => output plain text
+ {
+ //printf("found scName=%s fullName=%s scName==fullName=%d "
+ // "inSeeBlock=%d scopePos=%d!\n",
+ // scName,fullName.data(),scName==fullName,inSeeBlock,scopePos);
+ return FALSE;
+ }
+ // continue search...
+ }
+
+ // extract userscope+name
+ QCString nameStr=fullName.left(endNamePos);
+ if (explicitScope) nameStr=nameStr.mid(2);
+
+ // extract arguments
+ QCString argsStr;
+ if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
+
+ // strip template specifier
+ // TODO: match against the correct partial template instantiation
+ int templPos=nameStr.find('<');
+ bool tryUnspecializedVersion = FALSE;
+ if (templPos!=-1 && nameStr.find("operator")==-1)
+ {
+ int endTemplPos=nameStr.findRev('>');
+ if (endTemplPos!=-1)
+ {
+ if (!lookForSpecialization)
+ {
+ nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
+ }
+ else
+ {
+ tryUnspecializedVersion = TRUE;
+ }
+ }
+ }
+
+ QCString scopeStr=scName;
+
+ MemberDef *md = 0;
+ ClassDef *cd = 0;
+ FileDef *fd = 0;
+ NamespaceDef *nd = 0;
+ GroupDef *gd = 0;
+
+ // check if nameStr is a member or global.
+ //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
+ // scopeStr.data(),nameStr.data(),argsStr.data(),checkScope);
+ if (getDefs(scopeStr,nameStr,argsStr,
+ md,cd,fd,nd,gd,
+ //scopePos==0 && !memberScopeFirst, // forceEmptyScope
+ explicitScope, // replaces prev line due to bug 600829
+ currentFile,
+ TRUE // checkCV
+ )
+ )
+ {
+ //printf("after getDefs checkScope=%d nameStr=%s cd=%p nd=%p\n",checkScope,nameStr.data(),cd,nd);
+ if (checkScope && md && md->getOuterScope()==Doxygen::globalScope &&
+ !md->isStrongEnumValue() &&
+ (!scopeStr.isEmpty() || nameStr.find("::")>0))
+ {
+ // we did find a member, but it is a global one while we were explicitly
+ // looking for a scoped variable. See bug 616387 for an example why this check is needed.
+ // note we do need to support autolinking to "::symbol" hence the >0
+ //printf("not global member!\n");
+ *resContext=0;
+ *resMember=0;
+ return FALSE;
+ }
+ //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
+ if (md) { *resMember=md; *resContext=md; }
+ else if (cd) *resContext=cd;
+ else if (nd) *resContext=nd;
+ else if (fd) *resContext=fd;
+ else if (gd) *resContext=gd;
+ else { *resContext=0; *resMember=0; return FALSE; }
+ //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
+ // md->name().data(),md,md->anchor().data(),md->isLinkable(),(*resContext)->name().data());
+ return TRUE;
+ }
+ else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict->find(nameStr)))
+ { // group link
+ *resContext=gd;
+ return TRUE;
+ }
+ else if (tsName.find('.')!=-1) // maybe a link to a file
+ {
+ bool ambig;
+ fd=findFileDef(Doxygen::inputNameDict,tsName,ambig);
+ if (fd && !ambig)
+ {
+ *resContext=fd;
+ return TRUE;
+ }
+ }
+
+ if (tryUnspecializedVersion)
+ {
+ return resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE,0,checkScope);
+ }
+ if (bracePos!=-1) // Try without parameters as well, could be a contructor invocation
+ {
+ *resContext=getClass(fullName.left(bracePos));
+ if (*resContext)
+ {
+ return TRUE;
+ }
+ }
+ //printf("resolveRef: %s not found!\n",name);
+
+ return FALSE;
+}
+
+QCString linkToText(SrcLangExt lang,const char *link,bool isFileName)
+{
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ QCString result=link;
+ if (!result.isEmpty())
+ {
+ // replace # by ::
+ result=substitute(result,"#","::");
+ // replace . by ::
+ if (!isFileName && result.find('<')==-1) result=substitute(result,".","::");
+ // strip leading :: prefix if present
+ if (result.at(0)==':' && result.at(1)==':')
+ {
+ result=result.right(result.length()-2);
+ }
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ result=substitute(result,"::",sep);
+ }
+ }
+ return result;
+}
+
+#if 0
+/*
+ * generate a reference to a class, namespace or member.
+ * `scName' is the name of the scope that contains the documentation
+ * string that is returned.
+ * `name' is the name that we want to link to.
+ * `name' may have five formats:
+ * 1) "ScopeName"
+ * 2) "memberName()" one of the (overloaded) function or define
+ * with name memberName.
+ * 3) "memberName(...)" a specific (overloaded) function or define
+ * with name memberName
+ * 4) "::name a global variable or define
+ * 4) "\#memberName member variable, global variable or define
+ * 5) ("ScopeName::")+"memberName()"
+ * 6) ("ScopeName::")+"memberName(...)"
+ * 7) ("ScopeName::")+"memberName"
+ * instead of :: the \# symbol may also be used.
+ */
+
+bool generateRef(OutputDocInterface &od,const char *scName,
+ const char *name,bool inSeeBlock,const char *rt)
+{
+ //printf("generateRef(scName=%s,name=%s,inSee=%d,rt=%s)\n",scName,name,inSeeBlock,rt);
+
+ Definition *compound;
+ MemberDef *md;
+
+ // create default link text
+ QCString linkText = linkToText(rt,FALSE);
+
+ if (resolveRef(scName,name,inSeeBlock,&compound,&md))
+ {
+ if (md && md->isLinkable()) // link to member
+ {
+ od.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),linkText);
+ // generate the page reference (for LaTeX)
+ if (!md->isReference())
+ {
+ writePageRef(od,md->getOutputFileBase(),md->anchor());
+ }
+ return TRUE;
+ }
+ else if (compound && compound->isLinkable()) // link to compound
+ {
+ if (rt==0 && compound->definitionType()==Definition::TypeGroup)
+ {
+ linkText=((GroupDef *)compound)->groupTitle();
+ }
+ if (compound && compound->definitionType()==Definition::TypeFile)
+ {
+ linkText=linkToText(rt,TRUE);
+ }
+ od.writeObjectLink(compound->getReference(),
+ compound->getOutputFileBase(),
+ 0,linkText);
+ if (!compound->isReference())
+ {
+ writePageRef(od,compound->getOutputFileBase(),0);
+ }
+ return TRUE;
+ }
+ }
+ od.docify(linkText);
+ return FALSE;
+}
+#endif
+
+bool resolveLink(/* in */ const char *scName,
+ /* in */ const char *lr,
+ /* in */ bool /*inSeeBlock*/,
+ /* out */ Definition **resContext,
+ /* out */ QCString &resAnchor
+ )
+{
+ *resContext=0;
+
+ QCString linkRef=lr;
+ //printf("ResolveLink linkRef=%s inSee=%d\n",lr,inSeeBlock);
+ FileDef *fd;
+ GroupDef *gd;
+ PageDef *pd;
+ ClassDef *cd;
+ DirDef *dir;
+ NamespaceDef *nd;
+ SectionInfo *si=0;
+ bool ambig;
+ if (linkRef.isEmpty()) // no reference name!
+ {
+ return FALSE;
+ }
+ else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page
+ {
+ GroupDef *gd = pd->getGroupDef();
+ if (gd)
+ {
+ if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name());
+ *resContext=gd;
+ if (si) resAnchor = si->label;
+ }
+ else
+ {
+ *resContext=pd;
+ }
+ return TRUE;
+ }
+ else if ((si=Doxygen::sectionDict->find(linkRef)))
+ {
+ *resContext=si->definition;
+ resAnchor = si->label;
+ return TRUE;
+ }
+ else if ((pd=Doxygen::exampleSDict->find(linkRef))) // link to an example
+ {
+ *resContext=pd;
+ return TRUE;
+ }
+ else if ((gd=Doxygen::groupSDict->find(linkRef))) // link to a group
+ {
+ *resContext=gd;
+ return TRUE;
+ }
+ else if ((fd=findFileDef(Doxygen::inputNameDict,linkRef,ambig)) // file link
+ && fd->isLinkable())
+ {
+ *resContext=fd;
+ return TRUE;
+ }
+ else if ((cd=getClass(linkRef))) // class link
+ {
+ *resContext=cd;
+ resAnchor=cd->anchor();
+ return TRUE;
+ }
+ else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
+ {
+ *resContext=cd;
+ resAnchor=cd->anchor();
+ return TRUE;
+ }
+// else if ((cd=getClass(linkRef+"-g"))) // C# generic link
+// {
+// *resContext=cd;
+// resAnchor=cd->anchor();
+// return TRUE;
+// }
+ else if ((nd=Doxygen::namespaceSDict->find(linkRef)))
+ {
+ *resContext=nd;
+ return TRUE;
+ }
+ else if ((dir=Doxygen::directories->find(QFileInfo(linkRef).absFilePath().utf8()+"/"))
+ && dir->isLinkable()) // TODO: make this location independent like filedefs
+ {
+ *resContext=dir;
+ return TRUE;
+ }
+ else // probably a member reference
+ {
+ MemberDef *md;
+ bool res = resolveRef(scName,lr,TRUE,resContext,&md);
+ if (md) resAnchor=md->anchor();
+ return res;
+ }
+}
+
+
+//----------------------------------------------------------------------
+// General function that generates the HTML code for a reference to some
+// file, class or member from text `lr' within the context of class `clName'.
+// This link has the text 'lt' (if not 0), otherwise `lr' is used as a
+// basis for the link's text.
+// returns TRUE if a link could be generated.
+
+bool generateLink(OutputDocInterface &od,const char *clName,
+ const char *lr,bool inSeeBlock,const char *lt)
+{
+ //printf("generateLink(clName=%s,lr=%s,lr=%s)\n",clName,lr,lt);
+ Definition *compound;
+ //PageDef *pageDef=0;
+ QCString anchor,linkText=linkToText(SrcLangExt_Unknown,lt,FALSE);
+ //printf("generateLink linkText=%s\n",linkText.data());
+ if (resolveLink(clName,lr,inSeeBlock,&compound,anchor))
+ {
+ if (compound) // link to compound
+ {
+ if (lt==0 && anchor.isEmpty() && /* compound link */
+ compound->definitionType()==Definition::TypeGroup /* is group */
+ )
+ {
+ linkText=((GroupDef *)compound)->groupTitle(); // use group's title as link
+ }
+ else if (compound->definitionType()==Definition::TypeFile)
+ {
+ linkText=linkToText(compound->getLanguage(),lt,TRUE);
+ }
+ od.writeObjectLink(compound->getReference(),
+ compound->getOutputFileBase(),anchor,linkText);
+ if (!compound->isReference())
+ {
+ writePageRef(od,compound->getOutputFileBase(),anchor);
+ }
+ }
+ else
+ {
+ err("%s:%d: Internal error: resolveLink successful but no compound found!",__FILE__,__LINE__);
+ }
+ return TRUE;
+ }
+ else // link could not be found
+ {
+ od.docify(linkText);
+ return FALSE;
+ }
+}
+
+void generateFileRef(OutputDocInterface &od,const char *name,const char *text)
+{
+ //printf("generateFileRef(%s,%s)\n",name,text);
+ QCString linkText = text ? text : name;
+ //FileInfo *fi;
+ FileDef *fd;
+ bool ambig;
+ if ((fd=findFileDef(Doxygen::inputNameDict,name,ambig)) &&
+ fd->isLinkable())
+ // link to documented input file
+ od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,linkText);
+ else
+ od.docify(linkText);
+}
+
+//----------------------------------------------------------------------
+
+#if 0
+QCString substituteClassNames(const QCString &s)
+{
+ int i=0,l,p;
+ QCString result;
+ if (s.isEmpty()) return result;
+ QRegExp r("[a-z_A-Z][a-z_A-Z0-9]*");
+ while ((p=r.match(s,i,&l))!=-1)
+ {
+ QCString *subst;
+ if (p>i) result+=s.mid(i,p-i);
+ if ((subst=substituteDict[s.mid(p,l)]))
+ {
+ result+=*subst;
+ }
+ else
+ {
+ result+=s.mid(p,l);
+ }
+ i=p+l;
+ }
+ result+=s.mid(i,s.length()-i);
+ return result;
+}
+#endif
+
+//----------------------------------------------------------------------
+
+/** Cache element for the file name to FileDef mapping cache. */
+struct FindFileCacheElem
+{
+ FindFileCacheElem(FileDef *fd,bool ambig) : fileDef(fd), isAmbig(ambig) {}
+ FileDef *fileDef;
+ bool isAmbig;
+};
+
+static QCache<FindFileCacheElem> g_findFileDefCache(5000);
+
+FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig)
+{
+ ambig=FALSE;
+ if (n==0) return 0;
+
+ QCString key;
+ key.sprintf("%p:",fnDict);
+ key+=n;
+
+ g_findFileDefCache.setAutoDelete(TRUE);
+ FindFileCacheElem *cachedResult = g_findFileDefCache.find(key);
+ //printf("key=%s cachedResult=%p\n",key.data(),cachedResult);
+ if (cachedResult)
+ {
+ ambig = cachedResult->isAmbig;
+ //printf("cached: fileDef=%p\n",cachedResult->fileDef);
+ return cachedResult->fileDef;
+ }
+ else
+ {
+ cachedResult = new FindFileCacheElem(0,FALSE);
+ }
+
+ QCString name=QDir::cleanDirPath(n).utf8();
+ QCString path;
+ int slashPos;
+ FileName *fn;
+ if (name.isEmpty()) goto exit;
+ slashPos=QMAX(name.findRev('/'),name.findRev('\\'));
+ if (slashPos!=-1)
+ {
+ path=name.left(slashPos+1);
+ name=name.right(name.length()-slashPos-1);
+ //printf("path=%s name=%s\n",path.data(),name.data());
+ }
+ if (name.isEmpty()) goto exit;
+ if ((fn=(*fnDict)[name]))
+ {
+ //printf("fn->count()=%d\n",fn->count());
+ if (fn->count()==1)
+ {
+ FileDef *fd = fn->getFirst();
+#if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
+ bool isSamePath = fd->getPath().right(path.length()).lower()==path.lower();
+#else // Unix
+ bool isSamePath = fd->getPath().right(path.length())==path;
+#endif
+ if (path.isEmpty() || isSamePath)
+ {
+ cachedResult->fileDef = fd;
+ g_findFileDefCache.insert(key,cachedResult);
+ //printf("=1 ===> add to cache %p\n",fd);
+ return fd;
+ }
+ }
+ else // file name alone is ambiguous
+ {
+ int count=0;
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ FileDef *lastMatch=0;
+ QCString pathStripped = stripFromIncludePath(path);
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ QCString fdStripPath = stripFromIncludePath(fd->getPath());
+ if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
+ {
+ count++;
+ lastMatch=fd;
+ }
+ }
+ //printf(">1 ===> add to cache %p\n",fd);
+
+ ambig=(count>1);
+ cachedResult->isAmbig = ambig;
+ cachedResult->fileDef = lastMatch;
+ g_findFileDefCache.insert(key,cachedResult);
+ return lastMatch;
+ }
+ }
+ else
+ {
+ //printf("not found!\n");
+ }
+exit:
+ //printf("0 ===> add to cache %p: %s\n",cachedResult,n);
+ g_findFileDefCache.insert(key,cachedResult);
+ //delete cachedResult;
+ return 0;
+}
+
+//----------------------------------------------------------------------
+
+QCString showFileDefMatches(const FileNameDict *fnDict,const char *n)
+{
+ QCString result;
+ QCString name=n;
+ QCString path;
+ int slashPos=QMAX(name.findRev('/'),name.findRev('\\'));
+ if (slashPos!=-1)
+ {
+ path=name.left(slashPos+1);
+ name=name.right(name.length()-slashPos-1);
+ }
+ FileName *fn;
+ if ((fn=(*fnDict)[name]))
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (fni.toFirst();(fd=fni.current());++fni)
+ {
+ if (path.isEmpty() || fd->getPath().right(path.length())==path)
+ {
+ result+=" "+fd->absFilePath()+"\n";
+ }
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------
+
+QCString substituteKeywords(const QCString &s,const char *title,
+ const char *projName,const char *projNum,const char *projBrief)
+{
+ QCString result = s;
+ if (title) result = substitute(result,"$title",title);
+ result = substitute(result,"$datetime",dateToString(TRUE));
+ result = substitute(result,"$date",dateToString(FALSE));
+ result = substitute(result,"$year",yearToString());
+ result = substitute(result,"$doxygenversion",versionString);
+ result = substitute(result,"$projectname",projName);
+ result = substitute(result,"$projectnumber",projNum);
+ result = substitute(result,"$projectbrief",projBrief);
+ result = substitute(result,"$projectlogo",stripPath(Config_getString("PROJECT_LOGO")));
+ return result;
+}
+
+//----------------------------------------------------------------------
+
+/*! Returns the character index within \a name of the first prefix
+ * in Config_getList("IGNORE_PREFIX") that matches \a name at the left hand side,
+ * or zero if no match was found
+ */
+int getPrefixIndex(const QCString &name)
+{
+ if (name.isEmpty()) return 0;
+ static QStrList &sl = Config_getList("IGNORE_PREFIX");
+ char *s = sl.first();
+ while (s)
+ {
+ const char *ps=s;
+ const char *pd=name.data();
+ int i=0;
+ while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
+ if (*ps==0 && *pd!=0)
+ {
+ return i;
+ }
+ s = sl.next();
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+
+static void initBaseClassHierarchy(BaseClassList *bcl)
+{
+ if (bcl==0) return;
+ BaseClassListIterator bcli(*bcl);
+ for ( ; bcli.current(); ++bcli)
+ {
+ ClassDef *cd=bcli.current()->classDef;
+ if (cd->baseClasses()==0) // no base classes => new root
+ {
+ initBaseClassHierarchy(cd->baseClasses());
+ }
+ cd->visited=FALSE;
+ }
+}
+//----------------------------------------------------------------------------
+
+bool classHasVisibleChildren(ClassDef *cd)
+{
+ BaseClassList *bcl;
+
+ if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
+ {
+ if (cd->baseClasses()==0) return FALSE;
+ bcl=cd->baseClasses();
+ }
+ else
+ {
+ if (cd->subClasses()==0) return FALSE;
+ bcl=cd->subClasses();
+ }
+
+ BaseClassListIterator bcli(*bcl);
+ for ( ; bcli.current() ; ++bcli)
+ {
+ if (bcli.current()->classDef->isVisibleInHierarchy())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------
+
+void initClassHierarchy(ClassSDict *cl)
+{
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for ( ; (cd=cli.current()); ++cli)
+ {
+ cd->visited=FALSE;
+ initBaseClassHierarchy(cd->baseClasses());
+ }
+}
+
+//----------------------------------------------------------------------------
+
+bool hasVisibleRoot(BaseClassList *bcl)
+{
+ if (bcl)
+ {
+ BaseClassListIterator bcli(*bcl);
+ for ( ; bcli.current(); ++bcli)
+ {
+ ClassDef *cd=bcli.current()->classDef;
+ if (cd->isVisibleInHierarchy()) return TRUE;
+ hasVisibleRoot(cd->baseClasses());
+ }
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+
+// note that this function is not reentrant due to the use of static growBuf!
+QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscore)
+{
+ static bool caseSenseNames = Config_getBool("CASE_SENSE_NAMES");
+ static bool allowUnicodeNames = Config_getBool("ALLOW_UNICODE_NAMES");
+ static GrowBuf growBuf;
+ growBuf.clear();
+ char c;
+ const char *p=name;
+ while ((c=*p++)!=0)
+ {
+ switch(c)
+ {
+ case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
+ case '-': growBuf.addChar('-'); break;
+ case ':': growBuf.addStr("_1"); break;
+ case '/': growBuf.addStr("_2"); break;
+ case '<': growBuf.addStr("_3"); break;
+ case '>': growBuf.addStr("_4"); break;
+ case '*': growBuf.addStr("_5"); break;
+ case '&': growBuf.addStr("_6"); break;
+ case '|': growBuf.addStr("_7"); break;
+ case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
+ case '!': growBuf.addStr("_9"); break;
+ case ',': growBuf.addStr("_00"); break;
+ case ' ': growBuf.addStr("_01"); break;
+ case '{': growBuf.addStr("_02"); break;
+ case '}': growBuf.addStr("_03"); break;
+ case '?': growBuf.addStr("_04"); break;
+ case '^': growBuf.addStr("_05"); break;
+ case '%': growBuf.addStr("_06"); break;
+ case '(': growBuf.addStr("_07"); break;
+ case ')': growBuf.addStr("_08"); break;
+ case '+': growBuf.addStr("_09"); break;
+ case '=': growBuf.addStr("_0A"); break;
+ case '$': growBuf.addStr("_0B"); break;
+ case '\\': growBuf.addStr("_0C"); break;
+ default:
+ if (c<0)
+ {
+ char ids[5];
+ const unsigned char uc = (unsigned char)c;
+ bool doEscape = TRUE;
+ if (allowUnicodeNames && uc <= 0xf7)
+ {
+ const char* pt = p;
+ ids[ 0 ] = c;
+ int l = 0;
+ if ((uc&0xE0)==0xC0)
+ {
+ l=2; // 11xx.xxxx: >=2 byte character
+ }
+ if ((uc&0xF0)==0xE0)
+ {
+ l=3; // 111x.xxxx: >=3 byte character
+ }
+ if ((uc&0xF8)==0xF0)
+ {
+ l=4; // 1111.xxxx: >=4 byte character
+ }
+ doEscape = l==0;
+ for (int m=1; m<l && !doEscape; ++m)
+ {
+ unsigned char ct = (unsigned char)*pt;
+ if (ct==0 || (ct&0xC0)!=0x80) // invalid unicode character
+ {
+ doEscape=TRUE;
+ }
+ else
+ {
+ ids[ m ] = *pt++;
+ }
+ }
+ if ( !doEscape ) // got a valid unicode character
+ {
+ ids[ l ] = 0;
+ growBuf.addStr( ids );
+ p += l - 1;
+ }
+ }
+ if (doEscape) // not a valid unicode char or escaping needed
+ {
+ static char map[] = "0123456789ABCDEF";
+ unsigned char id = (unsigned char)c;
+ ids[0]='_';
+ ids[1]='x';
+ ids[2]=map[id>>4];
+ ids[3]=map[id&0xF];
+ ids[4]=0;
+ growBuf.addStr(ids);
+ }
+ }
+ else if (caseSenseNames || !isupper(c))
+ {
+ growBuf.addChar(c);
+ }
+ else
+ {
+ growBuf.addChar('_');
+ growBuf.addChar(tolower(c));
+ }
+ break;
+ }
+ }
+ growBuf.addChar(0);
+ return growBuf.get();
+}
+
+/*! This function determines the file name on disk of an item
+ * given its name, which could be a class name with template
+ * arguments, so special characters need to be escaped.
+ */
+QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore)
+{
+ static bool shortNames = Config_getBool("SHORT_NAMES");
+ static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
+ QCString result;
+ if (shortNames) // use short names only
+ {
+ static QDict<int> usedNames(10007);
+ usedNames.setAutoDelete(TRUE);
+ static int count=1;
+
+ int *value=usedNames.find(name);
+ int num;
+ if (value==0)
+ {
+ usedNames.insert(name,new int(count));
+ num = count++;
+ }
+ else
+ {
+ num = *value;
+ }
+ result.sprintf("a%05d",num);
+ }
+ else // long names
+ {
+ result=escapeCharsInString(name,allowDots,allowUnderscore);
+ int resultLen = result.length();
+ if (resultLen>=128) // prevent names that cannot be created!
+ {
+ // third algorithm based on MD5 hash
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)result.data(),resultLen,md5_sig);
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ result=result.left(128-32)+sigStr;
+ }
+ }
+ if (createSubdirs)
+ {
+ int l1Dir=0,l2Dir=0;
+
+#if MAP_ALGO==ALGO_COUNT
+ // old algorithm, has the problem that after regeneration the
+ // output can be located in a different dir.
+ if (Doxygen::htmlDirMap==0)
+ {
+ Doxygen::htmlDirMap=new QDict<int>(100003);
+ Doxygen::htmlDirMap->setAutoDelete(TRUE);
+ }
+ static int curDirNum=0;
+ int *dirNum = Doxygen::htmlDirMap->find(result);
+ if (dirNum==0) // new name
+ {
+ Doxygen::htmlDirMap->insert(result,new int(curDirNum));
+ l1Dir = (curDirNum)&0xf; // bits 0-3
+ l2Dir = (curDirNum>>4)&0xff; // bits 4-11
+ curDirNum++;
+ }
+ else // existing name
+ {
+ l1Dir = (*dirNum)&0xf; // bits 0-3
+ l2Dir = ((*dirNum)>>4)&0xff; // bits 4-11
+ }
+#elif MAP_ALGO==ALGO_CRC16
+ // second algorithm based on CRC-16 checksum
+ int dirNum = qChecksum(result,result.length());
+ l1Dir = dirNum&0xf;
+ l2Dir = (dirNum>>4)&0xff;
+#elif MAP_ALGO==ALGO_MD5
+ // third algorithm based on MD5 hash
+ uchar md5_sig[16];
+ MD5Buffer((const unsigned char *)result.data(),result.length(),md5_sig);
+ l1Dir = md5_sig[14]&0xf;
+ l2Dir = md5_sig[15];
+#endif
+ result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
+ }
+ //printf("*** convertNameToFile(%s)->%s\n",name,result.data());
+ return result;
+}
+
+QCString relativePathToRoot(const char *name)
+{
+ QCString result;
+ if (Config_getBool("CREATE_SUBDIRS"))
+ {
+ if (name==0)
+ {
+ return REL_PATH_TO_ROOT;
+ }
+ else
+ {
+ QCString n = name;
+ int i = n.findRev('/');
+ if (i!=-1)
+ {
+ result=REL_PATH_TO_ROOT;
+ }
+ }
+ }
+ return result;
+}
+
+void createSubDirs(QDir &d)
+{
+ if (Config_getBool("CREATE_SUBDIRS"))
+ {
+ // create 4096 subdirectories
+ int l1,l2;
+ for (l1=0;l1<16;l1++)
+ {
+ d.mkdir(QCString().sprintf("d%x",l1));
+ for (l2=0;l2<256;l2++)
+ {
+ d.mkdir(QCString().sprintf("d%x/d%02x",l1,l2));
+ }
+ }
+ }
+}
+
+/*! Input is a scopeName, output is the scopename split into a
+ * namespace part (as large as possible) and a classname part.
+ */
+void extractNamespaceName(const QCString &scopeName,
+ QCString &className,QCString &namespaceName,
+ bool allowEmptyClass)
+{
+ int i,p;
+ QCString clName=scopeName;
+ NamespaceDef *nd = 0;
+ if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==0)
+ { // the whole name is a namespace (and not a class)
+ namespaceName=nd->name().copy();
+ className.resize(0);
+ goto done;
+ }
+ p=clName.length()-2;
+ while (p>=0 && (i=clName.findRev("::",p))!=-1)
+ // see if the first part is a namespace (and not a class)
+ {
+ //printf("Trying %s\n",clName.left(i).data());
+ if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==0)
+ {
+ //printf("found!\n");
+ namespaceName=nd->name().copy();
+ className=clName.right(clName.length()-i-2);
+ goto done;
+ }
+ p=i-2; // try a smaller piece of the scope
+ }
+ //printf("not found!\n");
+
+ // not found, so we just have to guess.
+ className=scopeName.copy();
+ namespaceName.resize(0);
+
+done:
+ if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
+ {
+ // class and namespace with the same name, correct to return the class.
+ className=namespaceName.copy();
+ namespaceName.resize(0);
+ }
+ //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(),
+ // className.data(),namespaceName.data());
+ if (/*className.right(2)=="-g" ||*/ className.right(2)=="-p")
+ {
+ className = className.left(className.length()-2);
+ }
+ return;
+}
+
+QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ)
+{
+ QCString result=scope.copy();
+ if (!templ.isEmpty() && scope.find('<')==-1)
+ {
+ int si,pi=0;
+ ClassDef *cd=0;
+ while (
+ (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
+ ((cd=getClass(scope.left(si)))==0 || cd->templateArguments()==0)
+ )
+ {
+ //printf("Tried `%s'\n",(scope.left(si)+templ).data());
+ pi=si+2;
+ }
+ if (si==-1) // not nested => append template specifier
+ {
+ result+=templ;
+ }
+ else // nested => insert template specifier before after first class name
+ {
+ result=scope.left(si) + templ + scope.right(scope.length()-si);
+ }
+ }
+ //printf("insertTemplateSpecifierInScope(`%s',`%s')=%s\n",
+ // scope.data(),templ.data(),result.data());
+ return result;
+}
+
+#if 0 // original version
+/*! Strips the scope from a name. Examples: A::B will return A
+ * and A<T>::B<N::C<D> > will return A<T>.
+ */
+QCString stripScope(const char *name)
+{
+ QCString result = name;
+ int l=result.length();
+ int p=l-1;
+ bool done;
+ int count;
+
+ while (p>=0)
+ {
+ char c=result.at(p);
+ switch (c)
+ {
+ case ':':
+ //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data());
+ return result.right(l-p-1);
+ case '>':
+ count=1;
+ done=FALSE;
+ //printf("pos < = %d\n",p);
+ p--;
+ while (p>=0 && !done)
+ {
+ c=result.at(p--);
+ switch (c)
+ {
+ case '>': count++; break;
+ case '<': count--; if (count<=0) done=TRUE; break;
+ default:
+ //printf("c=%c count=%d\n",c,count);
+ break;
+ }
+ }
+ //printf("pos > = %d\n",p+1);
+ break;
+ default:
+ p--;
+ }
+ }
+ //printf("stripScope(%s)=%s\n",name,name);
+ return name;
+}
+#endif
+
+// new version by Davide Cesari which also works for Fortran
+QCString stripScope(const char *name)
+{
+ QCString result = name;
+ int l=result.length();
+ int p;
+ bool done = FALSE;
+ bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
+ int count=0;
+
+ do
+ {
+ p=l-1; // start at the end of the string
+ while (p>=0 && count>=0)
+ {
+ char c=result.at(p);
+ switch (c)
+ {
+ case ':':
+ // only exit in the case of ::
+ //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data());
+ if (p>0 && result.at(p-1)==':') return result.right(l-p-1);
+ p--;
+ break;
+ case '>':
+ if (skipBracket) // we don't care about brackets
+ {
+ p--;
+ }
+ else // count open/close brackets
+ {
+ if (p>0 && result.at(p-1)=='>') // skip >> operator
+ {
+ p-=2;
+ break;
+ }
+ count=1;
+ //printf("pos < = %d\n",p);
+ p--;
+ bool foundMatch=false;
+ while (p>=0 && !foundMatch)
+ {
+ c=result.at(p--);
+ switch (c)
+ {
+ case '>':
+ count++;
+ break;
+ case '<':
+ if (p>0)
+ {
+ if (result.at(p-1) == '<') // skip << operator
+ {
+ p--;
+ break;
+ }
+ }
+ count--;
+ foundMatch = count==0;
+ break;
+ default:
+ //printf("c=%c count=%d\n",c,count);
+ break;
+ }
+ }
+ }
+ //printf("pos > = %d\n",p+1);
+ break;
+ default:
+ p--;
+ }
+ }
+ done = count==0 || skipBracket; // reparse if brackets do not match
+ skipBracket=TRUE;
+ }
+ while (!done); // if < > unbalanced repeat ignoring them
+ //printf("stripScope(%s)=%s\n",name,name);
+ return name;
+}
+
+
+/*! Converts a string to an XML-encoded string */
+QCString convertToXML(const char *s)
+{
+ static GrowBuf growBuf;
+ growBuf.clear();
+ if (s==0) return "";
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '<': growBuf.addStr("<"); break;
+ case '>': growBuf.addStr(">"); break;
+ case '&': growBuf.addStr("&"); break;
+ case '\'': growBuf.addStr("'"); break;
+ case '"': growBuf.addStr("""); break;
+ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
+ case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
+ case 27: case 28: case 29: case 30: case 31:
+ break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
+ default: growBuf.addChar(c); break;
+ }
+ }
+ growBuf.addChar(0);
+ return growBuf.get();
+}
+
+/*! Converts a string to a HTML-encoded string */
+QCString convertToHtml(const char *s,bool keepEntities)
+{
+ static GrowBuf growBuf;
+ growBuf.clear();
+ if (s==0) return "";
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '<': growBuf.addStr("<"); break;
+ case '>': growBuf.addStr(">"); break;
+ case '&': if (keepEntities)
+ {
+ const char *e=p;
+ char ce;
+ while ((ce=*e++))
+ {
+ if (ce==';' || (!(isId(ce) || ce=='#'))) break;
+ }
+ if (ce==';') // found end of an entity
+ {
+ // copy entry verbatim
+ growBuf.addChar(c);
+ while (p<e) growBuf.addChar(*p++);
+ }
+ else
+ {
+ growBuf.addStr("&");
+ }
+ }
+ else
+ {
+ growBuf.addStr("&");
+ }
+ break;
+ case '\'': growBuf.addStr("'"); break;
+ case '"': growBuf.addStr("""); break;
+ default: growBuf.addChar(c); break;
+ }
+ }
+ growBuf.addChar(0);
+ return growBuf.get();
+}
+
+QCString convertToJSString(const char *s)
+{
+ static GrowBuf growBuf;
+ growBuf.clear();
+ if (s==0) return "";
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '"': growBuf.addStr("\\\""); break;
+ case '\\': growBuf.addStr("\\\\"); break;
+ default: growBuf.addChar(c); break;
+ }
+ }
+ growBuf.addChar(0);
+ return convertCharEntitiesToUTF8(growBuf.get());
+}
+
+
+QCString convertCharEntitiesToUTF8(const QCString &s)
+{
+ QCString result;
+ static QRegExp entityPat("&[a-zA-Z]+[0-9]*;");
+
+ if (s.length()==0) return result;
+ static GrowBuf growBuf;
+ growBuf.clear();
+ int p,i=0,l;
+ while ((p=entityPat.match(s,i,&l))!=-1)
+ {
+ if (p>i)
+ {
+ growBuf.addStr(s.mid(i,p-i));
+ }
+ QCString entity = s.mid(p,l);
+ DocSymbol::SymType symType = HtmlEntityMapper::instance()->name2sym(entity);
+ const char *code=0;
+ if (symType!=DocSymbol::Sym_Unknown && (code=HtmlEntityMapper::instance()->utf8(symType)))
+ {
+ growBuf.addStr(code);
+ }
+ else
+ {
+ growBuf.addStr(s.mid(p,l));
+ }
+ i=p+l;
+ }
+ growBuf.addStr(s.mid(i,s.length()-i));
+ growBuf.addChar(0);
+ //printf("convertCharEntitiesToUTF8(%s)->%s\n",s.data(),growBuf.get());
+ return growBuf.get();
+}
+
+/*! Returns the standard string that is generated when the \\overload
+ * command is used.
+ */
+QCString getOverloadDocs()
+{
+ return theTranslator->trOverloadText();
+ //"This is an overloaded member function, "
+ // "provided for convenience. It differs from the above "
+ // "function only in what argument(s) it accepts.";
+}
+
+void addMembersToMemberGroup(MemberList *ml,
+ MemberGroupSDict **ppMemberGroupSDict,
+ Definition *context)
+{
+ ASSERT(context!=0);
+ //printf("addMemberToMemberGroup()\n");
+ if (ml==0) return;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ uint index;
+ for (index=0;(md=mli.current());)
+ {
+ if (md->isEnumerate()) // insert enum value of this enum into groups
+ {
+ MemberList *fmdl=md->enumFieldList();
+ if (fmdl!=0)
+ {
+ MemberListIterator fmli(*fmdl);
+ MemberDef *fmd;
+ for (fmli.toFirst();(fmd=fmli.current());++fmli)
+ {
+ int groupId=fmd->getMemberGroupId();
+ if (groupId!=-1)
+ {
+ MemberGroupInfo *info = Doxygen::memGrpInfoDict[groupId];
+ //QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
+ //QCString *pDocs = Doxygen::memberDocDict[groupId];
+ if (info)
+ {
+ if (*ppMemberGroupSDict==0)
+ {
+ *ppMemberGroupSDict = new MemberGroupSDict;
+ (*ppMemberGroupSDict)->setAutoDelete(TRUE);
+ }
+ MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
+ if (mg==0)
+ {
+ mg = new MemberGroup(
+ context,
+ groupId,
+ info->header,
+ info->doc,
+ info->docFile
+ );
+ (*ppMemberGroupSDict)->append(groupId,mg);
+ }
+ mg->insertMember(fmd); // insert in member group
+ fmd->setMemberGroup(mg);
+ }
+ }
+ }
+ }
+ }
+ int groupId=md->getMemberGroupId();
+ if (groupId!=-1)
+ {
+ MemberGroupInfo *info = Doxygen::memGrpInfoDict[groupId];
+ //QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
+ //QCString *pDocs = Doxygen::memberDocDict[groupId];
+ if (info)
+ {
+ if (*ppMemberGroupSDict==0)
+ {
+ *ppMemberGroupSDict = new MemberGroupSDict;
+ (*ppMemberGroupSDict)->setAutoDelete(TRUE);
+ }
+ MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
+ if (mg==0)
+ {
+ mg = new MemberGroup(
+ context,
+ groupId,
+ info->header,
+ info->doc,
+ info->docFile
+ );
+ (*ppMemberGroupSDict)->append(groupId,mg);
+ }
+ md = ml->take(index); // remove from member list
+ mg->insertMember(md); // insert in member group
+ mg->setRefItems(info->m_sli);
+ md->setMemberGroup(mg);
+ continue;
+ }
+ }
+ ++mli;++index;
+ }
+}
+
+/*! Extracts a (sub-)string from \a type starting at \a pos that
+ * could form a class. The index of the match is returned and the found
+ * class \a name and a template argument list \a templSpec. If -1 is returned
+ * there are no more matches.
+ */
+int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCString &templSpec,SrcLangExt lang)
+{
+ static const QRegExp re_norm("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*");
+ static const QRegExp re_ftn("[a-z_A-Z\\x80-\\xFF][()=_a-z_A-Z0-9:\\x80-\\xFF]*");
+ QRegExp re;
+
+ name.resize(0);
+ templSpec.resize(0);
+ int i,l;
+ int typeLen=type.length();
+ if (typeLen>0)
+ {
+ if (lang == SrcLangExt_Fortran)
+ {
+ if (type.at(pos)==',') return -1;
+ if (type.left(4).lower()=="type")
+ {
+ re = re_norm;
+ }
+ else
+ {
+ re = re_ftn;
+ }
+ }
+ else
+ {
+ re = re_norm;
+ }
+
+ if ((i=re.match(type,pos,&l))!=-1) // for each class name in the type
+ {
+ int ts=i+l;
+ int te=ts;
+ int tl=0;
+ while (type.at(ts)==' ' && ts<typeLen) ts++,tl++; // skip any whitespace
+ if (type.at(ts)=='<') // assume template instance
+ {
+ // locate end of template
+ te=ts+1;
+ int brCount=1;
+ while (te<typeLen && brCount!=0)
+ {
+ if (type.at(te)=='<')
+ {
+ if (te<typeLen-1 && type.at(te+1)=='<') te++; else brCount++;
+ }
+ if (type.at(te)=='>')
+ {
+ if (te<typeLen-1 && type.at(te+1)=='>') te++; else brCount--;
+ }
+ te++;
+ }
+ }
+ name = type.mid(i,l);
+ if (te>ts)
+ {
+ templSpec = type.mid(ts,te-ts),tl+=te-ts;
+ pos=i+l+tl;
+ }
+ else // no template part
+ {
+ pos=i+l;
+ }
+ //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE\n",
+ // type.data(),pos,name.data(),templSpec.data());
+ return i;
+ }
+ }
+ pos = typeLen;
+ //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
+ // type.data(),pos,name.data(),templSpec.data());
+ return -1;
+}
+
+QCString normalizeNonTemplateArgumentsInString(
+ const QCString &name,
+ Definition *context,
+ const ArgumentList * formalArgs)
+{
+ // skip until <
+ int p=name.find('<');
+ if (p==-1) return name;
+ p++;
+ QCString result = name.left(p);
+
+ static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
+ int l,i;
+ // for each identifier in the template part (e.g. B<T> -> T)
+ while ((i=re.match(name,p,&l))!=-1)
+ {
+ result += name.mid(p,i-p);
+ QCString n = name.mid(i,l);
+ bool found=FALSE;
+ if (formalArgs) // check that n is not a formal template argument
+ {
+ ArgumentListIterator formAli(*formalArgs);
+ Argument *formArg;
+ for (formAli.toFirst();
+ (formArg=formAli.current()) && !found;
+ ++formAli
+ )
+ {
+ found = formArg->name==n;
+ }
+ }
+ if (!found)
+ {
+ // try to resolve the type
+ ClassDef *cd = getResolvedClass(context,0,n);
+ if (cd)
+ {
+ result+=cd->name();
+ }
+ else
+ {
+ result+=n;
+ }
+ }
+ else
+ {
+ result+=n;
+ }
+ p=i+l;
+ }
+ result+=name.right(name.length()-p);
+ //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",name.data(),result.data());
+ return removeRedundantWhiteSpace(result);
+}
+
+
+/*! Substitutes any occurrence of a formal argument from argument list
+ * \a formalArgs in \a name by the corresponding actual argument in
+ * argument list \a actualArgs. The result after substitution
+ * is returned as a string. The argument \a name is used to
+ * prevent recursive substitution.
+ */
+QCString substituteTemplateArgumentsInString(
+ const QCString &name,
+ ArgumentList *formalArgs,
+ ArgumentList *actualArgs)
+{
+ //printf("substituteTemplateArgumentsInString(name=%s formal=%s actualArg=%s)\n",
+ // name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data());
+ if (formalArgs==0) return name;
+ QCString result;
+ static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
+ int p=0,l,i;
+ // for each identifier in the base class name (e.g. B<T> -> B and T)
+ while ((i=re.match(name,p,&l))!=-1)
+ {
+ result += name.mid(p,i-p);
+ QCString n = name.mid(i,l);
+ ArgumentListIterator formAli(*formalArgs);
+ ArgumentListIterator actAli(*actualArgs);
+ Argument *formArg;
+ Argument *actArg;
+
+ // if n is a template argument, then we substitute it
+ // for its template instance argument.
+ bool found=FALSE;
+ for (formAli.toFirst();
+ (formArg=formAli.current()) && !found && (actArg=actAli.current());
+ ++formAli,++actAli
+ )
+ {
+ if (formArg->type.left(6)=="class " && formArg->name.isEmpty())
+ {
+ formArg->name = formArg->type.mid(6);
+ formArg->type = "class";
+ }
+ if (formArg->type.left(9)=="typename " && formArg->name.isEmpty())
+ {
+ formArg->name = formArg->type.mid(9);
+ formArg->type = "typename";
+ }
+ if (formArg->type=="class" || formArg->type=="typename" || formArg->type.left(8)=="template")
+ {
+ //printf("n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s'\n",
+ // n.data(),formArg->type.data(),formArg->name.data(),formArg->defval.data());
+ //printf(">> formArg->name='%s' actArg->type='%s' actArg->name='%s'\n",
+ // formArg->name.data(),actArg->type.data(),actArg->name.data()
+ // );
+ if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument
+ {
+ // replace formal argument with the actual argument of the instance
+ if (!leftScopeMatch(actArg->type,n))
+ // the scope guard is to prevent recursive lockup for
+ // template<class A> class C : public<A::T>,
+ // where A::T would become A::T::T here,
+ // since n==A and actArg->type==A::T
+ // see bug595833 for an example
+ {
+ if (actArg->name.isEmpty())
+ {
+ result += actArg->type+" ";
+ found=TRUE;
+ }
+ else
+ // for case where the actual arg is something like "unsigned int"
+ // the "int" part is in actArg->name.
+ {
+ result += actArg->type+" "+actArg->name+" ";
+ found=TRUE;
+ }
+ }
+ }
+ else if (formArg->name==n &&
+ actArg==0 &&
+ !formArg->defval.isEmpty() &&
+ formArg->defval!=name /* to prevent recursion */
+ )
+ {
+ result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs)+" ";
+ found=TRUE;
+ }
+ }
+ else if (formArg->name==n &&
+ actArg==0 &&
+ !formArg->defval.isEmpty() &&
+ formArg->defval!=name /* to prevent recursion */
+ )
+ {
+ result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs)+" ";
+ found=TRUE;
+ }
+ }
+ if (!found)
+ {
+ result += n;
+ }
+ p=i+l;
+ }
+ result+=name.right(name.length()-p);
+ //printf(" Inheritance relation %s -> %s\n",
+ // name.data(),result.data());
+ return result.stripWhiteSpace();
+}
+
+/*! Makes a deep copy of the list of argument lists \a srcLists.
+ * Will allocate memory, that is owned by the caller.
+ */
+QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists)
+{
+ ASSERT(srcLists!=0);
+ QList<ArgumentList> *dstLists = new QList<ArgumentList>;
+ dstLists->setAutoDelete(TRUE);
+ QListIterator<ArgumentList> sli(*srcLists);
+ ArgumentList *sl;
+ for (;(sl=sli.current());++sli)
+ {
+ dstLists->append(sl->deepCopy());
+ }
+ return dstLists;
+}
+
+/*! Strips template specifiers from scope \a fullName, except those
+ * that make up specialized classes. The switch \a parentOnly
+ * determines whether or not a template "at the end" of a scope
+ * should be considered, e.g. with \a parentOnly is \c TRUE, A<T>::B<S> will
+ * try to strip \<T\> and not \<S\>, while \a parentOnly is \c FALSE will
+ * strip both unless A<T> or B<S> are specialized template classes.
+ */
+QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
+ bool parentOnly,
+ QCString *pLastScopeStripped)
+{
+ QCString result;
+ int p=0;
+ int l=fullName.length();
+ int i=fullName.find('<');
+ while (i!=-1)
+ {
+ //printf("1:result+=%s\n",fullName.mid(p,i-p).data());
+ int e=i+1;
+ bool done=FALSE;
+ int count=1;
+ while (e<l && !done)
+ {
+ char c=fullName.at(e++);
+ if (c=='<')
+ {
+ count++;
+ }
+ else if (c=='>')
+ {
+ count--;
+ done = count==0;
+ }
+ }
+ int si= fullName.find("::",e);
+
+ if (parentOnly && si==-1) break;
+ // we only do the parent scope, so we stop here if needed
+
+ result+=fullName.mid(p,i-p);
+ //printf(" trying %s\n",(result+fullName.mid(i,e-i)).data());
+ if (getClass(result+fullName.mid(i,e-i))!=0)
+ {
+ result+=fullName.mid(i,e-i);
+ //printf(" 2:result+=%s\n",fullName.mid(i,e-i-1).data());
+ }
+ else if (pLastScopeStripped)
+ {
+ //printf(" last stripped scope '%s'\n",fullName.mid(i,e-i).data());
+ *pLastScopeStripped=fullName.mid(i,e-i);
+ }
+ p=e;
+ i=fullName.find('<',p);
+ }
+ result+=fullName.right(l-p);
+ //printf("3:result+=%s\n",fullName.right(l-p).data());
+ return result;
+}
+
+/*! Merges two scope parts together. The parts may (partially) overlap.
+ * Example1: \c A::B and \c B::C will result in \c A::B::C <br>
+ * Example2: \c A and \c B will be \c A::B <br>
+ * Example3: \c A::B and B will be \c A::B
+ *
+ * @param leftScope the left hand part of the scope.
+ * @param rightScope the right hand part of the scope.
+ * @returns the merged scope.
+ */
+QCString mergeScopes(const QCString &leftScope,const QCString &rightScope)
+{
+ // case leftScope=="A" rightScope=="A::B" => result = "A::B"
+ if (leftScopeMatch(rightScope,leftScope)) return rightScope;
+ QCString result;
+ int i=0,p=leftScope.length();
+
+ // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
+ // case leftScope=="A::B" rightScope=="B" => result = "A::B"
+ bool found=FALSE;
+ while ((i=leftScope.findRev("::",p))!=-1)
+ {
+ if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
+ {
+ result = leftScope.left(i+2)+rightScope;
+ found=TRUE;
+ }
+ p=i-1;
+ }
+ if (found) return result;
+
+ // case leftScope=="A" rightScope=="B" => result = "A::B"
+ result=leftScope.copy();
+ if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
+ result+=rightScope;
+ return result;
+}
+
+/*! Returns a fragment from scope \a s, starting at position \a p.
+ *
+ * @param s the scope name as a string.
+ * @param p the start position (0 is the first).
+ * @param l the resulting length of the fragment.
+ * @returns the location of the fragment, or -1 if non is found.
+ */
+int getScopeFragment(const QCString &s,int p,int *l)
+{
+ int sl=s.length();
+ int sp=p;
+ int count=0;
+ bool done;
+ if (sp>=sl) return -1;
+ while (sp<sl)
+ {
+ char c=s.at(sp);
+ if (c==':') sp++,p++; else break;
+ }
+ while (sp<sl)
+ {
+ char c=s.at(sp);
+ switch (c)
+ {
+ case ':': // found next part
+ goto found;
+ case '<': // skip template specifier
+ count=1;sp++;
+ done=FALSE;
+ while (sp<sl && !done)
+ {
+ // TODO: deal with << and >> operators!
+ char c=s.at(sp++);
+ switch(c)
+ {
+ case '<': count++; break;
+ case '>': count--; if (count==0) done=TRUE; break;
+ default: break;
+ }
+ }
+ break;
+ default:
+ sp++;
+ break;
+ }
+ }
+found:
+ *l=sp-p;
+ //printf("getScopeFragment(%s,%d)=%s\n",s.data(),p,s.mid(p,*l).data());
+ return p;
+}
+
+//----------------------------------------------------------------------------
+
+PageDef *addRelatedPage(const char *name,const QCString &ptitle,
+ const QCString &doc,
+ QList<SectionInfo> * /*anchors*/,
+ const char *fileName,int startLine,
+ const QList<ListItemInfo> *sli,
+ GroupDef *gd,
+ TagInfo *tagInfo,
+ SrcLangExt lang
+ )
+{
+ PageDef *pd=0;
+ //printf("addRelatedPage(name=%s gd=%p)\n",name,gd);
+ if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo)
+ {
+ // append documentation block to the page.
+ pd->setDocumentation(doc,fileName,startLine);
+ //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pi,name);
+ }
+ else // new page
+ {
+ QCString baseName=name;
+ if (baseName.right(4)==".tex")
+ baseName=baseName.left(baseName.length()-4);
+ else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
+ baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
+
+ QCString title=ptitle.stripWhiteSpace();
+ pd=new PageDef(fileName,startLine,baseName,doc,title);
+
+ pd->setRefItems(sli);
+ pd->setLanguage(lang);
+
+ if (tagInfo)
+ {
+ pd->setReference(tagInfo->tagName);
+ pd->setFileName(tagInfo->fileName,TRUE);
+ }
+ else
+ {
+ pd->setFileName(convertNameToFile(pd->name(),FALSE,TRUE),FALSE);
+ }
+
+ //printf("Appending page `%s'\n",baseName.data());
+ Doxygen::pageSDict->append(baseName,pd);
+
+ if (gd) gd->addPage(pd);
+
+ if (!pd->title().isEmpty())
+ {
+ //outputList->writeTitle(pi->name,pi->title);
+
+ // a page name is a label as well!
+ QCString file;
+ if (gd)
+ {
+ file=gd->getOutputFileBase();
+ }
+ else
+ {
+ file=pd->getOutputFileBase();
+ }
+ SectionInfo *si = Doxygen::sectionDict->find(pd->name());
+ if (si)
+ {
+ if (si->lineNr != -1)
+ {
+ warn(file,-1,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName.data(),si->lineNr);
+ }
+ else
+ {
+ warn(file,-1,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName.data());
+ }
+ }
+ else
+ {
+ si=new SectionInfo(
+ file,-1,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference());
+ //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
+ // si->label.data(),si->definition?si->definition->name().data():"<none>",
+ // si->fileName.data());
+ //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data());
+ //printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data());
+ Doxygen::sectionDict->append(pd->name(),si);
+ }
+ }
+ }
+ return pd;
+}
+
+//----------------------------------------------------------------------------
+
+void addRefItem(const QList<ListItemInfo> *sli,
+ const char *key,
+ const char *prefix, const char *name,const char *title,const char *args)
+{
+ //printf("addRefItem(sli=%p,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",sli,key,prefix,name,title,args);
+ if (sli && key && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
+ {
+ QListIterator<ListItemInfo> slii(*sli);
+ ListItemInfo *lii;
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ RefList *refList = Doxygen::xrefLists->find(lii->type);
+ if (refList
+ &&
+ (
+ // either not a built-in list or the list is enabled
+ (lii->type!="todo" || Config_getBool("GENERATE_TODOLIST")) &&
+ (lii->type!="test" || Config_getBool("GENERATE_TESTLIST")) &&
+ (lii->type!="bug" || Config_getBool("GENERATE_BUGLIST")) &&
+ (lii->type!="deprecated" || Config_getBool("GENERATE_DEPRECATEDLIST"))
+ )
+ )
+ {
+ RefItem *item = refList->getRefItem(lii->itemId);
+ ASSERT(item!=0);
+
+ item->prefix = prefix;
+ item->name = name;
+ item->title = title;
+ item->args = args;
+
+ refList->insertIntoList(key,item);
+
+ }
+ }
+ }
+}
+
+bool recursivelyAddGroupListToTitle(OutputList &ol,Definition *d,bool root)
+{
+ GroupList *groups = d->partOfGroups();
+ if (groups) // write list of group to which this definition belongs
+ {
+ if (root)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString("<div class=\"ingroups\">");
+ }
+ GroupListIterator gli(*groups);
+ GroupDef *gd;
+ bool first=true;
+ for (gli.toFirst();(gd=gli.current());++gli)
+ {
+ if (recursivelyAddGroupListToTitle(ol, gd, FALSE))
+ {
+ ol.writeString(" » ");
+ }
+ if (!first) { ol.writeString(" | "); } else first=FALSE;
+ ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle());
+ }
+ if (root)
+ {
+ ol.writeString("</div>");
+ ol.popGeneratorState();
+ }
+ return true;
+ }
+ return false;
+}
+
+void addGroupListToTitle(OutputList &ol,Definition *d)
+{
+ recursivelyAddGroupListToTitle(ol,d,TRUE);
+}
+
+void filterLatexString(FTextStream &t,const char *str,
+ bool insideTabbing,bool insidePre,bool insideItem)
+{
+ if (str==0) return;
+ //printf("filterLatexString(%s)\n",str);
+ //if (strlen(str)<2) stackTrace();
+ const unsigned char *p=(const unsigned char *)str;
+ unsigned char c;
+ unsigned char pc='\0';
+ while (*p)
+ {
+ c=*p++;
+
+ if (insidePre)
+ {
+ switch(c)
+ {
+ case '\\': t << "\\(\\backslash\\)"; break;
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '_': t << "\\_"; break;
+ default:
+ t << (char)c;
+ }
+ }
+ else
+ {
+ switch(c)
+ {
+ case '#': t << "\\#"; break;
+ case '$': t << "\\$"; break;
+ case '%': t << "\\%"; break;
+ case '^': t << "$^\\wedge$"; break;
+ case '&': t << "\\&"; break;
+ case '*': t << "$\\ast$"; break;
+ case '_': if (!insideTabbing) t << "\\+";
+ t << "\\_";
+ if (!insideTabbing) t << "\\+";
+ break;
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '<': t << "$<$"; break;
+ case '>': t << "$>$"; break;
+ case '|': t << "$\\vert$"; break;
+ case '~': t << "$\\sim$"; break;
+ case '[': if (Config_getBool("PDF_HYPERLINKS") || insideItem)
+ t << "\\mbox{[}";
+ else
+ t << "[";
+ break;
+ case ']': if (pc=='[') t << "$\\,$";
+ if (Config_getBool("PDF_HYPERLINKS") || insideItem)
+ t << "\\mbox{]}";
+ else
+ t << "]";
+ break;
+ case '-': t << "-\\/";
+ break;
+ case '\\': t << "\\textbackslash{}";
+ break;
+ case '"': t << "\\char`\\\"{}";
+ break;
+
+ default:
+ //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
+ if (!insideTabbing &&
+ ((c>='A' && c<='Z' && pc!=' ' && pc!='\0') || (c==':' && pc!=':') || (pc=='.' && isId(c)))
+ )
+ {
+ t << "\\+";
+ }
+ t << (char)c;
+ }
+ }
+ pc = c;
+ }
+}
+
+
+QCString rtfFormatBmkStr(const char *name)
+{
+ static QCString g_nextTag( "AAAAAAAAAA" );
+ static QDict<QCString> g_tagDict( 5003 );
+
+ g_tagDict.setAutoDelete(TRUE);
+
+ // To overcome the 40-character tag limitation, we
+ // substitute a short arbitrary string for the name
+ // supplied, and keep track of the correspondence
+ // between names and strings.
+ QCString key( name );
+ QCString* tag = g_tagDict.find( key );
+ if ( !tag )
+ {
+ // This particular name has not yet been added
+ // to the list. Add it, associating it with the
+ // next tag value, and increment the next tag.
+ tag = new QCString( g_nextTag.copy() ); // Make sure to use a deep copy!
+ g_tagDict.insert( key, tag );
+
+ // This is the increment part
+ char* nxtTag = g_nextTag.data() + g_nextTag.length() - 1;
+ for ( unsigned int i = 0; i < g_nextTag.length(); ++i, --nxtTag )
+ {
+ if ( ( ++(*nxtTag) ) > 'Z' )
+ {
+ *nxtTag = 'A';
+ }
+ else
+ {
+ // Since there was no carry, we can stop now
+ break;
+ }
+ }
+ }
+
+ return *tag;
+}
+
+QCString stripExtension(const char *fName)
+{
+ QCString result=fName;
+ if (result.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
+ {
+ result=result.left(result.length()-Doxygen::htmlFileExtension.length());
+ }
+ return result;
+}
+
+
+void replaceNamespaceAliases(QCString &scope,int i)
+{
+ while (i>0)
+ {
+ QCString ns = scope.left(i);
+ QCString *s = Doxygen::namespaceAliasDict[ns];
+ if (s)
+ {
+ scope=*s+scope.right(scope.length()-i);
+ i=s->length();
+ }
+ if (i>0 && ns==scope.left(i)) break;
+ }
+}
+
+QCString stripPath(const char *s)
+{
+ QCString result=s;
+ int i=result.findRev('/');
+ if (i!=-1)
+ {
+ result=result.mid(i+1);
+ }
+ i=result.findRev('\\');
+ if (i!=-1)
+ {
+ result=result.mid(i+1);
+ }
+ return result;
+}
+
+/** returns \c TRUE iff string \a s contains word \a w */
+bool containsWord(const QCString &s,const QCString &word)
+{
+ static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
+ int p=0,i,l;
+ while ((i=wordExp.match(s,p,&l))!=-1)
+ {
+ if (s.mid(i,l)==word) return TRUE;
+ p=i+l;
+ }
+ return FALSE;
+}
+
+bool findAndRemoveWord(QCString &s,const QCString &word)
+{
+ static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
+ int p=0,i,l;
+ while ((i=wordExp.match(s,p,&l))!=-1)
+ {
+ if (s.mid(i,l)==word)
+ {
+ if (i>0 && isspace((uchar)s.at(i-1)))
+ i--,l++;
+ else if (i+l<(int)s.length() && isspace(s.at(i+l)))
+ l++;
+ s = s.left(i)+s.mid(i+l); // remove word + spacing
+ return TRUE;
+ }
+ p=i+l;
+ }
+ return FALSE;
+}
+
+/** Special version of QCString::stripWhiteSpace() that only strips
+ * completely blank lines.
+ * @param s the string to be stripped
+ * @param docLine the line number corresponding to the start of the
+ * string. This will be adjusted based on the number of lines stripped
+ * from the start.
+ * @returns The stripped string.
+ */
+QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
+{
+ const char *p = s.data();
+ if (p==0) return 0;
+
+ // search for leading empty lines
+ int i=0,li=-1,l=s.length();
+ char c;
+ while ((c=*p++))
+ {
+ if (c==' ' || c=='\t' || c=='\r') i++;
+ else if (c=='\n') i++,li=i,docLine++;
+ else break;
+ }
+
+ // search for trailing empty lines
+ int b=l-1,bi=-1;
+ p=s.data()+b;
+ while (b>=0)
+ {
+ c=*p; p--;
+ if (c==' ' || c=='\t' || c=='\r') b--;
+ else if (c=='\n') bi=b,b--;
+ else break;
+ }
+
+ // return whole string if no leading or trailing lines where found
+ if (li==-1 && bi==-1) return s;
+
+ // return substring
+ if (bi==-1) bi=l;
+ if (li==-1) li=0;
+ if (bi<=li) return 0; // only empty lines
+ return s.mid(li,bi-li);
+}
+
+#if 0
+void stringToSearchIndex(const QCString &docBaseUrl,const QCString &title,
+ const QCString &str,bool priority,const QCString &anchor)
+{
+ static bool searchEngine = Config_getBool("SEARCHENGINE");
+ if (searchEngine)
+ {
+ Doxygen::searchIndex->setCurrentDoc(title,docBaseUrl,anchor);
+ static QRegExp wordPattern("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
+ int i,p=0,l;
+ while ((i=wordPattern.match(str,p,&l))!=-1)
+ {
+ Doxygen::searchIndex->addWord(str.mid(i,l),priority);
+ p=i+l;
+ }
+ }
+}
+#endif
+
+//--------------------------------------------------------------------------
+
+static QDict<int> g_extLookup;
+
+static struct Lang2ExtMap
+{
+ const char *langName;
+ const char *parserName;
+ SrcLangExt parserId;
+}
+g_lang2extMap[] =
+{
+// language parser parser option
+ { "idl", "c", SrcLangExt_IDL },
+ { "java", "c", SrcLangExt_Java },
+ { "javascript", "c", SrcLangExt_JS },
+ { "csharp", "c", SrcLangExt_CSharp },
+ { "d", "c", SrcLangExt_D },
+ { "php", "c", SrcLangExt_PHP },
+ { "objective-c", "c", SrcLangExt_ObjC },
+ { "c", "c", SrcLangExt_Cpp },
+ { "c++", "c", SrcLangExt_Cpp },
+ { "python", "python", SrcLangExt_Python },
+ { "fortran", "fortran", SrcLangExt_Fortran },
+ { "fortranfree", "fortranfree", SrcLangExt_Fortran },
+ { "fortranfixed", "fortranfixed", SrcLangExt_Fortran },
+ { "vhdl", "vhdl", SrcLangExt_VHDL },
+ { "dbusxml", "dbusxml", SrcLangExt_XML },
+ { "tcl", "tcl", SrcLangExt_Tcl },
+ { "md", "md", SrcLangExt_Markdown },
+ { 0, 0, (SrcLangExt)0 }
+};
+
+bool updateLanguageMapping(const QCString &extension,const QCString &language)
+{
+ const Lang2ExtMap *p = g_lang2extMap;
+ QCString langName = language.lower();
+ while (p->langName)
+ {
+ if (langName==p->langName) break;
+ p++;
+ }
+ if (!p->langName) return FALSE;
+
+ // found the language
+ SrcLangExt parserId = p->parserId;
+ QCString extName = extension.lower();
+ if (extName.isEmpty()) return FALSE;
+ if (extName.at(0)!='.') extName.prepend(".");
+ if (g_extLookup.find(extension)!=0) // language was already register for this ext
+ {
+ g_extLookup.remove(extension);
+ }
+ //printf("registering extension %s\n",extName.data());
+ g_extLookup.insert(extName,new int(parserId));
+ if (!Doxygen::parserManager->registerExtension(extName,p->parserName))
+ {
+ err("Failed to assign extension %s to parser %s for language %s\n",
+ extName.data(),p->parserName,language.data());
+ }
+ else
+ {
+ //msg("Registered extension %s to language parser %s...\n",
+ // extName.data(),language.data());
+ }
+ return TRUE;
+}
+
+void initDefaultExtensionMapping()
+{
+ g_extLookup.setAutoDelete(TRUE);
+ // extension parser id
+ updateLanguageMapping(".dox", "c");
+ updateLanguageMapping(".txt", "c");
+ updateLanguageMapping(".doc", "c");
+ updateLanguageMapping(".c", "c");
+ updateLanguageMapping(".C", "c");
+ updateLanguageMapping(".cc", "c");
+ updateLanguageMapping(".CC", "c");
+ updateLanguageMapping(".cxx", "c");
+ updateLanguageMapping(".cpp", "c");
+ updateLanguageMapping(".c++", "c");
+ updateLanguageMapping(".ii", "c");
+ updateLanguageMapping(".ixx", "c");
+ updateLanguageMapping(".ipp", "c");
+ updateLanguageMapping(".i++", "c");
+ updateLanguageMapping(".inl", "c");
+ updateLanguageMapping(".h", "c");
+ updateLanguageMapping(".H", "c");
+ updateLanguageMapping(".hh", "c");
+ updateLanguageMapping(".HH", "c");
+ updateLanguageMapping(".hxx", "c");
+ updateLanguageMapping(".hpp", "c");
+ updateLanguageMapping(".h++", "c");
+ updateLanguageMapping(".idl", "idl");
+ updateLanguageMapping(".ddl", "idl");
+ updateLanguageMapping(".odl", "idl");
+ updateLanguageMapping(".java", "java");
+ updateLanguageMapping(".as", "javascript");
+ updateLanguageMapping(".js", "javascript");
+ updateLanguageMapping(".cs", "csharp");
+ updateLanguageMapping(".d", "d");
+ updateLanguageMapping(".php", "php");
+ updateLanguageMapping(".php4", "php");
+ updateLanguageMapping(".php5", "php");
+ updateLanguageMapping(".inc", "php");
+ updateLanguageMapping(".phtml", "php");
+ updateLanguageMapping(".m", "objective-c");
+ updateLanguageMapping(".M", "objective-c");
+ updateLanguageMapping(".mm", "objective-c");
+ updateLanguageMapping(".py", "python");
+ updateLanguageMapping(".f", "fortran");
+ updateLanguageMapping(".for", "fortran");
+ updateLanguageMapping(".f90", "fortran");
+ updateLanguageMapping(".vhd", "vhdl");
+ updateLanguageMapping(".vhdl", "vhdl");
+ updateLanguageMapping(".tcl", "tcl");
+ updateLanguageMapping(".ucf", "vhdl");
+ updateLanguageMapping(".qsf", "vhdl");
+ updateLanguageMapping(".md", "md");
+ updateLanguageMapping(".markdown", "md");
+
+ //updateLanguageMapping(".xml", "dbusxml");
+}
+
+SrcLangExt getLanguageFromFileName(const QCString fileName)
+{
+ int i = fileName.findRev('.');
+ if (i!=-1) // name has an extension
+ {
+ QCString extStr=fileName.right(fileName.length()-i).lower();
+ if (!extStr.isEmpty()) // non-empty extension
+ {
+ int *pVal=g_extLookup.find(extStr);
+ if (pVal) // listed extension
+ {
+ //printf("getLanguageFromFileName(%s)=%x\n",extStr.data(),*pVal);
+ return (SrcLangExt)*pVal;
+ }
+ }
+ }
+ //printf("getLanguageFromFileName(%s) not found!\n",fileName.data());
+ return SrcLangExt_Cpp; // not listed => assume C-ish language.
+}
+
+//--------------------------------------------------------------------------
+
+MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope,
+ const char *n)
+{
+ if (scope==0 ||
+ (scope->definitionType()!=Definition::TypeClass &&
+ scope->definitionType()!=Definition::TypeNamespace
+ )
+ )
+ {
+ scope=Doxygen::globalScope;
+ }
+
+ QCString name = n;
+ if (name.isEmpty())
+ return 0; // no name was given
+
+ DefinitionIntf *di = Doxygen::symbolMap->find(name);
+ if (di==0)
+ return 0; // could not find any matching symbols
+
+ // mostly copied from getResolvedClassRec()
+ QCString explicitScopePart;
+ int qualifierIndex = computeQualifiedIndex(name);
+ if (qualifierIndex!=-1)
+ {
+ explicitScopePart = name.left(qualifierIndex);
+ replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
+ name = name.mid(qualifierIndex+2);
+ }
+ //printf("explicitScopePart=%s\n",explicitScopePart.data());
+
+ int minDistance = 10000;
+ MemberDef *bestMatch = 0;
+
+ if (di->definitionType()==DefinitionIntf::TypeSymbolList)
+ {
+ //printf("multiple matches!\n");
+ // find the closest closest matching definition
+ DefinitionListIterator dli(*(DefinitionList*)di);
+ Definition *d;
+ for (dli.toFirst();(d=dli.current());++dli)
+ {
+ if (d->definitionType()==Definition::TypeMember)
+ {
+ g_visitedNamespaces.clear();
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ if (distance!=-1 && distance<minDistance)
+ {
+ minDistance = distance;
+ bestMatch = (MemberDef *)d;
+ //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
+ }
+ }
+ }
+ }
+ else if (di->definitionType()==Definition::TypeMember)
+ {
+ //printf("unique match!\n");
+ Definition *d = (Definition *)di;
+ g_visitedNamespaces.clear();
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ if (distance!=-1 && distance<minDistance)
+ {
+ minDistance = distance;
+ bestMatch = (MemberDef *)d;
+ //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
+ }
+ }
+ return bestMatch;
+}
+
+/*! Returns true iff the given name string appears to be a typedef in scope. */
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n)
+{
+ MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
+
+ if (bestMatch && bestMatch->isTypedef())
+ return TRUE; // closest matching symbol is a typedef
+ else
+ return FALSE;
+}
+
+const char *writeUtf8Char(FTextStream &t,const char *s)
+{
+ char c=*s++;
+ t << c;
+ if (c<0) // multibyte character
+ {
+ if (((uchar)c&0xE0)==0xC0)
+ {
+ t << *s++; // 11xx.xxxx: >=2 byte character
+ }
+ if (((uchar)c&0xF0)==0xE0)
+ {
+ t << *s++; // 111x.xxxx: >=3 byte character
+ }
+ if (((uchar)c&0xF8)==0xF0)
+ {
+ t << *s++; // 1111.xxxx: >=4 byte character
+ }
+ if (((uchar)c&0xFC)==0xF8)
+ {
+ t << *s++; // 1111.1xxx: >=5 byte character
+ }
+ if (((uchar)c&0xFE)==0xFC)
+ {
+ t << *s++; // 1111.1xxx: 6 byte character
+ }
+ }
+ return s;
+}
+
+int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos)
+{
+ int bytes=1;
+ if (startPos>=len) return len;
+ char c = utf8Str[startPos];
+ if (c<0) // multibyte utf-8 character
+ {
+ if (((uchar)c&0xE0)==0xC0)
+ {
+ bytes++; // 11xx.xxxx: >=2 byte character
+ }
+ if (((uchar)c&0xF0)==0xE0)
+ {
+ bytes++; // 111x.xxxx: >=3 byte character
+ }
+ if (((uchar)c&0xF8)==0xF0)
+ {
+ bytes++; // 1111.xxxx: >=4 byte character
+ }
+ if (((uchar)c&0xFC)==0xF8)
+ {
+ bytes++; // 1111.1xxx: >=5 byte character
+ }
+ if (((uchar)c&0xFE)==0xFC)
+ {
+ bytes++; // 1111.1xxx: 6 byte character
+ }
+ }
+ else if (c=='&') // skip over character entities
+ {
+ static QRegExp re1("&#[0-9]+;"); // numerical entity
+ static QRegExp re2("&[A-Z_a-z]+;"); // named entity
+ int l1,l2;
+ int i1 = re1.match(utf8Str,startPos,&l1);
+ int i2 = re2.match(utf8Str,startPos,&l2);
+ if (i1!=-1)
+ {
+ bytes=l1;
+ }
+ else if (i2!=-1)
+ {
+ bytes=l2;
+ }
+ }
+ return startPos+bytes;
+}
+
+QCString parseCommentAsText(const Definition *scope,const MemberDef *md,
+ const QCString &doc,const QCString &fileName,int lineNr)
+{
+ QGString s;
+ if (doc.isEmpty()) return s.data();
+ FTextStream t(&s);
+ DocNode *root = validatingParseDoc(fileName,lineNr,
+ (Definition*)scope,(MemberDef*)md,doc,FALSE,FALSE);
+ TextDocVisitor *visitor = new TextDocVisitor(t);
+ root->accept(visitor);
+ delete visitor;
+ delete root;
+ QCString result = convertCharEntitiesToUTF8(s.data());
+ int i=0;
+ int charCnt=0;
+ int l=result.length();
+ bool addEllipsis=FALSE;
+ while ((i=nextUtf8CharPosition(result,l,i))<l)
+ {
+ charCnt++;
+ if (charCnt>=80) break;
+ }
+ if (charCnt>=80) // try to truncate the string
+ {
+ while ((i=nextUtf8CharPosition(result,l,i))<l && charCnt<100)
+ {
+ charCnt++;
+ if (result.at(i)>=0 && isspace(result.at(i)))
+ {
+ addEllipsis=TRUE;
+ }
+ else if (result.at(i)==',' ||
+ result.at(i)=='.' ||
+ result.at(i)=='?')
+ {
+ break;
+ }
+ }
+ }
+ if (addEllipsis || charCnt==100) result=result.left(i)+"...";
+ return result.data();
+}
+
+//--------------------------------------------------------------------------------------
+
+static QDict<void> aliasesProcessed;
+
+static QCString expandAliasRec(const QCString s,bool allowRecursion=FALSE);
+
+struct Marker
+{
+ Marker(int p, int n,int s) : pos(p),number(n),size(s) {}
+ int pos; // position in the string
+ int number; // argument number
+ int size; // size of the marker
+};
+
+/** For a string \a s that starts with a command name, returns the character
+ * offset within that string representing the first character after the
+ * command. For an alias with argument, this is the offset to the
+ * character just after the argument list.
+ *
+ * Examples:
+ * - s=="a b" returns 1
+ * - s=="a{2,3} b" returns 6
+ * = s=="#" returns 0
+ */
+static int findEndOfCommand(const char *s)
+{
+ const char *p = s;
+ char c;
+ int i=0;
+ if (p)
+ {
+ while ((c=*p) && isId(c)) p++;
+ if (c=='{')
+ {
+ QCString args = extractAliasArgs(p,0);
+ i+=args.length();
+ }
+ i+=p-s;
+ }
+ return i;
+}
+
+/** Replaces the markers in an alias definition \a aliasValue
+ * with the corresponding values found in the comma separated argument
+ * list \a argList and the returns the result after recursive alias expansion.
+ */
+static QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList)
+{
+ //printf("----- replaceAliasArguments(val=[%s],args=[%s])\n",aliasValue.data(),argList.data());
+
+ // first make a list of arguments from the comma separated argument list
+ QList<QCString> args;
+ args.setAutoDelete(TRUE);
+ int i,l=(int)argList.length();
+ int s=0;
+ for (i=0;i<l;i++)
+ {
+ char c = argList.at(i);
+ if (c==',' && (i==0 || argList.at(i-1)!='\\'))
+ {
+ args.append(new QCString(argList.mid(s,i-s)));
+ s=i+1; // start of next argument
+ }
+ else if (c=='@' || c=='\\')
+ {
+ // check if this is the start of another aliased command (see bug704172)
+ i+=findEndOfCommand(argList.data()+i+1);
+ }
+ }
+ if (l>s) args.append(new QCString(argList.right(l-s)));
+ //printf("found %d arguments\n",args.count());
+
+ // next we look for the positions of the markers and add them to a list
+ QList<Marker> markerList;
+ markerList.setAutoDelete(TRUE);
+ l = aliasValue.length();
+ int markerStart=0;
+ int markerEnd=0;
+ for (i=0;i<l;i++)
+ {
+ if (markerStart==0 && aliasValue.at(i)=='\\') // start of a \xx marker
+ {
+ markerStart=i+1;
+ }
+ else if (markerStart>0 && aliasValue.at(i)>='0' && aliasValue.at(i)<='9')
+ {
+ // read digit that make up the marker number
+ markerEnd=i+1;
+ }
+ else
+ {
+ if (markerStart>0 && markerEnd>markerStart) // end of marker
+ {
+ int markerLen = markerEnd-markerStart;
+ markerList.append(new Marker(markerStart-1, // include backslash
+ atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
+ //printf("found marker at %d with len %d and number %d\n",
+ // markerStart-1,markerLen+1,atoi(aliasValue.mid(markerStart,markerLen)));
+ }
+ markerStart=0; // outside marker
+ markerEnd=0;
+ }
+ }
+ if (markerStart>0)
+ {
+ markerEnd=l;
+ }
+ if (markerStart>0 && markerEnd>markerStart)
+ {
+ int markerLen = markerEnd-markerStart;
+ markerList.append(new Marker(markerStart-1, // include backslash
+ atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
+ //printf("found marker at %d with len %d and number %d\n",
+ // markerStart-1,markerLen+1,atoi(aliasValue.mid(markerStart,markerLen)));
+ }
+
+ // then we replace the markers with the corresponding arguments in one pass
+ QCString result;
+ int p=0;
+ for (i=0;i<(int)markerList.count();i++)
+ {
+ Marker *m = markerList.at(i);
+ result+=aliasValue.mid(p,m->pos-p);
+ //printf("part before marker %d: '%s'\n",i,aliasValue.mid(p,m->pos-p).data());
+ if (m->number>0 && m->number<=(int)args.count()) // valid number
+ {
+ result+=expandAliasRec(*args.at(m->number-1),TRUE);
+ //printf("marker index=%d pos=%d number=%d size=%d replacement %s\n",i,m->pos,m->number,m->size,
+ // args.at(m->number-1)->data());
+ }
+ p=m->pos+m->size; // continue after the marker
+ }
+ result+=aliasValue.right(l-p); // append remainder
+ //printf("string after replacement of markers: '%s'\n",result.data());
+
+ // expand the result again
+ result = substitute(result,"\\{","{");
+ result = substitute(result,"\\}","}");
+ result = expandAliasRec(substitute(result,"\\,",","));
+
+ return result;
+}
+
+static QCString escapeCommas(const QCString &s)
+{
+ QGString result;
+ const char *p = s.data();
+ char c,pc=0;
+ while ((c=*p++))
+ {
+ if (c==',' && pc!='\\')
+ {
+ result+="\\,";
+ }
+ else
+ {
+ result+=c;
+ }
+ pc=c;
+ }
+ result+='\0';
+ //printf("escapeCommas: '%s'->'%s'\n",s.data(),result.data());
+ return result.data();
+}
+
+static QCString expandAliasRec(const QCString s,bool allowRecursion)
+{
+ QCString result;
+ static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
+ QCString value=s;
+ int i,p=0,l;
+ while ((i=cmdPat.match(value,p,&l))!=-1)
+ {
+ result+=value.mid(p,i-p);
+ QCString args = extractAliasArgs(value,i+l);
+ bool hasArgs = !args.isEmpty(); // found directly after command
+ int argsLen = args.length();
+ QCString cmd = value.mid(i+1,l-1);
+ QCString cmdNoArgs = cmd;
+ int numArgs=0;
+ if (hasArgs)
+ {
+ numArgs = countAliasArguments(args);
+ cmd += QCString().sprintf("{%d}",numArgs); // alias name + {n}
+ }
+ QCString *aliasText=Doxygen::aliasDict.find(cmd);
+ if (numArgs>1 && aliasText==0)
+ { // in case there is no command with numArgs parameters, but there is a command with 1 parameter,
+ // we also accept all text as the argument of that command (so you don't have to escape commas)
+ aliasText=Doxygen::aliasDict.find(cmdNoArgs+"{1}");
+ if (aliasText)
+ {
+ cmd = cmdNoArgs+"{1}";
+ args = escapeCommas(args); // escape , so that everything is seen as one argument
+ }
+ }
+ //printf("Found command s='%s' cmd='%s' numArgs=%d args='%s' aliasText=%s\n",
+ // s.data(),cmd.data(),numArgs,args.data(),aliasText?aliasText->data():"<none>");
+ if ((allowRecursion || aliasesProcessed.find(cmd)==0) && aliasText) // expand the alias
+ {
+ //printf("is an alias!\n");
+ if (!allowRecursion) aliasesProcessed.insert(cmd,(void *)0x8);
+ QCString val = *aliasText;
+ if (hasArgs)
+ {
+ val = replaceAliasArguments(val,args);
+ //printf("replace '%s'->'%s' args='%s'\n",
+ // aliasText->data(),val.data(),args.data());
+ }
+ result+=expandAliasRec(val);
+ if (!allowRecursion) aliasesProcessed.remove(cmd);
+ p=i+l;
+ if (hasArgs) p+=argsLen+2;
+ }
+ else // command is not an alias
+ {
+ //printf("not an alias!\n");
+ result+=value.mid(i,l);
+ p=i+l;
+ }
+ }
+ result+=value.right(value.length()-p);
+
+ //printf("expandAliases '%s'->'%s'\n",s.data(),result.data());
+ return result;
+}
+
+
+int countAliasArguments(const QCString argList)
+{
+ int count=1;
+ int l = argList.length();
+ int i;
+ for (i=0;i<l;i++)
+ {
+ char c = argList.at(i);
+ if (c==',' && (i==0 || argList.at(i-1)!='\\')) count++;
+ else if (c=='@' || c=='\\')
+ {
+ // check if this is the start of another aliased command (see bug704172)
+ i+=findEndOfCommand(argList.data()+i+1);
+ }
+ }
+ //printf("countAliasArguments=%d\n",count);
+ return count;
+}
+
+QCString extractAliasArgs(const QCString &args,int pos)
+{
+ int i;
+ int bc=0;
+ char prevChar=0;
+ if (args.at(pos)=='{') // alias has argument
+ {
+ for (i=pos;i<(int)args.length();i++)
+ {
+ if (prevChar!='\\')
+ {
+ if (args.at(i)=='{') bc++;
+ if (args.at(i)=='}') bc--;
+ prevChar=args.at(i);
+ }
+ else
+ {
+ prevChar=0;
+ }
+
+ if (bc==0)
+ {
+ //printf("extractAliasArgs('%s')->'%s'\n",args.data(),args.mid(pos+1,i-pos-1).data());
+ return args.mid(pos+1,i-pos-1);
+ }
+ }
+ }
+ return "";
+}
+
+QCString resolveAliasCmd(const QCString aliasCmd)
+{
+ QCString result;
+ aliasesProcessed.clear();
+ //printf("Expanding: '%s'\n",aliasCmd.data());
+ result = expandAliasRec(aliasCmd);
+ //printf("Expanding result: '%s'->'%s'\n",aliasCmd.data(),result.data());
+ return result;
+}
+
+QCString expandAlias(const QCString &aliasName,const QCString &aliasValue)
+{
+ QCString result;
+ aliasesProcessed.clear();
+ // avoid expanding this command recursively
+ aliasesProcessed.insert(aliasName,(void *)0x8);
+ // expand embedded commands
+ //printf("Expanding: '%s'->'%s'\n",aliasName.data(),aliasValue.data());
+ result = expandAliasRec(aliasValue);
+ //printf("Expanding result: '%s'->'%s'\n",aliasName.data(),result.data());
+ return result;
+}
+
+void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al)
+{
+ if (al==0) return;
+ ol.startConstraintList(theTranslator->trTypeConstraints());
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ ol.startConstraintParam();
+ ol.parseText(a->name);
+ ol.endConstraintParam();
+ ol.startConstraintType();
+ linkifyText(TextGeneratorOLImpl(ol),d,0,0,a->type);
+ ol.endConstraintType();
+ ol.startConstraintDocs();
+ ol.generateDoc(d->docFile(),d->docLine(),d,0,a->docs,TRUE,FALSE);
+ ol.endConstraintDocs();
+ }
+ ol.endConstraintList();
+}
+
+//----------------------------------------------------------------------------
+
+void stackTrace()
+{
+#ifdef TRACINGSUPPORT
+ void *backtraceFrames[128];
+ int frameCount = backtrace(backtraceFrames, 128);
+ static char cmd[40960];
+ char *p = cmd;
+ p += sprintf(p,"/usr/bin/atos -p %d ", (int)getpid());
+ for (int x = 0; x < frameCount; x++)
+ {
+ p += sprintf(p,"%p ", backtraceFrames[x]);
+ }
+ fprintf(stderr,"========== STACKTRACE START ==============\n");
+ if (FILE *fp = popen(cmd, "r"))
+ {
+ char resBuf[512];
+ while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
+ {
+ fwrite(resBuf, 1, len, stderr);
+ }
+ pclose(fp);
+ }
+ fprintf(stderr,"============ STACKTRACE END ==============\n");
+ //fprintf(stderr,"%s\n", frameStrings[x]);
+#endif
+}
+
+static int transcodeCharacterBuffer(const char *fileName,BufStr &srcBuf,int size,
+ const char *inputEncoding,const char *outputEncoding)
+{
+ if (inputEncoding==0 || outputEncoding==0) return size;
+ if (qstricmp(inputEncoding,outputEncoding)==0) return size;
+ void *cd = portable_iconv_open(outputEncoding,inputEncoding);
+ if (cd==(void *)(-1))
+ {
+ err("unsupported character conversion: '%s'->'%s': %s\n"
+ "Check the INPUT_ENCODING setting in the config file!\n",
+ inputEncoding,outputEncoding,strerror(errno));
+ exit(1);
+ }
+ int tmpBufSize=size*4+1;
+ BufStr tmpBuf(tmpBufSize);
+ size_t iLeft=size;
+ size_t oLeft=tmpBufSize;
+ char *srcPtr = srcBuf.data();
+ char *dstPtr = tmpBuf.data();
+ uint newSize=0;
+ if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
+ {
+ newSize = tmpBufSize-(int)oLeft;
+ srcBuf.shrink(newSize);
+ strncpy(srcBuf.data(),tmpBuf.data(),newSize);
+ //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,srcBuf.data());
+ }
+ else
+ {
+ err("%s: failed to translate characters from %s to %s: check INPUT_ENCODING\n",
+ fileName,inputEncoding,outputEncoding);
+ exit(1);
+ }
+ portable_iconv_close(cd);
+ return newSize;
+}
+
+//! read a file name \a fileName and optionally filter and transcode it
+bool readInputFile(const char *fileName,BufStr &inBuf,bool filter,bool isSourceCode)
+{
+ // try to open file
+ int size=0;
+ //uint oldPos = dest.curPos();
+ //printf(".......oldPos=%d\n",oldPos);
+
+ QFileInfo fi(fileName);
+ if (!fi.exists()) return FALSE;
+ QCString filterName = getFileFilter(fileName,isSourceCode);
+ if (filterName.isEmpty() || !filter)
+ {
+ QFile f(fileName);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("could not open file %s\n",fileName);
+ return FALSE;
+ }
+ size=fi.size();
+ // read the file
+ inBuf.skip(size);
+ if (f.readBlock(inBuf.data()/*+oldPos*/,size)!=size)
+ {
+ err("problems while reading file %s\n",fileName);
+ return FALSE;
+ }
+ }
+ else
+ {
+ QCString cmd=filterName+" \""+fileName+"\"";
+ Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
+ FILE *f=portable_popen(cmd,"r");
+ if (!f)
+ {
+ err("could not execute filter %s\n",filterName.data());
+ return FALSE;
+ }
+ const int bufSize=1024;
+ char buf[bufSize];
+ int numRead;
+ while ((numRead=(int)fread(buf,1,bufSize,f))>0)
+ {
+ //printf(">>>>>>>>Reading %d bytes\n",numRead);
+ inBuf.addArray(buf,numRead),size+=numRead;
+ }
+ portable_pclose(f);
+ inBuf.at(inBuf.curPos()) ='\0';
+ Debug::print(Debug::FilterOutput, 0, "Filter output\n");
+ Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",inBuf.data());
+ }
+
+ int start=0;
+ if (size>=2 &&
+ ((inBuf.at(0)==-1 && inBuf.at(1)==-2) || // Litte endian BOM
+ (inBuf.at(0)==-2 && inBuf.at(1)==-1) // big endian BOM
+ )
+ ) // UCS-2 encoded file
+ {
+ transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(),
+ "UCS-2","UTF-8");
+ }
+ else if (size>=3 &&
+ (uchar)inBuf.at(0)==0xEF &&
+ (uchar)inBuf.at(1)==0xBB &&
+ (uchar)inBuf.at(2)==0xBF
+ ) // UTF-8 encoded file
+ {
+ inBuf.dropFromStart(3); // remove UTF-8 BOM: no translation needed
+ }
+ else // transcode according to the INPUT_ENCODING setting
+ {
+ // do character transcoding if needed.
+ transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(),
+ Config_getString("INPUT_ENCODING"),"UTF-8");
+ }
+
+ //inBuf.addChar('\n'); /* to prevent problems under Windows ? */
+
+ // and translate CR's
+ size=inBuf.curPos()-start;
+ int newSize=filterCRLF(inBuf.data()+start,size);
+ //printf("filter char at %p size=%d newSize=%d\n",dest.data()+oldPos,size,newSize);
+ if (newSize!=size) // we removed chars
+ {
+ inBuf.shrink(newSize); // resize the array
+ //printf(".......resizing from %d to %d result=[%s]\n",oldPos+size,oldPos+newSize,dest.data());
+ }
+ inBuf.addChar(0);
+ return TRUE;
+}
+
+// Replace %word by word in title
+QCString filterTitle(const QCString &title)
+{
+ QCString tf;
+ static QRegExp re("%[A-Z_a-z]");
+ int p=0,i,l;
+ while ((i=re.match(title,p,&l))!=-1)
+ {
+ tf+=title.mid(p,i-p);
+ tf+=title.mid(i+1,l-1); // skip %
+ p=i+l;
+ }
+ tf+=title.right(title.length()-p);
+ return tf;
+}
+
+//----------------------------------------------------------------------------
+// returns TRUE if the name of the file represented by `fi' matches
+// one of the file patterns in the `patList' list.
+
+bool patternMatch(const QFileInfo &fi,const QStrList *patList)
+{
+ bool found=FALSE;
+ if (patList)
+ {
+ QStrListIterator it(*patList);
+ QCString pattern;
+
+ QCString fn = fi.fileName().data();
+ QCString fp = fi.filePath().data();
+ QCString afp= fi.absFilePath().data();
+
+ for (it.toFirst();(pattern=it.current());++it)
+ {
+ if (!pattern.isEmpty())
+ {
+ int i=pattern.find('=');
+ if (i!=-1) pattern=pattern.left(i); // strip of the extension specific filter name
+
+#if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
+ QRegExp re(pattern,FALSE,TRUE); // case insensitive match
+#else // unix
+ QRegExp re(pattern,TRUE,TRUE); // case sensitive match
+#endif
+ found = re.match(fn)!=-1 ||
+ re.match(fp)!=-1 ||
+ re.match(afp)!=-1;
+ if (found) break;
+ //printf("Matching `%s' against pattern `%s' found=%d\n",
+ // fi->fileName().data(),pattern.data(),found);
+ }
+ }
+ }
+ return found;
+}
+
+#if 0 // move to HtmlGenerator::writeSummaryLink
+void writeSummaryLink(OutputList &ol,const char *label,const char *title,
+ bool &first,const char *file)
+{
+ if (first)
+ {
+ ol.writeString(" <div class=\"summary\">\n");
+ first=FALSE;
+ }
+ else
+ {
+ ol.writeString(" |\n");
+ }
+ if (file)
+ {
+ ol.writeString("<a href=\"");
+ ol.writeString(file);
+ ol.writeString(Doxygen::htmlFileExtension);
+ }
+ else
+ {
+ ol.writeString("<a href=\"#");
+ ol.writeString(label);
+ }
+ ol.writeString("\">");
+ ol.writeString(title);
+ ol.writeString("</a>");
+}
+#endif
+
+QCString externalLinkTarget()
+{
+ static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW");
+ if (extLinksInWindow) return "target=\"_blank\" "; else return "";
+}
+
+QCString externalRef(const QCString &relPath,const QCString &ref,bool href)
+{
+ QCString result;
+ if (!ref.isEmpty())
+ {
+ QCString *dest = Doxygen::tagDestinationDict[ref];
+ if (dest)
+ {
+ result = *dest;
+ int l = result.length();
+ if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
+ { // relative path -> prepend relPath.
+ result.prepend(relPath);
+ }
+ if (!href) result.prepend("doxygen=\""+ref+":");
+ if (l>0 && result.at(l-1)!='/') result+='/';
+ if (!href) result.append("\" ");
+ }
+ }
+ else
+ {
+ result = relPath;
+ }
+ return result;
+}
+
+/** Writes the intensity only bitmap representated by \a data as an image to
+ * directory \a dir using the colors defined by HTML_COLORSTYLE_*.
+ */
+void writeColoredImgData(const char *dir,ColoredImgDataItem data[])
+{
+ static int hue = Config_getInt("HTML_COLORSTYLE_HUE");
+ static int sat = Config_getInt("HTML_COLORSTYLE_SAT");
+ static int gamma = Config_getInt("HTML_COLORSTYLE_GAMMA");
+ while (data->name)
+ {
+ QCString fileName;
+ fileName=(QCString)dir+"/"+data->name;
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ ColoredImage img(data->width,data->height,data->content,data->alpha,
+ sat,hue,gamma);
+ img.save(fileName);
+ }
+ else
+ {
+ fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
+ }
+ Doxygen::indexList->addImageFile(data->name);
+ data++;
+ }
+}
+
+/** Replaces any markers of the form \#\#AA in input string \a str
+ * by new markers of the form \#AABBCC, where \#AABBCC represents a
+ * valid color, based on the intensity represented by hex number AA
+ * and the current HTML_COLORSTYLE_* settings.
+ */
+QCString replaceColorMarkers(const char *str)
+{
+ QCString result;
+ QCString s=str;
+ if (s.isEmpty()) return result;
+ static QRegExp re("##[0-9A-Fa-f][0-9A-Fa-f]");
+ static const char hex[] = "0123456789ABCDEF";
+ static int hue = Config_getInt("HTML_COLORSTYLE_HUE");
+ static int sat = Config_getInt("HTML_COLORSTYLE_SAT");
+ static int gamma = Config_getInt("HTML_COLORSTYLE_GAMMA");
+ int i,l,sl=s.length(),p=0;
+ while ((i=re.match(s,p,&l))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ QCString lumStr = s.mid(i+2,l-2);
+#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
+ ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
+ ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
+
+ double r,g,b;
+ int red,green,blue;
+ int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
+ ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
+ pow(level/255.0,gamma/100.0),&r,&g,&b);
+ red = (int)(r*255.0);
+ green = (int)(g*255.0);
+ blue = (int)(b*255.0);
+ char colStr[8];
+ colStr[0]='#';
+ colStr[1]=hex[red>>4];
+ colStr[2]=hex[red&0xf];
+ colStr[3]=hex[green>>4];
+ colStr[4]=hex[green&0xf];
+ colStr[5]=hex[blue>>4];
+ colStr[6]=hex[blue&0xf];
+ colStr[7]=0;
+ //printf("replacing %s->%s (level=%d)\n",lumStr.data(),colStr,level);
+ result+=colStr;
+ p=i+l;
+ }
+ result+=s.right(sl-p);
+ return result;
+}
+
+/** Copies the contents of file with name \a src to the newly created
+ * file with name \a dest. Returns TRUE if successful.
+ */
+bool copyFile(const QCString &src,const QCString &dest)
+{
+ QFile sf(src);
+ if (sf.open(IO_ReadOnly))
+ {
+ QFileInfo fi(src);
+ QFile df(dest);
+ if (df.open(IO_WriteOnly))
+ {
+ char *buffer = new char[fi.size()];
+ sf.readBlock(buffer,fi.size());
+ df.writeBlock(buffer,fi.size());
+ df.flush();
+ delete[] buffer;
+ }
+ else
+ {
+ err("could not write to file %s\n",dest.data());
+ return FALSE;
+ }
+ }
+ else
+ {
+ err("could not open user specified file %s\n",src.data());
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** Returns the section of text, in between a pair of markers.
+ * Full lines are returned, excluding the lines on which the markers appear.
+ */
+QCString extractBlock(const QCString text,const QCString marker)
+{
+ QCString result;
+ int p=0,i;
+ bool found=FALSE;
+
+ // find the character positions of the markers
+ int m1 = text.find(marker);
+ if (m1==-1) return result;
+ int m2 = text.find(marker,m1+marker.length());
+ if (m2==-1) return result;
+
+ // find start and end line positions for the markers
+ int l1=-1,l2=-1;
+ while (!found && (i=text.find('\n',p))!=-1)
+ {
+ found = (p<=m1 && m1<i); // found the line with the start marker
+ p=i+1;
+ }
+ l1=p;
+ int lp=i;
+ if (found)
+ {
+ while ((i=text.find('\n',p))!=-1)
+ {
+ if (p<=m2 && m2<i) // found the line with the end marker
+ {
+ l2=p;
+ break;
+ }
+ p=i+1;
+ lp=i;
+ }
+ }
+ if (l2==-1) // marker at last line without newline (see bug706874)
+ {
+ l2=lp;
+ }
+ //printf("text=[%s]\n",text.mid(l1,l2-l1).data());
+ return l2>l1 ? text.mid(l1,l2-l1) : QCString();
+}
+
+/** Returns a string representation of \a lang. */
+QCString langToString(SrcLangExt lang)
+{
+ switch(lang)
+ {
+ case SrcLangExt_Unknown: return "Unknown";
+ case SrcLangExt_IDL: return "IDL";
+ case SrcLangExt_Java: return "Java";
+ case SrcLangExt_CSharp: return "C#";
+ case SrcLangExt_D: return "D";
+ case SrcLangExt_PHP: return "PHP";
+ case SrcLangExt_ObjC: return "Objective-C";
+ case SrcLangExt_Cpp: return "C++";
+ case SrcLangExt_JS: return "Javascript";
+ case SrcLangExt_Python: return "Python";
+ case SrcLangExt_Fortran: return "Fortran";
+ case SrcLangExt_VHDL: return "VHDL";
+ case SrcLangExt_XML: return "XML";
+ case SrcLangExt_Tcl: return "Tcl";
+ case SrcLangExt_Markdown: return "Markdown";
+ }
+ return "Unknown";
+}
+
+/** Returns the scope separator to use given the programming language \a lang */
+QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope)
+{
+ if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp || lang==SrcLangExt_VHDL || lang==SrcLangExt_Python)
+ {
+ return ".";
+ }
+ else if (lang==SrcLangExt_PHP && !classScope)
+ {
+ return "\\";
+ }
+ else
+ {
+ return "::";
+ }
+}
+
+/** Corrects URL \a url according to the relative path \a relPath.
+ * Returns the corrected URL. For absolute URLs no correction will be done.
+ */
+QCString correctURL(const QCString &url,const QCString &relPath)
+{
+ QCString result = url;
+ if (!relPath.isEmpty() &&
+ url.left(5)!="http:" && url.left(6)!="https:" &&
+ url.left(4)!="ftp:" && url.left(5)!="file:")
+ {
+ result.prepend(relPath);
+ }
+ return result;
+}
+
+//---------------------------------------------------------------------------
+
+bool protectionLevelVisible(Protection prot)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ static bool extractPackage = Config_getBool("EXTRACT_PACKAGE");
+
+ return (prot!=Private && prot!=Package) ||
+ (prot==Private && extractPrivate) ||
+ (prot==Package && extractPackage);
+}
+
+//---------------------------------------------------------------------------
+
+QCString stripIndentation(const QCString &s)
+{
+ if (s.isEmpty()) return s; // empty string -> we're done
+
+ //printf("stripIndentation:\n%s\n------\n",s.data());
+ // compute minimum indentation over all lines
+ const char *p=s.data();
+ char c;
+ int indent=0;
+ int minIndent=1000000; // "infinite"
+ bool searchIndent=TRUE;
+ static int tabSize=Config_getInt("TAB_SIZE");
+ while ((c=*p++))
+ {
+ if (c=='\t') indent+=tabSize - (indent%tabSize);
+ else if (c=='\n') indent=0,searchIndent=TRUE;
+ else if (c==' ') indent++;
+ else if (searchIndent)
+ {
+ searchIndent=FALSE;
+ if (indent<minIndent) minIndent=indent;
+ }
+ }
+
+ // no indent to remove -> we're done
+ if (minIndent==0) return s;
+
+ // remove minimum indentation for each line
+ QGString result;
+ p=s.data();
+ indent=0;
+ while ((c=*p++))
+ {
+ if (c=='\n') // start of new line
+ {
+ indent=0;
+ result+=c;
+ }
+ else if (indent<minIndent) // skip until we reach minIndent
+ {
+ if (c=='\t')
+ {
+ int newIndent = indent+tabSize-(indent%tabSize);
+ int i=newIndent;
+ while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
+ {
+ result+=' ';
+ i--;
+ }
+ indent=newIndent;
+ }
+ else // space
+ {
+ indent++;
+ }
+ }
+ else // copy anything until the end of the line
+ {
+ result+=c;
+ }
+ }
+
+ result+='\0';
+ return result.data();
+}
+
+
+bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile)
+{
+ static bool allExternals = Config_getBool("ALLEXTERNALS");
+ bool isDocFile = fd->isDocumentationFile();
+ genSourceFile = !isDocFile && fd->generateSourceFile();
+ return ( ((allExternals && fd->isLinkable()) ||
+ fd->isLinkableInProject()
+ ) &&
+ !isDocFile
+ );
+}
+
+void addDocCrossReference(MemberDef *src,MemberDef *dst)
+{
+ static bool referencedByRelation = Config_getBool("REFERENCED_BY_RELATION");
+ static bool referencesRelation = Config_getBool("REFERENCES_RELATION");
+ static bool callerGraph = Config_getBool("CALLER_GRAPH");
+ static bool callGraph = Config_getBool("CALL_GRAPH");
+
+ //printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data());
+ if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types
+ if ((referencedByRelation || callerGraph || dst->hasCallerGraph()) &&
+ src->showInCallGraph()
+ )
+ {
+ dst->addSourceReferencedBy(src);
+ MemberDef *mdDef = dst->memberDefinition();
+ if (mdDef)
+ {
+ mdDef->addSourceReferencedBy(src);
+ }
+ MemberDef *mdDecl = dst->memberDeclaration();
+ if (mdDecl)
+ {
+ mdDecl->addSourceReferencedBy(src);
+ }
+ }
+ if ((referencesRelation || callGraph || src->hasCallGraph()) &&
+ src->showInCallGraph()
+ )
+ {
+ src->addSourceReferences(dst);
+ MemberDef *mdDef = src->memberDefinition();
+ if (mdDef)
+ {
+ mdDef->addSourceReferences(dst);
+ }
+ MemberDef *mdDecl = src->memberDeclaration();
+ if (mdDecl)
+ {
+ mdDecl->addSourceReferences(dst);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------
+
+/*! @brief Get one unicode character as an unsigned integer from utf-8 string
+ *
+ * @param s utf-8 encoded string
+ * @param idx byte position of given string \a s.
+ * @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT
+ * @see getNextUtf8OrToLower()
+ * @see getNextUtf8OrToUpper()
+ */
+uint getUtf8Code( const QCString& s, int idx )
+{
+ const int length = s.length();
+ if (idx >= length) { return 0; }
+ const uint c0 = (uchar)s.at(idx);
+ if ( c0 < 0xC2 || c0 >= 0xF8 ) // 1 byte character
+ {
+ return c0;
+ }
+ if (idx+1 >= length) { return 0; }
+ const uint c1 = ((uchar)s.at(idx+1)) & 0x3f;
+ if ( c0 < 0xE0 ) // 2 byte character
+ {
+ return ((c0 & 0x1f) << 6) | c1;
+ }
+ if (idx+2 >= length) { return 0; }
+ const uint c2 = ((uchar)s.at(idx+2)) & 0x3f;
+ if ( c0 < 0xF0 ) // 3 byte character
+ {
+ return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
+ }
+ if (idx+3 >= length) { return 0; }
+ // 4 byte character
+ const uint c3 = ((uchar)s.at(idx+3)) & 0x3f;
+ return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
+}
+
+
+/*! @brief Returns one unicode character as an unsigned integer
+ * from utf-8 string, making the character lower case if it was upper case.
+ *
+ * @param s utf-8 encoded string
+ * @param idx byte position of given string \a s.
+ * @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
+ * @see getNextUtf8Code()
+*/
+uint getUtf8CodeToLower( const QCString& s, int idx )
+{
+ const uint v = getUtf8Code( s, idx );
+ return v < 0x7f ? tolower( v ) : v;
+}
+
+
+/*! @brief Returns one unicode character as ian unsigned interger
+ * from utf-8 string, making the character upper case if it was lower case.
+ *
+ * @param s utf-8 encoded string
+ * @param idx byte position of given string \a s.
+ * @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
+ * @see getNextUtf8Code()
+ */
+uint getUtf8CodeToUpper( const QCString& s, int idx )
+{
+ const uint v = getUtf8Code( s, idx );
+ return v < 0x7f ? toupper( v ) : v;
+}
+
+//--------------------------------------------------------------------------------------
+
+bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses)
+{
+ if (nd->getNamespaceSDict())
+ {
+ NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict());
+ NamespaceDef *cnd;
+ for (cnli.toFirst();(cnd=cnli.current());++cnli)
+ {
+ if (cnd->isLinkableInProject() && cnd->localName().find('@')==-1)
+ {
+ return TRUE;
+ }
+ else if (namespaceHasVisibleChild(cnd,includeClasses))
+ {
+ return TRUE;
+ }
+ }
+ }
+ if (includeClasses && nd->getClassSDict())
+ {
+ ClassSDict::Iterator cli(*nd->getClassSDict());
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------
+
+bool classVisibleInIndex(ClassDef *cd)
+{
+ static bool allExternals = Config_getBool("ALLEXTERNALS");
+ return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
+}
+
+//----------------------------------------------------------------------------
+
+QCString extractDirection(QCString &docs)
+{
+ QRegExp re("\\[[^\\]]+\\]"); // [...]
+ int l=0;
+ if (re.match(docs,0,&l)==0)
+ {
+ int inPos = docs.find("in", 1,FALSE);
+ int outPos = docs.find("out",1,FALSE);
+ bool input = inPos!=-1 && inPos<l;
+ bool output = outPos!=-1 && outPos<l;
+ if (input || output) // in,out attributes
+ {
+ docs = docs.mid(l); // strip attributes
+ if (input && output) return "[in,out]";
+ else if (input) return "[in]";
+ else if (output) return "[out]";
+ }
+ }
+ return QCString();
+}
+
+//-----------------------------------------------------------
+
+/** Computes for a given list type \a inListType, which are the
+ * the corresponding list type(s) in the base class that are to be
+ * added to this list.
+ *
+ * So for public inheritance, the mapping is 1-1, so outListType1=inListType
+ * Private members are to be hidden completely.
+ *
+ * For protected inheritance, both protected and public members of the
+ * base class should be joined in the protected member section.
+ *
+ * For private inheritance, both protected and public members of the
+ * base class should be joined in the private member section.
+ */
+void convertProtectionLevel(
+ MemberListType inListType,
+ Protection inProt,
+ int *outListType1,
+ int *outListType2
+ )
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ // default representing 1-1 mapping
+ *outListType1=inListType;
+ *outListType2=-1;
+ if (inProt==Public)
+ {
+ switch (inListType) // in the private section of the derived class,
+ // the private section of the base class should not
+ // be visible
+ {
+ case MemberListType_priMethods:
+ case MemberListType_priStaticMethods:
+ case MemberListType_priSlots:
+ case MemberListType_priAttribs:
+ case MemberListType_priStaticAttribs:
+ case MemberListType_priTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (inProt==Protected) // Protected inheritance
+ {
+ switch (inListType) // in the protected section of the derived class,
+ // both the public and protected members are shown
+ // as protected
+ {
+ case MemberListType_pubMethods:
+ case MemberListType_pubStaticMethods:
+ case MemberListType_pubSlots:
+ case MemberListType_pubAttribs:
+ case MemberListType_pubStaticAttribs:
+ case MemberListType_pubTypes:
+ case MemberListType_priMethods:
+ case MemberListType_priStaticMethods:
+ case MemberListType_priSlots:
+ case MemberListType_priAttribs:
+ case MemberListType_priStaticAttribs:
+ case MemberListType_priTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+
+ case MemberListType_proMethods:
+ *outListType2=MemberListType_pubMethods;
+ break;
+ case MemberListType_proStaticMethods:
+ *outListType2=MemberListType_pubStaticMethods;
+ break;
+ case MemberListType_proSlots:
+ *outListType2=MemberListType_pubSlots;
+ break;
+ case MemberListType_proAttribs:
+ *outListType2=MemberListType_pubAttribs;
+ break;
+ case MemberListType_proStaticAttribs:
+ *outListType2=MemberListType_pubStaticAttribs;
+ break;
+ case MemberListType_proTypes:
+ *outListType2=MemberListType_pubTypes;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (inProt==Private)
+ {
+ switch (inListType) // in the private section of the derived class,
+ // both the public and protected members are shown
+ // as private
+ {
+ case MemberListType_pubMethods:
+ case MemberListType_pubStaticMethods:
+ case MemberListType_pubSlots:
+ case MemberListType_pubAttribs:
+ case MemberListType_pubStaticAttribs:
+ case MemberListType_pubTypes:
+ case MemberListType_proMethods:
+ case MemberListType_proStaticMethods:
+ case MemberListType_proSlots:
+ case MemberListType_proAttribs:
+ case MemberListType_proStaticAttribs:
+ case MemberListType_proTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+
+ case MemberListType_priMethods:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubMethods;
+ *outListType2=MemberListType_proMethods;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ case MemberListType_priStaticMethods:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubStaticMethods;
+ *outListType2=MemberListType_proStaticMethods;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ case MemberListType_priSlots:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubSlots;
+ *outListType1=MemberListType_proSlots;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ case MemberListType_priAttribs:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubAttribs;
+ *outListType2=MemberListType_proAttribs;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ case MemberListType_priStaticAttribs:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubStaticAttribs;
+ *outListType2=MemberListType_proStaticAttribs;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ case MemberListType_priTypes:
+ if (extractPrivate)
+ {
+ *outListType1=MemberListType_pubTypes;
+ *outListType2=MemberListType_proTypes;
+ }
+ else
+ {
+ *outListType1=-1;
+ *outListType2=-1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ //printf("convertProtectionLevel(type=%d prot=%d): %d,%d\n",
+ // inListType,inProt,*outListType1,*outListType2);
+}
+
+bool mainPageHasTitle()
+{
+ if (Doxygen::mainPage==0) return FALSE;
+ if (Doxygen::mainPage->title().isEmpty()) return FALSE;
+ if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
+ return TRUE;
+}
+
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..f74fad0
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,462 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+/*! \file
+ * \brief A bunch of utility functions.
+ */
+
+#include <qlist.h>
+#include <ctype.h>
+#include "types.h"
+#include "sortdict.h"
+#include "docparser.h"
+
+//--------------------------------------------------------------------
+
+class ClassDef;
+class FileDef;
+class MemberList;
+class NamespaceDef;
+class FileNameDict;
+class ArgumentList;
+class OutputList;
+class OutputDocInterface;
+class MemberDef;
+class ExampleSDict;
+class ClassSDict;
+class BaseClassList;
+class GroupDef;
+class NamespaceSDict;
+class ClassList;
+class MemberGroupSDict;
+struct TagInfo;
+class MemberNameInfoSDict;
+struct ListItemInfo;
+class PageDef;
+struct SectionInfo;
+class QDir;
+class Definition;
+class BufStr;
+class QFileInfo;
+class QStrList;
+class FTextStream;
+
+//--------------------------------------------------------------------
+
+/** Abstract interface for a hyperlinked text fragment. */
+class TextGeneratorIntf
+{
+ public:
+ virtual ~TextGeneratorIntf() {}
+ virtual void writeString(const char *,bool) const = 0;
+ virtual void writeBreak(int indent) const = 0;
+ virtual void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const = 0;
+};
+
+/** Implements TextGeneratorIntf for an OutputDocInterface stream. */
+class TextGeneratorOLImpl : public TextGeneratorIntf
+{
+ public:
+ virtual ~TextGeneratorOLImpl() {}
+ TextGeneratorOLImpl(OutputDocInterface &od);
+ void writeString(const char *s,bool keepSpaces) const;
+ void writeBreak(int indent) const;
+ void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const;
+ private:
+ OutputDocInterface &m_od;
+};
+
+//--------------------------------------------------------------------
+
+/** @brief maps a unicode character code to a list of T::ElementType's
+ */
+template<class T>
+class LetterToIndexMap : public SIntDict<T>
+{
+ public:
+ LetterToIndexMap() { SIntDict<T>::setAutoDelete(TRUE); }
+ void append(uint letter,typename T::ElementType *elem)
+ {
+ T *l = SIntDict<T>::find((int)letter);
+ if (l==0)
+ {
+ l = new T(letter);
+ SIntDict<T>::inSort((int)letter,l);
+ }
+ l->append(elem);
+ }
+ private:
+ int compareValues(const T *l1, const T *l2) const
+ {
+ return (int)l1->letter()-(int)l2->letter();
+ }
+};
+
+//--------------------------------------------------------------------
+
+QCString langToString(SrcLangExt lang);
+QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE);
+
+//--------------------------------------------------------------------
+
+void linkifyText(const TextGeneratorIntf &ol,
+ Definition *scope,
+ FileDef *fileScope,
+ Definition *self,
+ const char *text,
+ bool autoBreak=FALSE,
+ bool external=TRUE,
+ bool keepSpaces=FALSE,
+ int indentLevel=0
+ );
+
+void setAnchors(MemberList *ml);
+
+QCString fileToString(const char *name,bool filter=FALSE,bool isSourceCode=FALSE);
+
+QCString dateToString(bool);
+
+bool getDefs(const QCString &scopeName,
+ const QCString &memberName,
+ const char *,
+ MemberDef *&md,
+ ClassDef *&cd,
+ FileDef *&fd,
+ NamespaceDef *&nd,
+ GroupDef *&gd,
+ bool forceEmptyScope=FALSE,
+ FileDef *currentFile=0,
+ bool checkCV=FALSE,
+ const char *forceTagFile=0
+ );
+
+QCString getFileFilter(const char* name,bool isSourceCode);
+
+bool resolveRef(/* in */ const char *scName,
+ /* in */ const char *name,
+ /* in */ bool inSeeBlock,
+ /* out */ Definition **resContext,
+ /* out */ MemberDef **resMember,
+ /* in */ bool lookForSpecializations = TRUE,
+ /* in */ FileDef *currentFile = 0,
+ /* in */ bool checkScope = FALSE
+ );
+
+bool resolveLink(/* in */ const char *scName,
+ /* in */ const char *lr,
+ /* in */ bool inSeeBlock,
+ /* out */ Definition **resContext,
+ /* out */ QCString &resAnchor
+ );
+
+//bool generateRef(OutputDocInterface &od,const char *,
+// const char *,bool inSeeBlock,const char * =0);
+
+bool generateLink(OutputDocInterface &od,const char *,
+ const char *,bool inSeeBlock,const char *);
+
+void generateFileRef(OutputDocInterface &od,const char *,
+ const char *linkTxt=0);
+
+void writePageRef(OutputDocInterface &od,const char *cn,const char *mn);
+
+QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec);
+
+bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
+ Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
+ bool checkCV
+ );
+
+void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE);
+
+QCString substituteClassNames(const QCString &s);
+
+QCString substitute(const char *s,const char *src,const char *dst);
+
+QCString clearBlock(const char *s,const char *begin,const char *end);
+
+QCString selectBlock(const QCString& s,const QCString &name,bool which);
+
+QCString resolveDefines(const char *n);
+
+ClassDef *getClass(const char *key);
+
+ClassDef *getResolvedClass(Definition *scope,
+ FileDef *fileScope,
+ const char *key,
+ MemberDef **pTypeDef=0,
+ QCString *pTemplSpec=0,
+ bool mayBeUnlinkable=FALSE,
+ bool mayBeHidden=FALSE,
+ QCString *pResolvedType=0);
+
+NamespaceDef *getResolvedNamespace(const char *key);
+
+FileDef *findFileDef(const FileNameDict *fnDict,const char *n,
+ bool &ambig);
+
+QCString showFileDefMatches(const FileNameDict *fnDict,const char *n);
+
+int guessSection(const char *name);
+
+inline bool isId(int c)
+{
+ return c=='_' || c>=128 || c<0 || isalnum(c);
+}
+
+QCString removeRedundantWhiteSpace(const QCString &s);
+
+QCString argListToString(ArgumentList *al,bool useCanonicalType=FALSE,bool showDefVals=TRUE);
+
+QCString tempArgListToString(ArgumentList *al);
+
+QCString generateMarker(int id);
+
+void writeExample(OutputList &ol,ExampleSDict *el);
+
+QCString stripAnonymousNamespaceScope(const QCString &s);
+
+QCString stripFromPath(const QCString &path);
+
+QCString stripFromIncludePath(const QCString &path);
+
+bool rightScopeMatch(const QCString &scope, const QCString &name);
+
+bool leftScopeMatch(const QCString &scope, const QCString &name);
+
+QCString substituteKeywords(const QCString &s,const char *title,
+ const char *projName,const char *projNum,const char *projBrief);
+
+int getPrefixIndex(const QCString &name);
+
+QCString removeAnonymousScopes(const QCString &s);
+
+QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0);
+
+void initClassHierarchy(ClassSDict *cl);
+
+bool hasVisibleRoot(BaseClassList *bcl);
+bool classHasVisibleChildren(ClassDef *cd);
+bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses);
+bool classVisibleInIndex(ClassDef *cd);
+
+int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0);
+Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection prot=Public,int level=0);
+
+QCString convertNameToFile(const char *name,bool allowDots=FALSE,bool allowUnderscore=FALSE);
+
+void extractNamespaceName(const QCString &scopeName,
+ QCString &className,QCString &namespaceName,
+ bool allowEmptyClass=FALSE);
+
+QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ);
+
+QCString stripScope(const char *name);
+
+QCString convertToHtml(const char *s,bool keepEntities=TRUE);
+
+QCString convertToXML(const char *s);
+
+QCString convertToJSString(const char *s);
+
+QCString getOverloadDocs();
+
+void addMembersToMemberGroup(/* in */ MemberList *ml,
+ /* in,out */ MemberGroupSDict **ppMemberGroupSDict,
+ /* in */ Definition *context);
+
+int extractClassNameFromType(const QCString &type,int &pos,
+ QCString &name,QCString &templSpec,SrcLangExt=SrcLangExt_Unknown);
+
+QCString normalizeNonTemplateArgumentsInString(
+ const QCString &name,
+ Definition *context,
+ const ArgumentList *formalArgs);
+
+QCString substituteTemplateArgumentsInString(
+ const QCString &name,
+ ArgumentList *formalArgs,
+ ArgumentList *actualArgs);
+
+QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists);
+
+QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
+ bool parentOnly=TRUE,
+ QCString *lastScopeStripped=0);
+
+QCString resolveTypeDef(Definition *d,const QCString &name,
+ Definition **typedefContext=0);
+
+QCString mergeScopes(const QCString &leftScope,const QCString &rightScope);
+
+int getScopeFragment(const QCString &s,int p,int *l);
+
+int filterCRLF(char *buf,int len);
+
+void addRefItem(const QList<ListItemInfo> *sli,const char *prefix,
+ const char *key,
+ const char *name,const char *title,const char *args);
+
+PageDef *addRelatedPage(const char *name,const QCString &ptitle,
+ const QCString &doc,QList<SectionInfo> *anchors,
+ const char *fileName,int startLine,
+ const QList<ListItemInfo> *sli,
+ GroupDef *gd=0,
+ TagInfo *tagInfo=0,
+ SrcLangExt lang=SrcLangExt_Unknown
+ );
+
+QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscore=FALSE);
+
+void addGroupListToTitle(OutputList &ol,Definition *d);
+
+void filterLatexString(FTextStream &t,const char *str,
+ bool insideTabbing=FALSE,
+ bool insidePre=FALSE,
+ bool insideItem=FALSE);
+
+QCString rtfFormatBmkStr(const char *name);
+
+QCString linkToText(SrcLangExt lang,const char *link,bool isFileName);
+
+QCString stripExtension(const char *fName);
+
+void replaceNamespaceAliases(QCString &scope,int i);
+
+int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item);
+
+int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item,
+ const QCString &explicitScopePart);
+
+int computeQualifiedIndex(const QCString &name);
+
+void addDirPrefix(QCString &fileName);
+
+QCString relativePathToRoot(const char *name);
+
+void createSubDirs(QDir &d);
+
+QCString stripPath(const char *s);
+
+bool containsWord(const QCString &s,const QCString &word);
+
+bool findAndRemoveWord(QCString &s,const QCString &word);
+
+QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine);
+
+//void stringToSearchIndex(const QCString &docUrlBase,const QCString &title,
+// const QCString &str, bool priority=FALSE,
+// const QCString &anchor="");
+
+bool updateLanguageMapping(const QCString &extension,const QCString &parser);
+SrcLangExt getLanguageFromFileName(const QCString fileName);
+void initDefaultExtensionMapping();
+
+MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope,
+ const char *n);
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n);
+
+ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md,
+ MemberDef **pMemType=0,QCString *pTemplSpec=0,
+ QCString *pResolvedType=0,
+ ArgumentList *actTemplParams=0);
+
+QCString parseCommentAsText(const Definition *scope,const MemberDef *member,const QCString &doc,const QCString &fileName,int lineNr);
+
+QCString transcodeCharacterStringToUTF8(const QCString &input);
+
+QCString recodeString(const QCString &str,const char *fromEncoding,const char *toEncoding);
+
+QCString extractAliasArgs(const QCString &args,int pos);
+
+int countAliasArguments(const QCString argList);
+
+//QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList);
+
+QCString resolveAliasCmd(const QCString aliasCmd);
+QCString expandAlias(const QCString &aliasName,const QCString &aliasValue);
+
+void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al);
+
+QCString convertCharEntitiesToUTF8(const QCString &s);
+
+void stackTrace();
+
+bool readInputFile(const char *fileName,BufStr &inBuf,
+ bool filter=TRUE,bool isSourceCode=FALSE);
+QCString filterTitle(const QCString &title);
+
+bool patternMatch(const QFileInfo &fi,const QStrList *patList);
+
+QCString externalLinkTarget();
+QCString externalRef(const QCString &relPath,const QCString &ref,bool href);
+int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos);
+const char *writeUtf8Char(FTextStream &t,const char *s);
+
+
+/** Data associated with a HSV colored image. */
+struct ColoredImgDataItem
+{
+ const char *name;
+ unsigned short width;
+ unsigned short height;
+ unsigned char *content;
+ unsigned char *alpha;
+};
+
+void writeColoredImgData(const char *dir,ColoredImgDataItem data[]);
+QCString replaceColorMarkers(const char *str);
+
+bool copyFile(const QCString &src,const QCString &dest);
+QCString extractBlock(const QCString text,const QCString marker);
+
+QCString correctURL(const QCString &url,const QCString &relPath);
+
+QCString processMarkup(const QCString &s);
+
+bool protectionLevelVisible(Protection prot);
+
+QCString stripIndentation(const QCString &s);
+
+bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile);
+
+void addDocCrossReference(MemberDef *src,MemberDef *dst);
+
+uint getUtf8Code( const QCString& s, int idx );
+uint getUtf8CodeToLower( const QCString& s, int idx );
+uint getUtf8CodeToUpper( const QCString& s, int idx );
+
+QCString extractDirection(QCString &docs);
+
+void convertProtectionLevel(
+ MemberListType inListType,
+ Protection inProt,
+ int *outListType1,
+ int *outListType2
+ );
+
+bool mainPageHasTitle();
+
+#endif
+
diff --git a/src/version.cpp b/src/version.cpp
new file mode 100644
index 0000000..33e8787
--- /dev/null
+++ b/src/version.cpp
@@ -0,0 +1 @@
+char versionString[]="1.8.8";
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..b31fe4f
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+extern char versionString[];
+
+#endif
diff --git a/src/version.py b/src/version.py
new file mode 100755
index 0000000..003cf95
--- /dev/null
+++ b/src/version.py
@@ -0,0 +1,58 @@
+#
+
+# script to read the version information from `../configure`
+# relevant lines are starting with:
+# `doxygen_version_major`
+# `doxygen_version_minor`
+# `doxygen_version_revision`
+# `doxygen_version_mmn`
+# the collected information is written to: `../VERSION` and `../src/version.cpp`
+#
+import sys
+import os
+#
+# set 'default' values
+#
+major = 0
+minor = 0
+revision = 0
+mnt = 'NO'
+#
+# open input file
+# read file and get relevant information
+# close
+#
+f = open('../configure', 'r')
+for line in f:
+ # check if line can match (saves 3 comparisons)
+ if (line.startswith('doxygen_version')):
+ if (line.startswith('doxygen_version_major')):
+ major = line.replace('doxygen_version_major=','')
+ elif (line.startswith('doxygen_version_minor')):
+ minor = line.replace('doxygen_version_minor=','')
+ elif (line.startswith('doxygen_version_revision')):
+ revision = line.replace('doxygen_version_revision=','')
+ elif (line.startswith('doxygen_version_mmn')):
+ mnt = line.replace('doxygen_version_mmn=','')
+f.close()
+
+# strip superfluous '\n`
+major = major.replace('\n','')
+minor = minor.replace('\n','')
+revision = revision.replace('\n','')
+mnt = mnt.replace('\n','')
+#
+# open output files
+# write relevant infomation
+# close files
+#
+f1 = open('../VERSION','w')
+f2 = open(os.path.join(sys.argv[1],'version.cpp'),'w')
+if (mnt == 'NO'):
+ f1.write(major + '.' + minor + '.' + revision)
+ f2.write('char versionString[]="' + major + '.' + minor + '.' + revision + '";')
+else:
+ f1.write(major + '.' + minor + '.' + revision + '-' + mnt)
+ f2.write('char versionString[]="' + major + '.' + minor + '.' + revision + '-' + mnt + '";')
+f1.close()
+f2.close()
diff --git a/src/vhdlcode.h b/src/vhdlcode.h
new file mode 100644
index 0000000..e21ddea
--- /dev/null
+++ b/src/vhdlcode.h
@@ -0,0 +1,16 @@
+#ifndef VHDLCODE_H
+#define VHDLCODE_H
+
+class CodeOutputInterface;
+class FileDef;
+class MemberDef;
+
+void parseVhdlCode(CodeOutputInterface &,const char *,const QCString &,
+ bool ,const char *,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
+ bool collectXRefs);
+void resetVhdlCodeParserState();
+void codeFreeVhdlScanner();
+
+#endif
diff --git a/src/vhdlcode.l b/src/vhdlcode.l
new file mode 100644
index 0000000..fa199d1
--- /dev/null
+++ b/src/vhdlcode.l
@@ -0,0 +1,1628 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/******************************************************************************
+ * Parser for syntax hightlighting and references for vhdl subset
+ * written by M. Kreis
+ * supports VHDL-87/93/2008
+ ******************************************************************************/
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <qregexp.h>
+#include <qdir.h>
+#include <qstringlist.h>
+
+#include "entry.h"
+#include "doxygen.h"
+#include "message.h"
+#include "outputlist.h"
+#include "util.h"
+#include "membername.h"
+#include "searchindex.h"
+#include "vhdldocgen.h"
+#include "arguments.h"
+#include "config.h"
+#include "classdef.h"
+#include "filedef.h"
+#include "tooltip.h"
+
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+
+// Toggle for some debugging info
+//#define DBG_CTX(x) fprintf x
+#define DBG_CTX(x) do { } while(0)
+
+
+/* -----------------------------------------------------------------
+ * statics
+ */
+
+// ----------------- <vhdl> ----------------------------------
+
+//static bool isPackBody=FALSE;
+//static bool isStartMap;
+static bool isFuncProto=FALSE;
+static bool isComponent=FALSE;
+static bool isPackageBody=FALSE;
+static bool isProto = FALSE;
+static bool g_startCode = FALSE;
+static QCString g_PrevString;
+static QCString g_CurrClass;
+static QDict<QCString>g_vhdlKeyDict;
+static QCString g_tempClass;
+static QCString g_tempComp;
+static QCString g_PortMapComp;
+static MemberDef *g_vhdlMember;
+static QCString g_FuncProto;
+
+//-----------------------------------------------------------
+
+static CodeOutputInterface * g_code;
+static QCString g_curClassName;
+static QCString g_parmType;
+static QCString g_parmName;
+static const char * g_inputString; //!< the code fragment as text
+static int g_inputPosition; //!< read offset during parsing
+static int g_inputLines; //!< number of line in the code fragment
+static int g_yyLineNr; //!< current line number
+static bool g_needsTermination;
+static Definition *g_searchCtx;
+
+static QCString g_exampleName;
+static QCString g_exampleFile;
+
+static QCString g_type;
+static QCString g_name;
+static QCString g_args;
+static QCString g_classScope;
+
+static QCString g_CurrScope;
+
+static FileDef * g_sourceFileDef;
+static Definition * g_currentDefinition;
+static MemberDef * g_currentMemberDef;
+static bool g_includeCodeFragment;
+static const char * g_currentFontClass;
+
+static bool g_lexInit = FALSE;
+static int g_braceCount=0;
+
+
+static void writeFont(const char *s,const char* text);
+static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
+static bool writeColoredWord(QCString& word );
+static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE);
+static void endFontClass();
+static void startFontClass(const char *s);
+//-------------------------------------------------------------------
+
+
+static void setCurrentDoc(const QCString &anchor)
+{
+ if (Doxygen::searchIndex)
+ {
+ if (g_searchCtx)
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
+ }
+ else
+ {
+ Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
+ }
+ }
+}
+
+static bool checkVhdlString(QCString &name)
+{
+ if (name.isEmpty()) return FALSE;
+ static QRegExp regg("[\\s\"]");
+
+ int len=name.length();
+ if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
+ {
+ QStringList qrl=QStringList::split(regg,name,FALSE);
+ if (VhdlDocGen::isNumber(qrl[0].utf8()))
+ {
+ g_code->codify("\"");
+ startFontClass("vhdllogic");
+ QCString mid=name.mid(1,len-2); //" 1223 "
+ g_code->codify(mid.data());
+ endFontClass();
+ g_code->codify("\"");
+ }
+ else
+ {
+ startFontClass("keyword");
+ g_code->codify(name.data());
+ endFontClass();
+ }
+ return TRUE;
+ }
+
+ if (VhdlDocGen::isNumber(name))
+ {
+ startFontClass("vhdllogic");
+ g_code->codify(name.data());
+ endFontClass();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void addToSearchIndex(const char *text)
+{
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->addWord(text,FALSE);
+ }
+}
+
+
+/*! start a new line of code, inserting a line number if g_sourceFileDef
+ * is TRUE. If a definition starts at the current line, then the line
+ * number is linked to the documentation of that definition.
+ */
+static void startCodeLine()
+{
+ //if (g_currentFontClass) { g_code->endFontClass(); }
+ if (g_sourceFileDef)
+ {
+ g_startCode=TRUE;
+ //QCString lineNumber,lineAnchor;
+ //lineNumber.sprintf("%05d",g_yyLineNr);
+ //lineAnchor.sprintf("l%05d",g_yyLineNr);
+ // if ((g_yyLineNr % 500) == 0)
+ // fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
+ Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
+ //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
+ if (!g_includeCodeFragment && d)
+ {
+ g_currentDefinition = d;
+ g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
+ if (!g_tempComp.isEmpty() && g_currentMemberDef )
+ {
+ //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
+ QCString nn=g_currentMemberDef->name();
+ MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
+ if (mdeff)
+ {
+ g_currentMemberDef=mdeff;
+ }
+ }
+
+ g_parmType.resize(0);
+ g_parmName.resize(0);
+ QCString lineAnchor;
+ lineAnchor.sprintf("l%05d",g_yyLineNr);
+ if (g_currentMemberDef)
+ {
+ g_code->writeLineNumber(g_currentMemberDef->getReference(),
+ g_currentMemberDef->getOutputFileBase(),
+ g_currentMemberDef->anchor(),g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ else if (d->isLinkableInProject())
+ {
+ g_code->writeLineNumber(d->getReference(),
+ d->getOutputFileBase(),
+ 0,g_yyLineNr);
+ setCurrentDoc(lineAnchor);
+ }
+ }
+ else
+ {
+ g_code->writeLineNumber(0,0,0,g_yyLineNr);
+ }
+ }
+ g_code->startCodeLine(g_sourceFileDef);
+ if (g_currentFontClass)
+ {
+ g_code->startFontClass(g_currentFontClass);
+ }
+}
+
+static void endFontClass();
+static void endCodeLine()
+{
+ endFontClass();
+ g_code->endCodeLine();
+}
+
+static void nextCodeLine()
+{
+ if (g_startCode)
+ {
+ endCodeLine(); // </div>
+ }
+ const char *fc = g_currentFontClass;
+ if (g_yyLineNr<g_inputLines)
+ {
+ g_currentFontClass = fc;
+ startCodeLine(); //<div>
+ }
+}
+
+/*! writes a word to the output.
+ * If curr_class is defined, the word belongs to a class
+ * and will be linked.
+ */
+
+static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
+{
+ bool found=FALSE;
+ QCString temp;
+ QCString tclass(curr_class);
+ QCString ttt(word);
+ if (ttt.isEmpty()) return;
+ for (unsigned int j=0;j<ttt.length();j++)
+ {
+ char c=ttt.at(j);
+ if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
+ {
+ if (found)
+ {
+ if (!writeColoredWord(temp)) // is it a keyword ?
+ {
+ //if (VhdlDocGen::findKeyWord(temp))
+ // writeFont("vhdlkeyword",temp.data());
+ //printf("writeWord: %s\n",temp.data());
+ if (!tclass.isEmpty())
+ {
+ if (!classLink)
+ {
+ generateMemLink(*g_code,tclass,temp);
+ }
+ else
+ {
+ generateClassOrGlobalLink(*g_code,temp);
+ }
+ }
+ else
+ {
+ if (!checkVhdlString(temp))
+ g_code->codify(temp.data());
+ }
+ }
+ temp.resize(0);
+ found=FALSE;
+ }
+
+ char cc[2];
+ cc[0]=c;
+ cc[1]=0;
+ g_code->codify(cc);
+ }
+ else
+ {
+ found=TRUE;
+ temp+=c;
+ }
+ } // for
+
+ if (!temp.isEmpty())
+ {
+ if (!writeColoredWord(temp))
+ {
+ if (!tclass.isEmpty())
+ {
+ if (!classLink)
+ {
+ generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left);
+ }
+ else
+ {
+ generateClassOrGlobalLink(*g_code,temp);
+ }
+ }
+ else
+ {
+ QCString qc(temp.data());
+ if (VhdlDocGen::isNumber(qc)){
+ startFontClass("vhdllogic");
+ g_code->codify(temp.data());
+ endFontClass();
+ }
+ else
+ g_code->codify(temp.data());
+ }
+ }
+ }
+}// writeWord
+
+
+/*! write a code fragment `text' that may span multiple lines, inserting
+ * line numbers for each line.
+ */
+static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,bool comment=FALSE)
+{
+ if (text==0) return;
+ //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
+ const char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ sp=p;
+ while ((c=*p++) && c!='\n') {}
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ QCString line = sp;
+ line = line.left((int)(p-sp)-1);
+ //*(p-1)='\0';
+ //g_code->codify(sp);
+ if (comment)
+ {
+ writeFont("keyword",line.data());
+ }
+ else
+ {
+ writeWord(line,cl,classlink);
+ }
+ nextCodeLine();
+ }
+ else
+ {
+ if (comment)
+ writeFont("keyword",sp);
+ else
+ writeWord(sp,cl,classlink);
+ done=TRUE;
+ }
+ }
+}
+
+/*! writes a link to a fragment \a text that may span multiple lines, inserting
+ * line numbers for each line. If \a text contains newlines, the link will be
+ * split into multiple links with the same destination, one for each line.
+ */
+static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ Definition *d,
+ const char *text)
+{
+ static bool sourceTooltips = Config_getBool("SOURCE_TOOLTIPS");
+ TooltipManager::instance()->addTooltip(d);
+ QCString ref = d->getReference();
+ QCString file = d->getOutputFileBase();
+ QCString anchor = d->anchor();
+ QCString tooltip;
+ if (!sourceTooltips) // fall back to simple "title" tooltips
+ {
+ tooltip = d->briefDescriptionAsTooltip();
+ }
+ bool done=FALSE;
+ char *p=(char *)text;
+ while (!done)
+ {
+ char *sp=p;
+ char c;
+ while ((c=*p++) && c!='\n') {}
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ nextCodeLine();
+ }
+ else
+ {
+ ol.writeCodeLink(ref,file,anchor,sp,tooltip);
+ done=TRUE;
+ }
+ }
+}
+
+static void setParameterList(MemberDef *md)
+{
+ g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
+ ArgumentList *al = md->argumentList();
+ if (al==0) return;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ g_parmName = a->name.copy();
+ g_parmType = a->type.copy();
+ int i = g_parmType.find('*');
+ if (i!=-1) g_parmType = g_parmType.left(i);
+ i = g_parmType.find('&');
+ if (i!=-1) g_parmType = g_parmType.left(i);
+ g_parmType.stripPrefix("const ");
+ g_parmType=g_parmType.stripWhiteSpace();
+ // g_theVarContext.addVariable(g_parmType,g_parmName);
+ }
+}
+
+
+/*! writes a link to a function or procedure
+ */
+
+static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
+{
+
+ //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
+ QCString memberName=mdef->name();
+
+ if (mdef && mdef->isLinkable()) // is it a linkable class
+ {
+ writeMultiLineCodeLink(ol,mdef,mdef->name());
+ addToSearchIndex(memberName);
+ return;
+ }
+ codifyLines(memberName.data());
+ addToSearchIndex(memberName);
+} // generateFuncLink
+
+
+static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
+{
+ if (memberName.isEmpty()) return;
+ if (clName.isEmpty())
+ {
+ codifyLines(memberName.data());
+
+ return;
+ }
+
+ QCString className=clName;
+
+ MemberDef *md=0;
+ //MemberDef *comp=0;
+ //bool isLocal=FALSE;
+
+ md=VhdlDocGen::findMember(className,memberName);
+ ClassDef *po=VhdlDocGen::getClass(className.data());
+
+ if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS)
+ {
+ QCString temp=className;//.stripPrefix("_");
+ temp.stripPrefix("_");
+ md=VhdlDocGen::findMember(temp,memberName);
+ }
+
+ if (md && md->isLinkable()) // is it a linkable class
+ {
+ writeMultiLineCodeLink(ol,md,memberName);
+ addToSearchIndex(memberName);
+ return;
+ }
+ // nothing found, just write out the word
+ codifyLines(memberName.data());
+ addToSearchIndex(memberName);
+}// generateMemLink
+
+
+static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/)
+{
+ QCString className=clName;
+
+ if (className.isEmpty()) return;
+
+ ClassDef *cd=0;
+ //MemberDef *md=0;
+ //bool isLocal=FALSE;
+ className.stripPrefix("_");
+ cd = getClass(className.data());
+ while (cd)
+ {
+ //className.stripPrefix("_");
+ QCString temp(clName);
+ temp.stripPrefix("_");
+ if (cd && cd->isLinkable()) // is it a linkable class
+ {
+ //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
+ //{
+ // temp=VhdlDocGen::getClassName(cd);
+ //}
+ writeMultiLineCodeLink(ol,cd,temp);
+ addToSearchIndex(className);
+ return;
+ }
+ Definition *d = cd->getOuterScope();
+ if (d && d->definitionType()==Definition::TypeClass)
+ {
+ cd = (ClassDef*)d;
+ }
+ else
+ {
+ cd = 0;
+ }
+ }
+
+ // nothing found, just write out the word
+ codifyLines(clName);
+ addToSearchIndex(clName);
+}// generateClasss or global link
+
+
+/*! counts the number of lines in the input */
+static int countLines()
+{
+ const char *p=g_inputString;
+ char c;
+ int count=1;
+ while ((c=*p))
+ {
+ p++ ;
+ if (c=='\n') count++;
+ }
+ if (p>g_inputString && *(p-1)!='\n')
+ { // last line does not end with a \n, so we add an extra
+ // line and explicitly terminate the line after parsing.
+ count++,
+ g_needsTermination=TRUE;
+ }
+ return count;
+}
+
+static void endFontClass()
+{
+ if (g_currentFontClass)
+ {
+ g_code->endFontClass();
+ g_currentFontClass=0;
+ }
+}
+
+static void startFontClass(const char *s)
+{
+ if (s==0) return;
+ endFontClass();
+ g_code->startFontClass(s);
+ g_currentFontClass=s;
+}
+
+static void writeFont(const char *s,const char* text)
+{
+ if (s==0 || text==0) return;
+ //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
+ g_code->startFontClass(s);
+ g_code->codify(text);
+ g_code->endFontClass();
+}
+
+//----------------------------------------------------------------------------
+
+static void appStringLower(QCString& qcs,const char* text)
+{
+ qcs.resize(0);
+ qcs.append(text);
+ //qcs=qcs.lower();
+ qcs=qcs.stripWhiteSpace();
+}
+
+//static void appString(QCString& qcs,const char* text)
+//{
+// qcs.resize(0);
+// qcs.append(text);
+//}
+
+static QCString g_temp;
+
+/* writes and links a port map statement */
+static void codifyMapLines(char *text)
+{
+ if (text==0) return;
+ g_temp.resize(0);
+ //bool dot=FALSE;
+ int wordCounter=0;
+ QCString ctemp;
+ //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
+ char *p=text; //,*sp=p;
+ char c;
+ bool done=FALSE;
+ while (!done)
+ {
+ //sp=p;
+ while ((c=*p++) && c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
+ {
+ if (c!=0x9)
+ g_temp+=c;
+ }
+ if (c=='\0') return;
+ if (!g_temp.isEmpty()) wordCounter++;
+
+ if (!g_temp.isEmpty())
+ {
+ // different kinds of component instantiations
+ // xxx:yyy (generic/port) map(
+ // xxx:(entity/component/configuration) yyy (generic/port) map(
+ // xxx: entity yyy(zzz) (generic/port) map(
+ if (wordCounter==2 || wordCounter==3)
+ {
+ QCString q=g_temp.lower(); // consider (upper/lower) cases
+ if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
+ {
+ generateMemLink(*g_code,g_CurrClass,g_temp);
+ }
+ else
+ {
+ g_PortMapComp=g_temp;
+ generateClassOrGlobalLink(*g_code,g_temp);
+ }
+ }
+ else
+ {
+ generateMemLink(*g_code,g_CurrClass,g_temp);
+ }
+ }
+ ctemp.fill(c,1);
+ codifyLines(ctemp.data());
+ ctemp.resize(0);
+ g_temp.resize(0);
+ }//while
+}//codifymaplines
+
+/*
+* writes a function|procedure prototype and links the function|procedure name
+*/
+
+static void writeFuncProto()
+{
+ QList<Argument> ql;
+ QCString name,ret;
+ VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
+
+ if (name.isEmpty())
+ {
+ codifyLines(g_FuncProto.data(),g_CurrClass.data());
+ return;
+ }
+ QStringList qlist=QStringList::split(name,g_FuncProto,FALSE);
+ QCString temp=qlist[0].utf8();
+ codifyLines(temp.data(),g_CurrClass.data());
+ g_FuncProto.stripPrefix(temp.data());
+ temp.resize(0);
+ temp=g_CurrClass;
+ if (isPackageBody)
+ {
+ temp.stripPrefix("_");// _{package body name}
+ }
+ MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
+
+ if (mdef)
+ {
+ generateFuncLink(*g_code,mdef);
+ g_FuncProto.stripPrefix(name.data());
+ codifyLines(g_FuncProto.data(),g_CurrClass.data());
+ }
+ else
+ {
+ codifyLines(g_FuncProto.data(),g_CurrClass.data());
+ }
+}// writeFuncProto
+
+/* writes a process prototype to the ouput */
+
+ static void writeProcessProto(){
+ codifyLines(g_FuncProto.data(),g_CurrClass.data());
+ g_vhdlKeyDict.clear();
+}// writeProcessProto
+
+/* writes a keyword */
+
+static bool writeColoredWord(QCString& word )
+{
+ QCString qcs=word.lower();
+ QCString *ss=VhdlDocGen::findKeyWord(qcs);
+ if (ss)
+ {
+ writeFont(ss->data(),word.data());
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && g_inputString[g_inputPosition] )
+ {
+ *buf = g_inputString[g_inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+
+B [ \t]
+BN [ \t\n\r]
+STRING ["][^"\n]*["]
+NAME [a-z_A-Z][ a-z_A-Z0-9]*
+FUNCNAME [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
+ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
+SPECSIGN [:;, +*&\/=<>'\t]*
+DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
+ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}*
+ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}*
+
+ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}
+PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
+
+END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
+END2 [^a-zA-Z_]("end"){BN}*[;]
+END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
+END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
+ENDEFUNC {END3}|{END4}|{END2}
+
+KEYWORD ("new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
+TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
+FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
+
+ARITHOP "+"|"-"|"/"|"*"|"%"|"/="|":="
+ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
+LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
+BITOP "&"|"|"|"^"|"<<"|">>"|"~"
+OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
+
+PORT {B}*("port"){BN}*("(")
+GENERIC {B}*("generic"){BN}*("(")
+
+BRACEOPEN [(]{1}
+BRACECLOSE [)]{1}
+
+TEXTT {B}*"--"[^\n]*
+
+MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
+MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
+MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
+MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
+
+XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFIG"|"CONFIG_MODE"|"COOL_CLK"|"DATA_GATE"|"DCI_VALUE"|"DISABLE"|"DRIVE"|"DROP_SPEC"|"ENABLE"|"FAST"|"FEEDBACK"|"FILE"|"FLOAT"|"FROM-THRU-TO"|"FROM-TO"|"HBLKNM"|"HU_SET"|"INREG"|"IOB"|"IOBDELAY"|"IOSTANDARD"|"KEEP"|"KEEPER"|"LOC"|"LOCATE"|"LOCK_PINS"|"MAP"|"MAXDELAY"|"MAXPT"|"MAXSKEW"|"NODELAY"|"NOREDUCE"|"OFFSET"|"OPEN_DRAIN"|"OPT_EFFORT"|"OPTIMIZE"|"PERIOD"|"PIN"|"PRIORITY"|"PROHIBIT"|"PULLDOWN"|"PULLUP"|"PWR_ [...]
+
+%option noyywrap
+%option nounput
+
+%x Bases
+%x ParseType
+%x ParseFuncProto
+%x ParseComponent
+%x ParsePackage
+%x ParseProcessProto
+%x ClassName
+%x PackageName
+%x ClassVar
+%x ClassesName
+%x Map
+%x Body
+
+%%
+
+. {
+ BEGIN(Bases);
+ }
+
+<Map>{BRACEOPEN} {
+ g_braceCount++;
+ writeFont("vhdlchar",vhdlcodeYYtext);
+ BEGIN(Map);
+ }
+
+<Map>[^()\n,--]* { /* write and link a port map lines */
+ QCString tt(vhdlcodeYYtext);
+ VhdlDocGen::deleteAllChars(tt,',');
+ QRegExp r("=>");
+ QStringList ql=QStringList::split(r,tt,FALSE);
+ if (ql.count()>=2)
+ {
+ unsigned int index=0;
+ QCString t1=ql[0].utf8();
+ char cc=t1.at(index);
+ while (cc==' ' || cc=='\t')
+ {
+ char c2[2];
+ c2[0]=cc;
+ c2[1]=0;
+ g_code->codify(c2);
+ index++;
+ if (index>=t1.size()) break;
+ cc=t1.at(index);
+ }
+
+ QCString s1=t1;
+ s1=s1.stripWhiteSpace();
+
+ // if (!g_PortMapComp.isEmpty())
+ generateMemLink(*g_code,g_PortMapComp,s1);
+ while (index++<t1.size())
+ {
+ char cc=t1.at(index);
+ if (cc==' ' || cc=='\t')
+ {
+ char c2[2];
+ c2[0]=cc;
+ c2[1]=0;
+ g_code->codify(c2);
+ }
+ }
+ codifyLines("=>");
+ index=0;
+ QCString s2=ql[1].utf8();
+ t1=s2;
+ cc=t1.at(index);
+ while (cc==' ' || cc=='\t')
+ {
+ char c2[2];
+ c2[0]=cc;
+ c2[1]=0;
+ g_code->codify(c2);
+ index++;
+ if (index>=t1.size()) break;
+ cc=t1.at(index);
+ }
+ s2=s2.stripWhiteSpace();
+ if (!checkVhdlString(s2))
+ generateMemLink(*g_code,g_CurrClass,s2);
+ while (index++<t1.size())
+ {
+ if (t1.at(index)==' ')
+ {
+ g_code->codify(" ");
+ }
+ }
+ }
+ else
+ {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ }
+ BEGIN(Map);
+ }
+
+<Map>"\n"|"," {
+ codifyLines(vhdlcodeYYtext);
+ BEGIN(Map);
+ }
+
+<Map>{BRACECLOSE} {
+ g_braceCount--;
+ writeFont("vhdlchar",vhdlcodeYYtext);
+ if (g_braceCount==0)
+ {
+ BEGIN(Bases);
+ }
+ }
+
+<ParseFuncProto>{NAME} {
+ QCString tmp(vhdlcodeYYtext);
+ tmp=tmp.stripWhiteSpace();
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
+ if (!writeColoredWord(tmp))
+ {
+ generateMemLink(*g_code,g_CurrClass,tmp);
+ }
+ BEGIN(Bases);
+ }
+
+<ParseType>{STRING} {
+ QCString qcs(vhdlcodeYYtext);
+ VhdlDocGen::deleteAllChars(qcs,'"');
+ VhdlDocGen::deleteAllChars(qcs,' ');
+ if (VhdlDocGen::isNumber(qcs))
+ writeFont("vhdllogic",vhdlcodeYYtext);
+ else
+ writeFont("keyword",vhdlcodeYYtext);
+ }
+
+<ParseType>"\n" {
+ g_FuncProto.append(vhdlcodeYYtext);
+ if (isProto)
+ {
+ codifyLines(vhdlcodeYYtext);
+ }
+ BEGIN(ParseType);
+ }
+
+
+<ParseType>{TEXTT} {
+ g_FuncProto.append(vhdlcodeYYtext);
+ if (isProto)
+ {
+ writeFont("keyword",vhdlcodeYYtext);
+ }
+ BEGIN(ParseType);
+ }
+
+<ParseType>{ENDEFUNC} {
+ QRegExp regg("[\\s]");
+ QCString tt(vhdlcodeYYtext);
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ tt=tt.lower();
+ VhdlDocGen::deleteAllChars(tt,';');
+ tt.stripWhiteSpace();
+ QStringList ql=QStringList::split(regg,tt,FALSE);
+ int index=ql.findIndex(QCString("if"))+1;
+ index+=ql.findIndex(QCString("case"))+1;
+ index+=ql.findIndex(QCString("loop"))+1;
+ index+=ql.findIndex(QCString("generate"))+1;
+ if (index==0)
+ {
+ BEGIN(Bases);
+ }
+ else
+ {
+ BEGIN(ParseType);
+ }
+ }
+
+<ParseType>{END1} {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ g_vhdlKeyDict.clear();
+ }
+
+<ParseType>^{B}*("begin "|"begin") {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ isFuncProto=FALSE;
+ }
+
+<ParseType>{SPECSIGN} {
+ g_FuncProto.append(vhdlcodeYYtext);
+ if (isProto)
+ {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ }
+ }
+
+<ParseType>["_a-zA-Z0-9]* {
+ QCString val(vhdlcodeYYtext);
+ g_FuncProto.append(vhdlcodeYYtext);
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+
+ if (isFuncProto && g_braceCount==0)
+ {
+ g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
+ }
+
+ if (isProto)
+ {
+ if (!writeColoredWord(val))
+ {
+ if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
+ {
+ val=val.stripWhiteSpace();
+ if (VhdlDocGen::isNumber(val))
+ {
+ startFontClass("vhdllogic");
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ endFontClass();
+ }
+ else
+ generateMemLink(*g_code,g_CurrClass,val);
+ }
+ else
+ {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ }
+ }
+ }
+ BEGIN(ParseType);
+ }
+
+<ParseType>{BRACEOPEN} {
+ g_braceCount++;
+ g_FuncProto+='(';
+ if (isProto)
+ {
+ writeFont("vhdlchar",vhdlcodeYYtext);
+ }
+ BEGIN(ParseType);
+ }
+
+<ParseType>{BRACECLOSE} {
+ g_braceCount--;
+ g_FuncProto+=')';
+ if (isProto)
+ {
+ writeFont("vhdlchar",vhdlcodeYYtext);
+ }
+ if (g_braceCount==0 && !isProto)// && !isPackageBody)
+ {
+ isProto=TRUE;
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ writeFuncProto();
+ BEGIN(Bases);
+ }
+ if (isPackageBody)
+ {
+ BEGIN(ParseType);
+ }
+ }
+
+
+<ClassesName>{FUNCNAME} {
+ QDict<QCString> mem;
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ g_CurrClass.resize(0);
+ g_CurrClass.append(vhdlcodeYYtext);
+ g_CurrClass=g_CurrClass.stripWhiteSpace();
+
+ if (!writeColoredWord(g_CurrScope))
+ {
+ generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
+ }
+ else
+ {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data());
+ }
+ BEGIN(Bases);
+ }
+
+
+<ParseComponent>{BRACEOPEN} {
+ g_braceCount++;
+ g_code->codify(vhdlcodeYYtext);
+ }
+
+
+<ParseComponent>{BRACECLOSE} {
+ g_braceCount--;
+ g_code->codify(vhdlcodeYYtext);
+ if (g_braceCount==0 && !isComponent)
+ {
+ g_tempComp.resize(0);
+ BEGIN(Bases);
+ }
+ else
+ {
+ BEGIN(ParseComponent);
+ }
+ }
+
+<ParseComponent>{B}*"-" {
+ if (strlen(vhdlcodeYYtext)>=2) // found text ?
+ {
+ writeFont("keyword",vhdlcodeYYtext);
+ }
+ else
+ {
+ writeFont("vhdlchar",vhdlcodeYYtext);
+ }
+ }
+
+<ParseComponent>{SPECSIGN} {
+ codifyLines(vhdlcodeYYtext);
+ }
+
+
+
+<ParseComponent>"\n"|" " {
+ codifyLines(vhdlcodeYYtext);
+ }
+
+<ParseComponent>{DIGITSS} {
+ startFontClass("vhdllogic");
+ codifyLines(vhdlcodeYYtext);
+ endFontClass();
+ }
+
+<ParseComponent>{PORT} {
+ codifyLines(vhdlcodeYYtext);
+ g_braceCount=1;
+ isComponent=FALSE;
+ }
+
+<ParseComponent>{GENERIC} {
+ codifyLines(vhdlcodeYYtext);
+ g_braceCount=1;
+ }
+
+<ParseComponent>[_a-zA_Z][_a-zA-Z0-9]* {
+ QCString temp(vhdlcodeYYtext);
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ if (!checkVhdlString(temp)){
+ if (!writeColoredWord(g_PrevString))
+ {
+ generateMemLink(*g_code,g_tempComp,temp);
+ }
+ }
+ }
+
+<ParseComponent>{STRING} {
+ QCString temp(vhdlcodeYYtext);
+ if (!checkVhdlString(temp))
+ codifyLines(vhdlcodeYYtext);
+ }
+
+
+<ParseProcessProto>[^()]* {
+ g_FuncProto.append(vhdlcodeYYtext);
+ }
+
+
+
+<ParseProcessProto>{BRACEOPEN} {
+ g_FuncProto.append(vhdlcodeYYtext);
+ g_braceCount++;
+ }
+
+<ParseProcessProto>{BRACECLOSE} {
+ g_FuncProto.append(vhdlcodeYYtext);
+ g_braceCount--;
+ if (g_braceCount==0)
+ {
+ writeProcessProto();
+ BEGIN(Bases);
+ }
+ }
+
+<ParsePackage>[^:;]* { //found package
+ QCString temp(vhdlcodeYYtext);
+ QStringList strl=QStringList::split(".",temp,FALSE);
+
+ if (strl.count()>2)
+ {
+ QCString s1=strl[0].utf8();
+ QCString s2=strl[1].utf8();
+ QCString s3=strl[2].utf8();
+ s1.append(".");
+ s3.prepend(".");
+ codifyLines(s1.data(),g_CurrClass.data());
+ ClassDef *cd=VhdlDocGen::getPackageName(s2);
+ if (cd)
+ {
+ generateClassOrGlobalLink(*g_code,s2.data());
+ }
+ else
+ {
+ codifyLines(s2.data());
+ }
+ codifyLines(s3.data());
+ }
+ else
+ {
+ writeFont("keywordflow",vhdlcodeYYtext);
+ }
+ BEGIN(Bases);
+ }
+
+<Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4} { // found port or generic map
+ QCString tt(vhdlcodeYYtext);
+ /*
+ if (tt.contains(':',FALSE))
+ {
+ isStartMap=TRUE;
+ }
+ else
+ {
+ isStartMap=FALSE;
+ }
+ */
+ int j=tt.find('.');
+
+ if (j>0)
+ {
+ QCString left=tt.left(j+1);
+ codifyLines(left.data());
+ tt=tt.right(tt.length()-j-1);
+ left=VhdlDocGen::getIndexWord(tt.data(),0);
+ if (!left.isEmpty())
+ {
+ if (left.contains('('))
+ {
+ j=left.find('(',FALSE);
+ QCString name=left.left(j);
+ generateClassOrGlobalLink(*g_code,name.data());
+ g_PortMapComp=name;
+ name=tt.right(tt.length()-name.length());
+ codifyLines(name.data());
+ }
+ else
+ {
+ generateClassOrGlobalLink(*g_code,left.data());
+ tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
+
+ g_PortMapComp=left;
+ codifyLines(tt.data());
+ }
+ }
+ }
+ else
+ {
+ if (tt.contains(':',FALSE))
+ codifyMapLines(tt.data());
+ else
+ codifyLines(tt.data());
+ }
+ g_braceCount=1;
+ BEGIN(Map);
+ }
+
+<Bases>^{B}*("component"){BN}+{FUNCNAME} { // found component
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ // writeFont("keywordflow",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
+ // writeFont("vhdlkeyword"," ");
+ QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
+ temp=temp.stripWhiteSpace();
+ VhdlDocGen::deleteAllChars(temp,'\n');
+ g_tempComp=temp;
+ codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
+ g_braceCount=0;
+
+ //if (getClass(temp.data()))
+ // generateClassOrGlobalLink(*g_code,temp.data());
+ //else
+ // generateMemLink(*g_code,g_CurrClass,temp);
+
+ isComponent=TRUE;
+ BEGIN(ParseComponent);
+ }
+
+
+
+<Bases>{ARCHITECTURE} { // found architecture
+ g_PortMapComp.resize(0);
+ // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
+ // writeFont("vhdlkeyword"," ");
+ // writeFont("vhdlchar",VhdlDocGen::getIndexWord(vhdlcodeYYtext,1).data());
+ // writeFont("vhdlkeyword"," ");
+ // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,2).data());
+ // writeFont("vhdlkeyword"," ");
+ //QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
+ //temp=temp.stripWhiteSpace();
+ //temp+=("-");
+ //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
+ QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
+ temp+="::";
+ temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
+ g_CurrClass=temp;
+ VhdlDocGen::deleteAllChars(temp,'\n');
+ codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
+ //generateClassOrGlobalLink(*g_code,temp.data());
+ isPackageBody=FALSE;
+ BEGIN(ClassName);
+ }
+
+
+<Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body
+ QCString ss(vhdlcodeYYtext);
+ QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
+ QStringList ql=QStringList::split(temp,ss,FALSE);
+ QCString ll=ql[0].utf8();
+ codifyLines(ll.data(),g_CurrClass.data());
+ temp=temp.stripWhiteSpace();
+ temp.prepend("_");
+ generateClassOrGlobalLink(*g_code,temp.data());
+ g_CurrClass.resize(0);
+ g_CurrClass=temp;
+ isProto=FALSE;
+ isPackageBody=TRUE;
+ // BEGIN(ClassesName);
+ }
+
+<Bases>{PROCESS} { // found process
+ isFuncProto=TRUE;
+ g_FuncProto.resize(0);
+ g_FuncProto.append(vhdlcodeYYtext);
+ g_vhdlKeyDict.clear();
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ if (g_PrevString.contains('('))
+ {
+ g_braceCount=1;
+ BEGIN(ParseProcessProto);
+ }
+ else
+ {
+ writeProcessProto();
+ }
+ }
+
+<Bases>("end"){BN}+("process") { // end of process
+ isFuncProto=FALSE;
+ codifyLines(vhdlcodeYYtext);
+ BEGIN(Bases);
+ }
+
+
+<Bases>^{B}*("begin "|"begin") {
+ isFuncProto=FALSE;
+ writeFont("vhdlkeyword",vhdlcodeYYtext);
+ }
+
+<Bases>^{B}*("use"|"library"){BN}+ { //found package or library
+ writeFont("vhdlkeyword",vhdlcodeYYtext);
+ BEGIN(ParsePackage);
+ }
+
+
+<Bases>^{B}*("use"){BN}+("configuration")[^\n]* {
+ codifyLines(vhdlcodeYYtext);
+ }
+
+
+
+<Bases>{FUNC} { // found function|procedure
+ g_vhdlKeyDict.clear();
+ g_FuncProto.resize(0);
+ isProto=FALSE;
+ g_FuncProto.append(vhdlcodeYYtext);
+ g_braceCount=1;
+ BEGIN(ParseType);
+ }
+
+
+
+<Bases>^{B}*("entity"|"package"){BN}+ {
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ writeFont("keywordflow",vhdlcodeYYtext);
+ isPackageBody=FALSE;
+ BEGIN(ClassesName);
+ }
+
+
+<Bases>{KEYWORD} { // found keyword
+ QCString qcs(vhdlcodeYYtext);
+ if (!writeColoredWord(qcs))
+ {
+ startFontClass("vhdlchar");
+ g_code->codify(vhdlcodeYYtext);
+ endFontClass();
+ }
+ }
+
+
+<Bases>{ID} {
+ appStringLower(g_PrevString,vhdlcodeYYtext);
+ QCString temp(vhdlcodeYYtext);
+ temp=temp.stripWhiteSpace();
+
+ if (!writeColoredWord(temp))
+ {
+ startFontClass("vhdlchar");
+ generateMemLink(*g_code,g_CurrClass,temp);
+ endFontClass();
+ }
+ }
+
+<Bases,ParseComponent>{DIGITSS} {
+ startFontClass("vhdllogic");
+ codifyLines(vhdlcodeYYtext);
+ endFontClass();
+ }
+
+<Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* {
+ codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
+ }
+
+
+<Bases>{TYPEKW} {
+ codifyLines(vhdlcodeYYtext);
+ if (isFuncProto)
+ {
+ BEGIN(ParseFuncProto);
+ }
+ else
+ {
+ BEGIN(Bases);
+ }
+ }
+
+<Bases>{OPERATOR} {
+ startFontClass("vhdlchar");
+ g_code->codify(vhdlcodeYYtext);
+ endFontClass();
+ }
+
+<Bases>","|"."|":"|"'"|"("|")" {
+ startFontClass("vhdlchar");
+ g_code->codify(vhdlcodeYYtext);
+ endFontClass();
+ }
+
+<Bases>{STRING} {
+ QCString qcs(vhdlcodeYYtext);
+ VhdlDocGen::deleteAllChars(qcs,'"');
+ VhdlDocGen::deleteAllChars(qcs,' ');
+
+ if (VhdlDocGen::isNumber(qcs))
+ writeFont("vhdllogic",vhdlcodeYYtext);
+ else
+ writeFont("keyword",vhdlcodeYYtext);
+ }
+
+<Bases>{B}*"#"[^\n]* {
+ writeFont("keyword",vhdlcodeYYtext);
+ }
+
+<Bases>^{B}*{XILINX}[^\n]* {
+ writeWord(yytext);
+ //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
+ }
+
+<Bases>^{B}*"set_"[^\n]* {
+ writeWord(yytext);
+ }
+
+<*>\n {
+ codifyLines(vhdlcodeYYtext);
+ BEGIN(Bases);
+ }
+
+<*>. {
+ g_code->codify(vhdlcodeYYtext);
+ }
+
+<*>\n{TEXTT} { // found normal or special comment on its own line
+ QCString text(vhdlcodeYYtext);
+ int i=text.find("--");
+ if (text.mid(i,3)=="--!" && // hide special comment
+ Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ g_yyLineNr++; // skip complete line
+ }
+ else // normal comment
+ {
+ // startFontClass("keyword");
+ codifyLines(text,0,FALSE,TRUE);
+ // endFontClass();
+ }
+ }
+<*>{TEXTT} { // found normal or special comment after something
+ QCString text(vhdlcodeYYtext);
+ int i=text.find("--");
+ if (text.mid(i,3)=="--!" &&
+ Config_getBool("STRIP_CODE_COMMENTS"))
+ {
+ // hide special comment
+ }
+ else // normal comment
+ {
+ // startFontClass("keyword");
+ codifyLines(text,0,FALSE,TRUE);
+ // endFontClass();
+ }
+ }
+
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+void resetVhdlCodeParserState()
+{
+ g_vhdlKeyDict.setAutoDelete(TRUE);
+ g_vhdlKeyDict.clear();
+}
+
+void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s,
+ bool /*exBlock*/, const char *exName,FileDef *fd,
+ int startLine,int endLine,bool inlineFragment,
+ MemberDef *memberDef,bool,Definition *searchCtx,
+ bool /* collectXRefs */)
+{
+ //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
+ if (s.isEmpty()) return;
+ printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
+ TooltipManager::instance()->clearTooltips();
+ if (memberDef)
+ {
+ ClassDef *dd=memberDef->getClassDef();
+ if (dd) g_CurrClass=dd->name();
+ startLine--;
+ }
+ resetVhdlCodeParserState();
+ g_code = &od;
+ g_inputString = s;
+ g_inputPosition = 0;
+ g_currentFontClass = 0;
+ g_needsTermination = FALSE;
+ g_searchCtx = searchCtx;
+
+ if (endLine!=-1)
+ g_inputLines = endLine+1;
+ else
+ g_inputLines = countLines();
+
+ if (startLine!=-1)
+ g_yyLineNr = startLine;
+ else
+ g_yyLineNr = 1;
+
+
+ // g_theCallContext.clear();
+ g_classScope = className;
+ g_exampleName = exName;
+ g_sourceFileDef = fd;
+ bool cleanupSourceDef = FALSE;
+ if (fd==0)
+ {
+ // create a dummy filedef for the example
+ g_sourceFileDef = new FileDef("",exName);
+ cleanupSourceDef = TRUE;
+ }
+ if (g_sourceFileDef)
+ {
+ setCurrentDoc("l00001");
+ }
+ g_currentDefinition = 0;
+ g_currentMemberDef = 0;
+ g_vhdlMember=0;
+ if (!g_exampleName.isEmpty())
+ {
+ g_exampleFile = convertNameToFile(g_exampleName+"-example");
+ }
+ g_includeCodeFragment = inlineFragment;
+ if (!memberDef)
+ {
+ startCodeLine();
+ }
+ // g_type.resize(0);
+ // g_name.resize(0);
+ // g_args.resize(0);
+ g_parmName.resize(0);
+ g_parmType.resize(0);
+ if(!g_lexInit)
+ VhdlDocGen::init();
+ if (memberDef)
+ {
+ setParameterList(memberDef);
+ }
+ /*int iLine=*/countLines();
+ vhdlcodeYYrestart( vhdlcodeYYin );
+ BEGIN( Bases );
+ vhdlcodeYYlex();
+ g_lexInit=TRUE;
+ if (g_needsTermination)
+ {
+ endCodeLine();
+ }
+ if (fd)
+ {
+ TooltipManager::instance()->writeTooltips(*g_code);
+ }
+ if (cleanupSourceDef)
+ {
+ // delete the temporary file definition used for this example
+ delete g_sourceFileDef;
+ g_sourceFileDef=0;
+ }
+ g_startCode=FALSE;
+ printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
+}
+
+void codeFreeVhdlScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+ if (g_lexInit)
+ {
+ vhdlcodeYYlex_destroy();
+ }
+#endif
+}
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+extern "C" { // some bogus code to keep the compiler happy
+ void vhdlcodeYYdummy() { yy_flex_realloc(0,0); }
+}
+#elif YY_FLEX_SUBMINOR_VERSION<33
+#error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
+#endif
+
+
+
+
diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp
new file mode 100644
index 0000000..0617ea6
--- /dev/null
+++ b/src/vhdldocgen.cpp
@@ -0,0 +1,4483 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/******************************************************************************
+ * Parser for VHDL subset
+ * written by M. Kreis
+ * supports VHDL-87/93/2008
+ * does not support VHDL-AMS
+ ******************************************************************************/
+
+// global includes
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <qcstring.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+//#ifdef DEBUGFLOW
+#include <qmap.h>
+//#endif
+
+/* --------------------------------------------------------------- */
+
+// local includes
+#include "vhdldocgen.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "language.h"
+#include "commentscan.h"
+#include "index.h"
+#include "definition.h"
+#include "searchindex.h"
+#include "outputlist.h"
+#include "parserintf.h"
+
+#include "layout.h"
+#include "arguments.h"
+#include "portable.h"
+#include "memberlist.h"
+#include "memberdef.h"
+#include "groupdef.h"
+#include "classlist.h"
+#include "namespacedef.h"
+#include "filename.h"
+#include "membergroup.h"
+#include "memberdef.h"
+
+#include "vhdljjparser.h"
+#include "VhdlParser.h"
+
+#include "vhdlcode.h"
+#define theTranslator_vhdlType VhdlDocGen::trVhdlType
+
+static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
+static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
+static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
+static QDict<QCString> g_vhdlKeyDict3(17,FALSE);
+static QDict<QCString> g_xilinxUcfDict(17,FALSE);
+
+static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
+static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
+static void assignBinding(VhdlConfNode* conf);
+static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
+
+//---------- create svg -------------------------------------------------------------
+static void createSVG();
+static void startDot(FTextStream &t);
+static void startTable(FTextStream &t,const QCString &className);
+static QList<MemberDef>* getPorts(ClassDef *cd);
+static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
+static void endDot(FTextStream &t);
+static void writeTable(QList<MemberDef>* port,FTextStream & t);
+static void endTabel(FTextStream &t);
+static void writeClassToDot(FTextStream &t,ClassDef* cd);
+static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
+//static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
+static const MemberDef *flowMember=0;
+
+void VhdlDocGen::setFlowMember( const MemberDef* mem)
+{
+ flowMember=mem;
+}
+
+const MemberDef* VhdlDocGen::getFlowMember()
+{
+ return flowMember;
+}
+
+
+
+//--------------------------------------------------------------------------------------------------
+static void codify(FTextStream &t,const char *str)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '<': t << "<";
+ break;
+ case '>': t << ">";
+ break;
+ case '&': t << "&";
+ break;
+ case '\'': t << "'";
+ break;
+ case '"': t << """;
+ break;
+ default: t << c;
+ break;
+ }
+ }
+ }
+}
+
+static void writeLink(const MemberDef* mdef,OutputList &ol)
+{
+ ol.writeObjectLink(mdef->getReference(),
+ mdef->getOutputFileBase(),
+ mdef->anchor(),
+ mdef->name());
+}
+
+static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
+{
+ ol.startFontClass(keyword);
+ ol.docify(q.data());
+ ol.endFontClass();
+}
+
+static QCString splitString(QCString& str,char c)
+{
+ QCString n=str;
+ int i=str.find(c);
+ if (i>0)
+ {
+ n=str.left(i);
+ str=str.remove(0,i+1);
+ }
+ return n;
+}
+
+static int compareString(const QCString& s1,const QCString& s2)
+{
+ return qstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
+}
+
+static void createSVG()
+{
+ QCString ov =Config_getString("HTML_OUTPUT");
+ QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
+ ov+="/vhdl_design.dot";
+
+ QRegExp ep("[\\s]");
+ QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
+
+ if (portable_system("dot",vlargs)!=0)
+ {
+ err("could not create dot file");
+ }
+}
+
+// Creates a svg image. All in/out/inout ports are shown with brief description and direction.
+// Brief descriptions for entities are shown too.
+void VhdlDocGen::writeOverview()
+{
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ bool found=FALSE;
+ for ( ; (cd=cli.current()) ; ++cli )
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )
+ {
+ found=TRUE;
+ break;
+ }
+ }
+
+ if (!found) return;
+
+ QCString ov =Config_getString("HTML_OUTPUT");
+ QCString fileName=ov+"/vhdl_design.dot";
+ QFile f(fileName);
+ QStringList qli;
+ FTextStream t(&f);
+
+ if (!f.open(IO_WriteOnly))
+ {
+ fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
+ return;
+ }
+
+ startDot(t);
+
+ for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
+ {
+ if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS )
+ {
+ continue;
+ }
+
+ QList<MemberDef>* port= getPorts(cd);
+ if (port==0)
+ {
+ continue;
+ }
+ if (port->count()==0)
+ {
+ delete port;
+ port=NULL;
+ continue;
+ }
+
+ startTable(t,cd->name());
+ writeClassToDot(t,cd);
+ writeTable(port,t);
+ endTabel(t);
+
+ // writeVhdlPortToolTip(t,port,cd);
+ writeVhdlEntityToolTip(t,cd);
+ delete port;
+
+ BaseClassList *bl=cd->baseClasses();
+ if (bl)
+ {
+ BaseClassListIterator bcli(*bl);
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ ClassDef *bClass=bcd->classDef;
+ QCString dotn=cd->name()+":";
+ dotn+=cd->name();
+ QCString csc=bClass->name()+":";
+ csc+=bClass->name();
+ // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
+ writeVhdlDotLink(t,dotn,csc,0);
+ }
+ }// if bl
+ }// for
+
+ endDot(t);
+ // writePortLinks(t);
+ f.close();
+ createSVG();
+}
+
+//------------------------------------------------------------------------------------------------------------------------------------------------------
+
+static void startDot(FTextStream &t)
+{
+ t << " digraph G { \n";
+ t << "rankdir=LR \n";
+ t << "concentrate=TRUE\n";
+ t << "stylesheet=\"doxygen.css\"\n";
+}
+
+static void endDot(FTextStream &t)
+{
+ t <<" } \n";
+}
+
+static void startTable(FTextStream &t,const QCString &className)
+{
+ t << className <<" [ shape=none , fontname=\"arial\", fontcolor=\"blue\" , \n";
+ t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
+}
+
+static void writeVhdlDotLink(FTextStream &t,
+ const QCString &a,const QCString &b,const QCString &style)
+{
+ t << a << "->" << b;
+ if (!style.isEmpty())
+ {
+ t << "[style=" << style << "];\n";
+ }
+ t << "\n";
+}
+
+
+static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
+{
+ QRegExp ep("[\n]");
+ QCString vForm;
+ QCString repl("<BR ALIGN=\"LEFT\"/>");
+ QCString file=cd->getDefFileName();
+
+ int k=cd->briefLine();
+
+ QStringList qsl=QStringList::split(ep,brief);
+ for(uint j=0;j<qsl.count();j++)
+ {
+ QCString qcs=qsl[j].data();
+ vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
+ k++;
+ vForm+='\n';
+ }
+
+ vForm.replace(ep,repl.data());
+ return vForm;
+}
+
+#if 0
+static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
+{
+/*
+ uint len=port->count();
+ MemberDef *md;
+
+ for (uint j=0;j<len;j++)
+ {
+ md=(MemberDef*)port->at(j);
+ QCString brief=md->briefDescriptionAsTooltip();
+ if (brief.isEmpty()) continue;
+
+ QCString node="node";
+ node+=VhdlDocGen::getRecordNumber();
+ t << node <<"[shape=box margin=0.1, label=<\n";
+ t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
+ t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
+ t<<brief;
+ t<<" </TD></TR></TABLE>>];";
+ QCString dotn=cd->name()+":";
+ dotn+=md->name();
+ // writeVhdlDotLink(t,dotn,node,"dotted");
+ }
+*/
+}
+#endif
+
+static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd)
+{
+
+ QCString brief=cd->briefDescription();
+
+ if (brief.isEmpty()) return;
+
+ brief=formatBriefNote(brief,cd);
+
+ QCString node="node";
+ node+=VhdlDocGen::getRecordNumber();
+ t << node <<"[shape=none margin=0.1, label=<\n";
+ t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
+ t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
+ t << brief;
+ t << " </TD></TR></TABLE>>];";
+ QCString dotn=cd->name()+":";
+ dotn+=cd->name();
+ writeVhdlDotLink(t,dotn,node,"dotted");
+}
+
+static void writeColumn(FTextStream &t,MemberDef *md,bool start)
+{
+ QCString toolTip;
+
+ static QRegExp reg("[%]");
+ bool bidir=(md!=0 &&( qstricmp(md->typeString(),"inout")==0));
+
+ if (md)
+ {
+ toolTip=md->briefDescriptionAsTooltip();
+ if (!toolTip.isEmpty())
+ {
+ QCString largs = md->argsString();
+ if (!largs.isEmpty())
+ largs=largs.replace(reg," ");
+ toolTip+=" [";
+ toolTip+=largs;
+ toolTip+="]";
+ }
+ }
+ if (start)
+ {
+ t <<"<TR>\n";
+ }
+
+ t << "<TD ALIGN=\"LEFT\" ";
+ if (md)
+ {
+ t << "href=\"";
+ t << md->getOutputFileBase()<< Doxygen::htmlFileExtension;
+ t << "#" << md->anchor();
+ t<<"\" ";
+
+ t<<" TOOLTIP=\"";
+ if (!toolTip.isEmpty())
+ {
+ codify(t,toolTip.data());
+ }
+ else
+ {
+ QCString largs = md->argsString();
+ if (!largs.isEmpty())
+ {
+ largs=largs.replace(reg," ");
+ codify(t,largs.data());
+ }
+ }
+ t << "\" ";
+
+ t << " PORT=\"";
+ t << md->name();
+ t << "\" ";
+ }
+ if (!toolTip.isEmpty())
+ {
+ // if (!toolTip.isEmpty())
+
+ if (bidir)
+ t << "BGCOLOR=\"orange\">";
+ else
+ t << "BGCOLOR=\"azure\">";
+ }
+ else if (bidir)
+ {
+ t << "BGCOLOR=\"pink\">";
+ }
+ else
+ {
+ t << "BGCOLOR=\"lightgrey\">";
+ }
+ if (md)
+ {
+ t << md->name();
+ }
+ else
+ {
+ t << " \n";
+ }
+ t << "</TD>\n";
+
+ if (!start)
+ {
+ t << "</TR>\n";
+ }
+}
+
+static void endTabel(FTextStream &t)
+{
+ t << "</TABLE>>\n";
+ t << "] \n";
+}
+
+static void writeClassToDot(FTextStream &t,ClassDef* cd)
+{
+ t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
+ t << "PORT=\"";
+ t << cd->name();
+ t << "\" ";
+ t << "href=\"";
+ t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
+ t << "\" ";
+ t << ">";
+ t << cd->name();
+ t << " </TD></TR>\n";
+}
+
+static QList<MemberDef>* getPorts(ClassDef *cd)
+{
+ MemberDef* md;
+ QList<MemberDef> *portList=new QList<MemberDef>;
+ MemberList *ml=cd->getMemberList(MemberListType_variableMembers);
+
+ if (ml==0) return NULL;
+
+ MemberListIterator fmni(*ml);
+
+ for (fmni.toFirst();(md=fmni.current());++fmni)
+ {
+ if (md->getMemberSpecifiers()==VhdlDocGen::PORT)
+ {
+ portList->append(md);
+ }
+ }
+
+ return portList;
+}
+
+//writeColumn(FTextStream &t,QCString name,bool start)
+
+static void writeTable(QList<MemberDef>* port,FTextStream & t)
+{
+ QCString space(" ");
+ MemberDef *md;
+ uint len=port->count();
+
+ QList<MemberDef> inPorts;
+ QList<MemberDef> outPorts;
+
+ uint j;
+ for (j=0;j<len;j++)
+ {
+ md=(MemberDef*)port->at(j);
+ QCString qc=md->typeString();
+ if(qc=="in")
+ {
+ inPorts.append(md);
+ }
+ else
+ {
+ outPorts.append(md);
+ }
+ }
+
+ int inp = inPorts.count();
+ int outp = outPorts.count();
+ int maxLen;
+
+ if (inp>=outp)
+ {
+ maxLen=inp;
+ }
+ else
+ {
+ maxLen=outp;
+ }
+
+ int i;
+ for(i=0;i<maxLen;i++)
+ {
+ //write inports
+ if (i<inp)
+ {
+ md=(MemberDef*)inPorts.at(i);
+ writeColumn(t,md,TRUE);
+ }
+ else
+ {
+ writeColumn(t,NULL,TRUE);
+ }
+
+ if (i<outp)
+ {
+ md=(MemberDef*)outPorts.at(i);
+ writeColumn(t,md,FALSE);
+ }
+ else
+ {
+ writeColumn(t,NULL,FALSE);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+
+
+VhdlDocGen::VhdlDocGen()
+{
+}
+
+VhdlDocGen::~VhdlDocGen()
+{
+}
+
+void VhdlDocGen::init()
+{
+
+ // vhdl keywords inlcuded VHDL 2008
+const char* g_vhdlKeyWordMap0[] =
+{
+ "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
+ "begin","block","body","buffer","bus",
+ "case","component","configuration","constant","context","cover",
+ "default","disconnect","downto",
+ "else","elsif","end","entity","exit",
+ "fairness","file","for","force","function",
+ "generate","generic","group","guarded",
+ "if","impure","in","inertial","inout","is",
+ "label","library","linkage","literal","loop",
+ "map","mod",
+ "nand","new","next","nor","not","null",
+ "of","on","open","or","others","out",
+ "package","parameter","port","postponed","procedure","process","property","proctected","pure",
+ "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
+ "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
+ "then","to","transport","type",
+ "unaffected","units","until","use",
+ "variable","vmode","vprop","vunit",
+ "wait","when","while","with",
+ "xor","xnor",
+ 0
+};
+
+
+// type
+const char* g_vhdlKeyWordMap1[] =
+{
+ "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
+ "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
+ "real","float","ufixed","sfixed","time",0
+};
+
+// logic
+const char* g_vhdlKeyWordMap2[] =
+{
+ "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
+ "sll",0
+};
+
+// predefined attributes
+const char* g_vhdlKeyWordMap3[] =
+{
+"base","left","right","high","low","ascending",
+"image","value","pos","val","succ","pred","leftof","rightof","left","right","high","low",
+"range","reverse_range","length","ascending","delayed","stable","quiet","transaction","event",
+"active","last_event","last_active","last_value","driving","driving_value","simple_name","instance_name","path_name",0
+};
+
+ int j=0;
+ g_vhdlKeyDict0.setAutoDelete(TRUE);
+ g_vhdlKeyDict1.setAutoDelete(TRUE);
+ g_vhdlKeyDict2.setAutoDelete(TRUE);
+ g_vhdlKeyDict3.setAutoDelete(TRUE);
+
+ while (g_vhdlKeyWordMap0[j])
+ {
+ g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
+ new QCString(g_vhdlKeyWordMap0[j]));
+ j++;
+ }
+
+ j=0;
+ while (g_vhdlKeyWordMap1[j])
+ {
+ g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
+ new QCString(g_vhdlKeyWordMap1[j]));
+ j++;
+ }
+
+ j=0;
+ while (g_vhdlKeyWordMap2[j])
+ {
+ g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
+ new QCString(g_vhdlKeyWordMap2[j]));
+ j++;
+ }
+
+ j=0;
+ while (g_vhdlKeyWordMap3[j])
+ {
+ g_vhdlKeyDict3.insert(g_vhdlKeyWordMap3[j],
+ new QCString(g_vhdlKeyWordMap3[j]));
+ j++;
+ }
+
+}// buildKeyMap
+
+/*!
+ * returns the color of a keyword
+ */
+
+QCString* VhdlDocGen::findKeyWord(const QCString& tmp)
+{
+ static QCString vhdlkeyword("vhdlkeyword");
+ static QCString vhdltype("comment");
+ static QCString vhdllogic("vhdllogic");
+ static QCString preprocessor("keywordflow");
+
+ QCString word=tmp.lower();
+
+ if (word.isEmpty() || word.at(0)=='\0') return 0;
+
+ if (g_vhdlKeyDict0.find(word))
+ return &preprocessor;
+
+ if (g_vhdlKeyDict1.find(word))
+ return &vhdltype;
+
+ if (g_vhdlKeyDict2.find(word))
+ return &vhdllogic;
+
+ if (g_vhdlKeyDict3.find(word))
+ return &vhdlkeyword;
+
+ return 0;
+}
+
+ClassDef *VhdlDocGen::getClass(const char *name)
+{
+ if (name==0 || name[0]=='\0') return 0;
+
+ ClassDef *cd=0;
+ QCString temp(name);
+ //temp=temp.lower();
+ temp=temp.stripWhiteSpace();
+ cd= Doxygen::classSDict->find(temp.data());
+ return cd;
+}
+
+ClassDef* VhdlDocGen::getPackageName(const QCString & name)
+{
+ ClassDef* cd=0;
+ QStringList ql=QStringList::split(".",name,FALSE);
+ cd=getClass(name);
+
+ return cd;
+}
+
+static QMap<QCString,MemberDef*> varMap;
+static QList<ClassDef> qli;
+static QMap<ClassDef*,QList<ClassDef> > packages;
+
+MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
+{
+ ClassDef* cd,*ecd;
+ MemberDef *mdef=0;
+
+ cd=getClass(className);
+ //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
+ if (cd==0) return 0;
+
+ mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_variableMembers);
+ if (mdef) return mdef;
+ mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
+ if (mdef) return mdef;
+
+ // nothing found so far
+ // if we are an architecture or package body search in entitiy
+
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ {
+ Definition *d = cd->getOuterScope();
+ // searching upper/lower case names
+
+ QCString tt=d->name();
+ ecd =getClass(tt);
+ if (!ecd)
+ {
+ tt=tt.upper();
+ ecd =getClass(tt);
+ }
+ if (!ecd)
+ {
+ tt=tt.lower();
+ ecd =getClass(tt);
+ }
+
+ if (ecd) //d && d->definitionType()==Definition::TypeClass)
+ {
+ //ClassDef *ecd = (ClassDef*)d;
+ mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberListType_variableMembers);
+ if (mdef) return mdef;
+ mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
+ if (mdef) return mdef;
+ }
+ }
+
+
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
+ (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ {
+ Definition *d = cd->getOuterScope();
+
+ QCString tt=d->name();
+ ClassDef *ecd =getClass(tt);
+ if (!ecd)
+ {
+ tt=tt.upper();
+ ecd =getClass(tt);
+ }
+ if (!ecd)
+ {
+ tt=tt.lower();
+ ecd =getClass(tt);
+ }
+ if (ecd) //d && d->definitionType()==Definition::TypeClass)
+ {
+ if(!packages.contains(ecd))
+ {
+ VhdlDocGen::findAllPackages(ecd);
+ }
+ }
+ }
+ else
+ {
+ ecd=cd;
+ if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
+ }
+
+ uint len=packages.count();
+ for (uint j=0;j<len;j++)
+ {
+ for (QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.begin();cList != packages.end();cList++)
+ {
+ if (cList.key()==0) continue;
+ QList<ClassDef> mlist=cList.data();
+ for (uint j=0;j<mlist.count();j++)
+ {
+ mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_variableMembers);
+ if (mdef) return mdef;
+ mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
+ if (mdef) return mdef;
+ }
+ }
+ }
+ return 0;
+
+}//findMember
+
+/**
+ * This function returns the entity|package
+ * in which the key (type) is found
+ */
+MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberListType type)
+{
+ MemberDef *md=0;
+ MemberList *ml=0;
+ QCString keyType=cd->symbolName()+"@"+key;
+ //printf("\n %s | %s | %s",cd->symbolName().data(),key.data(,),keyType.data());
+
+ QMap<QCString, MemberDef*>::Iterator it =varMap.find(keyType);
+ if (it.key())
+ {
+ md=it.data();
+ if (md)
+ {
+ return md;
+ }
+ }
+ if (qli.contains(cd))
+ {
+ return 0;
+ }
+ ml=cd->getMemberList(type);
+ qli.append(cd);
+ if (!ml)
+ {
+ return 0;
+ }
+ MemberListIterator fmni(*ml);
+ //int l=ml->count();
+ // fprintf(stderr,"\n loading enity %s %s: %d",cd->symbolName().data(),keyType.data(),l);
+
+ for (fmni.toFirst();(md=fmni.current());++fmni)
+ {
+ QCString tkey=cd->symbolName()+"@"+md->name();
+ if (varMap.contains(tkey))
+ {
+ continue;
+ }
+ varMap.insert(tkey.data(),md);
+ }
+ it=varMap.find(keyType.data());
+ if (it.key())
+ {
+ md=it.data();
+ if (md)
+ {
+ return md;
+ }
+ }
+ return 0;
+}//findMemberDef
+
+/*!
+ * finds all included packages of an Entity or Package
+ */
+
+void VhdlDocGen::findAllPackages( ClassDef *cdef)
+{
+ QList<ClassDef> cList;
+ if (packages.contains(cdef)) return;
+ MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
+ MemberDef *md;
+
+ if (!mem) return;
+
+ MemberListIterator fmni(*mem);
+ for (fmni.toFirst();(md=fmni.current());++fmni)
+ {
+ if (VhdlDocGen::isPackage(md))
+ {
+ ClassDef* cd=VhdlDocGen::getPackageName(md->name());
+ if (cd)
+ {
+ cList.append(cd);
+ VhdlDocGen::findAllPackages(cd);
+ packages.insert(cdef,cList);
+ }
+ }
+ }//for
+
+}// findAllPackages
+
+/*!
+ * returns the function with the matching argument list
+ * is called in vhdlcode.l
+ */
+
+MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
+ const QCString& funcname,
+ const QCString& package, bool /*type*/)
+{
+ MemberDef* mdef=0;
+ //int funcType;
+ ClassDef *cdef=getClass(package.data());
+ if (cdef==0) return 0;
+
+ MemberList *mem=cdef->getMemberList(MemberListType_pubMethods);
+
+ if (mem)
+ {
+ MemberListIterator fmni(*mem);
+ for (fmni.toFirst();(mdef=fmni.current());++fmni)
+ {
+ QCString mname=mdef->name();
+ if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
+ {
+ ArgumentList *alp = mdef->argumentList();
+
+ // ArgumentList* arg2=mdef->getArgumentList();
+ if (alp==0) break;
+ ArgumentListIterator ali(*alp);
+ ArgumentListIterator ali1(ql);
+
+ if (ali.count() != ali1.count()) break;
+
+ Argument *arg,*arg1;
+ int equ=0;
+
+ for (;(arg=ali.current());++ali)
+ {
+ arg1=ali1.current(); ++ali1;
+ equ+=abs(compareString(arg->type,arg1->type));
+
+ QCString s1=arg->type;
+ QCString s2=arg1->type;
+ VhdlDocGen::deleteAllChars(s1,' ');
+ VhdlDocGen::deleteAllChars(s2,' ');
+ equ+=abs(compareString(s1,s2));
+ s1=arg->attrib;
+ s2=arg1->attrib;
+ VhdlDocGen::deleteAllChars(s1,' ');
+ VhdlDocGen::deleteAllChars(s2,' ');
+ equ+=abs(compareString(s1,s2));
+ // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
+ // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
+ } // for
+ if (equ==0) return mdef;
+ }//if
+ }//for
+ }//if
+ return mdef;
+} //findFunction
+
+
+
+
+/*!
+ * returns the class title+ref
+ */
+
+QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
+{
+ QCString pageTitle;
+ if (cd==0) return "";
+ pageTitle+=cd->displayName();
+ pageTitle=VhdlDocGen::getClassName(cd);
+ int ii=cd->protection();
+ pageTitle+=" ";
+ pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
+ pageTitle+=" ";
+ return pageTitle;
+} // getClassTitle
+
+/* returns the class name without their prefixes */
+
+QCString VhdlDocGen::getClassName(const ClassDef* cd)
+{
+ QCString temp;
+ if (cd==0) return "";
+
+ if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
+ {
+ temp=cd->name();
+ temp.stripPrefix("_");
+ return temp;
+ }
+
+ return substitute(cd->className(),"::",".");
+}
+
+/*!
+ * writes an inline link form entity|package to architecture|package body and vice verca
+ */
+
+void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol)
+{
+ QList<QCString> ql;
+ ql.setAutoDelete(TRUE);
+ QCString nn=cd->className();
+ int ii=(int)cd->protection()+2;
+
+ QCString type;
+ if (ii==VhdlDocGen::ENTITY)
+ type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE);
+ else if (ii==VhdlDocGen::ARCHITECTURE)
+ type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE);
+ else if (ii==VhdlDocGen::PACKAGE_BODY)
+ type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
+ else if (ii==VhdlDocGen::PACKAGE)
+ type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE);
+ else
+ type+="";
+
+ //type=type.lower();
+ type+=" >> ";
+ ol.disable(OutputGenerator::RTF);
+ ol.disable(OutputGenerator::Man);
+
+ if (ii==VhdlDocGen::PACKAGE_BODY)
+ {
+ nn.stripPrefix("_");
+ cd=getClass(nn.data());
+ }
+ else if (ii==VhdlDocGen::PACKAGE)
+ {
+ nn.prepend("_");
+ cd=getClass(nn.data());
+ }
+ else if (ii==VhdlDocGen::ARCHITECTURE)
+ {
+ QStringList qlist=QStringList::split("-",nn,FALSE);
+ nn=qlist[1].utf8();
+ cd=VhdlDocGen::getClass(nn.data());
+ }
+
+ QCString opp;
+ if (ii==VhdlDocGen::ENTITY)
+ {
+ VhdlDocGen::findAllArchitectures(ql,cd);
+ int j=ql.count();
+ for (int i=0;i<j;i++)
+ {
+ QCString *temp=ql.at(i);
+ QStringList qlist=QStringList::split("-",*temp,FALSE);
+ QCString s1=qlist[0].utf8();
+ QCString s2=qlist[1].utf8();
+ s1.stripPrefix("_");
+ if (j==1) s1.resize(0);
+ ClassDef*cc = getClass(temp->data());
+ if (cc)
+ {
+ VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
+ }
+ }
+ }
+ else
+ {
+ VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
+ }
+
+ ol.enable(OutputGenerator::Man);
+ ol.enable(OutputGenerator::RTF);
+
+}// write
+
+/*
+ * finds all architectures which belongs to an entiy
+ */
+void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
+{
+ ClassDef *citer;
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ for ( ; (citer=cli.current()) ; ++cli )
+ {
+ QCString jj=citer->className();
+ if (cd != citer && jj.contains('-')!=-1)
+ {
+ QStringList ql=QStringList::split("-",jj,FALSE);
+ QCString temp=ql[1].utf8();
+ if (qstricmp(cd->className(),temp)==0)
+ {
+ QCString *cl=new QCString(jj);
+ qll.insert(0,cl);
+ }
+ }
+ }// for
+}//findAllArchitectures
+
+ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd)
+{
+ ClassDef *citer;
+ QCString nn=cd->name();
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+
+ for ( ; (citer=cli.current()) ; ++cli )
+ {
+ QCString jj=citer->name();
+ QStringList ql=QStringList::split(":",jj,FALSE);
+ if (ql.count()>1)
+ {
+ if (ql[0].utf8()==nn )
+ {
+ return citer;
+ }
+ }
+ }
+ return 0;
+}
+/*
+ * writes the link entity >> .... or architecture >> ...
+ */
+
+void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
+{
+ if (ccd==0) return;
+ QCString temp=ccd->getOutputFileBase();
+ ol.startBold();
+ ol.docify(type.data());
+ ol.endBold();
+ nn.stripPrefix("_");
+ ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
+
+ if (!behav.isEmpty())
+ {
+ behav.prepend(" ");
+ ol.startBold();
+ ol.docify(behav.data());
+ ol.endBold();
+ }
+
+ ol.lineBreak();
+}
+
+
+/*!
+ * strips the "--" prefixes of vhdl comments
+ */
+void VhdlDocGen::prepareComment(QCString& qcs)
+{
+ const char* s="--!";
+ int index=0;
+
+ while (TRUE)
+ {
+ index=qcs.find(s,0,TRUE);
+ if (index<0) break;
+ qcs=qcs.remove(index,qstrlen(s));
+ }
+ qcs=qcs.stripWhiteSpace();
+}
+
+
+/*!
+ * parses a function proto
+ * @param text function string
+ * @param qlist stores the function types
+ * @param name points to the function name
+ * @param ret Stores the return type
+ * @param doc ???
+ */
+void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
+ QCString& name,QCString& ret,bool doc)
+{
+ (void)qlist; //unused
+ int index,end;
+ QCString s1(text);
+ QCString temp;
+
+ index=s1.find("(");
+ end=s1.findRev(")");
+
+ if ((end-index)>0)
+ {
+ QCString tt=s1.mid(index,(end-index+1));
+ temp=s1.mid(index+1,(end-index-1));
+ //getFuncParams(qlist,temp);
+ }
+ if (doc)
+ {
+ name=s1.left(index);
+ name=name.stripWhiteSpace();
+ if ((end-index)>0)
+ {
+ ret="function";
+ }
+ return;
+ }
+ else
+ {
+ QCString s1(text);
+ s1=s1.stripWhiteSpace();
+ int i=s1.find("(",0,FALSE);
+ int s=s1.find(QRegExp("[ \\t]"));
+ if (i==-1 || i<s)
+ s1=VhdlDocGen::getIndexWord(s1.data(),1);
+ else // s<i, s=start of name, i=end of name
+ s1=s1.mid(s,(i-s));
+
+ name=s1.stripWhiteSpace();
+ }
+ index=s1.findRev("return",-1,FALSE);
+ if (index !=-1)
+ {
+ ret=s1.mid(index+6,s1.length());
+ ret=ret.stripWhiteSpace();
+ VhdlDocGen::deleteCharRev(ret,';');
+ }
+}
+
+/*
+ * returns the n'th word of a string
+ */
+
+QCString VhdlDocGen::getIndexWord(const char* c,int index)
+{
+ QStringList ql;
+ QCString temp(c);
+ QRegExp reg("[\\s:|]");
+
+ ql=QStringList::split(reg,temp,FALSE);
+
+ if (ql.count() > (unsigned int)index)
+ {
+ return ql[index].utf8();
+ }
+
+ return "";
+}
+
+
+QCString VhdlDocGen::getProtectionName(int prot)
+{
+ if (prot==VhdlDocGen::ENTITYCLASS)
+ return "entity";
+ else if (prot==VhdlDocGen::ARCHITECTURECLASS)
+ return "architecture";
+ else if (prot==VhdlDocGen::PACKAGECLASS)
+ return "package";
+ else if (prot==VhdlDocGen::PACKBODYCLASS)
+ return "package body";
+
+ return "";
+}
+
+QCString VhdlDocGen::trTypeString(uint64 type)
+{
+ switch(type)
+ {
+ case VhdlDocGen::LIBRARY: return "Library";
+ case VhdlDocGen::ENTITY: return "Entity";
+ case VhdlDocGen::PACKAGE_BODY: return "Package Body";
+ case VhdlDocGen::ATTRIBUTE: return "Attribute";
+ case VhdlDocGen::PACKAGE: return "Package";
+ case VhdlDocGen::SIGNAL: return "Signal";
+ case VhdlDocGen::COMPONENT: return "Component";
+ case VhdlDocGen::CONSTANT: return "Constant";
+ case VhdlDocGen::TYPE: return "Type";
+ case VhdlDocGen::SUBTYPE: return "Subtype";
+ case VhdlDocGen::FUNCTION: return "Function";
+ case VhdlDocGen::RECORD: return "Record";
+ case VhdlDocGen::PROCEDURE: return "Procedure";
+ case VhdlDocGen::ARCHITECTURE: return "Architecture";
+ case VhdlDocGen::USE: return "Package";
+ case VhdlDocGen::PROCESS: return "Process";
+ case VhdlDocGen::PORT: return "Port";
+ case VhdlDocGen::GENERIC: return "Generic";
+ case VhdlDocGen::UNITS: return "Units";
+ //case VhdlDocGen::PORTMAP: return "Port Map";
+ case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
+ case VhdlDocGen::GROUP: return "Group";
+ case VhdlDocGen::VFILE: return "File";
+ case VhdlDocGen::INSTANTIATION: return "Instantiation";
+ case VhdlDocGen::ALIAS: return "Alias";
+ case VhdlDocGen::CONFIG: return "Configuration";
+ case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous";
+ case VhdlDocGen::UCF_CONST: return "Constraints";
+ default: return "";
+ }
+} // convertType
+
+/*!
+ * deletes a char backwards in a string
+ */
+
+bool VhdlDocGen::deleteCharRev(QCString &s,char c)
+{
+ int index=s.findRev(c,-1,FALSE);
+ if (index > -1)
+ {
+ QCString qcs=s.remove(index,1);
+ s=qcs;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void VhdlDocGen::deleteAllChars(QCString &s,char c)
+{
+ int index=s.findRev(c,-1,FALSE);
+ while (index > -1)
+ {
+ QCString qcs=s.remove(index,1);
+ s=qcs;
+ index=s.findRev(c,-1,FALSE);
+ }
+}
+
+
+static int recordCounter=0;
+
+/*!
+ * returns the next number of a record|unit member
+ */
+
+QCString VhdlDocGen::getRecordNumber()
+{
+ char buf[12];
+ sprintf(buf,"%d",recordCounter++);
+ QCString qcs(&buf[0]);
+ return qcs;
+}
+
+/*!
+ * returns the next number of an anonymous process
+ */
+
+QCString VhdlDocGen::getProcessNumber()
+{
+ static int stringCounter;
+ char buf[8];
+ QCString qcs("PROCESS_");
+ sprintf(buf,"%d",stringCounter++);
+ qcs.append(&buf[0]);
+ return qcs;
+}
+
+/*!
+ * writes a colored and formatted string
+ */
+
+void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
+{
+ QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
+ QCString qcs = s;
+ qcs+=QCString(" ");// parsing the last sign
+ QCString *ss;
+ QCString find=qcs;
+ QCString temp=qcs;
+ char buf[2];
+ buf[1]='\0';
+
+ int j;
+ int len;
+ j = reg.match(temp.data(),0,&len);
+
+ ol.startBold();
+ if (j>=0)
+ {
+ while (j>=0)
+ {
+ find=find.left(j);
+ buf[0]=temp[j];
+ ss=VhdlDocGen::findKeyWord(find);
+ bool k=isNumber(find); // is this a number
+ if (k)
+ {
+ ol.docify(" ");
+ startFonts(find,"vhdldigit",ol);
+ ol.docify(" ");
+ }
+ else if (j != 0 && ss)
+ {
+ startFonts(find,ss->data(),ol);
+ }
+ else
+ {
+ if (j>0)
+ {
+ VhdlDocGen::writeStringLink(mdef,find,ol);
+ }
+ }
+ startFonts(&buf[0],"vhdlchar",ol);
+
+ QCString st=temp.remove(0,j+1);
+ find=st;
+ if (!find.isEmpty() && find.at(0)=='"')
+ {
+ int ii=find.find('"',2);
+ if (ii>1)
+ {
+ QCString com=find.left(ii+1);
+ startFonts(com,"keyword",ol);
+ temp=find.remove(0,ii+1);
+ }
+ }
+ else
+ {
+ temp=st;
+ }
+ j = reg.match(temp.data(),0,&len);
+ }//while
+ }//if
+ else
+ {
+ startFonts(find,"vhdlchar",ol);
+ }
+ ol.endBold();
+}// writeFormatString
+
+/*!
+ * returns TRUE if this string is a number
+ */
+bool VhdlDocGen::isNumber(const QCString& s)
+{
+ static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
+
+ if (s.isEmpty()) return FALSE;
+ int j,len;
+ j = regg.match(s.data(),0,&len);
+ if ((j==0) && (len==(int)s.length())) return TRUE;
+ return FALSE;
+
+}// isNumber
+
+
+/*!
+ * inserts white spaces for better readings
+ * and writes a colored string to the output
+ */
+
+void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
+{
+ QCString qcs = s;
+ QCString temp(qcs.length());
+ qcs.stripPrefix(":");
+ qcs.stripPrefix("is");
+ qcs.stripPrefix("IS");
+ qcs.stripPrefix("of");
+ qcs.stripPrefix("OF");
+
+ // VhdlDocGen::deleteCharRev(qcs,';');
+ //char white='\t';
+ int len = qcs.length();
+ unsigned int index=1;//temp.length();
+
+ for (int j=0;j<len;j++)
+ {
+ char c=qcs[j];
+ char b=c;
+ if (j>0) b=qcs[j-1];
+ if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
+ {
+ if (temp.at(index-1) != ' ')
+ {
+ temp+=" ";
+ }
+ temp+=c;
+ temp+=" ";
+ }
+ else if (c=='=')
+ {
+ if (b==':') // := operator
+ {
+ temp.replace(index-1,1,"=");
+ temp+=" ";
+ }
+ else // = operator
+ {
+ temp+=" ";
+ temp+=c;
+ temp+=" ";
+ }
+ }
+ else
+ {
+ temp+=c;
+ }
+
+ index=temp.length();
+ }// for
+ temp=temp.stripWhiteSpace();
+ // printf("\n [%s]",qcs.data());
+ VhdlDocGen::writeFormatString(temp,ol,mdef);
+}
+
+/*!
+ * writes a procedure prototype to the output
+ */
+
+void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
+{
+ ArgumentListIterator ali(*al);
+ Argument *arg;
+ bool sem=FALSE;
+ int len=al->count();
+ ol.docify("( ");
+ if (len > 2)
+ {
+ ol.lineBreak();
+ }
+ for (;(arg=ali.current());++ali)
+ {
+ ol.startBold();
+ if (sem && len <3)
+ ol.writeChar(',');
+
+ QCString nn=arg->name;
+ nn+=": ";
+
+ QCString *str=VhdlDocGen::findKeyWord(arg->defval);
+ arg->defval+=" ";
+ if (str)
+ {
+ startFonts(arg->defval,str->data(),ol);
+ }
+ else
+ {
+ startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
+ }
+
+ startFonts(nn,"vhdlchar",ol); // write name
+ if (qstricmp(arg->attrib,arg->type) != 0)
+ {
+ startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
+ }
+ ol.docify(" ");
+ VhdlDocGen::formatString(arg->type,ol,mdef);
+ sem=TRUE;
+ ol.endBold();
+ if (len > 2)
+ {
+ ol.lineBreak();
+ ol.docify(" ");
+ }
+ }//for
+
+ ol.docify(" )");
+
+
+}
+
+/*!
+ * writes a function prototype to the output
+ */
+
+void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
+{
+ if (al==0) return;
+ ArgumentListIterator ali(*al);
+ Argument *arg;
+ bool sem=FALSE;
+ int len=al->count();
+ ol.startBold();
+ ol.docify(" ( ");
+ ol.endBold();
+ if (len>2)
+ {
+ ol.lineBreak();
+ }
+ for (;(arg=ali.current());++ali)
+ {
+ ol.startBold();
+ QCString att=arg->defval;
+ bool bGen=att.stripPrefix("gen!");
+
+ if (sem && len < 3)
+ {
+ ol.docify(" , ");
+ }
+
+ if (bGen)
+ {
+ VhdlDocGen::formatString(QCString("generic "),ol,mdef);
+ }
+ if (!att.isEmpty())
+ {
+ QCString *str=VhdlDocGen::findKeyWord(att);
+ att+=" ";
+ if (str)
+ VhdlDocGen::formatString(att,ol,mdef);
+ else
+ startFonts(att,"vhdlchar",ol);
+ }
+
+ QCString nn=arg->name;
+ nn+=": ";
+ QCString ss=arg->type.stripWhiteSpace(); //.lower();
+ QCString w=ss.stripWhiteSpace();//.upper();
+ startFonts(nn,"vhdlchar",ol);
+ startFonts("in ","stringliteral",ol);
+ QCString *str=VhdlDocGen::findKeyWord(ss);
+ if (str)
+ VhdlDocGen::formatString(w,ol,mdef);
+ else
+ startFonts(w,"vhdlchar",ol);
+
+ if (arg->attrib)
+ startFonts(arg->attrib,"vhdlchar",ol);
+
+
+ sem=TRUE;
+ ol.endBold();
+ if (len > 2)
+ {
+ ol.lineBreak();
+ }
+ }
+ ol.startBold();
+ ol.docify(" )");
+ const char *exp=mdef->excpString();
+ if (exp)
+ {
+ ol.insertMemberAlign();
+ ol.startBold();
+ ol.docify("[ ");
+ ol.docify(exp);
+ ol.docify(" ]");
+ ol.endBold();
+ }
+ ol.endBold();
+}
+
+/*!
+ * writes a process prototype to the output
+ */
+
+void VhdlDocGen::writeProcessProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
+{
+ if (al==0) return;
+ ArgumentListIterator ali(*al);
+ Argument *arg;
+ bool sem=FALSE;
+ ol.startBold();
+ ol.docify(" ( ");
+ for (;(arg=ali.current());++ali)
+ {
+ if (sem)
+ {
+ ol.docify(" , ");
+ }
+ QCString nn=arg->name;
+ // startFonts(nn,"vhdlchar",ol);
+ VhdlDocGen::writeFormatString(nn,ol,mdef);
+ sem=TRUE;
+ }
+ ol.docify(" )");
+ ol.endBold();
+}
+
+
+/*!
+ * writes a function|procedure documentation to the output
+ */
+
+bool VhdlDocGen::writeFuncProcDocu(
+ const MemberDef *md,
+ OutputList& ol,
+ const ArgumentList* al,
+ bool /*type*/)
+{
+ if (al==0) return FALSE;
+ //bool sem=FALSE;
+ ol.enableAll();
+
+ ArgumentListIterator ali(*al);
+ int index=ali.count();
+ if (index==0)
+ {
+ ol.docify(" ( ) ");
+ return FALSE;
+ }
+ ol.endMemberDocName();
+ ol.startParameterList(TRUE);
+ //ol.startParameterName(FALSE);
+ Argument *arg;
+ bool first=TRUE;
+ for (;(arg=ali.current());++ali)
+ {
+ ol.startParameterType(first,"");
+ // if (first) ol.writeChar('(');
+ QCString attl=arg->defval;
+ bool bGen=attl.stripPrefix("gen!");
+ if (bGen)
+ VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
+
+
+ if (VhdlDocGen::isProcedure(md))
+ {
+ startFonts(arg->defval,"keywordtype",ol);
+ ol.docify(" ");
+ }
+ ol.endParameterType();
+
+ ol.startParameterName(TRUE);
+ VhdlDocGen::writeFormatString(arg->name,ol,md);
+
+ if (VhdlDocGen::isProcedure(md))
+ {
+ startFonts(arg->attrib,"stringliteral",ol);
+ }
+ else if (VhdlDocGen::isVhdlFunction(md))
+ {
+ startFonts(QCString("in"),"stringliteral",ol);
+ }
+
+ ol.docify(" ");
+ ol.disable(OutputGenerator::Man);
+ ol.startEmphasis();
+ ol.enable(OutputGenerator::Man);
+ if (!VhdlDocGen::isProcess(md))
+ {
+ // startFonts(arg->type,"vhdlkeyword",ol);
+ VhdlDocGen::writeFormatString(arg->type,ol,md);
+ }
+ ol.disable(OutputGenerator::Man);
+ ol.endEmphasis();
+ ol.enable(OutputGenerator::Man);
+
+ if (--index)
+ {
+ ol.docify(" , ");
+ }
+ else
+ {
+ // ol.docify(" ) ");
+ ol.endParameterName(TRUE,FALSE,TRUE);
+ break;
+ }
+ ol.endParameterName(FALSE,FALSE,FALSE);
+
+ //sem=TRUE;
+ first=FALSE;
+ }
+ //ol.endParameterList();
+ return TRUE;
+
+} // writeDocFunProc
+
+
+
+
+QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool func)
+{
+ QCString argString;
+ bool sem=FALSE;
+ ArgumentListIterator ali(*al);
+ Argument *arg;
+
+ for (;(arg=ali.current());++ali)
+ {
+ if (sem) argString.append(", ");
+ if (func)
+ {
+ argString+=arg->name;
+ argString+=":";
+ argString+=arg->type;
+ }
+ else
+ {
+ argString+=arg->defval+" ";
+ argString+=arg->name+" :";
+ argString+=arg->attrib+" ";
+ argString+=arg->type;
+ }
+ sem=TRUE;
+ }
+ return argString;
+}
+
+
+void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
+ OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
+{
+ static ClassDef *cdef;
+ //static GroupDef* gdef;
+ if (cd && cdef!=cd)
+ { // only one inline link
+ VhdlDocGen::writeInlineClassLink(cd,ol);
+ cdef=cd;
+ }
+
+ /*
+ if (gd && gdef==gd) return;
+ if (gd && gdef!=gd)
+ {
+ gdef=gd;
+ }
+ */
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONSTANT,FALSE),0,FALSE,VhdlDocGen::CONSTANT);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::TYPE,FALSE),0,FALSE,VhdlDocGen::TYPE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SUBTYPE,FALSE),0,FALSE,VhdlDocGen::SUBTYPE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GENERIC,FALSE),0,FALSE,VhdlDocGen::GENERIC);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PORT,FALSE),0,FALSE,VhdlDocGen::PORT);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCESS,FALSE),0,FALSE,VhdlDocGen::PROCESS);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SIGNAL,FALSE),0,FALSE,VhdlDocGen::SIGNAL);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ATTRIBUTE,FALSE),0,FALSE,VhdlDocGen::ATTRIBUTE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCEDURE,FALSE),0,FALSE,VhdlDocGen::PROCEDURE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::RECORD,FALSE),0,FALSE,VhdlDocGen::RECORD);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UNITS,FALSE),0,FALSE,VhdlDocGen::UNITS);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS);
+
+ // configurations must be added to global file definitions.
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG);
+ VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
+
+}
+
+static void setGlobalType(MemberList *ml)
+{
+ if (ml==0) return;
+ MemberDef *mdd=0;
+ MemberListIterator mmli(*ml);
+ for ( ; (mdd=mmli.current()); ++mmli )
+ {
+ QCString l=mdd->typeString();
+
+ if (qstrcmp(mdd->argsString(),"package")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
+ }
+ else if (qstrcmp(mdd->argsString(),"configuration")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::CONFIG);
+ }
+ else if (qstrcmp(mdd->typeString(),"library")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY);
+ }
+ else if (qstrcmp(mdd->typeString(),"use")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::USE);
+ }
+ else if (qstricmp(mdd->typeString(),"misc")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
+ }
+ else if (qstricmp(mdd->typeString(),"ucf_const")==0)
+ {
+ mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
+ }
+ }
+}
+
+/* writes a vhdl type documentation */
+bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol)
+{
+ ClassDef *cd=(ClassDef*)d;
+ bool hasParams = FALSE;
+
+ if (cd==0) return hasParams;
+
+ QCString ttype=mdef->typeString();
+ QCString largs=mdef->argsString();
+
+ if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
+ {
+ QCString nn=mdef->typeString();
+ nn=nn.stripWhiteSpace();
+ QCString na=cd->name();
+ MemberDef* memdef=VhdlDocGen::findMember(na,nn);
+ if (memdef && memdef->isLinkable())
+ {
+ ol.docify(" ");
+
+ ol.startBold();
+ writeLink(memdef,ol);
+ ol.endBold();
+ ol.docify(" ");
+ }
+ else
+ {
+ ol.docify(" ");
+ VhdlDocGen::formatString(ttype,ol,mdef);
+ ol.docify(" ");
+ }
+ ol.docify(mdef->name());
+ hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
+ }
+
+
+ if (mdef->isVariable())
+ {
+ if (VhdlDocGen::isConstraint(mdef))
+ {
+ writeLink(mdef,ol);
+ ol.docify(" ");
+
+ largs=largs.replace(QRegExp("#")," ");
+ VhdlDocGen::formatString(largs,ol,mdef);
+ return hasParams;
+ }
+ else
+ {
+ writeLink(mdef,ol);
+ if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
+ {
+ return hasParams;
+ }
+ ol.docify(" ");
+ }
+
+ // QCString largs=mdef->argsString();
+
+ bool c=largs=="context";
+ bool brec=largs.stripPrefix("record") ;
+
+ if (!brec && !c)
+ VhdlDocGen::formatString(ttype,ol,mdef);
+
+ if (c || brec || largs.stripPrefix("units"))
+ {
+ if (c)
+ largs=ttype;
+ VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
+ return hasParams;
+ }
+
+ ol.docify(" ");
+ if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
+ {
+ // QCString largs=mdef->argsString();
+ VhdlDocGen::formatString(largs,ol,mdef);
+ ol.docify(" ");
+ }
+ }
+ return hasParams;
+}
+
+/* writes a vhdl type declaration */
+
+void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool /*inGroup*/)
+{
+ static QRegExp reg("[%]");
+
+ Definition *d=0;
+
+
+ ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
+ mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY ||
+ mdef->getMemberSpecifiers()==VhdlDocGen::USE
+ ); // member should belong to something
+ if (cd) d=cd;
+ else if (nd) d=nd;
+ else if (fd) d=fd;
+ else if (gd) d=gd;
+ else d=(Definition*)mdef;
+
+ // write tag file information of this member
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <member kind=\"";
+ if (VhdlDocGen::isGeneric(mdef)) Doxygen::tagFile << "generic";
+ if (VhdlDocGen::isPort(mdef)) Doxygen::tagFile << "port";
+ if (VhdlDocGen::isEntity(mdef)) Doxygen::tagFile << "entity";
+ if (VhdlDocGen::isComponent(mdef)) Doxygen::tagFile << "component";
+ if (VhdlDocGen::isVType(mdef)) Doxygen::tagFile << "type";
+ if (VhdlDocGen::isConstant(mdef)) Doxygen::tagFile << "constant";
+ if (VhdlDocGen::isSubType(mdef)) Doxygen::tagFile << "subtype";
+ if (VhdlDocGen::isVhdlFunction(mdef)) Doxygen::tagFile << "function";
+ if (VhdlDocGen::isProcedure(mdef)) Doxygen::tagFile << "procedure";
+ if (VhdlDocGen::isProcess(mdef)) Doxygen::tagFile << "process";
+ if (VhdlDocGen::isSignals(mdef)) Doxygen::tagFile << "signal";
+ if (VhdlDocGen::isAttribute(mdef)) Doxygen::tagFile << "attribute";
+ if (VhdlDocGen::isRecord(mdef)) Doxygen::tagFile << "record";
+ if (VhdlDocGen::isLibrary(mdef)) Doxygen::tagFile << "library";
+ if (VhdlDocGen::isPackage(mdef)) Doxygen::tagFile << "package";
+ if (VhdlDocGen::isVariable(mdef)) Doxygen::tagFile << "shared variable";
+ if (VhdlDocGen::isFile(mdef)) Doxygen::tagFile << "file";
+ if (VhdlDocGen::isGroup(mdef)) Doxygen::tagFile << "group";
+ if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << " instantiation";
+ if (VhdlDocGen::isAlias(mdef)) Doxygen::tagFile << "alias";
+ if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << "configuration";
+
+ Doxygen::tagFile << "\">" << endl;
+ Doxygen::tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
+ Doxygen::tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
+ Doxygen::tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
+
+ if (VhdlDocGen::isVhdlFunction(mdef))
+ Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),TRUE)) << "</arglist>" << endl;
+ else if (VhdlDocGen::isProcedure(mdef))
+ Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),FALSE)) << "</arglist>" << endl;
+ else
+ Doxygen::tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
+
+ mdef->writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </member>" << endl;
+
+ }
+
+ // write search index info
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
+ Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
+ Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
+ }
+
+ QCString cname = d->name();
+ QCString cfname = d->getOutputFileBase();
+
+ //HtmlHelp *htmlHelp=0;
+ // bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
+ // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
+
+ // search for the last anonymous scope in the member type
+ ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
+
+ // start a new member declaration
+ uint isAnonymous = (bool)(annoClassDef); // || m_impl->annMemb || m_impl->annEnumType;
+ ///printf("startMemberItem for %s\n",name().data());
+ int mm=mdef->getMemberSpecifiers();
+ if (mm==VhdlDocGen::MISCELLANEOUS)
+ isAnonymous=3;
+
+ ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
+
+ // If there is no detailed description we need to write the anchor here.
+ bool detailsVisible = mdef->isDetailedSectionLinkable();
+ if (!detailsVisible) // && !m_impl->annMemb)
+ {
+ QCString doxyName=mdef->name().copy();
+ if (!cname.isEmpty()) doxyName.prepend(cname+"::");
+ QCString doxyArgs=mdef->argsString();
+ ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.docify("\n");
+ ol.popGeneratorState();
+
+ }
+ // *** write type
+ /*VHDL CHANGE */
+ bool bRec,bUnit;
+ QCString ltype(mdef->typeString());
+ // ltype=ltype.replace(reg," ");
+ QCString largs(mdef->argsString());
+ // largs=largs.replace(reg," ");
+ mdef->setType(ltype.data());
+ mdef->setArgsString(largs.data());
+ //ClassDef * plo=mdef->getClassDef();
+ ClassDef *kl=0;
+ ArgumentList *alp = mdef->argumentList();
+ QCString nn;
+ //VhdlDocGen::adjustRecordMember(mdef);
+ if (gd) gd=0;
+ switch (mm)
+ {
+ case VhdlDocGen::MISCELLANEOUS:
+ VhdlDocGen::writeSource(mdef,ol,nn);
+ break;
+ case VhdlDocGen::PROCEDURE:
+ case VhdlDocGen::FUNCTION:
+ ol.startBold();
+ VhdlDocGen::formatString(ltype,ol,mdef);
+ ol.endBold();
+ ol.insertMemberAlign();
+ ol.docify(" ");
+
+ writeLink(mdef,ol);
+ if (alp!=0 && mm==VhdlDocGen::FUNCTION)
+ VhdlDocGen::writeFunctionProto(ol,alp,mdef);
+
+ if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
+ VhdlDocGen::writeProcedureProto(ol,alp,mdef);
+
+ break;
+ case VhdlDocGen::USE:
+ kl=VhdlDocGen::getClass(mdef->name());
+ if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
+ writeLink(mdef,ol);
+ ol.insertMemberAlign();
+ ol.docify(" ");
+
+ if (kl)
+ {
+ nn=kl->getOutputFileBase();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
+ ol.startBold();
+ ol.docify(name.data());
+ name.resize(0);
+ ol.endBold();
+ name+=" <"+mdef->name()+">";
+ ol.startEmphasis();
+ ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
+ ol.popGeneratorState();
+ }
+ break;
+ case VhdlDocGen::LIBRARY:
+ writeLink(mdef,ol);
+ ol.insertMemberAlign();
+ if (largs=="context")
+ {
+ VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
+ }
+
+ break;
+
+ case VhdlDocGen::GENERIC:
+ case VhdlDocGen::PORT:
+ case VhdlDocGen::ALIAS:
+
+ writeLink(mdef,ol);
+ ol.docify(" ");
+ ol.insertMemberAlign();
+ if (mm==VhdlDocGen::GENERIC)
+ {
+ ol.startBold();
+ VhdlDocGen::formatString(largs,ol,mdef);
+ ol.endBold();
+ }
+ else
+ {
+ ol.docify(" ");
+ ol.startBold();
+ VhdlDocGen::formatString(ltype,ol,mdef);
+ ol.endBold();
+ ol.docify(" ");
+ VhdlDocGen::formatString(largs,ol,mdef);
+ }
+ break;
+ case VhdlDocGen::PROCESS:
+ writeLink(mdef,ol);
+ ol.insertMemberAlign();
+ VhdlDocGen::writeProcessProto(ol,alp,mdef);
+ break;
+ case VhdlDocGen::PACKAGE:
+ case VhdlDocGen::ENTITY:
+ case VhdlDocGen::COMPONENT:
+ case VhdlDocGen::INSTANTIATION:
+ case VhdlDocGen::CONFIG:
+ if (VhdlDocGen::isCompInst(mdef) )
+ {
+ nn=largs;
+ if(nn.stripPrefix("function") || nn.stripPrefix("package"))
+ {
+ VhdlDocGen::formatString(largs,ol,mdef);
+ ol.insertMemberAlign();
+ writeLink(mdef,ol);
+ ol.docify(" ");
+ VhdlDocGen::formatString(ltype,ol,mdef);
+ break;
+ }
+
+ largs.prepend("::");
+ largs.prepend(mdef->name().data());
+ ol.writeObjectLink(mdef->getReference(),
+ cfname,
+ mdef->anchor(),
+ mdef->name());
+ }
+ else
+ writeLink(mdef,ol);
+
+ ol.insertMemberAlign();
+ ol.docify(" ");
+
+ ol.startBold();
+ ol.docify(ltype);
+ ol.endBold();
+ ol.docify(" ");
+ if (VhdlDocGen::isComponent(mdef) ||
+ VhdlDocGen::isConfig(mdef) ||
+ VhdlDocGen::isCompInst(mdef))
+ {
+ if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
+ {
+ nn=mdef->getOutputFileBase();
+ nn=ltype;
+ }
+ else
+ {
+ nn=mdef->name();
+ }
+ kl=getClass(nn.data());
+ if (kl)
+ {
+ nn=kl->getOutputFileBase();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startEmphasis();
+ QCString name("<Entity ");
+ if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
+ {
+ name+=ltype+">";
+ }
+ else
+ {
+ name+=mdef->name()+"> ";
+ }
+ ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
+ ol.endEmphasis();
+ ol.popGeneratorState();
+ }
+ }
+ break;
+ case VhdlDocGen::UCF_CONST:
+ mm=mdef->name().findRev('_');
+ if (mm>0)
+ {
+ mdef->setName(mdef->name().left(mm));
+ }
+ writeUCFLink(mdef,ol);
+ break;
+ case VhdlDocGen::SIGNAL:
+ case VhdlDocGen::ATTRIBUTE:
+ case VhdlDocGen::SUBTYPE:
+ case VhdlDocGen::CONSTANT:
+ case VhdlDocGen::SHAREDVARIABLE:
+ case VhdlDocGen::VFILE:
+ case VhdlDocGen::GROUP:
+ writeLink(mdef,ol);
+ ol.docify(" ");
+ ol.insertMemberAlign();
+ VhdlDocGen::formatString(ltype,ol,mdef);
+ break;
+ case VhdlDocGen::TYPE:
+ bRec=largs.stripPrefix("record") ;
+ bUnit=largs.stripPrefix("units") ;
+ ol.startBold();
+ if (bRec) ol.docify("record: ");
+ if (bUnit) ol.docify("units: ");
+ writeLink(mdef,ol);
+ ol.insertMemberAlign();
+ if (!bRec && !bUnit) VhdlDocGen::formatString(ltype,ol,mdef);
+ if (bUnit) ol.lineBreak();
+ if (bRec || bUnit)
+ {
+ writeRecorUnit(largs,ol,mdef);
+ mdef->setType("");
+ }
+ ol.endBold();
+ break;
+
+ default: break;
+ }
+
+ bool htmlOn = ol.isEnabled(OutputGenerator::Html);
+ if (htmlOn && /*Config_getBool("HTML_ALIGN_MEMBERS") &&*/ !ltype.isEmpty())
+ {
+ ol.disable(OutputGenerator::Html);
+ }
+ if (!ltype.isEmpty()) ol.docify(" ");
+
+ if (htmlOn)
+ {
+ ol.enable(OutputGenerator::Html);
+ }
+
+ if (!detailsVisible)// && !m_impl->annMemb)
+ {
+ ol.endDoxyAnchor(cfname,mdef->anchor());
+ }
+
+ // name().data(),annoClassDef,annEnumType);
+ // if(mm!=VhdlDocGen::MISCELLANEOUS)
+ ol.endMemberItem();
+ if (!mdef->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC") /* && !annMemb */)
+ {
+ ol.startMemberDescription(mdef->anchor());
+ ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
+ mdef->getOuterScope()?mdef->getOuterScope():d,
+ mdef,mdef->briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ if (detailsVisible)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ //ol.endEmphasis();
+ ol.docify(" ");
+ if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
+ {
+ ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
+ }
+ else // local link
+ {
+ ol.startTextLink(0,mdef->anchor());
+ }
+ ol.endTextLink();
+ //ol.startEmphasis();
+ ol.popGeneratorState();
+ }
+ //ol.newParagraph();
+ ol.endMemberDescription();
+ }
+ mdef->warnIfUndocumented();
+
+}// end writeVhdlDeclaration
+
+
+void VhdlDocGen::writePlainVHDLDeclarations(
+ MemberList* mlist,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
+{
+
+ SDict<QCString> pack(1009);
+
+ bool first=TRUE;
+ MemberDef *md;
+ MemberListIterator mli(*mlist);
+ for ( ; (md=mli.current()); ++mli )
+ {
+ int mems=md->getMemberSpecifiers();
+ if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
+ {
+ if (first) { ol.startMemberList();first=FALSE; }
+ VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
+ } //if
+ else if (md->isBriefSectionVisible() && (mems==specifier))
+ {
+ if (!pack.find(md->name().data()))
+ {
+ if (first) ol.startMemberList(),first=FALSE;
+ VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
+ pack.append(md->name().data(),new QCString(md->name().data()));
+ }
+ } //if
+ } //for
+ if (!first) ol.endMemberList();
+ pack.clear();
+}//plainDeclaration
+
+static bool membersHaveSpecificType(MemberList *ml,uint64 type)
+{
+ if (ml==0) return FALSE;
+ MemberDef *mdd=0;
+ MemberListIterator mmli(*ml);
+ for ( ; (mdd=mmli.current()); ++mmli )
+ {
+ if (mdd->getMemberSpecifiers()==type) //is type in class
+ {
+ return TRUE;
+ }
+ }
+ if (ml->getMemberGroupList())
+ {
+ MemberGroupListIterator mgli(*ml->getMemberGroupList());
+ MemberGroup *mg;
+ while ((mg=mgli.current()))
+ {
+ if (mg->members())
+ {
+ if (membersHaveSpecificType(mg->members(),type)) return TRUE;
+ }
+ ++mgli;
+ }
+ }
+ return FALSE;
+}
+
+void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
+{
+ setGlobalType(ml);
+ if (!membersHaveSpecificType(ml,type)) return;
+
+ if (title)
+ {
+ ol.startMemberHeader(title);
+ ol.parseText(title);
+ ol.endMemberHeader();
+ ol.docify(" ");
+ }
+ if (subtitle && subtitle[0]!=0)
+ {
+ ol.startMemberSubtitle();
+ ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
+ ol.endMemberSubtitle();
+ } //printf("memberGroupList=%p\n",memberGroupList);
+
+ VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
+
+ if (ml->getMemberGroupList())
+ {
+ MemberGroupListIterator mgli(*ml->getMemberGroupList());
+ MemberGroup *mg;
+ while ((mg=mgli.current()))
+ {
+ if (membersHaveSpecificType(mg->members(),type))
+ {
+ //printf("mg->header=%s\n",mg->header().data());
+ bool hasHeader=mg->header()!="[NOHEADER]";
+ ol.startMemberGroupHeader(hasHeader);
+ if (hasHeader)
+ {
+ ol.parseText(mg->header());
+ }
+ ol.endMemberGroupHeader();
+ if (!mg->documentation().isEmpty())
+ {
+ //printf("Member group has docs!\n");
+ ol.startMemberGroupDocs();
+ ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.endMemberGroupDocs();
+ }
+ ol.startMemberGroup();
+ //printf("--- mg->writePlainDeclarations ---\n");
+ VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
+ ol.endMemberGroup(hasHeader);
+ }
+ ++mgli;
+ }
+ }
+}// writeVHDLDeclarations
+
+
+bool VhdlDocGen::writeClassType( ClassDef *& cd,
+ OutputList &ol ,QCString & cname)
+{
+ int id=cd->protection();
+ QCString qcs = VhdlDocGen::trTypeString(id+2);
+ cname=VhdlDocGen::getClassName(cd);
+ ol.startBold();
+ ol.writeString(qcs.data());
+ ol.writeString(" ");
+ ol.endBold();
+ //ol.insertMemberAlign();
+ return FALSE;
+}// writeClassLink
+
+QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
+{
+ switch(type)
+ {
+ case VhdlDocGen::LIBRARY:
+ if (sing) return "Library";
+ else return "Libraries";
+ case VhdlDocGen::PACKAGE:
+ if (sing) return "Package";
+ else return "Packages";
+ case VhdlDocGen::SIGNAL:
+ if (sing) return "Signal";
+ else return "Signals";
+ case VhdlDocGen::COMPONENT:
+ if (sing) return "Component";
+ else return "Components";
+ case VhdlDocGen::CONSTANT:
+ if (sing) return "Constant";
+ else return "Constants";
+ case VhdlDocGen::ENTITY:
+ if (sing) return "Entity";
+ else return "Entities";
+ case VhdlDocGen::TYPE:
+ if (sing) return "Type";
+ else return "Types";
+ case VhdlDocGen::SUBTYPE:
+ if (sing) return "Subtype";
+ else return "Subtypes";
+ case VhdlDocGen::FUNCTION:
+ if (sing) return "Function";
+ else return "Functions";
+ case VhdlDocGen::RECORD:
+ if (sing) return "Record";
+ else return "Records";
+ case VhdlDocGen::PROCEDURE:
+ if (sing) return "Procedure";
+ else return "Procedures";
+ case VhdlDocGen::ARCHITECTURE:
+ if (sing) return "Architecture";
+ else return "Architectures";
+ case VhdlDocGen::ATTRIBUTE:
+ if (sing) return "Attribute";
+ else return "Attributes";
+ case VhdlDocGen::PROCESS:
+ if (sing) return "Process";
+ else return "Processes";
+ case VhdlDocGen::PORT:
+ if (sing) return "Port";
+ else return "Ports";
+ case VhdlDocGen::USE:
+ if (sing) return "use clause";
+ else return "Use Clauses";
+ case VhdlDocGen::GENERIC:
+ if (sing) return "Generic";
+ else return "Generics";
+ case VhdlDocGen::PACKAGE_BODY:
+ return "Package Body";
+ case VhdlDocGen::UNITS:
+ return "Units";
+ case VhdlDocGen::SHAREDVARIABLE:
+ if (sing) return "Shared Variable";
+ return "Shared Variables";
+ case VhdlDocGen::VFILE:
+ if (sing) return "File";
+ return "Files";
+ case VhdlDocGen::GROUP:
+ if (sing) return "Group";
+ return "Groups";
+ case VhdlDocGen::INSTANTIATION:
+ if (sing) return "Instantiation";
+ else return "Instantiations";
+ case VhdlDocGen::ALIAS:
+ if (sing) return "Alias";
+ return "Aliases";
+ case VhdlDocGen::CONFIG:
+ if (sing) return "Configuration";
+ return "Configurations";
+ case VhdlDocGen::MISCELLANEOUS:
+ return "Miscellaneous";
+ case VhdlDocGen::UCF_CONST:
+ return "Constraints";
+ default:
+ return "Class";
+ }
+}
+
+QCString VhdlDocGen::trDesignUnitHierarchy()
+{
+ return "Design Unit Hierarchy";
+}
+
+QCString VhdlDocGen::trDesignUnitList()
+{
+ return "Design Unit List";
+}
+
+QCString VhdlDocGen::trDesignUnitMembers()
+{
+ return "Design Unit Members";
+}
+
+QCString VhdlDocGen::trDesignUnitListDescription()
+{
+ return "Here is a list of all design unit members with links to "
+ "the Entities they belong to:";
+}
+
+QCString VhdlDocGen::trDesignUnitIndex()
+{
+ return "Design Unit Index";
+}
+
+QCString VhdlDocGen::trDesignUnits()
+{
+ return "Design Units";
+}
+
+QCString VhdlDocGen::trFunctionAndProc()
+{
+ return "Functions/Procedures/Processes";
+}
+
+
+/*! writes a link if the string is linkable else a formatted string */
+
+void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
+{
+ if (mdef)
+ {
+ ClassDef *cd=mdef->getClassDef();
+ if (cd)
+ {
+ QCString n=cd->name();
+ MemberDef* memdef=VhdlDocGen::findMember(n,mem);
+ if (memdef && memdef->isLinkable())
+ {
+ ol.startBold();
+ writeLink(memdef,ol);
+ ol.endBold();
+ ol.docify(" ");
+ return;
+ }
+ }
+ }
+ startFonts(mem,"vhdlchar",ol);
+}// found component
+
+
+
+void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
+{
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd");
+ // pIntf->resetCodeParserState();
+
+ QCString codeFragment=mdef->documentation();
+
+ if (cname.isEmpty())
+ {
+ writeLink(mdef,ol);
+ int fi=0;
+ int j=0;
+ do
+ {
+ fi=codeFragment.find("\n",++fi);
+ } while(fi>=0 && j++ <3);
+
+ // show only the first four lines
+ if (j==4)
+ {
+ codeFragment=codeFragment.left(fi);
+ codeFragment.append("\n .... ");
+ }
+ }
+
+ codeFragment.prepend("\n");
+ ol.pushGeneratorState();
+ ol.startCodeFragment();
+ pIntf->parseCode(ol, // codeOutIntf
+ 0, // scope
+ codeFragment, // input
+ SrcLangExt_VHDL, // lang
+ FALSE, // isExample
+ 0, // exampleName
+ mdef->getFileDef(), // fileDef
+ mdef->getStartBodyLine(), // startLine
+ mdef->getEndBodyLine(), // endLine
+ TRUE, // inlineFragment
+ mdef, // memberDef
+ TRUE // show line numbers
+ );
+
+ ol.endCodeFragment();
+ ol.popGeneratorState();
+
+ if (cname.isEmpty()) return;
+
+ mdef->writeSourceDef(ol,cname);
+ mdef->writeSourceRefs(ol,cname);
+ mdef->writeSourceReffedBy(ol,cname);
+}
+
+
+
+QCString VhdlDocGen::convertFileNameToClassName(QCString name)
+{
+
+ QCString n=name;
+ n=n.remove(0,6);
+
+ int i=0;
+
+ while((i=n.find("__"))>0)
+ {
+ n=n.remove(i,1);
+ }
+
+ while((i=n.find("_1"))>0)
+ {
+ n=n.replace(i,2,":");
+ }
+
+ return n;
+}
+
+void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,bool altera)
+{
+ QCString ucFile(input);
+ int lineNo=0;
+ QCString newLine="\n";
+ QCString comment("#!");
+ QCString brief;
+
+ while (!ucFile.isEmpty())
+ {
+ int i=ucFile.find("\n");
+ if (i<0) break;
+ lineNo++;
+ QCString temp=ucFile.left(i);
+ temp=temp.stripWhiteSpace();
+ bool bb=temp.stripPrefix("//");
+
+ if (!temp.isEmpty())
+ {
+ if (temp.stripPrefix(comment) )
+ {
+ brief+=temp;
+ brief.append("\\n");
+ }
+ else if (!temp.stripPrefix("#") && !bb)
+ {
+ if (altera)
+ {
+ int i=temp.find("-name");
+ if (i>0)
+ {
+ temp=temp.remove(0,i+5);
+ }
+
+ temp.stripPrefix("set_location_assignment");
+
+ initUCF(entity,0,temp,lineNo,fileName,brief);
+ }
+ else
+ {
+ QRegExp ee("[\\s=]");
+ int i=temp.find(ee);
+ QCString ff=temp.left(i);
+ temp.stripPrefix(ff.data());
+ ff.append("#");
+ if (!temp.isEmpty())
+ {
+ initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
+ }
+ }
+ }
+ }//temp
+
+ ucFile=ucFile.remove(0,i+1);
+ }// while
+}
+
+static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief)
+{
+ if (qcs.isEmpty())return;
+ QRegExp sp("\\s");
+ QRegExp reg("[\\s=]");
+ QCString n;
+ // bool bo=(qstricmp(type,qcs.data())==0);
+
+ VhdlDocGen::deleteAllChars(qcs,';');
+ qcs=qcs.stripWhiteSpace();
+
+ int i= qcs.find(reg);
+ if (i<0) return;
+ if (i==0)
+ {
+ n=type;
+ VhdlDocGen::deleteAllChars(n,'#');
+ type="";
+ }
+ else
+ {
+ n=qcs.left(i);
+ }
+ qcs=qcs.remove(0,i+1);
+ // qcs.prepend("|");
+
+ qcs.stripPrefix("=");
+
+ Entry* current=new Entry;
+ current->spec=VhdlDocGen::UCF_CONST;
+ current->section=Entry::VARIABLE_SEC;
+ current->bodyLine=line;
+ current->fileName=fileName;
+ current->type="ucf_const";
+ current->args+=qcs;
+ current->lang= SrcLangExt_VHDL ;
+
+ // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
+ if (n.isEmpty())
+ {
+ n="dummy";
+ n+=VhdlDocGen::getRecordNumber();
+ }
+
+ current->name= n+"_";
+ current->name.append(VhdlDocGen::getRecordNumber().data());
+
+ if (!brief.isEmpty())
+ {
+ current->brief=brief;
+ current->briefLine=line;
+ current->briefFile=fileName;
+ brief.resize(0);
+ }
+
+ root->addSubEntry(current);
+}
+
+
+static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
+{
+
+ QCString largs(mdef->argsString());
+ QCString n= splitString(largs, '#');
+ // VhdlDocGen::adjustRecordMember(mdef);
+ bool equ=(n.length()==largs.length());
+
+ if (!equ)
+ {
+ ol.writeString(n.data());
+ ol.docify(" ");
+ ol.insertMemberAlign();
+ }
+
+ if (mdef->name().contains("dummy")==0)
+ {
+ writeLink(mdef,ol);
+ }
+ if (equ)
+ {
+ ol.insertMemberAlign();
+ }
+ ol.docify(" ");
+ VhdlDocGen::formatString(largs,ol,mdef);
+}
+
+bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne)
+{
+ FileName *fn=Doxygen::inputNameList->getFirst();
+ //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
+ uint count=Doxygen::inputNameList->count();
+ LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files);
+ // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files);
+ QCString file;
+ QCString co("Constraints");
+
+ if (Config_getBool("HAVE_DOT") && Config_getEnum("DOT_IMAGE_FORMAT")=="svg")
+ {
+ QCString ov = theTranslator->trDesignOverview();
+ QCString ofile("vhdl_design_overview");
+ LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,"");
+ kk->addChild(oo);
+ }
+
+ uint i=0;
+ while (i<count)
+ {
+ FileDef *fd=fn->at(i);
+ if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
+ {
+ file = convertNameToFile(fd->name().data(),FALSE,FALSE);
+ LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
+ kk->addChild(ucf);
+ break;
+ }
+ i++;
+ }
+ return FALSE;
+}
+
+
+// for cell_inst : [entity] work.proto [ (label|expr) ]
+QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
+{
+ int index;
+ QCString label;
+ QCString ent("entity");
+ if (!entity.contains(":")) return "";
+
+ QRegExp exp("[:()\\s]");
+ QStringList ql=QStringList::split(exp,entity,FALSE);
+ //int ii=ql.findIndex(ent);
+ assert(ql.count()>=2);
+ label = ql[0].utf8();
+ entity = ql[1].utf8();
+ if ((index=entity.findRev("."))>=0)
+ {
+ entity.remove(0,index+1);
+ }
+
+ if (ql.count()==3)
+ {
+ arch= ql[2].utf8();
+ ql=QStringList::split(exp,arch,FALSE);
+ if (ql.count()>1) // expression
+ {
+ arch="";
+ }
+ }
+ return label; // label
+}
+
+// use (configuration|entity|open) work.test [(cellfor)];
+
+QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
+{
+ int index;
+ QRegExp exp("[()\\s]");
+
+ QCString label="";
+ QStringList ql=QStringList::split(exp,entity,FALSE);
+
+ if (ql.contains("open"))
+ {
+ return "open";
+ }
+
+ label=ql[0].utf8();
+
+ entity = ql[1].utf8();
+ if ((index=entity.findRev("."))>=0)
+ {
+ entity.remove(0,index+1);
+ }
+
+ if (ql.count()==3)
+ {
+ arch=ql[2].utf8();
+ }
+ return label;
+}
+
+
+
+ // find class with upper/lower letters
+ ClassDef* VhdlDocGen::findVhdlClass(const char *className )
+ {
+
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (;(cd=cli.current());++cli)
+ {
+ if (qstricmp(className,cd->name().data())==0)
+ {
+ return cd;
+ }
+ }
+ return 0;
+ }
+
+
+//@param arch bit0:flipflop
+//@param binding e.g entity work.foo(bar)
+//@param label |label0|label1
+// label0:architecture name
+//@param confVhdl of configuration file (identifier::entity_name) or
+// the architecture if isInlineConf TRUE
+//@param isInlineConf
+//@param confN List of configurations
+
+void assignBinding(VhdlConfNode * conf)
+{
+ QList<Entry> instList=getVhdlInstList();
+ QListIterator<Entry> eli(instList);
+ Entry *cur=0;
+ ClassDef *archClass=0,*entClass=0;
+ QCString archName,entityName;
+ QCString arcBind,entBind;
+
+ bool others,all;
+ entBind=conf->binding;
+ QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind);
+
+ if (qstricmp(conf2,"configuration")==0)
+ {
+ QList<VhdlConfNode> confList = getVhdlConfiguration();
+ VhdlConfNode* vconf;
+ // bool found=false;
+ for (uint iter=0;iter<confList.count(); iter++)
+ {
+ vconf= (VhdlConfNode *)confList.at(iter);
+ QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0);
+ if (n==entBind)
+ {
+ // found=true;
+ entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1);
+ QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
+ QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
+ a=e+"::"+a;
+ archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data());
+ entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data());
+ break;
+ }
+ }
+ }
+ else // conf2!=configuration
+ {
+ QCString a,c,e;
+ if (conf->isInlineConf)
+ {
+ c=conf->confVhdl;
+ e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0);
+ }
+ else
+ {
+ a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
+ e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
+ c=e+"::"+a;
+ }
+ archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data());
+ entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data());
+ }
+
+ QCString label=conf->compSpec.lower();
+ //label.prepend("|");
+
+ if (!archClass)
+ {
+ // err("architecture %s not found ! ",conf->confVhdl.data());
+ return;
+ }
+
+ archName=archClass->name();
+ QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
+ all=allOt.lower()=="all" ;
+ others= allOt.lower()=="others";
+
+ for (;(cur=eli.current());++eli)
+ {
+ if (cur->exception.lower()==label || conf->isInlineConf)
+ {
+ QCString sign,archy;
+
+ if (all || others)
+ {
+ archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
+ }
+ else
+ {
+ archy=conf->arch;
+ }
+
+ QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower();
+ QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower();
+
+ QStringList ql=QStringList::split(",",inst1);
+
+ for (uint j=0;j<ql.count();j++)
+ {
+ QCString archy1,sign1;
+ if (all || others)
+ {
+ archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1);
+ sign1=cur->type;
+ }
+ else
+ {
+ archy1=comp+":"+ql[j].utf8();
+ sign1=cur->type+":"+cur->name;
+ }
+
+ if (archy1==sign1.lower() && !cur->stat)
+ {
+ // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
+ ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data());
+
+ if (entClass==0 || ent==0)
+ {
+ continue;
+ }
+
+ addInstance(ent,archClass,entClass,cur);
+ cur->stat=TRUE;
+ break;
+ }
+ }// for
+ }
+ }//for each element in instList
+
+}//assignBinding
+
+/*
+
+// file foo.vhd
+// enitity foo
+// .....
+// end entity
+
+// file foo_arch.vhd
+// architecture xxx of foo is
+// ........
+// end architecture
+
+*/
+void VhdlDocGen::computeVhdlComponentRelations()
+{
+
+ QCString entity,arch,inst;
+ QList<VhdlConfNode> confList = getVhdlConfiguration();
+
+ for (uint iter=0;iter<confList.count(); iter++)
+ {
+ VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
+ if (!(conf->isInlineConf || conf->isLeaf))
+ {
+ continue;
+ }
+ assignBinding(conf);
+ }
+
+ QList<Entry> qsl= getVhdlInstList();
+ QListIterator<Entry> eli(qsl);
+ Entry *cur;
+
+ for (eli.toFirst();(cur=eli.current());++eli)
+ {
+ if (cur->stat ) // was bind
+ {
+ continue;
+ }
+
+ if (cur->includeName=="entity" || cur->includeName=="component" )
+ {
+ entity=cur->includeName+" "+cur->type;
+ QCString rr=VhdlDocGen::parseForBinding(entity,arch);
+ }
+ else if (cur->includeName.isEmpty())
+ {
+ entity=cur->type;
+ }
+
+ ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity);
+ inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
+ ClassDef *cd=Doxygen::classSDict->find(inst);
+ ClassDef *ar=Doxygen::classSDict->find(cur->args);
+
+ if (cd==0)
+ {
+ continue;
+ }
+
+ // if (classEntity==0)
+ // err("%s:%d:Entity:%s%s",cur->fileName.data(),cur->startLine,entity.data()," could not be found");
+
+ addInstance(classEntity,ar,cd,cur);
+ }
+
+}
+
+static void addInstance(ClassDef* classEntity, ClassDef* ar,
+ ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
+{
+
+ QCString bName,n1;
+ if (ar==0) return;
+
+ if (classEntity==0)
+ {
+ //add component inst
+ n1=cur->type;
+ goto ferr;
+ }
+
+ if (classEntity==cd) return;
+
+ bName=classEntity->name();
+ // fprintf(stderr,"\naddInstance %s to %s %s %s\n", classEntity->name().data(),cd->name().data(),ar->name().data(),cur->name);
+ n1=classEntity->name().data();
+
+ if (!cd->isBaseClass(classEntity, true, 0))
+ {
+ cd->insertBaseClass(classEntity,n1,Public,Normal,0);
+ }
+ else
+ {
+ VhdlDocGen::addBaseClass(cd,classEntity);
+ }
+
+ if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
+ {
+ classEntity->insertSubClass(cd,Public,Normal,0);
+ classEntity->setLanguage(SrcLangExt_VHDL);
+ }
+
+ferr:
+ QCString uu=cur->name;
+ MemberDef *md=new MemberDef(
+ ar->getDefFileName(), cur->startLine,cur->startColumn,
+ n1,uu,uu, 0,
+ Public, Normal, cur->stat,Member,
+ MemberType_Variable,
+ 0,
+ 0);
+
+ if (ar->getOutputFileBase())
+ {
+ TagInfo tg;
+ tg.anchor = 0;
+ tg.fileName = ar->getOutputFileBase();
+ tg.tagName = 0;
+ md->setTagInfo(&tg);
+ }
+
+ //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
+
+ md->setLanguage(SrcLangExt_VHDL);
+ md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
+ md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
+ md->setBodySegment(cur->startLine,-1) ;
+ md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine);
+ FileDef *fd=ar->getFileDef();
+ md->setBodyDef(fd);
+
+
+ QCString info="Info: Elaborating entity "+n1;
+ fd=ar->getFileDef();
+ info+=" for hierarchy ";
+ QRegExp epr("[|]");
+ QCString label=cur->type+":"+cur->write+":"+cur->name;
+ label.replace(epr,":");
+ info+=label;
+ fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data());
+
+
+ ar->insertMember(md);
+
+}
+
+
+void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
+{
+ QStringList ql=QStringList::split("#",largs,FALSE);
+ uint len=ql.count();
+ for(uint i=0;i<len;i++)
+ {
+ QCString n=ql[i].utf8();
+ VhdlDocGen::formatString(n,ol,mdef);
+ if ((len-i)>1) ol.lineBreak();
+ }
+}
+
+
+void VhdlDocGen::writeRecUnitDocu(
+ const MemberDef *md,
+ OutputList& ol,
+ QCString largs)
+{
+
+ QStringList ql=QStringList::split("#",largs,FALSE);
+ uint len=ql.count();
+ ol.startParameterList(TRUE);
+ bool first=TRUE;
+
+ for(uint i=0;i<len;i++)
+ {
+ QCString n=ql[i].utf8();
+ ol.startParameterType(first,"");
+ ol.endParameterType();
+ ol.startParameterName(TRUE);
+ VhdlDocGen::formatString(n,ol,md);
+ if ((len-i)>1)
+ {
+ ol.endParameterName(FALSE,FALSE,FALSE);
+ }
+ else
+ {
+ ol.endParameterName(TRUE,FALSE,TRUE);
+ }
+
+ first=FALSE;
+ }
+
+}//#
+
+
+
+bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
+{
+ bool found=FALSE;
+ //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
+ if (level>255)
+ {
+ err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
+ abort();
+ return FALSE;
+ }
+
+ if (cd->subClasses())
+ {
+ BaseClassListIterator bcli(*cd->subClasses());
+ for ( ; bcli.current() && !found ; ++bcli)
+ {
+ ClassDef *ccd=bcli.current()->classDef;
+ if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
+ //printf("isSubClass() subclass %s\n",ccd->name().data());
+ if (ccd==scd)
+ {
+ found=TRUE;
+ }
+ else
+ {
+ if (level <256)
+ {
+ found=ccd->isBaseClass(scd,followInstances,level+1);
+ }
+ }
+ }
+ }
+ return found;
+}
+
+void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
+{
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ for ( ; bcli.current() ; ++bcli)
+ {
+ ClassDef *ccd=bcli.current()->classDef;
+ if (ccd==ent)
+ {
+ QCString n = bcli.current()->usedName;
+ int i = n.find('(');
+ if(i<0)
+ {
+ bcli.current()->usedName.append("(2)");
+ return;
+ }
+ static QRegExp reg("[0-9]+");
+ QCString s=n.left(i);
+ QCString r=n.right(n.length()-i);
+ QCString t=r;
+ VhdlDocGen::deleteAllChars(r,')');
+ VhdlDocGen::deleteAllChars(r,'(');
+ r.setNum(r.toInt()+1);
+ t.replace(reg,r.data());
+ s.append(t.data());
+ bcli.current()->usedName=s;
+ bcli.current()->templSpecifiers=t;
+ }
+ }
+ }
+}
+
+
+static QList<MemberDef> mdList;
+
+static MemberDef* findMemFlow(const MemberDef* mdef)
+{
+ for(uint j=0;j<mdList.count();j++)
+ {
+ MemberDef* md=(MemberDef*)mdList.at(j);
+ if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
+ return md;
+ }
+ return 0;
+}
+
+void VhdlDocGen::createFlowChart(const MemberDef *mdef)
+{
+ if (mdef==0) return;
+
+ QCString codeFragment;
+ MemberDef* mm=0;
+ if((mm=findMemFlow(mdef))!=0)
+ {
+ // don't create the same flowchart twice
+ VhdlDocGen::setFlowMember(mm);
+ return;
+ }
+ else
+ {
+ mdList.append(mdef);
+ }
+
+ //fprintf(stderr,"\n create flow mem %s %p\n",mdef->name().data(),mdef);
+
+ int actualStart= mdef->getStartBodyLine();
+ int actualEnd=mdef->getEndBodyLine();
+ FileDef* fd=mdef->getFileDef();
+ bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment);
+ if (!b) return;
+
+ VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd");
+ VhdlDocGen::setFlowMember(mdef);
+ Entry root;
+ QStrList filesInSameTu;
+ pIntf->startTranslationUnit("");
+ pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu);
+ pIntf->finishTranslationUnit();
+}
+
+void VhdlDocGen::resetCodeVhdlParserState()
+{
+ varMap.clear();
+ qli.clear();
+ packages.clear();
+}
+
+bool VhdlDocGen::isConstraint(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::UCF_CONST; }
+bool VhdlDocGen::isConfig(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; }
+bool VhdlDocGen::isAlias(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; }
+bool VhdlDocGen::isLibrary(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; }
+bool VhdlDocGen::isGeneric(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::GENERIC; }
+bool VhdlDocGen::isPort(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::PORT; }
+bool VhdlDocGen::isComponent(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT; }
+bool VhdlDocGen::isPackage(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::USE; }
+bool VhdlDocGen::isEntity(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::ENTITY; }
+bool VhdlDocGen::isConstant(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::CONSTANT; }
+bool VhdlDocGen::isVType(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::TYPE; }
+bool VhdlDocGen::isSubType(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::SUBTYPE; }
+bool VhdlDocGen::isVhdlFunction(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::FUNCTION; }
+bool VhdlDocGen::isProcess(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::PROCESS; }
+bool VhdlDocGen::isSignal(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
+bool VhdlDocGen::isAttribute(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::ATTRIBUTE; }
+bool VhdlDocGen::isSignals(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
+bool VhdlDocGen::isProcedure(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::PROCEDURE; }
+bool VhdlDocGen::isRecord(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::RECORD; }
+bool VhdlDocGen::isArchitecture(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::ARCHITECTURE; }
+bool VhdlDocGen::isUnit(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::UNITS; }
+bool VhdlDocGen::isPackageBody(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::PACKAGE_BODY; }
+bool VhdlDocGen::isVariable(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::SHAREDVARIABLE; }
+bool VhdlDocGen::isFile(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; }
+bool VhdlDocGen::isGroup(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; }
+bool VhdlDocGen::isCompInst(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::INSTANTIATION; }
+bool VhdlDocGen::isMisc(const MemberDef *mdef)
+{ return mdef->getMemberSpecifiers()==VhdlDocGen::MISCELLANEOUS; }
+
+
+
+//############################## Flowcharts #################################################
+
+#define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
+ FlowChart::FOR_NO | FlowChart::CASE_NO | \
+ FlowChart::LOOP_NO | WHEN_NO)
+#define DECLN (FlowChart::WHEN_NO | \
+ FlowChart::ELSIF_NO | FlowChart::IF_NO | \
+ FlowChart::FOR_NO | FlowChart::WHILE_NO | \
+ FlowChart::CASE_NO | FlowChart::LOOP_NO )
+#define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
+#define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
+ FlowChart::LOOP_NO )
+#define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
+#define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
+#define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
+#define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
+#define EMPTY (EEND | FlowChart::ELSIF_NO)
+#define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
+#define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
+#define FLOWLEN (flowList.count()-1)
+
+static int ifcounter=0;
+static int nodeCounter=0;
+
+static struct
+{
+ // link colors
+ const char *textNodeLink;
+ const char *yesNodeLink;
+ const char *noNodeLink;
+
+ // node colors
+ const char* comment;
+ const char* decisionNode;
+ const char* varNode;
+ const char *startEndNode;
+ const char* textNode;
+} flowCol =
+{ "green", // textNodeLink
+ "red", // yesNodeLink
+ "black", // noNodeLink
+ "khaki", // comment
+ "0.7 0.3 1.0", // decisionNode
+ "lightyellow", // varNode
+ "white", // startEndNode
+ "lightcyan" // textNode
+};
+
+QList<FlowChart> FlowChart::flowList;
+
+#ifdef DEBUGFLOW
+static QMap<QCString,int> keyMap;
+#endif
+
+void alignText(QCString & q)
+{
+ if (q.length()<=80) return;
+
+ if (q.length()>200)
+ {
+ q.resize(200);
+ }
+
+ q.append(" ...");
+
+ QRegExp reg("[\\s|]");
+ QCString str(q.data());
+ QCString temp;
+
+ while (str.length()>80)
+ {
+ int j=str.findRev(reg,80);
+ if (j<=0)
+ {
+ temp+=str;
+ q=temp;
+ return;
+ }
+ else
+ {
+ QCString qcs=str.left(j);
+ temp+=qcs+"\\";
+ temp+="n";
+ str.remove(0,j);
+ }
+ }//while
+
+ q=temp+str;
+// #endif
+}
+
+void FlowChart::printNode(const FlowChart* flo)
+{
+ if (flo==0) return;
+ QCString ui="-";
+ QCString q,t;
+ QRegExp ep("[\t\n\r]");
+
+ ui.fill('-',255);
+
+ if (flo->type & STARTL)
+ {
+ if (flo->stamp>0)
+ {
+ q=ui.left(2*flo->stamp);
+ }
+ else
+ {
+ q=" ";
+ }
+ QCString nn=flo->exp.stripWhiteSpace();
+ printf("\nYES: %s%s[%d,%d]",q.data(),nn.data(),flo->stamp,flo->id);
+ }
+ else
+ {
+ if (flo->type & COMMENT_NO)
+ {
+ t=flo->label;
+ }
+ else
+ {
+ t=flo->text;
+ }
+ t=t.replace(ep,"");
+ if (t.isEmpty())
+ {
+ t=" ";
+ }
+ if (flo->stamp>0)
+ {
+ q=ui.left(2*flo->stamp);
+ }
+ else
+ {
+ q=" ";
+ }
+ if (flo->type & EMPTNODE)
+ {
+ printf("\n NO: %s%s[%d,%d]",q.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
+ }
+ else if (flo->type & COMMENT_NO)
+ {
+ printf("\n NO: %s%s[%d,%d]",t.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
+ }
+ else
+ {
+ printf("\n NO: %s%s[%d,%d]",q.data(),t.data(),flo->stamp,flo->id);
+ }
+ }
+}
+
+void FlowChart::printFlowTree()
+{
+ uint size=flowList.count();
+ for (uint j=0;j<size;j++)
+ {
+ printNode(flowList.at(j));
+ }
+}
+
+void FlowChart::colTextNodes()
+{
+ QCString text;
+ FlowChart *flno;
+ bool found=FALSE;
+ for (uint j=0;j<flowList.count();j++)
+ {
+ FlowChart *flo=flowList.at(j);
+ if (flo->type&TEXT_NO)
+ {
+ text+=flo->text+'\n';
+ if (!found)
+ {
+ flno=flo;
+ }
+ if (found)
+ {
+ flno->text+=flo->text;
+ flowList.remove(flo);
+ if (j>0) j=j-1;
+ }
+ found=TRUE;
+ }
+ else
+ found=FALSE;
+ }
+
+ // find if..endif without text
+ // if..elseif without text
+ for (uint j=0;j<flowList.count()-1;j++)
+ {
+ FlowChart *flo=flowList.at(j);
+ int kind=flo->type;
+ if ( (kind & IFF) || (flo->type & ELSE_NO))
+ {
+ FlowChart *ftemp=flowList.at(j+1);
+ if (ftemp->type & EMPTY)
+ {
+ FlowChart *fNew = new FlowChart(TEXT_NO,"empty ",0);
+ fNew->stamp=flo->stamp;
+ flowList.insert(j+1,fNew);
+ }
+ }
+ }
+
+}// colTextNode
+
+QCString FlowChart::getNodeName(int n)
+{
+ QCString node;
+ node.setNum(n);
+ return node.prepend("node");
+}
+
+void FlowChart::delFlowList()
+{
+ ifcounter=0;
+ nodeCounter=0;
+ uint size=flowList.count();
+
+ for (uint j=0;j <size ;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+ delete fll;
+ }
+ flowList.clear();
+}
+
+void FlowChart::alignCommentNode(FTextStream &t,QCString com)
+{
+ uint max=0;
+ QCString s;
+ QStringList ql=QStringList::split("\n",com);
+ for (uint j=0;j<ql.count();j++)
+ {
+ s=(QCString)ql[j].utf8();
+ if (max<s.length()) max=s.length();
+ }
+
+ s=ql.last().utf8();
+ int diff=max-s.length();
+
+ QCString n(1);
+ if (diff>0)
+ {
+ n.fill(' ',2*diff);
+ n.append(".");
+ s+=n;
+ ql.remove(ql.last());
+ ql.append(s);
+ }
+
+ for (uint j=0;j<ql.count();j++)
+ {
+ s=(QCString)ql[j].utf8();
+ if (j<ql.count()-1)
+ {
+ s+="\n";
+ }
+ FlowChart::codify(t,s.data());
+ }
+}
+
+
+void FlowChart::buildCommentNodes(FTextStream & t)
+{
+ uint size=flowList.count();
+ bool begin=false;
+
+ for (uint j=0;j < size-1 ;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+ if (fll->type & COMMENT_NO)
+ {
+ FlowChart* to=flowList.at(j+1);
+ if (to->type & COMMENT_NO)
+ {
+ fll->label+="\n";
+ QCString temp=fll->label+to->label;
+ to->label=temp;
+ flowList.remove(j);
+ size--;
+ if (j>0) j--;
+ }
+ }
+ }// for
+
+ for (uint j=0;j <flowList.count() ;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+
+ if (fll->type & BEGIN_NO)
+ {
+ begin = true;
+ continue;
+ }
+
+ if (fll->type & COMMENT_NO)
+ {
+ FlowChart* to;
+ if (!begin)
+ {
+ // comment between function/process .. begin is linked to start node
+ to=flowList.at(0);
+ }
+ else
+ {
+ if (j>0 && flowList.at(j-1)->line==fll->line)
+ to=flowList.at(j-1);
+ else
+ to=flowList.at(j+1);
+ }
+ t << getNodeName(fll->id);
+ t << "[shape=none, label=<\n";
+ t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
+ t << "<TR><TD BGCOLOR=\"";
+ t << flowCol.comment;
+ t << "\" > ";
+
+ FlowChart::alignCommentNode(t,fll->label);
+ t << " </TD></TR></TABLE>>];";
+ writeEdge(t,fll->id,to->id,2);
+ }
+ }// for
+
+ // delete comment nodes;
+ size=flowList.count();
+ for (uint j=0;j < size;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+ if (fll->type & (COMMENT_NO | BEGIN_NO))
+ {
+ flowList.remove(j);
+ delete fll;
+ fll=0;
+ size--;
+ if (j>0) j--;
+ }
+ }// for;
+}
+
+void FlowChart::codify(FTextStream &t,const char *str)
+{
+ if (str)
+ {
+ const char *p=str;
+ char c;
+ while (*p)
+ {
+ c=*p++;
+ switch(c)
+ {
+ case '<': t << "<"; break;
+ case '>': t << ">"; break;
+ case '&': t << "&"; break;
+ case '\'': t << "'"; break;
+ case '"': t << """; break;
+ case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
+ default: t << c; break;
+ }
+ }
+ }
+}//codify
+
+FlowChart::~FlowChart()
+{
+}
+
+FlowChart::FlowChart(int typ,const char * t,const char* ex,const char* lab)
+{
+ stamp=ifcounter;
+
+ if (typ & STARTL)
+ {
+ ifcounter++;
+ }
+
+ text=t;
+ exp=ex;
+ type=typ;
+ label=lab;
+
+ if (typ & (ELSE_NO | ELSIF_NO))
+ {
+ stamp--;
+ }
+
+ if (typ & (START_NO | END_NO | VARIABLE_NO))
+ {
+ stamp=0;
+ }
+
+ id=nodeCounter++;
+}
+
+void FlowChart::addFlowChart(int type,const char* text,const char* exp, const char *label)
+{
+ static QRegExp reg("[;]");
+ static QRegExp reg1("[\"]");
+
+ if (!VhdlDocGen::getFlowMember()) return;
+
+ QCString typeString(text);
+ QCString expression(exp);
+
+
+ if (text)
+ {
+ typeString=typeString.replace(reg,"\n");
+ }
+
+ if (exp)
+ {
+ expression=expression.replace(reg1,"\\\"");
+ }
+
+ FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label);
+
+ fl->line=vhdl::parser::VhdlParser::getLine();
+
+ if (type & (START_NO | VARIABLE_NO))
+ {
+ flowList.prepend(fl);
+ }
+ else
+ {
+ flowList.append(fl);
+ }
+
+}
+
+void FlowChart::moveToPrevLevel()
+{
+ if (!VhdlDocGen::getFlowMember()) return;
+ ifcounter--;
+}
+
+
+QCString FlowChart::convertNameToFileName()
+{
+ static QRegExp exp ("[^][a-z_A-Z0-9]");
+ QCString temp,qcs;
+ const MemberDef* md=VhdlDocGen::getFlowMember();
+
+ temp.sprintf("%p",md);
+ qcs=md->name();
+
+ if (qcs.find(exp,0)>=0)
+ {
+ qcs.prepend("Z");
+ qcs=qcs.replace(exp,"_");
+ }
+
+ return qcs+temp;
+}
+
+const char* FlowChart::getNodeType(int c)
+{
+ switch(c)
+ {
+ case IF_NO: return "if ";
+ case ELSIF_NO: return "elsif ";
+ case ELSE_NO: return "else ";
+ case CASE_NO: return "case ";
+ case WHEN_NO: return "when ";
+ case EXIT_NO: return "exit ";
+ case END_NO: return "end ";
+ case TEXT_NO: return "text ";
+ case START_NO: return "start ";
+ case ENDIF_NO: return "endif ";
+ case FOR_NO: return "for ";
+ case WHILE_NO: return "while ";
+ case END_LOOP: return "end_loop ";
+ case END_CASE: return "end_case ";
+ case VARIABLE_NO: return "variable_decl ";
+ case RETURN_NO: return "return ";
+ case LOOP_NO: return "infinte loop ";
+ case NEXT_NO: return "next ";
+ case COMMENT_NO: return "comment ";
+ case EMPTY_NO: return "empty ";
+ case BEGIN_NO: return "<begin> ";
+ default: return "--failure--";
+ }
+}
+
+void FlowChart::createSVG()
+{
+ QCString qcs("/");
+ QCString ov = Config_getString("HTML_OUTPUT");
+
+ qcs+=FlowChart::convertNameToFileName()+".svg";
+
+ //const MemberDef *m=VhdlDocGen::getFlowMember();
+ //if (m)
+ // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data());
+
+ QCString dir=" -o "+ov+qcs;
+ ov+="/flow_design.dot";
+
+ QCString vlargs="-Tsvg "+ov+dir ;
+
+ if (portable_system("dot",vlargs)!=0)
+ {
+ err("could not create dot file");
+ }
+}
+
+void FlowChart::startDot(FTextStream &t)
+{
+ t << " digraph G { \n";
+ t << "rankdir=TB \n";
+ t << "concentrate=true\n";
+ t << "stylesheet=\"doxygen.css\"\n";
+}
+
+void FlowChart::endDot(FTextStream &t)
+{
+ t << " } \n";
+}
+
+void FlowChart::writeFlowChart()
+{
+ // assert(VhdlDocGen::flowMember);
+
+ QCString ov = Config_getString("HTML_OUTPUT");
+ QCString fileName = ov+"/flow_design.dot";
+ QFile f(fileName);
+ FTextStream t(&f);
+
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing\n",fileName.data());
+ return;
+ }
+
+ colTextNodes();
+
+#ifdef DEBUGFLOW
+ printFlowTree();
+#endif
+
+ startDot(t);
+ buildCommentNodes(t);
+
+ uint size=flowList.count();
+
+ for (uint j=0;j <size ;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+ writeShape(t,fll);
+ }
+ writeFlowLinks(t);
+
+ FlowChart::endDot(t);
+ delFlowList();
+ f.close();
+ FlowChart::createSVG();
+}// writeFlowChart
+
+void FlowChart::writeShape(FTextStream &t,const FlowChart* fl)
+{
+ if (fl->type & EEND) return;
+ QCString var;
+ if (fl->type & LOOP)
+ {
+ var=" loop";
+ }
+ else if (fl->type & IFF)
+ {
+ var=" then";
+ }
+ else
+ {
+ var="";
+ }
+
+ t<<getNodeName(fl->id).data();
+ QCString q=getNodeType(fl->type);
+
+#ifdef DEBUGFLOW
+ QCString qq(getNodeName(fl->id).data());
+ keyMap.insert(qq,fl->id);
+#endif
+
+ bool dec=(fl->type & DECLN);
+ bool exit=(fl->type & EXITNEXT);
+ if (exit && !fl->exp.isEmpty())
+ {
+ dec=TRUE;
+ }
+ if (dec)
+ {
+ QCString exp=fl->exp;
+ alignText(exp);
+
+ t << " [shape=diamond,style=filled,color=\"";
+ t << flowCol.decisionNode;
+ t << "\",label=\" ";
+ QCString kl;
+ if (exit) kl=fl->text+" ";
+
+ if (fl->label)
+ {
+ kl+=fl->label+":"+exp+var;
+ }
+ else
+ {
+ kl+=exp+var;
+ }
+
+ FlowChart::alignCommentNode(t,kl);
+ t << "\"]\n";
+ }
+ else if (fl->type & ENDCL)
+ {
+ QCString val=fl->text;
+ t << " [shape=ellipse ,label=\""+val+"\"]\n";
+ }
+ else if (fl->type & STARTFIN)
+ {
+ QCString val=fl->text;
+ t << "[shape=box , style=rounded label=<\n";
+ t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
+ t << "<TR><TD BGCOLOR=\"";
+ t<< flowCol.startEndNode;
+ t<< "\"> ";
+ FlowChart::alignCommentNode(t,val);
+ t << " </TD></TR></TABLE>>];";
+ }
+ else
+ {
+ if (fl->text.isEmpty()) return;
+ bool var=(fl->type & FlowChart::VARIABLE_NO);
+ QCString repl("<BR ALIGN=\"LEFT\"/>");
+ QCString q=fl->text;
+
+ if (exit)
+ {
+ q+=" "+fl->label;
+ }
+
+ int z=q.findRev("\n");
+
+ if (z==(int)q.length()-1)
+ {
+ q=q.remove(z,2);
+ }
+ t << "[shape=none margin=0.1, label=<\n";
+ t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
+ if (var)
+ {
+ t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
+ }
+ else
+ {
+ t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
+ }
+ FlowChart::alignCommentNode(t,q);
+ t << " </TD></TR></TABLE>>];";
+ }
+}
+
+
+void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i)
+{
+ bool b=fl_from->type & STARTL;
+ bool c=fl_to->type & STARTL;
+
+#ifdef DEBUGFLOW
+ QCString s1(getNodeName(fl_from->id).data());
+ QCString s2(getNodeName(fl_to->id).data());
+ QMap<QCString, int>::Iterator it = keyMap.find(s1);
+ QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
+ // checks if the link is connected to a valid node
+ assert(it.key());
+ assert(it1.key());
+#endif
+
+ writeEdge(t,fl_from->id,fl_to->id,i,b,c);
+}
+
+void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
+{
+ QCString label,col;
+
+ if (i==0)
+ {
+ col=flowCol.yesNodeLink;
+ label="yes";
+ }
+ else if (i==1)
+ {
+ col=flowCol.noNodeLink;
+ label="no";
+ }
+ else
+ {
+ col=flowCol.textNodeLink;
+ label="";
+ }
+
+ t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
+ t << getNodeName(fl_from).data();
+ if (bFrom) t << ":s";
+ t << "->";
+ t << getNodeName(fl_to).data();
+ if (bTo) t << ":n";
+ t << "\n";
+}
+
+void FlowChart::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc)
+{
+ if (al==0) return;
+
+ ArgumentListIterator ali(*al);
+ int index=ali.count();
+ if (index==0) return;
+
+ int len=q.length()+VhdlDocGen::getFlowMember()->name().length();
+ QCString prev,temp;
+ prev.fill(' ',len+1);
+
+ Argument *arg;
+ q+="\n";
+ for (;(arg=ali.current());++ali)
+ {
+ QCString attl=arg->defval+" ";
+ attl+=arg->name+" ";
+
+ if (!isFunc)
+ {
+ attl+=arg->attrib+" ";
+ }
+ else
+ {
+ attl+=" in ";
+ }
+ attl+=arg->type;
+ if (--index) attl+=",\n"; else attl+="\n";
+
+ attl.prepend(prev.data());
+ temp+=attl;
+ }
+
+ q+=temp;
+}
+
+int FlowChart::findNextLoop(int index,int stamp)
+{
+ for (uint j=index+1;j<flowList.count();j++)
+ {
+ FlowChart *flo=flowList.at(j);
+ if (flo->stamp==stamp)
+ {
+ continue;
+ }
+ if (flo->type&END_LOOP)
+ {
+ return j;
+ }
+ }
+ return flowList.count()-1;
+}
+
+int FlowChart::findPrevLoop(int index,int stamp,bool endif)
+{
+ for (uint j=index;j>0;j--)
+ {
+ FlowChart *flo=flowList.at(j);
+ if (flo->type & LOOP)
+ {
+ if (flo->stamp==stamp && endif)
+ {
+ return j;
+ }
+ else
+ {
+ if (flo->stamp<stamp)
+ {
+ return j;
+ }
+ }
+ }
+ }
+ return flowList.count()-1;
+}
+
+int FlowChart::findLabel(int index,QCString &label)
+{
+ for (uint j=index;j>0;j--)
+ {
+ FlowChart *flo=flowList.at(j);
+ if ((flo->type & LOOP) && !flo->label.isEmpty() && qstricmp(flo->label,label)==0)
+ {
+ return j;
+ }
+ }
+ err("could not find label: ",label.data());
+ return 0;
+}
+
+int FlowChart::findNode(int index,int stamp,int type)
+{
+ for (uint j=index+1;j<flowList.count();j++)
+ {
+ FlowChart *flo=flowList.at(j);
+ if (flo->type==type && flo->stamp==stamp)
+ {
+ return j;
+ }
+ }
+ return 0;
+}// findNode
+
+int FlowChart::getNextNode(int index,int stamp)
+{
+ for (uint j=index+1;j<flowList.count();j++)
+ {
+ FlowChart *flo=flowList.at(j);
+ int kind=flo->type;
+ int s=flo->stamp;
+ if (s>stamp)
+ {
+ continue;
+ }
+ if (kind & ENDIF_NO)
+ {
+ if (s<stamp && stamp>0)
+ {
+ stamp--;
+ continue;
+ }
+ }
+ if (kind & (ELSE_NO | ELSIF_NO))
+ {
+ if (s<stamp && stamp>0)
+ {
+ stamp--;
+ }
+ j=findNode(j,stamp,ENDIF_NO);
+ continue;
+ }
+ if (kind & WHEN_NO)
+ {
+ if (s<stamp && stamp>0)
+ {
+ stamp--;
+ }
+ return findNode(j,stamp-1,END_CASE);
+ }
+ return j;
+ }
+ return FLOWLEN;
+}
+
+int FlowChart::getNextIfLink(const FlowChart* fl,uint index)
+{
+ int stamp=fl->stamp;
+ uint start = index+1;
+ int endifNode = findNode(start,stamp,ENDIF_NO);
+ int elseifNode = findNode(start,stamp,ELSIF_NO);
+ int elseNode = findNode(start,stamp,ELSE_NO);
+
+ assert(endifNode>-1);
+
+ if (elseifNode>0 && elseifNode<endifNode)
+ {
+ return elseifNode;
+ }
+
+ if (elseNode>0 && elseNode<endifNode)
+ {
+ return elseNode+1;
+ }
+
+ stamp=flowList.at(endifNode)->stamp;
+ return getNextNode(endifNode,stamp);
+}
+
+void FlowChart::writeFlowLinks(FTextStream &t)
+{
+ uint size=flowList.count();
+ if (size<2) return;
+
+ // write start link
+ writeEdge(t,flowList.at(0),flowList.at(1),2);
+
+ for (uint j=0;j<size;j++)
+ {
+ FlowChart *fll=flowList.at(j);
+ int kind=fll->type;
+ int stamp=fll->stamp;
+ if (kind & EEND)
+ {
+ continue;
+ }
+
+ if (kind & IFF)
+ {
+ writeEdge(t,fll,flowList.at(j+1),0);
+ int z=getNextIfLink(fll,j);
+ // assert(z>-1);
+ writeEdge(t,fll,flowList.at(z),1);
+ }
+ else if (kind & LOOP_NO)
+ {
+ writeEdge(t,fll,flowList.at(j+1),2);
+ continue;
+ }
+ else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
+ {
+ if (kind & CASE_NO)
+ {
+ writeEdge(t,fll,flowList.at(j+1),2);
+ continue;
+ }
+ else
+ {
+ writeEdge(t,fll,flowList.at(j+1),0);
+ }
+
+ kind=END_LOOP;
+ int z=findNode(j+1,fll->stamp,kind);
+ z=getNextNode(z,flowList.at(z)->stamp);
+
+ // assert(z>-1);
+ writeEdge(t,fll,flowList.at(z),1);
+ continue;
+ }
+ else if (kind & (TEXT_NO | VARIABLE_NO))
+ {
+ int z=getNextNode(j,stamp);
+ writeEdge(t,fll,flowList.at(z),2);
+ }
+ else if (kind & WHEN_NO)
+ {
+ // default value
+ if (qstricmp(fll->text.simplifyWhiteSpace().data(),"others")==0)
+ {
+ writeEdge(t,fll,flowList.at(j+1),2);
+ continue;
+ }
+
+
+ writeEdge(t,fll,flowList.at(j+1),0);
+ int u=findNode(j,stamp,WHEN_NO);
+ int v=findNode(j,stamp-1,END_CASE);
+
+ if (u>0 && u<v)
+ {
+ writeEdge(t,fll,flowList.at(u),1);
+ }
+ else
+ {
+ writeEdge(t,fll,flowList.at(v),1);
+ }
+ }
+ else if (kind & END_CASE)
+ {
+ int z=FlowChart::getNextNode(j,fll->stamp);
+ writeEdge(t,fll,flowList.at(z),2);
+ }
+ else if (kind & END_LOOP)
+ {
+ int z=findPrevLoop(j,fll->stamp,true);
+ writeEdge(t,fll,flowList.at(z),2);
+ }
+ else if (kind & RETURN_NO)
+ {
+ writeEdge(t,fll,FlowChart::flowList.at(size-1),2);
+ }
+ else if (kind & (EXIT_NO | NEXT_NO))
+ {
+ int z;
+ bool b = kind==NEXT_NO;
+ if (fll->exp)
+ {
+ writeEdge(t,fll,flowList.at(j+1),1);
+ }
+ if (!fll->label.isEmpty())
+ {
+ z=findLabel(j,fll->label);
+ if (b)
+ {
+ writeEdge(t,fll,flowList.at(z),0);
+ }
+ else
+ {
+ z=findNode(z,flowList.at(z)->stamp,END_LOOP);
+ z=getNextNode(z,flowList.at(z)->stamp);
+ writeEdge(t,fll,flowList.at(z),0);
+ }
+ continue;
+ }
+ else
+ {
+ if (b)
+ {
+ z=findPrevLoop(j,fll->stamp);
+ writeEdge(t,fll,flowList.at(z),0);
+ continue;
+ }
+ else
+ {
+ z =findNextLoop(j,fll->stamp-1);
+ }
+ z=getNextNode(z,flowList.at(z)->stamp);
+ }
+ writeEdge(t,fll,flowList.at(z),0);
+ }
+ } //for
+} //writeFlowLinks
+
+
+void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt, // lang
+ bool isExampleBlock,
+ const char *exampleName,
+ FileDef *fileDef,
+ int startLine,
+ int endLine,
+ bool inlineFragment,
+ MemberDef *memberDef,
+ bool showLineNumbers,
+ Definition *searchCtx,
+ bool collectXRefs
+ )
+{
+
+parseVhdlCode(codeOutIntf,
+ scopeName,
+ input,
+ isExampleBlock,
+ exampleName,
+ fileDef,
+ startLine,
+ endLine,
+ inlineFragment,
+ memberDef,
+ showLineNumbers,
+ searchCtx,
+ collectXRefs
+
+);
+
+}
diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h
new file mode 100644
index 0000000..b9f9afb
--- /dev/null
+++ b/src/vhdldocgen.h
@@ -0,0 +1,345 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2013 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef VHDLDOCGEN_H
+#define VHDLDOCGEN_H
+
+/**
+ * This class implements functions for parsing and generating
+ * vhdl documents
+ */
+
+#include <qdict.h>
+#include <qcstring.h>
+#include "layout.h"
+#include "arguments.h"
+#include "entry.h"
+
+class Entry;
+class ClassDef;
+class MemberList;
+class MemberDef;
+class FTextStream;
+class OutputList;
+class Definition;
+class GroupDef;
+class FileDef;
+class NamespaceDef;
+struct Argument;
+
+/** Class for generating documentation specific for VHDL */
+class VhdlDocGen
+{
+ public:
+
+ enum VhdlClasses // Overlays: Protection
+ {
+ ENTITYCLASS, // Overlays: Public
+ PACKBODYCLASS, // Overlays: Protected
+ ARCHITECTURECLASS, // Overlays: Private
+ PACKAGECLASS // Overlays: Package
+ };
+
+ enum VhdlKeyWords
+ {
+ LIBRARY=1,
+ ENTITY,
+ PACKAGE_BODY,
+ ARCHITECTURE,
+ PACKAGE,
+ ATTRIBUTE,
+ SIGNAL,
+ COMPONENT,
+ CONSTANT,
+ TYPE,
+ SUBTYPE,
+ FUNCTION,
+ RECORD,
+ PROCEDURE,
+ USE,
+ PROCESS,
+ PORT,
+ UNITS,
+ GENERIC,
+ INSTANTIATION,
+ GROUP,
+ VFILE,
+ SHAREDVARIABLE,
+ CONFIG,
+ ALIAS,
+ MISCELLANEOUS,
+ UCF_CONST
+ };
+
+ VhdlDocGen();
+ virtual ~VhdlDocGen();
+ static void init();
+ static QCString convertFileNameToClassName(QCString name);
+ // --- used by vhdlscanner.l -----------
+
+ static bool isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level);
+
+ static QCString getIndexWord(const char* ,int index);
+ static bool deleteCharRev(QCString &s,char c);
+ static void deleteAllChars(QCString &s,char c);
+ static void parseFuncProto(const char* text,
+ QList<Argument>& ,
+ QCString& name,
+ QCString& ret,
+ bool doc=false);
+ // -----------------------------------
+
+ static void computeVhdlComponentRelations();
+
+ static QCString* findKeyWord(const QCString& word);
+
+ static ClassDef* getPackageName(const QCString& name);
+ static MemberDef* findMember(const QCString& className,
+ const QCString& memName);
+ static void findAllPackages(ClassDef*);
+ static MemberDef* findMemberDef(ClassDef* cd,
+ const QCString& key,
+ MemberListType type);
+ static ClassDef *getClass(const char *name);
+ static MemberDef* findFunction(const QList<Argument> &ql,
+ const QCString& name,
+ const QCString& package, bool type);
+ static QCString getClassTitle(const ClassDef*);
+ static void writeInlineClassLink(const ClassDef*,
+ OutputList &ol);
+
+ static bool isConstraint(const MemberDef *mdef);
+ static bool isConfig(const MemberDef *mdef);
+ static bool isAlias(const MemberDef *mdef);
+ static bool isLibrary(const MemberDef *mdef);
+ static bool isGeneric(const MemberDef *mdef);
+ static bool isPort(const MemberDef *mdef);
+ static bool isComponent(const MemberDef *mdef);
+ static bool isPackage(const MemberDef *mdef);
+ static bool isEntity(const MemberDef *mdef);
+ static bool isConstant(const MemberDef *mdef);
+ static bool isVType(const MemberDef *mdef);
+ static bool isSubType(const MemberDef *mdef);
+ static bool isVhdlFunction(const MemberDef *mdef);
+ static bool isProcess(const MemberDef *mdef);
+ static bool isSignal(const MemberDef *mdef);
+ static bool isAttribute(const MemberDef *mdef);
+ static bool isSignals(const MemberDef *mdef);
+ static bool isProcedure(const MemberDef *mdef);
+ static bool isRecord(const MemberDef *mdef);
+ static bool isArchitecture(const MemberDef *mdef);
+ static bool isUnit(const MemberDef *mdef);
+ static bool isPackageBody(const MemberDef *mdef);
+ static bool isVariable(const MemberDef *mdef);
+ static bool isFile(const MemberDef *mdef);
+ static bool isGroup(const MemberDef *mdef);
+ static bool isCompInst(const MemberDef *mdef);
+ static bool isMisc(const MemberDef *mdef);
+
+ //-----------------------------------------------------
+ // translatable items
+
+ static QCString trTypeString(uint64 type);
+ static QCString trVhdlType(uint64 type,bool sing=true);
+
+ // trClassHierarchy.
+ static QCString trDesignUnitHierarchy();
+
+ // trCompoundList
+ static QCString trDesignUnitList();
+
+ // trCompoundMembers.
+ static QCString trDesignUnitMembers();
+
+ // trCompoundListDescription
+ static QCString trDesignUnitListDescription();
+
+ // trCompounds
+ static QCString trDesignUnits();
+
+ // trCompoundIndex
+ static QCString trDesignUnitIndex();
+
+ // trFunctions
+ static QCString trFunctionAndProc();
+
+ //-----------------------------------------------------
+
+ static void prepareComment(QCString&);
+ static void formatString(const QCString&,OutputList& ol,const MemberDef*);
+
+ static void writeFormatString(const QCString&,OutputList& ol,const MemberDef*);
+ static void writeFunctionProto(OutputList& ol,const ArgumentList *al,const MemberDef*);
+ static void writeProcessProto(OutputList& ol,const ArgumentList *al,const MemberDef*);
+ static void writeProcedureProto(OutputList& ol, const ArgumentList *al,const MemberDef*);
+ static bool writeFuncProcDocu(const MemberDef *mdef, OutputList& ol,const ArgumentList* al,bool type=false);
+ static void writeRecordProto(const MemberDef *mdef, OutputList& ol,const ArgumentList *al);
+
+ static bool writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition* d, OutputList &ol);
+
+ static void writeVhdlDeclarations(MemberList*,OutputList&,GroupDef*,ClassDef*,FileDef*,NamespaceDef*);
+
+ static void writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool inGroup);
+
+ static void writePlainVHDLDeclarations(MemberList* ml,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier);
+
+ static void writeVHDLDeclarations(MemberList* ml,OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const char *title,const char *subtitle,bool showEnumValues,int type);
+
+ static bool writeClassType(ClassDef *&,OutputList &ol ,QCString & cname);
+
+ static QCString convertArgumentListToString(const ArgumentList* al,bool f);
+ static QCString getProcessNumber();
+ static QCString getRecordNumber();
+
+ static QCString getClassName(const ClassDef*);
+ static bool isNumber(const QCString& s);
+ static QCString getProtectionName(int prot);
+
+ static void parseUCF(const char* input,Entry* entity,QCString f,bool vendor);
+ static bool findConstraintFile( LayoutNavEntry *lne);
+
+ static ClassDef* findArchitecture(const ClassDef *cd);
+ static ClassDef* findArchitecture(QCString identifier, QCString entity_name);
+
+
+ static void writeSource(MemberDef *mdef,OutputList& ol,QCString & cname);
+ static void writeAlphbeticalClass(OutputList& ol,const ClassDef* cd,const QCString &);
+
+ static QCString parseForConfig(QCString & entity,QCString & arch);
+ static QCString parseForBinding(QCString & entity,QCString & arch);
+ static void addBaseClass(ClassDef* cd,ClassDef *ent);
+ static ClassDef* findVhdlClass(const char *className );
+
+ static void writeOverview(OutputList &ol);
+ static void writeOverview();
+
+ // flowcharts
+ static void createFlowChart(const MemberDef*);
+ //static void addFlowImage(const FTextStream &,const QCString &);
+
+ static void setFlowMember( const MemberDef *flowMember);
+ static const MemberDef *getFlowMember();
+
+ static bool isVhdlClass (const Entry *cu)
+ {
+ return cu->spec==VhdlDocGen::ENTITY ||
+ cu->spec==VhdlDocGen::PACKAGE ||
+ cu->spec==VhdlDocGen::ARCHITECTURE ||
+ cu->spec==VhdlDocGen::PACKAGE_BODY;
+ }
+
+ static void resetCodeVhdlParserState();
+
+ private:
+ static void findAllArchitectures(QList<QCString>& ql,const ClassDef *cd);
+ static bool compareArgList(ArgumentList*,ArgumentList*);
+ static void writeVhdlLink(const ClassDef* cdd ,OutputList& ol,QCString& type,QCString& name,QCString& beh);
+ static void writeStringLink(const MemberDef *mdef,QCString mem,OutputList& ol);
+ static void writeRecUnitDocu( const MemberDef *md, OutputList& ol,QCString largs);
+ static void writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef);
+};
+
+//-------------------------------------------------------------------------------------------------------------------
+//-------------- VHDL Flowcharts -------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------------------------------------------
+
+
+//#define DEBUGFLOW
+
+class FlowChart
+{
+ public:
+ enum nodeTypes {
+ IF_NO = 1<<1,
+ ELSIF_NO = 1<<2,
+ ELSE_NO = 1<<3,
+ CASE_NO = 1<<4,
+ WHEN_NO = 1<<5,
+ EXIT_NO = 1<<6,
+ END_NO = 1<<7,
+ TEXT_NO = 1<<8,
+ START_NO = 1<<9,
+ ENDIF_NO = 1<<10,
+ FOR_NO = 1<<11,
+ WHILE_NO = 1<<12,
+ END_LOOP = 1<<13,
+ END_CASE = 1<<14,
+ VARIABLE_NO = 1<<15,
+ RETURN_NO = 1<<16,
+ LOOP_NO = 1<<17,
+ NEXT_NO = 1<<18,
+ EMPTY_NO = 1<<19,
+ COMMENT_NO = 1<<20,
+ BEGIN_NO = 1<<21
+ };
+
+ //---------- create svg -------------------------------------------------------------
+ static void createSVG();
+ static void startDot(FTextStream &t);
+ static void endDot(FTextStream &t);
+ static void codify(FTextStream &t,const char *str);
+ static void writeShape(FTextStream &t,const FlowChart* fl);
+ static void writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom=FALSE,bool bTo=FALSE);
+ static void writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i);
+ static void writeFlowLinks(FTextStream &t);
+
+ static QCString getNodeName(int n);
+ static void colTextNodes();
+
+ static int getNextTextLink(const FlowChart* fl,uint index);
+ static int getNextIfLink(const FlowChart*,uint);
+ static int getNextNode(int,int);
+ static int findNode(int index,int stamp,int type);
+ static int findNode(int index,int type);
+ static int findNextLoop(int j,int stamp);
+ static int findPrevLoop(int j,int stamp,bool endif=FALSE);
+ static int findLabel(int j,QCString &);
+ static void delFlowList();
+ static const char* getNodeType(int c);
+
+ static void addFlowChart(int type,const char* text,const char* exp,const char * label=NULL);
+ static void moveToPrevLevel();
+ static int getTimeStamp();
+ static void writeFlowChart();
+ static void alignFuncProc(QCString & q,const ArgumentList* al,bool isFunc);
+ static QCString convertNameToFileName();
+ static void printNode(const FlowChart* n);
+ static void printFlowTree();
+ static void buildCommentNodes(FTextStream &t);
+ static void alignCommentNode(FTextStream &t,QCString com);
+
+ static QList<FlowChart> flowList;
+
+ FlowChart(int typ,const char* t,const char* ex,const char* label=0);
+ ~FlowChart();
+
+private:
+ int id;
+ int stamp;
+ int type;
+
+ int line;
+
+ QCString label;
+ QCString text;
+ QCString exp;
+};
+
+#endif
diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp
new file mode 100644
index 0000000..f31c9fb
--- /dev/null
+++ b/src/vhdljjparser.cpp
@@ -0,0 +1,828 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 by M. Kreis
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#include <qcstring.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include "vhdljjparser.h"
+#include "vhdlcode.h"
+#include "vhdldocgen.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "language.h"
+#include "commentscan.h"
+#include "index.h"
+#include "definition.h"
+#include "searchindex.h"
+#include "outputlist.h"
+#include "arguments.h"
+#include "types.h"
+#include "VhdlParserIF.h"
+
+using namespace vhdl::parser;
+using namespace std;
+
+static ParserInterface *g_thisParser;
+
+static QCString yyFileName;
+static int yyLineNr = 1;
+static int* lineParse;
+static int iDocLine = -1;
+static QCString inputString;
+static Entry gBlock;
+static Entry* previous = 0;
+#if 0
+int iLine;
+QStringList qrl;
+ParserInterface *g_thisParser;
+int inputPosition;
+int inputLen;
+int startComment = 0;
+QFile inputFile;
+QCString inbuf;
+
+QCString yyFileName;
+bool g_lexInit = FALSE;
+int yyLineNr = 1;
+int g_lastCommentContext = 0;
+bool docBlockAutoBrief;
+char docBlockTerm;
+int iDocLine = -1;
+int num_chars;
+int* lineParse;
+#endif
+//-------------------------------------------------------
+
+static Entry* oldEntry;
+static bool varr=FALSE;
+static QCString varName;
+
+static QList<Entry> instFiles;
+static QList<Entry> libUse;
+static QList<Entry> lineEntry;
+
+Entry* VhdlParser::currentCompound=0;
+Entry* VhdlParser::tempEntry=0;
+Entry* VhdlParser::lastEntity=0 ;
+Entry* VhdlParser::lastCompound=0 ;
+Entry* VhdlParser::current=0;
+Entry* VhdlParser::current_root = 0;
+QCString VhdlParser::compSpec;
+QCString VhdlParser::currName;
+QCString VhdlParser::confName;
+QCString VhdlParser::genLabels;
+QCString VhdlParser::lab;
+QCString VhdlParser::forL;
+
+int VhdlParser::param_sec = 0;
+int VhdlParser::parse_sec=0;
+int VhdlParser::currP=0;
+int VhdlParser::levelCounter;
+
+static QList<VhdlConfNode> configL;
+
+struct
+{
+ QCString doc;
+ bool brief;
+ bool pending;
+ int iDocLine;
+} str_doc;
+
+static bool doxComment=FALSE; // doxygen comment ?
+static QCString strComment;
+static int iCodeLen;
+
+bool checkMultiComment(QCString& qcs,int line);
+QList<Entry>* getEntryAtLine(const Entry* ce,int line);
+
+//-------------------------------------
+
+QList<VhdlConfNode>& getVhdlConfiguration() { return configL; }
+QList<Entry>& getVhdlInstList() { return instFiles; }
+
+Entry* getVhdlCompound()
+{
+ if (VhdlParser::lastEntity) return VhdlParser::lastEntity;
+ if (VhdlParser::lastCompound) return VhdlParser::lastCompound;
+ return NULL;
+}
+
+void startCodeBlock(int index)
+{
+ int ll=strComment.length();
+ iCodeLen=inputString.findRev(strComment.data())+ll;
+ // fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll);
+ //assert(false);
+ gBlock.reset();
+ int len=strComment.length();
+ QCString name=strComment.right(len-index);//
+ name=VhdlDocGen::getIndexWord(name.data(),1);
+ if (!name)
+ gBlock.name="misc"+ VhdlDocGen::getRecordNumber();
+ else
+ gBlock.name=name;
+
+ //int li=strComment.contains('\n');
+
+ gBlock.startLine=yyLineNr;
+ gBlock.bodyLine=yyLineNr;
+
+ strComment=strComment.left(index);
+ VhdlDocGen::prepareComment(strComment);
+ gBlock.brief+=strComment;
+}
+
+void makeInlineDoc(int endCode)
+{
+ int len=endCode-iCodeLen;
+ QCString par=inputString.mid(iCodeLen,len);
+ //fprintf(stderr,"\n inline code: \n<%s>",par.data());
+ gBlock.doc=par;
+ gBlock.inbodyDocs=par;
+ gBlock.section=Entry::VARIABLE_SEC;
+ gBlock.spec=VhdlDocGen::MISCELLANEOUS;
+ gBlock.fileName = yyFileName;
+ gBlock.endBodyLine=yyLineNr-1;
+ gBlock.lang=SrcLangExt_VHDL;
+ Entry *temp=new Entry(gBlock);
+ Entry* compound=getVhdlCompound();
+
+ if (compound)
+ {
+ compound->addSubEntry(temp);
+ }
+ else
+ {
+ temp->type="misc"; // global code like library ieee...
+ VhdlParser::current_root->addSubEntry(temp);
+ }
+ strComment.resize(0);
+ gBlock.reset();
+}// makeInlineDoc
+
+
+bool isConstraintFile(const QCString &fileName,const QCString &ext)
+{
+ return fileName.right(ext.length())==ext;
+}
+
+
+void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root,
+ bool ,QStrList&)
+{
+ g_thisParser=this;
+ bool inLine=false;
+ inputString=fileBuf;
+ if (strlen(fileName)==0)
+ {
+ inLine=true;
+ }
+
+ yyFileName+=fileName;
+
+ bool xilinx_ucf=isConstraintFile(yyFileName,".ucf");
+ bool altera_qsf=isConstraintFile(yyFileName,".qsf");
+
+ // support XILINX(ucf) and ALTERA (qsf) file
+
+ if (xilinx_ucf)
+ {
+ VhdlDocGen::parseUCF(fileBuf,root,yyFileName,FALSE);
+ return;
+ }
+ if (altera_qsf)
+ {
+ VhdlDocGen::parseUCF(fileBuf,root,yyFileName,TRUE);
+ return;
+ }
+ libUse.setAutoDelete(true);
+ yyLineNr=1;
+ VhdlParser::current_root=root;
+ VhdlParser::lastCompound=0;
+ VhdlParser::lastEntity=0;
+ VhdlParser::currentCompound=0;
+ VhdlParser::lastEntity=0;
+ VhdlParser::current=new Entry();
+ VhdlParser::initEntry(VhdlParser::current);
+ groupEnterFile(fileName,yyLineNr);
+ lineParse=new int[200];
+ VhdlParserIF::parseVhdlfile(fileBuf,inLine);
+
+ delete VhdlParser::current;
+ VhdlParser::current=0;
+
+ if (!inLine)
+ VhdlParser::mapLibPackage(root);
+
+ delete lineParse;
+ yyFileName.resize(0);
+ libUse.clear();
+ VhdlDocGen::resetCodeVhdlParserState();
+}
+
+void VhdlParser::lineCount(){ yyLineNr++; }
+
+void VhdlParser::lineCount(const char* text)
+{
+ for (const char* c=text ; *c ; ++c )
+ {
+ yyLineNr += (*c == '\n') ;
+ }
+}
+
+void isVhdlDocPending()
+{
+ if (!str_doc.pending) return;
+
+ str_doc.pending=FALSE;
+ oldEntry=0; // prevents endless recursion
+ iDocLine=str_doc.iDocLine;
+ VhdlParser::handleCommentBlock(str_doc.doc,str_doc.brief);
+ iDocLine=-1;
+}
+
+void VhdlParser::initEntry(Entry *e)
+{
+ e->fileName = yyFileName;
+ e->lang = SrcLangExt_VHDL;
+ isVhdlDocPending();
+ initGroupInfo(e);
+}
+
+void VhdlParser::newEntry()
+{
+ if (current->spec==VhdlDocGen::ENTITY ||
+ current->spec==VhdlDocGen::PACKAGE ||
+ current->spec==VhdlDocGen::ARCHITECTURE ||
+ current->spec==VhdlDocGen::PACKAGE_BODY)
+ {
+ current_root->addSubEntry(current);
+ }
+ else
+ {
+ if (lastCompound)
+ {
+ lastCompound->addSubEntry(current);
+ }
+ else
+ {
+ if (lastEntity)
+ {
+ lastEntity->addSubEntry(current);
+ }
+ else
+ {
+ current_root->addSubEntry(current);
+ }
+ }
+ }
+ previous = current;
+ current = new Entry ;
+ initEntry(current);
+}
+
+bool checkInlineCode(QCString & doc)
+{
+ int index=doc.find("\\code");
+
+ if (index>0)
+ {
+ strComment+=doc;
+ startCodeBlock(index);
+ doxComment=TRUE;
+ return true;
+ }
+ return false;
+}
+
+void VhdlParser::handleFlowComment(const char* doc)
+{
+ lineCount(doc);
+ if (VhdlDocGen::getFlowMember())
+ {
+ QCString qcs(doc);
+ qcs=qcs.stripWhiteSpace();
+ qcs.stripPrefix("--#");
+ FlowChart::addFlowChart(FlowChart::COMMENT_NO,0,0,qcs.data());
+ }
+}
+
+void VhdlParser::handleCommentBlock(const char* doc1,bool brief)
+{
+ int position=0;
+ static bool isIn;
+ QCString doc(doc1);
+ if (doc.isEmpty()) return;
+
+ if (checkMultiComment(doc,yyLineNr))
+ {
+ lineCount(doc1);
+ return;
+ }
+
+ isIn=checkInlineCode(doc);
+ bool isEndCode=doc.contains("\\endcode");
+ // empty comment --!
+ if (isEndCode)
+ {
+ int end=inputString.find(doc.data(),iCodeLen);
+ makeInlineDoc(end);
+ strComment.resize(0);
+ isIn=false;
+ }
+ if (isIn)
+ {
+ isIn=false;
+ lineCount(doc1);
+ return;
+ }
+
+ VhdlDocGen::prepareComment(doc);
+
+ bool needsEntry=FALSE;
+ Protection protection=Public;
+ int lineNr = iDocLine;
+
+ if (oldEntry==current)
+ {
+ //printf("\n find pending message < %s > at line: %d \n ",doc.data(),iDocLine);
+ str_doc.doc=doc;
+ str_doc.iDocLine=iDocLine;
+ str_doc.brief=brief;
+ str_doc.pending=TRUE;
+ return;
+ }
+
+ oldEntry=current;
+
+ if (brief)
+ {
+ current->briefLine = yyLineNr;
+ }
+ else
+ {
+ current->docLine = yyLineNr;
+ }
+ // printf("parseCommentBlock file<%s>\n [%s]\n",yyFileName.data(),doc.data());
+ while (parseCommentBlock(
+ g_thisParser,
+ current,
+ doc, // text
+ yyFileName, // file
+ lineNr, // line of block start
+ brief,
+ 0,
+ FALSE,
+ protection,
+ position,
+ needsEntry
+ )
+ )
+ {
+ //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
+ if (needsEntry) newEntry();
+ }
+ if (needsEntry)
+ {
+ if (varr)
+ {
+ varr=FALSE;
+ current->name=varName;
+ current->section=Entry::VARIABLEDOC_SEC;
+ varName="";
+ }
+ newEntry();
+ }
+ lineCount(doc1);
+}
+
+void VHDLLanguageScanner::parsePrototype(const char *text)
+{
+ varName=text;
+ varr=TRUE;
+}
+
+void VhdlParser::addCompInst(char *n, char* instName, char* comp,int iLine)
+{
+ current->spec=VhdlDocGen::INSTANTIATION;
+ current->section=Entry::VARIABLE_SEC;
+ current->startLine=iLine;
+ current->bodyLine=iLine;
+ current->type=instName; // foo:instname e.g proto or work. proto(ttt)
+ current->exception=genLabels.lower(); // |arch|label1:label2...
+ current->name=n; // foo
+ current->args=lastCompound->name; // architecture name
+ current->includeName=comp; // component/enity/configuration
+ int u=genLabels.find("|",1);
+ if (u>0)
+ {
+ current->write=genLabels.right(genLabels.length()-u);
+ current->read=genLabels.left(u);
+ }
+ //printf (" \n genlable: [%s] inst: [%s] name: [%s] %d\n",n,instName,comp,iLine);
+
+ if (lastCompound)
+ {
+ current->args=lastCompound->name;
+ if (true) // !findInstant(current->type))
+ {
+ initEntry(current);
+ instFiles.append(new Entry(*current));
+ }
+
+ Entry *temp=current; // hold current pointer (temp=oldEntry)
+ current=new Entry; // (oldEntry != current)
+ delete temp;
+ }
+ else
+ {
+ newEntry();
+ }
+}
+
+void VhdlParser::addVhdlType(const char *n,int startLine,int section,
+ uint64 spec,const char* args,const char* type,Protection prot)
+{
+ static QRegExp reg("[\\s]");
+ QCString name(n);
+ if (isFuncProcProced() || VhdlDocGen::getFlowMember()) return;
+
+ if (parse_sec==GEN_SEC)
+ {
+ spec= VhdlDocGen::GENERIC;
+ }
+
+ QStringList ql=QStringList::split(",",name,FALSE);
+
+ for (uint u=0;u<ql.count();u++)
+ {
+ current->name=ql[u].utf8();
+ current->startLine=startLine;
+ current->bodyLine=startLine;
+ current->section=section;
+ current->spec=spec;
+ current->fileName=yyFileName;
+ if (current->args.isEmpty())
+ {
+ current->args=args;
+ }
+ current->type=type;
+ current->protection=prot;
+
+ if (!lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) )
+ {
+ libUse.append(new Entry(*current));
+ current->reset();
+ }
+ newEntry();
+ }
+}
+
+void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn)
+{
+ QCString impure(imp);
+ QCString fname(fn);
+ current->spec=spec;
+ current->section=Entry::FUNCTION_SEC;
+
+ if (impure=="impure" || impure=="pure")
+ {
+ current->exception=impure;
+ }
+
+ if (parse_sec==GEN_SEC)
+ {
+ current->spec= VhdlDocGen::GENERIC;
+ current->section=Entry::FUNCTION_SEC;
+ }
+
+ if (currP==VhdlDocGen::PROCEDURE)
+ {
+ current->name=impure;
+ current->exception="";
+ }
+ else
+ {
+ current->name=fname;
+ }
+
+ if (spec==VhdlDocGen::PROCESS)
+ {
+ current->args=fname;
+ current->name=impure;
+ VhdlDocGen::deleteAllChars(current->args,' ');
+ if (!fname.isEmpty())
+ {
+ QStringList q1=QStringList::split(",",fname);
+ for (uint ii=0;ii<q1.count();ii++)
+ {
+ Argument *arg=new Argument;
+ arg->name=q1[ii].utf8();
+ current->argList->append(arg);
+ }
+ }
+ return;
+ }
+ }
+
+
+bool VhdlParser::isFuncProcProced()
+{
+ if (currP==VhdlDocGen::FUNCTION ||
+ currP==VhdlDocGen::PROCEDURE ||
+ currP==VhdlDocGen::PROCESS
+ )
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void VhdlParser::pushLabel( QCString &label,QCString & val)
+{
+ label+="|";
+ label+=val;
+}
+
+ QCString VhdlParser::popLabel(QCString & q)
+{
+ QCString u=q;
+ int i=q.findRev("|");
+ if (i<0) return "";
+ q = q.left(i);
+ return q;
+}
+
+void VhdlParser::addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf)
+{
+ VhdlConfNode* co=0;
+ QCString ent,arch,lab;
+ QCString l=genLabels;
+ ent=a;
+ // lab = VhdlDocGen::parseForConfig(ent,arch);
+
+ if (b)
+ {
+ ent=b;
+ // lab=VhdlDocGen::parseForBinding(ent,arch);
+ }
+ int level=0;
+
+ if (!configL.isEmpty())
+ {
+ VhdlConfNode* vc=configL.getLast();
+ level=vc->level;
+ if (levelCounter==0)
+ {
+ pushLabel(forL,ent);
+ }
+ else if (level<levelCounter)
+ {
+ if (!isLeaf)
+ {
+ pushLabel(forL,ent);
+ }
+ }
+ else if (level>levelCounter)
+ {
+ forL=popLabel(forL);
+ }
+ }
+ else
+ {
+ pushLabel(forL,ent);
+ }
+
+ if (inlineConf)
+ {
+ confName=lastCompound->name;
+ }
+
+ //fprintf(stderr,"\n[%s %d %d]\n",forL.data(),levelCounter,level);
+ co=new VhdlConfNode(a,b,confName.lower().data(),forL.lower().data(),isLeaf);
+
+ if (inlineConf)
+ {
+ co->isInlineConf=TRUE;
+ }
+
+ configL.append(co);
+
+}// addConfigure
+
+
+void VhdlParser::addProto(const char *s1,const char *s2,const char *s3,
+ const char *s4,const char *s5,const char *s6)
+{
+ (void)s5; // avoid unused warning
+ static QRegExp reg("[\\s]");
+ QCString name=s2;
+ QStringList ql=QStringList::split(",",name,FALSE);
+
+ for (uint u=0;u<ql.count();u++)
+ {
+ Argument *arg=new Argument;
+ arg->name=ql[u].utf8();
+ if (s3)
+ {
+ arg->type=s3;
+ }
+ arg->type+=" ";
+ arg->type+=s4;
+ if (s6)
+ {
+ arg->type+=s6;
+ }
+ if (parse_sec==GEN_SEC && param_sec==0)
+ {
+ arg->defval="gen!";
+ }
+
+ if (parse_sec==PARAM_SEC)
+ {
+ // assert(false);
+ }
+
+ arg->defval+=s1;
+ arg->attrib="";//s6;
+
+ current->argList->append(arg);
+ current->args+=s2;
+ current->args+=",";
+ }
+}
+
+
+/*
+ * adds the library|use statements to the next class (entity|package|architecture|package body
+ * library ieee
+ * entity xxx
+ * .....
+ * library
+ * package
+ * enity zzz
+ * .....
+ * and so on..
+ */
+void VhdlParser::mapLibPackage( Entry* root)
+{
+ QList<Entry> epp=libUse;
+ EntryListIterator eli(epp);
+ Entry *rt;
+ for (;(rt=eli.current());++eli)
+ {
+ if (addLibUseClause(rt->name))
+ {
+ Entry *current;
+ EntryListIterator eLib(*root->children());
+ bool bFound=FALSE;
+ for (eLib.toFirst();(current=eLib.current());++eLib)
+ {
+ if (VhdlDocGen::isVhdlClass(current))
+ {
+ if (current->startLine > rt->startLine)
+ {
+ bFound=TRUE;
+ current->addSubEntry(new Entry(*rt));
+ break;
+ }
+ }
+ }//for
+ if (!bFound)
+ {
+ root->addSubEntry(new Entry(*rt));
+ }
+ } //if
+ }// for
+}//MapLib
+
+bool VhdlParser::addLibUseClause(const QCString &type)
+{
+ static bool showIEEESTD=Config_getBool("FORCE_LOCAL_INCLUDES");
+
+ if (showIEEESTD) // all standard packages and libraries will not be shown
+ {
+ if (type.lower().stripPrefix("ieee")) return FALSE;
+ if (type.lower().stripPrefix("std")) return FALSE;
+ }
+ return TRUE;
+}
+
+int VhdlParser::getLine()
+{
+ return yyLineNr;
+}
+
+void VhdlParser::setLineParsed(int tok)
+{
+ lineParse[tok]=yyLineNr;
+}
+
+int VhdlParser::getLine(int tok)
+{
+ int val=lineParse[tok];
+ if (val<0) val=0;
+ //assert(val>=0 && val<=yyLineNr);
+ return val;
+}
+
+
+void VhdlParser::createFlow()
+{
+ if (!VhdlDocGen::getFlowMember())
+ {
+ return;
+ }
+ QCString q,ret;
+
+ if (currP==VhdlDocGen::FUNCTION)
+ {
+ q=":function( ";
+ FlowChart::alignFuncProc(q,tempEntry->argList,true);
+ q+=")";
+ }
+ else if (currP==VhdlDocGen::PROCEDURE)
+ {
+ q=":procedure (";
+ FlowChart::alignFuncProc(q,tempEntry->argList,false);
+ q+=")";
+ }
+ else
+ {
+ q=":process( "+tempEntry->args;
+ q+=")";
+ }
+
+ q.prepend(VhdlDocGen::getFlowMember()->name().data());
+
+ FlowChart::addFlowChart(FlowChart::START_NO,q,0);
+
+ if (currP==VhdlDocGen::FUNCTION)
+ {
+ ret="end function ";
+ }
+ else if (currP==VhdlDocGen::PROCEDURE)
+ {
+ ret="end procedure";
+ }
+ else
+ {
+ ret="end process ";
+ }
+
+ FlowChart::addFlowChart(FlowChart::END_NO,ret,0);
+ // FlowChart::printFlowList();
+ FlowChart::writeFlowChart();
+ currP=0;
+}
+
+bool checkMultiComment(QCString& qcs,int line)
+{
+ QList<Entry> *pTemp=getEntryAtLine(VhdlParser::current_root,line);
+
+ if (pTemp->isEmpty()) return false;
+
+ //int ii=pTemp->count();
+ // qcs.stripPrefix("--!");
+ VhdlDocGen::prepareComment(qcs);
+ while (!pTemp->isEmpty())
+ {
+ Entry *e=(Entry*)pTemp->getFirst();
+ e->briefLine=line;
+ e->brief+=qcs;
+ iDocLine=-1;
+ pTemp->removeFirst();
+ //ii=pTemp->count();
+ }
+ return true;
+}
+
+// returns the vhdl parsed types at line xxx
+QList<Entry>* getEntryAtLine(const Entry* ce,int line)
+{
+ EntryListIterator eli(*ce->children());
+ Entry *rt;
+ for (;(rt=eli.current());++eli)
+ {
+ if (rt->bodyLine==line)
+ {
+ lineEntry.insert(0,rt);
+ } // if
+
+ getEntryAtLine(rt,line);
+ }
+ return &lineEntry;
+}
+
diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h
new file mode 100644
index 0000000..a0851d7
--- /dev/null
+++ b/src/vhdljjparser.h
@@ -0,0 +1,102 @@
+#ifndef VHDLJJPARSER_H
+#define VHDLJJPARSER_H
+
+#include "parserintf.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <qarray.h>
+
+#include <qfile.h>
+#include <qdict.h>
+#include <string>
+#include "types.h"
+#include "entry.h"
+#include "vhdldocgen.h"
+#include "qstringlist.h"
+#include "vhdlcode.h"
+#include "memberlist.h"
+#include "config.h"
+
+
+
+
+enum { GEN_SEC=0x1, PARAM_SEC,CONTEXT_SEC,PROTECTED_SEC } ;
+void parserVhdlfile(const char* inputBuffer);
+
+class Entry;
+class ClassSDict;
+class FileStorage;
+class ClassDef;
+class MemberDef;
+class QStringList;
+struct VhdlConfNode;
+
+
+/** \brief VHDL parser using state-based lexical scanning.
+ *
+ * This is the VHDL language parser for doxygen.
+ */
+class VHDLLanguageScanner : public ParserInterface
+{
+ public:
+ virtual ~VHDLLanguageScanner() {}
+ void startTranslationUnit(const char *) {}
+ void finishTranslationUnit() {}
+ void parseInput(const char * fileName,
+ const char *fileBuf,
+ Entry *root,
+ bool sameTranslationUnit,
+ QStrList &filesInSameTranslationUnit);
+
+ void parseCode(CodeOutputInterface &codeOutIntf,
+ const char *scopeName,
+ const QCString &input,
+ SrcLangExt lang,
+ bool isExampleBlock,
+ const char *exampleName=0,
+ FileDef *fileDef=0,
+ int startLine=-1,
+ int endLine=-1,
+ bool inlineFragment=FALSE,
+ MemberDef *memberDef=0,
+ bool showLineNumbers=TRUE,
+ Definition *searchCtx=0,
+ bool collectXRefs=TRUE
+ );
+ bool needsPreprocessing(const QCString &) { return TRUE; }
+ void resetCodeParserState(){};
+ void parsePrototype(const char *text);
+};
+
+struct VhdlConfNode
+{
+ VhdlConfNode(const char* a,const char* b,const char* config,const char* cs,bool leaf)
+ {
+ arch=a; // architecture e.g. for iobuffer
+ arch=arch.lower();
+ binding=b; // binding e.g. use entiy work.xxx(bev)
+ binding=binding.lower();
+ confVhdl=config; // configuration foo is bar
+ compSpec=cs;
+ isInlineConf=false; // primary configuration?
+ isLeaf=leaf;
+ };
+
+ QCString confVhdl;
+ QCString arch;
+ QCString binding;
+ QCString compSpec;
+ int level;
+ bool isLeaf;
+ bool isInlineConf;
+
+};
+
+void vhdlscanFreeScanner();
+
+QList<VhdlConfNode>& getVhdlConfiguration();
+QList<Entry>& getVhdlInstList();
+
+#endif
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
new file mode 100644
index 0000000..f2da28c
--- /dev/null
+++ b/src/xmldocvisitor.cpp
@@ -0,0 +1,1055 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfileinfo.h>
+
+#include "xmldocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "xmlgen.h"
+#include "dot.h"
+#include "message.h"
+#include "util.h"
+#include "parserintf.h"
+#include "filename.h"
+#include "config.h"
+#include "htmlentity.h"
+
+XmlDocVisitor::XmlDocVisitor(FTextStream &t,CodeOutputInterface &ci)
+ : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
+{
+}
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+void XmlDocVisitor::visit(DocWord *w)
+{
+ if (m_hide) return;
+ filter(w->word());
+}
+
+void XmlDocVisitor::visit(DocLinkedWord *w)
+{
+ if (m_hide) return;
+ startLink(w->ref(),w->file(),w->anchor());
+ filter(w->word());
+ endLink();
+}
+
+void XmlDocVisitor::visit(DocWhiteSpace *w)
+{
+ if (m_hide) return;
+ if (m_insidePre)
+ {
+ m_t << w->chars();
+ }
+ else
+ {
+ m_t << " ";
+ }
+}
+
+void XmlDocVisitor::visit(DocSymbol *s)
+{
+ if (m_hide) return;
+ const char *res = HtmlEntityMapper::instance()->xml(s->symbol());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ err("XML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
+ }
+}
+
+void XmlDocVisitor::visit(DocURL *u)
+{
+ if (m_hide) return;
+ m_t << "<ulink url=\"";
+ if (u->isEmail()) m_t << "mailto:";
+ filter(u->url());
+ m_t << "\">";
+ filter(u->url());
+ m_t << "</ulink>";
+}
+
+void XmlDocVisitor::visit(DocLineBreak *)
+{
+ if (m_hide) return;
+ m_t << "<linebreak/>\n";
+}
+
+void XmlDocVisitor::visit(DocHorRuler *)
+{
+ if (m_hide) return;
+ m_t << "<hruler/>\n";
+}
+
+void XmlDocVisitor::visit(DocStyleChange *s)
+{
+ if (m_hide) return;
+ switch (s->style())
+ {
+ case DocStyleChange::Bold:
+ if (s->enable()) m_t << "<bold>"; else m_t << "</bold>";
+ break;
+ case DocStyleChange::Italic:
+ if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>";
+ break;
+ case DocStyleChange::Code:
+ if (s->enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>";
+ break;
+ case DocStyleChange::Subscript:
+ if (s->enable()) m_t << "<subscript>"; else m_t << "</subscript>";
+ break;
+ case DocStyleChange::Superscript:
+ if (s->enable()) m_t << "<superscript>"; else m_t << "</superscript>";
+ break;
+ case DocStyleChange::Center:
+ if (s->enable()) m_t << "<center>"; else m_t << "</center>";
+ break;
+ case DocStyleChange::Small:
+ if (s->enable()) m_t << "<small>"; else m_t << "</small>";
+ break;
+ case DocStyleChange::Preformatted:
+ if (s->enable())
+ {
+ m_t << "<preformatted>";
+ m_insidePre=TRUE;
+ }
+ else
+ {
+ m_t << "</preformatted>";
+ m_insidePre=FALSE;
+ }
+ break;
+ case DocStyleChange::Div: /* HTML only */ break;
+ case DocStyleChange::Span: /* HTML only */ break;
+ }
+}
+
+void XmlDocVisitor::visit(DocVerbatim *s)
+{
+ if (m_hide) return;
+ QCString lang = m_langExt;
+ if (!s->language().isEmpty()) // explicit language setting
+ {
+ lang = s->language();
+ }
+ SrcLangExt langExt = getLanguageFromFileName(lang);
+ switch(s->type())
+ {
+ case DocVerbatim::Code: // fall though
+ m_t << "<programlisting>";
+ Doxygen::parserManager->getParser(lang)
+ ->parseCode(m_ci,s->context(),s->text(),langExt,
+ s->isExample(),s->exampleFile());
+ m_t << "</programlisting>";
+ break;
+ case DocVerbatim::Verbatim:
+ m_t << "<verbatim>";
+ filter(s->text());
+ m_t << "</verbatim>";
+ break;
+ case DocVerbatim::HtmlOnly:
+ m_t << "<htmlonly>";
+ filter(s->text());
+ m_t << "</htmlonly>";
+ break;
+ case DocVerbatim::RtfOnly:
+ m_t << "<rtfonly>";
+ filter(s->text());
+ m_t << "</rtfonly>";
+ break;
+ case DocVerbatim::ManOnly:
+ m_t << "<manonly>";
+ filter(s->text());
+ m_t << "</manonly>";
+ break;
+ case DocVerbatim::LatexOnly:
+ m_t << "<latexonly>";
+ filter(s->text());
+ m_t << "</latexonly>";
+ break;
+ case DocVerbatim::XmlOnly:
+ m_t << s->text();
+ break;
+ case DocVerbatim::DocbookOnly:
+ m_t << "<docbookonly>";
+ filter(s->text());
+ m_t << "</docbookonly>";
+ break;
+ case DocVerbatim::Dot:
+ m_t << "<dot>";
+ filter(s->text());
+ m_t << "</dot>";
+ break;
+ case DocVerbatim::Msc:
+ m_t << "<msc>";
+ filter(s->text());
+ m_t << "</msc>";
+ break;
+ case DocVerbatim::PlantUML:
+ m_t << "<plantuml>";
+ filter(s->text());
+ m_t << "</plantuml>";
+ break;
+ }
+}
+
+void XmlDocVisitor::visit(DocAnchor *anc)
+{
+ if (m_hide) return;
+ m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
+}
+
+void XmlDocVisitor::visit(DocInclude *inc)
+{
+ if (m_hide) return;
+ SrcLangExt langExt = getLanguageFromFileName(inc->extension());
+ switch(inc->type())
+ {
+ case DocInclude::IncWithLines:
+ {
+ m_t << "<programlisting>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile(), &fd);
+ m_t << "</programlisting>";
+ }
+ break;
+ case DocInclude::Include:
+ m_t << "<programlisting>";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,inc->context(),
+ inc->text(),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile());
+ m_t << "</programlisting>";
+ break;
+ case DocInclude::DontInclude:
+ break;
+ case DocInclude::HtmlInclude:
+ m_t << "<htmlonly>";
+ filter(inc->text());
+ m_t << "</htmlonly>";
+ break;
+ case DocInclude::LatexInclude:
+ m_t << "<latexonly>";
+ filter(inc->text());
+ m_t << "</latexonly>";
+ break;
+ case DocInclude::VerbInclude:
+ m_t << "<verbatim>";
+ filter(inc->text());
+ m_t << "</verbatim>";
+ break;
+ case DocInclude::Snippet:
+ m_t << "<programlisting>";
+ Doxygen::parserManager->getParser(inc->extension())
+ ->parseCode(m_ci,
+ inc->context(),
+ extractBlock(inc->text(),inc->blockId()),
+ langExt,
+ inc->isExample(),
+ inc->exampleFile()
+ );
+ m_t << "</programlisting>";
+ break;
+ }
+}
+
+void XmlDocVisitor::visit(DocIncOperator *op)
+{
+ //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+ // op->type(),op->isFirst(),op->isLast(),op->text().data());
+ if (op->isFirst())
+ {
+ if (!m_hide)
+ {
+ m_t << "<programlisting>";
+ }
+ pushEnabled();
+ m_hide = TRUE;
+ }
+ SrcLangExt langExt = getLanguageFromFileName(m_langExt);
+ if (op->type()!=DocIncOperator::Skip)
+ {
+ popEnabled();
+ if (!m_hide)
+ {
+ Doxygen::parserManager->getParser(m_langExt)
+ ->parseCode(m_ci,op->context(),
+ op->text(),langExt,op->isExample(),
+ op->exampleFile());
+ }
+ pushEnabled();
+ m_hide=TRUE;
+ }
+ if (op->isLast())
+ {
+ popEnabled();
+ if (!m_hide) m_t << "</programlisting>";
+ }
+ else
+ {
+ if (!m_hide) m_t << endl;
+ }
+}
+
+void XmlDocVisitor::visit(DocFormula *f)
+{
+ if (m_hide) return;
+ m_t << "<formula id=\"" << f->id() << "\">";
+ filter(f->text());
+ m_t << "</formula>";
+}
+
+void XmlDocVisitor::visit(DocIndexEntry *ie)
+{
+ if (m_hide) return;
+ m_t << "<indexentry>"
+ "<primaryie>";
+ filter(ie->entry());
+ m_t << "</primaryie>"
+ "<secondaryie></secondaryie>"
+ "</indexentry>";
+}
+
+void XmlDocVisitor::visit(DocSimpleSectSep *sep)
+{
+ if (sep->parent() && sep->parent()->kind()==DocNode::Kind_SimpleSect)
+ {
+ visitPost((DocSimpleSect*)sep->parent()); // end current section
+ visitPre((DocSimpleSect*)sep->parent()); // start new section
+ }
+}
+
+void XmlDocVisitor::visit(DocCite *cite)
+{
+ if (m_hide) return;
+ if (!cite->file().isEmpty()) startLink(cite->ref(),cite->file(),cite->anchor());
+ filter(cite->text());
+ if (!cite->file().isEmpty()) endLink();
+}
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void XmlDocVisitor::visitPre(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "<orderedlist>\n";
+ }
+ else
+ {
+ m_t << "<itemizedlist>\n";
+ }
+}
+
+void XmlDocVisitor::visitPost(DocAutoList *l)
+{
+ if (m_hide) return;
+ if (l->isEnumList())
+ {
+ m_t << "</orderedlist>\n";
+ }
+ else
+ {
+ m_t << "</itemizedlist>\n";
+ }
+}
+
+void XmlDocVisitor::visitPre(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocAutoListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>";
+}
+
+void XmlDocVisitor::visitPre(DocPara *)
+{
+ if (m_hide) return;
+ m_t << "<para>";
+}
+
+void XmlDocVisitor::visitPost(DocPara *)
+{
+ if (m_hide) return;
+ m_t << "</para>";
+}
+
+void XmlDocVisitor::visitPre(DocRoot *)
+{
+ //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
+}
+
+void XmlDocVisitor::visitPost(DocRoot *)
+{
+ //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleSect *s)
+{
+ if (m_hide) return;
+ m_t << "<simplesect kind=\"";
+ switch(s->type())
+ {
+ case DocSimpleSect::See:
+ m_t << "see"; break;
+ case DocSimpleSect::Return:
+ m_t << "return"; break;
+ case DocSimpleSect::Author:
+ m_t << "author"; break;
+ case DocSimpleSect::Authors:
+ m_t << "authors"; break;
+ case DocSimpleSect::Version:
+ m_t << "version"; break;
+ case DocSimpleSect::Since:
+ m_t << "since"; break;
+ case DocSimpleSect::Date:
+ m_t << "date"; break;
+ case DocSimpleSect::Note:
+ m_t << "note"; break;
+ case DocSimpleSect::Warning:
+ m_t << "warning"; break;
+ case DocSimpleSect::Pre:
+ m_t << "pre"; break;
+ case DocSimpleSect::Post:
+ m_t << "post"; break;
+ case DocSimpleSect::Copyright:
+ m_t << "copyright"; break;
+ case DocSimpleSect::Invar:
+ m_t << "invariant"; break;
+ case DocSimpleSect::Remark:
+ m_t << "remark"; break;
+ case DocSimpleSect::Attention:
+ m_t << "attention"; break;
+ case DocSimpleSect::User:
+ m_t << "par"; break;
+ case DocSimpleSect::Rcs:
+ m_t << "rcs"; break;
+ case DocSimpleSect::Unknown: break;
+ }
+ m_t << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleSect *)
+{
+ if (m_hide) return;
+ m_t << "</simplesect>\n";
+}
+
+void XmlDocVisitor::visitPre(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "<title>";
+}
+
+void XmlDocVisitor::visitPost(DocTitle *)
+{
+ if (m_hide) return;
+ m_t << "</title>";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "<itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleList *)
+{
+ if (m_hide) return;
+ m_t << "</itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSection *s)
+{
+ if (m_hide) return;
+ m_t << "<sect" << s->level() << " id=\"" << s->file();
+ if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor();
+ m_t << "\">" << endl;
+ m_t << "<title>";
+ filter(convertCharEntitiesToUTF8(s->title()));
+ m_t << "</title>" << endl;
+}
+
+void XmlDocVisitor::visitPost(DocSection *s)
+{
+ m_t << "</sect" << s->level() << ">\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "<orderedlist>\n";
+ else
+ m_t << "<itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlList *s)
+{
+ if (m_hide) return;
+ if (s->type()==DocHtmlList::Ordered)
+ m_t << "</orderedlist>\n";
+ else
+ m_t << "</itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlListItem *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ m_t << "<variablelist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescList *)
+{
+ if (m_hide) return;
+ m_t << "</variablelist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "<varlistentry><term>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescTitle *)
+{
+ if (m_hide) return;
+ m_t << "</term></varlistentry>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescData *)
+{
+ if (m_hide) return;
+ m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlTable *t)
+{
+ if (m_hide) return;
+ m_t << "<table rows=\"" << t->numRows()
+ << "\" cols=\"" << t->numColumns() << "\">" ;
+}
+
+void XmlDocVisitor::visitPost(DocHtmlTable *)
+{
+ if (m_hide) return;
+ m_t << "</table>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlRow *)
+{
+ if (m_hide) return;
+ m_t << "<row>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlRow *)
+{
+ if (m_hide) return;
+ m_t << "</row>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlCell *c)
+{
+ if (m_hide) return;
+ if (c->isHeading()) m_t << "<entry thead=\"yes\">"; else m_t << "<entry thead=\"no\">";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlCell *)
+{
+ if (m_hide) return;
+ m_t << "</entry>";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "<caption>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlCaption *)
+{
+ if (m_hide) return;
+ m_t << "</caption>\n";
+}
+
+void XmlDocVisitor::visitPre(DocInternal *)
+{
+ if (m_hide) return;
+ m_t << "<internal>";
+}
+
+void XmlDocVisitor::visitPost(DocInternal *)
+{
+ if (m_hide) return;
+ m_t << "</internal>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocHRef *href)
+{
+ if (m_hide) return;
+ m_t << "<ulink url=\"";
+ filter(href->url());
+ m_t << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocHRef *)
+{
+ if (m_hide) return;
+ m_t << "</ulink>";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlHeader *header)
+{
+ if (m_hide) return;
+ m_t << "<heading level=\"" << header->level() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlHeader *)
+{
+ if (m_hide) return;
+ m_t << "</heading>\n";
+}
+
+void XmlDocVisitor::visitPre(DocImage *img)
+{
+ if (m_hide) return;
+ m_t << "<image type=\"";
+ switch(img->type())
+ {
+ case DocImage::Html: m_t << "html"; break;
+ case DocImage::Latex: m_t << "latex"; break;
+ case DocImage::Rtf: m_t << "rtf"; break;
+ case DocImage::DocBook: m_t << "docbook"; break;
+ }
+ m_t << "\"";
+
+ QCString baseName=img->name();
+ int i;
+ if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+ {
+ baseName=baseName.right(baseName.length()-i-1);
+ }
+ m_t << " name=\"" << baseName << "\"";
+ if (!img->width().isEmpty())
+ {
+ m_t << " width=\"";
+ filter(img->width());
+ m_t << "\"";
+ }
+ else if (!img->height().isEmpty())
+ {
+ m_t << " height=\"";
+ filter(img->height());
+ m_t << "\"";
+ }
+ m_t << ">";
+
+ // copy the image to the output dir
+ QFile inImage(img->name());
+ QFile outImage(Config_getString("XML_OUTPUT")+"/"+baseName.data());
+ if (inImage.open(IO_ReadOnly))
+ {
+ if (outImage.open(IO_WriteOnly))
+ {
+ char *buffer = new char[inImage.size()];
+ inImage.readBlock(buffer,inImage.size());
+ outImage.writeBlock(buffer,inImage.size());
+ outImage.flush();
+ delete[] buffer;
+ }
+ }
+}
+
+void XmlDocVisitor::visitPost(DocImage *)
+{
+ if (m_hide) return;
+ m_t << "</image>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocDotFile *df)
+{
+ if (m_hide) return;
+ m_t << "<dotfile name=\"" << df->file() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocDotFile *)
+{
+ if (m_hide) return;
+ m_t << "</dotfile>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocMscFile *df)
+{
+ if (m_hide) return;
+ m_t << "<mscfile name=\"" << df->file() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocMscFile *)
+{
+ if (m_hide) return;
+ m_t << "</mscfile>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocDiaFile *df)
+{
+ if (m_hide) return;
+ m_t << "<diafile name=\"" << df->file() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocDiaFile *)
+{
+ if (m_hide) return;
+ m_t << "</diafile>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocLink *lnk)
+{
+ if (m_hide) return;
+ startLink(lnk->ref(),lnk->file(),lnk->anchor());
+}
+
+void XmlDocVisitor::visitPost(DocLink *)
+{
+ if (m_hide) return;
+ endLink();
+}
+
+void XmlDocVisitor::visitPre(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty())
+ {
+ startLink(ref->ref(),ref->file(),ref->isSubPage() ? QCString() : ref->anchor());
+ }
+ if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void XmlDocVisitor::visitPost(DocRef *ref)
+{
+ if (m_hide) return;
+ if (!ref->file().isEmpty()) endLink();
+ //m_t << " ";
+}
+
+void XmlDocVisitor::visitPre(DocSecRefItem *ref)
+{
+ if (m_hide) return;
+ m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocSecRefItem *)
+{
+ if (m_hide) return;
+ m_t << "</tocitem>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "<toclist>" << endl;
+}
+
+void XmlDocVisitor::visitPost(DocSecRefList *)
+{
+ if (m_hide) return;
+ m_t << "</toclist>" << endl;
+}
+
+//void XmlDocVisitor::visitPre(DocLanguage *l)
+//{
+// if (m_hide) return;
+// m_t << "<language langid=\"" << l->id() << "\">";
+//}
+//
+//void XmlDocVisitor::visitPost(DocLanguage *)
+//{
+// if (m_hide) return;
+// m_t << "</language>" << endl;
+//}
+
+void XmlDocVisitor::visitPre(DocParamSect *s)
+{
+ if (m_hide) return;
+ m_t << "<parameterlist kind=\"";
+ switch(s->type())
+ {
+ case DocParamSect::Param:
+ m_t << "param"; break;
+ case DocParamSect::RetVal:
+ m_t << "retval"; break;
+ case DocParamSect::Exception:
+ m_t << "exception"; break;
+ case DocParamSect::TemplateParam:
+ m_t << "templateparam"; break;
+ default:
+ ASSERT(0);
+ }
+ m_t << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocParamSect *)
+{
+ if (m_hide) return;
+ m_t << "</parameterlist>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocParamList *pl)
+{
+ if (m_hide) return;
+ m_t << "<parameteritem>" << endl;
+ m_t << "<parameternamelist>" << endl;
+ //QStrListIterator li(pl->parameters());
+ //const char *s;
+ QListIterator<DocNode> li(pl->parameters());
+ DocNode *param;
+ for (li.toFirst();(param=li.current());++li)
+ {
+ if (pl->paramTypes().count()>0)
+ {
+ QListIterator<DocNode> li(pl->paramTypes());
+ DocNode *type;
+ for (li.toFirst();(type=li.current());++li)
+ {
+ m_t << "<parametertype>";
+ if (type->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)type);
+ }
+ else if (type->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)type);
+ }
+ m_t << "</parametertype>" << endl;
+ }
+ }
+ m_t << "<parametername";
+ if (pl->direction()!=DocParamSect::Unspecified)
+ {
+ m_t << " direction=\"";
+ if (pl->direction()==DocParamSect::In)
+ {
+ m_t << "in";
+ }
+ else if (pl->direction()==DocParamSect::Out)
+ {
+ m_t << "out";
+ }
+ else if (pl->direction()==DocParamSect::InOut)
+ {
+ m_t << "inout";
+ }
+ m_t << "\"";
+ }
+ m_t << ">";
+ if (param->kind()==DocNode::Kind_Word)
+ {
+ visit((DocWord*)param);
+ }
+ else if (param->kind()==DocNode::Kind_LinkedWord)
+ {
+ visit((DocLinkedWord*)param);
+ }
+ m_t << "</parametername>" << endl;
+ }
+ m_t << "</parameternamelist>" << endl;
+ m_t << "<parameterdescription>" << endl;
+}
+
+void XmlDocVisitor::visitPost(DocParamList *)
+{
+ if (m_hide) return;
+ m_t << "</parameterdescription>" << endl;
+ m_t << "</parameteritem>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "<xrefsect id=\"";
+ m_t << x->file() << "_1" << x->anchor();
+ m_t << "\">";
+ m_t << "<xreftitle>";
+ filter(x->title());
+ m_t << "</xreftitle>";
+ m_t << "<xrefdescription>";
+}
+
+void XmlDocVisitor::visitPost(DocXRefItem *x)
+{
+ if (m_hide) return;
+ if (x->title().isEmpty()) return;
+ m_t << "</xrefdescription>";
+ m_t << "</xrefsect>";
+}
+
+void XmlDocVisitor::visitPre(DocInternalRef *ref)
+{
+ if (m_hide) return;
+ startLink(0,ref->file(),ref->anchor());
+}
+
+void XmlDocVisitor::visitPost(DocInternalRef *)
+{
+ if (m_hide) return;
+ endLink();
+ m_t << " ";
+}
+
+void XmlDocVisitor::visitPre(DocCopy *c)
+{
+ if (m_hide) return;
+ m_t << "<copydoc link=\"" << convertToXML(c->link()) << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocCopy *)
+{
+ if (m_hide) return;
+ m_t << "</copydoc>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocText *)
+{
+}
+
+void XmlDocVisitor::visitPost(DocText *)
+{
+}
+
+void XmlDocVisitor::visitPre(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "<blockquote>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlBlockQuote *)
+{
+ if (m_hide) return;
+ m_t << "</blockquote>";
+}
+
+void XmlDocVisitor::visitPre(DocVhdlFlow *)
+{
+}
+
+void XmlDocVisitor::visitPost(DocVhdlFlow *)
+{
+}
+
+void XmlDocVisitor::visitPre(DocParBlock *)
+{
+ if (m_hide) return;
+ m_t << "<parblock>";
+}
+
+void XmlDocVisitor::visitPost(DocParBlock *)
+{
+ if (m_hide) return;
+ m_t << "</parblock>";
+}
+
+
+void XmlDocVisitor::filter(const char *str)
+{
+ m_t << convertToXML(str);
+}
+
+void XmlDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
+{
+ //printf("XmlDocVisitor: file=%s anchor=%s\n",file.data(),anchor.data());
+ m_t << "<ref refid=\"" << file;
+ if (!anchor.isEmpty()) m_t << "_1" << anchor;
+ m_t << "\" kindref=\"";
+ if (!anchor.isEmpty()) m_t << "member"; else m_t << "compound";
+ m_t << "\"";
+ if (!ref.isEmpty()) m_t << " external=\"" << ref << "\"";
+ m_t << ">";
+}
+
+void XmlDocVisitor::endLink()
+{
+ m_t << "</ref>";
+}
+
+void XmlDocVisitor::pushEnabled()
+{
+ m_enabled.push(new bool(m_hide));
+}
+
+void XmlDocVisitor::popEnabled()
+{
+ bool *v=m_enabled.pop();
+ ASSERT(v!=0);
+ m_hide = *v;
+ delete v;
+}
+
diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h
new file mode 100644
index 0000000..3e2236c
--- /dev/null
+++ b/src/xmldocvisitor.h
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _XMLDOCVISITOR_H
+#define _XMLDOCVISITOR_H
+
+#include "docvisitor.h"
+#include <qstack.h>
+#include <qcstring.h>
+
+class FTextStream;
+class CodeOutputInterface;
+class QCString;
+
+/*! @brief Concrete visitor implementation for XML output. */
+class XmlDocVisitor : public DocVisitor
+{
+ public:
+ XmlDocVisitor(FTextStream &t,CodeOutputInterface &ci);
+
+ //--------------------------------------
+ // visitor functions for leaf nodes
+ //--------------------------------------
+
+ void visit(DocWord *);
+ void visit(DocLinkedWord *);
+ void visit(DocWhiteSpace *);
+ void visit(DocSymbol *);
+ void visit(DocURL *);
+ void visit(DocLineBreak *);
+ void visit(DocHorRuler *);
+ void visit(DocStyleChange *);
+ void visit(DocVerbatim *);
+ void visit(DocAnchor *);
+ void visit(DocInclude *);
+ void visit(DocIncOperator *);
+ void visit(DocFormula *);
+ void visit(DocIndexEntry *);
+ void visit(DocSimpleSectSep *);
+ void visit(DocCite *);
+
+ //--------------------------------------
+ // visitor functions for compound nodes
+ //--------------------------------------
+
+ void visitPre(DocAutoList *);
+ void visitPost(DocAutoList *);
+ void visitPre(DocAutoListItem *);
+ void visitPost(DocAutoListItem *);
+ void visitPre(DocPara *) ;
+ void visitPost(DocPara *);
+ void visitPre(DocRoot *);
+ void visitPost(DocRoot *);
+ void visitPre(DocSimpleSect *);
+ void visitPost(DocSimpleSect *);
+ void visitPre(DocTitle *);
+ void visitPost(DocTitle *);
+ void visitPre(DocSimpleList *);
+ void visitPost(DocSimpleList *);
+ void visitPre(DocSimpleListItem *);
+ void visitPost(DocSimpleListItem *);
+ void visitPre(DocSection *);
+ void visitPost(DocSection *);
+ void visitPre(DocHtmlList *);
+ void visitPost(DocHtmlList *) ;
+ void visitPre(DocHtmlListItem *);
+ void visitPost(DocHtmlListItem *);
+ //void visitPre(DocHtmlPre *);
+ //void visitPost(DocHtmlPre *);
+ void visitPre(DocHtmlDescList *);
+ void visitPost(DocHtmlDescList *);
+ void visitPre(DocHtmlDescTitle *);
+ void visitPost(DocHtmlDescTitle *);
+ void visitPre(DocHtmlDescData *);
+ void visitPost(DocHtmlDescData *);
+ void visitPre(DocHtmlTable *);
+ void visitPost(DocHtmlTable *);
+ void visitPre(DocHtmlRow *);
+ void visitPost(DocHtmlRow *) ;
+ void visitPre(DocHtmlCell *);
+ void visitPost(DocHtmlCell *);
+ void visitPre(DocHtmlCaption *);
+ void visitPost(DocHtmlCaption *);
+ void visitPre(DocInternal *);
+ void visitPost(DocInternal *);
+ void visitPre(DocHRef *);
+ void visitPost(DocHRef *);
+ void visitPre(DocHtmlHeader *);
+ void visitPost(DocHtmlHeader *);
+ void visitPre(DocImage *);
+ void visitPost(DocImage *);
+ void visitPre(DocDotFile *);
+ void visitPost(DocDotFile *);
+
+ void visitPre(DocMscFile *);
+ void visitPost(DocMscFile *);
+ void visitPre(DocDiaFile *);
+ void visitPost(DocDiaFile *);
+ void visitPre(DocLink *);
+ void visitPost(DocLink *);
+ void visitPre(DocRef *);
+ void visitPost(DocRef *);
+ void visitPre(DocSecRefItem *);
+ void visitPost(DocSecRefItem *);
+ void visitPre(DocSecRefList *);
+ void visitPost(DocSecRefList *);
+ //void visitPre(DocLanguage *);
+ //void visitPost(DocLanguage *);
+ void visitPre(DocParamSect *);
+ void visitPost(DocParamSect *);
+ void visitPre(DocParamList *);
+ void visitPost(DocParamList *);
+ void visitPre(DocXRefItem *);
+ void visitPost(DocXRefItem *);
+ void visitPre(DocInternalRef *);
+ void visitPost(DocInternalRef *);
+ void visitPre(DocCopy *);
+ void visitPost(DocCopy *);
+ void visitPre(DocText *);
+ void visitPost(DocText *);
+ void visitPre(DocHtmlBlockQuote *);
+ void visitPost(DocHtmlBlockQuote *);
+ void visitPre(DocVhdlFlow *);
+ void visitPost(DocVhdlFlow *);
+ void visitPre(DocParBlock *);
+ void visitPost(DocParBlock *);
+
+ private:
+
+ //--------------------------------------
+ // helper functions
+ //--------------------------------------
+
+ void filter(const char *str);
+ void startLink(const QCString &ref,const QCString &file,
+ const QCString &anchor);
+ void endLink();
+
+ void pushEnabled();
+ void popEnabled();
+
+ //--------------------------------------
+ // state variables
+ //--------------------------------------
+
+ FTextStream &m_t;
+ CodeOutputInterface &m_ci;
+ bool m_insidePre;
+ bool m_hide;
+ QStack<bool> m_enabled;
+ QCString m_langExt;
+};
+
+#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
new file mode 100644
index 0000000..549ff0f
--- /dev/null
+++ b/src/xmlgen.cpp
@@ -0,0 +1,2052 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qintdict.h>
+
+#include "xmlgen.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "classlist.h"
+#include "util.h"
+#include "defargs.h"
+#include "outputgen.h"
+#include "dot.h"
+#include "pagedef.h"
+#include "filename.h"
+#include "version.h"
+#include "xmldocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "parserintf.h"
+#include "arguments.h"
+#include "memberlist.h"
+#include "groupdef.h"
+#include "memberdef.h"
+#include "namespacedef.h"
+#include "membername.h"
+#include "membergroup.h"
+#include "dirdef.h"
+#include "section.h"
+#include "htmlentity.h"
+
+// no debug info
+#define XML_DB(x) do {} while(0)
+// debug to stdout
+//#define XML_DB(x) printf x
+// debug inside output
+//#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
+
+//------------------
+
+static const char index_xsd[] =
+#include "index.xsd.h"
+;
+
+//------------------
+//
+static const char compound_xsd[] =
+#include "compound.xsd.h"
+;
+
+//------------------
+
+/** Helper class mapping MemberList::ListType to a string representing */
+class XmlSectionMapper : public QIntDict<char>
+{
+ public:
+ XmlSectionMapper() : QIntDict<char>(47)
+ {
+ insert(MemberListType_pubTypes,"public-type");
+ insert(MemberListType_pubMethods,"public-func");
+ insert(MemberListType_pubAttribs,"public-attrib");
+ insert(MemberListType_pubSlots,"public-slot");
+ insert(MemberListType_signals,"signal");
+ insert(MemberListType_dcopMethods,"dcop-func");
+ insert(MemberListType_properties,"property");
+ insert(MemberListType_events,"event");
+ insert(MemberListType_interfaces,"interfaces");
+ insert(MemberListType_services,"services");
+ insert(MemberListType_pubStaticMethods,"public-static-func");
+ insert(MemberListType_pubStaticAttribs,"public-static-attrib");
+ insert(MemberListType_proTypes,"protected-type");
+ insert(MemberListType_proMethods,"protected-func");
+ insert(MemberListType_proAttribs,"protected-attrib");
+ insert(MemberListType_proSlots,"protected-slot");
+ insert(MemberListType_proStaticMethods,"protected-static-func");
+ insert(MemberListType_proStaticAttribs,"protected-static-attrib");
+ insert(MemberListType_pacTypes,"package-type");
+ insert(MemberListType_pacMethods,"package-func");
+ insert(MemberListType_pacAttribs,"package-attrib");
+ insert(MemberListType_pacStaticMethods,"package-static-func");
+ insert(MemberListType_pacStaticAttribs,"package-static-attrib");
+ insert(MemberListType_priTypes,"private-type");
+ insert(MemberListType_priMethods,"private-func");
+ insert(MemberListType_priAttribs,"private-attrib");
+ insert(MemberListType_priSlots,"private-slot");
+ insert(MemberListType_priStaticMethods,"private-static-func");
+ insert(MemberListType_priStaticAttribs,"private-static-attrib");
+ insert(MemberListType_friends,"friend");
+ insert(MemberListType_related,"related");
+ insert(MemberListType_decDefineMembers,"define");
+ insert(MemberListType_decProtoMembers,"prototype");
+ insert(MemberListType_decTypedefMembers,"typedef");
+ insert(MemberListType_decEnumMembers,"enum");
+ insert(MemberListType_decFuncMembers,"func");
+ insert(MemberListType_decVarMembers,"var");
+ }
+};
+
+static XmlSectionMapper g_xmlSectionMapper;
+
+
+inline void writeXMLString(FTextStream &t,const char *s)
+{
+ t << convertToXML(s);
+}
+
+inline void writeXMLCodeString(FTextStream &t,const char *s, int &col)
+{
+ char c;
+ while ((c=*s++))
+ {
+ switch(c)
+ {
+ case '\t':
+ {
+ static int tabSize = Config_getInt("TAB_SIZE");
+ int spacesToNextTabStop = tabSize - (col%tabSize);
+ col+=spacesToNextTabStop;
+ while (spacesToNextTabStop--) t << "<sp/>";
+ break;
+ }
+ case ' ': t << "<sp/>"; col++; break;
+ case '<': t << "<"; col++; break;
+ case '>': t << ">"; col++; break;
+ case '&': t << "&"; col++; break;
+ case '\'': t << "'"; col++; break;
+ case '"': t << """; col++; break;
+ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
+ case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
+ case 27: case 28: case 29: case 30: case 31:
+ break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
+ default: s=writeUtf8Char(t,s-1); col++; break;
+ }
+ }
+}
+
+
+static void writeXMLHeader(FTextStream &t)
+{
+ t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
+ t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
+ t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
+ t << "version=\"" << versionString << "\">" << endl;
+}
+
+static void writeCombineScript()
+{
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/combine.xslt";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ t <<
+ "<!-- XSLT script to combine the generated output into a single file. \n"
+ " If you have xsltproc you could use:\n"
+ " xsltproc combine.xslt index.xml >all.xml\n"
+ "-->\n"
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
+ " <xsl:template match=\"/\">\n"
+ " <doxygen version=\"{doxygenindex/@version}\">\n"
+ " <!-- Load all doxgen generated xml files -->\n"
+ " <xsl:for-each select=\"doxygenindex/compound\">\n"
+ " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
+ " </xsl:for-each>\n"
+ " </doxygen>\n"
+ " </xsl:template>\n"
+ "</xsl:stylesheet>\n";
+
+}
+
+void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
+ const char *anchorId,const char *text,const char *tooltip)
+{
+ t << "<ref refid=\"" << compoundId;
+ if (anchorId) t << "_1" << anchorId;
+ t << "\" kindref=\"";
+ if (anchorId) t << "member"; else t << "compound";
+ t << "\"";
+ if (extRef) t << " external=\"" << extRef << "\"";
+ if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
+ t << ">";
+ writeXMLString(t,text);
+ t << "</ref>";
+}
+
+/** Implements TextGeneratorIntf for an XML stream. */
+class TextGeneratorXMLImpl : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
+ void writeString(const char *s,bool /*keepSpaces*/) const
+ {
+ writeXMLString(m_t,s);
+ }
+ void writeBreak(int) const {}
+ void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const
+ {
+ writeXMLLink(m_t,extRef,file,anchor,text,0);
+ }
+ private:
+ FTextStream &m_t;
+};
+
+
+/** Generator for producing XML formatted source code. */
+class XMLCodeGenerator : public CodeOutputInterface
+{
+ public:
+
+ XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1),
+ m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE),
+ m_insideSpecialHL(FALSE) {}
+ virtual ~XMLCodeGenerator() { }
+
+ void codify(const char *text)
+ {
+ XML_DB(("(codify \"%s\")\n",text));
+ if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
+ {
+ m_t << "<highlight class=\"normal\">";
+ m_normalHLNeedStartTag=FALSE;
+ }
+ writeXMLCodeString(m_t,text,col);
+ }
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip)
+ {
+ XML_DB(("(writeCodeLink)\n"));
+ if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
+ {
+ m_t << "<highlight class=\"normal\">";
+ m_normalHLNeedStartTag=FALSE;
+ }
+ writeXMLLink(m_t,ref,file,anchor,name,tooltip);
+ col+=qstrlen(name);
+ }
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ )
+ {
+ XML_DB(("(writeToolTip)\n"));
+ }
+ void startCodeLine(bool)
+ {
+ XML_DB(("(startCodeLine)\n"));
+ m_t << "<codeline";
+ if (m_lineNumber!=-1)
+ {
+ m_t << " lineno=\"" << m_lineNumber << "\"";
+ if (!m_refId.isEmpty())
+ {
+ m_t << " refid=\"" << m_refId << "\"";
+ if (m_isMemberRef)
+ {
+ m_t << " refkind=\"member\"";
+ }
+ else
+ {
+ m_t << " refkind=\"compound\"";
+ }
+ }
+ if (!m_external.isEmpty())
+ {
+ m_t << " external=\"" << m_external << "\"";
+ }
+ }
+ m_t << ">";
+ m_insideCodeLine=TRUE;
+ col=0;
+ }
+ void endCodeLine()
+ {
+ XML_DB(("(endCodeLine)\n"));
+ if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
+ {
+ m_t << "</highlight>";
+ m_normalHLNeedStartTag=TRUE;
+ }
+ m_t << "</codeline>" << endl; // non DocBook
+ m_lineNumber = -1;
+ m_refId.resize(0);
+ m_external.resize(0);
+ m_insideCodeLine=FALSE;
+ }
+ void startFontClass(const char *colorClass)
+ {
+ XML_DB(("(startFontClass)\n"));
+ if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
+ {
+ m_t << "</highlight>";
+ m_normalHLNeedStartTag=TRUE;
+ }
+ m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
+ m_insideSpecialHL=TRUE;
+ }
+ void endFontClass()
+ {
+ XML_DB(("(endFontClass)\n"));
+ m_t << "</highlight>"; // non DocBook
+ m_insideSpecialHL=FALSE;
+ }
+ void writeCodeAnchor(const char *)
+ {
+ XML_DB(("(writeCodeAnchor)\n"));
+ }
+ void writeLineNumber(const char *extRef,const char *compId,
+ const char *anchorId,int l)
+ {
+ XML_DB(("(writeLineNumber)\n"));
+ // we remember the information provided here to use it
+ // at the <codeline> start tag.
+ m_lineNumber = l;
+ if (compId)
+ {
+ m_refId=compId;
+ if (anchorId) m_refId+=(QCString)"_1"+anchorId;
+ m_isMemberRef = anchorId!=0;
+ if (extRef) m_external=extRef;
+ }
+ }
+ void setCurrentDoc(Definition *,const char *,bool)
+ {
+ }
+ void addWord(const char *,bool)
+ {
+ }
+
+ void finish()
+ {
+ if (m_insideCodeLine) endCodeLine();
+ }
+
+ private:
+ FTextStream &m_t;
+ QCString m_refId;
+ QCString m_external;
+ int m_lineNumber;
+ bool m_isMemberRef;
+ int col;
+
+ bool m_insideCodeLine;
+ bool m_normalHLNeedStartTag;
+ bool m_insideSpecialHL;
+};
+
+
+static void writeTemplateArgumentList(ArgumentList *al,
+ FTextStream &t,
+ Definition *scope,
+ FileDef *fileScope,
+ int indent)
+{
+ QCString indentStr;
+ indentStr.fill(' ',indent);
+ if (al)
+ {
+ t << indentStr << "<templateparamlist>" << endl;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ t << indentStr << " <param>" << endl;
+ if (!a->type.isEmpty())
+ {
+ t << indentStr << " <type>";
+ linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
+ t << "</type>" << endl;
+ }
+ if (!a->name.isEmpty())
+ {
+ t << indentStr << " <declname>" << a->name << "</declname>" << endl;
+ t << indentStr << " <defname>" << a->name << "</defname>" << endl;
+ }
+ if (!a->defval.isEmpty())
+ {
+ t << indentStr << " <defval>";
+ linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
+ t << "</defval>" << endl;
+ }
+ t << indentStr << " </param>" << endl;
+ }
+ t << indentStr << "</templateparamlist>" << endl;
+ }
+}
+
+static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
+{
+ ArgumentList *templMd = md->templateArguments();
+ if (templMd) // function template prefix
+ {
+ writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8);
+ }
+}
+
+static void writeTemplateList(ClassDef *cd,FTextStream &t)
+{
+ writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
+}
+
+static void writeXMLDocBlock(FTextStream &t,
+ const QCString &fileName,
+ int lineNr,
+ Definition *scope,
+ MemberDef * md,
+ const QCString &text)
+{
+ QCString stext = text.stripWhiteSpace();
+ if (stext.isEmpty()) return;
+ // convert the documentation string into an abstract syntax tree
+ DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
+ // create a code generator
+ XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
+ // create a parse tree visitor for XML
+ XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
+ // visit all nodes
+ root->accept(visitor);
+ // clean up
+ delete visitor;
+ delete xmlCodeGen;
+ delete root;
+
+}
+
+void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
+{
+ ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
+ SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
+ pIntf->resetCodeParserState();
+ XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
+ pIntf->parseCode(*xmlGen, // codeOutIntf
+ 0, // scopeName
+ fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
+ langExt, // lang
+ FALSE, // isExampleBlock
+ 0, // exampleName
+ fd, // fileDef
+ -1, // startLine
+ -1, // endLine
+ FALSE, // inlineFragement
+ 0, // memberDef
+ TRUE // showLineNumbers
+ );
+ xmlGen->finish();
+ delete xmlGen;
+}
+
+static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
+{
+ QCString scope = rmd->getScopeString();
+ QCString name = rmd->name();
+ if (!scope.isEmpty() && scope!=def->name())
+ {
+ name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
+ }
+ t << " <" << tagName << " refid=\"";
+ t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
+ if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
+ {
+ t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
+ t << " startline=\"" << rmd->getStartBodyLine() << "\"";
+ if (rmd->getEndBodyLine()!=-1)
+ {
+ t << " endline=\"" << rmd->getEndBodyLine() << "\"";
+ }
+ }
+ t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
+
+}
+
+static void stripQualifiers(QCString &typeStr)
+{
+ bool done=FALSE;
+ while (!done)
+ {
+ if (typeStr.stripPrefix("static "));
+ else if (typeStr.stripPrefix("virtual "));
+ else if (typeStr.stripPrefix("volatile "));
+ else if (typeStr=="virtual") typeStr="";
+ else done=TRUE;
+ }
+}
+
+static QCString classOutputFileBase(ClassDef *cd)
+{
+ //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ //if (inlineGroupedClasses && cd->partOfGroups()!=0)
+ return cd->getOutputFileBase();
+ //else
+ // return cd->getOutputFileBase();
+}
+
+static QCString memberOutputFileBase(MemberDef *md)
+{
+ //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
+ // return md->getClassDef()->getXmlOutputFileBase();
+ //else
+ // return md->getOutputFileBase();
+ return md->getOutputFileBase();
+}
+
+
+static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
+{
+
+ // + declaration/definition arg lists
+ // + reimplements
+ // + reimplementedBy
+ // + exceptions
+ // + const/volatile specifiers
+ // - examples
+ // + source definition
+ // + source references
+ // + source referenced by
+ // - body code
+ // + template arguments
+ // (templateArguments(), definitionTemplateParameterLists())
+ // - call graph
+
+ // enum values are written as part of the enum
+ if (md->memberType()==MemberType_EnumValue) return;
+ if (md->isHidden()) return;
+ //if (md->name().at(0)=='@') return; // anonymous member
+
+ // group members are only visible in their group
+ //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
+
+ QCString memType;
+ bool isFunc=FALSE;
+ switch (md->memberType())
+ {
+ case MemberType_Define: memType="define"; break;
+ case MemberType_Function: memType="function"; isFunc=TRUE; break;
+ case MemberType_Variable: memType="variable"; break;
+ case MemberType_Typedef: memType="typedef"; break;
+ case MemberType_Enumeration: memType="enum"; break;
+ case MemberType_EnumValue: ASSERT(0); break;
+ case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
+ case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
+ case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
+ case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
+ case MemberType_Property: memType="property"; break;
+ case MemberType_Event: memType="event"; break;
+ case MemberType_Interface: memType="interface"; break;
+ case MemberType_Service: memType="service"; break;
+ }
+
+ ti << " <member refid=\"" << memberOutputFileBase(md)
+ << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>"
+ << convertToXML(md->name()) << "</name></member>" << endl;
+
+ QCString scopeName;
+ if (md->getClassDef())
+ scopeName=md->getClassDef()->name();
+ else if (md->getNamespaceDef())
+ scopeName=md->getNamespaceDef()->name();
+
+ t << " <memberdef kind=\"";
+ //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
+ t << memType << "\" id=\"";
+ if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
+ {
+ t << md->getGroupDef()->getOutputFileBase();
+ }
+ else
+ {
+ t << memberOutputFileBase(md);
+ }
+ t << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
+ << md->anchor();
+ t << "\" prot=\"";
+ switch(md->protection())
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: t << "package"; break;
+ }
+ t << "\"";
+
+ t << " static=\"";
+ if (md->isStatic()) t << "yes"; else t << "no";
+ t << "\"";
+
+ if (isFunc)
+ {
+ ArgumentList *al = md->argumentList();
+ t << " const=\"";
+ if (al!=0 && al->constSpecifier) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " explicit=\"";
+ if (md->isExplicit()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " inline=\"";
+ if (md->isInline()) t << "yes"; else t << "no";
+ t << "\"";
+
+ if (md->isFinal())
+ {
+ t << " final=\"yes\"";
+ }
+
+ if (md->isSealed())
+ {
+ t << " sealed=\"yes\"";
+ }
+
+ if (md->isNew())
+ {
+ t << " new=\"yes\"";
+ }
+
+ if (md->isOptional())
+ {
+ t << " optional=\"yes\"";
+ }
+
+ if (md->isRequired())
+ {
+ t << " required=\"yes\"";
+ }
+
+ if (al && al->volatileSpecifier)
+ {
+ t << " volatile=\"yes\"";
+ }
+
+ t << " virt=\"";
+ switch (md->virtualness())
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
+ default: ASSERT(0);
+ }
+ t << "\"";
+ }
+
+ if (md->memberType() == MemberType_Variable)
+ {
+ //ArgumentList *al = md->argumentList();
+ //t << " volatile=\"";
+ //if (al && al->volatileSpecifier) t << "yes"; else t << "no";
+
+ t << " mutable=\"";
+ if (md->isMutable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ if (md->isInitonly())
+ {
+ t << " initonly=\"yes\"";
+ }
+ if (md->isAttribute())
+ {
+ t << " attribute=\"yes\"";
+ }
+ if (md->isUNOProperty())
+ {
+ t << " property=\"yes\"";
+ }
+ if (md->isReadonly())
+ {
+ t << " readonly=\"yes\"";
+ }
+ if (md->isBound())
+ {
+ t << " bound=\"yes\"";
+ }
+ if (md->isRemovable())
+ {
+ t << " removable=\"yes\"";
+ }
+ if (md->isConstrained())
+ {
+ t << " constrained=\"yes\"";
+ }
+ if (md->isTransient())
+ {
+ t << " transient=\"yes\"";
+ }
+ if (md->isMaybeVoid())
+ {
+ t << " maybevoid=\"yes\"";
+ }
+ if (md->isMaybeDefault())
+ {
+ t << " maybedefault=\"yes\"";
+ }
+ if (md->isMaybeAmbiguous())
+ {
+ t << " maybeambiguous=\"yes\"";
+ }
+ }
+ else if (md->memberType() == MemberType_Property)
+ {
+ t << " readable=\"";
+ if (md->isReadable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " writable=\"";
+ if (md->isWritable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " gettable=\"";
+ if (md->isGettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " privategettable=\"";
+ if (md->isPrivateGettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " protectedgettable=\"";
+ if (md->isProtectedGettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " settable=\"";
+ if (md->isSettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " privatesettable=\"";
+ if (md->isPrivateSettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " protectedsettable=\"";
+ if (md->isProtectedSettable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
+ {
+ t << " accessor=\"";
+ if (md->isAssign()) t << "assign";
+ else if (md->isCopy()) t << "copy";
+ else if (md->isRetain()) t << "retain";
+ else if (md->isStrong()) t << "strong";
+ else if (md->isWeak()) t << "weak";
+ t << "\"";
+ }
+ }
+ else if (md->memberType() == MemberType_Event)
+ {
+ t << " add=\"";
+ if (md->isAddable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " remove=\"";
+ if (md->isRemovable()) t << "yes"; else t << "no";
+ t << "\"";
+
+ t << " raise=\"";
+ if (md->isRaisable()) t << "yes"; else t << "no";
+ t << "\"";
+ }
+
+ t << ">" << endl;
+
+ if (md->memberType()!=MemberType_Define &&
+ md->memberType()!=MemberType_Enumeration
+ )
+ {
+ if (md->memberType()!=MemberType_Typedef)
+ {
+ writeMemberTemplateLists(md,t);
+ }
+ QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
+ stripQualifiers(typeStr);
+ t << " <type>";
+ linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
+ t << "</type>" << endl;
+ t << " <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
+ t << " <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
+ }
+
+ t << " <name>" << convertToXML(md->name()) << "</name>" << endl;
+
+ if (md->memberType() == MemberType_Property)
+ {
+ if (md->isReadable())
+ t << " <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
+ if (md->isWritable())
+ t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
+ }
+ if (md->memberType()==MemberType_Variable && md->bitfieldString())
+ {
+ QCString bitfield = md->bitfieldString();
+ if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
+ t << " <bitfield>" << bitfield << "</bitfield>" << endl;
+ }
+
+ MemberDef *rmd = md->reimplements();
+ if (rmd)
+ {
+ t << " <reimplements refid=\""
+ << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
+ << convertToXML(rmd->name()) << "</reimplements>" << endl;
+ }
+ MemberList *rbml = md->reimplementedBy();
+ if (rbml)
+ {
+ MemberListIterator mli(*rbml);
+ for (mli.toFirst();(rmd=mli.current());++mli)
+ {
+ t << " <reimplementedby refid=\""
+ << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
+ << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
+ }
+ }
+
+ if (isFunc) //function
+ {
+ ArgumentList *declAl = md->declArgumentList();
+ ArgumentList *defAl = md->argumentList();
+ if (declAl && declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ Argument *defArg = defAli.current();
+ t << " <param>" << endl;
+ if (!a->attrib.isEmpty())
+ {
+ t << " <attributes>";
+ writeXMLString(t,a->attrib);
+ t << "</attributes>" << endl;
+ }
+ if (!a->type.isEmpty())
+ {
+ t << " <type>";
+ linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
+ t << "</type>" << endl;
+ }
+ if (!a->name.isEmpty())
+ {
+ t << " <declname>";
+ writeXMLString(t,a->name);
+ t << "</declname>" << endl;
+ }
+ if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
+ {
+ t << " <defname>";
+ writeXMLString(t,defArg->name);
+ t << "</defname>" << endl;
+ }
+ if (!a->array.isEmpty())
+ {
+ t << " <array>";
+ writeXMLString(t,a->array);
+ t << "</array>" << endl;
+ }
+ if (!a->defval.isEmpty())
+ {
+ t << " <defval>";
+ linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
+ t << "</defval>" << endl;
+ }
+ if (defArg && defArg->hasDocumentation())
+ {
+ t << " <briefdescription>";
+ writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
+ md->getOuterScope(),md,defArg->docs);
+ t << "</briefdescription>" << endl;
+ }
+ t << " </param>" << endl;
+ if (defArg) ++defAli;
+ }
+ }
+ }
+ else if (md->memberType()==MemberType_Define &&
+ md->argsString()) // define
+ {
+ if (md->argumentList()->count()==0) // special case for "foo()" to
+ // disguish it from "foo".
+ {
+ t << " <param></param>" << endl;
+ }
+ else
+ {
+ ArgumentListIterator ali(*md->argumentList());
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ t << " <param><defname>" << a->type << "</defname></param>" << endl;
+ }
+ }
+ }
+
+ if (md->hasOneLineInitializer() || md->hasMultiLineInitializer())
+ {
+ t << " <initializer>";
+ linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
+ t << "</initializer>" << endl;
+ }
+
+ if (md->excpString())
+ {
+ t << " <exceptions>";
+ linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
+ t << "</exceptions>" << endl;
+ }
+
+ if (md->memberType()==MemberType_Enumeration) // enum
+ {
+ MemberList *enumFields = md->enumFieldList();
+ if (enumFields)
+ {
+ MemberListIterator emli(*enumFields);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ ti << " <member refid=\"" << memberOutputFileBase(emd)
+ << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
+ << convertToXML(emd->name()) << "</name></member>" << endl;
+
+ t << " <enumvalue id=\"" << memberOutputFileBase(emd) << "_1"
+ << emd->anchor() << "\" prot=\"";
+ switch (emd->protection())
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: t << "package"; break;
+ }
+ t << "\">" << endl;
+ t << " <name>";
+ writeXMLString(t,emd->name());
+ t << "</name>" << endl;
+ if (!emd->initializer().isEmpty())
+ {
+ t << " <initializer>";
+ writeXMLString(t,emd->initializer());
+ t << "</initializer>" << endl;
+ }
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
+ t << " </detaileddescription>" << endl;
+ t << " </enumvalue>" << endl;
+ }
+ }
+ }
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
+ t << " </detaileddescription>" << endl;
+ t << " <inbodydescription>" << endl;
+ writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
+ t << " </inbodydescription>" << endl;
+ if (md->getDefLine()!=-1)
+ {
+ t << " <location file=\""
+ << md->getDefFileName() << "\" line=\""
+ << md->getDefLine() << "\"" << " column=\""
+ << md->getDefColumn() << "\"" ;
+ if (md->getStartBodyLine()!=-1)
+ {
+ FileDef *bodyDef = md->getBodyDef();
+ if (bodyDef)
+ {
+ t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
+ }
+ t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\""
+ << md->getEndBodyLine() << "\"";
+ }
+ t << "/>" << endl;
+ }
+
+ //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
+ MemberSDict *mdict = md->getReferencesMembers();
+ if (mdict)
+ {
+ MemberSDict::Iterator mdi(*mdict);
+ MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ writeMemberReference(t,def,rmd,"references");
+ }
+ }
+ mdict = md->getReferencedByMembers();
+ if (mdict)
+ {
+ MemberSDict::Iterator mdi(*mdict);
+ MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ writeMemberReference(t,def,rmd,"referencedby");
+ }
+ }
+
+ t << " </memberdef>" << endl;
+}
+
+static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
+ MemberList *ml,const char *kind,const char *header=0,
+ const char *documentation=0)
+{
+ if (ml==0) return;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ int count=0;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the XML output, we filter those here.
+ if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ count++;
+ }
+ }
+ if (count==0) return; // empty list
+
+ t << " <sectiondef kind=\"" << kind << "\">" << endl;
+ if (header)
+ {
+ t << " <header>" << convertToXML(header) << "</header>" << endl;
+ }
+ if (documentation)
+ {
+ t << " <description>";
+ writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
+ t << "</description>" << endl;
+ }
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ // namespace members are also inserted in the file scope, but
+ // to prevent this duplication in the XML output, we filter those here.
+ if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ {
+ generateXMLForMember(md,ti,t,d);
+ }
+ }
+ t << " </sectiondef>" << endl;
+}
+
+static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
+{
+ t << " <listofallmembers>" << endl;
+ if (cd->memberNameInfoSDict())
+ {
+ MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberNameInfoIterator mii(*mni);
+ MemberInfo *mi;
+ for (mii.toFirst();(mi=mii.current());++mii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->name().at(0)!='@') // skip anonymous members
+ {
+ Protection prot = mi->prot;
+ Specifier virt=md->virtualness();
+ t << " <member refid=\"" << memberOutputFileBase(md) << "_1" <<
+ md->anchor() << "\" prot=\"";
+ switch (prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: t << "package"; break;
+ }
+ t << "\" virt=\"";
+ switch(virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
+ }
+ t << "\"";
+ if (!mi->ambiguityResolutionScope.isEmpty())
+ {
+ t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
+ }
+ t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" <<
+ convertToXML(md->name()) << "</name></member>" << endl;
+ }
+ }
+ }
+ }
+ t << " </listofallmembers>" << endl;
+}
+
+static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
+{
+ if (cl)
+ {
+ ClassSDict::Iterator cli(*cl);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
+ {
+ t << " <innerclass refid=\"" << classOutputFileBase(cd)
+ << "\" prot=\"";
+ switch(cd->protection())
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: t << "package"; break;
+ }
+ t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
+ }
+ }
+ }
+}
+
+static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
+{
+ if (nl)
+ {
+ NamespaceSDict::Iterator nli(*nl);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
+ {
+ t << " <innernamespace refid=\"" << nd->getOutputFileBase()
+ << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
+ }
+ }
+ }
+}
+
+static void writeInnerFiles(const FileList *fl,FTextStream &t)
+{
+ if (fl)
+ {
+ QListIterator<FileDef> fli(*fl);
+ FileDef *fd;
+ for (fli.toFirst();(fd=fli.current());++fli)
+ {
+ t << " <innerfile refid=\"" << fd->getOutputFileBase()
+ << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
+ }
+ }
+}
+
+static void writeInnerPages(const PageSDict *pl,FTextStream &t)
+{
+ if (pl)
+ {
+ PageSDict::Iterator pli(*pl);
+ PageDef *pd;
+ for (pli.toFirst();(pd=pli.current());++pli)
+ {
+ t << " <innerpage refid=\"" << pd->getOutputFileBase();
+ if (pd->getGroupDef())
+ {
+ t << "_" << pd->name();
+ }
+ t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
+ }
+ }
+}
+
+static void writeInnerGroups(const GroupList *gl,FTextStream &t)
+{
+ if (gl)
+ {
+ GroupListIterator gli(*gl);
+ GroupDef *sgd;
+ for (gli.toFirst();(sgd=gli.current());++gli)
+ {
+ t << " <innergroup refid=\"" << sgd->getOutputFileBase()
+ << "\">" << convertToXML(sgd->groupTitle())
+ << "</innergroup>" << endl;
+ }
+ }
+}
+
+static void writeInnerDirs(const DirList *dl,FTextStream &t)
+{
+ if (dl)
+ {
+ QListIterator<DirDef> subdirs(*dl);
+ DirDef *subdir;
+ for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
+ {
+ t << " <innerdir refid=\"" << subdir->getOutputFileBase()
+ << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
+ }
+ }
+}
+
+static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
+{
+ // + brief description
+ // + detailed description
+ // + template argument list(s)
+ // - include file
+ // + member groups
+ // + inheritance diagram
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + list of inner classes
+ // + collaboration diagram
+ // + list of all members
+ // + user defined member sections
+ // + standard member sections
+ // + detailed member documentation
+ // - examples using the class
+
+ if (cd->isReference()) return; // skip external references.
+ if (cd->isHidden()) return; // skip hidden classes.
+ if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
+ if (cd->templateMaster()!=0) return; // skip generated template instances.
+ if (cd->isArtificial()) return; // skip artificially created classes
+
+ msg("Generating XML output for class %s\n",cd->name().data());
+
+ ti << " <compound refid=\"" << classOutputFileBase(cd)
+ << "\" kind=\"" << cd->compoundTypeString()
+ << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ writeXMLHeader(t);
+ t << " <compounddef id=\""
+ << classOutputFileBase(cd) << "\" kind=\""
+ << cd->compoundTypeString() << "\" prot=\"";
+ switch (cd->protection())
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: t << "package"; break;
+ }
+ if (cd->isFinal()) t << "\" final=\"yes";
+ if (cd->isSealed()) t << "\" sealed=\"yes";
+ if (cd->isAbstract()) t << "\" abstract=\"yes";
+ t << "\">" << endl;
+ t << " <compoundname>";
+ writeXMLString(t,cd->name());
+ t << "</compoundname>" << endl;
+ if (cd->baseClasses())
+ {
+ BaseClassListIterator bcli(*cd->baseClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " <basecompoundref ";
+ if (bcd->classDef->isLinkable())
+ {
+ t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
+ }
+ t << "prot=\"";
+ switch (bcd->prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: ASSERT(0); break;
+ }
+ t << "\" virt=\"";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t <<"pure-virtual"; break;
+ }
+ t << "\">";
+ if (!bcd->templSpecifiers.isEmpty())
+ {
+ t << convertToXML(
+ insertTemplateSpecifierInScope(
+ bcd->classDef->name(),bcd->templSpecifiers)
+ );
+ }
+ else
+ {
+ t << convertToXML(bcd->classDef->displayName());
+ }
+ t << "</basecompoundref>" << endl;
+ }
+ }
+ if (cd->subClasses())
+ {
+ BaseClassListIterator bcli(*cd->subClasses());
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " <derivedcompoundref refid=\""
+ << classOutputFileBase(bcd->classDef)
+ << "\" prot=\"";
+ switch (bcd->prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: ASSERT(0); break;
+ }
+ t << "\" virt=\"";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
+ }
+ t << "\">" << convertToXML(bcd->classDef->displayName())
+ << "</derivedcompoundref>" << endl;
+ }
+ }
+
+ IncludeInfo *ii=cd->includeInfo();
+ if (ii)
+ {
+ QCString nm = ii->includeName;
+ if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
+ if (!nm.isEmpty())
+ {
+ t << " <includes";
+ if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
+ {
+ t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
+ }
+ t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
+ t << nm;
+ t << "</includes>" << endl;
+ }
+ }
+
+ writeInnerClasses(cd->getClassSDict(),t);
+
+ writeTemplateList(cd,t);
+ if (cd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(cd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_detailedLists)==0)
+ {
+ generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+#if 0
+ generateXMLSection(cd,ti,t,cd->pubTypes,"public-type");
+ generateXMLSection(cd,ti,t,cd->pubMethods,"public-func");
+ generateXMLSection(cd,ti,t,cd->pubAttribs,"public-attrib");
+ generateXMLSection(cd,ti,t,cd->pubSlots,"public-slot");
+ generateXMLSection(cd,ti,t,cd->signals,"signal");
+ generateXMLSection(cd,ti,t,cd->dcopMethods,"dcop-func");
+ generateXMLSection(cd,ti,t,cd->properties,"property");
+ generateXMLSection(cd,ti,t,cd->events,"event");
+ generateXMLSection(cd,ti,t,cd->pubStaticMethods,"public-static-func");
+ generateXMLSection(cd,ti,t,cd->pubStaticAttribs,"public-static-attrib");
+ generateXMLSection(cd,ti,t,cd->proTypes,"protected-type");
+ generateXMLSection(cd,ti,t,cd->proMethods,"protected-func");
+ generateXMLSection(cd,ti,t,cd->proAttribs,"protected-attrib");
+ generateXMLSection(cd,ti,t,cd->proSlots,"protected-slot");
+ generateXMLSection(cd,ti,t,cd->proStaticMethods,"protected-static-func");
+ generateXMLSection(cd,ti,t,cd->proStaticAttribs,"protected-static-attrib");
+ generateXMLSection(cd,ti,t,cd->pacTypes,"package-type");
+ generateXMLSection(cd,ti,t,cd->pacMethods,"package-func");
+ generateXMLSection(cd,ti,t,cd->pacAttribs,"package-attrib");
+ generateXMLSection(cd,ti,t,cd->pacStaticMethods,"package-static-func");
+ generateXMLSection(cd,ti,t,cd->pacStaticAttribs,"package-static-attrib");
+ generateXMLSection(cd,ti,t,cd->priTypes,"private-type");
+ generateXMLSection(cd,ti,t,cd->priMethods,"private-func");
+ generateXMLSection(cd,ti,t,cd->priAttribs,"private-attrib");
+ generateXMLSection(cd,ti,t,cd->priSlots,"private-slot");
+ generateXMLSection(cd,ti,t,cd->priStaticMethods,"private-static-func");
+ generateXMLSection(cd,ti,t,cd->priStaticAttribs,"private-static-attrib");
+ generateXMLSection(cd,ti,t,cd->friends,"friend");
+ generateXMLSection(cd,ti,t,cd->related,"related");
+#endif
+
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
+ t << " </detaileddescription>" << endl;
+ DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial())
+ {
+ t << " <inheritancegraph>" << endl;
+ inheritanceGraph.writeXML(t);
+ t << " </inheritancegraph>" << endl;
+ }
+ DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
+ if (!collaborationGraph.isTrivial())
+ {
+ t << " <collaborationgraph>" << endl;
+ collaborationGraph.writeXML(t);
+ t << " </collaborationgraph>" << endl;
+ }
+ t << " <location file=\""
+ << cd->getDefFileName() << "\" line=\""
+ << cd->getDefLine() << "\"" << " column=\""
+ << cd->getDefColumn() << "\"" ;
+ if (cd->getStartBodyLine()!=-1)
+ {
+ FileDef *bodyDef = cd->getBodyDef();
+ if (bodyDef)
+ {
+ t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
+ }
+ t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
+ << cd->getEndBodyLine() << "\"";
+ }
+ t << "/>" << endl;
+ writeListOfAllMembers(cd,t);
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
+{
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // + location
+ // - files containing (parts of) the namespace definition
+
+ if (nd->isReference() || nd->isHidden()) return; // skip external references
+
+ ti << " <compound refid=\"" << nd->getOutputFileBase()
+ << "\" kind=\"namespace\"" << "><name>"
+ << convertToXML(nd->name()) << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ writeXMLHeader(t);
+ t << " <compounddef id=\""
+ << nd->getOutputFileBase() << "\" kind=\"namespace\">" << endl;
+ t << " <compoundname>";
+ writeXMLString(t,nd->name());
+ t << "</compoundname>" << endl;
+
+ writeInnerClasses(nd->getClassSDict(),t);
+ writeInnerNamespaces(nd->getNamespaceSDict(),t);
+
+ if (nd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(nd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+#if 0
+ generateXMLSection(nd,ti,t,&nd->decDefineMembers,"define");
+ generateXMLSection(nd,ti,t,&nd->decProtoMembers,"prototype");
+ generateXMLSection(nd,ti,t,&nd->decTypedefMembers,"typedef");
+ generateXMLSection(nd,ti,t,&nd->decEnumMembers,"enum");
+ generateXMLSection(nd,ti,t,&nd->decFuncMembers,"func");
+ generateXMLSection(nd,ti,t,&nd->decVarMembers,"var");
+#endif
+
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
+ t << " </detaileddescription>" << endl;
+ t << " <location file=\""
+ << nd->getDefFileName() << "\" line=\""
+ << nd->getDefLine() << "\"" << " column=\""
+ << nd->getDefColumn() << "\"/>" << endl ;
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+static void generateXMLForFile(FileDef *fd,FTextStream &ti)
+{
+ // + includes files
+ // + includedby files
+ // + include graph
+ // + included by graph
+ // + contained class definitions
+ // + contained namespace definitions
+ // + member groups
+ // + normal members
+ // + brief desc
+ // + detailed desc
+ // + source code
+ // + location
+ // - number of lines
+
+ if (fd->isReference()) return; // skip external references
+
+ ti << " <compound refid=\"" << fd->getOutputFileBase()
+ << "\" kind=\"file\"><name>" << convertToXML(fd->name())
+ << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ writeXMLHeader(t);
+ t << " <compounddef id=\""
+ << fd->getOutputFileBase() << "\" kind=\"file\">" << endl;
+ t << " <compoundname>";
+ writeXMLString(t,fd->name());
+ t << "</compoundname>" << endl;
+
+ IncludeInfo *inc;
+
+ if (fd->includeFileList())
+ {
+ QListIterator<IncludeInfo> ili1(*fd->includeFileList());
+ for (ili1.toFirst();(inc=ili1.current());++ili1)
+ {
+ t << " <includes";
+ if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
+ {
+ t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
+ }
+ t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
+ t << inc->includeName;
+ t << "</includes>" << endl;
+ }
+ }
+
+ if (fd->includedByFileList())
+ {
+ QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
+ for (ili2.toFirst();(inc=ili2.current());++ili2)
+ {
+ t << " <includedby";
+ if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
+ {
+ t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
+ }
+ t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
+ t << inc->includeName;
+ t << "</includedby>" << endl;
+ }
+ }
+
+ DotInclDepGraph incDepGraph(fd,FALSE);
+ if (!incDepGraph.isTrivial())
+ {
+ t << " <incdepgraph>" << endl;
+ incDepGraph.writeXML(t);
+ t << " </incdepgraph>" << endl;
+ }
+
+ DotInclDepGraph invIncDepGraph(fd,TRUE);
+ if (!invIncDepGraph.isTrivial())
+ {
+ t << " <invincdepgraph>" << endl;
+ invIncDepGraph.writeXML(t);
+ t << " </invincdepgraph>" << endl;
+ }
+
+ if (fd->getClassSDict())
+ {
+ writeInnerClasses(fd->getClassSDict(),t);
+ }
+ if (fd->getNamespaceSDict())
+ {
+ writeInnerNamespaces(fd->getNamespaceSDict(),t);
+ }
+
+ if (fd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(fd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+#if 0
+ generateXMLSection(fd,ti,t,fd->decDefineMembers,"define");
+ generateXMLSection(fd,ti,t,fd->decProtoMembers,"prototype");
+ generateXMLSection(fd,ti,t,fd->decTypedefMembers,"typedef");
+ generateXMLSection(fd,ti,t,fd->decEnumMembers,"enum");
+ generateXMLSection(fd,ti,t,fd->decFuncMembers,"func");
+ generateXMLSection(fd,ti,t,fd->decVarMembers,"var");
+#endif
+
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
+ t << " </detaileddescription>" << endl;
+ if (Config_getBool("XML_PROGRAMLISTING"))
+ {
+ t << " <programlisting>" << endl;
+ writeXMLCodeBlock(t,fd);
+ t << " </programlisting>" << endl;
+ }
+ t << " <location file=\"" << fd->getDefFileName() << "\"/>" << endl;
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
+{
+ // + members
+ // + member groups
+ // + files
+ // + classes
+ // + namespaces
+ // - packages
+ // + pages
+ // + child groups
+ // - examples
+ // + brief description
+ // + detailed description
+
+ if (gd->isReference()) return; // skip external references
+
+ ti << " <compound refid=\"" << gd->getOutputFileBase()
+ << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeXMLHeader(t);
+ t << " <compounddef id=\""
+ << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
+ t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
+ t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
+
+ writeInnerFiles(gd->getFiles(),t);
+ writeInnerClasses(gd->getClasses(),t);
+ writeInnerNamespaces(gd->getNamespaces(),t);
+ writeInnerPages(gd->getPages(),t);
+ writeInnerGroups(gd->getSubGroups(),t);
+
+ if (gd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ QListIterator<MemberList> mli(gd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+ }
+ }
+#if 0
+ generateXMLSection(gd,ti,t,&gd->decDefineMembers,"define");
+ generateXMLSection(gd,ti,t,&gd->decProtoMembers,"prototype");
+ generateXMLSection(gd,ti,t,&gd->decTypedefMembers,"typedef");
+ generateXMLSection(gd,ti,t,&gd->decEnumMembers,"enum");
+ generateXMLSection(gd,ti,t,&gd->decFuncMembers,"func");
+ generateXMLSection(gd,ti,t,&gd->decVarMembers,"var");
+#endif
+
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
+ t << " </detaileddescription>" << endl;
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+static void generateXMLForDir(DirDef *dd,FTextStream &ti)
+{
+ if (dd->isReference()) return; // skip external references
+ ti << " <compound refid=\"" << dd->getOutputFileBase()
+ << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName())
+ << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeXMLHeader(t);
+ t << " <compounddef id=\""
+ << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
+ t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
+
+ writeInnerDirs(&dd->subDirs(),t);
+ writeInnerFiles(dd->getFiles(),t);
+
+ t << " <briefdescription>" << endl;
+ writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
+ t << " </briefdescription>" << endl;
+ t << " <detaileddescription>" << endl;
+ writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
+ t << " </detaileddescription>" << endl;
+ t << " <location file=\"" << dd->name() << "\"/>" << endl;
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
+{
+ // + name
+ // + title
+ // + documentation
+
+ const char *kindName = isExample ? "example" : "page";
+
+ if (pd->isReference()) return;
+
+ QCString pageName = pd->getOutputFileBase();
+ if (pd->getGroupDef())
+ {
+ pageName+=(QCString)"_"+pd->name();
+ }
+ if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
+
+ ti << " <compound refid=\"" << pageName
+ << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name())
+ << "</name>" << endl;
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QCString fileName=outputDirectory+"/"+pageName+".xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+ writeXMLHeader(t);
+ t << " <compounddef id=\"" << pageName;
+ t << "\" kind=\"" << kindName << "\">" << endl;
+ t << " <compoundname>" << convertToXML(pd->name())
+ << "</compoundname>" << endl;
+
+ if (pd==Doxygen::mainPage) // main page is special
+ {
+ QCString title;
+ if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
+ {
+ title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
+ }
+ else
+ {
+ title = Config_getString("PROJECT_NAME");
+ }
+ t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title))
+ << "</title>" << endl;
+ }
+ else
+ {
+ SectionInfo *si = Doxygen::sectionDict->find(pd->name());
+ if (si)
+ {
+ t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title)))
+ << "</title>" << endl;
+ }
+ }
+ writeInnerPages(pd->getSubPages(),t);
+ t << " <detaileddescription>" << endl;
+ if (isExample)
+ {
+ writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
+ pd->documentation()+"\n\\include "+pd->name());
+ }
+ else
+ {
+ writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
+ pd->documentation());
+ }
+ t << " </detaileddescription>" << endl;
+
+ t << " </compounddef>" << endl;
+ t << "</doxygen>" << endl;
+
+ ti << " </compound>" << endl;
+}
+
+void generateXML()
+{
+ // + classes
+ // + namespaces
+ // + files
+ // + groups
+ // + related pages
+ // - examples
+
+ QCString outputDirectory = Config_getString("XML_OUTPUT");
+ QDir xmlDir(outputDirectory);
+ createSubDirs(xmlDir);
+ QCString fileName=outputDirectory+"/index.xsd";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ f.writeBlock(index_xsd,qstrlen(index_xsd));
+ f.close();
+
+ fileName=outputDirectory+"/compound.xsd";
+ f.setName(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+
+ // write compound.xsd, but replace special marker with the entities
+ const char *startLine = compound_xsd;
+ while (*startLine)
+ {
+ // find end of the line
+ const char *endLine = startLine+1;
+ while (*endLine && *(endLine-1)!='\n') endLine++; // skip to end of the line including \n
+ int len=endLine-startLine;
+ if (len>0)
+ {
+ QCString s(len+1);
+ qstrncpy(s.data(),startLine,len);
+ s[len]='\0';
+ if (s.find("<!-- Automatically insert here the HTML entities -->")!=-1)
+ {
+ FTextStream t(&f);
+ HtmlEntityMapper::instance()->writeXMLSchema(t);
+ }
+ else
+ {
+ f.writeBlock(startLine,len);
+ }
+ }
+ startLine=endLine;
+ }
+ f.close();
+
+ fileName=outputDirectory+"/index.xml";
+ f.setName(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ FTextStream t(&f);
+ //t.setEncoding(FTextStream::UnicodeUTF8);
+
+ // write index header
+ t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
+ t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
+ t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
+ t << "version=\"" << versionString << "\">" << endl;
+
+ {
+ ClassSDict::Iterator cli(*Doxygen::classSDict);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ generateXMLForClass(cd,t);
+ }
+ }
+ //{
+ // ClassSDict::Iterator cli(Doxygen::hiddenClasses);
+ // ClassDef *cd;
+ // for (cli.toFirst();(cd=cli.current());++cli)
+ // {
+ // msg("Generating XML output for class %s\n",cd->name().data());
+ // generateXMLForClass(cd,t);
+ // }
+ //}
+ NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+ NamespaceDef *nd;
+ for (nli.toFirst();(nd=nli.current());++nli)
+ {
+ msg("Generating XML output for namespace %s\n",nd->name().data());
+ generateXMLForNamespace(nd,t);
+ }
+ FileNameListIterator fnli(*Doxygen::inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ msg("Generating XML output for file %s\n",fd->name().data());
+ generateXMLForFile(fd,t);
+ }
+ }
+ GroupSDict::Iterator gli(*Doxygen::groupSDict);
+ GroupDef *gd;
+ for (;(gd=gli.current());++gli)
+ {
+ msg("Generating XML output for group %s\n",gd->name().data());
+ generateXMLForGroup(gd,t);
+ }
+ {
+ PageSDict::Iterator pdi(*Doxygen::pageSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating XML output for page %s\n",pd->name().data());
+ generateXMLForPage(pd,t,FALSE);
+ }
+ }
+ {
+ DirDef *dir;
+ DirSDict::Iterator sdi(*Doxygen::directories);
+ for (sdi.toFirst();(dir=sdi.current());++sdi)
+ {
+ msg("Generate XML output for dir %s\n",dir->name().data());
+ generateXMLForDir(dir,t);
+ }
+ }
+ {
+ PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+ PageDef *pd=0;
+ for (pdi.toFirst();(pd=pdi.current());++pdi)
+ {
+ msg("Generating XML output for example %s\n",pd->name().data());
+ generateXMLForPage(pd,t,TRUE);
+ }
+ }
+ if (Doxygen::mainPage)
+ {
+ msg("Generating XML output for the main page\n");
+ generateXMLForPage(Doxygen::mainPage,t,FALSE);
+ }
+
+ //t << " </compoundlist>" << endl;
+ t << "</doxygenindex>" << endl;
+
+ writeCombineScript();
+}
+
+
diff --git a/src/xmlgen.h b/src/xmlgen.h
new file mode 100644
index 0000000..9c9ae17
--- /dev/null
+++ b/src/xmlgen.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2014 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+
+#ifndef XMLGEN_H
+#define XMLGEN_H
+
+void generateXML();
+
+#endif
diff --git a/testing/001/indexpage.xml b/testing/001/indexpage.xml
new file mode 100644
index 0000000..06d680b
--- /dev/null
+++ b/testing/001/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Text <emphasis>argument</emphasis> more text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/001_a.dox b/testing/001_a.dox
new file mode 100644
index 0000000..c37136b
--- /dev/null
+++ b/testing/001_a.dox
@@ -0,0 +1,5 @@
+// objective: test the \a and \mainpage commands
+// check: indexpage.xml
+/** \mainpage
+ * Text \a argument more text.
+ */
diff --git a/testing/002/indexpage.xml b/testing/002/indexpage.xml
new file mode 100644
index 0000000..1eba9d5
--- /dev/null
+++ b/testing/002/indexpage.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <indexentry>
+ <primaryie>keyword</primaryie>
+ <secondaryie/>
+ </indexentry>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/002_addindex.dox b/testing/002_addindex.dox
new file mode 100644
index 0000000..b1c941f
--- /dev/null
+++ b/testing/002_addindex.dox
@@ -0,0 +1,5 @@
+// objective: test \addindex command
+// check: indexpage.xml
+/** \mainpage
+ * \addindex keyword
+ */
diff --git a/testing/003/indexpage.xml b/testing/003/indexpage.xml
new file mode 100644
index 0000000..a4f42e2
--- /dev/null
+++ b/testing/003/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para><ref refid="index_1myanchor" kindref="member">See Anchor</ref> Some text. <anchor id="index_1myanchor"/>More text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/003_anchor.dox b/testing/003_anchor.dox
new file mode 100644
index 0000000..b28fc5e
--- /dev/null
+++ b/testing/003_anchor.dox
@@ -0,0 +1,8 @@
+// objective: test \anchor command
+// check: indexpage.xml
+/** \mainpage
+ * \ref myanchor "See Anchor"
+ * Some text.
+ * \anchor myanchor
+ * More text.
+ */
diff --git a/testing/004/indexpage.xml b/testing/004/indexpage.xml
new file mode 100644
index 0000000..3d0a713
--- /dev/null
+++ b/testing/004/indexpage.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para><itemizedlist><listitem><para><computeroutput>AlignLeft</computeroutput> left alignment. </para></listitem><listitem><para><computeroutput>AlignCenter</computeroutput> center alignment. </para></listitem><listitem><para><computeroutput>AlignRight</computeroutput> right alignment</para></listitem></itemizedlist>
+No other types of alignment are supported.</para>
+ <para><itemizedlist><listitem><para><computeroutput>AlignLeft</computeroutput> left alignment. </para></listitem><listitem><para><computeroutput>AlignCenter</computeroutput> center alignment. </para></listitem><listitem><para><computeroutput>AlignRight</computeroutput> right alignment</para></listitem></itemizedlist>
+No other types of alignment are supported. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/004_arg.dox b/testing/004_arg.dox
new file mode 100644
index 0000000..c6ea8e5
--- /dev/null
+++ b/testing/004_arg.dox
@@ -0,0 +1,15 @@
+// objective: test \arg and \li commands
+// check: indexpage.xml
+/** \mainpage
+ \arg \c AlignLeft left alignment.
+ \arg \c AlignCenter center alignment.
+ \arg \c AlignRight right alignment
+
+ No other types of alignment are supported.
+
+ \li \c AlignLeft left alignment.
+ \li \c AlignCenter center alignment.
+ \li \c AlignRight right alignment
+
+ No other types of alignment are supported.
+*/
diff --git a/testing/005/indexpage.xml b/testing/005/indexpage.xml
new file mode 100644
index 0000000..5a2e6f9
--- /dev/null
+++ b/testing/005/indexpage.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <simplesect kind="attention">
+ <para>Attention message. </para>
+ </simplesect>
+ <simplesect kind="note">
+ <para>Something to note. </para>
+ </simplesect>
+ <simplesect kind="remark">
+ <para>A remark. </para>
+ </simplesect>
+ <simplesect kind="warning">
+ <para>A warning message. </para>
+ </simplesect>
+ <simplesect kind="par">
+ <title/>
+ <para>Second paragraph </para>
+ </simplesect>
+ <simplesect kind="par">
+ <title>User defined paragraph.</title>
+ <para>Contents of paragraph. </para>
+ </simplesect>
+ <simplesect kind="par">
+ <title/>
+ <para>More text in a new paragraph. </para>
+ </simplesect>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/005_attention.dox b/testing/005_attention.dox
new file mode 100644
index 0000000..c3c390e
--- /dev/null
+++ b/testing/005_attention.dox
@@ -0,0 +1,14 @@
+// objective: test \attention, \not, \remark, \warning, and \par commands
+// check: indexpage.xml
+/** \mainpage
+ * \attention Attention message.
+ * \note Something to note.
+ * \remark A remark.
+ * \warning A warning message.
+ * \par
+ * Second paragraph
+ * \par User defined paragraph.
+ * Contents of paragraph.
+ * \par
+ * More text in a new paragraph.
+ */
diff --git a/testing/006/indexpage.xml b/testing/006/indexpage.xml
new file mode 100644
index 0000000..1afe69b
--- /dev/null
+++ b/testing/006/indexpage.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <simplesect kind="author">
+ <para>John Doe </para>
+ </simplesect>
+ <simplesect kind="author">
+ <para>Jane Doe </para>
+ </simplesect>
+ <simplesect kind="authors">
+ <para>David, Steven </para>
+ </simplesect>
+ <simplesect kind="since">
+ <para>version 1.2 </para>
+ </simplesect>
+ <simplesect kind="version">
+ <para>1.8-beta2 </para>
+ </simplesect>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/006_author.dox b/testing/006_author.dox
new file mode 100644
index 0000000..ba07c1e
--- /dev/null
+++ b/testing/006_author.dox
@@ -0,0 +1,9 @@
+// objective: test the \author, \since, and \version command
+// check: indexpage.xml
+/** \mainpage
+ * \author John Doe
+ * \author Jane Doe
+ * \authors David, Steven
+ * \since version 1.2
+ * \version 1.8-beta2
+ */
diff --git a/testing/007/indexpage.xml b/testing/007/indexpage.xml
new file mode 100644
index 0000000..9b22813
--- /dev/null
+++ b/testing/007/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Text <bold>bold</bold> normal text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/007_b.dox b/testing/007_b.dox
new file mode 100644
index 0000000..887c19f
--- /dev/null
+++ b/testing/007_b.dox
@@ -0,0 +1,5 @@
+// objective: test the \b command
+// check: indexpage.xml
+/** \mainpage
+ * Text \b bold normal text.
+ */
diff --git a/testing/008/008__brief_8c.xml b/testing/008/008__brief_8c.xml
new file mode 100644
index 0000000..3416798
--- /dev/null
+++ b/testing/008/008__brief_8c.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="008__brief_8c" kind="file">
+ <compoundname>008_brief.c</compoundname>
+ <briefdescription>
+ <para>A brief description. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>More details. </para>
+ </detaileddescription>
+ <location file="008_brief.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/008_brief.c b/testing/008_brief.c
new file mode 100644
index 0000000..773eaf1
--- /dev/null
+++ b/testing/008_brief.c
@@ -0,0 +1,7 @@
+// objective: test \brief and \file command
+// check: 008__brief_8c.xml
+/** \file
+ * \brief A brief description.
+ *
+ * More details.
+ */
diff --git a/testing/009/bug.xml b/testing/009/bug.xml
new file mode 100644
index 0000000..1d80134
--- /dev/null
+++ b/testing/009/bug.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="bug" kind="page">
+ <compoundname>bug</compoundname>
+ <title>Bug List</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="bug_1_bug000001"/>Class <ref refid="class_bug" kindref="compound">Bug</ref></term>
+ </varlistentry>
+ <listitem>
+ <para>Class bug. </para>
+ </listitem>
+ <varlistentry>
+ <term><anchor id="bug_1_bug000002"/>Member <ref refid="class_bug_1a1f720954dd97cd1203e80501a6eae74c" kindref="member">Bug::foo</ref> ()</term>
+ </varlistentry>
+ <listitem>
+ <para>Function bug<itemizedlist><listitem><para>list item 1 in bug</para></listitem><listitem><para>list item 2 in bug</para></listitem></itemizedlist>
+</para>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/class_bug.xml b/testing/009/class_bug.xml
new file mode 100644
index 0000000..75a3fa1
--- /dev/null
+++ b/testing/009/class_bug.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_bug" kind="class" prot="public">
+ <compoundname>Bug</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_bug_1a1f720954dd97cd1203e80501a6eae74c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Bug::foo</definition>
+ <argsstring>()</argsstring>
+ <name>foo</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Description <xrefsect id="bug_1_bug000002"><xreftitle>Bug</xreftitle><xrefdescription><para>Function bug<itemizedlist><listitem><para>list item 1 in bug</para></listitem><listitem><para>list item 2 in bug</para></listitem></itemizedlist>
+</para></xrefdescription></xrefsect></para>
+ <para>More text. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="009_bug.cpp" line="25" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="bug_1_bug000001">
+ <xreftitle>Bug</xreftitle>
+ <xrefdescription>
+ <para>Class bug. </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <location file="009_bug.cpp" bodystart="15" bodyend="26"/>
+ <listofallmembers>
+ <member refid="class_bug_1a1f720954dd97cd1203e80501a6eae74c" prot="public" virt="non-virtual">
+ <scope>Bug</scope>
+ <name>foo</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/class_deprecated.xml b/testing/009/class_deprecated.xml
new file mode 100644
index 0000000..2420466
--- /dev/null
+++ b/testing/009/class_deprecated.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_deprecated" kind="class" prot="public">
+ <compoundname>Deprecated</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_deprecated_1a1d5f6803e72c625727e7083d1722dbf9" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Deprecated::deprecated</definition>
+ <argsstring>()</argsstring>
+ <name>deprecated</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Do deprecated things. <xrefsect id="deprecated_1_deprecated000002"><xreftitle>Deprecated</xreftitle><xrefdescription><para>No not use this function anymore. </para></xrefdescription></xrefsect></para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="009_bug.cpp" line="35" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="deprecated_1_deprecated000001">
+ <xreftitle>Deprecated</xreftitle>
+ <xrefdescription>
+ <para>This class is deprecated </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <location file="009_bug.cpp" bodystart="29" bodyend="36"/>
+ <listofallmembers>
+ <member refid="class_deprecated_1a1d5f6803e72c625727e7083d1722dbf9" prot="public" virt="non-virtual">
+ <scope>Deprecated</scope>
+ <name>deprecated</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/class_reminder.xml b/testing/009/class_reminder.xml
new file mode 100644
index 0000000..2f3c641
--- /dev/null
+++ b/testing/009/class_reminder.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_reminder" kind="class" prot="public">
+ <compoundname>Reminder</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_reminder_1a173b5218bb11287b0e86a550d9f0728d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Reminder::reminder</definition>
+ <argsstring>()</argsstring>
+ <name>reminder</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="reminders_1_reminders000002">
+ <xreftitle>Reminder</xreftitle>
+ <xrefdescription>
+ <para>Need to rework this before the next release. </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="009_bug.cpp" line="59" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="reminders_1_reminders000001">
+ <xreftitle>Reminder</xreftitle>
+ <xrefdescription>
+ <para>A reminder </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <location file="009_bug.cpp" bodystart="55" bodyend="60"/>
+ <listofallmembers>
+ <member refid="class_reminder_1a173b5218bb11287b0e86a550d9f0728d" prot="public" virt="non-virtual">
+ <scope>Reminder</scope>
+ <name>reminder</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/class_test.xml b/testing/009/class_test.xml
new file mode 100644
index 0000000..505617f
--- /dev/null
+++ b/testing/009/class_test.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1a9fc54b716f326514a4c5f434137f4fc0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::test</definition>
+ <argsstring>()</argsstring>
+ <name>test</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="test_1_test000002">
+ <xreftitle>Test</xreftitle>
+ <xrefdescription>
+ <para>more things to test. </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="009_bug.cpp" line="51" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="test_1_test000001">
+ <xreftitle>Test</xreftitle>
+ <xrefdescription>
+ <para>This is part of testing </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <location file="009_bug.cpp" bodystart="47" bodyend="52"/>
+ <listofallmembers>
+ <member refid="class_test_1a9fc54b716f326514a4c5f434137f4fc0" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>test</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/class_todo.xml b/testing/009/class_todo.xml
new file mode 100644
index 0000000..0ac555f
--- /dev/null
+++ b/testing/009/class_todo.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_todo" kind="class" prot="public">
+ <compoundname>Todo</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_todo_1a9e70ec9176ac4c1b20e011b4daddc9d8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Todo::todo</definition>
+ <argsstring>()</argsstring>
+ <name>todo</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="todo_1_todo000002">
+ <xreftitle>Todo</xreftitle>
+ <xrefdescription>
+ <para>more things to do here </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="009_bug.cpp" line="43" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <xrefsect id="todo_1_todo000001">
+ <xreftitle>Todo</xreftitle>
+ <xrefdescription>
+ <para>This still needs to be done. </para>
+ </xrefdescription>
+ </xrefsect>
+ </para>
+ </detaileddescription>
+ <location file="009_bug.cpp" bodystart="39" bodyend="44"/>
+ <listofallmembers>
+ <member refid="class_todo_1a9e70ec9176ac4c1b20e011b4daddc9d8" prot="public" virt="non-virtual">
+ <scope>Todo</scope>
+ <name>todo</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/deprecated.xml b/testing/009/deprecated.xml
new file mode 100644
index 0000000..0613b25
--- /dev/null
+++ b/testing/009/deprecated.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="deprecated" kind="page">
+ <compoundname>deprecated</compoundname>
+ <title>Deprecated List</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="deprecated_1_deprecated000001"/>Class <ref refid="class_deprecated" kindref="compound">Deprecated</ref></term>
+ </varlistentry>
+ <listitem>
+ <para>This class is deprecated </para>
+ </listitem>
+ <varlistentry>
+ <term><anchor id="deprecated_1_deprecated000002"/>Member <ref refid="class_deprecated_1a1d5f6803e72c625727e7083d1722dbf9" kindref="member">Deprecated::deprecated</ref> ()</term>
+ </varlistentry>
+ <listitem>
+ <para>No not use this function anymore. </para>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/reminders.xml b/testing/009/reminders.xml
new file mode 100644
index 0000000..e9983ed
--- /dev/null
+++ b/testing/009/reminders.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="reminders" kind="page">
+ <compoundname>reminders</compoundname>
+ <title>Reminders</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="reminders_1_reminders000001"/>Class <ref refid="class_reminder" kindref="compound">Reminder</ref></term>
+ </varlistentry>
+ <listitem>
+ <para>A reminder </para>
+ </listitem>
+ <varlistentry>
+ <term><anchor id="reminders_1_reminders000002"/>Member <ref refid="class_reminder_1a173b5218bb11287b0e86a550d9f0728d" kindref="member">Reminder::reminder</ref> ()</term>
+ </varlistentry>
+ <listitem>
+ <para>Need to rework this before the next release. </para>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/test.xml b/testing/009/test.xml
new file mode 100644
index 0000000..14395bf
--- /dev/null
+++ b/testing/009/test.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="test" kind="page">
+ <compoundname>test</compoundname>
+ <title>Test List</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="test_1_test000001"/>Class <ref refid="class_test" kindref="compound">Test</ref></term>
+ </varlistentry>
+ <listitem>
+ <para>This is part of testing </para>
+ </listitem>
+ <varlistentry>
+ <term><anchor id="test_1_test000002"/>Member <ref refid="class_test_1a9fc54b716f326514a4c5f434137f4fc0" kindref="member">Test::test</ref> ()</term>
+ </varlistentry>
+ <listitem>
+ <para>more things to test. </para>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/009/todo.xml b/testing/009/todo.xml
new file mode 100644
index 0000000..4b731e3
--- /dev/null
+++ b/testing/009/todo.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="todo" kind="page">
+ <compoundname>todo</compoundname>
+ <title>Todo List</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="todo_1_todo000001"/>Class <ref refid="class_todo" kindref="compound">Todo</ref></term>
+ </varlistentry>
+ <listitem>
+ <para>This still needs to be done. </para>
+ </listitem>
+ <varlistentry>
+ <term><anchor id="todo_1_todo000002"/>Member <ref refid="class_todo_1a9e70ec9176ac4c1b20e011b4daddc9d8" kindref="member">Todo::todo</ref> ()</term>
+ </varlistentry>
+ <listitem>
+ <para>more things to do here </para>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/009_bug.cpp b/testing/009_bug.cpp
new file mode 100644
index 0000000..285c77e
--- /dev/null
+++ b/testing/009_bug.cpp
@@ -0,0 +1,62 @@
+// objective: test the \bug, \deprecated, \todo, \test, and \xrefitem commands
+// check: class_bug.xml
+// check: class_deprecated.xml
+// check: class_todo.xml
+// check: class_test.xml
+// check: class_reminder.xml
+// check: bug.xml
+// check: deprecated.xml
+// check: todo.xml
+// check: test.xml
+// check: reminders.xml
+// config: ALIASES = "reminder=\xrefitem reminders \"Reminder\" \"Reminders\""
+
+/** \bug Class bug. */
+class Bug
+{
+ public:
+ /** Description
+ * \bug Function bug
+ * - list item 1 in bug
+ * - list item 2 in bug
+ *
+ * More text.
+ */
+ void foo();
+};
+
+/** \deprecated This class is deprecated */
+class Deprecated
+{
+ public:
+ /** Do deprecated things.
+ * \deprecated No not use this function anymore.
+ */
+ void deprecated();
+};
+
+/** \todo This still needs to be done. */
+class Todo
+{
+ public:
+ /** \todo more things to do here */
+ void todo();
+};
+
+/** \test This is part of testing */
+class Test
+{
+ public:
+ /** \test more things to test. */
+ void test();
+};
+
+/** \reminder A reminder */
+class Reminder
+{
+ public:
+ /** \reminder Need to rework this before the next release. */
+ void reminder();
+};
+
+
diff --git a/testing/010/indexpage.xml b/testing/010/indexpage.xml
new file mode 100644
index 0000000..61f515c
--- /dev/null
+++ b/testing/010/indexpage.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Text <computeroutput>code</computeroutput> normal text.</para>
+ <para>Text <computeroutput>code</computeroutput> normal text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/010_c.dox b/testing/010_c.dox
new file mode 100644
index 0000000..a26b5fd
--- /dev/null
+++ b/testing/010_c.dox
@@ -0,0 +1,7 @@
+// objective: test the \c and \p commands
+// check: indexpage.xml
+/** \mainpage
+ * Text \c code normal text.
+ *
+ * Text \p code normal text.
+ */
diff --git a/testing/011/category_integer_07_arithmetic_08.xml b/testing/011/category_integer_07_arithmetic_08.xml
new file mode 100644
index 0000000..9d64d98
--- /dev/null
+++ b/testing/011/category_integer_07_arithmetic_08.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="category_integer_07_arithmetic_08" kind="category" prot="public">
+ <compoundname>Integer(Arithmetic)</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="category_integer_07_arithmetic_08_1a12f411c5872ba3bafb8ea7dd1826cf2a" prot="public" static="no" const="no" explicit="no" inline="no" virt="virtual">
+ <type>id</type>
+ <definition>id Integer(Arithmetic)::add:</definition>
+ <argsstring>(Integer *addend)</argsstring>
+ <name>add:</name>
+ <param>
+ <type><ref refid="interface_integer" kindref="compound">Integer</ref> *</type>
+ <declname>addend</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>add operation </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="011_category.m" line="8" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="category_integer_07_arithmetic_08_1ae4ff0b0c62b6809e8f5bcee9baa6e521" prot="public" static="no" const="no" explicit="no" inline="no" virt="virtual">
+ <type>id</type>
+ <definition>id Integer(Arithmetic)::sub:</definition>
+ <argsstring>(Integer *subtrahend)</argsstring>
+ <name>sub:</name>
+ <param>
+ <type><ref refid="interface_integer" kindref="compound">Integer</ref> *</type>
+ <declname>subtrahend</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>substract operation </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="011_category.m" line="8" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A category </para>
+ </detaileddescription>
+ <location file="011_category.m" bodystart="17" bodyend="-1"/>
+ <listofallmembers>
+ <member refid="category_integer_07_arithmetic_08_1a12f411c5872ba3bafb8ea7dd1826cf2a" prot="public" virt="virtual">
+ <scope>Integer(Arithmetic)</scope>
+ <name>add:</name>
+ </member>
+ <member refid="category_integer_07_arithmetic_08_1ae4ff0b0c62b6809e8f5bcee9baa6e521" prot="public" virt="virtual">
+ <scope>Integer(Arithmetic)</scope>
+ <name>sub:</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/011/interface_integer.xml b/testing/011/interface_integer.xml
new file mode 100644
index 0000000..bdbcad2
--- /dev/null
+++ b/testing/011/interface_integer.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="interface_integer" kind="class" prot="public">
+ <compoundname>Integer</compoundname>
+ <basecompoundref prot="public" virt="non-virtual">Object</basecompoundref>
+ <sectiondef kind="protected-attrib">
+ <memberdef kind="variable" id="interface_integer_1a35e89216966d8179a1b77f14b8211fda" prot="protected" static="no" mutable="no">
+ <type>int</type>
+ <definition>int Integer::integer</definition>
+ <argsstring/>
+ <name>integer</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>data member </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="011_category.m" bodystart="8" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="interface_integer_1a7b55035e1b0e8e7d4c8587f54a760819" prot="public" static="no" const="no" explicit="no" inline="no" virt="virtual">
+ <type>int</type>
+ <definition>int Integer::integer</definition>
+ <argsstring>()</argsstring>
+ <name>integer</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>getter </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="011_category.m" line="8" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="interface_integer_1ad2f47761103b2442ff7b3fbfe33ec6c9" prot="public" static="no" const="no" explicit="no" inline="no" virt="virtual">
+ <type>id</type>
+ <definition>id Integer::integer:</definition>
+ <argsstring>(int _integer)</argsstring>
+ <name>integer:</name>
+ <param>
+ <type>int</type>
+ <declname>_integer</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>setter </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="011_category.m" line="8" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>An interface </para>
+ </detaileddescription>
+ <inheritancegraph>
+ <node id="1">
+ <label>Object</label>
+ </node>
+ <node id="0">
+ <label>Integer</label>
+ <link refid="interface_integer"/>
+ <childnode refid="1" relation="public-inheritance">
+ </childnode>
+ </node>
+ </inheritancegraph>
+ <collaborationgraph>
+ <node id="3">
+ <label>Object</label>
+ </node>
+ <node id="2">
+ <label>Integer</label>
+ <link refid="interface_integer"/>
+ <childnode refid="3" relation="public-inheritance">
+ </childnode>
+ </node>
+ </collaborationgraph>
+ <location file="011_category.m" bodystart="6" bodyend="-1"/>
+ <listofallmembers>
+ <member refid="interface_integer_1a35e89216966d8179a1b77f14b8211fda" prot="protected" virt="non-virtual">
+ <scope>Integer</scope>
+ <name>integer</name>
+ </member>
+ <member refid="interface_integer_1a7b55035e1b0e8e7d4c8587f54a760819" prot="public" virt="virtual">
+ <scope>Integer</scope>
+ <name>integer</name>
+ </member>
+ <member refid="interface_integer_1ad2f47761103b2442ff7b3fbfe33ec6c9" prot="public" virt="virtual">
+ <scope>Integer</scope>
+ <name>integer:</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/011_category.m b/testing/011_category.m
new file mode 100644
index 0000000..8cb4d3a
--- /dev/null
+++ b/testing/011_category.m
@@ -0,0 +1,30 @@
+// objective: test the \interface and \category command
+// check: category_integer_07_arithmetic_08.xml
+// check: interface_integer.xml
+# import <objc/Object.h>
+
+ at interface Integer : Object {
+ /** data member */
+ int integer;
+}
+
+/** getter */
+- (int) integer;
+/** setter */
+- (id) integer: (int) _integer;
+ at end
+
+ at interface Integer (Arithmetic)
+/** add operation */
+- (id) add: (Integer *) addend;
+/** substract operation */
+- (id) sub: (Integer *) subtrahend;
+ at end
+
+/** \interface Integer
+ * An interface
+ */
+
+/** \category Integer(Arithmetic)
+ * A category
+ */
diff --git a/testing/012/citelist.xml b/testing/012/citelist.xml
new file mode 100644
index 0000000..6b11c4f
--- /dev/null
+++ b/testing/012/citelist.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="citelist" kind="page">
+ <compoundname>citelist</compoundname>
+ <title>Bibliography</title>
+ <detaileddescription>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><anchor id="_1CITEREF_knuth79"/>[1]</term>
+ </varlistentry>
+ <listitem>
+ <para>Donald<nonbreakablespace/>E. Knuth. <emphasis>Tex and Metafont, New Directions in Typesetting</emphasis>. American Mathematical Society and Digital Press, Stanford, 1979.</para>
+ <para/>
+ </listitem>
+ </variablelist>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/012/indexpage.xml b/testing/012/indexpage.xml
new file mode 100644
index 0000000..926b53b
--- /dev/null
+++ b/testing/012/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>See <ref refid="citelist_1CITEREF_knuth79" kindref="member">[1]</ref> for more info. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/012_cite.dox b/testing/012_cite.dox
new file mode 100644
index 0000000..9bcb2c5
--- /dev/null
+++ b/testing/012_cite.dox
@@ -0,0 +1,7 @@
+// objective: test the \cite command
+// check: indexpage.xml
+// check: citelist.xml
+// config: CITE_BIB_FILES = sample.bib
+/** \mainpage
+ * See \cite knuth79 for more info.
+ */
diff --git a/testing/013/class_t1.xml b/testing/013/class_t1.xml
new file mode 100644
index 0000000..2a9b415
--- /dev/null
+++ b/testing/013/class_t1.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_t1" kind="class" prot="public">
+ <compoundname>T1</compoundname>
+ <includes refid="013__class_8h" local="yes">inc/013_class.h</includes>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A class </para>
+ </detaileddescription>
+ <location file="013_class.h" bodystart="10" bodyend="12"/>
+ <listofallmembers>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/013/class_t2.xml b/testing/013/class_t2.xml
new file mode 100644
index 0000000..9c85ff6
--- /dev/null
+++ b/testing/013/class_t2.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_t2" kind="class" prot="public">
+ <compoundname>T2</compoundname>
+ <includes refid="013__class_8h" local="no">013_class.h</includes>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>class <ref refid="class_t2" kindref="compound">T2</ref> </para>
+ </detaileddescription>
+ <location file="013_class.h" bodystart="14" bodyend="16"/>
+ <listofallmembers>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/013/class_t3.xml b/testing/013/class_t3.xml
new file mode 100644
index 0000000..49e7a16
--- /dev/null
+++ b/testing/013/class_t3.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_t3" kind="class" prot="public">
+ <compoundname>T3</compoundname>
+ <includes refid="013__class_8h" local="no">013_class.h</includes>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>class <ref refid="class_t3" kindref="compound">T3</ref> </para>
+ </detaileddescription>
+ <location file="013_class.h" bodystart="18" bodyend="20"/>
+ <listofallmembers>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/013/class_t4.xml b/testing/013/class_t4.xml
new file mode 100644
index 0000000..d87571d
--- /dev/null
+++ b/testing/013/class_t4.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_t4" kind="class" prot="public">
+ <compoundname>T4</compoundname>
+ <includes refid="013__class_8h" local="yes">inc/013_class.h</includes>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>class <ref refid="class_t4" kindref="compound">T4</ref> </para>
+ </detaileddescription>
+ <location file="013_class.h" bodystart="22" bodyend="24"/>
+ <listofallmembers>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/013_class.h b/testing/013_class.h
new file mode 100644
index 0000000..346250b
--- /dev/null
+++ b/testing/013_class.h
@@ -0,0 +1,37 @@
+// objective: test the \class and \headerfile commands
+// check: class_t1.xml
+// check: class_t2.xml
+// check: class_t3.xml
+// check: class_t4.xml
+
+/** A class
+ * \headerfile 013_class.h "inc/013_class.h"
+ */
+class T1
+{
+};
+
+class T2
+{
+};
+
+class T3
+{
+};
+
+class T4
+{
+};
+
+/** \class T2
+ * \headerfile <>
+ * class T2
+ */
+
+/** \class T3 013_class.h
+ * class T3
+ */
+
+/** \class T4 013_class.h "inc/013_class.h"
+ * class T4
+ */
diff --git a/testing/014/indexpage.xml b/testing/014/indexpage.xml
new file mode 100644
index 0000000..c2fe57a
--- /dev/null
+++ b/testing/014/indexpage.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <programlisting>
+ <codeline lineno="1">
+ <highlight class="comment">#<sp/>comment<sp/>in<sp/>Python</highlight>
+ <highlight class="normal"/>
+ </codeline>
+ <codeline lineno="2">
+ <highlight class="normal"/>
+ <highlight class="keyword">class<sp/></highlight>
+ <highlight class="normal">Python:</highlight>
+ </codeline>
+ <codeline lineno="3">
+ <highlight class="normal">
+ <sp/>
+ <sp/>
+ </highlight>
+ <highlight class="keywordflow">pass</highlight>
+ </codeline>
+ </programlisting>
+ </para>
+ <para>
+ <programlisting>
+ <codeline>
+ <highlight class="comment">//<sp/>comment<sp/>in<sp/>a<sp/>code<sp/>block</highlight>
+ <highlight class="normal"/>
+ </codeline>
+ <codeline>
+ <highlight class="normal"/>
+ <highlight class="keyword">class<sp/></highlight>
+ <highlight class="normal">Cpp<sp/>{};</highlight>
+ </codeline>
+ </programlisting>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/014_code.dox b/testing/014_code.dox
new file mode 100644
index 0000000..871a44c
--- /dev/null
+++ b/testing/014_code.dox
@@ -0,0 +1,14 @@
+// objective: test the \code command
+// check: indexpage.xml
+/** \mainpage
+ * \code{.py}
+ * # comment in Python
+ * class Python:
+ * pass
+ * \endcode
+ *
+ * \code{.cpp}
+ * // comment in a code block
+ * class Cpp {};
+ * \endcode
+ */
diff --git a/testing/015/015__cond_8c.xml b/testing/015/015__cond_8c.xml
new file mode 100644
index 0000000..39baed7
--- /dev/null
+++ b/testing/015/015__cond_8c.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="015__cond_8c" kind="file">
+ <compoundname>015_cond.c</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="015__cond_8c_1a2521dcda743ec66ad8e030113d6e0c63" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void cond_enabled</definition>
+ <argsstring>()</argsstring>
+ <name>cond_enabled</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="015_cond.c" bodystart="20" bodyend="22"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="015_cond.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/015_cond.c b/testing/015_cond.c
new file mode 100644
index 0000000..ab3044c
--- /dev/null
+++ b/testing/015_cond.c
@@ -0,0 +1,30 @@
+// objective: test the \cond command
+// check: 015__cond_8c.xml
+// config: ENABLED_SECTIONS = COND_ENABLED
+
+/** \file
+ * Text \a argument more text.
+ */
+
+/// \cond
+
+/** A function */
+void func();
+
+/** A macro */
+#define MACRO 42
+
+/// \endcond
+
+/// \cond COND_ENABLED
+void cond_enabled()
+{
+}
+/// \endcond
+
+/** \cond COND_DISABLED */
+void cond_disabled()
+{
+}
+/** \endcond */
+
diff --git a/testing/016/016__copydoc_8c.xml b/testing/016/016__copydoc_8c.xml
new file mode 100644
index 0000000..dd1de8f
--- /dev/null
+++ b/testing/016/016__copydoc_8c.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="016__copydoc_8c" kind="file">
+ <compoundname>016_copydoc.c</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="016__copydoc_8c_1af721a79655a3857b98d70fa6ada8a916" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func</definition>
+ <argsstring>(int i)</argsstring>
+ <name>func</name>
+ <param>
+ <type>int</type>
+ <declname>i</declname>
+ </param>
+ <briefdescription>
+ <para>Brief description. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>Detailed description. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="016_copydoc.c" line="11" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="016__copydoc_8c_1a119dbcf2f0bc3ec1fbf77fcd35dec6df" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_brief</definition>
+ <argsstring>()</argsstring>
+ <name>func_brief</name>
+ <briefdescription>
+ <para>Brief description. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="016_copydoc.c" line="14" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="016__copydoc_8c_1a3c1e44de2b412b5218b55e216cebb4ac" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_details</definition>
+ <argsstring>()</argsstring>
+ <name>func_details</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Detailed description. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="016_copydoc.c" line="17" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="016__copydoc_8c_1a2535f29ea009c3d7449264671e15afe9" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_doc</definition>
+ <argsstring>()</argsstring>
+ <name>func_doc</name>
+ <briefdescription>
+ <para>Brief description. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>Detailed description. More text. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="016_copydoc.c" line="22" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Text <emphasis>argument</emphasis> more text. </para>
+ </detaileddescription>
+ <location file="016_copydoc.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/016_copydoc.c b/testing/016_copydoc.c
new file mode 100644
index 0000000..bb8b1bb
--- /dev/null
+++ b/testing/016_copydoc.c
@@ -0,0 +1,23 @@
+// objective: test the \copydoc, \copybrief, \copydetails, and \details commands
+// check: 016__copydoc_8c.xml
+
+/** \file
+ * Text \a argument more text.
+ */
+
+/** \brief Brief description.
+ * \details Detailed description.
+ */
+void func(int i);
+
+/** \copybrief func(int) */
+void func_brief();
+
+/** \copydetails func(int) */
+void func_details();
+
+/** \copydoc func(int)
+ * More text.
+ */
+void func_doc();
+
diff --git a/testing/017/indexpage.xml b/testing/017/indexpage.xml
new file mode 100644
index 0000000..f1bfc5e
--- /dev/null
+++ b/testing/017/indexpage.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <simplesect kind="copyright">
+ <para>Dimitri van Heesch </para>
+ </simplesect>
+ <simplesect kind="date">
+ <para>July 13 2013 </para>
+ </simplesect>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/017_copyright.dox b/testing/017_copyright.dox
new file mode 100644
index 0000000..2351180
--- /dev/null
+++ b/testing/017_copyright.dox
@@ -0,0 +1,6 @@
+// objective: test \copyright and \date commands
+// check: indexpage.xml
+/** \mainpage
+ * \copyright Dimitri van Heesch
+ * \date July 13 2013
+ */
diff --git a/testing/018/018__def_8c.xml b/testing/018/018__def_8c.xml
new file mode 100644
index 0000000..b55a2eb
--- /dev/null
+++ b/testing/018/018__def_8c.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="018__def_8c" kind="file">
+ <compoundname>018_def.c</compoundname>
+ <sectiondef kind="define">
+ <memberdef kind="define" id="018__def_8c_1a824c99cb152a3c2e9111a2cb9c34891e" prot="public" static="no">
+ <name>MACRO</name>
+ <initializer>42</initializer>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A macro definition </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" line="8" column="9"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="enum">
+ <memberdef kind="enum" id="018__def_8c_1aa57b8491d1d8fc1014dd54bcf83b130a" prot="public" static="no">
+ <name>E</name>
+ <enumvalue id="018__def_8c_1aa57b8491d1d8fc1014dd54bcf83b130aab1710e6a49014ba389d57c8753c530f4" prot="public">
+ <name>E1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ </enumvalue>
+ <enumvalue id="018__def_8c_1aa57b8491d1d8fc1014dd54bcf83b130aace9a5783f96994d28bc6ec5c9ece8c80" prot="public">
+ <name>E2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ </enumvalue>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>An enum </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" bodystart="13" bodyend="13"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="typedef">
+ <memberdef kind="typedef" id="018__def_8c_1a1d1cfd8ffb84e947f82999c682b666a7" prot="public" static="no">
+ <type>int</type>
+ <definition>Type</definition>
+ <argsstring/>
+ <name>Type</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A type definition. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" bodystart="12" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="var">
+ <memberdef kind="variable" id="018__def_8c_1a335628f2e9085305224b4f9cc6e95ed5" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>var</definition>
+ <argsstring/>
+ <name>var</name>
+ <initializer>= 10</initializer>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A variable </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" bodystart="9" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="018__def_8c_1aee50dbe7d43d2202b490a6977a325584" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>func</definition>
+ <argsstring>(int)</argsstring>
+ <name>func</name>
+ <param>
+ <type>int</type>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function with one parameter. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" bodystart="10" bodyend="10"/>
+ </memberdef>
+ <memberdef kind="function" id="018__def_8c_1a2652ccbfb85efa2df3c70ba6c4628f8d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>func</definition>
+ <argsstring>(int, const char *)</argsstring>
+ <name>func</name>
+ <param>
+ <type>int</type>
+ </param>
+ <param>
+ <type>const char *</type>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function with two parameters </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="018_def.c" bodystart="11" bodyend="11"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Text <emphasis>argument</emphasis> more text. </para>
+ </detaileddescription>
+ <location file="018_def.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/018_def.c b/testing/018_def.c
new file mode 100644
index 0000000..dadc71c
--- /dev/null
+++ b/testing/018_def.c
@@ -0,0 +1,37 @@
+// objective: test the \def, \var, \fn, and \typedef commands
+// check: 018__def_8c.xml
+
+/** \file
+ * Text \a argument more text.
+ */
+
+#define MACRO 42
+int var = 10;
+void func(int) {}
+void func(int,const char *) {}
+typedef int Type;
+enum E { E1, E2 };
+
+/** \def MACRO
+ * A macro definition
+ */
+
+/** \var var
+ * A variable
+ */
+
+/** \fn func(int)
+ * A function with one parameter.
+ */
+
+/** \fn func(int,const char *)
+ * A function with two parameters
+ */
+
+/** \typedef Type
+ * A type definition.
+ */
+
+/** \enum E
+ * An enum
+ */
diff --git a/testing/019/group__g1.xml b/testing/019/group__g1.xml
new file mode 100644
index 0000000..23d9c31
--- /dev/null
+++ b/testing/019/group__g1.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="group__g1" kind="group">
+ <compoundname>g1</compoundname>
+ <title>First Group</title>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="group__g1_1gae84463e3941387a9da58279761e18d7e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_g1</definition>
+ <argsstring>()</argsstring>
+ <name>func_g1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function in the first group. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="019_defgroup.c" line="13" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Text for first group. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/019/group__g2.xml b/testing/019/group__g2.xml
new file mode 100644
index 0000000..51df509
--- /dev/null
+++ b/testing/019/group__g2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="group__g2" kind="group">
+ <compoundname>g2</compoundname>
+ <title>Second Group</title>
+ <innergroup refid="group__g3">Third Group</innergroup>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="group__g2_1gafd310bbec27993e80a5dbaf6c54d5e0b" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_g2</definition>
+ <argsstring>()</argsstring>
+ <name>func_g2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function in the second group </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="019_defgroup.c" line="23" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Text for second group. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/019/group__g3.xml b/testing/019/group__g3.xml
new file mode 100644
index 0000000..1c2b33b
--- /dev/null
+++ b/testing/019/group__g3.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="group__g3" kind="group">
+ <compoundname>g3</compoundname>
+ <title>Third Group</title>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="group__g3_1ga59de48fb40aec5ee2623cc453fe71643" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_g3</definition>
+ <argsstring>()</argsstring>
+ <name>func_g3</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function in the third group </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="019_defgroup.c" line="36" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="group__g3_1gaf32d23522a5d9c3e7fed3dd5710001f7" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func_g3_add</definition>
+ <argsstring>()</argsstring>
+ <name>func_g3_add</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Another function added to the third group </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="019_defgroup.c" line="45" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Text for third group. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/019_defgroup.c b/testing/019_defgroup.c
new file mode 100644
index 0000000..d42d63e
--- /dev/null
+++ b/testing/019_defgroup.c
@@ -0,0 +1,48 @@
+// objective: test the \defgroup, \addtogroup, and \ingroup command.
+// check: group__g1.xml
+// check: group__g2.xml
+// check: group__g3.xml
+
+/** \defgroup g1 First Group
+ * Text for first group.
+ */
+
+/** A function in the first group.
+ * \ingroup g1
+ */
+void func_g1();
+
+//--------------------------------
+
+/** \defgroup g2 Second Group
+ * Text for second group.
+ */
+/// \{
+
+/** A function in the second group */
+void func_g2();
+
+/// \}
+
+/** \defgroup g3 Third Group
+ * Text for third group.
+ * \ingroup g2
+ * \{
+ */
+
+//--------------------------------
+
+/** A function in the third group */
+void func_g3();
+
+/** \} */
+
+/** \addtogroup g3
+ * \{
+ */
+
+/** Another function added to the third group */
+void func_g3_add();
+
+/** \} */
+
diff --git a/testing/020/indexpage.xml b/testing/020/indexpage.xml
new file mode 100644
index 0000000..87ceb53
--- /dev/null
+++ b/testing/020/indexpage.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Text. <htmlonly>
+HTML
+</htmlonly> <htmlonly>
+HTML with block
+</htmlonly> <rtfonly>
+RTF
+</rtfonly> <manonly>
+Man
+</manonly> <latexonly>
+LaTeX
+</latexonly>
+XML
+ <docbookonly>
+DocBook
+</docbookonly> More text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/020_only.dox b/testing/020_only.dox
new file mode 100644
index 0000000..f8e2ce1
--- /dev/null
+++ b/testing/020_only.dox
@@ -0,0 +1,27 @@
+// objective: test the \*only and \*endonly commands
+// check: indexpage.xml
+/** \mainpage
+ * Text.
+ * \htmlonly
+ * HTML
+ * \endhtmlonly
+ * \htmlonly[block]
+ * HTML with block
+ * \endhtmlonly
+ * \rtfonly
+ * RTF
+ * \endrtfonly
+ * \manonly
+ * Man
+ * \endmanonly
+ * \latexonly
+ * LaTeX
+ * \endlatexonly
+ * \xmlonly
+ * XML
+ * \endxmlonly
+ * \docbookonly
+ * DocBook
+ * \enddocbookonly
+ * More text.
+ */
diff --git a/testing/021/indexpage.xml b/testing/021/indexpage.xml
new file mode 100644
index 0000000..20e1ad2
--- /dev/null
+++ b/testing/021/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para> Our main function starts like this: <programlisting><codeline><highlight class="normal">void<sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline></programlisting> First we create a object <computeroutput>t</computeroutput> of the <ref refid="class_test" kindref="compound">Test</ref> class. <programlisting><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline></programlisting> Then we call the example member f [...]
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/021_dontinclude.cpp b/testing/021_dontinclude.cpp
new file mode 100644
index 0000000..107991a
--- /dev/null
+++ b/testing/021_dontinclude.cpp
@@ -0,0 +1,24 @@
+// objective: test the \dontinclude, \skip, \until, \skipline, \line commands
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+/*! A test class. */
+
+class Test
+{
+ public:
+ /// a member function
+ void example();
+};
+
+/*! \mainpage
+ * \dontinclude example_test.cpp
+ * Our main function starts like this:
+ * \skip main
+ * \until {
+ * First we create a object \c t of the Test class.
+ * \skipline Test
+ * Then we call the example member function
+ * \line example
+ * After that our little test routine ends.
+ * \line }
+ */
diff --git a/testing/022/indexpage.xml b/testing/022/indexpage.xml
new file mode 100644
index 0000000..83ed868
--- /dev/null
+++ b/testing/022/indexpage.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Class relations expressed via an inline dot graph: <dot>
+digraph example {
+ node [shape=record, fontname=Helvetica, fontsize=10];
+ b [ label="class B" URL="\ref B"];
+ c [ label="class C" URL="\ref C"];
+ b -> c [ arrowhead="open", style="dashed" ];
+}
+</dot> </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/022_dot.cpp b/testing/022_dot.cpp
new file mode 100644
index 0000000..2db7c38
--- /dev/null
+++ b/testing/022_dot.cpp
@@ -0,0 +1,22 @@
+// objective: test the \dot and \enddot commands
+// check: indexpage.xml
+// config: HAVE_DOT = YES
+// config: DOTFILE_DIRS = .
+
+/*! class B */
+class B {};
+/*! class C */
+class C {};
+
+/*! \mainpage
+Class relations expressed via an inline dot graph:
+\dot
+digraph example {
+ node [shape=record, fontname=Helvetica, fontsize=10];
+ b [ label="class B" URL="\ref B"];
+ c [ label="class C" URL="\ref C"];
+ b -> c [ arrowhead="open", style="dashed" ];
+}
+\enddot
+*/
+
diff --git a/testing/023/indexpage.xml b/testing/023/indexpage.xml
new file mode 100644
index 0000000..b907db9
--- /dev/null
+++ b/testing/023/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Normal <emphasis>emphasis</emphasis> and more <emphasis>emphasis</emphasis> back to normal. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/023_e.dox b/testing/023_e.dox
new file mode 100644
index 0000000..5f787b7
--- /dev/null
+++ b/testing/023_e.dox
@@ -0,0 +1,5 @@
+// objective: test the \e, \em commands
+// check: indexpage.xml
+/** \mainpage
+ * Normal \e emphasis and more \em emphasis back to normal.
+ */
diff --git a/testing/024/indexpage.xml b/testing/024/indexpage.xml
new file mode 100644
index 0000000..11a385b
--- /dev/null
+++ b/testing/024/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Unconditional (start) Enabled (if). Enabled (else). Unconditional (middle) Enabled (else). Unconditional (end) </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/024_if.dox b/testing/024_if.dox
new file mode 100644
index 0000000..f24be43
--- /dev/null
+++ b/testing/024_if.dox
@@ -0,0 +1,21 @@
+// objective: test the \if, \ifnot, \elsif, \else, and \endif commands
+// check: indexpage.xml
+// config: ENABLED_SECTIONS = GUARD_ENABLED
+/** \mainpage
+ * Unconditional (start)
+ * \if GUARD_ENABLED
+ * Enabled (if).
+ * \if (!GUARD_ENABLED) Disabled (if).\else Enabled (else). \endif
+ * \else
+ * Disabled.
+ * \endif
+ * Unconditional (middle)
+ * \ifnot GUARD_ENABLED
+ * Disabled (ifnot).
+ * \elseif GUARD_DISABLED
+ * Disabled (elseif).
+ * \else
+ * Enabled (else).
+ * \endif
+ * Unconditional (end)
+ */
diff --git a/testing/025/class_test.xml b/testing/025/class_test.xml
new file mode 100644
index 0000000..8d3f076
--- /dev/null
+++ b/testing/025/class_test.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1a47b775f65718978f1ffcd96376f8ecfa" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::example</definition>
+ <argsstring>()</argsstring>
+ <name>example</name>
+ <briefdescription>
+ <para>An example member function. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>More details about this function. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="025_example.cpp" bodystart="20" bodyend="20"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ <para>A <ref refid="class_test" kindref="compound">Test</ref> class. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>More details about this class. </para>
+ </detaileddescription>
+ <location file="025_example.cpp" bodystart="10" bodyend="18"/>
+ <listofallmembers>
+ <member refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>example</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/025/example_test_8cpp-example.xml b/testing/025/example_test_8cpp-example.xml
new file mode 100644
index 0000000..6c0ce90
--- /dev/null
+++ b/testing/025/example_test_8cpp-example.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="example_test_8cpp-example" kind="example">
+ <compoundname>example_test.cpp</compoundname>
+ <detaileddescription>
+ <para>This is an example of how to use the <ref refid="class_test" kindref="compound">Test</ref> class.</para>
+ <para>More details about this example. <programlisting><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="class_test" kindref="compound">Test</ref><sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.<ref refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" kindref="member">e [...]
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/025_example.cpp b/testing/025_example.cpp
new file mode 100644
index 0000000..39736f8
--- /dev/null
+++ b/testing/025_example.cpp
@@ -0,0 +1,26 @@
+// objective: test the \example command
+// check: example_test_8cpp-example.xml
+// check: class_test.xml
+// config: EXAMPLE_PATH = .
+
+/** \brief A Test class.
+ *
+ * More details about this class.
+ */
+class Test
+{
+ public:
+ /** \brief An example member function.
+ *
+ * More details about this function.
+ */
+ void example();
+};
+
+void Test::example() {}
+
+/** \example example_test.cpp
+ * This is an example of how to use the Test class.
+ *
+ * More details about this example.
+ */
diff --git a/testing/026/class_test.xml b/testing/026/class_test.xml
new file mode 100644
index 0000000..f49cc8d
--- /dev/null
+++ b/testing/026/class_test.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <templateparamlist>
+ <param>
+ <type>class T</type>
+ </param>
+ </templateparamlist>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1abf9d5fbdaa4c23d0a513ee9746060779" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>int</type>
+ <definition>int Test< T >::example</definition>
+ <argsstring>(int p1, int p2)</argsstring>
+ <name>example</name>
+ <param>
+ <type>int</type>
+ <declname>p1</declname>
+ </param>
+ <param>
+ <type>int</type>
+ <declname>p2</declname>
+ </param>
+ <exceptions> throw (std::out_of_range)</exceptions>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>An example member function. <parameterlist kind="param"><parameteritem><parameternamelist><parametername>p1</parametername></parameternamelist><parameterdescription><para>First parameter. </para></parameterdescription></parameteritem><parameteritem><parameternamelist><parametername>p2</parametername></parameternamelist><parameterdescription><para>Second parameter. </para></parameterdescription></parameteritem></parameterlist>
+<parameterlist kind="exception"><parameteritem><parameternamelist><parametername>std::out_of_range</parametername></parameternamelist><parameterdescription><para>parameter is out of range. </para></parameterdescription></parameteritem></parameterlist>
+<parameterlist kind="retval"><parameteritem><parameternamelist><parametername>0</parametername></parameternamelist><parameterdescription><para>if p1 and p2 are equal </para></parameterdescription></parameteritem><parameteritem><parameternamelist><parametername>-1</parametername></parameternamelist><parameterdescription><para>if p1 is smaller than p2 </para></parameterdescription></parameteritem><parameteritem><parameternamelist><parametername>1</parametername></parameternamelist><paramet [...]
+</para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="026_exception.cpp" line="19" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A <ref refid="class_test" kindref="compound">Test</ref> class. More details about this class. <parameterlist kind="templateparam"><parameteritem><parameternamelist><parametername>T</parametername></parameternamelist><parameterdescription><para>A template parameter. </para></parameterdescription></parameteritem></parameterlist>
+</para>
+ </detaileddescription>
+ <location file="026_exception.cpp" bodystart="8" bodyend="20"/>
+ <listofallmembers>
+ <member refid="class_test_1abf9d5fbdaa4c23d0a513ee9746060779" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>example</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/026_exception.cpp b/testing/026_exception.cpp
new file mode 100644
index 0000000..cabb128
--- /dev/null
+++ b/testing/026_exception.cpp
@@ -0,0 +1,21 @@
+// objective: test the \exception, \param, and \tparam commands
+// check: class_test.xml
+
+/** A Test class.
+ * More details about this class.
+ * @tparam T A template parameter.
+ */
+template<class T> class Test
+{
+ public:
+ /** An example member function.
+ * \param p1 First parameter.
+ * \param p2 Second parameter.
+ * \exception std::out_of_range parameter is out of range.
+ * \retval 0 if p1 and p2 are equal
+ * \retval -1 if p1 is smaller than p2
+ * \retval 1 if p1 is bigger than p2
+ */
+ int example(int p1,int p2) throw(std::out_of_range);
+};
+
diff --git a/testing/027/struct_car.xml b/testing/027/struct_car.xml
new file mode 100644
index 0000000..0e40922
--- /dev/null
+++ b/testing/027/struct_car.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="struct_car" kind="struct" prot="public">
+ <compoundname>Car</compoundname>
+ <basecompoundref refid="struct_vehicle" prot="public" virt="non-virtual">Vehicle</basecompoundref>
+ <sectiondef kind="protected-attrib">
+ <memberdef kind="variable" id="struct_car_1ab8ff28306286da5a8b14fa9bdccaafaa" prot="protected" static="no" mutable="no">
+ <type>
+ <ref refid="struct_vehicle" kindref="compound">Vehicle</ref>
+ </type>
+ <definition>Vehicle Car::base</definition>
+ <argsstring/>
+ <name>base</name>
+ <briefdescription>
+ <para>Base class. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" bodystart="69" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para><ref refid="struct_car" kindref="compound">Car</ref> class. </para>
+ </detaileddescription>
+ <inheritancegraph>
+ <node id="1">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="2" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="2">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ <node id="0">
+ <label>Car</label>
+ <link refid="struct_car"/>
+ <childnode refid="1" relation="public-inheritance">
+ </childnode>
+ </node>
+ </inheritancegraph>
+ <collaborationgraph>
+ <node id="4">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="5" relation="public-inheritance">
+ </childnode>
+ <childnode refid="5" relation="usage">
+ <edgelabel>base</edgelabel>
+ </childnode>
+ </node>
+ <node id="5">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ <node id="3">
+ <label>Car</label>
+ <link refid="struct_car"/>
+ <childnode refid="4" relation="public-inheritance">
+ </childnode>
+ <childnode refid="4" relation="usage">
+ <edgelabel>base</edgelabel>
+ </childnode>
+ </node>
+ </collaborationgraph>
+ <location file="027_extends.c" bodystart="67" bodyend="70"/>
+ <listofallmembers>
+ <member refid="struct_car_1ab8ff28306286da5a8b14fa9bdccaafaa" prot="protected" virt="non-virtual">
+ <scope>Car</scope>
+ <name>base</name>
+ </member>
+ <member refid="struct_object_1a71225073d06a793b9a6ea9263ed37b12" prot="public" virt="non-virtual">
+ <scope>Car</scope>
+ <name>objRef</name>
+ </member>
+ <member refid="struct_object_1a924ee0cecc906d148022b3f0d6325cfb" prot="public" virt="non-virtual">
+ <scope>Car</scope>
+ <name>objUnref</name>
+ </member>
+ <member refid="struct_vehicle_1a6891d3d28853bc3fdd075596dc6de9f8" prot="public" virt="non-virtual">
+ <scope>Car</scope>
+ <name>vehicleStart</name>
+ </member>
+ <member refid="struct_vehicle_1a4dcbcba43792dcd673a552b14479ab77" prot="public" virt="non-virtual">
+ <scope>Car</scope>
+ <name>vehicleStop</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/027/struct_object.xml b/testing/027/struct_object.xml
new file mode 100644
index 0000000..107548d
--- /dev/null
+++ b/testing/027/struct_object.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="struct_object" kind="struct" prot="public">
+ <compoundname>Object</compoundname>
+ <derivedcompoundref refid="struct_vehicle" prot="public" virt="non-virtual">Vehicle</derivedcompoundref>
+ <sectiondef kind="private-attrib">
+ <memberdef kind="variable" id="struct_object_1a1b6037fba835e83243ababce426ff9af" prot="private" static="no" mutable="no">
+ <type>int</type>
+ <definition>int Object::ref</definition>
+ <argsstring/>
+ <name>ref</name>
+ <briefdescription>
+ <para>Reference count. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" bodystart="21" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="struct_object_1a71225073d06a793b9a6ea9263ed37b12" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type><ref refid="struct_object" kindref="compound">Object</ref> *</type>
+ <definition>static Object * objRef</definition>
+ <argsstring>(Object *obj)</argsstring>
+ <name>objRef</name>
+ <param>
+ <type><ref refid="struct_object" kindref="compound">Object</ref> *</type>
+ <declname>obj</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Increments object reference count by one. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" line="29" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="struct_object_1a924ee0cecc906d148022b3f0d6325cfb" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type><ref refid="struct_object" kindref="compound">Object</ref> *</type>
+ <definition>static Object * objUnref</definition>
+ <argsstring>(Object *obj)</argsstring>
+ <name>objUnref</name>
+ <param>
+ <type><ref refid="struct_object" kindref="compound">Object</ref> *</type>
+ <declname>obj</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Decrements object reference count by one. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" line="36" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Base object class. </para>
+ </detaileddescription>
+ <inheritancegraph>
+ <node id="9">
+ <label>Truck</label>
+ <link refid="struct_truck"/>
+ <childnode refid="7" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="7">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="6" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="6">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ <node id="8">
+ <label>Car</label>
+ <link refid="struct_car"/>
+ <childnode refid="7" relation="public-inheritance">
+ </childnode>
+ </node>
+ </inheritancegraph>
+ <location file="027_extends.c" bodystart="19" bodyend="22"/>
+ <listofallmembers>
+ <member refid="struct_object_1a71225073d06a793b9a6ea9263ed37b12" prot="public" virt="non-virtual">
+ <scope>Object</scope>
+ <name>objRef</name>
+ </member>
+ <member refid="struct_object_1a924ee0cecc906d148022b3f0d6325cfb" prot="public" virt="non-virtual">
+ <scope>Object</scope>
+ <name>objUnref</name>
+ </member>
+ <member refid="struct_object_1a1b6037fba835e83243ababce426ff9af" prot="private" virt="non-virtual">
+ <scope>Object</scope>
+ <name>ref</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/027/struct_truck.xml b/testing/027/struct_truck.xml
new file mode 100644
index 0000000..1da9e2f
--- /dev/null
+++ b/testing/027/struct_truck.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="struct_truck" kind="struct" prot="public">
+ <compoundname>Truck</compoundname>
+ <basecompoundref refid="struct_vehicle" prot="public" virt="non-virtual">Vehicle</basecompoundref>
+ <sectiondef kind="protected-attrib">
+ <memberdef kind="variable" id="struct_truck_1ad0ac321609dda1a6c552488b05ec7ac8" prot="protected" static="no" mutable="no">
+ <type>
+ <ref refid="struct_vehicle" kindref="compound">Vehicle</ref>
+ </type>
+ <definition>Vehicle Truck::base</definition>
+ <argsstring/>
+ <name>base</name>
+ <briefdescription>
+ <para>Base class. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" bodystart="79" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para><ref refid="struct_truck" kindref="compound">Truck</ref> class. </para>
+ </detaileddescription>
+ <inheritancegraph>
+ <node id="11">
+ <label>Truck</label>
+ <link refid="struct_truck"/>
+ <childnode refid="12" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="12">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="13" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="13">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ </inheritancegraph>
+ <collaborationgraph>
+ <node id="14">
+ <label>Truck</label>
+ <link refid="struct_truck"/>
+ <childnode refid="15" relation="public-inheritance">
+ </childnode>
+ <childnode refid="15" relation="usage">
+ <edgelabel>base</edgelabel>
+ </childnode>
+ </node>
+ <node id="15">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="16" relation="public-inheritance">
+ </childnode>
+ <childnode refid="16" relation="usage">
+ <edgelabel>base</edgelabel>
+ </childnode>
+ </node>
+ <node id="16">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ </collaborationgraph>
+ <location file="027_extends.c" bodystart="77" bodyend="80"/>
+ <listofallmembers>
+ <member refid="struct_truck_1ad0ac321609dda1a6c552488b05ec7ac8" prot="protected" virt="non-virtual">
+ <scope>Truck</scope>
+ <name>base</name>
+ </member>
+ <member refid="struct_object_1a71225073d06a793b9a6ea9263ed37b12" prot="public" virt="non-virtual">
+ <scope>Truck</scope>
+ <name>objRef</name>
+ </member>
+ <member refid="struct_object_1a924ee0cecc906d148022b3f0d6325cfb" prot="public" virt="non-virtual">
+ <scope>Truck</scope>
+ <name>objUnref</name>
+ </member>
+ <member refid="struct_vehicle_1a6891d3d28853bc3fdd075596dc6de9f8" prot="public" virt="non-virtual">
+ <scope>Truck</scope>
+ <name>vehicleStart</name>
+ </member>
+ <member refid="struct_vehicle_1a4dcbcba43792dcd673a552b14479ab77" prot="public" virt="non-virtual">
+ <scope>Truck</scope>
+ <name>vehicleStop</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/027/struct_vehicle.xml b/testing/027/struct_vehicle.xml
new file mode 100644
index 0000000..a1f7654
--- /dev/null
+++ b/testing/027/struct_vehicle.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="struct_vehicle" kind="struct" prot="public">
+ <compoundname>Vehicle</compoundname>
+ <basecompoundref refid="struct_object" prot="public" virt="non-virtual">Object</basecompoundref>
+ <derivedcompoundref refid="struct_car" prot="public" virt="non-virtual">Car</derivedcompoundref>
+ <derivedcompoundref refid="struct_truck" prot="public" virt="non-virtual">Truck</derivedcompoundref>
+ <sectiondef kind="protected-attrib">
+ <memberdef kind="variable" id="struct_vehicle_1ad7970f528d429f6fc1725173e93a77c2" prot="protected" static="no" mutable="no">
+ <type>
+ <ref refid="struct_object" kindref="compound">Object</ref>
+ </type>
+ <definition>Object Vehicle::base</definition>
+ <argsstring/>
+ <name>base</name>
+ <briefdescription>
+ <para>Base class. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" bodystart="45" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="struct_vehicle_1a6891d3d28853bc3fdd075596dc6de9f8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void vehicleStart</definition>
+ <argsstring>(Vehicle *obj)</argsstring>
+ <name>vehicleStart</name>
+ <param>
+ <type><ref refid="struct_vehicle" kindref="compound">Vehicle</ref> *</type>
+ <declname>obj</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Starts the vehicle. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" line="53" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="struct_vehicle_1a4dcbcba43792dcd673a552b14479ab77" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void vehicleStop</definition>
+ <argsstring>(Vehicle *obj)</argsstring>
+ <name>vehicleStop</name>
+ <param>
+ <type><ref refid="struct_vehicle" kindref="compound">Vehicle</ref> *</type>
+ <declname>obj</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Stops the vehicle. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="027_extends.c" line="60" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para><ref refid="struct_vehicle" kindref="compound">Vehicle</ref> class. </para>
+ </detaileddescription>
+ <inheritancegraph>
+ <node id="20">
+ <label>Truck</label>
+ <link refid="struct_truck"/>
+ <childnode refid="17" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="17">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="18" relation="public-inheritance">
+ </childnode>
+ </node>
+ <node id="18">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ <node id="19">
+ <label>Car</label>
+ <link refid="struct_car"/>
+ <childnode refid="17" relation="public-inheritance">
+ </childnode>
+ </node>
+ </inheritancegraph>
+ <collaborationgraph>
+ <node id="21">
+ <label>Vehicle</label>
+ <link refid="struct_vehicle"/>
+ <childnode refid="22" relation="public-inheritance">
+ </childnode>
+ <childnode refid="22" relation="usage">
+ <edgelabel>base</edgelabel>
+ </childnode>
+ </node>
+ <node id="22">
+ <label>Object</label>
+ <link refid="struct_object"/>
+ </node>
+ </collaborationgraph>
+ <location file="027_extends.c" bodystart="43" bodyend="46"/>
+ <listofallmembers>
+ <member refid="struct_vehicle_1ad7970f528d429f6fc1725173e93a77c2" prot="protected" virt="non-virtual">
+ <scope>Vehicle</scope>
+ <name>base</name>
+ </member>
+ <member refid="struct_object_1a71225073d06a793b9a6ea9263ed37b12" prot="public" virt="non-virtual">
+ <scope>Vehicle</scope>
+ <name>objRef</name>
+ </member>
+ <member refid="struct_object_1a924ee0cecc906d148022b3f0d6325cfb" prot="public" virt="non-virtual">
+ <scope>Vehicle</scope>
+ <name>objUnref</name>
+ </member>
+ <member refid="struct_vehicle_1a6891d3d28853bc3fdd075596dc6de9f8" prot="public" virt="non-virtual">
+ <scope>Vehicle</scope>
+ <name>vehicleStart</name>
+ </member>
+ <member refid="struct_vehicle_1a4dcbcba43792dcd673a552b14479ab77" prot="public" virt="non-virtual">
+ <scope>Vehicle</scope>
+ <name>vehicleStop</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/027_extends.c b/testing/027_extends.c
new file mode 100644
index 0000000..7860abd
--- /dev/null
+++ b/testing/027_extends.c
@@ -0,0 +1,93 @@
+// objective: test the \extends, \implements, \memberof, \private, and \public commands
+// check: struct_object.xml
+// check: struct_vehicle.xml
+// check: struct_car.xml
+// check: struct_truck.xml
+
+/**
+ * \file
+ */
+
+typedef struct Object Object; //!< Object type
+typedef struct Vehicle Vehicle; //!< Vehicle type
+typedef struct Car Car; //!< Car type
+typedef struct Truck Truck; //!< Truck type
+
+/*!
+ * Base object class.
+ */
+struct Object
+{
+ int ref; //!< \private Reference count.
+};
+
+
+/*!
+ * Increments object reference count by one.
+ * \public \memberof Object
+ */
+static Object * objRef(Object *obj);
+
+
+/*!
+ * Decrements object reference count by one.
+ * \public \memberof Object
+ */
+static Object * objUnref(Object *obj);
+
+
+/*!
+ * Vehicle class.
+ * \extends Object
+ */
+struct Vehicle
+{
+ Object base; //!< \protected Base class.
+};
+
+
+/*!
+ * Starts the vehicle.
+ * \public \memberof Vehicle
+ */
+void vehicleStart(Vehicle *obj);
+
+
+/*!
+ * Stops the vehicle.
+ * \public \memberof Vehicle
+ */
+void vehicleStop(Vehicle *obj);
+
+
+/*!
+ * Car class.
+ * \implements Vehicle
+ */
+struct Car
+{
+ Vehicle base; //!< \protected Base class.
+};
+
+
+/*!
+ * Truck class.
+ * \implements Vehicle
+ */
+struct Truck
+{
+ Vehicle base; //!< \protected Base class.
+};
+
+
+/*!
+ * Main function.
+ *
+ * Ref vehicleStart(), objRef(), objUnref().
+ */
+int main(void)
+{
+ Car c;
+ vehicleStart((Vehicle*) &c);
+}
+
diff --git a/testing/028/indexpage.xml b/testing/028/indexpage.xml
new file mode 100644
index 0000000..d508adb
--- /dev/null
+++ b/testing/028/indexpage.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Here are some formulas:<orderedlist><listitem><para>The distance between <formula id="0">$(x_1,y_1)$</formula> and <formula id="1">$(x_2,y_2)$</formula> is <formula id="2">$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}$</formula>.</para></listitem><listitem><para>Unnumbered formula: <formula id="3">\[ |I_2|=\left| \int_{0}^T \psi(t) \left\{ u(a,t)- \int_{\gamma(t)}^a \frac{d\theta}{k(\theta,t)} \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi \right\} dt \right| \]</formula></para></listitem><listite [...]
+</para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/028_formula.c b/testing/028_formula.c
new file mode 100644
index 0000000..2a4c5cb
--- /dev/null
+++ b/testing/028_formula.c
@@ -0,0 +1,17 @@
+// objective: test the \f$, \f[, \f], \f{, and \f} commands
+// check: indexpage.xml
+
+/** @mainpage
+Here are some formulas:
+-# The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is
+ \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$.
+-# Unnumbered formula:
+ \f[ |I_2|=\left| \int_{0}^T \psi(t) \left\{ u(a,t)- \int_{\gamma(t)}^a
+ \frac{d\theta}{k(\theta,t)} \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi \right\} dt \right| \f]
+-# Formula in different environment
+ \f{eqnarray*}{ g &=& \frac{Gm_2}{r^2} \\
+ &=& \frac{(6.673 \times 10^{-11}\,\mbox{m}^3\,\mbox{kg}^{-1}\,
+ \mbox{s}^{-2})(5.9736 \times 10^{24}\,\mbox{kg})}{(6371.01\,\mbox{km})^2} \\
+ &=& 9.82066032\,\mbox{m/s}^2
+ \f}
+*/
diff --git a/testing/029/029__hideinit_8c.xml b/testing/029/029__hideinit_8c.xml
new file mode 100644
index 0000000..4bf1516
--- /dev/null
+++ b/testing/029/029__hideinit_8c.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="029__hideinit_8c" kind="file">
+ <compoundname>029_hideinit.c</compoundname>
+ <sectiondef kind="var">
+ <memberdef kind="variable" id="029__hideinit_8c_1a799f44203647e4c53bdb0386aa95680f" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int var1</definition>
+ <argsstring/>
+ <name>var1</name>
+ <initializer>= 10</initializer>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>a variable with initializer visible </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="029_hideinit.c" bodystart="7" bodyend="-1"/>
+ </memberdef>
+ <memberdef kind="variable" id="029__hideinit_8c_1ac0da06d47d79ad4b9fb1c0eaf1118c3f" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int var2</definition>
+ <argsstring/>
+ <name>var2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>a variable without initializer visible </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="029_hideinit.c" bodystart="12" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="029_hideinit.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/029_hideinit.c b/testing/029_hideinit.c
new file mode 100644
index 0000000..da3f4a5
--- /dev/null
+++ b/testing/029_hideinit.c
@@ -0,0 +1,12 @@
+// objective: test the \hideinitializer command
+// check: 029__hideinit_8c.xml
+
+/** \file */
+
+/** a variable with initializer visible */
+int var1 = 10;
+
+/** a variable without initializer visible
+ * \hideinitializer
+ */
+int var2 = 20;
diff --git a/testing/030/indexpage.xml b/testing/030/indexpage.xml
new file mode 100644
index 0000000..62046d4
--- /dev/null
+++ b/testing/030/indexpage.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text. <htmlonly><h1>Hello world</h1>
+</htmlonly> More text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/030_htmlinclude.dox b/testing/030_htmlinclude.dox
new file mode 100644
index 0000000..a3716e6
--- /dev/null
+++ b/testing/030_htmlinclude.dox
@@ -0,0 +1,8 @@
+// objective: test the \htmlinclude command
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+/** \mainpage
+ * Some text.
+ * \htmlinclude sample.html
+ * More text.
+ */
diff --git a/testing/031/indexpage.xml b/testing/031/indexpage.xml
new file mode 100644
index 0000000..a0297fa
--- /dev/null
+++ b/testing/031/indexpage.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text. <image type="html" name="sample.png"/>
+ <image type="latex" name="sample.png" width="5cm">Doxygen logo</image>
+ More text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/031_image.dox b/testing/031_image.dox
new file mode 100644
index 0000000..96ba43b
--- /dev/null
+++ b/testing/031_image.dox
@@ -0,0 +1,9 @@
+// objective: test the \image command
+// check: indexpage.xml
+// config: IMAGE_PATH = .
+/** \mainpage
+ * Some text.
+ * \image html sample.png
+ * \image latex sample.png "Doxygen logo" width=5cm
+ * More text.
+ */
diff --git a/testing/032/indexpage.xml b/testing/032/indexpage.xml
new file mode 100644
index 0000000..ba401c8
--- /dev/null
+++ b/testing/032/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text. <programlisting><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></progr [...]
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/032_include.cpp b/testing/032_include.cpp
new file mode 100644
index 0000000..8aae8e9
--- /dev/null
+++ b/testing/032_include.cpp
@@ -0,0 +1,11 @@
+// objective: test the \include and \includelineno commands
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+
+/** \mainpage
+ * Some text.
+ * \include example_test.cpp
+ * More text.
+ * \includelineno example_test.cpp
+ * End.
+ */
diff --git a/testing/033/indexpage.xml b/testing/033/indexpage.xml
new file mode 100644
index 0000000..4b2f47d
--- /dev/null
+++ b/testing/033/indexpage.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text.</para>
+ <para>More visible text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/033_internal.dox b/testing/033_internal.dox
new file mode 100644
index 0000000..6e28f22
--- /dev/null
+++ b/testing/033_internal.dox
@@ -0,0 +1,12 @@
+// objective: test the \internal and \endinternal commands (1)
+// check: indexpage.xml
+
+/** \mainpage
+ * Some text.
+ * \internal
+ * Internal text.
+ * \endinternal
+ * More visible text.
+ * \internal
+ * More internal text.
+ */
diff --git a/testing/034/indexpage.xml b/testing/034/indexpage.xml
new file mode 100644
index 0000000..e994666
--- /dev/null
+++ b/testing/034/indexpage.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text. </para>
+ <internal>
+ <para>Internal text. </para>
+ </internal>
+ <sect1 id="index_1s1">
+ <title>A Section</title>
+ <para>Some text in the section 1. </para>
+ <internal>
+ <para>Internal text. </para>
+ <sect2 id="index_1ss1">
+ <title>A Subsection</title>
+ <para>Some text in the subsection. </para>
+ </sect2>
+ </internal>
+ <para>Visible text in section 1. </para>
+ </sect1>
+ <sect1 id="index_1s2">
+ <title>Another Section</title>
+ <para>Visible text. </para>
+ </sect1>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/034_internal.dox b/testing/034_internal.dox
new file mode 100644
index 0000000..01587a9
--- /dev/null
+++ b/testing/034_internal.dox
@@ -0,0 +1,21 @@
+// objective: test the \internal and \endinternal commands (2)
+// check: indexpage.xml
+// config: INTERNAL_DOCS = YES
+
+/** \mainpage
+ * Some text.
+ * \internal
+ * Internal text.
+ * \endinternal
+ * \section s1 A Section
+ * Some text in the section 1.
+ * \internal
+ * Internal text.
+ * \subsection ss1 A Subsection
+ * Some text in the subsection.
+ * \endinternal
+ * Visible text in section 1.
+ * \section s2 Another Section
+ * Visible text.
+ */
+
diff --git a/testing/035/035__invariant_8c.xml b/testing/035/035__invariant_8c.xml
new file mode 100644
index 0000000..d036388
--- /dev/null
+++ b/testing/035/035__invariant_8c.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="035__invariant_8c" kind="file">
+ <compoundname>035_invariant.c</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="035__invariant_8c_1a92e32ddd4278ab907422d5aaa34cb796" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func</definition>
+ <argsstring>(int p, int *q)</argsstring>
+ <name>func</name>
+ <param>
+ <type>int</type>
+ <declname>p</declname>
+ </param>
+ <param>
+ <type>int *</type>
+ <declname>q</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>
+ <simplesect kind="invariant">
+ <para>i+j=p </para>
+ </simplesect>
+ <simplesect kind="pre">
+ <para>p>=0 </para>
+ </simplesect>
+ <simplesect kind="post">
+ <para>*q=2^(p+1) </para>
+ </simplesect>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="035_invariant.c" bodystart="10" bodyend="15"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="035_invariant.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/035_invariant.c b/testing/035_invariant.c
new file mode 100644
index 0000000..28c08f8
--- /dev/null
+++ b/testing/035_invariant.c
@@ -0,0 +1,15 @@
+// objective: test \invariant, \pre and \post commands
+// check: 035__invariant_8c.xml
+
+/** \file */
+
+/** \invariant i+j=p
+ * \pre p\>=0
+ * \post *q=2^(p+1)
+ */
+void func(int p,int *q)
+{
+ int j = p, k=1, i;
+ for (i=0; i<=p; i++) j--,k=k*2;
+ *q = k;
+}
diff --git a/testing/036/036__link_8c.xml b/testing/036/036__link_8c.xml
new file mode 100644
index 0000000..4347d4b
--- /dev/null
+++ b/testing/036/036__link_8c.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="036__link_8c" kind="file">
+ <compoundname>036_link.c</compoundname>
+ <innerclass refid="class_test" prot="public">Test</innerclass>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="036__link_8c_1affb6da6cff1b57cdf8efc0123dceac9b" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void func</definition>
+ <argsstring>(int p)</argsstring>
+ <name>func</name>
+ <param>
+ <type>int</type>
+ <declname>p</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="036_link.c" line="11" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>See <ref refid="036__link_8c_1affb6da6cff1b57cdf8efc0123dceac9b" kindref="member">the function</ref> for more info. See the <ref refid="class_test" kindref="compound">test</ref> class. </para>
+ </detaileddescription>
+ <location file="036_link.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/036_link.c b/testing/036_link.c
new file mode 100644
index 0000000..901f660
--- /dev/null
+++ b/testing/036_link.c
@@ -0,0 +1,16 @@
+// objective: test \link command
+// check: 036__link_8c.xml
+
+/** \file
+ * See \link func() the function\endlink for more info.
+ * See the \link Test test\endlink class.
+ */
+
+/** A function
+ */
+void func(int p);
+
+/** A test */
+class Test
+{
+};
diff --git a/testing/037/class_receiver.xml b/testing/037/class_receiver.xml
new file mode 100644
index 0000000..eb37d47
--- /dev/null
+++ b/testing/037/class_receiver.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_receiver" kind="class" prot="public">
+ <compoundname>Receiver</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_receiver_1a162099741e0324e6254c9bc570566e40" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Receiver::Command</definition>
+ <argsstring>(int commandId)</argsstring>
+ <name>Command</name>
+ <param>
+ <type>int</type>
+ <declname>commandId</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Executable a command on the server </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="037_msc.cpp" line="32" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para><ref refid="class_receiver" kindref="compound">Receiver</ref> class. Can be used to receive and execute commands. After execution of a command, the receiver will send an acknowledgement <msc>
+ Receiver,Sender;
+ Receiver<-Sender [label="Command()", URL="\ref Command()"];
+ Receiver->Sender [label="Ack()", URL="\ref Sender::Ack()", ID="1"];
+</msc> </para>
+ </detaileddescription>
+ <location file="037_msc.cpp" bodystart="28" bodyend="33"/>
+ <listofallmembers>
+ <member refid="class_receiver_1a162099741e0324e6254c9bc570566e40" prot="public" virt="non-virtual">
+ <scope>Receiver</scope>
+ <name>Command</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/037/class_sender.xml b/testing/037/class_sender.xml
new file mode 100644
index 0000000..117ed93
--- /dev/null
+++ b/testing/037/class_sender.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_sender" kind="class" prot="public">
+ <compoundname>Sender</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_sender_1a8ad2c6f9baa4e798868fe4a4d45f8fda" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Sender::Ack</definition>
+ <argsstring>(bool ok)</argsstring>
+ <name>Ack</name>
+ <param>
+ <type>bool</type>
+ <declname>ok</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Acknowledgement from server </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="037_msc.cpp" line="17" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para><ref refid="class_sender" kindref="compound">Sender</ref> class. Can be used to send a command to the server. The receiver will acknowledge the command by calling <ref refid="class_sender_1a8ad2c6f9baa4e798868fe4a4d45f8fda" kindref="member">Ack()</ref>. <msc>
+ Sender,Receiver;
+ Sender->Receiver [label="Command()", URL="\ref Receiver::Command()"];
+ Sender<-Receiver [label="Ack()", URL="\ref Ack()", ID="1"];
+</msc> </para>
+ </detaileddescription>
+ <location file="037_msc.cpp" bodystart="13" bodyend="18"/>
+ <listofallmembers>
+ <member refid="class_sender_1a8ad2c6f9baa4e798868fe4a4d45f8fda" prot="public" virt="non-virtual">
+ <scope>Sender</scope>
+ <name>Ack</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/037_msc.cpp b/testing/037_msc.cpp
new file mode 100644
index 0000000..84ffc55
--- /dev/null
+++ b/testing/037_msc.cpp
@@ -0,0 +1,33 @@
+// objective: test the \msc and \endmsc commands
+// check: class_sender.xml
+// check: class_receiver.xml
+
+/** Sender class. Can be used to send a command to the server.
+ * The receiver will acknowledge the command by calling Ack().
+ * \msc
+ * Sender,Receiver;
+ * Sender->Receiver [label="Command()", URL="\ref Receiver::Command()"];
+ * Sender<-Receiver [label="Ack()", URL="\ref Ack()", ID="1"];
+ * \endmsc
+ */
+class Sender
+{
+ public:
+ /** Acknowledgement from server */
+ void Ack(bool ok);
+};
+
+/** Receiver class. Can be used to receive and execute commands.
+ * After execution of a command, the receiver will send an acknowledgement
+ * \msc
+ * Receiver,Sender;
+ * Receiver<-Sender [label="Command()", URL="\ref Command()"];
+ * Receiver->Sender [label="Ack()", URL="\ref Sender::Ack()", ID="1"];
+ * \endmsc
+ */
+class Receiver
+{
+ public:
+ /** Executable a command on the server */
+ void Command(int commandId);
+};
diff --git a/testing/038/indexpage.xml b/testing/038/indexpage.xml
new file mode 100644
index 0000000..3657034
--- /dev/null
+++ b/testing/038/indexpage.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Text<linebreak/>
+New line<linebreak/>
+Another line </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/038_n.dox b/testing/038_n.dox
new file mode 100644
index 0000000..617743c
--- /dev/null
+++ b/testing/038_n.dox
@@ -0,0 +1,7 @@
+// objective: test the \n command
+// check: indexpage.xml
+/** \mainpage
+Text\n
+New line\n
+Another line
+*/
diff --git a/testing/039/class_test.xml b/testing/039/class_test.xml
new file mode 100644
index 0000000..3f38916
--- /dev/null
+++ b/testing/039/class_test.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="user-defined">
+ <header>A group of functions.</header>
+ <memberdef kind="function" id="class_test_1a09d1d148c3624a636b7590f8cf816a55" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::foo</definition>
+ <argsstring>()</argsstring>
+ <name>foo</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>foo function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="039_name.cpp" line="16" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1a78e37a450a276b60a5a2fa4a46c86f2e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::bar</definition>
+ <argsstring>()</argsstring>
+ <name>bar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>bar function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="039_name.cpp" line="18" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1a1a26b34cfe612dacf462b81f74235269" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::ungrouped</definition>
+ <argsstring>()</argsstring>
+ <name>ungrouped</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>ungrouped function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="039_name.cpp" line="23" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ <para>A <ref refid="class_test" kindref="compound">Test</ref> class. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>More details about this class. </para>
+ </detaileddescription>
+ <location file="039_name.cpp" bodystart="8" bodyend="24"/>
+ <listofallmembers>
+ <member refid="class_test_1a78e37a450a276b60a5a2fa4a46c86f2e" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>bar</name>
+ </member>
+ <member refid="class_test_1a09d1d148c3624a636b7590f8cf816a55" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>foo</name>
+ </member>
+ <member refid="class_test_1a1a26b34cfe612dacf462b81f74235269" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>ungrouped</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/039_name.cpp b/testing/039_name.cpp
new file mode 100644
index 0000000..f07b45c
--- /dev/null
+++ b/testing/039_name.cpp
@@ -0,0 +1,25 @@
+// objective: test the \name and \short commands
+// check: class_test.xml
+
+/** \short A Test class.
+ *
+ * More details about this class.
+ */
+class Test
+{
+ public:
+ /** \name A group of functions.
+ * \{
+ */
+
+ /** foo function */
+ void foo();
+ /** bar function */
+ void bar();
+
+ /** \} */
+
+ /** ungrouped function */
+ void ungrouped();
+};
+
diff --git a/testing/040/namespace_n_s.xml b/testing/040/namespace_n_s.xml
new file mode 100644
index 0000000..14ffc26
--- /dev/null
+++ b/testing/040/namespace_n_s.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace_n_s" kind="namespace">
+ <compoundname>NS</compoundname>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A namespace </para>
+ </detaileddescription>
+ <location file="040_namespace.cpp" line="5" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/040_namespace.cpp b/testing/040_namespace.cpp
new file mode 100644
index 0000000..a90f377
--- /dev/null
+++ b/testing/040_namespace.cpp
@@ -0,0 +1,10 @@
+// objective: test the \namespace command
+// check: namespace_n_s.xml
+
+namespace NS
+{
+}
+
+/** @namespace NS
+ * A namespace
+ */
diff --git a/testing/041/class_test.xml b/testing/041/class_test.xml
new file mode 100644
index 0000000..294b67c
--- /dev/null
+++ b/testing/041/class_test.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1a8e7b46ceaf7bd2ab94114b390b3288ca" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::drawRect</definition>
+ <argsstring>(int, int, int, int)</argsstring>
+ <name>drawRect</name>
+ <param>
+ <type>int</type>
+ <defname>x</defname>
+ </param>
+ <param>
+ <type>int</type>
+ <defname>y</defname>
+ </param>
+ <param>
+ <type>int</type>
+ <defname>w</defname>
+ </param>
+ <param>
+ <type>int</type>
+ <defname>h</defname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>This command draws a rectangle with a left upper corner at ( <emphasis>x</emphasis> , <emphasis>y</emphasis> ), width <emphasis>w</emphasis> and height <emphasis>h</emphasis>. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="041_overload.cpp" bodystart="12" bodyend="12"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1ae87a6e26707e684c0d2d07bb3d4a9d7f" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::drawRect</definition>
+ <argsstring>(const Rect &r)</argsstring>
+ <name>drawRect</name>
+ <param>
+ <type>const Rect &</type>
+ <declname>r</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="041_overload.cpp" bodystart="13" bodyend="13"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1a62a76eed05fa84633d1e460aeeaf875d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::drawRect</definition>
+ <argsstring>(const Point &topLeft, const Point &bottomRight)</argsstring>
+ <name>drawRect</name>
+ <param>
+ <type>const Point &</type>
+ <declname>topLeft</declname>
+ </param>
+ <param>
+ <type>const Point &</type>
+ <declname>bottomRight</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.</para>
+ <para>More text. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="041_overload.cpp" bodystart="18" bodyend="18"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ <para>A short description. </para>
+ </briefdescription>
+ <detaileddescription>
+ <para>More text. </para>
+ </detaileddescription>
+ <location file="041_overload.cpp" bodystart="4" bodyend="10"/>
+ <listofallmembers>
+ <member refid="class_test_1a8e7b46ceaf7bd2ab94114b390b3288ca" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>drawRect</name>
+ </member>
+ <member refid="class_test_1ae87a6e26707e684c0d2d07bb3d4a9d7f" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>drawRect</name>
+ </member>
+ <member refid="class_test_1a62a76eed05fa84633d1e460aeeaf875d" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>drawRect</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/041_overload.cpp b/testing/041_overload.cpp
new file mode 100644
index 0000000..e206acf
--- /dev/null
+++ b/testing/041_overload.cpp
@@ -0,0 +1,33 @@
+// objective: test the \overload command
+// check: class_test.xml
+
+class Test
+{
+ public:
+ void drawRect(int,int,int,int);
+ void drawRect(const Rect &r);
+ void drawRect(const Point &topLeft,const Point &bottomRight);
+};
+
+void Test::drawRect(int x,int y,int w,int h) {}
+void Test::drawRect(const Rect &r) {}
+/*! \overload
+ *
+ * More text.
+ */
+void Test::drawRect(const Point &topLeft,const Point &bottomRight) {}
+
+/*! \class Test
+ * \brief A short description.
+ *
+ * More text.
+ */
+
+/*! \fn void Test::drawRect(int x,int y,int w,int h)
+ * This command draws a rectangle with a left upper corner at ( \a x , \a y ),
+ * width \a w and height \a h.
+ */
+
+/*!
+ * \overload void Test::drawRect(const Rect &r)
+ */
diff --git a/testing/042/namespaceorg_1_1doxygen_1_1_test.xml b/testing/042/namespaceorg_1_1doxygen_1_1_test.xml
new file mode 100644
index 0000000..b48c307
--- /dev/null
+++ b/testing/042/namespaceorg_1_1doxygen_1_1_test.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespaceorg_1_1doxygen_1_1_test" kind="namespace">
+ <compoundname>org::doxygen::Test</compoundname>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A test package. </para>
+ </detaileddescription>
+ <location file="042_package.java" line="4" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/042_package.java b/testing/042_package.java
new file mode 100644
index 0000000..f46d55c
--- /dev/null
+++ b/testing/042_package.java
@@ -0,0 +1,8 @@
+// objective: test the \package command
+// check: namespaceorg_1_1doxygen_1_1_test.xml
+
+package org.doxygen.Test;
+
+/** @package org.doxygen.Test
+ * A test package.
+ */
diff --git a/testing/043/another.xml b/testing/043/another.xml
new file mode 100644
index 0000000..f403e8f
--- /dev/null
+++ b/testing/043/another.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="another" kind="page">
+ <compoundname>another</compoundname>
+ <title>Another Page</title>
+ <detaileddescription>
+ <para>Another page's text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/043/mypage.xml b/testing/043/mypage.xml
new file mode 100644
index 0000000..efb09c7
--- /dev/null
+++ b/testing/043/mypage.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="mypage" kind="page">
+ <compoundname>mypage</compoundname>
+ <title>Page Title</title>
+ <innerpage refid="another">Another Page</innerpage>
+ <detaileddescription>
+ <para>Text at page level. See <ref refid="mypage_1mysect" kindref="member">Section Title.</ref> for more. </para>
+ <sect1 id="mypage_1mysect">
+ <title>Section Title.</title>
+ <para>Text at section level. See <ref refid="mypage_1mysubsect" kindref="member">Subsection Title.</ref> for more. </para>
+ <sect2 id="mypage_1mysubsect">
+ <title>Subsection Title.</title>
+ <para>Text at subsection level. see <ref refid="mypage_1mysubsubsect" kindref="member">Subsubsection Title.</ref> for more. </para>
+ <sect3 id="mypage_1mysubsubsect">
+ <title>Subsubsection Title.</title>
+ <para>Text at subsubsection level. <ref refid="mypage_1mypara" kindref="member">Paragraph Title.</ref> for more. </para>
+ <sect4 id="mypage_1mypara">
+ <title>Paragraph Title.</title>
+ <para>Text at paragraph level. <ref refid="mypage_1mysect2" kindref="member">Another Section Title.</ref> for more. </para>
+ </sect4>
+ </sect3>
+ </sect2>
+ </sect1>
+ <sect1 id="mypage_1mysect2">
+ <title>Another Section Title.</title>
+ <para>Text at section level.</para>
+ <para>
+ <ref refid="another" kindref="compound">Another Page</ref>
+ </para>
+ </sect1>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/043_page.dox b/testing/043_page.dox
new file mode 100644
index 0000000..784f58d
--- /dev/null
+++ b/testing/043_page.dox
@@ -0,0 +1,22 @@
+// objective: test \page, \subpage, \*section, \paragraph, and \ref commands
+// check: mypage.xml
+// check: another.xml
+/** \page mypage Page Title
+ * Text at page level. See \ref mysect for more.
+ * \section mysect Section Title.
+ * Text at section level. See \ref mysubsect for more.
+ * \subsection mysubsect Subsection Title.
+ * Text at subsection level. see \ref mysubsubsect for more.
+ * \subsubsection mysubsubsect Subsubsection Title.
+ * Text at subsubsection level. \ref mypara for more.
+ * \paragraph mypara Paragraph Title.
+ * Text at paragraph level. \ref mysect2 for more.
+ * \section mysect2 Another Section Title.
+ * Text at section level.
+ *
+ * \subpage another
+ */
+
+/** \page another Another Page
+ * Another page's text.
+ */
diff --git a/testing/044/struct_s.xml b/testing/044/struct_s.xml
new file mode 100644
index 0000000..9505f8c
--- /dev/null
+++ b/testing/044/struct_s.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="struct_s" kind="struct" prot="public">
+ <compoundname>S</compoundname>
+ <includes refid="044__section_8h" local="no">044_section.h</includes>
+ <sectiondef kind="public-attrib">
+ <memberdef kind="variable" id="struct_s_1aff6062601582dff52ace76d285c2e504" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pub1</definition>
+ <argsstring/>
+ <name>pub1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>public field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="10" bodyend="-1"/>
+ </memberdef>
+ <memberdef kind="variable" id="struct_s_1a413054db7785010db38c16322c8583cc" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pub2</definition>
+ <argsstring/>
+ <name>pub2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>another public field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="12" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="protected-attrib">
+ <memberdef kind="variable" id="struct_s_1ac506df106f05b04ac31b3b6ae1357067" prot="protected" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pro1</definition>
+ <argsstring/>
+ <name>pro1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>protected field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="17" bodyend="-1"/>
+ </memberdef>
+ <memberdef kind="variable" id="struct_s_1a0c535a6122f4ae509a336e3a67f927a4" prot="protected" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pro2</definition>
+ <argsstring/>
+ <name>pro2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>another protected field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="19" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="private-attrib">
+ <memberdef kind="variable" id="struct_s_1ab754fee7e3500035f644d0ac528cbfc3" prot="private" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pri1</definition>
+ <argsstring/>
+ <name>pri1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>private field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="24" bodyend="-1"/>
+ </memberdef>
+ <memberdef kind="variable" id="struct_s_1a4b26822a09bcd6b946702e99280826ff" prot="private" static="no" mutable="no">
+ <type>int</type>
+ <definition>int S::pri2</definition>
+ <argsstring/>
+ <name>pri2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>another private field </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="044_section.h" bodystart="26" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A struct </para>
+ </detaileddescription>
+ <location file="044_section.h" bodystart="5" bodyend="27"/>
+ <listofallmembers>
+ <member refid="struct_s_1ab754fee7e3500035f644d0ac528cbfc3" prot="private" virt="non-virtual">
+ <scope>S</scope>
+ <name>pri1</name>
+ </member>
+ <member refid="struct_s_1a4b26822a09bcd6b946702e99280826ff" prot="private" virt="non-virtual">
+ <scope>S</scope>
+ <name>pri2</name>
+ </member>
+ <member refid="struct_s_1ac506df106f05b04ac31b3b6ae1357067" prot="protected" virt="non-virtual">
+ <scope>S</scope>
+ <name>pro1</name>
+ </member>
+ <member refid="struct_s_1a0c535a6122f4ae509a336e3a67f927a4" prot="protected" virt="non-virtual">
+ <scope>S</scope>
+ <name>pro2</name>
+ </member>
+ <member refid="struct_s_1aff6062601582dff52ace76d285c2e504" prot="public" virt="non-virtual">
+ <scope>S</scope>
+ <name>pub1</name>
+ </member>
+ <member refid="struct_s_1a413054db7785010db38c16322c8583cc" prot="public" virt="non-virtual">
+ <scope>S</scope>
+ <name>pub2</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/044_section.h b/testing/044_section.h
new file mode 100644
index 0000000..ef48051
--- /dev/null
+++ b/testing/044_section.h
@@ -0,0 +1,28 @@
+// objective: test the \(public|protected|private)section commands
+// check: struct_s.xml
+
+/** A struct */
+struct S
+{
+ /** \publicsection */
+
+ /** public field */
+ int pub1;
+ /** another public field */
+ int pub2;
+
+ /** \protectedsection */
+
+ /** protected field */
+ int pro1;
+ /** another protected field */
+ int pro2;
+
+ /** \privatesection */
+
+ /** private field */
+ int pri1;
+ /** another private field */
+ int pri2;
+};
+
diff --git a/testing/045/indexpage.xml b/testing/045/indexpage.xml
new file mode 100644
index 0000000..75de4ab
--- /dev/null
+++ b/testing/045/indexpage.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>
+ <toclist>
+ <tocitem id="index_1item1">First Item</tocitem>
+ <tocitem id="item2_1item2">Second Item</tocitem>
+ <tocitem id="item2_1item3">Third Item</tocitem>
+ </toclist>
+ </para>
+ <para>Some filler text.</para>
+ <sect1 id="index_1item1">
+ <title>First Section</title>
+ <para>Section 1 text. </para>
+ </sect1>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/045_refitem.dox b/testing/045_refitem.dox
new file mode 100644
index 0000000..a6ba13b
--- /dev/null
+++ b/testing/045_refitem.dox
@@ -0,0 +1,20 @@
+// objective: test \refitem, \secreflist, \endsecreflist
+// check: indexpage.xml
+/** \mainpage
+ * \secreflist
+ * \refitem item1 First Item
+ * \refitem item2 Second Item
+ * \refitem item3 Third Item
+ * \endsecreflist
+ *
+ * Some filler text.
+ *
+ * \section item1 First Section
+ * Section 1 text.
+ */
+
+/** \page item2 A page
+ * Some text.
+ * \section item3 Another Section.
+ * Section 2 text.
+ */
diff --git a/testing/046/046__related_8cpp.xml b/testing/046/046__related_8cpp.xml
new file mode 100644
index 0000000..0291e84
--- /dev/null
+++ b/testing/046/046__related_8cpp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="046__related_8cpp" kind="file">
+ <compoundname>046_related.cpp</compoundname>
+ <innerclass refid="class_test" prot="public">Test</innerclass>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="046__related_8cpp_1a1283d836e0611ff772c1b06a31ecbbfe" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void another</definition>
+ <argsstring>()</argsstring>
+ <name>another</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Another function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="046_related.cpp" line="28" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="046_related.cpp"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/046/class_test.xml b/testing/046/class_test.xml
new file mode 100644
index 0000000..3c631ab
--- /dev/null
+++ b/testing/046/class_test.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1a1683da699dc049d74101488d143c8e98" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void Test::method</definition>
+ <argsstring>()</argsstring>
+ <name>method</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A method </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="046_related.cpp" line="14" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <sectiondef kind="related">
+ <memberdef kind="function" id="class_test_1a51a683fa4fcec142ab1574e00a7b6860" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void function</definition>
+ <argsstring>()</argsstring>
+ <name>function</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A function.</para>
+ <para>
+ <simplesect kind="see">
+ <para>
+ <ref refid="class_test_1a1283d836e0611ff772c1b06a31ecbbfe" kindref="member">another()</ref>
+ </para>
+ </simplesect>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="046_related.cpp" line="22" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1a1283d836e0611ff772c1b06a31ecbbfe" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void another</definition>
+ <argsstring>()</argsstring>
+ <name>another</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Another function </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="046_related.cpp" line="28" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>A test class <simplesect kind="see"><para><ref refid="class_test_1a1683da699dc049d74101488d143c8e98" kindref="member">Test::method()</ref></para></simplesect>
+</para>
+ </detaileddescription>
+ <location file="046_related.cpp" bodystart="10" bodyend="15"/>
+ <listofallmembers>
+ <member refid="class_test_1a1283d836e0611ff772c1b06a31ecbbfe" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>another</name>
+ </member>
+ <member refid="class_test_1a51a683fa4fcec142ab1574e00a7b6860" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>function</name>
+ </member>
+ <member refid="class_test_1a1683da699dc049d74101488d143c8e98" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>method</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/046_related.cpp b/testing/046_related.cpp
new file mode 100644
index 0000000..a8deb5a
--- /dev/null
+++ b/testing/046_related.cpp
@@ -0,0 +1,28 @@
+// objective: test the \related, \relatedalso, \see, and \sa commands
+// check: class_test.xml
+// check: 046__related_8cpp.xml
+
+/** @file */
+
+/** A test class
+ * @see Test::method()
+ */
+class Test
+{
+ public:
+ /** A method */
+ void method();
+};
+
+/*!
+ * A function.
+ * \related Test
+ * \sa another()
+ */
+void function();
+
+/*!
+ * Another function
+ * \relatedalso Test
+ */
+void another();
diff --git a/testing/047/047__return_8cpp.xml b/testing/047/047__return_8cpp.xml
new file mode 100644
index 0000000..2ed45d1
--- /dev/null
+++ b/testing/047/047__return_8cpp.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="047__return_8cpp" kind="file">
+ <compoundname>047_return.cpp</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="047__return_8cpp_1aab0ee031d46db05d47213d2625ab6aac" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>int</type>
+ <definition>int func1</definition>
+ <argsstring>()</argsstring>
+ <name>func1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Test function 1. <simplesect kind="return"><para>A integer. </para></simplesect>
+</para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="047_return.cpp" line="9" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="047__return_8cpp_1aa1d4878589351db8276c79f98ed9fb7d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>int</type>
+ <definition>int func2</definition>
+ <argsstring>()</argsstring>
+ <name>func2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Test function 2. <simplesect kind="return"><para>A integer. </para></simplesect>
+</para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="047_return.cpp" line="14" column="1"/>
+ </memberdef>
+ <memberdef kind="function" id="047__return_8cpp_1abee09dd9ed9ce93df5a931d16faac09a" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>int</type>
+ <definition>int func3</definition>
+ <argsstring>()</argsstring>
+ <name>func3</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Test function 3. <simplesect kind="return"><para>A integer. </para></simplesect>
+</para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="047_return.cpp" line="19" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="047_return.cpp"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/047_return.cpp b/testing/047_return.cpp
new file mode 100644
index 0000000..7585986
--- /dev/null
+++ b/testing/047_return.cpp
@@ -0,0 +1,20 @@
+// objective: test the \result, \return, and \returns commands
+// check: 047__return_8cpp.xml
+
+/** \file */
+
+/** Test function 1.
+ * \result A integer.
+ */
+int func1();
+
+/** Test function 2.
+ * \return A integer.
+ */
+int func2();
+
+/** Test function 3.
+ * \returns A integer.
+ */
+int func3();
+
diff --git a/testing/048/048__showinit_8c.xml b/testing/048/048__showinit_8c.xml
new file mode 100644
index 0000000..a44ccb9
--- /dev/null
+++ b/testing/048/048__showinit_8c.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="048__showinit_8c" kind="file">
+ <compoundname>048_showinit.c</compoundname>
+ <sectiondef kind="var">
+ <memberdef kind="variable" id="048__showinit_8c_1a799f44203647e4c53bdb0386aa95680f" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int var1</definition>
+ <argsstring/>
+ <name>var1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>a variable with initializer hidden due to MAX_INITIALIZER_LINES </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="048_showinit.c" bodystart="8" bodyend="-1"/>
+ </memberdef>
+ <memberdef kind="variable" id="048__showinit_8c_1ac0da06d47d79ad4b9fb1c0eaf1118c3f" prot="public" static="no" mutable="no">
+ <type>int</type>
+ <definition>int var2</definition>
+ <argsstring/>
+ <name>var2</name>
+ <initializer>= 20</initializer>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>a variable with initializer visible </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="048_showinit.c" bodystart="13" bodyend="-1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="048_showinit.c"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/048_showinit.c b/testing/048_showinit.c
new file mode 100644
index 0000000..a37865d
--- /dev/null
+++ b/testing/048_showinit.c
@@ -0,0 +1,13 @@
+// objective: test the \showinit command
+// check: 048__showinit_8c.xml
+// config: MAX_INITIALIZER_LINES = 0
+
+/** \file */
+
+/** a variable with initializer hidden due to MAX_INITIALIZER_LINES */
+int var1 = 10;
+
+/** a variable with initializer visible
+ * \showinitializer
+ */
+int var2 = 20;
diff --git a/testing/049/indexpage.xml b/testing/049/indexpage.xml
new file mode 100644
index 0000000..0f3a63b
--- /dev/null
+++ b/testing/049/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>A bubble sort algoritm First get the inputs <programlisting><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i<n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>Array[%d]<sp/>=<sp/>"</highlight><highlight cla [...]
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/049_snippet.cpp b/testing/049_snippet.cpp
new file mode 100644
index 0000000..2749a62
--- /dev/null
+++ b/testing/049_snippet.cpp
@@ -0,0 +1,13 @@
+// objective: test the \snippet command
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+
+/** \mainpage
+ * A bubble sort algoritm
+ * First get the inputs
+ * \snippet snippet_test.cpp input
+ * Then do the bubbling
+ * \snippet snippet_test.cpp bubble
+ * Then write the result
+ * \snippet snippet_test.cpp output
+ */
diff --git a/testing/050/indexpage.xml b/testing/050/indexpage.xml
new file mode 100644
index 0000000..73b6d4f
--- /dev/null
+++ b/testing/050/indexpage.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some normal text. <verbatim>A verbatim section with a /* C comment */ in it
+</verbatim> Showing a file as verbatim <verbatim>@book{knuth79,
+ author = "Donald E. Knuth",
+ title = "Tex and Metafont, New Directions in Typesetting",
+ year = "1979",
+ publisher = "American Mathematical Society and Digital Press",
+ address = "Stanford"
+}
+</verbatim> More text after the verbatim section. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/050_verbatim.dox b/testing/050_verbatim.dox
new file mode 100644
index 0000000..0ff315f
--- /dev/null
+++ b/testing/050_verbatim.dox
@@ -0,0 +1,14 @@
+// objective: test \verbatim and \verbinclude commands
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+/**
+\mainpage
+Some normal text.
+\verbatim
+A verbatim section with a /* C comment */ in it
+\endverbatim
+Showing a file as verbatim
+\verbinclude sample.bib
+More text after the verbatim section.
+
+*/
diff --git a/testing/051/indexpage.xml b/testing/051/indexpage.xml
new file mode 100644
index 0000000..4f13f56
--- /dev/null
+++ b/testing/051/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Dollar $ At @ Backslash \ Amphasand & Less < Greater > Hash # Percent % Quote " Dot . Double colon :: Pipe | </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/051_escape.dox b/testing/051_escape.dox
new file mode 100644
index 0000000..1497ad1
--- /dev/null
+++ b/testing/051_escape.dox
@@ -0,0 +1,18 @@
+// objective: test various characters that should be escaped
+// check: indexpage.xml
+/**
+\mainpage
+Dollar \$
+At \@
+Backslash \\
+Amphasand \&
+Less \<
+Greater \>
+Hash \#
+Percent \%
+Quote \"
+Dot \.
+Double colon \::
+Pipe \|
+
+*/
diff --git a/testing/052/indexpage.xml b/testing/052/indexpage.xml
new file mode 100644
index 0000000..792bee4
--- /dev/null
+++ b/testing/052/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>This is English. Output for all languages. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/052_tilde.dox b/testing/052_tilde.dox
new file mode 100644
index 0000000..81a8c9b
--- /dev/null
+++ b/testing/052_tilde.dox
@@ -0,0 +1,9 @@
+// objective: test \~ command
+// check: indexpage.xml
+/**
+\mainpage
+\~english This is English.
+\~dutch Dit is Nederlands.
+\~german Dies ist Deutsch.
+\~ Output for all languages.
+*/
diff --git a/testing/053/indexpage.xml b/testing/053/indexpage.xml
new file mode 100644
index 0000000..828fe96
--- /dev/null
+++ b/testing/053/indexpage.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Dit is Nederlands. Output for all languages. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/053_tilde.dox b/testing/053_tilde.dox
new file mode 100644
index 0000000..73cafa3
--- /dev/null
+++ b/testing/053_tilde.dox
@@ -0,0 +1,10 @@
+// objective: test \~ command with non default OUTPUT_LANGUAGE
+// check: indexpage.xml
+// config: OUTPUT_LANGUAGE = Dutch
+/**
+\mainpage
+\~english This is English.
+\~dutch Dit is Nederlands.
+\~german Dies ist Deutsch.
+\~ Output for all languages.
+*/
diff --git a/testing/054/054__parblock_8cpp.xml b/testing/054/054__parblock_8cpp.xml
new file mode 100644
index 0000000..a562a6d
--- /dev/null
+++ b/testing/054/054__parblock_8cpp.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="054__parblock_8cpp" kind="file">
+ <compoundname>054_parblock.cpp</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="054__parblock_8cpp_1a2dd0ac47f42a9994b91d34403be05fe9" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void function</definition>
+ <argsstring>(int client, int *resource, int parblock, int *test, int p)</argsstring>
+ <name>function</name>
+ <param>
+ <type>int</type>
+ <declname>client</declname>
+ </param>
+ <param>
+ <type>int *</type>
+ <declname>resource</declname>
+ </param>
+ <param>
+ <type>int</type>
+ <declname>parblock</declname>
+ </param>
+ <param>
+ <type>int *</type>
+ <declname>test</declname>
+ </param>
+ <param>
+ <type>int</type>
+ <declname>p</declname>
+ </param>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>call by target-specific code to manage resources required by the client.</para>
+ <para>
+ <parameterlist kind="param">
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">client</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>ID of client requesting resource. </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="out">resource</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>Requested resource </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">parblock</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>
+ <parblock>
+ <para>This is a test for the @parblock command.</para>
+ <para>A list if values for the parblock param:<itemizedlist><listitem><para>Item 1. This is short one-line description.</para></listitem><listitem><para>Item 2. This is a long bullet item; sometimes they wrap on multiple lines like this one.</para></listitem></itemizedlist>
+</para>
+ <para>This is the second paragraph description for the @parblock parameter. Always end the text inside the @parblock command with an @endparblock command. </para>
+ </parblock>
+ </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="out">test</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>This is a test parameter for this function to see if it is included in the parameter table </para>
+ </parameterdescription>
+ </parameteritem>
+ <parameteritem>
+ <parameternamelist>
+ <parametername direction="in">p</parametername>
+ </parameternamelist>
+ <parameterdescription>
+ <para>
+ <parblock>
+ <para>First paragraph of the param description. <verbatim> Second paragraph of the param description.
+</verbatim> </para>
+ </parblock>
+ </para>
+ </parameterdescription>
+ </parameteritem>
+ </parameterlist>
+ </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="054_parblock.cpp" line="32" column="1"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="054_parblock.cpp"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/054_parblock.cpp b/testing/054_parblock.cpp
new file mode 100644
index 0000000..186feb5
--- /dev/null
+++ b/testing/054_parblock.cpp
@@ -0,0 +1,32 @@
+// objective: test the \parblock command
+// check: 054__parblock_8cpp.xml
+
+/** @file */
+
+/**
+ call by target-specific code to manage resources required by the client.
+
+ @param[in] client ID of client requesting resource.
+ @param[out] resource Requested resource
+ @param[in] parblock @parblock This is a test for the \@parblock
+ command.
+
+ A list if values for the parblock param:
+ - Item 1. This is short one-line description.
+ - Item 2. This is a long bullet item;
+ sometimes they wrap on multiple lines like this
+ one.
+
+ This is the second paragraph description for the
+ \@parblock parameter. Always end the text inside
+ the \@parblock command with an \@endparblock
+ command.
+ @endparblock
+ @param[out] test This is a test parameter for this function to see if
+ it is included in the parameter table
+ @param[in] p @parblock First paragraph of the param description.
+
+ Second paragraph of the param description.
+ @endparblock
+ */
+void function(int client,int *resource,int parblock,int *test,int p);
diff --git a/testing/055/md_055_markdown.xml b/testing/055/md_055_markdown.xml
new file mode 100644
index 0000000..4006db8
--- /dev/null
+++ b/testing/055/md_055_markdown.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="md_055_markdown" kind="page">
+ <compoundname>md_055_markdown</compoundname>
+ <title>055_markdown</title>
+ <detaileddescription>
+ <para>
+ <heading level="1">Foo</heading>
+ </para>
+ <para>
+ <heading level="2">Bar</heading>
+ </para>
+ <para>
+ <ulink url="http://example.com/inline">Inline link</ulink>
+ </para>
+ <para>
+ <ulink url="http://example.com/reference">Reference link</ulink>
+ </para>
+ <para>
+ <heading level="2">Baz</heading>
+ </para>
+ <para>More text</para>
+ <para>
+ <ulink url="http://example.com/last-line">Upper-cased reference link on last line</ulink>
+ </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/055_markdown.md b/testing/055_markdown.md
new file mode 100644
index 0000000..aeb9f1a
--- /dev/null
+++ b/testing/055_markdown.md
@@ -0,0 +1,22 @@
+<!--
+// objective: test markdown parsing
+// check: md_055_markdown.xml
+-->
+
+# Foo
+
+## Bar
+
+[Inline link](http://example.com/inline)
+
+[Reference link][1]
+
+[1]: http://example.com/reference
+
+## Baz
+
+More text
+
+[Upper-cased reference link on last line][U]
+
+[U]: http://example.com/last-line
diff --git a/testing/056/indexpage.xml b/testing/056/indexpage.xml
new file mode 100644
index 0000000..8376a74
--- /dev/null
+++ b/testing/056/indexpage.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <detaileddescription>
+ <para>Some text. <latexonly>\section{Hello world}
+</latexonly> More text. </para>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
diff --git a/testing/056_latexinclude.dox b/testing/056_latexinclude.dox
new file mode 100644
index 0000000..6a8052a
--- /dev/null
+++ b/testing/056_latexinclude.dox
@@ -0,0 +1,8 @@
+// objective: test the \latexinclude command
+// check: indexpage.xml
+// config: EXAMPLE_PATH = .
+/** \mainpage
+ * Some text.
+ * \latexinclude sample.tex
+ * More text.
+ */
diff --git a/testing/057/057__caller__graphs_8tcl.xml b/testing/057/057__caller__graphs_8tcl.xml
new file mode 100644
index 0000000..4c54e1c
--- /dev/null
+++ b/testing/057/057__caller__graphs_8tcl.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="057__caller__graphs_8tcl" kind="file">
+ <compoundname>057_caller_graphs.tcl</compoundname>
+ <innernamespace refid="namespacebar">bar</innernamespace>
+ <innernamespace refid="namespacefoo">foo</innernamespace>
+ <innernamespace refid="namespace1_1_11_1_11">1::1::1</innernamespace>
+ <innernamespace refid="namespace1">1</innernamespace>
+ <innernamespace refid="namespace1_1_11">1::1</innernamespace>
+ <innernamespace refid="namespace2_1_12_1_12_1_12_1_12">2::2::2::2::2</innernamespace>
+ <innernamespace refid="namespace2">2</innernamespace>
+ <innernamespace refid="namespace2_1_12">2::2</innernamespace>
+ <innernamespace refid="namespace2_1_12_1_12">2::2::2</innernamespace>
+ <innernamespace refid="namespace2_1_12_1_12_1_12">2::2::2::2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="057__caller__graphs_8tcl_1a85c692c418fec91930cfc7b3e82857d7" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>baz</definition>
+ <argsstring>args</argsstring>
+ <name>baz</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="59" bodyend="61"/>
+ </memberdef>
+ <memberdef kind="function" id="057__caller__graphs_8tcl_1ae4e1c2bb3adfdfbb71f52de84a8285b0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>bar</definition>
+ <argsstring>args</argsstring>
+ <name>bar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="65" bodyend="67"/>
+ <referencedby refid="namespace1_1a9722420639306872cea2593b83028a45" compoundref="057__caller__graphs_8tcl" startline="85" endline="88">1::test3</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="057__caller__graphs_8tcl_1a3f808a00e1b937978455d707851ab33a" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="102" bodyend="105"/>
+ <references refid="namespace2_1a2839d9dea7f0d08f48958c3fc0cd00d3" compoundref="057__caller__graphs_8tcl" startline="106" endline="114">2::next</references>
+ </memberdef>
+ <memberdef kind="function" id="057__caller__graphs_8tcl_1a12acb916374f925e7b7ba302a1ca4efb" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>master</definition>
+ <argsstring>args</argsstring>
+ <name>master</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="136" bodyend="140"/>
+ <references refid="__057__caller__graphs_8tcl_1a7c3c8acee94bf61ba9e911dafe35adac" compoundref="__057__caller__graphs_8tcl" startline="1" endline="4">inFileB</references>
+ </memberdef>
+ <memberdef kind="function" id="057__caller__graphs_8tcl_1a7482c00c17357cf4846b0c1bd715979c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>inFileA</definition>
+ <argsstring>args</argsstring>
+ <name>inFileA</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="141" bodyend="144"/>
+ <referencedby refid="__057__caller__graphs_8tcl_1a7c3c8acee94bf61ba9e911dafe35adac" compoundref="__057__caller__graphs_8tcl" startline="1" endline="4">inFileB</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_caller_graphs.tcl"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/__057__caller__graphs_8tcl.xml b/testing/057/__057__caller__graphs_8tcl.xml
new file mode 100644
index 0000000..2fdcf6a
--- /dev/null
+++ b/testing/057/__057__caller__graphs_8tcl.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="__057__caller__graphs_8tcl" kind="file">
+ <compoundname>_057_caller_graphs.tcl</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="__057__caller__graphs_8tcl_1a7c3c8acee94bf61ba9e911dafe35adac" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>inFileB</definition>
+ <argsstring>args</argsstring>
+ <name>inFileB</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="_057_caller_graphs.tcl" bodystart="1" bodyend="4"/>
+ <references refid="057__caller__graphs_8tcl_1a7482c00c17357cf4846b0c1bd715979c" compoundref="057__caller__graphs_8tcl" startline="141" endline="144">inFileA</references>
+ <referencedby refid="057__caller__graphs_8tcl_1a12acb916374f925e7b7ba302a1ca4efb" compoundref="057__caller__graphs_8tcl" startline="136" endline="140">master</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="_057_caller_graphs.tcl"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace1.xml b/testing/057/namespace1.xml
new file mode 100644
index 0000000..e74d8fe
--- /dev/null
+++ b/testing/057/namespace1.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace1" kind="namespace">
+ <compoundname>1</compoundname>
+ <innernamespace refid="namespace1_1_11">1::1</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace1_1a5024a7bc323958c7230615f2fcaeaef8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::baz</definition>
+ <argsstring>args</argsstring>
+ <name>baz</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="62" bodyend="64"/>
+ <referencedby refid="namespace1_1a4a8285288ee1994ac886e2039777339e" compoundref="057__caller__graphs_8tcl" startline="77" endline="80">test1</referencedby>
+ <referencedby refid="namespace1_1a11615154d3c207ed4106dd0bcb0639e8" compoundref="057__caller__graphs_8tcl" startline="93" endline="96">test5</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1ad58c8f16ad5f12178c71ca988865bb58" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::bar</definition>
+ <argsstring>args</argsstring>
+ <name>bar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="68" bodyend="70"/>
+ <referencedby refid="namespace1_1ae1e88bb7ddd332348d7e29ac4a211b00" compoundref="057__caller__graphs_8tcl" startline="81" endline="84">test2</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1a4a8285288ee1994ac886e2039777339e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::test1</definition>
+ <argsstring>args</argsstring>
+ <name>test1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="77" bodyend="80"/>
+ <references refid="namespace1_1a5024a7bc323958c7230615f2fcaeaef8" compoundref="057__caller__graphs_8tcl" startline="62" endline="64">baz</references>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1ae1e88bb7ddd332348d7e29ac4a211b00" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::test2</definition>
+ <argsstring>args</argsstring>
+ <name>test2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="81" bodyend="84"/>
+ <references refid="namespace1_1ad58c8f16ad5f12178c71ca988865bb58" compoundref="057__caller__graphs_8tcl" startline="68" endline="70">bar</references>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1a9722420639306872cea2593b83028a45" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::test3</definition>
+ <argsstring>args</argsstring>
+ <name>test3</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="85" bodyend="88"/>
+ <references refid="057__caller__graphs_8tcl_1ae4e1c2bb3adfdfbb71f52de84a8285b0" compoundref="057__caller__graphs_8tcl" startline="65" endline="67">bar</references>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1addc9b30656419de5e2651e27a013db29" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::test4</definition>
+ <argsstring>args</argsstring>
+ <name>test4</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="89" bodyend="92"/>
+ <references refid="namespace1_1_11_1acebecc4cb718010d00c3c150158b75ab" compoundref="057__caller__graphs_8tcl" startline="71" endline="73">1::1::bar</references>
+ </memberdef>
+ <memberdef kind="function" id="namespace1_1a11615154d3c207ed4106dd0bcb0639e8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::test5</definition>
+ <argsstring>args</argsstring>
+ <name>test5</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="93" bodyend="96"/>
+ <references refid="namespace1_1a5024a7bc323958c7230615f2fcaeaef8" compoundref="057__caller__graphs_8tcl" startline="62" endline="64">baz</references>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace1_1_11.xml b/testing/057/namespace1_1_11.xml
new file mode 100644
index 0000000..e5c5596
--- /dev/null
+++ b/testing/057/namespace1_1_11.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace1_1_11" kind="namespace">
+ <compoundname>1::1</compoundname>
+ <innernamespace refid="namespace1_1_11_1_11">1::1::1</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace1_1_11_1acebecc4cb718010d00c3c150158b75ab" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::1::bar</definition>
+ <argsstring>args</argsstring>
+ <name>bar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="71" bodyend="73"/>
+ <referencedby refid="namespace1_1addc9b30656419de5e2651e27a013db29" compoundref="057__caller__graphs_8tcl" startline="89" endline="92">1::test4</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace1_1_11_1_11.xml b/testing/057/namespace1_1_11_1_11.xml
new file mode 100644
index 0000000..caccbe4
--- /dev/null
+++ b/testing/057/namespace1_1_11_1_11.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace1_1_11_1_11" kind="namespace">
+ <compoundname>1::1::1</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace1_1_11_1_11_1aa604df053f7ebe36205d1a5675459b96" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>1::1::1::bar</definition>
+ <argsstring>args</argsstring>
+ <name>bar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="74" bodyend="76"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_caller_graphs.tcl" line="58" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace2.xml b/testing/057/namespace2.xml
new file mode 100644
index 0000000..6ea122c
--- /dev/null
+++ b/testing/057/namespace2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace2" kind="namespace">
+ <compoundname>2</compoundname>
+ <innernamespace refid="namespace2_1_12">2::2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace2_1a2839d9dea7f0d08f48958c3fc0cd00d3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>2::next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="106" bodyend="114"/>
+ <references refid="namespace2_1_12_1aceefa876cf364f44da1f523d3f7b0649" compoundref="057__caller__graphs_8tcl" startline="115" endline="118">2::2::next</references>
+ <referencedby refid="057__caller__graphs_8tcl_1a3f808a00e1b937978455d707851ab33a" compoundref="057__caller__graphs_8tcl" startline="102" endline="105">next</referencedby>
+ <referencedby refid="namespace2_1_12_1_12_1_12_1_12_1ac07f64c62783fd8b44317389b4a711f8" compoundref="057__caller__graphs_8tcl" startline="127" endline="130">2::2::2::2::2::next</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace2_1_12.xml b/testing/057/namespace2_1_12.xml
new file mode 100644
index 0000000..d2a589a
--- /dev/null
+++ b/testing/057/namespace2_1_12.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace2_1_12" kind="namespace">
+ <compoundname>2::2</compoundname>
+ <innernamespace refid="namespace2_1_12_1_12">2::2::2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace2_1_12_1aceefa876cf364f44da1f523d3f7b0649" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>2::2::next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="115" bodyend="118"/>
+ <references refid="namespace2_1_12_1_12_1a85524e2015e377d433cd8384335c11d6" compoundref="057__caller__graphs_8tcl" startline="119" endline="122">2::2::2::next</references>
+ <referencedby refid="namespace2_1a2839d9dea7f0d08f48958c3fc0cd00d3" compoundref="057__caller__graphs_8tcl" startline="106" endline="114">2::next</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace2_1_12_1_12.xml b/testing/057/namespace2_1_12_1_12.xml
new file mode 100644
index 0000000..d04a73c
--- /dev/null
+++ b/testing/057/namespace2_1_12_1_12.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace2_1_12_1_12" kind="namespace">
+ <compoundname>2::2::2</compoundname>
+ <innernamespace refid="namespace2_1_12_1_12_1_12">2::2::2::2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace2_1_12_1_12_1a85524e2015e377d433cd8384335c11d6" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>2::2::2::next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="119" bodyend="122"/>
+ <references refid="namespace2_1_12_1_12_1_12_1a3ea6e2ce66f4a9c30009852e4c7da2fe" compoundref="057__caller__graphs_8tcl" startline="123" endline="126">2::2::2::2::next</references>
+ <referencedby refid="namespace2_1_12_1aceefa876cf364f44da1f523d3f7b0649" compoundref="057__caller__graphs_8tcl" startline="115" endline="118">2::2::next</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace2_1_12_1_12_1_12.xml b/testing/057/namespace2_1_12_1_12_1_12.xml
new file mode 100644
index 0000000..980906d
--- /dev/null
+++ b/testing/057/namespace2_1_12_1_12_1_12.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace2_1_12_1_12_1_12" kind="namespace">
+ <compoundname>2::2::2::2</compoundname>
+ <innernamespace refid="namespace2_1_12_1_12_1_12_1_12">2::2::2::2::2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace2_1_12_1_12_1_12_1a3ea6e2ce66f4a9c30009852e4c7da2fe" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>2::2::2::2::next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="123" bodyend="126"/>
+ <references refid="namespace2_1_12_1_12_1_12_1_12_1ac07f64c62783fd8b44317389b4a711f8" compoundref="057__caller__graphs_8tcl" startline="127" endline="130">2::2::2::2::2::next</references>
+ <referencedby refid="namespace2_1_12_1_12_1a85524e2015e377d433cd8384335c11d6" compoundref="057__caller__graphs_8tcl" startline="119" endline="122">2::2::2::next</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespace2_1_12_1_12_1_12_1_12.xml b/testing/057/namespace2_1_12_1_12_1_12_1_12.xml
new file mode 100644
index 0000000..0c6957b
--- /dev/null
+++ b/testing/057/namespace2_1_12_1_12_1_12_1_12.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespace2_1_12_1_12_1_12_1_12" kind="namespace">
+ <compoundname>2::2::2::2::2</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespace2_1_12_1_12_1_12_1_12_1ac07f64c62783fd8b44317389b4a711f8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>2::2::2::2::2::next</definition>
+ <argsstring>args</argsstring>
+ <name>next</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="127" bodyend="130"/>
+ <references refid="namespace2_1a2839d9dea7f0d08f48958c3fc0cd00d3" compoundref="057__caller__graphs_8tcl" startline="106" endline="114">2::next</references>
+ <referencedby refid="namespace2_1_12_1_12_1_12_1a3ea6e2ce66f4a9c30009852e4c7da2fe" compoundref="057__caller__graphs_8tcl" startline="123" endline="126">2::2::2::2::next</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_caller_graphs.tcl" line="101" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespacebar.xml b/testing/057/namespacebar.xml
new file mode 100644
index 0000000..3c0f6e9
--- /dev/null
+++ b/testing/057/namespacebar.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespacebar" kind="namespace">
+ <compoundname>bar</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespacebar_1aa1678a9adb588c0b91b118de7cc38ddb" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>bar::slave</definition>
+ <argsstring/>
+ <name>slave</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="29" bodyend="35"/>
+ <references refid="namespacebar_1a3426cd3a2eebcffa0dc333bcf5e2fe5e" compoundref="057__caller__graphs_8tcl" startline="36" endline="39">baz</references>
+ <referencedby refid="namespacefoo_1a265acdcaea6da32c3bbd9afb5d0e32a4" compoundref="057__caller__graphs_8tcl" startline="44" endline="48">foo::master</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="namespacebar_1a3426cd3a2eebcffa0dc333bcf5e2fe5e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>bar::baz</definition>
+ <argsstring/>
+ <name>baz</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="36" bodyend="39"/>
+ <references refid="namespacebar_1a88879545dee287d377e638b87cdf6dd7" compoundref="057__caller__graphs_8tcl" startline="40" endline="42">bazbaz</references>
+ <referencedby refid="namespacebar_1aa1678a9adb588c0b91b118de7cc38ddb" compoundref="057__caller__graphs_8tcl" startline="29" endline="35">slave</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="namespacebar_1a88879545dee287d377e638b87cdf6dd7" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>bar::bazbaz</definition>
+ <argsstring/>
+ <name>bazbaz</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="40" bodyend="42"/>
+ <referencedby refid="namespacebar_1a3426cd3a2eebcffa0dc333bcf5e2fe5e" compoundref="057__caller__graphs_8tcl" startline="36" endline="39">baz</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_caller_graphs.tcl" line="28" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespacefoo.xml b/testing/057/namespacefoo.xml
new file mode 100644
index 0000000..2aae8ea
--- /dev/null
+++ b/testing/057/namespacefoo.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespacefoo" kind="namespace">
+ <compoundname>foo</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespacefoo_1a265acdcaea6da32c3bbd9afb5d0e32a4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>foo::master</definition>
+ <argsstring/>
+ <name>master</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_caller_graphs.tcl" bodystart="44" bodyend="48"/>
+ <references refid="namespacebar_1aa1678a9adb588c0b91b118de7cc38ddb" compoundref="057__caller__graphs_8tcl" startline="29" endline="35">bar::slave</references>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_caller_graphs.tcl" line="43" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057_caller_graphs.tcl b/testing/057_caller_graphs.tcl
new file mode 100644
index 0000000..f6e0e77
--- /dev/null
+++ b/testing/057_caller_graphs.tcl
@@ -0,0 +1,155 @@
+#// objective: test for completeness and correctness of references/referencedby relations
+#// check: 057__caller__graphs_8tcl.xml
+#// check: __057__caller__graphs_8tcl.xml
+#// check: namespacebar.xml
+#// check: namespacefoo.xml
+#// check: namespace1.xml
+#// check: namespace1_1_11.xml
+#// check: namespace1_1_11_1_11.xml
+#// check: namespace2.xml
+#// check: namespace2_1_12.xml
+#// check: namespace2_1_12_1_12.xml
+#// check: namespace2_1_12_1_12_1_12.xml
+#// check: namespace2_1_12_1_12_1_12_1_12.xml
+#// config: EXTRACT_ALL = yes
+#// config: INLINE_SOURCES = no
+#// config: REFERENCED_BY_RELATION = yes
+#// config: REFERENCES_RELATION = yes
+#// config: INPUT = 057_caller_graphs.tcl _057_caller_graphs.tcl
+# config: HAVE_DOT = yes
+# config: CALLER_GRAPH = yes
+# config: CALL_GRAPH = yes
+# config: GENERATE_HTML = yes
+
+# This is a stripped down example from my code.
+# Doxygen 1.8.7 generates the correct relations (xml)
+# but caller graphs will be incomplete.
+# It does not generate any relations at all if INLINE_SOURCES = no.
+namespace eval bar {}
+proc bar::slave { } {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ if {1} then {
+ bar::baz
+ }
+ return
+}
+proc bar::baz {} {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ bar::bazbaz
+}
+proc bar::bazbaz {} {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+namespace eval foo {}
+proc foo::master { } {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ bar::slave
+ return
+}
+#
+# now we check tcl's rules: from the help
+# NAME RESOLUTION
+#... Command names are also always resolved by looking in the current
+#namespace first. If not found there, they are searched for in every namespace on
+#the current namespace's command path (which is empty by default). If not found
+#there, command names are looked up in the global namespace (or, failing that,
+#are processed by the unknown command.) ...
+#
+namespace eval ::1::1::1 {}
+proc ::baz args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::1::baz args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::bar args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::1::bar args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::1::1::bar args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::1::1::1::bar args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+}
+proc ::1::test1 args {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ baz
+}
+proc ::1::test2 args {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ bar
+}
+proc ::1::test3 args {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ ::bar
+}
+proc ::1::test4 args {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ 1::bar
+}
+proc ::1::test5 args {
+ array set info [info frame 0]; puts -nonewline $info(proc)
+ 1::baz
+}
+#
+# funny example, do you see the infinite loop?
+# we stop before the interpreter crashes
+set ::countdown 10
+namespace eval ::2::2::2::2::2 {}
+proc ::next args {
+ array set info [info frame 0]; puts $info(proc)
+ 2::next
+}
+proc ::2::next args {
+ array set info [info frame 0]; puts $info(proc)
+ incr ::countdown -1
+ if {$::countdown>0} then {
+ 2::next
+ } else {
+ puts "stop after 10 rounds."
+ }
+}
+proc ::2::2::next args {
+ array set info [info frame 0]; puts $info(proc)
+ 2::next
+}
+proc ::2::2::2::next args {
+ array set info [info frame 0]; puts $info(proc)
+ 2::next
+}
+proc ::2::2::2::2::next args {
+ array set info [info frame 0]; puts $info(proc)
+ 2::next
+}
+proc ::2::2::2::2::2::next args {
+ array set info [info frame 0]; puts $info(proc)
+ 2::next
+}
+#
+# cross check with two files
+# If doxygen did not do two passes, then xrefs would depend on file order
+# and would be incomplete.
+source _057_caller_graphs.tcl
+proc master args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ inFileB
+ return
+}
+proc inFileA args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+}
+# now, check with tcl what is called
+foo::master
+puts ""
+foreach proc [lsort [info procs ::1::test?]] {
+ $proc
+ puts ""
+}
+::next
+master
+exit
+
diff --git a/testing/058/058__bracket__recursion_8tcl.xml b/testing/058/058__bracket__recursion_8tcl.xml
new file mode 100644
index 0000000..fd36cee
--- /dev/null
+++ b/testing/058/058__bracket__recursion_8tcl.xml
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="058__bracket__recursion_8tcl" kind="file">
+ <compoundname>058_bracket_recursion.tcl</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Invoked</definition>
+ <argsstring>args</argsstring>
+ <name>Invoked</name>
+ <briefdescription>
+ <para>should be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="10" bodyend="13"/>
+ <referencedby refid="058__bracket__recursion_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" compoundref="058__bracket__recursion_8tcl" startline="22" endline="25">a</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a68bdb74c144118d936931c46f75d4b3e" compoundref="058__bracket__recursion_8tcl" startline="28" endline="32">b</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" compoundref="058__bracket__recursion_8tcl" startline="33" endline="37">c</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" compoundref="058__bracket__recursion_8tcl" startline="38" endline="42">d</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" compoundref="058__bracket__recursion_8tcl" startline="43" endline="46">e</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1af6830d2c644b45088ea8f1f74a46b778" compoundref="058__bracket__recursion_8tcl" startline="47" endline="50">f</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" compoundref="058__bracket__recursion_8tcl" startline="51" endline="55">g</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1af96fd0966e32a310a0778d2e5c357700" compoundref="058__bracket__recursion_8tcl" startline="56" endline="59">h</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" compoundref="058__bracket__recursion_8tcl" startline="64" endline="68">i</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a2aaa92757686acea102cba3475f0c13b" compoundref="058__bracket__recursion_8tcl" startline="69" endline="73">j</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a20363f854eb4098a446733d63d34dbc1" compoundref="058__bracket__recursion_8tcl" startline="74" endline="77">k</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1aff56f84b49947b84b2a304f51cf8e678" compoundref="058__bracket__recursion_8tcl" startline="78" endline="81">l</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a78d127e8bda64d4471ac811ad512fbd9" compoundref="058__bracket__recursion_8tcl" startline="82" endline="85">m</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1acdde3cd86eb2421ce8dbb2e85227d368" compoundref="058__bracket__recursion_8tcl" startline="86" endline="89">n</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a495e7a4ede0831107e9d435080a7c268" compoundref="058__bracket__recursion_8tcl" startline="90" endline="94">o</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a15229b450f26d8fa1c10bea4f3279f4d" compoundref="058__bracket__recursion_8tcl" startline="102" endline="107">p</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1ab678a0a9a7e94bce5b17141f40220d88" compoundref="058__bracket__recursion_8tcl" startline="108" endline="114">q</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a0a0bd3dc69dd06934c4e6362155e0ace" compoundref="058__bracket__recursion_8tcl" startline="115" endline="120">r</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a011c73f2dbb87635a3b4206c72355f6e" compoundref="058__bracket__recursion_8tcl" startline="121" endline="126">s</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a69e959f6901827e4d8271aeaa5fba0fc" compoundref="058__bracket__recursion_8tcl" startline="128" endline="131">t</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a2fb1c5cf58867b5bbc9a1b145a86f3a0" compoundref="058__bracket__recursion_8tcl" startline="137" endline="142">y</referencedby>
+ <referencedby refid="058__bracket__recursion_8tcl_1a25ed1bcb423b0b7200f485fc5ff71c8e" compoundref="058__bracket__recursion_8tcl" startline="143" endline="148">z</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a3f55465410c57ed00ab28827a741b1c3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>NotInvoked</definition>
+ <argsstring>args</argsstring>
+ <name>NotInvoked</name>
+ <briefdescription>
+ <para>must not be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="16" bodyend="19"/>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>a</definition>
+ <argsstring>args</argsstring>
+ <name>a</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="22" bodyend="25"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a68bdb74c144118d936931c46f75d4b3e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>b</definition>
+ <argsstring>args</argsstring>
+ <name>b</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="28" bodyend="32"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>c</definition>
+ <argsstring>args</argsstring>
+ <name>c</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="33" bodyend="37"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>d</definition>
+ <argsstring>args</argsstring>
+ <name>d</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="38" bodyend="42"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>e</definition>
+ <argsstring>args</argsstring>
+ <name>e</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="43" bodyend="46"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1af6830d2c644b45088ea8f1f74a46b778" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>f</definition>
+ <argsstring>args</argsstring>
+ <name>f</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="47" bodyend="50"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>g</definition>
+ <argsstring>args</argsstring>
+ <name>g</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="51" bodyend="55"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1af96fd0966e32a310a0778d2e5c357700" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>h</definition>
+ <argsstring>args</argsstring>
+ <name>h</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="56" bodyend="59"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>i</definition>
+ <argsstring>args</argsstring>
+ <name>i</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="64" bodyend="68"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a2aaa92757686acea102cba3475f0c13b" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>j</definition>
+ <argsstring>args</argsstring>
+ <name>j</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="69" bodyend="73"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a20363f854eb4098a446733d63d34dbc1" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>k</definition>
+ <argsstring>args</argsstring>
+ <name>k</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="74" bodyend="77"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1aff56f84b49947b84b2a304f51cf8e678" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>l</definition>
+ <argsstring>args</argsstring>
+ <name>l</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="78" bodyend="81"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a78d127e8bda64d4471ac811ad512fbd9" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>m</definition>
+ <argsstring>args</argsstring>
+ <name>m</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="82" bodyend="85"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1acdde3cd86eb2421ce8dbb2e85227d368" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n</definition>
+ <argsstring>args</argsstring>
+ <name>n</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="86" bodyend="89"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a495e7a4ede0831107e9d435080a7c268" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>o</definition>
+ <argsstring>args</argsstring>
+ <name>o</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="90" bodyend="94"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a8a57650834f5708d404e9c386b2edf87" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>$NotInvoked</definition>
+ <argsstring>args</argsstring>
+ <name>$NotInvoked</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="98" bodyend="101"/>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a15229b450f26d8fa1c10bea4f3279f4d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>p</definition>
+ <argsstring>args</argsstring>
+ <name>p</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="102" bodyend="107"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1ab678a0a9a7e94bce5b17141f40220d88" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>q</definition>
+ <argsstring>args</argsstring>
+ <name>q</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="108" bodyend="114"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a0a0bd3dc69dd06934c4e6362155e0ace" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>r</definition>
+ <argsstring>args</argsstring>
+ <name>r</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="115" bodyend="120"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a011c73f2dbb87635a3b4206c72355f6e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>s</definition>
+ <argsstring>args</argsstring>
+ <name>s</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="121" bodyend="126"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a69e959f6901827e4d8271aeaa5fba0fc" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>t</definition>
+ <argsstring>args</argsstring>
+ <name>t</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="128" bodyend="131"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a2fb1c5cf58867b5bbc9a1b145a86f3a0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>y</definition>
+ <argsstring/>
+ <name>y</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="137" bodyend="142"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="058__bracket__recursion_8tcl_1a25ed1bcb423b0b7200f485fc5ff71c8e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>z</definition>
+ <argsstring/>
+ <name>z</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="058_bracket_recursion.tcl" bodystart="143" bodyend="148"/>
+ <references refid="058__bracket__recursion_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="058__bracket__recursion_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="058_bracket_recursion.tcl"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/058_bracket_recursion.tcl b/testing/058_bracket_recursion.tcl
new file mode 100644
index 0000000..2ecd673
--- /dev/null
+++ b/testing/058_bracket_recursion.tcl
@@ -0,0 +1,157 @@
+#// objective: tests processing of commands inside brackets [], only references/referencedby relations are relevant
+#// check: 058__bracket__recursion_8tcl.xml
+#// config: REFERENCED_BY_RELATION = yes
+#// config: REFERENCES_RELATION = yes
+#// config: EXTRACT_ALL = yes
+#// config: INLINE_SOURCES = yes
+
+##
+# \brief should be reference by every proc below
+proc Invoked args {
+ puts "Procedure \"Invoked\" is invoked indeed. Ok."
+ return $args
+}
+##
+# \brief must not be reference by every proc below
+proc NotInvoked args {
+ puts "Procedure \"NotInvoked\" is invoked. Not Ok!"
+ return $args
+}
+#
+# check if call references work at all
+proc a args {
+ Invoked NotInvoked
+ return
+}
+#
+# check brackets with various quoting, bracing
+proc b args {
+ set r [Invoked]
+ set r [list \[NotInvoked \]]
+ return
+}
+proc c args {
+ set r \{[Invoked]\}
+ set r {[NotInvoked]}
+ return
+}
+proc d args {
+ set r "[Invoked]"
+ set r "\[NotInvoked \]"
+ return
+}
+proc e args {
+ set r [list \[NotInvoked [Invoked]\]]
+ return
+}
+proc f args {
+ set r [list [Invoked \[NotInvoked \]]]
+ return
+}
+proc g args {
+ set r "{[Invoked]}"
+ set r "{\[NotInvoked \]}"
+ return
+}
+proc h args {
+ [Invoked set] r {[NotInvoked]}
+ return
+}
+# check brackets in tcl commands containing script arguments
+#
+# example generated according to
+# https://groups.google.com/d/msg/comp.lang.tcl/G5-mc3GiIyY/e-AVD9t7xMkJ
+proc i args {
+ foreach item [Invoked] {
+ return
+ }
+}
+proc j args {
+ foreach [Invoked item] [list one two three] {
+ }
+ return
+}
+proc k args {
+ while {[Invoked 0]} {
+ }
+}
+proc l args {
+ for {} {[Invoked 0]} {} {
+ }
+}
+proc m args {
+ if {[Invoked 1]} {
+ }
+}
+proc n args {
+ if [Invoked 1] {
+ }
+}
+proc o args {
+ if {0} {
+ } elseif {[Invoked 0]} {
+ }
+}
+# these are really nasty examples
+# they shows, that the condition argument may not be parsed as a script
+set NotInvoked \$NotInvoked
+proc $NotInvoked args {
+ puts "Procedure \"\$NotInvoked\" is invoked. Not Ok!"
+ return $args
+}
+proc p args {
+ set NotInvoked \$NotInvoked
+ if {$NotInvoked eq [Invoked 1]} {
+ }
+ return
+}
+proc q args {
+ set NotInvoked \$NotInvoked
+ if {0} {
+ } elseif {$NotInvoked eq [Invoked 1]} {
+ }
+ return
+}
+proc r args {
+ set NotInvoked \$NotInvoked
+ while {$NotInvoked eq [Invoked 1]} {
+ }
+ return
+}
+proc s args {
+ set NotInvoked \$NotInvoked
+ for {} {$NotInvoked eq [Invoked 1]} {} {
+ }
+ return
+}
+# dangling open brackets should not confuse the scanner
+proc t args {
+ set foo ]]]][Invoked]
+ return
+}
+# Example according to
+# https://bugzilla.gnome.org/show_bug.cgi?id=729135
+# |
+# Note the subtle difference in this | whitespace
+# V
+proc y {} {
+ set classifier_state {{bphy} }
+ if { ($classifier_state == {{bphy} }) } {
+ Invoked
+ }
+}
+proc z {} {
+ set classifier_state {{bphy} }
+ if { ($classifier_state == {{bphy} } ) } {
+ Invoked
+ }
+}
+#
+# call all single letter procs
+# let tcl check what is called and what is not called
+foreach p [info procs ?] {
+ puts "Check procedure \"$p\""
+ $p
+}
+exit
+
diff --git a/testing/059/059__command__catch_8tcl.xml b/testing/059/059__command__catch_8tcl.xml
new file mode 100644
index 0000000..6604413
--- /dev/null
+++ b/testing/059/059__command__catch_8tcl.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="059__command__catch_8tcl" kind="file">
+ <compoundname>059_command_catch.tcl</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Invoked</definition>
+ <argsstring>args</argsstring>
+ <name>Invoked</name>
+ <briefdescription>
+ <para>should be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="10" bodyend="13"/>
+ <referencedby refid="059__command__catch_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" compoundref="059__command__catch_8tcl" startline="22" endline="25">a</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1a68bdb74c144118d936931c46f75d4b3e" compoundref="059__command__catch_8tcl" startline="29" endline="32">b</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" compoundref="059__command__catch_8tcl" startline="33" endline="36">c</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" compoundref="059__command__catch_8tcl" startline="37" endline="40">d</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" compoundref="059__command__catch_8tcl" startline="41" endline="44">e</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1af6830d2c644b45088ea8f1f74a46b778" compoundref="059__command__catch_8tcl" startline="45" endline="48">f</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" compoundref="059__command__catch_8tcl" startline="49" endline="54">g</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1af96fd0966e32a310a0778d2e5c357700" compoundref="059__command__catch_8tcl" startline="56" endline="59">h</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" compoundref="059__command__catch_8tcl" startline="60" endline="63">i</referencedby>
+ <referencedby refid="059__command__catch_8tcl_1a2aaa92757686acea102cba3475f0c13b" compoundref="059__command__catch_8tcl" startline="75" endline="78">j</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1a3f55465410c57ed00ab28827a741b1c3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>NotInvoked</definition>
+ <argsstring>args</argsstring>
+ <name>NotInvoked</name>
+ <briefdescription>
+ <para>must not be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="16" bodyend="19"/>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>a</definition>
+ <argsstring>args</argsstring>
+ <name>a</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="22" bodyend="25"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1a68bdb74c144118d936931c46f75d4b3e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>b</definition>
+ <argsstring>args</argsstring>
+ <name>b</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="29" bodyend="32"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>c</definition>
+ <argsstring>args</argsstring>
+ <name>c</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="33" bodyend="36"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>d</definition>
+ <argsstring>args</argsstring>
+ <name>d</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="37" bodyend="40"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>e</definition>
+ <argsstring>args</argsstring>
+ <name>e</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="41" bodyend="44"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1af6830d2c644b45088ea8f1f74a46b778" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>f</definition>
+ <argsstring>args</argsstring>
+ <name>f</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="45" bodyend="48"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>g</definition>
+ <argsstring>args</argsstring>
+ <name>g</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="49" bodyend="54"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1af96fd0966e32a310a0778d2e5c357700" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>h</definition>
+ <argsstring>args</argsstring>
+ <name>h</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="56" bodyend="59"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>i</definition>
+ <argsstring>args</argsstring>
+ <name>i</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="60" bodyend="63"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="059__command__catch_8tcl_1a2aaa92757686acea102cba3475f0c13b" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>j</definition>
+ <argsstring>args</argsstring>
+ <name>j</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="059_command_catch.tcl" bodystart="75" bodyend="78"/>
+ <references refid="059__command__catch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="059__command__catch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="059_command_catch.tcl"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/059_command_catch.tcl b/testing/059_command_catch.tcl
new file mode 100644
index 0000000..4227da7
--- /dev/null
+++ b/testing/059_command_catch.tcl
@@ -0,0 +1,87 @@
+#// objective: tests processing of catch/eval, only references/referencedby relations are relevant
+#// check: 059__command__catch_8tcl.xml
+#// config: REFERENCED_BY_RELATION = yes
+#// config: REFERENCES_RELATION = yes
+#// config: EXTRACT_ALL = yes
+#// config: INLINE_SOURCES = no
+
+##
+# \brief should be reference by every proc below
+proc Invoked args {
+ puts "Procedure \"Invoked\" is invoked indeed. Ok."
+ return $args
+}
+##
+# \brief must not be reference by every proc below
+proc NotInvoked args {
+ puts "Procedure \"NotInvoked\" is invoked. Not Ok!"
+ return $args
+}
+#
+# check if call references work at all
+proc a args {
+ Invoked NotInvoked
+ return
+}
+#
+# catch command
+# Tcl8.5: catch script ?resultVarName? ?optionsVarName?
+proc b args {
+ catch Invoked
+ return
+}
+proc c args {
+ catch Invoked NotInvoked
+ return
+}
+proc d args {
+ catch Invoked NotInvoked NotInvoked
+ return
+}
+proc e args {
+ set r [catch Invoked NotInvoked NotInvoked]
+ return
+}
+proc f args {
+ set r [catch {Invoked} NotInvoked NotInvoked]
+ return
+}
+proc g args {
+ set r [catch {
+ set x [Invoked]
+ } NotInvoked NotInvoked]
+ return
+}
+# eval arg ?arg ...?
+proc h args {
+ eval Invoked NotInvoked
+ return
+}
+proc i args {
+ eval set NotInvoked [Invoked NotInvoked]
+ return
+}
+# This is a striped down example. Original:
+#
+# jpeg.tcl --
+#
+# Querying and modifying JPEG image files.
+#
+# Copyright (c) 2004 Aaron Faupell <afaupell at users.sourceforge.net>
+#
+# ...
+# eval [list addComment $file] [lreplace $com 0 0 $comment]
+# ...
+proc j args {
+ eval [list set] [list NotInvoked] [Invoked NotInvoked]
+ return
+}
+#
+# call all single letter procs
+# let tcl check what is called and what is not called
+foreach p [info procs ?] {
+ puts "Check procedure \"$p\""
+ $p
+}
+exit
+
diff --git a/testing/060/060__command__switch_8tcl.xml b/testing/060/060__command__switch_8tcl.xml
new file mode 100644
index 0000000..05e01c6
--- /dev/null
+++ b/testing/060/060__command__switch_8tcl.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="060__command__switch_8tcl" kind="file">
+ <compoundname>060_command_switch.tcl</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Invoked</definition>
+ <argsstring>args</argsstring>
+ <name>Invoked</name>
+ <briefdescription>
+ <para>should be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="10" bodyend="13"/>
+ <referencedby refid="060__command__switch_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" compoundref="060__command__switch_8tcl" startline="22" endline="25">a</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a68bdb74c144118d936931c46f75d4b3e" compoundref="060__command__switch_8tcl" startline="29" endline="36">b</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" compoundref="060__command__switch_8tcl" startline="37" endline="43">c</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" compoundref="060__command__switch_8tcl" startline="44" endline="50">d</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" compoundref="060__command__switch_8tcl" startline="51" endline="57">e</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1af6830d2c644b45088ea8f1f74a46b778" compoundref="060__command__switch_8tcl" startline="58" endline="65">f</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" compoundref="060__command__switch_8tcl" startline="66" endline="73">g</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1af96fd0966e32a310a0778d2e5c357700" compoundref="060__command__switch_8tcl" startline="74" endline="81">h</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" compoundref="060__command__switch_8tcl" startline="83" endline="94">i</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a2aaa92757686acea102cba3475f0c13b" compoundref="060__command__switch_8tcl" startline="95" endline="106">j</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a20363f854eb4098a446733d63d34dbc1" compoundref="060__command__switch_8tcl" startline="107" endline="118">k</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1aff56f84b49947b84b2a304f51cf8e678" compoundref="060__command__switch_8tcl" startline="119" endline="129">l</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a78d127e8bda64d4471ac811ad512fbd9" compoundref="060__command__switch_8tcl" startline="130" endline="141">m</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1acdde3cd86eb2421ce8dbb2e85227d368" compoundref="060__command__switch_8tcl" startline="142" endline="153">n</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a495e7a4ede0831107e9d435080a7c268" compoundref="060__command__switch_8tcl" startline="154" endline="165">o</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a15229b450f26d8fa1c10bea4f3279f4d" compoundref="060__command__switch_8tcl" startline="166" endline="175">p</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1ab678a0a9a7e94bce5b17141f40220d88" compoundref="060__command__switch_8tcl" startline="176" endline="185">q</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a0a0bd3dc69dd06934c4e6362155e0ace" compoundref="060__command__switch_8tcl" startline="186" endline="195">r</referencedby>
+ <referencedby refid="060__command__switch_8tcl_1a011c73f2dbb87635a3b4206c72355f6e" compoundref="060__command__switch_8tcl" startline="196" endline="205">s</referencedby>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a3f55465410c57ed00ab28827a741b1c3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>NotInvoked</definition>
+ <argsstring>args</argsstring>
+ <name>NotInvoked</name>
+ <briefdescription>
+ <para>must not be reference by every proc below </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="16" bodyend="19"/>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1ab08ae027fc5777bc4f0629f1b60b35db" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>a</definition>
+ <argsstring>args</argsstring>
+ <name>a</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="22" bodyend="25"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a68bdb74c144118d936931c46f75d4b3e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>b</definition>
+ <argsstring>args</argsstring>
+ <name>b</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="29" bodyend="36"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1ab14f56bc3bd7680490ece4ad7815465f" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>c</definition>
+ <argsstring>args</argsstring>
+ <name>c</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="37" bodyend="43"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1af43f4b1f0064a33b2d662af9f06d3a00" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>d</definition>
+ <argsstring>args</argsstring>
+ <name>d</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="44" bodyend="50"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1aff65a51a703804e0ad1adbcfd76c86f8" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>e</definition>
+ <argsstring>args</argsstring>
+ <name>e</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="51" bodyend="57"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1af6830d2c644b45088ea8f1f74a46b778" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>f</definition>
+ <argsstring>args</argsstring>
+ <name>f</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="58" bodyend="65"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1af08b4b5bfa9edf0b0a7dee1c2b2c29e0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>g</definition>
+ <argsstring>args</argsstring>
+ <name>g</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="66" bodyend="73"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1af96fd0966e32a310a0778d2e5c357700" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>h</definition>
+ <argsstring>args</argsstring>
+ <name>h</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="74" bodyend="81"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a8c90afd4641b25be86bd09983c3cbee0" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>i</definition>
+ <argsstring>args</argsstring>
+ <name>i</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="83" bodyend="94"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a2aaa92757686acea102cba3475f0c13b" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>j</definition>
+ <argsstring>args</argsstring>
+ <name>j</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="95" bodyend="106"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a20363f854eb4098a446733d63d34dbc1" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>k</definition>
+ <argsstring>args</argsstring>
+ <name>k</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="107" bodyend="118"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1aff56f84b49947b84b2a304f51cf8e678" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>l</definition>
+ <argsstring>args</argsstring>
+ <name>l</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="119" bodyend="129"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a78d127e8bda64d4471ac811ad512fbd9" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>m</definition>
+ <argsstring>args</argsstring>
+ <name>m</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="130" bodyend="141"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1acdde3cd86eb2421ce8dbb2e85227d368" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n</definition>
+ <argsstring>args</argsstring>
+ <name>n</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="142" bodyend="153"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a495e7a4ede0831107e9d435080a7c268" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>o</definition>
+ <argsstring>args</argsstring>
+ <name>o</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="154" bodyend="165"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a15229b450f26d8fa1c10bea4f3279f4d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>p</definition>
+ <argsstring>args</argsstring>
+ <name>p</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="166" bodyend="175"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1ab678a0a9a7e94bce5b17141f40220d88" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>q</definition>
+ <argsstring>args</argsstring>
+ <name>q</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="176" bodyend="185"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a0a0bd3dc69dd06934c4e6362155e0ace" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>r</definition>
+ <argsstring>args</argsstring>
+ <name>r</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="186" bodyend="195"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ <memberdef kind="function" id="060__command__switch_8tcl_1a011c73f2dbb87635a3b4206c72355f6e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>s</definition>
+ <argsstring>args</argsstring>
+ <name>s</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="060_command_switch.tcl" bodystart="196" bodyend="205"/>
+ <references refid="060__command__switch_8tcl_1aa889853547f65a22ae133cd57ff89601" compoundref="060__command__switch_8tcl" startline="10" endline="13">Invoked</references>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="060_command_switch.tcl"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/060_command_switch.tcl b/testing/060_command_switch.tcl
new file mode 100644
index 0000000..407f2e9
--- /dev/null
+++ b/testing/060_command_switch.tcl
@@ -0,0 +1,238 @@
+#// objective: tests processing of switch, only references/referencedby relations are relevant
+#// check: 060__command__switch_8tcl.xml
+#// config: REFERENCED_BY_RELATION = yes
+#// config: REFERENCES_RELATION = yes
+#// config: EXTRACT_ALL = yes
+#// config: INLINE_SOURCES = no
+
+##
+# \brief should be reference by every proc below
+proc Invoked args {
+ puts "Procedure \"Invoked\" is invoked indeed. Ok."
+ return $args
+}
+##
+# \brief must not be reference by every proc below
+proc NotInvoked args {
+ puts "Procedure \"NotInvoked\" is invoked. Not Ok!"
+ return $args
+}
+#
+# check if call references work at all
+proc a args {
+ Invoked NotInvoked
+ return
+}
+#
+# switch command
+# switch ?options? string pattern body ?pattern body ...?
+proc b args {
+ switch value NotInvoked {
+ } NotInvoked {
+ } default {
+ Invoked
+ }
+ return
+}
+proc c args {
+ switch value NotInvoked {
+ } [Invoked] {
+ } default {
+ }
+ return
+}
+proc d args {
+ switch NotInvoked pattern {
+ } [Invoked] {
+ } default {
+ }
+ return
+}
+proc e args {
+ switch [Invoked] pattern {
+ } NotInvoked {
+ } default {
+ }
+ return
+}
+proc f args {
+ switch -exact value pattern {
+ } NotInvoked {
+ } default {
+ Invoked
+ }
+ return
+}
+proc g args {
+ switch -exact -- value pattern {
+ } NotInvoked {
+ } default {
+ Invoked
+ }
+ return
+}
+proc h args {
+ switch -exact -- -value pattern {
+ } NotInvoked {
+ } default {
+ Invoked
+ }
+ return
+}
+# switch ?options? string {pattern body ?pattern body ...?}
+proc i args {
+ switch value {
+ NotInvoked {
+ }
+ NotInvoked {
+ }
+ default {
+ Invoked
+ }
+ }
+ return
+}
+proc j args {
+ switch vale {
+ NotInvoked {
+ }
+ [NotInvoked] {
+ }
+ default {
+ Invoked
+ }
+ }
+ return
+}
+proc k args {
+ switch NotInvoked {
+ [NotInvoked] {
+ }
+ NotInvoked {
+ Invoked
+ }
+ default {
+ }
+ }
+ return
+}
+proc l args {
+ switch [Invoked] {
+ pattern {
+ }
+ NotInvoked {
+ }
+ default {
+ }
+ }
+ return
+}
+proc m args {
+ switch -exact value {
+ pattern {
+ }
+ NotInvoked {
+ }
+ default {
+ Invoked
+ }
+ }
+ return
+}
+proc n args {
+ switch -exact -- value {
+ pattern {
+ }
+ NotInvoked {
+ }
+ default {
+ Invoked
+ }
+ }
+ return
+}
+proc o args {
+ switch -exact -- -value {
+ pattern {
+ }
+ NotInvoked {
+ }
+ default {
+ Invoked
+ }
+ }
+ return
+}
+proc p args {
+ switch -exact -- inquotes {
+ "inquotes" {
+ Invoked
+ }
+ default {
+ }
+ }
+ return
+}
+proc q args {
+ switch -exact -- "in quotes" {
+ "in quotes" {
+ Invoked
+ }
+ default {
+ }
+ }
+ return
+}
+proc r args {
+ switch -exact -- inbraces {
+ {inbraces} {
+ Invoked
+ }
+ default {
+ }
+ }
+ return
+}
+proc s args {
+ switch -exact -- {in braces} {
+ {in braces} {
+ Invoked
+ }
+ default {
+ }
+ }
+ return
+}
+# wrong syntax
+#proc x args {
+# catch {switch -exact -- [Invoked] pattern1 NotInvoked pattern2}
+# return
+#}
+# The current version does not check the last argument beforehand.
+# Therefore, all script elements are evaluated as scripts before
+# the parser detects the dangling pattern. It throws a warning, at the very least.
+# Anyway, for working code the documentation will be correct.
+#proc y args {
+# catch {switch -exact -- [Invoked] {
+# pattern {
+# NotInvoked
+# }
+# NotInvoked {
+# NotInvoked
+# }
+# default {
+# NotInvoked
+# }
+# pattern
+# }}
+# return
+#}
+#
+# call all single letter procs
+# let tcl check what is called and what is not called
+foreach p [info procs ?] {
+ puts "Check procedure \"$p\""
+ $p
+}
+exit
+
diff --git a/testing/061/class_test.xml b/testing/061/class_test.xml
new file mode 100644
index 0000000..0922539
--- /dev/null
+++ b/testing/061/class_test.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="class_test" kind="class" prot="public">
+ <compoundname>Test</compoundname>
+ <sectiondef kind="public-func">
+ <memberdef kind="function" id="class_test_1af863c78bca81b4e276dcbb30f12e8ec6" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Test::testmethod_one</definition>
+ <argsstring>args</argsstring>
+ <name>testmethod_one</name>
+ <briefdescription>
+ <para><ref refid="class_test" kindref="compound">Test</ref> method 1. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="061_bug_705503.tcl" bodystart="12" bodyend="12"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1ac7148d2852b30d157e078fe0fe58a350" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Test::constructor</definition>
+ <argsstring>args</argsstring>
+ <name>constructor</name>
+ <briefdescription>
+ <para>Construction of class. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="061_bug_705503.tcl" bodystart="16" bodyend="16"/>
+ </memberdef>
+ <memberdef kind="function" id="class_test_1abdf3375950ec49e29f4bae947b7e3f26" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>Test::testmethod_two</definition>
+ <argsstring>args</argsstring>
+ <name>testmethod_two</name>
+ <briefdescription>
+ <para><ref refid="class_test" kindref="compound">Test</ref> method 2. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="061_bug_705503.tcl" bodystart="19" bodyend="19"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ <para>Testclass. </para>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="061_bug_705503.tcl" bodystart="10" bodyend="13"/>
+ <listofallmembers>
+ <member refid="class_test_1ac7148d2852b30d157e078fe0fe58a350" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>constructor</name>
+ </member>
+ <member refid="class_test_1af863c78bca81b4e276dcbb30f12e8ec6" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>testmethod_one</name>
+ </member>
+ <member refid="class_test_1abdf3375950ec49e29f4bae947b7e3f26" prot="public" virt="non-virtual">
+ <scope>Test</scope>
+ <name>testmethod_two</name>
+ </member>
+ </listofallmembers>
+ </compounddef>
+</doxygen>
diff --git a/testing/061_bug_705503.tcl b/testing/061_bug_705503.tcl
new file mode 100644
index 0000000..ce25d6e
--- /dev/null
+++ b/testing/061_bug_705503.tcl
@@ -0,0 +1,19 @@
+#// objective: test for bug 705503 - TCL: Documentation of oo::define is not working
+#// check: class_test.xml
+#// config: EXTRACT_ALL = yes
+
+# taken from
+# https://bugzilla.gnome.org/show_bug.cgi?id=705503
+
+## @class Test
+# @brief Testclass
+oo::class create Test {
+ ## @brief Test method 1.
+ method testmethod_one args {}
+}
+
+## @brief Construction of class
+oo::define Test constructor args {}
+
+## @brief Test method 2
+oo::define Test method testmethod_two args {}
diff --git a/testing/062/namespacen1.xml b/testing/062/namespacen1.xml
new file mode 100644
index 0000000..0ef31ff
--- /dev/null
+++ b/testing/062/namespacen1.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespacen1" kind="namespace">
+ <compoundname>n1</compoundname>
+ <innernamespace refid="namespacen1_1_1n1">n1::n1</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespacen1_1a9f23d7a7f141915457e8e26023d70cb4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n1::p1</definition>
+ <argsstring>args</argsstring>
+ <name>p1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="12" bodyend="16"/>
+ <references refid="namespacen1_1a0bff29f718fa43e49b7ca79985afb5fa" compoundref="062__namespace__resolution_8tcl" startline="17" endline="20">p2</references>
+ </memberdef>
+ <memberdef kind="function" id="namespacen1_1a0bff29f718fa43e49b7ca79985afb5fa" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n1::p2</definition>
+ <argsstring>args</argsstring>
+ <name>p2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="17" bodyend="20"/>
+ <referencedby refid="namespacen1_1a9f23d7a7f141915457e8e26023d70cb4" compoundref="062__namespace__resolution_8tcl" startline="12" endline="16">p1</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="062_namespace_resolution.tcl" line="11" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/062/namespacen2.xml b/testing/062/namespacen2.xml
new file mode 100644
index 0000000..39c21d2
--- /dev/null
+++ b/testing/062/namespacen2.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespacen2" kind="namespace">
+ <compoundname>n2</compoundname>
+ <innernamespace refid="namespacen2_1_1n2">n2::n2</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespacen2_1a74950c0185232e374220a0707b4903c6" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n2::p1</definition>
+ <argsstring>args</argsstring>
+ <name>p1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="31" bodyend="35"/>
+ <references refid="namespacen2_1a49fadfbefa795204a3c566ec76ff632f" compoundref="062__namespace__resolution_8tcl" startline="36" endline="39">p2</references>
+ </memberdef>
+ <memberdef kind="function" id="namespacen2_1a49fadfbefa795204a3c566ec76ff632f" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n2::p2</definition>
+ <argsstring>args</argsstring>
+ <name>p2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="36" bodyend="39"/>
+ <referencedby refid="namespacen2_1a74950c0185232e374220a0707b4903c6" compoundref="062__namespace__resolution_8tcl" startline="31" endline="35">p1</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="062_namespace_resolution.tcl" line="29" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/062/namespacen3.xml b/testing/062/namespacen3.xml
new file mode 100644
index 0000000..25c803c
--- /dev/null
+++ b/testing/062/namespacen3.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespacen3" kind="namespace">
+ <compoundname>n3</compoundname>
+ <innernamespace refid="namespacen3_1_1n3">n3::n3</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespacen3_1ae7e87e49507bd56dad087cffecd35b29" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n3::p1</definition>
+ <argsstring>args</argsstring>
+ <name>p1</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="47" bodyend="51"/>
+ <references refid="namespacen3_1a14e9fe1b27a6d36db9ace2eef4509979" compoundref="062__namespace__resolution_8tcl" startline="52" endline="55">p2</references>
+ </memberdef>
+ <memberdef kind="function" id="namespacen3_1a14e9fe1b27a6d36db9ace2eef4509979" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>n3::p2</definition>
+ <argsstring>args</argsstring>
+ <name>p2</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="062_namespace_resolution.tcl" bodystart="52" bodyend="55"/>
+ <referencedby refid="namespacen3_1ae7e87e49507bd56dad087cffecd35b29" compoundref="062__namespace__resolution_8tcl" startline="47" endline="51">p1</referencedby>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="062_namespace_resolution.tcl" line="45" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/062_namespace_resolution.tcl b/testing/062_namespace_resolution.tcl
new file mode 100644
index 0000000..dcc6701
--- /dev/null
+++ b/testing/062_namespace_resolution.tcl
@@ -0,0 +1,68 @@
+#// objective: tests correct namespace resolution, only references/referencedby relations are relevant
+#// check: namespacen1.xml
+#// check: namespacen2.xml
+#// check: namespacen3.xml
+#// config: REFERENCED_BY_RELATION = yes
+#// config: REFERENCES_RELATION = yes
+#// config: EXTRACT_ALL = yes
+#// config: INLINE_SOURCES = yes
+
+# now: combine namespace eval and qualified names
+namespace eval n1 {
+ proc p1 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ p2
+ return
+ }
+ proc p2 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+ }
+ namespace eval n1 {
+ proc p1 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+ }
+ }
+}
+# same thing, but fully qualified proc names
+namespace eval ::n2 {}
+namespace eval ::n2::n2 {}
+proc ::n2::p1 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ p2
+ return
+}
+proc ::n2::p2 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+}
+proc ::n2::n2::p2 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+}
+# same thing, without leading ::
+namespace eval n3 {}
+namespace eval n3::n3 {}
+proc n3::p1 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ p2
+ return
+}
+proc n3::p2 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+}
+proc n3::n3::p2 args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ return
+}
+# now, check with tcl what is called
+n1::p1
+puts ""
+n2::p1
+puts ""
+n3::p1
+puts ""
+exit
+
diff --git a/testing/063/namespaceoo.xml b/testing/063/namespaceoo.xml
new file mode 100644
index 0000000..eb0c93c
--- /dev/null
+++ b/testing/063/namespaceoo.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespaceoo" kind="namespace">
+ <compoundname>oo</compoundname>
+ <innernamespace refid="namespaceoo_1_1define">oo::define</innernamespace>
+ <innernamespace refid="namespaceoo_1_1_helpers">oo::Helpers</innernamespace>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="[generated]" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/063/namespaceoo_1_1_helpers.xml b/testing/063/namespaceoo_1_1_helpers.xml
new file mode 100644
index 0000000..ff309cf
--- /dev/null
+++ b/testing/063/namespaceoo_1_1_helpers.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespaceoo_1_1_helpers" kind="namespace">
+ <compoundname>oo::Helpers</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespaceoo_1_1_helpers_1a96c5b755588beb2e930cff23ce811d6c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>oo::Helpers::classvar</definition>
+ <argsstring>args</argsstring>
+ <name>classvar</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Extension to TclOO to add static variables. Defines variables on the class instead of on the object. Can be used to enforce a limited number of instantiations. </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="063_bug_729092.tcl" bodystart="34" bodyend="43"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="063_bug_729092.tcl" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/063/namespaceoo_1_1define.xml b/testing/063/namespaceoo_1_1define.xml
new file mode 100644
index 0000000..aa62fbd
--- /dev/null
+++ b/testing/063/namespaceoo_1_1define.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="">
+ <compounddef id="namespaceoo_1_1define" kind="namespace">
+ <compoundname>oo::define</compoundname>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="namespaceoo_1_1define_1a89e7ea222a316f1926c1f9f30f2cc5c1" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type/>
+ <definition>oo::define::classmethod</definition>
+ <argsstring>name?args??body?</argsstring>
+ <name>classmethod</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ <para>Extension to TclOO to add static methods. Defines the method on the class instead of on the object. Can be used for the creation of megawidgets using TclOO by overriding the unknown method to detect if the user is trying to instantiate a widget (because the method will be unknown and start with a dot). </para>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="063_bug_729092.tcl" bodystart="18" bodyend="27"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="063_bug_729092.tcl" line="1" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/063_bug_729092.tcl b/testing/063_bug_729092.tcl
new file mode 100644
index 0000000..a6d3341
--- /dev/null
+++ b/testing/063_bug_729092.tcl
@@ -0,0 +1,43 @@
+#// objective: test for bug 729092 - TCL: Full documentation not shown for procs in namespaces.
+#// check: namespaceoo.xml
+#// check: namespaceoo_1_1_helpers.xml
+#// check: namespaceoo_1_1define.xml
+#// config: EXTRACT_ALL = yes
+#// config: GENERATE_HTML = yes
+
+# taken from
+# https://bugzilla.gnome.org/show_bug.cgi?id=729092
+
+##
+# Extension to TclOO to add static methods.
+# Defines the method on the class instead of on the object. Can be used for
+# the creation of megawidgets using TclOO by overriding the unknown method to
+# detect if the user is trying to instantiate a widget (because the method
+# will be unknown and start with a dot).
+#
+proc ::oo::define::classmethod {name {args ""} {body ""}} {
+ # Create the method on the class if the caller gave arguments and body.
+ if {[llength [info level 0]] == 4} {
+ uplevel 1 [list self method $name $args $body]
+ }
+ # Get the name of the class being defined.
+ set cls [lindex [info level -1] 1]
+ # Make connection to private class "my" command by forwarding.
+ uplevel forward $name [info object namespace $cls]::my $name
+}
+
+##
+# Extension to TclOO to add static variables.
+# Defines variables on the class instead of on the object. Can be used to
+# enforce a limited number of instantiations.
+#
+proc ::oo::Helpers::classvar {args} {
+ # Get reference to class's namespace.
+ set nsCl [info object namespace [uplevel 1 {self class}]]
+ set nsObj [uplevel 1 {namespace current}]
+ # Link variables into local (caller's) scope.
+ foreach v $args {
+ uplevel "my variable $v"
+ upvar #0 ${nsCl}::$v ${nsObj}::$v
+ }
+}
diff --git a/testing/Doxyfile b/testing/Doxyfile
new file mode 100644
index 0000000..e1486d3
--- /dev/null
+++ b/testing/Doxyfile
@@ -0,0 +1,7 @@
+# start with defaults
+QUIET = YES
+GENERATE_HTML = NO
+GENERATE_LATEX = NO
+GENERATE_XML = YES
+XML_PROGRAMLISTING = NO
+CASE_SENSE_NAMES = NO
diff --git a/testing/Makefile b/testing/Makefile
new file mode 100644
index 0000000..f40107f
--- /dev/null
+++ b/testing/Makefile
@@ -0,0 +1,3 @@
+tests:
+ @perl runtests.pl --doxygen ../bin/doxygen
+
diff --git a/testing/README b/testing/README
new file mode 100644
index 0000000..993ff48
--- /dev/null
+++ b/testing/README
@@ -0,0 +1,48 @@
+Doxygen regession test suite
+============================
+
+This directory contains a set of regression tests. Each test consists of a
+file starting with a 3 digit number and a corresponding directory whose name
+has the same 3 digit number. The directory contains one or more reference
+files that are compared against the XML output produced by doxygen. If the
+result is the same, there is no regression and the test passes. If there is a
+difference the test fails and the difference (in diff -u format) will be shown.
+
+The runtest.pl script responsible for running the tests takes a number of
+optional parameters:
+-id n: run test with number n only (the option may be specified
+ multiple times) default is to run all tests.
+-updateref: update the reference files. Should be used in combination
+ with -id to update the reference file(s) for the given test.
+-all: can be used in combination with -updateref to update the
+ reference files for all tests.
+-doxygen exe: run the specified doxygen executable.
+-xmllint exe: run the specified xmllint executable.
+
+The runtest.pl has the following dependenies on 3rd party tools:
+- perl to run the script
+- xmllint to normalize the XML output
+- diff to show the differences in case a test fails
+
+Each test file can have a number of special comment lines that are extracted by
+the runtest.pl script and take the form:
+// <identifier>: 'argument'
+Where <identifier> can be one of:
+- objective: 'argument' provides the objective for the test (i.e. its purpose)
+- check: 'argument' names a file that is generated by doxygen, which should
+ be compared against the reference.
+- config: 'argument' is a line that is added to the default Doxyfile used to
+ run doxygen on the test file.
+
+Example to run all tests:
+ perl runtest.pl
+
+Example to run a test
+ perl runtest.pl -id 10
+
+Example to update the reference files for a test
+ perl runtest.pl -updateref -id 10
+
+There is also a Makefile, which can be used to run all tests by simply
+invoking make.
+
diff --git a/testing/_057_caller_graphs.tcl b/testing/_057_caller_graphs.tcl
new file mode 100644
index 0000000..24b9c20
--- /dev/null
+++ b/testing/_057_caller_graphs.tcl
@@ -0,0 +1,4 @@
+proc inFileB args {
+ array set info [info frame 0]; puts -nonewline ->$info(proc)
+ inFileA
+}
diff --git a/testing/debug.txt b/testing/debug.txt
new file mode 100644
index 0000000..377b307
--- /dev/null
+++ b/testing/debug.txt
@@ -0,0 +1,30 @@
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
+ASSERT: "m_numDecMembers!=-1" in ./memberlist.h (52)
diff --git a/testing/example_test.cpp b/testing/example_test.cpp
new file mode 100644
index 0000000..f589023
--- /dev/null
+++ b/testing/example_test.cpp
@@ -0,0 +1,6 @@
+void main()
+{
+ Test t;
+ t.example();
+}
+
diff --git a/testing/html/063__bug__729092_8tcl.html b/testing/html/063__bug__729092_8tcl.html
new file mode 100644
index 0000000..18e9369
--- /dev/null
+++ b/testing/html/063__bug__729092_8tcl.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: 063_bug_729092.tcl File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+</div><!-- top -->
+<div class="header">
+ <div class="summary">
+<a href="#namespaces">Namespaces</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">063_bug_729092.tcl File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="namespaces"></a>
+Namespaces</h2></td></tr>
+<tr class="memitem:namespaceoo_1_1define"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1define.html">oo::define</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:namespaceoo_1_1_helpers"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1_helpers.html">oo::Helpers</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:a89e7ea222a316f1926c1f9f30f2cc5c1"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1">oo::define::classmethod</a> name?args??body?</td></tr>
+<tr class="separator:a89e7ea222a316f1926c1f9f30f2cc5c1"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:a96c5b755588beb2e930cff23ce811d6c"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c">oo::Helpers::classvar</a> args</td></tr>
+<tr class="separator:a96c5b755588beb2e930cff23ce811d6c"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/bc_s.png b/testing/html/bc_s.png
new file mode 100644
index 0000000..224b29a
Binary files /dev/null and b/testing/html/bc_s.png differ
diff --git a/testing/html/bdwn.png b/testing/html/bdwn.png
new file mode 100644
index 0000000..940a0b9
Binary files /dev/null and b/testing/html/bdwn.png differ
diff --git a/testing/html/closed.png b/testing/html/closed.png
new file mode 100644
index 0000000..98cc2c9
Binary files /dev/null and b/testing/html/closed.png differ
diff --git a/testing/html/doxygen.css b/testing/html/doxygen.css
new file mode 100644
index 0000000..0a8f962
--- /dev/null
+++ b/testing/html/doxygen.css
@@ -0,0 +1,1440 @@
+/* The standard CSS for doxygen 1.8.7 */
+
+body, table, div, p, dl {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+ font-size: 150%;
+}
+
+.title {
+ font: 400 14px/28px Roboto,sans-serif;
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2.groupheader {
+ border-bottom: 1px solid #879ECB;
+ color: #354C7B;
+ font-size: 150%;
+ font-weight: normal;
+ margin-top: 1.75em;
+ padding-top: 8px;
+ padding-bottom: 4px;
+ width: 100%;
+}
+
+h3.groupheader {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+ margin-top: 2px;
+}
+
+p.starttd {
+ margin-top: 0px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #3D578C;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #4665A2;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #9CAFD4;
+ color: #ffffff;
+ border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+ color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ background-color: #FBFCFD;
+ border: 1px solid #C4CFE5;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ min-height: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+div.line.glow {
+ background-color: cyan;
+ box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 12px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: #EBEFF6;
+ font-weight: bold;
+ border: 1px solid #C4CFE5;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: #F7F8FB;
+ border-left: 2px solid #9CAFD4;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+ background: #EBEFF6;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+ background-color: cyan;
+ box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F9FAFC;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memSeparator {
+ border-bottom: 1px solid #DEE4F0;
+ line-height: 1px;
+ margin: 0px;
+ padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #4665A2;
+ white-space: nowrap;
+ font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #4665A2;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+ display: table !important;
+ width: 100%;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memname td {
+ vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 0px 6px 0px;
+ color: #253555;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 10px 2px 10px;
+ background-color: #FBFCFD;
+ border-top-width: 0;
+ background-image:url('nav_g.png');
+ background-repeat:repeat-x;
+ background-color: #FFFFFF;
+ /* opera specific markup */
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+.paramname code {
+ line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+table.mlabels {
+ border-spacing: 0px;
+}
+
+td.mlabels-left {
+ width: 100%;
+ padding: 0px;
+}
+
+td.mlabels-right {
+ vertical-align: bottom;
+ padding: 0px;
+ white-space: nowrap;
+}
+
+span.mlabels {
+ margin-left: 8px;
+}
+
+span.mlabel {
+ background-color: #728DC1;
+ border-top:1px solid #5373B4;
+ border-left:1px solid #5373B4;
+ border-right:1px solid #C4CFE5;
+ border-bottom:1px solid #C4CFE5;
+ text-shadow: none;
+ color: white;
+ margin-right: 4px;
+ padding: 2px 3px;
+ border-radius: 3px;
+ font-size: 7pt;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+ margin: 10px 0px;
+ border-top: 1px solid #9CAFD4;
+ border-bottom: 1px solid #9CAFD4;
+ width: 100%;
+}
+
+.directory table {
+ border-collapse:collapse;
+}
+
+.directory td {
+ margin: 0px;
+ padding: 0px;
+ vertical-align: top;
+}
+
+.directory td.entry {
+ white-space: nowrap;
+ padding-right: 6px;
+ padding-top: 3px;
+}
+
+.directory td.entry a {
+ outline:none;
+}
+
+.directory td.entry a img {
+ border: none;
+}
+
+.directory td.desc {
+ width: 100%;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 3px;
+ border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+ padding-left: 6px;
+ background-color: #F7F8FB;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+.directory .levels {
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ font-size: 9pt;
+}
+
+.directory .levels span {
+ cursor: pointer;
+ padding-left: 2px;
+ padding-right: 2px;
+ color: #3D578C;
+}
+
+.arrow {
+ color: #9CAFD4;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ font-size: 80%;
+ display: inline-block;
+ width: 16px;
+ height: 22px;
+}
+
+.icon {
+ font-family: Arial, Helvetica;
+ font-weight: bold;
+ font-size: 12px;
+ height: 14px;
+ width: 16px;
+ display: inline-block;
+ background-color: #728DC1;
+ color: white;
+ text-align: center;
+ border-radius: 4px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+
+.icona {
+ width: 24px;
+ height: 22px;
+ display: inline-block;
+}
+
+.iconfopen {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2folderopen.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.iconfclosed {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2folderclosed.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.icondoc {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('ftv2doc.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+table.directory {
+ font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+address {
+ font-style: normal;
+ color: #2A3D61;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #2D4068;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #374F7F;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+table.fieldtable {
+ /*width: 100%;*/
+ margin-bottom: 10px;
+ border: 1px solid #A8B8D9;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #A8B8D9;
+ border-bottom: 1px solid #A8B8D9;
+ vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+ padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #A8B8D9;
+ /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+ margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+ margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ font-size: 90%;
+ color: #253555;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ background-position: 0 -5px;
+ height:30px;
+ line-height:30px;
+ color:#8AA0CC;
+ border:solid 1px #C2CDE4;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+ color: #283A5D;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#6884BD;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.ingroups
+{
+ font-size: 8pt;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F9FAFC;
+ margin: 0px;
+ border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+dl.note
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #505050;
+}
+
+dl.todo
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.diagraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#334975;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: #F4F6FA;
+ border: 1px solid #D8DFEE;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 20px 10px 10px;
+ width: 200px;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ color: #4665A2;
+ border-bottom: 0 none;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+.inherit_header {
+ font-weight: bold;
+ color: gray;
+ cursor: pointer;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.inherit_header td {
+ padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+ display: none;
+}
+
+tr.heading h2 {
+ margin-top: 12px;
+ margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+ position: absolute;
+ display: none;
+}
+
+#powerTip {
+ cursor: default;
+ white-space: nowrap;
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 4px 4px 4px 4px;
+ box-shadow: 1px 1px 7px gray;
+ display: none;
+ font-size: smaller;
+ max-width: 80%;
+ opacity: 0.9;
+ padding: 1ex 1em 1em;
+ position: absolute;
+ z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+ color: grey;
+ font-style: italic;
+}
+
+#powerTip div.ttname a {
+ font-weight: bold;
+}
+
+#powerTip div.ttname {
+ font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+ color: #006318;
+}
+
+#powerTip div {
+ margin: 0px;
+ padding: 0px;
+ font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+ content: "";
+ position: absolute;
+ margin: 0px;
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.w:after, #powerTip.w:before,
+#powerTip.e:after, #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+}
+
+#powerTip.n:after, #powerTip.s:after,
+#powerTip.w:after, #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+ border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before, #powerTip.s:before,
+#powerTip.w:before, #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+ border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+ top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+ border-top-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+#powerTip.n:before {
+ border-top-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+ left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+ right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+ left: 14px;
+}
+
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+ border-bottom-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+ border-bottom-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+ left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+ right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+ left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+ left: 100%;
+}
+#powerTip.e:after {
+ border-left-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.e:before {
+ border-left-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+ right: 100%;
+}
+#powerTip.w:after {
+ border-right-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.w:before {
+ border-right-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+ at media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+}
+
diff --git a/testing/html/doxygen.png b/testing/html/doxygen.png
new file mode 100644
index 0000000..3ff17d8
Binary files /dev/null and b/testing/html/doxygen.png differ
diff --git a/testing/html/dynsections.js b/testing/html/dynsections.js
new file mode 100644
index 0000000..85e1836
--- /dev/null
+++ b/testing/html/dynsections.js
@@ -0,0 +1,97 @@
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+ content.hide();
+ summary.show();
+ $(linkObj).addClass('closed').removeClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ content.show();
+ summary.hide();
+ $(linkObj).removeClass('closed').addClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+ return false;
+}
+
+function updateStripes()
+{
+ $('table.directory tr').
+ removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+ $('table.directory tr').each(function() {
+ var l = this.id.split('_').length-1;
+ var i = $('#img'+this.id.substring(3));
+ var a = $('#arr'+this.id.substring(3));
+ if (l<level+1) {
+ i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+ a.html('▼');
+ $(this).show();
+ } else if (l==level+1) {
+ i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+ a.html('►');
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+ updateStripes();
+}
+
+function toggleFolder(id)
+{
+ // the clicked row
+ var currentRow = $('#row_'+id);
+
+ // all rows after the clicked row
+ var rows = currentRow.nextAll("tr");
+
+ var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+ // only match elements AFTER this one (can't hide elements before)
+ var childRows = rows.filter(function() { return this.id.match(re); });
+
+ // first row is visible we are HIDING
+ if (childRows.filter(':first').is(':visible')===true) {
+ // replace down arrow by right arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ currentRowSpans.filter(".arrow").html('►');
+ rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+ } else { // we are SHOWING
+ // replace right arrow by down arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+ currentRowSpans.filter(".arrow").html('▼');
+ // replace down arrows by right arrows for child rows
+ var childRowsSpans = childRows.find("span");
+ childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ childRowsSpans.filter(".arrow").html('►');
+ childRows.show(); //show all children
+ }
+ updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+ var rows = $('tr.inherit.'+id);
+ var img = $('tr.inherit_header.'+id+' img');
+ var src = $(img).attr('src');
+ if (rows.filter(':first').is(':visible')===true) {
+ rows.css('display','none');
+ $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ rows.css('display','table-row'); // using show() causes jump in firefox
+ $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+}
+
diff --git a/testing/html/files.html b/testing/html/files.html
new file mode 100644
index 0000000..4047cd6
--- /dev/null
+++ b/testing/html/files.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: File List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+</div><!-- top -->
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">File List</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here is a list of all files with brief descriptions:</div><div class="directory">
+<table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icondoc"></span><a class="el" href="063__bug__729092_8tcl.html" target="_self">063_bug_729092.tcl</a></td><td class="desc"></td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/ftv2blank.png b/testing/html/ftv2blank.png
new file mode 100644
index 0000000..63c605b
Binary files /dev/null and b/testing/html/ftv2blank.png differ
diff --git a/testing/html/ftv2doc.png b/testing/html/ftv2doc.png
new file mode 100644
index 0000000..17edabf
Binary files /dev/null and b/testing/html/ftv2doc.png differ
diff --git a/testing/html/ftv2folderclosed.png b/testing/html/ftv2folderclosed.png
new file mode 100644
index 0000000..bb8ab35
Binary files /dev/null and b/testing/html/ftv2folderclosed.png differ
diff --git a/testing/html/ftv2folderopen.png b/testing/html/ftv2folderopen.png
new file mode 100644
index 0000000..d6c7f67
Binary files /dev/null and b/testing/html/ftv2folderopen.png differ
diff --git a/testing/html/ftv2lastnode.png b/testing/html/ftv2lastnode.png
new file mode 100644
index 0000000..63c605b
Binary files /dev/null and b/testing/html/ftv2lastnode.png differ
diff --git a/testing/html/ftv2link.png b/testing/html/ftv2link.png
new file mode 100644
index 0000000..17edabf
Binary files /dev/null and b/testing/html/ftv2link.png differ
diff --git a/testing/html/ftv2mlastnode.png b/testing/html/ftv2mlastnode.png
new file mode 100644
index 0000000..0b63f6d
Binary files /dev/null and b/testing/html/ftv2mlastnode.png differ
diff --git a/testing/html/ftv2mnode.png b/testing/html/ftv2mnode.png
new file mode 100644
index 0000000..0b63f6d
Binary files /dev/null and b/testing/html/ftv2mnode.png differ
diff --git a/testing/html/ftv2node.png b/testing/html/ftv2node.png
new file mode 100644
index 0000000..63c605b
Binary files /dev/null and b/testing/html/ftv2node.png differ
diff --git a/testing/html/ftv2plastnode.png b/testing/html/ftv2plastnode.png
new file mode 100644
index 0000000..c6ee22f
Binary files /dev/null and b/testing/html/ftv2plastnode.png differ
diff --git a/testing/html/ftv2pnode.png b/testing/html/ftv2pnode.png
new file mode 100644
index 0000000..c6ee22f
Binary files /dev/null and b/testing/html/ftv2pnode.png differ
diff --git a/testing/html/ftv2splitbar.png b/testing/html/ftv2splitbar.png
new file mode 100644
index 0000000..fe895f2
Binary files /dev/null and b/testing/html/ftv2splitbar.png differ
diff --git a/testing/html/ftv2vertline.png b/testing/html/ftv2vertline.png
new file mode 100644
index 0000000..63c605b
Binary files /dev/null and b/testing/html/ftv2vertline.png differ
diff --git a/testing/html/index.html b/testing/html/index.html
new file mode 100644
index 0000000..5073706
--- /dev/null
+++ b/testing/html/index.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: Main Page</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li class="current"><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+</div><!-- top -->
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">My Project Documentation</div> </div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/jquery.js b/testing/html/jquery.js
new file mode 100644
index 0000000..c197801
--- /dev/null
+++ b/testing/html/jquery.js
@@ -0,0 +1,31 @@
+/*!
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/ [...]
+}else{--bw}}if(!bw){bC.resolveWith(bC,bx)}}else{if(bC!==bA){bC.resolveWith(bC,e?[bA]:[])}}return bE}});b.support=(function(){var bJ,bI,bF,bG,bx,bE,bA,bD,bz,bK,bB,by,bw,bv=av.createElement("div"),bH=av.documentElement;bv.setAttribute("className","t");bv.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElemen [...]
+if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);re [...]
+}b.event.add(this,"click._submit keypress._submit",function(bx){var bw=bx.target,bv=b.nodeName(bw,"input")||b.nodeName(bw,"button")?bw.form:L;if(bv&&!bv._submit_attached){b.event.add(bv,"submit._submit",function(e){if(this.parentNode&&!e.isTrigger){b.event.simulate("submit",this.parentNode,e,true)}});bv._submit_attached=true}})},teardown:function(){if(b.nodeName(this,"form")){return false}b.event.remove(this,"._submit")}}}if(!b.support.changeBubbles){b.event.special.change={setup:functio [...]
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU [...]
+},lt:function(bS,bR,e){return bR<e[3]-0},gt:function(bS,bR,e){return bR>e[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV<bU;bV++){if(bT[bV]===bS){return false}}return true}else{by.error(e)}}}},CHILD: [...]
+ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div<div>","</div>"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this [...]
+if(bA>0){if(bv!=="border"){for(;bx<e;bx++){if(!bv){bA-=parseFloat(b.css(by,"padding"+bz[bx]))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[bx]))||0}else{bA-=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}}}return bA+"px"}bA=Z(by,bw,bw);if(bA<0||bA==null){bA=by.style[bw]||0}bA=parseFloat(bA)||0;if(bv){for(;bx<e;bx++){bA+=parseFloat(b.css(by,"padding"+bz[bx]))||0;if(bv!=="padding"){bA+=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[ [...]
+}}}}})}var Q={},a8,m,aB=/^(?:toggle|show|hide)$/,aT=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,a3,aH=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],a4;b.fn.extend({show:function(bx,bA,bz){var bw,by;if(bx||bx===0){return this.animate(a0("show",3),bx,bA,bz)}else{for(var bv=0,e=this.length;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(!b._data(bw,"olddisplay")&&by==="none"){by=bw.style.d [...]
+})}})(window);
diff --git a/testing/html/namespacemembers.html b/testing/html/namespacemembers.html
new file mode 100644
index 0000000..5c0262f
--- /dev/null
+++ b/testing/html/namespacemembers.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: Namespace Members</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li class="current"><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow3" class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="namespacemembers.html"><span>All</span></a></li>
+ <li><a href="namespacemembers_func.html"><span>Functions</span></a></li>
+ </ul>
+ </div>
+</div><!-- top -->
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+<div class="textblock">Here is a list of all namespace members with links to the namespace documentation for each member:</div><ul>
+<li>classmethod()
+: <a class="el" href="namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1">oo::define</a>
+</li>
+<li>classvar()
+: <a class="el" href="namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c">oo::Helpers</a>
+</li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/namespacemembers_func.html b/testing/html/namespacemembers_func.html
new file mode 100644
index 0000000..f08dc76
--- /dev/null
+++ b/testing/html/namespacemembers_func.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: Namespace Members</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li class="current"><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow3" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespacemembers.html"><span>All</span></a></li>
+ <li class="current"><a href="namespacemembers_func.html"><span>Functions</span></a></li>
+ </ul>
+ </div>
+</div><!-- top -->
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+ <ul>
+<li>classmethod()
+: <a class="el" href="namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1">oo::define</a>
+</li>
+<li>classvar()
+: <a class="el" href="namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c">oo::Helpers</a>
+</li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/namespaceoo.html b/testing/html/namespaceoo.html
new file mode 100644
index 0000000..6cbf2f9
--- /dev/null
+++ b/testing/html/namespaceoo.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: oo Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+</div><!-- top -->
+<div class="header">
+ <div class="summary">
+<a href="#namespaces">Namespaces</a> </div>
+ <div class="headertitle">
+<div class="title">oo Namespace Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="namespaces"></a>
+Namespaces</h2></td></tr>
+<tr class="memitem:namespaceoo_1_1define"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1define.html">define</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:namespaceoo_1_1_helpers"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1_helpers.html">Helpers</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/namespaceoo_1_1_helpers.html b/testing/html/namespaceoo_1_1_helpers.html
new file mode 100644
index 0000000..5752f4c
--- /dev/null
+++ b/testing/html/namespaceoo_1_1_helpers.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: oo::Helpers Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="namespaceoo.html">oo</a></li><li class="navelem"><a class="el" href="namespaceoo_1_1_helpers.html">Helpers</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">oo::Helpers Namespace Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:a96c5b755588beb2e930cff23ce811d6c"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c">classvar</a> args</td></tr>
+<tr class="separator:a96c5b755588beb2e930cff23ce811d6c"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<h2 class="groupheader">Function Documentation</h2>
+<a class="anchor" id="a96c5b755588beb2e930cff23ce811d6c"></a>
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">oo::Helpers::classvar</td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">args </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+<p>Extension to TclOO to add static variables. Defines variables on the class instead of on the object. Can be used to enforce a limited number of instantiations. </p>
+
+</div>
+</div>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/namespaceoo_1_1define.html b/testing/html/namespaceoo_1_1define.html
new file mode 100644
index 0000000..7e2c5c4
--- /dev/null
+++ b/testing/html/namespaceoo_1_1define.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: oo::define Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="namespaceoo.html">oo</a></li><li class="navelem"><a class="el" href="namespaceoo_1_1define.html">define</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">oo::define Namespace Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:a89e7ea222a316f1926c1f9f30f2cc5c1"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1">classmethod</a> name?args??body?</td></tr>
+<tr class="separator:a89e7ea222a316f1926c1f9f30f2cc5c1"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<h2 class="groupheader">Function Documentation</h2>
+<a class="anchor" id="a89e7ea222a316f1926c1f9f30f2cc5c1"></a>
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">oo::define::classmethod</td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">name ?args? ?body? </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+<p>Extension to TclOO to add static methods. Defines the method on the class instead of on the object. Can be used for the creation of megawidgets using TclOO by overriding the unknown method to detect if the user is trying to instantiate a widget (because the method will be unknown and start with a dot). </p>
+
+</div>
+</div>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/namespaces.html b/testing/html/namespaces.html
new file mode 100644
index 0000000..a4299d8
--- /dev/null
+++ b/testing/html/namespaces.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<title>My Project: Namespace List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+ $(document).ready(function() { searchBox.OnSelectItem(0); });
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td style="padding-left: 0.5em;">
+ <div id="projectname">My Project
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.7 -->
+<script type="text/javascript">
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+</script>
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li class="current"><a href="namespaces.html"><span>Namespaces</span></a></li>
+ <li><a href="files.html"><span>Files</span></a></li>
+ <li>
+ <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.png"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
+ </span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li class="current"><a href="namespaces.html"><span>Namespace List</span></a></li>
+ <li><a href="namespacemembers.html"><span>Namespace Members</span></a></li>
+ </ul>
+ </div>
+</div><!-- top -->
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><sp [...]
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">Namespace List</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here is a list of all namespaces with brief descriptions:</div><div class="directory">
+<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span>]</div><table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceoo.html" target="_self">oo</a></td><td class="desc"></td></tr>
+<tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceoo_1_1define.html" target="_self">define</a></td><td class="desc"></td></tr>
+<tr id="row_0_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceoo_1_1_helpers.html" target="_self">Helpers</a></td><td class="desc"></td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated on Tue Aug 19 2014 12:23:54 for My Project by <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.7
+</small></address>
+</body>
+</html>
diff --git a/testing/html/nav_f.png b/testing/html/nav_f.png
new file mode 100644
index 0000000..72a58a5
Binary files /dev/null and b/testing/html/nav_f.png differ
diff --git a/testing/html/nav_g.png b/testing/html/nav_g.png
new file mode 100644
index 0000000..2093a23
Binary files /dev/null and b/testing/html/nav_g.png differ
diff --git a/testing/html/nav_h.png b/testing/html/nav_h.png
new file mode 100644
index 0000000..33389b1
Binary files /dev/null and b/testing/html/nav_h.png differ
diff --git a/testing/html/open.png b/testing/html/open.png
new file mode 100644
index 0000000..30f75c7
Binary files /dev/null and b/testing/html/open.png differ
diff --git a/testing/html/search/all_0.html b/testing/html/search/all_0.html
new file mode 100644
index 0000000..86e6c08
--- /dev/null
+++ b/testing/html/search/all_0.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/all_0.js b/testing/html/search/all_0.js
new file mode 100644
index 0000000..a6004cf
--- /dev/null
+++ b/testing/html/search/all_0.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+ ['063_5fbug_5f729092_2etcl',['063_bug_729092.tcl',['../063__bug__729092_8tcl.html',1,'']]]
+];
diff --git a/testing/html/search/all_1.html b/testing/html/search/all_1.html
new file mode 100644
index 0000000..122fcbb
--- /dev/null
+++ b/testing/html/search/all_1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/all_1.js b/testing/html/search/all_1.js
new file mode 100644
index 0000000..1a10142
--- /dev/null
+++ b/testing/html/search/all_1.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+ ['classmethod',['classmethod',['../namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1',1,'oo::define']]],
+ ['classvar',['classvar',['../namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c',1,'oo::Helpers']]]
+];
diff --git a/testing/html/search/all_2.html b/testing/html/search/all_2.html
new file mode 100644
index 0000000..6850d19
--- /dev/null
+++ b/testing/html/search/all_2.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/all_2.js b/testing/html/search/all_2.js
new file mode 100644
index 0000000..b6d7102
--- /dev/null
+++ b/testing/html/search/all_2.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+ ['define',['define',['../namespaceoo_1_1define.html',1,'oo']]],
+ ['helpers',['Helpers',['../namespaceoo_1_1_helpers.html',1,'oo']]],
+ ['oo',['oo',['../namespaceoo.html',1,'']]]
+];
diff --git a/testing/html/search/close.png b/testing/html/search/close.png
new file mode 100644
index 0000000..9342d3d
Binary files /dev/null and b/testing/html/search/close.png differ
diff --git a/testing/html/search/files_0.html b/testing/html/search/files_0.html
new file mode 100644
index 0000000..867c89d
--- /dev/null
+++ b/testing/html/search/files_0.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="files_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/files_0.js b/testing/html/search/files_0.js
new file mode 100644
index 0000000..a6004cf
--- /dev/null
+++ b/testing/html/search/files_0.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+ ['063_5fbug_5f729092_2etcl',['063_bug_729092.tcl',['../063__bug__729092_8tcl.html',1,'']]]
+];
diff --git a/testing/html/search/functions_0.html b/testing/html/search/functions_0.html
new file mode 100644
index 0000000..a3f28dc
--- /dev/null
+++ b/testing/html/search/functions_0.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/functions_0.js b/testing/html/search/functions_0.js
new file mode 100644
index 0000000..1a10142
--- /dev/null
+++ b/testing/html/search/functions_0.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+ ['classmethod',['classmethod',['../namespaceoo_1_1define.html#a89e7ea222a316f1926c1f9f30f2cc5c1',1,'oo::define']]],
+ ['classvar',['classvar',['../namespaceoo_1_1_helpers.html#a96c5b755588beb2e930cff23ce811d6c',1,'oo::Helpers']]]
+];
diff --git a/testing/html/search/mag_sel.png b/testing/html/search/mag_sel.png
new file mode 100644
index 0000000..81f6040
Binary files /dev/null and b/testing/html/search/mag_sel.png differ
diff --git a/testing/html/search/namespaces_0.html b/testing/html/search/namespaces_0.html
new file mode 100644
index 0000000..2336e75
--- /dev/null
+++ b/testing/html/search/namespaces_0.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.7"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="namespaces_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+createResults();
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+--></script>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/namespaces_0.js b/testing/html/search/namespaces_0.js
new file mode 100644
index 0000000..b6d7102
--- /dev/null
+++ b/testing/html/search/namespaces_0.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+ ['define',['define',['../namespaceoo_1_1define.html',1,'oo']]],
+ ['helpers',['Helpers',['../namespaceoo_1_1_helpers.html',1,'oo']]],
+ ['oo',['oo',['../namespaceoo.html',1,'']]]
+];
diff --git a/testing/html/search/nomatches.html b/testing/html/search/nomatches.html
new file mode 100644
index 0000000..b1ded27
--- /dev/null
+++ b/testing/html/search/nomatches.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="NoMatches">No Matches</div>
+</div>
+</body>
+</html>
diff --git a/testing/html/search/search.css b/testing/html/search/search.css
new file mode 100644
index 0000000..4d7612f
--- /dev/null
+++ b/testing/html/search/search.css
@@ -0,0 +1,271 @@
+/*---------------- Search Box */
+
+#FSearchBox {
+ float: left;
+}
+
+#MSearchBox {
+ white-space : nowrap;
+ position: absolute;
+ float: none;
+ display: inline;
+ margin-top: 8px;
+ right: 0px;
+ width: 170px;
+ z-index: 102;
+ background-color: white;
+}
+
+#MSearchBox .left
+{
+ display:block;
+ position:absolute;
+ left:10px;
+ width:20px;
+ height:19px;
+ background:url('search_l.png') no-repeat;
+ background-position:right;
+}
+
+#MSearchSelect {
+ display:block;
+ position:absolute;
+ width:20px;
+ height:19px;
+}
+
+.left #MSearchSelect {
+ left:4px;
+}
+
+.right #MSearchSelect {
+ right:5px;
+}
+
+#MSearchField {
+ display:block;
+ position:absolute;
+ height:19px;
+ background:url('search_m.png') repeat-x;
+ border:none;
+ width:111px;
+ margin-left:20px;
+ padding-left:4px;
+ color: #909090;
+ outline: none;
+ font: 9pt Arial, Verdana, sans-serif;
+}
+
+#FSearchBox #MSearchField {
+ margin-left:15px;
+}
+
+#MSearchBox .right {
+ display:block;
+ position:absolute;
+ right:10px;
+ top:0px;
+ width:20px;
+ height:19px;
+ background:url('search_r.png') no-repeat;
+ background-position:left;
+}
+
+#MSearchClose {
+ display: none;
+ position: absolute;
+ top: 4px;
+ background : none;
+ border: none;
+ margin: 0px 4px 0px 0px;
+ padding: 0px 0px;
+ outline: none;
+}
+
+.left #MSearchClose {
+ left: 6px;
+}
+
+.right #MSearchClose {
+ right: 2px;
+}
+
+.MSearchBoxActive #MSearchField {
+ color: #000000;
+}
+
+/*---------------- Search filter selection */
+
+#MSearchSelectWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid #90A5CE;
+ background-color: #F9FAFC;
+ z-index: 1;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+.SelectItem {
+ font: 8pt Arial, Verdana, sans-serif;
+ padding-left: 2px;
+ padding-right: 12px;
+ border: 0px;
+}
+
+span.SelectionMark {
+ margin-right: 4px;
+ font-family: monospace;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem {
+ display: block;
+ outline-style: none;
+ color: #000000;
+ text-decoration: none;
+ padding-left: 6px;
+ padding-right: 12px;
+}
+
+a.SelectItem:focus,
+a.SelectItem:active {
+ color: #000000;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem:hover {
+ color: #FFFFFF;
+ background-color: #3D578C;
+ outline-style: none;
+ text-decoration: none;
+ cursor: pointer;
+ display: block;
+}
+
+/*---------------- Search results window */
+
+iframe#MSearchResults {
+ width: 60ex;
+ height: 15em;
+}
+
+#MSearchResultsWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid #000;
+ background-color: #EEF1F7;
+}
+
+/* ----------------------------------- */
+
+
+#SRIndex {
+ clear:both;
+ padding-bottom: 15px;
+}
+
+.SREntry {
+ font-size: 10pt;
+ padding-left: 1ex;
+}
+
+.SRPage .SREntry {
+ font-size: 8pt;
+ padding: 1px 5px;
+}
+
+body.SRPage {
+ margin: 5px 2px;
+}
+
+.SRChildren {
+ padding-left: 3ex; padding-bottom: .5em
+}
+
+.SRPage .SRChildren {
+ display: none;
+}
+
+.SRSymbol {
+ font-weight: bold;
+ color: #425E97;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRScope {
+ display: block;
+ color: #425E97;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRSymbol:focus, a.SRSymbol:active,
+a.SRScope:focus, a.SRScope:active {
+ text-decoration: underline;
+}
+
+span.SRScope {
+ padding-left: 4px;
+}
+
+.SRPage .SRStatus {
+ padding: 2px 5px;
+ font-size: 8pt;
+ font-style: italic;
+}
+
+.SRResult {
+ display: none;
+}
+
+DIV.searchresults {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+/*---------------- External search page results */
+
+.searchresult {
+ background-color: #F0F3F8;
+}
+
+.pages b {
+ color: white;
+ padding: 5px 5px 3px 5px;
+ background-image: url("../tab_a.png");
+ background-repeat: repeat-x;
+ text-shadow: 0 1px 1px #000000;
+}
+
+.pages {
+ line-height: 17px;
+ margin-left: 4px;
+ text-decoration: none;
+}
+
+.hl {
+ font-weight: bold;
+}
+
+#searchresults {
+ margin-bottom: 20px;
+}
+
+.searchpages {
+ margin-top: 10px;
+}
+
diff --git a/testing/html/search/search.js b/testing/html/search/search.js
new file mode 100644
index 0000000..70cb40e
--- /dev/null
+++ b/testing/html/search/search.js
@@ -0,0 +1,799 @@
+// Search script generated by doxygen
+// Copyright (C) 2009 by Dimitri van Heesch.
+
+// The code in this file is loosly based on main.js, part of Natural Docs,
+// which is Copyright (C) 2003-2008 Greg Valure
+// Natural Docs is licensed under the GPL.
+
+var indexSectionsWithContent =
+{
+ 0: "0co",
+ 1: "o",
+ 2: "0",
+ 3: "c"
+};
+
+var indexSectionNames =
+{
+ 0: "all",
+ 1: "namespaces",
+ 2: "files",
+ 3: "functions"
+};
+
+function convertToId(search)
+{
+ var result = '';
+ for (i=0;i<search.length;i++)
+ {
+ var c = search.charAt(i);
+ var cn = c.charCodeAt(0);
+ if (c.match(/[a-z0-9\u0080-\uFFFF]/))
+ {
+ result+=c;
+ }
+ else if (cn<16)
+ {
+ result+="_0"+cn.toString(16);
+ }
+ else
+ {
+ result+="_"+cn.toString(16);
+ }
+ }
+ return result;
+}
+
+function getXPos(item)
+{
+ var x = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ x += item.offsetLeft;
+ item = item.offsetParent;
+ }
+ }
+ return x;
+}
+
+function getYPos(item)
+{
+ var y = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ y += item.offsetTop;
+ item = item.offsetParent;
+ }
+ }
+ return y;
+}
+
+/* A class handling everything associated with the search panel.
+
+ Parameters:
+ name - The name of the global variable that will be
+ storing this instance. Is needed to be able to set timeouts.
+ resultPath - path to use for external files
+*/
+function SearchBox(name, resultsPath, inFrame, label)
+{
+ if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
+
+ // ---------- Instance variables
+ this.name = name;
+ this.resultsPath = resultsPath;
+ this.keyTimeout = 0;
+ this.keyTimeoutLength = 500;
+ this.closeSelectionTimeout = 300;
+ this.lastSearchValue = "";
+ this.lastResultsPage = "";
+ this.hideTimeout = 0;
+ this.searchIndex = 0;
+ this.searchActive = false;
+ this.insideFrame = inFrame;
+ this.searchLabel = label;
+
+ // ----------- DOM Elements
+
+ this.DOMSearchField = function()
+ { return document.getElementById("MSearchField"); }
+
+ this.DOMSearchSelect = function()
+ { return document.getElementById("MSearchSelect"); }
+
+ this.DOMSearchSelectWindow = function()
+ { return document.getElementById("MSearchSelectWindow"); }
+
+ this.DOMPopupSearchResults = function()
+ { return document.getElementById("MSearchResults"); }
+
+ this.DOMPopupSearchResultsWindow = function()
+ { return document.getElementById("MSearchResultsWindow"); }
+
+ this.DOMSearchClose = function()
+ { return document.getElementById("MSearchClose"); }
+
+ this.DOMSearchBox = function()
+ { return document.getElementById("MSearchBox"); }
+
+ // ------------ Event Handlers
+
+ // Called when focus is added or removed from the search field.
+ this.OnSearchFieldFocus = function(isActive)
+ {
+ this.Activate(isActive);
+ }
+
+ this.OnSearchSelectShow = function()
+ {
+ var searchSelectWindow = this.DOMSearchSelectWindow();
+ var searchField = this.DOMSearchSelect();
+
+ if (this.insideFrame)
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ left += searchField.offsetWidth + 6;
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ left -= searchSelectWindow.offsetWidth;
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+ else
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+
+ // stop selection hide timer
+ if (this.hideTimeout)
+ {
+ clearTimeout(this.hideTimeout);
+ this.hideTimeout=0;
+ }
+ return false; // to avoid "image drag" default event
+ }
+
+ this.OnSearchSelectHide = function()
+ {
+ this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
+ this.closeSelectionTimeout);
+ }
+
+ // Called when the content of the search field is changed.
+ this.OnSearchFieldChange = function(evt)
+ {
+ if (this.keyTimeout) // kill running timer
+ {
+ clearTimeout(this.keyTimeout);
+ this.keyTimeout = 0;
+ }
+
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 || e.keyCode==13)
+ {
+ if (e.shiftKey==1)
+ {
+ this.OnSearchSelectShow();
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ child.focus();
+ return;
+ }
+ }
+ return;
+ }
+ else if (window.frames.MSearchResults.searchResults)
+ {
+ var elem = window.frames.MSearchResults.searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+ }
+ else if (e.keyCode==27) // Escape out of the search field
+ {
+ this.DOMSearchField().blur();
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ this.Activate(false);
+ return;
+ }
+
+ // strip whitespaces
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+
+ if (searchValue != this.lastSearchValue) // search value has changed
+ {
+ if (searchValue != "") // non-empty search
+ {
+ // set timer for search update
+ this.keyTimeout = setTimeout(this.name + '.Search()',
+ this.keyTimeoutLength);
+ }
+ else // empty search field
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ }
+ }
+ }
+
+ this.SelectItemCount = function(id)
+ {
+ var count=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ this.SelectItemSet = function(id)
+ {
+ var i,j=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ var node = child.firstChild;
+ if (j==id)
+ {
+ node.innerHTML='•';
+ }
+ else
+ {
+ node.innerHTML=' ';
+ }
+ j++;
+ }
+ }
+ }
+
+ // Called when an search filter selection is made.
+ // set item with index id as the active item
+ this.OnSelectItem = function(id)
+ {
+ this.searchIndex = id;
+ this.SelectItemSet(id);
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+ if (searchValue!="" && this.searchActive) // something was found -> do a search
+ {
+ this.Search();
+ }
+ }
+
+ this.OnSearchSelectKey = function(evt)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
+ {
+ this.searchIndex++;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==38 && this.searchIndex>0) // Up
+ {
+ this.searchIndex--;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==13 || e.keyCode==27)
+ {
+ this.OnSelectItem(this.searchIndex);
+ this.CloseSelectionWindow();
+ this.DOMSearchField().focus();
+ }
+ return false;
+ }
+
+ // --------- Actions
+
+ // Closes the results window.
+ this.CloseResultsWindow = function()
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.Activate(false);
+ }
+
+ this.CloseSelectionWindow = function()
+ {
+ this.DOMSearchSelectWindow().style.display = 'none';
+ }
+
+ // Performs a search.
+ this.Search = function()
+ {
+ this.keyTimeout = 0;
+
+ // strip leading whitespace
+ var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
+
+ var code = searchValue.toLowerCase().charCodeAt(0);
+ var idxChar = searchValue.substr(0, 1).toLowerCase();
+ if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
+ {
+ idxChar = searchValue.substr(0, 2);
+ }
+
+ var resultsPage;
+ var resultsPageWithSearch;
+ var hasResultsPage;
+
+ var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
+ if (idx!=-1)
+ {
+ var hexCode=idx.toString(16);
+ resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
+ resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
+ hasResultsPage = true;
+ }
+ else // nothing available for this search term
+ {
+ resultsPage = this.resultsPath + '/nomatches.html';
+ resultsPageWithSearch = resultsPage;
+ hasResultsPage = false;
+ }
+
+ window.frames.MSearchResults.location = resultsPageWithSearch;
+ var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
+
+ if (domPopupSearchResultsWindow.style.display!='block')
+ {
+ var domSearchBox = this.DOMSearchBox();
+ this.DOMSearchClose().style.display = 'inline';
+ if (this.insideFrame)
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ domPopupSearchResultsWindow.style.position = 'relative';
+ domPopupSearchResultsWindow.style.display = 'block';
+ var width = document.body.clientWidth - 8; // the -8 is for IE :-(
+ domPopupSearchResultsWindow.style.width = width + 'px';
+ domPopupSearchResults.style.width = width + 'px';
+ }
+ else
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
+ var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
+ domPopupSearchResultsWindow.style.display = 'block';
+ left -= domPopupSearchResults.offsetWidth;
+ domPopupSearchResultsWindow.style.top = top + 'px';
+ domPopupSearchResultsWindow.style.left = left + 'px';
+ }
+ }
+
+ this.lastSearchValue = searchValue;
+ this.lastResultsPage = resultsPage;
+ }
+
+ // -------- Activation Functions
+
+ // Activates or deactivates the search panel, resetting things to
+ // their default values if necessary.
+ this.Activate = function(isActive)
+ {
+ if (isActive || // open it
+ this.DOMPopupSearchResultsWindow().style.display == 'block'
+ )
+ {
+ this.DOMSearchBox().className = 'MSearchBoxActive';
+
+ var searchField = this.DOMSearchField();
+
+ if (searchField.value == this.searchLabel) // clear "Search" term upon entry
+ {
+ searchField.value = '';
+ this.searchActive = true;
+ }
+ }
+ else if (!isActive) // directly remove the panel
+ {
+ this.DOMSearchBox().className = 'MSearchBoxInactive';
+ this.DOMSearchField().value = this.searchLabel;
+ this.searchActive = false;
+ this.lastSearchValue = ''
+ this.lastResultsPage = '';
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// The class that handles everything on the search results page.
+function SearchResults(name)
+{
+ // The number of matches from the last run of <Search()>.
+ this.lastMatchCount = 0;
+ this.lastKey = 0;
+ this.repeatOn = false;
+
+ // Toggles the visibility of the passed element ID.
+ this.FindChildElement = function(id)
+ {
+ var parentElement = document.getElementById(id);
+ var element = parentElement.firstChild;
+
+ while (element && element!=parentElement)
+ {
+ if (element.nodeName == 'DIV' && element.className == 'SRChildren')
+ {
+ return element;
+ }
+
+ if (element.nodeName == 'DIV' && element.hasChildNodes())
+ {
+ element = element.firstChild;
+ }
+ else if (element.nextSibling)
+ {
+ element = element.nextSibling;
+ }
+ else
+ {
+ do
+ {
+ element = element.parentNode;
+ }
+ while (element && element!=parentElement && !element.nextSibling);
+
+ if (element && element!=parentElement)
+ {
+ element = element.nextSibling;
+ }
+ }
+ }
+ }
+
+ this.Toggle = function(id)
+ {
+ var element = this.FindChildElement(id);
+ if (element)
+ {
+ if (element.style.display == 'block')
+ {
+ element.style.display = 'none';
+ }
+ else
+ {
+ element.style.display = 'block';
+ }
+ }
+ }
+
+ // Searches for the passed string. If there is no parameter,
+ // it takes it from the URL query.
+ //
+ // Always returns true, since other documents may try to call it
+ // and that may or may not be possible.
+ this.Search = function(search)
+ {
+ if (!search) // get search word from URL
+ {
+ search = window.location.search;
+ search = search.substring(1); // Remove the leading '?'
+ search = unescape(search);
+ }
+
+ search = search.replace(/^ +/, ""); // strip leading spaces
+ search = search.replace(/ +$/, ""); // strip trailing spaces
+ search = search.toLowerCase();
+ search = convertToId(search);
+
+ var resultRows = document.getElementsByTagName("div");
+ var matches = 0;
+
+ var i = 0;
+ while (i < resultRows.length)
+ {
+ var row = resultRows.item(i);
+ if (row.className == "SRResult")
+ {
+ var rowMatchName = row.id.toLowerCase();
+ rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
+
+ if (search.length<=rowMatchName.length &&
+ rowMatchName.substr(0, search.length)==search)
+ {
+ row.style.display = 'block';
+ matches++;
+ }
+ else
+ {
+ row.style.display = 'none';
+ }
+ }
+ i++;
+ }
+ document.getElementById("Searching").style.display='none';
+ if (matches == 0) // no results
+ {
+ document.getElementById("NoMatches").style.display='block';
+ }
+ else // at least one result
+ {
+ document.getElementById("NoMatches").style.display='none';
+ }
+ this.lastMatchCount = matches;
+ return true;
+ }
+
+ // return the first item with index index or higher that is visible
+ this.NavNext = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index++;
+ }
+ return focusItem;
+ }
+
+ this.NavPrev = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index--;
+ }
+ return focusItem;
+ }
+
+ this.ProcessKeys = function(e)
+ {
+ if (e.type == "keydown")
+ {
+ this.repeatOn = false;
+ this.lastKey = e.keyCode;
+ }
+ else if (e.type == "keypress")
+ {
+ if (!this.repeatOn)
+ {
+ if (this.lastKey) this.repeatOn = true;
+ return false; // ignore first keypress after keydown
+ }
+ }
+ else if (e.type == "keyup")
+ {
+ this.lastKey = 0;
+ this.repeatOn = false;
+ }
+ return this.lastKey!=0;
+ }
+
+ this.Nav = function(evt,itemIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ var newIndex = itemIndex-1;
+ var focusItem = this.NavPrev(newIndex);
+ if (focusItem)
+ {
+ var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
+ if (child && child.style.display == 'block') // children visible
+ {
+ var n=0;
+ var tmpElem;
+ while (1) // search for last child
+ {
+ tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
+ if (tmpElem)
+ {
+ focusItem = tmpElem;
+ }
+ else // found it!
+ {
+ break;
+ }
+ n++;
+ }
+ }
+ }
+ if (focusItem)
+ {
+ focusItem.focus();
+ }
+ else // return focus to search field
+ {
+ parent.document.getElementById("MSearchField").focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = itemIndex+1;
+ var focusItem;
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem && elem.style.display == 'block') // children visible
+ {
+ focusItem = document.getElementById('Item'+itemIndex+'_c0');
+ }
+ if (!focusItem) focusItem = this.NavNext(newIndex);
+ if (focusItem) focusItem.focus();
+ }
+ else if (this.lastKey==39) // Right
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'block';
+ }
+ else if (this.lastKey==37) // Left
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'none';
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+
+ this.NavChild = function(evt,itemIndex,childIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ if (childIndex>0)
+ {
+ var newIndex = childIndex-1;
+ document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
+ }
+ else // already at first child, jump to parent
+ {
+ document.getElementById('Item'+itemIndex).focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = childIndex+1;
+ var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
+ if (!elem) // last child, jump to parent next parent
+ {
+ elem = this.NavNext(itemIndex+1);
+ }
+ if (elem)
+ {
+ elem.focus();
+ }
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+}
+
+function setKeyActions(elem,action)
+{
+ elem.setAttribute('onkeydown',action);
+ elem.setAttribute('onkeypress',action);
+ elem.setAttribute('onkeyup',action);
+}
+
+function setClassAttr(elem,attr)
+{
+ elem.setAttribute('class',attr);
+ elem.setAttribute('className',attr);
+}
+
+function createResults()
+{
+ var results = document.getElementById("SRResults");
+ for (var e=0; e<searchData.length; e++)
+ {
+ var id = searchData[e][0];
+ var srResult = document.createElement('div');
+ srResult.setAttribute('id','SR_'+id);
+ setClassAttr(srResult,'SRResult');
+ var srEntry = document.createElement('div');
+ setClassAttr(srEntry,'SREntry');
+ var srLink = document.createElement('a');
+ srLink.setAttribute('id','Item'+e);
+ setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
+ setClassAttr(srLink,'SRSymbol');
+ srLink.innerHTML = searchData[e][1][0];
+ srEntry.appendChild(srLink);
+ if (searchData[e][1].length==2) // single result
+ {
+ srLink.setAttribute('href',searchData[e][1][1][0]);
+ if (searchData[e][1][1][1])
+ {
+ srLink.setAttribute('target','_parent');
+ }
+ var srScope = document.createElement('span');
+ setClassAttr(srScope,'SRScope');
+ srScope.innerHTML = searchData[e][1][1][2];
+ srEntry.appendChild(srScope);
+ }
+ else // multiple results
+ {
+ srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
+ var srChildren = document.createElement('div');
+ setClassAttr(srChildren,'SRChildren');
+ for (var c=0; c<searchData[e][1].length-1; c++)
+ {
+ var srChild = document.createElement('a');
+ srChild.setAttribute('id','Item'+e+'_c'+c);
+ setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
+ setClassAttr(srChild,'SRScope');
+ srChild.setAttribute('href',searchData[e][1][c+1][0]);
+ if (searchData[e][1][c+1][1])
+ {
+ srChild.setAttribute('target','_parent');
+ }
+ srChild.innerHTML = searchData[e][1][c+1][2];
+ srChildren.appendChild(srChild);
+ }
+ srEntry.appendChild(srChildren);
+ }
+ srResult.appendChild(srEntry);
+ results.appendChild(srResult);
+ }
+}
+
diff --git a/testing/html/search/search_l.png b/testing/html/search/search_l.png
new file mode 100644
index 0000000..c872f4d
Binary files /dev/null and b/testing/html/search/search_l.png differ
diff --git a/testing/html/search/search_m.png b/testing/html/search/search_m.png
new file mode 100644
index 0000000..b429a16
Binary files /dev/null and b/testing/html/search/search_m.png differ
diff --git a/testing/html/search/search_r.png b/testing/html/search/search_r.png
new file mode 100644
index 0000000..97ee8b4
Binary files /dev/null and b/testing/html/search/search_r.png differ
diff --git a/testing/html/sync_off.png b/testing/html/sync_off.png
new file mode 100644
index 0000000..3b443fc
Binary files /dev/null and b/testing/html/sync_off.png differ
diff --git a/testing/html/sync_on.png b/testing/html/sync_on.png
new file mode 100644
index 0000000..e08320f
Binary files /dev/null and b/testing/html/sync_on.png differ
diff --git a/testing/html/tab_a.png b/testing/html/tab_a.png
new file mode 100644
index 0000000..3b725c4
Binary files /dev/null and b/testing/html/tab_a.png differ
diff --git a/testing/html/tab_b.png b/testing/html/tab_b.png
new file mode 100644
index 0000000..e2b4a86
Binary files /dev/null and b/testing/html/tab_b.png differ
diff --git a/testing/html/tab_h.png b/testing/html/tab_h.png
new file mode 100644
index 0000000..fd5cb70
Binary files /dev/null and b/testing/html/tab_h.png differ
diff --git a/testing/html/tab_s.png b/testing/html/tab_s.png
new file mode 100644
index 0000000..ab478c9
Binary files /dev/null and b/testing/html/tab_s.png differ
diff --git a/testing/html/tabs.css b/testing/html/tabs.css
new file mode 100644
index 0000000..9cf578f
--- /dev/null
+++ b/testing/html/tabs.css
@@ -0,0 +1,60 @@
+.tabs, .tabs2, .tabs3 {
+ background-image: url('tab_b.png');
+ width: 100%;
+ z-index: 101;
+ font-size: 13px;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+.tabs2 {
+ font-size: 10px;
+}
+.tabs3 {
+ font-size: 9px;
+}
+
+.tablist {
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ background-image: url('tab_b.png');
+ line-height: 36px;
+ list-style: none;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 20px;
+ font-weight: bold;
+ background-image:url('tab_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color: #283A5D;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding: 0 10px;
+}
+
+.tablist a:hover {
+ background-image: url('tab_h.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+ text-decoration: none;
+}
+
+.tablist li.current a {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
diff --git a/testing/runtests.pl b/testing/runtests.pl
new file mode 100755
index 0000000..6b705aa
--- /dev/null
+++ b/testing/runtests.pl
@@ -0,0 +1,252 @@
+#!/usr/bin/perl
+
+# perl script to execute doxygen's regression test suite.
+#
+# Copyright (C) 1997-2014 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+use Test::More;
+use File::Path qw(make_path remove_tree);
+use File::Copy qw(copy);
+
+my $Test = Test::Builder->new;
+my $opt_doxygen_exe = 'doxygen';
+my $opt_xmllint_exe = 'xmllint';
+my $opt_updateref = '';
+my @opt_test_ids;
+my $opt_all = '';
+
+GetOptions( 'updateref' => \$opt_updateref,
+ 'doxygen=s' => \$opt_doxygen_exe,
+ 'xmllint=s' => \$opt_xmllint_exe,
+ 'id=i' => \@opt_test_ids,
+ 'all' => \$opt_all
+ );
+
+sub read_two_files {
+ my $first = shift;
+ my $second = shift;
+ my $filter = shift;
+ my $success = 1;
+ my @errors;
+
+ unless (open FIRST, "$first") {
+ $success = 0;
+ push @errors, "$first absent";
+ }
+ unless (open SECOND, "$second") {
+ $success = 0;
+ push @errors, "$second absent";
+ }
+ return ($success, @errors) unless $success;
+
+ my $first_lines = join "",<FIRST>;
+ my $second_lines = join "",<SECOND>;
+
+ close FIRST;
+ close SECOND;
+
+ return ($success, $first_lines, $second_lines);
+}
+
+sub compare_ok {
+ my $got_file = shift;
+ my $expected_file = shift;
+ my $name = shift;
+ my @read_result = read_two_files($got_file, $expected_file);
+ my $files_exist = shift @read_result;
+
+ if ($files_exist) {
+ my ($got, $expected) = @read_result;
+ my $diff = `diff -u $got_file $expected_file`;
+ my $failed = length $diff;
+ return ($failed,"Difference between generated output and reference:\n$diff");
+ }
+ else {
+ return (1,join "\n", @read_result);
+ }
+}
+
+sub chop_volatile {
+ my $line = shift;
+ $line =~ s/version="\d\.\d.\d+"/version=""/g; # strip version
+ $line =~ s/file=".*\/(.*)"/file="$1"/g; # strip location
+ return $line;
+}
+
+sub get_config {
+ my $file = shift;
+ my %config;
+ open F,"<$file";
+ while (<F>) {
+ if (/\/\/\s*(\S+):\s*(.*)$/) {
+ my $key = $1;
+ my $val = $2;
+ chomp $val;
+ $config{$key} = [] unless defined $config{$key};
+ push @{$config{$key}},$val;
+ }
+ }
+ return %config;
+}
+
+sub perform_test {
+ my $test_file = shift;
+ my %config = get_config($test_file);
+ my $test_name = "[$test_file]: $config{'objective'}[0]";
+ my $test_id = $test_file;
+ $test_id =~ s/^(\d+).*$/$1/;
+ my $test_out = "test_output_${test_id}";
+
+ if (scalar($config{'check'})==0) {
+ $Test->ok(0, $test_name);
+ $Test->diag("Test doesn't specify any files to check");
+ return;
+ }
+
+ # prepare test environment
+ remove_tree("$test_out");
+ make_path("$test_out");
+ copy("Doxyfile","$test_out");
+ open(F,">>$test_out/Doxyfile");
+ print F "INPUT = $test_file\n";
+ print F "XML_OUTPUT = $test_out/out\n";
+ foreach my $cfg (@{$config{'config'}}) {
+ print F "$cfg\n";
+ }
+ close(F);
+
+ # run doxygen
+ if (system("$opt_doxygen_exe $test_out/Doxyfile")!=0) {
+ $Test->ok(0, $test_name);
+ $Test->diag("Failed to run doxygen");
+ return;
+ }
+
+ # look for files to check against the reference
+ foreach my $fn (@{$config{'check'}}) {
+ if (!-f "$test_out/out/$fn") {
+ $Test->ok(0, $test_name);
+ $Test->diag("Non-existing file $test_out/out/$fn after 'check:' statement");
+ return;
+ }
+ # run xmllint on the output file
+ my @lines = `$opt_xmllint_exe --format --noblanks --nowarning $test_out/out/$fn`;
+ if (scalar(@lines)>0 && open(F,">$test_out/$fn")) {
+ foreach my $line (@lines) {
+ print F chop_volatile($line);
+ }
+ close(F);
+ } else {
+ $Test->ok(0, $test_name);
+ $Test->diag("Failed to run xmllint on the doxygen output file $test_out/out/$fn");
+ }
+ my ($failed,$msg) = compare_ok("$test_out/$fn","$test_id/$fn",$test_name);
+ if ($failed) {
+ $Test->ok(0, $test_name);
+ $Test->diag($msg);
+ return;
+ }
+ }
+
+ # test passed
+ remove_tree("$test_out");
+ $Test->ok(1, $test_name);
+}
+
+sub update_test {
+ my $test_file = shift;
+ my %config = get_config($test_file);
+ my $test_name = "[$test_file]: $config{'objective'}[0]";
+ my $test_id = $test_file;
+ $test_id =~ s/^(\d+).*$/$1/;
+ my $test_out = $test_id;
+
+ # prepare reference environment
+ remove_tree("$test_out");
+ make_path("$test_out");
+ copy("Doxyfile","$test_out");
+ open(F,">>$test_out/Doxyfile");
+ print F "INPUT = $test_file\n";
+ print F "XML_OUTPUT = $test_out/out\n";
+ foreach my $cfg (@{$config{'config'}}) {
+ print F "$cfg\n";
+ }
+ close(F);
+
+ print "Updating reference for $test_name\n";
+
+ # run doxygen
+ if (system("$opt_doxygen_exe $test_out/Doxyfile")!=0) {
+ print("Error: failed to run doxygen");
+ return;
+ }
+ my $err=0;
+
+ # look for files to prepare as reference
+ foreach my $fn (@{$config{'check'}}) {
+ if (!-f "$test_out/out/$fn") {
+ printf("Error: Non-existing file $test_out/out/$fn after 'check:' statement\n");
+ $err=1;
+ }
+ # run xmllint on the output file
+ if (!$err) {
+ my @lines = `$opt_xmllint_exe --format --noblanks --nowarning $test_out/out/$fn`;
+ if (scalar(@lines)>0 && open(F,">$test_out/$fn")) {
+ foreach my $line (@lines) {
+ print F chop_volatile($line);
+ }
+ close(F);
+ } else {
+ printf("Error: Failed to run xmllint on the doxygen output file $test_out/out/$fn\n");
+ $err=1;
+ }
+ }
+ }
+
+ if (!$err) {
+ # clean-up
+ remove_tree("$test_out/out");
+ unlink("$test_out/Doxyfile");
+ }
+}
+
+# get the tests
+my @tests;
+if (scalar(@opt_test_ids)==0 && $opt_updateref && !$opt_all) {
+ printf("Error: updateref option requires -id to update a test or -all to update all\n");
+ exit(1);
+}
+if (scalar(@opt_test_ids)>0) {
+ foreach my $t (@opt_test_ids) {
+ push @tests, glob("${t}_* 0${t}_* 00${t}_*");
+ }
+} else {
+ @tests = glob('[0-9][0-9][0-9]_*');
+}
+
+if ($opt_updateref) {
+ # update reference
+ foreach my $test (@tests) {
+ update_test($test);
+ }
+} else {
+ # run tests
+ plan tests => scalar(@tests);
+ foreach my $test (@tests) {
+ perform_test($test);
+ }
+}
+
diff --git a/testing/sample.bib b/testing/sample.bib
new file mode 100644
index 0000000..436e8cd
--- /dev/null
+++ b/testing/sample.bib
@@ -0,0 +1,7 @@
+ at book{knuth79,
+ author = "Donald E. Knuth",
+ title = "Tex and Metafont, New Directions in Typesetting",
+ year = "1979",
+ publisher = "American Mathematical Society and Digital Press",
+ address = "Stanford"
+}
diff --git a/testing/sample.html b/testing/sample.html
new file mode 100644
index 0000000..159202e
--- /dev/null
+++ b/testing/sample.html
@@ -0,0 +1 @@
+<h1>Hello world</h1>
diff --git a/testing/sample.png b/testing/sample.png
new file mode 100644
index 0000000..3ff17d8
Binary files /dev/null and b/testing/sample.png differ
diff --git a/testing/sample.tex b/testing/sample.tex
new file mode 100644
index 0000000..9a1717e
--- /dev/null
+++ b/testing/sample.tex
@@ -0,0 +1 @@
+\section{Hello world}
diff --git a/testing/snippet_test.cpp b/testing/snippet_test.cpp
new file mode 100644
index 0000000..763f6be
--- /dev/null
+++ b/testing/snippet_test.cpp
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+void main()
+{
+ int i,n,temp,j,arr[25];
+ printf("Enter the number of elements in the Array: ");
+ scanf("%d",&n);
+ printf("\nEnter the elements:\n\n");
+
+ /* [input] */
+ for(i=0 ; i<n ; i++)
+ {
+ printf(" Array[%d] = ",i);
+ scanf("%d",&arr[i]);
+ }
+ /* [input] */
+
+ // [bubble]
+ for(i=0 ; i<n ; i++)
+ {
+ for(j=0 ; j<n-i-1 ; j++)
+ {
+ if(arr[j]>arr[j+1]) //Swapping Condition is Checked
+ {
+ temp=arr[j];
+ arr[j]=arr[j+1];
+ arr[j+1]=temp;
+ }
+ }
+ }
+ // [bubble]
+
+ printf("\nThe Sorted Array is:\n\n");
+ /* [output] */
+ for(i=0 ; i<n ; i++)
+ {
+ printf(" %4d",arr[i]);
+ }
+ /* [output] */
+}
diff --git a/testing/testsqlite3.py b/testing/testsqlite3.py
new file mode 100755
index 0000000..e8ab16c
--- /dev/null
+++ b/testing/testsqlite3.py
@@ -0,0 +1,146 @@
+#! /usr/bin/python
+from xml.etree import cElementTree as ET
+import os
+import sqlite3
+import sys
+import getopt
+
+# map XML attributes/elements to SQL rows
+# --POC: iterate through the children and attributes of the memberdef elelement
+# and search it in doxygen_sqlite3.db
+
+g_conn=None
+val=[]
+def print_unprocessed_attributes(node):
+ for key in node.attrib:
+ print "WARNING: '%s' has unprocessed attr '%s'" % (node.tag,key)
+
+def extract_attribute(node,attribute,pnl):
+ if not attribute in node.attrib:
+ return
+ pnl.append("%s = ?" % attribute)
+ val.append(node.attrib[attribute])
+ node.attrib.pop(attribute)
+
+def extract_element(node,chld,pnl):
+ # deal with <tag />
+ if chld.text == None:
+ if len(chld.attrib)==0:
+ node.remove(chld)
+ return
+
+ a=chld.text.strip()
+ if not a == "":
+ pnl.append("%s =?" % chld.tag)
+ val.append(chld.text.strip())
+ else:
+ pnl.append("%s IS NULL OR %s = ''" % (chld.tag,chld.tag))
+ node.remove(chld)
+
+def process_memberdef(node):
+ q=[]
+ for chld in node.getchildren():
+ if chld.tag == "referencedby":
+ continue
+ if chld.tag == "references":
+ continue
+ if chld.tag == "param":
+ continue
+ if chld.tag == "type":
+ continue
+ if chld.tag == "location":
+ extract_attribute(chld,"line",q)
+ extract_attribute(chld,"column",q)
+ extract_attribute(chld,"bodystart",q)
+ extract_attribute(chld,"bodyend",q)
+
+ q.append("id_bodyfile=(select id from files where name=?)")
+ val.append(chld.attrib["bodyfile"])
+ chld.attrib.pop("bodyfile")
+
+ q.append("id_file=(select id from files where name=?)")
+ val.append(chld.attrib["file"])
+ chld.attrib.pop("file")
+
+ print_unprocessed_attributes(chld)
+ if len(chld.attrib) == 0:
+ node.remove(chld)
+ else:
+ extract_element(node,chld,q)
+
+ for chld in node.getchildren():
+ print "WARNING: '%s' has unprocessed child elem '%s'" % (node.tag,chld.tag)
+
+ extract_attribute(node,"kind",q)
+ extract_attribute(node,"prot",q)
+ extract_attribute(node,"static",q)
+ extract_attribute(node,"mutable",q)
+ extract_attribute(node,"const",q)
+ extract_attribute(node,"virt",q)
+ extract_attribute(node,"explicit",q)
+ extract_attribute(node,"inline",q)
+
+ q.append("refid=?")
+ val.append(node.attrib['id'])
+ node.attrib.pop('id')
+
+ print_unprocessed_attributes(node)
+
+ query="SELECT * FROM memberdef WHERE %s" % " AND ".join(q)
+ r=[]
+ try:
+ r = g_conn.execute(query,val).fetchall()
+ except sqlite3.OperationalError,e:
+ print "SQL_ERROR:%s"%e
+
+ del val[:]
+ if not len(r) > 0:
+ print "TEST_ERROR: Member not found in SQL DB"
+
+
+def load_xml(name):
+ context = ET.iterparse(name, events=("start", "end"))
+ event, root = context.next()
+ for event, elem in context:
+ if event == "end" and elem.tag == "memberdef":
+ process_memberdef(elem)
+ print "\n== Unprocessed XML =="
+# ET.dump(root)
+
+
+def open_db(dbname):
+ global g_conn
+
+ if dbname == None:
+ dbname = "doxygen_sqlite3.db"
+
+ if not os.path.isfile(dbname):
+ raise BaseException("No such file %s" % dbname )
+
+ g_conn = sqlite3.connect(dbname)
+ g_conn.execute('PRAGMA temp_store = MEMORY;')
+ g_conn.row_factory = sqlite3.Row
+
+def main(argv):
+ try:
+ opts, args = getopt.getopt(argv, "hd:x:",["help"])
+ except getopt.GetoptError:
+ sys.exit(1)
+
+ dbname=None
+ xmlfile=None
+
+ for a, o in opts:
+ if a in ('-h', '--help'):
+ sys.exit(0)
+ elif a in ('-d'):
+ dbname=o
+ continue
+ elif a in ('-x'):
+ xmlfile=o
+ continue
+ open_db(dbname)
+ load_xml(xmlfile)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/tmake/CHANGES b/tmake/CHANGES
new file mode 100644
index 0000000..ce686e9
--- /dev/null
+++ b/tmake/CHANGES
@@ -0,0 +1,49 @@
+ Changes from version 1.2 to 1.3
+
+* Improved Qt 2.0 support.
+
+* INCLUDEPATH can have directories containing whitespace (use semicolon)
+ as separator.
+
+* Many, many code fixes and doc improvements.
+
+
+ Changes from version 1.1 to 1.2
+
+* tmake is no longer restricted to C++ only. You can now use both C++
+ and C files in your project. Thanks to Ulrich Ring for valuable feed-
+ back and comments.
+
+* Added support for building DLL libraries under Windows.
+ NOTE: Qt 1.42 and later now uses qtmain.lib in addition to qt.lib
+ when your application uses the Qt DLL. Add "DEFINES = QT_DLL" to
+ your project file to use the Qt DLL.
+
+* New dist target added in the app and lib templates.
+ Run "make dist" to pack all files in your project using tar/gzip or zip.
+ Thanks to Kalle Dalheimer for this patch.
+
+* Fixed bad command line interpretation bug in tmake.exe and progen.exe.
+
+* Added support for Borland C++ builder 3.
+
+* Initial support for QNX/g++ and the IBM Visual Age compiler on Win32.
+ Thanks to Igor Kovalenko and Joost Kraaijeveld.
+
+* Many fixes in tmake.conf for several Unix configurations.
+
+
+ Changes from version 1.0 to 1.1
+
+* Provides tmake.exe and progen.exe for Windows users without perl.
+
+* Added many new Unix templates.
+
+* Added subdirs.t templates.
+
+* Added system-dependent project settings
+ (e.g. solaris-cc:TMAKE_CFLAGS = -pts)
+
+* Many bug fixes and improvements for existing templates.
+
+* Improved documentation.
diff --git a/tmake/LICENSE b/tmake/LICENSE
new file mode 100644
index 0000000..7262d5a
--- /dev/null
+++ b/tmake/LICENSE
@@ -0,0 +1,9 @@
+ License Statement for tmake
+
+Copyright (C) 1996-1999 by Troll Tech AS. All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the this copyright notice appears in all copies.
+No representations are made about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
diff --git a/tmake/README b/tmake/README
new file mode 100644
index 0000000..b049d32
--- /dev/null
+++ b/tmake/README
@@ -0,0 +1,10 @@
+ tmake version 1.3
+
+tmake is an easy-to-use tool for creating and maintaining makefiles across
+many platforms and compilers. For information about installing and using
+tmake, see:
+
+ doc/tmake.html -- User's Guide
+ doc/tmake_ref.html -- Reference Manual
+
+Download the latest version from: <ftp://ftp.troll.no/freebies/tmake>
diff --git a/tmake/bin/progen b/tmake/bin/progen
new file mode 100755
index 0000000..5be6411
--- /dev/null
+++ b/tmake/bin/progen
@@ -0,0 +1,249 @@
+#!/usr/bin/perl
+############################################################################
+#
+#
+# Generates a tmake project file.
+#
+# Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted, provided
+# that this copyright notice appears in all copies.
+# No representations are made about the suitability of this software for any
+# purpose. It is provided "as is" without express or implied warranty.
+#
+############################################################################
+
+# Default project settings
+$project{"TEMPLATE"} = "app";
+$project{"CONFIG"} = "qt warn_on release";
+
+ at project_extra = ();
+
+while ( @ARGV ) { # parse command line args
+ $_ = shift @ARGV;
+ if ( s/^-// ) {
+ if ( /^o(.*)/ ) {
+ $outfile = ($1 eq "") ? shift @ARGV : $1;
+ ($outfile eq "-") && ($outfile = "");
+ } elsif ( /^n(.*)/ ) {
+ $project{"TARGET"} = ($1 eq "") ? shift @ARGV : $1;
+ } elsif ( /^t(.*)/ ) {
+ $project{"TEMPLATE"} = ($1 eq "") ? shift @ARGV : $1;
+ $project{"TEMPLATE"} =~ s/\.t$//i;
+ } elsif ( /lower/ ) {
+ $tolower = 1;
+ } else {
+ &progen_usage;
+ }
+ } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override
+ push( @project_extra, $_ );
+ } else {
+ push (@files, $_ );
+ }
+}
+
+$outfile eq "" || open(STDOUT,">" . $outfile) ||
+ &progen_error("Can't create \"$outfile\"");
+
+if ( ! @files ) {
+ @files = &find_files(".",".*",1);
+}
+
+if ( $tolower ) {
+ foreach $f ( @files ) {
+ $f =~ tr/A-Z/a-z/;
+ }
+}
+
+ at hdr = sort grep(/\.(h|hh|hpp|hxx)$/i, at files);
+ at src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i, at files);
+
+# Remove source files that are included by other source files
+foreach $f ( @src ) {
+ $srcdict{$f} = 1;
+}
+foreach $f ( @src ) {
+ if ( open(F,"< $f") ) {
+ while ( <F> ) {
+ if ( /^\s*#\s*include\s+\"([^\"]*)\"/ ) {
+ $srcdict{$1} = 0;
+ }
+ }
+ }
+}
+foreach $f( @src ) {
+ $srcdict{$f} && (push(@src2,$f));
+}
+ at src = @src2;
+
+$project{"HEADERS"} = join(" ",sort @hdr);
+$project{"SOURCES"} = join(" ",sort @src);
+
+foreach $p ( @project_extra ) {
+ if ( $p =~ /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) {
+ if ( $project{$1} ne "" ) {
+ Project($p);
+ }
+ }
+}
+
+$project{"HEADERS"} =~ s/\s+/ \\\n\t\t /g;
+$project{"SOURCES"} =~ s/\s+/ \\\n\t\t /g;
+
+print "TEMPLATE\t= " . $project{"TEMPLATE"} . "\n";
+print "CONFIG\t\t= " . $project{"CONFIG"} . "\n";
+print "HEADERS\t\t= " . $project{"HEADERS"} . "\n";
+print "SOURCES\t\t= " . $project{"SOURCES"} . "\n";
+if ( $project{"TARGET"} ne "" ) {
+ print "TARGET\t\t= " . $project{"TARGET"} . "\n";
+}
+
+foreach ( @project_extra ) {
+ if ( /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) {
+ if ( $project{$1} eq "" ) {
+ $t = $1;
+ if ( length($t) < 8 ) {
+ $t .= "\t\t";
+ } elsif ( length($t) < 16 ) {
+ $t .= "\t";
+ } else {
+ $t .= " ";
+ }
+ print "$t$2= $3\n";
+ }
+ }
+}
+
+exit 0;
+
+
+#
+# progen_usage()
+#
+# Prints a message about program usage and exits
+#
+
+sub progen_usage {
+ print STDERR "Usage:\n progen [options] [files]\n";
+ print STDERR "Options:\n";
+ print STDERR " -lower Lower-case letters filenames (useful for non-Unix)\n";
+ print STDERR " -n name Specify a project name (= TARGET)\n";
+ print STDERR " -o file Write output to \"file\"\n";
+ print STDERR " -t file Specify a template file other than qtapp\n";
+ exit 1;
+}
+
+
+#
+# progen_error(msg)
+#
+# Prints the message and exits
+#
+
+sub progen_error {
+ my($msg) = @_;
+ print STDERR "progen error: " . $msg . "\n";
+ exit 1;
+}
+
+
+#
+# Finds files.
+#
+# Examples:
+# find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below
+# find_files("/tmp","^#",0) - finds #* files in /tmp
+#
+
+sub find_files {
+ my($dir,$match,$descend) = @_;
+ my($file,$p, at files);
+ local(*D);
+ $dir =~ s=\\=/=g;
+ ($dir eq "") && ($dir = ".");
+ if ( opendir(D,$dir) ) {
+ if ( $dir eq "." ) {
+ $dir = "";
+ } else {
+ ($dir =~ /\/$/) || ($dir .= "/");
+ }
+ foreach $file ( readdir(D) ) {
+ next if ( $file =~ /^\.\.?$/ );
+ $p = $dir . $file;
+ ($file =~ /$match/i) && (push @files, $p);
+ if ( $descend && -d $p && ! -l $p ) {
+ push @files, &find_files($p,$match,$descend);
+ }
+ }
+ closedir(D);
+ }
+ return @files;
+}
+
+
+#
+# strip_project_val(tag)
+#
+# Strips white space from project value strings.
+#
+
+sub strip_project_val {
+ my($v) = @_;
+ $v =~ s/^\s+//; # trim white space
+ $v =~ s/\s+$//;
+ return $v;
+}
+
+
+#
+# Project(strings)
+#
+# This is a powerful function for setting or reading project variables.
+# Returns the resulting project variables (joined with space between).
+#
+# This is a slightly modified version of the Project function in tmake.
+
+sub Project {
+ my @settings = @_;
+ my($r,$t,$s,$v,$p,$c);
+ $r = "";
+ foreach ( @settings ) {
+ $v = $_;
+ if ( $v =~ s/^\s*((?:[\w\-]+:)?\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) {
+ $t = $1;
+ $s = $2;
+ $v = strip_project_val($v);
+ $p = $project{$t};
+ if ( $s eq "=" ) { # set variable
+ $p = $v;
+ } elsif ( $s eq "+=" ) { # append
+ if ( $p eq "" ) {
+ $p = $v;
+ } else {
+ $p .= " " . $v;
+ }
+ } elsif ( $s eq "*=" ) { # append if not contained
+ if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) {
+ if ( $p eq "" ) {
+ $p = $v;
+ } else {
+ $p .= " " . $v;
+ }
+ }
+ } elsif ( $s eq "-=" ) { # subtract
+ $p =~ s/$v//g;
+ } elsif ( $s eq "/=" ) { # sed
+ $cmd = '$p =~ ' . $v;
+ eval $cmd;
+ }
+ $project{$t} = strip_project_val($p);
+ } else {
+ $p = strip_project_val($project{$v});
+ }
+ if ( $p ne "" ) {
+ $r = ($r eq "") ? $p : ($r . " " . $p);
+ }
+ }
+ return $r;
+}
diff --git a/tmake/bin/tmake b/tmake/bin/tmake
new file mode 100755
index 0000000..9158d7a
--- /dev/null
+++ b/tmake/bin/tmake
@@ -0,0 +1,1262 @@
+#!/usr/bin/perl
+############################################################################
+#
+#
+# Creates a Makefile from a template and a project file.
+#
+# Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted, provided
+# that this copyright notice appears in all copies.
+# No representations are made about the suitability of this software for any
+# purpose. It is provided "as is" without express or implied warranty.
+#
+#
+# Some important, global variables in tmake:
+# cpp_ext C++ extension added to moc output (.cpp)
+# obj_ext Object file extension (.o on Unix, .obj otherwise)
+# moc_aware Will scan for files containing Qt signals/slots
+# moc_pre Moc prefix for generated moc file: x.h -> moc_x.cpp
+# moc_ext Moc extension for generated moc file: x.cpp -> x.moc
+# moc_cmd The moc command in your makefile, $(MOC)
+# linebreak Line break character (\)
+# dir_sep Directory separator (/ on Unix, \ on Windows)
+# is_unix Autodetected. If not Unix, assume Windows (Win32).
+#
+# If you need to customize any of these settings, do it before
+# calling StdInit() in the template file.
+#
+############################################################################
+
+$TMAKE_VERSION = "1.3";
+
+if ($] < 5.0) {
+ &tmake_error("This program requires perl version 5 or newer");
+}
+
+$cpp_ext = "cpp";
+$moc_aware = 0;
+$moc_pre = "moc_";
+$moc_ext = "moc";
+$moc_cmd = '$(MOC)';
+$linebreak = "\\";
+$really_unix = &check_unix();
+$is_unix = $really_unix;
+$dir_sep = $is_unix ? "/" : "\\";
+$obj_ext = $is_unix ? "o" : "obj";
+$depend_path = "";
+$nodepend = 0;
+$output_count = 0;
+$notrim_whitespace = 0;
+$read_tmakeconf = 0;
+
+$template_name = "";
+$project_name = "";
+$outfile = "";
+%project = ();
+$eval_quit = 0;
+
+$project{"TMAKEPATH"} = $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/";
+
+while ( @ARGV ) { # parse command line args
+ $_ = shift @ARGV;
+ if ( s/^-// ) {
+ if ( /^e(.*)/ ) {
+ if ( ! $read_tmakeconf ) {
+ $read_tmakeconf = 1;
+ &ScanProject( &find_template("tmake.conf") );
+ }
+ $text = "";
+ eval( ($1 eq "") ? shift @ARGV : $1 );
+ die $@ if $@;
+ print $text . "\n" if ($text ne "");
+ $eval_quit = 1;
+ } elsif ( /^t(.*)/ ) {
+ $template_name = ($1 eq "") ? shift @ARGV : $1;
+ } elsif ( /^o(.*)/ ) {
+ $outfile = ($1 eq "") ? shift @ARGV : $1;
+ ($outfile eq "-") && ($outfile = "");
+ if ( $outfile ne "" ) {
+ open(STDOUT,">" . fix_path($outfile)) ||
+ &tmake_error("Can't create \"$outfile\"");
+ }
+ } elsif ( /^p(.*)/ ) {
+ #
+ # The -p option is obsolete and will be removed in the next
+ # tmake release.
+ #
+ &tmake_warning( "-p option obsolete, instead use \"tmake file1.pro file2.pro ...\"");
+ my($pf) = ($1 eq "") ? shift @ARGV : $1;
+ if ( ! $read_tmakeconf ) {
+ $read_tmakeconf = 1;
+ &ScanProject( &find_template("tmake.conf") );
+ }
+ if ( ! ($pf =~ /\.pro$/i) && -f fix_path($pf . ".pro") ) {
+ $pf .= ".pro";
+ }
+ if ( $project_name eq "" ) {
+ $project_name = $pf;
+ $project{"PROJECT"} = $project_name;
+ $project{"PROJECT"} =~ s/\.pro$//i;
+ $project{"TARGET"} = $project{"PROJECT"};
+ }
+ if ( !&ScanProject($pf) ) {
+ &tmake_error("Can't open project file \"$pf\"");
+ }
+ } elsif ( /^unix$/ ) {
+ $is_unix = 1;
+ $dir_sep = "/";
+ $obj_ext = "o";
+ } elsif ( /^win32$/ ) {
+ $is_unix = 0;
+ $dir_sep = "\\";
+ $obj_ext = "obj";
+ } elsif ( /^nodepend$/ ) {
+ $nodepend = 1; # don't generate dependencies
+ } elsif ( /^v$/ ) {
+ $verbose = 1;
+ } else {
+ &tmake_usage();
+ }
+ } elsif ( /^\s*((?:[^:\s]*?:)?)(\w+)\s*(\+=|\*=|\-=|\/=|=)/ ) {
+ if ( ! $read_tmakeconf && ! (/^\s*TMAKEPATH/) ) {
+ $read_tmakeconf = 1;
+ &ScanProject( &find_template("tmake.conf") );
+ }
+ Project( $_ ); # manual project setting
+ } else {
+ my($pf) = $_;
+ if ( ! $read_tmakeconf ) {
+ $read_tmakeconf = 1;
+ &ScanProject( &find_template("tmake.conf") );
+ }
+ if ( ! ($pf =~ /\.pro$/i) && -f fix_path($pf . ".pro") ) {
+ $pf .= ".pro";
+ }
+ if ( $project_name eq "" ) {
+ $project_name = $pf;
+ $project{"PROJECT"} = $project_name;
+ $project{"PROJECT"} =~ s/\.pro$//i;
+ $project{"TARGET"} = $project{"PROJECT"};
+ }
+ if ( !&ScanProject($pf) ) {
+ &tmake_error("Can't open project file \"$pf\"");
+ }
+ }
+}
+
+&tmake_verb("Version $TMAKE_VERSION (runtime environment: " .
+ ($really_unix ? "Unix" : "Win32") . ")\n" );
+
+if ( $eval_quit ) {
+ &tmake_verb("Done!");
+ exit 0;
+}
+($project_name eq "") && &tmake_usage();
+
+if ( $template_name eq "" ) {
+ $template_name = $project{"TEMPLATE"} ?
+ $project{"TEMPLATE"} : "default.t";
+}
+$template_name = &find_template($template_name);
+&IncludeTemplate($template_name);
+&tmake_verb("Done!");
+exit 0; # finished!
+
+
+
+##############################################################################
+# Subroutines from here
+##############################################################################
+
+#
+# tmake_usage()
+#
+# Prints a message about program usage and exits
+#
+
+sub tmake_usage {
+ print STDERR "Usage:\n tmake [options] project-files\n";
+ print STDERR "Options:\n";
+ print STDERR " -e expr Evaluate expression, ignore template file\n";
+ print STDERR " -nodepend Don't generate dependency information\n";
+ print STDERR " -o file Write output to file\n";
+ print STDERR " -t file Specify a template file\n";
+ print STDERR " -unix Create output for Unix (auto detects)\n";
+ print STDERR " -v Verbose/debug mode\n";
+ print STDERR " -win32 Create output for Win32 (auto detects)\n";
+ exit 1;
+}
+
+
+#
+# tmake_error(msg)
+#
+# Prints the message and exits
+#
+
+sub tmake_error {
+ my($msg) = @_;
+ print STDERR "tmake error: " . $msg . "\n";
+ exit 1;
+}
+
+
+#
+# tmake_warning(msg)
+#
+# Prints the warning message
+#
+
+sub tmake_warning {
+ my($msg) = @_;
+ print STDERR "tmake warning: " . $msg . "\n";
+}
+
+
+#
+# tmake_verb()
+#
+# Prints a verbose message
+#
+
+sub tmake_verb {
+ my($msg) = @_;
+ $verbose && print STDERR "tmake: " . $msg . "\n";
+}
+
+
+#
+# check_unix()
+#
+# Returns 1 if this is a Unix, 0 otherwise.
+#
+
+sub check_unix {
+ my($r);
+ $r = 0;
+ if ( -f "/bin/uname" ) {
+ $r = 1;
+ (-f "\\bin\\uname") && ($r = 0);
+ }
+ if ( -f "/usr/bin/uname" ) {
+ $r = 1;
+ (-f "\\usr\\bin\\uname") && ($r = 0);
+ }
+ return $r;
+}
+
+
+#
+# find_template(filename)
+#
+# Looks for the template file.
+# 1. search the current directory
+# 2. search the directories in TMAKEPATH
+# 3. search in $HOME/.tmake
+#
+
+sub find_template {
+ my($filename) = @_;
+ my($tb,$d,$p, at dirs);
+ if ( !defined($template_base) || ($template_base eq "") ) {
+ $tb = "";
+ } else {
+ $tb = $template_base . ";";
+ }
+ $d = $tb . $project{"TMAKEPATH"};
+ @dirs = ("");
+ push @dirs, &split_path( $d );
+ $filename .= ".t" unless ($filename =~ /\.\w+$/);
+ for $d ( @dirs ) {
+ $p = $d . $filename;
+ if ( -f fix_path($p) ) {
+ if ( $filename eq "tmake.conf" ) {
+ $tmake_platform = $d;
+ $tmake_platform =~ s-.*[/\\]([^/\\]*)[/\\]-$1-;
+ &tmake_verb("Detected platform $tmake_platform");
+ }
+ return $p;
+ }
+ return ($d . $filename) if ( -f fix_path($d . $filename) );
+ }
+ &tmake_error("Template file " . $filename . " not found");
+}
+
+
+##############################################################################
+# User functions
+##############################################################################
+
+#
+# StdInit()
+#
+# Standard initialization
+#
+
+sub StdInit {
+ my($p);
+ return if $stdinit_done;
+ $stdinit_done = 1;
+ if ( defined($project{"OBJECTS_DIR"}) ) {
+ $project{"OBJECTS_DIR"} = FixPath($project{"OBJECTS_DIR"});
+ &mkdirp($project{"OBJECTS_DIR"},0777);
+ }
+ if ( defined($project{"MOC_DIR"}) ) {
+ $project{"MOC_DIR"} = FixPath($project{"MOC_DIR"});
+ &mkdirp($project{"MOC_DIR"},0777);
+ }
+ if ( defined($project{"DESTDIR"}) ) {
+ $project{"DESTDIR"} = FixPath($project{"DESTDIR"});
+ &mkdirp($project{"DESTDIR"},0777);
+ }
+ $project{"OBJECTS"} = &Objects($project{"SOURCES"});
+ if ( $moc_aware ) {
+ $project{"_HDRMOC"} = &list_moc($project{"HEADERS"},$moc_pre,$cpp_ext);
+ $project{"_SRCMOC"} = &list_moc($project{"SOURCES"},"",$moc_ext);
+ $project{"OBJMOC"} = &Objects($project{"_HDRMOC"});
+ $p = $project{"_HDRMOC"} . " " . $project{"_SRCMOC"};
+ $p =~ s/(^\s+|\s+$)//g;
+ $project{"SRCMOC"} = $p;
+ }
+ &AddIncludePath("");
+}
+
+
+sub FixPath {
+ my($p) = @_;
+ if ( !defined($p) || ($p eq "") || ($p eq ".") ) {
+ $p = "";
+ } else {
+ $p .= $dir_sep;
+ $p =~ s-[\\/]+-${dir_sep}-g;
+ }
+ return $p;
+}
+
+
+#
+# Config(name)
+#
+# Returns true if the project variable CONFIG contains the
+# configuration name.
+#
+
+sub Config {
+ my($name) = @_;
+ return $project{"CONFIG"} =~ /\b\Q$name\E\b/;
+}
+
+
+#
+# DisableOutput()
+#
+# Disables tmake output. Must be restored by calling a corresponding
+# EnableOutput().
+#
+
+sub DisableOutput {
+ $output_count++;
+}
+
+
+#
+# EnableOutput()
+#
+# Enables tmake output again after DisableOutput() has been called.
+#
+
+sub EnableOutput {
+ $output_count--;
+}
+
+
+#
+# Now() - sets $text
+#
+# Sets $text to the current date and time.
+#
+
+sub Now {
+ my($sec,$min,$hour,$mday,$mon,$year);
+ ($sec,$min,$hour,$mday,$mon,$year) = localtime(time());
+ $text = sprintf("%02d:%02d, %4d/%02d/%02d",
+ $hour, $min, 1900+$year, 1+$mon, $mday);
+}
+
+
+#
+# expand_project_var(var)
+#
+# Internal function for Project().
+# Expands a project value string.
+#
+
+sub expand_project_var {
+ my($v) = @_;
+ my($c);
+ return "" if !defined($v);
+ $c = 0;
+ while ( $c < 100 ) { # expand $$
+ if ( $v =~ s/(\$\$\w+)/\035/ ) {
+ $_ = $1;
+ s/\$\$//g;
+ if ( !defined($project{$_}) ) {
+ $v =~ s/\035//g;
+ } else {
+ $v =~ s/\035/$project{$_}/g;
+ }
+ $c++;
+ } else {
+ $c = 100;
+ }
+ }
+ return $v;
+}
+
+
+#
+# Project(strings)
+#
+# This is a powerful function for setting or reading project variables.
+# Returns the resulting project variables (joined with space between).
+#
+# Get a project variable:
+# $s = Project("TEMPLATE"); -> $s = "TEMPLATE"
+#
+# Set a project variable:
+# Project("TEMPLATE = lib"); -> TEMPLATE = lib
+# Project("CONFIG =";) -> CONFIG empty
+#
+# Append to a project variable:
+# Project("CONFIG = qt"); -> CONFIG = qt
+# Project("CONFIG += debug"); -> CONFIG = qt debug
+#
+# Append to a project variable if it does not contain the value already:
+# Project("CONFIG = qt release"); -> CONFIG = qt release
+# Project("CONFIG *= qt"); -> CONFIG = qt release
+# Project("CONFIG *= opengl"); -> CONFIG = qt release opengl
+#
+# Subtract from a project variable:
+# Project("THINGS = abc xyz"); -> THINGS = abc xyz
+# Project("THINGS -= abc"); -> THINGS = xyz
+#
+# Search/replace on a project variable:
+# Project("CONFIG = tq opengl"); -> CONFIG = tq opengl
+# Project("CONFIG /= s/tq/qt/"); -> CONFIG = qt opengl
+#
+# The operations can be performed on several project variables at a time.
+#
+# Project("TEMPLATE = app", "CONFIG *= opengl", "THINGS += klm");
+#
+
+sub Project {
+ my @settings = @_;
+ my($r,$if_var,$t,$s,$v,$p,$c);
+ $r = "";
+ foreach ( @settings ) {
+ $v = $_;
+ if ( $v =~ s/^\s*([^:\r\n]+:)?(\w+)\s*(\+=|\*=|\-=|\/=|=)// ) {
+ $if_var = $1;
+ if ( $if_var ne "" ) {
+ chop $if_var;
+ if ( $if_var eq "unix" ) {
+ return "" if !$is_unix;
+ } elsif ( $if_var eq "win32" ) {
+ return "" if $is_unix;
+ } elsif ( ($if_var ne $tmake_platform) && !Config($if_var) ) {
+ return "";
+ }
+ }
+ $t = $2;
+ $s = $3;
+ if ( ! $notrim_whitespace ) {
+ $v =~ s/^\s+//; # trim white space
+ $v =~ s/\s+$//;
+ }
+ $v = expand_project_var($v);
+ $p = $project{$t};
+ if ( $s ne "=" && $v eq "" ) {
+ # nothing to append, subtract or sed
+ } elsif ( $s eq "=" ) { # set variable
+ $p = $v;
+ } elsif ( $s eq "+=" ) { # append
+ if ( $p eq "" ) {
+ $p = $v;
+ } else {
+ $p .= " " . $v;
+ }
+ } elsif ( $s eq "*=" ) { # append if not contained
+ if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) {
+ if ( $p eq "" ) {
+ $p = $v;
+ } else {
+ $p .= " " . $v;
+ }
+ }
+ } elsif ( $s eq "-=" ) { # subtract
+ $p =~ s/$v//g;
+ } elsif ( $s eq "/=" ) { # sed
+ $cmd = '$p =~ ' . $v;
+ eval $cmd;
+ }
+ $project{$t} = expand_project_var($p);
+ } else {
+ $p = expand_project_var($project{$v});
+ }
+ if ( $p ne "" ) {
+ $r = ($r eq "") ? $p : ($r . " " . $p);
+ }
+ }
+ return $r;
+}
+
+
+#
+# Substitute(string)
+#
+# This function substitutes project variables in a text.
+#
+# Example:
+# Substitute('The project name is "$$PROJECT"')
+#
+
+sub Substitute {
+ my($subst) = @_;
+ $text = expand_project_var($subst);
+ return $text;
+}
+
+
+#
+# ScanProject(file)
+#
+# Scans a project file. Inserts project variables into the global
+# associative project array.
+#
+
+sub ScanProject {
+ my($file) = @_;
+ my($var,$val, at v,$more,$line,$endmark);
+
+ $var = "";
+ $line = 0;
+ open(TMP,fix_path($file)) || return 0;
+
+ &tmake_verb("Reading the project file $file");
+ while ( <TMP> ) {
+ $line++;
+ s/\#.*//; # strip comment
+ s/^\s+//; # strip white space
+ s/\s+$//;
+ if ( /^(([^:\r\n]+:)?\w+\s*(\+|\-|\*|\/)?=)/ ) {
+ $var = $1; # var also contains the ".="
+ s/^.*?=\s*//;
+ if ( /^\<\<(.*)$/ ) {
+ $endmark = $1;
+ $val = "";
+ while ( <TMP> ) {
+ $line++;
+ if ( /^\Q$endmark\E$/ ) {
+ $endmark = "";
+ last;
+ }
+ $val .= $_;
+ }
+ if ( $endmark ne "" ) {
+ tmake_error("$file:$line: End marker $endmark not found");
+ }
+ chop $val if ( $val ne "" );
+ $notrim_whitespace++;
+ Project( $var . $val );
+ $notrim_whitespace--;
+ $var = "";
+ $_ = "";
+ }
+ }
+ if ( $var ne "" ) {
+ $more = ( $_ =~ s/\s*\\\s*$// ); # more if \ at end of line
+ push( @v, split( /\s+/, $_ ) );
+ if ( ! $more ) {
+ $val = join(" ", at v);
+ Project( $var . $val );
+ $var = "";
+ @v = ();
+ }
+ } elsif ( $_ ne "" ) {
+ tmake_error("$file:$line: Syntax error");
+ }
+ }
+ close(TMP);
+ &tmake_verb("Done reading the project file $file");
+ return 1;
+}
+
+
+#
+# IncludeTemplate(template_name)
+#
+# Includes and processes a template file.
+#
+# Below, we read the template file and executes any perl code found.
+# Perl code comes after "#$". The variable $text contains the text
+# to replace the perl code that was executed.
+# Template comments begin with "#!".
+#
+
+sub IncludeTemplate {
+ my($t_name) = @_;
+ my($cmd,$cmd_block,$cmd_end,$is_cmd_block,$saveline,$spaceonly);
+ local($text);
+ local(*T);
+
+ $t_name = &find_template($t_name);
+ if ( $tmake_template_dict{$t_name} ) {
+ &tmake_error("Cyclic template inclusion for $t_name");
+ } else {
+ $tmake_template_dict{$t_name} = 1;
+ }
+ $template_base = $t_name;
+ $template_base =~ s-(.*[/\\]).*-$1-;
+ &tmake_verb("Reading the template $t_name");
+ open(T,fix_path($t_name)) ||
+ &tmake_error("Can't open template file \"$t_name\"");
+
+ while ( <T> ) {
+ if ( /\#\!/ ) { # tmake comment
+ s/\s*\#\!.*//;
+ next if /^$/;
+ }
+ if ( /\#\$(\{)?\s*(.*)\n/ ) { # code
+ $cmd = $2;
+ $is_cmd_block = defined($1) && ($1 eq "{");
+ s/\#\$.*\n//;
+ if ( $is_cmd_block ) { # code block #${ ...
+ $saveline = $_;
+ $cmd_block = $cmd;
+ $cmd_end = 0;
+ while ( <T> ) {
+ $cmd = $_;
+ $cmd =~ s/\s*\#\!.*//; # tmake comment
+ if ( $cmd =~ /^\s*\#\$\}/ ) {
+ $_ = "";
+ $cmd_end = 1;
+ last;
+ }
+ $cmd =~ s/^\s*\#(\$)?\s*//;
+ $cmd_block .= $cmd;
+ }
+ $cmd_end || &tmake_error('#$} expected but not found');
+ $cmd = $cmd_block;
+ $_ = $saveline;
+ }
+ $spaceonly = /^\s*$/;
+ $saveline = $_;
+ &tmake_verb("Evaluate: $cmd");
+ $text = "";
+ eval $cmd;
+ die $@ if $@;
+ next if $spaceonly && ($text =~ /^\s*$/);
+ print $saveline . $text . "\n" if $output_count <= 0;
+ } else { # something else
+ print if $output_count <= 0;
+ }
+ }
+ close( T );
+}
+
+
+#
+# Expand(var) - appends to $text
+#
+# Expands a list of $project{} variables with a space character between them.
+#
+
+sub Expand {
+ my @vars = @_;
+ my($t);
+ $t = Project(@vars);
+ if ( $text eq "" ) {
+ $text = $t;
+ } elsif ( $t ne "" ) {
+ $text .= " " . $t;
+ }
+ return $text;
+}
+
+
+#
+# ExpandGlue(var,prepend,glue,append) - appends to $text
+#
+# Expands a $project{} variable, splits on whitespace
+# and joins with $glue. $prepend is put at the start
+# of the string and $append is put at the end of the
+# string. The resulting string becomes "" if the project
+# var is empty or not defined.
+#
+# Example:
+#
+# The project file defines:
+# SOURCES = a b c
+#
+# ExpandGlue("SOURCES","<","-",">")
+#
+# The result:
+# $text = "<a-b-c>"
+#
+
+sub ExpandGlue {
+ my($var,$prepend,$glue,$append) = @_;
+ my($t,$v);
+ $v = Project($var);
+ if ( $v eq "" ) {
+ $t = "";
+ } else {
+ $t = $prepend . join($glue,split(/\s+/,$v)) . $append;
+ }
+ if ( $text eq "" ) {
+ $text = $t;
+ } elsif ( $t ne "" ) {
+ $text .= " " . $t;
+ }
+ return $text;
+}
+
+
+#
+# ExpandList(var) - sets $text.
+#
+# Suitable for expanding HEADERS = ... etc. in a Makefile
+#
+
+sub ExpandList {
+ my($var) = @_;
+ return ExpandGlue($var,""," ${linebreak}\n\t\t","");
+}
+
+
+#
+# ExpandPath(var,prepend,glue,append) - appends to $text
+#
+# Expands a $project{} variable, splits on either ';' or
+# whitespace and joins with $glue. $prepend is put at the
+# start of the string and $append is put at the end of the
+# string. The resulting string becomes "" if the project
+# variable is empty or not defined.
+#
+# If the variable contains at least one semicolon or tmake
+# is running on Windows, the resulting items are put in
+# double-quotes.
+#
+# Example:
+#
+# The project file defines:
+# INCLUDEPATH = "C:\qt\include;c:\program files\msdev\include
+#
+# ExpandGlue("INCLUDEPATH","-I","-I","")
+#
+# The result:
+# $text = -I"c:\qt\include" -I"c:\program files\msdev\include"
+#
+
+sub ExpandPath {
+ my($var,$prepend,$glue,$append) = @_;
+ my($t,$v);
+ my($s);
+ $v = Project($var);
+ if ( $v eq "" ) {
+ $t = "";
+ } else {
+ if ( $v =~ /;/ || !$is_unix ) {
+ $prepend .= '"';
+ $glue = '"' . $glue . '"';
+ $append = '"' . $append;
+ }
+
+ if ( $v =~ /;/ ) {
+ $t = $prepend . join($glue,split(/;+/,$v)) . $append;
+ } else {
+ $t = $prepend . join($glue,split(/\s+/,$v)) . $append;
+ }
+ }
+ if ( $text eq "" ) {
+ $text = $t;
+ } elsif ( $t ne "" ) {
+ $text .= " " . $t;
+ }
+ return $text;
+}
+
+
+#
+# TmakeSelf()
+#
+# Generates makefile rule to regenerate the makefile using tmake.
+#
+
+sub TmakeSelf {
+ my $a = "tmake $project_name";
+ if ( $nodepend ) {
+ $a .= " -nodepend";
+ }
+ if ( $outfile ) {
+ $text = "tmake: $outfile\n\n$outfile: $project_name\n\t";
+ $a .= " -o $outfile";
+ } else {
+ $text = "tmake:\n\t";
+ }
+ $text .= $a
+}
+
+
+#
+# Objects(files)
+#
+# Replaces any extension with .o ($obj_ext).
+#
+
+sub Objects {
+ local($_) = @_;
+ my(@a);
+ @a = split(/\s+/,$_);
+ foreach ( @a ) {
+ s-\.\w+$-.${obj_ext}-;
+ if ( defined($project{"OBJECTS_DIR"}) ) {
+ s-^.*[\\/]--;
+ $_ = $project{"OBJECTS_DIR"} . $_;
+ }
+ }
+ return join(" ", at a);
+}
+
+
+#
+# list_moc(files,prefix,extension)
+#
+# Scans all files and selects all files that contain Q_OBJECT.
+# Insert a prefix before the filename and replaces the filename extention.
+#
+
+sub list_moc {
+ my($files,$pre,$ext) = @_;
+ my(@v, at m, at lines,$contents,$n,$f,$t);
+ @v = split(/\s+/,$files);
+ undef $/;
+ foreach $f ( @v ) {
+ if ( open(TMP,fix_path($f)) ) {
+ $contents = <TMP>;
+ close(TMP);
+ $n = 0;
+ @lines = split(/\n/,$contents);
+ grep( /tmake\s+ignore\s+Q_OBJECT/ && $n--, @lines );
+ $contents =~ s-/\*.*?\*/--gs; # strip C/C++ comments
+ $contents =~ s-//.*\n--g;
+ @lines = split(/\n/,$contents);
+ grep( /(^|\W)Q_OBJECT(\W|$)/ && $n++, @lines );
+ if ( $n > 0 ) {
+ $t = $f;
+ $t =~ s-^(.*[/\\])?([^/\\]*?)\.(\w+)$-$1${pre}$2.${ext}-;
+ if ( defined($project{"MOC_DIR"}) ) {
+ $t =~ s-^.*[\\/]--;
+ $t = $project{"MOC_DIR"} . $t;
+ }
+ $moc_output{$f} = $t;
+ $moc_input{$t} = $f;
+ push(@m,$t);
+ }
+ $contents = "";
+ }
+ }
+ $/ = "\n";
+ return join(" ", at m);
+}
+
+
+#
+# BuildObj(objects,sources)
+#
+# Builds the object files.
+#
+
+sub BuildObj {
+ my($obj,$src) = @_;
+ my(@objv,$srcv,$i,$s,$o,$d,$c,$comp,$cimp);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ next if $s eq "";
+ $text .= $o . ": " . $s;
+ if ( defined($moc_output{$s}) && ($moc_output{$s} ne "") ) {
+ $text .= " ${linebreak}\n\t\t" . $moc_output{$s};
+ }
+ $d = &make_depend($s);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ if ( ($s =~ /\.c$/) ) {
+ $comp = "TMAKE_RUN_CC";
+ $cimp = "TMAKE_RUN_CC_IMP";
+ } else {
+ $comp = "TMAKE_RUN_CXX";
+ $cimp = "TMAKE_RUN_CXX_IMP";
+ }
+ if ( defined($project{"OBJECTS_DIR"}) ||
+ !defined($project{$cimp}) ) {
+ $c = $project{$comp};
+ $c =~ s/\$src/$s/;
+ $c =~ s/\$obj/$o/;
+ $text .= "\n\t$c";
+ }
+ $text .= "\n\n";
+ }
+ chop $text;
+}
+
+
+#
+# BuildMocObj(objects,sources)
+#
+# Builds the moc object files.
+#
+
+sub BuildMocObj {
+ my($obj,$src) = @_;
+ my(@objv,$srcv,$i,$s,$o,$hdr,$d);
+ @objv = split(/\s+/,$obj);
+ @srcv = split(/\s+/,$src);
+ for $i ( 0..$#objv ) {
+ $s = $srcv[$i];
+ $o = $objv[$i];
+ $hdr = $moc_input{$srcv[$i]};
+ $text .= $o . ": " . $s . " ${linebreak}\n\t\t" . $hdr;
+ $d = &make_depend($hdr);
+ $text .= " ${linebreak}\n\t\t" . $d if $d ne "";
+ if ( defined($project{"OBJECTS_DIR"}) || defined($project{"MOC_DIR"})||
+ !defined($project{"TMAKE_RUN_CXX_IMP"}) ) {
+ $c = $project{"TMAKE_RUN_CXX"};
+ $c =~ s/\$src/$s/;
+ $c =~ s/\$obj/$o/;
+ $text .= "\n\t$c";
+ }
+ $text .= "\n\n";
+ }
+ chop $text;
+}
+
+
+#
+# BuildMocSrc(files)
+#
+# Builds the moc source files from headers and sources.
+#
+
+sub BuildMocSrc {
+ my($f) = @_;
+ my(@v,$m,$o);
+ @v = split(/\s+/,$f);
+ foreach $m ( @v ) {
+ $o = $moc_output{$m};
+ if ( defined($o) && ($o ne "") ) {
+ $text .= "$o: $m\n\t$moc_cmd $m -o $o\n\n";
+ }
+ }
+ chop $text;
+}
+
+
+#
+# AddIncludePath(path)
+#
+# Adds path to the current include path, $project{"INCLUDEPATH"}.
+#
+
+sub AddIncludePath {
+ my($path) = @_;
+ my($p);
+ if ( $project{"INCPATH"} &&
+ ($project{"INCPATH"} =~ /(?:^|\s)\Q$path\E(?:\s|$)/) ) {
+ return;
+ }
+ $project{"INCLUDEPATH"} = "" if !defined($project{"INCLUDEPATH"});
+ if ( !defined($project{"INCPATH_SEP"}) ) {
+ if ( $project{"INCLUDEPATH"} =~ /;/ ) {
+ $project{"INCPATH_SEP"} = ";";
+ } else {
+ $project{"INCPATH_SEP"} = " ";
+ }
+ }
+ $p = $project{"INCLUDEPATH"};
+ $p = ($p && $path) ? ($p . ";" . $path) : ($p . $path);
+ $project{"INCLUDEPATH"} = $p;
+ $p = join($project{"INCPATH_SEP"},&split_path($p));
+ $p =~ s=[\\/]($project{"INCPATH_SEP"}|$)=$project{"INCPATH_SEP"}=g;
+ $project{"INCPATH"} = $p;
+}
+
+
+#
+# FindHighestLibVersion(dir,name)
+#
+# Returns the newest library version. Scans all the files in the specifies
+# directory and returns the highest version number.
+#
+# Used on Windows only.
+#
+# Example:
+# FindHighestLibVersion("c:\qt\lib","qt") returns "200" if
+# the c:\qt\lib directory contains qt141.lib and qt200.lib.
+#
+
+sub FindHighestLibVersion {
+ my($dir,$name) = @_;
+ my(@files,$f,$v,$highest);
+ $highest = "";
+ @files = find_files($dir,"${name}.*\.lib");
+ for $f ( @files ) {
+ if ( $f =~ /(\d+)\.lib/i ) {
+ $v = $1;
+ if ( $highest eq "" || $v > $highest ) {
+ $highest = $v;
+ }
+ }
+ }
+ return $highest;
+}
+
+
+#
+# Finds files.
+#
+# Examples:
+# find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below
+# find_files("/tmp","^#",0) - finds #* files in /tmp
+#
+
+sub find_files {
+ my($dir,$match,$descend) = @_;
+ my($file,$p, at files);
+ local(*D);
+ $dir =~ s=\\=/=g;
+ ($dir eq "") && ($dir = ".");
+ if ( opendir(D,fix_path($dir)) ) {
+ if ( $dir eq "." ) {
+ $dir = "";
+ } else {
+ ($dir =~ /\/$/) || ($dir .= "/");
+ }
+ foreach $file ( readdir(D) ) {
+ next if ( $file =~ /^\.\.?$/ );
+ $p = $dir . $file;
+ if ( $is_unix ) {
+ ($file =~ /$match/) && (push @files, $p);
+ } else {
+ ($file =~ /$match/i) && (push @files, $p);
+ }
+ if ( $descend && -d $p && ! -l $p ) {
+ push @files, &find_files($p,$match,$descend);
+ }
+ }
+ closedir(D);
+ }
+ return @files;
+}
+
+
+#
+# make_depend(file)
+#
+# Returns a list of included files.
+# Uses the global $depend_path variable.
+#
+
+sub make_depend {
+ my($file) = @_;
+ my($i,$count);
+ if ( $nodepend ) {
+ return "";
+ }
+ if ( ! $depend_path_fixed ) {
+ $depend_path_fixed = 1;
+ if ( defined($project{"DEPENDPATH"}) ) {
+ $depend_path = $project{"DEPENDPATH"};
+ } else {
+ $depend_path = "";
+ }
+ $count = 0;
+ while ( $count < 100 ) {
+ if ( $depend_path =~ s/(\$[\{\(]?\w+[\}\)]?)/035/ ) {
+ $_ = $1;
+ s/[\$\{\}\(\)]//g;
+ $depend_path =~ s/035/$ENV{$_}/g;
+ } else {
+ $count = 100;
+ }
+ }
+ @dep_path = &split_path($depend_path);
+ }
+ @cur_dep_path = @dep_path;
+ if ( $file =~ /(.*[\/\\])/ ) {
+ $dep_curdir = $1;
+ push @cur_dep_path, $dep_curdir;
+ } else {
+ $dep_curdir = "";
+ }
+ $dep_file = $file;
+ &canonical_dep($file);
+ %dep_dict = ();
+ $i = &build_dep($file);
+ chop $i;
+ $i =~ s=/=$dir_sep=g unless $is_unix;
+ $i =~ s=([a-zA-Z]):/=//$1/=g if (defined($gnuwin32) && $gnuwin32);
+ return join(" ${linebreak}\n\t\t",split(/ /,$i) );
+}
+
+#
+# build_dep() - Internal for make_depend()
+#
+
+sub build_dep {
+ my($file) = @_;
+ my(@i,$a,$n);
+ $a = "";
+ return $a if !(defined $depend_dict{$file});
+ @i = split(/ /,$depend_dict{$file});
+ for $n ( @i ) {
+ if ( !defined($dep_dict{$n}) && defined($full_path{$n}) ) {
+ $dep_dict{$n} = 1;
+ $a .= $full_path{$n} . " " . &build_dep($n);
+ }
+ }
+ return $a;
+}
+
+#
+# canonical_dep(file) - Internal for make_depend()
+#
+# Reads the file and all included files recursively.
+# %depend_dict associates a file name to a list of included files.
+#
+
+sub canonical_dep {
+ my($file) = @_;
+ my(@inc,$i);
+ @inc = &scan_dep($file);
+ if ( @inc ) {
+ $depend_dict{$file} = join(" ", at inc);
+ for $i ( @inc ) {
+ &canonical_dep($i) if !defined($depend_dict{$i});
+ }
+ }
+}
+
+#
+# scan_dep(file) - Internal for make_depend()
+#
+# Returns an array of included files.
+#
+
+sub scan_dep {
+ my($file) = @_;
+ my($dir,$path,$found, at allincs, at includes,%incs);
+ $path = $file;
+ @includes = ();
+ return @includes if $file =~ /\.$moc_ext$/; # avoid .moc files
+ if ( ! (-f fix_path($path)) ) {
+ $found = 0;
+ for $dir ( @cur_dep_path ) {
+ $path = $dir . $file;
+ last if ( $found = (-f fix_path($path)) );
+ }
+ return @includes if ! $found;
+ }
+ undef $/;
+ if ( open(TMP,fix_path($path)) ) {
+ $full_path{$file} = $path;
+ $_ = <TMP>;
+ s-/\*.*?\*/--gs; # strip C/C++ comments
+ s-//.*\n-\n-g;
+ @allincs = split(/\n/,$_);
+ @allincs = grep(/^\s*#\s*include/, at allincs);
+ foreach ( @allincs ) { # all #include lines
+ next if !(/^\s*#\s*include\s+[<"]([^>"]*)[>"]/) || defined($incs{$1});
+ push(@includes,$1);
+ $incs{$1} = "1";
+ }
+ close(TMP);
+ }
+ $/ = "\n";
+ return @includes;
+}
+
+
+#
+# split_path(path)
+#
+# Splits a path containing : (Unix) or ; (MSDOS, NT etc.) separators.
+# Returns an array.
+#
+
+sub split_path {
+ my($p) = @_;
+ my($s, at d);
+ @d = ();
+ return @d if !defined($p) || $p eq "";
+ $p =~ s=:=;=g if $is_unix;
+ $p =~ s=[/\\]+=/=g;
+ if ( !($p =~ /;/) ) {
+ $p =~ s/\s+/;/g;
+ }
+ $p =~ s/\s*;\s*/;/g;
+ while( $p =~ /(?:(?:[^\"\;][^\;]*;*)|(?:\"[^\"]*\";*))/g ) {
+ $s = $&;
+ $s =~ s=\"==g;
+ $s =~ s=[\s\;]+$==g;
+ $s =~ s=([^/:])$=$1/=g;
+ $s =~ s=/=$dir_sep=g unless $is_unix;
+ push @d, $s;
+ }
+ return @d;
+}
+
+
+#
+# fix_path(path)
+#
+# Converts all '\' to '/' if this really seems to be a Unix box.
+#
+
+sub fix_path {
+ my($p) = @_;
+ if ( $really_unix ) {
+ $p =~ s-\\-/-g;
+ } else {
+ $p =~ s-/-\\-g;
+ }
+ return $p;
+}
+
+
+#
+# mkdirp(filename,mode) - Internal for StdInit()
+#
+# Creates the directory specified by $filename, with permissions
+# specified by mode (as modified by umask). Recursively calls
+# mkdir, similar to 'mkdir -p'.
+#
+
+sub mkdirp {
+ my($filename,$mode) = @_;
+ if ( $filename =~ /\$\(\w+\)/ ) { # ignore "$(something)"
+ return 0;
+ }
+ $filename =~ s-[\\:/]+-/-g;
+ if ( -d $filename ) {
+ return 1;
+ }
+ $filename =~ m-^((.*)/)?(.*)-;
+ if ( defined($2) && ! mkdirp($2,$mode) ) {
+ return 0;
+ }
+ return mkdir($filename,$mode);
+}
diff --git a/tmake/doc/m-linux-gcc.html b/tmake/doc/m-linux-gcc.html
new file mode 100644
index 0000000..300ef35
--- /dev/null
+++ b/tmake/doc/m-linux-gcc.html
@@ -0,0 +1,85 @@
+<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
+<html><head><title>
+Generated Makefile for Linux / GNU g++
+</title></head><body bgcolor="#ffffff">
+<h2 align=center>Generated Makefile for Linux / GNU gcc</h2>
+
+<pre>
+#############################################################################
+# Makefile for building hello
+# Generated by tmake at 10:11, 1998/07/07
+# Project: hello
+# Template: app
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = g++
+CFLAGS = -Wall -W -O2 -fno-strength-reduce
+INCPATH = -I$(QTDIR)/include
+LINK = g++
+LFLAGS =
+LIBS = -L$(QTDIR)/lib -lqt -L/usr/X11R6/lib -lX11
+MOC = moc
+
+####### Files
+
+HEADERS = hello.h
+SOURCES = hello.cpp \
+ main.cpp
+OBJECTS = hello.o \
+ main.o
+SRCMOC = moc_hello.cpp
+OBJMOC = moc_hello.o
+TARGET = hello
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake hello.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+hello.o: hello.cpp \
+ hello.h
+
+main.o: main.cpp \
+ hello.h
+
+moc_hello.o: moc_hello.cpp \
+ hello.h
+
+moc_hello.cpp: hello.h
+ $(MOC) hello.h -o moc_hello.cpp
+</pre>
+</body></html>
diff --git a/tmake/doc/m-win32-msvc.html b/tmake/doc/m-win32-msvc.html
new file mode 100644
index 0000000..24097cc
--- /dev/null
+++ b/tmake/doc/m-win32-msvc.html
@@ -0,0 +1,89 @@
+<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
+<html><head><title>
+Generated Makefile for Win32 / Microsoft Visual C++
+</title></head><body bgcolor="#ffffff">
+<h2 align=center>Generated Makefile for Win32 / Microsoft Visual C++</h2>
+
+<pre>
+#############################################################################
+# Makefile for building hello
+# Generated by tmake at 20:40, 1998/02/27
+# Project: hello
+# Template: app
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cl
+CFLAGS = -nologo -W3 -O2
+INCPATH = -I"$(QTDIR)\include"
+LINK = link
+LFLAGS = /NOLOGO /SUBSYSTEM:windows
+LIBS = $(QTDIR)\lib\qt.lib user32.lib gdi32.lib comdlg32.lib wsock32.lib
+MOC = moc
+
+####### Files
+
+HEADERS = hello.h
+SOURCES = hello.cpp \
+ main.cpp
+OBJECTS = hello.obj \
+ main.obj
+SRCMOC = moc_hello.cpp
+OBJMOC = moc_hello.obj
+TARGET = hello.exe
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.obj:
+ $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+
+.cxx.obj:
+ $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+
+.cc.obj:
+ $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ $(LINK) $(LFLAGS) /OUT:$(TARGET) @<<
+ $(OBJECTS) $(OBJMOC) $(LIBS)
+<<
+
+moc: $(SRCMOC)
+
+tmake: Makefile
+
+Makefile: hello.pro
+ tmake hello.pro -o Makefile
+
+clean:
+ -del hello.obj
+ -del main.obj
+ -del moc_hello.cpp
+ -del moc_hello.obj
+ -del $(TARGET)
+
+####### Compile
+
+hello.obj: hello.cpp \
+ hello.h
+
+main.obj: main.cpp \
+ hello.h
+
+moc_hello.obj: moc_hello.cpp \
+ hello.h
+
+moc_hello.cpp: hello.h
+ $(MOC) hello.h -o moc_hello.cpp
+</pre>
+</body></html>
diff --git a/tmake/doc/tmake.html b/tmake/doc/tmake.html
new file mode 100644
index 0000000..1b14809
--- /dev/null
+++ b/tmake/doc/tmake.html
@@ -0,0 +1,727 @@
+<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
+<html><head><title>
+User's Guide - tmake
+</title></head><body bgcolor="#ffffff">
+<p><h1 align=center>User's Guide - tmake</h1>
+
+
+<hr>
+<h2>Introduction</h2>
+
+tmake is an easy-to-use tool from Troll Tech to create and maintain
+makefiles for software projects. It can be a painful task to manage
+makefiles manually, especially if you develop for more than one platform
+or use more than one compiler. tmake automates and streamlines this
+process and lets you spend your valuable time on writing code, not
+makefiles.
+
+<p>
+Our main motivation for developing tmake was that we spent far too much
+time maintaining makefiles for <a href="http://www.troll.no/qt">Qt</a>,
+our cross-platform GUI toolkit. Qt supports around 15 flavors of Unix,
+Microsoft Windows, and around 15 different C++ compilers. We looked at
+GNU autoconf, but it was Unix-specific and not flexible enough in our
+opinion. Our makefile system also had to deal with Qt <a
+href="http://www.troll.no/qt/metaobjects.html">meta object compiler</a>
+(moc) issues. The moc program extracts meta information from C++ files and
+generates a C++ file with data tables etc. It takes extra work to add
+makefile rules for the moc and wanted to automate this task.
+
+<p>
+tmake is written in Perl and requires that you have installed perl version
+5 or newer. Basic use of tmake requires no perl knowledge, but if you know
+perl you can extend tmake and write your own makefile templates.
+
+<p>
+<b>Windows users:</b> The tmake distribution for Win32 includes tmake.exe
+(built by the perl2exe utility) and you do not need to download and
+install perl unless you want to modify the tmake source code or run other
+perl scripts. You can download perl for Win32 (Windows NT and 95) from <a
+href="http://www.activestate.com">www.activestate.com</a>
+
+<p>
+tmake is free software and you may use, copy, modify and distribute tmake
+and its documentation for any purpose and without any fee. See the
+LICENSE file for details.
+
+<p>
+Feedback is highly appreciated. Contact the author, Haavard Nord <a
+href="mailto:hanord at troll.no">(hanord at troll.no)</a>, if you have ideas,
+patches etc. for tmake.
+
+<hr>
+<h2>Installation</h2>
+
+<ol>
+<li>Make sure you have perl version 5 or later installed (optional
+for Windows users).
+<li>Unpack the tmake tar.gz archive for Unix or the tmake .zip file for Windows.
+<li>Set the TMAKEPATH environment variable to the directories
+containing the template files (see below).
+<li>Add the tmake/bin directory to your PATH.
+</ol>
+
+Here are some examples:<p>
+<strong>Unix Bourne shell:</strong><pre>
+ TMAKEPATH=/local/tmake/lib/linux-g++
+ PATH=$PATH:/local/tmake/bin
+ export TMAKEPATH PATH
+</pre>
+
+<strong>Unix C shell:</strong><pre>
+ setenv TMAKEPATH /local/tmake/lib/linux-g++
+ setenv PATH $PATH:/local/tmake/bin
+</pre>
+
+<strong>Microsoft Windows:</strong><pre>
+ set TMAKEPATH=c:\tmake\lib\win32-msvc
+ set PATH=%PATH%;c:\tmake\bin
+</pre>
+
+<p>
+The template directory name has the form <em>platform</em>-<em>compiler</em>
+and contains a platform configuration file (tmake.conf) and tmake template
+files.
+
+<p>
+Supported platforms: AIX, Data General, FreeBSD, HPUX, SGI Irix, Linux,
+NetBSD, OpenBSD, OSF1/DEC, SCO, Solaris, SunOS, Ultrix, Unixware and
+Win32.
+
+<p>
+You can find your platform-compiler combination in the <tt>tmake/lib</tt>.
+
+<p>
+<b>Unix users:</b> tmake requires that perl is in /usr/bin. If your
+version of perl is elsewehere, either change the first line of tmake or
+make a small shell script which invokes tmake with the correct perl.
+
+
+<hr>
+<h2>Getting Started</h2>
+
+Let's assume you have a small Qt application consisting of one C++ header
+file and two source files.
+
+First you need to create a tmake project file, e.g. hello.pro:<pre>
+ HEADERS = hello.h
+ SOURCES = hello.cpp main.cpp
+ TARGET = hello
+</pre>
+
+Then run tmake to create a Makefile:<pre>
+ tmake hello.pro -o Makefile
+</pre>
+And finally:<pre>
+ make
+</pre>
+This builds the hello program. Remember to set the <code>TMAKEPATH</code>
+environment variable before you run tmake.
+<p>
+See <a href="m-linux-gcc.html">Makefile for Linux/g++</a>.<br>
+See <a href="m-win32-msvc.html">Makefile for Win32/msvc</a>
+(Microsoft Visual C++).<br>
+
+
+<hr>
+<h2>Makefile Templates</h2>
+
+The tmake distribution includes three makefile templates and one
+configuration file for each platform/compiler combination. The
+<code>TMAKEPATH</code> environment variable tells tmake where to find
+these files:
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>app.t</td>
+ <td> </td>
+ <td>Creates a makefile for building applications.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>lib.t</td>
+ <td> </td>
+ <td>Creates a makefile for building libraries.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>subdirs.t</td>
+ <td> </td>
+ <td>Creates a makefile for building targets in subdirectories.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>tmake.conf</td>
+ <td> </td>
+ <td>This configuration file contains compiler options and lists
+ tools and libraries.
+ </tr>
+</table>
+
+
+<p>
+The hello.pro project file above does not have a <code>TEMPLATE</code> or
+a <code>CONFIG</code> variable. The default template is <tt>app</tt> (the .t
+extension is optional) and the default configuration is <tt>qt warn_on
+release</tt>.
+
+This project file produces exactly the same result as the hello.pro
+above:<pre>
+ TEMPLATE = app
+ CONFIG = qt warn_on release
+ HEADERS = hello.h
+ SOURCES = hello.cpp main.cpp
+ TARGET = hello
+</pre>
+
+
+
+<h4>Makefile Configuration</h4>
+
+<p>
+The <code>CONFIG</code> variable is recognized by both the app.t and lib.t
+templates and specifies what compiler options to use and which extra
+libraries to link in.
+
+These options control the compilation flags:
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>release</td>
+ <td> </td>
+ <td>Compile with optimization enabled, ignored if
+ "debug" is specified.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>debug</td>
+ <td> </td>
+ <td>Compile with debug options enabled.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>warn_on</td>
+ <td> </td>
+ <td>The compiler should emit more warnings than normally, ignored if
+ "warn_off" is specified.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>warn_off</td>
+ <td> </td>
+ <td>The compiler should emit no warnings or as few as possible.</td>
+ </tr>
+</table>
+
+<p>
+These options defines the application/library type:
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>qt</td>
+ <td> </td>
+ <td>The target is a Qt application/library and requires Qt header
+ files/library.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>opengl</td>
+ <td> </td>
+ <td>The target requires the OpenGL (or Mesa) headers/libraries.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>x11</td>
+ <td> </td>
+ <td>The target is a X11 application or library.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>windows</td>
+ <td> </td>
+ <td>The target is a Win32 window application (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>console</td>
+ <td> </td>
+ <td>The target is a Win32 console application (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>dll</td>
+ <td> </td>
+ <td>The target is a shared object/DLL.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>staticlib</td>
+ <td> </td>
+ <td>The target is a static library (lib.t only).</td>
+ </tr>
+</table>
+
+<p>
+As an example, if the hello application uses both Qt and OpenGL and you
+want to compile it for debugging, your <code>CONFIG</code> line should
+read:<pre>
+ CONFIG = qt opengl debug
+</pre>
+
+<p>
+The most common tmake options and project variables are described here.
+See the tmake <a href="tmake_ref.html">reference manual</a> for
+details.<p>
+
+
+
+<h4>The Application Template</h4>
+
+The application template, app.t, lets you compile and link executable
+programs or shared objects (DLLs).
+
+This template recognizes several variabless.
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>HEADERS</td>
+ <td> </td>
+ <td>Header files.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>SOURCES</td>
+ <td> </td>
+ <td>Source files.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>TARGET</td>
+ <td> </td>
+ <td>Name of executable (adds .exe if on Windows).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>DESTDIR</td>
+ <td> </td>
+ <td>Where to put the target.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>DEFINES</td>
+ <td> </td>
+ <td>Tell compiler to define C preprocessor macros (-D option).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>INCLUDEPATH</td>
+ <td> </td>
+ <td>Sets the include file search path for the compiler (-I
+ option).
+ </td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>DEPENDPATH</td>
+ <td> </td>
+ <td>Sets the dependency search path for tmake.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>DEF_FILE</td>
+ <td> </td>
+ <td>Win32 only: Link with a .def file.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>RC_FILE</td>
+ <td> </td>
+ <td>Win32 only: Use a .rc file (compile to temporary .res).
+ </td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>RES_FILE</td>
+ <td> </td>
+ <td>Win32 only: Link with a .res file.
+ </td>
+ </tr>
+</table>
+
+<p>
+
+
+<h4>The Library Template</h4>
+
+The library template, lib.t, lets you compile and create static or shared
+libraries.
+
+<p>
+The lib.t template supports the same project variables as app.t, but also
+<code>VERSION</code>. <code>VERSION</code> is the version number of the
+target library, e.g. 1.40. The version is important for shared libraries.
+
+
+
+<h4>The Subdirs Template</h4>
+
+The subdirs template, subdirs.t, lets you invoke make in subdirectories.
+
+<p>The <code>SUBDIRS</code> variable contains the name of all subdirectories to
+be processed.
+
+
+<h4>Special Templates for Microsoft Visual C++</h4>
+
+If you have Microsoft Visual C++ 5.0, you can use two special templates to
+generate a MSVC++ IDE project (.dsp file). After you have generated
+e.g. hello.dsp, choose "File"->"Open Workspace" and select the hello.dsp
+file. Visual C++ will then create a workspace (.dsw file) for you.<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>vcapp.t</td>
+ <td> </td>
+ <td>Creates an application project file (Microsoft Visual C++ 5.0
+ only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>vclib.t</td>
+ <td> </td>
+ <td>Creates a library project file (Microsoft Visual C++ 5.0
+ only).</td>
+ </tr>
+</table>
+
+<p>
+Run tmake to create a hello.dsp file (use -t to override the default
+template):<pre>
+ tmake -t vcapp -o hello.dsp hello.pro
+</pre>
+
+
+<hr>
+<h2>Project File Syntax</h2>
+
+The tmake project file has a very simple syntax. You may set
+project variables, append to project variables, remove from
+project variable and substitute project variables.
+
+To set a project variable:<pre>
+ HEADERS = gui.h xml.h url.h
+</pre>
+
+If you cannot fit everything on one line, use '\' to split it up:<pre>
+ HEADERS = gui.h \
+ xml.h \
+ url.h
+</pre>
+
+<p>
+Project variables contains lists of items (such as header files,
+compiler options etc.) and use whitespace to separate the items.
+This means that tmake cannot deal with items containing whitespace.
+The INCLUDEPATH variable is an exception. If INCLUDEPATH contains
+one or more semicolons (;), tmake uses the semicolon to separate
+the include directories, hence you can have include directories
+containing whitespace (this is quite common on Windows).
+
+<p>
+Here is an example:<pre>
+ INCLUDEPATH = C:\Program Files\DBLib\Include;C:\qt\include
+</pre>
+
+<p>
+tmake supports <em>project variable expension</em>. Use $$ to expand
+any project variable:<pre>
+ ALLFILES = $$HEADERS $$SOURCES
+</pre>
+
+<p>
+Most often you assign some value to a project variable, but you can
+also add to, remove from or replace parts of a project variable.<pre>
+ A = abc
+ X = xyz
+ A += def # A = abc def
+ X *= xyz # X = xyz
+ B = $$A # B = abc def
+ B -= abc # B = def
+ X /= s/y/Y/ # X = xYz
+</pre>
+The *= operation adds the value if the variable does not already contain it.
+The /= operation performs regular expression substitution.
+
+<p>
+You can also set variables from the command line when running the tmake
+program. For instance, if you want to generate a makefile with debug
+information:<pre>
+ tmake "CONFIG+=debug" hello.pro
+</pre>
+
+<p>
+Use the <tt>unix:</tt> or <tt>win32:</tt> (conditional) qualifier if you want a
+platform-specific variable:<pre>
+ SOURCES = common.cpp # common for all platforms
+ unix:SOURCES += unix.cpp # additional sources for Unix
+ win32:SOURCES += win32.cpp # additional sources for Windows
+ unix:LIBS += -lm # on Unix we need the math lib
+</pre>
+If none of the platforms match, tmake looks for the variable in CONFIG
+variable:<pre>
+ debug:SOURCES += dbgstuff.cpp # additional source for debugging
+</pre>
+
+Finally, you can set platform and compiler-dependent variables:<pre>
+ linux-g++:TMAKE_CFLAGS = -fno-rtti
+</pre>
+
+<p>
+You may define your own project variables to be used by custom templates. A
+project variable is stored in <code>%project</code>, which is an associative
+Perl array. Access it like this: <code>$project{"var"}</code> or via the
+function <code>Project("var")</code>. For example, after reading
+"hello.pro", <code>$project{"SOURCES"}</code> contains "hello.cpp
+main.cpp".<p>
+
+
+<hr>
+<h2><a name="usage"></a>Running tmake</h2>
+
+Usage:<pre>
+ tmake [options] <em>project files or project settings</em>
+</pre>
+Options:<pre>
+ -e expr Evaluate the Perl expression. Ignores the template file.
+ -nodepend Don't generate dependency information.
+ -o <em>file</em> Write output to <em>file</em> instead of stdout.
+ -t <em>file</em> Specify a template <em>file</em>.
+ -unix Force tmake into Unix mode.
+ -v Verbose/debugging on.
+ -win32 Force tmake into Win32 mode.
+</pre>
+
+The -t option overrides any <code>TEMPLATE</code> variable in the project file.
+<p>
+The default project file extension is ".pro". The default template file
+extension is ".t". If you do not specify these extension tmake will
+automatically add them for you.
+
+<p>
+Example of basic use:<pre>
+ tmake hello -o Makefile
+</pre>
+
+<p>
+Example of how to create a makefile with debugging information:<pre>
+ tmake "CONFIG+=debug" hello -o Makefile
+</pre>
+
+<p>
+Exmaple of how to specify a TMAKEPATH:<pre>
+ tmake "TMAKEPATH=/local/tmake/lib/hpux-g++" hello.pro -o Makefile
+</pre>
+
+Example of how to evaluate a perl expression (print names of headers
+and source files):<pre>
+ tmake hello -e 'Expand("HEADERS","SOURCES")'
+</pre>
+
+<hr>
+<h2><a name="progen"></a>The progen Utility</h2>
+
+The progen utility creates project files for you. It can be used like
+this:<pre>
+ progen -n hello -o hello.pro
+</pre>
+If no .cpp or .h files are specified on the command line, progen
+searches for .cpp and .h (except moc_*.cpp) in the current directory
+and below.
+<p>
+Usage:<pre>
+ progen [options] [<em>C/C++ header files and source files</em>]
+</pre>
+Options:<pre>
+ -lower Lower-case letters in filenames (useful on Windows).
+ -n <em>name</em> Specify a project name (<code>TARGET</code>).
+ -o <em>file</em> Write output to <em>file</em> instead of stdout.
+ -t <em>file</em> Specify a template <em>file</em>.
+</pre>
+
+
+<hr>
+<h2>Advanced Topics</h2>
+
+In most cases you will be happy with using tmake as described above, but
+sometimes you need to add special compiler options or even add new
+makefile rules. This chapter describes how to customize your makefiles.
+
+<h4>Conditional Project Settings</h4>
+
+If you need a special compiler option etc., you can add platform-dependent
+settings in your project file:<pre>
+ solaris-cc:TMAKE_CC = /opt/bin/CC_5.0
+ solaris-cc:TMAKE_CFLAGS = -pts
+ unix:TMAKE_LIBS = -lXext
+ win32:INCLUDEPATH = c:\myinclude
+ win32-borland:DEFINES = NO_BOOL
+</pre>
+
+You can prefix a project variable with unix: or win32: to make it specific for
+either Unix or Windows. You can also prefix a variable with
+<em>platform-compiler</em>
+
+<h4>Your Own Templates</h4>
+
+If you know Perl programming, there is virtually no limitation to what you
+can do with tmake. First you need to know how tmake works.
+
+<h4>Template Processing</h4>
+
+When you run tmake, it first reads the <tt>tmake.conf</tt> file.
+This configuration file has the same syntax as the project file.
+
+tmake then reads the project file and sets the project variables it
+finds, e.g. <code>HEADERS</code>, <code>SOURCES</code> etc.
+
+All variables and values are stored in a global associative Perl hash
+array called <code>project</code>. For example,
+<code>$project{"SOURCES"}</code> contains "hello.cpp main.cpp"
+after processing hello.pro.
+
+When both the <tt>tmake.conf</tt> and the project files have been
+read, tmake starts reading the template file line by line and
+executes any Perl code it finds in the template.
+
+<ul>
+<li>Anything after <code>#$</code> until newline is
+ evaluated as perl code. The perl code is substituted
+ with the contents of the <code>$text</code>
+ variable.
+<li>Block of perl code: <code>#${</code> until
+ <code>#$}</code>.
+<li>Comments; <code>#!</code> until newline is stripped.
+<li>Anything else is copied directly from the template to
+ the output.
+</ul>
+
+<p>
+Example:<pre>
+ #! This is a comment which will be removed.
+ This text will appear in the output.
+ #$ $text = "The header file(s) are: " . $project{"HEADERS"};
+ # This text also appears in the output.
+ #${
+ $a = 12;
+ $b = 13;
+ $text = $a * $b;
+ #$}
+ That's all.
+</pre>
+Output:<pre>
+ This text will appear in the output.
+ The header file(s) are: hello.h
+ # This text also appears in the output.
+ 156
+ That's all.
+</pre>
+
+
+<h3>Using tmake With Lex and Yacc</h3>
+
+The standard tmake templates knows how to process C and C++ files, but
+sometimes you need to process additional files and link them into your
+project. A typical example is to process lex and yacc files when you're
+building a parser.
+
+<p>
+Parser template:<pre>
+ #!
+ #! parser.t: This is a custom template for building a parser
+ #!
+ #$ IncludeTemplate("app.t");
+
+ ####### Lex/yacc programs and options
+
+ LEX = flex
+ YACC = #$ $text = ($is_unix ? "yacc -d" : "byacc -d");
+
+ ####### Lex/yacc files
+
+ LEXIN = #$ Expand("LEXINPUT");
+ LEXOUT = lex.yy.c
+ YACCIN = #$ Expand("YACCINPUT");
+ YACCOUT = y.tab.c
+ YACCHDR = y.tab.h
+ PARSER = #$ Expand("PARSER");
+
+ ####### Process lex/yacc files
+
+ $(LEXOUT): $(LEXIN)
+ $(LEX) $(LEXIN)
+
+ $(PARSER): $(YACCIN) $(LEXOUT)
+ $(YACC) $(YACCIN)
+ #$ $text = ($is_unix ? "-rm -f " : "-del ") . '$(PARSER)';
+ #$ $text = ($is_unix ? "-mv " : "-ren ") . '$(YACCOUT) $(PARSER)';
+</pre>
+
+The parser template adds some extra rules to the application template
+in order to build the lex and yacc portions of the project. This
+template is portable across Unix and Windows since it generates different
+commands depending on the <code>$is_unix</code> variable.
+
+<p>
+To learn more about the Expand() function and other Perl functions which
+tmake provides, consult the <a href="tmake_ref.html">reference manual</a>.
+
+<p>
+Example project file:<pre>
+ TEMPLATE = parser.t
+ CONFIG = console release
+ LEXINPUT = lexer.l
+ YACCINPUT = grammar.y
+ PARSER = parser.cpp
+ SOURCES = $$PARSER \
+ node.cpp \
+ asmgen.cpp
+ TARGET = parser
+</pre>
+
+Here we use macro expansion <code>$$PARSER</code> to avoid writing parser.cpp
+two places.
+
+
+<h3>Counting the Number of Code Lines</h3>
+
+tmake is generic since it is based on Perl. You can create your own
+templates for other purposes than producing makefiles. Here is an example
+template that counts the number of code lines in our project.
+
+<p>
+Template wc.t:<pre>
+ #! Template that count number of C++ lines.
+ The number of C++ code lines for #$ $text=$project_name;
+ #${
+ $files = $project{"HEADERS"} . " " . $project{"SOURCES"};
+ $text = `wc -l $files`;
+ #$}
+</pre>
+Run it:<pre>
+ tmake -t wc hello
+</pre>
+Output:<pre>
+ The number of C++ code lines for hello.pro
+ 25 hello.h
+ 98 hello.cpp
+ 38 main.cpp
+ 161 total
+</pre>
+This will only work if the wc program is installed on your system.
+
+
+</body></html>
diff --git a/tmake/doc/tmake_ref.html b/tmake/doc/tmake_ref.html
new file mode 100644
index 0000000..c9124c4
--- /dev/null
+++ b/tmake/doc/tmake_ref.html
@@ -0,0 +1,463 @@
+<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
+<html><head><title>
+Reference Manual - tmake
+</title></head><body bgcolor="#ffffff">
+<p><h1 align=center>Reference Manual - tmake</h1>
+
+<hr>
+<h2>Project Variable Reference</h2>
+
+<h4><a name="ALL_DEPS"></a>ALL_DEPS</h4>
+Specifies additional dependencies for the makefile target "all:".<p>
+
+
+<h4><a name="CLEAN_FILES"></a>CLEAN_FILES</h4>
+Specifies additional files to be removed for "make clean".<p>
+Example:<pre>
+ CLEAN_FILES = core *~
+</pre>
+
+
+<h4><a name="CONFIG"></a>CONFIG</h4>
+Sets the make configuration. It tells the tmake templates what compiler
+options to use and which extra libraries to link in.<p>
+These options control the compilation flags:
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>release</td>
+ <td> </td>
+ <td>Compile with optimization enabled, ignored if
+ "debug" is specified.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>debug</td>
+ <td> </td>
+ <td>Compile with debug options enabled.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>warn_on</td>
+ <td> </td>
+ <td>The compiler should emit more warnings than normally, ignored if
+ "warn_off" is specified.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>warn_off</td>
+ <td> </td>
+ <td>The compiler should emit no warnings or as few as possible.</td>
+ </tr>
+</table>
+
+<p>
+These options defines the application/library type:
+<p>
+<table border="0">
+ <tr>
+ <td> </td>
+ <td>qt</td>
+ <td> </td>
+ <td>The target is a Qt application/library and requires Qt header
+ files/library.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>opengl</td>
+ <td> </td>
+ <td>The target requires the OpenGL (or Mesa) headers/libraries.</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>x11</td>
+ <td> </td>
+ <td>The target is a X11 application (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>windows</td>
+ <td> </td>
+ <td>The target is a Win32 window application (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>console</td>
+ <td> </td>
+ <td>The target is a Win32 console application (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>dll</td>
+ <td> </td>
+ <td>The target is a shared object/DLL (app.t only).</td>
+ </tr>
+ <tr>
+ <td> </td>
+ <td>staticlib</td>
+ <td> </td>
+ <td>The target is a static library (lib.t only).</td>
+ </tr>
+</table>
+
+
+<h4><a name="DEFINES"></a>DEFINES</h4>
+Specifies C/C++ macros (-D compiler option). On Windows you need
+to let DEFINES contain "QT_DLL" if you are building a Qt program
+which should link with the Qt DLL.
+
+
+<h4><a name="DEF_FILE"></a>DEF_FILE</h4>
+Win32/app.t only: Specifies a .def file.
+
+
+<h4><a name="DESTDIR"></a>DESTDIR</h4>
+Specifies where to put the target file.
+Example:<pre>
+ DESTDIR = ../../lib
+</pre>
+You must create this directory before running make.
+
+
+<h4><a name="HEADERS"></a>HEADERS</h4>
+Defines the header files of the project.
+
+
+<h4><a name="INCPATH"></a>INCPATH</h4>
+This variable is generated from <code>INCLUDEPATH</code>. The ';' or ':'
+separators have been replaced by ' ' (single space). This makes it
+easier to split. qtapp.t and other templates expand
+<code>INCPATH</code> to set -I options for the C++ compiler.
+
+
+<h4><a name="INCLUDEPATH"></a>INCLUDEPATH</h4>
+This variable specifies the #include directories. It can be set in the
+project file, or by the <a href="#AddIncludePath">AddIncludePath()</a>
+function.<p>
+Example:<pre>
+ INCLUDEPATH = c:\msdev\include d:\stl\include
+</pre>
+Use ';' or space as the directory separator.
+
+
+<h4><a name="LIBS"></a>LIBS</h4>
+Defines additional libraries to be linked in when creating an application
+or a shared library. You probably want to use a platform qualifier since
+libraries are specified differently on Unix and Win32.<p>
+Example:<pre>
+ unix:LIBS = -lXext -lm
+ win32:LIBS = ole32.lib
+</pre>
+
+
+<h4><a name="MOC_DIR"></a>MOC_DIR</h4>
+Specifies where to put the temporary moc output files. By default they
+are stored in the directory where the moc input files are.
+<p>
+Example:<pre>
+ MOC_DIR = tmp
+</pre>
+You must create this directory before running make.
+<p>
+See also: <a href="#OBJECTS_DIR">OBJECTS_DIR</a>.
+
+
+<h4><a name="OBJECTS"></a>OBJECTS</h4>
+This varialble is generated from <code>SOURCES</code> by the StdInit() function.
+The extension of each source file has been replaced by .o (Unix) or .obj
+(Win32).<p>
+Example:<pre>
+ SOURCES = a.x b.y
+</pre>
+Then <code>OBJECTS</code> become "a.o b.o" on Unix and "a.obj b.obj" on
+Win32.
+
+
+<h4><a name="OBJECTS_DIR"></a>OBJECTS_DIR</h4>
+Specifies where to put object files. By default they are stored in
+the directory where the source files are.<p>
+Example:<pre>
+ OBJECTS_DIR = tmp
+</pre>
+You must create this directory before running make.
+<p>
+See also: <a href="#MOC_DIR">MOC_DIR</a>.
+
+
+<h4><a name="OBJMOC"></a>OBJMOC</h4>
+This variable is generated by the <a href="#StdInit">StdInit()</a> function if
+<code>$moc_aware</code> is true. <code>OBJMOC</code> contains the name of
+all intermediate moc object files.<p>
+Example:<pre>
+ HEADERS = demo.h
+ SOURCES = demo.cpp main.cpp
+</pre>
+If <tt>demo.h</tt> and <tt>main.cpp</tt> define classes that use signals
+and slots (i.e. the <code>Q_OBJECT</code> "keyword" is found in these two
+files), <code>OBJMOC</code> becomes:<pre>
+ OBJMOC = moc_demo.obj
+</pre>
+See also: <a href="#SRCMOC">SRCMOC</a>.
+
+
+<h4><a name="PROJECT"></a>PROJECT</h4>
+This is the name of the project. It defaults to the name of the project
+file, excluding the .pro extension.
+
+
+<h4><a name="RC_FILE"></a>RC_FILE</h4>
+Win32/app.t only: Specifies a .rc file. Cannot be used with the RES_FILE
+variable.
+
+
+<h4><a name="RES_FILE"></a>RES_FILE</h4>
+Win32/app.t only: Specifies a .res file. You can either specify a
+.rc file or one or more .res files.
+
+
+<h4><a name="SOURCES"></a>SOURCES</h4>
+Defines the source files of the project.
+
+
+<h4><a name="SRCMOC"></a>SRCMOC</h4>
+This variable is generated by the <a href="#StdInit">StdInit()</a> function if
+<code>CONFIG</code> contains "qt". <code>SRCMOC</code> contains the name of
+all intermediate moc files.<p>
+Example:<pre>
+ HEADERS = demo.h
+ SOURCES = demo.cpp main.cpp
+</pre>
+If <tt>demo.h</tt> and <tt>main.cpp</tt> define classes that use signals
+and slots (i.e. the <code>Q_OBJECT</code> "keyword" is found in these two
+files), <code>SRCMOC</code> becomes:<pre>
+ SRCMOC = moc_demo.cpp main.moc
+</pre>
+See also: <a href="#OBJMOC">OBJMOC</a>.
+
+
+<h4><a name="TARGET"></a>TARGET</h4>
+Sets the makefile target, i.e. what program to build.
+
+
+<h4><a name="TEMPLATE"></a>TEMPLATE</h4>
+Sets the default template. This can be overridden by the tmake -t
+<a href="tmake.html#usage">option</a>.
+
+
+<h4><a name="TMAKE_CC"></a>TMAKE_CC</h4>
+Contains the name of the compiler.
+
+
+<h4><a name="TMAKE_CFLAGS"></a>TMAKE_CFLAGS</h4>
+Contains the default compiler flags.
+
+
+<h4><a name="TMAKE_FILEVARS"></a>TMAKE_FILEVARS</h4>
+Tells tmake which variables contain file names. This is because tmake
+on Windows replace the directory separator / with \.
+
+
+<hr>
+<h2>Function Reference</h2>
+This section contains a brief description of some important
+tmake functions used by the templates.
+
+
+<h3><a name="AddIncludePath"></a>AddIncludePath(path)</h3>
+Adds <em>path</em> to the include path variable,
+<a href="#INCLUDEPATH">INCLUDEPATH</a>. The include path is used
+for two purposes:<ol>
+<li>Searching files when generating include dependencies.
+<li>Setting -I options for the C/C++ compiler.
+</ol>
+<p>
+Example:<pre>
+ #$ AddIncludePath('$QTDIR/include;/local/include');
+</pre>
+
+
+<h3>BuildMocObj(objects,sources)</h3>
+Creates build rules for moc source files. Generates
+include dependencies.<p>
+Example:<pre>
+ #$ BuildMocObj($project{"OBJMOC"},$project{"SRCMOC"});
+</pre>Output:<pre>
+ moc_hello.o: moc_hello.cpp \
+ hello.h \
+ ...
+</pre>
+
+<h3>BuildMocSrc(files)</h3>
+Creates moc source files from C++ files containing classes that
+define signals and slots. For a header file <tt>x.h</tt>, the
+generated moc file is called <tt>moc_x.h</tt>. For a source file
+<tt>y.cpp</tt>, the generates moc file is called <tt>y.moc</tt> and
+should be #include'd by <tt>y.cpp</tt>.<p>
+Example:<pre>
+ #$ BuildMocSrc($project{"HEADERS"});
+ #$ BuildMocSrc($project{"SOURCES"});
+</pre>Output:<pre>
+ moc_hello.cpp: hello.h
+ $(MOC) hello.h -o moc_hello.cpp
+</pre>
+
+
+<h3>BuildObj(objects,sources)</h3>
+Creates build rules for source files. Generates
+include dependencies.<p>
+Example:<pre>
+ #$ BuildObj($project{"OBJECTS"},$project{"SOURCES"});
+</pre>Output:<pre>
+ hello.o: hello.cpp \
+ hello.h \
+ ...
+
+ main.o: main.cpp \
+ hello.h \
+ ...
+</pre>
+
+
+<h3>Config(string)</h3>
+Returns true if the <code>CONFIG</code> variable contains the given string.
+<p>Example:<pre>
+ #$ if ( Config("release") { }
+</pre>
+
+
+<h3>DisableOutput()</h3>
+Call this function to force tmake to generate no output until
+EnableOutput() is called.
+<p>Example:<pre>
+ #$ Config("debug") && DisableOutput();
+ Anything here is skipped if CONFIG contains "debug".
+ #$ Config("debug") && EnableOutput();
+</pre>
+
+
+<h3>EnableOutput()</h3>
+Enables tmake output after DisableOutput() was called.
+
+
+<h3>Expand(var)</h3>
+Expands a project variable. Equivalent to <code>$text = $project{$var}</code>.
+<p>Example:<pre>
+ VERSION = #$ Expand("VERSION");
+</pre>Output:<pre>
+ VERSION = 1.1
+</pre>
+
+<h3>ExpandGlue(var,prepend,glue,append)</h3>
+Expands a $project{} variable, splits on whitespace
+and joins with $glue. $prepend is put at the start
+of the string and $append is put at the end of the
+string. The resulting string ($text) becomes "" if
+the project variable is empty or not defined.<p>
+Example:<pre>
+ clear:
+ #$ ExpandGlue("OBJECTS","-del","\n\t-del ","");
+</pre>Output (Windows NT):<pre>
+ clear:
+ -del hello.obj
+ -del main.obj
+</pre>
+
+
+<h3>ExpandList(var)</h3>
+This function is suitable for expanding lists of files.
+Equivalent with <code>ExpandGlue($var,""," \\\n\t\t","")</code>.<p>
+Example:<pre>
+ OBJECTS = #$ ExpandList("OBJECTS");
+</pre>Output:<pre>
+ OBJECTS = hello.o \
+ main.o
+</pre>
+
+
+<h3>ExpandPath(var,prepend,glue,append)</h3>
+Similar to ExpandGlue, except that it splits the items on a semicolon
+instead of space (if the variable contains at least one semicolon).
+
+
+<h3>IncludeTemplate(file)</h3>
+Includes a template file. The ".t" extension is optional.<p>
+Example:<pre>
+ #$ IncludeTemplate("mytemplate");
+</pre>
+
+
+<h3>Now()</h3>
+Sets $text to the current date and time.<p>
+Example:<pre>
+ # Generated at #$ Now()
+</pre>Output:<pre>
+ # Generated at 12:58, 1996/11/19
+</pre>
+
+
+<h3>Project(strings)</h3>
+This is a powerful function for setting and reading project
+variables. Returns the resulting project variables (joined with space
+between).
+<p>Examples:<pre>
+# Get a project variable:
+ $s = Project("TEMPLATE"); -> $s = "TEMPLATE"
+
+# Set a project variable:
+ Project("TEMPLATE = lib"); -> TEMPLATE = lib
+ Project("CONFIG =";) -> CONFIG empty
+
+# Append to a project variable:
+ Project("CONFIG = qt"); -> CONFIG = qt
+ Project("CONFIG += debug"); -> CONFIG = qt debug
+
+# Append to a project variable if it does not contain the value already:
+ Project("CONFIG = qt release"); -> CONFIG = qt release
+ Project("CONFIG *= qt"); -> CONFIG = qt release
+ Project("CONFIG *= opengl"); -> CONFIG = qt release opengl
+
+# Subtract from a project variable:
+ Project("THINGS = abc xyz"); -> THINGS = abc xyz
+ Project("THINGS -= abc"); -> THINGS = xyz
+
+# Search/replace on a project variable:
+ Project("CONFIG = tq opengl"); -> CONFIG = tq opengl
+ Project("CONFIG /= s/tq/qt/"); -> CONFIG = qt opengl
+
+# The operations can be performed on several project variables at a time.
+
+ Project("TEMPLATE = app", "CONFIG *= opengl", "THINGS += klm");
+</pre>
+
+
+<h3><a name="ScanProject"></a>ScanProject(file)</h3>
+Scans a project file and stores the project variables and values in the
+global associative <code>%project</code> array.
+
+
+<h3><a name="StdInit"></a>StdInit()</h3>
+Standard initialization of tmake. StdInit() should be
+called from one of the first lines in the template.<p>
+
+This function creates some new project variables:<ul>
+<li><code><a href="#OBJECTS">OBJECTS</a></code>
+ - Object files corresponding to
+ <code><a href="#SOURCES">SOURCES</a></code>.
+<li><code><a href="#SRCMOC">SRCMOC</a></code> - moc source files.
+<li><code><a href="#OBJMOC">OBJMOC</a></code> - moc object files.
+</ul>
+
+The moc-related variables are created only if <code>CONFIG</code> contains "qt"
+
+
+<h3>Substitute(string)</h3>
+This function takes a string and substitutes any occurrence of $$var
+with the actual content of the variable. Returns the substituted string.
+Also sets $text.
+<p>
+Important: Use single quotes around the string, otherwise perl will expand
+any $vars it finds.
+<p>Example:<pre>
+ Substitute('Project name: $$PROJECT, uses template $$TEMPLATE');
+</pre>
diff --git a/tmake/example/hello.cpp b/tmake/example/hello.cpp
new file mode 100644
index 0000000..4868c4d
--- /dev/null
+++ b/tmake/example/hello.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+**
+** Copyright (C) 1992-1998 Troll Tech AS. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "hello.h"
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+
+
+/*
+ Constructs a Hello widget. Starts a 40 ms animation timer.
+*/
+
+Hello::Hello( const char *text, QWidget *parent, const char *name )
+ : QWidget(parent,name), t(text), b(0)
+{
+ QTimer *timer = new QTimer(this);
+ connect( timer, SIGNAL(timeout()), SLOT(animate()) );
+ timer->start( 40 );
+
+ resize( 200, 100 );
+}
+
+
+/*
+ This private slot is called each time the timer fires.
+*/
+
+void Hello::animate()
+{
+ b = (b + 1) & 15;
+ repaint( FALSE );
+}
+
+
+/*
+ Handles mouse button release events for the Hello widget.
+
+ We emit the clicked() signal when the mouse is released inside
+ the widget.
+*/
+
+void Hello::mouseReleaseEvent( QMouseEvent *e )
+{
+ if ( rect().contains( e->pos() ) )
+ emit clicked();
+}
+
+
+/*
+ Handles paint events for the Hello widget.
+
+ Flicker-free update. The text is first drawn in the pixmap and the
+ pixmap is then blt'ed to the screen.
+*/
+
+void Hello::paintEvent( QPaintEvent * )
+{
+ static int sin_tbl[16] = {
+ 0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38};
+
+ if ( t.isEmpty() )
+ return;
+
+ // 1: Compute some sizes, positions etc.
+ QFontMetrics fm = fontMetrics();
+ int w = fm.width(t) + 20;
+ int h = fm.height() * 2;
+ int pmx = width()/2 - w/2;
+ int pmy = height()/2 - h/2;
+
+ // 2: Create the pixmap and fill it with the widget's background
+ QPixmap pm( w, h );
+ pm.fill( this, pmx, pmy );
+
+ // 3: Paint the pixmap. Cool wave effect
+ QPainter p;
+ int x = 10;
+ int y = h/2 + fm.descent();
+ int i = 0;
+ p.begin( &pm );
+ p.setFont( font() );
+ while ( t[i] ) {
+ int i16 = (b+i) & 15;
+ p.setPen( QColor((15-i16)*16,255,255,QColor::Hsv) );
+ p.drawText( x, y-sin_tbl[i16]*h/800, &t[i], 1 );
+ x += fm.width( t[i] );
+ i++;
+ }
+ p.end();
+
+ // 4: Copy the pixmap to the Hello widget
+ bitBlt( this, pmx, pmy, &pm );
+}
diff --git a/tmake/example/hello.h b/tmake/example/hello.h
new file mode 100644
index 0000000..07fb8c5
--- /dev/null
+++ b/tmake/example/hello.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+**
+** Copyright (C) 1992-1998 Troll Tech AS. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef HELLO_H
+#define HELLO_H
+
+#include <qwidget.h>
+
+
+class Hello : public QWidget
+{
+ Q_OBJECT
+public:
+ Hello( const char *text, QWidget *parent=0, const char *name=0 );
+signals:
+ void clicked();
+protected:
+ void mouseReleaseEvent( QMouseEvent * );
+ void paintEvent( QPaintEvent * );
+private slots:
+ void animate();
+private:
+ QString t;
+ int b;
+};
+
+#endif
diff --git a/tmake/example/hello.pro b/tmake/example/hello.pro
new file mode 100644
index 0000000..a299923
--- /dev/null
+++ b/tmake/example/hello.pro
@@ -0,0 +1,3 @@
+HEADERS = hello.h
+SOURCES = hello.cpp main.cpp
+TARGET = hello
diff --git a/tmake/example/main.cpp b/tmake/example/main.cpp
new file mode 100644
index 0000000..4b55a58
--- /dev/null
+++ b/tmake/example/main.cpp
@@ -0,0 +1,38 @@
+//
+// File: main.cpp
+//
+// A small Qt example application written by Troll Tech.
+//
+// It displays a text in a window and quits when you click
+// the mouse in the window.
+//
+
+#include "hello.h"
+#include <qapp.h>
+
+
+/*
+ The program starts here. It parses the command line and build a message
+ string to be displayed by the Hello widget.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication a(argc,argv);
+ QString s;
+ for ( int i=1; i<argc; i++ ) {
+ s += argv[i];
+ if ( i<argc-1 )
+ s += " ";
+ }
+ if ( s.isEmpty() )
+ s = "Hello, World";
+ Hello h( s );
+ h.setCaption( "Qt says hello" );
+ QObject::connect( &h, SIGNAL(clicked()), &a, SLOT(quit()) );
+ h.setFont( QFont("times",32,QFont::Bold) ); // default font
+ h.setBackgroundColor( white ); // default bg color
+ a.setMainWidget( &h );
+ h.show();
+ return a.exec();
+}
diff --git a/tmake/example/wc.t b/tmake/example/wc.t
new file mode 100644
index 0000000..dc041b5
--- /dev/null
+++ b/tmake/example/wc.t
@@ -0,0 +1,6 @@
+#! Template that count number of C++ lines
+The number of C++ code lines for #$ $text=$project_name;
+#${
+ $files = $project{"HEADERS"} . " " . $project{"SOURCES"};
+ $text = `wc -l $files`;
+#$}
diff --git a/tmake/lib/aix-g++/app.t b/tmake/lib/aix-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/aix-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/aix-g++/lib.t b/tmake/lib/aix-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/aix-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/aix-g++/subdirs.t b/tmake/lib/aix-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/aix-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/aix-g++/tmake.conf b/tmake/lib/aix-g++/tmake.conf
new file mode 100644
index 0000000..897d509
--- /dev/null
+++ b/tmake/lib/aix-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for aix-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB =
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB =
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/aix-xlc/app.t b/tmake/lib/aix-xlc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/aix-xlc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/aix-xlc/lib.t b/tmake/lib/aix-xlc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/aix-xlc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/aix-xlc/subdirs.t b/tmake/lib/aix-xlc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/aix-xlc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/aix-xlc/tmake.conf b/tmake/lib/aix-xlc/tmake.conf
new file mode 100644
index 0000000..4013923
--- /dev/null
+++ b/tmake/lib/aix-xlc/tmake.conf
@@ -0,0 +1,64 @@
+#
+#
+#
+# tmake configuration for aix-xlc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = xlc
+TMAKE_CFLAGS = -qstrict
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = xlC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = xlC
+TMAKE_LINK_SHLIB = ld
+TMAKE_LINK_SHLIB_CMD = /usr/lpp/xlC/bin/makeC++SharedLib -p 0 \
+ -o lib$(TARGET).so.$(VER_MAJ).$(VER_MIN) \
+ -lXext -lX11 $(OBJECTS) $(OBJMOC); \
+ ar q lib$(TARGET).a lib$(TARGET).so.$(VER_MAJ).$(VER_MIN); \
+ ranlib lib$(TARGET).a; \
+ mv lib$(TARGET).a $(DESTDIR)
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB =
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -liconv
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/beos-g++/app.t b/tmake/lib/beos-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/beos-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/beos-g++/lib.t b/tmake/lib/beos-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/beos-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/beos-g++/subdirs.t b/tmake/lib/beos-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/beos-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/beos-g++/tmake.conf b/tmake/lib/beos-g++/tmake.conf
new file mode 100644
index 0000000..b6649c9
--- /dev/null
+++ b/tmake/lib/beos-g++/tmake.conf
@@ -0,0 +1,51 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE =
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS = -Wl,-rpath=/lib:$(QTDIR)/lib
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/bsdi-g++/app.t b/tmake/lib/bsdi-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/bsdi-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/bsdi-g++/lib.t b/tmake/lib/bsdi-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/bsdi-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/bsdi-g++/subdirs.t b/tmake/lib/bsdi-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/bsdi-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/bsdi-g++/tmake.conf b/tmake/lib/bsdi-g++/tmake.conf
new file mode 100644
index 0000000..65f7316
--- /dev/null
+++ b/tmake/lib/bsdi-g++/tmake.conf
@@ -0,0 +1,61 @@
+#
+#
+#
+# tmake configuration for bsdi-shlicc++, bsdi 4.0
+#
+# shlicc/++ is a BSDI wrapper around cc/g++ that enables shared libs
+# (info/7367)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = shlicc++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = shlicc++
+TMAKE_LINK_SHLIB = shlicc++
+TMAKE_LFLAGS = -Wl,-rpath=/lib:/usr/X11R6/lib:$(QTDIR)/lib
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/dgux-g++/app.t b/tmake/lib/dgux-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/dgux-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/dgux-g++/lib.t b/tmake/lib/dgux-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/dgux-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/dgux-g++/subdirs.t b/tmake/lib/dgux-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/dgux-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/dgux-g++/tmake.conf b/tmake/lib/dgux-g++/tmake.conf
new file mode 100644
index 0000000..f4132d1
--- /dev/null
+++ b/tmake/lib/dgux-g++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+# "Frithjof.Brestrich" <brest at infp.fzk.de> suggests -h not -soname
+TMAKE_LFLAGS_SONAME = -Wl,-h,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/freebsd-g++/app.t b/tmake/lib/freebsd-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/freebsd-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/freebsd-g++/lib.t b/tmake/lib/freebsd-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/freebsd-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/freebsd-g++/subdirs.t b/tmake/lib/freebsd-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/freebsd-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/freebsd-g++/tmake.conf b/tmake/lib/freebsd-g++/tmake.conf
new file mode 100644
index 0000000..0b3c497
--- /dev/null
+++ b/tmake/lib/freebsd-g++/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for freebsd-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -pipe
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+
+# soname does not work on fbsd 2.x
+#TMAKE_LFLAGS_SONAME = -Wl,-soname
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/gnu-g++/app.t b/tmake/lib/gnu-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/gnu-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/gnu-g++/lib.t b/tmake/lib/gnu-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/gnu-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/gnu-g++/subdirs.t b/tmake/lib/gnu-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/gnu-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/gnu-g++/tmake.conf b/tmake/lib/gnu-g++/tmake.conf
new file mode 100644
index 0000000..635bc5c
--- /dev/null
+++ b/tmake/lib/gnu-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS = -Wl,-rpath=/lib:/usr/X11R6/lib:$(QTDIR)/lib
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/hpux-acc/app.t b/tmake/lib/hpux-acc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/hpux-acc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/hpux-acc/lib.t b/tmake/lib/hpux-acc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/hpux-acc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/hpux-acc/subdirs.t b/tmake/lib/hpux-acc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/hpux-acc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/hpux-acc/tmake.conf b/tmake/lib/hpux-acc/tmake.conf
new file mode 100644
index 0000000..dbd0c8e
--- /dev/null
+++ b/tmake/lib/hpux-acc/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for hpux-acc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = aCC
+TMAKE_CFLAGS = -w -D__STRICT_ANSI__ -DPNG_USE_LOCAL_ARRAYS
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = +Z
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = aCC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/include/X11R6
+TMAKE_LIBDIR_X11 = /usr/lib/X11R6
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib
+
+TMAKE_LINK = aCC
+TMAKE_LINK_SHLIB = aCC
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -b
+TMAKE_LFLAGS_SONAME =
+TMAKE_HPUX_SHLIB = 1
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl -lGL
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+TMAKE_LIBS_YACC = -ly
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/hpux-cc/app.t b/tmake/lib/hpux-cc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/hpux-cc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/hpux-cc/lib.t b/tmake/lib/hpux-cc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/hpux-cc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/hpux-cc/subdirs.t b/tmake/lib/hpux-cc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/hpux-cc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/hpux-cc/tmake.conf b/tmake/lib/hpux-cc/tmake.conf
new file mode 100644
index 0000000..b5881ec
--- /dev/null
+++ b/tmake/lib/hpux-cc/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for hpux-cc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -w +a1 -DAportable
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = +Z
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/include/X11R6
+TMAKE_LIBDIR_X11 = /usr/lib/X11R6
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+TMAKE_LINK_SHLIB = CC
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -b
+TMAKE_LFLAGS_SONAME =
+TMAKE_HPUX_SHLIB = 1
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/hpux-g++/app.t b/tmake/lib/hpux-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/hpux-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/hpux-g++/lib.t b/tmake/lib/hpux-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/hpux-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/hpux-g++/subdirs.t b/tmake/lib/hpux-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/hpux-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/hpux-g++/tmake.conf b/tmake/lib/hpux-g++/tmake.conf
new file mode 100644
index 0000000..fb39414
--- /dev/null
+++ b/tmake/lib/hpux-g++/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for hpux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O0
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/include/X11R6
+TMAKE_LIBDIR_X11 = /usr/lib/X11R6
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -fPIC -shared
+TMAKE_LFLAGS_SONAME =
+TMAKE_HPUX_SHLIB = 1
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL =
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/irix-64/app.t b/tmake/lib/irix-64/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/irix-64/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/irix-64/lib.t b/tmake/lib/irix-64/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/irix-64/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/irix-64/subdirs.t b/tmake/lib/irix-64/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/irix-64/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/irix-64/tmake.conf b/tmake/lib/irix-64/tmake.conf
new file mode 100644
index 0000000..ac0e2fa
--- /dev/null
+++ b/tmake/lib/irix-64/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for irix-64
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -64 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CFLAGS_WARN_ON = -fullwarn
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -woff 1110,1174,3262
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = -64 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+TMAKE_LINK_SHLIB = CC
+TMAKE_LFLAGS = -64
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r so_locations ii_files
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/irix-dcc/app.t b/tmake/lib/irix-dcc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/irix-dcc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/irix-dcc/lib.t b/tmake/lib/irix-dcc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/irix-dcc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/irix-dcc/subdirs.t b/tmake/lib/irix-dcc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/irix-dcc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/irix-dcc/tmake.conf b/tmake/lib/irix-dcc/tmake.conf
new file mode 100644
index 0000000..0fcbaa8
--- /dev/null
+++ b/tmake/lib/irix-dcc/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for irix-dcc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = DCC
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -fullwarn
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = DCC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = DCC
+TMAKE_LINK_SHLIB = DCC
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = so_locations
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/irix-g++/app.t b/tmake/lib/irix-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/irix-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/irix-g++/lib.t b/tmake/lib/irix-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/irix-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/irix-g++/subdirs.t b/tmake/lib/irix-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/irix-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/irix-g++/tmake.conf b/tmake/lib/irix-g++/tmake.conf
new file mode 100644
index 0000000..2192c71
--- /dev/null
+++ b/tmake/lib/irix-g++/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for irix-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O0
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_CLEAN = so_locations
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/irix-n32/app.t b/tmake/lib/irix-n32/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/irix-n32/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/irix-n32/lib.t b/tmake/lib/irix-n32/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/irix-n32/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/irix-n32/subdirs.t b/tmake/lib/irix-n32/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/irix-n32/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/irix-n32/tmake.conf b/tmake/lib/irix-n32/tmake.conf
new file mode 100644
index 0000000..9d8bcb4
--- /dev/null
+++ b/tmake/lib/irix-n32/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for irix-n32
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -n32 -mips3 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CFLAGS_WARN_ON = -fullwarn
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -woff 1110,1174,3262
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = -n32 -mips3 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+TMAKE_LINK_SHLIB = CC
+TMAKE_LFLAGS = -n32
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl -lGL
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r so_locations ii_files
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/irix-o32/app.t b/tmake/lib/irix-o32/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/irix-o32/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/irix-o32/lib.t b/tmake/lib/irix-o32/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/irix-o32/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/irix-o32/subdirs.t b/tmake/lib/irix-o32/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/irix-o32/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/irix-o32/tmake.conf b/tmake/lib/irix-o32/tmake.conf
new file mode 100644
index 0000000..89b8728
--- /dev/null
+++ b/tmake/lib/irix-o32/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for irix-o32
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -32 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CFLAGS_WARN_ON = -fullwarn
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -woff 1110,1174,3262
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = -32 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+TMAKE_LINK_SHLIB = CC
+TMAKE_LFLAGS = -32
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r so_locations ii_files
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/linux-64/app.t b/tmake/lib/linux-64/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/linux-64/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/linux-64/lib.t b/tmake/lib/linux-64/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/linux-64/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/linux-64/subdirs.t b/tmake/lib/linux-64/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/linux-64/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/linux-64/tmake.conf b/tmake/lib/linux-64/tmake.conf
new file mode 100644
index 0000000..334cb0f
--- /dev/null
+++ b/tmake/lib/linux-64/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -pipe
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib64
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib64
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib64
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = -g
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_X11SM = -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/linux-g++/app.t b/tmake/lib/linux-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/linux-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/linux-g++/lib.t b/tmake/lib/linux-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/linux-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/linux-g++/subdirs.t b/tmake/lib/linux-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/linux-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/linux-g++/tmake.conf b/tmake/lib/linux-g++/tmake.conf
new file mode 100644
index 0000000..193fadd
--- /dev/null
+++ b/tmake/lib/linux-g++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -pipe -fsigned-char
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = -g
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_X11SM = -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/m68k-atari-mint-g++/app.t b/tmake/lib/m68k-atari-mint-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/m68k-atari-mint-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/m68k-atari-mint-g++/lib.t b/tmake/lib/m68k-atari-mint-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/m68k-atari-mint-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/m68k-atari-mint-g++/subdirs.t b/tmake/lib/m68k-atari-mint-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/m68k-atari-mint-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/m68k-atari-mint-g++/tmake.conf b/tmake/lib/m68k-atari-mint-g++/tmake.conf
new file mode 100644
index 0000000..9e1b373
--- /dev/null
+++ b/tmake/lib/m68k-atari-mint-g++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for linux-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O0
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = -g
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_X11SM = -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/macosx-c++/app.t b/tmake/lib/macosx-c++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/macosx-c++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/macosx-c++/lib.t b/tmake/lib/macosx-c++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/macosx-c++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/macosx-c++/subdirs.t b/tmake/lib/macosx-c++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/macosx-c++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/macosx-c++/tmake.conf b/tmake/lib/macosx-c++/tmake.conf
new file mode 100644
index 0000000..ade3437
--- /dev/null
+++ b/tmake/lib/macosx-c++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for macosx-c++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -pipe
+TMAKE_CFLAGS_WARN_ON = -Wall -W -Wno-deprecated-declarations
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g -fstack-protector
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = c++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = c++
+TMAKE_LINK_SHLIB = c++
+TMAKE_LFLAGS = -Wl,-search_paths_first
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+
+TMAKE_LFLAGS_SONAME = -dynamiclib -install_name
+
+TMAKE_LIBS = -liconv -framework CoreServices
+TMAKE_LIBS_X11 =
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/macosx-intel-c++/app.t b/tmake/lib/macosx-intel-c++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/macosx-intel-c++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/macosx-intel-c++/lib.t b/tmake/lib/macosx-intel-c++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/macosx-intel-c++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/macosx-intel-c++/subdirs.t b/tmake/lib/macosx-intel-c++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/macosx-intel-c++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/macosx-intel-c++/tmake.conf b/tmake/lib/macosx-intel-c++/tmake.conf
new file mode 100644
index 0000000..33af519
--- /dev/null
+++ b/tmake/lib/macosx-intel-c++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for macosx-c++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -pipe -arch i386 -arch x86_64
+TMAKE_CFLAGS_WARN_ON = -Wall -W -Wno-deprecated-declarations
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = c++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = c++
+TMAKE_LINK_SHLIB = c++
+TMAKE_LFLAGS = -Wl,-search_paths_first -arch i386 -arch x86_64
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+
+TMAKE_LFLAGS_SONAME = -dynamiclib -install_name
+
+TMAKE_LIBS = -liconv -framework CoreServices -mmacosx-version-min=10.5
+TMAKE_LIBS_X11 =
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/macosx-uni-c++/app.t b/tmake/lib/macosx-uni-c++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/macosx-uni-c++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/macosx-uni-c++/lib.t b/tmake/lib/macosx-uni-c++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/macosx-uni-c++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/macosx-uni-c++/subdirs.t b/tmake/lib/macosx-uni-c++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/macosx-uni-c++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/macosx-uni-c++/tmake.conf b/tmake/lib/macosx-uni-c++/tmake.conf
new file mode 100644
index 0000000..9d7a4a8
--- /dev/null
+++ b/tmake/lib/macosx-uni-c++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for macosx-c++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -pipe -arch i386 -arch ppc
+TMAKE_CFLAGS_WARN_ON = -Wall -W -Wno-deprecated-declarations
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = c++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = c++
+TMAKE_LINK_SHLIB = c++
+TMAKE_LFLAGS = -Wl,-search_paths_first -arch i386 -arch ppc
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+
+TMAKE_LFLAGS_SONAME = -dynamiclib -install_name
+
+TMAKE_LIBS = -liconv -framework CoreServices -mmacosx-version-min=10.5
+TMAKE_LIBS_X11 =
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/netbsd-g++/app.t b/tmake/lib/netbsd-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/netbsd-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/netbsd-g++/lib.t b/tmake/lib/netbsd-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/netbsd-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/netbsd-g++/subdirs.t b/tmake/lib/netbsd-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/netbsd-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/netbsd-g++/tmake.conf b/tmake/lib/netbsd-g++/tmake.conf
new file mode 100644
index 0000000..cad7876
--- /dev/null
+++ b/tmake/lib/netbsd-g++/tmake.conf
@@ -0,0 +1,61 @@
+#
+#
+#
+# tmake configuration for netbsd-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = ld
+TMAKE_LINK_SHLIB_CMD = $(SYSCONF_LINK_SHLIB) -Bshareable $(LFLAGS) -o $(DESTDIR)$(SYSCONF_LINK_TARGET_SHARED) \
+ `lorder /usr/lib/c++rt0.o $(OBJECTS) $(OBJMOC) | \
+ tsort` $(LIBS)
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -Bshareable
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/openbsd-g++/app.t b/tmake/lib/openbsd-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/openbsd-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/openbsd-g++/lib.t b/tmake/lib/openbsd-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/openbsd-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/openbsd-g++/subdirs.t b/tmake/lib/openbsd-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/openbsd-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/openbsd-g++/tmake.conf b/tmake/lib/openbsd-g++/tmake.conf
new file mode 100644
index 0000000..89cdc9b
--- /dev/null
+++ b/tmake/lib/openbsd-g++/tmake.conf
@@ -0,0 +1,61 @@
+#
+#
+#
+# tmake configuration for netbsd-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = ld
+TMAKE_LINK_SHLIB_CMD = $(SYSCONF_LINK_SHLIB) -Bshareable $(LFLAGS) -o $(DESTDIR)$(SYSCONF_LINK_TARGET_SHARED) \
+ `lorder /usr/lib/c++rt0.o $(OBJECTS) $(OBJMOC) | \
+ tsort` $(LIBS)
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -Bshareable
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar q
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/osf1-cxx/app.t b/tmake/lib/osf1-cxx/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/osf1-cxx/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/osf1-cxx/lib.t b/tmake/lib/osf1-cxx/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/osf1-cxx/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/osf1-cxx/subdirs.t b/tmake/lib/osf1-cxx/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/osf1-cxx/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/osf1-cxx/tmake.conf b/tmake/lib/osf1-cxx/tmake.conf
new file mode 100644
index 0000000..b3f9a5d
--- /dev/null
+++ b/tmake/lib/osf1-cxx/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for osf1-cxx (a.k.a. DEC Unix)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cxx
+TMAKE_CFLAGS = -x cc -w -D_POSIX_SOURCE -D_OSF_SOURCE -D_AES_SOURCE
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -Olimit 1000
+
+TMAKE_CXX = cxx
+TMAKE_CXXFLAGS = -x cxx -w -D_POSIX_SOURCE -D_OSF_SOURCE -D_AES_SOURCE
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = cxx
+TMAKE_LINK_SHLIB = cxx
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = <<END
+-soname
+END
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/osf1-g++/app.t b/tmake/lib/osf1-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/osf1-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/osf1-g++/lib.t b/tmake/lib/osf1-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/osf1-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/osf1-g++/subdirs.t b/tmake/lib/osf1-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/osf1-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/osf1-g++/tmake.conf b/tmake/lib/osf1-g++/tmake.conf
new file mode 100644
index 0000000..e23713e
--- /dev/null
+++ b/tmake/lib/osf1-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for osf1-g++ (a.k.a. DEC Unix)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -D_POSIX_SOURCE -D_OSF_SOURCE -D_AES_SOURCE
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/qnx-g++/app.t b/tmake/lib/qnx-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/qnx-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/qnx-g++/lib.t b/tmake/lib/qnx-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/qnx-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/qnx-g++/subdirs.t b/tmake/lib/qnx-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/qnx-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/qnx-g++/tmake.conf b/tmake/lib/qnx-g++/tmake.conf
new file mode 100644
index 0000000..4846d68
--- /dev/null
+++ b/tmake/lib/qnx-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for qnx-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -pipe
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O -fno-inline -fno-pack-struct
+TMAKE_CFLAGS_DEBUG = -g -fno-inline -fno-pack-struct
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -fno-inline -fno-pack-struct
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB =
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -lunix
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/sco-g++/app.t b/tmake/lib/sco-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/sco-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/sco-g++/lib.t b/tmake/lib/sco-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/sco-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/sco-g++/subdirs.t b/tmake/lib/sco-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/sco-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/sco-g++/tmake.conf b/tmake/lib/sco-g++/tmake.conf
new file mode 100644
index 0000000..c571f98
--- /dev/null
+++ b/tmake/lib/sco-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for sco-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/solaris-cc-64/app.t b/tmake/lib/solaris-cc-64/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/solaris-cc-64/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/solaris-cc-64/lib.t b/tmake/lib/solaris-cc-64/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/solaris-cc-64/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/solaris-cc-64/subdirs.t b/tmake/lib/solaris-cc-64/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/solaris-cc-64/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/solaris-cc-64/tmake.conf b/tmake/lib/solaris-cc-64/tmake.conf
new file mode 100644
index 0000000..889fde7
--- /dev/null
+++ b/tmake/lib/solaris-cc-64/tmake.conf
@@ -0,0 +1,61 @@
+#
+#
+#
+# tmake configuration for solaris-cc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS = -xtarget=generic64
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF = -w
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -KPIC
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = -xO2
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = -PIC
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/openwin/include
+TMAKE_LIBDIR_X11 = /usr/openwin/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+# Jan Wortelboer <janw at wins.uva.nl> suggests avoiding $LD_LIBRARY_PATH:
+TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib
+TMAKE_LFLAGS = -64 -xtarget=generic64
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1)
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl -lGL
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = CC -xar -o
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r Templates.DB
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/solaris-cc-gcc/app.t b/tmake/lib/solaris-cc-gcc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/solaris-cc-gcc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/solaris-cc-gcc/lib.t b/tmake/lib/solaris-cc-gcc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/solaris-cc-gcc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/solaris-cc-gcc/subdirs.t b/tmake/lib/solaris-cc-gcc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/solaris-cc-gcc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/solaris-cc-gcc/tmake.conf b/tmake/lib/solaris-cc-gcc/tmake.conf
new file mode 100644
index 0000000..de013a0
--- /dev/null
+++ b/tmake/lib/solaris-cc-gcc/tmake.conf
@@ -0,0 +1,62 @@
+#
+#
+#
+# tmake configuration for solaris-cc-gcc
+# (Using SunPro CC for C++ code and gcc for C code.)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS =
+TMAKE_CXXFLAGS_WARN_ON =
+TMAKE_CXXFLAGS_WARN_OFF = -w
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = -PIC
+TMAKE_CXXFLAGS_YACC =
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/openwin/include
+TMAKE_LIBDIR_X11 = /usr/openwin/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+# Jan Wortelboer <janw at wins.uva.nl> suggests avoiding $LD_LIBRARY_PATH:
+TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1)
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -lC
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = CC -xar -o
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r Templates.DB
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/solaris-cc/app.t b/tmake/lib/solaris-cc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/solaris-cc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/solaris-cc/lib.t b/tmake/lib/solaris-cc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/solaris-cc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/solaris-cc/subdirs.t b/tmake/lib/solaris-cc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/solaris-cc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/solaris-cc/tmake.conf b/tmake/lib/solaris-cc/tmake.conf
new file mode 100644
index 0000000..3dbe810
--- /dev/null
+++ b/tmake/lib/solaris-cc/tmake.conf
@@ -0,0 +1,61 @@
+#
+#
+#
+# tmake configuration for solaris-cc
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF = -w
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -KPIC
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = -O2
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = -PIC
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/openwin/include
+TMAKE_LIBDIR_X11 = /usr/openwin/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+# Jan Wortelboer <janw at wins.uva.nl> suggests avoiding $LD_LIBRARY_PATH:
+TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1)
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm -lICE -lSM
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl -lGL
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = CC -xar -o
+TMAKE_RANLIB =
+
+TMAKE_CLEAN = -r Templates.DB
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/solaris-g++/app.t b/tmake/lib/solaris-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/solaris-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/solaris-g++/lib.t b/tmake/lib/solaris-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/solaris-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/solaris-g++/subdirs.t b/tmake/lib/solaris-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/solaris-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/solaris-g++/tmake.conf b/tmake/lib/solaris-g++/tmake.conf
new file mode 100644
index 0000000..a6817bf
--- /dev/null
+++ b/tmake/lib/solaris-g++/tmake.conf
@@ -0,0 +1,59 @@
+#
+#
+#
+# tmake configuration for solaris-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/openwin/include
+TMAKE_LIBDIR_X11 = /usr/openwin/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHAPP = -shared
+TMAKE_LFLAGS_SHLIB = -shared -h $(TARGET1)
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -liconv
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/sunos-g++/app.t b/tmake/lib/sunos-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/sunos-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/sunos-g++/lib.t b/tmake/lib/sunos-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/sunos-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/sunos-g++/subdirs.t b/tmake/lib/sunos-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/sunos-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/sunos-g++/tmake.conf b/tmake/lib/sunos-g++/tmake.conf
new file mode 100644
index 0000000..52f9e2d
--- /dev/null
+++ b/tmake/lib/sunos-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for sunos-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/openwin/include
+TMAKE_LIBDIR_X11 = /usr/openwin/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -fPIC -shared
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB = ranlib
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/ultrix-g++/app.t b/tmake/lib/ultrix-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/ultrix-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/ultrix-g++/lib.t b/tmake/lib/ultrix-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/ultrix-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/ultrix-g++/subdirs.t b/tmake/lib/ultrix-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/ultrix-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/ultrix-g++/tmake.conf b/tmake/lib/ultrix-g++/tmake.conf
new file mode 100644
index 0000000..59813eb
--- /dev/null
+++ b/tmake/lib/ultrix-g++/tmake.conf
@@ -0,0 +1,58 @@
+#
+#
+#
+# tmake configuration for ultrix-g++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB =
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 = /usr/X11R6/include
+TMAKE_LIBDIR_X11 = /usr/X11R6/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL = /usr/X11R6/include
+TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+TMAKE_LINK = g++
+#TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+#TMAKE_LFLAGS_SHLIB = -shared
+#TMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/unix/app.t b/tmake/lib/unix/app.t
new file mode 100644
index 0000000..f59c9f9
--- /dev/null
+++ b/tmake/lib/unix/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Unix applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/unix/generic.t b/tmake/lib/unix/generic.t
new file mode 100644
index 0000000..2852b36
--- /dev/null
+++ b/tmake/lib/unix/generic.t
@@ -0,0 +1,283 @@
+#!
+#! This is a tmake template for building UNIX applications or libraries.
+#!
+#${
+ if ( Project("TMAKE_LIB_FLAG") && !Config("staticlib") ) {
+ Project('CONFIG *= dll');
+ } elsif ( Project("TMAKE_APP_FLAG") || Config("dll") ) {
+ Project('CONFIG -= staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG *= x11lib');
+ if ( Config("opengl") ) {
+ Project('CONFIG *= x11inc');
+ }
+ }
+ if ( Config("x11") ) {
+ Project('CONFIG *= x11lib');
+ Project('CONFIG *= x11inc');
+ }
+ if ( Config("qt") ) {
+ Project('CONFIG *= moc');
+ AddIncludePath(Project("TMAKE_INCDIR_QT"));
+ if ( Config("release") ) {
+ Project('DEFINES += NO_DEBUG');
+ }
+ if ( Config("opengl") ) {
+ Project("TMAKE_LIBDIR_QT") &&
+ Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_QT');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( !((Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG")) ) {
+ Project("TMAKE_LIBDIR_QT") &&
+ Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_QT');
+ if ( Config("thread") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_MT');
+ } else {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ AddIncludePath(Project("TMAKE_INCDIR_OPENGL"));
+ Project("TMAKE_LIBDIR_OPENGL") &&
+ Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_OPENGL');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("x11inc") ) {
+ AddIncludePath(Project("TMAKE_INCDIR_X11"));
+ }
+ if ( Config("x11lib") ) {
+ Project("TMAKE_LIBDIR_X11") &&
+ Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_X11');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_X11');
+ }
+ if ( Config("moc") ) {
+ $moc_aware = 1;
+ }
+ Project('TMAKE_LIBS = $$LIBS $$TMAKE_LIBS');
+ if ( !Project("TMAKE_RUN_CC") ) {
+ Project('TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src');
+ }
+ if ( !Project("TMAKE_RUN_CC_IMP") ) {
+ Project('TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<');
+ }
+ if ( !Project("TMAKE_RUN_CXX") ) {
+ Project('TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src');
+ }
+ if ( !Project("TMAKE_RUN_CXX_IMP") ) {
+ Project('TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<');
+ }
+ Project('TMAKE_FILETAGS = HEADERS SOURCES TARGET DESTDIR $$FILETAGS');
+ StdInit();
+ $project{"VERSION"} || ($project{"VERSION"} = "1.0");
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ Project('DESTDIR_TARGET = $(TARGET)');
+ if ( Project("TMAKE_APP_FLAG") ) {
+ if ( Config("dll") ) {
+ Project('TARGET = $$TARGET.so');
+ Project("TMAKE_LFLAGS_SHAPP") ||
+ ($project{"TMAKE_LFLAGS_SHAPP"} = $project{"TMAKE_LFLAGS_SHLIB"});
+ Project("TMAKE_LFLAGS_SONAME") &&
+ ($project{"TMAKE_LFLAGS_SONAME"} .= $project{"TARGET"});
+ }
+ $project{"TARGET"} = $project{"DESTDIR"} . $project{"TARGET"};
+ } elsif ( Config("staticlib") ) {
+ $project{"TARGET"} = $project{"DESTDIR"} . "lib" .
+ $project{"TARGET"} . ".a";
+ Project("TMAKE_AR_CMD") ||
+ Project('TMAKE_AR_CMD = $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)');
+ } else {
+ $project{"TARGETA"} = $project{"DESTDIR"} . "lib" .
+ $project{"TARGET"} . ".a";
+ if ( Project("TMAKE_AR_CMD") ) {
+ $project{"TMAKE_AR_CMD"} =~ s/\(TARGET\)/\(TARGETA\)/g;
+ } else {
+ Project('TMAKE_AR_CMD = $(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)');
+ }
+ if ( $project{"TMAKE_HPUX_SHLIB"} ) {
+ $project{"TARGET_x.y"} = "lib" . $project{"TARGET"} . ".sl";
+ } else {
+ $project{"TARGET_"} = "lib" . $project{"TARGET"} . ".so";
+ $project{"TARGET_x"} = $project{"TARGET_"} . "." .
+ $project{"VER_MAJ"};
+ $project{"TARGET_x.y"} = $project{"TARGET_"} . "." .
+ $project{"VERSION"};
+ $project{"TMAKE_LN_SHLIB"} = "-ln -s";
+ }
+ $project{"TARGET"} = $project{"TARGET_x.y"};
+ if ( $project{"DESTDIR"} ) {
+ $project{"DESTDIR_TARGET"} = $project{"DESTDIR"} .
+ $project{"TARGET"};
+ }
+ Project("TMAKE_LFLAGS_SONAME") &&
+ ($project{"TMAKE_LFLAGS_SONAME"} .= $project{"TARGET_x"});
+ $project{"TMAKE_LINK_SHLIB_CMD"} ||
+ ($project{"TMAKE_LINK_SHLIB_CMD"} =
+ '$(LINK) $(LFLAGS) -o $(TARGETD) $(OBJECTS) $(OBJMOC) $(LIBS)');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_CFLAGS *= $$TMAKE_CFLAGS_SHLIB' );
+ Project('TMAKE_CXXFLAGS *= $$TMAKE_CXXFLAGS_SHLIB' );
+ if ( Project("TMAKE_APP_FLAG") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHAPP');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHLIB $$TMAKE_LFLAGS_SONAME');
+ }
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CXX = #$ Expand("TMAKE_CXX");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH","-I"," -I","");
+#$ Config("staticlib") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ Config("staticlib") && EnableOutput();
+#$ Project("TMAKE_LIB_FLAG") || DisableOutput();
+AR = #$ Expand("TMAKE_AR");
+RANLIB = #$ Expand("TMAKE_RANLIB");
+#$ Project("TMAKE_LIB_FLAG") || EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+TAR = #$ Expand("TMAKE_TAR");
+GZIP = #$ Expand("TMAKE_GZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ Expand("TARGET");
+#$ (Project("TMAKE_APP_FLAG") || Config("staticlib")) && DisableOutput();
+TARGETA = #$ Expand("TARGETA");
+TARGETD = #$ Expand("TARGET_x.y");
+TARGET0 = #$ Expand("TARGET_");
+TARGET1 = #$ Expand("TARGET_x");
+#$ (Project("TMAKE_APP_FLAG") || Config("staticlib")) && EnableOutput();
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cxx.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cc.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.C.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.c.o:
+ #$ Expand("TMAKE_RUN_CC_IMP");
+
+####### Build rules
+
+#$ Project("TMAKE_APP_FLAG") || DisableOutput();
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+#$ Project("TMAKE_APP_FLAG") || EnableOutput();
+#$ (Config("staticlib") || Project("TMAKE_APP_FLAG")) && DisableOutput();
+all: #$ ExpandGlue("ALL_DEPS",""," ",""); Expand("DESTDIR_TARGET");
+
+#$ Substitute('$$DESTDIR_TARGET: $(OBJECTS) $(OBJMOC) $$TARGETDEPS');
+ -rm -f $(TARGET) $(TARGET0) $(TARGET1)
+ #$ Expand("TMAKE_LINK_SHLIB_CMD");
+ #$ ExpandGlue("TMAKE_LN_SHLIB",""," "," \$(TARGET) \$(TARGET0)");
+ #$ ExpandGlue("TMAKE_LN_SHLIB",""," "," \$(TARGET) \$(TARGET1)");
+ #${
+ $d = Project("DESTDIR");
+ if ( $d ) {
+ $d =~ s-([^/])$-$1/-;
+ if ( Project("TMAKE_HPUX_SHLIB") ) {
+ $text = "-rm -f $d\$(TARGET)\n\t" .
+ "-mv \$(TARGET) $d";
+ } else {
+ $text = "-rm -f $d\$(TARGET)\n\t" .
+ "-rm -f $d\$(TARGET0)\n\t" .
+ "-rm -f $d\$(TARGET1)\n\t" .
+ "-mv \$(TARGET) \$(TARGET0) \$(TARGET1) $d";
+ }
+ }
+ #$}
+
+staticlib: $(TARGETA)
+
+$(TARGETA): $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+ -rm -f $(TARGETA)
+ #$ Expand("TMAKE_AR_CMD");
+ #$ ExpandGlue("TMAKE_RANLIB","",""," \$(TARGETA)");
+#$ (Config("staticlib") || Project("TMAKE_APP_FLAG")) && EnableOutput();
+#$ Config("staticlib") || DisableOutput();
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+ -rm -f $(TARGET)
+ #$ Expand("TMAKE_AR_CMD");
+ #$ ExpandGlue("TMAKE_RANLIB","",""," \$(TARGET)");
+#$ Config("staticlib") || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(TAR) $$PROJECT.tar $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+ #$ Substitute('$(GZIP) $$PROJECT.tar');
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+#$ (Config("staticlib") || Project("TMAKE_APP_FLAG")) && DisableOutput();
+ -rm -f $(TARGET0) $(TARGET1) $(TARGETA)
+#$ (Config("staticlib") || Project("TMAKE_APP_FLAG")) && EnableOutput();
+ #$ ExpandGlue("TMAKE_CLEAN","-rm -f "," ","");
+ -rm -f *~ core
+ #$ ExpandGlue("CLEAN_FILES","-rm -f "," ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/unix/lib.t b/tmake/lib/unix/lib.t
new file mode 100644
index 0000000..dd24c63
--- /dev/null
+++ b/tmake/lib/unix/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Unix libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/unix/subdirs.t b/tmake/lib/unix/subdirs.t
new file mode 100644
index 0000000..e2b58a7
--- /dev/null
+++ b/tmake/lib/unix/subdirs.t
@@ -0,0 +1,38 @@
+#############################################################################
+#!
+#! This is a tmake template for creating a makefile that invokes make in
+#! sub directories - for Unix.
+#!
+#${
+ StdInit();
+ Project('MAKEFILE') || Project('MAKEFILE = Makefile');
+ Project('TMAKE') || Project('TMAKE = tmake');
+#$}
+#!
+# Makefile for building targets in sub directories.
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+MAKEFILE= #$ Expand("MAKEFILE");
+TMAKE = #$ Expand("TMAKE");
+
+SUBDIRS = #$ ExpandList("SUBDIRS");
+
+all: $(SUBDIRS)
+
+$(SUBDIRS): FORCE
+ cd $@; $(MAKE)
+
+#$ TmakeSelf();
+
+tmake_all:
+#${
+ $text = "\t" . 'for i in $(SUBDIRS); do ( cd $$i ; $(TMAKE) $$i.pro -o $(MAKEFILE); grep "TEMPLATE.*subdirs" $$i.pro 2>/dev/null >/dev/null && $(MAKE) -f $(MAKEFILE) tmake ) ; done';
+#$}
+
+clean:
+ for i in $(SUBDIRS); do ( cd $$i ; $(MAKE) clean ) ; done
+
+FORCE:
diff --git a/tmake/lib/unixware-g++/app.t b/tmake/lib/unixware-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/unixware-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/unixware-g++/lib.t b/tmake/lib/unixware-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/unixware-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/unixware-g++/subdirs.t b/tmake/lib/unixware-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/unixware-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/unixware-g++/tmake.conf b/tmake/lib/unixware-g++/tmake.conf
new file mode 100644
index 0000000..d4e063f
--- /dev/null
+++ b/tmake/lib/unixware-g++/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for sco-g++
+#
+# incl. UnixWare 7
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -D_UNIXWARE
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 = /usr/X/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -lc
+TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/unixware7-cc/app.t b/tmake/lib/unixware7-cc/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/unixware7-cc/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/unixware7-cc/lib.t b/tmake/lib/unixware7-cc/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/unixware7-cc/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/unixware7-cc/subdirs.t b/tmake/lib/unixware7-cc/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/unixware7-cc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/unixware7-cc/tmake.conf b/tmake/lib/unixware7-cc/tmake.conf
new file mode 100644
index 0000000..6e239dc
--- /dev/null
+++ b/tmake/lib/unixware7-cc/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for sco-g++
+#
+# (UnixWare file, with different -D)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O -T used
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -K PIC
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 = /usr/X/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = CC
+TMAKE_LINK_SHLIB = CC
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -G
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS =
+TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/unixware7-g++/app.t b/tmake/lib/unixware7-g++/app.t
new file mode 100644
index 0000000..867725e
--- /dev/null
+++ b/tmake/lib/unixware7-g++/app.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/app.t");
diff --git a/tmake/lib/unixware7-g++/lib.t b/tmake/lib/unixware7-g++/lib.t
new file mode 100644
index 0000000..2523b2f
--- /dev/null
+++ b/tmake/lib/unixware7-g++/lib.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/lib.t");
diff --git a/tmake/lib/unixware7-g++/subdirs.t b/tmake/lib/unixware7-g++/subdirs.t
new file mode 100644
index 0000000..5e888af
--- /dev/null
+++ b/tmake/lib/unixware7-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Unix template
+#$ IncludeTemplate("../unix/subdirs.t");
diff --git a/tmake/lib/unixware7-g++/tmake.conf b/tmake/lib/unixware7-g++/tmake.conf
new file mode 100644
index 0000000..44f30a5
--- /dev/null
+++ b/tmake/lib/unixware7-g++/tmake.conf
@@ -0,0 +1,60 @@
+#
+#
+#
+# tmake configuration for sco-g++
+#
+# (UnixWare file, with different -D)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS = -D_UNIXWARE7
+TMAKE_CFLAGS_WARN_ON = -Wall -W
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_SHLIB = -fPIC
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_LIBDIR =
+TMAKE_INCDIR_X11 =
+TMAKE_LIBDIR_X11 = /usr/X/lib
+TMAKE_INCDIR_QT = $(QTDIR)/include
+TMAKE_LIBDIR_QT = $(QTDIR)/lib
+TMAKE_INCDIR_OPENGL =
+TMAKE_LIBDIR_OPENGL =
+
+TMAKE_LINK = g++
+TMAKE_LINK_SHLIB = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_SHLIB = -shared
+TMAKE_LFLAGS_SONAME =
+
+TMAKE_LIBS = -lc
+TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm
+TMAKE_LIBS_QT = -lqt
+TMAKE_LIBS_QT_MT = -lqt-mt
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cq
+TMAKE_RANLIB =
+
+TMAKE_TAR = tar -cf
+TMAKE_GZIP = gzip -9f
diff --git a/tmake/lib/win32-borland/app.t b/tmake/lib/win32-borland/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-borland/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-borland/generic.t b/tmake/lib/win32-borland/generic.t
new file mode 100644
index 0000000..aa7f53b
--- /dev/null
+++ b/tmake/lib/win32-borland/generic.t
@@ -0,0 +1,237 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( !(Project("DEFINES") =~ /QT_NODLL/) &&
+ ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) ||
+ ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ Project('CONFIG *= moc');
+ AddIncludePath(Project("TMAKE_INCDIR_QT"));
+ if ( Config("release") ) {
+ Project('DEFINES += NO_DEBUG');
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES -= QT_DLL');
+ Project('DEFINES *= QT_MAKEDLL');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( Project("TMAKE_QT_DLL") ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ if ( !Config("dll") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project("TMAKE_APP_FLAG") ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".lib";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ if ( Config("moc") ) {
+ $moc_aware = 1;
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) {
+ $project{$_} =~ s-[/\\]+-\\-g;
+ }
+ if ( Project("DEF_FILE") ) {
+ Project('TMAKE_LFLAGS *= /DEF:$$DEF_FILE');
+ }
+ if ( Project("RC_FILE") ) {
+ if ( Project("RES_FILE") ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project("RES_FILE") ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+ Project('TMAKE_CLEAN += $$TARGET.tds');
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+!if !$d(BCB)
+BCB = $(MAKEDIR)\..
+!endif
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CXX = #$ Expand("TMAKE_CXX");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LIB = #$ Expand("TMAKE_LIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cxx.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cc.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.c.obj:
+ #$ Expand("TMAKE_RUN_CC_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ $(LINK) @&&|
+ $(LFLAGS) $(OBJECTS) $(OBJMOC), $(TARGET),,$(LIBS)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ -del $(TARGET)
+ $(LIB) $(TARGET) @&&|
+#${
+# $text = "+" . join(" \\\n+",split(/\s+/,$project{"OBJECTS"})) . " \\\n+"
+# . join(" \\\n+",split(/\s+/,$project{"OBJMOC"}));
+#$}
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+|
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -copy $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project("RC_FILE") || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project("RC_FILE") || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ #$ ExpandGlue("OBJECTS","-del ","\n\t-del ","");
+ #$ ExpandGlue("SRCMOC" ,"-del ","\n\t-del ","");
+ #$ ExpandGlue("OBJMOC" ,"-del ","\n\t-del ","");
+ -del $(TARGET)
+ #$ ExpandGlue("TMAKE_CLEAN","-del ","\n\t-del ","");
+ #$ ExpandGlue("CLEAN_FILES","-del ","\n\t-del ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-borland/lib.t b/tmake/lib/win32-borland/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-borland/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-borland/subdirs.t b/tmake/lib/win32-borland/subdirs.t
new file mode 100644
index 0000000..f08e41f
--- /dev/null
+++ b/tmake/lib/win32-borland/subdirs.t
@@ -0,0 +1,3 @@
+#! Use the common Win32 template
+#$ Project("TMAKE_NOFORCE = 1");
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-borland/tmake.conf b/tmake/lib/win32-borland/tmake.conf
new file mode 100644
index 0000000..bce6f1a
--- /dev/null
+++ b/tmake/lib/win32-borland/tmake.conf
@@ -0,0 +1,56 @@
+#
+#
+#
+# tmake configuration for Win32/Borland C++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = bcc32
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON = -w
+TMAKE_CFLAGS_WARN_OFF = -w-
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -v
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = $$TMAKE_CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)\include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o$obj $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o$@ $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$obj $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$@ $<
+
+TMAKE_LINK = ilink32
+TMAKE_LFLAGS = -L$(BCB)\lib -c -x -Gn
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = -v
+TMAKE_LFLAGS_CONSOLE = -ap -Tpe c0x32.obj
+TMAKE_LFLAGS_WINDOWS = -aa -Tpe c0w32.obj
+TMAKE_LFLAGS_CONSOLE_DLL= -Gi -ap -Tpd c0d32.obj
+TMAKE_LFLAGS_WINDOWS_DLL= -Gi -aa -Tpd c0d32.obj
+
+TMAKE_LIBS = import32.lib cw32.lib
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS =
+TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib
+TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib
+TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib
+TMAKE_LIBS_OPENGL =
+
+TMAKE_MOC = moc
+
+TMAKE_LIB = tlib /C /P256
+TMAKE_RC = brc32
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-g++/app.t b/tmake/lib/win32-g++/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-g++/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-g++/generic.t b/tmake/lib/win32-g++/generic.t
new file mode 100644
index 0000000..33494a2
--- /dev/null
+++ b/tmake/lib/win32-g++/generic.t
@@ -0,0 +1,243 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( !(Project("DEFINES") =~ /QT_NODLL/) &&
+ ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) ||
+ ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ Project('CONFIG *= moc');
+ AddIncludePath(Project("TMAKE_INCDIR_QT"));
+ if ( Config("release") ) {
+ Project('DEFINES += NO_DEBUG');
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES -= QT_DLL');
+ Project('DEFINES *= QT_MAKEDLL');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( Project("TMAKE_QT_DLL") ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ if ( !Config("dll") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ if ( Config("cgi") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ $project{"TARGET_EXT"} = "";
+ } else {
+ if ( Project("TMAKE_APP_FLAG") ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".a";
+ }
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ if ( Config("moc") ) {
+ $moc_aware = 1;
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) {
+ $project{$_} =~ s-[/\\]+-/-g;
+ }
+ if ( Project("DEF_FILE") ) {
+ Project('TMAKE_LFLAGS *= $$DEF_FILE');
+ }
+ if ( Project("RC_FILE") ) {
+ if ( Project("RES_FILE") ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project("RES_FILE") ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ $obj_ext = "o";
+ $dir_sep = "/";
+ $gnuwin32 = 1;
+ if ( Config("qt") ) {
+ $qtdir = $ENV{"QTDIR"};
+ $project{"INCPATH"} =~ s/\$\(QTDIR\)/$qtdir/;
+ $project{"INCPATH"} =~ s/\\/\//g;
+ $project{"TMAKE_LIBS"} =~ s/\$\(QTDIR\)/$qtdir/;
+ $project{"TMAKE_LIBS"} =~ s/\\/\//g;
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+ if ( Config("staticlib") ) {
+ $project{"TARGET"} = "lib" . $project{"TARGET"}
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CXX = #$ Expand("TMAKE_CXX");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+AR = #$ Expand("TMAKE_AR");
+RANLIB = #$ Expand("TMAKE_RANLIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cxx.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cc.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.c.o:
+ #$ Expand("TMAKE_RUN_CC_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ #$ ExpandGlue("TMAKE_RANLIB","",""," \$(TARGET)");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -cp $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project('RC_FILE') || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project('RC_FILE') || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ #$ ExpandGlue("TMAKE_CLEAN","-rm -f "," ","");
+ -rm -f *~ core
+ #$ ExpandGlue("CLEAN_FILES","-rm -f "," ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-g++/lib.t b/tmake/lib/win32-g++/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-g++/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-g++/subdirs.t b/tmake/lib/win32-g++/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-g++/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-g++/tmake.conf b/tmake/lib/win32-g++/tmake.conf
new file mode 100644
index 0000000..d313a44
--- /dev/null
+++ b/tmake/lib/win32-g++/tmake.conf
@@ -0,0 +1,56 @@
+#
+#
+#
+# tmake configuration for Win32/g++ (Cygnus gnu-win32)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+TMAKE_LINK = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
+TMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
+TMAKE_LFLAGS_CONSOLE_DLL= -Wl,-subsystem,console
+TMAKE_LFLAGS_WINDOWS_DLL= -Wl,-subsystem,windows
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS = -luser32 -lgdi32 -lcomdlg32 -limm32 -lole32 -luuid -lwsock32
+TMAKE_LIBS_QT = -L$(QTDIR)/lib -lqt
+TMAKE_LIBS_QT_DLL = -lqtmain
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lopengl32
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-mingw/app.t b/tmake/lib/win32-mingw/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-mingw/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-mingw/generic.t b/tmake/lib/win32-mingw/generic.t
new file mode 100644
index 0000000..4988d59
--- /dev/null
+++ b/tmake/lib/win32-mingw/generic.t
@@ -0,0 +1,239 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( !(Project("DEFINES") =~ /QT_NODLL/) &&
+ ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) ||
+ ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ Project('CONFIG *= moc');
+ AddIncludePath(Project("TMAKE_INCDIR_QT"));
+ if ( Config("release") ) {
+ Project('DEFINES += NO_DEBUG');
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES -= QT_DLL');
+ Project('DEFINES *= QT_MAKEDLL');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( Project("TMAKE_QT_DLL") ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ if ( !Config("dll") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project("TMAKE_APP_FLAG") ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".a";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ if ( Config("moc") ) {
+ $moc_aware = 1;
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) {
+ $project{$_} =~ s-[/\\]+-/-g;
+ }
+ if ( Project("DEF_FILE") ) {
+ Project('TMAKE_LFLAGS *= $$DEF_FILE');
+ }
+ if ( Project("RC_FILE") ) {
+ if ( Project("RES_FILE") ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project("RES_FILE") ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ $obj_ext = "o";
+ $dir_sep = "/";
+ $gnuwin32 = 1;
+ if ( Config("qt") ) {
+ $qtdir = $ENV{"QTDIR"};
+ $project{"INCPATH"} =~ s/\$\(QTDIR\)/$qtdir/;
+ $project{"INCPATH"} =~ s/\\/\//g;
+ $project{"TMAKE_LIBS"} =~ s/\$\(QTDIR\)/$qtdir/;
+ $project{"TMAKE_LIBS"} =~ s/\\/\//g;
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+ if ( Config("staticlib") ) {
+ $project{"TARGET"} = "lib" . $project{"TARGET"};
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CXX = #$ Expand("TMAKE_CXX");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+AR = #$ Expand("TMAKE_AR");
+RANLIB = #$ Expand("TMAKE_RANLIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cxx.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cc.o:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.c.o:
+ #$ Expand("TMAKE_RUN_CC_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ #$ ExpandGlue("TMAKE_RANLIB","",""," \$(TARGET)");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -cp $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project('RC_FILE') || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project('RC_FILE') || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ #$ ExpandGlue("TMAKE_CLEAN","-rm -f "," ","");
+ -rm -f *~ core
+ #$ ExpandGlue("CLEAN_FILES","-rm -f "," ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-mingw/lib.t b/tmake/lib/win32-mingw/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-mingw/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-mingw/subdirs.t b/tmake/lib/win32-mingw/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-mingw/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-mingw/tmake.conf b/tmake/lib/win32-mingw/tmake.conf
new file mode 100644
index 0000000..c6d1918
--- /dev/null
+++ b/tmake/lib/win32-mingw/tmake.conf
@@ -0,0 +1,56 @@
+#
+#
+#
+# tmake configuration for Win32/mingw (MINGW gnu-win32)
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = gcc
+TMAKE_CFLAGS =
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF =
+TMAKE_CFLAGS_RELEASE = -O2 -s
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+TMAKE_CXX = g++
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)/include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+TMAKE_LINK = g++
+TMAKE_LFLAGS =
+TMAKE_LFLAGS_RELEASE = -s
+TMAKE_LFLAGS_DEBUG =
+TMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
+TMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
+TMAKE_LFLAGS_CONSOLE_DLL= -Wl,-subsystem,console
+TMAKE_LFLAGS_WINDOWS_DLL= -Wl,-subsystem,windows
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS = -luser32 -lgdi32 -lcomdlg32 -limm32 -lole32 -luuid -lwsock32
+TMAKE_LIBS_QT = -L$(QTDIR)/lib -lqt
+TMAKE_LIBS_QT_DLL = -lqtmain
+TMAKE_LIBS_QT_OPENGL = -lqgl
+TMAKE_LIBS_OPENGL = -lopengl32
+
+TMAKE_MOC = moc
+
+TMAKE_AR = ar cqs
+TMAKE_RANLIB =
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-msvc/app.t b/tmake/lib/win32-msvc/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-msvc/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-msvc/generic.t b/tmake/lib/win32-msvc/generic.t
new file mode 100644
index 0000000..3344236
--- /dev/null
+++ b/tmake/lib/win32-msvc/generic.t
@@ -0,0 +1,229 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( !(Project("DEFINES") =~ /QT_NODLL/) &&
+ ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) ||
+ ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_CXXFLAGS += $$TMAKE_CXXFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ Project('CONFIG *= moc');
+ AddIncludePath(Project("TMAKE_INCDIR_QT"));
+ if ( Config("release") ) {
+ Project('DEFINES += NO_DEBUG');
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES -= QT_DLL');
+ Project('DEFINES *= QT_MAKEDLL');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( Project("TMAKE_QT_DLL") ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ if ( !Config("dll") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project("TMAKE_APP_FLAG") ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".lib";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ if ( Config("moc") ) {
+ $moc_aware = 1;
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) {
+ $project{$_} =~ s-[/\\]+-\\-g;
+ }
+ if ( Project("DEF_FILE") ) {
+ Project('TMAKE_LFLAGS *= /DEF:$$DEF_FILE');
+ }
+ if ( Project("RC_FILE") ) {
+ if ( Project("RES_FILE") ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project("RES_FILE") ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+ Project('debug:TMAKE_CLEAN += $$TARGET.pdb vc*.pdb $$TARGET.ilk');
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CXX = #$ Expand("TMAKE_CXX");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LIB = #$ Expand("TMAKE_LIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cxx.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.cc.obj:
+ #$ Expand("TMAKE_RUN_CXX_IMP");
+
+.c.obj:
+ #$ Expand("TMAKE_RUN_CC_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ $(LINK) $(LFLAGS) /OUT:$(TARGET) @<<
+ $(OBJECTS) $(OBJMOC) $(LIBS)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ $(LIB) /OUT:$(TARGET) @<<
+ $(OBJECTS) $(OBJMOC)
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+<<
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -copy $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project("RC_FILE") || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project("RC_FILE") || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ #$ ExpandGlue("OBJECTS","-del ","\n\t-del ","");
+ #$ ExpandGlue("SRCMOC" ,"-del ","\n\t-del ","");
+ #$ ExpandGlue("OBJMOC" ,"-del ","\n\t-del ","");
+ -del $(TARGET)
+ #$ ExpandGlue("TMAKE_CLEAN","-del ","\n\t-del ","");
+ #$ ExpandGlue("CLEAN_FILES","-del ","\n\t-del ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-msvc/lib.t b/tmake/lib/win32-msvc/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-msvc/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-msvc/subdirs.t b/tmake/lib/win32-msvc/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-msvc/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-msvc/tmake.conf b/tmake/lib/win32-msvc/tmake.conf
new file mode 100644
index 0000000..e3191a3
--- /dev/null
+++ b/tmake/lib/win32-msvc/tmake.conf
@@ -0,0 +1,65 @@
+#
+#
+#
+# tmake configuration for Win32/Microsoft C++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = cl
+TMAKE_CFLAGS = -nologo
+TMAKE_CFLAGS_WARN_ON = -W3
+TMAKE_CFLAGS_WARN_OFF = -W0
+TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_DEBUG = -Zi
+TMAKE_CFLAGS_MT = -MT
+TMAKE_CFLAGS_MT_DBG = -MTd
+TMAKE_CFLAGS_MT_DLL = -MD
+TMAKE_CFLAGS_MT_DLLDBG = -MDd
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = $$TMAKE_CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_MT = $$TMAKE_CFLAGS_MT
+TMAKE_CXXFLAGS_MT_DBG = $$TMAKE_CFLAGS_MT_DBG
+TMAKE_CXXFLAGS_MT_DLL = $$TMAKE_CFLAGS_MT_DLL
+TMAKE_CXXFLAGS_MT_DLLDBG= $$TMAKE_CFLAGS_MT_DLLDBG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)\include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+
+TMAKE_LINK = link
+TMAKE_LFLAGS = /NOLOGO
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = /DEBUG
+TMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:console
+TMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:windows
+TMAKE_LFLAGS_CONSOLE_DLL= /SUBSYSTEM:console /DLL
+TMAKE_LFLAGS_WINDOWS_DLL= /SUBSYSTEM:windows /DLL
+TMAKE_LFLAGS_QT_DLL = /BASE:0x39D00000
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib
+TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib
+TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib
+TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib
+TMAKE_LIBS_OPENGL = opengl32.lib glu32.lib
+
+TMAKE_MOC = moc
+
+TMAKE_LIB = lib /NOLOGO
+TMAKE_RC = rc
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-msvc/vcapp.t b/tmake/lib/win32-msvc/vcapp.t
new file mode 100644
index 0000000..ac7ae23
--- /dev/null
+++ b/tmake/lib/win32-msvc/vcapp.t
@@ -0,0 +1,244 @@
+#!
+#! This TMAKE template - Microsoft Visual C++ 5.0 applications
+#!
+#${
+ if ( Config("qt") ) {
+ if ( !(Project("DEFINES") =~ /QT_NODLL/) &&
+ ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) ||
+ ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows');
+ }
+ if ( Config("qt") ) {
+ $moc_aware = 1;
+ AddIncludePath(Project('TMAKE_INCDIR_QT'));
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( Project("TMAKE_QT_DLL") ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( Project("TMAKE_QT_DLL") ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+
+ if ( Config("console") ) {
+ $project{"VC_PROJ_TYPE"} = 'Win32 (x86) Console Application';
+ $project{"VC_PROJ_CODE"} = '0x0103';
+ $vc_base_libs = 'kernel32.lib user32.lib gdi32.lib winspool.lib ' .
+ 'comdlg32.lib advapi32.lib shell32.lib ole32.lib ' .
+ 'oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ';
+ $vc_libs = $vc_base_libs;
+ $vc_link_release = '/nologo /subsystem:console /machine:I386';
+ $vc_link_debug = '/nologo /subsystem:console /debug /machine:I386 /pdbtype:sept';
+ $vc_cpp_def_release = '/D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" ';
+ $vc_cpp_def_debug = '/D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" ';
+ } else {
+ $project{"VC_PROJ_TYPE"} = 'Win32 (x86) Application';
+ $project{"VC_PROJ_CODE"} = '0x0101';
+ $vc_base_libs = 'kernel32.lib user32.lib gdi32.lib winspool.lib ' .
+ 'comdlg32.lib advapi32.lib shell32.lib ole32.lib ' .
+ 'oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ';
+ $vc_libs = $vc_base_libs . 'wsock32.lib ';
+ $vc_link_release = '/nologo /subsystem:windows /machine:I386';
+ $vc_link_debug = '/nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept';
+ $vc_cpp_def_release = '/D "NDEBUG" /D "WIN32" /D "_WINDOWS" ';
+ $vc_cpp_def_debug = '/D "_DEBUG" /D "WIN32" /D "_WINDOWS" ';
+ }
+ $project{"VC_BASE_LINK_RELEASE"} = $vc_base_libs . $vc_link_release;
+ $project{"VC_BASE_LINK_DEBUG"} = $vc_base_libs . $vc_link_debug;
+ $tmake_libs = Project('TMAKE_LIBS') ? (Project('TMAKE_LIBS') . " ") : "";
+ $project{"VC_LINK_RELEASE"} = $vc_libs . $tmake_libs . $vc_link_release;
+ $project{"VC_LINK_DEBUG"} = $vc_libs . $tmake_libs . $vc_link_debug;
+
+ $vc_cpp_opt_release = '/nologo /W3 /GX /O2 ';
+ $vc_cpp_opt_debug = '/nologo /W3 /Gm /GX /Zi /Od ';
+ $vc_cpp_opt_common = '/YX /FD /c';
+ $project{"VC_BASE_CPP_RELEASE"} = $vc_cpp_opt_release . $vc_cpp_def_release . $vc_cpp_opt_common;
+ $project{"VC_BASE_CPP_DEBUG"} = $vc_cpp_opt_debug . $vc_cpp_def_debug . $vc_cpp_opt_common;
+ ExpandPath("INCPATH",'/I ',' /I ','');
+ if ( $text ne "" ) { $vc_inc = $text . " "; $text = ""; } else { $vc_inc = ""; }
+ ExpandGlue("DEFINES",'/D "','" /D "','"');
+ if ( $text ne "" ) { $vc_def = $text . " "; $text = ""; } else { $vc_def = ""; }
+ $project{"VC_CPP_RELEASE"} = $vc_cpp_opt_release . $vc_inc . $vc_cpp_def_release . $vc_def . $vc_cpp_opt_common;
+ $project{"VC_CPP_DEBUG"} = $vc_cpp_opt_debug . $vc_inc . $vc_cpp_def_debug . $vc_def . $vc_cpp_opt_common;
+
+ $project{"MAKEFILE"} = $project{"PROJECT"} . ".mak";
+ $project{"TARGETAPP"} = $project{"TARGET"} . ".exe";
+ Project('TMAKE_FILETAGS = HEADERS SOURCES TARGET DESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) {
+ $project{$_} =~ s-/-\\-g;
+ }
+ StdInit();
+ if ( defined($project{"DESTDIR"}) ) {
+ $project{"TARGETAPP"} = $project{"DESTDIR"} . "\\" . $project{"TARGETAPP"};
+ $project{"TARGETAPP"} =~ s/\\+/\\/g;
+ }
+ %all_files = ();
+ @files = split(/\s+/,$project{"HEADERS"});
+ foreach ( @files ) { $all_files{$_} = "h" };
+ @files = split(/\s+/,$project{"SOURCES"});
+ foreach ( @files ) { $all_files{$_} = "s" };
+ if ( $moc_aware ) {
+ @files = split(/\s+/,$project{"_HDRMOC"});
+ foreach ( @files ) { $all_files{$_} = "m"; }
+ @files = split(/\s+/,$project{"_SRCMOC"});
+ foreach ( @files ) { $all_files{$_} = "i"; }
+ }
+ %file_names = ();
+ foreach $f ( %all_files ) {
+ $n = $f;
+ $n =~ s/^.*\\//;
+ $file_names{$n} = $f;
+ $file_path{$n} = ".\\" . $f;
+ $file_path2{$n} = (($f =~ /^\./) ? "" : ".\\") . $f;
+ }
+#$}
+# Microsoft Developer Studio Project File - #$ Substitute('Name="$$TARGET" - Package Owner=<4>');
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE #$ Substitute('"$$VC_PROJ_TYPE" $$VC_PROJ_CODE');
+
+CFG=#$ Substitute('$$TARGET - Win32 Debug');
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "#$ ExpandGlue('MAKEFILE','','','".');
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f #$ Substitute('"$$MAKEFILE" CFG="$$TARGET - Win32 Debug"');
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE #$ Substitute('"$$TARGET - Win32 Release" (based on "$$VC_PROJ_TYPE")');
+!MESSAGE #$ Substitute('"$$TARGET - Win32 Debug" (based on "$$VC_PROJ_TYPE")');
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+#$ Config("windows") && ($text='MTL=midl.exe');
+RSC=rc.exe
+
+!IF "$(CFG)" == #$ Substitute('"$$TARGET - Win32 Release"');
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+#$ Config("windows") && ($text='# PROP Ignore_Export_Lib 0');
+# PROP Target_Dir ""
+# ADD BASE CPP #$ Expand("VC_BASE_CPP_RELEASE");
+# ADD CPP #$ Expand("VC_CPP_RELEASE");
+#$ Config("windows") || DisableOutput();
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+#$ Config("windows") || EnableOutput();
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 #$ Expand("VC_BASE_LINK_RELEASE");
+# ADD LINK32 #$ Expand("VC_LINK_RELEASE");
+
+!ELSEIF "$(CFG)" == #$ Substitute('"$$TARGET - Win32 Debug"');
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+#$ Config("windows") && ($text='# PROP Ignore_Export_Lib 0');
+# PROP Target_Dir ""
+# ADD BASE CPP #$ Expand("VC_BASE_CPP_DEBUG");
+# ADD CPP #$ Expand("VC_CPP_DEBUG");
+#$ Config("windows") || DisableOutput();
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+#$ Config("windows") || EnableOutput();
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 #$ Expand("VC_BASE_LINK_DEBUG");
+# ADD LINK32 #$ Expand("VC_LINK_DEBUG");
+
+!ENDIF
+
+# Begin Target
+
+# Name #$Substitute('"$$TARGET - Win32 Release"');
+# Name #$Substitute('"$$TARGET - Win32 Debug"');
+#${
+ foreach $n ( sort keys %file_names ) {
+ $f = $file_names{$n};
+ $p = $file_path{$n};
+ $p2 = $file_path2{$n};
+ $t = $all_files{$f};
+ if ( ($t eq "h") && $moc_output{$f} ) {
+ my($build);
+ $build = "\n\n# Begin Custom Build - Running moc...\nInputPath=" . $p2 . "\n\n"
+ . '"' . $moc_output{$f} . '" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"'
+ . "\n\tmoc $p2 -o " . $moc_output{$f} . "\n\n"
+ . "# End Custom Build\n\n";
+ $text .= ("# Begin Source File\n\nSOURCE=$p\n\n"
+ . '!IF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Release"'
+ . $build);
+ $text .= ('!ELSEIF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Debug"'
+ . $build
+ . "!ENDIF \n\n# End Source File\n");
+ } elsif ( $t eq "i" ) {
+ my($build,$dn);
+ $build = "\n\n# Begin Custom Build - Running moc...\nInputPath=" . $p2 . "\n\n"
+ . '"' . $f . '" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"'
+ . "\n\tmoc ". $moc_input{$f} . " -o $f\n\n"
+ . "# End Custom Build\n\n";
+ $dn = $n;
+ $dn =~ s/\..*//;
+ $dn =~ tr/a-z/A-Z/;
+ $text .= ("# Begin Source File\n\nSOURCE=$p\n"
+ . "USERDEP__$dn=" . '"' . $moc_input{$f} . '"' . "\n\n"
+ . '!IF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Release"'
+ . $build);
+ $text .= ('!ELSEIF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Debug"'
+ . $build
+ . "!ENDIF \n\n# End Source File\n");
+ } elsif ( $t eq "s" || $t eq "m" || $t eq "h" ) {
+ $text .= "# Begin Source File\n\nSOURCE=$p\n# End Source File\n";
+ }
+ }
+ chop $text;
+#$}
+# End Target
+# End Project
diff --git a/tmake/lib/win32-msvc/vclib.t b/tmake/lib/win32-msvc/vclib.t
new file mode 100644
index 0000000..11cd1d7
--- /dev/null
+++ b/tmake/lib/win32-msvc/vclib.t
@@ -0,0 +1,178 @@
+#!
+#! This TMAKE template - Microsoft Visual C++ 5.0 libraries
+#!
+#${
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows');
+ }
+ if ( Config("qt") ) {
+ $moc_aware = 1;
+ AddIncludePath(Project('TMAKE_INCDIR_QT'));
+ }
+
+ $project{"VC_PROJ_TYPE"} = 'Win32 (x86) Static Library';
+ $project{"VC_PROJ_CODE"} = '0x0104';
+
+ $vc_cpp_def_release = '/D "NDEBUG" /D "WIN32" /D "_WINDOWS" ';
+ $vc_cpp_def_debug = '/D "_DEBUG" /D "WIN32" /D "_WINDOWS" ';
+ $vc_cpp_opt_release = '/nologo /W3 /GX /O2 ';
+ $vc_cpp_opt_debug = '/nologo /W3 /Gm /GX /Zi /Od ';
+ $vc_cpp_opt_common = '/YX /FD /c';
+ $project{"VC_BASE_CPP_RELEASE"} = $vc_cpp_opt_release . $vc_cpp_def_release . $vc_cpp_opt_common;
+ $project{"VC_BASE_CPP_DEBUG"} = $vc_cpp_opt_debug . $vc_cpp_def_debug . $vc_cpp_opt_common;
+ ExpandPath("INCPATH",'/I ',' /I ','');
+ if ( $text ne "" ) { $vc_inc = $text . " "; $text = ""; } else { $vc_inc = ""; }
+ ExpandGlue("DEFINES",'/D "','" /D "','"');
+ if ( $text ne "" ) { $vc_def = $text . " "; $text = ""; } else { $vc_def = ""; }
+ $project{"VC_CPP_RELEASE"} = $vc_cpp_opt_release . $vc_inc . $vc_cpp_def_release . $vc_def . $vc_cpp_opt_common;
+ $project{"VC_CPP_DEBUG"} = $vc_cpp_opt_debug . $vc_inc . $vc_cpp_def_debug . $vc_def . $vc_cpp_opt_common;
+
+ $project{"MAKEFILE"} = $project{"PROJECT"} . ".mak";
+ $project{"TARGETLIB"} = $project{"TARGET"} . ".lib";
+ Project('TMAKE_FILETAGS = HEADERS SOURCES TARGET DESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) {
+ $project{$_} =~ s-/-\\-g;
+ }
+ StdInit();
+ if ( defined($project{"DESTDIR"}) ) {
+ $project{"TARGETLIB"} = $project{"DESTDIR"} . "\\" . $project{"TARGETLIB"};
+ $project{"TARGETLIB"} =~ s/\\+/\\/g;
+ }
+ %all_files = ();
+ @files = split(/\s+/,$project{"HEADERS"});
+ foreach ( @files ) { $all_files{$_} = "h" };
+ @files = split(/\s+/,$project{"SOURCES"});
+ foreach ( @files ) { $all_files{$_} = "s" };
+ if ( $moc_aware ) {
+ @files = split(/\s+/,$project{"_HDRMOC"});
+ foreach ( @files ) { $all_files{$_} = "m"; }
+ @files = split(/\s+/,$project{"_SRCMOC"});
+ foreach ( @files ) { $all_files{$_} = "i"; }
+ }
+ %file_names = ();
+ foreach $f ( %all_files ) {
+ $n = $f;
+ $n =~ s/^.*\\//;
+ $file_names{$n} = $f;
+ $file_path{$n} = ".\\" . $f;
+ $file_path2{$n} = (($f =~ /^\./) ? "" : ".\\") . $f;
+ }
+#$}
+# Microsoft Developer Studio Project File - #$ Substitute('Name="$$TARGET" - Package Owner=<4>');
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE #$ Substitute('"$$VC_PROJ_TYPE" $$VC_PROJ_CODE');
+
+CFG=#$ Substitute('$$TARGET - Win32 Debug');
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "#$ ExpandGlue('MAKEFILE','','','".');
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f #$ Substitute('"$$MAKEFILE" CFG="$$TARGET - Win32 Debug"');
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE #$ Substitute('"$$TARGET - Win32 Release" (based on "$$VC_PROJ_TYPE")');
+!MESSAGE #$ Substitute('"$$TARGET - Win32 Debug" (based on "$$VC_PROJ_TYPE")');
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF "$(CFG)" == #$ Substitute('"$$TARGET - Win32 Release"');
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP #$ Expand("VC_BASE_CPP_RELEASE");
+# ADD CPP #$ Expand("VC_CPP_RELEASE");
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo #$ Project("TARGETLIB") && Substitute('/out:"$$TARGETLIB"');
+
+!ELSEIF "$(CFG)" == #$ Substitute('"$$TARGET - Win32 Debug"');
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP #$ Expand("VC_BASE_CPP_DEBUG");
+# ADD CPP #$ Expand("VC_CPP_DEBUG");
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo #$ Project("TARGETLIB") && Substitute('/out:"$$TARGETLIB"');
+
+!ENDIF
+
+# Begin Target
+
+# Name #$Substitute('"$$TARGET - Win32 Release"');
+# Name #$Substitute('"$$TARGET - Win32 Debug"');
+#${
+ foreach $n ( sort keys %file_names ) {
+ $f = $file_names{$n};
+ $p = $file_path{$n};
+ $p2 = $file_path2{$n};
+ $t = $all_files{$f};
+ if ( ($t eq "h") && $moc_output{$f} ) {
+ my($build);
+ $build = "\n\n# Begin Custom Build - Running moc...\nInputPath=" . $p2 . "\n\n"
+ . '"' . $moc_output{$f} . '" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"'
+ . "\n\tmoc $p2 -o " . $moc_output{$f} . "\n\n"
+ . "# End Custom Build\n\n";
+ $text .= ("# Begin Source File\n\nSOURCE=$p\n\n"
+ . '!IF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Release"'
+ . $build);
+ $text .= ('!ELSEIF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Debug"'
+ . $build
+ . "!ENDIF \n\n# End Source File\n");
+ } elsif ( $t eq "i" ) {
+ my($build,$dn);
+ $build = "\n\n# Begin Custom Build - Running moc...\nInputPath=" . $p2 . "\n\n"
+ . '"' . $f . '" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"'
+ . "\n\tmoc ". $moc_input{$f} . " -o $f\n\n"
+ . "# End Custom Build\n\n";
+ $dn = $n;
+ $dn =~ s/\..*//;
+ $dn =~ tr/a-z/A-Z/;
+ $text .= ("# Begin Source File\n\nSOURCE=$p\n"
+ . "USERDEP__$dn=" . '"' . $moc_input{$f} . '"' . "\n\n"
+ . '!IF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Release"'
+ . $build);
+ $text .= ('!ELSEIF "$(CFG)" == "' . $project{"TARGET"} . ' - Win32 Debug"'
+ . $build
+ . "!ENDIF \n\n# End Source File\n");
+ } elsif ( $t eq "s" || $t eq "m" || $t eq "h" ) {
+ $text .= "# Begin Source File\n\nSOURCE=$p\n# End Source File\n";
+ }
+ }
+ chop $text;
+#$}
+# End Target
+# End Project
diff --git a/tmake/lib/win32-symantec/app.t b/tmake/lib/win32-symantec/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-symantec/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-symantec/generic.t b/tmake/lib/win32-symantec/generic.t
new file mode 100644
index 0000000..ab39654
--- /dev/null
+++ b/tmake/lib/win32-symantec/generic.t
@@ -0,0 +1,211 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( $ENV{"QT_DLL"} && !$ENV{"QT_NODLL"} ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( Project("TARGET") eq "qt" ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ $moc_aware = 1;
+ AddIncludePath(Project('TMAKE_INCDIR_QT'));
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( Project("TARGET") eq "qt" ) {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_MAKEDLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( (Project("DEFINES") =~ /QT_DLL/) ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project('TMAKE_APP_FLAG') ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".lib";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) {
+ $project{$_} =~ s-[/\\]+-\\-g;
+ }
+ if ( Project('DEF_FILE') ) {
+ Project('TMAKE_LFLAGS *= /DEF:$$DEF_FILE');
+ }
+ if ( Project('RC_FILE') ) {
+ if ( Project('RES_FILE') ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project('RES_FILE') ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandPath("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LIB = #$ Expand("TMAKE_LIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.cxx.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.cc.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.c.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ $(LINK) $(LFLAGS) $(OBJECTS) $(OBJMOC), $(TARGET),, $(LIBS)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ -del $(TARGET)
+#${
+# $text = "\t\$(LIB) \$(TARGET) "
+# . join(" \\\n+",split(/\s+/,$project{"OBJECTS"})) . " \\\n+"
+# . join(" \\\n+",split(/\s+/,$project{"OBJMOC"})) . ",;";
+#$}
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -copy $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project('RC_FILE') || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project('RC_FILE') || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ #$ ExpandGlue("OBJECTS","-del ","\n\t-del ","");
+ #$ ExpandGlue("SRCMOC" ,"-del ","\n\t-del ","");
+ #$ ExpandGlue("OBJMOC" ,"-del ","\n\t-del ","");
+ -del $(TARGET)
+ #$ ExpandGlue("CLEAN_FILES","-del ","\n\t-del ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-symantec/lib.t b/tmake/lib/win32-symantec/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-symantec/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-symantec/subdirs.t b/tmake/lib/win32-symantec/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-symantec/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-symantec/tmake.conf b/tmake/lib/win32-symantec/tmake.conf
new file mode 100644
index 0000000..81f88c2
--- /dev/null
+++ b/tmake/lib/win32-symantec/tmake.conf
@@ -0,0 +1,56 @@
+#
+#
+#
+# tmake configuration for Win32/Symantec C++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = sc
+TMAKE_CFLAGS = -mn -w2
+TMAKE_CFLAGS_WARN_ON =
+TMAKE_CFLAGS_WARN_OFF = -w
+TMAKE_CFLAGS_RELEASE = -o
+TMAKE_CFLAGS_DEBUG = -g
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = $$TMAKE_CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)\include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o$obj $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o$@ $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$obj $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$@ $<
+
+TMAKE_LINK = link
+TMAKE_LFLAGS = /NOLOGO /NOI
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = /DEBUG
+TMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:console
+TMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:windows
+TMAKE_LFLAGS_CONSOLE_DLL= /SUBSYSTEM:console /DLL
+TMAKE_LFLAGS_WINDOWS_DLL= /SUBSYSTEM:windows /DLL
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib
+TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib
+TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib
+TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib
+TMAKE_LIBS_OPENGL = opengl32.lib
+
+TMAKE_MOC = moc
+
+TMAKE_LIB = lib /C /N /NOI /P:32
+TMAKE_RC = rc
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-visage/app.t b/tmake/lib/win32-visage/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-visage/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-visage/generic.t b/tmake/lib/win32-visage/generic.t
new file mode 100644
index 0000000..b5b1fb6
--- /dev/null
+++ b/tmake/lib/win32-visage/generic.t
@@ -0,0 +1,207 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( $ENV{"QT_DLL"} && !$ENV{"QT_NODLL"} ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( Project("TARGET") eq "qt" ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ $moc_aware = 1;
+ AddIncludePath(Project('TMAKE_INCDIR_QT'));
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( Project("TARGET") eq "qt" ) {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_MAKEDLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( (Project("DEFINES") =~ /QT_DLL/) ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project('TMAKE_APP_FLAG') ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".lib";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) {
+ $project{$_} =~ s-[/\\]+-\\-g;
+ }
+ if ( Project('DEF_FILE') ) {
+ Project('TMAKE_LFLAGS *= /DEF:$$DEF_FILE');
+ }
+ if ( Project('RC_FILE') ) {
+ if ( Project('RES_FILE') ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project('RES_FILE') ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = #$ Expand("TMAKE_CC");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D","");
+INCPATH = #$ ExpandGlue("INCPATH",'-I',' -I','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LIB = #$ Expand("TMAKE_LIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .c
+
+.cpp.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.cxx.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.cc.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+.c.obj:
+ #$ Expand("TMAKE_COMPILE_IMP");
+
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+$(TARGET): $(OBJECTS) $(LIBS) #$ Expand("TARGETDEPS");
+ $(LINK) -B"$(LFLAGS)" $(OBJECTS) $(LIBS) -Fe$(TARGET)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ $(LIB) /OUT:$(TARGET) $(OBJECTS) $(OBJMOC)
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -copy $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project('RC_FILE') || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project('RC_FILE') || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ #$ ExpandGlue("OBJECTS","-del ","\n\t-del ","");
+ #$ ExpandGlue("SRCMOC" ,"-del ","\n\t-del ","");
+ #$ ExpandGlue("OBJMOC" ,"-del ","\n\t-del ","");
+ -del $(TARGET)
+ #$ ExpandGlue("CLEAN_FILES","-del ","\n\t-del ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-visage/lib.t b/tmake/lib/win32-visage/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-visage/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-visage/subdirs.t b/tmake/lib/win32-visage/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-visage/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-visage/tmake.conf b/tmake/lib/win32-visage/tmake.conf
new file mode 100644
index 0000000..69d3a82
--- /dev/null
+++ b/tmake/lib/win32-visage/tmake.conf
@@ -0,0 +1,56 @@
+#
+#
+#
+# tmake configuration for Win32/IBM Visual Age
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = icc -C
+TMAKE_CFLAGS = -Q -Ft -Gd -Gm+ -qrtti=all
+TMAKE_CFLAGS_WARN_ON = -W3
+TMAKE_CFLAGS_WARN_OFF = -W0
+TMAKE_CFLAGS_RELEASE = -Gl+ -O -Oc+
+TMAKE_CFLAGS_DEBUG = -Fb* -Ti -Tm
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = $$TMAKE_CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)\include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo"$obj" $src
+TMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo"$@" $<
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo"$obj" $src
+TMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo"$@" $<
+
+TMAKE_LINK = icc -Tdp $(CFLAGS)
+TMAKE_LFLAGS = -nologo -code:RX -data:RW -def -noe
+TMAKE_LFLAGS_RELEASE = -OPTF
+TMAKE_LFLAGS_DEBUG = -de -br
+TMAKE_LFLAGS_CONSOLE = -pmtype:vio
+TMAKE_LFLAGS_WINDOWS = -pmtype:pm
+TMAKE_LFLAGS_CONSOLE_DLL= -DLL
+TMAKE_LFLAGS_WINDOWS_DLL= -DLL
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib
+TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib
+TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib
+TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib
+TMAKE_LIBS_OPENGL = opengl32.lib glu32.lib
+
+TMAKE_MOC = moc
+
+TMAKE_LIB = ilib
+TMAKE_RC = rc
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32-watcom/app.t b/tmake/lib/win32-watcom/app.t
new file mode 100644
index 0000000..fc4dc2c
--- /dev/null
+++ b/tmake/lib/win32-watcom/app.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 applications.
+#!
+#$ Project('TMAKE_APP_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-watcom/generic.t b/tmake/lib/win32-watcom/generic.t
new file mode 100644
index 0000000..883c794
--- /dev/null
+++ b/tmake/lib/win32-watcom/generic.t
@@ -0,0 +1,201 @@
+#!
+#! This is a tmake template for building Win32 applications or libraries.
+#!
+#${
+ if ( Config("qt") ) {
+ if ( $ENV{"QT_DLL"} && !$ENV{"QT_NODLL"} ) {
+ Project('TMAKE_QT_DLL = 1');
+ if ( Project("TARGET") eq "qt" ) {
+ Project('CONFIG += dll');
+ }
+ }
+ }
+ if ( Config("dll") || Project("TMAKE_APP_FLAG") ) {
+ Project('CONFIG -= staticlib');
+ Project('TMAKE_APP_OR_DLL = 1');
+ } else {
+ Project('CONFIG += staticlib');
+ }
+ if ( Config("warn_off") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_OFF');
+ } elsif ( Config("warn_on") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_WARN_ON');
+ }
+ if ( Config("debug") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_DEBUG');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_DEBUG');
+ } elsif ( Config("release") ) {
+ Project('TMAKE_CFLAGS += $$TMAKE_CFLAGS_RELEASE');
+ Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_RELEASE');
+ }
+ if ( Config("qt") || Config("opengl") ) {
+ Project('CONFIG += windows' );
+ }
+ if ( Config("qt") ) {
+ $moc_aware = 1;
+ AddIncludePath(Project('TMAKE_INCDIR_QT'));
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL');
+ }
+ if ( Project("TARGET") eq "qt" ) {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_MAKEDLL');
+ }
+ } else {
+ if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) {
+ Project('DEFINES *= QT_DLL');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT');
+ if ( (Project("DEFINES") =~ /QT_DLL/) ) {
+ my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
+ Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
+ }
+ }
+ }
+ if ( Config("opengl") ) {
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
+ }
+ if ( Config("dll") ) {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE_DLL');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS_DLL');
+ if ( Project("TMAKE_LIB_FLAG") ) {
+ my $ver = Project("VERSION");
+ $ver =~ s/\.//g;
+ $project{"TARGET_EXT"} = "${ver}.dll";
+ } else {
+ $project{"TARGET_EXT"} = ".dll";
+ }
+ } else {
+ Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE');
+ Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS');
+ if ( Project('TMAKE_APP_FLAG') ) {
+ $project{"TARGET_EXT"} = ".exe";
+ } else {
+ $project{"TARGET_EXT"} = ".lib";
+ }
+ }
+ if ( Config("windows") ) {
+ if ( Config("console") ) {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_WINDOWS_ANY');
+ }
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_WINDOWS');
+ } else {
+ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY');
+ Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE');
+ }
+ Project('TMAKE_LIBS += $$LIBS');
+ Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS');
+ foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) {
+ $project{$_} =~ s-[/\\]+-\\-g;
+ }
+ if ( Project('DEF_FILE') ) {
+ Project('TMAKE_LFLAGS *= /DEF:$$DEF_FILE');
+ }
+ if ( Project('RC_FILE') ) {
+ if ( Project('RES_FILE') ) {
+ tmake_error("Both .rc and .res file specified.\n" .
+ "Please specify one of them, not both.");
+ }
+ $project{"RES_FILE"} = $project{"RC_FILE"};
+ $project{"RES_FILE"} =~ s/\.rc$/.res/i;
+ Project('TARGETDEPS += $$RES_FILE');
+ }
+ if ( Project('RES_FILE') ) {
+ Project('TMAKE_LIBS *= $$RES_FILE');
+ }
+ $linebreak = '&';
+ StdInit();
+ if ( Project("VERSION") ) {
+ $project{"VER_MAJ"} = $project{"VERSION"};
+ $project{"VER_MAJ"} =~ s/\.\d+$//;
+ $project{"VER_MIN"} = $project{"VERSION"};
+ $project{"VER_MIN"} =~ s/^\d+\.//;
+ }
+#$}
+#!
+# Makefile for building #$ Expand("TARGET")
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+####### Compiler, tools and options
+
+#$ Config("qt") || DisableOutput();
+QTDIR = #$ $text = $ENV{"QTDIR"};
+#$ Config("qt") || EnableOutput();
+CC = #$ Expand("TMAKE_CC");
+CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-d="," -d=","");
+INCPATH = #$ ExpandPath("INCPATH",'-i=',' -i=','');
+#$ !Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LINK = #$ Expand("TMAKE_LINK");
+LFLAGS = #$ Expand("TMAKE_LFLAGS");
+LIBS = #$ Expand("TMAKE_LIBS");
+#$ !Project("TMAKE_APP_OR_DLL") && EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+LIB = #$ Expand("TMAKE_LIB");
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+MOC = #$ Expand("TMAKE_MOC");
+
+ZIP = #$ Expand("TMAKE_ZIP");
+
+####### Files
+
+HEADERS = #$ ExpandList("HEADERS");
+SOURCES = #$ ExpandList("SOURCES");
+OBJECTS = #$ ExpandList("OBJECTS");
+SRCMOC = #$ ExpandList("SRCMOC");
+OBJMOC = #$ ExpandList("OBJMOC");
+DIST = #$ ExpandList("DISTFILES");
+TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"});
+TMPLIST = #$ ExpandGlue("TARGET","","",".lst");
+####### Build rules
+
+all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)';
+
+$(TARGET): $(HEADERS) $(OBJECTS) $(OBJMOC) #$ Expand("TARGETDEPS");
+ @%create $(TMPLIST)
+#$ Project("TMAKE_APP_OR_DLL") || DisableOutput();
+ @%append $(TMPLIST) NAME #$ Expand("TARGET");
+ #$ ExpandGlue("OBJECTS",'@%append $(TMPLIST) FIL ',",","");
+ #$ ExpandGlue("OBJMOC" ,'@%append $(TMPLIST) FIL ',",","");
+ #$ ExpandGlue("TMAKE_LIBS" ,'@%append $(TMPLIST) LIBR ',",","");
+ $(LINK) $(LFLAGS) @$(TMPLIST)
+#$ Project("TMAKE_APP_OR_DLL") || EnableOutput();
+#$ Project("TMAKE_APP_OR_DLL") && DisableOutput();
+ @for %i in ( $(OBJECTS) $(OBJMOC) ) do @%append $(TMPLIST) +'%i'
+ $(LIB) $(TARGET) @$(TMPLIST)
+#$ Project("TMAKE_APP_OR_DLL") && EnableOutput();
+ del $(TMPLIST)
+#$ (Config("dll") && Project("DLLDESTDIR")) || DisableOutput();
+ -copy $(TARGET) #$ Expand("DLLDESTDIR");
+#$ (Config("dll") && Project("DLLDESTDIR")) || EnableOutput();
+#$ Project('RC_FILE') || DisableOutput();
+
+#$ Substitute("\$\$RES_FILE: \$\$RC_FILE\n\t\$\$TMAKE_RC \$\$RC_FILE");
+#$ Project('RC_FILE') || EnableOutput();
+
+moc: $(SRCMOC)
+
+#$ TmakeSelf();
+
+dist:
+ #$ Substitute('$(ZIP) $$PROJECT.zip $$PROJECT.pro $(SOURCES) $(HEADERS) $(DIST)');
+
+clean:
+ #$ ExpandGlue("OBJECTS","-del ","\n\t-del ","");
+ #$ ExpandGlue("SRCMOC" ,"-del ","\n\t-del ","");
+ #$ ExpandGlue("OBJMOC" ,"-del ","\n\t-del ","");
+ -del $(TARGET)
+ #$ ExpandGlue("CLEAN_FILES","-del ","\n\t-del ","");
+
+####### Compile
+
+#$ BuildObj(Project("OBJECTS"),Project("SOURCES"));
+#$ BuildMocObj(Project("OBJMOC"),Project("SRCMOC"));
+#$ BuildMocSrc(Project("HEADERS"));
+#$ BuildMocSrc(Project("SOURCES"));
diff --git a/tmake/lib/win32-watcom/lib.t b/tmake/lib/win32-watcom/lib.t
new file mode 100644
index 0000000..d8ac6c7
--- /dev/null
+++ b/tmake/lib/win32-watcom/lib.t
@@ -0,0 +1,6 @@
+#############################################################################
+#!
+#! This is a tmake template for building Win32 libraries.
+#!
+#$ Project('TMAKE_LIB_FLAG = 1');
+#$ IncludeTemplate("generic.t");
diff --git a/tmake/lib/win32-watcom/subdirs.t b/tmake/lib/win32-watcom/subdirs.t
new file mode 100644
index 0000000..8b881ab
--- /dev/null
+++ b/tmake/lib/win32-watcom/subdirs.t
@@ -0,0 +1,2 @@
+#! Use the common Win32 template
+#$ IncludeTemplate("../win32/subdirs.t");
diff --git a/tmake/lib/win32-watcom/tmake.conf b/tmake/lib/win32-watcom/tmake.conf
new file mode 100644
index 0000000..862e915
--- /dev/null
+++ b/tmake/lib/win32-watcom/tmake.conf
@@ -0,0 +1,54 @@
+#
+#
+#
+# tmake configuration for Win32/Watcom C++
+#
+
+TEMPLATE = app
+CONFIG = qt warn_on release
+
+TMAKE_CC = wcl386
+TMAKE_CFLAGS = -zq
+TMAKE_CFLAGS_WARN_ON = -w2
+TMAKE_CFLAGS_WARN_OFF = -w0
+TMAKE_CFLAGS_RELEASE = -ox
+TMAKE_CFLAGS_DEBUG = -d2
+TMAKE_CFLAGS_YACC =
+
+TMAKE_CXX = $$TMAKE_CC
+TMAKE_CXXFLAGS = $$TMAKE_CFLAGS
+TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON
+TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF
+TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
+TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
+TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC
+
+TMAKE_INCDIR =
+TMAKE_INCDIR_QT = $(QTDIR)\include
+
+TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -fo=$obj $src
+TMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -fo=$obj $src
+
+TMAKE_LINK = wlink
+TMAKE_LFLAGS = op quiet op c
+TMAKE_LFLAGS_RELEASE =
+TMAKE_LFLAGS_DEBUG = d all
+TMAKE_LFLAGS_CONSOLE = sys nt
+TMAKE_LFLAGS_WINDOWS = sys nt_win
+TMAKE_LFLAGS_CONSOLE_DLL= sys nt
+TMAKE_LFLAGS_WINDOWS_DLL= sys nt_win
+
+TMAKE_LIBS =
+TMAKE_LIBS_CONSOLE =
+TMAKE_LIBS_WINDOWS =
+TMAKE_LIBS_QT = %QTDIR%\lib\qt.lib
+TMAKE_LIBS_QT_DLL = %QTDIR%\lib\qtmain.lib
+TMAKE_LIBS_QT_OPENGL = %QTDIR%\lib\qgl.lib
+TMAKE_LIBS_OPENGL = opengl32.lib
+
+TMAKE_MOC = moc
+
+TMAKE_LIB = wlib -b -c -n -q -p=512
+TMAKE_RC = rc
+
+TMAKE_ZIP = zip -r -9
diff --git a/tmake/lib/win32/subdirs.t b/tmake/lib/win32/subdirs.t
new file mode 100644
index 0000000..4c857fd
--- /dev/null
+++ b/tmake/lib/win32/subdirs.t
@@ -0,0 +1,54 @@
+#############################################################################
+#!
+#! This is a tmake template for creating a makefile that invokes make in
+#! sub directories - for Win32.
+#!
+#${
+ StdInit();
+ $m = "";
+ foreach ( split(/\s+/,$project{"SUBDIRS"}) ) {
+ $m = $m . "\tcd $_\n\tDOMAKE\n\t\@cd ..\n";
+ }
+ $project{"SUBMAKE"} = $m;
+ Project('MAKEFILE') || Project('MAKEFILE = Makefile');
+ Project('TMAKE') || Project('TMAKE = tmake');
+#$}
+#!
+# Makefile for building targets in sub directories.
+# Generated by tmake at #$ Now();
+# Project: #$ Expand("PROJECT");
+# Template: #$ Expand("TEMPLATE");
+#############################################################################
+
+MAKEFILE= #$ Expand("MAKEFILE");
+TMAKE = #$ Expand("TMAKE");
+
+SUBDIRS = #$ ExpandList("SUBDIRS");
+
+all: $(SUBDIRS)
+
+#${
+ foreach ( split(/\s+/,$project{"SUBDIRS"}) ) {
+ if ( Project("TMAKE_NOFORCE") ) {
+ $text = $text . $_ . ":\n\t" .
+ "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n";
+ } else {
+ $text = $text . $_ . ": FORCE\n\t" .
+ "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n";
+ }
+ }
+#$}
+#$ TmakeSelf();
+
+tmake_all:
+#${
+ foreach ( split(/\s+/,$project{"SUBDIRS"}) ) {
+ $text .= "\tcd $_\n\t\$(TMAKE\) $_.pro -o \$(MAKEFILE)\n\t\@cd ..\n";
+ }
+#$}
+
+clean:
+#$ $text = $project{"SUBMAKE"}; $text =~ s/DOMAKE/\$(MAKE\) clean/g;
+#$ Project("TMAKE_NOFORCE") && DisableOutput();
+FORCE:
+#$ Project("TMAKE_NOFORCE") && EnableOutput();
diff --git a/vhdlparser/CharStream.cc b/vhdlparser/CharStream.cc
new file mode 100644
index 0000000..8cc17c3
--- /dev/null
+++ b/vhdlparser/CharStream.cc
@@ -0,0 +1,212 @@
+/* Generated By:JavaCC: Do not edit this line. CharStream.cc Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#include "CharStream.h"
+
+namespace {
+template <class T>
+void ArrayCopy(T* src, int src_offset, T* dest, int dest_offset, int len) {
+ for (int i = 0; i < len; i++) {
+ dest[dest_offset + i] = src[src_offset + i];
+ }
+}
+
+class StringReaderStream : public ReaderStream {
+ public:
+ StringReaderStream(const JAVACC_STRING_TYPE& str) : str_(str), cur_(0), max_(str.size()) {}
+ virtual size_t read(JAVACC_CHAR_TYPE *bufptr, int offset, size_t len) {
+ size_t count = str_.copy(bufptr + offset, len > max_ ? max_ : len, cur_);
+ cur_ += count;
+ max_ -= count;
+ return count;
+ }
+ virtual ~StringReaderStream() {}
+ virtual bool endOfInput() {
+ return max_ == 0;
+ }
+
+ private:
+ const JAVACC_STRING_TYPE str_;
+ size_t cur_;
+ size_t max_;
+};
+}
+
+namespace vhdl {
+namespace parser {
+void CharStream::ReInit(const JAVACC_STRING_TYPE& str, int startline,
+ int startcolumn, int buffersize) {
+ StringReaderStream *stream = new StringReaderStream(str);
+ ReInit(stream, startline, startcolumn, buffersize);
+ deleteStream = true;
+}
+
+void CharStream::ReInit(ReaderStream *input_stream, int startline,
+ int startcolumn, int buffersize) {
+ if (deleteStream) {
+ delete inputStream;
+ }
+
+ if (buffer != NULL) {
+ DeleteBuffers();
+ }
+
+ available = bufsize = buffersize;
+ buffer = new JAVACC_CHAR_TYPE[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+
+ column = startcolumn - 1;
+ inputStream = input_stream;
+ line = startline;
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ bufpos = -1;
+ deleteStream = false;
+}
+
+void CharStream::DeleteBuffers() {
+ delete[] buffer;
+ delete[] bufline;
+ delete[] bufcolumn;
+}
+
+void CharStream::adjustBeginLineColumn(int newLine, int newCol) {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin) {
+ len = bufpos - tokenBegin + inBuf + 1;
+ } else {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len && bufline[j = start % bufsize] ==
+ bufline[k = (start + 1) % bufsize]) {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ start++;
+ }
+
+ if (i < len) {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len) {
+ if (bufline[j = start % bufsize] != bufline[(start + 1) % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ start++;
+ }
+ }
+
+ line = bufline[j];
+ column = bufcolumn[j];
+}
+
+void CharStream::ExpandBuff(bool wrapAround) {
+ JAVACC_CHAR_TYPE *newbuffer = new JAVACC_CHAR_TYPE[bufsize + 2048];
+ int *newbufline = new int[bufsize + 2048];
+ int *newbufcolumn = new int[bufsize + 2048];
+
+ if (wrapAround) {
+ ArrayCopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ ArrayCopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+ ArrayCopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ ArrayCopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ ArrayCopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ ArrayCopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufpos += (bufsize - tokenBegin);
+ } else {
+ ArrayCopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ ArrayCopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ ArrayCopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ bufpos -= tokenBegin;
+ }
+
+ maxNextCharInd = bufpos;
+ DeleteBuffers();
+ buffer = newbuffer;
+ bufline = newbufline;
+ bufcolumn = newbufcolumn;
+ bufsize += 2048;
+ available = bufsize;
+ tokenBegin = 0;
+}
+
+void CharStream::FillBuff() {
+ if (maxNextCharInd == available) {
+ if (available == bufsize) {
+ if (tokenBegin > 2048) {
+ bufpos = maxNextCharInd = 0;
+ available = tokenBegin;
+ } else if (tokenBegin < 0) {
+ bufpos = maxNextCharInd = 0;
+ } else {
+ ExpandBuff(false);
+ }
+ } else if (available > tokenBegin) {
+ available = bufsize;
+ } else if ((tokenBegin - available) < 2048) {
+ ExpandBuff(true);
+ } else {
+ available = tokenBegin;
+ }
+ }
+
+ int i = inputStream->read(buffer, maxNextCharInd, available - maxNextCharInd);
+ if (i > 0) {
+ maxNextCharInd += i;
+ } else {
+ --bufpos;
+ backup(0);
+ if (tokenBegin == -1) {
+ tokenBegin = bufpos;
+ }
+ }
+}
+
+void CharStream::UpdateLineColumn(JAVACC_CHAR_TYPE c) {
+ column++;
+ if (prevCharIsLF) {
+ prevCharIsLF = false;
+ column = 1;
+ line++;
+ } else if (prevCharIsCR) {
+ prevCharIsCR = false;
+ if (c == '\n') {
+ prevCharIsLF = true;
+ } else {
+ column = 1;
+ line++;
+ }
+ }
+
+ switch (c) {
+ case '\r' :
+ prevCharIsCR = true;
+ break;
+ case '\n' :
+ prevCharIsLF = true;
+ break;
+ case '\t' :
+ column--;
+ column += (tabSize - (column % tabSize));
+ break;
+ default :
+ break;
+ }
+
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+}
+
+}
+}
+/* JavaCC - OriginalChecksum=e709b9ee1adf0fcb6b1c5e1641f10348 (do not edit this line) */
diff --git a/vhdlparser/CharStream.h b/vhdlparser/CharStream.h
new file mode 100644
index 0000000..b0e74b6
--- /dev/null
+++ b/vhdlparser/CharStream.h
@@ -0,0 +1,257 @@
+/* Generated By:JavaCC: Do not edit this line. CharStream.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef CHARSTREAM_H
+#define CHARSTREAM_H
+#include "JavaCC.h"
+
+#ifndef INITIAL_BUFFER_SIZE
+#define INITIAL_BUFFER_SIZE 4096
+#endif
+
+namespace vhdl {
+namespace parser {
+
+/**
+ * This class describes a character stream that maintains line and
+ * column number positions of the characters. It also has the capability
+ * to backup the stream to some extent. An implementation of this
+ * class is used in the TokenManager implementation generated by
+ * JavaCCParser.
+ *
+ * All the methods except backup can be implemented in any fashion. backup
+ * needs to be implemented correctly for the correct operation of the lexer.
+ * Rest of the methods are all used to get information like line number,
+ * column number and the string that constitutes a token and are not used
+ * by the lexer. Hence their implementation won't affect the generated lexer's
+ * operation.
+ */
+
+
+class CharStream {
+ public:
+ void setTabSize(int i) { tabSize = i; }
+ int getTabSize(int) { return tabSize; }
+ virtual int getColumn() { return trackLineColumn ? bufcolumn[bufpos] : -1; }
+ virtual int getLine() { return trackLineColumn ? bufline[bufpos] : -1; }
+ virtual int getEndColumn() { return trackLineColumn ? bufcolumn[bufpos] : -1; }
+ virtual int getEndLine() { return trackLineColumn ? bufline[bufpos] : -1; }
+ virtual int getBeginColumn() { return trackLineColumn ? bufcolumn[tokenBegin] : -1; }
+ virtual int getBeginLine() { return trackLineColumn ? bufline[tokenBegin] : -1; }
+
+ virtual bool getTrackLineColumn() { return trackLineColumn; }
+ virtual void setTrackLineColumn(bool val) { trackLineColumn = val; }
+
+/**
+ * Backs up the input stream by amount steps. Lexer calls this method if it
+ * had already read some characters, but could not use them to match a
+ * (longer) token. So, they will be used again as the prefix of the next
+ * token and it is the implemetation's responsibility to do this right.
+ */
+virtual inline void backup(int amount) {
+ inBuf += amount;
+ bufpos -= amount;
+ if (bufpos < 0) {
+ bufpos += bufsize;
+ }
+}
+
+/**
+ * Returns the next character that marks the beginning of the next token.
+ * All characters must remain in the buffer between two successive calls
+ * to this method to implement backup correctly.
+ */
+virtual inline JAVACC_CHAR_TYPE BeginToken() {
+ tokenBegin = -1;
+ JAVACC_CHAR_TYPE c = readChar();
+ tokenBegin = bufpos;
+ return c;
+}
+
+
+/**
+ * Returns the next character from the selected input. The method
+ * of selecting the input is the responsibility of the class
+ * implementing this class.
+ */
+virtual inline JAVACC_CHAR_TYPE readChar() {
+ if (inBuf > 0) {
+ --inBuf;
+ ++bufpos;
+ if (bufpos == bufsize) {
+ bufpos = 0;
+ }
+
+ return buffer[bufpos];
+ }
+
+ ++bufpos;
+ if (bufpos >= maxNextCharInd) {
+ FillBuff();
+ }
+
+ JAVACC_CHAR_TYPE c = buffer[bufpos];
+
+ if (trackLineColumn) {
+ UpdateLineColumn(c);
+ }
+
+ return c;
+}
+
+
+ virtual void ExpandBuff(bool wrapAround);
+ virtual void FillBuff();
+
+ /**
+ * Returns a string made up of characters from the marked token beginning
+ * to the current buffer position. Implementations can return
+ * anything that they want to. For example, for efficiency, one might decide
+ * to just return NULL, which is a valid implementation.
+ */
+ virtual JAVACC_STRING_TYPE GetImage() {
+ if (bufpos >= tokenBegin)
+ return JAVACC_STRING_TYPE(buffer + tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return JAVACC_STRING_TYPE(buffer + tokenBegin, bufsize - tokenBegin)
+ .append(buffer, bufpos + 1);
+ }
+
+ /**
+ * Returns an array of characters that make up the suffix of length 'len' for
+ * the currently matched token. This is used to build up the matched string
+ * for use in actions in the case of MORE. A simple and inefficient
+ * implementation of this is as follows :
+ */
+ virtual JAVACC_STRING_TYPE GetSuffix(int len) {
+ if ((bufpos + 1) >= len) {
+ return JAVACC_STRING_TYPE(buffer + bufpos - len + 1, len);
+ }
+ return JAVACC_STRING_TYPE(buffer + bufsize - (len - bufpos - 1), len - bufpos - 1)
+ .append(buffer, bufpos + 1);
+ }
+
+ /**
+ * The lexer calls this function to indicate that it is done with the stream
+ * and hence implementations can free any resources held by this class.
+ */
+ virtual void DeleteBuffers();
+
+ virtual ~CharStream() {
+ if (deleteStream) {
+ delete inputStream;
+ }
+ DeleteBuffers();
+ }
+
+ bool endOfInput() {
+ return inBuf == 0 && bufpos + 1 >= maxNextCharInd &&
+ inputStream->endOfInput();
+ }
+
+ CharStream(const JAVACC_CHAR_TYPE *buf, int sz, int startline,
+ int startcolumn, int buffersize) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(JAVACC_STRING_TYPE(buf, sz), startline, startcolumn, buffersize);
+ }
+
+ CharStream(const JAVACC_CHAR_TYPE *buf, int sz, int startline, int startcolumn) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(JAVACC_STRING_TYPE(buf, sz), startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ CharStream(const JAVACC_STRING_TYPE& str, int startline,
+ int startcolumn, int buffersize) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(str, startline, startcolumn, buffersize);
+ }
+
+ CharStream(const JAVACC_STRING_TYPE& str, int startline, int startcolumn) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0) ,tabSize(8), trackLineColumn(true){
+ ReInit(str, startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ CharStream(ReaderStream *input_stream, int startline,
+ int startcolumn, int) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(input_stream, startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ CharStream(ReaderStream *input_stream, int startline, int startcolumn) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(input_stream, startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ CharStream(ReaderStream *input_stream) :
+ bufline(NULL), bufcolumn(NULL), inputStream(NULL), deleteStream(false),
+ buffer(NULL), bufpos(0), bufsize(0), tokenBegin(0), column(0), line(0),
+ prevCharIsCR (false), prevCharIsLF (false), available(0), maxNextCharInd(0),
+ inBuf(0),tabSize(8), trackLineColumn(true) {
+ ReInit(input_stream, 1, 1, INITIAL_BUFFER_SIZE);
+ }
+
+ virtual void ReInit(ReaderStream *input_stream, int startline, int startcolumn,
+ int buffersize);
+
+ virtual void ReInit(ReaderStream *input_stream, int startline,
+ int startcolumn) {
+ ReInit(input_stream, startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ virtual void ReInit(ReaderStream *input_stream) {
+ ReInit(input_stream, 1, 1, INITIAL_BUFFER_SIZE);
+ }
+
+ virtual void ReInit(const JAVACC_STRING_TYPE& str, int startline,
+ int startcolumn, int buffersize);
+
+ virtual void ReInit(const JAVACC_STRING_TYPE& str, int startline,
+ int startcolumn) {
+ ReInit(str, startline, startcolumn, INITIAL_BUFFER_SIZE);
+ }
+
+ virtual void adjustBeginLineColumn(int newLine, int newCol);
+
+ protected:
+ virtual void UpdateLineColumn(JAVACC_CHAR_TYPE c);
+
+ int *bufline;
+ int *bufcolumn;
+ ReaderStream *inputStream;
+ bool deleteStream;
+ JAVACC_CHAR_TYPE * buffer;
+ int bufpos;
+ int bufsize;
+ int tokenBegin;
+ int column;
+ int line;
+ bool prevCharIsCR ;
+ bool prevCharIsLF ;
+ int available;
+ int maxNextCharInd;
+ int inBuf ;
+ int tabSize ;
+ bool trackLineColumn;
+};
+
+}
+}
+#endif
+/* JavaCC - OriginalChecksum=5eaf75ef6a2c7859369c80cf6fd037e0 (do not edit this line) */
diff --git a/vhdlparser/ErrorHandler.h b/vhdlparser/ErrorHandler.h
new file mode 100644
index 0000000..fba0a0e
--- /dev/null
+++ b/vhdlparser/ErrorHandler.h
@@ -0,0 +1,78 @@
+/* Generated By:JavaCC: Do not edit this line. ErrorHandler.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true,BUILD_PARSER=true,BUILD_TOKEN_MANAGER=true */
+#ifndef ERRORHANDLER_H
+#define ERRORHANDLER_H
+//#include <string>
+#include "JavaCC.h"
+#include "Token.h"
+
+namespace vhdl {
+namespace parser {
+
+//JAVACC_SIMPLE_STRING addUnicodeEscapes(JAVACC_STRING_TYPE str);
+
+ class VhdlParser;
+ class ErrorHandler {
+ friend class VhdlParserTokenManager;
+ friend class VhdlParser;
+ protected:
+ int error_count;
+ public:
+ // Called when the parser encounters a different token when expecting to
+ // consume a specific kind of token.
+ // expectedKind - token kind that the parser was trying to consume.
+ // expectedToken - the image of the token - tokenImages[expectedKind].
+ // actual - the actual token that the parser got instead.
+ virtual void handleUnexpectedToken(int , JAVACC_STRING_TYPE , Token *, VhdlParser *) {
+ error_count++;
+ // fprintf(stderr, "Expecting %s at: %d:%d but got %s\n", addUnicodeEscapes(expectedToken).c_str(), actual->beginLine, actual->beginColumn, addUnicodeEscapes(actual->image).c_str());
+ }
+ // Called when the parser cannot continue parsing.
+ // last - the last token successfully parsed.
+ // unexpected - the token at which the error occurs.
+ // production - the production in which this error occurrs.
+ virtual void handleParseError(Token *, Token *, JAVACC_SIMPLE_STRING , VhdlParser *) {
+ error_count++;
+ // fprintf(stderr, "Encountered: %s at: %d:%d while parsing: %s\n", addUnicodeEscapes(unexpected->image).c_str(), unexpected->beginLine, unexpected->beginColumn, production.c_str());
+ }
+ virtual int getErrorCount() {
+ return error_count;
+ }
+ virtual void handleOtherError(JAVACC_STRING_TYPE message, VhdlParser *) {
+ fprintf(stderr, "Error: %s\n", (char*)message.c_str());
+ }
+ virtual ~ErrorHandler() {}
+ ErrorHandler() { error_count = 0; }
+ };
+
+ class VhdlParserTokenManager;
+ class TokenManagerErrorHandler {
+ friend class VhdlParserTokenManager;
+ protected:
+ int error_count;
+ public:
+ // Returns a detailed message for the Error when it is thrown by the
+ // token manager to indicate a lexical error.
+ // Parameters :
+ // EOFSeen : indicates if EOF caused the lexical error
+ // curLexState : lexical state in which this error occurred
+ // errorLine : line number when the error occurred
+ // errorColumn : column number when the error occurred
+ // errorAfter : prefix that was seen before this error occurred
+ // curchar : the offending character
+ //
+ virtual void lexicalError(bool EOFSeen, int /*lexState*/, int errorLine, int errorColumn, JAVACC_STRING_TYPE errorAfter, JAVACC_CHAR_TYPE curChar, VhdlParserTokenManager*) {
+ // by default, we just print an error message and return.
+ fprintf(stderr, "Lexical error at: %d:%d. Encountered: %c after: %s.\n", errorLine, errorColumn, curChar, (EOFSeen? "EOF" : (const char*)errorAfter.c_str()));
+ }
+ virtual void lexicalError(JAVACC_STRING_TYPE errorMessage, VhdlParserTokenManager* ) {
+ fprintf(stderr, "%s\n", (char*)errorMessage.c_str());
+ }
+ virtual ~TokenManagerErrorHandler() {}
+ };
+
+}
+}
+
+#endif
+/* JavaCC - OriginalChecksum=685d19cb4cd943b60089f599e45f23ad (do not edit this line) */
diff --git a/vhdlparser/JavaCC.h b/vhdlparser/JavaCC.h
new file mode 100644
index 0000000..b97c20d
--- /dev/null
+++ b/vhdlparser/JavaCC.h
@@ -0,0 +1,52 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCC.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef __JAVACC_H
+#define __JAVACC_H
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <assert.h>
+#include <cstring>
+
+#include "vhdlstring.h"
+
+#ifndef JAVACC_CHAR_TYPE
+#define JAVACC_CHAR_TYPE char
+#endif
+
+#ifndef JAVACC_STRING_TYPE
+#define JAVACC_STRING_TYPE VhdlString
+#endif
+
+#define finally // TODO(Sreeni): Get rid of when we fix jjtree
+
+#define JAVACC_SIMPLE_STRING VhdlString
+
+JAVACC_SIMPLE_STRING addUnicodeEscapes(JAVACC_STRING_TYPE str);
+
+
+typedef JAVACC_STRING_TYPE StringBuffer;
+typedef JAVACC_STRING_TYPE String;
+
+// Abstraction on stream classes to read a block of data into a buffer.
+class ReaderStream {
+ public:
+ // Read block of data into a buffer and return the actual number read.
+ virtual size_t read(JAVACC_CHAR_TYPE *, int, size_t) {
+ return 0;
+ }
+ virtual bool endOfInput() { return true; }
+ virtual ~ReaderStream() {}
+};
+
+const JAVACC_CHAR_TYPE EMPTY[] = { 0 };
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#endif
+/* JavaCC - OriginalChecksum=775c677272b259e2a33aac80851ba9f1 (do not edit this line) */
diff --git a/vhdlparser/JavaCC.h.in b/vhdlparser/JavaCC.h.in
new file mode 100644
index 0000000..b97c20d
--- /dev/null
+++ b/vhdlparser/JavaCC.h.in
@@ -0,0 +1,52 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCC.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef __JAVACC_H
+#define __JAVACC_H
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <assert.h>
+#include <cstring>
+
+#include "vhdlstring.h"
+
+#ifndef JAVACC_CHAR_TYPE
+#define JAVACC_CHAR_TYPE char
+#endif
+
+#ifndef JAVACC_STRING_TYPE
+#define JAVACC_STRING_TYPE VhdlString
+#endif
+
+#define finally // TODO(Sreeni): Get rid of when we fix jjtree
+
+#define JAVACC_SIMPLE_STRING VhdlString
+
+JAVACC_SIMPLE_STRING addUnicodeEscapes(JAVACC_STRING_TYPE str);
+
+
+typedef JAVACC_STRING_TYPE StringBuffer;
+typedef JAVACC_STRING_TYPE String;
+
+// Abstraction on stream classes to read a block of data into a buffer.
+class ReaderStream {
+ public:
+ // Read block of data into a buffer and return the actual number read.
+ virtual size_t read(JAVACC_CHAR_TYPE *, int, size_t) {
+ return 0;
+ }
+ virtual bool endOfInput() { return true; }
+ virtual ~ReaderStream() {}
+};
+
+const JAVACC_CHAR_TYPE EMPTY[] = { 0 };
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#endif
+/* JavaCC - OriginalChecksum=775c677272b259e2a33aac80851ba9f1 (do not edit this line) */
diff --git a/vhdlparser/Makefile b/vhdlparser/Makefile
new file mode 100644
index 0000000..afbe656
--- /dev/null
+++ b/vhdlparser/Makefile
@@ -0,0 +1,62 @@
+#
+# This file was generated from Makefile.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+DOXYGEN = /Users/dimitri/doxygen
+TMAKEPATH = /Users/dimitri/doxygen/tmake/lib/macosx-c++
+ENV = env TMAKEPATH="$(TMAKEPATH)"
+TMAKE = /Users/dimitri/doxygen/tmake/bin/tmake
+MAKE = /opt/local/bin/gmake
+PYTHON = /opt/local/bin/python2
+PERL = /opt/local/bin/perl
+LEX = /usr/bin/flex
+RM = rm -f
+CP = cp
+VERSION = 1.8.8
+INSTALL = /usr/local
+INSTTOOL = /opt/local/bin/ginstall
+DOXYDOCS = ..
+DOCDIR = $(INSTALL)/share/doc/packages/doxygen
+QTDIR = /usr
+HAVE_DOT = /usr/local/bin/dot
+MKSPECS = -spec macx-g++
+#
+#
+#
+# Copyright (C) 1997-2000 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+all: Makefile.vhdlparser Makefile
+ $(MAKE) -f Makefile.vhdlparser $@
+
+Makefile.vhdlparser: vhdlparser.pro
+ $(ENV) $(PERL) "$(TMAKE)" vhdlparser.pro >Makefile.vhdlparser
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" vhdlparser.pro >Makefile.vhdlparser
+
+clean: Makefile.vhdlparser
+ $(MAKE) -f Makefile.vhdlparser clean
+
+regenerate:
+ $(RM) CharStream.cc CharStream.h ErrorHandler.h ParseException.cc ParseException.h \
+ Token.cc Token.h TokenManager.h TokenMgrError.cc TokenMgrError.h VhdlParser.cc VhdlParser.h \
+ VhdlParserConstants.h VhdlParserTokenManager.cc VhdlParserTokenManager.h \
+ JavaCC.h
+ javacc vhdlparser.jj
+ patch <vhdlparser.patch
+ $(CP) JavaCC.h.in JavaCC.h
+
+distclean: clean
+ $(RM) Makefile vhdlparser.pro
+
+FORCE:
diff --git a/vhdlparser/Makefile.in b/vhdlparser/Makefile.in
new file mode 100644
index 0000000..2838700
--- /dev/null
+++ b/vhdlparser/Makefile.in
@@ -0,0 +1,40 @@
+#
+#
+#
+# Copyright (C) 1997-2000 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+all: Makefile.vhdlparser Makefile
+ $(MAKE) -f Makefile.vhdlparser $@
+
+Makefile.vhdlparser: vhdlparser.pro
+ $(ENV) $(PERL) "$(TMAKE)" vhdlparser.pro >Makefile.vhdlparser
+
+tmake:
+ $(ENV) $(PERL) "$(TMAKE)" vhdlparser.pro >Makefile.vhdlparser
+
+clean: Makefile.vhdlparser
+ $(MAKE) -f Makefile.vhdlparser clean
+
+regenerate:
+ $(RM) CharStream.cc CharStream.h ErrorHandler.h ParseException.cc ParseException.h \
+ Token.cc Token.h TokenManager.h TokenMgrError.cc TokenMgrError.h VhdlParser.cc VhdlParser.h \
+ VhdlParserConstants.h VhdlParserTokenManager.cc VhdlParserTokenManager.h \
+ JavaCC.h
+ javacc vhdlparser.jj
+ patch <vhdlparser.patch
+ $(CP) JavaCC.h.in JavaCC.h
+
+distclean: clean
+ $(RM) Makefile vhdlparser.pro
+
+FORCE:
diff --git a/vhdlparser/Makefile.vhdlparser b/vhdlparser/Makefile.vhdlparser
new file mode 100644
index 0000000..22f38e5
--- /dev/null
+++ b/vhdlparser/Makefile.vhdlparser
@@ -0,0 +1,165 @@
+#############################################################################
+# Makefile for building ../lib/libvhdlparser.a
+# Generated by tmake at 10:48, 2014/08/21
+# Project: vhdlparser
+# Template: lib
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = cc
+CXX = c++
+CFLAGS = -pipe -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+CXXFLAGS= -pipe -mmacosx-version-min=10.5 -DYY_TYPEDEF_YY_SIZE_T -Dyy_size_t=int -w -fexceptions -DQT_LITE_UNICODE -Wall -W -Wno-deprecated-declarations -g -fstack-protector
+INCPATH = -I. -I../src -I../qtools -Igenerated_src/doxygen -I/opt/local/include
+AR = ar cq
+RANLIB = ranlib
+MOC = /usr/bin/moc
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = CharStream.h \
+ ErrorHandler.h \
+ JavaCC.h \
+ ParseException.h \
+ TokenManager.h \
+ Token.h \
+ vhdlstring.h \
+ VhdlParser.h \
+ VhdlParserConstants.h \
+ VhdlParserTokenManager.h \
+ TokenMgrError.h \
+ VhdlParserIF.h \
+ VhdlParserErrorHandler.hpp
+SOURCES = CharStream.cc \
+ ParseException.cc \
+ Token.cc \
+ TokenMgrError.cc \
+ VhdlParser.cc \
+ VhdlParserTokenManager.cc \
+ VhdlParserIF.cpp
+OBJECTS = ../objects/vhdlparser/CharStream.o \
+ ../objects/vhdlparser/ParseException.o \
+ ../objects/vhdlparser/Token.o \
+ ../objects/vhdlparser/TokenMgrError.o \
+ ../objects/vhdlparser/VhdlParser.o \
+ ../objects/vhdlparser/VhdlParserTokenManager.o \
+ ../objects/vhdlparser/VhdlParserIF.o
+SRCMOC =
+OBJMOC =
+DIST =
+TARGET = ../lib/libvhdlparser.a
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+all: $(TARGET)
+
+staticlib: $(TARGET)
+
+$(TARGET): $(OBJECTS) $(OBJMOC)
+ -rm -f $(TARGET)
+ $(AR) $(TARGET) $(OBJECTS) $(OBJMOC)
+ ranlib $(TARGET)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake vhdlparser.pro
+
+dist:
+ $(TAR) vhdlparser.tar vhdlparser.pro $(SOURCES) $(HEADERS) $(DIST)
+ $(GZIP) vhdlparser.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET)
+ -rm -f *~ core
+
+####### Compile
+
+../objects/vhdlparser/CharStream.o: CharStream.cc \
+ CharStream.h \
+ JavaCC.h \
+ vhdlstring.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/CharStream.o CharStream.cc
+
+../objects/vhdlparser/ParseException.o: ParseException.cc \
+ ParseException.h \
+ JavaCC.h \
+ vhdlstring.h \
+ Token.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/ParseException.o ParseException.cc
+
+../objects/vhdlparser/Token.o: Token.cc \
+ Token.h \
+ JavaCC.h \
+ vhdlstring.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/Token.o Token.cc
+
+../objects/vhdlparser/TokenMgrError.o: TokenMgrError.cc \
+ TokenMgrError.h \
+ JavaCC.h \
+ vhdlstring.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/TokenMgrError.o TokenMgrError.cc
+
+../objects/vhdlparser/VhdlParser.o: VhdlParser.cc \
+ ./VhdlParser.h \
+ JavaCC.h \
+ vhdlstring.h \
+ CharStream.h \
+ Token.h \
+ TokenManager.h \
+ VhdlParserTokenManager.h \
+ ErrorHandler.h \
+ VhdlParserConstants.h \
+ VhdlParser.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/VhdlParser.o VhdlParser.cc
+
+../objects/vhdlparser/VhdlParserTokenManager.o: VhdlParserTokenManager.cc \
+ ./VhdlParserTokenManager.h \
+ JavaCC.h \
+ vhdlstring.h \
+ CharStream.h \
+ Token.h \
+ ErrorHandler.h \
+ TokenManager.h \
+ VhdlParserConstants.h \
+ VhdlParser.h \
+ VhdlParserTokenManager.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/VhdlParserTokenManager.o VhdlParserTokenManager.cc
+
+../objects/vhdlparser/VhdlParserIF.o: VhdlParserIF.cpp \
+ VhdlParserTokenManager.h \
+ JavaCC.h \
+ vhdlstring.h \
+ CharStream.h \
+ Token.h \
+ ErrorHandler.h \
+ TokenManager.h \
+ VhdlParserConstants.h \
+ VhdlParser.h \
+ VhdlParserErrorHandler.hpp \
+ VhdlParserIF.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../objects/vhdlparser/VhdlParserIF.o VhdlParserIF.cpp
+
diff --git a/vhdlparser/ParseException.cc b/vhdlparser/ParseException.cc
new file mode 100644
index 0000000..31ee7a3
--- /dev/null
+++ b/vhdlparser/ParseException.cc
@@ -0,0 +1,186 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.cc Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#include "ParseException.h"
+
+
+namespace vhdl {
+namespace parser {
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generate_ParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the fields.
+ */
+
+ /**
+ * This constructor is used by the method "generate_ParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set.
+ */
+ ParseException::ParseException(Token currentTokenVal,
+ int** expectedTokenSequencesVal,
+ JAVACC_STRING_TYPE* tokenImageVal
+ )
+ {
+ initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal);
+ currentToken = currentTokenVal;
+ expectedTokenSequences = expectedTokenSequencesVal;
+ tokenImage = tokenImageVal;
+ }
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+
+ ParseException::ParseException() {
+ }
+
+ /** Constructor with message. */
+ ParseException::ParseException(JAVACC_STRING_TYPE message) {
+ }
+
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ int** expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants class.
+ */
+ JAVACC_STRING_TYPE* tokenImage;
+
+ /**
+ * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser) the correct error message
+ * gets displayed.
+ */
+ JAVACC_STRING_TYPE ParseException::initialise(Token currentToken,
+ int** expectedTokenSequences,
+ JAVACC_STRING_TYPE* tokenImage) {
+#if 0
+ //JAVACC_STRING_TYPE eol = System.getProperty("line.separator", "\n");
+ expected = new JAVACC_STRING_TYPE();
+ int maxSize = 0;
+ for (int i = 0; i < expectedTokenSequences.length; i++) {
+ if (maxSize < expectedTokenSequences[i].length) {
+ maxSize = expectedTokenSequences[i].length;
+ }
+ for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+ expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+ }
+ if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+ expected.append((JAVACC_CHAR_TYPE*)"...");
+ }
+ expected.append(eol).append(" ");
+ }
+ JAVACC_STRING_TYPE retval = (JAVACC_CHAR_TYPE*)"Encountered \"";
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0) retval += (JAVACC_CHAR_TYPE*)" ";
+ if (tok.kind == 0) {
+ retval += tokenImage[0];
+ break;
+ }
+ retval += (JAVACC_CHAR_TYPE*)" " + tokenImage[tok.kind];
+ retval += (JAVACC_CHAR_TYPE*)" \"";
+ retval += add_escapes(tok.image);
+ retval += (JAVACC_CHAR_TYPE*)" \"";
+ tok = tok.next;
+ }
+ retval += (JAVACC_CHAR_TYPE*)"\" at line " + currentToken.next.beginLine + (JAVACC_CHAR_TYPE*)", column " + currentToken.next.beginColumn;
+ retval += (JAVACC_CHAR_TYPE*)"." + eol;
+ if (expectedTokenSequences.length == 1) {
+ retval += (JAVACC_CHAR_TYPE*)"Was expecting:" + eol + (JAVACC_CHAR_TYPE*)" ";
+ } else {
+ retval += (JAVACC_CHAR_TYPE*)"Was expecting one of:" + eol + (JAVACC_CHAR_TYPE*)" ";
+ }
+ retval += expected.toString();
+ return retval;
+#endif
+ return (JAVACC_CHAR_TYPE*)"Parse exception";
+ }
+
+ /**
+ * The end of line JAVACC_STRING_TYPE for this machine.
+ */
+#define eol "\n"
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ JAVACC_STRING_TYPE ParseException::add_escapes(JAVACC_STRING_TYPE str) {
+/*
+ JAVACC_STRING_TYPE *retval = new JAVACC_STRING_TYPE();
+ JAVACC_CHAR_TYPE ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ JAVACC_STRING_TYPE s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+*/ return str;
+ }
+
+}
+}
+/* JavaCC - OriginalChecksum=99d488e13335cf377284c90700f070ed (do not edit this line) */
diff --git a/vhdlparser/ParseException.h b/vhdlparser/ParseException.h
new file mode 100644
index 0000000..1f3a3dc
--- /dev/null
+++ b/vhdlparser/ParseException.h
@@ -0,0 +1,99 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef _PARSE_EXCEPTION_H
+#define _PARSE_EXCEPTION_H
+#include "JavaCC.h"
+#include "Token.h"
+
+
+namespace vhdl {
+namespace parser {
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the fields.
+ */
+class ParseException {
+ public:
+
+ /**
+ * This constructor is used by the method "generateParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set.
+ */
+ ParseException(Token currentTokenVal,
+ int** expectedTokenSequencesVal,
+ JAVACC_STRING_TYPE* tokenImageVal
+ );
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+
+ ParseException();
+
+ /** Constructor with message. */
+ ParseException(JAVACC_STRING_TYPE message);
+
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ int** expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants class.
+ */
+ JAVACC_STRING_TYPE* tokenImage;
+
+ /**
+ * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser) the correct error message
+ * gets displayed.
+ */
+ private: JAVACC_STRING_TYPE initialise(Token currentToken,
+ int** expectedTokenSequences,
+ JAVACC_STRING_TYPE* tokenImage);
+
+ /**
+ * The end of line string for this machine.
+ */
+#define eol "\n"
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ JAVACC_STRING_TYPE add_escapes(JAVACC_STRING_TYPE str);
+
+};
+
+}
+}
+#endif
+/* JavaCC - OriginalChecksum=8c47c56fc2030f05b43e20cae6ca5d66 (do not edit this line) */
diff --git a/vhdlparser/Token.cc b/vhdlparser/Token.cc
new file mode 100644
index 0000000..62a8169
--- /dev/null
+++ b/vhdlparser/Token.cc
@@ -0,0 +1,92 @@
+/* Generated By:JavaCC: Do not edit this line. Token.cc Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true,TOKEN_INCLUDES=,TOKEN_EXTENDS= */
+#include "Token.h"
+
+namespace vhdl {
+namespace parser {
+
+/**
+ * Describes the input token stream.
+ */
+
+ /**
+ * An optional attribute value of the Token.
+ * Tokens which are not used as syntactic sugar will often contain
+ * meaningful values that will be used later on by the compiler or
+ * interpreter. This attribute value is often different from the image.
+ * Any subclass of Token that actually wants to return a non-NULL value can
+ * override this method as appropriate.
+ */
+ void * Token::getValue() {
+ return NULL;
+ }
+
+ /**
+ * No-argument constructor
+ */
+ Token::Token() {
+ this->next = NULL;
+ this->specialToken = NULL;
+ }
+
+ /**
+ * Constructs a new token for the specified Image.
+ */
+ Token::Token(int kind)
+ {
+ this->kind = kind;
+ this->next = NULL;
+ this->specialToken = NULL;
+ }
+
+ /**
+ * Constructs a new token for the specified Image and Kind.
+ */
+ Token::Token(int kind, JAVACC_STRING_TYPE image)
+ {
+ this->kind = kind;
+ this->image = image;
+ this->next = NULL;
+ this->specialToken = NULL;
+ }
+
+ /**
+ * Returns the image.
+ */
+ JAVACC_STRING_TYPE Token::toString()
+ {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simply add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken(ofKind, image);
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use sit in your lexical actions.
+ */
+ Token *Token::newToken(int ofKind, JAVACC_STRING_TYPE image)
+ {
+ switch(ofKind)
+ {
+ default : return new Token(ofKind, image);
+ }
+ }
+
+ Token *Token::newToken(int ofKind)
+ {
+ return newToken(ofKind, JAVACC_STRING_TYPE((JAVACC_CHAR_TYPE*)""));
+ }
+
+ Token::~Token() {
+ if (specialToken) delete specialToken;
+ }
+
+}
+}
+/* JavaCC - OriginalChecksum=9db9ca693072c4c37bb7cc933c0c5e35 (do not edit this line) */
diff --git a/vhdlparser/Token.h b/vhdlparser/Token.h
new file mode 100644
index 0000000..5fce69f
--- /dev/null
+++ b/vhdlparser/Token.h
@@ -0,0 +1,116 @@
+/* Generated By:JavaCC: Do not edit this line. Token.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true,TOKEN_INCLUDES=,TOKEN_EXTENDS= */
+#ifndef TOKEN_H
+#define TOKEN_H
+#include "JavaCC.h"
+
+
+namespace vhdl {
+namespace parser {
+
+/**
+ * Describes the input token stream.
+ */
+
+class Token
+{
+ public:
+
+ /**
+ * An integer that describes the kind of this token. This numbering
+ * system is determined by JavaCCParser, and a table of these numbers is
+ * stored in the file ...Constants.java.
+ */
+ int kind;
+
+ /** The line number of the first character of this Token. */
+ int beginLine;
+ /** The column number of the first character of this Token. */
+ int beginColumn;
+ /** The line number of the last character of this Token. */
+ int endLine;
+ /** The column number of the last character of this Token. */
+ int endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ JAVACC_STRING_TYPE image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to NULL. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ Token *next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to NULL.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToke_ field is NULL).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is NULL.
+ */
+ Token *specialToken;
+
+ /**
+ * An optional attribute value of the Token.
+ * Tokens which are not used as syntactic sugar will often contain
+ * meaningful values that will be used later on by the compiler or
+ * interpreter. This attribute value is often different from the image.
+ * Any subclass of Token that actually wants to return a non-NULL value can
+ * override this method as appropriate.
+ */
+ void * getValue();
+
+ /**
+ * No-argument constructor
+ */
+ Token();
+
+ /**
+ * Constructs a new token for the specified Image.
+ */
+ Token(int kind);
+
+ /**
+ * Constructs a new token for the specified Image and Kind.
+ */
+ Token(int kind, JAVACC_STRING_TYPE image);
+
+ /**
+ * Returns the image.
+ */
+ JAVACC_STRING_TYPE toString();
+
+ public: virtual ~Token();
+
+ /**
+ * Returns a new Token void *, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simply add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken(ofKind, image);
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use sit in your lexical actions.
+ */
+ static Token *newToken(int ofKind, JAVACC_STRING_TYPE image);
+
+ static Token *newToken(int ofKind);
+};
+
+}
+}
+#endif
+/* JavaCC - OriginalChecksum=2f5eb1c937adc983dfa2008c4fe383a7 (do not edit this line) */
diff --git a/vhdlparser/TokenManager.h b/vhdlparser/TokenManager.h
new file mode 100644
index 0000000..efffce6
--- /dev/null
+++ b/vhdlparser/TokenManager.h
@@ -0,0 +1,33 @@
+/* Generated By:JavaCC: Do not edit this line. TokenManager.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef TOKENMANAGER_H
+#define TOKENMANAGER_H
+#include "JavaCC.h"
+#include "Token.h"
+
+
+namespace vhdl {
+namespace parser {
+/**
+ * An implementation for this interface is generated by
+ * JavaCCParser. The user is free to use any implementation
+ * of their choice.
+ */
+
+class TokenManager {
+public:
+ /** This gets the next token from the input stream.
+ * A token of kind 0 (<EOF>) should be returned on EOF.
+ */
+ public: virtual Token *getNextToken() = 0;
+ public: virtual ~TokenManager() { }
+ public: virtual void lexicalError() {
+ fprintf(stderr, "Lexical error encountered\n");
+ }
+
+};
+
+}
+}
+#endif
+/* JavaCC - OriginalChecksum=d4725ee75465725057819b3b07fadaa7 (do not edit this line) */
diff --git a/vhdlparser/TokenMgrError.cc b/vhdlparser/TokenMgrError.cc
new file mode 100644
index 0000000..9093e6e
--- /dev/null
+++ b/vhdlparser/TokenMgrError.cc
@@ -0,0 +1,121 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.cc Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#include "TokenMgrError.h"
+
+namespace vhdl {
+namespace parser {
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexical error
+ * curLexState : lexical state in which this error occurred
+ * errorLine : line number when the error occurred
+ * errorColumn : column number when the error occurred
+ * errorAfter : prefix that was seen before this error occurred
+ * curJAVACC_CHAR_TYPE : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ JAVACC_STRING_TYPE TokenMgrError::LexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JAVACC_STRING_TYPE errorAfter, JAVACC_CHAR_TYPE curChar) {
+#if 0
+ JAVACC_STRING_TYPE s;
+ stringstream<JAVACC_STRING_TYPE> ss;
+ ss << "Lexical error at line " << errorLine << " column " << errorColumn
+ << ". Encountered: " << curChar << "(" << (int)curChar
+ << ") after : \"" << errorAfter.c_str() << "\"";
+ return (JAVACC_STRING_TYPE)ss.rdbuf()->str();
+#endif
+ return EMPTY;
+ }
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ JAVACC_STRING_TYPE TokenMgrError::getMessage() {
+ return message;
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ /** No arg constructor. */
+ TokenMgrError::TokenMgrError() {
+ }
+
+ /** Constructor with message and reason. */
+ TokenMgrError::TokenMgrError(JAVACC_STRING_TYPE message, int reason) {
+ errorCode = reason;
+ }
+
+ /** Full Constructor. */
+ TokenMgrError::TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JAVACC_STRING_TYPE errorAfter, JAVACC_CHAR_TYPE curChar, int reason) {
+ message = LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar);
+ errorCode = reason;
+ }
+
+// i < 16 - guaranteed
+char hexChar(int i) {
+ if (i < 10) {
+ return i - '0';
+ }
+ return 'a' + (i - 10);
+}
+
+/**
+ * Replaces unprintable characters by their escaped (or unicode escaped)
+ * equivalents in the given string
+ */
+JAVACC_SIMPLE_STRING addUnicodeEscapes(JAVACC_STRING_TYPE str) {
+ JAVACC_SIMPLE_STRING retval;
+ for (size_t i = 0; i < str.size(); i++) {
+ JAVACC_CHAR_TYPE ch = str[i];
+ switch (ch)
+ {
+ case 0 :
+ retval += EMPTY[0];
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if (ch < 0xff) {
+ retval += ch;
+ continue;
+ }
+ retval.append("\\u");
+ retval += (hexChar(ch >> 12));
+ retval += (hexChar((ch & 0x0f00) >> 8));
+ retval += (hexChar((ch & 0x00f0) >> 4));
+ retval += (hexChar(ch & 0x000f));
+ continue;
+ }
+ }
+ return retval;
+}
+
+}
+}
+/* JavaCC - OriginalChecksum=2bf63f131c8e60fd30c70d0b4f660016 (do not edit this line) */
diff --git a/vhdlparser/TokenMgrError.h b/vhdlparser/TokenMgrError.h
new file mode 100644
index 0000000..2702b29
--- /dev/null
+++ b/vhdlparser/TokenMgrError.h
@@ -0,0 +1,90 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.h Version 6.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+#ifndef _TOKENMGRERROR_H
+#define _TOKENMGRERROR_H
+#include "JavaCC.h"
+
+
+namespace vhdl {
+namespace parser {
+
+ enum LexerErrors {
+ /**
+ * Lexical error occurred.
+ */
+ LEXICAL_ERROR = 0,
+
+ /**
+ * An attempt was made to create a second instance of a token manager.
+ */
+ STATIC_LEXER_ERROR = 1,
+
+ /**
+ * Tried to change to an invalid lexical state.
+ */
+ INVALID_LEXICAL_STATE = 2,
+
+ /**
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ LOOP_DETECTED = 3,
+ };
+
+class TokenMgrError
+{
+ public:
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /**
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexical error
+ * curLexState : lexical state in which this error occurred
+ * errorLine : line number when the error occurred
+ * errorColumn : column number when the error occurred
+ * errorAfter : prefix that was seen before this error occurred
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ JAVACC_STRING_TYPE LexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JAVACC_STRING_TYPE errorAfter, JAVACC_CHAR_TYPE curChar);
+
+ private: JAVACC_STRING_TYPE message;
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ JAVACC_STRING_TYPE getMessage() ;
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ /** No arg constructor. */
+ public: TokenMgrError() ;
+
+ /** Constructor with message and reason. */
+ public: TokenMgrError(JAVACC_STRING_TYPE message, int reason) ;
+
+ /** Full Constructor. */
+ public: TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, JAVACC_STRING_TYPE errorAfter, JAVACC_CHAR_TYPE curChar, int reason) ;
+};
+
+}
+}
+#endif
+/* JavaCC - OriginalChecksum=c7d825cb4d037b031ae43569d383f738 (do not edit this line) */
diff --git a/vhdlparser/VhdlParser.cc b/vhdlparser/VhdlParser.cc
new file mode 100644
index 0000000..47ecf49
--- /dev/null
+++ b/vhdlparser/VhdlParser.cc
@@ -0,0 +1,13071 @@
+/* VhdlParser.cc */
+#include "./VhdlParser.h"
+namespace vhdl {
+namespace parser {
+ unsigned int jj_la1_0[] = {
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x0,0x90404000,0x20080000,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90004000,0x400000,0x0,0x90404000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x40000000,0x0,0x400000,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x40020000,0x40020001,0x0,0x0,0x0,0x40000000,0xd0020000,0x0,0x0,0x800000,0x0,0x0,0x80004000,0x400000,0x0,0x0,0x80404000,0x0,0x0,0x0,0x0,0x8000,0x0,0 [...]
+ unsigned int jj_la1_1[] = {
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x125808,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x1000,0x104800,0x1008,0x20000,0x125808,0x10000,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000,0x1000,0x1000000,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x20000,0x1000,0x0,0x4000000,0x4000000,0x0,0x400000,0x4000101,0x4000101,0x0,0x10,0x0,0x100,0x12024900,0x0,0x0,0x0,0x100,0x0,0x104800,0x8,0x20000,0x0,0x124808,0x0,0x10000,0x0,0x0,0x0,0x0,0x0,0x [...]
+ unsigned int jj_la1_2[] = {
+0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x110000,0x28000,0x0,0x20000000,0x0,0x0,0x0,0x200000,0x0,0x0,0x0,0x4000,0x0,0x0,0x110000,0x0,0x0,0x110000,0x0,0x4000,0x4000,0x0,0x0,0x0,0x0,0x28000,0x0,0x0,0x0,0x400,0x0,0x4000,0x0,0x0,0x0,0x4000,0x0,0x4000,0x400000,0x8000,0x8000,0x8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x1000000,0x1000,0x1000,0x0,0x0,0x0,0x100,0x11000,0x0,0x0,0x0,0x0,0x0,0x110000,0x0,0x0,0x1000,0x111000,0x0,0x0,0x4000,0x0,0x400,0x8000,0x28000,0x0,0x0, [...]
+ unsigned int jj_la1_3[] = {
+0x0,0x0,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x188830,0x8000000,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x80000,0x0,0x0,0x80000,0x0,0x108830,0x80000,0x0,0x188830,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x2000000,0x0,0x0,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x0,0x2000000,0x0,0x0,0x80000,0x80000,0x0,0x0,0x80000,0x80000,0x0,0x4000,0x80000,0x80000,0x0,0x2000,0x0,0x0,0x128810,0x0,0x0,0x0,0x0,0x0,0x108830,0x80000,0x0,0x0,0x188830,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 [...]
+ unsigned int jj_la1_4[] = {
+0x0,0x0,0x60000,0x30,0x40,0x100,0x0,0x0,0x0,0x0,0x40000,0x0,0x40001,0x0,0x0,0x0,0x0,0x40,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x40001,0x0,0x0,0x0,0x0,0x10000000,0x200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x20000,0x40,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0x40000,0x40000,0x40000,0x40000,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x4,0x40001,0x0,0x0,0x40000,0x1 [...]
+ unsigned int jj_la1_5[] = {
+0x1420,0x0,0x1c0,0x0,0x0,0x0,0x2,0x3c0,0x0,0x0,0x1c0,0x4000000,0x40001c0,0x0,0x0,0x0,0x180,0x0,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000000,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x180,0x40001c0,0x180,0x0,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000000,0x0,0x0,0x1c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x0,0x0,0x0,0x4000000,0x4000000,0x2,0x0,0x0,0x3c0,0x3c0,0x1c0,0x1c0,0x3c0,0x380,0x0,0x180,0x180,0x0,0x0,0x0,0x0,0 [...]
+
+ /** Constructor with user supplied TokenManager. */
+
+
+
+
+QCString VhdlParser::abstract_literal() {Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case DECIMAL_LITERAL:{if (!hasError) {
+
+ tok = jj_consume_token(DECIMAL_LITERAL);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case INTEGER:{if (!hasError) {
+
+ tok = jj_consume_token(INTEGER);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case BASED_LITERAL:{if (!hasError) {
+
+ tok = jj_consume_token(BASED_LITERAL);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[0] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::access_type_definition() {Token *tok;QCString str,str1;if (!hasError) {
+
+ tok = jj_consume_token(ACCESS_T);
+ }
+ if (!hasError) {
+
+ str1 = subtype_indication();
+ }
+
+str=tok->image.c_str(); return str+str1;
+assert(false);
+ }
+
+
+QCString VhdlParser::actual_designator() {QCString str;Token *t;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case OPEN_T:{if (!hasError) {
+
+ t = jj_consume_token(OPEN_T);
+ }
+ if (!hasError) {
+
+return t->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[1] = jj_gen;
+ if (jj_2_1(2147483647)) {if (!hasError) {
+
+ str = expression();
+ }
+ if (!hasError) {
+
+return str;
+ }
+
+ } else if (jj_2_2(2147483647)) {if (!hasError) {
+
+ str = name();
+ }
+ if (!hasError) {
+
+return str;
+ }
+
+ } else {
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::actual_parameter_part() {QCString s;if (!hasError) {
+
+ s = association_list();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::actual_part() {QCString s,s1;
+ if (jj_2_3(2147483647)) {if (!hasError) {
+
+ s = actual_designator();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BOX_T:{if (!hasError) {
+
+ jj_consume_token(BOX_T);
+ }
+ if (!hasError) {
+
+return "<>";
+ }
+
+ break;
+ }
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = actual_designator();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="(";s+=s1+")";return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[2] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::adding_operator() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PLUS_T:{if (!hasError) {
+
+ jj_consume_token(PLUS_T);
+ }
+ if (!hasError) {
+
+return "+";
+ }
+
+ break;
+ }
+ case MINUS_T:{if (!hasError) {
+
+ jj_consume_token(MINUS_T);
+ }
+ if (!hasError) {
+
+return "-";
+ }
+
+ break;
+ }
+ case AMPERSAND_T:{if (!hasError) {
+
+ jj_consume_token(AMPERSAND_T);
+ }
+ if (!hasError) {
+
+return "&";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[3] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::aggregate() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s = element_association();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[4] = jj_gen;
+ goto end_label_1;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = element_association();
+ }
+ if (!hasError) {
+
+s+=","+s1;
+ }
+
+ }
+ end_label_1: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return "("+s+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::alias_declaration() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(ALIAS_T);
+ }
+ if (!hasError) {
+
+ s2 = alias_designator();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COLON_T:{if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[5] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+s+=" is ";
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LBRACKET_T:{if (!hasError) {
+
+ s1 = signature();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[6] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+addVhdlType(s2.data(),getLine(ALIAS_T),Entry::VARIABLE_SEC,VhdlDocGen::ALIAS,0,s.data(),Public);
+
+ return s2+" "+s+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::alias_designator() {Token *tok=0;QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ tok = jj_consume_token(CHARACTER_LITERAL);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case STRINGLITERAL:{if (!hasError) {
+
+ s = operator_symbol();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[7] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::allocator() {
+ if (jj_2_4(3)) {if (!hasError) {
+
+ jj_consume_token(NEW_T);
+ }
+ if (!hasError) {
+
+ qualified_expression();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case NEW_T:{if (!hasError) {
+
+ jj_consume_token(NEW_T);
+ }
+ if (!hasError) {
+
+ subtype_indication();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[8] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::architecture_body() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(ARCHITECTURE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+QCString t=s1+"::"+s;
+ genLabels.resize(0);
+ pushLabel(genLabels,s1);
+ lastCompound=current;
+ addVhdlType(t,getLine(ARCHITECTURE_T),Entry::CLASS_SEC,VhdlDocGen::ARCHITECTURE,0,0,Private);
+ }
+ if (!hasError) {
+
+ try {if (!hasError) {
+
+ architecture_declarative_part();
+ }
+
+ } catch ( ...) {
+error_skipto(BEGIN_T);
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ architecture_statement_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARCHITECTURE_T:{if (!hasError) {
+
+ jj_consume_token(ARCHITECTURE_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[9] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[10] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+lastEntity=0;lastCompound=0; genLabels.resize(0);
+ }
+
+
+void VhdlParser::architecture_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case COMPONENT_T:
+ case CONSTANT_T:
+ case DISCONNECT_T:
+ case FILE_T:
+ case FOR_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[11] = jj_gen;
+ goto end_label_2;
+ }if (!hasError) {
+
+ block_declarative_item();
+ }
+
+ }
+ end_label_2: ;
+ }
+
+ }
+
+
+void VhdlParser::architecture_statement_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case POSTPONED_T:
+ case PROCESS_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[12] = jj_gen;
+ goto end_label_3;
+ }if (!hasError) {
+
+ concurrent_statement();
+ }
+
+ }
+ end_label_3: ;
+ }
+
+ }
+
+
+QCString VhdlParser::array_type_definition() {QCString s;
+ if (jj_2_5(2147483647)) {if (!hasError) {
+
+ s = unconstraint_array_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARRAY_T:{if (!hasError) {
+
+ s = constraint_array_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[13] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::assertion() {QCString s,s1,s2;Token *t=0;Token *t1=0;if (!hasError) {
+
+ jj_consume_token(ASSERT_T);
+ }
+ if (!hasError) {
+
+ s = condition();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case REPORT_T:{if (!hasError) {
+
+ t = jj_consume_token(REPORT_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[14] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SEVERITY_T:{if (!hasError) {
+
+ t1 = jj_consume_token(SEVERITY_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[15] = jj_gen;
+ ;
+ }
+ }
+
+s.prepend("assert ");
+ if(t) s1.prepend(" report ");
+ if(t1) s2.prepend(" report ");
+ return s+s1+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::assertion_statement() {QCString s,s1,s2;Token *t=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = label();
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[16] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = assertion();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(t) s+=":";
+ return s+s1+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::association_element() {QCString s,s1;if (!hasError) {
+
+ if (jj_2_6(2147483647)) {if (!hasError) {
+
+ s = formal_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(ARROW_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = actual_part();
+ }
+
+return s+" => "+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::association_list() {QCString s,s1;if (!hasError) {
+
+ s = association_element();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[17] = jj_gen;
+ goto end_label_4;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = association_element();
+ }
+ if (!hasError) {
+
+s+=","+s1;
+ }
+
+ }
+ end_label_4: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::attribute_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(ATTRIBUTE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = type_mark();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+addVhdlType(s.data(),getLine(ATTRIBUTE_T),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,s1.data(),Public);
+ return " attribute "+s+":"+s1+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::attribute_designator() {QCString s;Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case RANGE_T:{if (!hasError) {
+
+ tok = jj_consume_token(RANGE_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[18] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::attribute_name() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(APOSTROPHE_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+="'"+s1;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+"("+s1+")";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[19] = jj_gen;
+ ;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::attribute_specification() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(ATTRIBUTE_T);
+ }
+ if (!hasError) {
+
+ s = attribute_designator();
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s1 = entity_specification();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QCString t= s1+" is "+s2;
+ addVhdlType(s.data(),getLine(ATTRIBUTE_T),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,t.data(),Public);
+ return " attribute "+s+" of "+s1+ " is "+s2+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::base() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(INTEGER);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::base_specifier() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BASIC_IDENTIFIER);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::base_unit_declaration() {QCString s;if (!hasError) {
+
+ s = identifier();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::based_integer() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BASIC_IDENTIFIER);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::based_literal() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BASED_LITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::basic_identifier() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BASIC_IDENTIFIER);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+void VhdlParser::binding_indication() {if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case USE_T:{if (!hasError) {
+
+ jj_consume_token(USE_T);
+ }
+ if (!hasError) {
+
+ entity_aspect();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[20] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ generic_map_aspect();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[21] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+ port_map_aspect();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[22] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+QCString VhdlParser::bit_string_literal() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BIT_STRING_LITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::bit_value() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(BASIC_IDENTIFIER);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+void VhdlParser::block_configuration() {if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ block_specification();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[23] = jj_gen;
+ goto end_label_5;
+ }if (!hasError) {
+
+ use_clause();
+ }
+
+ }
+ end_label_5: ;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[24] = jj_gen;
+ goto end_label_6;
+ }if (!hasError) {
+
+ configuration_item();
+ }
+
+ }
+ end_label_6: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::block_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ type_declaration();
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ subtype_declaration();
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ constant_declaration();
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ signal_declaration();
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ variable_declaration();
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ file_declaration();
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ alias_declaration();
+ }
+
+ break;
+ }
+ case COMPONENT_T:{if (!hasError) {
+
+ component_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[25] = jj_gen;
+ if (jj_2_7(2147483647)) {if (!hasError) {
+
+ attribute_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case FOR_T:{if (!hasError) {
+
+ configuration_specification();
+ }
+
+ break;
+ }
+ case DISCONNECT_T:{if (!hasError) {
+
+ disconnection_specification();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[26] = jj_gen;
+ if (jj_2_8(3)) {if (!hasError) {
+
+ group_template_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ case VHDL2008TOOLDIR:{if (!hasError) {
+
+ jj_consume_token(VHDL2008TOOLDIR);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[27] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+void VhdlParser::block_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case COMPONENT_T:
+ case CONSTANT_T:
+ case DISCONNECT_T:
+ case FILE_T:
+ case FOR_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[28] = jj_gen;
+ goto end_label_7;
+ }if (!hasError) {
+
+ block_declarative_item();
+ }
+
+ }
+ end_label_7: ;
+ }
+
+ }
+
+
+void VhdlParser::block_header() {if (!hasError) {
+
+ if (jj_2_9(2147483647)) {if (!hasError) {
+
+ generic_clause();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ generic_map_aspect();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[29] = jj_gen;
+ ;
+ }
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+ port_clause();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+ port_map_aspect();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[30] = jj_gen;
+ ;
+ }
+ }
+
+ break;
+ }
+ default:
+ jj_la1[31] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::block_specification() {if (!hasError) {
+
+ name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ index_specification();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[32] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::block_statement() {QCString s;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BLOCK_T);
+ }
+ if (!hasError) {
+
+pushLabel(genLabels,s);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[33] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:{if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[34] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ block_header();
+ }
+ if (!hasError) {
+
+ block_declarative_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ block_statement_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BLOCK_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[35] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+genLabels=popLabel(genLabels);
+ }
+
+
+void VhdlParser::block_statement_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case POSTPONED_T:
+ case PROCESS_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[36] = jj_gen;
+ goto end_label_8;
+ }if (!hasError) {
+
+ concurrent_statement();
+ }
+
+ }
+ end_label_8: ;
+ }
+
+ }
+
+
+void VhdlParser::case_statement() {QCString s;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[37] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(CASE_T);
+ }
+ if (!hasError) {
+
+ s = expression();
+ }
+ if (!hasError) {
+
+QCString ca="case "+s;
+ FlowChart::addFlowChart(FlowChart::CASE_NO,0,ca);
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ case_statement_alternative();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[38] = jj_gen;
+ goto end_label_9;
+ }if (!hasError) {
+
+ case_statement_alternative();
+ }
+
+ }
+ end_label_9: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(CASE_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[39] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::END_CASE,"end case",0);
+ }
+
+
+void VhdlParser::case_statement_alternative() {QCString s;if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ s = choices();
+ }
+ if (!hasError) {
+
+ jj_consume_token(ARROW_T);
+ }
+ if (!hasError) {
+
+QCString t="when ";
+ t+=s+"=> ";
+ FlowChart::addFlowChart(FlowChart::WHEN_NO,s.data(),t);
+ }
+ if (!hasError) {
+
+ sequence_of_statement();
+ }
+
+FlowChart::moveToPrevLevel();
+ }
+
+
+QCString VhdlParser::character_literal() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(CHARACTER_LITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::choice() {QCString s;
+ if (jj_2_10(2147483647)) {if (!hasError) {
+
+ s = simple_expression();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_11(2147483647)) {if (!hasError) {
+
+ s = discrete_range();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_12(2147483647)) {if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case OTHER_T:{if (!hasError) {
+
+ jj_consume_token(OTHER_T);
+ }
+ if (!hasError) {
+
+return " others ";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[40] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::choices() {QCString s,s1;if (!hasError) {
+
+ s = choice();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BAR_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[41] = jj_gen;
+ goto end_label_10;
+ }if (!hasError) {
+
+ jj_consume_token(BAR_T);
+ }
+ if (!hasError) {
+
+ s1 = choice();
+ }
+ if (!hasError) {
+
+s+="|";s+=s1;
+ }
+
+ }
+ end_label_10: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::component_configuration() {if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ component_specification();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:
+ case PORT_T:
+ case USE_T:
+ case SEMI_T:{if (!hasError) {
+
+ binding_indication();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[42] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:{if (!hasError) {
+
+ block_configuration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[43] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::component_declaration() {QCString s;if (!hasError) {
+
+ jj_consume_token(COMPONENT_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:{if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[44] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+currP=VhdlDocGen::COMPONENT;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ generic_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[45] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+ port_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[46] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+addVhdlType(s.data(),getLine(COMPONENT_T),Entry::VARIABLE_SEC,VhdlDocGen::COMPONENT,0,0,Public);
+ currP=0;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(COMPONENT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[47] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::component_instantiation_statement() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = instantiation_unit();
+ }
+ if (!hasError) {
+
+addCompInst(s.lower().data(),s1.lower().data(),0,getLine());
+ }
+ if (!hasError) {
+
+ if (jj_2_13(2147483647)) {if (!hasError) {
+
+ generic_map_aspect();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+ port_map_aspect();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[48] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::component_specification() {if (!hasError) {
+
+ instantiation_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ name();
+ }
+
+ }
+
+
+QCString VhdlParser::composite_type_definition() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARRAY_T:{if (!hasError) {
+
+ s = array_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case RECORD_T:{if (!hasError) {
+
+ record_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[49] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::concurrent_assertion_statement() {if (!hasError) {
+
+ if (jj_2_14(2)) {if (!hasError) {
+
+ identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:{if (!hasError) {
+
+ jj_consume_token(POSTPONED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[50] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ assertion();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::concurrent_procedure_call_statement() {if (!hasError) {
+
+ if (jj_2_15(2)) {if (!hasError) {
+
+ identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:{if (!hasError) {
+
+ jj_consume_token(POSTPONED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[51] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ procedure_call();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::concurrent_signal_assignment_statement() {if (!hasError) {
+
+ if (jj_2_16(2)) {if (!hasError) {
+
+ identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:{if (!hasError) {
+
+ jj_consume_token(POSTPONED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[52] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ if (jj_2_17(2147483647)) {if (!hasError) {
+
+ conditional_signal_assignment();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WITH_T:{if (!hasError) {
+
+ selected_signal_assignment();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[53] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+ }
+
+
+void VhdlParser::concurrent_statement() {
+ if (jj_2_18(2147483647)) {if (!hasError) {
+
+ block_statement();
+ }
+
+ } else if (jj_2_19(2147483647)) {if (!hasError) {
+
+ process_statement();
+ }
+
+ } else if (jj_2_20(2147483647)) {if (!hasError) {
+
+ generate_statement();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CASE_T:{if (!hasError) {
+
+ case_scheme();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[54] = jj_gen;
+ if (jj_2_21(2147483647)) {if (!hasError) {
+
+ concurrent_assertion_statement();
+ }
+
+ } else if (jj_2_22(2147483647)) {if (!hasError) {
+
+ concurrent_signal_assignment_statement();
+ }
+
+ } else if (jj_2_23(2147483647)) {if (!hasError) {
+
+ component_instantiation_statement();
+ }
+
+ } else if (jj_2_24(2147483647)) {if (!hasError) {
+
+ concurrent_procedure_call_statement();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VHDL2008TOOLDIR:{if (!hasError) {
+
+ jj_consume_token(VHDL2008TOOLDIR);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[55] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+
+
+QCString VhdlParser::condition() {QCString s;if (!hasError) {
+
+ s = expression();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::condition_clause() {QCString s;if (!hasError) {
+
+ jj_consume_token(UNTIL_T);
+ }
+ if (!hasError) {
+
+ s = condition();
+ }
+
+return " until "+s;
+assert(false);
+ }
+
+
+void VhdlParser::conditional_signal_assignment() {if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ options();
+ }
+ if (!hasError) {
+
+ conditional_waveforms();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::conditional_waveforms() {if (!hasError) {
+
+ waveform();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_25(2147483647)) {
+ ;
+ } else {
+ goto end_label_11;
+ }if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ condition();
+ }
+ if (!hasError) {
+
+ jj_consume_token(ELSE_T);
+ }
+ if (!hasError) {
+
+ waveform();
+ }
+
+ }
+ end_label_11: ;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ condition();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[56] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::configuration_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(CONFIGURATION_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+confName=s+"::"+s1;
+ addVhdlType(s.data(),getLine(CONFIGURATION_T),Entry::VARIABLE_SEC,VhdlDocGen::CONFIG,"configuration",s1.data(),Public);
+ }
+ if (!hasError) {
+
+ configuration_declarative_part();
+ }
+ if (!hasError) {
+
+ block_configuration();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONFIGURATION_T:{if (!hasError) {
+
+ jj_consume_token(CONFIGURATION_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[57] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[58] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+genLabels.resize(0); confName="";
+ }
+
+
+void VhdlParser::configuration_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[59] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::configuration_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:
+ case GROUP_T:
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[60] = jj_gen;
+ goto end_label_12;
+ }if (!hasError) {
+
+ configuration_declarative_item();
+ }
+
+ }
+ end_label_12: ;
+ }
+
+ }
+
+
+void VhdlParser::configuration_item() {
+ if (jj_2_26(2147483647)) {if (!hasError) {
+
+ component_configuration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:{if (!hasError) {
+
+ block_configuration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[61] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::configuration_specification() {if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ component_specification();
+ }
+ if (!hasError) {
+
+ binding_indication();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+QCString VhdlParser::constant_declaration() {QCString s,s1,s2;Token *t=0;if (!hasError) {
+
+ jj_consume_token(CONSTANT_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VARASSIGN_T:{if (!hasError) {
+
+ t = jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[62] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(t)
+ s2.prepend(":=");
+ QCString it=s1+s2;
+ addVhdlType(s.data(),getLine(CONSTANT_T),Entry::VARIABLE_SEC,VhdlDocGen::CONSTANT,0,it.data(),Public);
+ it.prepend("constant ");
+ return it;
+assert(false);
+ }
+
+
+QCString VhdlParser::constraint_array_definition() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(ARRAY_T);
+ }
+ if (!hasError) {
+
+ s = index_constraint();
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+
+return s+" "+s1;
+assert(false);
+ }
+
+
+void VhdlParser::context_clause() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LIBRARY_T:
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[63] = jj_gen;
+ goto end_label_13;
+ }if (!hasError) {
+
+ context_item();
+ }
+
+ }
+ end_label_13: ;
+ }
+
+ }
+
+
+QCString VhdlParser::constraint() {QCString s;
+ if (jj_2_27(2147483647)) {if (!hasError) {
+
+ s = range_constraint();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_28(2147483647)) {if (!hasError) {
+
+ s = index_constraint();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::context_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LIBRARY_T:{if (!hasError) {
+
+ library_clause();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[64] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+QCString VhdlParser::decimal_literal() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(DECIMAL_LITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::delay_mechanism() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case TRANSPORT_T:{if (!hasError) {
+
+ jj_consume_token(TRANSPORT_T);
+ }
+ if (!hasError) {
+
+return " transport ";
+ }
+
+ break;
+ }
+ case INERTIAL_T:
+ case REJECT_T:{if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case REJECT_T:{if (!hasError) {
+
+ jj_consume_token(REJECT_T);
+ }
+ if (!hasError) {
+
+ s = expression();
+ }
+ if (!hasError) {
+
+s.prepend(" reject ");
+ }
+
+ break;
+ }
+ default:
+ jj_la1[65] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(INERTIAL_T);
+ }
+ if (!hasError) {
+
+return s+" inertial ";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[66] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::design_file() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARCHITECTURE_T:
+ case CONFIGURATION_T:
+ case CONTEXT_T:
+ case ENTITY_T:
+ case LIBRARY_T:
+ case PACKAGE_T:
+ case USE_T:{if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ design_unit();
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARCHITECTURE_T:
+ case CONFIGURATION_T:
+ case CONTEXT_T:
+ case ENTITY_T:
+ case LIBRARY_T:
+ case PACKAGE_T:
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[67] = jj_gen;
+ goto end_label_14;
+ }
+ }
+ end_label_14: ;
+ }
+ if (!hasError) {
+
+
+ }
+
+ break;
+ }
+ case 0:{if (!hasError) {
+
+ jj_consume_token(0);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[68] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::design_unit() {if (!hasError) {
+
+ context_clause();
+ }
+ if (!hasError) {
+
+ library_unit();
+ }
+
+ }
+
+
+QCString VhdlParser::designator() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case STRINGLITERAL:{if (!hasError) {
+
+ s = operator_symbol();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[69] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::direction() {Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case TO_T:{if (!hasError) {
+
+ tok = jj_consume_token(TO_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case DOWNTO_T:{if (!hasError) {
+
+ tok = jj_consume_token(DOWNTO_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[70] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::disconnection_specification() {if (!hasError) {
+
+ jj_consume_token(DISCONNECT_T);
+ }
+ if (!hasError) {
+
+ guarded_signal_specificatio();
+ }
+ if (!hasError) {
+
+ jj_consume_token(AFTER_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::guarded_signal_specificatio() {if (!hasError) {
+
+ signal_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ name();
+ }
+
+ }
+
+
+QCString VhdlParser::discrete_range() {QCString s;
+ if (jj_2_29(2147483647)) {if (!hasError) {
+
+ s = range();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_30(2147483647)) {if (!hasError) {
+
+ s = subtype_indication();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::element_association() {QCString s,s1;if (!hasError) {
+
+ if (jj_2_31(2147483647)) {if (!hasError) {
+
+ s = choices();
+ }
+ if (!hasError) {
+
+ jj_consume_token(ARROW_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+
+if(!s.isEmpty())
+ return s+"=>"+s1;
+return s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::element_declaration() {QCString s,s1;if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return s+":"+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::entity_aspect() {Token *tok;QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ENTITY_T:{if (!hasError) {
+
+ tok = jj_consume_token(ENTITY_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="("+s1+")";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[71] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONFIGURATION_T:{if (!hasError) {
+
+ tok = jj_consume_token(CONFIGURATION_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return tok->image.c_str()+s;
+ }
+
+ break;
+ }
+ case OPEN_T:{if (!hasError) {
+
+ tok = jj_consume_token(OPEN_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[72] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::entity_class() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ENTITY_T:{if (!hasError) {
+
+ jj_consume_token(ENTITY_T);
+ }
+ if (!hasError) {
+
+return "entity";
+ }
+
+ break;
+ }
+ case ARCHITECTURE_T:{if (!hasError) {
+
+ jj_consume_token(ARCHITECTURE_T);
+ }
+ if (!hasError) {
+
+return "architecture";
+ }
+
+ break;
+ }
+ case CONFIGURATION_T:{if (!hasError) {
+
+ jj_consume_token(CONFIGURATION_T);
+ }
+ if (!hasError) {
+
+return "configuration";
+ }
+
+ break;
+ }
+ case PROCEDURE_T:{if (!hasError) {
+
+ jj_consume_token(PROCEDURE_T);
+ }
+ if (!hasError) {
+
+return "procedure";
+ }
+
+ break;
+ }
+ case FUNCTION_T:{if (!hasError) {
+
+ jj_consume_token(FUNCTION_T);
+ }
+ if (!hasError) {
+
+return "function";
+ }
+
+ break;
+ }
+ case PACKAGE_T:{if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+return "package";
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ jj_consume_token(TYPE_T);
+ }
+ if (!hasError) {
+
+return "type";
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ jj_consume_token(SUBTYPE_T);
+ }
+ if (!hasError) {
+
+return "subtype";
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ jj_consume_token(CONSTANT_T);
+ }
+ if (!hasError) {
+
+return "constant";
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ jj_consume_token(SIGNAL_T);
+ }
+ if (!hasError) {
+
+return "signal";
+ }
+
+ break;
+ }
+ case VARIABLE_T:{if (!hasError) {
+
+ jj_consume_token(VARIABLE_T);
+ }
+ if (!hasError) {
+
+return "variable";
+ }
+
+ break;
+ }
+ case COMPONENT_T:{if (!hasError) {
+
+ jj_consume_token(COMPONENT_T);
+ }
+ if (!hasError) {
+
+return "component";
+ }
+
+ break;
+ }
+ case LABEL_T:{if (!hasError) {
+
+ jj_consume_token(LABEL_T);
+ }
+ if (!hasError) {
+
+return "label";
+ }
+
+ break;
+ }
+ case LITERAL_T:{if (!hasError) {
+
+ jj_consume_token(LITERAL_T);
+ }
+ if (!hasError) {
+
+return "literal";
+ }
+
+ break;
+ }
+ case UNITS_T:{if (!hasError) {
+
+ jj_consume_token(UNITS_T);
+ }
+ if (!hasError) {
+
+return "units";
+ }
+
+ break;
+ }
+ case GROUP_T:{if (!hasError) {
+
+ jj_consume_token(GROUP_T);
+ }
+ if (!hasError) {
+
+return "group";
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ jj_consume_token(FILE_T);
+ }
+ if (!hasError) {
+
+return "file";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[73] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::entity_class_entry() {QCString s;if (!hasError) {
+
+ s = entity_class();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BOX_T:{if (!hasError) {
+
+ jj_consume_token(BOX_T);
+ }
+ if (!hasError) {
+
+s+="<>";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[74] = jj_gen;
+ ;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::entity_class_entry_list() {QCString s,s1,s2;if (!hasError) {
+ if (!hasError) {
+
+ s1 = entity_class_entry();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[75] = jj_gen;
+ goto end_label_15;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s = entity_class_entry();
+ }
+ if (!hasError) {
+
+s2+=",";s2+=s;
+ }
+
+ }
+ end_label_15: ;
+ }
+
+return s1+s2;
+assert(false);
+ }
+
+
+void VhdlParser::entity_declaration() {QCString s;if (!hasError) {
+
+ jj_consume_token(ENTITY_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+lastEntity=current;
+ lastCompound=0;
+ addVhdlType(s.data(),getLine(ENTITY_T),Entry::CLASS_SEC,VhdlDocGen::ENTITY,0,0,Public);
+ }
+ if (!hasError) {
+
+ entity_header();
+ }
+ if (!hasError) {
+
+ entity_declarative_part();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BEGIN_T:{if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ entity_statement_part();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[76] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ENTITY_T:{if (!hasError) {
+
+ jj_consume_token(ENTITY_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[77] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[78] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+lastEntity=0;lastCompound=0; genLabels.resize(0);
+ }
+
+
+void VhdlParser::entity_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ type_declaration();
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ subtype_declaration();
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ constant_declaration();
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ signal_declaration();
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ variable_declaration();
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ file_declaration();
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ alias_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[79] = jj_gen;
+ if (jj_2_32(2147483647)) {if (!hasError) {
+
+ attribute_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case DISCONNECT_T:{if (!hasError) {
+
+ disconnection_specification();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[80] = jj_gen;
+ if (jj_2_33(3)) {if (!hasError) {
+
+ group_template_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[81] = jj_gen;
+ if (jj_2_34(5)) {if (!hasError) {
+
+ package_instantiation_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ package_declaration();
+ }
+
+ break;
+ }
+ case VHDL2008TOOLDIR:{if (!hasError) {
+
+ jj_consume_token(VHDL2008TOOLDIR);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[82] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+void VhdlParser::entity_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case CONSTANT_T:
+ case DISCONNECT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PACKAGE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[83] = jj_gen;
+ goto end_label_16;
+ }if (!hasError) {
+
+ entity_declarative_item();
+ }
+
+ }
+ end_label_16: ;
+ }
+
+ }
+
+
+QCString VhdlParser::entity_designator() {QCString s,s1;if (!hasError) {
+
+ s = entity_tag();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LBRACKET_T:{if (!hasError) {
+
+ s1 = signature();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[84] = jj_gen;
+ ;
+ }
+ }
+
+return s+s1;
+assert(false);
+ }
+
+
+void VhdlParser::entity_header() {if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+currP=VhdlDocGen::GENERIC;parse_sec=GEN_SEC;
+ }
+ if (!hasError) {
+
+ generic_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[85] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PORT_T:{if (!hasError) {
+
+currP=VhdlDocGen::PORT;
+ }
+ if (!hasError) {
+
+ port_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[86] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+QCString VhdlParser::entity_name_list() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ s1 = entity_designator();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[87] = jj_gen;
+ goto end_label_17;
+ }
+ }
+ end_label_17: ;
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case OTHER_T:{if (!hasError) {
+
+ jj_consume_token(OTHER_T);
+ }
+ if (!hasError) {
+
+return "other";
+ }
+
+ break;
+ }
+ case ALL_T:{if (!hasError) {
+
+ jj_consume_token(ALL_T);
+ }
+ if (!hasError) {
+
+return "all";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[88] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::entity_specification() {QCString s,s1;if (!hasError) {
+
+ s = entity_name_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = entity_class();
+ }
+
+return s+":"+s1;
+assert(false);
+ }
+
+
+void VhdlParser::entity_statement() {
+ if (jj_2_35(2147483647)) {if (!hasError) {
+
+ concurrent_assertion_statement();
+ }
+
+ } else if (jj_2_36(2147483647)) {if (!hasError) {
+
+ process_statement();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ concurrent_procedure_call_statement();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[89] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::entity_statement_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case POSTPONED_T:
+ case PROCESS_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[90] = jj_gen;
+ goto end_label_18;
+ }if (!hasError) {
+
+ entity_statement();
+ }
+
+ }
+ end_label_18: ;
+ }
+
+ }
+
+
+QCString VhdlParser::entity_tag() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ s = character_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[91] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::enumeration_literal() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ s = character_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[92] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::enumeration_type_definition() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s = enumeration_literal();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[93] = jj_gen;
+ goto end_label_19;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = enumeration_literal();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_19: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return "("+s+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::exit_statement() {QCString s,s1,s2;Token *t=0;Token *t1=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[94] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(EXIT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s1 = identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[95] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{if (!hasError) {
+
+ t1 = jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ s2 = condition();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[96] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+lab.resize(0);
+ if(t) s+=":";
+ if(t1) s2.prepend(" when ");
+ FlowChart::addFlowChart(FlowChart::EXIT_NO,"exit",s2.data(),s1.data());
+
+ return s+s1+s2+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::expression() {QCString s,s1,s2;if (!hasError) {
+
+ s = relation();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case AND_T:
+ case NAND_T:
+ case NOR_T:
+ case OR_T:
+ case XOR_T:
+ case XNOR_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[97] = jj_gen;
+ goto end_label_20;
+ }if (!hasError) {
+
+ s1 = logop();
+ }
+ if (!hasError) {
+
+ s2 = relation();
+ }
+ if (!hasError) {
+
+s+=s1;s+=s2;
+ }
+
+ }
+ end_label_20: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::logop() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case AND_T:{if (!hasError) {
+
+ jj_consume_token(AND_T);
+ }
+ if (!hasError) {
+
+return "and" ;
+ }
+
+ break;
+ }
+ case NAND_T:{if (!hasError) {
+
+ jj_consume_token(NAND_T);
+ }
+ if (!hasError) {
+
+return "nand" ;
+ }
+
+ break;
+ }
+ case NOR_T:{if (!hasError) {
+
+ jj_consume_token(NOR_T);
+ }
+ if (!hasError) {
+
+return "nor" ;
+ }
+
+ break;
+ }
+ case XNOR_T:{if (!hasError) {
+
+ jj_consume_token(XNOR_T);
+ }
+ if (!hasError) {
+
+return "xnor" ;
+ }
+
+ break;
+ }
+ case XOR_T:{if (!hasError) {
+
+ jj_consume_token(XOR_T);
+ }
+ if (!hasError) {
+
+return "xor" ;
+ }
+
+ break;
+ }
+ case OR_T:{if (!hasError) {
+
+ jj_consume_token(OR_T);
+ }
+ if (!hasError) {
+
+return "or" ;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[98] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::extended_identifier() {Token *t;if (!hasError) {
+
+ t = jj_consume_token(EXTENDED_CHARACTER);
+ }
+
+return t->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::factor() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case NEW_T:
+ case NULL_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case INTEGER:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:
+ case BIT_STRING_LITERAL:{if (!hasError) {
+
+ s = primary();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case DOUBLEMULT_T:{if (!hasError) {
+
+ jj_consume_token(DOUBLEMULT_T);
+ }
+ if (!hasError) {
+
+ s1 = primary();
+ }
+ if (!hasError) {
+
+s+="**";s+=s1;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[99] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ABS_T:{if (!hasError) {
+
+ jj_consume_token(ABS_T);
+ }
+ if (!hasError) {
+
+ s = primary();
+ }
+ if (!hasError) {
+
+s1 = "abs "; return s1+s;
+ }
+
+ break;
+ }
+ case NOT_T:{if (!hasError) {
+
+ jj_consume_token(NOT_T);
+ }
+ if (!hasError) {
+
+ s = primary();
+ }
+ if (!hasError) {
+
+s1="not ";return s1+s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[100] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::file_declaration() {QCString s,s1,s2,s3;if (!hasError) {
+
+ jj_consume_token(FILE_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s2 = subtype_indication();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:
+ case OPEN_T:{if (!hasError) {
+
+ s3 = file_open_information();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[101] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QCString t1=s2+" "+s3;
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,t1.data(),Public);
+ return " file "+s+":"+s2+" "+s3+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::file_logical_name() {QCString s;if (!hasError) {
+
+ s = expression();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::file_open_information() {QCString s,s1,s2;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case OPEN_T:{if (!hasError) {
+
+ jj_consume_token(OPEN_T);
+ }
+ if (!hasError) {
+
+ s = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[102] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ s1 = file_logical_name();
+ }
+
+s2="open "+s+" is "+s1; return s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::file_type_definition() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(FILE_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s = type_mark();
+ }
+
+s1=" file of "+s; return s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::floating_type_definition() {QCString s;if (!hasError) {
+
+ s = range_constraint();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::formal_designator() {QCString s;Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case INTEGER:{if (!hasError) {
+
+ tok = jj_consume_token(INTEGER);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[103] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::formal_parameter_list() {QCString s;if (!hasError) {
+
+ s = interface_list();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::formal_part() {QCString s,s1;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ formal_designator();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+"("+s1+")";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[104] = jj_gen;
+ ;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::full_type_declaration() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(TYPE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ try {if (!hasError) {
+
+ s2 = type_definition();
+ }
+
+ } catch ( ...) {
+error_skipto(SEMI_T);
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+addVhdlType(s.data(),getLine(TYPE_T),Entry::VARIABLE_SEC,VhdlDocGen::TYPE,0,s2.data(),Public);
+ return "type "+s+" is "+s2+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::function_call() {QCString s,s1;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = actual_parameter_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return s+"("+s1+")";
+assert(false);
+ }
+
+
+void VhdlParser::generate_statement() {QCString s;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ try {if (!hasError) {
+
+ generate_scheme();
+ }
+ if (!hasError) {
+
+ jj_consume_token(GENERATE_T);
+ }
+ if (!hasError) {
+
+pushLabel(genLabels,s);
+ }
+ if (!hasError) {
+
+ generate_statement_body1();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+
+ } catch ( ...) {
+error_skipto(GENERATE_T);
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(GENERATE_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[105] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+genLabels=popLabel(genLabels);
+ }
+
+
+void VhdlParser::generate_scheme() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:{if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ parameter_specification();
+ }
+
+ break;
+ }
+ case IF_T:{if (!hasError) {
+
+ jj_consume_token(IF_T);
+ }
+ if (!hasError) {
+
+ condition();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[106] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::generic_clause() {QCString s;if (!hasError) {
+
+ jj_consume_token(GENERIC_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+parse_sec=GEN_SEC;
+ }
+ if (!hasError) {
+
+ s = generic_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+parse_sec=0;
+ }
+
+
+QCString VhdlParser::generic_list() {QCString s;if (!hasError) {
+
+ s = interface_list();
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::generic_map_aspect() {if (!hasError) {
+
+ jj_consume_token(GENERIC_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(MAP_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ association_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ }
+
+
+QCString VhdlParser::group_constituent() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ s = character_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[107] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::group_constituent_list() {QCString s,s1,s2;if (!hasError) {
+ if (!hasError) {
+
+ s1 = group_constituent();
+ }
+
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[108] = jj_gen;
+ goto end_label_21;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s = group_constituent();
+ }
+ if (!hasError) {
+
+s2+=",";s2+=s1;
+ }
+
+ }
+ end_label_21: ;
+ }
+
+return s+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::group_declaration() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(GROUP_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s2 = group_constituent_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return "group "+s+":"+s1+"("+s2+");";
+assert(false);
+ }
+
+
+QCString VhdlParser::group_template_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(GROUP_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = entity_class_entry_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return "group "+s+ "is ("+s1+");";
+assert(false);
+ }
+
+
+void VhdlParser::guarded_signal_specification() {if (!hasError) {
+
+ signal_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ type_mark();
+ }
+
+ }
+
+
+QCString VhdlParser::identifier() {Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ tok = jj_consume_token(EXTENDED_CHARACTER);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case BASIC_IDENTIFIER:{if (!hasError) {
+
+ tok = jj_consume_token(BASIC_IDENTIFIER);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[109] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::identifier_list() {QCString str,str1;if (!hasError) {
+
+ str = identifier();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[110] = jj_gen;
+ goto end_label_22;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ str1 = identifier();
+ }
+ if (!hasError) {
+
+str+=",";str+=str1;
+ }
+
+ }
+ end_label_22: ;
+ }
+
+return str;
+assert(false);
+ }
+
+
+void VhdlParser::if_statement() {QCString s,s1;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[111] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(IF_T);
+ }
+ if (!hasError) {
+
+ s = condition();
+ }
+ if (!hasError) {
+
+ jj_consume_token(THEN_T);
+ }
+ if (!hasError) {
+
+s.prepend("if ");
+ FlowChart::addFlowChart(FlowChart::IF_NO,0,s);
+ }
+ if (!hasError) {
+
+ sequence_of_statement();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ELSIF_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[112] = jj_gen;
+ goto end_label_23;
+ }if (!hasError) {
+
+ jj_consume_token(ELSIF_T);
+ }
+ if (!hasError) {
+
+ s1 = condition();
+ }
+ if (!hasError) {
+
+ jj_consume_token(THEN_T);
+ }
+ if (!hasError) {
+
+s1.prepend("elsif ");
+ FlowChart::addFlowChart(FlowChart::ELSIF_NO,0,s1.data());
+ }
+ if (!hasError) {
+
+ sequence_of_statement();
+ }
+
+ }
+ end_label_23: ;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ELSE_T:{if (!hasError) {
+
+ jj_consume_token(ELSE_T);
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::ELSE_NO,0,0);
+ }
+ if (!hasError) {
+
+ sequence_of_statement();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[113] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(IF_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[114] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::ENDIF_NO,0,0);
+ }
+
+
+QCString VhdlParser::incomplete_type_declaration() {QCString s;if (!hasError) {
+
+ jj_consume_token(TYPE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return "type "+s+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::index_constraint() {QCString s="("; QCString s1,s2;if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s2 = discrete_range();
+ }
+ if (!hasError) {
+
+s+=s2;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[115] = jj_gen;
+ goto end_label_24;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = discrete_range();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_24: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return s+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::index_specification() {QCString s;
+ if (jj_2_37(2147483647)) {if (!hasError) {
+
+ s = discrete_range();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ABS_T:
+ case NEW_T:
+ case NOT_T:
+ case NULL_T:
+ case LPAREN_T:
+ case PLUS_T:
+ case MINUS_T:
+ case SLSL_T:
+ case INTEGER:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:
+ case BIT_STRING_LITERAL:{if (!hasError) {
+
+ s = expression();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[116] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::index_subtype_definition() {QCString s;if (!hasError) {
+
+ s = type_mark();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RANGE_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BOX_T);
+ }
+
+return s+" range <> ";
+assert(false);
+ }
+
+
+QCString VhdlParser::instantiation_unit() {QCString s,s1,s2;Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMPONENT_T:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMPONENT_T:{if (!hasError) {
+
+ tok = jj_consume_token(COMPONENT_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[117] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+s1="component"; return s;
+ }
+
+ break;
+ }
+ case ENTITY_T:{if (!hasError) {
+
+ tok = jj_consume_token(ENTITY_T);
+ }
+ if (!hasError) {
+
+ s2 = name();
+ }
+ if (!hasError) {
+
+s=tok->image.c_str()+s2;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="(";s+=s1;s+=")" ;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[118] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONFIGURATION_T:{if (!hasError) {
+
+ jj_consume_token(CONFIGURATION_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+s1="configuration ";return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[119] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::instantiation_list() {QCString s;Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case OTHER_T:{if (!hasError) {
+
+ tok = jj_consume_token(OTHER_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case ALL_T:{if (!hasError) {
+
+ tok = jj_consume_token(ALL_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[120] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::integer() {Token *t;if (!hasError) {
+
+ t = jj_consume_token(INTEGER);
+ }
+
+return t->image.c_str();
+assert(false);
+ }
+
+
+QCString VhdlParser::integer_type_definition() {QCString s;if (!hasError) {
+
+ s = range_constraint();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::interface_declaration() {QCString s,s1;
+ if (jj_2_38(5)) {if (!hasError) {
+
+ s = interface_subprogram_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ interface_package_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[121] = jj_gen;
+ if (jj_2_39(5)) {if (!hasError) {
+
+ s = interface_variable_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_40(5)) {if (!hasError) {
+
+ interface_file_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_41(2147483647)) {if (!hasError) {
+
+ subprogram_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONSTANT_T:
+ case FILE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case TYPE_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ s = object_class();
+ }
+ if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+if (parse_sec==GEN_SEC)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,s1.data(),0,Public);
+ return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[122] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::interface_element() {QCString s;if (!hasError) {
+
+ s = interface_declaration();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::interface_file_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(FILE_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+
+addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,s1.data(),Public);
+ return " file "+s+":"+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::interface_list() {QCString s,s1,s2;if (!hasError) {
+
+ s = interface_element();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SEMI_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[123] = jj_gen;
+ goto end_label_25;
+ }if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+ if (!hasError) {
+
+ s1 = interface_element();
+ }
+ if (!hasError) {
+
+s2+=";";s2+=s1;
+ }
+
+ }
+ end_label_25: ;
+ }
+
+return s+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::interface_variable_declaration() {Token *tok=0;Token *tok1=0;Token *tok2=0;QCString s,s1,s2,s3,s4,s5;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONSTANT_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VARIABLE_T:{if (!hasError) {
+
+ tok = jj_consume_token(VARIABLE_T);
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ tok = jj_consume_token(SIGNAL_T);
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ tok = jj_consume_token(CONSTANT_T);
+ }
+
+ break;
+ }
+ case SHARED_T:{if (!hasError) {
+
+ tok = jj_consume_token(SHARED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[124] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+ break;
+ }
+ default:
+ jj_la1[125] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BUFFER_T:
+ case IN_T:
+ case INOUT_T:
+ case LINKAGE_T:
+ case OUT_T:{if (!hasError) {
+
+ s1 = mode();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[126] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s2 = subtype_indication();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BUS_T:{if (!hasError) {
+
+ tok1 = jj_consume_token(BUS_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[127] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VARASSIGN_T:{if (!hasError) {
+
+ tok2 = jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ s4 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[128] = jj_gen;
+ ;
+ }
+ }
+
+if(tok)
+ s5=tok->image.c_str();
+
+ if(tok1)
+ s3=tok->image.data();
+
+ if(tok2)
+ s3+=":=";
+
+ QCString it=s+":"+s1+" "+s2+" "+s3+" "+s4;
+ if (currP!=VhdlDocGen::COMPONENT)
+ {
+ if (currP==VhdlDocGen::FUNCTION || currP==VhdlDocGen::PROCEDURE)
+ {
+ addProto(s5.data(),s.data(),s1.data(),s2.data(),s3.data(),s4.data());
+ }
+ else
+ {
+ QCString i=s2+s3+s4;
+ if (currP==VhdlDocGen::GENERIC && param_sec==0)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,i.data(),s1.data(),Public);
+ else if(parse_sec != GEN_SEC)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,i.data(),s1.data(),Public);
+ }
+ // fprintf(stderr,"\n\n <<port %s >>\n",$$.data());
+ } // if component
+ return it;
+assert(false);
+ }
+
+
+QCString VhdlParser::iteration_scheme() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHILE_T:{if (!hasError) {
+
+ jj_consume_token(WHILE_T);
+ }
+ if (!hasError) {
+
+ s = condition();
+ }
+ if (!hasError) {
+
+s.prepend("while ");
+ FlowChart::addFlowChart(FlowChart::WHILE_NO,0,s.data(),lab.data());
+ lab="";
+ return s;
+ }
+
+ break;
+ }
+ case FOR_T:{if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ s = parameter_specification();
+ }
+ if (!hasError) {
+
+QCString q=lab+" for "+s;
+ FlowChart::addFlowChart(FlowChart::FOR_NO,0,q.data(),lab.data());
+ lab="";
+ return q;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[129] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::label() {QCString s;if (!hasError) {
+
+ s = identifier();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::library_clause() {QCString s;if (!hasError) {
+ if (!hasError) {
+
+ jj_consume_token(LIBRARY_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
+ {
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,s.data(),"_library_",Public);
+ }
+ QCString s1="library "+s;
+ return s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::library_unit() {QCString s;
+ if (jj_2_42(2)) {if (!hasError) {
+
+ primary_unit();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARCHITECTURE_T:
+ case PACKAGE_T:{if (!hasError) {
+
+ secondary_unit();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONTEXT_T:{if (!hasError) {
+
+ context_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[130] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::literal() {QCString s;
+ if (jj_2_43(2147483647)) {if (!hasError) {
+
+ s = bit_string_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_44(2147483647)) {if (!hasError) {
+
+ s = numeric_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_45(2147483647)) {if (!hasError) {
+
+ s = enumeration_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case STRINGLITERAL:{if (!hasError) {
+
+ s = string_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case NULL_T:{if (!hasError) {
+
+ jj_consume_token(NULL_T);
+ }
+ if (!hasError) {
+
+return "null";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[131] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::logical_operator() {QCString s;if (!hasError) {
+
+ s = logop();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::loop_statement() {QCString s,s1,s2,s3;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[132] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:
+ case WHILE_T:{if (!hasError) {
+
+ s1 = iteration_scheme();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[133] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+if(s1.isEmpty())
+ FlowChart::addFlowChart(FlowChart::LOOP_NO,0,"infinite");
+ }
+ if (!hasError) {
+
+ jj_consume_token(LOOP_T);
+ }
+ if (!hasError) {
+
+ s2 = sequence_of_statement();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LOOP_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s3 = identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[134] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QCString q = s+" loop "+s2+" end loop" +s3;
+ QCString endLoop="end loop" + s3;
+ FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::END_LOOP,endLoop.data(),0);
+ return q;
+assert(false);
+ }
+
+
+QCString VhdlParser::miscellaneous_operator() {Token *t=0;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case DOUBLEMULT_T:{if (!hasError) {
+
+ jj_consume_token(DOUBLEMULT_T);
+ }
+ if (!hasError) {
+
+return "**";
+ }
+
+ break;
+ }
+ case ABS_T:{if (!hasError) {
+
+ jj_consume_token(ABS_T);
+ }
+ if (!hasError) {
+
+return "abs";
+ }
+
+ break;
+ }
+ case NOT_T:{if (!hasError) {
+
+ jj_consume_token(NOT_T);
+ }
+ if (!hasError) {
+
+return "not";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[135] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::mode() {Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IN_T:{if (!hasError) {
+
+ tok = jj_consume_token(IN_T);
+ }
+ if (!hasError) {
+
+return "in";
+ }
+
+ break;
+ }
+ case OUT_T:{if (!hasError) {
+
+ tok = jj_consume_token(OUT_T);
+ }
+ if (!hasError) {
+
+return "out";
+ }
+
+ break;
+ }
+ case INOUT_T:{if (!hasError) {
+
+ tok = jj_consume_token(INOUT_T);
+ }
+ if (!hasError) {
+
+return "inout";
+ }
+
+ break;
+ }
+ case BUFFER_T:{if (!hasError) {
+
+ tok = jj_consume_token(BUFFER_T);
+ }
+ if (!hasError) {
+
+return "buffer";
+ }
+
+ break;
+ }
+ case LINKAGE_T:{if (!hasError) {
+
+ tok = jj_consume_token(LINKAGE_T);
+ }
+ if (!hasError) {
+
+return "linkage";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[136] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::multiplying_operation() {Token *tok;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case MULT_T:{if (!hasError) {
+
+ tok = jj_consume_token(MULT_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case SLASH_T:{if (!hasError) {
+
+ tok = jj_consume_token(SLASH_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case MOD_T:{if (!hasError) {
+
+ tok = jj_consume_token(MOD_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ case REM_T:{if (!hasError) {
+
+ tok = jj_consume_token(REM_T);
+ }
+ if (!hasError) {
+
+return tok->image.c_str();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[137] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::name() {QCString s,s1;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case STRINGLITERAL:{if (!hasError) {
+
+ s = operator_symbol();
+ }
+
+ break;
+ }
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+
+ break;
+ }
+ case SLSL_T:{if (!hasError) {
+
+ s = external_name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[138] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ if (!hasError) {
+
+ if (jj_2_46(2147483647)) {if (!hasError) {
+
+ s1 = name_ext1();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ } else {
+ ;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::name_ext1() {QCString s,s1,s2;if (!hasError) {
+
+ s = name_ext();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_47(2147483647)) {
+ ;
+ } else {
+ goto end_label_26;
+ }if (!hasError) {
+
+ s1 = name_ext();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ }
+ end_label_26: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::name_ext() {QCString s,s1,s2;if (!hasError) {
+
+ if (jj_2_48(2147483647)) {if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+ s1 = suffix();
+ }
+ if (!hasError) {
+
+s+=".";s+=s1;
+ }
+
+ } else if (jj_2_49(2147483647)) {if (!hasError) {
+
+ s1 = test_att_name();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ } else if (jj_2_50(2147483647)) {if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = discrete_range();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="(";s+=s1;s+=")";
+ }
+
+ } else if (jj_2_51(2147483647)) {if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+s+="(";s+=s1;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[139] = jj_gen;
+ goto end_label_27;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_27: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+=")";
+ }
+
+ } else {
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::test_att_name() {QCString s,s1;if (!hasError) {
+
+ if (jj_2_52(2147483647)) {if (!hasError) {
+
+ s1 = signature();
+ }
+ if (!hasError) {
+
+s=s1;
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(APOSTROPHE_T);
+ }
+ if (!hasError) {
+
+ s1 = attribute_designator();
+ }
+ if (!hasError) {
+
+s+="'";s+=s1;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="(";s+=s1;s+=")";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[140] = jj_gen;
+ ;
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::indexed_name() {QCString s,s1,s2;if (!hasError) {
+
+ s2 = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+s=s2+"("+s1;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[141] = jj_gen;
+ goto end_label_28;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_28: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return s+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::next_statement() {QCString s,s1,s2;Token *t=0;Token *t1=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[142] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(NEXT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s1 = identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[143] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{if (!hasError) {
+
+ t1 = jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ s2 = condition();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[144] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(t) s+=":";
+ FlowChart::addFlowChart(FlowChart::NEXT_NO,"next ",s2.data(),s1.data());
+ lab.resize(0);
+ if(t1) s2.prepend("when ");
+ return s+s1+s2+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::null_statement() {QCString s;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[145] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(NULL_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return s+="null";
+assert(false);
+ }
+
+
+QCString VhdlParser::numeric_literal() {QCString s;
+ if (jj_2_53(2147483647)) {if (!hasError) {
+
+ s = physical_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case INTEGER:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:{if (!hasError) {
+
+ s = abstract_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[146] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::object_class() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONSTANT_T:{if (!hasError) {
+
+ jj_consume_token(CONSTANT_T);
+ }
+ if (!hasError) {
+
+return "constant";
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ jj_consume_token(SIGNAL_T);
+ }
+ if (!hasError) {
+
+return "signal";
+ }
+
+ break;
+ }
+ case VARIABLE_T:{if (!hasError) {
+
+ jj_consume_token(VARIABLE_T);
+ }
+ if (!hasError) {
+
+return "variable";
+ }
+
+ break;
+ }
+ case SHARED_T:{if (!hasError) {
+
+ jj_consume_token(SHARED_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(VARIABLE_T);
+ }
+ if (!hasError) {
+
+return "shared variable";
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ jj_consume_token(FILE_T);
+ }
+ if (!hasError) {
+
+return "file";
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ jj_consume_token(TYPE_T);
+ }
+ if (!hasError) {
+
+return "type";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[147] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::operator_symbol() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(STRINGLITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+void VhdlParser::options() {if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GUARDED_T:{if (!hasError) {
+
+ jj_consume_token(GUARDED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[148] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case INERTIAL_T:
+ case REJECT_T:
+ case TRANSPORT_T:{if (!hasError) {
+
+ delay_mechanism();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[149] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::package_body() {QCString s;if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BODY_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+lastCompound=current;
+ s.prepend("_");
+ addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE_BODY,0,0,Protected);
+ }
+ if (!hasError) {
+
+ package_body_declarative_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BODY_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[150] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[151] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+lastCompound=0; genLabels.resize(0);
+ }
+
+
+void VhdlParser::package_body_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ type_declaration();
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ subtype_declaration();
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ constant_declaration();
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ variable_declaration();
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ file_declaration();
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ alias_declaration();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[152] = jj_gen;
+ if (jj_2_54(3)) {if (!hasError) {
+
+ group_template_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[153] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+
+
+void VhdlParser::package_body_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case CONSTANT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[154] = jj_gen;
+ goto end_label_29;
+ }if (!hasError) {
+
+ package_body_declarative_item();
+ }
+
+ }
+ end_label_29: ;
+ }
+
+ }
+
+
+void VhdlParser::package_declaration() {QCString s;if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+lastCompound=current;
+ Entry *clone=new Entry(*current);
+ clone->section=Entry::NAMESPACE_SEC;
+ clone->spec=VhdlDocGen::PACKAGE;
+ clone->name=s;
+ clone->startLine=getLine();
+ clone->bodyLine=getLine();
+ clone->protection=Package;
+ current_root->addSubEntry(clone);
+ addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE,0,0,Package);
+ }
+ if (!hasError) {
+
+ package_declarative_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[155] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[156] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+lastEntity=0;lastCompound=0; genLabels.resize(0);
+ }
+
+
+void VhdlParser::geninter() {if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ gen_interface_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ gen_assoc_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[157] = jj_gen;
+ ;
+ }
+ }
+
+ break;
+ }
+ default:
+ jj_la1[158] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::package_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ type_declaration();
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ subtype_declaration();
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ constant_declaration();
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ signal_declaration();
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ variable_declaration();
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ file_declaration();
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ alias_declaration();
+ }
+
+ break;
+ }
+ case COMPONENT_T:{if (!hasError) {
+
+ component_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[159] = jj_gen;
+ if (jj_2_55(2147483647)) {if (!hasError) {
+
+ attribute_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case DISCONNECT_T:{if (!hasError) {
+
+ disconnection_specification();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[160] = jj_gen;
+ if (jj_2_56(3)) {if (!hasError) {
+
+ group_template_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[161] = jj_gen;
+ if (jj_2_57(5)) {if (!hasError) {
+
+ package_instantiation_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ package_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[162] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+void VhdlParser::package_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case COMPONENT_T:
+ case CONSTANT_T:
+ case DISCONNECT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PACKAGE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[163] = jj_gen;
+ goto end_label_30;
+ }if (!hasError) {
+
+ package_declarative_item();
+ }
+
+ }
+ end_label_30: ;
+ }
+
+ }
+
+
+QCString VhdlParser::parameter_specification() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IN_T);
+ }
+ if (!hasError) {
+
+ s1 = discrete_range();
+ }
+
+return s+" in "+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::physical_literal() {QCString s,s1;if (!hasError) {
+
+ if (jj_2_58(2147483647)) {if (!hasError) {
+
+ s = abstract_literal();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+
+s+=" ";s+=s1;s.prepend(" "); return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::physical_type_definition() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(UNITS_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[164] = jj_gen;
+ goto end_label_31;
+ }if (!hasError) {
+
+ s1 = secondary_unit_declaration();
+ }
+ if (!hasError) {
+
+s2+=s1;s2+="#";
+ }
+
+ }
+ end_label_31: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(UNITS_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[165] = jj_gen;
+ ;
+ }
+ }
+
+current->args=s2;
+ current->args.prepend("units");
+ current->spec=VhdlDocGen::UNITS;
+ return s2;
+assert(false);
+ }
+
+
+void VhdlParser::port_clause() {if (!hasError) {
+
+ jj_consume_token(PORT_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ port_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+currP=0;
+ }
+
+
+QCString VhdlParser::port_list() {QCString s;if (!hasError) {
+
+ s = interface_list();
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::port_map_aspect() {if (!hasError) {
+
+ jj_consume_token(PORT_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(MAP_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ association_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ }
+
+
+QCString VhdlParser::primary() {QCString s,s1;
+ if (jj_2_59(2147483647)) {if (!hasError) {
+
+ s = function_call();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_60(2147483647)) {if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s="("+s1+")"; return s;
+ }
+
+ } else if (jj_2_61(2147483647)) {if (!hasError) {
+
+ s = qualified_expression();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_62(2147483647)) {if (!hasError) {
+
+ s = type_conversion();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_63(2147483647)) {if (!hasError) {
+
+ s = literal();
+ }
+ if (!hasError) {
+
+s.prepend(" ");return s;
+ }
+
+ } else if (jj_2_64(2147483647)) {if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case NEW_T:{if (!hasError) {
+
+ allocator();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ case LPAREN_T:{if (!hasError) {
+
+ s = aggregate();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[166] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+void VhdlParser::primary_unit() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ENTITY_T:{if (!hasError) {
+
+ entity_declaration();
+ }
+
+ break;
+ }
+ case CONFIGURATION_T:{if (!hasError) {
+
+ configuration_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[167] = jj_gen;
+ if (jj_2_65(2147483647)) {if (!hasError) {
+
+ package_instantiation_declaration();
+ }
+
+ } else if (jj_2_66(4)) {if (!hasError) {
+
+ interface_package_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PACKAGE_T:{if (!hasError) {
+
+ package_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[168] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+
+
+QCString VhdlParser::procedure_call() {QCString s,s1;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = actual_parameter_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s1.prepend("("); s1.append(")");
+ }
+
+ break;
+ }
+ default:
+ jj_la1[169] = jj_gen;
+ ;
+ }
+ }
+
+return s+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::procedure_call_statement() {QCString s,s1;if (!hasError) {
+
+ if (jj_2_67(2)) {if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = procedure_call();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return s+s1+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::process_declarative_item() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ s = type_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ s = subtype_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ s = constant_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ s = variable_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ s = file_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ s = alias_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[170] = jj_gen;
+ if (jj_2_68(3)) {if (!hasError) {
+
+ s = attribute_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ s = attribute_specification();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ s = use_clause();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[171] = jj_gen;
+ if (jj_2_69(3)) {if (!hasError) {
+
+ s = group_template_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ s = group_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[172] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::process_declarative_part() {QCString s,s1;if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case CONSTANT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[173] = jj_gen;
+ goto end_label_32;
+ }if (!hasError) {
+
+ s1 = process_declarative_item();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ }
+ end_label_32: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::process_statement() {QCString s,s1,s2;Token *tok=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[174] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:{if (!hasError) {
+
+ jj_consume_token(POSTPONED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[175] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+currP=VhdlDocGen::PROCESS;
+ current->startLine=getLine();
+ current->bodyLine=getLine();
+ }
+ if (!hasError) {
+
+ jj_consume_token(PROCESS_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALL_T:{if (!hasError) {
+
+ tok = jj_consume_token(ALL_T);
+ }
+
+ break;
+ }
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s1 = sensitivity_list();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[176] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[177] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:{if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[178] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s2 = process_declarative_part();
+ }
+ if (!hasError) {
+
+if (s2.data())
+ FlowChart::addFlowChart(FlowChart::VARIABLE_NO,s2.data(),0);
+ FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ process_statement_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:{if (!hasError) {
+
+ jj_consume_token(POSTPONED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[179] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(PROCESS_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[180] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(s.isEmpty())
+ currName=VhdlDocGen::getProcessNumber();
+ else
+ currName=s;
+
+ current->name=currName;
+ tempEntry=current;
+ current->endBodyLine=getLine();
+ currP=0;
+ if(tok)
+ s1=tok->image.data();
+ createFunction(currName,VhdlDocGen::PROCESS,s1.data());
+ createFlow();
+ currName="";
+ newEntry();
+ }
+
+
+void VhdlParser::process_statement_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case EXIT_T:
+ case FOR_T:
+ case IF_T:
+ case LOOP_T:
+ case NEXT_T:
+ case NULL_T:
+ case REPORT_T:
+ case RETURN_T:
+ case WAIT_T:
+ case WHILE_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[181] = jj_gen;
+ goto end_label_33;
+ }if (!hasError) {
+
+ sequential_statement();
+ }
+
+ }
+ end_label_33: ;
+ }
+
+ }
+
+
+QCString VhdlParser::qualified_expression() {QCString s,s1;if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(APOSTROPHE_T);
+ }
+ if (!hasError) {
+
+s=s1+"'";
+ }
+ if (!hasError) {
+
+ if (jj_2_70(2147483647)) {if (!hasError) {
+
+ s1 = aggregate();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+s+="(";s+=s1;s+=")";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[182] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::range() {QCString s,s1,s2;
+ if (jj_2_71(2147483647)) {if (!hasError) {
+
+ s = simple_expression();
+ }
+ if (!hasError) {
+
+ s1 = direction();
+ }
+ if (!hasError) {
+
+ s2 = simple_expression();
+ }
+ if (!hasError) {
+
+return s+" "+s1+" "+s2;
+ }
+
+ } else if (jj_2_72(2147483647)) {if (!hasError) {
+
+ s = attribute_name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::range_constraint() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(RANGE_T);
+ }
+ if (!hasError) {
+
+ s = range();
+ }
+
+return " range "+s;
+assert(false);
+ }
+
+
+void VhdlParser::record_type_definition() {if (!hasError) {
+
+ jj_consume_token(RECORD_T);
+ }
+ if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ element_declaration();
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[183] = jj_gen;
+ goto end_label_34;
+ }
+ }
+ end_label_34: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(RECORD_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[184] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+QCString VhdlParser::relation() {QCString s,s1,s2;if (!hasError) {
+
+ s = shift_expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LESSTHAN_T:
+ case GREATERTHAN_T:
+ case LT_T:
+ case GT_T:
+ case EQU_T:
+ case NOTEQU_T:{if (!hasError) {
+
+ s1 = relation_operator();
+ }
+ if (!hasError) {
+
+ s2 = shift_expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[185] = jj_gen;
+ ;
+ }
+ }
+
+return s+s1+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::relation_operator() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LT_T:{if (!hasError) {
+
+ jj_consume_token(LT_T);
+ }
+ if (!hasError) {
+
+return "<";
+ }
+
+ break;
+ }
+ case GT_T:{if (!hasError) {
+
+ jj_consume_token(GT_T);
+ }
+ if (!hasError) {
+
+return ">";
+ }
+
+ break;
+ }
+ case EQU_T:{if (!hasError) {
+
+ jj_consume_token(EQU_T);
+ }
+ if (!hasError) {
+
+return "=";
+ }
+
+ break;
+ }
+ case GREATERTHAN_T:{if (!hasError) {
+
+ jj_consume_token(GREATERTHAN_T);
+ }
+ if (!hasError) {
+
+return ">=";
+ }
+
+ break;
+ }
+ case LESSTHAN_T:{if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+return "<=";
+ }
+
+ break;
+ }
+ case NOTEQU_T:{if (!hasError) {
+
+ jj_consume_token(NOTEQU_T);
+ }
+ if (!hasError) {
+
+return "/=";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[186] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::report_statement() {Token *t=0;Token *t1=0;QCString s,s1,s2;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[187] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(REPORT_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SEVERITY_T:{if (!hasError) {
+
+ t1 = jj_consume_token(SEVERITY_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[188] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(t) s.append(":");
+ s1.prepend(" report ");
+ if(t1) s2.prepend(" severity ");
+ return s+s1+s2+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::return_statement() {QCString s,s1;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[189] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(RETURN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ABS_T:
+ case NEW_T:
+ case NOT_T:
+ case NULL_T:
+ case LPAREN_T:
+ case PLUS_T:
+ case MINUS_T:
+ case SLSL_T:
+ case INTEGER:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:
+ case BIT_STRING_LITERAL:{if (!hasError) {
+
+ s1 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[190] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return s+" return "+s1+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::scalar_type_definition() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ s = enumeration_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case RANGE_T:{if (!hasError) {
+
+ s = range_constraint();
+ }
+ if (!hasError) {
+
+ if (jj_2_73(2147483647)) {if (!hasError) {
+
+ s1 = physical_type_definition();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+s+=" ";s+=s1;return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[191] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::secondary_unit() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ARCHITECTURE_T:{if (!hasError) {
+
+ architecture_body();
+ }
+
+ break;
+ }
+ case PACKAGE_T:{if (!hasError) {
+
+ package_body();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[192] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+QCString VhdlParser::secondary_unit_declaration() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(EQU_T);
+ }
+ if (!hasError) {
+
+ s1 = physical_literal();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return s+"="+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::selected_name() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+ s1 = suffix();
+ }
+
+return s+"."+s1;
+assert(false);
+ }
+
+
+void VhdlParser::selected_signal_assignment() {if (!hasError) {
+
+ jj_consume_token(WITH_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SELECT_T);
+ }
+ if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ options();
+ }
+ if (!hasError) {
+
+ selected_waveforms();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::selected_waveforms() {if (!hasError) {
+
+ waveform();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ choices();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[193] = jj_gen;
+ goto end_label_35;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ waveform();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ choices();
+ }
+
+ }
+ end_label_35: ;
+ }
+
+ }
+
+
+QCString VhdlParser::sensitivity_clause() {QCString s;if (!hasError) {
+
+ jj_consume_token(ON_T);
+ }
+ if (!hasError) {
+
+ s = sensitivity_list();
+ }
+
+s.prepend(" on ");
+ return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::sensitivity_list() {QCString s,s1;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[194] = jj_gen;
+ goto end_label_36;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_36: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::sequence_of_statement() {QCString s,s1;if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_74(3)) {
+ ;
+ } else {
+ goto end_label_37;
+ }if (!hasError) {
+
+ s1 = sequential_statement();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ }
+ end_label_37: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::sequential_statement() {QCString s;
+ if (jj_2_75(2147483647)) {if (!hasError) {
+
+ s = signal_assignment_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_76(3)) {if (!hasError) {
+
+ s = assertion_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_77(3)) {if (!hasError) {
+
+ s = report_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_78(3)) {if (!hasError) {
+
+ s = wait_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_79(2147483647)) {if (!hasError) {
+
+ s = variable_assignment_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_80(3)) {if (!hasError) {
+
+ s = procedure_call_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ } else if (jj_2_81(3)) {if (!hasError) {
+
+ if_statement();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_82(3)) {if (!hasError) {
+
+ case_statement();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_83(3)) {if (!hasError) {
+
+ loop_statement();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_84(3)) {if (!hasError) {
+
+ s = next_statement();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_85(3)) {if (!hasError) {
+
+ s = exit_statement();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else if (jj_2_86(3)) {if (!hasError) {
+
+ s = return_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::RETURN_NO,s.data(),0);return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case NULL_T:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = null_statement();
+ }
+ if (!hasError) {
+
+FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[195] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::shift_expression() {QCString s,s1,s2;if (!hasError) {
+
+ s = simple_expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ROL_T:
+ case ROR_T:
+ case SLA_T:
+ case SLL_T:
+ case SRA_T:
+ case SRL_T:{if (!hasError) {
+
+ s1 = shift_operator();
+ }
+ if (!hasError) {
+
+ s2 = simple_expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[196] = jj_gen;
+ ;
+ }
+ }
+
+return s+s1+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::shift_operator() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLL_T:{if (!hasError) {
+
+ jj_consume_token(SLL_T);
+ }
+ if (!hasError) {
+
+return "sll";
+ }
+
+ break;
+ }
+ case SRL_T:{if (!hasError) {
+
+ jj_consume_token(SRL_T);
+ }
+ if (!hasError) {
+
+return "srl";
+ }
+
+ break;
+ }
+ case SLA_T:{if (!hasError) {
+
+ jj_consume_token(SLA_T);
+ }
+ if (!hasError) {
+
+return "sla";
+ }
+
+ break;
+ }
+ case SRA_T:{if (!hasError) {
+
+ jj_consume_token(SRA_T);
+ }
+ if (!hasError) {
+
+return "sra";
+ }
+
+ break;
+ }
+ case ROL_T:{if (!hasError) {
+
+ jj_consume_token(ROL_T);
+ }
+ if (!hasError) {
+
+return "rol";
+ }
+
+ break;
+ }
+ case ROR_T:{if (!hasError) {
+
+ jj_consume_token(ROR_T);
+ }
+ if (!hasError) {
+
+return "ror";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[197] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::sign() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PLUS_T:{if (!hasError) {
+
+ jj_consume_token(PLUS_T);
+ }
+ if (!hasError) {
+
+return "+";
+ }
+
+ break;
+ }
+ case MINUS_T:{if (!hasError) {
+
+ jj_consume_token(MINUS_T);
+ }
+ if (!hasError) {
+
+return "-";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[198] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::signal_assignment_statement() {QCString s,s1,s2,s3;
+ if (jj_2_88(2147483647)) {if (!hasError) {
+
+ conditional_signal_assignment_wave();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ } else if (jj_2_89(2147483647)) {if (!hasError) {
+
+ selected_signal_assignment_wave();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ if (jj_2_87(2)) {if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case INERTIAL_T:
+ case REJECT_T:
+ case TRANSPORT_T:{if (!hasError) {
+
+ s2 = delay_mechanism();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[199] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s3 = waveform();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+ if (!hasError) {
+
+return s+s1+"<="+s2+s3+";";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[200] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+void VhdlParser::semi() {if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::signal_declaration() {Token* tok=0;QCString s,s1,s2,s3,s4;if (!hasError) {
+
+ jj_consume_token(SIGNAL_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BUS_T:
+ case REGISTER_T:{if (!hasError) {
+
+ s2 = signal_kind();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[201] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VARASSIGN_T:{if (!hasError) {
+
+ tok = jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ s3 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[202] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(tok)
+ s3.prepend(":=");
+ s4=s1+s2+s3;
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::SIGNAL,0,s4.data(),Public);
+ }
+
+
+QCString VhdlParser::signal_kind() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case REGISTER_T:{if (!hasError) {
+
+ jj_consume_token(REGISTER_T);
+ }
+ if (!hasError) {
+
+return "register";
+ }
+
+ break;
+ }
+ case BUS_T:{if (!hasError) {
+
+ jj_consume_token(BUS_T);
+ }
+ if (!hasError) {
+
+return "bus";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[203] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::signal_list() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[204] = jj_gen;
+ goto end_label_38;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_38: ;
+ }
+
+ break;
+ }
+ case OTHER_T:{if (!hasError) {
+
+ jj_consume_token(OTHER_T);
+ }
+ if (!hasError) {
+
+return "other";
+ }
+
+ break;
+ }
+ case ALL_T:{if (!hasError) {
+
+ jj_consume_token(ALL_T);
+ }
+ if (!hasError) {
+
+return "all";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[205] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::signature() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(LBRACKET_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[206] = jj_gen;
+ goto end_label_39;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_39: ;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[207] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case RETURN_T:{if (!hasError) {
+
+ jj_consume_token(RETURN_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+s+="return ";s+=s1;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[208] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(RBRACKET_T);
+ }
+
+s1="["+s+"]";return s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::simple_expression() {QCString s,s1,s2;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PLUS_T:
+ case MINUS_T:{if (!hasError) {
+
+ s = sign();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[209] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = term();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_90(2147483647)) {
+ ;
+ } else {
+ goto end_label_40;
+ }if (!hasError) {
+
+ s1 = adding_operator();
+ }
+ if (!hasError) {
+
+ s2 = term();
+ }
+ if (!hasError) {
+
+s+=s1;s+=s2;
+ }
+
+ }
+ end_label_40: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::simple_name() {if (!hasError) {
+
+ name();
+ }
+
+ }
+
+
+QCString VhdlParser::slice_name() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = discrete_range();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return s+"("+s1+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::string_literal() {Token *tok;if (!hasError) {
+
+ tok = jj_consume_token(STRINGLITERAL);
+ }
+
+return tok->image.c_str();
+assert(false);
+ }
+
+
+void VhdlParser::subprogram_body() {QCString s;if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ //try{
+ s = subprogram_declarative_part();
+ }
+ if (!hasError) {
+
+if (s.data())
+ {
+ FlowChart::addFlowChart(FlowChart::VARIABLE_NO,s,0);
+ }
+ FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ subprogram_statement_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case PROCEDURE_T:{if (!hasError) {
+
+ subprogram_kind();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[210] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ designator();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[211] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+tempEntry->endBodyLine=getLine(END_T);
+ createFlow();
+ currP=0;
+ }
+
+
+void VhdlParser::subprogram_declaration() {
+ if (jj_2_91(2147483647)) {if (!hasError) {
+
+ subprogram_instantiation_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_specification();
+ }
+ if (!hasError) {
+
+ subprogram_1();
+ }
+ if (!hasError) {
+
+currP=0;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[212] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::subprogram_1() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:{if (!hasError) {
+
+ subprogram_body();
+ }
+
+ break;
+ }
+ case SEMI_T:{if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[213] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+QCString VhdlParser::subprogram_declarative_item() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ s = type_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case IS_T:{if (!hasError) {
+
+ subprogram_body();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ s = subtype_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ s = constant_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ s = variable_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ s = file_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ s = alias_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[214] = jj_gen;
+ if (jj_2_92(2147483647)) {if (!hasError) {
+
+ s = attribute_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ s = attribute_specification();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ s = use_clause();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[215] = jj_gen;
+ if (jj_2_93(3)) {if (!hasError) {
+
+ s = group_template_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ s = group_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[216] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::subprogram_declarative_part() {QCString s,s1;if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case CONSTANT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case IS_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[217] = jj_gen;
+ goto end_label_41;
+ }if (!hasError) {
+
+ s1 = subprogram_declarative_item();
+ }
+ if (!hasError) {
+
+s+=s1;
+ }
+
+ }
+ end_label_41: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+void VhdlParser::subprogram_kind() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:{if (!hasError) {
+
+ jj_consume_token(FUNCTION_T);
+ }
+
+ break;
+ }
+ case PROCEDURE_T:{if (!hasError) {
+
+ jj_consume_token(PROCEDURE_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[218] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::subprogram_specification() {QCString s;Token *tok=0;Token *t;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PROCEDURE_T:{if (!hasError) {
+
+ jj_consume_token(PROCEDURE_T);
+ }
+ if (!hasError) {
+
+ s = designator();
+ }
+ if (!hasError) {
+
+currP=VhdlDocGen::PROCEDURE;
+ createFunction(s.data(),currP,0);
+ tempEntry=current;
+ current->startLine=getLine(PROCEDURE_T);
+ current->bodyLine=getLine(PROCEDURE_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+param_sec=PARAM_SEC;
+ }
+ if (!hasError) {
+
+ interface_list();
+ }
+ if (!hasError) {
+
+param_sec=0;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[219] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ if (jj_2_94(2)) {if (!hasError) {
+
+ gen_interface_list();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ if (jj_2_95(2)) {if (!hasError) {
+
+ gen_assoc_list();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ param();
+ }
+ if (!hasError) {
+
+newEntry();
+ }
+
+ break;
+ }
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PURE_T:{if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IMPURE_T:
+ case PURE_T:{if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PURE_T:{if (!hasError) {
+
+ tok = jj_consume_token(PURE_T);
+ }
+
+ break;
+ }
+ case IMPURE_T:{if (!hasError) {
+
+ tok = jj_consume_token(IMPURE_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[220] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+ break;
+ }
+ default:
+ jj_la1[221] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(FUNCTION_T);
+ }
+ if (!hasError) {
+
+ s = designator();
+ }
+ if (!hasError) {
+
+currP=VhdlDocGen::FUNCTION;
+ if(tok)
+ createFunction(tok->image.c_str(),currP,s.data());
+ else
+ createFunction(0,currP,s.data());
+ tempEntry=current;
+ current->startLine=getLine(FUNCTION_T);
+ current->bodyLine=getLine(FUNCTION_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+param_sec=PARAM_SEC;
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ formal_parameter_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+param_sec=0;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[222] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(RETURN_T);
+ }
+ if (!hasError) {
+
+ s = type_mark();
+ }
+ if (!hasError) {
+
+tempEntry=current;
+ current->type=s;
+ newEntry();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[223] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::subprogram_statement_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case EXIT_T:
+ case FOR_T:
+ case IF_T:
+ case LOOP_T:
+ case NEXT_T:
+ case NULL_T:
+ case REPORT_T:
+ case RETURN_T:
+ case WAIT_T:
+ case WHILE_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[224] = jj_gen;
+ goto end_label_42;
+ }if (!hasError) {
+
+ sequential_statement();
+ }
+
+ }
+ end_label_42: ;
+ }
+
+ }
+
+
+QCString VhdlParser::subtype_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(SUBTYPE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::SUBTYPE,0,s1.data(),Public);
+ return " subtype "+s+" is "+s1+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::subtype_indication() {QCString s,s1,s2;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ if (jj_2_96(2147483647)) {if (!hasError) {
+
+ s1 = name();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ if (jj_2_97(2147483647)) {if (!hasError) {
+
+ s2 = constraint();
+ }
+
+ } else {
+ ;
+ }
+ }
+
+return s+" "+s1+" "+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::suffix() {QCString s;
+ if (jj_2_98(2147483647)) {if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CHARACTER_LITERAL:{if (!hasError) {
+
+ s = character_literal();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case STRINGLITERAL:{if (!hasError) {
+
+ s = operator_symbol();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ALL_T:{if (!hasError) {
+
+ jj_consume_token(ALL_T);
+ }
+ if (!hasError) {
+
+return " all ";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[225] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::target() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case LPAREN_T:{if (!hasError) {
+
+ s = aggregate();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[226] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::term() {QCString s,s1,s2;if (!hasError) {
+
+ s = factor();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_99(2)) {
+ ;
+ } else {
+ goto end_label_43;
+ }if (!hasError) {
+
+ s1 = multiplying_operation();
+ }
+ if (!hasError) {
+
+ s2 = factor();
+ }
+ if (!hasError) {
+
+s+=s1;s+=s2;
+ }
+
+ }
+ end_label_43: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::timeout_clause() {QCString s;if (!hasError) {
+
+ jj_consume_token(FOR_T);
+ }
+ if (!hasError) {
+
+ s = expression();
+ }
+
+return " for "+s;
+assert(false);
+ }
+
+
+QCString VhdlParser::type_conversion() {QCString s,s1;if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+return s+"("+s1+")";
+assert(false);
+ }
+
+
+QCString VhdlParser::type_declaration() {QCString s;
+ if (jj_2_100(3)) {if (!hasError) {
+
+ s = full_type_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case TYPE_T:{if (!hasError) {
+
+ s = incomplete_type_declaration();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[227] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::type_definition() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case RANGE_T:
+ case LPAREN_T:{if (!hasError) {
+
+ //try{
+ s = scalar_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ARRAY_T:
+ case RECORD_T:{if (!hasError) {
+
+ s = composite_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case ACCESS_T:{if (!hasError) {
+
+ s = access_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ s = file_type_definition();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[228] = jj_gen;
+ if (jj_2_101(2)) {if (!hasError) {
+
+ protected_type_body();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PROTECTED_T:{if (!hasError) {
+
+ protected_type_declaration();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[229] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::type_mark() {QCString s;if (!hasError) {
+
+ s = name();
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::unconstraint_array_definition() {QCString s,s1,s2,s3;if (!hasError) {
+
+ jj_consume_token(ARRAY_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s = index_subtype_definition();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[230] = jj_gen;
+ goto end_label_44;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = index_subtype_definition();
+ }
+ if (!hasError) {
+
+s3+=",";s3+=s1;
+ }
+
+ }
+ end_label_44: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(OF_T);
+ }
+ if (!hasError) {
+
+ s2 = subtype_indication();
+ }
+
+return "array("+s+s3+") of "+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::use_clause() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(USE_T);
+ }
+ if (!hasError) {
+
+ s = selected_name();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[231] = jj_gen;
+ goto end_label_45;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = selected_name();
+ }
+ if (!hasError) {
+
+s+=",";s+=s1;
+ }
+
+ }
+ end_label_45: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QStringList ql1=QStringList::split(",",s,FALSE);
+ for (uint j=0;j<ql1.count();j++)
+ {
+ QStringList ql=QStringList::split(".",ql1[j],FALSE);
+ QCString it=ql[1].utf8();
+ if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
+ {
+ VhdlParser::addVhdlType(it.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::USE,it.data(),"_use_",Public);
+ }
+ }
+ s1="use "+s;
+ return s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::variable_assignment_statement() {QCString s,s1,s2;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ if (jj_2_102(2)) {if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+s+=":";
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s1 = target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+ if (!hasError) {
+
+return s+s1+":="+s2+";";
+ }
+
+ break;
+ }
+ case WITH_T:{if (!hasError) {
+
+ selected_variable_assignment();
+ }
+ if (!hasError) {
+
+return "";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[232] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::variable_declaration() {Token *tok=0;Token *t1=0;QCString s,s1,s2;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SHARED_T:{if (!hasError) {
+
+ tok = jj_consume_token(SHARED_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[233] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(VARIABLE_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s1 = subtype_indication();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case VARASSIGN_T:{if (!hasError) {
+
+ t1 = jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ s2 = expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[234] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+int spec;
+ if(t1)
+ s2.prepend(":=");
+ QCString val=" variable "+s+":"+s1+s2+";";
+ QCString it=s1;
+ if(tok != 0)
+ {
+ it.prepend(" shared ");
+ val.prepend(" shared");
+ spec=VhdlDocGen::SHAREDVARIABLE;
+ }
+ else
+ spec=VhdlDocGen::SHAREDVARIABLE;
+
+ if(t1){
+ it+=":=";
+ it+=s2;
+ }
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,spec,0,it.data(),Public);
+ return val;
+assert(false);
+ }
+
+
+QCString VhdlParser::wait_statement() {QCString s,s1,s2,s3;Token *t=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ t = jj_consume_token(COLON_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[235] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(WAIT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ON_T:{if (!hasError) {
+
+ s1 = sensitivity_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[236] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case UNTIL_T:{if (!hasError) {
+
+ s2 = condition_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[237] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FOR_T:{if (!hasError) {
+
+ s3 = timeout_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[238] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+if(t) s.append(":");
+ return s+" wait "+s1+s2+s3+";";
+assert(false);
+ }
+
+
+QCString VhdlParser::waveform() {QCString s,s1;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ABS_T:
+ case NEW_T:
+ case NOT_T:
+ case NULL_T:
+ case LPAREN_T:
+ case PLUS_T:
+ case MINUS_T:
+ case SLSL_T:
+ case INTEGER:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:
+ case BIT_STRING_LITERAL:{if (!hasError) {
+
+ s = waveform_element();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[239] = jj_gen;
+ goto end_label_46;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ s1 = waveform_element();
+ }
+ if (!hasError) {
+
+s+=","; s+=s1;
+ }
+
+ }
+ end_label_46: ;
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case UNAFFECTED_T:{if (!hasError) {
+
+ jj_consume_token(UNAFFECTED_T);
+ }
+ if (!hasError) {
+
+return " unaffected ";
+ }
+
+ break;
+ }
+ default:
+ jj_la1[240] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::waveform_element() {QCString s,s1;if (!hasError) {
+
+ s = expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case AFTER_T:{if (!hasError) {
+
+ jj_consume_token(AFTER_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+s1.prepend(" after ");
+ }
+
+ break;
+ }
+ default:
+ jj_la1[241] = jj_gen;
+ ;
+ }
+ }
+
+return s+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::protected_type_body() {if (!hasError) {
+
+ jj_consume_token(PROTECTED_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BODY_T);
+ }
+ if (!hasError) {
+
+ protected_type_body_declarative_part();
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(PROTECTED_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(BODY_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[242] = jj_gen;
+ ;
+ }
+ }
+
+return "";
+assert(false);
+ }
+
+
+void VhdlParser::protected_type_body_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ case IS_T:{if (!hasError) {
+
+ subprogram_body();
+ }
+
+ break;
+ }
+ case TYPE_T:{if (!hasError) {
+
+ type_declaration();
+ }
+
+ break;
+ }
+ case SUBTYPE_T:{if (!hasError) {
+
+ subtype_declaration();
+ }
+
+ break;
+ }
+ case CONSTANT_T:{if (!hasError) {
+
+ constant_declaration();
+ }
+
+ break;
+ }
+ case SHARED_T:
+ case VARIABLE_T:{if (!hasError) {
+
+ variable_declaration();
+ }
+
+ break;
+ }
+ case FILE_T:{if (!hasError) {
+
+ file_declaration();
+ }
+
+ break;
+ }
+ case ALIAS_T:{if (!hasError) {
+
+ alias_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[243] = jj_gen;
+ if (jj_2_103(2147483647)) {if (!hasError) {
+
+ attribute_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[244] = jj_gen;
+ if (jj_2_104(3)) {if (!hasError) {
+
+ group_template_declaration();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GROUP_T:{if (!hasError) {
+
+ group_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[245] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+void VhdlParser::protected_type_body_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case CONSTANT_T:
+ case FILE_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case IS_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[246] = jj_gen;
+ goto end_label_47;
+ }if (!hasError) {
+
+ protected_type_body_declarative_item();
+ }
+
+ }
+ end_label_47: ;
+ }
+
+ }
+
+
+QCString VhdlParser::protected_type_declaration() {if (!hasError) {
+
+ jj_consume_token(PROTECTED_T);
+ }
+ if (!hasError) {
+
+ try {if (!hasError) {
+
+ protected_type_declarative_part();
+ }
+
+ } catch ( ...) {
+error_skipto(END_T);
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(PROTECTED_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[247] = jj_gen;
+ ;
+ }
+ }
+
+return "";
+assert(false);
+ }
+
+
+void VhdlParser::protected_type_declarative_item() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_specification();
+ }
+
+ break;
+ }
+ case ATTRIBUTE_T:{if (!hasError) {
+
+ attribute_specification();
+ }
+
+ break;
+ }
+ case USE_T:{if (!hasError) {
+
+ use_clause();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[248] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::protected_type_declarative_part() {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ATTRIBUTE_T:
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[249] = jj_gen;
+ goto end_label_48;
+ }if (!hasError) {
+
+ protected_type_declarative_item();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+ end_label_48: ;
+ }
+
+ }
+
+
+QCString VhdlParser::context_ref() {QCString s;if (!hasError) {
+
+ jj_consume_token(CONTEXT_T);
+ }
+ if (!hasError) {
+
+ s = identifier_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+return "context "+s ;
+assert(false);
+ }
+
+
+void VhdlParser::context_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(CONTEXT_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+parse_sec=CONTEXT_SEC;
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONTEXT_T:
+ case LIBRARY_T:
+ case USE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[250] = jj_gen;
+ goto end_label_49;
+ }if (!hasError) {
+
+ s1 = libustcont_stats();
+ }
+
+ }
+ end_label_49: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONTEXT_T:{if (!hasError) {
+
+ jj_consume_token(CONTEXT_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[251] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[252] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+parse_sec=0;
+ addVhdlType(s.data(),getLine(LIBRARY_T),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,"context",s1.data(),Public);
+ }
+
+
+QCString VhdlParser::libustcont_stats() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case USE_T:{if (!hasError) {
+
+ s = use_clause();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case LIBRARY_T:{if (!hasError) {
+
+ s = library_clause();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case CONTEXT_T:{if (!hasError) {
+
+ s = context_ref();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[253] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+void VhdlParser::package_instantiation_declaration() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(NEW_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+ s2 = signature();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ gen_assoc_list();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[254] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QCString q=" is new "+s1+s2;
+ addVhdlType(s.data(),getLine(PACKAGE_T),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"package",q.data(),Public);
+ }
+
+
+QCString VhdlParser::interface_package_declaration() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(PACKAGE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(NEW_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ gen_assoc_list();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[255] = jj_gen;
+ ;
+ }
+ }
+
+current->name=s;
+ return "package "+s+" is new "+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::subprogram_instantiation_declaration() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(FUNCTION_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(NEW_T);
+ }
+ if (!hasError) {
+
+ s1 = name();
+ }
+ if (!hasError) {
+
+ s2 = signature();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case GENERIC_T:{if (!hasError) {
+
+ gen_assoc_list();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[256] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+QCString q= " is new "+s1+s2;
+ addVhdlType(s.data(),getLine(FUNCTION_T),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"function ",q.data(),Public);
+ return q;
+assert(false);
+ }
+
+
+void VhdlParser::gen_assoc_list() {if (!hasError) {
+
+ jj_consume_token(GENERIC_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(MAP_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ association_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ }
+
+
+void VhdlParser::gen_interface_list() {if (!hasError) {
+
+ jj_consume_token(GENERIC_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+//int u=s_str.iLine;
+ parse_sec=GEN_SEC;
+ }
+ if (!hasError) {
+
+ interface_list();
+ }
+ if (!hasError) {
+
+// QCString vo=$3;
+ parse_sec=0;
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ }
+
+
+void VhdlParser::case_scheme() {if (!hasError) {
+
+ jj_consume_token(CASE_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(GENERATE_T);
+ }
+ if (!hasError) {
+
+ when_stats();
+ }
+ if (!hasError) {
+
+ if (jj_2_105(3)) {if (!hasError) {
+
+ ttend();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(GENERATE_T);
+ }
+ if (!hasError) {
+
+ generate_statement_body();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::when_stats() {if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ if (jj_2_106(2)) {if (!hasError) {
+
+ label();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ choices();
+ }
+ if (!hasError) {
+
+ jj_consume_token(ARROW_T);
+ }
+ if (!hasError) {
+
+ generate_statement_body();
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[257] = jj_gen;
+ goto end_label_50;
+ }
+ }
+ end_label_50: ;
+ }
+
+ }
+
+
+void VhdlParser::ttend() {if (!hasError) {
+
+ jj_consume_token(END_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ identifier();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[258] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::generate_statement_body() {if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ generate_statement_body();
+ }
+
+ }
+
+
+void VhdlParser::generate_statement_body1() {
+ if (jj_2_107(2147483647)) {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ALIAS_T:
+ case ATTRIBUTE_T:
+ case COMPONENT_T:
+ case CONSTANT_T:
+ case DISCONNECT_T:
+ case FILE_T:
+ case FOR_T:
+ case FUNCTION_T:
+ case GROUP_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:
+ case SIGNAL_T:
+ case SHARED_T:
+ case SUBTYPE_T:
+ case TYPE_T:
+ case USE_T:
+ case VARIABLE_T:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[259] = jj_gen;
+ goto end_label_51;
+ }if (!hasError) {
+
+ block_declarative_item();
+ }
+
+ }
+ end_label_51: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(BEGIN_T);
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case POSTPONED_T:
+ case PROCESS_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[260] = jj_gen;
+ goto end_label_52;
+ }if (!hasError) {
+
+ concurrent_statement();
+ }
+
+ }
+ end_label_52: ;
+ }
+
+ } else {if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ASSERT_T:
+ case CASE_T:
+ case POSTPONED_T:
+ case PROCESS_T:
+ case WITH_T:
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case VHDL2008TOOLDIR:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[261] = jj_gen;
+ goto end_label_53;
+ }if (!hasError) {
+
+ concurrent_statement();
+ }
+
+ }
+ end_label_53: ;
+ }
+
+ }
+ }
+
+
+QCString VhdlParser::external_name() {QCString s,s1,s2;if (!hasError) {
+
+ jj_consume_token(SLSL_T);
+ }
+ if (!hasError) {
+
+ s = sig_stat();
+ }
+ if (!hasError) {
+
+ s1 = external_pathname();
+ }
+ if (!hasError) {
+
+ jj_consume_token(COLON_T);
+ }
+ if (!hasError) {
+
+ s2 = subtype_indication();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RSRS_T);
+ }
+
+QCString t="<<"+s;
+ QCString t1=s1+":"+s2+">>";
+ return s+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::sig_stat() {Token *t;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case CONSTANT_T:{if (!hasError) {
+
+ t = jj_consume_token(CONSTANT_T);
+ }
+ if (!hasError) {
+
+return t->image.data();
+ }
+
+ break;
+ }
+ case SIGNAL_T:{if (!hasError) {
+
+ t = jj_consume_token(SIGNAL_T);
+ }
+ if (!hasError) {
+
+return t->image.data();
+ }
+
+ break;
+ }
+ case VARIABLE_T:{if (!hasError) {
+
+ t = jj_consume_token(VARIABLE_T);
+ }
+ if (!hasError) {
+
+return t->image.data();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[262] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::external_pathname() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case DOT_T:{if (!hasError) {
+
+ s = absolute_pathname();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case NEG_T:{if (!hasError) {
+
+ s = relative_pathname();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case AT_T:{if (!hasError) {
+
+ s = package_path_name();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[263] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::absolute_pathname() {QCString s,s1;
+ if (jj_2_108(2147483647)) {if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+ s = pathname_element_list();
+ }
+ if (!hasError) {
+
+ s1 = identifier();
+ }
+ if (!hasError) {
+
+return "."+s+s1;
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case DOT_T:{if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+return "."+s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[264] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::relative_pathname() {QCString s,s1,s2;if (!hasError) {
+
+ s = neg_list();
+ }
+ if (!hasError) {
+
+ if (jj_2_109(2147483647)) {if (!hasError) {
+
+ s1 = pathname_element_list();
+ }
+
+ } else {
+ ;
+ }
+ }
+ if (!hasError) {
+
+ s2 = identifier();
+ }
+
+return s+s1+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::neg_list() {QCString s;if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ jj_consume_token(NEG_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+s+="^.";
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case NEG_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[265] = jj_gen;
+ goto end_label_54;
+ }
+ }
+ end_label_54: ;
+ }
+
+return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::pathname_element() {QCString s,s1;if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[266] = jj_gen;
+ ;
+ }
+ }
+
+if(!s1.isEmpty())
+ return s+"("+s1+")";
+
+ return s;
+assert(false);
+ }
+
+
+QCString VhdlParser::pathname_element_list() {QCString s,s1,s2;if (!hasError) {
+ if (!hasError) {
+
+ s = pathname_element();
+ }
+ if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+
+ }
+ if (!hasError) {
+
+s+=".";
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_110(2147483647)) {
+ ;
+ } else {
+ goto end_label_55;
+ }if (!hasError) {
+
+ s1 = pathname_element();
+ }
+ if (!hasError) {
+
+ jj_consume_token(DOT_T);
+ }
+ if (!hasError) {
+
+s2+=s1;s2+=".";
+ }
+
+ }
+ end_label_55: ;
+ }
+
+return s+s2;
+assert(false);
+ }
+
+
+QCString VhdlParser::package_path_name() {QCString s;if (!hasError) {
+
+ jj_consume_token(AT_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+
+return "@"+s;
+assert(false);
+ }
+
+
+void VhdlParser::conditional_signal_assignment_wave() {
+ if (jj_2_111(2147483647)) {if (!hasError) {
+
+ conditional_force_assignment();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ conditional_waveform_assignment();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[267] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::conditional_waveform_assignment() {if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case INERTIAL_T:
+ case REJECT_T:
+ case TRANSPORT_T:{if (!hasError) {
+
+ delay_mechanism();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[268] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ waveform_element();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ELSE_T:{if (!hasError) {
+
+ else_wave_list();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[269] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::else_wave_list() {if (!hasError) {
+
+ jj_consume_token(ELSE_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[270] = jj_gen;
+ ;
+ }
+ }
+
+ }
+
+
+void VhdlParser::conditional_force_assignment() {if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(FORCE_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IN_T:
+ case OUT_T:{if (!hasError) {
+
+ inout_stat();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[271] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ABS_T:
+ case NEW_T:
+ case NOT_T:
+ case NULL_T:
+ case LPAREN_T:
+ case PLUS_T:
+ case MINUS_T:
+ case SLSL_T:
+ case INTEGER:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:
+ case CHARACTER_LITERAL:
+ case DECIMAL_LITERAL:
+ case BASED_LITERAL:
+ case BIT_STRING_LITERAL:{if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ else_stat();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[272] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::selected_signal_assignment_wave() {
+ if (jj_2_112(2147483647)) {if (!hasError) {
+
+ selected_force_assignment();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WITH_T:{if (!hasError) {
+
+ selected_waveform_assignment();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[273] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::selected_variable_assignment() {if (!hasError) {
+
+ jj_consume_token(WITH_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SELECT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case Q_T:{if (!hasError) {
+
+ jj_consume_token(Q_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[274] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ select_name();
+ }
+ if (!hasError) {
+
+ jj_consume_token(VARASSIGN_T);
+ }
+ if (!hasError) {
+
+ sel_var_list();
+ }
+
+ }
+
+
+void VhdlParser::select_name() {
+ if (jj_2_113(2147483647)) {if (!hasError) {
+
+ aggregate();
+ }
+
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case SLSL_T:
+ case STRINGLITERAL:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ name();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[275] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+ }
+
+
+void VhdlParser::selected_waveform_assignment() {if (!hasError) {
+
+ jj_consume_token(WITH_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SELECT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case Q_T:{if (!hasError) {
+
+ jj_consume_token(Q_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[276] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case INERTIAL_T:
+ case REJECT_T:
+ case TRANSPORT_T:{if (!hasError) {
+
+ delay_mechanism();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[277] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ sel_wave_list();
+ }
+
+ }
+
+
+void VhdlParser::selected_force_assignment() {if (!hasError) {
+
+ jj_consume_token(WITH_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(SELECT_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case Q_T:{if (!hasError) {
+
+ jj_consume_token(Q_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[278] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ target();
+ }
+ if (!hasError) {
+
+ jj_consume_token(LESSTHAN_T);
+ }
+ if (!hasError) {
+
+ jj_consume_token(FORCE_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IN_T:
+ case OUT_T:{if (!hasError) {
+
+ inout_stat();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[279] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ sel_var_list();
+ }
+
+ }
+
+
+void VhdlParser::sel_var_list() {if (!hasError) {
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ choices();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+
+ break;
+ }
+ case SEMI_T:{if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[280] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ if (jj_2_114(2147483647)) {
+ ;
+ } else {
+ goto end_label_56;
+ }if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ choices();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+
+ break;
+ }
+ case SEMI_T:{if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[281] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+ }
+ end_label_56: ;
+ }
+
+ }
+
+
+void VhdlParser::sel_wave_list() {if (!hasError) {
+
+ waveform_element();
+ }
+ if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ choices();
+ }
+ if (!hasError) {
+
+ while (!hasError) {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case COMMA_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[282] = jj_gen;
+ goto end_label_57;
+ }if (!hasError) {
+
+ jj_consume_token(COMMA_T);
+ }
+ if (!hasError) {
+
+ sel_wave_list();
+ }
+
+ }
+ end_label_57: ;
+ }
+ if (!hasError) {
+
+ jj_consume_token(SEMI_T);
+ }
+
+ }
+
+
+void VhdlParser::inout_stat() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IN_T:{if (!hasError) {
+
+ jj_consume_token(IN_T);
+ }
+
+ break;
+ }
+ case OUT_T:{if (!hasError) {
+
+ jj_consume_token(OUT_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[283] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+void VhdlParser::else_stat() {if (!hasError) {
+
+ while (!hasError) {if (!hasError) {
+
+ jj_consume_token(ELSE_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case WHEN_T:{if (!hasError) {
+
+ jj_consume_token(WHEN_T);
+ }
+ if (!hasError) {
+
+ expression();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[284] = jj_gen;
+ ;
+ }
+ }
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case ELSE_T:{
+ ;
+ break;
+ }
+ default:
+ jj_la1[285] = jj_gen;
+ goto end_label_58;
+ }
+ }
+ end_label_58: ;
+ }
+
+ }
+
+
+QCString VhdlParser::interface_subprogram_declaration() {QCString s;
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PROCEDURE_T:{if (!hasError) {
+
+ s = iproc();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PURE_T:{if (!hasError) {
+
+ s = ifunc();
+ }
+ if (!hasError) {
+
+return s;
+ }
+
+ break;
+ }
+ default:
+ jj_la1[286] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+assert(false);
+ }
+
+
+QCString VhdlParser::iproc() {QCString s,s1;if (!hasError) {
+
+ jj_consume_token(PROCEDURE_T);
+ }
+ if (!hasError) {
+
+ s = identifier();
+ }
+ if (!hasError) {
+
+ s1 = param();
+ }
+
+current->name=s;
+ return "procedure "+s+s1;
+assert(false);
+ }
+
+
+QCString VhdlParser::ifunc() {QCString s,s1,s2,s3;Token *t=0;Token *t1=0;Token *t2=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IMPURE_T:
+ case PURE_T:{
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PURE_T:{if (!hasError) {
+
+ t = jj_consume_token(PURE_T);
+ }
+
+ break;
+ }
+ case IMPURE_T:{if (!hasError) {
+
+ t = jj_consume_token(IMPURE_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[287] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ break;
+ }
+ default:
+ jj_la1[288] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+ jj_consume_token(FUNCTION_T);
+ }
+ if (!hasError) {
+
+ s = name();
+ }
+ if (!hasError) {
+
+ s1 = param();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RETURN_T);
+ }
+ if (!hasError) {
+
+ s2 = name();
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case IS_T:{if (!hasError) {
+
+ t1 = jj_consume_token(IS_T);
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ s3 = identifier();
+ }
+
+ break;
+ }
+ case BOX_T:{if (!hasError) {
+
+ t2 = jj_consume_token(BOX_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[289] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+ break;
+ }
+ default:
+ jj_la1[290] = jj_gen;
+ ;
+ }
+ }
+
+QCString q;
+ if(t) q=t->image.data();
+ if(t2) s3="<>";
+ if (!s3.isEmpty())
+ {
+ s3.prepend(" is ");
+ }
+ current->name=s;
+ if (parse_sec==GEN_SEC)
+ {
+ QCString ss=q+" function "+s1+" return "+s2+s3;
+ int a=getLine(FUNCTION_T);
+ int b=getLine(PROCEDURE_T);
+
+ if (a>b) b=a;
+ addVhdlType(current->name.data(),b,Entry::VARIABLE_SEC,VhdlDocGen::GENERIC,ss.data(),0,Public);
+ }
+ currP=0;return "";
+assert(false);
+ }
+
+
+QCString VhdlParser::param() {QCString s,s1;Token *tok=0;if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case PARAMETER_T:{if (!hasError) {
+
+ tok = jj_consume_token(PARAMETER_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[291] = jj_gen;
+ ;
+ }
+ }
+ if (!hasError) {
+
+param_sec=PARAM_SEC;
+ }
+ if (!hasError) {
+
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case LPAREN_T:{if (!hasError) {
+
+ jj_consume_token(LPAREN_T);
+ }
+ if (!hasError) {
+
+ s1 = interface_list();
+ }
+ if (!hasError) {
+
+ jj_consume_token(RPAREN_T);
+ }
+
+ break;
+ }
+ default:
+ jj_la1[292] = jj_gen;
+ ;
+ }
+ }
+
+if(tok)
+ {
+ s = tok->image.data();
+ param_sec=0;
+ }
+ return s+"("+s1+")";
+assert(false);
+ }
+
+
+void VhdlParser::parseInline() {
+ switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+ case POSTPONED_T:
+ case PROCESS_T:
+ case BASIC_IDENTIFIER:
+ case EXTENDED_CHARACTER:{if (!hasError) {
+
+ process_statement();
+ }
+
+ break;
+ }
+ case FUNCTION_T:
+ case IMPURE_T:
+ case PROCEDURE_T:
+ case PURE_T:{if (!hasError) {
+
+ subprogram_declaration();
+ }
+
+ break;
+ }
+ default:
+ jj_la1[293] = jj_gen;
+ jj_consume_token(-1);
+ errorHandler->handleParseError(token, getToken(1), __FUNCTION__, this), hasError = true;
+ }
+ }
+
+
+ VhdlParser::VhdlParser(TokenManager *tm){
+ head = NULL;
+ ReInit(tm);
+}
+ VhdlParser::~VhdlParser()
+{
+ if (token_source) delete token_source;
+ if (head) {
+ Token *next, *t = head;
+ while (t) {
+ next = t->next;
+ delete t;
+ t = next;
+ }
+ }
+ if (errorHandlerCreated) {
+ delete errorHandler;
+ }
+}
+
+void VhdlParser::ReInit(TokenManager *tm){
+ if (head) delete head;
+ errorHandler = new ErrorHandler();
+ errorHandlerCreated = true;
+ hasError = false;
+ token_source = tm;
+ head = token = new Token();
+ token->kind = 0;
+ token->next = NULL;
+ jj_lookingAhead = false;
+ jj_rescan = false;
+ jj_done = false;
+ jj_scanpos = jj_lastpos = NULL;
+ jj_gc = 0;
+ jj_kind = -1;
+ trace_indent = 0;
+ trace_enabled = false;
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 294; i++) jj_la1[i] = -1;
+ }
+
+
+Token * VhdlParser::jj_consume_token(int kind) {
+ Token *oldToken;
+ if ((oldToken = token)->next != NULL) token = token->next;
+ else token = token->next = token_source->getNextToken();
+ jj_ntk = -1;
+ if (token->kind == kind) {
+ jj_gen++;
+ if (++jj_gc > 100) {
+ jj_gc = 0;
+ for (int i = 0; i < 114; i++) {
+ JJCalls *c = &jj_2_rtns[i];
+ while (c != NULL) {
+ if (c->gen < jj_gen) c->first = NULL;
+ c = c->next;
+ }
+ }
+ }
+ return token;
+ }
+ token = oldToken;
+ jj_kind = kind;
+ JAVACC_STRING_TYPE image = kind >= 0 ? tokenImage[kind] : tokenImage[0];
+ errorHandler->handleUnexpectedToken(kind, image.substr(1, image.size() - 2), getToken(1), this), hasError = true;
+ return token;
+ }
+
+
+bool VhdlParser::jj_scan_token(int kind){
+ if (jj_scanpos == jj_lastpos) {
+ jj_la--;
+ if (jj_scanpos->next == NULL) {
+ jj_lastpos = jj_scanpos = jj_scanpos->next = token_source->getNextToken();
+ } else {
+ jj_lastpos = jj_scanpos = jj_scanpos->next;
+ }
+ } else {
+ jj_scanpos = jj_scanpos->next;
+ }
+ if (jj_rescan) {
+ int i = 0; Token *tok = token;
+ while (tok != NULL && tok != jj_scanpos) { i++; tok = tok->next; }
+ if (tok != NULL) jj_add_error_token(kind, i);
+ }
+ if (jj_scanpos->kind != kind) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) { return jj_done = true; }
+ return false;
+ }
+
+
+/** Get the next Token. */
+
+Token * VhdlParser::getNextToken(){
+ if (token->next != NULL) token = token->next;
+ else token = token->next = token_source->getNextToken();
+ jj_ntk = -1;
+ jj_gen++;
+ return token;
+ }
+
+/** Get the specific Token. */
+
+Token * VhdlParser::getToken(int index){
+ Token *t = token;
+ for (int i = 0; i < index; i++) {
+ if (t->next != NULL) t = t->next;
+ else t = t->next = token_source->getNextToken();
+ }
+ return t;
+ }
+
+
+int VhdlParser::jj_ntk_f(){
+ if ((jj_nt=token->next) == NULL)
+ return (jj_ntk = (token->next=token_source->getNextToken())->kind);
+ else
+ return (jj_ntk = jj_nt->kind);
+ }
+
+
+void VhdlParser::jj_add_error_token(int kind, int pos) {
+ }
+
+ /** Generate ParseException. */
+
+ void VhdlParser::parseError() {
+ // fprintf(stderr, "Parse error at: %d:%d, after token: %s encountered: %s\n", token->beginLine, token->beginColumn, addUnicodeEscapes(token->image).c_str(), addUnicodeEscapes(getToken(1)->image).c_str());
+ }
+
+
+ void VhdlParser::enable_tracing() {
+ }
+
+ /** Disable tracing. */
+
+ void VhdlParser::disable_tracing() {
+ }
+
+
+void VhdlParser::jj_rescan_token(){
+ jj_rescan = true;
+ for (int i = 0; i < 114; i++) {
+ JJCalls *p = &jj_2_rtns[i];
+ do {
+ if (p->gen > jj_gen) {
+ jj_la = p->arg; jj_lastpos = jj_scanpos = p->first;
+ switch (i) {
+ case 0: jj_3_1(); break;
+ case 1: jj_3_2(); break;
+ case 2: jj_3_3(); break;
+ case 3: jj_3_4(); break;
+ case 4: jj_3_5(); break;
+ case 5: jj_3_6(); break;
+ case 6: jj_3_7(); break;
+ case 7: jj_3_8(); break;
+ case 8: jj_3_9(); break;
+ case 9: jj_3_10(); break;
+ case 10: jj_3_11(); break;
+ case 11: jj_3_12(); break;
+ case 12: jj_3_13(); break;
+ case 13: jj_3_14(); break;
+ case 14: jj_3_15(); break;
+ case 15: jj_3_16(); break;
+ case 16: jj_3_17(); break;
+ case 17: jj_3_18(); break;
+ case 18: jj_3_19(); break;
+ case 19: jj_3_20(); break;
+ case 20: jj_3_21(); break;
+ case 21: jj_3_22(); break;
+ case 22: jj_3_23(); break;
+ case 23: jj_3_24(); break;
+ case 24: jj_3_25(); break;
+ case 25: jj_3_26(); break;
+ case 26: jj_3_27(); break;
+ case 27: jj_3_28(); break;
+ case 28: jj_3_29(); break;
+ case 29: jj_3_30(); break;
+ case 30: jj_3_31(); break;
+ case 31: jj_3_32(); break;
+ case 32: jj_3_33(); break;
+ case 33: jj_3_34(); break;
+ case 34: jj_3_35(); break;
+ case 35: jj_3_36(); break;
+ case 36: jj_3_37(); break;
+ case 37: jj_3_38(); break;
+ case 38: jj_3_39(); break;
+ case 39: jj_3_40(); break;
+ case 40: jj_3_41(); break;
+ case 41: jj_3_42(); break;
+ case 42: jj_3_43(); break;
+ case 43: jj_3_44(); break;
+ case 44: jj_3_45(); break;
+ case 45: jj_3_46(); break;
+ case 46: jj_3_47(); break;
+ case 47: jj_3_48(); break;
+ case 48: jj_3_49(); break;
+ case 49: jj_3_50(); break;
+ case 50: jj_3_51(); break;
+ case 51: jj_3_52(); break;
+ case 52: jj_3_53(); break;
+ case 53: jj_3_54(); break;
+ case 54: jj_3_55(); break;
+ case 55: jj_3_56(); break;
+ case 56: jj_3_57(); break;
+ case 57: jj_3_58(); break;
+ case 58: jj_3_59(); break;
+ case 59: jj_3_60(); break;
+ case 60: jj_3_61(); break;
+ case 61: jj_3_62(); break;
+ case 62: jj_3_63(); break;
+ case 63: jj_3_64(); break;
+ case 64: jj_3_65(); break;
+ case 65: jj_3_66(); break;
+ case 66: jj_3_67(); break;
+ case 67: jj_3_68(); break;
+ case 68: jj_3_69(); break;
+ case 69: jj_3_70(); break;
+ case 70: jj_3_71(); break;
+ case 71: jj_3_72(); break;
+ case 72: jj_3_73(); break;
+ case 73: jj_3_74(); break;
+ case 74: jj_3_75(); break;
+ case 75: jj_3_76(); break;
+ case 76: jj_3_77(); break;
+ case 77: jj_3_78(); break;
+ case 78: jj_3_79(); break;
+ case 79: jj_3_80(); break;
+ case 80: jj_3_81(); break;
+ case 81: jj_3_82(); break;
+ case 82: jj_3_83(); break;
+ case 83: jj_3_84(); break;
+ case 84: jj_3_85(); break;
+ case 85: jj_3_86(); break;
+ case 86: jj_3_87(); break;
+ case 87: jj_3_88(); break;
+ case 88: jj_3_89(); break;
+ case 89: jj_3_90(); break;
+ case 90: jj_3_91(); break;
+ case 91: jj_3_92(); break;
+ case 92: jj_3_93(); break;
+ case 93: jj_3_94(); break;
+ case 94: jj_3_95(); break;
+ case 95: jj_3_96(); break;
+ case 96: jj_3_97(); break;
+ case 97: jj_3_98(); break;
+ case 98: jj_3_99(); break;
+ case 99: jj_3_100(); break;
+ case 100: jj_3_101(); break;
+ case 101: jj_3_102(); break;
+ case 102: jj_3_103(); break;
+ case 103: jj_3_104(); break;
+ case 104: jj_3_105(); break;
+ case 105: jj_3_106(); break;
+ case 106: jj_3_107(); break;
+ case 107: jj_3_108(); break;
+ case 108: jj_3_109(); break;
+ case 109: jj_3_110(); break;
+ case 110: jj_3_111(); break;
+ case 111: jj_3_112(); break;
+ case 112: jj_3_113(); break;
+ case 113: jj_3_114(); break;
+ }
+ }
+ p = p->next;
+ } while (p != NULL);
+ }
+ jj_rescan = false;
+ }
+
+
+void VhdlParser::jj_save(int index, int xla){
+ JJCalls *p = &jj_2_rtns[index];
+ while (p->gen > jj_gen) {
+ if (p->next == NULL) { p = p->next = new JJCalls(); break; }
+ p = p->next;
+ }
+ p->gen = jj_gen + xla - jj_la; p->first = token; p->arg = xla;
+ }
+
+
+}
+}
diff --git a/vhdlparser/VhdlParser.h b/vhdlparser/VhdlParser.h
new file mode 100644
index 0000000..78450d1
--- /dev/null
+++ b/vhdlparser/VhdlParser.h
@@ -0,0 +1,8984 @@
+#ifndef VHDLPARSER_H
+#define VHDLPARSER_H
+#include "JavaCC.h"
+#include "CharStream.h"
+#include "Token.h"
+#include "TokenManager.h"
+#include "VhdlParserTokenManager.h"
+#include "vhdljjparser.h"
+
+#include "VhdlParserConstants.h"
+#include "ErrorHandler.h"
+namespace vhdl {
+namespace parser {
+ struct JJCalls {
+ int gen;
+ Token *first;
+ int arg;
+ JJCalls *next;
+ ~JJCalls() { if (next) delete next; }
+ JJCalls() { next = NULL; arg = 0; gen = -1; first = NULL; }
+ };
+
+class VhdlParser {
+ public:
+
+QCString abstract_literal();
+
+QCString access_type_definition();
+
+QCString actual_designator();
+
+QCString actual_parameter_part();
+
+QCString actual_part();
+
+QCString adding_operator();
+
+QCString aggregate();
+
+QCString alias_declaration();
+
+QCString alias_designator();
+
+void allocator();
+
+void architecture_body();
+
+void architecture_declarative_part();
+
+void architecture_statement_part();
+
+QCString array_type_definition();
+
+QCString assertion();
+
+QCString assertion_statement();
+
+QCString association_element();
+
+QCString association_list();
+
+QCString attribute_declaration();
+
+QCString attribute_designator();
+
+QCString attribute_name();
+
+QCString attribute_specification();
+
+QCString base();
+
+QCString base_specifier();
+
+QCString base_unit_declaration();
+
+QCString based_integer();
+
+QCString based_literal();
+
+QCString basic_identifier();
+
+void binding_indication();
+
+QCString bit_string_literal();
+
+QCString bit_value();
+
+void block_configuration();
+
+void block_declarative_item();
+
+void block_declarative_part();
+
+void block_header();
+
+void block_specification();
+
+void block_statement();
+
+void block_statement_part();
+
+void case_statement();
+
+void case_statement_alternative();
+
+QCString character_literal();
+
+QCString choice();
+
+QCString choices();
+
+void component_configuration();
+
+void component_declaration();
+
+void component_instantiation_statement();
+
+void component_specification();
+
+QCString composite_type_definition();
+
+void concurrent_assertion_statement();
+
+void concurrent_procedure_call_statement();
+
+void concurrent_signal_assignment_statement();
+
+void concurrent_statement();
+
+QCString condition();
+
+QCString condition_clause();
+
+void conditional_signal_assignment();
+
+void conditional_waveforms();
+
+void configuration_declaration();
+
+void configuration_declarative_item();
+
+void configuration_declarative_part();
+
+void configuration_item();
+
+void configuration_specification();
+
+QCString constant_declaration();
+
+QCString constraint_array_definition();
+
+void context_clause();
+
+QCString constraint();
+
+void context_item();
+
+QCString decimal_literal();
+
+QCString delay_mechanism();
+
+void design_file();
+
+void design_unit();
+
+QCString designator();
+
+QCString direction();
+
+void disconnection_specification();
+
+void guarded_signal_specificatio();
+
+QCString discrete_range();
+
+QCString element_association();
+
+QCString element_declaration();
+
+QCString entity_aspect();
+
+QCString entity_class();
+
+QCString entity_class_entry();
+
+QCString entity_class_entry_list();
+
+void entity_declaration();
+
+void entity_declarative_item();
+
+void entity_declarative_part();
+
+QCString entity_designator();
+
+void entity_header();
+
+QCString entity_name_list();
+
+QCString entity_specification();
+
+void entity_statement();
+
+void entity_statement_part();
+
+QCString entity_tag();
+
+QCString enumeration_literal();
+
+QCString enumeration_type_definition();
+
+QCString exit_statement();
+
+QCString expression();
+
+QCString logop();
+
+QCString extended_identifier();
+
+QCString factor();
+
+QCString file_declaration();
+
+QCString file_logical_name();
+
+QCString file_open_information();
+
+QCString file_type_definition();
+
+QCString floating_type_definition();
+
+QCString formal_designator();
+
+QCString formal_parameter_list();
+
+QCString formal_part();
+
+QCString full_type_declaration();
+
+QCString function_call();
+
+void generate_statement();
+
+void generate_scheme();
+
+void generic_clause();
+
+QCString generic_list();
+
+void generic_map_aspect();
+
+QCString group_constituent();
+
+QCString group_constituent_list();
+
+QCString group_declaration();
+
+QCString group_template_declaration();
+
+void guarded_signal_specification();
+
+QCString identifier();
+
+QCString identifier_list();
+
+void if_statement();
+
+QCString incomplete_type_declaration();
+
+QCString index_constraint();
+
+QCString index_specification();
+
+QCString index_subtype_definition();
+
+QCString instantiation_unit();
+
+QCString instantiation_list();
+
+QCString integer();
+
+QCString integer_type_definition();
+
+QCString interface_declaration();
+
+QCString interface_element();
+
+QCString interface_file_declaration();
+
+QCString interface_list();
+
+QCString interface_variable_declaration();
+
+QCString iteration_scheme();
+
+QCString label();
+
+QCString library_clause();
+
+QCString library_unit();
+
+QCString literal();
+
+QCString logical_operator();
+
+QCString loop_statement();
+
+QCString miscellaneous_operator();
+
+QCString mode();
+
+QCString multiplying_operation();
+
+QCString name();
+
+QCString name_ext1();
+
+QCString name_ext();
+
+QCString test_att_name();
+
+QCString indexed_name();
+
+QCString next_statement();
+
+QCString null_statement();
+
+QCString numeric_literal();
+
+QCString object_class();
+
+QCString operator_symbol();
+
+void options();
+
+void package_body();
+
+void package_body_declarative_item();
+
+void package_body_declarative_part();
+
+void package_declaration();
+
+void geninter();
+
+void package_declarative_item();
+
+void package_declarative_part();
+
+QCString parameter_specification();
+
+QCString physical_literal();
+
+QCString physical_type_definition();
+
+void port_clause();
+
+QCString port_list();
+
+void port_map_aspect();
+
+QCString primary();
+
+void primary_unit();
+
+QCString procedure_call();
+
+QCString procedure_call_statement();
+
+QCString process_declarative_item();
+
+QCString process_declarative_part();
+
+void process_statement();
+
+void process_statement_part();
+
+QCString qualified_expression();
+
+QCString range();
+
+QCString range_constraint();
+
+void record_type_definition();
+
+QCString relation();
+
+QCString relation_operator();
+
+QCString report_statement();
+
+QCString return_statement();
+
+QCString scalar_type_definition();
+
+void secondary_unit();
+
+QCString secondary_unit_declaration();
+
+QCString selected_name();
+
+void selected_signal_assignment();
+
+void selected_waveforms();
+
+QCString sensitivity_clause();
+
+QCString sensitivity_list();
+
+QCString sequence_of_statement();
+
+QCString sequential_statement();
+
+QCString shift_expression();
+
+QCString shift_operator();
+
+QCString sign();
+
+QCString signal_assignment_statement();
+
+void semi();
+
+void signal_declaration();
+
+QCString signal_kind();
+
+QCString signal_list();
+
+QCString signature();
+
+QCString simple_expression();
+
+void simple_name();
+
+QCString slice_name();
+
+QCString string_literal();
+
+void subprogram_body();
+
+void subprogram_declaration();
+
+void subprogram_1();
+
+QCString subprogram_declarative_item();
+
+QCString subprogram_declarative_part();
+
+void subprogram_kind();
+
+void subprogram_specification();
+
+void subprogram_statement_part();
+
+QCString subtype_declaration();
+
+QCString subtype_indication();
+
+QCString suffix();
+
+QCString target();
+
+QCString term();
+
+QCString timeout_clause();
+
+QCString type_conversion();
+
+QCString type_declaration();
+
+QCString type_definition();
+
+QCString type_mark();
+
+QCString unconstraint_array_definition();
+
+QCString use_clause();
+
+QCString variable_assignment_statement();
+
+QCString variable_declaration();
+
+QCString wait_statement();
+
+QCString waveform();
+
+QCString waveform_element();
+
+QCString protected_type_body();
+
+void protected_type_body_declarative_item();
+
+void protected_type_body_declarative_part();
+
+QCString protected_type_declaration();
+
+void protected_type_declarative_item();
+
+void protected_type_declarative_part();
+
+QCString context_ref();
+
+void context_declaration();
+
+QCString libustcont_stats();
+
+void package_instantiation_declaration();
+
+QCString interface_package_declaration();
+
+QCString subprogram_instantiation_declaration();
+
+void gen_assoc_list();
+
+void gen_interface_list();
+
+void case_scheme();
+
+void when_stats();
+
+void ttend();
+
+void generate_statement_body();
+
+void generate_statement_body1();
+
+QCString external_name();
+
+QCString sig_stat();
+
+QCString external_pathname();
+
+QCString absolute_pathname();
+
+QCString relative_pathname();
+
+QCString neg_list();
+
+QCString pathname_element();
+
+QCString pathname_element_list();
+
+QCString package_path_name();
+
+void conditional_signal_assignment_wave();
+
+void conditional_waveform_assignment();
+
+void else_wave_list();
+
+void conditional_force_assignment();
+
+void selected_signal_assignment_wave();
+
+void selected_variable_assignment();
+
+void select_name();
+
+void selected_waveform_assignment();
+
+void selected_force_assignment();
+
+void sel_var_list();
+
+void sel_wave_list();
+
+void inout_stat();
+
+void else_stat();
+
+QCString interface_subprogram_declaration();
+
+QCString iproc();
+
+QCString ifunc();
+
+QCString param();
+
+void parseInline();
+ inline bool jj_2_1(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_1() || jj_done;
+ { jj_save(0, xla); }
+ }
+
+ inline bool jj_2_2(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_2() || jj_done;
+ { jj_save(1, xla); }
+ }
+
+ inline bool jj_2_3(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_3() || jj_done;
+ { jj_save(2, xla); }
+ }
+
+ inline bool jj_2_4(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_4() || jj_done;
+ { jj_save(3, xla); }
+ }
+
+ inline bool jj_2_5(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_5() || jj_done;
+ { jj_save(4, xla); }
+ }
+
+ inline bool jj_2_6(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_6() || jj_done;
+ { jj_save(5, xla); }
+ }
+
+ inline bool jj_2_7(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_7() || jj_done;
+ { jj_save(6, xla); }
+ }
+
+ inline bool jj_2_8(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_8() || jj_done;
+ { jj_save(7, xla); }
+ }
+
+ inline bool jj_2_9(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_9() || jj_done;
+ { jj_save(8, xla); }
+ }
+
+ inline bool jj_2_10(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_10() || jj_done;
+ { jj_save(9, xla); }
+ }
+
+ inline bool jj_2_11(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_11() || jj_done;
+ { jj_save(10, xla); }
+ }
+
+ inline bool jj_2_12(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_12() || jj_done;
+ { jj_save(11, xla); }
+ }
+
+ inline bool jj_2_13(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_13() || jj_done;
+ { jj_save(12, xla); }
+ }
+
+ inline bool jj_2_14(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_14() || jj_done;
+ { jj_save(13, xla); }
+ }
+
+ inline bool jj_2_15(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_15() || jj_done;
+ { jj_save(14, xla); }
+ }
+
+ inline bool jj_2_16(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_16() || jj_done;
+ { jj_save(15, xla); }
+ }
+
+ inline bool jj_2_17(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_17() || jj_done;
+ { jj_save(16, xla); }
+ }
+
+ inline bool jj_2_18(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_18() || jj_done;
+ { jj_save(17, xla); }
+ }
+
+ inline bool jj_2_19(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_19() || jj_done;
+ { jj_save(18, xla); }
+ }
+
+ inline bool jj_2_20(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_20() || jj_done;
+ { jj_save(19, xla); }
+ }
+
+ inline bool jj_2_21(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_21() || jj_done;
+ { jj_save(20, xla); }
+ }
+
+ inline bool jj_2_22(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_22() || jj_done;
+ { jj_save(21, xla); }
+ }
+
+ inline bool jj_2_23(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_23() || jj_done;
+ { jj_save(22, xla); }
+ }
+
+ inline bool jj_2_24(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_24() || jj_done;
+ { jj_save(23, xla); }
+ }
+
+ inline bool jj_2_25(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_25() || jj_done;
+ { jj_save(24, xla); }
+ }
+
+ inline bool jj_2_26(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_26() || jj_done;
+ { jj_save(25, xla); }
+ }
+
+ inline bool jj_2_27(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_27() || jj_done;
+ { jj_save(26, xla); }
+ }
+
+ inline bool jj_2_28(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_28() || jj_done;
+ { jj_save(27, xla); }
+ }
+
+ inline bool jj_2_29(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_29() || jj_done;
+ { jj_save(28, xla); }
+ }
+
+ inline bool jj_2_30(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_30() || jj_done;
+ { jj_save(29, xla); }
+ }
+
+ inline bool jj_2_31(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_31() || jj_done;
+ { jj_save(30, xla); }
+ }
+
+ inline bool jj_2_32(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_32() || jj_done;
+ { jj_save(31, xla); }
+ }
+
+ inline bool jj_2_33(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_33() || jj_done;
+ { jj_save(32, xla); }
+ }
+
+ inline bool jj_2_34(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_34() || jj_done;
+ { jj_save(33, xla); }
+ }
+
+ inline bool jj_2_35(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_35() || jj_done;
+ { jj_save(34, xla); }
+ }
+
+ inline bool jj_2_36(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_36() || jj_done;
+ { jj_save(35, xla); }
+ }
+
+ inline bool jj_2_37(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_37() || jj_done;
+ { jj_save(36, xla); }
+ }
+
+ inline bool jj_2_38(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_38() || jj_done;
+ { jj_save(37, xla); }
+ }
+
+ inline bool jj_2_39(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_39() || jj_done;
+ { jj_save(38, xla); }
+ }
+
+ inline bool jj_2_40(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_40() || jj_done;
+ { jj_save(39, xla); }
+ }
+
+ inline bool jj_2_41(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_41() || jj_done;
+ { jj_save(40, xla); }
+ }
+
+ inline bool jj_2_42(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_42() || jj_done;
+ { jj_save(41, xla); }
+ }
+
+ inline bool jj_2_43(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_43() || jj_done;
+ { jj_save(42, xla); }
+ }
+
+ inline bool jj_2_44(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_44() || jj_done;
+ { jj_save(43, xla); }
+ }
+
+ inline bool jj_2_45(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_45() || jj_done;
+ { jj_save(44, xla); }
+ }
+
+ inline bool jj_2_46(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_46() || jj_done;
+ { jj_save(45, xla); }
+ }
+
+ inline bool jj_2_47(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_47() || jj_done;
+ { jj_save(46, xla); }
+ }
+
+ inline bool jj_2_48(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_48() || jj_done;
+ { jj_save(47, xla); }
+ }
+
+ inline bool jj_2_49(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_49() || jj_done;
+ { jj_save(48, xla); }
+ }
+
+ inline bool jj_2_50(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_50() || jj_done;
+ { jj_save(49, xla); }
+ }
+
+ inline bool jj_2_51(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_51() || jj_done;
+ { jj_save(50, xla); }
+ }
+
+ inline bool jj_2_52(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_52() || jj_done;
+ { jj_save(51, xla); }
+ }
+
+ inline bool jj_2_53(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_53() || jj_done;
+ { jj_save(52, xla); }
+ }
+
+ inline bool jj_2_54(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_54() || jj_done;
+ { jj_save(53, xla); }
+ }
+
+ inline bool jj_2_55(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_55() || jj_done;
+ { jj_save(54, xla); }
+ }
+
+ inline bool jj_2_56(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_56() || jj_done;
+ { jj_save(55, xla); }
+ }
+
+ inline bool jj_2_57(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_57() || jj_done;
+ { jj_save(56, xla); }
+ }
+
+ inline bool jj_2_58(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_58() || jj_done;
+ { jj_save(57, xla); }
+ }
+
+ inline bool jj_2_59(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_59() || jj_done;
+ { jj_save(58, xla); }
+ }
+
+ inline bool jj_2_60(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_60() || jj_done;
+ { jj_save(59, xla); }
+ }
+
+ inline bool jj_2_61(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_61() || jj_done;
+ { jj_save(60, xla); }
+ }
+
+ inline bool jj_2_62(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_62() || jj_done;
+ { jj_save(61, xla); }
+ }
+
+ inline bool jj_2_63(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_63() || jj_done;
+ { jj_save(62, xla); }
+ }
+
+ inline bool jj_2_64(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_64() || jj_done;
+ { jj_save(63, xla); }
+ }
+
+ inline bool jj_2_65(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_65() || jj_done;
+ { jj_save(64, xla); }
+ }
+
+ inline bool jj_2_66(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_66() || jj_done;
+ { jj_save(65, xla); }
+ }
+
+ inline bool jj_2_67(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_67() || jj_done;
+ { jj_save(66, xla); }
+ }
+
+ inline bool jj_2_68(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_68() || jj_done;
+ { jj_save(67, xla); }
+ }
+
+ inline bool jj_2_69(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_69() || jj_done;
+ { jj_save(68, xla); }
+ }
+
+ inline bool jj_2_70(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_70() || jj_done;
+ { jj_save(69, xla); }
+ }
+
+ inline bool jj_2_71(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_71() || jj_done;
+ { jj_save(70, xla); }
+ }
+
+ inline bool jj_2_72(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_72() || jj_done;
+ { jj_save(71, xla); }
+ }
+
+ inline bool jj_2_73(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_73() || jj_done;
+ { jj_save(72, xla); }
+ }
+
+ inline bool jj_2_74(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_74() || jj_done;
+ { jj_save(73, xla); }
+ }
+
+ inline bool jj_2_75(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_75() || jj_done;
+ { jj_save(74, xla); }
+ }
+
+ inline bool jj_2_76(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_76() || jj_done;
+ { jj_save(75, xla); }
+ }
+
+ inline bool jj_2_77(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_77() || jj_done;
+ { jj_save(76, xla); }
+ }
+
+ inline bool jj_2_78(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_78() || jj_done;
+ { jj_save(77, xla); }
+ }
+
+ inline bool jj_2_79(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_79() || jj_done;
+ { jj_save(78, xla); }
+ }
+
+ inline bool jj_2_80(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_80() || jj_done;
+ { jj_save(79, xla); }
+ }
+
+ inline bool jj_2_81(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_81() || jj_done;
+ { jj_save(80, xla); }
+ }
+
+ inline bool jj_2_82(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_82() || jj_done;
+ { jj_save(81, xla); }
+ }
+
+ inline bool jj_2_83(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_83() || jj_done;
+ { jj_save(82, xla); }
+ }
+
+ inline bool jj_2_84(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_84() || jj_done;
+ { jj_save(83, xla); }
+ }
+
+ inline bool jj_2_85(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_85() || jj_done;
+ { jj_save(84, xla); }
+ }
+
+ inline bool jj_2_86(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_86() || jj_done;
+ { jj_save(85, xla); }
+ }
+
+ inline bool jj_2_87(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_87() || jj_done;
+ { jj_save(86, xla); }
+ }
+
+ inline bool jj_2_88(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_88() || jj_done;
+ { jj_save(87, xla); }
+ }
+
+ inline bool jj_2_89(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_89() || jj_done;
+ { jj_save(88, xla); }
+ }
+
+ inline bool jj_2_90(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_90() || jj_done;
+ { jj_save(89, xla); }
+ }
+
+ inline bool jj_2_91(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_91() || jj_done;
+ { jj_save(90, xla); }
+ }
+
+ inline bool jj_2_92(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_92() || jj_done;
+ { jj_save(91, xla); }
+ }
+
+ inline bool jj_2_93(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_93() || jj_done;
+ { jj_save(92, xla); }
+ }
+
+ inline bool jj_2_94(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_94() || jj_done;
+ { jj_save(93, xla); }
+ }
+
+ inline bool jj_2_95(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_95() || jj_done;
+ { jj_save(94, xla); }
+ }
+
+ inline bool jj_2_96(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_96() || jj_done;
+ { jj_save(95, xla); }
+ }
+
+ inline bool jj_2_97(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_97() || jj_done;
+ { jj_save(96, xla); }
+ }
+
+ inline bool jj_2_98(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_98() || jj_done;
+ { jj_save(97, xla); }
+ }
+
+ inline bool jj_2_99(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_99() || jj_done;
+ { jj_save(98, xla); }
+ }
+
+ inline bool jj_2_100(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_100() || jj_done;
+ { jj_save(99, xla); }
+ }
+
+ inline bool jj_2_101(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_101() || jj_done;
+ { jj_save(100, xla); }
+ }
+
+ inline bool jj_2_102(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_102() || jj_done;
+ { jj_save(101, xla); }
+ }
+
+ inline bool jj_2_103(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_103() || jj_done;
+ { jj_save(102, xla); }
+ }
+
+ inline bool jj_2_104(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_104() || jj_done;
+ { jj_save(103, xla); }
+ }
+
+ inline bool jj_2_105(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_105() || jj_done;
+ { jj_save(104, xla); }
+ }
+
+ inline bool jj_2_106(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_106() || jj_done;
+ { jj_save(105, xla); }
+ }
+
+ inline bool jj_2_107(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_107() || jj_done;
+ { jj_save(106, xla); }
+ }
+
+ inline bool jj_2_108(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_108() || jj_done;
+ { jj_save(107, xla); }
+ }
+
+ inline bool jj_2_109(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_109() || jj_done;
+ { jj_save(108, xla); }
+ }
+
+ inline bool jj_2_110(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_110() || jj_done;
+ { jj_save(109, xla); }
+ }
+
+ inline bool jj_2_111(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_111() || jj_done;
+ { jj_save(110, xla); }
+ }
+
+ inline bool jj_2_112(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_112() || jj_done;
+ { jj_save(111, xla); }
+ }
+
+ inline bool jj_2_113(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_113() || jj_done;
+ { jj_save(112, xla); }
+ }
+
+ inline bool jj_2_114(int xla)
+ {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ jj_done = false;
+ return !jj_3_114() || jj_done;
+ { jj_save(113, xla); }
+ }
+
+ inline bool jj_3R_430()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(INOUT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_429()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OUT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_346()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_428()) {
+ jj_scanpos = xsp;
+ if (jj_3R_429()) {
+ jj_scanpos = xsp;
+ if (jj_3R_430()) {
+ jj_scanpos = xsp;
+ if (jj_3R_431()) {
+ jj_scanpos = xsp;
+ if (jj_3R_432()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_428()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(IN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_258()
+ {
+ if (jj_done) return true;
+ if (jj_3R_367()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_257()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_123()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_257()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_258()) jj_scanpos = xsp;
+ if (jj_scan_token(LOOP_T)) return true;
+ if (jj_3R_259()) return true;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(LOOP_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_625()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_45()
+ {
+ if (jj_done) return true;
+ if (jj_3R_97()) return true;
+ return false;
+ }
+
+ inline bool jj_3_44()
+ {
+ if (jj_done) return true;
+ if (jj_3R_96()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_233()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NULL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_43()
+ {
+ if (jj_done) return true;
+ if (jj_3R_95()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_232()
+ {
+ if (jj_done) return true;
+ if (jj_3R_356()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_231()
+ {
+ if (jj_done) return true;
+ if (jj_3R_97()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_230()
+ {
+ if (jj_done) return true;
+ if (jj_3R_96()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_229()
+ {
+ if (jj_done) return true;
+ if (jj_3R_95()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_107()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_229()) {
+ jj_scanpos = xsp;
+ if (jj_3R_230()) {
+ jj_scanpos = xsp;
+ if (jj_3R_231()) {
+ jj_scanpos = xsp;
+ if (jj_3R_232()) {
+ jj_scanpos = xsp;
+ if (jj_3R_233()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_42()
+ {
+ if (jj_done) return true;
+ if (jj_3R_94()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_140()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_199()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_444()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_408()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_367()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_443()) {
+ jj_scanpos = xsp;
+ if (jj_3R_444()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_443()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHILE_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_198()
+ {
+ if (jj_done) return true;
+ if (jj_3R_346()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_400()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ if (jj_3R_399()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_196()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(116)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(100)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(31)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(101)) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_91()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_196()) jj_scanpos = xsp;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_198()) jj_scanpos = xsp;
+ if (jj_3R_85()) return true;
+ xsp = jj_scanpos;
+ if (jj_scan_token(27)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_199()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_313()
+ {
+ if (jj_done) return true;
+ if (jj_3R_399()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_400()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_413()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_92()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FILE_T)) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_399()
+ {
+ if (jj_done) return true;
+ if (jj_3R_491()) return true;
+ return false;
+ }
+
+ inline bool jj_3_41()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_552()
+ {
+ if (jj_done) return true;
+ if (jj_3R_613()) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_551()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3_40()
+ {
+ if (jj_done) return true;
+ if (jj_3R_92()) return true;
+ return false;
+ }
+
+ inline bool jj_3_39()
+ {
+ if (jj_done) return true;
+ if (jj_3R_91()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_550()
+ {
+ if (jj_done) return true;
+ if (jj_3R_108()) return true;
+ return false;
+ }
+
+ inline bool jj_3_38()
+ {
+ if (jj_done) return true;
+ if (jj_3R_90()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_491()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_38()) {
+ jj_scanpos = xsp;
+ if (jj_3R_550()) {
+ jj_scanpos = xsp;
+ if (jj_3_39()) {
+ jj_scanpos = xsp;
+ if (jj_3_40()) {
+ jj_scanpos = xsp;
+ if (jj_3R_551()) {
+ jj_scanpos = xsp;
+ if (jj_3R_552()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_621()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_181()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_416()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ALL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_415()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OTHER_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_331()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_414()) {
+ jj_scanpos = xsp;
+ if (jj_3R_415()) {
+ jj_scanpos = xsp;
+ if (jj_3R_416()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_414()
+ {
+ if (jj_done) return true;
+ if (jj_3R_197()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_698()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_328()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONFIGURATION_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_327()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ENTITY_T)) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_413()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_174()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_326()) {
+ jj_scanpos = xsp;
+ if (jj_3R_327()) {
+ jj_scanpos = xsp;
+ if (jj_3R_328()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_37()
+ {
+ if (jj_done) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_326()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(28)) jj_scanpos = xsp;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_155()
+ {
+ if (jj_done) return true;
+ if (jj_3R_158()) return true;
+ if (jj_scan_token(RANGE_T)) return true;
+ if (jj_scan_token(BOX_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_427()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(IS_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_698()) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(145)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_618()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_617()
+ {
+ if (jj_done) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_565()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_617()) {
+ jj_scanpos = xsp;
+ if (jj_3R_618()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_83()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_69()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_181()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_620()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ELSE_T)) return true;
+ if (jj_3R_259()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_526()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TYPE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_619()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ELSIF_T)) return true;
+ if (jj_3R_80()) return true;
+ if (jj_scan_token(THEN_T)) return true;
+ if (jj_3R_259()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_345()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_514()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_313()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_255()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_121()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_255()) jj_scanpos = xsp;
+ if (jj_scan_token(IF_T)) return true;
+ if (jj_3R_80()) return true;
+ if (jj_scan_token(THEN_T)) return true;
+ if (jj_3R_259()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_619()) { jj_scanpos = xsp; break; }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_620()) jj_scanpos = xsp;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(IF_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_621()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_197()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_345()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_165()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BASIC_IDENTIFIER)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_164()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(EXTENDED_CHARACTER)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_70()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_164()) {
+ jj_scanpos = xsp;
+ if (jj_3R_165()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_539()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_538()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_425()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(77)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_514()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_114()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_66()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GROUP_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_475()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_386()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(134)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(137)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_447()
+ {
+ if (jj_done) return true;
+ if (jj_3R_523()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_383()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GROUP_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_476()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_524()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_449()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_540()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_305()
+ {
+ if (jj_done) return true;
+ if (jj_3R_384()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_476()
+ {
+ if (jj_done) return true;
+ if (jj_3R_538()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_539()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_426()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(84)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(52)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_344()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_426()) jj_scanpos = xsp;
+ if (jj_scan_token(FUNCTION_T)) return true;
+ if (jj_3R_60()) return true;
+ if (jj_3R_425()) return true;
+ if (jj_scan_token(RETURN_T)) return true;
+ if (jj_3R_60()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_427()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_171()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_608()
+ {
+ if (jj_done) return true;
+ if (jj_3R_352()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_607()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_538()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_607()) {
+ jj_scanpos = xsp;
+ if (jj_3R_608()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_71()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GENERIC_T)) return true;
+ if (jj_scan_token(MAP_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_166()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_304()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ if (jj_3R_385()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_343()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PROCEDURE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_3R_425()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_195()
+ {
+ if (jj_done) return true;
+ if (jj_3R_344()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_159()
+ {
+ if (jj_done) return true;
+ if (jj_3R_313()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_194()
+ {
+ if (jj_done) return true;
+ if (jj_3R_343()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_90()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_194()) {
+ jj_scanpos = xsp;
+ if (jj_3R_195()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_67()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GENERIC_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_159()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_477()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ELSE_T)) return true;
+ if (jj_3R_59()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_540()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_385()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ if (jj_3R_477()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_477()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_322()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(IF_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_169()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_321()) {
+ jj_scanpos = xsp;
+ if (jj_3R_322()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_321()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_408()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_384()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(53)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(75)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_448()
+ {
+ if (jj_done) return true;
+ if (jj_3R_405()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_449()
+ {
+ if (jj_done) return true;
+ if (jj_3R_446()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_524()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_464()
+ {
+ if (jj_done) return true;
+ if (jj_3R_528()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_75()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_169()) return true;
+ if (jj_scan_token(GENERATE_T)) return true;
+ if (jj_3R_170()) return true;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(GENERATE_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_171()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_306()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(134)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(137)) return true;
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_386()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_105()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_226()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_303()
+ {
+ if (jj_done) return true;
+ if (jj_3R_384()) return true;
+ return false;
+ }
+
+ inline bool jj_3_110()
+ {
+ if (jj_done) return true;
+ if (jj_3R_143()) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_145()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WITH_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SELECT_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(155)) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ if (jj_scan_token(FORCE_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_305()) jj_scanpos = xsp;
+ if (jj_3R_306()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_157()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_312()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_113()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_369()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WITH_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SELECT_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(155)) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_448()) jj_scanpos = xsp;
+ if (jj_3R_449()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_301()
+ {
+ if (jj_done) return true;
+ if (jj_3R_143()) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_689()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_137()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TYPE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_577()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_575()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_688()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_662()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_688()) {
+ jj_scanpos = xsp;
+ if (jj_3R_689()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_64()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_157()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_398()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(INTEGER)) return true;
+ return false;
+ }
+
+ inline bool jj_3_112()
+ {
+ if (jj_done) return true;
+ if (jj_3R_145()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_570()
+ {
+ if (jj_done) return true;
+ if (jj_3R_313()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_521()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WITH_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SELECT_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(155)) jj_scanpos = xsp;
+ if (jj_3R_662()) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_306()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_445()
+ {
+ if (jj_done) return true;
+ if (jj_3R_405()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_312()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_397()) {
+ jj_scanpos = xsp;
+ if (jj_3R_398()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_397()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_271()
+ {
+ if (jj_done) return true;
+ if (jj_3R_369()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_128()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_270()) {
+ jj_scanpos = xsp;
+ if (jj_3R_271()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_270()
+ {
+ if (jj_done) return true;
+ if (jj_3R_145()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_144()
+ {
+ if (jj_done) return true;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ if (jj_scan_token(FORCE_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_303()) jj_scanpos = xsp;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_304()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_654()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FILE_T)) return true;
+ if (jj_scan_token(OF_T)) return true;
+ if (jj_3R_158()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_523()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ELSE_T)) return true;
+ if (jj_3R_59()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_575()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_111()
+ {
+ if (jj_done) return true;
+ if (jj_3R_144()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_580()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OPEN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_528()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_580()) jj_scanpos = xsp;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_581()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_368()
+ {
+ if (jj_done) return true;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_445()) jj_scanpos = xsp;
+ if (jj_3R_446()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_59()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_447()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_269()
+ {
+ if (jj_done) return true;
+ if (jj_3R_368()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_581()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_127()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_268()) {
+ jj_scanpos = xsp;
+ if (jj_3R_269()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_268()
+ {
+ if (jj_done) return true;
+ if (jj_3R_144()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_450()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOUBLEMULT_T)) return true;
+ if (jj_3R_370()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_142()
+ {
+ if (jj_done) return true;
+ if (jj_3R_143()) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_301()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_549()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(AT_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_302()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_109()
+ {
+ if (jj_done) return true;
+ if (jj_3R_142()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_376()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FILE_T)) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_464()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_264()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_284()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NOT_T)) return true;
+ if (jj_3R_370()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_283()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ABS_T)) return true;
+ if (jj_3R_370()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_136()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_282()) {
+ jj_scanpos = xsp;
+ if (jj_3R_283()) {
+ jj_scanpos = xsp;
+ if (jj_3R_284()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_282()
+ {
+ if (jj_done) return true;
+ if (jj_3R_370()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_450()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_612()
+ {
+ if (jj_done) return true;
+ if (jj_3R_142()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_699()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_97()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_147()
+ {
+ if (jj_done) return true;
+ if (jj_3R_309()) return true;
+ if (jj_3R_146()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_143()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_302()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_394()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OR_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_393()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(XOR_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_392()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(XNOR_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_391()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NOR_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_636()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NEG_T)) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_390()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NAND_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_611()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ if (jj_3R_636()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_636()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_410()
+ {
+ if (jj_done) return true;
+ if (jj_3R_498()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_309()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_389()) {
+ jj_scanpos = xsp;
+ if (jj_3R_390()) {
+ jj_scanpos = xsp;
+ if (jj_3R_391()) {
+ jj_scanpos = xsp;
+ if (jj_3R_392()) {
+ jj_scanpos = xsp;
+ if (jj_3R_393()) {
+ jj_scanpos = xsp;
+ if (jj_3R_394()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_389()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(AND_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_108()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_142()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_548()
+ {
+ if (jj_done) return true;
+ if (jj_3R_611()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_612()) jj_scanpos = xsp;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_610()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_59()
+ {
+ if (jj_done) return true;
+ if (jj_3R_146()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_147()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_609()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_142()) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_547()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_609()) {
+ jj_scanpos = xsp;
+ if (jj_3R_610()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_490()
+ {
+ if (jj_done) return true;
+ if (jj_3R_549()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_489()
+ {
+ if (jj_done) return true;
+ if (jj_3R_548()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_396()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_488()) {
+ jj_scanpos = xsp;
+ if (jj_3R_489()) {
+ jj_scanpos = xsp;
+ if (jj_3R_490()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_488()
+ {
+ if (jj_done) return true;
+ if (jj_3R_547()) return true;
+ return false;
+ }
+
+ inline bool jj_3_105()
+ {
+ if (jj_done) return true;
+ if (jj_3R_139()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_265()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_263()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_487()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARIABLE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_125()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_263()) jj_scanpos = xsp;
+ if (jj_scan_token(EXIT_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_264()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_265()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_486()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SIGNAL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_395()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_485()) {
+ jj_scanpos = xsp;
+ if (jj_3R_486()) {
+ jj_scanpos = xsp;
+ if (jj_3R_487()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_485()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONSTANT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_690()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_97()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_699()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_275()
+ {
+ if (jj_done) return true;
+ if (jj_3R_133()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_209()
+ {
+ if (jj_done) return true;
+ if (jj_3R_352()) return true;
+ return false;
+ }
+
+ inline bool jj_3_107()
+ {
+ if (jj_done) return true;
+ if (jj_3R_141()) return true;
+ if (jj_scan_token(BEGIN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_208()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_97()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_208()) {
+ jj_scanpos = xsp;
+ if (jj_3R_209()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_311()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SLSL_T)) return true;
+ if (jj_3R_395()) return true;
+ if (jj_3R_396()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ if (jj_scan_token(RSRS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_411()
+ {
+ if (jj_done) return true;
+ if (jj_3R_498()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_697()
+ {
+ if (jj_done) return true;
+ if (jj_3R_352()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_324()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_411()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_409()
+ {
+ if (jj_done) return true;
+ if (jj_3R_141()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_696()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_683()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_696()) {
+ jj_scanpos = xsp;
+ if (jj_3R_697()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_170()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_323()) {
+ jj_scanpos = xsp;
+ if (jj_3R_324()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_323()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_409()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(BEGIN_T)) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_410()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3_36()
+ {
+ if (jj_done) return true;
+ if (jj_3R_89()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_285()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_687()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BEGIN_T)) return true;
+ if (jj_3R_687()) return true;
+ return false;
+ }
+
+ inline bool jj_3_35()
+ {
+ if (jj_done) return true;
+ if (jj_3R_88()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_235()
+ {
+ if (jj_done) return true;
+ if (jj_3R_133()) return true;
+ return false;
+ }
+
+ inline bool jj_3_106()
+ {
+ if (jj_done) return true;
+ if (jj_3R_140()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_139()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(END_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_285()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_637()
+ {
+ if (jj_done) return true;
+ if (jj_3R_133()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_661()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_106()) jj_scanpos = xsp;
+ if (jj_3R_86()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ if (jj_3R_687()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_649()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ if (jj_3R_661()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_661()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_471()
+ {
+ if (jj_done) return true;
+ if (jj_3R_533()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_534()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_684()
+ {
+ if (jj_done) return true;
+ if (jj_3R_234()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_585()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ALL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_584()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OTHER_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_615()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CASE_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(GENERATE_T)) return true;
+ if (jj_3R_649()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_634()
+ {
+ if (jj_done) return true;
+ if (jj_3R_656()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_583()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ if (jj_3R_634()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_634()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_533()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_583()) {
+ jj_scanpos = xsp;
+ if (jj_3R_584()) {
+ jj_scanpos = xsp;
+ if (jj_3R_585()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_656()
+ {
+ if (jj_done) return true;
+ if (jj_3R_683()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_684()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_132()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GENERIC_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_313()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_133()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GENERIC_T)) return true;
+ if (jj_scan_token(MAP_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_166()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_32()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3_34()
+ {
+ if (jj_done) return true;
+ if (jj_3R_87()) return true;
+ return false;
+ }
+
+ inline bool jj_3_33()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_537()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_536()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_131()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FUNCTION_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_scan_token(NEW_T)) return true;
+ if (jj_3R_60()) return true;
+ if (jj_3R_234()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_275()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_108()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PACKAGE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_scan_token(NEW_T)) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_637()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_87()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PACKAGE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_scan_token(NEW_T)) return true;
+ if (jj_3R_60()) return true;
+ if (jj_3R_234()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_235()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_606()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BOX_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_349()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ENTITY_T)) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_682()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_475()
+ {
+ if (jj_done) return true;
+ if (jj_3R_536()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_537()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_254()
+ {
+ if (jj_done) return true;
+ if (jj_3R_366()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_536()
+ {
+ if (jj_done) return true;
+ if (jj_3R_534()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_606()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_616()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_602()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FILE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_695()
+ {
+ if (jj_done) return true;
+ if (jj_3R_705()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_601()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GROUP_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_681()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_695()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_600()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(UNITS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_599()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LITERAL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_598()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LABEL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_722()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_597()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMPONENT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_721()
+ {
+ if (jj_done) return true;
+ if (jj_3R_379()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_596()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARIABLE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_595()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SIGNAL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_594()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONSTANT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_720()
+ {
+ if (jj_done) return true;
+ if (jj_3R_347()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_705()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_720()) {
+ jj_scanpos = xsp;
+ if (jj_3R_721()) {
+ jj_scanpos = xsp;
+ if (jj_3R_722()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_593()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SUBTYPE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_592()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TYPE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_591()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PACKAGE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_590()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FUNCTION_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_589()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PROCEDURE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_680()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_588()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONFIGURATION_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_587()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ARCHITECTURE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_586()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ENTITY_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_534()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_586()) {
+ jj_scanpos = xsp;
+ if (jj_3R_587()) {
+ jj_scanpos = xsp;
+ if (jj_3R_588()) {
+ jj_scanpos = xsp;
+ if (jj_3R_589()) {
+ jj_scanpos = xsp;
+ if (jj_3R_590()) {
+ jj_scanpos = xsp;
+ if (jj_3R_591()) {
+ jj_scanpos = xsp;
+ if (jj_3R_592()) {
+ jj_scanpos = xsp;
+ if (jj_3R_593()) {
+ jj_scanpos = xsp;
+ if (jj_3R_594()) {
+ jj_scanpos = xsp;
+ if (jj_3R_595()) {
+ jj_scanpos = xsp;
+ if (jj_3R_596()) {
+ jj_scanpos = xsp;
+ if (jj_3R_597()) {
+ jj_scanpos = xsp;
+ if (jj_3R_598()) {
+ jj_scanpos = xsp;
+ if (jj_3R_599()) {
+ jj_scanpos = xsp;
+ if (jj_3R_600()) {
+ jj_scanpos = xsp;
+ if (jj_3R_601()) {
+ jj_scanpos = xsp;
+ if (jj_3R_602()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_253()
+ {
+ if (jj_done) return true;
+ if (jj_3R_365()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_655()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PROTECTED_T)) return true;
+ if (jj_3R_681()) return true;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(PROTECTED_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_682()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_103()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_564()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OPEN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_563()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONFIGURATION_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_694()
+ {
+ if (jj_done) return true;
+ if (jj_3R_704()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_679()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_694()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_562()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ENTITY_T)) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_616()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_500()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_562()) {
+ jj_scanpos = xsp;
+ if (jj_3R_563()) {
+ jj_scanpos = xsp;
+ if (jj_3R_564()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_719()
+ {
+ if (jj_done) return true;
+ if (jj_3R_383()) return true;
+ return false;
+ }
+
+ inline bool jj_3_31()
+ {
+ if (jj_done) return true;
+ if (jj_3R_86()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_716()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_707()
+ {
+ if (jj_done) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_104()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_718()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_717()
+ {
+ if (jj_done) return true;
+ if (jj_3R_379()) return true;
+ return false;
+ }
+
+ inline bool jj_3_30()
+ {
+ if (jj_done) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_715()
+ {
+ if (jj_done) return true;
+ if (jj_3R_377()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_714()
+ {
+ if (jj_done) return true;
+ if (jj_3R_376()) return true;
+ return false;
+ }
+
+ inline bool jj_3_29()
+ {
+ if (jj_done) return true;
+ if (jj_3R_84()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_713()
+ {
+ if (jj_done) return true;
+ if (jj_3R_375()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_712()
+ {
+ if (jj_done) return true;
+ if (jj_3R_373()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_359()
+ {
+ if (jj_done) return true;
+ if (jj_3R_86()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_711()
+ {
+ if (jj_done) return true;
+ if (jj_3R_372()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_236()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_359()) jj_scanpos = xsp;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_710()
+ {
+ if (jj_done) return true;
+ if (jj_3R_371()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_708()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_704()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_708()) {
+ jj_scanpos = xsp;
+ if (jj_3R_709()) {
+ jj_scanpos = xsp;
+ if (jj_3R_710()) {
+ jj_scanpos = xsp;
+ if (jj_3R_711()) {
+ jj_scanpos = xsp;
+ if (jj_3R_712()) {
+ jj_scanpos = xsp;
+ if (jj_3R_713()) {
+ jj_scanpos = xsp;
+ if (jj_3R_714()) {
+ jj_scanpos = xsp;
+ if (jj_3R_715()) {
+ jj_scanpos = xsp;
+ if (jj_3R_716()) {
+ jj_scanpos = xsp;
+ if (jj_3R_717()) {
+ jj_scanpos = xsp;
+ if (jj_3R_718()) {
+ jj_scanpos = xsp;
+ if (jj_3_104()) {
+ jj_scanpos = xsp;
+ if (jj_3R_719()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_709()
+ {
+ if (jj_done) return true;
+ if (jj_3R_519()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_163()
+ {
+ if (jj_done) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_252()
+ {
+ if (jj_done) return true;
+ if (jj_3R_364()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_162()
+ {
+ if (jj_done) return true;
+ if (jj_3R_84()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_69()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_162()) {
+ jj_scanpos = xsp;
+ if (jj_3R_163()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_522()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(AFTER_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_472()
+ {
+ if (jj_done) return true;
+ if (jj_3R_535()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_138()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PROTECTED_T)) return true;
+ if (jj_scan_token(BODY_T)) return true;
+ if (jj_3R_679()) return true;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(PROTECTED_T)) return true;
+ if (jj_scan_token(BODY_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_680()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_497()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_446()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_381()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DISCONNECT_T)) return true;
+ if (jj_3R_472()) return true;
+ if (jj_scan_token(AFTER_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_460()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_239()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOWNTO_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_110()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_238()) {
+ jj_scanpos = xsp;
+ if (jj_3R_239()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_238()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TO_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_569()
+ {
+ if (jj_done) return true;
+ if (jj_3R_310()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_446()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_522()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_568()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_515()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_568()) {
+ jj_scanpos = xsp;
+ if (jj_3R_569()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_407()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(UNAFFECTED_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_318()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_406()) {
+ jj_scanpos = xsp;
+ if (jj_3R_407()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_406()
+ {
+ if (jj_done) return true;
+ if (jj_3R_446()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_497()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_553()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(REJECT_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_251()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_496()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_553()) jj_scanpos = xsp;
+ if (jj_scan_token(INERTIAL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_118()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_251()) jj_scanpos = xsp;
+ if (jj_scan_token(WAIT_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_252()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_253()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_254()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_28()
+ {
+ if (jj_done) return true;
+ if (jj_3R_83()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_405()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_495()) {
+ jj_scanpos = xsp;
+ if (jj_3R_496()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_495()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TRANSPORT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_27()
+ {
+ if (jj_done) return true;
+ if (jj_3R_82()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_277()
+ {
+ if (jj_done) return true;
+ if (jj_3R_83()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_156()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_155()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_134()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_276()) {
+ jj_scanpos = xsp;
+ if (jj_3R_277()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_276()
+ {
+ if (jj_done) return true;
+ if (jj_3R_82()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_463()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_375()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(101)) jj_scanpos = xsp;
+ if (jj_scan_token(VARIABLE_T)) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_463()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_474()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_473()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_706()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ARRAY_T)) return true;
+ if (jj_3R_83()) return true;
+ if (jj_scan_token(OF_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_441()
+ {
+ if (jj_done) return true;
+ if (jj_3R_521()) return true;
+ return false;
+ }
+
+ inline bool jj_3_102()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_362()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_440()) {
+ jj_scanpos = xsp;
+ if (jj_3R_441()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_440()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_102()) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_373()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONSTANT_T)) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_460()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_26()
+ {
+ if (jj_done) return true;
+ if (jj_3R_81()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_380()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_178()) return true;
+ if (jj_3R_332()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_567()
+ {
+ if (jj_done) return true;
+ if (jj_3R_333()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_382()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(USE_T)) return true;
+ if (jj_3R_473()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_474()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_566()
+ {
+ if (jj_done) return true;
+ if (jj_3R_81()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_502()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_566()) {
+ jj_scanpos = xsp;
+ if (jj_3R_567()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_63()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ARRAY_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_155()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_156()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ if (jj_scan_token(OF_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_158()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_633()
+ {
+ if (jj_done) return true;
+ if (jj_3R_655()) return true;
+ return false;
+ }
+
+ inline bool jj_3_101()
+ {
+ if (jj_done) return true;
+ if (jj_3R_138()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_632()
+ {
+ if (jj_done) return true;
+ if (jj_3R_654()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_631()
+ {
+ if (jj_done) return true;
+ if (jj_3R_653()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_630()
+ {
+ if (jj_done) return true;
+ if (jj_3R_652()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_629()
+ {
+ if (jj_done) return true;
+ if (jj_3R_651()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_577()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_629()) {
+ jj_scanpos = xsp;
+ if (jj_3R_630()) {
+ jj_scanpos = xsp;
+ if (jj_3R_631()) {
+ jj_scanpos = xsp;
+ if (jj_3R_632()) {
+ jj_scanpos = xsp;
+ if (jj_3_101()) {
+ jj_scanpos = xsp;
+ if (jj_3R_633()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_25()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_80()) return true;
+ if (jj_scan_token(ELSE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_350()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONFIGURATION_T)) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3_97()
+ {
+ if (jj_done) return true;
+ if (jj_3R_134()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_459()
+ {
+ if (jj_done) return true;
+ if (jj_3R_526()) return true;
+ return false;
+ }
+
+ inline bool jj_3_100()
+ {
+ if (jj_done) return true;
+ if (jj_3R_137()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_371()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_100()) {
+ jj_scanpos = xsp;
+ if (jj_3R_459()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_320()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_106()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_319()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_80()) return true;
+ if (jj_scan_token(ELSE_T)) return true;
+ if (jj_3R_318()) return true;
+ return false;
+ }
+
+ inline bool jj_3_99()
+ {
+ if (jj_done) return true;
+ if (jj_3R_135()) return true;
+ if (jj_3R_136()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_185()
+ {
+ if (jj_done) return true;
+ if (jj_3R_134()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_168()
+ {
+ if (jj_done) return true;
+ if (jj_3R_318()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_319()) { jj_scanpos = xsp; break; }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_320()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_366()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_72()
+ {
+ if (jj_done) return true;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ if (jj_3R_167()) return true;
+ if (jj_3R_168()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_130()
+ {
+ if (jj_done) return true;
+ if (jj_3R_136()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_99()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_247()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_365()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(UNTIL_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_115()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_246()) {
+ jj_scanpos = xsp;
+ if (jj_3R_247()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3_98()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_246()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3_96()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_218()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ALL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_80()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_217()
+ {
+ if (jj_done) return true;
+ if (jj_3R_310()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_216()
+ {
+ if (jj_done) return true;
+ if (jj_3R_352()) return true;
+ return false;
+ }
+
+ inline bool jj_3_24()
+ {
+ if (jj_done) return true;
+ if (jj_3R_79()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_215()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_100()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_215()) {
+ jj_scanpos = xsp;
+ if (jj_3R_216()) {
+ jj_scanpos = xsp;
+ if (jj_3R_217()) {
+ jj_scanpos = xsp;
+ if (jj_3R_218()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_23()
+ {
+ if (jj_done) return true;
+ if (jj_3R_78()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_184()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3_22()
+ {
+ if (jj_done) return true;
+ if (jj_3R_77()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_85()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_184()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_185()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_76()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_21()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_76()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_scan_token(ASSERT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_561()
+ {
+ if (jj_done) return true;
+ if (jj_3R_79()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_560()
+ {
+ if (jj_done) return true;
+ if (jj_3R_78()) return true;
+ return false;
+ }
+
+ inline bool jj_3_20()
+ {
+ if (jj_done) return true;
+ if (jj_3R_75()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_559()
+ {
+ if (jj_done) return true;
+ if (jj_3R_77()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_74()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_372()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SUBTYPE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_85()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_19()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_74()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_scan_token(PROCESS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_627()
+ {
+ if (jj_done) return true;
+ if (jj_3R_113()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_572()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_627()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_558()
+ {
+ if (jj_done) return true;
+ if (jj_3R_88()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_73()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_18()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_73()) jj_scanpos = xsp;
+ if (jj_scan_token(BLOCK_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_95()
+ {
+ if (jj_done) return true;
+ if (jj_3R_133()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_516()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_313()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_557()
+ {
+ if (jj_done) return true;
+ if (jj_3R_615()) return true;
+ return false;
+ }
+
+ inline bool jj_3_94()
+ {
+ if (jj_done) return true;
+ if (jj_3R_132()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_556()
+ {
+ if (jj_done) return true;
+ if (jj_3R_75()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_555()
+ {
+ if (jj_done) return true;
+ if (jj_3R_89()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_554()
+ {
+ if (jj_done) return true;
+ if (jj_3R_614()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_498()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_554()) {
+ jj_scanpos = xsp;
+ if (jj_3R_555()) {
+ jj_scanpos = xsp;
+ if (jj_3R_556()) {
+ jj_scanpos = xsp;
+ if (jj_3R_557()) {
+ jj_scanpos = xsp;
+ if (jj_3R_558()) {
+ jj_scanpos = xsp;
+ if (jj_3R_559()) {
+ jj_scanpos = xsp;
+ if (jj_3R_560()) {
+ jj_scanpos = xsp;
+ if (jj_3R_561()) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(186)) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_518()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_570()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_17()
+ {
+ if (jj_done) return true;
+ if (jj_3R_72()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_173()
+ {
+ if (jj_done) return true;
+ if (jj_3R_325()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_517()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(84)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(52)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_172()
+ {
+ if (jj_done) return true;
+ if (jj_3R_72()) return true;
+ return false;
+ }
+
+ inline bool jj_3_16()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_434()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_517()) jj_scanpos = xsp;
+ if (jj_scan_token(FUNCTION_T)) return true;
+ if (jj_3R_515()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_518()) jj_scanpos = xsp;
+ if (jj_scan_token(RETURN_T)) return true;
+ if (jj_3R_158()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_77()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_16()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_172()) {
+ jj_scanpos = xsp;
+ if (jj_3R_173()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3_15()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_79()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_15()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_3R_177()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_14()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_13()
+ {
+ if (jj_done) return true;
+ if (jj_3R_71()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_88()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_14()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_3R_188()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_678()
+ {
+ if (jj_done) return true;
+ if (jj_3R_693()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_470()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_347()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_433()) {
+ jj_scanpos = xsp;
+ if (jj_3R_434()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_433()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PROCEDURE_T)) return true;
+ if (jj_3R_515()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_516()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3_94()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3_95()) jj_scanpos = xsp;
+ if (jj_3R_425()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_677()
+ {
+ if (jj_done) return true;
+ if (jj_3R_692()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_652()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_677()) {
+ jj_scanpos = xsp;
+ if (jj_3R_678()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_176()
+ {
+ if (jj_done) return true;
+ if (jj_3R_329()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_175()
+ {
+ if (jj_done) return true;
+ if (jj_3R_71()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_628()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(46)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(80)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_178()
+ {
+ if (jj_done) return true;
+ if (jj_3R_331()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_626()
+ {
+ if (jj_done) return true;
+ if (jj_3R_650()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_571()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_626()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3_92()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_674()
+ {
+ if (jj_done) return true;
+ if (jj_3R_383()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_673()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_78()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_174()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_175()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_176()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_93()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_672()
+ {
+ if (jj_done) return true;
+ if (jj_3R_379()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_671()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_670()
+ {
+ if (jj_done) return true;
+ if (jj_3R_377()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_669()
+ {
+ if (jj_done) return true;
+ if (jj_3R_376()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_668()
+ {
+ if (jj_done) return true;
+ if (jj_3R_375()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_574()
+ {
+ if (jj_done) return true;
+ if (jj_3R_515()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_667()
+ {
+ if (jj_done) return true;
+ if (jj_3R_373()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_469()
+ {
+ if (jj_done) return true;
+ if (jj_3R_532()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_666()
+ {
+ if (jj_done) return true;
+ if (jj_3R_372()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_665()
+ {
+ if (jj_done) return true;
+ if (jj_3R_519()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_468()
+ {
+ if (jj_done) return true;
+ if (jj_3R_67()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_180()
+ {
+ if (jj_done) return true;
+ if (jj_3R_333()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_179()
+ {
+ if (jj_done) return true;
+ if (jj_3R_332()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_664()
+ {
+ if (jj_done) return true;
+ if (jj_3R_371()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_187()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BAR_T)) return true;
+ if (jj_3R_186()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_663()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_650()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_663()) {
+ jj_scanpos = xsp;
+ if (jj_3R_664()) {
+ jj_scanpos = xsp;
+ if (jj_3R_665()) {
+ jj_scanpos = xsp;
+ if (jj_3R_666()) {
+ jj_scanpos = xsp;
+ if (jj_3R_667()) {
+ jj_scanpos = xsp;
+ if (jj_3R_668()) {
+ jj_scanpos = xsp;
+ if (jj_3R_669()) {
+ jj_scanpos = xsp;
+ if (jj_3R_670()) {
+ jj_scanpos = xsp;
+ if (jj_3R_671()) {
+ jj_scanpos = xsp;
+ if (jj_3R_672()) {
+ jj_scanpos = xsp;
+ if (jj_3R_673()) {
+ jj_scanpos = xsp;
+ if (jj_3_93()) {
+ jj_scanpos = xsp;
+ if (jj_3R_674()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_378()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMPONENT_T)) return true;
+ if (jj_3R_70()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(56)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_468()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_469()) jj_scanpos = xsp;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(COMPONENT_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_470()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_462()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_81()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_178()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_179()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_180()) jj_scanpos = xsp;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_91()
+ {
+ if (jj_done) return true;
+ if (jj_3R_131()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_348()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_435()) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(137)) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_435()
+ {
+ if (jj_done) return true;
+ if (jj_3R_519()) return true;
+ return false;
+ }
+
+ inline bool jj_3_12()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3_11()
+ {
+ if (jj_done) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_86()
+ {
+ if (jj_done) return true;
+ if (jj_3R_186()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_187()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_201()
+ {
+ if (jj_done) return true;
+ if (jj_3R_347()) return true;
+ if (jj_3R_348()) return true;
+ return false;
+ }
+
+ inline bool jj_3_10()
+ {
+ if (jj_done) return true;
+ if (jj_3R_68()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_337()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OTHER_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_573()
+ {
+ if (jj_done) return true;
+ if (jj_3R_628()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_200()
+ {
+ if (jj_done) return true;
+ if (jj_3R_131()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_93()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_200()) {
+ jj_scanpos = xsp;
+ if (jj_3R_201()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3_90()
+ {
+ if (jj_done) return true;
+ if (jj_3R_129()) return true;
+ if (jj_3R_130()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_624()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_336()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_335()
+ {
+ if (jj_done) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_186()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_334()) {
+ jj_scanpos = xsp;
+ if (jj_3R_335()) {
+ jj_scanpos = xsp;
+ if (jj_3R_336()) {
+ jj_scanpos = xsp;
+ if (jj_3R_337()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_334()
+ {
+ if (jj_done) return true;
+ if (jj_3R_68()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_461()
+ {
+ if (jj_done) return true;
+ if (jj_3R_527()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_161()
+ {
+ if (jj_done) return true;
+ if (jj_3R_129()) return true;
+ if (jj_3R_130()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_648()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_352()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CHARACTER_LITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_644()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_519()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_571()) return true;
+ if (jj_scan_token(BEGIN_T)) return true;
+ if (jj_3R_572()) return true;
+ if (jj_scan_token(END_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_573()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_574()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_622()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ if (jj_3R_259()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_623()
+ {
+ if (jj_done) return true;
+ if (jj_3R_622()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_685()
+ {
+ if (jj_done) return true;
+ if (jj_3R_71()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_356()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(STRINGLITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_436()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_160()
+ {
+ if (jj_done) return true;
+ if (jj_3R_314()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_256()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_68()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_160()) jj_scanpos = xsp;
+ if (jj_3R_130()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_161()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_122()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_256()) jj_scanpos = xsp;
+ if (jj_scan_token(CASE_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_622()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_623()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(CASE_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_624()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_660()
+ {
+ if (jj_done) return true;
+ if (jj_3R_498()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_647()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_660()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_358()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(RETURN_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_635()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_357()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_436()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_234()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LBRACKET_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_357()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_358()) jj_scanpos = xsp;
+ if (jj_scan_token(RBRACKET_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_686()
+ {
+ if (jj_done) return true;
+ if (jj_3R_329()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_605()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ALL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_604()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OTHER_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_603()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_635()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_535()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_603()) {
+ jj_scanpos = xsp;
+ if (jj_3R_604()) {
+ jj_scanpos = xsp;
+ if (jj_3R_605()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_501()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_565()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_579()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BUS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_614()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_scan_token(BLOCK_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_644()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(56)) jj_scanpos = xsp;
+ if (jj_3R_645()) return true;
+ if (jj_3R_646()) return true;
+ if (jj_scan_token(BEGIN_T)) return true;
+ if (jj_3R_647()) return true;
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(BLOCK_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_648()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_578()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(REGISTER_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_527()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_578()) {
+ jj_scanpos = xsp;
+ if (jj_3R_579()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3_9()
+ {
+ if (jj_done) return true;
+ if (jj_3R_67()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_420()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_501()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_658()
+ {
+ if (jj_done) return true;
+ if (jj_3R_532()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_686()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_657()
+ {
+ if (jj_done) return true;
+ if (jj_3R_67()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_685()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_645()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_657()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_658()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_659()
+ {
+ if (jj_done) return true;
+ if (jj_3R_141()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_374()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SIGNAL_T)) return true;
+ if (jj_3R_197()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_461()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_462()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_646()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_659()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_300()
+ {
+ if (jj_done) return true;
+ if (jj_3R_383()) return true;
+ return false;
+ }
+
+ inline bool jj_3_89()
+ {
+ if (jj_done) return true;
+ if (jj_3R_128()) return true;
+ return false;
+ }
+
+ inline bool jj_3_7()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3_88()
+ {
+ if (jj_done) return true;
+ if (jj_3R_127()) return true;
+ return false;
+ }
+
+ inline bool jj_3_8()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_299()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_520()
+ {
+ if (jj_done) return true;
+ if (jj_3R_405()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_298()
+ {
+ if (jj_done) return true;
+ if (jj_3R_381()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_297()
+ {
+ if (jj_done) return true;
+ if (jj_3R_380()) return true;
+ return false;
+ }
+
+ inline bool jj_3_87()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_296()
+ {
+ if (jj_done) return true;
+ if (jj_3R_379()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_439()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_87()) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_520()) jj_scanpos = xsp;
+ if (jj_3R_318()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_438()
+ {
+ if (jj_done) return true;
+ if (jj_3R_128()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_294()
+ {
+ if (jj_done) return true;
+ if (jj_3R_378()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_295()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_387()
+ {
+ if (jj_done) return true;
+ if (jj_3R_478()) return true;
+ if (jj_3R_68()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_293()
+ {
+ if (jj_done) return true;
+ if (jj_3R_377()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_292()
+ {
+ if (jj_done) return true;
+ if (jj_3R_376()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_361()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_437()) {
+ jj_scanpos = xsp;
+ if (jj_3R_438()) {
+ jj_scanpos = xsp;
+ if (jj_3R_439()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_437()
+ {
+ if (jj_done) return true;
+ if (jj_3R_127()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_291()
+ {
+ if (jj_done) return true;
+ if (jj_3R_375()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_290()
+ {
+ if (jj_done) return true;
+ if (jj_3R_374()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_289()
+ {
+ if (jj_done) return true;
+ if (jj_3R_373()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_288()
+ {
+ if (jj_done) return true;
+ if (jj_3R_372()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_287()
+ {
+ if (jj_done) return true;
+ if (jj_3R_371()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_422()
+ {
+ if (jj_done) return true;
+ if (jj_3R_502()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_402()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(MINUS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_421()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_141()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_286()) {
+ jj_scanpos = xsp;
+ if (jj_3R_287()) {
+ jj_scanpos = xsp;
+ if (jj_3R_288()) {
+ jj_scanpos = xsp;
+ if (jj_3R_289()) {
+ jj_scanpos = xsp;
+ if (jj_3R_290()) {
+ jj_scanpos = xsp;
+ if (jj_3R_291()) {
+ jj_scanpos = xsp;
+ if (jj_3R_292()) {
+ jj_scanpos = xsp;
+ if (jj_3R_293()) {
+ jj_scanpos = xsp;
+ if (jj_3R_294()) {
+ jj_scanpos = xsp;
+ if (jj_3R_295()) {
+ jj_scanpos = xsp;
+ if (jj_3R_296()) {
+ jj_scanpos = xsp;
+ if (jj_3R_297()) {
+ jj_scanpos = xsp;
+ if (jj_3R_298()) {
+ jj_scanpos = xsp;
+ if (jj_3R_299()) {
+ jj_scanpos = xsp;
+ if (jj_3_8()) {
+ jj_scanpos = xsp;
+ if (jj_3R_300()) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(186)) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_286()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_314()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_401()) {
+ jj_scanpos = xsp;
+ if (jj_3R_402()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_401()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PLUS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_546()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ROR_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_545()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ROL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_544()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SRA_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_543()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SLA_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_333()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_3R_420()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_421()) { jj_scanpos = xsp; break; }
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_422()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(FOR_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_542()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SRL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_541()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SLL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_478()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_541()) {
+ jj_scanpos = xsp;
+ if (jj_3R_542()) {
+ jj_scanpos = xsp;
+ if (jj_3R_543()) {
+ jj_scanpos = xsp;
+ if (jj_3R_544()) {
+ jj_scanpos = xsp;
+ if (jj_3R_545()) {
+ jj_scanpos = xsp;
+ if (jj_3R_546()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_245()
+ {
+ if (jj_done) return true;
+ if (jj_3R_363()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_307()
+ {
+ if (jj_done) return true;
+ if (jj_3R_68()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_387()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_95()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BIT_STRING_LITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_240()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_85()
+ {
+ if (jj_done) return true;
+ if (jj_3R_125()) return true;
+ return false;
+ }
+
+ inline bool jj_3_86()
+ {
+ if (jj_done) return true;
+ if (jj_3R_126()) return true;
+ return false;
+ }
+
+ inline bool jj_3_84()
+ {
+ if (jj_done) return true;
+ if (jj_3R_124()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_419()
+ {
+ if (jj_done) return true;
+ if (jj_3R_329()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_418()
+ {
+ if (jj_done) return true;
+ if (jj_3R_71()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_417()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(USE_T)) return true;
+ if (jj_3R_500()) return true;
+ return false;
+ }
+
+ inline bool jj_3_83()
+ {
+ if (jj_done) return true;
+ if (jj_3R_123()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_332()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_417()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_418()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_419()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_119()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_82()
+ {
+ if (jj_done) return true;
+ if (jj_3R_122()) return true;
+ return false;
+ }
+
+ inline bool jj_3_79()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_119()) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(VARASSIGN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_81()
+ {
+ if (jj_done) return true;
+ if (jj_3R_121()) return true;
+ return false;
+ }
+
+ inline bool jj_3_80()
+ {
+ if (jj_done) return true;
+ if (jj_3R_120()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_114()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_78()
+ {
+ if (jj_done) return true;
+ if (jj_3R_118()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_244()
+ {
+ if (jj_done) return true;
+ if (jj_3R_362()) return true;
+ return false;
+ }
+
+ inline bool jj_3_75()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_114()) jj_scanpos = xsp;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_77()
+ {
+ if (jj_done) return true;
+ if (jj_3R_117()) return true;
+ return false;
+ }
+
+ inline bool jj_3_76()
+ {
+ if (jj_done) return true;
+ if (jj_3R_116()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_499()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_318()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_113()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_243()) {
+ jj_scanpos = xsp;
+ if (jj_3_76()) {
+ jj_scanpos = xsp;
+ if (jj_3_77()) {
+ jj_scanpos = xsp;
+ if (jj_3_78()) {
+ jj_scanpos = xsp;
+ if (jj_3R_244()) {
+ jj_scanpos = xsp;
+ if (jj_3_80()) {
+ jj_scanpos = xsp;
+ if (jj_3_81()) {
+ jj_scanpos = xsp;
+ if (jj_3_82()) {
+ jj_scanpos = xsp;
+ if (jj_3_83()) {
+ jj_scanpos = xsp;
+ if (jj_3_84()) {
+ jj_scanpos = xsp;
+ if (jj_3_85()) {
+ jj_scanpos = xsp;
+ if (jj_3_86()) {
+ jj_scanpos = xsp;
+ if (jj_3R_245()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_243()
+ {
+ if (jj_done) return true;
+ if (jj_3R_361()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_503()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_339()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SEVERITY_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3_74()
+ {
+ if (jj_done) return true;
+ if (jj_3R_113()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_259()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_74()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_267()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_423()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_503()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_379()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ATTRIBUTE_T)) return true;
+ if (jj_3R_220()) return true;
+ if (jj_scan_token(OF_T)) return true;
+ if (jj_3R_471()) return true;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_316()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_315()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_111()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(APOSTROPHE_T)) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_240()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_73()
+ {
+ if (jj_done) return true;
+ if (jj_3R_112()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_364()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ON_T)) return true;
+ if (jj_3R_423()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_355()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(RANGE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_220()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_354()) {
+ jj_scanpos = xsp;
+ if (jj_3R_355()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_354()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_412()
+ {
+ if (jj_done) return true;
+ if (jj_3R_318()) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_86()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_499()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_691()
+ {
+ if (jj_done) return true;
+ if (jj_3R_112()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_325()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WITH_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(SELECT_T)) return true;
+ if (jj_3R_115()) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ if (jj_3R_167()) return true;
+ if (jj_3R_412()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_6()
+ {
+ if (jj_done) return true;
+ if (jj_3R_64()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_65()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ATTRIBUTE_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_158()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_338()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(REPORT_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_473()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_100()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_166()
+ {
+ if (jj_done) return true;
+ if (jj_3R_315()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_316()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_360()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(EQU_T)) return true;
+ if (jj_3R_103()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_403()
+ {
+ if (jj_done) return true;
+ if (jj_3R_64()) return true;
+ if (jj_scan_token(ARROW_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_315()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_403()) jj_scanpos = xsp;
+ if (jj_3R_404()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_248()
+ {
+ if (jj_done) return true;
+ if (jj_3R_140()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_676()
+ {
+ if (jj_done) return true;
+ if (jj_3R_82()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_691()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_116()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_248()) jj_scanpos = xsp;
+ if (jj_3R_188()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_675()
+ {
+ if (jj_done) return true;
+ if (jj_3R_690()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_651()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_675()) {
+ jj_scanpos = xsp;
+ if (jj_3R_676()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_266()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_188()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ASSERT_T)) return true;
+ if (jj_3R_80()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_338()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_339()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_126()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_266()) jj_scanpos = xsp;
+ if (jj_scan_token(RETURN_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_267()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_5()
+ {
+ if (jj_done) return true;
+ if (jj_3R_63()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_250()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SEVERITY_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_701()
+ {
+ if (jj_done) return true;
+ if (jj_3R_706()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_308()
+ {
+ if (jj_done) return true;
+ if (jj_3R_388()) return true;
+ if (jj_3R_307()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_703()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_700()
+ {
+ if (jj_done) return true;
+ if (jj_3R_63()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_692()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_700()) {
+ jj_scanpos = xsp;
+ if (jj_3R_701()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_249()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_117()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_249()) jj_scanpos = xsp;
+ if (jj_scan_token(REPORT_T)) return true;
+ if (jj_3R_59()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_250()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_484()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NOTEQU_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_483()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LESSTHAN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_482()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GREATERTHAN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_481()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(EQU_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_480()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(GT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_388()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_479()) {
+ jj_scanpos = xsp;
+ if (jj_3R_480()) {
+ jj_scanpos = xsp;
+ if (jj_3R_481()) {
+ jj_scanpos = xsp;
+ if (jj_3R_482()) {
+ jj_scanpos = xsp;
+ if (jj_3R_483()) {
+ jj_scanpos = xsp;
+ if (jj_3R_484()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_479()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_702()
+ {
+ if (jj_done) return true;
+ if (jj_3R_707()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_467()
+ {
+ if (jj_done) return true;
+ if (jj_3R_234()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_146()
+ {
+ if (jj_done) return true;
+ if (jj_3R_307()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_308()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_693()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(RECORD_T)) return true;
+ Token * xsp;
+ if (jj_3R_702()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_702()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(RECORD_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_703()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_237()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_236()) return true;
+ return false;
+ }
+
+ inline bool jj_3_71()
+ {
+ if (jj_done) return true;
+ if (jj_3R_68()) return true;
+ if (jj_3R_110()) return true;
+ if (jj_3R_68()) return true;
+ return false;
+ }
+
+ inline bool jj_3_72()
+ {
+ if (jj_done) return true;
+ if (jj_3R_111()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_82()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(RANGE_T)) return true;
+ if (jj_3R_84()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_576()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NEW_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3_70()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_183()
+ {
+ if (jj_done) return true;
+ if (jj_3R_111()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_228()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_182()
+ {
+ if (jj_done) return true;
+ if (jj_3R_68()) return true;
+ if (jj_3R_110()) return true;
+ if (jj_3R_68()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_84()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_182()) {
+ jj_scanpos = xsp;
+ if (jj_3R_183()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_525()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_4()) {
+ jj_scanpos = xsp;
+ if (jj_3R_576()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3_4()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(NEW_T)) return true;
+ if (jj_3R_62()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_531()
+ {
+ if (jj_done) return true;
+ if (jj_3R_310()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_530()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CHARACTER_LITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_529()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_465()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_529()) {
+ jj_scanpos = xsp;
+ if (jj_3R_530()) {
+ jj_scanpos = xsp;
+ if (jj_3R_531()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_227()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_193()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_62()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(APOSTROPHE_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_227()) {
+ jj_scanpos = xsp;
+ if (jj_3R_228()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_342()
+ {
+ if (jj_done) return true;
+ if (jj_3R_113()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_192()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_342()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_466()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_377()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ALIAS_T)) return true;
+ if (jj_3R_465()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_466()) jj_scanpos = xsp;
+ if (jj_scan_token(IS_T)) return true;
+ if (jj_3R_60()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_467()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_340()
+ {
+ if (jj_done) return true;
+ if (jj_3R_423()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_109()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_236()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_237()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_273()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(MINUS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_274()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(AMPERSAND_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_129()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_272()) {
+ jj_scanpos = xsp;
+ if (jj_3R_273()) {
+ jj_scanpos = xsp;
+ if (jj_3R_274()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_272()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PLUS_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_3()
+ {
+ if (jj_done) return true;
+ if (jj_3R_61()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_493()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BOX_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_494()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_61()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_404()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_492()) {
+ jj_scanpos = xsp;
+ if (jj_3R_493()) {
+ jj_scanpos = xsp;
+ if (jj_3R_494()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_492()
+ {
+ if (jj_done) return true;
+ if (jj_3R_61()) return true;
+ return false;
+ }
+
+ inline bool jj_3_2()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_226()
+ {
+ if (jj_done) return true;
+ if (jj_3R_166()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_190()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(15)) {
+ jj_scanpos = xsp;
+ if (jj_3R_340()) return true;
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_1()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_154()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_189()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_89()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_189()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_scan_token(PROCESS_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_190()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(56)) jj_scanpos = xsp;
+ if (jj_3R_191()) return true;
+ if (jj_scan_token(BEGIN_T)) return true;
+ if (jj_3R_192()) return true;
+ if (jj_scan_token(END_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_scan_token(79)) jj_scanpos = xsp;
+ if (jj_scan_token(PROCESS_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_193()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_153()
+ {
+ if (jj_done) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_341()
+ {
+ if (jj_done) return true;
+ if (jj_3R_424()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_152()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(OPEN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_61()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_152()) {
+ jj_scanpos = xsp;
+ if (jj_3R_153()) {
+ jj_scanpos = xsp;
+ if (jj_3R_154()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_191()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_341()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_513()
+ {
+ if (jj_done) return true;
+ if (jj_3R_383()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_653()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(ACCESS_T)) return true;
+ if (jj_3R_85()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_225()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BASED_LITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3_69()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_512()
+ {
+ if (jj_done) return true;
+ if (jj_3R_382()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_224()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(INTEGER)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_511()
+ {
+ if (jj_done) return true;
+ if (jj_3R_379()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_223()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DECIMAL_LITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_104()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_223()) {
+ jj_scanpos = xsp;
+ if (jj_3R_224()) {
+ jj_scanpos = xsp;
+ if (jj_3R_225()) return true;
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_68()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_510()
+ {
+ if (jj_done) return true;
+ if (jj_3R_377()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_509()
+ {
+ if (jj_done) return true;
+ if (jj_3R_376()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_508()
+ {
+ if (jj_done) return true;
+ if (jj_3R_375()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_507()
+ {
+ if (jj_done) return true;
+ if (jj_3R_373()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_506()
+ {
+ if (jj_done) return true;
+ if (jj_3R_372()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_505()
+ {
+ if (jj_done) return true;
+ if (jj_3R_371()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_424()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_504()) {
+ jj_scanpos = xsp;
+ if (jj_3R_505()) {
+ jj_scanpos = xsp;
+ if (jj_3R_506()) {
+ jj_scanpos = xsp;
+ if (jj_3R_507()) {
+ jj_scanpos = xsp;
+ if (jj_3R_508()) {
+ jj_scanpos = xsp;
+ if (jj_3R_509()) {
+ jj_scanpos = xsp;
+ if (jj_3R_510()) {
+ jj_scanpos = xsp;
+ if (jj_3_68()) {
+ jj_scanpos = xsp;
+ if (jj_3R_511()) {
+ jj_scanpos = xsp;
+ if (jj_3R_512()) {
+ jj_scanpos = xsp;
+ if (jj_3_69()) {
+ jj_scanpos = xsp;
+ if (jj_3R_513()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_504()
+ {
+ if (jj_done) return true;
+ if (jj_3R_93()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_330()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_226()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_67()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_120()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3_67()) jj_scanpos = xsp;
+ if (jj_3R_177()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_177()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_330()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_65()
+ {
+ if (jj_done) return true;
+ if (jj_3R_87()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_205()
+ {
+ if (jj_done) return true;
+ if (jj_3R_351()) return true;
+ return false;
+ }
+
+ inline bool jj_3_66()
+ {
+ if (jj_done) return true;
+ if (jj_3R_108()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_204()
+ {
+ if (jj_done) return true;
+ if (jj_3R_87()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_203()
+ {
+ if (jj_done) return true;
+ if (jj_3R_350()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_202()
+ {
+ if (jj_done) return true;
+ if (jj_3R_349()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_94()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_202()) {
+ jj_scanpos = xsp;
+ if (jj_3R_203()) {
+ jj_scanpos = xsp;
+ if (jj_3R_204()) {
+ jj_scanpos = xsp;
+ if (jj_3_66()) {
+ jj_scanpos = xsp;
+ if (jj_3R_205()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_64()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3_63()
+ {
+ if (jj_done) return true;
+ if (jj_3R_107()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_458()
+ {
+ if (jj_done) return true;
+ if (jj_3R_109()) return true;
+ return false;
+ }
+
+ inline bool jj_3_62()
+ {
+ if (jj_done) return true;
+ if (jj_3R_106()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_242()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_457()
+ {
+ if (jj_done) return true;
+ if (jj_3R_525()) return true;
+ return false;
+ }
+
+ inline bool jj_3_61()
+ {
+ if (jj_done) return true;
+ if (jj_3R_62()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_456()
+ {
+ if (jj_done) return true;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3_60()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_455()
+ {
+ if (jj_done) return true;
+ if (jj_3R_107()) return true;
+ return false;
+ }
+
+ inline bool jj_3_59()
+ {
+ if (jj_done) return true;
+ if (jj_3R_105()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_454()
+ {
+ if (jj_done) return true;
+ if (jj_3R_106()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_453()
+ {
+ if (jj_done) return true;
+ if (jj_3R_62()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_452()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_370()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_451()) {
+ jj_scanpos = xsp;
+ if (jj_3R_452()) {
+ jj_scanpos = xsp;
+ if (jj_3R_453()) {
+ jj_scanpos = xsp;
+ if (jj_3R_454()) {
+ jj_scanpos = xsp;
+ if (jj_3R_455()) {
+ jj_scanpos = xsp;
+ if (jj_3R_456()) {
+ jj_scanpos = xsp;
+ if (jj_3R_457()) {
+ jj_scanpos = xsp;
+ if (jj_3R_458()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_451()
+ {
+ if (jj_done) return true;
+ if (jj_3R_105()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_329()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PORT_T)) return true;
+ if (jj_scan_token(MAP_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_166()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_582()
+ {
+ if (jj_done) return true;
+ if (jj_3R_313()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_532()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PORT_T)) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_582()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_241()
+ {
+ if (jj_done) return true;
+ if (jj_3R_360()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_112()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(UNITS_T)) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_241()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(END_T)) return true;
+ if (jj_scan_token(UNITS_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_242()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_58()
+ {
+ if (jj_done) return true;
+ if (jj_3R_104()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_222()
+ {
+ if (jj_done) return true;
+ if (jj_3R_104()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_103()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_222()) jj_scanpos = xsp;
+ if (jj_3R_60()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_408()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(IN_T)) return true;
+ if (jj_3R_69()) return true;
+ return false;
+ }
+
+ inline bool jj_3_57()
+ {
+ if (jj_done) return true;
+ if (jj_3R_87()) return true;
+ return false;
+ }
+
+ inline bool jj_3_55()
+ {
+ if (jj_done) return true;
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ inline bool jj_3_56()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_351()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(PACKAGE_T)) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3_54()
+ {
+ if (jj_done) return true;
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_317()
+ {
+ if (jj_done) return true;
+ if (jj_3R_405()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_261()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_167()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(50)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_317()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_310()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(STRINGLITERAL)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_643()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(TYPE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_642()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(FILE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_641()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SHARED_T)) return true;
+ if (jj_scan_token(VARIABLE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_53()
+ {
+ if (jj_done) return true;
+ if (jj_3R_103()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_640()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(VARIABLE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_639()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SIGNAL_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_638()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(CONSTANT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_613()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_638()) {
+ jj_scanpos = xsp;
+ if (jj_3R_639()) {
+ jj_scanpos = xsp;
+ if (jj_3R_640()) {
+ jj_scanpos = xsp;
+ if (jj_3R_641()) {
+ jj_scanpos = xsp;
+ if (jj_3R_642()) {
+ jj_scanpos = xsp;
+ if (jj_3R_643()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_353()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_207()
+ {
+ if (jj_done) return true;
+ if (jj_3R_104()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_206()
+ {
+ if (jj_done) return true;
+ if (jj_3R_103()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_96()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_206()) {
+ jj_scanpos = xsp;
+ if (jj_3R_207()) return true;
+ }
+ return false;
+ }
+
+ inline bool jj_3R_442()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_363()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_442()) jj_scanpos = xsp;
+ if (jj_scan_token(NULL_T)) return true;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_102()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(COMMA_T)) return true;
+ if (jj_3R_59()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_262()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(WHEN_T)) return true;
+ if (jj_3R_80()) return true;
+ return false;
+ }
+
+ inline bool jj_3_52()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LBRACKET_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_260()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ if (jj_scan_token(COLON_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_124()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_260()) jj_scanpos = xsp;
+ if (jj_scan_token(NEXT_T)) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_261()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_262()) jj_scanpos = xsp;
+ if (jj_scan_token(SEMI_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_221()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_219()
+ {
+ if (jj_done) return true;
+ if (jj_3R_234()) return true;
+ return false;
+ }
+
+ inline bool jj_3_51()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_102()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_101()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_219()) jj_scanpos = xsp;
+ if (jj_scan_token(APOSTROPHE_T)) return true;
+ if (jj_3R_220()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_221()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3_47()
+ {
+ if (jj_done) return true;
+ if (jj_3R_99()) return true;
+ return false;
+ }
+
+ inline bool jj_3_50()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_69()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_49()
+ {
+ if (jj_done) return true;
+ if (jj_3R_101()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_214()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_59()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_353()) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3_48()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_100()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_210()
+ {
+ if (jj_done) return true;
+ if (jj_3R_99()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_213()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LPAREN_T)) return true;
+ if (jj_3R_69()) return true;
+ if (jj_scan_token(RPAREN_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_150()
+ {
+ if (jj_done) return true;
+ if (jj_3R_311()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_212()
+ {
+ if (jj_done) return true;
+ if (jj_3R_101()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_211()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(DOT_T)) return true;
+ if (jj_3R_100()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_99()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_211()) {
+ jj_scanpos = xsp;
+ if (jj_3R_212()) {
+ jj_scanpos = xsp;
+ if (jj_3R_213()) {
+ jj_scanpos = xsp;
+ if (jj_3R_214()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3_46()
+ {
+ if (jj_done) return true;
+ if (jj_3R_98()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_98()
+ {
+ if (jj_done) return true;
+ if (jj_3R_99()) return true;
+ Token * xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_210()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_149()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_151()
+ {
+ if (jj_done) return true;
+ if (jj_3R_98()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_148()
+ {
+ if (jj_done) return true;
+ if (jj_3R_310()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_60()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_148()) {
+ jj_scanpos = xsp;
+ if (jj_3R_149()) {
+ jj_scanpos = xsp;
+ if (jj_3R_150()) return true;
+ }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_151()) jj_scanpos = xsp;
+ return false;
+ }
+
+ inline bool jj_3R_625()
+ {
+ if (jj_done) return true;
+ if (jj_3R_70()) return true;
+ return false;
+ }
+
+ inline bool jj_3R_281()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(REM_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_280()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(MOD_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_279()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(SLASH_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_135()
+ {
+ if (jj_done) return true;
+ Token * xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_278()) {
+ jj_scanpos = xsp;
+ if (jj_3R_279()) {
+ jj_scanpos = xsp;
+ if (jj_3R_280()) {
+ jj_scanpos = xsp;
+ if (jj_3R_281()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ inline bool jj_3R_278()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(MULT_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_432()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(LINKAGE_T)) return true;
+ return false;
+ }
+
+ inline bool jj_3R_431()
+ {
+ if (jj_done) return true;
+ if (jj_scan_token(BUFFER_T)) return true;
+ return false;
+ }
+
+ public: TokenManager *token_source;
+ public: CharStream *jj_input_stream;
+ /** Current token. */
+ public: Token *token;
+ /** Next token. */
+ public: Token *jj_nt;
+ private: int jj_ntk;
+ private: JJCalls jj_2_rtns[115];
+ private: bool jj_rescan;
+ private: int jj_gc;
+ private: Token *jj_scanpos, *jj_lastpos;
+ private: int jj_la;
+ /** Whether we are looking ahead. */
+ private: bool jj_lookingAhead;
+ private: bool jj_semLA;
+ private: int jj_gen;
+ private: int jj_la1[295];
+ private: ErrorHandler *errorHandler;
+ private: bool errorHandlerCreated;
+ protected: bool hasError;
+ public: void setErrorHandler(ErrorHandler *eh) {
+ if (errorHandlerCreated) delete errorHandler;
+ errorHandler = eh;
+ errorHandlerCreated = false;
+ }
+ Token *head;
+ public:
+
+ VhdlParser(TokenManager *tm);
+ public: virtual ~VhdlParser();
+
+void ReInit(TokenManager *tm);
+
+Token * jj_consume_token(int kind);
+
+bool jj_scan_token(int kind);
+
+Token * getNextToken();
+
+Token * getToken(int index);
+
+int jj_ntk_f();
+ private: int jj_kind;
+ int **jj_expentries;
+ int *jj_expentry;
+
+void jj_add_error_token(int kind, int pos);
+
+protected: virtual void parseError();
+ private: int trace_indent;
+ private: bool trace_enabled;
+ /** Enable tracing. */
+
+public: void enable_tracing();
+
+public: void disable_tracing();
+
+void jj_rescan_token();
+
+void jj_save(int index, int xla);
+typedef unsigned long long uint64;
+
+
+static Entry* current_root;
+static Entry* tempEntry;
+static Entry* lastEntity ;
+static Entry* lastCompound ;
+static Entry* current;
+static QCString compSpec;
+static QCString currName;
+static int levelCounter;
+static QCString confName;
+static QCString genLabels;
+static QCString lab;
+static QCString forL;
+static int param_sec ;
+static int parse_sec;
+static int currP;
+static Entry* currentCompound;
+
+//----------------------------------------
+
+static void setLineParsed(int tok);
+static int getLine(int tok);
+static int getLine();
+static void lineCount(const char*);
+static void lineCount();
+static void addProto(const char *s1,const char *s2,const char *s3,const char *s4,const char *s5,const char *s6);
+static void addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf);
+static void createFunction(const char *impure,uint64 spec,const char *fname);
+static void addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot);
+static void addCompInst(char *n, char* instName, char* comp,int iLine);
+static void handleCommentBlock(const char* doc,bool brief);
+static void handleFlowComment(const char*);
+static void initEntry(Entry *e);
+static void newEntry();
+static bool isFuncProcProced();
+static void pushLabel(QCString &,QCString&);
+static QCString popLabel(QCString & q);
+static bool addLibUseClause(const QCString &type);
+static void mapLibPackage( Entry* root);
+static void createFlow();
+static void error_skipto(int kind);private: bool jj_done;
+
+};
+}
+}
+#endif
diff --git a/vhdlparser/VhdlParserConstants.h b/vhdlparser/VhdlParserConstants.h
new file mode 100644
index 0000000..0c2c0e5
--- /dev/null
+++ b/vhdlparser/VhdlParserConstants.h
@@ -0,0 +1,950 @@
+/* Generated By:JavaCC: Do not edit this line. VhdlParserConstants.java */
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+#ifndef VHDLPARSERCONSTANTS_H
+#define VHDLPARSERCONSTANTS_H
+#include "JavaCC.h"
+
+namespace vhdl {
+namespace parser {
+ /** End of File. */
+const int _EOF = 0;
+ /** RegularExpression Id. */
+const int DOXYGEN_VHDL_COMMENT = 5;
+ /** RegularExpression Id. */
+const int MULT_DOXYGEN_COMMENT = 6;
+ /** RegularExpression Id. */
+const int VHDL_FLOWCHART_COMMENT = 7;
+ /** RegularExpression Id. */
+const int VHDL_COMMENT = 8;
+ /** RegularExpression Id. */
+const int MULT_DOXYGEN_VHDL_COMMENT_2008 = 9;
+ /** RegularExpression Id. */
+const int MULT_VHDL_2008_COMMENT = 10;
+ /** RegularExpression Id. */
+const int ABS_T = 11;
+ /** RegularExpression Id. */
+const int ACCESS_T = 12;
+ /** RegularExpression Id. */
+const int AFTER_T = 13;
+ /** RegularExpression Id. */
+const int ALIAS_T = 14;
+ /** RegularExpression Id. */
+const int ALL_T = 15;
+ /** RegularExpression Id. */
+const int AND_T = 16;
+ /** RegularExpression Id. */
+const int ARCHITECTURE_T = 17;
+ /** RegularExpression Id. */
+const int ARRAY_T = 18;
+ /** RegularExpression Id. */
+const int ASSERT_T = 19;
+ /** RegularExpression Id. */
+const int ASSUME_T = 20;
+ /** RegularExpression Id. */
+const int ASSUME_GUARANTEE_T = 21;
+ /** RegularExpression Id. */
+const int ATTRIBUTE_T = 22;
+ /** RegularExpression Id. */
+const int BEGIN_T = 23;
+ /** RegularExpression Id. */
+const int BLOCK_T = 24;
+ /** RegularExpression Id. */
+const int BODY_T = 25;
+ /** RegularExpression Id. */
+const int BUFFER_T = 26;
+ /** RegularExpression Id. */
+const int BUS_T = 27;
+ /** RegularExpression Id. */
+const int COMPONENT_T = 28;
+ /** RegularExpression Id. */
+const int CASE_T = 29;
+ /** RegularExpression Id. */
+const int CONFIGURATION_T = 30;
+ /** RegularExpression Id. */
+const int CONSTANT_T = 31;
+ /** RegularExpression Id. */
+const int CONTEXT_T = 32;
+ /** RegularExpression Id. */
+const int COVER_T = 33;
+ /** RegularExpression Id. */
+const int DEFAULT_T = 34;
+ /** RegularExpression Id. */
+const int DISCONNECT_T = 35;
+ /** RegularExpression Id. */
+const int DOWNTO_T = 36;
+ /** RegularExpression Id. */
+const int ELSE_T = 37;
+ /** RegularExpression Id. */
+const int ELSIF_T = 38;
+ /** RegularExpression Id. */
+const int END_T = 39;
+ /** RegularExpression Id. */
+const int ENTITY_T = 40;
+ /** RegularExpression Id. */
+const int EXIT_T = 41;
+ /** RegularExpression Id. */
+const int FAIRNESS_T = 42;
+ /** RegularExpression Id. */
+const int FILE_T = 43;
+ /** RegularExpression Id. */
+const int FOR_T = 44;
+ /** RegularExpression Id. */
+const int FORCE_T = 45;
+ /** RegularExpression Id. */
+const int FUNCTION_T = 46;
+ /** RegularExpression Id. */
+const int GENERATE_T = 47;
+ /** RegularExpression Id. */
+const int GENERIC_T = 48;
+ /** RegularExpression Id. */
+const int GROUP_T = 49;
+ /** RegularExpression Id. */
+const int GUARDED_T = 50;
+ /** RegularExpression Id. */
+const int IF_T = 51;
+ /** RegularExpression Id. */
+const int IMPURE_T = 52;
+ /** RegularExpression Id. */
+const int IN_T = 53;
+ /** RegularExpression Id. */
+const int INERTIAL_T = 54;
+ /** RegularExpression Id. */
+const int INOUT_T = 55;
+ /** RegularExpression Id. */
+const int IS_T = 56;
+ /** RegularExpression Id. */
+const int LABEL_T = 57;
+ /** RegularExpression Id. */
+const int LIBRARY_T = 58;
+ /** RegularExpression Id. */
+const int LINKAGE_T = 59;
+ /** RegularExpression Id. */
+const int LITERAL_T = 60;
+ /** RegularExpression Id. */
+const int LOOP_T = 61;
+ /** RegularExpression Id. */
+const int MAP_T = 62;
+ /** RegularExpression Id. */
+const int MOD_T = 63;
+ /** RegularExpression Id. */
+const int NAND_T = 64;
+ /** RegularExpression Id. */
+const int NEW_T = 65;
+ /** RegularExpression Id. */
+const int NEXT_T = 66;
+ /** RegularExpression Id. */
+const int NOR_T = 67;
+ /** RegularExpression Id. */
+const int NOT_T = 68;
+ /** RegularExpression Id. */
+const int NULL_T = 69;
+ /** RegularExpression Id. */
+const int OF_T = 70;
+ /** RegularExpression Id. */
+const int ON_T = 71;
+ /** RegularExpression Id. */
+const int OPEN_T = 72;
+ /** RegularExpression Id. */
+const int OR_T = 73;
+ /** RegularExpression Id. */
+const int OTHER_T = 74;
+ /** RegularExpression Id. */
+const int OUT_T = 75;
+ /** RegularExpression Id. */
+const int PACKAGE_T = 76;
+ /** RegularExpression Id. */
+const int PARAMETER_T = 77;
+ /** RegularExpression Id. */
+const int PORT_T = 78;
+ /** RegularExpression Id. */
+const int POSTPONED_T = 79;
+ /** RegularExpression Id. */
+const int PROCEDURE_T = 80;
+ /** RegularExpression Id. */
+const int PROCESS_T = 81;
+ /** RegularExpression Id. */
+const int PROPERTY_T = 82;
+ /** RegularExpression Id. */
+const int PROTECTED_T = 83;
+ /** RegularExpression Id. */
+const int PURE_T = 84;
+ /** RegularExpression Id. */
+const int RANGE_T = 85;
+ /** RegularExpression Id. */
+const int RECORD_T = 86;
+ /** RegularExpression Id. */
+const int REGISTER_T = 87;
+ /** RegularExpression Id. */
+const int REJECT_T = 88;
+ /** RegularExpression Id. */
+const int RELEASE_T = 89;
+ /** RegularExpression Id. */
+const int RESTRICT_T = 90;
+ /** RegularExpression Id. */
+const int RESTRICT_GUARANTEE_T = 91;
+ /** RegularExpression Id. */
+const int REM_T = 92;
+ /** RegularExpression Id. */
+const int REPORT_T = 93;
+ /** RegularExpression Id. */
+const int ROL_T = 94;
+ /** RegularExpression Id. */
+const int ROR_T = 95;
+ /** RegularExpression Id. */
+const int RETURN_T = 96;
+ /** RegularExpression Id. */
+const int SELECT_T = 97;
+ /** RegularExpression Id. */
+const int SEQUENCE_T = 98;
+ /** RegularExpression Id. */
+const int SEVERITY_T = 99;
+ /** RegularExpression Id. */
+const int SIGNAL_T = 100;
+ /** RegularExpression Id. */
+const int SHARED_T = 101;
+ /** RegularExpression Id. */
+const int SLA_T = 102;
+ /** RegularExpression Id. */
+const int SLL_T = 103;
+ /** RegularExpression Id. */
+const int SRA_T = 104;
+ /** RegularExpression Id. */
+const int SRL_T = 105;
+ /** RegularExpression Id. */
+const int STRONG_T = 106;
+ /** RegularExpression Id. */
+const int SUBTYPE_T = 107;
+ /** RegularExpression Id. */
+const int THEN_T = 108;
+ /** RegularExpression Id. */
+const int TO_T = 109;
+ /** RegularExpression Id. */
+const int TRANSPORT_T = 110;
+ /** RegularExpression Id. */
+const int TYPE_T = 111;
+ /** RegularExpression Id. */
+const int UNAFFECTED_T = 112;
+ /** RegularExpression Id. */
+const int UNITS_T = 113;
+ /** RegularExpression Id. */
+const int UNTIL_T = 114;
+ /** RegularExpression Id. */
+const int USE_T = 115;
+ /** RegularExpression Id. */
+const int VARIABLE_T = 116;
+ /** RegularExpression Id. */
+const int VMODE_T = 117;
+ /** RegularExpression Id. */
+const int VPROP_T = 118;
+ /** RegularExpression Id. */
+const int VUNIT_T = 119;
+ /** RegularExpression Id. */
+const int WAIT_T = 120;
+ /** RegularExpression Id. */
+const int WHEN_T = 121;
+ /** RegularExpression Id. */
+const int WHILE_T = 122;
+ /** RegularExpression Id. */
+const int WITH_T = 123;
+ /** RegularExpression Id. */
+const int XOR_T = 124;
+ /** RegularExpression Id. */
+const int XNOR_T = 125;
+ /** RegularExpression Id. */
+const int AMPERSAND_T = 126;
+ /** RegularExpression Id. */
+const int APOSTROPHE_T = 127;
+ /** RegularExpression Id. */
+const int LPAREN_T = 128;
+ /** RegularExpression Id. */
+const int RPAREN_T = 129;
+ /** RegularExpression Id. */
+const int DOUBLEMULT_T = 130;
+ /** RegularExpression Id. */
+const int MULT_T = 131;
+ /** RegularExpression Id. */
+const int PLUS_T = 132;
+ /** RegularExpression Id. */
+const int MINUS_T = 133;
+ /** RegularExpression Id. */
+const int COMMA_T = 134;
+ /** RegularExpression Id. */
+const int VARASSIGN_T = 135;
+ /** RegularExpression Id. */
+const int COLON_T = 136;
+ /** RegularExpression Id. */
+const int SEMI_T = 137;
+ /** RegularExpression Id. */
+const int LESSTHAN_T = 138;
+ /** RegularExpression Id. */
+const int GREATERTHAN_T = 139;
+ /** RegularExpression Id. */
+const int LT_T = 140;
+ /** RegularExpression Id. */
+const int GT_T = 141;
+ /** RegularExpression Id. */
+const int EQU_T = 142;
+ /** RegularExpression Id. */
+const int NOTEQU_T = 143;
+ /** RegularExpression Id. */
+const int ARROW_T = 144;
+ /** RegularExpression Id. */
+const int BOX_T = 145;
+ /** RegularExpression Id. */
+const int SLSL_T = 146;
+ /** RegularExpression Id. */
+const int RSRS_T = 147;
+ /** RegularExpression Id. */
+const int QQ_T = 148;
+ /** RegularExpression Id. */
+const int QGT_T = 149;
+ /** RegularExpression Id. */
+const int QLT_T = 150;
+ /** RegularExpression Id. */
+const int QG_T = 151;
+ /** RegularExpression Id. */
+const int QL_T = 152;
+ /** RegularExpression Id. */
+const int QEQU_T = 153;
+ /** RegularExpression Id. */
+const int QNEQU_T = 154;
+ /** RegularExpression Id. */
+const int Q_T = 155;
+ /** RegularExpression Id. */
+const int BAR_T = 156;
+ /** RegularExpression Id. */
+const int DOT_T = 157;
+ /** RegularExpression Id. */
+const int SLASH_T = 158;
+ /** RegularExpression Id. */
+const int AT_T = 159;
+ /** RegularExpression Id. */
+const int NEG_T = 160;
+ /** RegularExpression Id. */
+const int LBRACKET_T = 161;
+ /** RegularExpression Id. */
+const int RBRACKET_T = 162;
+ /** RegularExpression Id. */
+const int LBRACE = 163;
+ /** RegularExpression Id. */
+const int RBRACE = 164;
+ /** RegularExpression Id. */
+const int INTEGER = 165;
+ /** RegularExpression Id. */
+const int STRINGLITERAL = 166;
+ /** RegularExpression Id. */
+const int BASIC_IDENTIFIER = 167;
+ /** RegularExpression Id. */
+const int EXTENDED_CHARACTER = 168;
+ /** RegularExpression Id. */
+const int CHARACTER_LITERAL = 169;
+ /** RegularExpression Id. */
+const int DECIMAL_LITERAL = 170;
+ /** RegularExpression Id. */
+const int BASED_INTEGER = 171;
+ /** RegularExpression Id. */
+const int BASED_LITERAL = 172;
+ /** RegularExpression Id. */
+const int EXPONENT = 173;
+ /** RegularExpression Id. */
+const int BASIC_GRAPHIC_CHARACTER = 174;
+ /** RegularExpression Id. */
+const int GRAPHIC_CHARACTER = 175;
+ /** RegularExpression Id. */
+const int LETTER_OR_DIGIT = 176;
+ /** RegularExpression Id. */
+const int LETTER = 177;
+ /** RegularExpression Id. */
+const int UPPER_CASE_LETTER = 178;
+ /** RegularExpression Id. */
+const int BIT_STRING_LITERAL = 179;
+ /** RegularExpression Id. */
+const int BASE_SPECIFIER = 180;
+ /** RegularExpression Id. */
+const int DIGIT = 181;
+ /** RegularExpression Id. */
+const int SPECIAL_CHARACTER = 182;
+ /** RegularExpression Id. */
+const int OTHER_SPECIAL_CHARACTER = 183;
+ /** RegularExpression Id. */
+const int SPACE_CHARACTER = 184;
+ /** RegularExpression Id. */
+const int LOWER_CASE_LETTER = 185;
+ /** RegularExpression Id. */
+const int VHDL2008TOOLDIR = 186;
+
+ /** Lexical state. */
+const int DEFAULT = 0;
+
+ /** Literal token values. */
+ static JAVACC_CHAR_TYPE tokenImage_arr_0[] =
+{0x3c, 0x45, 0x4f, 0x46, 0x3e, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_1[] =
+{0x22, 0x20, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_2[] =
+{0x22, 0x9, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_3[] =
+{0x22, 0xa, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_4[] =
+{0x22, 0xd, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_5[] =
+{0x22, 0x3c, 0x44, 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e, 0x5f, 0x56, 0x48, 0x44, 0x4c, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_6[] =
+{0x22, 0x3c, 0x4d, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_7[] =
+{0x22, 0x3c, 0x56, 0x48, 0x44, 0x4c, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x43, 0x48, 0x41, 0x52, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_8[] =
+{0x22, 0x3c, 0x56, 0x48, 0x44, 0x4c, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_9[] =
+{0x22, 0x3c, 0x4d, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e, 0x5f, 0x56, 0x48, 0x44, 0x4c, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x32, 0x30, 0x30, 0x38, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_10[] =
+{0x22, 0x3c, 0x4d, 0x55, 0x4c, 0x54, 0x5f, 0x56, 0x48, 0x44, 0x4c, 0x5f, 0x32, 0x30, 0x30, 0x38, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_11[] =
+{0x22, 0x61, 0x62, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_12[] =
+{0x22, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_13[] =
+{0x22, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_14[] =
+{0x22, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_15[] =
+{0x22, 0x61, 0x6c, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_16[] =
+{0x22, 0x61, 0x6e, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_17[] =
+{0x22, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_18[] =
+{0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_19[] =
+{0x22, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_20[] =
+{0x22, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_21[] =
+{0x22, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_22[] =
+{0x22, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_23[] =
+{0x22, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_24[] =
+{0x22, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_25[] =
+{0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_26[] =
+{0x22, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_27[] =
+{0x22, 0x62, 0x75, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_28[] =
+{0x22, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_29[] =
+{0x22, 0x63, 0x61, 0x73, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_30[] =
+{0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_31[] =
+{0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_32[] =
+{0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_33[] =
+{0x22, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_34[] =
+{0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_35[] =
+{0x22, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_36[] =
+{0x22, 0x64, 0x6f, 0x77, 0x6e, 0x74, 0x6f, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_37[] =
+{0x22, 0x65, 0x6c, 0x73, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_38[] =
+{0x22, 0x65, 0x6c, 0x73, 0x69, 0x66, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_39[] =
+{0x22, 0x65, 0x6e, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_40[] =
+{0x22, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_41[] =
+{0x22, 0x65, 0x78, 0x69, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_42[] =
+{0x22, 0x66, 0x61, 0x69, 0x72, 0x6e, 0x65, 0x73, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_43[] =
+{0x22, 0x66, 0x69, 0x6c, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_44[] =
+{0x22, 0x66, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_45[] =
+{0x22, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_46[] =
+{0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_47[] =
+{0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_48[] =
+{0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_49[] =
+{0x22, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_50[] =
+{0x22, 0x67, 0x75, 0x61, 0x72, 0x64, 0x65, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_51[] =
+{0x22, 0x69, 0x66, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_52[] =
+{0x22, 0x69, 0x6d, 0x70, 0x75, 0x72, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_53[] =
+{0x22, 0x69, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_54[] =
+{0x22, 0x69, 0x6e, 0x65, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_55[] =
+{0x22, 0x69, 0x6e, 0x6f, 0x75, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_56[] =
+{0x22, 0x69, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_57[] =
+{0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_58[] =
+{0x22, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_59[] =
+{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x61, 0x67, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_60[] =
+{0x22, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_61[] =
+{0x22, 0x6c, 0x6f, 0x6f, 0x70, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_62[] =
+{0x22, 0x6d, 0x61, 0x70, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_63[] =
+{0x22, 0x6d, 0x6f, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_64[] =
+{0x22, 0x6e, 0x61, 0x6e, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_65[] =
+{0x22, 0x6e, 0x65, 0x77, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_66[] =
+{0x22, 0x6e, 0x65, 0x78, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_67[] =
+{0x22, 0x6e, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_68[] =
+{0x22, 0x6e, 0x6f, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_69[] =
+{0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_70[] =
+{0x22, 0x6f, 0x66, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_71[] =
+{0x22, 0x6f, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_72[] =
+{0x22, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_73[] =
+{0x22, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_74[] =
+{0x22, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_75[] =
+{0x22, 0x6f, 0x75, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_76[] =
+{0x22, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_77[] =
+{0x22, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_78[] =
+{0x22, 0x70, 0x6f, 0x72, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_79[] =
+{0x22, 0x70, 0x6f, 0x73, 0x74, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_80[] =
+{0x22, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_81[] =
+{0x22, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_82[] =
+{0x22, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_83[] =
+{0x22, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_84[] =
+{0x22, 0x70, 0x75, 0x72, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_85[] =
+{0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_86[] =
+{0x22, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_87[] =
+{0x22, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_88[] =
+{0x22, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_89[] =
+{0x22, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_90[] =
+{0x22, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_91[] =
+{0x22, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_92[] =
+{0x22, 0x72, 0x65, 0x6d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_93[] =
+{0x22, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_94[] =
+{0x22, 0x72, 0x6f, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_95[] =
+{0x22, 0x72, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_96[] =
+{0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_97[] =
+{0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_98[] =
+{0x22, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_99[] =
+{0x22, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_100[] =
+{0x22, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_101[] =
+{0x22, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_102[] =
+{0x22, 0x73, 0x6c, 0x61, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_103[] =
+{0x22, 0x73, 0x6c, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_104[] =
+{0x22, 0x73, 0x72, 0x61, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_105[] =
+{0x22, 0x73, 0x72, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_106[] =
+{0x22, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_107[] =
+{0x22, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_108[] =
+{0x22, 0x74, 0x68, 0x65, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_109[] =
+{0x22, 0x74, 0x6f, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_110[] =
+{0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_111[] =
+{0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_112[] =
+{0x22, 0x75, 0x6e, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_113[] =
+{0x22, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_114[] =
+{0x22, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_115[] =
+{0x22, 0x75, 0x73, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_116[] =
+{0x22, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_117[] =
+{0x22, 0x76, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_118[] =
+{0x22, 0x76, 0x70, 0x72, 0x6f, 0x70, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_119[] =
+{0x22, 0x76, 0x75, 0x6e, 0x69, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_120[] =
+{0x22, 0x77, 0x61, 0x69, 0x74, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_121[] =
+{0x22, 0x77, 0x68, 0x65, 0x6e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_122[] =
+{0x22, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_123[] =
+{0x22, 0x77, 0x69, 0x74, 0x68, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_124[] =
+{0x22, 0x78, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_125[] =
+{0x22, 0x78, 0x6e, 0x6f, 0x72, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_126[] =
+{0x22, 0x26, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_127[] =
+{0x22, 0x27, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_128[] =
+{0x22, 0x28, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_129[] =
+{0x22, 0x29, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_130[] =
+{0x22, 0x2a, 0x2a, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_131[] =
+{0x22, 0x2a, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_132[] =
+{0x22, 0x2b, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_133[] =
+{0x22, 0x2d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_134[] =
+{0x22, 0x2c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_135[] =
+{0x22, 0x3a, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_136[] =
+{0x22, 0x3a, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_137[] =
+{0x22, 0x3b, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_138[] =
+{0x22, 0x3c, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_139[] =
+{0x22, 0x3e, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_140[] =
+{0x22, 0x3c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_141[] =
+{0x22, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_142[] =
+{0x22, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_143[] =
+{0x22, 0x2f, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_144[] =
+{0x22, 0x3d, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_145[] =
+{0x22, 0x3c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_146[] =
+{0x22, 0x3c, 0x3c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_147[] =
+{0x22, 0x3e, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_148[] =
+{0x22, 0x3f, 0x3f, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_149[] =
+{0x22, 0x3f, 0x3e, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_150[] =
+{0x22, 0x3f, 0x3c, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_151[] =
+{0x22, 0x3f, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_152[] =
+{0x22, 0x3f, 0x3c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_153[] =
+{0x22, 0x3f, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_154[] =
+{0x22, 0x3f, 0x2f, 0x3d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_155[] =
+{0x22, 0x3f, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_156[] =
+{0x22, 0x7c, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_157[] =
+{0x22, 0x2e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_158[] =
+{0x22, 0x2f, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_159[] =
+{0x22, 0x40, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_160[] =
+{0x22, 0x5e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_161[] =
+{0x22, 0x5b, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_162[] =
+{0x22, 0x5d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_163[] =
+{0x22, 0x7b, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_164[] =
+{0x22, 0x7d, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_165[] =
+{0x22, 0x3c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_166[] =
+{0x22, 0x3c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_167[] =
+{0x22, 0x3c, 0x42, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x49, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_168[] =
+{0x22, 0x3c, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x44, 0x45, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_169[] =
+{0x22, 0x3c, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_170[] =
+{0x22, 0x3c, 0x44, 0x45, 0x43, 0x49, 0x4d, 0x41, 0x4c, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_171[] =
+{0x22, 0x3c, 0x42, 0x41, 0x53, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_172[] =
+{0x22, 0x3c, 0x42, 0x41, 0x53, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_173[] =
+{0x22, 0x3c, 0x45, 0x58, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_174[] =
+{0x22, 0x3c, 0x42, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_175[] =
+{0x22, 0x3c, 0x47, 0x52, 0x41, 0x50, 0x48, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_176[] =
+{0x22, 0x3c, 0x4c, 0x45, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x47, 0x49, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_177[] =
+{0x22, 0x3c, 0x4c, 0x45, 0x54, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_178[] =
+{0x22, 0x3c, 0x55, 0x50, 0x50, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x53, 0x45, 0x5f, 0x4c, 0x45, 0x54, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_179[] =
+{0x22, 0x3c, 0x42, 0x49, 0x54, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_180[] =
+{0x22, 0x3c, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_181[] =
+{0x22, 0x3c, 0x44, 0x49, 0x47, 0x49, 0x54, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_182[] =
+{0x22, 0x3c, 0x53, 0x50, 0x45, 0x43, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_183[] =
+{0x22, 0x3c, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_184[] =
+{0x22, 0x3c, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_185[] =
+{0x22, 0x3c, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x53, 0x45, 0x5f, 0x4c, 0x45, 0x54, 0x54, 0x45, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_CHAR_TYPE tokenImage_arr_186[] =
+{0x22, 0x3c, 0x56, 0x48, 0x44, 0x4c, 0x32, 0x30, 0x30, 0x38, 0x54, 0x4f, 0x4f, 0x4c, 0x44, 0x49, 0x52, 0x3e, 0x22, 0};
+ static JAVACC_STRING_TYPE tokenImage[] = {
+tokenImage_arr_0,
+tokenImage_arr_1,
+tokenImage_arr_2,
+tokenImage_arr_3,
+tokenImage_arr_4,
+tokenImage_arr_5,
+tokenImage_arr_6,
+tokenImage_arr_7,
+tokenImage_arr_8,
+tokenImage_arr_9,
+tokenImage_arr_10,
+tokenImage_arr_11,
+tokenImage_arr_12,
+tokenImage_arr_13,
+tokenImage_arr_14,
+tokenImage_arr_15,
+tokenImage_arr_16,
+tokenImage_arr_17,
+tokenImage_arr_18,
+tokenImage_arr_19,
+tokenImage_arr_20,
+tokenImage_arr_21,
+tokenImage_arr_22,
+tokenImage_arr_23,
+tokenImage_arr_24,
+tokenImage_arr_25,
+tokenImage_arr_26,
+tokenImage_arr_27,
+tokenImage_arr_28,
+tokenImage_arr_29,
+tokenImage_arr_30,
+tokenImage_arr_31,
+tokenImage_arr_32,
+tokenImage_arr_33,
+tokenImage_arr_34,
+tokenImage_arr_35,
+tokenImage_arr_36,
+tokenImage_arr_37,
+tokenImage_arr_38,
+tokenImage_arr_39,
+tokenImage_arr_40,
+tokenImage_arr_41,
+tokenImage_arr_42,
+tokenImage_arr_43,
+tokenImage_arr_44,
+tokenImage_arr_45,
+tokenImage_arr_46,
+tokenImage_arr_47,
+tokenImage_arr_48,
+tokenImage_arr_49,
+tokenImage_arr_50,
+tokenImage_arr_51,
+tokenImage_arr_52,
+tokenImage_arr_53,
+tokenImage_arr_54,
+tokenImage_arr_55,
+tokenImage_arr_56,
+tokenImage_arr_57,
+tokenImage_arr_58,
+tokenImage_arr_59,
+tokenImage_arr_60,
+tokenImage_arr_61,
+tokenImage_arr_62,
+tokenImage_arr_63,
+tokenImage_arr_64,
+tokenImage_arr_65,
+tokenImage_arr_66,
+tokenImage_arr_67,
+tokenImage_arr_68,
+tokenImage_arr_69,
+tokenImage_arr_70,
+tokenImage_arr_71,
+tokenImage_arr_72,
+tokenImage_arr_73,
+tokenImage_arr_74,
+tokenImage_arr_75,
+tokenImage_arr_76,
+tokenImage_arr_77,
+tokenImage_arr_78,
+tokenImage_arr_79,
+tokenImage_arr_80,
+tokenImage_arr_81,
+tokenImage_arr_82,
+tokenImage_arr_83,
+tokenImage_arr_84,
+tokenImage_arr_85,
+tokenImage_arr_86,
+tokenImage_arr_87,
+tokenImage_arr_88,
+tokenImage_arr_89,
+tokenImage_arr_90,
+tokenImage_arr_91,
+tokenImage_arr_92,
+tokenImage_arr_93,
+tokenImage_arr_94,
+tokenImage_arr_95,
+tokenImage_arr_96,
+tokenImage_arr_97,
+tokenImage_arr_98,
+tokenImage_arr_99,
+tokenImage_arr_100,
+tokenImage_arr_101,
+tokenImage_arr_102,
+tokenImage_arr_103,
+tokenImage_arr_104,
+tokenImage_arr_105,
+tokenImage_arr_106,
+tokenImage_arr_107,
+tokenImage_arr_108,
+tokenImage_arr_109,
+tokenImage_arr_110,
+tokenImage_arr_111,
+tokenImage_arr_112,
+tokenImage_arr_113,
+tokenImage_arr_114,
+tokenImage_arr_115,
+tokenImage_arr_116,
+tokenImage_arr_117,
+tokenImage_arr_118,
+tokenImage_arr_119,
+tokenImage_arr_120,
+tokenImage_arr_121,
+tokenImage_arr_122,
+tokenImage_arr_123,
+tokenImage_arr_124,
+tokenImage_arr_125,
+tokenImage_arr_126,
+tokenImage_arr_127,
+tokenImage_arr_128,
+tokenImage_arr_129,
+tokenImage_arr_130,
+tokenImage_arr_131,
+tokenImage_arr_132,
+tokenImage_arr_133,
+tokenImage_arr_134,
+tokenImage_arr_135,
+tokenImage_arr_136,
+tokenImage_arr_137,
+tokenImage_arr_138,
+tokenImage_arr_139,
+tokenImage_arr_140,
+tokenImage_arr_141,
+tokenImage_arr_142,
+tokenImage_arr_143,
+tokenImage_arr_144,
+tokenImage_arr_145,
+tokenImage_arr_146,
+tokenImage_arr_147,
+tokenImage_arr_148,
+tokenImage_arr_149,
+tokenImage_arr_150,
+tokenImage_arr_151,
+tokenImage_arr_152,
+tokenImage_arr_153,
+tokenImage_arr_154,
+tokenImage_arr_155,
+tokenImage_arr_156,
+tokenImage_arr_157,
+tokenImage_arr_158,
+tokenImage_arr_159,
+tokenImage_arr_160,
+tokenImage_arr_161,
+tokenImage_arr_162,
+tokenImage_arr_163,
+tokenImage_arr_164,
+tokenImage_arr_165,
+tokenImage_arr_166,
+tokenImage_arr_167,
+tokenImage_arr_168,
+tokenImage_arr_169,
+tokenImage_arr_170,
+tokenImage_arr_171,
+tokenImage_arr_172,
+tokenImage_arr_173,
+tokenImage_arr_174,
+tokenImage_arr_175,
+tokenImage_arr_176,
+tokenImage_arr_177,
+tokenImage_arr_178,
+tokenImage_arr_179,
+tokenImage_arr_180,
+tokenImage_arr_181,
+tokenImage_arr_182,
+tokenImage_arr_183,
+tokenImage_arr_184,
+tokenImage_arr_185,
+tokenImage_arr_186,
+ };
+
+}
+}
+#endif
diff --git a/vhdlparser/VhdlParserErrorHandler.hpp b/vhdlparser/VhdlParserErrorHandler.hpp
new file mode 100644
index 0000000..d98f029
--- /dev/null
+++ b/vhdlparser/VhdlParserErrorHandler.hpp
@@ -0,0 +1,40 @@
+#ifndef VHDLPARSERERRORHANDLER_H
+#define VHDLPARSERERRORHANDLER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <exception>
+#include "VhdlParser.h"
+#include "ErrorHandler.h"
+#include "vhdlstring.h"
+
+namespace vhdl { namespace parser {
+
+class VhdlErrorHandler: public ErrorHandler
+ {
+ virtual void handleUnexpectedToken(int expectedKind, JAVACC_STRING_TYPE expectedToken, Token *actual, VhdlParser *parser)
+ {
+ fprintf(stderr,"\n\n syntax error at line: %d : %s\n", actual->beginLine,actual->image.data());
+ error_count++;
+ throw std::exception();
+ }
+
+ virtual void handleParseError(Token *last, Token *unexpected, JAVACC_SIMPLE_STRING production, VhdlParser *parser)
+ {
+ fprintf(stderr,"\n\n unexpected token at line: %d %s\n", last->beginLine,unexpected->image.data());
+ error_count++;
+ throw std::exception();
+ }
+
+ virtual void handleOtherError(JAVACC_STRING_TYPE message, VhdlParser *parser)
+ {
+ fprintf(stderr, "\n\n unexpected error: %s\n", (char*)message.c_str());
+ error_count++;
+ throw std::exception();
+ }
+ };
+}
+}
+
+#endif
+
diff --git a/vhdlparser/VhdlParserIF.cpp b/vhdlparser/VhdlParserIF.cpp
new file mode 100644
index 0000000..e8768ee
--- /dev/null
+++ b/vhdlparser/VhdlParserIF.cpp
@@ -0,0 +1,55 @@
+
+#include "VhdlParserTokenManager.h"
+#include "VhdlParserErrorHandler.hpp"
+#include "VhdlParser.h"
+#include "VhdlParserIF.h"
+#include "CharStream.h"
+
+using namespace vhdl::parser;
+
+static VhdlParser * myParser=0;
+
+void VhdlParserIF::parseVhdlfile(const char* inputBuffer,bool inLine)
+{
+ JAVACC_STRING_TYPE s =inputBuffer;
+ CharStream *stream = new CharStream(s.c_str(), (int)s.size(), 1, 1);
+ VhdlParserTokenManager *tokenManager = new VhdlParserTokenManager(stream);
+ myParser=new VhdlParser(tokenManager);
+ VhdlErrorHandler *myErr=new VhdlErrorHandler();
+ myParser->setErrorHandler(myErr);
+ try
+ {
+ if(inLine)
+ {
+ myParser->parseInline();
+ }
+ else
+ {
+ myParser->design_file();
+ }
+ }
+ catch( std::exception &){ /* fprintf(stderr,"\n[%s]",e.what()); */ }
+ // fprintf(stderr,"\n\nparsed lines: %d\n",yyLineNr);
+ // fprintf(stderr,"\n\nerrors : %d\n\n",myErr->getErrorCount());
+ delete myParser;
+
+}
+
+void VhdlParser::error_skipto(int kind)
+{
+ Token *op;
+ do
+ {
+ Token *t = myParser->getNextToken();// step to next token
+ op=myParser->getToken(1); // get first token
+ if (op==0) break;
+ //fprintf(stderr,"\n %s",t->image.data());
+ } while (op->kind != kind);
+ myParser->hasError=false;
+ // The above loop consumes tokens all the way up to a token of
+ // "kind". We use a do-while loop rather than a while because the
+ // current token is the one immediately before the erroneous token
+ // (in our case the token immediately before what should have been
+ // "if"/"while".
+
+}
diff --git a/vhdlparser/VhdlParserIF.h b/vhdlparser/VhdlParserIF.h
new file mode 100644
index 0000000..d11389b
--- /dev/null
+++ b/vhdlparser/VhdlParserIF.h
@@ -0,0 +1,12 @@
+#ifndef VHDLPARSERIF
+#define VHDLPARSERIF
+
+#include "VhdlParser.h"
+
+class VhdlParserIF
+{
+ public:
+ static void parseVhdlfile(const char* inputBuffer,bool inLine);
+
+};
+#endif
diff --git a/vhdlparser/VhdlParserTokenManager.cc b/vhdlparser/VhdlParserTokenManager.cc
new file mode 100644
index 0000000..a35deb2
--- /dev/null
+++ b/vhdlparser/VhdlParserTokenManager.cc
@@ -0,0 +1,3605 @@
+/* VhdlParserTokenManager.cc */
+#include "./VhdlParserTokenManager.h"
+namespace vhdl {
+namespace parser {
+static const unsigned long long jjbitVec0[] = {
+ 0xfffffffffffffffeULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL
+};
+static const unsigned long long jjbitVec2[] = {
+ 0x0ULL, 0x0ULL, 0xffffffffffffffffULL, 0xffffffffffffffffULL
+};
+static const unsigned long long jjbitVec3[] = {
+ 0x0ULL, 0x0ULL, 0xffffffff00000000ULL, 0xffffffffffffffffULL
+};
+static const int jjnextStates[] = {
+ 53, 54, 55, 56, 57, 60, 64, 65, 66, 47, 48, 2, 36, 37, 0, 3,
+ 4, 5, 7, 12, 13, 15, 16, 32, 33, 35, 38, 39, 41, 55, 56, 57,
+ 60, 59, 58, 60, 64, 65, 66, 67, 68, 70, 9, 10, 23, 24, 27, 28,
+ 44, 46, 49, 51, 26, 29,
+};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_0[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_1[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_2[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_3[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_4[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_5[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_6[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_7[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_8[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_9[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_10[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_11[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_12[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_13[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_14[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_15[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_16[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_17[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_18[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_19[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_20[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_21[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_22[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_23[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_24[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_25[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_26[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_27[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_28[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_29[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_30[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_31[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_32[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_33[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_34[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_35[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_36[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_37[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_38[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_39[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_40[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_41[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_42[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_43[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_44[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_45[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_46[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_47[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_48[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_49[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_50[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_51[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_52[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_53[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_54[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_55[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_56[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_57[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_58[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_59[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_60[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_61[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_62[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_63[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_64[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_65[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_66[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_67[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_68[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_69[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_70[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_71[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_72[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_73[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_74[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_75[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_76[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_77[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_78[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_79[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_80[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_81[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_82[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_83[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_84[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_85[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_86[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_87[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_88[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_89[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_90[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_91[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_92[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_93[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_94[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_95[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_96[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_97[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_98[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_99[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_100[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_101[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_102[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_103[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_104[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_105[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_106[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_107[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_108[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_109[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_110[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_111[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_112[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_113[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_114[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_115[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_116[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_117[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_118[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_119[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_120[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_121[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_122[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_123[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_124[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_125[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_126[] = {0x26, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_127[] = {0x27, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_128[] = {0x28, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_129[] = {0x29, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_130[] = {0x2a, 0x2a, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_131[] = {0x2a, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_132[] = {0x2b, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_133[] = {0x2d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_134[] = {0x2c, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_135[] = {0x3a, 0x3d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_136[] = {0x3a, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_137[] = {0x3b, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_138[] = {0x3c, 0x3d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_139[] = {0x3e, 0x3d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_140[] = {0x3c, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_141[] = {0x3e, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_142[] = {0x3d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_143[] = {0x2f, 0x3d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_144[] = {0x3d, 0x3e, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_145[] = {0x3c, 0x3e, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_146[] = {0x3c, 0x3c, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_147[] = {0x3e, 0x3e, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_148[] = {0x3f, 0x3f, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_149[] = {0x3f, 0x3e, 0x3d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_150[] = {0x3f, 0x3c, 0x3d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_151[] = {0x3f, 0x3e, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_152[] = {0x3f, 0x3c, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_153[] = {0x3f, 0x3d, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_154[] = {0x3f, 0x2f, 0x3d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_155[] = {0x3f, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_156[] = {0x7c, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_157[] = {0x2e, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_158[] = {0x2f, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_159[] = {0x40, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_160[] = {0x5e, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_161[] = {0x5b, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_162[] = {0x5d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_163[] = {0x7b, 0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_164[] = {0x7d, 0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_165[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_166[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_167[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_168[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_169[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_170[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_171[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_172[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_173[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_174[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_175[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_176[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_177[] = {0};
+
+static JAVACC_CHAR_TYPE jjstrLiteralChars_178[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_179[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_180[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_181[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_182[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_183[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_184[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_185[] = {0};
+static JAVACC_CHAR_TYPE jjstrLiteralChars_186[] = {0};
+static const JAVACC_STRING_TYPE jjstrLiteralImages[] = {
+jjstrLiteralChars_0,
+jjstrLiteralChars_1,
+jjstrLiteralChars_2,
+jjstrLiteralChars_3,
+jjstrLiteralChars_4,
+jjstrLiteralChars_5,
+jjstrLiteralChars_6,
+jjstrLiteralChars_7,
+jjstrLiteralChars_8,
+jjstrLiteralChars_9,
+jjstrLiteralChars_10,
+jjstrLiteralChars_11,
+jjstrLiteralChars_12,
+jjstrLiteralChars_13,
+jjstrLiteralChars_14,
+jjstrLiteralChars_15,
+jjstrLiteralChars_16,
+jjstrLiteralChars_17,
+jjstrLiteralChars_18,
+jjstrLiteralChars_19,
+jjstrLiteralChars_20,
+jjstrLiteralChars_21,
+jjstrLiteralChars_22,
+jjstrLiteralChars_23,
+jjstrLiteralChars_24,
+jjstrLiteralChars_25,
+jjstrLiteralChars_26,
+jjstrLiteralChars_27,
+jjstrLiteralChars_28,
+jjstrLiteralChars_29,
+jjstrLiteralChars_30,
+jjstrLiteralChars_31,
+jjstrLiteralChars_32,
+jjstrLiteralChars_33,
+jjstrLiteralChars_34,
+jjstrLiteralChars_35,
+jjstrLiteralChars_36,
+jjstrLiteralChars_37,
+jjstrLiteralChars_38,
+jjstrLiteralChars_39,
+jjstrLiteralChars_40,
+jjstrLiteralChars_41,
+jjstrLiteralChars_42,
+jjstrLiteralChars_43,
+jjstrLiteralChars_44,
+jjstrLiteralChars_45,
+jjstrLiteralChars_46,
+jjstrLiteralChars_47,
+jjstrLiteralChars_48,
+jjstrLiteralChars_49,
+jjstrLiteralChars_50,
+jjstrLiteralChars_51,
+jjstrLiteralChars_52,
+jjstrLiteralChars_53,
+jjstrLiteralChars_54,
+jjstrLiteralChars_55,
+jjstrLiteralChars_56,
+jjstrLiteralChars_57,
+jjstrLiteralChars_58,
+jjstrLiteralChars_59,
+jjstrLiteralChars_60,
+jjstrLiteralChars_61,
+jjstrLiteralChars_62,
+jjstrLiteralChars_63,
+jjstrLiteralChars_64,
+jjstrLiteralChars_65,
+jjstrLiteralChars_66,
+jjstrLiteralChars_67,
+jjstrLiteralChars_68,
+jjstrLiteralChars_69,
+jjstrLiteralChars_70,
+jjstrLiteralChars_71,
+jjstrLiteralChars_72,
+jjstrLiteralChars_73,
+jjstrLiteralChars_74,
+jjstrLiteralChars_75,
+jjstrLiteralChars_76,
+jjstrLiteralChars_77,
+jjstrLiteralChars_78,
+jjstrLiteralChars_79,
+jjstrLiteralChars_80,
+jjstrLiteralChars_81,
+jjstrLiteralChars_82,
+jjstrLiteralChars_83,
+jjstrLiteralChars_84,
+jjstrLiteralChars_85,
+jjstrLiteralChars_86,
+jjstrLiteralChars_87,
+jjstrLiteralChars_88,
+jjstrLiteralChars_89,
+jjstrLiteralChars_90,
+jjstrLiteralChars_91,
+jjstrLiteralChars_92,
+jjstrLiteralChars_93,
+jjstrLiteralChars_94,
+jjstrLiteralChars_95,
+jjstrLiteralChars_96,
+jjstrLiteralChars_97,
+jjstrLiteralChars_98,
+jjstrLiteralChars_99,
+jjstrLiteralChars_100,
+jjstrLiteralChars_101,
+jjstrLiteralChars_102,
+jjstrLiteralChars_103,
+jjstrLiteralChars_104,
+jjstrLiteralChars_105,
+jjstrLiteralChars_106,
+jjstrLiteralChars_107,
+jjstrLiteralChars_108,
+jjstrLiteralChars_109,
+jjstrLiteralChars_110,
+jjstrLiteralChars_111,
+jjstrLiteralChars_112,
+jjstrLiteralChars_113,
+jjstrLiteralChars_114,
+jjstrLiteralChars_115,
+jjstrLiteralChars_116,
+jjstrLiteralChars_117,
+jjstrLiteralChars_118,
+jjstrLiteralChars_119,
+jjstrLiteralChars_120,
+jjstrLiteralChars_121,
+jjstrLiteralChars_122,
+jjstrLiteralChars_123,
+jjstrLiteralChars_124,
+jjstrLiteralChars_125,
+jjstrLiteralChars_126,
+jjstrLiteralChars_127,
+jjstrLiteralChars_128,
+jjstrLiteralChars_129,
+jjstrLiteralChars_130,
+jjstrLiteralChars_131,
+jjstrLiteralChars_132,
+jjstrLiteralChars_133,
+jjstrLiteralChars_134,
+jjstrLiteralChars_135,
+jjstrLiteralChars_136,
+jjstrLiteralChars_137,
+jjstrLiteralChars_138,
+jjstrLiteralChars_139,
+jjstrLiteralChars_140,
+jjstrLiteralChars_141,
+jjstrLiteralChars_142,
+jjstrLiteralChars_143,
+jjstrLiteralChars_144,
+jjstrLiteralChars_145,
+jjstrLiteralChars_146,
+jjstrLiteralChars_147,
+jjstrLiteralChars_148,
+jjstrLiteralChars_149,
+jjstrLiteralChars_150,
+jjstrLiteralChars_151,
+jjstrLiteralChars_152,
+jjstrLiteralChars_153,
+jjstrLiteralChars_154,
+jjstrLiteralChars_155,
+jjstrLiteralChars_156,
+jjstrLiteralChars_157,
+jjstrLiteralChars_158,
+jjstrLiteralChars_159,
+jjstrLiteralChars_160,
+jjstrLiteralChars_161,
+jjstrLiteralChars_162,
+jjstrLiteralChars_163,
+jjstrLiteralChars_164,
+jjstrLiteralChars_165,
+jjstrLiteralChars_166,
+jjstrLiteralChars_167,
+jjstrLiteralChars_168,
+jjstrLiteralChars_169,
+jjstrLiteralChars_170,
+jjstrLiteralChars_171,
+jjstrLiteralChars_172,
+jjstrLiteralChars_173,
+jjstrLiteralChars_174,
+jjstrLiteralChars_175,
+jjstrLiteralChars_176,
+jjstrLiteralChars_177,
+jjstrLiteralChars_178,
+jjstrLiteralChars_179,
+jjstrLiteralChars_180,
+jjstrLiteralChars_181,
+jjstrLiteralChars_182,
+jjstrLiteralChars_183,
+jjstrLiteralChars_184,
+jjstrLiteralChars_185,
+jjstrLiteralChars_186,
+};
+
+/** Lexer state names. */
+static const JAVACC_CHAR_TYPE lexStateNames_arr_0[] =
+{0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0};
+static const JAVACC_STRING_TYPE lexStateNames[] = {
+lexStateNames_arr_0,
+};
+static const unsigned long long jjtoToken[] = {
+ 0xfffffffffffff801ULL, 0xffffffffffffffffULL, 0x4081fffffffffffULL,
+};
+static const unsigned long long jjtoSkip[] = {
+ 0x7deULL, 0x0ULL, 0x0ULL,
+};
+
+void VhdlParserTokenManager::setDebugStream(FILE *ds){ debugStream = ds; }
+
+ int VhdlParserTokenManager::jjStopAtPos(int pos, int kind){
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ return pos + 1;
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa0_0(){
+ switch(curChar)
+ {
+ case 9:
+ jjmatchedKind = 2;
+ return jjMoveNfa_0(11, 0);
+ case 10:
+ jjmatchedKind = 3;
+ return jjMoveNfa_0(11, 0);
+ case 13:
+ jjmatchedKind = 4;
+ return jjMoveNfa_0(11, 0);
+ case 32:
+ jjmatchedKind = 1;
+ return jjMoveNfa_0(11, 0);
+ case 38:
+ jjmatchedKind = 126;
+ return jjMoveNfa_0(11, 0);
+ case 39:
+ jjmatchedKind = 127;
+ return jjMoveNfa_0(11, 0);
+ case 40:
+ jjmatchedKind = 128;
+ return jjMoveNfa_0(11, 0);
+ case 41:
+ jjmatchedKind = 129;
+ return jjMoveNfa_0(11, 0);
+ case 42:
+ jjmatchedKind = 131;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x4ULL);
+ case 43:
+ jjmatchedKind = 132;
+ return jjMoveNfa_0(11, 0);
+ case 44:
+ jjmatchedKind = 134;
+ return jjMoveNfa_0(11, 0);
+ case 45:
+ jjmatchedKind = 133;
+ return jjMoveNfa_0(11, 0);
+ case 46:
+ jjmatchedKind = 157;
+ return jjMoveNfa_0(11, 0);
+ case 47:
+ jjmatchedKind = 158;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x8000ULL);
+ case 58:
+ jjmatchedKind = 136;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x80ULL);
+ case 59:
+ jjmatchedKind = 137;
+ return jjMoveNfa_0(11, 0);
+ case 60:
+ jjmatchedKind = 140;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x60400ULL);
+ case 61:
+ jjmatchedKind = 142;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x10000ULL);
+ case 62:
+ jjmatchedKind = 141;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x80800ULL);
+ case 63:
+ jjmatchedKind = 155;
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x0ULL, 0x7f00000ULL);
+ case 64:
+ jjmatchedKind = 159;
+ return jjMoveNfa_0(11, 0);
+ case 65:
+ return jjMoveStringLiteralDfa1_0(0x7ff800ULL, 0x0ULL, 0x0ULL);
+ case 66:
+ return jjMoveStringLiteralDfa1_0(0xf800000ULL, 0x0ULL, 0x0ULL);
+ case 67:
+ return jjMoveStringLiteralDfa1_0(0x3f0000000ULL, 0x0ULL, 0x0ULL);
+ case 68:
+ return jjMoveStringLiteralDfa1_0(0x1c00000000ULL, 0x0ULL, 0x0ULL);
+ case 69:
+ return jjMoveStringLiteralDfa1_0(0x3e000000000ULL, 0x0ULL, 0x0ULL);
+ case 70:
+ return jjMoveStringLiteralDfa1_0(0x7c0000000000ULL, 0x0ULL, 0x0ULL);
+ case 71:
+ return jjMoveStringLiteralDfa1_0(0x7800000000000ULL, 0x0ULL, 0x0ULL);
+ case 73:
+ return jjMoveStringLiteralDfa1_0(0x1f8000000000000ULL, 0x0ULL, 0x0ULL);
+ case 76:
+ return jjMoveStringLiteralDfa1_0(0x3e00000000000000ULL, 0x0ULL, 0x0ULL);
+ case 77:
+ return jjMoveStringLiteralDfa1_0(0xc000000000000000ULL, 0x0ULL, 0x0ULL);
+ case 78:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x3fULL, 0x0ULL);
+ case 79:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xfc0ULL, 0x0ULL);
+ case 80:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x1ff000ULL, 0x0ULL);
+ case 82:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x1ffe00000ULL, 0x0ULL);
+ case 83:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xffe00000000ULL, 0x0ULL);
+ case 84:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf00000000000ULL, 0x0ULL);
+ case 85:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf000000000000ULL, 0x0ULL);
+ case 86:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf0000000000000ULL, 0x0ULL);
+ case 87:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf00000000000000ULL, 0x0ULL);
+ case 88:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x3000000000000000ULL, 0x0ULL);
+ case 91:
+ jjmatchedKind = 161;
+ return jjMoveNfa_0(11, 0);
+ case 93:
+ jjmatchedKind = 162;
+ return jjMoveNfa_0(11, 0);
+ case 94:
+ jjmatchedKind = 160;
+ return jjMoveNfa_0(11, 0);
+ case 97:
+ return jjMoveStringLiteralDfa1_0(0x7ff800ULL, 0x0ULL, 0x0ULL);
+ case 98:
+ return jjMoveStringLiteralDfa1_0(0xf800000ULL, 0x0ULL, 0x0ULL);
+ case 99:
+ return jjMoveStringLiteralDfa1_0(0x3f0000000ULL, 0x0ULL, 0x0ULL);
+ case 100:
+ return jjMoveStringLiteralDfa1_0(0x1c00000000ULL, 0x0ULL, 0x0ULL);
+ case 101:
+ return jjMoveStringLiteralDfa1_0(0x3e000000000ULL, 0x0ULL, 0x0ULL);
+ case 102:
+ return jjMoveStringLiteralDfa1_0(0x7c0000000000ULL, 0x0ULL, 0x0ULL);
+ case 103:
+ return jjMoveStringLiteralDfa1_0(0x7800000000000ULL, 0x0ULL, 0x0ULL);
+ case 105:
+ return jjMoveStringLiteralDfa1_0(0x1f8000000000000ULL, 0x0ULL, 0x0ULL);
+ case 108:
+ return jjMoveStringLiteralDfa1_0(0x3e00000000000000ULL, 0x0ULL, 0x0ULL);
+ case 109:
+ return jjMoveStringLiteralDfa1_0(0xc000000000000000ULL, 0x0ULL, 0x0ULL);
+ case 110:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x3fULL, 0x0ULL);
+ case 111:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xfc0ULL, 0x0ULL);
+ case 112:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x1ff000ULL, 0x0ULL);
+ case 114:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x1ffe00000ULL, 0x0ULL);
+ case 115:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xffe00000000ULL, 0x0ULL);
+ case 116:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf00000000000ULL, 0x0ULL);
+ case 117:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf000000000000ULL, 0x0ULL);
+ case 118:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf0000000000000ULL, 0x0ULL);
+ case 119:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0xf00000000000000ULL, 0x0ULL);
+ case 120:
+ return jjMoveStringLiteralDfa1_0(0x0ULL, 0x3000000000000000ULL, 0x0ULL);
+ case 123:
+ jjmatchedKind = 163;
+ return jjMoveNfa_0(11, 0);
+ case 124:
+ jjmatchedKind = 156;
+ return jjMoveNfa_0(11, 0);
+ case 125:
+ jjmatchedKind = 164;
+ return jjMoveNfa_0(11, 0);
+ default :
+ return jjMoveNfa_0(11, 0);
+ }
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa1_0(unsigned long long active0, unsigned long long active1, unsigned long long active2){
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 0);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 42:
+ if ((active2 & 0x4ULL) != 0L)
+ {
+ jjmatchedKind = 130;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 47:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x4000000ULL);
+ case 60:
+ if ((active2 & 0x40000ULL) != 0L)
+ {
+ jjmatchedKind = 146;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x1000000ULL) != 0L)
+ {
+ jjmatchedKind = 152;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x400000ULL);
+ case 61:
+ if ((active2 & 0x80ULL) != 0L)
+ {
+ jjmatchedKind = 135;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x400ULL) != 0L)
+ {
+ jjmatchedKind = 138;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x800ULL) != 0L)
+ {
+ jjmatchedKind = 139;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x8000ULL) != 0L)
+ {
+ jjmatchedKind = 143;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x2000000ULL) != 0L)
+ {
+ jjmatchedKind = 153;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 62:
+ if ((active2 & 0x10000ULL) != 0L)
+ {
+ jjmatchedKind = 144;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x20000ULL) != 0L)
+ {
+ jjmatchedKind = 145;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x80000ULL) != 0L)
+ {
+ jjmatchedKind = 147;
+ jjmatchedPos = 1;
+ }
+ else if ((active2 & 0x800000ULL) != 0L)
+ {
+ jjmatchedKind = 151;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x200000ULL);
+ case 63:
+ if ((active2 & 0x100000ULL) != 0L)
+ {
+ jjmatchedKind = 148;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 65:
+ return jjMoveStringLiteralDfa2_0(active0, 0x4200040020000000ULL, active1, 0x110000000203001ULL, active2, 0L);
+ case 66:
+ return jjMoveStringLiteralDfa2_0(active0, 0x800ULL, active1, 0L, active2, 0L);
+ case 67:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1000ULL, active1, 0L, active2, 0L);
+ case 69:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1800400800000ULL, active1, 0xf3fc00006ULL, active2, 0L);
+ case 70:
+ if ((active0 & 0x8000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 51;
+ jjmatchedPos = 1;
+ }
+ else if ((active1 & 0x40ULL) != 0L)
+ {
+ jjmatchedKind = 70;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000ULL, active1, 0L, active2, 0L);
+ case 72:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x600102000000000ULL, active2, 0L);
+ case 73:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1c00080800000000ULL, active1, 0x800001000000000ULL, active2, 0L);
+ case 76:
+ return jjMoveStringLiteralDfa2_0(active0, 0x600100c000ULL, active1, 0xc000000000ULL, active2, 0L);
+ case 77:
+ return jjMoveStringLiteralDfa2_0(active0, 0x10000000000000ULL, active1, 0x20000000000000ULL, active2, 0L);
+ case 78:
+ if ((active0 & 0x20000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 53;
+ jjmatchedPos = 1;
+ }
+ else if ((active1 & 0x80ULL) != 0L)
+ {
+ jjmatchedKind = 71;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0xc0018000010000ULL, active1, 0x2007000000000000ULL, active2, 0L);
+ case 79:
+ if ((active1 & 0x200000000000ULL) != 0L)
+ {
+ jjmatchedKind = 109;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0xa0003013d2000000ULL, active1, 0x10000000c000c018ULL, active2, 0L);
+ case 80:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x40000000000100ULL, active2, 0L);
+ case 82:
+ if ((active1 & 0x200ULL) != 0L)
+ {
+ jjmatchedKind = 73;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000000060000ULL, active1, 0x4300000f0000ULL, active2, 0L);
+ case 83:
+ if ((active0 & 0x100000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 56;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x380000ULL, active1, 0x8000000000000ULL, active2, 0L);
+ case 84:
+ return jjMoveStringLiteralDfa2_0(active0, 0x400000ULL, active1, 0x40000000400ULL, active2, 0L);
+ case 85:
+ return jjMoveStringLiteralDfa2_0(active0, 0x440000c000000ULL, active1, 0x80080000100820ULL, active2, 0L);
+ case 88:
+ return jjMoveStringLiteralDfa2_0(active0, 0x20000000000ULL, active1, 0L, active2, 0L);
+ case 89:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x800000000000ULL, active2, 0L);
+ case 97:
+ return jjMoveStringLiteralDfa2_0(active0, 0x4200040020000000ULL, active1, 0x110000000203001ULL, active2, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa2_0(active0, 0x800ULL, active1, 0L, active2, 0L);
+ case 99:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1000ULL, active1, 0L, active2, 0L);
+ case 101:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1800400800000ULL, active1, 0xf3fc00006ULL, active2, 0L);
+ case 102:
+ if ((active0 & 0x8000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 51;
+ jjmatchedPos = 1;
+ }
+ else if ((active1 & 0x40ULL) != 0L)
+ {
+ jjmatchedKind = 70;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000ULL, active1, 0L, active2, 0L);
+ case 104:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x600102000000000ULL, active2, 0L);
+ case 105:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1c00080800000000ULL, active1, 0x800001000000000ULL, active2, 0L);
+ case 108:
+ return jjMoveStringLiteralDfa2_0(active0, 0x600100c000ULL, active1, 0xc000000000ULL, active2, 0L);
+ case 109:
+ return jjMoveStringLiteralDfa2_0(active0, 0x10000000000000ULL, active1, 0x20000000000000ULL, active2, 0L);
+ case 110:
+ if ((active0 & 0x20000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 53;
+ jjmatchedPos = 1;
+ }
+ else if ((active1 & 0x80ULL) != 0L)
+ {
+ jjmatchedKind = 71;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0xc0018000010000ULL, active1, 0x2007000000000000ULL, active2, 0L);
+ case 111:
+ if ((active1 & 0x200000000000ULL) != 0L)
+ {
+ jjmatchedKind = 109;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0xa0003013d2000000ULL, active1, 0x10000000c000c018ULL, active2, 0L);
+ case 112:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x40000000000100ULL, active2, 0L);
+ case 114:
+ if ((active1 & 0x200ULL) != 0L)
+ {
+ jjmatchedKind = 73;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000000060000ULL, active1, 0x4300000f0000ULL, active2, 0L);
+ case 115:
+ if ((active0 & 0x100000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 56;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x380000ULL, active1, 0x8000000000000ULL, active2, 0L);
+ case 116:
+ return jjMoveStringLiteralDfa2_0(active0, 0x400000ULL, active1, 0x40000000400ULL, active2, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa2_0(active0, 0x440000c000000ULL, active1, 0x80080000100820ULL, active2, 0L);
+ case 120:
+ return jjMoveStringLiteralDfa2_0(active0, 0x20000000000ULL, active1, 0L, active2, 0L);
+ case 121:
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x800000000000ULL, active2, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 1);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa2_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1, unsigned long long old2, unsigned long long active2){
+ if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+ return jjMoveNfa_0(11, 1);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 1);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 61:
+ if ((active2 & 0x200000ULL) != 0L)
+ {
+ jjmatchedKind = 149;
+ jjmatchedPos = 2;
+ }
+ else if ((active2 & 0x400000ULL) != 0L)
+ {
+ jjmatchedKind = 150;
+ jjmatchedPos = 2;
+ }
+ else if ((active2 & 0x4000000ULL) != 0L)
+ {
+ jjmatchedKind = 154;
+ jjmatchedPos = 2;
+ }
+ break;
+ case 65:
+ if ((active1 & 0x4000000000ULL) != 0L)
+ {
+ jjmatchedKind = 102;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x10000000000ULL) != 0L)
+ {
+ jjmatchedKind = 104;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x4000000000000ULL, active1, 0x1402000000000ULL, active2, 0L);
+ case 66:
+ return jjMoveStringLiteralDfa3_0(active0, 0x600000000000000ULL, active1, 0x80000000000ULL, active2, 0L);
+ case 67:
+ return jjMoveStringLiteralDfa3_0(active0, 0x21000ULL, active1, 0x401000ULL, active2, 0L);
+ case 68:
+ if ((active0 & 0x10000ULL) != 0L)
+ {
+ jjmatchedKind = 16;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000000ULL) != 0L)
+ {
+ jjmatchedKind = 39;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 63;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x2000000ULL, active1, 0L, active2, 0L);
+ case 69:
+ if ((active1 & 0x8000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 115;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000ULL, active1, 0x200100000000100ULL, active2, 0L);
+ case 70:
+ return jjMoveStringLiteralDfa3_0(active0, 0x404000000ULL, active1, 0L, active2, 0L);
+ case 71:
+ return jjMoveStringLiteralDfa3_0(active0, 0x800000ULL, active1, 0x1000800000ULL, active2, 0L);
+ case 72:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400ULL, active2, 0L);
+ case 73:
+ return jjMoveStringLiteralDfa3_0(active0, 0x60000004000ULL, active1, 0x502000000000000ULL, active2, 0L);
+ case 74:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x1000000ULL, active2, 0L);
+ case 76:
+ if ((active0 & 0x8000ULL) != 0L)
+ {
+ jjmatchedKind = 15;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x40000000ULL) != 0L)
+ {
+ jjmatchedKind = 94;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x8000000000ULL) != 0L)
+ {
+ jjmatchedKind = 103;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x20000000000ULL) != 0L)
+ {
+ jjmatchedKind = 105;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x80000000000ULL, active1, 0x202000020ULL, active2, 0L);
+ case 77:
+ if ((active1 & 0x10000000ULL) != 0L)
+ {
+ jjmatchedKind = 92;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x10000000ULL, active1, 0L, active2, 0L);
+ case 78:
+ return jjMoveStringLiteralDfa3_0(active0, 0x801c001c0000000ULL, active1, 0x80000000200001ULL, active2, 0L);
+ case 79:
+ return jjMoveStringLiteralDfa3_0(active0, 0x2082000001000000ULL, active1, 0x20200000000f0000ULL, active2, 0L);
+ case 80:
+ if ((active0 & 0x4000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 62;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x10000000000000ULL, active1, 0x800020000000ULL, active2, 0L);
+ case 81:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400000000ULL, active2, 0L);
+ case 82:
+ if ((active0 & 0x100000000000ULL) != 0L)
+ {
+ jjmatchedKind = 44;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x8ULL) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x80000000ULL) != 0L)
+ {
+ jjmatchedKind = 95;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x1000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 124;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x200000040000ULL, active1, 0x50040000106000ULL, active2, 0L);
+ case 83:
+ if ((active0 & 0x800ULL) != 0L)
+ {
+ jjmatchedKind = 11;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000ULL) != 0L)
+ {
+ jjmatchedKind = 27;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x6820380000ULL, active1, 0xc008000ULL, active2, 0L);
+ case 84:
+ if ((active1 & 0x10ULL) != 0L)
+ {
+ jjmatchedKind = 68;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x800ULL) != 0L)
+ {
+ jjmatchedKind = 75;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x1000010000402000ULL, active1, 0x804000100000000ULL, active2, 0L);
+ case 86:
+ return jjMoveStringLiteralDfa3_0(active0, 0x200000000ULL, active1, 0x800000000ULL, active2, 0L);
+ case 87:
+ if ((active1 & 0x2ULL) != 0L)
+ {
+ jjmatchedKind = 65;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x1000000000ULL, active1, 0L, active2, 0L);
+ case 88:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x4ULL, active2, 0L);
+ case 97:
+ if ((active1 & 0x4000000000ULL) != 0L)
+ {
+ jjmatchedKind = 102;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x10000000000ULL) != 0L)
+ {
+ jjmatchedKind = 104;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x4000000000000ULL, active1, 0x1402000000000ULL, active2, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa3_0(active0, 0x600000000000000ULL, active1, 0x80000000000ULL, active2, 0L);
+ case 99:
+ return jjMoveStringLiteralDfa3_0(active0, 0x21000ULL, active1, 0x401000ULL, active2, 0L);
+ case 100:
+ if ((active0 & 0x10000ULL) != 0L)
+ {
+ jjmatchedKind = 16;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000000ULL) != 0L)
+ {
+ jjmatchedKind = 39;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 63;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x2000000ULL, active1, 0L, active2, 0L);
+ case 101:
+ if ((active1 & 0x8000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 115;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000ULL, active1, 0x200100000000100ULL, active2, 0L);
+ case 102:
+ return jjMoveStringLiteralDfa3_0(active0, 0x404000000ULL, active1, 0L, active2, 0L);
+ case 103:
+ return jjMoveStringLiteralDfa3_0(active0, 0x800000ULL, active1, 0x1000800000ULL, active2, 0L);
+ case 104:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400ULL, active2, 0L);
+ case 105:
+ return jjMoveStringLiteralDfa3_0(active0, 0x60000004000ULL, active1, 0x502000000000000ULL, active2, 0L);
+ case 106:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x1000000ULL, active2, 0L);
+ case 108:
+ if ((active0 & 0x8000ULL) != 0L)
+ {
+ jjmatchedKind = 15;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x40000000ULL) != 0L)
+ {
+ jjmatchedKind = 94;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x8000000000ULL) != 0L)
+ {
+ jjmatchedKind = 103;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x20000000000ULL) != 0L)
+ {
+ jjmatchedKind = 105;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x80000000000ULL, active1, 0x202000020ULL, active2, 0L);
+ case 109:
+ if ((active1 & 0x10000000ULL) != 0L)
+ {
+ jjmatchedKind = 92;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x10000000ULL, active1, 0L, active2, 0L);
+ case 110:
+ return jjMoveStringLiteralDfa3_0(active0, 0x801c001c0000000ULL, active1, 0x80000000200001ULL, active2, 0L);
+ case 111:
+ return jjMoveStringLiteralDfa3_0(active0, 0x2082000001000000ULL, active1, 0x20200000000f0000ULL, active2, 0L);
+ case 112:
+ if ((active0 & 0x4000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 62;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x10000000000000ULL, active1, 0x800020000000ULL, active2, 0L);
+ case 113:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400000000ULL, active2, 0L);
+ case 114:
+ if ((active0 & 0x100000000000ULL) != 0L)
+ {
+ jjmatchedKind = 44;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x8ULL) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x80000000ULL) != 0L)
+ {
+ jjmatchedKind = 95;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x1000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 124;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x200000040000ULL, active1, 0x50040000106000ULL, active2, 0L);
+ case 115:
+ if ((active0 & 0x800ULL) != 0L)
+ {
+ jjmatchedKind = 11;
+ jjmatchedPos = 2;
+ }
+ else if ((active0 & 0x8000000ULL) != 0L)
+ {
+ jjmatchedKind = 27;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x6820380000ULL, active1, 0xc008000ULL, active2, 0L);
+ case 116:
+ if ((active1 & 0x10ULL) != 0L)
+ {
+ jjmatchedKind = 68;
+ jjmatchedPos = 2;
+ }
+ else if ((active1 & 0x800ULL) != 0L)
+ {
+ jjmatchedKind = 75;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x1000010000402000ULL, active1, 0x804000100000000ULL, active2, 0L);
+ case 118:
+ return jjMoveStringLiteralDfa3_0(active0, 0x200000000ULL, active1, 0x800000000ULL, active2, 0L);
+ case 119:
+ if ((active1 & 0x2ULL) != 0L)
+ {
+ jjmatchedKind = 65;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x1000000000ULL, active1, 0L, active2, 0L);
+ case 120:
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x4ULL, active2, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 2);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa3_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1, unsigned long long old2, unsigned long long active2){
+ if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+ return jjMoveNfa_0(11, 2);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 2);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa4_0(active0, 0x400044000ULL, active1, 0x2000ULL);
+ case 67:
+ return jjMoveStringLiteralDfa4_0(active0, 0x600801000000ULL, active1, 0x30000ULL);
+ case 68:
+ if ((active1 & 0x1ULL) != 0L)
+ {
+ jjmatchedKind = 64;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x20000000000000ULL);
+ case 69:
+ if ((active0 & 0x20000000ULL) != 0L)
+ {
+ jjmatchedKind = 29;
+ jjmatchedPos = 3;
+ }
+ else if ((active0 & 0x2000000000ULL) != 0L)
+ {
+ jjmatchedKind = 37;
+ jjmatchedPos = 3;
+ }
+ else if ((active0 & 0x80000000000ULL) != 0L)
+ {
+ jjmatchedKind = 43;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000ULL) != 0L)
+ {
+ jjmatchedKind = 84;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x800000000000ULL) != 0L)
+ {
+ jjmatchedKind = 111;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x1201800200083000ULL, active1, 0xa03000400ULL);
+ case 70:
+ return jjMoveStringLiteralDfa4_0(active0, 0x44000000ULL, active1, 0x1000000000000ULL);
+ case 71:
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x200000ULL);
+ case 72:
+ if ((active1 & 0x800000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 123;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x20000ULL, active1, 0L);
+ case 73:
+ return jjMoveStringLiteralDfa4_0(active0, 0x14000800000ULL, active1, 0x94000000800000ULL);
+ case 75:
+ return jjMoveStringLiteralDfa4_0(active0, 0x800000000000000ULL, active1, 0x1000ULL);
+ case 76:
+ if ((active1 & 0x20ULL) != 0L)
+ {
+ jjmatchedKind = 69;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x400000000000000ULL);
+ case 78:
+ if ((active1 & 0x100ULL) != 0L)
+ {
+ jjmatchedKind = 72;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000000000ULL) != 0L)
+ {
+ jjmatchedKind = 108;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x200000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 121;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x1000000000ULL, active1, 0x401000000000ULL);
+ case 79:
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x40040020400000ULL);
+ case 80:
+ if ((active0 & 0x2000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 61;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x10000000ULL, active1, 0x40000ULL);
+ case 82:
+ if ((active1 & 0x2000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 125;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x444040000400000ULL, active1, 0x2000000000ULL);
+ case 83:
+ return jjMoveStringLiteralDfa4_0(active0, 0x80000000ULL, active1, 0L);
+ case 84:
+ if ((active0 & 0x20000000000ULL) != 0L)
+ {
+ jjmatchedKind = 41;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x4ULL) != 0L)
+ {
+ jjmatchedKind = 66;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x4000ULL) != 0L)
+ {
+ jjmatchedKind = 78;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 120;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x100000000ULL, active1, 0x208000c088000ULL);
+ case 85:
+ return jjMoveStringLiteralDfa4_0(active0, 0x92000000300000ULL, active1, 0x500000000ULL);
+ case 89:
+ if ((active0 & 0x2000000ULL) != 0L)
+ {
+ jjmatchedKind = 25;
+ jjmatchedPos = 3;
+ }
+ break;
+ case 97:
+ return jjMoveStringLiteralDfa4_0(active0, 0x400044000ULL, active1, 0x2000ULL);
+ case 99:
+ return jjMoveStringLiteralDfa4_0(active0, 0x600801000000ULL, active1, 0x30000ULL);
+ case 100:
+ if ((active1 & 0x1ULL) != 0L)
+ {
+ jjmatchedKind = 64;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x20000000000000ULL);
+ case 101:
+ if ((active0 & 0x20000000ULL) != 0L)
+ {
+ jjmatchedKind = 29;
+ jjmatchedPos = 3;
+ }
+ else if ((active0 & 0x2000000000ULL) != 0L)
+ {
+ jjmatchedKind = 37;
+ jjmatchedPos = 3;
+ }
+ else if ((active0 & 0x80000000000ULL) != 0L)
+ {
+ jjmatchedKind = 43;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000ULL) != 0L)
+ {
+ jjmatchedKind = 84;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x800000000000ULL) != 0L)
+ {
+ jjmatchedKind = 111;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x1201800200083000ULL, active1, 0xa03000400ULL);
+ case 102:
+ return jjMoveStringLiteralDfa4_0(active0, 0x44000000ULL, active1, 0x1000000000000ULL);
+ case 103:
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x200000ULL);
+ case 104:
+ if ((active1 & 0x800000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 123;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x20000ULL, active1, 0L);
+ case 105:
+ return jjMoveStringLiteralDfa4_0(active0, 0x14000800000ULL, active1, 0x94000000800000ULL);
+ case 107:
+ return jjMoveStringLiteralDfa4_0(active0, 0x800000000000000ULL, active1, 0x1000ULL);
+ case 108:
+ if ((active1 & 0x20ULL) != 0L)
+ {
+ jjmatchedKind = 69;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x400000000000000ULL);
+ case 110:
+ if ((active1 & 0x100ULL) != 0L)
+ {
+ jjmatchedKind = 72;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000000000ULL) != 0L)
+ {
+ jjmatchedKind = 108;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x200000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 121;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x1000000000ULL, active1, 0x401000000000ULL);
+ case 111:
+ return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x40040020400000ULL);
+ case 112:
+ if ((active0 & 0x2000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 61;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x10000000ULL, active1, 0x40000ULL);
+ case 114:
+ if ((active1 & 0x2000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 125;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x444040000400000ULL, active1, 0x2000000000ULL);
+ case 115:
+ return jjMoveStringLiteralDfa4_0(active0, 0x80000000ULL, active1, 0L);
+ case 116:
+ if ((active0 & 0x20000000000ULL) != 0L)
+ {
+ jjmatchedKind = 41;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x4ULL) != 0L)
+ {
+ jjmatchedKind = 66;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x4000ULL) != 0L)
+ {
+ jjmatchedKind = 78;
+ jjmatchedPos = 3;
+ }
+ else if ((active1 & 0x100000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 120;
+ jjmatchedPos = 3;
+ }
+ return jjMoveStringLiteralDfa4_0(active0, 0x100000000ULL, active1, 0x208000c088000ULL);
+ case 117:
+ return jjMoveStringLiteralDfa4_0(active0, 0x92000000300000ULL, active1, 0x500000000ULL);
+ case 121:
+ if ((active0 & 0x2000000ULL) != 0L)
+ {
+ jjmatchedKind = 25;
+ jjmatchedPos = 3;
+ }
+ break;
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 3);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa4_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 3);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 3);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa5_0(active0, 0xc00000000000000ULL, active1, 0x10001002001000ULL);
+ case 67:
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x201000000ULL);
+ case 68:
+ return jjMoveStringLiteralDfa5_0(active0, 0x4000000000000ULL, active1, 0L);
+ case 69:
+ if ((active0 & 0x200000000000ULL) != 0L)
+ {
+ jjmatchedKind = 45;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x200000ULL) != 0L)
+ {
+ jjmatchedKind = 85;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x20000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 117;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x400000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 122;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x104000000ULL, active1, 0x24000f0000ULL);
+ case 70:
+ if ((active0 & 0x4000000000ULL) != 0L)
+ {
+ jjmatchedKind = 38;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x1000000000000ULL);
+ case 73:
+ return jjMoveStringLiteralDfa5_0(active0, 0x40420000ULL, active1, 0L);
+ case 75:
+ if ((active0 & 0x1000000ULL) != 0L)
+ {
+ jjmatchedKind = 24;
+ jjmatchedPos = 4;
+ }
+ break;
+ case 76:
+ if ((active0 & 0x200000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 57;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x4000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 114;
+ jjmatchedPos = 4;
+ }
+ break;
+ case 77:
+ return jjMoveStringLiteralDfa5_0(active0, 0x300000ULL, active1, 0x2000ULL);
+ case 78:
+ if ((active0 & 0x800000ULL) != 0L)
+ {
+ jjmatchedKind = 23;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x40000000000ULL, active1, 0x40000000000ULL);
+ case 79:
+ return jjMoveStringLiteralDfa5_0(active0, 0x810000000ULL, active1, 0L);
+ case 80:
+ if ((active0 & 0x2000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 49;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x40000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 118;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x8000ULL);
+ case 82:
+ if ((active0 & 0x2000ULL) != 0L)
+ {
+ jjmatchedKind = 13;
+ jjmatchedPos = 4;
+ }
+ else if ((active0 & 0x200000000ULL) != 0L)
+ {
+ jjmatchedKind = 33;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x1011800000080000ULL, active1, 0x92c400400ULL);
+ case 83:
+ if ((active0 & 0x4000ULL) != 0L)
+ {
+ jjmatchedKind = 14;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x2000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 113;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x1000ULL, active1, 0x400000800000ULL);
+ case 84:
+ if ((active0 & 0x80000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 55;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x80000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 119;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x40411080000000ULL, active1, 0L);
+ case 85:
+ return jjMoveStringLiteralDfa5_0(active0, 0x400000000ULL, active1, 0L);
+ case 89:
+ if ((active0 & 0x40000ULL) != 0L)
+ {
+ jjmatchedKind = 18;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x80000000000ULL);
+ case 97:
+ return jjMoveStringLiteralDfa5_0(active0, 0xc00000000000000ULL, active1, 0x10001002001000ULL);
+ case 99:
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x201000000ULL);
+ case 100:
+ return jjMoveStringLiteralDfa5_0(active0, 0x4000000000000ULL, active1, 0L);
+ case 101:
+ if ((active0 & 0x200000000000ULL) != 0L)
+ {
+ jjmatchedKind = 45;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x200000ULL) != 0L)
+ {
+ jjmatchedKind = 85;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x20000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 117;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x400000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 122;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x104000000ULL, active1, 0x24000f0000ULL);
+ case 102:
+ if ((active0 & 0x4000000000ULL) != 0L)
+ {
+ jjmatchedKind = 38;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x1000000000000ULL);
+ case 105:
+ return jjMoveStringLiteralDfa5_0(active0, 0x40420000ULL, active1, 0L);
+ case 107:
+ if ((active0 & 0x1000000ULL) != 0L)
+ {
+ jjmatchedKind = 24;
+ jjmatchedPos = 4;
+ }
+ break;
+ case 108:
+ if ((active0 & 0x200000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 57;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x4000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 114;
+ jjmatchedPos = 4;
+ }
+ break;
+ case 109:
+ return jjMoveStringLiteralDfa5_0(active0, 0x300000ULL, active1, 0x2000ULL);
+ case 110:
+ if ((active0 & 0x800000ULL) != 0L)
+ {
+ jjmatchedKind = 23;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x40000000000ULL, active1, 0x40000000000ULL);
+ case 111:
+ return jjMoveStringLiteralDfa5_0(active0, 0x810000000ULL, active1, 0L);
+ case 112:
+ if ((active0 & 0x2000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 49;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x40000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 118;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x8000ULL);
+ case 114:
+ if ((active0 & 0x2000ULL) != 0L)
+ {
+ jjmatchedKind = 13;
+ jjmatchedPos = 4;
+ }
+ else if ((active0 & 0x200000000ULL) != 0L)
+ {
+ jjmatchedKind = 33;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x1011800000080000ULL, active1, 0x92c400400ULL);
+ case 115:
+ if ((active0 & 0x4000ULL) != 0L)
+ {
+ jjmatchedKind = 14;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x2000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 113;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x1000ULL, active1, 0x400000800000ULL);
+ case 116:
+ if ((active0 & 0x80000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 55;
+ jjmatchedPos = 4;
+ }
+ else if ((active1 & 0x80000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 119;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x40411080000000ULL, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa5_0(active0, 0x400000000ULL, active1, 0L);
+ case 121:
+ if ((active0 & 0x40000ULL) != 0L)
+ {
+ jjmatchedKind = 18;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x80000000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 4);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa5_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 4);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 4);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa6_0(active0, 0x1000800080000000ULL, active1, 0L);
+ case 66:
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000ULL, active1, 0x10000000000000ULL);
+ case 67:
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x80000ULL);
+ case 68:
+ if ((active1 & 0x400000ULL) != 0L)
+ {
+ jjmatchedKind = 86;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x2000000000ULL) != 0L)
+ {
+ jjmatchedKind = 101;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x10000ULL);
+ case 69:
+ if ((active0 & 0x100000ULL) != 0L)
+ {
+ jjmatchedKind = 20;
+ jjmatchedPos = 5;
+ }
+ else if ((active0 & 0x10000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 52;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x4040000200000ULL, active1, 0x1000000002000ULL);
+ case 71:
+ if ((active1 & 0x40000000000ULL) != 0L)
+ {
+ jjmatchedKind = 106;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x800000040000000ULL, active1, 0x1000ULL);
+ case 73:
+ return jjMoveStringLiteralDfa6_0(active0, 0x41400000000000ULL, active1, 0x80c000000ULL);
+ case 76:
+ if ((active1 & 0x1000000000ULL) != 0L)
+ {
+ jjmatchedKind = 100;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000000ULL, active1, 0L);
+ case 78:
+ if ((active1 & 0x100000000ULL) != 0L)
+ {
+ jjmatchedKind = 96;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x810000000ULL, active1, 0x400000000ULL);
+ case 79:
+ if ((active0 & 0x1000000000ULL) != 0L)
+ {
+ jjmatchedKind = 36;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x8000ULL);
+ case 80:
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x480000000000ULL);
+ case 82:
+ if ((active0 & 0x4000000ULL) != 0L)
+ {
+ jjmatchedKind = 26;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000000000000ULL, active1, 0x40000ULL);
+ case 83:
+ if ((active0 & 0x1000ULL) != 0L)
+ {
+ jjmatchedKind = 12;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x400ULL) != 0L)
+ {
+ jjmatchedKind = 74;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2020000ULL);
+ case 84:
+ if ((active0 & 0x80000ULL) != 0L)
+ {
+ jjmatchedKind = 19;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x1000000ULL) != 0L)
+ {
+ jjmatchedKind = 88;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x20000000ULL) != 0L)
+ {
+ jjmatchedKind = 93;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x200000000ULL) != 0L)
+ {
+ jjmatchedKind = 97;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x20000ULL, active1, 0x800000ULL);
+ case 88:
+ return jjMoveStringLiteralDfa6_0(active0, 0x100000000ULL, active1, 0L);
+ case 89:
+ if ((active0 & 0x10000000000ULL) != 0L)
+ {
+ jjmatchedKind = 40;
+ jjmatchedPos = 5;
+ }
+ break;
+ case 97:
+ return jjMoveStringLiteralDfa6_0(active0, 0x1000800080000000ULL, active1, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000ULL, active1, 0x10000000000000ULL);
+ case 99:
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x80000ULL);
+ case 100:
+ if ((active1 & 0x400000ULL) != 0L)
+ {
+ jjmatchedKind = 86;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x2000000000ULL) != 0L)
+ {
+ jjmatchedKind = 101;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x10000ULL);
+ case 101:
+ if ((active0 & 0x100000ULL) != 0L)
+ {
+ jjmatchedKind = 20;
+ jjmatchedPos = 5;
+ }
+ else if ((active0 & 0x10000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 52;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x4040000200000ULL, active1, 0x1000000002000ULL);
+ case 103:
+ if ((active1 & 0x40000000000ULL) != 0L)
+ {
+ jjmatchedKind = 106;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x800000040000000ULL, active1, 0x1000ULL);
+ case 105:
+ return jjMoveStringLiteralDfa6_0(active0, 0x41400000000000ULL, active1, 0x80c000000ULL);
+ case 108:
+ if ((active1 & 0x1000000000ULL) != 0L)
+ {
+ jjmatchedKind = 100;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000000ULL, active1, 0L);
+ case 110:
+ if ((active1 & 0x100000000ULL) != 0L)
+ {
+ jjmatchedKind = 96;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x810000000ULL, active1, 0x400000000ULL);
+ case 111:
+ if ((active0 & 0x1000000000ULL) != 0L)
+ {
+ jjmatchedKind = 36;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x8000ULL);
+ case 112:
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x480000000000ULL);
+ case 114:
+ if ((active0 & 0x4000000ULL) != 0L)
+ {
+ jjmatchedKind = 26;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x400000000000000ULL, active1, 0x40000ULL);
+ case 115:
+ if ((active0 & 0x1000ULL) != 0L)
+ {
+ jjmatchedKind = 12;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x400ULL) != 0L)
+ {
+ jjmatchedKind = 74;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2020000ULL);
+ case 116:
+ if ((active0 & 0x80000ULL) != 0L)
+ {
+ jjmatchedKind = 19;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x1000000ULL) != 0L)
+ {
+ jjmatchedKind = 88;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x20000000ULL) != 0L)
+ {
+ jjmatchedKind = 93;
+ jjmatchedPos = 5;
+ }
+ else if ((active1 & 0x200000000ULL) != 0L)
+ {
+ jjmatchedKind = 97;
+ jjmatchedPos = 5;
+ }
+ return jjMoveStringLiteralDfa6_0(active0, 0x20000ULL, active1, 0x800000ULL);
+ case 120:
+ return jjMoveStringLiteralDfa6_0(active0, 0x100000000ULL, active1, 0L);
+ case 121:
+ if ((active0 & 0x10000000000ULL) != 0L)
+ {
+ jjmatchedKind = 40;
+ jjmatchedPos = 5;
+ }
+ break;
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 5);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa6_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 5);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 5);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000000000000ULL, active1, 0L);
+ case 67:
+ if ((active0 & 0x1000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 48;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x100040c000000ULL);
+ case 68:
+ if ((active0 & 0x4000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 50;
+ jjmatchedPos = 6;
+ }
+ break;
+ case 69:
+ if ((active0 & 0x800000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 59;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x1000ULL) != 0L)
+ {
+ jjmatchedKind = 76;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x2000000ULL) != 0L)
+ {
+ jjmatchedKind = 89;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x80000000000ULL) != 0L)
+ {
+ jjmatchedKind = 107;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x10020000ULL, active1, 0x800000ULL);
+ case 76:
+ if ((active0 & 0x1000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 60;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x10000000000000ULL);
+ case 78:
+ return jjMoveStringLiteralDfa7_0(active0, 0x880000000ULL, active1, 0x8000ULL);
+ case 79:
+ return jjMoveStringLiteralDfa7_0(active0, 0x400000000000ULL, active1, 0x400000000000ULL);
+ case 83:
+ if ((active1 & 0x20000ULL) != 0L)
+ {
+ jjmatchedKind = 81;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000000000ULL, active1, 0L);
+ case 84:
+ if ((active0 & 0x100000000ULL) != 0L)
+ {
+ jjmatchedKind = 32;
+ jjmatchedPos = 6;
+ }
+ else if ((active0 & 0x400000000ULL) != 0L)
+ {
+ jjmatchedKind = 34;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x800000000000ULL, active1, 0x8000c2000ULL);
+ case 85:
+ return jjMoveStringLiteralDfa7_0(active0, 0x40400000ULL, active1, 0x10000ULL);
+ case 89:
+ if ((active0 & 0x400000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 58;
+ jjmatchedPos = 6;
+ }
+ break;
+ case 95:
+ return jjMoveStringLiteralDfa7_0(active0, 0x200000ULL, active1, 0L);
+ case 97:
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000000000000ULL, active1, 0L);
+ case 99:
+ if ((active0 & 0x1000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 48;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x100040c000000ULL);
+ case 100:
+ if ((active0 & 0x4000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 50;
+ jjmatchedPos = 6;
+ }
+ break;
+ case 101:
+ if ((active0 & 0x800000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 59;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x1000ULL) != 0L)
+ {
+ jjmatchedKind = 76;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x2000000ULL) != 0L)
+ {
+ jjmatchedKind = 89;
+ jjmatchedPos = 6;
+ }
+ else if ((active1 & 0x80000000000ULL) != 0L)
+ {
+ jjmatchedKind = 107;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x10020000ULL, active1, 0x800000ULL);
+ case 108:
+ if ((active0 & 0x1000000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 60;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x10000000000000ULL);
+ case 110:
+ return jjMoveStringLiteralDfa7_0(active0, 0x880000000ULL, active1, 0x8000ULL);
+ case 111:
+ return jjMoveStringLiteralDfa7_0(active0, 0x400000000000ULL, active1, 0x400000000000ULL);
+ case 115:
+ if ((active1 & 0x20000ULL) != 0L)
+ {
+ jjmatchedKind = 81;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000000000ULL, active1, 0L);
+ case 116:
+ if ((active0 & 0x100000000ULL) != 0L)
+ {
+ jjmatchedKind = 32;
+ jjmatchedPos = 6;
+ }
+ else if ((active0 & 0x400000000ULL) != 0L)
+ {
+ jjmatchedKind = 34;
+ jjmatchedPos = 6;
+ }
+ return jjMoveStringLiteralDfa7_0(active0, 0x800000000000ULL, active1, 0x8000c2000ULL);
+ case 117:
+ return jjMoveStringLiteralDfa7_0(active0, 0x40400000ULL, active1, 0x10000ULL);
+ case 121:
+ if ((active0 & 0x400000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 58;
+ jjmatchedPos = 6;
+ }
+ break;
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 6);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa7_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 6);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 6);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 67:
+ return jjMoveStringLiteralDfa8_0(active0, 0x20000ULL, active1, 0L);
+ case 69:
+ if ((active0 & 0x800000000000ULL) != 0L)
+ {
+ jjmatchedKind = 47;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x400000000ULL) != 0L)
+ {
+ jjmatchedKind = 98;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x10000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 116;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x800000000ULL, active1, 0x8a000ULL);
+ case 71:
+ return jjMoveStringLiteralDfa8_0(active0, 0x200000ULL, active1, 0L);
+ case 76:
+ if ((active0 & 0x40000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 54;
+ jjmatchedPos = 7;
+ }
+ break;
+ case 78:
+ if ((active0 & 0x400000000000ULL) != 0L)
+ {
+ jjmatchedKind = 46;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x10000000ULL, active1, 0L);
+ case 82:
+ if ((active1 & 0x800000ULL) != 0L)
+ {
+ jjmatchedKind = 87;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x40000000ULL, active1, 0x400000010000ULL);
+ case 83:
+ if ((active0 & 0x40000000000ULL) != 0L)
+ {
+ jjmatchedKind = 42;
+ jjmatchedPos = 7;
+ }
+ break;
+ case 84:
+ if ((active0 & 0x80000000ULL) != 0L)
+ {
+ jjmatchedKind = 31;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x4000000ULL) != 0L)
+ {
+ jjmatchedKind = 90;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x400000ULL, active1, 0x1000008000000ULL);
+ case 89:
+ if ((active1 & 0x40000ULL) != 0L)
+ {
+ jjmatchedKind = 82;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x800000000ULL) != 0L)
+ {
+ jjmatchedKind = 99;
+ jjmatchedPos = 7;
+ }
+ break;
+ case 99:
+ return jjMoveStringLiteralDfa8_0(active0, 0x20000ULL, active1, 0L);
+ case 101:
+ if ((active0 & 0x800000000000ULL) != 0L)
+ {
+ jjmatchedKind = 47;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x400000000ULL) != 0L)
+ {
+ jjmatchedKind = 98;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x10000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 116;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x800000000ULL, active1, 0x8a000ULL);
+ case 103:
+ return jjMoveStringLiteralDfa8_0(active0, 0x200000ULL, active1, 0L);
+ case 108:
+ if ((active0 & 0x40000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 54;
+ jjmatchedPos = 7;
+ }
+ break;
+ case 110:
+ if ((active0 & 0x400000000000ULL) != 0L)
+ {
+ jjmatchedKind = 46;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x10000000ULL, active1, 0L);
+ case 114:
+ if ((active1 & 0x800000ULL) != 0L)
+ {
+ jjmatchedKind = 87;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x40000000ULL, active1, 0x400000010000ULL);
+ case 115:
+ if ((active0 & 0x40000000000ULL) != 0L)
+ {
+ jjmatchedKind = 42;
+ jjmatchedPos = 7;
+ }
+ break;
+ case 116:
+ if ((active0 & 0x80000000ULL) != 0L)
+ {
+ jjmatchedKind = 31;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x4000000ULL) != 0L)
+ {
+ jjmatchedKind = 90;
+ jjmatchedPos = 7;
+ }
+ return jjMoveStringLiteralDfa8_0(active0, 0x400000ULL, active1, 0x1000008000000ULL);
+ case 121:
+ if ((active1 & 0x40000ULL) != 0L)
+ {
+ jjmatchedKind = 82;
+ jjmatchedPos = 7;
+ }
+ else if ((active1 & 0x800000000ULL) != 0L)
+ {
+ jjmatchedKind = 99;
+ jjmatchedPos = 7;
+ }
+ break;
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 7);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa8_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 7);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 7);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa9_0(active0, 0x40000000ULL, active1, 0L);
+ case 67:
+ return jjMoveStringLiteralDfa9_0(active0, 0x800000000ULL, active1, 0L);
+ case 68:
+ if ((active1 & 0x8000ULL) != 0L)
+ {
+ jjmatchedKind = 79;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x80000ULL) != 0L)
+ {
+ jjmatchedKind = 83;
+ jjmatchedPos = 8;
+ }
+ break;
+ case 69:
+ if ((active0 & 0x400000ULL) != 0L)
+ {
+ jjmatchedKind = 22;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x10000ULL) != 0L)
+ {
+ jjmatchedKind = 80;
+ jjmatchedPos = 8;
+ }
+ return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0x1000000000000ULL);
+ case 82:
+ if ((active1 & 0x2000ULL) != 0L)
+ {
+ jjmatchedKind = 77;
+ jjmatchedPos = 8;
+ }
+ break;
+ case 84:
+ if ((active0 & 0x10000000ULL) != 0L)
+ {
+ jjmatchedKind = 28;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x400000000000ULL) != 0L)
+ {
+ jjmatchedKind = 110;
+ jjmatchedPos = 8;
+ }
+ return jjMoveStringLiteralDfa9_0(active0, 0x20000ULL, active1, 0L);
+ case 85:
+ return jjMoveStringLiteralDfa9_0(active0, 0x200000ULL, active1, 0L);
+ case 95:
+ return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0x8000000ULL);
+ case 97:
+ return jjMoveStringLiteralDfa9_0(active0, 0x40000000ULL, active1, 0L);
+ case 99:
+ return jjMoveStringLiteralDfa9_0(active0, 0x800000000ULL, active1, 0L);
+ case 100:
+ if ((active1 & 0x8000ULL) != 0L)
+ {
+ jjmatchedKind = 79;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x80000ULL) != 0L)
+ {
+ jjmatchedKind = 83;
+ jjmatchedPos = 8;
+ }
+ break;
+ case 101:
+ if ((active0 & 0x400000ULL) != 0L)
+ {
+ jjmatchedKind = 22;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x10000ULL) != 0L)
+ {
+ jjmatchedKind = 80;
+ jjmatchedPos = 8;
+ }
+ return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0x1000000000000ULL);
+ case 114:
+ if ((active1 & 0x2000ULL) != 0L)
+ {
+ jjmatchedKind = 77;
+ jjmatchedPos = 8;
+ }
+ break;
+ case 116:
+ if ((active0 & 0x10000000ULL) != 0L)
+ {
+ jjmatchedKind = 28;
+ jjmatchedPos = 8;
+ }
+ else if ((active1 & 0x400000000000ULL) != 0L)
+ {
+ jjmatchedKind = 110;
+ jjmatchedPos = 8;
+ }
+ return jjMoveStringLiteralDfa9_0(active0, 0x20000ULL, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa9_0(active0, 0x200000ULL, active1, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 8);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa9_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 8);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 8);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa10_0(active0, 0x200000ULL, active1, 0L);
+ case 68:
+ if ((active1 & 0x1000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 112;
+ jjmatchedPos = 9;
+ }
+ break;
+ case 71:
+ return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x8000000ULL);
+ case 84:
+ if ((active0 & 0x800000000ULL) != 0L)
+ {
+ jjmatchedKind = 35;
+ jjmatchedPos = 9;
+ }
+ return jjMoveStringLiteralDfa10_0(active0, 0x40000000ULL, active1, 0L);
+ case 85:
+ return jjMoveStringLiteralDfa10_0(active0, 0x20000ULL, active1, 0L);
+ case 97:
+ return jjMoveStringLiteralDfa10_0(active0, 0x200000ULL, active1, 0L);
+ case 100:
+ if ((active1 & 0x1000000000000ULL) != 0L)
+ {
+ jjmatchedKind = 112;
+ jjmatchedPos = 9;
+ }
+ break;
+ case 103:
+ return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x8000000ULL);
+ case 116:
+ if ((active0 & 0x800000000ULL) != 0L)
+ {
+ jjmatchedKind = 35;
+ jjmatchedPos = 9;
+ }
+ return jjMoveStringLiteralDfa10_0(active0, 0x40000000ULL, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa10_0(active0, 0x20000ULL, active1, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 9);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa10_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 9);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 9);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 73:
+ return jjMoveStringLiteralDfa11_0(active0, 0x40000000ULL, active1, 0L);
+ case 82:
+ return jjMoveStringLiteralDfa11_0(active0, 0x220000ULL, active1, 0L);
+ case 85:
+ return jjMoveStringLiteralDfa11_0(active0, 0L, active1, 0x8000000ULL);
+ case 105:
+ return jjMoveStringLiteralDfa11_0(active0, 0x40000000ULL, active1, 0L);
+ case 114:
+ return jjMoveStringLiteralDfa11_0(active0, 0x220000ULL, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa11_0(active0, 0L, active1, 0x8000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 10);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa11_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 10);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 10);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x8000000ULL);
+ case 69:
+ if ((active0 & 0x20000ULL) != 0L)
+ {
+ jjmatchedKind = 17;
+ jjmatchedPos = 11;
+ }
+ return jjMoveStringLiteralDfa12_0(active0, 0x200000ULL, active1, 0L);
+ case 79:
+ return jjMoveStringLiteralDfa12_0(active0, 0x40000000ULL, active1, 0L);
+ case 97:
+ return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x8000000ULL);
+ case 101:
+ if ((active0 & 0x20000ULL) != 0L)
+ {
+ jjmatchedKind = 17;
+ jjmatchedPos = 11;
+ }
+ return jjMoveStringLiteralDfa12_0(active0, 0x200000ULL, active1, 0L);
+ case 111:
+ return jjMoveStringLiteralDfa12_0(active0, 0x40000000ULL, active1, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 11);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa12_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 11);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 11);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 78:
+ if ((active0 & 0x40000000ULL) != 0L)
+ {
+ jjmatchedKind = 30;
+ jjmatchedPos = 12;
+ }
+ return jjMoveStringLiteralDfa13_0(active0, 0x200000ULL, active1, 0L);
+ case 82:
+ return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x8000000ULL);
+ case 110:
+ if ((active0 & 0x40000000ULL) != 0L)
+ {
+ jjmatchedKind = 30;
+ jjmatchedPos = 12;
+ }
+ return jjMoveStringLiteralDfa13_0(active0, 0x200000ULL, active1, 0L);
+ case 114:
+ return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x8000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 12);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa13_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 12);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 12);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 65:
+ return jjMoveStringLiteralDfa14_0(active0, 0L, active1, 0x8000000ULL);
+ case 84:
+ return jjMoveStringLiteralDfa14_0(active0, 0x200000ULL, active1, 0L);
+ case 97:
+ return jjMoveStringLiteralDfa14_0(active0, 0L, active1, 0x8000000ULL);
+ case 116:
+ return jjMoveStringLiteralDfa14_0(active0, 0x200000ULL, active1, 0L);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 13);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa14_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 13);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 13);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 69:
+ return jjMoveStringLiteralDfa15_0(active0, 0x200000ULL, active1, 0L);
+ case 78:
+ return jjMoveStringLiteralDfa15_0(active0, 0L, active1, 0x8000000ULL);
+ case 101:
+ return jjMoveStringLiteralDfa15_0(active0, 0x200000ULL, active1, 0L);
+ case 110:
+ return jjMoveStringLiteralDfa15_0(active0, 0L, active1, 0x8000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 14);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa15_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 14);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 14);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 69:
+ if ((active0 & 0x200000ULL) != 0L)
+ {
+ jjmatchedKind = 21;
+ jjmatchedPos = 15;
+ }
+ break;
+ case 84:
+ return jjMoveStringLiteralDfa16_0(active0, 0L, active1, 0x8000000ULL);
+ case 101:
+ if ((active0 & 0x200000ULL) != 0L)
+ {
+ jjmatchedKind = 21;
+ jjmatchedPos = 15;
+ }
+ break;
+ case 116:
+ return jjMoveStringLiteralDfa16_0(active0, 0L, active1, 0x8000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 15);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa16_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1){
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 15);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 15);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 69:
+ return jjMoveStringLiteralDfa17_0(active1, 0x8000000ULL);
+ case 101:
+ return jjMoveStringLiteralDfa17_0(active1, 0x8000000ULL);
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 16);
+}
+
+ int VhdlParserTokenManager::jjMoveStringLiteralDfa17_0(unsigned long long old1, unsigned long long active1){
+ if (((active1 &= old1)) == 0L)
+ return jjMoveNfa_0(11, 16);
+ if (input_stream->endOfInput()) {
+ return jjMoveNfa_0(11, 16);
+ }
+ curChar = input_stream->readChar();
+ switch(curChar)
+ {
+ case 69:
+ if ((active1 & 0x8000000ULL) != 0L)
+ {
+ jjmatchedKind = 91;
+ jjmatchedPos = 17;
+ }
+ break;
+ case 101:
+ if ((active1 & 0x8000000ULL) != 0L)
+ {
+ jjmatchedKind = 91;
+ jjmatchedPos = 17;
+ }
+ break;
+ default :
+ break;
+ }
+ return jjMoveNfa_0(11, 17);
+}
+
+int VhdlParserTokenManager::jjMoveNfa_0(int startState, int curPos){
+ int strKind = jjmatchedKind;
+ int strPos = jjmatchedPos;
+ int seenUpto;
+ input_stream->backup(seenUpto = curPos + 1);
+ assert(!input_stream->endOfInput());
+ curChar = input_stream->readChar();
+ curPos = 0;
+ int startsAt = 0;
+ jjnewStateCnt = 75;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int kind = 0x7fffffff;
+ for (;;)
+ {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ unsigned long long l = 1ULL << curChar;
+ (void)l;
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 11:
+ if ((0x3ff000000000000ULL & l) != 0L)
+ {
+ if (kind > 165)
+ kind = 165;
+ { jjCheckNAddStates(0, 8); }
+ }
+ else if ((0x100000200ULL & l) != 0L)
+ { jjCheckNAddTwoStates(0, 3); }
+ else if (curChar == 47)
+ { jjAddStates(9, 10); }
+ else if (curChar == 45)
+ { jjCheckNAddStates(11, 13); }
+ else if (curChar == 39)
+ jjstateSet[jjnewStateCnt++] = 18;
+ else if (curChar == 34)
+ { jjCheckNAddTwoStates(9, 10); }
+ if ((0x3ff000000000000ULL & l) != 0L)
+ {
+ if (kind > 171)
+ kind = 171;
+ { jjCheckNAdd(20); }
+ }
+ break;
+ case 0:
+ if ((0x100000200ULL & l) != 0L)
+ { jjCheckNAddTwoStates(0, 3); }
+ break;
+ case 1:
+ if (curChar != 33)
+ break;
+ if (kind > 6)
+ kind = 6;
+ { jjCheckNAddStates(14, 18); }
+ break;
+ case 2:
+ if (curChar == 45)
+ jjstateSet[jjnewStateCnt++] = 1;
+ break;
+ case 3:
+ if (curChar == 45)
+ { jjCheckNAdd(2); }
+ break;
+ case 4:
+ if ((0xffffffffffffdbffULL & l) == 0L)
+ break;
+ if (kind > 6)
+ kind = 6;
+ { jjCheckNAddStates(14, 18); }
+ break;
+ case 5:
+ if ((0x2400ULL & l) == 0L)
+ break;
+ if (kind > 6)
+ kind = 6;
+ { jjCheckNAddTwoStates(0, 3); }
+ break;
+ case 6:
+ if (curChar != 10)
+ break;
+ if (kind > 6)
+ kind = 6;
+ { jjCheckNAddTwoStates(0, 3); }
+ break;
+ case 7:
+ if (curChar == 13)
+ jjstateSet[jjnewStateCnt++] = 6;
+ break;
+ case 8:
+ if (curChar == 34)
+ { jjCheckNAddTwoStates(9, 10); }
+ break;
+ case 9:
+ if ((0xfffffffb00000200ULL & l) != 0L)
+ { jjCheckNAddTwoStates(9, 10); }
+ break;
+ case 10:
+ if (curChar != 34)
+ break;
+ if (kind > 166)
+ kind = 166;
+ jjstateSet[jjnewStateCnt++] = 8;
+ break;
+ case 13:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 167)
+ kind = 167;
+ { jjAddStates(19, 20); }
+ break;
+ case 15:
+ if ((0xfffffffb00000200ULL & l) != 0L)
+ { jjAddStates(21, 22); }
+ break;
+ case 17:
+ if (curChar == 39)
+ jjstateSet[jjnewStateCnt++] = 18;
+ break;
+ case 18:
+ if ((0xfffffffb00000200ULL & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 19;
+ break;
+ case 19:
+ if (curChar == 39 && kind > 169)
+ kind = 169;
+ break;
+ case 20:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 171)
+ kind = 171;
+ { jjCheckNAdd(20); }
+ break;
+ case 22:
+ if (curChar == 34)
+ { jjCheckNAddTwoStates(23, 24); }
+ break;
+ case 23:
+ if ((0x3ff000000000000ULL & l) != 0L)
+ { jjCheckNAddTwoStates(23, 24); }
+ break;
+ case 24:
+ if (curChar == 34 && kind > 179)
+ kind = 179;
+ break;
+ case 26:
+ if (curChar == 34)
+ { jjCheckNAddTwoStates(27, 28); }
+ break;
+ case 27:
+ if ((0xfffffffb00000200ULL & l) != 0L)
+ { jjCheckNAddTwoStates(27, 28); }
+ break;
+ case 28:
+ if (curChar != 34)
+ break;
+ if (kind > 186)
+ kind = 186;
+ { jjCheckNAddTwoStates(26, 29); }
+ break;
+ case 29:
+ if ((0xfffffffb00000200ULL & l) == 0L)
+ break;
+ if (kind > 186)
+ kind = 186;
+ { jjCheckNAddTwoStates(26, 29); }
+ break;
+ case 30:
+ if (curChar == 45)
+ { jjCheckNAddStates(11, 13); }
+ break;
+ case 31:
+ if (curChar != 35)
+ break;
+ if (kind > 7)
+ kind = 7;
+ { jjCheckNAddStates(23, 25); }
+ break;
+ case 32:
+ if ((0xffffffffffffdbffULL & l) == 0L)
+ break;
+ if (kind > 7)
+ kind = 7;
+ { jjCheckNAddStates(23, 25); }
+ break;
+ case 33:
+ if ((0x2400ULL & l) != 0L && kind > 7)
+ kind = 7;
+ break;
+ case 34:
+ if (curChar == 10 && kind > 7)
+ kind = 7;
+ break;
+ case 35:
+ if (curChar == 13)
+ jjstateSet[jjnewStateCnt++] = 34;
+ break;
+ case 36:
+ if (curChar == 45)
+ jjstateSet[jjnewStateCnt++] = 31;
+ break;
+ case 37:
+ if (curChar != 45)
+ break;
+ if (kind > 8)
+ kind = 8;
+ { jjCheckNAddStates(26, 28); }
+ break;
+ case 38:
+ if ((0xffffffffffffdbffULL & l) == 0L)
+ break;
+ if (kind > 8)
+ kind = 8;
+ { jjCheckNAddStates(26, 28); }
+ break;
+ case 39:
+ if ((0x2400ULL & l) != 0L && kind > 8)
+ kind = 8;
+ break;
+ case 40:
+ if (curChar == 10 && kind > 8)
+ kind = 8;
+ break;
+ case 41:
+ if (curChar == 13)
+ jjstateSet[jjnewStateCnt++] = 40;
+ break;
+ case 42:
+ if (curChar == 47)
+ { jjAddStates(9, 10); }
+ break;
+ case 43:
+ if (curChar == 33)
+ { jjCheckNAddTwoStates(44, 46); }
+ break;
+ case 44:
+ { jjCheckNAddTwoStates(44, 46); }
+ break;
+ case 45:
+ if (curChar == 47 && kind > 9)
+ kind = 9;
+ break;
+ case 46:
+ if (curChar == 42)
+ jjstateSet[jjnewStateCnt++] = 45;
+ break;
+ case 47:
+ if (curChar == 42)
+ jjstateSet[jjnewStateCnt++] = 43;
+ break;
+ case 48:
+ if (curChar == 42)
+ { jjCheckNAddTwoStates(49, 51); }
+ break;
+ case 49:
+ { jjCheckNAddTwoStates(49, 51); }
+ break;
+ case 50:
+ if (curChar == 47 && kind > 10)
+ kind = 10;
+ break;
+ case 51:
+ if (curChar == 42)
+ jjstateSet[jjnewStateCnt++] = 50;
+ break;
+ case 52:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 165)
+ kind = 165;
+ { jjCheckNAddStates(0, 8); }
+ break;
+ case 54:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 165)
+ kind = 165;
+ { jjCheckNAddTwoStates(53, 54); }
+ break;
+ case 56:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 170)
+ kind = 170;
+ { jjCheckNAddStates(29, 32); }
+ break;
+ case 57:
+ if (curChar == 46)
+ { jjCheckNAdd(58); }
+ break;
+ case 58:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 170)
+ kind = 170;
+ { jjCheckNAddStates(33, 35); }
+ break;
+ case 61:
+ if ((0x280000000000ULL & l) != 0L)
+ { jjCheckNAdd(62); }
+ break;
+ case 62:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 170)
+ kind = 170;
+ { jjCheckNAddTwoStates(63, 62); }
+ break;
+ case 65:
+ if ((0x3ff000000000000ULL & l) != 0L)
+ { jjCheckNAddStates(36, 38); }
+ break;
+ case 66:
+ if (curChar == 35)
+ { jjCheckNAdd(67); }
+ break;
+ case 67:
+ if ((0x3ff000000000000ULL & l) != 0L)
+ { jjCheckNAddStates(39, 41); }
+ break;
+ case 68:
+ if (curChar == 46)
+ { jjCheckNAdd(69); }
+ break;
+ case 69:
+ if ((0x3ff000000000000ULL & l) != 0L)
+ { jjCheckNAddTwoStates(69, 70); }
+ break;
+ case 70:
+ if (curChar != 35)
+ break;
+ if (kind > 172)
+ kind = 172;
+ jjstateSet[jjnewStateCnt++] = 71;
+ break;
+ case 72:
+ if ((0x280000000000ULL & l) != 0L)
+ { jjCheckNAdd(73); }
+ break;
+ case 73:
+ if ((0x3ff000000000000ULL & l) == 0L)
+ break;
+ if (kind > 172)
+ kind = 172;
+ { jjCheckNAddTwoStates(74, 73); }
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ unsigned long long l = 1ULL << (curChar & 077);
+ (void)l;
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 11:
+ if ((0x7fffffe07fffffeULL & l) != 0L)
+ {
+ if (kind > 171)
+ kind = 171;
+ { jjCheckNAdd(20); }
+ }
+ else if (curChar == 96)
+ { jjCheckNAddTwoStates(26, 29); }
+ else if (curChar == 92)
+ { jjCheckNAddTwoStates(15, 16); }
+ if ((0x7fffffe07fffffeULL & l) != 0L)
+ {
+ if (kind > 167)
+ kind = 167;
+ { jjCheckNAddTwoStates(12, 13); }
+ }
+ if ((0x100800401008004ULL & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 22;
+ break;
+ case 4:
+ if (kind > 6)
+ kind = 6;
+ { jjAddStates(14, 18); }
+ break;
+ case 9:
+ if ((0x7fffffffffffffffULL & l) != 0L)
+ { jjAddStates(42, 43); }
+ break;
+ case 12:
+ if (curChar == 95)
+ { jjCheckNAddTwoStates(12, 13); }
+ break;
+ case 13:
+ if ((0x7fffffe07fffffeULL & l) == 0L)
+ break;
+ if (kind > 167)
+ kind = 167;
+ { jjCheckNAddTwoStates(12, 13); }
+ break;
+ case 14:
+ if (curChar == 92)
+ { jjCheckNAddTwoStates(15, 16); }
+ break;
+ case 15:
+ if ((0x7fffffffffffffffULL & l) != 0L)
+ { jjCheckNAddTwoStates(15, 16); }
+ break;
+ case 16:
+ if (curChar == 92 && kind > 168)
+ kind = 168;
+ break;
+ case 18:
+ if ((0x7fffffffffffffffULL & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 19;
+ break;
+ case 20:
+ if ((0x7fffffe07fffffeULL & l) == 0L)
+ break;
+ if (kind > 171)
+ kind = 171;
+ { jjCheckNAdd(20); }
+ break;
+ case 21:
+ if ((0x100800401008004ULL & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 22;
+ break;
+ case 23:
+ if ((0x7fffffe07fffffeULL & l) != 0L)
+ { jjAddStates(44, 45); }
+ break;
+ case 25:
+ if (curChar == 96)
+ { jjCheckNAddTwoStates(26, 29); }
+ break;
+ case 27:
+ if ((0x7fffffffffffffffULL & l) != 0L)
+ { jjAddStates(46, 47); }
+ break;
+ case 29:
+ if ((0x7fffffffffffffffULL & l) == 0L)
+ break;
+ if (kind > 186)
+ kind = 186;
+ { jjCheckNAddTwoStates(26, 29); }
+ break;
+ case 32:
+ if (kind > 7)
+ kind = 7;
+ { jjAddStates(23, 25); }
+ break;
+ case 38:
+ if (kind > 8)
+ kind = 8;
+ { jjAddStates(26, 28); }
+ break;
+ case 44:
+ { jjAddStates(48, 49); }
+ break;
+ case 49:
+ { jjAddStates(50, 51); }
+ break;
+ case 53:
+ if (curChar == 95)
+ jjstateSet[jjnewStateCnt++] = 54;
+ break;
+ case 55:
+ if (curChar == 95)
+ jjstateSet[jjnewStateCnt++] = 56;
+ break;
+ case 59:
+ if (curChar == 95)
+ jjstateSet[jjnewStateCnt++] = 58;
+ break;
+ case 60:
+ if ((0x2000000020ULL & l) != 0L)
+ { jjCheckNAddTwoStates(61, 62); }
+ break;
+ case 63:
+ if (curChar == 95)
+ { jjCheckNAdd(62); }
+ break;
+ case 64:
+ if (curChar == 95)
+ jjstateSet[jjnewStateCnt++] = 65;
+ break;
+ case 67:
+ if ((0x7fffffe07fffffeULL & l) != 0L)
+ { jjCheckNAddStates(39, 41); }
+ break;
+ case 69:
+ if ((0x7fffffe07fffffeULL & l) != 0L)
+ { jjCheckNAddTwoStates(69, 70); }
+ break;
+ case 71:
+ if ((0x2000000020ULL & l) != 0L)
+ { jjCheckNAddTwoStates(72, 73); }
+ break;
+ case 74:
+ if (curChar == 95)
+ { jjCheckNAdd(73); }
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else
+ {
+ int hiByte = (curChar >> 8);
+ int i1 = hiByte >> 6;
+ unsigned long long l1 = 1ULL << (hiByte & 077);
+ int i2 = (curChar & 0xff) >> 6;
+ unsigned long long l2 = 1ULL << (curChar & 077);
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 4:
+ if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 6)
+ kind = 6;
+ { jjAddStates(14, 18); }
+ break;
+ case 9:
+ if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+ { jjAddStates(42, 43); }
+ break;
+ case 15:
+ if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+ { jjAddStates(21, 22); }
+ break;
+ case 18:
+ if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+ jjstateSet[jjnewStateCnt++] = 19;
+ break;
+ case 27:
+ if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+ { jjAddStates(46, 47); }
+ break;
+ case 29:
+ if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 186)
+ kind = 186;
+ { jjAddStates(52, 53); }
+ break;
+ case 32:
+ if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 7)
+ kind = 7;
+ { jjAddStates(23, 25); }
+ break;
+ case 38:
+ if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 8)
+ kind = 8;
+ { jjAddStates(26, 28); }
+ break;
+ case 44:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ { jjAddStates(48, 49); }
+ break;
+ case 49:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ { jjAddStates(50, 51); }
+ break;
+ default : if (i1 == 0 || l1 == 0 || i2 == 0 || l2 == 0) break; else break;
+ }
+ } while(i != startsAt);
+ }
+ if (kind != 0x7fffffff)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt), (jjnewStateCnt = startsAt), (i == (startsAt = 75 - startsAt)))
+ break;
+ if (input_stream->endOfInput()) { break; }
+ curChar = input_stream->readChar();
+ }
+ if (jjmatchedPos > strPos)
+ return curPos;
+
+ int toRet = MAX(curPos, seenUpto);
+
+ if (curPos < toRet)
+ for (i = toRet - MIN(curPos, seenUpto); i-- > 0; )
+ { assert(!input_stream->endOfInput());
+ curChar = input_stream->readChar(); }
+
+ if (jjmatchedPos < strPos)
+ {
+ jjmatchedKind = strKind;
+ jjmatchedPos = strPos;
+ }
+ else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
+ jjmatchedKind = strKind;
+
+ return toRet;
+}
+
+bool VhdlParserTokenManager::jjCanMove_0(int hiByte, int i1, int i2, unsigned long long l1, unsigned long long l2){
+ switch(hiByte)
+ {
+ case 0:
+ return ((jjbitVec2[i2] & l2) != 0L);
+ default :
+ if ((jjbitVec0[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+}
+
+bool VhdlParserTokenManager::jjCanMove_1(int hiByte, int i1, int i2, unsigned long long l1, unsigned long long l2){
+ switch(hiByte)
+ {
+ case 0:
+ return ((jjbitVec3[i2] & l2) != 0L);
+ default :
+ return false;
+ }
+}
+
+/** Token literal values. */
+
+Token * VhdlParserTokenManager::jjFillToken(){
+ Token *t;
+ JAVACC_STRING_TYPE curTokenImage;
+ int beginLine;
+ int endLine;
+ int beginColumn;
+ int endColumn;
+ JAVACC_STRING_TYPE im = jjstrLiteralImages[jjmatchedKind];
+ curTokenImage = (im.length() == 0) ? input_stream->GetImage() : im;
+ if (input_stream->getTrackLineColumn()) {
+ beginLine = input_stream->getBeginLine();
+ beginColumn = input_stream->getBeginColumn();
+ endLine = input_stream->getEndLine();
+ endColumn = input_stream->getEndColumn();
+ }
+ t = Token::newToken(jjmatchedKind, curTokenImage);
+ t->specialToken = NULL;
+ t->next = NULL;
+
+ if (input_stream->getTrackLineColumn()) {
+ t->beginLine = beginLine;
+ t->endLine = endLine;
+ t->beginColumn = beginColumn;
+ t->endColumn = endColumn;
+ }
+
+ return t;
+}
+const int defaultLexState = 0;
+/** Get the next Token. */
+
+Token * VhdlParserTokenManager::getNextToken(){
+ Token *matchedToken;
+ int curPos = 0;
+
+ for (;;)
+ {
+ EOFLoop:
+ if (input_stream->endOfInput())
+ {
+ jjmatchedKind = 0;
+ jjmatchedPos = -1;
+ matchedToken = jjFillToken();
+ return matchedToken;
+ }
+ curChar = input_stream->BeginToken();
+ image = jjimage;
+ image.clear();
+ jjimageLen = 0;
+
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = jjMoveStringLiteralDfa0_0();
+ if (jjmatchedKind != 0x7fffffff)
+ {
+ if (jjmatchedPos + 1 < curPos)
+ input_stream->backup(curPos - jjmatchedPos - 1);
+ if ((jjtoToken[jjmatchedKind >> 6] & (1ULL << (jjmatchedKind & 077))) != 0L)
+ {
+ matchedToken = jjFillToken();
+ TokenLexicalActions(matchedToken);
+ return matchedToken;
+ }
+ else
+ {
+ SkipLexicalActions(NULL);
+ goto EOFLoop;
+ }
+ }
+ int error_line = input_stream->getEndLine();
+ int error_column = input_stream->getEndColumn();
+ JAVACC_STRING_TYPE error_after;
+ bool EOFSeen = false;
+ if (input_stream->endOfInput()) {
+ EOFSeen = true;
+ error_after = curPos <= 1 ? EMPTY : input_stream->GetImage();
+ if (curChar == '\n' || curChar == '\r') {
+ error_line++;
+ error_column = 0;
+ }
+ else
+ error_column++;
+ }
+ if (!EOFSeen) {
+ error_after = curPos <= 1 ? EMPTY : input_stream->GetImage();
+ }
+ errorHandler->lexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, this);
+ }
+}
+
+
+void VhdlParserTokenManager::SkipLexicalActions(Token *matchedToken){
+ switch(jjmatchedKind)
+ {
+ case 3 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::lineCount();
+ break;
+ }
+ case 6 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::handleCommentBlock(image.data(),TRUE);
+ break;
+ }
+ case 7 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::handleFlowComment(image.data());
+ break;
+ }
+ case 8 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::lineCount(image.data());
+ break;
+ }
+ case 9 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ QCString q(image.data());
+ q.stripPrefix("/*!");
+ q.resize(q.length()-2);
+ ::vhdl::parser::VhdlParser::handleCommentBlock(q.data(),TRUE);image.clear();
+ break;
+ }
+ case 10 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::lineCount(image.data());image.clear();
+ break;
+ }
+ default :
+ break;
+ }
+}
+
+void VhdlParserTokenManager::TokenLexicalActions(Token *matchedToken){
+ switch(jjmatchedKind)
+ {
+ case 17 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(ARCHITECTURE_T);
+ break;
+ }
+ case 18 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(ARRAY_T);
+ break;
+ }
+ case 22 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(ATTRIBUTE_T);
+ break;
+ }
+ case 25 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(BODY_T);
+ break;
+ }
+ case 28 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(COMPONENT_T);
+ break;
+ }
+ case 30 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(CONFIGURATION_T);
+ break;
+ }
+ case 31 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(CONSTANT_T);
+ break;
+ }
+ case 32 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(CONTEXT_T);
+ break;
+ }
+ case 39 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(END_T);
+ break;
+ }
+ case 40 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(ENTITY_T);
+ break;
+ }
+ case 43 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(FILE_T);
+ break;
+ }
+ case 46 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(FUNCTION_T);
+ break;
+ }
+ case 49 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(GROUP_T);
+ break;
+ }
+ case 58 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ VhdlParser::setLineParsed(LIBRARY_T);
+ break;
+ }
+ case 76 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(PACKAGE_T);
+ break;
+ }
+ case 78 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(PORT_T);
+ break;
+ }
+ case 80 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(PROCEDURE_T);
+ break;
+ }
+ case 81 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(PROCESS_T);
+ break;
+ }
+ case 86 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(RECORD_T);
+ break;
+ }
+ case 100 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(SIGNAL_T);
+ break;
+ }
+ case 107 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(SUBTYPE_T);
+ break;
+ }
+ case 111 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(TYPE_T);
+ break;
+ }
+ case 113 : {
+ image.append(input_stream->GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+ ::vhdl::parser::VhdlParser::setLineParsed(UNITS_T);
+ break;
+ }
+ default :
+ break;
+ }
+}
+ /** Reinitialise parser. */
+ void VhdlParserTokenManager::ReInit(JAVACC_CHARSTREAM *stream, int lexState, VhdlParser *parserArg) {
+ if (input_stream) delete input_stream;
+ jjmatchedPos = jjnewStateCnt = 0;
+ curLexState = lexState;
+ input_stream = stream;
+ ReInitRounds();
+ debugStream = stdout; // init
+ SwitchTo(lexState);
+ parser = parserArg;
+ errorHandler = new TokenManagerErrorHandler();
+ errorHandlerCreated = true;
+ }
+
+ void VhdlParserTokenManager::ReInitRounds() {
+ int i;
+ jjround = 0x80000001;
+ for (i = 75; i-- > 0;)
+ jjrounds[i] = 0x80000000;
+ }
+
+ /** Switch to specified lex state. */
+ void VhdlParserTokenManager::SwitchTo(int lexState) {
+ if (lexState >= 1 || lexState < 0)
+ assert(false);
+ //throw 1;//new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+ else
+ curLexState = lexState;
+ }
+
+ /** Constructor. */
+ VhdlParserTokenManager::VhdlParserTokenManager (JAVACC_CHARSTREAM *stream, int lexState, VhdlParser *parserArg)
+ {
+ input_stream = NULL;
+ ReInit(stream, lexState, parserArg);
+ }
+
+ // Destructor
+ VhdlParserTokenManager::~VhdlParserTokenManager () {
+ if (input_stream) delete input_stream;
+ if (errorHandlerCreated) delete errorHandler;
+ }
+
+}
+}
diff --git a/vhdlparser/VhdlParserTokenManager.h b/vhdlparser/VhdlParserTokenManager.h
new file mode 100644
index 0000000..3916069
--- /dev/null
+++ b/vhdlparser/VhdlParserTokenManager.h
@@ -0,0 +1,139 @@
+#ifndef VHDLPARSERTOKENMANAGER_H
+#define VHDLPARSERTOKENMANAGER_H
+#include "JavaCC.h"
+#include "CharStream.h"
+#include "Token.h"
+#include "ErrorHandler.h"
+#include "TokenManager.h"
+#include "VhdlParserConstants.h"
+#include "VhdlParser.h"
+
+namespace vhdl {
+namespace parser {
+class VhdlParser;
+
+/** Token Manager. */
+class VhdlParserTokenManager : public TokenManager {
+ public:
+
+ /** Debug output. */
+ FILE *debugStream;
+ /** Set debug output. */
+
+void setDebugStream(FILE *ds);
+
+ int jjStopAtPos(int pos, int kind);
+
+ int jjMoveStringLiteralDfa0_0();
+
+ int jjMoveStringLiteralDfa1_0(unsigned long long active0, unsigned long long active1, unsigned long long active2);
+
+ int jjMoveStringLiteralDfa2_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1, unsigned long long old2, unsigned long long active2);
+
+ int jjMoveStringLiteralDfa3_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1, unsigned long long old2, unsigned long long active2);
+
+ int jjMoveStringLiteralDfa4_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa5_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa6_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa7_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa8_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa9_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa10_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa11_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa12_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa13_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa14_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa15_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa16_0(unsigned long long old0, unsigned long long active0, unsigned long long old1, unsigned long long active1);
+
+ int jjMoveStringLiteralDfa17_0(unsigned long long old1, unsigned long long active1);
+
+int jjMoveNfa_0(int startState, int curPos);
+
+bool jjCanMove_0(int hiByte, int i1, int i2, unsigned long long l1, unsigned long long l2);
+
+bool jjCanMove_1(int hiByte, int i1, int i2, unsigned long long l1, unsigned long long l2);
+
+Token * jjFillToken();
+
+public: int curLexState;
+public: int jjnewStateCnt;
+public: int jjround;
+public: int jjmatchedPos;
+public: int jjmatchedKind;
+
+
+Token * getNextToken();
+
+void SkipLexicalActions(Token *matchedToken);
+
+void TokenLexicalActions(Token *matchedToken);
+#define jjCheckNAdd(state)\
+{\
+ if (jjrounds[state] != jjround)\
+ {\
+ jjstateSet[jjnewStateCnt++] = state;\
+ jjrounds[state] = jjround;\
+ }\
+}
+#define jjAddStates(start, end)\
+{\
+ for (int x = start; x <= end; x++) {\
+ jjstateSet[jjnewStateCnt++] = jjnextStates[x];\
+ } /*while (start++ != end);*/\
+}
+#define jjCheckNAddTwoStates(state1, state2)\
+{\
+ jjCheckNAdd(state1);\
+ jjCheckNAdd(state2);\
+}
+
+#define jjCheckNAddStates(start, end)\
+{\
+ for (int x = start; x <= end; x++) {\
+ jjCheckNAdd(jjnextStates[x]);\
+ } /*while (start++ != end);*/\
+}
+
+#ifndef JAVACC_CHARSTREAM
+#define JAVACC_CHARSTREAM CharStream
+#endif
+ private: VhdlParser*parser;
+ private: void ReInitRounds();
+ public: VhdlParserTokenManager(JAVACC_CHARSTREAM *stream, int lexState = 0, VhdlParser *parserArg = NULL);
+ public: virtual ~VhdlParserTokenManager();
+ void ReInit(JAVACC_CHARSTREAM *stream, int lexState = 0, VhdlParser *parserArg = NULL);
+ void SwitchTo(int lexState);
+ const JAVACC_SIMPLE_STRING jjKindsForBitVector(int i, unsigned long long vec);
+ const JAVACC_SIMPLE_STRING jjKindsForStateVector(int lexState, int vec[], int start, int end);
+ JAVACC_CHARSTREAM *input_stream;
+ int jjrounds[75];
+ int jjstateSet[2 * 75];
+ JAVACC_STRING_TYPE jjimage;
+ JAVACC_STRING_TYPE image;
+ int jjimageLen;
+ int lengthOfMatch;
+ JAVACC_CHAR_TYPE curChar;
+ TokenManagerErrorHandler *errorHandler;
+ bool errorHandlerCreated;
+ public: void setErrorHandler(TokenManagerErrorHandler *eh) {
+ if (errorHandlerCreated && errorHandler != NULL) delete errorHandler;
+ errorHandler = eh;
+ errorHandlerCreated = false;
+ }
+};
+}
+}
+#endif
diff --git a/vhdlparser/vhdlparser.jj b/vhdlparser/vhdlparser.jj
new file mode 100644
index 0000000..7a4283f
--- /dev/null
+++ b/vhdlparser/vhdlparser.jj
@@ -0,0 +1,2816 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 by M. Kreis
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ */
+options {
+ JAVA_UNICODE_ESCAPE = true;
+ OUTPUT_LANGUAGE = "c++";
+ NAMESPACE = "vhdl::parser";
+ STATIC=false;
+ PARSER_INCLUDES="vhdljjparser.h";
+ TOKEN_MANAGER_INCLUDES="VhdlParser.h";
+
+ //OUTPUT_DIRECTORY = ".";
+// DEBUG_PARSER=true;
+ //DEBUG_LOOKAHEAD=true;
+
+ }
+
+PARSER_BEGIN(VhdlParser)
+
+typedef unsigned long long uint64;
+
+
+static Entry* current_root;
+static Entry* tempEntry;
+static Entry* lastEntity ;
+static Entry* lastCompound ;
+static Entry* current;
+static QCString compSpec;
+static QCString currName;
+static int levelCounter;
+static QCString confName;
+static QCString genLabels;
+static QCString lab;
+static QCString forL;
+static int param_sec ;
+static int parse_sec;
+static int currP;
+static Entry* currentCompound;
+
+//----------------------------------------
+
+static void setLineParsed(int tok);
+static int getLine(int tok);
+static int getLine();
+static void lineCount(const char*);
+static void lineCount();
+static void addProto(const char *s1,const char *s2,const char *s3,const char *s4,const char *s5,const char *s6);
+static void addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf);
+static void createFunction(const char *impure,uint64 spec,const char *fname);
+static void addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot);
+static void addCompInst(char *n, char* instName, char* comp,int iLine);
+static void handleCommentBlock(const char* doc,bool brief);
+static void handleFlowComment(const char*);
+static void initEntry(Entry *e);
+static void newEntry();
+static bool isFuncProcProced();
+static void pushLabel(QCString &,QCString&);
+static QCString popLabel(QCString & q);
+static bool addLibUseClause(const QCString &type);
+static void mapLibPackage( Entry* root);
+static void createFlow();
+static void error_skipto(int kind);
+
+PARSER_END(VhdlParser)
+
+SKIP :
+{
+ " "
+| "\t"
+| "\n" {::vhdl::parser::VhdlParser::lineCount();}
+| "\r"
+}
+
+SKIP:
+{
+ // VHDL comment -- ......
+ // VHDL doxygen line comment --! ....
+ <#DOXYGEN_VHDL_COMMENT: (" "|"\t")*"--!"(~["\n", "\r"])* ("\n" | "\r" | "\r\n")?>
+ | <MULT_DOXYGEN_COMMENT: (<DOXYGEN_VHDL_COMMENT>)+ > { ::vhdl::parser::VhdlParser::handleCommentBlock(image.data(),TRUE); }
+ |<VHDL_FLOWCHART_COMMENT: "--#" (~["\n", "\r"])* ("\n" | "\r" | "\r\n")?> { ::vhdl::parser::VhdlParser::handleFlowComment(image.data());}
+ |<VHDL_COMMENT: "--" (~["\n", "\r"])* ("\n" | "\r" | "\r\n")?> { ::vhdl::parser::VhdlParser::lineCount(image.data());}
+ }
+
+// VHDL 2008 comment /* .... */
+// VHDL 2008 doxygen comment /*! .... */
+SKIP :
+{
+ <MULT_DOXYGEN_VHDL_COMMENT_2008 : "/*!" (~[])* "*/" >
+ {
+ QCString q(image.data());
+ q.stripPrefix("/*!");
+ q.resize(q.length()-2);
+ ::vhdl::parser::VhdlParser::handleCommentBlock(q.data(),TRUE);image.clear();
+ }
+ | <MULT_VHDL_2008_COMMENT : "/*" (~[])* "*/" > {::vhdl::parser::VhdlParser::lineCount(image.data());image.clear();}
+}
+
+/* KEYWORDS */
+
+TOKEN [IGNORE_CASE] :
+{
+ <ABS_T: "abs">
+| <ACCESS_T: "access">
+| <AFTER_T: "after">
+| <ALIAS_T: "alias">
+| <ALL_T: "all">
+| <AND_T: "and">
+| <ARCHITECTURE_T: "architecture"> {::vhdl::parser::VhdlParser::setLineParsed(ARCHITECTURE_T);}
+| <ARRAY_T: "array"> {VhdlParser::setLineParsed(ARRAY_T);}
+| <ASSERT_T: "assert">
+| <ASSUME_T: "assume">
+| <ASSUME_GUARANTEE_T: "assume_guarentee">
+| <ATTRIBUTE_T: "attribute"> {::vhdl::parser::VhdlParser::setLineParsed(ATTRIBUTE_T);}
+| <BEGIN_T: "begin">
+| <BLOCK_T: "block">
+| <BODY_T: "body"> {::vhdl::parser::VhdlParser::setLineParsed(BODY_T);}
+| <BUFFER_T: "buffer">
+| <BUS_T: "bus">
+| <COMPONENT_T: "component"> {VhdlParser::setLineParsed(COMPONENT_T);}
+| <CASE_T: "case">
+| <CONFIGURATION_T: "configuration"> {VhdlParser::setLineParsed(CONFIGURATION_T);}
+| <CONSTANT_T: "constant"> {VhdlParser::setLineParsed(CONSTANT_T);}
+| <CONTEXT_T: "context"> {VhdlParser::setLineParsed(CONTEXT_T);}
+| <COVER_T: "cover">
+| <DEFAULT_T: "default">
+| <DISCONNECT_T: "disconnect">
+| <DOWNTO_T: "downto">
+| <ELSE_T: "else">
+| <ELSIF_T: "elsif">
+| <END_T: "end"> {VhdlParser::setLineParsed(END_T);}
+| <ENTITY_T: "entity"> {VhdlParser::setLineParsed(ENTITY_T);}
+| <EXIT_T: "exit">
+| <FAIRNESS_T: "fairness">
+| <FILE_T: "file"> {VhdlParser::setLineParsed(FILE_T);}
+| <FOR_T: "for">
+| <FORCE_T: "force">
+| <FUNCTION_T: "function"> {VhdlParser::setLineParsed(FUNCTION_T);}
+| <GENERATE_T: "generate">
+| <GENERIC_T: "generic">
+| <GROUP_T: "group"> {VhdlParser::setLineParsed(GROUP_T);}
+| <GUARDED_T: "guarded">
+| <IF_T: "if">
+| <IMPURE_T: "impure">
+| <IN_T: "in">
+| <INERTIAL_T: "inertial">
+| <INOUT_T: "inout">
+| <IS_T: "is">
+| <LABEL_T: "label">
+| <LIBRARY_T: "library"> {VhdlParser::setLineParsed(LIBRARY_T);}
+| <LINKAGE_T: "linkage">
+| <LITERAL_T: "literal">
+| <LOOP_T: "loop">
+| <MAP_T: "map">
+| <MOD_T: "mod">
+| <NAND_T: "nand">
+| <NEW_T: "new">
+| <NEXT_T: "next">
+| <NOR_T: "nor">
+| <NOT_T: "not">
+| <NULL_T: "null">
+| <OF_T: "of">
+| <ON_T: "on">
+| <OPEN_T: "open">
+| <OR_T: "or">
+| <OTHER_T: "others">
+| <OUT_T: "out">
+| <PACKAGE_T: "package"> {::vhdl::parser::VhdlParser::setLineParsed(PACKAGE_T);}
+| <PARAMETER_T: "parameter">
+| <PORT_T: "port"> {::vhdl::parser::VhdlParser::setLineParsed(PORT_T);}
+| <POSTPONED_T: "postponed">
+| <PROCEDURE_T: "procedure"> {::vhdl::parser::VhdlParser::setLineParsed(PROCEDURE_T);}
+| <PROCESS_T: "process"> {::vhdl::parser::VhdlParser::setLineParsed(PROCESS_T);}
+| <PROPERTY_T: "property">
+| <PROTECTED_T: "protected">
+| <PURE_T: "pure">
+| <RANGE_T: "range">
+| <RECORD_T: "record"> {::vhdl::parser::VhdlParser::setLineParsed(RECORD_T);}
+| <REGISTER_T: "register">
+| <REJECT_T: "reject">
+| <RELEASE_T: "release">
+| <RESTRICT_T: "restrict">
+| <RESTRICT_GUARANTEE_T: "restrict_guarantee">
+| <REM_T: "rem">
+| <REPORT_T: "report">
+| <ROL_T: "rol">
+| <ROR_T: "ror">
+| <RETURN_T: "return">
+| <SELECT_T: "select">
+| <SEQUENCE_T: "sequence">
+| <SEVERITY_T: "severity">
+| <SIGNAL_T: "signal"> {::vhdl::parser::VhdlParser::setLineParsed(SIGNAL_T);}
+| <SHARED_T: "shared">
+| <SLA_T: "sla">
+| <SLL_T: "sll">
+| <SRA_T: "sra">
+| <SRL_T: "srl">
+| <STRONG_T: "strong">
+| <SUBTYPE_T: "subtype"> {::vhdl::parser::VhdlParser::setLineParsed(SUBTYPE_T);}
+| <THEN_T: "then">
+| <TO_T: "to">
+| <TRANSPORT_T: "transport">
+| <TYPE_T: "type"> {::vhdl::parser::VhdlParser::setLineParsed(TYPE_T);}
+| <UNAFFECTED_T: "unaffected">
+| <UNITS_T: "units"> {::vhdl::parser::VhdlParser::setLineParsed(UNITS_T);}
+| <UNTIL_T: "until">
+| <USE_T: "use">
+| <VARIABLE_T: "variable">
+| <VMODE_T: "vmode">
+| <VPROP_T: "vprop">
+| <VUNIT_T: "vunit">
+| <WAIT_T: "wait">
+| <WHEN_T: "when">
+| <WHILE_T: "while">
+| <WITH_T: "with">
+| <XOR_T: "xor">
+| <XNOR_T: "xnor">
+}
+
+/* OPERATORS */
+
+TOKEN :
+{
+ < AMPERSAND_T: "&" >
+| < APOSTROPHE_T: "'" >
+| < LPAREN_T: "(" >
+| < RPAREN_T: ")" >
+| < DOUBLEMULT_T: "**" >
+| < MULT_T: "*" >
+| < PLUS_T: "+" >
+| < MINUS_T: "-" >
+| < COMMA_T: "," >
+| < VARASSIGN_T: ":=" >
+| < COLON_T: ":" >
+| < SEMI_T: ";" >
+| < LESSTHAN_T: "<=" >
+| < GREATERTHAN_T: ">=" >
+| < LT_T: "<" >
+| < GT_T: ">" >
+| < EQU_T: "=" >
+| < NOTEQU_T: "/=" >
+| < ARROW_T: "=>" >
+| < BOX_T: "<>" >
+| < SLSL_T: "<<" >
+| < RSRS_T: ">>" >
+| < QQ_T: "??" >
+| < QGT_T: "?>=" >
+| < QLT_T: "?<=" >
+| < QG_T: "?>" >
+| < QL_T: "?<" >
+| < QEQU_T: "?=" >
+| < QNEQU_T: "?/=" >
+| < Q_T: "?" >
+| < BAR_T: "|" >
+| <DOT_T: "." >
+| < SLASH_T: "/" >
+| < AT_T: "@" >
+| < NEG_T: "^" >
+| < LBRACKET_T: "[" >
+| < RBRACKET_T: "]" >
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+
+}
+
+TOKEN:
+{
+ <INTEGER: <DIGIT> ((["_"])? (<DIGIT>))* >
+ | <STRINGLITERAL: (( ["\""](<GRAPHIC_CHARACTER>)*) "\"")+ >
+ | <BASIC_IDENTIFIER: (<LETTER> ( (["_"])* <LETTER_OR_DIGIT> )*) >
+ | <EXTENDED_CHARACTER: ( ["\\"](<GRAPHIC_CHARACTER>)*["\\"] ) >
+ | <CHARACTER_LITERAL: (["'"]<GRAPHIC_CHARACTER>["'"]) >
+ | <DECIMAL_LITERAL: (<INTEGER> (["."]<INTEGER>)? (<EXPONENT>)? ) >
+ | <BASED_INTEGER: <LETTER_OR_DIGIT>( <LETTER_OR_DIGIT>)* >
+ | <BASED_LITERAL: <INTEGER>["#"]<BASED_INTEGER>(["."] <BASED_INTEGER>)? ["#"] (<EXPONENT>)? >
+ | <#EXPONENT: (["e","E"] (["+","-"])? (<INTEGER>)+) >
+ | < #BASIC_GRAPHIC_CHARACTER: (<UPPER_CASE_LETTER>|<DIGIT>|<SPECIAL_CHARACTER>|<SPACE_CHARACTER>) >
+ | < #GRAPHIC_CHARACTER: ( <BASIC_GRAPHIC_CHARACTER>|<LOWER_CASE_LETTER>|<OTHER_SPECIAL_CHARACTER> ) >
+ | < #LETTER_OR_DIGIT: ( <LETTER> | <DIGIT> ) >
+ | < #LETTER: (<UPPER_CASE_LETTER>|<LOWER_CASE_LETTER>) >
+ | < #UPPER_CASE_LETTER: ["A"-"Z"] >
+ | <BIT_STRING_LITERAL : <BASE_SPECIFIER >["\""](<LETTER_OR_DIGIT>)* ["\""] >
+ | <#BASE_SPECIFIER:["B","O","X","b","o","x"]>
+ | < #DIGIT: ["0"-"9"] >
+ | < #SPECIAL_CHARACTER: ["#","&","'","(",")","*","+",",","-",".","/",":",";","<","=",">","_","|"] >
+ | < #OTHER_SPECIAL_CHARACTER: ["%","!","$","@","?","[","\\","]","^","`","{","}","~","\u00A0"-"\u00FF"]>
+ | < #SPACE_CHARACTER: [" ","\t"] >
+ | < #LOWER_CASE_LETTER: ["a"-"z"] >
+ | <VHDL2008TOOLDIR : ["`"](<GRAPHIC_CHARACTER>|<STRINGLITERAL>)+ >
+
+}
+
+QCString abstract_literal() :
+{Token *tok;}
+{
+ tok=<DECIMAL_LITERAL> { return tok->image.c_str(); }
+ | tok=<INTEGER> { return tok->image.c_str(); }
+ | tok=<BASED_LITERAL> { return tok->image.c_str(); }
+}
+
+QCString access_type_definition() :
+{Token *tok;QCString str,str1;}
+{
+tok=<ACCESS_T> str1=subtype_indication() {str=tok->image.c_str(); return str+str1;}
+}
+
+QCString actual_designator() :
+{QCString str;Token *t;}
+{
+t=<OPEN_T> { return t->image.c_str(); }
+|
+LOOKAHEAD(expression())
+ str=expression() { return str; }
+|
+ LOOKAHEAD(name())
+ str=name() { return str; }
+}
+
+QCString actual_parameter_part() :
+{QCString s;}
+{
+ s=association_list() { return s;}
+}
+
+QCString actual_part() :
+{QCString s,s1;}
+{
+ LOOKAHEAD(actual_designator())
+ s=actual_designator() { return s;}
+ |
+ <BOX_T> { return "<>";}
+ |
+ s=name() <LPAREN_T> s1=actual_designator() <RPAREN_T> {s+="(";s+=s1+")";return s;}
+
+ }
+
+QCString adding_operator () :
+{}
+{
+ <PLUS_T> { return "+";}
+ | <MINUS_T> { return "-";}
+ |<AMPERSAND_T> { return "&";}
+}
+
+QCString aggregate() : {QCString s,s1,s2;}
+{
+ <LPAREN_T> s=element_association() (<COMMA_T> s1=element_association(){s+=","+s1;})* <RPAREN_T> { return "("+s+")";}
+}
+
+QCString alias_declaration() : {QCString s,s1,s2;}
+{
+ <ALIAS_T> s2=alias_designator()
+ [ <COLON_T>{ s+=":"; } s1=subtype_indication() { s+=s1; }]
+ <IS_T> { s+=" is "; } s1=name() {s+=s1;} [s1=signature() {s+=s1;}]
+ <SEMI_T>
+{
+ addVhdlType(s2.data(),getLine(ALIAS_T),Entry::VARIABLE_SEC,VhdlDocGen::ALIAS,0,s.data(),Public);
+
+ return s2+" "+s+";";
+}
+ }
+
+QCString alias_designator() : {Token *tok=0;QCString s;}
+{
+ s=identifier() { return s;}
+ | tok=<CHARACTER_LITERAL> { return tok->image.c_str(); }
+ | s=operator_symbol() { return s; }
+}
+
+void allocator() :{}
+{
+ LOOKAHEAD(3)
+ <NEW_T> qualified_expression()
+ | <NEW_T> subtype_indication()
+}
+
+void architecture_body() : {QCString s,s1;}
+{
+
+ <ARCHITECTURE_T> s=identifier() <OF_T> s1=name() <IS_T>
+ {
+ QCString t=s1+"::"+s;
+ genLabels.resize(0);
+ pushLabel(genLabels,s1);
+ lastCompound=current;
+ addVhdlType(t,getLine(ARCHITECTURE_T),Entry::CLASS_SEC,VhdlDocGen::ARCHITECTURE,0,0,Private);
+ }
+ try{
+ architecture_declarative_part()
+ }catch(...){error_skipto(BEGIN_T);}
+ <BEGIN_T>
+ architecture_statement_part()
+ <END_T> [<ARCHITECTURE_T>] [name()] <SEMI_T>
+ { lastEntity=0;lastCompound=0; genLabels.resize(0); }
+}
+
+void architecture_declarative_part() : {}
+{
+ (block_declarative_item() )*
+ // | (<VHDL2008TOOLDIR>)
+}
+
+void architecture_statement_part() : {}
+{
+ (concurrent_statement())*
+ // | (<VHDL2008TOOLDIR>)
+}
+
+QCString array_type_definition (): { QCString s;}
+{
+
+ LOOKAHEAD(unconstraint_array_definition())
+
+ s=unconstraint_array_definition() {return s;}
+ | s=constraint_array_definition() {return s;}
+
+}
+
+QCString assertion() : {QCString s,s1,s2;Token *t=0;Token *t1=0;}
+{
+ <ASSERT_T> s=condition() [ t=<REPORT_T> s1=expression() ] [t1=<SEVERITY_T> s2=expression()]
+ {
+ s.prepend("assert ");
+ if(t) s1.prepend(" report ");
+ if(t1) s2.prepend(" report ");
+ return s+s1+s2;
+ }
+}
+
+QCString assertion_statement() : {QCString s,s1,s2;Token *t=0;}
+{
+ [ s=label() t=<COLON_T> ] s1=assertion() <SEMI_T>
+ {
+ if(t) s+=":";
+ return s+s1+";";
+ }
+}
+QCString association_element() : {QCString s,s1;}
+{
+ [LOOKAHEAD(formal_part() <ARROW_T>) s=formal_part() <ARROW_T> ] s1=actual_part()
+ { return s+" => "+s1;}
+}
+
+QCString association_list (): {QCString s,s1;}
+{
+s=association_element() (<COMMA_T> s1=association_element() { s+=","+s1; })* { return s; }
+}
+
+QCString attribute_declaration() : {QCString s,s1;}
+{
+ <ATTRIBUTE_T> s=identifier() <COLON_T> s1=type_mark() <SEMI_T>
+ {
+ addVhdlType(s.data(),getLine(ATTRIBUTE_T),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,s1.data(),Public);
+ return " attribute "+s+":"+s1+";";
+ }
+ }
+
+QCString attribute_designator (): {QCString s;Token *tok;}
+{
+ s=identifier() { return s;}
+ | tok=<RANGE_T> { return tok->image.c_str(); }
+}
+
+QCString attribute_name (): {QCString s,s1;}
+{
+ s=identifier() <APOSTROPHE_T> s1=name(){ s+="'"+s1; }[LOOKAHEAD(1)<LPAREN_T>s1=expression() <RPAREN_T> {s+"("+s1+")";}] { return s; }
+}
+
+
+QCString attribute_specification(): {QCString s,s1,s2;}
+{
+ <ATTRIBUTE_T> s=attribute_designator() <OF_T> s1=entity_specification() <IS_T> s2=expression() <SEMI_T>
+ {
+ QCString t= s1+" is "+s2;
+ addVhdlType(s.data(),getLine(ATTRIBUTE_T),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,t.data(),Public);
+ return " attribute "+s+" of "+s1+ " is "+s2+";";
+ }
+}
+
+QCString base() : {Token *tok;}
+{
+ tok=<INTEGER> { return tok->image.c_str();}
+}
+
+QCString base_specifier (): {Token *tok;}
+{
+ tok=<BASIC_IDENTIFIER> { return tok->image.c_str();}
+}
+
+QCString base_unit_declaration() :
+{QCString s;}
+{
+ s=identifier() { return s; }
+}
+
+QCString based_integer() : {Token *tok;}
+{
+ tok=<BASIC_IDENTIFIER> { return tok->image.c_str();}
+}
+
+QCString based_literal(): {Token *tok;}
+{
+ tok=<BASED_LITERAL> { return tok->image.c_str();}
+}
+
+QCString basic_identifier() : {Token *tok;}
+{
+ tok=<BASIC_IDENTIFIER> { return tok->image.c_str();}
+}
+
+void binding_indication() : {}
+{
+ [ <USE_T> entity_aspect() ]
+ [ generic_map_aspect() ]
+ [ port_map_aspect() ]
+}
+
+QCString bit_string_literal (): {Token *tok;}
+{
+ tok=<BIT_STRING_LITERAL> { return tok->image.c_str();}
+}
+
+
+QCString bit_value() : {Token *tok;}
+{
+ tok=<BASIC_IDENTIFIER> { return tok->image.c_str();}
+}
+
+void block_configuration() : {}
+{
+ <FOR_T> block_specification()
+ ( use_clause() )*
+ ( configuration_item())*
+ <END_T> <FOR_T> <SEMI_T>
+}
+
+void block_declarative_item (): {}
+{
+ subprogram_declaration()
+//| subprogram_body()
+| type_declaration()
+| subtype_declaration()
+| constant_declaration()
+| signal_declaration()
+| variable_declaration()
+| file_declaration()
+| alias_declaration()
+| component_declaration()
+|
+LOOKAHEAD(attribute_declaration())
+attribute_declaration()
+| attribute_specification()
+| configuration_specification()
+| disconnection_specification ()
+| use_clause()
+|
+LOOKAHEAD(3)
+group_template_declaration()
+| group_declaration()
+| <VHDL2008TOOLDIR>
+}
+
+void block_declarative_part() : {}
+{
+ (block_declarative_item() )*
+}
+
+void block_header() : {}
+{
+[LOOKAHEAD(generic_clause()) generic_clause()[ generic_map_aspect() <SEMI_T> ] ]
+[ port_clause() [ port_map_aspect() <SEMI_T> ] ]
+}
+
+void block_specification() : {}
+{
+ name()[LOOKAHEAD(1) <LPAREN_T> index_specification() <RPAREN_T>]
+}
+
+void block_statement() : {QCString s;}
+{
+ s=identifier() <COLON_T>
+ <BLOCK_T> { pushLabel(genLabels,s); }[ <LPAREN_T> expression() <RPAREN_T> ] [ <IS_T> ]
+ block_header()
+ block_declarative_part()
+ <BEGIN_T>
+ block_statement_part()
+ <END_T> <BLOCK_T> [ identifier() ] <SEMI_T>
+ {
+ genLabels=popLabel(genLabels);
+ }
+}
+
+void block_statement_part() : {}
+{
+ ( concurrent_statement() )*
+}
+
+void case_statement() : {QCString s;}
+{
+[ identifier() <COLON_T> ]
+ <CASE_T> s=expression()
+ {
+ QCString ca="case "+s;
+ FlowChart::addFlowChart(FlowChart::CASE_NO,0,ca);
+ }
+ <IS_T>
+ case_statement_alternative()
+ ( case_statement_alternative ())*
+ <END_T> <CASE_T> [ identifier() ] <SEMI_T>
+ {
+ FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::END_CASE,"end case",0);
+ }
+}
+
+void case_statement_alternative() : {QCString s;}
+{
+ <WHEN_T> s=choices() <ARROW_T>
+ {
+ QCString t="when ";
+ t+=s+"=> ";
+ FlowChart::addFlowChart(FlowChart::WHEN_NO,s.data(),t);
+ }
+ sequence_of_statement(){FlowChart::moveToPrevLevel(); }
+}
+
+QCString character_literal() : {Token *tok;}
+{
+ tok=<CHARACTER_LITERAL>{ return tok->image.c_str();}
+}
+
+QCString choice() : {QCString s;}
+{
+ LOOKAHEAD(simple_expression())
+ s=simple_expression(){ return s; }
+ |
+ LOOKAHEAD(discrete_range())
+ s=discrete_range(){ return s; }
+ |
+ LOOKAHEAD(identifier())
+ s=identifier(){ return s; }
+ | <OTHER_T> { return " others "; }
+}
+
+QCString choices() : {QCString s,s1;}
+{
+ s=choice() (<BAR_T> s1=choice(){s+="|";s+=s1;})* { return s; }
+}
+
+void component_configuration () :{}
+{
+ <FOR_T> component_specification()
+ [ binding_indication() <SEMI_T> ]
+ [ block_configuration() ]
+ <END_T> <FOR_T> <SEMI_T>
+}
+void component_declaration() : {QCString s;}
+{
+ <COMPONENT_T> s=identifier() [ <IS_T> ]
+ { currP=VhdlDocGen::COMPONENT; }
+ [ generic_clause() ]
+ [ port_clause() ]
+ {
+ addVhdlType(s.data(),getLine(COMPONENT_T),Entry::VARIABLE_SEC,VhdlDocGen::COMPONENT,0,0,Public);
+ currP=0;
+ }
+ <END_T> <COMPONENT_T> [ identifier() ] <SEMI_T>
+
+}
+
+void component_instantiation_statement() : {QCString s,s1;}
+{
+
+s=identifier() <COLON_T>
+ s1=instantiation_unit()
+ {
+ addCompInst(s.lower().data(),s1.lower().data(),0,getLine());
+ }
+ [ LOOKAHEAD(generic_map_aspect()) generic_map_aspect() ]
+ [ port_map_aspect() ] <SEMI_T>
+}
+
+void component_specification() : {}
+{
+instantiation_list() <COLON_T> name()
+}
+
+QCString composite_type_definition() : { QCString s,s1;}
+{
+ s=array_type_definition(){ return s; }
+| record_type_definition(){ return s; }
+}
+
+void concurrent_assertion_statement() : {}
+{
+[ LOOKAHEAD(2) identifier() <COLON_T> ] [ <POSTPONED_T> ] assertion() <SEMI_T>
+}
+
+void concurrent_procedure_call_statement() : {}
+{
+[ LOOKAHEAD(2) identifier() <COLON_T> ] [ <POSTPONED_T> ] procedure_call() <SEMI_T>
+}
+
+void concurrent_signal_assignment_statement() : {}
+{
+[ LOOKAHEAD(2) identifier() <COLON_T> ] [<POSTPONED_T> ]
+(
+LOOKAHEAD(conditional_signal_assignment() )
+ conditional_signal_assignment()
+| selected_signal_assignment()
+
+)
+}
+
+void concurrent_statement() : {}
+{
+
+// try {
+LOOKAHEAD([identifier() ":"] <BLOCK_T>)
+block_statement()
+|
+LOOKAHEAD([identifier() ":"] [<POSTPONED_T>] <PROCESS_T>)
+process_statement()
+|
+LOOKAHEAD(generate_statement())
+generate_statement()
+|
+case_scheme()
+|
+LOOKAHEAD([identifier() ":"] [<POSTPONED_T>] <ASSERT_T>)
+concurrent_assertion_statement()
+|
+LOOKAHEAD(concurrent_signal_assignment_statement())
+ concurrent_signal_assignment_statement()
+|
+LOOKAHEAD(component_instantiation_statement() )
+component_instantiation_statement()
+|
+LOOKAHEAD(concurrent_procedure_call_statement())
+concurrent_procedure_call_statement()
+| <VHDL2008TOOLDIR>
+ /*
+ catch( ParseException e )
+ {
+ error_skipto(SEMI_T, "syntax error in declarative item");
+ }
+ */
+}
+
+QCString condition() : {QCString s;}
+{
+ s=expression() { return s; }
+}
+
+QCString condition_clause() : {QCString s;}
+{
+ <UNTIL_T> s=condition()
+ {
+ return " until "+s;
+ }
+}
+
+void conditional_signal_assignment() : {}
+{
+ // LOOKAHEAD( target() "<=" options_() conditional_waveforms() ";")
+ target() <LESSTHAN_T> options() conditional_waveforms() <SEMI_T>
+}
+
+void conditional_waveforms() : {}
+{
+waveform()
+ ( LOOKAHEAD(<WHEN_T> condition() <ELSE_T>)
+ <WHEN_T> condition() <ELSE_T> waveform() )*
+ [ <WHEN_T> condition() ]
+}
+
+// ( waveform() < WHEN_T> condition() <ELSE_T> )*
+// waveform() [ <WHEN_T> condition() ]
+
+//waveform()
+ // ( LOOKAHEAD( <WHEN> condition() <ELSE>)
+ // <WHEN> condition() <ELSE> waveform() )*
+ //[ <WHEN> condition() ]
+
+void configuration_declaration() : {QCString s,s1;}
+{
+ <CONFIGURATION_T> s=identifier() <OF_T> s1=name() <IS_T>
+ {
+
+ confName=s+"::"+s1;
+ addVhdlType(s.data(),getLine(CONFIGURATION_T),Entry::VARIABLE_SEC,VhdlDocGen::CONFIG,"configuration",s1.data(),Public);
+ }
+ configuration_declarative_part()
+ block_configuration()
+ <END_T> [ <CONFIGURATION_T> ] [ name() ] <SEMI_T>
+ { genLabels.resize(0); confName="";}
+}
+
+void configuration_declarative_item() : {}
+{
+ use_clause()
+| attribute_specification()
+| group_declaration()
+}
+
+void configuration_declarative_part() : {}
+{
+ (configuration_declarative_item())*
+}
+
+void configuration_item (): {}
+{
+ LOOKAHEAD(component_configuration())
+ component_configuration()
+ | block_configuration()
+
+}
+
+void configuration_specification() : {}
+{
+<FOR_T> component_specification() binding_indication() <SEMI_T>
+}
+
+QCString constant_declaration() : {QCString s,s1,s2;Token *t=0;}
+{
+ <CONSTANT_T> s=identifier_list() <COLON_T> s1= subtype_indication() [ t=<VARASSIGN_T> s2=expression() ] <SEMI_T>
+ {
+ if(t)
+ s2.prepend(":=");
+ QCString it=s1+s2;
+ addVhdlType(s.data(),getLine(CONSTANT_T),Entry::VARIABLE_SEC,VhdlDocGen::CONSTANT,0,it.data(),Public);
+ it.prepend("constant ");
+ return it;
+ }
+}
+
+QCString constraint_array_definition (): {QCString s,s1;}
+{
+<ARRAY_T> s=index_constraint() <OF_T> s1=subtype_indication(){ return s+" "+s1;}
+}
+
+void context_clause (): {}
+{
+ (context_item())*
+}
+
+QCString constraint () :{QCString s;}
+ {
+ LOOKAHEAD(range_constraint())
+ s=range_constraint(){ return s;}
+ |
+ LOOKAHEAD(index_constraint())
+ s=index_constraint(){ return s;}
+}
+
+void context_item() : {}
+{
+ library_clause()
+| use_clause()
+}
+
+QCString decimal_literal() : {Token *tok;}
+{
+ tok=<DECIMAL_LITERAL> { return tok->image.c_str(); }
+}
+
+
+QCString delay_mechanism (): {QCString s;}
+{
+<TRANSPORT_T> { return " transport ";}
+| [ <REJECT_T> s=expression() {s.prepend(" reject ");}] <INERTIAL_T> { return s+" inertial "; }
+}
+
+void design_file() : {}
+{
+ (design_unit() )+ {}
+ | <EOF>
+}
+
+void design_unit() : {}
+{
+ context_clause()library_unit()
+
+}
+
+QCString designator() : {QCString s;}
+{
+ s=identifier() {return s;}
+ | s=operator_symbol(){return s;}
+}
+
+QCString direction (): {Token *tok;}
+{
+tok=<TO_T> { return tok->image.c_str();}
+| tok=<DOWNTO_T> { return tok->image.c_str();}
+}
+
+void disconnection_specification() : {}
+{
+<DISCONNECT_T> guarded_signal_specificatio() <AFTER_T> expression() <SEMI_T>
+}
+
+void guarded_signal_specificatio() : {}
+{
+ signal_list() <COLON_T> name()
+}
+
+QCString discrete_range() : {QCString s;}
+{
+ LOOKAHEAD(range())
+ s=range() { return s;}
+ |
+ LOOKAHEAD(subtype_indication())
+ s=subtype_indication() { return s;}
+}
+
+QCString element_association() : {QCString s,s1;}
+{
+[LOOKAHEAD(choices() <ARROW_T>) s=choices() <ARROW_T> ] s1=expression()
+ {
+if(!s.isEmpty())
+ return s+"=>"+s1;
+return s1;
+ }
+}
+
+QCString element_declaration() : {QCString s,s1;}
+{
+s=identifier_list() <COLON_T> s1=subtype_indication() <SEMI_T> {return s+":"+s1;}
+}
+
+
+QCString entity_aspect() : {Token *tok;QCString s,s1;}
+{
+tok=<ENTITY_T> s=name() [ LOOKAHEAD(1)<LPAREN_T> s1=identifier() <RPAREN_T> {s+="("+s1+")";} ] { return s;}
+| tok=<CONFIGURATION_T> s=name() { return tok->image.c_str()+s;}
+| tok=<OPEN_T> { return tok->image.c_str(); }
+}
+
+QCString entity_class() : {}
+{
+<ENTITY_T> { return "entity";}
+| <ARCHITECTURE_T> {return "architecture";}
+| <CONFIGURATION_T> {return "configuration";}
+| <PROCEDURE_T> {return "procedure";}
+| <FUNCTION_T> {return "function";}
+| <PACKAGE_T> {return "package";}
+| <TYPE_T> {return "type";}
+| <SUBTYPE_T> {return "subtype";}
+| <CONSTANT_T> {return "constant";}
+| <SIGNAL_T> {return "signal";}
+| <VARIABLE_T> {return "variable";}
+| <COMPONENT_T> {return "component";}
+| <LABEL_T> {return "label";}
+| <LITERAL_T> {return "literal";}
+| <UNITS_T> {return "units";}
+| <GROUP_T> {return "group";}
+| <FILE_T> {return "file";}
+}
+
+QCString entity_class_entry() : {QCString s;}
+{
+ s=entity_class() [ <BOX_T> {s+="<>";} ] { return s;}
+}
+
+QCString entity_class_entry_list() : {QCString s,s1,s2;}
+{
+ ( s1=entity_class_entry() {s+=s1;} )(<COMMA_T> s=entity_class_entry(){s2+=",";s2+=s;} )* { return s1+s2;}
+}
+
+void entity_declaration() : {QCString s;}
+{
+ // try{
+ <ENTITY_T> s=identifier() <IS_T>
+ {
+ lastEntity=current;
+ lastCompound=0;
+ addVhdlType(s.data(),getLine(ENTITY_T),Entry::CLASS_SEC,VhdlDocGen::ENTITY,0,0,Public);
+ }
+ entity_header()
+ entity_declarative_part ()
+ [ <BEGIN_T> entity_statement_part() ]
+ <END_T> [ <ENTITY_T> ] [ name() ]
+ // }catch(...){error_skipto(SEMI_T);}
+ <SEMI_T>
+ { lastEntity=0;lastCompound=0; genLabels.resize(0); }
+}
+
+void entity_declarative_item() : {}
+{
+subprogram_declaration()
+//| subprogram_body()
+| type_declaration()
+| subtype_declaration()
+| constant_declaration()
+| signal_declaration()
+| variable_declaration()
+| file_declaration()
+| alias_declaration()
+|
+LOOKAHEAD(attribute_declaration())
+attribute_declaration()
+| attribute_specification()
+| disconnection_specification()
+| use_clause()
+|
+LOOKAHEAD(3)
+group_template_declaration()
+| group_declaration()
+|
+LOOKAHEAD(5)
+ package_instantiation_declaration()
+|package_declaration()
+| <VHDL2008TOOLDIR>
+}
+
+void entity_declarative_part() : {}
+{
+ (entity_declarative_item() )*
+}
+
+QCString entity_designator() : {QCString s,s1;}
+{
+s=entity_tag() [ s1=signature() ] { return s+s1;}
+}
+
+void entity_header() : {}
+{
+ [ { currP=VhdlDocGen::GENERIC;parse_sec=GEN_SEC; } generic_clause()]
+ [ { currP=VhdlDocGen::PORT; } port_clause()]
+}
+
+QCString entity_name_list() : {QCString s,s1;}
+{
+(s1=entity_designator() {s+=s1;})+ { return s;}
+| <OTHER_T> { return "other";}
+| <ALL_T> {return "all";}
+}
+
+QCString entity_specification() : {QCString s,s1;}
+{
+s=entity_name_list() <COLON_T> s1=entity_class(){ return s+":"+s1;}
+}
+
+void entity_statement() : {}
+{
+LOOKAHEAD(concurrent_assertion_statement())
+concurrent_assertion_statement()
+|
+LOOKAHEAD(process_statement())
+ process_statement()
+| concurrent_procedure_call_statement()
+
+}
+
+void entity_statement_part() : {}
+{
+ (entity_statement())*
+}
+
+
+QCString entity_tag (): {QCString s;}
+{
+s=name() { return s;}
+| s=character_literal() { return s;}
+}
+
+QCString enumeration_literal() : {QCString s;}
+{
+ s=identifier() { return s;}
+ | s=character_literal() { return s;}
+}
+
+QCString enumeration_type_definition() : {QCString s,s1;}
+{
+ <LPAREN_T>s=enumeration_literal() (LOOKAHEAD(1)<COMMA_T> s1=enumeration_literal() {s+=",";s+=s1;} )* <RPAREN_T>
+ { return "("+s+")";}
+}
+
+QCString exit_statement() : {QCString s,s1,s2;Token *t=0;Token *t1=0;}
+{
+[ s=identifier() t=<COLON_T> ] <EXIT_T> [ s1=identifier() ]
+[ t1=<WHEN_T> s2=condition() ] <SEMI_T>
+{
+ lab.resize(0);
+ if(t) s+=":";
+ if(t1) s2.prepend(" when ");
+ FlowChart::addFlowChart(FlowChart::EXIT_NO,"exit",s2.data(),s1.data());
+
+ return s+s1+s2+";";
+}
+}
+
+QCString expression (): {QCString s,s1,s2;}
+{
+s=relation() ( s1=logop() s2=relation() {s+=s1;s+=s2;} )*
+{ return s; }
+}
+
+QCString logop() : {}
+{
+ <AND_T> { return "and" ;}
+ |<NAND_T> { return "nand" ;}
+ |<NOR_T> { return "nor" ;}
+ |<XNOR_T> { return "xnor" ;}
+ |<XOR_T> { return "xor" ;}
+ |<OR_T> { return "or" ;}
+ }
+
+QCString extended_identifier (): {Token *t;}
+{
+ t=<EXTENDED_CHARACTER> { return t->image.c_str(); }
+}
+
+QCString factor(): {QCString s,s1;}
+{
+s=primary() [LOOKAHEAD(1) <DOUBLEMULT_T> s1=primary(){ s+="**";s+=s1;} ] { return s;}
+| <ABS_T> s=primary(){ s1 = "abs "; return s1+s; }
+| <NOT_T> s=primary(){s1="not ";return s1+s;}
+}
+
+QCString file_declaration() : {QCString s,s1,s2,s3;}
+{
+ <FILE_T> s=identifier_list() <COLON_T> s2=subtype_indication() [ s3=file_open_information() ] <SEMI_T>
+ {
+ QCString t1=s2+" "+s3;
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,t1.data(),Public);
+ return " file "+s+":"+s2+" "+s3+";";
+ }
+ }
+
+QCString file_logical_name(): {QCString s;}
+{
+ s=expression() { return s; }
+}
+
+QCString file_open_information() : {QCString s,s1,s2;}
+{
+ [ <OPEN_T> s=expression() ] <IS_T> s1=file_logical_name() {s2="open "+s+" is "+s1; return s2; }
+}
+
+QCString file_type_definition() : {QCString s,s1;}
+{
+ <FILE_T> <OF_T> s=type_mark() { s1=" file of "+s; return s1;}
+}
+
+QCString floating_type_definition() : {QCString s;}
+{
+ s=range_constraint(){ return s;}
+}
+
+QCString formal_designator() : {QCString s;Token *tok;}
+{
+ s=name() { return s; }
+ |tok=<INTEGER> { return tok->image.c_str();}
+}
+
+
+QCString formal_parameter_list() : {QCString s;}
+{
+ s=interface_list(){ return s; }
+}
+
+QCString formal_part() : {QCString s,s1;}
+{
+s=name() [<LPAREN_T> formal_designator() <RPAREN_T> {s+"("+s1+")";}] {return s;}
+}
+
+QCString full_type_declaration() : {QCString s,s1,s2;}
+{
+<TYPE_T> s=identifier() <IS_T>
+ try{
+ s2=type_definition()
+ }catch(...){error_skipto(SEMI_T);}
+ <SEMI_T>
+ {
+ addVhdlType(s.data(),getLine(TYPE_T),Entry::VARIABLE_SEC,VhdlDocGen::TYPE,0,s2.data(),Public);
+ return "type "+s+" is "+s2+";";
+ }
+}
+
+QCString function_call() : {QCString s,s1;}
+{
+s=name() <LPAREN_T> s1=actual_parameter_part() <RPAREN_T> { return s+"("+s1+")";}
+}
+
+void generate_statement() : {QCString s;}
+{
+s=identifier() <COLON_T>
+ try{
+ generate_scheme() <GENERATE_T>
+ { pushLabel(genLabels,s); }
+ generate_statement_body1()
+ <END_T>
+ }catch(...){error_skipto(GENERATE_T);}
+ <GENERATE_T> [ identifier() ] <SEMI_T> {genLabels=popLabel(genLabels); }
+}
+
+void generate_scheme() : {}
+{
+<FOR_T> parameter_specification()
+| <IF_T> condition()
+}
+
+void generic_clause() : {QCString s;}
+{
+ <GENERIC_T> <LPAREN_T> { parse_sec=GEN_SEC; } s=generic_list() <RPAREN_T> <SEMI_T> { parse_sec=0; }
+}
+
+QCString generic_list() : {QCString s;}
+{
+ s=interface_list() { return s; }
+}
+
+void generic_map_aspect() : {}
+{
+ <GENERIC_T> <MAP_T> <LPAREN_T> association_list() <RPAREN_T>
+}
+
+QCString group_constituent() : {QCString s;}
+{
+ s=name() { return s; }
+ | s=character_literal() { return s;}
+}
+
+QCString group_constituent_list() : {QCString s,s1,s2;}
+{
+ (s1=group_constituent())(<COMMA_T> s=group_constituent(){s2+=",";s2+=s1;})* { return s+s2;}
+}
+
+QCString group_declaration() : {QCString s,s1,s2;}
+{
+ <GROUP_T> s=identifier() <COLON_T> s1=identifier() <LPAREN_T> s2=group_constituent_list() <RPAREN_T> <SEMI_T>
+ {
+ return "group "+s+":"+s1+"("+s2+");";
+ }
+}
+
+QCString group_template_declaration() : {QCString s,s1;}
+{
+ <GROUP_T> s=identifier() <IS_T> <LPAREN_T> s1=entity_class_entry_list() <RPAREN_T> <SEMI_T>
+ {
+ return "group "+s+ "is ("+s1+");";
+ }
+ }
+
+void guarded_signal_specification() : {}
+{
+ signal_list() <COLON_T> type_mark()
+}
+
+QCString identifier() : {Token *tok;}
+{
+ tok=<EXTENDED_CHARACTER>{ return tok->image.c_str(); }
+ |tok=<BASIC_IDENTIFIER> { return tok->image.c_str(); }
+}
+
+QCString identifier_list() : {QCString str,str1;}
+{
+ str=identifier() (<COMMA_T> str1=identifier() {str+=",";str+=str1;})* { return str; }
+}
+
+void if_statement() : {QCString s,s1;}
+{
+[LOOKAHEAD(1) identifier() <COLON_T> ]
+ <IF_T> s=condition() <THEN_T>
+ {
+ s.prepend("if ");
+ FlowChart::addFlowChart(FlowChart::IF_NO,0,s);
+ }
+ sequence_of_statement()
+ (
+ <ELSIF_T> s1=condition() <THEN_T>
+ {
+ s1.prepend("elsif ");
+ FlowChart::addFlowChart(FlowChart::ELSIF_NO,0,s1.data());
+ }
+ sequence_of_statement()
+ )*
+ [LOOKAHEAD(1) <ELSE_T>
+ {
+ FlowChart::addFlowChart(FlowChart::ELSE_NO,0,0);
+ }
+ sequence_of_statement() ] <END_T> <IF_T> [ identifier() ] <SEMI_T>
+ {
+ FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::ENDIF_NO,0,0);
+ }
+}
+
+QCString incomplete_type_declaration() : {QCString s;}
+{
+ <TYPE_T> s=identifier() <SEMI_T>
+ {
+ return "type "+s+";";
+ }
+}
+
+QCString index_constraint() : {QCString s="("; QCString s1,s2;}
+{
+ //try{
+ <LPAREN_T> s2=discrete_range(){s+=s2;}(LOOKAHEAD(1)<COMMA_T> s1=discrete_range(){s+=",";s+=s1;})* <RPAREN_T> {return s+")";}
+//}catch(...){ error_skipto(SEMI_T);hasError=false;return "";}
+ }
+
+QCString index_specification() : {QCString s;}
+{
+ LOOKAHEAD( discrete_range())
+ s=discrete_range() { return s;}
+| s=expression(){ return s;}
+}
+
+QCString index_subtype_definition() : {QCString s;}
+{
+ s=type_mark() <RANGE_T> <BOX_T> { return s+" range <> ";}
+}
+
+QCString instantiation_unit() : {QCString s,s1,s2;Token *tok;}
+{
+[ tok=<COMPONENT_T> ] s=identifier() {s1="component"; return s; }
+| tok=<ENTITY_T> s2=name() {s=tok->image.c_str()+s2;} [ <LPAREN_T> s1=identifier() <RPAREN_T> {s+="(";s+=s1;s+=")" ;}] { return s;}
+| <CONFIGURATION_T> s=name() {s1="configuration ";return s;}
+}
+
+QCString instantiation_list() : {QCString s;Token *tok;}
+{
+ s=identifier_list() { return s;}
+| tok=<OTHER_T> {return tok->image.c_str();}
+| tok=<ALL_T> {return tok->image.c_str();}
+}
+
+QCString integer() : {Token *t;}
+{
+ t=<INTEGER> {return t->image.c_str();}
+}
+
+QCString integer_type_definition() : {QCString s;}
+{
+ s=range_constraint(){ return s;}
+}
+
+QCString interface_declaration() : {QCString s,s1;}
+{
+
+LOOKAHEAD(5)
+ s=interface_subprogram_declaration() { return s;}
+
+|interface_package_declaration() { return s;}
+|
+ LOOKAHEAD(5)
+ s=interface_variable_declaration() { return s;}
+|
+LOOKAHEAD(5)
+interface_file_declaration() { return s;}
+|
+LOOKAHEAD(subprogram_declaration())
+subprogram_declaration() { return s;}
+|
+ s=object_class() s1=identifier()
+ {
+ if (parse_sec==GEN_SEC)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,s1.data(),0,Public);
+ return s;
+ }
+}
+
+QCString interface_element() : {QCString s;}
+{
+s=interface_declaration(){ return s;}
+}
+
+QCString interface_file_declaration() : {QCString s,s1;}
+{
+<FILE_T> s=identifier_list() <COLON_T> s1=subtype_indication()
+{
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,s1.data(),Public);
+ return " file "+s+":"+s1;
+}
+}
+
+QCString interface_list() : {QCString s,s1,s2;}
+{
+s=interface_element() (LOOKAHEAD(1) <SEMI_T> s1=interface_element(){s2+=";";s2+=s1;})* { return s+s2;}
+}
+
+
+
+QCString interface_variable_declaration() : {Token *tok=0;Token *tok1=0;Token *tok2=0;QCString s,s1,s2,s3,s4,s5;}
+{
+[( tok=<VARIABLE_T> | tok=<SIGNAL_T> | tok=<CONSTANT_T>|tok=<SHARED_T>) ]
+ s=identifier_list() <COLON_T> [ s1=mode() ]
+ s2=subtype_indication() [ tok1=<BUS_T> ] [ tok2=<VARASSIGN_T> s4=expression() ]
+{
+ if(tok)
+ s5=tok->image.c_str();
+
+ if(tok1)
+ s3=tok->image.data();
+
+ if(tok2)
+ s3+=":=";
+
+ QCString it=s+":"+s1+" "+s2+" "+s3+" "+s4;
+ if (currP!=VhdlDocGen::COMPONENT)
+ {
+ if (currP==VhdlDocGen::FUNCTION || currP==VhdlDocGen::PROCEDURE)
+ {
+ addProto(s5.data(),s.data(),s1.data(),s2.data(),s3.data(),s4.data());
+ }
+ else
+ {
+ QCString i=s2+s3+s4;
+ if (currP==VhdlDocGen::GENERIC && param_sec==0)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,i.data(),s1.data(),Public);
+ else if(parse_sec != GEN_SEC)
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,currP,i.data(),s1.data(),Public);
+ }
+ // fprintf(stderr,"\n\n <<port %s >>\n",$$.data());
+ } // if component
+ return it;
+ }
+}
+
+QCString iteration_scheme() : {QCString s;}
+{
+<WHILE_T> s=condition()
+{
+ s.prepend("while ");
+ FlowChart::addFlowChart(FlowChart::WHILE_NO,0,s.data(),lab.data());
+ lab="";
+ return s;
+}
+| <FOR_T> s=parameter_specification()
+{
+ QCString q=lab+" for "+s;
+ FlowChart::addFlowChart(FlowChart::FOR_NO,0,q.data(),lab.data());
+ lab="";
+ return q;
+}
+}
+
+QCString label() : {QCString s;}
+{
+ s=identifier() { return s;}
+}
+
+QCString library_clause() : {QCString s;}
+{
+ (<LIBRARY_T> s=identifier_list() <SEMI_T>
+ )
+ {
+ if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
+ {
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,s.data(),"_library_",Public);
+ }
+ QCString s1="library "+s;
+ return s1;
+ }
+}
+
+QCString library_unit() : {QCString s;}
+{
+LOOKAHEAD(2)
+primary_unit() { return s; }
+| secondary_unit() { return s; }
+| context_declaration()
+
+}
+
+QCString literal() : {QCString s;}
+{
+
+ LOOKAHEAD(bit_string_literal())
+s=bit_string_literal() { return s;}
+|
+ LOOKAHEAD(numeric_literal())
+ s=numeric_literal() { return s;}
+|
+
+LOOKAHEAD(enumeration_literal())
+s=enumeration_literal() { return s;}
+| s=string_literal() { return s;}
+| <NULL_T> {return "null";}
+}
+
+QCString logical_operator() : {QCString s;}
+{
+ s=logop() { return s;}
+}
+
+QCString loop_statement() : {QCString s,s1,s2,s3;}
+{
+[ s=identifier() <COLON_T> {s+=":";} ]
+ [ s1=iteration_scheme() ]
+ {
+ if(s1.isEmpty())
+ FlowChart::addFlowChart(FlowChart::LOOP_NO,0,"infinite");
+ }
+ <LOOP_T>
+ s2=sequence_of_statement()
+ <END_T> <LOOP_T> [ s3=identifier() ] <SEMI_T>
+ {
+ QCString q = s+" loop "+s2+" end loop" +s3;
+ QCString endLoop="end loop" + s3;
+ FlowChart::moveToPrevLevel();
+ FlowChart::addFlowChart(FlowChart::END_LOOP,endLoop.data(),0);
+ return q;
+ }
+
+}
+
+
+QCString miscellaneous_operator():{Token *t=0;}
+{
+ <DOUBLEMULT_T> {return "**";}
+ | <ABS_T> {return "abs";}
+ | <NOT_T> {return "not";}
+}
+
+QCString mode() : {Token *tok;}
+{
+tok=<IN_T> { return "in"; }
+| tok=<OUT_T> { return "out"; }
+| tok=<INOUT_T> { return "inout"; }
+| tok=<BUFFER_T> { return "buffer"; }
+| tok=<LINKAGE_T> { return "linkage"; }
+}
+
+QCString multiplying_operation() : {Token *tok;}
+{
+tok=<MULT_T> { return tok->image.c_str(); }
+| tok=<SLASH_T> { return tok->image.c_str(); }
+| tok=<MOD_T> { return tok->image.c_str(); }
+| tok=<REM_T> { return tok->image.c_str(); }
+}
+
+
+ QCString name() : {QCString s,s1;}
+{
+ (
+ s=operator_symbol()
+ | s=identifier()| s=external_name()
+ )
+ [LOOKAHEAD(name_ext1()) s1=name_ext1(){ s+=s1;}] { return s; }
+}
+
+QCString name_ext1() : {QCString s,s1,s2;}
+ {
+ s=name_ext() (LOOKAHEAD(name_ext()) s1=name_ext(){s+=s1;})* { return s;}
+ }
+
+ QCString name_ext() : {QCString s,s1,s2;}
+ {
+
+ (
+ LOOKAHEAD(<DOT_T> suffix())
+ <DOT_T> s1=suffix(){s+=".";s+=s1;}
+|
+ LOOKAHEAD(test_att_name())
+ s1=test_att_name() { s+=s1;}
+ |
+ LOOKAHEAD( <LPAREN_T> discrete_range() <RPAREN_T>)
+ <LPAREN_T> s1=discrete_range() <RPAREN_T> {s+="(";s+=s1;s+=")";}
+ |
+ LOOKAHEAD( "(" expression() ("," expression() )* ")" )
+ <LPAREN_T> s1=expression() {s+="(";s+=s1;} (LOOKAHEAD(1) <COMMA_T> s1=expression(){s+=",";s+=s1;})* <RPAREN_T> { s+=")";}
+
+ )
+ {return s;}
+ }
+
+ QCString test_att_name() : {QCString s,s1;}
+ {
+ [ LOOKAHEAD(<LBRACKET_T>) s1=signature() {s=s1;}]
+ <APOSTROPHE_T> s1=attribute_designator() {s+="'";s+=s1;}
+ [LOOKAHEAD(1) <LPAREN_T> s1=expression() <RPAREN_T> {s+="(";s+=s1;s+=")";}]
+ { return s;}
+ }
+
+ QCString indexed_name() : {QCString s,s1,s2;}
+ {
+ s2=identifier() <LPAREN_T> s1=expression(){s=s2+"("+s1;} (<COMMA_T> s1=expression(){s+=",";s+=s1;})* <RPAREN_T> {return s+")";}
+ }
+
+QCString next_statement() : {QCString s,s1,s2;Token *t=0;Token *t1=0;}
+{
+[LOOKAHEAD(1) s=identifier() t=<COLON_T> ] <NEXT_T> [ s1=identifier() ]
+[LOOKAHEAD(1) t1=<WHEN_T> s2=condition() ] <SEMI_T>
+{
+ if(t) s+=":";
+ FlowChart::addFlowChart(FlowChart::NEXT_NO,"next ",s2.data(),s1.data());
+ lab.resize(0);
+ if(t1) s2.prepend("when ");
+ return s+s1+s2+";";
+}
+}
+
+QCString null_statement() : {QCString s;}
+{
+[ s=identifier() <COLON_T> {s+=":";}] <NULL_T> <SEMI_T>{return s+="null";}
+}
+
+QCString numeric_literal() : {QCString s;}
+{
+
+ LOOKAHEAD(physical_literal())
+ s=physical_literal(){ return s;}
+ | s=abstract_literal() { return s;}
+}
+
+QCString object_class() : {}
+{
+<CONSTANT_T> { return "constant"; }
+|<SIGNAL_T> { return "signal"; }
+|<VARIABLE_T> { return "variable"; }
+|<SHARED_T> <VARIABLE_T> { return "shared variable"; }
+|<FILE_T> { return "file"; }
+|<TYPE_T> { return "type"; }
+}
+
+QCString operator_symbol() : {Token *tok;}
+{
+tok=<STRINGLITERAL> {return tok->image.c_str();}
+}
+
+void options() : {}
+{
+ [ <GUARDED_T> ] [ delay_mechanism() ]
+}
+
+void package_body() : {QCString s;}
+{
+<PACKAGE_T> <BODY_T> s=name() <IS_T>
+ {
+ lastCompound=current;
+ s.prepend("_");
+ addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE_BODY,0,0,Protected);
+ }
+ package_body_declarative_part()
+
+<END_T> [<PACKAGE_T> <BODY_T> ] [ name() ] <SEMI_T> { lastCompound=0; genLabels.resize(0); }
+}
+
+void package_body_declarative_item() : {}
+{
+subprogram_declaration()
+//| subprogram_body()
+| type_declaration()
+| subtype_declaration()
+| constant_declaration()
+| variable_declaration()
+| file_declaration()
+| alias_declaration()
+| use_clause()
+|
+LOOKAHEAD(3)
+group_template_declaration()
+| group_declaration()
+}
+
+void package_body_declarative_part() : {}
+{
+(package_body_declarative_item() )*
+}
+
+void package_declaration(): {QCString s;}
+{
+
+ <PACKAGE_T> s=identifier() <IS_T>
+ {
+ lastCompound=current;
+ Entry *clone=new Entry(*current);
+ clone->section=Entry::NAMESPACE_SEC;
+ clone->spec=VhdlDocGen::PACKAGE;
+ clone->name=s;
+ clone->startLine=getLine();
+ clone->bodyLine=getLine();
+ clone->protection=Package;
+ current_root->addSubEntry(clone);
+ addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE,0,0,Package);
+ }
+ package_declarative_part()
+<END_T> [ <PACKAGE_T>] [ name() ] <SEMI_T>
+{ lastEntity=0;lastCompound=0; genLabels.resize(0); }
+}
+
+void geninter():{}
+{
+ [gen_interface_list() <SEMI_T> [gen_assoc_list() <SEMI_T>]]
+}
+
+void package_declarative_item() : {}
+{
+//LOOKAHEAD(3)
+//interface_subprogram_declaration()
+subprogram_declaration()
+| type_declaration()
+| subtype_declaration()
+| constant_declaration()
+| signal_declaration()
+| variable_declaration()
+| file_declaration()
+| alias_declaration()
+| component_declaration()
+|
+LOOKAHEAD(attribute_declaration())
+ attribute_declaration()
+| attribute_specification()
+| disconnection_specification()
+| use_clause()
+|
+LOOKAHEAD(3)
+ group_template_declaration()
+| group_declaration()
+|
+ LOOKAHEAD(5)
+ package_instantiation_declaration()
+|package_declaration()
+
+}
+
+void package_declarative_part() : {}
+{
+ (package_declarative_item())*
+}
+
+QCString parameter_specification() : {QCString s,s1;}
+{
+s=identifier() <IN_T> s1=discrete_range(){ return s+" in "+s1;}
+}
+
+QCString physical_literal() : {QCString s,s1;}
+{
+ [LOOKAHEAD(abstract_literal()) s=abstract_literal()] s1=name(){s+=" ";s+=s1;s.prepend(" "); return s;}
+}
+
+QCString physical_type_definition() : {QCString s,s1,s2;}
+{
+ <UNITS_T>
+ s=identifier()<SEMI_T>
+ (s1=secondary_unit_declaration(){s2+=s1;s2+="#";})*
+ <END_T> <UNITS_T> [name()]
+ {
+ current->args=s2;
+ current->args.prepend("units");
+ current->spec=VhdlDocGen::UNITS;
+ return s2;
+ }
+}
+
+void port_clause() : {}
+{
+ <PORT_T> <LPAREN_T> port_list()<RPAREN_T> <SEMI_T>{ currP=0; }
+}
+
+QCString port_list() : {QCString s;}
+{
+ s=interface_list(){return s;}
+}
+
+void port_map_aspect() : {}
+{
+ <PORT_T> <MAP_T> <LPAREN_T> association_list() <RPAREN_T>
+}
+
+QCString primary() : {QCString s,s1;}
+{
+LOOKAHEAD(function_call())
+s=function_call() { return s;}
+|
+LOOKAHEAD(<LPAREN_T> expression() <RPAREN_T>)
+ <LPAREN_T> s1=expression() <RPAREN_T>{ s="("+s1+")"; return s;}
+|
+LOOKAHEAD(qualified_expression())
+s=qualified_expression() { return s;}
+|
+LOOKAHEAD(type_conversion())
+s=type_conversion() { return s;}
+|
+LOOKAHEAD(literal())
+s=literal() { s.prepend(" ");return s;}
+|
+LOOKAHEAD(name())
+s=name() { return s;}
+|
+allocator() { return "";}
+|
+s=aggregate() { return s; }
+}
+
+
+void primary_unit() : {}
+{
+entity_declaration()
+| configuration_declaration()
+|
+LOOKAHEAD(package_instantiation_declaration())
+package_instantiation_declaration()
+|
+LOOKAHEAD(4)
+ interface_package_declaration()
+| package_declaration()
+
+}
+
+QCString procedure_call() : {QCString s,s1;}
+{
+ s=name() [ <LPAREN_T> s1=actual_parameter_part() <RPAREN_T>{ s1.prepend("("); s1.append(")");}]
+{ return s+s1;}
+ }
+
+QCString procedure_call_statement() : {QCString s,s1;}
+{
+[LOOKAHEAD(2) s=identifier() <COLON_T> { s+=":"; }] s1=procedure_call() <SEMI_T>
+{
+ return s+s1+";";
+}
+}
+
+QCString process_declarative_item() : {QCString s;}
+{
+subprogram_declaration() { return "";}
+//| subprogram_body()
+| s=type_declaration() { return s;}
+| s=subtype_declaration() { return s;}
+| s=constant_declaration() { return s;}
+| s=variable_declaration() { return s;}
+| s=file_declaration() { return s;}
+| s=alias_declaration() { return s;}
+|
+LOOKAHEAD(3)
+s=attribute_declaration() { return s;}
+| s=attribute_specification() { return s;}
+| s=use_clause() { return s;}
+|
+LOOKAHEAD(3)
+s=group_template_declaration() { return s;}
+| s=group_declaration() { return s;}
+}
+
+QCString process_declarative_part() :{QCString s,s1;}
+{
+ ( s1=process_declarative_item(){s+=s1;} )* { return s;}
+}
+
+void process_statement() : {QCString s,s1,s2;Token *tok=0;}
+{
+[ s=identifier() <COLON_T> ]
+[ <POSTPONED_T> ]
+ {
+ currP=VhdlDocGen::PROCESS;
+ current->startLine=getLine();
+ current->bodyLine=getLine();
+ }
+ <PROCESS_T>
+ //try{
+ [ <LPAREN_T> (tok=<ALL_T> | s1=sensitivity_list()) <RPAREN_T> ] [ <IS_T> ]
+ s2=process_declarative_part()
+ {
+ if (s2.data())
+ FlowChart::addFlowChart(FlowChart::VARIABLE_NO,s2.data(),0);
+ FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
+ }
+ <BEGIN_T>
+ process_statement_part()
+ <END_T> [ <POSTPONED_T> ]
+ // }catch(...){error_skipto(PROCESS_T);}
+ <PROCESS_T> [ identifier() ] <SEMI_T>
+ {
+ if(s.isEmpty())
+ currName=VhdlDocGen::getProcessNumber();
+ else
+ currName=s;
+
+ current->name=currName;
+ tempEntry=current;
+ current->endBodyLine=getLine();
+ currP=0;
+ if(tok)
+ s1=tok->image.data();
+ createFunction(currName,VhdlDocGen::PROCESS,s1.data());
+ createFlow();
+ currName="";
+ newEntry();
+}
+}
+
+void process_statement_part() : {}
+{
+ (sequential_statement())*
+}
+
+QCString qualified_expression() : {QCString s,s1;}
+{
+ s1=identifier() <APOSTROPHE_T> {s=s1+"'";}
+ (
+ LOOKAHEAD(aggregate())
+ s1=aggregate(){s+=s1;}
+ | <LPAREN_T> s1=expression() <RPAREN_T>{s+="(";s+=s1;s+=")";}
+ )
+ {return s;}
+}
+
+QCString range() : {QCString s,s1,s2;}
+{
+ LOOKAHEAD( simple_expression() direction() simple_expression())
+ s=simple_expression() s1=direction() s2=simple_expression(){return s+" "+s1+" "+s2;}
+ |
+ LOOKAHEAD(attribute_name())
+ s=attribute_name(){ return s;}
+}
+
+QCString range_constraint() : {QCString s,s1;}
+{
+<RANGE_T> s=range(){return " range "+s;}
+}
+
+void record_type_definition() : {}
+{
+ <RECORD_T>
+ // try{
+ (element_declaration())+
+ // }catch(...){error_skipto(END_T);}
+ <END_T>
+ <RECORD_T> [ name()]
+}
+
+QCString relation() : {QCString s,s1,s2;}
+{
+ s=shift_expression() [LOOKAHEAD(1) s1=relation_operator() s2=shift_expression() ] {return s+s1+s2;}
+}
+
+QCString relation_operator() : {}
+{
+ <LT_T> {return "<";}
+ |<GT_T> {return ">";}
+ |<EQU_T> {return "=";}
+ |<GREATERTHAN_T> {return ">=";}
+ |<LESSTHAN_T> {return "<=";}
+ |<NOTEQU_T> {return "/=";}
+
+}
+
+QCString report_statement() : {Token *t=0;Token *t1=0;QCString s,s1,s2;}
+{
+[ s=identifier() t=<COLON_T> ]
+ <REPORT_T> s1=expression()
+ [ t1=<SEVERITY_T> s2=expression() ] <SEMI_T>
+ {
+ if(t) s.append(":");
+ s1.prepend(" report ");
+ if(t1) s2.prepend(" severity ");
+ return s+s1+s2+";";
+ }
+}
+
+QCString return_statement() : {QCString s,s1;}
+{
+[ s=identifier() <COLON_T> { s+=":";}] <RETURN_T> [ s1=expression() ] <SEMI_T>
+{ return s+" return "+s1+";";}
+}
+
+QCString scalar_type_definition() : {QCString s,s1;}
+{
+
+s=enumeration_type_definition(){ return s;}
+| s=range_constraint() [LOOKAHEAD( physical_type_definition()) s1=physical_type_definition()] { s+=" ";s+=s1;return s;}
+}
+
+void secondary_unit() : {}
+{
+architecture_body()
+| package_body()
+}
+
+QCString secondary_unit_declaration() : {QCString s,s1;}
+{
+s=identifier() <EQU_T> s1=physical_literal() <SEMI_T> { return s+"="+s1; }
+}
+
+QCString selected_name() : {QCString s,s1;}
+{
+ s=identifier() <DOT_T> s1=suffix(){ return s+"."+s1;}
+}
+
+void selected_signal_assignment() : {}
+{
+ <WITH_T> expression() <SELECT_T>
+
+ target() < LESSTHAN_T> options() selected_waveforms() <SEMI_T>
+}
+
+void selected_waveforms() : {}
+{
+ waveform() <WHEN_T> choices()(<COMMA_T> waveform() <WHEN_T> choices())*
+}
+
+QCString sensitivity_clause() : {QCString s;}
+{
+ <ON_T> s=sensitivity_list()
+ {
+ s.prepend(" on ");
+ return s;
+ }
+}
+
+QCString sensitivity_list() : {QCString s,s1;}
+{
+ s=name() (<COMMA_T> s1=name(){s+=",";s+=s1;} )* { return s;}
+}
+
+QCString sequence_of_statement() : {QCString s,s1;}
+{
+ ( LOOKAHEAD(3) s1=sequential_statement() {s+=s1;} )* { return s;}
+}
+
+QCString sequential_statement() :{QCString s;}
+{
+ LOOKAHEAD( [ identifier() ":" ] target() "<=")
+ s=signal_assignment_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+ |
+ LOOKAHEAD(3)
+ s=assertion_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+ |
+ LOOKAHEAD(3)
+ s=report_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+ |
+ LOOKAHEAD(3)
+ s=wait_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+ |
+ LOOKAHEAD( [ identifier() ":" ] target() ":=" )
+ s=variable_assignment_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+ |
+ LOOKAHEAD(3)
+ s=procedure_call_statement(){ FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s; }
+ |
+ LOOKAHEAD(3)
+ if_statement(){return s;}
+ |
+ LOOKAHEAD(3)
+ case_statement(){return s;}
+ |
+ LOOKAHEAD(3)
+ loop_statement(){return s;}
+ |
+ LOOKAHEAD(3)
+ s=next_statement() {return s;}
+ |
+ LOOKAHEAD(3)
+ s=exit_statement(){return s;}
+ |
+ LOOKAHEAD(3)
+ s=return_statement(){FlowChart::addFlowChart(FlowChart::RETURN_NO,s.data(),0);return s;}
+ |
+ s=null_statement(){FlowChart::addFlowChart(FlowChart::TEXT_NO,s.data(),0);return s;}
+}
+
+QCString shift_expression() : {QCString s,s1,s2;}
+{
+ s=simple_expression() [ s1=shift_operator() s2=simple_expression() ] { return s+s1+s2;}
+}
+QCString shift_operator() : {}
+{
+ <SLL_T> { return "sll";}
+ | <SRL_T> { return "srl";}
+ | <SLA_T> { return "sla";}
+ | <SRA_T> { return "sra";}
+ | <ROL_T> { return "rol";}
+ | <ROR_T> { return "ror";}
+}
+
+QCString sign() : {}
+{
+ <PLUS_T> { return "+";}
+ | <MINUS_T> { return "-";}
+}
+
+QCString signal_assignment_statement() : {QCString s,s1,s2,s3;}
+{
+
+ LOOKAHEAD(conditional_signal_assignment_wave())
+ conditional_signal_assignment_wave(){ return ""; }
+|
+ LOOKAHEAD(selected_signal_assignment_wave())
+ selected_signal_assignment_wave() { return ""; }
+ |
+ [LOOKAHEAD(2) s=identifier() <COLON_T> {s+=":";} ]
+s1=target() <LESSTHAN_T>
+[ s2=delay_mechanism() ]
+s3=waveform() <SEMI_T>
+{
+ return s+s1+"<="+s2+s3+";";
+}
+
+}
+
+void semi() : {}
+{
+<SEMI_T>
+}
+
+void signal_declaration() : { Token* tok=0;QCString s,s1,s2,s3,s4;}
+{
+<SIGNAL_T> s=identifier_list() <COLON_T> s1=subtype_indication() [ s2=signal_kind() ] [ tok=<VARASSIGN_T> s3=expression() ] <SEMI_T>
+ {
+ if(tok)
+ s3.prepend(":=");
+ s4=s1+s2+s3;
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::SIGNAL,0,s4.data(),Public);
+ }
+}
+QCString signal_kind() : {}
+{
+ <REGISTER_T> { return "register";}
+ | <BUS_T> { return "bus";}
+}
+
+QCString signal_list() : {QCString s,s1;}
+{
+ s=name() (<COMMA_T> s1=name() { s+=",";s+=s1;})*
+| <OTHER_T> { return "other";}
+| <ALL_T> { return "all";}
+}
+
+QCString signature() : {QCString s,s1,s2;}
+{
+<LBRACKET_T>
+ [ s=name() (<COMMA_T> s1=name() {s+=",";s+=s1; })* ]
+ [ <RETURN_T> s1=name() {s+="return ";s+=s1;}]
+ <RBRACKET_T>
+ { s1="["+s+"]";return s1;}
+ }
+
+QCString simple_expression(): {QCString s,s1,s2;}
+{
+[ s=sign() ] s1=term() {s+=s1;} ( LOOKAHEAD(adding_operator() term()) s1=adding_operator() s2=term() {s+=s1;s+=s2;})* { return s;}
+}
+
+void simple_name() : {}
+{
+name()
+}
+
+QCString slice_name() : {QCString s,s1;}
+{
+ s=identifier() <LPAREN_T> s1=discrete_range() <RPAREN_T> {return s+"("+s1+")";}
+}
+
+QCString string_literal() : {Token *tok;}
+{
+tok=<STRINGLITERAL> {return tok->image.c_str();}
+}
+
+ void subprogram_body() : {QCString s;}
+{
+//subprogram_specification()
+<IS_T>
+ //try{
+ s=subprogram_declarative_part()
+ {
+ if (s.data())
+ {
+ FlowChart::addFlowChart(FlowChart::VARIABLE_NO,s,0);
+ }
+ FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
+ }
+ // }catch(...){error_skipto(BEGIN_T);}
+<BEGIN_T>
+subprogram_statement_part()
+<END_T> [ subprogram_kind() ] [ designator() ] <SEMI_T>
+ {
+ tempEntry->endBodyLine=getLine(END_T);
+ createFlow();
+ currP=0;
+ }
+}
+
+void subprogram_declaration() : {}
+{
+LOOKAHEAD(subprogram_instantiation_declaration())
+subprogram_instantiation_declaration()
+|
+subprogram_specification()subprogram_1(){currP=0;}
+}
+
+void subprogram_1() : {}
+{
+
+ subprogram_body()
+ | <SEMI_T>
+}
+
+QCString subprogram_declarative_item() : {QCString s;}
+{
+subprogram_declaration(){ return "";}
+|s=type_declaration(){ return s;}
+ | subprogram_body(){ return "";}
+| s=subtype_declaration(){ return s;}
+| s=constant_declaration(){ return s;}
+| s=variable_declaration(){ return s;}
+| s=file_declaration(){ return s;}
+| s=alias_declaration(){ return s;}
+|
+LOOKAHEAD(attribute_declaration())
+s=attribute_declaration(){ return s;}
+| s=attribute_specification(){ return s;}
+| s=use_clause(){ return s;}
+|
+LOOKAHEAD(3)
+s=group_template_declaration(){ return s;}
+| s=group_declaration() { return s;}
+}
+
+QCString subprogram_declarative_part() : {QCString s,s1;}
+{
+ (s1=subprogram_declarative_item(){s+=s1;})* { return s;}
+}
+
+void subprogram_kind() : {}
+{
+ <FUNCTION_T>
+ |<PROCEDURE_T>
+}
+
+void subprogram_specification() : {QCString s;Token *tok=0;Token *t;}
+{
+ <PROCEDURE_T> s=designator()
+ {
+ currP=VhdlDocGen::PROCEDURE;
+ createFunction(s.data(),currP,0);
+ tempEntry=current;
+ current->startLine=getLine(PROCEDURE_T);
+ current->bodyLine=getLine(PROCEDURE_T);
+
+ } [LOOKAHEAD(1) <LPAREN_T> { param_sec=PARAM_SEC; } interface_list() { param_sec=0; }<RPAREN_T> ]
+ [LOOKAHEAD(2) gen_interface_list()]
+ [ LOOKAHEAD(2) gen_assoc_list()]
+ param()
+ { newEntry(); }
+|
+ [ (tok=<PURE_T> | tok=<IMPURE_T>) ] t=<FUNCTION_T> s=designator()
+ {
+ currP=VhdlDocGen::FUNCTION;
+ if(tok)
+ createFunction(tok->image.c_str(),currP,s.data());
+ else
+ createFunction(0,currP,s.data());
+ tempEntry=current;
+ current->startLine=getLine(FUNCTION_T);
+ current->bodyLine=getLine(FUNCTION_T);
+ }
+ [{ param_sec=PARAM_SEC; } <LPAREN_T> formal_parameter_list() <RPAREN_T> { param_sec=0; }]
+ <RETURN_T> s=type_mark()
+ {
+ tempEntry=current;
+ current->type=s;
+ newEntry();
+ }
+}
+
+void subprogram_statement_part() : {}
+{
+ (sequential_statement())*
+}
+
+QCString subtype_declaration() : {QCString s,s1;}
+{
+<SUBTYPE_T> s=identifier() <IS_T> s1=subtype_indication() <SEMI_T>
+ {
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::SUBTYPE,0,s1.data(),Public);
+ return " subtype "+s+" is "+s1+";";
+ }
+}
+
+QCString subtype_indication() : {QCString s,s1,s2;}
+{
+ s=name()
+ [LOOKAHEAD (name()) s1=name()] [LOOKAHEAD(constraint() ) s2=constraint()]
+ {return s+" "+s1+" "+s2;}
+}
+
+QCString suffix() : {QCString s;}
+{
+LOOKAHEAD(name())
+s=name() { return s;}
+| s=character_literal() { return s;}
+| s=operator_symbol(){ return s;}
+| <ALL_T> {return " all ";}
+}
+
+QCString target() : {QCString s;}
+{
+ s=name(){ return s;}
+| s=aggregate() { return s;}
+}
+
+QCString term() : {QCString s,s1,s2;}
+{
+ s=factor() ( LOOKAHEAD(2) s1=multiplying_operation() s2=factor(){s+=s1;s+=s2;} )* { return s;}
+}
+
+QCString timeout_clause() : {QCString s;}
+{
+<FOR_T> s=expression()
+{
+ return " for "+s;
+}
+}
+
+QCString type_conversion() : {QCString s,s1;}
+{
+ s=name() <LPAREN_T> s1=expression() <RPAREN_T> { return s+"("+s1+")";}
+}
+
+QCString type_declaration() : {QCString s;}
+{
+LOOKAHEAD(3)
+s=full_type_declaration(){ return s;}
+| s=incomplete_type_declaration(){ return s;}
+}
+
+QCString type_definition() : {QCString s;}
+{
+//try{
+s=scalar_type_definition(){ return s;}
+| s=composite_type_definition(){ return s;}
+| s=access_type_definition(){ return s;}
+| s=file_type_definition(){ return s;}
+|
+ LOOKAHEAD(2)
+ protected_type_body() { return ""; }
+| protected_type_declaration() { return ""; }
+//}catch(...){error_skipto(SEMI_T); return "";}
+}
+
+QCString type_mark() : {QCString s; }
+{
+ s=name() { return s;}
+}
+
+QCString unconstraint_array_definition() : {QCString s,s1,s2,s3;}
+{
+<ARRAY_T> <LPAREN_T> s=index_subtype_definition() ( <COMMA_T> s1=index_subtype_definition(){s3+=",";s3+=s1;})* <RPAREN_T>
+ <OF_T> s2=subtype_indication() {return "array("+s+s3+") of "+s2;}
+}
+
+ QCString use_clause() : {QCString s,s1;}
+{
+ <USE_T> s=selected_name()(<COMMA_T> s1=selected_name(){s+=",";s+=s1;})* <SEMI_T>
+ {
+ QStringList ql1=QStringList::split(",",s,FALSE);
+ for (uint j=0;j<ql1.count();j++)
+ {
+ QStringList ql=QStringList::split(".",ql1[j],FALSE);
+ QCString it=ql[1].utf8();
+ if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
+ {
+ VhdlParser::addVhdlType(it.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::USE,it.data(),"_use_",Public);
+ }
+ }
+ s1="use "+s;
+ return s1;
+ }
+}
+
+QCString variable_assignment_statement() : {QCString s,s1,s2;}
+{
+[LOOKAHEAD(2) s=identifier() <COLON_T> {s+=":";}]
+ s1=target() <VARASSIGN_T> s2=expression() <SEMI_T>
+ {return s+s1+":="+s2+";";}
+ |
+ selected_variable_assignment() { return ""; }
+}
+
+QCString variable_declaration() : {Token *tok=0;Token *t1=0;QCString s,s1,s2;}
+{
+[ tok=<SHARED_T> ] <VARIABLE_T> s=identifier_list() <COLON_T> s1=subtype_indication()
+[ t1=<VARASSIGN_T> s2=expression() ] <SEMI_T>
+
+{
+ int spec;
+ if(t1)
+ s2.prepend(":=");
+ QCString val=" variable "+s+":"+s1+s2+";";
+ QCString it=s1;
+ if(tok != 0)
+ {
+ it.prepend(" shared ");
+ val.prepend(" shared");
+ spec=VhdlDocGen::SHAREDVARIABLE;
+ }
+ else
+ spec=VhdlDocGen::SHAREDVARIABLE;
+
+ if(t1){
+ it+=":=";
+ it+=s2;
+ }
+ addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,spec,0,it.data(),Public);
+ return val;
+ }
+
+}
+
+QCString wait_statement() : {QCString s,s1,s2,s3;Token *t=0;}
+{
+[ s=identifier() t=<COLON_T> ] <WAIT_T> [ s1=sensitivity_clause() ] [ s2=condition_clause() ] [ s3=timeout_clause() ] <SEMI_T>
+{
+ if(t) s.append(":");
+ return s+" wait "+s1+s2+s3+";";
+}
+}
+
+QCString waveform() : {QCString s,s1;}
+{
+s=waveform_element() (LOOKAHEAD(1) <COMMA_T> s1=waveform_element(){s+=","; s+=s1;})* { return s;}
+|
+<UNAFFECTED_T> { return " unaffected ";}
+
+}
+
+QCString waveform_element() : {QCString s,s1;}
+{
+ s=expression() [ <AFTER_T> s1=expression(){ s1.prepend(" after ");} ]
+ { return s+s1;}
+//<NULL_T> [ <AFTER_T> expression() ]
+}
+
+// -----------------------------------------------------------------
+// VHDL 2002
+// -----------------------------------------------------------------
+
+QCString protected_type_body() :{ }
+{
+ // try{
+ <PROTECTED_T> <BODY_T>
+ protected_type_body_declarative_part()
+
+ //}catch(...){error_skipto(END_T);}
+ <END_T><PROTECTED_T> <BODY_T> [identifier()] {return "";}
+}
+
+void protected_type_body_declarative_item() : { }
+ {
+ subprogram_declaration()
+ | subprogram_body()
+ | type_declaration()
+ | subtype_declaration()
+ | constant_declaration()
+ | variable_declaration()
+ | file_declaration()
+ | alias_declaration()
+ |
+ LOOKAHEAD( attribute_declaration())
+ attribute_declaration()
+ | attribute_specification()
+ | use_clause()
+ | LOOKAHEAD(3)
+ group_template_declaration()
+ | group_declaration()
+
+}
+
+void protected_type_body_declarative_part() :{ }
+{
+ ( protected_type_body_declarative_item ())*
+}
+
+
+QCString protected_type_declaration() : { }
+ {
+ <PROTECTED_T>
+ try{
+ protected_type_declarative_part()
+ }catch(...){error_skipto(END_T);}
+ <END_T><PROTECTED_T> [ identifier() ] { return "";}
+ }
+
+
+void protected_type_declarative_item(): { }
+{
+ subprogram_specification()
+ | attribute_specification()
+ | use_clause()
+}
+
+void protected_type_declarative_part() : {}
+{
+ (protected_type_declarative_item ()<SEMI_T>)*
+}
+
+// -----------------------------------------------------------------
+// VHDL 2008
+// -----------------------------------------------------------------
+
+QCString context_ref() : {QCString s;}
+{
+ <CONTEXT_T> s=identifier_list() <SEMI_T>
+ {
+ return "context "+s ;
+ }
+}
+
+void context_declaration(): {QCString s,s1;}
+{
+ <CONTEXT_T> s=identifier() <IS_T> { parse_sec=CONTEXT_SEC; } (s1=libustcont_stats())* <END_T> [ <CONTEXT_T> ][identifier()] <SEMI_T>
+ {
+ parse_sec=0;
+ addVhdlType(s.data(),getLine(LIBRARY_T),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,"context",s1.data(),Public);
+ }
+}
+
+QCString libustcont_stats(): {QCString s;}
+{
+ s=use_clause() { return s;}
+ | s=library_clause() { return s;}
+ | s=context_ref() { return s;}
+}
+
+ void package_instantiation_declaration() : {QCString s,s1,s2;}
+ {
+ <PACKAGE_T> s=identifier() <IS_T> <NEW_T> s1=name() s2=signature() [gen_assoc_list()] <SEMI_T>
+ {
+ QCString q=" is new "+s1+s2;
+ addVhdlType(s.data(),getLine(PACKAGE_T),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"package",q.data(),Public);
+ }
+}
+
+QCString interface_package_declaration(): {QCString s,s1;}
+{
+ <PACKAGE_T> s=identifier() <IS_T> <NEW_T> s1=name() [gen_assoc_list()]
+ {
+ current->name=s;
+ return "package "+s+" is new "+s1;
+ }
+}
+
+QCString subprogram_instantiation_declaration():{QCString s,s1,s2;}
+{
+ <FUNCTION_T> s=identifier() <IS_T> <NEW_T> s1=name() s2=signature() [gen_assoc_list()] <SEMI_T>
+ {
+ QCString q= " is new "+s1+s2;
+ addVhdlType(s.data(),getLine(FUNCTION_T),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"function ",q.data(),Public);
+ return q;
+ }
+}
+
+
+void gen_assoc_list():{}
+{
+ <GENERIC_T> <MAP_T> <LPAREN_T> association_list()<RPAREN_T>
+}
+
+void gen_interface_list() : {}
+{
+ <GENERIC_T><LPAREN_T>
+ {
+ //int u=s_str.iLine;
+ parse_sec=GEN_SEC;
+ }
+ interface_list()
+ {
+ // QCString vo=$3;
+ parse_sec=0;
+ }
+ <RPAREN_T>
+}
+
+void case_scheme (): {}
+{
+ <CASE_T> expression() <GENERATE_T> when_stats() [LOOKAHEAD(3) ttend()] <END_T>
+ <GENERATE_T> generate_statement_body() <SEMI_T>
+}
+
+void when_stats() : {}
+{
+ (
+ <WHEN_T> [LOOKAHEAD(2) label() <COLON_T>] choices() <ARROW_T> generate_statement_body()
+ )+
+}
+
+void ttend(): {}
+{
+ <END_T> [identifier()] <SEMI_T>
+ }
+
+
+void generate_statement_body() : {}
+{
+ <BEGIN_T> generate_statement_body()
+}
+
+void generate_statement_body1() : {}
+{
+ LOOKAHEAD(block_declarative_item()<BEGIN_T> )
+ (block_declarative_item() )* <BEGIN_T> (concurrent_statement())*
+ | (concurrent_statement())*
+}
+
+QCString external_name(): {QCString s,s1,s2;}
+{
+ <SLSL_T> s=sig_stat() s1=external_pathname() <COLON_T> s2=subtype_indication() <RSRS_T>
+ {
+ QCString t="<<"+s;
+ QCString t1=s1+":"+s2+">>";
+ return s+s1;
+ }
+}
+
+QCString sig_stat(): {Token *t;}
+{
+ t=<CONSTANT_T> { return t->image.data(); }
+ | t=<SIGNAL_T> { return t->image.data(); }
+ | t=<VARIABLE_T> { return t->image.data(); }
+
+}
+
+QCString external_pathname(): {QCString s;}
+{
+ s=absolute_pathname() { return s;}
+ | s=relative_pathname() { return s;}
+ | s=package_path_name() { return s;}
+ }
+
+QCString absolute_pathname(): {QCString s,s1;}
+{
+ LOOKAHEAD(<DOT_T> pathname_element_list())
+ <DOT_T> s=pathname_element_list() s1=identifier() { return "."+s+s1;}
+| <DOT_T> s=identifier (){ return "."+s;}
+}
+
+QCString relative_pathname():{QCString s,s1,s2;}
+{
+ s=neg_list() [LOOKAHEAD( pathname_element_list()) s1=pathname_element_list() ] s2=identifier() { return s+s1+s2;}
+}
+
+QCString neg_list(): {QCString s;}
+{
+ (<NEG_T> <DOT_T>{s+="^.";})+ {return s; }
+}
+
+QCString pathname_element ():{QCString s,s1;}
+{
+ s=identifier() [<LPAREN_T> s1=expression() <RPAREN_T>]
+ {
+ if(!s1.isEmpty())
+ return s+"("+s1+")";
+
+ return s;
+ }
+ }
+
+QCString pathname_element_list():{QCString s,s1,s2;}
+{
+ ( s=pathname_element() <DOT_T> ) {s+=".";} (LOOKAHEAD(pathname_element() <DOT_T>) s1=pathname_element() <DOT_T> {s2+=s1;s2+="."; })*
+ { return s+s2; }
+}
+
+QCString package_path_name():{QCString s;}
+{
+ <AT_T> s=name() { return "@"+s; }
+}
+
+void conditional_signal_assignment_wave(): {}
+{
+ LOOKAHEAD(conditional_force_assignment())
+ conditional_force_assignment()
+ |conditional_waveform_assignment()
+}
+
+void conditional_waveform_assignment():{}
+{
+ target() <LESSTHAN_T> [LOOKAHEAD(1) delay_mechanism() ] waveform_element() <WHEN_T> expression() [else_wave_list()] <SEMI_T>
+ }
+
+void else_wave_list(): {}
+{
+<ELSE_T> expression() [ <WHEN_T> expression()]
+}
+
+void conditional_force_assignment(): {}
+{
+ target() <LESSTHAN_T> <FORCE_T> [inout_stat()] expression() <WHEN_T> [expression() else_stat()] <SEMI_T>
+}
+
+void selected_signal_assignment_wave() : {}
+{
+ LOOKAHEAD(selected_force_assignment() )
+ selected_force_assignment()
+| selected_waveform_assignment()
+}
+
+void selected_variable_assignment():{}
+{
+ <WITH_T> expression() <SELECT_T> [<Q_T>] select_name() <VARASSIGN_T> sel_var_list() // { $$=""; }
+}
+
+void select_name(): {}
+{
+ LOOKAHEAD(aggregate())
+ aggregate()
+ | name()
+
+}
+
+void selected_waveform_assignment():{}
+{
+ <WITH_T> expression() <SELECT_T> [<Q_T>]
+ target() <LESSTHAN_T> [delay_mechanism()] sel_wave_list()
+}
+
+void selected_force_assignment():{}
+{
+<WITH_T> expression() <SELECT_T> [<Q_T>] target() <LESSTHAN_T> <FORCE_T>
+ [inout_stat()] sel_var_list()
+}
+
+void sel_var_list(): {}
+{
+ (expression() <WHEN_T> choices() (<COMMA_T>|<SEMI_T>))(LOOKAHEAD(expression() <WHEN_T>) expression() <WHEN_T> choices() (<COMMA_T>|<SEMI_T>))*
+
+}
+
+
+void sel_wave_list() : {}
+{
+ waveform_element() <WHEN_T> choices() (LOOKAHEAD(1) <COMMA_T> sel_wave_list())* <SEMI_T>
+ // | sel_wave_list_1()
+}
+
+void inout_stat(): {}
+{
+ <IN_T>
+ | <OUT_T>
+ }
+
+void else_stat(): {}
+{
+ (<ELSE_T> expression() [LOOKAHEAD(1) <WHEN_T> expression()])+
+}
+
+
+
+QCString interface_subprogram_declaration(): {QCString s;}
+{
+ s=iproc() { return s;}
+ | s=ifunc() { return s; }
+}
+
+QCString iproc(): {QCString s,s1;}
+ {
+ <PROCEDURE_T> s=identifier() s1=param()
+ {
+ current->name=s;
+ return "procedure "+s+s1;
+ }
+ }
+
+QCString ifunc():{QCString s,s1,s2,s3;Token *t=0;Token *t1=0;Token *t2=0;}
+{
+
+ [t=<PURE_T> | t=<IMPURE_T> ] <FUNCTION_T> s=name() s1=param() <RETURN_T> s2=name() [t1=<IS_T> (s3=identifier() | t2=<BOX_T>)]
+ {
+ QCString q;
+ if(t) q=t->image.data();
+ if(t2) s3="<>";
+ if (!s3.isEmpty())
+ {
+ s3.prepend(" is ");
+ }
+ current->name=s;
+ if (parse_sec==GEN_SEC)
+ {
+ QCString ss=q+" function "+s1+" return "+s2+s3;
+ int a=getLine(FUNCTION_T);
+ int b=getLine(PROCEDURE_T);
+
+ if (a>b) b=a;
+ addVhdlType(current->name.data(),b,Entry::VARIABLE_SEC,VhdlDocGen::GENERIC,ss.data(),0,Public);
+ }
+ currP=0;return "";
+ }
+
+ }
+
+
+QCString param(): {QCString s,s1;Token *tok=0;}
+{
+[ tok=<PARAMETER_T> ] { param_sec=PARAM_SEC; }
+ [ <LPAREN_T> s1=interface_list() <RPAREN_T>]
+ {
+ if(tok)
+ {
+ s = tok->image.data();
+ param_sec=0;
+ }
+ return s+"("+s1+")";
+ }
+
+ }
+
+ // -----------------------------------------------------------------
+ // needed for inline (function/process/procedure) parsing
+
+void parseInline() : {}
+{
+ process_statement()
+ | subprogram_declaration()
+ }
diff --git a/vhdlparser/vhdlparser.patch b/vhdlparser/vhdlparser.patch
new file mode 100644
index 0000000..37cca10
--- /dev/null
+++ b/vhdlparser/vhdlparser.patch
@@ -0,0 +1,10 @@
+--- VhdlParser.h 2014-07-27 14:26:18.000000000 +0200
++++ VhdlParser.h.new 2014-07-27 14:23:22.000000000 +0200
+@@ -6,6 +6,7 @@
+ #include "TokenManager.h"
+ #include "VhdlParserTokenManager.h"
+ #include "VhdlParser.h"
++#include "vhdljjparser.h"
+
+ #include "VhdlParserConstants.h"
+ #include "ErrorHandler.h"
diff --git a/vhdlparser/vhdlparser.pro b/vhdlparser/vhdlparser.pro
new file mode 100644
index 0000000..cc034f0
--- /dev/null
+++ b/vhdlparser/vhdlparser.pro
@@ -0,0 +1,40 @@
+#
+# This file was generated from vhdlparser.pro.in on Thu Aug 21 10:48:35 CEST 2014
+#
+
+TEMPLATE = lib
+CONFIG = warn_on staticlib debug
+HEADERS = CharStream.h \
+ ErrorHandler.h \
+ JavaCC.h \
+ ParseException.h \
+ TokenManager.h \
+ Token.h \
+ vhdlstring.h \
+ VhdlParser.h \
+ VhdlParserConstants.h \
+ VhdlParserTokenManager.h \
+ TokenMgrError.h \
+ VhdlParserIF.h \
+ VhdlParserErrorHandler.hpp
+
+SOURCES = CharStream.cc \
+ ParseException.cc \
+ Token.cc \
+ TokenMgrError.cc \
+ VhdlParser.cc \
+ VhdlParserTokenManager.cc \
+ VhdlParserIF.cpp
+
+INCLUDEPATH = . ../src ../qtools generated_src/doxygen
+#TMAKE_CXXFLAGS += -DQT_NO_CODECS -DQ T_LITE_UNICODE
+
+#must enable -fexceptions because we have try catch blocks in VhdlParser.cc
+TMAKE_CXXFLAGS +=-w -fexceptions -DQT_LITE_UNICODE
+win32:TMAKE_CXXFLAGS += -fexceptions -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -fexceptions -D__CYGWIN__ -DALL_STATIC
+OBJECTS_DIR = ../objects/vhdlparser
+DESTDIR = ../lib
+TMAKE_MOC = /usr/bin/moc
+LIBS += -L/opt/local/lib
+INCLUDEPATH += /opt/local/include
diff --git a/vhdlparser/vhdlparser.pro.in b/vhdlparser/vhdlparser.pro.in
new file mode 100644
index 0000000..0232fd5
--- /dev/null
+++ b/vhdlparser/vhdlparser.pro.in
@@ -0,0 +1,33 @@
+TEMPLATE = lib
+CONFIG = warn_on staticlib $extraopts
+HEADERS = CharStream.h \
+ ErrorHandler.h \
+ JavaCC.h \
+ ParseException.h \
+ TokenManager.h \
+ Token.h \
+ vhdlstring.h \
+ VhdlParser.h \
+ VhdlParserConstants.h \
+ VhdlParserTokenManager.h \
+ TokenMgrError.h \
+ VhdlParserIF.h \
+ VhdlParserErrorHandler.hpp
+
+SOURCES = CharStream.cc \
+ ParseException.cc \
+ Token.cc \
+ TokenMgrError.cc \
+ VhdlParser.cc \
+ VhdlParserTokenManager.cc \
+ VhdlParserIF.cpp
+
+INCLUDEPATH = . ../src ../qtools generated_src/doxygen
+#TMAKE_CXXFLAGS += -DQT_NO_CODECS -DQ T_LITE_UNICODE
+
+#must enable -fexceptions because we have try catch blocks in VhdlParser.cc
+TMAKE_CXXFLAGS +=-w -fexceptions -DQT_LITE_UNICODE
+win32:TMAKE_CXXFLAGS += -fexceptions -DQT_NODLL
+win32-g++:TMAKE_CXXFLAGS += -fexceptions -D__CYGWIN__ -DALL_STATIC
+OBJECTS_DIR = ../objects/vhdlparser
+DESTDIR = ../lib
diff --git a/vhdlparser/vhdlstring.h b/vhdlparser/vhdlstring.h
new file mode 100644
index 0000000..ec13907
--- /dev/null
+++ b/vhdlparser/vhdlstring.h
@@ -0,0 +1,101 @@
+#ifndef VHDLSTRING_H
+#define VHDLSTRING_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/** @brief Minimal string class with std::string like behaviour that fulfills the JavaCC
+ * string requirements.
+ */
+class VhdlString
+{
+ public:
+ VhdlString()
+ {
+ init();
+ }
+ VhdlString(const VhdlString &other)
+ {
+ m_str = (char*)malloc(other.m_len+1);
+ memcpy(m_str,other.m_str,other.m_len);
+ m_len = other.m_len;
+ m_str[m_len]=0;
+ }
+ VhdlString &operator=(const VhdlString &other)
+ {
+ if (this!=&other)
+ {
+ free(m_str);
+ m_str = (char*)malloc(other.m_len+1);
+ memcpy(m_str,other.m_str,other.m_len);
+ m_len = other.m_len;
+ m_str[m_len]=0;
+ }
+ return *this;
+ }
+ VhdlString(const char *s)
+ {
+ m_len = strlen(s);
+ m_str=(char*)malloc(m_len+1);
+ memcpy(m_str,s,m_len+1);
+ }
+ VhdlString(const char *s,int size)
+ {
+ m_str = (char*)malloc(size+1);
+ memcpy(m_str,s,size);
+ m_str[size]=0;
+ m_len=size;
+ }
+ ~VhdlString()
+ {
+ delete[] m_str;
+ }
+ VhdlString& append(const char *s,int size)
+ {
+ int oldlen = m_len;
+ m_len+=size+1;
+ if (m_len)
+ {
+ m_str = (char*)realloc(m_str,m_len);
+ memcpy(m_str+oldlen,s,m_len-oldlen-1);
+ m_str[m_len-1]=0;
+ }
+ return *this;
+ }
+ VhdlString& append(const char *s)
+ {
+ return append(s,strlen(s));
+ }
+ VhdlString& append(const VhdlString &other)
+ {
+ return append(other.m_str,other.m_len);
+ }
+ VhdlString substr(int pos=0,int len=-1)
+ {
+ return VhdlString(m_str?m_str+pos:0,len==-1?m_len-pos:m_len);
+ }
+ int copy(char *s,int len,int pos=0) const
+ {
+ if (len==0) return 0;
+ if (pos>=m_len) { s[0]=0; return 0; }
+ int r=m_len<pos+len ? m_len-pos : len;
+ memcpy(s,m_str+pos,r);
+ return r;
+ }
+ const char *c_str() const { return m_str; }
+ const char *data() const { return m_str; }
+ int size() const { return m_len; }
+ int length() const { return m_len; }
+ char & operator[](int i) { return m_str[i]; }
+ const char &operator[](int i) const { return m_str[i]; }
+ void clear() { free(m_str); init(); }
+ VhdlString operator+=(char c) { char s[2]; s[0]=c; s[1]=0; return append(s); }
+
+ private:
+ void init() { m_str=(char*)calloc(1,1); m_len=0; }
+ char *m_str;
+ int m_len;
+};
+
+#endif
diff --git a/winbuild/.gitignore b/winbuild/.gitignore
new file mode 100644
index 0000000..a073474
--- /dev/null
+++ b/winbuild/.gitignore
@@ -0,0 +1,7 @@
+Debug/
+Debug64/
+Release/
+Release64/
+Doxygen.ncb
+Doxygen.suo
+*.user
\ No newline at end of file
diff --git a/winbuild/Config.rules b/winbuild/Config.rules
new file mode 100644
index 0000000..788497d
--- /dev/null
+++ b/winbuild/Config.rules
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="config"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Config"
+ DisplayName="Config"
+ CommandLine="python "$(ProjectDir)..\src\configgen.py" -cpp [AllOptions] [AdditionalOptions] [inputs] > $(IntDir)/$(InputName)options.cpp"
+ Outputs="$(IntDir)/$(InputName)options.cpp"
+ FileExtensions="*.xml"
+ AdditionalDependencies="$(ProjectDir)..\src\configgen.py"
+ ExecutionDescription="Executing configgen for doxygen..."
+ ShowOnlyRuleProperties="false"
+ >
+ </CustomBuildRule>
+ <CustomBuildRule
+ Name="Config_dw"
+ DisplayName="Config"
+ CommandLine="python "$(ProjectDir)..\src\configgen.py" -wiz [AllOptions] [AdditionalOptions] [inputs] > $(IntDir)/$(InputName)doc.cpp"
+ Outputs="$(IntDir)/$(InputName)doc.cpp"
+ FileExtensions="*.xml"
+ AdditionalDependencies="$(ProjectDir)..\src\configgen.py"
+ ExecutionDescription="Executing configgen for doxywizard ..."
+ ShowOnlyRuleProperties="false"
+ >
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/Doxygen.sln b/winbuild/Doxygen.sln
new file mode 100644
index 0000000..98e1c36
--- /dev/null
+++ b/winbuild/Doxygen.sln
@@ -0,0 +1,71 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Doxygen", "Doxygen.vcproj", "{309C9A4A-94D2-4837-9A11-45B0A6CF35C3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64} = {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtools", "qtools.vcproj", "{B6BB4771-8A4E-4656-AC08-1EF8AC182F64}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxywizard", "Doxywizard.vcproj", "{77C9C2D3-EA3F-3D59-8B4C-0ED852890172}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxysearch", "doxysearch.vcproj", "{F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doxyindexer", "doxyindexer.vcproj", "{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64} = {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Debug|Win32.Build.0 = Debug|Win32
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Debug|x64.ActiveCfg = Debug|x64
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Debug|x64.Build.0 = Debug|x64
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Release|Win32.ActiveCfg = Release|Win32
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Release|Win32.Build.0 = Release|Win32
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Release|x64.ActiveCfg = Release|x64
+ {309C9A4A-94D2-4837-9A11-45B0A6CF35C3}.Release|x64.Build.0 = Release|x64
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Debug|Win32.Build.0 = Debug|Win32
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Debug|x64.ActiveCfg = Debug|x64
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Debug|x64.Build.0 = Debug|x64
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Release|Win32.ActiveCfg = Release|Win32
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Release|Win32.Build.0 = Release|Win32
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Release|x64.ActiveCfg = Release|x64
+ {B6BB4771-8A4E-4656-AC08-1EF8AC182F64}.Release|x64.Build.0 = Release|x64
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Debug|Win32.ActiveCfg = Debug|Win32
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Debug|Win32.Build.0 = Debug|Win32
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Debug|x64.ActiveCfg = Debug|x64
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Debug|x64.Build.0 = Debug|x64
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Release|Win32.ActiveCfg = Release|Win32
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Release|Win32.Build.0 = Release|Win32
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Release|x64.ActiveCfg = Release|x64
+ {77C9C2D3-EA3F-3D59-8B4C-0ED852890172}.Release|x64.Build.0 = Release|x64
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Debug|Win32.Build.0 = Debug|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Debug|x64.ActiveCfg = Debug|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Release|Win32.ActiveCfg = Release|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Release|Win32.Build.0 = Release|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Release|x64.ActiveCfg = Release|Win32
+ {F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}.Release|x64.Build.0 = Release|Win32
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|Win32.Build.0 = Debug|Win32
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|x64.ActiveCfg = Debug|x64
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Debug|x64.Build.0 = Debug|x64
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|Win32.ActiveCfg = Release|Win32
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|Win32.Build.0 = Release|Win32
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|x64.ActiveCfg = Release|x64
+ {E543983A-D5BF-4865-B4A1-6D7EF2E1051C}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/winbuild/Doxygen.vcproj b/winbuild/Doxygen.vcproj
new file mode 100644
index 0000000..882e514
--- /dev/null
+++ b/winbuild/Doxygen.vcproj
@@ -0,0 +1,2989 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="Doxygen"
+ ProjectGUID="{309C9A4A-94D2-4837-9A11-45B0A6CF35C3}"
+ RootNamespace="Doxygen"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ <ToolFile
+ RelativePath=".\Lex.rules"
+ />
+ <ToolFile
+ RelativePath=".\Settings.rules"
+ />
+ <ToolFile
+ RelativePath=".\Unistd.rules"
+ />
+ <ToolFile
+ RelativePath=".\Version.rules"
+ />
+ <ToolFile
+ RelativePath=".\Config.rules"
+ />
+ <ToolFile
+ RelativePath=".\Gen_head.rules"
+ />
+ <ToolFile
+ RelativePath=".\Languages.rules"
+ />
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\Debug"
+ IntermediateDirectory=".\Debug\doxygen"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="Gen_head"
+ />
+ <Tool
+ Name="Languages"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Debug\doxygen\Doxygen.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/Zm200 "
+ Optimization="0"
+ AdditionalIncludeDirectories="..\src,..\qtools,..\libpng,..\libmd5,..\vhdlparser,$(IntDir),."
+ PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG; _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;LIBICONV_STATIC;CHARSET_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug\doxygen/Doxygen.pch"
+ AssemblerListingLocation=".\Debug\doxygen/"
+ ObjectFile=".\Debug\doxygen/"
+ ProgramDataBaseFileName=".\Debug\doxygen\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib ws2_32.lib iconv.lib shell32.lib"
+ OutputFile="..\bin\Debug\doxygen.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="Debug"
+ GenerateManifest="false"
+ IgnoreDefaultLibraryNames="libcmtd.lib libcpmtd.lib libcmt.lib"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug\doxygen\$(TargetName).pdb"
+ SubSystem="1"
+ LargeAddressAware="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug\doxygen/Doxygen.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="..\bin\Debug64"
+ IntermediateDirectory=".\Debug64\doxygen"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="Gen_head"
+ />
+ <Tool
+ Name="Languages"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Debug64\doxygen\Doxygen.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/Zm200 /bigobj"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\src,..\qtools,..\libpng,..\libmd5,..\vhdlparser,$(IntDir),."
+ PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG; _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;LIBICONV_STATIC;CHARSET_STATIC"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug64\doxygen/Doxygen.pch"
+ AssemblerListingLocation=".\Debug64\doxygen/"
+ ObjectFile=".\Debug64\doxygen/"
+ ProgramDataBaseFileName=".\Debug64\doxygen\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib ws2_32.lib iconv64.lib shell32.lib"
+ OutputFile="..\bin\Debug64\doxygen.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="Debug64"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug64\doxygen\$(TargetName).pdb"
+ SubSystem="1"
+ LargeAddressAware="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug64\doxygen/Doxygen.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\Release"
+ IntermediateDirectory=".\Release\doxygen"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="Gen_head"
+ />
+ <Tool
+ Name="Languages"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Release\doxygen\Doxygen.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/Zm200 "
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="..\src,..\qtools,..\libpng,..\libmd5,..\vhdlparser,$(IntDir),."
+ PreprocessorDefinitions="WIN32;_CINDEX_LIB_;_CINDEX_LIB_;NDEBUG;_CONSOLE; _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;LIBICONV_STATIC;CHARSET_STATIC"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release\doxygen/Doxygen.pch"
+ AssemblerListingLocation=".\Release\doxygen/"
+ ObjectFile=".\Release\doxygen/"
+ ProgramDataBaseFileName=".\Release\doxygen\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/LTCG"
+ AdditionalDependencies="qtools.lib iconv.lib shell32.lib"
+ OutputFile="..\bin\Release\doxygen.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="Release"
+ ProgramDatabaseFile=".\Release\doxygen\$(TargetName).pdb"
+ SubSystem="1"
+ LargeAddressAware="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release\doxygen/Doxygen.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="..\bin\Release64"
+ IntermediateDirectory=".\Release64\doxygen"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="Gen_head"
+ />
+ <Tool
+ Name="Languages"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release64\doxygen\Doxygen.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/Zm200 "
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="..\src,..\qtools,..\libpng,..\libmd5,..\vhdlparser,$(IntDir),."
+ PreprocessorDefinitions="WIN32;_CINDEX_LIB_;_CINDEX_LIB_;NDEBUG;_CONSOLE; _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;LIBICONV_STATIC;CHARSET_STATIC"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release64\doxygen/Doxygen.pch"
+ AssemblerListingLocation=".\Release64\doxygen/"
+ ObjectFile=".\Release64\doxygen/"
+ ProgramDataBaseFileName=".\Release64\doxygen\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/LTCG"
+ AdditionalDependencies="qtools.lib iconv64.lib shell32.lib"
+ OutputFile="..\bin\Release64\doxygen.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="Release64"
+ ProgramDatabaseFile=".\Release64\doxygen\$(TargetName).pdb"
+ SubSystem="1"
+ LargeAddressAware="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release64\doxygen/Doxygen.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\src\arguments.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\ce_parse.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\CharStream.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cite.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\clangparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\classdef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\classlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cmdmapper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\commentcnv.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\commentscan.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\condparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\config.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\configoptions.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\constexp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\context.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cppvalue.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dbusxmlscanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\debug.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\declinfo.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\defargs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\defgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\define.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\definition.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dia.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\diagram.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dirdef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docbookgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docbookvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docsets.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\doctokenizer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dot.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\doxygen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\eclipsehelp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\entry.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\filedef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\filename.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\fileparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\formula.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\fortrancode.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\fortranscanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\ftextstream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\ftvhelp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\groupdef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htags.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmldocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlentity.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlhelp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\image.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\index.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\language.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\latexdocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\latexgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\layout.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\lodepng.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\logos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mandocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mangen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\markdown.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\marshal.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\libmd5\md5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\memberdef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\membergroup.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\memberlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\membername.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\message.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\msc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\namespacedef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\objcache.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\outputgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\outputlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pagedef.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\ParseException.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\perlmodgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\plantuml.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\portable.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\portable_c.c"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\pre.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\pycode.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\pyscanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\qhp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\qhpxmlwriter.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\reflist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfdocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfstyle.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\scanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\searchindex.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\sqlite3gen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\store.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tagreader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\tclscanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\template.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\textdocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\textdocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\Token.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\TokenMgrError.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tooltip.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\util.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\version.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\vhdldocgen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\vhdljjparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParser.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserIF.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserTokenManager.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\xmldocvisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\xmlgen.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Yacc Files"
+ Filter="y"
+ >
+ <File
+ RelativePath="..\src\constexp.y"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Running bison on constexp.y"
+ CommandLine="bison -l -d -p ce_parseexpYY "$(InputPath)" -o $(IntDir)\ce_parse.c
bison -l -p constexpYY "$(InputPath)" -o $(IntDir)\ce_parse.cpp
del $(IntDir)\ce_parse.c
"
+ Outputs="$(IntDir)\ce_parse.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Running bison on constexp.y"
+ CommandLine="bison -l -d -p ce_parseexpYY "$(InputPath)" -o $(IntDir)\ce_parse.c
bison -l -p constexpYY "$(InputPath)" -o $(IntDir)\ce_parse.cpp
del $(IntDir)\ce_parse.c
"
+ Outputs="$(IntDir)\ce_parse.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Running bison on constexp.y"
+ CommandLine="bison -l -d -p ce_parseexpYY "$(InputPath)" -o $(IntDir)\ce_parse.c
bison -l -p constexpYY "$(InputPath)" -o $(IntDir)\ce_parse.cpp
del $(IntDir)\ce_parse.c
"
+ Outputs="$(IntDir)\ce_parse.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Running bison on constexp.y"
+ CommandLine="bison -l -d -p ce_parseexpYY "$(InputPath)" -o $(IntDir)\ce_parse.c
bison -l -p constexpYY "$(InputPath)" -o $(IntDir)\ce_parse.cpp
del $(IntDir)\ce_parse.c
"
+ Outputs="$(IntDir)\ce_parse.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Lex Files"
+ Filter="l"
+ >
+ <File
+ RelativePath="..\src\code.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\commentcnv.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\commentscan.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\config.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\constexp.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\declinfo.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\defargs.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\doctokenizer.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\fortrancode.l"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\fortranscanner.l"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\pre.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pycode.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pyscanner.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\scanner.l"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tclscanner.l"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\vhdlcode.l"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Lex"
+ Case="true"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Python Files"
+ >
+ <File
+ RelativePath="..\src\lang_cfg.py"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Languages"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Languages"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Languages"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Languages"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\settings.py"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="unistd.py"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\version.py"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="XML Files"
+ Filter="xml"
+ >
+ <File
+ RelativePath="..\src\config.xml"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Config"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Config"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Config"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Config"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Generating header Files"
+ >
+ <File
+ RelativePath="..\src\bib2xhtml.pl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\compound.xsd"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\doxygen.bst"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\doxygen.css"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\doxygen.sty"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\dynsections.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\extsearch.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\footer.html"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\header.html"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\index.xsd"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_fx.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_p1.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_p2.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_p3.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_pt.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\jquery_ui.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\layout_default.xml"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\navtree.css"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\navtree.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\resize.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\search.css"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\search.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\search_functions.php"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\search_opensearch.php"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\svgpan.js"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Gen_head"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\src\arguments.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\bib2xhtml.pl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\bufstr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\ce_parse.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\CharStream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cite.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\clangparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\classdef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\classlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cmdmapper.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\code.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\commentcnv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\commentscan.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\compound_xsd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\condparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\constexp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\context.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cppvalue.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dbusxmlscanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\debug.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\declinfo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\defargs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\defgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\define.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\definition.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dia.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\diagram.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dirdef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docbookgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docbookvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docsets.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\doctokenizer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\docvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\dot.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\doxygen.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\doxygen_bst.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\doxygen_css.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\doxygen_sty.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\dynsections_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\eclipsehelp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\entry.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\ErrorHandler.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\example.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\extsearch_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\filedef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\filename.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\fileparser.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\footer_html.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\formula.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\fortrancode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\fortranscanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\ftextstream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\ftvhelp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\groupdef.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\header_html.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlattrib.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmldocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlentity.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\htmlhelp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\iconv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\image.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\index.h"
+ >
+ </File>
+ <File
+ RelativePath="$(INtDir)\index_xsd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\instdox.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\JavaCC.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_fx_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_p1_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_p2_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_p3_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_pt_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\jquery_ui_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\lang_cfg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\language.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\latexdocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\latexgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\layout.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\layout_default_xml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\lockingptr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\lodepng.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\logos.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mandocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mangen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\marshal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\libmd5\md5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\libmd5\md5_loc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\memberdef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\membergroup.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\memberlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\membername.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\message.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\msc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\namespacedef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\navtree_css.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\navtree_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\objcache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\outputgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\outputlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pagedef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\ParseException.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\parserintf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\perlmodgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\plantuml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\portable.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pre.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\printdocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pycode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pyscanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\qhp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\qhpxmlwriter.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\qtbc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\reflist.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\resize_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfdocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtfstyle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\scanner.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\search_css.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\search_js.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\search_functionsjs.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\search_opensearch_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\searchindex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\section.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\settings.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\sortdict.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\svgpan_js.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\store.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tagreader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tclscanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\template.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\Token.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\TokenManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\TokenMgrError.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tooltip.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_adapter.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_am.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ar.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_br.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ca.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_cn.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_cz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_de.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_dk.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_en.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_eo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_es.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_fa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_fi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_fr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_gr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_hr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_hu.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_id.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_it.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_je.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_jp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ke.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_kr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_lt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_lv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_mk.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_nl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_no.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_pl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_pt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ro.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ru.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_sc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_si.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_sk.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_sr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_sv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_tr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_tw.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_ua.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_vi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\translator_za.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\unistd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\version.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\vhdlcode.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\vhdlcode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\vhdldocgen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\vhdljjparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\vhdlparser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserConstants.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserErrorHandler.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserIF.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\VhdlParserTokenManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\vhdlparser\vhdlstring.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\xmldocvisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\xmlgen.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/Doxywizard.vcproj b/winbuild/Doxywizard.vcproj
new file mode 100755
index 0000000..c424dc6
--- /dev/null
+++ b/winbuild/Doxywizard.vcproj
@@ -0,0 +1,718 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="doxywizard"
+ ProjectGUID="{77C9C2D3-EA3F-3D59-8B4C-0ED852890172}"
+ Keyword="Qt4VSv1.0"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ <ToolFile
+ RelativePath=".\Lex.rules"
+ />
+ <ToolFile
+ RelativePath=".\Version.rules"
+ />
+ <ToolFile
+ RelativePath=".\Settings.rules"
+ />
+ <ToolFile
+ RelativePath=".\Unistd.rules"
+ />
+ <ToolFile
+ RelativePath=".\Config.rules"
+ />
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\Debug"
+ IntermediateDirectory=".\Debug\doxywizard"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ WarningLevel="0"
+ DefaultCharType="0"
+ EnableErrorChecks="1"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="-Zm200 -w34100 -w34189 -Zm200 -w34100 -w34189 -w34100 -w34189"
+ Optimization="4"
+ AdditionalIncludeDirectories="$(IntDir);"$(QT_DIR)\include\QtCore","$(QT_DIR)\include\QtCore","$(QT_DIR)\include\QtGui","$(QT_DIR)\include\QtGui","$(QT_DIR)\include\QtXml","$(QT_DIR)\include\QtXml","$(QT_DIR)\include","..\addon\doxywizard","$(QT_DIR)\include\ActiveQt","moc","..\addon\doxywizard",".",$(QT_DIR)\mkspecs\win32-msvc2008"
+ PreprocessorDefinitions="_WINDOWS,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_NO_CAST_FROM_ASCII,QT_NO_CAST_TO_ASCII,QT_XML_LIB,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT"
+ GeneratePreprocessedFile="0"
+ ExceptionHandling="1"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ TreatWChar_tAsBuiltInType="false"
+ RuntimeTypeInfo="true"
+ AssemblerListingLocation="Debug\doxywizard\"
+ ObjectFile="Debug\doxywizard\"
+ ProgramDataBaseFileName=".\Debug\doxywizard\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_WINDOWS,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_NO_CAST_FROM_ASCII,QT_NO_CAST_TO_ASCII,QT_XML_LIB,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT,_DEBUG"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalOptions=""/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'""
+ AdditionalDependencies="$(QT_DIR)\lib\qtmaind.lib $(QT_DIR)\lib\QtXmld.lib $(QT_DIR)\lib\QtGuid.lib $(QT_DIR)\lib\QtCored.lib kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib msimg32.lib"
+ OutputFile="..\bin\Debug\doxywizard.exe"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="$(QT_DIR)\lib"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug\doxywizard\$(TargetName).pdb"
+ SubSystem="2"
+ LargeAddressAware="2"
+ LinkTimeCodeGeneration="0"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\Release"
+ IntermediateDirectory=".\Release\doxywizard"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="Lex"
+ />
+ <Tool
+ Name="Config"
+ />
+ <Tool
+ Name="Config_dw"
+ />
+ <Tool
+ Name="Settings"
+ />
+ <Tool
+ Name="Unistd"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ WarningLevel="0"
+ DefaultCharType="0"
+ EnableErrorChecks="1"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="-Zm200 -w34100 -w34189 -Zm200 -w34100 -w34189 -w34100 -w34189"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(IntDir);"$(QT_DIR)\include\QtCore","$(QT_DIR)\include\QtCore","$(QT_DIR)\include\QtGui","$(QT_DIR)\include\QtGui","$(QT_DIR)\include\QtXml","$(QT_DIR)\include\QtXml","$(QT_DIR)\include","..\addon\doxywizard","$(QT_DIR)\include\ActiveQt","moc","..\addon\doxywizard",".",$(QT_DIR)\mkspecs\win32-msvc2008"
+ PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,_WINDOWS,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_NO_CAST_FROM_ASCII,QT_NO_CAST_TO_ASCII,QT_NO_DEBUG,QT_XML_LIB,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT,NDEBUG"
+ GeneratePreprocessedFile="0"
+ ExceptionHandling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ TreatWChar_tAsBuiltInType="false"
+ RuntimeTypeInfo="true"
+ AssemblerListingLocation="Release\doxywizard\"
+ ObjectFile="Release\doxywizard\"
+ ProgramDataBaseFileName=".\Release\doxywizard\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,_WINDOWS,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_NO_CAST_FROM_ASCII,QT_NO_CAST_TO_ASCII,QT_NO_DEBUG,QT_XML_LIB,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalOptions=""/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'""
+ AdditionalDependencies="$(QT_DIR)\lib\qtmain.lib $(QT_DIR)\lib\QtXml.lib $(QT_DIR)\lib\QtGui.lib $(QT_DIR)\lib\QtCore.lib kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib msimg32.lib"
+ OutputFile="..\bin\Release\doxywizard.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="$(QT_DIR)\lib"
+ IgnoreAllDefaultLibraries="false"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="false"
+ ProgramDatabaseFile=".\Release\doxywizard\$(TargetName).pdb"
+ SubSystem="2"
+ LargeAddressAware="2"
+ LinkTimeCodeGeneration="0"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\addon\doxywizard\doxywizard.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\expert.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputbool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputint.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputstring.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputstrlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\version.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\wizard.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\addon\doxywizard\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\doxywizard.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\doxywizard.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\doxywizard.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_doxywizard.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\doxywizard.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\doxywizard.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_doxywizard.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\expert.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\expert.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\expert.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_expert.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\expert.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\expert.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_expert.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\helplabel.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\helplabel.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\helplabel.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_helplabel.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\helplabel.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\helplabel.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_helplabel.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputbool.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputbool.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\inputbool.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputbool.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputbool.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\inputbool.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputbool.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputint.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputint.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\inputint.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputint.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputint.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\inputint.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputint.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputstring.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputstring.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\inputstring.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputstring.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputstring.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\inputstring.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputstring.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\inputstrlist.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputstrlist.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\inputstrlist.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputstrlist.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\inputstrlist.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\inputstrlist.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_inputstrlist.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\wizard.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\wizard.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard" -I" [...]
+ AdditionalDependencies="..\addon\doxywizard\wizard.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_wizard.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC ..\addon\doxywizard\wizard.h"
+ CommandLine="$(QT_DIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtCore" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtGui" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include\QtXml" -I"$(QT_DIR)\include" -I"..\addon\doxywizard [...]
+ AdditionalDependencies="..\addon\doxywizard\wizard.h;$(QT_DIR)\bin\moc.exe"
+ Outputs="$(IntDir)\moc\moc_wizard.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Generated Files"
+ Filter="cpp;c;cxx;moc;h;def;odl;idl;res;"
+ UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
+ >
+ <File
+ RelativePath="$(IntDir)\config_doxyw.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\configdoc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_doxywizard.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_expert.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_helplabel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_inputbool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_inputint.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_inputstring.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_inputstrlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\moc\moc_wizard.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\rcc\qrc_doxywizard.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Lex Files"
+ Filter="l"
+ UniqueIdentifier="{E12AE0D2-192F-4d59-BD23-7D3FA58D3183}"
+ ParseFiles="false"
+ >
+ <File
+ RelativePath="..\addon\doxywizard\config_doxyw.l"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Python Files"
+ Filter="py"
+ >
+ <File
+ RelativePath="..\src\settings.py"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Settings"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="unistd.py"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Unistd"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\version.py"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="Version"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="XML Files"
+ Filter="xml"
+ >
+ <File
+ RelativePath="..\src\config.xml"
+ >
+ <FileConfiguration
+ Name="Debug|win32"
+ >
+ <Tool
+ Name="Config_dw"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|win32"
+ >
+ <Tool
+ Name="Config_dw"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="Config_dw"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="Config_dw"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="qrc;*"
+ UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
+ ParseFiles="false"
+ >
+ <File
+ RelativePath="..\addon\doxywizard\doxywizard.qrc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="RCC ..\addon\doxywizard\doxywizard.qrc"
+ CommandLine="$(QT_DIR)\bin\rcc.exe -name doxywizard ..\addon\doxywizard\doxywizard.qrc -o $(IntDir)\rcc\qrc_doxywizard.cpp
"
+ AdditionalDependencies="..\addon\doxywizard\doxywizard.qrc;$(QT_DIR)\bin\rcc.exe"
+ Outputs="$(IntDir)\rcc\qrc_doxywizard.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="RCC ..\addon\doxywizard\doxywizard.qrc"
+ CommandLine="$(QT_DIR)\bin\rcc.exe -name doxywizard ..\addon\doxywizard\doxywizard.qrc -o $(IntDir)\rcc\qrc_doxywizard.cpp
"
+ AdditionalDependencies="..\addon\doxywizard\doxywizard.qrc;$(QT_DIR)\bin\rcc.exe"
+ Outputs="$(IntDir)\rcc\qrc_doxywizard.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\addon\doxywizard\doxywizard.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/Gen_head.rules b/winbuild/Gen_head.rules
new file mode 100644
index 0000000..c2e7550
--- /dev/null
+++ b/winbuild/Gen_head.rules
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="gen_head"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Gen_head"
+ DisplayName="Gen_head"
+ CommandLine="python "$(ProjectDir)..\src\to_c_cmd.py" [AllOptions] [AdditionalOptions] [inputs] < "$(InputPath)" > $(IntDir)/$(InputName)$(InputExt).h"
+ Outputs="$(IntDir)/$(InputName)$(InputExt).h"
+ FileExtensions=".*"
+ AdditionalDependencies="$(ProjectDir)..\src\to_c_cmd.py"
+ ExecutionDescription="Executing to_c_cmd on $(InputPath) ..."
+ ShowOnlyRuleProperties="false"
+ >
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/Languages.rules b/winbuild/Languages.rules
new file mode 100755
index 0000000..8ff018a
--- /dev/null
+++ b/winbuild/Languages.rules
@@ -0,0 +1,862 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="languages"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Languages"
+ DisplayName="Languages"
+ CommandLine="python "$(InputPath)" [AllOptions] [AdditionalOptions] > $(IntDir)/$(InputName).h"
+ Outputs="$(IntDir)/$(InputName).h"
+ FileExtensions="*.py"
+ AdditionalDependencies=""
+ ExecutionDescription="Executing languages ..."
+ ShowOnlyRuleProperties="false"
+ >
+ <Properties>
+ <EnumProperty
+ Name="EnglishOnlys"
+ DisplayName="Use English Only"
+ Description="Use English Only"
+ DefaultValue="0"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use English Only"
+ />
+ <EnumValue
+ Value="1"
+ Switch="ENONLY"
+ DisplayName="Use English Only"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="armenian"
+ DisplayName="Use Armenian"
+ Description="Use Armenian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Armenian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="AM"
+ DisplayName="Use Armenian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="arabic"
+ DisplayName="Use Arabic"
+ Description="Use Arabic"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Arabic"
+ />
+ <EnumValue
+ Value="1"
+ Switch="AR"
+ DisplayName="Use Arabic"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="brazilian"
+ DisplayName="Use Brazilian"
+ Description="Use Brazilian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Brazilian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="BR"
+ DisplayName="Use Brazilian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="catalan"
+ DisplayName="Use Catalan"
+ Description="Use Catalan"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Catalan"
+ />
+ <EnumValue
+ Value="1"
+ Switch="CA"
+ DisplayName="Use Catalan"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="chinese"
+ DisplayName="Use Chinese"
+ Description="Use Chinese"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Chinese"
+ />
+ <EnumValue
+ Value="1"
+ Switch="CN"
+ DisplayName="Use Chinese"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="czech"
+ DisplayName="Use Czech"
+ Description="Use Czech"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Czech"
+ />
+ <EnumValue
+ Value="1"
+ Switch="CZ"
+ DisplayName="Use Czech"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="german"
+ DisplayName="Use German"
+ Description="Use German"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use German"
+ />
+ <EnumValue
+ Value="1"
+ Switch="DE"
+ DisplayName="Use German"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="danish"
+ DisplayName="Use Danish"
+ Description="Use Danish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Danish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="DK"
+ DisplayName="Use Danish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="esperanto"
+ DisplayName="Use Esperanto"
+ Description="Use Esperanto"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Esperanto"
+ />
+ <EnumValue
+ Value="1"
+ Switch="EO"
+ DisplayName="Use Esperanto"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="spanish"
+ DisplayName="Use Spanish"
+ Description="Use Spanish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Spanish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="ES"
+ DisplayName="Use Spanish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="persian"
+ DisplayName="Use Persian"
+ Description="Use Persian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Persian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="FA"
+ DisplayName="Use Persian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="finnish"
+ DisplayName="Use Finnish"
+ Description="Use Finnish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Finnish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="FI"
+ DisplayName="Use Finnish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="french"
+ DisplayName="Use French"
+ Description="Use French"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use French"
+ />
+ <EnumValue
+ Value="1"
+ Switch="FR"
+ DisplayName="Use French"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="greek"
+ DisplayName="Use Greek"
+ Description="Use Greek"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Greek"
+ />
+ <EnumValue
+ Value="1"
+ Switch="GR"
+ DisplayName="Use Greek"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="croatian"
+ DisplayName="Use Croatian"
+ Description="Use Croatian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Croatian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="HR"
+ DisplayName="Use Croatian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="hungarian"
+ DisplayName="Use Hungarian"
+ Description="Use Hungarian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Hungarian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="HU"
+ DisplayName="Use Hungarian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="indonesian"
+ DisplayName="Use Indonesian"
+ Description="Use Indonesian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Indonesian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="ID"
+ DisplayName="Use Indonesian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="italian"
+ DisplayName="Use Italian"
+ Description="Use Italian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Italian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="IT"
+ DisplayName="Use Italian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="japaneseen"
+ DisplayName="Use Japanese-En"
+ Description="Use Japanese-En"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Japanese-En"
+ />
+ <EnumValue
+ Value="1"
+ Switch="JE"
+ DisplayName="Use Japanese-En"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="japanese"
+ DisplayName="Use Japanese"
+ Description="Use Japanese"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Japanese"
+ />
+ <EnumValue
+ Value="1"
+ Switch="JP"
+ DisplayName="Use Japanese"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="koreanen"
+ DisplayName="Use Korean-En"
+ Description="Use Korean-En"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Korean-En"
+ />
+ <EnumValue
+ Value="1"
+ Switch="KE"
+ DisplayName="Use Korean-En"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="korean"
+ DisplayName="Use Korean"
+ Description="Use Korean"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Korean"
+ />
+ <EnumValue
+ Value="1"
+ Switch="KR"
+ DisplayName="Use Korean"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="lithuanian"
+ DisplayName="Use Lithuanian"
+ Description="Use Lithuanian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Lithuanian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="LT"
+ DisplayName="Use Lithuanian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="latvian"
+ DisplayName="Use Latvian"
+ Description="Use Latvian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Latvian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="LV"
+ DisplayName="Use Latvian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="macedonian"
+ DisplayName="Use Macedonian"
+ Description="Use Macedonian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Macedonian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="MK"
+ DisplayName="Use Macedonian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="dutch"
+ DisplayName="Use Dutch"
+ Description="Use Dutch"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Dutch"
+ />
+ <EnumValue
+ Value="1"
+ Switch="NL"
+ DisplayName="Use Dutch"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="norwegian"
+ DisplayName="Use Norwegian"
+ Description="Use Norwegian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Norwegian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="NO"
+ DisplayName="Use Norwegian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="polish"
+ DisplayName="Use Polish"
+ Description="Use Polish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Polish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="PL"
+ DisplayName="Use Polish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="portuguese"
+ DisplayName="Use Portuguese"
+ Description="Use Portuguese"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Portuguese"
+ />
+ <EnumValue
+ Value="1"
+ Switch="PT"
+ DisplayName="Use Portuguese"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="romanian"
+ DisplayName="Use Romanian"
+ Description="Use Romanian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Romanian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="RO"
+ DisplayName="Use Romanian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="russian"
+ DisplayName="Use Russian"
+ Description="Use Russian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Russian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="RU"
+ DisplayName="Use Russian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="serbiancyrillic"
+ DisplayName="Use Serbian-Cyrillic"
+ Description="Use Serbian-Cyrillic"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Serbian-Cyrillic"
+ />
+ <EnumValue
+ Value="1"
+ Switch="SC"
+ DisplayName="Use Serbian-Cyrillic"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="slovene"
+ DisplayName="Use Slovene"
+ Description="Use Slovene"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Slovene"
+ />
+ <EnumValue
+ Value="1"
+ Switch="SI"
+ DisplayName="Use Slovene"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="slovak"
+ DisplayName="Use Slovak"
+ Description="Use Slovak"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Slovak"
+ />
+ <EnumValue
+ Value="1"
+ Switch="SK"
+ DisplayName="Use Slovak"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="serbian"
+ DisplayName="Use Serbian"
+ Description="Use Serbian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Serbian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="SR"
+ DisplayName="Use Serbian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="swedish"
+ DisplayName="Use Swedish"
+ Description="Use Swedish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Swedish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="SV"
+ DisplayName="Use Swedish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="turkish"
+ DisplayName="Use Turkish"
+ Description="Use Turkish"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Turkish"
+ />
+ <EnumValue
+ Value="1"
+ Switch="TR"
+ DisplayName="Use Turkish"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="chinesetraditional"
+ DisplayName="Use Chinese-Traditional"
+ Description="Use Chinese-Traditional"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Chinese-Traditional"
+ />
+ <EnumValue
+ Value="1"
+ Switch="TW"
+ DisplayName="Use Chinese-Traditional"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="ukrainian"
+ DisplayName="Use Ukrainian"
+ Description="Use Ukrainian"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Ukrainian"
+ />
+ <EnumValue
+ Value="1"
+ Switch="UA"
+ DisplayName="Use Ukrainian"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="vietnamese"
+ DisplayName="Use Vietnamese"
+ Description="Use Vietnamese"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Vietnamese"
+ />
+ <EnumValue
+ Value="1"
+ Switch="VI"
+ DisplayName="Use Vietnamese"
+ />
+ </Values>
+ </EnumProperty>
+
+ <EnumProperty
+ Name="afrikaans"
+ DisplayName="Use Afrikaans"
+ Description="Use Afrikaans"
+ DefaultValue="1"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch=""
+ DisplayName="Don't use Afrikaans"
+ />
+ <EnumValue
+ Value="1"
+ Switch="ZA"
+ DisplayName="Use Afrikaans"
+ />
+ </Values>
+ </EnumProperty>
+
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
+
diff --git a/winbuild/Lex.rules b/winbuild/Lex.rules
new file mode 100644
index 0000000..52df322
--- /dev/null
+++ b/winbuild/Lex.rules
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="flex"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Lex"
+ DisplayName="Lex"
+ CommandLine="flex [AllOptions] -t -P$(InputName)YY [AdditionalOptions] [inputs] | python "$(ProjectDir)..\src\increasebuffer.py" > $(IntDir)/$(InputName).cpp"
+ Outputs="$(IntDir)/$(InputName).cpp"
+ FileExtensions="*.l"
+ AdditionalDependencies="$(ProjectDir)..\src\increasebuffer.py"
+ ExecutionDescription="Executing Lex for $(InputPath) ..."
+ ShowOnlyRuleProperties="false"
+ >
+ <Properties>
+ <BooleanProperty
+ Name="Case"
+ DisplayName="Case insensitive"
+ Description="case insensitive"
+ Switch="-i"
+ IsReadOnly="true"
+ />
+ <BooleanProperty
+ Name="Rules"
+ DisplayName="Write used lex rules"
+ Description="Write used lex rules"
+ Switch="-d"
+ />
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/Settings.rules b/winbuild/Settings.rules
new file mode 100644
index 0000000..29e7266
--- /dev/null
+++ b/winbuild/Settings.rules
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="settings"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Settings"
+ DisplayName="Settings"
+ CommandLine="python "$(InputPath)" [AllOptions] [AdditionalOptions] $(IntDir)"
+ Outputs="$(IntDir)/$(InputName).h"
+ FileExtensions="*.py"
+ AdditionalDependencies="$(ProjectDir)..\configure"
+ ExecutionDescription="Executing Settings ..."
+ ShowOnlyRuleProperties="false"
+ >
+ <Properties>
+ <EnumProperty
+ Name="SqlLite3"
+ DisplayName="Use SqlLite3"
+ Description="Use SqlLite3"
+ DefaultValue="0"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch="NO"
+ DisplayName="Don't use SqlLite3"
+ />
+ <EnumValue
+ Value="1"
+ Switch="YES"
+ DisplayName="Use SqlLite3"
+ />
+ </Values>
+ </EnumProperty>
+ <EnumProperty
+ Name="CLANG"
+ DisplayName="Use CLANG"
+ Description="Use CLANG"
+ DefaultValue="0"
+ >
+ <Values>
+ <EnumValue
+ Value="0"
+ Switch="NO"
+ DisplayName="Don't use CLANG"
+ />
+ <EnumValue
+ Value="1"
+ Switch="YES"
+ DisplayName="Use CLANG"
+ />
+ </Values>
+ </EnumProperty>
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/Unistd.rules b/winbuild/Unistd.rules
new file mode 100755
index 0000000..bd25661
--- /dev/null
+++ b/winbuild/Unistd.rules
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="unistd"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Unistd"
+ DisplayName="Unistd"
+ CommandLine="python "$(InputPath)" [AllOptions] [AdditionalOptions] $(IntDir)"
+ Outputs="$(IntDir)/$(InputName).h"
+ FileExtensions="*.py"
+ ExecutionDescription="Executing Unistd ..."
+ ShowOnlyRuleProperties="false"
+ >
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/Version.rules b/winbuild/Version.rules
new file mode 100644
index 0000000..3dfdf04
--- /dev/null
+++ b/winbuild/Version.rules
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="version"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="Version"
+ DisplayName="Version"
+ CommandLine="python "$(InputPath)" $(IntDir)"
+ Outputs="$(IntDir)\$(InputName).cpp"
+ FileExtensions="*.py"
+ AdditionalDependencies="$(ProjectDir)..\configure"
+ ExecutionDescription="Executing Version ..."
+ ShowOnlyRuleProperties="false"
+ >
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/doxyindexer.vcproj b/winbuild/doxyindexer.vcproj
new file mode 100644
index 0000000..499741f
--- /dev/null
+++ b/winbuild/doxyindexer.vcproj
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="doxyindexer"
+ ProjectGUID="{E543983A-D5BF-4865-B4A1-6D7EF2E1051C}"
+ RootNamespace="doxyindexer"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\Debug"
+ IntermediateDirectory=".\Debug\doxyindexer"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include",..\qtools"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ ProgramDatabaseFileName=".\Debug\doxyindexer\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Debug\doxyindexer.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Debug";Debug"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug\doxyindexer\$(TargetName).pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="..\bin\Debug64"
+ IntermediateDirectory=".\Debug64\doxyindexer"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include",..\qtools"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Debug64\doxyindexer\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Debug64\doxyindexer.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Debug64";Debug64"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug64\doxyindexer\$(TargetName).pdb"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\Release"
+ IntermediateDirectory=".\Release\doxyindexer"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include",..\qtools"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Release\doxyindexer\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Release\doxyindexer.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Release";Release"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release\doxyindexer\$(TargetName).pdb"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="..\bin\Release64"
+ IntermediateDirectory=".\Release64\doxyindexer"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include",..\qtools"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Release64\doxyindexer\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtools.lib xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Release64\doxyindexer.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Release64";Release64"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release64\doxyindexer\$(TargetName).pdb"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\addon\doxysearch\doxyindexer.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/doxysearch.vcproj b/winbuild/doxysearch.vcproj
new file mode 100644
index 0000000..a21168c
--- /dev/null
+++ b/winbuild/doxysearch.vcproj
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="doxysearch"
+ ProjectGUID="{F3F3408F-F6F7-46C7-BF1E-1FA056E0AE20}"
+ RootNamespace="doxysearch"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\Debug"
+ IntermediateDirectory=".\Debug\doxysearch"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include""
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ ProgramDatabaseFileName=".\Debug\doxysearch\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Debug\doxysearch.cgi"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Debug""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug\doxysearch\$(TargetName).pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="..\bin\Debug64"
+ IntermediateDirectory=".\Debug64\doxysearch"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include""
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Debug64\doxysearch\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Debug64\doxysearch.cgi"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Debug64""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug64\doxysearch\$(TargetName).pdb"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\Release"
+ IntermediateDirectory=".\Release\doxysearch"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include""
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Release\doxysearch\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Release\doxysearch.cgi"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Release""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release\doxysearch\$(TargetName).pdb"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="..\bin\Release64"
+ IntermediateDirectory=".\Release64\doxysearch"
+ ConfigurationType="1"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=""$(XAPIAN_DIR)\include""
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ ProgramDatabaseFileName=".\Release64\doxysearch\$(TargetName).pdb"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="xapian.lib uuid.lib rpcrt4.lib ws2_32.lib"
+ OutputFile="..\bin\Release64\doxysearch.cgi"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""$(XAPIAN_DIR)\Release64""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release64\doxysearch\$(TargetName).pdb"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\addon\doxysearch\doxysearch.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/iconv.h b/winbuild/iconv.h
new file mode 100644
index 0000000..0cc3f0c
--- /dev/null
+++ b/winbuild/iconv.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 1999-2003 Free Software Foundation, Inc.
+ This file is part of the GNU LIBICONV Library.
+
+ The GNU LIBICONV Library is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ The GNU LIBICONV Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU LIBICONV Library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation, Inc., 59 Temple Place -
+ Suite 330, Boston, MA 02111-1307, USA. */
+
+/* When installed, this file is called "iconv.h". */
+
+#ifndef _LIBICONV_H
+#define _LIBICONV_H
+
+#define _LIBICONV_VERSION 0x0109 /* version number: (major<<8) + minor */
+
+#ifdef LIBICONV_STATIC
+#define LIBICONV_DLL_EXPORTED
+#else /* LIBICONV_STATIC */
+#ifdef BUILDING_LIBICONV
+#define LIBICONV_DLL_EXPORTED __declspec(dllexport)
+#else
+#define LIBICONV_DLL_EXPORTED __declspec(dllimport)
+#endif
+#endif /* LIBICONV_STATIC */
+extern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */
+
+/* We would like to #include any system header file which could define
+ iconv_t, 1. in order to eliminate the risk that the user gets compilation
+ errors because some other system header file includes /usr/include/iconv.h
+ which defines iconv_t or declares iconv after this file, 2. when compiling
+ for LIBICONV_PLUG, we need the proper iconv_t type in order to produce
+ binary compatible code.
+ But gcc's #include_next is not portable. Thus, once libiconv's iconv.h
+ has been installed in /usr/local/include, there is no way any more to
+ include the original /usr/include/iconv.h. We simply have to get away
+ without it.
+ Ad 1. The risk that a system header file does
+ #include "iconv.h" or #include_next "iconv.h"
+ is small. They all do #include <iconv.h>.
+ Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It
+ has to be a scalar type because (iconv_t)(-1) is a possible return value
+ from iconv_open().) */
+
+/* Define iconv_t ourselves. */
+#undef iconv_t
+#define iconv_t libiconv_t
+typedef void* iconv_t;
+
+/* Get size_t declaration. */
+#include <stddef.h>
+
+/* Get errno declaration and values. */
+#include <errno.h>
+/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS,
+ have EILSEQ in a different header. On these systems, define EILSEQ
+ ourselves. */
+#ifndef EILSEQ
+#define EILSEQ
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Allocates descriptor for code conversion from encoding `fromcode' to
+ encoding `tocode'. */
+#ifndef LIBICONV_PLUG
+#define iconv_open libiconv_open
+#endif
+extern LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode);
+
+/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes
+ starting at `*inbuf', writing at most `*outbytesleft' bytes starting at
+ `*outbuf'.
+ Decrements `*inbytesleft' and increments `*inbuf' by the same amount.
+ Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */
+#ifndef LIBICONV_PLUG
+#define iconv libiconv
+#endif
+extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
+
+/* Frees resources allocated for conversion descriptor `cd'. */
+#ifndef LIBICONV_PLUG
+#define iconv_close libiconv_close
+#endif
+extern LIBICONV_DLL_EXPORTED int iconv_close (iconv_t cd);
+
+
+#ifndef LIBICONV_PLUG
+
+/* Nonstandard extensions. */
+
+/* Control of attributes. */
+#define iconvctl libiconvctl
+extern LIBICONV_DLL_EXPORTED int iconvctl (iconv_t cd, int request, void* argument);
+
+/* Requests for iconvctl. */
+#define ICONV_TRIVIALP 0 /* int *argument */
+#define ICONV_GET_TRANSLITERATE 1 /* int *argument */
+#define ICONV_SET_TRANSLITERATE 2 /* const int *argument */
+#define ICONV_GET_DISCARD_ILSEQ 3 /* int *argument */
+#define ICONV_SET_DISCARD_ILSEQ 4 /* const int *argument */
+
+/* Listing of locale independent encodings. */
+#define iconvlist libiconvlist
+extern LIBICONV_DLL_EXPORTED void iconvlist (int (*do_one) (unsigned int namescount,
+ const char * const * names,
+ void* data),
+ void* data);
+
+/* Support for relocatable packages. */
+
+/* Sets the original and the current installation prefix of the package.
+ Relocation simply replaces a pathname starting with the original prefix
+ by the corresponding pathname with the current prefix instead. Both
+ prefixes should be directory names without trailing slash (i.e. use ""
+ instead of "/"). */
+extern LIBICONV_DLL_EXPORTED void libiconv_set_relocation_prefix (const char *orig_prefix,
+ const char *curr_prefix);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LIBICONV_H */
diff --git a/winbuild/iconv.lib b/winbuild/iconv.lib
new file mode 100644
index 0000000..1407333
Binary files /dev/null and b/winbuild/iconv.lib differ
diff --git a/winbuild/iconv.vcproj b/winbuild/iconv.vcproj
new file mode 100644
index 0000000..1d50d39
--- /dev/null
+++ b/winbuild/iconv.vcproj
@@ -0,0 +1,468 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="iconv"
+ ProjectGUID="{B6BB4771-8A4E-4656-AC08-1EF8AC182F69}"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="iconv/windows;iconv/include;iconv/libcharset/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0;LIBCHARSET_STATIC;HAVE_STRING_H;"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/iconv.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\iconv.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/iconv.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory=".\Release64"
+ IntermediateDirectory=".\Release64"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="iconv/windows;iconv/include;iconv/libcharset/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0;LIBCHARSET_STATIC;HAVE_STRING_H;"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release64/iconv.pch"
+ AssemblerListingLocation=".\Release64/"
+ ObjectFile=".\Release64/"
+ ProgramDataBaseFileName=".\Release64/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\iconv64.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release64/iconv.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="iconv\lib\iconv.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="iconv\libcharset\lib\localcharset.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="iconv"
+ ProjectGUID="{B6BB4771-8A4E-4656-AC08-1EF8AC182F69}"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="iconv/windows;iconv/include;iconv/libcharset/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0;LIBCHARSET_STATIC;HAVE_STRING_H;"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/iconv.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\iconv.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/iconv.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory=".\Release64"
+ IntermediateDirectory=".\Release64"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="iconv/windows;iconv/include;iconv/libcharset/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0;LIBCHARSET_STATIC;HAVE_STRING_H;"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release64/iconv.pch"
+ AssemblerListingLocation=".\Release64/"
+ ObjectFile=".\Release64/"
+ ProgramDataBaseFileName=".\Release64/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\iconv64.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release64/iconv.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="iconv\lib\iconv.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="iconv\libcharset\lib\localcharset.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/iconv64.lib b/winbuild/iconv64.lib
new file mode 100644
index 0000000..a1afc1c
Binary files /dev/null and b/winbuild/iconv64.lib differ
diff --git a/winbuild/moc.rules b/winbuild/moc.rules
new file mode 100644
index 0000000..efe0f7f
--- /dev/null
+++ b/winbuild/moc.rules
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualStudioToolFile
+ Name="Run Moc"
+ Version="8.00"
+ >
+ <Rules>
+ <CustomBuildRule
+ Name="moc"
+ DisplayName="Moc"
+ CommandLine="$(QTDIR)/bin/moc.exe "$(InputPath)" -o moc_$(InputName).cpp"
+ Outputs="moc_$(InputName).cpp"
+ AdditionalDependencies="$(QTDIR)/bin/moc.exe"
+ FileExtensions="*.h"
+ ExecutionDescription="Moc'ing $(InputPath)"
+ >
+ <Properties>
+ </Properties>
+ </CustomBuildRule>
+ </Rules>
+</VisualStudioToolFile>
diff --git a/winbuild/pack_the_distribution_for_windows.py b/winbuild/pack_the_distribution_for_windows.py
new file mode 100644
index 0000000..dc2c3d9
--- /dev/null
+++ b/winbuild/pack_the_distribution_for_windows.py
@@ -0,0 +1,234 @@
+#!python2
+
+from __future__ import print_function
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+import textwrap
+
+
+def gitSHA_date_time():
+ cmd = 'git rev-parse --short HEAD'
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ output = p.communicate()[0]
+ output = output.decode('ASCII')
+ p.wait()
+ sha = output.strip()
+
+ cmd = 'git show -s --format="%ci" ' + sha
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ output = p.communicate()[0]
+ output = output.decode('ASCII')
+ p.wait()
+ date = output.strip()
+ lst = date.split() # string like '2013-06-21 09:23:47 +0200'
+ dstamp = lst[0].replace('-', '') # '20130621' for the date
+ tstamp = lst[1].replace(':', '') # '092347' for the time
+
+ return sha, dstamp, tstamp
+
+
+def getDoxygenVersion():
+ # ... from the VERSION file.
+ sdir, fname = getThisScriptPathAndName()
+ version_fname = os.path.join(sdir, '..', 'VERSION')
+
+ with open(version_fname) as f:
+ lst = f.readlines()
+
+ doxver = lst[0].strip()
+
+ m = re.match(r'^(?P<ver>[0-9.]+)(-(?P<date>\d{8}))?', doxver)
+ assert m
+ ver = m.group('ver')
+ return ver
+
+
+def getThisScriptPathAndName():
+ script_fname = os.path.realpath(__file__)
+ sdir, fname = os.path.split(script_fname)
+ return sdir, fname
+
+
+def getEmptyDistribDir():
+ # Get this script full path, name, and the script subdir name
+ # (for checking the location).
+ sdir, fname = getThisScriptPathAndName()
+ subdir = os.path.basename(sdir)
+ assert subdir == 'winbuild'
+
+ # The distribution directory will be a subdirectory of the "../__put"
+ # (created if it does not exist, not the part of the git repo).
+ target_dir = os.path.normpath(os.path.join(sdir, '..', '__put'))
+ if not os.path.exists(target_dir):
+ os.mkdir(target_dir)
+ assert os.path.isdir(target_dir)
+
+ # The distribution subdir is composed out of 'Doxygen-', version stamp,
+ # timestamp, and commit id (partial SHA). Ignore the date from the VERSION
+ # file, take the commit date.
+ ver = getDoxygenVersion()
+ sha, dstamp, tstamp = gitSHA_date_time()
+ dist_subdir = 'Doxygen-' + ver + '-' + dstamp + tstamp
+ dist_dir = os.path.join(target_dir, dist_subdir)
+ print(dist_dir)
+ if os.path.isdir(dist_dir):
+ print("Removing the existing '{}'".format(dist_dir))
+ shutil.rmtree(dist_dir)
+ assert not os.path.exists(dist_dir)
+ print("Creating the new '{}'".format(dist_dir))
+ os.mkdir(dist_dir)
+ assert os.path.isdir(dist_dir)
+
+ return dist_dir
+
+
+def copyBinaries(dist_dir, subdir):
+ '''Copy the Windows binaries (doxygen.exe only) to the dist_dir directory.'''
+
+ # Source file should exist.
+ sdir, fname = getThisScriptPathAndName()
+ src = os.path.normpath(os.path.join(sdir, '..', 'bin', subdir, 'doxygen.exe'))
+ if os.path.isfile(src):
+ # Destination directory must not exist. It must be created first.
+ dst_dir = os.path.normpath(os.path.join(dist_dir, 'bin', subdir))
+ assert not os.path.isdir(dst_dir)
+ os.makedirs(dst_dir)
+
+ # Copy the file.
+ print("Copying '{}'".format(src))
+ shutil.copy2(src, dst_dir)
+ else:
+ print("The binary '" + src + "'")
+ print('was not found. It will not be present in the distribution.')
+
+
+def getBinariesZipBareName():
+ ver = getDoxygenVersion()
+ sha, dstamp, tstamp = gitSHA_date_time()
+ fname = 'doxygenw{}_{}.zip'.format(dstamp, ver.replace('.', '_'))
+ return fname
+
+
+def getTranslatorReportZipBareName():
+ ver = getDoxygenVersion()
+ sha, dstamp, tstamp = gitSHA_date_time()
+ fname = 'tr{}_{}.zip'.format(dstamp, ver.replace('.', '_'))
+ return fname
+
+
+def zipBinaries(distr_dir):
+ # Build the zip filename. It is to be located at the same level as distr_dir.
+ zip_bare_name = getBinariesZipBareName()
+ dst, distr_subdir = os.path.split(distr_dir)
+ zip_full_name = os.path.join(dst, zip_bare_name)
+
+ if os.path.isfile(zip_full_name):
+ print("Removing the existing '{}'".format(zip_full_name))
+ os.remove(zip_full_name)
+
+ # Change the working directory to destination directory and zip from
+ # there using the bare names so that the full path is not zipped inside.
+ wd = os.getcwd()
+ os.chdir(dst)
+ print("Zipping new '{}'".format(zip_full_name))
+ subprocess.call('zip -r {} {}'.format(zip_bare_name, distr_subdir), shell=True)
+ os.chdir(wd) # back to the original working directory
+
+
+def buildAndZipTranslatorReport(distr_dir):
+ # Build the translator report zip filename. It is to be located at the same
+ # level as distr_dir.
+ zip_bare_name = getTranslatorReportZipBareName()
+ dst, subdir = os.path.split(distr_dir)
+ zip_full_name = os.path.join(dst, zip_bare_name)
+
+ if os.path.isfile(zip_full_name):
+ print("Removing the existing '{}'".format(zip_full_name))
+ os.remove(zip_full_name)
+ print("Zipping new '{}'".format(zip_full_name))
+
+ # Change the working directory to the doc one and generate
+ # the translator report.
+ sdir, fname = getThisScriptPathAndName()
+ docdir = os.path.join(sdir, '..', 'doc')
+ assert os.path.isdir(docdir)
+ wd = os.getcwd()
+ os.chdir(docdir)
+ subprocess.call('python translator.py', shell=True)
+
+ # Zip the generated translator_report.txt.
+ subprocess.call('zip -r {} {}'.format(zip_full_name,
+ 'translator_report.txt'), shell=True)
+
+ os.chdir(wd) # back to the original working directory
+
+
+def mailto():
+
+ # Information for the letter.
+ ver = getDoxygenVersion()
+ sha, dstamp, tstamp = gitSHA_date_time()
+ doxzipname = getBinariesZipBareName()
+ trzipname = getTranslatorReportZipBareName()
+
+ subject = 'Windows binaries available for {}-{} at SourceForge'.format(ver, dstamp)
+ subject = subject.replace(' ', '%20')
+
+ body = textwrap.dedent('''\
+ Hi,
+
+ If interested, you can download the doxygen binaries
+ compiled for MS Windows from
+
+ http://sourceforge.net/projects/doxygen/files/snapshots/doxygen-1.8-svn/windows
+
+ This is the place where you should find also the next
+ releases. Name of the archive file is
+
+ {}
+
+ The related translator report can be found inside the directory
+
+ http://sourceforge.net/projects/doxygen/files/snapshots/doxygen-1.8-svn/translator_reports/
+
+ Name of the archive file is
+
+ {}
+
+ The binaries are NOT created automatically, so it may
+ happen that some newer sources were not compiled
+ because I am not present to do that or I forgot... ;)
+
+ Regards,
+ Petr
+
+ --
+ Petr Prikryl (prikryl at atlas dot cz)''').format(doxzipname, trzipname)
+ body = body.replace('\n', '%0d')
+
+ # Make the mailto URI and launch the mailer.
+ to_addr = 'doxygen-users at lists.sourceforge.net'
+ mailtoURI = 'mailto:%s?subject=%s&body=%s' % (to_addr, subject, body)
+ os.startfile(mailtoURI)
+
+
+if __name__ == '__main__':
+ # Create the empty directory for the distribution files.
+ dist_dir = getEmptyDistribDir()
+
+ # Copy the compiled binaries to the distribution directory and zip them.
+ copyBinaries(dist_dir, 'Debug')
+ copyBinaries(dist_dir, 'Debug64')
+ copyBinaries(dist_dir, 'Release')
+ copyBinaries(dist_dir, 'Release64')
+ zipBinaries(dist_dir)
+
+ # The translator report...
+ buildAndZipTranslatorReport(dist_dir)
+
+ # Launch the mailer with the generated message body.
+ mailto()
\ No newline at end of file
diff --git a/winbuild/qtools.vcproj b/winbuild/qtools.vcproj
new file mode 100644
index 0000000..adc1ba9
--- /dev/null
+++ b/winbuild/qtools.vcproj
@@ -0,0 +1,1587 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="qtools"
+ ProjectGUID="{B6BB4771-8A4E-4656-AC08-1EF8AC182F64}"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release\qtools"
+ IntermediateDirectory=".\Release\qtools"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="..\qtools"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release\qtools/qtools.pch"
+ AssemblerListingLocation=".\Release\qtools/"
+ ObjectFile=".\Release\qtools/"
+ ProgramDatabaseFileName=".\Release\qtools\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\qtools.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release\qtools/qtools.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory=".\Release64\qtools"
+ IntermediateDirectory=".\Release64\qtools"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="..\qtools"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release64\qtools/qtools.pch"
+ AssemblerListingLocation=".\Release64\qtools/"
+ ObjectFile=".\Release64\qtools/"
+ ProgramDatabaseFileName=".\Release64\qtools\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release64\qtools.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release64\qtools/qtools.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug\qtools"
+ IntermediateDirectory=".\Debug\qtools"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ Optimization="0"
+ AdditionalIncludeDirectories="..\qtools"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug\qtools/qtools.pch"
+ AssemblerListingLocation=".\Debug\qtools/"
+ ObjectFile=".\Debug\qtools/"
+ ProgramDatabaseFileName=".\Debug\qtools\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\qtools.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug\qtools/qtools.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory=".\Debug64\qtools"
+ IntermediateDirectory=".\Debug64\qtools"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ BuildLogFile="$(IntDir)\$(TargetName)BuildLog.htm"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ Optimization="0"
+ AdditionalIncludeDirectories="..\qtools"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug64\qtools/qtools.pch"
+ AssemblerListingLocation=".\Debug64\qtools/"
+ ObjectFile=".\Debug64\qtools/"
+ ProgramDatabaseFileName=".\Debug64\qtools\$(TargetName).pdb"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug64\qtools.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug64\qtools/qtools.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\qtools\qbuffer.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qcollection.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qdatastream.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qdatetime.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qdir.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qdir_win32.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qfile.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qfile_win32.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qfileinfo.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qfileinfo_win32.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qgarray.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qgcache.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qgdict.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qglist.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qglobal.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qgstring.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgvector.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qiodevice.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qmap.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qmutex.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qmutex_win32.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qregexp.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qstring.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qstringlist.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qtextcodec.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qtextstream.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\qthread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qthread_win32.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qutfcodec.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qwaitcondition_win32.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qxml.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\qtools\scstring.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\qtools\qarray.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qasciidict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qbuffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qcache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qcollection.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qconfig.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qcstring.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qdatastream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qdatetime.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qdict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qdir.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qfeatures.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qfile.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qfiledefs_p.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qfileinfo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgarray.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgcache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgdict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgeneric.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qglist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qglobal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgstring.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qgvector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qintdict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qiodevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qmodules.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qmutex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qmutex_p.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qptrdict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qqueue.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qregexp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qshared.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qsortedlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qstack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qstring.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qstringlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qstrlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qstrvec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qtextcodec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qtextstream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qthread.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qthread_p.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qtl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qutfcodec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qvaluelist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qvaluestack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qvector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qwaitcondition.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\qxml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\qtools\scstring.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/winbuild/unistd.py b/winbuild/unistd.py
new file mode 100644
index 0000000..93b9341
--- /dev/null
+++ b/winbuild/unistd.py
@@ -0,0 +1,16 @@
+#
+
+import sys
+import os
+
+f1 = open(os.path.join(sys.argv[1],'unistd.h'),'w')
+
+f1.write("#ifndef UNISTD_H\n")
+f1.write("#define UNISTD_H\n")
+f1.write("/* this is a dummy file, that is needed for compiling files that are\n")
+f1.write(" * generated with flex under Windows 95/NT.\n")
+f1.write(" */\n")
+f1.write("#if defined(_MSC_VER)\n")
+f1.write(" #include <io.h>\n")
+f1.write("#endif\n")
+f1.write("#endif\n")
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/doxygen.git
More information about the Reproducible-commits
mailing list